VirtualBox

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

Last change on this file since 4014 was 4014, checked in by vboxsync, 17 years ago

Use pdmdrv.h and pdmdev.h where appropirate.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.8 KB
Line 
1/** @file
2 *
3 * VBox input devices:
4 * Mouse queue driver
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
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 AssertMsgFailed(("drvMouseQueuePutEvent: Queue is full!!!!\n"));
139 return VERR_PDM_NO_QUEUE_ITEMS;
140}
141
142
143/* -=-=-=-=- queue -=-=-=-=- */
144
145/**
146 * Queue callback for processing a queued item.
147 *
148 * @returns Success indicator.
149 * If false the item will not be removed and the flushing will stop.
150 * @param pDrvIns The driver instance.
151 * @param pItemCore Pointer to the queue item to process.
152 */
153static DECLCALLBACK(bool) drvMouseQueueConsumer(PPDMDRVINS pDrvIns, PPDMQUEUEITEMCORE pItemCore)
154{
155 PDRVMOUSEQUEUE pData = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
156 PDRVMOUSEQUEUEITEM pItem = (PDRVMOUSEQUEUEITEM)pItemCore;
157 int rc = pData->pUpPort->pfnPutEvent(pData->pUpPort, pItem->i32DeltaX, pItem->i32DeltaY, pItem->i32DeltaZ, pItem->fButtonStates);
158 return VBOX_SUCCESS(rc);
159}
160
161
162/* -=-=-=-=- driver interface -=-=-=-=- */
163
164/**
165 * Power On notification.
166 *
167 * @returns VBox status.
168 * @param pDrvIns The drive instance data.
169 */
170static DECLCALLBACK(void) drvMouseQueuePowerOn(PPDMDRVINS pDrvIns)
171{
172 PDRVMOUSEQUEUE pData = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
173 pData->fInactive = false;
174}
175
176
177/**
178 * Reset notification.
179 *
180 * @returns VBox status.
181 * @param pDrvIns The drive instance data.
182 */
183static DECLCALLBACK(void) drvMouseQueueReset(PPDMDRVINS pDrvIns)
184{
185 //PDRVKBDQUEUE pData = PDMINS2DATA(pDrvIns, PDRVKBDQUEUE);
186 /** @todo purge the queue on reset. */
187}
188
189
190/**
191 * Suspend notification.
192 *
193 * @returns VBox status.
194 * @param pDrvIns The drive instance data.
195 */
196static DECLCALLBACK(void) drvMouseQueueSuspend(PPDMDRVINS pDrvIns)
197{
198 PDRVMOUSEQUEUE pData = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
199 pData->fInactive = true;
200}
201
202
203/**
204 * Resume notification.
205 *
206 * @returns VBox status.
207 * @param pDrvIns The drive instance data.
208 */
209static DECLCALLBACK(void) drvMouseQueueResume(PPDMDRVINS pDrvIns)
210{
211 PDRVMOUSEQUEUE pData = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
212 pData->fInactive = false;
213}
214
215
216/**
217 * Power Off notification.
218 *
219 * @param pDrvIns The drive instance data.
220 */
221static DECLCALLBACK(void) drvMouseQueuePowerOff(PPDMDRVINS pDrvIns)
222{
223 PDRVMOUSEQUEUE pData = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
224 pData->fInactive = true;
225}
226
227
228/**
229 * Construct a mouse driver instance.
230 *
231 * @returns VBox status.
232 * @param pDrvIns The driver instance data.
233 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
234 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
235 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
236 * iInstance it's expected to be used a bit in this function.
237 */
238static DECLCALLBACK(int) drvMouseQueueConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
239{
240 PDRVMOUSEQUEUE pDrv = PDMINS2DATA(pDrvIns, PDRVMOUSEQUEUE);
241 LogFlow(("drvMouseQueueConstruct: iInstance=%d\n", pDrvIns->iInstance));
242
243 /*
244 * Validate configuration.
245 */
246 if (!CFGMR3AreValuesValid(pCfgHandle, "QueueSize\0Interval\0"))
247 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
248
249 /*
250 * Init basic data members and interfaces.
251 */
252 pDrv->fInactive = true;
253 /* IBase. */
254 pDrvIns->IBase.pfnQueryInterface = drvMouseQueueQueryInterface;
255 /* IMousePort. */
256 pDrv->Port.pfnPutEvent = drvMouseQueuePutEvent;
257
258 /*
259 * Get the IMousePort interface of the above driver/device.
260 */
261 pDrv->pUpPort = (PPDMIMOUSEPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_MOUSE_PORT);
262 if (!pDrv->pUpPort)
263 {
264 AssertMsgFailed(("Configuration error: No mouse port interface above!\n"));
265 return VERR_PDM_MISSING_INTERFACE_ABOVE;
266 }
267
268 /*
269 * Attach driver below and query it's connector interface.
270 */
271 PPDMIBASE pDownBase;
272 int rc = pDrvIns->pDrvHlp->pfnAttach(pDrvIns, &pDownBase);
273 if (VBOX_FAILURE(rc))
274 {
275 AssertMsgFailed(("Failed to attach driver below us! rc=%Vra\n", rc));
276 return rc;
277 }
278 pDrv->pDownConnector = (PPDMIMOUSECONNECTOR)pDownBase->pfnQueryInterface(pDownBase, PDMINTERFACE_MOUSE_CONNECTOR);
279 if (!pDrv->pDownConnector)
280 {
281 AssertMsgFailed(("Configuration error: No mouse connector interface below!\n"));
282 return VERR_PDM_MISSING_INTERFACE_BELOW;
283 }
284
285 /*
286 * Create the queue.
287 */
288 uint32_t cMilliesInterval = 0;
289 rc = CFGMR3QueryU32(pCfgHandle, "Interval", &cMilliesInterval);
290 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
291 cMilliesInterval = 0;
292 else if (VBOX_FAILURE(rc))
293 {
294 AssertMsgFailed(("Configuration error: 32-bit \"Interval\" -> rc=%Vrc\n", rc));
295 return rc;
296 }
297
298 uint32_t cItems = 0;
299 rc = CFGMR3QueryU32(pCfgHandle, "QueueSize", &cItems);
300 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
301 cItems = 128;
302 else if (VBOX_FAILURE(rc))
303 {
304 AssertMsgFailed(("Configuration error: 32-bit \"QueueSize\" -> rc=%Vrc\n", rc));
305 return rc;
306 }
307
308 rc = pDrvIns->pDrvHlp->pfnPDMQueueCreate(pDrvIns, sizeof(DRVMOUSEQUEUEITEM), cItems, cMilliesInterval, drvMouseQueueConsumer, &pDrv->pQueue);
309 if (VBOX_FAILURE(rc))
310 {
311 AssertMsgFailed(("Failed to create driver: cItems=%d cMilliesInterval=%d rc=%Vrc\n", cItems, cMilliesInterval, rc));
312 return rc;
313 }
314
315 return VINF_SUCCESS;
316}
317
318
319/**
320 * Mouse queue driver registration record.
321 */
322const PDMDRVREG g_DrvMouseQueue =
323{
324 /* u32Version */
325 PDM_DRVREG_VERSION,
326 /* szDriverName */
327 "MouseQueue",
328 /* pszDescription */
329 "Mouse queue driver to plug in between the key source and the device to do queueing and inter-thread transport.",
330 /* fFlags */
331 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
332 /* fClass. */
333 PDM_DRVREG_CLASS_MOUSE,
334 /* cMaxInstances */
335 ~0,
336 /* cbInstance */
337 sizeof(DRVMOUSEQUEUE),
338 /* pfnConstruct */
339 drvMouseQueueConstruct,
340 /* pfnDestruct */
341 NULL,
342 /* pfnIOCtl */
343 NULL,
344 /* pfnPowerOn */
345 drvMouseQueuePowerOn,
346 /* pfnReset */
347 drvMouseQueueReset,
348 /* pfnSuspend */
349 drvMouseQueueSuspend,
350 /* pfnResume */
351 drvMouseQueueResume,
352 /* pfnDetach */
353 NULL,
354 /** pfnPowerOff */
355 drvMouseQueuePowerOff
356};
357
358
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