VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibSeamless.cpp@ 93115

Last change on this file since 93115 was 93115, checked in by vboxsync, 2 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.4 KB
Line 
1/* $Id: VBoxGuestR3LibSeamless.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Seamless mode.
4 */
5
6/*
7 * Copyright (C) 2007-2022 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/assert.h>
32#include <iprt/errcore.h>
33#include <iprt/string.h>
34
35#include <VBox/log.h>
36
37#include "VBoxGuestR3LibInternal.h"
38
39#ifdef VBOX_VBGLR3_XFREE86
40/* Rather than try to resolve all the header file conflicts, I will just
41 prototype what we need here. */
42extern "C" void* xf86memcpy(void*,const void*,xf86size_t);
43# undef memcpy
44# define memcpy xf86memcpy
45#endif /* VBOX_VBGLR3_XFREE86 */
46
47/**
48 * Tell the host that we support (or no longer support) seamless mode.
49 *
50 * @returns IPRT status value
51 * @param fState whether or not we support seamless mode
52 */
53VBGLR3DECL(int) VbglR3SeamlessSetCap(bool fState)
54{
55 if (fState)
56 return VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_SEAMLESS, 0);
57 return VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_SEAMLESS);
58}
59
60/**
61 * Wait for a seamless mode change event.
62 *
63 * @returns IPRT status value.
64 * @param[out] pMode On success, the seamless mode to switch into (i.e.
65 * disabled, visible region or host window).
66 */
67VBGLR3DECL(int) VbglR3SeamlessWaitEvent(VMMDevSeamlessMode *pMode)
68{
69 AssertPtrReturn(pMode, VERR_INVALID_POINTER);
70
71 /** @todo r=andy The (similar / duplicate) Windows code does similar waiting. Merge / fix this. */
72 uint32_t fEvent = 0;
73 int rc = VbglR3WaitEvent(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 1000 /* ms */, &fEvent);
74 if (RT_SUCCESS(rc))
75 {
76 /* did we get the right event? */
77 if (fEvent & VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST)
78 {
79 VMMDevSeamlessChangeRequest seamlessChangeRequest;
80
81 /* get the seamless change request */
82 vmmdevInitRequest(&seamlessChangeRequest.header, VMMDevReq_GetSeamlessChangeRequest);
83 seamlessChangeRequest.mode = (VMMDevSeamlessMode)-1;
84 seamlessChangeRequest.eventAck = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
85 rc = vbglR3GRPerform(&seamlessChangeRequest.header);
86 if (RT_SUCCESS(rc))
87 {
88 *pMode = seamlessChangeRequest.mode;
89 return VINF_SUCCESS;
90 }
91 }
92 else
93 rc = VERR_TRY_AGAIN;
94 }
95 else if ( rc == VERR_INTERRUPTED
96 || rc == VERR_TIMEOUT /* just in case */)
97 rc = VERR_TRY_AGAIN;
98 return rc;
99}
100
101/**
102 * Request the last seamless mode switch from the host again.
103 *
104 * @returns IPRT status value.
105 * @param[out] pMode On success, the seamless mode that was switched
106 * into (i.e. disabled, visible region or host window).
107 */
108VBGLR3DECL(int) VbglR3SeamlessGetLastEvent(VMMDevSeamlessMode *pMode)
109{
110 VMMDevSeamlessChangeRequest seamlessChangeRequest;
111 int rc;
112
113 AssertPtrReturn(pMode, VERR_INVALID_PARAMETER);
114
115 /* get the seamless change request */
116 vmmdevInitRequest(&seamlessChangeRequest.header, VMMDevReq_GetSeamlessChangeRequest);
117 seamlessChangeRequest.mode = (VMMDevSeamlessMode)-1;
118 seamlessChangeRequest.eventAck = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
119 rc = vbglR3GRPerform(&seamlessChangeRequest.header);
120 if (RT_SUCCESS(rc))
121 {
122 *pMode = seamlessChangeRequest.mode;
123 return VINF_SUCCESS;
124 }
125 return rc;
126}
127
128/**
129 * Inform the host about the visible region
130 *
131 * @returns IPRT status code
132 * @param cRects number of rectangles in the list of visible rectangles
133 * @param pRects list of visible rectangles on the guest display
134 *
135 * @todo A scatter-gather version of vbglR3GRPerform would be nice, so that we don't have
136 * to copy our rectangle and header data into a single structure and perform an
137 * additional allocation.
138 * @todo Would that really gain us much, given that the rectangles may not
139 * be grouped at all, or in the format we need? Keeping the memory
140 * for our "single structure" around (re-alloc-ing it if necessary)
141 * sounds like a simpler optimisation if we need it.
142 */
143VBGLR3DECL(int) VbglR3SeamlessSendRects(uint32_t cRects, PRTRECT pRects)
144{
145 VMMDevVideoSetVisibleRegion *pReq;
146 int rc;
147
148 AssertReturn(pRects || cRects == 0, VERR_INVALID_PARAMETER);
149 AssertMsgReturn(cRects <= _1M, ("%u\n", cRects), VERR_OUT_OF_RANGE);
150
151 rc = vbglR3GRAlloc((VMMDevRequestHeader **)&pReq,
152 sizeof(VMMDevVideoSetVisibleRegion)
153 + cRects * sizeof(RTRECT)
154 - sizeof(RTRECT),
155 VMMDevReq_VideoSetVisibleRegion);
156 if (RT_SUCCESS(rc))
157 {
158 pReq->cRect = cRects;
159 if (cRects)
160 memcpy(&pReq->Rect, pRects, cRects * sizeof(RTRECT));
161 /* This will fail harmlessly for cRect == 0 and older host code */
162 rc = vbglR3GRPerform(&pReq->header);
163 LogFunc(("Visible region request returned %Rrc, internal %Rrc.\n",
164 rc, pReq->header.rc));
165 if (RT_SUCCESS(rc))
166 rc = pReq->header.rc;
167 vbglR3GRFree(&pReq->header);
168 }
169 LogFunc(("Sending %u rectangles to the host: %Rrc\n", cRects, rc));
170 return rc;
171}
172
173VBGLR3DECL(int) VbglR3SeamlessSendMonitorPositions(uint32_t cPositions, PRTPOINT pPositions)
174{
175 if (!pPositions || cPositions <= 0)
176 return VERR_INVALID_PARAMETER;
177
178 VMMDevVideoUpdateMonitorPositions *pReq;
179 int rc;
180
181 rc = vbglR3GRAlloc((VMMDevRequestHeader **)&pReq,
182 sizeof(VMMDevVideoUpdateMonitorPositions)
183 + (cPositions - 1) * sizeof(RTPOINT),
184 VMMDevReq_VideoUpdateMonitorPositions);
185 if (RT_SUCCESS(rc))
186 {
187 pReq->cPositions = cPositions;
188 if (cPositions)
189 memcpy(&pReq->aPositions, pPositions, cPositions * sizeof(RTPOINT));
190 rc = vbglR3GRPerform(&pReq->header);
191 LogFunc(("Monitor position update request returned %Rrc, internal %Rrc.\n",
192 rc, pReq->header.rc));
193 if (RT_SUCCESS(rc))
194 rc = pReq->header.rc;
195 vbglR3GRFree(&pReq->header);
196 }
197 LogFunc(("Sending monitor positions (%u of them) to the host: %Rrc\n", cPositions, rc));
198 return rc;
199}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use