VirtualBox

source: vbox/trunk/src/VBox/Main/testcase/tstMouseImpl.cpp@ 47841

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

Main/Devices: reverted combined use of two emulated USB devices for reporting absolute events.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
  • Property svn:mergeinfo set to (toggle deleted branches)
    /branches/VBox-3.0/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp58652,​70973
    /branches/VBox-3.2/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp66309,​66318
    /branches/VBox-4.0/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp70873
    /branches/VBox-4.1/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp74233,​78414,​78691,​81841,​82127
    /branches/VBox-4.1/src/VBox/Frontends/VBoxHeadless/VBoxBFE/testcase/tstMouseImpl.cpp82454
    /branches/andy/guestctrl20/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp78916,​78930
    /branches/dsen/gui/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp79076-79078,​79089,​79109-79110,​79112-79113,​79127-79130,​79134,​79141,​79151,​79155,​79157-79159,​79193,​79197
    /branches/dsen/gui2/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp79224,​79228,​79233,​79235,​79258,​79262-79263,​79273,​79341,​79345,​79354,​79357,​79387-79388,​79559-79569,​79572-79573,​79578,​79581-79582,​79590-79591,​79598-79599,​79602-79603,​79605-79606,​79632,​79635,​79637,​79644
    /branches/dsen/gui3/src/VBox/Frontends/VBoxBFE/testcase/tstMouseImpl.cpp79645-79692
File size: 15.6 KB
Line 
1/* $Id: tstMouseImpl.cpp 47841 2013-08-19 13:20:58Z vboxsync $ */
2/** @file
3 * Main unit test - Mouse class.
4 */
5
6/*
7 * Copyright (C) 2011-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#define IN_VMM_R3 /* Kill most Windows warnings on CFGMR3* implementations. */
22#include "MouseImpl.h"
23#include "VMMDev.h"
24#include "DisplayImpl.h"
25
26#include <VBox/vmm/cfgm.h>
27#include <VBox/vmm/pdmdrv.h>
28#include <VBox/VMMDev.h>
29#include <iprt/assert.h>
30#include <iprt/test.h>
31
32#ifndef RT_OS_WINDOWS
33NS_DECL_CLASSINFO(Mouse)
34NS_IMPL_THREADSAFE_ISUPPORTS1_CI(Mouse, IMouse)
35#endif
36
37PDMIVMMDEVPORT VMMDevPort;
38
39class TestVMMDev : public VMMDevMouseInterface
40{
41 PPDMIVMMDEVPORT getVMMDevPort(void) { return &VMMDevPort; }
42};
43
44class TestDisplay : public DisplayMouseInterface
45{
46 void getFramebufferDimensions(int32_t *px1, int32_t *py1,
47 int32_t *px2, int32_t *py2);
48 int getScreenResolution(uint32_t cScreen, ULONG *pcx, ULONG *pcy,
49 ULONG *pcBPP, LONG *pXOrigin, LONG *pYOrigin);
50};
51
52class TestConsole : public ConsoleMouseInterface
53{
54public:
55 VMMDevMouseInterface *getVMMDevMouseInterface() { return &mVMMDev; }
56 DisplayMouseInterface *getDisplayMouseInterface() { return &mDisplay; }
57 /** @todo why on earth is this not implemented? */
58 void onMouseCapabilityChange(BOOL supportsAbsolute, BOOL supportsRelative,
59 BOOL supportsMT, BOOL needsHostCursor) {}
60
61private:
62 TestVMMDev mVMMDev;
63 TestDisplay mDisplay;
64};
65
66static int pdmdrvhlpAttach(PPDMDRVINS pDrvIns, uint32_t fFlags,
67 PPDMIBASE *ppBaseInterface)
68{
69 return VERR_PDM_NO_ATTACHED_DRIVER;
70}
71
72static struct PDMDRVHLPR3 pdmHlpR3 =
73{
74 PDM_DRVHLPR3_VERSION,
75 pdmdrvhlpAttach,
76 NULL, /* pfnDetach */
77 NULL, /* pfnDetachSelf */
78 NULL, /* pfnMountPrepare */
79 NULL, /* pfnAssertEMT */
80 NULL, /* pfnAssertOther */
81 NULL, /* pfnVMSetError */
82 NULL, /* pfnVMSetErrorV */
83 NULL, /* pfnVMSetRuntimeError */
84 NULL, /* pfnVMSetRuntimeErrorV */
85 NULL, /* pfnVMState */
86 NULL, /* pfnVMTeleportedAndNotFullyResumedYet */
87 NULL, /* pfnGetSupDrvSession */
88 NULL, /* pfnQueueCreate */
89 NULL, /* pfnTMGetVirtualFreq */
90 NULL, /* pfnTMGetVirtualTime */
91 NULL, /* pfnTMTimerCreate */
92 NULL, /* pfnSSMRegister */
93 NULL, /* pfnSSMDeregister */
94 NULL, /* pfnDBGFInfoRegister */
95 NULL, /* pfnDBGFInfoDeregister */
96 NULL, /* pfnSTAMRegister */
97 NULL, /* pfnSTAMRegisterF */
98 NULL, /* pfnSTAMRegisterV */
99 NULL, /* pfnSTAMDeregister */
100 NULL, /* pfnSUPCallVMMR0Ex */
101 NULL, /* pfnUSBRegisterHub */
102 NULL, /* pfnSetAsyncNotification */
103 NULL, /* pfnAsyncNotificationCompleted */
104 NULL, /* pfnThreadCreate */
105 NULL, /* pfnAsyncCompletionTemplateCreate */
106#ifdef VBOX_WITH_NETSHAPER
107 NULL, /* pfnNetShaperAttach */
108 NULL, /* pfnNetShaperDetach */
109#endif
110 NULL, /* pfnLdrGetRCInterfaceSymbols */
111 NULL, /* pfnLdrGetR0InterfaceSymbols */
112 NULL, /* pfnCritSectInit */
113 NULL, /* pfnCallR0 */
114 NULL, /* pfnFTSetCheckpoint */
115 NULL, /* pfnBlkCacheRetain */
116 NULL, /* pfnVMGetSuspendReason */
117 NULL, /* pfnVMGetResumeReason */
118 NULL, /* pfnReserved0 */
119 NULL, /* pfnReserved1 */
120 NULL, /* pfnReserved2 */
121 NULL, /* pfnReserved3 */
122 NULL, /* pfnReserved4 */
123 NULL, /* pfnReserved5 */
124 NULL, /* pfnReserved6 */
125 NULL, /* pfnReserved7 */
126 NULL, /* pfnReserved8 */
127 NULL, /* pfnReserved9 */
128 PDM_DRVHLPR3_VERSION /* u32TheEnd */
129};
130
131static struct
132{
133 int32_t dx;
134 int32_t dy;
135 int32_t dz;
136 int32_t dw;
137} mouseEvent;
138
139static int mousePutEvent(PPDMIMOUSEPORT pInterface, int32_t iDeltaX,
140 int32_t iDeltaY, int32_t iDeltaZ, int32_t iDeltaW,
141 uint32_t fButtonStates)
142{
143 mouseEvent.dx = iDeltaX;
144 mouseEvent.dy = iDeltaY;
145 mouseEvent.dz = iDeltaZ;
146 mouseEvent.dw = iDeltaW;
147 return VINF_SUCCESS;
148}
149
150static struct
151{
152 uint32_t cx;
153 uint32_t cy;
154 int32_t dz;
155 int32_t dw;
156 uint32_t fButtonStates;
157} mouseEventAbs;
158
159static int mousePutEventAbs(PPDMIMOUSEPORT pInterface, uint32_t uX,
160 uint32_t uY, int32_t iDeltaZ, int32_t iDeltaW,
161 uint32_t fButtonStates)
162{
163 mouseEventAbs.cx = uX;
164 mouseEventAbs.cy = uY;
165 mouseEventAbs.dz = iDeltaZ;
166 mouseEventAbs.dw = iDeltaW;
167 mouseEventAbs.fButtonStates = fButtonStates;
168 return VINF_SUCCESS;
169}
170
171static struct PDMIMOUSEPORT pdmiMousePort =
172{
173 mousePutEvent,
174 mousePutEventAbs,
175 NULL /* pfnPutEventMT */
176};
177
178static void *pdmiBaseQuery(struct PDMIBASE *pInterface, const char *pszIID)
179{
180 return &pdmiMousePort;
181}
182
183static struct PDMIBASE pdmiBase =
184{
185 pdmiBaseQuery
186};
187
188static struct PDMDRVINS pdmdrvInsCore =
189{
190 PDM_DRVINS_VERSION,
191 0, /* iInstance */
192 NIL_RTRCPTR, /* pHlpRC */
193 NIL_RTRCPTR, /* pvInstanceDataRC */
194 NIL_RTR0PTR, /* pHelpR0 */
195 NIL_RTR0PTR, /* pvInstanceDataR0 */
196 &pdmHlpR3,
197 NULL, /* pvInstanceDataR3 */
198 NIL_RTR3PTR, /* pReg */
199 NIL_RTR3PTR, /* pCfg */
200 &pdmiBase,
201 NULL, /* pDownBase */
202 { /* IBase */
203 NULL /* pfnQueryInterface */
204 },
205 0, /* fTracing */
206 0, /* idTracing */
207#if HC_ARCH_BITS == 32
208 { 0 }, /* au32Padding */
209#endif
210 {
211 { 0 } /* padding */
212 }, /* Internal */
213 { 0 } /* achInstanceData */
214};
215
216static struct PDMDRVINS *ppdmdrvIns = NULL;
217
218ComObjPtr<Mouse> pMouse;
219ConsoleMouseInterface *pConsole = NULL;
220
221static struct
222{
223 int32_t x;
224 int32_t y;
225} absoluteMouse;
226
227static int setAbsoluteMouse(PPDMIVMMDEVPORT, int32_t x, int32_t y)
228{
229 absoluteMouse.x = x;
230 absoluteMouse.y = y;
231 return VINF_SUCCESS;
232}
233
234static int updateMouseCapabilities(PPDMIVMMDEVPORT, uint32_t, uint32_t)
235{
236 return VINF_SUCCESS;
237}
238
239void TestDisplay::getFramebufferDimensions(int32_t *px1, int32_t *py1,
240 int32_t *px2, int32_t *py2)
241{
242 if (px1)
243 *px1 = -320;
244 if (py1)
245 *py1 = -240;
246 if (px2)
247 *px2 = 320;
248 if (py2)
249 *py2 = 240;
250}
251
252int TestDisplay::getScreenResolution(uint32_t cScreen, ULONG *pcx,
253 ULONG *pcy, ULONG *pcBPP, LONG *pXOrigin, LONG *pYOrigin)
254{
255 NOREF(cScreen);
256 if (pcx)
257 *pcx = 640;
258 if (pcy)
259 *pcy = 480;
260 if (pcBPP)
261 *pcBPP = 32;
262 if (pXOrigin)
263 *pXOrigin = 0;
264 if (pYOrigin)
265 *pYOrigin = 0;
266 return S_OK;
267}
268
269/******************************************************************************
270* Main test code *
271******************************************************************************/
272
273static int setup(void)
274{
275 PCFGMNODE pCfg = NULL;
276 Mouse *pMouse2;
277 int rc = VERR_NO_MEMORY;
278 VMMDevPort.pfnSetAbsoluteMouse = setAbsoluteMouse;
279 VMMDevPort.pfnUpdateMouseCapabilities = updateMouseCapabilities;
280 HRESULT hrc = pMouse.createObject();
281 AssertComRC(hrc);
282 if (FAILED(hrc))
283 return VERR_GENERAL_FAILURE;
284 pConsole = new TestConsole;
285 pMouse->init(pConsole);
286 ppdmdrvIns = (struct PDMDRVINS *) RTMemAllocZ( sizeof(struct PDMDRVINS)
287 + Mouse::DrvReg.cbInstance);
288 *ppdmdrvIns = pdmdrvInsCore;
289 pMouse2 = pMouse;
290 pCfg = CFGMR3CreateTree(NULL);
291 if (pCfg)
292 {
293 rc = CFGMR3InsertInteger(pCfg, "Object", (uintptr_t)pMouse2);
294 if (RT_SUCCESS(rc))
295 Mouse::DrvReg.pfnConstruct(ppdmdrvIns, pCfg, 0);
296 }
297 return rc;
298}
299
300static void teardown(void)
301{
302 pMouse.setNull();
303 if (pConsole)
304 delete pConsole;
305 if (ppdmdrvIns)
306 RTMemFree(ppdmdrvIns);
307}
308
309static bool approxEq(int a, int b, int prec)
310{
311 return a - b < prec && b - a < prec;
312}
313
314/** @test testAbsToVMMDevNewProtocol */
315static void testAbsToVMMDevNewProtocol(RTTEST hTest)
316{
317 PPDMIBASE pBase;
318 PPDMIMOUSECONNECTOR pConnector;
319
320 RTTestSub(hTest, "Absolute event to VMMDev, new protocol");
321 pBase = &ppdmdrvIns->IBase;
322 pConnector = (PPDMIMOUSECONNECTOR)pBase->pfnQueryInterface(pBase,
323 PDMIMOUSECONNECTOR_IID);
324 pConnector->pfnReportModes(pConnector, true, false, false);
325 pMouse->onVMMDevGuestCapsChange( VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
326 | VMMDEV_MOUSE_NEW_PROTOCOL);
327 pMouse->PutMouseEventAbsolute(0, 0, 0, 0, 0);
328 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, 0x8000, 200),
329 ("absoluteMouse.x=%d\n", absoluteMouse.x));
330 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, 0x8000, 200),
331 ("absoluteMouse.y=%d\n", absoluteMouse.y));
332 pMouse->PutMouseEventAbsolute(-319, -239, 0, 0, 0);
333 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, 0, 200),
334 ("absoluteMouse.x=%d\n", absoluteMouse.x));
335 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, 0, 200),
336 ("absoluteMouse.y=%d\n", absoluteMouse.y));
337 pMouse->PutMouseEventAbsolute(320, 240, 0, 0, 0);
338 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, 0xffff, 200),
339 ("absoluteMouse.x=%d\n", absoluteMouse.x));
340 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, 0xffff, 200),
341 ("absoluteMouse.y=%d\n", absoluteMouse.y));
342 RTTestSubDone(hTest);
343}
344
345/** @test testAbsToVMMDevOldProtocol */
346static void testAbsToVMMDevOldProtocol(RTTEST hTest)
347{
348 PPDMIBASE pBase;
349 PPDMIMOUSECONNECTOR pConnector;
350
351 RTTestSub(hTest, "Absolute event to VMMDev, old protocol");
352 pBase = &ppdmdrvIns->IBase;
353 pConnector = (PPDMIMOUSECONNECTOR)pBase->pfnQueryInterface(pBase,
354 PDMIMOUSECONNECTOR_IID);
355 pConnector->pfnReportModes(pConnector, true, false, false);
356 pMouse->onVMMDevGuestCapsChange(VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE);
357 pMouse->PutMouseEventAbsolute(320, 240, 0, 0, 0);
358 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, 0x8000, 200),
359 ("absoluteMouse.x=%d\n", absoluteMouse.x));
360 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, 0x8000, 200),
361 ("absoluteMouse.y=%d\n", absoluteMouse.y));
362 pMouse->PutMouseEventAbsolute(0, 0, 0, 0, 0);
363 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, 0, 200),
364 ("absoluteMouse.x=%d\n", absoluteMouse.x));
365 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, 0, 200),
366 ("absoluteMouse.y=%d\n", absoluteMouse.y));
367 pMouse->PutMouseEventAbsolute(-319, -239, 0, 0, 0);
368 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.x, -0x8000, 200),
369 ("absoluteMouse.x=%d\n", absoluteMouse.x));
370 RTTESTI_CHECK_MSG(approxEq(absoluteMouse.y, -0x8000, 200),
371 ("absoluteMouse.y=%d\n", absoluteMouse.y));
372 RTTestSubDone(hTest);
373}
374
375/** @test testAbsToAbsDev */
376static void testAbsToAbsDev(RTTEST hTest)
377{
378 PPDMIBASE pBase;
379 PPDMIMOUSECONNECTOR pConnector;
380
381 RTTestSub(hTest, "Absolute event to absolute device");
382 pBase = &ppdmdrvIns->IBase;
383 pConnector = (PPDMIMOUSECONNECTOR)pBase->pfnQueryInterface(pBase,
384 PDMIMOUSECONNECTOR_IID);
385 pConnector->pfnReportModes(pConnector, false, true, false);
386 pMouse->onVMMDevGuestCapsChange(VMMDEV_MOUSE_NEW_PROTOCOL);
387 pMouse->PutMouseEventAbsolute(0, 0, 0, 0, 0);
388 RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cx, 0x8000, 200),
389 ("mouseEventAbs.cx=%d\n", mouseEventAbs.cx));
390 RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cy, 0x8000, 200),
391 ("mouseEventAbs.cy=%d\n", mouseEventAbs.cy));
392 pMouse->PutMouseEventAbsolute(-319, -239, 0, 0, 3);
393 RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cx, 0, 200),
394 ("mouseEventAbs.cx=%d\n", mouseEventAbs.cx));
395 RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cy, 0, 200),
396 ("mouseEventAbs.cy=%d\n", mouseEventAbs.cy));
397 RTTESTI_CHECK_MSG(mouseEventAbs.fButtonStates == 3,
398 ("mouseEventAbs.fButtonStates=%u\n",
399 (unsigned) mouseEventAbs.fButtonStates));
400 pMouse->PutMouseEventAbsolute(320, 240, -3, 2, 1);
401 RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cx, 0xffff, 200),
402 ("mouseEventAbs.cx=%d\n", mouseEventAbs.cx));
403 RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cy, 0xffff, 200),
404 ("mouseEventAbs.cy=%d\n", mouseEventAbs.cy));
405 RTTESTI_CHECK_MSG(mouseEventAbs.fButtonStates == 1,
406 ("mouseEventAbs.fButtonStates=%u\n",
407 (unsigned) mouseEventAbs.fButtonStates));
408 RTTESTI_CHECK_MSG(mouseEventAbs.dz == -3,
409 ("mouseEventAbs.dz=%d\n", (int) mouseEvent.dz));
410 RTTESTI_CHECK_MSG(mouseEventAbs.dw == 2,
411 ("mouseEventAbs.dw=%d\n", (int) mouseEvent.dw));
412 mouseEventAbs.cx = mouseEventAbs.cy = 0xffff;
413 pMouse->PutMouseEventAbsolute(-640, -480, 0, 0, 0);
414 RTTESTI_CHECK_MSG(mouseEventAbs.cx == 0xffff,
415 ("mouseEventAbs.cx=%d\n", mouseEventAbs.cx));
416 RTTESTI_CHECK_MSG(mouseEventAbs.cy == 0xffff,
417 ("mouseEventAbs.cy=%d\n", mouseEventAbs.cy));
418 RTTestSubDone(hTest);
419}
420
421/** @todo generate this using the @test blocks above */
422typedef void (*PFNTEST)(RTTEST);
423static PFNTEST g_tests[] =
424{
425 testAbsToVMMDevNewProtocol,
426 testAbsToVMMDevOldProtocol,
427 testAbsToAbsDev,
428 NULL
429};
430
431int main(void)
432{
433 /*
434 * Init the runtime, test and say hello.
435 */
436 RTTEST hTest;
437 RTEXITCODE rcExit = RTTestInitAndCreate("tstMouseImpl", &hTest);
438 if (rcExit != RTEXITCODE_SUCCESS)
439 return rcExit;
440 RTTestBanner(hTest);
441
442 /*
443 * Run the tests.
444 */
445 for (unsigned i = 0; g_tests[i]; ++i)
446 {
447 int rc = setup();
448 AssertRC(rc);
449 if (RT_SUCCESS(rc))
450 g_tests[i](hTest);
451 teardown();
452 }
453
454 /*
455 * Summary
456 */
457 return RTTestSummaryAndDestroy(hTest);
458}
459
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