X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin4_src%2FServer%2Fipc.cpp;h=70605fc0bad9b52413d434b9505ac3bae272228f;hb=1aed2067a0f084e9c5fa1af48e177e28a81466bc;hp=0d92e6ac8d02800d04dbafe6994e3322580acd10;hpb=340e7923b1e95c39ac85a4b22af7f1b53b315cd9;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin4_src/Server/ipc.cpp b/Usermode/Applications/axwin4_src/Server/ipc.cpp index 0d92e6ac..70605fc0 100644 --- a/Usermode/Applications/axwin4_src/Server/ipc.cpp +++ b/Usermode/Applications/axwin4_src/Server/ipc.cpp @@ -1,5 +1,6 @@ /* */ +#define __STDC_LIMIT_MACROS #include #include #include @@ -11,16 +12,24 @@ extern "C" { #include }; +#include namespace AxWin { namespace IPC { CCompositor* gpCompositor; -::std::list channels; +::std::list glChannels; +//::std::map glClients; -void Initialise(const CConfigIPC& config, CCompositor* compositor) +void Initialise(const CConfigIPC& config, CCompositor& compositor) { - gpCompositor = compositor; + gpCompositor = &compositor; + + ::std::string pipe_basepath = "axwin4"; + glChannels.push_back( new CIPCChannel_AcessIPCPipe( pipe_basepath ) ); + + //glChannels.push_back( new CIPCChannel_TCP("0.0.0.0:2100") ); + //for( auto channel : config.m_channels ) //{ // channels.push_back( ); @@ -30,65 +39,46 @@ void Initialise(const CConfigIPC& config, CCompositor* compositor) int FillSelect(fd_set& rfds) { int ret = 0; - for( auto channel : channels ) + for( const auto channel : glChannels ) { + _SysDebug("IPC::FillSelect - channel=%p", channel); + assert(channel); ret = ::std::max(ret, channel->FillSelect(rfds)); } return ret; } -void HandleSelect(fd_set& rfds) +void HandleSelect(const fd_set& rfds) { - + for( const auto channel : glChannels ) + { + assert(channel); + channel->HandleSelect(rfds); + } } -void RegisterClient(IIPCChannel& channel, CClient& client) +void RegisterClient(CClient& client) { - + // allocate a client ID, and save + //client.m_id = 123; + //glClients[client.m_id] = &client; } +void DeregisterClient(CClient& client) +{ + //glClients.erase( client.m_id ); +} -typedef void MessageHandler_op_t(CClient& client, CDeserialiser& message); -MessageHandler_op_t HandleMessage_Ping; -MessageHandler_op_t HandleMessage_GetWindowAttr; -MessageHandler_op_t HandleMessage_Reply; -MessageHandler_op_t HandleMessage_CreateWindow; -MessageHandler_op_t HandleMessage_CloseWindow; -MessageHandler_op_t HandleMessage_SetWindowAttr; -MessageHandler_op_t HandleMessage_AddRegion; -MessageHandler_op_t HandleMessage_DelRegion; -MessageHandler_op_t HandleMessage_SetRegionAttr; -MessageHandler_op_t HandleMessage_PushData; -MessageHandler_op_t HandleMessage_SendIPC; +void SendNotify_Dims(CClient& client, unsigned int NewW, unsigned int NewH) +{ + _SysDebug("TODO: CClient::SendNotify_Dims"); +} -MessageHandler_op_t *message_handlers[] = { - [IPCMSG_PING] = &HandleMessage_Ping, - [IPCMSG_REPLY] = &HandleMessage_Reply, - - [IPCMSG_CREATEWIN] = &HandleMessage_CreateWindow, - [IPCMSG_CLOSEWIN] = &HandleMessage_CloseWindow, - [IPCMSG_SETWINATTR] = &HandleMessage_SetWindowAttr, - [IPCMSG_GETWINATTR] = &HandleMessage_GetWindowAttr, - - [IPCMSG_RGNADD] = &HandleMessage_AddRegion, - [IPCMSG_RGNDEL] = &HandleMessage_DelRegion, - [IPCMSG_RGNSETATTR] = &HandleMessage_SetRegionAttr, - [IPCMSG_RGNPUSHDATA]= &HandleMessage_PushData, // to a region - [IPCMSG_SENDIPC] = &HandleMessage_SendIPC, // Use the GUI server for low-bandwith inter-process messaging -}; -void HandleMessage(CClient& client, CDeserialiser& message) +void HandleMessage_Nop(CClient& client, CDeserialiser& message) { - unsigned int command = message.ReadU8(); - if( command >= sizeof(message_handlers)/sizeof(IPC::MessageHandler_op_t*) ) { - // Drop, invalid command - return ; - } - - (message_handlers[command])(client, message); } - void HandleMessage_Reply(CClient& client, CDeserialiser& message) { // Reply to a sent message @@ -114,55 +104,208 @@ void HandleMessage_Ping(CClient& client, CDeserialiser& message) client.SendMessage(reply); } +void HandleMessage_GetGlobalAttr(CClient& client, CDeserialiser& message) +{ + uint16_t attr_id = message.ReadU16(); + + CSerialiser reply; + reply.WriteU8(IPCMSG_REPLY); + reply.WriteU8(IPCMSG_GETGLOBAL); + reply.WriteU16(attr_id); + + switch(attr_id) + { + case IPC_GLOBATTR_SCREENDIMS: { + uint8_t screen_id = message.ReadU8(); + unsigned int w, h; + gpCompositor->GetScreenDims(screen_id, &w, &h); + reply.WriteU16( (w <= UINT16_MAX ? w : UINT16_MAX) ); + reply.WriteU16( (h <= UINT16_MAX ? h : UINT16_MAX) ); + break; } + default: + throw IPC::CClientFailure("Bad global attribute ID"); + } + + client.SendMessage(reply); +} + +void HandleMessage_SetGlobalAttr(CClient& client, CDeserialiser& message) +{ + uint16_t attr_id = message.ReadU16(); + + switch(attr_id) + { + case IPC_GLOBATTR_SCREENDIMS: + // Setting readonly + break; + case IPC_GLOBATTR_MAXAREA: + assert(!"TODO: IPC_GLOBATTR_MAXAREA"); + break; + default: + throw IPC::CClientFailure("Bad global attribute ID"); + } +} + void HandleMessage_CreateWindow(CClient& client, CDeserialiser& message) { - uint16_t parent_id = message.ReadU16(); uint16_t new_id = message.ReadU16(); - CWindow* parent = client.GetWindow( parent_id ); + //uint16_t parent_id = message.ReadU16(); + //CWindow* parent = client.GetWindow( parent_id ); + ::std::string name = message.ReadString(); - client.SetWindow( new_id, gpCompositor->CreateWindow(client) ); + ::_SysDebug("_CreateWindow: (%i, '%s')", new_id, name.c_str()); + client.SetWindow( new_id, gpCompositor->CreateWindow(client, name) ); } -void HandleMessage_CloseWindow(CClient& client, CDeserialiser& message) +void HandleMessage_DestroyWindow(CClient& client, CDeserialiser& message) { - assert(!"TODO"); + uint16_t win_id = message.ReadU16(); + _SysDebug("_DestroyWindow: (%i)", win_id); + + CWindow* win = client.GetWindow(win_id); + if(!win) { + throw IPC::CClientFailure("_DestroyWindow: Bad window"); + } + client.SetWindow(win_id, 0); + + // TODO: Directly inform compositor? + delete win; } void HandleMessage_SetWindowAttr(CClient& client, CDeserialiser& message) { - assert(!"TODO"); + uint16_t win_id = message.ReadU16(); + uint16_t attr_id = message.ReadU16(); + _SysDebug("_SetWindowAttr: (%i, %i)", win_id, attr_id); + + CWindow* win = client.GetWindow(win_id); + if(!win) { + throw IPC::CClientFailure("_SetWindowAttr - Bad window"); + } + + switch(attr_id) + { + case IPC_WINATTR_DIMENSIONS: { + uint16_t new_w = message.ReadU16(); + uint16_t new_h = message.ReadU16(); + win->Resize(new_w, new_h); + break; } + case IPC_WINATTR_POSITION: { + int16_t new_x = message.ReadS16(); + int16_t new_y = message.ReadS16(); + win->Move(new_x, new_y); + break; } + default: + _SysDebug("HandleMessage_SetWindowAttr - Bad attr %u", attr_id); + throw IPC::CClientFailure("Bad window attr"); + } } void HandleMessage_GetWindowAttr(CClient& client, CDeserialiser& message) { - assert(!"TODO"); + assert(!"TODO HandleMessage_GetWindowAttr"); } -void HandleMessage_AddRegion(CClient& client, CDeserialiser& message) +void HandleMessage_SendIPC(CClient& client, CDeserialiser& message) { - assert(!"TODO"); + assert(!"TODO HandleMessage_SendIPC"); } -void HandleMessage_DelRegion(CClient& client, CDeserialiser& message) +void HandleMessage_GetWindowBuffer(CClient& client, CDeserialiser& message) { - assert(!"TODO"); + assert(!"TODO HandleMessage_GetWindowBuffer"); } -void HandleMessage_SetRegionAttr(CClient& client, CDeserialiser& message) +void HandleMessage_PushData(CClient& client, CDeserialiser& message) +{ + uint16_t win_id = message.ReadU16(); + uint16_t x = message.ReadU16(); + uint16_t y = message.ReadU16(); + uint16_t w = message.ReadU16(); + uint16_t h = message.ReadU16(); + _SysDebug("_PushData: (%i, (%i,%i) %ix%i)", win_id, x, y, w, h); + + CWindow* win = client.GetWindow(win_id); + if(!win) { + throw IPC::CClientFailure("_PushData: Bad window"); + } + + for( unsigned int row = 0; row < h; row ++ ) + { + const ::std::vector scanline_data = message.ReadBuffer(); + _SysDebug("_PushData: Scanline %i: %i bytes", row, scanline_data.size()); + if( scanline_data.size() != w * 4 ) { + _SysDebug("ERROR _PushData: Scanline buffer size mismatch (%i,%i)", + scanline_data.size(), w*4); + continue ; + } + win->m_surface.DrawScanline(y+row, x, w, scanline_data.data()); + } +} +void HandleMessage_Blit(CClient& client, CDeserialiser& message) { - assert(!"TODO"); + assert(!"TODO HandleMessage_Blit"); +} +void HandleMessage_DrawCtl(CClient& client, CDeserialiser& message) +{ + assert(!"TODO HandleMessage_DrawCtl"); +} +void HandleMessage_DrawText(CClient& client, CDeserialiser& message) +{ + assert(!"TODO HandleMessage_DrawText"); } -void HandleMessage_PushData(CClient& client, CDeserialiser& message) +typedef void MessageHandler_op_t(CClient& client, CDeserialiser& message); + +MessageHandler_op_t *message_handlers[] = { + [IPCMSG_NULL] = &HandleMessage_Nop, + [IPCMSG_REPLY] = &HandleMessage_Reply, + [IPCMSG_PING] = &HandleMessage_Ping, + [IPCMSG_GETGLOBAL] = &HandleMessage_GetGlobalAttr, + [IPCMSG_SETGLOBAL] = &HandleMessage_SetGlobalAttr, + + [IPCMSG_CREATEWIN] = &HandleMessage_CreateWindow, + [IPCMSG_CLOSEWIN] = &HandleMessage_DestroyWindow, + [IPCMSG_SETWINATTR] = &HandleMessage_SetWindowAttr, + [IPCMSG_GETWINATTR] = &HandleMessage_GetWindowAttr, + [IPCMSG_SENDIPC] = &HandleMessage_SendIPC, // Use the GUI server for low-bandwith IPC + [IPCMSG_GETWINBUF] = &HandleMessage_GetWindowBuffer, + [IPCMSG_PUSHDATA] = &HandleMessage_PushData, // to a window's buffer + [IPCMSG_BLIT] = &HandleMessage_Blit, // Copy data from one part of the window to another + [IPCMSG_DRAWCTL] = &HandleMessage_DrawCtl, // Draw a control + [IPCMSG_DRAWTEXT] = &HandleMessage_DrawText, // Draw text +}; + +void HandleMessage(CClient& client, CDeserialiser& message) { - assert(!"TODO"); + unsigned int command = message.ReadU8(); + if( command >= sizeof(message_handlers)/sizeof(IPC::MessageHandler_op_t*) ) { + // Drop, invalid command + return ; + } + + _SysDebug("IPC::HandleMessage - command=%i", command); + (message_handlers[command])(client, message); + _SysDebug("IPC::HandleMessage - Completed"); } -void HandleMessage_SendIPC(CClient& client, CDeserialiser& message) +CClientFailure::CClientFailure(std::string&& what): + m_what(what) +{ +} +const char *CClientFailure::what() const throw() +{ + return m_what.c_str(); +} +CClientFailure::~CClientFailure() throw() +{ +} + +}; // namespace IPC + +IIPCChannel::~IIPCChannel() { - assert(!"TODO"); } -}; }; // namespace AxWin