diff options
author | Peter Harris <pharris@opentext.com> | 2013-04-24 17:47:14 -0400 |
---|---|---|
committer | Peter Harris <pharris@opentext.com> | 2013-04-24 17:56:08 -0400 |
commit | 2e90f71c12825c0cc35b8786b5b0c8fe2def8fb7 (patch) | |
tree | 0c1444c9711c322c896afe8751b0609ec1589392 | |
parent | f98e35083af0f171aa775ebbc701eb679131ab9f (diff) |
Xlib4: Fix XMapSubwindows test 9
XMapSubwindows-9 creates a number of overlapping sibling windows, then
checks that a GetImage of each window is filled after processing all
Expose events.
This is invalid per the spec, as areas of a GetImage that are obscured
by a sibling are undefined. In particular, current servers intentionally
blank any area obscured by a sibling for security reasons.
Change XMapSubwindows to only verify the parts of the GetImage that are
not obscured by a sibling window.
Signed-off-by: Peter Harris <pharris@opentext.com>
-rw-r--r-- | xts5/Xlib4/XMapSubwindows/XMapSubwindows.m | 22 | ||||
-rw-r--r-- | xts5/include/xtlibproto.h | 2 | ||||
-rw-r--r-- | xts5/src/lib/checkarea.c | 148 |
3 files changed, 171 insertions, 1 deletions
diff --git a/xts5/Xlib4/XMapSubwindows/XMapSubwindows.m b/xts5/Xlib4/XMapSubwindows/XMapSubwindows.m index 7f1e708a..6a582cac 100644 --- a/xts5/Xlib4/XMapSubwindows/XMapSubwindows.m +++ b/xts5/Xlib4/XMapSubwindows/XMapSubwindows.m @@ -1,4 +1,5 @@ Copyright (c) 2005 X.Org Foundation L.L.C. +Copyright (c) Open Text SA and/or Open Text ULC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -822,7 +823,26 @@ int i; for (i = 1; i < NELEM(T1); i++) exposefill(display, bt[i].wid); for (i = 1; i < NELEM(T1); i++) { - if (exposecheck(display, bt[i].wid)) + /* Compute unobscured region */ + int j; + XRectangle rect; + Region sub = makeregion(); + Region rgn = makeregion(); + rect.x = 0; + rect.y = 0; + rect.width = bt[i].width; + rect.height = bt[i].height; + XUnionRectWithRegion(&rect, rgn, rgn); + for (j = i+1; j < NELEM(T1); j++) { + XSubtractRegion(sub, sub, sub); + rect.x = bt[j].x - bt[i].x; + rect.y = bt[j].y - bt[i].y; + rect.width = bt[j].width; + rect.height = bt[j].height; + XUnionRectWithRegion(&rect, sub, sub); + XSubtractRegion(rgn, sub, rgn); + } + if (checkregion(display, bt[i].wid, rgn, W_FG, W_FG, CHECK_IN)) CHECK; else { report("Neither Expose events or backing store processing"); diff --git a/xts5/include/xtlibproto.h b/xts5/include/xtlibproto.h index fdfd443d..33bd1de4 100644 --- a/xts5/include/xtlibproto.h +++ b/xts5/include/xtlibproto.h @@ -207,6 +207,7 @@ int nextsupvis(XVisualInfo **vi); int nsupvis(void); Status checkarea(Display *disp, Drawable d, register struct area *ap, unsigned long inpix, unsigned long outpix, int flags); Status checkclear(Display *disp, Drawable d); +Status checkregion(Display *disp, Drawable d, Region rgn, unsigned long inpix, unsigned long outpix, int flags); void getsize(Display *disp, Drawable d, unsigned int *widthp, unsigned int *heightp); unsigned int getdepth(Display *disp, Drawable d); void pattern(Display *disp, Drawable d); @@ -445,6 +446,7 @@ int nextsupvis(); int nsupvis(); Status checkarea(); Status checkclear(); +Status checkregion(); void getsize(); unsigned int getdepth(); void pattern(); diff --git a/xts5/src/lib/checkarea.c b/xts5/src/lib/checkarea.c index 88934bcd..81bcb345 100644 --- a/xts5/src/lib/checkarea.c +++ b/xts5/src/lib/checkarea.c @@ -1,5 +1,6 @@ /* Copyright (c) 2005 X.Org Foundation L.L.C. +Copyright (c) Open Text SA and/or Open Text ULC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -122,6 +123,7 @@ purpose. It is provided "as is" without express or implied warranty. #include "pixval.h" static void doerr(); +static void dorgnerr(XImage *im, Region rgn, unsigned long inpix, unsigned long outpix, int flags); #define inarea(ap, x, y) \ (\ @@ -136,6 +138,7 @@ static void doerr(); * If flags are CHECK_OUT only the outside is checked. * flags of 0 or CHECK_ALL check both. * If ap is NULL then the whole window is checked. (See also checkclear) + * (See also checkregion) */ Status checkarea(disp, d, ap, inpix, outpix, flags) @@ -241,6 +244,94 @@ Drawable d; } /* + * Same as checkarea, except it takes a 'Region' instead of an 'area' + */ +Status +checkregion(Display *disp, Drawable d, Region rgn, + unsigned long inpix, unsigned long outpix, int flags) +{ +int x, y; +XImage *im; +int xorig; +int yorig; +unsigned int width; +unsigned int height; +unsigned long pix; +int inloopflag = 0; + + if (flags == 0) + flags = CHECK_ALL; + if ((flags & CHECK_ALL) == 0) { + report("assert error in checkregion()"); + printf("assert error in checkregion()\n"); + exit(1); + } + + getsize(disp, d, &width, &height); + + /* + * If a NULL region has been given then error out + */ + if (rgn == NULL) { + report("assert error in checkregion()"); + printf("assert error in checkregion()\n"); + exit(1); + } + + im = XGetImage(disp, d, 0, 0, width, height, AllPlanes, ZPixmap); + if (im == (XImage*)0) { + delete("XGetImage failed"); + return(False); + } + + /* + * If we are only checking inside then only examine that part. + */ + if ((flags & CHECK_ALL) == CHECK_IN) { + XRectangle rect; + XClipBox(rgn, &rect); + xorig = rect.x; + yorig = rect.y; + width = rect.width; + height = rect.height; + } else { + xorig = 0; + yorig = 0; + } + + for (y = yorig; y < yorig+height; y++) { + for (x = xorig; x < xorig+width; x++) { + inloopflag = 1; + pix = XGetPixel(im, x, y); + if (XPointInRegion(rgn, x, y)) { + if (pix != inpix && (flags & CHECK_IN)) { + if (!(flags & CHECK_DIFFER)) + dorgnerr(im, rgn, inpix, outpix, flags); + XDestroyImage(im); + return(False); + } + } else { + if (pix != outpix && (flags & CHECK_OUT)) { + if (!(flags & CHECK_DIFFER)) + dorgnerr(im, rgn, inpix, outpix, flags); + XDestroyImage(im); + return(False); + } + } + } + } + + /* This is to catch bugs */ + if (inloopflag == 0) { + delete("No pixels checked in checkregion - internal error"); + XDestroyImage(im); + return(False); + } + XDestroyImage(im); + return(True); +} + +/* * Make up an error file by faking a known good image. */ static void @@ -301,3 +392,60 @@ extern int Errnum; XDestroyImage(good); XDestroyImage(bad); } + +/* + * Make up an error file by faking a known good image. + */ +static void +dorgnerr(XImage *im, Region rgn, unsigned long inpix, unsigned long outpix, int flags) +{ +XImage *good; +XImage *bad; +int x, y; +char name[32]; +extern int Errnum; + + flags &= CHECK_ALL; + + /* + * Make copies of the image, because we are going to scribble into them. + */ + good = XSubImage(im, 0, 0, im->width, im->height); + bad = XSubImage(im, 0, 0, im->width, im->height); + + for (y = 0; y < im->height; y++) { + for (x = 0; x < im->width; x++) { + /* + * For parts of the image that we are not interested in + * then we set both good and bad to W_BG. + * Otherwise build up a good image. + */ + if (XPointInRegion(rgn, x, y)) { + if (flags & CHECK_IN) { + XPutPixel(good, x, y, inpix); + } else { + XPutPixel(good, x, y, W_BG); + XPutPixel(bad, x, y, W_BG); + } + } else { + if (flags & CHECK_OUT) { + XPutPixel(good, x, y, outpix); + } else { + XPutPixel(good, x, y, W_BG); + XPutPixel(bad, x, y, W_BG); + } + } + } + } + report("Pixel mismatch in image"); + + /* Making up an error file should be a subroutine.. */ + sprintf(name, "Err%04d.err", Errnum++); + report("See file %s for details", name); + unlink(name); + dumpimage(bad, name, (struct area *)0); + dumpimage(good, name, (struct area *)0); + + XDestroyImage(good); + XDestroyImage(bad); +} |