1 /* Graphical user interface functions for Mac OS.
2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Contributed by Andrew Choi (akochoi@mac.com). */
37 #include "dispextern.h"
39 #include "intervals.h"
41 #include "blockinput.h"
43 #include "termhooks.h"
48 /* #include "bitmaps/gray.xbm" */
51 static unsigned char gray_bits
[] = {
54 /*#include <commdlg.h>
55 #include <shellapi.h>*/
71 /* Macros max and min defined in lisp.h conflict with those in
72 precompiled header Carbon.h. */
76 #include <Carbon/Carbon.h>
78 #define Z (current_buffer->text->z)
80 #define free unexec_free
82 #define malloc unexec_malloc
84 #define realloc unexec_realloc
86 #define min(a, b) ((a) < (b) ? (a) : (b))
88 #define max(a, b) ((a) > (b) ? (a) : (b))
90 #define init_process emacs_init_process
91 #else /* not MAC_OSX */
94 #include <TextUtils.h>
95 #endif /* not MAC_OSX */
97 /*extern void free_frame_menubar ();
98 extern double atof ();
99 extern int w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state);
100 extern int quit_char;*/
102 extern char *lispy_function_keys
[];
104 /* The gray bitmap `bitmaps/gray'. This is done because macterm.c uses
105 it, and including `bitmaps/gray' more than once is a problem when
106 config.h defines `static' as an empty replacement string. */
108 int gray_bitmap_width
= gray_width
;
109 int gray_bitmap_height
= gray_height
;
110 unsigned char *gray_bitmap_bits
= gray_bits
;
112 /* Non-zero means we're allowed to display an hourglass cursor. */
114 int display_hourglass_p
;
116 /* The background and shape of the mouse pointer, and shape when not
117 over text or in the modeline. */
119 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
120 Lisp_Object Vx_hourglass_pointer_shape
;
122 /* The shape when over mouse-sensitive text. */
124 Lisp_Object Vx_sensitive_text_pointer_shape
;
126 /* If non-nil, the pointer shape to indicate that windows can be
127 dragged horizontally. */
129 Lisp_Object Vx_window_horizontal_drag_shape
;
131 /* Color of chars displayed in cursor box. */
133 Lisp_Object Vx_cursor_fore_pixel
;
135 /* Nonzero if using Windows. */
137 static int mac_in_use
;
139 /* Non nil if no window manager is in use. */
141 Lisp_Object Vx_no_window_manager
;
143 /* Search path for bitmap files. */
145 Lisp_Object Vx_bitmap_file_path
;
147 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
149 Lisp_Object Vx_pixel_size_width_font_regexp
;
151 /* Evaluate this expression to rebuild the section of syms_of_macfns
152 that initializes and staticpros the symbols declared below. Note
153 that Emacs 18 has a bug that keeps C-x C-e from being able to
154 evaluate this expression.
157 ;; Accumulate a list of the symbols we want to initialize from the
158 ;; declarations at the top of the file.
159 (goto-char (point-min))
160 (search-forward "/\*&&& symbols declared here &&&*\/\n")
162 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
164 (cons (buffer-substring (match-beginning 1) (match-end 1))
167 (setq symbol-list (nreverse symbol-list))
168 ;; Delete the section of syms_of_... where we initialize the symbols.
169 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
170 (let ((start (point)))
171 (while (looking-at "^ Q")
173 (kill-region start (point)))
174 ;; Write a new symbol initialization section.
176 (insert (format " %s = intern (\"" (car symbol-list)))
177 (let ((start (point)))
178 (insert (substring (car symbol-list) 1))
179 (subst-char-in-region start (point) ?_ ?-))
180 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
181 (setq symbol-list (cdr symbol-list)))))
185 /*&&& symbols declared here &&&*/
187 Lisp_Object Qsuppress_icon
;
188 Lisp_Object Qundefined_color
;
190 Lisp_Object Qcancel_timer
;
196 Lisp_Object Qcontrol
;
199 extern Lisp_Object Vwindow_system_version
;
201 extern int mac_initialized
;
203 /* Functions in macterm.c. */
204 extern void x_set_window_size (struct frame
*, int, int, int);
205 extern void x_make_frame_visible (struct frame
*);
206 extern struct mac_display_info
*mac_term_init (Lisp_Object
, char *, char *);
207 extern struct font_info
*x_get_font_info (FRAME_PTR
, int);
208 extern struct font_info
*x_load_font (struct frame
*, char *, int);
209 extern void x_find_ccl_program (struct font_info
*);
210 extern struct font_info
*x_query_font (struct frame
*, char *);
211 extern void mac_initialize ();
213 /* compare two strings ignoring case */
216 stricmp (const char *s
, const char *t
)
218 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
221 return tolower (*s
) - tolower (*t
);
224 /* compare two strings up to n characters, ignoring case */
227 strnicmp (const char *s
, const char *t
, unsigned int n
)
229 for ( ; n
-- > 0 && tolower (*s
) == tolower (*t
); s
++, t
++)
232 return n
== 0 ? 0 : tolower (*s
) - tolower (*t
);
236 /* Error if we are not running on Mac OS. */
242 error ("Mac OS not in use or not initialized");
245 /* Nonzero if we can use mouse menus.
246 You should not call this unless HAVE_MENUS is defined. */
254 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
255 and checking validity for Mac. */
258 check_x_frame (frame
)
264 frame
= selected_frame
;
265 CHECK_LIVE_FRAME (frame
);
267 if (! FRAME_MAC_P (f
))
268 error ("non-mac frame used");
272 /* Let the user specify a display with a frame.
273 nil stands for the selected frame--or, if that is not a mac frame,
274 the first display on the list. */
276 struct mac_display_info
*
277 check_x_display_info (frame
)
280 if (!mac_initialized
)
288 struct frame
*sf
= XFRAME (selected_frame
);
290 if (FRAME_MAC_P (sf
) && FRAME_LIVE_P (sf
))
291 return FRAME_MAC_DISPLAY_INFO (sf
);
293 return &one_mac_display_info
;
295 else if (STRINGP (frame
))
296 return x_display_info_for_name (frame
);
301 CHECK_LIVE_FRAME (frame
);
303 if (! FRAME_MAC_P (f
))
304 error ("non-mac frame used");
305 return FRAME_MAC_DISPLAY_INFO (f
);
309 /* Return the Emacs frame-object corresponding to a mac window.
310 It could be the frame's main window or an icon window. */
312 /* This function can be called during GC, so use GC_xxx type test macros. */
315 x_window_to_frame (dpyinfo
, wdesc
)
316 struct mac_display_info
*dpyinfo
;
319 Lisp_Object tail
, frame
;
322 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
325 if (!GC_FRAMEP (frame
))
328 if (!FRAME_W32_P (f
) || FRAME_MAC_DISPLAY_INFO (f
) != dpyinfo
)
330 /*if (f->output_data.w32->hourglass_window == wdesc)
333 /* MAC_TODO: Check tooltips when supported. */
334 if (FRAME_MAC_WINDOW (f
) == wdesc
)
342 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
343 id, which is just an int that this section returns. Bitmaps are
344 reference counted so they can be shared among frames.
346 Bitmap indices are guaranteed to be > 0, so a negative number can
347 be used to indicate no bitmap.
349 If you use x_create_bitmap_from_data, then you must keep track of
350 the bitmaps yourself. That is, creating a bitmap from the same
351 data more than once will not be caught. */
354 /* Functions to access the contents of a bitmap, given an id. */
357 x_bitmap_height (f
, id
)
361 return FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
365 x_bitmap_width (f
, id
)
369 return FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
372 #if 0 /* MAC_TODO : not used anywhere (?) */
374 x_bitmap_pixmap (f
, id
)
378 return (int) FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
382 /* Allocate a new bitmap record. Returns index of new record. */
385 x_allocate_bitmap_record (f
)
388 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
391 if (dpyinfo
->bitmaps
== NULL
)
393 dpyinfo
->bitmaps_size
= 10;
394 dpyinfo
->bitmaps
= (struct mac_bitmap_record
*)
395 xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct mac_bitmap_record
));
396 dpyinfo
->bitmaps_last
= 1;
400 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
401 return ++dpyinfo
->bitmaps_last
;
403 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
404 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
407 dpyinfo
->bitmaps_size
*= 2;
408 dpyinfo
->bitmaps
= (struct mac_bitmap_record
*)
409 xrealloc (dpyinfo
->bitmaps
,
410 dpyinfo
->bitmaps_size
* sizeof (struct mac_bitmap_record
));
411 return ++dpyinfo
->bitmaps_last
;
414 /* Add one reference to the reference count of the bitmap with id
418 x_reference_bitmap (f
, id
)
422 ++FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
425 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at
429 x_create_bitmap_from_data (f
, bits
, width
, height
)
432 unsigned int width
, height
;
434 struct x_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
437 /* MAC_TODO: for now fail if width is not mod 16 (toolbox requires it) */
439 id
= x_allocate_bitmap_record (f
);
444 dpyinfo
->bitmaps
[id
- 1].bitmap_data
= (char *) xmalloc (height
* width
);
445 if (! dpyinfo
->bitmaps
[id
- 1].bitmap_data
)
448 bcopy (bits
, dpyinfo
->bitmaps
[id
- 1].bitmap_data
, height
* width
);
450 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
451 dpyinfo
->bitmaps
[id
- 1].height
= height
;
452 dpyinfo
->bitmaps
[id
- 1].width
= width
;
457 /* Create bitmap from file FILE for frame F. */
460 x_create_bitmap_from_file (f
, file
)
465 #if 0 /* MAC_TODO : bitmap support */
466 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
467 unsigned int width
, height
;
469 int xhot
, yhot
, result
, id
;
475 /* Look for an existing bitmap with the same name. */
476 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
478 if (dpyinfo
->bitmaps
[id
].refcount
479 && dpyinfo
->bitmaps
[id
].file
480 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
482 ++dpyinfo
->bitmaps
[id
].refcount
;
487 /* Search bitmap-file-path for the file, if appropriate. */
488 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, Qnil
);
491 /* LoadLibraryEx won't handle special files handled by Emacs handler. */
496 filename
= (char *) SDATA (found
);
498 hinst
= LoadLibraryEx (filename
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
504 result
= XReadBitmapFile (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
505 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
506 if (result
!= BitmapSuccess
)
509 id
= x_allocate_bitmap_record (f
);
510 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
511 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
512 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SCHARS (file
) + 1);
513 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
514 dpyinfo
->bitmaps
[id
- 1].height
= height
;
515 dpyinfo
->bitmaps
[id
- 1].width
= width
;
516 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
519 #endif /* MAC_TODO */
522 /* Remove reference to bitmap with id number ID. */
525 x_destroy_bitmap (f
, id
)
529 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
533 --dpyinfo
->bitmaps
[id
- 1].refcount
;
534 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
537 dpyinfo
->bitmaps
[id
- 1].bitmap_data
= NULL
;
543 /* Free all the bitmaps for the display specified by DPYINFO. */
546 x_destroy_all_bitmaps (dpyinfo
)
547 struct mac_display_info
*dpyinfo
;
550 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
551 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
552 xfree (dpyinfo
->bitmaps
[i
].bitmap_data
);
553 dpyinfo
->bitmaps_last
= 0;
556 /* Connect the frame-parameter names for W32 frames
557 to the ways of passing the parameter values to the window system.
559 The name of a parameter, as a Lisp symbol,
560 has an `x-frame-parameter' property which is an integer in Lisp
561 but can be interpreted as an `enum x_frame_parm' in C. */
563 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
564 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
565 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
566 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
567 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
568 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
569 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
570 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
571 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
572 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
573 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
574 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
575 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
577 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
579 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
585 /* Store the screen positions of frame F into XPTR and YPTR.
586 These are the positions of the containing window manager window,
587 not Emacs's own window. */
590 x_real_positions (f
, xptr
, yptr
)
597 #ifdef TARGET_API_MAC_CARBON
601 GetWindowPortBounds (f
->output_data
.mac
->mWP
, &r
);
602 SetPt (&pt
, r
.left
, r
.top
);
604 #else /* not TARGET_API_MAC_CARBON */
606 f
->output_data
.mac
->mWP
->portRect
.left
,
607 f
->output_data
.mac
->mWP
->portRect
.top
);
608 #endif /* not TARGET_API_MAC_CARBON */
618 /* The default colors for the Mac color map */
619 typedef struct colormap_t
625 colormap_t mac_color_map
[] =
627 { RGB_TO_ULONG(255, 250, 250), "snow" },
628 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
629 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
630 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
631 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
632 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
633 { RGB_TO_ULONG(255, 250, 240), "floral white" },
634 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
635 { RGB_TO_ULONG(253, 245, 230), "old lace" },
636 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
637 { RGB_TO_ULONG(250, 240, 230), "linen" },
638 { RGB_TO_ULONG(250, 235, 215), "antique white" },
639 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
640 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
641 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
642 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
643 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
644 { RGB_TO_ULONG(255, 228, 196), "bisque" },
645 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
646 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
647 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
648 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
649 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
650 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
651 { RGB_TO_ULONG(255, 255, 240), "ivory" },
652 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
653 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
654 { RGB_TO_ULONG(255, 245, 238), "seashell" },
655 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
656 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
657 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
658 { RGB_TO_ULONG(240, 255, 255), "azure" },
659 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
660 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
661 { RGB_TO_ULONG(230, 230, 250), "lavender" },
662 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
663 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
664 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
665 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
666 { RGB_TO_ULONG(255, 255, 255), "white" },
667 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
668 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
669 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
670 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
671 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
672 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
673 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
674 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
675 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
676 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
677 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
678 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
679 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
680 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
681 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
682 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
683 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
684 { RGB_TO_ULONG(190, 190, 190), "gray" },
685 { RGB_TO_ULONG(190, 190, 190), "grey" },
686 { RGB_TO_ULONG(211, 211, 211), "light grey" },
687 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
688 { RGB_TO_ULONG(211, 211, 211), "light gray" },
689 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
690 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
691 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
692 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
693 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
694 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
695 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
696 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
697 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
698 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
699 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
700 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
701 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
702 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
703 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
704 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
705 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
706 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
707 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
708 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
709 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
710 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
711 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
712 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
713 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
714 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
715 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
716 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
717 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
718 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
719 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
720 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
721 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
722 { RGB_TO_ULONG(173, 216, 230), "light blue" },
723 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
724 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
725 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
726 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
727 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
728 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
729 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
730 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
731 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
732 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
733 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
734 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
735 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
736 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
737 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
738 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
739 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
740 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
741 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
742 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
743 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
744 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
745 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
746 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
747 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
748 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
749 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
750 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
751 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
752 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
753 { RGB_TO_ULONG(152, 251, 152), "pale green" },
754 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
755 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
756 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
757 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
758 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
759 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
760 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
761 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
762 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
763 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
764 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
765 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
766 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
767 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
768 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
769 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
770 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
771 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
772 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
773 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
774 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
775 { RGB_TO_ULONG(240, 230, 140), "khaki" },
776 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
777 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
778 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
779 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
780 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
781 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
782 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
783 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
784 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
785 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
786 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
787 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
788 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
789 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
790 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
791 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
792 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
793 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
794 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
795 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
796 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
797 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
798 { RGB_TO_ULONG(245, 245, 220), "beige" },
799 { RGB_TO_ULONG(245, 222, 179), "wheat" },
800 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
801 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
802 { RGB_TO_ULONG(210, 180, 140), "tan" },
803 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
804 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
805 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
806 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
807 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
808 { RGB_TO_ULONG(250, 128, 114), "salmon" },
809 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
810 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
811 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
812 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
813 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
814 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
815 { RGB_TO_ULONG(240, 128, 128), "light coral" },
816 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
817 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
818 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
819 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
820 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
821 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
822 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
823 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
824 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
825 { RGB_TO_ULONG(255, 192, 203), "pink" },
826 { RGB_TO_ULONG(255, 182, 193), "light pink" },
827 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
828 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
829 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
830 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
831 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
832 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
833 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
834 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
835 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
836 { RGB_TO_ULONG(238, 130, 238), "violet" },
837 { RGB_TO_ULONG(221, 160, 221), "plum" },
838 { RGB_TO_ULONG(218, 112, 214), "orchid" },
839 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
840 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
841 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
842 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
843 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
844 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
845 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
846 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
847 { RGB_TO_ULONG(160, 32 , 240), "purple" },
848 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
849 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
850 { RGB_TO_ULONG(216, 191, 216), "thistle" },
851 { RGB_TO_ULONG(255, 250, 250), "snow1" },
852 { RGB_TO_ULONG(238, 233, 233), "snow2" },
853 { RGB_TO_ULONG(205, 201, 201), "snow3" },
854 { RGB_TO_ULONG(139, 137, 137), "snow4" },
855 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
856 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
857 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
858 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
859 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
860 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
861 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
862 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
863 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
864 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
865 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
866 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
867 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
868 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
869 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
870 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
871 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
872 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
873 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
874 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
875 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
876 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
877 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
878 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
879 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
880 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
881 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
882 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
883 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
884 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
885 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
886 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
887 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
888 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
889 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
890 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
891 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
892 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
893 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
894 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
895 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
896 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
897 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
898 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
899 { RGB_TO_ULONG(240, 255, 255), "azure1" },
900 { RGB_TO_ULONG(224, 238, 238), "azure2" },
901 { RGB_TO_ULONG(193, 205, 205), "azure3" },
902 { RGB_TO_ULONG(131, 139, 139), "azure4" },
903 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
904 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
905 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
906 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
907 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
908 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
909 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
910 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
911 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
912 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
913 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
914 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
915 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
916 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
917 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
918 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
919 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
920 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
921 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
922 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
923 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
924 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
925 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
926 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
927 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
928 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
929 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
930 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
931 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
932 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
933 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
934 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
935 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
936 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
937 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
938 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
939 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
940 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
941 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
942 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
943 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
944 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
945 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
946 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
947 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
948 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
949 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
950 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
951 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
952 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
953 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
954 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
955 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
956 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
957 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
958 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
959 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
960 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
961 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
962 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
963 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
964 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
965 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
966 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
967 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
968 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
969 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
970 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
971 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
972 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
973 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
974 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
975 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
976 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
977 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
978 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
979 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
980 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
981 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
982 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
983 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
984 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
985 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
986 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
987 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
988 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
989 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
990 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
991 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
992 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
993 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
994 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
995 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
996 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
997 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
998 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
999 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
1000 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
1001 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
1002 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
1003 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
1004 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
1005 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
1006 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
1007 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
1008 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
1009 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
1010 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
1011 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
1012 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
1013 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
1014 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
1015 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
1016 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
1017 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
1018 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
1019 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
1020 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
1021 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
1022 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
1023 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
1024 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
1025 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
1026 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
1027 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
1028 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
1029 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
1030 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
1031 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
1032 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
1033 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
1034 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
1035 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
1036 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
1037 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
1038 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
1039 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
1040 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
1041 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
1042 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
1043 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
1044 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
1045 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
1046 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
1047 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
1048 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
1049 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
1050 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
1051 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
1052 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
1053 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
1054 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
1055 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
1056 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
1057 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
1058 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
1059 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
1060 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
1061 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
1062 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
1063 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
1064 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
1065 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
1066 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
1067 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
1068 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
1069 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
1070 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
1071 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
1072 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
1073 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
1074 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
1075 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
1076 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
1077 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
1078 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
1079 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
1080 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
1081 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
1082 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
1083 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
1084 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
1085 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
1086 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
1087 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
1088 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
1089 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
1090 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
1091 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
1092 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
1093 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
1094 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
1095 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
1096 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
1097 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
1098 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
1099 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
1100 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
1101 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
1102 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
1103 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
1104 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
1105 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
1106 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
1107 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
1108 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
1109 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
1110 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
1111 { RGB_TO_ULONG(255, 181, 197), "pink1" },
1112 { RGB_TO_ULONG(238, 169, 184), "pink2" },
1113 { RGB_TO_ULONG(205, 145, 158), "pink3" },
1114 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
1115 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
1116 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
1117 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
1118 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
1119 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
1120 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
1121 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
1122 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
1123 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
1124 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
1125 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
1126 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
1127 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
1128 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
1129 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
1130 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
1131 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
1132 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
1133 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
1134 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
1135 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
1136 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
1137 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
1138 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
1139 { RGB_TO_ULONG(255, 187, 255), "plum1" },
1140 { RGB_TO_ULONG(238, 174, 238), "plum2" },
1141 { RGB_TO_ULONG(205, 150, 205), "plum3" },
1142 { RGB_TO_ULONG(139, 102, 139), "plum4" },
1143 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
1144 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
1145 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
1146 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
1147 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
1148 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
1149 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
1150 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
1151 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
1152 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
1153 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
1154 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
1155 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
1156 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
1157 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
1158 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
1159 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
1160 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
1161 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
1162 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
1163 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
1164 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
1165 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
1166 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
1167 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
1168 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
1169 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
1170 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
1171 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
1172 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
1173 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
1174 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
1175 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
1176 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
1177 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
1178 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
1179 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
1180 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
1181 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
1182 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
1183 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
1184 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
1185 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
1186 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
1187 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
1188 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
1189 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
1190 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
1191 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
1192 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
1193 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
1194 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
1195 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
1196 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
1197 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
1198 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
1199 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
1200 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
1201 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
1202 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
1203 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
1204 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
1205 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
1206 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
1207 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
1208 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
1209 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
1210 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
1211 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
1212 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
1213 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
1214 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
1215 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
1216 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
1217 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
1218 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
1219 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
1220 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
1221 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
1222 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
1223 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
1224 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
1225 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
1226 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
1227 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
1228 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
1229 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
1230 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
1231 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
1232 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
1233 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
1234 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
1235 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
1236 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
1237 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
1238 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
1239 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
1240 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
1241 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
1242 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
1243 { RGB_TO_ULONG(102, 102, 102), "gray40" },
1244 { RGB_TO_ULONG(102, 102, 102), "grey40" },
1245 { RGB_TO_ULONG(105, 105, 105), "gray41" },
1246 { RGB_TO_ULONG(105, 105, 105), "grey41" },
1247 { RGB_TO_ULONG(107, 107, 107), "gray42" },
1248 { RGB_TO_ULONG(107, 107, 107), "grey42" },
1249 { RGB_TO_ULONG(110, 110, 110), "gray43" },
1250 { RGB_TO_ULONG(110, 110, 110), "grey43" },
1251 { RGB_TO_ULONG(112, 112, 112), "gray44" },
1252 { RGB_TO_ULONG(112, 112, 112), "grey44" },
1253 { RGB_TO_ULONG(115, 115, 115), "gray45" },
1254 { RGB_TO_ULONG(115, 115, 115), "grey45" },
1255 { RGB_TO_ULONG(117, 117, 117), "gray46" },
1256 { RGB_TO_ULONG(117, 117, 117), "grey46" },
1257 { RGB_TO_ULONG(120, 120, 120), "gray47" },
1258 { RGB_TO_ULONG(120, 120, 120), "grey47" },
1259 { RGB_TO_ULONG(122, 122, 122), "gray48" },
1260 { RGB_TO_ULONG(122, 122, 122), "grey48" },
1261 { RGB_TO_ULONG(125, 125, 125), "gray49" },
1262 { RGB_TO_ULONG(125, 125, 125), "grey49" },
1263 { RGB_TO_ULONG(127, 127, 127), "gray50" },
1264 { RGB_TO_ULONG(127, 127, 127), "grey50" },
1265 { RGB_TO_ULONG(130, 130, 130), "gray51" },
1266 { RGB_TO_ULONG(130, 130, 130), "grey51" },
1267 { RGB_TO_ULONG(133, 133, 133), "gray52" },
1268 { RGB_TO_ULONG(133, 133, 133), "grey52" },
1269 { RGB_TO_ULONG(135, 135, 135), "gray53" },
1270 { RGB_TO_ULONG(135, 135, 135), "grey53" },
1271 { RGB_TO_ULONG(138, 138, 138), "gray54" },
1272 { RGB_TO_ULONG(138, 138, 138), "grey54" },
1273 { RGB_TO_ULONG(140, 140, 140), "gray55" },
1274 { RGB_TO_ULONG(140, 140, 140), "grey55" },
1275 { RGB_TO_ULONG(143, 143, 143), "gray56" },
1276 { RGB_TO_ULONG(143, 143, 143), "grey56" },
1277 { RGB_TO_ULONG(145, 145, 145), "gray57" },
1278 { RGB_TO_ULONG(145, 145, 145), "grey57" },
1279 { RGB_TO_ULONG(148, 148, 148), "gray58" },
1280 { RGB_TO_ULONG(148, 148, 148), "grey58" },
1281 { RGB_TO_ULONG(150, 150, 150), "gray59" },
1282 { RGB_TO_ULONG(150, 150, 150), "grey59" },
1283 { RGB_TO_ULONG(153, 153, 153), "gray60" },
1284 { RGB_TO_ULONG(153, 153, 153), "grey60" },
1285 { RGB_TO_ULONG(156, 156, 156), "gray61" },
1286 { RGB_TO_ULONG(156, 156, 156), "grey61" },
1287 { RGB_TO_ULONG(158, 158, 158), "gray62" },
1288 { RGB_TO_ULONG(158, 158, 158), "grey62" },
1289 { RGB_TO_ULONG(161, 161, 161), "gray63" },
1290 { RGB_TO_ULONG(161, 161, 161), "grey63" },
1291 { RGB_TO_ULONG(163, 163, 163), "gray64" },
1292 { RGB_TO_ULONG(163, 163, 163), "grey64" },
1293 { RGB_TO_ULONG(166, 166, 166), "gray65" },
1294 { RGB_TO_ULONG(166, 166, 166), "grey65" },
1295 { RGB_TO_ULONG(168, 168, 168), "gray66" },
1296 { RGB_TO_ULONG(168, 168, 168), "grey66" },
1297 { RGB_TO_ULONG(171, 171, 171), "gray67" },
1298 { RGB_TO_ULONG(171, 171, 171), "grey67" },
1299 { RGB_TO_ULONG(173, 173, 173), "gray68" },
1300 { RGB_TO_ULONG(173, 173, 173), "grey68" },
1301 { RGB_TO_ULONG(176, 176, 176), "gray69" },
1302 { RGB_TO_ULONG(176, 176, 176), "grey69" },
1303 { RGB_TO_ULONG(179, 179, 179), "gray70" },
1304 { RGB_TO_ULONG(179, 179, 179), "grey70" },
1305 { RGB_TO_ULONG(181, 181, 181), "gray71" },
1306 { RGB_TO_ULONG(181, 181, 181), "grey71" },
1307 { RGB_TO_ULONG(184, 184, 184), "gray72" },
1308 { RGB_TO_ULONG(184, 184, 184), "grey72" },
1309 { RGB_TO_ULONG(186, 186, 186), "gray73" },
1310 { RGB_TO_ULONG(186, 186, 186), "grey73" },
1311 { RGB_TO_ULONG(189, 189, 189), "gray74" },
1312 { RGB_TO_ULONG(189, 189, 189), "grey74" },
1313 { RGB_TO_ULONG(191, 191, 191), "gray75" },
1314 { RGB_TO_ULONG(191, 191, 191), "grey75" },
1315 { RGB_TO_ULONG(194, 194, 194), "gray76" },
1316 { RGB_TO_ULONG(194, 194, 194), "grey76" },
1317 { RGB_TO_ULONG(196, 196, 196), "gray77" },
1318 { RGB_TO_ULONG(196, 196, 196), "grey77" },
1319 { RGB_TO_ULONG(199, 199, 199), "gray78" },
1320 { RGB_TO_ULONG(199, 199, 199), "grey78" },
1321 { RGB_TO_ULONG(201, 201, 201), "gray79" },
1322 { RGB_TO_ULONG(201, 201, 201), "grey79" },
1323 { RGB_TO_ULONG(204, 204, 204), "gray80" },
1324 { RGB_TO_ULONG(204, 204, 204), "grey80" },
1325 { RGB_TO_ULONG(207, 207, 207), "gray81" },
1326 { RGB_TO_ULONG(207, 207, 207), "grey81" },
1327 { RGB_TO_ULONG(209, 209, 209), "gray82" },
1328 { RGB_TO_ULONG(209, 209, 209), "grey82" },
1329 { RGB_TO_ULONG(212, 212, 212), "gray83" },
1330 { RGB_TO_ULONG(212, 212, 212), "grey83" },
1331 { RGB_TO_ULONG(214, 214, 214), "gray84" },
1332 { RGB_TO_ULONG(214, 214, 214), "grey84" },
1333 { RGB_TO_ULONG(217, 217, 217), "gray85" },
1334 { RGB_TO_ULONG(217, 217, 217), "grey85" },
1335 { RGB_TO_ULONG(219, 219, 219), "gray86" },
1336 { RGB_TO_ULONG(219, 219, 219), "grey86" },
1337 { RGB_TO_ULONG(222, 222, 222), "gray87" },
1338 { RGB_TO_ULONG(222, 222, 222), "grey87" },
1339 { RGB_TO_ULONG(224, 224, 224), "gray88" },
1340 { RGB_TO_ULONG(224, 224, 224), "grey88" },
1341 { RGB_TO_ULONG(227, 227, 227), "gray89" },
1342 { RGB_TO_ULONG(227, 227, 227), "grey89" },
1343 { RGB_TO_ULONG(229, 229, 229), "gray90" },
1344 { RGB_TO_ULONG(229, 229, 229), "grey90" },
1345 { RGB_TO_ULONG(232, 232, 232), "gray91" },
1346 { RGB_TO_ULONG(232, 232, 232), "grey91" },
1347 { RGB_TO_ULONG(235, 235, 235), "gray92" },
1348 { RGB_TO_ULONG(235, 235, 235), "grey92" },
1349 { RGB_TO_ULONG(237, 237, 237), "gray93" },
1350 { RGB_TO_ULONG(237, 237, 237), "grey93" },
1351 { RGB_TO_ULONG(240, 240, 240), "gray94" },
1352 { RGB_TO_ULONG(240, 240, 240), "grey94" },
1353 { RGB_TO_ULONG(242, 242, 242), "gray95" },
1354 { RGB_TO_ULONG(242, 242, 242), "grey95" },
1355 { RGB_TO_ULONG(245, 245, 245), "gray96" },
1356 { RGB_TO_ULONG(245, 245, 245), "grey96" },
1357 { RGB_TO_ULONG(247, 247, 247), "gray97" },
1358 { RGB_TO_ULONG(247, 247, 247), "grey97" },
1359 { RGB_TO_ULONG(250, 250, 250), "gray98" },
1360 { RGB_TO_ULONG(250, 250, 250), "grey98" },
1361 { RGB_TO_ULONG(252, 252, 252), "gray99" },
1362 { RGB_TO_ULONG(252, 252, 252), "grey99" },
1363 { RGB_TO_ULONG(255, 255, 255), "gray100" },
1364 { RGB_TO_ULONG(255, 255, 255), "grey100" },
1365 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
1366 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
1367 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
1368 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
1369 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
1370 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
1371 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
1372 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
1373 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
1374 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
1375 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
1376 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1377 { RGB_TO_ULONG(144, 238, 144), "light green" },
1378 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1382 mac_color_map_lookup (colorname
)
1385 Lisp_Object ret
= Qnil
;
1390 for (i
= 0; i
< sizeof (mac_color_map
) / sizeof (mac_color_map
[0]); i
++)
1391 if (stricmp (colorname
, mac_color_map
[i
].name
) == 0)
1393 ret
= mac_color_map
[i
].color
;
1403 x_to_mac_color (colorname
)
1406 register Lisp_Object tail
, ret
= Qnil
;
1410 if (colorname
[0] == '#')
1412 /* Could be an old-style RGB Device specification. */
1415 color
= colorname
+ 1;
1417 size
= strlen(color
);
1418 if (size
== 3 || size
== 6 || size
== 9 || size
== 12)
1420 unsigned long colorval
;
1426 for (i
= 0; i
< 3; i
++)
1430 unsigned long value
;
1432 /* The check for 'x' in the following conditional takes into
1433 account the fact that strtol allows a "0x" in front of
1434 our numbers, and we don't. */
1435 if (!isxdigit(color
[0]) || color
[1] == 'x')
1439 value
= strtoul(color
, &end
, 16);
1441 if (errno
== ERANGE
|| end
- color
!= size
)
1446 value
= value
* 0x10;
1457 colorval
|= (value
<< pos
);
1468 else if (strnicmp(colorname
, "rgb:", 4) == 0)
1471 unsigned long colorval
;
1476 color
= colorname
+ 4;
1477 for (i
= 0; i
< 3; i
++)
1480 unsigned long value
;
1482 /* The check for 'x' in the following conditional takes into
1483 account the fact that strtol allows a "0x" in front of
1484 our numbers, and we don't. */
1485 if (!isxdigit(color
[0]) || color
[1] == 'x')
1487 value
= strtoul(color
, &end
, 16);
1488 if (errno
== ERANGE
)
1490 switch (end
- color
)
1493 value
= value
* 0x10 + value
;
1506 if (value
== ULONG_MAX
)
1508 colorval
|= (value
<< pos
);
1522 else if (strnicmp(colorname
, "rgbi:", 5) == 0)
1524 /* This is an RGB Intensity specification. */
1526 unsigned long colorval
;
1531 color
= colorname
+ 5;
1532 for (i
= 0; i
< 3; i
++)
1538 value
= strtod(color
, &end
);
1539 if (errno
== ERANGE
)
1541 if (value
< 0.0 || value
> 1.0)
1543 val
= (unsigned long)(0x100 * value
);
1544 /* We used 0x100 instead of 0xFF to give a continuous
1545 range between 0.0 and 1.0 inclusive. The next statement
1546 fixes the 1.0 case. */
1549 colorval
|= (val
<< pos
);
1564 ret
= mac_color_map_lookup (colorname
);
1570 /* Gamma-correct COLOR on frame F. */
1573 gamma_correct (f
, color
)
1575 unsigned long *color
;
1579 unsigned long red
, green
, blue
;
1581 red
= pow (RED_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
1582 green
= pow (GREEN_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
1583 blue
= pow (BLUE_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
1584 *color
= RGB_TO_ULONG (red
, green
, blue
);
1588 /* Decide if color named COLOR is valid for the display associated
1589 with the selected frame; if so, return the rgb values in COLOR_DEF.
1590 If ALLOC is nonzero, allocate a new colormap cell. */
1593 mac_defined_color (f
, color
, color_def
, alloc
)
1599 register Lisp_Object tem
;
1600 unsigned long mac_color_ref
;
1602 tem
= x_to_mac_color (color
);
1608 /* Apply gamma correction. */
1609 mac_color_ref
= XUINT (tem
);
1610 gamma_correct (f
, &mac_color_ref
);
1611 XSETINT (tem
, mac_color_ref
);
1614 color_def
->pixel
= mac_color_ref
;
1615 color_def
->red
= RED_FROM_ULONG (mac_color_ref
);
1616 color_def
->green
= GREEN_FROM_ULONG (mac_color_ref
);
1617 color_def
->blue
= BLUE_FROM_ULONG (mac_color_ref
);
1627 /* Given a string ARG naming a color, compute a pixel value from it
1628 suitable for screen F.
1629 If F is not a color screen, return DEF (default) regardless of what
1633 x_decode_color (f
, arg
, def
)
1642 if (strcmp (SDATA (arg
), "black") == 0)
1643 return BLACK_PIX_DEFAULT (f
);
1644 else if (strcmp (SDATA (arg
), "white") == 0)
1645 return WHITE_PIX_DEFAULT (f
);
1648 if ((FRAME_MAC_DISPLAY_INFO (f
)->n_planes
1649 * FRAME_MAC_DISPLAY_INFO (f
)->n_cbits
) == 1)
1653 if (mac_defined_color (f
, SDATA (arg
), &cdef
, 1))
1656 /* defined_color failed; return an ultimate default. */
1660 /* Functions called only from `x_set_frame_param'
1661 to set individual parameters.
1663 If FRAME_MAC_WINDOW (f) is 0,
1664 the frame is being created and its window does not exist yet.
1665 In that case, just record the parameter's new value
1666 in the standard place; do not attempt to change the window. */
1669 x_set_foreground_color (f
, arg
, oldval
)
1671 Lisp_Object arg
, oldval
;
1673 FRAME_FOREGROUND_PIXEL (f
)
1674 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1676 if (FRAME_MAC_WINDOW (f
) != 0)
1678 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
1679 if (FRAME_VISIBLE_P (f
))
1685 x_set_background_color (f
, arg
, oldval
)
1687 Lisp_Object arg
, oldval
;
1689 FRAME_BACKGROUND_PIXEL (f
)
1690 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1692 if (FRAME_MAC_WINDOW (f
) != 0)
1694 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
1696 if (FRAME_VISIBLE_P (f
))
1702 x_set_mouse_color (f
, arg
, oldval
)
1704 Lisp_Object arg
, oldval
;
1706 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
1710 if (!EQ (Qnil
, arg
))
1711 f
->output_data
.mac
->mouse_pixel
1712 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1713 mask_color
= FRAME_BACKGROUND_PIXEL (f
);
1715 /* Don't let pointers be invisible. */
1716 if (mask_color
== f
->output_data
.mac
->mouse_pixel
1717 && mask_color
== FRAME_BACKGROUND_PIXEL (f
))
1718 f
->output_data
.mac
->mouse_pixel
= FRAME_FOREGROUND_PIXEL (f
);
1720 #if 0 /* MAC_TODO : cursor changes */
1723 /* It's not okay to crash if the user selects a screwy cursor. */
1724 count
= x_catch_errors (FRAME_W32_DISPLAY (f
));
1726 if (!EQ (Qnil
, Vx_pointer_shape
))
1728 CHECK_NUMBER (Vx_pointer_shape
);
1729 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XINT (Vx_pointer_shape
));
1732 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1733 x_check_errors (FRAME_W32_DISPLAY (f
), "bad text pointer cursor: %s");
1735 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1737 CHECK_NUMBER (Vx_nontext_pointer_shape
);
1738 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1739 XINT (Vx_nontext_pointer_shape
));
1742 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_left_ptr
);
1743 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
1745 if (!EQ (Qnil
, Vx_hourglass_pointer_shape
))
1747 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
1748 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1749 XINT (Vx_hourglass_pointer_shape
));
1752 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_watch
);
1753 x_check_errors (FRAME_W32_DISPLAY (f
), "bad busy pointer cursor: %s");
1755 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
1756 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1758 CHECK_NUMBER (Vx_mode_pointer_shape
);
1759 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1760 XINT (Vx_mode_pointer_shape
));
1763 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1764 x_check_errors (FRAME_W32_DISPLAY (f
), "bad modeline pointer cursor: %s");
1766 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1768 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1770 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1771 XINT (Vx_sensitive_text_pointer_shape
));
1774 hand_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_crosshair
);
1776 if (!NILP (Vx_window_horizontal_drag_shape
))
1778 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1779 horizontal_drag_cursor
1780 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1781 XINT (Vx_window_horizontal_drag_shape
));
1784 horizontal_drag_cursor
1785 = XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_sb_h_double_arrow
);
1787 /* Check and report errors with the above calls. */
1788 x_check_errors (FRAME_W32_DISPLAY (f
), "can't set cursor shape: %s");
1789 x_uncatch_errors (FRAME_W32_DISPLAY (f
), count
);
1792 XColor fore_color
, back_color
;
1794 fore_color
.pixel
= f
->output_data
.w32
->mouse_pixel
;
1795 back_color
.pixel
= mask_color
;
1796 XQueryColor (FRAME_W32_DISPLAY (f
),
1797 DefaultColormap (FRAME_W32_DISPLAY (f
),
1798 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1800 XQueryColor (FRAME_W32_DISPLAY (f
),
1801 DefaultColormap (FRAME_W32_DISPLAY (f
),
1802 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1804 XRecolorCursor (FRAME_W32_DISPLAY (f
), cursor
,
1805 &fore_color
, &back_color
);
1806 XRecolorCursor (FRAME_W32_DISPLAY (f
), nontext_cursor
,
1807 &fore_color
, &back_color
);
1808 XRecolorCursor (FRAME_W32_DISPLAY (f
), mode_cursor
,
1809 &fore_color
, &back_color
);
1810 XRecolorCursor (FRAME_W32_DISPLAY (f
), hand_cursor
,
1811 &fore_color
, &back_color
);
1812 XRecolorCursor (FRAME_W32_DISPLAY (f
), hourglass_cursor
,
1813 &fore_color
, &back_color
);
1816 if (FRAME_W32_WINDOW (f
) != 0)
1817 XDefineCursor (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), cursor
);
1819 if (cursor
!= f
->output_data
.w32
->text_cursor
&& f
->output_data
.w32
->text_cursor
!= 0)
1820 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->text_cursor
);
1821 f
->output_data
.w32
->text_cursor
= cursor
;
1823 if (nontext_cursor
!= f
->output_data
.w32
->nontext_cursor
1824 && f
->output_data
.w32
->nontext_cursor
!= 0)
1825 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->nontext_cursor
);
1826 f
->output_data
.w32
->nontext_cursor
= nontext_cursor
;
1828 if (hourglass_cursor
!= f
->output_data
.w32
->hourglass_cursor
1829 && f
->output_data
.w32
->hourglass_cursor
!= 0)
1830 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hourglass_cursor
);
1831 f
->output_data
.w32
->hourglass_cursor
= hourglass_cursor
;
1833 if (mode_cursor
!= f
->output_data
.w32
->modeline_cursor
1834 && f
->output_data
.w32
->modeline_cursor
!= 0)
1835 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->modeline_cursor
);
1836 f
->output_data
.w32
->modeline_cursor
= mode_cursor
;
1838 if (hand_cursor
!= f
->output_data
.w32
->hand_cursor
1839 && f
->output_data
.w32
->hand_cursor
!= 0)
1840 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hand_cursor
);
1841 f
->output_data
.w32
->hand_cursor
= hand_cursor
;
1843 XFlush (FRAME_W32_DISPLAY (f
));
1846 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1847 #endif /* MAC_TODO */
1851 x_set_cursor_color (f
, arg
, oldval
)
1853 Lisp_Object arg
, oldval
;
1855 unsigned long fore_pixel
;
1857 if (!NILP (Vx_cursor_fore_pixel
))
1858 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1859 WHITE_PIX_DEFAULT (f
));
1861 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1862 f
->output_data
.mac
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1864 /* Make sure that the cursor color differs from the background color. */
1865 if (f
->output_data
.mac
->cursor_pixel
== FRAME_BACKGROUND_PIXEL (f
))
1867 f
->output_data
.mac
->cursor_pixel
= f
->output_data
.mac
->mouse_pixel
;
1868 if (f
->output_data
.mac
->cursor_pixel
== fore_pixel
)
1869 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1871 FRAME_FOREGROUND_PIXEL (f
) = fore_pixel
;
1873 #if 0 /* MAC_TODO: cannot figure out what to do (wrong number of params) */
1874 if (FRAME_MAC_WINDOW (f
) != 0)
1876 if (FRAME_VISIBLE_P (f
))
1879 display_and_set_cursor (f
, 0);
1880 display_and_set_cursor (f
, 1);
1886 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1889 /* Set the border-color of frame F to pixel value PIX.
1890 Note that this does not fully take effect if done before
1893 x_set_border_pixel (f
, pix
)
1897 f
->output_data
.mac
->border_pixel
= pix
;
1899 if (FRAME_MAC_WINDOW (f
) != 0 && f
->output_data
.mac
->border_width
> 0)
1901 if (FRAME_VISIBLE_P (f
))
1906 /* Set the border-color of frame F to value described by ARG.
1907 ARG can be a string naming a color.
1908 The border-color is used for the border that is drawn by the server.
1909 Note that this does not fully take effect if done before
1910 F has a window; it must be redone when the window is created. */
1913 x_set_border_color (f
, arg
, oldval
)
1915 Lisp_Object arg
, oldval
;
1920 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1921 x_set_border_pixel (f
, pix
);
1922 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1926 x_set_cursor_type (f
, arg
, oldval
)
1928 Lisp_Object arg
, oldval
;
1930 set_frame_cursor_types (f
, arg
);
1932 /* Make sure the cursor gets redrawn. This is overkill, but how
1933 often do people change cursor types? */
1934 update_mode_lines
++;
1937 #if 0 /* MAC_TODO: really no icon for Mac */
1939 x_set_icon_type (f
, arg
, oldval
)
1941 Lisp_Object arg
, oldval
;
1945 if (NILP (arg
) && NILP (oldval
))
1948 if (STRINGP (arg
) && STRINGP (oldval
)
1949 && EQ (Fstring_equal (oldval
, arg
), Qt
))
1952 if (SYMBOLP (arg
) && SYMBOLP (oldval
) && EQ (arg
, oldval
))
1957 result
= x_bitmap_icon (f
, arg
);
1961 error ("No icon window available");
1966 #endif /* MAC_TODO */
1969 x_set_icon_name (f
, arg
, oldval
)
1971 Lisp_Object arg
, oldval
;
1977 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1980 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1985 #if 0 /* MAC_TODO */
1986 if (f
->output_data
.w32
->icon_bitmap
!= 0)
1991 result
= x_text_icon (f
,
1992 (char *) SDATA ((!NILP (f
->icon_name
)
2001 error ("No icon window available");
2004 /* If the window was unmapped (and its icon was mapped),
2005 the new icon is not mapped, so map the window in its stead. */
2006 if (FRAME_VISIBLE_P (f
))
2008 #ifdef USE_X_TOOLKIT
2009 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
2011 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
2014 XFlush (FRAME_W32_DISPLAY (f
));
2016 #endif /* MAC_TODO */
2021 x_set_menu_bar_lines (f
, value
, oldval
)
2023 Lisp_Object value
, oldval
;
2026 int olines
= FRAME_MENU_BAR_LINES (f
);
2028 /* Right now, menu bars don't work properly in minibuf-only frames;
2029 most of the commands try to apply themselves to the minibuffer
2030 frame itself, and get an error because you can't switch buffers
2031 in or split the minibuffer window. */
2032 if (FRAME_MINIBUF_ONLY_P (f
))
2035 if (INTEGERP (value
))
2036 nlines
= XINT (value
);
2040 FRAME_MENU_BAR_LINES (f
) = 0;
2042 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
2045 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
2046 free_frame_menubar (f
);
2047 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
2049 /* Adjust the frame size so that the client (text) dimensions
2050 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
2052 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2053 do_pending_window_change (0);
2059 /* Set the number of lines used for the tool bar of frame F to VALUE.
2060 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
2061 is the old number of tool bar lines. This function changes the
2062 height of all windows on frame F to match the new tool bar height.
2063 The frame's height doesn't change. */
2066 x_set_tool_bar_lines (f
, value
, oldval
)
2068 Lisp_Object value
, oldval
;
2070 int delta
, nlines
, root_height
;
2071 Lisp_Object root_window
;
2073 /* Treat tool bars like menu bars. */
2074 if (FRAME_MINIBUF_ONLY_P (f
))
2077 /* Use VALUE only if an integer >= 0. */
2078 if (INTEGERP (value
) && XINT (value
) >= 0)
2079 nlines
= XFASTINT (value
);
2083 /* Make sure we redisplay all windows in this frame. */
2084 ++windows_or_buffers_changed
;
2086 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
2088 /* Don't resize the tool-bar to more than we have room for. */
2089 root_window
= FRAME_ROOT_WINDOW (f
);
2090 root_height
= XINT (XWINDOW (root_window
)->height
);
2091 if (root_height
- delta
< 1)
2093 delta
= root_height
- 1;
2094 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
2097 FRAME_TOOL_BAR_LINES (f
) = nlines
;
2098 change_window_heights (root_window
, delta
);
2101 /* We also have to make sure that the internal border at the top of
2102 the frame, below the menu bar or tool bar, is redrawn when the
2103 tool bar disappears. This is so because the internal border is
2104 below the tool bar if one is displayed, but is below the menu bar
2105 if there isn't a tool bar. The tool bar draws into the area
2106 below the menu bar. */
2107 if (FRAME_MAC_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
2111 clear_current_matrices (f
);
2112 updating_frame
= NULL
;
2115 /* If the tool bar gets smaller, the internal border below it
2116 has to be cleared. It was formerly part of the display
2117 of the larger tool bar, and updating windows won't clear it. */
2120 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
2121 int width
= PIXEL_WIDTH (f
);
2122 int y
= nlines
* CANON_Y_UNIT (f
);
2125 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2126 0, y
, width
, height
, 0);
2129 if (WINDOWP (f
->tool_bar_window
))
2130 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
2135 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
2138 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2139 name; if NAME is a string, set F's name to NAME and set
2140 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2142 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2143 suggesting a new name, which lisp code should override; if
2144 F->explicit_name is set, ignore the new name; otherwise, set it. */
2147 x_set_name (f
, name
, explicit)
2152 /* Make sure that requests from lisp code override requests from
2153 Emacs redisplay code. */
2156 /* If we're switching from explicit to implicit, we had better
2157 update the mode lines and thereby update the title. */
2158 if (f
->explicit_name
&& NILP (name
))
2159 update_mode_lines
= 1;
2161 f
->explicit_name
= ! NILP (name
);
2163 else if (f
->explicit_name
)
2166 /* If NAME is nil, set the name to the w32_id_name. */
2169 /* Check for no change needed in this very common case
2170 before we do any consing. */
2171 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
,
2174 name
= build_string (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
);
2177 CHECK_STRING (name
);
2179 /* Don't change the name if it's already NAME. */
2180 if (! NILP (Fstring_equal (name
, f
->name
)))
2185 /* For setting the frame title, the title parameter should override
2186 the name parameter. */
2187 if (! NILP (f
->title
))
2190 if (FRAME_MAC_WINDOW (f
))
2192 if (STRING_MULTIBYTE (name
))
2193 #if 0 /* MAC_TODO: encoding title string */
2194 name
= ENCODE_SYSTEM (name
);
2203 if (strlen (SDATA (name
)) < 255)
2205 strcpy (windowTitle
, SDATA (name
));
2206 c2pstr (windowTitle
);
2207 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2215 /* This function should be called when the user's lisp code has
2216 specified a name for the frame; the name will override any set by the
2219 x_explicitly_set_name (f
, arg
, oldval
)
2221 Lisp_Object arg
, oldval
;
2223 x_set_name (f
, arg
, 1);
2226 /* This function should be called by Emacs redisplay code to set the
2227 name; names set this way will never override names set by the user's
2230 x_implicitly_set_name (f
, arg
, oldval
)
2232 Lisp_Object arg
, oldval
;
2234 x_set_name (f
, arg
, 0);
2237 /* Change the title of frame F to NAME.
2238 If NAME is nil, use the frame name as the title.
2240 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2241 name; if NAME is a string, set F's name to NAME and set
2242 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2244 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2245 suggesting a new name, which lisp code should override; if
2246 F->explicit_name is set, ignore the new name; otherwise, set it. */
2249 x_set_title (f
, name
, old_name
)
2251 Lisp_Object name
, old_name
;
2253 /* Don't change the title if it's already NAME. */
2254 if (EQ (name
, f
->title
))
2257 update_mode_lines
= 1;
2264 if (FRAME_MAC_WINDOW (f
))
2266 if (STRING_MULTIBYTE (name
))
2267 #if 0 /* MAC_TODO: encoding title string */
2268 name
= ENCODE_SYSTEM (name
);
2277 if (strlen (SDATA (name
)) < 255)
2279 strcpy (windowTitle
, SDATA (name
));
2280 c2pstr (windowTitle
);
2281 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2290 x_set_scroll_bar_default_width (f
)
2293 /* Imitate X without X Toolkit */
2295 int wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
2298 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 16; /* Aqua scroll bars. */
2299 FRAME_SCROLL_BAR_COLS (f
) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) +
2301 #else /* not MAC_OSX */
2302 /* Make the actual width at least 14 pixels and a multiple of a
2304 FRAME_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2306 /* Use all of that space (aside from required margins) for the
2308 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
2309 #endif /* not MAC_OSX */
2313 /* Subroutines of creating a frame. */
2316 x_get_string_resource (rdb
, name
, class)
2320 /* MAC_TODO: implement resource strings */
2324 /* Return the value of parameter PARAM.
2326 First search ALIST, then Vdefault_frame_alist, then the X defaults
2327 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2329 Convert the resource to the type specified by desired_type.
2331 If no default is specified, return Qunbound. If you call
2332 mac_get_arg, make sure you deal with Qunbound in a reasonable way,
2333 and don't let it get stored in any Lisp-visible variables! */
2336 mac_get_arg (alist
, param
, attribute
, class, type
)
2337 Lisp_Object alist
, param
;
2340 enum resource_types type
;
2342 return x_get_arg (check_x_display_info (Qnil
),
2343 alist
, param
, attribute
, class, type
);
2347 /* XParseGeometry copied from w32xfns.c */
2350 * XParseGeometry parses strings of the form
2351 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
2352 * width, height, xoffset, and yoffset are unsigned integers.
2353 * Example: "=80x24+300-49"
2354 * The equal sign is optional.
2355 * It returns a bitmask that indicates which of the four values
2356 * were actually found in the string. For each value found,
2357 * the corresponding argument is updated; for each value
2358 * not found, the corresponding argument is left unchanged.
2362 read_integer (string
, NextString
)
2363 register char *string
;
2366 register int Result
= 0;
2371 else if (*string
== '-')
2376 for (; (*string
>= '0') && (*string
<= '9'); string
++)
2378 Result
= (Result
* 10) + (*string
- '0');
2380 *NextString
= string
;
2388 XParseGeometry (string
, x
, y
, width
, height
)
2391 unsigned int *width
, *height
; /* RETURN */
2394 register char *strind
;
2395 unsigned int tempWidth
, tempHeight
;
2397 char *nextCharacter
;
2399 if ((string
== NULL
) || (*string
== '\0')) return (mask
);
2401 string
++; /* ignore possible '=' at beg of geometry spec */
2403 strind
= (char *)string
;
2404 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
2406 tempWidth
= read_integer (strind
, &nextCharacter
);
2407 if (strind
== nextCharacter
)
2409 strind
= nextCharacter
;
2413 if (*strind
== 'x' || *strind
== 'X')
2416 tempHeight
= read_integer (strind
, &nextCharacter
);
2417 if (strind
== nextCharacter
)
2419 strind
= nextCharacter
;
2420 mask
|= HeightValue
;
2423 if ((*strind
== '+') || (*strind
== '-'))
2428 tempX
= -read_integer (strind
, &nextCharacter
);
2429 if (strind
== nextCharacter
)
2431 strind
= nextCharacter
;
2438 tempX
= read_integer (strind
, &nextCharacter
);
2439 if (strind
== nextCharacter
)
2441 strind
= nextCharacter
;
2444 if ((*strind
== '+') || (*strind
== '-'))
2449 tempY
= -read_integer (strind
, &nextCharacter
);
2450 if (strind
== nextCharacter
)
2452 strind
= nextCharacter
;
2459 tempY
= read_integer (strind
, &nextCharacter
);
2460 if (strind
== nextCharacter
)
2462 strind
= nextCharacter
;
2468 /* If strind isn't at the end of the string the it's an invalid
2469 geometry specification. */
2471 if (*strind
!= '\0') return (0);
2477 if (mask
& WidthValue
)
2479 if (mask
& HeightValue
)
2480 *height
= tempHeight
;
2485 #if 0 /* MAC_TODO */
2486 /* Create and set up the Mac window for frame F. */
2489 mac_window (f
, window_prompting
, minibuffer_only
)
2491 long window_prompting
;
2492 int minibuffer_only
;
2498 /* Use the resource name as the top-level window name
2499 for looking up resources. Make a non-Lisp copy
2500 for the window manager, so GC relocation won't bother it.
2502 Elsewhere we specify the window name for the window manager. */
2505 char *str
= (char *) SDATA (Vx_resource_name
);
2506 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2507 strcpy (f
->namebuf
, str
);
2510 SetRect (&r
, f
->output_data
.mac
->left_pos
, f
->output_data
.mac
->top_pos
,
2511 f
->output_data
.mac
->left_pos
+ PIXEL_WIDTH (f
),
2512 f
->output_data
.mac
->top_pos
+ PIXEL_HEIGHT (f
));
2513 FRAME_MAC_WINDOW (f
)
2514 = NewCWindow (NULL
, &r
, "\p", 1, zoomDocProc
, (WindowPtr
) -1, 1, (long) f
->output_data
.mac
);
2516 validate_x_resource_name ();
2518 /* x_set_name normally ignores requests to set the name if the
2519 requested name is the same as the current name. This is the one
2520 place where that assumption isn't correct; f->name is set, but
2521 the server hasn't been told. */
2524 int explicit = f
->explicit_name
;
2526 f
->explicit_name
= 0;
2529 x_set_name (f
, name
, explicit);
2532 ShowWindow (FRAME_MAC_WINDOW (f
));
2536 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2537 initialize_frame_menubar (f
);
2539 if (FRAME_MAC_WINDOW (f
) == 0)
2540 error ("Unable to create window");
2542 #endif /* MAC_TODO */
2544 /* Handle the icon stuff for this window. Perhaps later we might
2545 want an x_set_icon_position which can be called interactively as
2553 Lisp_Object icon_x
, icon_y
;
2555 /* Set the position of the icon. Note that Windows 95 groups all
2556 icons in the tray. */
2557 icon_x
= mac_get_arg (parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2558 icon_y
= mac_get_arg (parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2559 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2561 CHECK_NUMBER (icon_x
);
2562 CHECK_NUMBER (icon_y
);
2564 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2565 error ("Both left and top icon corners of icon must be specified");
2569 if (! EQ (icon_x
, Qunbound
))
2570 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2573 /* Start up iconic or window? */
2574 x_wm_set_window_state
2575 (f
, (EQ (w32_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
), Qicon
)
2579 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
2592 XGCValues gc_values
;
2596 /* Create the GC's of this frame.
2597 Note that many default values are used. */
2600 gc_values
.font
= f
->output_data
.mac
->font
;
2601 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
2602 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
2603 f
->output_data
.mac
->normal_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
2604 FRAME_MAC_WINDOW (f
),
2605 GCFont
| GCForeground
| GCBackground
,
2608 /* Reverse video style. */
2609 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2610 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
2611 f
->output_data
.mac
->reverse_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
2612 FRAME_MAC_WINDOW (f
),
2613 GCFont
| GCForeground
| GCBackground
,
2616 /* Cursor has cursor-color background, background-color foreground. */
2617 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2618 gc_values
.background
= f
->output_data
.mac
->cursor_pixel
;
2619 f
->output_data
.mac
->cursor_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
2620 FRAME_MAC_WINDOW (f
),
2621 GCFont
| GCForeground
| GCBackground
,
2625 f
->output_data
.mac
->white_relief
.gc
= 0;
2626 f
->output_data
.mac
->black_relief
.gc
= 0;
2632 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2634 doc
: /* Make a new window, which is called a \"frame\" in Emacs terms.
2635 Returns an Emacs frame object.
2636 ALIST is an alist of frame parameters.
2637 If the parameters specify that the frame should not have a minibuffer,
2638 and do not specify a specific minibuffer window to use,
2639 then `default-minibuffer-frame' must be a frame whose minibuffer can
2640 be shared by the new frame.
2642 This function is an internal primitive--use `make-frame' instead. */)
2647 Lisp_Object frame
, tem
;
2649 int minibuffer_only
= 0;
2650 long window_prompting
= 0;
2652 int count
= SPECPDL_INDEX ();
2653 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
2654 Lisp_Object display
;
2655 struct mac_display_info
*dpyinfo
= NULL
;
2658 char x_frame_name
[10];
2659 static int x_frame_count
= 2; /* begins at 2 because terminal frame is F1 */
2663 /* Use this general default value to start with
2664 until we know if this frame has a specified name. */
2665 Vx_resource_name
= Vinvocation_name
;
2667 display
= mac_get_arg (parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
2668 if (EQ (display
, Qunbound
))
2670 dpyinfo
= check_x_display_info (display
);
2672 kb
= dpyinfo
->kboard
;
2674 kb
= &the_only_kboard
;
2677 name
= mac_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
2679 && ! EQ (name
, Qunbound
)
2681 error ("Invalid frame name--not a string or nil");
2684 Vx_resource_name
= name
;
2686 /* See if parent window is specified. */
2687 parent
= mac_get_arg (parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
2688 if (EQ (parent
, Qunbound
))
2690 if (! NILP (parent
))
2691 CHECK_NUMBER (parent
);
2693 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2694 /* No need to protect DISPLAY because that's not used after passing
2695 it to make_frame_without_minibuffer. */
2697 GCPRO4 (parms
, parent
, name
, frame
);
2698 tem
= mac_get_arg (parms
, Qminibuffer
, "minibuffer", "Minibuffer",
2700 if (EQ (tem
, Qnone
) || NILP (tem
))
2701 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
2702 else if (EQ (tem
, Qonly
))
2704 f
= make_minibuffer_frame ();
2705 minibuffer_only
= 1;
2707 else if (WINDOWP (tem
))
2708 f
= make_frame_without_minibuffer (tem
, kb
, display
);
2712 if (EQ (name
, Qunbound
) || NILP (name
))
2714 sprintf (x_frame_name
, "F%d", x_frame_count
++);
2715 f
->name
= build_string (x_frame_name
);
2716 f
->explicit_name
= 0;
2721 f
->explicit_name
= 1;
2724 XSETFRAME (frame
, f
);
2726 /* Note that X Windows does support scroll bars. */
2727 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2729 f
->output_method
= output_mac
;
2730 f
->output_data
.mac
= (struct mac_output
*) xmalloc (sizeof (struct mac_output
));
2731 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
2732 FRAME_FONTSET (f
) = -1;
2733 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
2734 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
2737 FRAME_FONTSET (f
) = -1;
2741 = mac_get_arg (parms
, Qicon_name
, "iconName", "Title", RES_TYPE_STRING
);
2742 if (! STRINGP (f
->icon_name
))
2743 f
->icon_name
= Qnil
;
2745 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
2747 FRAME_KBOARD (f
) = kb
;
2750 /* Specify the parent under which to make this window. */
2754 f
->output_data
.mac
->parent_desc
= (Window
) parent
;
2755 f
->output_data
.mac
->explicit_parent
= 1;
2759 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
2760 f
->output_data
.mac
->explicit_parent
= 0;
2763 /* Set the name; the functions to which we pass f expect the name to
2765 if (EQ (name
, Qunbound
) || NILP (name
))
2767 f
->name
= build_string (dpyinfo
->mac_id_name
);
2768 f
->explicit_name
= 0;
2773 f
->explicit_name
= 1;
2774 /* use the frame's title when getting resources for this frame. */
2775 specbind (Qx_resource_name
, name
);
2778 /* Extract the window parameters from the supplied values
2779 that are needed to determine window geometry. */
2783 font
= mac_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
2786 /* First, try whatever font the caller has specified. */
2789 tem
= Fquery_fontset (font
, Qnil
);
2791 font
= x_new_fontset (f
, SDATA (tem
));
2793 font
= x_new_font (f
, SDATA (font
));
2795 /* Try out a font which we hope has bold and italic variations. */
2796 if (! STRINGP (font
))
2797 font
= x_new_font (f
, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
2798 /* If those didn't work, look for something which will at least work. */
2799 if (!STRINGP (font
))
2800 font
= x_new_font (f
, "-*-monaco-*-12-*-mac-roman");
2801 if (! STRINGP (font
))
2802 font
= x_new_font (f
, "-*-courier-*-10-*-mac-roman");
2803 if (! STRINGP (font
))
2804 error ("Cannot find any usable font");
2807 x_default_parameter (f
, parms
, Qfont
, font
,
2808 "font", "Font", RES_TYPE_STRING
);
2811 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
2812 "borderwidth", "BorderWidth", RES_TYPE_NUMBER
);
2813 /* This defaults to 2 in order to match xterm. We recognize either
2814 internalBorderWidth or internalBorder (which is what xterm calls
2816 if (NILP (Fassq (Qinternal_border_width
, parms
)))
2820 value
= mac_get_arg (parms
, Qinternal_border_width
,
2821 "internalBorder", "InternalBorder", RES_TYPE_NUMBER
);
2822 if (! EQ (value
, Qunbound
))
2823 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
2826 /* Default internalBorderWidth to 0 on Windows to match other programs. */
2827 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (0),
2828 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER
);
2829 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qright
,
2830 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL
);
2832 /* Also do the stuff which must be set before the window exists. */
2833 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
2834 "foreground", "Foreground", RES_TYPE_STRING
);
2835 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
2836 "background", "Background", RES_TYPE_STRING
);
2837 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
2838 "pointerColor", "Foreground", RES_TYPE_STRING
);
2839 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
2840 "cursorColor", "Foreground", RES_TYPE_STRING
);
2841 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
2842 "borderColor", "BorderColor", RES_TYPE_STRING
);
2843 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
2844 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
2845 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
2846 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
2847 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
2848 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
2849 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
2850 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
2853 /* Init faces before x_default_parameter is called for scroll-bar
2854 parameters because that function calls x_set_scroll_bar_width,
2855 which calls change_frame_size, which calls Fset_window_buffer,
2856 which runs hooks, which call Fvertical_motion. At the end, we
2857 end up in init_iterator with a null face cache, which should not
2859 init_frame_faces (f
);
2861 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
2862 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
2863 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (0),
2864 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
2865 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
2866 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL
);
2867 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
2868 "title", "Title", RES_TYPE_STRING
);
2870 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
2872 /* MAC_TODO: specify 1 below when toolbars are implemented. */
2873 window_prompting
= x_figure_window_size (f
, parms
, 0);
2875 tem
= mac_get_arg (parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
2876 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
2878 /* Create the window. Add the tool-bar height to the initial frame
2879 height so that the user gets a text display area of the size he
2880 specified with -g or via the registry. Later changes of the
2881 tool-bar height don't change the frame size. This is done so that
2882 users can create tall Emacs frames without having to guess how
2883 tall the tool-bar will get. */
2884 f
->height
+= FRAME_TOOL_BAR_LINES (f
);
2886 /* mac_window (f, window_prompting, minibuffer_only); */
2893 /* Now consider the frame official. */
2894 FRAME_MAC_DISPLAY_INFO (f
)->reference_count
++;
2895 Vframe_list
= Fcons (frame
, Vframe_list
);
2897 /* We need to do this after creating the window, so that the
2898 icon-creation functions can say whose icon they're describing. */
2899 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
2900 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
2902 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
2903 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
2904 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
2905 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
2906 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
2907 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
2908 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
2909 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER
);
2911 /* Dimensions, especially f->height, must be done via change_frame_size.
2912 Change will not be effected unless different from the current
2918 SET_FRAME_WIDTH (f
, 0);
2919 change_frame_size (f
, height
, width
, 1, 0, 0);
2921 /* Set up faces after all frame parameters are known. */
2922 call1 (Qface_set_after_frame_default
, frame
);
2924 #if 0 /* MAC_TODO: when we have window manager hints */
2925 /* Tell the server what size and position, etc, we want, and how
2926 badly we want them. This should be done after we have the menu
2927 bar so that its size can be taken into account. */
2929 x_wm_set_size_hint (f
, window_prompting
, 0);
2933 /* Make the window appear on the frame and enable display, unless
2934 the caller says not to. However, with explicit parent, Emacs
2935 cannot control visibility, so don't try. */
2936 if (! f
->output_data
.mac
->explicit_parent
)
2938 Lisp_Object visibility
;
2940 visibility
= mac_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
);
2941 if (EQ (visibility
, Qunbound
))
2944 #if 0 /* MAC_TODO: really no iconify on Mac */
2945 if (EQ (visibility
, Qicon
))
2946 x_iconify_frame (f
);
2949 if (! NILP (visibility
))
2950 x_make_frame_visible (f
);
2952 /* Must have been Qnil. */
2957 /* Make sure windows on this frame appear in calls to next-window
2958 and similar functions. */
2959 Vwindow_list
= Qnil
;
2961 return unbind_to (count
, frame
);
2964 /* FRAME is used only to get a handle on the X display. We don't pass the
2965 display info directly because we're called from frame.c, which doesn't
2966 know about that structure. */
2968 x_get_focus_frame (frame
)
2969 struct frame
*frame
;
2971 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
2973 if (! dpyinfo
->x_focus_frame
)
2976 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
2980 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
2981 doc
: /* Internal function called by `color-defined-p', which see. */)
2983 Lisp_Object color
, frame
;
2986 FRAME_PTR f
= check_x_frame (frame
);
2988 CHECK_STRING (color
);
2990 if (mac_defined_color (f
, SDATA (color
), &foo
, 0))
2996 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
2997 doc
: /* Internal function called by `color-values', which see. */)
2999 Lisp_Object color
, frame
;
3002 FRAME_PTR f
= check_x_frame (frame
);
3004 CHECK_STRING (color
);
3006 if (mac_defined_color (f
, SDATA (color
), &foo
, 0))
3010 rgb
[0] = make_number ((RED_FROM_ULONG (foo
.pixel
) << 8)
3011 | RED_FROM_ULONG (foo
.pixel
));
3012 rgb
[1] = make_number ((GREEN_FROM_ULONG (foo
.pixel
) << 8)
3013 | GREEN_FROM_ULONG (foo
.pixel
));
3014 rgb
[2] = make_number ((BLUE_FROM_ULONG (foo
.pixel
) << 8)
3015 | BLUE_FROM_ULONG (foo
.pixel
));
3016 return Flist (3, rgb
);
3022 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3023 doc
: /* Internal function called by `display-color-p', which see. */)
3025 Lisp_Object display
;
3027 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3029 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 2)
3035 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3037 doc
: /* Return t if the X display supports shades of gray.
3038 Note that color displays do support shades of gray.
3039 The optional argument DISPLAY specifies which display to ask about.
3040 DISPLAY should be either a frame or a display name (a string).
3041 If omitted or nil, that stands for the selected frame's display. */)
3043 Lisp_Object display
;
3045 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3047 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 1)
3053 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3055 doc
: /* Returns the width in pixels of the X display DISPLAY.
3056 The optional argument DISPLAY specifies which display to ask about.
3057 DISPLAY should be either a frame or a display name (a string).
3058 If omitted or nil, that stands for the selected frame's display. */)
3060 Lisp_Object display
;
3062 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3064 return make_number (dpyinfo
->width
);
3067 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3068 Sx_display_pixel_height
, 0, 1, 0,
3069 doc
: /* Returns the height in pixels of the X display DISPLAY.
3070 The optional argument DISPLAY specifies which display to ask about.
3071 DISPLAY should be either a frame or a display name (a string).
3072 If omitted or nil, that stands for the selected frame's display. */)
3074 Lisp_Object display
;
3076 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3078 return make_number (dpyinfo
->height
);
3081 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3083 doc
: /* Returns the number of bitplanes of the display DISPLAY.
3084 The optional argument DISPLAY specifies which display to ask about.
3085 DISPLAY should be either a frame or a display name (a string).
3086 If omitted or nil, that stands for the selected frame's display. */)
3088 Lisp_Object display
;
3090 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3092 return make_number (dpyinfo
->n_planes
* dpyinfo
->n_cbits
);
3095 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3097 doc
: /* Returns the number of color cells of the display DISPLAY.
3098 The optional argument DISPLAY specifies which display to ask about.
3099 DISPLAY should be either a frame or a display name (a string).
3100 If omitted or nil, that stands for the selected frame's display. */)
3102 Lisp_Object display
;
3104 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3106 /* MAC_TODO: check whether this is right */
3107 return make_number ((unsigned long) (pow (2, dpyinfo
->n_cbits
)));
3110 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3111 Sx_server_max_request_size
,
3113 doc
: /* Returns the maximum request size of the server of display DISPLAY.
3114 The optional argument DISPLAY specifies which display to ask about.
3115 DISPLAY should be either a frame or a display name (a string).
3116 If omitted or nil, that stands for the selected frame's display. */)
3118 Lisp_Object display
;
3120 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3122 return make_number (1);
3125 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3126 doc
: /* Returns the vendor ID string of the Mac OS system (Apple).
3127 The optional argument DISPLAY specifies which display to ask about.
3128 DISPLAY should be either a frame or a display name (a string).
3129 If omitted or nil, that stands for the selected frame's display. */)
3131 Lisp_Object display
;
3133 return build_string ("Apple Computers");
3136 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3137 doc
: /* Returns the version numbers of the server of display DISPLAY.
3138 The value is a list of three integers: the major and minor
3139 version numbers, and the vendor-specific release
3140 number. See also the function `x-server-vendor'.
3142 The optional argument DISPLAY specifies which display to ask about.
3143 DISPLAY should be either a frame or a display name (a string).
3144 If omitted or nil, that stands for the selected frame's display. */)
3146 Lisp_Object display
;
3148 int mac_major_version
, mac_minor_version
;
3151 if (Gestalt (gestaltSystemVersion
, &response
) != noErr
)
3152 error ("Cannot get Mac OS version");
3154 mac_major_version
= (response
>> 8) & 0xf;
3155 mac_minor_version
= (response
>> 4) & 0xf;
3157 return Fcons (make_number (mac_major_version
),
3158 Fcons (make_number (mac_minor_version
), Qnil
));
3161 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3162 doc
: /* Return the number of screens on the server of display DISPLAY.
3163 The optional argument DISPLAY specifies which display to ask about.
3164 DISPLAY should be either a frame or a display name (a string).
3165 If omitted or nil, that stands for the selected frame's display. */)
3167 Lisp_Object display
;
3169 return make_number (1);
3172 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3173 doc
: /* Return the height in millimeters of the X display DISPLAY.
3174 The optional argument DISPLAY specifies which display to ask about.
3175 DISPLAY should be either a frame or a display name (a string).
3176 If omitted or nil, that stands for the selected frame's display. */)
3178 Lisp_Object display
;
3180 /* MAC_TODO: this is an approximation, and only of the main display */
3182 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3187 return make_number ((int) (v
/ 72.0 * 25.4));
3190 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3191 doc
: /* Return the width in millimeters of the X display DISPLAY.
3192 The optional argument DISPLAY specifies which display to ask about.
3193 DISPLAY should be either a frame or a display name (a string).
3194 If omitted or nil, that stands for the selected frame's display. */)
3196 Lisp_Object display
;
3198 /* MAC_TODO: this is an approximation, and only of the main display */
3200 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3205 return make_number ((int) (h
/ 72.0 * 25.4));
3208 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3209 Sx_display_backing_store
, 0, 1, 0,
3210 doc
: /* Returns an indication of whether display DISPLAY does backing store.
3211 The value may be `always', `when-mapped', or `not-useful'.
3212 The optional argument DISPLAY specifies which display to ask about.
3213 DISPLAY should be either a frame or a display name (a string).
3214 If omitted or nil, that stands for the selected frame's display. */)
3216 Lisp_Object display
;
3218 return intern ("not-useful");
3221 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3222 Sx_display_visual_class
, 0, 1, 0,
3223 doc
: /* Returns the visual class of the display DISPLAY.
3224 The value is one of the symbols `static-gray', `gray-scale',
3225 `static-color', `pseudo-color', `true-color', or `direct-color'.
3227 The optional argument DISPLAY specifies which display to ask about.
3228 DISPLAY should be either a frame or a display name (a string).
3229 If omitted or nil, that stands for the selected frame's display. */)
3231 Lisp_Object display
;
3233 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3236 switch (dpyinfo
->visual
->class)
3238 case StaticGray
: return (intern ("static-gray"));
3239 case GrayScale
: return (intern ("gray-scale"));
3240 case StaticColor
: return (intern ("static-color"));
3241 case PseudoColor
: return (intern ("pseudo-color"));
3242 case TrueColor
: return (intern ("true-color"));
3243 case DirectColor
: return (intern ("direct-color"));
3245 error ("Display has an unknown visual class");
3249 return (intern ("true-color"));
3252 DEFUN ("x-display-save-under", Fx_display_save_under
,
3253 Sx_display_save_under
, 0, 1, 0,
3254 doc
: /* Returns t if the display DISPLAY supports the save-under feature.
3255 The optional argument DISPLAY specifies which display to ask about.
3256 DISPLAY should be either a frame or a display name (a string).
3257 If omitted or nil, that stands for the selected frame's display. */)
3259 Lisp_Object display
;
3266 register struct frame
*f
;
3268 return PIXEL_WIDTH (f
);
3273 register struct frame
*f
;
3275 return PIXEL_HEIGHT (f
);
3280 register struct frame
*f
;
3282 return FONT_WIDTH (f
->output_data
.mac
->font
);
3287 register struct frame
*f
;
3289 return f
->output_data
.mac
->line_height
;
3294 register struct frame
*f
;
3296 return FRAME_MAC_DISPLAY_INFO (f
)->n_planes
;
3299 /* Return the display structure for the display named NAME.
3300 Open a new connection if necessary. */
3302 struct mac_display_info
*
3303 x_display_info_for_name (name
)
3307 struct mac_display_info
*dpyinfo
;
3309 CHECK_STRING (name
);
3311 for (dpyinfo
= &one_mac_display_info
, names
= x_display_name_list
;
3313 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
3316 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
3321 /* Use this general default value to start with. */
3322 Vx_resource_name
= Vinvocation_name
;
3324 validate_x_resource_name ();
3326 dpyinfo
= mac_term_init (name
, (unsigned char *) 0,
3327 (char *) SDATA (Vx_resource_name
));
3330 error ("Cannot connect to server %s", SDATA (name
));
3333 XSETFASTINT (Vwindow_system_version
, 3);
3338 #if 0 /* MAC_TODO: implement network support */
3339 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
3341 doc
: /* Open a connection to a server.
3342 DISPLAY is the name of the display to connect to.
3343 Optional second arg XRM-STRING is a string of resources in xrdb format.
3344 If the optional third arg MUST-SUCCEED is non-nil,
3345 terminate Emacs if we can't open the connection. */)
3346 (display
, xrm_string
, must_succeed
)
3347 Lisp_Object display
, xrm_string
, must_succeed
;
3349 unsigned char *xrm_option
;
3350 struct mac_display_info
*dpyinfo
;
3352 CHECK_STRING (display
);
3353 if (! NILP (xrm_string
))
3354 CHECK_STRING (xrm_string
);
3356 if (! EQ (Vwindow_system
, intern ("mac")))
3357 error ("Not using Mac OS");
3359 if (! NILP (xrm_string
))
3360 xrm_option
= (unsigned char *) SDATA (xrm_string
);
3362 xrm_option
= (unsigned char *) 0;
3364 validate_x_resource_name ();
3366 /* This is what opens the connection and sets x_current_display.
3367 This also initializes many symbols, such as those used for input. */
3368 dpyinfo
= mac_term_init (display
, xrm_option
,
3369 (char *) SDATA (Vx_resource_name
));
3373 if (!NILP (must_succeed
))
3374 fatal ("Cannot connect to server %s.\n",
3377 error ("Cannot connect to server %s", SDATA (display
));
3382 XSETFASTINT (Vwindow_system_version
, 3);
3386 DEFUN ("x-close-connection", Fx_close_connection
,
3387 Sx_close_connection
, 1, 1, 0,
3388 doc
: /* Close the connection to DISPLAY's server.
3389 For DISPLAY, specify either a frame or a display name (a string).
3390 If DISPLAY is nil, that stands for the selected frame's display. */)
3392 Lisp_Object display
;
3394 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3397 if (dpyinfo
->reference_count
> 0)
3398 error ("Display still has frames on it");
3401 /* Free the fonts in the font table. */
3402 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
3403 if (dpyinfo
->font_table
[i
].name
)
3405 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
3406 xfree (dpyinfo
->font_table
[i
].full_name
);
3407 xfree (dpyinfo
->font_table
[i
].name
);
3408 x_unload_font (dpyinfo
, dpyinfo
->font_table
[i
].font
);
3410 x_destroy_all_bitmaps (dpyinfo
);
3412 x_delete_display (dpyinfo
);
3419 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
3420 doc
: /* Return the list of display names that Emacs has connections to. */)
3423 Lisp_Object tail
, result
;
3426 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
3427 result
= Fcons (XCAR (XCAR (tail
)), result
);
3432 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
3433 doc
: /* If ON is non-nil, report errors as soon as the erring request is made.
3434 If ON is nil, allow buffering of requests.
3435 This is a noop on Mac OS systems.
3436 The optional second argument DISPLAY specifies which display to act on.
3437 DISPLAY should be either a frame or a display name (a string).
3438 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
3440 Lisp_Object display
, on
;
3446 /***********************************************************************
3448 ***********************************************************************/
3450 /* Value is the number of elements of vector VECTOR. */
3452 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
3454 /* List of supported image types. Use define_image_type to add new
3455 types. Use lookup_image_type to find a type for a given symbol. */
3457 static struct image_type
*image_types
;
3459 /* The symbol `image' which is the car of the lists used to represent
3462 extern Lisp_Object Qimage
;
3464 /* The symbol `xbm' which is used as the type symbol for XBM images. */
3470 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
3471 extern Lisp_Object QCdata
, QCtype
;
3472 Lisp_Object QCascent
, QCmargin
, QCrelief
;
3473 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
3474 Lisp_Object QCindex
;
3476 /* Other symbols. */
3478 Lisp_Object Qlaplace
;
3480 /* Time in seconds after which images should be removed from the cache
3481 if not displayed. */
3483 Lisp_Object Vimage_cache_eviction_delay
;
3485 /* Function prototypes. */
3487 static void define_image_type
P_ ((struct image_type
*type
));
3488 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
3489 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
3490 static void x_laplace
P_ ((struct frame
*, struct image
*));
3491 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
3495 /* Define a new image type from TYPE. This adds a copy of TYPE to
3496 image_types and adds the symbol *TYPE->type to Vimage_types. */
3499 define_image_type (type
)
3500 struct image_type
*type
;
3502 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
3503 The initialized data segment is read-only. */
3504 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
3505 bcopy (type
, p
, sizeof *p
);
3506 p
->next
= image_types
;
3508 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
3512 /* Look up image type SYMBOL, and return a pointer to its image_type
3513 structure. Value is null if SYMBOL is not a known image type. */
3515 static INLINE
struct image_type
*
3516 lookup_image_type (symbol
)
3519 struct image_type
*type
;
3521 for (type
= image_types
; type
; type
= type
->next
)
3522 if (EQ (symbol
, *type
->type
))
3529 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
3530 valid image specification is a list whose car is the symbol
3531 `image', and whose rest is a property list. The property list must
3532 contain a value for key `:type'. That value must be the name of a
3533 supported image type. The rest of the property list depends on the
3537 valid_image_p (object
)
3542 if (CONSP (object
) && EQ (XCAR (object
), Qimage
))
3544 Lisp_Object symbol
= Fplist_get (XCDR (object
), QCtype
);
3545 struct image_type
*type
= lookup_image_type (symbol
);
3548 valid_p
= type
->valid_p (object
);
3555 /* Log error message with format string FORMAT and argument ARG.
3556 Signaling an error, e.g. when an image cannot be loaded, is not a
3557 good idea because this would interrupt redisplay, and the error
3558 message display would lead to another redisplay. This function
3559 therefore simply displays a message. */
3562 image_error (format
, arg1
, arg2
)
3564 Lisp_Object arg1
, arg2
;
3566 add_to_log (format
, arg1
, arg2
);
3571 /***********************************************************************
3572 Image specifications
3573 ***********************************************************************/
3575 enum image_value_type
3577 IMAGE_DONT_CHECK_VALUE_TYPE
,
3580 IMAGE_POSITIVE_INTEGER_VALUE
,
3581 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
3582 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
3584 IMAGE_INTEGER_VALUE
,
3585 IMAGE_FUNCTION_VALUE
,
3590 /* Structure used when parsing image specifications. */
3592 struct image_keyword
3594 /* Name of keyword. */
3597 /* The type of value allowed. */
3598 enum image_value_type type
;
3600 /* Non-zero means key must be present. */
3603 /* Used to recognize duplicate keywords in a property list. */
3606 /* The value that was found. */
3611 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
3613 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
3616 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
3617 has the format (image KEYWORD VALUE ...). One of the keyword/
3618 value pairs must be `:type TYPE'. KEYWORDS is a vector of
3619 image_keywords structures of size NKEYWORDS describing other
3620 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
3623 parse_image_spec (spec
, keywords
, nkeywords
, type
)
3625 struct image_keyword
*keywords
;
3632 if (!CONSP (spec
) || !EQ (XCAR (spec
), Qimage
))
3635 plist
= XCDR (spec
);
3636 while (CONSP (plist
))
3638 Lisp_Object key
, value
;
3640 /* First element of a pair must be a symbol. */
3642 plist
= XCDR (plist
);
3646 /* There must follow a value. */
3649 value
= XCAR (plist
);
3650 plist
= XCDR (plist
);
3652 /* Find key in KEYWORDS. Error if not found. */
3653 for (i
= 0; i
< nkeywords
; ++i
)
3654 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
3660 /* Record that we recognized the keyword. If a keywords
3661 was found more than once, it's an error. */
3662 keywords
[i
].value
= value
;
3663 ++keywords
[i
].count
;
3665 if (keywords
[i
].count
> 1)
3668 /* Check type of value against allowed type. */
3669 switch (keywords
[i
].type
)
3671 case IMAGE_STRING_VALUE
:
3672 if (!STRINGP (value
))
3676 case IMAGE_SYMBOL_VALUE
:
3677 if (!SYMBOLP (value
))
3681 case IMAGE_POSITIVE_INTEGER_VALUE
:
3682 if (!INTEGERP (value
) || XINT (value
) <= 0)
3686 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
3687 if (INTEGERP (value
) && XINT (value
) >= 0)
3690 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
3691 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
3695 case IMAGE_ASCENT_VALUE
:
3696 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
3698 else if (INTEGERP (value
)
3699 && XINT (value
) >= 0
3700 && XINT (value
) <= 100)
3704 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
3705 if (!INTEGERP (value
) || XINT (value
) < 0)
3709 case IMAGE_DONT_CHECK_VALUE_TYPE
:
3712 case IMAGE_FUNCTION_VALUE
:
3713 value
= indirect_function (value
);
3715 || COMPILEDP (value
)
3716 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
3720 case IMAGE_NUMBER_VALUE
:
3721 if (!INTEGERP (value
) && !FLOATP (value
))
3725 case IMAGE_INTEGER_VALUE
:
3726 if (!INTEGERP (value
))
3730 case IMAGE_BOOL_VALUE
:
3731 if (!NILP (value
) && !EQ (value
, Qt
))
3740 if (EQ (key
, QCtype
) && !EQ (type
, value
))
3744 /* Check that all mandatory fields are present. */
3745 for (i
= 0; i
< nkeywords
; ++i
)
3746 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
3749 return NILP (plist
);
3753 /* Return the value of KEY in image specification SPEC. Value is nil
3754 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
3755 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
3758 image_spec_value (spec
, key
, found
)
3759 Lisp_Object spec
, key
;
3764 xassert (valid_image_p (spec
));
3766 for (tail
= XCDR (spec
);
3767 CONSP (tail
) && CONSP (XCDR (tail
));
3768 tail
= XCDR (XCDR (tail
)))
3770 if (EQ (XCAR (tail
), key
))
3774 return XCAR (XCDR (tail
));
3786 /***********************************************************************
3787 Image type independent image structures
3788 ***********************************************************************/
3790 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
3791 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
3794 /* Allocate and return a new image structure for image specification
3795 SPEC. SPEC has a hash value of HASH. */
3797 static struct image
*
3798 make_image (spec
, hash
)
3802 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
3804 xassert (valid_image_p (spec
));
3805 bzero (img
, sizeof *img
);
3806 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
3807 xassert (img
->type
!= NULL
);
3809 img
->data
.lisp_val
= Qnil
;
3810 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
3816 /* Free image IMG which was used on frame F, including its resources. */
3825 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
3827 /* Remove IMG from the hash table of its cache. */
3829 img
->prev
->next
= img
->next
;
3831 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
3834 img
->next
->prev
= img
->prev
;
3836 c
->images
[img
->id
] = NULL
;
3838 /* Free resources, then free IMG. */
3839 img
->type
->free (f
, img
);
3845 /* Prepare image IMG for display on frame F. Must be called before
3846 drawing an image. */
3849 prepare_image_for_display (f
, img
)
3855 /* We're about to display IMG, so set its timestamp to `now'. */
3857 img
->timestamp
= EMACS_SECS (t
);
3859 /* If IMG doesn't have a pixmap yet, load it now, using the image
3860 type dependent loader function. */
3861 if (img
->pixmap
== 0 && !img
->load_failed_p
)
3862 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
3866 /* Value is the number of pixels for the ascent of image IMG when
3867 drawn in face FACE. */
3870 image_ascent (img
, face
)
3874 int height
= img
->height
+ img
->vmargin
;
3877 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
3880 ascent
= height
/ 2 - (FONT_DESCENT(face
->font
)
3881 - FONT_BASE(face
->font
)) / 2;
3883 ascent
= height
/ 2;
3886 ascent
= height
* img
->ascent
/ 100.0;
3893 /***********************************************************************
3894 Helper functions for X image types
3895 ***********************************************************************/
3897 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
3898 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
3900 Lisp_Object color_name
,
3901 unsigned long dflt
));
3903 /* Free X resources of image IMG which is used on frame F. */
3906 x_clear_image (f
, img
)
3910 #if 0 /* MAC_TODO: W32 image support */
3915 XFreePixmap (NULL
, img
->pixmap
);
3922 int class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
3924 /* If display has an immutable color map, freeing colors is not
3925 necessary and some servers don't allow it. So don't do it. */
3926 if (class != StaticColor
3927 && class != StaticGray
3928 && class != TrueColor
)
3932 cmap
= DefaultColormapOfScreen (FRAME_W32_DISPLAY_INFO (f
)->screen
);
3933 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
, img
->colors
,
3938 xfree (img
->colors
);
3942 #endif /* MAC_TODO */
3946 /* Allocate color COLOR_NAME for image IMG on frame F. If color
3947 cannot be allocated, use DFLT. Add a newly allocated color to
3948 IMG->colors, so that it can be freed again. Value is the pixel
3951 static unsigned long
3952 x_alloc_image_color (f
, img
, color_name
, dflt
)
3955 Lisp_Object color_name
;
3958 #if 0 /* MAC_TODO: allocing colors. */
3960 unsigned long result
;
3962 xassert (STRINGP (color_name
));
3964 if (w32_defined_color (f
, SDATA (color_name
), &color
, 1))
3966 /* This isn't called frequently so we get away with simply
3967 reallocating the color vector to the needed size, here. */
3970 (unsigned long *) xrealloc (img
->colors
,
3971 img
->ncolors
* sizeof *img
->colors
);
3972 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
3973 result
= color
.pixel
;
3978 #endif /* MAC_TODO */
3984 /***********************************************************************
3986 ***********************************************************************/
3988 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
3991 /* Return a new, initialized image cache that is allocated from the
3992 heap. Call free_image_cache to free an image cache. */
3994 struct image_cache
*
3997 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
4000 bzero (c
, sizeof *c
);
4002 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
4003 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
4004 c
->buckets
= (struct image
**) xmalloc (size
);
4005 bzero (c
->buckets
, size
);
4010 /* Free image cache of frame F. Be aware that X frames share images
4014 free_image_cache (f
)
4017 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4022 /* Cache should not be referenced by any frame when freed. */
4023 xassert (c
->refcount
== 0);
4025 for (i
= 0; i
< c
->used
; ++i
)
4026 free_image (f
, c
->images
[i
]);
4030 FRAME_X_IMAGE_CACHE (f
) = NULL
;
4035 /* Clear image cache of frame F. FORCE_P non-zero means free all
4036 images. FORCE_P zero means clear only images that haven't been
4037 displayed for some time. Should be called from time to time to
4038 reduce the number of loaded images. If image-eviction-seconds is
4039 non-nil, this frees images in the cache which weren't displayed for
4040 at least that many seconds. */
4043 clear_image_cache (f
, force_p
)
4047 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4049 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
4053 int i
, any_freed_p
= 0;
4056 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
4058 for (i
= 0; i
< c
->used
; ++i
)
4060 struct image
*img
= c
->images
[i
];
4063 || (img
->timestamp
> old
)))
4065 free_image (f
, img
);
4070 /* We may be clearing the image cache because, for example,
4071 Emacs was iconified for a longer period of time. In that
4072 case, current matrices may still contain references to
4073 images freed above. So, clear these matrices. */
4076 clear_current_matrices (f
);
4077 ++windows_or_buffers_changed
;
4083 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
4085 doc
: /* Clear the image cache of FRAME.
4086 FRAME nil or omitted means use the selected frame.
4087 FRAME t means clear the image caches of all frames. */)
4095 FOR_EACH_FRAME (tail
, frame
)
4096 if (FRAME_MAC_P (XFRAME (frame
)))
4097 clear_image_cache (XFRAME (frame
), 1);
4100 clear_image_cache (check_x_frame (frame
), 1);
4106 /* Return the id of image with Lisp specification SPEC on frame F.
4107 SPEC must be a valid Lisp image specification (see valid_image_p). */
4110 lookup_image (f
, spec
)
4114 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4118 struct gcpro gcpro1
;
4121 /* F must be a window-system frame, and SPEC must be a valid image
4123 xassert (FRAME_WINDOW_P (f
));
4124 xassert (valid_image_p (spec
));
4128 /* Look up SPEC in the hash table of the image cache. */
4129 hash
= sxhash (spec
, 0);
4130 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
4132 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
4133 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
4136 /* If not found, create a new image and cache it. */
4140 img
= make_image (spec
, hash
);
4141 cache_image (f
, img
);
4142 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
4143 xassert (!interrupt_input_blocked
);
4145 /* If we can't load the image, and we don't have a width and
4146 height, use some arbitrary width and height so that we can
4147 draw a rectangle for it. */
4148 if (img
->load_failed_p
)
4152 value
= image_spec_value (spec
, QCwidth
, NULL
);
4153 img
->width
= (INTEGERP (value
)
4154 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
4155 value
= image_spec_value (spec
, QCheight
, NULL
);
4156 img
->height
= (INTEGERP (value
)
4157 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
4161 /* Handle image type independent image attributes
4162 `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF'. */
4163 Lisp_Object ascent
, margin
, relief
;
4165 ascent
= image_spec_value (spec
, QCascent
, NULL
);
4166 if (INTEGERP (ascent
))
4167 img
->ascent
= XFASTINT (ascent
);
4168 else if (EQ (ascent
, Qcenter
))
4169 img
->ascent
= CENTERED_IMAGE_ASCENT
;
4171 margin
= image_spec_value (spec
, QCmargin
, NULL
);
4172 if (INTEGERP (margin
) && XINT (margin
) >= 0)
4173 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
4174 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
4175 && INTEGERP (XCDR (margin
)))
4177 if (XINT (XCAR (margin
)) > 0)
4178 img
->hmargin
= XFASTINT (XCAR (margin
));
4179 if (XINT (XCDR (margin
)) > 0)
4180 img
->vmargin
= XFASTINT (XCDR (margin
));
4183 relief
= image_spec_value (spec
, QCrelief
, NULL
);
4184 if (INTEGERP (relief
))
4186 img
->relief
= XINT (relief
);
4187 img
->hmargin
+= abs (img
->relief
);
4188 img
->vmargin
+= abs (img
->relief
);
4193 /* We're using IMG, so set its timestamp to `now'. */
4194 EMACS_GET_TIME (now
);
4195 img
->timestamp
= EMACS_SECS (now
);
4199 /* Value is the image id. */
4204 /* Cache image IMG in the image cache of frame F. */
4207 cache_image (f
, img
)
4211 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4214 /* Find a free slot in c->images. */
4215 for (i
= 0; i
< c
->used
; ++i
)
4216 if (c
->images
[i
] == NULL
)
4219 /* If no free slot found, maybe enlarge c->images. */
4220 if (i
== c
->used
&& c
->used
== c
->size
)
4223 c
->images
= (struct image
**) xrealloc (c
->images
,
4224 c
->size
* sizeof *c
->images
);
4227 /* Add IMG to c->images, and assign IMG an id. */
4233 /* Add IMG to the cache's hash table. */
4234 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
4235 img
->next
= c
->buckets
[i
];
4237 img
->next
->prev
= img
;
4239 c
->buckets
[i
] = img
;
4243 /* Call FN on every image in the image cache of frame F. Used to mark
4244 Lisp Objects in the image cache. */
4247 forall_images_in_image_cache (f
, fn
)
4249 void (*fn
) P_ ((struct image
*img
));
4251 if (FRAME_LIVE_P (f
) && FRAME_MAC_P (f
))
4253 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4257 for (i
= 0; i
< c
->used
; ++i
)
4266 /***********************************************************************
4268 ***********************************************************************/
4270 #if 0 /* MAC_TODO: Mac specific image code. */
4272 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
4273 XImage
**, Pixmap
*));
4274 static void x_destroy_x_image
P_ ((XImage
*));
4275 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
4278 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
4279 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
4280 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
4281 via xmalloc. Print error messages via image_error if an error
4282 occurs. Value is non-zero if successful. */
4285 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
4287 int width
, height
, depth
;
4291 #if 0 /* MAC_TODO: Image support for Mac */
4292 Display
*display
= FRAME_W32_DISPLAY (f
);
4293 Screen
*screen
= FRAME_X_SCREEN (f
);
4294 Window window
= FRAME_W32_WINDOW (f
);
4296 xassert (interrupt_input_blocked
);
4299 depth
= DefaultDepthOfScreen (screen
);
4300 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
4301 depth
, ZPixmap
, 0, NULL
, width
, height
,
4302 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
4305 image_error ("Unable to allocate X image", Qnil
, Qnil
);
4309 /* Allocate image raster. */
4310 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
4312 /* Allocate a pixmap of the same size. */
4313 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
4316 x_destroy_x_image (*ximg
);
4318 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
4321 #endif /* MAC_TODO */
4326 /* Destroy XImage XIMG. Free XIMG->data. */
4329 x_destroy_x_image (ximg
)
4332 xassert (interrupt_input_blocked
);
4337 XDestroyImage (ximg
);
4342 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
4343 are width and height of both the image and pixmap. */
4346 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
4353 xassert (interrupt_input_blocked
);
4354 gc
= XCreateGC (NULL
, pixmap
, 0, NULL
);
4355 XPutImage (NULL
, pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
4359 #endif /* MAC_TODO */
4362 /***********************************************************************
4364 ***********************************************************************/
4366 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
4368 /* Find image file FILE. Look in data-directory, then
4369 x-bitmap-file-path. Value is the full name of the file found, or
4370 nil if not found. */
4373 x_find_image_file (file
)
4376 Lisp_Object file_found
, search_path
;
4377 struct gcpro gcpro1
, gcpro2
;
4381 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
4382 GCPRO2 (file_found
, search_path
);
4384 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
4385 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
4397 /***********************************************************************
4399 ***********************************************************************/
4401 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
4402 static int xbm_load_image_from_file
P_ ((struct frame
*f
, struct image
*img
,
4404 static int xbm_image_p
P_ ((Lisp_Object object
));
4405 static int xbm_read_bitmap_file_data
P_ ((char *, int *, int *,
4409 /* Indices of image specification fields in xbm_format, below. */
4411 enum xbm_keyword_index
4428 /* Vector of image_keyword structures describing the format
4429 of valid XBM image specifications. */
4431 static struct image_keyword xbm_format
[XBM_LAST
] =
4433 {":type", IMAGE_SYMBOL_VALUE
, 1},
4434 {":file", IMAGE_STRING_VALUE
, 0},
4435 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
4436 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
4437 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4438 {":foreground", IMAGE_STRING_VALUE
, 0},
4439 {":background", IMAGE_STRING_VALUE
, 0},
4440 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
4441 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
4442 {":relief", IMAGE_INTEGER_VALUE
, 0},
4443 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4444 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
4447 /* Structure describing the image type XBM. */
4449 static struct image_type xbm_type
=
4458 /* Tokens returned from xbm_scan. */
4467 /* Return non-zero if OBJECT is a valid XBM-type image specification.
4468 A valid specification is a list starting with the symbol `image'
4469 The rest of the list is a property list which must contain an
4472 If the specification specifies a file to load, it must contain
4473 an entry `:file FILENAME' where FILENAME is a string.
4475 If the specification is for a bitmap loaded from memory it must
4476 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
4477 WIDTH and HEIGHT are integers > 0. DATA may be:
4479 1. a string large enough to hold the bitmap data, i.e. it must
4480 have a size >= (WIDTH + 7) / 8 * HEIGHT
4482 2. a bool-vector of size >= WIDTH * HEIGHT
4484 3. a vector of strings or bool-vectors, one for each line of the
4487 Both the file and data forms may contain the additional entries
4488 `:background COLOR' and `:foreground COLOR'. If not present,
4489 foreground and background of the frame on which the image is
4490 displayed, is used. */
4493 xbm_image_p (object
)
4496 struct image_keyword kw
[XBM_LAST
];
4498 bcopy (xbm_format
, kw
, sizeof kw
);
4499 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
4502 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
4504 if (kw
[XBM_FILE
].count
)
4506 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
4514 /* Entries for `:width', `:height' and `:data' must be present. */
4515 if (!kw
[XBM_WIDTH
].count
4516 || !kw
[XBM_HEIGHT
].count
4517 || !kw
[XBM_DATA
].count
)
4520 data
= kw
[XBM_DATA
].value
;
4521 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
4522 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
4524 /* Check type of data, and width and height against contents of
4530 /* Number of elements of the vector must be >= height. */
4531 if (XVECTOR (data
)->size
< height
)
4534 /* Each string or bool-vector in data must be large enough
4535 for one line of the image. */
4536 for (i
= 0; i
< height
; ++i
)
4538 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
4543 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
4546 else if (BOOL_VECTOR_P (elt
))
4548 if (XBOOL_VECTOR (elt
)->size
< width
)
4555 else if (STRINGP (data
))
4558 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
4561 else if (BOOL_VECTOR_P (data
))
4563 if (XBOOL_VECTOR (data
)->size
< width
* height
)
4570 /* Baseline must be a value between 0 and 100 (a percentage). */
4571 if (kw
[XBM_ASCENT
].count
4572 && XFASTINT (kw
[XBM_ASCENT
].value
) > 100)
4579 /* Scan a bitmap file. FP is the stream to read from. Value is
4580 either an enumerator from enum xbm_token, or a character for a
4581 single-character token, or 0 at end of file. If scanning an
4582 identifier, store the lexeme of the identifier in SVAL. If
4583 scanning a number, store its value in *IVAL. */
4586 xbm_scan (fp
, sval
, ival
)
4593 /* Skip white space. */
4594 while ((c
= fgetc (fp
)) != EOF
&& isspace (c
))
4599 else if (isdigit (c
))
4601 int value
= 0, digit
;
4606 if (c
== 'x' || c
== 'X')
4608 while ((c
= fgetc (fp
)) != EOF
)
4612 else if (c
>= 'a' && c
<= 'f')
4613 digit
= c
- 'a' + 10;
4614 else if (c
>= 'A' && c
<= 'F')
4615 digit
= c
- 'A' + 10;
4618 value
= 16 * value
+ digit
;
4621 else if (isdigit (c
))
4624 while ((c
= fgetc (fp
)) != EOF
4626 value
= 8 * value
+ c
- '0';
4632 while ((c
= fgetc (fp
)) != EOF
4634 value
= 10 * value
+ c
- '0';
4642 else if (isalpha (c
) || c
== '_')
4645 while ((c
= fgetc (fp
)) != EOF
4646 && (isalnum (c
) || c
== '_'))
4658 /* Replacement for XReadBitmapFileData which isn't available under old
4659 X versions. FILE is the name of the bitmap file to read. Set
4660 *WIDTH and *HEIGHT to the width and height of the image. Return in
4661 *DATA the bitmap data allocated with xmalloc. Value is non-zero if
4665 xbm_read_bitmap_file_data (file
, width
, height
, data
)
4667 int *width
, *height
;
4668 unsigned char **data
;
4671 char buffer
[BUFSIZ
];
4674 int bytes_per_line
, i
, nbytes
;
4680 LA1 = xbm_scan (fp, buffer, &value)
4682 #define expect(TOKEN) \
4683 if (LA1 != (TOKEN)) \
4688 #define expect_ident(IDENT) \
4689 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
4694 fp
= fopen (file
, "r");
4698 *width
= *height
= -1;
4700 LA1
= xbm_scan (fp
, buffer
, &value
);
4702 /* Parse defines for width, height and hot-spots. */
4706 expect_ident ("define");
4707 expect (XBM_TK_IDENT
);
4709 if (LA1
== XBM_TK_NUMBER
);
4711 char *p
= strrchr (buffer
, '_');
4712 p
= p
? p
+ 1 : buffer
;
4713 if (strcmp (p
, "width") == 0)
4715 else if (strcmp (p
, "height") == 0)
4718 expect (XBM_TK_NUMBER
);
4721 if (*width
< 0 || *height
< 0)
4724 /* Parse bits. Must start with `static'. */
4725 expect_ident ("static");
4726 if (LA1
== XBM_TK_IDENT
)
4728 if (strcmp (buffer
, "unsigned") == 0)
4731 expect_ident ("char");
4733 else if (strcmp (buffer
, "short") == 0)
4737 if (*width
% 16 && *width
% 16 < 9)
4740 else if (strcmp (buffer
, "char") == 0)
4748 expect (XBM_TK_IDENT
);
4754 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
4755 nbytes
= bytes_per_line
* *height
;
4756 p
= *data
= (char *) xmalloc (nbytes
);
4761 for (i
= 0; i
< nbytes
; i
+= 2)
4764 expect (XBM_TK_NUMBER
);
4767 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
4770 if (LA1
== ',' || LA1
== '}')
4778 for (i
= 0; i
< nbytes
; ++i
)
4781 expect (XBM_TK_NUMBER
);
4785 if (LA1
== ',' || LA1
== '}')
4811 /* Load XBM image IMG which will be displayed on frame F from file
4812 SPECIFIED_FILE. Value is non-zero if successful. */
4815 xbm_load_image_from_file (f
, img
, specified_file
)
4818 Lisp_Object specified_file
;
4821 unsigned char *data
;
4824 struct gcpro gcpro1
;
4826 xassert (STRINGP (specified_file
));
4830 file
= x_find_image_file (specified_file
);
4831 if (!STRINGP (file
))
4833 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
4838 rc
= xbm_read_bitmap_file_data (SDATA (file
), &img
->width
,
4839 &img
->height
, &data
);
4842 int depth
= one_mac_display_info
.n_cbits
;
4843 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
4844 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
4847 xassert (img
->width
> 0 && img
->height
> 0);
4849 /* Get foreground and background colors, maybe allocate colors. */
4850 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
4852 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
4854 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
4856 background
= x_alloc_image_color (f
, img
, value
, background
);
4858 #if 0 /* MAC_TODO : Port image display to Mac */
4861 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
4862 FRAME_W32_WINDOW (f
),
4864 img
->width
, img
->height
,
4865 foreground
, background
,
4869 if (img
->pixmap
== 0)
4871 x_clear_image (f
, img
);
4872 image_error ("Unable to create X pixmap for `%s'", file
, Qnil
);
4878 #endif /* MAC_TODO */
4881 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
4888 /* Fill image IMG which is used on frame F with pixmap data. Value is
4889 non-zero if successful. */
4897 Lisp_Object file_name
;
4899 xassert (xbm_image_p (img
->spec
));
4901 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4902 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4903 if (STRINGP (file_name
))
4904 success_p
= xbm_load_image_from_file (f
, img
, file_name
);
4907 struct image_keyword fmt
[XBM_LAST
];
4910 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
4911 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
4915 /* Parse the list specification. */
4916 bcopy (xbm_format
, fmt
, sizeof fmt
);
4917 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
4920 /* Get specified width, and height. */
4921 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
4922 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
4923 xassert (img
->width
> 0 && img
->height
> 0);
4927 if (fmt
[XBM_ASCENT
].count
)
4928 img
->ascent
= XFASTINT (fmt
[XBM_ASCENT
].value
);
4930 /* Get foreground and background colors, maybe allocate colors. */
4931 if (fmt
[XBM_FOREGROUND
].count
)
4932 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
4934 if (fmt
[XBM_BACKGROUND
].count
)
4935 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
4938 /* Set bits to the bitmap image data. */
4939 data
= fmt
[XBM_DATA
].value
;
4944 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
4946 p
= bits
= (char *) alloca (nbytes
* img
->height
);
4947 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
4949 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
4951 bcopy (SDATA (line
), p
, nbytes
);
4953 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
4956 else if (STRINGP (data
))
4957 bits
= SDATA (data
);
4959 bits
= XBOOL_VECTOR (data
)->data
;
4961 #if 0 /* MAC_TODO : port Mac display code */
4962 /* Create the pixmap. */
4963 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
4965 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
4966 FRAME_W32_WINDOW (f
),
4968 img
->width
, img
->height
,
4969 foreground
, background
,
4971 #endif /* MAC_TODO */
4977 image_error ("Unable to create pixmap for XBM image `%s'",
4979 x_clear_image (f
, img
);
4990 /***********************************************************************
4992 ***********************************************************************/
4996 static int xpm_image_p
P_ ((Lisp_Object object
));
4997 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
4998 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
5000 #include "X11/xpm.h"
5002 /* The symbol `xpm' identifying XPM-format images. */
5006 /* Indices of image specification fields in xpm_format, below. */
5008 enum xpm_keyword_index
5022 /* Vector of image_keyword structures describing the format
5023 of valid XPM image specifications. */
5025 static struct image_keyword xpm_format
[XPM_LAST
] =
5027 {":type", IMAGE_SYMBOL_VALUE
, 1},
5028 {":file", IMAGE_STRING_VALUE
, 0},
5029 {":data", IMAGE_STRING_VALUE
, 0},
5030 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
5031 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5032 {":relief", IMAGE_INTEGER_VALUE
, 0},
5033 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5034 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5035 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5038 /* Structure describing the image type XBM. */
5040 static struct image_type xpm_type
=
5050 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
5051 for XPM images. Such a list must consist of conses whose car and
5055 xpm_valid_color_symbols_p (color_symbols
)
5056 Lisp_Object color_symbols
;
5058 while (CONSP (color_symbols
))
5060 Lisp_Object sym
= XCAR (color_symbols
);
5062 || !STRINGP (XCAR (sym
))
5063 || !STRINGP (XCDR (sym
)))
5065 color_symbols
= XCDR (color_symbols
);
5068 return NILP (color_symbols
);
5072 /* Value is non-zero if OBJECT is a valid XPM image specification. */
5075 xpm_image_p (object
)
5078 struct image_keyword fmt
[XPM_LAST
];
5079 bcopy (xpm_format
, fmt
, sizeof fmt
);
5080 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
5081 /* Either `:file' or `:data' must be present. */
5082 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
5083 /* Either no `:color-symbols' or it's a list of conses
5084 whose car and cdr are strings. */
5085 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
5086 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
))
5087 && (fmt
[XPM_ASCENT
].count
== 0
5088 || XFASTINT (fmt
[XPM_ASCENT
].value
) < 100));
5092 /* Load image IMG which will be displayed on frame F. Value is
5093 non-zero if successful. */
5101 XpmAttributes attrs
;
5102 Lisp_Object specified_file
, color_symbols
;
5104 /* Configure the XPM lib. Use the visual of frame F. Allocate
5105 close colors. Return colors allocated. */
5106 bzero (&attrs
, sizeof attrs
);
5107 attrs
.visual
= FRAME_X_VISUAL (f
);
5108 attrs
.colormap
= FRAME_X_COLORMAP (f
);
5109 attrs
.valuemask
|= XpmVisual
;
5110 attrs
.valuemask
|= XpmColormap
;
5111 attrs
.valuemask
|= XpmReturnAllocPixels
;
5112 #ifdef XpmAllocCloseColors
5113 attrs
.alloc_close_colors
= 1;
5114 attrs
.valuemask
|= XpmAllocCloseColors
;
5116 attrs
.closeness
= 600;
5117 attrs
.valuemask
|= XpmCloseness
;
5120 /* If image specification contains symbolic color definitions, add
5121 these to `attrs'. */
5122 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
5123 if (CONSP (color_symbols
))
5126 XpmColorSymbol
*xpm_syms
;
5129 attrs
.valuemask
|= XpmColorSymbols
;
5131 /* Count number of symbols. */
5132 attrs
.numsymbols
= 0;
5133 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
5136 /* Allocate an XpmColorSymbol array. */
5137 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
5138 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
5139 bzero (xpm_syms
, size
);
5140 attrs
.colorsymbols
= xpm_syms
;
5142 /* Fill the color symbol array. */
5143 for (tail
= color_symbols
, i
= 0;
5145 ++i
, tail
= XCDR (tail
))
5147 Lisp_Object name
= XCAR (XCAR (tail
));
5148 Lisp_Object color
= XCDR (XCAR (tail
));
5149 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
5150 strcpy (xpm_syms
[i
].name
, SDATA (name
));
5151 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
5152 strcpy (xpm_syms
[i
].value
, SDATA (color
));
5156 /* Create a pixmap for the image, either from a file, or from a
5157 string buffer containing data in the same format as an XPM file. */
5159 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5160 if (STRINGP (specified_file
))
5162 Lisp_Object file
= x_find_image_file (specified_file
);
5163 if (!STRINGP (file
))
5165 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5170 rc
= XpmReadFileToPixmap (NULL
, FRAME_W32_WINDOW (f
),
5171 SDATA (file
), &img
->pixmap
, &img
->mask
,
5176 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
5177 rc
= XpmCreatePixmapFromBuffer (NULL
, FRAME_W32_WINDOW (f
),
5179 &img
->pixmap
, &img
->mask
,
5184 if (rc
== XpmSuccess
)
5186 /* Remember allocated colors. */
5187 img
->ncolors
= attrs
.nalloc_pixels
;
5188 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
5189 * sizeof *img
->colors
);
5190 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
5191 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
5193 img
->width
= attrs
.width
;
5194 img
->height
= attrs
.height
;
5195 xassert (img
->width
> 0 && img
->height
> 0);
5197 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
5199 XpmFreeAttributes (&attrs
);
5207 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
5210 case XpmFileInvalid
:
5211 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
5215 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
5218 case XpmColorFailed
:
5219 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
5223 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
5228 return rc
== XpmSuccess
;
5231 #endif /* HAVE_XPM != 0 */
5234 #if 0 /* MAC_TODO : Color tables on Mac. */
5235 /***********************************************************************
5237 ***********************************************************************/
5239 /* An entry in the color table mapping an RGB color to a pixel color. */
5244 unsigned long pixel
;
5246 /* Next in color table collision list. */
5247 struct ct_color
*next
;
5250 /* The bucket vector size to use. Must be prime. */
5254 /* Value is a hash of the RGB color given by R, G, and B. */
5256 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
5258 /* The color hash table. */
5260 struct ct_color
**ct_table
;
5262 /* Number of entries in the color table. */
5264 int ct_colors_allocated
;
5266 /* Function prototypes. */
5268 static void init_color_table
P_ ((void));
5269 static void free_color_table
P_ ((void));
5270 static unsigned long *colors_in_color_table
P_ ((int *n
));
5271 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
5272 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
5275 /* Initialize the color table. */
5280 int size
= CT_SIZE
* sizeof (*ct_table
);
5281 ct_table
= (struct ct_color
**) xmalloc (size
);
5282 bzero (ct_table
, size
);
5283 ct_colors_allocated
= 0;
5287 /* Free memory associated with the color table. */
5293 struct ct_color
*p
, *next
;
5295 for (i
= 0; i
< CT_SIZE
; ++i
)
5296 for (p
= ct_table
[i
]; p
; p
= next
)
5307 /* Value is a pixel color for RGB color R, G, B on frame F. If an
5308 entry for that color already is in the color table, return the
5309 pixel color of that entry. Otherwise, allocate a new color for R,
5310 G, B, and make an entry in the color table. */
5312 static unsigned long
5313 lookup_rgb_color (f
, r
, g
, b
)
5317 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
5318 int i
= hash
% CT_SIZE
;
5321 for (p
= ct_table
[i
]; p
; p
= p
->next
)
5322 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
5331 color
= RGB_TO_ULONG (r
, g
, b
);
5333 ++ct_colors_allocated
;
5335 p
= (struct ct_color
*) xmalloc (sizeof *p
);
5340 p
->next
= ct_table
[i
];
5348 /* Look up pixel color PIXEL which is used on frame F in the color
5349 table. If not already present, allocate it. Value is PIXEL. */
5351 static unsigned long
5352 lookup_pixel_color (f
, pixel
)
5354 unsigned long pixel
;
5356 int i
= pixel
% CT_SIZE
;
5359 for (p
= ct_table
[i
]; p
; p
= p
->next
)
5360 if (p
->pixel
== pixel
)
5371 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
5372 color
.pixel
= pixel
;
5373 XQueryColor (NULL
, cmap
, &color
);
5374 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
5379 ++ct_colors_allocated
;
5381 p
= (struct ct_color
*) xmalloc (sizeof *p
);
5386 p
->next
= ct_table
[i
];
5390 return FRAME_FOREGROUND_PIXEL (f
);
5396 /* Value is a vector of all pixel colors contained in the color table,
5397 allocated via xmalloc. Set *N to the number of colors. */
5399 static unsigned long *
5400 colors_in_color_table (n
)
5405 unsigned long *colors
;
5407 if (ct_colors_allocated
== 0)
5414 colors
= (unsigned long *) xmalloc (ct_colors_allocated
5416 *n
= ct_colors_allocated
;
5418 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
5419 for (p
= ct_table
[i
]; p
; p
= p
->next
)
5420 colors
[j
++] = p
->pixel
;
5426 #endif /* MAC_TODO */
5429 /***********************************************************************
5431 ***********************************************************************/
5433 #if 0 /* MAC_TODO : Mac versions of low level algorithms */
5434 static void x_laplace_write_row
P_ ((struct frame
*, long *,
5435 int, XImage
*, int));
5436 static void x_laplace_read_row
P_ ((struct frame
*, Colormap
,
5437 XColor
*, int, XImage
*, int));
5440 /* Fill COLORS with RGB colors from row Y of image XIMG. F is the
5441 frame we operate on, CMAP is the color-map in effect, and WIDTH is
5442 the width of one row in the image. */
5445 x_laplace_read_row (f
, cmap
, colors
, width
, ximg
, y
)
5455 for (x
= 0; x
< width
; ++x
)
5456 colors
[x
].pixel
= XGetPixel (ximg
, x
, y
);
5458 XQueryColors (NULL
, cmap
, colors
, width
);
5462 /* Write row Y of image XIMG. PIXELS is an array of WIDTH longs
5463 containing the pixel colors to write. F is the frame we are
5467 x_laplace_write_row (f
, pixels
, width
, ximg
, y
)
5476 for (x
= 0; x
< width
; ++x
)
5477 XPutPixel (ximg
, x
, y
, pixels
[x
]);
5479 #endif /* MAC_TODO */
5481 /* Transform image IMG which is used on frame F with a Laplace
5482 edge-detection algorithm. The result is an image that can be used
5483 to draw disabled buttons, for example. */
5490 #if 0 /* MAC_TODO : Mac version */
5491 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
5492 XImage
*ximg
, *oimg
;
5498 int in_y
, out_y
, rc
;
5503 /* Get the X image IMG->pixmap. */
5504 ximg
= XGetImage (NULL
, img
->pixmap
,
5505 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
5507 /* Allocate 3 input rows, and one output row of colors. */
5508 for (i
= 0; i
< 3; ++i
)
5509 in
[i
] = (XColor
*) alloca (img
->width
* sizeof (XColor
));
5510 out
= (long *) alloca (img
->width
* sizeof (long));
5512 /* Create an X image for output. */
5513 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
5516 /* Fill first two rows. */
5517 x_laplace_read_row (f
, cmap
, in
[0], img
->width
, ximg
, 0);
5518 x_laplace_read_row (f
, cmap
, in
[1], img
->width
, ximg
, 1);
5521 /* Write first row, all zeros. */
5522 init_color_table ();
5523 pixel
= lookup_rgb_color (f
, 0, 0, 0);
5524 for (x
= 0; x
< img
->width
; ++x
)
5526 x_laplace_write_row (f
, out
, img
->width
, oimg
, 0);
5529 for (y
= 2; y
< img
->height
; ++y
)
5532 int rowb
= (y
+ 2) % 3;
5534 x_laplace_read_row (f
, cmap
, in
[rowa
], img
->width
, ximg
, in_y
++);
5536 for (x
= 0; x
< img
->width
- 2; ++x
)
5538 int r
= in
[rowa
][x
].red
+ mv2
- in
[rowb
][x
+ 2].red
;
5539 int g
= in
[rowa
][x
].green
+ mv2
- in
[rowb
][x
+ 2].green
;
5540 int b
= in
[rowa
][x
].blue
+ mv2
- in
[rowb
][x
+ 2].blue
;
5542 out
[x
+ 1] = lookup_rgb_color (f
, r
& 0xffff, g
& 0xffff,
5546 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
++);
5549 /* Write last line, all zeros. */
5550 for (x
= 0; x
< img
->width
; ++x
)
5552 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
);
5554 /* Free the input image, and free resources of IMG. */
5555 XDestroyImage (ximg
);
5556 x_clear_image (f
, img
);
5558 /* Put the output image into pixmap, and destroy it. */
5559 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
5560 x_destroy_x_image (oimg
);
5562 /* Remember new pixmap and colors in IMG. */
5563 img
->pixmap
= pixmap
;
5564 img
->colors
= colors_in_color_table (&img
->ncolors
);
5565 free_color_table ();
5568 #endif /* MAC_TODO */
5572 /* Build a mask for image IMG which is used on frame F. FILE is the
5573 name of an image file, for error messages. HOW determines how to
5574 determine the background color of IMG. If it is a list '(R G B)',
5575 with R, G, and B being integers >= 0, take that as the color of the
5576 background. Otherwise, determine the background color of IMG
5577 heuristically. Value is non-zero if successful. */
5580 x_build_heuristic_mask (f
, img
, how
)
5585 #if 0 /* MAC_TODO : Mac version */
5586 Display
*dpy
= FRAME_W32_DISPLAY (f
);
5587 XImage
*ximg
, *mask_img
;
5588 int x
, y
, rc
, look_at_corners_p
;
5593 /* Create an image and pixmap serving as mask. */
5594 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
5595 &mask_img
, &img
->mask
);
5602 /* Get the X image of IMG->pixmap. */
5603 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
5606 /* Determine the background color of ximg. If HOW is `(R G B)'
5607 take that as color. Otherwise, try to determine the color
5609 look_at_corners_p
= 1;
5617 && NATNUMP (XCAR (how
)))
5619 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
5623 if (i
== 3 && NILP (how
))
5625 char color_name
[30];
5626 XColor exact
, color
;
5629 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
5631 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
5632 if (XLookupColor (dpy
, cmap
, color_name
, &exact
, &color
))
5635 look_at_corners_p
= 0;
5640 if (look_at_corners_p
)
5642 unsigned long corners
[4];
5645 /* Get the colors at the corners of ximg. */
5646 corners
[0] = XGetPixel (ximg
, 0, 0);
5647 corners
[1] = XGetPixel (ximg
, img
->width
- 1, 0);
5648 corners
[2] = XGetPixel (ximg
, img
->width
- 1, img
->height
- 1);
5649 corners
[3] = XGetPixel (ximg
, 0, img
->height
- 1);
5651 /* Choose the most frequently found color as background. */
5652 for (i
= best_count
= 0; i
< 4; ++i
)
5656 for (j
= n
= 0; j
< 4; ++j
)
5657 if (corners
[i
] == corners
[j
])
5661 bg
= corners
[i
], best_count
= n
;
5665 /* Set all bits in mask_img to 1 whose color in ximg is different
5666 from the background color bg. */
5667 for (y
= 0; y
< img
->height
; ++y
)
5668 for (x
= 0; x
< img
->width
; ++x
)
5669 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
5671 /* Put mask_img into img->mask. */
5672 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
5673 x_destroy_x_image (mask_img
);
5674 XDestroyImage (ximg
);
5677 #endif /* MAC_TODO */
5684 /***********************************************************************
5685 PBM (mono, gray, color)
5686 ***********************************************************************/
5689 static int pbm_image_p
P_ ((Lisp_Object object
));
5690 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
5691 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
5693 /* The symbol `pbm' identifying images of this type. */
5697 /* Indices of image specification fields in gs_format, below. */
5699 enum pbm_keyword_index
5712 /* Vector of image_keyword structures describing the format
5713 of valid user-defined image specifications. */
5715 static struct image_keyword pbm_format
[PBM_LAST
] =
5717 {":type", IMAGE_SYMBOL_VALUE
, 1},
5718 {":file", IMAGE_STRING_VALUE
, 0},
5719 {":data", IMAGE_STRING_VALUE
, 0},
5720 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
5721 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5722 {":relief", IMAGE_INTEGER_VALUE
, 0},
5723 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5724 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5727 /* Structure describing the image type `pbm'. */
5729 static struct image_type pbm_type
=
5739 /* Return non-zero if OBJECT is a valid PBM image specification. */
5742 pbm_image_p (object
)
5745 struct image_keyword fmt
[PBM_LAST
];
5747 bcopy (pbm_format
, fmt
, sizeof fmt
);
5749 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
)
5750 || (fmt
[PBM_ASCENT
].count
5751 && XFASTINT (fmt
[PBM_ASCENT
].value
) > 100))
5754 /* Must specify either :data or :file. */
5755 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
5759 /* Scan a decimal number from *S and return it. Advance *S while
5760 reading the number. END is the end of the string. Value is -1 at
5764 pbm_scan_number (s
, end
)
5765 unsigned char **s
, *end
;
5771 /* Skip white-space. */
5772 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5777 /* Skip comment to end of line. */
5778 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
5781 else if (isdigit (c
))
5783 /* Read decimal number. */
5785 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
5786 val
= 10 * val
+ c
- '0';
5797 /* Read FILE into memory. Value is a pointer to a buffer allocated
5798 with xmalloc holding FILE's contents. Value is null if an error
5799 occurred. *SIZE is set to the size of the file. */
5802 pbm_read_file (file
, size
)
5810 if (stat (SDATA (file
), &st
) == 0
5811 && (fp
= fopen (SDATA (file
), "r")) != NULL
5812 && (buf
= (char *) xmalloc (st
.st_size
),
5813 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5833 /* Load PBM image IMG for use on frame F. */
5841 int width
, height
, max_color_idx
= 0;
5843 Lisp_Object file
, specified_file
;
5844 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5845 struct gcpro gcpro1
;
5846 unsigned char *contents
= NULL
;
5847 unsigned char *end
, *p
;
5850 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5854 if (STRINGP (specified_file
))
5856 file
= x_find_image_file (specified_file
);
5857 if (!STRINGP (file
))
5859 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5864 contents
= pbm_read_file (file
, &size
);
5865 if (contents
== NULL
)
5867 image_error ("Error reading `%s'", file
, Qnil
);
5873 end
= contents
+ size
;
5878 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5880 end
= p
+ SBYTES (data
);
5883 /* Check magic number. */
5884 if (end
- p
< 2 || *p
++ != 'P')
5886 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5896 raw_p
= 0, type
= PBM_MONO
;
5900 raw_p
= 0, type
= PBM_GRAY
;
5904 raw_p
= 0, type
= PBM_COLOR
;
5908 raw_p
= 1, type
= PBM_MONO
;
5912 raw_p
= 1, type
= PBM_GRAY
;
5916 raw_p
= 1, type
= PBM_COLOR
;
5920 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5924 /* Read width, height, maximum color-component. Characters
5925 starting with `#' up to the end of a line are ignored. */
5926 width
= pbm_scan_number (&p
, end
);
5927 height
= pbm_scan_number (&p
, end
);
5929 if (type
!= PBM_MONO
)
5931 max_color_idx
= pbm_scan_number (&p
, end
);
5932 if (raw_p
&& max_color_idx
> 255)
5933 max_color_idx
= 255;
5938 || (type
!= PBM_MONO
&& max_color_idx
< 0))
5942 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
5943 &ximg
, &img
->pixmap
))
5949 /* Initialize the color hash table. */
5950 init_color_table ();
5952 if (type
== PBM_MONO
)
5956 for (y
= 0; y
< height
; ++y
)
5957 for (x
= 0; x
< width
; ++x
)
5967 g
= pbm_scan_number (&p
, end
);
5969 XPutPixel (ximg
, x
, y
, (g
5970 ? FRAME_FOREGROUND_PIXEL (f
)
5971 : FRAME_BACKGROUND_PIXEL (f
)));
5976 for (y
= 0; y
< height
; ++y
)
5977 for (x
= 0; x
< width
; ++x
)
5981 if (type
== PBM_GRAY
)
5982 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
5991 r
= pbm_scan_number (&p
, end
);
5992 g
= pbm_scan_number (&p
, end
);
5993 b
= pbm_scan_number (&p
, end
);
5996 if (r
< 0 || g
< 0 || b
< 0)
6000 XDestroyImage (ximg
);
6002 image_error ("Invalid pixel value in image `%s'",
6007 /* RGB values are now in the range 0..max_color_idx.
6008 Scale this to the range 0..0xffff supported by X. */
6009 r
= (double) r
* 65535 / max_color_idx
;
6010 g
= (double) g
* 65535 / max_color_idx
;
6011 b
= (double) b
* 65535 / max_color_idx
;
6012 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
6016 /* Store in IMG->colors the colors allocated for the image, and
6017 free the color table. */
6018 img
->colors
= colors_in_color_table (&img
->ncolors
);
6019 free_color_table ();
6021 /* Put the image into a pixmap. */
6022 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6023 x_destroy_x_image (ximg
);
6027 img
->height
= height
;
6033 #endif /* HAVE_PBM */
6036 /***********************************************************************
6038 ***********************************************************************/
6044 /* Function prototypes. */
6046 static int png_image_p
P_ ((Lisp_Object object
));
6047 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
6049 /* The symbol `png' identifying images of this type. */
6053 /* Indices of image specification fields in png_format, below. */
6055 enum png_keyword_index
6068 /* Vector of image_keyword structures describing the format
6069 of valid user-defined image specifications. */
6071 static struct image_keyword png_format
[PNG_LAST
] =
6073 {":type", IMAGE_SYMBOL_VALUE
, 1},
6074 {":data", IMAGE_STRING_VALUE
, 0},
6075 {":file", IMAGE_STRING_VALUE
, 0},
6076 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6077 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6078 {":relief", IMAGE_INTEGER_VALUE
, 0},
6079 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6080 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6083 /* Structure describing the image type `png'. */
6085 static struct image_type png_type
=
6095 /* Return non-zero if OBJECT is a valid PNG image specification. */
6098 png_image_p (object
)
6101 struct image_keyword fmt
[PNG_LAST
];
6102 bcopy (png_format
, fmt
, sizeof fmt
);
6104 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
)
6105 || (fmt
[PNG_ASCENT
].count
6106 && XFASTINT (fmt
[PNG_ASCENT
].value
) > 100))
6109 /* Must specify either the :data or :file keyword. */
6110 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
6114 /* Error and warning handlers installed when the PNG library
6118 my_png_error (png_ptr
, msg
)
6119 png_struct
*png_ptr
;
6122 xassert (png_ptr
!= NULL
);
6123 image_error ("PNG error: %s", build_string (msg
), Qnil
);
6124 longjmp (png_ptr
->jmpbuf
, 1);
6129 my_png_warning (png_ptr
, msg
)
6130 png_struct
*png_ptr
;
6133 xassert (png_ptr
!= NULL
);
6134 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
6137 /* Memory source for PNG decoding. */
6139 struct png_memory_storage
6141 unsigned char *bytes
; /* The data */
6142 size_t len
; /* How big is it? */
6143 int index
; /* Where are we? */
6147 /* Function set as reader function when reading PNG image from memory.
6148 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
6149 bytes from the input to DATA. */
6152 png_read_from_memory (png_ptr
, data
, length
)
6153 png_structp png_ptr
;
6157 struct png_memory_storage
*tbr
6158 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
6160 if (length
> tbr
->len
- tbr
->index
)
6161 png_error (png_ptr
, "Read error");
6163 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
6164 tbr
->index
= tbr
->index
+ length
;
6167 /* Load PNG image IMG for use on frame F. Value is non-zero if
6175 Lisp_Object file
, specified_file
;
6176 Lisp_Object specified_data
;
6178 XImage
*ximg
, *mask_img
= NULL
;
6179 struct gcpro gcpro1
;
6180 png_struct
*png_ptr
= NULL
;
6181 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
6184 png_byte
*pixels
= NULL
;
6185 png_byte
**rows
= NULL
;
6186 png_uint_32 width
, height
;
6187 int bit_depth
, color_type
, interlace_type
;
6189 png_uint_32 row_bytes
;
6192 double screen_gamma
, image_gamma
;
6194 struct png_memory_storage tbr
; /* Data to be read */
6196 /* Find out what file to load. */
6197 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6198 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6202 if (NILP (specified_data
))
6204 file
= x_find_image_file (specified_file
);
6205 if (!STRINGP (file
))
6207 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6212 /* Open the image file. */
6213 fp
= fopen (SDATA (file
), "rb");
6216 image_error ("Cannot open image file `%s'", file
, Qnil
);
6222 /* Check PNG signature. */
6223 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
6224 || !png_check_sig (sig
, sizeof sig
))
6226 image_error ("Not a PNG file:` %s'", file
, Qnil
);
6234 /* Read from memory. */
6235 tbr
.bytes
= SDATA (specified_data
);
6236 tbr
.len
= SBYTES (specified_data
);
6239 /* Check PNG signature. */
6240 if (tbr
.len
< sizeof sig
6241 || !png_check_sig (tbr
.bytes
, sizeof sig
))
6243 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
6248 /* Need to skip past the signature. */
6249 tbr
.bytes
+= sizeof (sig
);
6252 /* Initialize read and info structs for PNG lib. */
6253 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
6254 my_png_error
, my_png_warning
);
6257 if (fp
) fclose (fp
);
6262 info_ptr
= png_create_info_struct (png_ptr
);
6265 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
6266 if (fp
) fclose (fp
);
6271 end_info
= png_create_info_struct (png_ptr
);
6274 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
6275 if (fp
) fclose (fp
);
6280 /* Set error jump-back. We come back here when the PNG library
6281 detects an error. */
6282 if (setjmp (png_ptr
->jmpbuf
))
6286 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
6289 if (fp
) fclose (fp
);
6294 /* Read image info. */
6295 if (!NILP (specified_data
))
6296 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
6298 png_init_io (png_ptr
, fp
);
6300 png_set_sig_bytes (png_ptr
, sizeof sig
);
6301 png_read_info (png_ptr
, info_ptr
);
6302 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
6303 &interlace_type
, NULL
, NULL
);
6305 /* If image contains simply transparency data, we prefer to
6306 construct a clipping mask. */
6307 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
6312 /* This function is easier to write if we only have to handle
6313 one data format: RGB or RGBA with 8 bits per channel. Let's
6314 transform other formats into that format. */
6316 /* Strip more than 8 bits per channel. */
6317 if (bit_depth
== 16)
6318 png_set_strip_16 (png_ptr
);
6320 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
6322 png_set_expand (png_ptr
);
6324 /* Convert grayscale images to RGB. */
6325 if (color_type
== PNG_COLOR_TYPE_GRAY
6326 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
6327 png_set_gray_to_rgb (png_ptr
);
6329 /* The value 2.2 is a guess for PC monitors from PNG example.c. */
6330 gamma_str
= getenv ("SCREEN_GAMMA");
6331 screen_gamma
= gamma_str
? atof (gamma_str
) : 2.2;
6333 /* Tell the PNG lib to handle gamma correction for us. */
6335 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
6336 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
6337 /* There is a special chunk in the image specifying the gamma. */
6338 png_set_sRGB (png_ptr
, info_ptr
, intent
);
6341 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
6342 /* Image contains gamma information. */
6343 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
6345 /* Use a default of 0.5 for the image gamma. */
6346 png_set_gamma (png_ptr
, screen_gamma
, 0.5);
6348 /* Handle alpha channel by combining the image with a background
6349 color. Do this only if a real alpha channel is supplied. For
6350 simple transparency, we prefer a clipping mask. */
6353 png_color_16
*image_background
;
6355 if (png_get_bKGD (png_ptr
, info_ptr
, &image_background
))
6356 /* Image contains a background color with which to
6357 combine the image. */
6358 png_set_background (png_ptr
, image_background
,
6359 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
6362 /* Image does not contain a background color with which
6363 to combine the image data via an alpha channel. Use
6364 the frame's background instead. */
6367 png_color_16 frame_background
;
6370 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6371 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
6372 XQueryColor (FRAME_W32_DISPLAY (f
), cmap
, &color
);
6375 bzero (&frame_background
, sizeof frame_background
);
6376 frame_background
.red
= color
.red
;
6377 frame_background
.green
= color
.green
;
6378 frame_background
.blue
= color
.blue
;
6380 png_set_background (png_ptr
, &frame_background
,
6381 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
6385 /* Update info structure. */
6386 png_read_update_info (png_ptr
, info_ptr
);
6388 /* Get number of channels. Valid values are 1 for grayscale images
6389 and images with a palette, 2 for grayscale images with transparency
6390 information (alpha channel), 3 for RGB images, and 4 for RGB
6391 images with alpha channel, i.e. RGBA. If conversions above were
6392 sufficient we should only have 3 or 4 channels here. */
6393 channels
= png_get_channels (png_ptr
, info_ptr
);
6394 xassert (channels
== 3 || channels
== 4);
6396 /* Number of bytes needed for one row of the image. */
6397 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
6399 /* Allocate memory for the image. */
6400 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
6401 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
6402 for (i
= 0; i
< height
; ++i
)
6403 rows
[i
] = pixels
+ i
* row_bytes
;
6405 /* Read the entire image. */
6406 png_read_image (png_ptr
, rows
);
6407 png_read_end (png_ptr
, info_ptr
);
6416 /* Create the X image and pixmap. */
6417 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
6424 /* Create an image and pixmap serving as mask if the PNG image
6425 contains an alpha channel. */
6428 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
6429 &mask_img
, &img
->mask
))
6431 x_destroy_x_image (ximg
);
6432 XFreePixmap (FRAME_W32_DISPLAY (f
), img
->pixmap
);
6438 /* Fill the X image and mask from PNG data. */
6439 init_color_table ();
6441 for (y
= 0; y
< height
; ++y
)
6443 png_byte
*p
= rows
[y
];
6445 for (x
= 0; x
< width
; ++x
)
6452 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
6454 /* An alpha channel, aka mask channel, associates variable
6455 transparency with an image. Where other image formats
6456 support binary transparency---fully transparent or fully
6457 opaque---PNG allows up to 254 levels of partial transparency.
6458 The PNG library implements partial transparency by combining
6459 the image with a specified background color.
6461 I'm not sure how to handle this here nicely: because the
6462 background on which the image is displayed may change, for
6463 real alpha channel support, it would be necessary to create
6464 a new image for each possible background.
6466 What I'm doing now is that a mask is created if we have
6467 boolean transparency information. Otherwise I'm using
6468 the frame's background color to combine the image with. */
6473 XPutPixel (mask_img
, x
, y
, *p
> 0);
6479 /* Remember colors allocated for this image. */
6480 img
->colors
= colors_in_color_table (&img
->ncolors
);
6481 free_color_table ();
6484 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
6489 img
->height
= height
;
6491 /* Put the image into the pixmap, then free the X image and its buffer. */
6492 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6493 x_destroy_x_image (ximg
);
6495 /* Same for the mask. */
6498 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
6499 x_destroy_x_image (mask_img
);
6507 #endif /* HAVE_PNG != 0 */
6511 /***********************************************************************
6513 ***********************************************************************/
6517 /* Work around a warning about HAVE_STDLIB_H being redefined in
6519 #ifdef HAVE_STDLIB_H
6520 #define HAVE_STDLIB_H_1
6521 #undef HAVE_STDLIB_H
6522 #endif /* HAVE_STLIB_H */
6524 #include <jpeglib.h>
6528 #ifdef HAVE_STLIB_H_1
6529 #define HAVE_STDLIB_H 1
6532 static int jpeg_image_p
P_ ((Lisp_Object object
));
6533 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
6535 /* The symbol `jpeg' identifying images of this type. */
6539 /* Indices of image specification fields in gs_format, below. */
6541 enum jpeg_keyword_index
6550 JPEG_HEURISTIC_MASK
,
6554 /* Vector of image_keyword structures describing the format
6555 of valid user-defined image specifications. */
6557 static struct image_keyword jpeg_format
[JPEG_LAST
] =
6559 {":type", IMAGE_SYMBOL_VALUE
, 1},
6560 {":data", IMAGE_STRING_VALUE
, 0},
6561 {":file", IMAGE_STRING_VALUE
, 0},
6562 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6563 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6564 {":relief", IMAGE_INTEGER_VALUE
, 0},
6565 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6566 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6569 /* Structure describing the image type `jpeg'. */
6571 static struct image_type jpeg_type
=
6581 /* Return non-zero if OBJECT is a valid JPEG image specification. */
6584 jpeg_image_p (object
)
6587 struct image_keyword fmt
[JPEG_LAST
];
6589 bcopy (jpeg_format
, fmt
, sizeof fmt
);
6591 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
)
6592 || (fmt
[JPEG_ASCENT
].count
6593 && XFASTINT (fmt
[JPEG_ASCENT
].value
) > 100))
6596 /* Must specify either the :data or :file keyword. */
6597 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
6601 struct my_jpeg_error_mgr
6603 struct jpeg_error_mgr pub
;
6604 jmp_buf setjmp_buffer
;
6608 my_error_exit (cinfo
)
6611 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6612 longjmp (mgr
->setjmp_buffer
, 1);
6615 /* Init source method for JPEG data source manager. Called by
6616 jpeg_read_header() before any data is actually read. See
6617 libjpeg.doc from the JPEG lib distribution. */
6620 our_init_source (cinfo
)
6621 j_decompress_ptr cinfo
;
6626 /* Fill input buffer method for JPEG data source manager. Called
6627 whenever more data is needed. We read the whole image in one step,
6628 so this only adds a fake end of input marker at the end. */
6631 our_fill_input_buffer (cinfo
)
6632 j_decompress_ptr cinfo
;
6634 /* Insert a fake EOI marker. */
6635 struct jpeg_source_mgr
*src
= cinfo
->src
;
6636 static JOCTET buffer
[2];
6638 buffer
[0] = (JOCTET
) 0xFF;
6639 buffer
[1] = (JOCTET
) JPEG_EOI
;
6641 src
->next_input_byte
= buffer
;
6642 src
->bytes_in_buffer
= 2;
6647 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6648 is the JPEG data source manager. */
6651 our_skip_input_data (cinfo
, num_bytes
)
6652 j_decompress_ptr cinfo
;
6655 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6659 if (num_bytes
> src
->bytes_in_buffer
)
6660 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6662 src
->bytes_in_buffer
-= num_bytes
;
6663 src
->next_input_byte
+= num_bytes
;
6668 /* Method to terminate data source. Called by
6669 jpeg_finish_decompress() after all data has been processed. */
6672 our_term_source (cinfo
)
6673 j_decompress_ptr cinfo
;
6678 /* Set up the JPEG lib for reading an image from DATA which contains
6679 LEN bytes. CINFO is the decompression info structure created for
6680 reading the image. */
6683 jpeg_memory_src (cinfo
, data
, len
)
6684 j_decompress_ptr cinfo
;
6688 struct jpeg_source_mgr
*src
;
6690 if (cinfo
->src
== NULL
)
6692 /* First time for this JPEG object? */
6693 cinfo
->src
= (struct jpeg_source_mgr
*)
6694 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6695 sizeof (struct jpeg_source_mgr
));
6696 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6697 src
->next_input_byte
= data
;
6700 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6701 src
->init_source
= our_init_source
;
6702 src
->fill_input_buffer
= our_fill_input_buffer
;
6703 src
->skip_input_data
= our_skip_input_data
;
6704 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
6705 src
->term_source
= our_term_source
;
6706 src
->bytes_in_buffer
= len
;
6707 src
->next_input_byte
= data
;
6711 /* Load image IMG for use on frame F. Patterned after example.c
6712 from the JPEG lib. */
6719 struct jpeg_decompress_struct cinfo
;
6720 struct my_jpeg_error_mgr mgr
;
6721 Lisp_Object file
, specified_file
;
6722 Lisp_Object specified_data
;
6725 int row_stride
, x
, y
;
6726 XImage
*ximg
= NULL
;
6728 unsigned long *colors
;
6730 struct gcpro gcpro1
;
6732 /* Open the JPEG file. */
6733 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6734 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6738 if (NILP (specified_data
))
6740 file
= x_find_image_file (specified_file
);
6741 if (!STRINGP (file
))
6743 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6748 fp
= fopen (SDATA (file
), "r");
6751 image_error ("Cannot open `%s'", file
, Qnil
);
6757 /* Customize libjpeg's error handling to call my_error_exit when an
6758 error is detected. This function will perform a longjmp. */
6759 mgr
.pub
.error_exit
= my_error_exit
;
6760 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
6762 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
6766 /* Called from my_error_exit. Display a JPEG error. */
6767 char buffer
[JMSG_LENGTH_MAX
];
6768 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
6769 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
6770 build_string (buffer
));
6773 /* Close the input file and destroy the JPEG object. */
6776 jpeg_destroy_decompress (&cinfo
);
6780 /* If we already have an XImage, free that. */
6781 x_destroy_x_image (ximg
);
6783 /* Free pixmap and colors. */
6784 x_clear_image (f
, img
);
6791 /* Create the JPEG decompression object. Let it read from fp.
6792 Read the JPEG image header. */
6793 jpeg_create_decompress (&cinfo
);
6795 if (NILP (specified_data
))
6796 jpeg_stdio_src (&cinfo
, fp
);
6798 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
6799 SBYTES (specified_data
));
6801 jpeg_read_header (&cinfo
, TRUE
);
6803 /* Customize decompression so that color quantization will be used.
6804 Start decompression. */
6805 cinfo
.quantize_colors
= TRUE
;
6806 jpeg_start_decompress (&cinfo
);
6807 width
= img
->width
= cinfo
.output_width
;
6808 height
= img
->height
= cinfo
.output_height
;
6812 /* Create X image and pixmap. */
6813 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
6817 longjmp (mgr
.setjmp_buffer
, 2);
6820 /* Allocate colors. When color quantization is used,
6821 cinfo.actual_number_of_colors has been set with the number of
6822 colors generated, and cinfo.colormap is a two-dimensional array
6823 of color indices in the range 0..cinfo.actual_number_of_colors.
6824 No more than 255 colors will be generated. */
6828 if (cinfo
.out_color_components
> 2)
6829 ir
= 0, ig
= 1, ib
= 2;
6830 else if (cinfo
.out_color_components
> 1)
6831 ir
= 0, ig
= 1, ib
= 0;
6833 ir
= 0, ig
= 0, ib
= 0;
6835 /* Use the color table mechanism because it handles colors that
6836 cannot be allocated nicely. Such colors will be replaced with
6837 a default color, and we don't have to care about which colors
6838 can be freed safely, and which can't. */
6839 init_color_table ();
6840 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
6843 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
6845 /* Multiply RGB values with 255 because X expects RGB values
6846 in the range 0..0xffff. */
6847 int r
= cinfo
.colormap
[ir
][i
] << 8;
6848 int g
= cinfo
.colormap
[ig
][i
] << 8;
6849 int b
= cinfo
.colormap
[ib
][i
] << 8;
6850 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6853 /* Remember those colors actually allocated. */
6854 img
->colors
= colors_in_color_table (&img
->ncolors
);
6855 free_color_table ();
6859 row_stride
= width
* cinfo
.output_components
;
6860 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
6862 for (y
= 0; y
< height
; ++y
)
6864 jpeg_read_scanlines (&cinfo
, buffer
, 1);
6865 for (x
= 0; x
< cinfo
.output_width
; ++x
)
6866 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6870 jpeg_finish_decompress (&cinfo
);
6871 jpeg_destroy_decompress (&cinfo
);
6875 /* Put the image into the pixmap. */
6876 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6877 x_destroy_x_image (ximg
);
6883 #endif /* HAVE_JPEG */
6887 /***********************************************************************
6889 ***********************************************************************/
6895 static int tiff_image_p
P_ ((Lisp_Object object
));
6896 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
6898 /* The symbol `tiff' identifying images of this type. */
6902 /* Indices of image specification fields in tiff_format, below. */
6904 enum tiff_keyword_index
6913 TIFF_HEURISTIC_MASK
,
6917 /* Vector of image_keyword structures describing the format
6918 of valid user-defined image specifications. */
6920 static struct image_keyword tiff_format
[TIFF_LAST
] =
6922 {":type", IMAGE_SYMBOL_VALUE
, 1},
6923 {":data", IMAGE_STRING_VALUE
, 0},
6924 {":file", IMAGE_STRING_VALUE
, 0},
6925 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6926 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6927 {":relief", IMAGE_INTEGER_VALUE
, 0},
6928 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6929 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6932 /* Structure describing the image type `tiff'. */
6934 static struct image_type tiff_type
=
6944 /* Return non-zero if OBJECT is a valid TIFF image specification. */
6947 tiff_image_p (object
)
6950 struct image_keyword fmt
[TIFF_LAST
];
6951 bcopy (tiff_format
, fmt
, sizeof fmt
);
6953 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
)
6954 || (fmt
[TIFF_ASCENT
].count
6955 && XFASTINT (fmt
[TIFF_ASCENT
].value
) > 100))
6958 /* Must specify either the :data or :file keyword. */
6959 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6963 /* Reading from a memory buffer for TIFF images Based on the PNG
6964 memory source, but we have to provide a lot of extra functions.
6967 We really only need to implement read and seek, but I am not
6968 convinced that the TIFF library is smart enough not to destroy
6969 itself if we only hand it the function pointers we need to
6974 unsigned char *bytes
;
6981 tiff_read_from_memory (data
, buf
, size
)
6986 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6988 if (size
> src
->len
- src
->index
)
6990 bcopy (src
->bytes
+ src
->index
, buf
, size
);
6996 tiff_write_from_memory (data
, buf
, size
)
7005 tiff_seek_in_memory (data
, off
, whence
)
7010 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
7015 case SEEK_SET
: /* Go from beginning of source. */
7019 case SEEK_END
: /* Go from end of source. */
7020 idx
= src
->len
+ off
;
7023 case SEEK_CUR
: /* Go from current position. */
7024 idx
= src
->index
+ off
;
7027 default: /* Invalid `whence'. */
7031 if (idx
> src
->len
|| idx
< 0)
7039 tiff_close_memory (data
)
7047 tiff_mmap_memory (data
, pbase
, psize
)
7052 /* It is already _IN_ memory. */
7057 tiff_unmap_memory (data
, base
, size
)
7062 /* We don't need to do this. */
7066 tiff_size_of_memory (data
)
7069 return ((tiff_memory_source
*) data
)->len
;
7072 /* Load TIFF image IMG for use on frame F. Value is non-zero if
7080 Lisp_Object file
, specified_file
;
7081 Lisp_Object specified_data
;
7083 int width
, height
, x
, y
;
7087 struct gcpro gcpro1
;
7088 tiff_memory_source memsrc
;
7090 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7091 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7095 if (NILP (specified_data
))
7097 /* Read from a file */
7098 file
= x_find_image_file (specified_file
);
7099 if (!STRINGP (file
))
7101 image_error ("Cannot find image file `%s'", file
, Qnil
);
7106 /* Try to open the image file. */
7107 tiff
= TIFFOpen (SDATA (file
), "r");
7110 image_error ("Cannot open `%s'", file
, Qnil
);
7117 /* Memory source! */
7118 memsrc
.bytes
= SDATA (specified_data
);
7119 memsrc
.len
= SBYTES (specified_data
);
7122 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
7123 (TIFFReadWriteProc
) tiff_read_from_memory
,
7124 (TIFFReadWriteProc
) tiff_write_from_memory
,
7125 tiff_seek_in_memory
,
7127 tiff_size_of_memory
,
7133 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
7139 /* Get width and height of the image, and allocate a raster buffer
7140 of width x height 32-bit values. */
7141 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
7142 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
7143 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
7145 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
7149 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
7157 /* Create the X image and pixmap. */
7158 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7166 /* Initialize the color table. */
7167 init_color_table ();
7169 /* Process the pixel raster. Origin is in the lower-left corner. */
7170 for (y
= 0; y
< height
; ++y
)
7172 uint32
*row
= buf
+ y
* width
;
7174 for (x
= 0; x
< width
; ++x
)
7176 uint32 abgr
= row
[x
];
7177 int r
= TIFFGetR (abgr
) << 8;
7178 int g
= TIFFGetG (abgr
) << 8;
7179 int b
= TIFFGetB (abgr
) << 8;
7180 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
7184 /* Remember the colors allocated for the image. Free the color table. */
7185 img
->colors
= colors_in_color_table (&img
->ncolors
);
7186 free_color_table ();
7188 /* Put the image into the pixmap, then free the X image and its buffer. */
7189 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7190 x_destroy_x_image (ximg
);
7195 img
->height
= height
;
7201 #endif /* HAVE_TIFF != 0 */
7205 /***********************************************************************
7207 ***********************************************************************/
7211 #include <gif_lib.h>
7213 static int gif_image_p
P_ ((Lisp_Object object
));
7214 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
7216 /* The symbol `gif' identifying images of this type. */
7220 /* Indices of image specification fields in gif_format, below. */
7222 enum gif_keyword_index
7236 /* Vector of image_keyword structures describing the format
7237 of valid user-defined image specifications. */
7239 static struct image_keyword gif_format
[GIF_LAST
] =
7241 {":type", IMAGE_SYMBOL_VALUE
, 1},
7242 {":data", IMAGE_STRING_VALUE
, 0},
7243 {":file", IMAGE_STRING_VALUE
, 0},
7244 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7245 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7246 {":relief", IMAGE_INTEGER_VALUE
, 0},
7247 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7248 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7249 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
7252 /* Structure describing the image type `gif'. */
7254 static struct image_type gif_type
=
7263 /* Return non-zero if OBJECT is a valid GIF image specification. */
7266 gif_image_p (object
)
7269 struct image_keyword fmt
[GIF_LAST
];
7270 bcopy (gif_format
, fmt
, sizeof fmt
);
7272 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
)
7273 || (fmt
[GIF_ASCENT
].count
7274 && XFASTINT (fmt
[GIF_ASCENT
].value
) > 100))
7277 /* Must specify either the :data or :file keyword. */
7278 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
7281 /* Reading a GIF image from memory
7282 Based on the PNG memory stuff to a certain extent. */
7286 unsigned char *bytes
;
7292 /* Make the current memory source available to gif_read_from_memory.
7293 It's done this way because not all versions of libungif support
7294 a UserData field in the GifFileType structure. */
7295 static gif_memory_source
*current_gif_memory_src
;
7298 gif_read_from_memory (file
, buf
, len
)
7303 gif_memory_source
*src
= current_gif_memory_src
;
7305 if (len
> src
->len
- src
->index
)
7308 bcopy (src
->bytes
+ src
->index
, buf
, len
);
7314 /* Load GIF image IMG for use on frame F. Value is non-zero if
7322 Lisp_Object file
, specified_file
;
7323 Lisp_Object specified_data
;
7324 int rc
, width
, height
, x
, y
, i
;
7326 ColorMapObject
*gif_color_map
;
7327 unsigned long pixel_colors
[256];
7329 struct gcpro gcpro1
;
7331 int ino
, image_left
, image_top
, image_width
, image_height
;
7332 gif_memory_source memsrc
;
7333 unsigned char *raster
;
7335 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7336 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7340 if (NILP (specified_data
))
7342 file
= x_find_image_file (specified_file
);
7343 if (!STRINGP (file
))
7345 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7350 /* Open the GIF file. */
7351 gif
= DGifOpenFileName (SDATA (file
));
7354 image_error ("Cannot open `%s'", file
, Qnil
);
7361 /* Read from memory! */
7362 current_gif_memory_src
= &memsrc
;
7363 memsrc
.bytes
= SDATA (specified_data
);
7364 memsrc
.len
= SBYTES (specified_data
);
7367 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
7370 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
7376 /* Read entire contents. */
7377 rc
= DGifSlurp (gif
);
7378 if (rc
== GIF_ERROR
)
7380 image_error ("Error reading `%s'", img
->spec
, Qnil
);
7381 DGifCloseFile (gif
);
7386 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7387 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
7388 if (ino
>= gif
->ImageCount
)
7390 image_error ("Invalid image number `%s' in image `%s'",
7392 DGifCloseFile (gif
);
7397 width
= img
->width
= gif
->SWidth
;
7398 height
= img
->height
= gif
->SHeight
;
7402 /* Create the X image and pixmap. */
7403 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7406 DGifCloseFile (gif
);
7411 /* Allocate colors. */
7412 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
7414 gif_color_map
= gif
->SColorMap
;
7415 init_color_table ();
7416 bzero (pixel_colors
, sizeof pixel_colors
);
7418 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7420 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7421 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7422 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7423 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7426 img
->colors
= colors_in_color_table (&img
->ncolors
);
7427 free_color_table ();
7429 /* Clear the part of the screen image that are not covered by
7430 the image from the GIF file. Full animated GIF support
7431 requires more than can be done here (see the gif89 spec,
7432 disposal methods). Let's simply assume that the part
7433 not covered by a sub-image is in the frame's background color. */
7434 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
7435 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
7436 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
7437 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
7439 for (y
= 0; y
< image_top
; ++y
)
7440 for (x
= 0; x
< width
; ++x
)
7441 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7443 for (y
= image_top
+ image_height
; y
< height
; ++y
)
7444 for (x
= 0; x
< width
; ++x
)
7445 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7447 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
7449 for (x
= 0; x
< image_left
; ++x
)
7450 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7451 for (x
= image_left
+ image_width
; x
< width
; ++x
)
7452 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7455 /* Read the GIF image into the X image. We use a local variable
7456 `raster' here because RasterBits below is a char *, and invites
7457 problems with bytes >= 0x80. */
7458 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
7460 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
7462 static int interlace_start
[] = {0, 4, 2, 1};
7463 static int interlace_increment
[] = {8, 8, 4, 2};
7465 int row
= interlace_start
[0];
7469 for (y
= 0; y
< image_height
; y
++)
7471 if (row
>= image_height
)
7473 row
= interlace_start
[++pass
];
7474 while (row
>= image_height
)
7475 row
= interlace_start
[++pass
];
7478 for (x
= 0; x
< image_width
; x
++)
7480 int i
= raster
[(y
* image_width
) + x
];
7481 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
7485 row
+= interlace_increment
[pass
];
7490 for (y
= 0; y
< image_height
; ++y
)
7491 for (x
= 0; x
< image_width
; ++x
)
7493 int i
= raster
[y
* image_width
+ x
];
7494 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
7498 DGifCloseFile (gif
);
7500 /* Put the image into the pixmap, then free the X image and its buffer. */
7501 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7502 x_destroy_x_image (ximg
);
7509 #endif /* HAVE_GIF != 0 */
7513 /***********************************************************************
7515 ***********************************************************************/
7517 #ifdef HAVE_GHOSTSCRIPT
7518 static int gs_image_p
P_ ((Lisp_Object object
));
7519 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
7520 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
7522 /* The symbol `postscript' identifying images of this type. */
7524 Lisp_Object Qpostscript
;
7526 /* Keyword symbols. */
7528 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
7530 /* Indices of image specification fields in gs_format, below. */
7532 enum gs_keyword_index
7548 /* Vector of image_keyword structures describing the format
7549 of valid user-defined image specifications. */
7551 static struct image_keyword gs_format
[GS_LAST
] =
7553 {":type", IMAGE_SYMBOL_VALUE
, 1},
7554 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
7555 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
7556 {":file", IMAGE_STRING_VALUE
, 1},
7557 {":loader", IMAGE_FUNCTION_VALUE
, 0},
7558 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
7559 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7560 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7561 {":relief", IMAGE_INTEGER_VALUE
, 0},
7562 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7563 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7566 /* Structure describing the image type `ghostscript'. */
7568 static struct image_type gs_type
=
7578 /* Free X resources of Ghostscript image IMG which is used on frame F. */
7581 gs_clear_image (f
, img
)
7585 /* IMG->data.ptr_val may contain a recorded colormap. */
7586 xfree (img
->data
.ptr_val
);
7587 x_clear_image (f
, img
);
7591 /* Return non-zero if OBJECT is a valid Ghostscript image
7598 struct image_keyword fmt
[GS_LAST
];
7602 bcopy (gs_format
, fmt
, sizeof fmt
);
7604 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
)
7605 || (fmt
[GS_ASCENT
].count
7606 && XFASTINT (fmt
[GS_ASCENT
].value
) > 100))
7609 /* Bounding box must be a list or vector containing 4 integers. */
7610 tem
= fmt
[GS_BOUNDING_BOX
].value
;
7613 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
7614 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
7619 else if (VECTORP (tem
))
7621 if (XVECTOR (tem
)->size
!= 4)
7623 for (i
= 0; i
< 4; ++i
)
7624 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
7634 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
7643 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
7644 struct gcpro gcpro1
, gcpro2
;
7646 double in_width
, in_height
;
7647 Lisp_Object pixel_colors
= Qnil
;
7649 /* Compute pixel size of pixmap needed from the given size in the
7650 image specification. Sizes in the specification are in pt. 1 pt
7651 = 1/72 in, xdpi and ydpi are stored in the frame's X display
7653 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
7654 in_width
= XFASTINT (pt_width
) / 72.0;
7655 img
->width
= in_width
* FRAME_W32_DISPLAY_INFO (f
)->resx
;
7656 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
7657 in_height
= XFASTINT (pt_height
) / 72.0;
7658 img
->height
= in_height
* FRAME_W32_DISPLAY_INFO (f
)->resy
;
7660 /* Create the pixmap. */
7662 xassert (img
->pixmap
== 0);
7663 img
->pixmap
= XCreatePixmap (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
7664 img
->width
, img
->height
,
7665 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
7670 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
7674 /* Call the loader to fill the pixmap. It returns a process object
7675 if successful. We do not record_unwind_protect here because
7676 other places in redisplay like calling window scroll functions
7677 don't either. Let the Lisp loader use `unwind-protect' instead. */
7678 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
7680 sprintf (buffer
, "%lu %lu",
7681 (unsigned long) FRAME_W32_WINDOW (f
),
7682 (unsigned long) img
->pixmap
);
7683 window_and_pixmap_id
= build_string (buffer
);
7685 sprintf (buffer
, "%lu %lu",
7686 FRAME_FOREGROUND_PIXEL (f
),
7687 FRAME_BACKGROUND_PIXEL (f
));
7688 pixel_colors
= build_string (buffer
);
7690 XSETFRAME (frame
, f
);
7691 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
7693 loader
= intern ("gs-load-image");
7695 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
7696 make_number (img
->width
),
7697 make_number (img
->height
),
7698 window_and_pixmap_id
,
7701 return PROCESSP (img
->data
.lisp_val
);
7705 /* Kill the Ghostscript process that was started to fill PIXMAP on
7706 frame F. Called from XTread_socket when receiving an event
7707 telling Emacs that Ghostscript has finished drawing. */
7710 x_kill_gs_process (pixmap
, f
)
7714 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
7718 /* Find the image containing PIXMAP. */
7719 for (i
= 0; i
< c
->used
; ++i
)
7720 if (c
->images
[i
]->pixmap
== pixmap
)
7723 /* Kill the GS process. We should have found PIXMAP in the image
7724 cache and its image should contain a process object. */
7725 xassert (i
< c
->used
);
7727 xassert (PROCESSP (img
->data
.lisp_val
));
7728 Fkill_process (img
->data
.lisp_val
, Qnil
);
7729 img
->data
.lisp_val
= Qnil
;
7731 /* On displays with a mutable colormap, figure out the colors
7732 allocated for the image by looking at the pixels of an XImage for
7734 class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
7735 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
7741 /* Try to get an XImage for img->pixmep. */
7742 ximg
= XGetImage (FRAME_W32_DISPLAY (f
), img
->pixmap
,
7743 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
7748 /* Initialize the color table. */
7749 init_color_table ();
7751 /* For each pixel of the image, look its color up in the
7752 color table. After having done so, the color table will
7753 contain an entry for each color used by the image. */
7754 for (y
= 0; y
< img
->height
; ++y
)
7755 for (x
= 0; x
< img
->width
; ++x
)
7757 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
7758 lookup_pixel_color (f
, pixel
);
7761 /* Record colors in the image. Free color table and XImage. */
7762 img
->colors
= colors_in_color_table (&img
->ncolors
);
7763 free_color_table ();
7764 XDestroyImage (ximg
);
7766 #if 0 /* This doesn't seem to be the case. If we free the colors
7767 here, we get a BadAccess later in x_clear_image when
7768 freeing the colors. */
7769 /* We have allocated colors once, but Ghostscript has also
7770 allocated colors on behalf of us. So, to get the
7771 reference counts right, free them once. */
7774 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
7775 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
,
7776 img
->colors
, img
->ncolors
, 0);
7781 image_error ("Cannot get X image of `%s'; colors will not be freed",
7788 #endif /* HAVE_GHOSTSCRIPT */
7791 /***********************************************************************
7793 ***********************************************************************/
7795 DEFUN ("x-change-window-property", Fx_change_window_property
,
7796 Sx_change_window_property
, 2, 3, 0,
7797 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
7798 PROP and VALUE must be strings. FRAME nil or omitted means use the
7799 selected frame. Value is VALUE. */)
7800 (prop
, value
, frame
)
7801 Lisp_Object frame
, prop
, value
;
7803 #if 0 /* MAC_TODO : port window properties to Mac */
7804 struct frame
*f
= check_x_frame (frame
);
7807 CHECK_STRING (prop
);
7808 CHECK_STRING (value
);
7811 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
7812 XChangeProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
7813 prop_atom
, XA_STRING
, 8, PropModeReplace
,
7814 SDATA (value
), SCHARS (value
));
7816 /* Make sure the property is set when we return. */
7817 XFlush (FRAME_W32_DISPLAY (f
));
7820 #endif /* MAC_TODO */
7826 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
7827 Sx_delete_window_property
, 1, 2, 0,
7828 doc
: /* Remove window property PROP from X window of FRAME.
7829 FRAME nil or omitted means use the selected frame. Value is PROP. */)
7831 Lisp_Object prop
, frame
;
7833 #if 0 /* MAC_TODO : port window properties to Mac */
7835 struct frame
*f
= check_x_frame (frame
);
7838 CHECK_STRING (prop
);
7840 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
7841 XDeleteProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), prop_atom
);
7843 /* Make sure the property is removed when we return. */
7844 XFlush (FRAME_W32_DISPLAY (f
));
7846 #endif /* MAC_TODO */
7852 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
7854 doc
: /* Value is the value of window property PROP on FRAME.
7855 If FRAME is nil or omitted, use the selected frame. Value is nil
7856 if FRAME hasn't a property with name PROP or if PROP has no string
7859 Lisp_Object prop
, frame
;
7861 #if 0 /* MAC_TODO : port window properties to Mac */
7863 struct frame
*f
= check_x_frame (frame
);
7866 Lisp_Object prop_value
= Qnil
;
7867 char *tmp_data
= NULL
;
7870 unsigned long actual_size
, bytes_remaining
;
7872 CHECK_STRING (prop
);
7874 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
7875 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
7876 prop_atom
, 0, 0, False
, XA_STRING
,
7877 &actual_type
, &actual_format
, &actual_size
,
7878 &bytes_remaining
, (unsigned char **) &tmp_data
);
7881 int size
= bytes_remaining
;
7886 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
7887 prop_atom
, 0, bytes_remaining
,
7889 &actual_type
, &actual_format
,
7890 &actual_size
, &bytes_remaining
,
7891 (unsigned char **) &tmp_data
);
7893 prop_value
= make_string (tmp_data
, size
);
7902 #endif /* MAC_TODO */
7908 /***********************************************************************
7910 ***********************************************************************/
7912 /* If non-null, an asynchronous timer that, when it expires, displays
7913 an hourglass cursor on all frames. */
7915 static struct atimer
*hourglass_atimer
;
7917 /* Non-zero means an hourglass cursor is currently shown. */
7919 static int hourglass_shown_p
;
7921 /* Number of seconds to wait before displaying an hourglass cursor. */
7923 static Lisp_Object Vhourglass_delay
;
7925 /* Default number of seconds to wait before displaying an hourglass
7928 #define DEFAULT_HOURGLASS_DELAY 1
7930 /* Function prototypes. */
7932 static void show_hourglass
P_ ((struct atimer
*));
7933 static void hide_hourglass
P_ ((void));
7936 /* Cancel a currently active hourglass timer, and start a new one. */
7941 #if 0 /* MAC_TODO: cursor shape changes. */
7943 int secs
, usecs
= 0;
7945 cancel_hourglass ();
7947 if (INTEGERP (Vhourglass_delay
)
7948 && XINT (Vhourglass_delay
) > 0)
7949 secs
= XFASTINT (Vhourglass_delay
);
7950 else if (FLOATP (Vhourglass_delay
)
7951 && XFLOAT_DATA (Vhourglass_delay
) > 0)
7954 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
7955 secs
= XFASTINT (tem
);
7956 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
7959 secs
= DEFAULT_HOURGLASS_DELAY
;
7961 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
7962 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
7963 show_hourglass
, NULL
);
7964 #endif /* MAC_TODO */
7968 /* Cancel the hourglass cursor timer if active, hide an hourglass
7974 if (hourglass_atimer
)
7976 cancel_atimer (hourglass_atimer
);
7977 hourglass_atimer
= NULL
;
7980 if (hourglass_shown_p
)
7985 /* Timer function of hourglass_atimer. TIMER is equal to
7988 Display an hourglass cursor on all frames by mapping the frames'
7989 hourglass_window. Set the hourglass_p flag in the frames'
7990 output_data.x structure to indicate that an hourglass cursor is
7991 shown on the frames. */
7994 show_hourglass (timer
)
7995 struct atimer
*timer
;
7997 #if 0 /* MAC_TODO: cursor shape changes. */
7998 /* The timer implementation will cancel this timer automatically
7999 after this function has run. Set hourglass_atimer to null
8000 so that we know the timer doesn't have to be canceled. */
8001 hourglass_atimer
= NULL
;
8003 if (!hourglass_shown_p
)
8005 Lisp_Object rest
, frame
;
8009 FOR_EACH_FRAME (rest
, frame
)
8010 if (FRAME_W32_P (XFRAME (frame
)))
8012 struct frame
*f
= XFRAME (frame
);
8014 f
->output_data
.w32
->hourglass_p
= 1;
8016 if (!f
->output_data
.w32
->hourglass_window
)
8018 unsigned long mask
= CWCursor
;
8019 XSetWindowAttributes attrs
;
8021 attrs
.cursor
= f
->output_data
.w32
->hourglass_cursor
;
8023 f
->output_data
.w32
->hourglass_window
8024 = XCreateWindow (FRAME_X_DISPLAY (f
),
8025 FRAME_OUTER_WINDOW (f
),
8026 0, 0, 32000, 32000, 0, 0,
8032 XMapRaised (FRAME_X_DISPLAY (f
),
8033 f
->output_data
.w32
->hourglass_window
);
8034 XFlush (FRAME_X_DISPLAY (f
));
8037 hourglass_shown_p
= 1;
8040 #endif /* MAC_TODO */
8044 /* Hide the hourglass cursor on all frames, if it is currently shown. */
8049 #if 0 /* MAC_TODO: cursor shape changes. */
8050 if (hourglass_shown_p
)
8052 Lisp_Object rest
, frame
;
8055 FOR_EACH_FRAME (rest
, frame
)
8057 struct frame
*f
= XFRAME (frame
);
8060 /* Watch out for newly created frames. */
8061 && f
->output_data
.x
->hourglass_window
)
8063 XUnmapWindow (FRAME_X_DISPLAY (f
),
8064 f
->output_data
.x
->hourglass_window
);
8065 /* Sync here because XTread_socket looks at the
8066 hourglass_p flag that is reset to zero below. */
8067 XSync (FRAME_X_DISPLAY (f
), False
);
8068 f
->output_data
.x
->hourglass_p
= 0;
8072 hourglass_shown_p
= 0;
8075 #endif /* MAC_TODO */
8080 /***********************************************************************
8082 ***********************************************************************/
8084 static Lisp_Object x_create_tip_frame
P_ ((struct mac_display_info
*,
8087 /* The frame of a currently visible tooltip, or null. */
8089 Lisp_Object tip_frame
;
8091 /* If non-nil, a timer started that hides the last tooltip when it
8094 Lisp_Object tip_timer
;
8097 /* If non-nil, a vector of 3 elements containing the last args
8098 with which x-show-tip was called. See there. */
8100 Lisp_Object last_show_tip_args
;
8102 /* Create a frame for a tooltip on the display described by DPYINFO.
8103 PARMS is a list of frame parameters. Value is the frame. */
8106 x_create_tip_frame (dpyinfo
, parms
)
8107 struct mac_display_info
*dpyinfo
;
8110 #if 0 /* MAC_TODO : Mac version */
8112 Lisp_Object frame
, tem
;
8114 long window_prompting
= 0;
8116 int count
= SPECPDL_INDEX ();
8117 struct gcpro gcpro1
, gcpro2
, gcpro3
;
8122 /* Use this general default value to start with until we know if
8123 this frame has a specified name. */
8124 Vx_resource_name
= Vinvocation_name
;
8127 kb
= dpyinfo
->kboard
;
8129 kb
= &the_only_kboard
;
8132 /* Get the name of the frame to use for resource lookup. */
8133 name
= w32_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
8135 && !EQ (name
, Qunbound
)
8137 error ("Invalid frame name--not a string or nil");
8138 Vx_resource_name
= name
;
8141 GCPRO3 (parms
, name
, frame
);
8142 tip_frame
= f
= make_frame (1);
8143 XSETFRAME (frame
, f
);
8144 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
8146 f
->output_method
= output_w32
;
8147 f
->output_data
.w32
=
8148 (struct w32_output
*) xmalloc (sizeof (struct w32_output
));
8149 bzero (f
->output_data
.w32
, sizeof (struct w32_output
));
8151 f
->output_data
.w32
->icon_bitmap
= -1;
8153 f
->output_data
.w32
->fontset
= -1;
8154 f
->icon_name
= Qnil
;
8157 FRAME_KBOARD (f
) = kb
;
8159 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
8160 f
->output_data
.w32
->explicit_parent
= 0;
8162 /* Set the name; the functions to which we pass f expect the name to
8164 if (EQ (name
, Qunbound
) || NILP (name
))
8166 f
->name
= build_string (dpyinfo
->x_id_name
);
8167 f
->explicit_name
= 0;
8172 f
->explicit_name
= 1;
8173 /* use the frame's title when getting resources for this frame. */
8174 specbind (Qx_resource_name
, name
);
8177 /* Extract the window parameters from the supplied values
8178 that are needed to determine window geometry. */
8182 font
= w32_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
8185 /* First, try whatever font the caller has specified. */
8188 tem
= Fquery_fontset (font
, Qnil
);
8190 font
= x_new_fontset (f
, SDATA (tem
));
8192 font
= x_new_font (f
, SDATA (font
));
8195 /* Try out a font which we hope has bold and italic variations. */
8196 if (!STRINGP (font
))
8197 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
8198 if (!STRINGP (font
))
8199 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
8200 if (! STRINGP (font
))
8201 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
8202 if (! STRINGP (font
))
8203 /* This was formerly the first thing tried, but it finds too many fonts
8204 and takes too long. */
8205 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
8206 /* If those didn't work, look for something which will at least work. */
8207 if (! STRINGP (font
))
8208 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
8210 if (! STRINGP (font
))
8211 font
= build_string ("fixed");
8213 x_default_parameter (f
, parms
, Qfont
, font
,
8214 "font", "Font", RES_TYPE_STRING
);
8217 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
8218 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
8220 /* This defaults to 2 in order to match xterm. We recognize either
8221 internalBorderWidth or internalBorder (which is what xterm calls
8223 if (NILP (Fassq (Qinternal_border_width
, parms
)))
8227 value
= w32_get_arg (parms
, Qinternal_border_width
,
8228 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
8229 if (! EQ (value
, Qunbound
))
8230 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
8234 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
8235 "internalBorderWidth", "internalBorderWidth",
8238 /* Also do the stuff which must be set before the window exists. */
8239 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
8240 "foreground", "Foreground", RES_TYPE_STRING
);
8241 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
8242 "background", "Background", RES_TYPE_STRING
);
8243 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
8244 "pointerColor", "Foreground", RES_TYPE_STRING
);
8245 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
8246 "cursorColor", "Foreground", RES_TYPE_STRING
);
8247 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
8248 "borderColor", "BorderColor", RES_TYPE_STRING
);
8250 /* Init faces before x_default_parameter is called for scroll-bar
8251 parameters because that function calls x_set_scroll_bar_width,
8252 which calls change_frame_size, which calls Fset_window_buffer,
8253 which runs hooks, which call Fvertical_motion. At the end, we
8254 end up in init_iterator with a null face cache, which should not
8256 init_frame_faces (f
);
8258 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
8260 window_prompting
= x_figure_window_size (f
, parms
, 0);
8263 XSetWindowAttributes attrs
;
8267 mask
= CWBackPixel
| CWOverrideRedirect
| CWSaveUnder
| CWEventMask
;
8268 /* Window managers looks at the override-redirect flag to
8269 determine whether or net to give windows a decoration (Xlib
8271 attrs
.override_redirect
= True
;
8272 attrs
.save_under
= True
;
8273 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
8274 /* Arrange for getting MapNotify and UnmapNotify events. */
8275 attrs
.event_mask
= StructureNotifyMask
;
8277 = FRAME_W32_WINDOW (f
)
8278 = XCreateWindow (FRAME_W32_DISPLAY (f
),
8279 FRAME_W32_DISPLAY_INFO (f
)->root_window
,
8280 /* x, y, width, height */
8284 CopyFromParent
, InputOutput
, CopyFromParent
,
8291 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
8292 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
8293 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
8294 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
8295 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
8296 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
8298 /* Dimensions, especially f->height, must be done via change_frame_size.
8299 Change will not be effected unless different from the current
8304 SET_FRAME_WIDTH (f
, 0);
8305 change_frame_size (f
, height
, width
, 1, 0, 0);
8307 /* Add `tooltip' frame parameter's default value. */
8308 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
8309 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
8316 /* It is now ok to make the frame official even if we get an error
8317 below. And the frame needs to be on Vframe_list or making it
8318 visible won't work. */
8319 Vframe_list
= Fcons (frame
, Vframe_list
);
8321 /* Now that the frame is official, it counts as a reference to
8323 FRAME_W32_DISPLAY_INFO (f
)->reference_count
++;
8325 return unbind_to (count
, frame
);
8326 #endif /* MAC_TODO */
8331 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
8332 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
8333 A tooltip window is a small window displaying a string.
8335 FRAME nil or omitted means use the selected frame.
8337 PARMS is an optional list of frame parameters which can be used to
8338 change the tooltip's appearance.
8340 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
8341 means use the default timeout of 5 seconds.
8343 If the list of frame parameters PARAMS contains a `left' parameters,
8344 the tooltip is displayed at that x-position. Otherwise it is
8345 displayed at the mouse position, with offset DX added (default is 5 if
8346 DX isn't specified). Likewise for the y-position; if a `top' frame
8347 parameter is specified, it determines the y-position of the tooltip
8348 window, otherwise it is displayed at the mouse position, with offset
8349 DY added (default is 10). */)
8350 (string
, frame
, parms
, timeout
, dx
, dy
)
8351 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
8356 Lisp_Object buffer
, top
, left
;
8357 struct buffer
*old_buffer
;
8358 struct text_pos pos
;
8359 int i
, width
, height
;
8360 int root_x
, root_y
, win_x
, win_y
;
8362 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
8363 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
8364 int count
= SPECPDL_INDEX ();
8366 specbind (Qinhibit_redisplay
, Qt
);
8368 GCPRO4 (string
, parms
, frame
, timeout
);
8370 CHECK_STRING (string
);
8371 f
= check_x_frame (frame
);
8373 timeout
= make_number (5);
8375 CHECK_NATNUM (timeout
);
8378 dx
= make_number (5);
8383 dy
= make_number (-10);
8387 if (NILP (last_show_tip_args
))
8388 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
8390 if (!NILP (tip_frame
))
8392 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
8393 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
8394 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
8396 if (EQ (frame
, last_frame
)
8397 && !NILP (Fequal (last_string
, string
))
8398 && !NILP (Fequal (last_parms
, parms
)))
8400 struct frame
*f
= XFRAME (tip_frame
);
8402 /* Only DX and DY have changed. */
8403 if (!NILP (tip_timer
))
8405 Lisp_Object timer
= tip_timer
;
8407 call1 (Qcancel_timer
, timer
);
8410 #if 0 /* MAC_TODO : Mac specifics */
8412 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
8413 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8414 root_x
, root_y
- PIXEL_HEIGHT (f
));
8416 #endif /* MAC_TODO */
8421 /* Hide a previous tip, if any. */
8424 ASET (last_show_tip_args
, 0, string
);
8425 ASET (last_show_tip_args
, 1, frame
);
8426 ASET (last_show_tip_args
, 2, parms
);
8428 /* Add default values to frame parameters. */
8429 if (NILP (Fassq (Qname
, parms
)))
8430 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
8431 if (NILP (Fassq (Qinternal_border_width
, parms
)))
8432 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
8433 if (NILP (Fassq (Qborder_width
, parms
)))
8434 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
8435 if (NILP (Fassq (Qborder_color
, parms
)))
8436 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
8437 if (NILP (Fassq (Qbackground_color
, parms
)))
8438 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
8441 /* Create a frame for the tooltip, and record it in the global
8442 variable tip_frame. */
8443 frame
= x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f
), parms
);
8446 /* Set up the frame's root window. Currently we use a size of 80
8447 columns x 40 lines. If someone wants to show a larger tip, he
8448 will loose. I don't think this is a realistic case. */
8449 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
8450 w
->left
= w
->top
= make_number (0);
8451 w
->width
= make_number (80);
8452 w
->height
= make_number (40);
8454 w
->pseudo_window_p
= 1;
8456 /* Display the tooltip text in a temporary buffer. */
8457 buffer
= Fget_buffer_create (build_string (" *tip*"));
8458 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
);
8459 old_buffer
= current_buffer
;
8460 set_buffer_internal_1 (XBUFFER (buffer
));
8462 Finsert (1, &string
);
8463 clear_glyph_matrix (w
->desired_matrix
);
8464 clear_glyph_matrix (w
->current_matrix
);
8465 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
8466 try_window (FRAME_ROOT_WINDOW (f
), pos
);
8468 /* Compute width and height of the tooltip. */
8470 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
8472 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
8476 /* Stop at the first empty row at the end. */
8477 if (!row
->enabled_p
|| !row
->displays_text_p
)
8480 /* Let the row go over the full width of the frame. */
8481 row
->full_width_p
= 1;
8483 /* There's a glyph at the end of rows that is use to place
8484 the cursor there. Don't include the width of this glyph. */
8485 if (row
->used
[TEXT_AREA
])
8487 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
8488 row_width
= row
->pixel_width
- last
->pixel_width
;
8491 row_width
= row
->pixel_width
;
8493 height
+= row
->height
;
8494 width
= max (width
, row_width
);
8497 /* Add the frame's internal border to the width and height the X
8498 window should have. */
8499 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
8500 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
8502 /* Move the tooltip window where the mouse pointer is. Resize and
8504 #if 0 /* TODO : Mac specifics */
8505 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
8508 XQueryPointer (FRAME_W32_DISPLAY (f
), FRAME_W32_DISPLAY_INFO (f
)->root_window
,
8509 &root
, &child
, &root_x
, &root_y
, &win_x
, &win_y
, &pmask
);
8510 XMoveResizeWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
8511 root_x
+ 5, root_y
- height
- 5, width
, height
);
8512 XMapRaised (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
8514 #endif /* MAC_TODO */
8516 /* Draw into the window. */
8517 w
->must_be_updated_p
= 1;
8518 update_single_window (w
, 1);
8520 /* Restore original current buffer. */
8521 set_buffer_internal_1 (old_buffer
);
8522 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
8525 /* Let the tip disappear after timeout seconds. */
8526 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
8527 intern ("x-hide-tip"));
8530 return unbind_to (count
, Qnil
);
8534 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
8535 doc
: /* Hide the current tooltip window, if there is any.
8536 Value is t is tooltip was open, nil otherwise. */)
8540 Lisp_Object deleted
, frame
, timer
;
8541 struct gcpro gcpro1
, gcpro2
;
8543 /* Return quickly if nothing to do. */
8544 if (NILP (tip_timer
) && NILP (tip_frame
))
8549 GCPRO2 (frame
, timer
);
8550 tip_frame
= tip_timer
= deleted
= Qnil
;
8552 count
= SPECPDL_INDEX ();
8553 specbind (Qinhibit_redisplay
, Qt
);
8554 specbind (Qinhibit_quit
, Qt
);
8557 call1 (Qcancel_timer
, timer
);
8561 Fdelete_frame (frame
, Qnil
);
8566 return unbind_to (count
, deleted
);
8571 /***********************************************************************
8572 File selection dialog
8573 ***********************************************************************/
8575 #if 0 /* MAC_TODO: can standard file dialog */
8576 extern Lisp_Object Qfile_name_history
;
8578 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
8579 doc
: /* Read file name, prompting with PROMPT in directory DIR.
8580 Use a file selection dialog.
8581 Select DEFAULT-FILENAME in the dialog's file selection box, if
8582 specified. Don't let the user enter a file name in the file
8583 selection dialog's entry field, if MUSTMATCH is non-nil. */)
8584 (prompt
, dir
, default_filename
, mustmatch
)
8585 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
8587 struct frame
*f
= SELECTED_FRAME ();
8588 Lisp_Object file
= Qnil
;
8589 int count
= SPECPDL_INDEX ();
8590 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
8591 char filename
[MAX_PATH
+ 1];
8592 char init_dir
[MAX_PATH
+ 1];
8593 int use_dialog_p
= 1;
8595 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
8596 CHECK_STRING (prompt
);
8599 /* Create the dialog with PROMPT as title, using DIR as initial
8600 directory and using "*" as pattern. */
8601 dir
= Fexpand_file_name (dir
, Qnil
);
8602 strncpy (init_dir
, SDATA (dir
), MAX_PATH
);
8603 init_dir
[MAX_PATH
] = '\0';
8604 unixtodos_filename (init_dir
);
8606 if (STRINGP (default_filename
))
8608 char *file_name_only
;
8609 char *full_path_name
= SDATA (default_filename
);
8611 unixtodos_filename (full_path_name
);
8613 file_name_only
= strrchr (full_path_name
, '\\');
8614 if (!file_name_only
)
8615 file_name_only
= full_path_name
;
8620 /* If default_file_name is a directory, don't use the open
8621 file dialog, as it does not support selecting
8623 if (!(*file_name_only
))
8627 strncpy (filename
, file_name_only
, MAX_PATH
);
8628 filename
[MAX_PATH
] = '\0';
8635 OPENFILENAME file_details
;
8636 char *filename_file
;
8638 /* Prevent redisplay. */
8639 specbind (Qinhibit_redisplay
, Qt
);
8642 bzero (&file_details
, sizeof (file_details
));
8643 file_details
.lStructSize
= sizeof (file_details
);
8644 file_details
.hwndOwner
= FRAME_W32_WINDOW (f
);
8645 file_details
.lpstrFile
= filename
;
8646 file_details
.nMaxFile
= sizeof (filename
);
8647 file_details
.lpstrInitialDir
= init_dir
;
8648 file_details
.lpstrTitle
= SDATA (prompt
);
8649 file_details
.Flags
= OFN_HIDEREADONLY
| OFN_NOCHANGEDIR
;
8651 if (!NILP (mustmatch
))
8652 file_details
.Flags
|= OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
;
8654 if (GetOpenFileName (&file_details
))
8656 dostounix_filename (filename
);
8657 file
= build_string (filename
);
8663 file
= unbind_to (count
, file
);
8665 /* Open File dialog will not allow folders to be selected, so resort
8666 to minibuffer completing reads for directories. */
8668 file
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
8669 dir
, mustmatch
, dir
, Qfile_name_history
,
8670 default_filename
, Qnil
);
8674 /* Make "Cancel" equivalent to C-g. */
8676 Fsignal (Qquit
, Qnil
);
8678 return unbind_to (count
, file
);
8680 #endif /* MAC_TODO */
8684 /***********************************************************************
8686 ***********************************************************************/
8690 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
8691 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
8695 return valid_image_p (spec
) ? Qt
: Qnil
;
8699 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
8705 if (valid_image_p (spec
))
8706 id
= lookup_image (SELECTED_FRAME (), spec
);
8709 return make_number (id
);
8712 #endif /* GLYPH_DEBUG != 0 */
8716 /***********************************************************************
8718 ***********************************************************************/
8720 /* Keep this list in the same order as frame_parms in frame.c.
8721 Use 0 for unsupported frame parameters. */
8723 frame_parm_handler mac_frame_parm_handlers
[] =
8727 x_set_background_color
,
8733 x_set_foreground_color
,
8735 0, /* MAC_TODO: x_set_icon_type, */
8736 x_set_internal_border_width
,
8737 x_set_menu_bar_lines
,
8739 x_explicitly_set_name
,
8740 x_set_scroll_bar_width
,
8743 x_set_vertical_scroll_bars
,
8745 x_set_tool_bar_lines
,
8746 0, /* MAC_TODO: x_set_scroll_bar_foreground, */
8747 0, /* MAC_TODO: x_set_scroll_bar_background, */
8750 0, /* MAC_TODO: x_set_fringe_width, */
8751 0, /* MAC_TODO: x_set_fringe_width, */
8752 0, /* x_set_wait_for_wm, */
8753 0, /* MAC_TODO: x_set_fullscreen, */
8759 /* Certainly running on Mac. */
8762 /* The section below is built by the lisp expression at the top of the file,
8763 just above where these variables are declared. */
8764 /*&&& init symbols here &&&*/
8765 Qnone
= intern ("none");
8767 Qsuppress_icon
= intern ("suppress-icon");
8768 staticpro (&Qsuppress_icon
);
8769 Qundefined_color
= intern ("undefined-color");
8770 staticpro (&Qundefined_color
);
8771 Qcenter
= intern ("center");
8772 staticpro (&Qcenter
);
8773 /* This is the end of symbol initialization. */
8775 Qhyper
= intern ("hyper");
8776 staticpro (&Qhyper
);
8777 Qsuper
= intern ("super");
8778 staticpro (&Qsuper
);
8779 Qmeta
= intern ("meta");
8781 Qalt
= intern ("alt");
8783 Qctrl
= intern ("ctrl");
8785 Qcontrol
= intern ("control");
8786 staticpro (&Qcontrol
);
8787 Qshift
= intern ("shift");
8788 staticpro (&Qshift
);
8790 /* Text property `display' should be nonsticky by default. */
8791 Vtext_property_default_nonsticky
8792 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
8795 Qlaplace
= intern ("laplace");
8796 staticpro (&Qlaplace
);
8798 Qface_set_after_frame_default
= intern ("face-set-after-frame-default");
8799 staticpro (&Qface_set_after_frame_default
);
8801 Fput (Qundefined_color
, Qerror_conditions
,
8802 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
8803 Fput (Qundefined_color
, Qerror_message
,
8804 build_string ("Undefined color"));
8806 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
8807 doc
: /* List of directories to search for window system bitmap files. */);
8808 Vx_bitmap_file_path
= decode_env_path ((char *) 0, "PATH");
8810 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
8811 doc
: /* The shape of the pointer when over text.
8812 Changing the value does not affect existing frames
8813 unless you set the mouse color. */);
8814 Vx_pointer_shape
= Qnil
;
8816 Vx_nontext_pointer_shape
= Qnil
;
8818 Vx_mode_pointer_shape
= Qnil
;
8820 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
8821 doc
: /* The shape of the pointer when Emacs is hourglass.
8822 This variable takes effect when you create a new frame
8823 or when you set the mouse color. */);
8824 Vx_hourglass_pointer_shape
= Qnil
;
8826 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
8827 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
8828 display_hourglass_p
= 1;
8830 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
8831 doc
: /* *Seconds to wait before displaying an hourglass pointer.
8832 Value must be an integer or float. */);
8833 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
8835 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
8836 &Vx_sensitive_text_pointer_shape
,
8837 doc
: /* The shape of the pointer when over mouse-sensitive text.
8838 This variable takes effect when you create a new frame
8839 or when you set the mouse color. */);
8840 Vx_sensitive_text_pointer_shape
= Qnil
;
8842 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
8843 doc
: /* A string indicating the foreground color of the cursor box. */);
8844 Vx_cursor_fore_pixel
= Qnil
;
8846 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
8847 doc
: /* Non-nil if no window manager is in use.
8848 Emacs doesn't try to figure this out; this is always nil
8849 unless you set it to something else. */);
8850 /* We don't have any way to find this out, so set it to nil
8851 and maybe the user would like to set it to t. */
8852 Vx_no_window_manager
= Qnil
;
8854 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
8855 &Vx_pixel_size_width_font_regexp
,
8856 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
8858 Since Emacs gets width of a font matching with this regexp from
8859 PIXEL_SIZE field of the name, font finding mechanism gets faster for
8860 such a font. This is especially effective for such large fonts as
8861 Chinese, Japanese, and Korean. */);
8862 Vx_pixel_size_width_font_regexp
= Qnil
;
8864 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
8865 doc
: /* Time after which cached images are removed from the cache.
8866 When an image has not been displayed this many seconds, remove it
8867 from the image cache. Value must be an integer or nil with nil
8868 meaning don't clear the cache. */);
8869 Vimage_cache_eviction_delay
= make_number (30 * 60);
8871 defsubr (&Sx_change_window_property
);
8872 defsubr (&Sx_delete_window_property
);
8873 defsubr (&Sx_window_property
);
8874 defsubr (&Sxw_display_color_p
);
8875 defsubr (&Sx_display_grayscale_p
);
8876 defsubr (&Sxw_color_defined_p
);
8877 defsubr (&Sxw_color_values
);
8878 defsubr (&Sx_server_max_request_size
);
8879 defsubr (&Sx_server_vendor
);
8880 defsubr (&Sx_server_version
);
8881 defsubr (&Sx_display_pixel_width
);
8882 defsubr (&Sx_display_pixel_height
);
8883 defsubr (&Sx_display_mm_width
);
8884 defsubr (&Sx_display_mm_height
);
8885 defsubr (&Sx_display_screens
);
8886 defsubr (&Sx_display_planes
);
8887 defsubr (&Sx_display_color_cells
);
8888 defsubr (&Sx_display_visual_class
);
8889 defsubr (&Sx_display_backing_store
);
8890 defsubr (&Sx_display_save_under
);
8891 defsubr (&Sx_create_frame
);
8892 #if 0 /* MAC_TODO: implement network support */
8893 defsubr (&Sx_open_connection
);
8894 defsubr (&Sx_close_connection
);
8896 defsubr (&Sx_display_list
);
8897 defsubr (&Sx_synchronize
);
8899 /* Setting callback functions for fontset handler. */
8900 get_font_info_func
= x_get_font_info
;
8902 #if 0 /* This function pointer doesn't seem to be used anywhere.
8903 And the pointer assigned has the wrong type, anyway. */
8904 list_fonts_func
= x_list_fonts
;
8907 load_font_func
= x_load_font
;
8908 find_ccl_program_func
= x_find_ccl_program
;
8909 query_font_func
= x_query_font
;
8911 set_frame_fontset_func
= x_set_font
;
8912 check_window_system_func
= check_mac
;
8914 #if 0 /* MAC_TODO: Image support for Mac Images. */
8915 Qxbm
= intern ("xbm");
8917 QCtype
= intern (":type");
8918 staticpro (&QCtype
);
8919 QCconversion
= intern (":conversion");
8920 staticpro (&QCconversion
);
8921 QCheuristic_mask
= intern (":heuristic-mask");
8922 staticpro (&QCheuristic_mask
);
8923 QCcolor_symbols
= intern (":color-symbols");
8924 staticpro (&QCcolor_symbols
);
8925 QCascent
= intern (":ascent");
8926 staticpro (&QCascent
);
8927 QCmargin
= intern (":margin");
8928 staticpro (&QCmargin
);
8929 QCrelief
= intern (":relief");
8930 staticpro (&QCrelief
);
8931 Qpostscript
= intern ("postscript");
8932 staticpro (&Qpostscript
);
8933 QCloader
= intern (":loader");
8934 staticpro (&QCloader
);
8935 QCbounding_box
= intern (":bounding-box");
8936 staticpro (&QCbounding_box
);
8937 QCpt_width
= intern (":pt-width");
8938 staticpro (&QCpt_width
);
8939 QCpt_height
= intern (":pt-height");
8940 staticpro (&QCpt_height
);
8941 QCindex
= intern (":index");
8942 staticpro (&QCindex
);
8943 Qpbm
= intern ("pbm");
8947 Qxpm
= intern ("xpm");
8952 Qjpeg
= intern ("jpeg");
8957 Qtiff
= intern ("tiff");
8962 Qgif
= intern ("gif");
8967 Qpng
= intern ("png");
8971 defsubr (&Sclear_image_cache
);
8975 defsubr (&Slookup_image
);
8977 #endif /* MAC_TODO */
8979 hourglass_atimer
= NULL
;
8980 hourglass_shown_p
= 0;
8982 defsubr (&Sx_show_tip
);
8983 defsubr (&Sx_hide_tip
);
8984 staticpro (&tip_timer
);
8987 #if 0 /* MAC_TODO */
8988 defsubr (&Sx_file_dialog
);
8997 Vimage_types
= Qnil
;
8999 define_image_type (&xbm_type
);
9000 #if 0 /* NTEMACS_TODO : Image support for W32 */
9001 define_image_type (&gs_type
);
9002 define_image_type (&pbm_type
);
9005 define_image_type (&xpm_type
);
9009 define_image_type (&jpeg_type
);
9013 define_image_type (&tiff_type
);
9017 define_image_type (&gif_type
);
9021 define_image_type (&png_type
);
9023 #endif /* NTEMACS_TODO */