markv@pixar.com (Mark VandeWettering) (04/11/91)
I am having trouble with a current project that requires the use of a 24 bit directcolor visual under X windows. Everytime I do a XCreateWindow, I get a XBadMatch error, which I cannot figure out the cause of. (gosh, leave that preposition dangling). The steps I need to do is: 1. Use XMatchVisual to decide if a 24 bit visual is available (it is not my default visual) 2. Use XCreateWindow to create a window. 3. Create an XImage to be used with the window. If anyone has a simple program or program fragment that you know works, then please send it to me. I am also open to any hints on how to proceed, as I am strictly a novice X programmer. If it helps, I have tested this on an HP9000 300 series, which supports X11R3. Thanks in advance. Mark VandeWettering (markv%pixar.uucp@ucbvax.berkeley.edu)
rthomson@mesa.dsd.es.com (Rich Thomson) (04/14/91)
In article <1991Apr10.190204.20085@pixar.com> markv@pixar.com (Mark VandeWettering) writes: >I am having trouble with a current project that requires the use of a >24 bit directcolor visual under X windows. Everytime I do a XCreateWindow, >I get a XBadMatch error, which I cannot figure out the cause of. (gosh, >leave that preposition dangling). > >The steps I need to do is: > > 1. Use XMatchVisual to decide if a 24 bit visual is available > (it is not my default visual) > 2. Use XCreateWindow to create a window. > 3. Create an XImage to be used with the window. Try creating a colormap and explicitly setting the colormap, foreground/background pixel entries in the window attributes structure. Chances are you're getting a bad match because the root window isn't the same visual type as your directcolor window. If you don't supply the needed attributes the server attempts to inherit them from the parent window (I assume the root window in your case), where they won't be properly matched for the new window's visual. Here's a little program that opens up a directcolor window on our server (which supports TrueColor, DirectColor and PseudoColor visuals). This program is from the MIT X11R4 contrib software. -- Rich /* * worm.c: draw wiggly worms. * * Adapted from a concept in the Dec 87 issue of Scientific American. * Makes a nice lockscreen via "lockscreen nice worm". * * compile: cc worm.c -o worm -lm -lsuntool -lsunwindow -lpixrect * * usage: worm [-l length] [-s size] [-n number] * where "length" is length of each worm in segments (default 50) * "size" is size of each segment (default 2) * "number" is number of worms to draw (default 64) * * This program looks best on a color monitor. Try these options: * worm -n 1 Just one really fast worm * worm -l 2 Paramecia * worm -s 500 Mondrian painting (actually enormous worms) * worm -l -1 Jackson Pollack painting (actually infinite length worms) * * -- Thu Dec 17 09:58:48 PST 1987 * -- Brad Taylor (brad@sun) */ /* * hacked to use X11 by Dave Lemke (lemke@sun.com) * Wed Dec 23 09:57:32 PST 1987 * * additional options: * -S -R -C [-g geometry] [-d display] * * -S screen saver mode - covers screen * -R rotate colormap while running * -C chromocolor worms - colors change as they crawl */ /************************************************************ Copyright 1988 by Sun Microsystems, Inc. Mountain View, CA. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Sun or MIT not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. Sun and M.I.T. make no representations about the suitability of this software for any purpose. It is provided "as is" without any express or implied warranty. SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ************************************************************/ #include <stdio.h> #include <sys/types.h> #include <math.h> #include <X11/Xos.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #define NUM_COLORS 256 #define MIN_COLORS 16 #define SEGMENTS 36 #define PI 3.14159265358979323844 extern char *malloc(); extern long random(); typedef struct _wormstuff { int *xcirc; int *ycirc; int dir; int tail; int x; int y; } wormstuff; wormstuff *worm_init(); int wormlength = 50; int circsize = 2; int nworms = 64; int sintab[SEGMENTS]; int costab[SEGMENTS]; int ncolors; XWMHints xwmh = { (InputHint | StateHint), True, NormalState, 0, 0, 0, 0, 0, 0, }; Display *dpy; Window w; int screen; GC gc, wgc; Colormap cmap; Bool is_color = True; Bool is_dynamic = False; Bool screen_saver = False; Bool rotate = False; Bool chromocolor = False; XColor colors[NUM_COLORS]; extern char *getenv(); char *defgeo = "=500x500+10+10"; Visual *visual; int depth = 1; long backpixel; Atom protocol_atom, kill_atom; main(argc, argv) int argc; char **argv; { char *display = NULL; char *geo = NULL; int xsize = 500; int ysize = 500; int x = 0, y = 0; register int i; wormstuff **worm; char *cmd; char c; extern int optind; extern char *optarg; XSizeHints xsh; XWindowAttributes xwa; int vmask; XSetWindowAttributes values; Bool freeze = False; Bool is_visible = True; cmd = argv[0]; while ((c = getopt(argc, argv, "SCRl:n:g:d:s:")) != EOF) switch(c) { case 'l': wormlength = atoi(optarg); break; case 'n': nworms = atoi(optarg); break; case 's': circsize = atoi(optarg); break; case 'd': display = optarg; break; case 'g': geo = optarg; break; case 'S': screen_saver = True; break; case 'C': chromocolor = True; break; case 'R': rotate = True; break; case '?': usage(cmd); } srandom(getpid()); for (i = 0; i < SEGMENTS; i++) { sintab[i] = round(circsize * sin(i * 2 * PI / SEGMENTS)); costab[i] = round(circsize * cos(i * 2 * PI / SEGMENTS)); } if ((dpy = XOpenDisplay(display)) == NULL) { fprintf(stderr,"Can\'t open %s\n", (display ? display : getenv("DISPLAY"))); exit(0); } screen = DefaultScreen(dpy); ncolors = NUM_COLORS; if (screen_saver) { xsize = DisplayWidth(dpy, screen); ysize = DisplayHeight(dpy, screen); x = 0; y = 0; } else { int flags; if (geo == NULL) geo = defgeo; flags = XParseGeometry(geo, &x, &y, &xsize, &ysize); if ((flags & XValue) && (flags & XNegative)) x += DisplayWidth(dpy, screen) - xsize; if ((flags & YValue) && (flags & YNegative)) y += DisplayHeight(dpy, screen) - ysize; } visual = DefaultVisual(dpy, screen); depth = DefaultDepth(dpy, screen); cmap = DefaultColormap(dpy, screen); /* set up the color map */ if (DisplayCells(dpy, screen) > 2) cmap_init(w); else { is_color = False; backpixel = BlackPixel(dpy, screen); } vmask = CWBackPixel | CWColormap; values.background_pixel = backpixel; values.colormap = cmap; w = XCreateWindow(dpy, RootWindow(dpy, screen), x, y, xsize, ysize, 0, depth, InputOutput, visual, vmask, &values); xsh.flags = (PPosition | PSize); xsh.x = x; xsh.y = y; xsh.width = xsize; xsh.height = ysize; XSetStandardProperties(dpy, w, "Worms", "Worms", None, argv, argc, &xsh); XSetWMHints(dpy, w, &xwmh); protocol_atom = XInternAtom(dpy, "WM_PROTOCOLS", False); kill_atom = XInternAtom(dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(dpy, w, &kill_atom, 1); XMapRaised(dpy, w); XSelectInput(dpy, w, ExposureMask | StructureNotifyMask | #ifdef DUMB_WM EnterWindowMask | LeaveWindowMask | #endif KeyPressMask | VisibilityChangeMask); gc = XCreateGC(dpy, w, 0, 0); wgc = XCreateGC(dpy, w, 0, 0); XSetForeground(dpy, wgc, WhitePixel(dpy, screen)); worm = (wormstuff **)malloc((unsigned)(sizeof(wormstuff) * nworms)); for (i = 0; i < nworms; i++) { worm[i] = worm_init(xsize, ysize, wormlength); } for (;;) { XEvent e; register int wcolor, chromo; /* chromo looks best with HSB */ if (XPending(dpy)) { XNextEvent(dpy, &e); if (e.type == VisibilityNotify) { XVisibilityEvent *ev = (XVisibilityEvent *) &e; if (ev->state == VisibilityFullyObscured) is_visible = False; else is_visible = True; } else if (e.type == KeyPress) { if (freeze == False) freeze = True; else freeze = False; } else if (e.type == ConfigureNotify) { XConfigureEvent *ev = (XConfigureEvent *) &e; xsize = ev->width; ysize = ev->height; for (i = 0; i < nworms; i++) { free(worm[i]->xcirc); free(worm[i]->ycirc); free(worm[i]); worm[i] = worm_init(xsize, ysize, wormlength); } XClearWindow(dpy, w); /* really want to remove all the pending graphics requests - can't figure out * how... * attempted to use GraphicsExposure, but it put so much crap into the * queue that the configure was never found... */ XFlush(dpy); } else if (e.type == ClientMessage) { XClientMessageEvent *ev = (XClientMessageEvent *)&e; if (ev->message_type == protocol_atom && ev->data.l[0] == kill_atom) exit(0); } #ifdef DUMB_WM else if (e.type == EnterNotify) XInstallColormap(dpy, cmap); else if (e.type == LeaveNotify) XUninstallColormap(dpy, cmap); #endif /* * since visibvility notify doesn't allow for * the totally obscured -> partially obscured * case, we have to depend on exposure instead. */ else if (e.type == Expose) is_visible = True; } if (is_visible) { if (rotate && is_color && is_dynamic) { rotate_colors(); } if (!freeze) { for (i = 0; i < nworms; i++) { wcolor = (((i * ncolors) / nworms) + chromo) % ncolors; worm_doit(worm[i], xsize, ysize, colors[wcolor].pixel); } } /* note that there is a little jump in the worms * if they are frozen and no rotation exists. * doesn't seem to be possible to (easily) get away * from this */ } if (chromocolor) chromo++; } } rotate_colors() { register int i; long temp; temp = colors[1].pixel; /* start at 1 - don't want the black */ for (i = 1; i < ncolors - 1; i++) { colors[i].pixel = colors[i+1].pixel; } colors[ncolors - 1].pixel = temp; XStoreColors(dpy, cmap, colors, ncolors); } wormstuff * worm_init(xsize, ysize, wormlength) int xsize; int ysize; int wormlength; { register int i; wormstuff *ws; ws = (wormstuff *)malloc(sizeof(wormstuff)); if (wormlength > 0) { ws->xcirc = (int *)malloc((unsigned)(wormlength * sizeof(int))); ws->ycirc = (int *)malloc((unsigned)(wormlength * sizeof(int))); for (i = 0; i < wormlength; i++) { ws->xcirc[i] = xsize / 2; ws->ycirc[i] = ysize / 2; } } ws->dir = (unsigned) random() % SEGMENTS; ws->tail = 0; ws->x = xsize / 2; ws->y = ysize / 2; return (ws); } worm_doit(ws, xsize, ysize, color) register wormstuff *ws; int xsize; int ysize; unsigned long color; { register int x, y; if (wormlength > 0) { ws->tail = (ws->tail + 1) % wormlength; x = ws->xcirc[ws->tail]; y = ws->ycirc[ws->tail]; XClearArea(dpy, w, x, y, circsize, circsize, False); } if (random() & 1) { ws->dir = (ws->dir + 1) % SEGMENTS; } else { ws->dir = (ws->dir + SEGMENTS - 1) % SEGMENTS; } x = (ws->x + costab[ws->dir] + xsize) % xsize; y = (ws->y + sintab[ws->dir] + ysize) % ysize; if (wormlength > 0) { ws->xcirc[ws->tail] = x; ws->ycirc[ws->tail] = y; } if (is_color) drawseg(x, y, color); else { XFillRectangle(dpy, w, wgc, x, y, circsize, circsize); } ws->x = x; ws->y = y; } round(x) float x; { return ((int) rint((double)x)); } drawseg(x, y, c) int x, y; unsigned long c; { XSetForeground(dpy, gc, c); XFillRectangle(dpy, w, gc, x, y, circsize, circsize); } usage(cmd) char *cmd; { (void)fprintf(stderr, "usage: %s -S -C -R [-l length] [-s size] [-n number]\n[-g geometry] [-d display]\n -S screensaver\n -C chromocolor\n -R Rotate colormap\n", cmd); exit(1); } cmap_init(win) Window win; { int pixels[NUM_COLORS]; int pmasks; register int i; XVisualInfo vinfo; int num_vis, vmask; XColor stat_colors[NUM_COLORS]; int planes; #define VALUES 256 #define rnd(x) (random() % x) /* #define RANDOM /* use an random colormap - messy */ #define HSB /* use an HSB colormap - makes colorwheel look neat */ planes = DisplayPlanes(dpy, screen); /* see what kind of visual we're dealing with */ if (XMatchVisualInfo(dpy, screen, planes, PseudoColor, &vinfo) || XMatchVisualInfo(dpy, screen, planes, GrayScale, &vinfo) || XMatchVisualInfo(dpy, screen, planes, DirectColor, &vinfo)) goto read_write_map; else goto read_only_map; read_write_map: visual = vinfo.visual; depth = vinfo.depth; cmap = XCreateColormap(dpy, RootWindow(dpy, screen), visual, AllocNone); ncolors = vinfo.colormap_size; /* grab as many color cells as we can */ for (i = ncolors; i > MIN_COLORS; i--) { if (XAllocColorCells(dpy, cmap, False, &pmasks, 0, pixels, i)) break; } if (i == MIN_COLORS) { fprintf(stderr, "Couldn't allocate even %d colors - exiting\n", MIN_COLORS); exit(0); } ncolors = i; #ifdef RANDOM /* make the black for background */ backpixel = colors[0].pixel = pixels[0]; colors[0].red = colors[0].green = colors[0].blue = 0; colors[0].flags = DoRed | DoGreen | DoBlue; for (i = 1; i < ncolors; i++) { colors[i].pixel = pixels[i]; colors[i].red = rnd(VALUES) << 8; colors[i].green = rnd(VALUES) << 8; colors[i].blue = rnd(VALUES) << 8; colors[i].flags = DoRed | DoGreen | DoBlue; } XStoreColors(dpy, cmap, colors, ncolors); #else #ifdef HSB /* this colormap makes things look a lot nicer when worms goes * into freeze mode. */ { double hue, sat, bright, r, g, b; sat = 0.9; bright = 1.0; /* make the black for background */ backpixel = colors[0].pixel = pixels[0]; colors[0].red = colors[0].green = colors[0].blue = 0; colors[0].flags = DoRed | DoGreen | DoBlue; for (i = 1; i < ncolors; i++) { hue = (float) i / (float) ncolors; hsb2rgb(hue, sat, bright, &r, &g, &b); colors[i].pixel = pixels[i]; colors[i].red = (int) (r * 255.0) << 8; colors[i].green = (int) (g * 255.0) << 8; colors[i].blue = (int) (b * 255.0) << 8; colors[i].flags = DoRed | DoGreen | DoBlue; } XStoreColors(dpy, cmap, colors, ncolors); } #else for (i = 0; i < ncolors; i++) stat_colors[i].pixel = i; XQueryColors(dpy, DefaultColormap(dpy, screen), stat_colors, ncolors); XStoreColors(dpy, cmap, stat_colors, ncolors); bcopy(stat_colors, colors, ncolors * sizeof(XColor)); #endif #endif is_dynamic = True; return; read_only_map: is_dynamic = False; visual = vinfo.visual; depth = vinfo.depth; /* for a Static colormap, just make each worm a random pixel */ for (i = 0; i < NUM_COLORS; i++) { colors[i].pixel = rnd(NUM_COLORS); } } hsb2rgb(h, s, i, r, g, b) double h, s, i; double *r, *g, *b; { register int j; register double f, p, q, t; if (s == 0.0) *r = *g = *b = i; else { h -= floor(h); /* remove anything over 1 */ h *= 6.0; j = floor(h); f = h - (float) j; p = i * (1.0 - s); q = i * (1.0 - s * f); t = i * (1.0 - (s * (1.0 - f))); switch(j) { case 0: *r = i; *g = t; *b = p; break; case 1: *r = q; *g = i; *b = p; break; case 2: *r = p; *g = i; *b = t; break; case 3: *r = p; *g = q; *b = i; break; case 4: *r = t; *g = p; *b = i; break; case 5: *r = i; *g = p; *b = q; break; } } } -- ``Read my MIPS -- no new VAXes!!'' -- George Bush after sniffing freon Disclaimer: I speak for myself, except as noted. UUCP: ...!uunet!dsd.es.com!rthomson Rich Thomson ARPA: rthomson@dsd.es.com PEXt Programmer
brown@hpfcdq.HP.COM (John Brown) (04/15/91)
Mark writes . . . > I am having trouble with a current project that requires the use of a > 24 bit directcolor visual under X windows. Everytime I do a XCreateWindow, > I get a XBadMatch error, which I cannot figure out the cause of. (gosh, > leave that preposition dangling). > > The steps I need to do is: > > 1. Use XMatchVisual to decide if a 24 bit visual is available > (it is not my default visual) > 2. Use XCreateWindow to create a window. > 3. Create an XImage to be used with the window. > > If anyone has a simple program or program fragment that you know works, then > please send it to me. I am also open to any hints on how to proceed, as > I am strictly a novice X programmer. > > If it helps, I have tested this on an HP9000 300 series, which supports > X11R3. I thought I'd just post a short example which shows how to create the 24 bit window and gopen it with Starbase. For your needs, you'll want to ignore the Starbase part and add code for the XImage. The code to open the X window will work fine on HP s300 X servers which support the 24 bit DirectColor visual, but I can't promise it will work on other vendors' X servers. Good Luck! John Brown HP Graphics Technology Division This response does not represent the official position of, or statement by, the Hewlett-Packard Company. The above data is provided for informational purposes only. It is supplied without warranty of any kind. ----------------------------------- cut here ---------------------------------- #include <stdio.h> #include <starbase.c.h> #include <X11/Xlib.h> #include <X11/Xutil.h> /* 24bit.c Sample program to illustrate how to create a 24-bit X window and then gopen it with Starbase. If running on 8.0 or greater, use shared libraries and compile as: cc -o 24bit 24bit.c -DHPUX_80 -L/usr/lib/X11R4 -lXwindow \ -lsb -ldld -lXhp11 -lX11 -lm If running on pre-8.0, compile as (where xxxx is the driver for your display device, e.g. 98731): cc -o 24bit 24bit.c -lddxxxx -lXwindow -lsb1 -lsb2 -lXhp11 -lX11 -lm To run the program on an 8.0 or greater system, simply invoke as "24bit". If running on pre-8.0, either set the SB_OUTDRIVER environment variable first, or invoke as "24bit drivername" (where drivername is the appropriate driver name for your device, e.g. hp98731). ****************************************************************** * This program does not represent the official position of, * * or statement by, the Hewlett-Packard Company. This program * * is provided for informational purposes only. It is supplied * * without warranty of any kind. * ****************************************************************** */ main(argc, argv) int argc; char *argv[]; { Display *display; int screen, fildes; XVisualInfo my_visualinfo; Visual *my_visual; XSetWindowAttributes my_attributes; Window my_window; Colormap my_colormap; XEvent my_event; char *device, *driver, reply[80]; /* Open the X display */ if ( (display = XOpenDisplay(NULL)) == NULL ) { printf("ERROR: Could not open the X display.\n"); printf(" Check the DISPLAY environment variable.\n"); exit(-1); } screen = DefaultScreen( display ); /* Then, see if the desired visual exists. Although this sample program checks specifically for the 24-bit visual, a well-behaved application should really be willing to use other visuals if it can't find the ideal one. */ if ( XMatchVisualInfo(display,screen,24,DirectColor,&my_visualinfo) ) { my_visual = my_visualinfo.visual; } else { printf("ERROR: Could not create a 24-bit DirectColor window.\n"); exit(-1); } /* Next, it is necessary to create a colormap for the window */ my_colormap = XCreateColormap( display, RootWindow(display,screen), my_visual, AllocAll ); /* Finally, we need to specify a few other window attributes so that we can successfully create the 24-bit window */ my_attributes.colormap = my_colormap; my_attributes.border_pixel = 0; my_attributes.background_pixel = 0; my_window = XCreateWindow( display, RootWindow(display,screen), 10,10, 1024, 800, 0, 24, InputOutput, my_visual, CWBorderPixel|CWColormap|CWBackPixel, &my_attributes ); /* Map the window, and wait for the map to occur */ XSelectInput(display, my_window, ExposureMask | StructureNotifyMask ); XMapWindow( display, my_window ); XWindowEvent( display, my_window, ExposureMask, &my_event ); /* Create a device string for a Starbase gopen */ device = make_X11_gopen_string( display, my_window ); /* Now, do the actual gopen. Notice that, beginning with 8.0 (including the initial release on the s700) the actual driver name can be replaced with NULL and the gopen is smart enough to determine the correct driver name. */ #ifdef HPUX_80 /* We're being complied for 8.0 or greater */ fildes = gopen( device, OUTDEV, NULL, INIT ); #else /* We must be on a pre-8.0 system. Try to get the drivername from the arg list if possible, then look for the env var if not in the arg list */ if ( argc > 1 ) driver = argv[1]; else driver = (char *) getenv("SB_OUTDRIVER"); fildes = gopen( device, OUTDEV, driver, INIT ); #endif /* Check to verify that we did indeed open the device correctly. */ if ( fildes >= 0 ) { /* Let the user know about the gopen */ printf("gopen was successful . . . clearing window to red\n"); /* Clear the window to red just to show that we did open it */ shade_mode( fildes, CMAP_FULL|INIT, FALSE ); background_color( fildes, 1.0, 0.0, 0.0 ); clear_view_surface( fildes ); make_picture_current( fildes ); printf("Hit return when finished viewing . . ."); gets( reply ); gclose( fildes ); } else { /* Let the user know about the failure */ printf("ERROR: Could not gopen window with driver '%s'\n", driver ); exit( -1 ); } } /* end of main */