VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h@ 85922

Last change on this file since 85922 was 85121, checked in by vboxsync, 4 years ago

iprt/cdefs.h: Refactored the typedef use of DECLCALLBACK as well as DECLCALLBACKMEMBER to wrap the whole expression, similar to the DECLR?CALLBACKMEMBER macros. This allows adding a throw() at the end when compiling with the VC++ compiler to indicate that the callbacks won't throw anything, so we can stop supressing the C5039 warning about passing functions that can potential throw C++ exceptions to extern C code that can't necessarily cope with such (unwind,++). Introduced a few _EX variations that allows specifying different/no calling convention too, as that's handy when dynamically resolving host APIs. Fixed numerous places missing DECLCALLBACK and such. Left two angry @todos regarding use of CreateThread. bugref:9794

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.5 KB
Line 
1/* $Id: seamless-x11.h 85121 2020-07-08 19:33:26Z vboxsync $ */
2/** @file
3 * Seamless mode - X11 guests.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef GA_INCLUDED_SRC_x11_VBoxClient_seamless_x11_h
19#define GA_INCLUDED_SRC_x11_VBoxClient_seamless_x11_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <VBox/log.h>
25#include <iprt/avl.h>
26#ifdef RT_NEED_NEW_AND_DELETE
27# include <iprt/mem.h>
28# include <new>
29#endif
30
31#include <X11/Xlib.h>
32#include <X11/Xutil.h>
33#include <X11/extensions/shape.h>
34
35#define WM_TYPE_PROP "_NET_WM_WINDOW_TYPE"
36#define WM_TYPE_DESKTOP_PROP "_NET_WM_WINDOW_TYPE_DESKTOP"
37
38/* This is defined wrong in my X11 header files! */
39#define VBoxShapeNotify 64
40
41/**
42 * Callback which provides the interface for notifying the host of changes to
43 * the X11 window configuration, mainly split out from @a VBoxGuestSeamlessHost
44 * to simplify the unit test.
45 */
46typedef void FNSENDREGIONUPDATE(RTRECT *pRects, size_t cRects);
47typedef FNSENDREGIONUPDATE *PFNSENDREGIONUPDATE;
48
49/** Structure containing information about a guest window's position and visible area.
50 Used inside of VBoxGuestWindowList. */
51struct VBoxGuestWinInfo
52{
53public:
54 /** Header structure for insertion into an AVL tree */
55 AVLU32NODECORE Core;
56 /** Is the window currently mapped? */
57 bool mhasShape;
58 /** Co-ordinates in the guest screen. */
59 int mX, mY;
60 /** Window dimensions. */
61 int mWidth, mHeight;
62 /** Number of rectangles used to represent the visible area. */
63 int mcRects;
64 /** Rectangles representing the visible area. These must be allocated
65 * by XMalloc and will be freed automatically if non-null when the class
66 * is destroyed. */
67 XRectangle *mpRects;
68 /** Constructor. */
69 VBoxGuestWinInfo(bool hasShape, int x, int y, int w, int h, int cRects, XRectangle *pRects)
70 : mhasShape(hasShape), mX(x), mY(y), mWidth(w), mHeight(h)
71 , mcRects(cRects), mpRects(pRects)
72 {}
73
74 /** Destructor */
75 ~VBoxGuestWinInfo()
76 {
77 if (mpRects)
78 XFree(mpRects);
79 }
80#ifdef RT_NEED_NEW_AND_DELETE
81 RTMEM_IMPLEMENT_NEW_AND_DELETE();
82#endif
83
84private:
85 // We don't want a copy constructor or assignment operator
86 VBoxGuestWinInfo(const VBoxGuestWinInfo &);
87 VBoxGuestWinInfo &operator=(const VBoxGuestWinInfo &);
88};
89
90/** Callback type used for "DoWithAll" calls */
91typedef DECLCALLBACKTYPE(int, FNVBOXGUESTWINCALLBACK,(VBoxGuestWinInfo *, void *));
92/** Pointer to VBOXGUESTWINCALLBACK */
93typedef FNVBOXGUESTWINCALLBACK *PFNVBOXGUESTWINCALLBACK;
94
95static inline DECLCALLBACK(int) VBoxGuestWinCleanup(VBoxGuestWinInfo *pInfo, void *)
96{
97 delete pInfo;
98 return VINF_SUCCESS;
99}
100
101/**
102 * This class is just a wrapper around a map of structures containing
103 * information about the windows on the guest system. It has a function for
104 * adding a structure (see addWindow) and one for removing it by window
105 * handle (see removeWindow).
106 */
107class VBoxGuestWindowList
108{
109private:
110 // We don't want a copy constructor or an assignment operator
111 VBoxGuestWindowList(const VBoxGuestWindowList&);
112 VBoxGuestWindowList& operator=(const VBoxGuestWindowList&);
113
114 // Private class members
115 AVLU32TREE mWindows;
116
117public:
118 // Constructor
119 VBoxGuestWindowList(void) : mWindows(NULL) {}
120 // Destructor
121 ~VBoxGuestWindowList()
122 {
123 /** @todo having this inside the container class hard codes that the
124 * elements have to be allocated with the "new" operator, and
125 * I don't see a need to require this. */
126 doWithAll(VBoxGuestWinCleanup, NULL);
127 }
128
129#ifdef RT_NEED_NEW_AND_DELETE
130 RTMEM_IMPLEMENT_NEW_AND_DELETE();
131#endif
132
133 // Standard operations
134 VBoxGuestWinInfo *find(Window hWin)
135 {
136 return (VBoxGuestWinInfo *)RTAvlU32Get(&mWindows, hWin);
137 }
138
139 void detachAll(PFNVBOXGUESTWINCALLBACK pfnCallback, void *pvParam)
140 {
141 RTAvlU32Destroy(&mWindows, (PAVLU32CALLBACK)pfnCallback, pvParam);
142 }
143
144 int doWithAll(PFNVBOXGUESTWINCALLBACK pfnCallback, void *pvParam)
145 {
146 return RTAvlU32DoWithAll(&mWindows, 1, (PAVLU32CALLBACK)pfnCallback, pvParam);
147 }
148
149 bool addWindow(Window hWin, bool isMapped, int x, int y, int w, int h, int cRects,
150 XRectangle *pRects)
151 {
152 LogRelFlowFunc(("hWin=%lu, isMapped=%RTbool, x=%d, y=%d, w=%d, h=%d, cRects=%d\n",
153 (unsigned long) hWin, isMapped, x, y, w, h, cRects));
154 VBoxGuestWinInfo *pInfo = new VBoxGuestWinInfo(isMapped, x, y, w, h, cRects, pRects);
155 pInfo->Core.Key = hWin;
156 LogRelFlowFuncLeave();
157 return RTAvlU32Insert(&mWindows, &pInfo->Core);
158 }
159
160 VBoxGuestWinInfo *removeWindow(Window hWin)
161 {
162 LogRelFlowFuncEnter();
163 return (VBoxGuestWinInfo *)RTAvlU32Remove(&mWindows, hWin);
164 }
165};
166
167class SeamlessX11
168{
169private:
170 // We don't want a copy constructor or assignment operator
171 SeamlessX11(const SeamlessX11&);
172 SeamlessX11& operator=(const SeamlessX11&);
173
174 // Private member variables
175 /** Pointer to the host callback. */
176 PFNSENDREGIONUPDATE mHostCallback;
177 /** Our connection to the X11 display we are running on. */
178 Display *mDisplay;
179 /** Class to keep track of visible guest windows. */
180 VBoxGuestWindowList mGuestWindows;
181 /** The current set of seamless rectangles. */
182 RTRECT *mpRects;
183 /** The current number of seamless rectangles. */
184 int mcRects;
185 /** Do we support the X shaped window extension? */
186 bool mSupportsShape;
187 /** Is seamless mode currently enabled? */
188 bool mEnabled;
189 /** Have there been changes since the last time we sent a notification? */
190 bool mChanged;
191
192 // Private methods
193
194 // Methods to manage guest window information
195 /**
196 * Store information about a desktop window and register for structure events on it.
197 * If it is mapped, go through the list of it's children and add information about
198 * mapped children to the tree of visible windows, making sure that those windows are
199 * not already in our list of desktop windows.
200 *
201 * @param hWin the window concerned - should be a "desktop" window
202 */
203 void monitorClientList(void);
204 void unmonitorClientList(void);
205 void rebuildWindowTree(void);
206 void addClients(const Window hRoot);
207 bool isVirtualRoot(Window hWin);
208 void addClientWindow(Window hWin);
209 void freeWindowTree(void);
210 void updateHostSeamlessInfo(void);
211 int updateRects(void);
212
213public:
214 /**
215 * Initialise the guest and ensure that it is capable of handling seamless mode
216 * @param pHostCallback Host interface callback to notify of window configuration
217 * changes.
218 *
219 * @returns iprt status code
220 */
221 int init(PFNSENDREGIONUPDATE pHostCallback);
222
223 /**
224 * Shutdown seamless event monitoring.
225 */
226 void uninit(void)
227 {
228 if (mHostCallback)
229 stop();
230 mHostCallback = NULL;
231 if (mDisplay)
232 XCloseDisplay(mDisplay);
233 mDisplay = NULL;
234 }
235
236 /**
237 * Initialise seamless event reporting in the guest.
238 *
239 * @returns IPRT status code
240 */
241 int start(void);
242 /** Stop reporting seamless events. */
243 void stop(void);
244 /** Get the current list of visible rectangles. */
245 RTRECT *getRects(void);
246 /** Get the number of visible rectangles in the current list */
247 size_t getRectCount(void);
248
249 /** Process next event in the guest event queue - called by the event thread. */
250 void nextConfigurationEvent(void);
251 /** Wake up the event thread if it is waiting for an event so that it can exit. */
252 bool interruptEventWait(void);
253
254 /* Methods to handle X11 events. These are public so that the unit test
255 * can call them. */
256 void doConfigureEvent(Window hWin);
257 void doShapeEvent(Window hWin);
258
259 SeamlessX11(void)
260 : mHostCallback(NULL), mDisplay(NULL), mpRects(NULL), mcRects(0),
261 mSupportsShape(false), mEnabled(false), mChanged(false) {}
262
263 ~SeamlessX11()
264 {
265 uninit();
266 }
267
268#ifdef RT_NEED_NEW_AND_DELETE
269 RTMEM_IMPLEMENT_NEW_AND_DELETE();
270#endif
271};
272
273#endif /* !GA_INCLUDED_SRC_x11_VBoxClient_seamless_x11_h */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette