Usermode/AxWin3 - Implementing SendMessage for client
[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
15 // === CONSTANTS ===
16 enum eConnectionType
17 {
18         CONNTYPE_SENDMESSAGE,
19         CONNTYPE_UDP,
20         CONNTYPE_TCP
21 };
22
23 // === GLOBALS ===
24 enum eConnectionType    giConnectionType;
25 int     giConnectionNum;        // FD or PID
26 char    gaAxWin3_int_UDPHeader[] = {5,16,0,0};  // Port 4101
27  int    giAxWin3_int_UDPHeaderLen = sizeof(gaAxWin3_int_UDPHeader);
28 const char      *gsAxWin3_int_ServerDesc;
29 tAxWin3_MessageCallback gAxWin3_MessageCallback;
30
31 // === CODE ===
32 void AxWin3_Connect(const char *ServerDesc)
33 {
34         _SysDebug("ServerDesc = %s", ServerDesc);
35         if( !ServerDesc )
36         {
37                 ServerDesc = gsAxWin3_int_ServerDesc;
38         }
39         _SysDebug("ServerDesc = %s", ServerDesc);
40         if( !ServerDesc )
41         {
42                 // TODO: Error out
43                 return ;
44         }
45         switch(ServerDesc[0])
46         {
47         case '1': case '2': case '3': case '4': case '5':
48         case '6': case '7': case '8': case '9': case '0':
49                 giConnectionType = CONNTYPE_SENDMESSAGE;
50                 giConnectionNum = atoi(ServerDesc);
51                 break;
52         case 'u':
53                 while(*ServerDesc && *ServerDesc != ':')        ServerDesc ++;
54                 ServerDesc ++;
55                 // TODO: Open socket and create UDP header
56                 break;
57         case 't':
58                 while(*ServerDesc && *ServerDesc != ':')        ServerDesc ++;
59                 ServerDesc ++;
60                 // TODO: Open socket
61                 break;
62         }
63 }
64
65 tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback)
66 {
67         tAxWin3_MessageCallback old = gAxWin3_MessageCallback;
68         gAxWin3_MessageCallback = Callback;
69         return old;
70 }
71
72 uint32_t AxWin3_int_GetWindowID(tHWND Window)
73 {
74         if(Window)
75                 return Window->ServerID;
76         else
77                 return -1;
78 }
79
80 tAxWin_IPCMessage *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes)
81 {
82         tAxWin_IPCMessage       *ret;
83
84         ret = malloc( sizeof(tAxWin_IPCMessage) + ExtraBytes );
85         ret->Flags = Flags;
86         ret->ID = Message;
87         ret->Window = AxWin3_int_GetWindowID(Window);
88         ret->Size = ExtraBytes;
89         return ret;
90 }
91
92 void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
93 {
94          int    size = sizeof(tAxWin_IPCMessage) + Msg->Size;
95         switch(giConnectionType)
96         {
97         case CONNTYPE_SENDMESSAGE:
98                 SysSendMessage(giConnectionNum, size, Msg);
99                 break;
100         case CONNTYPE_UDP: {
101                 // Create UDP header
102                 char    tmpbuf[giAxWin3_int_UDPHeaderLen + size];
103                 memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen);
104                 memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size);
105                 write(giConnectionNum, tmpbuf, sizeof(tmpbuf));
106                 }
107                 break;
108         case CONNTYPE_TCP:
109                 write(giConnectionNum, Msg, size);
110                 break;
111         default:
112                 break;
113         }
114 }
115
116 tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(void)
117 {
118          int    len;
119         tAxWin_IPCMessage       *ret = NULL;
120         switch(giConnectionType)
121         {
122         case CONNTYPE_SENDMESSAGE:
123                 // TODO: Less hack, I need a version of select for GetMessage etc
124                 if(SysGetMessage(NULL, NULL) == 0)      sleep();
125                 while(SysGetMessage(NULL, NULL))
126                 {
127                         pid_t   tid;
128                         len = SysGetMessage(&tid, NULL);
129                         // Check if the message came from the server
130                         if(tid != giConnectionNum)
131                         {
132                                 // If not, pass the buck (or ignore)
133                                 if( gAxWin3_MessageCallback )
134                                         gAxWin3_MessageCallback(tid, len);
135                                 else
136                                         SysGetMessage(NULL, GETMSG_IGNORE);
137                                 continue ;
138                         }
139                         
140                         // If it's from the server, allocate a buffer and return it
141                         ret = malloc(len);
142                         if(ret == NULL) return NULL;
143                         SysGetMessage(NULL, ret);
144                         break;
145                 }
146                 break;
147         default:
148                 // TODO: Implement
149                 _SysDebug("TODO: Implement AxWin3_int_GetIPCMessage for TCP/UDP");
150                 break;
151         }
152
153         // No message?
154         if( ret == NULL )
155                 return NULL;
156
157         // TODO: Sanity checks, so a stupid server can't crash us
158
159         return ret;
160 }
161

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