VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp@ 36308

Last change on this file since 36308 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.2 KB
Line 
1/** @file
2 * X11 Guest client - seamless mode, missing proper description while using the
3 * potentially confusing word 'host'.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/*****************************************************************************
19* Header files *
20*****************************************************************************/
21#include <VBox/log.h>
22#include <VBox/VMMDev.h>
23#include <VBox/VBoxGuestLib.h>
24#include <iprt/err.h>
25
26#include "seamless-host.h"
27
28/**
29 * Start the service.
30 * @returns iprt status value
31 */
32int VBoxGuestSeamlessHost::start(void)
33{
34 int rc = VERR_NOT_SUPPORTED;
35
36 LogRelFlowFunc(("\n"));
37 if (mRunning) /* Assertion */
38 {
39 LogRel(("VBoxClient: seamless service started twice!\n"));
40 return VERR_INTERNAL_ERROR;
41 }
42 rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0);
43 if (RT_FAILURE(rc))
44 {
45 LogRel(("VBoxClient (seamless): failed to set the guest IRQ filter mask, rc=%Rrc\n", rc));
46 }
47 rc = VbglR3SeamlessSetCap(true);
48 if (RT_SUCCESS(rc))
49 {
50 LogRel(("VBoxClient: enabled seamless capability on host.\n"));
51 rc = mThread.start();
52 if (RT_SUCCESS(rc))
53 {
54 mRunning = true;
55 }
56 else
57 {
58 LogRel(("VBoxClient: failed to start seamless event thread, rc=%Rrc. Disabled seamless capability on host again.\n", rc));
59 VbglR3SeamlessSetCap(false);
60 }
61 }
62 if (RT_FAILURE(rc))
63 {
64 LogRel(("VBoxClient (seamless): failed to enable seamless capability on host, rc=%Rrc\n", rc));
65 }
66 LogRelFlowFunc(("returning %Rrc\n", rc));
67 return rc;
68}
69
70/** Stops the service. */
71void VBoxGuestSeamlessHost::stop(RTMSINTERVAL cMillies /* = RT_INDEFINITE_WAIT */)
72{
73 LogRelFlowFunc(("returning\n"));
74 if (!mRunning) /* Assertion */
75 {
76 LogRel(("VBoxClient: tried to stop seamless service which is not running!\n"));
77 return;
78 }
79 mThread.stop(cMillies, 0);
80 VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
81 VbglR3SeamlessSetCap(false);
82 mRunning = false;
83 LogRelFlowFunc(("returning\n"));
84}
85
86/**
87 * Waits for a seamless state change events from the host and dispatch it.
88 *
89 * @returns IRPT return code.
90 */
91int VBoxGuestSeamlessHost::nextEvent(void)
92{
93 VMMDevSeamlessMode newMode = VMMDev_Seamless_Disabled;
94
95 LogRelFlowFunc(("\n"));
96 int rc = VbglR3SeamlessWaitEvent(&newMode);
97 if (RT_SUCCESS(rc))
98 {
99 switch(newMode)
100 {
101 case VMMDev_Seamless_Visible_Region:
102 /* A simplified seamless mode, obtained by making the host VM window borderless and
103 making the guest desktop transparent. */
104#ifdef DEBUG
105 LogRelFunc(("VMMDev_Seamless_Visible_Region request received (VBoxClient).\n"));
106#endif
107 mState = ENABLE;
108 mObserver->notify();
109 break;
110 case VMMDev_Seamless_Host_Window:
111 /* One host window represents one guest window. Not yet implemented. */
112 LogRelFunc(("Warning: VMMDev_Seamless_Host_Window request received (VBoxClient).\n"));
113 /* fall through to default */
114 default:
115 LogRelFunc(("Warning: unsupported VMMDev_Seamless request %d received (VBoxClient).\n", newMode));
116 /* fall through to case VMMDev_Seamless_Disabled */
117 case VMMDev_Seamless_Disabled:
118#ifdef DEBUG
119 LogRelFunc(("VMMDev_Seamless_Disabled set (VBoxClient).\n"));
120#endif
121 mState = DISABLE;
122 mObserver->notify();
123 }
124 }
125 else
126 {
127 LogRelFunc(("VbglR3SeamlessWaitEvent returned %Rrc (VBoxClient)\n", rc));
128 }
129 LogRelFlowFunc(("returning %Rrc\n", rc));
130 return rc;
131}
132
133/**
134 * Update the set of visible rectangles in the host.
135 */
136void VBoxGuestSeamlessHost::updateRects(std::auto_ptr<std::vector<RTRECT> > pRects)
137{
138 LogRelFlowFunc(("\n"));
139 if (0 == pRects.get()) /* Assertion */
140 {
141 LogRelThisFunc(("ERROR: called with null pointer!\n"));
142 return;
143 }
144 VbglR3SeamlessSendRects(pRects.get()->size(), pRects.get()->empty() ? NULL : &pRects.get()->front());
145 LogRelFlowFunc(("returning\n"));
146}
147
148/**
149 * The actual thread function.
150 *
151 * @returns iprt status code as thread return value
152 * @param pParent the VBoxGuestThread running this thread function
153 */
154int VBoxGuestSeamlessHostThread::threadFunction(VBoxGuestThread *pThread)
155{
156 LogRelFlowFunc(("\n"));
157 if (0 != mHost)
158 {
159 mThread = pThread;
160 while (!mThread->isStopping())
161 {
162 if (RT_FAILURE(mHost->nextEvent()) && !mThread->isStopping())
163 {
164 /* If we are not stopping, sleep for a bit to avoid using up too
165 much CPU while retrying. */
166 mThread->yield();
167 }
168 }
169 }
170 LogRelFlowFunc(("returning VINF_SUCCESS\n"));
171 return VINF_SUCCESS;
172}
173
174/**
175 * Send a signal to the thread function that it should exit
176 */
177void VBoxGuestSeamlessHostThread::stop(void)
178{
179 LogRelFlowFunc(("\n"));
180 if (0 != mHost)
181 {
182 /**
183 * @todo is this reasonable? If the thread is in the event loop then the cancelEvent()
184 * will cause it to exit. If it enters or exits the event loop it will also
185 * notice that we wish it to exit. And if it is somewhere in-between, the
186 * yield() should give it time to get to one of places mentioned above.
187 */
188 for (int i = 0; (i < 5) && mThread->isRunning(); ++i)
189 {
190 mHost->cancelEvent();
191 mThread->yield();
192 }
193 }
194 LogRelFlowFunc(("returning\n"));
195}
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