From 9c435c78b45c6b62a8182334e44d87b4a6a198f7 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 31 Jul 2012 19:44:04 +0800 Subject: [PATCH] AxWin3 - Bugfixes everywhere, hotkeys working - Fixed offset errors in mouse input - Fixed Widget_GetText never returning > Compound bug, IPC wait failure and not implimented serverside - Used the return value of client window message handlers > Now warns when a message is unhandled - Hotkeys implimented and work > NOTE: Win-R -> Run is hardcoded in WM/main.c > TODO: Use a config library/server instead. --- .../Applications/axwin3_src/Interface/main.c | 6 ++ .../axwin3_src/WM/include/wm_hotkeys.h | 1 + Usermode/Applications/axwin3_src/WM/ipc.c | 20 +++++ Usermode/Applications/axwin3_src/WM/main.c | 7 ++ .../axwin3_src/WM/renderers/widget.c | 30 ++++++++ .../Applications/axwin3_src/WM/wm_hotkeys.c | 13 +++- .../Applications/axwin3_src/WM/wm_input.c | 4 +- .../axwin3_src/include/ipcmessages.h | 7 ++ .../axwin3_src/libaxwin3.so_src/r_widget.c | 16 ++-- .../axwin3_src/libaxwin3.so_src/wm.c | 77 ++++++++++++++++++- .../include_exp/axwin3/axwin.h | 5 ++ 11 files changed, 171 insertions(+), 15 deletions(-) diff --git a/Usermode/Applications/axwin3_src/Interface/main.c b/Usermode/Applications/axwin3_src/Interface/main.c index e34968c9..fd4ff3f4 100644 --- a/Usermode/Applications/axwin3_src/Interface/main.c +++ b/Usermode/Applications/axwin3_src/Interface/main.c @@ -19,6 +19,7 @@ void create_sidebar(void); void create_mainmenu(void); void create_run_dialog(void); +void mainmenu_run_dialog(void *unused); // === GLOBALS === tHWND gSidebar; @@ -49,6 +50,10 @@ int main(int argc, char *argv[]) create_mainmenu(); create_run_dialog(); + AxWin3_RegisterAction(gSidebar, "Interface>Run", (tAxWin3_HotkeyCallback)mainmenu_run_dialog); +// AxWin3_RegisterAction(gSidebar, "Interface>Terminal", mainmenu_app_terminal); +// AxWin3_RegisterAction(gSidebar, "Interface>TextEdit", mainmenu_app_textedit); + // Idle loop AxWin3_MainLoop(); @@ -130,6 +135,7 @@ void create_mainmenu(void) // -------------------------------------------------------------------- int run_dorun(tAxWin3_Widget *unused) { + _SysDebug("DoRun pressed"); char *cmd = AxWin3_Widget_GetText(gRunInput); _SysDebug("Command string '%s'", cmd); AxWin3_ShowWindow(gRunDialog, 0); diff --git a/Usermode/Applications/axwin3_src/WM/include/wm_hotkeys.h b/Usermode/Applications/axwin3_src/WM/include/wm_hotkeys.h index 44675d21..1a7ca7ef 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm_hotkeys.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm_hotkeys.h @@ -33,6 +33,7 @@ struct sHotkeyTarget extern void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName); +extern void WM_Hotkey_RegisterAction(const char *ActionName, tWindow *Target, uint16_t Index); extern void WM_Hotkey_KeyDown(uint32_t Scancode); extern void WM_Hotkey_KeyUp(uint32_t Scancode); diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index b3648bb7..cbed7fd1 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -13,6 +13,7 @@ #include #include #include +#include #define AXWIN_PORT 4101 @@ -495,7 +496,26 @@ int IPC_Msg_SetWinPos(tIPC_Client *Client, tAxWin_IPCMessage *Msg) int IPC_Msg_RegisterAction(tIPC_Client *Client, tAxWin_IPCMessage *Msg) { + tIPCMsg_RegAction *info = (void*)Msg->Data; + tWindow *win; + ASSERT(Msg->ID == IPCMSG_REGACTION); + + if( Msg->Size < sizeof(*info) + 1 ) + return -1; + + win = IPC_int_GetWindow(Client, Msg->Window); + if(!win) return 1; + + if( strnlen(info->Action, Msg->Size - sizeof(*info)) == Msg->Size - sizeof(*info) ) + return 1; + + _SysDebug("RegisterAction %p:%i [%i]\"%s\"", + Client, Msg->Window, info->Index, info->Action + ); + + WM_Hotkey_RegisterAction(info->Action, win, info->Index); + return 0; } diff --git a/Usermode/Applications/axwin3_src/WM/main.c b/Usermode/Applications/axwin3_src/WM/main.c index 7aa5534a..0996f909 100644 --- a/Usermode/Applications/axwin3_src/WM/main.c +++ b/Usermode/Applications/axwin3_src/WM/main.c @@ -9,6 +9,7 @@ #include #include #include +#include // === IMPORTS === extern void Video_Setup(void); @@ -18,6 +19,7 @@ extern int Renderer_Widget_Init(void); extern int Renderer_Background_Init(void); extern int Renderer_Framebuffer_Init(void); extern void WM_Update(void); +extern void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName); // === PROTOTYPES === void ParseCommandline(int argc, char **argv); @@ -63,6 +65,11 @@ int main(int argc, char *argv[]) Renderer_Background_Init(); Renderer_Framebuffer_Init(); WM_Initialise(); + + // TODO: Config + uint32_t keys[4]; + keys[0] = KEYSYM_LEFTGUI; keys[1] = KEYSYM_r; + WM_Hotkey_Register(2, keys, "Interface>Run"); // Spawn interface root if( clone(CLONE_VM, 0) == 0 ) diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget.c b/Usermode/Applications/axwin3_src/WM/renderers/widget.c index 7668cbd6..46b3198a 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget.c @@ -552,6 +552,34 @@ void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) // } } +int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) +{ + if( Len < sizeof(*Msg) ) + return 0; + if( Len > sizeof(*Msg) ) + return 1; // Pass to user + + 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; + + if( text ) { + omsg->WidgetID = Msg->WidgetID; + strcpy(omsg->Text, text); + } + else { + omsg->WidgetID = -1; + omsg->Text[0] = 0; + } + + WM_SendMessage(Info->RootElement.Window, Info->RootElement.Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf); + return 0; +} + int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) { tWidgetWin *info = Target->RendererInfo; @@ -691,6 +719,8 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void case MSG_WIDGET_SETTEXT: Widget_SetText(info, Len, Data); return 0; + case MSG_WIDGET_GETTEXT: + return Widget_GetText(info, Len, Data); // default: diff --git a/Usermode/Applications/axwin3_src/WM/wm_hotkeys.c b/Usermode/Applications/axwin3_src/WM/wm_hotkeys.c index 3fbe4f76..c8eab697 100644 --- a/Usermode/Applications/axwin3_src/WM/wm_hotkeys.c +++ b/Usermode/Applications/axwin3_src/WM/wm_hotkeys.c @@ -40,6 +40,11 @@ void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName) h->Target = (void*)( h->Keys + nKeys ); strcpy((char*)h->Target, ActionName); memcpy(h->Keys, Keys, nKeys * sizeof(uint32_t)); + + h->Next = NULL; + if( gpWM_Hotkeys ) + gpWM_Hotkeys->Next = h; + gpWM_Hotkeys = h; } void WM_Hotkey_RegisterAction(const char *ActionName, tWindow *Target, uint16_t Index) @@ -82,6 +87,8 @@ void WM_Hotkey_KeyUp(uint32_t Scancode) { _UnsetKey(Scancode); + // Ensure that hotkeys are triggered on the longest sequence + // (so Win-Shift-R doesn't trigger Win-R if shift is released) if( !gbWM_HasBeenKeyDown ) return ; @@ -94,7 +101,8 @@ void WM_Hotkey_KeyUp(uint32_t Scancode) if( _IsKeySet(hk->Keys[i]) ) continue ; break; } - if( i == hk->nKeys ) + _SysDebug("%i/%i satisfied for %s", i, hk->nKeys, hk->Target); + if( i != hk->nKeys ) continue ; // Fire shortcut @@ -108,6 +116,7 @@ void WM_Hotkey_KeyUp(uint32_t Scancode) void WM_Hotkey_FireEvent(const char *Target) { + _SysDebug("WM_Hotkey_FireEvent: (%s)", Target); // - Internal events (Alt-Tab, Close, Maximize, etc...) // TODO: Internal event handling @@ -133,11 +142,13 @@ void WM_Hotkey_FireEvent(const char *Target) static void _SetKey(uint32_t sc) { + _SysDebug("_SetKey: (%x)", sc); if( sc >= MAX_STATE_SCANCODE ) return; gWM_KeyStates[sc/8] |= 1 << (sc % 8); } static void _UnsetKey(uint32_t sc) { + _SysDebug("_UnsetKey: (%x)", sc); if( sc >= MAX_STATE_SCANCODE ) return; gWM_KeyStates[sc/8] &= ~(1 << (sc % 8)); } diff --git a/Usermode/Applications/axwin3_src/WM/wm_input.c b/Usermode/Applications/axwin3_src/WM/wm_input.c index 751bcbbe..5f6ef853 100644 --- a/Usermode/Applications/axwin3_src/WM/wm_input.c +++ b/Usermode/Applications/axwin3_src/WM/wm_input.c @@ -34,8 +34,8 @@ tWindow *WM_int_GetWindowAtPos(int X, int Y) for(win = ret->FirstChild; win; win = win->NextSibling) { if( !(win->Flags & WINFLAG_SHOW) ) continue ; - if( X < win->X || X >= win->X + win->W ) continue; - if( Y < win->Y || Y >= win->Y + win->H ) continue; + if( X < win->X || X >= win->X + win->RealW ) continue; + if( Y < win->Y || Y >= win->Y + win->RealH ) continue; next_win = win; // Overwrite as we want the final rendered window } } diff --git a/Usermode/Applications/axwin3_src/include/ipcmessages.h b/Usermode/Applications/axwin3_src/include/ipcmessages.h index e7424fe3..6e61ba8e 100644 --- a/Usermode/Applications/axwin3_src/include/ipcmessages.h +++ b/Usermode/Applications/axwin3_src/include/ipcmessages.h @@ -17,6 +17,7 @@ typedef struct sIPCMsg_CreateWin tIPCMsg_CreateWin; typedef struct sIPCMsg_Boolean tIPCMsg_Boolean; typedef struct sIPCMsg_SetWindowPos tIPCMsg_SetWindowPos; typedef struct sIPCMsg_SendMsg tIPCMsg_SendMsg; +typedef struct sIPCMsg_RegAction tIPCMsg_RegAction; typedef struct sIPCMsg_GetDisplayDims tIPCMsg_GetDisplayDims; typedef struct sIPCMsg_RetDisplayDims tIPCMsg_RetDisplayDims; @@ -73,6 +74,12 @@ struct sIPCMsg_SetWindowPos uint8_t bSetDims; }; +struct sIPCMsg_RegAction +{ + uint16_t Index; + char Action[]; +}; + struct sIPCMsg_GetDisplayDims { uint16_t DisplayID; 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 875f14b8..450e4b4f 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c @@ -8,7 +8,6 @@ #include #include #include "include/internal.h" -#include "include/ipc.h" #include #include #include @@ -232,23 +231,20 @@ char *AxWin3_Widget_GetText(tAxWin3_Widget *Widget) { char buf[sizeof(tWidgetMsg_SetText)]; tWidgetMsg_SetText *msg = (void*)buf; - tAxWin_IPCMessage *retmsg; - char *ret; + size_t retmsg_size; msg->WidgetID = Widget->ID; AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf); - retmsg = AxWin3_int_WaitIPCMessage(MSG_WIDGET_GETTEXT); - msg = (void*)retmsg->Data; - - if( retmsg->Size < sizeof(*msg) ) { - free(retmsg); + msg = AxWin3_WaitMessage(Widget->Window, MSG_WIDGET_GETTEXT, &retmsg_size); + if( retmsg_size < sizeof(*msg) ) { + free(msg); return NULL; } - ret = strndup(msg->Text, retmsg->Size - sizeof(*msg)); - free(retmsg); + char *ret = strndup(msg->Text, retmsg_size - sizeof(*msg)); + free(msg); return ret; } diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c index 8b138606..4a6d8d33 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c @@ -10,8 +10,10 @@ #include #include "include/internal.h" #include "include/ipc.h" +#include -#define WINDOWS_PER_ALLOC (63) +#define WINDOWS_PER_ALLOC (64-1) // -1 to make it 64 pointers (+ Next) +#define MAX_HOTKEYS 32 typedef struct sWindowBlock tWindowBlock; @@ -28,6 +30,7 @@ struct sWindowBlock int giAxWin3_LowestFreeWinID; int giAxWin3_HighestUsedWinID; tWindowBlock gAxWin3_WindowList; +tAxWin3_HotkeyCallback gAxWin3_Hotkeys[MAX_HOTKEYS]; // === CODE === tWindow *AxWin3_int_CreateWindowStruct(uint32_t ServerID, int ExtraBytes) @@ -198,7 +201,26 @@ void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg) return ; } _SysDebug("IPC Message 0x%x - %i bytes", info->ID, info->Length); - dest->Handler(dest, info->ID, info->Length, info->Data); + + if( dest->Handler(dest, info->ID, info->Length, info->Data) ) + ; + else { + switch( info->ID ) + { + case WNDMSG_HOTKEY: { + const struct sWndMsg_Hotkey *mi = (void*)info->Data; + if( mi->ID >= MAX_HOTKEYS ) + ; // TODO: Error when hotkey is out of range + else if( gAxWin3_Hotkeys[mi->ID] == 0 ) + _SysDebug("--- Unmapped hotkey ID %i fired", mi->ID); + else + gAxWin3_Hotkeys[mi->ID](); + }break; + default: + _SysDebug("--- Unhandled SENDMSG %i", info->ID); + break; + } + } break; } default: _SysDebug("Unknow message ID %i", Msg->ID); @@ -235,6 +257,32 @@ void AxWin3_SendMessage(tHWND Window, tHWND Destination, int Message, int Length free(msg); } +void *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length) +{ + tAxWin_IPCMessage *msg; + + for( ;; ) + { + msg = AxWin3_int_WaitIPCMessage(IPCMSG_SENDMSG); + if( msg->Window != AxWin3_int_GetWindowID(Window) ) { + AxWin3_int_HandleMessage(msg); + continue ; + } + tIPCMsg_SendMsg *info = (void*)msg->Data; + if( info->ID != MessageID ) { + AxWin3_int_HandleMessage(msg); + continue ; + } + + *Length = info->Length; + void *ret = malloc(info->Length); + memcpy(ret, info->Data, info->Length); + free(msg); + + return ret; + } +} + void AxWin3_FocusWindow(tHWND Window) { tAxWin_IPCMessage *msg; @@ -326,3 +374,28 @@ void AxWin3_ResizeWindow(tHWND Window, short W, short H) free(msg); } +int AxWin3_RegisterAction(tHWND Window, const char *Action, tAxWin3_HotkeyCallback cb) +{ + int i; + for( i = 0; i < MAX_HOTKEYS; i ++ ) + { + if( gAxWin3_Hotkeys[i] == NULL ) + { + tAxWin_IPCMessage *msg; + struct sIPCMsg_RegAction *info; + gAxWin3_Hotkeys[i] = cb; + + msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_REGACTION, 0, sizeof(*info)+strlen(Action)+1); + info = (void*)msg->Data; + + info->Index = i; + strcpy(info->Action, Action); + + AxWin3_int_SendIPCMessage(msg); + free(msg); + return i; + } + } + return -1; +} + 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 fe116e9d..8d911733 100644 --- a/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/axwin.h +++ b/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/axwin.h @@ -8,6 +8,8 @@ #ifndef _AXWIN3_AXWIN_H_ #define _AXWIN3_AXWIN_H_ +#include // size_t + // === CONSTANTS === // === TYPES === @@ -15,6 +17,7 @@ typedef struct sAxWin3_Window *tHWND; typedef unsigned int tAxWin3_Colour; // TODO: Actual 32-bit typedef void (*tAxWin3_MessageCallback)(int SourceTID, int Length); +typedef void (*tAxWin3_HotkeyCallback)(void); typedef int (*tAxWin3_WindowMessageHandler)(tHWND Window, int Message, int Length, void *Data); @@ -49,9 +52,11 @@ extern tHWND AxWin3_CreateWindow( * \param Window Handle to a window to destroy */ extern void AxWin3_DestroyWindow(tHWND Window); +extern int AxWin3_RegisterAction(tHWND Window, const char *Action, tAxWin3_HotkeyCallback cb); // --- Core window management functions extern void AxWin3_SendMessage(tHWND Window, tHWND Dest, int Message, int Length, void *Data); +extern void *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length); extern void AxWin3_SetWindowTitle(tHWND Window, const char *Title); extern void AxWin3_FocusWindow(tHWND Window); extern void AxWin3_ShowWindow(tHWND Window, int bShow); -- 2.20.1