VirtualBox

source: vbox/trunk/src/VBox/Main/MouseImpl.cpp@ 27200

Last change on this file since 27200 was 27189, checked in by vboxsync, 15 years ago

Main/MouseImpl.cpp: updated a todo

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.7 KB
Line 
1/* $Id: MouseImpl.cpp 27189 2010-03-08 23:07:52Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#include "MouseImpl.h"
23#include "DisplayImpl.h"
24#include "VMMDev.h"
25
26#include "AutoCaller.h"
27#include "Logging.h"
28
29#include <VBox/pdmdrv.h>
30#include <iprt/asm.h>
31#include <VBox/VMMDev.h>
32
33/** @name Mouse device capabilities bitfield
34 * @{ */
35enum
36{
37 /** The mouse device can do relative reporting */
38 MOUSE_DEVCAP_RELATIVE = 1,
39 /** The mouse device can do absolute reporting */
40 MOUSE_DEVCAP_ABSOLUTE = 2
41};
42/** @} */
43
44/**
45 * Mouse driver instance data.
46 */
47struct DRVMAINMOUSE
48{
49 /** Pointer to the mouse object. */
50 Mouse *pMouse;
51 /** Pointer to the driver instance structure. */
52 PPDMDRVINS pDrvIns;
53 /** Pointer to the mouse port interface of the driver/device above us. */
54 PPDMIMOUSEPORT pUpPort;
55 /** Our mouse connector interface. */
56 PDMIMOUSECONNECTOR IConnector;
57 /** The capabilities of this device. */
58 uint32_t u32DevCaps;
59};
60
61
62// constructor / destructor
63/////////////////////////////////////////////////////////////////////////////
64
65DEFINE_EMPTY_CTOR_DTOR (Mouse)
66
67HRESULT Mouse::FinalConstruct()
68{
69 RT_ZERO(mpDrv);
70 fVMMDevCanAbs = false;
71 fVMMDevNeedsHostCursor = false;
72 mLastAbsX = 0x8000;
73 mLastAbsY = 0x8000;
74 mLastButtons = 0;
75 return S_OK;
76}
77
78void Mouse::FinalRelease()
79{
80 uninit();
81}
82
83// public methods only for internal purposes
84/////////////////////////////////////////////////////////////////////////////
85
86/**
87 * Initializes the mouse object.
88 *
89 * @returns COM result indicator
90 * @param parent handle of our parent object
91 */
92HRESULT Mouse::init (Console *parent)
93{
94 LogFlowThisFunc(("\n"));
95
96 ComAssertRet(parent, E_INVALIDARG);
97
98 /* Enclose the state transition NotReady->InInit->Ready */
99 AutoInitSpan autoInitSpan(this);
100 AssertReturn(autoInitSpan.isOk(), E_FAIL);
101
102 unconst(mParent) = parent;
103
104#ifdef RT_OS_L4
105 /* L4 console has no own mouse cursor */
106 uHostCaps = VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER;
107#else
108 uHostCaps = 0;
109#endif
110
111 /* Confirm a successful initialization */
112 autoInitSpan.setSucceeded();
113
114 return S_OK;
115}
116
117/**
118 * Uninitializes the instance and sets the ready flag to FALSE.
119 * Called either from FinalRelease() or by the parent when it gets destroyed.
120 */
121void Mouse::uninit()
122{
123 LogFlowThisFunc(("\n"));
124
125 /* Enclose the state transition Ready->InUninit->NotReady */
126 AutoUninitSpan autoUninitSpan(this);
127 if (autoUninitSpan.uninitDone())
128 return;
129
130 for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
131 {
132 if (mpDrv[i])
133 mpDrv[i]->pMouse = NULL;
134 mpDrv[i] = NULL;
135 }
136
137#ifdef VBOXBFE_WITHOUT_COM
138 mParent = NULL;
139#else
140 unconst(mParent).setNull();
141#endif
142}
143
144
145// IMouse properties
146/////////////////////////////////////////////////////////////////////////////
147
148HRESULT Mouse::getVMMDevMouseCaps(uint32_t *pfCaps)
149{
150 AssertPtrReturn(pfCaps, E_POINTER);
151 VMMDev *pVMMDev = mParent->getVMMDev();
152 ComAssertRet(pVMMDev, E_FAIL);
153 PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
154 ComAssertRet(pVMMDevPort, E_FAIL);
155
156 int rc = pVMMDevPort->pfnQueryMouseCapabilities(pVMMDevPort, pfCaps);
157 return RT_SUCCESS(rc) ? S_OK : E_FAIL;
158}
159
160HRESULT Mouse::setVMMDevMouseCaps(uint32_t fCaps)
161{
162 VMMDev *pVMMDev = mParent->getVMMDev();
163 ComAssertRet(pVMMDev, E_FAIL);
164 PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
165 ComAssertRet(pVMMDevPort, E_FAIL);
166
167 int rc = pVMMDevPort->pfnSetMouseCapabilities(pVMMDevPort, fCaps);
168 return RT_SUCCESS(rc) ? S_OK : E_FAIL;
169}
170
171/**
172 * Returns whether the current setup can accept absolute mouse
173 * events.
174 *
175 * @returns COM status code
176 * @param absoluteSupported address of result variable
177 */
178STDMETHODIMP Mouse::COMGETTER(AbsoluteSupported) (BOOL *absoluteSupported)
179{
180 if (!absoluteSupported)
181 return E_POINTER;
182
183 AutoCaller autoCaller(this);
184 if (FAILED(autoCaller.rc())) return autoCaller.rc();
185
186 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
187 bool fAbs = false;
188
189 if (fVMMDevCanAbs)
190 fAbs = TRUE;
191
192 for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
193 if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE))
194 fAbs = TRUE;
195
196 *absoluteSupported = fAbs;
197 return S_OK;
198}
199
200/**
201 * Returns whether the current setup can accept relative mouse
202 * events.
203 *
204 * @returns COM status code
205 * @param relativeSupported address of result variable
206 */
207STDMETHODIMP Mouse::COMGETTER(RelativeSupported) (BOOL *relativeSupported)
208{
209 if (!relativeSupported)
210 return E_POINTER;
211
212 AutoCaller autoCaller(this);
213 if (FAILED(autoCaller.rc())) return autoCaller.rc();
214
215 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
216 bool fRel = false;
217
218 for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
219 if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE))
220 fRel = TRUE;
221
222 *relativeSupported = fRel;
223 return S_OK;
224}
225
226/**
227 * Returns whether the guest can currently draw the mouse cursor itself.
228 *
229 * @returns COM status code
230 * @param pfNeedsHostCursor address of result variable
231 */
232STDMETHODIMP Mouse::COMGETTER(NeedsHostCursor) (BOOL *pfNeedsHostCursor)
233{
234 if (!pfNeedsHostCursor)
235 return E_POINTER;
236
237 AutoCaller autoCaller(this);
238 if (FAILED(autoCaller.rc())) return autoCaller.rc();
239
240 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
241
242 *pfNeedsHostCursor = fVMMDevNeedsHostCursor;
243 return S_OK;
244}
245
246// IMouse methods
247/////////////////////////////////////////////////////////////////////////////
248
249static uint32_t mouseButtonsToPDM(LONG buttonState)
250{
251 uint32_t fButtons = 0;
252 if (buttonState & MouseButtonState_LeftButton)
253 fButtons |= PDMIMOUSEPORT_BUTTON_LEFT;
254 if (buttonState & MouseButtonState_RightButton)
255 fButtons |= PDMIMOUSEPORT_BUTTON_RIGHT;
256 if (buttonState & MouseButtonState_MiddleButton)
257 fButtons |= PDMIMOUSEPORT_BUTTON_MIDDLE;
258 if (buttonState & MouseButtonState_XButton1)
259 fButtons |= PDMIMOUSEPORT_BUTTON_X1;
260 if (buttonState & MouseButtonState_XButton2)
261 fButtons |= PDMIMOUSEPORT_BUTTON_X2;
262 return fButtons;
263}
264
265
266/**
267 * Send a relative event to the mouse device.
268 *
269 * @returns COM status code
270 */
271HRESULT Mouse::reportRelEventToMouseDev(int32_t dx, int32_t dy, int32_t dz,
272 int32_t dw, uint32_t fButtons)
273{
274 if (dx || dy || dz || dw || fButtons != mLastButtons)
275 {
276 PPDMIMOUSEPORT pUpPort = NULL;
277 for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i)
278 {
279 if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE))
280 pUpPort = mpDrv[i]->pUpPort;
281 }
282 if (!pUpPort)
283 return S_OK;
284
285 int vrc = pUpPort->pfnPutEvent(pUpPort, dx, dy, dz, dw, fButtons);
286
287 if (RT_FAILURE(vrc))
288 return setError(VBOX_E_IPRT_ERROR,
289 tr("Could not send the mouse event to the virtual mouse (%Rrc)"),
290 vrc);
291 }
292 return S_OK;
293}
294
295
296/**
297 * Send an absolute position event to the mouse device.
298 *
299 * @returns COM status code
300 */
301HRESULT Mouse::reportAbsEventToMouseDev(uint32_t mouseXAbs, uint32_t mouseYAbs,
302 int32_t dz, int32_t dw, uint32_t fButtons)
303{
304 if ( mouseXAbs != mLastAbsX || mouseYAbs != mLastAbsY
305 || dz || dw || fButtons != mLastButtons)
306 {
307 PPDMIMOUSEPORT pUpPort = NULL;
308 for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i)
309 {
310 if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE))
311 pUpPort = mpDrv[i]->pUpPort;
312 }
313 if (!pUpPort)
314 return S_OK;
315
316 int vrc = pUpPort->pfnPutEventAbs(pUpPort, mouseXAbs, mouseYAbs, dz,
317 dw, fButtons);
318 if (RT_FAILURE(vrc))
319 return setError(VBOX_E_IPRT_ERROR,
320 tr("Could not send the mouse event to the virtual mouse (%Rrc)"),
321 vrc);
322 }
323 return S_OK;
324}
325
326
327/**
328 * Send an absolute position event to the VMM device.
329 *
330 * @returns COM status code
331 */
332HRESULT Mouse::reportAbsEventToVMMDev(uint32_t mouseXAbs, uint32_t mouseYAbs)
333{
334 VMMDev *pVMMDev = mParent->getVMMDev();
335 ComAssertRet(pVMMDev, E_FAIL);
336 PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
337 ComAssertRet(pVMMDevPort, E_FAIL);
338
339 if (mouseXAbs != mLastAbsX || mouseYAbs != mLastAbsY)
340 {
341 int vrc = pVMMDevPort->pfnSetAbsoluteMouse(pVMMDevPort,
342 mouseXAbs, mouseYAbs);
343 if (RT_FAILURE(vrc))
344 return setError(VBOX_E_IPRT_ERROR,
345 tr("Could not send the mouse event to the virtual mouse (%Rrc)"),
346 vrc);
347 }
348 return S_OK;
349}
350
351/**
352 * Send a mouse event.
353 *
354 * @returns COM status code
355 * @param dx X movement
356 * @param dy Y movement
357 * @param dz Z movement
358 * @param buttonState The mouse button state
359 */
360STDMETHODIMP Mouse::PutMouseEvent(LONG dx, LONG dy, LONG dz, LONG dw, LONG buttonState)
361{
362 HRESULT rc = S_OK;
363
364 AutoCaller autoCaller(this);
365 if (FAILED(autoCaller.rc())) return autoCaller.rc();
366
367 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
368
369 LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d\n", __PRETTY_FUNCTION__,
370 dx, dy, dz, dw));
371 /*
372 * This method being called implies that the host no
373 * longer wants to use absolute coordinates. If the VMM
374 * device isn't aware of that yet, tell it.
375 */
376 if (uHostCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE)
377 {
378 uHostCaps &= ~VMMDEV_MOUSE_HOST_CAN_ABSOLUTE;
379 setVMMDevMouseCaps(uHostCaps);
380 }
381
382 uint32_t fButtons = mouseButtonsToPDM(buttonState);
383 rc = reportRelEventToMouseDev(dx, dy, dz, dw, fButtons);
384 if (SUCCEEDED(rc))
385 mLastButtons = fButtons;
386
387 return rc;
388}
389
390/**
391 * Convert an X value in screen co-ordinates to a value from 0 to 0xffff
392 *
393 * @returns COM status value
394 */
395HRESULT Mouse::convertDisplayWidth(LONG x, uint32_t *pcX)
396{
397 AssertPtrReturn(pcX, E_POINTER);
398 Display *pDisplay = mParent->getDisplay();
399 ComAssertRet(pDisplay, E_FAIL);
400
401 ULONG displayWidth;
402 HRESULT rc = pDisplay->COMGETTER(Width)(&displayWidth);
403 if (FAILED(rc)) return rc;
404
405 *pcX = displayWidth ? (x * 0xFFFF) / displayWidth: 0;
406 return S_OK;
407}
408
409/**
410 * Convert a Y value in screen co-ordinates to a value from 0 to 0xffff
411 *
412 * @returns COM status value
413 */
414HRESULT Mouse::convertDisplayHeight(LONG y, uint32_t *pcY)
415{
416 AssertPtrReturn(pcY, E_POINTER);
417 Display *pDisplay = mParent->getDisplay();
418 ComAssertRet(pDisplay, E_FAIL);
419
420 ULONG displayHeight;
421 HRESULT rc = pDisplay->COMGETTER(Height)(&displayHeight);
422 if (FAILED(rc)) return rc;
423
424 *pcY = displayHeight ? (y * 0xFFFF) / displayHeight: 0;
425 return S_OK;
426}
427
428
429/**
430 * Send an absolute mouse event to the VM. This only works
431 * when the required guest support has been installed.
432 *
433 * @returns COM status code
434 * @param x X position (pixel)
435 * @param y Y position (pixel)
436 * @param dz Z movement
437 * @param buttonState The mouse button state
438 */
439STDMETHODIMP Mouse::PutMouseEventAbsolute(LONG x, LONG y, LONG dz, LONG dw,
440 LONG buttonState)
441{
442 AutoCaller autoCaller(this);
443 if (FAILED(autoCaller.rc())) return autoCaller.rc();
444
445 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
446
447 LogRel3(("%s: x=%d, y=%d, dz=%d, dw=%d, buttonState=0x%x\n",
448 __PRETTY_FUNCTION__, x, y, dz, dw, buttonState));
449
450 uint32_t mouseXAbs;
451 HRESULT rc = convertDisplayWidth(x, &mouseXAbs);
452 if (FAILED(rc)) return rc;
453
454 /**
455 * @todo multi-monitor Windows guests expect this to be unbounded.
456 * Understand the issues involved and fix for the rest.
457 */
458 /* if (mouseXAbs > 0xffff)
459 mouseXAbs = mLastAbsX; */
460
461 uint32_t mouseYAbs;
462 rc = convertDisplayHeight(y, &mouseYAbs);
463 if (FAILED(rc)) return rc;
464 /* if (mouseYAbs > 0xffff)
465 mouseYAbs = mLastAbsY; */
466
467 uint32_t fButtons = mouseButtonsToPDM(buttonState);
468
469 uint32_t mouseCaps;
470 rc = getVMMDevMouseCaps(&mouseCaps);
471 if (FAILED(rc)) return rc;
472
473 /*
474 * This method being called implies that the host wants
475 * to use absolute coordinates. If the VMM device isn't
476 * aware of that yet, tell it.
477 */
478 if (!(mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE))
479 {
480 uHostCaps |= VMMDEV_MOUSE_HOST_CAN_ABSOLUTE;
481 setVMMDevMouseCaps(uHostCaps);
482 }
483
484 if (fVMMDevCanAbs)
485 {
486 /*
487 * Send the absolute mouse position to the VMM device.
488 */
489 rc = reportAbsEventToVMMDev(mouseXAbs, mouseYAbs);
490 /* We may need to send an additional event for button information or
491 * to wake up older guests to the changed absolute co-ordinates. If
492 * the event is a pure wake up one, we make sure it contains some
493 * (possibly phony) event data to make sure it isn't just discarded
494 * on the way. */
495 bool fNeedsJiggle = !(mouseCaps & VMMDEV_MOUSE_GUEST_USES_VMMDEV);
496 if (fNeedsJiggle || fButtons != mLastButtons || dz || dw)
497 {
498 rc = reportRelEventToMouseDev(fNeedsJiggle ? 1 : 0, 0, dz, dw,
499 fButtons);
500 }
501 }
502 else
503 rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons);
504
505 if (FAILED(rc)) return rc;
506
507 mLastAbsX = mouseXAbs;
508 mLastAbsY = mouseYAbs;
509
510 mLastButtons = fButtons;
511 return rc;
512}
513
514// private methods
515/////////////////////////////////////////////////////////////////////////////
516
517
518void Mouse::sendMouseCapsNotifications(void)
519{
520 bool fAbsDev = false;
521 bool fRelDev = false;
522 uint32_t u32MouseCaps;
523 for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
524 if (mpDrv[i])
525 {
526 if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE)
527 fAbsDev = true;
528 if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE)
529 fRelDev = true;
530 }
531 if (SUCCEEDED(getVMMDevMouseCaps(&u32MouseCaps)))
532 fVMMDevCanAbs = (u32MouseCaps & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
533 && fRelDev;
534 else
535 fVMMDevCanAbs = false;
536 mParent->onMouseCapabilityChange(fAbsDev || fVMMDevCanAbs, fRelDev,
537 fVMMDevNeedsHostCursor);
538 /** @todo if this gets called during device initialisation we get an
539 * error due to VMMDev not being initialised yet. */
540 if (fAbsDev && !(uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
541 uHostCaps |= VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
542 if (!fAbsDev && (uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
543 uHostCaps &= ~VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
544 setVMMDevMouseCaps(uHostCaps);
545}
546
547
548/**
549 * @interface_method_impl{PDMIMOUSECONNECTOR,pfnReportModes}
550 */
551DECLCALLBACK(void) Mouse::mouseReportModes(PPDMIMOUSECONNECTOR pInterface, bool fRel, bool fAbs)
552{
553 PDRVMAINMOUSE pDrv = RT_FROM_MEMBER(pInterface, DRVMAINMOUSE, IConnector);
554 if (fRel)
555 pDrv->u32DevCaps |= MOUSE_DEVCAP_RELATIVE;
556 else
557 pDrv->u32DevCaps &= ~MOUSE_DEVCAP_RELATIVE;
558 if (fAbs)
559 pDrv->u32DevCaps |= MOUSE_DEVCAP_ABSOLUTE;
560 else
561 pDrv->u32DevCaps &= ~MOUSE_DEVCAP_ABSOLUTE;
562
563 pDrv->pMouse->sendMouseCapsNotifications();
564}
565
566
567/**
568 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
569 */
570DECLCALLBACK(void *) Mouse::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)
571{
572 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
573 PDRVMAINMOUSE pDrv = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
574
575 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
576 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUSECONNECTOR, &pDrv->IConnector);
577 return NULL;
578}
579
580
581/**
582 * Destruct a mouse driver instance.
583 *
584 * @returns VBox status.
585 * @param pDrvIns The driver instance data.
586 */
587DECLCALLBACK(void) Mouse::drvDestruct(PPDMDRVINS pDrvIns)
588{
589 PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
590 LogFlow(("Mouse::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
591 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
592
593 if (pData->pMouse)
594 {
595 AutoWriteLock mouseLock(pData->pMouse COMMA_LOCKVAL_SRC_POS);
596 RT_ZERO(pData->pMouse->mpDrv);
597 }
598}
599
600
601/**
602 * Construct a mouse driver instance.
603 *
604 * @copydoc FNPDMDRVCONSTRUCT
605 */
606DECLCALLBACK(int) Mouse::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
607{
608 PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
609 LogFlow(("drvMainMouse_Construct: iInstance=%d\n", pDrvIns->iInstance));
610 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
611
612 /*
613 * Validate configuration.
614 */
615 if (!CFGMR3AreValuesValid(pCfg, "Object\0"))
616 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
617 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
618 ("Configuration error: Not possible to attach anything to this driver!\n"),
619 VERR_PDM_DRVINS_NO_ATTACH);
620
621 /*
622 * IBase.
623 */
624 pDrvIns->IBase.pfnQueryInterface = Mouse::drvQueryInterface;
625
626 pData->IConnector.pfnReportModes = Mouse::mouseReportModes;
627
628 /*
629 * Get the IMousePort interface of the above driver/device.
630 */
631 pData->pUpPort = (PPDMIMOUSEPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMIMOUSEPORT_IID);
632 if (!pData->pUpPort)
633 {
634 AssertMsgFailed(("Configuration error: No mouse port interface above!\n"));
635 return VERR_PDM_MISSING_INTERFACE_ABOVE;
636 }
637
638 /*
639 * Get the Mouse object pointer and update the mpDrv member.
640 */
641 void *pv;
642 int rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
643 if (RT_FAILURE(rc))
644 {
645 AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
646 return rc;
647 }
648 pData->pMouse = (Mouse *)pv; /** @todo Check this cast! */
649 unsigned cDev;
650 for (cDev = 0; cDev < MOUSE_MAX_DEVICES; ++cDev)
651 if (!pData->pMouse->mpDrv[cDev])
652 {
653 pData->pMouse->mpDrv[cDev] = pData;
654 break;
655 }
656 if (cDev == MOUSE_MAX_DEVICES)
657 return VERR_NO_MORE_HANDLES;
658
659 return VINF_SUCCESS;
660}
661
662
663/**
664 * Main mouse driver registration record.
665 */
666const PDMDRVREG Mouse::DrvReg =
667{
668 /* u32Version */
669 PDM_DRVREG_VERSION,
670 /* szName */
671 "MainMouse",
672 /* szRCMod */
673 "",
674 /* szR0Mod */
675 "",
676 /* pszDescription */
677 "Main mouse driver (Main as in the API).",
678 /* fFlags */
679 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
680 /* fClass. */
681 PDM_DRVREG_CLASS_MOUSE,
682 /* cMaxInstances */
683 ~0,
684 /* cbInstance */
685 sizeof(DRVMAINMOUSE),
686 /* pfnConstruct */
687 Mouse::drvConstruct,
688 /* pfnDestruct */
689 Mouse::drvDestruct,
690 /* pfnRelocate */
691 NULL,
692 /* pfnIOCtl */
693 NULL,
694 /* pfnPowerOn */
695 NULL,
696 /* pfnReset */
697 NULL,
698 /* pfnSuspend */
699 NULL,
700 /* pfnResume */
701 NULL,
702 /* pfnAttach */
703 NULL,
704 /* pfnDetach */
705 NULL,
706 /* pfnPowerOff */
707 NULL,
708 /* pfnSoftReset */
709 NULL,
710 /* u32EndVersion */
711 PDM_DRVREG_VERSION
712};
713/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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