VirtualBox

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

Last change on this file since 2390 was 1, checked in by vboxsync, 55 years ago

import

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