AxWin2 - Cleaned out messy code
[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  int    IPC_Type_Datagram_GetSize(void *Ident);
23  int    IPC_Type_Datagram_Compare(void *Ident1, void *Ident2);
24 void    IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data);
25  int    IPC_Type_Sys_GetSize(void *Ident);
26  int    IPC_Type_Sys_Compare(void *Ident1, void *Ident2);
27 void    IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data);
28
29 // === GLOBALS ===
30  int    giNetworkFileHandle = -1;
31  int    giMessagesFileHandle = -1;
32 tIPC_Type       gIPC_Type_Datagram = {
33         IPC_Type_Datagram_GetSize,
34         IPC_Type_Datagram_Compare, 
35         IPC_Type_Datagram_Send
36 };
37 tIPC_Type       gIPC_Type_SysMessage = {
38         IPC_Type_Sys_GetSize,
39         IPC_Type_Sys_Compare,
40         IPC_Type_Sys_Send
41 };
42
43 // === CODE ===
44 void IPC_Init(void)
45 {
46          int    tmp;
47         // TODO: Check this
48         giNetworkFileHandle = open("/Devices/ip/loop/udp", OPENFLAG_READ);
49         tmp = AXWIN_PORT;       ioctl(giNetworkFileHandle, 4, &tmp);    // TODO: Don't hard-code IOCtl number
50 }
51
52 void IPC_FillSelect(int *nfds, fd_set *set)
53 {
54         if( giNetworkFileHandle > *nfds )       *nfds = giNetworkFileHandle;
55         FD_SET(giNetworkFileHandle, set);
56 }
57
58 void IPC_HandleSelect(fd_set *set)
59 {
60         if( FD_ISSET(giNetworkFileHandle, set) )
61         {
62                 char    staticBuf[STATICBUF_SIZE];
63                  int    readlen, identlen;
64                 char    *msg;
65
66                 readlen = read(giNetworkFileHandle, sizeof(staticBuf), staticBuf);
67                 
68                 // Assume that all connections are from localhost
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         }
74
75         while(SysGetMessage(NULL, NULL))
76         {
77                 pid_t   tid;
78                  int    len = SysGetMessage(&tid, NULL);
79                 char    data[len];
80                 SysGetMessage(NULL, data);
81
82                 IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data);
83         }
84 }
85
86 void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_Message *Msg)
87 {
88         tApplication    *app;
89         
90         if( MsgLen < sizeof(tAxWin_Message) )
91                 return ;
92         if( MsgLen < sizeof(tAxWin_Message) + Msg->Size )
93                 return ;
94         
95         app = AxWin_GetClient(IPCType, Ident);
96
97         switch((enum eAxWin_Messages) Msg->ID)
98         {
99         // --- Ping message (reset timeout and get server version)
100         case MSG_SREQ_PING:
101                 if( MsgLen < sizeof(tAxWin_Message) + 4 )       return;
102                 Msg->ID = MSG_SRSP_VERSION;
103                 Msg->Size = 4;
104                 Msg->Data[0] = 0;
105                 Msg->Data[1] = 1;
106                 *(uint16_t*)&Msg->Data[2] = -1;
107                 IPCType->SendMessage(Ident, sizeof(Msg->ID), Msg);
108                 break;
109
110
111         // --- Register an application
112         case MSG_SREQ_REGISTER:
113                 if( Msg->Data[Msg->Size-1] != '\0' ) {
114                         // Invalid message
115                         return ;
116                 }
117                 
118                 if( app != NULL ) {
119                         _SysDebug("Notice: Duplicate registration (%s)\n", Msg->Data);
120                         return ;
121                 }
122                 
123                 // TODO: Should this function be implemented here?
124                 AxWin_RegisterClient(IPCType, Ident, Msg->Data);
125                 break;
126         
127         // --- Create a window
128         case MSG_SREQ_ADDWIN:
129                 if( Msg->Data[Msg->Size-1] != '\0' ) {
130                         // Invalid message
131                         return ;
132                 }
133                 
134                 break;
135         
136         // --- Unknown message
137         default:
138                 fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
139                 _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
140                 break;
141         }
142 }
143
144 int IPC_Type_Datagram_GetSize(void *Ident)
145 {
146         return 4 + Net_GetAddressSize( ((uint16_t*)Ident)[1] );
147 }
148
149 int IPC_Type_Datagram_Compare(void *Ident1, void *Ident2)
150 {
151         // Pass the buck :)
152         // - No need to worry about mis-matching sizes, as the size is computed
153         //   from the 3rd/4th bytes, hence it will differ before the size is hit.
154         return memcmp(Ident1, Ident2, IPC_Type_Datagram_GetSize(Ident1));
155 }
156
157 void IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data)
158 {
159          int    identlen = IPC_Type_Datagram_GetSize(Ident);
160         char    tmpbuf[ identlen + Length ];
161         memcpy(tmpbuf, Ident, identlen);        // Header
162         memcpy(tmpbuf + identlen, Data, Length);        // Data
163         // TODO: Handle fragmented packets
164         write(giNetworkFileHandle, sizeof(tmpbuf), tmpbuf);
165 }
166
167 int IPC_Type_Sys_GetSize(void *Ident)
168 {
169         return sizeof(pid_t);
170 }
171
172 int IPC_Type_Sys_Compare(void *Ident1, void *Ident2)
173 {
174         return *(int*)Ident1 - *(int*)Ident2;
175 }
176
177 void IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data)
178 {
179         SysSendMessage( *(tid_t*)Ident, Length, Data );
180 }

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