VirtualBox

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

Last change on this file since 50346 was 50346, checked in by vboxsync, 11 years ago

Additions/x11/VBoxClient: more clean-up.

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

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