VirtualBox

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

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

Main: comments

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.0 KB
Line 
1/* $Id: MouseImpl.cpp 27403 2010-03-16 13:29:14Z 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 (starting from 1) to a value
392 * from 0 to 0xffff.
393 *
394 * @returns COM status value
395 */
396HRESULT Mouse::convertDisplayWidth(LONG x, uint32_t *pcX)
397{
398 AssertPtrReturn(pcX, E_POINTER);
399 Display *pDisplay = mParent->getDisplay();
400 ComAssertRet(pDisplay, E_FAIL);
401
402 ULONG displayWidth;
403 HRESULT rc = pDisplay->COMGETTER(Width)(&displayWidth);
404 if (FAILED(rc)) return rc;
405
406 *pcX = displayWidth ? ((x - 1) * 0xFFFF) / displayWidth: 0;
407 return S_OK;
408}
409
410/**
411 * Convert a Y value in screen co-ordinates (starting from 1) to a value
412 * from 0 to 0xffff.
413 *
414 * @returns COM status value
415 */
416HRESULT Mouse::convertDisplayHeight(LONG y, uint32_t *pcY)
417{
418 AssertPtrReturn(pcY, E_POINTER);
419 Display *pDisplay = mParent->getDisplay();
420 ComAssertRet(pDisplay, E_FAIL);
421
422 ULONG displayHeight;
423 HRESULT rc = pDisplay->COMGETTER(Height)(&displayHeight);
424 if (FAILED(rc)) return rc;
425
426 *pcY = displayHeight ? ((y - 1) * 0xFFFF) / displayHeight: 0;
427 return S_OK;
428}
429
430
431/**
432 * Send an absolute mouse event to the VM. This only works
433 * when the required guest support has been installed.
434 *
435 * @returns COM status code
436 * @param x X position (pixel), starting from 1
437 * @param y Y position (pixel), starting from 1
438 * @param dz Z movement
439 * @param buttonState The mouse button state
440 */
441STDMETHODIMP Mouse::PutMouseEventAbsolute(LONG x, LONG y, LONG dz, LONG dw,
442 LONG buttonState)
443{
444 AutoCaller autoCaller(this);
445 if (FAILED(autoCaller.rc())) return autoCaller.rc();
446
447 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
448
449 LogRel3(("%s: x=%d, y=%d, dz=%d, dw=%d, buttonState=0x%x\n",
450 __PRETTY_FUNCTION__, x, y, dz, dw, buttonState));
451
452 uint32_t mouseXAbs;
453 /** @todo the front end should do this conversion to avoid races */
454 HRESULT rc = convertDisplayWidth(x, &mouseXAbs);
455 if (FAILED(rc)) return rc;
456
457 /**
458 * @todo multi-monitor Windows guests expect this to be unbounded.
459 * Understand the issues involved and fix for the rest.
460 */
461 /* if (mouseXAbs > 0xffff)
462 mouseXAbs = mLastAbsX; */
463
464 uint32_t mouseYAbs;
465 rc = convertDisplayHeight(y, &mouseYAbs);
466 if (FAILED(rc)) return rc;
467 /* if (mouseYAbs > 0xffff)
468 mouseYAbs = mLastAbsY; */
469
470 uint32_t fButtons = mouseButtonsToPDM(buttonState);
471
472 uint32_t mouseCaps;
473 rc = getVMMDevMouseCaps(&mouseCaps);
474 if (FAILED(rc)) return rc;
475
476 /*
477 * This method being called implies that the host wants
478 * to use absolute coordinates. If the VMM device isn't
479 * aware of that yet, tell it.
480 */
481 if (!(mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE))
482 {
483 uHostCaps |= VMMDEV_MOUSE_HOST_CAN_ABSOLUTE;
484 setVMMDevMouseCaps(uHostCaps);
485 }
486
487 if (fVMMDevCanAbs)
488 {
489 /*
490 * Send the absolute mouse position to the VMM device.
491 */
492 rc = reportAbsEventToVMMDev(mouseXAbs, mouseYAbs);
493 /* We may need to send an additional event for button information or
494 * to wake up older guests to the changed absolute co-ordinates. If
495 * the event is a pure wake up one, we make sure it contains some
496 * (possibly phony) event data to make sure it isn't just discarded
497 * on the way. */
498 bool fNeedsJiggle = !(mouseCaps & VMMDEV_MOUSE_GUEST_USES_VMMDEV);
499 if (fNeedsJiggle || fButtons != mLastButtons || dz || dw)
500 {
501 rc = reportRelEventToMouseDev(fNeedsJiggle ? 1 : 0, 0, dz, dw,
502 fButtons);
503 }
504 }
505 else
506 rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons);
507
508 if (FAILED(rc)) return rc;
509
510 mLastAbsX = mouseXAbs;
511 mLastAbsY = mouseYAbs;
512
513 mLastButtons = fButtons;
514 return rc;
515}
516
517// private methods
518/////////////////////////////////////////////////////////////////////////////
519
520
521void Mouse::sendMouseCapsNotifications(void)
522{
523 bool fAbsDev = false;
524 bool fRelDev = false;
525 uint32_t u32MouseCaps;
526 for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
527 if (mpDrv[i])
528 {
529 if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE)
530 fAbsDev = true;
531 if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE)
532 fRelDev = true;
533 }
534 if (SUCCEEDED(getVMMDevMouseCaps(&u32MouseCaps)))
535 fVMMDevCanAbs = (u32MouseCaps & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
536 && fRelDev;
537 else
538 fVMMDevCanAbs = false;
539 mParent->onMouseCapabilityChange(fAbsDev || fVMMDevCanAbs, fRelDev,
540 fVMMDevNeedsHostCursor);
541 /** @todo if this gets called during device initialisation we get an
542 * error due to VMMDev not being initialised yet. */
543 if (fAbsDev && !(uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
544 uHostCaps |= VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
545 if (!fAbsDev && (uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
546 uHostCaps &= ~VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
547 setVMMDevMouseCaps(uHostCaps);
548}
549
550
551/**
552 * @interface_method_impl{PDMIMOUSECONNECTOR,pfnReportModes}
553 */
554DECLCALLBACK(void) Mouse::mouseReportModes(PPDMIMOUSECONNECTOR pInterface, bool fRel, bool fAbs)
555{
556 PDRVMAINMOUSE pDrv = RT_FROM_MEMBER(pInterface, DRVMAINMOUSE, IConnector);
557 if (fRel)
558 pDrv->u32DevCaps |= MOUSE_DEVCAP_RELATIVE;
559 else
560 pDrv->u32DevCaps &= ~MOUSE_DEVCAP_RELATIVE;
561 if (fAbs)
562 pDrv->u32DevCaps |= MOUSE_DEVCAP_ABSOLUTE;
563 else
564 pDrv->u32DevCaps &= ~MOUSE_DEVCAP_ABSOLUTE;
565
566 pDrv->pMouse->sendMouseCapsNotifications();
567}
568
569
570/**
571 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
572 */
573DECLCALLBACK(void *) Mouse::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)
574{
575 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
576 PDRVMAINMOUSE pDrv = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
577
578 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
579 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUSECONNECTOR, &pDrv->IConnector);
580 return NULL;
581}
582
583
584/**
585 * Destruct a mouse driver instance.
586 *
587 * @returns VBox status.
588 * @param pDrvIns The driver instance data.
589 */
590DECLCALLBACK(void) Mouse::drvDestruct(PPDMDRVINS pDrvIns)
591{
592 PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
593 LogFlow(("Mouse::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
594 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
595
596 if (pData->pMouse)
597 {
598 AutoWriteLock mouseLock(pData->pMouse COMMA_LOCKVAL_SRC_POS);
599 for (unsigned cDev = 0; cDev < MOUSE_MAX_DEVICES; ++cDev)
600 if (pData->pMouse->mpDrv[cDev] == pData)
601 {
602 pData->pMouse->mpDrv[cDev] = NULL;
603 break;
604 }
605 }
606}
607
608
609/**
610 * Construct a mouse driver instance.
611 *
612 * @copydoc FNPDMDRVCONSTRUCT
613 */
614DECLCALLBACK(int) Mouse::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
615{
616 PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
617 LogFlow(("drvMainMouse_Construct: iInstance=%d\n", pDrvIns->iInstance));
618 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
619
620 /*
621 * Validate configuration.
622 */
623 if (!CFGMR3AreValuesValid(pCfg, "Object\0"))
624 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
625 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
626 ("Configuration error: Not possible to attach anything to this driver!\n"),
627 VERR_PDM_DRVINS_NO_ATTACH);
628
629 /*
630 * IBase.
631 */
632 pDrvIns->IBase.pfnQueryInterface = Mouse::drvQueryInterface;
633
634 pData->IConnector.pfnReportModes = Mouse::mouseReportModes;
635
636 /*
637 * Get the IMousePort interface of the above driver/device.
638 */
639 pData->pUpPort = (PPDMIMOUSEPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMIMOUSEPORT_IID);
640 if (!pData->pUpPort)
641 {
642 AssertMsgFailed(("Configuration error: No mouse port interface above!\n"));
643 return VERR_PDM_MISSING_INTERFACE_ABOVE;
644 }
645
646 /*
647 * Get the Mouse object pointer and update the mpDrv member.
648 */
649 void *pv;
650 int rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
651 if (RT_FAILURE(rc))
652 {
653 AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
654 return rc;
655 }
656 pData->pMouse = (Mouse *)pv; /** @todo Check this cast! */
657 unsigned cDev;
658 for (cDev = 0; cDev < MOUSE_MAX_DEVICES; ++cDev)
659 if (!pData->pMouse->mpDrv[cDev])
660 {
661 pData->pMouse->mpDrv[cDev] = pData;
662 break;
663 }
664 if (cDev == MOUSE_MAX_DEVICES)
665 return VERR_NO_MORE_HANDLES;
666
667 return VINF_SUCCESS;
668}
669
670
671/**
672 * Main mouse driver registration record.
673 */
674const PDMDRVREG Mouse::DrvReg =
675{
676 /* u32Version */
677 PDM_DRVREG_VERSION,
678 /* szName */
679 "MainMouse",
680 /* szRCMod */
681 "",
682 /* szR0Mod */
683 "",
684 /* pszDescription */
685 "Main mouse driver (Main as in the API).",
686 /* fFlags */
687 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
688 /* fClass. */
689 PDM_DRVREG_CLASS_MOUSE,
690 /* cMaxInstances */
691 ~0,
692 /* cbInstance */
693 sizeof(DRVMAINMOUSE),
694 /* pfnConstruct */
695 Mouse::drvConstruct,
696 /* pfnDestruct */
697 Mouse::drvDestruct,
698 /* pfnRelocate */
699 NULL,
700 /* pfnIOCtl */
701 NULL,
702 /* pfnPowerOn */
703 NULL,
704 /* pfnReset */
705 NULL,
706 /* pfnSuspend */
707 NULL,
708 /* pfnResume */
709 NULL,
710 /* pfnAttach */
711 NULL,
712 /* pfnDetach */
713 NULL,
714 /* pfnPowerOff */
715 NULL,
716 /* pfnSoftReset */
717 NULL,
718 /* u32EndVersion */
719 PDM_DRVREG_VERSION
720};
721/* 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