Usermode/AxWin4 - (minor) Log and fail when wrong window ID is returned from server
[tpg/acess2.git] / Usermode / Libraries / libaxwin4.so_src / wm.cpp
1 /*
2  * AxWin4 Interface Library
3  * - By John Hodge (thePowersGang)
4  *
5  * wm.cpp
6  * - Window Management
7  */
8 #include <axwin4/axwin.h>
9 #include "include/common.hpp"
10 #include <ipc_proto.hpp>
11 #include <vector>
12 #include <algorithm>
13 #include <mutex>
14
15 namespace AxWin {
16
17 static const int        MAX_WINDOW_ID = 16;
18 static ::std::mutex     glWindowList;
19 static ::std::vector<tAxWin4_Window*>   gWindowList;
20
21 extern "C" tAxWin4_Window *AxWin4_CreateWindow(const char *Name)
22 {
23         // Allocate a window ID
24         ::std::lock_guard<std::mutex>   lock(glWindowList);
25         int id = ::std::find(gWindowList.begin(), gWindowList.end(), nullptr) - gWindowList.end();
26         if( id >= MAX_WINDOW_ID ) {
27                 throw ::std::runtime_error("AxWin4_CreateWindow - Out of IDs (TODO: Better exception)");
28         }
29         if( id == gWindowList.size() )
30         {
31                 gWindowList.push_back(nullptr);
32         }
33         
34         // Create window structure locally
35         tAxWin4_Window *ret = new tAxWin4_Window();
36         gWindowList[id] = ret;
37         ret->m_id = id;
38         ret->m_fd = -1;
39         ret->m_buffer = nullptr;
40         // Request creation of window
41         CSerialiser     message;
42         message.WriteU8(IPCMSG_CREATEWIN);
43         message.WriteU16(ret->m_id);
44         message.WriteString(Name);
45         ::AxWin::SendMessage(message);
46         return ret;
47 }
48
49 extern "C" void AxWin4_ShowWindow(tAxWin4_Window *Window, bool Show)
50 {
51         CSerialiser     message;
52         message.WriteU8(IPCMSG_SETWINATTR);
53         message.WriteU16(Window->m_id);
54         message.WriteU16(IPC_WINATTR_SHOW);
55         message.WriteU8( (Show ? 1 : 0) );
56         ::AxWin::SendMessage(message);
57 }
58
59 extern "C" void AxWin4_SetWindowFlags(tAxWin4_Window *Window, unsigned int Flags)
60 {
61         CSerialiser     message;
62         message.WriteU8(IPCMSG_SETWINATTR);
63         message.WriteU16(Window->m_id);
64         message.WriteU16(IPC_WINATTR_FLAGS);
65         message.WriteU8( Flags );
66         ::AxWin::SendMessage(message);
67 }
68
69 extern "C" void AxWin4_MoveWindow(tAxWin4_Window *Window, int X, int Y)
70 {
71         CSerialiser     message;
72         message.WriteU8(IPCMSG_SETWINATTR);
73         message.WriteU16(Window->m_id);
74         message.WriteU16(IPC_WINATTR_POSITION);
75         message.WriteS16(X);
76         message.WriteS16(Y);
77         ::AxWin::SendMessage(message);
78 }
79 extern "C" void AxWin4_ResizeWindow(tAxWin4_Window *Window, unsigned int W, unsigned int H)
80 {
81         CSerialiser     message;
82         message.WriteU8(IPCMSG_SETWINATTR);
83         message.WriteU16(Window->m_id);
84         message.WriteU16(IPC_WINATTR_DIMENSIONS);
85         message.WriteU16(W);
86         message.WriteU16(H);
87         ::AxWin::SendMessage(message);
88 }
89
90 extern "C" void AxWin4_SetTitle(tAxWin4_Window *Window, const char *Title)
91 {
92         CSerialiser     message;
93         message.WriteU8(IPCMSG_SETWINATTR);
94         message.WriteU16(Window->m_id);
95         message.WriteU16(IPC_WINATTR_TITLE);
96         message.WriteString(Title);
97         ::AxWin::SendMessage(message);
98 }
99
100 extern "C" void AxWin4_DamageRect(tAxWin4_Window *Window, unsigned int X, unsigned int Y, unsigned int W, unsigned int H)
101 {
102         CSerialiser     message;
103         message.WriteU8(IPCMSG_DAMAGERECT);
104         message.WriteU16(Window->m_id);
105         message.WriteU16(X);
106         message.WriteU16(Y);
107         message.WriteU16(W);
108         message.WriteU16(H);
109         ::AxWin::SendMessage(message);
110 }
111
112 extern "C" void *AxWin4_GetWindowBuffer(tAxWin4_Window *Window)
113 {
114         if( Window->m_fd == -1 )
115         {
116                 CSerialiser     req;
117                 req.WriteU8(IPCMSG_GETWINBUF);
118                 req.WriteU16(Window->m_id);
119                 
120                 CDeserialiser   response = GetSyncReply(req, IPCMSG_GETWINBUF);
121                 unsigned int rspwin = response.ReadU16();
122                 if( rspwin != Window->m_id )
123                 {
124                         _SysDebug("AxWin4_GetWindowBuffer: GETWINBUF reply for different window (%u != %u)", rspwin, Window->m_id);
125                         return NULL;
126                 }
127                 
128                 uint64_t handle = response.ReadU64();
129                 Window->m_fd = _SysUnMarshalFD(handle);
130                 
131                 _SysDebug("AxWin4_GetWindowBuffer: %llx = %i", handle, Window->m_fd);
132         }
133
134         if( !Window->m_buffer )
135         {
136                 size_t  size = 640*480*4;
137                 Window->m_buffer = _SysMMap(NULL, size, MMAP_PROT_WRITE, MMAP_MAP_SHARED, Window->m_fd, 0);
138         }
139
140         return Window->m_buffer;
141 }
142
143 };      // namespace AxWin
144

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