X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin2_src%2FWM%2Fmessages.c;h=6fd01c55c0307b9119264f1002abcab95f35ed2b;hb=bd2f2872dd2c125d9200a0465cdeddaf8794e31f;hp=61ffc53042d94b4cb2dee1ae7aeb2ff15fe31a1a;hpb=3117b20bcbfbed588ede9b29a7f90eafc762b138;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin2_src/WM/messages.c b/Usermode/Applications/axwin2_src/WM/messages.c index 61ffc530..6fd01c55 100644 --- a/Usermode/Applications/axwin2_src/WM/messages.c +++ b/Usermode/Applications/axwin2_src/WM/messages.c @@ -18,13 +18,28 @@ void IPC_Init(void); void IPC_FillSelect(int *nfds, fd_set *set); void IPC_HandleSelect(fd_set *set); -void Messages_RespondDatagram(void *Ident, size_t Length, void *Data); -void Messages_RespondIPC(void *Ident, size_t Length, void *Data); -void Messages_Handle(size_t IdentLen, void *Ident, size_t MsgLen, tAxWin_Message *Msg, tMessages_Handle_Callback *Respond); +void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *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); // === GLOBALS === int giNetworkFileHandle = -1; int giMessagesFileHandle = -1; +tIPC_Type gIPC_Type_Datagram = { + IPC_Type_Datagram_GetSize, + IPC_Type_Datagram_Compare, + IPC_Type_Datagram_Send +}; +tIPC_Type gIPC_Type_SysMessage = { + IPC_Type_Sys_GetSize, + IPC_Type_Sys_Compare, + IPC_Type_Sys_Send +}; // === CODE === void IPC_Init(void) @@ -51,11 +66,11 @@ void IPC_HandleSelect(fd_set *set) readlen = read(giNetworkFileHandle, sizeof(staticBuf), staticBuf); - // Assume that all connections are from localhost identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] ); msg = staticBuf + identlen; - Messages_Handle(identlen, staticBuf, readlen - identlen, (void*)msg, Messages_RespondDatagram); + IPC_Handle(&gIPC_Type_Datagram, staticBuf, readlen - identlen, (void*)msg); + _SysDebug("IPC_HandleSelect: UDP handled"); } while(SysGetMessage(NULL, NULL)) @@ -65,58 +80,148 @@ void IPC_HandleSelect(fd_set *set) char data[len]; SysGetMessage(NULL, data); - Messages_Handle(sizeof(tid), &tid, len, (void*)data, Messages_RespondIPC); + IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data); + _SysDebug("IPC_HandleSelect: Message handled"); } } -void Messages_RespondDatagram(void *Ident, size_t Length, void *Data) -{ - int addrSize = Net_GetAddressSize( ((uint16_t*)Ident)[1] ); - char tmpbuf[ 4 + addrSize + Length ]; - memcpy(tmpbuf, Ident, 4 + addrSize); - memcpy(tmpbuf + 4 + addrSize, Data, Length); - // TODO: Handle fragmented packets - write(giNetworkFileHandle, sizeof(tmpbuf), tmpbuf); -} - -void Messages_RespondIPC(void *Ident, size_t Length, void *Data) -{ - SysSendMessage( *(tid_t*)Ident, Length, Data ); -} - -void Messages_Handle(size_t IdentLen, void *Ident, size_t MsgLen, tAxWin_Message *Msg, tMessages_Handle_Callback *Respond) +void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg) { + tApplication *app; + tElement *ele; + + _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)", + IPCType, Ident, MsgLen, Msg); + if( MsgLen < sizeof(tAxWin_Message) ) return ; if( MsgLen < sizeof(tAxWin_Message) + Msg->Size ) return ; + + app = AxWin_GetClient(IPCType, Ident); - switch(Msg->ID) + switch((enum eAxWin_Messages) Msg->ID) { + // --- Ping message (reset timeout and get server version) case MSG_SREQ_PING: + _SysDebug(" IPC_Handle: MSG_SREQ_PING"); if( MsgLen < sizeof(tAxWin_Message) + 4 ) return; Msg->ID = MSG_SRSP_VERSION; Msg->Size = 4; Msg->Data[0] = 0; Msg->Data[1] = 1; *(uint16_t*)&Msg->Data[2] = -1; - Respond(Ident, sizeof(Msg->ID), Msg); + IPCType->SendMessage(Ident, sizeof(Msg->ID), Msg); break; + + // --- Register an application case MSG_SREQ_REGISTER: + _SysDebug(" IPC_Handle: MSG_SREQ_REGISTER"); if( Msg->Data[Msg->Size-1] != '\0' ) { // Invalid message + _SysDebug("IPC_Handle: RETURN - Not NULL terminated"); return ; } - AxWin_RegisterClient(IdentLen, Ident, Respond, Msg->Data); - + if( app != NULL ) { + _SysDebug("Notice: Duplicate registration (%s)\n", Msg->Data); + return ; + } + + // TODO: Should this function be implemented here? + AxWin_RegisterClient(IPCType, Ident, Msg->Data); break; - + + // --- Create a window + case MSG_SREQ_ADDWIN: + _SysDebug(" IPC_Handle: MSG_SREQ_ADDWIN"); + if( Msg->Data[Msg->Size-1] != '\0' ) { + // Invalid message + return ; + } + + ele = AxWin_CreateAppWindow(app, Msg->Data); + IPC_ReturnValue(IPCType, Ident, MSG_SREQ_ADDWIN, ele->ApplicationID); + break; + + // --- Set a window's icon + case MSG_SREQ_SETICON: + _SysDebug(" IPC_Handle: MSG_SREQ_SETICON"); + // TODO: Find a good way of implementing this + break; + + // --- Create an element + case MSG_SREQ_INSERT: { + _SysDebug(" IPC_Handle: MSG_SREQ_INSERT"); + struct sAxWin_SReq_NewElement *info = (void *)Msg->Data; + + if( Msg->Size != sizeof(*info) ) return; + + if( !app || info->Parent > app->MaxElementIndex ) return ; + + ele = AxWin_CreateElement( app->EleIndex[info->Parent], info->Type, info->Flags, NULL ); + IPC_ReturnValue(IPCType, Ident, MSG_SREQ_ADDWIN, ele->ApplicationID); + break; } + + // --- Unknown message default: - fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, Respond); - _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, Respond); + fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType); + _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType); break; } } +void IPC_ReturnValue(tIPC_Type *IPCType, void *Ident, int MessageID, uint32_t Value) +{ + char data[sizeof(tAxWin_Message) + sizeof(tAxWin_RetMsg)]; + tAxWin_Message *msg = (void *)data; + tAxWin_RetMsg *ret_msg = (void *)msg->Data; + + msg->Source = 0; // 0 = Server + msg->ID = MSG_SRSP_RETURN; + msg->Size = sizeof(tAxWin_RetMsg); + ret_msg->ReqID = MessageID; + ret_msg->Rsvd = 0; + ret_msg->Value = Value; + + IPCType->SendMessage(Ident, sizeof(data), data); +} + +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, sizeof(tmpbuf), 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 ); +}