From fbe3dc8eed612e18263f96fe59ccf79ab587ce0b Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 4 Nov 2011 10:48:10 +0800 Subject: [PATCH 1/1] Usermode/AxWin3 - Working on IPC, compiles and runs, just nothing happens :) --- .../axwin3_src/WM/include/ipcmessages.h | 16 +- .../Applications/axwin3_src/WM/include/wm.h | 2 +- Usermode/Applications/axwin3_src/WM/ipc.c | 246 ++++++++++++++---- Usermode/Applications/axwin3_src/WM/wm.c | 14 + .../libaxwin3.so_src/include/internal.h | 4 + .../Libraries/libaxwin3.so_src/include/ipc.h | 52 +--- Usermode/Libraries/libaxwin3.so_src/msg.c | 4 +- 7 files changed, 229 insertions(+), 109 deletions(-) diff --git a/Usermode/Applications/axwin3_src/WM/include/ipcmessages.h b/Usermode/Applications/axwin3_src/WM/include/ipcmessages.h index d9d7ee83..29c8b69f 100644 --- a/Usermode/Applications/axwin3_src/WM/include/ipcmessages.h +++ b/Usermode/Applications/axwin3_src/WM/include/ipcmessages.h @@ -4,12 +4,16 @@ * * ipcmessages.h * - IPC Message format definition + * - Shared between library and server */ #ifndef _IPCMESSAGES_H_ #define _IPCMESSAGES_H_ +#include + typedef struct sAxWin_IPCMessage tAxWin_IPCMessage; typedef struct sIPCMsg_Return tIPCMsg_Return; +typedef struct sIPCMsg_CreateWin tIPCMsg_CreateWin; /** * \name Flags for IPC Messages @@ -17,6 +21,9 @@ typedef struct sIPCMsg_Return tIPCMsg_Return; */ //! Request a return value #define IPCMSG_FLAG_RETURN 0x01 +/** + * \} + */ struct sAxWin_IPCMessage { @@ -32,11 +39,18 @@ struct sIPCMsg_Return uint32_t Value; }; +struct sIPCMsg_CreateWin +{ + uint32_t NewWinID; + uint32_t Flags; + char Renderer[]; +}; + enum eAxWin_IPCMessageTypes { IPCMSG_PING, //!< IPCMSG_SENDMSG, //!< Send a message to another window + IPCMSG_CREATEWIN, //!< Create a window }; #endif - diff --git a/Usermode/Applications/axwin3_src/WM/include/wm.h b/Usermode/Applications/axwin3_src/WM/include/wm.h index cac23cb3..a5a779fc 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm.h @@ -27,7 +27,7 @@ typedef uint32_t tColour; // === FUNCTIONS === // --- Management -extern tWindow *WM_CreateWindow(tWindow *Parent, int X, int Y, int W, int H, int Flags, tWMRenderer *Handler); +extern tWindow *WM_CreateWindow(tWindow *Parent, int Flags, const char *Renderer); extern int WM_Reposition(tWindow *Window, int X, int Y, int W, int H); extern int WM_SetFlags(tWindow *Window, int Flags); extern int WM_SendMessage(tWindow *Window, int MessageID, int Length, void *Data); diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index 30516007..0ec25dbe 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -11,6 +11,7 @@ #include #include #include +#include #define AXWIN_PORT 4101 @@ -18,39 +19,52 @@ // === TYPES === typedef struct sIPC_Type tIPC_Type; +typedef struct sIPC_Client tIPC_Client; + struct sIPC_Type { - int (*GetIdentSize)(void *Ident); - int (*CompareIdent)(void *Ident1, void *Ident2); - void (*SendMessage)(void *Ident, size_t, void *Data); + int (*GetIdentSize)(const void *Ident); + int (*CompareIdent)(const void *Ident1, const void *Ident2); + void (*SendMessage)(const void *Ident, size_t Length, const void *Data); }; +struct sIPC_Client +{ + const tIPC_Type *IPCType; + const void *Ident; // Stored after structure + + int nWindows; + tWindow **Windows; +}; + + // === PROTOTYPES === void IPC_Init(void); void IPC_FillSelect(int *nfds, fd_set *set); void IPC_HandleSelect(fd_set *set); -void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_IPCMessage *Msg); -void IPC_ReturnValue(tIPC_Type *IPCType, void *Ident, int MessageID, uint32_t Value); - int IPC_Type_Datagram_GetSize(void *Ident); - int IPC_Type_Datagram_Compare(void *Ident1, void *Ident2); -void IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data); - int IPC_Type_Sys_GetSize(void *Ident); - int IPC_Type_Sys_Compare(void *Ident1, void *Ident2); -void IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data); + int IPC_Type_Datagram_GetSize(const void *Ident); + int IPC_Type_Datagram_Compare(const void *Ident1, const void *Ident2); +void IPC_Type_Datagram_Send(const void *Ident, size_t Length, const void *Data); + int IPC_Type_Sys_GetSize(const void *Ident); + int IPC_Type_Sys_Compare(const void *Ident1, const void *Ident2); +void IPC_Type_Sys_Send(const void *Ident, size_t Length, const void *Data); +void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxWin_IPCMessage *Msg); // === GLOBALS === - int giNetworkFileHandle = -1; - int giMessagesFileHandle = -1; -tIPC_Type gIPC_Type_Datagram = { +const tIPC_Type gIPC_Type_Datagram = { IPC_Type_Datagram_GetSize, IPC_Type_Datagram_Compare, IPC_Type_Datagram_Send }; -tIPC_Type gIPC_Type_SysMessage = { +const tIPC_Type gIPC_Type_SysMessage = { IPC_Type_Sys_GetSize, IPC_Type_Sys_Compare, IPC_Type_Sys_Send }; + int giNetworkFileHandle = -1; + int giMessagesFileHandle = -1; + int giIPC_ClientCount; +tIPC_Client **gIPC_Clients; // === CODE === void IPC_Init(void) @@ -96,8 +110,161 @@ void IPC_HandleSelect(fd_set *set) } } -void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_IPCMessage *Msg) +int IPC_Type_Datagram_GetSize(const void *Ident) +{ + return 4 + Net_GetAddressSize( ((const uint16_t*)Ident)[1] ); +} + +int IPC_Type_Datagram_Compare(const void *Ident1, const void *Ident2) +{ + // Pass the buck :) + // - No need to worry about mis-matching sizes, as the size is computed + // from the 3rd/4th bytes, hence it will differ before the size is hit. + return memcmp(Ident1, Ident2, IPC_Type_Datagram_GetSize(Ident1)); +} + +void IPC_Type_Datagram_Send(const void *Ident, size_t Length, const void *Data) +{ + int identlen = IPC_Type_Datagram_GetSize(Ident); + char tmpbuf[ identlen + Length ]; + memcpy(tmpbuf, Ident, identlen); // Header + memcpy(tmpbuf + identlen, Data, Length); // Data + // TODO: Handle fragmented packets + write(giNetworkFileHandle, tmpbuf, sizeof(tmpbuf)); +} + +int IPC_Type_Sys_GetSize(const void *Ident) +{ + return sizeof(pid_t); +} + +int IPC_Type_Sys_Compare(const void *Ident1, const void *Ident2) +{ + return *(const int*)Ident1 - *(const int*)Ident2; +} + +void IPC_Type_Sys_Send(const void *Ident, size_t Length, const void *Data) +{ + SysSendMessage( *(const tid_t*)Ident, Length, Data ); +} + +// --- Client -> Window Mappings +int _CompareClientPtrs(const void *_a, const void *_b) +{ + tIPC_Client *a = *(tIPC_Client**)_a; + tIPC_Client *b = *(tIPC_Client**)_b; + + if(a->IPCType < b->IPCType) return -1; + if(a->IPCType > b->IPCType) return 1; + + return a->IPCType->CompareIdent(a->Ident, b->Ident); +} + +tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident) +{ + int pos; // Position where the new client will be inserted + int ident_size; + tIPC_Client *ret; + UNIMPLEMENTED(); + + // - Search list of registered clients + { + tIPC_Client target; + int div; + int cmp = -1; + + target.IPCType = IPCType; + target.Ident = Ident; + ret = ⌖ // Abuse ret to get a pointer + + div = giIPC_ClientCount; + pos = div/2; + while(div > 0) + { + div /= 2; + cmp = _CompareClientPtrs(&ret, &gIPC_Clients[pos]); + if(cmp == 0) break; + if(cmp < 0) + pos -= div; + else + pos += div; + } + + // - Return if found + if(cmp == 0) + return gIPC_Clients[pos]; + + // Adjust pos to be the index where the new client will be placed + if(cmp > 0) pos ++; + } + + + // - Create a new client entry + ident_size = IPCType->GetIdentSize(Ident); + ret = malloc( sizeof(tIPC_Client) + ident_size ); + if(!ret) return NULL; + ret->IPCType = IPCType; + ret->Ident = &ret + 1; // Get the end of the structure + memcpy( (void*)ret->Ident, Ident, ident_size ); + + // TODO: Register some way of detecting the client disconnecting + // > Wait on the thread / register with kernel somehow + // > Sockets are easier, but UDP is harder. Might get rid of it + + // - Insert + giIPC_ClientCount ++; + gIPC_Clients = realloc(gIPC_Clients, giIPC_ClientCount*sizeof(tIPC_Client*)); + memmove(&gIPC_Clients[pos+1], &gIPC_Clients[pos], (giIPC_ClientCount-pos-1) * sizeof(tIPC_Client*)); + gIPC_Clients[pos] = ret; + + return ret; +} + +tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t WindowID) { + if( WindowID == -1 ) + return NULL; + + UNIMPLEMENTED(); + return NULL; +} + +void IPC_int_SetWindow(tIPC_Client *Client, uint32_t WindowID, tWindow *WindowPtr) +{ + UNIMPLEMENTED(); +} + +// --- IPC Message Handlers --- +int IPC_Msg_CreateWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tIPCMsg_CreateWin *info = (void*)Msg->Data; + tWindow *newwin, *parent; + + // - Sanity checks + // > +1 is for NULL byte on string + if( Msg->Size < sizeof(tIPCMsg_CreateWin) + 1 ) + return -1; + if( info->Renderer[Msg->Size - sizeof(tIPCMsg_CreateWin)] != '\0' ) + return -1; + + // - Get the parent window ID + parent = IPC_int_GetWindow(Client, Msg->Window); + + // Catch creating a window with an existing ID + if( IPC_int_GetWindow(Client, info->NewWinID) ) + return 1; + + // - Create the new window, and save its pointer + newwin = WM_CreateWindow(parent, info->Flags, info->Renderer); + IPC_int_SetWindow(Client, info->NewWinID, newwin); + + return 0; +} + +void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxWin_IPCMessage *Msg) +{ + tIPC_Client *client; + _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)", IPCType, Ident, MsgLen, Msg); @@ -106,14 +273,14 @@ void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_IPCMessag if( MsgLen < sizeof(tAxWin_IPCMessage) + Msg->Size ) return ; -// win = AxWin_GetClient(IPCType, Ident, Msg->Window); + client = IPC_int_GetClient(IPCType, Ident); switch((enum eAxWin_IPCMessageTypes) Msg->ID) { // --- Ping message (reset timeout and get server version) case IPCMSG_PING: _SysDebug(" IPC_Handle: IPCMSG_PING"); - if( MsgLen < sizeof(tAxWin_IPCMessage) + 4 ) return; + if( Msg->Size < 4 ) return; if( Msg->Flags & IPCMSG_FLAG_RETURN ) { Msg->ID = IPCMSG_PING; @@ -123,7 +290,11 @@ void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_IPCMessag } break; - // --- + // --- Create window + case IPCMSG_CREATEWIN: + _SysDebug(" IPC_Handle: IPCMSG_CREATEWIN"); + IPC_Msg_CreateWin(client, Msg); + break; // --- Unknown message default: @@ -133,40 +304,3 @@ void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_IPCMessag } } -int IPC_Type_Datagram_GetSize(void *Ident) -{ - return 4 + Net_GetAddressSize( ((uint16_t*)Ident)[1] ); -} - -int IPC_Type_Datagram_Compare(void *Ident1, void *Ident2) -{ - // Pass the buck :) - // - No need to worry about mis-matching sizes, as the size is computed - // from the 3rd/4th bytes, hence it will differ before the size is hit. - return memcmp(Ident1, Ident2, IPC_Type_Datagram_GetSize(Ident1)); -} - -void IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data) -{ - int identlen = IPC_Type_Datagram_GetSize(Ident); - char tmpbuf[ identlen + Length ]; - memcpy(tmpbuf, Ident, identlen); // Header - memcpy(tmpbuf + identlen, Data, Length); // Data - // TODO: Handle fragmented packets - write(giNetworkFileHandle, tmpbuf, sizeof(tmpbuf)); -} - -int IPC_Type_Sys_GetSize(void *Ident) -{ - return sizeof(pid_t); -} - -int IPC_Type_Sys_Compare(void *Ident1, void *Ident2) -{ - return *(int*)Ident1 - *(int*)Ident2; -} - -void IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data) -{ - SysSendMessage( *(tid_t*)Ident, Length, Data ); -} diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c index 533754c4..3b60d1ab 100644 --- a/Usermode/Applications/axwin3_src/WM/wm.c +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -14,6 +14,20 @@ void WM_RegisterRenderer(tWMRenderer *Renderer) UNIMPLEMENTED(); } +tWindow *WM_CreateWindow(tWindow *Parent, int Flags, const char *RendererName) +{ + UNIMPLEMENTED(); + + // - Get Renderer + + // - Call create window function + + // - Fill common fields on that + + // - Return! + return NULL; +} + tWindow *WM_CreateWindowStruct(size_t ExtraSize) { return NULL; diff --git a/Usermode/Libraries/libaxwin3.so_src/include/internal.h b/Usermode/Libraries/libaxwin3.so_src/include/internal.h index f8040506..52910bd3 100644 --- a/Usermode/Libraries/libaxwin3.so_src/include/internal.h +++ b/Usermode/Libraries/libaxwin3.so_src/include/internal.h @@ -18,5 +18,9 @@ struct sAxWin3_Window extern const char *gsAxWin3_int_ServerDesc; +extern tAxWin_IPCMessage *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes); +extern void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg); +extern tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(void); + #endif diff --git a/Usermode/Libraries/libaxwin3.so_src/include/ipc.h b/Usermode/Libraries/libaxwin3.so_src/include/ipc.h index 231ee484..8cbe20d8 100644 --- a/Usermode/Libraries/libaxwin3.so_src/include/ipc.h +++ b/Usermode/Libraries/libaxwin3.so_src/include/ipc.h @@ -5,56 +5,10 @@ * ipcmessages.h * - IPC Message format definition */ -#ifndef _IPCMESSAGES_H_ -#define _IPCMESSAGES_H_ +#ifndef _IPCMESSAGES_LIB_H_ +#define _IPCMESSAGES_LIB_H_ -#include - -typedef struct sAxWin_IPCMessage tAxWin_IPCMessage; -typedef struct sIPCMsg_Return tIPCMsg_Return; -typedef struct sIPCMsg_CreateWin tIPCMsg_CreateWin; - -/** - * \name Flags for IPC Messages - * \{ - */ -//! Request a return value -#define IPCMSG_FLAG_RETURN 0x01 -/** - * \} - */ - -struct sAxWin_IPCMessage -{ - uint8_t ID; - uint8_t Flags; - uint16_t Size; - uint32_t Window; - char Data[]; -}; - -struct sIPCMsg_Return -{ - uint32_t Value; -}; - -struct sIPCMsg_CreateWin -{ - uint32_t NewWinID; - uint32_t Flags; - char Renderer[]; -}; - -enum eAxWin_IPCMessageTypes -{ - IPCMSG_PING, //!< - IPCMSG_SENDMSG, //!< Send a message to another window - IPCMSG_CREATEWIN, //!< Create a window -}; - -extern tAxWin_IPCMessage *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes); -extern void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg); -extern tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(void); +#include "../../../Applications/axwin3_src/WM/include/ipcmessages.h" #endif diff --git a/Usermode/Libraries/libaxwin3.so_src/msg.c b/Usermode/Libraries/libaxwin3.so_src/msg.c index 49bc77e8..76b38c2d 100644 --- a/Usermode/Libraries/libaxwin3.so_src/msg.c +++ b/Usermode/Libraries/libaxwin3.so_src/msg.c @@ -115,8 +115,8 @@ tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(void) switch(giConnectionType) { case CONNTYPE_SENDMESSAGE: - if(SysGetMessage(NULL, NULL) == 0) - sleep(); + // TODO: Less hack, I need a version of select for GetMessage etc + if(SysGetMessage(NULL, NULL) == 0) sleep(); while(SysGetMessage(NULL, NULL)) { pid_t tid; -- 2.20.1