X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin4_src%2FServer%2Fipc.cpp;h=f522ac22767ea79b4d3b9808d1e924f65a528459;hb=0dd55a90dfc0073f9432635a621c3ec6d2d9bca9;hp=4ed0352fea91a4750467a705885e9b170f0264a4;hpb=327dc4547b437dca7e6e839119a1ca1481b8a40a;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin4_src/Server/ipc.cpp b/Usermode/Applications/axwin4_src/Server/ipc.cpp index 4ed0352f..f522ac22 100644 --- a/Usermode/Applications/axwin4_src/Server/ipc.cpp +++ b/Usermode/Applications/axwin4_src/Server/ipc.cpp @@ -19,13 +19,15 @@ extern "C" { }; #include #include +#include namespace AxWin { namespace IPC { CCompositor* gpCompositor; ::std::list glChannels; -//::std::map glClients; +::std::map glClients; +uint16_t giNextClient = 1; void Initialise(const CConfigIPC& config, CCompositor& compositor) { @@ -64,20 +66,72 @@ void HandleSelect(const fd_set& rfds) void RegisterClient(CClient& client) { + _SysDebug("RegisterClient(&client=%p)", &client); // allocate a client ID, and save - //client.m_id = 123; - //glClients[client.m_id] = &client; + for( int i = 0; i < 100; i ++ ) + { + uint16_t id = giNextClient++; + if(giNextClient == 0) giNextClient = 1; + auto r = glClients.insert( ::std::pair(id, &client) ); + if( r.second == true ) + { + client.set_id(id); + return; + } + } + // Wut? 100 attempts and fail! + assert(!"Todo - Better way of handling client ID reuse"); +} + +CClient* GetClientByID(uint16_t id) +{ + auto it = glClients.find(id); + if(it == glClients.end()) { + //_SysDebug("Client %i not registered", id); + return nullptr; + } + else { + //_SysDebug("Client %i %i = %p", id, it->first, it->second); + return it->second; + } } void DeregisterClient(CClient& client) { - //glClients.erase( client.m_id ); + glClients.erase( client.id() ); } -void SendMessage_NotifyDims(CClient& client, unsigned int NewW, unsigned int NewH) +void SendMessage_NotifyDims(CClient& client, unsigned int WinID, unsigned int NewW, unsigned int NewH) +{ + _SysDebug("TODO: IPC::SendMessage_NotifyDims"); +} +void SendMessage_MouseButton(CClient& client, unsigned int WinID, unsigned int X, unsigned int Y, uint8_t Button, bool Pressed) +{ + CSerialiser msg; + msg.WriteU8(IPCMSG_INPUTEVENT); + msg.WriteU8(IPC_INEV_MOUSEBTN); + msg.WriteU16(WinID); + msg.WriteU16(X); + msg.WriteU16(Y); + msg.WriteU8(Button); + msg.WriteU8(Pressed ? 0 : 1); + client.SendMessage(msg); +} +void SendMessage_MouseMove(CClient& client, unsigned int WinID, unsigned int X, unsigned int Y) +{ + _SysDebug("TODO: IPC::SendMessage_MouseMove"); +} +void SendMessage_KeyEvent(CClient& client, unsigned int WinID, uint32_t KeySym, bool Pressed, const char *Translated) { - _SysDebug("TODO: CClient::SendNotify_Dims"); + CSerialiser msg; + msg.WriteU8(IPCMSG_INPUTEVENT); + msg.WriteU8(IPC_INEV_KEYBOARD); + msg.WriteU16(WinID); + msg.WriteU16(KeySym); + msg.WriteU8(Pressed ? 0 : 1); + msg.WriteString(Translated); + client.SendMessage(msg); } @@ -163,7 +217,7 @@ void HandleMessage_CreateWindow(CClient& client, CDeserialiser& message) ::std::string name = message.ReadString(); ::_SysDebug("_CreateWindow: (%i, '%s')", new_id, name.c_str()); - client.SetWindow( new_id, gpCompositor->CreateWindow(client, name) ); + client.SetWindow( new_id, new CWindow(*gpCompositor, client, name, new_id) ); } void HandleMessage_DestroyWindow(CClient& client, CDeserialiser& message) @@ -185,7 +239,7 @@ void HandleMessage_SetWindowAttr(CClient& client, CDeserialiser& message) { uint16_t win_id = message.ReadU16(); uint16_t attr_id = message.ReadU16(); - _SysDebug("_SetWindowAttr: (%i, %i)", win_id, attr_id); + _SysDebug("_SetWindowAttr: (Win=%i, ID=%i)", win_id, attr_id); CWindow* win = client.GetWindow(win_id); if(!win) { @@ -276,7 +330,7 @@ void HandleMessage_PushData(CClient& client, CDeserialiser& message) 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); + _SysDebug("_PushData: (%i, (%i,%i) %ix%i)", win_id, x, y, w, h); CWindow* win = client.GetWindow(win_id); if(!win) { @@ -307,6 +361,7 @@ void HandleMessage_DrawCtl(CClient& client, CDeserialiser& message) uint16_t h = message.ReadU16(); uint16_t ctrl_id = message.ReadU16(); uint16_t frame = message.ReadU16(); + _SysDebug("_DrawCtl: (%i, (%i,%i) %ix%i Ctl%i frame?=0x%04x)", win_id, x, y, w, h, ctrl_id, frame); CWindow* win = client.GetWindow(win_id); if(!win) { @@ -328,9 +383,76 @@ void HandleMessage_DrawText(CClient& client, CDeserialiser& message) uint16_t y = message.ReadU16(); uint16_t w = message.ReadU16(); uint16_t h = message.ReadU16(); + uint16_t font_id = message.ReadU16(); ::std::string str = message.ReadString(); + _SysDebug("_DrawText: (%i (%i,%i) %ix%i Font%i \"%s\")", win_id, x, y, w, h, font_id, str.c_str()); - assert(!"TODO HandleMessage_DrawText"); + CWindow* win = client.GetWindow(win_id); + if(!win) { + throw IPC::CClientFailure("_DrawText: Bad window"); + } + + // 1. Get font from client structure + IFontFace& fontface = client.GetFont(font_id); + + // 2. Render + CRect area(x, y, w, h); + fontface.Render(win->m_surface, area, str, h); +} + +void HandleMessage_FillRect(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(); + uint32_t colour = message.ReadU32(); + _SysDebug("_FillRect: (%i (%i,%i) %ix%i %06x)", win_id, x, y, w, h, colour); + + CWindow* win = client.GetWindow(win_id); + if(!win) { + throw IPC::CClientFailure("_FillRect: Bad window"); + } + + while(h -- ) { + win->FillScanline(y++, x, w, colour); + } +} + +void HandleMessage_DrawRect(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(); + uint32_t colour = message.ReadU32(); + _SysDebug("_DrawRect: (%i (%i,%i) %ix%i %06x)", win_id, x, y, w, h, colour); + + CWindow* win = client.GetWindow(win_id); + if(!win) { + throw IPC::CClientFailure("_DrawRect: Bad window"); + } + + if(h == 0) { + } + else if(h == 1) { + win->FillScanline(y, x, w, colour); + } + else if(h == 2) { + win->FillScanline(y++, x, w, colour); + win->FillScanline(y++, x, w, colour); + } + else { + win->FillScanline(y++, x, w, colour); + while( h -- > 2 ) { + win->FillScanline(y, x, 1, colour); + win->FillScanline(y, x+w-1, 1, colour); + y ++; + } + win->FillScanline(y++, x, w, colour); + } } typedef void MessageHandler_op_t(CClient& client, CDeserialiser& message); @@ -353,13 +475,17 @@ MessageHandler_op_t *message_handlers[] = { [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 + [IPCMSG_FILLRECT] = &HandleMessage_FillRect, // Fill a rectangle + [IPCMSG_DRAWRECT] = &HandleMessage_DrawRect, // Draw (outline) a rectangle }; void HandleMessage(CClient& client, CDeserialiser& message) { + const unsigned int num_commands = sizeof(message_handlers)/sizeof(IPC::MessageHandler_op_t*); unsigned int command = message.ReadU8(); - if( command >= sizeof(message_handlers)/sizeof(IPC::MessageHandler_op_t*) ) { + if( command >= num_commands ) { // Drop, invalid command + _SysDebug("HandleMessage: Command %u is invalid (out of range for %u)", command, num_commands); return ; }