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 /* A definition of XColor for non-X frames. */
103 #ifndef HAVE_X_WINDOWS
106 unsigned short red
, green
, blue
;
112 extern char *lispy_function_keys
[];
114 /* The gray bitmap `bitmaps/gray'. This is done because macterm.c uses
115 it, and including `bitmaps/gray' more than once is a problem when
116 config.h defines `static' as an empty replacement string. */
118 int gray_bitmap_width
= gray_width
;
119 int gray_bitmap_height
= gray_height
;
120 unsigned char *gray_bitmap_bits
= gray_bits
;
122 /* The name we're using in resource queries. */
124 Lisp_Object Vx_resource_name
;
126 /* Non-zero means we're allowed to display an hourglass cursor. */
128 int display_hourglass_p
;
130 /* The background and shape of the mouse pointer, and shape when not
131 over text or in the modeline. */
133 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
134 Lisp_Object Vx_hourglass_pointer_shape
;
136 /* The shape when over mouse-sensitive text. */
138 Lisp_Object Vx_sensitive_text_pointer_shape
;
140 /* If non-nil, the pointer shape to indicate that windows can be
141 dragged horizontally. */
143 Lisp_Object Vx_window_horizontal_drag_shape
;
145 /* Color of chars displayed in cursor box. */
147 Lisp_Object Vx_cursor_fore_pixel
;
149 /* Nonzero if using Windows. */
151 static int mac_in_use
;
153 /* Non nil if no window manager is in use. */
155 Lisp_Object Vx_no_window_manager
;
157 /* Search path for bitmap files. */
159 Lisp_Object Vx_bitmap_file_path
;
161 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
163 Lisp_Object Vx_pixel_size_width_font_regexp
;
165 /* Evaluate this expression to rebuild the section of syms_of_macfns
166 that initializes and staticpros the symbols declared below. Note
167 that Emacs 18 has a bug that keeps C-x C-e from being able to
168 evaluate this expression.
171 ;; Accumulate a list of the symbols we want to initialize from the
172 ;; declarations at the top of the file.
173 (goto-char (point-min))
174 (search-forward "/\*&&& symbols declared here &&&*\/\n")
176 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
178 (cons (buffer-substring (match-beginning 1) (match-end 1))
181 (setq symbol-list (nreverse symbol-list))
182 ;; Delete the section of syms_of_... where we initialize the symbols.
183 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
184 (let ((start (point)))
185 (while (looking-at "^ Q")
187 (kill-region start (point)))
188 ;; Write a new symbol initialization section.
190 (insert (format " %s = intern (\"" (car symbol-list)))
191 (let ((start (point)))
192 (insert (substring (car symbol-list) 1))
193 (subst-char-in-region start (point) ?_ ?-))
194 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
195 (setq symbol-list (cdr symbol-list)))))
199 /*&&& symbols declared here &&&*/
200 Lisp_Object Qauto_raise
;
201 Lisp_Object Qauto_lower
;
202 Lisp_Object Qborder_color
;
203 Lisp_Object Qborder_width
;
204 Lisp_Object Qcursor_color
;
205 Lisp_Object Qcursor_type
;
206 Lisp_Object Qgeometry
;
207 Lisp_Object Qicon_left
;
208 Lisp_Object Qicon_top
;
209 Lisp_Object Qicon_type
;
210 Lisp_Object Qicon_name
;
211 Lisp_Object Qinternal_border_width
;
214 Lisp_Object Qmouse_color
;
216 Lisp_Object Qparent_id
;
217 Lisp_Object Qscroll_bar_width
;
218 Lisp_Object Qsuppress_icon
;
219 Lisp_Object Qundefined_color
;
220 Lisp_Object Qvertical_scroll_bars
;
221 Lisp_Object Qvisibility
;
222 Lisp_Object Qwindow_id
;
223 Lisp_Object Qx_frame_parameter
;
224 Lisp_Object Qx_resource_name
;
225 Lisp_Object Quser_position
;
226 Lisp_Object Quser_size
;
227 Lisp_Object Qscreen_gamma
;
228 Lisp_Object Qline_spacing
;
230 Lisp_Object Qcancel_timer
;
236 Lisp_Object Qcontrol
;
239 extern Lisp_Object Qtop
;
240 extern Lisp_Object Qdisplay
;
241 Lisp_Object Qscroll_bar_foreground
, Qscroll_bar_background
;
242 extern Lisp_Object Qtool_bar_lines
;
244 /* These are defined in frame.c. */
245 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
246 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
, Qbuffer_predicate
, Qtitle
;
247 extern Lisp_Object Qtool_bar_lines
;
249 extern Lisp_Object Vwindow_system_version
;
251 Lisp_Object Qface_set_after_frame_default
;
253 extern int mac_initialized
;
255 /* Functions in macterm.c. */
256 extern void x_set_offset (struct frame
*, int, int, int);
257 extern void x_wm_set_icon_position (struct frame
*, int, int);
258 extern void x_display_cursor (struct window
*, int, int, int, int, int);
259 extern void x_set_window_size (struct frame
*, int, int, int);
260 extern void x_make_frame_visible (struct frame
*);
261 extern struct mac_display_info
*mac_term_init (Lisp_Object
, char *, char *);
262 extern struct font_info
*x_get_font_info (FRAME_PTR
, int);
263 extern struct font_info
*x_load_font (struct frame
*, char *, int);
264 extern void x_find_ccl_program (struct font_info
*);
265 extern struct font_info
*x_query_font (struct frame
*, char *);
266 extern void mac_initialize ();
268 /* compare two strings ignoring case */
271 stricmp (const char *s
, const char *t
)
273 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
276 return tolower (*s
) - tolower (*t
);
279 /* compare two strings up to n characters, ignoring case */
282 strnicmp (const char *s
, const char *t
, unsigned int n
)
284 for ( ; n
-- > 0 && tolower (*s
) == tolower (*t
); s
++, t
++)
287 return n
== 0 ? 0 : tolower (*s
) - tolower (*t
);
291 /* Error if we are not running on Mac OS. */
297 error ("Mac OS not in use or not initialized");
300 /* Nonzero if we can use mouse menus.
301 You should not call this unless HAVE_MENUS is defined. */
309 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
310 and checking validity for Mac. */
313 check_x_frame (frame
)
319 frame
= selected_frame
;
320 CHECK_LIVE_FRAME (frame
);
322 if (! FRAME_MAC_P (f
))
323 error ("non-mac frame used");
327 /* Let the user specify an display with a frame.
328 nil stands for the selected frame--or, if that is not a mac frame,
329 the first display on the list. */
331 static struct mac_display_info
*
332 check_x_display_info (frame
)
335 if (!mac_initialized
)
343 struct frame
*sf
= XFRAME (selected_frame
);
345 if (FRAME_MAC_P (sf
) && FRAME_LIVE_P (sf
))
346 return FRAME_MAC_DISPLAY_INFO (sf
);
348 return &one_mac_display_info
;
350 else if (STRINGP (frame
))
351 return x_display_info_for_name (frame
);
356 CHECK_LIVE_FRAME (frame
);
358 if (! FRAME_MAC_P (f
))
359 error ("non-mac frame used");
360 return FRAME_MAC_DISPLAY_INFO (f
);
364 /* Return the Emacs frame-object corresponding to an mac window.
365 It could be the frame's main window or an icon window. */
367 /* This function can be called during GC, so use GC_xxx type test macros. */
370 x_window_to_frame (dpyinfo
, wdesc
)
371 struct mac_display_info
*dpyinfo
;
374 Lisp_Object tail
, frame
;
377 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
380 if (!GC_FRAMEP (frame
))
383 if (!FRAME_W32_P (f
) || FRAME_MAC_DISPLAY_INFO (f
) != dpyinfo
)
385 /*if (f->output_data.w32->hourglass_window == wdesc)
388 /* MAC_TODO: Check tooltips when supported. */
389 if (FRAME_MAC_WINDOW (f
) == wdesc
)
397 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
398 id, which is just an int that this section returns. Bitmaps are
399 reference counted so they can be shared among frames.
401 Bitmap indices are guaranteed to be > 0, so a negative number can
402 be used to indicate no bitmap.
404 If you use x_create_bitmap_from_data, then you must keep track of
405 the bitmaps yourself. That is, creating a bitmap from the same
406 data more than once will not be caught. */
409 /* Functions to access the contents of a bitmap, given an id. */
412 x_bitmap_height (f
, id
)
416 return FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
420 x_bitmap_width (f
, id
)
424 return FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
427 #if 0 /* MAC_TODO : not used anywhere (?) */
429 x_bitmap_pixmap (f
, id
)
433 return (int) FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
437 /* Allocate a new bitmap record. Returns index of new record. */
440 x_allocate_bitmap_record (f
)
443 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
446 if (dpyinfo
->bitmaps
== NULL
)
448 dpyinfo
->bitmaps_size
= 10;
449 dpyinfo
->bitmaps
= (struct mac_bitmap_record
*)
450 xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct mac_bitmap_record
));
451 dpyinfo
->bitmaps_last
= 1;
455 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
456 return ++dpyinfo
->bitmaps_last
;
458 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
459 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
462 dpyinfo
->bitmaps_size
*= 2;
463 dpyinfo
->bitmaps
= (struct mac_bitmap_record
*)
464 xrealloc (dpyinfo
->bitmaps
,
465 dpyinfo
->bitmaps_size
* sizeof (struct mac_bitmap_record
));
466 return ++dpyinfo
->bitmaps_last
;
469 /* Add one reference to the reference count of the bitmap with id
473 x_reference_bitmap (f
, id
)
477 ++FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
480 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at
484 x_create_bitmap_from_data (f
, bits
, width
, height
)
487 unsigned int width
, height
;
489 struct x_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
492 /* MAC_TODO: for now fail if width is not mod 16 (toolbox requires it) */
494 id
= x_allocate_bitmap_record (f
);
499 dpyinfo
->bitmaps
[id
- 1].bitmap_data
= (char *) xmalloc (height
* width
);
500 if (! dpyinfo
->bitmaps
[id
- 1].bitmap_data
)
503 bcopy (bits
, dpyinfo
->bitmaps
[id
- 1].bitmap_data
, height
* width
);
505 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
506 dpyinfo
->bitmaps
[id
- 1].height
= height
;
507 dpyinfo
->bitmaps
[id
- 1].width
= width
;
512 /* Create bitmap from file FILE for frame F. */
515 x_create_bitmap_from_file (f
, file
)
520 #if 0 /* MAC_TODO : bitmap support */
521 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
522 unsigned int width
, height
;
524 int xhot
, yhot
, result
, id
;
530 /* Look for an existing bitmap with the same name. */
531 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
533 if (dpyinfo
->bitmaps
[id
].refcount
534 && dpyinfo
->bitmaps
[id
].file
535 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
537 ++dpyinfo
->bitmaps
[id
].refcount
;
542 /* Search bitmap-file-path for the file, if appropriate. */
543 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, Qnil
);
546 /* LoadLibraryEx won't handle special files handled by Emacs handler. */
551 filename
= (char *) SDATA (found
);
553 hinst
= LoadLibraryEx (filename
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
559 result
= XReadBitmapFile (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
560 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
561 if (result
!= BitmapSuccess
)
564 id
= x_allocate_bitmap_record (f
);
565 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
566 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
567 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SCHARS (file
) + 1);
568 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
569 dpyinfo
->bitmaps
[id
- 1].height
= height
;
570 dpyinfo
->bitmaps
[id
- 1].width
= width
;
571 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
574 #endif /* MAC_TODO */
577 /* Remove reference to bitmap with id number ID. */
580 x_destroy_bitmap (f
, id
)
584 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
588 --dpyinfo
->bitmaps
[id
- 1].refcount
;
589 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
592 dpyinfo
->bitmaps
[id
- 1].bitmap_data
= NULL
;
598 /* Free all the bitmaps for the display specified by DPYINFO. */
601 x_destroy_all_bitmaps (dpyinfo
)
602 struct mac_display_info
*dpyinfo
;
605 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
606 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
607 xfree (dpyinfo
->bitmaps
[i
].bitmap_data
);
608 dpyinfo
->bitmaps_last
= 0;
611 /* Connect the frame-parameter names for W32 frames
612 to the ways of passing the parameter values to the window system.
614 The name of a parameter, as a Lisp symbol,
615 has an `x-frame-parameter' property which is an integer in Lisp
616 but can be interpreted as an `enum x_frame_parm' in C. */
618 struct x_frame_parm_table
621 void (*setter
) P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
624 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
625 static void x_set_line_spacing
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
626 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
627 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
628 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
629 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
630 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
631 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
632 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
633 void x_set_font
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
634 void x_set_border_width
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
635 void x_set_internal_border_width
P_ ((struct frame
*, Lisp_Object
,
637 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
638 void x_set_autoraise
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
639 void x_set_autolower
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
640 void x_set_vertical_scroll_bars
P_ ((struct frame
*, Lisp_Object
,
642 void x_set_visibility
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
643 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
644 void x_set_scroll_bar_width
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
645 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
646 void x_set_unsplittable
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
647 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
648 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
650 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
652 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
657 static void x_set_screen_gamma
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
659 static struct x_frame_parm_table x_frame_parms
[] =
661 "auto-raise", x_set_autoraise
,
662 "auto-lower", x_set_autolower
,
663 "background-color", x_set_background_color
,
664 "border-color", x_set_border_color
,
665 "border-width", x_set_border_width
,
666 "cursor-color", x_set_cursor_color
,
667 "cursor-type", x_set_cursor_type
,
669 "foreground-color", x_set_foreground_color
,
670 "icon-name", x_set_icon_name
,
671 #if 0 /* MAC_TODO: no icons for Mac */
672 "icon-type", x_set_icon_type
,
674 "internal-border-width", x_set_internal_border_width
,
675 "menu-bar-lines", x_set_menu_bar_lines
,
676 "mouse-color", x_set_mouse_color
,
677 "name", x_explicitly_set_name
,
678 "scroll-bar-width", x_set_scroll_bar_width
,
679 "title", x_set_title
,
680 "unsplittable", x_set_unsplittable
,
681 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
682 "visibility", x_set_visibility
,
683 "tool-bar-lines", x_set_tool_bar_lines
,
684 #if 0 /* MAC_TODO: cannot set color of scroll bar on the Mac? */
685 "scroll-bar-foreground", x_set_scroll_bar_foreground
,
686 "scroll-bar-background", x_set_scroll_bar_background
,
688 "screen-gamma", x_set_screen_gamma
,
689 "line-spacing", x_set_line_spacing
692 /* Attach the `x-frame-parameter' properties to
693 the Lisp symbol names of parameters relevant to Mac. */
696 init_x_parm_symbols ()
700 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
701 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
705 /* Change the parameters of frame F as specified by ALIST.
706 If a parameter is not specially recognized, do nothing;
707 otherwise call the `x_set_...' function for that parameter. */
710 x_set_frame_parameters (f
, alist
)
716 /* If both of these parameters are present, it's more efficient to
717 set them both at once. So we wait until we've looked at the
718 entire list before we set them. */
722 Lisp_Object left
, top
;
724 /* Same with these. */
725 Lisp_Object icon_left
, icon_top
;
727 /* Record in these vectors all the parms specified. */
731 int left_no_change
= 0, top_no_change
= 0;
732 int icon_left_no_change
= 0, icon_top_no_change
= 0;
734 struct gcpro gcpro1
, gcpro2
;
737 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
740 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
741 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
743 /* Extract parm names and values into those vectors. */
746 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
751 parms
[i
] = Fcar (elt
);
752 values
[i
] = Fcdr (elt
);
755 /* TAIL and ALIST are not used again below here. */
758 GCPRO2 (*parms
, *values
);
762 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
763 because their values appear in VALUES and strings are not valid. */
764 top
= left
= Qunbound
;
765 icon_left
= icon_top
= Qunbound
;
767 /* Provide default values for HEIGHT and WIDTH. */
768 if (FRAME_NEW_WIDTH (f
))
769 width
= FRAME_NEW_WIDTH (f
);
771 width
= FRAME_WIDTH (f
);
773 if (FRAME_NEW_HEIGHT (f
))
774 height
= FRAME_NEW_HEIGHT (f
);
776 height
= FRAME_HEIGHT (f
);
778 /* Process foreground_color and background_color before anything else.
779 They are independent of other properties, but other properties (e.g.,
780 cursor_color) are dependent upon them. */
781 for (p
= 0; p
< i
; p
++)
783 Lisp_Object prop
, val
;
787 if (EQ (prop
, Qforeground_color
) || EQ (prop
, Qbackground_color
))
789 register Lisp_Object param_index
, old_value
;
791 param_index
= Fget (prop
, Qx_frame_parameter
);
792 old_value
= get_frame_param (f
, prop
);
793 store_frame_param (f
, prop
, val
);
794 if (NATNUMP (param_index
)
795 && (XFASTINT (param_index
)
796 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
797 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
801 /* Now process them in reverse of specified order. */
802 for (i
--; i
>= 0; i
--)
804 Lisp_Object prop
, val
;
809 if (EQ (prop
, Qwidth
) && NUMBERP (val
))
810 width
= XFASTINT (val
);
811 else if (EQ (prop
, Qheight
) && NUMBERP (val
))
812 height
= XFASTINT (val
);
813 else if (EQ (prop
, Qtop
))
815 else if (EQ (prop
, Qleft
))
817 else if (EQ (prop
, Qicon_top
))
819 else if (EQ (prop
, Qicon_left
))
821 else if (EQ (prop
, Qforeground_color
) || EQ (prop
, Qbackground_color
))
822 /* Processed above. */
826 register Lisp_Object param_index
, old_value
;
828 param_index
= Fget (prop
, Qx_frame_parameter
);
829 old_value
= get_frame_param (f
, prop
);
830 store_frame_param (f
, prop
, val
);
831 if (NATNUMP (param_index
)
832 && (XFASTINT (param_index
)
833 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
834 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
838 /* Don't die if just one of these was set. */
839 if (EQ (left
, Qunbound
))
842 if (f
->output_data
.mac
->left_pos
< 0)
844 Fcons (make_number (f
->output_data
.mac
->left_pos
),
847 XSETINT (left
, f
->output_data
.mac
->left_pos
);
849 if (EQ (top
, Qunbound
))
852 if (f
->output_data
.mac
->top_pos
< 0)
854 Fcons (make_number (f
->output_data
.mac
->top_pos
), Qnil
));
856 XSETINT (top
, f
->output_data
.mac
->top_pos
);
859 /* If one of the icon positions was not set, preserve or default it. */
860 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
862 icon_left_no_change
= 1;
863 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
864 if (NILP (icon_left
))
865 XSETINT (icon_left
, 0);
867 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
869 icon_top_no_change
= 1;
870 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
872 XSETINT (icon_top
, 0);
875 /* Don't set these parameters unless they've been explicitly
876 specified. The window might be mapped or resized while we're in
877 this function, and we don't want to override that unless the lisp
878 code has asked for it.
880 Don't set these parameters unless they actually differ from the
881 window's current parameters; the window may not actually exist
886 check_frame_size (f
, &height
, &width
);
888 XSETFRAME (frame
, f
);
890 if (width
!= FRAME_WIDTH (f
)
891 || height
!= FRAME_HEIGHT (f
)
892 || FRAME_NEW_HEIGHT (f
) || FRAME_NEW_WIDTH (f
))
893 Fset_frame_size (frame
, make_number (width
), make_number (height
));
895 if ((!NILP (left
) || !NILP (top
))
896 && ! (left_no_change
&& top_no_change
)
897 && ! (NUMBERP (left
) && XINT (left
) == f
->output_data
.mac
->left_pos
898 && NUMBERP (top
) && XINT (top
) == f
->output_data
.mac
->top_pos
))
903 /* Record the signs. */
904 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
905 if (EQ (left
, Qminus
))
906 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
907 else if (INTEGERP (left
))
909 leftpos
= XINT (left
);
911 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
913 else if (CONSP (left
) && EQ (XCAR (left
), Qminus
)
914 && CONSP (XCDR (left
))
915 && INTEGERP (XCAR (XCDR (left
))))
917 leftpos
= - XINT (XCAR (XCDR (left
)));
918 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
920 else if (CONSP (left
) && EQ (XCAR (left
), Qplus
)
921 && CONSP (XCDR (left
))
922 && INTEGERP (XCAR (XCDR (left
))))
924 leftpos
= XINT (XCAR (XCDR (left
)));
927 if (EQ (top
, Qminus
))
928 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
929 else if (INTEGERP (top
))
933 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
935 else if (CONSP (top
) && EQ (XCAR (top
), Qminus
)
936 && CONSP (XCDR (top
))
937 && INTEGERP (XCAR (XCDR (top
))))
939 toppos
= - XINT (XCAR (XCDR (top
)));
940 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
942 else if (CONSP (top
) && EQ (XCAR (top
), Qplus
)
943 && CONSP (XCDR (top
))
944 && INTEGERP (XCAR (XCDR (top
))))
946 toppos
= XINT (XCAR (XCDR (top
)));
950 /* Store the numeric value of the position. */
951 f
->output_data
.mac
->top_pos
= toppos
;
952 f
->output_data
.mac
->left_pos
= leftpos
;
954 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
956 /* Actually set that position, and convert to absolute. */
957 x_set_offset (f
, leftpos
, toppos
, -1);
960 if ((!NILP (icon_left
) || !NILP (icon_top
))
961 && ! (icon_left_no_change
&& icon_top_no_change
))
962 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
968 /* Store the screen positions of frame F into XPTR and YPTR.
969 These are the positions of the containing window manager window,
970 not Emacs's own window. */
973 x_real_positions (f
, xptr
, yptr
)
980 #ifdef TARGET_API_MAC_CARBON
984 GetWindowPortBounds (f
->output_data
.mac
->mWP
, &r
);
985 SetPt (&pt
, r
.left
, r
.top
);
987 #else /* not TARGET_API_MAC_CARBON */
989 f
->output_data
.mac
->mWP
->portRect
.left
,
990 f
->output_data
.mac
->mWP
->portRect
.top
);
991 #endif /* not TARGET_API_MAC_CARBON */
1000 /* Insert a description of internally-recorded parameters of frame X
1001 into the parameter alist *ALISTPTR that is to be given to the user.
1002 Only parameters that are specific to Mac and whose values are not
1003 correctly recorded in the frame's param_alist need to be considered
1007 x_report_frame_params (f
, alistptr
)
1009 Lisp_Object
*alistptr
;
1014 /* Represent negative positions (off the top or left screen edge)
1015 in a way that Fmodify_frame_parameters will understand correctly. */
1016 XSETINT (tem
, f
->output_data
.mac
->left_pos
);
1017 if (f
->output_data
.mac
->left_pos
>= 0)
1018 store_in_alist (alistptr
, Qleft
, tem
);
1020 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1022 XSETINT (tem
, f
->output_data
.mac
->top_pos
);
1023 if (f
->output_data
.mac
->top_pos
>= 0)
1024 store_in_alist (alistptr
, Qtop
, tem
);
1026 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1028 store_in_alist (alistptr
, Qborder_width
,
1029 make_number (f
->output_data
.mac
->border_width
));
1030 store_in_alist (alistptr
, Qinternal_border_width
,
1031 make_number (f
->output_data
.mac
->internal_border_width
));
1032 sprintf (buf
, "%ld", (long) FRAME_MAC_WINDOW (f
));
1033 store_in_alist (alistptr
, Qwindow_id
,
1034 build_string (buf
));
1035 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
1036 FRAME_SAMPLE_VISIBILITY (f
);
1037 store_in_alist (alistptr
, Qvisibility
,
1038 (FRAME_VISIBLE_P (f
) ? Qt
1039 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1040 store_in_alist (alistptr
, Qdisplay
,
1041 XCAR (FRAME_MAC_DISPLAY_INFO (f
)->name_list_element
));
1044 /* The default colors for the Mac color map */
1045 typedef struct colormap_t
1047 unsigned long color
;
1051 colormap_t mac_color_map
[] =
1053 { RGB_TO_ULONG(255, 250, 250), "snow" },
1054 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
1055 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
1056 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
1057 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
1058 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
1059 { RGB_TO_ULONG(255, 250, 240), "floral white" },
1060 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
1061 { RGB_TO_ULONG(253, 245, 230), "old lace" },
1062 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
1063 { RGB_TO_ULONG(250, 240, 230), "linen" },
1064 { RGB_TO_ULONG(250, 235, 215), "antique white" },
1065 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
1066 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
1067 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
1068 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
1069 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
1070 { RGB_TO_ULONG(255, 228, 196), "bisque" },
1071 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
1072 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
1073 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
1074 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
1075 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
1076 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
1077 { RGB_TO_ULONG(255, 255, 240), "ivory" },
1078 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
1079 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
1080 { RGB_TO_ULONG(255, 245, 238), "seashell" },
1081 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
1082 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
1083 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
1084 { RGB_TO_ULONG(240, 255, 255), "azure" },
1085 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
1086 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
1087 { RGB_TO_ULONG(230, 230, 250), "lavender" },
1088 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
1089 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
1090 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
1091 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
1092 { RGB_TO_ULONG(255, 255, 255), "white" },
1093 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
1094 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
1095 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
1096 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
1097 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
1098 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
1099 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
1100 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
1101 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
1102 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
1103 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
1104 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
1105 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
1106 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
1107 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
1108 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
1109 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
1110 { RGB_TO_ULONG(190, 190, 190), "gray" },
1111 { RGB_TO_ULONG(190, 190, 190), "grey" },
1112 { RGB_TO_ULONG(211, 211, 211), "light grey" },
1113 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
1114 { RGB_TO_ULONG(211, 211, 211), "light gray" },
1115 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
1116 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
1117 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
1118 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
1119 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
1120 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
1121 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
1122 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
1123 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
1124 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
1125 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
1126 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
1127 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
1128 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
1129 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
1130 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
1131 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
1132 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
1133 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
1134 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
1135 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
1136 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
1137 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
1138 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
1139 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
1140 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
1141 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
1142 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
1143 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
1144 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
1145 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
1146 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
1147 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
1148 { RGB_TO_ULONG(173, 216, 230), "light blue" },
1149 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
1150 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
1151 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
1152 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
1153 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
1154 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
1155 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
1156 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
1157 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
1158 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
1159 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
1160 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
1161 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
1162 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
1163 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
1164 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
1165 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
1166 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
1167 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
1168 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
1169 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
1170 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
1171 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
1172 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
1173 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
1174 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
1175 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
1176 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
1177 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
1178 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
1179 { RGB_TO_ULONG(152, 251, 152), "pale green" },
1180 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
1181 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
1182 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
1183 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
1184 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
1185 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
1186 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
1187 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
1188 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
1189 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
1190 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
1191 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
1192 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
1193 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
1194 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
1195 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
1196 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
1197 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
1198 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
1199 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
1200 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
1201 { RGB_TO_ULONG(240, 230, 140), "khaki" },
1202 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
1203 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
1204 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
1205 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
1206 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
1207 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
1208 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
1209 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
1210 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
1211 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
1212 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
1213 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
1214 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
1215 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
1216 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
1217 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
1218 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
1219 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
1220 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
1221 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
1222 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
1223 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
1224 { RGB_TO_ULONG(245, 245, 220), "beige" },
1225 { RGB_TO_ULONG(245, 222, 179), "wheat" },
1226 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
1227 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
1228 { RGB_TO_ULONG(210, 180, 140), "tan" },
1229 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
1230 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
1231 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
1232 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
1233 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
1234 { RGB_TO_ULONG(250, 128, 114), "salmon" },
1235 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
1236 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
1237 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
1238 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
1239 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
1240 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
1241 { RGB_TO_ULONG(240, 128, 128), "light coral" },
1242 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
1243 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
1244 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
1245 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
1246 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
1247 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
1248 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
1249 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
1250 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
1251 { RGB_TO_ULONG(255, 192, 203), "pink" },
1252 { RGB_TO_ULONG(255, 182, 193), "light pink" },
1253 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
1254 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
1255 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
1256 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
1257 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
1258 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
1259 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
1260 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
1261 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
1262 { RGB_TO_ULONG(238, 130, 238), "violet" },
1263 { RGB_TO_ULONG(221, 160, 221), "plum" },
1264 { RGB_TO_ULONG(218, 112, 214), "orchid" },
1265 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
1266 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
1267 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
1268 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
1269 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
1270 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
1271 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
1272 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
1273 { RGB_TO_ULONG(160, 32 , 240), "purple" },
1274 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
1275 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
1276 { RGB_TO_ULONG(216, 191, 216), "thistle" },
1277 { RGB_TO_ULONG(255, 250, 250), "snow1" },
1278 { RGB_TO_ULONG(238, 233, 233), "snow2" },
1279 { RGB_TO_ULONG(205, 201, 201), "snow3" },
1280 { RGB_TO_ULONG(139, 137, 137), "snow4" },
1281 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
1282 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
1283 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
1284 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
1285 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
1286 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
1287 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
1288 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
1289 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
1290 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
1291 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
1292 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
1293 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
1294 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
1295 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
1296 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
1297 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
1298 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
1299 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
1300 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
1301 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
1302 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
1303 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
1304 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
1305 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
1306 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
1307 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
1308 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
1309 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
1310 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
1311 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
1312 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
1313 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
1314 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
1315 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
1316 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
1317 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
1318 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
1319 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
1320 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
1321 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
1322 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
1323 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
1324 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
1325 { RGB_TO_ULONG(240, 255, 255), "azure1" },
1326 { RGB_TO_ULONG(224, 238, 238), "azure2" },
1327 { RGB_TO_ULONG(193, 205, 205), "azure3" },
1328 { RGB_TO_ULONG(131, 139, 139), "azure4" },
1329 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
1330 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
1331 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
1332 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
1333 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
1334 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
1335 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
1336 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
1337 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
1338 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
1339 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
1340 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
1341 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
1342 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
1343 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
1344 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
1345 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
1346 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
1347 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
1348 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
1349 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
1350 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
1351 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
1352 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
1353 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
1354 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
1355 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
1356 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
1357 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
1358 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
1359 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
1360 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
1361 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
1362 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
1363 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
1364 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
1365 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
1366 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
1367 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
1368 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
1369 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
1370 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
1371 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
1372 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
1373 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
1374 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
1375 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
1376 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
1377 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
1378 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
1379 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
1380 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
1381 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
1382 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
1383 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
1384 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
1385 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
1386 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
1387 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
1388 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
1389 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
1390 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
1391 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
1392 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
1393 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
1394 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
1395 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
1396 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
1397 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
1398 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
1399 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
1400 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
1401 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
1402 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
1403 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
1404 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
1405 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
1406 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
1407 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
1408 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
1409 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
1410 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
1411 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
1412 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
1413 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
1414 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
1415 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
1416 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
1417 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
1418 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
1419 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
1420 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
1421 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
1422 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
1423 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
1424 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
1425 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
1426 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
1427 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
1428 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
1429 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
1430 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
1431 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
1432 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
1433 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
1434 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
1435 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
1436 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
1437 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
1438 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
1439 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
1440 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
1441 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
1442 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
1443 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
1444 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
1445 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
1446 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
1447 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
1448 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
1449 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
1450 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
1451 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
1452 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
1453 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
1454 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
1455 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
1456 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
1457 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
1458 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
1459 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
1460 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
1461 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
1462 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
1463 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
1464 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
1465 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
1466 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
1467 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
1468 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
1469 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
1470 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
1471 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
1472 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
1473 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
1474 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
1475 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
1476 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
1477 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
1478 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
1479 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
1480 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
1481 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
1482 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
1483 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
1484 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
1485 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
1486 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
1487 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
1488 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
1489 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
1490 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
1491 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
1492 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
1493 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
1494 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
1495 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
1496 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
1497 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
1498 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
1499 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
1500 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
1501 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
1502 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
1503 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
1504 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
1505 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
1506 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
1507 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
1508 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
1509 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
1510 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
1511 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
1512 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
1513 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
1514 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
1515 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
1516 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
1517 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
1518 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
1519 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
1520 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
1521 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
1522 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
1523 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
1524 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
1525 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
1526 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
1527 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
1528 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
1529 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
1530 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
1531 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
1532 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
1533 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
1534 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
1535 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
1536 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
1537 { RGB_TO_ULONG(255, 181, 197), "pink1" },
1538 { RGB_TO_ULONG(238, 169, 184), "pink2" },
1539 { RGB_TO_ULONG(205, 145, 158), "pink3" },
1540 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
1541 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
1542 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
1543 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
1544 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
1545 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
1546 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
1547 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
1548 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
1549 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
1550 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
1551 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
1552 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
1553 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
1554 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
1555 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
1556 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
1557 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
1558 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
1559 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
1560 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
1561 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
1562 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
1563 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
1564 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
1565 { RGB_TO_ULONG(255, 187, 255), "plum1" },
1566 { RGB_TO_ULONG(238, 174, 238), "plum2" },
1567 { RGB_TO_ULONG(205, 150, 205), "plum3" },
1568 { RGB_TO_ULONG(139, 102, 139), "plum4" },
1569 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
1570 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
1571 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
1572 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
1573 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
1574 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
1575 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
1576 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
1577 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
1578 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
1579 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
1580 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
1581 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
1582 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
1583 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
1584 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
1585 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
1586 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
1587 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
1588 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
1589 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
1590 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
1591 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
1592 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
1593 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
1594 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
1595 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
1596 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
1597 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
1598 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
1599 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
1600 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
1601 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
1602 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
1603 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
1604 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
1605 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
1606 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
1607 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
1608 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
1609 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
1610 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
1611 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
1612 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
1613 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
1614 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
1615 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
1616 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
1617 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
1618 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
1619 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
1620 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
1621 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
1622 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
1623 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
1624 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
1625 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
1626 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
1627 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
1628 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
1629 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
1630 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
1631 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
1632 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
1633 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
1634 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
1635 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
1636 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
1637 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
1638 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
1639 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
1640 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
1641 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
1642 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
1643 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
1644 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
1645 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
1646 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
1647 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
1648 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
1649 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
1650 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
1651 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
1652 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
1653 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
1654 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
1655 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
1656 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
1657 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
1658 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
1659 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
1660 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
1661 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
1662 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
1663 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
1664 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
1665 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
1666 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
1667 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
1668 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
1669 { RGB_TO_ULONG(102, 102, 102), "gray40" },
1670 { RGB_TO_ULONG(102, 102, 102), "grey40" },
1671 { RGB_TO_ULONG(105, 105, 105), "gray41" },
1672 { RGB_TO_ULONG(105, 105, 105), "grey41" },
1673 { RGB_TO_ULONG(107, 107, 107), "gray42" },
1674 { RGB_TO_ULONG(107, 107, 107), "grey42" },
1675 { RGB_TO_ULONG(110, 110, 110), "gray43" },
1676 { RGB_TO_ULONG(110, 110, 110), "grey43" },
1677 { RGB_TO_ULONG(112, 112, 112), "gray44" },
1678 { RGB_TO_ULONG(112, 112, 112), "grey44" },
1679 { RGB_TO_ULONG(115, 115, 115), "gray45" },
1680 { RGB_TO_ULONG(115, 115, 115), "grey45" },
1681 { RGB_TO_ULONG(117, 117, 117), "gray46" },
1682 { RGB_TO_ULONG(117, 117, 117), "grey46" },
1683 { RGB_TO_ULONG(120, 120, 120), "gray47" },
1684 { RGB_TO_ULONG(120, 120, 120), "grey47" },
1685 { RGB_TO_ULONG(122, 122, 122), "gray48" },
1686 { RGB_TO_ULONG(122, 122, 122), "grey48" },
1687 { RGB_TO_ULONG(125, 125, 125), "gray49" },
1688 { RGB_TO_ULONG(125, 125, 125), "grey49" },
1689 { RGB_TO_ULONG(127, 127, 127), "gray50" },
1690 { RGB_TO_ULONG(127, 127, 127), "grey50" },
1691 { RGB_TO_ULONG(130, 130, 130), "gray51" },
1692 { RGB_TO_ULONG(130, 130, 130), "grey51" },
1693 { RGB_TO_ULONG(133, 133, 133), "gray52" },
1694 { RGB_TO_ULONG(133, 133, 133), "grey52" },
1695 { RGB_TO_ULONG(135, 135, 135), "gray53" },
1696 { RGB_TO_ULONG(135, 135, 135), "grey53" },
1697 { RGB_TO_ULONG(138, 138, 138), "gray54" },
1698 { RGB_TO_ULONG(138, 138, 138), "grey54" },
1699 { RGB_TO_ULONG(140, 140, 140), "gray55" },
1700 { RGB_TO_ULONG(140, 140, 140), "grey55" },
1701 { RGB_TO_ULONG(143, 143, 143), "gray56" },
1702 { RGB_TO_ULONG(143, 143, 143), "grey56" },
1703 { RGB_TO_ULONG(145, 145, 145), "gray57" },
1704 { RGB_TO_ULONG(145, 145, 145), "grey57" },
1705 { RGB_TO_ULONG(148, 148, 148), "gray58" },
1706 { RGB_TO_ULONG(148, 148, 148), "grey58" },
1707 { RGB_TO_ULONG(150, 150, 150), "gray59" },
1708 { RGB_TO_ULONG(150, 150, 150), "grey59" },
1709 { RGB_TO_ULONG(153, 153, 153), "gray60" },
1710 { RGB_TO_ULONG(153, 153, 153), "grey60" },
1711 { RGB_TO_ULONG(156, 156, 156), "gray61" },
1712 { RGB_TO_ULONG(156, 156, 156), "grey61" },
1713 { RGB_TO_ULONG(158, 158, 158), "gray62" },
1714 { RGB_TO_ULONG(158, 158, 158), "grey62" },
1715 { RGB_TO_ULONG(161, 161, 161), "gray63" },
1716 { RGB_TO_ULONG(161, 161, 161), "grey63" },
1717 { RGB_TO_ULONG(163, 163, 163), "gray64" },
1718 { RGB_TO_ULONG(163, 163, 163), "grey64" },
1719 { RGB_TO_ULONG(166, 166, 166), "gray65" },
1720 { RGB_TO_ULONG(166, 166, 166), "grey65" },
1721 { RGB_TO_ULONG(168, 168, 168), "gray66" },
1722 { RGB_TO_ULONG(168, 168, 168), "grey66" },
1723 { RGB_TO_ULONG(171, 171, 171), "gray67" },
1724 { RGB_TO_ULONG(171, 171, 171), "grey67" },
1725 { RGB_TO_ULONG(173, 173, 173), "gray68" },
1726 { RGB_TO_ULONG(173, 173, 173), "grey68" },
1727 { RGB_TO_ULONG(176, 176, 176), "gray69" },
1728 { RGB_TO_ULONG(176, 176, 176), "grey69" },
1729 { RGB_TO_ULONG(179, 179, 179), "gray70" },
1730 { RGB_TO_ULONG(179, 179, 179), "grey70" },
1731 { RGB_TO_ULONG(181, 181, 181), "gray71" },
1732 { RGB_TO_ULONG(181, 181, 181), "grey71" },
1733 { RGB_TO_ULONG(184, 184, 184), "gray72" },
1734 { RGB_TO_ULONG(184, 184, 184), "grey72" },
1735 { RGB_TO_ULONG(186, 186, 186), "gray73" },
1736 { RGB_TO_ULONG(186, 186, 186), "grey73" },
1737 { RGB_TO_ULONG(189, 189, 189), "gray74" },
1738 { RGB_TO_ULONG(189, 189, 189), "grey74" },
1739 { RGB_TO_ULONG(191, 191, 191), "gray75" },
1740 { RGB_TO_ULONG(191, 191, 191), "grey75" },
1741 { RGB_TO_ULONG(194, 194, 194), "gray76" },
1742 { RGB_TO_ULONG(194, 194, 194), "grey76" },
1743 { RGB_TO_ULONG(196, 196, 196), "gray77" },
1744 { RGB_TO_ULONG(196, 196, 196), "grey77" },
1745 { RGB_TO_ULONG(199, 199, 199), "gray78" },
1746 { RGB_TO_ULONG(199, 199, 199), "grey78" },
1747 { RGB_TO_ULONG(201, 201, 201), "gray79" },
1748 { RGB_TO_ULONG(201, 201, 201), "grey79" },
1749 { RGB_TO_ULONG(204, 204, 204), "gray80" },
1750 { RGB_TO_ULONG(204, 204, 204), "grey80" },
1751 { RGB_TO_ULONG(207, 207, 207), "gray81" },
1752 { RGB_TO_ULONG(207, 207, 207), "grey81" },
1753 { RGB_TO_ULONG(209, 209, 209), "gray82" },
1754 { RGB_TO_ULONG(209, 209, 209), "grey82" },
1755 { RGB_TO_ULONG(212, 212, 212), "gray83" },
1756 { RGB_TO_ULONG(212, 212, 212), "grey83" },
1757 { RGB_TO_ULONG(214, 214, 214), "gray84" },
1758 { RGB_TO_ULONG(214, 214, 214), "grey84" },
1759 { RGB_TO_ULONG(217, 217, 217), "gray85" },
1760 { RGB_TO_ULONG(217, 217, 217), "grey85" },
1761 { RGB_TO_ULONG(219, 219, 219), "gray86" },
1762 { RGB_TO_ULONG(219, 219, 219), "grey86" },
1763 { RGB_TO_ULONG(222, 222, 222), "gray87" },
1764 { RGB_TO_ULONG(222, 222, 222), "grey87" },
1765 { RGB_TO_ULONG(224, 224, 224), "gray88" },
1766 { RGB_TO_ULONG(224, 224, 224), "grey88" },
1767 { RGB_TO_ULONG(227, 227, 227), "gray89" },
1768 { RGB_TO_ULONG(227, 227, 227), "grey89" },
1769 { RGB_TO_ULONG(229, 229, 229), "gray90" },
1770 { RGB_TO_ULONG(229, 229, 229), "grey90" },
1771 { RGB_TO_ULONG(232, 232, 232), "gray91" },
1772 { RGB_TO_ULONG(232, 232, 232), "grey91" },
1773 { RGB_TO_ULONG(235, 235, 235), "gray92" },
1774 { RGB_TO_ULONG(235, 235, 235), "grey92" },
1775 { RGB_TO_ULONG(237, 237, 237), "gray93" },
1776 { RGB_TO_ULONG(237, 237, 237), "grey93" },
1777 { RGB_TO_ULONG(240, 240, 240), "gray94" },
1778 { RGB_TO_ULONG(240, 240, 240), "grey94" },
1779 { RGB_TO_ULONG(242, 242, 242), "gray95" },
1780 { RGB_TO_ULONG(242, 242, 242), "grey95" },
1781 { RGB_TO_ULONG(245, 245, 245), "gray96" },
1782 { RGB_TO_ULONG(245, 245, 245), "grey96" },
1783 { RGB_TO_ULONG(247, 247, 247), "gray97" },
1784 { RGB_TO_ULONG(247, 247, 247), "grey97" },
1785 { RGB_TO_ULONG(250, 250, 250), "gray98" },
1786 { RGB_TO_ULONG(250, 250, 250), "grey98" },
1787 { RGB_TO_ULONG(252, 252, 252), "gray99" },
1788 { RGB_TO_ULONG(252, 252, 252), "grey99" },
1789 { RGB_TO_ULONG(255, 255, 255), "gray100" },
1790 { RGB_TO_ULONG(255, 255, 255), "grey100" },
1791 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
1792 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
1793 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
1794 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
1795 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
1796 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
1797 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
1798 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
1799 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
1800 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
1801 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
1802 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1803 { RGB_TO_ULONG(144, 238, 144), "light green" },
1804 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1808 mac_color_map_lookup (colorname
)
1811 Lisp_Object ret
= Qnil
;
1816 for (i
= 0; i
< sizeof (mac_color_map
) / sizeof (mac_color_map
[0]); i
++)
1817 if (stricmp (colorname
, mac_color_map
[i
].name
) == 0)
1819 ret
= mac_color_map
[i
].color
;
1829 x_to_mac_color (colorname
)
1832 register Lisp_Object tail
, ret
= Qnil
;
1836 if (colorname
[0] == '#')
1838 /* Could be an old-style RGB Device specification. */
1841 color
= colorname
+ 1;
1843 size
= strlen(color
);
1844 if (size
== 3 || size
== 6 || size
== 9 || size
== 12)
1846 unsigned long colorval
;
1852 for (i
= 0; i
< 3; i
++)
1856 unsigned long value
;
1858 /* The check for 'x' in the following conditional takes into
1859 account the fact that strtol allows a "0x" in front of
1860 our numbers, and we don't. */
1861 if (!isxdigit(color
[0]) || color
[1] == 'x')
1865 value
= strtoul(color
, &end
, 16);
1867 if (errno
== ERANGE
|| end
- color
!= size
)
1872 value
= value
* 0x10;
1883 colorval
|= (value
<< pos
);
1894 else if (strnicmp(colorname
, "rgb:", 4) == 0)
1897 unsigned long colorval
;
1902 color
= colorname
+ 4;
1903 for (i
= 0; i
< 3; i
++)
1906 unsigned long value
;
1908 /* The check for 'x' in the following conditional takes into
1909 account the fact that strtol allows a "0x" in front of
1910 our numbers, and we don't. */
1911 if (!isxdigit(color
[0]) || color
[1] == 'x')
1913 value
= strtoul(color
, &end
, 16);
1914 if (errno
== ERANGE
)
1916 switch (end
- color
)
1919 value
= value
* 0x10 + value
;
1932 if (value
== ULONG_MAX
)
1934 colorval
|= (value
<< pos
);
1948 else if (strnicmp(colorname
, "rgbi:", 5) == 0)
1950 /* This is an RGB Intensity specification. */
1952 unsigned long colorval
;
1957 color
= colorname
+ 5;
1958 for (i
= 0; i
< 3; i
++)
1964 value
= strtod(color
, &end
);
1965 if (errno
== ERANGE
)
1967 if (value
< 0.0 || value
> 1.0)
1969 val
= (unsigned long)(0x100 * value
);
1970 /* We used 0x100 instead of 0xFF to give an continuous
1971 range between 0.0 and 1.0 inclusive. The next statement
1972 fixes the 1.0 case. */
1975 colorval
|= (val
<< pos
);
1990 ret
= mac_color_map_lookup (colorname
);
1996 /* Gamma-correct COLOR on frame F. */
1999 gamma_correct (f
, color
)
2001 unsigned long *color
;
2005 unsigned long red
, green
, blue
;
2007 red
= pow (RED_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2008 green
= pow (GREEN_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2009 blue
= pow (BLUE_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2010 *color
= RGB_TO_ULONG (red
, green
, blue
);
2014 /* Decide if color named COLOR is valid for the display associated
2015 with the selected frame; if so, return the rgb values in COLOR_DEF.
2016 If ALLOC is nonzero, allocate a new colormap cell. */
2019 mac_defined_color (f
, color
, color_def
, alloc
)
2025 register Lisp_Object tem
;
2026 unsigned long mac_color_ref
;
2028 tem
= x_to_mac_color (color
);
2034 /* Apply gamma correction. */
2035 mac_color_ref
= XUINT (tem
);
2036 gamma_correct (f
, &mac_color_ref
);
2037 XSETINT (tem
, mac_color_ref
);
2040 color_def
->pixel
= mac_color_ref
;
2041 color_def
->red
= RED_FROM_ULONG (mac_color_ref
);
2042 color_def
->green
= GREEN_FROM_ULONG (mac_color_ref
);
2043 color_def
->blue
= BLUE_FROM_ULONG (mac_color_ref
);
2053 /* Given a string ARG naming a color, compute a pixel value from it
2054 suitable for screen F.
2055 If F is not a color screen, return DEF (default) regardless of what
2059 x_decode_color (f
, arg
, def
)
2068 if (strcmp (SDATA (arg
), "black") == 0)
2069 return BLACK_PIX_DEFAULT (f
);
2070 else if (strcmp (SDATA (arg
), "white") == 0)
2071 return WHITE_PIX_DEFAULT (f
);
2074 if ((FRAME_MAC_DISPLAY_INFO (f
)->n_planes
2075 * FRAME_MAC_DISPLAY_INFO (f
)->n_cbits
) == 1)
2079 if (mac_defined_color (f
, SDATA (arg
), &cdef
, 1))
2082 /* defined_color failed; return an ultimate default. */
2086 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
2087 the previous value of that parameter, NEW_VALUE is the new value. */
2090 x_set_line_spacing (f
, new_value
, old_value
)
2092 Lisp_Object new_value
, old_value
;
2094 if (NILP (new_value
))
2095 f
->extra_line_spacing
= 0;
2096 else if (NATNUMP (new_value
))
2097 f
->extra_line_spacing
= XFASTINT (new_value
);
2099 Fsignal (Qerror
, Fcons (build_string ("Illegal line-spacing"),
2100 Fcons (new_value
, Qnil
)));
2101 if (FRAME_VISIBLE_P (f
))
2106 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
2107 the previous value of that parameter, NEW_VALUE is the new value. */
2110 x_set_screen_gamma (f
, new_value
, old_value
)
2112 Lisp_Object new_value
, old_value
;
2114 if (NILP (new_value
))
2116 else if (NUMBERP (new_value
) && XFLOATINT (new_value
) > 0)
2117 /* The value 0.4545 is the normal viewing gamma. */
2118 f
->gamma
= 1.0 / (0.4545 * XFLOATINT (new_value
));
2120 Fsignal (Qerror
, Fcons (build_string ("Illegal screen-gamma"),
2121 Fcons (new_value
, Qnil
)));
2123 clear_face_cache (0);
2127 /* Functions called only from `x_set_frame_param'
2128 to set individual parameters.
2130 If FRAME_MAC_WINDOW (f) is 0,
2131 the frame is being created and its window does not exist yet.
2132 In that case, just record the parameter's new value
2133 in the standard place; do not attempt to change the window. */
2136 x_set_foreground_color (f
, arg
, oldval
)
2138 Lisp_Object arg
, oldval
;
2140 FRAME_FOREGROUND_PIXEL (f
)
2141 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2143 if (FRAME_MAC_WINDOW (f
) != 0)
2145 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
2146 if (FRAME_VISIBLE_P (f
))
2152 x_set_background_color (f
, arg
, oldval
)
2154 Lisp_Object arg
, oldval
;
2156 FRAME_BACKGROUND_PIXEL (f
)
2157 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
2159 if (FRAME_MAC_WINDOW (f
) != 0)
2161 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
2163 if (FRAME_VISIBLE_P (f
))
2169 x_set_mouse_color (f
, arg
, oldval
)
2171 Lisp_Object arg
, oldval
;
2173 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
2177 if (!EQ (Qnil
, arg
))
2178 f
->output_data
.mac
->mouse_pixel
2179 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2180 mask_color
= FRAME_BACKGROUND_PIXEL (f
);
2182 /* Don't let pointers be invisible. */
2183 if (mask_color
== f
->output_data
.mac
->mouse_pixel
2184 && mask_color
== FRAME_BACKGROUND_PIXEL (f
))
2185 f
->output_data
.mac
->mouse_pixel
= FRAME_FOREGROUND_PIXEL (f
);
2187 #if 0 /* MAC_TODO : cursor changes */
2190 /* It's not okay to crash if the user selects a screwy cursor. */
2191 count
= x_catch_errors (FRAME_W32_DISPLAY (f
));
2193 if (!EQ (Qnil
, Vx_pointer_shape
))
2195 CHECK_NUMBER (Vx_pointer_shape
);
2196 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XINT (Vx_pointer_shape
));
2199 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
2200 x_check_errors (FRAME_W32_DISPLAY (f
), "bad text pointer cursor: %s");
2202 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
2204 CHECK_NUMBER (Vx_nontext_pointer_shape
);
2205 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2206 XINT (Vx_nontext_pointer_shape
));
2209 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_left_ptr
);
2210 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
2212 if (!EQ (Qnil
, Vx_hourglass_pointer_shape
))
2214 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
2215 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2216 XINT (Vx_hourglass_pointer_shape
));
2219 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_watch
);
2220 x_check_errors (FRAME_W32_DISPLAY (f
), "bad busy pointer cursor: %s");
2222 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
2223 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
2225 CHECK_NUMBER (Vx_mode_pointer_shape
);
2226 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2227 XINT (Vx_mode_pointer_shape
));
2230 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
2231 x_check_errors (FRAME_W32_DISPLAY (f
), "bad modeline pointer cursor: %s");
2233 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
2235 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
2237 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2238 XINT (Vx_sensitive_text_pointer_shape
));
2241 cross_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_crosshair
);
2243 if (!NILP (Vx_window_horizontal_drag_shape
))
2245 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
2246 horizontal_drag_cursor
2247 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2248 XINT (Vx_window_horizontal_drag_shape
));
2251 horizontal_drag_cursor
2252 = XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_sb_h_double_arrow
);
2254 /* Check and report errors with the above calls. */
2255 x_check_errors (FRAME_W32_DISPLAY (f
), "can't set cursor shape: %s");
2256 x_uncatch_errors (FRAME_W32_DISPLAY (f
), count
);
2259 XColor fore_color
, back_color
;
2261 fore_color
.pixel
= f
->output_data
.w32
->mouse_pixel
;
2262 back_color
.pixel
= mask_color
;
2263 XQueryColor (FRAME_W32_DISPLAY (f
),
2264 DefaultColormap (FRAME_W32_DISPLAY (f
),
2265 DefaultScreen (FRAME_W32_DISPLAY (f
))),
2267 XQueryColor (FRAME_W32_DISPLAY (f
),
2268 DefaultColormap (FRAME_W32_DISPLAY (f
),
2269 DefaultScreen (FRAME_W32_DISPLAY (f
))),
2271 XRecolorCursor (FRAME_W32_DISPLAY (f
), cursor
,
2272 &fore_color
, &back_color
);
2273 XRecolorCursor (FRAME_W32_DISPLAY (f
), nontext_cursor
,
2274 &fore_color
, &back_color
);
2275 XRecolorCursor (FRAME_W32_DISPLAY (f
), mode_cursor
,
2276 &fore_color
, &back_color
);
2277 XRecolorCursor (FRAME_W32_DISPLAY (f
), cross_cursor
,
2278 &fore_color
, &back_color
);
2279 XRecolorCursor (FRAME_W32_DISPLAY (f
), hourglass_cursor
,
2280 &fore_color
, &back_color
);
2283 if (FRAME_W32_WINDOW (f
) != 0)
2284 XDefineCursor (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), cursor
);
2286 if (cursor
!= f
->output_data
.w32
->text_cursor
&& f
->output_data
.w32
->text_cursor
!= 0)
2287 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->text_cursor
);
2288 f
->output_data
.w32
->text_cursor
= cursor
;
2290 if (nontext_cursor
!= f
->output_data
.w32
->nontext_cursor
2291 && f
->output_data
.w32
->nontext_cursor
!= 0)
2292 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->nontext_cursor
);
2293 f
->output_data
.w32
->nontext_cursor
= nontext_cursor
;
2295 if (hourglass_cursor
!= f
->output_data
.w32
->hourglass_cursor
2296 && f
->output_data
.w32
->hourglass_cursor
!= 0)
2297 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hourglass_cursor
);
2298 f
->output_data
.w32
->hourglass_cursor
= hourglass_cursor
;
2300 if (mode_cursor
!= f
->output_data
.w32
->modeline_cursor
2301 && f
->output_data
.w32
->modeline_cursor
!= 0)
2302 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->modeline_cursor
);
2303 f
->output_data
.w32
->modeline_cursor
= mode_cursor
;
2305 if (cross_cursor
!= f
->output_data
.w32
->cross_cursor
2306 && f
->output_data
.w32
->cross_cursor
!= 0)
2307 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->cross_cursor
);
2308 f
->output_data
.w32
->cross_cursor
= cross_cursor
;
2310 XFlush (FRAME_W32_DISPLAY (f
));
2313 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
2314 #endif /* MAC_TODO */
2318 x_set_cursor_color (f
, arg
, oldval
)
2320 Lisp_Object arg
, oldval
;
2322 unsigned long fore_pixel
;
2324 if (!NILP (Vx_cursor_fore_pixel
))
2325 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
2326 WHITE_PIX_DEFAULT (f
));
2328 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2329 f
->output_data
.mac
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2331 /* Make sure that the cursor color differs from the background color. */
2332 if (f
->output_data
.mac
->cursor_pixel
== FRAME_BACKGROUND_PIXEL (f
))
2334 f
->output_data
.mac
->cursor_pixel
= f
->output_data
.mac
->mouse_pixel
;
2335 if (f
->output_data
.mac
->cursor_pixel
== fore_pixel
)
2336 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2338 FRAME_FOREGROUND_PIXEL (f
) = fore_pixel
;
2340 #if 0 /* MAC_TODO: cannot figure out what to do (wrong number of params) */
2341 if (FRAME_MAC_WINDOW (f
) != 0)
2343 if (FRAME_VISIBLE_P (f
))
2345 x_display_cursor (f
, 0);
2346 x_display_cursor (f
, 1);
2351 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
2354 /* Set the border-color of frame F to pixel value PIX.
2355 Note that this does not fully take effect if done before
2358 x_set_border_pixel (f
, pix
)
2362 f
->output_data
.mac
->border_pixel
= pix
;
2364 if (FRAME_MAC_WINDOW (f
) != 0 && f
->output_data
.mac
->border_width
> 0)
2366 if (FRAME_VISIBLE_P (f
))
2371 /* Set the border-color of frame F to value described by ARG.
2372 ARG can be a string naming a color.
2373 The border-color is used for the border that is drawn by the server.
2374 Note that this does not fully take effect if done before
2375 F has a window; it must be redone when the window is created. */
2378 x_set_border_color (f
, arg
, oldval
)
2380 Lisp_Object arg
, oldval
;
2385 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2386 x_set_border_pixel (f
, pix
);
2387 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
2391 x_set_cursor_type (f
, arg
, oldval
)
2393 Lisp_Object arg
, oldval
;
2395 set_frame_cursor_types (f
, arg
);
2397 /* Make sure the cursor gets redrawn. This is overkill, but how
2398 often do people change cursor types? */
2399 update_mode_lines
++;
2402 #if 0 /* MAC_TODO: really no icon for Mac */
2404 x_set_icon_type (f
, arg
, oldval
)
2406 Lisp_Object arg
, oldval
;
2410 if (NILP (arg
) && NILP (oldval
))
2413 if (STRINGP (arg
) && STRINGP (oldval
)
2414 && EQ (Fstring_equal (oldval
, arg
), Qt
))
2417 if (SYMBOLP (arg
) && SYMBOLP (oldval
) && EQ (arg
, oldval
))
2422 result
= x_bitmap_icon (f
, arg
);
2426 error ("No icon window available");
2431 #endif /* MAC_TODO */
2433 /* Return non-nil if frame F wants a bitmap icon. */
2441 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
2449 x_set_icon_name (f
, arg
, oldval
)
2451 Lisp_Object arg
, oldval
;
2457 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
2460 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
2465 #if 0 /* MAC_TODO */
2466 if (f
->output_data
.w32
->icon_bitmap
!= 0)
2471 result
= x_text_icon (f
,
2472 (char *) SDATA ((!NILP (f
->icon_name
)
2481 error ("No icon window available");
2484 /* If the window was unmapped (and its icon was mapped),
2485 the new icon is not mapped, so map the window in its stead. */
2486 if (FRAME_VISIBLE_P (f
))
2488 #ifdef USE_X_TOOLKIT
2489 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
2491 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
2494 XFlush (FRAME_W32_DISPLAY (f
));
2496 #endif /* MAC_TODO */
2499 extern Lisp_Object
x_new_font ();
2500 extern Lisp_Object
x_new_fontset();
2503 x_set_font (f
, arg
, oldval
)
2505 Lisp_Object arg
, oldval
;
2508 Lisp_Object fontset_name
;
2510 int old_fontset
= FRAME_FONTSET(f
);
2514 fontset_name
= Fquery_fontset (arg
, Qnil
);
2517 result
= (STRINGP (fontset_name
)
2518 ? x_new_fontset (f
, SDATA (fontset_name
))
2519 : x_new_font (f
, SDATA (arg
)));
2522 if (EQ (result
, Qnil
))
2523 error ("Font `%s' is not defined", SDATA (arg
));
2524 else if (EQ (result
, Qt
))
2525 error ("The characters of the given font have varying widths");
2526 else if (STRINGP (result
))
2528 if (STRINGP (fontset_name
))
2530 /* Fontset names are built from ASCII font names, so the
2531 names may be equal despite there was a change. */
2532 if (old_fontset
== FRAME_FONTSET (f
))
2535 else if (!NILP (Fequal (result
, oldval
)))
2538 store_frame_param (f
, Qfont
, result
);
2539 recompute_basic_faces (f
);
2544 do_pending_window_change (0);
2546 /* Don't call `face-set-after-frame-default' when faces haven't been
2547 initialized yet. This is the case when called from
2548 Fx_create_frame. In that case, the X widget or window doesn't
2549 exist either, and we can end up in x_report_frame_params with a
2550 null widget which gives a segfault. */
2551 if (FRAME_FACE_CACHE (f
))
2553 XSETFRAME (frame
, f
);
2554 call1 (Qface_set_after_frame_default
, frame
);
2559 x_set_border_width (f
, arg
, oldval
)
2561 Lisp_Object arg
, oldval
;
2565 if (XINT (arg
) == f
->output_data
.mac
->border_width
)
2568 #if 0 /* MAC_TODO */
2569 if (FRAME_MAC_WINDOW (f
) != 0)
2570 error ("Cannot change the border width of a window");
2573 f
->output_data
.mac
->border_width
= XINT (arg
);
2577 x_set_internal_border_width (f
, arg
, oldval
)
2579 Lisp_Object arg
, oldval
;
2581 int old
= f
->output_data
.mac
->internal_border_width
;
2584 f
->output_data
.mac
->internal_border_width
= XINT (arg
);
2585 if (f
->output_data
.mac
->internal_border_width
< 0)
2586 f
->output_data
.mac
->internal_border_width
= 0;
2588 if (f
->output_data
.mac
->internal_border_width
== old
)
2591 if (FRAME_MAC_WINDOW (f
) != 0)
2593 x_set_window_size (f
, 0, f
->width
, f
->height
);
2594 SET_FRAME_GARBAGED (f
);
2595 do_pending_window_change (0);
2598 SET_FRAME_GARBAGED (f
);
2602 x_set_visibility (f
, value
, oldval
)
2604 Lisp_Object value
, oldval
;
2607 XSETFRAME (frame
, f
);
2610 Fmake_frame_invisible (frame
, Qt
);
2611 else if (EQ (value
, Qicon
))
2612 Ficonify_frame (frame
);
2614 Fmake_frame_visible (frame
);
2618 /* Change window heights in windows rooted in WINDOW by N lines. */
2621 x_change_window_heights (window
, n
)
2625 struct window
*w
= XWINDOW (window
);
2627 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
2628 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
2630 if (INTEGERP (w
->orig_top
))
2631 XSETFASTINT (w
->orig_top
, XFASTINT (w
->orig_top
) + n
);
2632 if (INTEGERP (w
->orig_height
))
2633 XSETFASTINT (w
->orig_height
, XFASTINT (w
->orig_height
) - n
);
2635 /* Handle just the top child in a vertical split. */
2636 if (!NILP (w
->vchild
))
2637 x_change_window_heights (w
->vchild
, n
);
2639 /* Adjust all children in a horizontal split. */
2640 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
2642 w
= XWINDOW (window
);
2643 x_change_window_heights (window
, n
);
2648 x_set_menu_bar_lines (f
, value
, oldval
)
2650 Lisp_Object value
, oldval
;
2653 int olines
= FRAME_MENU_BAR_LINES (f
);
2655 /* Right now, menu bars don't work properly in minibuf-only frames;
2656 most of the commands try to apply themselves to the minibuffer
2657 frame itself, and get an error because you can't switch buffers
2658 in or split the minibuffer window. */
2659 if (FRAME_MINIBUF_ONLY_P (f
))
2662 if (INTEGERP (value
))
2663 nlines
= XINT (value
);
2667 FRAME_MENU_BAR_LINES (f
) = 0;
2669 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
2672 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
2673 free_frame_menubar (f
);
2674 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
2676 /* Adjust the frame size so that the client (text) dimensions
2677 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
2679 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2680 do_pending_window_change (0);
2686 /* Set the number of lines used for the tool bar of frame F to VALUE.
2687 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
2688 is the old number of tool bar lines. This function changes the
2689 height of all windows on frame F to match the new tool bar height.
2690 The frame's height doesn't change. */
2693 x_set_tool_bar_lines (f
, value
, oldval
)
2695 Lisp_Object value
, oldval
;
2697 int delta
, nlines
, root_height
;
2698 Lisp_Object root_window
;
2700 /* Treat tool bars like menu bars. */
2701 if (FRAME_MINIBUF_ONLY_P (f
))
2704 /* Use VALUE only if an integer >= 0. */
2705 if (INTEGERP (value
) && XINT (value
) >= 0)
2706 nlines
= XFASTINT (value
);
2710 /* Make sure we redisplay all windows in this frame. */
2711 ++windows_or_buffers_changed
;
2713 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
2715 /* Don't resize the tool-bar to more than we have room for. */
2716 root_window
= FRAME_ROOT_WINDOW (f
);
2717 root_height
= XINT (XWINDOW (root_window
)->height
);
2718 if (root_height
- delta
< 1)
2720 delta
= root_height
- 1;
2721 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
2724 FRAME_TOOL_BAR_LINES (f
) = nlines
;
2725 x_change_window_heights (root_window
, delta
);
2728 /* We also have to make sure that the internal border at the top of
2729 the frame, below the menu bar or tool bar, is redrawn when the
2730 tool bar disappears. This is so because the internal border is
2731 below the tool bar if one is displayed, but is below the menu bar
2732 if there isn't a tool bar. The tool bar draws into the area
2733 below the menu bar. */
2734 if (FRAME_MAC_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
2738 clear_current_matrices (f
);
2739 updating_frame
= NULL
;
2742 /* If the tool bar gets smaller, the internal border below it
2743 has to be cleared. It was formerly part of the display
2744 of the larger tool bar, and updating windows won't clear it. */
2747 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
2748 int width
= PIXEL_WIDTH (f
);
2749 int y
= nlines
* CANON_Y_UNIT (f
);
2752 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2753 0, y
, width
, height
, 0);
2756 if (WINDOWP (f
->tool_bar_window
))
2757 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
2762 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
2765 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2766 name; if NAME is a string, set F's name to NAME and set
2767 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2769 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2770 suggesting a new name, which lisp code should override; if
2771 F->explicit_name is set, ignore the new name; otherwise, set it. */
2774 x_set_name (f
, name
, explicit)
2779 /* Make sure that requests from lisp code override requests from
2780 Emacs redisplay code. */
2783 /* If we're switching from explicit to implicit, we had better
2784 update the mode lines and thereby update the title. */
2785 if (f
->explicit_name
&& NILP (name
))
2786 update_mode_lines
= 1;
2788 f
->explicit_name
= ! NILP (name
);
2790 else if (f
->explicit_name
)
2793 /* If NAME is nil, set the name to the w32_id_name. */
2796 /* Check for no change needed in this very common case
2797 before we do any consing. */
2798 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
,
2801 name
= build_string (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
);
2804 CHECK_STRING (name
);
2806 /* Don't change the name if it's already NAME. */
2807 if (! NILP (Fstring_equal (name
, f
->name
)))
2812 /* For setting the frame title, the title parameter should override
2813 the name parameter. */
2814 if (! NILP (f
->title
))
2817 if (FRAME_MAC_WINDOW (f
))
2819 if (STRING_MULTIBYTE (name
))
2820 #if 0 /* MAC_TODO: encoding title string */
2821 name
= ENCODE_SYSTEM (name
);
2830 if (strlen (SDATA (name
)) < 255)
2832 strcpy (windowTitle
, SDATA (name
));
2833 c2pstr (windowTitle
);
2834 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2842 /* This function should be called when the user's lisp code has
2843 specified a name for the frame; the name will override any set by the
2846 x_explicitly_set_name (f
, arg
, oldval
)
2848 Lisp_Object arg
, oldval
;
2850 x_set_name (f
, arg
, 1);
2853 /* This function should be called by Emacs redisplay code to set the
2854 name; names set this way will never override names set by the user's
2857 x_implicitly_set_name (f
, arg
, oldval
)
2859 Lisp_Object arg
, oldval
;
2861 x_set_name (f
, arg
, 0);
2864 /* Change the title of frame F to NAME.
2865 If NAME is nil, use the frame name as the title.
2867 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2868 name; if NAME is a string, set F's name to NAME and set
2869 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2871 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2872 suggesting a new name, which lisp code should override; if
2873 F->explicit_name is set, ignore the new name; otherwise, set it. */
2876 x_set_title (f
, name
, old_name
)
2878 Lisp_Object name
, old_name
;
2880 /* Don't change the title if it's already NAME. */
2881 if (EQ (name
, f
->title
))
2884 update_mode_lines
= 1;
2891 if (FRAME_MAC_WINDOW (f
))
2893 if (STRING_MULTIBYTE (name
))
2894 #if 0 /* MAC_TODO: encoding title string */
2895 name
= ENCODE_SYSTEM (name
);
2904 if (strlen (SDATA (name
)) < 255)
2906 strcpy (windowTitle
, SDATA (name
));
2907 c2pstr (windowTitle
);
2908 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2917 x_set_autoraise (f
, arg
, oldval
)
2919 Lisp_Object arg
, oldval
;
2921 f
->auto_raise
= !EQ (Qnil
, arg
);
2925 x_set_autolower (f
, arg
, oldval
)
2927 Lisp_Object arg
, oldval
;
2929 f
->auto_lower
= !EQ (Qnil
, arg
);
2933 x_set_unsplittable (f
, arg
, oldval
)
2935 Lisp_Object arg
, oldval
;
2937 f
->no_split
= !NILP (arg
);
2941 x_set_vertical_scroll_bars (f
, arg
, oldval
)
2943 Lisp_Object arg
, oldval
;
2945 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
2946 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
2947 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
2948 || (!NILP (arg
) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
2950 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
)
2952 ? vertical_scroll_bar_none
2954 ? vertical_scroll_bar_right
2955 : vertical_scroll_bar_left
);
2957 /* We set this parameter before creating the window for the
2958 frame, so we can get the geometry right from the start.
2959 However, if the window hasn't been created yet, we shouldn't
2960 call x_set_window_size. */
2961 if (FRAME_MAC_WINDOW (f
))
2962 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2963 do_pending_window_change (0);
2968 x_set_scroll_bar_width (f
, arg
, oldval
)
2970 Lisp_Object arg
, oldval
;
2972 /* Imitate X without X Toolkit */
2974 int wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
2979 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 16; /* Aqua scroll bars. */
2980 FRAME_SCROLL_BAR_COLS (f
) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) +
2982 #else /* not MAC_OSX */
2983 /* Make the actual width at least 14 pixels and a multiple of a
2985 FRAME_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2987 /* Use all of that space (aside from required margins) for the
2989 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
2990 #endif /* not MAC_OSX */
2991 if (FRAME_MAC_WINDOW (f
))
2992 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2993 do_pending_window_change (0);
2995 else if (INTEGERP (arg
) && XINT (arg
) > 0
2996 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
2998 if (XFASTINT (arg
) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
2999 XSETINT (arg
, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
+ 1);
3001 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
3002 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
3003 if (FRAME_MAC_WINDOW (f
))
3004 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
3005 do_pending_window_change (0);
3007 change_frame_size (f
, 0, FRAME_WIDTH (f
), 0, 0, 0);
3008 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.hpos
= 0;
3009 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.x
= 0;
3012 /* Subroutines of creating an frame. */
3014 /* Make sure that Vx_resource_name is set to a reasonable value.
3015 Fix it up, or set it to `emacs' if it is too hopeless. */
3018 validate_x_resource_name ()
3021 /* Number of valid characters in the resource name. */
3023 /* Number of invalid characters in the resource name. */
3028 if (STRINGP (Vx_resource_name
))
3030 unsigned char *p
= SDATA (Vx_resource_name
);
3033 len
= SBYTES (Vx_resource_name
);
3035 /* Only letters, digits, - and _ are valid in resource names.
3036 Count the valid characters and count the invalid ones. */
3037 for (i
= 0; i
< len
; i
++)
3040 if (! ((c
>= 'a' && c
<= 'z')
3041 || (c
>= 'A' && c
<= 'Z')
3042 || (c
>= '0' && c
<= '9')
3043 || c
== '-' || c
== '_'))
3050 /* Not a string => completely invalid. */
3051 bad_count
= 5, good_count
= 0;
3053 /* If name is valid already, return. */
3057 /* If name is entirely invalid, or nearly so, use `emacs'. */
3059 || (good_count
== 1 && bad_count
> 0))
3061 Vx_resource_name
= build_string ("emacs");
3065 /* Name is partly valid. Copy it and replace the invalid characters
3066 with underscores. */
3068 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
3070 for (i
= 0; i
< len
; i
++)
3072 int c
= SREF (new, i
);
3073 if (! ((c
>= 'a' && c
<= 'z')
3074 || (c
>= 'A' && c
<= 'Z')
3075 || (c
>= '0' && c
<= '9')
3076 || c
== '-' || c
== '_'))
3082 #if 0 /* MAC_TODO: implement resource strings */
3083 extern char *x_get_string_resource ();
3085 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
3086 doc
: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3087 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3088 class, where INSTANCE is the name under which Emacs was invoked, or
3089 the name specified by the `-name' or `-rn' command-line arguments.
3091 The optional arguments COMPONENT and SUBCLASS add to the key and the
3092 class, respectively. You must specify both of them or neither.
3093 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3094 and the class is `Emacs.CLASS.SUBCLASS'. */)
3095 (attribute
, class, component
, subclass
)
3096 Lisp_Object attribute
, class, component
, subclass
;
3098 register char *value
;
3102 CHECK_STRING (attribute
);
3103 CHECK_STRING (class);
3105 if (!NILP (component
))
3106 CHECK_STRING (component
);
3107 if (!NILP (subclass
))
3108 CHECK_STRING (subclass
);
3109 if (NILP (component
) != NILP (subclass
))
3110 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3112 validate_x_resource_name ();
3114 /* Allocate space for the components, the dots which separate them,
3115 and the final '\0'. Make them big enough for the worst case. */
3116 name_key
= (char *) alloca (SBYTES (Vx_resource_name
)
3117 + (STRINGP (component
)
3118 ? SBYTES (component
) : 0)
3119 + SBYTES (attribute
)
3122 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
3124 + (STRINGP (subclass
)
3125 ? SBYTES (subclass
) : 0)
3128 /* Start with emacs.FRAMENAME for the name (the specific one)
3129 and with `Emacs' for the class key (the general one). */
3130 strcpy (name_key
, SDATA (Vx_resource_name
));
3131 strcpy (class_key
, EMACS_CLASS
);
3133 strcat (class_key
, ".");
3134 strcat (class_key
, SDATA (class));
3136 if (!NILP (component
))
3138 strcat (class_key
, ".");
3139 strcat (class_key
, SDATA (subclass
));
3141 strcat (name_key
, ".");
3142 strcat (name_key
, SDATA (component
));
3145 strcat (name_key
, ".");
3146 strcat (name_key
, SDATA (attribute
));
3148 value
= x_get_string_resource (Qnil
,
3149 name_key
, class_key
);
3151 if (value
!= (char *) 0)
3152 return build_string (value
);
3157 /* Used when C code wants a resource value. */
3160 x_get_resource_string (attribute
, class)
3161 char *attribute
, *class;
3165 struct frame
*sf
= SELECTED_FRAME ();
3167 /* Allocate space for the components, the dots which separate them,
3168 and the final '\0'. */
3169 name_key
= (char *) alloca (SBYTES (Vinvocation_name
)
3170 + strlen (attribute
) + 2);
3171 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
3172 + strlen (class) + 2);
3174 sprintf (name_key
, "%s.%s",
3175 SDATA (Vinvocation_name
),
3177 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
3179 return x_get_string_resource (sf
, name_key
, class_key
);
3181 #endif /* MAC_TODO */
3183 /* Types we might convert a resource string into. */
3193 /* Return the value of parameter PARAM.
3195 First search ALIST, then Vdefault_frame_alist, then the X defaults
3196 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3198 Convert the resource to the type specified by desired_type.
3200 If no default is specified, return Qunbound. If you call
3201 w32_get_arg, make sure you deal with Qunbound in a reasonable way,
3202 and don't let it get stored in any Lisp-visible variables! */
3205 mac_get_arg (alist
, param
, attribute
, class, type
)
3206 Lisp_Object alist
, param
;
3209 enum resource_types type
;
3211 register Lisp_Object tem
;
3213 tem
= Fassq (param
, alist
);
3215 tem
= Fassq (param
, Vdefault_frame_alist
);
3219 #if 0 /* MAC_TODO: search resource also */
3222 tem
= Fx_get_resource (build_string (attribute
),
3223 build_string (class),
3231 case RES_TYPE_NUMBER
:
3232 return make_number (atoi (SDATA (tem
)));
3234 case RES_TYPE_FLOAT
:
3235 return make_float (atof (SDATA (tem
)));
3237 case RES_TYPE_BOOLEAN
:
3238 tem
= Fdowncase (tem
);
3239 if (!strcmp (SDATA (tem
), "on")
3240 || !strcmp (SDATA (tem
), "true"))
3245 case RES_TYPE_STRING
:
3248 case RES_TYPE_SYMBOL
:
3249 /* As a special case, we map the values `true' and `on'
3250 to Qt, and `false' and `off' to Qnil. */
3253 lower
= Fdowncase (tem
);
3254 if (!strcmp (SDATA (lower
), "on")
3255 || !strcmp (SDATA (lower
), "true"))
3257 else if (!strcmp (SDATA (lower
), "off")
3258 || !strcmp (SDATA (lower
), "false"))
3261 return Fintern (tem
, Qnil
);
3269 #endif /* MAC_TODO */
3275 /* Record in frame F the specified or default value according to ALIST
3276 of the parameter named PROP (a Lisp symbol).
3277 If no value is specified for PROP, look for an X default for XPROP
3278 on the frame named NAME.
3279 If that is not found either, use the value DEFLT. */
3282 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
3289 enum resource_types type
;
3293 tem
= mac_get_arg (alist
, prop
, xprop
, xclass
, type
);
3294 if (EQ (tem
, Qunbound
))
3296 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
3300 /* XParseGeometry copied from w32xfns.c */
3303 * XParseGeometry parses strings of the form
3304 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
3305 * width, height, xoffset, and yoffset are unsigned integers.
3306 * Example: "=80x24+300-49"
3307 * The equal sign is optional.
3308 * It returns a bitmask that indicates which of the four values
3309 * were actually found in the string. For each value found,
3310 * the corresponding argument is updated; for each value
3311 * not found, the corresponding argument is left unchanged.
3315 read_integer (string
, NextString
)
3316 register char *string
;
3319 register int Result
= 0;
3324 else if (*string
== '-')
3329 for (; (*string
>= '0') && (*string
<= '9'); string
++)
3331 Result
= (Result
* 10) + (*string
- '0');
3333 *NextString
= string
;
3341 XParseGeometry (string
, x
, y
, width
, height
)
3344 unsigned int *width
, *height
; /* RETURN */
3347 register char *strind
;
3348 unsigned int tempWidth
, tempHeight
;
3350 char *nextCharacter
;
3352 if ((string
== NULL
) || (*string
== '\0')) return (mask
);
3354 string
++; /* ignore possible '=' at beg of geometry spec */
3356 strind
= (char *)string
;
3357 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
3359 tempWidth
= read_integer (strind
, &nextCharacter
);
3360 if (strind
== nextCharacter
)
3362 strind
= nextCharacter
;
3366 if (*strind
== 'x' || *strind
== 'X')
3369 tempHeight
= read_integer (strind
, &nextCharacter
);
3370 if (strind
== nextCharacter
)
3372 strind
= nextCharacter
;
3373 mask
|= HeightValue
;
3376 if ((*strind
== '+') || (*strind
== '-'))
3381 tempX
= -read_integer (strind
, &nextCharacter
);
3382 if (strind
== nextCharacter
)
3384 strind
= nextCharacter
;
3391 tempX
= read_integer (strind
, &nextCharacter
);
3392 if (strind
== nextCharacter
)
3394 strind
= nextCharacter
;
3397 if ((*strind
== '+') || (*strind
== '-'))
3402 tempY
= -read_integer (strind
, &nextCharacter
);
3403 if (strind
== nextCharacter
)
3405 strind
= nextCharacter
;
3412 tempY
= read_integer (strind
, &nextCharacter
);
3413 if (strind
== nextCharacter
)
3415 strind
= nextCharacter
;
3421 /* If strind isn't at the end of the string the it's an invalid
3422 geometry specification. */
3424 if (*strind
!= '\0') return (0);
3430 if (mask
& WidthValue
)
3432 if (mask
& HeightValue
)
3433 *height
= tempHeight
;
3437 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
3438 doc
: /* Parse an X-style geometry string STRING.
3439 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
3440 The properties returned may include `top', `left', `height', and `width'.
3441 The value of `left' or `top' may be an integer,
3442 or a list (+ N) meaning N pixels relative to top/left corner,
3443 or a list (- N) meaning -N pixels relative to bottom/right corner. */)
3448 unsigned int width
, height
;
3451 CHECK_STRING (string
);
3453 geometry
= XParseGeometry ((char *) SDATA (string
),
3454 &x
, &y
, &width
, &height
);
3457 if (geometry
& XValue
)
3459 Lisp_Object element
;
3461 if (x
>= 0 && (geometry
& XNegative
))
3462 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
3463 else if (x
< 0 && ! (geometry
& XNegative
))
3464 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
3466 element
= Fcons (Qleft
, make_number (x
));
3467 result
= Fcons (element
, result
);
3470 if (geometry
& YValue
)
3472 Lisp_Object element
;
3474 if (y
>= 0 && (geometry
& YNegative
))
3475 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
3476 else if (y
< 0 && ! (geometry
& YNegative
))
3477 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
3479 element
= Fcons (Qtop
, make_number (y
));
3480 result
= Fcons (element
, result
);
3483 if (geometry
& WidthValue
)
3484 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
3485 if (geometry
& HeightValue
)
3486 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
3491 /* Calculate the desired size and position of this window,
3492 and return the flags saying which aspects were specified.
3494 This function does not make the coordinates positive. */
3496 #define DEFAULT_ROWS 40
3497 #define DEFAULT_COLS 80
3500 x_figure_window_size (f
, parms
)
3504 register Lisp_Object tem0
, tem1
, tem2
;
3505 long window_prompting
= 0;
3507 /* Default values if we fall through.
3508 Actually, if that happens we should get
3509 window manager prompting. */
3510 SET_FRAME_WIDTH (f
, DEFAULT_COLS
);
3511 f
->height
= DEFAULT_ROWS
;
3512 /* Window managers expect that if program-specified
3513 positions are not (0,0), they're intentional, not defaults. */
3514 f
->output_data
.mac
->top_pos
= 0;
3515 f
->output_data
.mac
->left_pos
= 0;
3517 tem0
= mac_get_arg (parms
, Qheight
, 0, 0, RES_TYPE_NUMBER
);
3518 tem1
= mac_get_arg (parms
, Qwidth
, 0, 0, RES_TYPE_NUMBER
);
3519 tem2
= mac_get_arg (parms
, Quser_size
, 0, 0, RES_TYPE_NUMBER
);
3520 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
3522 if (!EQ (tem0
, Qunbound
))
3524 CHECK_NUMBER (tem0
);
3525 f
->height
= XINT (tem0
);
3527 if (!EQ (tem1
, Qunbound
))
3529 CHECK_NUMBER (tem1
);
3530 SET_FRAME_WIDTH (f
, XINT (tem1
));
3532 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
3533 window_prompting
|= USSize
;
3535 window_prompting
|= PSize
;
3538 f
->output_data
.mac
->vertical_scroll_bar_extra
3539 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
3541 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
3542 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
3543 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
3545 x_compute_fringe_widths (f
, 0);
3547 f
->output_data
.mac
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
3548 f
->output_data
.mac
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
3550 tem0
= mac_get_arg (parms
, Qtop
, 0, 0, RES_TYPE_NUMBER
);
3551 tem1
= mac_get_arg (parms
, Qleft
, 0, 0, RES_TYPE_NUMBER
);
3552 tem2
= mac_get_arg (parms
, Quser_position
, 0, 0, RES_TYPE_NUMBER
);
3553 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
3555 if (EQ (tem0
, Qminus
))
3557 f
->output_data
.mac
->top_pos
= 0;
3558 window_prompting
|= YNegative
;
3560 else if (CONSP (tem0
) && EQ (XCAR (tem0
), Qminus
)
3561 && CONSP (XCDR (tem0
))
3562 && INTEGERP (XCAR (XCDR (tem0
))))
3564 f
->output_data
.mac
->top_pos
= - XINT (XCAR (XCDR (tem0
)));
3565 window_prompting
|= YNegative
;
3567 else if (CONSP (tem0
) && EQ (XCAR (tem0
), Qplus
)
3568 && CONSP (XCDR (tem0
))
3569 && INTEGERP (XCAR (XCDR (tem0
))))
3571 f
->output_data
.mac
->top_pos
= XINT (XCAR (XCDR (tem0
)));
3573 else if (EQ (tem0
, Qunbound
))
3574 f
->output_data
.mac
->top_pos
= 0;
3577 CHECK_NUMBER (tem0
);
3578 f
->output_data
.mac
->top_pos
= XINT (tem0
);
3579 if (f
->output_data
.mac
->top_pos
< 0)
3580 window_prompting
|= YNegative
;
3583 if (EQ (tem1
, Qminus
))
3585 f
->output_data
.mac
->left_pos
= 0;
3586 window_prompting
|= XNegative
;
3588 else if (CONSP (tem1
) && EQ (XCAR (tem1
), Qminus
)
3589 && CONSP (XCDR (tem1
))
3590 && INTEGERP (XCAR (XCDR (tem1
))))
3592 f
->output_data
.mac
->left_pos
= - XINT (XCAR (XCDR (tem1
)));
3593 window_prompting
|= XNegative
;
3595 else if (CONSP (tem1
) && EQ (XCAR (tem1
), Qplus
)
3596 && CONSP (XCDR (tem1
))
3597 && INTEGERP (XCAR (XCDR (tem1
))))
3599 f
->output_data
.mac
->left_pos
= XINT (XCAR (XCDR (tem1
)));
3601 else if (EQ (tem1
, Qunbound
))
3602 f
->output_data
.mac
->left_pos
= 0;
3605 CHECK_NUMBER (tem1
);
3606 f
->output_data
.mac
->left_pos
= XINT (tem1
);
3607 if (f
->output_data
.mac
->left_pos
< 0)
3608 window_prompting
|= XNegative
;
3611 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
3612 window_prompting
|= USPosition
;
3614 window_prompting
|= PPosition
;
3617 return window_prompting
;
3621 #if 0 /* MAC_TODO */
3622 /* Create and set up the Mac window for frame F. */
3625 mac_window (f
, window_prompting
, minibuffer_only
)
3627 long window_prompting
;
3628 int minibuffer_only
;
3634 /* Use the resource name as the top-level window name
3635 for looking up resources. Make a non-Lisp copy
3636 for the window manager, so GC relocation won't bother it.
3638 Elsewhere we specify the window name for the window manager. */
3641 char *str
= (char *) SDATA (Vx_resource_name
);
3642 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
3643 strcpy (f
->namebuf
, str
);
3646 SetRect (&r
, f
->output_data
.mac
->left_pos
, f
->output_data
.mac
->top_pos
,
3647 f
->output_data
.mac
->left_pos
+ PIXEL_WIDTH (f
),
3648 f
->output_data
.mac
->top_pos
+ PIXEL_HEIGHT (f
));
3649 FRAME_MAC_WINDOW (f
)
3650 = NewCWindow (NULL
, &r
, "\p", 1, zoomDocProc
, (WindowPtr
) -1, 1, (long) f
->output_data
.mac
);
3652 validate_x_resource_name ();
3654 /* x_set_name normally ignores requests to set the name if the
3655 requested name is the same as the current name. This is the one
3656 place where that assumption isn't correct; f->name is set, but
3657 the server hasn't been told. */
3660 int explicit = f
->explicit_name
;
3662 f
->explicit_name
= 0;
3665 x_set_name (f
, name
, explicit);
3668 ShowWindow (FRAME_MAC_WINDOW (f
));
3672 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3673 initialize_frame_menubar (f
);
3675 if (FRAME_MAC_WINDOW (f
) == 0)
3676 error ("Unable to create window");
3678 #endif /* MAC_TODO */
3680 /* Handle the icon stuff for this window. Perhaps later we might
3681 want an x_set_icon_position which can be called interactively as
3689 Lisp_Object icon_x
, icon_y
;
3691 /* Set the position of the icon. Note that Windows 95 groups all
3692 icons in the tray. */
3693 icon_x
= mac_get_arg (parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
3694 icon_y
= mac_get_arg (parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
3695 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
3697 CHECK_NUMBER (icon_x
);
3698 CHECK_NUMBER (icon_y
);
3700 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
3701 error ("Both left and top icon corners of icon must be specified");
3705 if (! EQ (icon_x
, Qunbound
))
3706 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
3709 /* Start up iconic or window? */
3710 x_wm_set_window_state
3711 (f
, (EQ (w32_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
), Qicon
)
3715 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
3728 XGCValues gc_values
;
3732 /* Create the GC's of this frame.
3733 Note that many default values are used. */
3736 gc_values
.font
= f
->output_data
.mac
->font
;
3737 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
3738 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
3739 f
->output_data
.mac
->normal_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3740 FRAME_MAC_WINDOW (f
),
3741 GCFont
| GCForeground
| GCBackground
,
3744 /* Reverse video style. */
3745 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3746 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
3747 f
->output_data
.mac
->reverse_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3748 FRAME_MAC_WINDOW (f
),
3749 GCFont
| GCForeground
| GCBackground
,
3752 /* Cursor has cursor-color background, background-color foreground. */
3753 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3754 gc_values
.background
= f
->output_data
.mac
->cursor_pixel
;
3755 f
->output_data
.mac
->cursor_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3756 FRAME_MAC_WINDOW (f
),
3757 GCFont
| GCForeground
| GCBackground
,
3761 f
->output_data
.mac
->white_relief
.gc
= 0;
3762 f
->output_data
.mac
->black_relief
.gc
= 0;
3768 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3770 doc
: /* Make a new window, which is called a \"frame\" in Emacs terms.
3771 Returns an Emacs frame object.
3772 ALIST is an alist of frame parameters.
3773 If the parameters specify that the frame should not have a minibuffer,
3774 and do not specify a specific minibuffer window to use,
3775 then `default-minibuffer-frame' must be a frame whose minibuffer can
3776 be shared by the new frame.
3778 This function is an internal primitive--use `make-frame' instead. */)
3783 Lisp_Object frame
, tem
;
3785 int minibuffer_only
= 0;
3786 long window_prompting
= 0;
3788 int count
= SPECPDL_INDEX ();
3789 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3790 Lisp_Object display
;
3791 struct mac_display_info
*dpyinfo
= NULL
;
3794 char x_frame_name
[10];
3795 static int x_frame_count
= 2; /* begins at 2 because terminal frame is F1 */
3799 /* Use this general default value to start with
3800 until we know if this frame has a specified name. */
3801 Vx_resource_name
= Vinvocation_name
;
3803 display
= mac_get_arg (parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3804 if (EQ (display
, Qunbound
))
3806 dpyinfo
= check_x_display_info (display
);
3808 kb
= dpyinfo
->kboard
;
3810 kb
= &the_only_kboard
;
3813 name
= mac_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3815 && ! EQ (name
, Qunbound
)
3817 error ("Invalid frame name--not a string or nil");
3820 Vx_resource_name
= name
;
3822 /* See if parent window is specified. */
3823 parent
= mac_get_arg (parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3824 if (EQ (parent
, Qunbound
))
3826 if (! NILP (parent
))
3827 CHECK_NUMBER (parent
);
3829 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3830 /* No need to protect DISPLAY because that's not used after passing
3831 it to make_frame_without_minibuffer. */
3833 GCPRO4 (parms
, parent
, name
, frame
);
3834 tem
= mac_get_arg (parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3836 if (EQ (tem
, Qnone
) || NILP (tem
))
3837 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3838 else if (EQ (tem
, Qonly
))
3840 f
= make_minibuffer_frame ();
3841 minibuffer_only
= 1;
3843 else if (WINDOWP (tem
))
3844 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3848 if (EQ (name
, Qunbound
) || NILP (name
))
3850 sprintf (x_frame_name
, "F%d", x_frame_count
++);
3851 f
->name
= build_string (x_frame_name
);
3852 f
->explicit_name
= 0;
3857 f
->explicit_name
= 1;
3860 XSETFRAME (frame
, f
);
3862 /* Note that X Windows does support scroll bars. */
3863 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3865 f
->output_method
= output_mac
;
3866 f
->output_data
.mac
= (struct mac_output
*) xmalloc (sizeof (struct mac_output
));
3867 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
3868 FRAME_FONTSET (f
) = -1;
3869 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
3870 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
3873 FRAME_FONTSET (f
) = -1;
3877 = mac_get_arg (parms
, Qicon_name
, "iconName", "Title", RES_TYPE_STRING
);
3878 if (! STRINGP (f
->icon_name
))
3879 f
->icon_name
= Qnil
;
3881 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
3883 FRAME_KBOARD (f
) = kb
;
3886 /* Specify the parent under which to make this window. */
3890 f
->output_data
.mac
->parent_desc
= (Window
) parent
;
3891 f
->output_data
.mac
->explicit_parent
= 1;
3895 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
3896 f
->output_data
.mac
->explicit_parent
= 0;
3899 /* Set the name; the functions to which we pass f expect the name to
3901 if (EQ (name
, Qunbound
) || NILP (name
))
3903 f
->name
= build_string (dpyinfo
->mac_id_name
);
3904 f
->explicit_name
= 0;
3909 f
->explicit_name
= 1;
3910 /* use the frame's title when getting resources for this frame. */
3911 specbind (Qx_resource_name
, name
);
3914 /* Extract the window parameters from the supplied values
3915 that are needed to determine window geometry. */
3919 font
= mac_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3922 /* First, try whatever font the caller has specified. */
3925 tem
= Fquery_fontset (font
, Qnil
);
3927 font
= x_new_fontset (f
, SDATA (tem
));
3929 font
= x_new_font (f
, SDATA (font
));
3931 /* Try out a font which we hope has bold and italic variations. */
3932 if (! STRINGP (font
))
3933 font
= x_new_font (f
, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
3934 /* If those didn't work, look for something which will at least work. */
3935 if (!STRINGP (font
))
3936 font
= x_new_font (f
, "-*-monaco-*-12-*-mac-roman");
3937 if (! STRINGP (font
))
3938 font
= x_new_font (f
, "-*-courier-*-10-*-mac-roman");
3939 if (! STRINGP (font
))
3940 error ("Cannot find any usable font");
3943 x_default_parameter (f
, parms
, Qfont
, font
,
3944 "font", "Font", RES_TYPE_STRING
);
3947 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
3948 "borderwidth", "BorderWidth", RES_TYPE_NUMBER
);
3949 /* This defaults to 2 in order to match xterm. We recognize either
3950 internalBorderWidth or internalBorder (which is what xterm calls
3952 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3956 value
= mac_get_arg (parms
, Qinternal_border_width
,
3957 "internalBorder", "InternalBorder", RES_TYPE_NUMBER
);
3958 if (! EQ (value
, Qunbound
))
3959 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3962 /* Default internalBorderWidth to 0 on Windows to match other programs. */
3963 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (0),
3964 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER
);
3965 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qright
,
3966 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL
);
3968 /* Also do the stuff which must be set before the window exists. */
3969 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3970 "foreground", "Foreground", RES_TYPE_STRING
);
3971 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3972 "background", "Background", RES_TYPE_STRING
);
3973 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3974 "pointerColor", "Foreground", RES_TYPE_STRING
);
3975 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3976 "cursorColor", "Foreground", RES_TYPE_STRING
);
3977 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3978 "borderColor", "BorderColor", RES_TYPE_STRING
);
3979 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3980 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3981 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3982 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3983 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3984 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3985 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3986 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3989 /* Init faces before x_default_parameter is called for scroll-bar
3990 parameters because that function calls x_set_scroll_bar_width,
3991 which calls change_frame_size, which calls Fset_window_buffer,
3992 which runs hooks, which call Fvertical_motion. At the end, we
3993 end up in init_iterator with a null face cache, which should not
3995 init_frame_faces (f
);
3997 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3998 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3999 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (0),
4000 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
4001 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
4002 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL
);
4003 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
4004 "title", "Title", RES_TYPE_STRING
);
4006 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
4007 window_prompting
= x_figure_window_size (f
, parms
);
4009 if (window_prompting
& XNegative
)
4011 if (window_prompting
& YNegative
)
4012 f
->output_data
.mac
->win_gravity
= SouthEastGravity
;
4014 f
->output_data
.mac
->win_gravity
= NorthEastGravity
;
4018 if (window_prompting
& YNegative
)
4019 f
->output_data
.mac
->win_gravity
= SouthWestGravity
;
4021 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
4024 f
->output_data
.mac
->size_hint_flags
= window_prompting
;
4026 tem
= mac_get_arg (parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
4027 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
4029 /* Create the window. Add the tool-bar height to the initial frame
4030 height so that the user gets a text display area of the size he
4031 specified with -g or via the registry. Later changes of the
4032 tool-bar height don't change the frame size. This is done so that
4033 users can create tall Emacs frames without having to guess how
4034 tall the tool-bar will get. */
4035 f
->height
+= FRAME_TOOL_BAR_LINES (f
);
4037 /* mac_window (f, window_prompting, minibuffer_only); */
4044 /* Now consider the frame official. */
4045 FRAME_MAC_DISPLAY_INFO (f
)->reference_count
++;
4046 Vframe_list
= Fcons (frame
, Vframe_list
);
4048 /* We need to do this after creating the window, so that the
4049 icon-creation functions can say whose icon they're describing. */
4050 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
4051 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
4053 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
4054 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4055 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
4056 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4057 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
4058 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
4059 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
4060 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER
);
4062 /* Dimensions, especially f->height, must be done via change_frame_size.
4063 Change will not be effected unless different from the current
4069 SET_FRAME_WIDTH (f
, 0);
4070 change_frame_size (f
, height
, width
, 1, 0, 0);
4072 /* Set up faces after all frame parameters are known. */
4073 call1 (Qface_set_after_frame_default
, frame
);
4075 #if 0 /* MAC_TODO: when we have window manager hints */
4076 /* Tell the server what size and position, etc, we want, and how
4077 badly we want them. This should be done after we have the menu
4078 bar so that its size can be taken into account. */
4080 x_wm_set_size_hint (f
, window_prompting
, 0);
4084 /* Make the window appear on the frame and enable display, unless
4085 the caller says not to. However, with explicit parent, Emacs
4086 cannot control visibility, so don't try. */
4087 if (! f
->output_data
.mac
->explicit_parent
)
4089 Lisp_Object visibility
;
4091 visibility
= mac_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
);
4092 if (EQ (visibility
, Qunbound
))
4095 #if 0 /* MAC_TODO: really no iconify on Mac */
4096 if (EQ (visibility
, Qicon
))
4097 x_iconify_frame (f
);
4100 if (! NILP (visibility
))
4101 x_make_frame_visible (f
);
4103 /* Must have been Qnil. */
4108 /* Make sure windows on this frame appear in calls to next-window
4109 and similar functions. */
4110 Vwindow_list
= Qnil
;
4112 return unbind_to (count
, frame
);
4115 /* FRAME is used only to get a handle on the X display. We don't pass the
4116 display info directly because we're called from frame.c, which doesn't
4117 know about that structure. */
4119 x_get_focus_frame (frame
)
4120 struct frame
*frame
;
4122 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
4124 if (! dpyinfo
->x_focus_frame
)
4127 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
4131 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
4132 doc
: /* Internal function called by `color-defined-p', which see. */)
4134 Lisp_Object color
, frame
;
4137 FRAME_PTR f
= check_x_frame (frame
);
4139 CHECK_STRING (color
);
4141 if (mac_defined_color (f
, SDATA (color
), &foo
, 0))
4147 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
4148 doc
: /* Internal function called by `color-values', which see. */)
4150 Lisp_Object color
, frame
;
4153 FRAME_PTR f
= check_x_frame (frame
);
4155 CHECK_STRING (color
);
4157 if (mac_defined_color (f
, SDATA (color
), &foo
, 0))
4161 rgb
[0] = make_number ((RED_FROM_ULONG (foo
.pixel
) << 8)
4162 | RED_FROM_ULONG (foo
.pixel
));
4163 rgb
[1] = make_number ((GREEN_FROM_ULONG (foo
.pixel
) << 8)
4164 | GREEN_FROM_ULONG (foo
.pixel
));
4165 rgb
[2] = make_number ((BLUE_FROM_ULONG (foo
.pixel
) << 8)
4166 | BLUE_FROM_ULONG (foo
.pixel
));
4167 return Flist (3, rgb
);
4173 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
4174 doc
: /* Internal function called by `display-color-p', which see. */)
4176 Lisp_Object display
;
4178 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4180 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 2)
4186 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
4188 doc
: /* Return t if the X display supports shades of gray.
4189 Note that color displays do support shades of gray.
4190 The optional argument DISPLAY specifies which display to ask about.
4191 DISPLAY should be either a frame or a display name (a string).
4192 If omitted or nil, that stands for the selected frame's display. */)
4194 Lisp_Object display
;
4196 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4198 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 1)
4204 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
4206 doc
: /* Returns the width in pixels of the X display DISPLAY.
4207 The optional argument DISPLAY specifies which display to ask about.
4208 DISPLAY should be either a frame or a display name (a string).
4209 If omitted or nil, that stands for the selected frame's display. */)
4211 Lisp_Object display
;
4213 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4215 return make_number (dpyinfo
->width
);
4218 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
4219 Sx_display_pixel_height
, 0, 1, 0,
4220 doc
: /* Returns the height in pixels of the X display DISPLAY.
4221 The optional argument DISPLAY specifies which display to ask about.
4222 DISPLAY should be either a frame or a display name (a string).
4223 If omitted or nil, that stands for the selected frame's display. */)
4225 Lisp_Object display
;
4227 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4229 return make_number (dpyinfo
->height
);
4232 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
4234 doc
: /* Returns the number of bitplanes of the display DISPLAY.
4235 The optional argument DISPLAY specifies which display to ask about.
4236 DISPLAY should be either a frame or a display name (a string).
4237 If omitted or nil, that stands for the selected frame's display. */)
4239 Lisp_Object display
;
4241 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4243 return make_number (dpyinfo
->n_planes
* dpyinfo
->n_cbits
);
4246 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
4248 doc
: /* Returns the number of color cells of the display DISPLAY.
4249 The optional argument DISPLAY specifies which display to ask about.
4250 DISPLAY should be either a frame or a display name (a string).
4251 If omitted or nil, that stands for the selected frame's display. */)
4253 Lisp_Object display
;
4255 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4257 /* MAC_TODO: check whether this is right */
4258 return make_number ((unsigned long) (pow (2, dpyinfo
->n_cbits
)));
4261 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
4262 Sx_server_max_request_size
,
4264 doc
: /* Returns the maximum request size of the server of display DISPLAY.
4265 The optional argument DISPLAY specifies which display to ask about.
4266 DISPLAY should be either a frame or a display name (a string).
4267 If omitted or nil, that stands for the selected frame's display. */)
4269 Lisp_Object display
;
4271 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4273 return make_number (1);
4276 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
4277 doc
: /* Returns the vendor ID string of the Mac OS system (Apple).
4278 The optional argument DISPLAY specifies which display to ask about.
4279 DISPLAY should be either a frame or a display name (a string).
4280 If omitted or nil, that stands for the selected frame's display. */)
4282 Lisp_Object display
;
4284 return build_string ("Apple Computers");
4287 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
4288 doc
: /* Returns the version numbers of the server of display DISPLAY.
4289 The value is a list of three integers: the major and minor
4290 version numbers, and the vendor-specific release
4291 number. See also the function `x-server-vendor'.
4293 The optional argument DISPLAY specifies which display to ask about.
4294 DISPLAY should be either a frame or a display name (a string).
4295 If omitted or nil, that stands for the selected frame's display. */)
4297 Lisp_Object display
;
4299 int mac_major_version
, mac_minor_version
;
4302 if (Gestalt (gestaltSystemVersion
, &response
) != noErr
)
4303 error ("Cannot get Mac OS version");
4305 mac_major_version
= (response
>> 8) & 0xf;
4306 mac_minor_version
= (response
>> 4) & 0xf;
4308 return Fcons (make_number (mac_major_version
),
4309 Fcons (make_number (mac_minor_version
), Qnil
));
4312 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
4313 doc
: /* Return the number of screens on the server of display DISPLAY.
4314 The optional argument DISPLAY specifies which display to ask about.
4315 DISPLAY should be either a frame or a display name (a string).
4316 If omitted or nil, that stands for the selected frame's display. */)
4318 Lisp_Object display
;
4320 return make_number (1);
4323 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
4324 doc
: /* Return the height in millimeters of the X display DISPLAY.
4325 The optional argument DISPLAY specifies which display to ask about.
4326 DISPLAY should be either a frame or a display name (a string).
4327 If omitted or nil, that stands for the selected frame's display. */)
4329 Lisp_Object display
;
4331 /* MAC_TODO: this is an approximation, and only of the main display */
4333 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4338 return make_number ((int) (v
/ 72.0 * 25.4));
4341 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
4342 doc
: /* Return the width in millimeters of the X display DISPLAY.
4343 The optional argument DISPLAY specifies which display to ask about.
4344 DISPLAY should be either a frame or a display name (a string).
4345 If omitted or nil, that stands for the selected frame's display. */)
4347 Lisp_Object display
;
4349 /* MAC_TODO: this is an approximation, and only of the main display */
4351 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4356 return make_number ((int) (h
/ 72.0 * 25.4));
4359 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
4360 Sx_display_backing_store
, 0, 1, 0,
4361 doc
: /* Returns an indication of whether display DISPLAY does backing store.
4362 The value may be `always', `when-mapped', or `not-useful'.
4363 The optional argument DISPLAY specifies which display to ask about.
4364 DISPLAY should be either a frame or a display name (a string).
4365 If omitted or nil, that stands for the selected frame's display. */)
4367 Lisp_Object display
;
4369 return intern ("not-useful");
4372 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
4373 Sx_display_visual_class
, 0, 1, 0,
4374 doc
: /* Returns the visual class of the display DISPLAY.
4375 The value is one of the symbols `static-gray', `gray-scale',
4376 `static-color', `pseudo-color', `true-color', or `direct-color'.
4378 The optional argument DISPLAY specifies which display to ask about.
4379 DISPLAY should be either a frame or a display name (a string).
4380 If omitted or nil, that stands for the selected frame's display. */)
4382 Lisp_Object display
;
4384 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4387 switch (dpyinfo
->visual
->class)
4389 case StaticGray
: return (intern ("static-gray"));
4390 case GrayScale
: return (intern ("gray-scale"));
4391 case StaticColor
: return (intern ("static-color"));
4392 case PseudoColor
: return (intern ("pseudo-color"));
4393 case TrueColor
: return (intern ("true-color"));
4394 case DirectColor
: return (intern ("direct-color"));
4396 error ("Display has an unknown visual class");
4400 return (intern ("true-color"));
4403 DEFUN ("x-display-save-under", Fx_display_save_under
,
4404 Sx_display_save_under
, 0, 1, 0,
4405 doc
: /* Returns t if the display DISPLAY supports the save-under feature.
4406 The optional argument DISPLAY specifies which display to ask about.
4407 DISPLAY should be either a frame or a display name (a string).
4408 If omitted or nil, that stands for the selected frame's display. */)
4410 Lisp_Object display
;
4417 register struct frame
*f
;
4419 return PIXEL_WIDTH (f
);
4424 register struct frame
*f
;
4426 return PIXEL_HEIGHT (f
);
4431 register struct frame
*f
;
4433 return FONT_WIDTH (f
->output_data
.mac
->font
);
4438 register struct frame
*f
;
4440 return f
->output_data
.mac
->line_height
;
4445 register struct frame
*f
;
4447 return FRAME_MAC_DISPLAY_INFO (f
)->n_planes
;
4450 /* Return the display structure for the display named NAME.
4451 Open a new connection if necessary. */
4453 struct mac_display_info
*
4454 x_display_info_for_name (name
)
4458 struct mac_display_info
*dpyinfo
;
4460 CHECK_STRING (name
);
4462 for (dpyinfo
= &one_mac_display_info
, names
= x_display_name_list
;
4464 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4467 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4472 /* Use this general default value to start with. */
4473 Vx_resource_name
= Vinvocation_name
;
4475 validate_x_resource_name ();
4477 dpyinfo
= mac_term_init (name
, (unsigned char *) 0,
4478 (char *) SDATA (Vx_resource_name
));
4481 error ("Cannot connect to server %s", SDATA (name
));
4484 XSETFASTINT (Vwindow_system_version
, 3);
4489 #if 0 /* MAC_TODO: implement network support */
4490 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4492 doc
: /* Open a connection to a server.
4493 DISPLAY is the name of the display to connect to.
4494 Optional second arg XRM-STRING is a string of resources in xrdb format.
4495 If the optional third arg MUST-SUCCEED is non-nil,
4496 terminate Emacs if we can't open the connection. */)
4497 (display
, xrm_string
, must_succeed
)
4498 Lisp_Object display
, xrm_string
, must_succeed
;
4500 unsigned char *xrm_option
;
4501 struct mac_display_info
*dpyinfo
;
4503 CHECK_STRING (display
);
4504 if (! NILP (xrm_string
))
4505 CHECK_STRING (xrm_string
);
4507 if (! EQ (Vwindow_system
, intern ("mac")))
4508 error ("Not using Mac OS");
4510 if (! NILP (xrm_string
))
4511 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4513 xrm_option
= (unsigned char *) 0;
4515 validate_x_resource_name ();
4517 /* This is what opens the connection and sets x_current_display.
4518 This also initializes many symbols, such as those used for input. */
4519 dpyinfo
= mac_term_init (display
, xrm_option
,
4520 (char *) SDATA (Vx_resource_name
));
4524 if (!NILP (must_succeed
))
4525 fatal ("Cannot connect to server %s.\n",
4528 error ("Cannot connect to server %s", SDATA (display
));
4533 XSETFASTINT (Vwindow_system_version
, 3);
4537 DEFUN ("x-close-connection", Fx_close_connection
,
4538 Sx_close_connection
, 1, 1, 0,
4539 doc
: /* Close the connection to DISPLAY's server.
4540 For DISPLAY, specify either a frame or a display name (a string).
4541 If DISPLAY is nil, that stands for the selected frame's display. */)
4543 Lisp_Object display
;
4545 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4548 if (dpyinfo
->reference_count
> 0)
4549 error ("Display still has frames on it");
4552 /* Free the fonts in the font table. */
4553 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4554 if (dpyinfo
->font_table
[i
].name
)
4556 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
4557 xfree (dpyinfo
->font_table
[i
].full_name
);
4558 xfree (dpyinfo
->font_table
[i
].name
);
4559 x_unload_font (dpyinfo
, dpyinfo
->font_table
[i
].font
);
4561 x_destroy_all_bitmaps (dpyinfo
);
4563 x_delete_display (dpyinfo
);
4570 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4571 doc
: /* Return the list of display names that Emacs has connections to. */)
4574 Lisp_Object tail
, result
;
4577 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4578 result
= Fcons (XCAR (XCAR (tail
)), result
);
4583 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4584 doc
: /* If ON is non-nil, report errors as soon as the erring request is made.
4585 If ON is nil, allow buffering of requests.
4586 This is a noop on Mac OS systems.
4587 The optional second argument DISPLAY specifies which display to act on.
4588 DISPLAY should be either a frame or a display name (a string).
4589 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4591 Lisp_Object display
, on
;
4597 /***********************************************************************
4599 ***********************************************************************/
4601 /* Value is the number of elements of vector VECTOR. */
4603 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4605 /* List of supported image types. Use define_image_type to add new
4606 types. Use lookup_image_type to find a type for a given symbol. */
4608 static struct image_type
*image_types
;
4610 /* The symbol `image' which is the car of the lists used to represent
4613 extern Lisp_Object Qimage
;
4615 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4621 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4622 extern Lisp_Object QCdata
, QCtype
;
4623 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4624 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4625 Lisp_Object QCindex
;
4627 /* Other symbols. */
4629 Lisp_Object Qlaplace
;
4631 /* Time in seconds after which images should be removed from the cache
4632 if not displayed. */
4634 Lisp_Object Vimage_cache_eviction_delay
;
4636 /* Function prototypes. */
4638 static void define_image_type
P_ ((struct image_type
*type
));
4639 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4640 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4641 static void x_laplace
P_ ((struct frame
*, struct image
*));
4642 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4646 /* Define a new image type from TYPE. This adds a copy of TYPE to
4647 image_types and adds the symbol *TYPE->type to Vimage_types. */
4650 define_image_type (type
)
4651 struct image_type
*type
;
4653 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4654 The initialized data segment is read-only. */
4655 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4656 bcopy (type
, p
, sizeof *p
);
4657 p
->next
= image_types
;
4659 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4663 /* Look up image type SYMBOL, and return a pointer to its image_type
4664 structure. Value is null if SYMBOL is not a known image type. */
4666 static INLINE
struct image_type
*
4667 lookup_image_type (symbol
)
4670 struct image_type
*type
;
4672 for (type
= image_types
; type
; type
= type
->next
)
4673 if (EQ (symbol
, *type
->type
))
4680 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4681 valid image specification is a list whose car is the symbol
4682 `image', and whose rest is a property list. The property list must
4683 contain a value for key `:type'. That value must be the name of a
4684 supported image type. The rest of the property list depends on the
4688 valid_image_p (object
)
4693 if (CONSP (object
) && EQ (XCAR (object
), Qimage
))
4695 Lisp_Object symbol
= Fplist_get (XCDR (object
), QCtype
);
4696 struct image_type
*type
= lookup_image_type (symbol
);
4699 valid_p
= type
->valid_p (object
);
4706 /* Log error message with format string FORMAT and argument ARG.
4707 Signaling an error, e.g. when an image cannot be loaded, is not a
4708 good idea because this would interrupt redisplay, and the error
4709 message display would lead to another redisplay. This function
4710 therefore simply displays a message. */
4713 image_error (format
, arg1
, arg2
)
4715 Lisp_Object arg1
, arg2
;
4717 add_to_log (format
, arg1
, arg2
);
4722 /***********************************************************************
4723 Image specifications
4724 ***********************************************************************/
4726 enum image_value_type
4728 IMAGE_DONT_CHECK_VALUE_TYPE
,
4731 IMAGE_POSITIVE_INTEGER_VALUE
,
4732 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4733 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4735 IMAGE_INTEGER_VALUE
,
4736 IMAGE_FUNCTION_VALUE
,
4741 /* Structure used when parsing image specifications. */
4743 struct image_keyword
4745 /* Name of keyword. */
4748 /* The type of value allowed. */
4749 enum image_value_type type
;
4751 /* Non-zero means key must be present. */
4754 /* Used to recognize duplicate keywords in a property list. */
4757 /* The value that was found. */
4762 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4764 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4767 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4768 has the format (image KEYWORD VALUE ...). One of the keyword/
4769 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4770 image_keywords structures of size NKEYWORDS describing other
4771 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4774 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4776 struct image_keyword
*keywords
;
4783 if (!CONSP (spec
) || !EQ (XCAR (spec
), Qimage
))
4786 plist
= XCDR (spec
);
4787 while (CONSP (plist
))
4789 Lisp_Object key
, value
;
4791 /* First element of a pair must be a symbol. */
4793 plist
= XCDR (plist
);
4797 /* There must follow a value. */
4800 value
= XCAR (plist
);
4801 plist
= XCDR (plist
);
4803 /* Find key in KEYWORDS. Error if not found. */
4804 for (i
= 0; i
< nkeywords
; ++i
)
4805 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
4811 /* Record that we recognized the keyword. If a keywords
4812 was found more than once, it's an error. */
4813 keywords
[i
].value
= value
;
4814 ++keywords
[i
].count
;
4816 if (keywords
[i
].count
> 1)
4819 /* Check type of value against allowed type. */
4820 switch (keywords
[i
].type
)
4822 case IMAGE_STRING_VALUE
:
4823 if (!STRINGP (value
))
4827 case IMAGE_SYMBOL_VALUE
:
4828 if (!SYMBOLP (value
))
4832 case IMAGE_POSITIVE_INTEGER_VALUE
:
4833 if (!INTEGERP (value
) || XINT (value
) <= 0)
4837 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4838 if (INTEGERP (value
) && XINT (value
) >= 0)
4841 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4842 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4846 case IMAGE_ASCENT_VALUE
:
4847 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4849 else if (INTEGERP (value
)
4850 && XINT (value
) >= 0
4851 && XINT (value
) <= 100)
4855 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4856 if (!INTEGERP (value
) || XINT (value
) < 0)
4860 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4863 case IMAGE_FUNCTION_VALUE
:
4864 value
= indirect_function (value
);
4866 || COMPILEDP (value
)
4867 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4871 case IMAGE_NUMBER_VALUE
:
4872 if (!INTEGERP (value
) && !FLOATP (value
))
4876 case IMAGE_INTEGER_VALUE
:
4877 if (!INTEGERP (value
))
4881 case IMAGE_BOOL_VALUE
:
4882 if (!NILP (value
) && !EQ (value
, Qt
))
4891 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4895 /* Check that all mandatory fields are present. */
4896 for (i
= 0; i
< nkeywords
; ++i
)
4897 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4900 return NILP (plist
);
4904 /* Return the value of KEY in image specification SPEC. Value is nil
4905 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4906 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4909 image_spec_value (spec
, key
, found
)
4910 Lisp_Object spec
, key
;
4915 xassert (valid_image_p (spec
));
4917 for (tail
= XCDR (spec
);
4918 CONSP (tail
) && CONSP (XCDR (tail
));
4919 tail
= XCDR (XCDR (tail
)))
4921 if (EQ (XCAR (tail
), key
))
4925 return XCAR (XCDR (tail
));
4937 /***********************************************************************
4938 Image type independent image structures
4939 ***********************************************************************/
4941 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4942 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4945 /* Allocate and return a new image structure for image specification
4946 SPEC. SPEC has a hash value of HASH. */
4948 static struct image
*
4949 make_image (spec
, hash
)
4953 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4955 xassert (valid_image_p (spec
));
4956 bzero (img
, sizeof *img
);
4957 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4958 xassert (img
->type
!= NULL
);
4960 img
->data
.lisp_val
= Qnil
;
4961 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
4967 /* Free image IMG which was used on frame F, including its resources. */
4976 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4978 /* Remove IMG from the hash table of its cache. */
4980 img
->prev
->next
= img
->next
;
4982 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
4985 img
->next
->prev
= img
->prev
;
4987 c
->images
[img
->id
] = NULL
;
4989 /* Free resources, then free IMG. */
4990 img
->type
->free (f
, img
);
4996 /* Prepare image IMG for display on frame F. Must be called before
4997 drawing an image. */
5000 prepare_image_for_display (f
, img
)
5006 /* We're about to display IMG, so set its timestamp to `now'. */
5008 img
->timestamp
= EMACS_SECS (t
);
5010 /* If IMG doesn't have a pixmap yet, load it now, using the image
5011 type dependent loader function. */
5012 if (img
->pixmap
== 0 && !img
->load_failed_p
)
5013 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5017 /* Value is the number of pixels for the ascent of image IMG when
5018 drawn in face FACE. */
5021 image_ascent (img
, face
)
5025 int height
= img
->height
+ img
->vmargin
;
5028 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
5031 ascent
= height
/ 2 - (FONT_DESCENT(face
->font
)
5032 - FONT_BASE(face
->font
)) / 2;
5034 ascent
= height
/ 2;
5037 ascent
= height
* img
->ascent
/ 100.0;
5044 /***********************************************************************
5045 Helper functions for X image types
5046 ***********************************************************************/
5048 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
5049 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
5051 Lisp_Object color_name
,
5052 unsigned long dflt
));
5054 /* Free X resources of image IMG which is used on frame F. */
5057 x_clear_image (f
, img
)
5061 #if 0 /* MAC_TODO: W32 image support */
5066 XFreePixmap (NULL
, img
->pixmap
);
5073 int class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
5075 /* If display has an immutable color map, freeing colors is not
5076 necessary and some servers don't allow it. So don't do it. */
5077 if (class != StaticColor
5078 && class != StaticGray
5079 && class != TrueColor
)
5083 cmap
= DefaultColormapOfScreen (FRAME_W32_DISPLAY_INFO (f
)->screen
);
5084 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
, img
->colors
,
5089 xfree (img
->colors
);
5093 #endif /* MAC_TODO */
5097 /* Allocate color COLOR_NAME for image IMG on frame F. If color
5098 cannot be allocated, use DFLT. Add a newly allocated color to
5099 IMG->colors, so that it can be freed again. Value is the pixel
5102 static unsigned long
5103 x_alloc_image_color (f
, img
, color_name
, dflt
)
5106 Lisp_Object color_name
;
5109 #if 0 /* MAC_TODO: allocing colors. */
5111 unsigned long result
;
5113 xassert (STRINGP (color_name
));
5115 if (w32_defined_color (f
, SDATA (color_name
), &color
, 1))
5117 /* This isn't called frequently so we get away with simply
5118 reallocating the color vector to the needed size, here. */
5121 (unsigned long *) xrealloc (img
->colors
,
5122 img
->ncolors
* sizeof *img
->colors
);
5123 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
5124 result
= color
.pixel
;
5129 #endif /* MAC_TODO */
5135 /***********************************************************************
5137 ***********************************************************************/
5139 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
5142 /* Return a new, initialized image cache that is allocated from the
5143 heap. Call free_image_cache to free an image cache. */
5145 struct image_cache
*
5148 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
5151 bzero (c
, sizeof *c
);
5153 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
5154 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
5155 c
->buckets
= (struct image
**) xmalloc (size
);
5156 bzero (c
->buckets
, size
);
5161 /* Free image cache of frame F. Be aware that X frames share images
5165 free_image_cache (f
)
5168 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5173 /* Cache should not be referenced by any frame when freed. */
5174 xassert (c
->refcount
== 0);
5176 for (i
= 0; i
< c
->used
; ++i
)
5177 free_image (f
, c
->images
[i
]);
5181 FRAME_X_IMAGE_CACHE (f
) = NULL
;
5186 /* Clear image cache of frame F. FORCE_P non-zero means free all
5187 images. FORCE_P zero means clear only images that haven't been
5188 displayed for some time. Should be called from time to time to
5189 reduce the number of loaded images. If image-eviction-seconds is
5190 non-nil, this frees images in the cache which weren't displayed for
5191 at least that many seconds. */
5194 clear_image_cache (f
, force_p
)
5198 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5200 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
5204 int i
, any_freed_p
= 0;
5207 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
5209 for (i
= 0; i
< c
->used
; ++i
)
5211 struct image
*img
= c
->images
[i
];
5214 || (img
->timestamp
> old
)))
5216 free_image (f
, img
);
5221 /* We may be clearing the image cache because, for example,
5222 Emacs was iconified for a longer period of time. In that
5223 case, current matrices may still contain references to
5224 images freed above. So, clear these matrices. */
5227 clear_current_matrices (f
);
5228 ++windows_or_buffers_changed
;
5234 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
5236 doc
: /* Clear the image cache of FRAME.
5237 FRAME nil or omitted means use the selected frame.
5238 FRAME t means clear the image caches of all frames. */)
5246 FOR_EACH_FRAME (tail
, frame
)
5247 if (FRAME_MAC_P (XFRAME (frame
)))
5248 clear_image_cache (XFRAME (frame
), 1);
5251 clear_image_cache (check_x_frame (frame
), 1);
5257 /* Return the id of image with Lisp specification SPEC on frame F.
5258 SPEC must be a valid Lisp image specification (see valid_image_p). */
5261 lookup_image (f
, spec
)
5265 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5269 struct gcpro gcpro1
;
5272 /* F must be a window-system frame, and SPEC must be a valid image
5274 xassert (FRAME_WINDOW_P (f
));
5275 xassert (valid_image_p (spec
));
5279 /* Look up SPEC in the hash table of the image cache. */
5280 hash
= sxhash (spec
, 0);
5281 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5283 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5284 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5287 /* If not found, create a new image and cache it. */
5291 img
= make_image (spec
, hash
);
5292 cache_image (f
, img
);
5293 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5294 xassert (!interrupt_input_blocked
);
5296 /* If we can't load the image, and we don't have a width and
5297 height, use some arbitrary width and height so that we can
5298 draw a rectangle for it. */
5299 if (img
->load_failed_p
)
5303 value
= image_spec_value (spec
, QCwidth
, NULL
);
5304 img
->width
= (INTEGERP (value
)
5305 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5306 value
= image_spec_value (spec
, QCheight
, NULL
);
5307 img
->height
= (INTEGERP (value
)
5308 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5312 /* Handle image type independent image attributes
5313 `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF'. */
5314 Lisp_Object ascent
, margin
, relief
;
5316 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5317 if (INTEGERP (ascent
))
5318 img
->ascent
= XFASTINT (ascent
);
5319 else if (EQ (ascent
, Qcenter
))
5320 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5322 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5323 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5324 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5325 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5326 && INTEGERP (XCDR (margin
)))
5328 if (XINT (XCAR (margin
)) > 0)
5329 img
->hmargin
= XFASTINT (XCAR (margin
));
5330 if (XINT (XCDR (margin
)) > 0)
5331 img
->vmargin
= XFASTINT (XCDR (margin
));
5334 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5335 if (INTEGERP (relief
))
5337 img
->relief
= XINT (relief
);
5338 img
->hmargin
+= abs (img
->relief
);
5339 img
->vmargin
+= abs (img
->relief
);
5344 /* We're using IMG, so set its timestamp to `now'. */
5345 EMACS_GET_TIME (now
);
5346 img
->timestamp
= EMACS_SECS (now
);
5350 /* Value is the image id. */
5355 /* Cache image IMG in the image cache of frame F. */
5358 cache_image (f
, img
)
5362 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5365 /* Find a free slot in c->images. */
5366 for (i
= 0; i
< c
->used
; ++i
)
5367 if (c
->images
[i
] == NULL
)
5370 /* If no free slot found, maybe enlarge c->images. */
5371 if (i
== c
->used
&& c
->used
== c
->size
)
5374 c
->images
= (struct image
**) xrealloc (c
->images
,
5375 c
->size
* sizeof *c
->images
);
5378 /* Add IMG to c->images, and assign IMG an id. */
5384 /* Add IMG to the cache's hash table. */
5385 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5386 img
->next
= c
->buckets
[i
];
5388 img
->next
->prev
= img
;
5390 c
->buckets
[i
] = img
;
5394 /* Call FN on every image in the image cache of frame F. Used to mark
5395 Lisp Objects in the image cache. */
5398 forall_images_in_image_cache (f
, fn
)
5400 void (*fn
) P_ ((struct image
*img
));
5402 if (FRAME_LIVE_P (f
) && FRAME_MAC_P (f
))
5404 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5408 for (i
= 0; i
< c
->used
; ++i
)
5417 /***********************************************************************
5419 ***********************************************************************/
5421 #if 0 /* MAC_TODO: Mac specific image code. */
5423 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5424 XImage
**, Pixmap
*));
5425 static void x_destroy_x_image
P_ ((XImage
*));
5426 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5429 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5430 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5431 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5432 via xmalloc. Print error messages via image_error if an error
5433 occurs. Value is non-zero if successful. */
5436 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5438 int width
, height
, depth
;
5442 #if 0 /* MAC_TODO: Image support for Mac */
5443 Display
*display
= FRAME_W32_DISPLAY (f
);
5444 Screen
*screen
= FRAME_X_SCREEN (f
);
5445 Window window
= FRAME_W32_WINDOW (f
);
5447 xassert (interrupt_input_blocked
);
5450 depth
= DefaultDepthOfScreen (screen
);
5451 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5452 depth
, ZPixmap
, 0, NULL
, width
, height
,
5453 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5456 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5460 /* Allocate image raster. */
5461 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5463 /* Allocate a pixmap of the same size. */
5464 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5467 x_destroy_x_image (*ximg
);
5469 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5472 #endif /* MAC_TODO */
5477 /* Destroy XImage XIMG. Free XIMG->data. */
5480 x_destroy_x_image (ximg
)
5483 xassert (interrupt_input_blocked
);
5488 XDestroyImage (ximg
);
5493 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5494 are width and height of both the image and pixmap. */
5497 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5504 xassert (interrupt_input_blocked
);
5505 gc
= XCreateGC (NULL
, pixmap
, 0, NULL
);
5506 XPutImage (NULL
, pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5510 #endif /* MAC_TODO */
5513 /***********************************************************************
5515 ***********************************************************************/
5517 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5519 /* Find image file FILE. Look in data-directory, then
5520 x-bitmap-file-path. Value is the full name of the file found, or
5521 nil if not found. */
5524 x_find_image_file (file
)
5527 Lisp_Object file_found
, search_path
;
5528 struct gcpro gcpro1
, gcpro2
;
5532 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5533 GCPRO2 (file_found
, search_path
);
5535 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5536 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5548 /***********************************************************************
5550 ***********************************************************************/
5552 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5553 static int xbm_load_image_from_file
P_ ((struct frame
*f
, struct image
*img
,
5555 static int xbm_image_p
P_ ((Lisp_Object object
));
5556 static int xbm_read_bitmap_file_data
P_ ((char *, int *, int *,
5560 /* Indices of image specification fields in xbm_format, below. */
5562 enum xbm_keyword_index
5579 /* Vector of image_keyword structures describing the format
5580 of valid XBM image specifications. */
5582 static struct image_keyword xbm_format
[XBM_LAST
] =
5584 {":type", IMAGE_SYMBOL_VALUE
, 1},
5585 {":file", IMAGE_STRING_VALUE
, 0},
5586 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5587 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5588 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5589 {":foreground", IMAGE_STRING_VALUE
, 0},
5590 {":background", IMAGE_STRING_VALUE
, 0},
5591 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
5592 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5593 {":relief", IMAGE_INTEGER_VALUE
, 0},
5594 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5595 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5598 /* Structure describing the image type XBM. */
5600 static struct image_type xbm_type
=
5609 /* Tokens returned from xbm_scan. */
5618 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5619 A valid specification is a list starting with the symbol `image'
5620 The rest of the list is a property list which must contain an
5623 If the specification specifies a file to load, it must contain
5624 an entry `:file FILENAME' where FILENAME is a string.
5626 If the specification is for a bitmap loaded from memory it must
5627 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5628 WIDTH and HEIGHT are integers > 0. DATA may be:
5630 1. a string large enough to hold the bitmap data, i.e. it must
5631 have a size >= (WIDTH + 7) / 8 * HEIGHT
5633 2. a bool-vector of size >= WIDTH * HEIGHT
5635 3. a vector of strings or bool-vectors, one for each line of the
5638 Both the file and data forms may contain the additional entries
5639 `:background COLOR' and `:foreground COLOR'. If not present,
5640 foreground and background of the frame on which the image is
5641 displayed, is used. */
5644 xbm_image_p (object
)
5647 struct image_keyword kw
[XBM_LAST
];
5649 bcopy (xbm_format
, kw
, sizeof kw
);
5650 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5653 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5655 if (kw
[XBM_FILE
].count
)
5657 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5665 /* Entries for `:width', `:height' and `:data' must be present. */
5666 if (!kw
[XBM_WIDTH
].count
5667 || !kw
[XBM_HEIGHT
].count
5668 || !kw
[XBM_DATA
].count
)
5671 data
= kw
[XBM_DATA
].value
;
5672 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5673 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5675 /* Check type of data, and width and height against contents of
5681 /* Number of elements of the vector must be >= height. */
5682 if (XVECTOR (data
)->size
< height
)
5685 /* Each string or bool-vector in data must be large enough
5686 for one line of the image. */
5687 for (i
= 0; i
< height
; ++i
)
5689 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5694 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5697 else if (BOOL_VECTOR_P (elt
))
5699 if (XBOOL_VECTOR (elt
)->size
< width
)
5706 else if (STRINGP (data
))
5709 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5712 else if (BOOL_VECTOR_P (data
))
5714 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5721 /* Baseline must be a value between 0 and 100 (a percentage). */
5722 if (kw
[XBM_ASCENT
].count
5723 && XFASTINT (kw
[XBM_ASCENT
].value
) > 100)
5730 /* Scan a bitmap file. FP is the stream to read from. Value is
5731 either an enumerator from enum xbm_token, or a character for a
5732 single-character token, or 0 at end of file. If scanning an
5733 identifier, store the lexeme of the identifier in SVAL. If
5734 scanning a number, store its value in *IVAL. */
5737 xbm_scan (fp
, sval
, ival
)
5744 /* Skip white space. */
5745 while ((c
= fgetc (fp
)) != EOF
&& isspace (c
))
5750 else if (isdigit (c
))
5752 int value
= 0, digit
;
5757 if (c
== 'x' || c
== 'X')
5759 while ((c
= fgetc (fp
)) != EOF
)
5763 else if (c
>= 'a' && c
<= 'f')
5764 digit
= c
- 'a' + 10;
5765 else if (c
>= 'A' && c
<= 'F')
5766 digit
= c
- 'A' + 10;
5769 value
= 16 * value
+ digit
;
5772 else if (isdigit (c
))
5775 while ((c
= fgetc (fp
)) != EOF
5777 value
= 8 * value
+ c
- '0';
5783 while ((c
= fgetc (fp
)) != EOF
5785 value
= 10 * value
+ c
- '0';
5793 else if (isalpha (c
) || c
== '_')
5796 while ((c
= fgetc (fp
)) != EOF
5797 && (isalnum (c
) || c
== '_'))
5809 /* Replacement for XReadBitmapFileData which isn't available under old
5810 X versions. FILE is the name of the bitmap file to read. Set
5811 *WIDTH and *HEIGHT to the width and height of the image. Return in
5812 *DATA the bitmap data allocated with xmalloc. Value is non-zero if
5816 xbm_read_bitmap_file_data (file
, width
, height
, data
)
5818 int *width
, *height
;
5819 unsigned char **data
;
5822 char buffer
[BUFSIZ
];
5825 int bytes_per_line
, i
, nbytes
;
5831 LA1 = xbm_scan (fp, buffer, &value)
5833 #define expect(TOKEN) \
5834 if (LA1 != (TOKEN)) \
5839 #define expect_ident(IDENT) \
5840 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
5845 fp
= fopen (file
, "r");
5849 *width
= *height
= -1;
5851 LA1
= xbm_scan (fp
, buffer
, &value
);
5853 /* Parse defines for width, height and hot-spots. */
5857 expect_ident ("define");
5858 expect (XBM_TK_IDENT
);
5860 if (LA1
== XBM_TK_NUMBER
);
5862 char *p
= strrchr (buffer
, '_');
5863 p
= p
? p
+ 1 : buffer
;
5864 if (strcmp (p
, "width") == 0)
5866 else if (strcmp (p
, "height") == 0)
5869 expect (XBM_TK_NUMBER
);
5872 if (*width
< 0 || *height
< 0)
5875 /* Parse bits. Must start with `static'. */
5876 expect_ident ("static");
5877 if (LA1
== XBM_TK_IDENT
)
5879 if (strcmp (buffer
, "unsigned") == 0)
5882 expect_ident ("char");
5884 else if (strcmp (buffer
, "short") == 0)
5888 if (*width
% 16 && *width
% 16 < 9)
5891 else if (strcmp (buffer
, "char") == 0)
5899 expect (XBM_TK_IDENT
);
5905 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
5906 nbytes
= bytes_per_line
* *height
;
5907 p
= *data
= (char *) xmalloc (nbytes
);
5912 for (i
= 0; i
< nbytes
; i
+= 2)
5915 expect (XBM_TK_NUMBER
);
5918 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
5921 if (LA1
== ',' || LA1
== '}')
5929 for (i
= 0; i
< nbytes
; ++i
)
5932 expect (XBM_TK_NUMBER
);
5936 if (LA1
== ',' || LA1
== '}')
5962 /* Load XBM image IMG which will be displayed on frame F from file
5963 SPECIFIED_FILE. Value is non-zero if successful. */
5966 xbm_load_image_from_file (f
, img
, specified_file
)
5969 Lisp_Object specified_file
;
5972 unsigned char *data
;
5975 struct gcpro gcpro1
;
5977 xassert (STRINGP (specified_file
));
5981 file
= x_find_image_file (specified_file
);
5982 if (!STRINGP (file
))
5984 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5989 rc
= xbm_read_bitmap_file_data (SDATA (file
), &img
->width
,
5990 &img
->height
, &data
);
5993 int depth
= one_mac_display_info
.n_cbits
;
5994 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
5995 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
5998 xassert (img
->width
> 0 && img
->height
> 0);
6000 /* Get foreground and background colors, maybe allocate colors. */
6001 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
6003 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
6005 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
6007 background
= x_alloc_image_color (f
, img
, value
, background
);
6009 #if 0 /* MAC_TODO : Port image display to Mac */
6012 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
6013 FRAME_W32_WINDOW (f
),
6015 img
->width
, img
->height
,
6016 foreground
, background
,
6020 if (img
->pixmap
== 0)
6022 x_clear_image (f
, img
);
6023 image_error ("Unable to create X pixmap for `%s'", file
, Qnil
);
6029 #endif /* MAC_TODO */
6032 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6039 /* Fill image IMG which is used on frame F with pixmap data. Value is
6040 non-zero if successful. */
6048 Lisp_Object file_name
;
6050 xassert (xbm_image_p (img
->spec
));
6052 /* If IMG->spec specifies a file name, create a non-file spec from it. */
6053 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
6054 if (STRINGP (file_name
))
6055 success_p
= xbm_load_image_from_file (f
, img
, file_name
);
6058 struct image_keyword fmt
[XBM_LAST
];
6061 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6062 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6066 /* Parse the list specification. */
6067 bcopy (xbm_format
, fmt
, sizeof fmt
);
6068 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
6071 /* Get specified width, and height. */
6072 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
6073 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
6074 xassert (img
->width
> 0 && img
->height
> 0);
6078 if (fmt
[XBM_ASCENT
].count
)
6079 img
->ascent
= XFASTINT (fmt
[XBM_ASCENT
].value
);
6081 /* Get foreground and background colors, maybe allocate colors. */
6082 if (fmt
[XBM_FOREGROUND
].count
)
6083 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
6085 if (fmt
[XBM_BACKGROUND
].count
)
6086 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
6089 /* Set bits to the bitmap image data. */
6090 data
= fmt
[XBM_DATA
].value
;
6095 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
6097 p
= bits
= (char *) alloca (nbytes
* img
->height
);
6098 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
6100 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
6102 bcopy (SDATA (line
), p
, nbytes
);
6104 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
6107 else if (STRINGP (data
))
6108 bits
= SDATA (data
);
6110 bits
= XBOOL_VECTOR (data
)->data
;
6112 #if 0 /* MAC_TODO : port Mac display code */
6113 /* Create the pixmap. */
6114 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6116 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
6117 FRAME_W32_WINDOW (f
),
6119 img
->width
, img
->height
,
6120 foreground
, background
,
6122 #endif /* MAC_TODO */
6128 image_error ("Unable to create pixmap for XBM image `%s'",
6130 x_clear_image (f
, img
);
6141 /***********************************************************************
6143 ***********************************************************************/
6147 static int xpm_image_p
P_ ((Lisp_Object object
));
6148 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6149 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6151 #include "X11/xpm.h"
6153 /* The symbol `xpm' identifying XPM-format images. */
6157 /* Indices of image specification fields in xpm_format, below. */
6159 enum xpm_keyword_index
6173 /* Vector of image_keyword structures describing the format
6174 of valid XPM image specifications. */
6176 static struct image_keyword xpm_format
[XPM_LAST
] =
6178 {":type", IMAGE_SYMBOL_VALUE
, 1},
6179 {":file", IMAGE_STRING_VALUE
, 0},
6180 {":data", IMAGE_STRING_VALUE
, 0},
6181 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6182 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6183 {":relief", IMAGE_INTEGER_VALUE
, 0},
6184 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6185 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6186 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6189 /* Structure describing the image type XBM. */
6191 static struct image_type xpm_type
=
6201 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6202 for XPM images. Such a list must consist of conses whose car and
6206 xpm_valid_color_symbols_p (color_symbols
)
6207 Lisp_Object color_symbols
;
6209 while (CONSP (color_symbols
))
6211 Lisp_Object sym
= XCAR (color_symbols
);
6213 || !STRINGP (XCAR (sym
))
6214 || !STRINGP (XCDR (sym
)))
6216 color_symbols
= XCDR (color_symbols
);
6219 return NILP (color_symbols
);
6223 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6226 xpm_image_p (object
)
6229 struct image_keyword fmt
[XPM_LAST
];
6230 bcopy (xpm_format
, fmt
, sizeof fmt
);
6231 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6232 /* Either `:file' or `:data' must be present. */
6233 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6234 /* Either no `:color-symbols' or it's a list of conses
6235 whose car and cdr are strings. */
6236 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6237 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
))
6238 && (fmt
[XPM_ASCENT
].count
== 0
6239 || XFASTINT (fmt
[XPM_ASCENT
].value
) < 100));
6243 /* Load image IMG which will be displayed on frame F. Value is
6244 non-zero if successful. */
6252 XpmAttributes attrs
;
6253 Lisp_Object specified_file
, color_symbols
;
6255 /* Configure the XPM lib. Use the visual of frame F. Allocate
6256 close colors. Return colors allocated. */
6257 bzero (&attrs
, sizeof attrs
);
6258 attrs
.visual
= FRAME_X_VISUAL (f
);
6259 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6260 attrs
.valuemask
|= XpmVisual
;
6261 attrs
.valuemask
|= XpmColormap
;
6262 attrs
.valuemask
|= XpmReturnAllocPixels
;
6263 #ifdef XpmAllocCloseColors
6264 attrs
.alloc_close_colors
= 1;
6265 attrs
.valuemask
|= XpmAllocCloseColors
;
6267 attrs
.closeness
= 600;
6268 attrs
.valuemask
|= XpmCloseness
;
6271 /* If image specification contains symbolic color definitions, add
6272 these to `attrs'. */
6273 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6274 if (CONSP (color_symbols
))
6277 XpmColorSymbol
*xpm_syms
;
6280 attrs
.valuemask
|= XpmColorSymbols
;
6282 /* Count number of symbols. */
6283 attrs
.numsymbols
= 0;
6284 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6287 /* Allocate an XpmColorSymbol array. */
6288 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6289 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6290 bzero (xpm_syms
, size
);
6291 attrs
.colorsymbols
= xpm_syms
;
6293 /* Fill the color symbol array. */
6294 for (tail
= color_symbols
, i
= 0;
6296 ++i
, tail
= XCDR (tail
))
6298 Lisp_Object name
= XCAR (XCAR (tail
));
6299 Lisp_Object color
= XCDR (XCAR (tail
));
6300 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
6301 strcpy (xpm_syms
[i
].name
, SDATA (name
));
6302 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
6303 strcpy (xpm_syms
[i
].value
, SDATA (color
));
6307 /* Create a pixmap for the image, either from a file, or from a
6308 string buffer containing data in the same format as an XPM file. */
6310 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6311 if (STRINGP (specified_file
))
6313 Lisp_Object file
= x_find_image_file (specified_file
);
6314 if (!STRINGP (file
))
6316 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6321 rc
= XpmReadFileToPixmap (NULL
, FRAME_W32_WINDOW (f
),
6322 SDATA (file
), &img
->pixmap
, &img
->mask
,
6327 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6328 rc
= XpmCreatePixmapFromBuffer (NULL
, FRAME_W32_WINDOW (f
),
6330 &img
->pixmap
, &img
->mask
,
6335 if (rc
== XpmSuccess
)
6337 /* Remember allocated colors. */
6338 img
->ncolors
= attrs
.nalloc_pixels
;
6339 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6340 * sizeof *img
->colors
);
6341 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6342 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6344 img
->width
= attrs
.width
;
6345 img
->height
= attrs
.height
;
6346 xassert (img
->width
> 0 && img
->height
> 0);
6348 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6350 XpmFreeAttributes (&attrs
);
6358 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6361 case XpmFileInvalid
:
6362 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6366 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6369 case XpmColorFailed
:
6370 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6374 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6379 return rc
== XpmSuccess
;
6382 #endif /* HAVE_XPM != 0 */
6385 #if 0 /* MAC_TODO : Color tables on Mac. */
6386 /***********************************************************************
6388 ***********************************************************************/
6390 /* An entry in the color table mapping an RGB color to a pixel color. */
6395 unsigned long pixel
;
6397 /* Next in color table collision list. */
6398 struct ct_color
*next
;
6401 /* The bucket vector size to use. Must be prime. */
6405 /* Value is a hash of the RGB color given by R, G, and B. */
6407 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6409 /* The color hash table. */
6411 struct ct_color
**ct_table
;
6413 /* Number of entries in the color table. */
6415 int ct_colors_allocated
;
6417 /* Function prototypes. */
6419 static void init_color_table
P_ ((void));
6420 static void free_color_table
P_ ((void));
6421 static unsigned long *colors_in_color_table
P_ ((int *n
));
6422 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
6423 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
6426 /* Initialize the color table. */
6431 int size
= CT_SIZE
* sizeof (*ct_table
);
6432 ct_table
= (struct ct_color
**) xmalloc (size
);
6433 bzero (ct_table
, size
);
6434 ct_colors_allocated
= 0;
6438 /* Free memory associated with the color table. */
6444 struct ct_color
*p
, *next
;
6446 for (i
= 0; i
< CT_SIZE
; ++i
)
6447 for (p
= ct_table
[i
]; p
; p
= next
)
6458 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6459 entry for that color already is in the color table, return the
6460 pixel color of that entry. Otherwise, allocate a new color for R,
6461 G, B, and make an entry in the color table. */
6463 static unsigned long
6464 lookup_rgb_color (f
, r
, g
, b
)
6468 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6469 int i
= hash
% CT_SIZE
;
6472 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6473 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6482 color
= RGB_TO_ULONG (r
, g
, b
);
6484 ++ct_colors_allocated
;
6486 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6491 p
->next
= ct_table
[i
];
6499 /* Look up pixel color PIXEL which is used on frame F in the color
6500 table. If not already present, allocate it. Value is PIXEL. */
6502 static unsigned long
6503 lookup_pixel_color (f
, pixel
)
6505 unsigned long pixel
;
6507 int i
= pixel
% CT_SIZE
;
6510 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6511 if (p
->pixel
== pixel
)
6522 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6523 color
.pixel
= pixel
;
6524 XQueryColor (NULL
, cmap
, &color
);
6525 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6530 ++ct_colors_allocated
;
6532 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6537 p
->next
= ct_table
[i
];
6541 return FRAME_FOREGROUND_PIXEL (f
);
6547 /* Value is a vector of all pixel colors contained in the color table,
6548 allocated via xmalloc. Set *N to the number of colors. */
6550 static unsigned long *
6551 colors_in_color_table (n
)
6556 unsigned long *colors
;
6558 if (ct_colors_allocated
== 0)
6565 colors
= (unsigned long *) xmalloc (ct_colors_allocated
6567 *n
= ct_colors_allocated
;
6569 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
6570 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6571 colors
[j
++] = p
->pixel
;
6577 #endif /* MAC_TODO */
6580 /***********************************************************************
6582 ***********************************************************************/
6584 #if 0 /* MAC_TODO : Mac versions of low level algorithms */
6585 static void x_laplace_write_row
P_ ((struct frame
*, long *,
6586 int, XImage
*, int));
6587 static void x_laplace_read_row
P_ ((struct frame
*, Colormap
,
6588 XColor
*, int, XImage
*, int));
6591 /* Fill COLORS with RGB colors from row Y of image XIMG. F is the
6592 frame we operate on, CMAP is the color-map in effect, and WIDTH is
6593 the width of one row in the image. */
6596 x_laplace_read_row (f
, cmap
, colors
, width
, ximg
, y
)
6606 for (x
= 0; x
< width
; ++x
)
6607 colors
[x
].pixel
= XGetPixel (ximg
, x
, y
);
6609 XQueryColors (NULL
, cmap
, colors
, width
);
6613 /* Write row Y of image XIMG. PIXELS is an array of WIDTH longs
6614 containing the pixel colors to write. F is the frame we are
6618 x_laplace_write_row (f
, pixels
, width
, ximg
, y
)
6627 for (x
= 0; x
< width
; ++x
)
6628 XPutPixel (ximg
, x
, y
, pixels
[x
]);
6630 #endif /* MAC_TODO */
6632 /* Transform image IMG which is used on frame F with a Laplace
6633 edge-detection algorithm. The result is an image that can be used
6634 to draw disabled buttons, for example. */
6641 #if 0 /* MAC_TODO : Mac version */
6642 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6643 XImage
*ximg
, *oimg
;
6649 int in_y
, out_y
, rc
;
6654 /* Get the X image IMG->pixmap. */
6655 ximg
= XGetImage (NULL
, img
->pixmap
,
6656 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
6658 /* Allocate 3 input rows, and one output row of colors. */
6659 for (i
= 0; i
< 3; ++i
)
6660 in
[i
] = (XColor
*) alloca (img
->width
* sizeof (XColor
));
6661 out
= (long *) alloca (img
->width
* sizeof (long));
6663 /* Create an X image for output. */
6664 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
6667 /* Fill first two rows. */
6668 x_laplace_read_row (f
, cmap
, in
[0], img
->width
, ximg
, 0);
6669 x_laplace_read_row (f
, cmap
, in
[1], img
->width
, ximg
, 1);
6672 /* Write first row, all zeros. */
6673 init_color_table ();
6674 pixel
= lookup_rgb_color (f
, 0, 0, 0);
6675 for (x
= 0; x
< img
->width
; ++x
)
6677 x_laplace_write_row (f
, out
, img
->width
, oimg
, 0);
6680 for (y
= 2; y
< img
->height
; ++y
)
6683 int rowb
= (y
+ 2) % 3;
6685 x_laplace_read_row (f
, cmap
, in
[rowa
], img
->width
, ximg
, in_y
++);
6687 for (x
= 0; x
< img
->width
- 2; ++x
)
6689 int r
= in
[rowa
][x
].red
+ mv2
- in
[rowb
][x
+ 2].red
;
6690 int g
= in
[rowa
][x
].green
+ mv2
- in
[rowb
][x
+ 2].green
;
6691 int b
= in
[rowa
][x
].blue
+ mv2
- in
[rowb
][x
+ 2].blue
;
6693 out
[x
+ 1] = lookup_rgb_color (f
, r
& 0xffff, g
& 0xffff,
6697 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
++);
6700 /* Write last line, all zeros. */
6701 for (x
= 0; x
< img
->width
; ++x
)
6703 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
);
6705 /* Free the input image, and free resources of IMG. */
6706 XDestroyImage (ximg
);
6707 x_clear_image (f
, img
);
6709 /* Put the output image into pixmap, and destroy it. */
6710 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
6711 x_destroy_x_image (oimg
);
6713 /* Remember new pixmap and colors in IMG. */
6714 img
->pixmap
= pixmap
;
6715 img
->colors
= colors_in_color_table (&img
->ncolors
);
6716 free_color_table ();
6719 #endif /* MAC_TODO */
6723 /* Build a mask for image IMG which is used on frame F. FILE is the
6724 name of an image file, for error messages. HOW determines how to
6725 determine the background color of IMG. If it is a list '(R G B)',
6726 with R, G, and B being integers >= 0, take that as the color of the
6727 background. Otherwise, determine the background color of IMG
6728 heuristically. Value is non-zero if successful. */
6731 x_build_heuristic_mask (f
, img
, how
)
6736 #if 0 /* MAC_TODO : Mac version */
6737 Display
*dpy
= FRAME_W32_DISPLAY (f
);
6738 XImage
*ximg
, *mask_img
;
6739 int x
, y
, rc
, look_at_corners_p
;
6744 /* Create an image and pixmap serving as mask. */
6745 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
6746 &mask_img
, &img
->mask
);
6753 /* Get the X image of IMG->pixmap. */
6754 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
6757 /* Determine the background color of ximg. If HOW is `(R G B)'
6758 take that as color. Otherwise, try to determine the color
6760 look_at_corners_p
= 1;
6768 && NATNUMP (XCAR (how
)))
6770 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
6774 if (i
== 3 && NILP (how
))
6776 char color_name
[30];
6777 XColor exact
, color
;
6780 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
6782 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6783 if (XLookupColor (dpy
, cmap
, color_name
, &exact
, &color
))
6786 look_at_corners_p
= 0;
6791 if (look_at_corners_p
)
6793 unsigned long corners
[4];
6796 /* Get the colors at the corners of ximg. */
6797 corners
[0] = XGetPixel (ximg
, 0, 0);
6798 corners
[1] = XGetPixel (ximg
, img
->width
- 1, 0);
6799 corners
[2] = XGetPixel (ximg
, img
->width
- 1, img
->height
- 1);
6800 corners
[3] = XGetPixel (ximg
, 0, img
->height
- 1);
6802 /* Choose the most frequently found color as background. */
6803 for (i
= best_count
= 0; i
< 4; ++i
)
6807 for (j
= n
= 0; j
< 4; ++j
)
6808 if (corners
[i
] == corners
[j
])
6812 bg
= corners
[i
], best_count
= n
;
6816 /* Set all bits in mask_img to 1 whose color in ximg is different
6817 from the background color bg. */
6818 for (y
= 0; y
< img
->height
; ++y
)
6819 for (x
= 0; x
< img
->width
; ++x
)
6820 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
6822 /* Put mask_img into img->mask. */
6823 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
6824 x_destroy_x_image (mask_img
);
6825 XDestroyImage (ximg
);
6828 #endif /* MAC_TODO */
6835 /***********************************************************************
6836 PBM (mono, gray, color)
6837 ***********************************************************************/
6840 static int pbm_image_p
P_ ((Lisp_Object object
));
6841 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
6842 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
6844 /* The symbol `pbm' identifying images of this type. */
6848 /* Indices of image specification fields in gs_format, below. */
6850 enum pbm_keyword_index
6863 /* Vector of image_keyword structures describing the format
6864 of valid user-defined image specifications. */
6866 static struct image_keyword pbm_format
[PBM_LAST
] =
6868 {":type", IMAGE_SYMBOL_VALUE
, 1},
6869 {":file", IMAGE_STRING_VALUE
, 0},
6870 {":data", IMAGE_STRING_VALUE
, 0},
6871 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6872 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6873 {":relief", IMAGE_INTEGER_VALUE
, 0},
6874 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6875 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6878 /* Structure describing the image type `pbm'. */
6880 static struct image_type pbm_type
=
6890 /* Return non-zero if OBJECT is a valid PBM image specification. */
6893 pbm_image_p (object
)
6896 struct image_keyword fmt
[PBM_LAST
];
6898 bcopy (pbm_format
, fmt
, sizeof fmt
);
6900 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
)
6901 || (fmt
[PBM_ASCENT
].count
6902 && XFASTINT (fmt
[PBM_ASCENT
].value
) > 100))
6905 /* Must specify either :data or :file. */
6906 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
6910 /* Scan a decimal number from *S and return it. Advance *S while
6911 reading the number. END is the end of the string. Value is -1 at
6915 pbm_scan_number (s
, end
)
6916 unsigned char **s
, *end
;
6922 /* Skip white-space. */
6923 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
6928 /* Skip comment to end of line. */
6929 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
6932 else if (isdigit (c
))
6934 /* Read decimal number. */
6936 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
6937 val
= 10 * val
+ c
- '0';
6948 /* Read FILE into memory. Value is a pointer to a buffer allocated
6949 with xmalloc holding FILE's contents. Value is null if an error
6950 occurred. *SIZE is set to the size of the file. */
6953 pbm_read_file (file
, size
)
6961 if (stat (SDATA (file
), &st
) == 0
6962 && (fp
= fopen (SDATA (file
), "r")) != NULL
6963 && (buf
= (char *) xmalloc (st
.st_size
),
6964 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
6984 /* Load PBM image IMG for use on frame F. */
6992 int width
, height
, max_color_idx
= 0;
6994 Lisp_Object file
, specified_file
;
6995 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
6996 struct gcpro gcpro1
;
6997 unsigned char *contents
= NULL
;
6998 unsigned char *end
, *p
;
7001 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7005 if (STRINGP (specified_file
))
7007 file
= x_find_image_file (specified_file
);
7008 if (!STRINGP (file
))
7010 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7015 contents
= pbm_read_file (file
, &size
);
7016 if (contents
== NULL
)
7018 image_error ("Error reading `%s'", file
, Qnil
);
7024 end
= contents
+ size
;
7029 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7031 end
= p
+ SBYTES (data
);
7034 /* Check magic number. */
7035 if (end
- p
< 2 || *p
++ != 'P')
7037 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7047 raw_p
= 0, type
= PBM_MONO
;
7051 raw_p
= 0, type
= PBM_GRAY
;
7055 raw_p
= 0, type
= PBM_COLOR
;
7059 raw_p
= 1, type
= PBM_MONO
;
7063 raw_p
= 1, type
= PBM_GRAY
;
7067 raw_p
= 1, type
= PBM_COLOR
;
7071 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7075 /* Read width, height, maximum color-component. Characters
7076 starting with `#' up to the end of a line are ignored. */
7077 width
= pbm_scan_number (&p
, end
);
7078 height
= pbm_scan_number (&p
, end
);
7080 if (type
!= PBM_MONO
)
7082 max_color_idx
= pbm_scan_number (&p
, end
);
7083 if (raw_p
&& max_color_idx
> 255)
7084 max_color_idx
= 255;
7089 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7093 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7094 &ximg
, &img
->pixmap
))
7100 /* Initialize the color hash table. */
7101 init_color_table ();
7103 if (type
== PBM_MONO
)
7107 for (y
= 0; y
< height
; ++y
)
7108 for (x
= 0; x
< width
; ++x
)
7118 g
= pbm_scan_number (&p
, end
);
7120 XPutPixel (ximg
, x
, y
, (g
7121 ? FRAME_FOREGROUND_PIXEL (f
)
7122 : FRAME_BACKGROUND_PIXEL (f
)));
7127 for (y
= 0; y
< height
; ++y
)
7128 for (x
= 0; x
< width
; ++x
)
7132 if (type
== PBM_GRAY
)
7133 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7142 r
= pbm_scan_number (&p
, end
);
7143 g
= pbm_scan_number (&p
, end
);
7144 b
= pbm_scan_number (&p
, end
);
7147 if (r
< 0 || g
< 0 || b
< 0)
7151 XDestroyImage (ximg
);
7153 image_error ("Invalid pixel value in image `%s'",
7158 /* RGB values are now in the range 0..max_color_idx.
7159 Scale this to the range 0..0xffff supported by X. */
7160 r
= (double) r
* 65535 / max_color_idx
;
7161 g
= (double) g
* 65535 / max_color_idx
;
7162 b
= (double) b
* 65535 / max_color_idx
;
7163 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7167 /* Store in IMG->colors the colors allocated for the image, and
7168 free the color table. */
7169 img
->colors
= colors_in_color_table (&img
->ncolors
);
7170 free_color_table ();
7172 /* Put the image into a pixmap. */
7173 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7174 x_destroy_x_image (ximg
);
7178 img
->height
= height
;
7184 #endif /* HAVE_PBM */
7187 /***********************************************************************
7189 ***********************************************************************/
7195 /* Function prototypes. */
7197 static int png_image_p
P_ ((Lisp_Object object
));
7198 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7200 /* The symbol `png' identifying images of this type. */
7204 /* Indices of image specification fields in png_format, below. */
7206 enum png_keyword_index
7219 /* Vector of image_keyword structures describing the format
7220 of valid user-defined image specifications. */
7222 static struct image_keyword png_format
[PNG_LAST
] =
7224 {":type", IMAGE_SYMBOL_VALUE
, 1},
7225 {":data", IMAGE_STRING_VALUE
, 0},
7226 {":file", IMAGE_STRING_VALUE
, 0},
7227 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7228 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7229 {":relief", IMAGE_INTEGER_VALUE
, 0},
7230 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7231 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7234 /* Structure describing the image type `png'. */
7236 static struct image_type png_type
=
7246 /* Return non-zero if OBJECT is a valid PNG image specification. */
7249 png_image_p (object
)
7252 struct image_keyword fmt
[PNG_LAST
];
7253 bcopy (png_format
, fmt
, sizeof fmt
);
7255 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
)
7256 || (fmt
[PNG_ASCENT
].count
7257 && XFASTINT (fmt
[PNG_ASCENT
].value
) > 100))
7260 /* Must specify either the :data or :file keyword. */
7261 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7265 /* Error and warning handlers installed when the PNG library
7269 my_png_error (png_ptr
, msg
)
7270 png_struct
*png_ptr
;
7273 xassert (png_ptr
!= NULL
);
7274 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7275 longjmp (png_ptr
->jmpbuf
, 1);
7280 my_png_warning (png_ptr
, msg
)
7281 png_struct
*png_ptr
;
7284 xassert (png_ptr
!= NULL
);
7285 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7288 /* Memory source for PNG decoding. */
7290 struct png_memory_storage
7292 unsigned char *bytes
; /* The data */
7293 size_t len
; /* How big is it? */
7294 int index
; /* Where are we? */
7298 /* Function set as reader function when reading PNG image from memory.
7299 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7300 bytes from the input to DATA. */
7303 png_read_from_memory (png_ptr
, data
, length
)
7304 png_structp png_ptr
;
7308 struct png_memory_storage
*tbr
7309 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7311 if (length
> tbr
->len
- tbr
->index
)
7312 png_error (png_ptr
, "Read error");
7314 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7315 tbr
->index
= tbr
->index
+ length
;
7318 /* Load PNG image IMG for use on frame F. Value is non-zero if
7326 Lisp_Object file
, specified_file
;
7327 Lisp_Object specified_data
;
7329 XImage
*ximg
, *mask_img
= NULL
;
7330 struct gcpro gcpro1
;
7331 png_struct
*png_ptr
= NULL
;
7332 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7335 png_byte
*pixels
= NULL
;
7336 png_byte
**rows
= NULL
;
7337 png_uint_32 width
, height
;
7338 int bit_depth
, color_type
, interlace_type
;
7340 png_uint_32 row_bytes
;
7343 double screen_gamma
, image_gamma
;
7345 struct png_memory_storage tbr
; /* Data to be read */
7347 /* Find out what file to load. */
7348 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7349 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7353 if (NILP (specified_data
))
7355 file
= x_find_image_file (specified_file
);
7356 if (!STRINGP (file
))
7358 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7363 /* Open the image file. */
7364 fp
= fopen (SDATA (file
), "rb");
7367 image_error ("Cannot open image file `%s'", file
, Qnil
);
7373 /* Check PNG signature. */
7374 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7375 || !png_check_sig (sig
, sizeof sig
))
7377 image_error ("Not a PNG file:` %s'", file
, Qnil
);
7385 /* Read from memory. */
7386 tbr
.bytes
= SDATA (specified_data
);
7387 tbr
.len
= SBYTES (specified_data
);
7390 /* Check PNG signature. */
7391 if (tbr
.len
< sizeof sig
7392 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7394 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7399 /* Need to skip past the signature. */
7400 tbr
.bytes
+= sizeof (sig
);
7403 /* Initialize read and info structs for PNG lib. */
7404 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7405 my_png_error
, my_png_warning
);
7408 if (fp
) fclose (fp
);
7413 info_ptr
= png_create_info_struct (png_ptr
);
7416 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7417 if (fp
) fclose (fp
);
7422 end_info
= png_create_info_struct (png_ptr
);
7425 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7426 if (fp
) fclose (fp
);
7431 /* Set error jump-back. We come back here when the PNG library
7432 detects an error. */
7433 if (setjmp (png_ptr
->jmpbuf
))
7437 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7440 if (fp
) fclose (fp
);
7445 /* Read image info. */
7446 if (!NILP (specified_data
))
7447 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7449 png_init_io (png_ptr
, fp
);
7451 png_set_sig_bytes (png_ptr
, sizeof sig
);
7452 png_read_info (png_ptr
, info_ptr
);
7453 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7454 &interlace_type
, NULL
, NULL
);
7456 /* If image contains simply transparency data, we prefer to
7457 construct a clipping mask. */
7458 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7463 /* This function is easier to write if we only have to handle
7464 one data format: RGB or RGBA with 8 bits per channel. Let's
7465 transform other formats into that format. */
7467 /* Strip more than 8 bits per channel. */
7468 if (bit_depth
== 16)
7469 png_set_strip_16 (png_ptr
);
7471 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7473 png_set_expand (png_ptr
);
7475 /* Convert grayscale images to RGB. */
7476 if (color_type
== PNG_COLOR_TYPE_GRAY
7477 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7478 png_set_gray_to_rgb (png_ptr
);
7480 /* The value 2.2 is a guess for PC monitors from PNG example.c. */
7481 gamma_str
= getenv ("SCREEN_GAMMA");
7482 screen_gamma
= gamma_str
? atof (gamma_str
) : 2.2;
7484 /* Tell the PNG lib to handle gamma correction for us. */
7486 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7487 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7488 /* There is a special chunk in the image specifying the gamma. */
7489 png_set_sRGB (png_ptr
, info_ptr
, intent
);
7492 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7493 /* Image contains gamma information. */
7494 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7496 /* Use a default of 0.5 for the image gamma. */
7497 png_set_gamma (png_ptr
, screen_gamma
, 0.5);
7499 /* Handle alpha channel by combining the image with a background
7500 color. Do this only if a real alpha channel is supplied. For
7501 simple transparency, we prefer a clipping mask. */
7504 png_color_16
*image_background
;
7506 if (png_get_bKGD (png_ptr
, info_ptr
, &image_background
))
7507 /* Image contains a background color with which to
7508 combine the image. */
7509 png_set_background (png_ptr
, image_background
,
7510 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
7513 /* Image does not contain a background color with which
7514 to combine the image data via an alpha channel. Use
7515 the frame's background instead. */
7518 png_color_16 frame_background
;
7521 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
7522 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7523 XQueryColor (FRAME_W32_DISPLAY (f
), cmap
, &color
);
7526 bzero (&frame_background
, sizeof frame_background
);
7527 frame_background
.red
= color
.red
;
7528 frame_background
.green
= color
.green
;
7529 frame_background
.blue
= color
.blue
;
7531 png_set_background (png_ptr
, &frame_background
,
7532 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7536 /* Update info structure. */
7537 png_read_update_info (png_ptr
, info_ptr
);
7539 /* Get number of channels. Valid values are 1 for grayscale images
7540 and images with a palette, 2 for grayscale images with transparency
7541 information (alpha channel), 3 for RGB images, and 4 for RGB
7542 images with alpha channel, i.e. RGBA. If conversions above were
7543 sufficient we should only have 3 or 4 channels here. */
7544 channels
= png_get_channels (png_ptr
, info_ptr
);
7545 xassert (channels
== 3 || channels
== 4);
7547 /* Number of bytes needed for one row of the image. */
7548 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
7550 /* Allocate memory for the image. */
7551 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
7552 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
7553 for (i
= 0; i
< height
; ++i
)
7554 rows
[i
] = pixels
+ i
* row_bytes
;
7556 /* Read the entire image. */
7557 png_read_image (png_ptr
, rows
);
7558 png_read_end (png_ptr
, info_ptr
);
7567 /* Create the X image and pixmap. */
7568 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7575 /* Create an image and pixmap serving as mask if the PNG image
7576 contains an alpha channel. */
7579 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
7580 &mask_img
, &img
->mask
))
7582 x_destroy_x_image (ximg
);
7583 XFreePixmap (FRAME_W32_DISPLAY (f
), img
->pixmap
);
7589 /* Fill the X image and mask from PNG data. */
7590 init_color_table ();
7592 for (y
= 0; y
< height
; ++y
)
7594 png_byte
*p
= rows
[y
];
7596 for (x
= 0; x
< width
; ++x
)
7603 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7605 /* An alpha channel, aka mask channel, associates variable
7606 transparency with an image. Where other image formats
7607 support binary transparency---fully transparent or fully
7608 opaque---PNG allows up to 254 levels of partial transparency.
7609 The PNG library implements partial transparency by combining
7610 the image with a specified background color.
7612 I'm not sure how to handle this here nicely: because the
7613 background on which the image is displayed may change, for
7614 real alpha channel support, it would be necessary to create
7615 a new image for each possible background.
7617 What I'm doing now is that a mask is created if we have
7618 boolean transparency information. Otherwise I'm using
7619 the frame's background color to combine the image with. */
7624 XPutPixel (mask_img
, x
, y
, *p
> 0);
7630 /* Remember colors allocated for this image. */
7631 img
->colors
= colors_in_color_table (&img
->ncolors
);
7632 free_color_table ();
7635 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7640 img
->height
= height
;
7642 /* Put the image into the pixmap, then free the X image and its buffer. */
7643 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7644 x_destroy_x_image (ximg
);
7646 /* Same for the mask. */
7649 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7650 x_destroy_x_image (mask_img
);
7658 #endif /* HAVE_PNG != 0 */
7662 /***********************************************************************
7664 ***********************************************************************/
7668 /* Work around a warning about HAVE_STDLIB_H being redefined in
7670 #ifdef HAVE_STDLIB_H
7671 #define HAVE_STDLIB_H_1
7672 #undef HAVE_STDLIB_H
7673 #endif /* HAVE_STLIB_H */
7675 #include <jpeglib.h>
7679 #ifdef HAVE_STLIB_H_1
7680 #define HAVE_STDLIB_H 1
7683 static int jpeg_image_p
P_ ((Lisp_Object object
));
7684 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
7686 /* The symbol `jpeg' identifying images of this type. */
7690 /* Indices of image specification fields in gs_format, below. */
7692 enum jpeg_keyword_index
7701 JPEG_HEURISTIC_MASK
,
7705 /* Vector of image_keyword structures describing the format
7706 of valid user-defined image specifications. */
7708 static struct image_keyword jpeg_format
[JPEG_LAST
] =
7710 {":type", IMAGE_SYMBOL_VALUE
, 1},
7711 {":data", IMAGE_STRING_VALUE
, 0},
7712 {":file", IMAGE_STRING_VALUE
, 0},
7713 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7714 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7715 {":relief", IMAGE_INTEGER_VALUE
, 0},
7716 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7717 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7720 /* Structure describing the image type `jpeg'. */
7722 static struct image_type jpeg_type
=
7732 /* Return non-zero if OBJECT is a valid JPEG image specification. */
7735 jpeg_image_p (object
)
7738 struct image_keyword fmt
[JPEG_LAST
];
7740 bcopy (jpeg_format
, fmt
, sizeof fmt
);
7742 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
)
7743 || (fmt
[JPEG_ASCENT
].count
7744 && XFASTINT (fmt
[JPEG_ASCENT
].value
) > 100))
7747 /* Must specify either the :data or :file keyword. */
7748 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
7752 struct my_jpeg_error_mgr
7754 struct jpeg_error_mgr pub
;
7755 jmp_buf setjmp_buffer
;
7759 my_error_exit (cinfo
)
7762 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
7763 longjmp (mgr
->setjmp_buffer
, 1);
7766 /* Init source method for JPEG data source manager. Called by
7767 jpeg_read_header() before any data is actually read. See
7768 libjpeg.doc from the JPEG lib distribution. */
7771 our_init_source (cinfo
)
7772 j_decompress_ptr cinfo
;
7777 /* Fill input buffer method for JPEG data source manager. Called
7778 whenever more data is needed. We read the whole image in one step,
7779 so this only adds a fake end of input marker at the end. */
7782 our_fill_input_buffer (cinfo
)
7783 j_decompress_ptr cinfo
;
7785 /* Insert a fake EOI marker. */
7786 struct jpeg_source_mgr
*src
= cinfo
->src
;
7787 static JOCTET buffer
[2];
7789 buffer
[0] = (JOCTET
) 0xFF;
7790 buffer
[1] = (JOCTET
) JPEG_EOI
;
7792 src
->next_input_byte
= buffer
;
7793 src
->bytes_in_buffer
= 2;
7798 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
7799 is the JPEG data source manager. */
7802 our_skip_input_data (cinfo
, num_bytes
)
7803 j_decompress_ptr cinfo
;
7806 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7810 if (num_bytes
> src
->bytes_in_buffer
)
7811 ERREXIT (cinfo
, JERR_INPUT_EOF
);
7813 src
->bytes_in_buffer
-= num_bytes
;
7814 src
->next_input_byte
+= num_bytes
;
7819 /* Method to terminate data source. Called by
7820 jpeg_finish_decompress() after all data has been processed. */
7823 our_term_source (cinfo
)
7824 j_decompress_ptr cinfo
;
7829 /* Set up the JPEG lib for reading an image from DATA which contains
7830 LEN bytes. CINFO is the decompression info structure created for
7831 reading the image. */
7834 jpeg_memory_src (cinfo
, data
, len
)
7835 j_decompress_ptr cinfo
;
7839 struct jpeg_source_mgr
*src
;
7841 if (cinfo
->src
== NULL
)
7843 /* First time for this JPEG object? */
7844 cinfo
->src
= (struct jpeg_source_mgr
*)
7845 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
7846 sizeof (struct jpeg_source_mgr
));
7847 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7848 src
->next_input_byte
= data
;
7851 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7852 src
->init_source
= our_init_source
;
7853 src
->fill_input_buffer
= our_fill_input_buffer
;
7854 src
->skip_input_data
= our_skip_input_data
;
7855 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
7856 src
->term_source
= our_term_source
;
7857 src
->bytes_in_buffer
= len
;
7858 src
->next_input_byte
= data
;
7862 /* Load image IMG for use on frame F. Patterned after example.c
7863 from the JPEG lib. */
7870 struct jpeg_decompress_struct cinfo
;
7871 struct my_jpeg_error_mgr mgr
;
7872 Lisp_Object file
, specified_file
;
7873 Lisp_Object specified_data
;
7876 int row_stride
, x
, y
;
7877 XImage
*ximg
= NULL
;
7879 unsigned long *colors
;
7881 struct gcpro gcpro1
;
7883 /* Open the JPEG file. */
7884 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7885 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7889 if (NILP (specified_data
))
7891 file
= x_find_image_file (specified_file
);
7892 if (!STRINGP (file
))
7894 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7899 fp
= fopen (SDATA (file
), "r");
7902 image_error ("Cannot open `%s'", file
, Qnil
);
7908 /* Customize libjpeg's error handling to call my_error_exit when an
7909 error is detected. This function will perform a longjmp. */
7910 mgr
.pub
.error_exit
= my_error_exit
;
7911 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
7913 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
7917 /* Called from my_error_exit. Display a JPEG error. */
7918 char buffer
[JMSG_LENGTH_MAX
];
7919 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
7920 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
7921 build_string (buffer
));
7924 /* Close the input file and destroy the JPEG object. */
7927 jpeg_destroy_decompress (&cinfo
);
7931 /* If we already have an XImage, free that. */
7932 x_destroy_x_image (ximg
);
7934 /* Free pixmap and colors. */
7935 x_clear_image (f
, img
);
7942 /* Create the JPEG decompression object. Let it read from fp.
7943 Read the JPEG image header. */
7944 jpeg_create_decompress (&cinfo
);
7946 if (NILP (specified_data
))
7947 jpeg_stdio_src (&cinfo
, fp
);
7949 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
7950 SBYTES (specified_data
));
7952 jpeg_read_header (&cinfo
, TRUE
);
7954 /* Customize decompression so that color quantization will be used.
7955 Start decompression. */
7956 cinfo
.quantize_colors
= TRUE
;
7957 jpeg_start_decompress (&cinfo
);
7958 width
= img
->width
= cinfo
.output_width
;
7959 height
= img
->height
= cinfo
.output_height
;
7963 /* Create X image and pixmap. */
7964 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7968 longjmp (mgr
.setjmp_buffer
, 2);
7971 /* Allocate colors. When color quantization is used,
7972 cinfo.actual_number_of_colors has been set with the number of
7973 colors generated, and cinfo.colormap is a two-dimensional array
7974 of color indices in the range 0..cinfo.actual_number_of_colors.
7975 No more than 255 colors will be generated. */
7979 if (cinfo
.out_color_components
> 2)
7980 ir
= 0, ig
= 1, ib
= 2;
7981 else if (cinfo
.out_color_components
> 1)
7982 ir
= 0, ig
= 1, ib
= 0;
7984 ir
= 0, ig
= 0, ib
= 0;
7986 /* Use the color table mechanism because it handles colors that
7987 cannot be allocated nicely. Such colors will be replaced with
7988 a default color, and we don't have to care about which colors
7989 can be freed safely, and which can't. */
7990 init_color_table ();
7991 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
7994 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
7996 /* Multiply RGB values with 255 because X expects RGB values
7997 in the range 0..0xffff. */
7998 int r
= cinfo
.colormap
[ir
][i
] << 8;
7999 int g
= cinfo
.colormap
[ig
][i
] << 8;
8000 int b
= cinfo
.colormap
[ib
][i
] << 8;
8001 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8004 /* Remember those colors actually allocated. */
8005 img
->colors
= colors_in_color_table (&img
->ncolors
);
8006 free_color_table ();
8010 row_stride
= width
* cinfo
.output_components
;
8011 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8013 for (y
= 0; y
< height
; ++y
)
8015 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8016 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8017 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8021 jpeg_finish_decompress (&cinfo
);
8022 jpeg_destroy_decompress (&cinfo
);
8026 /* Put the image into the pixmap. */
8027 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8028 x_destroy_x_image (ximg
);
8034 #endif /* HAVE_JPEG */
8038 /***********************************************************************
8040 ***********************************************************************/
8046 static int tiff_image_p
P_ ((Lisp_Object object
));
8047 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8049 /* The symbol `tiff' identifying images of this type. */
8053 /* Indices of image specification fields in tiff_format, below. */
8055 enum tiff_keyword_index
8064 TIFF_HEURISTIC_MASK
,
8068 /* Vector of image_keyword structures describing the format
8069 of valid user-defined image specifications. */
8071 static struct image_keyword tiff_format
[TIFF_LAST
] =
8073 {":type", IMAGE_SYMBOL_VALUE
, 1},
8074 {":data", IMAGE_STRING_VALUE
, 0},
8075 {":file", IMAGE_STRING_VALUE
, 0},
8076 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8077 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8078 {":relief", IMAGE_INTEGER_VALUE
, 0},
8079 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8080 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
8083 /* Structure describing the image type `tiff'. */
8085 static struct image_type tiff_type
=
8095 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8098 tiff_image_p (object
)
8101 struct image_keyword fmt
[TIFF_LAST
];
8102 bcopy (tiff_format
, fmt
, sizeof fmt
);
8104 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
)
8105 || (fmt
[TIFF_ASCENT
].count
8106 && XFASTINT (fmt
[TIFF_ASCENT
].value
) > 100))
8109 /* Must specify either the :data or :file keyword. */
8110 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8114 /* Reading from a memory buffer for TIFF images Based on the PNG
8115 memory source, but we have to provide a lot of extra functions.
8118 We really only need to implement read and seek, but I am not
8119 convinced that the TIFF library is smart enough not to destroy
8120 itself if we only hand it the function pointers we need to
8125 unsigned char *bytes
;
8132 tiff_read_from_memory (data
, buf
, size
)
8137 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8139 if (size
> src
->len
- src
->index
)
8141 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8147 tiff_write_from_memory (data
, buf
, size
)
8156 tiff_seek_in_memory (data
, off
, whence
)
8161 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8166 case SEEK_SET
: /* Go from beginning of source. */
8170 case SEEK_END
: /* Go from end of source. */
8171 idx
= src
->len
+ off
;
8174 case SEEK_CUR
: /* Go from current position. */
8175 idx
= src
->index
+ off
;
8178 default: /* Invalid `whence'. */
8182 if (idx
> src
->len
|| idx
< 0)
8190 tiff_close_memory (data
)
8198 tiff_mmap_memory (data
, pbase
, psize
)
8203 /* It is already _IN_ memory. */
8208 tiff_unmap_memory (data
, base
, size
)
8213 /* We don't need to do this. */
8217 tiff_size_of_memory (data
)
8220 return ((tiff_memory_source
*) data
)->len
;
8223 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8231 Lisp_Object file
, specified_file
;
8232 Lisp_Object specified_data
;
8234 int width
, height
, x
, y
;
8238 struct gcpro gcpro1
;
8239 tiff_memory_source memsrc
;
8241 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8242 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8246 if (NILP (specified_data
))
8248 /* Read from a file */
8249 file
= x_find_image_file (specified_file
);
8250 if (!STRINGP (file
))
8252 image_error ("Cannot find image file `%s'", file
, Qnil
);
8257 /* Try to open the image file. */
8258 tiff
= TIFFOpen (SDATA (file
), "r");
8261 image_error ("Cannot open `%s'", file
, Qnil
);
8268 /* Memory source! */
8269 memsrc
.bytes
= SDATA (specified_data
);
8270 memsrc
.len
= SBYTES (specified_data
);
8273 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8274 (TIFFReadWriteProc
) tiff_read_from_memory
,
8275 (TIFFReadWriteProc
) tiff_write_from_memory
,
8276 tiff_seek_in_memory
,
8278 tiff_size_of_memory
,
8284 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8290 /* Get width and height of the image, and allocate a raster buffer
8291 of width x height 32-bit values. */
8292 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8293 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8294 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8296 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8300 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8308 /* Create the X image and pixmap. */
8309 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8317 /* Initialize the color table. */
8318 init_color_table ();
8320 /* Process the pixel raster. Origin is in the lower-left corner. */
8321 for (y
= 0; y
< height
; ++y
)
8323 uint32
*row
= buf
+ y
* width
;
8325 for (x
= 0; x
< width
; ++x
)
8327 uint32 abgr
= row
[x
];
8328 int r
= TIFFGetR (abgr
) << 8;
8329 int g
= TIFFGetG (abgr
) << 8;
8330 int b
= TIFFGetB (abgr
) << 8;
8331 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8335 /* Remember the colors allocated for the image. Free the color table. */
8336 img
->colors
= colors_in_color_table (&img
->ncolors
);
8337 free_color_table ();
8339 /* Put the image into the pixmap, then free the X image and its buffer. */
8340 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8341 x_destroy_x_image (ximg
);
8346 img
->height
= height
;
8352 #endif /* HAVE_TIFF != 0 */
8356 /***********************************************************************
8358 ***********************************************************************/
8362 #include <gif_lib.h>
8364 static int gif_image_p
P_ ((Lisp_Object object
));
8365 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8367 /* The symbol `gif' identifying images of this type. */
8371 /* Indices of image specification fields in gif_format, below. */
8373 enum gif_keyword_index
8387 /* Vector of image_keyword structures describing the format
8388 of valid user-defined image specifications. */
8390 static struct image_keyword gif_format
[GIF_LAST
] =
8392 {":type", IMAGE_SYMBOL_VALUE
, 1},
8393 {":data", IMAGE_STRING_VALUE
, 0},
8394 {":file", IMAGE_STRING_VALUE
, 0},
8395 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8396 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8397 {":relief", IMAGE_INTEGER_VALUE
, 0},
8398 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8399 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8400 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
8403 /* Structure describing the image type `gif'. */
8405 static struct image_type gif_type
=
8414 /* Return non-zero if OBJECT is a valid GIF image specification. */
8417 gif_image_p (object
)
8420 struct image_keyword fmt
[GIF_LAST
];
8421 bcopy (gif_format
, fmt
, sizeof fmt
);
8423 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
)
8424 || (fmt
[GIF_ASCENT
].count
8425 && XFASTINT (fmt
[GIF_ASCENT
].value
) > 100))
8428 /* Must specify either the :data or :file keyword. */
8429 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8432 /* Reading a GIF image from memory
8433 Based on the PNG memory stuff to a certain extent. */
8437 unsigned char *bytes
;
8443 /* Make the current memory source available to gif_read_from_memory.
8444 It's done this way because not all versions of libungif support
8445 a UserData field in the GifFileType structure. */
8446 static gif_memory_source
*current_gif_memory_src
;
8449 gif_read_from_memory (file
, buf
, len
)
8454 gif_memory_source
*src
= current_gif_memory_src
;
8456 if (len
> src
->len
- src
->index
)
8459 bcopy (src
->bytes
+ src
->index
, buf
, len
);
8465 /* Load GIF image IMG for use on frame F. Value is non-zero if
8473 Lisp_Object file
, specified_file
;
8474 Lisp_Object specified_data
;
8475 int rc
, width
, height
, x
, y
, i
;
8477 ColorMapObject
*gif_color_map
;
8478 unsigned long pixel_colors
[256];
8480 struct gcpro gcpro1
;
8482 int ino
, image_left
, image_top
, image_width
, image_height
;
8483 gif_memory_source memsrc
;
8484 unsigned char *raster
;
8486 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8487 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8491 if (NILP (specified_data
))
8493 file
= x_find_image_file (specified_file
);
8494 if (!STRINGP (file
))
8496 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8501 /* Open the GIF file. */
8502 gif
= DGifOpenFileName (SDATA (file
));
8505 image_error ("Cannot open `%s'", file
, Qnil
);
8512 /* Read from memory! */
8513 current_gif_memory_src
= &memsrc
;
8514 memsrc
.bytes
= SDATA (specified_data
);
8515 memsrc
.len
= SBYTES (specified_data
);
8518 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
8521 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
8527 /* Read entire contents. */
8528 rc
= DGifSlurp (gif
);
8529 if (rc
== GIF_ERROR
)
8531 image_error ("Error reading `%s'", img
->spec
, Qnil
);
8532 DGifCloseFile (gif
);
8537 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
8538 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
8539 if (ino
>= gif
->ImageCount
)
8541 image_error ("Invalid image number `%s' in image `%s'",
8543 DGifCloseFile (gif
);
8548 width
= img
->width
= gif
->SWidth
;
8549 height
= img
->height
= gif
->SHeight
;
8553 /* Create the X image and pixmap. */
8554 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8557 DGifCloseFile (gif
);
8562 /* Allocate colors. */
8563 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
8565 gif_color_map
= gif
->SColorMap
;
8566 init_color_table ();
8567 bzero (pixel_colors
, sizeof pixel_colors
);
8569 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
8571 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
8572 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
8573 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
8574 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8577 img
->colors
= colors_in_color_table (&img
->ncolors
);
8578 free_color_table ();
8580 /* Clear the part of the screen image that are not covered by
8581 the image from the GIF file. Full animated GIF support
8582 requires more than can be done here (see the gif89 spec,
8583 disposal methods). Let's simply assume that the part
8584 not covered by a sub-image is in the frame's background color. */
8585 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
8586 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
8587 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
8588 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
8590 for (y
= 0; y
< image_top
; ++y
)
8591 for (x
= 0; x
< width
; ++x
)
8592 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8594 for (y
= image_top
+ image_height
; y
< height
; ++y
)
8595 for (x
= 0; x
< width
; ++x
)
8596 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8598 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
8600 for (x
= 0; x
< image_left
; ++x
)
8601 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8602 for (x
= image_left
+ image_width
; x
< width
; ++x
)
8603 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8606 /* Read the GIF image into the X image. We use a local variable
8607 `raster' here because RasterBits below is a char *, and invites
8608 problems with bytes >= 0x80. */
8609 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
8611 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
8613 static int interlace_start
[] = {0, 4, 2, 1};
8614 static int interlace_increment
[] = {8, 8, 4, 2};
8616 int row
= interlace_start
[0];
8620 for (y
= 0; y
< image_height
; y
++)
8622 if (row
>= image_height
)
8624 row
= interlace_start
[++pass
];
8625 while (row
>= image_height
)
8626 row
= interlace_start
[++pass
];
8629 for (x
= 0; x
< image_width
; x
++)
8631 int i
= raster
[(y
* image_width
) + x
];
8632 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
8636 row
+= interlace_increment
[pass
];
8641 for (y
= 0; y
< image_height
; ++y
)
8642 for (x
= 0; x
< image_width
; ++x
)
8644 int i
= raster
[y
* image_width
+ x
];
8645 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
8649 DGifCloseFile (gif
);
8651 /* Put the image into the pixmap, then free the X image and its buffer. */
8652 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8653 x_destroy_x_image (ximg
);
8660 #endif /* HAVE_GIF != 0 */
8664 /***********************************************************************
8666 ***********************************************************************/
8668 #ifdef HAVE_GHOSTSCRIPT
8669 static int gs_image_p
P_ ((Lisp_Object object
));
8670 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
8671 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
8673 /* The symbol `postscript' identifying images of this type. */
8675 Lisp_Object Qpostscript
;
8677 /* Keyword symbols. */
8679 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
8681 /* Indices of image specification fields in gs_format, below. */
8683 enum gs_keyword_index
8699 /* Vector of image_keyword structures describing the format
8700 of valid user-defined image specifications. */
8702 static struct image_keyword gs_format
[GS_LAST
] =
8704 {":type", IMAGE_SYMBOL_VALUE
, 1},
8705 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8706 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8707 {":file", IMAGE_STRING_VALUE
, 1},
8708 {":loader", IMAGE_FUNCTION_VALUE
, 0},
8709 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
8710 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8711 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8712 {":relief", IMAGE_INTEGER_VALUE
, 0},
8713 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8714 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
8717 /* Structure describing the image type `ghostscript'. */
8719 static struct image_type gs_type
=
8729 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8732 gs_clear_image (f
, img
)
8736 /* IMG->data.ptr_val may contain a recorded colormap. */
8737 xfree (img
->data
.ptr_val
);
8738 x_clear_image (f
, img
);
8742 /* Return non-zero if OBJECT is a valid Ghostscript image
8749 struct image_keyword fmt
[GS_LAST
];
8753 bcopy (gs_format
, fmt
, sizeof fmt
);
8755 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
)
8756 || (fmt
[GS_ASCENT
].count
8757 && XFASTINT (fmt
[GS_ASCENT
].value
) > 100))
8760 /* Bounding box must be a list or vector containing 4 integers. */
8761 tem
= fmt
[GS_BOUNDING_BOX
].value
;
8764 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
8765 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
8770 else if (VECTORP (tem
))
8772 if (XVECTOR (tem
)->size
!= 4)
8774 for (i
= 0; i
< 4; ++i
)
8775 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
8785 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
8794 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
8795 struct gcpro gcpro1
, gcpro2
;
8797 double in_width
, in_height
;
8798 Lisp_Object pixel_colors
= Qnil
;
8800 /* Compute pixel size of pixmap needed from the given size in the
8801 image specification. Sizes in the specification are in pt. 1 pt
8802 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8804 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
8805 in_width
= XFASTINT (pt_width
) / 72.0;
8806 img
->width
= in_width
* FRAME_W32_DISPLAY_INFO (f
)->resx
;
8807 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
8808 in_height
= XFASTINT (pt_height
) / 72.0;
8809 img
->height
= in_height
* FRAME_W32_DISPLAY_INFO (f
)->resy
;
8811 /* Create the pixmap. */
8813 xassert (img
->pixmap
== 0);
8814 img
->pixmap
= XCreatePixmap (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
8815 img
->width
, img
->height
,
8816 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
8821 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
8825 /* Call the loader to fill the pixmap. It returns a process object
8826 if successful. We do not record_unwind_protect here because
8827 other places in redisplay like calling window scroll functions
8828 don't either. Let the Lisp loader use `unwind-protect' instead. */
8829 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
8831 sprintf (buffer
, "%lu %lu",
8832 (unsigned long) FRAME_W32_WINDOW (f
),
8833 (unsigned long) img
->pixmap
);
8834 window_and_pixmap_id
= build_string (buffer
);
8836 sprintf (buffer
, "%lu %lu",
8837 FRAME_FOREGROUND_PIXEL (f
),
8838 FRAME_BACKGROUND_PIXEL (f
));
8839 pixel_colors
= build_string (buffer
);
8841 XSETFRAME (frame
, f
);
8842 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
8844 loader
= intern ("gs-load-image");
8846 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
8847 make_number (img
->width
),
8848 make_number (img
->height
),
8849 window_and_pixmap_id
,
8852 return PROCESSP (img
->data
.lisp_val
);
8856 /* Kill the Ghostscript process that was started to fill PIXMAP on
8857 frame F. Called from XTread_socket when receiving an event
8858 telling Emacs that Ghostscript has finished drawing. */
8861 x_kill_gs_process (pixmap
, f
)
8865 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
8869 /* Find the image containing PIXMAP. */
8870 for (i
= 0; i
< c
->used
; ++i
)
8871 if (c
->images
[i
]->pixmap
== pixmap
)
8874 /* Kill the GS process. We should have found PIXMAP in the image
8875 cache and its image should contain a process object. */
8876 xassert (i
< c
->used
);
8878 xassert (PROCESSP (img
->data
.lisp_val
));
8879 Fkill_process (img
->data
.lisp_val
, Qnil
);
8880 img
->data
.lisp_val
= Qnil
;
8882 /* On displays with a mutable colormap, figure out the colors
8883 allocated for the image by looking at the pixels of an XImage for
8885 class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
8886 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
8892 /* Try to get an XImage for img->pixmep. */
8893 ximg
= XGetImage (FRAME_W32_DISPLAY (f
), img
->pixmap
,
8894 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
8899 /* Initialize the color table. */
8900 init_color_table ();
8902 /* For each pixel of the image, look its color up in the
8903 color table. After having done so, the color table will
8904 contain an entry for each color used by the image. */
8905 for (y
= 0; y
< img
->height
; ++y
)
8906 for (x
= 0; x
< img
->width
; ++x
)
8908 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8909 lookup_pixel_color (f
, pixel
);
8912 /* Record colors in the image. Free color table and XImage. */
8913 img
->colors
= colors_in_color_table (&img
->ncolors
);
8914 free_color_table ();
8915 XDestroyImage (ximg
);
8917 #if 0 /* This doesn't seem to be the case. If we free the colors
8918 here, we get a BadAccess later in x_clear_image when
8919 freeing the colors. */
8920 /* We have allocated colors once, but Ghostscript has also
8921 allocated colors on behalf of us. So, to get the
8922 reference counts right, free them once. */
8925 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
8926 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
,
8927 img
->colors
, img
->ncolors
, 0);
8932 image_error ("Cannot get X image of `%s'; colors will not be freed",
8939 #endif /* HAVE_GHOSTSCRIPT */
8942 /***********************************************************************
8944 ***********************************************************************/
8946 DEFUN ("x-change-window-property", Fx_change_window_property
,
8947 Sx_change_window_property
, 2, 3, 0,
8948 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
8949 PROP and VALUE must be strings. FRAME nil or omitted means use the
8950 selected frame. Value is VALUE. */)
8951 (prop
, value
, frame
)
8952 Lisp_Object frame
, prop
, value
;
8954 #if 0 /* MAC_TODO : port window properties to Mac */
8955 struct frame
*f
= check_x_frame (frame
);
8958 CHECK_STRING (prop
);
8959 CHECK_STRING (value
);
8962 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
8963 XChangeProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
8964 prop_atom
, XA_STRING
, 8, PropModeReplace
,
8965 SDATA (value
), SCHARS (value
));
8967 /* Make sure the property is set when we return. */
8968 XFlush (FRAME_W32_DISPLAY (f
));
8971 #endif /* MAC_TODO */
8977 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
8978 Sx_delete_window_property
, 1, 2, 0,
8979 doc
: /* Remove window property PROP from X window of FRAME.
8980 FRAME nil or omitted means use the selected frame. Value is PROP. */)
8982 Lisp_Object prop
, frame
;
8984 #if 0 /* MAC_TODO : port window properties to Mac */
8986 struct frame
*f
= check_x_frame (frame
);
8989 CHECK_STRING (prop
);
8991 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
8992 XDeleteProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), prop_atom
);
8994 /* Make sure the property is removed when we return. */
8995 XFlush (FRAME_W32_DISPLAY (f
));
8997 #endif /* MAC_TODO */
9003 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9005 doc
: /* Value is the value of window property PROP on FRAME.
9006 If FRAME is nil or omitted, use the selected frame. Value is nil
9007 if FRAME hasn't a property with name PROP or if PROP has no string
9010 Lisp_Object prop
, frame
;
9012 #if 0 /* MAC_TODO : port window properties to Mac */
9014 struct frame
*f
= check_x_frame (frame
);
9017 Lisp_Object prop_value
= Qnil
;
9018 char *tmp_data
= NULL
;
9021 unsigned long actual_size
, bytes_remaining
;
9023 CHECK_STRING (prop
);
9025 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
9026 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9027 prop_atom
, 0, 0, False
, XA_STRING
,
9028 &actual_type
, &actual_format
, &actual_size
,
9029 &bytes_remaining
, (unsigned char **) &tmp_data
);
9032 int size
= bytes_remaining
;
9037 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9038 prop_atom
, 0, bytes_remaining
,
9040 &actual_type
, &actual_format
,
9041 &actual_size
, &bytes_remaining
,
9042 (unsigned char **) &tmp_data
);
9044 prop_value
= make_string (tmp_data
, size
);
9053 #endif /* MAC_TODO */
9059 /***********************************************************************
9061 ***********************************************************************/
9063 /* If non-null, an asynchronous timer that, when it expires, displays
9064 an hourglass cursor on all frames. */
9066 static struct atimer
*hourglass_atimer
;
9068 /* Non-zero means an hourglass cursor is currently shown. */
9070 static int hourglass_shown_p
;
9072 /* Number of seconds to wait before displaying an hourglass cursor. */
9074 static Lisp_Object Vhourglass_delay
;
9076 /* Default number of seconds to wait before displaying an hourglass
9079 #define DEFAULT_HOURGLASS_DELAY 1
9081 /* Function prototypes. */
9083 static void show_hourglass
P_ ((struct atimer
*));
9084 static void hide_hourglass
P_ ((void));
9087 /* Cancel a currently active hourglass timer, and start a new one. */
9092 #if 0 /* MAC_TODO: cursor shape changes. */
9094 int secs
, usecs
= 0;
9096 cancel_hourglass ();
9098 if (INTEGERP (Vhourglass_delay
)
9099 && XINT (Vhourglass_delay
) > 0)
9100 secs
= XFASTINT (Vhourglass_delay
);
9101 else if (FLOATP (Vhourglass_delay
)
9102 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9105 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9106 secs
= XFASTINT (tem
);
9107 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9110 secs
= DEFAULT_HOURGLASS_DELAY
;
9112 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9113 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9114 show_hourglass
, NULL
);
9115 #endif /* MAC_TODO */
9119 /* Cancel the hourglass cursor timer if active, hide an hourglass
9125 if (hourglass_atimer
)
9127 cancel_atimer (hourglass_atimer
);
9128 hourglass_atimer
= NULL
;
9131 if (hourglass_shown_p
)
9136 /* Timer function of hourglass_atimer. TIMER is equal to
9139 Display an hourglass cursor on all frames by mapping the frames'
9140 hourglass_window. Set the hourglass_p flag in the frames'
9141 output_data.x structure to indicate that an hourglass cursor is
9142 shown on the frames. */
9145 show_hourglass (timer
)
9146 struct atimer
*timer
;
9148 #if 0 /* MAC_TODO: cursor shape changes. */
9149 /* The timer implementation will cancel this timer automatically
9150 after this function has run. Set hourglass_atimer to null
9151 so that we know the timer doesn't have to be canceled. */
9152 hourglass_atimer
= NULL
;
9154 if (!hourglass_shown_p
)
9156 Lisp_Object rest
, frame
;
9160 FOR_EACH_FRAME (rest
, frame
)
9161 if (FRAME_W32_P (XFRAME (frame
)))
9163 struct frame
*f
= XFRAME (frame
);
9165 f
->output_data
.w32
->hourglass_p
= 1;
9167 if (!f
->output_data
.w32
->hourglass_window
)
9169 unsigned long mask
= CWCursor
;
9170 XSetWindowAttributes attrs
;
9172 attrs
.cursor
= f
->output_data
.w32
->hourglass_cursor
;
9174 f
->output_data
.w32
->hourglass_window
9175 = XCreateWindow (FRAME_X_DISPLAY (f
),
9176 FRAME_OUTER_WINDOW (f
),
9177 0, 0, 32000, 32000, 0, 0,
9183 XMapRaised (FRAME_X_DISPLAY (f
),
9184 f
->output_data
.w32
->hourglass_window
);
9185 XFlush (FRAME_X_DISPLAY (f
));
9188 hourglass_shown_p
= 1;
9191 #endif /* MAC_TODO */
9195 /* Hide the hourglass cursor on all frames, if it is currently shown. */
9200 #if 0 /* MAC_TODO: cursor shape changes. */
9201 if (hourglass_shown_p
)
9203 Lisp_Object rest
, frame
;
9206 FOR_EACH_FRAME (rest
, frame
)
9208 struct frame
*f
= XFRAME (frame
);
9211 /* Watch out for newly created frames. */
9212 && f
->output_data
.x
->hourglass_window
)
9214 XUnmapWindow (FRAME_X_DISPLAY (f
),
9215 f
->output_data
.x
->hourglass_window
);
9216 /* Sync here because XTread_socket looks at the
9217 hourglass_p flag that is reset to zero below. */
9218 XSync (FRAME_X_DISPLAY (f
), False
);
9219 f
->output_data
.x
->hourglass_p
= 0;
9223 hourglass_shown_p
= 0;
9226 #endif /* MAC_TODO */
9231 /***********************************************************************
9233 ***********************************************************************/
9235 static Lisp_Object x_create_tip_frame
P_ ((struct mac_display_info
*,
9238 /* The frame of a currently visible tooltip, or null. */
9240 Lisp_Object tip_frame
;
9242 /* If non-nil, a timer started that hides the last tooltip when it
9245 Lisp_Object tip_timer
;
9248 /* If non-nil, a vector of 3 elements containing the last args
9249 with which x-show-tip was called. See there. */
9251 Lisp_Object last_show_tip_args
;
9253 /* Create a frame for a tooltip on the display described by DPYINFO.
9254 PARMS is a list of frame parameters. Value is the frame. */
9257 x_create_tip_frame (dpyinfo
, parms
)
9258 struct mac_display_info
*dpyinfo
;
9261 #if 0 /* MAC_TODO : Mac version */
9263 Lisp_Object frame
, tem
;
9265 long window_prompting
= 0;
9267 int count
= SPECPDL_INDEX ();
9268 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9273 /* Use this general default value to start with until we know if
9274 this frame has a specified name. */
9275 Vx_resource_name
= Vinvocation_name
;
9278 kb
= dpyinfo
->kboard
;
9280 kb
= &the_only_kboard
;
9283 /* Get the name of the frame to use for resource lookup. */
9284 name
= w32_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9286 && !EQ (name
, Qunbound
)
9288 error ("Invalid frame name--not a string or nil");
9289 Vx_resource_name
= name
;
9292 GCPRO3 (parms
, name
, frame
);
9293 tip_frame
= f
= make_frame (1);
9294 XSETFRAME (frame
, f
);
9295 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9297 f
->output_method
= output_w32
;
9298 f
->output_data
.w32
=
9299 (struct w32_output
*) xmalloc (sizeof (struct w32_output
));
9300 bzero (f
->output_data
.w32
, sizeof (struct w32_output
));
9302 f
->output_data
.w32
->icon_bitmap
= -1;
9304 f
->output_data
.w32
->fontset
= -1;
9305 f
->icon_name
= Qnil
;
9308 FRAME_KBOARD (f
) = kb
;
9310 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
9311 f
->output_data
.w32
->explicit_parent
= 0;
9313 /* Set the name; the functions to which we pass f expect the name to
9315 if (EQ (name
, Qunbound
) || NILP (name
))
9317 f
->name
= build_string (dpyinfo
->x_id_name
);
9318 f
->explicit_name
= 0;
9323 f
->explicit_name
= 1;
9324 /* use the frame's title when getting resources for this frame. */
9325 specbind (Qx_resource_name
, name
);
9328 /* Extract the window parameters from the supplied values
9329 that are needed to determine window geometry. */
9333 font
= w32_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
9336 /* First, try whatever font the caller has specified. */
9339 tem
= Fquery_fontset (font
, Qnil
);
9341 font
= x_new_fontset (f
, SDATA (tem
));
9343 font
= x_new_font (f
, SDATA (font
));
9346 /* Try out a font which we hope has bold and italic variations. */
9347 if (!STRINGP (font
))
9348 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
9349 if (!STRINGP (font
))
9350 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9351 if (! STRINGP (font
))
9352 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9353 if (! STRINGP (font
))
9354 /* This was formerly the first thing tried, but it finds too many fonts
9355 and takes too long. */
9356 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
9357 /* If those didn't work, look for something which will at least work. */
9358 if (! STRINGP (font
))
9359 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
9361 if (! STRINGP (font
))
9362 font
= build_string ("fixed");
9364 x_default_parameter (f
, parms
, Qfont
, font
,
9365 "font", "Font", RES_TYPE_STRING
);
9368 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
9369 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
9371 /* This defaults to 2 in order to match xterm. We recognize either
9372 internalBorderWidth or internalBorder (which is what xterm calls
9374 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9378 value
= w32_get_arg (parms
, Qinternal_border_width
,
9379 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
9380 if (! EQ (value
, Qunbound
))
9381 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
9385 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
9386 "internalBorderWidth", "internalBorderWidth",
9389 /* Also do the stuff which must be set before the window exists. */
9390 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
9391 "foreground", "Foreground", RES_TYPE_STRING
);
9392 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
9393 "background", "Background", RES_TYPE_STRING
);
9394 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
9395 "pointerColor", "Foreground", RES_TYPE_STRING
);
9396 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
9397 "cursorColor", "Foreground", RES_TYPE_STRING
);
9398 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
9399 "borderColor", "BorderColor", RES_TYPE_STRING
);
9401 /* Init faces before x_default_parameter is called for scroll-bar
9402 parameters because that function calls x_set_scroll_bar_width,
9403 which calls change_frame_size, which calls Fset_window_buffer,
9404 which runs hooks, which call Fvertical_motion. At the end, we
9405 end up in init_iterator with a null face cache, which should not
9407 init_frame_faces (f
);
9409 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
9410 window_prompting
= x_figure_window_size (f
, parms
);
9412 if (window_prompting
& XNegative
)
9414 if (window_prompting
& YNegative
)
9415 f
->output_data
.w32
->win_gravity
= SouthEastGravity
;
9417 f
->output_data
.w32
->win_gravity
= NorthEastGravity
;
9421 if (window_prompting
& YNegative
)
9422 f
->output_data
.w32
->win_gravity
= SouthWestGravity
;
9424 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9427 f
->output_data
.w32
->size_hint_flags
= window_prompting
;
9429 XSetWindowAttributes attrs
;
9433 mask
= CWBackPixel
| CWOverrideRedirect
| CWSaveUnder
| CWEventMask
;
9434 /* Window managers looks at the override-redirect flag to
9435 determine whether or net to give windows a decoration (Xlib
9437 attrs
.override_redirect
= True
;
9438 attrs
.save_under
= True
;
9439 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
9440 /* Arrange for getting MapNotify and UnmapNotify events. */
9441 attrs
.event_mask
= StructureNotifyMask
;
9443 = FRAME_W32_WINDOW (f
)
9444 = XCreateWindow (FRAME_W32_DISPLAY (f
),
9445 FRAME_W32_DISPLAY_INFO (f
)->root_window
,
9446 /* x, y, width, height */
9450 CopyFromParent
, InputOutput
, CopyFromParent
,
9457 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
9458 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9459 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
9460 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9461 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
9462 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
9464 /* Dimensions, especially f->height, must be done via change_frame_size.
9465 Change will not be effected unless different from the current
9470 SET_FRAME_WIDTH (f
, 0);
9471 change_frame_size (f
, height
, width
, 1, 0, 0);
9477 /* It is now ok to make the frame official even if we get an error
9478 below. And the frame needs to be on Vframe_list or making it
9479 visible won't work. */
9480 Vframe_list
= Fcons (frame
, Vframe_list
);
9482 /* Now that the frame is official, it counts as a reference to
9484 FRAME_W32_DISPLAY_INFO (f
)->reference_count
++;
9486 return unbind_to (count
, frame
);
9487 #endif /* MAC_TODO */
9492 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
9493 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
9494 A tooltip window is a small window displaying a string.
9496 FRAME nil or omitted means use the selected frame.
9498 PARMS is an optional list of frame parameters which can be used to
9499 change the tooltip's appearance.
9501 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
9502 means use the default timeout of 5 seconds.
9504 If the list of frame parameters PARAMS contains a `left' parameters,
9505 the tooltip is displayed at that x-position. Otherwise it is
9506 displayed at the mouse position, with offset DX added (default is 5 if
9507 DX isn't specified). Likewise for the y-position; if a `top' frame
9508 parameter is specified, it determines the y-position of the tooltip
9509 window, otherwise it is displayed at the mouse position, with offset
9510 DY added (default is 10). */)
9511 (string
, frame
, parms
, timeout
, dx
, dy
)
9512 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
9517 Lisp_Object buffer
, top
, left
;
9518 struct buffer
*old_buffer
;
9519 struct text_pos pos
;
9520 int i
, width
, height
;
9521 int root_x
, root_y
, win_x
, win_y
;
9523 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
9524 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
9525 int count
= SPECPDL_INDEX ();
9527 specbind (Qinhibit_redisplay
, Qt
);
9529 GCPRO4 (string
, parms
, frame
, timeout
);
9531 CHECK_STRING (string
);
9532 f
= check_x_frame (frame
);
9534 timeout
= make_number (5);
9536 CHECK_NATNUM (timeout
);
9539 dx
= make_number (5);
9544 dy
= make_number (-10);
9548 if (NILP (last_show_tip_args
))
9549 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
9551 if (!NILP (tip_frame
))
9553 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
9554 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
9555 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
9557 if (EQ (frame
, last_frame
)
9558 && !NILP (Fequal (last_string
, string
))
9559 && !NILP (Fequal (last_parms
, parms
)))
9561 struct frame
*f
= XFRAME (tip_frame
);
9563 /* Only DX and DY have changed. */
9564 if (!NILP (tip_timer
))
9566 Lisp_Object timer
= tip_timer
;
9568 call1 (Qcancel_timer
, timer
);
9571 #if 0 /* MAC_TODO : Mac specifics */
9573 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
9574 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9575 root_x
, root_y
- PIXEL_HEIGHT (f
));
9577 #endif /* MAC_TODO */
9582 /* Hide a previous tip, if any. */
9585 ASET (last_show_tip_args
, 0, string
);
9586 ASET (last_show_tip_args
, 1, frame
);
9587 ASET (last_show_tip_args
, 2, parms
);
9589 /* Add default values to frame parameters. */
9590 if (NILP (Fassq (Qname
, parms
)))
9591 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
9592 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9593 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
9594 if (NILP (Fassq (Qborder_width
, parms
)))
9595 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
9596 if (NILP (Fassq (Qborder_color
, parms
)))
9597 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
9598 if (NILP (Fassq (Qbackground_color
, parms
)))
9599 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
9602 /* Create a frame for the tooltip, and record it in the global
9603 variable tip_frame. */
9604 frame
= x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f
), parms
);
9607 /* Set up the frame's root window. Currently we use a size of 80
9608 columns x 40 lines. If someone wants to show a larger tip, he
9609 will loose. I don't think this is a realistic case. */
9610 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
9611 w
->left
= w
->top
= make_number (0);
9612 w
->width
= make_number (80);
9613 w
->height
= make_number (40);
9615 w
->pseudo_window_p
= 1;
9617 /* Display the tooltip text in a temporary buffer. */
9618 buffer
= Fget_buffer_create (build_string (" *tip*"));
9619 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
);
9620 old_buffer
= current_buffer
;
9621 set_buffer_internal_1 (XBUFFER (buffer
));
9623 Finsert (1, &string
);
9624 clear_glyph_matrix (w
->desired_matrix
);
9625 clear_glyph_matrix (w
->current_matrix
);
9626 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
9627 try_window (FRAME_ROOT_WINDOW (f
), pos
);
9629 /* Compute width and height of the tooltip. */
9631 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
9633 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
9637 /* Stop at the first empty row at the end. */
9638 if (!row
->enabled_p
|| !row
->displays_text_p
)
9641 /* Let the row go over the full width of the frame. */
9642 row
->full_width_p
= 1;
9644 /* There's a glyph at the end of rows that is use to place
9645 the cursor there. Don't include the width of this glyph. */
9646 if (row
->used
[TEXT_AREA
])
9648 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
9649 row_width
= row
->pixel_width
- last
->pixel_width
;
9652 row_width
= row
->pixel_width
;
9654 height
+= row
->height
;
9655 width
= max (width
, row_width
);
9658 /* Add the frame's internal border to the width and height the X
9659 window should have. */
9660 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
9661 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
9663 /* Move the tooltip window where the mouse pointer is. Resize and
9665 #if 0 /* TODO : Mac specifics */
9666 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
9669 XQueryPointer (FRAME_W32_DISPLAY (f
), FRAME_W32_DISPLAY_INFO (f
)->root_window
,
9670 &root
, &child
, &root_x
, &root_y
, &win_x
, &win_y
, &pmask
);
9671 XMoveResizeWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9672 root_x
+ 5, root_y
- height
- 5, width
, height
);
9673 XMapRaised (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
9675 #endif /* MAC_TODO */
9677 /* Draw into the window. */
9678 w
->must_be_updated_p
= 1;
9679 update_single_window (w
, 1);
9681 /* Restore original current buffer. */
9682 set_buffer_internal_1 (old_buffer
);
9683 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
9686 /* Let the tip disappear after timeout seconds. */
9687 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
9688 intern ("x-hide-tip"));
9691 return unbind_to (count
, Qnil
);
9695 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
9696 doc
: /* Hide the current tooltip window, if there is any.
9697 Value is t is tooltip was open, nil otherwise. */)
9701 Lisp_Object deleted
, frame
, timer
;
9702 struct gcpro gcpro1
, gcpro2
;
9704 /* Return quickly if nothing to do. */
9705 if (NILP (tip_timer
) && NILP (tip_frame
))
9710 GCPRO2 (frame
, timer
);
9711 tip_frame
= tip_timer
= deleted
= Qnil
;
9713 count
= SPECPDL_INDEX ();
9714 specbind (Qinhibit_redisplay
, Qt
);
9715 specbind (Qinhibit_quit
, Qt
);
9718 call1 (Qcancel_timer
, timer
);
9722 Fdelete_frame (frame
, Qnil
);
9727 return unbind_to (count
, deleted
);
9732 /***********************************************************************
9733 File selection dialog
9734 ***********************************************************************/
9736 #if 0 /* MAC_TODO: can standard file dialog */
9737 extern Lisp_Object Qfile_name_history
;
9739 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
9740 doc
: /* Read file name, prompting with PROMPT in directory DIR.
9741 Use a file selection dialog.
9742 Select DEFAULT-FILENAME in the dialog's file selection box, if
9743 specified. Don't let the user enter a file name in the file
9744 selection dialog's entry field, if MUSTMATCH is non-nil. */)
9745 (prompt
, dir
, default_filename
, mustmatch
)
9746 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
9748 struct frame
*f
= SELECTED_FRAME ();
9749 Lisp_Object file
= Qnil
;
9750 int count
= SPECPDL_INDEX ();
9751 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
9752 char filename
[MAX_PATH
+ 1];
9753 char init_dir
[MAX_PATH
+ 1];
9754 int use_dialog_p
= 1;
9756 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
9757 CHECK_STRING (prompt
);
9760 /* Create the dialog with PROMPT as title, using DIR as initial
9761 directory and using "*" as pattern. */
9762 dir
= Fexpand_file_name (dir
, Qnil
);
9763 strncpy (init_dir
, SDATA (dir
), MAX_PATH
);
9764 init_dir
[MAX_PATH
] = '\0';
9765 unixtodos_filename (init_dir
);
9767 if (STRINGP (default_filename
))
9769 char *file_name_only
;
9770 char *full_path_name
= SDATA (default_filename
);
9772 unixtodos_filename (full_path_name
);
9774 file_name_only
= strrchr (full_path_name
, '\\');
9775 if (!file_name_only
)
9776 file_name_only
= full_path_name
;
9781 /* If default_file_name is a directory, don't use the open
9782 file dialog, as it does not support selecting
9784 if (!(*file_name_only
))
9788 strncpy (filename
, file_name_only
, MAX_PATH
);
9789 filename
[MAX_PATH
] = '\0';
9796 OPENFILENAME file_details
;
9797 char *filename_file
;
9799 /* Prevent redisplay. */
9800 specbind (Qinhibit_redisplay
, Qt
);
9803 bzero (&file_details
, sizeof (file_details
));
9804 file_details
.lStructSize
= sizeof (file_details
);
9805 file_details
.hwndOwner
= FRAME_W32_WINDOW (f
);
9806 file_details
.lpstrFile
= filename
;
9807 file_details
.nMaxFile
= sizeof (filename
);
9808 file_details
.lpstrInitialDir
= init_dir
;
9809 file_details
.lpstrTitle
= SDATA (prompt
);
9810 file_details
.Flags
= OFN_HIDEREADONLY
| OFN_NOCHANGEDIR
;
9812 if (!NILP (mustmatch
))
9813 file_details
.Flags
|= OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
;
9815 if (GetOpenFileName (&file_details
))
9817 dostounix_filename (filename
);
9818 file
= build_string (filename
);
9824 file
= unbind_to (count
, file
);
9826 /* Open File dialog will not allow folders to be selected, so resort
9827 to minibuffer completing reads for directories. */
9829 file
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
9830 dir
, mustmatch
, dir
, Qfile_name_history
,
9831 default_filename
, Qnil
);
9835 /* Make "Cancel" equivalent to C-g. */
9837 Fsignal (Qquit
, Qnil
);
9839 return unbind_to (count
, file
);
9841 #endif /* MAC_TODO */
9845 /***********************************************************************
9847 ***********************************************************************/
9851 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
9852 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
9856 return valid_image_p (spec
) ? Qt
: Qnil
;
9860 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
9866 if (valid_image_p (spec
))
9867 id
= lookup_image (SELECTED_FRAME (), spec
);
9870 return make_number (id
);
9873 #endif /* GLYPH_DEBUG != 0 */
9880 /* Certainly running on Mac. */
9883 /* The section below is built by the lisp expression at the top of the file,
9884 just above where these variables are declared. */
9885 /*&&& init symbols here &&&*/
9886 Qauto_raise
= intern ("auto-raise");
9887 staticpro (&Qauto_raise
);
9888 Qauto_lower
= intern ("auto-lower");
9889 staticpro (&Qauto_lower
);
9890 Qborder_color
= intern ("border-color");
9891 staticpro (&Qborder_color
);
9892 Qborder_width
= intern ("border-width");
9893 staticpro (&Qborder_width
);
9894 Qcursor_color
= intern ("cursor-color");
9895 staticpro (&Qcursor_color
);
9896 Qcursor_type
= intern ("cursor-type");
9897 staticpro (&Qcursor_type
);
9898 Qgeometry
= intern ("geometry");
9899 staticpro (&Qgeometry
);
9900 Qicon_left
= intern ("icon-left");
9901 staticpro (&Qicon_left
);
9902 Qicon_top
= intern ("icon-top");
9903 staticpro (&Qicon_top
);
9904 Qicon_type
= intern ("icon-type");
9905 staticpro (&Qicon_type
);
9906 Qicon_name
= intern ("icon-name");
9907 staticpro (&Qicon_name
);
9908 Qinternal_border_width
= intern ("internal-border-width");
9909 staticpro (&Qinternal_border_width
);
9910 Qleft
= intern ("left");
9912 Qright
= intern ("right");
9913 staticpro (&Qright
);
9914 Qmouse_color
= intern ("mouse-color");
9915 staticpro (&Qmouse_color
);
9916 Qnone
= intern ("none");
9918 Qparent_id
= intern ("parent-id");
9919 staticpro (&Qparent_id
);
9920 Qscroll_bar_width
= intern ("scroll-bar-width");
9921 staticpro (&Qscroll_bar_width
);
9922 Qsuppress_icon
= intern ("suppress-icon");
9923 staticpro (&Qsuppress_icon
);
9924 Qundefined_color
= intern ("undefined-color");
9925 staticpro (&Qundefined_color
);
9926 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
9927 staticpro (&Qvertical_scroll_bars
);
9928 Qvisibility
= intern ("visibility");
9929 staticpro (&Qvisibility
);
9930 Qwindow_id
= intern ("window-id");
9931 staticpro (&Qwindow_id
);
9932 Qx_frame_parameter
= intern ("x-frame-parameter");
9933 staticpro (&Qx_frame_parameter
);
9934 Qx_resource_name
= intern ("x-resource-name");
9935 staticpro (&Qx_resource_name
);
9936 Quser_position
= intern ("user-position");
9937 staticpro (&Quser_position
);
9938 Quser_size
= intern ("user-size");
9939 staticpro (&Quser_size
);
9940 Qscreen_gamma
= intern ("screen-gamma");
9941 staticpro (&Qscreen_gamma
);
9942 Qline_spacing
= intern ("line-spacing");
9943 staticpro (&Qline_spacing
);
9944 Qcenter
= intern ("center");
9945 staticpro (&Qcenter
);
9946 /* This is the end of symbol initialization. */
9948 Qhyper
= intern ("hyper");
9949 staticpro (&Qhyper
);
9950 Qsuper
= intern ("super");
9951 staticpro (&Qsuper
);
9952 Qmeta
= intern ("meta");
9954 Qalt
= intern ("alt");
9956 Qctrl
= intern ("ctrl");
9958 Qcontrol
= intern ("control");
9959 staticpro (&Qcontrol
);
9960 Qshift
= intern ("shift");
9961 staticpro (&Qshift
);
9963 /* Text property `display' should be nonsticky by default. */
9964 Vtext_property_default_nonsticky
9965 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
9968 Qlaplace
= intern ("laplace");
9969 staticpro (&Qlaplace
);
9971 Qface_set_after_frame_default
= intern ("face-set-after-frame-default");
9972 staticpro (&Qface_set_after_frame_default
);
9974 Fput (Qundefined_color
, Qerror_conditions
,
9975 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
9976 Fput (Qundefined_color
, Qerror_message
,
9977 build_string ("Undefined color"));
9979 init_x_parm_symbols ();
9981 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
9982 doc
: /* List of directories to search for bitmap files for w32. */);
9983 Vx_bitmap_file_path
= decode_env_path ((char *) 0, "PATH");
9985 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
9986 doc
: /* The shape of the pointer when over text.
9987 Changing the value does not affect existing frames
9988 unless you set the mouse color. */);
9989 Vx_pointer_shape
= Qnil
;
9991 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
9992 doc
: /* The name Emacs uses to look up resources; for internal use only.
9993 `x-get-resource' uses this as the first component of the instance name
9994 when requesting resource values.
9995 Emacs initially sets `x-resource-name' to the name under which Emacs
9996 was invoked, or to the value specified with the `-name' or `-rn'
9997 switches, if present. */);
9998 Vx_resource_name
= Qnil
;
10000 Vx_nontext_pointer_shape
= Qnil
;
10002 Vx_mode_pointer_shape
= Qnil
;
10004 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10005 doc
: /* The shape of the pointer when Emacs is hourglass.
10006 This variable takes effect when you create a new frame
10007 or when you set the mouse color. */);
10008 Vx_hourglass_pointer_shape
= Qnil
;
10010 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10011 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10012 display_hourglass_p
= 1;
10014 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10015 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10016 Value must be an integer or float. */);
10017 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10019 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10020 &Vx_sensitive_text_pointer_shape
,
10021 doc
: /* The shape of the pointer when over mouse-sensitive text.
10022 This variable takes effect when you create a new frame
10023 or when you set the mouse color. */);
10024 Vx_sensitive_text_pointer_shape
= Qnil
;
10026 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
10027 doc
: /* A string indicating the foreground color of the cursor box. */);
10028 Vx_cursor_fore_pixel
= Qnil
;
10030 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
10031 doc
: /* Non-nil if no window manager is in use.
10032 Emacs doesn't try to figure this out; this is always nil
10033 unless you set it to something else. */);
10034 /* We don't have any way to find this out, so set it to nil
10035 and maybe the user would like to set it to t. */
10036 Vx_no_window_manager
= Qnil
;
10038 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10039 &Vx_pixel_size_width_font_regexp
,
10040 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10042 Since Emacs gets width of a font matching with this regexp from
10043 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10044 such a font. This is especially effective for such large fonts as
10045 Chinese, Japanese, and Korean. */);
10046 Vx_pixel_size_width_font_regexp
= Qnil
;
10048 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
10049 doc
: /* Time after which cached images are removed from the cache.
10050 When an image has not been displayed this many seconds, remove it
10051 from the image cache. Value must be an integer or nil with nil
10052 meaning don't clear the cache. */);
10053 Vimage_cache_eviction_delay
= make_number (30 * 60);
10055 #if 0 /* MAC_TODO: implement get X resource */
10056 defsubr (&Sx_get_resource
);
10058 defsubr (&Sx_change_window_property
);
10059 defsubr (&Sx_delete_window_property
);
10060 defsubr (&Sx_window_property
);
10061 defsubr (&Sxw_display_color_p
);
10062 defsubr (&Sx_display_grayscale_p
);
10063 defsubr (&Sxw_color_defined_p
);
10064 defsubr (&Sxw_color_values
);
10065 defsubr (&Sx_server_max_request_size
);
10066 defsubr (&Sx_server_vendor
);
10067 defsubr (&Sx_server_version
);
10068 defsubr (&Sx_display_pixel_width
);
10069 defsubr (&Sx_display_pixel_height
);
10070 defsubr (&Sx_display_mm_width
);
10071 defsubr (&Sx_display_mm_height
);
10072 defsubr (&Sx_display_screens
);
10073 defsubr (&Sx_display_planes
);
10074 defsubr (&Sx_display_color_cells
);
10075 defsubr (&Sx_display_visual_class
);
10076 defsubr (&Sx_display_backing_store
);
10077 defsubr (&Sx_display_save_under
);
10078 #if 0 /* MAC_TODO: implement XParseGeometry */
10079 defsubr (&Sx_parse_geometry
);
10081 defsubr (&Sx_create_frame
);
10082 #if 0 /* MAC_TODO: implement network support */
10083 defsubr (&Sx_open_connection
);
10084 defsubr (&Sx_close_connection
);
10086 defsubr (&Sx_display_list
);
10087 defsubr (&Sx_synchronize
);
10089 /* Setting callback functions for fontset handler. */
10090 get_font_info_func
= x_get_font_info
;
10092 #if 0 /* This function pointer doesn't seem to be used anywhere.
10093 And the pointer assigned has the wrong type, anyway. */
10094 list_fonts_func
= x_list_fonts
;
10097 load_font_func
= x_load_font
;
10098 find_ccl_program_func
= x_find_ccl_program
;
10099 query_font_func
= x_query_font
;
10101 set_frame_fontset_func
= x_set_font
;
10102 check_window_system_func
= check_mac
;
10104 #if 0 /* MAC_TODO: Image support for Mac Images. */
10105 Qxbm
= intern ("xbm");
10107 QCtype
= intern (":type");
10108 staticpro (&QCtype
);
10109 QCconversion
= intern (":conversion");
10110 staticpro (&QCconversion
);
10111 QCheuristic_mask
= intern (":heuristic-mask");
10112 staticpro (&QCheuristic_mask
);
10113 QCcolor_symbols
= intern (":color-symbols");
10114 staticpro (&QCcolor_symbols
);
10115 QCascent
= intern (":ascent");
10116 staticpro (&QCascent
);
10117 QCmargin
= intern (":margin");
10118 staticpro (&QCmargin
);
10119 QCrelief
= intern (":relief");
10120 staticpro (&QCrelief
);
10121 Qpostscript
= intern ("postscript");
10122 staticpro (&Qpostscript
);
10123 QCloader
= intern (":loader");
10124 staticpro (&QCloader
);
10125 QCbounding_box
= intern (":bounding-box");
10126 staticpro (&QCbounding_box
);
10127 QCpt_width
= intern (":pt-width");
10128 staticpro (&QCpt_width
);
10129 QCpt_height
= intern (":pt-height");
10130 staticpro (&QCpt_height
);
10131 QCindex
= intern (":index");
10132 staticpro (&QCindex
);
10133 Qpbm
= intern ("pbm");
10137 Qxpm
= intern ("xpm");
10142 Qjpeg
= intern ("jpeg");
10143 staticpro (&Qjpeg
);
10147 Qtiff
= intern ("tiff");
10148 staticpro (&Qtiff
);
10152 Qgif
= intern ("gif");
10157 Qpng
= intern ("png");
10161 defsubr (&Sclear_image_cache
);
10164 defsubr (&Simagep
);
10165 defsubr (&Slookup_image
);
10167 #endif /* MAC_TODO */
10169 hourglass_atimer
= NULL
;
10170 hourglass_shown_p
= 0;
10172 defsubr (&Sx_show_tip
);
10173 defsubr (&Sx_hide_tip
);
10174 staticpro (&tip_timer
);
10177 #if 0 /* MAC_TODO */
10178 defsubr (&Sx_file_dialog
);
10186 image_types
= NULL
;
10187 Vimage_types
= Qnil
;
10189 define_image_type (&xbm_type
);
10190 #if 0 /* NTEMACS_TODO : Image support for W32 */
10191 define_image_type (&gs_type
);
10192 define_image_type (&pbm_type
);
10195 define_image_type (&xpm_type
);
10199 define_image_type (&jpeg_type
);
10203 define_image_type (&tiff_type
);
10207 define_image_type (&gif_type
);
10211 define_image_type (&png_type
);
10213 #endif /* NTEMACS_TODO */