luke@umnstat.stat.umn.edu (Luke Tierney) (10/13/89)
I have run into a problem with clipping in X on color displays and was wondering if anyone out there might be able to help. I have a program that uses an offscreen Pixmap to construct an image and then copies that image into a window. To make some things easier I want to be able to clip some of the drawing in the pixmap and the window to a rectangle. The code I have seems to work fine on monochrome displays but not on color sun or DEC3100 displays. I have narrowed the problem down to the attached short program. The program opens a window. It uses two GC's, one for erasing and one for drawing. The ease_gc has both fore and background color set to WhitePixel, the drawing gc has fore color set to BlackPixel and background to WhitePixel. The window handles only Expose and ButtonPress events. On an expose event it clips the gc's to the size specified for the window erases a rectangle in the the Pixmap by filling with erase_gc fills the same rectangle with black using gc copies the rectangle to the window with XCopyArea On a ButtonPress event it does the same thing but without the clipping. The idea is that the clip region should not have changed since it was set in response to an Expose event. The routine doing the drawing is called `draw'. Expose events call it with clip=TRUE, ButtonPress events with clip=FALSE. On a color sparcstation running MIT R3 with fixes and using twm or olwm as the window manager the window comes up black, as it should, but when I click the mouse in it only the lower right two thirds are black, the rest is white. Exactly how much is black seems to depend on where the window is placed. Under olwm if the window is forced to appear at the top left corner of the screen the amount of the shift in the black area seems to be equal to the border width in the horizontal and the height of the title bar in the vertical direction. The problem does not occur if I use only one gc and change its fore color before each XFillRectangle call. Here is the code; any help would be greatly appreciated. ------------------ #include <X11/Xlib.h> #include <stdio.h> #define TRUE 1 #define FALSE 0 #define TOP 100 #define LEFT 100 #define WIDTH 400 #define HEIGHT 400 Display *dpy; int screen; GC gc, erase_gc; Pixmap WorkPort; Window win; main() { char *display_name = NULL; unsigned long valuemask; XGCValues values; XEvent report; /* connect to X server */ if ((dpy = XOpenDisplay(display_name)) == NULL) { fprintf(stderr, "%s: can't connect to X server %s\n", "bug", XDisplayName(display_name)); exit(-1); } /* get the default screen */ screen = DefaultScreen(dpy); /* make GC's */ valuemask = 0; /* ignore XGCValues and use defaults */ gc = XCreateGC(dpy, RootWindow(dpy, screen), valuemask, &values); XSetForeground(dpy, gc, BlackPixel(dpy, screen)); XSetBackground(dpy, gc, WhitePixel(dpy, screen)); erase_gc = XCreateGC(dpy, RootWindow(dpy, screen), valuemask, &values); XSetForeground(dpy, erase_gc, WhitePixel(dpy, screen)); XSetBackground(dpy, erase_gc, WhitePixel(dpy, screen)); /* create the window */ win = XCreateSimpleWindow(dpy, RootWindow(dpy, screen), LEFT, TOP, WIDTH, HEIGHT, 1, BlackPixel(dpy, screen), WhitePixel(dpy, screen)); XSelectInput(dpy, win, ExposureMask | ButtonPressMask); /* Display (map) the window */ XMapWindow(dpy, win); MakeWorkPort(); while (TRUE) { XNextEvent(dpy, &report); if (win == report.xany.window) { switch(report.type) { case Expose: if (report.xexpose.count == 0) draw(TRUE); break; case ButtonPress: draw(FALSE); break; default: break; } } } } /**************************************************************************/ /** **/ /** Drawing Functions **/ /** **/ /**************************************************************************/ draw(clip) int clip; { XRectangle r; if (clip) { r.x = 0; r.y = 0; r.width = WIDTH; r.height = HEIGHT; XSetClipRectangles(dpy, gc, 0, 0, &r, 1, Unsorted); XSetClipRectangles(dpy, erase_gc, 0, 0, &r, 1, Unsorted); } XFillRectangle(dpy, WorkPort, erase_gc, 0, 0, WIDTH, HEIGHT); XFillRectangle(dpy, WorkPort, gc, 0, 0, WIDTH, HEIGHT); XCopyArea(dpy, WorkPort, win, gc, 0, 0, WIDTH, HEIGHT, 0, 0); } /**************************************************************************/ /** **/ /** Buffering Functions **/ /** **/ /**************************************************************************/ MakeWorkPort() { int width, height; width = DisplayWidth(dpy, screen); height = DisplayHeight(dpy, screen); WorkPort = XCreatePixmap(dpy, RootWindow(dpy, screen), width, height, DefaultDepth(dpy, screen)); /* it is not clear whether this is the proper error check */ if (WorkPort == NULL) { fprintf(stderr, "work port allocation failed"); exit(-1); } }
rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (10/13/89)
On a color sparcstation running MIT R3 with fixes and using twm or olwm as the window manager the window comes up black, as it should, but when I click the mouse in it only the lower right two thirds are black, the rest is white. Works fine on an R4-server-to-be. Looking at our logs, it appears that we have fixed a clipping bug in the cfb code, when switching a gc between a window and a pixmap, but I don't have an easy way of generating a simple diff for you, sorry.