VirtualBox

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

Last change on this file since 84479 was 83135, checked in by vboxsync, 5 years ago

bugref:9637. Reverting the changes to seamless related files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.6 KB
Line 
1/* $Id: seamless-x11.h 83135 2020-02-21 14:28:56Z 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 {
52public:
53 /** Header structure for insertion into an AVL tree */
54 AVLU32NODECORE Core;
55 /** Is the window currently mapped? */
56 bool mhasShape;
57 /** Co-ordinates in the guest screen. */
58 int mX, mY;
59 /** Window dimensions. */
60 int mWidth, mHeight;
61 /** Number of rectangles used to represent the visible area. */
62 int mcRects;
63 /** Rectangles representing the visible area. These must be allocated
64 * by XMalloc and will be freed automatically if non-null when the class
65 * is destroyed. */
66 XRectangle *mpRects;
67 /** Constructor. */
68 VBoxGuestWinInfo(bool hasShape, int x, int y, int w, int h, int cRects,
69 XRectangle *pRects)
70 : mhasShape(hasShape), mX(x), mY(y), mWidth(w), mHeight(h),
71 mcRects(cRects), mpRects(pRects) {}
72
73 /** Destructor */
74 ~VBoxGuestWinInfo()
75 {
76 if (mpRects)
77 XFree(mpRects);
78 }
79#ifdef RT_NEED_NEW_AND_DELETE
80 RTMEM_IMPLEMENT_NEW_AND_DELETE();
81#endif
82
83private:
84 // We don't want a copy constructor or assignment operator
85 VBoxGuestWinInfo(const VBoxGuestWinInfo&);
86 VBoxGuestWinInfo& operator=(const VBoxGuestWinInfo&);
87};
88
89/** Callback type used for "DoWithAll" calls */
90typedef DECLCALLBACK(int) VBOXGUESTWINCALLBACK(VBoxGuestWinInfo *, void *);
91/** Pointer to VBOXGUESTWINCALLBACK */
92typedef VBOXGUESTWINCALLBACK *PVBOXGUESTWINCALLBACK;
93
94DECLCALLBACK(int) inline VBoxGuestWinCleanup(VBoxGuestWinInfo *pInfo, void *)
95{
96 delete pInfo;
97 return VINF_SUCCESS;
98}
99
100/**
101 * This class is just a wrapper around a map of structures containing
102 * information about the windows on the guest system. It has a function for
103 * adding a structure (see addWindow) and one for removing it by window
104 * handle (see removeWindow).
105 */
106class VBoxGuestWindowList
107{
108private:
109 // We don't want a copy constructor or an assignment operator
110 VBoxGuestWindowList(const VBoxGuestWindowList&);
111 VBoxGuestWindowList& operator=(const VBoxGuestWindowList&);
112
113 // Private class members
114 AVLU32TREE mWindows;
115
116public:
117 // Constructor
118 VBoxGuestWindowList(void) : mWindows(NULL) {}
119 // Destructor
120 ~VBoxGuestWindowList()
121 {
122 /** @todo having this inside the container class hard codes that the
123 * elements have to be allocated with the "new" operator, and
124 * I don't see a need to require this. */
125 doWithAll(VBoxGuestWinCleanup, NULL);
126 }
127
128#ifdef RT_NEED_NEW_AND_DELETE
129 RTMEM_IMPLEMENT_NEW_AND_DELETE();
130#endif
131
132 // Standard operations
133 VBoxGuestWinInfo *find(Window hWin)
134 {
135 return (VBoxGuestWinInfo *)RTAvlU32Get(&mWindows, hWin);
136 }
137
138 void detachAll(PVBOXGUESTWINCALLBACK pCallback, void *pvParam)
139 {
140 RTAvlU32Destroy(&mWindows, (PAVLU32CALLBACK)pCallback, pvParam);
141 }
142
143 int doWithAll(PVBOXGUESTWINCALLBACK pCallback, void *pvParam)
144 {
145 return RTAvlU32DoWithAll(&mWindows, 1, (PAVLU32CALLBACK)pCallback,
146 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,
155 pRects);
156 pInfo->Core.Key = hWin;
157 LogRelFlowFuncLeave();
158 return RTAvlU32Insert(&mWindows, &pInfo->Core);
159 }
160
161 VBoxGuestWinInfo *removeWindow(Window hWin)
162 {
163 LogRelFlowFuncEnter();
164 return (VBoxGuestWinInfo *)RTAvlU32Remove(&mWindows, hWin);
165 }
166};
167
168class SeamlessX11
169{
170private:
171 // We don't want a copy constructor or assignment operator
172 SeamlessX11(const SeamlessX11&);
173 SeamlessX11& operator=(const SeamlessX11&);
174
175 // Private member variables
176 /** Pointer to the host callback. */
177 PFNSENDREGIONUPDATE mHostCallback;
178 /** Our connection to the X11 display we are running on. */
179 Display *mDisplay;
180 /** Class to keep track of visible guest windows. */
181 VBoxGuestWindowList mGuestWindows;
182 /** The current set of seamless rectangles. */
183 RTRECT *mpRects;
184 /** The current number of seamless rectangles. */
185 int mcRects;
186 /** Do we support the X shaped window extension? */
187 bool mSupportsShape;
188 /** Is seamless mode currently enabled? */
189 bool mEnabled;
190 /** Have there been changes since the last time we sent a notification? */
191 bool mChanged;
192
193 // Private methods
194
195 // Methods to manage guest window information
196 /**
197 * Store information about a desktop window and register for structure events on it.
198 * If it is mapped, go through the list of it's children and add information about
199 * mapped children to the tree of visible windows, making sure that those windows are
200 * not already in our list of desktop windows.
201 *
202 * @param hWin the window concerned - should be a "desktop" window
203 */
204 void monitorClientList(void);
205 void unmonitorClientList(void);
206 void rebuildWindowTree(void);
207 void addClients(const Window hRoot);
208 bool isVirtualRoot(Window hWin);
209 void addClientWindow(Window hWin);
210 void freeWindowTree(void);
211 void updateHostSeamlessInfo(void);
212 int updateRects(void);
213
214public:
215 /**
216 * Initialise the guest and ensure that it is capable of handling seamless mode
217 * @param pHostCallback Host interface callback to notify of window configuration
218 * changes.
219 *
220 * @returns iprt status code
221 */
222 int init(PFNSENDREGIONUPDATE pHostCallback);
223
224 /**
225 * Shutdown seamless event monitoring.
226 */
227 void uninit(void)
228 {
229 if (mHostCallback)
230 stop();
231 mHostCallback = NULL;
232 if (mDisplay)
233 XCloseDisplay(mDisplay);
234 mDisplay = NULL;
235 }
236
237 /**
238 * Initialise seamless event reporting in the guest.
239 *
240 * @returns IPRT status code
241 */
242 int start(void);
243 /** Stop reporting seamless events. */
244 void stop(void);
245 /** Get the current list of visible rectangles. */
246 RTRECT *getRects(void);
247 /** Get the number of visible rectangles in the current list */
248 size_t getRectCount(void);
249
250 /** Process next event in the guest event queue - called by the event thread. */
251 void nextConfigurationEvent(void);
252 /** Wake up the event thread if it is waiting for an event so that it can exit. */
253 bool interruptEventWait(void);
254
255 /* Methods to handle X11 events. These are public so that the unit test
256 * can call them. */
257 void doConfigureEvent(Window hWin);
258 void doShapeEvent(Window hWin);
259
260 SeamlessX11(void)
261 : mHostCallback(NULL), mDisplay(NULL), mpRects(NULL), mcRects(0),
262 mSupportsShape(false), mEnabled(false), mChanged(false) {}
263
264 ~SeamlessX11()
265 {
266 uninit();
267 }
268
269#ifdef RT_NEED_NEW_AND_DELETE
270 RTMEM_IMPLEMENT_NEW_AND_DELETE();
271#endif
272};
273
274#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