VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/xclient/seamless-x11.h@ 11602

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

Solaris 10 build (with no additions); XPCOM Python works on Solaris

  • 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 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 LogFlowThisFunc(("\n"));
243 VBoxGuestWinInfo *pInfo = new VBoxGuestWinInfo(isMapped, x, y, w, h, cRects,
244 rects);
245 mWindows.insert(std::pair<Window, VBoxGuestWinInfo *>(hWin, pInfo));
246 LogFlowThisFunc(("returning\n"));
247 }
248
249 void removeWindow(iterator it)
250 {
251 LogFlowThisFunc(("called\n"));
252 delete it->second;
253 mWindows.erase(it);
254 }
255
256 void removeWindow(Window hWin)
257 {
258 LogFlowThisFunc(("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 seamles mode currently enabled? */
286 bool mEnabled;
287
288 // Private methods
289
290 // Methods to handle X11 events
291 void doConfigureEvent(const XConfigureEvent *event);
292 void doMapEvent(const XMapEvent *event);
293 void doUnmapEvent(const XUnmapEvent *event);
294 void doShapeEvent(const XShapeEvent *event);
295
296 // Methods to manage guest window information
297 /**
298 * Store information about a desktop window and register for structure events on it.
299 * If it is mapped, go through the list of it's children and add information about
300 * mapped children to the tree of visible windows, making sure that those windows are
301 * not already in our list of desktop windows.
302 *
303 * @param hWin the window concerned - should be a "desktop" window
304 */
305 void monitorClientList(void);
306 void unmonitorClientList(void);
307 void rebuildWindowTree(void);
308 void addClients(const Window hRoot);
309 bool isVirtualRoot(Window hWin);
310 void addClientWindow(Window hWin);
311 void freeWindowTree(void);
312 void updateHostSeamlessInfo(void);
313
314public:
315 /**
316 * Initialise the guest and ensure that it is capable of handling seamless mode
317 * @param pObserver Observer class to connect host and guest interfaces
318 *
319 * @returns iprt status code
320 */
321 int init(VBoxGuestSeamlessObserver *pObserver);
322
323 /**
324 * Shutdown seamless event monitoring.
325 */
326 void uninit(void)
327 {
328 if (0 != mObserver)
329 {
330 stop();
331 }
332 mObserver = 0;
333 }
334
335 /**
336 * Initialise seamless event reporting in the guest.
337 *
338 * @returns IPRT status code
339 */
340 int start(void);
341 /** Stop reporting seamless events. */
342 void stop(void);
343 /** Get the current list of visible rectangles. */
344 std::auto_ptr<std::vector<RTRECT> > getRects(void);
345
346 /** Process next event in the guest event queue - called by the event thread. */
347 void nextEvent(void);
348 /** Wake up the event thread if it is waiting for an event so that it can exit. */
349 bool interruptEvent(void);
350
351 VBoxGuestSeamlessX11(void)
352 {
353 mObserver = 0; mcRects = 0; mEnabled = false; mSupportsShape = false;
354 }
355
356 ~VBoxGuestSeamlessX11()
357 {
358 try
359 {
360 uninit();
361 }
362 catch(...) {}
363 }
364};
365
366typedef VBoxGuestSeamlessX11 VBoxGuestSeamlessGuestImpl;
367
368#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