Syscalls - Changed SysGetMessage to provide a buffer size
[tpg/acess2.git] / Usermode / Applications / axwin3_src / libaxwin3.so_src / msg.c
1 /*
2  * AxWin3 Interface Library
3  * - By John Hodge (thePowersGang)
4  *
5  * msg.c
6  * - Message handling / IPC
7  */
8 #include <axwin3/axwin.h>
9 #include <acess/sys.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <ipcmessages.h>        // AxWin3 common
13 #include "include/internal.h"
14 #include "include/ipc.h"
15
16 // === CONSTANTS ===
17 enum eConnectionType
18 {
19         CONNTYPE_NONE,
20         CONNTYPE_SENDMESSAGE,
21         CONNTYPE_UDP,
22         CONNTYPE_TCP
23 };
24
25 // === GLOBALS ===
26 enum eConnectionType    giConnectionType;
27 int     giConnectionNum;        // FD or PID
28 char    gaAxWin3_int_UDPHeader[] = {5,16,0,0};  // Port 4101
29  int    giAxWin3_int_UDPHeaderLen = sizeof(gaAxWin3_int_UDPHeader);
30 const char      *gsAxWin3_int_ServerDesc;
31 tAxWin3_MessageCallback gAxWin3_MessageCallback;
32
33 // === CODE ===
34 void AxWin3_Connect(const char *ServerDesc)
35 {
36         _SysDebug("ServerDesc = %s", ServerDesc);
37         if( !ServerDesc )
38         {
39                 ServerDesc = gsAxWin3_int_ServerDesc;
40         }
41         _SysDebug("ServerDesc = %s", ServerDesc);
42         if( !ServerDesc )
43         {
44                 // TODO: Error out
45                 return ;
46         }
47         switch(ServerDesc[0])
48         {
49         case '1': case '2': case '3': case '4': case '5':
50         case '6': case '7': case '8': case '9': case '0':
51                 giConnectionType = CONNTYPE_SENDMESSAGE;
52                 giConnectionNum = atoi(ServerDesc);
53                 break;
54         case 'u':
55                 while(*ServerDesc && *ServerDesc != ':')        ServerDesc ++;
56                 ServerDesc ++;
57                 // TODO: Open socket and create UDP header
58                 break;
59         case 't':
60                 while(*ServerDesc && *ServerDesc != ':')        ServerDesc ++;
61                 ServerDesc ++;
62                 // TODO: Open socket
63                 break;
64         }
65 }
66
67 tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback)
68 {
69         tAxWin3_MessageCallback old = gAxWin3_MessageCallback;
70         gAxWin3_MessageCallback = Callback;
71         return old;
72 }
73
74 uint32_t AxWin3_int_GetWindowID(tHWND Window)
75 {
76         if(Window)
77                 return Window->ServerID;
78         else
79                 return -1;
80 }
81
82 tAxWin_IPCMessage *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes)
83 {
84         tAxWin_IPCMessage       *ret;
85
86         ret = malloc( sizeof(tAxWin_IPCMessage) + ExtraBytes );
87         ret->Flags = Flags;
88         ret->ID = Message;
89         ret->Window = AxWin3_int_GetWindowID(Window);
90         ret->Size = ExtraBytes;
91         return ret;
92 }
93
94 void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
95 {
96          int    size = sizeof(tAxWin_IPCMessage) + Msg->Size;
97         switch(giConnectionType)
98         {
99         case CONNTYPE_SENDMESSAGE:
100                 SysSendMessage(giConnectionNum, size, Msg);
101                 break;
102         case CONNTYPE_UDP: {
103                 // Create UDP header
104                 char    tmpbuf[giAxWin3_int_UDPHeaderLen + size];
105                 memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen);
106                 memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size);
107                 write(giConnectionNum, tmpbuf, sizeof(tmpbuf));
108                 }
109                 break;
110         case CONNTYPE_TCP:
111                 write(giConnectionNum, Msg, size);
112                 break;
113         default:
114                 break;
115         }
116 }
117
118 tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(void)
119 {
120          int    len;
121         tAxWin_IPCMessage       *ret = NULL;
122         switch(giConnectionType)
123         {
124         case CONNTYPE_SENDMESSAGE:
125                 for( ;; )
126                 {
127                         pid_t   tid;
128                 
129                         // Wait for a message to arrive 
130                         while( !(len = SysGetMessage(&tid, 0, NULL)) )
131                         {
132                                 _SysWaitEvent(THREAD_EVENT_IPCMSG);
133                         }
134                         
135                         // Check if the message came from the server
136                         if(tid != giConnectionNum)
137                         {
138                                 _SysDebug("%i byte message from %i", len, tid);
139                                 // If not, pass the buck (or ignore)
140                                 if( gAxWin3_MessageCallback )
141                                         gAxWin3_MessageCallback(tid, len);
142                                 else
143                                         SysGetMessage(NULL, 0, GETMSG_IGNORE);
144                                 continue ;
145                         }
146                         
147                         // If it's from the server, allocate a buffer and return it
148                         ret = malloc(len);
149                         if(ret == NULL) {
150                                 _SysDebug("malloc() failed, ignoring message");
151                                 SysGetMessage(NULL, 0, GETMSG_IGNORE);
152                                 return NULL;
153                         }
154                         SysGetMessage(NULL, len, ret);
155                         break;
156                 }
157                 break;
158         default:
159                 // TODO: Implement
160                 _SysDebug("TODO: Implement AxWin3_int_GetIPCMessage for TCP/UDP");
161                 break;
162         }
163
164         // No message?
165         if( ret == NULL )
166                 return NULL;
167
168         // TODO: Sanity checks, so a stupid server can't crash us
169
170         return ret;
171 }
172
173 tAxWin_IPCMessage *AxWin3_int_WaitIPCMessage(int WantedID)
174 {
175         tAxWin_IPCMessage       *msg;
176         for(;;)
177         {
178                 msg = AxWin3_int_GetIPCMessage();
179                 if(msg->ID == WantedID) return msg;
180                 AxWin3_int_HandleMessage( msg );
181                 free(msg);
182         }
183 }
184

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