aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSteven Tamm2004-02-26 17:46:48 +0000
committerSteven Tamm2004-02-26 17:46:48 +0000
commite35644615b2a506daa457cbc5613ba8d16a46be6 (patch)
treec9a8a5555b8bffd7808612c10958a1cd96a7a75f /src
parentaf617d0febe392e1d55978df89a73f6c2fca74d4 (diff)
downloademacs-e35644615b2a506daa457cbc5613ba8d16a46be6.tar.gz
emacs-e35644615b2a506daa457cbc5613ba8d16a46be6.zip
Inserting Yamomotosan's changes for MacOSX image support, better support
of Asian fonts, and some long awaited header cleanup and centralization.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog212
-rw-r--r--src/dispextern.h30
-rw-r--r--src/emacs.c2
-rw-r--r--src/macfns.c2937
-rw-r--r--src/macgui.h36
-rw-r--r--src/macmenu.c29
-rw-r--r--src/macterm.c1050
-rw-r--r--src/macterm.h46
-rw-r--r--src/s/darwin.h2
9 files changed, 3146 insertions, 1198 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 892e7c621a5..0fe8fbf9225 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,215 @@
12004-02-26 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2
3 * s/darwin.h (LD_SWITCH_SYSTEM_TEMACS): Add `-framework
4 QuickTime'.
5
6 * dispextern.h [MAC_OSX]: Do not include Carbon/Carbon.h (now in
7 macgui.h).
8
9 * emacs.c (main) [HAVE_CARBON]: Call init_xfns.
10
11 * macgui.h [MAC_OSX]: Include Carbon/Carbon.h.
12 (mktime, DEBUG, Z, free, malloc, realloc, max, min)
13 (init_process) [MAC_OSX] : Avoid conflicts with Carbon/Carbon.h.
14 [!MAC_OSX]: Include QDOffscreen.h and Controls.h.
15 (INFINITY) [MAC_OSX]: Avoid conflict with definition in math.h.
16 (Bitmap): Remove typedef.
17 (Pixmap): Change int to GWorldPtr.
18
19 * macmenu.c [MAC_OSX]: Do not include Carbon/Carbon.h (now in
20 macgui.h).
21
22 * macterm.h [MAC_OSX]: Do not include Carbon/Carbon.h (now in
23 macgui.h).
24 (RED16_FROM_ULONG, GREEN16_FROM_ULONG, BLUE16_FROM_ULONG): New
25 #define to extract 16-bit depth color components from unsigned
26 long representation.
27 (PIX_MASK_DRAW, PIX_MASK_RETAIN): New #define to represent pixel
28 colors used for masks.
29 (struct mac_display_info): Add color_p. Remove n_cbits.
30
31 * macfns.c: Include sys/types.h and sys/stat.h.
32 [MAC_OSX]: Do not include Carbon/Carbon.h (now in macgui.h).
33 Include QuickTime/QuickTime.h.
34 (XCreatePixmap, XCreatePixmapFromBitmapData, XFreePixmap)
35 (XSetForeground, mac_draw_line_to_pixmap): Add externs for
36 functions defined in macterm.c.
37 (XImagePtr): New typedef. Corresponds to XImage * in xfns.c.
38 (ZPixmap): New #define for compatibility with xfns.c.
39 (XGetImage, XPutPixel, XGetPixel, XDestroyImage)
40 (x_create_x_image_and_pixmap, x_destroy_x_image, x_put_x_image)
41 (find_image_fsspec, image_load_qt_1, image_load_quicktime): New
42 functions.
43 (four_corners_best, x_create_x_image_and_pixmap)
44 (x_destroy_x_image, unwind_create_frame, x_disable_image,
45 (x_edge_detection, init_color_table, colors_in_color_table,
46 (lookup_rgb_color, lookup_pixel_color, postprocess_image)
47 (x_put_x_image, slurp_file, xbm_scan, xbm_load, xbm_load_image)
48 (xbm_image_p, xbm_read_bitmap_data, xbm_file_p, x_to_xcolors)
49 (x_from_xcolors, x_detect_edges): New declarations (from xfns.c).
50 (mac_color_map_lookup, x_to_mac_color): Fix Lisp_Object/unsigned
51 long mixup.
52 (mac_defined_color, x_to_x_colors): Use RED16_FROM_ULONG etc.
53 (x_decode_color): Don't use n_cbits (in struct mac_display_info).
54 (x_set_foreground_color, x_set_cursor_color): Sync with w32fns.c.
55 (x_set_cursor_type, Fxw_color_values, valid_image_p)
56 (image_value_type, parse_image_spec, image_ascent, x_clear_image)
57 (x_alloc_image_color, clear_image_cache, lookup_image)
58 (x_find_image_file, xbm_read_bitmap_file_data)
59 (enum xbm_keyword_index, xbm_format, xbm_image_p, xbm_scan)
60 (xbm_read_bitmap_data, xbm_load, pbm_image_p, pbm_scan_number)
61 (enum pbm_keyword_index, pbm_format, enum png_keyword_index)
62 (png_format, png_image_p, enum jpeg_keyword_index, jpeg_format)
63 (jpeg_image_p, enum tiff_keyword_index, tiff_format, tiff_image_p)
64 (enum gif_keyword_index, gif_format, gif_image_p): Sync with
65 xfns.c.
66 (x_make_gc): Sync with xfns.c. Enclose unused `border_tile' with
67 #if 0.
68 (x_free_gcs): Sync with xfns.c. Enclose unused `border_tile' with
69 #if 0. Free white_relief.gc and black_relief.gc.
70 (unwind_create_frame, x_emboss, x_laplace, x_edge_detection): New
71 functions (from xfns.c).
72 (Fx_create_frame): Record unwind_create_frame.
73 (Fxw_display_color_p): Use dpyinfo->color_p.
74 (Fx_display_grayscale_p, Fx_display_planes): Don't use
75 dpyinfo->n_cbits.
76 (Fx_display_color_cells): Use dpyinfo->n_planes;
77 (QCmatrix, QCcolor_adjustment, QCmask, Qemboss, Qedge_detection)
78 (Qheuristic, cross_disabled_images, emboss_matrix)
79 (laplace_matrix): New variables (from xfns.c).
80 (Fimage_size, Fimage_mask_p, four_corners_best, image_background)
81 (x_clear_image_1, postprocess_image, slurp_file, xbm_load_image)
82 (xbm_file_p, x_to_xcolors, x_from_xcolors, x_detect_edges)
83 (image_background_transparent): New function (from xfns.c). Use
84 PIX_MASK_DRAW/PIX_MASK_RETAIN.
85 (image_load_quicktime): Add declaration.
86 [MAC_OSX] (image_load_quartz2d): Likewise.
87 [MAC_OSX] (CGImageCreateWithPNGDataProviderProcType): New typedef.
88 [MAC_OSX] (MyCGImageCreateWithPNGDataProvider): New variable.
89 [MAC_OSX] (init_image_func_pointer, image_load_quartz2d): New
90 functions.
91 (xbm_load_image_from_file, x_laplace_read_row)
92 (x_laplace_write_row, pbm_read_file): Remove functions.
93 [HAVE_XPM] (enum xpm_keyword_index, xpm_format, xpm_image_p)
94 (xpm_load): Sync with xfns.c (although XPM is not supported yet).
95 (colors_in_color_table): Sync with xfns.c (although not used).
96 (lookup_rgb_color): Don't lookup color table. Just do gamma
97 correction.
98 (COLOR_INTENSITY): New #define (from xfns.c).
99 (x_disable_image): New function (from xfns.c). Use
100 PIX_MASK_DRAW/PIX_MASK_RETAIN.
101 (x_build_heuristic_mask): Sync with xfns.c. Use
102 PIX_MASK_DRAW/PIX_MASK_RETAIN.
103 (HAVE_PBM): Remove #ifdef.
104 (pbm_load): Sync with xfns.c. Set img->width and img->height
105 before IMAGE_BACKGROUND.
106 (png_image_p, png_load): Don't enclose declarations with #if
107 HAVE_PNG.
108 (Qpng, enum png_keyword_index, png_format, png_type, png_image_p):
109 Don't enclose with #if HAVE_PNG.
110 [!HAVE_PNG] (png_load) [MAC_OSX]: Use image_load_quartz2d if a
111 symbol _CGImageCreateWithPNGDataProvider is defined. Otherwise
112 use image_load_quicktime.
113 [!HAVE_PNG] (png_load) [!MAC_OSX]: Use image_load_quicktime.
114 [HAVE_PNG] (png_load): Sync with xfns.c. Use
115 PIX_MASK_DRAW/PIX_MASK_RETAIN.
116 (jpeg_image_p, jpeg_load): Don't enclose declarations with #if
117 HAVE_JPEG.
118 (Qjpeg, enum jpeg_keyword_index, jpeg_format, jpeg_type)
119 (jpeg_image_p): Don't enclose with #if HAVE_JPEG.
120 [!HAVE_JPEG] (jpeg_load) [MAC_OSX]: Use image_load_quartz2d.
121 [!HAVE_JPEG] (jpeg_load) [!MAC_OSX]: Use image_load_quicktime.
122 [HAVE_JPEG] (jpeg_load): Sync with xfns.c.
123 (tiff_image_p, tiff_load): Don't enclose declarations with #if
124 HAVE_TIFF.
125 (Qtiff, enum tiff_keyword_index, tiff_format, tiff_type)
126 (tiff_image_p): Don't enclose with #if HAVE_TIFF.
127 [!HAVE_TIFF] (tiff_load): Use image_load_quicktime.
128 [HAVE_TIFF] (tiff_error_handler, tiff_warning_handler): New
129 functions (from xfns.c).
130 [HAVE_TIFF] (tiff_load): Sync with xfns.c.
131 (gif_image_p, gif_load): Don't enclose declarations with #if
132 HAVE_GIF.
133 (Qgif, enum gif_keyword_index, gif_format, gif_type, gif_image_p):
134 Don't enclose with #if HAVE_GIF.
135 [!HAVE_GIF] (gif_load): Use Quicktime Movie Toolbox if it is
136 animated gif. Otherwise use image_load_quicktime.
137 [HAVE_GIF] (gif_lib.h): Temporarily define DrawText as
138 gif_DrawText to avoid conflict with QuickdrawText.h.
139 [HAVE_GIF] (gif_load): Sync with xfns.c.
140 (enum gs_keyword_index, gs_format, gs_image_p, gs_load)
141 [HAVE_GHOSTSCRIPT] (x_kill_gs_process): Sync with xfns.c (although
142 Ghostscript is not supported yet).
143 (syms_of_macfns): Initialize Qemboss, Qedge_detection, Qheuristic,
144 QCmatrix, QCcolor_adjustment, and QCmask. Add DEFVAR_BOOL
145 cross_disabled_images (from xfns.c). Remove #if 0 for supported
146 image types. Remove #if HAVE_JPEG, HAVE_TIFF, HAVE_GIF, and
147 HAVE_PNG. Add defsubr for Simage_size and Simage_mask_p.
148 (init_xfns): Remove #if HAVE_JPEG, HAVE_TIFF, HAVE_GIF, and
149 HAVE_PNG. Call EnterMovies to support animated gifs. Call
150 init_image_func_pointer to bind a symbol
151 _CGImageCreateWithPNGDataProvider if it is defined.
152
153 * macterm.c [MAC_OSX]: Do not include Carbon/Carbon.h (now in
154 macgui.h).
155 (x_draw_bar_cursor): Sync declaration with xterm.c.
156 (XFreePixmap, mac_draw_rectangle_to_pixmap, mac_copy_area)
157 (mac_copy_area_to_pixmap): Implementation with GWorld (offscreen
158 graphics).
159 (mac_set_forecolor, mac_set_backcolor): Use RED16_FROM_ULONG etc.
160 (mac_draw_line_to_pixmap, XCreatePixmap)
161 (XCreatePixmapFromBitmapData, mac_fill_rectangle_to_pixmap)
162 (mac_copy_area_with_mask, mac_copy_area_with_mask_to_pixmap): New
163 functions.
164 (mac_draw_bitmap) [TARGET_API_MAC_CARBON]: Use
165 GetPortBitMapForCopyBits instead of the cast to Bitmap *. Cast
166 bits to char *.
167 (reflect_byte): New function (from w32fns.c).
168 (mac_create_bitmap_from_bitmap_data): Use it and don't stuff bits
169 due to byte alignment.
170 (mac_scroll_area) [TARGET_API_MAC_CARBON]: Use
171 GetPortBitMapForCopyBits instead of the cast to Bitmap *.
172 (XSetForeground): Remove static (now used in macfns.c).
173 (HIGHLIGHT_COLOR_DARK_BOOST_LIMIT): New #define (from w32term.c).
174 (mac_alloc_lighter_color, x_destroy_window): Sync with w32term.c.
175 (x_setup_relief_color, x_setup_relief_colors, x_draw_box_rect)
176 (x_draw_glyph_string_box, x_draw_image_foreground)
177 (x_draw_image_foreground_1, x_draw_image_glyph_string)
178 (x_draw_stretch_glyph_string, x_draw_glyph_string)
179 (x_draw_hollow_cursor, x_draw_bar_cursor, mac_draw_window_cursor):
180 Sync with xterm.c.
181 (x_draw_relief_rect): Sync with xterm.c. Make 1 pixel shorter
182 than the xterm.c version when a strictly horizontal or vertical
183 line is drawn.
184 (XTset_terminal_window): Add static.
185 (x_make_frame_visible): Add UNBLOCK_INPUT.
186 (x_free_frame_resources): New funcion (from xterm.c).
187 (XTread_socket): Call handle_tool_bar_click if mouse up/down event
188 occurs in tool bar area.
189 (mac_initialize_display_info): Remove dpyinfo->n_cbits. Set
190 dpyinfo->color_p. Determine dpyinfo->n_planes using HasDepth.
191 Initialize image cache.
192 (stricmp, wildstrieq, mac_font_pattern_match, mac_font_match):
193 Enclose unused functions with #if 0.
194 (Qbig5, Qcn_gb, Qsjis, Qeuc_kr): New variables.
195 (decode_mac_font_name): New function to apply code conversions
196 from a mac font name to an XLFD font name according to its script
197 code.
198 (x_font_name_to_mac_font_name): Apply code conversion from an XLFD
199 font name to a mac font name according to REGISTRY and ENCODING
200 fields.
201 (init_font_name_table) [TARGET_API_MAC_CARBON]: Don't use a font
202 whose name starts with `.'.
203 (init_font_name_table): Use decode_mac_font_name. Add both
204 jisx0208.1983-sjis and jisx0201.1976-0 entries if the script code
205 of a font is smJapanese.
206 (mac_do_list_fonts): New function to list fonts that match a given
207 pattern.
208 (x_list_fonts, XLoadQueryFont): Use it.
209 (XLoadQueryFont): Set rbearing field for each variable width
210 character to avoid needless redraw.
211 (syms_of_macterm): Initialize Qbig5, Qcn_gb, Qsjis, and Qeuc_kr.
212
12004-02-26 Kim F. Storm <storm@cua.dk> 2132004-02-26 Kim F. Storm <storm@cua.dk>
2 214
3 * keyboard.c (NREAD_INPUT_EVENTS): Temporarily increase to 512 215 * keyboard.c (NREAD_INPUT_EVENTS): Temporarily increase to 512
diff --git a/src/dispextern.h b/src/dispextern.h
index fc27c6e185e..bb421e0618b 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -61,38 +61,8 @@ typedef struct w32_display_info Display_Info;
61#ifdef HAVE_CARBON 61#ifdef HAVE_CARBON
62#include "macgui.h" 62#include "macgui.h"
63typedef struct mac_display_info Display_Info; 63typedef struct mac_display_info Display_Info;
64
65/* Include Carbon.h to define Cursor and Rect. */
66#undef mktime
67#undef DEBUG
68#undef Z
69#undef free
70#undef malloc
71#undef realloc
72/* Macros max and min defined in lisp.h conflict with those in
73 precompiled header Carbon.h. */
74#undef max
75#undef min
76#undef init_process
77#include <Carbon/Carbon.h>
78#undef Z
79#define Z (current_buffer->text->z)
80#undef free
81#define free unexec_free
82#undef malloc
83#define malloc unexec_malloc
84#undef realloc
85#define realloc unexec_realloc
86#undef min
87#define min(a, b) ((a) < (b) ? (a) : (b))
88#undef max
89#define max(a, b) ((a) > (b) ? (a) : (b))
90#undef init_process
91#define init_process emacs_init_process
92
93#endif 64#endif
94 65
95
96#ifndef NativeRectangle 66#ifndef NativeRectangle
97#define NativeRectangle int 67#define NativeRectangle int
98#endif 68#endif
diff --git a/src/emacs.c b/src/emacs.c
index 283f7949bfd..66a2af72fb5 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1589,7 +1589,7 @@ main (argc, argv
1589 init_vmsproc (); /* And this too. */ 1589 init_vmsproc (); /* And this too. */
1590#endif /* VMS */ 1590#endif /* VMS */
1591 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.). */ 1591 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.). */
1592#if defined (HAVE_X_WINDOWS) || defined (WINDOWSNT) 1592#if defined (HAVE_X_WINDOWS) || defined (WINDOWSNT) || defined (HAVE_CARBON)
1593 init_xfns (); 1593 init_xfns ();
1594#endif /* HAVE_X_WINDOWS */ 1594#endif /* HAVE_X_WINDOWS */
1595 init_fns (); 1595 init_fns ();
diff --git a/src/macfns.c b/src/macfns.c
index a01811048fe..1b854489480 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -54,6 +54,8 @@ static unsigned char gray_bits[] = {
54/*#include <commdlg.h> 54/*#include <commdlg.h>
55#include <shellapi.h>*/ 55#include <shellapi.h>*/
56#include <ctype.h> 56#include <ctype.h>
57#include <sys/types.h>
58#include <sys/stat.h>
57 59
58#include <stdlib.h> 60#include <stdlib.h>
59#include <string.h> 61#include <string.h>
@@ -62,32 +64,7 @@ static unsigned char gray_bits[] = {
62#endif 64#endif
63 65
64#ifdef MAC_OSX 66#ifdef MAC_OSX
65#undef mktime 67#include <QuickTime/QuickTime.h>
66#undef DEBUG
67#undef Z
68#undef free
69#undef malloc
70#undef realloc
71/* Macros max and min defined in lisp.h conflict with those in
72 precompiled header Carbon.h. */
73#undef max
74#undef min
75#undef init_process
76#include <Carbon/Carbon.h>
77#undef Z
78#define Z (current_buffer->text->z)
79#undef free
80#define free unexec_free
81#undef malloc
82#define malloc unexec_malloc
83#undef realloc
84#define realloc unexec_realloc
85#undef min
86#define min(a, b) ((a) < (b) ? (a) : (b))
87#undef max
88#define max(a, b) ((a) > (b) ? (a) : (b))
89#undef init_process
90#define init_process emacs_init_process
91#else /* not MAC_OSX */ 68#else /* not MAC_OSX */
92#include <Windows.h> 69#include <Windows.h>
93#include <Gestalt.h> 70#include <Gestalt.h>
@@ -209,6 +186,12 @@ extern struct font_info *x_load_font (struct frame *, char *, int);
209extern void x_find_ccl_program (struct font_info *); 186extern void x_find_ccl_program (struct font_info *);
210extern struct font_info *x_query_font (struct frame *, char *); 187extern struct font_info *x_query_font (struct frame *, char *);
211extern void mac_initialize (); 188extern void mac_initialize ();
189extern Pixmap XCreatePixmap (Display *, WindowPtr, unsigned int, unsigned int, unsigned int);
190extern Pixmap XCreatePixmapFromBitmapData (Display *, WindowPtr, char *, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int);
191extern void XFreePixmap (Display *, Pixmap);
192extern void XSetForeground (Display *, GC, unsigned long);
193extern void mac_draw_line_to_pixmap (Display *, Pixmap, GC, int, int, int, int);
194
212 195
213/* compare two strings ignoring case */ 196/* compare two strings ignoring case */
214 197
@@ -552,13 +535,89 @@ x_destroy_all_bitmaps (dpyinfo)
552 xfree (dpyinfo->bitmaps[i].bitmap_data); 535 xfree (dpyinfo->bitmaps[i].bitmap_data);
553 dpyinfo->bitmaps_last = 0; 536 dpyinfo->bitmaps_last = 0;
554} 537}
538
539
555 540
556/* Connect the frame-parameter names for W32 frames 541/* Mac equivalent of XImage. */
557 to the ways of passing the parameter values to the window system. 542typedef Pixmap XImagePtr;
543#define ZPixmap 0 /* arbitrary */
544
545static XImagePtr
546XGetImage (display, pixmap, x, y, width, height, plane_mask, format)
547 Display *display; /* not used */
548 Pixmap pixmap;
549 int x, y; /* not used */
550 unsigned int width, height; /* not used */
551 unsigned long plane_mask; /* not used */
552 int format; /* not used */
553{
554#if GLYPH_DEBUG
555 xassert (x == 0 && y == 0);
556 {
557 Rect ri, rp;
558 SetRect (&ri, 0, 0, width, height);
559 xassert (EqualRect (&ri, GetPixBounds (GetGWorldPixMap (pixmap), &rp)));
560 }
561 xassert (! (pixelsLocked & GetPixelsState (GetGWorldPixMap (pixmap))));
562#endif
558 563
559 The name of a parameter, as a Lisp symbol, 564 LockPixels (GetGWorldPixMap (pixmap));
560 has an `x-frame-parameter' property which is an integer in Lisp 565
561 but can be interpreted as an `enum x_frame_parm' in C. */ 566 return pixmap;
567}
568
569static void
570XPutPixel (ximage, x, y, pixel)
571 XImagePtr ximage;
572 int x, y;
573 unsigned long pixel;
574{
575 RGBColor color;
576
577 SetGWorld (ximage, NULL);
578
579 color.red = RED16_FROM_ULONG (pixel);
580 color.green = GREEN16_FROM_ULONG (pixel);
581 color.blue = BLUE16_FROM_ULONG (pixel);
582 SetCPixel (x, y, &color);
583}
584
585static unsigned long
586XGetPixel (ximage, x, y)
587 XImagePtr ximage;
588 int x, y;
589{
590 RGBColor color;
591
592 SetGWorld (ximage, NULL);
593
594 GetCPixel (x, y, &color);
595 return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8);
596}
597
598static void
599XDestroyImage (ximg)
600 XImagePtr ximg;
601{
602 UnlockPixels (GetGWorldPixMap (ximg));
603}
604
605
606
607/* Useful functions defined in the section
608 `Image type independent image structures' below. */
609
610static unsigned long four_corners_best P_ ((XImagePtr ximg, unsigned long width,
611 unsigned long height));
612
613static int x_create_x_image_and_pixmap P_ ((struct frame *f, int width, int height,
614 int depth, XImagePtr *ximg,
615 Pixmap *pixmap));
616
617static void x_destroy_x_image P_ ((XImagePtr ximg));
618
619static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
620static void x_disable_image P_ ((struct frame *, struct image *));
562 621
563void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); 622void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
564void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); 623void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
@@ -581,6 +640,13 @@ static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
581 Lisp_Object, 640 Lisp_Object,
582 char *, char *, 641 char *, char *,
583 int)); 642 int));
643static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
644 Lisp_Object));
645static void init_color_table P_ ((void));
646static void free_color_table P_ ((void));
647static unsigned long *colors_in_color_table P_ ((int *n));
648static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b));
649static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
584 650
585/* Store the screen positions of frame F into XPTR and YPTR. 651/* Store the screen positions of frame F into XPTR and YPTR.
586 These are the positions of the containing window manager window, 652 These are the positions of the containing window manager window,
@@ -1382,7 +1448,7 @@ colormap_t mac_color_map[] =
1382 { RGB_TO_ULONG(144, 238, 144), "LightGreen" } 1448 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1383}; 1449};
1384 1450
1385unsigned long 1451Lisp_Object
1386mac_color_map_lookup (colorname) 1452mac_color_map_lookup (colorname)
1387 char *colorname; 1453 char *colorname;
1388{ 1454{
@@ -1394,7 +1460,7 @@ mac_color_map_lookup (colorname)
1394 for (i = 0; i < sizeof (mac_color_map) / sizeof (mac_color_map[0]); i++) 1460 for (i = 0; i < sizeof (mac_color_map) / sizeof (mac_color_map[0]); i++)
1395 if (stricmp (colorname, mac_color_map[i].name) == 0) 1461 if (stricmp (colorname, mac_color_map[i].name) == 0)
1396 { 1462 {
1397 ret = mac_color_map[i].color; 1463 ret = make_number (mac_color_map[i].color);
1398 break; 1464 break;
1399 } 1465 }
1400 1466
@@ -1463,7 +1529,7 @@ x_to_mac_color (colorname)
1463 if (i == 2) 1529 if (i == 2)
1464 { 1530 {
1465 UNBLOCK_INPUT; 1531 UNBLOCK_INPUT;
1466 return (colorval); 1532 return make_number (colorval);
1467 } 1533 }
1468 color = end; 1534 color = end;
1469 } 1535 }
@@ -1516,7 +1582,7 @@ x_to_mac_color (colorname)
1516 if (*end != '\0') 1582 if (*end != '\0')
1517 break; 1583 break;
1518 UNBLOCK_INPUT; 1584 UNBLOCK_INPUT;
1519 return (colorval); 1585 return make_number (colorval);
1520 } 1586 }
1521 if (*end != '/') 1587 if (*end != '/')
1522 break; 1588 break;
@@ -1557,7 +1623,7 @@ x_to_mac_color (colorname)
1557 if (*end != '\0') 1623 if (*end != '\0')
1558 break; 1624 break;
1559 UNBLOCK_INPUT; 1625 UNBLOCK_INPUT;
1560 return (colorval); 1626 return make_number (colorval);
1561 } 1627 }
1562 if (*end != '/') 1628 if (*end != '/')
1563 break; 1629 break;
@@ -1616,9 +1682,9 @@ mac_defined_color (f, color, color_def, alloc)
1616 } 1682 }
1617 1683
1618 color_def->pixel = mac_color_ref; 1684 color_def->pixel = mac_color_ref;
1619 color_def->red = RED_FROM_ULONG (mac_color_ref); 1685 color_def->red = RED16_FROM_ULONG (mac_color_ref);
1620 color_def->green = GREEN_FROM_ULONG (mac_color_ref); 1686 color_def->green = GREEN16_FROM_ULONG (mac_color_ref);
1621 color_def->blue = BLUE_FROM_ULONG (mac_color_ref); 1687 color_def->blue = BLUE16_FROM_ULONG (mac_color_ref);
1622 1688
1623 return 1; 1689 return 1;
1624 } 1690 }
@@ -1649,8 +1715,7 @@ x_decode_color (f, arg, def)
1649 return WHITE_PIX_DEFAULT (f); 1715 return WHITE_PIX_DEFAULT (f);
1650 1716
1651#if 0 1717#if 0
1652 if ((FRAME_MAC_DISPLAY_INFO (f)->n_planes 1718 if (FRAME_MAC_DISPLAY_INFO (f)->n_planes) == 1)
1653 * FRAME_MAC_DISPLAY_INFO (f)->n_cbits) == 1)
1654 return def; 1719 return def;
1655#endif 1720#endif
1656 1721
@@ -1674,8 +1739,11 @@ x_set_foreground_color (f, arg, oldval)
1674 struct frame *f; 1739 struct frame *f;
1675 Lisp_Object arg, oldval; 1740 Lisp_Object arg, oldval;
1676{ 1741{
1677 FRAME_FOREGROUND_PIXEL (f) 1742 unsigned long fg, old_fg;
1678 = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); 1743
1744 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1745 old_fg = FRAME_FOREGROUND_PIXEL (f);
1746 FRAME_FOREGROUND_PIXEL (f) = fg;
1679 1747
1680 if (FRAME_MAC_WINDOW (f) != 0) 1748 if (FRAME_MAC_WINDOW (f) != 0)
1681 { 1749 {
@@ -1856,36 +1924,42 @@ x_set_cursor_color (f, arg, oldval)
1856 struct frame *f; 1924 struct frame *f;
1857 Lisp_Object arg, oldval; 1925 Lisp_Object arg, oldval;
1858{ 1926{
1859 unsigned long fore_pixel; 1927 unsigned long fore_pixel, pixel;
1860 1928
1861 if (!NILP (Vx_cursor_fore_pixel)) 1929 if (!NILP (Vx_cursor_fore_pixel))
1862 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel, 1930 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1863 WHITE_PIX_DEFAULT (f)); 1931 WHITE_PIX_DEFAULT (f));
1864 else 1932 else
1865 fore_pixel = FRAME_BACKGROUND_PIXEL (f); 1933 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1866 f->output_data.mac->cursor_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); 1934
1935 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1867 1936
1868 /* Make sure that the cursor color differs from the background color. */ 1937 /* Make sure that the cursor color differs from the background color. */
1869 if (f->output_data.mac->cursor_pixel == FRAME_BACKGROUND_PIXEL (f)) 1938 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1870 { 1939 {
1871 f->output_data.mac->cursor_pixel = f->output_data.mac->mouse_pixel; 1940 pixel = f->output_data.mac->mouse_pixel;
1872 if (f->output_data.mac->cursor_pixel == fore_pixel) 1941 if (pixel == fore_pixel)
1873 fore_pixel = FRAME_BACKGROUND_PIXEL (f); 1942 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1874 } 1943 }
1875 FRAME_FOREGROUND_PIXEL (f) = fore_pixel;
1876 1944
1877#if 0 /* MAC_TODO: cannot figure out what to do (wrong number of params) */ 1945 f->output_data.mac->cursor_foreground_pixel = fore_pixel;
1946 f->output_data.mac->cursor_pixel = pixel;
1947
1878 if (FRAME_MAC_WINDOW (f) != 0) 1948 if (FRAME_MAC_WINDOW (f) != 0)
1879 { 1949 {
1950 BLOCK_INPUT;
1951 /* Update frame's cursor_gc. */
1952 f->output_data.mac->cursor_gc->foreground = fore_pixel;
1953 f->output_data.mac->cursor_gc->background = pixel;
1954
1955 UNBLOCK_INPUT;
1956
1880 if (FRAME_VISIBLE_P (f)) 1957 if (FRAME_VISIBLE_P (f))
1881 { 1958 {
1882 BLOCK_INPUT; 1959 x_update_cursor (f, 0);
1883 display_and_set_cursor (f, 0); 1960 x_update_cursor (f, 1);
1884 display_and_set_cursor (f, 1);
1885 UNBLOCK_INPUT;
1886 } 1961 }
1887 } 1962 }
1888#endif
1889 1963
1890 update_face_from_frame_parameter (f, Qcursor_color, arg); 1964 update_face_from_frame_parameter (f, Qcursor_color, arg);
1891} 1965}
@@ -1893,11 +1967,13 @@ x_set_cursor_color (f, arg, oldval)
1893/* Set the border-color of frame F to pixel value PIX. 1967/* Set the border-color of frame F to pixel value PIX.
1894 Note that this does not fully take effect if done before 1968 Note that this does not fully take effect if done before
1895 F has a window. */ 1969 F has a window. */
1970
1896void 1971void
1897x_set_border_pixel (f, pix) 1972x_set_border_pixel (f, pix)
1898 struct frame *f; 1973 struct frame *f;
1899 int pix; 1974 int pix;
1900{ 1975{
1976
1901 f->output_data.mac->border_pixel = pix; 1977 f->output_data.mac->border_pixel = pix;
1902 1978
1903 if (FRAME_MAC_WINDOW (f) != 0 && f->border_width > 0) 1979 if (FRAME_MAC_WINDOW (f) != 0 && f->border_width > 0)
@@ -1926,6 +2002,7 @@ x_set_border_color (f, arg, oldval)
1926 update_face_from_frame_parameter (f, Qborder_color, arg); 2002 update_face_from_frame_parameter (f, Qborder_color, arg);
1927} 2003}
1928 2004
2005
1929void 2006void
1930x_set_cursor_type (f, arg, oldval) 2007x_set_cursor_type (f, arg, oldval)
1931 FRAME_PTR f; 2008 FRAME_PTR f;
@@ -1933,9 +2010,8 @@ x_set_cursor_type (f, arg, oldval)
1933{ 2010{
1934 set_frame_cursor_types (f, arg); 2011 set_frame_cursor_types (f, arg);
1935 2012
1936 /* Make sure the cursor gets redrawn. This is overkill, but how 2013 /* Make sure the cursor gets redrawn. */
1937 often do people change cursor types? */ 2014 cursor_type_changed = 1;
1938 update_mode_lines++;
1939} 2015}
1940 2016
1941#if 0 /* MAC_TODO: really no icon for Mac */ 2017#if 0 /* MAC_TODO: really no icon for Mac */
@@ -2597,7 +2673,7 @@ x_make_gc (f)
2597 2673
2598 BLOCK_INPUT; 2674 BLOCK_INPUT;
2599 2675
2600 /* Create the GC's of this frame. 2676 /* Create the GCs of this frame.
2601 Note that many default values are used. */ 2677 Note that many default values are used. */
2602 2678
2603 /* Normal video */ 2679 /* Normal video */
@@ -2629,10 +2705,104 @@ x_make_gc (f)
2629 f->output_data.mac->white_relief.gc = 0; 2705 f->output_data.mac->white_relief.gc = 0;
2630 f->output_data.mac->black_relief.gc = 0; 2706 f->output_data.mac->black_relief.gc = 0;
2631 2707
2708#if 0
2709 /* Create the gray border tile used when the pointer is not in
2710 the frame. Since this depends on the frame's pixel values,
2711 this must be done on a per-frame basis. */
2712 f->output_data.x->border_tile
2713 = (XCreatePixmapFromBitmapData
2714 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2715 gray_bits, gray_width, gray_height,
2716 f->output_data.x->foreground_pixel,
2717 f->output_data.x->background_pixel,
2718 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2719#endif
2720
2632 UNBLOCK_INPUT; 2721 UNBLOCK_INPUT;
2633} 2722}
2634 2723
2635 2724
2725/* Free what was was allocated in x_make_gc. */
2726
2727void
2728x_free_gcs (f)
2729 struct frame *f;
2730{
2731 Display *dpy = FRAME_MAC_DISPLAY (f);
2732
2733 BLOCK_INPUT;
2734
2735 if (f->output_data.mac->normal_gc)
2736 {
2737 XFreeGC (dpy, f->output_data.mac->normal_gc);
2738 f->output_data.mac->normal_gc = 0;
2739 }
2740
2741 if (f->output_data.mac->reverse_gc)
2742 {
2743 XFreeGC (dpy, f->output_data.mac->reverse_gc);
2744 f->output_data.mac->reverse_gc = 0;
2745 }
2746
2747 if (f->output_data.mac->cursor_gc)
2748 {
2749 XFreeGC (dpy, f->output_data.mac->cursor_gc);
2750 f->output_data.mac->cursor_gc = 0;
2751 }
2752
2753#if 0
2754 if (f->output_data.mac->border_tile)
2755 {
2756 XFreePixmap (dpy, f->output_data.mac->border_tile);
2757 f->output_data.mac->border_tile = 0;
2758 }
2759#endif
2760
2761 if (f->output_data.mac->white_relief.gc)
2762 {
2763 XFreeGC (dpy, f->output_data.mac->white_relief.gc);
2764 f->output_data.mac->white_relief.gc = 0;
2765 }
2766
2767 if (f->output_data.mac->black_relief.gc)
2768 {
2769 XFreeGC (dpy, f->output_data.mac->black_relief.gc);
2770 f->output_data.mac->black_relief.gc = 0;
2771 }
2772
2773 UNBLOCK_INPUT;
2774}
2775
2776
2777/* Handler for signals raised during x_create_frame and
2778 x_create_top_frame. FRAME is the frame which is partially
2779 constructed. */
2780
2781static Lisp_Object
2782unwind_create_frame (frame)
2783 Lisp_Object frame;
2784{
2785 struct frame *f = XFRAME (frame);
2786
2787 /* If frame is ``official'', nothing to do. */
2788 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
2789 {
2790#if GLYPH_DEBUG
2791 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2792#endif
2793
2794 x_free_frame_resources (f);
2795
2796 /* Check that reference counts are indeed correct. */
2797 xassert (dpyinfo->reference_count == dpyinfo_refcount);
2798 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
2799 return Qt;
2800 }
2801
2802 return Qnil;
2803}
2804
2805
2636DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 2806DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2637 1, 1, 0, 2807 1, 1, 0,
2638 doc: /* Make a new window, which is called a \"frame\" in Emacs terms. 2808 doc: /* Make a new window, which is called a \"frame\" in Emacs terms.
@@ -2736,10 +2906,7 @@ This function is an internal primitive--use `make-frame' instead. */)
2736 FRAME_FONTSET (f) = -1; 2906 FRAME_FONTSET (f) = -1;
2737 f->output_data.mac->scroll_bar_foreground_pixel = -1; 2907 f->output_data.mac->scroll_bar_foreground_pixel = -1;
2738 f->output_data.mac->scroll_bar_background_pixel = -1; 2908 f->output_data.mac->scroll_bar_background_pixel = -1;
2739 2909 record_unwind_protect (unwind_create_frame, frame);
2740#if 0
2741 FRAME_FONTSET (f) = -1;
2742#endif
2743 2910
2744 f->icon_name 2911 f->icon_name
2745 = mac_get_arg (parms, Qicon_name, "iconName", "Title", RES_TYPE_STRING); 2912 = mac_get_arg (parms, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
@@ -2790,17 +2957,18 @@ This function is an internal primitive--use `make-frame' instead. */)
2790 /* First, try whatever font the caller has specified. */ 2957 /* First, try whatever font the caller has specified. */
2791 if (STRINGP (font)) 2958 if (STRINGP (font))
2792 { 2959 {
2793 tem = Fquery_fontset (font, Qnil); 2960 tem = Fquery_fontset (font, Qnil);
2794 if (STRINGP (tem)) 2961 if (STRINGP (tem))
2795 font = x_new_fontset (f, SDATA (tem)); 2962 font = x_new_fontset (f, SDATA (tem));
2796 else 2963 else
2797 font = x_new_font (f, SDATA (font)); 2964 font = x_new_font (f, SDATA (font));
2798 } 2965 }
2966
2799 /* Try out a font which we hope has bold and italic variations. */ 2967 /* Try out a font which we hope has bold and italic variations. */
2800 if (! STRINGP (font)) 2968 if (! STRINGP (font))
2801 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1"); 2969 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
2802 /* If those didn't work, look for something which will at least work. */ 2970 /* If those didn't work, look for something which will at least work. */
2803 if (!STRINGP (font)) 2971 if (! STRINGP (font))
2804 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman"); 2972 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
2805 if (! STRINGP (font)) 2973 if (! STRINGP (font))
2806 font = x_new_font (f, "-*-courier-*-10-*-mac-roman"); 2974 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
@@ -3011,12 +3179,9 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3011 { 3179 {
3012 Lisp_Object rgb[3]; 3180 Lisp_Object rgb[3];
3013 3181
3014 rgb[0] = make_number ((RED_FROM_ULONG (foo.pixel) << 8) 3182 rgb[0] = make_number (foo.red);
3015 | RED_FROM_ULONG (foo.pixel)); 3183 rgb[1] = make_number (foo.green);
3016 rgb[1] = make_number ((GREEN_FROM_ULONG (foo.pixel) << 8) 3184 rgb[2] = make_number (foo.blue);
3017 | GREEN_FROM_ULONG (foo.pixel));
3018 rgb[2] = make_number ((BLUE_FROM_ULONG (foo.pixel) << 8)
3019 | BLUE_FROM_ULONG (foo.pixel));
3020 return Flist (3, rgb); 3185 return Flist (3, rgb);
3021 } 3186 }
3022 else 3187 else
@@ -3030,7 +3195,7 @@ DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3030{ 3195{
3031 struct mac_display_info *dpyinfo = check_x_display_info (display); 3196 struct mac_display_info *dpyinfo = check_x_display_info (display);
3032 3197
3033 if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 2) 3198 if (!dpyinfo->color_p)
3034 return Qnil; 3199 return Qnil;
3035 3200
3036 return Qt; 3201 return Qt;
@@ -3048,7 +3213,7 @@ If omitted or nil, that stands for the selected frame's display. */)
3048{ 3213{
3049 struct mac_display_info *dpyinfo = check_x_display_info (display); 3214 struct mac_display_info *dpyinfo = check_x_display_info (display);
3050 3215
3051 if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 1) 3216 if (dpyinfo->n_planes <= 1)
3052 return Qnil; 3217 return Qnil;
3053 3218
3054 return Qt; 3219 return Qt;
@@ -3093,7 +3258,7 @@ If omitted or nil, that stands for the selected frame's display. */)
3093{ 3258{
3094 struct mac_display_info *dpyinfo = check_x_display_info (display); 3259 struct mac_display_info *dpyinfo = check_x_display_info (display);
3095 3260
3096 return make_number (dpyinfo->n_planes * dpyinfo->n_cbits); 3261 return make_number (dpyinfo->n_planes);
3097} 3262}
3098 3263
3099DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells, 3264DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
@@ -3108,7 +3273,7 @@ If omitted or nil, that stands for the selected frame's display. */)
3108 struct mac_display_info *dpyinfo = check_x_display_info (display); 3273 struct mac_display_info *dpyinfo = check_x_display_info (display);
3109 3274
3110 /* MAC_TODO: check whether this is right */ 3275 /* MAC_TODO: check whether this is right */
3111 return make_number ((unsigned long) (pow (2, dpyinfo->n_cbits))); 3276 return make_number (dpyinfo->n_planes >= 8 ? 256 : 1 << dpyinfo->n_planes - 1);
3112} 3277}
3113 3278
3114DEFUN ("x-server-max-request-size", Fx_server_max_request_size, 3279DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
@@ -3446,6 +3611,7 @@ If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
3446 return Qnil; 3611 return Qnil;
3447} 3612}
3448 3613
3614
3449 3615
3450/*********************************************************************** 3616/***********************************************************************
3451 Image types 3617 Image types
@@ -3470,11 +3636,11 @@ extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
3470extern Lisp_Object QCdata, QCtype; 3636extern Lisp_Object QCdata, QCtype;
3471Lisp_Object QCascent, QCmargin, QCrelief; 3637Lisp_Object QCascent, QCmargin, QCrelief;
3472Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; 3638Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
3473Lisp_Object QCindex; 3639Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
3474 3640
3475/* Other symbols. */ 3641/* Other symbols. */
3476 3642
3477Lisp_Object Qlaplace; 3643Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
3478 3644
3479/* Time in seconds after which images should be removed from the cache 3645/* Time in seconds after which images should be removed from the cache
3480 if not displayed. */ 3646 if not displayed. */
@@ -3487,6 +3653,7 @@ static void define_image_type P_ ((struct image_type *type));
3487static struct image_type *lookup_image_type P_ ((Lisp_Object symbol)); 3653static struct image_type *lookup_image_type P_ ((Lisp_Object symbol));
3488static void image_error P_ ((char *format, Lisp_Object, Lisp_Object)); 3654static void image_error P_ ((char *format, Lisp_Object, Lisp_Object));
3489static void x_laplace P_ ((struct frame *, struct image *)); 3655static void x_laplace P_ ((struct frame *, struct image *));
3656static void x_emboss P_ ((struct frame *, struct image *));
3490static int x_build_heuristic_mask P_ ((struct frame *, struct image *, 3657static int x_build_heuristic_mask P_ ((struct frame *, struct image *,
3491 Lisp_Object)); 3658 Lisp_Object));
3492 3659
@@ -3540,11 +3707,22 @@ valid_image_p (object)
3540 3707
3541 if (IMAGEP (object)) 3708 if (IMAGEP (object))
3542 { 3709 {
3543 Lisp_Object symbol = Fplist_get (XCDR (object), QCtype); 3710 Lisp_Object tem;
3544 struct image_type *type = lookup_image_type (symbol);
3545 3711
3546 if (type) 3712 for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem))
3547 valid_p = type->valid_p (object); 3713 if (EQ (XCAR (tem), QCtype))
3714 {
3715 tem = XCDR (tem);
3716 if (CONSP (tem) && SYMBOLP (XCAR (tem)))
3717 {
3718 struct image_type *type;
3719 type = lookup_image_type (XCAR (tem));
3720 if (type)
3721 valid_p = type->valid_p (object);
3722 }
3723
3724 break;
3725 }
3548 } 3726 }
3549 3727
3550 return valid_p; 3728 return valid_p;
@@ -3554,8 +3732,8 @@ valid_image_p (object)
3554/* Log error message with format string FORMAT and argument ARG. 3732/* Log error message with format string FORMAT and argument ARG.
3555 Signaling an error, e.g. when an image cannot be loaded, is not a 3733 Signaling an error, e.g. when an image cannot be loaded, is not a
3556 good idea because this would interrupt redisplay, and the error 3734 good idea because this would interrupt redisplay, and the error
3557 message display would lead to another redisplay. This function 3735 message display would lead to another redisplay. This function
3558 therefore simply displays a message. */ 3736 therefore simply displays a message. */
3559 3737
3560static void 3738static void
3561image_error (format, arg1, arg2) 3739image_error (format, arg1, arg2)
@@ -3575,6 +3753,7 @@ enum image_value_type
3575{ 3753{
3576 IMAGE_DONT_CHECK_VALUE_TYPE, 3754 IMAGE_DONT_CHECK_VALUE_TYPE,
3577 IMAGE_STRING_VALUE, 3755 IMAGE_STRING_VALUE,
3756 IMAGE_STRING_OR_NIL_VALUE,
3578 IMAGE_SYMBOL_VALUE, 3757 IMAGE_SYMBOL_VALUE,
3579 IMAGE_POSITIVE_INTEGER_VALUE, 3758 IMAGE_POSITIVE_INTEGER_VALUE,
3580 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 3759 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
@@ -3654,7 +3833,7 @@ parse_image_spec (spec, keywords, nkeywords, type)
3654 break; 3833 break;
3655 3834
3656 if (i == nkeywords) 3835 if (i == nkeywords)
3657 continue; 3836 continue;
3658 3837
3659 /* Record that we recognized the keyword. If a keywords 3838 /* Record that we recognized the keyword. If a keywords
3660 was found more than once, it's an error. */ 3839 was found more than once, it's an error. */
@@ -3672,6 +3851,11 @@ parse_image_spec (spec, keywords, nkeywords, type)
3672 return 0; 3851 return 0;
3673 break; 3852 break;
3674 3853
3854 case IMAGE_STRING_OR_NIL_VALUE:
3855 if (!STRINGP (value) && !NILP (value))
3856 return 0;
3857 break;
3858
3675 case IMAGE_SYMBOL_VALUE: 3859 case IMAGE_SYMBOL_VALUE:
3676 if (!SYMBOLP (value)) 3860 if (!SYMBOLP (value))
3677 return 0; 3861 return 0;
@@ -3691,7 +3875,7 @@ parse_image_spec (spec, keywords, nkeywords, type)
3691 break; 3875 break;
3692 return 0; 3876 return 0;
3693 3877
3694 case IMAGE_ASCENT_VALUE: 3878 case IMAGE_ASCENT_VALUE:
3695 if (SYMBOLP (value) && EQ (value, Qcenter)) 3879 if (SYMBOLP (value) && EQ (value, Qcenter))
3696 break; 3880 break;
3697 else if (INTEGERP (value) 3881 else if (INTEGERP (value)
@@ -3780,6 +3964,63 @@ image_spec_value (spec, key, found)
3780} 3964}
3781 3965
3782 3966
3967DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
3968 doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
3969PIXELS non-nil means return the size in pixels, otherwise return the
3970size in canonical character units.
3971FRAME is the frame on which the image will be displayed. FRAME nil
3972or omitted means use the selected frame. */)
3973 (spec, pixels, frame)
3974 Lisp_Object spec, pixels, frame;
3975{
3976 Lisp_Object size;
3977
3978 size = Qnil;
3979 if (valid_image_p (spec))
3980 {
3981 struct frame *f = check_x_frame (frame);
3982 int id = lookup_image (f, spec);
3983 struct image *img = IMAGE_FROM_ID (f, id);
3984 int width = img->width + 2 * img->hmargin;
3985 int height = img->height + 2 * img->vmargin;
3986
3987 if (NILP (pixels))
3988 size = Fcons (make_float ((double) width / FRAME_COLUMN_WIDTH (f)),
3989 make_float ((double) height / FRAME_LINE_HEIGHT (f)));
3990 else
3991 size = Fcons (make_number (width), make_number (height));
3992 }
3993 else
3994 error ("Invalid image specification");
3995
3996 return size;
3997}
3998
3999
4000DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
4001 doc: /* Return t if image SPEC has a mask bitmap.
4002FRAME is the frame on which the image will be displayed. FRAME nil
4003or omitted means use the selected frame. */)
4004 (spec, frame)
4005 Lisp_Object spec, frame;
4006{
4007 Lisp_Object mask;
4008
4009 mask = Qnil;
4010 if (valid_image_p (spec))
4011 {
4012 struct frame *f = check_x_frame (frame);
4013 int id = lookup_image (f, spec);
4014 struct image *img = IMAGE_FROM_ID (f, id);
4015 if (img->mask)
4016 mask = Qt;
4017 }
4018 else
4019 error ("Invalid image specification");
4020
4021 return mask;
4022}
4023
3783 4024
3784 4025
3785/*********************************************************************** 4026/***********************************************************************
@@ -3876,8 +4117,12 @@ image_ascent (img, face)
3876 if (img->ascent == CENTERED_IMAGE_ASCENT) 4117 if (img->ascent == CENTERED_IMAGE_ASCENT)
3877 { 4118 {
3878 if (face->font) 4119 if (face->font)
3879 ascent = height / 2 - (FONT_DESCENT(face->font) 4120 /* This expression is arranged so that if the image can't be
3880 - FONT_BASE(face->font)) / 2; 4121 exactly centered, it will be moved slightly up. This is
4122 because a typical font is `top-heavy' (due to the presence
4123 uppercase letters), so the image placement should err towards
4124 being top-heavy too. It also just generally looks better. */
4125 ascent = (height + face->font->ascent - face->font->descent + 1) / 2;
3881 else 4126 else
3882 ascent = height / 2; 4127 ascent = height / 2;
3883 } 4128 }
@@ -3887,58 +4132,165 @@ image_ascent (img, face)
3887 return ascent; 4132 return ascent;
3888} 4133}
3889 4134
4135
4136/* Image background colors. */
4137
4138static unsigned long
4139four_corners_best (ximg, width, height)
4140 XImagePtr ximg;
4141 unsigned long width, height;
4142{
4143 unsigned long corners[4], best;
4144 int i, best_count;
4145
4146 /* Get the colors at the corners of ximg. */
4147 corners[0] = XGetPixel (ximg, 0, 0);
4148 corners[1] = XGetPixel (ximg, width - 1, 0);
4149 corners[2] = XGetPixel (ximg, width - 1, height - 1);
4150 corners[3] = XGetPixel (ximg, 0, height - 1);
4151
4152 /* Choose the most frequently found color as background. */
4153 for (i = best_count = 0; i < 4; ++i)
4154 {
4155 int j, n;
4156
4157 for (j = n = 0; j < 4; ++j)
4158 if (corners[i] == corners[j])
4159 ++n;
4160
4161 if (n > best_count)
4162 best = corners[i], best_count = n;
4163 }
4164
4165 return best;
4166}
4167
4168/* Return the `background' field of IMG. If IMG doesn't have one yet,
4169 it is guessed heuristically. If non-zero, XIMG is an existing XImage
4170 object to use for the heuristic. */
4171
4172unsigned long
4173image_background (img, f, ximg)
4174 struct image *img;
4175 struct frame *f;
4176 XImagePtr ximg;
4177{
4178 if (! img->background_valid)
4179 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4180 {
4181 int free_ximg = !ximg;
4182
4183 if (! ximg)
4184 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
4185 0, 0, img->width, img->height, ~0, ZPixmap);
4186
4187 img->background = four_corners_best (ximg, img->width, img->height);
4188
4189 if (free_ximg)
4190 XDestroyImage (ximg);
4191
4192 img->background_valid = 1;
4193 }
4194
4195 return img->background;
4196}
4197
4198/* Return the `background_transparent' field of IMG. If IMG doesn't
4199 have one yet, it is guessed heuristically. If non-zero, MASK is an
4200 existing XImage object to use for the heuristic. */
4201
4202int
4203image_background_transparent (img, f, mask)
4204 struct image *img;
4205 struct frame *f;
4206 XImagePtr mask;
4207{
4208 if (! img->background_transparent_valid)
4209 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4210 {
4211 if (img->mask)
4212 {
4213 int free_mask = !mask;
4214
4215 if (! mask)
4216 mask = XGetImage (FRAME_X_DISPLAY (f), img->mask,
4217 0, 0, img->width, img->height, ~0, ZPixmap);
4218
4219 img->background_transparent
4220 = four_corners_best (mask, img->width, img->height) == PIX_MASK_RETAIN (f);
4221
4222 if (free_mask)
4223 XDestroyImage (mask);
4224 }
4225 else
4226 img->background_transparent = 0;
4227
4228 img->background_transparent_valid = 1;
4229 }
4230
4231 return img->background_transparent;
4232}
3890 4233
3891 4234
3892/*********************************************************************** 4235/***********************************************************************
3893 Helper functions for X image types 4236 Helper functions for X image types
3894 ***********************************************************************/ 4237 ***********************************************************************/
3895 4238
4239static void x_clear_image_1 P_ ((struct frame *, struct image *, int,
4240 int, int));
3896static void x_clear_image P_ ((struct frame *f, struct image *img)); 4241static void x_clear_image P_ ((struct frame *f, struct image *img));
3897static unsigned long x_alloc_image_color P_ ((struct frame *f, 4242static unsigned long x_alloc_image_color P_ ((struct frame *f,
3898 struct image *img, 4243 struct image *img,
3899 Lisp_Object color_name, 4244 Lisp_Object color_name,
3900 unsigned long dflt)); 4245 unsigned long dflt));
3901 4246
3902/* Free X resources of image IMG which is used on frame F. */ 4247
4248/* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
4249 free the pixmap if any. MASK_P non-zero means clear the mask
4250 pixmap if any. COLORS_P non-zero means free colors allocated for
4251 the image, if any. */
3903 4252
3904static void 4253static void
3905x_clear_image (f, img) 4254x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
3906 struct frame *f; 4255 struct frame *f;
3907 struct image *img; 4256 struct image *img;
4257 int pixmap_p, mask_p, colors_p;
3908{ 4258{
3909#if 0 /* MAC_TODO: W32 image support */ 4259 if (pixmap_p && img->pixmap)
3910
3911 if (img->pixmap)
3912 { 4260 {
3913 BLOCK_INPUT; 4261 XFreePixmap (FRAME_X_DISPLAY (f), img->pixmap);
3914 XFreePixmap (NULL, img->pixmap); 4262 img->pixmap = NULL;
3915 img->pixmap = 0; 4263 img->background_valid = 0;
3916 UNBLOCK_INPUT;
3917 } 4264 }
3918 4265
3919 if (img->ncolors) 4266 if (mask_p && img->mask)
3920 { 4267 {
3921 int class = FRAME_W32_DISPLAY_INFO (f)->visual->class; 4268 XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
3922 4269 img->mask = NULL;
3923 /* If display has an immutable color map, freeing colors is not 4270 img->background_transparent_valid = 0;
3924 necessary and some servers don't allow it. So don't do it. */ 4271 }
3925 if (class != StaticColor
3926 && class != StaticGray
3927 && class != TrueColor)
3928 {
3929 Colormap cmap;
3930 BLOCK_INPUT;
3931 cmap = DefaultColormapOfScreen (FRAME_W32_DISPLAY_INFO (f)->screen);
3932 XFreeColors (FRAME_W32_DISPLAY (f), cmap, img->colors,
3933 img->ncolors, 0);
3934 UNBLOCK_INPUT;
3935 }
3936 4272
4273 if (colors_p && img->ncolors)
4274 {
4275#if 0 /* TODO: color table support. */
4276 x_free_colors (f, img->colors, img->ncolors);
4277#endif
3937 xfree (img->colors); 4278 xfree (img->colors);
3938 img->colors = NULL; 4279 img->colors = NULL;
3939 img->ncolors = 0; 4280 img->ncolors = 0;
3940 } 4281 }
3941#endif /* MAC_TODO */ 4282}
4283
4284/* Free X resources of image IMG which is used on frame F. */
4285
4286static void
4287x_clear_image (f, img)
4288 struct frame *f;
4289 struct image *img;
4290{
4291 BLOCK_INPUT;
4292 x_clear_image_1 (f, img, 1, 1, 1);
4293 UNBLOCK_INPUT;
3942} 4294}
3943 4295
3944 4296
@@ -3954,13 +4306,12 @@ x_alloc_image_color (f, img, color_name, dflt)
3954 Lisp_Object color_name; 4306 Lisp_Object color_name;
3955 unsigned long dflt; 4307 unsigned long dflt;
3956{ 4308{
3957#if 0 /* MAC_TODO: allocing colors. */
3958 XColor color; 4309 XColor color;
3959 unsigned long result; 4310 unsigned long result;
3960 4311
3961 xassert (STRINGP (color_name)); 4312 xassert (STRINGP (color_name));
3962 4313
3963 if (w32_defined_color (f, SDATA (color_name), &color, 1)) 4314 if (mac_defined_color (f, SDATA (color_name), &color, 1))
3964 { 4315 {
3965 /* This isn't called frequently so we get away with simply 4316 /* This isn't called frequently so we get away with simply
3966 reallocating the color vector to the needed size, here. */ 4317 reallocating the color vector to the needed size, here. */
@@ -3973,9 +4324,8 @@ x_alloc_image_color (f, img, color_name, dflt)
3973 } 4324 }
3974 else 4325 else
3975 result = dflt; 4326 result = dflt;
4327
3976 return result; 4328 return result;
3977#endif /* MAC_TODO */
3978 return 0;
3979} 4329}
3980 4330
3981 4331
@@ -3985,6 +4335,7 @@ x_alloc_image_color (f, img, color_name, dflt)
3985 ***********************************************************************/ 4335 ***********************************************************************/
3986 4336
3987static void cache_image P_ ((struct frame *f, struct image *img)); 4337static void cache_image P_ ((struct frame *f, struct image *img));
4338static void postprocess_image P_ ((struct frame *, struct image *));
3988 4339
3989 4340
3990/* Return a new, initialized image cache that is allocated from the 4341/* Return a new, initialized image cache that is allocated from the
@@ -4049,20 +4400,23 @@ clear_image_cache (f, force_p)
4049 { 4400 {
4050 EMACS_TIME t; 4401 EMACS_TIME t;
4051 unsigned long old; 4402 unsigned long old;
4052 int i, any_freed_p = 0; 4403 int i, nfreed;
4053 4404
4054 EMACS_GET_TIME (t); 4405 EMACS_GET_TIME (t);
4055 old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay); 4406 old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay);
4056 4407
4057 for (i = 0; i < c->used; ++i) 4408 /* Block input so that we won't be interrupted by a SIGIO
4409 while being in an inconsistent state. */
4410 BLOCK_INPUT;
4411
4412 for (i = nfreed = 0; i < c->used; ++i)
4058 { 4413 {
4059 struct image *img = c->images[i]; 4414 struct image *img = c->images[i];
4060 if (img != NULL 4415 if (img != NULL
4061 && (force_p 4416 && (force_p || img->timestamp < old))
4062 || (img->timestamp > old)))
4063 { 4417 {
4064 free_image (f, img); 4418 free_image (f, img);
4065 any_freed_p = 1; 4419 ++nfreed;
4066 } 4420 }
4067 } 4421 }
4068 4422
@@ -4070,11 +4424,22 @@ clear_image_cache (f, force_p)
4070 Emacs was iconified for a longer period of time. In that 4424 Emacs was iconified for a longer period of time. In that
4071 case, current matrices may still contain references to 4425 case, current matrices may still contain references to
4072 images freed above. So, clear these matrices. */ 4426 images freed above. So, clear these matrices. */
4073 if (any_freed_p) 4427 if (nfreed)
4074 { 4428 {
4075 clear_current_matrices (f); 4429 Lisp_Object tail, frame;
4430
4431 FOR_EACH_FRAME (tail, frame)
4432 {
4433 struct frame *f = XFRAME (frame);
4434 if (FRAME_MAC_P (f)
4435 && FRAME_X_IMAGE_CACHE (f) == c)
4436 clear_current_matrices (f);
4437 }
4438
4076 ++windows_or_buffers_changed; 4439 ++windows_or_buffers_changed;
4077 } 4440 }
4441
4442 UNBLOCK_INPUT;
4078 } 4443 }
4079} 4444}
4080 4445
@@ -4084,7 +4449,7 @@ DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
4084 doc: /* Clear the image cache of FRAME. 4449 doc: /* Clear the image cache of FRAME.
4085FRAME nil or omitted means use the selected frame. 4450FRAME nil or omitted means use the selected frame.
4086FRAME t means clear the image caches of all frames. */) 4451FRAME t means clear the image caches of all frames. */)
4087 (frame) 4452 (frame)
4088 Lisp_Object frame; 4453 Lisp_Object frame;
4089{ 4454{
4090 if (EQ (frame, Qt)) 4455 if (EQ (frame, Qt))
@@ -4102,6 +4467,81 @@ FRAME t means clear the image caches of all frames. */)
4102} 4467}
4103 4468
4104 4469
4470/* Compute masks and transform image IMG on frame F, as specified
4471 by the image's specification, */
4472
4473static void
4474postprocess_image (f, img)
4475 struct frame *f;
4476 struct image *img;
4477{
4478 /* Manipulation of the image's mask. */
4479 if (img->pixmap)
4480 {
4481 Lisp_Object conversion, spec;
4482 Lisp_Object mask;
4483
4484 spec = img->spec;
4485
4486 /* `:heuristic-mask t'
4487 `:mask heuristic'
4488 means build a mask heuristically.
4489 `:heuristic-mask (R G B)'
4490 `:mask (heuristic (R G B))'
4491 means build a mask from color (R G B) in the
4492 image.
4493 `:mask nil'
4494 means remove a mask, if any. */
4495
4496 mask = image_spec_value (spec, QCheuristic_mask, NULL);
4497 if (!NILP (mask))
4498 x_build_heuristic_mask (f, img, mask);
4499 else
4500 {
4501 int found_p;
4502
4503 mask = image_spec_value (spec, QCmask, &found_p);
4504
4505 if (EQ (mask, Qheuristic))
4506 x_build_heuristic_mask (f, img, Qt);
4507 else if (CONSP (mask)
4508 && EQ (XCAR (mask), Qheuristic))
4509 {
4510 if (CONSP (XCDR (mask)))
4511 x_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
4512 else
4513 x_build_heuristic_mask (f, img, XCDR (mask));
4514 }
4515 else if (NILP (mask) && found_p && img->mask)
4516 {
4517 XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
4518 img->mask = NULL;
4519 }
4520 }
4521
4522
4523 /* Should we apply an image transformation algorithm? */
4524 conversion = image_spec_value (spec, QCconversion, NULL);
4525 if (EQ (conversion, Qdisabled))
4526 x_disable_image (f, img);
4527 else if (EQ (conversion, Qlaplace))
4528 x_laplace (f, img);
4529 else if (EQ (conversion, Qemboss))
4530 x_emboss (f, img);
4531 else if (CONSP (conversion)
4532 && EQ (XCAR (conversion), Qedge_detection))
4533 {
4534 Lisp_Object tem;
4535 tem = XCDR (conversion);
4536 if (CONSP (tem))
4537 x_edge_detection (f, img,
4538 Fplist_get (tem, QCmatrix),
4539 Fplist_get (tem, QCcolor_adjustment));
4540 }
4541 }
4542}
4543
4544
4105/* Return the id of image with Lisp specification SPEC on frame F. 4545/* Return the id of image with Lisp specification SPEC on frame F.
4106 SPEC must be a valid Lisp image specification (see valid_image_p). */ 4546 SPEC must be a valid Lisp image specification (see valid_image_p). */
4107 4547
@@ -4135,11 +4575,12 @@ lookup_image (f, spec)
4135 /* If not found, create a new image and cache it. */ 4575 /* If not found, create a new image and cache it. */
4136 if (img == NULL) 4576 if (img == NULL)
4137 { 4577 {
4578 extern Lisp_Object Qpostscript;
4579
4138 BLOCK_INPUT; 4580 BLOCK_INPUT;
4139 img = make_image (spec, hash); 4581 img = make_image (spec, hash);
4140 cache_image (f, img); 4582 cache_image (f, img);
4141 img->load_failed_p = img->type->load (f, img) == 0; 4583 img->load_failed_p = img->type->load (f, img) == 0;
4142 xassert (!interrupt_input_blocked);
4143 4584
4144 /* If we can't load the image, and we don't have a width and 4585 /* If we can't load the image, and we don't have a width and
4145 height, use some arbitrary width and height so that we can 4586 height, use some arbitrary width and height so that we can
@@ -4158,14 +4599,15 @@ lookup_image (f, spec)
4158 else 4599 else
4159 { 4600 {
4160 /* Handle image type independent image attributes 4601 /* Handle image type independent image attributes
4161 `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF'. */ 4602 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
4162 Lisp_Object ascent, margin, relief; 4603 `:background COLOR'. */
4604 Lisp_Object ascent, margin, relief, bg;
4163 4605
4164 ascent = image_spec_value (spec, QCascent, NULL); 4606 ascent = image_spec_value (spec, QCascent, NULL);
4165 if (INTEGERP (ascent)) 4607 if (INTEGERP (ascent))
4166 img->ascent = XFASTINT (ascent); 4608 img->ascent = XFASTINT (ascent);
4167 else if (EQ (ascent, Qcenter)) 4609 else if (EQ (ascent, Qcenter))
4168 img->ascent = CENTERED_IMAGE_ASCENT; 4610 img->ascent = CENTERED_IMAGE_ASCENT;
4169 4611
4170 margin = image_spec_value (spec, QCmargin, NULL); 4612 margin = image_spec_value (spec, QCmargin, NULL);
4171 if (INTEGERP (margin) && XINT (margin) >= 0) 4613 if (INTEGERP (margin) && XINT (margin) >= 0)
@@ -4186,7 +4628,26 @@ lookup_image (f, spec)
4186 img->hmargin += abs (img->relief); 4628 img->hmargin += abs (img->relief);
4187 img->vmargin += abs (img->relief); 4629 img->vmargin += abs (img->relief);
4188 } 4630 }
4631
4632 if (! img->background_valid)
4633 {
4634 bg = image_spec_value (img->spec, QCbackground, NULL);
4635 if (!NILP (bg))
4636 {
4637 img->background
4638 = x_alloc_image_color (f, img, bg,
4639 FRAME_BACKGROUND_PIXEL (f));
4640 img->background_valid = 1;
4641 }
4642 }
4643
4644 /* Do image transformations and compute masks, unless we
4645 don't have the image yet. */
4646 if (!EQ (*img->type->type, Qpostscript))
4647 postprocess_image (f, img);
4189 } 4648 }
4649
4650 UNBLOCK_INPUT;
4190 } 4651 }
4191 4652
4192 /* We're using IMG, so set its timestamp to `now'. */ 4653 /* We're using IMG, so set its timestamp to `now'. */
@@ -4266,48 +4727,23 @@ forall_images_in_image_cache (f, fn)
4266 Mac support code 4727 Mac support code
4267 ***********************************************************************/ 4728 ***********************************************************************/
4268 4729
4269#if 0 /* MAC_TODO: Mac specific image code. */
4270
4271static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int, 4730static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
4272 XImage **, Pixmap *)); 4731 XImagePtr *, Pixmap *));
4273static void x_destroy_x_image P_ ((XImage *)); 4732static void x_destroy_x_image P_ ((XImagePtr));
4274static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int)); 4733static void x_put_x_image P_ ((struct frame *, XImagePtr, Pixmap, int, int));
4275 4734
4276 4735
4277/* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
4278 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
4279 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
4280 via xmalloc. Print error messages via image_error if an error
4281 occurs. Value is non-zero if successful. */
4282
4283static int
4284x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap) 4736x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
4285 struct frame *f; 4737 struct frame *f;
4286 int width, height, depth; 4738 int width, height, depth;
4287 XImage **ximg; 4739 XImagePtr *ximg;
4288 Pixmap *pixmap; 4740 Pixmap *pixmap;
4289{ 4741{
4290#if 0 /* MAC_TODO: Image support for Mac */ 4742 Display *display = FRAME_MAC_DISPLAY (f);
4291 Display *display = FRAME_W32_DISPLAY (f); 4743 Window window = FRAME_MAC_WINDOW (f);
4292 Screen *screen = FRAME_X_SCREEN (f);
4293 Window window = FRAME_W32_WINDOW (f);
4294 4744
4295 xassert (interrupt_input_blocked); 4745 xassert (interrupt_input_blocked);
4296 4746
4297 if (depth <= 0)
4298 depth = DefaultDepthOfScreen (screen);
4299 *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
4300 depth, ZPixmap, 0, NULL, width, height,
4301 depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
4302 if (*ximg == NULL)
4303 {
4304 image_error ("Unable to allocate X image", Qnil, Qnil);
4305 return 0;
4306 }
4307
4308 /* Allocate image raster. */
4309 (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height);
4310
4311 /* Allocate a pixmap of the same size. */ 4747 /* Allocate a pixmap of the same size. */
4312 *pixmap = XCreatePixmap (display, window, width, height, depth); 4748 *pixmap = XCreatePixmap (display, window, width, height, depth);
4313 if (*pixmap == 0) 4749 if (*pixmap == 0)
@@ -4317,52 +4753,39 @@ x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
4317 image_error ("Unable to create X pixmap", Qnil, Qnil); 4753 image_error ("Unable to create X pixmap", Qnil, Qnil);
4318 return 0; 4754 return 0;
4319 } 4755 }
4320#endif /* MAC_TODO */ 4756
4757 LockPixels (GetGWorldPixMap (*pixmap));
4758 *ximg = *pixmap;
4321 return 1; 4759 return 1;
4322} 4760}
4323 4761
4324
4325/* Destroy XImage XIMG. Free XIMG->data. */
4326
4327static void 4762static void
4328x_destroy_x_image (ximg) 4763x_destroy_x_image (ximg)
4329 XImage *ximg; 4764 XImagePtr ximg;
4330{ 4765{
4331 xassert (interrupt_input_blocked); 4766 xassert (interrupt_input_blocked);
4332 if (ximg) 4767 if (ximg)
4333 { 4768 XDestroyImage (ximg);
4334 xfree (ximg->data);
4335 ximg->data = NULL;
4336 XDestroyImage (ximg);
4337 }
4338} 4769}
4339 4770
4340
4341/* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
4342 are width and height of both the image and pixmap. */
4343
4344static void 4771static void
4345x_put_x_image (f, ximg, pixmap, width, height) 4772x_put_x_image (f, ximg, pixmap, width, height)
4346 struct frame *f; 4773 struct frame *f;
4347 XImage *ximg; 4774 XImagePtr ximg;
4348 Pixmap pixmap; 4775 Pixmap pixmap;
4349{ 4776{
4350 GC gc; 4777 xassert (ximg == pixmap);
4351
4352 xassert (interrupt_input_blocked);
4353 gc = XCreateGC (NULL, pixmap, 0, NULL);
4354 XPutImage (NULL, pixmap, gc, ximg, 0, 0, 0, 0, width, height);
4355 XFreeGC (NULL, gc);
4356} 4778}
4357 4779
4358#endif /* MAC_TODO */
4359 4780
4360 4781
4361/*********************************************************************** 4782/***********************************************************************
4362 Searching files 4783 File Handling
4363 ***********************************************************************/ 4784 ***********************************************************************/
4364 4785
4365static Lisp_Object x_find_image_file P_ ((Lisp_Object)); 4786static Lisp_Object x_find_image_file P_ ((Lisp_Object));
4787static char *slurp_file P_ ((char *, int *));
4788
4366 4789
4367/* Find image file FILE. Look in data-directory, then 4790/* Find image file FILE. Look in data-directory, then
4368 x-bitmap-file-path. Value is the full name of the file found, or 4791 x-bitmap-file-path. Value is the full name of the file found, or
@@ -4383,7 +4806,7 @@ x_find_image_file (file)
4383 /* Try to find FILE in data-directory, then x-bitmap-file-path. */ 4806 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
4384 fd = openp (search_path, file, Qnil, &file_found, Qnil); 4807 fd = openp (search_path, file, Qnil, &file_found, Qnil);
4385 4808
4386 if (fd < 0) 4809 if (fd == -1)
4387 file_found = Qnil; 4810 file_found = Qnil;
4388 else 4811 else
4389 close (fd); 4812 close (fd);
@@ -4392,17 +4815,398 @@ x_find_image_file (file)
4392 return file_found; 4815 return file_found;
4393} 4816}
4394 4817
4818
4819/* Read FILE into memory. Value is a pointer to a buffer allocated
4820 with xmalloc holding FILE's contents. Value is null if an error
4821 occurred. *SIZE is set to the size of the file. */
4822
4823static char *
4824slurp_file (file, size)
4825 char *file;
4826 int *size;
4827{
4828 FILE *fp = NULL;
4829 char *buf = NULL;
4830 struct stat st;
4831
4832 if (stat (file, &st) == 0
4833 && (fp = fopen (file, "r")) != NULL
4834 && (buf = (char *) xmalloc (st.st_size),
4835 fread (buf, 1, st.st_size, fp) == st.st_size))
4836 {
4837 *size = st.st_size;
4838 fclose (fp);
4839 }
4840 else
4841 {
4842 if (fp)
4843 fclose (fp);
4844 if (buf)
4845 {
4846 xfree (buf);
4847 buf = NULL;
4848 }
4849 }
4850
4851 return buf;
4852}
4853
4854
4855
4856/***********************************************************************
4857 Image Load Functions
4858 ***********************************************************************/
4859
4860static int image_load_quicktime P_ ((struct frame *, struct image *img,
4861 OSType));
4862#ifdef MAC_OSX
4863static int image_load_quartz2d P_ ((struct frame *, struct image *img, int));
4864#endif
4865
4866
4867static OSErr
4868find_image_fsspec (specified_file, file, fss)
4869 Lisp_Object specified_file, *file;
4870 FSSpec *fss;
4871{
4872#if TARGET_API_MAC_CARBON
4873 FSRef fsr;
4874#else
4875 Str255 mac_pathname;
4876#endif
4877 OSErr err;
4878
4879 *file = x_find_image_file (specified_file);
4880 if (!STRINGP (*file))
4881 return fnfErr; /* file or directory not found;
4882 incomplete pathname */
4883 /* Try to open the image file. */
4884#if TARGET_API_MAC_CARBON
4885 err = FSPathMakeRef (SDATA (*file), &fsr, NULL);
4886 if (err == noErr)
4887 err = FSGetCatalogInfo (&fsr, kFSCatInfoNone, NULL, NULL, fss, NULL);
4888#else
4889 if (posix_to_mac_pathname (SDATA (*file), mac_pathname, MAXPATHLEN+1) == 0)
4890 return fnfErr;
4891 c2pstr (mac_pathname);
4892 err = FSMakeFSSpec (0, 0, mac_pathname, fss);
4893#endif
4894 return err;
4895}
4896
4897
4898static int
4899image_load_qt_1 (f, img, type, fss, dh)
4900 struct frame *f;
4901 struct image *img;
4902 OSType type;
4903 FSSpec *fss;
4904 Handle dh;
4905{
4906 OSErr err;
4907 GraphicsImportComponent gi;
4908 Rect rect;
4909 int width, height;
4910 short draw_all_pixels;
4911 Lisp_Object specified_bg;
4912 XColor color;
4913 XImagePtr ximg;
4914 RGBColor bg_color;
4915
4916 err = OpenADefaultComponent (GraphicsImporterComponentType,
4917 type, &gi);
4918 if (err != noErr)
4919 {
4920 image_error ("Cannot get importer component for `%s'", img->spec, Qnil);
4921 return 0;
4922 }
4923 if (dh == NULL)
4924 {
4925 /* read from file system spec */
4926 err = GraphicsImportSetDataFile (gi, fss);
4927 if (err != noErr)
4928 {
4929 image_error ("Cannot set fsspec to graphics importer for '%s'",
4930 img->spec, Qnil);
4931 goto error;
4932 }
4933 }
4934 else
4935 {
4936 /* read from data handle */
4937 err = GraphicsImportSetDataHandle (gi, dh);
4938 if (err != noErr)
4939 {
4940 image_error ("Cannot set data handle to graphics importer for `%s'",
4941 img->spec, Qnil);
4942 goto error;
4943 }
4944 }
4945 err = GraphicsImportGetNaturalBounds (gi, &rect);
4946 if (err != noErr)
4947 {
4948 image_error ("Error reading `%s'", img->spec, Qnil);
4949 goto error;
4950 }
4951 width = img->width = rect.right - rect.left;
4952 height = img->height = rect.bottom - rect.top;
4953 err = GraphicsImportDoesDrawAllPixels (gi, &draw_all_pixels);
4954#if 0
4955 /* Don't check the error code here. It may have an undocumented
4956 value -32766. */
4957 if (err != noErr)
4958 {
4959 image_error ("Error reading `%s'", img->spec, Qnil);
4960 goto error;
4961 }
4962#endif
4963 if (draw_all_pixels != graphicsImporterDrawsAllPixels)
4964 {
4965 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
4966 if (!STRINGP (specified_bg) ||
4967 !mac_defined_color (f, SDATA (specified_bg), &color, 0))
4968 {
4969 color.pixel = FRAME_BACKGROUND_PIXEL (f);
4970 color.red = RED16_FROM_ULONG (color.pixel);
4971 color.green = GREEN16_FROM_ULONG (color.pixel);
4972 color.blue = BLUE16_FROM_ULONG (color.pixel);
4973 }
4974 }
4975
4976 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
4977 goto error;
4978 if (draw_all_pixels != graphicsImporterDrawsAllPixels)
4979 {
4980 SetGWorld (ximg, NULL);
4981 bg_color.red = color.red;
4982 bg_color.green = color.green;
4983 bg_color.blue = color.blue;
4984 RGBBackColor (&bg_color);
4985#if TARGET_API_MAC_CARBON
4986 GetPortBounds (ximg, &rect);
4987 EraseRect (&rect);
4988#else
4989 EraseRect (&(ximg->portRect));
4990#endif
4991 }
4992 GraphicsImportSetGWorld (gi, ximg, NULL);
4993 GraphicsImportDraw (gi);
4994 CloseComponent (gi);
4995
4996 /* Maybe fill in the background field while we have ximg handy. */
4997 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
4998 IMAGE_BACKGROUND (img, f, ximg);
4999
5000 /* Put the image into the pixmap. */
5001 x_put_x_image (f, ximg, img->pixmap, width, height);
5002 x_destroy_x_image (ximg);
5003 return 1;
5004
5005 error:
5006 CloseComponent (gi);
5007 return 0;
5008}
5009
5010
5011/* Load an image using the QuickTime Graphics Importer.
5012 Note: The alpha channel does not work for PNG images. */
5013static int
5014image_load_quicktime (f, img, type)
5015 struct frame *f;
5016 struct image *img;
5017 OSType type;
5018{
5019 Lisp_Object specified_file;
5020 Lisp_Object specified_data;
5021 OSErr err;
5022
5023 specified_file = image_spec_value (img->spec, QCfile, NULL);
5024 specified_data = image_spec_value (img->spec, QCdata, NULL);
5025
5026 if (NILP (specified_data))
5027 {
5028 /* Read from a file */
5029 Lisp_Object file;
5030 FSSpec fss;
5031
5032 err = find_image_fsspec (specified_file, &file, &fss);
5033 if (err != noErr)
5034 {
5035 if (err == fnfErr)
5036 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5037 else
5038 image_error ("Cannot open `%s'", file, Qnil);
5039 return 0;
5040 }
5041 return image_load_qt_1 (f, img, type, &fss, NULL);
5042 }
5043 else
5044 {
5045 /* Memory source! */
5046 int success_p;
5047 Handle dh;
5048
5049 err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data));
5050 if (err != noErr)
5051 {
5052 image_error ("Cannot allocate data handle for `%s'",
5053 img->spec, Qnil);
5054 return 0;
5055 }
5056 success_p = image_load_qt_1 (f, img, type, NULL, dh);
5057 DisposeHandle (dh);
5058 return success_p;
5059 }
5060}
5061
5062
5063#ifdef MAC_OSX
5064/* Load a PNG/JPEG image using Quartz 2D decoding routines.
5065 CGImageCreateWithPNGDataProvider is provided after Mac OS X 10.2.
5066 So don't use this function directly but determine at runtime
5067 whether it exists. */
5068typedef CGImageRef (*CGImageCreateWithPNGDataProviderProcType)
5069 (CGDataProviderRef, const float [], bool, CGColorRenderingIntent);
5070static CGImageCreateWithPNGDataProviderProcType MyCGImageCreateWithPNGDataProvider;
5071
5072
5073static void
5074init_image_func_pointer ()
5075{
5076 if (NSIsSymbolNameDefined ("_CGImageCreateWithPNGDataProvider"))
5077 {
5078 MyCGImageCreateWithPNGDataProvider
5079 = (CGImageCreateWithPNGDataProviderProcType)
5080 NSAddressOfSymbol (NSLookupAndBindSymbol
5081 ("_CGImageCreateWithPNGDataProvider"));
5082 }
5083 else
5084 MyCGImageCreateWithPNGDataProvider = NULL;
5085}
5086
5087
5088static int
5089image_load_quartz2d (f, img, png_p)
5090 struct frame *f;
5091 struct image *img;
5092 int png_p;
5093{
5094 Lisp_Object file, specified_file;
5095 Lisp_Object specified_data, specified_bg;
5096 struct gcpro gcpro1;
5097 CGDataProviderRef source;
5098 CGImageRef image;
5099 int width, height;
5100 XColor color;
5101 XImagePtr ximg = NULL;
5102 CGContextRef context;
5103 CGRect rectangle;
5104
5105 /* Open the file. */
5106 specified_file = image_spec_value (img->spec, QCfile, NULL);
5107 specified_data = image_spec_value (img->spec, QCdata, NULL);
5108
5109 file = Qnil;
5110 GCPRO1 (file);
5111
5112 if (NILP (specified_data))
5113 {
5114 CFStringRef path;
5115 CFURLRef url;
5116
5117 file = x_find_image_file (specified_file);
5118 if (!STRINGP (file))
5119 {
5120 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5121 UNGCPRO;
5122 return 0;
5123 }
5124 path = CFStringCreateWithCString (NULL, SDATA (file),
5125 kCFStringEncodingUTF8);
5126 url = CFURLCreateWithFileSystemPath (NULL, path,
5127 kCFURLPOSIXPathStyle, 0);
5128 CFRelease (path);
5129 source = CGDataProviderCreateWithURL (url);
5130 CFRelease (url);
5131 }
5132 else
5133 source = CGDataProviderCreateWithData (NULL, SDATA (specified_data),
5134 SBYTES (specified_data), NULL);
5135
5136 if (png_p)
5137 image = (*MyCGImageCreateWithPNGDataProvider) (source, NULL, FALSE,
5138 kCGRenderingIntentDefault);
5139 else
5140 image = CGImageCreateWithJPEGDataProvider (source, NULL, FALSE,
5141 kCGRenderingIntentDefault);
5142
5143 CGDataProviderRelease (source);
5144 if (image == NULL)
5145 {
5146 UNGCPRO;
5147 image_error ("Error reading image `%s'", img->spec, Qnil);
5148 return 0;
5149 }
5150
5151 if (png_p)
5152 {
5153 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
5154 if (!STRINGP (specified_bg) ||
5155 !mac_defined_color (f, SDATA (specified_bg), &color, 0))
5156 {
5157 color.pixel = FRAME_BACKGROUND_PIXEL (f);
5158 color.red = RED16_FROM_ULONG (color.pixel);
5159 color.green = GREEN16_FROM_ULONG (color.pixel);
5160 color.blue = BLUE16_FROM_ULONG (color.pixel);
5161 }
5162 }
5163 width = img->width = CGImageGetWidth (image);
5164 height = img->height = CGImageGetHeight (image);
5165 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
5166 {
5167 CGImageRelease (image);
5168 UNGCPRO;
5169 return 0;
5170 }
5171 rectangle = CGRectMake (0, 0, width, height);
5172 QDBeginCGContext (ximg, &context);
5173 if (png_p)
5174 {
5175 CGContextSetRGBFillColor (context, color.red / 65535.0,
5176 color.green / 65535.0,
5177 color.blue / 65535.0, 1.0);
5178 CGContextFillRect (context, rectangle);
5179 }
5180 CGContextDrawImage (context, rectangle, image);
5181 QDEndCGContext (ximg, &context);
5182 CGImageRelease (image);
5183
5184 /* Maybe fill in the background field while we have ximg handy. */
5185 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5186 IMAGE_BACKGROUND (img, f, ximg);
5187
5188 /* Put the image into the pixmap. */
5189 x_put_x_image (f, ximg, img->pixmap, width, height);
5190 x_destroy_x_image (ximg);
5191 UNGCPRO;
5192 return 1;
5193}
5194#endif
5195
5196
4395 5197
4396/*********************************************************************** 5198/***********************************************************************
4397 XBM images 5199 XBM images
4398 ***********************************************************************/ 5200 ***********************************************************************/
4399 5201
5202static int xbm_scan P_ ((char **, char *, char *, int *));
4400static int xbm_load P_ ((struct frame *f, struct image *img)); 5203static int xbm_load P_ ((struct frame *f, struct image *img));
4401static int xbm_load_image_from_file P_ ((struct frame *f, struct image *img, 5204static int xbm_load_image P_ ((struct frame *f, struct image *img,
4402 Lisp_Object file)); 5205 char *, char *));
4403static int xbm_image_p P_ ((Lisp_Object object)); 5206static int xbm_image_p P_ ((Lisp_Object object));
4404static int xbm_read_bitmap_file_data P_ ((char *, int *, int *, 5207static int xbm_read_bitmap_data P_ ((char *, char *, int *, int *,
4405 unsigned char **)); 5208 unsigned char **));
5209static int xbm_file_p P_ ((Lisp_Object));
4406 5210
4407 5211
4408/* Indices of image specification fields in xbm_format, below. */ 5212/* Indices of image specification fields in xbm_format, below. */
@@ -4421,6 +5225,7 @@ enum xbm_keyword_index
4421 XBM_RELIEF, 5225 XBM_RELIEF,
4422 XBM_ALGORITHM, 5226 XBM_ALGORITHM,
4423 XBM_HEURISTIC_MASK, 5227 XBM_HEURISTIC_MASK,
5228 XBM_MASK,
4424 XBM_LAST 5229 XBM_LAST
4425}; 5230};
4426 5231
@@ -4434,13 +5239,14 @@ static struct image_keyword xbm_format[XBM_LAST] =
4434 {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0}, 5239 {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
4435 {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0}, 5240 {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0},
4436 {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 5241 {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
4437 {":foreground", IMAGE_STRING_VALUE, 0}, 5242 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
4438 {":background", IMAGE_STRING_VALUE, 0}, 5243 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
4439 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 5244 {":ascent", IMAGE_ASCENT_VALUE, 0},
4440 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 5245 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
4441 {":relief", IMAGE_INTEGER_VALUE, 0}, 5246 {":relief", IMAGE_INTEGER_VALUE, 0},
4442 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 5247 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
4443 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} 5248 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5249 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
4444}; 5250};
4445 5251
4446/* Structure describing the image type XBM. */ 5252/* Structure describing the image type XBM. */
@@ -4483,10 +5289,14 @@ enum xbm_token
4483 3. a vector of strings or bool-vectors, one for each line of the 5289 3. a vector of strings or bool-vectors, one for each line of the
4484 bitmap. 5290 bitmap.
4485 5291
5292 4. A string containing an in-memory XBM file. WIDTH and HEIGHT
5293 may not be specified in this case because they are defined in the
5294 XBM file.
5295
4486 Both the file and data forms may contain the additional entries 5296 Both the file and data forms may contain the additional entries
4487 `:background COLOR' and `:foreground COLOR'. If not present, 5297 `:background COLOR' and `:foreground COLOR'. If not present,
4488 foreground and background of the frame on which the image is 5298 foreground and background of the frame on which the image is
4489 displayed, is used. */ 5299 displayed is used. */
4490 5300
4491static int 5301static int
4492xbm_image_p (object) 5302xbm_image_p (object)
@@ -4505,6 +5315,12 @@ xbm_image_p (object)
4505 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count) 5315 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count)
4506 return 0; 5316 return 0;
4507 } 5317 }
5318 else if (kw[XBM_DATA].count && xbm_file_p (kw[XBM_DATA].value))
5319 {
5320 /* In-memory XBM file. */
5321 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_FILE].count)
5322 return 0;
5323 }
4508 else 5324 else
4509 { 5325 {
4510 Lisp_Object data; 5326 Lisp_Object data;
@@ -4566,11 +5382,6 @@ xbm_image_p (object)
4566 return 0; 5382 return 0;
4567 } 5383 }
4568 5384
4569 /* Baseline must be a value between 0 and 100 (a percentage). */
4570 if (kw[XBM_ASCENT].count
4571 && XFASTINT (kw[XBM_ASCENT].value) > 100)
4572 return 0;
4573
4574 return 1; 5385 return 1;
4575} 5386}
4576 5387
@@ -4582,30 +5393,33 @@ xbm_image_p (object)
4582 scanning a number, store its value in *IVAL. */ 5393 scanning a number, store its value in *IVAL. */
4583 5394
4584static int 5395static int
4585xbm_scan (fp, sval, ival) 5396xbm_scan (s, end, sval, ival)
4586 FILE *fp; 5397 char **s, *end;
4587 char *sval; 5398 char *sval;
4588 int *ival; 5399 int *ival;
4589{ 5400{
4590 int c; 5401 int c;
4591 5402
5403 loop:
5404
4592 /* Skip white space. */ 5405 /* Skip white space. */
4593 while ((c = fgetc (fp)) != EOF && isspace (c)) 5406 while (*s < end && (c = *(*s)++, isspace (c)))
4594 ; 5407 ;
4595 5408
4596 if (c == EOF) 5409 if (*s >= end)
4597 c = 0; 5410 c = 0;
4598 else if (isdigit (c)) 5411 else if (isdigit (c))
4599 { 5412 {
4600 int value = 0, digit; 5413 int value = 0, digit;
4601 5414
4602 if (c == '0') 5415 if (c == '0' && *s < end)
4603 { 5416 {
4604 c = fgetc (fp); 5417 c = *(*s)++;
4605 if (c == 'x' || c == 'X') 5418 if (c == 'x' || c == 'X')
4606 { 5419 {
4607 while ((c = fgetc (fp)) != EOF) 5420 while (*s < end)
4608 { 5421 {
5422 c = *(*s)++;
4609 if (isdigit (c)) 5423 if (isdigit (c))
4610 digit = c - '0'; 5424 digit = c - '0';
4611 else if (c >= 'a' && c <= 'f') 5425 else if (c >= 'a' && c <= 'f')
@@ -4620,53 +5434,66 @@ xbm_scan (fp, sval, ival)
4620 else if (isdigit (c)) 5434 else if (isdigit (c))
4621 { 5435 {
4622 value = c - '0'; 5436 value = c - '0';
4623 while ((c = fgetc (fp)) != EOF 5437 while (*s < end
4624 && isdigit (c)) 5438 && (c = *(*s)++, isdigit (c)))
4625 value = 8 * value + c - '0'; 5439 value = 8 * value + c - '0';
4626 } 5440 }
4627 } 5441 }
4628 else 5442 else
4629 { 5443 {
4630 value = c - '0'; 5444 value = c - '0';
4631 while ((c = fgetc (fp)) != EOF 5445 while (*s < end
4632 && isdigit (c)) 5446 && (c = *(*s)++, isdigit (c)))
4633 value = 10 * value + c - '0'; 5447 value = 10 * value + c - '0';
4634 } 5448 }
4635 5449
4636 if (c != EOF) 5450 if (*s < end)
4637 ungetc (c, fp); 5451 *s = *s - 1;
4638 *ival = value; 5452 *ival = value;
4639 c = XBM_TK_NUMBER; 5453 c = XBM_TK_NUMBER;
4640 } 5454 }
4641 else if (isalpha (c) || c == '_') 5455 else if (isalpha (c) || c == '_')
4642 { 5456 {
4643 *sval++ = c; 5457 *sval++ = c;
4644 while ((c = fgetc (fp)) != EOF 5458 while (*s < end
4645 && (isalnum (c) || c == '_')) 5459 && (c = *(*s)++, (isalnum (c) || c == '_')))
4646 *sval++ = c; 5460 *sval++ = c;
4647 *sval = 0; 5461 *sval = 0;
4648 if (c != EOF) 5462 if (*s < end)
4649 ungetc (c, fp); 5463 *s = *s - 1;
4650 c = XBM_TK_IDENT; 5464 c = XBM_TK_IDENT;
4651 } 5465 }
5466 else if (c == '/' && **s == '*')
5467 {
5468 /* C-style comment. */
5469 ++*s;
5470 while (**s && (**s != '*' || *(*s + 1) != '/'))
5471 ++*s;
5472 if (**s)
5473 {
5474 *s += 2;
5475 goto loop;
5476 }
5477 }
4652 5478
4653 return c; 5479 return c;
4654} 5480}
4655 5481
4656 5482
4657/* Replacement for XReadBitmapFileData which isn't available under old 5483/* Replacement for XReadBitmapFileData which isn't available under old
4658 X versions. FILE is the name of the bitmap file to read. Set 5484 X versions. CONTENTS is a pointer to a buffer to parse; END is the
4659 *WIDTH and *HEIGHT to the width and height of the image. Return in 5485 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
4660 *DATA the bitmap data allocated with xmalloc. Value is non-zero if 5486 the image. Return in *DATA the bitmap data allocated with xmalloc.
4661 successful. */ 5487 Value is non-zero if successful. DATA null means just test if
5488 CONTENTS looks like an in-memory XBM file. */
4662 5489
4663static int 5490static int
4664xbm_read_bitmap_file_data (file, width, height, data) 5491xbm_read_bitmap_data (contents, end, width, height, data)
4665 char *file; 5492 char *contents, *end;
4666 int *width, *height; 5493 int *width, *height;
4667 unsigned char **data; 5494 unsigned char **data;
4668{ 5495{
4669 FILE *fp; 5496 char *s = contents;
4670 char buffer[BUFSIZ]; 5497 char buffer[BUFSIZ];
4671 int padding_p = 0; 5498 int padding_p = 0;
4672 int v10 = 0; 5499 int v10 = 0;
@@ -4676,7 +5503,7 @@ xbm_read_bitmap_file_data (file, width, height, data)
4676 int LA1; 5503 int LA1;
4677 5504
4678#define match() \ 5505#define match() \
4679 LA1 = xbm_scan (fp, buffer, &value) 5506 LA1 = xbm_scan (&s, end, buffer, &value)
4680 5507
4681#define expect(TOKEN) \ 5508#define expect(TOKEN) \
4682 if (LA1 != (TOKEN)) \ 5509 if (LA1 != (TOKEN)) \
@@ -4690,13 +5517,10 @@ xbm_read_bitmap_file_data (file, width, height, data)
4690 else \ 5517 else \
4691 goto failure 5518 goto failure
4692 5519
4693 fp = fopen (file, "r");
4694 if (fp == NULL)
4695 return 0;
4696
4697 *width = *height = -1; 5520 *width = *height = -1;
4698 *data = NULL; 5521 if (data)
4699 LA1 = xbm_scan (fp, buffer, &value); 5522 *data = NULL;
5523 LA1 = xbm_scan (&s, end, buffer, &value);
4700 5524
4701 /* Parse defines for width, height and hot-spots. */ 5525 /* Parse defines for width, height and hot-spots. */
4702 while (LA1 == '#') 5526 while (LA1 == '#')
@@ -4719,6 +5543,8 @@ xbm_read_bitmap_file_data (file, width, height, data)
4719 5543
4720 if (*width < 0 || *height < 0) 5544 if (*width < 0 || *height < 0)
4721 goto failure; 5545 goto failure;
5546 else if (data == NULL)
5547 goto success;
4722 5548
4723 /* Parse bits. Must start with `static'. */ 5549 /* Parse bits. Must start with `static'. */
4724 expect_ident ("static"); 5550 expect_ident ("static");
@@ -4756,7 +5582,6 @@ xbm_read_bitmap_file_data (file, width, height, data)
4756 5582
4757 if (v10) 5583 if (v10)
4758 { 5584 {
4759
4760 for (i = 0; i < nbytes; i += 2) 5585 for (i = 0; i < nbytes; i += 2)
4761 { 5586 {
4762 int val = value; 5587 int val = value;
@@ -4788,13 +5613,12 @@ xbm_read_bitmap_file_data (file, width, height, data)
4788 } 5613 }
4789 } 5614 }
4790 5615
4791 fclose (fp); 5616 success:
4792 return 1; 5617 return 1;
4793 5618
4794 failure: 5619 failure:
4795 5620
4796 fclose (fp); 5621 if (data && *data)
4797 if (*data)
4798 { 5622 {
4799 xfree (*data); 5623 xfree (*data);
4800 *data = NULL; 5624 *data = NULL;
@@ -4807,38 +5631,24 @@ xbm_read_bitmap_file_data (file, width, height, data)
4807} 5631}
4808 5632
4809 5633
4810/* Load XBM image IMG which will be displayed on frame F from file 5634/* Load XBM image IMG which will be displayed on frame F from buffer
4811 SPECIFIED_FILE. Value is non-zero if successful. */ 5635 CONTENTS. END is the end of the buffer. Value is non-zero if
5636 successful. */
4812 5637
4813static int 5638static int
4814xbm_load_image_from_file (f, img, specified_file) 5639xbm_load_image (f, img, contents, end)
4815 struct frame *f; 5640 struct frame *f;
4816 struct image *img; 5641 struct image *img;
4817 Lisp_Object specified_file; 5642 char *contents, *end;
4818{ 5643{
4819 int rc; 5644 int rc;
4820 unsigned char *data; 5645 unsigned char *data;
4821 int success_p = 0; 5646 int success_p = 0;
4822 Lisp_Object file;
4823 struct gcpro gcpro1;
4824
4825 xassert (STRINGP (specified_file));
4826 file = Qnil;
4827 GCPRO1 (file);
4828 5647
4829 file = x_find_image_file (specified_file); 5648 rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data);
4830 if (!STRINGP (file))
4831 {
4832 image_error ("Cannot find image file `%s'", specified_file, Qnil);
4833 UNGCPRO;
4834 return 0;
4835 }
4836
4837 rc = xbm_read_bitmap_file_data (SDATA (file), &img->width,
4838 &img->height, &data);
4839 if (rc) 5649 if (rc)
4840 { 5650 {
4841 int depth = one_mac_display_info.n_cbits; 5651 int depth = one_mac_display_info.n_planes;
4842 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); 5652 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
4843 unsigned long background = FRAME_BACKGROUND_PIXEL (f); 5653 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
4844 Lisp_Object value; 5654 Lisp_Object value;
@@ -4849,16 +5659,17 @@ xbm_load_image_from_file (f, img, specified_file)
4849 value = image_spec_value (img->spec, QCforeground, NULL); 5659 value = image_spec_value (img->spec, QCforeground, NULL);
4850 if (!NILP (value)) 5660 if (!NILP (value))
4851 foreground = x_alloc_image_color (f, img, value, foreground); 5661 foreground = x_alloc_image_color (f, img, value, foreground);
4852
4853 value = image_spec_value (img->spec, QCbackground, NULL); 5662 value = image_spec_value (img->spec, QCbackground, NULL);
4854 if (!NILP (value)) 5663 if (!NILP (value))
4855 background = x_alloc_image_color (f, img, value, background); 5664 {
5665 background = x_alloc_image_color (f, img, value, background);
5666 img->background = background;
5667 img->background_valid = 1;
5668 }
4856 5669
4857#if 0 /* MAC_TODO : Port image display to Mac */
4858 BLOCK_INPUT;
4859 img->pixmap 5670 img->pixmap
4860 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f), 5671 = XCreatePixmapFromBitmapData (FRAME_MAC_DISPLAY (f),
4861 FRAME_W32_WINDOW (f), 5672 FRAME_MAC_WINDOW (f),
4862 data, 5673 data,
4863 img->width, img->height, 5674 img->width, img->height,
4864 foreground, background, 5675 foreground, background,
@@ -4868,22 +5679,33 @@ xbm_load_image_from_file (f, img, specified_file)
4868 if (img->pixmap == 0) 5679 if (img->pixmap == 0)
4869 { 5680 {
4870 x_clear_image (f, img); 5681 x_clear_image (f, img);
4871 image_error ("Unable to create X pixmap for `%s'", file, Qnil); 5682 image_error ("Unable to create X pixmap for `%s'", img->spec, Qnil);
4872 } 5683 }
4873 else 5684 else
4874 success_p = 1; 5685 success_p = 1;
4875
4876 UNBLOCK_INPUT;
4877#endif /* MAC_TODO */
4878 } 5686 }
4879 else 5687 else
4880 image_error ("Error loading XBM image `%s'", img->spec, Qnil); 5688 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
4881 5689
4882 UNGCPRO;
4883 return success_p; 5690 return success_p;
4884} 5691}
4885 5692
4886 5693
5694/* Value is non-zero if DATA looks like an in-memory XBM file. */
5695
5696static int
5697xbm_file_p (data)
5698 Lisp_Object data;
5699{
5700 int w, h;
5701 return (STRINGP (data)
5702 && xbm_read_bitmap_data (SDATA (data),
5703 (SDATA (data)
5704 + SBYTES (data)),
5705 &w, &h, NULL));
5706}
5707
5708
4887/* Fill image IMG which is used on frame F with pixmap data. Value is 5709/* Fill image IMG which is used on frame F with pixmap data. Value is
4888 non-zero if successful. */ 5710 non-zero if successful. */
4889 5711
@@ -4900,7 +5722,32 @@ xbm_load (f, img)
4900 /* If IMG->spec specifies a file name, create a non-file spec from it. */ 5722 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4901 file_name = image_spec_value (img->spec, QCfile, NULL); 5723 file_name = image_spec_value (img->spec, QCfile, NULL);
4902 if (STRINGP (file_name)) 5724 if (STRINGP (file_name))
4903 success_p = xbm_load_image_from_file (f, img, file_name); 5725 {
5726 Lisp_Object file;
5727 char *contents;
5728 int size;
5729 struct gcpro gcpro1;
5730
5731 file = x_find_image_file (file_name);
5732 GCPRO1 (file);
5733 if (!STRINGP (file))
5734 {
5735 image_error ("Cannot find image file `%s'", file_name, Qnil);
5736 UNGCPRO;
5737 return 0;
5738 }
5739
5740 contents = slurp_file (SDATA (file), &size);
5741 if (contents == NULL)
5742 {
5743 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
5744 UNGCPRO;
5745 return 0;
5746 }
5747
5748 success_p = xbm_load_image (f, img, contents, contents + size);
5749 UNGCPRO;
5750 }
4904 else 5751 else
4905 { 5752 {
4906 struct image_keyword fmt[XBM_LAST]; 5753 struct image_keyword fmt[XBM_LAST];
@@ -4910,75 +5757,80 @@ xbm_load (f, img)
4910 unsigned long background = FRAME_BACKGROUND_PIXEL (f); 5757 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
4911 char *bits; 5758 char *bits;
4912 int parsed_p; 5759 int parsed_p;
5760 int in_memory_file_p = 0;
4913 5761
4914 /* Parse the list specification. */ 5762 /* See if data looks like an in-memory XBM file. */
5763 data = image_spec_value (img->spec, QCdata, NULL);
5764 in_memory_file_p = xbm_file_p (data);
5765
5766 /* Parse the image specification. */
4915 bcopy (xbm_format, fmt, sizeof fmt); 5767 bcopy (xbm_format, fmt, sizeof fmt);
4916 parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm); 5768 parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm);
4917 xassert (parsed_p); 5769 xassert (parsed_p);
4918 5770
4919 /* Get specified width, and height. */ 5771 /* Get specified width, and height. */
4920 img->width = XFASTINT (fmt[XBM_WIDTH].value); 5772 if (!in_memory_file_p)
4921 img->height = XFASTINT (fmt[XBM_HEIGHT].value); 5773 {
4922 xassert (img->width > 0 && img->height > 0); 5774 img->width = XFASTINT (fmt[XBM_WIDTH].value);
4923 5775 img->height = XFASTINT (fmt[XBM_HEIGHT].value);
4924 BLOCK_INPUT; 5776 xassert (img->width > 0 && img->height > 0);
4925 5777 }
4926 if (fmt[XBM_ASCENT].count)
4927 img->ascent = XFASTINT (fmt[XBM_ASCENT].value);
4928 5778
4929 /* Get foreground and background colors, maybe allocate colors. */ 5779 /* Get foreground and background colors, maybe allocate colors. */
4930 if (fmt[XBM_FOREGROUND].count) 5780 if (fmt[XBM_FOREGROUND].count
5781 && STRINGP (fmt[XBM_FOREGROUND].value))
4931 foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value, 5782 foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value,
4932 foreground); 5783 foreground);
4933 if (fmt[XBM_BACKGROUND].count) 5784 if (fmt[XBM_BACKGROUND].count
5785 && STRINGP (fmt[XBM_BACKGROUND].value))
4934 background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value, 5786 background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value,
4935 background); 5787 background);
4936 5788
4937 /* Set bits to the bitmap image data. */ 5789 if (in_memory_file_p)
4938 data = fmt[XBM_DATA].value; 5790 success_p = xbm_load_image (f, img, SDATA (data),
4939 if (VECTORP (data)) 5791 (SDATA (data)
5792 + SBYTES (data)));
5793 else
4940 { 5794 {
4941 int i; 5795 if (VECTORP (data))
4942 char *p; 5796 {
4943 int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; 5797 int i;
5798 char *p;
5799 int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
4944 5800
4945 p = bits = (char *) alloca (nbytes * img->height); 5801 p = bits = (char *) alloca (nbytes * img->height);
4946 for (i = 0; i < img->height; ++i, p += nbytes) 5802 for (i = 0; i < img->height; ++i, p += nbytes)
5803 {
5804 Lisp_Object line = XVECTOR (data)->contents[i];
5805 if (STRINGP (line))
5806 bcopy (SDATA (line), p, nbytes);
5807 else
5808 bcopy (XBOOL_VECTOR (line)->data, p, nbytes);
5809 }
5810 }
5811 else if (STRINGP (data))
5812 bits = SDATA (data);
5813 else
5814 bits = XBOOL_VECTOR (data)->data;
5815
5816 /* Create the pixmap. */
5817 depth = one_mac_display_info.n_planes;
5818 img->pixmap
5819 = XCreatePixmapFromBitmapData (FRAME_MAC_DISPLAY (f),
5820 FRAME_MAC_WINDOW (f),
5821 bits,
5822 img->width, img->height,
5823 foreground, background,
5824 depth);
5825 if (img->pixmap)
5826 success_p = 1;
5827 else
4947 { 5828 {
4948 Lisp_Object line = XVECTOR (data)->contents[i]; 5829 image_error ("Unable to create pixmap for XBM image `%s'",
4949 if (STRINGP (line)) 5830 img->spec, Qnil);
4950 bcopy (SDATA (line), p, nbytes); 5831 x_clear_image (f, img);
4951 else
4952 bcopy (XBOOL_VECTOR (line)->data, p, nbytes);
4953 } 5832 }
4954 } 5833 }
4955 else if (STRINGP (data))
4956 bits = SDATA (data);
4957 else
4958 bits = XBOOL_VECTOR (data)->data;
4959
4960#if 0 /* MAC_TODO : port Mac display code */
4961 /* Create the pixmap. */
4962 depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
4963 img->pixmap
4964 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f),
4965 FRAME_W32_WINDOW (f),
4966 bits,
4967 img->width, img->height,
4968 foreground, background,
4969 depth);
4970#endif /* MAC_TODO */
4971
4972 if (img->pixmap)
4973 success_p = 1;
4974 else
4975 {
4976 image_error ("Unable to create pixmap for XBM image `%s'",
4977 img->spec, Qnil);
4978 x_clear_image (f, img);
4979 }
4980
4981 UNBLOCK_INPUT;
4982 } 5834 }
4983 5835
4984 return success_p; 5836 return success_p;
@@ -5014,7 +5866,9 @@ enum xpm_keyword_index
5014 XPM_RELIEF, 5866 XPM_RELIEF,
5015 XPM_ALGORITHM, 5867 XPM_ALGORITHM,
5016 XPM_HEURISTIC_MASK, 5868 XPM_HEURISTIC_MASK,
5869 XPM_MASK,
5017 XPM_COLOR_SYMBOLS, 5870 XPM_COLOR_SYMBOLS,
5871 XPM_BACKGROUND,
5018 XPM_LAST 5872 XPM_LAST
5019}; 5873};
5020 5874
@@ -5026,12 +5880,14 @@ static struct image_keyword xpm_format[XPM_LAST] =
5026 {":type", IMAGE_SYMBOL_VALUE, 1}, 5880 {":type", IMAGE_SYMBOL_VALUE, 1},
5027 {":file", IMAGE_STRING_VALUE, 0}, 5881 {":file", IMAGE_STRING_VALUE, 0},
5028 {":data", IMAGE_STRING_VALUE, 0}, 5882 {":data", IMAGE_STRING_VALUE, 0},
5029 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 5883 {":ascent", IMAGE_ASCENT_VALUE, 0},
5030 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 5884 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
5031 {":relief", IMAGE_INTEGER_VALUE, 0}, 5885 {":relief", IMAGE_INTEGER_VALUE, 0},
5032 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 5886 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5033 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 5887 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5034 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0} 5888 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5889 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5890 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5035}; 5891};
5036 5892
5037/* Structure describing the image type XBM. */ 5893/* Structure describing the image type XBM. */
@@ -5082,9 +5938,7 @@ xpm_image_p (object)
5082 /* Either no `:color-symbols' or it's a list of conses 5938 /* Either no `:color-symbols' or it's a list of conses
5083 whose car and cdr are strings. */ 5939 whose car and cdr are strings. */
5084 && (fmt[XPM_COLOR_SYMBOLS].count == 0 5940 && (fmt[XPM_COLOR_SYMBOLS].count == 0
5085 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)) 5941 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
5086 && (fmt[XPM_ASCENT].count == 0
5087 || XFASTINT (fmt[XPM_ASCENT].value) < 100));
5088} 5942}
5089 5943
5090 5944
@@ -5096,7 +5950,7 @@ xpm_load (f, img)
5096 struct frame *f; 5950 struct frame *f;
5097 struct image *img; 5951 struct image *img;
5098{ 5952{
5099 int rc, i; 5953 int rc;
5100 XpmAttributes attrs; 5954 XpmAttributes attrs;
5101 Lisp_Object specified_file, color_symbols; 5955 Lisp_Object specified_file, color_symbols;
5102 5956
@@ -5111,10 +5965,10 @@ xpm_load (f, img)
5111#ifdef XpmAllocCloseColors 5965#ifdef XpmAllocCloseColors
5112 attrs.alloc_close_colors = 1; 5966 attrs.alloc_close_colors = 1;
5113 attrs.valuemask |= XpmAllocCloseColors; 5967 attrs.valuemask |= XpmAllocCloseColors;
5114#else 5968#else /* not XpmAllocCloseColors */
5115 attrs.closeness = 600; 5969 attrs.closeness = 600;
5116 attrs.valuemask |= XpmCloseness; 5970 attrs.valuemask |= XpmCloseness;
5117#endif 5971#endif /* not XpmAllocCloseColors */
5118 5972
5119 /* If image specification contains symbolic color definitions, add 5973 /* If image specification contains symbolic color definitions, add
5120 these to `attrs'. */ 5974 these to `attrs'. */
@@ -5154,7 +6008,7 @@ xpm_load (f, img)
5154 6008
5155 /* Create a pixmap for the image, either from a file, or from a 6009 /* Create a pixmap for the image, either from a file, or from a
5156 string buffer containing data in the same format as an XPM file. */ 6010 string buffer containing data in the same format as an XPM file. */
5157 BLOCK_INPUT; 6011
5158 specified_file = image_spec_value (img->spec, QCfile, NULL); 6012 specified_file = image_spec_value (img->spec, QCfile, NULL);
5159 if (STRINGP (specified_file)) 6013 if (STRINGP (specified_file))
5160 { 6014 {
@@ -5162,27 +6016,26 @@ xpm_load (f, img)
5162 if (!STRINGP (file)) 6016 if (!STRINGP (file))
5163 { 6017 {
5164 image_error ("Cannot find image file `%s'", specified_file, Qnil); 6018 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5165 UNBLOCK_INPUT;
5166 return 0; 6019 return 0;
5167 } 6020 }
5168 6021
5169 rc = XpmReadFileToPixmap (NULL, FRAME_W32_WINDOW (f), 6022 rc = XpmReadFileToPixmap (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
5170 SDATA (file), &img->pixmap, &img->mask, 6023 SDATA (file), &img->pixmap, &img->mask,
5171 &attrs); 6024 &attrs);
5172 } 6025 }
5173 else 6026 else
5174 { 6027 {
5175 Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL); 6028 Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
5176 rc = XpmCreatePixmapFromBuffer (NULL, FRAME_W32_WINDOW (f), 6029 rc = XpmCreatePixmapFromBuffer (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
5177 SDATA (buffer), 6030 SDATA (buffer),
5178 &img->pixmap, &img->mask, 6031 &img->pixmap, &img->mask,
5179 &attrs); 6032 &attrs);
5180 } 6033 }
5181 UNBLOCK_INPUT;
5182 6034
5183 if (rc == XpmSuccess) 6035 if (rc == XpmSuccess)
5184 { 6036 {
5185 /* Remember allocated colors. */ 6037 int i;
6038
5186 img->ncolors = attrs.nalloc_pixels; 6039 img->ncolors = attrs.nalloc_pixels;
5187 img->colors = (unsigned long *) xmalloc (img->ncolors 6040 img->colors = (unsigned long *) xmalloc (img->ncolors
5188 * sizeof *img->colors); 6041 * sizeof *img->colors);
@@ -5194,9 +6047,7 @@ xpm_load (f, img)
5194 xassert (img->width > 0 && img->height > 0); 6047 xassert (img->width > 0 && img->height > 0);
5195 6048
5196 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */ 6049 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
5197 BLOCK_INPUT;
5198 XpmFreeAttributes (&attrs); 6050 XpmFreeAttributes (&attrs);
5199 UNBLOCK_INPUT;
5200 } 6051 }
5201 else 6052 else
5202 { 6053 {
@@ -5262,15 +6113,6 @@ struct ct_color **ct_table;
5262 6113
5263int ct_colors_allocated; 6114int ct_colors_allocated;
5264 6115
5265/* Function prototypes. */
5266
5267static void init_color_table P_ ((void));
5268static void free_color_table P_ ((void));
5269static unsigned long *colors_in_color_table P_ ((int *n));
5270static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b));
5271static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
5272
5273
5274/* Initialize the color table. */ 6116/* Initialize the color table. */
5275 6117
5276static void 6118static void
@@ -5422,6 +6264,17 @@ colors_in_color_table (n)
5422 return colors; 6264 return colors;
5423} 6265}
5424 6266
6267#else
6268static unsigned long
6269lookup_rgb_color (f, r, g, b)
6270 struct frame *f;
6271 int r, g, b;
6272{
6273 unsigned long pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
6274
6275 gamma_correct (f, &pixel);
6276 return pixel;
6277}
5425#endif /* MAC_TODO */ 6278#endif /* MAC_TODO */
5426 6279
5427 6280
@@ -5429,151 +6282,333 @@ colors_in_color_table (n)
5429 Algorithms 6282 Algorithms
5430 ***********************************************************************/ 6283 ***********************************************************************/
5431 6284
5432#if 0 /* MAC_TODO : Mac versions of low level algorithms */ 6285static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
5433static void x_laplace_write_row P_ ((struct frame *, long *, 6286static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
5434 int, XImage *, int)); 6287static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int));
5435static void x_laplace_read_row P_ ((struct frame *, Colormap, 6288
5436 XColor *, int, XImage *, int)); 6289/* Non-zero means draw a cross on images having `:conversion
6290 disabled'. */
6291
6292int cross_disabled_images;
6293
6294/* Edge detection matrices for different edge-detection
6295 strategies. */
6296
6297static int emboss_matrix[9] = {
6298 /* x - 1 x x + 1 */
6299 2, -1, 0, /* y - 1 */
6300 -1, 0, 1, /* y */
6301 0, 1, -2 /* y + 1 */
6302};
6303
6304static int laplace_matrix[9] = {
6305 /* x - 1 x x + 1 */
6306 1, 0, 0, /* y - 1 */
6307 0, 0, 0, /* y */
6308 0, 0, -1 /* y + 1 */
6309};
6310
6311/* Value is the intensity of the color whose red/green/blue values
6312 are R, G, and B. */
6313
6314#define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
6315
6316
6317/* On frame F, return an array of XColor structures describing image
6318 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
6319 non-zero means also fill the red/green/blue members of the XColor
6320 structures. Value is a pointer to the array of XColors structures,
6321 allocated with xmalloc; it must be freed by the caller. */
6322
6323static XColor *
6324x_to_xcolors (f, img, rgb_p)
6325 struct frame *f;
6326 struct image *img;
6327 int rgb_p;
6328{
6329 int x, y;
6330 XColor *colors, *p;
6331 XImagePtr ximg;
6332
6333 colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors);
6334
6335 /* Get the X image IMG->pixmap. */
6336 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
6337 0, 0, img->width, img->height, ~0, ZPixmap);
5437 6338
6339 /* Fill the `pixel' members of the XColor array. I wished there
6340 were an easy and portable way to circumvent XGetPixel. */
6341 p = colors;
6342 for (y = 0; y < img->height; ++y)
6343 {
6344 XColor *row = p;
5438 6345
5439/* Fill COLORS with RGB colors from row Y of image XIMG. F is the 6346 for (x = 0; x < img->width; ++x, ++p)
5440 frame we operate on, CMAP is the color-map in effect, and WIDTH is 6347 {
5441 the width of one row in the image. */ 6348 p->pixel = XGetPixel (ximg, x, y);
6349
6350 if (rgb_p)
6351 {
6352 p->red = RED16_FROM_ULONG (p->pixel);
6353 p->green = GREEN16_FROM_ULONG (p->pixel);
6354 p->blue = BLUE16_FROM_ULONG (p->pixel);
6355 }
6356 }
6357 }
6358
6359 XDestroyImage (ximg);
6360 return colors;
6361}
6362
6363
6364/* Create IMG->pixmap from an array COLORS of XColor structures, whose
6365 RGB members are set. F is the frame on which this all happens.
6366 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
5442 6367
5443static void 6368static void
5444x_laplace_read_row (f, cmap, colors, width, ximg, y) 6369x_from_xcolors (f, img, colors)
5445 struct frame *f; 6370 struct frame *f;
5446 Colormap cmap; 6371 struct image *img;
5447 XColor *colors; 6372 XColor *colors;
5448 int width;
5449 XImage *ximg;
5450 int y;
5451{ 6373{
5452 int x; 6374 int x, y;
6375 XImagePtr oimg;
6376 Pixmap pixmap;
6377 XColor *p;
6378
6379#if 0 /* TODO: color tables. */
6380 init_color_table ();
6381#endif
6382
6383 x_create_x_image_and_pixmap (f, img->width, img->height, 0,
6384 &oimg, &pixmap);
6385 p = colors;
6386 for (y = 0; y < img->height; ++y)
6387 for (x = 0; x < img->width; ++x, ++p)
6388 {
6389 unsigned long pixel;
6390 pixel = lookup_rgb_color (f, p->red, p->green, p->blue);
6391 XPutPixel (oimg, x, y, pixel);
6392 }
5453 6393
5454 for (x = 0; x < width; ++x) 6394 xfree (colors);
5455 colors[x].pixel = XGetPixel (ximg, x, y); 6395 x_clear_image_1 (f, img, 1, 0, 1);
5456 6396
5457 XQueryColors (NULL, cmap, colors, width); 6397 x_put_x_image (f, oimg, pixmap, img->width, img->height);
6398 x_destroy_x_image (oimg);
6399 img->pixmap = pixmap;
6400#if 0 /* TODO: color tables. */
6401 img->colors = colors_in_color_table (&img->ncolors);
6402 free_color_table ();
6403#endif
5458} 6404}
5459 6405
5460 6406
5461/* Write row Y of image XIMG. PIXELS is an array of WIDTH longs 6407/* On frame F, perform edge-detection on image IMG.
5462 containing the pixel colors to write. F is the frame we are 6408
5463 working on. */ 6409 MATRIX is a nine-element array specifying the transformation
6410 matrix. See emboss_matrix for an example.
6411
6412 COLOR_ADJUST is a color adjustment added to each pixel of the
6413 outgoing image. */
5464 6414
5465static void 6415static void
5466x_laplace_write_row (f, pixels, width, ximg, y) 6416x_detect_edges (f, img, matrix, color_adjust)
5467 struct frame *f; 6417 struct frame *f;
5468 long *pixels; 6418 struct image *img;
5469 int width; 6419 int matrix[9], color_adjust;
5470 XImage *ximg;
5471 int y;
5472{ 6420{
5473 int x; 6421 XColor *colors = x_to_xcolors (f, img, 1);
6422 XColor *new, *p;
6423 int x, y, i, sum;
6424
6425 for (i = sum = 0; i < 9; ++i)
6426 sum += abs (matrix[i]);
6427
6428#define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
6429
6430 new = (XColor *) xmalloc (img->width * img->height * sizeof *new);
5474 6431
5475 for (x = 0; x < width; ++x) 6432 for (y = 0; y < img->height; ++y)
5476 XPutPixel (ximg, x, y, pixels[x]); 6433 {
6434 p = COLOR (new, 0, y);
6435 p->red = p->green = p->blue = 0xffff/2;
6436 p = COLOR (new, img->width - 1, y);
6437 p->red = p->green = p->blue = 0xffff/2;
6438 }
6439
6440 for (x = 1; x < img->width - 1; ++x)
6441 {
6442 p = COLOR (new, x, 0);
6443 p->red = p->green = p->blue = 0xffff/2;
6444 p = COLOR (new, x, img->height - 1);
6445 p->red = p->green = p->blue = 0xffff/2;
6446 }
6447
6448 for (y = 1; y < img->height - 1; ++y)
6449 {
6450 p = COLOR (new, 1, y);
6451
6452 for (x = 1; x < img->width - 1; ++x, ++p)
6453 {
6454 int r, g, b, y1, x1;
6455
6456 r = g = b = i = 0;
6457 for (y1 = y - 1; y1 < y + 2; ++y1)
6458 for (x1 = x - 1; x1 < x + 2; ++x1, ++i)
6459 if (matrix[i])
6460 {
6461 XColor *t = COLOR (colors, x1, y1);
6462 r += matrix[i] * t->red;
6463 g += matrix[i] * t->green;
6464 b += matrix[i] * t->blue;
6465 }
6466
6467 r = (r / sum + color_adjust) & 0xffff;
6468 g = (g / sum + color_adjust) & 0xffff;
6469 b = (b / sum + color_adjust) & 0xffff;
6470 p->red = p->green = p->blue = COLOR_INTENSITY (r, g, b);
6471 }
6472 }
6473
6474 xfree (colors);
6475 x_from_xcolors (f, img, new);
6476
6477#undef COLOR
5477} 6478}
5478#endif /* MAC_TODO */
5479 6479
5480/* Transform image IMG which is used on frame F with a Laplace 6480
5481 edge-detection algorithm. The result is an image that can be used 6481/* Perform the pre-defined `emboss' edge-detection on image IMG
5482 to draw disabled buttons, for example. */ 6482 on frame F. */
6483
6484static void
6485x_emboss (f, img)
6486 struct frame *f;
6487 struct image *img;
6488{
6489 x_detect_edges (f, img, emboss_matrix, 0xffff / 2);
6490}
6491
6492
6493/* Perform the pre-defined `laplace' edge-detection on image IMG
6494 on frame F. */
5483 6495
5484static void 6496static void
5485x_laplace (f, img) 6497x_laplace (f, img)
5486 struct frame *f; 6498 struct frame *f;
5487 struct image *img; 6499 struct image *img;
5488{ 6500{
5489#if 0 /* MAC_TODO : Mac version */ 6501 x_detect_edges (f, img, laplace_matrix, 45000);
5490 Colormap cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); 6502}
5491 XImage *ximg, *oimg;
5492 XColor *in[3];
5493 long *out;
5494 Pixmap pixmap;
5495 int x, y, i;
5496 long pixel;
5497 int in_y, out_y, rc;
5498 int mv2 = 45000;
5499 6503
5500 BLOCK_INPUT;
5501 6504
5502 /* Get the X image IMG->pixmap. */ 6505/* Perform edge-detection on image IMG on frame F, with specified
5503 ximg = XGetImage (NULL, img->pixmap, 6506 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
5504 0, 0, img->width, img->height, ~0, ZPixmap);
5505 6507
5506 /* Allocate 3 input rows, and one output row of colors. */ 6508 MATRIX must be either
5507 for (i = 0; i < 3; ++i)
5508 in[i] = (XColor *) alloca (img->width * sizeof (XColor));
5509 out = (long *) alloca (img->width * sizeof (long));
5510 6509
5511 /* Create an X image for output. */ 6510 - a list of at least 9 numbers in row-major form
5512 rc = x_create_x_image_and_pixmap (f, img->width, img->height, 0, 6511 - a vector of at least 9 numbers
5513 &oimg, &pixmap);
5514 6512
5515 /* Fill first two rows. */ 6513 COLOR_ADJUST nil means use a default; otherwise it must be a
5516 x_laplace_read_row (f, cmap, in[0], img->width, ximg, 0); 6514 number. */
5517 x_laplace_read_row (f, cmap, in[1], img->width, ximg, 1);
5518 in_y = 2;
5519 6515
5520 /* Write first row, all zeros. */ 6516static void
5521 init_color_table (); 6517x_edge_detection (f, img, matrix, color_adjust)
5522 pixel = lookup_rgb_color (f, 0, 0, 0); 6518 struct frame *f;
5523 for (x = 0; x < img->width; ++x) 6519 struct image *img;
5524 out[x] = pixel; 6520 Lisp_Object matrix, color_adjust;
5525 x_laplace_write_row (f, out, img->width, oimg, 0); 6521{
5526 out_y = 1; 6522 int i = 0;
6523 int trans[9];
5527 6524
5528 for (y = 2; y < img->height; ++y) 6525 if (CONSP (matrix))
6526 {
6527 for (i = 0;
6528 i < 9 && CONSP (matrix) && NUMBERP (XCAR (matrix));
6529 ++i, matrix = XCDR (matrix))
6530 trans[i] = XFLOATINT (XCAR (matrix));
6531 }
6532 else if (VECTORP (matrix) && ASIZE (matrix) >= 9)
5529 { 6533 {
5530 int rowa = y % 3; 6534 for (i = 0; i < 9 && NUMBERP (AREF (matrix, i)); ++i)
5531 int rowb = (y + 2) % 3; 6535 trans[i] = XFLOATINT (AREF (matrix, i));
6536 }
5532 6537
5533 x_laplace_read_row (f, cmap, in[rowa], img->width, ximg, in_y++); 6538 if (NILP (color_adjust))
6539 color_adjust = make_number (0xffff / 2);
5534 6540
5535 for (x = 0; x < img->width - 2; ++x) 6541 if (i == 9 && NUMBERP (color_adjust))
5536 { 6542 x_detect_edges (f, img, trans, (int) XFLOATINT (color_adjust));
5537 int r = in[rowa][x].red + mv2 - in[rowb][x + 2].red; 6543}
5538 int g = in[rowa][x].green + mv2 - in[rowb][x + 2].green;
5539 int b = in[rowa][x].blue + mv2 - in[rowb][x + 2].blue;
5540 6544
5541 out[x + 1] = lookup_rgb_color (f, r & 0xffff, g & 0xffff,
5542 b & 0xffff);
5543 }
5544 6545
5545 x_laplace_write_row (f, out, img->width, oimg, out_y++); 6546/* Transform image IMG on frame F so that it looks disabled. */
5546 } 6547
6548static void
6549x_disable_image (f, img)
6550 struct frame *f;
6551 struct image *img;
6552{
6553 struct x_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
5547 6554
5548 /* Write last line, all zeros. */ 6555 if (dpyinfo->n_planes >= 2)
5549 for (x = 0; x < img->width; ++x) 6556 {
5550 out[x] = pixel; 6557 /* Color (or grayscale). Convert to gray, and equalize. Just
5551 x_laplace_write_row (f, out, img->width, oimg, out_y); 6558 drawing such images with a stipple can look very odd, so
6559 we're using this method instead. */
6560 XColor *colors = x_to_xcolors (f, img, 1);
6561 XColor *p, *end;
6562 const int h = 15000;
6563 const int l = 30000;
5552 6564
5553 /* Free the input image, and free resources of IMG. */ 6565 for (p = colors, end = colors + img->width * img->height;
5554 XDestroyImage (ximg); 6566 p < end;
5555 x_clear_image (f, img); 6567 ++p)
6568 {
6569 int i = COLOR_INTENSITY (p->red, p->green, p->blue);
6570 int i2 = (0xffff - h - l) * i / 0xffff + l;
6571 p->red = p->green = p->blue = i2;
6572 }
5556 6573
5557 /* Put the output image into pixmap, and destroy it. */ 6574 x_from_xcolors (f, img, colors);
5558 x_put_x_image (f, oimg, pixmap, img->width, img->height); 6575 }
5559 x_destroy_x_image (oimg);
5560 6576
5561 /* Remember new pixmap and colors in IMG. */ 6577 /* Draw a cross over the disabled image, if we must or if we
5562 img->pixmap = pixmap; 6578 should. */
5563 img->colors = colors_in_color_table (&img->ncolors); 6579 if (dpyinfo->n_planes < 2 || cross_disabled_images)
5564 free_color_table (); 6580 {
6581 Display *dpy = FRAME_MAC_DISPLAY (f);
6582 GC gc;
5565 6583
5566 UNBLOCK_INPUT; 6584 gc = XCreateGC (dpy, NULL /*img->pixmap*/, 0, NULL);
5567#endif /* MAC_TODO */ 6585 XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
6586 mac_draw_line_to_pixmap (dpy, img->pixmap, gc, 0, 0,
6587 img->width - 1, img->height - 1);
6588 mac_draw_line_to_pixmap (dpy, img->pixmap, gc, 0, img->height - 1,
6589 img->width - 1, 0);
6590 XFreeGC (dpy, gc);
6591
6592 if (img->mask)
6593 {
6594 gc = XCreateGC (dpy, NULL /*img->mask*/, 0, NULL);
6595 XSetForeground (dpy, gc, PIX_MASK_DRAW (f));
6596 mac_draw_line_to_pixmap (dpy, img->mask, gc, 0, 0,
6597 img->width - 1, img->height - 1);
6598 mac_draw_line_to_pixmap (dpy, img->mask, gc, 0, img->height - 1,
6599 img->width - 1, 0);
6600 XFreeGC (dpy, gc);
6601 }
6602 }
5568} 6603}
5569 6604
5570 6605
5571/* Build a mask for image IMG which is used on frame F. FILE is the 6606/* Build a mask for image IMG which is used on frame F. FILE is the
5572 name of an image file, for error messages. HOW determines how to 6607 name of an image file, for error messages. HOW determines how to
5573 determine the background color of IMG. If it is a list '(R G B)', 6608 determine the background color of IMG. If it is a list '(R G B)',
5574 with R, G, and B being integers >= 0, take that as the color of the 6609 with R, G, and B being integers >= 0, take that as the color of the
5575 background. Otherwise, determine the background color of IMG 6610 background. Otherwise, determine the background color of IMG
5576 heuristically. Value is non-zero if successful. */ 6611 heuristically. Value is non-zero if successful. */
5577 6612
5578static int 6613static int
5579x_build_heuristic_mask (f, img, how) 6614x_build_heuristic_mask (f, img, how)
@@ -5581,39 +6616,37 @@ x_build_heuristic_mask (f, img, how)
5581 struct image *img; 6616 struct image *img;
5582 Lisp_Object how; 6617 Lisp_Object how;
5583{ 6618{
5584#if 0 /* MAC_TODO : Mac version */ 6619 Display *dpy = FRAME_X_DISPLAY (f);
5585 Display *dpy = FRAME_W32_DISPLAY (f); 6620 XImagePtr ximg, mask_img;
5586 XImage *ximg, *mask_img; 6621 int x, y, rc, use_img_background;
5587 int x, y, rc, look_at_corners_p; 6622 unsigned long bg = 0;
5588 unsigned long bg;
5589 6623
5590 BLOCK_INPUT; 6624 if (img->mask)
6625 {
6626 XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
6627 img->mask = 0;
6628 img->background_transparent_valid = 0;
6629 }
5591 6630
5592 /* Create an image and pixmap serving as mask. */ 6631 /* Create an image and pixmap serving as mask. */
5593 rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1, 6632 rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1,
5594 &mask_img, &img->mask); 6633 &mask_img, &img->mask);
5595 if (!rc) 6634 if (!rc)
5596 { 6635 return 0;
5597 UNBLOCK_INPUT;
5598 return 0;
5599 }
5600 6636
5601 /* Get the X image of IMG->pixmap. */ 6637 /* Get the X image of IMG->pixmap. */
5602 ximg = XGetImage (dpy, img->pixmap, 0, 0, img->width, img->height, 6638 ximg = XGetImage (dpy, img->pixmap, 0, 0, img->width, img->height,
5603 ~0, ZPixmap); 6639 ~0, ZPixmap);
5604 6640
5605 /* Determine the background color of ximg. If HOW is `(R G B)' 6641 /* Determine the background color of ximg. If HOW is `(R G B)'
5606 take that as color. Otherwise, try to determine the color 6642 take that as color. Otherwise, use the image's background color. */
5607 heuristically. */ 6643 use_img_background = 1;
5608 look_at_corners_p = 1;
5609 6644
5610 if (CONSP (how)) 6645 if (CONSP (how))
5611 { 6646 {
5612 int rgb[3], i = 0; 6647 int rgb[3], i;
5613 6648
5614 while (i < 3 6649 for (i = 0; i < 3 && CONSP (how) && NATNUMP (XCAR (how)); ++i)
5615 && CONSP (how)
5616 && NATNUMP (XCAR (how)))
5617 { 6650 {
5618 rgb[i] = XFASTINT (XCAR (how)) & 0xffff; 6651 rgb[i] = XFASTINT (XCAR (how)) & 0xffff;
5619 how = XCDR (how); 6652 how = XCDR (how);
@@ -5622,59 +6655,29 @@ x_build_heuristic_mask (f, img, how)
5622 if (i == 3 && NILP (how)) 6655 if (i == 3 && NILP (how))
5623 { 6656 {
5624 char color_name[30]; 6657 char color_name[30];
5625 XColor exact, color;
5626 Colormap cmap;
5627
5628 sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]); 6658 sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
5629 6659 bg = x_alloc_image_color (f, img, build_string (color_name), 0);
5630 cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); 6660 use_img_background = 0;
5631 if (XLookupColor (dpy, cmap, color_name, &exact, &color))
5632 {
5633 bg = color.pixel;
5634 look_at_corners_p = 0;
5635 }
5636 } 6661 }
5637 } 6662 }
5638 6663
5639 if (look_at_corners_p) 6664 if (use_img_background)
5640 { 6665 bg = four_corners_best (ximg, img->width, img->height);
5641 unsigned long corners[4];
5642 int i, best_count;
5643
5644 /* Get the colors at the corners of ximg. */
5645 corners[0] = XGetPixel (ximg, 0, 0);
5646 corners[1] = XGetPixel (ximg, img->width - 1, 0);
5647 corners[2] = XGetPixel (ximg, img->width - 1, img->height - 1);
5648 corners[3] = XGetPixel (ximg, 0, img->height - 1);
5649
5650 /* Choose the most frequently found color as background. */
5651 for (i = best_count = 0; i < 4; ++i)
5652 {
5653 int j, n;
5654
5655 for (j = n = 0; j < 4; ++j)
5656 if (corners[i] == corners[j])
5657 ++n;
5658
5659 if (n > best_count)
5660 bg = corners[i], best_count = n;
5661 }
5662 }
5663 6666
5664 /* Set all bits in mask_img to 1 whose color in ximg is different 6667 /* Set all bits in mask_img to 1 whose color in ximg is different
5665 from the background color bg. */ 6668 from the background color bg. */
5666 for (y = 0; y < img->height; ++y) 6669 for (y = 0; y < img->height; ++y)
5667 for (x = 0; x < img->width; ++x) 6670 for (x = 0; x < img->width; ++x)
5668 XPutPixel (mask_img, x, y, XGetPixel (ximg, x, y) != bg); 6671 XPutPixel (mask_img, x, y, XGetPixel (ximg, x, y) != bg ? PIX_MASK_DRAW (f) : PIX_MASK_RETAIN (f));
6672
6673 /* Fill in the background_transparent field while we have the mask handy. */
6674 image_background_transparent (img, f, mask_img);
5669 6675
5670 /* Put mask_img into img->mask. */ 6676 /* Put mask_img into img->mask. */
5671 x_put_x_image (f, mask_img, img->mask, img->width, img->height); 6677 x_put_x_image (f, mask_img, img->mask, img->width, img->height);
5672 x_destroy_x_image (mask_img); 6678 x_destroy_x_image (mask_img);
5673 XDestroyImage (ximg); 6679 XDestroyImage (ximg);
5674 6680
5675 UNBLOCK_INPUT;
5676#endif /* MAC_TODO */
5677
5678 return 1; 6681 return 1;
5679} 6682}
5680 6683
@@ -5683,7 +6686,6 @@ x_build_heuristic_mask (f, img, how)
5683/*********************************************************************** 6686/***********************************************************************
5684 PBM (mono, gray, color) 6687 PBM (mono, gray, color)
5685 ***********************************************************************/ 6688 ***********************************************************************/
5686#ifdef HAVE_PBM
5687 6689
5688static int pbm_image_p P_ ((Lisp_Object object)); 6690static int pbm_image_p P_ ((Lisp_Object object));
5689static int pbm_load P_ ((struct frame *f, struct image *img)); 6691static int pbm_load P_ ((struct frame *f, struct image *img));
@@ -5705,6 +6707,9 @@ enum pbm_keyword_index
5705 PBM_RELIEF, 6707 PBM_RELIEF,
5706 PBM_ALGORITHM, 6708 PBM_ALGORITHM,
5707 PBM_HEURISTIC_MASK, 6709 PBM_HEURISTIC_MASK,
6710 PBM_MASK,
6711 PBM_FOREGROUND,
6712 PBM_BACKGROUND,
5708 PBM_LAST 6713 PBM_LAST
5709}; 6714};
5710 6715
@@ -5716,11 +6721,14 @@ static struct image_keyword pbm_format[PBM_LAST] =
5716 {":type", IMAGE_SYMBOL_VALUE, 1}, 6721 {":type", IMAGE_SYMBOL_VALUE, 1},
5717 {":file", IMAGE_STRING_VALUE, 0}, 6722 {":file", IMAGE_STRING_VALUE, 0},
5718 {":data", IMAGE_STRING_VALUE, 0}, 6723 {":data", IMAGE_STRING_VALUE, 0},
5719 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 6724 {":ascent", IMAGE_ASCENT_VALUE, 0},
5720 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 6725 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
5721 {":relief", IMAGE_INTEGER_VALUE, 0}, 6726 {":relief", IMAGE_INTEGER_VALUE, 0},
5722 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 6727 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5723 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} 6728 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6729 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6730 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
6731 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5724}; 6732};
5725 6733
5726/* Structure describing the image type `pbm'. */ 6734/* Structure describing the image type `pbm'. */
@@ -5745,9 +6753,7 @@ pbm_image_p (object)
5745 6753
5746 bcopy (pbm_format, fmt, sizeof fmt); 6754 bcopy (pbm_format, fmt, sizeof fmt);
5747 6755
5748 if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm) 6756 if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm))
5749 || (fmt[PBM_ASCENT].count
5750 && XFASTINT (fmt[PBM_ASCENT].value) > 100))
5751 return 0; 6757 return 0;
5752 6758
5753 /* Must specify either :data or :file. */ 6759 /* Must specify either :data or :file. */
@@ -5763,7 +6769,7 @@ static int
5763pbm_scan_number (s, end) 6769pbm_scan_number (s, end)
5764 unsigned char **s, *end; 6770 unsigned char **s, *end;
5765{ 6771{
5766 int c, val = -1; 6772 int c = 0, val = -1;
5767 6773
5768 while (*s < end) 6774 while (*s < end)
5769 { 6775 {
@@ -5793,42 +6799,6 @@ pbm_scan_number (s, end)
5793} 6799}
5794 6800
5795 6801
5796/* Read FILE into memory. Value is a pointer to a buffer allocated
5797 with xmalloc holding FILE's contents. Value is null if an error
5798 occurred. *SIZE is set to the size of the file. */
5799
5800static char *
5801pbm_read_file (file, size)
5802 Lisp_Object file;
5803 int *size;
5804{
5805 FILE *fp = NULL;
5806 char *buf = NULL;
5807 struct stat st;
5808
5809 if (stat (SDATA (file), &st) == 0
5810 && (fp = fopen (SDATA (file), "r")) != NULL
5811 && (buf = (char *) xmalloc (st.st_size),
5812 fread (buf, 1, st.st_size, fp) == st.st_size))
5813 {
5814 *size = st.st_size;
5815 fclose (fp);
5816 }
5817 else
5818 {
5819 if (fp)
5820 fclose (fp);
5821 if (buf)
5822 {
5823 xfree (buf);
5824 buf = NULL;
5825 }
5826 }
5827
5828 return buf;
5829}
5830
5831
5832/* Load PBM image IMG for use on frame F. */ 6802/* Load PBM image IMG for use on frame F. */
5833 6803
5834static int 6804static int
@@ -5838,7 +6808,7 @@ pbm_load (f, img)
5838{ 6808{
5839 int raw_p, x, y; 6809 int raw_p, x, y;
5840 int width, height, max_color_idx = 0; 6810 int width, height, max_color_idx = 0;
5841 XImage *ximg; 6811 XImagePtr ximg;
5842 Lisp_Object file, specified_file; 6812 Lisp_Object file, specified_file;
5843 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; 6813 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5844 struct gcpro gcpro1; 6814 struct gcpro gcpro1;
@@ -5854,13 +6824,13 @@ pbm_load (f, img)
5854 { 6824 {
5855 file = x_find_image_file (specified_file); 6825 file = x_find_image_file (specified_file);
5856 if (!STRINGP (file)) 6826 if (!STRINGP (file))
5857 { 6827 {
5858 image_error ("Cannot find image file `%s'", specified_file, Qnil); 6828 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5859 UNGCPRO; 6829 UNGCPRO;
5860 return 0; 6830 return 0;
5861 } 6831 }
5862 6832
5863 contents = pbm_read_file (file, &size); 6833 contents = slurp_file (SDATA (file), &size);
5864 if (contents == NULL) 6834 if (contents == NULL)
5865 { 6835 {
5866 image_error ("Error reading `%s'", file, Qnil); 6836 image_error ("Error reading `%s'", file, Qnil);
@@ -5937,20 +6907,37 @@ pbm_load (f, img)
5937 || (type != PBM_MONO && max_color_idx < 0)) 6907 || (type != PBM_MONO && max_color_idx < 0))
5938 goto error; 6908 goto error;
5939 6909
5940 BLOCK_INPUT;
5941 if (!x_create_x_image_and_pixmap (f, width, height, 0, 6910 if (!x_create_x_image_and_pixmap (f, width, height, 0,
5942 &ximg, &img->pixmap)) 6911 &ximg, &img->pixmap))
5943 { 6912 goto error;
5944 UNBLOCK_INPUT;
5945 goto error;
5946 }
5947 6913
6914#if 0 /* TODO: color tables. */
5948 /* Initialize the color hash table. */ 6915 /* Initialize the color hash table. */
5949 init_color_table (); 6916 init_color_table ();
6917#endif
5950 6918
5951 if (type == PBM_MONO) 6919 if (type == PBM_MONO)
5952 { 6920 {
5953 int c = 0, g; 6921 int c = 0, g;
6922 struct image_keyword fmt[PBM_LAST];
6923 unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
6924 unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
6925
6926 /* Parse the image specification. */
6927 bcopy (pbm_format, fmt, sizeof fmt);
6928 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
6929
6930 /* Get foreground and background colors, maybe allocate colors. */
6931 if (fmt[PBM_FOREGROUND].count
6932 && STRINGP (fmt[PBM_FOREGROUND].value))
6933 fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
6934 if (fmt[PBM_BACKGROUND].count
6935 && STRINGP (fmt[PBM_BACKGROUND].value))
6936 {
6937 bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
6938 img->background = bg;
6939 img->background_valid = 1;
6940 }
5954 6941
5955 for (y = 0; y < height; ++y) 6942 for (y = 0; y < height; ++y)
5956 for (x = 0; x < width; ++x) 6943 for (x = 0; x < width; ++x)
@@ -5965,9 +6952,7 @@ pbm_load (f, img)
5965 else 6952 else
5966 g = pbm_scan_number (&p, end); 6953 g = pbm_scan_number (&p, end);
5967 6954
5968 XPutPixel (ximg, x, y, (g 6955 XPutPixel (ximg, x, y, g ? fg : bg);
5969 ? FRAME_FOREGROUND_PIXEL (f)
5970 : FRAME_BACKGROUND_PIXEL (f)));
5971 } 6956 }
5972 } 6957 }
5973 else 6958 else
@@ -5994,13 +6979,10 @@ pbm_load (f, img)
5994 6979
5995 if (r < 0 || g < 0 || b < 0) 6980 if (r < 0 || g < 0 || b < 0)
5996 { 6981 {
5997 xfree (ximg->data); 6982 x_destroy_x_image (ximg);
5998 ximg->data = NULL;
5999 XDestroyImage (ximg);
6000 UNBLOCK_INPUT;
6001 image_error ("Invalid pixel value in image `%s'", 6983 image_error ("Invalid pixel value in image `%s'",
6002 img->spec, Qnil); 6984 img->spec, Qnil);
6003 goto error; 6985 goto error;
6004 } 6986 }
6005 6987
6006 /* RGB values are now in the range 0..max_color_idx. 6988 /* RGB values are now in the range 0..max_color_idx.
@@ -6012,33 +6994,35 @@ pbm_load (f, img)
6012 } 6994 }
6013 } 6995 }
6014 6996
6997#if 0 /* TODO: color tables. */
6015 /* Store in IMG->colors the colors allocated for the image, and 6998 /* Store in IMG->colors the colors allocated for the image, and
6016 free the color table. */ 6999 free the color table. */
6017 img->colors = colors_in_color_table (&img->ncolors); 7000 img->colors = colors_in_color_table (&img->ncolors);
6018 free_color_table (); 7001 free_color_table ();
7002#endif
7003
7004 img->width = width;
7005 img->height = height;
7006
7007 /* Maybe fill in the background field while we have ximg handy. */
7008 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7009 IMAGE_BACKGROUND (img, f, ximg);
6019 7010
6020 /* Put the image into a pixmap. */ 7011 /* Put the image into a pixmap. */
6021 x_put_x_image (f, ximg, img->pixmap, width, height); 7012 x_put_x_image (f, ximg, img->pixmap, width, height);
6022 x_destroy_x_image (ximg); 7013 x_destroy_x_image (ximg);
6023 UNBLOCK_INPUT;
6024
6025 img->width = width;
6026 img->height = height;
6027 7014
6028 UNGCPRO; 7015 UNGCPRO;
6029 xfree (contents); 7016 xfree (contents);
6030 return 1; 7017 return 1;
6031} 7018}
6032#endif /* HAVE_PBM */ 7019
6033 7020
6034 7021
6035/*********************************************************************** 7022/***********************************************************************
6036 PNG 7023 PNG
6037 ***********************************************************************/ 7024 ***********************************************************************/
6038 7025
6039#if HAVE_PNG
6040
6041#include <png.h>
6042 7026
6043/* Function prototypes. */ 7027/* Function prototypes. */
6044 7028
@@ -6061,6 +7045,8 @@ enum png_keyword_index
6061 PNG_RELIEF, 7045 PNG_RELIEF,
6062 PNG_ALGORITHM, 7046 PNG_ALGORITHM,
6063 PNG_HEURISTIC_MASK, 7047 PNG_HEURISTIC_MASK,
7048 PNG_MASK,
7049 PNG_BACKGROUND,
6064 PNG_LAST 7050 PNG_LAST
6065}; 7051};
6066 7052
@@ -6072,11 +7058,13 @@ static struct image_keyword png_format[PNG_LAST] =
6072 {":type", IMAGE_SYMBOL_VALUE, 1}, 7058 {":type", IMAGE_SYMBOL_VALUE, 1},
6073 {":data", IMAGE_STRING_VALUE, 0}, 7059 {":data", IMAGE_STRING_VALUE, 0},
6074 {":file", IMAGE_STRING_VALUE, 0}, 7060 {":file", IMAGE_STRING_VALUE, 0},
6075 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 7061 {":ascent", IMAGE_ASCENT_VALUE, 0},
6076 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 7062 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
6077 {":relief", IMAGE_INTEGER_VALUE, 0}, 7063 {":relief", IMAGE_INTEGER_VALUE, 0},
6078 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7064 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6079 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} 7065 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7066 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7067 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6080}; 7068};
6081 7069
6082/* Structure describing the image type `png'. */ 7070/* Structure describing the image type `png'. */
@@ -6100,9 +7088,7 @@ png_image_p (object)
6100 struct image_keyword fmt[PNG_LAST]; 7088 struct image_keyword fmt[PNG_LAST];
6101 bcopy (png_format, fmt, sizeof fmt); 7089 bcopy (png_format, fmt, sizeof fmt);
6102 7090
6103 if (!parse_image_spec (object, fmt, PNG_LAST, Qpng) 7091 if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
6104 || (fmt[PNG_ASCENT].count
6105 && XFASTINT (fmt[PNG_ASCENT].value) > 100))
6106 return 0; 7092 return 0;
6107 7093
6108 /* Must specify either the :data or :file keyword. */ 7094 /* Must specify either the :data or :file keyword. */
@@ -6110,6 +7096,27 @@ png_image_p (object)
6110} 7096}
6111 7097
6112 7098
7099#ifndef HAVE_PNG
7100static int
7101png_load (f, img)
7102 struct frame *f;
7103 struct image *img;
7104{
7105#ifdef MAC_OSX
7106 if (MyCGImageCreateWithPNGDataProvider)
7107 return image_load_quartz2d (f, img, 1);
7108 else
7109#endif
7110 return image_load_quicktime (f, img, kQTFileTypePNG);
7111}
7112#else
7113
7114#if defined HAVE_LIBPNG_PNG_H
7115# include <libpng/png.h>
7116#else
7117# include <png.h>
7118#endif
7119
6113/* Error and warning handlers installed when the PNG library 7120/* Error and warning handlers installed when the PNG library
6114 is initialized. */ 7121 is initialized. */
6115 7122
@@ -6174,22 +7181,20 @@ png_load (f, img)
6174 Lisp_Object file, specified_file; 7181 Lisp_Object file, specified_file;
6175 Lisp_Object specified_data; 7182 Lisp_Object specified_data;
6176 int x, y, i; 7183 int x, y, i;
6177 XImage *ximg, *mask_img = NULL; 7184 XImagePtr ximg, mask_img = NULL;
6178 struct gcpro gcpro1; 7185 struct gcpro gcpro1;
6179 png_struct *png_ptr = NULL; 7186 png_struct *png_ptr = NULL;
6180 png_info *info_ptr = NULL, *end_info = NULL; 7187 png_info *info_ptr = NULL, *end_info = NULL;
6181 FILE *fp = NULL; 7188 FILE *volatile fp = NULL;
6182 png_byte sig[8]; 7189 png_byte sig[8];
6183 png_byte *pixels = NULL; 7190 png_byte * volatile pixels = NULL;
6184 png_byte **rows = NULL; 7191 png_byte ** volatile rows = NULL;
6185 png_uint_32 width, height; 7192 png_uint_32 width, height;
6186 int bit_depth, color_type, interlace_type; 7193 int bit_depth, color_type, interlace_type;
6187 png_byte channels; 7194 png_byte channels;
6188 png_uint_32 row_bytes; 7195 png_uint_32 row_bytes;
6189 int transparent_p; 7196 int transparent_p;
6190 char *gamma_str; 7197 double screen_gamma;
6191 double screen_gamma, image_gamma;
6192 int intent;
6193 struct png_memory_storage tbr; /* Data to be read */ 7198 struct png_memory_storage tbr; /* Data to be read */
6194 7199
6195 /* Find out what file to load. */ 7200 /* Find out what file to load. */
@@ -6202,31 +7207,31 @@ png_load (f, img)
6202 { 7207 {
6203 file = x_find_image_file (specified_file); 7208 file = x_find_image_file (specified_file);
6204 if (!STRINGP (file)) 7209 if (!STRINGP (file))
6205 { 7210 {
6206 image_error ("Cannot find image file `%s'", specified_file, Qnil); 7211 image_error ("Cannot find image file `%s'", specified_file, Qnil);
6207 UNGCPRO; 7212 UNGCPRO;
6208 return 0; 7213 return 0;
6209 } 7214 }
6210 7215
6211 /* Open the image file. */ 7216 /* Open the image file. */
6212 fp = fopen (SDATA (file), "rb"); 7217 fp = fopen (SDATA (file), "rb");
6213 if (!fp) 7218 if (!fp)
6214 { 7219 {
6215 image_error ("Cannot open image file `%s'", file, Qnil); 7220 image_error ("Cannot open image file `%s'", file, Qnil);
6216 UNGCPRO; 7221 UNGCPRO;
6217 fclose (fp); 7222 fclose (fp);
6218 return 0; 7223 return 0;
6219 } 7224 }
6220 7225
6221 /* Check PNG signature. */ 7226 /* Check PNG signature. */
6222 if (fread (sig, 1, sizeof sig, fp) != sizeof sig 7227 if (fread (sig, 1, sizeof sig, fp) != sizeof sig
6223 || !png_check_sig (sig, sizeof sig)) 7228 || !png_check_sig (sig, sizeof sig))
6224 { 7229 {
6225 image_error ("Not a PNG file:` %s'", file, Qnil); 7230 image_error ("Not a PNG file: `%s'", file, Qnil);
6226 UNGCPRO; 7231 UNGCPRO;
6227 fclose (fp); 7232 fclose (fp);
6228 return 0; 7233 return 0;
6229 } 7234 }
6230 } 7235 }
6231 else 7236 else
6232 { 7237 {
@@ -6325,56 +7330,76 @@ png_load (f, img)
6325 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 7330 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
6326 png_set_gray_to_rgb (png_ptr); 7331 png_set_gray_to_rgb (png_ptr);
6327 7332
6328 /* The value 2.2 is a guess for PC monitors from PNG example.c. */ 7333 screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2);
6329 gamma_str = getenv ("SCREEN_GAMMA");
6330 screen_gamma = gamma_str ? atof (gamma_str) : 2.2;
6331
6332 /* Tell the PNG lib to handle gamma correction for us. */
6333 7334
7335#if 0 /* Avoid double gamma correction for PNG images. */
7336 { /* Tell the PNG lib to handle gamma correction for us. */
7337 int intent;
7338 double image_gamma;
6334#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED) 7339#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
6335 if (png_get_sRGB (png_ptr, info_ptr, &intent)) 7340 if (png_get_sRGB (png_ptr, info_ptr, &intent))
6336 /* There is a special chunk in the image specifying the gamma. */ 7341 /* The libpng documentation says this is right in this case. */
6337 png_set_sRGB (png_ptr, info_ptr, intent); 7342 png_set_gamma (png_ptr, screen_gamma, 0.45455);
6338 else 7343 else
6339#endif 7344#endif
6340 if (png_get_gAMA (png_ptr, info_ptr, &image_gamma)) 7345 if (png_get_gAMA (png_ptr, info_ptr, &image_gamma))
6341 /* Image contains gamma information. */ 7346 /* Image contains gamma information. */
6342 png_set_gamma (png_ptr, screen_gamma, image_gamma); 7347 png_set_gamma (png_ptr, screen_gamma, image_gamma);
6343 else 7348 else
6344 /* Use a default of 0.5 for the image gamma. */ 7349 /* Use the standard default for the image gamma. */
6345 png_set_gamma (png_ptr, screen_gamma, 0.5); 7350 png_set_gamma (png_ptr, screen_gamma, 0.45455);
7351 }
7352#endif /* if 0 */
6346 7353
6347 /* Handle alpha channel by combining the image with a background 7354 /* Handle alpha channel by combining the image with a background
6348 color. Do this only if a real alpha channel is supplied. For 7355 color. Do this only if a real alpha channel is supplied. For
6349 simple transparency, we prefer a clipping mask. */ 7356 simple transparency, we prefer a clipping mask. */
6350 if (!transparent_p) 7357 if (!transparent_p)
6351 { 7358 {
6352 png_color_16 *image_background; 7359 png_color_16 *image_bg;
7360 Lisp_Object specified_bg
7361 = image_spec_value (img->spec, QCbackground, NULL);
6353 7362
6354 if (png_get_bKGD (png_ptr, info_ptr, &image_background)) 7363 if (STRINGP (specified_bg))
7364 /* The user specified `:background', use that. */
7365 {
7366 XColor color;
7367 if (mac_defined_color (f, SDATA (specified_bg), &color, 0))
7368 {
7369 png_color_16 user_bg;
7370
7371 bzero (&user_bg, sizeof user_bg);
7372 user_bg.red = color.red >> 8;
7373 user_bg.green = color.green >> 8;
7374 user_bg.blue = color.blue >> 8;
7375
7376 png_set_background (png_ptr, &user_bg,
7377 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
7378 }
7379 }
7380 else if (png_get_bKGD (png_ptr, info_ptr, &image_bg))
6355 /* Image contains a background color with which to 7381 /* Image contains a background color with which to
6356 combine the image. */ 7382 combine the image. */
6357 png_set_background (png_ptr, image_background, 7383 png_set_background (png_ptr, image_bg,
6358 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); 7384 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
6359 else 7385 else
6360 { 7386 {
6361 /* Image does not contain a background color with which 7387 /* Image does not contain a background color with which
6362 to combine the image data via an alpha channel. Use 7388 to combine the image data via an alpha channel. Use
6363 the frame's background instead. */ 7389 the frame's background instead. */
6364 XColor color; 7390 unsigned long color;
6365 Colormap cmap;
6366 png_color_16 frame_background; 7391 png_color_16 frame_background;
7392 color = FRAME_BACKGROUND_PIXEL (f);
7393#if 0 /* TODO : Colormap support. */
7394 Colormap cmap;
6367 7395
6368 BLOCK_INPUT; 7396 cmap = FRAME_X_COLORMAP (f);
6369 cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); 7397 x_query_color (f, &color);
6370 color.pixel = FRAME_BACKGROUND_PIXEL (f); 7398#endif
6371 XQueryColor (FRAME_W32_DISPLAY (f), cmap, &color);
6372 UNBLOCK_INPUT;
6373
6374 bzero (&frame_background, sizeof frame_background); 7399 bzero (&frame_background, sizeof frame_background);
6375 frame_background.red = color.red; 7400 frame_background.red = RED_FROM_ULONG (color);
6376 frame_background.green = color.green; 7401 frame_background.green = GREEN_FROM_ULONG (color);
6377 frame_background.blue = color.blue; 7402 frame_background.blue = BLUE_FROM_ULONG (color);
6378 7403
6379 png_set_background (png_ptr, &frame_background, 7404 png_set_background (png_ptr, &frame_background,
6380 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); 7405 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
@@ -6410,15 +7435,10 @@ png_load (f, img)
6410 fp = NULL; 7435 fp = NULL;
6411 } 7436 }
6412 7437
6413 BLOCK_INPUT;
6414
6415 /* Create the X image and pixmap. */ 7438 /* Create the X image and pixmap. */
6416 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, 7439 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
6417 &img->pixmap)) 7440 &img->pixmap))
6418 { 7441 goto error;
6419 UNBLOCK_INPUT;
6420 goto error;
6421 }
6422 7442
6423 /* Create an image and pixmap serving as mask if the PNG image 7443 /* Create an image and pixmap serving as mask if the PNG image
6424 contains an alpha channel. */ 7444 contains an alpha channel. */
@@ -6428,14 +7448,15 @@ png_load (f, img)
6428 &mask_img, &img->mask)) 7448 &mask_img, &img->mask))
6429 { 7449 {
6430 x_destroy_x_image (ximg); 7450 x_destroy_x_image (ximg);
6431 XFreePixmap (FRAME_W32_DISPLAY (f), img->pixmap); 7451 XFreePixmap (FRAME_MAC_DISPLAY (f), img->pixmap);
6432 img->pixmap = 0; 7452 img->pixmap = NULL;
6433 UNBLOCK_INPUT;
6434 goto error; 7453 goto error;
6435 } 7454 }
6436 7455
6437 /* Fill the X image and mask from PNG data. */ 7456 /* Fill the X image and mask from PNG data. */
7457#if 0 /* TODO: Color tables. */
6438 init_color_table (); 7458 init_color_table ();
7459#endif
6439 7460
6440 for (y = 0; y < height; ++y) 7461 for (y = 0; y < height; ++y)
6441 { 7462 {
@@ -6469,15 +7490,29 @@ png_load (f, img)
6469 if (channels == 4) 7490 if (channels == 4)
6470 { 7491 {
6471 if (mask_img) 7492 if (mask_img)
6472 XPutPixel (mask_img, x, y, *p > 0); 7493 XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW (f) : PIX_MASK_RETAIN (f));
6473 ++p; 7494 ++p;
6474 } 7495 }
6475 } 7496 }
6476 } 7497 }
6477 7498
7499 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7500 /* Set IMG's background color from the PNG image, unless the user
7501 overrode it. */
7502 {
7503 png_color_16 *bg;
7504 if (png_get_bKGD (png_ptr, info_ptr, &bg))
7505 {
7506 img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
7507 img->background_valid = 1;
7508 }
7509 }
7510
7511#if 0 /* TODO: Color tables. */
6478 /* Remember colors allocated for this image. */ 7512 /* Remember colors allocated for this image. */
6479 img->colors = colors_in_color_table (&img->ncolors); 7513 img->colors = colors_in_color_table (&img->ncolors);
6480 free_color_table (); 7514 free_color_table ();
7515#endif
6481 7516
6482 /* Clean up. */ 7517 /* Clean up. */
6483 png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); 7518 png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
@@ -6487,6 +7522,9 @@ png_load (f, img)
6487 img->width = width; 7522 img->width = width;
6488 img->height = height; 7523 img->height = height;
6489 7524
7525 /* Maybe fill in the background field while we have ximg handy. */
7526 IMAGE_BACKGROUND (img, f, ximg);
7527
6490 /* Put the image into the pixmap, then free the X image and its buffer. */ 7528 /* Put the image into the pixmap, then free the X image and its buffer. */
6491 x_put_x_image (f, ximg, img->pixmap, width, height); 7529 x_put_x_image (f, ximg, img->pixmap, width, height);
6492 x_destroy_x_image (ximg); 7530 x_destroy_x_image (ximg);
@@ -6494,16 +7532,19 @@ png_load (f, img)
6494 /* Same for the mask. */ 7532 /* Same for the mask. */
6495 if (mask_img) 7533 if (mask_img)
6496 { 7534 {
7535 /* Fill in the background_transparent field while we have the mask
7536 handy. */
7537 image_background_transparent (img, f, mask_img);
7538
6497 x_put_x_image (f, mask_img, img->mask, img->width, img->height); 7539 x_put_x_image (f, mask_img, img->mask, img->width, img->height);
6498 x_destroy_x_image (mask_img); 7540 x_destroy_x_image (mask_img);
6499 } 7541 }
6500 7542
6501 UNBLOCK_INPUT;
6502 UNGCPRO; 7543 UNGCPRO;
6503 return 1; 7544 return 1;
6504} 7545}
6505 7546
6506#endif /* HAVE_PNG != 0 */ 7547#endif /* HAVE_PNG */
6507 7548
6508 7549
6509 7550
@@ -6511,23 +7552,6 @@ png_load (f, img)
6511 JPEG 7552 JPEG
6512 ***********************************************************************/ 7553 ***********************************************************************/
6513 7554
6514#if HAVE_JPEG
6515
6516/* Work around a warning about HAVE_STDLIB_H being redefined in
6517 jconfig.h. */
6518#ifdef HAVE_STDLIB_H
6519#define HAVE_STDLIB_H_1
6520#undef HAVE_STDLIB_H
6521#endif /* HAVE_STLIB_H */
6522
6523#include <jpeglib.h>
6524#include <jerror.h>
6525#include <setjmp.h>
6526
6527#ifdef HAVE_STLIB_H_1
6528#define HAVE_STDLIB_H 1
6529#endif
6530
6531static int jpeg_image_p P_ ((Lisp_Object object)); 7555static int jpeg_image_p P_ ((Lisp_Object object));
6532static int jpeg_load P_ ((struct frame *f, struct image *img)); 7556static int jpeg_load P_ ((struct frame *f, struct image *img));
6533 7557
@@ -6547,6 +7571,8 @@ enum jpeg_keyword_index
6547 JPEG_RELIEF, 7571 JPEG_RELIEF,
6548 JPEG_ALGORITHM, 7572 JPEG_ALGORITHM,
6549 JPEG_HEURISTIC_MASK, 7573 JPEG_HEURISTIC_MASK,
7574 JPEG_MASK,
7575 JPEG_BACKGROUND,
6550 JPEG_LAST 7576 JPEG_LAST
6551}; 7577};
6552 7578
@@ -6558,11 +7584,13 @@ static struct image_keyword jpeg_format[JPEG_LAST] =
6558 {":type", IMAGE_SYMBOL_VALUE, 1}, 7584 {":type", IMAGE_SYMBOL_VALUE, 1},
6559 {":data", IMAGE_STRING_VALUE, 0}, 7585 {":data", IMAGE_STRING_VALUE, 0},
6560 {":file", IMAGE_STRING_VALUE, 0}, 7586 {":file", IMAGE_STRING_VALUE, 0},
6561 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 7587 {":ascent", IMAGE_ASCENT_VALUE, 0},
6562 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 7588 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
6563 {":relief", IMAGE_INTEGER_VALUE, 0}, 7589 {":relief", IMAGE_INTEGER_VALUE, 0},
6564 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7590 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6565 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} 7591 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7592 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7593 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6566}; 7594};
6567 7595
6568/* Structure describing the image type `jpeg'. */ 7596/* Structure describing the image type `jpeg'. */
@@ -6587,9 +7615,7 @@ jpeg_image_p (object)
6587 7615
6588 bcopy (jpeg_format, fmt, sizeof fmt); 7616 bcopy (jpeg_format, fmt, sizeof fmt);
6589 7617
6590 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg) 7618 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
6591 || (fmt[JPEG_ASCENT].count
6592 && XFASTINT (fmt[JPEG_ASCENT].value) > 100))
6593 return 0; 7619 return 0;
6594 7620
6595 /* Must specify either the :data or :file keyword. */ 7621 /* Must specify either the :data or :file keyword. */
@@ -6597,12 +7623,42 @@ jpeg_image_p (object)
6597} 7623}
6598 7624
6599 7625
7626#ifndef HAVE_JPEG
7627static int
7628jpeg_load (f, img)
7629 struct frame *f;
7630 struct image *img;
7631{
7632#ifdef MAC_OSX
7633 return image_load_quartz2d (f, img, 0);
7634#else
7635 return image_load_quicktime (f, img, kQTFileTypeJPEG);
7636#endif
7637}
7638#else
7639
7640/* Work around a warning about HAVE_STDLIB_H being redefined in
7641 jconfig.h. */
7642#ifdef HAVE_STDLIB_H
7643#define HAVE_STDLIB_H_1
7644#undef HAVE_STDLIB_H
7645#endif /* HAVE_STLIB_H */
7646
7647#include <jpeglib.h>
7648#include <jerror.h>
7649#include <setjmp.h>
7650
7651#ifdef HAVE_STLIB_H_1
7652#define HAVE_STDLIB_H 1
7653#endif
7654
6600struct my_jpeg_error_mgr 7655struct my_jpeg_error_mgr
6601{ 7656{
6602 struct jpeg_error_mgr pub; 7657 struct jpeg_error_mgr pub;
6603 jmp_buf setjmp_buffer; 7658 jmp_buf setjmp_buffer;
6604}; 7659};
6605 7660
7661
6606static void 7662static void
6607my_error_exit (cinfo) 7663my_error_exit (cinfo)
6608 j_common_ptr cinfo; 7664 j_common_ptr cinfo;
@@ -6611,6 +7667,7 @@ my_error_exit (cinfo)
6611 longjmp (mgr->setjmp_buffer, 1); 7667 longjmp (mgr->setjmp_buffer, 1);
6612} 7668}
6613 7669
7670
6614/* Init source method for JPEG data source manager. Called by 7671/* Init source method for JPEG data source manager. Called by
6615 jpeg_read_header() before any data is actually read. See 7672 jpeg_read_header() before any data is actually read. See
6616 libjpeg.doc from the JPEG lib distribution. */ 7673 libjpeg.doc from the JPEG lib distribution. */
@@ -6719,10 +7776,10 @@ jpeg_load (f, img)
6719 struct my_jpeg_error_mgr mgr; 7776 struct my_jpeg_error_mgr mgr;
6720 Lisp_Object file, specified_file; 7777 Lisp_Object file, specified_file;
6721 Lisp_Object specified_data; 7778 Lisp_Object specified_data;
6722 FILE *fp = NULL; 7779 FILE * volatile fp = NULL;
6723 JSAMPARRAY buffer; 7780 JSAMPARRAY buffer;
6724 int row_stride, x, y; 7781 int row_stride, x, y;
6725 XImage *ximg = NULL; 7782 XImagePtr ximg = NULL;
6726 int rc; 7783 int rc;
6727 unsigned long *colors; 7784 unsigned long *colors;
6728 int width, height; 7785 int width, height;
@@ -6738,25 +7795,25 @@ jpeg_load (f, img)
6738 { 7795 {
6739 file = x_find_image_file (specified_file); 7796 file = x_find_image_file (specified_file);
6740 if (!STRINGP (file)) 7797 if (!STRINGP (file))
6741 { 7798 {
6742 image_error ("Cannot find image file `%s'", specified_file, Qnil); 7799 image_error ("Cannot find image file `%s'", specified_file, Qnil);
6743 UNGCPRO; 7800 UNGCPRO;
6744 return 0; 7801 return 0;
6745 } 7802 }
6746 7803
6747 fp = fopen (SDATA (file), "r"); 7804 fp = fopen (SDATA (file), "r");
6748 if (fp == NULL) 7805 if (fp == NULL)
6749 { 7806 {
6750 image_error ("Cannot open `%s'", file, Qnil); 7807 image_error ("Cannot open `%s'", file, Qnil);
6751 UNGCPRO; 7808 UNGCPRO;
6752 return 0; 7809 return 0;
6753 } 7810 }
6754 } 7811 }
6755 7812
6756 /* Customize libjpeg's error handling to call my_error_exit when an 7813 /* Customize libjpeg's error handling to call my_error_exit when an
6757 error is detected. This function will perform a longjmp. */ 7814 error is detected. This function will perform a longjmp. */
6758 mgr.pub.error_exit = my_error_exit;
6759 cinfo.err = jpeg_std_error (&mgr.pub); 7815 cinfo.err = jpeg_std_error (&mgr.pub);
7816 mgr.pub.error_exit = my_error_exit;
6760 7817
6761 if ((rc = setjmp (mgr.setjmp_buffer)) != 0) 7818 if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
6762 { 7819 {
@@ -6771,28 +7828,25 @@ jpeg_load (f, img)
6771 7828
6772 /* Close the input file and destroy the JPEG object. */ 7829 /* Close the input file and destroy the JPEG object. */
6773 if (fp) 7830 if (fp)
6774 fclose (fp); 7831 fclose ((FILE *) fp);
6775 jpeg_destroy_decompress (&cinfo); 7832 jpeg_destroy_decompress (&cinfo);
6776 7833
6777 BLOCK_INPUT;
6778
6779 /* If we already have an XImage, free that. */ 7834 /* If we already have an XImage, free that. */
6780 x_destroy_x_image (ximg); 7835 x_destroy_x_image (ximg);
6781 7836
6782 /* Free pixmap and colors. */ 7837 /* Free pixmap and colors. */
6783 x_clear_image (f, img); 7838 x_clear_image (f, img);
6784 7839
6785 UNBLOCK_INPUT;
6786 UNGCPRO; 7840 UNGCPRO;
6787 return 0; 7841 return 0;
6788 } 7842 }
6789 7843
6790 /* Create the JPEG decompression object. Let it read from fp. 7844 /* Create the JPEG decompression object. Let it read from fp.
6791 Read the JPEG image header. */ 7845 Read the JPEG image header. */
6792 jpeg_create_decompress (&cinfo); 7846 jpeg_create_decompress (&cinfo);
6793 7847
6794 if (NILP (specified_data)) 7848 if (NILP (specified_data))
6795 jpeg_stdio_src (&cinfo, fp); 7849 jpeg_stdio_src (&cinfo, (FILE *) fp);
6796 else 7850 else
6797 jpeg_memory_src (&cinfo, SDATA (specified_data), 7851 jpeg_memory_src (&cinfo, SDATA (specified_data),
6798 SBYTES (specified_data)); 7852 SBYTES (specified_data));
@@ -6800,21 +7854,15 @@ jpeg_load (f, img)
6800 jpeg_read_header (&cinfo, TRUE); 7854 jpeg_read_header (&cinfo, TRUE);
6801 7855
6802 /* Customize decompression so that color quantization will be used. 7856 /* Customize decompression so that color quantization will be used.
6803 Start decompression. */ 7857 Start decompression. */
6804 cinfo.quantize_colors = TRUE; 7858 cinfo.quantize_colors = TRUE;
6805 jpeg_start_decompress (&cinfo); 7859 jpeg_start_decompress (&cinfo);
6806 width = img->width = cinfo.output_width; 7860 width = img->width = cinfo.output_width;
6807 height = img->height = cinfo.output_height; 7861 height = img->height = cinfo.output_height;
6808 7862
6809 BLOCK_INPUT;
6810
6811 /* Create X image and pixmap. */ 7863 /* Create X image and pixmap. */
6812 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, 7864 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
6813 &img->pixmap)) 7865 longjmp (mgr.setjmp_buffer, 2);
6814 {
6815 UNBLOCK_INPUT;
6816 longjmp (mgr.setjmp_buffer, 2);
6817 }
6818 7866
6819 /* Allocate colors. When color quantization is used, 7867 /* Allocate colors. When color quantization is used,
6820 cinfo.actual_number_of_colors has been set with the number of 7868 cinfo.actual_number_of_colors has been set with the number of
@@ -6831,11 +7879,13 @@ jpeg_load (f, img)
6831 else 7879 else
6832 ir = 0, ig = 0, ib = 0; 7880 ir = 0, ig = 0, ib = 0;
6833 7881
7882#if 0 /* TODO: Color tables. */
6834 /* Use the color table mechanism because it handles colors that 7883 /* Use the color table mechanism because it handles colors that
6835 cannot be allocated nicely. Such colors will be replaced with 7884 cannot be allocated nicely. Such colors will be replaced with
6836 a default color, and we don't have to care about which colors 7885 a default color, and we don't have to care about which colors
6837 can be freed safely, and which can't. */ 7886 can be freed safely, and which can't. */
6838 init_color_table (); 7887 init_color_table ();
7888#endif
6839 colors = (unsigned long *) alloca (cinfo.actual_number_of_colors 7889 colors = (unsigned long *) alloca (cinfo.actual_number_of_colors
6840 * sizeof *colors); 7890 * sizeof *colors);
6841 7891
@@ -6849,9 +7899,11 @@ jpeg_load (f, img)
6849 colors[i] = lookup_rgb_color (f, r, g, b); 7899 colors[i] = lookup_rgb_color (f, r, g, b);
6850 } 7900 }
6851 7901
7902#if 0 /* TODO: Color tables. */
6852 /* Remember those colors actually allocated. */ 7903 /* Remember those colors actually allocated. */
6853 img->colors = colors_in_color_table (&img->ncolors); 7904 img->colors = colors_in_color_table (&img->ncolors);
6854 free_color_table (); 7905 free_color_table ();
7906#endif
6855 } 7907 }
6856 7908
6857 /* Read pixels. */ 7909 /* Read pixels. */
@@ -6869,12 +7921,15 @@ jpeg_load (f, img)
6869 jpeg_finish_decompress (&cinfo); 7921 jpeg_finish_decompress (&cinfo);
6870 jpeg_destroy_decompress (&cinfo); 7922 jpeg_destroy_decompress (&cinfo);
6871 if (fp) 7923 if (fp)
6872 fclose (fp); 7924 fclose ((FILE *) fp);
7925
7926 /* Maybe fill in the background field while we have ximg handy. */
7927 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7928 IMAGE_BACKGROUND (img, f, ximg);
6873 7929
6874 /* Put the image into the pixmap. */ 7930 /* Put the image into the pixmap. */
6875 x_put_x_image (f, ximg, img->pixmap, width, height); 7931 x_put_x_image (f, ximg, img->pixmap, width, height);
6876 x_destroy_x_image (ximg); 7932 x_destroy_x_image (ximg);
6877 UNBLOCK_INPUT;
6878 UNGCPRO; 7933 UNGCPRO;
6879 return 1; 7934 return 1;
6880} 7935}
@@ -6887,10 +7942,6 @@ jpeg_load (f, img)
6887 TIFF 7942 TIFF
6888 ***********************************************************************/ 7943 ***********************************************************************/
6889 7944
6890#if HAVE_TIFF
6891
6892#include <tiffio.h>
6893
6894static int tiff_image_p P_ ((Lisp_Object object)); 7945static int tiff_image_p P_ ((Lisp_Object object));
6895static int tiff_load P_ ((struct frame *f, struct image *img)); 7946static int tiff_load P_ ((struct frame *f, struct image *img));
6896 7947
@@ -6910,6 +7961,8 @@ enum tiff_keyword_index
6910 TIFF_RELIEF, 7961 TIFF_RELIEF,
6911 TIFF_ALGORITHM, 7962 TIFF_ALGORITHM,
6912 TIFF_HEURISTIC_MASK, 7963 TIFF_HEURISTIC_MASK,
7964 TIFF_MASK,
7965 TIFF_BACKGROUND,
6913 TIFF_LAST 7966 TIFF_LAST
6914}; 7967};
6915 7968
@@ -6921,11 +7974,13 @@ static struct image_keyword tiff_format[TIFF_LAST] =
6921 {":type", IMAGE_SYMBOL_VALUE, 1}, 7974 {":type", IMAGE_SYMBOL_VALUE, 1},
6922 {":data", IMAGE_STRING_VALUE, 0}, 7975 {":data", IMAGE_STRING_VALUE, 0},
6923 {":file", IMAGE_STRING_VALUE, 0}, 7976 {":file", IMAGE_STRING_VALUE, 0},
6924 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 7977 {":ascent", IMAGE_ASCENT_VALUE, 0},
6925 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 7978 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
6926 {":relief", IMAGE_INTEGER_VALUE, 0}, 7979 {":relief", IMAGE_INTEGER_VALUE, 0},
6927 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7980 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6928 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} 7981 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7982 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7983 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6929}; 7984};
6930 7985
6931/* Structure describing the image type `tiff'. */ 7986/* Structure describing the image type `tiff'. */
@@ -6949,15 +8004,26 @@ tiff_image_p (object)
6949 struct image_keyword fmt[TIFF_LAST]; 8004 struct image_keyword fmt[TIFF_LAST];
6950 bcopy (tiff_format, fmt, sizeof fmt); 8005 bcopy (tiff_format, fmt, sizeof fmt);
6951 8006
6952 if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff) 8007 if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff))
6953 || (fmt[TIFF_ASCENT].count
6954 && XFASTINT (fmt[TIFF_ASCENT].value) > 100))
6955 return 0; 8008 return 0;
6956 8009
6957 /* Must specify either the :data or :file keyword. */ 8010 /* Must specify either the :data or :file keyword. */
6958 return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1; 8011 return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
6959} 8012}
6960 8013
8014#ifndef HAVE_TIFF
8015
8016static int
8017tiff_load (f, img)
8018 struct frame *f;
8019 struct image *img;
8020{
8021 return image_load_quicktime (f, img, kQTFileTypeTIFF);
8022}
8023
8024#else
8025
8026#include <tiffio.h>
6961 8027
6962/* Reading from a memory buffer for TIFF images Based on the PNG 8028/* Reading from a memory buffer for TIFF images Based on the PNG
6963 memory source, but we have to provide a lot of extra functions. 8029 memory source, but we have to provide a lot of extra functions.
@@ -6976,6 +8042,7 @@ typedef struct
6976} 8042}
6977tiff_memory_source; 8043tiff_memory_source;
6978 8044
8045
6979static size_t 8046static size_t
6980tiff_read_from_memory (data, buf, size) 8047tiff_read_from_memory (data, buf, size)
6981 thandle_t data; 8048 thandle_t data;
@@ -6991,6 +8058,7 @@ tiff_read_from_memory (data, buf, size)
6991 return size; 8058 return size;
6992} 8059}
6993 8060
8061
6994static size_t 8062static size_t
6995tiff_write_from_memory (data, buf, size) 8063tiff_write_from_memory (data, buf, size)
6996 thandle_t data; 8064 thandle_t data;
@@ -7000,6 +8068,7 @@ tiff_write_from_memory (data, buf, size)
7000 return (size_t) -1; 8068 return (size_t) -1;
7001} 8069}
7002 8070
8071
7003static toff_t 8072static toff_t
7004tiff_seek_in_memory (data, off, whence) 8073tiff_seek_in_memory (data, off, whence)
7005 thandle_t data; 8074 thandle_t data;
@@ -7023,7 +8092,7 @@ tiff_seek_in_memory (data, off, whence)
7023 idx = src->index + off; 8092 idx = src->index + off;
7024 break; 8093 break;
7025 8094
7026 default: /* Invalid `whence'. */ 8095 default: /* Invalid `whence'. */
7027 return -1; 8096 return -1;
7028 } 8097 }
7029 8098
@@ -7034,6 +8103,7 @@ tiff_seek_in_memory (data, off, whence)
7034 return src->index; 8103 return src->index;
7035} 8104}
7036 8105
8106
7037static int 8107static int
7038tiff_close_memory (data) 8108tiff_close_memory (data)
7039 thandle_t data; 8109 thandle_t data;
@@ -7042,6 +8112,7 @@ tiff_close_memory (data)
7042 return 0; 8112 return 0;
7043} 8113}
7044 8114
8115
7045static int 8116static int
7046tiff_mmap_memory (data, pbase, psize) 8117tiff_mmap_memory (data, pbase, psize)
7047 thandle_t data; 8118 thandle_t data;
@@ -7052,6 +8123,7 @@ tiff_mmap_memory (data, pbase, psize)
7052 return 0; 8123 return 0;
7053} 8124}
7054 8125
8126
7055static void 8127static void
7056tiff_unmap_memory (data, base, size) 8128tiff_unmap_memory (data, base, size)
7057 thandle_t data; 8129 thandle_t data;
@@ -7061,6 +8133,7 @@ tiff_unmap_memory (data, base, size)
7061 /* We don't need to do this. */ 8133 /* We don't need to do this. */
7062} 8134}
7063 8135
8136
7064static toff_t 8137static toff_t
7065tiff_size_of_memory (data) 8138tiff_size_of_memory (data)
7066 thandle_t data; 8139 thandle_t data;
@@ -7068,6 +8141,35 @@ tiff_size_of_memory (data)
7068 return ((tiff_memory_source *) data)->len; 8141 return ((tiff_memory_source *) data)->len;
7069} 8142}
7070 8143
8144
8145static void
8146tiff_error_handler (title, format, ap)
8147 const char *title, *format;
8148 va_list ap;
8149{
8150 char buf[512];
8151 int len;
8152
8153 len = sprintf (buf, "TIFF error: %s ", title);
8154 vsprintf (buf + len, format, ap);
8155 add_to_log (buf, Qnil, Qnil);
8156}
8157
8158
8159static void
8160tiff_warning_handler (title, format, ap)
8161 const char *title, *format;
8162 va_list ap;
8163{
8164 char buf[512];
8165 int len;
8166
8167 len = sprintf (buf, "TIFF warning: %s ", title);
8168 vsprintf (buf + len, format, ap);
8169 add_to_log (buf, Qnil, Qnil);
8170}
8171
8172
7071/* Load TIFF image IMG for use on frame F. Value is non-zero if 8173/* Load TIFF image IMG for use on frame F. Value is non-zero if
7072 successful. */ 8174 successful. */
7073 8175
@@ -7082,7 +8184,7 @@ tiff_load (f, img)
7082 int width, height, x, y; 8184 int width, height, x, y;
7083 uint32 *buf; 8185 uint32 *buf;
7084 int rc; 8186 int rc;
7085 XImage *ximg; 8187 XImagePtr ximg;
7086 struct gcpro gcpro1; 8188 struct gcpro gcpro1;
7087 tiff_memory_source memsrc; 8189 tiff_memory_source memsrc;
7088 8190
@@ -7091,25 +8193,28 @@ tiff_load (f, img)
7091 file = Qnil; 8193 file = Qnil;
7092 GCPRO1 (file); 8194 GCPRO1 (file);
7093 8195
8196 TIFFSetErrorHandler (tiff_error_handler);
8197 TIFFSetWarningHandler (tiff_warning_handler);
8198
7094 if (NILP (specified_data)) 8199 if (NILP (specified_data))
7095 { 8200 {
7096 /* Read from a file */ 8201 /* Read from a file */
7097 file = x_find_image_file (specified_file); 8202 file = x_find_image_file (specified_file);
7098 if (!STRINGP (file)) 8203 if (!STRINGP (file))
7099 { 8204 {
7100 image_error ("Cannot find image file `%s'", file, Qnil); 8205 image_error ("Cannot find image file `%s'", specified_file, Qnil);
7101 UNGCPRO; 8206 UNGCPRO;
7102 return 0; 8207 return 0;
7103 } 8208 }
7104 8209
7105 /* Try to open the image file. */ 8210 /* Try to open the image file. */
7106 tiff = TIFFOpen (SDATA (file), "r"); 8211 tiff = TIFFOpen (SDATA (file), "r");
7107 if (tiff == NULL) 8212 if (tiff == NULL)
7108 { 8213 {
7109 image_error ("Cannot open `%s'", file, Qnil); 8214 image_error ("Cannot open `%s'", file, Qnil);
7110 UNGCPRO; 8215 UNGCPRO;
7111 return 0; 8216 return 0;
7112 } 8217 }
7113 } 8218 }
7114 else 8219 else
7115 { 8220 {
@@ -7151,19 +8256,18 @@ tiff_load (f, img)
7151 return 0; 8256 return 0;
7152 } 8257 }
7153 8258
7154 BLOCK_INPUT;
7155
7156 /* Create the X image and pixmap. */ 8259 /* Create the X image and pixmap. */
7157 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 8260 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7158 { 8261 {
7159 UNBLOCK_INPUT;
7160 xfree (buf); 8262 xfree (buf);
7161 UNGCPRO; 8263 UNGCPRO;
7162 return 0; 8264 return 0;
7163 } 8265 }
7164 8266
8267#if 0 /* TODO: Color tables. */
7165 /* Initialize the color table. */ 8268 /* Initialize the color table. */
7166 init_color_table (); 8269 init_color_table ();
8270#endif
7167 8271
7168 /* Process the pixel raster. Origin is in the lower-left corner. */ 8272 /* Process the pixel raster. Origin is in the lower-left corner. */
7169 for (y = 0; y < height; ++y) 8273 for (y = 0; y < height; ++y)
@@ -7180,24 +8284,29 @@ tiff_load (f, img)
7180 } 8284 }
7181 } 8285 }
7182 8286
8287#if 0 /* TODO: Color tables. */
7183 /* Remember the colors allocated for the image. Free the color table. */ 8288 /* Remember the colors allocated for the image. Free the color table. */
7184 img->colors = colors_in_color_table (&img->ncolors); 8289 img->colors = colors_in_color_table (&img->ncolors);
7185 free_color_table (); 8290 free_color_table ();
8291#endif
8292
8293 img->width = width;
8294 img->height = height;
8295
8296 /* Maybe fill in the background field while we have ximg handy. */
8297 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
8298 IMAGE_BACKGROUND (img, f, ximg);
7186 8299
7187 /* Put the image into the pixmap, then free the X image and its buffer. */ 8300 /* Put the image into the pixmap, then free the X image and its buffer. */
7188 x_put_x_image (f, ximg, img->pixmap, width, height); 8301 x_put_x_image (f, ximg, img->pixmap, width, height);
7189 x_destroy_x_image (ximg); 8302 x_destroy_x_image (ximg);
7190 xfree (buf); 8303 xfree (buf);
7191 UNBLOCK_INPUT;
7192
7193 img->width = width;
7194 img->height = height;
7195 8304
7196 UNGCPRO; 8305 UNGCPRO;
7197 return 1; 8306 return 1;
7198} 8307}
7199 8308
7200#endif /* HAVE_TIFF != 0 */ 8309#endif /* HAVE_TIFF */
7201 8310
7202 8311
7203 8312
@@ -7205,10 +8314,6 @@ tiff_load (f, img)
7205 GIF 8314 GIF
7206 ***********************************************************************/ 8315 ***********************************************************************/
7207 8316
7208#if HAVE_GIF
7209
7210#include <gif_lib.h>
7211
7212static int gif_image_p P_ ((Lisp_Object object)); 8317static int gif_image_p P_ ((Lisp_Object object));
7213static int gif_load P_ ((struct frame *f, struct image *img)); 8318static int gif_load P_ ((struct frame *f, struct image *img));
7214 8319
@@ -7228,7 +8333,9 @@ enum gif_keyword_index
7228 GIF_RELIEF, 8333 GIF_RELIEF,
7229 GIF_ALGORITHM, 8334 GIF_ALGORITHM,
7230 GIF_HEURISTIC_MASK, 8335 GIF_HEURISTIC_MASK,
8336 GIF_MASK,
7231 GIF_IMAGE, 8337 GIF_IMAGE,
8338 GIF_BACKGROUND,
7232 GIF_LAST 8339 GIF_LAST
7233}; 8340};
7234 8341
@@ -7240,12 +8347,14 @@ static struct image_keyword gif_format[GIF_LAST] =
7240 {":type", IMAGE_SYMBOL_VALUE, 1}, 8347 {":type", IMAGE_SYMBOL_VALUE, 1},
7241 {":data", IMAGE_STRING_VALUE, 0}, 8348 {":data", IMAGE_STRING_VALUE, 0},
7242 {":file", IMAGE_STRING_VALUE, 0}, 8349 {":file", IMAGE_STRING_VALUE, 0},
7243 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 8350 {":ascent", IMAGE_ASCENT_VALUE, 0},
7244 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 8351 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
7245 {":relief", IMAGE_INTEGER_VALUE, 0}, 8352 {":relief", IMAGE_INTEGER_VALUE, 0},
7246 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8353 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7247 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8354 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7248 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0} 8355 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8356 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
8357 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7249}; 8358};
7250 8359
7251/* Structure describing the image type `gif'. */ 8360/* Structure describing the image type `gif'. */
@@ -7259,6 +8368,7 @@ static struct image_type gif_type =
7259 NULL 8368 NULL
7260}; 8369};
7261 8370
8371
7262/* Return non-zero if OBJECT is a valid GIF image specification. */ 8372/* Return non-zero if OBJECT is a valid GIF image specification. */
7263 8373
7264static int 8374static int
@@ -7268,15 +8378,200 @@ gif_image_p (object)
7268 struct image_keyword fmt[GIF_LAST]; 8378 struct image_keyword fmt[GIF_LAST];
7269 bcopy (gif_format, fmt, sizeof fmt); 8379 bcopy (gif_format, fmt, sizeof fmt);
7270 8380
7271 if (!parse_image_spec (object, fmt, GIF_LAST, Qgif) 8381 if (!parse_image_spec (object, fmt, GIF_LAST, Qgif))
7272 || (fmt[GIF_ASCENT].count
7273 && XFASTINT (fmt[GIF_ASCENT].value) > 100))
7274 return 0; 8382 return 0;
7275 8383
7276 /* Must specify either the :data or :file keyword. */ 8384 /* Must specify either the :data or :file keyword. */
7277 return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1; 8385 return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
7278} 8386}
7279 8387
8388#ifndef HAVE_GIF
8389
8390static int
8391gif_load (f, img)
8392 struct frame *f;
8393 struct image *img;
8394{
8395 Lisp_Object specified_file, file;
8396 Lisp_Object specified_data;
8397 OSErr err;
8398 Boolean graphic_p, movie_p, prefer_graphic_p;
8399 Handle dh = NULL;
8400 Movie movie = NULL;
8401 Lisp_Object image;
8402 Track track = NULL;
8403 Media media = NULL;
8404 long nsamples;
8405 Rect rect;
8406 Lisp_Object specified_bg;
8407 XColor color;
8408 RGBColor bg_color;
8409 int width, height;
8410 XImagePtr ximg;
8411 TimeValue time;
8412 struct gcpro gcpro1;
8413 int ino;
8414
8415 specified_file = image_spec_value (img->spec, QCfile, NULL);
8416 specified_data = image_spec_value (img->spec, QCdata, NULL);
8417
8418 if (NILP (specified_data))
8419 {
8420 /* Read from a file */
8421 FSSpec fss;
8422 short refnum;
8423
8424 err = find_image_fsspec (specified_file, &file, &fss);
8425 if (err != noErr)
8426 {
8427 if (err == fnfErr)
8428 image_error ("Cannot find image file `%s'", specified_file, Qnil);
8429 else
8430 goto open_error;
8431 }
8432
8433 err = CanQuickTimeOpenFile (&fss, kQTFileTypeGIF, 0,
8434 &graphic_p, &movie_p, &prefer_graphic_p, 0);
8435 if (err != noErr)
8436 goto open_error;
8437
8438 if (!graphic_p && !movie_p)
8439 goto open_error;
8440 if (prefer_graphic_p)
8441 return image_load_qt_1 (f, img, kQTFileTypeGIF, &fss, NULL);
8442 err = OpenMovieFile (&fss, &refnum, fsRdPerm);
8443 if (err != noErr)
8444 goto open_error;
8445 err = NewMovieFromFile (&movie, refnum, NULL, NULL, 0, NULL);
8446 CloseMovieFile (refnum);
8447 if (err != noErr)
8448 {
8449 image_error ("Error reading `%s'", file, Qnil);
8450 return 0;
8451 }
8452 }
8453 else
8454 {
8455 /* Memory source! */
8456 Handle dref = NULL;
8457 long file_type_atom[3];
8458
8459 err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data));
8460 if (err != noErr)
8461 {
8462 image_error ("Cannot allocate data handle for `%s'",
8463 img->spec, Qnil);
8464 goto error;
8465 }
8466
8467 file_type_atom[0] = EndianU32_NtoB (sizeof (long) * 3);
8468 file_type_atom[1] = EndianU32_NtoB (kDataRefExtensionMacOSFileType);
8469 file_type_atom[2] = EndianU32_NtoB (kQTFileTypeGIF);
8470 err = PtrToHand (&dh, &dref, sizeof (Handle));
8471 if (err == noErr)
8472 /* no file name */
8473 err = PtrAndHand ("\p", dref, 1);
8474 if (err == noErr)
8475 err = PtrAndHand (file_type_atom, dref, sizeof (long) * 3);
8476 if (err != noErr)
8477 {
8478 image_error ("Cannot allocate handle data ref for `%s'", img->spec, Qnil);
8479 goto error;
8480 }
8481 err = CanQuickTimeOpenDataRef (dref, HandleDataHandlerSubType, &graphic_p,
8482 &movie_p, &prefer_graphic_p, 0);
8483 if (err != noErr)
8484 goto open_error;
8485
8486 if (!graphic_p && !movie_p)
8487 goto open_error;
8488 if (prefer_graphic_p)
8489 {
8490 int success_p;
8491
8492 DisposeHandle (dref);
8493 success_p = image_load_qt_1 (f, img, kQTFileTypeGIF, NULL, dh);
8494 DisposeHandle (dh);
8495 return success_p;
8496 }
8497 err = NewMovieFromDataRef (&movie, 0, NULL, dref,
8498 HandleDataHandlerSubType);
8499 DisposeHandle (dref);
8500 if (err != noErr)
8501 goto open_error;
8502 }
8503
8504 image = image_spec_value (img->spec, QCindex, NULL);
8505 ino = INTEGERP (image) ? XFASTINT (image) : 0;
8506 track = GetMovieIndTrack (movie, 1);
8507 media = GetTrackMedia (track);
8508 nsamples = GetMediaSampleCount (media);
8509 if (ino >= nsamples)
8510 {
8511 image_error ("Invalid image number `%s' in image `%s'",
8512 image, img->spec);
8513 goto error;
8514 }
8515
8516 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
8517 if (!STRINGP (specified_bg) ||
8518 !mac_defined_color (f, SDATA (specified_bg), &color, 0))
8519 {
8520 color.pixel = FRAME_BACKGROUND_PIXEL (f);
8521 color.red = RED16_FROM_ULONG (color.pixel);
8522 color.green = GREEN16_FROM_ULONG (color.pixel);
8523 color.blue = BLUE16_FROM_ULONG (color.pixel);
8524 }
8525 GetMovieBox (movie, &rect);
8526 width = img->width = rect.right - rect.left;
8527 height = img->height = rect.bottom - rect.top;
8528 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
8529 goto error;
8530
8531 SetGWorld (ximg, NULL);
8532 bg_color.red = color.red;
8533 bg_color.green = color.green;
8534 bg_color.blue = color.blue;
8535 RGBBackColor (&bg_color);
8536 SetMovieActive (movie, TRUE);
8537 SetMovieGWorld (movie, ximg, NULL);
8538 SampleNumToMediaTime (media, ino + 1, &time, NULL);
8539 SetMovieTimeValue (movie, time);
8540 MoviesTask (movie, 0L);
8541 DisposeTrackMedia (media);
8542 DisposeMovieTrack (track);
8543 DisposeMovie (movie);
8544 if (dh)
8545 DisposeHandle (dh);
8546 /* Maybe fill in the background field while we have ximg handy. */
8547 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
8548 IMAGE_BACKGROUND (img, f, ximg);
8549
8550 /* Put the image into the pixmap. */
8551 x_put_x_image (f, ximg, img->pixmap, width, height);
8552 x_destroy_x_image (ximg);
8553 return 1;
8554
8555 open_error:
8556 image_error ("Cannot open `%s'", file, Qnil);
8557 error:
8558 if (media)
8559 DisposeTrackMedia (media);
8560 if (track)
8561 DisposeMovieTrack (track);
8562 if (movie)
8563 DisposeMovie (movie);
8564 if (dh)
8565 DisposeHandle (dh);
8566 return 0;
8567}
8568
8569#else
8570
8571#define DrawText gif_DrawText /* avoid conflict with QuickdrawText.h */
8572#include <gif_lib.h>
8573#undef DrawText
8574
7280/* Reading a GIF image from memory 8575/* Reading a GIF image from memory
7281 Based on the PNG memory stuff to a certain extent. */ 8576 Based on the PNG memory stuff to a certain extent. */
7282 8577
@@ -7288,6 +8583,7 @@ typedef struct
7288} 8583}
7289gif_memory_source; 8584gif_memory_source;
7290 8585
8586
7291/* Make the current memory source available to gif_read_from_memory. 8587/* Make the current memory source available to gif_read_from_memory.
7292 It's done this way because not all versions of libungif support 8588 It's done this way because not all versions of libungif support
7293 a UserData field in the GifFileType structure. */ 8589 a UserData field in the GifFileType structure. */
@@ -7321,7 +8617,7 @@ gif_load (f, img)
7321 Lisp_Object file, specified_file; 8617 Lisp_Object file, specified_file;
7322 Lisp_Object specified_data; 8618 Lisp_Object specified_data;
7323 int rc, width, height, x, y, i; 8619 int rc, width, height, x, y, i;
7324 XImage *ximg; 8620 XImagePtr ximg;
7325 ColorMapObject *gif_color_map; 8621 ColorMapObject *gif_color_map;
7326 unsigned long pixel_colors[256]; 8622 unsigned long pixel_colors[256];
7327 GifFileType *gif; 8623 GifFileType *gif;
@@ -7340,20 +8636,20 @@ gif_load (f, img)
7340 { 8636 {
7341 file = x_find_image_file (specified_file); 8637 file = x_find_image_file (specified_file);
7342 if (!STRINGP (file)) 8638 if (!STRINGP (file))
7343 { 8639 {
7344 image_error ("Cannot find image file `%s'", specified_file, Qnil); 8640 image_error ("Cannot find image file `%s'", specified_file, Qnil);
7345 UNGCPRO; 8641 UNGCPRO;
7346 return 0; 8642 return 0;
7347 } 8643 }
7348 8644
7349 /* Open the GIF file. */ 8645 /* Open the GIF file. */
7350 gif = DGifOpenFileName (SDATA (file)); 8646 gif = DGifOpenFileName (SDATA (file));
7351 if (gif == NULL) 8647 if (gif == NULL)
7352 { 8648 {
7353 image_error ("Cannot open `%s'", file, Qnil); 8649 image_error ("Cannot open `%s'", file, Qnil);
7354 UNGCPRO; 8650 UNGCPRO;
7355 return 0; 8651 return 0;
7356 } 8652 }
7357 } 8653 }
7358 else 8654 else
7359 { 8655 {
@@ -7363,7 +8659,7 @@ gif_load (f, img)
7363 memsrc.len = SBYTES (specified_data); 8659 memsrc.len = SBYTES (specified_data);
7364 memsrc.index = 0; 8660 memsrc.index = 0;
7365 8661
7366 gif = DGifOpen(&memsrc, gif_read_from_memory); 8662 gif = DGifOpen (&memsrc, gif_read_from_memory);
7367 if (!gif) 8663 if (!gif)
7368 { 8664 {
7369 image_error ("Cannot open memory source `%s'", img->spec, Qnil); 8665 image_error ("Cannot open memory source `%s'", img->spec, Qnil);
@@ -7387,21 +8683,18 @@ gif_load (f, img)
7387 if (ino >= gif->ImageCount) 8683 if (ino >= gif->ImageCount)
7388 { 8684 {
7389 image_error ("Invalid image number `%s' in image `%s'", 8685 image_error ("Invalid image number `%s' in image `%s'",
7390 image, img->spec); 8686 image, img->spec);
7391 DGifCloseFile (gif); 8687 DGifCloseFile (gif);
7392 UNGCPRO; 8688 UNGCPRO;
7393 return 0; 8689 return 0;
7394 } 8690 }
7395 8691
7396 width = img->width = gif->SWidth; 8692 width = img->width = max (gif->SWidth, gif->Image.Left + gif->Image.Width);
7397 height = img->height = gif->SHeight; 8693 height = img->height = max (gif->SHeight, gif->Image.Top + gif->Image.Height);
7398
7399 BLOCK_INPUT;
7400 8694
7401 /* Create the X image and pixmap. */ 8695 /* Create the X image and pixmap. */
7402 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 8696 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7403 { 8697 {
7404 UNBLOCK_INPUT;
7405 DGifCloseFile (gif); 8698 DGifCloseFile (gif);
7406 UNGCPRO; 8699 UNGCPRO;
7407 return 0; 8700 return 0;
@@ -7411,7 +8704,9 @@ gif_load (f, img)
7411 gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap; 8704 gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap;
7412 if (!gif_color_map) 8705 if (!gif_color_map)
7413 gif_color_map = gif->SColorMap; 8706 gif_color_map = gif->SColorMap;
8707#if 0 /* TODO: Color tables */
7414 init_color_table (); 8708 init_color_table ();
8709#endif
7415 bzero (pixel_colors, sizeof pixel_colors); 8710 bzero (pixel_colors, sizeof pixel_colors);
7416 8711
7417 for (i = 0; i < gif_color_map->ColorCount; ++i) 8712 for (i = 0; i < gif_color_map->ColorCount; ++i)
@@ -7422,8 +8717,10 @@ gif_load (f, img)
7422 pixel_colors[i] = lookup_rgb_color (f, r, g, b); 8717 pixel_colors[i] = lookup_rgb_color (f, r, g, b);
7423 } 8718 }
7424 8719
8720#if 0 /* TODO: Color tables */
7425 img->colors = colors_in_color_table (&img->ncolors); 8721 img->colors = colors_in_color_table (&img->ncolors);
7426 free_color_table (); 8722 free_color_table ();
8723#endif
7427 8724
7428 /* Clear the part of the screen image that are not covered by 8725 /* Clear the part of the screen image that are not covered by
7429 the image from the GIF file. Full animated GIF support 8726 the image from the GIF file. Full animated GIF support
@@ -7460,7 +8757,7 @@ gif_load (f, img)
7460 { 8757 {
7461 static int interlace_start[] = {0, 4, 2, 1}; 8758 static int interlace_start[] = {0, 4, 2, 1};
7462 static int interlace_increment[] = {8, 8, 4, 2}; 8759 static int interlace_increment[] = {8, 8, 4, 2};
7463 int pass, inc; 8760 int pass;
7464 int row = interlace_start[0]; 8761 int row = interlace_start[0];
7465 8762
7466 pass = 0; 8763 pass = 0;
@@ -7489,23 +8786,25 @@ gif_load (f, img)
7489 for (y = 0; y < image_height; ++y) 8786 for (y = 0; y < image_height; ++y)
7490 for (x = 0; x < image_width; ++x) 8787 for (x = 0; x < image_width; ++x)
7491 { 8788 {
7492 int i = raster[y* image_width + x]; 8789 int i = raster[y * image_width + x];
7493 XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]); 8790 XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]);
7494 } 8791 }
7495 } 8792 }
7496 8793
7497 DGifCloseFile (gif); 8794 DGifCloseFile (gif);
7498 8795
8796 /* Maybe fill in the background field while we have ximg handy. */
8797 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
8798 IMAGE_BACKGROUND (img, f, ximg);
8799
7499 /* Put the image into the pixmap, then free the X image and its buffer. */ 8800 /* Put the image into the pixmap, then free the X image and its buffer. */
7500 x_put_x_image (f, ximg, img->pixmap, width, height); 8801 x_put_x_image (f, ximg, img->pixmap, width, height);
7501 x_destroy_x_image (ximg); 8802 x_destroy_x_image (ximg);
7502 UNBLOCK_INPUT;
7503 8803
7504 UNGCPRO; 8804 UNGCPRO;
7505 return 1; 8805 return 1;
7506} 8806}
7507 8807#endif /* HAVE_GIF */
7508#endif /* HAVE_GIF != 0 */
7509 8808
7510 8809
7511 8810
@@ -7513,11 +8812,6 @@ gif_load (f, img)
7513 Ghostscript 8812 Ghostscript
7514 ***********************************************************************/ 8813 ***********************************************************************/
7515 8814
7516#ifdef HAVE_GHOSTSCRIPT
7517static int gs_image_p P_ ((Lisp_Object object));
7518static int gs_load P_ ((struct frame *f, struct image *img));
7519static void gs_clear_image P_ ((struct frame *f, struct image *img));
7520
7521/* The symbol `postscript' identifying images of this type. */ 8815/* The symbol `postscript' identifying images of this type. */
7522 8816
7523Lisp_Object Qpostscript; 8817Lisp_Object Qpostscript;
@@ -7526,6 +8820,11 @@ Lisp_Object Qpostscript;
7526 8820
7527Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height; 8821Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height;
7528 8822
8823#ifdef HAVE_GHOSTSCRIPT
8824static int gs_image_p P_ ((Lisp_Object object));
8825static int gs_load P_ ((struct frame *f, struct image *img));
8826static void gs_clear_image P_ ((struct frame *f, struct image *img));
8827
7529/* Indices of image specification fields in gs_format, below. */ 8828/* Indices of image specification fields in gs_format, below. */
7530 8829
7531enum gs_keyword_index 8830enum gs_keyword_index
@@ -7541,6 +8840,8 @@ enum gs_keyword_index
7541 GS_RELIEF, 8840 GS_RELIEF,
7542 GS_ALGORITHM, 8841 GS_ALGORITHM,
7543 GS_HEURISTIC_MASK, 8842 GS_HEURISTIC_MASK,
8843 GS_MASK,
8844 GS_BACKGROUND,
7544 GS_LAST 8845 GS_LAST
7545}; 8846};
7546 8847
@@ -7555,11 +8856,13 @@ static struct image_keyword gs_format[GS_LAST] =
7555 {":file", IMAGE_STRING_VALUE, 1}, 8856 {":file", IMAGE_STRING_VALUE, 1},
7556 {":loader", IMAGE_FUNCTION_VALUE, 0}, 8857 {":loader", IMAGE_FUNCTION_VALUE, 0},
7557 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1}, 8858 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
7558 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 8859 {":ascent", IMAGE_ASCENT_VALUE, 0},
7559 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 8860 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
7560 {":relief", IMAGE_INTEGER_VALUE, 0}, 8861 {":relief", IMAGE_INTEGER_VALUE, 0},
7561 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8862 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7562 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} 8863 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8864 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8865 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7563}; 8866};
7564 8867
7565/* Structure describing the image type `ghostscript'. */ 8868/* Structure describing the image type `ghostscript'. */
@@ -7600,9 +8903,7 @@ gs_image_p (object)
7600 8903
7601 bcopy (gs_format, fmt, sizeof fmt); 8904 bcopy (gs_format, fmt, sizeof fmt);
7602 8905
7603 if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript) 8906 if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript))
7604 || (fmt[GS_ASCENT].count
7605 && XFASTINT (fmt[GS_ASCENT].value) > 100))
7606 return 0; 8907 return 0;
7607 8908
7608 /* Bounding box must be a list or vector containing 4 integers. */ 8909 /* Bounding box must be a list or vector containing 4 integers. */
@@ -7651,18 +8952,16 @@ gs_load (f, img)
7651 info. */ 8952 info. */
7652 pt_width = image_spec_value (img->spec, QCpt_width, NULL); 8953 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
7653 in_width = XFASTINT (pt_width) / 72.0; 8954 in_width = XFASTINT (pt_width) / 72.0;
7654 img->width = in_width * FRAME_W32_DISPLAY_INFO (f)->resx; 8955 img->width = in_width * FRAME_MAC_DISPLAY_INFO (f)->resx;
7655 pt_height = image_spec_value (img->spec, QCpt_height, NULL); 8956 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
7656 in_height = XFASTINT (pt_height) / 72.0; 8957 in_height = XFASTINT (pt_height) / 72.0;
7657 img->height = in_height * FRAME_W32_DISPLAY_INFO (f)->resy; 8958 img->height = in_height * FRAME_MAC_DISPLAY_INFO (f)->resy;
7658 8959
7659 /* Create the pixmap. */ 8960 /* Create the pixmap. */
7660 BLOCK_INPUT; 8961 xassert (img->pixmap == NULL);
7661 xassert (img->pixmap == 0); 8962 img->pixmap = XCreatePixmap (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
7662 img->pixmap = XCreatePixmap (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
7663 img->width, img->height, 8963 img->width, img->height,
7664 DefaultDepthOfScreen (FRAME_X_SCREEN (f))); 8964 one_mac_display_info.n_planes);
7665 UNBLOCK_INPUT;
7666 8965
7667 if (!img->pixmap) 8966 if (!img->pixmap)
7668 { 8967 {
@@ -7677,7 +8976,7 @@ gs_load (f, img)
7677 GCPRO2 (window_and_pixmap_id, pixel_colors); 8976 GCPRO2 (window_and_pixmap_id, pixel_colors);
7678 8977
7679 sprintf (buffer, "%lu %lu", 8978 sprintf (buffer, "%lu %lu",
7680 (unsigned long) FRAME_W32_WINDOW (f), 8979 (unsigned long) FRAME_MAC_WINDOW (f),
7681 (unsigned long) img->pixmap); 8980 (unsigned long) img->pixmap);
7682 window_and_pixmap_id = build_string (buffer); 8981 window_and_pixmap_id = build_string (buffer);
7683 8982
@@ -7719,26 +9018,31 @@ x_kill_gs_process (pixmap, f)
7719 if (c->images[i]->pixmap == pixmap) 9018 if (c->images[i]->pixmap == pixmap)
7720 break; 9019 break;
7721 9020
9021 /* Should someone in between have cleared the image cache, for
9022 instance, give up. */
9023 if (i == c->used)
9024 return;
9025
7722 /* Kill the GS process. We should have found PIXMAP in the image 9026 /* Kill the GS process. We should have found PIXMAP in the image
7723 cache and its image should contain a process object. */ 9027 cache and its image should contain a process object. */
7724 xassert (i < c->used);
7725 img = c->images[i]; 9028 img = c->images[i];
7726 xassert (PROCESSP (img->data.lisp_val)); 9029 xassert (PROCESSP (img->data.lisp_val));
7727 Fkill_process (img->data.lisp_val, Qnil); 9030 Fkill_process (img->data.lisp_val, Qnil);
7728 img->data.lisp_val = Qnil; 9031 img->data.lisp_val = Qnil;
7729 9032
9033#if 0
7730 /* On displays with a mutable colormap, figure out the colors 9034 /* On displays with a mutable colormap, figure out the colors
7731 allocated for the image by looking at the pixels of an XImage for 9035 allocated for the image by looking at the pixels of an XImage for
7732 img->pixmap. */ 9036 img->pixmap. */
7733 class = FRAME_W32_DISPLAY_INFO (f)->visual->class; 9037 class = FRAME_MAC_DISPLAY_INFO (f)->visual->class;
7734 if (class != StaticColor && class != StaticGray && class != TrueColor) 9038 if (class != StaticColor && class != StaticGray && class != TrueColor)
7735 { 9039 {
7736 XImage *ximg; 9040 XImagePtr ximg;
7737 9041
7738 BLOCK_INPUT; 9042 BLOCK_INPUT;
7739 9043
7740 /* Try to get an XImage for img->pixmep. */ 9044 /* Try to get an XImage for img->pixmep. */
7741 ximg = XGetImage (FRAME_W32_DISPLAY (f), img->pixmap, 9045 ximg = XGetImage (FRAME_MAC_DISPLAY (f), img->pixmap,
7742 0, 0, img->width, img->height, ~0, ZPixmap); 9046 0, 0, img->width, img->height, ~0, ZPixmap);
7743 if (ximg) 9047 if (ximg)
7744 { 9048 {
@@ -7769,11 +9073,7 @@ x_kill_gs_process (pixmap, f)
7769 allocated colors on behalf of us. So, to get the 9073 allocated colors on behalf of us. So, to get the
7770 reference counts right, free them once. */ 9074 reference counts right, free them once. */
7771 if (img->ncolors) 9075 if (img->ncolors)
7772 { 9076 x_free_colors (f, img->colors, img->ncolors);
7773 Colormap cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
7774 XFreeColors (FRAME_W32_DISPLAY (f), cmap,
7775 img->colors, img->ncolors, 0);
7776 }
7777#endif 9077#endif
7778 } 9078 }
7779 else 9079 else
@@ -7782,6 +9082,13 @@ x_kill_gs_process (pixmap, f)
7782 9082
7783 UNBLOCK_INPUT; 9083 UNBLOCK_INPUT;
7784 } 9084 }
9085#endif
9086
9087 /* Now that we have the pixmap, compute mask and transform the
9088 image if requested. */
9089 BLOCK_INPUT;
9090 postprocess_image (f, img);
9091 UNBLOCK_INPUT;
7785} 9092}
7786 9093
7787#endif /* HAVE_GHOSTSCRIPT */ 9094#endif /* HAVE_GHOSTSCRIPT */
@@ -8806,6 +10113,18 @@ syms_of_macfns ()
8806 10113
8807 Qlaplace = intern ("laplace"); 10114 Qlaplace = intern ("laplace");
8808 staticpro (&Qlaplace); 10115 staticpro (&Qlaplace);
10116 Qemboss = intern ("emboss");
10117 staticpro (&Qemboss);
10118 Qedge_detection = intern ("edge-detection");
10119 staticpro (&Qedge_detection);
10120 Qheuristic = intern ("heuristic");
10121 staticpro (&Qheuristic);
10122 QCmatrix = intern (":matrix");
10123 staticpro (&QCmatrix);
10124 QCcolor_adjustment = intern (":color-adjustment");
10125 staticpro (&QCcolor_adjustment);
10126 QCmask = intern (":mask");
10127 staticpro (&QCmask);
8809 10128
8810 Qface_set_after_frame_default = intern ("face-set-after-frame-default"); 10129 Qface_set_after_frame_default = intern ("face-set-after-frame-default");
8811 staticpro (&Qface_set_after_frame_default); 10130 staticpro (&Qface_set_after_frame_default);
@@ -8815,6 +10134,12 @@ syms_of_macfns ()
8815 Fput (Qundefined_color, Qerror_message, 10134 Fput (Qundefined_color, Qerror_message,
8816 build_string ("Undefined color")); 10135 build_string ("Undefined color"));
8817 10136
10137 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images,
10138 doc: /* Non-nil means always draw a cross over disabled images.
10139Disabled images are those having an `:conversion disabled' property.
10140A cross is always drawn on black & white displays. */);
10141 cross_disabled_images = 0;
10142
8818 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, 10143 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
8819 doc: /* List of directories to search for window system bitmap files. */); 10144 doc: /* List of directories to search for window system bitmap files. */);
8820 Vx_bitmap_file_path = decode_env_path ((char *) 0, "PATH"); 10145 Vx_bitmap_file_path = decode_env_path ((char *) 0, "PATH");
@@ -8880,9 +10205,11 @@ from the image cache. Value must be an integer or nil with nil
8880meaning don't clear the cache. */); 10205meaning don't clear the cache. */);
8881 Vimage_cache_eviction_delay = make_number (30 * 60); 10206 Vimage_cache_eviction_delay = make_number (30 * 60);
8882 10207
10208 /* X window properties. */
8883 defsubr (&Sx_change_window_property); 10209 defsubr (&Sx_change_window_property);
8884 defsubr (&Sx_delete_window_property); 10210 defsubr (&Sx_delete_window_property);
8885 defsubr (&Sx_window_property); 10211 defsubr (&Sx_window_property);
10212
8886 defsubr (&Sxw_display_color_p); 10213 defsubr (&Sxw_display_color_p);
8887 defsubr (&Sx_display_grayscale_p); 10214 defsubr (&Sx_display_grayscale_p);
8888 defsubr (&Sxw_color_defined_p); 10215 defsubr (&Sxw_color_defined_p);
@@ -8919,15 +10246,12 @@ meaning don't clear the cache. */);
8919 load_font_func = x_load_font; 10246 load_font_func = x_load_font;
8920 find_ccl_program_func = x_find_ccl_program; 10247 find_ccl_program_func = x_find_ccl_program;
8921 query_font_func = x_query_font; 10248 query_font_func = x_query_font;
8922
8923 set_frame_fontset_func = x_set_font; 10249 set_frame_fontset_func = x_set_font;
8924 check_window_system_func = check_mac; 10250 check_window_system_func = check_mac;
8925 10251
8926#if 0 /* MAC_TODO: Image support for Mac Images. */ 10252 /* Images. */
8927 Qxbm = intern ("xbm"); 10253 Qxbm = intern ("xbm");
8928 staticpro (&Qxbm); 10254 staticpro (&Qxbm);
8929 QCtype = intern (":type");
8930 staticpro (&QCtype);
8931 QCconversion = intern (":conversion"); 10255 QCconversion = intern (":conversion");
8932 staticpro (&QCconversion); 10256 staticpro (&QCconversion);
8933 QCheuristic_mask = intern (":heuristic-mask"); 10257 QCheuristic_mask = intern (":heuristic-mask");
@@ -8960,41 +10284,36 @@ meaning don't clear the cache. */);
8960 staticpro (&Qxpm); 10284 staticpro (&Qxpm);
8961#endif 10285#endif
8962 10286
8963#if HAVE_JPEG
8964 Qjpeg = intern ("jpeg"); 10287 Qjpeg = intern ("jpeg");
8965 staticpro (&Qjpeg); 10288 staticpro (&Qjpeg);
8966#endif
8967 10289
8968#if HAVE_TIFF
8969 Qtiff = intern ("tiff"); 10290 Qtiff = intern ("tiff");
8970 staticpro (&Qtiff); 10291 staticpro (&Qtiff);
8971#endif
8972 10292
8973#if HAVE_GIF
8974 Qgif = intern ("gif"); 10293 Qgif = intern ("gif");
8975 staticpro (&Qgif); 10294 staticpro (&Qgif);
8976#endif
8977 10295
8978#if HAVE_PNG
8979 Qpng = intern ("png"); 10296 Qpng = intern ("png");
8980 staticpro (&Qpng); 10297 staticpro (&Qpng);
8981#endif
8982 10298
8983 defsubr (&Sclear_image_cache); 10299 defsubr (&Sclear_image_cache);
10300 defsubr (&Simage_size);
10301 defsubr (&Simage_mask_p);
8984 10302
8985#if GLYPH_DEBUG 10303#if GLYPH_DEBUG
8986 defsubr (&Simagep); 10304 defsubr (&Simagep);
8987 defsubr (&Slookup_image); 10305 defsubr (&Slookup_image);
8988#endif 10306#endif
8989#endif /* MAC_TODO */
8990 10307
8991 hourglass_atimer = NULL; 10308 hourglass_atimer = NULL;
8992 hourglass_shown_p = 0; 10309 hourglass_shown_p = 0;
8993 10310
8994 defsubr (&Sx_show_tip); 10311 defsubr (&Sx_show_tip);
8995 defsubr (&Sx_hide_tip); 10312 defsubr (&Sx_hide_tip);
8996 staticpro (&tip_timer);
8997 tip_timer = Qnil; 10313 tip_timer = Qnil;
10314 staticpro (&tip_timer);
10315 tip_frame = Qnil;
10316 staticpro (&tip_frame);
8998 10317
8999#if 0 /* MAC_TODO */ 10318#if 0 /* MAC_TODO */
9000 defsubr (&Sx_file_dialog); 10319 defsubr (&Sx_file_dialog);
@@ -9009,30 +10328,26 @@ init_xfns ()
9009 Vimage_types = Qnil; 10328 Vimage_types = Qnil;
9010 10329
9011 define_image_type (&xbm_type); 10330 define_image_type (&xbm_type);
9012#if 0 /* NTEMACS_TODO : Image support for W32 */ 10331#if HAVE_GHOSTSCRIPT
9013 define_image_type (&gs_type); 10332 define_image_type (&gs_type);
10333#endif
9014 define_image_type (&pbm_type); 10334 define_image_type (&pbm_type);
9015 10335
9016#if HAVE_XPM 10336#if HAVE_XPM
9017 define_image_type (&xpm_type); 10337 define_image_type (&xpm_type);
9018#endif 10338#endif
9019 10339
9020#if HAVE_JPEG
9021 define_image_type (&jpeg_type); 10340 define_image_type (&jpeg_type);
9022#endif
9023
9024#if HAVE_TIFF
9025 define_image_type (&tiff_type); 10341 define_image_type (&tiff_type);
9026#endif
9027
9028#if HAVE_GIF
9029 define_image_type (&gif_type); 10342 define_image_type (&gif_type);
9030#endif
9031
9032#if HAVE_PNG
9033 define_image_type (&png_type); 10343 define_image_type (&png_type);
10344
10345 /* Animated gifs use QuickTime Movie Toolbox. So initialize it
10346 here. */
10347 EnterMovies ();
10348#ifdef MAC_OSX
10349 init_image_func_pointer ();
9034#endif 10350#endif
9035#endif /* NTEMACS_TODO */
9036} 10351}
9037 10352
9038/* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc 10353/* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc
diff --git a/src/macgui.h b/src/macgui.h
index 34f5913d5df..2bb346e9d30 100644
--- a/src/macgui.h
+++ b/src/macgui.h
@@ -23,9 +23,6 @@ Boston, MA 02111-1307, USA. */
23#ifndef EMACS_MACGUI_H 23#ifndef EMACS_MACGUI_H
24#define EMACS_MACGUI_H 24#define EMACS_MACGUI_H
25 25
26typedef int Pixmap;
27typedef int Bitmap;
28
29typedef int Display; /* fix later */ 26typedef int Display; /* fix later */
30 27
31typedef char * XrmDatabase; /* fix later */ 28typedef char * XrmDatabase; /* fix later */
@@ -33,12 +30,43 @@ typedef char * XrmDatabase; /* fix later */
33typedef unsigned long Time; 30typedef unsigned long Time;
34 31
35#if MAC_OSX 32#if MAC_OSX
33#undef mktime
34#undef DEBUG
35#undef Z
36#undef free
37#undef malloc
38#undef realloc
39/* Macros max and min defined in lisp.h conflict with those in
40 precompiled header Carbon.h. */
41#undef max
42#undef min
43#undef init_process
44#include <Carbon/Carbon.h>
45#undef Z
46#define Z (current_buffer->text->z)
47#undef free
48#define free unexec_free
49#undef malloc
50#define malloc unexec_malloc
51#undef realloc
52#define realloc unexec_realloc
53#undef min
54#define min(a, b) ((a) < (b) ? (a) : (b))
55#undef max
56#define max(a, b) ((a) > (b) ? (a) : (b))
57#undef init_process
58#define init_process emacs_init_process
59#undef INFINITY
36typedef struct OpaqueWindowPtr* Window; 60typedef struct OpaqueWindowPtr* Window;
37#else 61#else
38#include <QuickDraw.h> 62#include <QuickDraw.h> /* for WindowPtr */
63#include <QDOffscreen.h> /* for GWorldPtr */
64#include <Controls.h> /* for ControlHandle in xdisp.c */
39typedef WindowPtr Window; 65typedef WindowPtr Window;
40#endif 66#endif
41 67
68typedef GWorldPtr Pixmap;
69
42#define FACE_DEFAULT (~0) 70#define FACE_DEFAULT (~0)
43 71
44 72
diff --git a/src/macmenu.c b/src/macmenu.c
index 0a6747896b6..06b1b16cf41 100644
--- a/src/macmenu.c
+++ b/src/macmenu.c
@@ -35,34 +35,7 @@ Boston, MA 02111-1307, USA. */
35#include "charset.h" 35#include "charset.h"
36#include "coding.h" 36#include "coding.h"
37 37
38#ifdef MAC_OSX 38#ifndef MAC_OSX
39#undef mktime
40#undef DEBUG
41#undef Z
42#undef free
43#undef malloc
44#undef realloc
45/* Macros max and min defined in lisp.h conflict with those in
46 precompiled header Carbon.h. */
47#undef max
48#undef min
49#undef init_process
50#include <Carbon/Carbon.h>
51#undef Z
52#define Z (current_buffer->text->z)
53#undef free
54#define free unexec_free
55#undef malloc
56#define malloc unexec_malloc
57#undef realloc
58#define realloc unexec_realloc
59#undef min
60#define min(a, b) ((a) < (b) ? (a) : (b))
61#undef max
62#define max(a, b) ((a) > (b) ? (a) : (b))
63#undef init_process
64#define init_process emacs_init_process
65#else /* not MAC_OSX */
66#include <MacTypes.h> 39#include <MacTypes.h>
67#include <Menus.h> 40#include <Menus.h>
68#include <QuickDraw.h> 41#include <QuickDraw.h>
diff --git a/src/macterm.c b/src/macterm.c
index f6e5414c299..a22a1cfafe8 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -35,29 +35,6 @@ Boston, MA 02111-1307, USA. */
35#endif 35#endif
36 36
37#ifdef MAC_OSX 37#ifdef MAC_OSX
38#undef mktime
39#undef DEBUG
40#undef free
41#undef malloc
42#undef realloc
43/* Macros max and min defined in lisp.h conflict with those in
44 precompiled header Carbon.h. */
45#undef max
46#undef min
47#undef init_process
48#include <Carbon/Carbon.h>
49#undef free
50#define free unexec_free
51#undef malloc
52#define malloc unexec_malloc
53#undef realloc
54#define realloc unexec_realloc
55#undef min
56#define min(a, b) ((a) < (b) ? (a) : (b))
57#undef max
58#define max(a, b) ((a) > (b) ? (a) : (b))
59#undef init_process
60#define init_process emacs_init_process
61/* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to 38/* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
62 obtain events from the event queue. If set to 0, WaitNextEvent is 39 obtain events from the event queue. If set to 0, WaitNextEvent is
63 used instead. */ 40 used instead. */
@@ -303,7 +280,9 @@ static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
303static void XTframe_rehighlight P_ ((struct frame *)); 280static void XTframe_rehighlight P_ ((struct frame *));
304static void x_frame_rehighlight P_ ((struct x_display_info *)); 281static void x_frame_rehighlight P_ ((struct x_display_info *));
305static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); 282static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
306static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int)); 283static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
284 enum text_cursor_kinds));
285
307static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC)); 286static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC));
308static void x_flush P_ ((struct frame *f)); 287static void x_flush P_ ((struct frame *f));
309static void x_update_begin P_ ((struct frame *)); 288static void x_update_begin P_ ((struct frame *));
@@ -327,15 +306,12 @@ extern void set_frame_menubar (FRAME_PTR, int, int);
327 306
328/* X display function emulation */ 307/* X display function emulation */
329 308
330static void 309void
331XFreePixmap (display, pixmap) 310XFreePixmap (display, pixmap)
332 Display *display; 311 Display *display; /* not used */
333 Pixmap pixmap; 312 Pixmap pixmap;
334{ 313{
335 PixMap *p = (PixMap *) pixmap; 314 DisposeGWorld (pixmap);
336
337 xfree (p->baseAddr);
338 xfree (p);
339} 315}
340 316
341 317
@@ -347,9 +323,9 @@ mac_set_forecolor (unsigned long color)
347{ 323{
348 RGBColor fg_color; 324 RGBColor fg_color;
349 325
350 fg_color.red = RED_FROM_ULONG (color) * 256; 326 fg_color.red = RED16_FROM_ULONG (color);
351 fg_color.green = GREEN_FROM_ULONG (color) * 256; 327 fg_color.green = GREEN16_FROM_ULONG (color);
352 fg_color.blue = BLUE_FROM_ULONG (color) * 256; 328 fg_color.blue = BLUE16_FROM_ULONG (color);
353 329
354 RGBForeColor (&fg_color); 330 RGBForeColor (&fg_color);
355} 331}
@@ -363,9 +339,9 @@ mac_set_backcolor (unsigned long color)
363{ 339{
364 RGBColor bg_color; 340 RGBColor bg_color;
365 341
366 bg_color.red = RED_FROM_ULONG (color) * 256; 342 bg_color.red = RED16_FROM_ULONG (color);
367 bg_color.green = GREEN_FROM_ULONG (color) * 256; 343 bg_color.green = GREEN16_FROM_ULONG (color);
368 bg_color.blue = BLUE_FROM_ULONG (color) * 256; 344 bg_color.blue = BLUE16_FROM_ULONG (color);
369 345
370 RGBBackColor (&bg_color); 346 RGBBackColor (&bg_color);
371} 347}
@@ -401,6 +377,23 @@ XDrawLine (display, w, gc, x1, y1, x2, y2)
401 LineTo (x2, y2); 377 LineTo (x2, y2);
402} 378}
403 379
380void
381mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2)
382 Display *display;
383 Pixmap p;
384 GC gc;
385 int x1, y1, x2, y2;
386{
387 SetGWorld (p, NULL);
388
389 mac_set_colors (gc);
390
391 LockPixels (GetGWorldPixMap (p));
392 MoveTo (x1, y1);
393 LineTo (x2, y2);
394 UnlockPixels (GetGWorldPixMap (p));
395}
396
404/* Mac version of XClearArea. */ 397/* Mac version of XClearArea. */
405 398
406void 399void
@@ -479,7 +472,7 @@ mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
479 Rect r; 472 Rect r;
480 473
481 bitmap.rowBytes = sizeof(unsigned short); 474 bitmap.rowBytes = sizeof(unsigned short);
482 bitmap.baseAddr = bits; 475 bitmap.baseAddr = (char *)bits;
483 SetRect (&(bitmap.bounds), 0, 0, width, height); 476 SetRect (&(bitmap.bounds), 0, 0, width, height);
484 477
485#if TARGET_API_MAC_CARBON 478#if TARGET_API_MAC_CARBON
@@ -489,18 +482,13 @@ mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
489#endif 482#endif
490 483
491 mac_set_colors (gc); 484 mac_set_colors (gc);
492 SetRect (&r, x, y, x + bitmap.bounds.right, y + bitmap.bounds.bottom); 485 SetRect (&r, x, y, x + width, y + height);
493 486
494#if TARGET_API_MAC_CARBON 487#if TARGET_API_MAC_CARBON
495 { 488 LockPortBits (GetWindowPort (w));
496 PixMapHandle pmh; 489 CopyBits (&bitmap, GetPortBitMapForCopyBits (GetWindowPort (w)),
497 490 &(bitmap.bounds), &r, overlay_p ? srcOr : srcCopy, 0);
498 LockPortBits (GetWindowPort (w)); 491 UnlockPortBits (GetWindowPort (w));
499 pmh = GetPortPixMap (GetWindowPort (w));
500 CopyBits (&bitmap, (BitMap *) *pmh, &(bitmap.bounds), &r,
501 overlay_p ? srcOr : srcCopy, 0);
502 UnlockPortBits (GetWindowPort (w));
503 }
504#else /* not TARGET_API_MAC_CARBON */ 492#else /* not TARGET_API_MAC_CARBON */
505 CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r, 493 CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r,
506 overlay_p ? srcOr : srcCopy, 0); 494 overlay_p ? srcOr : srcCopy, 0);
@@ -546,6 +534,23 @@ mac_reset_clipping (display, w)
546} 534}
547 535
548 536
537/* XBM bits seem to be backward within bytes compared with how
538 Mac does things. */
539static unsigned char
540reflect_byte (orig)
541 unsigned char orig;
542{
543 int i;
544 unsigned char reflected = 0x00;
545 for (i = 0; i < 8; i++)
546 {
547 if (orig & (0x01 << i))
548 reflected |= 0x80 >> i;
549 }
550 return reflected;
551}
552
553
549/* Mac replacement for XCreateBitmapFromBitmapData. */ 554/* Mac replacement for XCreateBitmapFromBitmapData. */
550 555
551static void 556static void
@@ -554,18 +559,19 @@ mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h)
554 char *bits; 559 char *bits;
555 int w, h; 560 int w, h;
556{ 561{
557 int bytes_per_row, i, j; 562 int i, j, w1;
563 char *p;
558 564
559 bitmap->rowBytes = (w + 15) / 16 * 2; /* must be on word boundary */ 565 w1 = (w + 7) / 8; /* nb of 8bits elt in X bitmap */
566 bitmap->rowBytes = ((w + 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
560 bitmap->baseAddr = xmalloc (bitmap->rowBytes * h); 567 bitmap->baseAddr = xmalloc (bitmap->rowBytes * h);
561 if (!bitmap->baseAddr)
562 abort ();
563
564 bzero (bitmap->baseAddr, bitmap->rowBytes * h); 568 bzero (bitmap->baseAddr, bitmap->rowBytes * h);
565 for (i = 0; i < h; i++) 569 for (i = 0; i < h; i++)
566 for (j = 0; j < w; j++) 570 {
567 if (BitTst (bits, i * w + j)) 571 p = bitmap->baseAddr + i * bitmap->rowBytes;
568 BitSet (bitmap->baseAddr, i * bitmap->rowBytes * 8 + j); 572 for (j = 0; j < w1; j++)
573 *p++ = reflect_byte (*bits++);
574 }
569 575
570 SetRect (&(bitmap->bounds), 0, 0, w, h); 576 SetRect (&(bitmap->bounds), 0, 0, w, h);
571} 577}
@@ -578,6 +584,67 @@ mac_free_bitmap (bitmap)
578 xfree (bitmap->baseAddr); 584 xfree (bitmap->baseAddr);
579} 585}
580 586
587
588Pixmap
589XCreatePixmap (display, w, width, height, depth)
590 Display *display; /* not used */
591 WindowPtr w;
592 unsigned int width, height;
593 unsigned int depth; /* not used */
594{
595 Pixmap pixmap;
596 Rect r;
597 QDErr err;
598
599#if TARGET_API_MAC_CARBON
600 SetPort (GetWindowPort (w));
601#else
602 SetPort (w);
603#endif
604
605 SetRect (&r, 0, 0, width, height);
606 err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0);
607 if (err != noErr)
608 return NULL;
609 return pixmap;
610}
611
612
613Pixmap
614XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
615 Display *display; /* not used */
616 WindowPtr w;
617 char *data;
618 unsigned int width, height;
619 unsigned long fg, bg;
620 unsigned int depth; /* not used */
621{
622 Pixmap pixmap;
623 BitMap bitmap;
624
625 pixmap = XCreatePixmap (display, w, width, height, depth);
626 if (pixmap == NULL)
627 return NULL;
628
629 SetGWorld (pixmap, NULL);
630 mac_create_bitmap_from_bitmap_data (&bitmap, data, width, height);
631 mac_set_forecolor (fg);
632 mac_set_backcolor (bg);
633 LockPixels (GetGWorldPixMap (pixmap));
634#if TARGET_API_MAC_CARBON
635 CopyBits (&bitmap, GetPortBitMapForCopyBits (pixmap),
636 &bitmap.bounds, &bitmap.bounds, srcCopy, 0);
637#else /* not TARGET_API_MAC_CARBON */
638 CopyBits (&bitmap, &(((GrafPtr)pixmap)->portBits),
639 &bitmap.bounds, &bitmap.bounds, srcCopy, 0);
640#endif /* not TARGET_API_MAC_CARBON */
641 UnlockPixels (GetGWorldPixMap (pixmap));
642 mac_free_bitmap (&bitmap);
643
644 return pixmap;
645}
646
647
581/* Mac replacement for XFillRectangle. */ 648/* Mac replacement for XFillRectangle. */
582 649
583static void 650static void
@@ -603,6 +670,26 @@ XFillRectangle (display, w, gc, x, y, width, height)
603} 670}
604 671
605 672
673static void
674mac_fill_rectangle_to_pixmap (display, p, gc, x, y, width, height)
675 Display *display;
676 Pixmap p;
677 GC gc;
678 int x, y;
679 unsigned int width, height;
680{
681 Rect r;
682
683 SetGWorld (p, NULL);
684 mac_set_colors (gc);
685 SetRect (&r, x, y, x + width, y + height);
686
687 LockPixels (GetGWorldPixMap (p));
688 PaintRect (&r); /* using foreground color of gc */
689 UnlockPixels (GetGWorldPixMap (p));
690}
691
692
606/* Mac replacement for XDrawRectangle: dest is a window. */ 693/* Mac replacement for XDrawRectangle: dest is a window. */
607 694
608static void 695static void
@@ -638,20 +725,15 @@ mac_draw_rectangle_to_pixmap (display, p, gc, x, y, width, height)
638 int x, y; 725 int x, y;
639 unsigned int width, height; 726 unsigned int width, height;
640{ 727{
641#if 0 /* MAC_TODO: draw a rectangle in a PixMap */
642 Rect r; 728 Rect r;
643 729
644#if TARGET_API_MAC_CARBON 730 SetGWorld (p, NULL);
645 SetPort (GetWindowPort (w));
646#else
647 SetPort (w);
648#endif
649
650 mac_set_colors (gc); 731 mac_set_colors (gc);
651 SetRect (&r, x, y, x + width, y + height); 732 SetRect (&r, x, y, x + width + 1, y + height + 1);
652 733
734 LockPixels (GetGWorldPixMap (p));
653 FrameRect (&r); /* using foreground color of gc */ 735 FrameRect (&r); /* using foreground color of gc */
654#endif /* 0 */ 736 UnlockPixels (GetGWorldPixMap (p));
655} 737}
656 738
657 739
@@ -766,23 +848,66 @@ mac_copy_area (display, src, dest, gc, src_x, src_y, width, height, dest_x,
766 SetPort (dest); 848 SetPort (dest);
767#endif 849#endif
768 850
769 mac_set_colors (gc);
770
771 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); 851 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
772 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); 852 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
773 853
854 ForeColor (blackColor);
855 BackColor (whiteColor);
856
857 LockPixels (GetGWorldPixMap (src));
774#if TARGET_API_MAC_CARBON 858#if TARGET_API_MAC_CARBON
775 { 859 LockPortBits (GetWindowPort (dest));
776 PixMapHandle pmh; 860 CopyBits (GetPortBitMapForCopyBits (src),
861 GetPortBitMapForCopyBits (GetWindowPort (dest)),
862 &src_r, &dest_r, srcCopy, 0);
863 UnlockPortBits (GetWindowPort (dest));
864#else /* not TARGET_API_MAC_CARBON */
865 CopyBits (&(((GrafPtr)src)->portBits), &(dest->portBits),
866 &src_r, &dest_r, srcCopy, 0);
867#endif /* not TARGET_API_MAC_CARBON */
868 UnlockPixels (GetGWorldPixMap (src));
869}
777 870
778 LockPortBits (GetWindowPort (dest)); 871
779 pmh = GetPortPixMap (GetWindowPort (dest)); 872static void
780 CopyBits ((BitMap *) &src, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0); 873mac_copy_area_with_mask (display, src, mask, dest, gc, src_x, src_y,
781 UnlockPortBits (GetWindowPort (dest)); 874 width, height, dest_x, dest_y)
782 } 875 Display *display;
876 Pixmap src, mask;
877 WindowPtr dest;
878 GC gc;
879 int src_x, src_y;
880 unsigned int width, height;
881 int dest_x, dest_y;
882{
883 Rect src_r, dest_r;
884
885#if TARGET_API_MAC_CARBON
886 SetPort (GetWindowPort (dest));
887#else
888 SetPort (dest);
889#endif
890
891 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
892 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
893
894 ForeColor (blackColor);
895 BackColor (whiteColor);
896
897 LockPixels (GetGWorldPixMap (src));
898 LockPixels (GetGWorldPixMap (mask));
899#if TARGET_API_MAC_CARBON
900 LockPortBits (GetWindowPort (dest));
901 CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask),
902 GetPortBitMapForCopyBits (GetWindowPort (dest)),
903 &src_r, &src_r, &dest_r);
904 UnlockPortBits (GetWindowPort (dest));
783#else /* not TARGET_API_MAC_CARBON */ 905#else /* not TARGET_API_MAC_CARBON */
784 CopyBits ((BitMap *) &src, &(dest->portBits), &src_r, &dest_r, srcCopy, 0); 906 CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits),
907 &(dest->portBits), &src_r, &src_r, &dest_r);
785#endif /* not TARGET_API_MAC_CARBON */ 908#endif /* not TARGET_API_MAC_CARBON */
909 UnlockPixels (GetGWorldPixMap (mask));
910 UnlockPixels (GetGWorldPixMap (src));
786} 911}
787 912
788 913
@@ -817,7 +942,6 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y)
817{ 942{
818#if TARGET_API_MAC_CARBON 943#if TARGET_API_MAC_CARBON
819 Rect gw_r, src_r, dest_r; 944 Rect gw_r, src_r, dest_r;
820 PixMapHandle pmh;
821 945
822 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); 946 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
823 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); 947 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
@@ -828,8 +952,10 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y)
828 BackColor (whiteColor); 952 BackColor (whiteColor);
829 953
830 LockPortBits (GetWindowPort (w)); 954 LockPortBits (GetWindowPort (w));
831 pmh = GetPortPixMap (GetWindowPort (w)); 955 {
832 CopyBits ((BitMap *) *pmh, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0); 956 const BitMap *bitmap = GetPortBitMapForCopyBits (GetWindowPort (w));
957 CopyBits (bitmap, bitmap, &src_r, &dest_r, srcCopy, 0);
958 }
833 UnlockPortBits (GetWindowPort (w)); 959 UnlockPortBits (GetWindowPort (w));
834 960
835 mac_set_colors (gc); 961 mac_set_colors (gc);
@@ -872,25 +998,67 @@ static void
872mac_copy_area_to_pixmap (display, src, dest, gc, src_x, src_y, width, height, 998mac_copy_area_to_pixmap (display, src, dest, gc, src_x, src_y, width, height,
873 dest_x, dest_y) 999 dest_x, dest_y)
874 Display *display; 1000 Display *display;
875 Pixmap src; 1001 Pixmap src, dest;
876 Pixmap dest;
877 GC gc; 1002 GC gc;
878 int src_x, src_y; 1003 int src_x, src_y;
879 unsigned int width, height; 1004 unsigned int width, height;
880 int dest_x, dest_y; 1005 int dest_x, dest_y;
881{ 1006{
882 Rect src_r, dest_r; 1007 Rect src_r, dest_r;
883 int src_right = ((PixMap *) src)->bounds.right;
884 int src_bottom = ((PixMap *) src)->bounds.bottom;
885 int w = src_right - src_x;
886 int h = src_bottom - src_y;
887 1008
888 mac_set_colors (gc); 1009 SetGWorld (dest, NULL);
1010 ForeColor (blackColor);
1011 BackColor (whiteColor);
1012
1013 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
1014 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
1015
1016 LockPixels (GetGWorldPixMap (src));
1017 LockPixels (GetGWorldPixMap (dest));
1018#if TARGET_API_MAC_CARBON
1019 CopyBits (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (dest),
1020 &src_r, &dest_r, srcCopy, 0);
1021#else /* not TARGET_API_MAC_CARBON */
1022 CopyBits (&(((GrafPtr)src)->portBits), &(((GrafPtr)dest)->portBits),
1023 &src_r, &dest_r, srcCopy, 0);
1024#endif /* not TARGET_API_MAC_CARBON */
1025 UnlockPixels (GetGWorldPixMap (dest));
1026 UnlockPixels (GetGWorldPixMap (src));
1027}
1028
1029
1030static void
1031mac_copy_area_with_mask_to_pixmap (display, src, mask, dest, gc, src_x, src_y,
1032 width, height, dest_x, dest_y)
1033 Display *display;
1034 Pixmap src, mask, dest;
1035 GC gc;
1036 int src_x, src_y;
1037 unsigned int width, height;
1038 int dest_x, dest_y;
1039{
1040 Rect src_r, dest_r;
1041
1042 SetGWorld (dest, NULL);
1043 ForeColor (blackColor);
1044 BackColor (whiteColor);
889 1045
890 SetRect (&src_r, src_x, src_y, src_right, src_bottom); 1046 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
891 SetRect (&dest_r, dest_x, dest_y, dest_x + w, dest_y + h); 1047 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
892 1048
893 CopyBits ((BitMap *) &src, (BitMap *) &dest, &src_r, &dest_r, srcCopy, 0); 1049 LockPixels (GetGWorldPixMap (src));
1050 LockPixels (GetGWorldPixMap (mask));
1051 LockPixels (GetGWorldPixMap (dest));
1052#if TARGET_API_MAC_CARBON
1053 CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask),
1054 GetPortBitMapForCopyBits (dest), &src_r, &src_r, &dest_r);
1055#else /* not TARGET_API_MAC_CARBON */
1056 CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits),
1057 &(((GrafPtr)dest)->portBits), &src_r, &src_r, &dest_r);
1058#endif /* not TARGET_API_MAC_CARBON */
1059 UnlockPixels (GetGWorldPixMap (dest));
1060 UnlockPixels (GetGWorldPixMap (mask));
1061 UnlockPixels (GetGWorldPixMap (src));
894} 1062}
895 1063
896 1064
@@ -947,7 +1115,7 @@ XGetGCValues (void* ignore, XGCValues *gc,
947 1115
948/* Mac replacement for XSetForeground. */ 1116/* Mac replacement for XSetForeground. */
949 1117
950static void 1118void
951XSetForeground (display, gc, color) 1119XSetForeground (display, gc, color)
952 Display *display; 1120 Display *display;
953 GC gc; 1121 GC gc;
@@ -2139,6 +2307,21 @@ x_copy_dpy_color (dpy, cmap, pixel)
2139 2307
2140#endif /* MAC_TODO */ 2308#endif /* MAC_TODO */
2141 2309
2310
2311/* Brightness beyond which a color won't have its highlight brightness
2312 boosted.
2313
2314 Nominally, highlight colors for `3d' faces are calculated by
2315 brightening an object's color by a constant scale factor, but this
2316 doesn't yield good results for dark colors, so for colors who's
2317 brightness is less than this value (on a scale of 0-255) have to
2318 use an additional additive factor.
2319
2320 The value here is set so that the default menu-bar/mode-line color
2321 (grey75) will not have its highlights changed at all. */
2322#define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
2323
2324
2142/* Allocate a color which is lighter or darker than *COLOR by FACTOR 2325/* Allocate a color which is lighter or darker than *COLOR by FACTOR
2143 or DELTA. Try a color with RGB values multiplied by FACTOR first. 2326 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2144 If this produces the same color as COLOR, try a color where all RGB 2327 If this produces the same color as COLOR, try a color where all RGB
@@ -2154,12 +2337,42 @@ mac_alloc_lighter_color (f, color, factor, delta)
2154 int delta; 2337 int delta;
2155{ 2338{
2156 unsigned long new; 2339 unsigned long new;
2340 long bright;
2341
2342 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
2343 delta /= 256;
2157 2344
2158 /* Change RGB values by specified FACTOR. Avoid overflow! */ 2345 /* Change RGB values by specified FACTOR. Avoid overflow! */
2159 xassert (factor >= 0); 2346 xassert (factor >= 0);
2160 new = RGB_TO_ULONG (min (0xff, (int) (factor * RED_FROM_ULONG (*color))), 2347 new = RGB_TO_ULONG (min (0xff, (int) (factor * RED_FROM_ULONG (*color))),
2161 min (0xff, (int) (factor * GREEN_FROM_ULONG (*color))), 2348 min (0xff, (int) (factor * GREEN_FROM_ULONG (*color))),
2162 min (0xff, (int) (factor * BLUE_FROM_ULONG (*color)))); 2349 min (0xff, (int) (factor * BLUE_FROM_ULONG (*color))));
2350
2351 /* Calculate brightness of COLOR. */
2352 bright = (2 * RED_FROM_ULONG (*color) + 3 * GREEN_FROM_ULONG (*color)
2353 + BLUE_FROM_ULONG (*color)) / 6;
2354
2355 /* We only boost colors that are darker than
2356 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2357 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2358 /* Make an additive adjustment to NEW, because it's dark enough so
2359 that scaling by FACTOR alone isn't enough. */
2360 {
2361 /* How far below the limit this color is (0 - 1, 1 being darker). */
2362 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2363 /* The additive adjustment. */
2364 int min_delta = delta * dimness * factor / 2;
2365
2366 if (factor < 1)
2367 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color)) - min_delta)),
2368 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color)) - min_delta)),
2369 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color)) - min_delta)));
2370 else
2371 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta + RED_FROM_ULONG (*color)))),
2372 max (0, min (0xff, (int) (min_delta + GREEN_FROM_ULONG (*color)))),
2373 max (0, min (0xff, (int) (min_delta + BLUE_FROM_ULONG (*color)))));
2374 }
2375
2163 if (new == *color) 2376 if (new == *color)
2164 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta + RED_FROM_ULONG (*color)))), 2377 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta + RED_FROM_ULONG (*color)))),
2165 max (0, min (0xff, (int) (delta + GREEN_FROM_ULONG (*color)))), 2378 max (0, min (0xff, (int) (delta + GREEN_FROM_ULONG (*color)))),
@@ -2204,7 +2417,8 @@ x_setup_relief_color (f, relief, factor, delta, default_pixel)
2204 /* Allocate new color. */ 2417 /* Allocate new color. */
2205 xgcv.foreground = default_pixel; 2418 xgcv.foreground = default_pixel;
2206 pixel = background; 2419 pixel = background;
2207 if (mac_alloc_lighter_color (f, &pixel, factor, delta)) 2420 if (dpyinfo->n_planes != 1
2421 && mac_alloc_lighter_color (f, &pixel, factor, delta))
2208 { 2422 {
2209 relief->allocated_p = 1; 2423 relief->allocated_p = 1;
2210 xgcv.foreground = relief->pixel = pixel; 2424 xgcv.foreground = relief->pixel = pixel;
@@ -2234,6 +2448,10 @@ x_setup_relief_colors (s)
2234 2448
2235 if (s->face->use_box_color_for_shadows_p) 2449 if (s->face->use_box_color_for_shadows_p)
2236 color = s->face->box_color; 2450 color = s->face->box_color;
2451 else if (s->first_glyph->type == IMAGE_GLYPH
2452 && s->img->pixmap
2453 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2454 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2237 else 2455 else
2238 { 2456 {
2239 XGCValues xgcv; 2457 XGCValues xgcv;
@@ -2267,9 +2485,11 @@ static void
2267x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, 2485x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
2268 raised_p, left_p, right_p, clip_rect) 2486 raised_p, left_p, right_p, clip_rect)
2269 struct frame *f; 2487 struct frame *f;
2270 int left_x, top_y, right_x, bottom_y, left_p, right_p, raised_p; 2488 int left_x, top_y, right_x, bottom_y, width, left_p, right_p, raised_p;
2271 Rect *clip_rect; 2489 Rect *clip_rect;
2272{ 2490{
2491 Display *dpy = FRAME_MAC_DISPLAY (f);
2492 Window window = FRAME_MAC_WINDOW (f);
2273 int i; 2493 int i;
2274 GC gc; 2494 GC gc;
2275 2495
@@ -2277,41 +2497,41 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
2277 gc = f->output_data.mac->white_relief.gc; 2497 gc = f->output_data.mac->white_relief.gc;
2278 else 2498 else
2279 gc = f->output_data.mac->black_relief.gc; 2499 gc = f->output_data.mac->black_relief.gc;
2280 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), clip_rect); 2500 mac_set_clip_rectangle (dpy, window, clip_rect);
2281 2501
2282 /* Top. */ 2502 /* Top. */
2283 for (i = 0; i < width; ++i) 2503 for (i = 0; i < width; ++i)
2284 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, 2504 XDrawLine (dpy, window, gc,
2285 left_x + i * left_p, top_y + i, 2505 left_x + i * left_p, top_y + i,
2286 right_x + 1 - i * right_p, top_y + i); 2506 right_x - i * right_p, top_y + i);
2287 2507
2288 /* Left. */ 2508 /* Left. */
2289 if (left_p) 2509 if (left_p)
2290 for (i = 0; i < width; ++i) 2510 for (i = 0; i < width; ++i)
2291 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, 2511 XDrawLine (dpy, window, gc,
2292 left_x + i, top_y + i, left_x + i, bottom_y - i); 2512 left_x + i, top_y + i, left_x + i, bottom_y - i);
2293 2513
2294 mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f)); 2514 mac_reset_clipping (dpy, window);
2295 if (raised_p) 2515 if (raised_p)
2296 gc = f->output_data.mac->black_relief.gc; 2516 gc = f->output_data.mac->black_relief.gc;
2297 else 2517 else
2298 gc = f->output_data.mac->white_relief.gc; 2518 gc = f->output_data.mac->white_relief.gc;
2299 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), 2519 mac_set_clip_rectangle (dpy, window,
2300 clip_rect); 2520 clip_rect);
2301 2521
2302 /* Bottom. */ 2522 /* Bottom. */
2303 for (i = 0; i < width; ++i) 2523 for (i = 0; i < width; ++i)
2304 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, 2524 XDrawLine (dpy, window, gc,
2305 left_x + i * left_p, bottom_y - i, 2525 left_x + i * left_p, bottom_y - i,
2306 right_x + 1 - i * right_p, bottom_y - i); 2526 right_x - i * right_p, bottom_y - i);
2307 2527
2308 /* Right. */ 2528 /* Right. */
2309 if (right_p) 2529 if (right_p)
2310 for (i = 0; i < width; ++i) 2530 for (i = 0; i < width; ++i)
2311 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, 2531 XDrawLine (dpy, window, gc,
2312 right_x - i, top_y + i + 1, right_x - i, bottom_y - i); 2532 right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1);
2313 2533
2314 mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f)); 2534 mac_reset_clipping (dpy, window);
2315} 2535}
2316 2536
2317 2537
@@ -2326,7 +2546,7 @@ static void
2326x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, 2546x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2327 left_p, right_p, clip_rect) 2547 left_p, right_p, clip_rect)
2328 struct glyph_string *s; 2548 struct glyph_string *s;
2329 int left_x, top_y, right_x, bottom_y, left_p, right_p; 2549 int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
2330 Rect *clip_rect; 2550 Rect *clip_rect;
2331{ 2551{
2332 XGCValues xgcv; 2552 XGCValues xgcv;
@@ -2336,21 +2556,21 @@ x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2336 2556
2337 /* Top. */ 2557 /* Top. */
2338 XFillRectangle (s->display, s->window, &xgcv, 2558 XFillRectangle (s->display, s->window, &xgcv,
2339 left_x, top_y, right_x - left_x, width); 2559 left_x, top_y, right_x - left_x + 1, width);
2340 2560
2341 /* Left. */ 2561 /* Left. */
2342 if (left_p) 2562 if (left_p)
2343 XFillRectangle (s->display, s->window, &xgcv, 2563 XFillRectangle (s->display, s->window, &xgcv,
2344 left_x, top_y, width, bottom_y - top_y); 2564 left_x, top_y, width, bottom_y - top_y + 1);
2345 2565
2346 /* Bottom. */ 2566 /* Bottom. */
2347 XFillRectangle (s->display, s->window, &xgcv, 2567 XFillRectangle (s->display, s->window, &xgcv,
2348 left_x, bottom_y - width, right_x - left_x, width); 2568 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2349 2569
2350 /* Right. */ 2570 /* Right. */
2351 if (right_p) 2571 if (right_p)
2352 XFillRectangle (s->display, s->window, &xgcv, 2572 XFillRectangle (s->display, s->window, &xgcv,
2353 right_x - width, top_y, width, bottom_y - top_y); 2573 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2354 2574
2355 mac_reset_clipping (s->display, s->window); 2575 mac_reset_clipping (s->display, s->window);
2356} 2576}
@@ -2385,9 +2605,9 @@ x_draw_glyph_string_box (s)
2385 width = abs (s->face->box_line_width); 2605 width = abs (s->face->box_line_width);
2386 raised_p = s->face->box == FACE_RAISED_BOX; 2606 raised_p = s->face->box == FACE_RAISED_BOX;
2387 left_x = s->x; 2607 left_x = s->x;
2388 right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p 2608 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2389 ? last_x - 1 2609 ? last_x - 1
2390 : min (last_x, s->x + s->background_width) - 1)); 2610 : min (last_x, s->x + s->background_width) - 1);
2391 top_y = s->y; 2611 top_y = s->y;
2392 bottom_y = top_y + s->height - 1; 2612 bottom_y = top_y + s->height - 1;
2393 2613
@@ -2438,39 +2658,36 @@ x_draw_image_foreground (s)
2438 2658
2439 if (s->img->pixmap) 2659 if (s->img->pixmap)
2440 { 2660 {
2441#if 0 /* MAC_TODO: image mask */
2442 if (s->img->mask) 2661 if (s->img->mask)
2443 { 2662 {
2444 /* We can't set both a clip mask and use XSetClipRectangles 2663 Rect nr;
2445 because the latter also sets a clip mask. We also can't
2446 trust on the shape extension to be available
2447 (XShapeCombineRegion). So, compute the rectangle to draw
2448 manually. */
2449 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2450 | GCFunction);
2451 XGCValues xgcv;
2452 XRectangle clip_rect, image_rect, r; 2664 XRectangle clip_rect, image_rect, r;
2453 2665
2454 xgcv.clip_mask = s->img->mask; 2666 get_glyph_string_clip_rect (s, &nr);
2455 xgcv.clip_x_origin = x; 2667 CONVERT_TO_XRECT (clip_rect, nr);
2456 xgcv.clip_y_origin = y;
2457 xgcv.function = GXcopy;
2458 XChangeGC (s->display, s->gc, mask, &xgcv);
2459
2460 get_glyph_string_clip_rect (s, &clip_rect);
2461 image_rect.x = x; 2668 image_rect.x = x;
2462 image_rect.y = y; 2669 image_rect.y = y;
2463 image_rect.width = s->img->width; 2670 image_rect.width = s->img->width;
2464 image_rect.height = s->img->height; 2671 image_rect.height = s->img->height;
2465 if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) 2672 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2466 XCopyArea (s->display, s->img->pixmap, s->window, s->gc, 2673 mac_copy_area_with_mask (s->display, s->img->pixmap, s->img->mask,
2467 r.x - x, r.y - y, r.width, r.height, r.x, r.y); 2674 s->window, s->gc, r.x - x, r.y - y,
2675 r.width, r.height, r.x, r.y);
2468 } 2676 }
2469 else 2677 else
2470#endif /* MAC_TODO */
2471 { 2678 {
2472 mac_copy_area (s->display, s->img->pixmap, s->window, s->gc, 2679 Rect nr;
2473 0, 0, s->img->width, s->img->height, x, y); 2680 XRectangle clip_rect, image_rect, r;
2681
2682 get_glyph_string_clip_rect (s, &nr);
2683 CONVERT_TO_XRECT (clip_rect, nr);
2684 image_rect.x = x;
2685 image_rect.y = y;
2686 image_rect.width = s->img->width;
2687 image_rect.height = s->img->height;
2688 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2689 mac_copy_area (s->display, s->img->pixmap, s->window, s->gc,
2690 r.x - x, r.y - y, r.width, r.height, r.x, r.y);
2474 2691
2475 /* When the image has a mask, we can expect that at 2692 /* When the image has a mask, we can expect that at
2476 least part of a mouse highlight or a block cursor will 2693 least part of a mouse highlight or a block cursor will
@@ -2494,7 +2711,6 @@ x_draw_image_foreground (s)
2494} 2711}
2495 2712
2496 2713
2497
2498/* Draw a relief around the image glyph string S. */ 2714/* Draw a relief around the image glyph string S. */
2499 2715
2500static void 2716static void
@@ -2567,30 +2783,12 @@ x_draw_image_foreground_1 (s, pixmap)
2567 2783
2568 if (s->img->pixmap) 2784 if (s->img->pixmap)
2569 { 2785 {
2570#if 0 /* MAC_TODO: image mask */
2571 if (s->img->mask) 2786 if (s->img->mask)
2572 { 2787 mac_copy_area_with_mask_to_pixmap (s->display, s->img->pixmap,
2573 /* We can't set both a clip mask and use XSetClipRectangles 2788 s->img->mask, pixmap, s->gc,
2574 because the latter also sets a clip mask. We also can't 2789 0, 0, s->img->width, s->img->height,
2575 trust on the shape extension to be available 2790 x, y);
2576 (XShapeCombineRegion). So, compute the rectangle to draw
2577 manually. */
2578 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2579 | GCFunction);
2580 XGCValues xgcv;
2581
2582 xgcv.clip_mask = s->img->mask;
2583 xgcv.clip_x_origin = x;
2584 xgcv.clip_y_origin = y;
2585 xgcv.function = GXcopy;
2586 XChangeGC (s->display, s->gc, mask, &xgcv);
2587
2588 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
2589 0, 0, s->img->width, s->img->height, x, y);
2590 XSetClipMask (s->display, s->gc, None);
2591 }
2592 else 2791 else
2593#endif /* MAC_TODO */
2594 { 2792 {
2595 mac_copy_area_to_pixmap (s->display, s->img->pixmap, pixmap, s->gc, 2793 mac_copy_area_to_pixmap (s->display, s->img->pixmap, pixmap, s->gc,
2596 0, 0, s->img->width, s->img->height, x, y); 2794 0, 0, s->img->width, s->img->height, x, y);
@@ -2605,15 +2803,16 @@ x_draw_image_foreground_1 (s, pixmap)
2605 { 2803 {
2606 int r = s->img->relief; 2804 int r = s->img->relief;
2607 if (r < 0) r = -r; 2805 if (r < 0) r = -r;
2608 mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x - r, y - r, 2806 mac_draw_rectangle (s->display, s->window, s->gc, x - r, y - r,
2609 s->img->width + r*2 - 1, s->img->height + r*2 - 1); 2807 s->img->width + r*2 - 1,
2808 s->img->height + r*2 - 1);
2610 } 2809 }
2611 } 2810 }
2612 } 2811 }
2613 else 2812 else
2614 /* Draw a rectangle if image could not be loaded. */ 2813 /* Draw a rectangle if image could not be loaded. */
2615 mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y, 2814 mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y,
2616 s->img->width - 1, s->img->height - 1); 2815 s->img->width - 1, s->img->height - 1);
2617} 2816}
2618 2817
2619 2818
@@ -2646,7 +2845,7 @@ x_draw_glyph_string_bg_rect (s, x, y, w, h)
2646 | s->face->box 2845 | s->face->box
2647 | 2846 |
2648 | +------------------------- 2847 | +-------------------------
2649 | | s->img->vmargin 2848 | | s->img->margin
2650 | | 2849 | |
2651 | | +------------------- 2850 | | +-------------------
2652 | | | the image 2851 | | | the image
@@ -2665,6 +2864,7 @@ x_draw_image_glyph_string (s)
2665 2864
2666 height = s->height - 2 * box_line_vwidth; 2865 height = s->height - 2 * box_line_vwidth;
2667 2866
2867
2668 /* Fill background with face under the image. Do it only if row is 2868 /* Fill background with face under the image. Do it only if row is
2669 taller than image or if image has a clip mask to reduce 2869 taller than image or if image has a clip mask to reduce
2670 flickering. */ 2870 flickering. */
@@ -2672,9 +2872,7 @@ x_draw_image_glyph_string (s)
2672 if (height > s->img->height 2872 if (height > s->img->height
2673 || s->img->hmargin 2873 || s->img->hmargin
2674 || s->img->vmargin 2874 || s->img->vmargin
2675#if 0 /* TODO: image mask */
2676 || s->img->mask 2875 || s->img->mask
2677#endif
2678 || s->img->pixmap == 0 2876 || s->img->pixmap == 0
2679 || s->width != s->background_width) 2877 || s->width != s->background_width)
2680 { 2878 {
@@ -2684,25 +2882,21 @@ x_draw_image_glyph_string (s)
2684 x = s->x; 2882 x = s->x;
2685 2883
2686 y = s->y + box_line_vwidth; 2884 y = s->y + box_line_vwidth;
2687#if 0 /* TODO: image mask */ 2885
2688 if (s->img->mask) 2886 if (s->img->mask)
2689 { 2887 {
2690 /* Create a pixmap as large as the glyph string. Fill it 2888 /* Create a pixmap as large as the glyph string. Fill it
2691 with the background color. Copy the image to it, using 2889 with the background color. Copy the image to it, using
2692 its mask. Copy the temporary pixmap to the display. */ 2890 its mask. Copy the temporary pixmap to the display. */
2693 Screen *screen = FRAME_X_SCREEN (s->f); 2891 int depth = one_mac_display_info.n_planes;
2694 int depth = DefaultDepthOfScreen (screen);
2695 2892
2696 /* Create a pixmap as large as the glyph string. */ 2893 /* Create a pixmap as large as the glyph string. */
2697 pixmap = XCreatePixmap (s->display, s->window, 2894 pixmap = XCreatePixmap (s->display, s->window,
2698 s->background_width, 2895 s->background_width,
2699 s->height, depth); 2896 s->height, depth);
2700 2897
2701 /* Don't clip in the following because we're working on the
2702 pixmap. */
2703 XSetClipMask (s->display, s->gc, None);
2704
2705 /* Fill the pixmap with the background color/stipple. */ 2898 /* Fill the pixmap with the background color/stipple. */
2899#if 0 /* TODO: stipple */
2706 if (s->stippled_p) 2900 if (s->stippled_p)
2707 { 2901 {
2708 /* Fill background with a stipple pattern. */ 2902 /* Fill background with a stipple pattern. */
@@ -2712,18 +2906,19 @@ x_draw_image_glyph_string (s)
2712 XSetFillStyle (s->display, s->gc, FillSolid); 2906 XSetFillStyle (s->display, s->gc, FillSolid);
2713 } 2907 }
2714 else 2908 else
2909#endif
2715 { 2910 {
2716 XGCValues xgcv; 2911 XGCValues xgcv;
2717 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, 2912 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
2718 &xgcv); 2913 &xgcv);
2719 XSetForeground (s->display, s->gc, xgcv.background); 2914 XSetForeground (s->display, s->gc, xgcv.background);
2720 XFillRectangle (s->display, pixmap, s->gc, 2915 mac_fill_rectangle_to_pixmap (s->display, pixmap, s->gc,
2721 0, 0, s->background_width, s->height); 2916 0, 0, s->background_width,
2917 s->height);
2722 XSetForeground (s->display, s->gc, xgcv.foreground); 2918 XSetForeground (s->display, s->gc, xgcv.foreground);
2723 } 2919 }
2724 } 2920 }
2725 else 2921 else
2726#endif
2727 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height); 2922 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
2728 2923
2729 s->background_filled_p = 1; 2924 s->background_filled_p = 1;
@@ -2735,7 +2930,7 @@ x_draw_image_glyph_string (s)
2735 x_draw_image_foreground_1 (s, pixmap); 2930 x_draw_image_foreground_1 (s, pixmap);
2736 x_set_glyph_string_clipping (s); 2931 x_set_glyph_string_clipping (s);
2737 mac_copy_area (s->display, pixmap, s->window, s->gc, 2932 mac_copy_area (s->display, pixmap, s->window, s->gc,
2738 0, 0, s->background_width, s->height, s->x, s->y); 2933 0, 0, s->background_width, s->height, s->x, s->y);
2739 mac_reset_clipping (s->display, s->window); 2934 mac_reset_clipping (s->display, s->window);
2740 XFreePixmap (s->display, pixmap); 2935 XFreePixmap (s->display, pixmap);
2741 } 2936 }
@@ -2772,10 +2967,10 @@ x_draw_stretch_glyph_string (s)
2772 /* Clear rest using the GC of the original non-cursor face. */ 2967 /* Clear rest using the GC of the original non-cursor face. */
2773 if (width < s->background_width) 2968 if (width < s->background_width)
2774 { 2969 {
2775 GC gc = s->face->gc;
2776 int x = s->x + width, y = s->y; 2970 int x = s->x + width, y = s->y;
2777 int w = s->background_width - width, h = s->height; 2971 int w = s->background_width - width, h = s->height;
2778 Rect r; 2972 Rect r;
2973 GC gc;
2779 2974
2780 if (s->row->mouse_face_p 2975 if (s->row->mouse_face_p
2781 && cursor_in_mouse_face_p (s->w)) 2976 && cursor_in_mouse_face_p (s->w))
@@ -2835,7 +3030,6 @@ x_draw_glyph_string (s)
2835 x_set_glyph_string_gc (s->next); 3030 x_set_glyph_string_gc (s->next);
2836 x_set_glyph_string_clipping (s->next); 3031 x_set_glyph_string_clipping (s->next);
2837 x_draw_glyph_string_background (s->next, 1); 3032 x_draw_glyph_string_background (s->next, 1);
2838
2839 } 3033 }
2840 3034
2841 /* Set up S->gc, set clipping and draw S. */ 3035 /* Set up S->gc, set clipping and draw S. */
@@ -2872,7 +3066,7 @@ x_draw_glyph_string (s)
2872 if (s->for_overlaps_p) 3066 if (s->for_overlaps_p)
2873 s->background_filled_p = 1; 3067 s->background_filled_p = 1;
2874 else 3068 else
2875 x_draw_glyph_string_background (s, 0); 3069 x_draw_glyph_string_background (s, 0);
2876 x_draw_glyph_string_foreground (s); 3070 x_draw_glyph_string_foreground (s);
2877 break; 3071 break;
2878 3072
@@ -2949,9 +3143,9 @@ x_draw_glyph_string (s)
2949 } 3143 }
2950 } 3144 }
2951 3145
2952 /* Draw relief. */ 3146 /* Draw relief if not yet drawn. */
2953 if (!relief_drawn_p && s->face->box != FACE_NO_BOX) 3147 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
2954 x_draw_glyph_string_box (s); 3148 x_draw_glyph_string_box (s);
2955 } 3149 }
2956 3150
2957 /* Reset clipping. */ 3151 /* Reset clipping. */
@@ -2971,7 +3165,6 @@ mac_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
2971 x + shift_by, y); 3165 x + shift_by, y);
2972} 3166}
2973 3167
2974
2975/* Delete N glyphs at the nominal cursor position. Not implemented 3168/* Delete N glyphs at the nominal cursor position. Not implemented
2976 for X frames. */ 3169 for X frames. */
2977 3170
@@ -3026,6 +3219,7 @@ x_clear_frame ()
3026 3219
3027#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) 3220#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3028 3221
3222
3029/* Subtract the `struct timeval' values X and Y, storing the result in 3223/* Subtract the `struct timeval' values X and Y, storing the result in
3030 *RESULT. Return 1 if the difference is negative, otherwise 0. */ 3224 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3031 3225
@@ -3129,7 +3323,7 @@ XTring_bell ()
3129 This, and those operations, are used only within an update 3323 This, and those operations, are used only within an update
3130 that is bounded by calls to x_update_begin and x_update_end. */ 3324 that is bounded by calls to x_update_begin and x_update_end. */
3131 3325
3132void 3326static void
3133XTset_terminal_window (n) 3327XTset_terminal_window (n)
3134 register int n; 3328 register int n;
3135{ 3329{
@@ -3165,7 +3359,7 @@ x_scroll_run (w, run)
3165 3359
3166 /* Get frame-relative bounding box of the text display area of W, 3360 /* Get frame-relative bounding box of the text display area of W,
3167 without mode lines. Include in this box the left and right 3361 without mode lines. Include in this box the left and right
3168 fringes of W. */ 3362 fringe of W. */
3169 window_box (w, -1, &x, &y, &width, &height); 3363 window_box (w, -1, &x, &y, &width, &height);
3170 3364
3171 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y); 3365 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
@@ -3287,8 +3481,6 @@ static void
3287XTframe_rehighlight (frame) 3481XTframe_rehighlight (frame)
3288 struct frame *frame; 3482 struct frame *frame;
3289{ 3483{
3290
3291
3292 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame)); 3484 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
3293} 3485}
3294 3486
@@ -4429,13 +4621,6 @@ x_draw_hollow_cursor (w, row)
4429 struct glyph *cursor_glyph; 4621 struct glyph *cursor_glyph;
4430 GC gc; 4622 GC gc;
4431 4623
4432 /* Compute frame-relative coordinates from window-relative
4433 coordinates. */
4434 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
4435 y = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
4436 + row->ascent - w->phys_cursor_ascent);
4437 h = row->height - 1;
4438
4439 /* Get the glyph the cursor is on. If we can't tell because 4624 /* Get the glyph the cursor is on. If we can't tell because
4440 the current matrix is invalid or such, give up. */ 4625 the current matrix is invalid or such, give up. */
4441 cursor_glyph = get_phys_cursor_glyph (w); 4626 cursor_glyph = get_phys_cursor_glyph (w);
@@ -4450,6 +4635,20 @@ x_draw_hollow_cursor (w, row)
4450 if (cursor_glyph->type == STRETCH_GLYPH 4635 if (cursor_glyph->type == STRETCH_GLYPH
4451 && !x_stretch_cursor_p) 4636 && !x_stretch_cursor_p)
4452 wd = min (FRAME_COLUMN_WIDTH (f), wd); 4637 wd = min (FRAME_COLUMN_WIDTH (f), wd);
4638 w->phys_cursor_width = wd;
4639
4640 /* Compute frame-relative coordinates from window-relative
4641 coordinates. */
4642 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
4643 y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
4644
4645 /* Compute the proper height and ascent of the rectangle, based
4646 on the actual glyph. Using the full height of the row looks
4647 bad when there are tall images on that row. */
4648 h = max (FRAME_LINE_HEIGHT (f), cursor_glyph->ascent + cursor_glyph->descent);
4649 if (h < row->height)
4650 y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
4651 h--;
4453 4652
4454 /* The foreground of cursor_gc is typically the same as the normal 4653 /* The foreground of cursor_gc is typically the same as the normal
4455 background color, which can cause the cursor box to be invisible. */ 4654 background color, which can cause the cursor box to be invisible. */
@@ -4476,35 +4675,49 @@ x_draw_hollow_cursor (w, row)
4476 --gerd. */ 4675 --gerd. */
4477 4676
4478static void 4677static void
4479x_draw_bar_cursor (w, row, width) 4678x_draw_bar_cursor (w, row, width, kind)
4480 struct window *w; 4679 struct window *w;
4481 struct glyph_row *row; 4680 struct glyph_row *row;
4482 int width; 4681 int width;
4682 enum text_cursor_kinds kind;
4483{ 4683{
4484 /* If cursor hpos is out of bounds, don't draw garbage. This can 4684 struct frame *f = XFRAME (w->frame);
4485 happen in mini-buffer windows when switching between echo area 4685 struct glyph *cursor_glyph;
4486 glyphs and mini-buffer. */ 4686
4487 if (w->phys_cursor.hpos < row->used[TEXT_AREA]) 4687 /* If cursor is out of bounds, don't draw garbage. This can happen
4688 in mini-buffer windows when switching between echo area glyphs
4689 and mini-buffer. */
4690 cursor_glyph = get_phys_cursor_glyph (w);
4691 if (cursor_glyph == NULL)
4692 return;
4693
4694 /* If on an image, draw like a normal cursor. That's usually better
4695 visible than drawing a bar, esp. if the image is large so that
4696 the bar might not be in the window. */
4697 if (cursor_glyph->type == IMAGE_GLYPH)
4488 { 4698 {
4489 struct frame *f = XFRAME (w->frame); 4699 struct glyph_row *row;
4490 struct glyph *cursor_glyph; 4700 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
4491 GC gc; 4701 draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
4492 int x; 4702 }
4493 unsigned long mask; 4703 else
4704 {
4705 Display *dpy = FRAME_MAC_DISPLAY (f);
4706 Window window = FRAME_MAC_WINDOW (f);
4707 GC gc = FRAME_MAC_DISPLAY_INFO (f)->scratch_cursor_gc;
4708 unsigned long mask = GCForeground | GCBackground;
4709 struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
4494 XGCValues xgcv; 4710 XGCValues xgcv;
4495 Display *dpy;
4496 Window window;
4497 4711
4498 cursor_glyph = get_phys_cursor_glyph (w); 4712 /* If the glyph's background equals the color we normally draw
4499 if (cursor_glyph == NULL) 4713 the bar cursor in, the bar cursor in its normal color is
4500 return; 4714 invisible. Use the glyph's foreground color instead in this
4501 4715 case, on the assumption that the glyph's colors are chosen so
4502 xgcv.background = f->output_data.mac->cursor_pixel; 4716 that the glyph is legible. */
4503 xgcv.foreground = f->output_data.mac->cursor_pixel; 4717 if (face->background == f->output_data.mac->cursor_pixel)
4504 mask = GCForeground | GCBackground; 4718 xgcv.background = xgcv.foreground = face->foreground;
4505 dpy = FRAME_MAC_DISPLAY (f); 4719 else
4506 window = FRAME_MAC_WINDOW (f); 4720 xgcv.background = xgcv.foreground = f->output_data.mac->cursor_pixel;
4507 gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc;
4508 4721
4509 if (gc) 4722 if (gc)
4510 XChangeGC (dpy, gc, mask, &xgcv); 4723 XChangeGC (dpy, gc, mask, &xgcv);
@@ -4516,14 +4729,24 @@ x_draw_bar_cursor (w, row, width)
4516 4729
4517 if (width < 0) 4730 if (width < 0)
4518 width = FRAME_CURSOR_WIDTH (f); 4731 width = FRAME_CURSOR_WIDTH (f);
4732 width = min (cursor_glyph->pixel_width, width);
4519 4733
4520 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); 4734 w->phys_cursor_width = width;
4521 x_clip_to_row (w, row, gc); 4735 x_clip_to_row (w, row, gc);
4522 XFillRectangle (dpy, window, gc, 4736
4523 x, 4737 if (kind == BAR_CURSOR)
4524 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), 4738 XFillRectangle (dpy, window, gc,
4525 min (cursor_glyph->pixel_width, width), 4739 WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
4526 row->height); 4740 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
4741 width, row->height);
4742 else
4743 XFillRectangle (dpy, window, gc,
4744 WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
4745 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
4746 row->height - width),
4747 cursor_glyph->pixel_width,
4748 width);
4749
4527 mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); 4750 mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f));
4528 } 4751 }
4529} 4752}
@@ -4565,7 +4788,6 @@ mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
4565 if (on_p) 4788 if (on_p)
4566 { 4789 {
4567 w->phys_cursor_type = cursor_type; 4790 w->phys_cursor_type = cursor_type;
4568 w->phys_cursor_width = cursor_width;
4569 w->phys_cursor_on_p = 1; 4791 w->phys_cursor_on_p = 1;
4570 4792
4571 if (glyph_row->exact_window_width_line_p 4793 if (glyph_row->exact_window_width_line_p
@@ -4573,9 +4795,8 @@ mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
4573 { 4795 {
4574 glyph_row->cursor_in_fringe_p = 1; 4796 glyph_row->cursor_in_fringe_p = 1;
4575 draw_fringe_bitmap (w, glyph_row, 0); 4797 draw_fringe_bitmap (w, glyph_row, 0);
4576 return;
4577 } 4798 }
4578 4799 else
4579 switch (cursor_type) 4800 switch (cursor_type)
4580 { 4801 {
4581 case HOLLOW_BOX_CURSOR: 4802 case HOLLOW_BOX_CURSOR:
@@ -4586,13 +4807,16 @@ mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
4586 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); 4807 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
4587 break; 4808 break;
4588 4809
4589 case HBAR_CURSOR:
4590 /* TODO. For now, just draw bar cursor. */
4591 case BAR_CURSOR: 4810 case BAR_CURSOR:
4592 x_draw_bar_cursor (w, glyph_row, cursor_width); 4811 x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
4812 break;
4813
4814 case HBAR_CURSOR:
4815 x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
4593 break; 4816 break;
4594 4817
4595 case NO_CURSOR: 4818 case NO_CURSOR:
4819 w->phys_cursor_width = 0;
4596 break; 4820 break;
4597 4821
4598 default: 4822 default:
@@ -5117,6 +5341,8 @@ x_make_frame_visible (f)
5117 FRAME_SAMPLE_VISIBILITY (f); 5341 FRAME_SAMPLE_VISIBILITY (f);
5118 } 5342 }
5119 } 5343 }
5344#else
5345 UNBLOCK_INPUT;
5120#endif /* MAC_TODO */ 5346#endif /* MAC_TODO */
5121} 5347}
5122 5348
@@ -5173,10 +5399,10 @@ x_iconify_frame (f)
5173} 5399}
5174 5400
5175 5401
5176/* Destroy the X window of frame F. */ 5402/* Free X resources of frame F. */
5177 5403
5178void 5404void
5179x_destroy_window (f) 5405x_free_frame_resources (f)
5180 struct frame *f; 5406 struct frame *f;
5181{ 5407{
5182 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f); 5408 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
@@ -5186,10 +5412,15 @@ x_destroy_window (f)
5186 DisposeWindow (FRAME_MAC_WINDOW (f)); 5412 DisposeWindow (FRAME_MAC_WINDOW (f));
5187 5413
5188 free_frame_menubar (f); 5414 free_frame_menubar (f);
5189 free_frame_faces (f); 5415
5416 if (FRAME_FACE_CACHE (f))
5417 free_frame_faces (f);
5418
5419 x_free_gcs (f);
5190 5420
5191 xfree (f->output_data.mac); 5421 xfree (f->output_data.mac);
5192 f->output_data.mac = 0; 5422 f->output_data.mac = NULL;
5423
5193 if (f == dpyinfo->x_focus_frame) 5424 if (f == dpyinfo->x_focus_frame)
5194 dpyinfo->x_focus_frame = 0; 5425 dpyinfo->x_focus_frame = 0;
5195 if (f == dpyinfo->x_focus_event_frame) 5426 if (f == dpyinfo->x_focus_event_frame)
@@ -5197,8 +5428,6 @@ x_destroy_window (f)
5197 if (f == dpyinfo->x_highlight_frame) 5428 if (f == dpyinfo->x_highlight_frame)
5198 dpyinfo->x_highlight_frame = 0; 5429 dpyinfo->x_highlight_frame = 0;
5199 5430
5200 dpyinfo->reference_count--;
5201
5202 if (f == dpyinfo->mouse_face_mouse_frame) 5431 if (f == dpyinfo->mouse_face_mouse_frame)
5203 { 5432 {
5204 dpyinfo->mouse_face_beg_row 5433 dpyinfo->mouse_face_beg_row
@@ -5212,6 +5441,21 @@ x_destroy_window (f)
5212 5441
5213 UNBLOCK_INPUT; 5442 UNBLOCK_INPUT;
5214} 5443}
5444
5445
5446/* Destroy the X window of frame F. */
5447
5448void
5449x_destroy_window (f)
5450 struct frame *f;
5451{
5452 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
5453
5454 x_free_frame_resources (f);
5455
5456 dpyinfo->reference_count--;
5457}
5458
5215 5459
5216/* Setting window manager hints. */ 5460/* Setting window manager hints. */
5217 5461
@@ -5478,6 +5722,7 @@ char **font_name_table = NULL;
5478int font_name_table_size = 0; 5722int font_name_table_size = 0;
5479int font_name_count = 0; 5723int font_name_count = 0;
5480 5724
5725#if 0
5481/* compare two strings ignoring case */ 5726/* compare two strings ignoring case */
5482static int 5727static int
5483stricmp (const char *s, const char *t) 5728stricmp (const char *s, const char *t)
@@ -5557,13 +5802,53 @@ mac_font_match (char *mf, char *xf)
5557 && wildstrieq (m_charset, x_charset)) 5802 && wildstrieq (m_charset, x_charset))
5558 || mac_font_pattern_match (mf, xf); 5803 || mac_font_pattern_match (mf, xf);
5559} 5804}
5805#endif
5806
5807static Lisp_Object Qbig5, Qcn_gb, Qsjis, Qeuc_kr;
5808
5809static void
5810decode_mac_font_name (char *name, int size, short scriptcode)
5811{
5812 Lisp_Object coding_system;
5813 struct coding_system coding;
5814 char *buf;
5815
5816 switch (scriptcode)
5817 {
5818 case smTradChinese:
5819 coding_system = Qbig5;
5820 break;
5821 case smSimpChinese:
5822 coding_system = Qcn_gb;
5823 break;
5824 case smJapanese:
5825 coding_system = Qsjis;
5826 break;
5827 case smKorean:
5828 coding_system = Qeuc_kr;
5829 break;
5830 default:
5831 return;
5832 }
5833
5834 setup_coding_system (coding_system, &coding);
5835 coding.src_multibyte = 0;
5836 coding.dst_multibyte = 1;
5837 coding.mode |= CODING_MODE_LAST_BLOCK;
5838 coding.composing = COMPOSITION_DISABLED;
5839 buf = (char *) alloca (size);
5840
5841 decode_coding (&coding, name, buf, strlen (name), size - 1);
5842 bcopy (buf, name, coding.produced);
5843 name[coding.produced] = '\0';
5844}
5560 5845
5561 5846
5562static char * 5847static char *
5563mac_to_x_fontname (char *name, int size, Style style, short scriptcode) 5848mac_to_x_fontname (char *name, int size, Style style, short scriptcode)
5564{ 5849{
5565 char foundry[32], family[32], cs[32]; 5850 char foundry[32], family[32], cs[32];
5566 char xf[255], *result, *p; 5851 char xf[256], *result, *p;
5567 5852
5568 if (sscanf (name, "%31[^-]-%31[^-]-%31s", foundry, family, cs) != 3) 5853 if (sscanf (name, "%31[^-]-%31[^-]-%31s", foundry, family, cs) != 3)
5569 { 5854 {
@@ -5622,6 +5907,8 @@ static void
5622x_font_name_to_mac_font_name (char *xf, char *mf) 5907x_font_name_to_mac_font_name (char *xf, char *mf)
5623{ 5908{
5624 char foundry[32], family[32], weight[20], slant[2], cs[32]; 5909 char foundry[32], family[32], weight[20], slant[2], cs[32];
5910 Lisp_Object coding_system = Qnil;
5911 struct coding_system coding;
5625 5912
5626 strcpy (mf, ""); 5913 strcpy (mf, "");
5627 5914
@@ -5631,13 +5918,29 @@ x_font_name_to_mac_font_name (char *xf, char *mf)
5631 foundry, family, weight, slant, cs) != 5) 5918 foundry, family, weight, slant, cs) != 5)
5632 return; 5919 return;
5633 5920
5634 if (strcmp (cs, "big5-0") == 0 || strcmp (cs, "gb2312.1980-0") == 0 5921 if (strcmp (cs, "big5-0") == 0)
5635 || strcmp (cs, "jisx0208.1983-sjis") == 0 5922 coding_system = Qbig5;
5636 || strcmp (cs, "jisx0201.1976-0") == 0 5923 else if (strcmp (cs, "gb2312.1980-0") == 0)
5637 || strcmp (cs, "ksc5601.1989-0") == 0 || strcmp (cs, "mac-roman") == 0) 5924 coding_system = Qcn_gb;
5638 strcpy(mf, family); 5925 else if (strcmp (cs, "jisx0208.1983-sjis") == 0
5926 || strcmp (cs, "jisx0201.1976-0") == 0)
5927 coding_system = Qsjis;
5928 else if (strcmp (cs, "ksc5601.1989-0") == 0)
5929 coding_system = Qeuc_kr;
5930 else if (strcmp (cs, "mac-roman") == 0)
5931 strcpy (mf, family);
5639 else 5932 else
5640 sprintf(mf, "%s-%s-%s", foundry, family, cs); 5933 sprintf (mf, "%s-%s-%s", foundry, family, cs);
5934
5935 if (!NILP (coding_system))
5936 {
5937 setup_coding_system (coding_system, &coding);
5938 coding.src_multibyte = 1;
5939 coding.dst_multibyte = 1;
5940 coding.mode |= CODING_MODE_LAST_BLOCK;
5941 encode_coding (&coding, family, mf, strlen (family), sizeof (Str32) - 1);
5942 mf[coding.produced] = '\0';
5943 }
5641} 5944}
5642 5945
5643 5946
@@ -5701,36 +6004,45 @@ init_font_name_table ()
5701 if (FMGetFontFamilyName (ff, name) != noErr) 6004 if (FMGetFontFamilyName (ff, name) != noErr)
5702 break; 6005 break;
5703 p2cstr (name); 6006 p2cstr (name);
6007 if (*name == '.')
6008 continue;
5704 6009
5705 sc = FontToScript (ff); 6010 sc = FontToScript (ff);
6011 decode_mac_font_name (name, sizeof (name), sc);
5706 6012
5707 /* Point the instance iterator at the current font family. */ 6013 /* Point the instance iterator at the current font family. */
5708 if (FMResetFontFamilyInstanceIterator(ff, &ffii) != noErr) 6014 if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr)
5709 break; 6015 break;
5710 6016
5711 while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size) 6017 while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
5712 == noErr) 6018 == noErr)
5713 if (size == 0) 6019 {
5714 { 6020 /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
5715 add_font_name_table_entry (mac_to_x_fontname (name, size, 6021 contained in Apple Japanese (SJIS) font. */
5716 style, sc)); 6022 again:
5717 add_font_name_table_entry (mac_to_x_fontname (name, size, 6023 if (size == 0)
5718 italic, sc)); 6024 {
5719 add_font_name_table_entry (mac_to_x_fontname (name, size, 6025 add_font_name_table_entry (mac_to_x_fontname (name, size,
5720 bold, sc)); 6026 style, sc));
5721 add_font_name_table_entry (mac_to_x_fontname (name, size, 6027 add_font_name_table_entry (mac_to_x_fontname (name, size,
5722 italic | bold, 6028 italic, sc));
5723 sc)); 6029 add_font_name_table_entry (mac_to_x_fontname (name, size,
5724 } 6030 bold, sc));
5725 else 6031 add_font_name_table_entry (mac_to_x_fontname (name, size,
5726 { 6032 italic | bold,
6033 sc));
6034 }
6035 else
5727 add_font_name_table_entry (mac_to_x_fontname (name, size, 6036 add_font_name_table_entry (mac_to_x_fontname (name, size,
5728 style, sc)); 6037 style, sc));
5729 if (smJapanese == sc) 6038 if (sc == smJapanese)
5730 add_font_name_table_entry (mac_to_x_fontname (name, size, 6039 {
5731 style, 6040 sc = -smJapanese;
5732 -smJapanese)); 6041 goto again;
5733 } 6042 }
6043 else if (sc == -smJapanese)
6044 sc = smJapanese;
6045 }
5734 } 6046 }
5735 6047
5736 /* Dispose of the iterators. */ 6048 /* Dispose of the iterators. */
@@ -5772,6 +6084,7 @@ init_font_name_table ()
5772 6084
5773 TextFont (fontnum); 6085 TextFont (fontnum);
5774 scriptcode = FontToScript (fontnum); 6086 scriptcode = FontToScript (fontnum);
6087 decode_mac_font_name (name, sizeof (name), scriptcode);
5775 do 6088 do
5776 { 6089 {
5777 HLock (font_handle); 6090 HLock (font_handle);
@@ -5806,9 +6119,9 @@ init_font_name_table ()
5806 assc_entry->fontSize, 6119 assc_entry->fontSize,
5807 assc_entry->fontStyle, 6120 assc_entry->fontStyle,
5808 scriptcode); 6121 scriptcode);
5809 /* Both jisx0208.1983-sjis and 6122 /* Both jisx0208.1983-sjis and jisx0201.1976-0
5810 jisx0201.1976-sjis parts are contained in 6123 parts are contained in Apple Japanese (SJIS)
5811 Apple Japanese (SJIS) font. */ 6124 font. */
5812 if (smJapanese == scriptcode) 6125 if (smJapanese == scriptcode)
5813 { 6126 {
5814 font_name_table[font_name_count++] 6127 font_name_table[font_name_count++]
@@ -5835,6 +6148,145 @@ init_font_name_table ()
5835} 6148}
5836 6149
5837 6150
6151enum xlfd_scalable_field_index
6152 {
6153 XLFD_SCL_PIXEL_SIZE,
6154 XLFD_SCL_POINT_SIZE,
6155 XLFD_SCL_AVGWIDTH,
6156 XLFD_SCL_LAST
6157 };
6158
6159static int xlfd_scalable_fields[] =
6160 {
6161 6, /* PIXEL_SIZE */
6162 7, /* POINT_SIZE */
6163 11, /* AVGWIDTH */
6164 -1
6165 };
6166
6167static Lisp_Object
6168mac_do_list_fonts (pattern, maxnames)
6169 char *pattern;
6170 int maxnames;
6171{
6172 int i, n_fonts = 0;
6173 Lisp_Object font_list = Qnil, pattern_regex, fontname;
6174 char *regex = (char *) alloca (strlen (pattern) * 2 + 3);
6175 char scaled[256];
6176 char *ptr;
6177 int scl_val[XLFD_SCL_LAST], *field, *val;
6178
6179 for (i = 0; i < XLFD_SCL_LAST; i++)
6180 scl_val[i] = -1;
6181
6182 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
6183 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
6184 fonts are scaled according to the specified size. */
6185 ptr = pattern;
6186 i = 0;
6187 field = xlfd_scalable_fields;
6188 val = scl_val;
6189 if (*ptr == '-')
6190 do
6191 {
6192 ptr++;
6193 if (i == *field)
6194 {
6195 if ('1' <= *ptr && *ptr <= '9')
6196 {
6197 *val = *ptr++ - '0';
6198 while ('0' <= *ptr && *ptr <= '9' && *val < 10000)
6199 *val = *val * 10 + *ptr++ - '0';
6200 if (*ptr != '-')
6201 *val = -1;
6202 }
6203 field++;
6204 val++;
6205 }
6206 ptr = strchr (ptr, '-');
6207 i++;
6208 }
6209 while (ptr && i < 14);
6210
6211 if (i == 14 && ptr == NULL)
6212 {
6213 if (scl_val[XLFD_SCL_POINT_SIZE] > 0)
6214 {
6215 scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_POINT_SIZE] / 10;
6216 scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_POINT_SIZE];
6217 }
6218 else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0)
6219 {
6220 scl_val[XLFD_SCL_POINT_SIZE] =
6221 scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_PIXEL_SIZE] * 10;
6222 }
6223 else if (scl_val[XLFD_SCL_AVGWIDTH] > 0)
6224 {
6225 scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_AVGWIDTH] / 10;
6226 scl_val[XLFD_SCL_POINT_SIZE] = scl_val[XLFD_SCL_AVGWIDTH];
6227 }
6228 }
6229 else
6230 scl_val[XLFD_SCL_PIXEL_SIZE] = -1;
6231
6232 ptr = regex;
6233 *ptr++ = '^';
6234
6235 /* Turn pattern into a regexp and do a regexp match. */
6236 for (; *pattern; pattern++)
6237 {
6238 if (*pattern == '?')
6239 *ptr++ = '.';
6240 else if (*pattern == '*')
6241 {
6242 *ptr++ = '.';
6243 *ptr++ = '*';
6244 }
6245 else
6246 *ptr++ = tolower (*pattern);
6247 }
6248 *ptr = '$';
6249 *(ptr + 1) = '\0';
6250
6251 pattern_regex = build_string (regex);
6252
6253 for (i = 0; i < font_name_count; i++)
6254 {
6255 fontname = build_string (font_name_table[i]);
6256 if (fast_string_match (pattern_regex, fontname) >= 0)
6257 {
6258 font_list = Fcons (fontname, font_list);
6259
6260 n_fonts++;
6261 if (maxnames > 0 && n_fonts >= maxnames)
6262 break;
6263 }
6264 else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0
6265 && (ptr = strstr (font_name_table[i], "-0-0-75-75-m-0-")))
6266 {
6267 int former_len = ptr - font_name_table[i];
6268
6269 memcpy (scaled, font_name_table[i], former_len);
6270 sprintf (scaled + former_len,
6271 "-%d-%d-75-75-m-%d-%s",
6272 scl_val[XLFD_SCL_PIXEL_SIZE],
6273 scl_val[XLFD_SCL_POINT_SIZE],
6274 scl_val[XLFD_SCL_AVGWIDTH],
6275 ptr + sizeof ("-0-0-75-75-m-0-") - 1);
6276 fontname = build_string (scaled);
6277 if (fast_string_match (pattern_regex, fontname) >= 0)
6278 {
6279 font_list = Fcons (fontname, font_list);
6280
6281 n_fonts++;
6282 if (maxnames > 0 && n_fonts >= maxnames)
6283 break;
6284 }
6285 }
6286 }
6287 return font_list;
6288}
6289
5838/* Return a list of at most MAXNAMES font specs matching the one in 6290/* Return a list of at most MAXNAMES font specs matching the one in
5839 PATTERN. Cache matching fonts for patterns in 6291 PATTERN. Cache matching fonts for patterns in
5840 dpyinfo->name_list_element to avoid looking them up again by 6292 dpyinfo->name_list_element to avoid looking them up again by
@@ -5847,11 +6299,7 @@ x_list_fonts (struct frame *f,
5847 int size, 6299 int size,
5848 int maxnames) 6300 int maxnames)
5849{ 6301{
5850 char *ptnstr;
5851 Lisp_Object newlist = Qnil, tem, key; 6302 Lisp_Object newlist = Qnil, tem, key;
5852 int n_fonts = 0;
5853 int i;
5854 struct gcpro gcpro1, gcpro2;
5855 struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL; 6303 struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL;
5856 6304
5857 if (font_name_table == NULL) /* Initialize when first used. */ 6305 if (font_name_table == NULL) /* Initialize when first used. */
@@ -5870,27 +6318,10 @@ x_list_fonts (struct frame *f,
5870 } 6318 }
5871 } 6319 }
5872 6320
5873 ptnstr = SDATA (pattern); 6321 newlist = mac_do_list_fonts (SDATA (pattern), maxnames);
5874
5875 GCPRO2 (pattern, newlist);
5876
5877 /* Scan and matching bitmap fonts. */
5878 for (i = 0; i < font_name_count; i++)
5879 {
5880 if (mac_font_pattern_match (font_name_table[i], ptnstr))
5881 {
5882 newlist = Fcons (build_string (font_name_table[i]), newlist);
5883
5884 n_fonts++;
5885 if (maxnames > 0 && n_fonts >= maxnames)
5886 break;
5887 }
5888 }
5889 6322
5890 /* MAC_TODO: add code for matching outline fonts here */ 6323 /* MAC_TODO: add code for matching outline fonts here */
5891 6324
5892 UNGCPRO;
5893
5894 if (dpyinfo) 6325 if (dpyinfo)
5895 { 6326 {
5896 XSETCDR (dpyinfo->name_list_element, 6327 XSETCDR (dpyinfo->name_list_element,
@@ -6050,14 +6481,12 @@ XLoadQueryFont (Display *dpy, char *fontname)
6050 name = fontname; 6481 name = fontname;
6051 else 6482 else
6052 { 6483 {
6053 for (i = 0; i < font_name_count; i++) 6484 Lisp_Object matched_fonts;
6054 if (mac_font_pattern_match (font_name_table[i], fontname))
6055 break;
6056 6485
6057 if (i >= font_name_count) 6486 matched_fonts = mac_do_list_fonts (fontname, 1);
6058 return NULL; 6487 if (NILP (matched_fonts))
6059 6488 return NULL;
6060 name = font_name_table[i]; 6489 name = SDATA (XCAR (matched_fonts));
6061 } 6490 }
6062 6491
6063 GetPort (&port); /* save the current font number used */ 6492 GetPort (&port); /* save the current font number used */
@@ -6179,7 +6608,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
6179 for (c = 0x20; c <= 0xff; c++) 6608 for (c = 0x20; c <= 0xff; c++)
6180 { 6609 {
6181 font->per_char[c - 0x20] = font->max_bounds; 6610 font->per_char[c - 0x20] = font->max_bounds;
6182 font->per_char[c - 0x20].width = CharWidth (c); 6611 font->per_char[c - 0x20].width =
6612 font->per_char[c - 0x20].rbearing = CharWidth (c);
6183 } 6613 }
6184 } 6614 }
6185 } 6615 }
@@ -7833,14 +8263,32 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
7833 } 8263 }
7834 else 8264 else
7835 { 8265 {
7836 bufp->kind = MOUSE_CLICK_EVENT; 8266 Lisp_Object window;
8267
8268 bufp->kind = MOUSE_CLICK_EVENT;
7837 XSETFRAME (bufp->frame_or_window, mwp->mFP); 8269 XSETFRAME (bufp->frame_or_window, mwp->mFP);
7838 if (er.what == mouseDown) 8270 if (er.what == mouseDown)
7839 mouse_tracking_in_progress 8271 mouse_tracking_in_progress
7840 = mouse_tracking_mouse_movement; 8272 = mouse_tracking_mouse_movement;
7841 else 8273 else
7842 mouse_tracking_in_progress = mouse_tracking_none; 8274 mouse_tracking_in_progress = mouse_tracking_none;
7843 } 8275 window = window_from_coordinates (mwp->mFP, bufp->x, bufp->y, 0, 0, 0, 1);
8276
8277 if (EQ (window, mwp->mFP->tool_bar_window))
8278 {
8279 if (er.what == mouseDown)
8280 handle_tool_bar_click (mwp->mFP, bufp->x, bufp->y, 1, 0);
8281 else
8282 handle_tool_bar_click (mwp->mFP, bufp->x, bufp->y, 0,
8283#if USE_CARBON_EVENTS
8284 mac_event_to_emacs_modifiers (eventRef)
8285#else
8286 er.modifiers
8287#endif
8288 );
8289 break;
8290 }
8291 }
7844 8292
7845#if USE_CARBON_EVENTS 8293#if USE_CARBON_EVENTS
7846 bufp->modifiers = mac_event_to_emacs_modifiers (eventRef); 8294 bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
@@ -8352,12 +8800,16 @@ mac_initialize_display_info ()
8352 dpyinfo->reference_count = 0; 8800 dpyinfo->reference_count = 0;
8353 dpyinfo->resx = 75.0; 8801 dpyinfo->resx = 75.0;
8354 dpyinfo->resy = 75.0; 8802 dpyinfo->resy = 75.0;
8355 dpyinfo->n_planes = 1; 8803 dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
8356 dpyinfo->n_cbits = 16; 8804 for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
8805 if (HasDepth (main_device_handle, dpyinfo->n_planes,
8806 gdDevType, dpyinfo->color_p))
8807 break;
8357 dpyinfo->height = (**main_device_handle).gdRect.bottom; 8808 dpyinfo->height = (**main_device_handle).gdRect.bottom;
8358 dpyinfo->width = (**main_device_handle).gdRect.right; 8809 dpyinfo->width = (**main_device_handle).gdRect.right;
8359 dpyinfo->grabbed = 0; 8810 dpyinfo->grabbed = 0;
8360 dpyinfo->root_window = NULL; 8811 dpyinfo->root_window = NULL;
8812 dpyinfo->image_cache = make_image_cache ();
8361 8813
8362 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; 8814 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
8363 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; 8815 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
@@ -8696,6 +9148,18 @@ syms_of_macterm ()
8696 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); 9148 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop");
8697 staticpro (&Qmac_ready_for_drag_n_drop); 9149 staticpro (&Qmac_ready_for_drag_n_drop);
8698 9150
9151 Qbig5 = intern ("big5");
9152 staticpro (&Qbig5);
9153
9154 Qcn_gb = intern ("cn-gb");
9155 staticpro (&Qcn_gb);
9156
9157 Qsjis = intern ("sjis");
9158 staticpro (&Qsjis);
9159
9160 Qeuc_kr = intern ("euc-kr");
9161 staticpro (&Qeuc_kr);
9162
8699 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p, 9163 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p,
8700 doc: /* *Non-nil means autoselect window with mouse pointer. */); 9164 doc: /* *Non-nil means autoselect window with mouse pointer. */);
8701 x_autoselect_window_p = 0; 9165 x_autoselect_window_p = 0;
diff --git a/src/macterm.h b/src/macterm.h
index b3fe53c86ea..17b8a0fb298 100644
--- a/src/macterm.h
+++ b/src/macterm.h
@@ -23,45 +23,26 @@ Boston, MA 02111-1307, USA. */
23#include "macgui.h" 23#include "macgui.h"
24#include "frame.h" 24#include "frame.h"
25 25
26/* Include Carbon.h to define Cursor and Rect. */
27#ifdef HAVE_CARBON
28#undef mktime
29#undef DEBUG
30#undef Z
31#undef free
32#undef malloc
33#undef realloc
34/* Macros max and min defined in lisp.h conflict with those in
35 precompiled header Carbon.h. */
36#undef max
37#undef min
38#undef init_process
39#include <Carbon/Carbon.h>
40#undef Z
41#define Z (current_buffer->text->z)
42#undef free
43#define free unexec_free
44#undef malloc
45#define malloc unexec_malloc
46#undef realloc
47#define realloc unexec_realloc
48#undef min
49#define min(a, b) ((a) < (b) ? (a) : (b))
50#undef max
51#define max(a, b) ((a) > (b) ? (a) : (b))
52#undef init_process
53#define init_process emacs_init_process
54#endif /* MAC_OSX */
55
56#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b)) 26#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
57 27
58#define RED_FROM_ULONG(color) ((color) >> 16) 28#define RED_FROM_ULONG(color) ((color) >> 16)
59#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff) 29#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
60#define BLUE_FROM_ULONG(color) ((color) & 0xff) 30#define BLUE_FROM_ULONG(color) ((color) & 0xff)
61 31
32/* Do not change `* 0x101' in the following lines to `<< 8'. If
33 changed, image masks in 1-bit depth will not work. */
34#define RED16_FROM_ULONG(color) (RED_FROM_ULONG(color) * 0x101)
35#define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG(color) * 0x101)
36#define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG(color) * 0x101)
37
62#define BLACK_PIX_DEFAULT(f) RGB_TO_ULONG(0,0,0) 38#define BLACK_PIX_DEFAULT(f) RGB_TO_ULONG(0,0,0)
63#define WHITE_PIX_DEFAULT(f) RGB_TO_ULONG(255,255,255) 39#define WHITE_PIX_DEFAULT(f) RGB_TO_ULONG(255,255,255)
64 40
41/* A black pixel in a mask bitmap/pixmap means ``draw a source
42 pixel''. A white pixel means ``retain the current pixel''. */
43#define PIX_MASK_DRAW(f) BLACK_PIX_DEFAULT(f)
44#define PIX_MASK_RETAIN(f) WHITE_PIX_DEFAULT(f)
45
65#define FONT_WIDTH(f) ((f)->max_bounds.width) 46#define FONT_WIDTH(f) ((f)->max_bounds.width)
66#define FONT_HEIGHT(f) ((f)->ascent + (f)->descent) 47#define FONT_HEIGHT(f) ((f)->ascent + (f)->descent)
67#define FONT_BASE(f) ((f)->ascent) 48#define FONT_BASE(f) ((f)->ascent)
@@ -101,8 +82,13 @@ struct mac_display_info
101 /* Number of planes on this screen. */ 82 /* Number of planes on this screen. */
102 int n_planes; 83 int n_planes;
103 84
85 /* Whether the screen supports color */
86 int color_p;
87
88#if 0
104 /* Number of bits per pixel on this screen. */ 89 /* Number of bits per pixel on this screen. */
105 int n_cbits; 90 int n_cbits;
91#endif
106 92
107 /* Dimensions of this screen. */ 93 /* Dimensions of this screen. */
108 int height, width; 94 int height, width;
diff --git a/src/s/darwin.h b/src/s/darwin.h
index abc56901e17..814de2c2c51 100644
--- a/src/s/darwin.h
+++ b/src/s/darwin.h
@@ -247,7 +247,7 @@ Boston, MA 02111-1307, USA. */
247 page) to leave room at the end of the header for adding load 247 page) to leave room at the end of the header for adding load
248 commands. Needed for dumping. 0x690 is the total size of 30 248 commands. Needed for dumping. 0x690 is the total size of 30
249 segment load commands (at 56 each). */ 249 segment load commands (at 56 each). */
250#define LD_SWITCH_SYSTEM_TEMACS -prebind -framework Carbon -lstdc++ -Xlinker -headerpad -Xlinker 690 250#define LD_SWITCH_SYSTEM_TEMACS -prebind -framework Carbon -framework QuickTime -lstdc++ -Xlinker -headerpad -Xlinker 690
251 251
252#define C_SWITCH_SYSTEM_TEMACS -Dtemacs 252#define C_SWITCH_SYSTEM_TEMACS -Dtemacs
253 253