VirtualBox

source: vbox/trunk/src/VBox/Devices/Input/DrvMouseQueue.cpp@ 22455

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

PDMDRVREG change (big changeset).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1/** @file
2 *
3 * VBox input devices:
4 * Mouse queue driver
5 */
6
7/*
8 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#define LOG_GROUP LOG_GROUP_DRV_MOUSE_QUEUE
28#include <VBox/pdmdrv.h>
29#include <iprt/assert.h>
30
31#include "Builtins.h"
32
33
34
35/*******************************************************************************
36* Structures and Typedefs *
37*******************************************************************************/
38/**
39 * Mouse queue driver instance data.
40 */
41typedef struct DRVMOUSEQUEUE
42{
43 /** Pointer to the driver instance structure. */
44 PPDMDRVINS pDrvIns;
45 /** Pointer to the mouse port interface of the driver/device above us. */
46 PPDMIMOUSEPORT pUpPort;
47 /** Pointer to the mouse port interface of the driver/device below us. */
48 PPDMIMOUSECONNECTOR pDownConnector;
49 /** Our mouse connector interface. */
50 PDMIMOUSECONNECTOR Connector;
51 /** Our mouse port interface. */
52 PDMIMOUSEPORT Port;
53 /** The queue handle. */
54 PPDMQUEUE pQueue;
55 /** Discard input when this flag is set.
56 * We only accept input when the VM is running. */
57 bool fInactive;
58} DRVMOUSEQUEUE, *PDRVMOUSEQUEUE;
59
60
61/**
62 * Mouse queue item.
63 */
64typedef struct DRVMOUSEQUEUEITEM
65{
66 /** The core part owned by the queue manager. */
67 PDMQUEUEITEMCORE Core;
68 int32_t i32DeltaX;
69 int32_t i32DeltaY;
70 int32_t i32DeltaZ;
71 uint32_t fButtonStates;
72} DRVMOUSEQUEUEITEM, *PDRVMOUSEQUEUEITEM;
73
74
75
76/* -=-=-=-=- IBase -=-=-=-=- */
77
78/**
79 * Queries an interface to the driver.
80 *
81 * @returns Pointer to interface.
82 * @returns NULL if the interface was not supported by the driver.
83 * @param pInterface Pointer to this interface structure.
84 * @param enmInterface The requested interface identification.
85 */
86static DECLCALLBACK(void *) drvMouseQueueQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
87{
88 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
89 PDRVMOUSEQUEUE pDrv = PDMINS_2_DATA(pDrvIns, PDRVMOUSEQUEUE);
90 switch (enmInterface)
91 {
92 case PDMINTERFACE_BASE:
93 return &pDrvIns->IBase;
94 case PDMINTERFACE_MOUSE_PORT:
95 return &pDrv->Port;
96 case PDMINTERFACE_MOUSE_CONNECTOR:
97 return &pDrv->Connector;
98 default:
99 return NULL;
100 }
101}
102
103
104/* -=-=-=-=- IMousePort -=-=-=-=- */
105
106/** Converts a pointer to DRVMOUSEQUEUE::Port to a DRVMOUSEQUEUE pointer. */
107#define IMOUSEPORT_2_DRVMOUSEQUEUE(pInterface) ( (PDRVMOUSEQUEUE)((char *)(pInterface) - RT_OFFSETOF(DRVMOUSEQUEUE, Port)) )
108
109
110/**
111 * Queues a mouse event.
112 * Because of the event queueing the EMT context requirement is lifted.
113 *
114 * @returns VBox status code.
115 * @param pInterface Pointer to interface structure.
116 * @param i32DeltaX The X delta.
117 * @param i32DeltaY The Y delta.
118 * @param i32DeltaZ The Z delta.
119 * @param fButtonStates The button states.
120 * @thread Any thread.
121 */
122static DECLCALLBACK(int) drvMouseQueuePutEvent(PPDMIMOUSEPORT pInterface, int32_t i32DeltaX, int32_t i32DeltaY, int32_t i32DeltaZ, uint32_t fButtonStates)
123{
124 PDRVMOUSEQUEUE pDrv = IMOUSEPORT_2_DRVMOUSEQUEUE(pInterface);
125 if (pDrv->fInactive)
126 return VINF_SUCCESS;
127
128 PDRVMOUSEQUEUEITEM pItem = (PDRVMOUSEQUEUEITEM)PDMQueueAlloc(pDrv->pQueue);
129 if (pItem)
130 {
131 pItem->i32DeltaX = i32DeltaX;
132 pItem->i32DeltaY = i32DeltaY;
133 pItem->i32DeltaZ = i32DeltaZ;
134 pItem->fButtonStates = fButtonStates;
135 PDMQueueInsert(pDrv->pQueue, &pItem->Core);
136 return VINF_SUCCESS;
137 }
138 return VERR_PDM_NO_QUEUE_ITEMS;
139}
140
141
142/* -=-=-=-=- queue -=-=-=-=- */
143
144/**
145 * Queue callback for processing a queued item.
146 *
147 * @returns Success indicator.
148 * If false the item will not be removed and the flushing will stop.
149 * @param pDrvIns The driver instance.
150 * @param pItemCore Pointer to the queue item to process.
151 */
152static DECLCALLBACK(bool) drvMouseQueueConsumer(PPDMDRVINS pDrvIns, PPDMQUEUEITEMCORE pItemCore)
153{
154 PDRVMOUSEQUEUE pThis = PDMINS_2_DATA(pDrvIns, PDRVMOUSEQUEUE);
155 PDRVMOUSEQUEUEITEM pItem = (PDRVMOUSEQUEUEITEM)pItemCore;
156 int rc = pThis->pUpPort->pfnPutEvent(pThis->pUpPort, pItem->i32DeltaX, pItem->i32DeltaY, pItem->i32DeltaZ, pItem->fButtonStates);
157 return RT_SUCCESS(rc);
158}
159
160
161/* -=-=-=-=- driver interface -=-=-=-=- */
162
163/**
164 * Power On notification.
165 *
166 * @returns VBox status.
167 * @param pDrvIns The drive instance data.
168 */
169static DECLCALLBACK(void) drvMouseQueuePowerOn(PPDMDRVINS pDrvIns)
170{
171 PDRVMOUSEQUEUE pThis = PDMINS_2_DATA(pDrvIns, PDRVMOUSEQUEUE);
172 pThis->fInactive = false;
173}
174
175
176/**
177 * Reset notification.
178 *
179 * @returns VBox status.
180 * @param pDrvIns The drive instance data.
181 */
182static DECLCALLBACK(void) drvMouseQueueReset(PPDMDRVINS pDrvIns)
183{
184 //PDRVKBDQUEUE pThis = PDMINS_2_DATA(pDrvIns, PDRVKBDQUEUE);
185 /** @todo purge the queue on reset. */
186}
187
188
189/**
190 * Suspend notification.
191 *
192 * @returns VBox status.
193 * @param pDrvIns The drive instance data.
194 */
195static DECLCALLBACK(void) drvMouseQueueSuspend(PPDMDRVINS pDrvIns)
196{
197 PDRVMOUSEQUEUE pThis = PDMINS_2_DATA(pDrvIns, PDRVMOUSEQUEUE);
198 pThis->fInactive = true;
199}
200
201
202/**
203 * Resume notification.
204 *
205 * @returns VBox status.
206 * @param pDrvIns The drive instance data.
207 */
208static DECLCALLBACK(void) drvMouseQueueResume(PPDMDRVINS pDrvIns)
209{
210 PDRVMOUSEQUEUE pThis = PDMINS_2_DATA(pDrvIns, PDRVMOUSEQUEUE);
211 pThis->fInactive = false;
212}
213
214
215/**
216 * Power Off notification.
217 *
218 * @param pDrvIns The drive instance data.
219 */
220static DECLCALLBACK(void) drvMouseQueuePowerOff(PPDMDRVINS pDrvIns)
221{
222 PDRVMOUSEQUEUE pThis = PDMINS_2_DATA(pDrvIns, PDRVMOUSEQUEUE);
223 pThis->fInactive = true;
224}
225
226
227/**
228 * Construct a mouse driver instance.
229 *
230 * @copydoc FNPDMDRVCONSTRUCT
231 */
232static DECLCALLBACK(int) drvMouseQueueConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
233{
234 PDRVMOUSEQUEUE pDrv = PDMINS_2_DATA(pDrvIns, PDRVMOUSEQUEUE);
235 LogFlow(("drvMouseQueueConstruct: iInstance=%d\n", pDrvIns->iInstance));
236
237 /*
238 * Validate configuration.
239 */
240 if (!CFGMR3AreValuesValid(pCfgHandle, "QueueSize\0Interval\0"))
241 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
242
243 /*
244 * Init basic data members and interfaces.
245 */
246 pDrv->fInactive = true;
247 /* IBase. */
248 pDrvIns->IBase.pfnQueryInterface = drvMouseQueueQueryInterface;
249 /* IMousePort. */
250 pDrv->Port.pfnPutEvent = drvMouseQueuePutEvent;
251
252 /*
253 * Get the IMousePort interface of the above driver/device.
254 */
255 pDrv->pUpPort = (PPDMIMOUSEPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_MOUSE_PORT);
256 if (!pDrv->pUpPort)
257 {
258 AssertMsgFailed(("Configuration error: No mouse port interface above!\n"));
259 return VERR_PDM_MISSING_INTERFACE_ABOVE;
260 }
261
262 /*
263 * Attach driver below and query it's connector interface.
264 */
265 PPDMIBASE pDownBase;
266 int rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pDownBase);
267 if (RT_FAILURE(rc))
268 {
269 AssertMsgFailed(("Failed to attach driver below us! rc=%Rra\n", rc));
270 return rc;
271 }
272 pDrv->pDownConnector = (PPDMIMOUSECONNECTOR)pDownBase->pfnQueryInterface(pDownBase, PDMINTERFACE_MOUSE_CONNECTOR);
273 if (!pDrv->pDownConnector)
274 {
275 AssertMsgFailed(("Configuration error: No mouse connector interface below!\n"));
276 return VERR_PDM_MISSING_INTERFACE_BELOW;
277 }
278
279 /*
280 * Create the queue.
281 */
282 uint32_t cMilliesInterval = 0;
283 rc = CFGMR3QueryU32(pCfgHandle, "Interval", &cMilliesInterval);
284 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
285 cMilliesInterval = 0;
286 else if (RT_FAILURE(rc))
287 {
288 AssertMsgFailed(("Configuration error: 32-bit \"Interval\" -> rc=%Rrc\n", rc));
289 return rc;
290 }
291
292 uint32_t cItems = 0;
293 rc = CFGMR3QueryU32(pCfgHandle, "QueueSize", &cItems);
294 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
295 cItems = 128;
296 else if (RT_FAILURE(rc))
297 {
298 AssertMsgFailed(("Configuration error: 32-bit \"QueueSize\" -> rc=%Rrc\n", rc));
299 return rc;
300 }
301
302 rc = PDMDrvHlpPDMQueueCreate(pDrvIns, sizeof(DRVMOUSEQUEUEITEM), cItems, cMilliesInterval, drvMouseQueueConsumer, "Mouse", &pDrv->pQueue);
303 if (RT_FAILURE(rc))
304 {
305 AssertMsgFailed(("Failed to create driver: cItems=%d cMilliesInterval=%d rc=%Rrc\n", cItems, cMilliesInterval, rc));
306 return rc;
307 }
308
309 return VINF_SUCCESS;
310}
311
312
313/**
314 * Mouse queue driver registration record.
315 */
316const PDMDRVREG g_DrvMouseQueue =
317{
318 /* u32Version */
319 PDM_DRVREG_VERSION,
320 /* szDriverName */
321 "MouseQueue",
322 /* pszDescription */
323 "Mouse queue driver to plug in between the key source and the device to do queueing and inter-thread transport.",
324 /* fFlags */
325 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
326 /* fClass. */
327 PDM_DRVREG_CLASS_MOUSE,
328 /* cMaxInstances */
329 ~0,
330 /* cbInstance */
331 sizeof(DRVMOUSEQUEUE),
332 /* pfnConstruct */
333 drvMouseQueueConstruct,
334 /* pfnDestruct */
335 NULL,
336 /* pfnIOCtl */
337 NULL,
338 /* pfnPowerOn */
339 drvMouseQueuePowerOn,
340 /* pfnReset */
341 drvMouseQueueReset,
342 /* pfnSuspend */
343 drvMouseQueueSuspend,
344 /* pfnResume */
345 drvMouseQueueResume,
346 /* pfnAttach */
347 NULL,
348 /* pfnDetach */
349 NULL,
350 /* pfnPowerOff */
351 drvMouseQueuePowerOff,
352 /* pfnSoftReset */
353 NULL,
354 /* u32EndVersion */
355 PDM_DRVREG_VERSION
356};
357
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