1: #ifndef lint 2: static char *rcsid_bitpix_c = "$Header: bitpix.c,v 10.2 86/02/01 16:20:31 tony Rel $"; 3: #endif lint 4: #ifdef sun 5: /* 6: * The Sun X drivers are a product of Sun Microsystems, Inc. and are provided 7: * for unrestricted use provided that this legend is included on all tape 8: * media and as a part of the software program in whole or part. Users 9: * may copy or modify these drivers without charge, but are not authorized 10: * to license or distribute them to anyone else except as part of a product or 11: * program developed by the user. 12: * 13: * THE SUN X DRIVERS ARE PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND 14: * INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A 15: * PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE 16: * PRACTICE. 17: * 18: * The Sun X Drivers are provided with no support and without any obligation 19: * on the part of Sun Microsystems, Inc. to assist in their use, correction, 20: * modification or enhancement. 21: * 22: * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 23: * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THE SUN X 24: * DRIVERS OR ANY PART THEREOF. 25: * 26: * In no event will Sun Microsystems, Inc. be liable for any lost revenue 27: * or profits or other special, indirect and consequential damages, even if 28: * Sun has been advised of the possibility of such damages. 29: * 30: * Sun Microsystems, Inc. 31: * 2550 Garcia Avenue 32: * Mountain View, California 94043 33: */ 34: 35: #ifndef lint 36: static char sccsid[] = "@(#)bitpix.c 2.1 86/01/28 Copyright 1986 Sun Micro"; 37: #endif 38: 39: /*- 40: * Copyright (c) 1986 by Sun Microsystems, Inc. 41: */ 42: /* Copyright 1985 Massachusetts Institute of Technology */ 43: 44: /* Routines to cache bitmaps and pixmaps in the frame buffer memory: 45: * 46: * StoreBitmap Creates a bitmap 47: * FreeBitmap Frees the storage taken by a bitmap 48: * CharBitmap Creates a bitmap from a font character 49: * StorePixmap Creates a pixmap 50: * FreePixmap Frees the storage taken by a pixmap 51: * MakePixmap Create a pixmap from a bitmap 52: * PixmapSave Save a region of the screen 53: * PixmapGet Read a region of the screen 54: * 55: */ 56: 57: #include "Xsun.h" 58: #include <errno.h> 59: 60: extern int errno; 61: extern struct pixrect *PixRect; 62: 63: char *Xalloc(); 64: PIXMAP *MakePixmap(); 65: 66: BITMAP *StoreBitmap (width, height, data) 67: int width, height; 68: char *data; 69: { 70: register BITMAP *bm; 71: int size; 72: 73: bm = (BITMAP *) Xalloc (sizeof (BITMAP)); 74: bm->width = width; 75: bm->height = height; 76: bm->refcnt = 1; 77: 78: size = BitmapSize(width, height); 79: if ((bm->data = (caddr_t) malloc (size)) == NULL) { 80: free ((caddr_t) bm); 81: return (NULL); 82: } 83: bcopy (data, bm->data, size); 84: InvertPixelOrder((short *) bm->data, size>>1); 85: 86: return (bm); 87: } 88: 89: FreeBitmap (bitmap) 90: register BITMAP *bitmap; 91: { 92: free ((caddr_t) bitmap->data); 93: free ((caddr_t) bitmap); 94: } 95: 96: BITMAP *CharBitmap (c, font) 97: unsigned c; 98: register FONT *font; 99: { 100: int width; 101: register BITMAP *bm; 102: 103: if (c < font->first || c > font->last) { 104: errno = EINVAL; 105: return (NULL); 106: } 107: if (font->fixed) 108: width = font->avg_width; 109: else 110: width = ((struct pixfont *)font->data)->pf_char[c].pc_adv.x; 111: if (width == 0) { 112: errno = EINVAL; 113: return (NULL); 114: } 115: bm = (BITMAP *) Xalloc (sizeof (BITMAP)); 116: bm->width = width; 117: bm->height = font->height; 118: bm->refcnt = 1; 119: if ((bm->data = 120: (caddr_t) malloc (BitmapSize(width, bm->height))) == NULL) { 121: free ((caddr_t) bm); 122: errno = ENOMEM; 123: return (NULL); 124: } 125: 126: CopyText ((caddr_t) &c, 1, font, bm); 127: return (bm); 128: } 129: 130: /*ARGSUSED*/ 131: PIXMAP *StorePixmap (width, height, format, data) 132: int width, height, format; 133: char *data; 134: { 135: register PIXMAP *pm; 136: 137: if (PixRect->pr_depth == 1) { 138: register BITMAP *bm; 139: 140: bm = (BITMAP *) StoreBitmap(width, height, data); 141: if (bm == NULL) 142: return (NULL); 143: bm->refcnt = 0; 144: if ((pm = MakePixmap(bm, 1, 0)) == NULL) { 145: FreeBitmap(bm); 146: return (NULL); 147: } 148: } 149: else if (PixRect->pr_depth <= 8) { 150: char * newdata; 151: int size; 152: 153: pm = (PIXMAP *) Xalloc(sizeof(PIXMAP)); 154: pm->width = width; 155: pm->height = height; 156: pm->refcnt = 1; 157: switch (format) { 158: case XYFormat: 159: size = XYPixmapSize(width, height, PixRect->pr_depth); 160: pm->kind = XYColorPixmap; 161: break; 162: case ZFormat: 163: size = BZPixmapSize(width, height); 164: if (width&1) 165: size += height; 166: pm->kind = ZColorPixmap; 167: break; 168: } 169: newdata = (char *) Xalloc(size); 170: if (width&1) { 171: register int i; 172: register char * old = data, *new = newdata; 173: 174: for (i = 0; i < height; i++) { 175: bcopy(old, new, width); 176: old += width; 177: new += width + 1; 178: } 179: } else 180: bcopy(data, newdata, size); 181: pm->data = newdata; 182: } 183: return (pm); 184: } 185: 186: FreePixmap (pixmap) 187: register PIXMAP *pixmap; 188: { 189: switch (pixmap->kind) { 190: case BitmapPixmap: 191: { 192: register BITMAP *bm; 193: 194: bm = PDATA(pixmap); 195: if (--bm->refcnt == 0) 196: FreeBitmap(bm); 197: } 198: break; 199: case ZColorPixmap: 200: case XYColorPixmap: 201: free((caddr_t)pixmap->data); 202: break; 203: case ConstantPixmap: 204: return; 205: } 206: free((caddr_t) pixmap); 207: } 208: 209: PIXMAP constpix0 = {1, 1, 1, 1, ConstantPixmap, (caddr_t) 0}; 210: PIXMAP constpix1 = {1, 1, 1, 1, ConstantPixmap, (caddr_t) 1}; 211: 212: PIXMAP *MakePixmap (xymask, fore, back) 213: register BITMAP *xymask; 214: int fore, back; 215: { 216: register PIXMAP *pm = NULL; 217: 218: if (xymask == NULL) { 219: if (PixRect->pr_depth == 1) { 220: if (fore & 1) 221: pm = &constpix1; 222: else 223: pm = &constpix0; 224: pm->refcnt++; 225: } 226: else if (PixRect->pr_depth <= 8) { 227: static PIXMAP *constpm[256]; 228: 229: if (constpm[fore & 0xFF] == 0) { 230: constpm[fore & 0xFF] = pm = (PIXMAP *) Xalloc(sizeof(PIXMAP)); 231: pm->width = 1; 232: pm->height = 1; 233: pm->refcnt = 1; 234: pm->tile = CanBeTiled; 235: pm->kind = ConstantPixmap; 236: pm->data = (caddr_t) fore; 237: } 238: else { 239: pm = constpm[fore & 0xFF]; 240: pm->refcnt++; 241: } 242: } 243: return (pm); 244: } 245: 246: pm = (PIXMAP *) Xalloc(sizeof(PIXMAP)); 247: pm->width = xymask->width; 248: pm->height = xymask->height; 249: pm->refcnt = 1; 250: xymask->refcnt++; 251: pm->kind = BitmapPixmap; 252: pm->data = (caddr_t) xymask; 253: pm->tile = CanBeTiled; 254: /* save a bit to indicate if we have to invert the source */ 255: 256: if ((PixRect->pr_depth == 1) && (back & 1)) 257: pm->kind |= InvertFlag; 258: return (pm); 259: } 260: 261: PIXMAP *PixmapSave (srcx, srcy, width, height) 262: int srcx, srcy, width, height; 263: { 264: PIXMAP *pm = NULL; 265: 266: 267: if (PixRect->pr_depth == 1) { 268: register BITMAP *bm; 269: 270: bm = (BITMAP *) Xalloc(sizeof(BITMAP)); 271: bm->width = width; 272: bm->height = height; 273: bm->refcnt = 0; 274: 275: if ((bm->data = 276: (caddr_t) malloc(BitmapSize(width, height))) == NULL) { 277: free((caddr_t) bm); 278: return (NULL); 279: } 280: { 281: struct pixrect *dest; 282: 283: dest = mem_point(width, height, 1, bm->data); 284: CheckCursor(srcx, srcy, width, height); 285: pr_rop(dest, 0, 0, width, height, PIX_SRC | PIX_DONTCLIP, PixRect, srcx, srcy); 286: pr_destroy(dest); 287: RestoreCursor(); 288: } 289: if ((pm = MakePixmap(bm, 1, 0)) == 0) { 290: FreeBitmap(bm); 291: return (NULL); 292: } 293: } 294: else if (PixRect->pr_depth <= 8) { 295: int sz = BZPixmapSize(width, height); 296: 297: if (width&1) 298: sz += height; 299: pm = (PIXMAP *) Xalloc(sizeof(PIXMAP)); 300: pm->width = width; 301: pm->height = height; 302: pm->refcnt = 1; 303: pm->kind = ZColorPixmap; 304: if ((pm->data = 305: (caddr_t) malloc(sz)) == NULL) { 306: free((caddr_t) pm); 307: return (NULL); 308: } 309: { 310: struct pixrect *dest; 311: 312: dest = mem_point(width, height, PixRect->pr_depth, pm->data); 313: CheckCursor(srcx, srcy, width, height); 314: pr_rop(dest, 0, 0, width, height, PIX_SRC | PIX_DONTCLIP, PixRect, srcx, srcy); 315: pr_destroy(dest); 316: RestoreCursor(); 317: } 318: } 319: return (pm); 320: } 321: 322: /*ARGSUSED*/ 323: PixmapGet (srcx, srcy, width, height, client, format, swapit) 324: int srcx, srcy, width, height, client, format; 325: { 326: PIXMAP *pm; 327: BITMAP *bm; 328: pm = PixmapSave(srcx, srcy, width, height); 329: switch (pm->kind) { 330: case BitmapPixmap:{ 331: int size = BitmapSize(width, height); 332: 333: bm = (BITMAP *) pm->data; 334: if (swapit) 335: Swap_shorts((short *) bm->data, size >> 1); 336: InvertPixelOrder((short *) bm->data, size >> 1); 337: Write(client, bm->data, size); 338: /* Pad amount written to 32-bit boundary - Ahem! */ 339: if (size%4) { 340: Write(client, bm->data, 4 - (size%4)); 341: } 342: } 343: break; 344: case ZColorPixmap:{ 345: switch (format) { 346: case XYFormat:{ 347: caddr_t newdata; 348: int size; 349: 350: size = XYPixmapSize(width, height, PixRect->pr_depth); 351: newdata = (caddr_t) malloc(size); 352: if (newdata) { 353: ZtoXY(width, height, PixRect->pr_depth, pm->data, newdata); 354: free(pm->data); 355: pm->data = newdata; 356: if (swapit) 357: Swap_shorts((short *) pm->data, size >> 1); 358: InvertPixelOrder((short *) pm->data, size >> 1); 359: } 360: Write(client, pm->data, size); 361: /* Pad amount written to 32-bit boundary - Ahem! */ 362: if (size%4) { 363: Write(client, pm->data, 4 - (size%4)); 364: } 365: } 366: break; 367: case ZFormat: { 368: int size = BZPixmapSize(width, height); 369: 370: if (width&1) { 371: register int i; 372: register char *old = pm->data; 373: 374: for (i = 0; i < height; i++) { 375: Write(client, old, width); 376: old += width + 1; 377: } 378: } else { 379: Write(client, pm->data, size); 380: } 381: /* Pad amount written to 32-bit boundary - Ahem! */ 382: if (size%4) { 383: Write(client, pm->data, 4 - (size%4)); 384: } 385: } 386: break; 387: } 388: break; 389: } 390: case XYColorPixmap: 391: /*NOTREACHED*/ 392: break; 393: } 394: FreePixmap(pm); 395: } 396: 397: static ZtoXY(w, h, d, old, new) 398: int w, h, d; 399: caddr_t old; 400: u_char *new; 401: { 402: unsigned mask = 1; 403: struct pixrect *New, *Old; 404: 405: Old = mem_point(w, h, d, old); 406: while (d--) { 407: register int y; 408: 409: New = mem_point(w, h, 1, new); 410: new += BitmapSize(w, h); 411: for (y = 0; y < h; y++) { 412: register int x; 413: 414: for (x = 0; x < w; x++) { 415: pr_put(New, x, y, (pr_get(Old, x, y) & mask)); 416: } 417: } 418: pr_destroy(New); 419: mask <<= 1; 420: } 421: } 422: #endif