DiskTool - Added LVM support
[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_SENDMESSAGE,
20         CONNTYPE_UDP,
21         CONNTYPE_TCP
22 };
23
24 // === GLOBALS ===
25 enum eConnectionType    giConnectionType;
26 int     giConnectionNum;        // FD or PID
27 char    gaAxWin3_int_UDPHeader[] = {5,16,0,0};  // Port 4101
28  int    giAxWin3_int_UDPHeaderLen = sizeof(gaAxWin3_int_UDPHeader);
29 const char      *gsAxWin3_int_ServerDesc;
30 tAxWin3_MessageCallback gAxWin3_MessageCallback;
31
32 // === CODE ===
33 void AxWin3_Connect(const char *ServerDesc)
34 {
35         _SysDebug("ServerDesc = %s", ServerDesc);
36         if( !ServerDesc )
37         {
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                 break;
53         case 'u':
54                 while(*ServerDesc && *ServerDesc != ':')        ServerDesc ++;
55                 ServerDesc ++;
56                 // TODO: Open socket and create UDP header
57                 break;
58         case 't':
59                 while(*ServerDesc && *ServerDesc != ':')        ServerDesc ++;
60                 ServerDesc ++;
61                 // TODO: Open socket
62                 break;
63         }
64 }
65
66 tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback)
67 {
68         tAxWin3_MessageCallback old = gAxWin3_MessageCallback;
69         gAxWin3_MessageCallback = Callback;
70         return old;
71 }
72
73 uint32_t AxWin3_int_GetWindowID(tHWND Window)
74 {
75         if(Window)
76                 return Window->ServerID;
77         else
78                 return -1;
79 }
80
81 tAxWin_IPCMessage *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes)
82 {
83         tAxWin_IPCMessage       *ret;
84
85         ret = malloc( sizeof(tAxWin_IPCMessage) + ExtraBytes );
86         ret->Flags = Flags;
87         ret->ID = Message;
88         ret->Window = AxWin3_int_GetWindowID(Window);
89         ret->Size = ExtraBytes;
90         return ret;
91 }
92
93 void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
94 {
95          int    size = sizeof(tAxWin_IPCMessage) + Msg->Size;
96         switch(giConnectionType)
97         {
98         case CONNTYPE_SENDMESSAGE:
99                 SysSendMessage(giConnectionNum, size, Msg);
100                 break;
101         case CONNTYPE_UDP: {
102                 // Create UDP header
103                 char    tmpbuf[giAxWin3_int_UDPHeaderLen + size];
104                 memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen);
105                 memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size);
106                 write(giConnectionNum, tmpbuf, sizeof(tmpbuf));
107                 }
108                 break;
109         case CONNTYPE_TCP:
110                 write(giConnectionNum, Msg, size);
111                 break;
112         default:
113                 break;
114         }
115 }
116
117 tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(void)
118 {
119          int    len;
120         tAxWin_IPCMessage       *ret = NULL;
121         switch(giConnectionType)
122         {
123         case CONNTYPE_SENDMESSAGE:
124                 for( ;; )
125                 {
126                         pid_t   tid;
127                 
128                         // Wait for a message to arrive 
129                         while( !(len = SysGetMessage(&tid, NULL)) )
130                         {
131                                 _SysWaitEvent(THREAD_EVENT_IPCMSG);
132                         }
133                         
134                         // Check if the message came from the server
135                         if(tid != giConnectionNum)
136                         {
137                                 _SysDebug("%i byte message from %i", len, tid);
138                                 // If not, pass the buck (or ignore)
139                                 if( gAxWin3_MessageCallback )
140                                         gAxWin3_MessageCallback(tid, len);
141                                 else
142                                         SysGetMessage(NULL, GETMSG_IGNORE);
143                                 continue ;
144                         }
145                         
146                         // If it's from the server, allocate a buffer and return it
147                         ret = malloc(len);
148                         if(ret == NULL) {
149                                 _SysDebug("malloc() failed, ignoring message");
150                                 SysGetMessage(NULL, GETMSG_IGNORE);
151                                 return NULL;
152                         }
153                         SysGetMessage(NULL, ret);
154                         break;
155                 }
156                 break;
157         default:
158                 // TODO: Implement
159                 _SysDebug("TODO: Implement AxWin3_int_GetIPCMessage for TCP/UDP");
160                 break;
161         }
162
163         // No message?
164         if( ret == NULL )
165                 return NULL;
166
167         // TODO: Sanity checks, so a stupid server can't crash us
168
169         return ret;
170 }
171
172 tAxWin_IPCMessage *AxWin3_int_WaitIPCMessage(int WantedID)
173 {
174         tAxWin_IPCMessage       *msg;
175         for(;;)
176         {
177                 msg = AxWin3_int_GetIPCMessage();
178                 if(msg->ID == WantedID) return msg;
179                 AxWin3_int_HandleMessage( msg );
180                 free(msg);
181         }
182 }
183

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