Usermode/AxWin4 - Server implementation runnable
[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         client.SetWindow( new_id, gpCompositor->CreateWindow(client, name) );
153 }
154
155 void HandleMessage_DestroyWindow(CClient& client, CDeserialiser& message)
156 {
157         uint16_t        win_id = message.ReadU16();
158         
159         CWindow*        win = client.GetWindow(win_id);
160         if(!win) {
161                 throw IPC::CClientFailure("Bad window");
162         }
163         client.SetWindow(win_id, 0);    
164         
165         // TODO: Directly inform compositor?
166         delete win;
167 }
168
169 void HandleMessage_SetWindowAttr(CClient& client, CDeserialiser& message)
170 {
171         uint16_t        win_id = message.ReadU16();
172         uint16_t        attr_id = message.ReadU16();
173
174         CWindow*        win = client.GetWindow(win_id);
175         if(!win) {
176                 throw IPC::CClientFailure("Bad window");
177         }
178         
179         switch(attr_id)
180         {
181         case IPC_WINATTR_DIMENSIONS: {
182                 uint16_t new_w = message.ReadU16();
183                 uint16_t new_h = message.ReadU16();
184                 win->Resize(new_w, new_h);
185                 assert(!"TODO: IPC_WINATTR_DIMENSIONS");
186                 break; }
187         case IPC_WINATTR_POSITION: {
188                 int16_t new_x = message.ReadS16();
189                 int16_t new_y = message.ReadS16();
190                 win->Move(new_x, new_y);
191                 assert(!"TODO: IPC_WINATTR_POSITION");
192                 break; }
193         default:
194                 _SysDebug("HandleMessage_SetWindowAttr - Bad attr %u", attr_id);
195                 throw IPC::CClientFailure("Bad window attr");
196         }
197 }
198
199 void HandleMessage_GetWindowAttr(CClient& client, CDeserialiser& message)
200 {
201         assert(!"TODO");
202 }
203
204 void HandleMessage_SendIPC(CClient& client, CDeserialiser& message)
205 {
206         assert(!"TODO");
207 }
208
209 void HandleMessage_GetWindowBuffer(CClient& client, CDeserialiser& message)
210 {
211         assert(!"TODO");
212 }
213
214 void HandleMessage_PushData(CClient& client, CDeserialiser& message)
215 {
216         assert(!"TODO");
217 }
218 void HandleMessage_Blit(CClient& client, CDeserialiser& message)
219 {
220         assert(!"TODO");
221 }
222 void HandleMessage_DrawCtl(CClient& client, CDeserialiser& message)
223 {
224         assert(!"TODO");
225 }
226 void HandleMessage_DrawText(CClient& client, CDeserialiser& message)
227 {
228         assert(!"TODO");
229 }
230
231 typedef void    MessageHandler_op_t(CClient& client, CDeserialiser& message);
232
233 MessageHandler_op_t     *message_handlers[] = {
234         [IPCMSG_NULL]       = &HandleMessage_Nop,
235         [IPCMSG_REPLY]      = &HandleMessage_Reply,
236         [IPCMSG_PING]       = &HandleMessage_Ping,
237         [IPCMSG_GETGLOBAL]  = &HandleMessage_GetGlobalAttr,
238         [IPCMSG_SETGLOBAL]  = &HandleMessage_SetGlobalAttr,
239         
240         [IPCMSG_CREATEWIN]  = &HandleMessage_CreateWindow,
241         [IPCMSG_CLOSEWIN]   = &HandleMessage_DestroyWindow,
242         [IPCMSG_SETWINATTR] = &HandleMessage_SetWindowAttr,
243         [IPCMSG_GETWINATTR] = &HandleMessage_GetWindowAttr,
244         [IPCMSG_SENDIPC]    = &HandleMessage_SendIPC,   // Use the GUI server for low-bandwith IPC
245         [IPCMSG_GETWINBUF]  = &HandleMessage_GetWindowBuffer,
246         [IPCMSG_PUSHDATA]   = &HandleMessage_PushData,  // to a window's buffer
247         [IPCMSG_BLIT]       = &HandleMessage_Blit,      // Copy data from one part of the window to another
248         [IPCMSG_DRAWCTL]    = &HandleMessage_DrawCtl,   // Draw a control
249         [IPCMSG_DRAWTEXT]   = &HandleMessage_DrawText,  // Draw text
250 };
251
252 void HandleMessage(CClient& client, CDeserialiser& message)
253 {
254         unsigned int command = message.ReadU8();
255         if( command >= sizeof(message_handlers)/sizeof(IPC::MessageHandler_op_t*) ) {
256                 // Drop, invalid command
257                 return ;
258         }
259         
260         (message_handlers[command])(client, message);
261 }
262
263 CClientFailure::CClientFailure(std::string&& what):
264         m_what(what)
265 {
266 }
267 const char *CClientFailure::what() const throw()
268 {
269         return m_what.c_str();
270 }
271 CClientFailure::~CClientFailure() throw()
272 {
273 }
274
275 };      // namespace IPC
276
277 IIPCChannel::~IIPCChannel()
278 {
279 }
280
281 };      // namespace AxWin
282

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