[PATCH xts] Xlib4: Fix XMapSubwindows test 9
Peter Harris
pharris at opentext.com
Mon Apr 29 12:31:42 PDT 2013
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 at opentext.com>
---
This change would have been much smaller (and also a bit riskier) if I
had rewritten checkarea to call checkregion. This would also eliminate
the need for a separate dorgnerr function. I could be persuaded to
refactor and resubmit.
xts5/Xlib4/XMapSubwindows/XMapSubwindows.m | 22 ++++-
xts5/include/xtlibproto.h | 2 +
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 7f1e708..6a582ca 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 fdfd443..33bd1de 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 88934bc..81bcb34 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);
+}
--
1.7.2.5
More information about the xorg-devel
mailing list