From: John Hodge (sonata) Date: Tue, 27 Nov 2012 12:13:39 +0000 (+0800) Subject: Usermode/AxWin3 - Reworked renderers to use raw IPC calls X-Git-Tag: rel0.15~648 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=ed78a9ac44c440180c37c1cbbbd7ecbc4d9076d7;p=tpg%2Facess2.git Usermode/AxWin3 - Reworked renderers to use raw IPC calls - Instead of using WM_SendMessage (thiner and easier to handle) --- diff --git a/Usermode/Applications/axwin3_src/WM/Makefile b/Usermode/Applications/axwin3_src/WM/Makefile index 972f72fe..1d674507 100644 --- a/Usermode/Applications/axwin3_src/WM/Makefile +++ b/Usermode/Applications/axwin3_src/WM/Makefile @@ -10,7 +10,7 @@ BIN := AxWinWM OBJ := main.o input.o video.o ipc.o image.o utf-8.o OBJ += wm.o wm_input.o wm_render.o wm_render_text.o wm_hotkeys.o OBJ += decorator.o -OBJ += renderers/passthru.o +OBJ += renderers/framebuffer.o OBJ += renderers/background.o OBJ += renderers/menu.o OBJ += renderers/richtext.o diff --git a/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h b/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h index 58825491..89aceb9f 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h @@ -52,9 +52,17 @@ struct sWMRenderer * \return Boolean failure (0: Handled, 1: Unhandled) */ int (*HandleMessage)(tWindow *Window, int MessageID, int Length, const void *Data); + + int nIPCHandlers; + + /** + * \brief IPC Message handler + */ + int (*IPCHandlers[])(tWindow *Window, size_t Length, const void *Data); }; extern void WM_RegisterRenderer(tWMRenderer *Renderer); extern tWindow *WM_CreateWindowStruct(size_t ExtraBytes); +extern int WM_SendIPCReply(tWindow *Window, int Message, size_t Length, const void *Data); #endif diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index bc38fb55..38cd1335 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -13,7 +13,8 @@ #include #include #include -#include +#include // Hotkey registration +#include // Renderer IPC messages #define AXWIN_PORT 4101 @@ -539,8 +540,8 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW tIPC_Client *client; int rv = 0; - _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)", - IPCType, Ident, MsgLen, Msg); +// _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)", +// IPCType, Ident, MsgLen, Msg); if( MsgLen < sizeof(tAxWin_IPCMessage) ) return ; @@ -548,22 +549,48 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW return ; client = IPC_int_GetClient(IPCType, Ident); - - if( Msg->ID >= giIPC_NumMessageHandlers ) { - fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType); - _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType); - return ; + if( !client ) { + // Oops? } - if( !gIPC_MessageHandlers[ Msg->ID ] ) { - fprintf(stderr, "WARNING: Message %i does not have a handler\n", Msg->ID); - _SysDebug("WARNING: Message %i does not have a handler", Msg->ID); - return ; + if( Msg->Flags & IPCMSG_FLAG_RENDERER ) + { + tWindow *win = IPC_int_GetWindow(client, Msg->Window); + if( !win ) { + _SysDebug("WARNING: NULL window in message %i", Msg->ID); + return ; + } + tWMRenderer *renderer = win->Renderer; + if( Msg->ID >= renderer->nIPCHandlers ) { + _SysDebug("WARNING: Message %i out of range in %s", Msg->ID, renderer->Name); + return ; + } + if( !renderer->IPCHandlers[Msg->ID] ) { + _SysDebug("WARNING: Message %i has no handler in %s", Msg->ID, renderer->Name); + return ; + } + _SysDebug("IPC_Handle: Call %s-%i", renderer->Name, Msg->ID); + rv = renderer->IPCHandlers[Msg->ID](win, Msg->Size, Msg->Data); + _SysDebug("IPC_Handle: rv = %i", rv); + } + else + { + if( Msg->ID >= giIPC_NumMessageHandlers ) { + fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType); + _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType); + return ; + } + + if( !gIPC_MessageHandlers[ Msg->ID ] ) { + fprintf(stderr, "WARNING: Message %i does not have a handler\n", Msg->ID); + _SysDebug("WARNING: Message %i does not have a handler", Msg->ID); + return ; + } + + _SysDebug("IPC_Handle: Call WM-%i", Msg->ID); + rv = gIPC_MessageHandlers[Msg->ID](client, Msg); + _SysDebug("IPC_Handle: rv = %i", rv); } - - _SysDebug("IPC_Handle: Msg->ID = %i", Msg->ID); - rv = gIPC_MessageHandlers[Msg->ID](client, Msg); - _SysDebug("IPC_Handle: rv = %i", rv); } // --- Server->Client replies @@ -589,3 +616,19 @@ void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int MsgI Client->IPCType->SendMessage(Client->Ident, sizeof(buf), buf); } +void IPC_SendReply(tIPC_Client *Client, uint32_t WinID, int MsgID, size_t Len, const void *Data) +{ + tAxWin_IPCMessage *hdr; + char buf[sizeof(*hdr)+Len]; + + hdr = (void*)buf; + + hdr->ID = MsgID; + hdr->Flags = IPCMSG_FLAG_RENDERER; + hdr->Size = Len; + hdr->Window = WinID; + + memcpy(hdr->Data, Data, Len); + Client->IPCType->SendMessage(Client->Ident, sizeof(buf), buf); +} + diff --git a/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c b/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c new file mode 100644 index 00000000..fc838cb0 --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c @@ -0,0 +1,258 @@ +/* + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * renderer_passthru.c + * - Passthrough window render (framebuffer essentially) + */ +#include +#include +#include +#include +#include + +// === TYPES === +typedef struct +{ + short W, H; + void *Data; + char _data[]; +} tFBBuffer; +typedef struct +{ + tFBBuffer BackBuffer; + int MaxBufferCount; + tFBBuffer *Buffers[]; +} tFBWin; + +// === PROTOTYPES === +tWindow *Renderer_Framebuffer_Create(int Flags); +void Renderer_Framebuffer_Redraw(tWindow *Window); + int _Handle_Commit(tWindow *Target, size_t Len, const void *Data); + int _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data); + int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); + +// === GLOBALS === +tWMRenderer gRenderer_Framebuffer = { + .Name = "FrameBuffer", + .CreateWindow = Renderer_Framebuffer_Create, + .Redraw = Renderer_Framebuffer_Redraw, + .HandleMessage = Renderer_Framebuffer_HandleMessage, + .nIPCHandlers = N_IPC_FB, + .IPCHandlers = { + [IPC_FB_COMMIT] = _Handle_Commit, + [IPC_FB_NEWBUF] = _Handle_CreateBuf, + } +}; + +// === CODE === +int Renderer_Framebuffer_Init(void) +{ + WM_RegisterRenderer(&gRenderer_Framebuffer); + return 0; +} + +tWindow *Renderer_Framebuffer_Create(int Flags) +{ + tWindow *ret; + tFBWin *info; + const int max_buffers = 10; // TODO: Have this be configurable + + ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) ); + info = ret->RendererInfo; + + info->BackBuffer.W = 0; + info->BackBuffer.H = 0; + info->BackBuffer.Data = NULL; + info->MaxBufferCount = max_buffers; + memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers ); + + return ret; +} + +void Renderer_Framebuffer_Redraw(tWindow *Window) +{ + +} + +// --- --- +tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID) +{ + tFBWin *info = Win->RendererInfo; + if( ID == 0xFFFF ) + return &info->BackBuffer; + else if( ID >= info->MaxBufferCount ) + return NULL; + else + return info->Buffers[ ID ]; +} + +void _Blit( + tFBBuffer *Dest, uint16_t DX, uint16_t DY, + const tFBBuffer *Src, uint16_t SX, uint16_t SY, + uint16_t W, uint16_t H + ) +{ + uint32_t *dest_data = Dest->Data; + const uint32_t *src_data = Src->Data; + // First, some sanity + if( DX > Dest->W ) return ; + if( DY > Dest->H ) return ; + if( SX > Src->W ) return ; + if( SY > Src->H ) return ; + + if( DX + W > Dest->W ) W = Dest->W - DX; + if( SX + W > Src->W ) W = Src->W - SX; + if( DY + H > Dest->H ) H = Dest->H - DY; + if( SY + H > Src->H ) H = Src->H - SY; + + dest_data += (DY * Dest->W) + DX; + src_data += (SY * Src->W ) + SX; + for( int i = 0; i < H; i ++ ) + { + memcpy( dest_data, src_data, W * 4 ); + dest_data += Dest->W; + src_data += Src->W; + } +} + +void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour) +{ + uint32_t *data = Buf->Data; + + if( X > Buf->W ) return ; + if( Y > Buf->H ) return ; + if( X + W > Buf->W ) W = Buf->W - X; + if( Y + H > Buf->H ) H = Buf->H - Y; + + data += (Y * Buf->W) + X; + for( int i = 0; i < H; i ++ ) + { + for( int j = 0; j < W; j ++ ) + *data++ = Colour; + data += Buf->W - W; + } +} + +// --- --- +int _Handle_Commit(tWindow *Target, size_t Len, const void *Data) +{ + // Do a window invalidate + return 0; +} + +int _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data) +{ + const tFBIPC_NewBuf *msg = Data; + tFBBuffer *buf; + tFBWin *info = Target->RendererInfo; + + if( Len < sizeof(*msg) ) return -1; + + if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) { + // Can't reallocate -1 + return 1; + } + + if( info->Buffers[msg->Buffer] ) { + free(info->Buffers[msg->Buffer]); + info->Buffers[msg->Buffer] = NULL; + } + + buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4); + buf->W = msg->W; + buf->H = msg->H; + buf->Data = buf->_data; + + info->Buffers[msg->Buffer] = buf; + + return 0; +} + +int _Handle_Upload(tWindow *Target, size_t Len, const void *Data) +{ + const tFBIPC_Transfer *msg = Data; + tFBBuffer *dest, src; + + if( Len < sizeof(*msg) ) return -1; + if( Len < sizeof(*msg) + msg->W * msg->H * 4 ) return -1; + + dest = _GetBuffer(Target, msg->Buffer); + + src.W = msg->W; + src.H = msg->H; + src.Data = (void*)msg->ImageData; + + _Blit( dest, msg->X, msg->Y, &src, 0, 0, msg->W, msg->H ); + return 0; +} + +int _Handle_Download(tWindow *Target, size_t Len, const void *Data) +{ + const tFBIPC_Transfer *msg = Data; + tFBBuffer dest, *src; + + if( Len < sizeof(*msg) ) return -1; + + src = _GetBuffer(Target, msg->Buffer); + + tFBIPC_Transfer *ret; + int retlen = sizeof(*ret) + msg->W*msg->H*4; + ret = malloc( retlen ); + + dest.W = ret->W = msg->W; + dest.H = ret->H = msg->H; + dest.Data = ret->ImageData; + + _Blit( &dest, 0, 0, src, msg->X, msg->Y, msg->W, msg->H ); + + WM_SendIPCReply(Target, IPC_FB_DOWNLOAD, retlen, ret); + + free(ret); + + return 0; +} + +int _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data) +{ + const tFBIPC_Blit *msg = Data; + tFBBuffer *dest, *src; + + if( Len < sizeof(*msg) ) return -1; + + src = _GetBuffer(Target, msg->Source); + dest = _GetBuffer(Target, msg->Dest); + + _Blit( dest, msg->DstX, msg->DstY, src, msg->SrcX, msg->SrcY, msg->W, msg->H ); + return 0; +} + +int _Handle_FillRect(tWindow *Target, size_t Len, const void *Data) +{ + const tFBIPC_Fill *msg = Data; + tFBBuffer *dest; + + if( Len < sizeof(*msg) ) return -1; + + dest = _GetBuffer(Target, msg->Buffer); + + _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour ); + return 0; +} + +int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) +{ + switch(Msg) + { + case WNDMSG_RESIZE: + // Resize the framebuffer + return 1; // Pass on + + // Messages that get passed on + case WNDMSG_MOUSEBTN: + return 1; + } + return 1; +} + + diff --git a/Usermode/Applications/axwin3_src/WM/renderers/menu.c b/Usermode/Applications/axwin3_src/WM/renderers/menu.c index a183de00..9d2ecea7 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/menu.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/menu.c @@ -47,6 +47,8 @@ typedef struct sMenuWindowInfo void Renderer_Menu_Init(void); tWindow *Renderer_Menu_Create(int Argument); void Renderer_Menu_Redraw(tWindow *Window); + int Renderer_Menu_HandleIPC_AddItem(tWindow *Window, size_t Length, const void *Data); + int Renderer_Menu_HandleIPC_SetFlags(tWindow *Window, size_t Length, const void *Data); int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, const void *Data); // === CONSTANTS === @@ -70,7 +72,12 @@ tWMRenderer gRenderer_Menu = { .Name = "Menu", .CreateWindow = Renderer_Menu_Create, .Redraw = Renderer_Menu_Redraw, - .HandleMessage = Renderer_Menu_HandleMessage + .HandleMessage = Renderer_Menu_HandleMessage, + .nIPCHandlers = 2, + .IPCHandlers = { + Renderer_Menu_HandleIPC_AddItem, +// Renderer_Menu_HandleIPC_SetFlags + } }; tFont *gMenu_Font = NULL; // System monospace @@ -196,8 +203,9 @@ void Renderer_Menu_Redraw(tWindow *Window) } } -int Renderer_Menu_int_AddItem(tWindow *Window, int Length, const tMenuMsg_AddItem *Msg) +int Renderer_Menu_HandleIPC_AddItem(tWindow *Window, size_t Length, const void *Data) { + const tMenuIPC_AddItem *Msg = Data; tMenuWindowInfo *info = Window->RendererInfo; tMenuItem *item; @@ -418,11 +426,6 @@ int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, const void return 0; } - // Manipulation messages - case MSG_MENU_ADDITEM: -// _SysDebug("MSG_MENU_ADDITEM"); - return Renderer_Menu_int_AddItem(Window, Length, Data); - // Only message to pass to client case MSG_MENU_SELECT: return 1; diff --git a/Usermode/Applications/axwin3_src/WM/renderers/passthru.c b/Usermode/Applications/axwin3_src/WM/renderers/passthru.c deleted file mode 100644 index c8d61cfd..00000000 --- a/Usermode/Applications/axwin3_src/WM/renderers/passthru.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Acess2 Window Manager v3 - * - By John Hodge (thePowersGang) - * - * renderer_passthru.c - * - Passthrough window render (framebuffer essentially) - */ -#include -#include -#include -#include -#include - -// === TYPES === -typedef struct -{ - short W, H; - void *Data; - char _data[]; -} tFBBuffer; -typedef struct -{ - tFBBuffer BackBuffer; - int MaxBufferCount; - tFBBuffer *Buffers[]; -} tFBWin; - -// === PROTOTYPES === -tWindow *Renderer_Framebuffer_Create(int Flags); -void Renderer_Framebuffer_Redraw(tWindow *Window); - int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); - -// === GLOBALS === -tWMRenderer gRenderer_Framebuffer = { - .Name = "FrameBuffer", - .CreateWindow = Renderer_Framebuffer_Create, - .Redraw = Renderer_Framebuffer_Redraw, - .HandleMessage = Renderer_Framebuffer_HandleMessage -}; - -// === CODE === -int Renderer_Framebuffer_Init(void) -{ - WM_RegisterRenderer(&gRenderer_Framebuffer); - return 0; -} - -tWindow *Renderer_Framebuffer_Create(int Flags) -{ - tWindow *ret; - tFBWin *info; - const int max_buffers = 10; // TODO: Have this be configurable - - ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) ); - info = ret->RendererInfo; - - info->BackBuffer.W = 0; - info->BackBuffer.H = 0; - info->BackBuffer.Data = NULL; - info->MaxBufferCount = max_buffers; - memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers ); - - return ret; -} - -void Renderer_Framebuffer_Redraw(tWindow *Window) -{ - -} - -// --- --- -tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID) -{ - tFBWin *info = Win->RendererInfo; - if( ID == 0xFFFF ) - return &info->BackBuffer; - else if( ID >= info->MaxBufferCount ) - return NULL; - else - return info->Buffers[ ID ]; -} - -void _Blit( - tFBBuffer *Dest, uint16_t DX, uint16_t DY, - const tFBBuffer *Src, uint16_t SX, uint16_t SY, - uint16_t W, uint16_t H - ) -{ - uint32_t *dest_data = Dest->Data; - const uint32_t *src_data = Src->Data; - // First, some sanity - if( DX > Dest->W ) return ; - if( DY > Dest->H ) return ; - if( SX > Src->W ) return ; - if( SY > Src->H ) return ; - - if( DX + W > Dest->W ) W = Dest->W - DX; - if( SX + W > Src->W ) W = Src->W - SX; - if( DY + H > Dest->H ) H = Dest->H - DY; - if( SY + H > Src->H ) H = Src->H - SY; - - dest_data += (DY * Dest->W) + DX; - src_data += (SY * Src->W ) + SX; - for( int i = 0; i < H; i ++ ) - { - memcpy( dest_data, src_data, W * 4 ); - dest_data += Dest->W; - src_data += Src->W; - } -} - -void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour) -{ - uint32_t *data = Buf->Data; - - if( X > Buf->W ) return ; - if( Y > Buf->H ) return ; - if( X + W > Buf->W ) W = Buf->W - X; - if( Y + H > Buf->H ) H = Buf->H - Y; - - data += (Y * Buf->W) + X; - for( int i = 0; i < H; i ++ ) - { - for( int j = 0; j < W; j ++ ) - *data++ = Colour; - data += Buf->W - W; - } -} - -// --- --- -void _Handle_Commit(tWindow *Target, size_t Len, const void *Data) -{ - // Do a window invalidate -} - -void _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data) -{ - const tFBMsg_NewBuf *msg = Data; - tFBBuffer *buf; - tFBWin *info = Target->RendererInfo; - - if( Len < sizeof(*msg) ) return ; - - if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) { - // Can't reallocate -1 - return ; - } - - if( info->Buffers[msg->Buffer] ) { - free(info->Buffers[msg->Buffer]); - info->Buffers[msg->Buffer] = NULL; - } - - buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4); - buf->W = msg->W; - buf->H = msg->H; - buf->Data = buf->_data; - - info->Buffers[msg->Buffer] = buf; -} - -void _Handle_Upload(tWindow *Target, size_t Len, const void *Data) -{ - const tFBMsg_Transfer *msg = Data; - tFBBuffer *dest, src; - - if( Len < sizeof(*msg) ) return ; - if( Len < sizeof(*msg) + msg->W * msg->H * 4 ) return ; - - dest = _GetBuffer(Target, msg->Buffer); - - src.W = msg->W; - src.H = msg->H; - src.Data = (void*)msg->ImageData; - - _Blit( dest, msg->X, msg->Y, &src, 0, 0, msg->W, msg->H ); -} - -void _Handle_Download(tWindow *Target, size_t Len, const void *Data) -{ - #if 0 - const tFBMsg_Transfer *msg = Data; - tFBBuffer dest, *src; - - if( Len < sizeof(*msg) ) return ; - if( Len < sizeof(*msg) + msg->W * msg->H * 4 ) return ; - - src = _GetBuffer(Target, msg->Buffer); - - dest.W = msg->W; - dest.H = msg->H; - dest.Data = msg->ImageData; - - _Blit( &dest, 0, 0, src, msg->X, msg->Y, msg->W, msg->H ); - #endif -} - -void _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data) -{ - const tFBMsg_Blit *msg = Data; - tFBBuffer *dest, *src; - - if( Len < sizeof(*msg) ) return ; - - src = _GetBuffer(Target, msg->Source); - dest = _GetBuffer(Target, msg->Dest); - - _Blit( dest, msg->DstX, msg->DstY, src, msg->SrcX, msg->SrcY, msg->W, msg->H ); -} - -void _Handle_FillRect(tWindow *Target, size_t Len, const void *Data) -{ - const tFBMsg_Fill *msg = Data; - tFBBuffer *dest; - - if( Len < sizeof(*msg) ) return ; - - dest = _GetBuffer(Target, msg->Buffer); - - _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour ); -} - -int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) -{ - switch(Msg) - { - case WNDMSG_RESIZE: - // Resize the framebuffer - return 1; // Pass on - - // Messages that get passed on - case WNDMSG_MOUSEBTN: - return 1; - - // --- Local messages --- - // - Drawing completed, do an update - case MSG_FB_COMMIT: - _Handle_Commit(Target, Len, Data); - return 0; - // - New Buffer (create a new server-side buffer) - case MSG_FB_NEWBUF: - _Handle_CreateBuf(Target, Len, Data); - return 0; - // - Upload (Transfer data from client to server) - case MSG_FB_UPLOAD: - _Handle_Upload(Target, Len, Data); - return 0; - // - Download (Transfer image data from server to client) - case MSG_FB_DOWNLOAD: - _Handle_Download(Target, Len, Data); - return 0; - // - Local Blit (Transfer from server to server) - case MSG_FB_BLIT: - _Handle_LocalBlit(Target, Len, Data); - return 0; - // - Fill a rectangle - case MSG_FB_FILL: - _Handle_FillRect(Target, Len, Data); - return 0; - } - return 1; -} - - diff --git a/Usermode/Applications/axwin3_src/WM/renderers/richtext.c b/Usermode/Applications/axwin3_src/WM/renderers/richtext.c index 79e60108..28be1aeb 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/richtext.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/richtext.c @@ -44,6 +44,8 @@ typedef struct sRichText_Window int Renderer_RichText_Init(void); tWindow *Renderer_RichText_Create(int Flags); void Renderer_RichText_Redraw(tWindow *Window); + int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data); + int Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const void *Data); int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); // === GLOBALS === @@ -51,7 +53,12 @@ tWMRenderer gRenderer_RichText = { .Name = "RichText", .CreateWindow = Renderer_RichText_Create, .Redraw = Renderer_RichText_Redraw, - .HandleMessage = Renderer_RichText_HandleMessage + .HandleMessage = Renderer_RichText_HandleMessage, + .nIPCHandlers = N_IPC_RICHTEXT, + .IPCHandlers = { + [IPC_RICHTEXT_SETATTR] = Renderer_RichText_HandleIPC_SetAttr, + [IPC_RICHTEXT_WRITELINE] = Renderer_RichText_HandleIPC_WriteLine + } }; // === CODE === @@ -219,6 +226,82 @@ void Renderer_RichText_Redraw(tWindow *Window) ); } +int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data) +{ + tRichText_Window *info = Window->RendererInfo; + const struct sRichTextIPC_SetAttr *msg = Data; + if(Len < sizeof(*msg)) return -1; + + _SysDebug("RichText Attr %i set to %x", msg->Attr, msg->Value); + switch(msg->Attr) + { + case _ATTR_DEFBG: + info->DefaultBG = msg->Value; + break; + case _ATTR_DEFFG: + info->DefaultFG = msg->Value; + break; + case _ATTR_SCROLL: + // TODO: Set scroll flag + break; + case _ATTR_LINECOUNT: + info->nLines = msg->Value; + break; + } + + return 0; +} + +int Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const void *Data) +{ + tRichText_Window *info = Window->RendererInfo; + const struct sRichTextIPC_WriteLine *msg = Data; + if( Len < sizeof(*msg) ) return -1; + if( msg->Line >= info->nLines ) return 1; // Bad count + + tRichText_Line *line = info->FirstLine; + tRichText_Line *prev = NULL; + while(line && line->Num < msg->Line) + prev = line, line = line->Next; + if( !line || line->Num > msg->Line ) + { + // New line! + // Round up to 32 + int space = ((Len - sizeof(*msg)) + 32-1) & ~(32-1); + tRichText_Line *new = malloc(sizeof(*line) + space); + // TODO: Bookkeeping on how much memory each window uses + new->Next = line; + new->Prev = prev; + new->Num = msg->Line; + new->Space = space; + if(new->Prev) new->Prev->Next = new; + else info->FirstLine = new; + if(new->Next) new->Next->Prev = new; + line = new; + } + else if( line->Space < Len - sizeof(*msg) ) + { + // Need to allocate more space + int space = ((Len - sizeof(*msg)) + 32-1) & ~(32-1); + tRichText_Line *new = realloc(line, space); + // TODO: Bookkeeping on how much memory each window uses + new->Space = space; + + if(new->Prev) new->Prev->Next = new; + else info->FirstLine = new; + if(new->Next) new->Next->Prev = new; + line = new; + } + else + { + // It fits :) + } + line->ByteLength = Len - sizeof(*msg); + memcpy(line->Data, msg->LineData, Len - sizeof(*msg)); + + return 0; +} + int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) { tRichText_Window *info = Target->RendererInfo; @@ -229,73 +312,6 @@ int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const voi if(Len < sizeof(*msg)) return -1; info->DispLines = msg->H / info->LineHeight; return 1; } - case MSG_RICHTEXT_SETATTR: { - const struct sRichTextMsg_SetAttr *msg = Data; - if(Len < sizeof(*msg)) return -1; - _SysDebug("RichText Attr %i set to %x", msg->Attr, msg->Value); - switch(msg->Attr) - { - case _ATTR_DEFBG: - info->DefaultBG = msg->Value; - break; - case _ATTR_DEFFG: - info->DefaultFG = msg->Value; - break; - case _ATTR_SCROLL: - // TODO: Set scroll flag - break; - case _ATTR_LINECOUNT: - info->nLines = msg->Value; - break; - } - return 1; } - // Update a line - case MSG_RICHTEXT_SENDLINE: { - const struct sRichTextMsg_SendLine *msg = Data; - if(Len < sizeof(*msg)) return -1; - _SysDebug("RichText Line %i = '%.*s'", msg->Line, Len - sizeof(*msg), msg->LineData); - if( msg->Line >= info->nLines ) return 1; // Bad count - - tRichText_Line *line = info->FirstLine; - tRichText_Line *prev = NULL; - while(line && line->Num < msg->Line) - prev = line, line = line->Next; - if( !line || line->Num > msg->Line ) - { - // New line! - // Round up to 32 - int space = ((Len - sizeof(*msg)) + 32-1) & ~(32-1); - tRichText_Line *new = malloc(sizeof(*line) + space); - // TODO: Bookkeeping on how much memory each window uses - new->Next = line; - new->Prev = prev; - new->Num = msg->Line; - new->Space = space; - if(new->Prev) new->Prev->Next = new; - else info->FirstLine = new; - if(new->Next) new->Next->Prev = new; - line = new; - } - else if( line->Space < Len - sizeof(*msg) ) - { - // Need to allocate more space - int space = ((Len - sizeof(*msg)) + 32-1) & ~(32-1); - tRichText_Line *new = realloc(line, space); - // TODO: Bookkeeping on how much memory each window uses - new->Space = space; - - if(new->Prev) new->Prev->Next = new; - else info->FirstLine = new; - if(new->Next) new->Next->Prev = new; - line = new; - } - else - { - // It fits :) - } - line->ByteLength = Len - sizeof(*msg); - memcpy(line->Data, msg->LineData, Len - sizeof(*msg)); - return 1; } } return 0; } diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget.c b/Usermode/Applications/axwin3_src/WM/renderers/widget.c index b8c454c8..12566d53 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget.c @@ -26,10 +26,15 @@ void Widget_UpdateDimensions(tElement *Element); void Widget_UpdatePosition(tElement *Element); // --- Messages tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID); -void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg); -void Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg); -void Widget_SetSize(tWidgetWin *Info, int Len, const tWidgetMsg_SetSize *Msg); -void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg); + int Widget_IPC_Create(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_NewWidgetSubwin(tWindow *Win, size_t Len, const void *Data); +// int Widget_IPC_Delete(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_SetFocus(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_SetFlags(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_SetSize(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_SetText(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_GetText(tWindow *Win, size_t Len, const void *Data); +// int Widget_IPC_SetColour(tWindow *Win, size_t Len, const void *Data); int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); // === GLOBALS === @@ -37,7 +42,17 @@ tWMRenderer gRenderer_Widget = { .Name = "Widget", .CreateWindow = Renderer_Widget_Create, .Redraw = Renderer_Widget_Redraw, - .HandleMessage = Renderer_Widget_HandleMessage + .HandleMessage = Renderer_Widget_HandleMessage, + .nIPCHandlers = N_IPC_WIDGET, + .IPCHandlers = { + [IPC_WIDGET_CREATE] = Widget_IPC_Create, + [IPC_WIDGET_CREATESUBWIN] = Widget_IPC_NewWidgetSubwin, + [IPC_WIDGET_SETFOCUS] = Widget_IPC_SetFocus, + [IPC_WIDGET_SETFLAGS] = Widget_IPC_SetFlags, + [IPC_WIDGET_SETSIZE] = Widget_IPC_SetSize, + [IPC_WIDGET_SETTEXT] = Widget_IPC_SetText, + [IPC_WIDGET_GETTEXT] = Widget_IPC_GetText, + } }; // --- Element callbacks @@ -464,17 +479,27 @@ tElement *Widget_int_Create(tWidgetWin *Info, tElement *Parent, int ID, int Type return new; } +void Widget_SetFocus(tWidgetWin *Info, tElement *Ele) +{ + // TODO: Callbacks + + Info->FocusedElement = Ele; +} + + // --- Message Handlers --- -void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg) +int Widget_IPC_Create(tWindow *Win, size_t Len, const void *Data) { - const int max_debugname_len = Len - sizeof(tWidgetMsg_Create); + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_Create *Msg = Data; + const int max_debugname_len = Len - sizeof(*Msg); tElement *parent; // Sanity check if( Len < sizeof(*Msg) ) - return ; + return -1; if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len ) - return ; + return -1; _SysDebug("Widget_NewWidget (%i %i Type %i Flags 0x%x)", Msg->Parent, Msg->NewID, Msg->Type, Msg->Flags); @@ -482,7 +507,7 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg if(Msg->Type >= ciWM_NumWidgetTypes) { _SysDebug("Widget_NewWidget - Bad widget type %i", Msg->Type); - return ; + return 1; } // Create @@ -490,82 +515,101 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg if(!parent) { _SysDebug("Widget_NewWidget - Bad parent ID %i", Msg->Parent); - return ; + return 1; } Widget_int_Create(Info, parent, Msg->NewID, Msg->Type, Msg->Flags); Widget_UpdateMinDims(parent); + return 0; } -void Widget_NewWidgetSubwin(tWidgetWin *Info, size_t Len, const tWidgetMsg_CreateSubWin *Msg) +int Widget_IPC_NewWidgetSubwin(tWindow *Win, size_t Len, const void *Data) { - const int max_debugname_len = Len - sizeof(tWidgetMsg_CreateSubWin); + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_CreateSubWin *Msg = Data; + const int max_debugname_len = Len - sizeof(*Msg); tElement *parent, *new; // Sanity check if( Len < sizeof(*Msg) ) - return ; + return -1; if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len ) - return ; + return -1; parent = Widget_GetElementById(Info, Msg->Parent); - if(!parent) return; - if( Widget_GetElementById(Info, Msg->NewID) ) return ; + if(!parent) return 1; + if( Widget_GetElementById(Info, Msg->NewID) ) return 1; new = Widget_int_Create(Info, parent, Msg->NewID, Msg->Type, Msg->Flags); new->Data = WM_GetWindowByID(parent->Window, Msg->WindowHandle); Widget_UpdateMinDims(parent); + return 0; } -void Widget_SetFocus(tWidgetWin *Info, tElement *Ele) -{ - // TODO: Callbacks +// TODO: Widget_IPC_Delete - Info->FocusedElement = Ele; +int Widget_IPC_SetFocus(tWindow *Win, size_t Len, const void *Data) +{ + tWidgetWin *info = Win->RendererInfo; + tElement *ele; + const tWidgetIPC_SetFocus *msg = Data; + if(Len < sizeof(*msg)) return -1; + + ele = Widget_GetElementById(info, msg->WidgetID); + Widget_SetFocus(info, ele); + return 0; } -void Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg) +int Widget_IPC_SetFlags(tWindow *Win, size_t Len, const void *Data) { + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_SetFlags *Msg = Data; tElement *ele; if( Len < sizeof(*Msg) ) - return ; + return -1; _SysDebug("Widget_SetFlags: (%i 0x%x 0x%x)", Msg->WidgetID, Msg->Value, Msg->Mask); ele = Widget_GetElementById(Info, Msg->WidgetID); - if(!ele) return; + if(!ele) return 1; ele->Flags &= ~Msg->Mask; ele->Flags |= Msg->Value & Msg->Mask; + + return 0; } -void Widget_SetSize(tWidgetWin *Info, int Len, const tWidgetMsg_SetSize *Msg) +int Widget_IPC_SetSize(tWindow *Win, size_t Len, const void *Data) { + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_SetSize *Msg = Data; tElement *ele; if( Len < sizeof(*Msg) ) - return ; + return -1; ele = Widget_GetElementById(Info, Msg->WidgetID); - if(!ele) return ; + if(!ele) return 1; ele->FixedWith = Msg->Value; + return 0; } -void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) +int Widget_IPC_SetText(tWindow *Win, size_t Len, const void *Data) { + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_SetText *Msg = Data; tElement *ele; if( Len < sizeof(*Msg) + 1 ) - return ; + return -1; if( Msg->Text[Len - sizeof(*Msg) - 1] != '\0' ) - return ; + return -1; ele = Widget_GetElementById(Info, Msg->WidgetID); - if(!ele) return ; - + if(!ele) return 1; if( gaWM_WidgetTypes[ele->Type]->UpdateText ) { @@ -576,22 +620,23 @@ void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) // if(ele->Text) free(ele->Text); // ele->Text = strdup(Msg->Text); // } + return 0; } -int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) +int Widget_IPC_GetText(tWindow *Win, size_t Len, const void *Data) { + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_SetText *Msg = Data; if( Len < sizeof(*Msg) ) - return 0; - if( Len > sizeof(*Msg) ) - return 1; // Pass to user + return -1; const char *text = NULL; tElement *ele = Widget_GetElementById(Info, Msg->WidgetID); if(ele) text = ele->Text; - char buf[sizeof(tWidgetMsg_SetText) + strlen(text?text:"") + 1]; - tWidgetMsg_SetText *omsg = (void*)buf; + char buf[sizeof(tWidgetIPC_SetText) + strlen(text?text:"") + 1]; + tWidgetIPC_SetText *omsg = (void*)buf; if( text ) { omsg->WidgetID = Msg->WidgetID; @@ -602,7 +647,7 @@ int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) omsg->Text[0] = 0; } - WM_SendMessage(Info->RootElement.Window, Info->RootElement.Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf); + WM_SendIPCReply(Win, IPC_WIDGET_GETTEXT, sizeof(buf), buf); return 0; } @@ -711,46 +756,6 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void } return 0; } - // New Widget - case MSG_WIDGET_CREATE: - Widget_NewWidget(info, Len, Data); - return 0; - case MSG_WIDGET_CREATESUBWIN: - Widget_NewWidgetSubwin(info, Len, Data); - return 0; - - // Delete a widget - case MSG_WIDGET_DELETE: - _SysDebug("TODO: Implement MSG_WIDGET_DELETE"); - return 0; - - // Set focused widget - case MSG_WIDGET_SETFOCUS: { - tElement *ele; - const tWidgetMsg_SetFocus *msg = Data; - if(Len < sizeof(*msg)) return -1; - - ele = Widget_GetElementById(info, msg->WidgetID); - Widget_SetFocus(info, ele); - return 0; } - - // Set Flags - case MSG_WIDGET_SETFLAGS: - Widget_SetFlags(info, Len, Data); - return 0; - - // Set length - case MSG_WIDGET_SETSIZE: - Widget_SetSize(info, Len, Data); - return 0; - - // Set text - case MSG_WIDGET_SETTEXT: - Widget_SetText(info, Len, Data); - return 0; - case MSG_WIDGET_GETTEXT: - return Widget_GetText(info, Len, Data); - // default: return 1; // Unhandled, pass to user diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c index fe944e3a..4afe1dc8 100644 --- a/Usermode/Applications/axwin3_src/WM/wm.c +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -15,6 +15,7 @@ // === IMPORTS === extern void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int Msg, int Len, const void *Data); +extern void IPC_SendReply(tIPC_Client *Client, uint32_t WinID, int MsgID, size_t Len, const void *Data); extern tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t ID); // === GLOBALS === @@ -331,6 +332,12 @@ int WM_SendMessage(tWindow *Source, tWindow *Dest, int Message, int Length, cons return 1; } +int WM_SendIPCReply(tWindow *Window, int Message, size_t Length, const void *Data) +{ + IPC_SendReply(Window->Client, Window->ID, Message, Length, Data); + return 0; +} + void WM_Invalidate(tWindow *Window) { if(!Window) return ; diff --git a/Usermode/Applications/axwin3_src/include/framebuffer_messages.h b/Usermode/Applications/axwin3_src/include/framebuffer_messages.h index 034999b8..7b2a0494 100644 --- a/Usermode/Applications/axwin3_src/include/framebuffer_messages.h +++ b/Usermode/Applications/axwin3_src/include/framebuffer_messages.h @@ -8,21 +8,22 @@ #ifndef _AXWIN3__FRAMEBUFFER_MESSAGES_H_ #define _AXWIN3__FRAMEBUFFER_MESSAGES_H_ -enum +enum eFrameBuffer_IPCCalls { - MSG_FB_COMMIT = 0x1000, - MSG_FB_NEWBUF, - MSG_FB_UPLOAD, - MSG_FB_DOWNLOAD, - MSG_FB_BLIT, - MSG_FB_FILL + IPC_FB_COMMIT, + IPC_FB_NEWBUF, + IPC_FB_UPLOAD, + IPC_FB_DOWNLOAD, // Replies with requested data + IPC_FB_BLIT, + IPC_FB_FILL, + N_IPC_FB }; typedef struct { uint16_t Buffer; uint16_t W, H; -} tFBMsg_NewBuf; +} tFBIPC_NewBuf; typedef struct { @@ -30,7 +31,7 @@ typedef struct uint16_t W, H; uint16_t X, Y; uint32_t ImageData[]; -} tFBMsg_Transfer; +} tFBIPC_Transfer; typedef struct { @@ -39,7 +40,7 @@ typedef struct uint16_t SrcX, SrcY; uint16_t DstX, DstY; uint16_t W, H; -} tFBMsg_Blit; +} tFBIPC_Blit; typedef struct { @@ -47,7 +48,7 @@ typedef struct uint16_t X, Y; uint16_t W, H; uint32_t Colour; -} tFBMsg_Fill; +} tFBIPC_Fill; #endif diff --git a/Usermode/Applications/axwin3_src/include/ipcmessages.h b/Usermode/Applications/axwin3_src/include/ipcmessages.h index 6e61ba8e..50a9955b 100644 --- a/Usermode/Applications/axwin3_src/include/ipcmessages.h +++ b/Usermode/Applications/axwin3_src/include/ipcmessages.h @@ -28,6 +28,8 @@ typedef struct sIPCMsg_RetDisplayDims tIPCMsg_RetDisplayDims; */ //! Request a return value #define IPCMSG_FLAG_RETURN 0x01 +//! IPC Message for renderer +#define IPCMSG_FLAG_RENDERER 0x80 /** * \} */ diff --git a/Usermode/Applications/axwin3_src/include/menu_messages.h b/Usermode/Applications/axwin3_src/include/menu_messages.h index 04dcd2da..12d7ba5a 100644 --- a/Usermode/Applications/axwin3_src/include/menu_messages.h +++ b/Usermode/Applications/axwin3_src/include/menu_messages.h @@ -10,12 +10,11 @@ #include "ipcmessages.h" -enum eMenuMessages +// Client->Server IPC methods +enum eMenuIPCCalls { - MSG_MENU_ADDITEM = 0x1000, - MSG_MENU_SETFLAGS, - - MSG_MENU_SELECT + IPC_MENU_ADDITEM, + IPC_MENU_SETFLAGS }; typedef struct @@ -24,14 +23,20 @@ typedef struct uint16_t Flags; uint32_t SubMenuID; char Label[]; -} tMenuMsg_AddItem; +} tMenuIPC_AddItem; typedef struct { uint16_t ID; uint16_t Value; uint16_t Mask; -} tMenuMsg_SetFlags; +} tMenuIPC_SetFlags; + +// Server->Client messages +enum eMenuMessages +{ + MSG_MENU_SELECT = 0x1000 +}; typedef struct { diff --git a/Usermode/Applications/axwin3_src/include/richtext_messages.h b/Usermode/Applications/axwin3_src/include/richtext_messages.h index a440592c..7f53eb21 100644 --- a/Usermode/Applications/axwin3_src/include/richtext_messages.h +++ b/Usermode/Applications/axwin3_src/include/richtext_messages.h @@ -19,41 +19,55 @@ enum eRichText_Attrs { _ATTR_CURSORPOS, }; -enum +enum eRichText_IPCCalls { - // Calls - MSG_RICHTEXT_SETATTR, - MSG_RICHTEXT_SETFONT, - MSG_RICHTEXT_DELLINE, - MSG_RICHTEXT_ADDLINE, - - // Events - MSG_RICHTEXT_KEYPRESS, - MSG_RICHTEXT_MOUSEBTN, - - // Bi-directional messages - // - Sent by server to get a line that is not cached - // - Sent by client to read line contents - MSG_RICHTEXT_REQLINE, - // - Response to _REQLINE - MSG_RICHTEXT_SENDLINE, + IPC_RICHTEXT_SETATTR, + IPC_RICHTEXT_SETFONT, + IPC_RICHTEXT_DELLINE, + IPC_RICHTEXT_ADDLINE, + IPC_RICHTEXT_WRITELINE, // Set line contents + IPC_RICHTEXT_READLINE, // Request line contents + N_IPC_RICHTEXT }; -struct sRichTextMsg_SetAttr +struct sRichTextIPC_SetAttr { uint32_t Attr; uint32_t Value; }; -struct sRichTextMsg_SetFont +struct sRichTextIPC_SetFont { uint16_t Size; char Name[]; }; -struct sRichTextMsg_AddDelLine +struct sRichTextIPC_AddDelLine +{ + uint32_t Line; +}; + +struct sRichTextIPC_ReadLine +{ + uint32_t Line; +}; + +struct sRichTextIPC_WriteLine { uint32_t Line; + char LineData[]; +}; + +enum +{ + // Events + MSG_RICHTEXT_KEYPRESS = 0x1000, + MSG_RICHTEXT_MOUSEBTN, + + // Sent by server to get a line that is not cached (expects IPC WRITELINE) + MSG_RICHTEXT_REQLINE, + // Response to IPC READLINE + MSG_RICHTEXT_LINEDATA, }; struct sRichTextMsg_ReqLine @@ -61,7 +75,7 @@ struct sRichTextMsg_ReqLine uint32_t Line; }; -struct sRichTextMsg_SendLine +struct sRichTextMsg_LineData { uint32_t Line; char LineData[]; diff --git a/Usermode/Applications/axwin3_src/include/widget_messages.h b/Usermode/Applications/axwin3_src/include/widget_messages.h index f36c729c..6064d6f2 100644 --- a/Usermode/Applications/axwin3_src/include/widget_messages.h +++ b/Usermode/Applications/axwin3_src/include/widget_messages.h @@ -8,29 +8,23 @@ #ifndef _WIDGET_MESSAGES_H_ #define _WIDGET_MESSAGES_H_ -enum +enum eWidgetIPCCalls { // Control (Client->Server) messages - MSG_WIDGET_CREATE = 0x1000, - MSG_WIDGET_CREATESUBWIN, - MSG_WIDGET_DELETE, - MSG_WIDGET_SETFOCUS, - MSG_WIDGET_SETFLAGS, - MSG_WIDGET_SETSIZE, - MSG_WIDGET_SETTEXT, - MSG_WIDGET_SETCOLOUR, + IPC_WIDGET_CREATE, + IPC_WIDGET_CREATESUBWIN, + IPC_WIDGET_DELETE, + IPC_WIDGET_SETFOCUS, + IPC_WIDGET_SETFLAGS, + IPC_WIDGET_SETSIZE, + IPC_WIDGET_SETTEXT, + IPC_WIDGET_SETCOLOUR, - - // Request (Client->Server->Client) messages - MSG_WIDGET_GETTEXT, - - // Event (Server->Client) messages - MSG_WIDGET_FIRE, - MSG_WIDGET_KEYPRESS, - MSG_WIDGET_MOUSEBTN, + IPC_WIDGET_GETTEXT, + + N_IPC_WIDGET }; - typedef struct { uint32_t Parent; @@ -38,7 +32,7 @@ typedef struct uint32_t Type; uint32_t Flags; char DebugName[]; -} tWidgetMsg_Create; +} tWidgetIPC_Create; typedef struct { @@ -48,43 +42,53 @@ typedef struct uint32_t Flags; uint32_t WindowHandle; char DebugName[]; -} tWidgetMsg_CreateSubWin; +} tWidgetIPC_CreateSubWin; typedef struct { uint32_t WidgetID; -} tWidgetMsg_Delete; +} tWidgetIPC_Delete; typedef struct { uint32_t WidgetID; -} tWidgetMsg_SetFocus; +} tWidgetIPC_SetFocus; typedef struct { uint32_t WidgetID; uint32_t Value; uint32_t Mask; -} tWidgetMsg_SetFlags; +} tWidgetIPC_SetFlags; typedef struct { uint32_t WidgetID; uint32_t Value; -} tWidgetMsg_SetSize; +} tWidgetIPC_SetSize; typedef struct { uint32_t WidgetID; char Text[]; -} tWidgetMsg_SetText; +} tWidgetIPC_SetText; typedef struct { uint32_t WidgetID; uint32_t Index; uint32_t Colour; -} tWidgetMsg_SetColour; +} tWidgetIPC_SetColour; + +enum eWidgetMessages +{ + // Event (Server->Client) messages + MSG_WIDGET_FIRE = 0x1000, + MSG_WIDGET_KEYPRESS, + MSG_WIDGET_MOUSEBTN, +}; + + typedef struct { diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/include/internal.h b/Usermode/Applications/axwin3_src/libaxwin3.so_src/include/internal.h index 913cf35c..19ee8fd0 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/include/internal.h +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/include/internal.h @@ -22,6 +22,8 @@ struct sAxWin3_Window extern void *AxWin3_int_GetDataPtr(tHWND Window); extern uint32_t AxWin3_int_GetWindowID(tHWND Window); +extern void AxWin3_SendIPC(tHWND Window, int Message, size_t Length, const void *Data); +extern void *AxWin3_WaitIPCMessage(tHWND Window, int Message, size_t *Length); #endif diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_menu.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_menu.c index 1a6bfdf0..4b7bb562 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_menu.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_menu.c @@ -96,7 +96,7 @@ tAxWin3_MenuItem *AxWin3_Menu_AddItem( ret->SubMenu = SubMenu; { - tMenuMsg_AddItem *req; + tMenuIPC_AddItem *req; int data_size; if(!Label) Label = ""; data_size = sizeof(*req)+strlen(Label)+1; @@ -105,7 +105,7 @@ tAxWin3_MenuItem *AxWin3_Menu_AddItem( req->Flags = Flags; req->SubMenuID = AxWin3_int_GetWindowID(SubMenu); strcpy(req->Label, Label); - AxWin3_SendMessage(Menu, Menu, MSG_MENU_ADDITEM, data_size, req); + AxWin3_SendIPC(Menu, IPC_MENU_ADDITEM, data_size, req); free(req); } diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c index b1620dd2..fd1cf391 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c @@ -28,10 +28,10 @@ int AxWin3_RichText_MessageHandler(tHWND Window, int MessageID, int Size, void * static void _SendAttrib(tHWND Window, int Attr, uint32_t Value) { - struct sRichTextMsg_SetAttr msg; + struct sRichTextIPC_SetAttr msg; msg.Attr = Attr; msg.Value = Value; - AxWin3_SendMessage(Window, Window, MSG_RICHTEXT_SETATTR, sizeof(msg), &msg); + AxWin3_SendIPC(Window, IPC_RICHTEXT_SETATTR, sizeof(msg), &msg); } tHWND AxWin3_RichText_CreateWindow(tHWND Parent, int Flags) @@ -95,12 +95,12 @@ void AxWin3_RichText_SetCursorPos(tHWND Window, int Row, int Column) void AxWin3_RichText_SendLine(tHWND Window, int Line, const char *Text) { // TODO: Local sanity check on `Line`? - struct sRichTextMsg_SendLine *msg; + struct sRichTextIPC_WriteLine *msg; size_t len = sizeof(*msg) + strlen(Text) + 1; char buffer[len]; msg = (void*)buffer; msg->Line = Line; strcpy(msg->LineData, Text); - AxWin3_SendMessage(Window, Window, MSG_RICHTEXT_SENDLINE, len, msg); + AxWin3_SendIPC(Window, IPC_RICHTEXT_WRITELINE, len, msg); } diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c index c050e90c..62e42779 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c @@ -63,10 +63,10 @@ uint32_t AxWin3_Widget_int_AllocateID(tWidgetWindowInfo *Info) Info->Elements = realloc(Info->Elements, sizeof(*Info->Elements)*Info->nElements); newID = Info->nElements - 4; memset( &Info->Elements[newID+1], 0, (size_step-1)*sizeof(Info->Elements)); - _SysDebug("Expanded to %i and allocated %i", Info->nElements, newID); + _SysDebug("Widget: Expanded to %i and allocated %i", Info->nElements, newID); } else - _SysDebug("Allocated %i", newID); + _SysDebug("Widget: Allocated %i", newID); Info->Elements[newID] = (void*)-1; return newID; @@ -85,7 +85,7 @@ int AxWin3_Widget_MessageHandler(tHWND Window, int MessageID, int Size, void *Da widget = AxWin3_Widget_int_GetElementByID(Window, msg->WidgetID); if(widget->Fire) widget->Fire(widget); - return 0; } + return 1; } default: return 0; } @@ -146,14 +146,14 @@ tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Fl // Send create widget message { - char tmp[sizeof(tWidgetMsg_Create)+1]; - tWidgetMsg_Create *msg = (void*)tmp; + char tmp[sizeof(tWidgetIPC_Create)+1]; + tWidgetIPC_Create *msg = (void*)tmp; msg->Parent = Parent->ID; msg->NewID = newID; msg->Type = Type; msg->Flags = Flags; msg->DebugName[0] = '\0'; - AxWin3_SendMessage(ret->Window, ret->Window, MSG_WIDGET_CREATE, sizeof(tmp), tmp); + AxWin3_SendIPC(ret->Window, IPC_WIDGET_CREATE, sizeof(tmp), tmp); } return ret; @@ -171,15 +171,15 @@ tAxWin3_Widget *AxWin3_Widget_AddWidget_SubWindow(tAxWin3_Widget *Parent, tHWND // Send message { - char tmp[sizeof(tWidgetMsg_CreateSubWin)+1]; - tWidgetMsg_CreateSubWin *msg = (void*)tmp; + char tmp[sizeof(tWidgetIPC_CreateSubWin)+1]; + tWidgetIPC_CreateSubWin *msg = (void*)tmp; msg->Parent = Parent->ID; msg->NewID = newID; msg->Type = ELETYPE_SUBWIN; msg->Flags = Flags; // TODO: Flags msg->WindowHandle = AxWin3_int_GetWindowID(Window); msg->DebugName[0] = '\0'; - AxWin3_SendMessage(ret->Window, ret->Window, MSG_WIDGET_CREATESUBWIN, sizeof(tmp), tmp); + AxWin3_SendIPC(ret->Window, IPC_WIDGET_CREATESUBWIN, sizeof(tmp), tmp); } return ret; @@ -188,11 +188,11 @@ tAxWin3_Widget *AxWin3_Widget_AddWidget_SubWindow(tAxWin3_Widget *Parent, tHWND void AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget) { - tWidgetMsg_Delete msg; + tWidgetIPC_Delete msg; tWidgetWindowInfo *info = AxWin3_int_GetDataPtr(Widget->Window); msg.WidgetID = Widget->ID; - AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_DELETE, sizeof(msg), &msg); + AxWin3_SendIPC(Widget->Window, IPC_WIDGET_DELETE, sizeof(msg), &msg); info->Elements[Widget->ID] = NULL; if(Widget->ID < info->FirstFreeID) @@ -234,45 +234,45 @@ void AxWin3_Widget_SetMouseButtonHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_ // --- Manipulation void AxWin3_Widget_SetFlags(tAxWin3_Widget *Widget, int FlagSet, int FlagMask) { - tWidgetMsg_SetFlags msg; + tWidgetIPC_SetFlags msg; msg.WidgetID = Widget->ID; msg.Value = FlagSet; msg.Mask = FlagMask; - AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETFLAGS, sizeof(msg), &msg); + AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETFLAGS, sizeof(msg), &msg); } void AxWin3_Widget_SetSize(tAxWin3_Widget *Widget, int Size) { - tWidgetMsg_SetSize msg; + tWidgetIPC_SetSize msg; msg.WidgetID = Widget->ID; msg.Value = Size; - AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETSIZE, sizeof(msg), &msg); + AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETSIZE, sizeof(msg), &msg); } void AxWin3_Widget_SetText(tAxWin3_Widget *Widget, const char *Text) { - char buf[sizeof(tWidgetMsg_SetText) + strlen(Text) + 1]; - tWidgetMsg_SetText *msg = (void*)buf; + char buf[sizeof(tWidgetIPC_SetText) + strlen(Text) + 1]; + tWidgetIPC_SetText *msg = (void*)buf; msg->WidgetID = Widget->ID; strcpy(msg->Text, Text); - AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETTEXT, sizeof(buf), buf); + AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETTEXT, sizeof(buf), buf); } char *AxWin3_Widget_GetText(tAxWin3_Widget *Widget) { - char buf[sizeof(tWidgetMsg_SetText)]; - tWidgetMsg_SetText *msg = (void*)buf; + char buf[sizeof(tWidgetIPC_SetText)]; + tWidgetIPC_SetText *msg = (void*)buf; size_t retmsg_size; msg->WidgetID = Widget->ID; - AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf); + AxWin3_SendIPC(Widget->Window, IPC_WIDGET_GETTEXT, sizeof(buf), buf); - msg = AxWin3_WaitMessage(Widget->Window, MSG_WIDGET_GETTEXT, &retmsg_size); + msg = AxWin3_WaitIPCMessage(Widget->Window, IPC_WIDGET_GETTEXT, &retmsg_size); if( retmsg_size < sizeof(*msg) ) { free(msg); return NULL; @@ -285,10 +285,10 @@ char *AxWin3_Widget_GetText(tAxWin3_Widget *Widget) void AxWin3_Widget_SetColour(tAxWin3_Widget *Widget, int Index, tAxWin3_Colour Colour) { - tWidgetMsg_SetColour msg; + tWidgetIPC_SetColour msg; msg.WidgetID = Widget->ID; msg.Index = Index; msg.Colour = Colour; - AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETCOLOUR, sizeof(msg), &msg); + AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETCOLOUR, sizeof(msg), &msg); } diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c index 412f5832..53208f2d 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c @@ -127,7 +127,7 @@ int AxWin3_GetDisplayDims(int Display, int *X, int *Y, int *Width, int *Height) ret = (void*)msg->Data; if(X) *X = ret->X; - if(X) *X = ret->Y; + if(Y) *Y = ret->Y; if(Width) *Width = ret->W; if(Height) *Height = ret->H; @@ -161,6 +161,8 @@ tHWND AxWin3_CreateWindow( AxWin3_int_SendIPCMessage(msg); free(msg); + _SysDebug("AxWin3_CreateWindow: %i :: '%s'", newWinID, Renderer); + // TODO: Detect and handle possible errors // Return success @@ -217,7 +219,7 @@ void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg) gAxWin3_Hotkeys[mi->ID](); }break; default: - _SysDebug("--- Unhandled SENDMSG %i", info->ID); + _SysDebug("--- Unhandled SENDMSG 0x%x win %i", info->ID, Msg->Window); break; } } @@ -285,6 +287,36 @@ void *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length) } } +void AxWin3_SendIPC(tHWND Window, int Message, size_t Length, const void *Data) +{ + tAxWin_IPCMessage *msg; + + msg = AxWin3_int_AllocateIPCMessage(Window, Message, IPCMSG_FLAG_RENDERER, Length); + memcpy(msg->Data, Data, Length); + AxWin3_int_SendIPCMessage(msg); + free(msg); +} + +void *AxWin3_WaitIPCMessage(tHWND Window, int MessageID, size_t *Length) +{ + tAxWin_IPCMessage *msg; + for( ;; ) + { + msg = AxWin3_int_WaitIPCMessage(MessageID); + if( !(msg->Flags & IPCMSG_FLAG_RENDERER) || msg->Window != AxWin3_int_GetWindowID(Window) ) { + AxWin3_int_HandleMessage(msg); + continue ; + } + + *Length = msg->Size; + void *ret = malloc(msg->Size); + memcpy(ret, msg->Data, msg->Size); + free(msg); + + return ret; + } +} + void AxWin3_FocusWindow(tHWND Window) { tAxWin_IPCMessage *msg;