VirtualBox

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

Last change on this file since 17610 was 12916, checked in by vboxsync, 16 years ago

warning

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