Usermode/AxWin4 - Fix deserialiser, ::std::map for client windows, debugging
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / ipc.cpp
1 /*
2  */
3 #define __STDC_LIMIT_MACROS
4 #include <ipc.hpp>
5 #include <list>
6 #include <IIPCChannel.hpp>
7 #include <algorithm>
8 #include <CClient.hpp>
9 #include <serialisation.hpp>
10 #include <ipc_proto.hpp>
11 #include <CCompositor.hpp>
12 extern "C" {
13 #include <assert.h>
14 };
15 #include <CIPCChannel_AcessIPCPipe.hpp>
16
17 namespace AxWin {
18 namespace IPC {
19
20 CCompositor*    gpCompositor;
21 ::std::list<IIPCChannel*>       glChannels;
22 //::std::map<uint16_t,CClient*> glClients;
23
24 void Initialise(const CConfigIPC& config, CCompositor& compositor)
25 {
26         gpCompositor = &compositor;
27         
28         ::std::string pipe_basepath = "axwin4";
29         glChannels.push_back( new CIPCChannel_AcessIPCPipe( pipe_basepath ) );
30
31         //glChannels.push_back( new CIPCChannel_TCP("0.0.0.0:2100") );
32         
33         //for( auto channel : config.m_channels )
34         //{
35         //      channels.push_back(  );
36         //}
37 }
38
39 int FillSelect(fd_set& rfds)
40 {
41         int ret = 0;
42         _SysDebug("IPC::FillSelect");
43         for( auto channel : glChannels )
44         {
45                 _SysDebug("IPC::FillSelect - channel=%p", channel);
46                 ret = ::std::max(ret, channel->FillSelect(rfds));
47         }
48         return ret;
49 }
50
51 void HandleSelect(const fd_set& rfds)
52 {
53         _SysDebug("IPC::HandleSelect");
54         for( auto channel : glChannels )
55         {
56                 _SysDebug("IPC::HandleSelect - channel=%p", channel);
57                 channel->HandleSelect(rfds);
58         }
59 }
60
61 void RegisterClient(CClient& client)
62 {
63         // allocate a client ID, and save
64         //client.m_id = 123;
65         //glClients[client.m_id] = &client;
66 }
67
68 void DeregisterClient(CClient& client)
69 {
70         //glClients.erase( client.m_id );
71 }
72
73
74
75 void HandleMessage_Nop(CClient& client, CDeserialiser& message)
76 {
77 }
78 void HandleMessage_Reply(CClient& client, CDeserialiser& message)
79 {
80         // Reply to a sent message
81         // - Not many messages need server-bound replies
82         int orig_command = message.ReadU8();
83         switch(orig_command)
84         {
85         case IPCMSG_PING:
86                 // Ping reply, mark client as still responding
87                 break;
88         default:
89                 // Unexpected reply
90                 break;
91         }
92 }
93
94 void HandleMessage_Ping(CClient& client, CDeserialiser& message)
95 {
96         // A client has asked for a ping, we pong them back
97         CSerialiser     reply;
98         reply.WriteU8(IPCMSG_REPLY);
99         reply.WriteU8(IPCMSG_PING);
100         client.SendMessage(reply);
101 }
102
103 void HandleMessage_GetGlobalAttr(CClient& client, CDeserialiser& message)
104 {
105         uint16_t        attr_id = message.ReadU16();
106         
107         CSerialiser     reply;
108         reply.WriteU8(IPCMSG_REPLY);
109         reply.WriteU8(IPCMSG_GETGLOBAL);
110         reply.WriteU16(attr_id);
111         
112         switch(attr_id)
113         {
114         case IPC_GLOBATTR_SCREENDIMS: {
115                 uint8_t screen_id = message.ReadU8();
116                 unsigned int w, h;
117                 gpCompositor->GetScreenDims(screen_id, &w, &h);
118                 reply.WriteU16( (w <= UINT16_MAX ? w : UINT16_MAX) );
119                 reply.WriteU16( (h <= UINT16_MAX ? h : UINT16_MAX) );
120                 break; }
121         default:
122                 throw IPC::CClientFailure("Bad global attribute ID");
123         }
124         
125         client.SendMessage(reply);
126 }
127
128 void HandleMessage_SetGlobalAttr(CClient& client, CDeserialiser& message)
129 {
130         uint16_t        attr_id = message.ReadU16();
131         
132         switch(attr_id)
133         {
134         case IPC_GLOBATTR_SCREENDIMS:
135                 // Setting readonly
136                 break;
137         case IPC_GLOBATTR_MAXAREA:
138                 assert(!"TODO: IPC_GLOBATTR_MAXAREA");
139                 break;
140         default:
141                 throw IPC::CClientFailure("Bad global attribute ID");
142         }
143 }
144
145 void HandleMessage_CreateWindow(CClient& client, CDeserialiser& message)
146 {
147         uint16_t        new_id = message.ReadU16();
148         //uint16_t      parent_id = message.ReadU16();
149         //CWindow* parent = client.GetWindow( parent_id );
150         ::std::string   name = message.ReadString();
151         
152         ::_SysDebug("_CreateWindow: (%i, '%s')", new_id, name.c_str());
153         client.SetWindow( new_id, gpCompositor->CreateWindow(client, name) );
154 }
155
156 void HandleMessage_DestroyWindow(CClient& client, CDeserialiser& message)
157 {
158         uint16_t        win_id = message.ReadU16();
159         
160         CWindow*        win = client.GetWindow(win_id);
161         if(!win) {
162                 throw IPC::CClientFailure("Bad window");
163         }
164         client.SetWindow(win_id, 0);    
165         
166         // TODO: Directly inform compositor?
167         delete win;
168 }
169
170 void HandleMessage_SetWindowAttr(CClient& client, CDeserialiser& message)
171 {
172         uint16_t        win_id = message.ReadU16();
173         uint16_t        attr_id = message.ReadU16();
174
175         CWindow*        win = client.GetWindow(win_id);
176         if(!win) {
177                 throw IPC::CClientFailure("Bad window");
178         }
179         
180         switch(attr_id)
181         {
182         case IPC_WINATTR_DIMENSIONS: {
183                 uint16_t new_w = message.ReadU16();
184                 uint16_t new_h = message.ReadU16();
185                 win->Resize(new_w, new_h);
186                 assert(!"TODO: IPC_WINATTR_DIMENSIONS");
187                 break; }
188         case IPC_WINATTR_POSITION: {
189                 int16_t new_x = message.ReadS16();
190                 int16_t new_y = message.ReadS16();
191                 win->Move(new_x, new_y);
192                 assert(!"TODO: IPC_WINATTR_POSITION");
193                 break; }
194         default:
195                 _SysDebug("HandleMessage_SetWindowAttr - Bad attr %u", attr_id);
196                 throw IPC::CClientFailure("Bad window attr");
197         }
198 }
199
200 void HandleMessage_GetWindowAttr(CClient& client, CDeserialiser& message)
201 {
202         assert(!"TODO");
203 }
204
205 void HandleMessage_SendIPC(CClient& client, CDeserialiser& message)
206 {
207         assert(!"TODO");
208 }
209
210 void HandleMessage_GetWindowBuffer(CClient& client, CDeserialiser& message)
211 {
212         assert(!"TODO");
213 }
214
215 void HandleMessage_PushData(CClient& client, CDeserialiser& message)
216 {
217         assert(!"TODO");
218 }
219 void HandleMessage_Blit(CClient& client, CDeserialiser& message)
220 {
221         assert(!"TODO");
222 }
223 void HandleMessage_DrawCtl(CClient& client, CDeserialiser& message)
224 {
225         assert(!"TODO");
226 }
227 void HandleMessage_DrawText(CClient& client, CDeserialiser& message)
228 {
229         assert(!"TODO");
230 }
231
232 typedef void    MessageHandler_op_t(CClient& client, CDeserialiser& message);
233
234 MessageHandler_op_t     *message_handlers[] = {
235         [IPCMSG_NULL]       = &HandleMessage_Nop,
236         [IPCMSG_REPLY]      = &HandleMessage_Reply,
237         [IPCMSG_PING]       = &HandleMessage_Ping,
238         [IPCMSG_GETGLOBAL]  = &HandleMessage_GetGlobalAttr,
239         [IPCMSG_SETGLOBAL]  = &HandleMessage_SetGlobalAttr,
240         
241         [IPCMSG_CREATEWIN]  = &HandleMessage_CreateWindow,
242         [IPCMSG_CLOSEWIN]   = &HandleMessage_DestroyWindow,
243         [IPCMSG_SETWINATTR] = &HandleMessage_SetWindowAttr,
244         [IPCMSG_GETWINATTR] = &HandleMessage_GetWindowAttr,
245         [IPCMSG_SENDIPC]    = &HandleMessage_SendIPC,   // Use the GUI server for low-bandwith IPC
246         [IPCMSG_GETWINBUF]  = &HandleMessage_GetWindowBuffer,
247         [IPCMSG_PUSHDATA]   = &HandleMessage_PushData,  // to a window's buffer
248         [IPCMSG_BLIT]       = &HandleMessage_Blit,      // Copy data from one part of the window to another
249         [IPCMSG_DRAWCTL]    = &HandleMessage_DrawCtl,   // Draw a control
250         [IPCMSG_DRAWTEXT]   = &HandleMessage_DrawText,  // Draw text
251 };
252
253 void HandleMessage(CClient& client, CDeserialiser& message)
254 {
255         unsigned int command = message.ReadU8();
256         if( command >= sizeof(message_handlers)/sizeof(IPC::MessageHandler_op_t*) ) {
257                 // Drop, invalid command
258                 return ;
259         }
260         
261         _SysDebug("IPC::HandleMessage - command=%i", command);
262         (message_handlers[command])(client, message);
263         _SysDebug("IPC::HandleMessage - Completed");
264 }
265
266 CClientFailure::CClientFailure(std::string&& what):
267         m_what(what)
268 {
269 }
270 const char *CClientFailure::what() const throw()
271 {
272         return m_what.c_str();
273 }
274 CClientFailure::~CClientFailure() throw()
275 {
276 }
277
278 };      // namespace IPC
279
280 IIPCChannel::~IIPCChannel()
281 {
282 }
283
284 };      // namespace AxWin
285

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