rbd@lamont.ldgo.columbia.edu (roger davis) (01/14/90)
X Window System Bug Report xbugs@expo.lcs.mit.edu VERSION: R4 CLIENT MACHINE and OPERATING SYSTEM: Various Sun/3 and Sun/4 workstations running 4.0.3 DISPLAY TYPE: cgtwo0, cgfour0 WINDOW MANAGER: twm AREA: Xlib/Xsun SYNOPSIS: XCreatePixmapCursor, XDefineCursor DESCRIPTION: When creating and installing a cursor with XCreatePixmapCursor() and XDefineCursor() on a color display, the cursor foreground and background colors are reversed. REPEAT BY: Compile and run the following short program with % cc -o cursor cursor.c -lX11 % cursor This program, which will run on any Sun monochrome or 8-bit color display, creates a 100x100 background-colored window with a small foreground-colored rectangle drawn in its center. An upper-left-pointing foreground-colored arrow cursor is installed. On a monochrome display where foreground is black and background is white, everything works properly -- the black arrow cursor is visible above the white background and invisible above the black foreground rectangle. On a color display, where foreground is set to green and background is set to red, this code breaks -- the arrow cursor is drawn in the red background color instead of the desired green foreground color, and is thus invisible above the red background and visible above the green foreground rectangle. If the fgxc and bgxc arguments to the XCreatePixmapCursor() call are swapped, the problem disappears on the color display. Unfortunately, this breaks on the monochrome display where the program worked properly to begin with. Under X11R3, this program works properly on both color and monochrome Sun displays. /* cursor.c -- demonstrates color cursor problem */ #include <X11/Xlib.h> char *fgstr= "green"; char *bgstr= "red"; main() { Display *dpy; Window win; Cursor curs; Pixmap curspm; unsigned long fgpix, bgpix; XEvent event; int screen; unsigned long plane_mask; Colormap cmap; XColor fgxc, bgxc; XGCValues gcv; GC gc; if ((dpy= XOpenDisplay((char *) 0)) == (Display *) 0) exit(-1); screen= DefaultScreen(dpy); cmap= DefaultColormap(dpy, screen); /* set up foreground and background */ if (DisplayCells(dpy, screen) > 2) { if (XParseColor(dpy, cmap, fgstr, &fgxc) && XParseColor(dpy, cmap, bgstr, &bgxc) && XAllocColorCells(dpy, cmap, True, &plane_mask, 1, &bgpix, 1)) { bgxc.pixel= bgpix; XStoreColor(dpy, cmap, &bgxc); fgxc.pixel= fgpix= bgpix | plane_mask; XStoreColor(dpy, cmap, &fgxc); } else exit(-1); } /* use black and white on a monochrome display */ else { fgxc.pixel= fgpix= BlackPixel(dpy, screen); bgxc.pixel= bgpix= WhitePixel(dpy, screen); } /* create window */ win= XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 100, 100, 100, 100, 2, fgpix, bgpix); /* create and clear cursor pixmap */ curspm= XCreatePixmap(dpy, DefaultRootWindow(dpy), 16, 16, 1); gcv.foreground= 0; gc= XCreateGC(dpy, curspm, GCForeground, &gcv); XFillRectangle(dpy, curspm, gc, 0, 0, 16, 16); /* draw upper-left-pointing arrow into cursor pixmap */ gcv.foreground= 1; gc= XCreateGC(dpy, curspm, GCForeground, &gcv); XDrawLine(dpy, curspm, gc, 0, 0, 15, 15); XDrawLine(dpy, curspm, gc, 0, 0, 0, 5); XDrawLine(dpy, curspm, gc, 0, 0, 5, 0); /* create and install new cursor */ XQueryColor(dpy, cmap, &fgxc); XQueryColor(dpy, cmap, &bgxc); curs= XCreatePixmapCursor(dpy, curspm, curspm, &fgxc, &bgxc, 0, 0); XDefineCursor(dpy, win, curs); /* create a GC to draw the rectangle */ gcv.foreground= fgpix; gc= XCreateGC(dpy, win, GCForeground, &gcv); XSelectInput(dpy, win, ExposureMask); XMapWindow(dpy, win); /* on exposure, draw a small filled rectangle with the foreground color in the middle of an area of background color to aid in the display of the otherwise invisible cursor */ for (;;) { XNextEvent(dpy, &event); if (event.type == Expose) { XClearWindow(dpy, win); XFillRectangle(dpy, win, gc, 30, 30, 40, 40); } } } -- Roger Davis Lamont-Doherty Geological Observatory rbd@lamont.ldgo.columbia.edu
rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (01/14/90)
When creating and installing a cursor with XCreatePixmapCursor() and XDefineCursor() on a color display, the cursor foreground and background colors are reversed. Not quite a correct statement (both colors are sometimes being allocated to the same colormap entry, actually), but there's certainly a bug. This is a software cursor bug (so it won't show up on servers with hardware cursors). The guy who wrote this code clearly didn't think hard enough, I'll have to razz him. I haven't come up with a trivial fix, but I'll note that if the colors have been pre-allocated read-only in the colormap, it will work right.