VirtualBox

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

Last change on this file since 6202 was 6202, checked in by vboxsync, 17 years ago

re-export x11

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