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 */
613 /* MAC has no frame pixel diff. */
614 f
->x_pixels_diff
= 0;
615 f
->y_pixels_diff
= 0;
622 /* The default colors for the Mac color map */
623 typedef struct colormap_t
629 colormap_t mac_color_map
[] =
631 { RGB_TO_ULONG(255, 250, 250), "snow" },
632 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
633 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
634 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
635 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
636 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
637 { RGB_TO_ULONG(255, 250, 240), "floral white" },
638 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
639 { RGB_TO_ULONG(253, 245, 230), "old lace" },
640 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
641 { RGB_TO_ULONG(250, 240, 230), "linen" },
642 { RGB_TO_ULONG(250, 235, 215), "antique white" },
643 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
644 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
645 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
646 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
647 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
648 { RGB_TO_ULONG(255, 228, 196), "bisque" },
649 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
650 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
651 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
652 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
653 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
654 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
655 { RGB_TO_ULONG(255, 255, 240), "ivory" },
656 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
657 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
658 { RGB_TO_ULONG(255, 245, 238), "seashell" },
659 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
660 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
661 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
662 { RGB_TO_ULONG(240, 255, 255), "azure" },
663 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
664 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
665 { RGB_TO_ULONG(230, 230, 250), "lavender" },
666 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
667 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
668 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
669 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
670 { RGB_TO_ULONG(255, 255, 255), "white" },
671 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
672 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
673 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
674 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
675 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
676 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
677 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
678 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
679 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
680 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
681 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
682 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
683 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
684 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
685 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
686 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
687 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
688 { RGB_TO_ULONG(190, 190, 190), "gray" },
689 { RGB_TO_ULONG(190, 190, 190), "grey" },
690 { RGB_TO_ULONG(211, 211, 211), "light grey" },
691 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
692 { RGB_TO_ULONG(211, 211, 211), "light gray" },
693 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
694 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
695 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
696 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
697 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
698 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
699 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
700 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
701 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
702 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
703 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
704 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
705 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
706 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
707 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
708 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
709 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
710 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
711 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
712 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
713 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
714 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
715 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
716 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
717 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
718 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
719 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
720 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
721 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
722 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
723 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
724 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
725 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
726 { RGB_TO_ULONG(173, 216, 230), "light blue" },
727 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
728 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
729 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
730 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
731 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
732 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
733 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
734 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
735 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
736 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
737 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
738 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
739 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
740 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
741 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
742 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
743 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
744 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
745 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
746 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
747 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
748 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
749 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
750 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
751 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
752 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
753 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
754 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
755 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
756 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
757 { RGB_TO_ULONG(152, 251, 152), "pale green" },
758 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
759 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
760 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
761 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
762 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
763 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
764 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
765 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
766 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
767 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
768 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
769 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
770 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
771 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
772 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
773 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
774 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
775 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
776 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
777 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
778 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
779 { RGB_TO_ULONG(240, 230, 140), "khaki" },
780 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
781 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
782 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
783 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
784 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
785 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
786 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
787 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
788 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
789 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
790 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
791 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
792 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
793 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
794 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
795 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
796 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
797 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
798 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
799 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
800 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
801 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
802 { RGB_TO_ULONG(245, 245, 220), "beige" },
803 { RGB_TO_ULONG(245, 222, 179), "wheat" },
804 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
805 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
806 { RGB_TO_ULONG(210, 180, 140), "tan" },
807 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
808 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
809 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
810 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
811 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
812 { RGB_TO_ULONG(250, 128, 114), "salmon" },
813 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
814 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
815 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
816 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
817 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
818 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
819 { RGB_TO_ULONG(240, 128, 128), "light coral" },
820 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
821 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
822 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
823 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
824 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
825 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
826 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
827 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
828 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
829 { RGB_TO_ULONG(255, 192, 203), "pink" },
830 { RGB_TO_ULONG(255, 182, 193), "light pink" },
831 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
832 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
833 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
834 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
835 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
836 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
837 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
838 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
839 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
840 { RGB_TO_ULONG(238, 130, 238), "violet" },
841 { RGB_TO_ULONG(221, 160, 221), "plum" },
842 { RGB_TO_ULONG(218, 112, 214), "orchid" },
843 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
844 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
845 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
846 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
847 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
848 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
849 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
850 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
851 { RGB_TO_ULONG(160, 32 , 240), "purple" },
852 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
853 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
854 { RGB_TO_ULONG(216, 191, 216), "thistle" },
855 { RGB_TO_ULONG(255, 250, 250), "snow1" },
856 { RGB_TO_ULONG(238, 233, 233), "snow2" },
857 { RGB_TO_ULONG(205, 201, 201), "snow3" },
858 { RGB_TO_ULONG(139, 137, 137), "snow4" },
859 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
860 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
861 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
862 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
863 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
864 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
865 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
866 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
867 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
868 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
869 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
870 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
871 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
872 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
873 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
874 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
875 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
876 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
877 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
878 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
879 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
880 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
881 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
882 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
883 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
884 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
885 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
886 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
887 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
888 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
889 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
890 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
891 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
892 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
893 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
894 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
895 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
896 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
897 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
898 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
899 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
900 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
901 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
902 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
903 { RGB_TO_ULONG(240, 255, 255), "azure1" },
904 { RGB_TO_ULONG(224, 238, 238), "azure2" },
905 { RGB_TO_ULONG(193, 205, 205), "azure3" },
906 { RGB_TO_ULONG(131, 139, 139), "azure4" },
907 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
908 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
909 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
910 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
911 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
912 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
913 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
914 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
915 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
916 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
917 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
918 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
919 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
920 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
921 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
922 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
923 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
924 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
925 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
926 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
927 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
928 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
929 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
930 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
931 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
932 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
933 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
934 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
935 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
936 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
937 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
938 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
939 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
940 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
941 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
942 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
943 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
944 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
945 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
946 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
947 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
948 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
949 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
950 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
951 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
952 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
953 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
954 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
955 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
956 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
957 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
958 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
959 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
960 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
961 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
962 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
963 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
964 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
965 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
966 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
967 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
968 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
969 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
970 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
971 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
972 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
973 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
974 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
975 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
976 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
977 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
978 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
979 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
980 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
981 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
982 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
983 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
984 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
985 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
986 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
987 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
988 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
989 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
990 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
991 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
992 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
993 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
994 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
995 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
996 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
997 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
998 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
999 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
1000 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
1001 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
1002 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
1003 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
1004 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
1005 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
1006 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
1007 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
1008 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
1009 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
1010 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
1011 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
1012 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
1013 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
1014 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
1015 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
1016 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
1017 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
1018 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
1019 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
1020 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
1021 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
1022 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
1023 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
1024 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
1025 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
1026 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
1027 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
1028 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
1029 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
1030 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
1031 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
1032 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
1033 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
1034 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
1035 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
1036 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
1037 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
1038 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
1039 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
1040 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
1041 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
1042 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
1043 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
1044 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
1045 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
1046 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
1047 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
1048 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
1049 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
1050 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
1051 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
1052 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
1053 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
1054 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
1055 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
1056 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
1057 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
1058 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
1059 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
1060 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
1061 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
1062 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
1063 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
1064 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
1065 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
1066 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
1067 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
1068 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
1069 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
1070 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
1071 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
1072 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
1073 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
1074 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
1075 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
1076 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
1077 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
1078 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
1079 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
1080 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
1081 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
1082 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
1083 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
1084 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
1085 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
1086 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
1087 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
1088 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
1089 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
1090 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
1091 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
1092 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
1093 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
1094 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
1095 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
1096 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
1097 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
1098 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
1099 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
1100 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
1101 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
1102 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
1103 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
1104 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
1105 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
1106 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
1107 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
1108 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
1109 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
1110 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
1111 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
1112 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
1113 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
1114 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
1115 { RGB_TO_ULONG(255, 181, 197), "pink1" },
1116 { RGB_TO_ULONG(238, 169, 184), "pink2" },
1117 { RGB_TO_ULONG(205, 145, 158), "pink3" },
1118 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
1119 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
1120 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
1121 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
1122 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
1123 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
1124 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
1125 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
1126 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
1127 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
1128 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
1129 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
1130 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
1131 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
1132 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
1133 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
1134 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
1135 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
1136 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
1137 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
1138 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
1139 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
1140 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
1141 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
1142 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
1143 { RGB_TO_ULONG(255, 187, 255), "plum1" },
1144 { RGB_TO_ULONG(238, 174, 238), "plum2" },
1145 { RGB_TO_ULONG(205, 150, 205), "plum3" },
1146 { RGB_TO_ULONG(139, 102, 139), "plum4" },
1147 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
1148 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
1149 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
1150 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
1151 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
1152 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
1153 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
1154 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
1155 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
1156 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
1157 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
1158 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
1159 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
1160 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
1161 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
1162 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
1163 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
1164 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
1165 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
1166 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
1167 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
1168 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
1169 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
1170 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
1171 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
1172 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
1173 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
1174 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
1175 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
1176 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
1177 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
1178 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
1179 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
1180 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
1181 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
1182 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
1183 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
1184 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
1185 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
1186 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
1187 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
1188 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
1189 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
1190 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
1191 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
1192 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
1193 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
1194 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
1195 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
1196 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
1197 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
1198 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
1199 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
1200 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
1201 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
1202 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
1203 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
1204 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
1205 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
1206 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
1207 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
1208 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
1209 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
1210 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
1211 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
1212 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
1213 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
1214 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
1215 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
1216 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
1217 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
1218 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
1219 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
1220 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
1221 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
1222 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
1223 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
1224 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
1225 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
1226 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
1227 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
1228 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
1229 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
1230 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
1231 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
1232 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
1233 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
1234 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
1235 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
1236 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
1237 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
1238 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
1239 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
1240 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
1241 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
1242 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
1243 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
1244 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
1245 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
1246 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
1247 { RGB_TO_ULONG(102, 102, 102), "gray40" },
1248 { RGB_TO_ULONG(102, 102, 102), "grey40" },
1249 { RGB_TO_ULONG(105, 105, 105), "gray41" },
1250 { RGB_TO_ULONG(105, 105, 105), "grey41" },
1251 { RGB_TO_ULONG(107, 107, 107), "gray42" },
1252 { RGB_TO_ULONG(107, 107, 107), "grey42" },
1253 { RGB_TO_ULONG(110, 110, 110), "gray43" },
1254 { RGB_TO_ULONG(110, 110, 110), "grey43" },
1255 { RGB_TO_ULONG(112, 112, 112), "gray44" },
1256 { RGB_TO_ULONG(112, 112, 112), "grey44" },
1257 { RGB_TO_ULONG(115, 115, 115), "gray45" },
1258 { RGB_TO_ULONG(115, 115, 115), "grey45" },
1259 { RGB_TO_ULONG(117, 117, 117), "gray46" },
1260 { RGB_TO_ULONG(117, 117, 117), "grey46" },
1261 { RGB_TO_ULONG(120, 120, 120), "gray47" },
1262 { RGB_TO_ULONG(120, 120, 120), "grey47" },
1263 { RGB_TO_ULONG(122, 122, 122), "gray48" },
1264 { RGB_TO_ULONG(122, 122, 122), "grey48" },
1265 { RGB_TO_ULONG(125, 125, 125), "gray49" },
1266 { RGB_TO_ULONG(125, 125, 125), "grey49" },
1267 { RGB_TO_ULONG(127, 127, 127), "gray50" },
1268 { RGB_TO_ULONG(127, 127, 127), "grey50" },
1269 { RGB_TO_ULONG(130, 130, 130), "gray51" },
1270 { RGB_TO_ULONG(130, 130, 130), "grey51" },
1271 { RGB_TO_ULONG(133, 133, 133), "gray52" },
1272 { RGB_TO_ULONG(133, 133, 133), "grey52" },
1273 { RGB_TO_ULONG(135, 135, 135), "gray53" },
1274 { RGB_TO_ULONG(135, 135, 135), "grey53" },
1275 { RGB_TO_ULONG(138, 138, 138), "gray54" },
1276 { RGB_TO_ULONG(138, 138, 138), "grey54" },
1277 { RGB_TO_ULONG(140, 140, 140), "gray55" },
1278 { RGB_TO_ULONG(140, 140, 140), "grey55" },
1279 { RGB_TO_ULONG(143, 143, 143), "gray56" },
1280 { RGB_TO_ULONG(143, 143, 143), "grey56" },
1281 { RGB_TO_ULONG(145, 145, 145), "gray57" },
1282 { RGB_TO_ULONG(145, 145, 145), "grey57" },
1283 { RGB_TO_ULONG(148, 148, 148), "gray58" },
1284 { RGB_TO_ULONG(148, 148, 148), "grey58" },
1285 { RGB_TO_ULONG(150, 150, 150), "gray59" },
1286 { RGB_TO_ULONG(150, 150, 150), "grey59" },
1287 { RGB_TO_ULONG(153, 153, 153), "gray60" },
1288 { RGB_TO_ULONG(153, 153, 153), "grey60" },
1289 { RGB_TO_ULONG(156, 156, 156), "gray61" },
1290 { RGB_TO_ULONG(156, 156, 156), "grey61" },
1291 { RGB_TO_ULONG(158, 158, 158), "gray62" },
1292 { RGB_TO_ULONG(158, 158, 158), "grey62" },
1293 { RGB_TO_ULONG(161, 161, 161), "gray63" },
1294 { RGB_TO_ULONG(161, 161, 161), "grey63" },
1295 { RGB_TO_ULONG(163, 163, 163), "gray64" },
1296 { RGB_TO_ULONG(163, 163, 163), "grey64" },
1297 { RGB_TO_ULONG(166, 166, 166), "gray65" },
1298 { RGB_TO_ULONG(166, 166, 166), "grey65" },
1299 { RGB_TO_ULONG(168, 168, 168), "gray66" },
1300 { RGB_TO_ULONG(168, 168, 168), "grey66" },
1301 { RGB_TO_ULONG(171, 171, 171), "gray67" },
1302 { RGB_TO_ULONG(171, 171, 171), "grey67" },
1303 { RGB_TO_ULONG(173, 173, 173), "gray68" },
1304 { RGB_TO_ULONG(173, 173, 173), "grey68" },
1305 { RGB_TO_ULONG(176, 176, 176), "gray69" },
1306 { RGB_TO_ULONG(176, 176, 176), "grey69" },
1307 { RGB_TO_ULONG(179, 179, 179), "gray70" },
1308 { RGB_TO_ULONG(179, 179, 179), "grey70" },
1309 { RGB_TO_ULONG(181, 181, 181), "gray71" },
1310 { RGB_TO_ULONG(181, 181, 181), "grey71" },
1311 { RGB_TO_ULONG(184, 184, 184), "gray72" },
1312 { RGB_TO_ULONG(184, 184, 184), "grey72" },
1313 { RGB_TO_ULONG(186, 186, 186), "gray73" },
1314 { RGB_TO_ULONG(186, 186, 186), "grey73" },
1315 { RGB_TO_ULONG(189, 189, 189), "gray74" },
1316 { RGB_TO_ULONG(189, 189, 189), "grey74" },
1317 { RGB_TO_ULONG(191, 191, 191), "gray75" },
1318 { RGB_TO_ULONG(191, 191, 191), "grey75" },
1319 { RGB_TO_ULONG(194, 194, 194), "gray76" },
1320 { RGB_TO_ULONG(194, 194, 194), "grey76" },
1321 { RGB_TO_ULONG(196, 196, 196), "gray77" },
1322 { RGB_TO_ULONG(196, 196, 196), "grey77" },
1323 { RGB_TO_ULONG(199, 199, 199), "gray78" },
1324 { RGB_TO_ULONG(199, 199, 199), "grey78" },
1325 { RGB_TO_ULONG(201, 201, 201), "gray79" },
1326 { RGB_TO_ULONG(201, 201, 201), "grey79" },
1327 { RGB_TO_ULONG(204, 204, 204), "gray80" },
1328 { RGB_TO_ULONG(204, 204, 204), "grey80" },
1329 { RGB_TO_ULONG(207, 207, 207), "gray81" },
1330 { RGB_TO_ULONG(207, 207, 207), "grey81" },
1331 { RGB_TO_ULONG(209, 209, 209), "gray82" },
1332 { RGB_TO_ULONG(209, 209, 209), "grey82" },
1333 { RGB_TO_ULONG(212, 212, 212), "gray83" },
1334 { RGB_TO_ULONG(212, 212, 212), "grey83" },
1335 { RGB_TO_ULONG(214, 214, 214), "gray84" },
1336 { RGB_TO_ULONG(214, 214, 214), "grey84" },
1337 { RGB_TO_ULONG(217, 217, 217), "gray85" },
1338 { RGB_TO_ULONG(217, 217, 217), "grey85" },
1339 { RGB_TO_ULONG(219, 219, 219), "gray86" },
1340 { RGB_TO_ULONG(219, 219, 219), "grey86" },
1341 { RGB_TO_ULONG(222, 222, 222), "gray87" },
1342 { RGB_TO_ULONG(222, 222, 222), "grey87" },
1343 { RGB_TO_ULONG(224, 224, 224), "gray88" },
1344 { RGB_TO_ULONG(224, 224, 224), "grey88" },
1345 { RGB_TO_ULONG(227, 227, 227), "gray89" },
1346 { RGB_TO_ULONG(227, 227, 227), "grey89" },
1347 { RGB_TO_ULONG(229, 229, 229), "gray90" },
1348 { RGB_TO_ULONG(229, 229, 229), "grey90" },
1349 { RGB_TO_ULONG(232, 232, 232), "gray91" },
1350 { RGB_TO_ULONG(232, 232, 232), "grey91" },
1351 { RGB_TO_ULONG(235, 235, 235), "gray92" },
1352 { RGB_TO_ULONG(235, 235, 235), "grey92" },
1353 { RGB_TO_ULONG(237, 237, 237), "gray93" },
1354 { RGB_TO_ULONG(237, 237, 237), "grey93" },
1355 { RGB_TO_ULONG(240, 240, 240), "gray94" },
1356 { RGB_TO_ULONG(240, 240, 240), "grey94" },
1357 { RGB_TO_ULONG(242, 242, 242), "gray95" },
1358 { RGB_TO_ULONG(242, 242, 242), "grey95" },
1359 { RGB_TO_ULONG(245, 245, 245), "gray96" },
1360 { RGB_TO_ULONG(245, 245, 245), "grey96" },
1361 { RGB_TO_ULONG(247, 247, 247), "gray97" },
1362 { RGB_TO_ULONG(247, 247, 247), "grey97" },
1363 { RGB_TO_ULONG(250, 250, 250), "gray98" },
1364 { RGB_TO_ULONG(250, 250, 250), "grey98" },
1365 { RGB_TO_ULONG(252, 252, 252), "gray99" },
1366 { RGB_TO_ULONG(252, 252, 252), "grey99" },
1367 { RGB_TO_ULONG(255, 255, 255), "gray100" },
1368 { RGB_TO_ULONG(255, 255, 255), "grey100" },
1369 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
1370 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
1371 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
1372 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
1373 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
1374 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
1375 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
1376 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
1377 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
1378 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
1379 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
1380 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1381 { RGB_TO_ULONG(144, 238, 144), "light green" },
1382 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1386 mac_color_map_lookup (colorname
)
1389 Lisp_Object ret
= Qnil
;
1394 for (i
= 0; i
< sizeof (mac_color_map
) / sizeof (mac_color_map
[0]); i
++)
1395 if (stricmp (colorname
, mac_color_map
[i
].name
) == 0)
1397 ret
= mac_color_map
[i
].color
;
1407 x_to_mac_color (colorname
)
1410 register Lisp_Object tail
, ret
= Qnil
;
1414 if (colorname
[0] == '#')
1416 /* Could be an old-style RGB Device specification. */
1419 color
= colorname
+ 1;
1421 size
= strlen(color
);
1422 if (size
== 3 || size
== 6 || size
== 9 || size
== 12)
1424 unsigned long colorval
;
1430 for (i
= 0; i
< 3; i
++)
1434 unsigned long value
;
1436 /* The check for 'x' in the following conditional takes into
1437 account the fact that strtol allows a "0x" in front of
1438 our numbers, and we don't. */
1439 if (!isxdigit(color
[0]) || color
[1] == 'x')
1443 value
= strtoul(color
, &end
, 16);
1445 if (errno
== ERANGE
|| end
- color
!= size
)
1450 value
= value
* 0x10;
1461 colorval
|= (value
<< pos
);
1472 else if (strnicmp(colorname
, "rgb:", 4) == 0)
1475 unsigned long colorval
;
1480 color
= colorname
+ 4;
1481 for (i
= 0; i
< 3; i
++)
1484 unsigned long value
;
1486 /* The check for 'x' in the following conditional takes into
1487 account the fact that strtol allows a "0x" in front of
1488 our numbers, and we don't. */
1489 if (!isxdigit(color
[0]) || color
[1] == 'x')
1491 value
= strtoul(color
, &end
, 16);
1492 if (errno
== ERANGE
)
1494 switch (end
- color
)
1497 value
= value
* 0x10 + value
;
1510 if (value
== ULONG_MAX
)
1512 colorval
|= (value
<< pos
);
1526 else if (strnicmp(colorname
, "rgbi:", 5) == 0)
1528 /* This is an RGB Intensity specification. */
1530 unsigned long colorval
;
1535 color
= colorname
+ 5;
1536 for (i
= 0; i
< 3; i
++)
1542 value
= strtod(color
, &end
);
1543 if (errno
== ERANGE
)
1545 if (value
< 0.0 || value
> 1.0)
1547 val
= (unsigned long)(0x100 * value
);
1548 /* We used 0x100 instead of 0xFF to give a continuous
1549 range between 0.0 and 1.0 inclusive. The next statement
1550 fixes the 1.0 case. */
1553 colorval
|= (val
<< pos
);
1568 ret
= mac_color_map_lookup (colorname
);
1574 /* Gamma-correct COLOR on frame F. */
1577 gamma_correct (f
, color
)
1579 unsigned long *color
;
1583 unsigned long red
, green
, blue
;
1585 red
= pow (RED_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
1586 green
= pow (GREEN_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
1587 blue
= pow (BLUE_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
1588 *color
= RGB_TO_ULONG (red
, green
, blue
);
1592 /* Decide if color named COLOR is valid for the display associated
1593 with the selected frame; if so, return the rgb values in COLOR_DEF.
1594 If ALLOC is nonzero, allocate a new colormap cell. */
1597 mac_defined_color (f
, color
, color_def
, alloc
)
1603 register Lisp_Object tem
;
1604 unsigned long mac_color_ref
;
1606 tem
= x_to_mac_color (color
);
1612 /* Apply gamma correction. */
1613 mac_color_ref
= XUINT (tem
);
1614 gamma_correct (f
, &mac_color_ref
);
1615 XSETINT (tem
, mac_color_ref
);
1618 color_def
->pixel
= mac_color_ref
;
1619 color_def
->red
= RED_FROM_ULONG (mac_color_ref
);
1620 color_def
->green
= GREEN_FROM_ULONG (mac_color_ref
);
1621 color_def
->blue
= BLUE_FROM_ULONG (mac_color_ref
);
1631 /* Given a string ARG naming a color, compute a pixel value from it
1632 suitable for screen F.
1633 If F is not a color screen, return DEF (default) regardless of what
1637 x_decode_color (f
, arg
, def
)
1646 if (strcmp (SDATA (arg
), "black") == 0)
1647 return BLACK_PIX_DEFAULT (f
);
1648 else if (strcmp (SDATA (arg
), "white") == 0)
1649 return WHITE_PIX_DEFAULT (f
);
1652 if ((FRAME_MAC_DISPLAY_INFO (f
)->n_planes
1653 * FRAME_MAC_DISPLAY_INFO (f
)->n_cbits
) == 1)
1657 if (mac_defined_color (f
, SDATA (arg
), &cdef
, 1))
1660 /* defined_color failed; return an ultimate default. */
1664 /* Functions called only from `x_set_frame_param'
1665 to set individual parameters.
1667 If FRAME_MAC_WINDOW (f) is 0,
1668 the frame is being created and its window does not exist yet.
1669 In that case, just record the parameter's new value
1670 in the standard place; do not attempt to change the window. */
1673 x_set_foreground_color (f
, arg
, oldval
)
1675 Lisp_Object arg
, oldval
;
1677 FRAME_FOREGROUND_PIXEL (f
)
1678 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1680 if (FRAME_MAC_WINDOW (f
) != 0)
1682 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
1683 if (FRAME_VISIBLE_P (f
))
1689 x_set_background_color (f
, arg
, oldval
)
1691 Lisp_Object arg
, oldval
;
1693 FRAME_BACKGROUND_PIXEL (f
)
1694 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1696 if (FRAME_MAC_WINDOW (f
) != 0)
1698 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
1700 if (FRAME_VISIBLE_P (f
))
1706 x_set_mouse_color (f
, arg
, oldval
)
1708 Lisp_Object arg
, oldval
;
1710 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
1714 if (!EQ (Qnil
, arg
))
1715 f
->output_data
.mac
->mouse_pixel
1716 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1717 mask_color
= FRAME_BACKGROUND_PIXEL (f
);
1719 /* Don't let pointers be invisible. */
1720 if (mask_color
== f
->output_data
.mac
->mouse_pixel
1721 && mask_color
== FRAME_BACKGROUND_PIXEL (f
))
1722 f
->output_data
.mac
->mouse_pixel
= FRAME_FOREGROUND_PIXEL (f
);
1724 #if 0 /* MAC_TODO : cursor changes */
1727 /* It's not okay to crash if the user selects a screwy cursor. */
1728 count
= x_catch_errors (FRAME_W32_DISPLAY (f
));
1730 if (!EQ (Qnil
, Vx_pointer_shape
))
1732 CHECK_NUMBER (Vx_pointer_shape
);
1733 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XINT (Vx_pointer_shape
));
1736 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1737 x_check_errors (FRAME_W32_DISPLAY (f
), "bad text pointer cursor: %s");
1739 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1741 CHECK_NUMBER (Vx_nontext_pointer_shape
);
1742 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1743 XINT (Vx_nontext_pointer_shape
));
1746 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_left_ptr
);
1747 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
1749 if (!EQ (Qnil
, Vx_hourglass_pointer_shape
))
1751 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
1752 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1753 XINT (Vx_hourglass_pointer_shape
));
1756 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_watch
);
1757 x_check_errors (FRAME_W32_DISPLAY (f
), "bad busy pointer cursor: %s");
1759 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
1760 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1762 CHECK_NUMBER (Vx_mode_pointer_shape
);
1763 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1764 XINT (Vx_mode_pointer_shape
));
1767 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1768 x_check_errors (FRAME_W32_DISPLAY (f
), "bad modeline pointer cursor: %s");
1770 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1772 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1774 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1775 XINT (Vx_sensitive_text_pointer_shape
));
1778 hand_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_crosshair
);
1780 if (!NILP (Vx_window_horizontal_drag_shape
))
1782 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1783 horizontal_drag_cursor
1784 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1785 XINT (Vx_window_horizontal_drag_shape
));
1788 horizontal_drag_cursor
1789 = XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_sb_h_double_arrow
);
1791 /* Check and report errors with the above calls. */
1792 x_check_errors (FRAME_W32_DISPLAY (f
), "can't set cursor shape: %s");
1793 x_uncatch_errors (FRAME_W32_DISPLAY (f
), count
);
1796 XColor fore_color
, back_color
;
1798 fore_color
.pixel
= f
->output_data
.w32
->mouse_pixel
;
1799 back_color
.pixel
= mask_color
;
1800 XQueryColor (FRAME_W32_DISPLAY (f
),
1801 DefaultColormap (FRAME_W32_DISPLAY (f
),
1802 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1804 XQueryColor (FRAME_W32_DISPLAY (f
),
1805 DefaultColormap (FRAME_W32_DISPLAY (f
),
1806 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1808 XRecolorCursor (FRAME_W32_DISPLAY (f
), cursor
,
1809 &fore_color
, &back_color
);
1810 XRecolorCursor (FRAME_W32_DISPLAY (f
), nontext_cursor
,
1811 &fore_color
, &back_color
);
1812 XRecolorCursor (FRAME_W32_DISPLAY (f
), mode_cursor
,
1813 &fore_color
, &back_color
);
1814 XRecolorCursor (FRAME_W32_DISPLAY (f
), hand_cursor
,
1815 &fore_color
, &back_color
);
1816 XRecolorCursor (FRAME_W32_DISPLAY (f
), hourglass_cursor
,
1817 &fore_color
, &back_color
);
1820 if (FRAME_W32_WINDOW (f
) != 0)
1821 XDefineCursor (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), cursor
);
1823 if (cursor
!= f
->output_data
.w32
->text_cursor
&& f
->output_data
.w32
->text_cursor
!= 0)
1824 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->text_cursor
);
1825 f
->output_data
.w32
->text_cursor
= cursor
;
1827 if (nontext_cursor
!= f
->output_data
.w32
->nontext_cursor
1828 && f
->output_data
.w32
->nontext_cursor
!= 0)
1829 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->nontext_cursor
);
1830 f
->output_data
.w32
->nontext_cursor
= nontext_cursor
;
1832 if (hourglass_cursor
!= f
->output_data
.w32
->hourglass_cursor
1833 && f
->output_data
.w32
->hourglass_cursor
!= 0)
1834 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hourglass_cursor
);
1835 f
->output_data
.w32
->hourglass_cursor
= hourglass_cursor
;
1837 if (mode_cursor
!= f
->output_data
.w32
->modeline_cursor
1838 && f
->output_data
.w32
->modeline_cursor
!= 0)
1839 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->modeline_cursor
);
1840 f
->output_data
.w32
->modeline_cursor
= mode_cursor
;
1842 if (hand_cursor
!= f
->output_data
.w32
->hand_cursor
1843 && f
->output_data
.w32
->hand_cursor
!= 0)
1844 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hand_cursor
);
1845 f
->output_data
.w32
->hand_cursor
= hand_cursor
;
1847 XFlush (FRAME_W32_DISPLAY (f
));
1850 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1851 #endif /* MAC_TODO */
1855 x_set_cursor_color (f
, arg
, oldval
)
1857 Lisp_Object arg
, oldval
;
1859 unsigned long fore_pixel
;
1861 if (!NILP (Vx_cursor_fore_pixel
))
1862 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1863 WHITE_PIX_DEFAULT (f
));
1865 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1866 f
->output_data
.mac
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1868 /* Make sure that the cursor color differs from the background color. */
1869 if (f
->output_data
.mac
->cursor_pixel
== FRAME_BACKGROUND_PIXEL (f
))
1871 f
->output_data
.mac
->cursor_pixel
= f
->output_data
.mac
->mouse_pixel
;
1872 if (f
->output_data
.mac
->cursor_pixel
== fore_pixel
)
1873 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1875 FRAME_FOREGROUND_PIXEL (f
) = fore_pixel
;
1877 #if 0 /* MAC_TODO: cannot figure out what to do (wrong number of params) */
1878 if (FRAME_MAC_WINDOW (f
) != 0)
1880 if (FRAME_VISIBLE_P (f
))
1883 display_and_set_cursor (f
, 0);
1884 display_and_set_cursor (f
, 1);
1890 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1893 /* Set the border-color of frame F to pixel value PIX.
1894 Note that this does not fully take effect if done before
1897 x_set_border_pixel (f
, pix
)
1901 f
->output_data
.mac
->border_pixel
= pix
;
1903 if (FRAME_MAC_WINDOW (f
) != 0 && f
->border_width
> 0)
1905 if (FRAME_VISIBLE_P (f
))
1910 /* Set the border-color of frame F to value described by ARG.
1911 ARG can be a string naming a color.
1912 The border-color is used for the border that is drawn by the server.
1913 Note that this does not fully take effect if done before
1914 F has a window; it must be redone when the window is created. */
1917 x_set_border_color (f
, arg
, oldval
)
1919 Lisp_Object arg
, oldval
;
1924 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1925 x_set_border_pixel (f
, pix
);
1926 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1930 x_set_cursor_type (f
, arg
, oldval
)
1932 Lisp_Object arg
, oldval
;
1934 set_frame_cursor_types (f
, arg
);
1936 /* Make sure the cursor gets redrawn. This is overkill, but how
1937 often do people change cursor types? */
1938 update_mode_lines
++;
1941 #if 0 /* MAC_TODO: really no icon for Mac */
1943 x_set_icon_type (f
, arg
, oldval
)
1945 Lisp_Object arg
, oldval
;
1949 if (NILP (arg
) && NILP (oldval
))
1952 if (STRINGP (arg
) && STRINGP (oldval
)
1953 && EQ (Fstring_equal (oldval
, arg
), Qt
))
1956 if (SYMBOLP (arg
) && SYMBOLP (oldval
) && EQ (arg
, oldval
))
1961 result
= x_bitmap_icon (f
, arg
);
1965 error ("No icon window available");
1970 #endif /* MAC_TODO */
1973 x_set_icon_name (f
, arg
, oldval
)
1975 Lisp_Object arg
, oldval
;
1981 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1984 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1989 #if 0 /* MAC_TODO */
1990 if (f
->output_data
.w32
->icon_bitmap
!= 0)
1995 result
= x_text_icon (f
,
1996 (char *) SDATA ((!NILP (f
->icon_name
)
2005 error ("No icon window available");
2008 /* If the window was unmapped (and its icon was mapped),
2009 the new icon is not mapped, so map the window in its stead. */
2010 if (FRAME_VISIBLE_P (f
))
2012 #ifdef USE_X_TOOLKIT
2013 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
2015 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
2018 XFlush (FRAME_W32_DISPLAY (f
));
2020 #endif /* MAC_TODO */
2025 x_set_menu_bar_lines (f
, value
, oldval
)
2027 Lisp_Object value
, oldval
;
2030 int olines
= FRAME_MENU_BAR_LINES (f
);
2032 /* Right now, menu bars don't work properly in minibuf-only frames;
2033 most of the commands try to apply themselves to the minibuffer
2034 frame itself, and get an error because you can't switch buffers
2035 in or split the minibuffer window. */
2036 if (FRAME_MINIBUF_ONLY_P (f
))
2039 if (INTEGERP (value
))
2040 nlines
= XINT (value
);
2044 FRAME_MENU_BAR_LINES (f
) = 0;
2046 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
2049 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
2050 free_frame_menubar (f
);
2051 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
2053 /* Adjust the frame size so that the client (text) dimensions
2054 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
2056 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
2057 do_pending_window_change (0);
2063 /* Set the number of lines used for the tool bar of frame F to VALUE.
2064 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
2065 is the old number of tool bar lines. This function changes the
2066 height of all windows on frame F to match the new tool bar height.
2067 The frame's height doesn't change. */
2070 x_set_tool_bar_lines (f
, value
, oldval
)
2072 Lisp_Object value
, oldval
;
2074 int delta
, nlines
, root_height
;
2075 Lisp_Object root_window
;
2077 /* Treat tool bars like menu bars. */
2078 if (FRAME_MINIBUF_ONLY_P (f
))
2081 /* Use VALUE only if an integer >= 0. */
2082 if (INTEGERP (value
) && XINT (value
) >= 0)
2083 nlines
= XFASTINT (value
);
2087 /* Make sure we redisplay all windows in this frame. */
2088 ++windows_or_buffers_changed
;
2090 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
2092 /* Don't resize the tool-bar to more than we have room for. */
2093 root_window
= FRAME_ROOT_WINDOW (f
);
2094 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
2095 if (root_height
- delta
< 1)
2097 delta
= root_height
- 1;
2098 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
2101 FRAME_TOOL_BAR_LINES (f
) = nlines
;
2102 change_window_heights (root_window
, delta
);
2105 /* We also have to make sure that the internal border at the top of
2106 the frame, below the menu bar or tool bar, is redrawn when the
2107 tool bar disappears. This is so because the internal border is
2108 below the tool bar if one is displayed, but is below the menu bar
2109 if there isn't a tool bar. The tool bar draws into the area
2110 below the menu bar. */
2111 if (FRAME_MAC_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
2115 clear_current_matrices (f
);
2116 updating_frame
= NULL
;
2119 /* If the tool bar gets smaller, the internal border below it
2120 has to be cleared. It was formerly part of the display
2121 of the larger tool bar, and updating windows won't clear it. */
2124 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
2125 int width
= FRAME_PIXEL_WIDTH (f
);
2126 int y
= nlines
* FRAME_LINE_HEIGHT (f
);
2129 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2130 0, y
, width
, height
, 0);
2133 if (WINDOWP (f
->tool_bar_window
))
2134 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
2139 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
2142 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2143 name; if NAME is a string, set F's name to NAME and set
2144 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2146 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2147 suggesting a new name, which lisp code should override; if
2148 F->explicit_name is set, ignore the new name; otherwise, set it. */
2151 x_set_name (f
, name
, explicit)
2156 /* Make sure that requests from lisp code override requests from
2157 Emacs redisplay code. */
2160 /* If we're switching from explicit to implicit, we had better
2161 update the mode lines and thereby update the title. */
2162 if (f
->explicit_name
&& NILP (name
))
2163 update_mode_lines
= 1;
2165 f
->explicit_name
= ! NILP (name
);
2167 else if (f
->explicit_name
)
2170 /* If NAME is nil, set the name to the w32_id_name. */
2173 /* Check for no change needed in this very common case
2174 before we do any consing. */
2175 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
,
2178 name
= build_string (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
);
2181 CHECK_STRING (name
);
2183 /* Don't change the name if it's already NAME. */
2184 if (! NILP (Fstring_equal (name
, f
->name
)))
2189 /* For setting the frame title, the title parameter should override
2190 the name parameter. */
2191 if (! NILP (f
->title
))
2194 if (FRAME_MAC_WINDOW (f
))
2196 if (STRING_MULTIBYTE (name
))
2197 #if 0 /* MAC_TODO: encoding title string */
2198 name
= ENCODE_SYSTEM (name
);
2207 if (strlen (SDATA (name
)) < 255)
2209 strcpy (windowTitle
, SDATA (name
));
2210 c2pstr (windowTitle
);
2211 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2219 /* This function should be called when the user's lisp code has
2220 specified a name for the frame; the name will override any set by the
2223 x_explicitly_set_name (f
, arg
, oldval
)
2225 Lisp_Object arg
, oldval
;
2227 x_set_name (f
, arg
, 1);
2230 /* This function should be called by Emacs redisplay code to set the
2231 name; names set this way will never override names set by the user's
2234 x_implicitly_set_name (f
, arg
, oldval
)
2236 Lisp_Object arg
, oldval
;
2238 x_set_name (f
, arg
, 0);
2241 /* Change the title of frame F to NAME.
2242 If NAME is nil, use the frame name as the title.
2244 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2245 name; if NAME is a string, set F's name to NAME and set
2246 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2248 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2249 suggesting a new name, which lisp code should override; if
2250 F->explicit_name is set, ignore the new name; otherwise, set it. */
2253 x_set_title (f
, name
, old_name
)
2255 Lisp_Object name
, old_name
;
2257 /* Don't change the title if it's already NAME. */
2258 if (EQ (name
, f
->title
))
2261 update_mode_lines
= 1;
2268 if (FRAME_MAC_WINDOW (f
))
2270 if (STRING_MULTIBYTE (name
))
2271 #if 0 /* MAC_TODO: encoding title string */
2272 name
= ENCODE_SYSTEM (name
);
2281 if (strlen (SDATA (name
)) < 255)
2283 strcpy (windowTitle
, SDATA (name
));
2284 c2pstr (windowTitle
);
2285 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2294 x_set_scroll_bar_default_width (f
)
2297 /* Imitate X without X Toolkit */
2299 int wid
= FRAME_COLUMN_WIDTH (f
);
2302 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 16; /* Aqua scroll bars. */
2303 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) +
2305 #else /* not MAC_OSX */
2306 /* Make the actual width at least 14 pixels and a multiple of a
2308 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2310 /* Use all of that space (aside from required margins) for the
2312 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
2313 #endif /* not MAC_OSX */
2317 /* Subroutines of creating a frame. */
2320 x_get_string_resource (rdb
, name
, class)
2324 /* MAC_TODO: implement resource strings */
2328 /* Return the value of parameter PARAM.
2330 First search ALIST, then Vdefault_frame_alist, then the X defaults
2331 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2333 Convert the resource to the type specified by desired_type.
2335 If no default is specified, return Qunbound. If you call
2336 mac_get_arg, make sure you deal with Qunbound in a reasonable way,
2337 and don't let it get stored in any Lisp-visible variables! */
2340 mac_get_arg (alist
, param
, attribute
, class, type
)
2341 Lisp_Object alist
, param
;
2344 enum resource_types type
;
2346 return x_get_arg (check_x_display_info (Qnil
),
2347 alist
, param
, attribute
, class, type
);
2351 /* XParseGeometry copied from w32xfns.c */
2354 * XParseGeometry parses strings of the form
2355 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
2356 * width, height, xoffset, and yoffset are unsigned integers.
2357 * Example: "=80x24+300-49"
2358 * The equal sign is optional.
2359 * It returns a bitmask that indicates which of the four values
2360 * were actually found in the string. For each value found,
2361 * the corresponding argument is updated; for each value
2362 * not found, the corresponding argument is left unchanged.
2366 read_integer (string
, NextString
)
2367 register char *string
;
2370 register int Result
= 0;
2375 else if (*string
== '-')
2380 for (; (*string
>= '0') && (*string
<= '9'); string
++)
2382 Result
= (Result
* 10) + (*string
- '0');
2384 *NextString
= string
;
2392 XParseGeometry (string
, x
, y
, width
, height
)
2395 unsigned int *width
, *height
; /* RETURN */
2398 register char *strind
;
2399 unsigned int tempWidth
, tempHeight
;
2401 char *nextCharacter
;
2403 if ((string
== NULL
) || (*string
== '\0')) return (mask
);
2405 string
++; /* ignore possible '=' at beg of geometry spec */
2407 strind
= (char *)string
;
2408 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
2410 tempWidth
= read_integer (strind
, &nextCharacter
);
2411 if (strind
== nextCharacter
)
2413 strind
= nextCharacter
;
2417 if (*strind
== 'x' || *strind
== 'X')
2420 tempHeight
= read_integer (strind
, &nextCharacter
);
2421 if (strind
== nextCharacter
)
2423 strind
= nextCharacter
;
2424 mask
|= HeightValue
;
2427 if ((*strind
== '+') || (*strind
== '-'))
2432 tempX
= -read_integer (strind
, &nextCharacter
);
2433 if (strind
== nextCharacter
)
2435 strind
= nextCharacter
;
2442 tempX
= read_integer (strind
, &nextCharacter
);
2443 if (strind
== nextCharacter
)
2445 strind
= nextCharacter
;
2448 if ((*strind
== '+') || (*strind
== '-'))
2453 tempY
= -read_integer (strind
, &nextCharacter
);
2454 if (strind
== nextCharacter
)
2456 strind
= nextCharacter
;
2463 tempY
= read_integer (strind
, &nextCharacter
);
2464 if (strind
== nextCharacter
)
2466 strind
= nextCharacter
;
2472 /* If strind isn't at the end of the string the it's an invalid
2473 geometry specification. */
2475 if (*strind
!= '\0') return (0);
2481 if (mask
& WidthValue
)
2483 if (mask
& HeightValue
)
2484 *height
= tempHeight
;
2489 #if 0 /* MAC_TODO */
2490 /* Create and set up the Mac window for frame F. */
2493 mac_window (f
, window_prompting
, minibuffer_only
)
2495 long window_prompting
;
2496 int minibuffer_only
;
2502 /* Use the resource name as the top-level window name
2503 for looking up resources. Make a non-Lisp copy
2504 for the window manager, so GC relocation won't bother it.
2506 Elsewhere we specify the window name for the window manager. */
2509 char *str
= (char *) SDATA (Vx_resource_name
);
2510 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2511 strcpy (f
->namebuf
, str
);
2514 SetRect (&r
, f
->left_pos
, f
->top_pos
,
2515 f
->left_pos
+ FRAME_PIXEL_WIDTH (f
),
2516 f
->top_pos
+ FRAME_PIXEL_HEIGHT (f
));
2517 FRAME_MAC_WINDOW (f
)
2518 = NewCWindow (NULL
, &r
, "\p", 1, zoomDocProc
, (WindowPtr
) -1, 1, (long) f
->output_data
.mac
);
2520 validate_x_resource_name ();
2522 /* x_set_name normally ignores requests to set the name if the
2523 requested name is the same as the current name. This is the one
2524 place where that assumption isn't correct; f->name is set, but
2525 the server hasn't been told. */
2528 int explicit = f
->explicit_name
;
2530 f
->explicit_name
= 0;
2533 x_set_name (f
, name
, explicit);
2536 ShowWindow (FRAME_MAC_WINDOW (f
));
2540 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2541 initialize_frame_menubar (f
);
2543 if (FRAME_MAC_WINDOW (f
) == 0)
2544 error ("Unable to create window");
2546 #endif /* MAC_TODO */
2548 /* Handle the icon stuff for this window. Perhaps later we might
2549 want an x_set_icon_position which can be called interactively as
2557 Lisp_Object icon_x
, icon_y
;
2559 /* Set the position of the icon. Note that Windows 95 groups all
2560 icons in the tray. */
2561 icon_x
= mac_get_arg (parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2562 icon_y
= mac_get_arg (parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2563 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2565 CHECK_NUMBER (icon_x
);
2566 CHECK_NUMBER (icon_y
);
2568 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2569 error ("Both left and top icon corners of icon must be specified");
2573 if (! EQ (icon_x
, Qunbound
))
2574 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2577 /* Start up iconic or window? */
2578 x_wm_set_window_state
2579 (f
, (EQ (w32_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
), Qicon
)
2583 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
2596 XGCValues gc_values
;
2600 /* Create the GC's of this frame.
2601 Note that many default values are used. */
2604 gc_values
.font
= FRAME_FONT (f
);
2605 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
2606 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
2607 f
->output_data
.mac
->normal_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
2608 FRAME_MAC_WINDOW (f
),
2609 GCFont
| GCForeground
| GCBackground
,
2612 /* Reverse video style. */
2613 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2614 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
2615 f
->output_data
.mac
->reverse_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
2616 FRAME_MAC_WINDOW (f
),
2617 GCFont
| GCForeground
| GCBackground
,
2620 /* Cursor has cursor-color background, background-color foreground. */
2621 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2622 gc_values
.background
= f
->output_data
.mac
->cursor_pixel
;
2623 f
->output_data
.mac
->cursor_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
2624 FRAME_MAC_WINDOW (f
),
2625 GCFont
| GCForeground
| GCBackground
,
2629 f
->output_data
.mac
->white_relief
.gc
= 0;
2630 f
->output_data
.mac
->black_relief
.gc
= 0;
2636 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2638 doc
: /* Make a new window, which is called a \"frame\" in Emacs terms.
2639 Returns an Emacs frame object.
2640 ALIST is an alist of frame parameters.
2641 If the parameters specify that the frame should not have a minibuffer,
2642 and do not specify a specific minibuffer window to use,
2643 then `default-minibuffer-frame' must be a frame whose minibuffer can
2644 be shared by the new frame.
2646 This function is an internal primitive--use `make-frame' instead. */)
2651 Lisp_Object frame
, tem
;
2653 int minibuffer_only
= 0;
2654 long window_prompting
= 0;
2656 int count
= SPECPDL_INDEX ();
2657 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
2658 Lisp_Object display
;
2659 struct mac_display_info
*dpyinfo
= NULL
;
2662 char x_frame_name
[10];
2663 static int x_frame_count
= 2; /* begins at 2 because terminal frame is F1 */
2667 /* Use this general default value to start with
2668 until we know if this frame has a specified name. */
2669 Vx_resource_name
= Vinvocation_name
;
2671 display
= mac_get_arg (parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
2672 if (EQ (display
, Qunbound
))
2674 dpyinfo
= check_x_display_info (display
);
2676 kb
= dpyinfo
->kboard
;
2678 kb
= &the_only_kboard
;
2681 name
= mac_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
2683 && ! EQ (name
, Qunbound
)
2685 error ("Invalid frame name--not a string or nil");
2688 Vx_resource_name
= name
;
2690 /* See if parent window is specified. */
2691 parent
= mac_get_arg (parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
2692 if (EQ (parent
, Qunbound
))
2694 if (! NILP (parent
))
2695 CHECK_NUMBER (parent
);
2697 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2698 /* No need to protect DISPLAY because that's not used after passing
2699 it to make_frame_without_minibuffer. */
2701 GCPRO4 (parms
, parent
, name
, frame
);
2702 tem
= mac_get_arg (parms
, Qminibuffer
, "minibuffer", "Minibuffer",
2704 if (EQ (tem
, Qnone
) || NILP (tem
))
2705 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
2706 else if (EQ (tem
, Qonly
))
2708 f
= make_minibuffer_frame ();
2709 minibuffer_only
= 1;
2711 else if (WINDOWP (tem
))
2712 f
= make_frame_without_minibuffer (tem
, kb
, display
);
2716 if (EQ (name
, Qunbound
) || NILP (name
))
2718 sprintf (x_frame_name
, "F%d", x_frame_count
++);
2719 f
->name
= build_string (x_frame_name
);
2720 f
->explicit_name
= 0;
2725 f
->explicit_name
= 1;
2728 XSETFRAME (frame
, f
);
2730 /* Note that X Windows does support scroll bars. */
2731 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2733 f
->output_method
= output_mac
;
2734 f
->output_data
.mac
= (struct mac_output
*) xmalloc (sizeof (struct mac_output
));
2735 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
2736 FRAME_FONTSET (f
) = -1;
2737 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
2738 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
2741 FRAME_FONTSET (f
) = -1;
2745 = mac_get_arg (parms
, Qicon_name
, "iconName", "Title", RES_TYPE_STRING
);
2746 if (! STRINGP (f
->icon_name
))
2747 f
->icon_name
= Qnil
;
2749 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
2751 FRAME_KBOARD (f
) = kb
;
2754 /* Specify the parent under which to make this window. */
2758 f
->output_data
.mac
->parent_desc
= (Window
) parent
;
2759 f
->output_data
.mac
->explicit_parent
= 1;
2763 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
2764 f
->output_data
.mac
->explicit_parent
= 0;
2767 /* Set the name; the functions to which we pass f expect the name to
2769 if (EQ (name
, Qunbound
) || NILP (name
))
2771 f
->name
= build_string (dpyinfo
->mac_id_name
);
2772 f
->explicit_name
= 0;
2777 f
->explicit_name
= 1;
2778 /* use the frame's title when getting resources for this frame. */
2779 specbind (Qx_resource_name
, name
);
2782 /* Extract the window parameters from the supplied values
2783 that are needed to determine window geometry. */
2787 font
= mac_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
2790 /* First, try whatever font the caller has specified. */
2793 tem
= Fquery_fontset (font
, Qnil
);
2795 font
= x_new_fontset (f
, SDATA (tem
));
2797 font
= x_new_font (f
, SDATA (font
));
2799 /* Try out a font which we hope has bold and italic variations. */
2800 if (! STRINGP (font
))
2801 font
= x_new_font (f
, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
2802 /* If those didn't work, look for something which will at least work. */
2803 if (!STRINGP (font
))
2804 font
= x_new_font (f
, "-*-monaco-*-12-*-mac-roman");
2805 if (! STRINGP (font
))
2806 font
= x_new_font (f
, "-*-courier-*-10-*-mac-roman");
2807 if (! STRINGP (font
))
2808 error ("Cannot find any usable font");
2811 x_default_parameter (f
, parms
, Qfont
, font
,
2812 "font", "Font", RES_TYPE_STRING
);
2815 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
2816 "borderwidth", "BorderWidth", RES_TYPE_NUMBER
);
2817 /* This defaults to 2 in order to match xterm. We recognize either
2818 internalBorderWidth or internalBorder (which is what xterm calls
2820 if (NILP (Fassq (Qinternal_border_width
, parms
)))
2824 value
= mac_get_arg (parms
, Qinternal_border_width
,
2825 "internalBorder", "InternalBorder", RES_TYPE_NUMBER
);
2826 if (! EQ (value
, Qunbound
))
2827 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
2830 /* Default internalBorderWidth to 0 on Windows to match other programs. */
2831 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (0),
2832 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER
);
2833 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qright
,
2834 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL
);
2836 /* Also do the stuff which must be set before the window exists. */
2837 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
2838 "foreground", "Foreground", RES_TYPE_STRING
);
2839 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
2840 "background", "Background", RES_TYPE_STRING
);
2841 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
2842 "pointerColor", "Foreground", RES_TYPE_STRING
);
2843 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
2844 "cursorColor", "Foreground", RES_TYPE_STRING
);
2845 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
2846 "borderColor", "BorderColor", RES_TYPE_STRING
);
2847 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
2848 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
2849 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
2850 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
2851 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
2852 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
2853 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
2854 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
2857 /* Init faces before x_default_parameter is called for scroll-bar
2858 parameters because that function calls x_set_scroll_bar_width,
2859 which calls change_frame_size, which calls Fset_window_buffer,
2860 which runs hooks, which call Fvertical_motion. At the end, we
2861 end up in init_iterator with a null face cache, which should not
2863 init_frame_faces (f
);
2865 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
2866 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
2867 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (0),
2868 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
2869 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
2870 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL
);
2871 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
2872 "title", "Title", RES_TYPE_STRING
);
2874 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
2876 /* MAC_TODO: specify 1 below when toolbars are implemented. */
2877 window_prompting
= x_figure_window_size (f
, parms
, 0);
2879 tem
= mac_get_arg (parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
2880 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
2882 /* Create the window. Add the tool-bar height to the initial frame
2883 height so that the user gets a text display area of the size he
2884 specified with -g or via the registry. Later changes of the
2885 tool-bar height don't change the frame size. This is done so that
2886 users can create tall Emacs frames without having to guess how
2887 tall the tool-bar will get. */
2888 FRAME_LINES (f
) += FRAME_TOOL_BAR_LINES (f
);
2890 /* mac_window (f, window_prompting, minibuffer_only); */
2897 /* Now consider the frame official. */
2898 FRAME_MAC_DISPLAY_INFO (f
)->reference_count
++;
2899 Vframe_list
= Fcons (frame
, Vframe_list
);
2901 /* We need to do this after creating the window, so that the
2902 icon-creation functions can say whose icon they're describing. */
2903 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
2904 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
2906 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
2907 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
2908 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
2909 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
2910 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
2911 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
2912 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
2913 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER
);
2915 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
2916 Change will not be effected unless different from the current
2918 width
= FRAME_COLS (f
);
2919 height
= FRAME_LINES (f
);
2921 FRAME_LINES (f
) = 0;
2922 SET_FRAME_COLS (f
, 0);
2923 change_frame_size (f
, height
, width
, 1, 0, 0);
2925 /* Set up faces after all frame parameters are known. */
2926 call1 (Qface_set_after_frame_default
, frame
);
2928 #if 0 /* MAC_TODO: when we have window manager hints */
2929 /* Tell the server what size and position, etc, we want, and how
2930 badly we want them. This should be done after we have the menu
2931 bar so that its size can be taken into account. */
2933 x_wm_set_size_hint (f
, window_prompting
, 0);
2937 /* Make the window appear on the frame and enable display, unless
2938 the caller says not to. However, with explicit parent, Emacs
2939 cannot control visibility, so don't try. */
2940 if (! f
->output_data
.mac
->explicit_parent
)
2942 Lisp_Object visibility
;
2944 visibility
= mac_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
);
2945 if (EQ (visibility
, Qunbound
))
2948 #if 0 /* MAC_TODO: really no iconify on Mac */
2949 if (EQ (visibility
, Qicon
))
2950 x_iconify_frame (f
);
2953 if (! NILP (visibility
))
2954 x_make_frame_visible (f
);
2956 /* Must have been Qnil. */
2961 /* Make sure windows on this frame appear in calls to next-window
2962 and similar functions. */
2963 Vwindow_list
= Qnil
;
2965 return unbind_to (count
, frame
);
2968 /* FRAME is used only to get a handle on the X display. We don't pass the
2969 display info directly because we're called from frame.c, which doesn't
2970 know about that structure. */
2972 x_get_focus_frame (frame
)
2973 struct frame
*frame
;
2975 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
2977 if (! dpyinfo
->x_focus_frame
)
2980 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
2984 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
2985 doc
: /* Internal function called by `color-defined-p', which see. */)
2987 Lisp_Object color
, frame
;
2990 FRAME_PTR f
= check_x_frame (frame
);
2992 CHECK_STRING (color
);
2994 if (mac_defined_color (f
, SDATA (color
), &foo
, 0))
3000 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3001 doc
: /* Internal function called by `color-values', which see. */)
3003 Lisp_Object color
, frame
;
3006 FRAME_PTR f
= check_x_frame (frame
);
3008 CHECK_STRING (color
);
3010 if (mac_defined_color (f
, SDATA (color
), &foo
, 0))
3014 rgb
[0] = make_number ((RED_FROM_ULONG (foo
.pixel
) << 8)
3015 | RED_FROM_ULONG (foo
.pixel
));
3016 rgb
[1] = make_number ((GREEN_FROM_ULONG (foo
.pixel
) << 8)
3017 | GREEN_FROM_ULONG (foo
.pixel
));
3018 rgb
[2] = make_number ((BLUE_FROM_ULONG (foo
.pixel
) << 8)
3019 | BLUE_FROM_ULONG (foo
.pixel
));
3020 return Flist (3, rgb
);
3026 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3027 doc
: /* Internal function called by `display-color-p', which see. */)
3029 Lisp_Object display
;
3031 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3033 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 2)
3039 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3041 doc
: /* Return t if the X display supports shades of gray.
3042 Note that color displays do support shades of gray.
3043 The optional argument DISPLAY specifies which display to ask about.
3044 DISPLAY should be either a frame or a display name (a string).
3045 If omitted or nil, that stands for the selected frame's display. */)
3047 Lisp_Object display
;
3049 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3051 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 1)
3057 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3059 doc
: /* Returns the width in pixels of the X display DISPLAY.
3060 The optional argument DISPLAY specifies which display to ask about.
3061 DISPLAY should be either a frame or a display name (a string).
3062 If omitted or nil, that stands for the selected frame's display. */)
3064 Lisp_Object display
;
3066 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3068 return make_number (dpyinfo
->width
);
3071 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3072 Sx_display_pixel_height
, 0, 1, 0,
3073 doc
: /* Returns the height in pixels of the X display DISPLAY.
3074 The optional argument DISPLAY specifies which display to ask about.
3075 DISPLAY should be either a frame or a display name (a string).
3076 If omitted or nil, that stands for the selected frame's display. */)
3078 Lisp_Object display
;
3080 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3082 return make_number (dpyinfo
->height
);
3085 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3087 doc
: /* Returns the number of bitplanes of the display DISPLAY.
3088 The optional argument DISPLAY specifies which display to ask about.
3089 DISPLAY should be either a frame or a display name (a string).
3090 If omitted or nil, that stands for the selected frame's display. */)
3092 Lisp_Object display
;
3094 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3096 return make_number (dpyinfo
->n_planes
* dpyinfo
->n_cbits
);
3099 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3101 doc
: /* Returns the number of color cells of the display DISPLAY.
3102 The optional argument DISPLAY specifies which display to ask about.
3103 DISPLAY should be either a frame or a display name (a string).
3104 If omitted or nil, that stands for the selected frame's display. */)
3106 Lisp_Object display
;
3108 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3110 /* MAC_TODO: check whether this is right */
3111 return make_number ((unsigned long) (pow (2, dpyinfo
->n_cbits
)));
3114 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3115 Sx_server_max_request_size
,
3117 doc
: /* Returns the maximum request size of the server of display DISPLAY.
3118 The optional argument DISPLAY specifies which display to ask about.
3119 DISPLAY should be either a frame or a display name (a string).
3120 If omitted or nil, that stands for the selected frame's display. */)
3122 Lisp_Object display
;
3124 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3126 return make_number (1);
3129 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3130 doc
: /* Returns the vendor ID string of the Mac OS system (Apple).
3131 The optional argument DISPLAY specifies which display to ask about.
3132 DISPLAY should be either a frame or a display name (a string).
3133 If omitted or nil, that stands for the selected frame's display. */)
3135 Lisp_Object display
;
3137 return build_string ("Apple Computers");
3140 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3141 doc
: /* Returns the version numbers of the server of display DISPLAY.
3142 The value is a list of three integers: the major and minor
3143 version numbers, and the vendor-specific release
3144 number. See also the function `x-server-vendor'.
3146 The optional argument DISPLAY specifies which display to ask about.
3147 DISPLAY should be either a frame or a display name (a string).
3148 If omitted or nil, that stands for the selected frame's display. */)
3150 Lisp_Object display
;
3152 int mac_major_version
, mac_minor_version
;
3155 if (Gestalt (gestaltSystemVersion
, &response
) != noErr
)
3156 error ("Cannot get Mac OS version");
3158 mac_major_version
= (response
>> 8) & 0xf;
3159 mac_minor_version
= (response
>> 4) & 0xf;
3161 return Fcons (make_number (mac_major_version
),
3162 Fcons (make_number (mac_minor_version
), Qnil
));
3165 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3166 doc
: /* Return the number of screens on the server of display DISPLAY.
3167 The optional argument DISPLAY specifies which display to ask about.
3168 DISPLAY should be either a frame or a display name (a string).
3169 If omitted or nil, that stands for the selected frame's display. */)
3171 Lisp_Object display
;
3173 return make_number (1);
3176 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3177 doc
: /* Return the height in millimeters of the X display DISPLAY.
3178 The optional argument DISPLAY specifies which display to ask about.
3179 DISPLAY should be either a frame or a display name (a string).
3180 If omitted or nil, that stands for the selected frame's display. */)
3182 Lisp_Object display
;
3184 /* MAC_TODO: this is an approximation, and only of the main display */
3186 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3191 return make_number ((int) (v
/ 72.0 * 25.4));
3194 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3195 doc
: /* Return the width in millimeters of the X display DISPLAY.
3196 The optional argument DISPLAY specifies which display to ask about.
3197 DISPLAY should be either a frame or a display name (a string).
3198 If omitted or nil, that stands for the selected frame's display. */)
3200 Lisp_Object display
;
3202 /* MAC_TODO: this is an approximation, and only of the main display */
3204 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3209 return make_number ((int) (h
/ 72.0 * 25.4));
3212 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3213 Sx_display_backing_store
, 0, 1, 0,
3214 doc
: /* Returns an indication of whether display DISPLAY does backing store.
3215 The value may be `always', `when-mapped', or `not-useful'.
3216 The optional argument DISPLAY specifies which display to ask about.
3217 DISPLAY should be either a frame or a display name (a string).
3218 If omitted or nil, that stands for the selected frame's display. */)
3220 Lisp_Object display
;
3222 return intern ("not-useful");
3225 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3226 Sx_display_visual_class
, 0, 1, 0,
3227 doc
: /* Returns the visual class of the display DISPLAY.
3228 The value is one of the symbols `static-gray', `gray-scale',
3229 `static-color', `pseudo-color', `true-color', or `direct-color'.
3231 The optional argument DISPLAY specifies which display to ask about.
3232 DISPLAY should be either a frame or a display name (a string).
3233 If omitted or nil, that stands for the selected frame's display. */)
3235 Lisp_Object display
;
3237 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3240 switch (dpyinfo
->visual
->class)
3242 case StaticGray
: return (intern ("static-gray"));
3243 case GrayScale
: return (intern ("gray-scale"));
3244 case StaticColor
: return (intern ("static-color"));
3245 case PseudoColor
: return (intern ("pseudo-color"));
3246 case TrueColor
: return (intern ("true-color"));
3247 case DirectColor
: return (intern ("direct-color"));
3249 error ("Display has an unknown visual class");
3253 return (intern ("true-color"));
3256 DEFUN ("x-display-save-under", Fx_display_save_under
,
3257 Sx_display_save_under
, 0, 1, 0,
3258 doc
: /* Returns t if the display DISPLAY supports the save-under feature.
3259 The optional argument DISPLAY specifies which display to ask about.
3260 DISPLAY should be either a frame or a display name (a string).
3261 If omitted or nil, that stands for the selected frame's display. */)
3263 Lisp_Object display
;
3270 register struct frame
*f
;
3272 return FRAME_PIXEL_WIDTH (f
);
3277 register struct frame
*f
;
3279 return FRAME_PIXEL_HEIGHT (f
);
3284 register struct frame
*f
;
3286 return FRAME_COLUMN_WIDTH (f
);
3291 register struct frame
*f
;
3293 return FRAME_LINE_HEIGHT (f
);
3298 register struct frame
*f
;
3300 return FRAME_MAC_DISPLAY_INFO (f
)->n_planes
;
3303 /* Return the display structure for the display named NAME.
3304 Open a new connection if necessary. */
3306 struct mac_display_info
*
3307 x_display_info_for_name (name
)
3311 struct mac_display_info
*dpyinfo
;
3313 CHECK_STRING (name
);
3315 for (dpyinfo
= &one_mac_display_info
, names
= x_display_name_list
;
3317 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
3320 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
3325 /* Use this general default value to start with. */
3326 Vx_resource_name
= Vinvocation_name
;
3328 validate_x_resource_name ();
3330 dpyinfo
= mac_term_init (name
, (unsigned char *) 0,
3331 (char *) SDATA (Vx_resource_name
));
3334 error ("Cannot connect to server %s", SDATA (name
));
3337 XSETFASTINT (Vwindow_system_version
, 3);
3342 #if 0 /* MAC_TODO: implement network support */
3343 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
3345 doc
: /* Open a connection to a server.
3346 DISPLAY is the name of the display to connect to.
3347 Optional second arg XRM-STRING is a string of resources in xrdb format.
3348 If the optional third arg MUST-SUCCEED is non-nil,
3349 terminate Emacs if we can't open the connection. */)
3350 (display
, xrm_string
, must_succeed
)
3351 Lisp_Object display
, xrm_string
, must_succeed
;
3353 unsigned char *xrm_option
;
3354 struct mac_display_info
*dpyinfo
;
3356 CHECK_STRING (display
);
3357 if (! NILP (xrm_string
))
3358 CHECK_STRING (xrm_string
);
3360 if (! EQ (Vwindow_system
, intern ("mac")))
3361 error ("Not using Mac OS");
3363 if (! NILP (xrm_string
))
3364 xrm_option
= (unsigned char *) SDATA (xrm_string
);
3366 xrm_option
= (unsigned char *) 0;
3368 validate_x_resource_name ();
3370 /* This is what opens the connection and sets x_current_display.
3371 This also initializes many symbols, such as those used for input. */
3372 dpyinfo
= mac_term_init (display
, xrm_option
,
3373 (char *) SDATA (Vx_resource_name
));
3377 if (!NILP (must_succeed
))
3378 fatal ("Cannot connect to server %s.\n",
3381 error ("Cannot connect to server %s", SDATA (display
));
3386 XSETFASTINT (Vwindow_system_version
, 3);
3390 DEFUN ("x-close-connection", Fx_close_connection
,
3391 Sx_close_connection
, 1, 1, 0,
3392 doc
: /* Close the connection to DISPLAY's server.
3393 For DISPLAY, specify either a frame or a display name (a string).
3394 If DISPLAY is nil, that stands for the selected frame's display. */)
3396 Lisp_Object display
;
3398 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
3401 if (dpyinfo
->reference_count
> 0)
3402 error ("Display still has frames on it");
3405 /* Free the fonts in the font table. */
3406 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
3407 if (dpyinfo
->font_table
[i
].name
)
3409 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
3410 xfree (dpyinfo
->font_table
[i
].full_name
);
3411 xfree (dpyinfo
->font_table
[i
].name
);
3412 x_unload_font (dpyinfo
, dpyinfo
->font_table
[i
].font
);
3414 x_destroy_all_bitmaps (dpyinfo
);
3416 x_delete_display (dpyinfo
);
3423 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
3424 doc
: /* Return the list of display names that Emacs has connections to. */)
3427 Lisp_Object tail
, result
;
3430 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
3431 result
= Fcons (XCAR (XCAR (tail
)), result
);
3436 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
3437 doc
: /* If ON is non-nil, report errors as soon as the erring request is made.
3438 If ON is nil, allow buffering of requests.
3439 This is a noop on Mac OS systems.
3440 The optional second argument DISPLAY specifies which display to act on.
3441 DISPLAY should be either a frame or a display name (a string).
3442 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
3444 Lisp_Object display
, on
;
3450 /***********************************************************************
3452 ***********************************************************************/
3454 /* Value is the number of elements of vector VECTOR. */
3456 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
3458 /* List of supported image types. Use define_image_type to add new
3459 types. Use lookup_image_type to find a type for a given symbol. */
3461 static struct image_type
*image_types
;
3463 /* The symbol `xbm' which is used as the type symbol for XBM images. */
3469 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
3470 extern Lisp_Object QCdata
, QCtype
;
3471 Lisp_Object QCascent
, QCmargin
, QCrelief
;
3472 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
3473 Lisp_Object QCindex
;
3475 /* Other symbols. */
3477 Lisp_Object Qlaplace
;
3479 /* Time in seconds after which images should be removed from the cache
3480 if not displayed. */
3482 Lisp_Object Vimage_cache_eviction_delay
;
3484 /* Function prototypes. */
3486 static void define_image_type
P_ ((struct image_type
*type
));
3487 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
3488 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
3489 static void x_laplace
P_ ((struct frame
*, struct image
*));
3490 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
3494 /* Define a new image type from TYPE. This adds a copy of TYPE to
3495 image_types and adds the symbol *TYPE->type to Vimage_types. */
3498 define_image_type (type
)
3499 struct image_type
*type
;
3501 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
3502 The initialized data segment is read-only. */
3503 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
3504 bcopy (type
, p
, sizeof *p
);
3505 p
->next
= image_types
;
3507 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
3511 /* Look up image type SYMBOL, and return a pointer to its image_type
3512 structure. Value is null if SYMBOL is not a known image type. */
3514 static INLINE
struct image_type
*
3515 lookup_image_type (symbol
)
3518 struct image_type
*type
;
3520 for (type
= image_types
; type
; type
= type
->next
)
3521 if (EQ (symbol
, *type
->type
))
3528 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
3529 valid image specification is a list whose car is the symbol
3530 `image', and whose rest is a property list. The property list must
3531 contain a value for key `:type'. That value must be the name of a
3532 supported image type. The rest of the property list depends on the
3536 valid_image_p (object
)
3541 if (IMAGEP (object
))
3543 Lisp_Object symbol
= Fplist_get (XCDR (object
), QCtype
);
3544 struct image_type
*type
= lookup_image_type (symbol
);
3547 valid_p
= type
->valid_p (object
);
3554 /* Log error message with format string FORMAT and argument ARG.
3555 Signaling an error, e.g. when an image cannot be loaded, is not a
3556 good idea because this would interrupt redisplay, and the error
3557 message display would lead to another redisplay. This function
3558 therefore simply displays a message. */
3561 image_error (format
, arg1
, arg2
)
3563 Lisp_Object arg1
, arg2
;
3565 add_to_log (format
, arg1
, arg2
);
3570 /***********************************************************************
3571 Image specifications
3572 ***********************************************************************/
3574 enum image_value_type
3576 IMAGE_DONT_CHECK_VALUE_TYPE
,
3579 IMAGE_POSITIVE_INTEGER_VALUE
,
3580 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
3581 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
3583 IMAGE_INTEGER_VALUE
,
3584 IMAGE_FUNCTION_VALUE
,
3589 /* Structure used when parsing image specifications. */
3591 struct image_keyword
3593 /* Name of keyword. */
3596 /* The type of value allowed. */
3597 enum image_value_type type
;
3599 /* Non-zero means key must be present. */
3602 /* Used to recognize duplicate keywords in a property list. */
3605 /* The value that was found. */
3610 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
3612 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
3615 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
3616 has the format (image KEYWORD VALUE ...). One of the keyword/
3617 value pairs must be `:type TYPE'. KEYWORDS is a vector of
3618 image_keywords structures of size NKEYWORDS describing other
3619 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
3622 parse_image_spec (spec
, keywords
, nkeywords
, type
)
3624 struct image_keyword
*keywords
;
3634 plist
= XCDR (spec
);
3635 while (CONSP (plist
))
3637 Lisp_Object key
, value
;
3639 /* First element of a pair must be a symbol. */
3641 plist
= XCDR (plist
);
3645 /* There must follow a value. */
3648 value
= XCAR (plist
);
3649 plist
= XCDR (plist
);
3651 /* Find key in KEYWORDS. Error if not found. */
3652 for (i
= 0; i
< nkeywords
; ++i
)
3653 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
3659 /* Record that we recognized the keyword. If a keywords
3660 was found more than once, it's an error. */
3661 keywords
[i
].value
= value
;
3662 ++keywords
[i
].count
;
3664 if (keywords
[i
].count
> 1)
3667 /* Check type of value against allowed type. */
3668 switch (keywords
[i
].type
)
3670 case IMAGE_STRING_VALUE
:
3671 if (!STRINGP (value
))
3675 case IMAGE_SYMBOL_VALUE
:
3676 if (!SYMBOLP (value
))
3680 case IMAGE_POSITIVE_INTEGER_VALUE
:
3681 if (!INTEGERP (value
) || XINT (value
) <= 0)
3685 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
3686 if (INTEGERP (value
) && XINT (value
) >= 0)
3689 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
3690 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
3694 case IMAGE_ASCENT_VALUE
:
3695 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
3697 else if (INTEGERP (value
)
3698 && XINT (value
) >= 0
3699 && XINT (value
) <= 100)
3703 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
3704 if (!INTEGERP (value
) || XINT (value
) < 0)
3708 case IMAGE_DONT_CHECK_VALUE_TYPE
:
3711 case IMAGE_FUNCTION_VALUE
:
3712 value
= indirect_function (value
);
3714 || COMPILEDP (value
)
3715 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
3719 case IMAGE_NUMBER_VALUE
:
3720 if (!INTEGERP (value
) && !FLOATP (value
))
3724 case IMAGE_INTEGER_VALUE
:
3725 if (!INTEGERP (value
))
3729 case IMAGE_BOOL_VALUE
:
3730 if (!NILP (value
) && !EQ (value
, Qt
))
3739 if (EQ (key
, QCtype
) && !EQ (type
, value
))
3743 /* Check that all mandatory fields are present. */
3744 for (i
= 0; i
< nkeywords
; ++i
)
3745 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
3748 return NILP (plist
);
3752 /* Return the value of KEY in image specification SPEC. Value is nil
3753 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
3754 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
3757 image_spec_value (spec
, key
, found
)
3758 Lisp_Object spec
, key
;
3763 xassert (valid_image_p (spec
));
3765 for (tail
= XCDR (spec
);
3766 CONSP (tail
) && CONSP (XCDR (tail
));
3767 tail
= XCDR (XCDR (tail
)))
3769 if (EQ (XCAR (tail
), key
))
3773 return XCAR (XCDR (tail
));
3785 /***********************************************************************
3786 Image type independent image structures
3787 ***********************************************************************/
3789 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
3790 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
3793 /* Allocate and return a new image structure for image specification
3794 SPEC. SPEC has a hash value of HASH. */
3796 static struct image
*
3797 make_image (spec
, hash
)
3801 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
3803 xassert (valid_image_p (spec
));
3804 bzero (img
, sizeof *img
);
3805 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
3806 xassert (img
->type
!= NULL
);
3808 img
->data
.lisp_val
= Qnil
;
3809 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
3815 /* Free image IMG which was used on frame F, including its resources. */
3824 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
3826 /* Remove IMG from the hash table of its cache. */
3828 img
->prev
->next
= img
->next
;
3830 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
3833 img
->next
->prev
= img
->prev
;
3835 c
->images
[img
->id
] = NULL
;
3837 /* Free resources, then free IMG. */
3838 img
->type
->free (f
, img
);
3844 /* Prepare image IMG for display on frame F. Must be called before
3845 drawing an image. */
3848 prepare_image_for_display (f
, img
)
3854 /* We're about to display IMG, so set its timestamp to `now'. */
3856 img
->timestamp
= EMACS_SECS (t
);
3858 /* If IMG doesn't have a pixmap yet, load it now, using the image
3859 type dependent loader function. */
3860 if (img
->pixmap
== 0 && !img
->load_failed_p
)
3861 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
3865 /* Value is the number of pixels for the ascent of image IMG when
3866 drawn in face FACE. */
3869 image_ascent (img
, face
)
3873 int height
= img
->height
+ img
->vmargin
;
3876 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
3879 ascent
= height
/ 2 - (FONT_DESCENT(face
->font
)
3880 - FONT_BASE(face
->font
)) / 2;
3882 ascent
= height
/ 2;
3885 ascent
= height
* img
->ascent
/ 100.0;
3892 /***********************************************************************
3893 Helper functions for X image types
3894 ***********************************************************************/
3896 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
3897 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
3899 Lisp_Object color_name
,
3900 unsigned long dflt
));
3902 /* Free X resources of image IMG which is used on frame F. */
3905 x_clear_image (f
, img
)
3909 #if 0 /* MAC_TODO: W32 image support */
3914 XFreePixmap (NULL
, img
->pixmap
);
3921 int class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
3923 /* If display has an immutable color map, freeing colors is not
3924 necessary and some servers don't allow it. So don't do it. */
3925 if (class != StaticColor
3926 && class != StaticGray
3927 && class != TrueColor
)
3931 cmap
= DefaultColormapOfScreen (FRAME_W32_DISPLAY_INFO (f
)->screen
);
3932 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
, img
->colors
,
3937 xfree (img
->colors
);
3941 #endif /* MAC_TODO */
3945 /* Allocate color COLOR_NAME for image IMG on frame F. If color
3946 cannot be allocated, use DFLT. Add a newly allocated color to
3947 IMG->colors, so that it can be freed again. Value is the pixel
3950 static unsigned long
3951 x_alloc_image_color (f
, img
, color_name
, dflt
)
3954 Lisp_Object color_name
;
3957 #if 0 /* MAC_TODO: allocing colors. */
3959 unsigned long result
;
3961 xassert (STRINGP (color_name
));
3963 if (w32_defined_color (f
, SDATA (color_name
), &color
, 1))
3965 /* This isn't called frequently so we get away with simply
3966 reallocating the color vector to the needed size, here. */
3969 (unsigned long *) xrealloc (img
->colors
,
3970 img
->ncolors
* sizeof *img
->colors
);
3971 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
3972 result
= color
.pixel
;
3977 #endif /* MAC_TODO */
3983 /***********************************************************************
3985 ***********************************************************************/
3987 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
3990 /* Return a new, initialized image cache that is allocated from the
3991 heap. Call free_image_cache to free an image cache. */
3993 struct image_cache
*
3996 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
3999 bzero (c
, sizeof *c
);
4001 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
4002 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
4003 c
->buckets
= (struct image
**) xmalloc (size
);
4004 bzero (c
->buckets
, size
);
4009 /* Free image cache of frame F. Be aware that X frames share images
4013 free_image_cache (f
)
4016 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4021 /* Cache should not be referenced by any frame when freed. */
4022 xassert (c
->refcount
== 0);
4024 for (i
= 0; i
< c
->used
; ++i
)
4025 free_image (f
, c
->images
[i
]);
4029 FRAME_X_IMAGE_CACHE (f
) = NULL
;
4034 /* Clear image cache of frame F. FORCE_P non-zero means free all
4035 images. FORCE_P zero means clear only images that haven't been
4036 displayed for some time. Should be called from time to time to
4037 reduce the number of loaded images. If image-eviction-seconds is
4038 non-nil, this frees images in the cache which weren't displayed for
4039 at least that many seconds. */
4042 clear_image_cache (f
, force_p
)
4046 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4048 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
4052 int i
, any_freed_p
= 0;
4055 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
4057 for (i
= 0; i
< c
->used
; ++i
)
4059 struct image
*img
= c
->images
[i
];
4062 || (img
->timestamp
> old
)))
4064 free_image (f
, img
);
4069 /* We may be clearing the image cache because, for example,
4070 Emacs was iconified for a longer period of time. In that
4071 case, current matrices may still contain references to
4072 images freed above. So, clear these matrices. */
4075 clear_current_matrices (f
);
4076 ++windows_or_buffers_changed
;
4082 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
4084 doc
: /* Clear the image cache of FRAME.
4085 FRAME nil or omitted means use the selected frame.
4086 FRAME t means clear the image caches of all frames. */)
4094 FOR_EACH_FRAME (tail
, frame
)
4095 if (FRAME_MAC_P (XFRAME (frame
)))
4096 clear_image_cache (XFRAME (frame
), 1);
4099 clear_image_cache (check_x_frame (frame
), 1);
4105 /* Return the id of image with Lisp specification SPEC on frame F.
4106 SPEC must be a valid Lisp image specification (see valid_image_p). */
4109 lookup_image (f
, spec
)
4113 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4117 struct gcpro gcpro1
;
4120 /* F must be a window-system frame, and SPEC must be a valid image
4122 xassert (FRAME_WINDOW_P (f
));
4123 xassert (valid_image_p (spec
));
4127 /* Look up SPEC in the hash table of the image cache. */
4128 hash
= sxhash (spec
, 0);
4129 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
4131 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
4132 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
4135 /* If not found, create a new image and cache it. */
4139 img
= make_image (spec
, hash
);
4140 cache_image (f
, img
);
4141 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
4142 xassert (!interrupt_input_blocked
);
4144 /* If we can't load the image, and we don't have a width and
4145 height, use some arbitrary width and height so that we can
4146 draw a rectangle for it. */
4147 if (img
->load_failed_p
)
4151 value
= image_spec_value (spec
, QCwidth
, NULL
);
4152 img
->width
= (INTEGERP (value
)
4153 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
4154 value
= image_spec_value (spec
, QCheight
, NULL
);
4155 img
->height
= (INTEGERP (value
)
4156 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
4160 /* Handle image type independent image attributes
4161 `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF'. */
4162 Lisp_Object ascent
, margin
, relief
;
4164 ascent
= image_spec_value (spec
, QCascent
, NULL
);
4165 if (INTEGERP (ascent
))
4166 img
->ascent
= XFASTINT (ascent
);
4167 else if (EQ (ascent
, Qcenter
))
4168 img
->ascent
= CENTERED_IMAGE_ASCENT
;
4170 margin
= image_spec_value (spec
, QCmargin
, NULL
);
4171 if (INTEGERP (margin
) && XINT (margin
) >= 0)
4172 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
4173 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
4174 && INTEGERP (XCDR (margin
)))
4176 if (XINT (XCAR (margin
)) > 0)
4177 img
->hmargin
= XFASTINT (XCAR (margin
));
4178 if (XINT (XCDR (margin
)) > 0)
4179 img
->vmargin
= XFASTINT (XCDR (margin
));
4182 relief
= image_spec_value (spec
, QCrelief
, NULL
);
4183 if (INTEGERP (relief
))
4185 img
->relief
= XINT (relief
);
4186 img
->hmargin
+= abs (img
->relief
);
4187 img
->vmargin
+= abs (img
->relief
);
4192 /* We're using IMG, so set its timestamp to `now'. */
4193 EMACS_GET_TIME (now
);
4194 img
->timestamp
= EMACS_SECS (now
);
4198 /* Value is the image id. */
4203 /* Cache image IMG in the image cache of frame F. */
4206 cache_image (f
, img
)
4210 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4213 /* Find a free slot in c->images. */
4214 for (i
= 0; i
< c
->used
; ++i
)
4215 if (c
->images
[i
] == NULL
)
4218 /* If no free slot found, maybe enlarge c->images. */
4219 if (i
== c
->used
&& c
->used
== c
->size
)
4222 c
->images
= (struct image
**) xrealloc (c
->images
,
4223 c
->size
* sizeof *c
->images
);
4226 /* Add IMG to c->images, and assign IMG an id. */
4232 /* Add IMG to the cache's hash table. */
4233 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
4234 img
->next
= c
->buckets
[i
];
4236 img
->next
->prev
= img
;
4238 c
->buckets
[i
] = img
;
4242 /* Call FN on every image in the image cache of frame F. Used to mark
4243 Lisp Objects in the image cache. */
4246 forall_images_in_image_cache (f
, fn
)
4248 void (*fn
) P_ ((struct image
*img
));
4250 if (FRAME_LIVE_P (f
) && FRAME_MAC_P (f
))
4252 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4256 for (i
= 0; i
< c
->used
; ++i
)
4265 /***********************************************************************
4267 ***********************************************************************/
4269 #if 0 /* MAC_TODO: Mac specific image code. */
4271 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
4272 XImage
**, Pixmap
*));
4273 static void x_destroy_x_image
P_ ((XImage
*));
4274 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
4277 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
4278 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
4279 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
4280 via xmalloc. Print error messages via image_error if an error
4281 occurs. Value is non-zero if successful. */
4284 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
4286 int width
, height
, depth
;
4290 #if 0 /* MAC_TODO: Image support for Mac */
4291 Display
*display
= FRAME_W32_DISPLAY (f
);
4292 Screen
*screen
= FRAME_X_SCREEN (f
);
4293 Window window
= FRAME_W32_WINDOW (f
);
4295 xassert (interrupt_input_blocked
);
4298 depth
= DefaultDepthOfScreen (screen
);
4299 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
4300 depth
, ZPixmap
, 0, NULL
, width
, height
,
4301 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
4304 image_error ("Unable to allocate X image", Qnil
, Qnil
);
4308 /* Allocate image raster. */
4309 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
4311 /* Allocate a pixmap of the same size. */
4312 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
4315 x_destroy_x_image (*ximg
);
4317 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
4320 #endif /* MAC_TODO */
4325 /* Destroy XImage XIMG. Free XIMG->data. */
4328 x_destroy_x_image (ximg
)
4331 xassert (interrupt_input_blocked
);
4336 XDestroyImage (ximg
);
4341 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
4342 are width and height of both the image and pixmap. */
4345 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
4352 xassert (interrupt_input_blocked
);
4353 gc
= XCreateGC (NULL
, pixmap
, 0, NULL
);
4354 XPutImage (NULL
, pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
4358 #endif /* MAC_TODO */
4361 /***********************************************************************
4363 ***********************************************************************/
4365 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
4367 /* Find image file FILE. Look in data-directory, then
4368 x-bitmap-file-path. Value is the full name of the file found, or
4369 nil if not found. */
4372 x_find_image_file (file
)
4375 Lisp_Object file_found
, search_path
;
4376 struct gcpro gcpro1
, gcpro2
;
4380 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
4381 GCPRO2 (file_found
, search_path
);
4383 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
4384 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
4396 /***********************************************************************
4398 ***********************************************************************/
4400 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
4401 static int xbm_load_image_from_file
P_ ((struct frame
*f
, struct image
*img
,
4403 static int xbm_image_p
P_ ((Lisp_Object object
));
4404 static int xbm_read_bitmap_file_data
P_ ((char *, int *, int *,
4408 /* Indices of image specification fields in xbm_format, below. */
4410 enum xbm_keyword_index
4427 /* Vector of image_keyword structures describing the format
4428 of valid XBM image specifications. */
4430 static struct image_keyword xbm_format
[XBM_LAST
] =
4432 {":type", IMAGE_SYMBOL_VALUE
, 1},
4433 {":file", IMAGE_STRING_VALUE
, 0},
4434 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
4435 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
4436 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4437 {":foreground", IMAGE_STRING_VALUE
, 0},
4438 {":background", IMAGE_STRING_VALUE
, 0},
4439 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
4440 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
4441 {":relief", IMAGE_INTEGER_VALUE
, 0},
4442 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4443 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
4446 /* Structure describing the image type XBM. */
4448 static struct image_type xbm_type
=
4457 /* Tokens returned from xbm_scan. */
4466 /* Return non-zero if OBJECT is a valid XBM-type image specification.
4467 A valid specification is a list starting with the symbol `image'
4468 The rest of the list is a property list which must contain an
4471 If the specification specifies a file to load, it must contain
4472 an entry `:file FILENAME' where FILENAME is a string.
4474 If the specification is for a bitmap loaded from memory it must
4475 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
4476 WIDTH and HEIGHT are integers > 0. DATA may be:
4478 1. a string large enough to hold the bitmap data, i.e. it must
4479 have a size >= (WIDTH + 7) / 8 * HEIGHT
4481 2. a bool-vector of size >= WIDTH * HEIGHT
4483 3. a vector of strings or bool-vectors, one for each line of the
4486 Both the file and data forms may contain the additional entries
4487 `:background COLOR' and `:foreground COLOR'. If not present,
4488 foreground and background of the frame on which the image is
4489 displayed, is used. */
4492 xbm_image_p (object
)
4495 struct image_keyword kw
[XBM_LAST
];
4497 bcopy (xbm_format
, kw
, sizeof kw
);
4498 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
4501 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
4503 if (kw
[XBM_FILE
].count
)
4505 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
4513 /* Entries for `:width', `:height' and `:data' must be present. */
4514 if (!kw
[XBM_WIDTH
].count
4515 || !kw
[XBM_HEIGHT
].count
4516 || !kw
[XBM_DATA
].count
)
4519 data
= kw
[XBM_DATA
].value
;
4520 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
4521 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
4523 /* Check type of data, and width and height against contents of
4529 /* Number of elements of the vector must be >= height. */
4530 if (XVECTOR (data
)->size
< height
)
4533 /* Each string or bool-vector in data must be large enough
4534 for one line of the image. */
4535 for (i
= 0; i
< height
; ++i
)
4537 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
4542 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
4545 else if (BOOL_VECTOR_P (elt
))
4547 if (XBOOL_VECTOR (elt
)->size
< width
)
4554 else if (STRINGP (data
))
4557 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
4560 else if (BOOL_VECTOR_P (data
))
4562 if (XBOOL_VECTOR (data
)->size
< width
* height
)
4569 /* Baseline must be a value between 0 and 100 (a percentage). */
4570 if (kw
[XBM_ASCENT
].count
4571 && XFASTINT (kw
[XBM_ASCENT
].value
) > 100)
4578 /* Scan a bitmap file. FP is the stream to read from. Value is
4579 either an enumerator from enum xbm_token, or a character for a
4580 single-character token, or 0 at end of file. If scanning an
4581 identifier, store the lexeme of the identifier in SVAL. If
4582 scanning a number, store its value in *IVAL. */
4585 xbm_scan (fp
, sval
, ival
)
4592 /* Skip white space. */
4593 while ((c
= fgetc (fp
)) != EOF
&& isspace (c
))
4598 else if (isdigit (c
))
4600 int value
= 0, digit
;
4605 if (c
== 'x' || c
== 'X')
4607 while ((c
= fgetc (fp
)) != EOF
)
4611 else if (c
>= 'a' && c
<= 'f')
4612 digit
= c
- 'a' + 10;
4613 else if (c
>= 'A' && c
<= 'F')
4614 digit
= c
- 'A' + 10;
4617 value
= 16 * value
+ digit
;
4620 else if (isdigit (c
))
4623 while ((c
= fgetc (fp
)) != EOF
4625 value
= 8 * value
+ c
- '0';
4631 while ((c
= fgetc (fp
)) != EOF
4633 value
= 10 * value
+ c
- '0';
4641 else if (isalpha (c
) || c
== '_')
4644 while ((c
= fgetc (fp
)) != EOF
4645 && (isalnum (c
) || c
== '_'))
4657 /* Replacement for XReadBitmapFileData which isn't available under old
4658 X versions. FILE is the name of the bitmap file to read. Set
4659 *WIDTH and *HEIGHT to the width and height of the image. Return in
4660 *DATA the bitmap data allocated with xmalloc. Value is non-zero if
4664 xbm_read_bitmap_file_data (file
, width
, height
, data
)
4666 int *width
, *height
;
4667 unsigned char **data
;
4670 char buffer
[BUFSIZ
];
4673 int bytes_per_line
, i
, nbytes
;
4679 LA1 = xbm_scan (fp, buffer, &value)
4681 #define expect(TOKEN) \
4682 if (LA1 != (TOKEN)) \
4687 #define expect_ident(IDENT) \
4688 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
4693 fp
= fopen (file
, "r");
4697 *width
= *height
= -1;
4699 LA1
= xbm_scan (fp
, buffer
, &value
);
4701 /* Parse defines for width, height and hot-spots. */
4705 expect_ident ("define");
4706 expect (XBM_TK_IDENT
);
4708 if (LA1
== XBM_TK_NUMBER
);
4710 char *p
= strrchr (buffer
, '_');
4711 p
= p
? p
+ 1 : buffer
;
4712 if (strcmp (p
, "width") == 0)
4714 else if (strcmp (p
, "height") == 0)
4717 expect (XBM_TK_NUMBER
);
4720 if (*width
< 0 || *height
< 0)
4723 /* Parse bits. Must start with `static'. */
4724 expect_ident ("static");
4725 if (LA1
== XBM_TK_IDENT
)
4727 if (strcmp (buffer
, "unsigned") == 0)
4730 expect_ident ("char");
4732 else if (strcmp (buffer
, "short") == 0)
4736 if (*width
% 16 && *width
% 16 < 9)
4739 else if (strcmp (buffer
, "char") == 0)
4747 expect (XBM_TK_IDENT
);
4753 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
4754 nbytes
= bytes_per_line
* *height
;
4755 p
= *data
= (char *) xmalloc (nbytes
);
4760 for (i
= 0; i
< nbytes
; i
+= 2)
4763 expect (XBM_TK_NUMBER
);
4766 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
4769 if (LA1
== ',' || LA1
== '}')
4777 for (i
= 0; i
< nbytes
; ++i
)
4780 expect (XBM_TK_NUMBER
);
4784 if (LA1
== ',' || LA1
== '}')
4810 /* Load XBM image IMG which will be displayed on frame F from file
4811 SPECIFIED_FILE. Value is non-zero if successful. */
4814 xbm_load_image_from_file (f
, img
, specified_file
)
4817 Lisp_Object specified_file
;
4820 unsigned char *data
;
4823 struct gcpro gcpro1
;
4825 xassert (STRINGP (specified_file
));
4829 file
= x_find_image_file (specified_file
);
4830 if (!STRINGP (file
))
4832 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
4837 rc
= xbm_read_bitmap_file_data (SDATA (file
), &img
->width
,
4838 &img
->height
, &data
);
4841 int depth
= one_mac_display_info
.n_cbits
;
4842 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
4843 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
4846 xassert (img
->width
> 0 && img
->height
> 0);
4848 /* Get foreground and background colors, maybe allocate colors. */
4849 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
4851 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
4853 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
4855 background
= x_alloc_image_color (f
, img
, value
, background
);
4857 #if 0 /* MAC_TODO : Port image display to Mac */
4860 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
4861 FRAME_W32_WINDOW (f
),
4863 img
->width
, img
->height
,
4864 foreground
, background
,
4868 if (img
->pixmap
== 0)
4870 x_clear_image (f
, img
);
4871 image_error ("Unable to create X pixmap for `%s'", file
, Qnil
);
4877 #endif /* MAC_TODO */
4880 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
4887 /* Fill image IMG which is used on frame F with pixmap data. Value is
4888 non-zero if successful. */
4896 Lisp_Object file_name
;
4898 xassert (xbm_image_p (img
->spec
));
4900 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4901 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4902 if (STRINGP (file_name
))
4903 success_p
= xbm_load_image_from_file (f
, img
, file_name
);
4906 struct image_keyword fmt
[XBM_LAST
];
4909 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
4910 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
4914 /* Parse the list specification. */
4915 bcopy (xbm_format
, fmt
, sizeof fmt
);
4916 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
4919 /* Get specified width, and height. */
4920 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
4921 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
4922 xassert (img
->width
> 0 && img
->height
> 0);
4926 if (fmt
[XBM_ASCENT
].count
)
4927 img
->ascent
= XFASTINT (fmt
[XBM_ASCENT
].value
);
4929 /* Get foreground and background colors, maybe allocate colors. */
4930 if (fmt
[XBM_FOREGROUND
].count
)
4931 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
4933 if (fmt
[XBM_BACKGROUND
].count
)
4934 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
4937 /* Set bits to the bitmap image data. */
4938 data
= fmt
[XBM_DATA
].value
;
4943 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
4945 p
= bits
= (char *) alloca (nbytes
* img
->height
);
4946 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
4948 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
4950 bcopy (SDATA (line
), p
, nbytes
);
4952 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
4955 else if (STRINGP (data
))
4956 bits
= SDATA (data
);
4958 bits
= XBOOL_VECTOR (data
)->data
;
4960 #if 0 /* MAC_TODO : port Mac display code */
4961 /* Create the pixmap. */
4962 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
4964 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
4965 FRAME_W32_WINDOW (f
),
4967 img
->width
, img
->height
,
4968 foreground
, background
,
4970 #endif /* MAC_TODO */
4976 image_error ("Unable to create pixmap for XBM image `%s'",
4978 x_clear_image (f
, img
);
4989 /***********************************************************************
4991 ***********************************************************************/
4995 static int xpm_image_p
P_ ((Lisp_Object object
));
4996 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
4997 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
4999 #include "X11/xpm.h"
5001 /* The symbol `xpm' identifying XPM-format images. */
5005 /* Indices of image specification fields in xpm_format, below. */
5007 enum xpm_keyword_index
5021 /* Vector of image_keyword structures describing the format
5022 of valid XPM image specifications. */
5024 static struct image_keyword xpm_format
[XPM_LAST
] =
5026 {":type", IMAGE_SYMBOL_VALUE
, 1},
5027 {":file", IMAGE_STRING_VALUE
, 0},
5028 {":data", IMAGE_STRING_VALUE
, 0},
5029 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
5030 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5031 {":relief", IMAGE_INTEGER_VALUE
, 0},
5032 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5033 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5034 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5037 /* Structure describing the image type XBM. */
5039 static struct image_type xpm_type
=
5049 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
5050 for XPM images. Such a list must consist of conses whose car and
5054 xpm_valid_color_symbols_p (color_symbols
)
5055 Lisp_Object color_symbols
;
5057 while (CONSP (color_symbols
))
5059 Lisp_Object sym
= XCAR (color_symbols
);
5061 || !STRINGP (XCAR (sym
))
5062 || !STRINGP (XCDR (sym
)))
5064 color_symbols
= XCDR (color_symbols
);
5067 return NILP (color_symbols
);
5071 /* Value is non-zero if OBJECT is a valid XPM image specification. */
5074 xpm_image_p (object
)
5077 struct image_keyword fmt
[XPM_LAST
];
5078 bcopy (xpm_format
, fmt
, sizeof fmt
);
5079 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
5080 /* Either `:file' or `:data' must be present. */
5081 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
5082 /* Either no `:color-symbols' or it's a list of conses
5083 whose car and cdr are strings. */
5084 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
5085 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
))
5086 && (fmt
[XPM_ASCENT
].count
== 0
5087 || XFASTINT (fmt
[XPM_ASCENT
].value
) < 100));
5091 /* Load image IMG which will be displayed on frame F. Value is
5092 non-zero if successful. */
5100 XpmAttributes attrs
;
5101 Lisp_Object specified_file
, color_symbols
;
5103 /* Configure the XPM lib. Use the visual of frame F. Allocate
5104 close colors. Return colors allocated. */
5105 bzero (&attrs
, sizeof attrs
);
5106 attrs
.visual
= FRAME_X_VISUAL (f
);
5107 attrs
.colormap
= FRAME_X_COLORMAP (f
);
5108 attrs
.valuemask
|= XpmVisual
;
5109 attrs
.valuemask
|= XpmColormap
;
5110 attrs
.valuemask
|= XpmReturnAllocPixels
;
5111 #ifdef XpmAllocCloseColors
5112 attrs
.alloc_close_colors
= 1;
5113 attrs
.valuemask
|= XpmAllocCloseColors
;
5115 attrs
.closeness
= 600;
5116 attrs
.valuemask
|= XpmCloseness
;
5119 /* If image specification contains symbolic color definitions, add
5120 these to `attrs'. */
5121 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
5122 if (CONSP (color_symbols
))
5125 XpmColorSymbol
*xpm_syms
;
5128 attrs
.valuemask
|= XpmColorSymbols
;
5130 /* Count number of symbols. */
5131 attrs
.numsymbols
= 0;
5132 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
5135 /* Allocate an XpmColorSymbol array. */
5136 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
5137 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
5138 bzero (xpm_syms
, size
);
5139 attrs
.colorsymbols
= xpm_syms
;
5141 /* Fill the color symbol array. */
5142 for (tail
= color_symbols
, i
= 0;
5144 ++i
, tail
= XCDR (tail
))
5146 Lisp_Object name
= XCAR (XCAR (tail
));
5147 Lisp_Object color
= XCDR (XCAR (tail
));
5148 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
5149 strcpy (xpm_syms
[i
].name
, SDATA (name
));
5150 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
5151 strcpy (xpm_syms
[i
].value
, SDATA (color
));
5155 /* Create a pixmap for the image, either from a file, or from a
5156 string buffer containing data in the same format as an XPM file. */
5158 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5159 if (STRINGP (specified_file
))
5161 Lisp_Object file
= x_find_image_file (specified_file
);
5162 if (!STRINGP (file
))
5164 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5169 rc
= XpmReadFileToPixmap (NULL
, FRAME_W32_WINDOW (f
),
5170 SDATA (file
), &img
->pixmap
, &img
->mask
,
5175 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
5176 rc
= XpmCreatePixmapFromBuffer (NULL
, FRAME_W32_WINDOW (f
),
5178 &img
->pixmap
, &img
->mask
,
5183 if (rc
== XpmSuccess
)
5185 /* Remember allocated colors. */
5186 img
->ncolors
= attrs
.nalloc_pixels
;
5187 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
5188 * sizeof *img
->colors
);
5189 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
5190 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
5192 img
->width
= attrs
.width
;
5193 img
->height
= attrs
.height
;
5194 xassert (img
->width
> 0 && img
->height
> 0);
5196 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
5198 XpmFreeAttributes (&attrs
);
5206 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
5209 case XpmFileInvalid
:
5210 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
5214 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
5217 case XpmColorFailed
:
5218 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
5222 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
5227 return rc
== XpmSuccess
;
5230 #endif /* HAVE_XPM != 0 */
5233 #if 0 /* MAC_TODO : Color tables on Mac. */
5234 /***********************************************************************
5236 ***********************************************************************/
5238 /* An entry in the color table mapping an RGB color to a pixel color. */
5243 unsigned long pixel
;
5245 /* Next in color table collision list. */
5246 struct ct_color
*next
;
5249 /* The bucket vector size to use. Must be prime. */
5253 /* Value is a hash of the RGB color given by R, G, and B. */
5255 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
5257 /* The color hash table. */
5259 struct ct_color
**ct_table
;
5261 /* Number of entries in the color table. */
5263 int ct_colors_allocated
;
5265 /* Function prototypes. */
5267 static void init_color_table
P_ ((void));
5268 static void free_color_table
P_ ((void));
5269 static unsigned long *colors_in_color_table
P_ ((int *n
));
5270 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
5271 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
5274 /* Initialize the color table. */
5279 int size
= CT_SIZE
* sizeof (*ct_table
);
5280 ct_table
= (struct ct_color
**) xmalloc (size
);
5281 bzero (ct_table
, size
);
5282 ct_colors_allocated
= 0;
5286 /* Free memory associated with the color table. */
5292 struct ct_color
*p
, *next
;
5294 for (i
= 0; i
< CT_SIZE
; ++i
)
5295 for (p
= ct_table
[i
]; p
; p
= next
)
5306 /* Value is a pixel color for RGB color R, G, B on frame F. If an
5307 entry for that color already is in the color table, return the
5308 pixel color of that entry. Otherwise, allocate a new color for R,
5309 G, B, and make an entry in the color table. */
5311 static unsigned long
5312 lookup_rgb_color (f
, r
, g
, b
)
5316 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
5317 int i
= hash
% CT_SIZE
;
5320 for (p
= ct_table
[i
]; p
; p
= p
->next
)
5321 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
5330 color
= RGB_TO_ULONG (r
, g
, b
);
5332 ++ct_colors_allocated
;
5334 p
= (struct ct_color
*) xmalloc (sizeof *p
);
5339 p
->next
= ct_table
[i
];
5347 /* Look up pixel color PIXEL which is used on frame F in the color
5348 table. If not already present, allocate it. Value is PIXEL. */
5350 static unsigned long
5351 lookup_pixel_color (f
, pixel
)
5353 unsigned long pixel
;
5355 int i
= pixel
% CT_SIZE
;
5358 for (p
= ct_table
[i
]; p
; p
= p
->next
)
5359 if (p
->pixel
== pixel
)
5370 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
5371 color
.pixel
= pixel
;
5372 XQueryColor (NULL
, cmap
, &color
);
5373 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
5378 ++ct_colors_allocated
;
5380 p
= (struct ct_color
*) xmalloc (sizeof *p
);
5385 p
->next
= ct_table
[i
];
5389 return FRAME_FOREGROUND_PIXEL (f
);
5395 /* Value is a vector of all pixel colors contained in the color table,
5396 allocated via xmalloc. Set *N to the number of colors. */
5398 static unsigned long *
5399 colors_in_color_table (n
)
5404 unsigned long *colors
;
5406 if (ct_colors_allocated
== 0)
5413 colors
= (unsigned long *) xmalloc (ct_colors_allocated
5415 *n
= ct_colors_allocated
;
5417 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
5418 for (p
= ct_table
[i
]; p
; p
= p
->next
)
5419 colors
[j
++] = p
->pixel
;
5425 #endif /* MAC_TODO */
5428 /***********************************************************************
5430 ***********************************************************************/
5432 #if 0 /* MAC_TODO : Mac versions of low level algorithms */
5433 static void x_laplace_write_row
P_ ((struct frame
*, long *,
5434 int, XImage
*, int));
5435 static void x_laplace_read_row
P_ ((struct frame
*, Colormap
,
5436 XColor
*, int, XImage
*, int));
5439 /* Fill COLORS with RGB colors from row Y of image XIMG. F is the
5440 frame we operate on, CMAP is the color-map in effect, and WIDTH is
5441 the width of one row in the image. */
5444 x_laplace_read_row (f
, cmap
, colors
, width
, ximg
, y
)
5454 for (x
= 0; x
< width
; ++x
)
5455 colors
[x
].pixel
= XGetPixel (ximg
, x
, y
);
5457 XQueryColors (NULL
, cmap
, colors
, width
);
5461 /* Write row Y of image XIMG. PIXELS is an array of WIDTH longs
5462 containing the pixel colors to write. F is the frame we are
5466 x_laplace_write_row (f
, pixels
, width
, ximg
, y
)
5475 for (x
= 0; x
< width
; ++x
)
5476 XPutPixel (ximg
, x
, y
, pixels
[x
]);
5478 #endif /* MAC_TODO */
5480 /* Transform image IMG which is used on frame F with a Laplace
5481 edge-detection algorithm. The result is an image that can be used
5482 to draw disabled buttons, for example. */
5489 #if 0 /* MAC_TODO : Mac version */
5490 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
5491 XImage
*ximg
, *oimg
;
5497 int in_y
, out_y
, rc
;
5502 /* Get the X image IMG->pixmap. */
5503 ximg
= XGetImage (NULL
, img
->pixmap
,
5504 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
5506 /* Allocate 3 input rows, and one output row of colors. */
5507 for (i
= 0; i
< 3; ++i
)
5508 in
[i
] = (XColor
*) alloca (img
->width
* sizeof (XColor
));
5509 out
= (long *) alloca (img
->width
* sizeof (long));
5511 /* Create an X image for output. */
5512 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
5515 /* Fill first two rows. */
5516 x_laplace_read_row (f
, cmap
, in
[0], img
->width
, ximg
, 0);
5517 x_laplace_read_row (f
, cmap
, in
[1], img
->width
, ximg
, 1);
5520 /* Write first row, all zeros. */
5521 init_color_table ();
5522 pixel
= lookup_rgb_color (f
, 0, 0, 0);
5523 for (x
= 0; x
< img
->width
; ++x
)
5525 x_laplace_write_row (f
, out
, img
->width
, oimg
, 0);
5528 for (y
= 2; y
< img
->height
; ++y
)
5531 int rowb
= (y
+ 2) % 3;
5533 x_laplace_read_row (f
, cmap
, in
[rowa
], img
->width
, ximg
, in_y
++);
5535 for (x
= 0; x
< img
->width
- 2; ++x
)
5537 int r
= in
[rowa
][x
].red
+ mv2
- in
[rowb
][x
+ 2].red
;
5538 int g
= in
[rowa
][x
].green
+ mv2
- in
[rowb
][x
+ 2].green
;
5539 int b
= in
[rowa
][x
].blue
+ mv2
- in
[rowb
][x
+ 2].blue
;
5541 out
[x
+ 1] = lookup_rgb_color (f
, r
& 0xffff, g
& 0xffff,
5545 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
++);
5548 /* Write last line, all zeros. */
5549 for (x
= 0; x
< img
->width
; ++x
)
5551 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
);
5553 /* Free the input image, and free resources of IMG. */
5554 XDestroyImage (ximg
);
5555 x_clear_image (f
, img
);
5557 /* Put the output image into pixmap, and destroy it. */
5558 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
5559 x_destroy_x_image (oimg
);
5561 /* Remember new pixmap and colors in IMG. */
5562 img
->pixmap
= pixmap
;
5563 img
->colors
= colors_in_color_table (&img
->ncolors
);
5564 free_color_table ();
5567 #endif /* MAC_TODO */
5571 /* Build a mask for image IMG which is used on frame F. FILE is the
5572 name of an image file, for error messages. HOW determines how to
5573 determine the background color of IMG. If it is a list '(R G B)',
5574 with R, G, and B being integers >= 0, take that as the color of the
5575 background. Otherwise, determine the background color of IMG
5576 heuristically. Value is non-zero if successful. */
5579 x_build_heuristic_mask (f
, img
, how
)
5584 #if 0 /* MAC_TODO : Mac version */
5585 Display
*dpy
= FRAME_W32_DISPLAY (f
);
5586 XImage
*ximg
, *mask_img
;
5587 int x
, y
, rc
, look_at_corners_p
;
5592 /* Create an image and pixmap serving as mask. */
5593 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
5594 &mask_img
, &img
->mask
);
5601 /* Get the X image of IMG->pixmap. */
5602 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
5605 /* Determine the background color of ximg. If HOW is `(R G B)'
5606 take that as color. Otherwise, try to determine the color
5608 look_at_corners_p
= 1;
5616 && NATNUMP (XCAR (how
)))
5618 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
5622 if (i
== 3 && NILP (how
))
5624 char color_name
[30];
5625 XColor exact
, color
;
5628 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
5630 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
5631 if (XLookupColor (dpy
, cmap
, color_name
, &exact
, &color
))
5634 look_at_corners_p
= 0;
5639 if (look_at_corners_p
)
5641 unsigned long corners
[4];
5644 /* Get the colors at the corners of ximg. */
5645 corners
[0] = XGetPixel (ximg
, 0, 0);
5646 corners
[1] = XGetPixel (ximg
, img
->width
- 1, 0);
5647 corners
[2] = XGetPixel (ximg
, img
->width
- 1, img
->height
- 1);
5648 corners
[3] = XGetPixel (ximg
, 0, img
->height
- 1);
5650 /* Choose the most frequently found color as background. */
5651 for (i
= best_count
= 0; i
< 4; ++i
)
5655 for (j
= n
= 0; j
< 4; ++j
)
5656 if (corners
[i
] == corners
[j
])
5660 bg
= corners
[i
], best_count
= n
;
5664 /* Set all bits in mask_img to 1 whose color in ximg is different
5665 from the background color bg. */
5666 for (y
= 0; y
< img
->height
; ++y
)
5667 for (x
= 0; x
< img
->width
; ++x
)
5668 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
5670 /* Put mask_img into img->mask. */
5671 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
5672 x_destroy_x_image (mask_img
);
5673 XDestroyImage (ximg
);
5676 #endif /* MAC_TODO */
5683 /***********************************************************************
5684 PBM (mono, gray, color)
5685 ***********************************************************************/
5688 static int pbm_image_p
P_ ((Lisp_Object object
));
5689 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
5690 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
5692 /* The symbol `pbm' identifying images of this type. */
5696 /* Indices of image specification fields in gs_format, below. */
5698 enum pbm_keyword_index
5711 /* Vector of image_keyword structures describing the format
5712 of valid user-defined image specifications. */
5714 static struct image_keyword pbm_format
[PBM_LAST
] =
5716 {":type", IMAGE_SYMBOL_VALUE
, 1},
5717 {":file", IMAGE_STRING_VALUE
, 0},
5718 {":data", IMAGE_STRING_VALUE
, 0},
5719 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
5720 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5721 {":relief", IMAGE_INTEGER_VALUE
, 0},
5722 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5723 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5726 /* Structure describing the image type `pbm'. */
5728 static struct image_type pbm_type
=
5738 /* Return non-zero if OBJECT is a valid PBM image specification. */
5741 pbm_image_p (object
)
5744 struct image_keyword fmt
[PBM_LAST
];
5746 bcopy (pbm_format
, fmt
, sizeof fmt
);
5748 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
)
5749 || (fmt
[PBM_ASCENT
].count
5750 && XFASTINT (fmt
[PBM_ASCENT
].value
) > 100))
5753 /* Must specify either :data or :file. */
5754 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
5758 /* Scan a decimal number from *S and return it. Advance *S while
5759 reading the number. END is the end of the string. Value is -1 at
5763 pbm_scan_number (s
, end
)
5764 unsigned char **s
, *end
;
5770 /* Skip white-space. */
5771 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5776 /* Skip comment to end of line. */
5777 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
5780 else if (isdigit (c
))
5782 /* Read decimal number. */
5784 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
5785 val
= 10 * val
+ c
- '0';
5796 /* Read FILE into memory. Value is a pointer to a buffer allocated
5797 with xmalloc holding FILE's contents. Value is null if an error
5798 occurred. *SIZE is set to the size of the file. */
5801 pbm_read_file (file
, size
)
5809 if (stat (SDATA (file
), &st
) == 0
5810 && (fp
= fopen (SDATA (file
), "r")) != NULL
5811 && (buf
= (char *) xmalloc (st
.st_size
),
5812 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5832 /* Load PBM image IMG for use on frame F. */
5840 int width
, height
, max_color_idx
= 0;
5842 Lisp_Object file
, specified_file
;
5843 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5844 struct gcpro gcpro1
;
5845 unsigned char *contents
= NULL
;
5846 unsigned char *end
, *p
;
5849 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5853 if (STRINGP (specified_file
))
5855 file
= x_find_image_file (specified_file
);
5856 if (!STRINGP (file
))
5858 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5863 contents
= pbm_read_file (file
, &size
);
5864 if (contents
== NULL
)
5866 image_error ("Error reading `%s'", file
, Qnil
);
5872 end
= contents
+ size
;
5877 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5879 end
= p
+ SBYTES (data
);
5882 /* Check magic number. */
5883 if (end
- p
< 2 || *p
++ != 'P')
5885 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5895 raw_p
= 0, type
= PBM_MONO
;
5899 raw_p
= 0, type
= PBM_GRAY
;
5903 raw_p
= 0, type
= PBM_COLOR
;
5907 raw_p
= 1, type
= PBM_MONO
;
5911 raw_p
= 1, type
= PBM_GRAY
;
5915 raw_p
= 1, type
= PBM_COLOR
;
5919 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5923 /* Read width, height, maximum color-component. Characters
5924 starting with `#' up to the end of a line are ignored. */
5925 width
= pbm_scan_number (&p
, end
);
5926 height
= pbm_scan_number (&p
, end
);
5928 if (type
!= PBM_MONO
)
5930 max_color_idx
= pbm_scan_number (&p
, end
);
5931 if (raw_p
&& max_color_idx
> 255)
5932 max_color_idx
= 255;
5937 || (type
!= PBM_MONO
&& max_color_idx
< 0))
5941 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
5942 &ximg
, &img
->pixmap
))
5948 /* Initialize the color hash table. */
5949 init_color_table ();
5951 if (type
== PBM_MONO
)
5955 for (y
= 0; y
< height
; ++y
)
5956 for (x
= 0; x
< width
; ++x
)
5966 g
= pbm_scan_number (&p
, end
);
5968 XPutPixel (ximg
, x
, y
, (g
5969 ? FRAME_FOREGROUND_PIXEL (f
)
5970 : FRAME_BACKGROUND_PIXEL (f
)));
5975 for (y
= 0; y
< height
; ++y
)
5976 for (x
= 0; x
< width
; ++x
)
5980 if (type
== PBM_GRAY
)
5981 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
5990 r
= pbm_scan_number (&p
, end
);
5991 g
= pbm_scan_number (&p
, end
);
5992 b
= pbm_scan_number (&p
, end
);
5995 if (r
< 0 || g
< 0 || b
< 0)
5999 XDestroyImage (ximg
);
6001 image_error ("Invalid pixel value in image `%s'",
6006 /* RGB values are now in the range 0..max_color_idx.
6007 Scale this to the range 0..0xffff supported by X. */
6008 r
= (double) r
* 65535 / max_color_idx
;
6009 g
= (double) g
* 65535 / max_color_idx
;
6010 b
= (double) b
* 65535 / max_color_idx
;
6011 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
6015 /* Store in IMG->colors the colors allocated for the image, and
6016 free the color table. */
6017 img
->colors
= colors_in_color_table (&img
->ncolors
);
6018 free_color_table ();
6020 /* Put the image into a pixmap. */
6021 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6022 x_destroy_x_image (ximg
);
6026 img
->height
= height
;
6032 #endif /* HAVE_PBM */
6035 /***********************************************************************
6037 ***********************************************************************/
6043 /* Function prototypes. */
6045 static int png_image_p
P_ ((Lisp_Object object
));
6046 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
6048 /* The symbol `png' identifying images of this type. */
6052 /* Indices of image specification fields in png_format, below. */
6054 enum png_keyword_index
6067 /* Vector of image_keyword structures describing the format
6068 of valid user-defined image specifications. */
6070 static struct image_keyword png_format
[PNG_LAST
] =
6072 {":type", IMAGE_SYMBOL_VALUE
, 1},
6073 {":data", IMAGE_STRING_VALUE
, 0},
6074 {":file", IMAGE_STRING_VALUE
, 0},
6075 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6076 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6077 {":relief", IMAGE_INTEGER_VALUE
, 0},
6078 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6079 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6082 /* Structure describing the image type `png'. */
6084 static struct image_type png_type
=
6094 /* Return non-zero if OBJECT is a valid PNG image specification. */
6097 png_image_p (object
)
6100 struct image_keyword fmt
[PNG_LAST
];
6101 bcopy (png_format
, fmt
, sizeof fmt
);
6103 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
)
6104 || (fmt
[PNG_ASCENT
].count
6105 && XFASTINT (fmt
[PNG_ASCENT
].value
) > 100))
6108 /* Must specify either the :data or :file keyword. */
6109 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
6113 /* Error and warning handlers installed when the PNG library
6117 my_png_error (png_ptr
, msg
)
6118 png_struct
*png_ptr
;
6121 xassert (png_ptr
!= NULL
);
6122 image_error ("PNG error: %s", build_string (msg
), Qnil
);
6123 longjmp (png_ptr
->jmpbuf
, 1);
6128 my_png_warning (png_ptr
, msg
)
6129 png_struct
*png_ptr
;
6132 xassert (png_ptr
!= NULL
);
6133 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
6136 /* Memory source for PNG decoding. */
6138 struct png_memory_storage
6140 unsigned char *bytes
; /* The data */
6141 size_t len
; /* How big is it? */
6142 int index
; /* Where are we? */
6146 /* Function set as reader function when reading PNG image from memory.
6147 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
6148 bytes from the input to DATA. */
6151 png_read_from_memory (png_ptr
, data
, length
)
6152 png_structp png_ptr
;
6156 struct png_memory_storage
*tbr
6157 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
6159 if (length
> tbr
->len
- tbr
->index
)
6160 png_error (png_ptr
, "Read error");
6162 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
6163 tbr
->index
= tbr
->index
+ length
;
6166 /* Load PNG image IMG for use on frame F. Value is non-zero if
6174 Lisp_Object file
, specified_file
;
6175 Lisp_Object specified_data
;
6177 XImage
*ximg
, *mask_img
= NULL
;
6178 struct gcpro gcpro1
;
6179 png_struct
*png_ptr
= NULL
;
6180 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
6183 png_byte
*pixels
= NULL
;
6184 png_byte
**rows
= NULL
;
6185 png_uint_32 width
, height
;
6186 int bit_depth
, color_type
, interlace_type
;
6188 png_uint_32 row_bytes
;
6191 double screen_gamma
, image_gamma
;
6193 struct png_memory_storage tbr
; /* Data to be read */
6195 /* Find out what file to load. */
6196 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6197 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6201 if (NILP (specified_data
))
6203 file
= x_find_image_file (specified_file
);
6204 if (!STRINGP (file
))
6206 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6211 /* Open the image file. */
6212 fp
= fopen (SDATA (file
), "rb");
6215 image_error ("Cannot open image file `%s'", file
, Qnil
);
6221 /* Check PNG signature. */
6222 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
6223 || !png_check_sig (sig
, sizeof sig
))
6225 image_error ("Not a PNG file:` %s'", file
, Qnil
);
6233 /* Read from memory. */
6234 tbr
.bytes
= SDATA (specified_data
);
6235 tbr
.len
= SBYTES (specified_data
);
6238 /* Check PNG signature. */
6239 if (tbr
.len
< sizeof sig
6240 || !png_check_sig (tbr
.bytes
, sizeof sig
))
6242 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
6247 /* Need to skip past the signature. */
6248 tbr
.bytes
+= sizeof (sig
);
6251 /* Initialize read and info structs for PNG lib. */
6252 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
6253 my_png_error
, my_png_warning
);
6256 if (fp
) fclose (fp
);
6261 info_ptr
= png_create_info_struct (png_ptr
);
6264 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
6265 if (fp
) fclose (fp
);
6270 end_info
= png_create_info_struct (png_ptr
);
6273 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
6274 if (fp
) fclose (fp
);
6279 /* Set error jump-back. We come back here when the PNG library
6280 detects an error. */
6281 if (setjmp (png_ptr
->jmpbuf
))
6285 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
6288 if (fp
) fclose (fp
);
6293 /* Read image info. */
6294 if (!NILP (specified_data
))
6295 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
6297 png_init_io (png_ptr
, fp
);
6299 png_set_sig_bytes (png_ptr
, sizeof sig
);
6300 png_read_info (png_ptr
, info_ptr
);
6301 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
6302 &interlace_type
, NULL
, NULL
);
6304 /* If image contains simply transparency data, we prefer to
6305 construct a clipping mask. */
6306 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
6311 /* This function is easier to write if we only have to handle
6312 one data format: RGB or RGBA with 8 bits per channel. Let's
6313 transform other formats into that format. */
6315 /* Strip more than 8 bits per channel. */
6316 if (bit_depth
== 16)
6317 png_set_strip_16 (png_ptr
);
6319 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
6321 png_set_expand (png_ptr
);
6323 /* Convert grayscale images to RGB. */
6324 if (color_type
== PNG_COLOR_TYPE_GRAY
6325 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
6326 png_set_gray_to_rgb (png_ptr
);
6328 /* The value 2.2 is a guess for PC monitors from PNG example.c. */
6329 gamma_str
= getenv ("SCREEN_GAMMA");
6330 screen_gamma
= gamma_str
? atof (gamma_str
) : 2.2;
6332 /* Tell the PNG lib to handle gamma correction for us. */
6334 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
6335 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
6336 /* There is a special chunk in the image specifying the gamma. */
6337 png_set_sRGB (png_ptr
, info_ptr
, intent
);
6340 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
6341 /* Image contains gamma information. */
6342 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
6344 /* Use a default of 0.5 for the image gamma. */
6345 png_set_gamma (png_ptr
, screen_gamma
, 0.5);
6347 /* Handle alpha channel by combining the image with a background
6348 color. Do this only if a real alpha channel is supplied. For
6349 simple transparency, we prefer a clipping mask. */
6352 png_color_16
*image_background
;
6354 if (png_get_bKGD (png_ptr
, info_ptr
, &image_background
))
6355 /* Image contains a background color with which to
6356 combine the image. */
6357 png_set_background (png_ptr
, image_background
,
6358 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
6361 /* Image does not contain a background color with which
6362 to combine the image data via an alpha channel. Use
6363 the frame's background instead. */
6366 png_color_16 frame_background
;
6369 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6370 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
6371 XQueryColor (FRAME_W32_DISPLAY (f
), cmap
, &color
);
6374 bzero (&frame_background
, sizeof frame_background
);
6375 frame_background
.red
= color
.red
;
6376 frame_background
.green
= color
.green
;
6377 frame_background
.blue
= color
.blue
;
6379 png_set_background (png_ptr
, &frame_background
,
6380 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
6384 /* Update info structure. */
6385 png_read_update_info (png_ptr
, info_ptr
);
6387 /* Get number of channels. Valid values are 1 for grayscale images
6388 and images with a palette, 2 for grayscale images with transparency
6389 information (alpha channel), 3 for RGB images, and 4 for RGB
6390 images with alpha channel, i.e. RGBA. If conversions above were
6391 sufficient we should only have 3 or 4 channels here. */
6392 channels
= png_get_channels (png_ptr
, info_ptr
);
6393 xassert (channels
== 3 || channels
== 4);
6395 /* Number of bytes needed for one row of the image. */
6396 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
6398 /* Allocate memory for the image. */
6399 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
6400 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
6401 for (i
= 0; i
< height
; ++i
)
6402 rows
[i
] = pixels
+ i
* row_bytes
;
6404 /* Read the entire image. */
6405 png_read_image (png_ptr
, rows
);
6406 png_read_end (png_ptr
, info_ptr
);
6415 /* Create the X image and pixmap. */
6416 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
6423 /* Create an image and pixmap serving as mask if the PNG image
6424 contains an alpha channel. */
6427 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
6428 &mask_img
, &img
->mask
))
6430 x_destroy_x_image (ximg
);
6431 XFreePixmap (FRAME_W32_DISPLAY (f
), img
->pixmap
);
6437 /* Fill the X image and mask from PNG data. */
6438 init_color_table ();
6440 for (y
= 0; y
< height
; ++y
)
6442 png_byte
*p
= rows
[y
];
6444 for (x
= 0; x
< width
; ++x
)
6451 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
6453 /* An alpha channel, aka mask channel, associates variable
6454 transparency with an image. Where other image formats
6455 support binary transparency---fully transparent or fully
6456 opaque---PNG allows up to 254 levels of partial transparency.
6457 The PNG library implements partial transparency by combining
6458 the image with a specified background color.
6460 I'm not sure how to handle this here nicely: because the
6461 background on which the image is displayed may change, for
6462 real alpha channel support, it would be necessary to create
6463 a new image for each possible background.
6465 What I'm doing now is that a mask is created if we have
6466 boolean transparency information. Otherwise I'm using
6467 the frame's background color to combine the image with. */
6472 XPutPixel (mask_img
, x
, y
, *p
> 0);
6478 /* Remember colors allocated for this image. */
6479 img
->colors
= colors_in_color_table (&img
->ncolors
);
6480 free_color_table ();
6483 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
6488 img
->height
= height
;
6490 /* Put the image into the pixmap, then free the X image and its buffer. */
6491 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6492 x_destroy_x_image (ximg
);
6494 /* Same for the mask. */
6497 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
6498 x_destroy_x_image (mask_img
);
6506 #endif /* HAVE_PNG != 0 */
6510 /***********************************************************************
6512 ***********************************************************************/
6516 /* Work around a warning about HAVE_STDLIB_H being redefined in
6518 #ifdef HAVE_STDLIB_H
6519 #define HAVE_STDLIB_H_1
6520 #undef HAVE_STDLIB_H
6521 #endif /* HAVE_STLIB_H */
6523 #include <jpeglib.h>
6527 #ifdef HAVE_STLIB_H_1
6528 #define HAVE_STDLIB_H 1
6531 static int jpeg_image_p
P_ ((Lisp_Object object
));
6532 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
6534 /* The symbol `jpeg' identifying images of this type. */
6538 /* Indices of image specification fields in gs_format, below. */
6540 enum jpeg_keyword_index
6549 JPEG_HEURISTIC_MASK
,
6553 /* Vector of image_keyword structures describing the format
6554 of valid user-defined image specifications. */
6556 static struct image_keyword jpeg_format
[JPEG_LAST
] =
6558 {":type", IMAGE_SYMBOL_VALUE
, 1},
6559 {":data", IMAGE_STRING_VALUE
, 0},
6560 {":file", IMAGE_STRING_VALUE
, 0},
6561 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6562 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6563 {":relief", IMAGE_INTEGER_VALUE
, 0},
6564 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6565 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6568 /* Structure describing the image type `jpeg'. */
6570 static struct image_type jpeg_type
=
6580 /* Return non-zero if OBJECT is a valid JPEG image specification. */
6583 jpeg_image_p (object
)
6586 struct image_keyword fmt
[JPEG_LAST
];
6588 bcopy (jpeg_format
, fmt
, sizeof fmt
);
6590 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
)
6591 || (fmt
[JPEG_ASCENT
].count
6592 && XFASTINT (fmt
[JPEG_ASCENT
].value
) > 100))
6595 /* Must specify either the :data or :file keyword. */
6596 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
6600 struct my_jpeg_error_mgr
6602 struct jpeg_error_mgr pub
;
6603 jmp_buf setjmp_buffer
;
6607 my_error_exit (cinfo
)
6610 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6611 longjmp (mgr
->setjmp_buffer
, 1);
6614 /* Init source method for JPEG data source manager. Called by
6615 jpeg_read_header() before any data is actually read. See
6616 libjpeg.doc from the JPEG lib distribution. */
6619 our_init_source (cinfo
)
6620 j_decompress_ptr cinfo
;
6625 /* Fill input buffer method for JPEG data source manager. Called
6626 whenever more data is needed. We read the whole image in one step,
6627 so this only adds a fake end of input marker at the end. */
6630 our_fill_input_buffer (cinfo
)
6631 j_decompress_ptr cinfo
;
6633 /* Insert a fake EOI marker. */
6634 struct jpeg_source_mgr
*src
= cinfo
->src
;
6635 static JOCTET buffer
[2];
6637 buffer
[0] = (JOCTET
) 0xFF;
6638 buffer
[1] = (JOCTET
) JPEG_EOI
;
6640 src
->next_input_byte
= buffer
;
6641 src
->bytes_in_buffer
= 2;
6646 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6647 is the JPEG data source manager. */
6650 our_skip_input_data (cinfo
, num_bytes
)
6651 j_decompress_ptr cinfo
;
6654 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6658 if (num_bytes
> src
->bytes_in_buffer
)
6659 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6661 src
->bytes_in_buffer
-= num_bytes
;
6662 src
->next_input_byte
+= num_bytes
;
6667 /* Method to terminate data source. Called by
6668 jpeg_finish_decompress() after all data has been processed. */
6671 our_term_source (cinfo
)
6672 j_decompress_ptr cinfo
;
6677 /* Set up the JPEG lib for reading an image from DATA which contains
6678 LEN bytes. CINFO is the decompression info structure created for
6679 reading the image. */
6682 jpeg_memory_src (cinfo
, data
, len
)
6683 j_decompress_ptr cinfo
;
6687 struct jpeg_source_mgr
*src
;
6689 if (cinfo
->src
== NULL
)
6691 /* First time for this JPEG object? */
6692 cinfo
->src
= (struct jpeg_source_mgr
*)
6693 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6694 sizeof (struct jpeg_source_mgr
));
6695 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6696 src
->next_input_byte
= data
;
6699 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6700 src
->init_source
= our_init_source
;
6701 src
->fill_input_buffer
= our_fill_input_buffer
;
6702 src
->skip_input_data
= our_skip_input_data
;
6703 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
6704 src
->term_source
= our_term_source
;
6705 src
->bytes_in_buffer
= len
;
6706 src
->next_input_byte
= data
;
6710 /* Load image IMG for use on frame F. Patterned after example.c
6711 from the JPEG lib. */
6718 struct jpeg_decompress_struct cinfo
;
6719 struct my_jpeg_error_mgr mgr
;
6720 Lisp_Object file
, specified_file
;
6721 Lisp_Object specified_data
;
6724 int row_stride
, x
, y
;
6725 XImage
*ximg
= NULL
;
6727 unsigned long *colors
;
6729 struct gcpro gcpro1
;
6731 /* Open the JPEG file. */
6732 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6733 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6737 if (NILP (specified_data
))
6739 file
= x_find_image_file (specified_file
);
6740 if (!STRINGP (file
))
6742 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6747 fp
= fopen (SDATA (file
), "r");
6750 image_error ("Cannot open `%s'", file
, Qnil
);
6756 /* Customize libjpeg's error handling to call my_error_exit when an
6757 error is detected. This function will perform a longjmp. */
6758 mgr
.pub
.error_exit
= my_error_exit
;
6759 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
6761 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
6765 /* Called from my_error_exit. Display a JPEG error. */
6766 char buffer
[JMSG_LENGTH_MAX
];
6767 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
6768 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
6769 build_string (buffer
));
6772 /* Close the input file and destroy the JPEG object. */
6775 jpeg_destroy_decompress (&cinfo
);
6779 /* If we already have an XImage, free that. */
6780 x_destroy_x_image (ximg
);
6782 /* Free pixmap and colors. */
6783 x_clear_image (f
, img
);
6790 /* Create the JPEG decompression object. Let it read from fp.
6791 Read the JPEG image header. */
6792 jpeg_create_decompress (&cinfo
);
6794 if (NILP (specified_data
))
6795 jpeg_stdio_src (&cinfo
, fp
);
6797 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
6798 SBYTES (specified_data
));
6800 jpeg_read_header (&cinfo
, TRUE
);
6802 /* Customize decompression so that color quantization will be used.
6803 Start decompression. */
6804 cinfo
.quantize_colors
= TRUE
;
6805 jpeg_start_decompress (&cinfo
);
6806 width
= img
->width
= cinfo
.output_width
;
6807 height
= img
->height
= cinfo
.output_height
;
6811 /* Create X image and pixmap. */
6812 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
6816 longjmp (mgr
.setjmp_buffer
, 2);
6819 /* Allocate colors. When color quantization is used,
6820 cinfo.actual_number_of_colors has been set with the number of
6821 colors generated, and cinfo.colormap is a two-dimensional array
6822 of color indices in the range 0..cinfo.actual_number_of_colors.
6823 No more than 255 colors will be generated. */
6827 if (cinfo
.out_color_components
> 2)
6828 ir
= 0, ig
= 1, ib
= 2;
6829 else if (cinfo
.out_color_components
> 1)
6830 ir
= 0, ig
= 1, ib
= 0;
6832 ir
= 0, ig
= 0, ib
= 0;
6834 /* Use the color table mechanism because it handles colors that
6835 cannot be allocated nicely. Such colors will be replaced with
6836 a default color, and we don't have to care about which colors
6837 can be freed safely, and which can't. */
6838 init_color_table ();
6839 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
6842 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
6844 /* Multiply RGB values with 255 because X expects RGB values
6845 in the range 0..0xffff. */
6846 int r
= cinfo
.colormap
[ir
][i
] << 8;
6847 int g
= cinfo
.colormap
[ig
][i
] << 8;
6848 int b
= cinfo
.colormap
[ib
][i
] << 8;
6849 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6852 /* Remember those colors actually allocated. */
6853 img
->colors
= colors_in_color_table (&img
->ncolors
);
6854 free_color_table ();
6858 row_stride
= width
* cinfo
.output_components
;
6859 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
6861 for (y
= 0; y
< height
; ++y
)
6863 jpeg_read_scanlines (&cinfo
, buffer
, 1);
6864 for (x
= 0; x
< cinfo
.output_width
; ++x
)
6865 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6869 jpeg_finish_decompress (&cinfo
);
6870 jpeg_destroy_decompress (&cinfo
);
6874 /* Put the image into the pixmap. */
6875 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6876 x_destroy_x_image (ximg
);
6882 #endif /* HAVE_JPEG */
6886 /***********************************************************************
6888 ***********************************************************************/
6894 static int tiff_image_p
P_ ((Lisp_Object object
));
6895 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
6897 /* The symbol `tiff' identifying images of this type. */
6901 /* Indices of image specification fields in tiff_format, below. */
6903 enum tiff_keyword_index
6912 TIFF_HEURISTIC_MASK
,
6916 /* Vector of image_keyword structures describing the format
6917 of valid user-defined image specifications. */
6919 static struct image_keyword tiff_format
[TIFF_LAST
] =
6921 {":type", IMAGE_SYMBOL_VALUE
, 1},
6922 {":data", IMAGE_STRING_VALUE
, 0},
6923 {":file", IMAGE_STRING_VALUE
, 0},
6924 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6925 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6926 {":relief", IMAGE_INTEGER_VALUE
, 0},
6927 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6928 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6931 /* Structure describing the image type `tiff'. */
6933 static struct image_type tiff_type
=
6943 /* Return non-zero if OBJECT is a valid TIFF image specification. */
6946 tiff_image_p (object
)
6949 struct image_keyword fmt
[TIFF_LAST
];
6950 bcopy (tiff_format
, fmt
, sizeof fmt
);
6952 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
)
6953 || (fmt
[TIFF_ASCENT
].count
6954 && XFASTINT (fmt
[TIFF_ASCENT
].value
) > 100))
6957 /* Must specify either the :data or :file keyword. */
6958 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6962 /* Reading from a memory buffer for TIFF images Based on the PNG
6963 memory source, but we have to provide a lot of extra functions.
6966 We really only need to implement read and seek, but I am not
6967 convinced that the TIFF library is smart enough not to destroy
6968 itself if we only hand it the function pointers we need to
6973 unsigned char *bytes
;
6980 tiff_read_from_memory (data
, buf
, size
)
6985 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6987 if (size
> src
->len
- src
->index
)
6989 bcopy (src
->bytes
+ src
->index
, buf
, size
);
6995 tiff_write_from_memory (data
, buf
, size
)
7004 tiff_seek_in_memory (data
, off
, whence
)
7009 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
7014 case SEEK_SET
: /* Go from beginning of source. */
7018 case SEEK_END
: /* Go from end of source. */
7019 idx
= src
->len
+ off
;
7022 case SEEK_CUR
: /* Go from current position. */
7023 idx
= src
->index
+ off
;
7026 default: /* Invalid `whence'. */
7030 if (idx
> src
->len
|| idx
< 0)
7038 tiff_close_memory (data
)
7046 tiff_mmap_memory (data
, pbase
, psize
)
7051 /* It is already _IN_ memory. */
7056 tiff_unmap_memory (data
, base
, size
)
7061 /* We don't need to do this. */
7065 tiff_size_of_memory (data
)
7068 return ((tiff_memory_source
*) data
)->len
;
7071 /* Load TIFF image IMG for use on frame F. Value is non-zero if
7079 Lisp_Object file
, specified_file
;
7080 Lisp_Object specified_data
;
7082 int width
, height
, x
, y
;
7086 struct gcpro gcpro1
;
7087 tiff_memory_source memsrc
;
7089 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7090 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7094 if (NILP (specified_data
))
7096 /* Read from a file */
7097 file
= x_find_image_file (specified_file
);
7098 if (!STRINGP (file
))
7100 image_error ("Cannot find image file `%s'", file
, Qnil
);
7105 /* Try to open the image file. */
7106 tiff
= TIFFOpen (SDATA (file
), "r");
7109 image_error ("Cannot open `%s'", file
, Qnil
);
7116 /* Memory source! */
7117 memsrc
.bytes
= SDATA (specified_data
);
7118 memsrc
.len
= SBYTES (specified_data
);
7121 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
7122 (TIFFReadWriteProc
) tiff_read_from_memory
,
7123 (TIFFReadWriteProc
) tiff_write_from_memory
,
7124 tiff_seek_in_memory
,
7126 tiff_size_of_memory
,
7132 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
7138 /* Get width and height of the image, and allocate a raster buffer
7139 of width x height 32-bit values. */
7140 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
7141 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
7142 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
7144 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
7148 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
7156 /* Create the X image and pixmap. */
7157 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7165 /* Initialize the color table. */
7166 init_color_table ();
7168 /* Process the pixel raster. Origin is in the lower-left corner. */
7169 for (y
= 0; y
< height
; ++y
)
7171 uint32
*row
= buf
+ y
* width
;
7173 for (x
= 0; x
< width
; ++x
)
7175 uint32 abgr
= row
[x
];
7176 int r
= TIFFGetR (abgr
) << 8;
7177 int g
= TIFFGetG (abgr
) << 8;
7178 int b
= TIFFGetB (abgr
) << 8;
7179 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
7183 /* Remember the colors allocated for the image. Free the color table. */
7184 img
->colors
= colors_in_color_table (&img
->ncolors
);
7185 free_color_table ();
7187 /* Put the image into the pixmap, then free the X image and its buffer. */
7188 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7189 x_destroy_x_image (ximg
);
7194 img
->height
= height
;
7200 #endif /* HAVE_TIFF != 0 */
7204 /***********************************************************************
7206 ***********************************************************************/
7210 #include <gif_lib.h>
7212 static int gif_image_p
P_ ((Lisp_Object object
));
7213 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
7215 /* The symbol `gif' identifying images of this type. */
7219 /* Indices of image specification fields in gif_format, below. */
7221 enum gif_keyword_index
7235 /* Vector of image_keyword structures describing the format
7236 of valid user-defined image specifications. */
7238 static struct image_keyword gif_format
[GIF_LAST
] =
7240 {":type", IMAGE_SYMBOL_VALUE
, 1},
7241 {":data", IMAGE_STRING_VALUE
, 0},
7242 {":file", IMAGE_STRING_VALUE
, 0},
7243 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7244 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7245 {":relief", IMAGE_INTEGER_VALUE
, 0},
7246 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7247 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7248 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
7251 /* Structure describing the image type `gif'. */
7253 static struct image_type gif_type
=
7262 /* Return non-zero if OBJECT is a valid GIF image specification. */
7265 gif_image_p (object
)
7268 struct image_keyword fmt
[GIF_LAST
];
7269 bcopy (gif_format
, fmt
, sizeof fmt
);
7271 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
)
7272 || (fmt
[GIF_ASCENT
].count
7273 && XFASTINT (fmt
[GIF_ASCENT
].value
) > 100))
7276 /* Must specify either the :data or :file keyword. */
7277 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
7280 /* Reading a GIF image from memory
7281 Based on the PNG memory stuff to a certain extent. */
7285 unsigned char *bytes
;
7291 /* Make the current memory source available to gif_read_from_memory.
7292 It's done this way because not all versions of libungif support
7293 a UserData field in the GifFileType structure. */
7294 static gif_memory_source
*current_gif_memory_src
;
7297 gif_read_from_memory (file
, buf
, len
)
7302 gif_memory_source
*src
= current_gif_memory_src
;
7304 if (len
> src
->len
- src
->index
)
7307 bcopy (src
->bytes
+ src
->index
, buf
, len
);
7313 /* Load GIF image IMG for use on frame F. Value is non-zero if
7321 Lisp_Object file
, specified_file
;
7322 Lisp_Object specified_data
;
7323 int rc
, width
, height
, x
, y
, i
;
7325 ColorMapObject
*gif_color_map
;
7326 unsigned long pixel_colors
[256];
7328 struct gcpro gcpro1
;
7330 int ino
, image_left
, image_top
, image_width
, image_height
;
7331 gif_memory_source memsrc
;
7332 unsigned char *raster
;
7334 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7335 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7339 if (NILP (specified_data
))
7341 file
= x_find_image_file (specified_file
);
7342 if (!STRINGP (file
))
7344 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7349 /* Open the GIF file. */
7350 gif
= DGifOpenFileName (SDATA (file
));
7353 image_error ("Cannot open `%s'", file
, Qnil
);
7360 /* Read from memory! */
7361 current_gif_memory_src
= &memsrc
;
7362 memsrc
.bytes
= SDATA (specified_data
);
7363 memsrc
.len
= SBYTES (specified_data
);
7366 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
7369 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
7375 /* Read entire contents. */
7376 rc
= DGifSlurp (gif
);
7377 if (rc
== GIF_ERROR
)
7379 image_error ("Error reading `%s'", img
->spec
, Qnil
);
7380 DGifCloseFile (gif
);
7385 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7386 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
7387 if (ino
>= gif
->ImageCount
)
7389 image_error ("Invalid image number `%s' in image `%s'",
7391 DGifCloseFile (gif
);
7396 width
= img
->width
= gif
->SWidth
;
7397 height
= img
->height
= gif
->SHeight
;
7401 /* Create the X image and pixmap. */
7402 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7405 DGifCloseFile (gif
);
7410 /* Allocate colors. */
7411 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
7413 gif_color_map
= gif
->SColorMap
;
7414 init_color_table ();
7415 bzero (pixel_colors
, sizeof pixel_colors
);
7417 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7419 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7420 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7421 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7422 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7425 img
->colors
= colors_in_color_table (&img
->ncolors
);
7426 free_color_table ();
7428 /* Clear the part of the screen image that are not covered by
7429 the image from the GIF file. Full animated GIF support
7430 requires more than can be done here (see the gif89 spec,
7431 disposal methods). Let's simply assume that the part
7432 not covered by a sub-image is in the frame's background color. */
7433 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
7434 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
7435 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
7436 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
7438 for (y
= 0; y
< image_top
; ++y
)
7439 for (x
= 0; x
< width
; ++x
)
7440 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7442 for (y
= image_top
+ image_height
; y
< height
; ++y
)
7443 for (x
= 0; x
< width
; ++x
)
7444 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7446 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
7448 for (x
= 0; x
< image_left
; ++x
)
7449 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7450 for (x
= image_left
+ image_width
; x
< width
; ++x
)
7451 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7454 /* Read the GIF image into the X image. We use a local variable
7455 `raster' here because RasterBits below is a char *, and invites
7456 problems with bytes >= 0x80. */
7457 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
7459 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
7461 static int interlace_start
[] = {0, 4, 2, 1};
7462 static int interlace_increment
[] = {8, 8, 4, 2};
7464 int row
= interlace_start
[0];
7468 for (y
= 0; y
< image_height
; y
++)
7470 if (row
>= image_height
)
7472 row
= interlace_start
[++pass
];
7473 while (row
>= image_height
)
7474 row
= interlace_start
[++pass
];
7477 for (x
= 0; x
< image_width
; x
++)
7479 int i
= raster
[(y
* image_width
) + x
];
7480 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
7484 row
+= interlace_increment
[pass
];
7489 for (y
= 0; y
< image_height
; ++y
)
7490 for (x
= 0; x
< image_width
; ++x
)
7492 int i
= raster
[y
* image_width
+ x
];
7493 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
7497 DGifCloseFile (gif
);
7499 /* Put the image into the pixmap, then free the X image and its buffer. */
7500 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7501 x_destroy_x_image (ximg
);
7508 #endif /* HAVE_GIF != 0 */
7512 /***********************************************************************
7514 ***********************************************************************/
7516 #ifdef HAVE_GHOSTSCRIPT
7517 static int gs_image_p
P_ ((Lisp_Object object
));
7518 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
7519 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
7521 /* The symbol `postscript' identifying images of this type. */
7523 Lisp_Object Qpostscript
;
7525 /* Keyword symbols. */
7527 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
7529 /* Indices of image specification fields in gs_format, below. */
7531 enum gs_keyword_index
7547 /* Vector of image_keyword structures describing the format
7548 of valid user-defined image specifications. */
7550 static struct image_keyword gs_format
[GS_LAST
] =
7552 {":type", IMAGE_SYMBOL_VALUE
, 1},
7553 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
7554 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
7555 {":file", IMAGE_STRING_VALUE
, 1},
7556 {":loader", IMAGE_FUNCTION_VALUE
, 0},
7557 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
7558 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7559 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7560 {":relief", IMAGE_INTEGER_VALUE
, 0},
7561 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7562 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7565 /* Structure describing the image type `ghostscript'. */
7567 static struct image_type gs_type
=
7577 /* Free X resources of Ghostscript image IMG which is used on frame F. */
7580 gs_clear_image (f
, img
)
7584 /* IMG->data.ptr_val may contain a recorded colormap. */
7585 xfree (img
->data
.ptr_val
);
7586 x_clear_image (f
, img
);
7590 /* Return non-zero if OBJECT is a valid Ghostscript image
7597 struct image_keyword fmt
[GS_LAST
];
7601 bcopy (gs_format
, fmt
, sizeof fmt
);
7603 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
)
7604 || (fmt
[GS_ASCENT
].count
7605 && XFASTINT (fmt
[GS_ASCENT
].value
) > 100))
7608 /* Bounding box must be a list or vector containing 4 integers. */
7609 tem
= fmt
[GS_BOUNDING_BOX
].value
;
7612 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
7613 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
7618 else if (VECTORP (tem
))
7620 if (XVECTOR (tem
)->size
!= 4)
7622 for (i
= 0; i
< 4; ++i
)
7623 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
7633 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
7642 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
7643 struct gcpro gcpro1
, gcpro2
;
7645 double in_width
, in_height
;
7646 Lisp_Object pixel_colors
= Qnil
;
7648 /* Compute pixel size of pixmap needed from the given size in the
7649 image specification. Sizes in the specification are in pt. 1 pt
7650 = 1/72 in, xdpi and ydpi are stored in the frame's X display
7652 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
7653 in_width
= XFASTINT (pt_width
) / 72.0;
7654 img
->width
= in_width
* FRAME_W32_DISPLAY_INFO (f
)->resx
;
7655 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
7656 in_height
= XFASTINT (pt_height
) / 72.0;
7657 img
->height
= in_height
* FRAME_W32_DISPLAY_INFO (f
)->resy
;
7659 /* Create the pixmap. */
7661 xassert (img
->pixmap
== 0);
7662 img
->pixmap
= XCreatePixmap (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
7663 img
->width
, img
->height
,
7664 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
7669 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
7673 /* Call the loader to fill the pixmap. It returns a process object
7674 if successful. We do not record_unwind_protect here because
7675 other places in redisplay like calling window scroll functions
7676 don't either. Let the Lisp loader use `unwind-protect' instead. */
7677 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
7679 sprintf (buffer
, "%lu %lu",
7680 (unsigned long) FRAME_W32_WINDOW (f
),
7681 (unsigned long) img
->pixmap
);
7682 window_and_pixmap_id
= build_string (buffer
);
7684 sprintf (buffer
, "%lu %lu",
7685 FRAME_FOREGROUND_PIXEL (f
),
7686 FRAME_BACKGROUND_PIXEL (f
));
7687 pixel_colors
= build_string (buffer
);
7689 XSETFRAME (frame
, f
);
7690 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
7692 loader
= intern ("gs-load-image");
7694 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
7695 make_number (img
->width
),
7696 make_number (img
->height
),
7697 window_and_pixmap_id
,
7700 return PROCESSP (img
->data
.lisp_val
);
7704 /* Kill the Ghostscript process that was started to fill PIXMAP on
7705 frame F. Called from XTread_socket when receiving an event
7706 telling Emacs that Ghostscript has finished drawing. */
7709 x_kill_gs_process (pixmap
, f
)
7713 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
7717 /* Find the image containing PIXMAP. */
7718 for (i
= 0; i
< c
->used
; ++i
)
7719 if (c
->images
[i
]->pixmap
== pixmap
)
7722 /* Kill the GS process. We should have found PIXMAP in the image
7723 cache and its image should contain a process object. */
7724 xassert (i
< c
->used
);
7726 xassert (PROCESSP (img
->data
.lisp_val
));
7727 Fkill_process (img
->data
.lisp_val
, Qnil
);
7728 img
->data
.lisp_val
= Qnil
;
7730 /* On displays with a mutable colormap, figure out the colors
7731 allocated for the image by looking at the pixels of an XImage for
7733 class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
7734 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
7740 /* Try to get an XImage for img->pixmep. */
7741 ximg
= XGetImage (FRAME_W32_DISPLAY (f
), img
->pixmap
,
7742 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
7747 /* Initialize the color table. */
7748 init_color_table ();
7750 /* For each pixel of the image, look its color up in the
7751 color table. After having done so, the color table will
7752 contain an entry for each color used by the image. */
7753 for (y
= 0; y
< img
->height
; ++y
)
7754 for (x
= 0; x
< img
->width
; ++x
)
7756 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
7757 lookup_pixel_color (f
, pixel
);
7760 /* Record colors in the image. Free color table and XImage. */
7761 img
->colors
= colors_in_color_table (&img
->ncolors
);
7762 free_color_table ();
7763 XDestroyImage (ximg
);
7765 #if 0 /* This doesn't seem to be the case. If we free the colors
7766 here, we get a BadAccess later in x_clear_image when
7767 freeing the colors. */
7768 /* We have allocated colors once, but Ghostscript has also
7769 allocated colors on behalf of us. So, to get the
7770 reference counts right, free them once. */
7773 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
7774 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
,
7775 img
->colors
, img
->ncolors
, 0);
7780 image_error ("Cannot get X image of `%s'; colors will not be freed",
7787 #endif /* HAVE_GHOSTSCRIPT */
7790 /***********************************************************************
7792 ***********************************************************************/
7794 DEFUN ("x-change-window-property", Fx_change_window_property
,
7795 Sx_change_window_property
, 2, 3, 0,
7796 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
7797 PROP and VALUE must be strings. FRAME nil or omitted means use the
7798 selected frame. Value is VALUE. */)
7799 (prop
, value
, frame
)
7800 Lisp_Object frame
, prop
, value
;
7802 #if 0 /* MAC_TODO : port window properties to Mac */
7803 struct frame
*f
= check_x_frame (frame
);
7806 CHECK_STRING (prop
);
7807 CHECK_STRING (value
);
7810 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
7811 XChangeProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
7812 prop_atom
, XA_STRING
, 8, PropModeReplace
,
7813 SDATA (value
), SCHARS (value
));
7815 /* Make sure the property is set when we return. */
7816 XFlush (FRAME_W32_DISPLAY (f
));
7819 #endif /* MAC_TODO */
7825 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
7826 Sx_delete_window_property
, 1, 2, 0,
7827 doc
: /* Remove window property PROP from X window of FRAME.
7828 FRAME nil or omitted means use the selected frame. Value is PROP. */)
7830 Lisp_Object prop
, frame
;
7832 #if 0 /* MAC_TODO : port window properties to Mac */
7834 struct frame
*f
= check_x_frame (frame
);
7837 CHECK_STRING (prop
);
7839 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
7840 XDeleteProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), prop_atom
);
7842 /* Make sure the property is removed when we return. */
7843 XFlush (FRAME_W32_DISPLAY (f
));
7845 #endif /* MAC_TODO */
7851 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
7853 doc
: /* Value is the value of window property PROP on FRAME.
7854 If FRAME is nil or omitted, use the selected frame. Value is nil
7855 if FRAME hasn't a property with name PROP or if PROP has no string
7858 Lisp_Object prop
, frame
;
7860 #if 0 /* MAC_TODO : port window properties to Mac */
7862 struct frame
*f
= check_x_frame (frame
);
7865 Lisp_Object prop_value
= Qnil
;
7866 char *tmp_data
= NULL
;
7869 unsigned long actual_size
, bytes_remaining
;
7871 CHECK_STRING (prop
);
7873 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
7874 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
7875 prop_atom
, 0, 0, False
, XA_STRING
,
7876 &actual_type
, &actual_format
, &actual_size
,
7877 &bytes_remaining
, (unsigned char **) &tmp_data
);
7880 int size
= bytes_remaining
;
7885 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
7886 prop_atom
, 0, bytes_remaining
,
7888 &actual_type
, &actual_format
,
7889 &actual_size
, &bytes_remaining
,
7890 (unsigned char **) &tmp_data
);
7892 prop_value
= make_string (tmp_data
, size
);
7901 #endif /* MAC_TODO */
7907 /***********************************************************************
7909 ***********************************************************************/
7911 /* If non-null, an asynchronous timer that, when it expires, displays
7912 an hourglass cursor on all frames. */
7914 static struct atimer
*hourglass_atimer
;
7916 /* Non-zero means an hourglass cursor is currently shown. */
7918 static int hourglass_shown_p
;
7920 /* Number of seconds to wait before displaying an hourglass cursor. */
7922 static Lisp_Object Vhourglass_delay
;
7924 /* Default number of seconds to wait before displaying an hourglass
7927 #define DEFAULT_HOURGLASS_DELAY 1
7929 /* Function prototypes. */
7931 static void show_hourglass
P_ ((struct atimer
*));
7932 static void hide_hourglass
P_ ((void));
7935 /* Cancel a currently active hourglass timer, and start a new one. */
7940 #if 0 /* MAC_TODO: cursor shape changes. */
7942 int secs
, usecs
= 0;
7944 cancel_hourglass ();
7946 if (INTEGERP (Vhourglass_delay
)
7947 && XINT (Vhourglass_delay
) > 0)
7948 secs
= XFASTINT (Vhourglass_delay
);
7949 else if (FLOATP (Vhourglass_delay
)
7950 && XFLOAT_DATA (Vhourglass_delay
) > 0)
7953 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
7954 secs
= XFASTINT (tem
);
7955 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
7958 secs
= DEFAULT_HOURGLASS_DELAY
;
7960 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
7961 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
7962 show_hourglass
, NULL
);
7963 #endif /* MAC_TODO */
7967 /* Cancel the hourglass cursor timer if active, hide an hourglass
7973 if (hourglass_atimer
)
7975 cancel_atimer (hourglass_atimer
);
7976 hourglass_atimer
= NULL
;
7979 if (hourglass_shown_p
)
7984 /* Timer function of hourglass_atimer. TIMER is equal to
7987 Display an hourglass cursor on all frames by mapping the frames'
7988 hourglass_window. Set the hourglass_p flag in the frames'
7989 output_data.x structure to indicate that an hourglass cursor is
7990 shown on the frames. */
7993 show_hourglass (timer
)
7994 struct atimer
*timer
;
7996 #if 0 /* MAC_TODO: cursor shape changes. */
7997 /* The timer implementation will cancel this timer automatically
7998 after this function has run. Set hourglass_atimer to null
7999 so that we know the timer doesn't have to be canceled. */
8000 hourglass_atimer
= NULL
;
8002 if (!hourglass_shown_p
)
8004 Lisp_Object rest
, frame
;
8008 FOR_EACH_FRAME (rest
, frame
)
8009 if (FRAME_W32_P (XFRAME (frame
)))
8011 struct frame
*f
= XFRAME (frame
);
8013 f
->output_data
.w32
->hourglass_p
= 1;
8015 if (!f
->output_data
.w32
->hourglass_window
)
8017 unsigned long mask
= CWCursor
;
8018 XSetWindowAttributes attrs
;
8020 attrs
.cursor
= f
->output_data
.w32
->hourglass_cursor
;
8022 f
->output_data
.w32
->hourglass_window
8023 = XCreateWindow (FRAME_X_DISPLAY (f
),
8024 FRAME_OUTER_WINDOW (f
),
8025 0, 0, 32000, 32000, 0, 0,
8031 XMapRaised (FRAME_X_DISPLAY (f
),
8032 f
->output_data
.w32
->hourglass_window
);
8033 XFlush (FRAME_X_DISPLAY (f
));
8036 hourglass_shown_p
= 1;
8039 #endif /* MAC_TODO */
8043 /* Hide the hourglass cursor on all frames, if it is currently shown. */
8048 #if 0 /* MAC_TODO: cursor shape changes. */
8049 if (hourglass_shown_p
)
8051 Lisp_Object rest
, frame
;
8054 FOR_EACH_FRAME (rest
, frame
)
8056 struct frame
*f
= XFRAME (frame
);
8059 /* Watch out for newly created frames. */
8060 && f
->output_data
.x
->hourglass_window
)
8062 XUnmapWindow (FRAME_X_DISPLAY (f
),
8063 f
->output_data
.x
->hourglass_window
);
8064 /* Sync here because XTread_socket looks at the
8065 hourglass_p flag that is reset to zero below. */
8066 XSync (FRAME_X_DISPLAY (f
), False
);
8067 f
->output_data
.x
->hourglass_p
= 0;
8071 hourglass_shown_p
= 0;
8074 #endif /* MAC_TODO */
8079 /***********************************************************************
8081 ***********************************************************************/
8083 static Lisp_Object x_create_tip_frame
P_ ((struct mac_display_info
*,
8086 /* The frame of a currently visible tooltip, or null. */
8088 Lisp_Object tip_frame
;
8090 /* If non-nil, a timer started that hides the last tooltip when it
8093 Lisp_Object tip_timer
;
8096 /* If non-nil, a vector of 3 elements containing the last args
8097 with which x-show-tip was called. See there. */
8099 Lisp_Object last_show_tip_args
;
8101 /* Create a frame for a tooltip on the display described by DPYINFO.
8102 PARMS is a list of frame parameters. Value is the frame. */
8105 x_create_tip_frame (dpyinfo
, parms
)
8106 struct mac_display_info
*dpyinfo
;
8109 #if 0 /* MAC_TODO : Mac version */
8111 Lisp_Object frame
, tem
;
8113 long window_prompting
= 0;
8115 int count
= SPECPDL_INDEX ();
8116 struct gcpro gcpro1
, gcpro2
, gcpro3
;
8121 /* Use this general default value to start with until we know if
8122 this frame has a specified name. */
8123 Vx_resource_name
= Vinvocation_name
;
8126 kb
= dpyinfo
->kboard
;
8128 kb
= &the_only_kboard
;
8131 /* Get the name of the frame to use for resource lookup. */
8132 name
= w32_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
8134 && !EQ (name
, Qunbound
)
8136 error ("Invalid frame name--not a string or nil");
8137 Vx_resource_name
= name
;
8140 GCPRO3 (parms
, name
, frame
);
8141 tip_frame
= f
= make_frame (1);
8142 XSETFRAME (frame
, f
);
8143 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
8145 f
->output_method
= output_w32
;
8146 f
->output_data
.w32
=
8147 (struct w32_output
*) xmalloc (sizeof (struct w32_output
));
8148 bzero (f
->output_data
.w32
, sizeof (struct w32_output
));
8150 f
->output_data
.w32
->icon_bitmap
= -1;
8152 FRAME_FONTSET (f
) = -1;
8153 f
->icon_name
= Qnil
;
8156 FRAME_KBOARD (f
) = kb
;
8158 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
8159 f
->output_data
.w32
->explicit_parent
= 0;
8161 /* Set the name; the functions to which we pass f expect the name to
8163 if (EQ (name
, Qunbound
) || NILP (name
))
8165 f
->name
= build_string (dpyinfo
->x_id_name
);
8166 f
->explicit_name
= 0;
8171 f
->explicit_name
= 1;
8172 /* use the frame's title when getting resources for this frame. */
8173 specbind (Qx_resource_name
, name
);
8176 /* Extract the window parameters from the supplied values
8177 that are needed to determine window geometry. */
8181 font
= w32_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
8184 /* First, try whatever font the caller has specified. */
8187 tem
= Fquery_fontset (font
, Qnil
);
8189 font
= x_new_fontset (f
, SDATA (tem
));
8191 font
= x_new_font (f
, SDATA (font
));
8194 /* Try out a font which we hope has bold and italic variations. */
8195 if (!STRINGP (font
))
8196 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
8197 if (!STRINGP (font
))
8198 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
8199 if (! STRINGP (font
))
8200 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
8201 if (! STRINGP (font
))
8202 /* This was formerly the first thing tried, but it finds too many fonts
8203 and takes too long. */
8204 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
8205 /* If those didn't work, look for something which will at least work. */
8206 if (! STRINGP (font
))
8207 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
8209 if (! STRINGP (font
))
8210 font
= build_string ("fixed");
8212 x_default_parameter (f
, parms
, Qfont
, font
,
8213 "font", "Font", RES_TYPE_STRING
);
8216 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
8217 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
8219 /* This defaults to 2 in order to match xterm. We recognize either
8220 internalBorderWidth or internalBorder (which is what xterm calls
8222 if (NILP (Fassq (Qinternal_border_width
, parms
)))
8226 value
= w32_get_arg (parms
, Qinternal_border_width
,
8227 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
8228 if (! EQ (value
, Qunbound
))
8229 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
8233 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
8234 "internalBorderWidth", "internalBorderWidth",
8237 /* Also do the stuff which must be set before the window exists. */
8238 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
8239 "foreground", "Foreground", RES_TYPE_STRING
);
8240 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
8241 "background", "Background", RES_TYPE_STRING
);
8242 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
8243 "pointerColor", "Foreground", RES_TYPE_STRING
);
8244 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
8245 "cursorColor", "Foreground", RES_TYPE_STRING
);
8246 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
8247 "borderColor", "BorderColor", RES_TYPE_STRING
);
8249 /* Init faces before x_default_parameter is called for scroll-bar
8250 parameters because that function calls x_set_scroll_bar_width,
8251 which calls change_frame_size, which calls Fset_window_buffer,
8252 which runs hooks, which call Fvertical_motion. At the end, we
8253 end up in init_iterator with a null face cache, which should not
8255 init_frame_faces (f
);
8257 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
8259 window_prompting
= x_figure_window_size (f
, parms
, 0);
8262 XSetWindowAttributes attrs
;
8266 mask
= CWBackPixel
| CWOverrideRedirect
| CWSaveUnder
| CWEventMask
;
8267 /* Window managers looks at the override-redirect flag to
8268 determine whether or net to give windows a decoration (Xlib
8270 attrs
.override_redirect
= True
;
8271 attrs
.save_under
= True
;
8272 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
8273 /* Arrange for getting MapNotify and UnmapNotify events. */
8274 attrs
.event_mask
= StructureNotifyMask
;
8276 = FRAME_W32_WINDOW (f
)
8277 = XCreateWindow (FRAME_W32_DISPLAY (f
),
8278 FRAME_W32_DISPLAY_INFO (f
)->root_window
,
8279 /* x, y, width, height */
8283 CopyFromParent
, InputOutput
, CopyFromParent
,
8290 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
8291 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
8292 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
8293 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
8294 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
8295 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
8297 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
8298 Change will not be effected unless different from the current
8300 width
= FRAME_COLS (f
);
8301 height
= FRAME_LINES (f
);
8302 FRAME_LINES (f
) = 0;
8303 SET_FRAME_COLS (f
, 0);
8304 change_frame_size (f
, height
, width
, 1, 0, 0);
8306 /* Add `tooltip' frame parameter's default value. */
8307 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
8308 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
8315 /* It is now ok to make the frame official even if we get an error
8316 below. And the frame needs to be on Vframe_list or making it
8317 visible won't work. */
8318 Vframe_list
= Fcons (frame
, Vframe_list
);
8320 /* Now that the frame is official, it counts as a reference to
8322 FRAME_W32_DISPLAY_INFO (f
)->reference_count
++;
8324 return unbind_to (count
, frame
);
8325 #endif /* MAC_TODO */
8330 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
8331 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
8332 A tooltip window is a small window displaying a string.
8334 FRAME nil or omitted means use the selected frame.
8336 PARMS is an optional list of frame parameters which can be used to
8337 change the tooltip's appearance.
8339 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
8340 means use the default timeout of 5 seconds.
8342 If the list of frame parameters PARAMS contains a `left' parameters,
8343 the tooltip is displayed at that x-position. Otherwise it is
8344 displayed at the mouse position, with offset DX added (default is 5 if
8345 DX isn't specified). Likewise for the y-position; if a `top' frame
8346 parameter is specified, it determines the y-position of the tooltip
8347 window, otherwise it is displayed at the mouse position, with offset
8348 DY added (default is 10). */)
8349 (string
, frame
, parms
, timeout
, dx
, dy
)
8350 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
8355 Lisp_Object buffer
, top
, left
;
8356 struct buffer
*old_buffer
;
8357 struct text_pos pos
;
8358 int i
, width
, height
;
8359 int root_x
, root_y
, win_x
, win_y
;
8361 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
8362 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
8363 int count
= SPECPDL_INDEX ();
8365 specbind (Qinhibit_redisplay
, Qt
);
8367 GCPRO4 (string
, parms
, frame
, timeout
);
8369 CHECK_STRING (string
);
8370 f
= check_x_frame (frame
);
8372 timeout
= make_number (5);
8374 CHECK_NATNUM (timeout
);
8377 dx
= make_number (5);
8382 dy
= make_number (-10);
8386 if (NILP (last_show_tip_args
))
8387 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
8389 if (!NILP (tip_frame
))
8391 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
8392 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
8393 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
8395 if (EQ (frame
, last_frame
)
8396 && !NILP (Fequal (last_string
, string
))
8397 && !NILP (Fequal (last_parms
, parms
)))
8399 struct frame
*f
= XFRAME (tip_frame
);
8401 /* Only DX and DY have changed. */
8402 if (!NILP (tip_timer
))
8404 Lisp_Object timer
= tip_timer
;
8406 call1 (Qcancel_timer
, timer
);
8409 #if 0 /* MAC_TODO : Mac specifics */
8411 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
8412 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8413 root_x
, root_y
- FRAME_PIXEL_HEIGHT (f
));
8415 #endif /* MAC_TODO */
8420 /* Hide a previous tip, if any. */
8423 ASET (last_show_tip_args
, 0, string
);
8424 ASET (last_show_tip_args
, 1, frame
);
8425 ASET (last_show_tip_args
, 2, parms
);
8427 /* Add default values to frame parameters. */
8428 if (NILP (Fassq (Qname
, parms
)))
8429 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
8430 if (NILP (Fassq (Qinternal_border_width
, parms
)))
8431 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
8432 if (NILP (Fassq (Qborder_width
, parms
)))
8433 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
8434 if (NILP (Fassq (Qborder_color
, parms
)))
8435 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
8436 if (NILP (Fassq (Qbackground_color
, parms
)))
8437 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
8440 /* Create a frame for the tooltip, and record it in the global
8441 variable tip_frame. */
8442 frame
= x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f
), parms
);
8445 /* Set up the frame's root window. Currently we use a size of 80
8446 columns x 40 lines. If someone wants to show a larger tip, he
8447 will loose. I don't think this is a realistic case. */
8448 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
8449 w
->left_col
= w
->top_line
= make_number (0);
8450 w
->total_cols
= make_number (80);
8451 w
->total_lines
= make_number (40);
8453 w
->pseudo_window_p
= 1;
8455 /* Display the tooltip text in a temporary buffer. */
8456 buffer
= Fget_buffer_create (build_string (" *tip*"));
8457 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
8458 old_buffer
= current_buffer
;
8459 set_buffer_internal_1 (XBUFFER (buffer
));
8461 Finsert (1, &string
);
8462 clear_glyph_matrix (w
->desired_matrix
);
8463 clear_glyph_matrix (w
->current_matrix
);
8464 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
8465 try_window (FRAME_ROOT_WINDOW (f
), pos
);
8467 /* Compute width and height of the tooltip. */
8469 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
8471 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
8475 /* Stop at the first empty row at the end. */
8476 if (!row
->enabled_p
|| !row
->displays_text_p
)
8479 /* Let the row go over the full width of the frame. */
8480 row
->full_width_p
= 1;
8482 /* There's a glyph at the end of rows that is use to place
8483 the cursor there. Don't include the width of this glyph. */
8484 if (row
->used
[TEXT_AREA
])
8486 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
8487 row_width
= row
->pixel_width
- last
->pixel_width
;
8490 row_width
= row
->pixel_width
;
8492 height
+= row
->height
;
8493 width
= max (width
, row_width
);
8496 /* Add the frame's internal border to the width and height the X
8497 window should have. */
8498 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
8499 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
8501 /* Move the tooltip window where the mouse pointer is. Resize and
8503 #if 0 /* TODO : Mac specifics */
8504 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
8507 XQueryPointer (FRAME_W32_DISPLAY (f
), FRAME_W32_DISPLAY_INFO (f
)->root_window
,
8508 &root
, &child
, &root_x
, &root_y
, &win_x
, &win_y
, &pmask
);
8509 XMoveResizeWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
8510 root_x
+ 5, root_y
- height
- 5, width
, height
);
8511 XMapRaised (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
8513 #endif /* MAC_TODO */
8515 /* Draw into the window. */
8516 w
->must_be_updated_p
= 1;
8517 update_single_window (w
, 1);
8519 /* Restore original current buffer. */
8520 set_buffer_internal_1 (old_buffer
);
8521 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
8524 /* Let the tip disappear after timeout seconds. */
8525 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
8526 intern ("x-hide-tip"));
8529 return unbind_to (count
, Qnil
);
8533 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
8534 doc
: /* Hide the current tooltip window, if there is any.
8535 Value is t is tooltip was open, nil otherwise. */)
8539 Lisp_Object deleted
, frame
, timer
;
8540 struct gcpro gcpro1
, gcpro2
;
8542 /* Return quickly if nothing to do. */
8543 if (NILP (tip_timer
) && NILP (tip_frame
))
8548 GCPRO2 (frame
, timer
);
8549 tip_frame
= tip_timer
= deleted
= Qnil
;
8551 count
= SPECPDL_INDEX ();
8552 specbind (Qinhibit_redisplay
, Qt
);
8553 specbind (Qinhibit_quit
, Qt
);
8556 call1 (Qcancel_timer
, timer
);
8560 Fdelete_frame (frame
, Qnil
);
8565 return unbind_to (count
, deleted
);
8570 /***********************************************************************
8571 File selection dialog
8572 ***********************************************************************/
8574 #if 0 /* MAC_TODO: can standard file dialog */
8575 extern Lisp_Object Qfile_name_history
;
8577 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
8578 doc
: /* Read file name, prompting with PROMPT in directory DIR.
8579 Use a file selection dialog.
8580 Select DEFAULT-FILENAME in the dialog's file selection box, if
8581 specified. Don't let the user enter a file name in the file
8582 selection dialog's entry field, if MUSTMATCH is non-nil. */)
8583 (prompt
, dir
, default_filename
, mustmatch
)
8584 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
8586 struct frame
*f
= SELECTED_FRAME ();
8587 Lisp_Object file
= Qnil
;
8588 int count
= SPECPDL_INDEX ();
8589 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
8590 char filename
[MAX_PATH
+ 1];
8591 char init_dir
[MAX_PATH
+ 1];
8592 int use_dialog_p
= 1;
8594 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
8595 CHECK_STRING (prompt
);
8598 /* Create the dialog with PROMPT as title, using DIR as initial
8599 directory and using "*" as pattern. */
8600 dir
= Fexpand_file_name (dir
, Qnil
);
8601 strncpy (init_dir
, SDATA (dir
), MAX_PATH
);
8602 init_dir
[MAX_PATH
] = '\0';
8603 unixtodos_filename (init_dir
);
8605 if (STRINGP (default_filename
))
8607 char *file_name_only
;
8608 char *full_path_name
= SDATA (default_filename
);
8610 unixtodos_filename (full_path_name
);
8612 file_name_only
= strrchr (full_path_name
, '\\');
8613 if (!file_name_only
)
8614 file_name_only
= full_path_name
;
8619 /* If default_file_name is a directory, don't use the open
8620 file dialog, as it does not support selecting
8622 if (!(*file_name_only
))
8626 strncpy (filename
, file_name_only
, MAX_PATH
);
8627 filename
[MAX_PATH
] = '\0';
8634 OPENFILENAME file_details
;
8635 char *filename_file
;
8637 /* Prevent redisplay. */
8638 specbind (Qinhibit_redisplay
, Qt
);
8641 bzero (&file_details
, sizeof (file_details
));
8642 file_details
.lStructSize
= sizeof (file_details
);
8643 file_details
.hwndOwner
= FRAME_W32_WINDOW (f
);
8644 file_details
.lpstrFile
= filename
;
8645 file_details
.nMaxFile
= sizeof (filename
);
8646 file_details
.lpstrInitialDir
= init_dir
;
8647 file_details
.lpstrTitle
= SDATA (prompt
);
8648 file_details
.Flags
= OFN_HIDEREADONLY
| OFN_NOCHANGEDIR
;
8650 if (!NILP (mustmatch
))
8651 file_details
.Flags
|= OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
;
8653 if (GetOpenFileName (&file_details
))
8655 dostounix_filename (filename
);
8656 file
= build_string (filename
);
8662 file
= unbind_to (count
, file
);
8664 /* Open File dialog will not allow folders to be selected, so resort
8665 to minibuffer completing reads for directories. */
8667 file
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
8668 dir
, mustmatch
, dir
, Qfile_name_history
,
8669 default_filename
, Qnil
);
8673 /* Make "Cancel" equivalent to C-g. */
8675 Fsignal (Qquit
, Qnil
);
8677 return unbind_to (count
, file
);
8679 #endif /* MAC_TODO */
8683 /***********************************************************************
8685 ***********************************************************************/
8689 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
8690 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
8694 return valid_image_p (spec
) ? Qt
: Qnil
;
8698 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
8704 if (valid_image_p (spec
))
8705 id
= lookup_image (SELECTED_FRAME (), spec
);
8708 return make_number (id
);
8711 #endif /* GLYPH_DEBUG != 0 */
8715 /***********************************************************************
8717 ***********************************************************************/
8719 /* Keep this list in the same order as frame_parms in frame.c.
8720 Use 0 for unsupported frame parameters. */
8722 frame_parm_handler mac_frame_parm_handlers
[] =
8726 x_set_background_color
,
8732 x_set_foreground_color
,
8734 0, /* MAC_TODO: x_set_icon_type, */
8735 x_set_internal_border_width
,
8736 x_set_menu_bar_lines
,
8738 x_explicitly_set_name
,
8739 x_set_scroll_bar_width
,
8742 x_set_vertical_scroll_bars
,
8744 x_set_tool_bar_lines
,
8745 0, /* MAC_TODO: x_set_scroll_bar_foreground, */
8746 0, /* MAC_TODO: x_set_scroll_bar_background, */
8749 0, /* MAC_TODO: x_set_fringe_width, */
8750 0, /* MAC_TODO: x_set_fringe_width, */
8751 0, /* x_set_wait_for_wm, */
8752 0, /* MAC_TODO: x_set_fullscreen, */
8758 /* Certainly running on Mac. */
8761 /* The section below is built by the lisp expression at the top of the file,
8762 just above where these variables are declared. */
8763 /*&&& init symbols here &&&*/
8764 Qnone
= intern ("none");
8766 Qsuppress_icon
= intern ("suppress-icon");
8767 staticpro (&Qsuppress_icon
);
8768 Qundefined_color
= intern ("undefined-color");
8769 staticpro (&Qundefined_color
);
8770 Qcenter
= intern ("center");
8771 staticpro (&Qcenter
);
8772 /* This is the end of symbol initialization. */
8774 Qhyper
= intern ("hyper");
8775 staticpro (&Qhyper
);
8776 Qsuper
= intern ("super");
8777 staticpro (&Qsuper
);
8778 Qmeta
= intern ("meta");
8780 Qalt
= intern ("alt");
8782 Qctrl
= intern ("ctrl");
8784 Qcontrol
= intern ("control");
8785 staticpro (&Qcontrol
);
8786 Qshift
= intern ("shift");
8787 staticpro (&Qshift
);
8789 /* Text property `display' should be nonsticky by default. */
8790 Vtext_property_default_nonsticky
8791 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
8794 Qlaplace
= intern ("laplace");
8795 staticpro (&Qlaplace
);
8797 Qface_set_after_frame_default
= intern ("face-set-after-frame-default");
8798 staticpro (&Qface_set_after_frame_default
);
8800 Fput (Qundefined_color
, Qerror_conditions
,
8801 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
8802 Fput (Qundefined_color
, Qerror_message
,
8803 build_string ("Undefined color"));
8805 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
8806 doc
: /* List of directories to search for window system bitmap files. */);
8807 Vx_bitmap_file_path
= decode_env_path ((char *) 0, "PATH");
8809 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
8810 doc
: /* The shape of the pointer when over text.
8811 Changing the value does not affect existing frames
8812 unless you set the mouse color. */);
8813 Vx_pointer_shape
= Qnil
;
8815 Vx_nontext_pointer_shape
= Qnil
;
8817 Vx_mode_pointer_shape
= Qnil
;
8819 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
8820 doc
: /* The shape of the pointer when Emacs is hourglass.
8821 This variable takes effect when you create a new frame
8822 or when you set the mouse color. */);
8823 Vx_hourglass_pointer_shape
= Qnil
;
8825 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
8826 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
8827 display_hourglass_p
= 1;
8829 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
8830 doc
: /* *Seconds to wait before displaying an hourglass pointer.
8831 Value must be an integer or float. */);
8832 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
8834 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
8835 &Vx_sensitive_text_pointer_shape
,
8836 doc
: /* The shape of the pointer when over mouse-sensitive text.
8837 This variable takes effect when you create a new frame
8838 or when you set the mouse color. */);
8839 Vx_sensitive_text_pointer_shape
= Qnil
;
8841 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
8842 doc
: /* A string indicating the foreground color of the cursor box. */);
8843 Vx_cursor_fore_pixel
= Qnil
;
8845 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
8846 doc
: /* Non-nil if no window manager is in use.
8847 Emacs doesn't try to figure this out; this is always nil
8848 unless you set it to something else. */);
8849 /* We don't have any way to find this out, so set it to nil
8850 and maybe the user would like to set it to t. */
8851 Vx_no_window_manager
= Qnil
;
8853 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
8854 &Vx_pixel_size_width_font_regexp
,
8855 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
8857 Since Emacs gets width of a font matching with this regexp from
8858 PIXEL_SIZE field of the name, font finding mechanism gets faster for
8859 such a font. This is especially effective for such large fonts as
8860 Chinese, Japanese, and Korean. */);
8861 Vx_pixel_size_width_font_regexp
= Qnil
;
8863 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
8864 doc
: /* Time after which cached images are removed from the cache.
8865 When an image has not been displayed this many seconds, remove it
8866 from the image cache. Value must be an integer or nil with nil
8867 meaning don't clear the cache. */);
8868 Vimage_cache_eviction_delay
= make_number (30 * 60);
8870 defsubr (&Sx_change_window_property
);
8871 defsubr (&Sx_delete_window_property
);
8872 defsubr (&Sx_window_property
);
8873 defsubr (&Sxw_display_color_p
);
8874 defsubr (&Sx_display_grayscale_p
);
8875 defsubr (&Sxw_color_defined_p
);
8876 defsubr (&Sxw_color_values
);
8877 defsubr (&Sx_server_max_request_size
);
8878 defsubr (&Sx_server_vendor
);
8879 defsubr (&Sx_server_version
);
8880 defsubr (&Sx_display_pixel_width
);
8881 defsubr (&Sx_display_pixel_height
);
8882 defsubr (&Sx_display_mm_width
);
8883 defsubr (&Sx_display_mm_height
);
8884 defsubr (&Sx_display_screens
);
8885 defsubr (&Sx_display_planes
);
8886 defsubr (&Sx_display_color_cells
);
8887 defsubr (&Sx_display_visual_class
);
8888 defsubr (&Sx_display_backing_store
);
8889 defsubr (&Sx_display_save_under
);
8890 defsubr (&Sx_create_frame
);
8891 #if 0 /* MAC_TODO: implement network support */
8892 defsubr (&Sx_open_connection
);
8893 defsubr (&Sx_close_connection
);
8895 defsubr (&Sx_display_list
);
8896 defsubr (&Sx_synchronize
);
8898 /* Setting callback functions for fontset handler. */
8899 get_font_info_func
= x_get_font_info
;
8901 #if 0 /* This function pointer doesn't seem to be used anywhere.
8902 And the pointer assigned has the wrong type, anyway. */
8903 list_fonts_func
= x_list_fonts
;
8906 load_font_func
= x_load_font
;
8907 find_ccl_program_func
= x_find_ccl_program
;
8908 query_font_func
= x_query_font
;
8910 set_frame_fontset_func
= x_set_font
;
8911 check_window_system_func
= check_mac
;
8913 #if 0 /* MAC_TODO: Image support for Mac Images. */
8914 Qxbm
= intern ("xbm");
8916 QCtype
= intern (":type");
8917 staticpro (&QCtype
);
8918 QCconversion
= intern (":conversion");
8919 staticpro (&QCconversion
);
8920 QCheuristic_mask
= intern (":heuristic-mask");
8921 staticpro (&QCheuristic_mask
);
8922 QCcolor_symbols
= intern (":color-symbols");
8923 staticpro (&QCcolor_symbols
);
8924 QCascent
= intern (":ascent");
8925 staticpro (&QCascent
);
8926 QCmargin
= intern (":margin");
8927 staticpro (&QCmargin
);
8928 QCrelief
= intern (":relief");
8929 staticpro (&QCrelief
);
8930 Qpostscript
= intern ("postscript");
8931 staticpro (&Qpostscript
);
8932 QCloader
= intern (":loader");
8933 staticpro (&QCloader
);
8934 QCbounding_box
= intern (":bounding-box");
8935 staticpro (&QCbounding_box
);
8936 QCpt_width
= intern (":pt-width");
8937 staticpro (&QCpt_width
);
8938 QCpt_height
= intern (":pt-height");
8939 staticpro (&QCpt_height
);
8940 QCindex
= intern (":index");
8941 staticpro (&QCindex
);
8942 Qpbm
= intern ("pbm");
8946 Qxpm
= intern ("xpm");
8951 Qjpeg
= intern ("jpeg");
8956 Qtiff
= intern ("tiff");
8961 Qgif
= intern ("gif");
8966 Qpng
= intern ("png");
8970 defsubr (&Sclear_image_cache
);
8974 defsubr (&Slookup_image
);
8976 #endif /* MAC_TODO */
8978 hourglass_atimer
= NULL
;
8979 hourglass_shown_p
= 0;
8981 defsubr (&Sx_show_tip
);
8982 defsubr (&Sx_hide_tip
);
8983 staticpro (&tip_timer
);
8986 #if 0 /* MAC_TODO */
8987 defsubr (&Sx_file_dialog
);
8996 Vimage_types
= Qnil
;
8998 define_image_type (&xbm_type
);
8999 #if 0 /* NTEMACS_TODO : Image support for W32 */
9000 define_image_type (&gs_type
);
9001 define_image_type (&pbm_type
);
9004 define_image_type (&xpm_type
);
9008 define_image_type (&jpeg_type
);
9012 define_image_type (&tiff_type
);
9016 define_image_type (&gif_type
);
9020 define_image_type (&png_type
);
9022 #endif /* NTEMACS_TODO */
9025 /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc
9026 (do not change this comment) */