2 * AxWin3 Interface Library
3 * - By John Hodge (thePowersGang)
6 * - Message handling / IPC
8 #include <axwin3/axwin.h>
12 #include <ipcmessages.h> // AxWin3 common
13 #include "include/internal.h"
14 #include "include/ipc.h"
16 #define assert(cnd) do{if(!(cnd)){_SysDebug("Assertion failed: %s", #cnd);}}while(0)
18 #define STATICBUF_SIZE 0x1000
31 enum eConnectionType giConnectionType;
32 int giConnectionNum; // FD or PID
33 char gaAxWin3_int_UDPHeader[] = {5,16,0,0}; // Port 4101
34 int giAxWin3_int_UDPHeaderLen = sizeof(gaAxWin3_int_UDPHeader);
35 const char *gsAxWin3_int_ServerDesc;
36 tAxWin3_MessageCallback gAxWin3_MessageCallback;
39 void AxWin3_Connect(const char *ServerDesc)
42 ServerDesc = gsAxWin3_int_ServerDesc;
44 _SysDebug("ServerDesc = %s", ServerDesc);
52 case '1': case '2': case '3': case '4': case '5':
53 case '6': case '7': case '8': case '9': case '0':
54 giConnectionType = CONNTYPE_SENDMESSAGE;
55 giConnectionNum = atoi(ServerDesc);
56 if( giConnectionNum == 0 ) {
57 _SysDebug("Invalid server PID");
62 assert( strncmp(ServerDesc, "udp:", 4) == 0 );
64 _SysDebug("TODO: UDP connection to '%s'", ServerDesc);
65 // TODO: Open socket and create UDP header
68 assert( strncmp(ServerDesc, "tcp:", 4) == 0 );
70 _SysDebug("TODO: TCP connection to '%s'", ServerDesc);
74 assert( strncmp(ServerDesc, "pipe:", 5) == 0 );
76 giConnectionType = CONNTYPE_IPCPIPE;
77 giConnectionNum = _SysOpen(ServerDesc, OPENFLAG_READ|OPENFLAG_WRITE);
78 if( giConnectionNum == -1 ) {
79 _SysDebug("Cannot open IPC Pipe '%s'", ServerDesc);
84 _SysDebug("Unknown server desc format '%s'", ServerDesc);
90 tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback)
92 tAxWin3_MessageCallback old = gAxWin3_MessageCallback;
93 gAxWin3_MessageCallback = Callback;
97 uint32_t AxWin3_int_GetWindowID(tHWND Window)
100 return Window->ServerID;
105 tAxWin_IPCMessage *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes)
107 tAxWin_IPCMessage *ret;
109 ret = malloc( sizeof(tAxWin_IPCMessage) + ExtraBytes );
112 ret->Window = AxWin3_int_GetWindowID(Window);
113 ret->Size = ExtraBytes;
117 void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
119 int size = sizeof(tAxWin_IPCMessage) + Msg->Size;
120 switch(giConnectionType)
122 case CONNTYPE_SENDMESSAGE:
123 _SysSendMessage(giConnectionNum, size, Msg);
127 char tmpbuf[giAxWin3_int_UDPHeaderLen + size];
128 memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen);
129 memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size);
130 _SysWrite(giConnectionNum, tmpbuf, sizeof(tmpbuf));
133 case CONNTYPE_IPCPIPE:
135 _SysWrite(giConnectionNum, Msg, size);
142 tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(int nFD, fd_set *fds)
145 tAxWin_IPCMessage *ret = NULL;
152 if( giConnectionType != CONNTYPE_SENDMESSAGE )
154 if(nFD <= giConnectionNum)
155 nFD = giConnectionNum+1;
156 FD_SET(giConnectionNum, fds);
159 _SysSelect(nFD, fds, NULL, NULL, NULL, THREAD_EVENT_IPCMSG);
161 // Clear out IPC messages
162 while( (len = _SysGetMessage(&tid, 0, NULL)) )
164 if( giConnectionType != CONNTYPE_SENDMESSAGE || tid != giConnectionNum )
166 _SysDebug("%i byte message from %i", len, tid);
167 // If not, pass the buck (or ignore)
168 if( gAxWin3_MessageCallback )
169 gAxWin3_MessageCallback(tid, len);
171 _SysGetMessage(NULL, 0, GETMSG_IGNORE);
175 // Using CONNTYPE_SENDMESSAGE and server message has arrived
178 _SysDebug("malloc() failed, ignoring message");
179 _SysGetMessage(NULL, 0, GETMSG_IGNORE);
182 _SysGetMessage(NULL, len, ret);
186 if( giConnectionType != CONNTYPE_SENDMESSAGE )
188 if( FD_ISSET(giConnectionNum, fds) )
190 char tmpbuf[STATICBUF_SIZE];
192 size_t len = _SysRead(giConnectionNum, tmpbuf, sizeof(tmpbuf));
194 if( giConnectionType == CONNTYPE_UDP )
196 assert(len > giAxWin3_int_UDPHeaderLen);
197 len -= giAxWin3_int_UDPHeaderLen;
198 data += giAxWin3_int_UDPHeaderLen;
200 assert(len >= sizeof(tAxWin_IPCMessage));
202 memcpy(ret, data, len);
209 tAxWin_IPCMessage *AxWin3_int_WaitIPCMessage(int WantedID)
211 tAxWin_IPCMessage *msg;
214 msg = AxWin3_int_GetIPCMessage(0, NULL);
215 if(msg->ID == WantedID) return msg;
216 AxWin3_int_HandleMessage( msg );