VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp@ 97956

最後變更 在這個檔案從97956是 96407,由 vboxsync 提交於 3 年 前

scm copyright and license note update

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 23.9 KB
 
1/* $Id: tstSeamlessX11-auto.cpp 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * Automated test of the X11 seamless Additions code.
4 * @todo Better separate test data from implementation details!
5 */
6
7/*
8 * Copyright (C) 2007-2022 Oracle and/or its affiliates.
9 *
10 * This file is part of VirtualBox base platform packages, as
11 * available from https://www.alldomusa.eu.org.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation, in version 3 of the
16 * License.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <https://www.gnu.org/licenses>.
25 *
26 * SPDX-License-Identifier: GPL-3.0-only
27 */
28
29#include <stdlib.h> /* exit() */
30
31#include <X11/Xatom.h>
32#include <X11/Xmu/WinUtil.h>
33
34#include <iprt/initterm.h>
35#include <iprt/mem.h>
36#include <iprt/path.h>
37#include <iprt/semaphore.h>
38#include <iprt/stream.h>
39#include <iprt/string.h>
40
41#include "../seamless.h"
42
43#undef DefaultRootWindow
44
45/******************************************************
46* Mock X11 functions needed by the seamless X11 class *
47******************************************************/
48
49int XFree(void *data)
50{
51 RTMemFree(data);
52 return 0;
53}
54
55#define TEST_DISPLAY ((Display *)0xffff)
56#define TEST_ROOT ((Window)1)
57
58void VBClLogError(const char *pszFormat, ...)
59{
60 va_list args;
61 va_start(args, pszFormat);
62 char *psz = NULL;
63 RTStrAPrintfV(&psz, pszFormat, args);
64 va_end(args);
65
66 AssertPtr(psz);
67 RTPrintf("Error: %s", psz);
68
69 RTStrFree(psz);
70}
71
72/** Exit with a fatal error. */
73void VBClLogFatalError(const char *pszFormat, ...)
74{
75 va_list args;
76 va_start(args, pszFormat);
77 char *psz = NULL;
78 RTStrAPrintfV(&psz, pszFormat, args);
79 va_end(args);
80
81 AssertPtr(psz);
82 RTPrintf("Fatal error: %s", psz);
83
84 RTStrFree(psz);
85
86 exit(1);
87}
88
89extern "C" Display *XOpenDisplay(const char *display_name);
90Display *XOpenDisplay(const char *display_name)
91{
92 RT_NOREF1(display_name);
93 return TEST_DISPLAY;
94}
95
96extern "C" int XCloseDisplay(Display *display);
97int XCloseDisplay(Display *display)
98{
99 RT_NOREF1(display);
100 Assert(display == TEST_DISPLAY);
101 return 0;
102}
103
104enum
105{
106 ATOM_PROP = 1,
107 ATOM_DESKTOP_PROP
108};
109
110extern "C" Atom XInternAtom(Display *display, const char *atom_name, Bool only_if_exists);
111Atom XInternAtom(Display *display, const char *atom_name, Bool only_if_exists)
112{
113 RT_NOREF2(only_if_exists, display);
114 Assert(display == TEST_DISPLAY);
115 if (!RTStrCmp(atom_name, WM_TYPE_PROP))
116 return (Atom) ATOM_PROP;
117 if (!RTStrCmp(atom_name, WM_TYPE_DESKTOP_PROP))
118 return (Atom) ATOM_DESKTOP_PROP;
119 AssertFailed();
120 return (Atom)0;
121}
122
123/** The window (if any) on which the WM_TYPE_PROP property is set to the
124 * WM_TYPE_DESKTOP_PROP atom. */
125static Window g_hSmlsDesktopWindow = 0;
126
127extern "C" int XGetWindowProperty(Display *display, Window w, Atom property,
128 long long_offset, long long_length,
129 Bool delProp, Atom req_type,
130 Atom *actual_type_return,
131 int *actual_format_return,
132 unsigned long *nitems_return,
133 unsigned long *bytes_after_return,
134 unsigned char **prop_return);
135int XGetWindowProperty(Display *display, Window w, Atom property,
136 long long_offset, long long_length, Bool delProp,
137 Atom req_type, Atom *actual_type_return,
138 int *actual_format_return,
139 unsigned long *nitems_return,
140 unsigned long *bytes_after_return,
141 unsigned char **prop_return)
142{
143 RT_NOREF2(display, long_length);
144 Assert(display == TEST_DISPLAY);
145 Atom atomType = XInternAtom (display, WM_TYPE_PROP, true);
146 Atom atomTypeDesktop = XInternAtom (display, WM_TYPE_DESKTOP_PROP, true);
147 /* We only handle things we expect. */
148 AssertReturn((req_type == XA_ATOM) || (req_type == AnyPropertyType),
149 0xffff);
150 AssertReturn(property == atomType, 0xffff);
151 *actual_type_return = XA_ATOM;
152 *actual_format_return = sizeof(Atom) * 8;
153 *nitems_return = 0;
154 *bytes_after_return = sizeof(Atom);
155 *prop_return = NULL;
156 if ((w != g_hSmlsDesktopWindow) || (g_hSmlsDesktopWindow == 0))
157 return Success;
158 AssertReturn(long_offset == 0, 0);
159 AssertReturn(delProp == false, 0);
160 unsigned char *pProp;
161 pProp = (unsigned char *)RTMemDup(&atomTypeDesktop,
162 sizeof(atomTypeDesktop));
163 AssertReturn(pProp, 0xffff);
164 *nitems_return = 1;
165 *prop_return = pProp;
166 *bytes_after_return = 0;
167 return 0;
168}
169
170#if 0 /* unused */
171/** Sets the current set of properties for all mock X11 windows */
172static void smlsSetDesktopWindow(Window hWin)
173{
174 g_hSmlsDesktopWindow = hWin;
175}
176#endif
177
178extern "C" Bool XShapeQueryExtension(Display *dpy, int *event_basep, int *error_basep);
179Bool XShapeQueryExtension(Display *dpy, int *event_basep, int *error_basep)
180{
181 RT_NOREF3(dpy, event_basep, error_basep);
182 Assert(dpy == TEST_DISPLAY);
183 return true;
184}
185
186/* We silently ignore this for now. */
187extern "C" int XSelectInput(Display *display, Window w, long event_mask);
188int XSelectInput(Display *display, Window w, long event_mask)
189{
190 RT_NOREF3(display, w, event_mask);
191 Assert(display == TEST_DISPLAY);
192 return 0;
193}
194
195/* We silently ignore this for now. */
196extern "C" void XShapeSelectInput(Display *display, Window w, unsigned long event_mask);
197void XShapeSelectInput(Display *display, Window w, unsigned long event_mask)
198{
199 RT_NOREF3(display, w, event_mask);
200 Assert(display == TEST_DISPLAY);
201}
202
203extern "C" Window XDefaultRootWindow(Display *display);
204Window XDefaultRootWindow(Display *display)
205{
206 RT_NOREF1(display);
207 Assert(display == TEST_DISPLAY);
208 return TEST_ROOT;
209}
210
211static unsigned g_cSmlsWindows = 0;
212static Window *g_paSmlsWindows = NULL;
213static XWindowAttributes *g_paSmlsWinAttribs = NULL;
214static const char **g_papszSmlsWinNames = NULL;
215
216extern "C" Status XQueryTree(Display *display, Window w, Window *root_return,
217 Window *parent_return, Window **children_return,
218 unsigned int *nchildren_return);
219Status XQueryTree(Display *display, Window w, Window *root_return,
220 Window *parent_return, Window **children_return,
221 unsigned int *nchildren_return)
222{
223 RT_NOREF1(display);
224 Assert(display == TEST_DISPLAY);
225 AssertReturn(w == TEST_ROOT, False); /* We support nothing else */
226 AssertPtrReturn(children_return, False);
227 AssertReturn(g_paSmlsWindows, False);
228 if (root_return)
229 *root_return = TEST_ROOT;
230 if (parent_return)
231 *parent_return = TEST_ROOT;
232 *children_return = (Window *)RTMemDup(g_paSmlsWindows,
233 g_cSmlsWindows * sizeof(Window));
234 if (nchildren_return)
235 *nchildren_return = g_cSmlsWindows;
236 return (g_cSmlsWindows != 0);
237}
238
239extern "C" Window XmuClientWindow(Display *dpy, Window win);
240Window XmuClientWindow(Display *dpy, Window win)
241{
242 RT_NOREF1(dpy);
243 Assert(dpy == TEST_DISPLAY);
244 return win;
245}
246
247extern "C" Status XGetWindowAttributes(Display *display, Window w,
248 XWindowAttributes *window_attributes_return);
249Status XGetWindowAttributes(Display *display, Window w,
250 XWindowAttributes *window_attributes_return)
251{
252 RT_NOREF1(display);
253 Assert(display == TEST_DISPLAY);
254 AssertPtrReturn(window_attributes_return, 1);
255 for (unsigned i = 0; i < g_cSmlsWindows; ++i)
256 if (g_paSmlsWindows[i] == w)
257 {
258 *window_attributes_return = g_paSmlsWinAttribs[i];
259 return 1;
260 }
261 return 0;
262}
263
264extern "C" Status XGetWMNormalHints(Display *display, Window w,
265 XSizeHints *hints_return,
266 long *supplied_return);
267
268Status XGetWMNormalHints(Display *display, Window w,
269 XSizeHints *hints_return, long *supplied_return)
270{
271 RT_NOREF4(display, w, hints_return, supplied_return);
272 Assert(display == TEST_DISPLAY);
273 return 1;
274}
275
276static void smlsSetWindowAttributes(XWindowAttributes *pAttribs,
277 Window *pWindows, unsigned cAttribs,
278 const char **paNames)
279{
280 g_paSmlsWinAttribs = pAttribs;
281 g_paSmlsWindows = pWindows;
282 g_cSmlsWindows = cAttribs;
283 g_papszSmlsWinNames = paNames;
284}
285
286static Window g_SmlsShapedWindow = 0;
287static int g_cSmlsShapeRectangles = 0;
288static XRectangle *g_pSmlsShapeRectangles = NULL;
289
290extern "C" XRectangle *XShapeGetRectangles (Display *dpy, Window window,
291 int kind, int *count,
292 int *ordering);
293XRectangle *XShapeGetRectangles (Display *dpy, Window window, int kind,
294 int *count, int *ordering)
295{
296 RT_NOREF2(dpy, kind);
297 Assert(dpy == TEST_DISPLAY);
298 if ((window != g_SmlsShapedWindow) || (window == 0))
299 return NULL; /* Probably not correct, but works for us. */
300 *count = g_cSmlsShapeRectangles;
301 *ordering = 0;
302 return (XRectangle *)RTMemDup(g_pSmlsShapeRectangles,
303 sizeof(XRectangle)
304 * g_cSmlsShapeRectangles);
305}
306
307static void smlsSetShapeRectangles(Window window, int cRects,
308 XRectangle *pRects)
309{
310 g_SmlsShapedWindow = window;
311 g_cSmlsShapeRectangles = cRects;
312 g_pSmlsShapeRectangles = pRects;
313}
314
315static int g_SmlsEventType = 0;
316static Window g_SmlsEventWindow = 0;
317
318/* This should not be needed in the bits of the code we test. */
319extern "C" int XNextEvent(Display *display, XEvent *event_return);
320int XNextEvent(Display *display, XEvent *event_return)
321{
322 RT_NOREF1(display);
323 Assert(display == TEST_DISPLAY);
324 event_return->xany.type = g_SmlsEventType;
325 event_return->xany.window = g_SmlsEventWindow;
326 event_return->xmap.window = g_SmlsEventWindow;
327 return True;
328}
329
330/* Mock XPending(): this also should not be needed. Just in case, always
331 * return that at least one event is pending to be processed. */
332extern "C" int XPending(Display *display);
333int XPending(Display *display)
334{
335 RT_NOREF1(display);
336 return 1;
337}
338
339static void smlsSetNextEvent(int type, Window window)
340{
341 g_SmlsEventType = type;
342 g_SmlsEventWindow = window;
343}
344
345/* This should not be needed in the bits of the code we test. */
346extern "C" Status XSendEvent(Display *display, Window w, Bool propagate,
347 long event_mask, XEvent *event_send);
348Status XSendEvent(Display *display, Window w, Bool propagate,
349 long event_mask, XEvent *event_send)
350{
351 RT_NOREF5(display, w, propagate, event_mask, event_send);
352 Assert(display == TEST_DISPLAY);
353 AssertFailedReturn(0);
354}
355
356/* This should not be needed in the bits of the code we test. */
357extern "C" int XFlush(Display *display);
358int XFlush(Display *display)
359{
360 RT_NOREF1(display);
361 Assert(display == TEST_DISPLAY);
362 AssertFailedReturn(0);
363}
364
365/** Global "received a notification" flag. */
366static bool g_fNotified = false;
367
368/** Dummy host call-back. */
369static void sendRegionUpdate(RTRECT *pRects, size_t cRects)
370{
371 RT_NOREF2(pRects, cRects);
372 g_fNotified = true;
373}
374
375static bool gotNotification(void)
376{
377 if (!g_fNotified)
378 return false;
379 g_fNotified = false;
380 return true;
381}
382
383/*****************************
384* The actual tests to be run *
385*****************************/
386
387/** The name of the unit test */
388static const char *g_pszTestName = NULL;
389
390/*** Test fixture data and data structures ***/
391
392/** A structure describing a test fixture to be run through. Each fixture
393 * describes the state of the windows visible (and unmapped) on the X server
394 * before and after a particular event is delivered, and the expected
395 * on-screen positions of all interesting visible windows at the end of the
396 * fixture as reported by the code (currently in the order it is likely to
397 * report them in, @todo sort this). We expect that the set of visible
398 * windows will be the same whether we start the code before the event and
399 * handle it or start the code after the event.
400 */
401struct SMLSFIXTURE
402{
403 /** The number of windows visible before the event */
404 unsigned cWindowsBefore;
405 /** An array of Window IDs for the visible and unmapped windows before
406 * the event */
407 Window *pahWindowsBefore;
408 /** The window attributes matching the windows in @a paWindowsBefore */
409 XWindowAttributes *paAttribsBefore;
410 /** The window names matching the windows in @a paWindowsBefore */
411 const char **papszNamesBefore;
412 /** The shaped window before the event - we allow at most one of these.
413 * Zero for none. */
414 Window hShapeWindowBefore;
415 /** The number of rectangles in the shaped window before the event. */
416 int cShapeRectsBefore;
417 /** The rectangles in the shaped window before the event */
418 XRectangle *paShapeRectsBefore;
419 /** The number of windows visible after the event */
420 unsigned cWindowsAfter;
421 /** An array of Window IDs for the visible and unmapped windows after
422 * the event */
423 Window *pahWindowsAfter;
424 /** The window attributes matching the windows in @a paWindowsAfter */
425 XWindowAttributes *paAttribsAfter;
426 /** The window names matching the windows in @a paWindowsAfter */
427 const char **papszNamesAfter;
428 /** The shaped window after the event - we allow at most one of these.
429 * Zero for none. */
430 Window hShapeWindowAfter;
431 /** The number of rectangles in the shaped window after the event. */
432 int cShapeRectsAfter;
433 /** The rectangles in the shaped window after the event */
434 XRectangle *paShapeRectsAfter;
435 /** The event to delivered */
436 int x11EventType;
437 /** The window for which the event in @enmEvent is delivered */
438 Window hEventWindow;
439 /** The number of windows expected to be reported at the end of the
440 * fixture */
441 unsigned cReportedRects;
442 /** The onscreen positions of those windows. */
443 RTRECT *paReportedRects;
444 /** Do we expect notification after the event? */
445 bool fExpectNotification;
446};
447
448/*** Test fixture to test the code against X11 configure (move) events ***/
449
450static Window g_ahWin1[] = { 20 };
451static XWindowAttributes g_aAttrib1Before[] =
452{ { 100, 200, 200, 300, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IsViewable }
453};
454static XRectangle g_aRectangle1[] =
455{
456 { 0, 0, 50, 50 },
457 { 50, 50, 150, 250 }
458};
459static XWindowAttributes g_aAttrib1After[] =
460{ { 200, 300, 200, 300, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IsViewable }
461};
462static const char *g_apszNames1[] = { "Test Window" };
463
464AssertCompile(RT_ELEMENTS(g_ahWin1) == RT_ELEMENTS(g_aAttrib1Before));
465AssertCompile(RT_ELEMENTS(g_ahWin1) == RT_ELEMENTS(g_aAttrib1After));
466AssertCompile(RT_ELEMENTS(g_ahWin1) == RT_ELEMENTS(g_apszNames1));
467
468static RTRECT g_aRects1[] =
469{
470 { 200, 300, 250, 350 },
471 { 250, 350, 400, 600 }
472};
473
474static SMLSFIXTURE g_testMove =
475{
476 RT_ELEMENTS(g_ahWin1),
477 g_ahWin1,
478 g_aAttrib1Before,
479 g_apszNames1,
480 20,
481 RT_ELEMENTS(g_aRectangle1),
482 g_aRectangle1,
483 RT_ELEMENTS(g_ahWin1),
484 g_ahWin1,
485 g_aAttrib1After,
486 g_apszNames1,
487 20,
488 RT_ELEMENTS(g_aRectangle1),
489 g_aRectangle1,
490 ConfigureNotify,
491 20,
492 RT_ELEMENTS(g_aRects1),
493 g_aRects1,
494 true
495};
496
497/*** Test fixture to test the code against X11 configure (resize) events ***/
498
499static XWindowAttributes g_aAttrib2Before[] =
500{ { 100, 200, 200, 300, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IsViewable }
501};
502static XRectangle g_aRectangle2Before[] =
503{
504 { 0, 0, 50, 50 },
505 { 50, 50, 100, 100 }
506};
507
508AssertCompile(RT_ELEMENTS(g_ahWin1) == RT_ELEMENTS(g_aAttrib2Before));
509
510static SMLSFIXTURE g_testResize =
511{
512 RT_ELEMENTS(g_ahWin1),
513 g_ahWin1,
514 g_aAttrib2Before,
515 g_apszNames1,
516 20,
517 RT_ELEMENTS(g_aRectangle2Before),
518 g_aRectangle2Before,
519 RT_ELEMENTS(g_ahWin1),
520 g_ahWin1,
521 g_aAttrib1After,
522 g_apszNames1,
523 20,
524 RT_ELEMENTS(g_aRectangle1),
525 g_aRectangle1,
526 ConfigureNotify,
527 20,
528 RT_ELEMENTS(g_aRects1),
529 g_aRects1,
530 true
531};
532
533/*** Test fixture to test the code against X11 map events ***/
534
535static XWindowAttributes g_aAttrib3Before[] =
536{ { 200, 300, 200, 300, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IsUnmapped }
537};
538
539AssertCompile(RT_ELEMENTS(g_ahWin1) == RT_ELEMENTS(g_aAttrib3Before));
540
541static SMLSFIXTURE g_testMap =
542{
543 RT_ELEMENTS(g_ahWin1),
544 g_ahWin1,
545 g_aAttrib3Before,
546 g_apszNames1,
547 20,
548 RT_ELEMENTS(g_aRectangle1),
549 g_aRectangle1,
550 RT_ELEMENTS(g_ahWin1),
551 g_ahWin1,
552 g_aAttrib1After,
553 g_apszNames1,
554 20,
555 RT_ELEMENTS(g_aRectangle1),
556 g_aRectangle1,
557 MapNotify,
558 20,
559 RT_ELEMENTS(g_aRects1),
560 g_aRects1,
561 true
562};
563
564/*** Test fixtures to test the code against X11 unmap events ***/
565
566static XWindowAttributes g_aAttrib4After[] =
567{ { 100, 200, 300, 400, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IsUnmapped }
568};
569
570AssertCompile(RT_ELEMENTS(g_ahWin1) == RT_ELEMENTS(g_aAttrib4After));
571
572static SMLSFIXTURE g_testUnmap =
573{
574 RT_ELEMENTS(g_ahWin1),
575 g_ahWin1,
576 g_aAttrib1Before,
577 g_apszNames1,
578 20,
579 RT_ELEMENTS(g_aRectangle1),
580 g_aRectangle1,
581 RT_ELEMENTS(g_ahWin1),
582 g_ahWin1,
583 g_aAttrib4After,
584 g_apszNames1,
585 20,
586 RT_ELEMENTS(g_aRectangle1),
587 g_aRectangle1,
588 UnmapNotify,
589 20,
590 0,
591 NULL,
592 true
593};
594
595/*** A window we are not monitoring has been unmapped. Nothing should
596 *** happen, especially nothing bad. ***/
597
598static RTRECT g_aRects2[] =
599{
600 { 100, 200, 150, 250 },
601 { 150, 250, 300, 500 }
602};
603
604static SMLSFIXTURE g_testUnmapOther =
605{
606 RT_ELEMENTS(g_ahWin1),
607 g_ahWin1,
608 g_aAttrib1Before,
609 g_apszNames1,
610 20,
611 RT_ELEMENTS(g_aRectangle1),
612 g_aRectangle1,
613 RT_ELEMENTS(g_ahWin1),
614 g_ahWin1,
615 g_aAttrib1Before,
616 g_apszNames1,
617 20,
618 RT_ELEMENTS(g_aRectangle1),
619 g_aRectangle1,
620 UnmapNotify,
621 21,
622 RT_ELEMENTS(g_aRects2),
623 g_aRects2,
624 false
625};
626
627/*** Test fixture to test the code against X11 shape events ***/
628
629static XRectangle g_aRectangle5Before[] =
630{
631 { 0, 0, 200, 200 }
632};
633
634static SMLSFIXTURE g_testShape =
635{
636 RT_ELEMENTS(g_ahWin1),
637 g_ahWin1,
638 g_aAttrib1After,
639 g_apszNames1,
640 20,
641 RT_ELEMENTS(g_aRectangle5Before),
642 g_aRectangle5Before,
643 RT_ELEMENTS(g_ahWin1),
644 g_ahWin1,
645 g_aAttrib1After,
646 g_apszNames1,
647 20,
648 RT_ELEMENTS(g_aRectangle1),
649 g_aRectangle1,
650 VBoxShapeNotify,
651 20,
652 RT_ELEMENTS(g_aRects1),
653 g_aRects1,
654 true
655};
656
657/*** And the test code proper ***/
658
659/** Compare two RTRECT structures */
660static bool smlsCompRect(RTRECT *pFirst, RTRECT *pSecond)
661{
662 return ( (pFirst->xLeft == pSecond->xLeft)
663 && (pFirst->yTop == pSecond->yTop)
664 && (pFirst->xRight == pSecond->xRight)
665 && (pFirst->yBottom == pSecond->yBottom));
666}
667
668static void smlsPrintDiffRects(RTRECT *pExp, RTRECT *pGot)
669{
670 RTPrintf(" Expected: %d, %d, %d, %d. Got: %d, %d, %d, %d\n",
671 pExp->xLeft, pExp->yTop, pExp->xRight, pExp->yBottom,
672 pGot->xLeft, pGot->yTop, pGot->xRight, pGot->yBottom);
673}
674
675/** Run through a test fixture */
676static unsigned smlsDoFixture(SMLSFIXTURE *pFixture, const char *pszDesc)
677{
678 SeamlessX11 subject;
679 unsigned cErrs = 0;
680
681 subject.init(sendRegionUpdate);
682 smlsSetWindowAttributes(pFixture->paAttribsBefore,
683 pFixture->pahWindowsBefore,
684 pFixture->cWindowsBefore,
685 pFixture->papszNamesBefore);
686 smlsSetShapeRectangles(pFixture->hShapeWindowBefore,
687 pFixture->cShapeRectsBefore,
688 pFixture->paShapeRectsBefore);
689 subject.start();
690 smlsSetWindowAttributes(pFixture->paAttribsAfter,
691 pFixture->pahWindowsAfter,
692 pFixture->cWindowsAfter,
693 pFixture->papszNamesAfter);
694 smlsSetShapeRectangles(pFixture->hShapeWindowAfter,
695 pFixture->cShapeRectsAfter,
696 pFixture->paShapeRectsAfter);
697 smlsSetNextEvent(pFixture->x11EventType, pFixture->hEventWindow);
698 if (gotNotification()) /* Initial window tree rebuild */
699 {
700 RTPrintf("%s: fixture: %s. Notification was set before the first event!!!\n",
701 g_pszTestName, pszDesc);
702 ++cErrs;
703 }
704 subject.nextConfigurationEvent();
705 if (!gotNotification())
706 {
707 RTPrintf("%s: fixture: %s. No notification was sent for the initial window tree rebuild.\n",
708 g_pszTestName, pszDesc);
709 ++cErrs;
710 }
711 smlsSetNextEvent(0, 0);
712 subject.nextConfigurationEvent();
713 if (pFixture->fExpectNotification && !gotNotification())
714 {
715 RTPrintf("%s: fixture: %s. No notification was sent after the event.\n",
716 g_pszTestName, pszDesc);
717 ++cErrs;
718 }
719 RTRECT *pRects = subject.getRects();
720 size_t cRects = subject.getRectCount();
721 if (cRects != pFixture->cReportedRects)
722 {
723 RTPrintf("%s: fixture: %s. Wrong number of rectangles reported after processing event (expected %u, got %u).\n",
724 g_pszTestName, pszDesc, pFixture->cReportedRects,
725 cRects);
726 ++cErrs;
727 }
728 else
729 for (unsigned i = 0; i < cRects; ++i)
730 if (!smlsCompRect(&pRects[i], &pFixture->paReportedRects[i]))
731 {
732 RTPrintf("%s: fixture: %s. Rectangle %u wrong after processing event.\n",
733 g_pszTestName, pszDesc, i);
734 smlsPrintDiffRects(&pFixture->paReportedRects[i],
735 &pRects[i]);
736 ++cErrs;
737 break;
738 }
739 subject.stop();
740 subject.start();
741 if (cRects != pFixture->cReportedRects)
742 {
743 RTPrintf("%s: fixture: %s. Wrong number of rectangles reported without processing event (expected %u, got %u).\n",
744 g_pszTestName, pszDesc, pFixture->cReportedRects,
745 cRects);
746 ++cErrs;
747 }
748 else
749 for (unsigned i = 0; i < cRects; ++i)
750 if (!smlsCompRect(&pRects[i], &pFixture->paReportedRects[i]))
751 {
752 RTPrintf("%s: fixture: %s. Rectangle %u wrong without processing event.\n",
753 g_pszTestName, pszDesc, i);
754 smlsPrintDiffRects(&pFixture->paReportedRects[i],
755 &pRects[i]);
756 ++cErrs;
757 break;
758 }
759 return cErrs;
760}
761
762int main(int argc, char **argv)
763{
764 RTR3InitExe(argc, &argv, 0);
765 unsigned cErrs = 0;
766 g_pszTestName = RTPathFilename(argv[0]);
767
768 RTPrintf("%s: TESTING\n", g_pszTestName);
769
770/** @todo r=bird: This testcase is broken and we didn't notice because we
771 * don't run it on the testboxes! @bugref{9842} */
772if (argc == 1)
773{
774 RTPrintf("%s: Note! This testcase is broken, skipping!\n", g_pszTestName);
775 return RTEXITCODE_SUCCESS;
776}
777
778 cErrs += smlsDoFixture(&g_testMove,
779 "ConfigureNotify event (window moved)");
780 // Currently not working
781 cErrs += smlsDoFixture(&g_testResize,
782 "ConfigureNotify event (window resized)");
783 cErrs += smlsDoFixture(&g_testMap, "MapNotify event");
784 cErrs += smlsDoFixture(&g_testUnmap, "UnmapNotify event");
785 cErrs += smlsDoFixture(&g_testUnmapOther,
786 "UnmapNotify event for unmonitored window");
787 cErrs += smlsDoFixture(&g_testShape, "ShapeNotify event");
788 if (cErrs > 0)
789 RTPrintf("%u errors\n", cErrs);
790 return cErrs == 0 ? 0 : 1;
791}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette