VirtualBox

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

Last change on this file since 10052 was 9022, checked in by vboxsync, 16 years ago

Don't assert when the queue is full.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.7 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 = PDMINS2DATA(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 pData = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
155 PDRVMOUSEQUEUEITEM pItem = (PDRVMOUSEQUEUEITEM)pItemCore;
156 int rc = pData->pUpPort->pfnPutEvent(pData->pUpPort, pItem->i32DeltaX, pItem->i32DeltaY, pItem->i32DeltaZ, pItem->fButtonStates);
157 return VBOX_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 pData = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
172 pData->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 pData = PDMINS2DATA(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 pData = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
198 pData->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 pData = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
211 pData->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 pData = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
223 pData->fInactive = true;
224}
225
226
227/**
228 * Construct a mouse driver instance.
229 *
230 * @returns VBox status.
231 * @param pDrvIns The driver instance data.
232 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
233 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
234 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
235 * iInstance it's expected to be used a bit in this function.
236 */
237static DECLCALLBACK(int) drvMouseQueueConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
238{
239 PDRVMOUSEQUEUE pDrv = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
240 LogFlow(("drvMouseQueueConstruct: iInstance=%d\n", pDrvIns->iInstance));
241
242 /*
243 * Validate configuration.
244 */
245 if (!CFGMR3AreValuesValid(pCfgHandle, "QueueSize\0Interval\0"))
246 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
247
248 /*
249 * Init basic data members and interfaces.
250 */
251 pDrv->fInactive = true;
252 /* IBase. */
253 pDrvIns->IBase.pfnQueryInterface = drvMouseQueueQueryInterface;
254 /* IMousePort. */
255 pDrv->Port.pfnPutEvent = drvMouseQueuePutEvent;
256
257 /*
258 * Get the IMousePort interface of the above driver/device.
259 */
260 pDrv->pUpPort = (PPDMIMOUSEPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_MOUSE_PORT);
261 if (!pDrv->pUpPort)
262 {
263 AssertMsgFailed(("Configuration error: No mouse port interface above!\n"));
264 return VERR_PDM_MISSING_INTERFACE_ABOVE;
265 }
266
267 /*
268 * Attach driver below and query it's connector interface.
269 */
270 PPDMIBASE pDownBase;
271 int rc = pDrvIns->pDrvHlp->pfnAttach(pDrvIns, &pDownBase);
272 if (VBOX_FAILURE(rc))
273 {
274 AssertMsgFailed(("Failed to attach driver below us! rc=%Vra\n", rc));
275 return rc;
276 }
277 pDrv->pDownConnector = (PPDMIMOUSECONNECTOR)pDownBase->pfnQueryInterface(pDownBase, PDMINTERFACE_MOUSE_CONNECTOR);
278 if (!pDrv->pDownConnector)
279 {
280 AssertMsgFailed(("Configuration error: No mouse connector interface below!\n"));
281 return VERR_PDM_MISSING_INTERFACE_BELOW;
282 }
283
284 /*
285 * Create the queue.
286 */
287 uint32_t cMilliesInterval = 0;
288 rc = CFGMR3QueryU32(pCfgHandle, "Interval", &cMilliesInterval);
289 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
290 cMilliesInterval = 0;
291 else if (VBOX_FAILURE(rc))
292 {
293 AssertMsgFailed(("Configuration error: 32-bit \"Interval\" -> rc=%Vrc\n", rc));
294 return rc;
295 }
296
297 uint32_t cItems = 0;
298 rc = CFGMR3QueryU32(pCfgHandle, "QueueSize", &cItems);
299 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
300 cItems = 128;
301 else if (VBOX_FAILURE(rc))
302 {
303 AssertMsgFailed(("Configuration error: 32-bit \"QueueSize\" -> rc=%Vrc\n", rc));
304 return rc;
305 }
306
307 rc = pDrvIns->pDrvHlp->pfnPDMQueueCreate(pDrvIns, sizeof(DRVMOUSEQUEUEITEM), cItems, cMilliesInterval, drvMouseQueueConsumer, &pDrv->pQueue);
308 if (VBOX_FAILURE(rc))
309 {
310 AssertMsgFailed(("Failed to create driver: cItems=%d cMilliesInterval=%d rc=%Vrc\n", cItems, cMilliesInterval, rc));
311 return rc;
312 }
313
314 return VINF_SUCCESS;
315}
316
317
318/**
319 * Mouse queue driver registration record.
320 */
321const PDMDRVREG g_DrvMouseQueue =
322{
323 /* u32Version */
324 PDM_DRVREG_VERSION,
325 /* szDriverName */
326 "MouseQueue",
327 /* pszDescription */
328 "Mouse queue driver to plug in between the key source and the device to do queueing and inter-thread transport.",
329 /* fFlags */
330 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
331 /* fClass. */
332 PDM_DRVREG_CLASS_MOUSE,
333 /* cMaxInstances */
334 ~0,
335 /* cbInstance */
336 sizeof(DRVMOUSEQUEUE),
337 /* pfnConstruct */
338 drvMouseQueueConstruct,
339 /* pfnDestruct */
340 NULL,
341 /* pfnIOCtl */
342 NULL,
343 /* pfnPowerOn */
344 drvMouseQueuePowerOn,
345 /* pfnReset */
346 drvMouseQueueReset,
347 /* pfnSuspend */
348 drvMouseQueueSuspend,
349 /* pfnResume */
350 drvMouseQueueResume,
351 /* pfnDetach */
352 NULL,
353 /** pfnPowerOff */
354 drvMouseQueuePowerOff
355};
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