X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin2_src%2FWM%2Fmessages.c;h=f25e1c4b1cefd377b779ab3a9289925a21b0270e;hb=ada42e7583b4fa07b30d5c1a3e813c9754ec5e0f;hp=af7c81944d3dd1fcd6dff6a684f6d91f6294b86f;hpb=b32d0aff4c3ed251970a2244d5ead84cd86d50cd;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin2_src/WM/messages.c b/Usermode/Applications/axwin2_src/WM/messages.c index af7c8194..f25e1c4b 100644 --- a/Usermode/Applications/axwin2_src/WM/messages.c +++ b/Usermode/Applications/axwin2_src/WM/messages.c @@ -6,23 +6,40 @@ #include #include #include -//#include +#include #define AXWIN_PORT 4101 #define STATICBUF_SIZE 64 // === TYPES === -typedef void tMessages_Handle_Callback(void*, size_t, void*); // === PROTOTYPES === -void Messages_PollIPC(); -void Messages_RespondIPC(void *Ident, size_t Length, void *Data); -void Messages_Handle(void *Ident, int MsgLen, tAxWin_Message *Msg, tMessages_Handle_Callback *Respond); +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_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) @@ -30,10 +47,7 @@ void IPC_Init(void) int tmp; // TODO: Check this giNetworkFileHandle = open("/Devices/ip/loop/udp", OPENFLAG_READ); - tmp = AXWIN_PORT; ioctl(giIPCFileHandle, 4, &tmp); // TODO: Don't hard-code IOCtl number - - // TODO: Open a handle to something like /Devices/proc/cur/messages to watch for messages -// giMessagesFileHandle = open("/Devices/" + tmp = AXWIN_PORT; ioctl(giNetworkFileHandle, 4, &tmp); // TODO: Don't hard-code IOCtl number } void IPC_FillSelect(int *nfds, fd_set *set) @@ -44,79 +58,170 @@ void IPC_FillSelect(int *nfds, fd_set *set) void IPC_HandleSelect(fd_set *set) { - if( FD_ISSET(giIPCFileHandle, set) ) + if( FD_ISSET(giNetworkFileHandle, set) ) { char staticBuf[STATICBUF_SIZE]; int readlen, identlen; char *msg; - readlen = read(giIPCFileHandle, sizeof(staticBuf), staticBuf); + readlen = read(giNetworkFileHandle, staticBuf, sizeof(staticBuf)); - // Assume that all connections are from localhost identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] ); msg = staticBuf + identlen; - Messages_Handle(staticBuf, readlen - identlen, (void*)msg, Messages_RespondIPC); + IPC_Handle(&gIPC_Type_Datagram, staticBuf, readlen - identlen, (void*)msg); + _SysDebug("IPC_HandleSelect: UDP handled"); + } + + while(SysGetMessage(NULL, NULL)) + { + pid_t tid; + int len = SysGetMessage(&tid, NULL); + char data[len]; + SysGetMessage(NULL, data); + + IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data); + _SysDebug("IPC_HandleSelect: Message handled"); } } -#if 0 -void Messages_PollIPC() +void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg) { - int len; - pid_t tid = 0; - char staticBuf[STATICBUF_SIZE]; - tAxWin_Message *msg; + tApplication *app; + tElement *ele; - // Wait for a message - while( (len = SysGetMessage(&tid, NULL)) == 0 ) - sleep(); + _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)", + IPCType, Ident, MsgLen, Msg); - // Allocate the space for it - if( len <= STATICBUF_SIZE ) - msg = (void*)staticBuf; - else { - msg = malloc( len ); - if(!msg) { - fprintf( - stderr, - "ERROR - Unable to allocate message buffer, ignoring message from %i\n", - tid); - SysGetMessage(NULL, GETMSG_IGNORE); - return ; - } - } + if( MsgLen < sizeof(tAxWin_Message) ) + return ; + if( MsgLen < sizeof(tAxWin_Message) + Msg->Size ) + return ; - // Get message data - SysGetMessage(NULL, msg); - - Messages_Handle(msg, Messages_RespondIPC, tid); -} -#endif + app = AxWin_GetClient(IPCType, Ident); -void Messages_RespondIPC(void *Ident, size_t Length, void *Data) -{ - SysSendMessage( *(tid_t*)Ident, Length, Data ); -} - -void Messages_Handle(void *Ident, int MsgLen, tAxWin_Message *Msg, tMessages_Handle_Callback *Respond) -{ - switch(Msg->ID) + switch((enum eAxWin_Messages) Msg->ID) { - #if 0 + // --- 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 = 2; + 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; - #endif + + + // --- 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 ; + } + + 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, 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 ); +}