|
|
1.1 root 1: #ifndef lint
2: static char *rcsid_bitpix_c = "$Header: bitpix.c,v 10.1 86/11/29 13:50:35 jg Rel $";
3: #endif lint
4: /*
5:
6: Copyright 1986 by the University of Utah
7:
8: Permission to use, copy, modify, and distribute this
9: software and its documentation for any purpose and without
10: fee is hereby granted, provided that the above copyright
11: notice appear in all copies and that both that copyright
12: notice and this permission notice appear in supporting
13: documentation, and that the name of the University of Utah
14: not be used in advertising or publicity pertaining to
15: distribution of the software without specific, written
16: prior permission. The University of Utah makes no
17: representations about the suitability of this software for
18: any purpose. It is provided "as is" without express or
19: implied warranty.
20:
21: */
22:
23: /* Routines to cache bitmaps and pixmaps in the frame buffer memory:
24: *
25: * StoreBitmap Creates a bitmap
26: * FreeBitmap Frees the storage taken by a bitmap
27: * CharBitmap Creates a bitmap from a font character
28: * StorePixmap Creates a pixmap
29: * FreePixmap Frees the storage taken by a pixmap
30: * MakePixmap Create a pixmap from a bitmap
31: * PixmapSave Save a region of the screen
32: * PixmapGet Read a region of the screen
33: *
34: */
35:
36: #include "Xapollo.h"
37: #include <errno.h>
38:
39: extern int errno;
40: extern struct Scr Screen;
41: status_$t status;
42:
43: char *Xalloc();
44: PIXMAP *MakePixmap();
45:
46: BITMAP
47: *StoreBitmap (width, height, data)
48: int width, height;
49: char *data;
50: {
51: register BITMAP *bm;
52: int size;
53:
54: bm = make_bitmap(data, width, height, true);
55: return (bm);
56: }
57:
58: FreeBitmap (bitmap)
59: register BITMAP *bitmap;
60: {
61:
62: if( bitmap->kind == (int)memory_bitmap )
63: free ((caddr_t) bitmap->data);
64: else
65: if( bitmap->kind == (int)apollo_bitmap )
66: gpr_$deallocate_bitmap((gpr_$bitmap_desc_t)bitmap->data, status);
67: /* need to free attribute block as well... */
68: free ((caddr_t) bitmap);
69:
70: }
71:
72: BITMAP
73: *CharBitmap (c, font)
74: unsigned c;
75: register FONT *font;
76: {
77: int width;
78: register BITMAP *bm;
79:
80:
81: if (c < font->first || c > font->last) {
82: fprintf(stderr, "CharBitmap: font: %s char: %x\n", font->name, c);
83: errno = EINVAL;
84: return (NULL);
85: }
86:
87: if (font->fixed)
88: width = font->avg_width;
89: else
90: /* this won't work for Apollo-style fonts */
91: {
92: FontPriv * fp = (FontPriv *)font->data;
93: width = fp->widths[c];
94: }
95: if (width == 0) {
96: errno = EINVAL;
97: fprintf(stderr, "CharBitmap: font: %s char: %x\n", font->name, c);
98: return (NULL);
99: }
100: bm = (BITMAP *) Xalloc (sizeof (BITMAP));
101: bm->width = width;
102: bm->height = font->height;
103: bm->refcnt = 1;
104: if ((bm->data =
105: (caddr_t) malloc (BitmapSize(width, bm->height))) == NULL) {
106: free ((caddr_t) bm);
107: errno = ENOMEM;
108: return (NULL);
109: }
110:
111: CopyText ((caddr_t) &c, 1, font, bm);
112: return (bm);
113: }
114:
115: /*ARGSUSED*/
116: PIXMAP
117: *StorePixmap (width, height, format, data)
118: int width, height, format;
119: char *data;
120: {
121: register PIXMAP *pm;
122:
123: if (Screen.depth == 1) {
124: register BITMAP *bm;
125:
126: bm = (BITMAP *) StoreBitmap(width, height, data);
127: if (bm == NULL)
128: return (NULL);
129: bm->refcnt = 0;
130: if ((pm = MakePixmap(bm, 1, 0)) == NULL) {
131: FreeBitmap(bm);
132: return (NULL);
133: }
134: }
135: else if (Screen.depth <= 8) {
136: char * newdata;
137: int size;
138:
139: pm = (PIXMAP *) Xalloc(sizeof(PIXMAP));
140: pm->width = width;
141: pm->height = height;
142: pm->refcnt = 1;
143: switch (format) {
144: case XYFormat:
145: size = XYPixmapSize(width, height, Screen.depth);
146: pm->kind = XYColorPixmap;
147: break;
148: case ZFormat:
149: size = BZPixmapSize(width, height);
150: if (width&1)
151: size += height;
152: pm->kind = ZColorPixmap;
153: break;
154: }
155: newdata = (char *) Xalloc(size);
156: if (width&1) {
157: register int i;
158: register char * old = data, *new = newdata;
159:
160: for (i = 0; i < height; i++) {
161: bcopy(old, new, width);
162: old += width;
163: new += width + 1;
164: }
165: } else
166: bcopy(data, newdata, size);
167: pm->data = newdata;
168: }
169:
170: return (pm);
171: }
172:
173: FreePixmap (pixmap)
174: register PIXMAP *pixmap;
175: {
176: register BITMAP *bm;
177:
178: switch (pixmap->kind) {
179: case BitmapPixmap:
180: bm = PDATA(pixmap);
181: if (--bm->refcnt == 0)
182: FreeBitmap(bm);
183: break;
184: case ZColorPixmap:
185: case XYColorPixmap:
186: free((caddr_t)pixmap->data);
187: break;
188: case ConstantPixmap:
189: return;
190: }
191: free((caddr_t) pixmap);
192: }
193:
194: PIXMAP constpix0 = {1, 1, 1, 1, ConstantPixmap, (caddr_t) 0};
195: PIXMAP constpix1 = {1, 1, 1, 1, ConstantPixmap, (caddr_t) 1};
196:
197: PIXMAP
198: *MakePixmap (xymask, fore, back)
199: register BITMAP *xymask;
200: int fore, back;
201: {
202: register PIXMAP *pm = NULL;
203:
204:
205: if (xymask == NULL) {
206: if (Screen.depth == 1) {
207: if (fore & 1)
208: pm = &constpix1;
209: else
210: pm = &constpix0;
211: pm->refcnt++;
212: }
213: else if (Screen.depth <= 8) {
214: static PIXMAP *constpm[256];
215:
216: if (constpm[fore & 0xFF] == 0) {
217: constpm[fore & 0xFF] = pm = (PIXMAP *) Xalloc(sizeof(PIXMAP));
218: pm->width = 1;
219: pm->height = 1;
220: pm->refcnt = 1;
221: pm->tile = CanBeTiled;
222: pm->kind = ConstantPixmap;
223: pm->data = (caddr_t) fore;
224: }
225: else {
226: pm = constpm[fore & 0xFF];
227: pm->refcnt++;
228: }
229: }
230: return (pm);
231: }
232:
233: pm = (PIXMAP *) Xalloc(sizeof(PIXMAP));
234: pm->width = xymask->width;
235: pm->height = xymask->height;
236: pm->refcnt = 1;
237: xymask->refcnt++;
238: pm->kind = BitmapPixmap;
239: pm->data = (caddr_t) xymask;
240: pm->tile = CanBeTiled;
241: /* save a bit to indicate if we have to invert the source */
242:
243: if ((Screen.depth == 1) && (back & 1))
244: pm->kind |= InvertFlag;
245:
246: return (pm);
247: }
248:
249: PIXMAP
250: *PixmapSave (srcx, srcy, width, height)
251: int srcx, srcy, width, height;
252: {
253: gpr_$position_t dest;
254: gpr_$window_t sou;
255: PIXMAP *pm = NULL;
256:
257: if (Screen.depth == 1)
258: {
259: register BITMAP *bm;
260:
261: bm = make_bitmap(NULL, width, height, false);
262: /* should check for NULL */
263: bm->refcnt = 0;
264:
265: CheckCursor(srcx, srcy, width, height);
266: sou.x_coord = srcx;
267: sou.y_coord = srcy;
268: sou.x_size = width;
269: sou.y_size = height;
270: dest.x_coord = 0;
271: dest.y_coord = 0;
272: gpr_$set_bitmap((gpr_$bitmap_desc_t)bm->data, status);
273: gpr_$pixel_blt(Screen.bm, sou, dest, status);
274: gpr_$set_bitmap(Screen.bm, status);
275: RestoreCursor();
276:
277: if ((pm = MakePixmap(bm, 1, 0)) == 0) {
278: FreeBitmap(bm);
279: return (NULL);
280: }
281: }
282: else if (Screen.depth <= 8) {
283: int sz = BZPixmapSize(width, height);
284:
285: if (width&1)
286: sz += height;
287: pm = (PIXMAP *) Xalloc(sizeof(PIXMAP));
288: pm->width = width;
289: pm->height = height;
290: pm->refcnt = 1;
291: pm->kind = ZColorPixmap;
292: if ((pm->data =
293: (caddr_t) malloc(sz)) == NULL) {
294: free((caddr_t) pm);
295: return (NULL);
296: }
297: }
298:
299: return (pm);
300: }
301:
302: /*ARGSUSED*/
303: PixmapGet (srcx, srcy, width, height, client, format, swapit)
304: int srcx, srcy, width, height, client, format;
305: {
306: PIXMAP *pm;
307: BITMAP *bm;
308:
309: dprintf( stderr, "pixmapget: %d,%d\n", srcx, srcy );
310:
311: /* !! this only works if PixmapSave returns a memory_bitmap */
312: /* hence, it doesn't work now because all bitmaps are apollo bitmaps */
313: pm = PixmapSave(srcx, srcy, width, height);
314: switch (pm->kind) {
315: case BitmapPixmap:{
316: int size = BitmapSize(width, height);
317:
318: bm = (BITMAP *) pm->data;
319: if (swapit)
320: Swap_shorts((short *) bm->data, size >> 1);
321: InvertPixelOrder((short *) bm->data, size >> 1);
322: Write(client, bm->data, size);
323: /* Pad amount written to 32-bit boundary - Ahem! */
324: if (size%4) {
325: Write(client, bm->data, 4 - (size%4));
326: }
327: }
328: break;
329: case ZColorPixmap:{
330: switch (format) {
331: case XYFormat:{
332: caddr_t newdata;
333: int size;
334:
335: size = XYPixmapSize(width, height, Screen.depth);
336: newdata = (caddr_t) malloc(size);
337: if (newdata) {
338: ZtoXY(width, height, Screen.depth, pm->data, newdata);
339: free(pm->data);
340: pm->data = newdata;
341: if (swapit)
342: Swap_shorts((short *) pm->data, size >> 1);
343: InvertPixelOrder((short *) pm->data, size >> 1);
344: }
345: Write(client, pm->data, size);
346: /* Pad amount written to 32-bit boundary - Ahem! */
347: if (size%4) {
348: Write(client, pm->data, 4 - (size%4));
349: }
350: }
351: break;
352: case ZFormat: {
353: int size = BZPixmapSize(width, height);
354:
355: if (width&1) {
356: register int i;
357: register char *old = pm->data;
358:
359: for (i = 0; i < height; i++) {
360: Write(client, old, width);
361: old += width + 1;
362: }
363: } else {
364: Write(client, pm->data, size);
365: }
366: /* Pad amount written to 32-bit boundary - Ahem! */
367: if (size%4) {
368: Write(client, pm->data, 4 - (size%4));
369: }
370: }
371: break;
372: }
373: break;
374: }
375: case XYColorPixmap:
376: #ifdef apollo_color
377: #else
378: /*NOTREACHED*/
379: #endif apollo_color
380: break;
381: }
382: FreePixmap(pm);
383:
384: }
385:
386: static ZtoXY(w, h, d, old, new)
387: int w, h, d;
388: caddr_t old;
389: u_char *new;
390: {
391: #ifdef apollo_color
392: unsigned mask = 1;
393: struct pixrect *New, *Old;
394:
395: Old = mem_point(w, h, d, old);
396: while (d--) {
397: register int y;
398:
399: New = mem_point(w, h, 1, new);
400: new += BitmapSize(w, h);
401: for (y = 0; y < h; y++) {
402: register int x;
403:
404: for (x = 0; x < w; x++) {
405: pr_put(New, x, y, (pr_get(Old, x, y) & mask));
406: }
407: }
408: pr_destroy(New);
409: mask <<= 1;
410: }
411: #endif apollo_color
412: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.