Usermode/AxWin4 - Send mouse/keyboard events to client
[tpg/acess2.git] / Usermode / Libraries / libaxwin4.so_src / ipc.cpp
index 10331fb..e42d406 100644 (file)
@@ -9,7 +9,10 @@
 #include "include/common.hpp"
 #include "include/IIPCChannel.hpp"
 #include "include/CIPCChannel_AcessIPCPipe.hpp"
+#include <ipc_proto.hpp>
 #include <algorithm>
+#include <mutex>
+#include <stdexcept>
 
 #include <cstring>
 #include <cstdio>
 namespace AxWin {
 
 IIPCChannel*   gIPCChannel;
+::std::mutex   glSyncReply;
+bool   gSyncReplyActive;
+bool   gSyncReplyValid;
+CDeserialiser  gSyncReplyBuf;
 
 extern "C" bool AxWin4_Connect(const char *URI)
 {
@@ -50,7 +57,7 @@ extern "C" bool AxWin4_PeekEventQueue(void)
 
 extern "C" bool AxWin4_WaitEventQueue(uint64_t Timeout)
 {
-       AxWin4_WaitEventQueueSelect(0, NULL, NULL, NULL, Timeout);
+       return AxWin4_WaitEventQueueSelect(0, NULL, NULL, NULL, Timeout);
 }
 
 extern "C" bool AxWin4_WaitEventQueueSelect(int nFDs, fd_set *rfds, fd_set *wfds, fd_set *efds, uint64_t Timeout)
@@ -73,6 +80,92 @@ void SendMessage(CSerialiser& message)
 {
        gIPCChannel->Send(message);
 }
+void RecvMessage(CDeserialiser& message)
+{
+       uint8_t id = message.ReadU8();
+       _SysDebug("RecvMessage: id=%i", id);
+       switch(id)
+       {
+       case IPCMSG_PING:
+               // If we hear ping, we must pong
+               {
+               CSerialiser     pong;
+               pong.WriteU8(IPCMSG_REPLY);
+               pong.WriteU8(IPCMSG_PING);
+               SendMessage(pong);
+               }
+               break;
+       case IPCMSG_REPLY:
+               // Flag reply and take a copy of this message
+               if( !gSyncReplyActive )
+               {
+                       _SysDebug("Unexpected reply message %i", message.ReadU8());
+               }
+               else if( gSyncReplyValid )
+               {
+                       // Oh... that was unexpected
+                       _SysDebug("Unexpected second reply message %i", message.ReadU8());
+               }
+               else
+               {
+                       gSyncReplyValid = true;
+                       gSyncReplyBuf = message;
+               }
+               break;
+       // TODO: Handle messages from server (input events, IPC)
+       // TODO: If an event is currently being processed, save the message in a queue to be handled when processing is complete
+       // - This will prevent deep recursion (and make server errors aparent)
+       default:
+               _SysDebug("TODO: RecvMessage(%i)", id);
+               break;
+       }
+}
+
+CDeserialiser GetSyncReply(CSerialiser& request, unsigned int Message)
+{
+       ::std::lock_guard<std::mutex>   lock(glSyncReply);
+       gSyncReplyActive = true;
+       gSyncReplyValid = false;
+       // Send once lock is acquired
+       SendMessage(request);
+       
+       while( !gSyncReplyValid )
+       {
+               // Tick along
+               if( !AxWin4_WaitEventQueue(0) )
+                       throw ::std::runtime_error("Connection dropped while waiting for reply");
+       }
+       gSyncReplyActive = false;
+       
+       uint8_t id = gSyncReplyBuf.ReadU8();
+       if( id != Message )
+       {
+               _SysDebug("Unexpected reply message id=%i, expected %i",
+                       id, Message);
+               throw ::std::runtime_error("Sequencing error, unexpected reply");
+       }
+       
+       // Use move to avoid copying
+       return ::std::move(gSyncReplyBuf);
+}
+
+extern "C" void AxWin4_GetScreenDimensions(unsigned int ScreenIndex, unsigned int *Width, unsigned int *Height)
+{
+       CSerialiser     req;
+       req.WriteU8(IPCMSG_GETGLOBAL);
+       req.WriteU16(IPC_GLOBATTR_SCREENDIMS);
+       req.WriteU8(ScreenIndex);
+       
+       CDeserialiser   response = GetSyncReply(req, IPCMSG_GETGLOBAL);
+       if( response.ReadU16() != IPC_GLOBATTR_SCREENDIMS ) {
+               
+       }
+       
+       *Width = response.ReadU16();
+       *Height = response.ReadU16();
+       
+       _SysDebug("AxWin4_GetScreenDimensions: %i = %ix%i", ScreenIndex, *Width, *Height);
+}
 
 IIPCChannel::~IIPCChannel()
 {

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