VirtualBox

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

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

Devices, Main, pdmifs.h: changed the Main-to-Device absolute event protocol to include button and wheel events; some cleanups and fixes

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