X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Fipc.c;h=46aff215dd9287e7995fd75dff7bbe16cef66d94;hb=bfacdd3b71576cf6ceaa83352d3a7d162adb75e1;hp=0ec25dbe26ff5a159cbf8a92f708fb2e083b586c;hpb=fbe3dc8eed612e18263f96fe59ccf79ab587ce0b;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index 0ec25dbe..46aff215 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -12,14 +12,15 @@ #include #include #include +#include #define AXWIN_PORT 4101 #define STATICBUF_SIZE 64 +#define MAX_WINDOWS_PER_APP 128 // === TYPES === typedef struct sIPC_Type tIPC_Type; -typedef struct sIPC_Client tIPC_Client; struct sIPC_Type { @@ -37,6 +38,8 @@ struct sIPC_Client tWindow **Windows; }; +// === IMPORTS === +extern tWindow *gpWM_FocusedWindow; // Needed for _FocusWindow // === PROTOTYPES === void IPC_Init(void); @@ -95,7 +98,7 @@ void IPC_HandleSelect(fd_set *set) msg = staticBuf + identlen; IPC_Handle(&gIPC_Type_Datagram, staticBuf, readlen - identlen, (void*)msg); - _SysDebug("IPC_HandleSelect: UDP handled"); +// _SysDebug("IPC_HandleSelect: UDP handled"); } while(SysGetMessage(NULL, NULL)) @@ -106,7 +109,7 @@ void IPC_HandleSelect(fd_set *set) SysGetMessage(NULL, data); IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data); - _SysDebug("IPC_HandleSelect: Message handled"); +// _SysDebug("IPC_HandleSelect: Message handled"); } } @@ -140,7 +143,7 @@ int IPC_Type_Sys_GetSize(const void *Ident) int IPC_Type_Sys_Compare(const void *Ident1, const void *Ident2) { - return *(const int*)Ident1 - *(const int*)Ident2; + return *(const tid_t*)Ident1 - *(const tid_t*)Ident2; } void IPC_Type_Sys_Send(const void *Ident, size_t Length, const void *Data) @@ -162,12 +165,12 @@ int _CompareClientPtrs(const void *_a, const void *_b) tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident) { - int pos; // Position where the new client will be inserted + int pos = 0; // Position where the new client will be inserted int ident_size; tIPC_Client *ret; - UNIMPLEMENTED(); // - Search list of registered clients + if(giIPC_ClientCount > 0) { tIPC_Client target; int div; @@ -183,6 +186,7 @@ tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident) { div /= 2; cmp = _CompareClientPtrs(&ret, &gIPC_Clients[pos]); +// _SysDebug("Checking against %i gives %i", pos, cmp); if(cmp == 0) break; if(cmp < 0) pos -= div; @@ -201,11 +205,14 @@ tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident) // - Create a new client entry ident_size = IPCType->GetIdentSize(Ident); +// _SysDebug("ident_size = %i", ident_size); ret = malloc( sizeof(tIPC_Client) + ident_size ); if(!ret) return NULL; ret->IPCType = IPCType; - ret->Ident = &ret + 1; // Get the end of the structure + ret->Ident = ret + 1; // Get the end of the structure memcpy( (void*)ret->Ident, Ident, ident_size ); + ret->nWindows = 0; + ret->Windows = NULL; // TODO: Register some way of detecting the client disconnecting // > Wait on the thread / register with kernel somehow @@ -224,17 +231,71 @@ tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t WindowID) { if( WindowID == -1 ) return NULL; - - UNIMPLEMENTED(); - return NULL; + + if( WindowID >= Client->nWindows ) { +// _SysDebug("Window %i out of range for %p (%i)", WindowID, Client, Client->nWindows); + return NULL; + } + + return Client->Windows[WindowID]; } void IPC_int_SetWindow(tIPC_Client *Client, uint32_t WindowID, tWindow *WindowPtr) { - UNIMPLEMENTED(); + if( WindowID >= MAX_WINDOWS_PER_APP ) + return ; + + if( WindowID >= Client->nWindows ) + { + int oldCount = Client->nWindows; + Client->nWindows = WindowID + 1; + Client->Windows = realloc(Client->Windows, Client->nWindows*sizeof(tWindow*)); + memset( &Client->Windows[oldCount], 0, (Client->nWindows-oldCount)*sizeof(tWindow*) ); + _SysDebug("Expanded %p's window list from %i to %i", Client, oldCount, Client->nWindows); + } + + _SysDebug("Assigned %p to window %i for %p", WindowPtr, WindowID, Client); + Client->Windows[WindowID] = WindowPtr; } // --- IPC Message Handlers --- +int IPC_Msg_SendMsg(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tIPCMsg_SendMsg *info = (void*)Msg->Data; + tWindow *src, *dest; + + // - Sanity checks + if( Msg->Size < sizeof(tIPCMsg_SendMsg) ) + return -1; + if( Msg->Size < sizeof(tIPCMsg_SendMsg) + info->Length ) + return -1; + + src = IPC_int_GetWindow(Client, Msg->Window); + if(!src) return 1; + dest = IPC_int_GetWindow(Client, info->Remote); + if(!dest) return 1; + + WM_SendMessage(src, dest, info->ID, info->Length, info->Data); + + return 0; +} + +int IPC_Msg_FocusWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tWindow *win; + + // Don't allow the focus to be changed unless the client has the focus + if(!gpWM_FocusedWindow) return 1; + if(gpWM_FocusedWindow->Client != Client) return 1; + + win = IPC_int_GetWindow(Client, Msg->Window); + if(!win) return 1; + + WM_FocusWindow(win); + + return 0; +} + int IPC_Msg_CreateWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg) { tIPCMsg_CreateWin *info = (void*)Msg->Data; @@ -242,10 +303,19 @@ int IPC_Msg_CreateWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg) // - Sanity checks // > +1 is for NULL byte on string - if( Msg->Size < sizeof(tIPCMsg_CreateWin) + 1 ) + if( Msg->Size < sizeof(*info) + 1 ) { + _SysDebug("IPC_Msg_CreateWin: Size check 1 failed"); return -1; - if( info->Renderer[Msg->Size - sizeof(tIPCMsg_CreateWin)] != '\0' ) + } + if( info->Renderer[Msg->Size - sizeof(*info) - 1] != '\0' ) { + _SysDebug("IPC_Msg_CreateWin: Size check 2 failed"); + _SysDebug("info = {"); + _SysDebug(" .NewWinID = %i", info->NewWinID); + _SysDebug(" .RendererArg = %i", info->RendererArg); + _SysDebug(" .Renderer = '%.*s'", Msg->Size - sizeof(*info), info->Renderer); + _SysDebug("}"); return -1; + } // - Get the parent window ID parent = IPC_int_GetWindow(Client, Msg->Window); @@ -255,15 +325,136 @@ int IPC_Msg_CreateWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg) return 1; // - Create the new window, and save its pointer - newwin = WM_CreateWindow(parent, info->Flags, info->Renderer); + newwin = WM_CreateWindow(parent, Client, info->NewWinID, info->RendererArg, info->Renderer); IPC_int_SetWindow(Client, info->NewWinID, newwin); return 0; } +int IPC_Msg_SetWindowTitle(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tWindow *win; + + if( Msg->Size < 1 ) return -1; + if( Msg->Data[ Msg->Size-1 ] != '\0' ) return -1; + + win = IPC_int_GetWindow(Client, Msg->Window); + if(!win) return 1; + + WM_SetWindowTitle(win, Msg->Data); + + return 0; +} + +int IPC_Msg_ShowWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tIPCMsg_Boolean *info = (void*)Msg->Data; + tWindow *win; + + if( Msg->Size < sizeof(*info) ) return -1; + + win = IPC_int_GetWindow(Client, Msg->Window); + if(!win) return 1; + + WM_ShowWindow(win, !!info->Value); + + return 0; +} + +int IPC_Msg_DecorateWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tIPCMsg_Boolean *info = (void*)Msg->Data; + tWindow *win; + + if( Msg->Size < sizeof(*info) ) return -1; + + win = IPC_int_GetWindow(Client, Msg->Window); + if(!win) return 1; + + WM_DecorateWindow(win, !!info->Value); + return 0; +} + +int IPC_Msg_SetWinPos(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tIPCMsg_SetWindowPos *info = (void*)Msg->Data; + tWindow *win; + + if(Msg->Size < sizeof(*info)) return -1; + + win = IPC_int_GetWindow(Client, Msg->Window); + if(!win) return 1; + + _SysDebug("info = {..., bSetPos=%i,bSetDims=%i}", info->bSetPos, info->bSetDims); + + if(info->bSetPos) + WM_MoveWindow(win, info->X, info->Y); + if(info->bSetDims) + WM_ResizeWindow(win, info->W, info->H); + + return 0; +} + +int IPC_Msg_GetDisplayCount(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tAxWin_IPCMessage *ret_hdr; + tIPCMsg_ReturnInt *ret; + char buf[sizeof(*ret_hdr)+sizeof(*ret)]; + + if( !(Msg->Flags & IPCMSG_FLAG_RETURN) ) return 0; + + ret_hdr = (void*)buf; + ret_hdr->ID = IPCMSG_GETDISPLAYCOUNT; + ret_hdr->Flags = 0; + ret_hdr->Window = -1; + ret_hdr->Size = sizeof(*ret); + ret = (void*)ret_hdr->Data; + ret->Value = 1; // HARD CODE - Current version only supports one display + + Client->IPCType->SendMessage(Client->Ident, sizeof(buf), buf); + return 0; +} + +int IPC_Msg_GetDisplayDims(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tIPCMsg_GetDisplayDims *info; + tAxWin_IPCMessage *ret_hdr; + tIPCMsg_RetDisplayDims *ret; + char buf[sizeof(*ret_hdr)+sizeof(*ret)]; + + if( !(Msg->Flags & IPCMSG_FLAG_RETURN) ) return 0; + + info = (void*)Msg->Data; + + ret_hdr = (void*)buf; + ret_hdr->ID = IPCMSG_GETDISPLAYDIMS; + ret_hdr->Flags = 0; + ret_hdr->Window = -1; + ret_hdr->Size = sizeof(*ret); + ret = (void*)ret_hdr->Data; + + // HARD CODE! Only one display supported + if( info->DisplayID == 0 ) + { + ret->X = 0; + ret->Y = 0; + ret->W = giScreenWidth; + ret->H = giScreenHeight; + } + else + { + ret->X = 0; ret->Y = 0; + ret->W = 0; ret->H = 0; + } + + Client->IPCType->SendMessage(Client->Ident, sizeof(buf), buf); + return 0; +} + void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxWin_IPCMessage *Msg) { tIPC_Client *client; + int rv = 0; _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)", IPCType, Ident, MsgLen, Msg); @@ -283,24 +474,93 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW if( Msg->Size < 4 ) return; if( Msg->Flags & IPCMSG_FLAG_RETURN ) { + tIPCMsg_ReturnInt *ret = (void*)Msg->Data; Msg->ID = IPCMSG_PING; - Msg->Size = sizeof(tIPCMsg_Return); - ((tIPCMsg_Return*)Msg->Data)->Value = AXWIN_VERSION; - IPCType->SendMessage(Ident, sizeof(tIPCMsg_Return), Msg); + Msg->Size = sizeof(*ret); + ret->Value = AXWIN_VERSION; + IPCType->SendMessage(Ident, sizeof(*Msg)+sizeof(*ret), Msg); } break; - // --- Create window + // -- Get display count + case IPCMSG_GETDISPLAYCOUNT: + rv = IPC_Msg_GetDisplayCount(client, Msg); + break; + + // --- Get display dimensions + case IPCMSG_GETDISPLAYDIMS: + rv = IPC_Msg_GetDisplayDims(client, Msg); + break; + + // --- Send a message + case IPCMSG_SENDMSG: + _SysDebug(" IPC_Handle: IPCMSG_SENDMSG %i", ((tIPCMsg_SendMsg*)Msg->Data)->ID); + rv = IPC_Msg_SendMsg(client, Msg); + break; + + // --- Create window case IPCMSG_CREATEWIN: _SysDebug(" IPC_Handle: IPCMSG_CREATEWIN"); - IPC_Msg_CreateWin(client, Msg); + rv = IPC_Msg_CreateWin(client, Msg); + break; + // TODO: Destroy window + + // --- Set window title + case IPCMSG_SETWINTITLE: + _SysDebug(" IPC_Handle: IPCMSG_SETWINTITLE"); + rv = IPC_Msg_SetWindowTitle(client, Msg); + break; + + // --- Give a window focus + case IPCMSG_FOCUSWINDOW: + _SysDebug(" IPC_Handle: IPCMSG_FOCUSWINDOW"); + rv = IPC_Msg_FocusWindow(client, Msg); + break; + // --- Show/Hide a window + case IPCMSG_SHOWWINDOW: + _SysDebug(" IPC_Handle: IPCMSG_SHOWWINDOW"); + rv = IPC_Msg_ShowWindow(client, Msg); + break; + case IPCMSG_DECORATEWINDOW: + _SysDebug(" IPC_Handle: IPCMSG_DECORATEWINDOW"); + rv = IPC_Msg_DecorateWindow(client, Msg); + break; + // --- Move/Resize a window + case IPCMSG_SETWINPOS: + _SysDebug(" IPC_Handle: IPCMSG_SETWINPOS"); + rv = IPC_Msg_SetWinPos(client, Msg); break; // --- Unknown message default: fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType); - _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType); + _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType); break; } + if(rv) + _SysDebug("IPC_Handle: rv = %i", rv); +} + +// --- Server->Client replies +void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int MsgID, int Len, void *Data) +{ + tAxWin_IPCMessage *hdr; + tIPCMsg_SendMsg *msg; + char buf[sizeof(*hdr)+sizeof(*msg)+Len]; + + hdr = (void*)buf; + msg = (void*)hdr->Data; + + hdr->ID = IPCMSG_SENDMSG; + hdr->Flags = 0; + hdr->Size = sizeof(*msg) + Len; + hdr->Window = Dst; + + msg->Remote = Src; + msg->ID = MsgID; + msg->Length = Len; + memcpy(msg->Data, Data, Len); + + Client->IPCType->SendMessage(Client->Ident, sizeof(buf), buf); }