home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / PX / X11RASTE.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  7KB  |  288 lines

  1. /* Copyright 1990 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)x11raster.c 2.7 10/12/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  * x11raster.c - routines to handle images for X windows.
  9.  *
  10.  *    2/18/88
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <X11/Xlib.h>
  15. #include <X11/Xutil.h>
  16.  
  17. #include "color.h"
  18. #include "x11raster.h"
  19.  
  20.  
  21. XRASTER *
  22. make_raster(disp, vis, npixbits, data, width, height, bm_pad)
  23. Display    *disp;
  24. XVisualInfo    *vis;
  25. int    npixbits;
  26. char    *data;
  27. int    width, height;
  28. int    bm_pad;
  29. {
  30.     static long    swaptest = 1;
  31.     register XRASTER    *xr;
  32.  
  33.     if ((xr = (XRASTER *)calloc(1, sizeof(XRASTER))) == NULL)
  34.         return(NULL);
  35.     xr->disp = disp;
  36.     xr->screen = vis->screen;
  37.     xr->visual = vis->visual;
  38.     if (npixbits == 1)
  39.         xr->image = XCreateImage(disp,vis->visual,1,
  40.                 XYBitmap,0,data,width,height,bm_pad,0);
  41.     else
  42.         xr->image = XCreateImage(disp,vis->visual,vis->depth,
  43.                 ZPixmap,0,data,width,height,bm_pad,0);
  44.     xr->image->bitmap_bit_order = MSBFirst;
  45.     xr->image->bitmap_unit = bm_pad;
  46.     xr->image->byte_order = *(char *)&swaptest ? LSBFirst : MSBFirst;
  47.     if (vis->depth >= 24 && (xr->image->red_mask != 0xff ||
  48.             xr->image->green_mask != 0xff00 ||
  49.             xr->image->blue_mask != 0xff0000) &&
  50.             (xr->image->red_mask != 0xff0000 ||
  51.             xr->image->green_mask != 0xff00 ||
  52.             xr->image->blue_mask != 0xff)) {
  53.         xr->image->red_mask = 0xff;
  54.         xr->image->green_mask = 0xff00;
  55.         xr->image->blue_mask = 0xff0000;
  56.     }
  57.     xr->gc = 0;
  58.     return(xr);
  59. }
  60.  
  61.  
  62. int
  63. init_rcolors(xr, cmap)            /* initialize colors */
  64. register XRASTER    *xr;
  65. BYTE    cmap[][3];
  66. {
  67.     register unsigned char    *p;
  68.     register int    i;
  69.  
  70.     if (xr->image->depth > 8 | xr->ncolors != 0)
  71.         return(xr->ncolors);
  72.     xr->pmap = (short *)malloc(256*sizeof(short));
  73.     if (xr->pmap == NULL)
  74.         return(0);
  75.     xr->cdefs = (XColor *)malloc(256*sizeof(XColor));
  76.     if (xr->cdefs == NULL)
  77.         return(0);
  78.     for (i = 0; i < 256; i++)
  79.         xr->pmap[i] = -1;
  80.     for (p = (unsigned char *)xr->image->data,
  81.             i = xr->image->width*xr->image->height;
  82.             i--; p++)
  83.         if (xr->pmap[*p] == -1) {
  84.             xr->cdefs[xr->ncolors].red = cmap[*p][RED] << 8;
  85.             xr->cdefs[xr->ncolors].green = cmap[*p][GRN] << 8;
  86.             xr->cdefs[xr->ncolors].blue = cmap[*p][BLU] << 8;
  87.             xr->cdefs[xr->ncolors].pixel = *p;
  88.             xr->cdefs[xr->ncolors].flags = DoRed|DoGreen|DoBlue;
  89.             xr->pmap[*p] = xr->ncolors++;
  90.         }
  91.     xr->cdefs = (XColor *)realloc((char *)xr->cdefs,
  92.             xr->ncolors*sizeof(XColor));
  93.     if (xr->cdefs == NULL)
  94.         return(0);
  95.     return(xr->ncolors);
  96. }
  97.  
  98.  
  99. Colormap
  100. newcmap(disp, scrn, w, vis)        /* get colormap and fix b & w */
  101. Display    *disp;
  102. int    scrn;
  103. Window    w;
  104. Visual    *vis;
  105. {
  106.     XColor    thiscolor;
  107.     unsigned long    *pixels;
  108.     Colormap    cmap;
  109.     int    n;
  110.     register int    i, j;
  111.  
  112.     cmap = XCreateColormap(disp, w, vis, AllocNone);
  113.     if (cmap == 0)
  114.         return(0);
  115.     pixels=(unsigned long *)malloc(vis->map_entries*sizeof(unsigned long));
  116.     if (pixels == NULL)
  117.         return(0);
  118.     for (n = vis->map_entries; n > 0; n--)
  119.         if (XAllocColorCells(disp, cmap, 0, NULL, 0, pixels, n) != 0)
  120.             break;
  121.     if (n == 0)
  122.         return(0);
  123.                     /* reset black and white */
  124.     for (i = 0; i < n; i++) {
  125.         if (pixels[i] != BlackPixel(disp,scrn)
  126.                 && pixels[i] != WhitePixel(disp,scrn))
  127.             continue;
  128.         thiscolor.pixel = pixels[i];
  129.         thiscolor.flags = DoRed|DoGreen|DoBlue;
  130.         XQueryColor(disp, DefaultColormap(disp,scrn), &thiscolor);
  131.         XStoreColor(disp, cmap, &thiscolor);
  132.         for (j = i; j+1 < n; j++)
  133.             pixels[j] = pixels[j+1];
  134.         n--;
  135.         i--;
  136.     }
  137.     XFreeColors(disp, cmap, pixels, n, 0);
  138.     free((char *)pixels);
  139.     return(cmap);
  140. }
  141.  
  142.  
  143. unsigned long *
  144. map_rcolors(xr, w)                /* get and assign pixels */
  145. register XRASTER    *xr;
  146. Window    w;
  147. {
  148.     register int    i;
  149.     register unsigned char    *p;
  150.  
  151.     if (xr->ncolors == 0 || xr->image->depth > 8)
  152.         return(NULL);
  153.     if (xr->pixels != NULL)
  154.         return(xr->pixels);
  155.     xr->pixels = (unsigned long *)malloc(xr->ncolors*sizeof(unsigned long));
  156.     if (xr->pixels == NULL)
  157.         return(NULL);
  158.     if (xr->visual == DefaultVisual(xr->disp, xr->screen))
  159.         xr->cmap = DefaultColormap(xr->disp, xr->screen);
  160.     else
  161.         xr->cmap = newcmap(xr->disp, xr->screen, w, xr->visual);
  162.     while (XAllocColorCells(xr->disp, xr->cmap, 0,
  163.             NULL, 0, xr->pixels, xr->ncolors) == 0)
  164.         if (xr->cmap == DefaultColormap(xr->disp, xr->screen))
  165.             xr->cmap = newcmap(xr->disp, xr->screen, w, xr->visual);
  166.         else {
  167.             free((char *)xr->pixels);
  168.             xr->pixels = NULL;
  169.             return(NULL);
  170.         }
  171.     for (i = 0; i < xr->ncolors; i++)
  172.         if (xr->pmap[xr->pixels[i]] == -1)
  173.             break;
  174.     if (i < xr->ncolors) {            /* different pixels */
  175.         for (p = (unsigned char *)xr->image->data,
  176.                 i = xr->image->width*xr->image->height;
  177.                 i--; p++)
  178.             *p = xr->pixels[xr->pmap[*p]];
  179.         for (i = 0; i < 256; i++)
  180.             xr->pmap[i] = -1;
  181.         for (i = 0; i < xr->ncolors; i++) {
  182.             xr->cdefs[i].pixel = xr->pixels[i];
  183.             xr->pmap[xr->pixels[i]] = i;
  184.         }
  185.         free_rpixmap(xr);        /* Pixmap invalid */
  186.     }
  187.     XStoreColors(xr->disp, xr->cmap, xr->cdefs, xr->ncolors);
  188.     XSetWindowColormap(xr->disp, w, xr->cmap);
  189.     return(xr->pixels);
  190. }
  191.  
  192.  
  193. Pixmap
  194. make_rpixmap(xr, w)            /* make pixmap for raster */
  195. register XRASTER    *xr;
  196. Window    w;
  197. {
  198.     XWindowAttributes    xwattr;
  199.     Pixmap    pm;
  200.  
  201.     if (xr->pm != 0)
  202.         return(xr->pm);
  203.     XGetWindowAttributes(xr->disp, w, &xwattr);
  204.     pm = XCreatePixmap(xr->disp, w,
  205.             xr->image->width, xr->image->height,
  206.             xwattr.depth);
  207.     if (pm == 0)
  208.         return(0);
  209.     put_raster(pm, 0, 0, xr);
  210.     return(xr->pm = pm);
  211. }
  212.  
  213.  
  214. patch_raster(d, xsrc, ysrc, xdst, ydst, width, height, xr)    /* redraw */
  215. Drawable    d;
  216. int    xsrc, ysrc, xdst, ydst;
  217. int    width, height;
  218. register XRASTER    *xr;
  219. {
  220.     if (xsrc >= xr->image->width || ysrc >= xr->image->height)
  221.         return;
  222.     if (xsrc < 0) {
  223.         xdst -= xsrc; width += xsrc;
  224.         xsrc = 0;
  225.     }
  226.     if (ysrc < 0) {
  227.         ydst -= ysrc; height += ysrc;
  228.         ysrc = 0;
  229.     }
  230.     if (width <= 0 || height <= 0)
  231.         return;
  232.     if (xsrc + width > xr->image->width)
  233.         width = xr->image->width - xsrc;
  234.     if (ysrc + height > xr->image->height)
  235.         height = xr->image->height - ysrc;
  236.  
  237.     if (xr->gc == 0) {
  238.         xr->gc = XCreateGC(xr->disp, d, 0, 0);
  239.         XSetState(xr->disp, xr->gc, BlackPixel(xr->disp,xr->screen),
  240.             WhitePixel(xr->disp,xr->screen), GXcopy, AllPlanes);
  241.     }
  242.     if (xr->pm == 0)
  243.         XPutImage(xr->disp, d, xr->gc, xr->image, xsrc, ysrc,
  244.                 xdst, ydst, width, height);
  245.     else
  246.         XCopyArea(xr->disp, xr->pm, d, xr->gc, xsrc, ysrc,
  247.                 width, height, xdst, ydst);
  248. }
  249.  
  250.  
  251. unmap_rcolors(xr)            /* free colors */
  252. register XRASTER    *xr;
  253. {
  254.     if (xr->pixels == NULL)
  255.         return;
  256.     XFreeColors(xr->disp, xr->cmap, xr->pixels, xr->ncolors, 0);
  257.     if (xr->cmap != DefaultColormap(xr->disp, xr->screen))
  258.         XFreeColormap(xr->disp, xr->cmap);
  259.     free((char *)xr->pixels);
  260.     xr->pixels = NULL;
  261. }
  262.  
  263.  
  264. free_rpixmap(xr)            /* release Pixmap */
  265. register XRASTER    *xr;
  266. {
  267.     if (xr->pm == 0)
  268.         return;
  269.     XFreePixmap(xr->disp, xr->pm);
  270.     xr->pm = 0;
  271. }
  272.  
  273.  
  274. free_raster(xr)                /* free raster data */
  275. register XRASTER    *xr;
  276. {
  277.     free_rpixmap(xr);
  278.     if (xr->ncolors > 0) {
  279.         unmap_rcolors(xr);
  280.         free((char *)xr->pmap);
  281.         free((char *)xr->cdefs);
  282.     }
  283.     XDestroyImage(xr->image);
  284.     if (xr->gc != 0)
  285.         XFreeGC(xr->disp, xr->gc);
  286.     free((char *)xr);
  287. }
  288.