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"
17 #define assert(cnd) do{if(!(cnd)){_SysDebug("Assertion failed: %s", #cnd);}}while(0)
19 #define STATICBUF_SIZE 0x1000
32 enum eConnectionType giConnectionType;
33 int giConnectionNum; // FD or PID
34 char gaAxWin3_int_UDPHeader[] = {5,16,0,0}; // Port 4101
35 int giAxWin3_int_UDPHeaderLen = sizeof(gaAxWin3_int_UDPHeader);
36 const char *gsAxWin3_int_ServerDesc;
37 tAxWin3_MessageCallback gAxWin3_MessageCallback;
40 void AxWin3_Connect(const char *ServerDesc)
43 ServerDesc = gsAxWin3_int_ServerDesc;
45 _SysDebug("ServerDesc = %s", ServerDesc);
53 case '1': case '2': case '3': case '4': case '5':
54 case '6': case '7': case '8': case '9': case '0':
55 giConnectionType = CONNTYPE_SENDMESSAGE;
56 giConnectionNum = atoi(ServerDesc);
57 if( giConnectionNum == 0 ) {
58 _SysDebug("Invalid server PID");
63 assert( strncmp(ServerDesc, "udp:", 4) == 0 );
65 _SysDebug("TODO: UDP connection to '%s'", ServerDesc);
66 // TODO: Open socket and create UDP header
69 assert( strncmp(ServerDesc, "tcp:", 4) == 0 );
71 _SysDebug("TODO: TCP connection to '%s'", ServerDesc);
75 assert( strncmp(ServerDesc, "pipe:", 5) == 0 );
77 giConnectionType = CONNTYPE_IPCPIPE;
78 giConnectionNum = _SysOpen(ServerDesc, OPENFLAG_READ|OPENFLAG_WRITE);
79 if( giConnectionNum == -1 ) {
80 _SysDebug("Cannot open IPC Pipe '%s'", ServerDesc);
85 _SysDebug("Unknown server desc format '%s'", ServerDesc);
91 tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback)
93 tAxWin3_MessageCallback old = gAxWin3_MessageCallback;
94 gAxWin3_MessageCallback = Callback;
98 uint32_t AxWin3_int_GetWindowID(tHWND Window)
101 return Window->ServerID;
106 tAxWin_IPCMessage *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes)
108 tAxWin_IPCMessage *ret;
110 ret = malloc( sizeof(tAxWin_IPCMessage) + ExtraBytes );
113 ret->Window = AxWin3_int_GetWindowID(Window);
114 ret->Size = ExtraBytes;
118 void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
120 int size = sizeof(tAxWin_IPCMessage) + Msg->Size;
121 switch(giConnectionType)
123 case CONNTYPE_SENDMESSAGE:
124 _SysSendMessage(giConnectionNum, size, Msg);
128 char tmpbuf[giAxWin3_int_UDPHeaderLen + size];
129 memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen);
130 memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size);
131 size_t rv = _SysWrite(giConnectionNum, tmpbuf, sizeof(tmpbuf));
133 _SysDebug("AxWin3 SendIPCMessage: UDP Write Failed %s", strerror(errno));
138 case CONNTYPE_IPCPIPE:
140 size_t rv = _SysWrite(giConnectionNum, Msg, size);
142 _SysDebug("AxWin3 SendIPCMessage: Write Failed %s - sent %i want %i",
143 strerror(errno), rv, size);
153 tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(int nFD, fd_set *fds)
156 tAxWin_IPCMessage *ret = NULL;
163 if( giConnectionType != CONNTYPE_SENDMESSAGE )
165 if(nFD <= giConnectionNum)
166 nFD = giConnectionNum+1;
167 FD_SET(giConnectionNum, fds);
170 _SysSelect(nFD, fds, NULL, NULL, NULL, THREAD_EVENT_IPCMSG);
172 // Clear out IPC messages
173 while( (len = _SysGetMessage(&tid, 0, NULL)) )
175 if( giConnectionType != CONNTYPE_SENDMESSAGE || tid != giConnectionNum )
177 _SysDebug("%i byte message from %i", len, tid);
178 // If not, pass the buck (or ignore)
179 if( gAxWin3_MessageCallback )
180 gAxWin3_MessageCallback(tid, len);
182 _SysGetMessage(NULL, 0, GETMSG_IGNORE);
186 // Using CONNTYPE_SENDMESSAGE and server message has arrived
189 _SysDebug("malloc() failed, ignoring message");
190 _SysGetMessage(NULL, 0, GETMSG_IGNORE);
193 _SysGetMessage(NULL, len, ret);
197 if( giConnectionType != CONNTYPE_SENDMESSAGE )
199 if( FD_ISSET(giConnectionNum, fds) )
201 char tmpbuf[STATICBUF_SIZE];
203 size_t len = _SysRead(giConnectionNum, tmpbuf, sizeof(tmpbuf));
205 if( giConnectionType == CONNTYPE_UDP )
207 assert(len > giAxWin3_int_UDPHeaderLen);
208 len -= giAxWin3_int_UDPHeaderLen;
209 data += giAxWin3_int_UDPHeaderLen;
211 assert(len >= sizeof(tAxWin_IPCMessage));
213 memcpy(ret, data, len);
220 tAxWin_IPCMessage *AxWin3_int_WaitIPCMessage(int WantedID)
222 tAxWin_IPCMessage *msg;
225 msg = AxWin3_int_GetIPCMessage(0, NULL);
226 if(msg->ID == WantedID) return msg;
227 AxWin3_int_HandleMessage( msg );