home *** CD-ROM | disk | FTP | other *** search
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <stdio.h>
- #include <sys/file.h>
-
- Display *dpy; /* X server we're talking to */
- Window win; /* Window to paint the image in */
- GC gc; /* GC to use for painting */
- Visual *visual; /* Visual to use for the window */
- Colormap cmap; /* Colormap to use for painting */
- XEvent ev; /* Event received from the server */
- XImage *image; /* To hold the image to be painted */
- int width, height; /* Size of the window */
- int best_size[6]; /* Largest colormap per Visual class */
- XVisualInfo *best_vis[6]; /* Best Visual per Visual class */
- int best_class[] = { TrueColor, DirectColor, PseudoColor,
- StaticColor, GrayScale, StaticGray };
-
- /*
- * Return the most suitable Visual for representing numcolors colors
- */
- XVisualInfo *
- FindVisual(numcolors)
- int numcolors;
- {
- int num_vis, i, big_map = 0;
- XVisualInfo vinfo_template, *vlist, *v, *big_vis = NULL;
-
- /* Get descriptions of all the visuals */
- vlist = XGetVisualInfo(dpy, VisualNoMask, &vinfo_template, &num_vis);
- /* Scan the list examining the colormap size */
- for (v = vlist; v < vlist + num_vis; v++) {
- /* Remember the biggest colormap among all classes */
- if (v->colormap_size > big_map) {
- big_map = v->colormap_size;
- big_vis = v;
- }
- /* If the colormap is big enough, remember it */
- if (v->colormap_size > numcolors) {
- if ((best_size[v->class] == 0)
- || (v->colormap_size < best_size[v->class])) {
- /* Smallest so far that'll do */
- best_size[v->class] = v->colormap_size;
- best_vis[v->class] = v;
- }
- }
- }
- /* In decreasing order of usability, look at each class */
- for (i = 0; i < 6; i++)
- if (best_size[best_class[i]] > numcolors)
- /* This class can represent enough colors */
- return (best_vis[best_class[i]]);
- /* Sigh! We'll have to make do with a Visual that's too small */
- return (big_vis);
- }
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int numcolors, num_pxls, num_vis, x, y;
- unsigned short *rgbvalues;
- XVisualInfo *vis;
- XSetWindowAttributes values;
- XColor color;
-
-
- /* Read the size information from stdin */
- fread((char *) &width, sizeof(int), 1, stdin);
- fread((char *) &height, sizeof(int), 1, stdin);
- fread((char *) &numcolors, sizeof(int), 1, stdin);
- /* Allocate space to hold the RGB data, and read it in */
- num_pxls = width * height;
- rgbvalues = (unsigned short *) malloc(sizeof(unsigned short)
- * 3 * num_pxls);
- fread((char *) rgbvalues, sizeof(unsigned short), 3 * num_pxls, stdin);
- /* Connect to the server */
- if ((dpy = XOpenDisplay(NULL)) == (Display *) 0) {
- fprintf(stderr, "can't open display\n");
- exit(1);
- }
- /* Find a suitable Visual for numcolors */
- vis = FindVisual(numcolors);
- /* Create a Colormap in the Visual we found */
- cmap = XCreateColormap(dpy, RootWindow(dpy, DefaultScreen(dpy)),
- vis->visual, AllocNone);
- /* Create an image the right size */
- image = XCreateImage(dpy, vis->visual, vis->depth, ZPixmap, 0,
- (unsigned long *) malloc(num_pxls * sizeof(unsigned long)),
- width, height, 32, 0);
- /* For each pixel in the image */
- for (y = 0; y < height; y++)
- for (x = 0; x < width; x++) {
- /* Fill out the RGB fields of the XColor struct */
- color.red = *rgbvalues++;
- color.green = *rgbvalues++;
- color.blue = *rgbvalues++;
- color.flags = DoRed | DoGreen | DoBlue;
- /* Get the server to convert from RGB to pixel value */
- if (!XAllocColor(dpy, cmap, &color)) {
- /* The colormap filled up - give up */
- fprintf(stderr, "Colormap full\n");
- exit(1);
- }
- /* Put the pixel value into the image */
- (void) XPutPixel(image, x, y, color.pixel);
- }
- /* Create a suitable window using the Colormap, background White */
- values.colormap = cmap;
- /* get White from our colormap */
- XAllocNamedColor(dpy, cmap, "white", &color, &color);
- values.background_pixel = color.pixel;
- /* Listen for Expose, Enter and Leave events */
- values.event_mask = ExposureMask | EnterWindowMask | LeaveWindowMask;
- win = XCreateWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)),
- 0, 0, width, height, 0, vis->depth, InputOutput,
- vis->visual, CWColormap | CWEventMask | CWBackPixel,
- &values);
- /* Create a GC to use for repainting the window */
- gc = XCreateGC(dpy, win, 0, NULL);
- /* Map the window, wait for the Expose events, and paint */
- XMapWindow(dpy, win);
- while (True) {
- XExposeEvent *e;
-
- XNextEvent(dpy, &ev);
- switch (ev.type) {
- case Expose:
- e = (XExposeEvent *) & ev;
- /* Copy the image to the exposed part of the window */
- XPutImage(dpy, win, gc, image, e->x, e->y, e->x, e->y,
- (e->x + e->width > width ? width - e->x : e->width),
- (e->y + e->height > height ? height - e->y : e->height));
- break;
- case EnterNotify:
- /* Mouse is in the window, install its Colormap */
- XInstallColormap(dpy, cmap);
- break;
- case LeaveNotify:
- /* Mouse has left the window, uninstall its Colormap */
- XUninstallColormap(dpy, cmap);
- break;
- }
- }
- }
-