X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibaxwin4.so_src%2Fipc.cpp;h=e42d4060fc1deb9c5878652140b639f2dd1a5936;hb=6fbf6b93bec9b8b5bd6d7c683eefb0ebed8dff77;hp=10331fb386c83ce3f19d8823c6553237a257f27a;hpb=9b09b24a5cc3dfb0cee51e0d1876c9253894666a;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libaxwin4.so_src/ipc.cpp b/Usermode/Libraries/libaxwin4.so_src/ipc.cpp index 10331fb3..e42d4060 100644 --- a/Usermode/Libraries/libaxwin4.so_src/ipc.cpp +++ b/Usermode/Libraries/libaxwin4.so_src/ipc.cpp @@ -9,7 +9,10 @@ #include "include/common.hpp" #include "include/IIPCChannel.hpp" #include "include/CIPCChannel_AcessIPCPipe.hpp" +#include #include +#include +#include #include #include @@ -17,6 +20,10 @@ 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 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() {