X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin2_src%2FWM%2Fmessages.c;h=6fd01c55c0307b9119264f1002abcab95f35ed2b;hb=bd2f2872dd2c125d9200a0465cdeddaf8794e31f;hp=92137f076bf52e525ef782f011d58536665b75f0;hpb=85eb17b306404571aa39596946c87ad9bb1d9d13;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin2_src/WM/messages.c b/Usermode/Applications/axwin2_src/WM/messages.c index 92137f07..6fd01c55 100644 --- a/Usermode/Applications/axwin2_src/WM/messages.c +++ b/Usermode/Applications/axwin2_src/WM/messages.c @@ -4,76 +4,224 @@ */ #include "common.h" #include -#include +#include +#include +#include + +#define AXWIN_PORT 4101 #define STATICBUF_SIZE 64 // === TYPES === -typedef void tMessages_Handle_Callback(int, size_t,void*); // === PROTOTYPES === -void Messages_PollIPC(); -void Messages_RespondIPC(int ID, size_t Length, void *Data); -void Messages_Handle(tAxWin_Message *Msg, tMessages_Handle_Callback *Respond, int ID); +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 Messages_PollIPC() +void IPC_Init(void) { - int len; - pid_t tid = 0; - char staticBuf[STATICBUF_SIZE]; - tAxWin_Message *msg; - - // Wait for a message - while( (len = SysGetMessage(&tid, NULL)) == 0 ) - sleep(); - - // 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 ; - } - } - - // Get message data - SysGetMessage(NULL, msg); - - Messages_Handle(msg, Messages_RespondIPC, tid); + int tmp; + // TODO: Check this + giNetworkFileHandle = open("/Devices/ip/loop/udp", OPENFLAG_READ); + tmp = AXWIN_PORT; ioctl(giNetworkFileHandle, 4, &tmp); // TODO: Don't hard-code IOCtl number } -void Messages_RespondIPC(int ID, size_t Length, void *Data) +void IPC_FillSelect(int *nfds, fd_set *set) { - SysSendMessage(ID, Length, Data); + if( giNetworkFileHandle > *nfds ) *nfds = giNetworkFileHandle; + FD_SET(giNetworkFileHandle, set); +} + +void IPC_HandleSelect(fd_set *set) +{ + if( FD_ISSET(giNetworkFileHandle, set) ) + { + char staticBuf[STATICBUF_SIZE]; + int readlen, identlen; + char *msg; + + readlen = read(giNetworkFileHandle, sizeof(staticBuf), staticBuf); + + identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] ); + msg = staticBuf + identlen; + + 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"); + } } -void Messages_Handle(tAxWin_Message *Msg, tMessages_Handle_Callback *Respond, int ID) +void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg) { - switch(Msg->ID) + 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((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; - Messages_RespondIPC(ID, 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 ; + } + + 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; - #endif + + // --- 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 from %i (%p)\n", Msg->ID, ID, Respond); - _SysDebug("WARNING: Unknown message %i from %i (%p)\n", Msg->ID, 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 ); +}