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.edurws@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.