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 while(*ServerDesc && *ServerDesc != ':') ServerDesc ++;
64 // TODO: Open socket and create UDP header
67 while(*ServerDesc && *ServerDesc != ':') ServerDesc ++;
72 assert( strncmp(ServerDesc, "pipe:", 5) == 0 );
74 giConnectionType = CONNTYPE_IPCPIPE;
75 giConnectionNum = _SysOpen(ServerDesc, OPENFLAG_READ|OPENFLAG_WRITE);
76 if( giConnectionNum == -1 ) {
77 _SysDebug("Cannot open IPC Pipe '%s'", ServerDesc);
82 _SysDebug("Unknown server desc format '%s'", ServerDesc);
88 tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback)
90 tAxWin3_MessageCallback old = gAxWin3_MessageCallback;
91 gAxWin3_MessageCallback = Callback;
95 uint32_t AxWin3_int_GetWindowID(tHWND Window)
98 return Window->ServerID;
103 tAxWin_IPCMessage *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes)
105 tAxWin_IPCMessage *ret;
107 ret = malloc( sizeof(tAxWin_IPCMessage) + ExtraBytes );
110 ret->Window = AxWin3_int_GetWindowID(Window);
111 ret->Size = ExtraBytes;
115 void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
117 int size = sizeof(tAxWin_IPCMessage) + Msg->Size;
118 switch(giConnectionType)
120 case CONNTYPE_SENDMESSAGE:
121 _SysSendMessage(giConnectionNum, size, Msg);
125 char tmpbuf[giAxWin3_int_UDPHeaderLen + size];
126 memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen);
127 memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size);
128 _SysWrite(giConnectionNum, tmpbuf, sizeof(tmpbuf));
131 case CONNTYPE_IPCPIPE:
133 _SysWrite(giConnectionNum, Msg, size);
140 tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(int nFD, fd_set *fds)
143 tAxWin_IPCMessage *ret = NULL;
150 if( giConnectionType != CONNTYPE_SENDMESSAGE )
152 if(nFD <= giConnectionNum)
153 nFD = giConnectionNum+1;
154 FD_SET(giConnectionNum, fds);
157 _SysSelect(nFD, fds, NULL, NULL, NULL, THREAD_EVENT_IPCMSG);
159 // Clear out IPC messages
160 while( (len = _SysGetMessage(&tid, 0, NULL)) )
162 if( giConnectionType != CONNTYPE_SENDMESSAGE || tid != giConnectionNum )
164 _SysDebug("%i byte message from %i", len, tid);
165 // If not, pass the buck (or ignore)
166 if( gAxWin3_MessageCallback )
167 gAxWin3_MessageCallback(tid, len);
169 _SysGetMessage(NULL, 0, GETMSG_IGNORE);
173 // Using CONNTYPE_SENDMESSAGE and server message has arrived
176 _SysDebug("malloc() failed, ignoring message");
177 _SysGetMessage(NULL, 0, GETMSG_IGNORE);
180 _SysGetMessage(NULL, len, ret);
184 if( giConnectionType != CONNTYPE_SENDMESSAGE )
186 if( FD_ISSET(giConnectionNum, fds) )
188 char tmpbuf[STATICBUF_SIZE];
190 size_t len = _SysRead(giConnectionNum, tmpbuf, sizeof(tmpbuf));
192 if( giConnectionType == CONNTYPE_UDP )
194 assert(len > giAxWin3_int_UDPHeaderLen);
195 len -= giAxWin3_int_UDPHeaderLen;
196 data += giAxWin3_int_UDPHeaderLen;
198 assert(len >= sizeof(tAxWin_IPCMessage));
200 memcpy(ret, data, len);
207 tAxWin_IPCMessage *AxWin3_int_WaitIPCMessage(int WantedID)
209 tAxWin_IPCMessage *msg;
212 msg = AxWin3_int_GetIPCMessage(0, NULL);
213 if(msg->ID == WantedID) return msg;
214 AxWin3_int_HandleMessage( msg );