VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxBFE/MouseImpl.cpp@ 6603

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

The Giant CDDL Dual-License Header Change.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/** @file
2 *
3 * VBox frontends: Basic Frontend (BFE):
4 * Implementation of Mouse class
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#ifdef VBOXBFE_WITHOUT_COM
20# include "COMDefs.h"
21#else
22# include <VBox/com/defs.h>
23#endif
24#include <VBox/pdm.h>
25#include <VBox/cfgm.h>
26#include <VBox/err.h>
27#include <iprt/assert.h>
28#include <VBox/log.h>
29#include <iprt/asm.h>
30#include <VBox/VBoxDev.h>
31#include "MouseImpl.h"
32#include "DisplayImpl.h"
33#include "VMMDevInterface.h"
34
35/**
36 * Mouse driver instance data.
37 */
38typedef struct DRVMAINMOUSE
39{
40 /** Pointer to the associated mouse driver. */
41 Mouse *mpDrv;
42 /** Pointer to the driver instance structure. */
43 PPDMDRVINS pDrvIns;
44 /** Pointer to the mouse port interface of the driver/device above us. */
45 PPDMIMOUSEPORT pUpPort;
46 /** Our mouse connector interface. */
47 PDMIMOUSECONNECTOR Connector;
48} DRVMAINMOUSE, *PDRVMAINMOUSE;
49
50/** Converts PDMIMOUSECONNECTOR pointer to a DRVMAINMOUSE pointer. */
51#define PDMIMOUSECONNECTOR_2_MAINMOUSE(pInterface) ( (PDRVMAINMOUSE) ((uintptr_t)pInterface - RT_OFFSETOF(DRVMAINMOUSE, Connector)) )
52
53// IMouse methods
54/////////////////////////////////////////////////////////////////////////////
55
56int Mouse::setAbsoluteCoordinates(bool fAbsolute)
57{
58 this->fAbsolute = fAbsolute;
59 return S_OK;
60}
61
62int Mouse::setNeedsHostCursor(bool fNeedsHostCursor)
63{
64 this->fNeedsHostCursor = fNeedsHostCursor;
65 return S_OK;
66}
67
68int Mouse::setHostCursor(bool enable)
69{
70 uHostCaps = enable ? 0 : VMMDEV_MOUSEHOSTCANNOTHWPOINTER;
71 gVMMDev->SetMouseCapabilities(uHostCaps);
72 return S_OK;
73}
74
75/**
76 * Send a mouse event.
77 *
78 * @returns COM status code
79 * @param dx X movement
80 * @param dy Y movement
81 * @param dz Z movement
82 * @param buttonState The mouse button state
83 */
84int Mouse::PutMouseEvent(LONG dx, LONG dy, LONG dz, LONG buttonState)
85{
86 uint32_t mouseCaps;
87 gVMMDev->QueryMouseCapabilities(&mouseCaps);
88
89 /*
90 * This method being called implies that the host no
91 * longer wants to use absolute coordinates. If the VMM
92 * device isn't aware of that yet, tell it.
93 */
94 if (mouseCaps & VMMDEV_MOUSEHOSTWANTSABS)
95 {
96 gVMMDev->SetMouseCapabilities(uHostCaps);
97 }
98
99 uint32_t fButtons = 0;
100 if (buttonState & PDMIMOUSEPORT_BUTTON_LEFT)
101 fButtons |= PDMIMOUSEPORT_BUTTON_LEFT;
102 if (buttonState & PDMIMOUSEPORT_BUTTON_RIGHT)
103 fButtons |= PDMIMOUSEPORT_BUTTON_RIGHT;
104 if (buttonState & PDMIMOUSEPORT_BUTTON_MIDDLE)
105 fButtons |= PDMIMOUSEPORT_BUTTON_MIDDLE;
106
107 int vrc = mpDrv->pUpPort->pfnPutEvent(mpDrv->pUpPort, dx, dy, dz, fButtons);
108 if (VBOX_FAILURE (vrc))
109 return E_FAIL;
110
111 return S_OK;
112}
113
114/**
115 * Send an absolute mouse event to the VM. This only works
116 * when the required guest support has been installed.
117 *
118 * @returns COM status code
119 * @param x X position (pixel)
120 * @param y Y position (pixel)
121 * @param dz Z movement
122 * @param buttonState The mouse button state
123 */
124int Mouse::PutMouseEventAbsolute(LONG x, LONG y, LONG dz, LONG buttonState)
125{
126 uint32_t mouseCaps;
127 gVMMDev->QueryMouseCapabilities(&mouseCaps);
128
129 /*
130 * This method being called implies that the host no
131 * longer wants to use absolute coordinates. If the VMM
132 * device isn't aware of that yet, tell it.
133 */
134 if (!(mouseCaps & VMMDEV_MOUSEHOSTWANTSABS))
135 {
136 gVMMDev->SetMouseCapabilities(uHostCaps | VMMDEV_MOUSEHOSTWANTSABS);
137 }
138
139 ULONG displayWidth;
140 ULONG displayHeight;
141 displayHeight = gDisplay->getHeight();
142 displayWidth = gDisplay->getWidth();
143
144 uint32_t mouseXAbs = (x * 0xFFFF) / displayWidth;
145 uint32_t mouseYAbs = (y * 0xFFFF) / displayHeight;
146
147 /*
148 * Send the absolute mouse position to the VMM device
149 */
150 int vrc = gVMMDev->SetAbsoluteMouse(mouseXAbs, mouseYAbs);
151 AssertRC(vrc);
152
153 // check if the guest actually wants absolute mouse positions
154 if (mouseCaps & VMMDEV_MOUSEGUESTWANTSABS)
155 {
156 uint32_t fButtons = 0;
157 if (buttonState & PDMIMOUSEPORT_BUTTON_LEFT)
158 fButtons |= PDMIMOUSEPORT_BUTTON_LEFT;
159 if (buttonState & PDMIMOUSEPORT_BUTTON_RIGHT)
160 fButtons |= PDMIMOUSEPORT_BUTTON_RIGHT;
161 if (buttonState & PDMIMOUSEPORT_BUTTON_MIDDLE)
162 fButtons |= PDMIMOUSEPORT_BUTTON_MIDDLE;
163
164 vrc = mpDrv->pUpPort->pfnPutEvent(mpDrv->pUpPort, 1, 1, dz, fButtons);
165 if (VBOX_FAILURE (vrc))
166 return E_FAIL;
167 }
168
169 return S_OK;
170}
171
172/////////////////////////////////////////////////////////////////////////////
173
174/**
175 * Queries an interface to the driver.
176 *
177 * @returns Pointer to interface.
178 * @returns NULL if the interface was not supported by the driver.
179 * @param pInterface Pointer to this interface structure.
180 * @param enmInterface The requested interface identification.
181 */
182DECLCALLBACK(void *) Mouse::drvQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
183{
184 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
185 PDRVMAINMOUSE pDrv = PDMINS2DATA(pDrvIns, PDRVMAINMOUSE);
186 switch (enmInterface)
187 {
188 case PDMINTERFACE_BASE:
189 return &pDrvIns->IBase;
190 case PDMINTERFACE_MOUSE_CONNECTOR:
191 return &pDrv->Connector;
192 default:
193 return NULL;
194 }
195}
196
197
198/**
199 * Destruct a mouse driver instance.
200 *
201 * @returns VBox status.
202 * @param pDrvIns The driver instance data.
203 */
204DECLCALLBACK(void) Mouse::drvDestruct(PPDMDRVINS pDrvIns)
205{
206 //PDRVMAINMOUSE pData = PDMINS2DATA(pDrvIns, PDRVMAINMOUSE);
207 LogFlow(("Mouse::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
208}
209
210
211/**
212 * Construct a mouse driver instance.
213 *
214 * @returns VBox status.
215 * @param pDrvIns The driver instance data.
216 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
217 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
218 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
219 * iInstance it's expected to be used a bit in this function.
220 */
221DECLCALLBACK(int) Mouse::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
222{
223 PDRVMAINMOUSE pData = PDMINS2DATA(pDrvIns, PDRVMAINMOUSE);
224 LogFlow(("drvMainMouse_Construct: iInstance=%d\n", pDrvIns->iInstance));
225
226 /*
227 * Validate configuration.
228 */
229 if (!CFGMR3AreValuesValid(pCfgHandle, "Object\0"))
230 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
231
232 PPDMIBASE pBaseIgnore;
233 int rc = pDrvIns->pDrvHlp->pfnAttach(pDrvIns, &pBaseIgnore);
234 if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
235 {
236 AssertMsgFailed(("Configuration error: Not possible to attach anything to this driver!\n"));
237 return VERR_PDM_DRVINS_NO_ATTACH;
238 }
239
240 /*
241 * IBase.
242 */
243 pDrvIns->IBase.pfnQueryInterface = Mouse::drvQueryInterface;
244
245 /*
246 * Get the IMousePort interface of the above driver/device.
247 */
248 pData->pUpPort = (PPDMIMOUSEPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_MOUSE_PORT);
249 if (!pData->pUpPort)
250 {
251 AssertMsgFailed(("Configuration error: No mouse port interface above!\n"));
252 return VERR_PDM_MISSING_INTERFACE_ABOVE;
253 }
254
255 /*
256 * Get the Mouse object pointer and update the mpDrv member.
257 */
258 void *pv;
259 rc = CFGMR3QueryPtr(pCfgHandle, "Object", &pv);
260 if (VBOX_FAILURE(rc))
261 {
262 AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Vrc\n", rc));
263 return rc;
264 }
265
266 pData->mpDrv = (Mouse*)pv; /** @todo Check this cast! */
267 pData->mpDrv->mpDrv = pData;
268
269 return VINF_SUCCESS;
270}
271
272
273/**
274 * Main mouse driver registration record.
275 */
276const PDMDRVREG Mouse::DrvReg =
277{
278 /* u32Version */
279 PDM_DRVREG_VERSION,
280 /* szDriverName */
281 "MainMouse",
282 /* pszDescription */
283 "Main mouse driver (Main as in the API).",
284 /* fFlags */
285 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
286 /* fClass. */
287 PDM_DRVREG_CLASS_MOUSE,
288 /* cMaxInstances */
289 ~0,
290 /* cbInstance */
291 sizeof(DRVMAINMOUSE),
292 /* pfnConstruct */
293 Mouse::drvConstruct,
294 /* pfnDestruct */
295 Mouse::drvDestruct,
296 /* pfnIOCtl */
297 NULL,
298 /* pfnPowerOn */
299 NULL,
300 /* pfnReset */
301 NULL,
302 /* pfnSuspend */
303 NULL,
304 /* pfnResume */
305 NULL,
306 /* pfnDetach */
307 NULL
308};
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