Usermode/AxWin3 - Added keysyms (symlink to kernel version)
[tpg/acess2.git] / Usermode / Applications / axwin2_src / WM / messages.c
1 /*
2  * Acess GUI (AxWin) Version 2
3  * By John Hodge (thePowersGang)
4  */
5 #include "common.h"
6 #include <acess/sys.h>
7 #include <net.h>
8 #include <axwin2/messages.h>
9 #include <string.h>
10
11 #define AXWIN_PORT      4101
12
13 #define STATICBUF_SIZE  64
14
15 // === TYPES ===
16
17 // === PROTOTYPES ===
18 void    IPC_Init(void);
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);
29
30 // === GLOBALS ===
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
37 };
38 tIPC_Type       gIPC_Type_SysMessage = {
39         IPC_Type_Sys_GetSize,
40         IPC_Type_Sys_Compare,
41         IPC_Type_Sys_Send
42 };
43
44 // === CODE ===
45 void IPC_Init(void)
46 {
47          int    tmp;
48         // TODO: Check this
49         giNetworkFileHandle = open("/Devices/ip/loop/udp", OPENFLAG_READ);
50         tmp = AXWIN_PORT;       ioctl(giNetworkFileHandle, 4, &tmp);    // TODO: Don't hard-code IOCtl number
51 }
52
53 void IPC_FillSelect(int *nfds, fd_set *set)
54 {
55         if( giNetworkFileHandle > *nfds )       *nfds = giNetworkFileHandle;
56         FD_SET(giNetworkFileHandle, set);
57 }
58
59 void IPC_HandleSelect(fd_set *set)
60 {
61         if( FD_ISSET(giNetworkFileHandle, set) )
62         {
63                 char    staticBuf[STATICBUF_SIZE];
64                  int    readlen, identlen;
65                 char    *msg;
66
67                 readlen = read(giNetworkFileHandle, staticBuf, sizeof(staticBuf));
68                 
69                 identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] );
70                 msg = staticBuf + identlen;
71
72                 IPC_Handle(&gIPC_Type_Datagram, staticBuf, readlen - identlen, (void*)msg);
73                 _SysDebug("IPC_HandleSelect: UDP handled");
74         }
75
76         while(SysGetMessage(NULL, NULL))
77         {
78                 pid_t   tid;
79                  int    len = SysGetMessage(&tid, NULL);
80                 char    data[len];
81                 SysGetMessage(NULL, data);
82
83                 IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data);
84                 _SysDebug("IPC_HandleSelect: Message handled");
85         }
86 }
87
88 void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg)
89 {
90         tApplication    *app;
91         tElement        *ele;
92         
93         _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)",
94                 IPCType, Ident, MsgLen, Msg);
95         
96         if( MsgLen < sizeof(tAxWin_Message) )
97                 return ;
98         if( MsgLen < sizeof(tAxWin_Message) + Msg->Size )
99                 return ;
100         
101         app = AxWin_GetClient(IPCType, Ident);
102
103         switch((enum eAxWin_Messages) Msg->ID)
104         {
105         // --- Ping message (reset timeout and get server version)
106         case MSG_SREQ_PING:
107                 _SysDebug(" IPC_Handle: MSG_SREQ_PING");
108                 if( MsgLen < sizeof(tAxWin_Message) + 4 )       return;
109                 Msg->ID = MSG_SRSP_VERSION;
110                 Msg->Size = 4;
111                 Msg->Data[0] = 0;
112                 Msg->Data[1] = 1;
113                 *(uint16_t*)&Msg->Data[2] = -1;
114                 IPCType->SendMessage(Ident, sizeof(Msg->ID), Msg);
115                 break;
116
117
118         // --- Register an application
119         case MSG_SREQ_REGISTER:
120                 _SysDebug(" IPC_Handle: MSG_SREQ_REGISTER");
121                 if( Msg->Data[Msg->Size-1] != '\0' ) {
122                         // Invalid message
123                         _SysDebug("IPC_Handle: RETURN - Not NULL terminated");
124                         return ;
125                 }
126                 
127                 if( app != NULL ) {
128                         _SysDebug("Notice: Duplicate registration (%s)\n", Msg->Data);
129                         return ;
130                 }
131                 
132                 // TODO: Should this function be implemented here?
133                 AxWin_RegisterClient(IPCType, Ident, Msg->Data);
134                 break;
135         
136         // --- Create a window
137         case MSG_SREQ_ADDWIN:
138                 _SysDebug(" IPC_Handle: MSG_SREQ_ADDWIN");
139                 if( Msg->Data[Msg->Size-1] != '\0' ) {
140                         // Invalid message
141                         return ;
142                 }
143                 
144                 ele = AxWin_CreateAppWindow(app, Msg->Data);
145                 IPC_ReturnValue(IPCType, Ident, MSG_SREQ_ADDWIN, ele->ApplicationID);
146                 break;
147         
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
152                 break;
153         
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;
158                 
159                 if( Msg->Size != sizeof(*info) )        return;
160                 
161                 if( !app || info->Parent > app->MaxElementIndex )       return ;
162                 
163                 ele = AxWin_CreateElement( app->EleIndex[info->Parent], info->Type, info->Flags, NULL );
164                 IPC_ReturnValue(IPCType, Ident, MSG_SREQ_ADDWIN, ele->ApplicationID);
165                 break; }
166         
167         // --- Unknown message
168         default:
169                 fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
170                 _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
171                 break;
172         }
173 }
174
175 void IPC_ReturnValue(tIPC_Type *IPCType, void *Ident, int MessageID, uint32_t Value)
176 {
177         char    data[sizeof(tAxWin_Message) + sizeof(tAxWin_RetMsg)];
178         tAxWin_Message  *msg = (void *)data;
179         tAxWin_RetMsg   *ret_msg = (void *)msg->Data;
180         
181         msg->Source = 0;        // 0 = Server
182         msg->ID = MSG_SRSP_RETURN;
183         msg->Size = sizeof(tAxWin_RetMsg);
184         ret_msg->ReqID = MessageID;
185         ret_msg->Rsvd = 0;
186         ret_msg->Value = Value;
187         
188         IPCType->SendMessage(Ident, sizeof(data), data);
189 }
190
191 int IPC_Type_Datagram_GetSize(void *Ident)
192 {
193         return 4 + Net_GetAddressSize( ((uint16_t*)Ident)[1] );
194 }
195
196 int IPC_Type_Datagram_Compare(void *Ident1, void *Ident2)
197 {
198         // Pass the buck :)
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));
202 }
203
204 void IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data)
205 {
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, tmpbuf, sizeof(tmpbuf));
212 }
213
214 int IPC_Type_Sys_GetSize(void *Ident)
215 {
216         return sizeof(pid_t);
217 }
218
219 int IPC_Type_Sys_Compare(void *Ident1, void *Ident2)
220 {
221         return *(int*)Ident1 - *(int*)Ident2;
222 }
223
224 void IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data)
225 {
226         SysSendMessage( *(tid_t*)Ident, Length, Data );
227 }

UCC git Repository :: git.ucc.asn.au