3 #define __STDC_LIMIT_MACROS
6 #include <IIPCChannel.hpp>
9 #include <serialisation.hpp>
10 #include <ipc_proto.hpp>
11 #include <CCompositor.hpp>
15 #include <CIPCChannel_AcessIPCPipe.hpp>
20 CCompositor* gpCompositor;
21 ::std::list<IIPCChannel*> glChannels;
22 //::std::map<uint16_t,CClient*> glClients;
24 void Initialise(const CConfigIPC& config, CCompositor& compositor)
26 gpCompositor = &compositor;
28 ::std::string pipe_basepath = "axwin4";
29 glChannels.push_back( new CIPCChannel_AcessIPCPipe( pipe_basepath ) );
31 //glChannels.push_back( new CIPCChannel_TCP("0.0.0.0:2100") );
33 //for( auto channel : config.m_channels )
35 // channels.push_back( );
39 int FillSelect(fd_set& rfds)
42 for( const auto channel : glChannels )
45 ret = ::std::max(ret, channel->FillSelect(rfds));
50 void HandleSelect(const fd_set& rfds)
52 for( const auto channel : glChannels )
55 channel->HandleSelect(rfds);
59 void RegisterClient(CClient& client)
61 // allocate a client ID, and save
63 //glClients[client.m_id] = &client;
66 void DeregisterClient(CClient& client)
68 //glClients.erase( client.m_id );
72 void SendNotify_Dims(CClient& client, unsigned int NewW, unsigned int NewH)
74 _SysDebug("TODO: CClient::SendNotify_Dims");
78 void HandleMessage_Nop(CClient& client, CDeserialiser& message)
81 void HandleMessage_Reply(CClient& client, CDeserialiser& message)
83 // Reply to a sent message
84 // - Not many messages need server-bound replies
85 int orig_command = message.ReadU8();
89 // Ping reply, mark client as still responding
97 void HandleMessage_Ping(CClient& client, CDeserialiser& message)
99 // A client has asked for a ping, we pong them back
101 reply.WriteU8(IPCMSG_REPLY);
102 reply.WriteU8(IPCMSG_PING);
103 client.SendMessage(reply);
106 void HandleMessage_GetGlobalAttr(CClient& client, CDeserialiser& message)
108 uint16_t attr_id = message.ReadU16();
111 reply.WriteU8(IPCMSG_REPLY);
112 reply.WriteU8(IPCMSG_GETGLOBAL);
113 reply.WriteU16(attr_id);
117 case IPC_GLOBATTR_SCREENDIMS: {
118 uint8_t screen_id = message.ReadU8();
120 gpCompositor->GetScreenDims(screen_id, &w, &h);
121 reply.WriteU16( (w <= UINT16_MAX ? w : UINT16_MAX) );
122 reply.WriteU16( (h <= UINT16_MAX ? h : UINT16_MAX) );
124 case IPC_GLOBATTR_MAXAREA:
125 assert(!"TODO: IPC_GLOBATTR_MAXAREA");
128 throw IPC::CClientFailure("Bad global attribute ID");
131 client.SendMessage(reply);
134 void HandleMessage_SetGlobalAttr(CClient& client, CDeserialiser& message)
136 uint16_t attr_id = message.ReadU16();
140 case IPC_GLOBATTR_SCREENDIMS:
143 case IPC_GLOBATTR_MAXAREA:
144 assert(!"TODO: IPC_GLOBATTR_MAXAREA");
147 throw IPC::CClientFailure("Bad global attribute ID");
151 void HandleMessage_CreateWindow(CClient& client, CDeserialiser& message)
153 uint16_t new_id = message.ReadU16();
154 //uint16_t parent_id = message.ReadU16();
155 //CWindow* parent = client.GetWindow( parent_id );
156 ::std::string name = message.ReadString();
158 ::_SysDebug("_CreateWindow: (%i, '%s')", new_id, name.c_str());
159 client.SetWindow( new_id, gpCompositor->CreateWindow(client, name) );
162 void HandleMessage_DestroyWindow(CClient& client, CDeserialiser& message)
164 uint16_t win_id = message.ReadU16();
165 _SysDebug("_DestroyWindow: (%i)", win_id);
167 CWindow* win = client.GetWindow(win_id);
169 throw IPC::CClientFailure("_DestroyWindow: Bad window");
171 client.SetWindow(win_id, 0);
173 // TODO: Directly inform compositor?
177 void HandleMessage_SetWindowAttr(CClient& client, CDeserialiser& message)
179 uint16_t win_id = message.ReadU16();
180 uint16_t attr_id = message.ReadU16();
181 _SysDebug("_SetWindowAttr: (%i, %i)", win_id, attr_id);
183 CWindow* win = client.GetWindow(win_id);
185 throw IPC::CClientFailure("_SetWindowAttr - Bad window");
190 case IPC_WINATTR_DIMENSIONS: {
191 uint16_t new_w = message.ReadU16();
192 uint16_t new_h = message.ReadU16();
193 win->Resize(new_w, new_h);
195 case IPC_WINATTR_POSITION: {
196 int16_t new_x = message.ReadS16();
197 int16_t new_y = message.ReadS16();
198 win->Move(new_x, new_y);
200 case IPC_WINATTR_SHOW:
201 win->Show( message.ReadU8() != 0 );
203 case IPC_WINATTR_FLAGS:
204 _SysDebug("TODO: IPC_WINATTR_FLAGS");
206 case IPC_WINATTR_TITLE:
207 assert(!"TODO: IPC_WINATTR_TITLE");
210 _SysDebug("HandleMessage_SetWindowAttr - Bad attr %u", attr_id);
211 throw IPC::CClientFailure("Bad window attr");
215 void HandleMessage_GetWindowAttr(CClient& client, CDeserialiser& message)
217 assert(!"TODO HandleMessage_GetWindowAttr");
220 void HandleMessage_SendIPC(CClient& client, CDeserialiser& message)
222 assert(!"TODO HandleMessage_SendIPC");
225 void HandleMessage_GetWindowBuffer(CClient& client, CDeserialiser& message)
227 assert(!"TODO HandleMessage_GetWindowBuffer");
230 void HandleMessage_PushData(CClient& client, CDeserialiser& message)
232 uint16_t win_id = message.ReadU16();
233 uint16_t x = message.ReadU16();
234 uint16_t y = message.ReadU16();
235 uint16_t w = message.ReadU16();
236 uint16_t h = message.ReadU16();
237 _SysDebug("_PushData: (%i, (%i,%i) %ix%i)", win_id, x, y, w, h);
239 CWindow* win = client.GetWindow(win_id);
241 throw IPC::CClientFailure("_PushData: Bad window");
244 for( unsigned int row = 0; row < h; row ++ )
246 const ::std::vector<uint8_t> scanline_data = message.ReadBuffer();
247 if( scanline_data.size() != w * 4 ) {
248 _SysDebug("ERROR _PushData: Scanline buffer size mismatch (%i,%i)",
249 scanline_data.size(), w*4);
252 win->DrawScanline(y+row, x, w, scanline_data.data());
255 void HandleMessage_Blit(CClient& client, CDeserialiser& message)
257 assert(!"TODO HandleMessage_Blit");
259 void HandleMessage_DrawCtl(CClient& client, CDeserialiser& message)
261 assert(!"TODO HandleMessage_DrawCtl");
263 void HandleMessage_DrawText(CClient& client, CDeserialiser& message)
265 assert(!"TODO HandleMessage_DrawText");
268 typedef void MessageHandler_op_t(CClient& client, CDeserialiser& message);
270 MessageHandler_op_t *message_handlers[] = {
271 [IPCMSG_NULL] = &HandleMessage_Nop,
272 [IPCMSG_REPLY] = &HandleMessage_Reply,
273 [IPCMSG_PING] = &HandleMessage_Ping,
274 [IPCMSG_GETGLOBAL] = &HandleMessage_GetGlobalAttr,
275 [IPCMSG_SETGLOBAL] = &HandleMessage_SetGlobalAttr,
277 [IPCMSG_CREATEWIN] = &HandleMessage_CreateWindow,
278 [IPCMSG_CLOSEWIN] = &HandleMessage_DestroyWindow,
279 [IPCMSG_SETWINATTR] = &HandleMessage_SetWindowAttr,
280 [IPCMSG_GETWINATTR] = &HandleMessage_GetWindowAttr,
281 [IPCMSG_SENDIPC] = &HandleMessage_SendIPC, // Use the GUI server for low-bandwith IPC
282 [IPCMSG_GETWINBUF] = &HandleMessage_GetWindowBuffer,
283 [IPCMSG_PUSHDATA] = &HandleMessage_PushData, // to a window's buffer
284 [IPCMSG_BLIT] = &HandleMessage_Blit, // Copy data from one part of the window to another
285 [IPCMSG_DRAWCTL] = &HandleMessage_DrawCtl, // Draw a control
286 [IPCMSG_DRAWTEXT] = &HandleMessage_DrawText, // Draw text
289 void HandleMessage(CClient& client, CDeserialiser& message)
291 unsigned int command = message.ReadU8();
292 if( command >= sizeof(message_handlers)/sizeof(IPC::MessageHandler_op_t*) ) {
293 // Drop, invalid command
297 (message_handlers[command])(client, message);
300 CClientFailure::CClientFailure(std::string&& what):
304 const char *CClientFailure::what() const throw()
306 return m_what.c_str();
308 CClientFailure::~CClientFailure() throw()
314 IIPCChannel::~IIPCChannel()
318 }; // namespace AxWin