1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22: #include <config.h>
23: #include <stdio.h>
24: #include <math.h>
25: #include <ctype.h>
26:
27: #ifdef HAVE_UNISTD_H
28: #include <unistd.h>
29: #endif
30:
31:
32:
33: #define XLIB_ILLEGAL_ACCESS
34:
35: #include "lisp.h"
36: #include "frame.h"
37: #include "window.h"
38: #include "dispextern.h"
39: #include "blockinput.h"
40: #include "systime.h"
41: #include <epaths.h>
42: #include "charset.h"
43: #include "coding.h"
44:
45:
46: #ifdef HAVE_X_WINDOWS
47: #include "xterm.h"
48: #include <sys/types.h>
49: #include <sys/stat.h>
50:
51: #define COLOR_TABLE_SUPPORT 1
52:
53: typedef struct x_bitmap_record Bitmap_Record;
54: #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
55: #define NO_PIXMAP None
56:
57: #define RGB_PIXEL_COLOR unsigned long
58:
59: #define PIX_MASK_RETAIN 0
60: #define PIX_MASK_DRAW 1
61: #endif
62:
63:
64: #ifdef HAVE_NTGUI
65: #include "w32term.h"
66:
67:
68: #undef COLOR_TABLE_SUPPORT
69:
70: typedef struct w32_bitmap_record Bitmap_Record;
71: #define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y)
72: #define NO_PIXMAP 0
73:
74: #define RGB_PIXEL_COLOR COLORREF
75:
76: #define PIX_MASK_RETAIN 0
77: #define PIX_MASK_DRAW 1
78:
79: #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
80: #define x_defined_color w32_defined_color
81: #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
82: #endif
83:
84:
85: #ifdef MAC_OS
86: #include "macterm.h"
87: #include <sys/stat.h>
88: #ifndef MAC_OSX
89: #include <alloca.h>
90: #include <sys/param.h>
91: #endif
92: #if TARGET_API_MAC_CARBON
93: #ifdef MAC_OSX
94: #include <QuickTime/QuickTime.h>
95: #else
96: #include <QuickTime.h>
97: #endif
98: #else
99: #include <Windows.h>
100: #include <Gestalt.h>
101: #include <TextUtils.h>
102: #include <ImageCompression.h>
103: #include <QuickTimeComponents.h>
104: #endif
105:
106:
107: #undef COLOR_TABLE_SUPPORT
108:
109: #define ZPixmap 0
110: typedef struct mac_bitmap_record Bitmap_Record;
111:
112: #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
113: #define NO_PIXMAP 0
114:
115: #define RGB_PIXEL_COLOR unsigned long
116:
117:
118:
119: #define PIX_MASK_DRAW RGB_TO_ULONG(0,0,0)
120: #define PIX_MASK_RETAIN RGB_TO_ULONG(255,255,255)
121:
122: #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
123: #define x_defined_color mac_defined_color
124: #define DefaultDepthOfScreen(screen) (one_mac_display_info.n_planes)
125:
126: #endif
127:
128:
129:
130:
131: Lisp_Object Vx_bitmap_file_path;
132:
133:
134: static void x_disable_image P_ ((struct frame *, struct image *));
135: static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
136: Lisp_Object));
137:
138: static void init_color_table P_ ((void));
139: static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b));
140: #ifdef COLOR_TABLE_SUPPORT
141: static void free_color_table P_ ((void));
142: static unsigned long *colors_in_color_table P_ ((int *n));
143: static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
144: #endif
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157: #ifdef MAC_OS
158:
159: static XImagePtr
160: XGetImage (display, pixmap, x, y, width, height, plane_mask, format)
161: Display *display;
162: Pixmap pixmap;
163: int x, y;
164: unsigned int width, height;
165: unsigned long plane_mask;
166: int format;
167: {
168: #if GLYPH_DEBUG
169: xassert (x == 0 && y == 0);
170: {
171: Rect ri, rp;
172: SetRect (&ri, 0, 0, width, height);
173: xassert (EqualRect (&ri, GetPixBounds (GetGWorldPixMap (pixmap), &rp)));
174: }
175: xassert (! (pixelsLocked & GetPixelsState (GetGWorldPixMap (pixmap))));
176: #endif
177:
178: LockPixels (GetGWorldPixMap (pixmap));
179:
180: return pixmap;
181: }
182:
183: static void
184: XPutPixel (ximage, x, y, pixel)
185: XImagePtr ximage;
186: int x, y;
187: unsigned long pixel;
188: {
189: PixMapHandle pixmap = GetGWorldPixMap (ximage);
190: short depth = GetPixDepth (pixmap);
191:
192: #if defined (WORDS_BIG_ENDIAN) || !USE_CG_DRAWING
193: if (depth == 32)
194: {
195: char *base_addr = GetPixBaseAddr (pixmap);
196: short row_bytes = GetPixRowBytes (pixmap);
197:
198: ((unsigned long *) (base_addr + y * row_bytes))[x] = 0xff000000 | pixel;
199: }
200: else
201: #endif
202: if (depth == 1)
203: {
204: char *base_addr = GetPixBaseAddr (pixmap);
205: short row_bytes = GetPixRowBytes (pixmap);
206:
207: if (pixel == PIX_MASK_DRAW)
208: base_addr[y * row_bytes + x / 8] |= (1 << 7) >> (x & 7);
209: else
210: base_addr[y * row_bytes + x / 8] &= ~((1 << 7) >> (x & 7));
211: }
212: else
213: {
214: CGrafPtr old_port;
215: GDHandle old_gdh;
216: RGBColor color;
217:
218: GetGWorld (&old_port, &old_gdh);
219: SetGWorld (ximage, NULL);
220:
221: color.red = RED16_FROM_ULONG (pixel);
222: color.green = GREEN16_FROM_ULONG (pixel);
223: color.blue = BLUE16_FROM_ULONG (pixel);
224:
225: SetCPixel (x, y, &color);
226:
227: SetGWorld (old_port, old_gdh);
228: }
229: }
230:
231: static unsigned long
232: XGetPixel (ximage, x, y)
233: XImagePtr ximage;
234: int x, y;
235: {
236: PixMapHandle pixmap = GetGWorldPixMap (ximage);
237: short depth = GetPixDepth (pixmap);
238:
239: #if defined (WORDS_BIG_ENDIAN) || !USE_CG_DRAWING
240: if (depth == 32)
241: {
242: char *base_addr = GetPixBaseAddr (pixmap);
243: short row_bytes = GetPixRowBytes (pixmap);
244:
245: return ((unsigned long *) (base_addr + y * row_bytes))[x] & 0x00ffffff;
246: }
247: else
248: #endif
249: if (depth == 1)
250: {
251: char *base_addr = GetPixBaseAddr (pixmap);
252: short row_bytes = GetPixRowBytes (pixmap);
253:
254: if (base_addr[y * row_bytes + x / 8] & (1 << (~x & 7)))
255: return PIX_MASK_DRAW;
256: else
257: return PIX_MASK_RETAIN;
258: }
259: else
260: {
261: CGrafPtr old_port;
262: GDHandle old_gdh;
263: RGBColor color;
264:
265: GetGWorld (&old_port, &old_gdh);
266: SetGWorld (ximage, NULL);
267:
268: GetCPixel (x, y, &color);
269:
270: SetGWorld (old_port, old_gdh);
271: return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8);
272: }
273: }
274:
275: static void
276: XDestroyImage (ximg)
277: XImagePtr ximg;
278: {
279: UnlockPixels (GetGWorldPixMap (ximg));
280: }
281:
282: #if USE_CG_DRAWING
283: static CGImageRef
284: mac_create_cg_image_from_image (f, img)
285: struct frame *f;
286: struct image *img;
287: {
288: Pixmap mask;
289: CGImageRef result = NULL;
290:
291: BLOCK_INPUT;
292: if (img->mask)
293: mask = img->mask;
294: else
295: {
296: mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
297: img->width, img->height, 1);
298: if (mask)
299: {
300: CGrafPtr old_port;
301: GDHandle old_gdh;
302: Rect r;
303:
304: GetGWorld (&old_port, &old_gdh);
305: SetGWorld (mask, NULL);
306: BackColor (blackColor);
307: SetRect (&r, 0, 0, img->width, img->height);
308: EraseRect (&r);
309: SetGWorld (old_port, old_gdh);
310: }
311: }
312: if (mask)
313: {
314: CreateCGImageFromPixMaps (GetGWorldPixMap (img->pixmap),
315: GetGWorldPixMap (mask), &result);
316: if (mask != img->mask)
317: XFreePixmap (FRAME_X_DISPLAY (f), mask);
318: }
319: UNBLOCK_INPUT;
320:
321: return result;
322: }
323: #endif
324: #endif
325:
326:
327:
328:
329: int
330: x_bitmap_height (f, id)
331: FRAME_PTR f;
332: int id;
333: {
334: return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].height;
335: }
336:
337: int
338: x_bitmap_width (f, id)
339: FRAME_PTR f;
340: int id;
341: {
342: return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].width;
343: }
344:
345: #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
346: int
347: x_bitmap_pixmap (f, id)
348: FRAME_PTR f;
349: int id;
350: {
351: return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
352: }
353: #endif
354:
355: #ifdef HAVE_X_WINDOWS
356: int
357: x_bitmap_mask (f, id)
358: FRAME_PTR f;
359: int id;
360: {
361: return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].mask;
362: }
363: #endif
364:
365:
366:
367: static int
368: x_allocate_bitmap_record (f)
369: FRAME_PTR f;
370: {
371: Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
372: int i;
373:
374: if (dpyinfo->bitmaps == NULL)
375: {
376: dpyinfo->bitmaps_size = 10;
377: dpyinfo->bitmaps
378: = (Bitmap_Record *) xmalloc (dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
379: dpyinfo->bitmaps_last = 1;
380: return 1;
381: }
382:
383: if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
384: return ++dpyinfo->bitmaps_last;
385:
386: for (i = 0; i < dpyinfo->bitmaps_size; ++i)
387: if (dpyinfo->bitmaps[i].refcount == 0)
388: return i + 1;
389:
390: dpyinfo->bitmaps_size *= 2;
391: dpyinfo->bitmaps
392: = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps,
393: dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
394: return ++dpyinfo->bitmaps_last;
395: }
396:
397:
398:
399: void
400: x_reference_bitmap (f, id)
401: FRAME_PTR f;
402: int id;
403: {
404: ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
405: }
406:
407:
408:
409: int
410: x_create_bitmap_from_data (f, bits, width, height)
411: struct frame *f;
412: char *bits;
413: unsigned int width, height;
414: {
415: Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
416: int id;
417:
418: #ifdef HAVE_X_WINDOWS
419: Pixmap bitmap;
420: bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
421: bits, width, height);
422: if (! bitmap)
423: return -1;
424: #endif
425:
426: #ifdef HAVE_NTGUI
427: Pixmap bitmap;
428: bitmap = CreateBitmap (width, height,
429: FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_planes,
430: FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_cbits,
431: bits);
432: if (! bitmap)
433: return -1;
434: #endif
435:
436: #ifdef MAC_OS
437:
438: if (width % 16 != 0)
439: return -1;
440: #endif
441:
442: id = x_allocate_bitmap_record (f);
443: #ifdef MAC_OS
444: dpyinfo->bitmaps[id - 1].bitmap_data = (char *) xmalloc (height * width);
445: bcopy (bits, dpyinfo->bitmaps[id - 1].bitmap_data, height * width);
446: #endif
447:
448: dpyinfo->bitmaps[id - 1].file = NULL;
449: dpyinfo->bitmaps[id - 1].height = height;
450: dpyinfo->bitmaps[id - 1].width = width;
451: dpyinfo->bitmaps[id - 1].refcount = 1;
452:
453: #ifdef HAVE_X_WINDOWS
454: dpyinfo->bitmaps[id - 1].pixmap = bitmap;
455: dpyinfo->bitmaps[id - 1].have_mask = 0;
456: dpyinfo->bitmaps[id - 1].depth = 1;
457: #endif
458:
459: #ifdef HAVE_NTGUI
460: dpyinfo->bitmaps[id - 1].pixmap = bitmap;
461: dpyinfo->bitmaps[id - 1].hinst = NULL;
462: dpyinfo->bitmaps[id - 1].depth = 1;
463: #endif
464:
465: return id;
466: }
467:
468:
469:
470: int
471: x_create_bitmap_from_file (f, file)
472: struct frame *f;
473: Lisp_Object file;
474: {
475: #ifdef MAC_OS
476: return -1;
477: #endif
478:
479: #ifdef HAVE_NTGUI
480: return -1;
481: #endif
482:
483: #ifdef HAVE_X_WINDOWS
484: Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
485: unsigned int width, height;
486: Pixmap bitmap;
487: int xhot, yhot, result, id;
488: Lisp_Object found;
489: int fd;
490: char *filename;
491:
492:
493: for (id = 0; id < dpyinfo->bitmaps_last; ++id)
494: {
495: if (dpyinfo->bitmaps[id].refcount
496: && dpyinfo->bitmaps[id].file
497: && !strcmp (dpyinfo->bitmaps[id].file, (char *) SDATA (file)))
498: {
499: ++dpyinfo->bitmaps[id].refcount;
500: return id + 1;
501: }
502: }
503:
504:
505: fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil);
506: if (fd < 0)
507: return -1;
508: emacs_close (fd);
509:
510: filename = (char *) SDATA (found);
511:
512: result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
513: filename, &width, &height, &bitmap, &xhot, &yhot);
514: if (result != BitmapSuccess)
515: return -1;
516:
517: id = x_allocate_bitmap_record (f);
518: dpyinfo->bitmaps[id - 1].pixmap = bitmap;
519: dpyinfo->bitmaps[id - 1].have_mask = 0;
520: dpyinfo->bitmaps[id - 1].refcount = 1;
521: dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (SBYTES (file) + 1);
522: dpyinfo->bitmaps[id - 1].depth = 1;
523: dpyinfo->bitmaps[id - 1].height = height;
524: dpyinfo->bitmaps[id - 1].width = width;
525: strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
526:
527: return id;
528: #endif
529: }
530:
531:
532:
533: static void
534: Free_Bitmap_Record (dpyinfo, bm)
535: Display_Info *dpyinfo;
536: Bitmap_Record *bm;
537: {
538: #ifdef HAVE_X_WINDOWS
539: XFreePixmap (dpyinfo->display, bm->pixmap);
540: if (bm->have_mask)
541: XFreePixmap (dpyinfo->display, bm->mask);
542: #endif
543:
544: #ifdef HAVE_NTGUI
545: DeleteObject (bm->pixmap);
546: #endif
547:
548: #ifdef MAC_OS
549: xfree (bm->bitmap_data);
550: bm->bitmap_data = NULL;
551: #endif
552:
553: if (bm->file)
554: {
555: xfree (bm->file);
556: bm->file = NULL;
557: }
558: }
559:
560:
561:
562: void
563: x_destroy_bitmap (f, id)
564: FRAME_PTR f;
565: