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

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