VirtualBox

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

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

FE/BFE: more clean-up to reduce the difference between MouseImpl.cpp in Main and VBoxBFE

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