mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (03/06/91)
X Window System Bug Report xbugs@expo.lcs.mit.edu [copy sent to xpert as well] VERSION: R4 CLIENT MACHINE and OPERATING SYSTEM: N/A DISPLAY TYPE: Any using mfb WINDOW MANAGER: N/A AREA: server SYNOPSIS: mfb CopyPlane doesn't truncate the foreground and background values in the GC to "the appropriate number of bits" as required by the protocol document. DESCRIPTION: mfbCopyPlane tests the fgPixel and bgPixel values in the GC for equality with 1, 0, and one another. Apparently (this is purely inference from the observed behavior), these values have not yet been "truncated to the appropriate number of bits". For example, setting a foreground color of ~0L is not the same as setting a foreground color of 1L. REPEAT BY: Run this program on (against :-) an mfb-based server. Notice that when it does the AND operation, the outer edges remain striped and the inner bar becomes solid (white or black depending on your server). Change the ~0L to 1L and notice that this time, the inner bar is the piece that stays striped. (The latter is the correct behavior, but the presence of any difference is enough to indicate a bug.) #define X 100 #define Y 100 #define W 100 #define H 100 #include <stdio.h> #include <X11/X.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xatom.h> int argc; char **argv; Display *disp; Screen *scr; int width; int height; int depth; Window rootwin; Window win; GC wingc; Pixmap pic; Pixmap mask; GC maskgc; unsigned long int black; unsigned long int white; main(ac,av) int ac; char **av; { int i; unsigned long int attrmask; unsigned long int gcvalmask; XGCValues gcval; XSetWindowAttributes attr; XTextProperty wn_prop; XTextProperty in_prop; XSizeHints normal_hints; XWMHints wm_hints; XClassHint class_hints; XEvent e; /* boilerplate begins here */ disp = XOpenDisplay((char *)0); scr = XDefaultScreenOfDisplay(disp); depth = XDefaultDepthOfScreen(scr); rootwin = XRootWindowOfScreen(scr); white = XWhitePixelOfScreen(scr); black = XBlackPixelOfScreen(scr); attrmask = 0; attr.background_pixel = black; attrmask |= CWBackPixel; attr.border_pixel = white; attrmask |= CWBorderPixel; attr.backing_store = NotUseful; attrmask |= CWBackingStore; attr.event_mask = ExposureMask | ButtonPressMask | ButtonMotionMask; attrmask |= CWEventMask; win = XCreateWindow(disp,rootwin,X,Y,W,H,1,depth,InputOutput,CopyFromParent,attrmask,&attr); wn_prop.value = (unsigned char *) "bug-test"; wn_prop.encoding = XA_STRING; wn_prop.format = 8; wn_prop.nitems = strlen((char *)wn_prop.value); in_prop.value = (unsigned char *) "bug-test"; in_prop.encoding = XA_STRING; in_prop.format = 8; in_prop.nitems = strlen((char *)in_prop.value); normal_hints.flags = PPosition | PSize; normal_hints.x = X; normal_hints.y = Y; normal_hints.width = W; normal_hints.height = H; wm_hints.flags = InputHint; wm_hints.input = False; class_hints.res_name = "bugtest"; class_hints.res_class = "BugTest"; XSetWMProperties(disp,win,&wn_prop,&in_prop,argv,argc,&normal_hints,&wm_hints,&class_hints); XMapRaised(disp,win); /* boilerplate ends. */ /* create a pixmap and a bitmap of appropriate size, and a GC for each */ wingc = XCreateGC(disp,win,0L,&gcval); pic = XCreatePixmap(disp,rootwin,W,H,depth); mask = XCreatePixmap(disp,rootwin,W,H,1); maskgc = XCreateGC(disp,mask,0L,&gcval); /* draw a pattern of diagonal lines in the pixmap */ XSetForeground(disp,wingc,black); XSetFunction(disp,wingc,GXcopy); XFillRectangle(disp,pic,wingc,0,0,W,H); XSetForeground(disp,wingc,white); for (i=0;i<W+H;i+=4) XDrawLine(disp,pic,wingc,i,0,0,i); /* put a vertical bar of 1s in a field of 0s in the bitmap */ XSetForeground(disp,maskgc,0L); XFillRectangle(disp,mask,maskgc,0,0,W,H); XSetForeground(disp,maskgc,1L); XFillRectangle(disp,mask,maskgc,W/3,0,W/3,H); /* wait for an Expose from the window map above */ while (1) { XNextEvent(disp,&e); if (e.type == Expose) break; } /* wait for user confirmation before proceeding */ getchar(); /* display the pixmap in the window */ XCopyArea(disp,pic,win,wingc,0,0,W,H,0,0); /* wait for confirmation */ XSync(disp,True); getchar(); /* AND the pixmap with the bitmap. on an mfb server, this actually ands with the complement of the bitmap; changing ~0L to 1L works. */ XSetForeground(disp,wingc,~0L); XSetBackground(disp,wingc,0L); XSetFunction(disp,wingc,GXand); XCopyPlane(disp,mask,pic,wingc,0,0,W,H,0,0,1L); /* display the masked picture */ XCopyArea(disp,pic,win,wingc,0,0,W,H,0,0); /* let the user look at it */ XSync(disp,True); getchar(); exit(0); } SAMPLE FIX: The following patch to mit/ddx/mfb/mfbbitblt.c works for me. *** mit/ddx/mfb/mfbbitblt.c= Wed Mar 7 10:01:25 1990 --- mit/ddx/mfb/mfbbitblt.c Wed Mar 6 04:47:17 1991 *************** *** 1083,1094 **** if (plane != 1) return NULL; ! if ((pGC->fgPixel == 1) && (pGC->bgPixel == 0)) { prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty); } ! else if (pGC->fgPixel == pGC->bgPixel) { alu = pGC->alu; pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel); --- 1083,1094 ---- if (plane != 1) return NULL; ! if ((pGC->fgPixel & 1) && !(pGC->bgPixel & 1)) { prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty); } ! else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1)) { alu = pGC->alu; pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel); der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu