home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / doc / tutorials / visuals / xsud.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-15  |  5.2 KB  |  146 lines

  1. #include    <X11/Xlib.h>
  2. #include    <X11/Xutil.h>
  3. #include    <stdio.h>
  4. #include    <sys/file.h>
  5.  
  6. Display            *dpy;        /*  X server we're talking to */
  7. Window            win;        /*  Window to paint the image in */
  8. GC            gc;        /*  GC to use for painting */
  9. Visual            *visual;    /*  Visual to use for the window */
  10. Colormap        cmap;        /*  Colormap to use for painting */
  11. XEvent            ev;        /*  Event received from the server */
  12. XImage            *image;        /*  To hold the image to be painted */
  13. int            width, height;    /*  Size of the window */
  14. int                     best_size[6];    /*  Largest colormap per Visual class */
  15. XVisualInfo             *best_vis[6];    /*  Best Visual per Visual class */
  16. int                     best_class[] = { TrueColor, DirectColor, PseudoColor,
  17.                                          StaticColor, GrayScale, StaticGray };
  18.  
  19. /*
  20.  *  Return the most suitable Visual for representing numcolors colors
  21.  */
  22. XVisualInfo *
  23. FindVisual(numcolors)
  24.     int        numcolors;
  25. {
  26.     int            num_vis, i, big_map = 0;
  27.     XVisualInfo     vinfo_template, *vlist, *v, *big_vis = NULL;
  28.  
  29.     /*  Get descriptions of all the visuals */
  30.     vlist = XGetVisualInfo(dpy, VisualNoMask, &vinfo_template, &num_vis);
  31.     /* Scan the list examining the colormap size */
  32.     for (v = vlist; v < vlist + num_vis; v++) {
  33.         /*  Remember the biggest colormap among all classes */
  34.     if (v->colormap_size > big_map) {
  35.         big_map = v->colormap_size;
  36.         big_vis = v;
  37.     }
  38.     /*  If the colormap is big enough,  remember it */
  39.         if (v->colormap_size > numcolors) {
  40.             if ((best_size[v->class] == 0)
  41.               || (v->colormap_size < best_size[v->class])) {
  42.             /*  Smallest so far that'll do */
  43.                 best_size[v->class] = v->colormap_size;
  44.                 best_vis[v->class] = v;
  45.             }
  46.     }
  47.     }
  48.     /*  In decreasing order of usability,  look at each class */
  49.     for (i = 0; i < 6; i++)
  50.         if (best_size[best_class[i]] > numcolors)
  51.             /*  This class can represent enough colors */
  52.             return (best_vis[best_class[i]]);
  53.     /*  Sigh!  We'll have to make do with a Visual that's too small */
  54.     return (big_vis);
  55. }
  56.  
  57. main(argc, argv)
  58. int    argc;
  59. char    **argv;
  60. {
  61.     int         numcolors, num_pxls, num_vis, x, y;
  62.     unsigned short *rgbvalues;
  63.     XVisualInfo *vis;
  64.     XSetWindowAttributes values;
  65.     XColor      color;
  66.  
  67.  
  68.     /* Read the size information from stdin */
  69.     fread((char *) &width, sizeof(int), 1, stdin);
  70.     fread((char *) &height, sizeof(int), 1, stdin);
  71.     fread((char *) &numcolors, sizeof(int), 1, stdin);
  72.     /* Allocate space to hold the RGB data,  and read it in */
  73.     num_pxls = width * height;
  74.     rgbvalues = (unsigned short *) malloc(sizeof(unsigned short)
  75.                       * 3 * num_pxls);
  76.     fread((char *) rgbvalues, sizeof(unsigned short), 3 * num_pxls, stdin);
  77.     /* Connect to the server */
  78.     if ((dpy = XOpenDisplay(NULL)) == (Display *) 0) {
  79.     fprintf(stderr, "can't open display\n");
  80.     exit(1);
  81.     }
  82.     /* Find a suitable Visual for numcolors */
  83.     vis = FindVisual(numcolors);
  84.     /* Create a Colormap in the Visual we found */
  85.     cmap = XCreateColormap(dpy, RootWindow(dpy, DefaultScreen(dpy)),
  86.                vis->visual, AllocNone);
  87.     /* Create an image the right size */
  88.     image = XCreateImage(dpy, vis->visual, vis->depth, ZPixmap, 0,
  89.           (unsigned long *) malloc(num_pxls * sizeof(unsigned long)),
  90.              width, height, 32, 0);
  91.     /* For each pixel in the image */
  92.     for (y = 0; y < height; y++)
  93.     for (x = 0; x < width; x++) {
  94.         /* Fill out the RGB fields of the XColor struct */
  95.         color.red = *rgbvalues++;
  96.         color.green = *rgbvalues++;
  97.         color.blue = *rgbvalues++;
  98.         color.flags = DoRed | DoGreen | DoBlue;
  99.         /* Get the server to convert from RGB to pixel value */
  100.         if (!XAllocColor(dpy, cmap, &color)) {
  101.         /* The colormap filled up - give up */
  102.         fprintf(stderr, "Colormap full\n");
  103.         exit(1);
  104.         }
  105.         /* Put the pixel value into the image */
  106.         (void) XPutPixel(image, x, y, color.pixel);
  107.     }
  108.     /* Create a suitable window using the Colormap, background White */
  109.     values.colormap = cmap;
  110.     /* get White from our colormap */
  111.     XAllocNamedColor(dpy, cmap, "white", &color, &color);
  112.     values.background_pixel = color.pixel;
  113.     /* Listen for Expose,  Enter and Leave events */
  114.     values.event_mask = ExposureMask | EnterWindowMask | LeaveWindowMask;
  115.     win = XCreateWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)),
  116.             0, 0, width, height, 0, vis->depth, InputOutput,
  117.              vis->visual, CWColormap | CWEventMask | CWBackPixel,
  118.             &values);
  119.     /* Create a GC to use for repainting the window */
  120.     gc = XCreateGC(dpy, win, 0, NULL);
  121.     /* Map the window,  wait for the Expose events,  and paint */
  122.     XMapWindow(dpy, win);
  123.     while (True) {
  124.     XExposeEvent *e;
  125.  
  126.     XNextEvent(dpy, &ev);
  127.     switch (ev.type) {
  128.         case Expose:
  129.         e = (XExposeEvent *) & ev;
  130.         /* Copy the image to the exposed part of the window */
  131.         XPutImage(dpy, win, gc, image, e->x, e->y, e->x, e->y,
  132.               (e->x + e->width > width ? width - e->x : e->width),
  133.               (e->y + e->height > height ? height - e->y : e->height));
  134.         break;
  135.         case EnterNotify:
  136.         /* Mouse is in the window,  install its Colormap */
  137.         XInstallColormap(dpy, cmap);
  138.         break;
  139.         case LeaveNotify:
  140.         /* Mouse has left the window,  uninstall its Colormap */
  141.         XUninstallColormap(dpy, cmap);
  142.         break;
  143.     }
  144.     }
  145. }
  146.