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

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