VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/xclient/seamless-host.cpp@ 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: 4.7 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/*****************************************************************************
20* Header files *
21*****************************************************************************/
22
23#include <iprt/log.h>
24#include <iprt/err.h>
25
26#include "seamless-host.h"
27
28#ifdef DEBUG
29# include <stdio.h>
30# define DPRINT(a) printf a
31#else
32# define DPRINT(a)
33#endif
34
35/**
36 * Start the service.
37 * @returns iprt status value
38 */
39int VBoxGuestSeamlessHost::start(void)
40{
41 int rc = VERR_NOT_SUPPORTED;
42
43 if (mRunning) /* Assertion */
44 {
45 LogRelThisFunc(("Service started twice!\n"));
46 DPRINT(("Service started twice!\n"));
47 return VERR_INTERNAL_ERROR;
48 }
49 if (VbglR3SeamlessSetCap(true))
50 {
51 DPRINT(("Enabled host seamless.\n"));
52 rc = mThread.start();
53 if (RT_SUCCESS(rc))
54 {
55 mRunning = true;
56 }
57 else
58 {
59 DPRINT(("Disabled host seamless again.\n"));
60 VbglR3SeamlessSetCap(false);
61 }
62 }
63 if (RT_FAILURE(rc))
64 {
65 DPRINT(("Failed to enable host seamless, rc=%d\n", rc));
66 }
67 return rc;
68}
69
70/** Stops the service. */
71void VBoxGuestSeamlessHost::stop(void)
72{
73 if (!mRunning) /* Assertion */
74 {
75 LogRelThisFunc(("Service not running!\n"));
76 return;
77 }
78 mThread.stop(0, 0);
79 VbglR3SeamlessSetCap(false);
80 mRunning = false;
81}
82
83/**
84 * Waits for a seamless state change events from the host and dispatch it.
85 *
86 * @returns IRPT return code.
87 */
88int VBoxGuestSeamlessHost::nextEvent(void)
89{
90 VMMDevSeamlessMode newMode;
91
92 int rc = VbglR3SeamlessWaitEvent(&newMode);
93 switch(newMode)
94 {
95 case VMMDev_Seamless_Visible_Region:
96 /* A simplified seamless mode, obtained by making the host VM window borderless and
97 making the guest desktop transparent. */
98 mState = ENABLE;
99 mObserver->notify();
100 break;
101 case VMMDev_Seamless_Host_Window:
102 /* One host window represents one guest window. Not yet implemented. */
103 LogRelFunc(("Warning: VMMDev_Seamless_Host_Window request received.\n"));
104 /* fall through to default */
105 default:
106 LogRelFunc(("Warning: unsupported VMMDev_Seamless request received.\n"));
107 /* fall through to case VMMDev_Seamless_Disabled */
108 case VMMDev_Seamless_Disabled:
109 mState = DISABLE;
110 mObserver->notify();
111 }
112 return rc;
113}
114
115/**
116 * Update the set of visible rectangles in the host.
117 */
118void VBoxGuestSeamlessHost::updateRects(std::auto_ptr<std::vector<RTRECT> > pRects)
119{
120 if (0 == pRects.get()) /* Assertion */
121 {
122 LogRelThisFunc(("ERROR: called with null pointer!\n"));
123 return;
124 }
125 VbglR3SeamlessSendRects(pRects.get()->size(), pRects.get()->data());
126}
127
128/**
129 * The actual thread function.
130 *
131 * @returns iprt status code as thread return value
132 * @param pParent the VBoxGuestThread running this thread function
133 */
134int VBoxGuestSeamlessHostThread::threadFunction(VBoxGuestThread *pThread)
135{
136 if (0 != mHost)
137 {
138 mThread = pThread;
139 while (!mThread->isStopping())
140 {
141 if (RT_FAILURE(mHost->nextEvent()) && !mThread->isStopping())
142 {
143 /* If we are not stopping, sleep for a bit to avoid using up too
144 much CPU while retrying. */
145 mThread->yield();
146 }
147 }
148 }
149 return VINF_SUCCESS;
150}
151
152/**
153 * Send a signal to the thread function that it should exit
154 */
155void VBoxGuestSeamlessHostThread::stop(void)
156{
157 if (0 != mHost)
158 {
159 /**
160 * @todo is this reasonable? If the thread is in the event loop then the cancelEvent()
161 * will cause it to exit. If it enters or exits the event loop it will also
162 * notice that we wish it to exit. And if it is somewhere in-between, the
163 * yield() should give it time to get to one of places mentioned above.
164 */
165 for (int i = 0; (i < 5) && mThread->isRunning(); ++i)
166 {
167 mHost->cancelEvent();
168 mThread->yield();
169 }
170 }
171}
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