VirtualBox

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

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

FE/BFE: resynchronise MouseImpl from Main

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