Usermode/AxWin4 - Send mouse/keyboard events to client
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / ipc.cpp
index 732ddfd..5f59ae1 100644 (file)
@@ -1,4 +1,9 @@
 /*
+ * Acess2 GUI v4
+ * - By John Hodge (thePowersGang)
+ *
+ * ipc.cpp
+ * - Client-Server communication (dispatch)
  */
 #define __STDC_LIMIT_MACROS
 #include <ipc.hpp>
@@ -13,13 +18,15 @@ extern "C" {
 #include <assert.h>
 };
 #include <CIPCChannel_AcessIPCPipe.hpp>
+#include <draw_control.hpp>
 
 namespace AxWin {
 namespace IPC {
 
 CCompositor*   gpCompositor;
 ::std::list<IIPCChannel*>      glChannels;
-//::std::map<uint16_t,CClient*>        glClients;
+::std::map<uint16_t,CClient*>  glClients;
+uint16_t       giNextClient = 1;
 
 void Initialise(const CConfigIPC& config, CCompositor& compositor)
 {
@@ -58,25 +65,78 @@ 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<uint16_t,CClient*>(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 SendNotify_Dims(CClient& client, unsigned int NewW, unsigned int NewH)
+void SendMessage_NotifyDims(CClient& client, unsigned int WinID, unsigned int NewW, unsigned int NewH)
 {
-       _SysDebug("TODO: CClient::SendNotify_Dims");
+       _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_MouseButton");
+}
+void SendMessage_KeyEvent(CClient& client, unsigned int WinID, uint32_t KeySym, bool Pressed, const char *Translated)
+{
+       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);
 }
 
 
 void HandleMessage_Nop(CClient& client, CDeserialiser& message)
 {
+       // Do nothing
 }
 void HandleMessage_Reply(CClient& client, CDeserialiser& message)
 {
@@ -156,7 +216,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)
@@ -178,7 +238,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) {
@@ -201,7 +261,7 @@ void HandleMessage_SetWindowAttr(CClient& client, CDeserialiser& message)
                win->Show( message.ReadU8() != 0 );
                break;
        case IPC_WINATTR_FLAGS:
-               _SysDebug("TODO: IPC_WINATTR_FLAGS");
+               win->SetFlags( message.ReadU8() );      // TODO: U8? why so small?
                break;
        case IPC_WINATTR_TITLE:
                assert(!"TODO: IPC_WINATTR_TITLE");
@@ -224,7 +284,42 @@ void HandleMessage_SendIPC(CClient& client, CDeserialiser& message)
 
 void HandleMessage_GetWindowBuffer(CClient& client, CDeserialiser& message)
 {
-       assert(!"TODO HandleMessage_GetWindowBuffer");
+       uint16_t        win_id = message.ReadU16();
+       _SysDebug("_GetWindowBuffer: (%i)", win_id);
+       
+       CWindow*        win = client.GetWindow(win_id);
+       if(!win) {
+               throw IPC::CClientFailure("_PushData: Bad window");
+       }
+       
+       uint64_t handle = win->m_surface.GetSHMHandle();
+       
+       CSerialiser     reply;
+       reply.WriteU8(IPCMSG_REPLY);
+       reply.WriteU8(IPCMSG_GETWINBUF);
+       reply.WriteU16(win_id);
+       reply.WriteU64(handle);
+       client.SendMessage(reply);
+}
+
+void HandleMessage_DamageRect(CClient& client, CDeserialiser& message)
+{
+       uint16_t        winid = message.ReadU16();
+       uint16_t        x = message.ReadU16();
+       uint16_t        y = message.ReadU16();
+       uint16_t        w = message.ReadU16();
+       uint16_t        h = message.ReadU16();
+       
+       _SysDebug("_DamageRect: (%i %i,%i %ix%i)", winid, x, y, w, h);
+       
+       CWindow*        win = client.GetWindow(winid);
+       if(!win) {
+               throw IPC::CClientFailure("_PushData: Bad window");
+       }
+       
+       CRect   area(x,y,w,h);
+       
+       win->Repaint(area);
 }
 
 void HandleMessage_PushData(CClient& client, CDeserialiser& message)
@@ -258,11 +353,52 @@ void HandleMessage_Blit(CClient& client, CDeserialiser& message)
 }
 void HandleMessage_DrawCtl(CClient& client, CDeserialiser& message)
 {
-       assert(!"TODO HandleMessage_DrawCtl");
+       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();
+       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) {
+               throw IPC::CClientFailure("_DrawCtl: Bad window");
+       }
+       
+       const CControl* ctrl = CControl::GetByID(ctrl_id);
+       if(!ctrl) {
+               throw IPC::CClientFailure("_DrawCtl: Invalid control ID");
+       }
+       
+       CRect   area(x,y,w,h);
+       ctrl->Render(win->m_surface, area);
 }
 void HandleMessage_DrawText(CClient& client, CDeserialiser& message)
 {
-       assert(!"TODO HandleMessage_DrawText");
+       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();
+       uint16_t        font = message.ReadU16();
+       ::std::string   str = message.ReadString();
+       _SysDebug("_DrawText: (%i (%i,%i) %ix%i Font%i \"%s\")", win_id, x, y, w, h, font, str.c_str());
+       
+       CWindow*        win = client.GetWindow(win_id);
+       if(!win) {
+               throw IPC::CClientFailure("_DrawText: Bad window");
+       }
+       
+       // 1. Get font from client structure
+       //CFont& font = client.GetFont(font_id);
+       
+       // 2. Render
+       //CRect area(x, y, w, h);
+       //font->Render(win->m_surface, area, str, h);
+       
+       _SysDebug("TODO: HandleMessage_DrawText");
 }
 
 typedef void   MessageHandler_op_t(CClient& client, CDeserialiser& message);
@@ -280,6 +416,7 @@ MessageHandler_op_t *message_handlers[] = {
        [IPCMSG_GETWINATTR] = &HandleMessage_GetWindowAttr,
        [IPCMSG_SENDIPC]    = &HandleMessage_SendIPC,   // Use the GUI server for low-bandwith IPC
        [IPCMSG_GETWINBUF]  = &HandleMessage_GetWindowBuffer,
+       [IPCMSG_DAMAGERECT] = &HandleMessage_DamageRect,
        [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

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