VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp@ 3584

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

Fixed typo and added UpdateGuestCapabilities support to VBoxBFE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/** @file
2 *
3 * VBox frontends: Basic Frontend (BFE):
4 * Implementation of VMMDev: driver interface to VMM device
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 as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23#define LOG_GROUP LOG_GROUP_MAIN
24
25#ifdef VBOXBFE_WITHOUT_COM
26# include "COMDefs.h"
27#else
28# include <VBox/com/defs.h>
29#endif
30#include <VBox/pdm.h>
31#include <VBox/VBoxDev.h>
32#include <VBox/VBoxGuest.h>
33#include <VBox/cfgm.h>
34#include <VBox/err.h>
35#include <iprt/assert.h>
36#include <VBox/log.h>
37#include <iprt/asm.h>
38
39#include "VBoxBFE.h"
40#include "VMMDevInterface.h"
41#include "MouseImpl.h"
42#include "DisplayImpl.h"
43#include "ConsoleImpl.h"
44
45#ifdef __L4__
46#include <l4/util/util.h> /* for l4_sleep */
47#endif
48/**
49 * VMMDev driver instance data.
50 */
51typedef struct DRVMAINVMMDEV
52{
53 /** Pointer to the VMMDev object. */
54 VMMDev *pVMMDev;
55 /** Pointer to the driver instance structure. */
56 PPDMDRVINS pDrvIns;
57 /** Pointer to the VMMDev port interface of the driver/device above us. */
58 PPDMIVMMDEVPORT pUpPort;
59 /** Our VMM device connector interface. */
60 PDMIVMMDEVCONNECTOR Connector;
61} DRVMAINVMMDEV, *PDRVMAINVMMDEV;
62
63/** Converts PDMIVMMDEVCONNECTOR pointer to a DRVMAINVMMDEV pointer. */
64#define PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface) ( (PDRVMAINVMMDEV) ((uintptr_t)pInterface - RT_OFFSETOF(DRVMAINVMMDEV, Connector)) )
65
66
67PPDMIVMMDEVPORT VMMDev::getVMMDevPort()
68{
69 Assert(mpDrv);
70 return mpDrv->pUpPort;
71}
72
73int VMMDev::SetMouseCapabilities(uint32_t mouseCaps)
74{
75 return mpDrv->pUpPort->pfnSetMouseCapabilities(mpDrv->pUpPort, mouseCaps);
76}
77
78
79int VMMDev::SetAbsoluteMouse(uint32_t mouseXAbs, uint32_t mouseYAbs)
80{
81 return mpDrv->pUpPort->pfnSetAbsoluteMouse(mpDrv->pUpPort, mouseXAbs, mouseYAbs);
82}
83
84void VMMDev::QueryMouseCapabilities(uint32_t *pMouseCaps)
85{
86
87 Assert(mpDrv);
88 mpDrv->pUpPort->pfnQueryMouseCapabilities(mpDrv->pUpPort, pMouseCaps);
89}
90
91
92/**
93 * Report guest OS version.
94 * Called whenever the Additions issue a guest version report request.
95 *
96 * @param pInterface Pointer to this interface.
97 * @param guestInfo Pointer to guest information structure
98 * @thread The emulation thread.
99 */
100DECLCALLBACK(void) VMMDev::UpdateGuestVersion(PPDMIVMMDEVCONNECTOR pInterface, VBoxGuestInfo *guestInfo)
101{
102 return;
103}
104
105/**
106 * Update the guest additions capabilities.
107 * This is called when the guest additions capabilities change. The new capabilities
108 * are given and the connector should update its internal state.
109 *
110 * @param pInterface Pointer to this interface.
111 * @param newCapabilities New capabilities.
112 * @thread The emulation thread.
113 */
114DECLCALLBACK(void) VMMDev::UpdateGuestCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities)
115{
116 return;
117}
118
119/**
120 * Update the mouse capabilities.
121 * This is called when the mouse capabilities change. The new capabilities
122 * are given and the connector should update its internal state.
123 *
124 * @param pInterface Pointer to this interface.
125 * @param newCapabilities New capabilities.
126 * @thread The emulation thread.
127 */
128DECLCALLBACK(void) VMMDev::UpdateMouseCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities)
129{
130 /*
131 * Tell the console interface about the event so that it can notify its consumers.
132 */
133
134 if (gMouse)
135 {
136 gMouse->setAbsoluteCoordinates(!!(newCapabilities & VMMDEV_MOUSEGUESTWANTSABS));
137 gMouse->setNeedsHostCursor(!!(newCapabilities & VMMDEV_MOUSEGUESTNEEDSHOSTCUR));
138 }
139 if (gConsole)
140 {
141 gConsole->resetCursor();
142 }
143}
144
145
146/**
147 * Update the pointer shape or visibility.
148 *
149 * This is called when the mouse pointer shape changes or pointer is hidden/displaying.
150 * The new shape is passed as a caller allocated buffer that will be freed after returning.
151 *
152 * @param pInterface Pointer to this interface.
153 * @param fVisible Whether the pointer is visible or not.
154 * @param fAlpha Alpha channel information is present.
155 * @param xHot Horizontal coordinate of the pointer hot spot.
156 * @param yHot Vertical coordinate of the pointer hot spot.
157 * @param width Pointer width in pixels.
158 * @param height Pointer height in pixels.
159 * @param pShape The shape buffer. If NULL, then only pointer visibility is being changed.
160 * @thread The emulation thread.
161 */
162DECLCALLBACK(void) VMMDev::UpdatePointerShape(PPDMIVMMDEVCONNECTOR pInterface, bool fVisible, bool fAlpha,
163 uint32_t xHot, uint32_t yHot,
164 uint32_t width, uint32_t height,
165 void *pShape)
166{
167 if (gConsole)
168 gConsole->onMousePointerShapeChange(fVisible, fAlpha, xHot,
169 yHot, width, height, pShape);
170}
171
172DECLCALLBACK(int) iface_VideoAccelEnable(PPDMIVMMDEVCONNECTOR pInterface, bool fEnable, VBVAMEMORY *pVbvaMemory)
173{
174 LogFlow(("VMMDev::VideoAccelEnable: %d, %p\n", fEnable, pVbvaMemory));
175 if (gDisplay)
176 gDisplay->VideoAccelEnable (fEnable, pVbvaMemory);
177 return VINF_SUCCESS;
178}
179
180DECLCALLBACK(void) iface_VideoAccelFlush(PPDMIVMMDEVCONNECTOR pInterface)
181{
182 if (gDisplay)
183 gDisplay->VideoAccelFlush ();
184}
185
186DECLCALLBACK(int) iface_SetVisibleRegion(PPDMIVMMDEVCONNECTOR pInterface, uint32_t cRect, PRTRECT pRect)
187{
188 /* not implemented */
189 return VINF_SUCCESS;
190}
191
192DECLCALLBACK(int) iface_QueryVisibleRegion(PPDMIVMMDEVCONNECTOR pInterface, uint32_t *pcRect, PRTRECT pRect)
193{
194 /* not implemented */
195 return VINF_SUCCESS;
196}
197
198DECLCALLBACK(int) VMMDev::VideoModeSupported(PPDMIVMMDEVCONNECTOR pInterface, uint32_t width, uint32_t height,
199 uint32_t bpp, bool *fSupported)
200{
201 PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
202 (void)pDrv;
203
204 if (!fSupported)
205 return VERR_INVALID_PARAMETER;
206 *fSupported = true;
207 return VINF_SUCCESS;
208}
209
210DECLCALLBACK(int) VMMDev::GetHeightReduction(PPDMIVMMDEVCONNECTOR pInterface, uint32_t *heightReduction)
211{
212 PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
213 (void)pDrv;
214
215 if (!heightReduction)
216 return VERR_INVALID_PARAMETER;
217 /* XXX hard-coded */
218 *heightReduction = 18;
219 return VINF_SUCCESS;
220}
221
222/**
223 * Queries an interface to the driver.
224 *
225 * @returns Pointer to interface.
226 * @returns NULL if the interface was not supported by the driver.
227 * @param pInterface Pointer to this interface structure.
228 * @param enmInterface The requested interface identification.
229 */
230DECLCALLBACK(void *) VMMDev::drvQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
231{
232 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
233 PDRVMAINVMMDEV pDrv = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV);
234 switch (enmInterface)
235 {
236 case PDMINTERFACE_BASE:
237 return &pDrvIns->IBase;
238 case PDMINTERFACE_VMMDEV_CONNECTOR:
239 return &pDrv->Connector;
240 default:
241 return NULL;
242 }
243}
244
245
246/**
247 * Destruct a VMMDev driver instance.
248 *
249 * @returns VBox status.
250 * @param pDrvIns The driver instance data.
251 */
252DECLCALLBACK(void) VMMDev::drvDestruct(PPDMDRVINS pDrvIns)
253{
254 /*PDRVMAINVMMDEV pData = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV); - unused variables makes gcc bitch. */
255}
256
257
258/**
259 * Construct a VMMDev driver instance.
260 *
261 * @returns VBox status.
262 * @param pDrvIns The driver instance data.
263 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
264 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
265 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
266 * iInstance it's expected to be used a bit in this function.
267 */
268DECLCALLBACK(int) VMMDev::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
269{
270 PDRVMAINVMMDEV pData = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV);
271 LogFlow(("Keyboard::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
272
273 /*
274 * Validate configuration.
275 */
276 if (!CFGMR3AreValuesValid(pCfgHandle, "Object\0"))
277 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
278
279 PPDMIBASE pBaseIgnore;
280 int rc = pDrvIns->pDrvHlp->pfnAttach(pDrvIns, &pBaseIgnore);
281 if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
282 {
283 AssertMsgFailed(("Configuration error: Not possible to attach anything to this driver!\n"));
284 return VERR_PDM_DRVINS_NO_ATTACH;
285 }
286
287 /*
288 * IBase.
289 */
290 pDrvIns->IBase.pfnQueryInterface = VMMDev::drvQueryInterface;
291
292 pData->Connector.pfnUpdateGuestVersion = VMMDev::UpdateGuestVersion;
293 pData->Connector.pfnUpdateGuestCapabilities = VMMDev::UpdateGuestCapabilities;
294 pData->Connector.pfnUpdateMouseCapabilities = VMMDev::UpdateMouseCapabilities;
295 pData->Connector.pfnUpdatePointerShape = VMMDev::UpdatePointerShape;
296 pData->Connector.pfnVideoAccelEnable = iface_VideoAccelEnable;
297 pData->Connector.pfnVideoAccelFlush = iface_VideoAccelFlush;
298 pData->Connector.pfnVideoModeSupported = VMMDev::VideoModeSupported;
299 pData->Connector.pfnGetHeightReduction = VMMDev::GetHeightReduction;
300 pData->Connector.pfnSetVisibleRegion = iface_SetVisibleRegion;
301 pData->Connector.pfnQueryVisibleRegion = iface_QueryVisibleRegion;
302
303 /*
304 * Get the IVMMDevPort interface of the above driver/device.
305 */
306 pData->pUpPort = (PPDMIVMMDEVPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_VMMDEV_PORT);
307 if (!pData->pUpPort)
308 {
309 AssertMsgFailed(("Configuration error: No VMMDev port interface above!\n"));
310 return VERR_PDM_MISSING_INTERFACE_ABOVE;
311 }
312
313 /*
314 * Get the VMMDev object pointer and update the mpDrv member.
315 */
316 void *pv;
317 rc = CFGMR3QueryPtr(pCfgHandle, "Object", &pv);
318 if (VBOX_FAILURE(rc))
319 {
320 AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Vrc\n", rc));
321 return rc;
322 }
323
324 pData->pVMMDev = (VMMDev*)pv; /** @todo Check this cast! */
325 pData->pVMMDev->mpDrv = pData;
326 return VINF_SUCCESS;
327}
328
329
330/**
331 * VMMDevice driver registration record.
332 */
333const PDMDRVREG VMMDev::DrvReg =
334{
335 /* u32Version */
336 PDM_DRVREG_VERSION,
337 /* szDriverName */
338 "MainVMMDev",
339 /* pszDescription */
340 "Main VMMDev driver (Main as in the API).",
341 /* fFlags */
342 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
343 /* fClass. */
344 PDM_DRVREG_CLASS_VMMDEV,
345 /* cMaxInstances */
346 ~0,
347 /* cbInstance */
348 sizeof(DRVMAINVMMDEV),
349 /* pfnConstruct */
350 VMMDev::drvConstruct,
351 /* pfnDestruct */
352 VMMDev::drvDestruct,
353 /* pfnIOCtl */
354 NULL,
355 /* pfnPowerOn */
356 NULL,
357 /* pfnReset */
358 NULL,
359 /* pfnSuspend */
360 NULL,
361 /* pfnResume */
362 NULL,
363 /* pfnDetach */
364 NULL
365};
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