--- ray/src/px/x11raster.c 1990/03/01 13:18:23 1.1 +++ ray/src/px/x11raster.c 1993/07/19 15:18:10 2.8 @@ -14,54 +14,62 @@ static char SCCSid[] = "$SunId$ LBL"; #include #include +#include "color.h" #include "x11raster.h" +extern char *malloc(), *realloc(), *calloc(); + XRASTER * -make_raster(disp, scrn, depth, data, width, height, bm_pad) +make_raster(disp, vis, npixbits, data, width, height, bm_pad) Display *disp; -int scrn; -int depth; +XVisualInfo *vis; +int npixbits; char *data; int width, height; int bm_pad; { + static long swaptest = 1; register XRASTER *xr; - XVisualInfo ourvinfo; - /* Pick appropriate Visual */ - if (depth == 1) { - ourvinfo.visual = DefaultVisual(disp,scrn); - } else if (depth == 8) { - if (!XMatchVisualInfo(disp,scrn,8,PseudoColor,&ourvinfo)) - return(NULL); - } else if (depth > 12) { - if (!XMatchVisualInfo(disp,scrn,24,TrueColor,&ourvinfo)) - return(NULL); - } else - return(NULL); + if ((xr = (XRASTER *)calloc(1, sizeof(XRASTER))) == NULL) return(NULL); xr->disp = disp; - xr->screen = scrn; - xr->visual = ourvinfo.visual; - xr->image = XCreateImage(disp,ourvinfo.visual,depth, - ZPixmap,0,data,width,height,bm_pad,0); - xr->gc = XCreateGC(disp, RootWindow(disp,scrn), 0, 0); - XSetState(disp, xr->gc, BlackPixel(disp,scrn), WhitePixel(disp,scrn), - GXcopy, ~0L); + xr->screen = vis->screen; + xr->visual = vis->visual; + if (npixbits == 1) + xr->image = XCreateImage(disp,vis->visual,1, + XYBitmap,0,data,width,height,bm_pad,0); + else + xr->image = XCreateImage(disp,vis->visual,vis->depth, + ZPixmap,0,data,width,height,bm_pad,0); + xr->image->bitmap_bit_order = MSBFirst; + xr->image->bitmap_unit = bm_pad; + xr->image->byte_order = *(char *)&swaptest ? LSBFirst : MSBFirst; + if (vis->depth >= 24 && (xr->image->red_mask != 0xff || + xr->image->green_mask != 0xff00 || + xr->image->blue_mask != 0xff0000) && + (xr->image->red_mask != 0xff0000 || + xr->image->green_mask != 0xff00 || + xr->image->blue_mask != 0xff)) { + xr->image->red_mask = 0xff; + xr->image->green_mask = 0xff00; + xr->image->blue_mask = 0xff0000; + } + xr->gc = 0; return(xr); } int -init_rcolors(xr, rmap, gmap, bmap) /* initialize colors */ +init_rcolors(xr, cmap) /* initialize colors */ register XRASTER *xr; -unsigned char rmap[256], gmap[256], bmap[256]; +BYTE cmap[][3]; { register unsigned char *p; register int i; - if (xr->image->depth != 8 || xr->ncolors != 0) + if (xr->image->depth > 8 | xr->ncolors != 0) return(xr->ncolors); xr->pmap = (short *)malloc(256*sizeof(short)); if (xr->pmap == NULL) @@ -75,9 +83,9 @@ unsigned char rmap[256], gmap[256], bmap[256]; i = xr->image->width*xr->image->height; i--; p++) if (xr->pmap[*p] == -1) { - xr->cdefs[xr->ncolors].red = rmap[*p] << 8; - xr->cdefs[xr->ncolors].green = gmap[*p] << 8; - xr->cdefs[xr->ncolors].blue = bmap[*p] << 8; + xr->cdefs[xr->ncolors].red = cmap[*p][RED] << 8; + xr->cdefs[xr->ncolors].green = cmap[*p][GRN] << 8; + xr->cdefs[xr->ncolors].blue = cmap[*p][BLU] << 8; xr->cdefs[xr->ncolors].pixel = *p; xr->cdefs[xr->ncolors].flags = DoRed|DoGreen|DoBlue; xr->pmap[*p] = xr->ncolors++; @@ -90,6 +98,50 @@ unsigned char rmap[256], gmap[256], bmap[256]; } +Colormap +newcmap(disp, scrn, w, vis) /* get colormap and fix b & w */ +Display *disp; +int scrn; +Window w; +Visual *vis; +{ + XColor thiscolor; + unsigned long *pixels; + Colormap cmap; + int n; + register int i, j; + + cmap = XCreateColormap(disp, w, vis, AllocNone); + if (cmap == 0) + return(0); + pixels=(unsigned long *)malloc(vis->map_entries*sizeof(unsigned long)); + if (pixels == NULL) + return(0); + for (n = vis->map_entries; n > 0; n--) + if (XAllocColorCells(disp, cmap, 0, NULL, 0, pixels, n) != 0) + break; + if (n == 0) + return(0); + /* reset black and white */ + for (i = 0; i < n; i++) { + if (pixels[i] != BlackPixel(disp,scrn) + && pixels[i] != WhitePixel(disp,scrn)) + continue; + thiscolor.pixel = pixels[i]; + thiscolor.flags = DoRed|DoGreen|DoBlue; + XQueryColor(disp, DefaultColormap(disp,scrn), &thiscolor); + XStoreColor(disp, cmap, &thiscolor); + for (j = i; j+1 < n; j++) + pixels[j] = pixels[j+1]; + n--; + i--; + } + XFreeColors(disp, cmap, pixels, n, 0); + free((char *)pixels); + return(cmap); +} + + unsigned long * map_rcolors(xr, w) /* get and assign pixels */ register XRASTER *xr; @@ -97,30 +149,27 @@ Window w; { register int i; register unsigned char *p; - int j; - if (xr->ncolors == 0 || xr->image->depth != 8) + if (xr->ncolors == 0 || xr->image->depth > 8) return(NULL); if (xr->pixels != NULL) return(xr->pixels); xr->pixels = (unsigned long *)malloc(xr->ncolors*sizeof(unsigned long)); if (xr->pixels == NULL) return(NULL); - if (xr->visual == DefaultVisual(xr->disp, xr->screen)) { + if (xr->visual == DefaultVisual(xr->disp, xr->screen)) xr->cmap = DefaultColormap(xr->disp, xr->screen); - goto gotmap; - } -getmap: - xr->cmap = XCreateColormap(xr->disp, w, xr->visual, AllocNone); -gotmap: - if (XAllocColorCells(xr->disp, xr->cmap, 0, - &j, 0, xr->pixels, xr->ncolors) == 0) { + else + xr->cmap = newcmap(xr->disp, xr->screen, w, xr->visual); + while (XAllocColorCells(xr->disp, xr->cmap, 0, + NULL, 0, xr->pixels, xr->ncolors) == 0) if (xr->cmap == DefaultColormap(xr->disp, xr->screen)) - goto getmap; - free((char *)xr->pixels); - xr->pixels = NULL; - return(NULL); - } + xr->cmap = newcmap(xr->disp, xr->screen, w, xr->visual); + else { + free((char *)xr->pixels); + xr->pixels = NULL; + return(NULL); + } for (i = 0; i < xr->ncolors; i++) if (xr->pmap[xr->pixels[i]] == -1) break; @@ -144,15 +193,19 @@ gotmap: Pixmap -make_rpixmap(xr) /* make pixmap for raster */ +make_rpixmap(xr, w) /* make pixmap for raster */ register XRASTER *xr; +Window w; { + XWindowAttributes xwattr; Pixmap pm; if (xr->pm != 0) return(xr->pm); - pm = XCreatePixmap(xr->disp, RootWindow(xr->disp, xr->screen), - xr->image->width, xr->image->height, xr->image->depth); + XGetWindowAttributes(xr->disp, w, &xwattr); + pm = XCreatePixmap(xr->disp, w, + xr->image->width, xr->image->height, + xwattr.depth); if (pm == 0) return(0); put_raster(pm, 0, 0, xr); @@ -160,6 +213,43 @@ register XRASTER *xr; } +patch_raster(d, xsrc, ysrc, xdst, ydst, width, height, xr) /* redraw */ +Drawable d; +int xsrc, ysrc, xdst, ydst; +int width, height; +register XRASTER *xr; +{ + if (xsrc >= xr->image->width || ysrc >= xr->image->height) + return; + if (xsrc < 0) { + xdst -= xsrc; width += xsrc; + xsrc = 0; + } + if (ysrc < 0) { + ydst -= ysrc; height += ysrc; + ysrc = 0; + } + if (width <= 0 || height <= 0) + return; + if (xsrc + width > xr->image->width) + width = xr->image->width - xsrc; + if (ysrc + height > xr->image->height) + height = xr->image->height - ysrc; + + if (xr->gc == 0) { + xr->gc = XCreateGC(xr->disp, d, 0, 0); + XSetState(xr->disp, xr->gc, BlackPixel(xr->disp,xr->screen), + WhitePixel(xr->disp,xr->screen), GXcopy, AllPlanes); + } + if (xr->pm == 0) + XPutImage(xr->disp, d, xr->gc, xr->image, xsrc, ysrc, + xdst, ydst, width, height); + else + XCopyArea(xr->disp, xr->pm, d, xr->gc, xsrc, ysrc, + width, height, xdst, ydst); +} + + unmap_rcolors(xr) /* free colors */ register XRASTER *xr; { @@ -193,6 +283,7 @@ register XRASTER *xr; free((char *)xr->cdefs); } XDestroyImage(xr->image); - XFreeGC(xr->disp, xr->gc); + if (xr->gc != 0) + XFreeGC(xr->disp, xr->gc); free((char *)xr); }