VirtualBox

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

Last change on this file since 61176 was 57265, checked in by vboxsync, 9 years ago

Additions/x11/VBoxClient: fix problems with invisible seamless windows in OpenBox and improve seamless responsiveness.

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