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 _SysDebug("IPC::FillSelect");
43 for( auto channel : glChannels )
45 _SysDebug("IPC::FillSelect - channel=%p", channel);
46 ret = ::std::max(ret, channel->FillSelect(rfds));
51 void HandleSelect(const fd_set& rfds)
53 _SysDebug("IPC::HandleSelect");
54 for( auto channel : glChannels )
56 _SysDebug("IPC::HandleSelect - channel=%p", channel);
57 channel->HandleSelect(rfds);
61 void RegisterClient(CClient& client)
63 // allocate a client ID, and save
65 //glClients[client.m_id] = &client;
68 void DeregisterClient(CClient& client)
70 //glClients.erase( client.m_id );
75 void HandleMessage_Nop(CClient& client, CDeserialiser& message)
78 void HandleMessage_Reply(CClient& client, CDeserialiser& message)
80 // Reply to a sent message
81 // - Not many messages need server-bound replies
82 int orig_command = message.ReadU8();
86 // Ping reply, mark client as still responding
94 void HandleMessage_Ping(CClient& client, CDeserialiser& message)
96 // A client has asked for a ping, we pong them back
98 reply.WriteU8(IPCMSG_REPLY);
99 reply.WriteU8(IPCMSG_PING);
100 client.SendMessage(reply);
103 void HandleMessage_GetGlobalAttr(CClient& client, CDeserialiser& message)
105 uint16_t attr_id = message.ReadU16();
108 reply.WriteU8(IPCMSG_REPLY);
109 reply.WriteU8(IPCMSG_GETGLOBAL);
110 reply.WriteU16(attr_id);
114 case IPC_GLOBATTR_SCREENDIMS: {
115 uint8_t screen_id = message.ReadU8();
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) );
122 throw IPC::CClientFailure("Bad global attribute ID");
125 client.SendMessage(reply);
128 void HandleMessage_SetGlobalAttr(CClient& client, CDeserialiser& message)
130 uint16_t attr_id = message.ReadU16();
134 case IPC_GLOBATTR_SCREENDIMS:
137 case IPC_GLOBATTR_MAXAREA:
138 assert(!"TODO: IPC_GLOBATTR_MAXAREA");
141 throw IPC::CClientFailure("Bad global attribute ID");
145 void HandleMessage_CreateWindow(CClient& client, CDeserialiser& message)
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();
152 client.SetWindow( new_id, gpCompositor->CreateWindow(client, name) );
155 void HandleMessage_DestroyWindow(CClient& client, CDeserialiser& message)
157 uint16_t win_id = message.ReadU16();
159 CWindow* win = client.GetWindow(win_id);
161 throw IPC::CClientFailure("Bad window");
163 client.SetWindow(win_id, 0);
165 // TODO: Directly inform compositor?
169 void HandleMessage_SetWindowAttr(CClient& client, CDeserialiser& message)
171 uint16_t win_id = message.ReadU16();
172 uint16_t attr_id = message.ReadU16();
174 CWindow* win = client.GetWindow(win_id);
176 throw IPC::CClientFailure("Bad window");
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");
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");
194 _SysDebug("HandleMessage_SetWindowAttr - Bad attr %u", attr_id);
195 throw IPC::CClientFailure("Bad window attr");
199 void HandleMessage_GetWindowAttr(CClient& client, CDeserialiser& message)
204 void HandleMessage_SendIPC(CClient& client, CDeserialiser& message)
209 void HandleMessage_GetWindowBuffer(CClient& client, CDeserialiser& message)
214 void HandleMessage_PushData(CClient& client, CDeserialiser& message)
218 void HandleMessage_Blit(CClient& client, CDeserialiser& message)
222 void HandleMessage_DrawCtl(CClient& client, CDeserialiser& message)
226 void HandleMessage_DrawText(CClient& client, CDeserialiser& message)
231 typedef void MessageHandler_op_t(CClient& client, CDeserialiser& message);
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,
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
252 void HandleMessage(CClient& client, CDeserialiser& message)
254 unsigned int command = message.ReadU8();
255 if( command >= sizeof(message_handlers)/sizeof(IPC::MessageHandler_op_t*) ) {
256 // Drop, invalid command
260 (message_handlers[command])(client, message);
263 CClientFailure::CClientFailure(std::string&& what):
267 const char *CClientFailure::what() const throw()
269 return m_what.c_str();
271 CClientFailure::~CClientFailure() throw()
277 IIPCChannel::~IIPCChannel()
281 }; // namespace AxWin