X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=Usermode%2FLibraries%2Flibaxwin4.so_src%2Fwm.cpp;h=cae79c719a824d9c8005fe683eca2a746c8774ab;hb=b5f8fa2dea9d6a67ac5c8a3a442ee4570deaa56c;hp=2144eb741ca93267610479de944f7f93c3d2c8eb;hpb=d87b9f934993d643b193880603523dead2a63547;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libaxwin4.so_src/wm.cpp b/Usermode/Libraries/libaxwin4.so_src/wm.cpp index 2144eb74..cae79c71 100644 --- a/Usermode/Libraries/libaxwin4.so_src/wm.cpp +++ b/Usermode/Libraries/libaxwin4.so_src/wm.cpp @@ -8,16 +8,37 @@ #include #include "include/common.hpp" #include +#include +#include +#include +#include namespace AxWin { +static const int MAX_WINDOW_ID = 16; +static ::std::mutex glWindowList; +static ::std::vector gWindowList; + extern "C" tAxWin4_Window *AxWin4_CreateWindow(const char *Name) { // Allocate a window ID + ::std::lock_guard lock(glWindowList); + int id = ::std::find(gWindowList.begin(), gWindowList.end(), nullptr) - gWindowList.begin(); + if( id >= MAX_WINDOW_ID ) { + throw ::std::runtime_error("AxWin4_CreateWindow - Out of IDs (TODO: Better exception)"); + } + if( id == gWindowList.size() ) + { + gWindowList.push_back(nullptr); + } + assert(gWindowList[id] == nullptr); // Create window structure locally tAxWin4_Window *ret = new tAxWin4_Window(); - ret->m_id = 0; + gWindowList[id] = ret; + ret->m_id = id; + ret->m_fd = -1; + ret->m_buffer = nullptr; // Request creation of window CSerialiser message; message.WriteU8(IPCMSG_CREATEWIN); @@ -27,13 +48,23 @@ extern "C" tAxWin4_Window *AxWin4_CreateWindow(const char *Name) return ret; } -extern "C" void AxWin4_ShowWindow(tAxWin4_Window *Window) +extern "C" void AxWin4_ShowWindow(tAxWin4_Window *Window, bool Show) { CSerialiser message; message.WriteU8(IPCMSG_SETWINATTR); message.WriteU16(Window->m_id); message.WriteU16(IPC_WINATTR_SHOW); - message.WriteU8(1); + message.WriteU8( (Show ? 1 : 0) ); + ::AxWin::SendMessage(message); +} + +extern "C" void AxWin4_SetWindowFlags(tAxWin4_Window *Window, unsigned int Flags) +{ + CSerialiser message; + message.WriteU8(IPCMSG_SETWINATTR); + message.WriteU16(Window->m_id); + message.WriteU16(IPC_WINATTR_FLAGS); + message.WriteU8( Flags ); ::AxWin::SendMessage(message); } @@ -68,13 +99,51 @@ extern "C" void AxWin4_SetTitle(tAxWin4_Window *Window, const char *Title) ::AxWin::SendMessage(message); } +extern "C" void AxWin4_DamageRect(tAxWin4_Window *Window, unsigned int X, unsigned int Y, unsigned int W, unsigned int H) +{ + CSerialiser message; + message.WriteU8(IPCMSG_DAMAGERECT); + message.WriteU16(Window->m_id); + message.WriteU16(X); + message.WriteU16(Y); + message.WriteU16(W); + message.WriteU16(H); + ::AxWin::SendMessage(message); +} + extern "C" void *AxWin4_GetWindowBuffer(tAxWin4_Window *Window) { - //if( !Window->m_buffer ) - //{ - // // TODO: Support non-blocking operations - //} - return NULL; + if( Window->m_fd == -1 ) + { + CSerialiser req; + req.WriteU8(IPCMSG_GETWINBUF); + req.WriteU16(Window->m_id); + + CDeserialiser response = GetSyncReply(req, IPCMSG_GETWINBUF); + unsigned int rspwin = response.ReadU16(); + if( rspwin != Window->m_id ) + { + _SysDebug("AxWin4_GetWindowBuffer: GETWINBUF reply for different window (%u != %u)", rspwin, Window->m_id); + return NULL; + } + + uint64_t handle = response.ReadU64(); + Window->m_fd = _SysUnMarshalFD(handle); + if( Window->m_fd == -1 ) { + _SysDebug("AxWin4_GetWindowBuffer: Unable to unmarshal resultant FD (0x%llx)", handle); + return NULL; + } + + _SysDebug("AxWin4_GetWindowBuffer: %llx = %i", handle, Window->m_fd); + } + + if( !Window->m_buffer ) + { + size_t size = 640*480*4; + Window->m_buffer = _SysMMap(NULL, size, MMAP_PROT_WRITE, MMAP_MAP_SHARED, Window->m_fd, 0); + } + + return Window->m_buffer; } }; // namespace AxWin