erythros/System/Core/SystemTray.HC

139 lines
No EOL
3.6 KiB
HolyC

#define SYSTRAY_MSG_NULL 0x0
#define SYSTRAY_MSG_REGISTER 0x1
#define SYSTRAY_MSG_UNREGISTER 0x2
class @systemtray
{
CTask* task;
@window_widgets_list* item;
U0 (*Init)();
U0 (*Task)();
Context2DWidget* (*RegisterItem)();
U0 (*UnregisterItem)(Widget* widget);
U0 (*SetIcon)(Context2DWidget* widget, U8* path);
};
@systemtray SystemTray;
U0 @systemtray_register_item(I64 addr)
{
Context2DWidget* item = Gui.CreateWidget(
Compositor.menubar.win, WIDGET_TYPE_CONTEXT2D, -24, 0, 24, 24);
item->ctx = NewContext2D(item->width, item->height);
item->ctx->fill(0);
MemSetI64(addr, item, 1);
}
U0 @systemtray_unregister_item(Widget* item)
{
IpcMessage* msg = CAlloc2(sizeof(IpcMessage));
msg->client = NULL;
msg->type = CPZ_MSG_WIN_WIDGET_DESTROY;
msg->payload = item;
System.Log(Fs, "Sent message → WidgetDestroy");
Ipc.MsgSend(Compositor.menubar.task, msg);
}
U0 @systemtray_reindex_items()
{
I64 x = Display.Width() - 100;
@window_widgets_list* item = Compositor.menubar.win->widget;
while (item->next)
item = item->next;
while (item->widget->type == WIDGET_TYPE_CONTEXT2D) {
x -= item->widget->width + 4;
item->widget->x = x;
item = item->prev;
}
Gui.Window.Refresh(Compositor.menubar.win);
}
U0 @systemtray_ipc_queue_process()
{
IpcMessage* msg;
msg = Ipc.MsgRecv();
if (msg) {
switch (msg->type) {
case SYSTRAY_MSG_REGISTER:
@systemtray_register_item(msg->payload);
@systemtray_reindex_items;
break;
case SYSTRAY_MSG_UNREGISTER:
@systemtray_unregister_item(msg->payload);
@systemtray_reindex_items;
break;
default:
break;
}
Free(msg);
}
}
U0 @systemtray_init() { }
U0 @systemtray_task()
{
Ipc.InitQueue(Fs);
SystemTray.task = Fs;
System.Log(Fs, "Task running at 0x%08x", Fs);
while (!Compositor.menubar.win) // Wait for instance
Sleep(1);
while (1) {
@systemtray_ipc_queue_process();
Sleep(1);
}
}
Context2DWidget* @systemtray_client_register_item()
{
Context2DWidget* item = NULL;
IpcMessage* msg = CAlloc2(sizeof(IpcMessage));
msg->client = NULL;
msg->type = SYSTRAY_MSG_REGISTER;
msg->payload = &item;
System.Log(Fs, "Sent message → SystrayRegisterItem");
Ipc.MsgSend(SystemTray.task, msg);
while (!item)
Sleep(1);
return item;
}
U0 @systemtray_client_unregister_item(Widget* item)
{
IpcMessage* msg = CAlloc2(sizeof(IpcMessage));
msg->client = NULL;
msg->type = SYSTRAY_MSG_UNREGISTER;
msg->payload = item;
System.Log(Fs, "Sent message → SystrayUnRegisterItem");
Ipc.MsgSend(SystemTray.task, msg);
while (item->type)
Sleep(1);
@systemtray_reindex_items;
}
U0 @systemtray_set_icon(Context2DWidget* widget, U8* path)
{
if (!widget || !path)
return;
U8 full_path[512];
if (2 == 3) // FIXME
StrCpy(&full_path, path);
else {
StrCpy(&full_path, "M:/Media/Themes/Umami/Icon/");
String.Append(&full_path, path);
}
if (!FileFind(&full_path))
return;
Context2D* icon = Image.FileToContext2D(&full_path);
CopyRect2D(widget->ctx, 0, 0, icon);
DelContext2D(icon);
Gui.Window.Refresh(Compositor.menubar.win);
}
SystemTray.Init = &@systemtray_init;
SystemTray.RegisterItem = &@systemtray_client_register_item;
SystemTray.SetIcon = &@systemtray_set_icon;
SystemTray.Task = &@systemtray_task;
SystemTray.UnregisterItem = &@systemtray_client_unregister_item;
"systemtray ";