VirtualBox

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

Last change on this file since 57442 was 57358, checked in by vboxsync, 9 years ago

*: scm cleanup run.

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