VirtualBox

source: vbox/trunk/src/VBox/Devices/Input/testcase/tstUsbMouse.cpp@ 47796

Last change on this file since 47796 was 47796, checked in by vboxsync, 11 years ago

Devices/Input: reverting r88027 as several guests did not like it.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 KB
Line 
1/* $Id: tstUsbMouse.cpp 47796 2013-08-16 10:31:34Z vboxsync $ */
2/** @file
3 * tstUsbMouse.cpp - testcase USB mouse and tablet devices.
4 */
5
6/*
7 * Copyright (C) 2013 Oracle Corporation
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
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#include "VBoxDD.h"
22#include <VBox/vmm/pdmdrv.h>
23#include <iprt/alloc.h>
24#include <iprt/stream.h>
25#include <iprt/test.h>
26#include <iprt/uuid.h>
27
28/** Test mouse driver structure. */
29typedef struct DRVTSTMOUSE
30{
31 /** The USBHID structure. */
32 struct USBHID *pUsbHid;
33 /** The base interface for the mouse driver. */
34 PDMIBASE IBase;
35 /** Our mouse connector interface. */
36 PDMIMOUSECONNECTOR IConnector;
37 /** The base interface of the attached mouse port. */
38 PPDMIBASE pDrvBase;
39 /** The mouse port interface of the attached mouse port. */
40 PPDMIMOUSEPORT pDrv;
41 /** Is relative mode currently supported? */
42 bool fRel;
43 /** Is absolute mode currently supported? */
44 bool fAbs;
45 /** Is multi-touch mode currently supported? */
46 bool fMT;
47} DRVTSTMOUSE, *PDRVTSTMOUSE;
48
49
50/** Global mouse driver variable.
51 * @todo To be improved some time. */
52static DRVTSTMOUSE s_drvTstMouse;
53
54
55/** @interface_method_impl{PDMUSBHLPR3,pfnVMSetErrorV} */
56static DECLCALLBACK(int) tstVMSetErrorV(PPDMUSBINS pUsbIns, int rc,
57 RT_SRC_POS_DECL, const char *pszFormat,
58 va_list va)
59{
60 NOREF(pUsbIns);
61 RTPrintf("Error: %s:%u:%s:", RT_SRC_POS_ARGS);
62 RTPrintfV(pszFormat, va);
63 return rc;
64}
65
66/** @interface_method_impl{PDMUSBHLPR3,pfnDriverAttach} */
67/** @todo We currently just take the driver interface from the global
68 * variable. This is sufficient for a unit test but still a bit sad. */
69static DECLCALLBACK(int) tstDriverAttach(PPDMUSBINS pUsbIns, RTUINT iLun,
70 PPDMIBASE pBaseInterface,
71 PPDMIBASE *ppBaseInterface,
72 const char *pszDesc)
73{
74 NOREF(iLun);
75 NOREF(pszDesc);
76 s_drvTstMouse.pDrvBase = pBaseInterface;
77 s_drvTstMouse.pDrv = PDMIBASE_QUERY_INTERFACE(pBaseInterface,
78 PDMIMOUSEPORT);
79 *ppBaseInterface = &s_drvTstMouse.IBase;
80 return VINF_SUCCESS;
81}
82
83
84static PDMUSBHLP s_tstUsbHlp;
85
86
87/**
88 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
89 */
90static DECLCALLBACK(void *) tstMouseQueryInterface(PPDMIBASE pInterface,
91 const char *pszIID)
92{
93 PDRVTSTMOUSE pThis = RT_FROM_MEMBER(pInterface, DRVTSTMOUSE, IBase);
94 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase);
95 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUSECONNECTOR, &pThis->IConnector);
96 return NULL;
97}
98
99
100/**
101 * @interface_method_impl{PDMIMOUSECONNECTOR,pfnReportModes}
102 */
103static DECLCALLBACK(void) tstMouseReportModes(PPDMIMOUSECONNECTOR pInterface,
104 bool fRel, bool fAbs, bool fMT)
105{
106 PDRVTSTMOUSE pDrv = RT_FROM_MEMBER(pInterface, DRVTSTMOUSE, IConnector);
107 pDrv->fRel = fRel;
108 pDrv->fAbs = fAbs;
109 pDrv->fMT = fMT;
110}
111
112
113static int tstMouseConstruct(int iInstance, const char *pcszMode,
114 uint8_t u8CoordShift, PPDMUSBINS *ppThis)
115{
116 int rc = VERR_NO_MEMORY;
117 PPDMUSBINS pThis = (PPDMUSBINS)RTMemAllocZ( sizeof(*pThis)
118 + g_UsbHidMou.cbInstance);
119 PCFGMNODE pCfg = NULL;
120 if (pThis)
121 pCfg = CFGMR3CreateTree(NULL);
122 if (pCfg)
123 rc = CFGMR3InsertString(pCfg, "Mode", pcszMode);
124 if (RT_SUCCESS(rc))
125 rc = CFGMR3InsertInteger(pCfg, "CoordShift", u8CoordShift);
126 if (RT_SUCCESS(rc))
127 {
128 s_drvTstMouse.pDrv = NULL;
129 s_drvTstMouse.pDrvBase = NULL;
130 pThis->iInstance = iInstance;
131 pThis->pHlpR3 = &s_tstUsbHlp;
132 rc = g_UsbHidMou.pfnConstruct(pThis, iInstance, pCfg, NULL);
133 if (RT_SUCCESS(rc))
134 {
135 *ppThis = pThis;
136 return rc;
137 }
138 }
139 /* Failure */
140 if (pCfg)
141 CFGMR3DestroyTree(pCfg);
142 if (pThis)
143 RTMemFree(pThis);
144 return rc;
145}
146
147
148static void testConstructAndDestruct(RTTEST hTest)
149{
150 PPDMUSBINS pThis;
151 RTTestSub(hTest, "simple construction and destruction");
152 int rc = tstMouseConstruct(0, "relative", 1, &pThis);
153 RTTEST_CHECK_RC_OK(hTest, rc);
154 if (pThis)
155 g_UsbHidMou.pfnDestruct(pThis);
156}
157
158
159static void testSendPositionRel(RTTEST hTest)
160{
161 PPDMUSBINS pThis = NULL;
162 VUSBURB Urb;
163 RTTestSub(hTest, "sending a relative position event");
164 int rc = tstMouseConstruct(0, "relative", 1, &pThis);
165 RT_ZERO(Urb);
166 if (RT_SUCCESS(rc))
167 rc = g_UsbHidMou.pfnUsbReset(pThis, false);
168 if (RT_SUCCESS(rc) && !s_drvTstMouse.pDrv)
169 rc = VERR_PDM_MISSING_INTERFACE;
170 RTTEST_CHECK_RC_OK(hTest, rc);
171 if (RT_SUCCESS(rc))
172 {
173 s_drvTstMouse.pDrv->pfnPutEvent(s_drvTstMouse.pDrv, 123, -16, 1, -1, 3);
174 Urb.EndPt = 0x01;
175 rc = g_UsbHidMou.pfnUrbQueue(pThis, &Urb);
176 }
177 if (RT_SUCCESS(rc))
178 {
179 PVUSBURB pUrb = g_UsbHidMou.pfnUrbReap(pThis, 0);
180 if (pUrb)
181 {
182 if (pUrb == &Urb)
183 {
184 if ( Urb.abData[0] != 3 /* Buttons */
185 || Urb.abData[1] != 123 /* x */
186 || Urb.abData[2] != 240 /* 256 - y */
187 || Urb.abData[3] != 255 /* z */)
188 rc = VERR_GENERAL_FAILURE;
189 }
190 else
191 rc = VERR_GENERAL_FAILURE;
192 }
193 else
194 rc = VERR_GENERAL_FAILURE;
195 }
196 RTTEST_CHECK_RC_OK(hTest, rc);
197 if (pThis)
198 g_UsbHidMou.pfnDestruct(pThis);
199}
200
201
202static void testSendPositionAbs(RTTEST hTest)
203{
204 PPDMUSBINS pThis = NULL;
205 VUSBURB Urb;
206 RTTestSub(hTest, "sending an absolute position event");
207 int rc = tstMouseConstruct(0, "absolute", 1, &pThis);
208 RT_ZERO(Urb);
209 if (RT_SUCCESS(rc))
210 {
211 rc = g_UsbHidMou.pfnUsbReset(pThis, false);
212 }
213 if (RT_SUCCESS(rc))
214 {
215 if (s_drvTstMouse.pDrv)
216 s_drvTstMouse.pDrv->pfnPutEventAbs(s_drvTstMouse.pDrv, 300, 200, 1,
217 0, 3);
218 else
219 rc = VERR_PDM_MISSING_INTERFACE;
220 }
221 if (RT_SUCCESS(rc))
222 {
223 Urb.EndPt = 0x01;
224 rc = g_UsbHidMou.pfnUrbQueue(pThis, &Urb);
225 }
226 if (RT_SUCCESS(rc))
227 {
228 PVUSBURB pUrb = g_UsbHidMou.pfnUrbReap(pThis, 0);
229 if (pUrb)
230 {
231 if (pUrb == &Urb)
232 {
233 if ( *(uint16_t *)&Urb.abData[2] != 150 /* x >> 1 */
234 || *(uint16_t *)&Urb.abData[4] != 100 /* y >> 1 */
235 || Urb.abData[0] != 3 /* Buttons */)
236 rc = VERR_GENERAL_FAILURE;
237 }
238 else
239 rc = VERR_GENERAL_FAILURE;
240 }
241 else
242 rc = VERR_GENERAL_FAILURE;
243 }
244 RTTEST_CHECK_RC_OK(hTest, rc);
245 if (pThis)
246 g_UsbHidMou.pfnDestruct(pThis);
247}
248
249#if 0
250/** @todo PDM interface was updated. This is not working anymore. */
251static void testSendPositionMT(RTTEST hTest)
252{
253 PPDMUSBINS pThis = NULL;
254 VUSBURB Urb;
255 RTTestSub(hTest, "sending a multi-touch position event");
256 int rc = tstMouseConstruct(0, "multitouch", 1, &pThis);
257 RT_ZERO(Urb);
258 if (RT_SUCCESS(rc))
259 {
260 rc = g_UsbHidMou.pfnUsbReset(pThis, false);
261 }
262 if (RT_SUCCESS(rc))
263 {
264 if (s_drvTstMouse.pDrv)
265 s_drvTstMouse.pDrv->pfnPutEventMT(s_drvTstMouse.pDrv, 300, 200, 2,
266 3);
267 else
268 rc = VERR_PDM_MISSING_INTERFACE;
269 }
270 if (RT_SUCCESS(rc))
271 {
272 Urb.EndPt = 0x01;
273 rc = g_UsbHidMou.pfnUrbQueue(pThis, &Urb);
274 }
275 if (RT_SUCCESS(rc))
276 {
277 PVUSBURB pUrb = g_UsbHidMou.pfnUrbReap(pThis, 0);
278 if (pUrb)
279 {
280 if (pUrb == &Urb)
281 {
282 if ( Urb.abData[0] != 1 /* Report ID */
283 || Urb.abData[1] != 3 /* Contact flags */
284 || *(uint16_t *)&Urb.abData[2] != 150 /* x >> 1 */
285 || *(uint16_t *)&Urb.abData[4] != 100 /* y >> 1 */
286 || Urb.abData[6] != 2 /* Contact number */)
287 rc = VERR_GENERAL_FAILURE;
288 }
289 else
290 rc = VERR_GENERAL_FAILURE;
291 }
292 else
293 rc = VERR_GENERAL_FAILURE;
294 }
295 RTTEST_CHECK_RC_OK(hTest, rc);
296 if (pThis)
297 g_UsbHidMou.pfnDestruct(pThis);
298}
299#endif
300
301int main()
302{
303 /*
304 * Init the runtime, test and say hello.
305 */
306 RTTEST hTest;
307 PDRVTSTMOUSE pThis;
308 int rc = RTTestInitAndCreate("tstUsbMouse", &hTest);
309 if (rc)
310 return rc;
311 RTTestBanner(hTest);
312 /* Set up our faked PDMUSBHLP interface. */
313 s_tstUsbHlp.pfnVMSetErrorV = tstVMSetErrorV;
314 s_tstUsbHlp.pfnDriverAttach = tstDriverAttach;
315 /* Set up our global mouse driver */
316 s_drvTstMouse.IBase.pfnQueryInterface = tstMouseQueryInterface;
317 s_drvTstMouse.IConnector.pfnReportModes = tstMouseReportModes;
318
319 /*
320 * Run the tests.
321 */
322 testConstructAndDestruct(hTest);
323 testSendPositionRel(hTest);
324 testSendPositionAbs(hTest);
325 /* testSendPositionMT(hTest); */
326 return RTTestSummaryAndDestroy(hTest);
327}
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