From 58a0f278ca687c7ed28f4fd212123db2f056ffec Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 4 Nov 2011 19:01:55 +0800 Subject: [PATCH] Usermode/AxWin3 - Implementing window creation --- .../Applications/axwin3_src/Interface/main.c | 15 +- .../axwin3_src/WM/include/ipcmessages.h | 23 ++- Usermode/Applications/axwin3_src/WM/ipc.c | 4 +- Usermode/Applications/axwin3_src/WM/main.c | 4 +- .../axwin3_src/WM/renderer_widget.c | 2 +- Usermode/Applications/axwin3_src/WM/wm.c | 23 ++- Usermode/Libraries/libaxwin3.so_src/wm.c | 152 ++++++++++++++---- Usermode/include/axwin3/axwin.h | 9 +- 8 files changed, 186 insertions(+), 46 deletions(-) diff --git a/Usermode/Applications/axwin3_src/Interface/main.c b/Usermode/Applications/axwin3_src/Interface/main.c index f56cd699..698b2d49 100644 --- a/Usermode/Applications/axwin3_src/Interface/main.c +++ b/Usermode/Applications/axwin3_src/Interface/main.c @@ -12,6 +12,11 @@ tHWND gSidebar; // === CODE === +int sidebar_callback(tHWND Window, int Length, void *Data) +{ + return 0; +} + int main(int argc, char *argv[]) { // Connect to AxWin3 Server @@ -19,8 +24,16 @@ int main(int argc, char *argv[]) // Create sidebar // TODO: Use the widget library instead - gSidebar = AxWin3_CreateWindow(NULL, "widget", 0, 0, NULL); + gSidebar = AxWin3_CreateWindow(NULL, "Widget", 0, 0, NULL, sidebar_callback); + + // TODO: Get screen dimensions somehow + + // Size the window + AxWin3_SetWindowPos(gSidebar, 0, 0, 32, 600); + // Show! + AxWin3_ShowWindow(gSidebar, 1); + // Idle loop AxWin3_MainLoop(); diff --git a/Usermode/Applications/axwin3_src/WM/include/ipcmessages.h b/Usermode/Applications/axwin3_src/WM/include/ipcmessages.h index 29c8b69f..b0cf14ea 100644 --- a/Usermode/Applications/axwin3_src/WM/include/ipcmessages.h +++ b/Usermode/Applications/axwin3_src/WM/include/ipcmessages.h @@ -14,6 +14,8 @@ typedef struct sAxWin_IPCMessage tAxWin_IPCMessage; typedef struct sIPCMsg_Return tIPCMsg_Return; typedef struct sIPCMsg_CreateWin tIPCMsg_CreateWin; +typedef struct sIPCMsg_ShowWindow tIPCMsg_ShowWindow; +typedef struct sIPCMsg_SetWindowPos tIPCMsg_SetWindowPos; /** * \name Flags for IPC Messages @@ -46,11 +48,28 @@ struct sIPCMsg_CreateWin char Renderer[]; }; +struct sIPCMsg_ShowWindow +{ + uint32_t bShow; +}; + +struct sIPCMsg_SetWindowPos +{ + int16_t X; + int16_t Y; + uint16_t W; + uint16_t H; + uint8_t Fields; +}; + enum eAxWin_IPCMessageTypes { - IPCMSG_PING, //!< - IPCMSG_SENDMSG, //!< Send a message to another window + IPCMSG_PING, //!< Get the server version + IPCMSG_SENDMSG, //!< Send a message to another window (or to self) IPCMSG_CREATEWIN, //!< Create a window + IPCMSG_DESTROYWIN, //!< Destroy a window + IPCMSG_SHOWWINDOW, //!< Show/Hide a window + IPCMSG_SETWINPOS, //!< Set a window position }; #endif diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index e07b1e0b..d8420710 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -311,10 +311,12 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW IPC_Msg_CreateWin(client, Msg); break; +// case IPCMSG_SHOWWINDOW: + // --- Unknown message default: fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType); - _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType); + _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType); break; } } diff --git a/Usermode/Applications/axwin3_src/WM/main.c b/Usermode/Applications/axwin3_src/WM/main.c index 0b63a183..0562d7d5 100644 --- a/Usermode/Applications/axwin3_src/WM/main.c +++ b/Usermode/Applications/axwin3_src/WM/main.c @@ -55,7 +55,6 @@ int main(int argc, char *argv[]) Input_Init(); Renderer_Widget_Init(); -// WM_Update(); // Spawn interface root if( clone(CLONE_VM, 0) == 0 ) @@ -66,6 +65,7 @@ int main(int argc, char *argv[]) char *argv[] = {csInterfaceApp, NULL}; sprintf(server_info, "AXWIN3_SERVER=%i", server_tid); execve(csInterfaceApp, argv, envp); + exit(1); } // Main Loop @@ -75,6 +75,8 @@ int main(int argc, char *argv[]) int nfds = 0; FD_ZERO(&fds); + WM_Update(); + Input_FillSelect(&nfds, &fds); IPC_FillSelect(&nfds, &fds); diff --git a/Usermode/Applications/axwin3_src/WM/renderer_widget.c b/Usermode/Applications/axwin3_src/WM/renderer_widget.c index 7f0cb0ea..6da79e39 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderer_widget.c @@ -67,7 +67,7 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) // === GLOBALS === tWMRenderer gRenderer_Widget = { - .Name = "Classful", + .Name = "Widget", .CreateWindow = Renderer_Widget_Create, .Redraw = Renderer_Widget_Redraw, .HandleMessage = Renderer_Widget_HandleMessage diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c index 355229df..2ae73fdd 100644 --- a/Usermode/Applications/axwin3_src/WM/wm.c +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -16,8 +16,7 @@ tWMRenderer *gpWM_Renderers; // === CODE === void WM_RegisterRenderer(tWMRenderer *Renderer) { - // TODO: Catch re-adding the first somehow? - if(Renderer->Next) return; + // TODO: Catch out duplicates Renderer->Next = gpWM_Renderers; gpWM_Renderers = Renderer; } @@ -51,8 +50,28 @@ tWindow *WM_CreateWindowStruct(size_t ExtraSize) return calloc( sizeof(tWindow) + ExtraSize, 1 ); } +void WM_Update(void) +{ + // - Iterate through visible windows, updating them as needed + + // - Draw windows from back to front to the render buffer + + // - Blit the buffer to the screen +} + void WM_Render_FilledRect(tWindow *Window, tColour Colour, int X, int Y, int W, int H) { + // Clip to window dimensions + if(X < 0) { W += X; X = 0; } + if(Y < 0) { H += Y; Y = 0; } + if(X >= Window->W) return; + if(Y >= Window->H) return; + if(X + W > Window->W) W = Window->W - X; + if(Y + H > Window->H) H = Window->H - Y; + + // Render to buffer + // Create if needed? + UNIMPLEMENTED(); } diff --git a/Usermode/Libraries/libaxwin3.so_src/wm.c b/Usermode/Libraries/libaxwin3.so_src/wm.c index 7315c05a..9f15ad7e 100644 --- a/Usermode/Libraries/libaxwin3.so_src/wm.c +++ b/Usermode/Libraries/libaxwin3.so_src/wm.c @@ -40,7 +40,49 @@ tWindow *AxWin3_int_CreateWindowStruct(uint32_t ServerID, int ExtraBytes) return ret; } -tHWND AxWin3_CreateWindow(tHWND Parent, const char *Renderer, int Flags, int DataBytes, void **DataPtr) +tWindow *AxWin3_int_AllocateWindowInfo(int DataBytes, int *WinID) +{ + int idx, newWinID; + tWindowBlock *block, *prev; + tWindow *ret; + + block = &gAxWin3_WindowList; + newWinID = giAxWin3_LowestFreeWinID; + for( idx = 0; block; newWinID ++ ) + { + if( block->Windows[idx] == NULL ) + break; + idx ++; + if(idx == WINDOWS_PER_ALLOC) { + prev = block; + block = block->Next; + idx = 0; + } + } + + if( !block ) + { + block = calloc(sizeof(tWindowBlock), 1); + prev->Next = block; + idx = 0; + } + + ret = block->Windows[idx] = AxWin3_int_CreateWindowStruct(newWinID, DataBytes); + if(newWinID > giAxWin3_HighestUsedWinID) + giAxWin3_HighestUsedWinID = newWinID; + if(newWinID == giAxWin3_LowestFreeWinID) + giAxWin3_HighestUsedWinID ++; + + if(WinID) *WinID = newWinID; + + return ret; +} + +tHWND AxWin3_CreateWindow( + tHWND Parent, const char *Renderer, int Flags, + int DataBytes, void **DataPtr, + tAxWin3_WindowMessageHandler MessageHandler + ) { tWindow *ret; int newWinID; @@ -48,40 +90,10 @@ tHWND AxWin3_CreateWindow(tHWND Parent, const char *Renderer, int Flags, int Dat tAxWin_IPCMessage *msg; tIPCMsg_CreateWin *create_win; - // TODO: Validate `Parent` - // Allocate a window ID - { - int idx; - tWindowBlock *block, *prev; - block = &gAxWin3_WindowList; - newWinID = giAxWin3_LowestFreeWinID; - for( idx = 0; block; newWinID ++ ) - { - if( block->Windows[idx] == NULL ) - break; - idx ++; - if(idx == WINDOWS_PER_ALLOC) { - prev = block; - block = block->Next; - idx = 0; - } - } - - if( !block ) - { - block = calloc(sizeof(tWindowBlock), 1); - prev->Next = block; - idx = 0; - } - - ret = block->Windows[idx] = AxWin3_int_CreateWindowStruct(newWinID, DataBytes); - - if(newWinID > giAxWin3_HighestUsedWinID) - giAxWin3_HighestUsedWinID = newWinID; - if(newWinID == giAxWin3_LowestFreeWinID) - giAxWin3_HighestUsedWinID ++; - } + ret = AxWin3_int_AllocateWindowInfo(DataBytes, &newWinID); + if(!ret) return NULL; + ret->Handler = MessageHandler; // Create message msg = AxWin3_int_AllocateIPCMessage(Parent, IPCMSG_CREATEWIN, 0, dataSize); @@ -94,7 +106,7 @@ tHWND AxWin3_CreateWindow(tHWND Parent, const char *Renderer, int Flags, int Dat AxWin3_int_SendIPCMessage(msg); free(msg); - // TODO: Detect errors in AxWin3_CreateWindow + // TODO: Detect and handle possible errors // Return success if(DataPtr) *DataPtr = ret->Data; @@ -103,4 +115,74 @@ tHWND AxWin3_CreateWindow(tHWND Parent, const char *Renderer, int Flags, int Dat void AxWin3_DestroyWindow(tHWND Window) { + tAxWin_IPCMessage *msg; + + msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_DESTROYWIN, 0, 0); + AxWin3_int_SendIPCMessage(msg); + free(msg); +} + +void AxWin3_ShowWindow(tHWND Window, int bShow) +{ + tAxWin_IPCMessage *msg; + tIPCMsg_ShowWindow *info; + + msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SHOWWINDOW, 0, sizeof(*info)); + info = (void*)msg->Data; + info->bShow = !!bShow; + + AxWin3_int_SendIPCMessage(msg); + + free(msg); +} + +void AxWin3_SetWindowPos(tHWND Window, short X, short Y, short W, short H) +{ + tAxWin_IPCMessage *msg; + tIPCMsg_SetWindowPos *info; + + msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info)); + info = (void*)msg->Data; + + info->Fields = 0xF; + info->X = X; info->Y = Y; + info->W = W; info->H = H; + + AxWin3_int_SendIPCMessage(msg); + free(msg); +} + +void AxWin3_MoveWindow(tHWND Window, short X, short Y) +{ + tAxWin_IPCMessage *msg; + tIPCMsg_SetWindowPos *info; + + msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info)); + info = (void*)msg->Data; + + info->Fields = 0x3; + info->X = X; + info->Y = Y; + + AxWin3_int_SendIPCMessage(msg); + + free(msg); +} + +void AxWin3_ResizeWindow(tHWND Window, short W, short H) +{ + tAxWin_IPCMessage *msg; + tIPCMsg_SetWindowPos *info; + + msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info)); + info = (void*)msg->Data; + + info->Fields = 0xC; + info->W = W; + info->H = H; + + AxWin3_int_SendIPCMessage(msg); + + free(msg); } + diff --git a/Usermode/include/axwin3/axwin.h b/Usermode/include/axwin3/axwin.h index af5c242b..6564e23c 100644 --- a/Usermode/include/axwin3/axwin.h +++ b/Usermode/include/axwin3/axwin.h @@ -18,12 +18,15 @@ extern void AxWin3_Connect(const char *ServerDesc); extern tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback); extern void AxWin3_MainLoop(void); -extern tHWND AxWin3_CreateWindow(tHWND Parent, const char *Renderer, int Flags, int DataBytes, void **DataPtr); +extern tHWND AxWin3_CreateWindow(tHWND Parent, const char *Renderer, int Flags, int DataBytes, void **DataPtr, + tAxWin3_WindowMessageHandler MessageHandler); extern void AxWin3_DestroyWindow(tHWND Window); extern void AxWin3_SendMessage(tHWND Window, int Length, void *Data); -extern void AxWin3_SetWindowPos(tHWND Window, int X, int Y, int W, int H); -extern void AxWin3_SetWindowShown(tHWND Window, int bShow); +extern void AxWin3_ShowWindow(tHWND Window, int bShow); +extern void AxWin3_SetWindowPos(tHWND Window, short X, short Y, short W, short H); +extern void AxWin3_MoveWindow(tHWND Window, short X, short Y); +extern void AxWin3_ResizeWindow(tHWND Window, short W, short H); #endif -- 2.20.1