X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Fipc.c;h=79e0956fc6a4e1a341b107f9f7d735643483afea;hb=4c78a1bdd506cda6cda27ee342165c7dfa7ecdc2;hp=38cd1335fa7f9837128132504b6a2a9fc96eae73;hpb=ed78a9ac44c440180c37c1cbbbd7ecbc4d9076d7;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index 38cd1335..79e0956f 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -53,7 +53,12 @@ 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); + int IPC_Type_IPCPipe_GetSize(const void *Ident); + int IPC_Type_IPCPipe_Compare(const void *Ident1, const void *Ident2); +void IPC_Type_IPCPipe_Send(const void *Ident, size_t Length, const void *Data); +tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident); +void IPC_int_DropClient(tIPC_Client *Client); +void IPC_Handle(tIPC_Client *Client, size_t MsgLen, tAxWin_IPCMessage *Msg); // === GLOBALS === const tIPC_Type gIPC_Type_Datagram = { @@ -65,9 +70,14 @@ const tIPC_Type gIPC_Type_SysMessage = { IPC_Type_Sys_GetSize, IPC_Type_Sys_Compare, IPC_Type_Sys_Send +}; +const tIPC_Type gIPC_Type_IPCPipe = { + IPC_Type_IPCPipe_GetSize, + IPC_Type_IPCPipe_Compare, + IPC_Type_IPCPipe_Send }; int giNetworkFileHandle = -1; - int giMessagesFileHandle = -1; + int giIPCPipeHandle = -1; int giIPC_ClientCount; tIPC_Client **gIPC_Clients; @@ -76,51 +86,91 @@ void IPC_Init(void) { int tmp; // TODO: Check this - giNetworkFileHandle = open("/Devices/ip/loop/udp", OPENFLAG_READ); + giNetworkFileHandle = _SysOpen("/Devices/ip/loop/udp", OPENFLAG_READ); if( giNetworkFileHandle != -1 ) { tmp = AXWIN_PORT; - ioctl(giNetworkFileHandle, 4, &tmp); // TODO: Don't hard-code IOCtl number + _SysIOCtl(giNetworkFileHandle, 4, &tmp); // TODO: Don't hard-code IOCtl number + } + + giIPCPipeHandle = _SysOpen("/Devices/ipcpipe/axwin"/*-$USER*/, OPENFLAG_CREATE); + _SysDebug("giIPCPipeHandle = %i", giIPCPipeHandle); + if( giIPCPipeHandle == -1 ) + _SysDebug("ERROR: Can't create IPCPipe handle"); +} + +void _setfd(int fd, int *nfds, fd_set *set) +{ + if( fd >= 0 ) + { + if( fd >= *nfds ) *nfds = fd+1; + FD_SET(fd, set); } } void IPC_FillSelect(int *nfds, fd_set *set) { - if( giNetworkFileHandle != -1 ) + _setfd(giNetworkFileHandle, nfds, set); + _setfd(giIPCPipeHandle, nfds, set); + for( int i = 0; i < giIPC_ClientCount; i ++ ) { - if( giNetworkFileHandle > *nfds ) *nfds = giNetworkFileHandle; - FD_SET(giNetworkFileHandle, set); + if( gIPC_Clients[i] && gIPC_Clients[i]->IPCType == &gIPC_Type_IPCPipe ) + _setfd( *(int*)(gIPC_Clients[i]->Ident), nfds, set ); } } void IPC_HandleSelect(fd_set *set) { - if( giNetworkFileHandle != -1 ) + if( giNetworkFileHandle != -1 && FD_ISSET(giNetworkFileHandle, set) ) { - if( FD_ISSET(giNetworkFileHandle, set) ) - { - char staticBuf[STATICBUF_SIZE]; - int readlen, identlen; - char *msg; + char staticBuf[STATICBUF_SIZE]; + int readlen, identlen; + char *msg; + + readlen = _SysRead(giNetworkFileHandle, staticBuf, sizeof(staticBuf)); + + identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] ); + msg = staticBuf + identlen; + + IPC_Handle( IPC_int_GetClient(&gIPC_Type_Datagram, staticBuf), readlen - identlen, (void*)msg); + //_SysDebug("IPC_HandleSelect: UDP handled"); + } - readlen = read(giNetworkFileHandle, staticBuf, sizeof(staticBuf)); - - identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] ); - msg = staticBuf + identlen; + if( giIPCPipeHandle != -1 && FD_ISSET(giIPCPipeHandle, set) ) + { + int newfd = _SysOpenChild(giIPCPipeHandle, "newclient", OPENFLAG_READ|OPENFLAG_WRITE); + _SysDebug("newfd = %i", newfd); + IPC_int_GetClient(&gIPC_Type_IPCPipe, &newfd); + } - IPC_Handle(&gIPC_Type_Datagram, staticBuf, readlen - identlen, (void*)msg); -// _SysDebug("IPC_HandleSelect: UDP handled"); + for( int i = 0; i < giIPC_ClientCount; i ++ ) + { + if( gIPC_Clients[i] && gIPC_Clients[i]->IPCType == &gIPC_Type_IPCPipe ) + { + int fd = *(const int*)gIPC_Clients[i]->Ident; + if( FD_ISSET(fd, set) ) + { + char staticBuf[STATICBUF_SIZE]; + size_t len; + len = _SysRead(fd, staticBuf, sizeof(staticBuf)); + if( len == (size_t)-1 ) { + // TODO: Check errno for EINTR + IPC_int_DropClient(gIPC_Clients[i]); + break; + } + IPC_Handle( gIPC_Clients[i], len, (void*)staticBuf ); + } } } size_t len; - pid_t tid; - while( (len = SysGetMessage(&tid, 0, NULL)) ) + int tid; + while( (len = _SysGetMessage(&tid, 0, NULL)) ) { char data[len]; - SysGetMessage(NULL, len, data); + _SysGetMessage(NULL, len, data); - IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data); + IPC_Handle( IPC_int_GetClient(&gIPC_Type_SysMessage, &tid), len, (void*)data ); // _SysDebug("IPC_HandleSelect: Message handled"); } } @@ -145,7 +195,7 @@ void IPC_Type_Datagram_Send(const void *Ident, size_t Length, const void *Data) memcpy(tmpbuf, Ident, identlen); // Header memcpy(tmpbuf + identlen, Data, Length); // Data // TODO: Handle fragmented packets - write(giNetworkFileHandle, tmpbuf, sizeof(tmpbuf)); + _SysWrite(giNetworkFileHandle, tmpbuf, sizeof(tmpbuf)); } int IPC_Type_Sys_GetSize(const void *Ident) @@ -160,7 +210,23 @@ 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) { - SysSendMessage( *(const tid_t*)Ident, Length, Data ); + _SysSendMessage( *(const tid_t*)Ident, Length, Data ); +} + +int IPC_Type_IPCPipe_GetSize(const void *Ident) +{ + return sizeof(int); +} +int IPC_Type_IPCPipe_Compare(const void *Ident1, const void *Ident2) +{ + return *(const int*)Ident1 - *(const int*)Ident2; +} +void IPC_Type_IPCPipe_Send(const void *Ident, size_t Length, const void *Data) +{ + size_t rv = _SysWrite( *(const int*)Ident, Data, Length ); + if(rv != Length) { + _SysDebug("Sent message oversize %x", Length); + } } // --- Client -> Window Mappings @@ -168,13 +234,48 @@ int _CompareClientPtrs(const void *_a, const void *_b) { tIPC_Client *a = *(tIPC_Client**)_a; tIPC_Client *b = *(tIPC_Client**)_b; - + + ASSERT(a); + ASSERT(b); + if(a->IPCType < b->IPCType) return -1; if(a->IPCType > b->IPCType) return 1; return a->IPCType->CompareIdent(a->Ident, b->Ident); } +int IPC_int_BSearchClients(const tIPC_Client *TargetClient, int *Pos) +{ + int div; + int cmp = -1; + int pos = 0; + + div = giIPC_ClientCount; + pos = div/2; + while(div > 0) + { + div /= 2; + cmp = _CompareClientPtrs(&TargetClient, &gIPC_Clients[pos]); +// _SysDebug("Checking against %i gives %i", pos, cmp); + if(cmp == 0) break; + if(cmp < 0) + pos -= div; + else + pos += div; + } + + // - Return if found + if(cmp == 0) { + *Pos = pos; + return 1; + } + + // Adjust pos to be the index where the new client will be placed + if(cmp > 0) pos ++; + *Pos = pos; + return 0; +} + tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident) { int pos = 0; // Position where the new client will be inserted @@ -185,33 +286,10 @@ tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident) if(giIPC_ClientCount > 0) { 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]); -// _SysDebug("Checking against %i gives %i", pos, cmp); - if(cmp == 0) break; - if(cmp < 0) - pos -= div; - else - pos += div; - } - - // - Return if found - if(cmp == 0) + if( IPC_int_BSearchClients(&target, &pos) ) return gIPC_Clients[pos]; - - // Adjust pos to be the index where the new client will be placed - if(cmp > 0) pos ++; } @@ -239,6 +317,40 @@ tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident) return ret; } +void IPC_int_DropClient(tIPC_Client *Client) +{ + // Remove from client list + int pos; + if( !IPC_int_BSearchClients(Client, &pos) ) { + _SysDebug("IPC_int_DropClient: Can't find client %p", Client); + return ; + } + + giIPC_ClientCount --; + memmove(&gIPC_Clients[pos], &gIPC_Clients[pos+1], (giIPC_ClientCount-pos)*sizeof(tIPC_Client*)); + + // Terminate client's windows + // - If there were active windows, show an error? + int nWindowsDestroyed = 0; + for(int i = 0; i < Client->nWindows; i ++) + { + if( Client->Windows[i] ) + { + _SysDebug("Window %p:%i %p still exists", Client, i, Client->Windows[i]); + WM_DestroyWindow(Client->Windows[i]); + nWindowsDestroyed ++; + } + } + if( nWindowsDestroyed ) + { + _SysDebug("TODO: Show notice that application exited without destroying windows"); + } + + // Free client structure + free(Client); + _SysDebug("Dropped client %p", Client); +} + tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t WindowID) { if( WindowID == -1 ) @@ -406,6 +518,21 @@ int IPC_Msg_CreateWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg) return 0; } +int IPC_Msg_DestroyWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg) +{ + tWindow *win; + + ASSERT(Msg->ID == IPCMSG_DESTROYWIN); + + win = IPC_int_GetWindow(Client, Msg->Window); + if( !win ) + return 0; + + WM_DestroyWindow(win); + IPC_int_SetWindow(Client, Msg->Window, NULL); + return 0; +} + int IPC_Msg_SetWindowTitle(tIPC_Client *Client, tAxWin_IPCMessage *Msg) { tWindow *win; @@ -461,8 +588,8 @@ int IPC_Msg_FocusWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg) ASSERT(Msg->ID == IPCMSG_FOCUSWINDOW); // 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; +// if(!gpWM_FocusedWindow) return 1; +// if(gpWM_FocusedWindow->Client != Client) return 1; win = IPC_int_GetWindow(Client, Msg->Window); if(!win) return 1; @@ -525,7 +652,7 @@ int (*gIPC_MessageHandlers[])(tIPC_Client *Client, tAxWin_IPCMessage *Msg) = { IPC_Msg_GetDisplayDims, IPC_Msg_SendMsg, IPC_Msg_CreateWin, - NULL, // Destroy window + IPC_Msg_DestroyWin, // Destroy window IPC_Msg_SetWindowTitle, IPC_Msg_ShowWindow, IPC_Msg_DecorateWindow, @@ -535,9 +662,8 @@ int (*gIPC_MessageHandlers[])(tIPC_Client *Client, tAxWin_IPCMessage *Msg) = { }; const int giIPC_NumMessageHandlers = sizeof(gIPC_MessageHandlers)/sizeof(gIPC_MessageHandlers[0]); -void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxWin_IPCMessage *Msg) +void IPC_Handle(tIPC_Client *Client, size_t MsgLen, tAxWin_IPCMessage *Msg) { - tIPC_Client *client; int rv = 0; // _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)", @@ -548,16 +674,11 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW if( MsgLen < sizeof(tAxWin_IPCMessage) + Msg->Size ) return ; - client = IPC_int_GetClient(IPCType, Ident); - if( !client ) { - // Oops? - } - if( Msg->Flags & IPCMSG_FLAG_RENDERER ) { - tWindow *win = IPC_int_GetWindow(client, Msg->Window); + tWindow *win = IPC_int_GetWindow(Client, Msg->Window); if( !win ) { - _SysDebug("WARNING: NULL window in message %i", Msg->ID); + _SysDebug("WARNING: NULL window in message %i (%x)", Msg->ID, Msg->Window); return ; } tWMRenderer *renderer = win->Renderer; @@ -571,13 +692,14 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW } _SysDebug("IPC_Handle: Call %s-%i", renderer->Name, Msg->ID); rv = renderer->IPCHandlers[Msg->ID](win, Msg->Size, Msg->Data); - _SysDebug("IPC_Handle: rv = %i", rv); + if( rv ) + _SysDebug("IPC_Handle: rv != 0 (%i)", rv); } else { if( Msg->ID >= giIPC_NumMessageHandlers ) { - fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType); - _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType); + fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, Client); + _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, Client); return ; } @@ -588,12 +710,13 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW } _SysDebug("IPC_Handle: Call WM-%i", Msg->ID); - rv = gIPC_MessageHandlers[Msg->ID](client, Msg); - _SysDebug("IPC_Handle: rv = %i", rv); + rv = gIPC_MessageHandlers[Msg->ID](Client, Msg); + if( rv ) + _SysDebug("IPC_Handle: rv != 0 (%i)", rv); } } -// --- Server->Client replies +// Dispatch a message to the client void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int MsgID, int Len, void *Data) { tAxWin_IPCMessage *hdr; @@ -616,6 +739,7 @@ void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int MsgI Client->IPCType->SendMessage(Client->Ident, sizeof(buf), buf); } +// --- Server->Client replies void IPC_SendReply(tIPC_Client *Client, uint32_t WinID, int MsgID, size_t Len, const void *Data) { tAxWin_IPCMessage *hdr;