|
|
1.1 root 1: #ifndef lint
2: static char *rcsid_bitpix_c = "$Header: bitpix.c,v 10.3 86/11/29 13:47:16 jg 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: if (PixRect->pr_depth > 1) {
251: struct pixrect *mask, *dest;
252:
253: if (PixRect->pr_depth > 8) {
254: pm->data = (caddr_t) Xalloc(WZPixmapSize(pm->width, pm->height));
255: } else {
256: pm->data = (caddr_t) Xalloc(BZPixmapSize(pm->width, pm->height));
257: }
258: dest = mem_point(pm->width, pm->height, PixRect->pr_depth, pm->data);
259: mask = mem_point(pm->width, pm->height, 1, xymask->data);
260:
261: /*
262: * First paint the background color over the whole region. Then
263: * paint the foreground color over the region using xymask as a stencil.
264: */
265: pr_rop(dest, 0, 0, pm->width, pm->height,
266: PIX_SRC | PIX_DONTCLIP | PIX_COLOR(back), NULL, 0, 0);
267: pr_stencil(dest, 0, 0, pm->width, pm->height,
268: PIX_SRC | PIX_DONTCLIP | PIX_COLOR(fore),
269: mask, 0, 0, NULL, 0 ,0);
270: pr_destroy(mask);
271: /*
272: * We assume pm->data is NOT freed when dest is destroyed.
273: */
274: pr_destroy(dest);
275:
276: pm->kind = ZColorPixmap;
277: } else {
278: xymask->refcnt++;
279: pm->kind = BitmapPixmap;
280: pm->data = (caddr_t) xymask;
281: }
282: pm->tile = CanBeTiled;
283: /* save a bit to indicate if we have to invert the source */
284:
285: if ((PixRect->pr_depth == 1) && (back & 1))
286: pm->kind |= InvertFlag;
287: return (pm);
288: }
289:
290: PIXMAP *PixmapSave (srcx, srcy, width, height)
291: int srcx, srcy, width, height;
292: {
293: PIXMAP *pm = NULL;
294:
295:
296: if (PixRect->pr_depth == 1) {
297: register BITMAP *bm;
298:
299: bm = (BITMAP *) Xalloc(sizeof(BITMAP));
300: bm->width = width;
301: bm->height = height;
302: bm->refcnt = 0;
303:
304: if ((bm->data =
305: (caddr_t) malloc(BitmapSize(width, height))) == NULL) {
306: free((caddr_t) bm);
307: return (NULL);
308: }
309: {
310: struct pixrect *dest;
311:
312: dest = mem_point(width, height, 1, bm->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: if ((pm = MakePixmap(bm, 1, 0)) == 0) {
319: FreeBitmap(bm);
320: return (NULL);
321: }
322: }
323: else if (PixRect->pr_depth <= 8) {
324: int sz = BZPixmapSize(width, height);
325:
326: if (width&1)
327: sz += height;
328: pm = (PIXMAP *) Xalloc(sizeof(PIXMAP));
329: pm->width = width;
330: pm->height = height;
331: pm->refcnt = 1;
332: pm->kind = ZColorPixmap;
333: if ((pm->data =
334: (caddr_t) malloc(sz)) == NULL) {
335: free((caddr_t) pm);
336: return (NULL);
337: }
338: {
339: struct pixrect *dest;
340:
341: dest = mem_point(width, height, PixRect->pr_depth, pm->data);
342: CheckCursor(srcx, srcy, width, height);
343: pr_rop(dest, 0, 0, width, height, PIX_SRC | PIX_DONTCLIP, PixRect, srcx, srcy);
344: pr_destroy(dest);
345: RestoreCursor();
346: }
347: }
348: return (pm);
349: }
350:
351: /*ARGSUSED*/
352: PixmapGet (srcx, srcy, width, height, client, format, swapit)
353: int srcx, srcy, width, height, client, format;
354: {
355: PIXMAP *pm;
356: BITMAP *bm;
357: pm = PixmapSave(srcx, srcy, width, height);
358: switch (pm->kind) {
359: case BitmapPixmap:{
360: int size = BitmapSize(width, height);
361:
362: bm = (BITMAP *) pm->data;
363: if (swapit)
364: Swap_shorts((short *) bm->data, size >> 1);
365: InvertPixelOrder((short *) bm->data, size >> 1);
366: Write(client, bm->data, size);
367: /* Pad amount written to 32-bit boundary - Ahem! */
368: if (size%4) {
369: Write(client, bm->data, 4 - (size%4));
370: }
371: }
372: break;
373: case ZColorPixmap:{
374: switch (format) {
375: case XYFormat:{
376: caddr_t newdata;
377: int size;
378:
379: size = XYPixmapSize(width, height, PixRect->pr_depth);
380: newdata = (caddr_t) malloc(size);
381: if (newdata) {
382: ZtoXY(width, height, PixRect->pr_depth, pm->data, newdata);
383: free(pm->data);
384: pm->data = newdata;
385: if (swapit)
386: Swap_shorts((short *) pm->data, size >> 1);
387: InvertPixelOrder((short *) pm->data, size >> 1);
388: }
389: Write(client, pm->data, size);
390: /* Pad amount written to 32-bit boundary - Ahem! */
391: if (size%4) {
392: Write(client, pm->data, 4 - (size%4));
393: }
394: }
395: break;
396: case ZFormat: {
397: int size = BZPixmapSize(width, height);
398:
399: if (width&1) {
400: register int i;
401: register char *old = pm->data;
402:
403: for (i = 0; i < height; i++) {
404: Write(client, old, width);
405: old += width + 1;
406: }
407: } else {
408: Write(client, pm->data, size);
409: }
410: /* Pad amount written to 32-bit boundary - Ahem! */
411: if (size%4) {
412: Write(client, pm->data, 4 - (size%4));
413: }
414: }
415: break;
416: }
417: break;
418: }
419: case XYColorPixmap:
420: /*NOTREACHED*/
421: break;
422: }
423: FreePixmap(pm);
424: }
425:
426: static ZtoXY(w, h, d, old, new)
427: int w, h, d;
428: caddr_t old;
429: u_char *new;
430: {
431: unsigned mask = 1;
432: struct pixrect *New, *Old;
433:
434: Old = mem_point(w, h, d, old);
435: while (d--) {
436: register int y;
437:
438: New = mem_point(w, h, 1, new);
439: new += BitmapSize(w, h);
440: for (y = 0; y < h; y++) {
441: register int x;
442:
443: for (x = 0; x < w; x++) {
444: pr_put(New, x, y, (pr_get(Old, x, y) & mask));
445: }
446: }
447: pr_destroy(New);
448: mask <<= 1;
449: }
450: }
451: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.