From e3b5f81f2af81fbb2f2b0f449f71324e63f9a645 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 18 Feb 2013 15:44:37 +0800 Subject: [PATCH] Usermode/axwin3 - Window destruction and client exit - NOTE: Server does not clean up client yet --- .../Applications/axwin3_src/WM/decorator.c | 3 ++ .../Applications/axwin3_src/WM/include/wm.h | 1 + .../axwin3_src/WM/include/wm_renderer.h | 6 +++ Usermode/Applications/axwin3_src/WM/ipc.c | 16 ++++++- Usermode/Applications/axwin3_src/WM/main.c | 2 + .../axwin3_src/WM/renderers/widget.c | 4 +- Usermode/Applications/axwin3_src/WM/wm.c | 46 +++++++++++++++++++ .../axwin3_src/libaxwin3.so_src/main.c | 16 +++++-- .../axwin3_src/libaxwin3.so_src/wm.c | 5 ++ Usermode/Applications/gui_ate_src/Makefile | 2 +- Usermode/Applications/gui_ate_src/main.c | 20 ++++++-- Usermode/Applications/gui_ate_src/strings.c | 27 ++++++++++- .../include_exp/axwin3/axwin.h | 3 +- 13 files changed, 137 insertions(+), 14 deletions(-) diff --git a/Usermode/Applications/axwin3_src/WM/decorator.c b/Usermode/Applications/axwin3_src/WM/decorator.c index 6600408a..d30eadcc 100644 --- a/Usermode/Applications/axwin3_src/WM/decorator.c +++ b/Usermode/Applications/axwin3_src/WM/decorator.c @@ -129,6 +129,9 @@ void Decorator_Redraw(tWindow *Window) ciSideBorderWidth*2+Window->W, ciBottomBorderWidth-1, cColour_BottomBorder ); + + // Buttons + // TODO: Conditional for each } int Decorator_HandleMessage(tWindow *Window, int Message, int Length, const void *Data) diff --git a/Usermode/Applications/axwin3_src/WM/include/wm.h b/Usermode/Applications/axwin3_src/WM/include/wm.h index e060e246..a4275c9f 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm.h @@ -47,6 +47,7 @@ typedef struct sIPC_Client tIPC_Client; // === FUNCTIONS === // --- Management extern tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int Flags, const char *Renderer); +extern void WM_DestroyWindow(tWindow *Window); extern tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID); extern void WM_Invalidate(tWindow *Window); extern void WM_SetWindowTitle(tWindow *Window, const char *Title); diff --git a/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h b/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h index 89aceb9f..f91ccaf9 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h @@ -31,6 +31,12 @@ struct sWMRenderer * set the copy in the window structure. */ tWindow *(*CreateWindow)(int Arg); + + /** + * \brief Clean up any stored info + * \param Window Window being destroyed + */ + void (*DestroyWindow)(tWindow *Window); /** * \brief Redraw a window on the screen diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index 7874335c..4bb753ee 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -406,6 +406,20 @@ int IPC_Msg_CreateWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg) return 0; } +int IPC_Msg_DestroyWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tWindow *win; + + ASSERT(Msg->ID == IPCMSG_DESTROYWIN); + + win = IPC_int_GetWindow(Client, Msg->Window); + if( !win ) + return 0; + + WM_DestroyWindow(win); + return 0; +} + int IPC_Msg_SetWindowTitle(tIPC_Client *Client, tAxWin_IPCMessage *Msg) { tWindow *win; @@ -525,7 +539,7 @@ int (*gIPC_MessageHandlers[])(tIPC_Client *Client, tAxWin_IPCMessage *Msg) = { IPC_Msg_GetDisplayDims, IPC_Msg_SendMsg, IPC_Msg_CreateWin, - NULL, // Destroy window + IPC_Msg_DestroyWin, // Destroy window IPC_Msg_SetWindowTitle, IPC_Msg_ShowWindow, IPC_Msg_DecorateWindow, diff --git a/Usermode/Applications/axwin3_src/WM/main.c b/Usermode/Applications/axwin3_src/WM/main.c index 9db1c15c..1d833148 100644 --- a/Usermode/Applications/axwin3_src/WM/main.c +++ b/Usermode/Applications/axwin3_src/WM/main.c @@ -72,6 +72,8 @@ int main(int argc, char *argv[]) WM_Hotkey_Register(2, keys, "Interface>Run"); keys[0] = KEYSYM_LEFTGUI; keys[1] = KEYSYM_t; WM_Hotkey_Register(2, keys, "Interface>Terminal"); + keys[0] = KEYSYM_LEFTGUI; keys[1] = KEYSYM_e; + WM_Hotkey_Register(2, keys, "Interface>TextEdit"); // Spawn interface root { diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget.c b/Usermode/Applications/axwin3_src/WM/renderers/widget.c index 49f1f646..247152d7 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget.c @@ -249,7 +249,7 @@ void Widget_UpdateDimensions(tElement *Element) if( child->Flags & ELEFLAG_ABSOLUTEPOS ) continue ; // --- Width --- - if( child->Flags & ELEFLAG_NOEXPAND ) + if( child->Flags & (bVertical ? ELEFLAG_NOEXPAND : ELEFLAG_NOSTRETCH) ) w = child->MinW; else if( bVertical ) w = child->FixedCross ? child->FixedCross : fullCross; @@ -257,7 +257,7 @@ void Widget_UpdateDimensions(tElement *Element) w = child->FixedWith ? child->FixedWith : dynWith; // --- Height --- - if( child->Flags & ELEFLAG_NOSTRETCH ) + if( child->Flags & (bVertical ? ELEFLAG_NOSTRETCH : ELEFLAG_NOEXPAND) ) h = child->MinH; else if( bVertical ) h = child->FixedWith ? child->FixedWith : dynWith; diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c index 8886af19..1de599b3 100644 --- a/Usermode/Applications/axwin3_src/WM/wm.c +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -94,6 +94,52 @@ tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int return ret; } +void WM_DestroyWindow(tWindow *Window) +{ + // TODO: Lock window and flag as invalid + + // - Remove from render tree + { + // TODO: Lock render tree? + tWindow *prev = Window->PrevSibling; + tWindow *next = Window->NextSibling; + if(prev) + prev->NextSibling = next; + else + Window->Parent->FirstChild = next; + if(next) + next->PrevSibling = prev; + else + Window->Parent->LastChild = prev; + } + WM_Invalidate(Window->Parent); + + // - Remove from inheritance tree? + + // - Clean up render children + // Lock should not be needed + tWindow *win, *next; + for( win = Window->FirstChild; win; win = next ) + { + next = win->NextSibling; + ASSERT(Window->FirstChild->Parent == Window); + WM_DestroyWindow(win); + } + + // - Clean up inheriting children? + + // - Tell renderer to clean up + if( Window->Renderer->DestroyWindow ) + Window->Renderer->DestroyWindow(Window); + else + _SysDebug("WARN: Renderer %s does not have a destroy function", Window->Renderer->Name); + + // - Clean up render cache and window structure + free(Window->Title); + free(Window->RenderBuffer); + free(Window); +} + tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID) { return IPC_int_GetWindow(Requester->Client, ID); diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/main.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/main.c index 453d4baa..da2ffe77 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/main.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/main.c @@ -10,6 +10,9 @@ #include "include/ipc.h" #include +// === GLOBALS === +int giAxWin3_MainLoopExit; + // === CODE === int SoMain(void *Base, int argc, const char *argv[], const char **envp) { @@ -18,12 +21,13 @@ int SoMain(void *Base, int argc, const char *argv[], const char **envp) return 0; } -void AxWin3_MainLoop(void) +int AxWin3_MainLoop(void) { tAxWin_IPCMessage *msg; - int bExit = 0; - while(!bExit) + giAxWin3_MainLoopExit = 0; + + while(!giAxWin3_MainLoopExit) { msg = AxWin3_int_GetIPCMessage(0, NULL); if(!msg) continue; @@ -33,6 +37,12 @@ void AxWin3_MainLoop(void) AxWin3_int_HandleMessage( msg ); } + return giAxWin3_MainLoopExit; +} + +void AxWin3_StopMainLoop(int Reason) +{ + giAxWin3_MainLoopExit = Reason; } void AxWin3_MessageSelect(int nFD, fd_set *FDs) diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c index 53208f2d..cb21b7fd 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c @@ -176,6 +176,8 @@ void AxWin3_DestroyWindow(tHWND Window) msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_DESTROYWIN, 0, 0); AxWin3_int_SendIPCMessage(msg); free(msg); + + free(ret); } void *AxWin3_int_GetDataPtr(tHWND Window) @@ -224,6 +226,9 @@ void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg) } } break; } + case IPCMSG_DESTROYWIN: + // Clean up resources associated with this window + break; default: _SysDebug("Unknow message ID %i", Msg->ID); break; diff --git a/Usermode/Applications/gui_ate_src/Makefile b/Usermode/Applications/gui_ate_src/Makefile index 569e1417..b52a551d 100644 --- a/Usermode/Applications/gui_ate_src/Makefile +++ b/Usermode/Applications/gui_ate_src/Makefile @@ -4,7 +4,7 @@ LDFLAGS += -laxwin3 -OBJ = main.o +OBJ = main.o strings.o BIN = ate DIR := Apps/AxWin/3.0 diff --git a/Usermode/Applications/gui_ate_src/main.c b/Usermode/Applications/gui_ate_src/main.c index 032a9685..ae8593e6 100644 --- a/Usermode/Applications/gui_ate_src/main.c +++ b/Usermode/Applications/gui_ate_src/main.c @@ -20,6 +20,7 @@ void add_toolbar_button(tAxWin3_Widget *Toolbar, const char *Ident, tAxWin3_Widg int Toolbar_New(tAxWin3_Widget *Widget); int Toolbar_Open(tAxWin3_Widget *Widget); int Toolbar_Save(tAxWin3_Widget *Widget); + int Toolbar_Close(tAxWin3_Widget *Widget); // === GLOBALS === tHWND gMainWindow; @@ -43,18 +44,20 @@ int main(int argc, char *argv[]) // TODO: Populate menu // Create toolbar - gMainWindow_Toolbar = AxWin3_Widget_AddWidget(gMainWindow_Root, ELETYPE_TOOLBAR, ELEFLAG_NOSTRETCH, "Toolbar"); + gMainWindow_Toolbar = AxWin3_Widget_AddWidget(gMainWindow_Root, + ELETYPE_TOOLBAR, ELEFLAG_NOSTRETCH, "Toolbar"); add_toolbar_button(gMainWindow_Toolbar, "BtnNew", Toolbar_New); add_toolbar_button(gMainWindow_Toolbar, "BtnOpen", Toolbar_Open); add_toolbar_button(gMainWindow_Toolbar, "BtnSave", Toolbar_Save); - AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, ""); + add_toolbar_button(gMainWindow_Toolbar, "BtnClose", Toolbar_Close); + AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, ""); add_toolbar_button(gMainWindow_Toolbar, "BtnUndo", NULL); add_toolbar_button(gMainWindow_Toolbar, "BtnRedo", NULL); - AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, ""); + AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, ""); add_toolbar_button(gMainWindow_Toolbar, "BtnCut", NULL); add_toolbar_button(gMainWindow_Toolbar, "BtnCopy", NULL); add_toolbar_button(gMainWindow_Toolbar, "BtnPaste", NULL); - AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, ""); + AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, ""); add_toolbar_button(gMainWindow_Toolbar, "BtnSearch", NULL); add_toolbar_button(gMainWindow_Toolbar, "BtnReplace", NULL); @@ -87,6 +90,8 @@ int main(int argc, char *argv[]) // Main loop AxWin3_MainLoop(); + AxWin3_DestroyWindow(gMainWindow); + return 0; } @@ -105,7 +110,7 @@ void add_toolbar_button(tAxWin3_Widget *Toolbar, const char *Ident, tAxWin3_Widg tAxWin3_Widget *btn = AxWin3_Widget_AddWidget(Toolbar, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, Ident); tAxWin3_Widget *txt = AxWin3_Widget_AddWidget(btn, ELETYPE_TEXT, 0, Ident); // TODO: Get image / text using `Ident` as a lookup key - AxWin3_Widget_SetText(txt, Ident); + AxWin3_Widget_SetText(txt, getstr(Ident)); AxWin3_Widget_SetFireHandler(btn, Callback); } @@ -121,4 +126,9 @@ int Toolbar_Save(tAxWin3_Widget *Widget) { return 0; } +int Toolbar_Close(tAxWin3_Widget *Widget) +{ + AxWin3_StopMainLoop(1); + return 0; +} diff --git a/Usermode/Applications/gui_ate_src/strings.c b/Usermode/Applications/gui_ate_src/strings.c index 5cfee5dd..a6999934 100644 --- a/Usermode/Applications/gui_ate_src/strings.c +++ b/Usermode/Applications/gui_ate_src/strings.c @@ -5,6 +5,8 @@ * strings.c * - String Localisation */ +#include "strings.h" +#include struct keyval_str { @@ -16,6 +18,29 @@ const struct keyval_str gaDisplayStrings[] = { {"BtnNew", "New"}, {"BtnOpen", "Open"}, {"BtnSave", "Save"}, - {"BtnUndo", "Undo"} + {"BtnClose", "Close"}, + {"BtnUndo", "Undo"}, + {"BtnRedo", "Redo"}, + {"BtnCut", "Cut"}, + {"BtnCopy", "Copy"}, + {"BtnPaste", "Paste"}, + {"BtnSearch", "Search"}, + {"BtnReplace", "Replace"}, }; +const int ciNumDisplayStrings = sizeof(gaDisplayStrings)/sizeof(gaDisplayStrings[0]); +const char *getstr(const char *key) +{ + int i; + for(i = 0; i < ciNumDisplayStrings; i ++) + { + if( strcmp(key, gaDisplayStrings[i].key) == 0 ) + return gaDisplayStrings[i].val; + } + return "-nostr-"; +} + +const char *getimg(const char *key) +{ + return ""; +} diff --git a/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/axwin.h b/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/axwin.h index 04abfaf9..437820c0 100644 --- a/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/axwin.h +++ b/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/axwin.h @@ -25,7 +25,8 @@ typedef int (*tAxWin3_WindowMessageHandler)(tHWND Window, int Message, int Lengt // --- Connection management extern void AxWin3_Connect(const char *ServerDesc); extern tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback); -extern void AxWin3_MainLoop(void); +extern int AxWin3_MainLoop(void); +extern void AxWin3_StopMainLoop(int Reason); extern void AxWin3_MessageSelect(int nFD, fd_set *FDs); // --- Non-Window based functions -- 2.20.1