AxWin3 - Bugfixes everywhere, hotkeys working
authorJohn Hodge <[email protected]>
Tue, 31 Jul 2012 11:44:04 +0000 (19:44 +0800)
committerJohn Hodge <[email protected]>
Tue, 31 Jul 2012 11:44:04 +0000 (19:44 +0800)
- 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.

Usermode/Applications/axwin3_src/Interface/main.c
Usermode/Applications/axwin3_src/WM/include/wm_hotkeys.h
Usermode/Applications/axwin3_src/WM/ipc.c
Usermode/Applications/axwin3_src/WM/main.c
Usermode/Applications/axwin3_src/WM/renderers/widget.c
Usermode/Applications/axwin3_src/WM/wm_hotkeys.c
Usermode/Applications/axwin3_src/WM/wm_input.c
Usermode/Applications/axwin3_src/include/ipcmessages.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c
Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/axwin.h

index e34968c..fd4ff3f 100644 (file)
@@ -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);
index 44675d2..1a7ca7e 100644 (file)
@@ -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);
 
index b3648bb..cbed7fd 100644 (file)
@@ -13,6 +13,7 @@
 #include <stdio.h>
 #include <wm.h>
 #include <wm_internals.h>
+#include <wm_hotkeys.h>
 
 #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;
 }
 
index 7aa5534..0996f90 100644 (file)
@@ -9,6 +9,7 @@
 #include <acess/sys.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <axwin3/keysyms.h>
 
 // === 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 )
index 7668cbd..46b3198 100644 (file)
@@ -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:
index 3fbe4f7..c8eab69 100644 (file)
@@ -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));
 }
index 751bcbb..5f6ef85 100644 (file)
@@ -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
                }
        }
index e7424fe..6e61ba8 100644 (file)
@@ -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;
index 875f14b..450e4b4 100644 (file)
@@ -8,7 +8,6 @@
 #include <axwin3/axwin.h>
 #include <axwin3/widget.h>
 #include "include/internal.h"
-#include "include/ipc.h"
 #include <stdlib.h>
 #include <widget_messages.h>
 #include <string.h>
@@ -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;
 }
 
index 8b13860..4a6d8d3 100644 (file)
 #include <string.h>
 #include "include/internal.h"
 #include "include/ipc.h"
+#include <wm_messages.h>
 
-#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;
+}
+
index fe116e9..8d91173 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _AXWIN3_AXWIN_H_
 #define _AXWIN3_AXWIN_H_
 
+#include <stddef.h>    // 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);

UCC git Repository :: git.ucc.asn.au