Usermode - Renamed VFS syscalls to _Sys* to remove POSIX collisions
[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 (argument) = %s", ServerDesc);
37         if( !ServerDesc ) {
38                 ServerDesc = gsAxWin3_int_ServerDesc;
39         }
40         _SysDebug("ServerDesc = %s", ServerDesc);
41         if( !ServerDesc )
42         {
43                 // TODO: Error out
44                 return ;
45         }
46         switch(ServerDesc[0])
47         {
48         case '1': case '2': case '3': case '4': case '5':
49         case '6': case '7': case '8': case '9': case '0':
50                 giConnectionType = CONNTYPE_SENDMESSAGE;
51                 giConnectionNum = atoi(ServerDesc);
52                 if( giConnectionNum == 0 ) {
53                         _SysDebug("Invalid server PID");
54                         exit(-1);
55                 }
56                 break;
57         case 'u':
58                 while(*ServerDesc && *ServerDesc != ':')        ServerDesc ++;
59                 ServerDesc ++;
60                 // TODO: Open socket and create UDP header
61                 break;
62         case 't':
63                 while(*ServerDesc && *ServerDesc != ':')        ServerDesc ++;
64                 ServerDesc ++;
65                 // TODO: Open socket
66                 break;
67         }
68 }
69
70 tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback)
71 {
72         tAxWin3_MessageCallback old = gAxWin3_MessageCallback;
73         gAxWin3_MessageCallback = Callback;
74         return old;
75 }
76
77 uint32_t AxWin3_int_GetWindowID(tHWND Window)
78 {
79         if(Window)
80                 return Window->ServerID;
81         else
82                 return -1;
83 }
84
85 tAxWin_IPCMessage *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes)
86 {
87         tAxWin_IPCMessage       *ret;
88
89         ret = malloc( sizeof(tAxWin_IPCMessage) + ExtraBytes );
90         ret->Flags = Flags;
91         ret->ID = Message;
92         ret->Window = AxWin3_int_GetWindowID(Window);
93         ret->Size = ExtraBytes;
94         return ret;
95 }
96
97 void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
98 {
99          int    size = sizeof(tAxWin_IPCMessage) + Msg->Size;
100         switch(giConnectionType)
101         {
102         case CONNTYPE_SENDMESSAGE:
103                 SysSendMessage(giConnectionNum, size, Msg);
104                 break;
105         case CONNTYPE_UDP: {
106                 // Create UDP header
107                 char    tmpbuf[giAxWin3_int_UDPHeaderLen + size];
108                 memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen);
109                 memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size);
110                 _SysWrite(giConnectionNum, tmpbuf, sizeof(tmpbuf));
111                 }
112                 break;
113         case CONNTYPE_TCP:
114                 _SysWrite(giConnectionNum, Msg, size);
115                 break;
116         default:
117                 break;
118         }
119 }
120
121 tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(int nFD, fd_set *fds)
122 {
123          int    len;
124         tAxWin_IPCMessage       *ret = NULL;
125          int    tid;
126
127         _SysSelect(nFD, fds, NULL, NULL, NULL, THREAD_EVENT_IPCMSG);
128         
129         // Clear out IPC messages
130         while( (len = SysGetMessage(&tid, 0, NULL)) )
131         {
132                 if( giConnectionType != CONNTYPE_SENDMESSAGE || tid != giConnectionNum )
133                 {
134                         _SysDebug("%i byte message from %i", len, tid);
135                         // If not, pass the buck (or ignore)
136                         if( gAxWin3_MessageCallback )
137                                 gAxWin3_MessageCallback(tid, len);
138                         else
139                                 SysGetMessage(NULL, 0, GETMSG_IGNORE);
140                         continue ;
141                 }
142                 
143                 // Using CONNTYPE_SENDMESSAGE and server message has arrived
144                 ret = malloc(len);
145                 if(ret == NULL) {
146                         _SysDebug("malloc() failed, ignoring message");
147                         SysGetMessage(NULL, 0, GETMSG_IGNORE);
148                         return NULL;
149                 }
150                 SysGetMessage(NULL, len, ret);
151                 break;
152         }
153
154         if( giConnectionType == CONNTYPE_TCP || giConnectionType == CONNTYPE_UDP )
155         {
156                 // Check fds
157         }
158
159         return ret;
160 }
161
162 tAxWin_IPCMessage *AxWin3_int_WaitIPCMessage(int WantedID)
163 {
164         tAxWin_IPCMessage       *msg;
165         for(;;)
166         {
167                 msg = AxWin3_int_GetIPCMessage(0, NULL);
168                 if(msg->ID == WantedID) return msg;
169                 AxWin3_int_HandleMessage( msg );
170         }
171 }
172

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