Usermode/AxWin3 - Fixed all compile errors, runs and cursor moves, that is all
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / ipc.c
1 /*
2  * Acess2 GUI (AxWin) Version 3
3  * - By John Hodge (thePowersGang)
4  * 
5  * ipc.c
6  * - Interprocess communication
7  */
8 #include <common.h>
9 #include <acess/sys.h>
10 #include <net.h>
11 #include <string.h>
12 #include <ipcmessages.h>
13 #include <stdio.h>
14
15 #define AXWIN_PORT      4101
16
17 #define STATICBUF_SIZE  64
18
19 // === TYPES ===
20 typedef struct sIPC_Type        tIPC_Type;
21 struct sIPC_Type
22 {
23          int    (*GetIdentSize)(void *Ident);
24          int    (*CompareIdent)(void *Ident1, void *Ident2);
25         void    (*SendMessage)(void *Ident, size_t, void *Data);
26 };
27
28 // === PROTOTYPES ===
29 void    IPC_Init(void);
30 void    IPC_FillSelect(int *nfds, fd_set *set);
31 void    IPC_HandleSelect(fd_set *set);
32 void    IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_IPCMessage *Msg);
33 void    IPC_ReturnValue(tIPC_Type *IPCType, void *Ident, int MessageID, uint32_t Value);
34  int    IPC_Type_Datagram_GetSize(void *Ident);
35  int    IPC_Type_Datagram_Compare(void *Ident1, void *Ident2);
36 void    IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data);
37  int    IPC_Type_Sys_GetSize(void *Ident);
38  int    IPC_Type_Sys_Compare(void *Ident1, void *Ident2);
39 void    IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data);
40
41 // === GLOBALS ===
42  int    giNetworkFileHandle = -1;
43  int    giMessagesFileHandle = -1;
44 tIPC_Type       gIPC_Type_Datagram = {
45         IPC_Type_Datagram_GetSize,
46         IPC_Type_Datagram_Compare, 
47         IPC_Type_Datagram_Send
48 };
49 tIPC_Type       gIPC_Type_SysMessage = {
50         IPC_Type_Sys_GetSize,
51         IPC_Type_Sys_Compare,
52         IPC_Type_Sys_Send
53 };
54
55 // === CODE ===
56 void IPC_Init(void)
57 {
58          int    tmp;
59         // TODO: Check this
60         giNetworkFileHandle = open("/Devices/ip/loop/udp", OPENFLAG_READ);
61         tmp = AXWIN_PORT;       ioctl(giNetworkFileHandle, 4, &tmp);    // TODO: Don't hard-code IOCtl number
62 }
63
64 void IPC_FillSelect(int *nfds, fd_set *set)
65 {
66         if( giNetworkFileHandle > *nfds )       *nfds = giNetworkFileHandle;
67         FD_SET(giNetworkFileHandle, set);
68 }
69
70 void IPC_HandleSelect(fd_set *set)
71 {
72         if( FD_ISSET(giNetworkFileHandle, set) )
73         {
74                 char    staticBuf[STATICBUF_SIZE];
75                  int    readlen, identlen;
76                 char    *msg;
77
78                 readlen = read(giNetworkFileHandle, staticBuf, sizeof(staticBuf));
79                 
80                 identlen = 4 + Net_GetAddressSize( ((uint16_t*)staticBuf)[1] );
81                 msg = staticBuf + identlen;
82
83                 IPC_Handle(&gIPC_Type_Datagram, staticBuf, readlen - identlen, (void*)msg);
84                 _SysDebug("IPC_HandleSelect: UDP handled");
85         }
86
87         while(SysGetMessage(NULL, NULL))
88         {
89                 pid_t   tid;
90                  int    len = SysGetMessage(&tid, NULL);
91                 char    data[len];
92                 SysGetMessage(NULL, data);
93
94                 IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data);
95                 _SysDebug("IPC_HandleSelect: Message handled");
96         }
97 }
98
99 void IPC_Handle(tIPC_Type *IPCType, void *Ident, size_t MsgLen, tAxWin_IPCMessage *Msg)
100 {
101         _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)",
102                 IPCType, Ident, MsgLen, Msg);
103         
104         if( MsgLen < sizeof(tAxWin_IPCMessage) )
105                 return ;
106         if( MsgLen < sizeof(tAxWin_IPCMessage) + Msg->Size )
107                 return ;
108         
109 //      win = AxWin_GetClient(IPCType, Ident, Msg->Window);
110
111         switch((enum eAxWin_IPCMessageTypes) Msg->ID)
112         {
113         // --- Ping message (reset timeout and get server version)
114         case IPCMSG_PING:
115                 _SysDebug(" IPC_Handle: IPCMSG_PING");
116                 if( MsgLen < sizeof(tAxWin_IPCMessage) + 4 )    return;
117                 if( Msg->Flags & IPCMSG_FLAG_RETURN )
118                 {
119                         Msg->ID = IPCMSG_PING;
120                         Msg->Size = sizeof(tIPCMsg_Return);
121                         ((tIPCMsg_Return*)Msg->Data)->Value = AXWIN_VERSION;
122                         IPCType->SendMessage(Ident, sizeof(tIPCMsg_Return), Msg);
123                 }
124                 break;
125
126         // --- 
127
128         // --- Unknown message
129         default:
130                 fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
131                 _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
132                 break;
133         }
134 }
135
136 int IPC_Type_Datagram_GetSize(void *Ident)
137 {
138         return 4 + Net_GetAddressSize( ((uint16_t*)Ident)[1] );
139 }
140
141 int IPC_Type_Datagram_Compare(void *Ident1, void *Ident2)
142 {
143         // Pass the buck :)
144         // - No need to worry about mis-matching sizes, as the size is computed
145         //   from the 3rd/4th bytes, hence it will differ before the size is hit.
146         return memcmp(Ident1, Ident2, IPC_Type_Datagram_GetSize(Ident1));
147 }
148
149 void IPC_Type_Datagram_Send(void *Ident, size_t Length, void *Data)
150 {
151          int    identlen = IPC_Type_Datagram_GetSize(Ident);
152         char    tmpbuf[ identlen + Length ];
153         memcpy(tmpbuf, Ident, identlen);        // Header
154         memcpy(tmpbuf + identlen, Data, Length);        // Data
155         // TODO: Handle fragmented packets
156         write(giNetworkFileHandle, tmpbuf, sizeof(tmpbuf));
157 }
158
159 int IPC_Type_Sys_GetSize(void *Ident)
160 {
161         return sizeof(pid_t);
162 }
163
164 int IPC_Type_Sys_Compare(void *Ident1, void *Ident2)
165 {
166         return *(int*)Ident1 - *(int*)Ident2;
167 }
168
169 void IPC_Type_Sys_Send(void *Ident, size_t Length, void *Data)
170 {
171         SysSendMessage( *(tid_t*)Ident, Length, Data );
172 }

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