2 * Acess GUI (AxWin) Version 2
3 * By John Hodge (thePowersGang)
8 #include <axwin2/messages.h>
11 #define AXWIN_PORT 4101
13 #define STATICBUF_SIZE 64
19 void IPC_FillSelect(int *nfds, fd_set *set);
20 void IPC_HandleSelect(fd_set *set);
21 void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg);
22 void IPC_ReturnValue(tIPC_Type *IPCType, void *Ident, int MessageID, uint32_t Value);
23 int IPC_Type_Datagram_GetSize(void *Ident);
24 int IPC_Type_Datagram_Compare(void *Ident1, void *Ident2);
25 void IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data);
26 int IPC_Type_Sys_GetSize(void *Ident);
27 int IPC_Type_Sys_Compare(void *Ident1, void *Ident2);
28 void IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data);
31 int giNetworkFileHandle = -1;
32 int giMessagesFileHandle = -1;
33 tIPC_Type gIPC_Type_Datagram = {
34 IPC_Type_Datagram_GetSize,
35 IPC_Type_Datagram_Compare,
36 IPC_Type_Datagram_Send
38 tIPC_Type gIPC_Type_SysMessage = {
49 giNetworkFileHandle = open("/Devices/ip/loop/udp", OPENFLAG_READ);
50 tmp = AXWIN_PORT; ioctl(giNetworkFileHandle, 4, &tmp); // TODO: Don't hard-code IOCtl number
53 void IPC_FillSelect(int *nfds, fd_set *set)
55 if( giNetworkFileHandle > *nfds ) *nfds = giNetworkFileHandle;
56 FD_SET(giNetworkFileHandle, set);
59 void IPC_HandleSelect(fd_set *set)
61 if( FD_ISSET(giNetworkFileHandle, set) )
63 char staticBuf[STATICBUF_SIZE];
64 int readlen, identlen;
67 readlen = read(giNetworkFileHandle, sizeof(staticBuf), staticBuf);
69 identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] );
70 msg = staticBuf + identlen;
72 IPC_Handle(&gIPC_Type_Datagram, staticBuf, readlen - identlen, (void*)msg);
73 _SysDebug("IPC_HandleSelect: UDP handled");
76 while(SysGetMessage(NULL, NULL))
79 int len = SysGetMessage(&tid, NULL);
81 SysGetMessage(NULL, data);
83 IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data);
84 _SysDebug("IPC_HandleSelect: Message handled");
88 void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg)
93 _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)",
94 IPCType, Ident, MsgLen, Msg);
96 if( MsgLen < sizeof(tAxWin_Message) )
98 if( MsgLen < sizeof(tAxWin_Message) + Msg->Size )
101 app = AxWin_GetClient(IPCType, Ident);
103 switch((enum eAxWin_Messages) Msg->ID)
105 // --- Ping message (reset timeout and get server version)
107 _SysDebug(" IPC_Handle: MSG_SREQ_PING");
108 if( MsgLen < sizeof(tAxWin_Message) + 4 ) return;
109 Msg->ID = MSG_SRSP_VERSION;
113 *(uint16_t*)&Msg->Data[2] = -1;
114 IPCType->SendMessage(Ident, sizeof(Msg->ID), Msg);
118 // --- Register an application
119 case MSG_SREQ_REGISTER:
120 _SysDebug(" IPC_Handle: MSG_SREQ_REGISTER");
121 if( Msg->Data[Msg->Size-1] != '\0' ) {
123 _SysDebug("IPC_Handle: RETURN - Not NULL terminated");
128 _SysDebug("Notice: Duplicate registration (%s)\n", Msg->Data);
132 // TODO: Should this function be implemented here?
133 AxWin_RegisterClient(IPCType, Ident, Msg->Data);
136 // --- Create a window
137 case MSG_SREQ_ADDWIN:
138 _SysDebug(" IPC_Handle: MSG_SREQ_ADDWIN");
139 if( Msg->Data[Msg->Size-1] != '\0' ) {
144 ele = AxWin_CreateAppWindow(app, Msg->Data);
145 IPC_ReturnValue(IPCType, Ident, MSG_SREQ_ADDWIN, ele->ApplicationID);
148 // --- Set a window's icon
149 case MSG_SREQ_SETICON:
150 _SysDebug(" IPC_Handle: MSG_SREQ_SETICON");
151 // TODO: Find a good way of implementing this
154 // --- Create an element
155 case MSG_SREQ_INSERT: {
156 _SysDebug(" IPC_Handle: MSG_SREQ_INSERT");
157 struct sAxWin_SReq_NewElement *info = (void *)Msg->Data;
159 if( Msg->Size != sizeof(*info) ) return;
161 if( !app || info->Parent > app->MaxElementIndex ) return ;
163 ele = AxWin_CreateElement( app->EleIndex[info->Parent], info->Type, info->Flags, NULL );
164 IPC_ReturnValue(IPCType, Ident, MSG_SREQ_ADDWIN, ele->ApplicationID);
167 // --- Unknown message
169 fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
170 _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
175 void IPC_ReturnValue(tIPC_Type *IPCType, void *Ident, int MessageID, uint32_t Value)
177 char data[sizeof(tAxWin_Message) + sizeof(tAxWin_RetMsg)];
178 tAxWin_Message *msg = (void *)data;
179 tAxWin_RetMsg *ret_msg = (void *)msg->Data;
181 msg->Source = 0; // 0 = Server
182 msg->ID = MSG_SRSP_RETURN;
183 msg->Size = sizeof(tAxWin_RetMsg);
184 ret_msg->ReqID = MessageID;
186 ret_msg->Value = Value;
188 IPCType->SendMessage(Ident, sizeof(data), data);
191 int IPC_Type_Datagram_GetSize(void *Ident)
193 return 4 + Net_GetAddressSize( ((uint16_t*)Ident)[1] );
196 int IPC_Type_Datagram_Compare(void *Ident1, void *Ident2)
199 // - No need to worry about mis-matching sizes, as the size is computed
200 // from the 3rd/4th bytes, hence it will differ before the size is hit.
201 return memcmp(Ident1, Ident2, IPC_Type_Datagram_GetSize(Ident1));
204 void IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data)
206 int identlen = IPC_Type_Datagram_GetSize(Ident);
207 char tmpbuf[ identlen + Length ];
208 memcpy(tmpbuf, Ident, identlen); // Header
209 memcpy(tmpbuf + identlen, Data, Length); // Data
210 // TODO: Handle fragmented packets
211 write(giNetworkFileHandle, sizeof(tmpbuf), tmpbuf);
214 int IPC_Type_Sys_GetSize(void *Ident)
216 return sizeof(pid_t);
219 int IPC_Type_Sys_Compare(void *Ident1, void *Ident2)
221 return *(int*)Ident1 - *(int*)Ident2;
224 void IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data)
226 SysSendMessage( *(tid_t*)Ident, Length, Data );