VirtualBox

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

Last change on this file since 33983 was 33540, checked in by vboxsync, 14 years ago

*: spelling fixes, thanks Timeless!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.2 KB
Line 
1/** @file
2 *
3 * Seamless mode:
4 * Linux guest.
5 */
6
7/*
8 * Copyright (C) 2006-2007 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
24#include "seamless-guest.h"
25
26#include <X11/Xlib.h>
27#include <X11/Xutil.h>
28#include <X11/extensions/shape.h>
29
30#include <map>
31#include <vector>
32
33#define WM_TYPE_PROP "_NET_WM_WINDOW_TYPE"
34#define WM_TYPE_DESKTOP_PROP "_NET_WM_WINDOW_TYPE_DESKTOP"
35
36/* This is defined wrong in my X11 header files! */
37#define VBoxShapeNotify 64
38
39/**
40 * Wrapper class around the VBoxGuestX11Pointer to provide reference semantics.
41 * See auto_ptr in the C++ <memory> header.
42 */
43template <class T>
44struct VBoxGuestX11PointerRef
45{
46 T *mValue;
47
48 VBoxGuestX11PointerRef(T* pValue) { mValue = pValue; }
49};
50
51/** An auto pointer for pointers which have to be XFree'd. */
52template <class T>
53class VBoxGuestX11Pointer
54{
55private:
56 T *mValue;
57public:
58 VBoxGuestX11Pointer(T *pValue = 0) { mValue = pValue; }
59 ~VBoxGuestX11Pointer() { if (0 != mValue) XFree(mValue); }
60
61 /** release method to get the pointer's value and "reset" the pointer. */
62 T *release(void) { T *pTmp = mValue; mValue = 0; return pTmp; }
63
64 /** reset the pointer value to zero or to another pointer. */
65 void reset(T* pValue = 0) { if (pValue != mValue) { XFree(mValue); mValue = pValue; } }
66
67 /** Copy constructor */
68 VBoxGuestX11Pointer(VBoxGuestX11Pointer &orig) { mValue = orig.release(); }
69
70 /** Copy from equivalent class */
71 template <class T1>
72 VBoxGuestX11Pointer(VBoxGuestX11Pointer<T1> &orig) { mValue = orig.release(); }
73
74 /** Assignment operator. */
75 VBoxGuestX11Pointer& operator=(VBoxGuestX11Pointer &orig)
76 {
77 reset(orig.release());
78 return *this;
79 }
80
81 /** Assignment from equivalent class. */
82 template <class T1>
83 VBoxGuestX11Pointer& operator=(VBoxGuestX11Pointer<T1> &orig)
84 {
85 reset(orig.release);
86 return *this;
87 }
88
89 /** Assignment from a pointer. */
90 VBoxGuestX11Pointer& operator=(T *pValue)
91 {
92 if (0 != mValue)
93 {
94 XFree(mValue);
95 }
96 mValue = pValue;
97 return *this;
98 }
99
100 /** Dereference with * operator. */
101 T &operator*() { return *mValue; }
102
103 /** Dereference with -> operator. */
104 T *operator->() { return mValue; }
105
106 /** Accessing the value inside. */
107 T *get(void) { return mValue; }
108
109 /** Convert a reference structure into an X11 pointer. */
110 VBoxGuestX11Pointer(VBoxGuestX11PointerRef<T> ref) { mValue = ref.mValue; }
111
112 /** Assign from a reference structure into an X11 pointer. */
113 VBoxGuestX11Pointer& operator=(VBoxGuestX11PointerRef<T> ref)
114 {
115 if (ref.mValue != mValue)
116 {
117 XFree(mValue);
118 mValue = ref.mValue;
119 }
120 return *this;
121 }
122
123 /** Typecast an X11 pointer to a reference structure. */
124 template <class T1>
125 operator VBoxGuestX11PointerRef<T1>() { return VBoxGuestX11PointerRef<T1>(release()); }
126
127 /** Typecast an X11 pointer to an X11 pointer around a different type. */
128 template <class T1>
129 operator VBoxGuestX11Pointer<T1>() { return VBoxGuestX11Pointer<T1>(release()); }
130};
131
132/**
133 * Wrapper class around an X11 display pointer which takes care of closing the display
134 * when it is destroyed at the latest.
135 */
136class VBoxGuestX11Display
137{
138private:
139 Display *mDisplay;
140public:
141 VBoxGuestX11Display(void) { mDisplay = NULL; }
142 bool init(char *name = NULL)
143 {
144 LogRelFlowFunc(("\n"));
145 mDisplay = XOpenDisplay(name);
146 LogRelFlowFunc(("returning\n"));
147 return (mDisplay != NULL);
148 }
149 operator Display *() { return mDisplay; }
150 Display *get(void) { return mDisplay; }
151 bool isValid(void) { return (mDisplay != NULL); }
152 int close(void)
153 {
154 LogRelFlowFunc(("\n"));
155 int rc = XCloseDisplay(mDisplay);
156 mDisplay = NULL;
157 LogRelFlowFunc(("returning\n"));
158 return rc;
159 }
160 ~VBoxGuestX11Display()
161 {
162 if (mDisplay != NULL)
163 close();
164 }
165};
166
167/** Structure containing information about a guest window's position and visible area.
168 Used inside of VBoxGuestWindowList. */
169struct VBoxGuestWinInfo {
170public:
171 /** Is the window currently mapped? */
172 bool mhasShape;
173 /** Co-ordinates in the guest screen. */
174 int mX, mY;
175 /** Window dimensions. */
176 int mWidth, mHeight;
177 /** Number of rectangles used to represent the visible area. */
178 int mcRects;
179 /** Rectangles representing the visible area. These must be allocated by XMalloc
180 and will be freed automatically if non-null when the class is destroyed. */
181 VBoxGuestX11Pointer<XRectangle> mapRects;
182 /** Constructor. */
183 VBoxGuestWinInfo(bool hasShape, int x, int y, int w, int h, int cRects,
184 VBoxGuestX11Pointer<XRectangle> rects)
185 : mapRects(rects)
186 {
187 mhasShape = hasShape, mX = x; mY = y; mWidth = w; mHeight = h; mcRects = cRects;
188 }
189
190private:
191 // We don't want a copy constructor or assignment operator
192 VBoxGuestWinInfo(const VBoxGuestWinInfo&);
193 VBoxGuestWinInfo& operator=(const VBoxGuestWinInfo&);
194};
195
196/**
197 * This class is just a wrapper around a map of structures containing information about
198 * the windows on the guest system. It has a function for adding a structure (see addWindow),
199 * for removing it by window handle (see removeWindow) and an iterator for
200 * going through the list.
201 */
202class VBoxGuestWindowList
203{
204private:
205 // We don't want a copy constructor or an assignment operator
206 VBoxGuestWindowList(const VBoxGuestWindowList&);
207 VBoxGuestWindowList& operator=(const VBoxGuestWindowList&);
208
209 // Private class members
210 std::map<Window, VBoxGuestWinInfo *> mWindows;
211
212public:
213 // Just proxy iterators to map::iterator
214 typedef std::map<Window, VBoxGuestWinInfo *>::const_iterator const_iterator;
215 typedef std::map<Window, VBoxGuestWinInfo *>::iterator iterator;
216
217 // Constructor
218 VBoxGuestWindowList(void) {}
219 // Destructor
220 ~VBoxGuestWindowList()
221 {
222 /* We use post-increment in the operation to prevent the iterator from being invalidated. */
223 try
224 {
225 for (iterator it = begin(); it != end(); removeWindow(it++))
226 ;
227 }
228 catch(...) {}
229 }
230
231 // Standard operations
232 const_iterator begin() const { return mWindows.begin(); }
233 iterator begin() { return mWindows.begin(); }
234 const_iterator end() const { return mWindows.end(); }
235 iterator end() { return mWindows.end(); }
236 const_iterator find(Window win) const { return mWindows.find(win); }
237 iterator find(Window win) { return mWindows.find(win); }
238
239 void addWindow(Window hWin, bool isMapped, int x, int y, int w, int h, int cRects,
240 VBoxGuestX11Pointer<XRectangle> rects)
241 {
242 LogRelFlowFunc(("\n"));
243 VBoxGuestWinInfo *pInfo = new VBoxGuestWinInfo(isMapped, x, y, w, h, cRects,
244 rects);
245 mWindows.insert(std::pair<Window, VBoxGuestWinInfo *>(hWin, pInfo));
246 LogRelFlowFunc(("returning\n"));
247 }
248
249 void removeWindow(iterator it)
250 {
251 LogRelFlowFunc(("called\n"));
252 delete it->second;
253 mWindows.erase(it);
254 }
255
256 void removeWindow(Window hWin)
257 {
258 LogRelFlowFunc(("called\n"));
259 removeWindow(find(hWin));
260 }
261};
262
263class VBoxGuestSeamlessX11;
264
265class VBoxGuestSeamlessX11 : public VBoxGuestSeamlessGuest
266{
267private:
268 // We don't want a copy constructor or assignment operator
269 VBoxGuestSeamlessX11(const VBoxGuestSeamlessX11&);
270 VBoxGuestSeamlessX11& operator=(const VBoxGuestSeamlessX11&);
271
272 // Private member variables
273 /** Pointer to the observer class. */
274 VBoxGuestSeamlessObserver *mObserver;
275 /** Our connection to the X11 display we are running on. */
276 VBoxGuestX11Display mDisplay;
277 /** Class to keep track of visible guest windows. */
278 VBoxGuestWindowList mGuestWindows;
279 /** Keeps track of the total number of rectangles needed for the visible area of all
280 guest windows on the last call to getRects. Used for pre-allocating space in
281 the vector of rectangles passed to the host. */
282 int mcRects;
283 /** Do we support the X shaped window extension? */
284 bool mSupportsShape;
285 /** Is seamless mode currently enabled? */
286 bool mEnabled;
287 /** Have there been changes since the last time we sent a notification? */
288 bool mChanged;
289
290 // Private methods
291
292 // Methods to manage guest window information
293 /**
294 * Store information about a desktop window and register for structure events on it.
295 * If it is mapped, go through the list of it's children and add information about
296 * mapped children to the tree of visible windows, making sure that those windows are
297 * not already in our list of desktop windows.
298 *
299 * @param hWin the window concerned - should be a "desktop" window
300 */
301 void monitorClientList(void);
302 void unmonitorClientList(void);
303 void rebuildWindowTree(void);
304 void addClients(const Window hRoot);
305 bool isVirtualRoot(Window hWin);
306 void addClientWindow(Window hWin);
307 void freeWindowTree(void);
308 void updateHostSeamlessInfo(void);
309
310public:
311 /**
312 * Initialise the guest and ensure that it is capable of handling seamless mode
313 * @param pObserver Observer class to connect host and guest interfaces
314 *
315 * @returns iprt status code
316 */
317 int init(VBoxGuestSeamlessObserver *pObserver);
318
319 /**
320 * Shutdown seamless event monitoring.
321 */
322 void uninit(void)
323 {
324 if (0 != mObserver)
325 {
326 stop();
327 }
328 mObserver = 0;
329 }
330
331 /**
332 * Initialise seamless event reporting in the guest.
333 *
334 * @returns IPRT status code
335 */
336 int start(void);
337 /** Stop reporting seamless events. */
338 void stop(void);
339 /** Get the current list of visible rectangles. */
340 std::auto_ptr<std::vector<RTRECT> > getRects(void);
341
342 /** Process next event in the guest event queue - called by the event thread. */
343 void nextEvent(void);
344 /** Wake up the event thread if it is waiting for an event so that it can exit. */
345 bool interruptEvent(void);
346
347 /* Methods to handle X11 events. These are public so that the unit test
348 * can call them. */
349 void doConfigureEvent(Window hWin);
350 void doMapEvent(Window hWin);
351 void doUnmapEvent(Window hWin);
352 void doShapeEvent(Window hWin);
353
354 VBoxGuestSeamlessX11(void)
355 {
356 mObserver = 0; mcRects = 0; mEnabled = false; mSupportsShape = false;
357 }
358
359 ~VBoxGuestSeamlessX11()
360 {
361 try
362 {
363 uninit();
364 }
365 catch(...) {}
366 }
367};
368
369typedef VBoxGuestSeamlessX11 VBoxGuestSeamlessGuestImpl;
370
371#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