Usermode/AxWin3 - Cleaner libaxwin WNDMSG handling
[tpg/acess2.git] / Usermode / Applications / axwin3_src / libaxwin3.so_src / wm.c
index d64bcbc..99b9a1b 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)
@@ -124,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;
        
@@ -158,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
@@ -178,6 +183,37 @@ void *AxWin3_int_GetDataPtr(tHWND Window)
        return Window->Data;
 }
 
+int AxWin3_int_DefaultMessageHandler(tWindow *Win, int ID, size_t Len, const void *Data)
+{
+       switch(ID)
+       {
+       case WNDMSG_HOTKEY: {
+               const struct sWndMsg_Hotkey *mi = Data;
+               if( Len < sizeof(*mi) )
+                       return -1;
+
+               if( mi->ID >= MAX_HOTKEYS ) 
+                       _SysDebug("--- Out of range hotkey %i fired", mi->ID);
+               else if( gAxWin3_Hotkeys[mi->ID] == 0 )
+                       _SysDebug("--- Unmapped hotkey ID %i fired", mi->ID);
+               else
+                       gAxWin3_Hotkeys[mi->ID]();
+               }
+               return 1;
+       // Honour a close message by default
+       case WNDMSG_CLOSE:
+               AxWin3_DestroyWindow(Win);
+               return 1;
+       // Zero fucks given?
+       case WNDMSG_DESTROY:
+               _SysDebug("TODO: Check that WNDMSG_DESTROY was from us calling _DestroyWindow");
+               // TODO: Finalise cleanup of window, this will be the last message sent to this window
+               return 1;
+       default:
+               return 0;
+       }
+}
+
 void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg)
 {
        tWindow *dest;
@@ -188,12 +224,46 @@ void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg)
        {
        case IPCMSG_SENDMSG: {
                tIPCMsg_SendMsg *info = (void*)Msg->Data;
-               if(Msg->Size < sizeof(*info))   return ;
-               if(Msg->Size < sizeof(*info) + info->Length)    return ;
-               if(!dest || !dest->Handler)     return ;
-               dest->Handler(dest, info->ID, info->Length, info->Data);
+               if(Msg->Size < sizeof(*info) || Msg->Size < sizeof(*info) + info->Length) {
+                       _SysDebug("Message is undersized (%i < %i + %i)",
+                               Msg->Size < sizeof(*info), info->Length);
+                       return ;
+               }
+               if(!dest || !dest->Handler) {
+                       _SysDebug("No handler for destination %p", dest);
+                       return ;
+               }
+               _SysDebug("IPC Message 0x%x - %i bytes", info->ID, info->Length);
+
+               if( dest->Handler(dest, info->ID, info->Length, info->Data) )
+                       ;
+               else if( AxWin3_int_DefaultMessageHandler(dest, info->ID, info->Length, info->Data) )
+                       ;
+               else
+                       _SysDebug("--- Unhandled SENDMSG 0x%x win %i", info->ID, Msg->Window);
                break; }
+       case IPCMSG_DESTROYWIN:
+               // Clean up resources associated with this window
+               break;
+       default:
+               _SysDebug("Unknow message ID %i", Msg->ID);
+               break;
        }
+       
+       free(Msg);
+}
+
+void AxWin3_SetWindowTitle(tHWND Window, const char *Title)
+{
+       tAxWin_IPCMessage       *msg;
+        int    len = strlen(Title);
+       
+       msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINTITLE, 0, len+1);
+       strcpy(msg->Data, Title);
+       
+       AxWin3_int_SendIPCMessage(msg);
+       
+       free(msg);
 }
 
 void AxWin3_SendMessage(tHWND Window, tHWND Destination, int Message, int Length, void *Data)
@@ -212,6 +282,62 @@ 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_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;
@@ -225,11 +351,25 @@ void AxWin3_FocusWindow(tHWND Window)
 void AxWin3_ShowWindow(tHWND Window, int bShow)
 {
        tAxWin_IPCMessage       *msg;
-       tIPCMsg_ShowWindow      *info;
+       tIPCMsg_Boolean *info;
 
        msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SHOWWINDOW, 0, sizeof(*info));
        info = (void*)msg->Data;
-       info->bShow = !!bShow;
+       info->Value = !!bShow;
+       
+       AxWin3_int_SendIPCMessage(msg);
+       
+       free(msg);
+}
+
+void AxWin3_DecorateWindow(tHWND Window, int bDecorate)
+{
+       tAxWin_IPCMessage       *msg;
+       tIPCMsg_Boolean *info;
+
+       msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_DECORATEWINDOW, 0, sizeof(*info));
+       info = (void*)msg->Data;
+       info->Value = !!bDecorate;
        
        AxWin3_int_SendIPCMessage(msg);
        
@@ -289,3 +429,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;
+}
+

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