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 extern Lisp_Object Qbox
;
253 Lisp_Object Qface_set_after_frame_default
;
255 extern int mac_initialized
;
257 /* Functions in macterm.c. */
258 extern void x_set_offset (struct frame
*, int, int, int);
259 extern void x_wm_set_icon_position (struct frame
*, int, int);
260 extern void x_display_cursor (struct window
*, int, int, int, int, int);
261 extern void x_set_window_size (struct frame
*, int, int, int);
262 extern void x_make_frame_visible (struct frame
*);
263 extern struct mac_display_info
*mac_term_init (Lisp_Object
, char *, char *);
264 extern struct font_info
*x_get_font_info (FRAME_PTR
, int);
265 extern struct font_info
*x_load_font (struct frame
*, char *, int);
266 extern void x_find_ccl_program (struct font_info
*);
267 extern struct font_info
*x_query_font (struct frame
*, char *);
268 extern void mac_initialize ();
270 /* compare two strings ignoring case */
273 stricmp (const char *s
, const char *t
)
275 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
278 return tolower (*s
) - tolower (*t
);
281 /* compare two strings up to n characters, ignoring case */
284 strnicmp (const char *s
, const char *t
, unsigned int n
)
286 for ( ; n
-- > 0 && tolower (*s
) == tolower (*t
); s
++, t
++)
289 return n
== 0 ? 0 : tolower (*s
) - tolower (*t
);
293 /* Error if we are not running on Mac OS. */
299 error ("Mac OS not in use or not initialized");
302 /* Nonzero if we can use mouse menus.
303 You should not call this unless HAVE_MENUS is defined. */
311 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
312 and checking validity for Mac. */
315 check_x_frame (frame
)
321 frame
= selected_frame
;
322 CHECK_LIVE_FRAME (frame
);
324 if (! FRAME_MAC_P (f
))
325 error ("non-mac frame used");
329 /* Let the user specify an display with a frame.
330 nil stands for the selected frame--or, if that is not a mac frame,
331 the first display on the list. */
333 static struct mac_display_info
*
334 check_x_display_info (frame
)
337 if (!mac_initialized
)
345 struct frame
*sf
= XFRAME (selected_frame
);
347 if (FRAME_MAC_P (sf
) && FRAME_LIVE_P (sf
))
348 return FRAME_MAC_DISPLAY_INFO (sf
);
350 return &one_mac_display_info
;
352 else if (STRINGP (frame
))
353 return x_display_info_for_name (frame
);
358 CHECK_LIVE_FRAME (frame
);
360 if (! FRAME_MAC_P (f
))
361 error ("non-mac frame used");
362 return FRAME_MAC_DISPLAY_INFO (f
);
366 /* Return the Emacs frame-object corresponding to an mac window.
367 It could be the frame's main window or an icon window. */
369 /* This function can be called during GC, so use GC_xxx type test macros. */
372 x_window_to_frame (dpyinfo
, wdesc
)
373 struct mac_display_info
*dpyinfo
;
376 Lisp_Object tail
, frame
;
379 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
382 if (!GC_FRAMEP (frame
))
385 if (!FRAME_W32_P (f
) || FRAME_MAC_DISPLAY_INFO (f
) != dpyinfo
)
387 /*if (f->output_data.w32->hourglass_window == wdesc)
390 /* MAC_TODO: Check tooltips when supported. */
391 if (FRAME_MAC_WINDOW (f
) == wdesc
)
399 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
400 id, which is just an int that this section returns. Bitmaps are
401 reference counted so they can be shared among frames.
403 Bitmap indices are guaranteed to be > 0, so a negative number can
404 be used to indicate no bitmap.
406 If you use x_create_bitmap_from_data, then you must keep track of
407 the bitmaps yourself. That is, creating a bitmap from the same
408 data more than once will not be caught. */
411 /* Functions to access the contents of a bitmap, given an id. */
414 x_bitmap_height (f
, id
)
418 return FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
422 x_bitmap_width (f
, id
)
426 return FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
429 #if 0 /* MAC_TODO : not used anywhere (?) */
431 x_bitmap_pixmap (f
, id
)
435 return (int) FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
439 /* Allocate a new bitmap record. Returns index of new record. */
442 x_allocate_bitmap_record (f
)
445 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
448 if (dpyinfo
->bitmaps
== NULL
)
450 dpyinfo
->bitmaps_size
= 10;
451 dpyinfo
->bitmaps
= (struct mac_bitmap_record
*)
452 xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct mac_bitmap_record
));
453 dpyinfo
->bitmaps_last
= 1;
457 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
458 return ++dpyinfo
->bitmaps_last
;
460 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
461 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
464 dpyinfo
->bitmaps_size
*= 2;
465 dpyinfo
->bitmaps
= (struct mac_bitmap_record
*)
466 xrealloc (dpyinfo
->bitmaps
,
467 dpyinfo
->bitmaps_size
* sizeof (struct mac_bitmap_record
));
468 return ++dpyinfo
->bitmaps_last
;
471 /* Add one reference to the reference count of the bitmap with id
475 x_reference_bitmap (f
, id
)
479 ++FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
482 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at
486 x_create_bitmap_from_data (f
, bits
, width
, height
)
489 unsigned int width
, height
;
491 struct x_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
494 /* MAC_TODO: for now fail if width is not mod 16 (toolbox requires it) */
496 id
= x_allocate_bitmap_record (f
);
501 dpyinfo
->bitmaps
[id
- 1].bitmap_data
= (char *) xmalloc (height
* width
);
502 if (! dpyinfo
->bitmaps
[id
- 1].bitmap_data
)
505 bcopy (bits
, dpyinfo
->bitmaps
[id
- 1].bitmap_data
, height
* width
);
507 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
508 dpyinfo
->bitmaps
[id
- 1].height
= height
;
509 dpyinfo
->bitmaps
[id
- 1].width
= width
;
514 /* Create bitmap from file FILE for frame F. */
517 x_create_bitmap_from_file (f
, file
)
522 #if 0 /* MAC_TODO : bitmap support */
523 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
524 unsigned int width
, height
;
526 int xhot
, yhot
, result
, id
;
532 /* Look for an existing bitmap with the same name. */
533 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
535 if (dpyinfo
->bitmaps
[id
].refcount
536 && dpyinfo
->bitmaps
[id
].file
537 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
539 ++dpyinfo
->bitmaps
[id
].refcount
;
544 /* Search bitmap-file-path for the file, if appropriate. */
545 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, Qnil
);
548 /* LoadLibraryEx won't handle special files handled by Emacs handler. */
553 filename
= (char *) SDATA (found
);
555 hinst
= LoadLibraryEx (filename
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
561 result
= XReadBitmapFile (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
562 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
563 if (result
!= BitmapSuccess
)
566 id
= x_allocate_bitmap_record (f
);
567 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
568 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
569 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SCHARS (file
) + 1);
570 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
571 dpyinfo
->bitmaps
[id
- 1].height
= height
;
572 dpyinfo
->bitmaps
[id
- 1].width
= width
;
573 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
576 #endif /* MAC_TODO */
579 /* Remove reference to bitmap with id number ID. */
582 x_destroy_bitmap (f
, id
)
586 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
590 --dpyinfo
->bitmaps
[id
- 1].refcount
;
591 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
594 dpyinfo
->bitmaps
[id
- 1].bitmap_data
= NULL
;
600 /* Free all the bitmaps for the display specified by DPYINFO. */
603 x_destroy_all_bitmaps (dpyinfo
)
604 struct mac_display_info
*dpyinfo
;
607 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
608 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
609 xfree (dpyinfo
->bitmaps
[i
].bitmap_data
);
610 dpyinfo
->bitmaps_last
= 0;
613 /* Connect the frame-parameter names for W32 frames
614 to the ways of passing the parameter values to the window system.
616 The name of a parameter, as a Lisp symbol,
617 has an `x-frame-parameter' property which is an integer in Lisp
618 but can be interpreted as an `enum x_frame_parm' in C. */
620 struct x_frame_parm_table
623 void (*setter
) P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
626 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
627 static void x_set_line_spacing
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
628 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
629 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
630 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
631 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
632 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
633 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
634 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
635 void x_set_font
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
636 void x_set_border_width
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
637 void x_set_internal_border_width
P_ ((struct frame
*, Lisp_Object
,
639 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
640 void x_set_autoraise
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
641 void x_set_autolower
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
642 void x_set_vertical_scroll_bars
P_ ((struct frame
*, Lisp_Object
,
644 void x_set_visibility
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
645 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
646 void x_set_scroll_bar_width
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
647 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
648 void x_set_unsplittable
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
649 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
650 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
652 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
654 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
659 static void x_set_screen_gamma
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
661 static struct x_frame_parm_table x_frame_parms
[] =
663 "auto-raise", x_set_autoraise
,
664 "auto-lower", x_set_autolower
,
665 "background-color", x_set_background_color
,
666 "border-color", x_set_border_color
,
667 "border-width", x_set_border_width
,
668 "cursor-color", x_set_cursor_color
,
669 "cursor-type", x_set_cursor_type
,
671 "foreground-color", x_set_foreground_color
,
672 "icon-name", x_set_icon_name
,
673 #if 0 /* MAC_TODO: no icons for Mac */
674 "icon-type", x_set_icon_type
,
676 "internal-border-width", x_set_internal_border_width
,
677 "menu-bar-lines", x_set_menu_bar_lines
,
678 "mouse-color", x_set_mouse_color
,
679 "name", x_explicitly_set_name
,
680 "scroll-bar-width", x_set_scroll_bar_width
,
681 "title", x_set_title
,
682 "unsplittable", x_set_unsplittable
,
683 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
684 "visibility", x_set_visibility
,
685 "tool-bar-lines", x_set_tool_bar_lines
,
686 #if 0 /* MAC_TODO: cannot set color of scroll bar on the Mac? */
687 "scroll-bar-foreground", x_set_scroll_bar_foreground
,
688 "scroll-bar-background", x_set_scroll_bar_background
,
690 "screen-gamma", x_set_screen_gamma
,
691 "line-spacing", x_set_line_spacing
694 /* Attach the `x-frame-parameter' properties to
695 the Lisp symbol names of parameters relevant to Mac. */
698 init_x_parm_symbols ()
702 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
703 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
707 /* Change the parameters of frame F as specified by ALIST.
708 If a parameter is not specially recognized, do nothing;
709 otherwise call the `x_set_...' function for that parameter. */
712 x_set_frame_parameters (f
, alist
)
718 /* If both of these parameters are present, it's more efficient to
719 set them both at once. So we wait until we've looked at the
720 entire list before we set them. */
724 Lisp_Object left
, top
;
726 /* Same with these. */
727 Lisp_Object icon_left
, icon_top
;
729 /* Record in these vectors all the parms specified. */
733 int left_no_change
= 0, top_no_change
= 0;
734 int icon_left_no_change
= 0, icon_top_no_change
= 0;
736 struct gcpro gcpro1
, gcpro2
;
739 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
742 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
743 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
745 /* Extract parm names and values into those vectors. */
748 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
753 parms
[i
] = Fcar (elt
);
754 values
[i
] = Fcdr (elt
);
757 /* TAIL and ALIST are not used again below here. */
760 GCPRO2 (*parms
, *values
);
764 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
765 because their values appear in VALUES and strings are not valid. */
766 top
= left
= Qunbound
;
767 icon_left
= icon_top
= Qunbound
;
769 /* Provide default values for HEIGHT and WIDTH. */
770 if (FRAME_NEW_WIDTH (f
))
771 width
= FRAME_NEW_WIDTH (f
);
773 width
= FRAME_WIDTH (f
);
775 if (FRAME_NEW_HEIGHT (f
))
776 height
= FRAME_NEW_HEIGHT (f
);
778 height
= FRAME_HEIGHT (f
);
780 /* Process foreground_color and background_color before anything else.
781 They are independent of other properties, but other properties (e.g.,
782 cursor_color) are dependent upon them. */
783 for (p
= 0; p
< i
; p
++)
785 Lisp_Object prop
, val
;
789 if (EQ (prop
, Qforeground_color
) || EQ (prop
, Qbackground_color
))
791 register Lisp_Object param_index
, old_value
;
793 param_index
= Fget (prop
, Qx_frame_parameter
);
794 old_value
= get_frame_param (f
, prop
);
795 store_frame_param (f
, prop
, val
);
796 if (NATNUMP (param_index
)
797 && (XFASTINT (param_index
)
798 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
799 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
803 /* Now process them in reverse of specified order. */
804 for (i
--; i
>= 0; i
--)
806 Lisp_Object prop
, val
;
811 if (EQ (prop
, Qwidth
) && NUMBERP (val
))
812 width
= XFASTINT (val
);
813 else if (EQ (prop
, Qheight
) && NUMBERP (val
))
814 height
= XFASTINT (val
);
815 else if (EQ (prop
, Qtop
))
817 else if (EQ (prop
, Qleft
))
819 else if (EQ (prop
, Qicon_top
))
821 else if (EQ (prop
, Qicon_left
))
823 else if (EQ (prop
, Qforeground_color
) || EQ (prop
, Qbackground_color
))
824 /* Processed above. */
828 register Lisp_Object param_index
, old_value
;
830 param_index
= Fget (prop
, Qx_frame_parameter
);
831 old_value
= get_frame_param (f
, prop
);
832 store_frame_param (f
, prop
, val
);
833 if (NATNUMP (param_index
)
834 && (XFASTINT (param_index
)
835 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
836 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
840 /* Don't die if just one of these was set. */
841 if (EQ (left
, Qunbound
))
844 if (f
->output_data
.mac
->left_pos
< 0)
846 Fcons (make_number (f
->output_data
.mac
->left_pos
),
849 XSETINT (left
, f
->output_data
.mac
->left_pos
);
851 if (EQ (top
, Qunbound
))
854 if (f
->output_data
.mac
->top_pos
< 0)
856 Fcons (make_number (f
->output_data
.mac
->top_pos
), Qnil
));
858 XSETINT (top
, f
->output_data
.mac
->top_pos
);
861 /* If one of the icon positions was not set, preserve or default it. */
862 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
864 icon_left_no_change
= 1;
865 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
866 if (NILP (icon_left
))
867 XSETINT (icon_left
, 0);
869 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
871 icon_top_no_change
= 1;
872 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
874 XSETINT (icon_top
, 0);
877 /* Don't set these parameters unless they've been explicitly
878 specified. The window might be mapped or resized while we're in
879 this function, and we don't want to override that unless the lisp
880 code has asked for it.
882 Don't set these parameters unless they actually differ from the
883 window's current parameters; the window may not actually exist
888 check_frame_size (f
, &height
, &width
);
890 XSETFRAME (frame
, f
);
892 if (width
!= FRAME_WIDTH (f
)
893 || height
!= FRAME_HEIGHT (f
)
894 || FRAME_NEW_HEIGHT (f
) || FRAME_NEW_WIDTH (f
))
895 Fset_frame_size (frame
, make_number (width
), make_number (height
));
897 if ((!NILP (left
) || !NILP (top
))
898 && ! (left_no_change
&& top_no_change
)
899 && ! (NUMBERP (left
) && XINT (left
) == f
->output_data
.mac
->left_pos
900 && NUMBERP (top
) && XINT (top
) == f
->output_data
.mac
->top_pos
))
905 /* Record the signs. */
906 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
907 if (EQ (left
, Qminus
))
908 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
909 else if (INTEGERP (left
))
911 leftpos
= XINT (left
);
913 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
915 else if (CONSP (left
) && EQ (XCAR (left
), Qminus
)
916 && CONSP (XCDR (left
))
917 && INTEGERP (XCAR (XCDR (left
))))
919 leftpos
= - XINT (XCAR (XCDR (left
)));
920 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
922 else if (CONSP (left
) && EQ (XCAR (left
), Qplus
)
923 && CONSP (XCDR (left
))
924 && INTEGERP (XCAR (XCDR (left
))))
926 leftpos
= XINT (XCAR (XCDR (left
)));
929 if (EQ (top
, Qminus
))
930 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
931 else if (INTEGERP (top
))
935 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
937 else if (CONSP (top
) && EQ (XCAR (top
), Qminus
)
938 && CONSP (XCDR (top
))
939 && INTEGERP (XCAR (XCDR (top
))))
941 toppos
= - XINT (XCAR (XCDR (top
)));
942 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
944 else if (CONSP (top
) && EQ (XCAR (top
), Qplus
)
945 && CONSP (XCDR (top
))
946 && INTEGERP (XCAR (XCDR (top
))))
948 toppos
= XINT (XCAR (XCDR (top
)));
952 /* Store the numeric value of the position. */
953 f
->output_data
.mac
->top_pos
= toppos
;
954 f
->output_data
.mac
->left_pos
= leftpos
;
956 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
958 /* Actually set that position, and convert to absolute. */
959 x_set_offset (f
, leftpos
, toppos
, -1);
962 if ((!NILP (icon_left
) || !NILP (icon_top
))
963 && ! (icon_left_no_change
&& icon_top_no_change
))
964 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
970 /* Store the screen positions of frame F into XPTR and YPTR.
971 These are the positions of the containing window manager window,
972 not Emacs's own window. */
975 x_real_positions (f
, xptr
, yptr
)
982 #ifdef TARGET_API_MAC_CARBON
986 GetWindowPortBounds (f
->output_data
.mac
->mWP
, &r
);
987 SetPt (&pt
, r
.left
, r
.top
);
989 #else /* not TARGET_API_MAC_CARBON */
991 f
->output_data
.mac
->mWP
->portRect
.left
,
992 f
->output_data
.mac
->mWP
->portRect
.top
);
993 #endif /* not TARGET_API_MAC_CARBON */
1002 /* Insert a description of internally-recorded parameters of frame X
1003 into the parameter alist *ALISTPTR that is to be given to the user.
1004 Only parameters that are specific to Mac and whose values are not
1005 correctly recorded in the frame's param_alist need to be considered
1009 x_report_frame_params (f
, alistptr
)
1011 Lisp_Object
*alistptr
;
1016 /* Represent negative positions (off the top or left screen edge)
1017 in a way that Fmodify_frame_parameters will understand correctly. */
1018 XSETINT (tem
, f
->output_data
.mac
->left_pos
);
1019 if (f
->output_data
.mac
->left_pos
>= 0)
1020 store_in_alist (alistptr
, Qleft
, tem
);
1022 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1024 XSETINT (tem
, f
->output_data
.mac
->top_pos
);
1025 if (f
->output_data
.mac
->top_pos
>= 0)
1026 store_in_alist (alistptr
, Qtop
, tem
);
1028 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1030 store_in_alist (alistptr
, Qborder_width
,
1031 make_number (f
->output_data
.mac
->border_width
));
1032 store_in_alist (alistptr
, Qinternal_border_width
,
1033 make_number (f
->output_data
.mac
->internal_border_width
));
1034 sprintf (buf
, "%ld", (long) FRAME_MAC_WINDOW (f
));
1035 store_in_alist (alistptr
, Qwindow_id
,
1036 build_string (buf
));
1037 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
1038 FRAME_SAMPLE_VISIBILITY (f
);
1039 store_in_alist (alistptr
, Qvisibility
,
1040 (FRAME_VISIBLE_P (f
) ? Qt
1041 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1042 store_in_alist (alistptr
, Qdisplay
,
1043 XCAR (FRAME_MAC_DISPLAY_INFO (f
)->name_list_element
));
1046 /* The default colors for the Mac color map */
1047 typedef struct colormap_t
1049 unsigned long color
;
1053 colormap_t mac_color_map
[] =
1055 { RGB_TO_ULONG(255, 250, 250), "snow" },
1056 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
1057 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
1058 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
1059 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
1060 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
1061 { RGB_TO_ULONG(255, 250, 240), "floral white" },
1062 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
1063 { RGB_TO_ULONG(253, 245, 230), "old lace" },
1064 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
1065 { RGB_TO_ULONG(250, 240, 230), "linen" },
1066 { RGB_TO_ULONG(250, 235, 215), "antique white" },
1067 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
1068 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
1069 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
1070 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
1071 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
1072 { RGB_TO_ULONG(255, 228, 196), "bisque" },
1073 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
1074 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
1075 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
1076 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
1077 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
1078 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
1079 { RGB_TO_ULONG(255, 255, 240), "ivory" },
1080 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
1081 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
1082 { RGB_TO_ULONG(255, 245, 238), "seashell" },
1083 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
1084 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
1085 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
1086 { RGB_TO_ULONG(240, 255, 255), "azure" },
1087 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
1088 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
1089 { RGB_TO_ULONG(230, 230, 250), "lavender" },
1090 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
1091 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
1092 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
1093 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
1094 { RGB_TO_ULONG(255, 255, 255), "white" },
1095 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
1096 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
1097 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
1098 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
1099 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
1100 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
1101 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
1102 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
1103 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
1104 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
1105 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
1106 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
1107 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
1108 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
1109 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
1110 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
1111 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
1112 { RGB_TO_ULONG(190, 190, 190), "gray" },
1113 { RGB_TO_ULONG(190, 190, 190), "grey" },
1114 { RGB_TO_ULONG(211, 211, 211), "light grey" },
1115 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
1116 { RGB_TO_ULONG(211, 211, 211), "light gray" },
1117 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
1118 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
1119 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
1120 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
1121 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
1122 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
1123 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
1124 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
1125 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
1126 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
1127 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
1128 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
1129 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
1130 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
1131 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
1132 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
1133 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
1134 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
1135 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
1136 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
1137 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
1138 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
1139 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
1140 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
1141 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
1142 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
1143 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
1144 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
1145 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
1146 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
1147 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
1148 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
1149 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
1150 { RGB_TO_ULONG(173, 216, 230), "light blue" },
1151 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
1152 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
1153 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
1154 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
1155 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
1156 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
1157 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
1158 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
1159 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
1160 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
1161 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
1162 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
1163 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
1164 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
1165 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
1166 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
1167 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
1168 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
1169 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
1170 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
1171 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
1172 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
1173 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
1174 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
1175 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
1176 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
1177 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
1178 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
1179 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
1180 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
1181 { RGB_TO_ULONG(152, 251, 152), "pale green" },
1182 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
1183 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
1184 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
1185 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
1186 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
1187 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
1188 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
1189 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
1190 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
1191 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
1192 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
1193 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
1194 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
1195 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
1196 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
1197 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
1198 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
1199 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
1200 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
1201 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
1202 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
1203 { RGB_TO_ULONG(240, 230, 140), "khaki" },
1204 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
1205 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
1206 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
1207 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
1208 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
1209 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
1210 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
1211 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
1212 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
1213 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
1214 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
1215 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
1216 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
1217 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
1218 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
1219 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
1220 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
1221 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
1222 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
1223 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
1224 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
1225 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
1226 { RGB_TO_ULONG(245, 245, 220), "beige" },
1227 { RGB_TO_ULONG(245, 222, 179), "wheat" },
1228 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
1229 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
1230 { RGB_TO_ULONG(210, 180, 140), "tan" },
1231 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
1232 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
1233 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
1234 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
1235 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
1236 { RGB_TO_ULONG(250, 128, 114), "salmon" },
1237 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
1238 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
1239 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
1240 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
1241 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
1242 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
1243 { RGB_TO_ULONG(240, 128, 128), "light coral" },
1244 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
1245 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
1246 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
1247 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
1248 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
1249 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
1250 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
1251 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
1252 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
1253 { RGB_TO_ULONG(255, 192, 203), "pink" },
1254 { RGB_TO_ULONG(255, 182, 193), "light pink" },
1255 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
1256 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
1257 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
1258 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
1259 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
1260 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
1261 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
1262 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
1263 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
1264 { RGB_TO_ULONG(238, 130, 238), "violet" },
1265 { RGB_TO_ULONG(221, 160, 221), "plum" },
1266 { RGB_TO_ULONG(218, 112, 214), "orchid" },
1267 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
1268 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
1269 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
1270 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
1271 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
1272 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
1273 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
1274 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
1275 { RGB_TO_ULONG(160, 32 , 240), "purple" },
1276 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
1277 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
1278 { RGB_TO_ULONG(216, 191, 216), "thistle" },
1279 { RGB_TO_ULONG(255, 250, 250), "snow1" },
1280 { RGB_TO_ULONG(238, 233, 233), "snow2" },
1281 { RGB_TO_ULONG(205, 201, 201), "snow3" },
1282 { RGB_TO_ULONG(139, 137, 137), "snow4" },
1283 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
1284 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
1285 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
1286 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
1287 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
1288 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
1289 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
1290 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
1291 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
1292 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
1293 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
1294 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
1295 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
1296 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
1297 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
1298 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
1299 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
1300 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
1301 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
1302 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
1303 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
1304 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
1305 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
1306 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
1307 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
1308 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
1309 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
1310 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
1311 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
1312 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
1313 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
1314 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
1315 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
1316 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
1317 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
1318 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
1319 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
1320 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
1321 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
1322 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
1323 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
1324 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
1325 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
1326 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
1327 { RGB_TO_ULONG(240, 255, 255), "azure1" },
1328 { RGB_TO_ULONG(224, 238, 238), "azure2" },
1329 { RGB_TO_ULONG(193, 205, 205), "azure3" },
1330 { RGB_TO_ULONG(131, 139, 139), "azure4" },
1331 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
1332 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
1333 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
1334 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
1335 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
1336 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
1337 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
1338 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
1339 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
1340 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
1341 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
1342 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
1343 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
1344 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
1345 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
1346 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
1347 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
1348 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
1349 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
1350 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
1351 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
1352 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
1353 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
1354 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
1355 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
1356 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
1357 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
1358 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
1359 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
1360 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
1361 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
1362 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
1363 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
1364 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
1365 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
1366 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
1367 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
1368 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
1369 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
1370 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
1371 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
1372 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
1373 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
1374 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
1375 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
1376 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
1377 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
1378 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
1379 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
1380 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
1381 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
1382 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
1383 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
1384 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
1385 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
1386 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
1387 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
1388 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
1389 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
1390 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
1391 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
1392 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
1393 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
1394 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
1395 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
1396 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
1397 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
1398 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
1399 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
1400 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
1401 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
1402 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
1403 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
1404 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
1405 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
1406 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
1407 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
1408 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
1409 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
1410 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
1411 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
1412 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
1413 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
1414 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
1415 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
1416 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
1417 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
1418 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
1419 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
1420 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
1421 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
1422 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
1423 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
1424 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
1425 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
1426 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
1427 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
1428 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
1429 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
1430 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
1431 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
1432 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
1433 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
1434 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
1435 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
1436 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
1437 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
1438 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
1439 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
1440 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
1441 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
1442 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
1443 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
1444 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
1445 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
1446 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
1447 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
1448 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
1449 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
1450 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
1451 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
1452 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
1453 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
1454 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
1455 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
1456 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
1457 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
1458 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
1459 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
1460 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
1461 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
1462 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
1463 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
1464 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
1465 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
1466 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
1467 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
1468 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
1469 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
1470 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
1471 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
1472 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
1473 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
1474 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
1475 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
1476 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
1477 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
1478 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
1479 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
1480 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
1481 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
1482 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
1483 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
1484 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
1485 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
1486 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
1487 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
1488 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
1489 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
1490 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
1491 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
1492 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
1493 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
1494 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
1495 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
1496 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
1497 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
1498 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
1499 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
1500 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
1501 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
1502 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
1503 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
1504 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
1505 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
1506 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
1507 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
1508 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
1509 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
1510 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
1511 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
1512 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
1513 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
1514 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
1515 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
1516 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
1517 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
1518 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
1519 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
1520 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
1521 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
1522 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
1523 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
1524 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
1525 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
1526 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
1527 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
1528 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
1529 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
1530 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
1531 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
1532 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
1533 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
1534 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
1535 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
1536 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
1537 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
1538 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
1539 { RGB_TO_ULONG(255, 181, 197), "pink1" },
1540 { RGB_TO_ULONG(238, 169, 184), "pink2" },
1541 { RGB_TO_ULONG(205, 145, 158), "pink3" },
1542 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
1543 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
1544 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
1545 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
1546 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
1547 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
1548 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
1549 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
1550 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
1551 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
1552 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
1553 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
1554 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
1555 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
1556 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
1557 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
1558 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
1559 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
1560 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
1561 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
1562 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
1563 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
1564 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
1565 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
1566 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
1567 { RGB_TO_ULONG(255, 187, 255), "plum1" },
1568 { RGB_TO_ULONG(238, 174, 238), "plum2" },
1569 { RGB_TO_ULONG(205, 150, 205), "plum3" },
1570 { RGB_TO_ULONG(139, 102, 139), "plum4" },
1571 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
1572 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
1573 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
1574 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
1575 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
1576 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
1577 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
1578 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
1579 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
1580 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
1581 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
1582 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
1583 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
1584 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
1585 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
1586 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
1587 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
1588 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
1589 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
1590 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
1591 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
1592 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
1593 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
1594 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
1595 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
1596 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
1597 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
1598 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
1599 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
1600 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
1601 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
1602 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
1603 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
1604 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
1605 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
1606 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
1607 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
1608 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
1609 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
1610 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
1611 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
1612 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
1613 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
1614 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
1615 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
1616 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
1617 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
1618 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
1619 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
1620 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
1621 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
1622 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
1623 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
1624 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
1625 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
1626 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
1627 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
1628 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
1629 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
1630 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
1631 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
1632 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
1633 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
1634 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
1635 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
1636 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
1637 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
1638 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
1639 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
1640 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
1641 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
1642 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
1643 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
1644 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
1645 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
1646 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
1647 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
1648 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
1649 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
1650 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
1651 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
1652 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
1653 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
1654 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
1655 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
1656 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
1657 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
1658 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
1659 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
1660 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
1661 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
1662 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
1663 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
1664 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
1665 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
1666 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
1667 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
1668 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
1669 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
1670 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
1671 { RGB_TO_ULONG(102, 102, 102), "gray40" },
1672 { RGB_TO_ULONG(102, 102, 102), "grey40" },
1673 { RGB_TO_ULONG(105, 105, 105), "gray41" },
1674 { RGB_TO_ULONG(105, 105, 105), "grey41" },
1675 { RGB_TO_ULONG(107, 107, 107), "gray42" },
1676 { RGB_TO_ULONG(107, 107, 107), "grey42" },
1677 { RGB_TO_ULONG(110, 110, 110), "gray43" },
1678 { RGB_TO_ULONG(110, 110, 110), "grey43" },
1679 { RGB_TO_ULONG(112, 112, 112), "gray44" },
1680 { RGB_TO_ULONG(112, 112, 112), "grey44" },
1681 { RGB_TO_ULONG(115, 115, 115), "gray45" },
1682 { RGB_TO_ULONG(115, 115, 115), "grey45" },
1683 { RGB_TO_ULONG(117, 117, 117), "gray46" },
1684 { RGB_TO_ULONG(117, 117, 117), "grey46" },
1685 { RGB_TO_ULONG(120, 120, 120), "gray47" },
1686 { RGB_TO_ULONG(120, 120, 120), "grey47" },
1687 { RGB_TO_ULONG(122, 122, 122), "gray48" },
1688 { RGB_TO_ULONG(122, 122, 122), "grey48" },
1689 { RGB_TO_ULONG(125, 125, 125), "gray49" },
1690 { RGB_TO_ULONG(125, 125, 125), "grey49" },
1691 { RGB_TO_ULONG(127, 127, 127), "gray50" },
1692 { RGB_TO_ULONG(127, 127, 127), "grey50" },
1693 { RGB_TO_ULONG(130, 130, 130), "gray51" },
1694 { RGB_TO_ULONG(130, 130, 130), "grey51" },
1695 { RGB_TO_ULONG(133, 133, 133), "gray52" },
1696 { RGB_TO_ULONG(133, 133, 133), "grey52" },
1697 { RGB_TO_ULONG(135, 135, 135), "gray53" },
1698 { RGB_TO_ULONG(135, 135, 135), "grey53" },
1699 { RGB_TO_ULONG(138, 138, 138), "gray54" },
1700 { RGB_TO_ULONG(138, 138, 138), "grey54" },
1701 { RGB_TO_ULONG(140, 140, 140), "gray55" },
1702 { RGB_TO_ULONG(140, 140, 140), "grey55" },
1703 { RGB_TO_ULONG(143, 143, 143), "gray56" },
1704 { RGB_TO_ULONG(143, 143, 143), "grey56" },
1705 { RGB_TO_ULONG(145, 145, 145), "gray57" },
1706 { RGB_TO_ULONG(145, 145, 145), "grey57" },
1707 { RGB_TO_ULONG(148, 148, 148), "gray58" },
1708 { RGB_TO_ULONG(148, 148, 148), "grey58" },
1709 { RGB_TO_ULONG(150, 150, 150), "gray59" },
1710 { RGB_TO_ULONG(150, 150, 150), "grey59" },
1711 { RGB_TO_ULONG(153, 153, 153), "gray60" },
1712 { RGB_TO_ULONG(153, 153, 153), "grey60" },
1713 { RGB_TO_ULONG(156, 156, 156), "gray61" },
1714 { RGB_TO_ULONG(156, 156, 156), "grey61" },
1715 { RGB_TO_ULONG(158, 158, 158), "gray62" },
1716 { RGB_TO_ULONG(158, 158, 158), "grey62" },
1717 { RGB_TO_ULONG(161, 161, 161), "gray63" },
1718 { RGB_TO_ULONG(161, 161, 161), "grey63" },
1719 { RGB_TO_ULONG(163, 163, 163), "gray64" },
1720 { RGB_TO_ULONG(163, 163, 163), "grey64" },
1721 { RGB_TO_ULONG(166, 166, 166), "gray65" },
1722 { RGB_TO_ULONG(166, 166, 166), "grey65" },
1723 { RGB_TO_ULONG(168, 168, 168), "gray66" },
1724 { RGB_TO_ULONG(168, 168, 168), "grey66" },
1725 { RGB_TO_ULONG(171, 171, 171), "gray67" },
1726 { RGB_TO_ULONG(171, 171, 171), "grey67" },
1727 { RGB_TO_ULONG(173, 173, 173), "gray68" },
1728 { RGB_TO_ULONG(173, 173, 173), "grey68" },
1729 { RGB_TO_ULONG(176, 176, 176), "gray69" },
1730 { RGB_TO_ULONG(176, 176, 176), "grey69" },
1731 { RGB_TO_ULONG(179, 179, 179), "gray70" },
1732 { RGB_TO_ULONG(179, 179, 179), "grey70" },
1733 { RGB_TO_ULONG(181, 181, 181), "gray71" },
1734 { RGB_TO_ULONG(181, 181, 181), "grey71" },
1735 { RGB_TO_ULONG(184, 184, 184), "gray72" },
1736 { RGB_TO_ULONG(184, 184, 184), "grey72" },
1737 { RGB_TO_ULONG(186, 186, 186), "gray73" },
1738 { RGB_TO_ULONG(186, 186, 186), "grey73" },
1739 { RGB_TO_ULONG(189, 189, 189), "gray74" },
1740 { RGB_TO_ULONG(189, 189, 189), "grey74" },
1741 { RGB_TO_ULONG(191, 191, 191), "gray75" },
1742 { RGB_TO_ULONG(191, 191, 191), "grey75" },
1743 { RGB_TO_ULONG(194, 194, 194), "gray76" },
1744 { RGB_TO_ULONG(194, 194, 194), "grey76" },
1745 { RGB_TO_ULONG(196, 196, 196), "gray77" },
1746 { RGB_TO_ULONG(196, 196, 196), "grey77" },
1747 { RGB_TO_ULONG(199, 199, 199), "gray78" },
1748 { RGB_TO_ULONG(199, 199, 199), "grey78" },
1749 { RGB_TO_ULONG(201, 201, 201), "gray79" },
1750 { RGB_TO_ULONG(201, 201, 201), "grey79" },
1751 { RGB_TO_ULONG(204, 204, 204), "gray80" },
1752 { RGB_TO_ULONG(204, 204, 204), "grey80" },
1753 { RGB_TO_ULONG(207, 207, 207), "gray81" },
1754 { RGB_TO_ULONG(207, 207, 207), "grey81" },
1755 { RGB_TO_ULONG(209, 209, 209), "gray82" },
1756 { RGB_TO_ULONG(209, 209, 209), "grey82" },
1757 { RGB_TO_ULONG(212, 212, 212), "gray83" },
1758 { RGB_TO_ULONG(212, 212, 212), "grey83" },
1759 { RGB_TO_ULONG(214, 214, 214), "gray84" },
1760 { RGB_TO_ULONG(214, 214, 214), "grey84" },
1761 { RGB_TO_ULONG(217, 217, 217), "gray85" },
1762 { RGB_TO_ULONG(217, 217, 217), "grey85" },
1763 { RGB_TO_ULONG(219, 219, 219), "gray86" },
1764 { RGB_TO_ULONG(219, 219, 219), "grey86" },
1765 { RGB_TO_ULONG(222, 222, 222), "gray87" },
1766 { RGB_TO_ULONG(222, 222, 222), "grey87" },
1767 { RGB_TO_ULONG(224, 224, 224), "gray88" },
1768 { RGB_TO_ULONG(224, 224, 224), "grey88" },
1769 { RGB_TO_ULONG(227, 227, 227), "gray89" },
1770 { RGB_TO_ULONG(227, 227, 227), "grey89" },
1771 { RGB_TO_ULONG(229, 229, 229), "gray90" },
1772 { RGB_TO_ULONG(229, 229, 229), "grey90" },
1773 { RGB_TO_ULONG(232, 232, 232), "gray91" },
1774 { RGB_TO_ULONG(232, 232, 232), "grey91" },
1775 { RGB_TO_ULONG(235, 235, 235), "gray92" },
1776 { RGB_TO_ULONG(235, 235, 235), "grey92" },
1777 { RGB_TO_ULONG(237, 237, 237), "gray93" },
1778 { RGB_TO_ULONG(237, 237, 237), "grey93" },
1779 { RGB_TO_ULONG(240, 240, 240), "gray94" },
1780 { RGB_TO_ULONG(240, 240, 240), "grey94" },
1781 { RGB_TO_ULONG(242, 242, 242), "gray95" },
1782 { RGB_TO_ULONG(242, 242, 242), "grey95" },
1783 { RGB_TO_ULONG(245, 245, 245), "gray96" },
1784 { RGB_TO_ULONG(245, 245, 245), "grey96" },
1785 { RGB_TO_ULONG(247, 247, 247), "gray97" },
1786 { RGB_TO_ULONG(247, 247, 247), "grey97" },
1787 { RGB_TO_ULONG(250, 250, 250), "gray98" },
1788 { RGB_TO_ULONG(250, 250, 250), "grey98" },
1789 { RGB_TO_ULONG(252, 252, 252), "gray99" },
1790 { RGB_TO_ULONG(252, 252, 252), "grey99" },
1791 { RGB_TO_ULONG(255, 255, 255), "gray100" },
1792 { RGB_TO_ULONG(255, 255, 255), "grey100" },
1793 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
1794 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
1795 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
1796 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
1797 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
1798 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
1799 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
1800 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
1801 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
1802 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
1803 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
1804 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1805 { RGB_TO_ULONG(144, 238, 144), "light green" },
1806 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1810 mac_color_map_lookup (colorname
)
1813 Lisp_Object ret
= Qnil
;
1818 for (i
= 0; i
< sizeof (mac_color_map
) / sizeof (mac_color_map
[0]); i
++)
1819 if (stricmp (colorname
, mac_color_map
[i
].name
) == 0)
1821 ret
= mac_color_map
[i
].color
;
1831 x_to_mac_color (colorname
)
1834 register Lisp_Object tail
, ret
= Qnil
;
1838 if (colorname
[0] == '#')
1840 /* Could be an old-style RGB Device specification. */
1843 color
= colorname
+ 1;
1845 size
= strlen(color
);
1846 if (size
== 3 || size
== 6 || size
== 9 || size
== 12)
1848 unsigned long colorval
;
1854 for (i
= 0; i
< 3; i
++)
1858 unsigned long value
;
1860 /* The check for 'x' in the following conditional takes into
1861 account the fact that strtol allows a "0x" in front of
1862 our numbers, and we don't. */
1863 if (!isxdigit(color
[0]) || color
[1] == 'x')
1867 value
= strtoul(color
, &end
, 16);
1869 if (errno
== ERANGE
|| end
- color
!= size
)
1874 value
= value
* 0x10;
1885 colorval
|= (value
<< pos
);
1896 else if (strnicmp(colorname
, "rgb:", 4) == 0)
1899 unsigned long colorval
;
1904 color
= colorname
+ 4;
1905 for (i
= 0; i
< 3; i
++)
1908 unsigned long value
;
1910 /* The check for 'x' in the following conditional takes into
1911 account the fact that strtol allows a "0x" in front of
1912 our numbers, and we don't. */
1913 if (!isxdigit(color
[0]) || color
[1] == 'x')
1915 value
= strtoul(color
, &end
, 16);
1916 if (errno
== ERANGE
)
1918 switch (end
- color
)
1921 value
= value
* 0x10 + value
;
1934 if (value
== ULONG_MAX
)
1936 colorval
|= (value
<< pos
);
1950 else if (strnicmp(colorname
, "rgbi:", 5) == 0)
1952 /* This is an RGB Intensity specification. */
1954 unsigned long colorval
;
1959 color
= colorname
+ 5;
1960 for (i
= 0; i
< 3; i
++)
1966 value
= strtod(color
, &end
);
1967 if (errno
== ERANGE
)
1969 if (value
< 0.0 || value
> 1.0)
1971 val
= (unsigned long)(0x100 * value
);
1972 /* We used 0x100 instead of 0xFF to give an continuous
1973 range between 0.0 and 1.0 inclusive. The next statement
1974 fixes the 1.0 case. */
1977 colorval
|= (val
<< pos
);
1992 ret
= mac_color_map_lookup (colorname
);
1998 /* Gamma-correct COLOR on frame F. */
2001 gamma_correct (f
, color
)
2003 unsigned long *color
;
2007 unsigned long red
, green
, blue
;
2009 red
= pow (RED_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2010 green
= pow (GREEN_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2011 blue
= pow (BLUE_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2012 *color
= RGB_TO_ULONG (red
, green
, blue
);
2016 /* Decide if color named COLOR is valid for the display associated
2017 with the selected frame; if so, return the rgb values in COLOR_DEF.
2018 If ALLOC is nonzero, allocate a new colormap cell. */
2021 mac_defined_color (f
, color
, color_def
, alloc
)
2027 register Lisp_Object tem
;
2028 unsigned long mac_color_ref
;
2030 tem
= x_to_mac_color (color
);
2036 /* Apply gamma correction. */
2037 mac_color_ref
= XUINT (tem
);
2038 gamma_correct (f
, &mac_color_ref
);
2039 XSETINT (tem
, mac_color_ref
);
2042 color_def
->pixel
= mac_color_ref
;
2043 color_def
->red
= RED_FROM_ULONG (mac_color_ref
);
2044 color_def
->green
= GREEN_FROM_ULONG (mac_color_ref
);
2045 color_def
->blue
= BLUE_FROM_ULONG (mac_color_ref
);
2055 /* Given a string ARG naming a color, compute a pixel value from it
2056 suitable for screen F.
2057 If F is not a color screen, return DEF (default) regardless of what
2061 x_decode_color (f
, arg
, def
)
2070 if (strcmp (SDATA (arg
), "black") == 0)
2071 return BLACK_PIX_DEFAULT (f
);
2072 else if (strcmp (SDATA (arg
), "white") == 0)
2073 return WHITE_PIX_DEFAULT (f
);
2076 if ((FRAME_MAC_DISPLAY_INFO (f
)->n_planes
2077 * FRAME_MAC_DISPLAY_INFO (f
)->n_cbits
) == 1)
2081 if (mac_defined_color (f
, SDATA (arg
), &cdef
, 1))
2084 /* defined_color failed; return an ultimate default. */
2088 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
2089 the previous value of that parameter, NEW_VALUE is the new value. */
2092 x_set_line_spacing (f
, new_value
, old_value
)
2094 Lisp_Object new_value
, old_value
;
2096 if (NILP (new_value
))
2097 f
->extra_line_spacing
= 0;
2098 else if (NATNUMP (new_value
))
2099 f
->extra_line_spacing
= XFASTINT (new_value
);
2101 Fsignal (Qerror
, Fcons (build_string ("Illegal line-spacing"),
2102 Fcons (new_value
, Qnil
)));
2103 if (FRAME_VISIBLE_P (f
))
2108 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
2109 the previous value of that parameter, NEW_VALUE is the new value. */
2112 x_set_screen_gamma (f
, new_value
, old_value
)
2114 Lisp_Object new_value
, old_value
;
2116 if (NILP (new_value
))
2118 else if (NUMBERP (new_value
) && XFLOATINT (new_value
) > 0)
2119 /* The value 0.4545 is the normal viewing gamma. */
2120 f
->gamma
= 1.0 / (0.4545 * XFLOATINT (new_value
));
2122 Fsignal (Qerror
, Fcons (build_string ("Illegal screen-gamma"),
2123 Fcons (new_value
, Qnil
)));
2125 clear_face_cache (0);
2129 /* Functions called only from `x_set_frame_param'
2130 to set individual parameters.
2132 If FRAME_MAC_WINDOW (f) is 0,
2133 the frame is being created and its window does not exist yet.
2134 In that case, just record the parameter's new value
2135 in the standard place; do not attempt to change the window. */
2138 x_set_foreground_color (f
, arg
, oldval
)
2140 Lisp_Object arg
, oldval
;
2142 FRAME_FOREGROUND_PIXEL (f
)
2143 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2145 if (FRAME_MAC_WINDOW (f
) != 0)
2147 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
2148 if (FRAME_VISIBLE_P (f
))
2154 x_set_background_color (f
, arg
, oldval
)
2156 Lisp_Object arg
, oldval
;
2158 FRAME_BACKGROUND_PIXEL (f
)
2159 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
2161 if (FRAME_MAC_WINDOW (f
) != 0)
2163 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
2165 if (FRAME_VISIBLE_P (f
))
2171 x_set_mouse_color (f
, arg
, oldval
)
2173 Lisp_Object arg
, oldval
;
2175 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
2179 if (!EQ (Qnil
, arg
))
2180 f
->output_data
.mac
->mouse_pixel
2181 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2182 mask_color
= FRAME_BACKGROUND_PIXEL (f
);
2184 /* Don't let pointers be invisible. */
2185 if (mask_color
== f
->output_data
.mac
->mouse_pixel
2186 && mask_color
== FRAME_BACKGROUND_PIXEL (f
))
2187 f
->output_data
.mac
->mouse_pixel
= FRAME_FOREGROUND_PIXEL (f
);
2189 #if 0 /* MAC_TODO : cursor changes */
2192 /* It's not okay to crash if the user selects a screwy cursor. */
2193 count
= x_catch_errors (FRAME_W32_DISPLAY (f
));
2195 if (!EQ (Qnil
, Vx_pointer_shape
))
2197 CHECK_NUMBER (Vx_pointer_shape
);
2198 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XINT (Vx_pointer_shape
));
2201 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
2202 x_check_errors (FRAME_W32_DISPLAY (f
), "bad text pointer cursor: %s");
2204 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
2206 CHECK_NUMBER (Vx_nontext_pointer_shape
);
2207 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2208 XINT (Vx_nontext_pointer_shape
));
2211 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_left_ptr
);
2212 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
2214 if (!EQ (Qnil
, Vx_hourglass_pointer_shape
))
2216 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
2217 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2218 XINT (Vx_hourglass_pointer_shape
));
2221 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_watch
);
2222 x_check_errors (FRAME_W32_DISPLAY (f
), "bad busy pointer cursor: %s");
2224 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
2225 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
2227 CHECK_NUMBER (Vx_mode_pointer_shape
);
2228 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2229 XINT (Vx_mode_pointer_shape
));
2232 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
2233 x_check_errors (FRAME_W32_DISPLAY (f
), "bad modeline pointer cursor: %s");
2235 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
2237 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
2239 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2240 XINT (Vx_sensitive_text_pointer_shape
));
2243 cross_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_crosshair
);
2245 if (!NILP (Vx_window_horizontal_drag_shape
))
2247 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
2248 horizontal_drag_cursor
2249 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2250 XINT (Vx_window_horizontal_drag_shape
));
2253 horizontal_drag_cursor
2254 = XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_sb_h_double_arrow
);
2256 /* Check and report errors with the above calls. */
2257 x_check_errors (FRAME_W32_DISPLAY (f
), "can't set cursor shape: %s");
2258 x_uncatch_errors (FRAME_W32_DISPLAY (f
), count
);
2261 XColor fore_color
, back_color
;
2263 fore_color
.pixel
= f
->output_data
.w32
->mouse_pixel
;
2264 back_color
.pixel
= mask_color
;
2265 XQueryColor (FRAME_W32_DISPLAY (f
),
2266 DefaultColormap (FRAME_W32_DISPLAY (f
),
2267 DefaultScreen (FRAME_W32_DISPLAY (f
))),
2269 XQueryColor (FRAME_W32_DISPLAY (f
),
2270 DefaultColormap (FRAME_W32_DISPLAY (f
),
2271 DefaultScreen (FRAME_W32_DISPLAY (f
))),
2273 XRecolorCursor (FRAME_W32_DISPLAY (f
), cursor
,
2274 &fore_color
, &back_color
);
2275 XRecolorCursor (FRAME_W32_DISPLAY (f
), nontext_cursor
,
2276 &fore_color
, &back_color
);
2277 XRecolorCursor (FRAME_W32_DISPLAY (f
), mode_cursor
,
2278 &fore_color
, &back_color
);
2279 XRecolorCursor (FRAME_W32_DISPLAY (f
), cross_cursor
,
2280 &fore_color
, &back_color
);
2281 XRecolorCursor (FRAME_W32_DISPLAY (f
), hourglass_cursor
,
2282 &fore_color
, &back_color
);
2285 if (FRAME_W32_WINDOW (f
) != 0)
2286 XDefineCursor (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), cursor
);
2288 if (cursor
!= f
->output_data
.w32
->text_cursor
&& f
->output_data
.w32
->text_cursor
!= 0)
2289 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->text_cursor
);
2290 f
->output_data
.w32
->text_cursor
= cursor
;
2292 if (nontext_cursor
!= f
->output_data
.w32
->nontext_cursor
2293 && f
->output_data
.w32
->nontext_cursor
!= 0)
2294 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->nontext_cursor
);
2295 f
->output_data
.w32
->nontext_cursor
= nontext_cursor
;
2297 if (hourglass_cursor
!= f
->output_data
.w32
->hourglass_cursor
2298 && f
->output_data
.w32
->hourglass_cursor
!= 0)
2299 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hourglass_cursor
);
2300 f
->output_data
.w32
->hourglass_cursor
= hourglass_cursor
;
2302 if (mode_cursor
!= f
->output_data
.w32
->modeline_cursor
2303 && f
->output_data
.w32
->modeline_cursor
!= 0)
2304 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->modeline_cursor
);
2305 f
->output_data
.w32
->modeline_cursor
= mode_cursor
;
2307 if (cross_cursor
!= f
->output_data
.w32
->cross_cursor
2308 && f
->output_data
.w32
->cross_cursor
!= 0)
2309 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->cross_cursor
);
2310 f
->output_data
.w32
->cross_cursor
= cross_cursor
;
2312 XFlush (FRAME_W32_DISPLAY (f
));
2315 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
2316 #endif /* MAC_TODO */
2320 x_set_cursor_color (f
, arg
, oldval
)
2322 Lisp_Object arg
, oldval
;
2324 unsigned long fore_pixel
;
2326 if (!NILP (Vx_cursor_fore_pixel
))
2327 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
2328 WHITE_PIX_DEFAULT (f
));
2330 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2331 f
->output_data
.mac
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2333 /* Make sure that the cursor color differs from the background color. */
2334 if (f
->output_data
.mac
->cursor_pixel
== FRAME_BACKGROUND_PIXEL (f
))
2336 f
->output_data
.mac
->cursor_pixel
= f
->output_data
.mac
->mouse_pixel
;
2337 if (f
->output_data
.mac
->cursor_pixel
== fore_pixel
)
2338 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2340 FRAME_FOREGROUND_PIXEL (f
) = fore_pixel
;
2342 #if 0 /* MAC_TODO: cannot figure out what to do (wrong number of params) */
2343 if (FRAME_MAC_WINDOW (f
) != 0)
2345 if (FRAME_VISIBLE_P (f
))
2347 x_display_cursor (f
, 0);
2348 x_display_cursor (f
, 1);
2353 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
2356 /* Set the border-color of frame F to pixel value PIX.
2357 Note that this does not fully take effect if done before
2360 x_set_border_pixel (f
, pix
)
2364 f
->output_data
.mac
->border_pixel
= pix
;
2366 if (FRAME_MAC_WINDOW (f
) != 0 && f
->output_data
.mac
->border_width
> 0)
2368 if (FRAME_VISIBLE_P (f
))
2373 /* Set the border-color of frame F to value described by ARG.
2374 ARG can be a string naming a color.
2375 The border-color is used for the border that is drawn by the server.
2376 Note that this does not fully take effect if done before
2377 F has a window; it must be redone when the window is created. */
2380 x_set_border_color (f
, arg
, oldval
)
2382 Lisp_Object arg
, oldval
;
2387 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2388 x_set_border_pixel (f
, pix
);
2389 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
2393 x_set_cursor_type (f
, arg
, oldval
)
2395 Lisp_Object arg
, oldval
;
2397 set_frame_cursor_types (f
, arg
);
2399 /* Make sure the cursor gets redrawn. This is overkill, but how
2400 often do people change cursor types? */
2401 update_mode_lines
++;
2404 #if 0 /* MAC_TODO: really no icon for Mac */
2406 x_set_icon_type (f
, arg
, oldval
)
2408 Lisp_Object arg
, oldval
;
2412 if (NILP (arg
) && NILP (oldval
))
2415 if (STRINGP (arg
) && STRINGP (oldval
)
2416 && EQ (Fstring_equal (oldval
, arg
), Qt
))
2419 if (SYMBOLP (arg
) && SYMBOLP (oldval
) && EQ (arg
, oldval
))
2424 result
= x_bitmap_icon (f
, arg
);
2428 error ("No icon window available");
2433 #endif /* MAC_TODO */
2435 /* Return non-nil if frame F wants a bitmap icon. */
2443 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
2451 x_set_icon_name (f
, arg
, oldval
)
2453 Lisp_Object arg
, oldval
;
2459 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
2462 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
2467 #if 0 /* MAC_TODO */
2468 if (f
->output_data
.w32
->icon_bitmap
!= 0)
2473 result
= x_text_icon (f
,
2474 (char *) SDATA ((!NILP (f
->icon_name
)
2483 error ("No icon window available");
2486 /* If the window was unmapped (and its icon was mapped),
2487 the new icon is not mapped, so map the window in its stead. */
2488 if (FRAME_VISIBLE_P (f
))
2490 #ifdef USE_X_TOOLKIT
2491 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
2493 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
2496 XFlush (FRAME_W32_DISPLAY (f
));
2498 #endif /* MAC_TODO */
2501 extern Lisp_Object
x_new_font ();
2502 extern Lisp_Object
x_new_fontset();
2505 x_set_font (f
, arg
, oldval
)
2507 Lisp_Object arg
, oldval
;
2510 Lisp_Object fontset_name
;
2512 int old_fontset
= FRAME_FONTSET(f
);
2516 fontset_name
= Fquery_fontset (arg
, Qnil
);
2519 result
= (STRINGP (fontset_name
)
2520 ? x_new_fontset (f
, SDATA (fontset_name
))
2521 : x_new_font (f
, SDATA (arg
)));
2524 if (EQ (result
, Qnil
))
2525 error ("Font `%s' is not defined", SDATA (arg
));
2526 else if (EQ (result
, Qt
))
2527 error ("The characters of the given font have varying widths");
2528 else if (STRINGP (result
))
2530 if (STRINGP (fontset_name
))
2532 /* Fontset names are built from ASCII font names, so the
2533 names may be equal despite there was a change. */
2534 if (old_fontset
== FRAME_FONTSET (f
))
2537 else if (!NILP (Fequal (result
, oldval
)))
2540 store_frame_param (f
, Qfont
, result
);
2541 recompute_basic_faces (f
);
2546 do_pending_window_change (0);
2548 /* Don't call `face-set-after-frame-default' when faces haven't been
2549 initialized yet. This is the case when called from
2550 Fx_create_frame. In that case, the X widget or window doesn't
2551 exist either, and we can end up in x_report_frame_params with a
2552 null widget which gives a segfault. */
2553 if (FRAME_FACE_CACHE (f
))
2555 XSETFRAME (frame
, f
);
2556 call1 (Qface_set_after_frame_default
, frame
);
2561 x_set_border_width (f
, arg
, oldval
)
2563 Lisp_Object arg
, oldval
;
2567 if (XINT (arg
) == f
->output_data
.mac
->border_width
)
2570 #if 0 /* MAC_TODO */
2571 if (FRAME_MAC_WINDOW (f
) != 0)
2572 error ("Cannot change the border width of a window");
2575 f
->output_data
.mac
->border_width
= XINT (arg
);
2579 x_set_internal_border_width (f
, arg
, oldval
)
2581 Lisp_Object arg
, oldval
;
2583 int old
= f
->output_data
.mac
->internal_border_width
;
2586 f
->output_data
.mac
->internal_border_width
= XINT (arg
);
2587 if (f
->output_data
.mac
->internal_border_width
< 0)
2588 f
->output_data
.mac
->internal_border_width
= 0;
2590 if (f
->output_data
.mac
->internal_border_width
== old
)
2593 if (FRAME_MAC_WINDOW (f
) != 0)
2595 x_set_window_size (f
, 0, f
->width
, f
->height
);
2596 SET_FRAME_GARBAGED (f
);
2597 do_pending_window_change (0);
2600 SET_FRAME_GARBAGED (f
);
2604 x_set_visibility (f
, value
, oldval
)
2606 Lisp_Object value
, oldval
;
2609 XSETFRAME (frame
, f
);
2612 Fmake_frame_invisible (frame
, Qt
);
2613 else if (EQ (value
, Qicon
))
2614 Ficonify_frame (frame
);
2616 Fmake_frame_visible (frame
);
2620 /* Change window heights in windows rooted in WINDOW by N lines. */
2623 x_change_window_heights (window
, n
)
2627 struct window
*w
= XWINDOW (window
);
2629 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
2630 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
2632 if (INTEGERP (w
->orig_top
))
2633 XSETFASTINT (w
->orig_top
, XFASTINT (w
->orig_top
) + n
);
2634 if (INTEGERP (w
->orig_height
))
2635 XSETFASTINT (w
->orig_height
, XFASTINT (w
->orig_height
) - n
);
2637 /* Handle just the top child in a vertical split. */
2638 if (!NILP (w
->vchild
))
2639 x_change_window_heights (w
->vchild
, n
);
2641 /* Adjust all children in a horizontal split. */
2642 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
2644 w
= XWINDOW (window
);
2645 x_change_window_heights (window
, n
);
2650 x_set_menu_bar_lines (f
, value
, oldval
)
2652 Lisp_Object value
, oldval
;
2655 int olines
= FRAME_MENU_BAR_LINES (f
);
2657 /* Right now, menu bars don't work properly in minibuf-only frames;
2658 most of the commands try to apply themselves to the minibuffer
2659 frame itself, and get an error because you can't switch buffers
2660 in or split the minibuffer window. */
2661 if (FRAME_MINIBUF_ONLY_P (f
))
2664 if (INTEGERP (value
))
2665 nlines
= XINT (value
);
2669 FRAME_MENU_BAR_LINES (f
) = 0;
2671 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
2674 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
2675 free_frame_menubar (f
);
2676 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
2678 /* Adjust the frame size so that the client (text) dimensions
2679 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
2681 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2682 do_pending_window_change (0);
2688 /* Set the number of lines used for the tool bar of frame F to VALUE.
2689 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
2690 is the old number of tool bar lines. This function changes the
2691 height of all windows on frame F to match the new tool bar height.
2692 The frame's height doesn't change. */
2695 x_set_tool_bar_lines (f
, value
, oldval
)
2697 Lisp_Object value
, oldval
;
2699 int delta
, nlines
, root_height
;
2700 Lisp_Object root_window
;
2702 /* Treat tool bars like menu bars. */
2703 if (FRAME_MINIBUF_ONLY_P (f
))
2706 /* Use VALUE only if an integer >= 0. */
2707 if (INTEGERP (value
) && XINT (value
) >= 0)
2708 nlines
= XFASTINT (value
);
2712 /* Make sure we redisplay all windows in this frame. */
2713 ++windows_or_buffers_changed
;
2715 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
2717 /* Don't resize the tool-bar to more than we have room for. */
2718 root_window
= FRAME_ROOT_WINDOW (f
);
2719 root_height
= XINT (XWINDOW (root_window
)->height
);
2720 if (root_height
- delta
< 1)
2722 delta
= root_height
- 1;
2723 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
2726 FRAME_TOOL_BAR_LINES (f
) = nlines
;
2727 x_change_window_heights (root_window
, delta
);
2730 /* We also have to make sure that the internal border at the top of
2731 the frame, below the menu bar or tool bar, is redrawn when the
2732 tool bar disappears. This is so because the internal border is
2733 below the tool bar if one is displayed, but is below the menu bar
2734 if there isn't a tool bar. The tool bar draws into the area
2735 below the menu bar. */
2736 if (FRAME_MAC_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
2740 clear_current_matrices (f
);
2741 updating_frame
= NULL
;
2744 /* If the tool bar gets smaller, the internal border below it
2745 has to be cleared. It was formerly part of the display
2746 of the larger tool bar, and updating windows won't clear it. */
2749 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
2750 int width
= PIXEL_WIDTH (f
);
2751 int y
= nlines
* CANON_Y_UNIT (f
);
2754 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2755 0, y
, width
, height
, 0);
2758 if (WINDOWP (f
->tool_bar_window
))
2759 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
2764 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
2767 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2768 name; if NAME is a string, set F's name to NAME and set
2769 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2771 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2772 suggesting a new name, which lisp code should override; if
2773 F->explicit_name is set, ignore the new name; otherwise, set it. */
2776 x_set_name (f
, name
, explicit)
2781 /* Make sure that requests from lisp code override requests from
2782 Emacs redisplay code. */
2785 /* If we're switching from explicit to implicit, we had better
2786 update the mode lines and thereby update the title. */
2787 if (f
->explicit_name
&& NILP (name
))
2788 update_mode_lines
= 1;
2790 f
->explicit_name
= ! NILP (name
);
2792 else if (f
->explicit_name
)
2795 /* If NAME is nil, set the name to the w32_id_name. */
2798 /* Check for no change needed in this very common case
2799 before we do any consing. */
2800 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
,
2803 name
= build_string (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
);
2806 CHECK_STRING (name
);
2808 /* Don't change the name if it's already NAME. */
2809 if (! NILP (Fstring_equal (name
, f
->name
)))
2814 /* For setting the frame title, the title parameter should override
2815 the name parameter. */
2816 if (! NILP (f
->title
))
2819 if (FRAME_MAC_WINDOW (f
))
2821 if (STRING_MULTIBYTE (name
))
2822 #if 0 /* MAC_TODO: encoding title string */
2823 name
= ENCODE_SYSTEM (name
);
2832 if (strlen (SDATA (name
)) < 255)
2834 strcpy (windowTitle
, SDATA (name
));
2835 c2pstr (windowTitle
);
2836 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2844 /* This function should be called when the user's lisp code has
2845 specified a name for the frame; the name will override any set by the
2848 x_explicitly_set_name (f
, arg
, oldval
)
2850 Lisp_Object arg
, oldval
;
2852 x_set_name (f
, arg
, 1);
2855 /* This function should be called by Emacs redisplay code to set the
2856 name; names set this way will never override names set by the user's
2859 x_implicitly_set_name (f
, arg
, oldval
)
2861 Lisp_Object arg
, oldval
;
2863 x_set_name (f
, arg
, 0);
2866 /* Change the title of frame F to NAME.
2867 If NAME is nil, use the frame name as the title.
2869 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2870 name; if NAME is a string, set F's name to NAME and set
2871 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2873 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2874 suggesting a new name, which lisp code should override; if
2875 F->explicit_name is set, ignore the new name; otherwise, set it. */
2878 x_set_title (f
, name
, old_name
)
2880 Lisp_Object name
, old_name
;
2882 /* Don't change the title if it's already NAME. */
2883 if (EQ (name
, f
->title
))
2886 update_mode_lines
= 1;
2893 if (FRAME_MAC_WINDOW (f
))
2895 if (STRING_MULTIBYTE (name
))
2896 #if 0 /* MAC_TODO: encoding title string */
2897 name
= ENCODE_SYSTEM (name
);
2906 if (strlen (SDATA (name
)) < 255)
2908 strcpy (windowTitle
, SDATA (name
));
2909 c2pstr (windowTitle
);
2910 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2919 x_set_autoraise (f
, arg
, oldval
)
2921 Lisp_Object arg
, oldval
;
2923 f
->auto_raise
= !EQ (Qnil
, arg
);
2927 x_set_autolower (f
, arg
, oldval
)
2929 Lisp_Object arg
, oldval
;
2931 f
->auto_lower
= !EQ (Qnil
, arg
);
2935 x_set_unsplittable (f
, arg
, oldval
)
2937 Lisp_Object arg
, oldval
;
2939 f
->no_split
= !NILP (arg
);
2943 x_set_vertical_scroll_bars (f
, arg
, oldval
)
2945 Lisp_Object arg
, oldval
;
2947 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
2948 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
2949 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
2950 || (!NILP (arg
) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
2952 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
)
2954 ? vertical_scroll_bar_none
2956 ? vertical_scroll_bar_right
2957 : vertical_scroll_bar_left
);
2959 /* We set this parameter before creating the window for the
2960 frame, so we can get the geometry right from the start.
2961 However, if the window hasn't been created yet, we shouldn't
2962 call x_set_window_size. */
2963 if (FRAME_MAC_WINDOW (f
))
2964 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2965 do_pending_window_change (0);
2970 x_set_scroll_bar_width (f
, arg
, oldval
)
2972 Lisp_Object arg
, oldval
;
2974 /* Imitate X without X Toolkit */
2976 int wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
2981 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 16; /* Aqua scroll bars. */
2982 FRAME_SCROLL_BAR_COLS (f
) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) +
2984 #else /* not MAC_OSX */
2985 /* Make the actual width at least 14 pixels and a multiple of a
2987 FRAME_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2989 /* Use all of that space (aside from required margins) for the
2991 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
2992 #endif /* not MAC_OSX */
2993 if (FRAME_MAC_WINDOW (f
))
2994 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2995 do_pending_window_change (0);
2997 else if (INTEGERP (arg
) && XINT (arg
) > 0
2998 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
3000 if (XFASTINT (arg
) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
3001 XSETINT (arg
, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
+ 1);
3003 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
3004 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
3005 if (FRAME_MAC_WINDOW (f
))
3006 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
3007 do_pending_window_change (0);
3009 change_frame_size (f
, 0, FRAME_WIDTH (f
), 0, 0, 0);
3010 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.hpos
= 0;
3011 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.x
= 0;
3014 /* Subroutines of creating an frame. */
3016 /* Make sure that Vx_resource_name is set to a reasonable value.
3017 Fix it up, or set it to `emacs' if it is too hopeless. */
3020 validate_x_resource_name ()
3023 /* Number of valid characters in the resource name. */
3025 /* Number of invalid characters in the resource name. */
3030 if (STRINGP (Vx_resource_name
))
3032 unsigned char *p
= SDATA (Vx_resource_name
);
3035 len
= SBYTES (Vx_resource_name
);
3037 /* Only letters, digits, - and _ are valid in resource names.
3038 Count the valid characters and count the invalid ones. */
3039 for (i
= 0; i
< len
; i
++)
3042 if (! ((c
>= 'a' && c
<= 'z')
3043 || (c
>= 'A' && c
<= 'Z')
3044 || (c
>= '0' && c
<= '9')
3045 || c
== '-' || c
== '_'))
3052 /* Not a string => completely invalid. */
3053 bad_count
= 5, good_count
= 0;
3055 /* If name is valid already, return. */
3059 /* If name is entirely invalid, or nearly so, use `emacs'. */
3061 || (good_count
== 1 && bad_count
> 0))
3063 Vx_resource_name
= build_string ("emacs");
3067 /* Name is partly valid. Copy it and replace the invalid characters
3068 with underscores. */
3070 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
3072 for (i
= 0; i
< len
; i
++)
3074 int c
= SREF (new, i
);
3075 if (! ((c
>= 'a' && c
<= 'z')
3076 || (c
>= 'A' && c
<= 'Z')
3077 || (c
>= '0' && c
<= '9')
3078 || c
== '-' || c
== '_'))
3084 #if 0 /* MAC_TODO: implement resource strings */
3085 extern char *x_get_string_resource ();
3087 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
3088 doc
: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3089 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3090 class, where INSTANCE is the name under which Emacs was invoked, or
3091 the name specified by the `-name' or `-rn' command-line arguments.
3093 The optional arguments COMPONENT and SUBCLASS add to the key and the
3094 class, respectively. You must specify both of them or neither.
3095 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3096 and the class is `Emacs.CLASS.SUBCLASS'. */)
3097 (attribute
, class, component
, subclass
)
3098 Lisp_Object attribute
, class, component
, subclass
;
3100 register char *value
;
3104 CHECK_STRING (attribute
);
3105 CHECK_STRING (class);
3107 if (!NILP (component
))
3108 CHECK_STRING (component
);
3109 if (!NILP (subclass
))
3110 CHECK_STRING (subclass
);
3111 if (NILP (component
) != NILP (subclass
))
3112 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3114 validate_x_resource_name ();
3116 /* Allocate space for the components, the dots which separate them,
3117 and the final '\0'. Make them big enough for the worst case. */
3118 name_key
= (char *) alloca (SBYTES (Vx_resource_name
)
3119 + (STRINGP (component
)
3120 ? SBYTES (component
) : 0)
3121 + SBYTES (attribute
)
3124 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
3126 + (STRINGP (subclass
)
3127 ? SBYTES (subclass
) : 0)
3130 /* Start with emacs.FRAMENAME for the name (the specific one)
3131 and with `Emacs' for the class key (the general one). */
3132 strcpy (name_key
, SDATA (Vx_resource_name
));
3133 strcpy (class_key
, EMACS_CLASS
);
3135 strcat (class_key
, ".");
3136 strcat (class_key
, SDATA (class));
3138 if (!NILP (component
))
3140 strcat (class_key
, ".");
3141 strcat (class_key
, SDATA (subclass
));
3143 strcat (name_key
, ".");
3144 strcat (name_key
, SDATA (component
));
3147 strcat (name_key
, ".");
3148 strcat (name_key
, SDATA (attribute
));
3150 value
= x_get_string_resource (Qnil
,
3151 name_key
, class_key
);
3153 if (value
!= (char *) 0)
3154 return build_string (value
);
3159 /* Used when C code wants a resource value. */
3162 x_get_resource_string (attribute
, class)
3163 char *attribute
, *class;
3167 struct frame
*sf
= SELECTED_FRAME ();
3169 /* Allocate space for the components, the dots which separate them,
3170 and the final '\0'. */
3171 name_key
= (char *) alloca (SBYTES (Vinvocation_name
)
3172 + strlen (attribute
) + 2);
3173 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
3174 + strlen (class) + 2);
3176 sprintf (name_key
, "%s.%s",
3177 SDATA (Vinvocation_name
),
3179 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
3181 return x_get_string_resource (sf
, name_key
, class_key
);
3183 #endif /* MAC_TODO */
3185 /* Types we might convert a resource string into. */
3195 /* Return the value of parameter PARAM.
3197 First search ALIST, then Vdefault_frame_alist, then the X defaults
3198 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3200 Convert the resource to the type specified by desired_type.
3202 If no default is specified, return Qunbound. If you call
3203 w32_get_arg, make sure you deal with Qunbound in a reasonable way,
3204 and don't let it get stored in any Lisp-visible variables! */
3207 mac_get_arg (alist
, param
, attribute
, class, type
)
3208 Lisp_Object alist
, param
;
3211 enum resource_types type
;
3213 register Lisp_Object tem
;
3215 tem
= Fassq (param
, alist
);
3217 tem
= Fassq (param
, Vdefault_frame_alist
);
3221 #if 0 /* MAC_TODO: search resource also */
3224 tem
= Fx_get_resource (build_string (attribute
),
3225 build_string (class),
3233 case RES_TYPE_NUMBER
:
3234 return make_number (atoi (SDATA (tem
)));
3236 case RES_TYPE_FLOAT
:
3237 return make_float (atof (SDATA (tem
)));
3239 case RES_TYPE_BOOLEAN
:
3240 tem
= Fdowncase (tem
);
3241 if (!strcmp (SDATA (tem
), "on")
3242 || !strcmp (SDATA (tem
), "true"))
3247 case RES_TYPE_STRING
:
3250 case RES_TYPE_SYMBOL
:
3251 /* As a special case, we map the values `true' and `on'
3252 to Qt, and `false' and `off' to Qnil. */
3255 lower
= Fdowncase (tem
);
3256 if (!strcmp (SDATA (lower
), "on")
3257 || !strcmp (SDATA (lower
), "true"))
3259 else if (!strcmp (SDATA (lower
), "off")
3260 || !strcmp (SDATA (lower
), "false"))
3263 return Fintern (tem
, Qnil
);
3271 #endif /* MAC_TODO */
3277 /* Record in frame F the specified or default value according to ALIST
3278 of the parameter named PROP (a Lisp symbol).
3279 If no value is specified for PROP, look for an X default for XPROP
3280 on the frame named NAME.
3281 If that is not found either, use the value DEFLT. */
3284 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
3291 enum resource_types type
;
3295 tem
= mac_get_arg (alist
, prop
, xprop
, xclass
, type
);
3296 if (EQ (tem
, Qunbound
))
3298 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
3302 /* XParseGeometry copied from w32xfns.c */
3305 * XParseGeometry parses strings of the form
3306 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
3307 * width, height, xoffset, and yoffset are unsigned integers.
3308 * Example: "=80x24+300-49"
3309 * The equal sign is optional.
3310 * It returns a bitmask that indicates which of the four values
3311 * were actually found in the string. For each value found,
3312 * the corresponding argument is updated; for each value
3313 * not found, the corresponding argument is left unchanged.
3317 read_integer (string
, NextString
)
3318 register char *string
;
3321 register int Result
= 0;
3326 else if (*string
== '-')
3331 for (; (*string
>= '0') && (*string
<= '9'); string
++)
3333 Result
= (Result
* 10) + (*string
- '0');
3335 *NextString
= string
;
3343 XParseGeometry (string
, x
, y
, width
, height
)
3346 unsigned int *width
, *height
; /* RETURN */
3349 register char *strind
;
3350 unsigned int tempWidth
, tempHeight
;
3352 char *nextCharacter
;
3354 if ((string
== NULL
) || (*string
== '\0')) return (mask
);
3356 string
++; /* ignore possible '=' at beg of geometry spec */
3358 strind
= (char *)string
;
3359 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
3361 tempWidth
= read_integer (strind
, &nextCharacter
);
3362 if (strind
== nextCharacter
)
3364 strind
= nextCharacter
;
3368 if (*strind
== 'x' || *strind
== 'X')
3371 tempHeight
= read_integer (strind
, &nextCharacter
);
3372 if (strind
== nextCharacter
)
3374 strind
= nextCharacter
;
3375 mask
|= HeightValue
;
3378 if ((*strind
== '+') || (*strind
== '-'))
3383 tempX
= -read_integer (strind
, &nextCharacter
);
3384 if (strind
== nextCharacter
)
3386 strind
= nextCharacter
;
3393 tempX
= read_integer (strind
, &nextCharacter
);
3394 if (strind
== nextCharacter
)
3396 strind
= nextCharacter
;
3399 if ((*strind
== '+') || (*strind
== '-'))
3404 tempY
= -read_integer (strind
, &nextCharacter
);
3405 if (strind
== nextCharacter
)
3407 strind
= nextCharacter
;
3414 tempY
= read_integer (strind
, &nextCharacter
);
3415 if (strind
== nextCharacter
)
3417 strind
= nextCharacter
;
3423 /* If strind isn't at the end of the string the it's an invalid
3424 geometry specification. */
3426 if (*strind
!= '\0') return (0);
3432 if (mask
& WidthValue
)
3434 if (mask
& HeightValue
)
3435 *height
= tempHeight
;
3439 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
3440 doc
: /* Parse an X-style geometry string STRING.
3441 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
3442 The properties returned may include `top', `left', `height', and `width'.
3443 The value of `left' or `top' may be an integer,
3444 or a list (+ N) meaning N pixels relative to top/left corner,
3445 or a list (- N) meaning -N pixels relative to bottom/right corner. */)
3450 unsigned int width
, height
;
3453 CHECK_STRING (string
);
3455 geometry
= XParseGeometry ((char *) SDATA (string
),
3456 &x
, &y
, &width
, &height
);
3459 if (geometry
& XValue
)
3461 Lisp_Object element
;
3463 if (x
>= 0 && (geometry
& XNegative
))
3464 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
3465 else if (x
< 0 && ! (geometry
& XNegative
))
3466 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
3468 element
= Fcons (Qleft
, make_number (x
));
3469 result
= Fcons (element
, result
);
3472 if (geometry
& YValue
)
3474 Lisp_Object element
;
3476 if (y
>= 0 && (geometry
& YNegative
))
3477 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
3478 else if (y
< 0 && ! (geometry
& YNegative
))
3479 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
3481 element
= Fcons (Qtop
, make_number (y
));
3482 result
= Fcons (element
, result
);
3485 if (geometry
& WidthValue
)
3486 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
3487 if (geometry
& HeightValue
)
3488 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
3493 /* Calculate the desired size and position of this window,
3494 and return the flags saying which aspects were specified.
3496 This function does not make the coordinates positive. */
3498 #define DEFAULT_ROWS 40
3499 #define DEFAULT_COLS 80
3502 x_figure_window_size (f
, parms
)
3506 register Lisp_Object tem0
, tem1
, tem2
;
3507 long window_prompting
= 0;
3509 /* Default values if we fall through.
3510 Actually, if that happens we should get
3511 window manager prompting. */
3512 SET_FRAME_WIDTH (f
, DEFAULT_COLS
);
3513 f
->height
= DEFAULT_ROWS
;
3514 /* Window managers expect that if program-specified
3515 positions are not (0,0), they're intentional, not defaults. */
3516 f
->output_data
.mac
->top_pos
= 0;
3517 f
->output_data
.mac
->left_pos
= 0;
3519 tem0
= mac_get_arg (parms
, Qheight
, 0, 0, RES_TYPE_NUMBER
);
3520 tem1
= mac_get_arg (parms
, Qwidth
, 0, 0, RES_TYPE_NUMBER
);
3521 tem2
= mac_get_arg (parms
, Quser_size
, 0, 0, RES_TYPE_NUMBER
);
3522 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
3524 if (!EQ (tem0
, Qunbound
))
3526 CHECK_NUMBER (tem0
);
3527 f
->height
= XINT (tem0
);
3529 if (!EQ (tem1
, Qunbound
))
3531 CHECK_NUMBER (tem1
);
3532 SET_FRAME_WIDTH (f
, XINT (tem1
));
3534 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
3535 window_prompting
|= USSize
;
3537 window_prompting
|= PSize
;
3540 f
->output_data
.mac
->vertical_scroll_bar_extra
3541 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
3543 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
3544 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
3545 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
3547 x_compute_fringe_widths (f
, 0);
3549 f
->output_data
.mac
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
3550 f
->output_data
.mac
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
3552 tem0
= mac_get_arg (parms
, Qtop
, 0, 0, RES_TYPE_NUMBER
);
3553 tem1
= mac_get_arg (parms
, Qleft
, 0, 0, RES_TYPE_NUMBER
);
3554 tem2
= mac_get_arg (parms
, Quser_position
, 0, 0, RES_TYPE_NUMBER
);
3555 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
3557 if (EQ (tem0
, Qminus
))
3559 f
->output_data
.mac
->top_pos
= 0;
3560 window_prompting
|= YNegative
;
3562 else if (CONSP (tem0
) && EQ (XCAR (tem0
), Qminus
)
3563 && CONSP (XCDR (tem0
))
3564 && INTEGERP (XCAR (XCDR (tem0
))))
3566 f
->output_data
.mac
->top_pos
= - XINT (XCAR (XCDR (tem0
)));
3567 window_prompting
|= YNegative
;
3569 else if (CONSP (tem0
) && EQ (XCAR (tem0
), Qplus
)
3570 && CONSP (XCDR (tem0
))
3571 && INTEGERP (XCAR (XCDR (tem0
))))
3573 f
->output_data
.mac
->top_pos
= XINT (XCAR (XCDR (tem0
)));
3575 else if (EQ (tem0
, Qunbound
))
3576 f
->output_data
.mac
->top_pos
= 0;
3579 CHECK_NUMBER (tem0
);
3580 f
->output_data
.mac
->top_pos
= XINT (tem0
);
3581 if (f
->output_data
.mac
->top_pos
< 0)
3582 window_prompting
|= YNegative
;
3585 if (EQ (tem1
, Qminus
))
3587 f
->output_data
.mac
->left_pos
= 0;
3588 window_prompting
|= XNegative
;
3590 else if (CONSP (tem1
) && EQ (XCAR (tem1
), Qminus
)
3591 && CONSP (XCDR (tem1
))
3592 && INTEGERP (XCAR (XCDR (tem1
))))
3594 f
->output_data
.mac
->left_pos
= - XINT (XCAR (XCDR (tem1
)));
3595 window_prompting
|= XNegative
;
3597 else if (CONSP (tem1
) && EQ (XCAR (tem1
), Qplus
)
3598 && CONSP (XCDR (tem1
))
3599 && INTEGERP (XCAR (XCDR (tem1
))))
3601 f
->output_data
.mac
->left_pos
= XINT (XCAR (XCDR (tem1
)));
3603 else if (EQ (tem1
, Qunbound
))
3604 f
->output_data
.mac
->left_pos
= 0;
3607 CHECK_NUMBER (tem1
);
3608 f
->output_data
.mac
->left_pos
= XINT (tem1
);
3609 if (f
->output_data
.mac
->left_pos
< 0)
3610 window_prompting
|= XNegative
;
3613 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
3614 window_prompting
|= USPosition
;
3616 window_prompting
|= PPosition
;
3619 return window_prompting
;
3623 #if 0 /* MAC_TODO */
3624 /* Create and set up the Mac window for frame F. */
3627 mac_window (f
, window_prompting
, minibuffer_only
)
3629 long window_prompting
;
3630 int minibuffer_only
;
3636 /* Use the resource name as the top-level window name
3637 for looking up resources. Make a non-Lisp copy
3638 for the window manager, so GC relocation won't bother it.
3640 Elsewhere we specify the window name for the window manager. */
3643 char *str
= (char *) SDATA (Vx_resource_name
);
3644 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
3645 strcpy (f
->namebuf
, str
);
3648 SetRect (&r
, f
->output_data
.mac
->left_pos
, f
->output_data
.mac
->top_pos
,
3649 f
->output_data
.mac
->left_pos
+ PIXEL_WIDTH (f
),
3650 f
->output_data
.mac
->top_pos
+ PIXEL_HEIGHT (f
));
3651 FRAME_MAC_WINDOW (f
)
3652 = NewCWindow (NULL
, &r
, "\p", 1, zoomDocProc
, (WindowPtr
) -1, 1, (long) f
->output_data
.mac
);
3654 validate_x_resource_name ();
3656 /* x_set_name normally ignores requests to set the name if the
3657 requested name is the same as the current name. This is the one
3658 place where that assumption isn't correct; f->name is set, but
3659 the server hasn't been told. */
3662 int explicit = f
->explicit_name
;
3664 f
->explicit_name
= 0;
3667 x_set_name (f
, name
, explicit);
3670 ShowWindow (FRAME_MAC_WINDOW (f
));
3674 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3675 initialize_frame_menubar (f
);
3677 if (FRAME_MAC_WINDOW (f
) == 0)
3678 error ("Unable to create window");
3680 #endif /* MAC_TODO */
3682 /* Handle the icon stuff for this window. Perhaps later we might
3683 want an x_set_icon_position which can be called interactively as
3691 Lisp_Object icon_x
, icon_y
;
3693 /* Set the position of the icon. Note that Windows 95 groups all
3694 icons in the tray. */
3695 icon_x
= mac_get_arg (parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
3696 icon_y
= mac_get_arg (parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
3697 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
3699 CHECK_NUMBER (icon_x
);
3700 CHECK_NUMBER (icon_y
);
3702 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
3703 error ("Both left and top icon corners of icon must be specified");
3707 if (! EQ (icon_x
, Qunbound
))
3708 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
3711 /* Start up iconic or window? */
3712 x_wm_set_window_state
3713 (f
, (EQ (w32_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
), Qicon
)
3717 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
3730 XGCValues gc_values
;
3734 /* Create the GC's of this frame.
3735 Note that many default values are used. */
3738 gc_values
.font
= f
->output_data
.mac
->font
;
3739 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
3740 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
3741 f
->output_data
.mac
->normal_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3742 FRAME_MAC_WINDOW (f
),
3743 GCFont
| GCForeground
| GCBackground
,
3746 /* Reverse video style. */
3747 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3748 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
3749 f
->output_data
.mac
->reverse_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3750 FRAME_MAC_WINDOW (f
),
3751 GCFont
| GCForeground
| GCBackground
,
3754 /* Cursor has cursor-color background, background-color foreground. */
3755 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3756 gc_values
.background
= f
->output_data
.mac
->cursor_pixel
;
3757 f
->output_data
.mac
->cursor_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3758 FRAME_MAC_WINDOW (f
),
3759 GCFont
| GCForeground
| GCBackground
,
3763 f
->output_data
.mac
->white_relief
.gc
= 0;
3764 f
->output_data
.mac
->black_relief
.gc
= 0;
3770 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3772 doc
: /* Make a new window, which is called a \"frame\" in Emacs terms.
3773 Returns an Emacs frame object.
3774 ALIST is an alist of frame parameters.
3775 If the parameters specify that the frame should not have a minibuffer,
3776 and do not specify a specific minibuffer window to use,
3777 then `default-minibuffer-frame' must be a frame whose minibuffer can
3778 be shared by the new frame.
3780 This function is an internal primitive--use `make-frame' instead. */)
3785 Lisp_Object frame
, tem
;
3787 int minibuffer_only
= 0;
3788 long window_prompting
= 0;
3790 int count
= SPECPDL_INDEX ();
3791 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3792 Lisp_Object display
;
3793 struct mac_display_info
*dpyinfo
= NULL
;
3796 char x_frame_name
[10];
3797 static int x_frame_count
= 2; /* begins at 2 because terminal frame is F1 */
3801 /* Use this general default value to start with
3802 until we know if this frame has a specified name. */
3803 Vx_resource_name
= Vinvocation_name
;
3805 display
= mac_get_arg (parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3806 if (EQ (display
, Qunbound
))
3808 dpyinfo
= check_x_display_info (display
);
3810 kb
= dpyinfo
->kboard
;
3812 kb
= &the_only_kboard
;
3815 name
= mac_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3817 && ! EQ (name
, Qunbound
)
3819 error ("Invalid frame name--not a string or nil");
3822 Vx_resource_name
= name
;
3824 /* See if parent window is specified. */
3825 parent
= mac_get_arg (parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3826 if (EQ (parent
, Qunbound
))
3828 if (! NILP (parent
))
3829 CHECK_NUMBER (parent
);
3831 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3832 /* No need to protect DISPLAY because that's not used after passing
3833 it to make_frame_without_minibuffer. */
3835 GCPRO4 (parms
, parent
, name
, frame
);
3836 tem
= mac_get_arg (parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3838 if (EQ (tem
, Qnone
) || NILP (tem
))
3839 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3840 else if (EQ (tem
, Qonly
))
3842 f
= make_minibuffer_frame ();
3843 minibuffer_only
= 1;
3845 else if (WINDOWP (tem
))
3846 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3850 if (EQ (name
, Qunbound
) || NILP (name
))
3852 sprintf (x_frame_name
, "F%d", x_frame_count
++);
3853 f
->name
= build_string (x_frame_name
);
3854 f
->explicit_name
= 0;
3859 f
->explicit_name
= 1;
3862 XSETFRAME (frame
, f
);
3864 /* Note that X Windows does support scroll bars. */
3865 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3867 f
->output_method
= output_mac
;
3868 f
->output_data
.mac
= (struct mac_output
*) xmalloc (sizeof (struct mac_output
));
3869 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
3870 FRAME_FONTSET (f
) = -1;
3871 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
3872 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
3875 FRAME_FONTSET (f
) = -1;
3879 = mac_get_arg (parms
, Qicon_name
, "iconName", "Title", RES_TYPE_STRING
);
3880 if (! STRINGP (f
->icon_name
))
3881 f
->icon_name
= Qnil
;
3883 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
3885 FRAME_KBOARD (f
) = kb
;
3888 /* Specify the parent under which to make this window. */
3892 f
->output_data
.mac
->parent_desc
= (Window
) parent
;
3893 f
->output_data
.mac
->explicit_parent
= 1;
3897 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
3898 f
->output_data
.mac
->explicit_parent
= 0;
3901 /* Set the name; the functions to which we pass f expect the name to
3903 if (EQ (name
, Qunbound
) || NILP (name
))
3905 f
->name
= build_string (dpyinfo
->mac_id_name
);
3906 f
->explicit_name
= 0;
3911 f
->explicit_name
= 1;
3912 /* use the frame's title when getting resources for this frame. */
3913 specbind (Qx_resource_name
, name
);
3916 /* Extract the window parameters from the supplied values
3917 that are needed to determine window geometry. */
3921 font
= mac_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3924 /* First, try whatever font the caller has specified. */
3927 tem
= Fquery_fontset (font
, Qnil
);
3929 font
= x_new_fontset (f
, SDATA (tem
));
3931 font
= x_new_font (f
, SDATA (font
));
3933 /* Try out a font which we hope has bold and italic variations. */
3934 if (! STRINGP (font
))
3935 font
= x_new_font (f
, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
3936 /* If those didn't work, look for something which will at least work. */
3937 if (!STRINGP (font
))
3938 font
= x_new_font (f
, "-*-monaco-*-12-*-mac-roman");
3939 if (! STRINGP (font
))
3940 font
= x_new_font (f
, "-*-courier-*-10-*-mac-roman");
3941 if (! STRINGP (font
))
3942 error ("Cannot find any usable font");
3945 x_default_parameter (f
, parms
, Qfont
, font
,
3946 "font", "Font", RES_TYPE_STRING
);
3949 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
3950 "borderwidth", "BorderWidth", RES_TYPE_NUMBER
);
3951 /* This defaults to 2 in order to match xterm. We recognize either
3952 internalBorderWidth or internalBorder (which is what xterm calls
3954 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3958 value
= mac_get_arg (parms
, Qinternal_border_width
,
3959 "internalBorder", "InternalBorder", RES_TYPE_NUMBER
);
3960 if (! EQ (value
, Qunbound
))
3961 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3964 /* Default internalBorderWidth to 0 on Windows to match other programs. */
3965 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (0),
3966 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER
);
3967 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qright
,
3968 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL
);
3970 /* Also do the stuff which must be set before the window exists. */
3971 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3972 "foreground", "Foreground", RES_TYPE_STRING
);
3973 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3974 "background", "Background", RES_TYPE_STRING
);
3975 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3976 "pointerColor", "Foreground", RES_TYPE_STRING
);
3977 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3978 "cursorColor", "Foreground", RES_TYPE_STRING
);
3979 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3980 "borderColor", "BorderColor", RES_TYPE_STRING
);
3981 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3982 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3983 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3984 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3985 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3986 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3987 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3988 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3991 /* Init faces before x_default_parameter is called for scroll-bar
3992 parameters because that function calls x_set_scroll_bar_width,
3993 which calls change_frame_size, which calls Fset_window_buffer,
3994 which runs hooks, which call Fvertical_motion. At the end, we
3995 end up in init_iterator with a null face cache, which should not
3997 init_frame_faces (f
);
3999 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
4000 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
4001 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (0),
4002 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
4003 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
4004 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL
);
4005 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
4006 "title", "Title", RES_TYPE_STRING
);
4008 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
4009 window_prompting
= x_figure_window_size (f
, parms
);
4011 if (window_prompting
& XNegative
)
4013 if (window_prompting
& YNegative
)
4014 f
->output_data
.mac
->win_gravity
= SouthEastGravity
;
4016 f
->output_data
.mac
->win_gravity
= NorthEastGravity
;
4020 if (window_prompting
& YNegative
)
4021 f
->output_data
.mac
->win_gravity
= SouthWestGravity
;
4023 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
4026 f
->output_data
.mac
->size_hint_flags
= window_prompting
;
4028 tem
= mac_get_arg (parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
4029 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
4031 /* Create the window. Add the tool-bar height to the initial frame
4032 height so that the user gets a text display area of the size he
4033 specified with -g or via the registry. Later changes of the
4034 tool-bar height don't change the frame size. This is done so that
4035 users can create tall Emacs frames without having to guess how
4036 tall the tool-bar will get. */
4037 f
->height
+= FRAME_TOOL_BAR_LINES (f
);
4039 /* mac_window (f, window_prompting, minibuffer_only); */
4046 /* Now consider the frame official. */
4047 FRAME_MAC_DISPLAY_INFO (f
)->reference_count
++;
4048 Vframe_list
= Fcons (frame
, Vframe_list
);
4050 /* We need to do this after creating the window, so that the
4051 icon-creation functions can say whose icon they're describing. */
4052 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
4053 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
4055 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
4056 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4057 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
4058 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4059 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
4060 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
4061 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
4062 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER
);
4064 /* Dimensions, especially f->height, must be done via change_frame_size.
4065 Change will not be effected unless different from the current
4071 SET_FRAME_WIDTH (f
, 0);
4072 change_frame_size (f
, height
, width
, 1, 0, 0);
4074 /* Set up faces after all frame parameters are known. */
4075 call1 (Qface_set_after_frame_default
, frame
);
4077 #if 0 /* MAC_TODO: when we have window manager hints */
4078 /* Tell the server what size and position, etc, we want, and how
4079 badly we want them. This should be done after we have the menu
4080 bar so that its size can be taken into account. */
4082 x_wm_set_size_hint (f
, window_prompting
, 0);
4086 /* Make the window appear on the frame and enable display, unless
4087 the caller says not to. However, with explicit parent, Emacs
4088 cannot control visibility, so don't try. */
4089 if (! f
->output_data
.mac
->explicit_parent
)
4091 Lisp_Object visibility
;
4093 visibility
= mac_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
);
4094 if (EQ (visibility
, Qunbound
))
4097 #if 0 /* MAC_TODO: really no iconify on Mac */
4098 if (EQ (visibility
, Qicon
))
4099 x_iconify_frame (f
);
4102 if (! NILP (visibility
))
4103 x_make_frame_visible (f
);
4105 /* Must have been Qnil. */
4110 /* Make sure windows on this frame appear in calls to next-window
4111 and similar functions. */
4112 Vwindow_list
= Qnil
;
4114 return unbind_to (count
, frame
);
4117 /* FRAME is used only to get a handle on the X display. We don't pass the
4118 display info directly because we're called from frame.c, which doesn't
4119 know about that structure. */
4121 x_get_focus_frame (frame
)
4122 struct frame
*frame
;
4124 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
4126 if (! dpyinfo
->x_focus_frame
)
4129 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
4133 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
4134 doc
: /* Internal function called by `color-defined-p', which see. */)
4136 Lisp_Object color
, frame
;
4139 FRAME_PTR f
= check_x_frame (frame
);
4141 CHECK_STRING (color
);
4143 if (mac_defined_color (f
, SDATA (color
), &foo
, 0))
4149 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
4150 doc
: /* Internal function called by `color-values', which see. */)
4152 Lisp_Object color
, frame
;
4155 FRAME_PTR f
= check_x_frame (frame
);
4157 CHECK_STRING (color
);
4159 if (mac_defined_color (f
, SDATA (color
), &foo
, 0))
4163 rgb
[0] = make_number ((RED_FROM_ULONG (foo
.pixel
) << 8)
4164 | RED_FROM_ULONG (foo
.pixel
));
4165 rgb
[1] = make_number ((GREEN_FROM_ULONG (foo
.pixel
) << 8)
4166 | GREEN_FROM_ULONG (foo
.pixel
));
4167 rgb
[2] = make_number ((BLUE_FROM_ULONG (foo
.pixel
) << 8)
4168 | BLUE_FROM_ULONG (foo
.pixel
));
4169 return Flist (3, rgb
);
4175 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
4176 doc
: /* Internal function called by `display-color-p', which see. */)
4178 Lisp_Object display
;
4180 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4182 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 2)
4188 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
4190 doc
: /* Return t if the X display supports shades of gray.
4191 Note that color displays do support shades of gray.
4192 The optional argument DISPLAY specifies which display to ask about.
4193 DISPLAY should be either a frame or a display name (a string).
4194 If omitted or nil, that stands for the selected frame's display. */)
4196 Lisp_Object display
;
4198 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4200 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 1)
4206 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
4208 doc
: /* Returns the width in pixels of the X display DISPLAY.
4209 The optional argument DISPLAY specifies which display to ask about.
4210 DISPLAY should be either a frame or a display name (a string).
4211 If omitted or nil, that stands for the selected frame's display. */)
4213 Lisp_Object display
;
4215 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4217 return make_number (dpyinfo
->width
);
4220 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
4221 Sx_display_pixel_height
, 0, 1, 0,
4222 doc
: /* Returns the height in pixels of the X display DISPLAY.
4223 The optional argument DISPLAY specifies which display to ask about.
4224 DISPLAY should be either a frame or a display name (a string).
4225 If omitted or nil, that stands for the selected frame's display. */)
4227 Lisp_Object display
;
4229 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4231 return make_number (dpyinfo
->height
);
4234 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
4236 doc
: /* Returns the number of bitplanes of the display DISPLAY.
4237 The optional argument DISPLAY specifies which display to ask about.
4238 DISPLAY should be either a frame or a display name (a string).
4239 If omitted or nil, that stands for the selected frame's display. */)
4241 Lisp_Object display
;
4243 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4245 return make_number (dpyinfo
->n_planes
* dpyinfo
->n_cbits
);
4248 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
4250 doc
: /* Returns the number of color cells of the display DISPLAY.
4251 The optional argument DISPLAY specifies which display to ask about.
4252 DISPLAY should be either a frame or a display name (a string).
4253 If omitted or nil, that stands for the selected frame's display. */)
4255 Lisp_Object display
;
4257 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4259 /* MAC_TODO: check whether this is right */
4260 return make_number ((unsigned long) (pow (2, dpyinfo
->n_cbits
)));
4263 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
4264 Sx_server_max_request_size
,
4266 doc
: /* Returns the maximum request size of the server of display DISPLAY.
4267 The optional argument DISPLAY specifies which display to ask about.
4268 DISPLAY should be either a frame or a display name (a string).
4269 If omitted or nil, that stands for the selected frame's display. */)
4271 Lisp_Object display
;
4273 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4275 return make_number (1);
4278 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
4279 doc
: /* Returns the vendor ID string of the Mac OS system (Apple).
4280 The optional argument DISPLAY specifies which display to ask about.
4281 DISPLAY should be either a frame or a display name (a string).
4282 If omitted or nil, that stands for the selected frame's display. */)
4284 Lisp_Object display
;
4286 return build_string ("Apple Computers");
4289 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
4290 doc
: /* Returns the version numbers of the server of display DISPLAY.
4291 The value is a list of three integers: the major and minor
4292 version numbers, and the vendor-specific release
4293 number. See also the function `x-server-vendor'.
4295 The optional argument DISPLAY specifies which display to ask about.
4296 DISPLAY should be either a frame or a display name (a string).
4297 If omitted or nil, that stands for the selected frame's display. */)
4299 Lisp_Object display
;
4301 int mac_major_version
, mac_minor_version
;
4304 if (Gestalt (gestaltSystemVersion
, &response
) != noErr
)
4305 error ("Cannot get Mac OS version");
4307 mac_major_version
= (response
>> 8) & 0xf;
4308 mac_minor_version
= (response
>> 4) & 0xf;
4310 return Fcons (make_number (mac_major_version
),
4311 Fcons (make_number (mac_minor_version
), Qnil
));
4314 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
4315 doc
: /* Return the number of screens on the server of display DISPLAY.
4316 The optional argument DISPLAY specifies which display to ask about.
4317 DISPLAY should be either a frame or a display name (a string).
4318 If omitted or nil, that stands for the selected frame's display. */)
4320 Lisp_Object display
;
4322 return make_number (1);
4325 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
4326 doc
: /* Return the height in millimeters of the X display DISPLAY.
4327 The optional argument DISPLAY specifies which display to ask about.
4328 DISPLAY should be either a frame or a display name (a string).
4329 If omitted or nil, that stands for the selected frame's display. */)
4331 Lisp_Object display
;
4333 /* MAC_TODO: this is an approximation, and only of the main display */
4335 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4340 return make_number ((int) (v
/ 72.0 * 25.4));
4343 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
4344 doc
: /* Return the width in millimeters of the X display DISPLAY.
4345 The optional argument DISPLAY specifies which display to ask about.
4346 DISPLAY should be either a frame or a display name (a string).
4347 If omitted or nil, that stands for the selected frame's display. */)
4349 Lisp_Object display
;
4351 /* MAC_TODO: this is an approximation, and only of the main display */
4353 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4358 return make_number ((int) (h
/ 72.0 * 25.4));
4361 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
4362 Sx_display_backing_store
, 0, 1, 0,
4363 doc
: /* Returns an indication of whether display DISPLAY does backing store.
4364 The value may be `always', `when-mapped', or `not-useful'.
4365 The optional argument DISPLAY specifies which display to ask about.
4366 DISPLAY should be either a frame or a display name (a string).
4367 If omitted or nil, that stands for the selected frame's display. */)
4369 Lisp_Object display
;
4371 return intern ("not-useful");
4374 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
4375 Sx_display_visual_class
, 0, 1, 0,
4376 doc
: /* Returns the visual class of the display DISPLAY.
4377 The value is one of the symbols `static-gray', `gray-scale',
4378 `static-color', `pseudo-color', `true-color', or `direct-color'.
4380 The optional argument DISPLAY specifies which display to ask about.
4381 DISPLAY should be either a frame or a display name (a string).
4382 If omitted or nil, that stands for the selected frame's display. */)
4384 Lisp_Object display
;
4386 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4389 switch (dpyinfo
->visual
->class)
4391 case StaticGray
: return (intern ("static-gray"));
4392 case GrayScale
: return (intern ("gray-scale"));
4393 case StaticColor
: return (intern ("static-color"));
4394 case PseudoColor
: return (intern ("pseudo-color"));
4395 case TrueColor
: return (intern ("true-color"));
4396 case DirectColor
: return (intern ("direct-color"));
4398 error ("Display has an unknown visual class");
4402 return (intern ("true-color"));
4405 DEFUN ("x-display-save-under", Fx_display_save_under
,
4406 Sx_display_save_under
, 0, 1, 0,
4407 doc
: /* Returns t if the display DISPLAY supports the save-under feature.
4408 The optional argument DISPLAY specifies which display to ask about.
4409 DISPLAY should be either a frame or a display name (a string).
4410 If omitted or nil, that stands for the selected frame's display. */)
4412 Lisp_Object display
;
4419 register struct frame
*f
;
4421 return PIXEL_WIDTH (f
);
4426 register struct frame
*f
;
4428 return PIXEL_HEIGHT (f
);
4433 register struct frame
*f
;
4435 return FONT_WIDTH (f
->output_data
.mac
->font
);
4440 register struct frame
*f
;
4442 return f
->output_data
.mac
->line_height
;
4447 register struct frame
*f
;
4449 return FRAME_MAC_DISPLAY_INFO (f
)->n_planes
;
4452 /* Return the display structure for the display named NAME.
4453 Open a new connection if necessary. */
4455 struct mac_display_info
*
4456 x_display_info_for_name (name
)
4460 struct mac_display_info
*dpyinfo
;
4462 CHECK_STRING (name
);
4464 for (dpyinfo
= &one_mac_display_info
, names
= x_display_name_list
;
4466 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4469 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4474 /* Use this general default value to start with. */
4475 Vx_resource_name
= Vinvocation_name
;
4477 validate_x_resource_name ();
4479 dpyinfo
= mac_term_init (name
, (unsigned char *) 0,
4480 (char *) SDATA (Vx_resource_name
));
4483 error ("Cannot connect to server %s", SDATA (name
));
4486 XSETFASTINT (Vwindow_system_version
, 3);
4491 #if 0 /* MAC_TODO: implement network support */
4492 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4494 doc
: /* Open a connection to a server.
4495 DISPLAY is the name of the display to connect to.
4496 Optional second arg XRM-STRING is a string of resources in xrdb format.
4497 If the optional third arg MUST-SUCCEED is non-nil,
4498 terminate Emacs if we can't open the connection. */)
4499 (display
, xrm_string
, must_succeed
)
4500 Lisp_Object display
, xrm_string
, must_succeed
;
4502 unsigned char *xrm_option
;
4503 struct mac_display_info
*dpyinfo
;
4505 CHECK_STRING (display
);
4506 if (! NILP (xrm_string
))
4507 CHECK_STRING (xrm_string
);
4509 if (! EQ (Vwindow_system
, intern ("mac")))
4510 error ("Not using Mac OS");
4512 if (! NILP (xrm_string
))
4513 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4515 xrm_option
= (unsigned char *) 0;
4517 validate_x_resource_name ();
4519 /* This is what opens the connection and sets x_current_display.
4520 This also initializes many symbols, such as those used for input. */
4521 dpyinfo
= mac_term_init (display
, xrm_option
,
4522 (char *) SDATA (Vx_resource_name
));
4526 if (!NILP (must_succeed
))
4527 fatal ("Cannot connect to server %s.\n",
4530 error ("Cannot connect to server %s", SDATA (display
));
4535 XSETFASTINT (Vwindow_system_version
, 3);
4539 DEFUN ("x-close-connection", Fx_close_connection
,
4540 Sx_close_connection
, 1, 1, 0,
4541 doc
: /* Close the connection to DISPLAY's server.
4542 For DISPLAY, specify either a frame or a display name (a string).
4543 If DISPLAY is nil, that stands for the selected frame's display. */)
4545 Lisp_Object display
;
4547 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4550 if (dpyinfo
->reference_count
> 0)
4551 error ("Display still has frames on it");
4554 /* Free the fonts in the font table. */
4555 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4556 if (dpyinfo
->font_table
[i
].name
)
4558 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
4559 xfree (dpyinfo
->font_table
[i
].full_name
);
4560 xfree (dpyinfo
->font_table
[i
].name
);
4561 x_unload_font (dpyinfo
, dpyinfo
->font_table
[i
].font
);
4563 x_destroy_all_bitmaps (dpyinfo
);
4565 x_delete_display (dpyinfo
);
4572 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4573 doc
: /* Return the list of display names that Emacs has connections to. */)
4576 Lisp_Object tail
, result
;
4579 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4580 result
= Fcons (XCAR (XCAR (tail
)), result
);
4585 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4586 doc
: /* If ON is non-nil, report errors as soon as the erring request is made.
4587 If ON is nil, allow buffering of requests.
4588 This is a noop on Mac OS systems.
4589 The optional second argument DISPLAY specifies which display to act on.
4590 DISPLAY should be either a frame or a display name (a string).
4591 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4593 Lisp_Object display
, on
;
4599 /***********************************************************************
4601 ***********************************************************************/
4603 /* Value is the number of elements of vector VECTOR. */
4605 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4607 /* List of supported image types. Use define_image_type to add new
4608 types. Use lookup_image_type to find a type for a given symbol. */
4610 static struct image_type
*image_types
;
4612 /* The symbol `image' which is the car of the lists used to represent
4615 extern Lisp_Object Qimage
;
4617 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4623 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4624 extern Lisp_Object QCdata
, QCtype
;
4625 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4626 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4627 Lisp_Object QCindex
;
4629 /* Other symbols. */
4631 Lisp_Object Qlaplace
;
4633 /* Time in seconds after which images should be removed from the cache
4634 if not displayed. */
4636 Lisp_Object Vimage_cache_eviction_delay
;
4638 /* Function prototypes. */
4640 static void define_image_type
P_ ((struct image_type
*type
));
4641 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4642 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4643 static void x_laplace
P_ ((struct frame
*, struct image
*));
4644 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4648 /* Define a new image type from TYPE. This adds a copy of TYPE to
4649 image_types and adds the symbol *TYPE->type to Vimage_types. */
4652 define_image_type (type
)
4653 struct image_type
*type
;
4655 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4656 The initialized data segment is read-only. */
4657 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4658 bcopy (type
, p
, sizeof *p
);
4659 p
->next
= image_types
;
4661 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4665 /* Look up image type SYMBOL, and return a pointer to its image_type
4666 structure. Value is null if SYMBOL is not a known image type. */
4668 static INLINE
struct image_type
*
4669 lookup_image_type (symbol
)
4672 struct image_type
*type
;
4674 for (type
= image_types
; type
; type
= type
->next
)
4675 if (EQ (symbol
, *type
->type
))
4682 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4683 valid image specification is a list whose car is the symbol
4684 `image', and whose rest is a property list. The property list must
4685 contain a value for key `:type'. That value must be the name of a
4686 supported image type. The rest of the property list depends on the
4690 valid_image_p (object
)
4695 if (CONSP (object
) && EQ (XCAR (object
), Qimage
))
4697 Lisp_Object symbol
= Fplist_get (XCDR (object
), QCtype
);
4698 struct image_type
*type
= lookup_image_type (symbol
);
4701 valid_p
= type
->valid_p (object
);
4708 /* Log error message with format string FORMAT and argument ARG.
4709 Signaling an error, e.g. when an image cannot be loaded, is not a
4710 good idea because this would interrupt redisplay, and the error
4711 message display would lead to another redisplay. This function
4712 therefore simply displays a message. */
4715 image_error (format
, arg1
, arg2
)
4717 Lisp_Object arg1
, arg2
;
4719 add_to_log (format
, arg1
, arg2
);
4724 /***********************************************************************
4725 Image specifications
4726 ***********************************************************************/
4728 enum image_value_type
4730 IMAGE_DONT_CHECK_VALUE_TYPE
,
4733 IMAGE_POSITIVE_INTEGER_VALUE
,
4734 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4735 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4737 IMAGE_INTEGER_VALUE
,
4738 IMAGE_FUNCTION_VALUE
,
4743 /* Structure used when parsing image specifications. */
4745 struct image_keyword
4747 /* Name of keyword. */
4750 /* The type of value allowed. */
4751 enum image_value_type type
;
4753 /* Non-zero means key must be present. */
4756 /* Used to recognize duplicate keywords in a property list. */
4759 /* The value that was found. */
4764 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4766 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4769 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4770 has the format (image KEYWORD VALUE ...). One of the keyword/
4771 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4772 image_keywords structures of size NKEYWORDS describing other
4773 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4776 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4778 struct image_keyword
*keywords
;
4785 if (!CONSP (spec
) || !EQ (XCAR (spec
), Qimage
))
4788 plist
= XCDR (spec
);
4789 while (CONSP (plist
))
4791 Lisp_Object key
, value
;
4793 /* First element of a pair must be a symbol. */
4795 plist
= XCDR (plist
);
4799 /* There must follow a value. */
4802 value
= XCAR (plist
);
4803 plist
= XCDR (plist
);
4805 /* Find key in KEYWORDS. Error if not found. */
4806 for (i
= 0; i
< nkeywords
; ++i
)
4807 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
4813 /* Record that we recognized the keyword. If a keywords
4814 was found more than once, it's an error. */
4815 keywords
[i
].value
= value
;
4816 ++keywords
[i
].count
;
4818 if (keywords
[i
].count
> 1)
4821 /* Check type of value against allowed type. */
4822 switch (keywords
[i
].type
)
4824 case IMAGE_STRING_VALUE
:
4825 if (!STRINGP (value
))
4829 case IMAGE_SYMBOL_VALUE
:
4830 if (!SYMBOLP (value
))
4834 case IMAGE_POSITIVE_INTEGER_VALUE
:
4835 if (!INTEGERP (value
) || XINT (value
) <= 0)
4839 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4840 if (INTEGERP (value
) && XINT (value
) >= 0)
4843 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4844 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4848 case IMAGE_ASCENT_VALUE
:
4849 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4851 else if (INTEGERP (value
)
4852 && XINT (value
) >= 0
4853 && XINT (value
) <= 100)
4857 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4858 if (!INTEGERP (value
) || XINT (value
) < 0)
4862 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4865 case IMAGE_FUNCTION_VALUE
:
4866 value
= indirect_function (value
);
4868 || COMPILEDP (value
)
4869 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4873 case IMAGE_NUMBER_VALUE
:
4874 if (!INTEGERP (value
) && !FLOATP (value
))
4878 case IMAGE_INTEGER_VALUE
:
4879 if (!INTEGERP (value
))
4883 case IMAGE_BOOL_VALUE
:
4884 if (!NILP (value
) && !EQ (value
, Qt
))
4893 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4897 /* Check that all mandatory fields are present. */
4898 for (i
= 0; i
< nkeywords
; ++i
)
4899 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4902 return NILP (plist
);
4906 /* Return the value of KEY in image specification SPEC. Value is nil
4907 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4908 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4911 image_spec_value (spec
, key
, found
)
4912 Lisp_Object spec
, key
;
4917 xassert (valid_image_p (spec
));
4919 for (tail
= XCDR (spec
);
4920 CONSP (tail
) && CONSP (XCDR (tail
));
4921 tail
= XCDR (XCDR (tail
)))
4923 if (EQ (XCAR (tail
), key
))
4927 return XCAR (XCDR (tail
));
4939 /***********************************************************************
4940 Image type independent image structures
4941 ***********************************************************************/
4943 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4944 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4947 /* Allocate and return a new image structure for image specification
4948 SPEC. SPEC has a hash value of HASH. */
4950 static struct image
*
4951 make_image (spec
, hash
)
4955 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4957 xassert (valid_image_p (spec
));
4958 bzero (img
, sizeof *img
);
4959 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4960 xassert (img
->type
!= NULL
);
4962 img
->data
.lisp_val
= Qnil
;
4963 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
4969 /* Free image IMG which was used on frame F, including its resources. */
4978 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4980 /* Remove IMG from the hash table of its cache. */
4982 img
->prev
->next
= img
->next
;
4984 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
4987 img
->next
->prev
= img
->prev
;
4989 c
->images
[img
->id
] = NULL
;
4991 /* Free resources, then free IMG. */
4992 img
->type
->free (f
, img
);
4998 /* Prepare image IMG for display on frame F. Must be called before
4999 drawing an image. */
5002 prepare_image_for_display (f
, img
)
5008 /* We're about to display IMG, so set its timestamp to `now'. */
5010 img
->timestamp
= EMACS_SECS (t
);
5012 /* If IMG doesn't have a pixmap yet, load it now, using the image
5013 type dependent loader function. */
5014 if (img
->pixmap
== 0 && !img
->load_failed_p
)
5015 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5019 /* Value is the number of pixels for the ascent of image IMG when
5020 drawn in face FACE. */
5023 image_ascent (img
, face
)
5027 int height
= img
->height
+ img
->vmargin
;
5030 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
5033 ascent
= height
/ 2 - (FONT_DESCENT(face
->font
)
5034 - FONT_BASE(face
->font
)) / 2;
5036 ascent
= height
/ 2;
5039 ascent
= height
* img
->ascent
/ 100.0;
5046 /***********************************************************************
5047 Helper functions for X image types
5048 ***********************************************************************/
5050 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
5051 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
5053 Lisp_Object color_name
,
5054 unsigned long dflt
));
5056 /* Free X resources of image IMG which is used on frame F. */
5059 x_clear_image (f
, img
)
5063 #if 0 /* MAC_TODO: W32 image support */
5068 XFreePixmap (NULL
, img
->pixmap
);
5075 int class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
5077 /* If display has an immutable color map, freeing colors is not
5078 necessary and some servers don't allow it. So don't do it. */
5079 if (class != StaticColor
5080 && class != StaticGray
5081 && class != TrueColor
)
5085 cmap
= DefaultColormapOfScreen (FRAME_W32_DISPLAY_INFO (f
)->screen
);
5086 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
, img
->colors
,
5091 xfree (img
->colors
);
5095 #endif /* MAC_TODO */
5099 /* Allocate color COLOR_NAME for image IMG on frame F. If color
5100 cannot be allocated, use DFLT. Add a newly allocated color to
5101 IMG->colors, so that it can be freed again. Value is the pixel
5104 static unsigned long
5105 x_alloc_image_color (f
, img
, color_name
, dflt
)
5108 Lisp_Object color_name
;
5111 #if 0 /* MAC_TODO: allocing colors. */
5113 unsigned long result
;
5115 xassert (STRINGP (color_name
));
5117 if (w32_defined_color (f
, SDATA (color_name
), &color
, 1))
5119 /* This isn't called frequently so we get away with simply
5120 reallocating the color vector to the needed size, here. */
5123 (unsigned long *) xrealloc (img
->colors
,
5124 img
->ncolors
* sizeof *img
->colors
);
5125 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
5126 result
= color
.pixel
;
5131 #endif /* MAC_TODO */
5137 /***********************************************************************
5139 ***********************************************************************/
5141 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
5144 /* Return a new, initialized image cache that is allocated from the
5145 heap. Call free_image_cache to free an image cache. */
5147 struct image_cache
*
5150 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
5153 bzero (c
, sizeof *c
);
5155 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
5156 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
5157 c
->buckets
= (struct image
**) xmalloc (size
);
5158 bzero (c
->buckets
, size
);
5163 /* Free image cache of frame F. Be aware that X frames share images
5167 free_image_cache (f
)
5170 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5175 /* Cache should not be referenced by any frame when freed. */
5176 xassert (c
->refcount
== 0);
5178 for (i
= 0; i
< c
->used
; ++i
)
5179 free_image (f
, c
->images
[i
]);
5183 FRAME_X_IMAGE_CACHE (f
) = NULL
;
5188 /* Clear image cache of frame F. FORCE_P non-zero means free all
5189 images. FORCE_P zero means clear only images that haven't been
5190 displayed for some time. Should be called from time to time to
5191 reduce the number of loaded images. If image-eviction-seconds is
5192 non-nil, this frees images in the cache which weren't displayed for
5193 at least that many seconds. */
5196 clear_image_cache (f
, force_p
)
5200 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5202 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
5206 int i
, any_freed_p
= 0;
5209 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
5211 for (i
= 0; i
< c
->used
; ++i
)
5213 struct image
*img
= c
->images
[i
];
5216 || (img
->timestamp
> old
)))
5218 free_image (f
, img
);
5223 /* We may be clearing the image cache because, for example,
5224 Emacs was iconified for a longer period of time. In that
5225 case, current matrices may still contain references to
5226 images freed above. So, clear these matrices. */
5229 clear_current_matrices (f
);
5230 ++windows_or_buffers_changed
;
5236 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
5238 doc
: /* Clear the image cache of FRAME.
5239 FRAME nil or omitted means use the selected frame.
5240 FRAME t means clear the image caches of all frames. */)
5248 FOR_EACH_FRAME (tail
, frame
)
5249 if (FRAME_MAC_P (XFRAME (frame
)))
5250 clear_image_cache (XFRAME (frame
), 1);
5253 clear_image_cache (check_x_frame (frame
), 1);
5259 /* Return the id of image with Lisp specification SPEC on frame F.
5260 SPEC must be a valid Lisp image specification (see valid_image_p). */
5263 lookup_image (f
, spec
)
5267 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5271 struct gcpro gcpro1
;
5274 /* F must be a window-system frame, and SPEC must be a valid image
5276 xassert (FRAME_WINDOW_P (f
));
5277 xassert (valid_image_p (spec
));
5281 /* Look up SPEC in the hash table of the image cache. */
5282 hash
= sxhash (spec
, 0);
5283 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5285 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5286 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5289 /* If not found, create a new image and cache it. */
5293 img
= make_image (spec
, hash
);
5294 cache_image (f
, img
);
5295 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5296 xassert (!interrupt_input_blocked
);
5298 /* If we can't load the image, and we don't have a width and
5299 height, use some arbitrary width and height so that we can
5300 draw a rectangle for it. */
5301 if (img
->load_failed_p
)
5305 value
= image_spec_value (spec
, QCwidth
, NULL
);
5306 img
->width
= (INTEGERP (value
)
5307 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5308 value
= image_spec_value (spec
, QCheight
, NULL
);
5309 img
->height
= (INTEGERP (value
)
5310 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5314 /* Handle image type independent image attributes
5315 `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF'. */
5316 Lisp_Object ascent
, margin
, relief
;
5318 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5319 if (INTEGERP (ascent
))
5320 img
->ascent
= XFASTINT (ascent
);
5321 else if (EQ (ascent
, Qcenter
))
5322 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5324 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5325 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5326 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5327 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5328 && INTEGERP (XCDR (margin
)))
5330 if (XINT (XCAR (margin
)) > 0)
5331 img
->hmargin
= XFASTINT (XCAR (margin
));
5332 if (XINT (XCDR (margin
)) > 0)
5333 img
->vmargin
= XFASTINT (XCDR (margin
));
5336 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5337 if (INTEGERP (relief
))
5339 img
->relief
= XINT (relief
);
5340 img
->hmargin
+= abs (img
->relief
);
5341 img
->vmargin
+= abs (img
->relief
);
5346 /* We're using IMG, so set its timestamp to `now'. */
5347 EMACS_GET_TIME (now
);
5348 img
->timestamp
= EMACS_SECS (now
);
5352 /* Value is the image id. */
5357 /* Cache image IMG in the image cache of frame F. */
5360 cache_image (f
, img
)
5364 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5367 /* Find a free slot in c->images. */
5368 for (i
= 0; i
< c
->used
; ++i
)
5369 if (c
->images
[i
] == NULL
)
5372 /* If no free slot found, maybe enlarge c->images. */
5373 if (i
== c
->used
&& c
->used
== c
->size
)
5376 c
->images
= (struct image
**) xrealloc (c
->images
,
5377 c
->size
* sizeof *c
->images
);
5380 /* Add IMG to c->images, and assign IMG an id. */
5386 /* Add IMG to the cache's hash table. */
5387 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5388 img
->next
= c
->buckets
[i
];
5390 img
->next
->prev
= img
;
5392 c
->buckets
[i
] = img
;
5396 /* Call FN on every image in the image cache of frame F. Used to mark
5397 Lisp Objects in the image cache. */
5400 forall_images_in_image_cache (f
, fn
)
5402 void (*fn
) P_ ((struct image
*img
));
5404 if (FRAME_LIVE_P (f
) && FRAME_MAC_P (f
))
5406 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5410 for (i
= 0; i
< c
->used
; ++i
)
5419 /***********************************************************************
5421 ***********************************************************************/
5423 #if 0 /* MAC_TODO: Mac specific image code. */
5425 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5426 XImage
**, Pixmap
*));
5427 static void x_destroy_x_image
P_ ((XImage
*));
5428 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5431 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5432 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5433 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5434 via xmalloc. Print error messages via image_error if an error
5435 occurs. Value is non-zero if successful. */
5438 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5440 int width
, height
, depth
;
5444 #if 0 /* MAC_TODO: Image support for Mac */
5445 Display
*display
= FRAME_W32_DISPLAY (f
);
5446 Screen
*screen
= FRAME_X_SCREEN (f
);
5447 Window window
= FRAME_W32_WINDOW (f
);
5449 xassert (interrupt_input_blocked
);
5452 depth
= DefaultDepthOfScreen (screen
);
5453 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5454 depth
, ZPixmap
, 0, NULL
, width
, height
,
5455 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5458 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5462 /* Allocate image raster. */
5463 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5465 /* Allocate a pixmap of the same size. */
5466 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5469 x_destroy_x_image (*ximg
);
5471 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5474 #endif /* MAC_TODO */
5479 /* Destroy XImage XIMG. Free XIMG->data. */
5482 x_destroy_x_image (ximg
)
5485 xassert (interrupt_input_blocked
);
5490 XDestroyImage (ximg
);
5495 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5496 are width and height of both the image and pixmap. */
5499 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5506 xassert (interrupt_input_blocked
);
5507 gc
= XCreateGC (NULL
, pixmap
, 0, NULL
);
5508 XPutImage (NULL
, pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5512 #endif /* MAC_TODO */
5515 /***********************************************************************
5517 ***********************************************************************/
5519 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5521 /* Find image file FILE. Look in data-directory, then
5522 x-bitmap-file-path. Value is the full name of the file found, or
5523 nil if not found. */
5526 x_find_image_file (file
)
5529 Lisp_Object file_found
, search_path
;
5530 struct gcpro gcpro1
, gcpro2
;
5534 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5535 GCPRO2 (file_found
, search_path
);
5537 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5538 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5550 /***********************************************************************
5552 ***********************************************************************/
5554 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5555 static int xbm_load_image_from_file
P_ ((struct frame
*f
, struct image
*img
,
5557 static int xbm_image_p
P_ ((Lisp_Object object
));
5558 static int xbm_read_bitmap_file_data
P_ ((char *, int *, int *,
5562 /* Indices of image specification fields in xbm_format, below. */
5564 enum xbm_keyword_index
5581 /* Vector of image_keyword structures describing the format
5582 of valid XBM image specifications. */
5584 static struct image_keyword xbm_format
[XBM_LAST
] =
5586 {":type", IMAGE_SYMBOL_VALUE
, 1},
5587 {":file", IMAGE_STRING_VALUE
, 0},
5588 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5589 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5590 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5591 {":foreground", IMAGE_STRING_VALUE
, 0},
5592 {":background", IMAGE_STRING_VALUE
, 0},
5593 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
5594 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5595 {":relief", IMAGE_INTEGER_VALUE
, 0},
5596 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5597 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5600 /* Structure describing the image type XBM. */
5602 static struct image_type xbm_type
=
5611 /* Tokens returned from xbm_scan. */
5620 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5621 A valid specification is a list starting with the symbol `image'
5622 The rest of the list is a property list which must contain an
5625 If the specification specifies a file to load, it must contain
5626 an entry `:file FILENAME' where FILENAME is a string.
5628 If the specification is for a bitmap loaded from memory it must
5629 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5630 WIDTH and HEIGHT are integers > 0. DATA may be:
5632 1. a string large enough to hold the bitmap data, i.e. it must
5633 have a size >= (WIDTH + 7) / 8 * HEIGHT
5635 2. a bool-vector of size >= WIDTH * HEIGHT
5637 3. a vector of strings or bool-vectors, one for each line of the
5640 Both the file and data forms may contain the additional entries
5641 `:background COLOR' and `:foreground COLOR'. If not present,
5642 foreground and background of the frame on which the image is
5643 displayed, is used. */
5646 xbm_image_p (object
)
5649 struct image_keyword kw
[XBM_LAST
];
5651 bcopy (xbm_format
, kw
, sizeof kw
);
5652 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5655 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5657 if (kw
[XBM_FILE
].count
)
5659 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5667 /* Entries for `:width', `:height' and `:data' must be present. */
5668 if (!kw
[XBM_WIDTH
].count
5669 || !kw
[XBM_HEIGHT
].count
5670 || !kw
[XBM_DATA
].count
)
5673 data
= kw
[XBM_DATA
].value
;
5674 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5675 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5677 /* Check type of data, and width and height against contents of
5683 /* Number of elements of the vector must be >= height. */
5684 if (XVECTOR (data
)->size
< height
)
5687 /* Each string or bool-vector in data must be large enough
5688 for one line of the image. */
5689 for (i
= 0; i
< height
; ++i
)
5691 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5696 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5699 else if (BOOL_VECTOR_P (elt
))
5701 if (XBOOL_VECTOR (elt
)->size
< width
)
5708 else if (STRINGP (data
))
5711 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5714 else if (BOOL_VECTOR_P (data
))
5716 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5723 /* Baseline must be a value between 0 and 100 (a percentage). */
5724 if (kw
[XBM_ASCENT
].count
5725 && XFASTINT (kw
[XBM_ASCENT
].value
) > 100)
5732 /* Scan a bitmap file. FP is the stream to read from. Value is
5733 either an enumerator from enum xbm_token, or a character for a
5734 single-character token, or 0 at end of file. If scanning an
5735 identifier, store the lexeme of the identifier in SVAL. If
5736 scanning a number, store its value in *IVAL. */
5739 xbm_scan (fp
, sval
, ival
)
5746 /* Skip white space. */
5747 while ((c
= fgetc (fp
)) != EOF
&& isspace (c
))
5752 else if (isdigit (c
))
5754 int value
= 0, digit
;
5759 if (c
== 'x' || c
== 'X')
5761 while ((c
= fgetc (fp
)) != EOF
)
5765 else if (c
>= 'a' && c
<= 'f')
5766 digit
= c
- 'a' + 10;
5767 else if (c
>= 'A' && c
<= 'F')
5768 digit
= c
- 'A' + 10;
5771 value
= 16 * value
+ digit
;
5774 else if (isdigit (c
))
5777 while ((c
= fgetc (fp
)) != EOF
5779 value
= 8 * value
+ c
- '0';
5785 while ((c
= fgetc (fp
)) != EOF
5787 value
= 10 * value
+ c
- '0';
5795 else if (isalpha (c
) || c
== '_')
5798 while ((c
= fgetc (fp
)) != EOF
5799 && (isalnum (c
) || c
== '_'))
5811 /* Replacement for XReadBitmapFileData which isn't available under old
5812 X versions. FILE is the name of the bitmap file to read. Set
5813 *WIDTH and *HEIGHT to the width and height of the image. Return in
5814 *DATA the bitmap data allocated with xmalloc. Value is non-zero if
5818 xbm_read_bitmap_file_data (file
, width
, height
, data
)
5820 int *width
, *height
;
5821 unsigned char **data
;
5824 char buffer
[BUFSIZ
];
5827 int bytes_per_line
, i
, nbytes
;
5833 LA1 = xbm_scan (fp, buffer, &value)
5835 #define expect(TOKEN) \
5836 if (LA1 != (TOKEN)) \
5841 #define expect_ident(IDENT) \
5842 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
5847 fp
= fopen (file
, "r");
5851 *width
= *height
= -1;
5853 LA1
= xbm_scan (fp
, buffer
, &value
);
5855 /* Parse defines for width, height and hot-spots. */
5859 expect_ident ("define");
5860 expect (XBM_TK_IDENT
);
5862 if (LA1
== XBM_TK_NUMBER
);
5864 char *p
= strrchr (buffer
, '_');
5865 p
= p
? p
+ 1 : buffer
;
5866 if (strcmp (p
, "width") == 0)
5868 else if (strcmp (p
, "height") == 0)
5871 expect (XBM_TK_NUMBER
);
5874 if (*width
< 0 || *height
< 0)
5877 /* Parse bits. Must start with `static'. */
5878 expect_ident ("static");
5879 if (LA1
== XBM_TK_IDENT
)
5881 if (strcmp (buffer
, "unsigned") == 0)
5884 expect_ident ("char");
5886 else if (strcmp (buffer
, "short") == 0)
5890 if (*width
% 16 && *width
% 16 < 9)
5893 else if (strcmp (buffer
, "char") == 0)
5901 expect (XBM_TK_IDENT
);
5907 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
5908 nbytes
= bytes_per_line
* *height
;
5909 p
= *data
= (char *) xmalloc (nbytes
);
5914 for (i
= 0; i
< nbytes
; i
+= 2)
5917 expect (XBM_TK_NUMBER
);
5920 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
5923 if (LA1
== ',' || LA1
== '}')
5931 for (i
= 0; i
< nbytes
; ++i
)
5934 expect (XBM_TK_NUMBER
);
5938 if (LA1
== ',' || LA1
== '}')
5964 /* Load XBM image IMG which will be displayed on frame F from file
5965 SPECIFIED_FILE. Value is non-zero if successful. */
5968 xbm_load_image_from_file (f
, img
, specified_file
)
5971 Lisp_Object specified_file
;
5974 unsigned char *data
;
5977 struct gcpro gcpro1
;
5979 xassert (STRINGP (specified_file
));
5983 file
= x_find_image_file (specified_file
);
5984 if (!STRINGP (file
))
5986 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5991 rc
= xbm_read_bitmap_file_data (SDATA (file
), &img
->width
,
5992 &img
->height
, &data
);
5995 int depth
= one_mac_display_info
.n_cbits
;
5996 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
5997 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6000 xassert (img
->width
> 0 && img
->height
> 0);
6002 /* Get foreground and background colors, maybe allocate colors. */
6003 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
6005 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
6007 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
6009 background
= x_alloc_image_color (f
, img
, value
, background
);
6011 #if 0 /* MAC_TODO : Port image display to Mac */
6014 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
6015 FRAME_W32_WINDOW (f
),
6017 img
->width
, img
->height
,
6018 foreground
, background
,
6022 if (img
->pixmap
== 0)
6024 x_clear_image (f
, img
);
6025 image_error ("Unable to create X pixmap for `%s'", file
, Qnil
);
6031 #endif /* MAC_TODO */
6034 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6041 /* Fill image IMG which is used on frame F with pixmap data. Value is
6042 non-zero if successful. */
6050 Lisp_Object file_name
;
6052 xassert (xbm_image_p (img
->spec
));
6054 /* If IMG->spec specifies a file name, create a non-file spec from it. */
6055 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
6056 if (STRINGP (file_name
))
6057 success_p
= xbm_load_image_from_file (f
, img
, file_name
);
6060 struct image_keyword fmt
[XBM_LAST
];
6063 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6064 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6068 /* Parse the list specification. */
6069 bcopy (xbm_format
, fmt
, sizeof fmt
);
6070 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
6073 /* Get specified width, and height. */
6074 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
6075 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
6076 xassert (img
->width
> 0 && img
->height
> 0);
6080 if (fmt
[XBM_ASCENT
].count
)
6081 img
->ascent
= XFASTINT (fmt
[XBM_ASCENT
].value
);
6083 /* Get foreground and background colors, maybe allocate colors. */
6084 if (fmt
[XBM_FOREGROUND
].count
)
6085 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
6087 if (fmt
[XBM_BACKGROUND
].count
)
6088 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
6091 /* Set bits to the bitmap image data. */
6092 data
= fmt
[XBM_DATA
].value
;
6097 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
6099 p
= bits
= (char *) alloca (nbytes
* img
->height
);
6100 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
6102 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
6104 bcopy (SDATA (line
), p
, nbytes
);
6106 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
6109 else if (STRINGP (data
))
6110 bits
= SDATA (data
);
6112 bits
= XBOOL_VECTOR (data
)->data
;
6114 #if 0 /* MAC_TODO : port Mac display code */
6115 /* Create the pixmap. */
6116 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6118 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
6119 FRAME_W32_WINDOW (f
),
6121 img
->width
, img
->height
,
6122 foreground
, background
,
6124 #endif /* MAC_TODO */
6130 image_error ("Unable to create pixmap for XBM image `%s'",
6132 x_clear_image (f
, img
);
6143 /***********************************************************************
6145 ***********************************************************************/
6149 static int xpm_image_p
P_ ((Lisp_Object object
));
6150 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6151 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6153 #include "X11/xpm.h"
6155 /* The symbol `xpm' identifying XPM-format images. */
6159 /* Indices of image specification fields in xpm_format, below. */
6161 enum xpm_keyword_index
6175 /* Vector of image_keyword structures describing the format
6176 of valid XPM image specifications. */
6178 static struct image_keyword xpm_format
[XPM_LAST
] =
6180 {":type", IMAGE_SYMBOL_VALUE
, 1},
6181 {":file", IMAGE_STRING_VALUE
, 0},
6182 {":data", IMAGE_STRING_VALUE
, 0},
6183 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6184 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6185 {":relief", IMAGE_INTEGER_VALUE
, 0},
6186 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6187 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6188 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6191 /* Structure describing the image type XBM. */
6193 static struct image_type xpm_type
=
6203 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6204 for XPM images. Such a list must consist of conses whose car and
6208 xpm_valid_color_symbols_p (color_symbols
)
6209 Lisp_Object color_symbols
;
6211 while (CONSP (color_symbols
))
6213 Lisp_Object sym
= XCAR (color_symbols
);
6215 || !STRINGP (XCAR (sym
))
6216 || !STRINGP (XCDR (sym
)))
6218 color_symbols
= XCDR (color_symbols
);
6221 return NILP (color_symbols
);
6225 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6228 xpm_image_p (object
)
6231 struct image_keyword fmt
[XPM_LAST
];
6232 bcopy (xpm_format
, fmt
, sizeof fmt
);
6233 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6234 /* Either `:file' or `:data' must be present. */
6235 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6236 /* Either no `:color-symbols' or it's a list of conses
6237 whose car and cdr are strings. */
6238 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6239 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
))
6240 && (fmt
[XPM_ASCENT
].count
== 0
6241 || XFASTINT (fmt
[XPM_ASCENT
].value
) < 100));
6245 /* Load image IMG which will be displayed on frame F. Value is
6246 non-zero if successful. */
6254 XpmAttributes attrs
;
6255 Lisp_Object specified_file
, color_symbols
;
6257 /* Configure the XPM lib. Use the visual of frame F. Allocate
6258 close colors. Return colors allocated. */
6259 bzero (&attrs
, sizeof attrs
);
6260 attrs
.visual
= FRAME_X_VISUAL (f
);
6261 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6262 attrs
.valuemask
|= XpmVisual
;
6263 attrs
.valuemask
|= XpmColormap
;
6264 attrs
.valuemask
|= XpmReturnAllocPixels
;
6265 #ifdef XpmAllocCloseColors
6266 attrs
.alloc_close_colors
= 1;
6267 attrs
.valuemask
|= XpmAllocCloseColors
;
6269 attrs
.closeness
= 600;
6270 attrs
.valuemask
|= XpmCloseness
;
6273 /* If image specification contains symbolic color definitions, add
6274 these to `attrs'. */
6275 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6276 if (CONSP (color_symbols
))
6279 XpmColorSymbol
*xpm_syms
;
6282 attrs
.valuemask
|= XpmColorSymbols
;
6284 /* Count number of symbols. */
6285 attrs
.numsymbols
= 0;
6286 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6289 /* Allocate an XpmColorSymbol array. */
6290 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6291 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6292 bzero (xpm_syms
, size
);
6293 attrs
.colorsymbols
= xpm_syms
;
6295 /* Fill the color symbol array. */
6296 for (tail
= color_symbols
, i
= 0;
6298 ++i
, tail
= XCDR (tail
))
6300 Lisp_Object name
= XCAR (XCAR (tail
));
6301 Lisp_Object color
= XCDR (XCAR (tail
));
6302 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
6303 strcpy (xpm_syms
[i
].name
, SDATA (name
));
6304 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
6305 strcpy (xpm_syms
[i
].value
, SDATA (color
));
6309 /* Create a pixmap for the image, either from a file, or from a
6310 string buffer containing data in the same format as an XPM file. */
6312 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6313 if (STRINGP (specified_file
))
6315 Lisp_Object file
= x_find_image_file (specified_file
);
6316 if (!STRINGP (file
))
6318 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6323 rc
= XpmReadFileToPixmap (NULL
, FRAME_W32_WINDOW (f
),
6324 SDATA (file
), &img
->pixmap
, &img
->mask
,
6329 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6330 rc
= XpmCreatePixmapFromBuffer (NULL
, FRAME_W32_WINDOW (f
),
6332 &img
->pixmap
, &img
->mask
,
6337 if (rc
== XpmSuccess
)
6339 /* Remember allocated colors. */
6340 img
->ncolors
= attrs
.nalloc_pixels
;
6341 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6342 * sizeof *img
->colors
);
6343 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6344 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6346 img
->width
= attrs
.width
;
6347 img
->height
= attrs
.height
;
6348 xassert (img
->width
> 0 && img
->height
> 0);
6350 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6352 XpmFreeAttributes (&attrs
);
6360 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6363 case XpmFileInvalid
:
6364 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6368 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6371 case XpmColorFailed
:
6372 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6376 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6381 return rc
== XpmSuccess
;
6384 #endif /* HAVE_XPM != 0 */
6387 #if 0 /* MAC_TODO : Color tables on Mac. */
6388 /***********************************************************************
6390 ***********************************************************************/
6392 /* An entry in the color table mapping an RGB color to a pixel color. */
6397 unsigned long pixel
;
6399 /* Next in color table collision list. */
6400 struct ct_color
*next
;
6403 /* The bucket vector size to use. Must be prime. */
6407 /* Value is a hash of the RGB color given by R, G, and B. */
6409 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6411 /* The color hash table. */
6413 struct ct_color
**ct_table
;
6415 /* Number of entries in the color table. */
6417 int ct_colors_allocated
;
6419 /* Function prototypes. */
6421 static void init_color_table
P_ ((void));
6422 static void free_color_table
P_ ((void));
6423 static unsigned long *colors_in_color_table
P_ ((int *n
));
6424 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
6425 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
6428 /* Initialize the color table. */
6433 int size
= CT_SIZE
* sizeof (*ct_table
);
6434 ct_table
= (struct ct_color
**) xmalloc (size
);
6435 bzero (ct_table
, size
);
6436 ct_colors_allocated
= 0;
6440 /* Free memory associated with the color table. */
6446 struct ct_color
*p
, *next
;
6448 for (i
= 0; i
< CT_SIZE
; ++i
)
6449 for (p
= ct_table
[i
]; p
; p
= next
)
6460 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6461 entry for that color already is in the color table, return the
6462 pixel color of that entry. Otherwise, allocate a new color for R,
6463 G, B, and make an entry in the color table. */
6465 static unsigned long
6466 lookup_rgb_color (f
, r
, g
, b
)
6470 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6471 int i
= hash
% CT_SIZE
;
6474 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6475 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6484 color
= RGB_TO_ULONG (r
, g
, b
);
6486 ++ct_colors_allocated
;
6488 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6493 p
->next
= ct_table
[i
];
6501 /* Look up pixel color PIXEL which is used on frame F in the color
6502 table. If not already present, allocate it. Value is PIXEL. */
6504 static unsigned long
6505 lookup_pixel_color (f
, pixel
)
6507 unsigned long pixel
;
6509 int i
= pixel
% CT_SIZE
;
6512 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6513 if (p
->pixel
== pixel
)
6524 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6525 color
.pixel
= pixel
;
6526 XQueryColor (NULL
, cmap
, &color
);
6527 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6532 ++ct_colors_allocated
;
6534 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6539 p
->next
= ct_table
[i
];
6543 return FRAME_FOREGROUND_PIXEL (f
);
6549 /* Value is a vector of all pixel colors contained in the color table,
6550 allocated via xmalloc. Set *N to the number of colors. */
6552 static unsigned long *
6553 colors_in_color_table (n
)
6558 unsigned long *colors
;
6560 if (ct_colors_allocated
== 0)
6567 colors
= (unsigned long *) xmalloc (ct_colors_allocated
6569 *n
= ct_colors_allocated
;
6571 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
6572 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6573 colors
[j
++] = p
->pixel
;
6579 #endif /* MAC_TODO */
6582 /***********************************************************************
6584 ***********************************************************************/
6586 #if 0 /* MAC_TODO : Mac versions of low level algorithms */
6587 static void x_laplace_write_row
P_ ((struct frame
*, long *,
6588 int, XImage
*, int));
6589 static void x_laplace_read_row
P_ ((struct frame
*, Colormap
,
6590 XColor
*, int, XImage
*, int));
6593 /* Fill COLORS with RGB colors from row Y of image XIMG. F is the
6594 frame we operate on, CMAP is the color-map in effect, and WIDTH is
6595 the width of one row in the image. */
6598 x_laplace_read_row (f
, cmap
, colors
, width
, ximg
, y
)
6608 for (x
= 0; x
< width
; ++x
)
6609 colors
[x
].pixel
= XGetPixel (ximg
, x
, y
);
6611 XQueryColors (NULL
, cmap
, colors
, width
);
6615 /* Write row Y of image XIMG. PIXELS is an array of WIDTH longs
6616 containing the pixel colors to write. F is the frame we are
6620 x_laplace_write_row (f
, pixels
, width
, ximg
, y
)
6629 for (x
= 0; x
< width
; ++x
)
6630 XPutPixel (ximg
, x
, y
, pixels
[x
]);
6632 #endif /* MAC_TODO */
6634 /* Transform image IMG which is used on frame F with a Laplace
6635 edge-detection algorithm. The result is an image that can be used
6636 to draw disabled buttons, for example. */
6643 #if 0 /* MAC_TODO : Mac version */
6644 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6645 XImage
*ximg
, *oimg
;
6651 int in_y
, out_y
, rc
;
6656 /* Get the X image IMG->pixmap. */
6657 ximg
= XGetImage (NULL
, img
->pixmap
,
6658 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
6660 /* Allocate 3 input rows, and one output row of colors. */
6661 for (i
= 0; i
< 3; ++i
)
6662 in
[i
] = (XColor
*) alloca (img
->width
* sizeof (XColor
));
6663 out
= (long *) alloca (img
->width
* sizeof (long));
6665 /* Create an X image for output. */
6666 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
6669 /* Fill first two rows. */
6670 x_laplace_read_row (f
, cmap
, in
[0], img
->width
, ximg
, 0);
6671 x_laplace_read_row (f
, cmap
, in
[1], img
->width
, ximg
, 1);
6674 /* Write first row, all zeros. */
6675 init_color_table ();
6676 pixel
= lookup_rgb_color (f
, 0, 0, 0);
6677 for (x
= 0; x
< img
->width
; ++x
)
6679 x_laplace_write_row (f
, out
, img
->width
, oimg
, 0);
6682 for (y
= 2; y
< img
->height
; ++y
)
6685 int rowb
= (y
+ 2) % 3;
6687 x_laplace_read_row (f
, cmap
, in
[rowa
], img
->width
, ximg
, in_y
++);
6689 for (x
= 0; x
< img
->width
- 2; ++x
)
6691 int r
= in
[rowa
][x
].red
+ mv2
- in
[rowb
][x
+ 2].red
;
6692 int g
= in
[rowa
][x
].green
+ mv2
- in
[rowb
][x
+ 2].green
;
6693 int b
= in
[rowa
][x
].blue
+ mv2
- in
[rowb
][x
+ 2].blue
;
6695 out
[x
+ 1] = lookup_rgb_color (f
, r
& 0xffff, g
& 0xffff,
6699 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
++);
6702 /* Write last line, all zeros. */
6703 for (x
= 0; x
< img
->width
; ++x
)
6705 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
);
6707 /* Free the input image, and free resources of IMG. */
6708 XDestroyImage (ximg
);
6709 x_clear_image (f
, img
);
6711 /* Put the output image into pixmap, and destroy it. */
6712 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
6713 x_destroy_x_image (oimg
);
6715 /* Remember new pixmap and colors in IMG. */
6716 img
->pixmap
= pixmap
;
6717 img
->colors
= colors_in_color_table (&img
->ncolors
);
6718 free_color_table ();
6721 #endif /* MAC_TODO */
6725 /* Build a mask for image IMG which is used on frame F. FILE is the
6726 name of an image file, for error messages. HOW determines how to
6727 determine the background color of IMG. If it is a list '(R G B)',
6728 with R, G, and B being integers >= 0, take that as the color of the
6729 background. Otherwise, determine the background color of IMG
6730 heuristically. Value is non-zero if successful. */
6733 x_build_heuristic_mask (f
, img
, how
)
6738 #if 0 /* MAC_TODO : Mac version */
6739 Display
*dpy
= FRAME_W32_DISPLAY (f
);
6740 XImage
*ximg
, *mask_img
;
6741 int x
, y
, rc
, look_at_corners_p
;
6746 /* Create an image and pixmap serving as mask. */
6747 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
6748 &mask_img
, &img
->mask
);
6755 /* Get the X image of IMG->pixmap. */
6756 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
6759 /* Determine the background color of ximg. If HOW is `(R G B)'
6760 take that as color. Otherwise, try to determine the color
6762 look_at_corners_p
= 1;
6770 && NATNUMP (XCAR (how
)))
6772 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
6776 if (i
== 3 && NILP (how
))
6778 char color_name
[30];
6779 XColor exact
, color
;
6782 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
6784 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6785 if (XLookupColor (dpy
, cmap
, color_name
, &exact
, &color
))
6788 look_at_corners_p
= 0;
6793 if (look_at_corners_p
)
6795 unsigned long corners
[4];
6798 /* Get the colors at the corners of ximg. */
6799 corners
[0] = XGetPixel (ximg
, 0, 0);
6800 corners
[1] = XGetPixel (ximg
, img
->width
- 1, 0);
6801 corners
[2] = XGetPixel (ximg
, img
->width
- 1, img
->height
- 1);
6802 corners
[3] = XGetPixel (ximg
, 0, img
->height
- 1);
6804 /* Choose the most frequently found color as background. */
6805 for (i
= best_count
= 0; i
< 4; ++i
)
6809 for (j
= n
= 0; j
< 4; ++j
)
6810 if (corners
[i
] == corners
[j
])
6814 bg
= corners
[i
], best_count
= n
;
6818 /* Set all bits in mask_img to 1 whose color in ximg is different
6819 from the background color bg. */
6820 for (y
= 0; y
< img
->height
; ++y
)
6821 for (x
= 0; x
< img
->width
; ++x
)
6822 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
6824 /* Put mask_img into img->mask. */
6825 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
6826 x_destroy_x_image (mask_img
);
6827 XDestroyImage (ximg
);
6830 #endif /* MAC_TODO */
6837 /***********************************************************************
6838 PBM (mono, gray, color)
6839 ***********************************************************************/
6842 static int pbm_image_p
P_ ((Lisp_Object object
));
6843 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
6844 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
6846 /* The symbol `pbm' identifying images of this type. */
6850 /* Indices of image specification fields in gs_format, below. */
6852 enum pbm_keyword_index
6865 /* Vector of image_keyword structures describing the format
6866 of valid user-defined image specifications. */
6868 static struct image_keyword pbm_format
[PBM_LAST
] =
6870 {":type", IMAGE_SYMBOL_VALUE
, 1},
6871 {":file", IMAGE_STRING_VALUE
, 0},
6872 {":data", IMAGE_STRING_VALUE
, 0},
6873 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6874 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6875 {":relief", IMAGE_INTEGER_VALUE
, 0},
6876 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6877 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6880 /* Structure describing the image type `pbm'. */
6882 static struct image_type pbm_type
=
6892 /* Return non-zero if OBJECT is a valid PBM image specification. */
6895 pbm_image_p (object
)
6898 struct image_keyword fmt
[PBM_LAST
];
6900 bcopy (pbm_format
, fmt
, sizeof fmt
);
6902 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
)
6903 || (fmt
[PBM_ASCENT
].count
6904 && XFASTINT (fmt
[PBM_ASCENT
].value
) > 100))
6907 /* Must specify either :data or :file. */
6908 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
6912 /* Scan a decimal number from *S and return it. Advance *S while
6913 reading the number. END is the end of the string. Value is -1 at
6917 pbm_scan_number (s
, end
)
6918 unsigned char **s
, *end
;
6924 /* Skip white-space. */
6925 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
6930 /* Skip comment to end of line. */
6931 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
6934 else if (isdigit (c
))
6936 /* Read decimal number. */
6938 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
6939 val
= 10 * val
+ c
- '0';
6950 /* Read FILE into memory. Value is a pointer to a buffer allocated
6951 with xmalloc holding FILE's contents. Value is null if an error
6952 occurred. *SIZE is set to the size of the file. */
6955 pbm_read_file (file
, size
)
6963 if (stat (SDATA (file
), &st
) == 0
6964 && (fp
= fopen (SDATA (file
), "r")) != NULL
6965 && (buf
= (char *) xmalloc (st
.st_size
),
6966 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
6986 /* Load PBM image IMG for use on frame F. */
6994 int width
, height
, max_color_idx
= 0;
6996 Lisp_Object file
, specified_file
;
6997 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
6998 struct gcpro gcpro1
;
6999 unsigned char *contents
= NULL
;
7000 unsigned char *end
, *p
;
7003 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7007 if (STRINGP (specified_file
))
7009 file
= x_find_image_file (specified_file
);
7010 if (!STRINGP (file
))
7012 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7017 contents
= pbm_read_file (file
, &size
);
7018 if (contents
== NULL
)
7020 image_error ("Error reading `%s'", file
, Qnil
);
7026 end
= contents
+ size
;
7031 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7033 end
= p
+ SBYTES (data
);
7036 /* Check magic number. */
7037 if (end
- p
< 2 || *p
++ != 'P')
7039 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7049 raw_p
= 0, type
= PBM_MONO
;
7053 raw_p
= 0, type
= PBM_GRAY
;
7057 raw_p
= 0, type
= PBM_COLOR
;
7061 raw_p
= 1, type
= PBM_MONO
;
7065 raw_p
= 1, type
= PBM_GRAY
;
7069 raw_p
= 1, type
= PBM_COLOR
;
7073 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7077 /* Read width, height, maximum color-component. Characters
7078 starting with `#' up to the end of a line are ignored. */
7079 width
= pbm_scan_number (&p
, end
);
7080 height
= pbm_scan_number (&p
, end
);
7082 if (type
!= PBM_MONO
)
7084 max_color_idx
= pbm_scan_number (&p
, end
);
7085 if (raw_p
&& max_color_idx
> 255)
7086 max_color_idx
= 255;
7091 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7095 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7096 &ximg
, &img
->pixmap
))
7102 /* Initialize the color hash table. */
7103 init_color_table ();
7105 if (type
== PBM_MONO
)
7109 for (y
= 0; y
< height
; ++y
)
7110 for (x
= 0; x
< width
; ++x
)
7120 g
= pbm_scan_number (&p
, end
);
7122 XPutPixel (ximg
, x
, y
, (g
7123 ? FRAME_FOREGROUND_PIXEL (f
)
7124 : FRAME_BACKGROUND_PIXEL (f
)));
7129 for (y
= 0; y
< height
; ++y
)
7130 for (x
= 0; x
< width
; ++x
)
7134 if (type
== PBM_GRAY
)
7135 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7144 r
= pbm_scan_number (&p
, end
);
7145 g
= pbm_scan_number (&p
, end
);
7146 b
= pbm_scan_number (&p
, end
);
7149 if (r
< 0 || g
< 0 || b
< 0)
7153 XDestroyImage (ximg
);
7155 image_error ("Invalid pixel value in image `%s'",
7160 /* RGB values are now in the range 0..max_color_idx.
7161 Scale this to the range 0..0xffff supported by X. */
7162 r
= (double) r
* 65535 / max_color_idx
;
7163 g
= (double) g
* 65535 / max_color_idx
;
7164 b
= (double) b
* 65535 / max_color_idx
;
7165 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7169 /* Store in IMG->colors the colors allocated for the image, and
7170 free the color table. */
7171 img
->colors
= colors_in_color_table (&img
->ncolors
);
7172 free_color_table ();
7174 /* Put the image into a pixmap. */
7175 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7176 x_destroy_x_image (ximg
);
7180 img
->height
= height
;
7186 #endif /* HAVE_PBM */
7189 /***********************************************************************
7191 ***********************************************************************/
7197 /* Function prototypes. */
7199 static int png_image_p
P_ ((Lisp_Object object
));
7200 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7202 /* The symbol `png' identifying images of this type. */
7206 /* Indices of image specification fields in png_format, below. */
7208 enum png_keyword_index
7221 /* Vector of image_keyword structures describing the format
7222 of valid user-defined image specifications. */
7224 static struct image_keyword png_format
[PNG_LAST
] =
7226 {":type", IMAGE_SYMBOL_VALUE
, 1},
7227 {":data", IMAGE_STRING_VALUE
, 0},
7228 {":file", IMAGE_STRING_VALUE
, 0},
7229 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7230 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7231 {":relief", IMAGE_INTEGER_VALUE
, 0},
7232 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7233 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7236 /* Structure describing the image type `png'. */
7238 static struct image_type png_type
=
7248 /* Return non-zero if OBJECT is a valid PNG image specification. */
7251 png_image_p (object
)
7254 struct image_keyword fmt
[PNG_LAST
];
7255 bcopy (png_format
, fmt
, sizeof fmt
);
7257 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
)
7258 || (fmt
[PNG_ASCENT
].count
7259 && XFASTINT (fmt
[PNG_ASCENT
].value
) > 100))
7262 /* Must specify either the :data or :file keyword. */
7263 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7267 /* Error and warning handlers installed when the PNG library
7271 my_png_error (png_ptr
, msg
)
7272 png_struct
*png_ptr
;
7275 xassert (png_ptr
!= NULL
);
7276 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7277 longjmp (png_ptr
->jmpbuf
, 1);
7282 my_png_warning (png_ptr
, msg
)
7283 png_struct
*png_ptr
;
7286 xassert (png_ptr
!= NULL
);
7287 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7290 /* Memory source for PNG decoding. */
7292 struct png_memory_storage
7294 unsigned char *bytes
; /* The data */
7295 size_t len
; /* How big is it? */
7296 int index
; /* Where are we? */
7300 /* Function set as reader function when reading PNG image from memory.
7301 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7302 bytes from the input to DATA. */
7305 png_read_from_memory (png_ptr
, data
, length
)
7306 png_structp png_ptr
;
7310 struct png_memory_storage
*tbr
7311 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7313 if (length
> tbr
->len
- tbr
->index
)
7314 png_error (png_ptr
, "Read error");
7316 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7317 tbr
->index
= tbr
->index
+ length
;
7320 /* Load PNG image IMG for use on frame F. Value is non-zero if
7328 Lisp_Object file
, specified_file
;
7329 Lisp_Object specified_data
;
7331 XImage
*ximg
, *mask_img
= NULL
;
7332 struct gcpro gcpro1
;
7333 png_struct
*png_ptr
= NULL
;
7334 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7337 png_byte
*pixels
= NULL
;
7338 png_byte
**rows
= NULL
;
7339 png_uint_32 width
, height
;
7340 int bit_depth
, color_type
, interlace_type
;
7342 png_uint_32 row_bytes
;
7345 double screen_gamma
, image_gamma
;
7347 struct png_memory_storage tbr
; /* Data to be read */
7349 /* Find out what file to load. */
7350 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7351 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7355 if (NILP (specified_data
))
7357 file
= x_find_image_file (specified_file
);
7358 if (!STRINGP (file
))
7360 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7365 /* Open the image file. */
7366 fp
= fopen (SDATA (file
), "rb");
7369 image_error ("Cannot open image file `%s'", file
, Qnil
);
7375 /* Check PNG signature. */
7376 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7377 || !png_check_sig (sig
, sizeof sig
))
7379 image_error ("Not a PNG file:` %s'", file
, Qnil
);
7387 /* Read from memory. */
7388 tbr
.bytes
= SDATA (specified_data
);
7389 tbr
.len
= SBYTES (specified_data
);
7392 /* Check PNG signature. */
7393 if (tbr
.len
< sizeof sig
7394 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7396 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7401 /* Need to skip past the signature. */
7402 tbr
.bytes
+= sizeof (sig
);
7405 /* Initialize read and info structs for PNG lib. */
7406 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7407 my_png_error
, my_png_warning
);
7410 if (fp
) fclose (fp
);
7415 info_ptr
= png_create_info_struct (png_ptr
);
7418 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7419 if (fp
) fclose (fp
);
7424 end_info
= png_create_info_struct (png_ptr
);
7427 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7428 if (fp
) fclose (fp
);
7433 /* Set error jump-back. We come back here when the PNG library
7434 detects an error. */
7435 if (setjmp (png_ptr
->jmpbuf
))
7439 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7442 if (fp
) fclose (fp
);
7447 /* Read image info. */
7448 if (!NILP (specified_data
))
7449 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7451 png_init_io (png_ptr
, fp
);
7453 png_set_sig_bytes (png_ptr
, sizeof sig
);
7454 png_read_info (png_ptr
, info_ptr
);
7455 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7456 &interlace_type
, NULL
, NULL
);
7458 /* If image contains simply transparency data, we prefer to
7459 construct a clipping mask. */
7460 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7465 /* This function is easier to write if we only have to handle
7466 one data format: RGB or RGBA with 8 bits per channel. Let's
7467 transform other formats into that format. */
7469 /* Strip more than 8 bits per channel. */
7470 if (bit_depth
== 16)
7471 png_set_strip_16 (png_ptr
);
7473 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7475 png_set_expand (png_ptr
);
7477 /* Convert grayscale images to RGB. */
7478 if (color_type
== PNG_COLOR_TYPE_GRAY
7479 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7480 png_set_gray_to_rgb (png_ptr
);
7482 /* The value 2.2 is a guess for PC monitors from PNG example.c. */
7483 gamma_str
= getenv ("SCREEN_GAMMA");
7484 screen_gamma
= gamma_str
? atof (gamma_str
) : 2.2;
7486 /* Tell the PNG lib to handle gamma correction for us. */
7488 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7489 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7490 /* There is a special chunk in the image specifying the gamma. */
7491 png_set_sRGB (png_ptr
, info_ptr
, intent
);
7494 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7495 /* Image contains gamma information. */
7496 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7498 /* Use a default of 0.5 for the image gamma. */
7499 png_set_gamma (png_ptr
, screen_gamma
, 0.5);
7501 /* Handle alpha channel by combining the image with a background
7502 color. Do this only if a real alpha channel is supplied. For
7503 simple transparency, we prefer a clipping mask. */
7506 png_color_16
*image_background
;
7508 if (png_get_bKGD (png_ptr
, info_ptr
, &image_background
))
7509 /* Image contains a background color with which to
7510 combine the image. */
7511 png_set_background (png_ptr
, image_background
,
7512 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
7515 /* Image does not contain a background color with which
7516 to combine the image data via an alpha channel. Use
7517 the frame's background instead. */
7520 png_color_16 frame_background
;
7523 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
7524 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7525 XQueryColor (FRAME_W32_DISPLAY (f
), cmap
, &color
);
7528 bzero (&frame_background
, sizeof frame_background
);
7529 frame_background
.red
= color
.red
;
7530 frame_background
.green
= color
.green
;
7531 frame_background
.blue
= color
.blue
;
7533 png_set_background (png_ptr
, &frame_background
,
7534 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7538 /* Update info structure. */
7539 png_read_update_info (png_ptr
, info_ptr
);
7541 /* Get number of channels. Valid values are 1 for grayscale images
7542 and images with a palette, 2 for grayscale images with transparency
7543 information (alpha channel), 3 for RGB images, and 4 for RGB
7544 images with alpha channel, i.e. RGBA. If conversions above were
7545 sufficient we should only have 3 or 4 channels here. */
7546 channels
= png_get_channels (png_ptr
, info_ptr
);
7547 xassert (channels
== 3 || channels
== 4);
7549 /* Number of bytes needed for one row of the image. */
7550 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
7552 /* Allocate memory for the image. */
7553 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
7554 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
7555 for (i
= 0; i
< height
; ++i
)
7556 rows
[i
] = pixels
+ i
* row_bytes
;
7558 /* Read the entire image. */
7559 png_read_image (png_ptr
, rows
);
7560 png_read_end (png_ptr
, info_ptr
);
7569 /* Create the X image and pixmap. */
7570 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7577 /* Create an image and pixmap serving as mask if the PNG image
7578 contains an alpha channel. */
7581 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
7582 &mask_img
, &img
->mask
))
7584 x_destroy_x_image (ximg
);
7585 XFreePixmap (FRAME_W32_DISPLAY (f
), img
->pixmap
);
7591 /* Fill the X image and mask from PNG data. */
7592 init_color_table ();
7594 for (y
= 0; y
< height
; ++y
)
7596 png_byte
*p
= rows
[y
];
7598 for (x
= 0; x
< width
; ++x
)
7605 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7607 /* An alpha channel, aka mask channel, associates variable
7608 transparency with an image. Where other image formats
7609 support binary transparency---fully transparent or fully
7610 opaque---PNG allows up to 254 levels of partial transparency.
7611 The PNG library implements partial transparency by combining
7612 the image with a specified background color.
7614 I'm not sure how to handle this here nicely: because the
7615 background on which the image is displayed may change, for
7616 real alpha channel support, it would be necessary to create
7617 a new image for each possible background.
7619 What I'm doing now is that a mask is created if we have
7620 boolean transparency information. Otherwise I'm using
7621 the frame's background color to combine the image with. */
7626 XPutPixel (mask_img
, x
, y
, *p
> 0);
7632 /* Remember colors allocated for this image. */
7633 img
->colors
= colors_in_color_table (&img
->ncolors
);
7634 free_color_table ();
7637 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7642 img
->height
= height
;
7644 /* Put the image into the pixmap, then free the X image and its buffer. */
7645 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7646 x_destroy_x_image (ximg
);
7648 /* Same for the mask. */
7651 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7652 x_destroy_x_image (mask_img
);
7660 #endif /* HAVE_PNG != 0 */
7664 /***********************************************************************
7666 ***********************************************************************/
7670 /* Work around a warning about HAVE_STDLIB_H being redefined in
7672 #ifdef HAVE_STDLIB_H
7673 #define HAVE_STDLIB_H_1
7674 #undef HAVE_STDLIB_H
7675 #endif /* HAVE_STLIB_H */
7677 #include <jpeglib.h>
7681 #ifdef HAVE_STLIB_H_1
7682 #define HAVE_STDLIB_H 1
7685 static int jpeg_image_p
P_ ((Lisp_Object object
));
7686 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
7688 /* The symbol `jpeg' identifying images of this type. */
7692 /* Indices of image specification fields in gs_format, below. */
7694 enum jpeg_keyword_index
7703 JPEG_HEURISTIC_MASK
,
7707 /* Vector of image_keyword structures describing the format
7708 of valid user-defined image specifications. */
7710 static struct image_keyword jpeg_format
[JPEG_LAST
] =
7712 {":type", IMAGE_SYMBOL_VALUE
, 1},
7713 {":data", IMAGE_STRING_VALUE
, 0},
7714 {":file", IMAGE_STRING_VALUE
, 0},
7715 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7716 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7717 {":relief", IMAGE_INTEGER_VALUE
, 0},
7718 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7719 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7722 /* Structure describing the image type `jpeg'. */
7724 static struct image_type jpeg_type
=
7734 /* Return non-zero if OBJECT is a valid JPEG image specification. */
7737 jpeg_image_p (object
)
7740 struct image_keyword fmt
[JPEG_LAST
];
7742 bcopy (jpeg_format
, fmt
, sizeof fmt
);
7744 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
)
7745 || (fmt
[JPEG_ASCENT
].count
7746 && XFASTINT (fmt
[JPEG_ASCENT
].value
) > 100))
7749 /* Must specify either the :data or :file keyword. */
7750 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
7754 struct my_jpeg_error_mgr
7756 struct jpeg_error_mgr pub
;
7757 jmp_buf setjmp_buffer
;
7761 my_error_exit (cinfo
)
7764 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
7765 longjmp (mgr
->setjmp_buffer
, 1);
7768 /* Init source method for JPEG data source manager. Called by
7769 jpeg_read_header() before any data is actually read. See
7770 libjpeg.doc from the JPEG lib distribution. */
7773 our_init_source (cinfo
)
7774 j_decompress_ptr cinfo
;
7779 /* Fill input buffer method for JPEG data source manager. Called
7780 whenever more data is needed. We read the whole image in one step,
7781 so this only adds a fake end of input marker at the end. */
7784 our_fill_input_buffer (cinfo
)
7785 j_decompress_ptr cinfo
;
7787 /* Insert a fake EOI marker. */
7788 struct jpeg_source_mgr
*src
= cinfo
->src
;
7789 static JOCTET buffer
[2];
7791 buffer
[0] = (JOCTET
) 0xFF;
7792 buffer
[1] = (JOCTET
) JPEG_EOI
;
7794 src
->next_input_byte
= buffer
;
7795 src
->bytes_in_buffer
= 2;
7800 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
7801 is the JPEG data source manager. */
7804 our_skip_input_data (cinfo
, num_bytes
)
7805 j_decompress_ptr cinfo
;
7808 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7812 if (num_bytes
> src
->bytes_in_buffer
)
7813 ERREXIT (cinfo
, JERR_INPUT_EOF
);
7815 src
->bytes_in_buffer
-= num_bytes
;
7816 src
->next_input_byte
+= num_bytes
;
7821 /* Method to terminate data source. Called by
7822 jpeg_finish_decompress() after all data has been processed. */
7825 our_term_source (cinfo
)
7826 j_decompress_ptr cinfo
;
7831 /* Set up the JPEG lib for reading an image from DATA which contains
7832 LEN bytes. CINFO is the decompression info structure created for
7833 reading the image. */
7836 jpeg_memory_src (cinfo
, data
, len
)
7837 j_decompress_ptr cinfo
;
7841 struct jpeg_source_mgr
*src
;
7843 if (cinfo
->src
== NULL
)
7845 /* First time for this JPEG object? */
7846 cinfo
->src
= (struct jpeg_source_mgr
*)
7847 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
7848 sizeof (struct jpeg_source_mgr
));
7849 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7850 src
->next_input_byte
= data
;
7853 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7854 src
->init_source
= our_init_source
;
7855 src
->fill_input_buffer
= our_fill_input_buffer
;
7856 src
->skip_input_data
= our_skip_input_data
;
7857 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
7858 src
->term_source
= our_term_source
;
7859 src
->bytes_in_buffer
= len
;
7860 src
->next_input_byte
= data
;
7864 /* Load image IMG for use on frame F. Patterned after example.c
7865 from the JPEG lib. */
7872 struct jpeg_decompress_struct cinfo
;
7873 struct my_jpeg_error_mgr mgr
;
7874 Lisp_Object file
, specified_file
;
7875 Lisp_Object specified_data
;
7878 int row_stride
, x
, y
;
7879 XImage
*ximg
= NULL
;
7881 unsigned long *colors
;
7883 struct gcpro gcpro1
;
7885 /* Open the JPEG file. */
7886 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7887 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7891 if (NILP (specified_data
))
7893 file
= x_find_image_file (specified_file
);
7894 if (!STRINGP (file
))
7896 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7901 fp
= fopen (SDATA (file
), "r");
7904 image_error ("Cannot open `%s'", file
, Qnil
);
7910 /* Customize libjpeg's error handling to call my_error_exit when an
7911 error is detected. This function will perform a longjmp. */
7912 mgr
.pub
.error_exit
= my_error_exit
;
7913 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
7915 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
7919 /* Called from my_error_exit. Display a JPEG error. */
7920 char buffer
[JMSG_LENGTH_MAX
];
7921 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
7922 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
7923 build_string (buffer
));
7926 /* Close the input file and destroy the JPEG object. */
7929 jpeg_destroy_decompress (&cinfo
);
7933 /* If we already have an XImage, free that. */
7934 x_destroy_x_image (ximg
);
7936 /* Free pixmap and colors. */
7937 x_clear_image (f
, img
);
7944 /* Create the JPEG decompression object. Let it read from fp.
7945 Read the JPEG image header. */
7946 jpeg_create_decompress (&cinfo
);
7948 if (NILP (specified_data
))
7949 jpeg_stdio_src (&cinfo
, fp
);
7951 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
7952 SBYTES (specified_data
));
7954 jpeg_read_header (&cinfo
, TRUE
);
7956 /* Customize decompression so that color quantization will be used.
7957 Start decompression. */
7958 cinfo
.quantize_colors
= TRUE
;
7959 jpeg_start_decompress (&cinfo
);
7960 width
= img
->width
= cinfo
.output_width
;
7961 height
= img
->height
= cinfo
.output_height
;
7965 /* Create X image and pixmap. */
7966 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7970 longjmp (mgr
.setjmp_buffer
, 2);
7973 /* Allocate colors. When color quantization is used,
7974 cinfo.actual_number_of_colors has been set with the number of
7975 colors generated, and cinfo.colormap is a two-dimensional array
7976 of color indices in the range 0..cinfo.actual_number_of_colors.
7977 No more than 255 colors will be generated. */
7981 if (cinfo
.out_color_components
> 2)
7982 ir
= 0, ig
= 1, ib
= 2;
7983 else if (cinfo
.out_color_components
> 1)
7984 ir
= 0, ig
= 1, ib
= 0;
7986 ir
= 0, ig
= 0, ib
= 0;
7988 /* Use the color table mechanism because it handles colors that
7989 cannot be allocated nicely. Such colors will be replaced with
7990 a default color, and we don't have to care about which colors
7991 can be freed safely, and which can't. */
7992 init_color_table ();
7993 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
7996 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
7998 /* Multiply RGB values with 255 because X expects RGB values
7999 in the range 0..0xffff. */
8000 int r
= cinfo
.colormap
[ir
][i
] << 8;
8001 int g
= cinfo
.colormap
[ig
][i
] << 8;
8002 int b
= cinfo
.colormap
[ib
][i
] << 8;
8003 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8006 /* Remember those colors actually allocated. */
8007 img
->colors
= colors_in_color_table (&img
->ncolors
);
8008 free_color_table ();
8012 row_stride
= width
* cinfo
.output_components
;
8013 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8015 for (y
= 0; y
< height
; ++y
)
8017 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8018 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8019 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8023 jpeg_finish_decompress (&cinfo
);
8024 jpeg_destroy_decompress (&cinfo
);
8028 /* Put the image into the pixmap. */
8029 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8030 x_destroy_x_image (ximg
);
8036 #endif /* HAVE_JPEG */
8040 /***********************************************************************
8042 ***********************************************************************/
8048 static int tiff_image_p
P_ ((Lisp_Object object
));
8049 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8051 /* The symbol `tiff' identifying images of this type. */
8055 /* Indices of image specification fields in tiff_format, below. */
8057 enum tiff_keyword_index
8066 TIFF_HEURISTIC_MASK
,
8070 /* Vector of image_keyword structures describing the format
8071 of valid user-defined image specifications. */
8073 static struct image_keyword tiff_format
[TIFF_LAST
] =
8075 {":type", IMAGE_SYMBOL_VALUE
, 1},
8076 {":data", IMAGE_STRING_VALUE
, 0},
8077 {":file", IMAGE_STRING_VALUE
, 0},
8078 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8079 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8080 {":relief", IMAGE_INTEGER_VALUE
, 0},
8081 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8082 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
8085 /* Structure describing the image type `tiff'. */
8087 static struct image_type tiff_type
=
8097 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8100 tiff_image_p (object
)
8103 struct image_keyword fmt
[TIFF_LAST
];
8104 bcopy (tiff_format
, fmt
, sizeof fmt
);
8106 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
)
8107 || (fmt
[TIFF_ASCENT
].count
8108 && XFASTINT (fmt
[TIFF_ASCENT
].value
) > 100))
8111 /* Must specify either the :data or :file keyword. */
8112 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8116 /* Reading from a memory buffer for TIFF images Based on the PNG
8117 memory source, but we have to provide a lot of extra functions.
8120 We really only need to implement read and seek, but I am not
8121 convinced that the TIFF library is smart enough not to destroy
8122 itself if we only hand it the function pointers we need to
8127 unsigned char *bytes
;
8134 tiff_read_from_memory (data
, buf
, size
)
8139 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8141 if (size
> src
->len
- src
->index
)
8143 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8149 tiff_write_from_memory (data
, buf
, size
)
8158 tiff_seek_in_memory (data
, off
, whence
)
8163 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8168 case SEEK_SET
: /* Go from beginning of source. */
8172 case SEEK_END
: /* Go from end of source. */
8173 idx
= src
->len
+ off
;
8176 case SEEK_CUR
: /* Go from current position. */
8177 idx
= src
->index
+ off
;
8180 default: /* Invalid `whence'. */
8184 if (idx
> src
->len
|| idx
< 0)
8192 tiff_close_memory (data
)
8200 tiff_mmap_memory (data
, pbase
, psize
)
8205 /* It is already _IN_ memory. */
8210 tiff_unmap_memory (data
, base
, size
)
8215 /* We don't need to do this. */
8219 tiff_size_of_memory (data
)
8222 return ((tiff_memory_source
*) data
)->len
;
8225 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8233 Lisp_Object file
, specified_file
;
8234 Lisp_Object specified_data
;
8236 int width
, height
, x
, y
;
8240 struct gcpro gcpro1
;
8241 tiff_memory_source memsrc
;
8243 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8244 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8248 if (NILP (specified_data
))
8250 /* Read from a file */
8251 file
= x_find_image_file (specified_file
);
8252 if (!STRINGP (file
))
8254 image_error ("Cannot find image file `%s'", file
, Qnil
);
8259 /* Try to open the image file. */
8260 tiff
= TIFFOpen (SDATA (file
), "r");
8263 image_error ("Cannot open `%s'", file
, Qnil
);
8270 /* Memory source! */
8271 memsrc
.bytes
= SDATA (specified_data
);
8272 memsrc
.len
= SBYTES (specified_data
);
8275 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8276 (TIFFReadWriteProc
) tiff_read_from_memory
,
8277 (TIFFReadWriteProc
) tiff_write_from_memory
,
8278 tiff_seek_in_memory
,
8280 tiff_size_of_memory
,
8286 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8292 /* Get width and height of the image, and allocate a raster buffer
8293 of width x height 32-bit values. */
8294 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8295 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8296 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8298 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8302 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8310 /* Create the X image and pixmap. */
8311 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8319 /* Initialize the color table. */
8320 init_color_table ();
8322 /* Process the pixel raster. Origin is in the lower-left corner. */
8323 for (y
= 0; y
< height
; ++y
)
8325 uint32
*row
= buf
+ y
* width
;
8327 for (x
= 0; x
< width
; ++x
)
8329 uint32 abgr
= row
[x
];
8330 int r
= TIFFGetR (abgr
) << 8;
8331 int g
= TIFFGetG (abgr
) << 8;
8332 int b
= TIFFGetB (abgr
) << 8;
8333 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8337 /* Remember the colors allocated for the image. Free the color table. */
8338 img
->colors
= colors_in_color_table (&img
->ncolors
);
8339 free_color_table ();
8341 /* Put the image into the pixmap, then free the X image and its buffer. */
8342 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8343 x_destroy_x_image (ximg
);
8348 img
->height
= height
;
8354 #endif /* HAVE_TIFF != 0 */
8358 /***********************************************************************
8360 ***********************************************************************/
8364 #include <gif_lib.h>
8366 static int gif_image_p
P_ ((Lisp_Object object
));
8367 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8369 /* The symbol `gif' identifying images of this type. */
8373 /* Indices of image specification fields in gif_format, below. */
8375 enum gif_keyword_index
8389 /* Vector of image_keyword structures describing the format
8390 of valid user-defined image specifications. */
8392 static struct image_keyword gif_format
[GIF_LAST
] =
8394 {":type", IMAGE_SYMBOL_VALUE
, 1},
8395 {":data", IMAGE_STRING_VALUE
, 0},
8396 {":file", IMAGE_STRING_VALUE
, 0},
8397 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8398 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8399 {":relief", IMAGE_INTEGER_VALUE
, 0},
8400 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8401 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8402 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
8405 /* Structure describing the image type `gif'. */
8407 static struct image_type gif_type
=
8416 /* Return non-zero if OBJECT is a valid GIF image specification. */
8419 gif_image_p (object
)
8422 struct image_keyword fmt
[GIF_LAST
];
8423 bcopy (gif_format
, fmt
, sizeof fmt
);
8425 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
)
8426 || (fmt
[GIF_ASCENT
].count
8427 && XFASTINT (fmt
[GIF_ASCENT
].value
) > 100))
8430 /* Must specify either the :data or :file keyword. */
8431 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8434 /* Reading a GIF image from memory
8435 Based on the PNG memory stuff to a certain extent. */
8439 unsigned char *bytes
;
8445 /* Make the current memory source available to gif_read_from_memory.
8446 It's done this way because not all versions of libungif support
8447 a UserData field in the GifFileType structure. */
8448 static gif_memory_source
*current_gif_memory_src
;
8451 gif_read_from_memory (file
, buf
, len
)
8456 gif_memory_source
*src
= current_gif_memory_src
;
8458 if (len
> src
->len
- src
->index
)
8461 bcopy (src
->bytes
+ src
->index
, buf
, len
);
8467 /* Load GIF image IMG for use on frame F. Value is non-zero if
8475 Lisp_Object file
, specified_file
;
8476 Lisp_Object specified_data
;
8477 int rc
, width
, height
, x
, y
, i
;
8479 ColorMapObject
*gif_color_map
;
8480 unsigned long pixel_colors
[256];
8482 struct gcpro gcpro1
;
8484 int ino
, image_left
, image_top
, image_width
, image_height
;
8485 gif_memory_source memsrc
;
8486 unsigned char *raster
;
8488 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8489 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8493 if (NILP (specified_data
))
8495 file
= x_find_image_file (specified_file
);
8496 if (!STRINGP (file
))
8498 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8503 /* Open the GIF file. */
8504 gif
= DGifOpenFileName (SDATA (file
));
8507 image_error ("Cannot open `%s'", file
, Qnil
);
8514 /* Read from memory! */
8515 current_gif_memory_src
= &memsrc
;
8516 memsrc
.bytes
= SDATA (specified_data
);
8517 memsrc
.len
= SBYTES (specified_data
);
8520 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
8523 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
8529 /* Read entire contents. */
8530 rc
= DGifSlurp (gif
);
8531 if (rc
== GIF_ERROR
)
8533 image_error ("Error reading `%s'", img
->spec
, Qnil
);
8534 DGifCloseFile (gif
);
8539 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
8540 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
8541 if (ino
>= gif
->ImageCount
)
8543 image_error ("Invalid image number `%s' in image `%s'",
8545 DGifCloseFile (gif
);
8550 width
= img
->width
= gif
->SWidth
;
8551 height
= img
->height
= gif
->SHeight
;
8555 /* Create the X image and pixmap. */
8556 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8559 DGifCloseFile (gif
);
8564 /* Allocate colors. */
8565 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
8567 gif_color_map
= gif
->SColorMap
;
8568 init_color_table ();
8569 bzero (pixel_colors
, sizeof pixel_colors
);
8571 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
8573 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
8574 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
8575 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
8576 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8579 img
->colors
= colors_in_color_table (&img
->ncolors
);
8580 free_color_table ();
8582 /* Clear the part of the screen image that are not covered by
8583 the image from the GIF file. Full animated GIF support
8584 requires more than can be done here (see the gif89 spec,
8585 disposal methods). Let's simply assume that the part
8586 not covered by a sub-image is in the frame's background color. */
8587 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
8588 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
8589 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
8590 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
8592 for (y
= 0; y
< image_top
; ++y
)
8593 for (x
= 0; x
< width
; ++x
)
8594 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8596 for (y
= image_top
+ image_height
; y
< height
; ++y
)
8597 for (x
= 0; x
< width
; ++x
)
8598 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8600 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
8602 for (x
= 0; x
< image_left
; ++x
)
8603 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8604 for (x
= image_left
+ image_width
; x
< width
; ++x
)
8605 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8608 /* Read the GIF image into the X image. We use a local variable
8609 `raster' here because RasterBits below is a char *, and invites
8610 problems with bytes >= 0x80. */
8611 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
8613 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
8615 static int interlace_start
[] = {0, 4, 2, 1};
8616 static int interlace_increment
[] = {8, 8, 4, 2};
8618 int row
= interlace_start
[0];
8622 for (y
= 0; y
< image_height
; y
++)
8624 if (row
>= image_height
)
8626 row
= interlace_start
[++pass
];
8627 while (row
>= image_height
)
8628 row
= interlace_start
[++pass
];
8631 for (x
= 0; x
< image_width
; x
++)
8633 int i
= raster
[(y
* image_width
) + x
];
8634 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
8638 row
+= interlace_increment
[pass
];
8643 for (y
= 0; y
< image_height
; ++y
)
8644 for (x
= 0; x
< image_width
; ++x
)
8646 int i
= raster
[y
* image_width
+ x
];
8647 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
8651 DGifCloseFile (gif
);
8653 /* Put the image into the pixmap, then free the X image and its buffer. */
8654 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8655 x_destroy_x_image (ximg
);
8662 #endif /* HAVE_GIF != 0 */
8666 /***********************************************************************
8668 ***********************************************************************/
8670 #ifdef HAVE_GHOSTSCRIPT
8671 static int gs_image_p
P_ ((Lisp_Object object
));
8672 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
8673 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
8675 /* The symbol `postscript' identifying images of this type. */
8677 Lisp_Object Qpostscript
;
8679 /* Keyword symbols. */
8681 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
8683 /* Indices of image specification fields in gs_format, below. */
8685 enum gs_keyword_index
8701 /* Vector of image_keyword structures describing the format
8702 of valid user-defined image specifications. */
8704 static struct image_keyword gs_format
[GS_LAST
] =
8706 {":type", IMAGE_SYMBOL_VALUE
, 1},
8707 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8708 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8709 {":file", IMAGE_STRING_VALUE
, 1},
8710 {":loader", IMAGE_FUNCTION_VALUE
, 0},
8711 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
8712 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8713 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8714 {":relief", IMAGE_INTEGER_VALUE
, 0},
8715 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8716 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
8719 /* Structure describing the image type `ghostscript'. */
8721 static struct image_type gs_type
=
8731 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8734 gs_clear_image (f
, img
)
8738 /* IMG->data.ptr_val may contain a recorded colormap. */
8739 xfree (img
->data
.ptr_val
);
8740 x_clear_image (f
, img
);
8744 /* Return non-zero if OBJECT is a valid Ghostscript image
8751 struct image_keyword fmt
[GS_LAST
];
8755 bcopy (gs_format
, fmt
, sizeof fmt
);
8757 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
)
8758 || (fmt
[GS_ASCENT
].count
8759 && XFASTINT (fmt
[GS_ASCENT
].value
) > 100))
8762 /* Bounding box must be a list or vector containing 4 integers. */
8763 tem
= fmt
[GS_BOUNDING_BOX
].value
;
8766 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
8767 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
8772 else if (VECTORP (tem
))
8774 if (XVECTOR (tem
)->size
!= 4)
8776 for (i
= 0; i
< 4; ++i
)
8777 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
8787 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
8796 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
8797 struct gcpro gcpro1
, gcpro2
;
8799 double in_width
, in_height
;
8800 Lisp_Object pixel_colors
= Qnil
;
8802 /* Compute pixel size of pixmap needed from the given size in the
8803 image specification. Sizes in the specification are in pt. 1 pt
8804 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8806 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
8807 in_width
= XFASTINT (pt_width
) / 72.0;
8808 img
->width
= in_width
* FRAME_W32_DISPLAY_INFO (f
)->resx
;
8809 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
8810 in_height
= XFASTINT (pt_height
) / 72.0;
8811 img
->height
= in_height
* FRAME_W32_DISPLAY_INFO (f
)->resy
;
8813 /* Create the pixmap. */
8815 xassert (img
->pixmap
== 0);
8816 img
->pixmap
= XCreatePixmap (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
8817 img
->width
, img
->height
,
8818 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
8823 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
8827 /* Call the loader to fill the pixmap. It returns a process object
8828 if successful. We do not record_unwind_protect here because
8829 other places in redisplay like calling window scroll functions
8830 don't either. Let the Lisp loader use `unwind-protect' instead. */
8831 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
8833 sprintf (buffer
, "%lu %lu",
8834 (unsigned long) FRAME_W32_WINDOW (f
),
8835 (unsigned long) img
->pixmap
);
8836 window_and_pixmap_id
= build_string (buffer
);
8838 sprintf (buffer
, "%lu %lu",
8839 FRAME_FOREGROUND_PIXEL (f
),
8840 FRAME_BACKGROUND_PIXEL (f
));
8841 pixel_colors
= build_string (buffer
);
8843 XSETFRAME (frame
, f
);
8844 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
8846 loader
= intern ("gs-load-image");
8848 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
8849 make_number (img
->width
),
8850 make_number (img
->height
),
8851 window_and_pixmap_id
,
8854 return PROCESSP (img
->data
.lisp_val
);
8858 /* Kill the Ghostscript process that was started to fill PIXMAP on
8859 frame F. Called from XTread_socket when receiving an event
8860 telling Emacs that Ghostscript has finished drawing. */
8863 x_kill_gs_process (pixmap
, f
)
8867 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
8871 /* Find the image containing PIXMAP. */
8872 for (i
= 0; i
< c
->used
; ++i
)
8873 if (c
->images
[i
]->pixmap
== pixmap
)
8876 /* Kill the GS process. We should have found PIXMAP in the image
8877 cache and its image should contain a process object. */
8878 xassert (i
< c
->used
);
8880 xassert (PROCESSP (img
->data
.lisp_val
));
8881 Fkill_process (img
->data
.lisp_val
, Qnil
);
8882 img
->data
.lisp_val
= Qnil
;
8884 /* On displays with a mutable colormap, figure out the colors
8885 allocated for the image by looking at the pixels of an XImage for
8887 class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
8888 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
8894 /* Try to get an XImage for img->pixmep. */
8895 ximg
= XGetImage (FRAME_W32_DISPLAY (f
), img
->pixmap
,
8896 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
8901 /* Initialize the color table. */
8902 init_color_table ();
8904 /* For each pixel of the image, look its color up in the
8905 color table. After having done so, the color table will
8906 contain an entry for each color used by the image. */
8907 for (y
= 0; y
< img
->height
; ++y
)
8908 for (x
= 0; x
< img
->width
; ++x
)
8910 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8911 lookup_pixel_color (f
, pixel
);
8914 /* Record colors in the image. Free color table and XImage. */
8915 img
->colors
= colors_in_color_table (&img
->ncolors
);
8916 free_color_table ();
8917 XDestroyImage (ximg
);
8919 #if 0 /* This doesn't seem to be the case. If we free the colors
8920 here, we get a BadAccess later in x_clear_image when
8921 freeing the colors. */
8922 /* We have allocated colors once, but Ghostscript has also
8923 allocated colors on behalf of us. So, to get the
8924 reference counts right, free them once. */
8927 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
8928 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
,
8929 img
->colors
, img
->ncolors
, 0);
8934 image_error ("Cannot get X image of `%s'; colors will not be freed",
8941 #endif /* HAVE_GHOSTSCRIPT */
8944 /***********************************************************************
8946 ***********************************************************************/
8948 DEFUN ("x-change-window-property", Fx_change_window_property
,
8949 Sx_change_window_property
, 2, 3, 0,
8950 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
8951 PROP and VALUE must be strings. FRAME nil or omitted means use the
8952 selected frame. Value is VALUE. */)
8953 (prop
, value
, frame
)
8954 Lisp_Object frame
, prop
, value
;
8956 #if 0 /* MAC_TODO : port window properties to Mac */
8957 struct frame
*f
= check_x_frame (frame
);
8960 CHECK_STRING (prop
);
8961 CHECK_STRING (value
);
8964 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
8965 XChangeProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
8966 prop_atom
, XA_STRING
, 8, PropModeReplace
,
8967 SDATA (value
), SCHARS (value
));
8969 /* Make sure the property is set when we return. */
8970 XFlush (FRAME_W32_DISPLAY (f
));
8973 #endif /* MAC_TODO */
8979 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
8980 Sx_delete_window_property
, 1, 2, 0,
8981 doc
: /* Remove window property PROP from X window of FRAME.
8982 FRAME nil or omitted means use the selected frame. Value is PROP. */)
8984 Lisp_Object prop
, frame
;
8986 #if 0 /* MAC_TODO : port window properties to Mac */
8988 struct frame
*f
= check_x_frame (frame
);
8991 CHECK_STRING (prop
);
8993 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
8994 XDeleteProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), prop_atom
);
8996 /* Make sure the property is removed when we return. */
8997 XFlush (FRAME_W32_DISPLAY (f
));
8999 #endif /* MAC_TODO */
9005 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9007 doc
: /* Value is the value of window property PROP on FRAME.
9008 If FRAME is nil or omitted, use the selected frame. Value is nil
9009 if FRAME hasn't a property with name PROP or if PROP has no string
9012 Lisp_Object prop
, frame
;
9014 #if 0 /* MAC_TODO : port window properties to Mac */
9016 struct frame
*f
= check_x_frame (frame
);
9019 Lisp_Object prop_value
= Qnil
;
9020 char *tmp_data
= NULL
;
9023 unsigned long actual_size
, bytes_remaining
;
9025 CHECK_STRING (prop
);
9027 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
9028 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9029 prop_atom
, 0, 0, False
, XA_STRING
,
9030 &actual_type
, &actual_format
, &actual_size
,
9031 &bytes_remaining
, (unsigned char **) &tmp_data
);
9034 int size
= bytes_remaining
;
9039 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9040 prop_atom
, 0, bytes_remaining
,
9042 &actual_type
, &actual_format
,
9043 &actual_size
, &bytes_remaining
,
9044 (unsigned char **) &tmp_data
);
9046 prop_value
= make_string (tmp_data
, size
);
9055 #endif /* MAC_TODO */
9061 /***********************************************************************
9063 ***********************************************************************/
9065 /* If non-null, an asynchronous timer that, when it expires, displays
9066 an hourglass cursor on all frames. */
9068 static struct atimer
*hourglass_atimer
;
9070 /* Non-zero means an hourglass cursor is currently shown. */
9072 static int hourglass_shown_p
;
9074 /* Number of seconds to wait before displaying an hourglass cursor. */
9076 static Lisp_Object Vhourglass_delay
;
9078 /* Default number of seconds to wait before displaying an hourglass
9081 #define DEFAULT_HOURGLASS_DELAY 1
9083 /* Function prototypes. */
9085 static void show_hourglass
P_ ((struct atimer
*));
9086 static void hide_hourglass
P_ ((void));
9089 /* Cancel a currently active hourglass timer, and start a new one. */
9094 #if 0 /* MAC_TODO: cursor shape changes. */
9096 int secs
, usecs
= 0;
9098 cancel_hourglass ();
9100 if (INTEGERP (Vhourglass_delay
)
9101 && XINT (Vhourglass_delay
) > 0)
9102 secs
= XFASTINT (Vhourglass_delay
);
9103 else if (FLOATP (Vhourglass_delay
)
9104 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9107 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9108 secs
= XFASTINT (tem
);
9109 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9112 secs
= DEFAULT_HOURGLASS_DELAY
;
9114 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9115 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9116 show_hourglass
, NULL
);
9117 #endif /* MAC_TODO */
9121 /* Cancel the hourglass cursor timer if active, hide an hourglass
9127 if (hourglass_atimer
)
9129 cancel_atimer (hourglass_atimer
);
9130 hourglass_atimer
= NULL
;
9133 if (hourglass_shown_p
)
9138 /* Timer function of hourglass_atimer. TIMER is equal to
9141 Display an hourglass cursor on all frames by mapping the frames'
9142 hourglass_window. Set the hourglass_p flag in the frames'
9143 output_data.x structure to indicate that an hourglass cursor is
9144 shown on the frames. */
9147 show_hourglass (timer
)
9148 struct atimer
*timer
;
9150 #if 0 /* MAC_TODO: cursor shape changes. */
9151 /* The timer implementation will cancel this timer automatically
9152 after this function has run. Set hourglass_atimer to null
9153 so that we know the timer doesn't have to be canceled. */
9154 hourglass_atimer
= NULL
;
9156 if (!hourglass_shown_p
)
9158 Lisp_Object rest
, frame
;
9162 FOR_EACH_FRAME (rest
, frame
)
9163 if (FRAME_W32_P (XFRAME (frame
)))
9165 struct frame
*f
= XFRAME (frame
);
9167 f
->output_data
.w32
->hourglass_p
= 1;
9169 if (!f
->output_data
.w32
->hourglass_window
)
9171 unsigned long mask
= CWCursor
;
9172 XSetWindowAttributes attrs
;
9174 attrs
.cursor
= f
->output_data
.w32
->hourglass_cursor
;
9176 f
->output_data
.w32
->hourglass_window
9177 = XCreateWindow (FRAME_X_DISPLAY (f
),
9178 FRAME_OUTER_WINDOW (f
),
9179 0, 0, 32000, 32000, 0, 0,
9185 XMapRaised (FRAME_X_DISPLAY (f
),
9186 f
->output_data
.w32
->hourglass_window
);
9187 XFlush (FRAME_X_DISPLAY (f
));
9190 hourglass_shown_p
= 1;
9193 #endif /* MAC_TODO */
9197 /* Hide the hourglass cursor on all frames, if it is currently shown. */
9202 #if 0 /* MAC_TODO: cursor shape changes. */
9203 if (hourglass_shown_p
)
9205 Lisp_Object rest
, frame
;
9208 FOR_EACH_FRAME (rest
, frame
)
9210 struct frame
*f
= XFRAME (frame
);
9213 /* Watch out for newly created frames. */
9214 && f
->output_data
.x
->hourglass_window
)
9216 XUnmapWindow (FRAME_X_DISPLAY (f
),
9217 f
->output_data
.x
->hourglass_window
);
9218 /* Sync here because XTread_socket looks at the
9219 hourglass_p flag that is reset to zero below. */
9220 XSync (FRAME_X_DISPLAY (f
), False
);
9221 f
->output_data
.x
->hourglass_p
= 0;
9225 hourglass_shown_p
= 0;
9228 #endif /* MAC_TODO */
9233 /***********************************************************************
9235 ***********************************************************************/
9237 static Lisp_Object x_create_tip_frame
P_ ((struct mac_display_info
*,
9240 /* The frame of a currently visible tooltip, or null. */
9242 Lisp_Object tip_frame
;
9244 /* If non-nil, a timer started that hides the last tooltip when it
9247 Lisp_Object tip_timer
;
9250 /* If non-nil, a vector of 3 elements containing the last args
9251 with which x-show-tip was called. See there. */
9253 Lisp_Object last_show_tip_args
;
9255 /* Create a frame for a tooltip on the display described by DPYINFO.
9256 PARMS is a list of frame parameters. Value is the frame. */
9259 x_create_tip_frame (dpyinfo
, parms
)
9260 struct mac_display_info
*dpyinfo
;
9263 #if 0 /* MAC_TODO : Mac version */
9265 Lisp_Object frame
, tem
;
9267 long window_prompting
= 0;
9269 int count
= SPECPDL_INDEX ();
9270 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9275 /* Use this general default value to start with until we know if
9276 this frame has a specified name. */
9277 Vx_resource_name
= Vinvocation_name
;
9280 kb
= dpyinfo
->kboard
;
9282 kb
= &the_only_kboard
;
9285 /* Get the name of the frame to use for resource lookup. */
9286 name
= w32_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9288 && !EQ (name
, Qunbound
)
9290 error ("Invalid frame name--not a string or nil");
9291 Vx_resource_name
= name
;
9294 GCPRO3 (parms
, name
, frame
);
9295 tip_frame
= f
= make_frame (1);
9296 XSETFRAME (frame
, f
);
9297 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9299 f
->output_method
= output_w32
;
9300 f
->output_data
.w32
=
9301 (struct w32_output
*) xmalloc (sizeof (struct w32_output
));
9302 bzero (f
->output_data
.w32
, sizeof (struct w32_output
));
9304 f
->output_data
.w32
->icon_bitmap
= -1;
9306 f
->output_data
.w32
->fontset
= -1;
9307 f
->icon_name
= Qnil
;
9310 FRAME_KBOARD (f
) = kb
;
9312 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
9313 f
->output_data
.w32
->explicit_parent
= 0;
9315 /* Set the name; the functions to which we pass f expect the name to
9317 if (EQ (name
, Qunbound
) || NILP (name
))
9319 f
->name
= build_string (dpyinfo
->x_id_name
);
9320 f
->explicit_name
= 0;
9325 f
->explicit_name
= 1;
9326 /* use the frame's title when getting resources for this frame. */
9327 specbind (Qx_resource_name
, name
);
9330 /* Extract the window parameters from the supplied values
9331 that are needed to determine window geometry. */
9335 font
= w32_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
9338 /* First, try whatever font the caller has specified. */
9341 tem
= Fquery_fontset (font
, Qnil
);
9343 font
= x_new_fontset (f
, SDATA (tem
));
9345 font
= x_new_font (f
, SDATA (font
));
9348 /* Try out a font which we hope has bold and italic variations. */
9349 if (!STRINGP (font
))
9350 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
9351 if (!STRINGP (font
))
9352 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9353 if (! STRINGP (font
))
9354 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9355 if (! STRINGP (font
))
9356 /* This was formerly the first thing tried, but it finds too many fonts
9357 and takes too long. */
9358 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
9359 /* If those didn't work, look for something which will at least work. */
9360 if (! STRINGP (font
))
9361 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
9363 if (! STRINGP (font
))
9364 font
= build_string ("fixed");
9366 x_default_parameter (f
, parms
, Qfont
, font
,
9367 "font", "Font", RES_TYPE_STRING
);
9370 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
9371 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
9373 /* This defaults to 2 in order to match xterm. We recognize either
9374 internalBorderWidth or internalBorder (which is what xterm calls
9376 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9380 value
= w32_get_arg (parms
, Qinternal_border_width
,
9381 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
9382 if (! EQ (value
, Qunbound
))
9383 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
9387 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
9388 "internalBorderWidth", "internalBorderWidth",
9391 /* Also do the stuff which must be set before the window exists. */
9392 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
9393 "foreground", "Foreground", RES_TYPE_STRING
);
9394 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
9395 "background", "Background", RES_TYPE_STRING
);
9396 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
9397 "pointerColor", "Foreground", RES_TYPE_STRING
);
9398 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
9399 "cursorColor", "Foreground", RES_TYPE_STRING
);
9400 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
9401 "borderColor", "BorderColor", RES_TYPE_STRING
);
9403 /* Init faces before x_default_parameter is called for scroll-bar
9404 parameters because that function calls x_set_scroll_bar_width,
9405 which calls change_frame_size, which calls Fset_window_buffer,
9406 which runs hooks, which call Fvertical_motion. At the end, we
9407 end up in init_iterator with a null face cache, which should not
9409 init_frame_faces (f
);
9411 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
9412 window_prompting
= x_figure_window_size (f
, parms
);
9414 if (window_prompting
& XNegative
)
9416 if (window_prompting
& YNegative
)
9417 f
->output_data
.w32
->win_gravity
= SouthEastGravity
;
9419 f
->output_data
.w32
->win_gravity
= NorthEastGravity
;
9423 if (window_prompting
& YNegative
)
9424 f
->output_data
.w32
->win_gravity
= SouthWestGravity
;
9426 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9429 f
->output_data
.w32
->size_hint_flags
= window_prompting
;
9431 XSetWindowAttributes attrs
;
9435 mask
= CWBackPixel
| CWOverrideRedirect
| CWSaveUnder
| CWEventMask
;
9436 /* Window managers looks at the override-redirect flag to
9437 determine whether or net to give windows a decoration (Xlib
9439 attrs
.override_redirect
= True
;
9440 attrs
.save_under
= True
;
9441 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
9442 /* Arrange for getting MapNotify and UnmapNotify events. */
9443 attrs
.event_mask
= StructureNotifyMask
;
9445 = FRAME_W32_WINDOW (f
)
9446 = XCreateWindow (FRAME_W32_DISPLAY (f
),
9447 FRAME_W32_DISPLAY_INFO (f
)->root_window
,
9448 /* x, y, width, height */
9452 CopyFromParent
, InputOutput
, CopyFromParent
,
9459 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
9460 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9461 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
9462 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9463 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
9464 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
9466 /* Dimensions, especially f->height, must be done via change_frame_size.
9467 Change will not be effected unless different from the current
9472 SET_FRAME_WIDTH (f
, 0);
9473 change_frame_size (f
, height
, width
, 1, 0, 0);
9475 /* Add `tooltip' frame parameter's default value. */
9476 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
9477 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
9484 /* It is now ok to make the frame official even if we get an error
9485 below. And the frame needs to be on Vframe_list or making it
9486 visible won't work. */
9487 Vframe_list
= Fcons (frame
, Vframe_list
);
9489 /* Now that the frame is official, it counts as a reference to
9491 FRAME_W32_DISPLAY_INFO (f
)->reference_count
++;
9493 return unbind_to (count
, frame
);
9494 #endif /* MAC_TODO */
9499 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
9500 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
9501 A tooltip window is a small window displaying a string.
9503 FRAME nil or omitted means use the selected frame.
9505 PARMS is an optional list of frame parameters which can be used to
9506 change the tooltip's appearance.
9508 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
9509 means use the default timeout of 5 seconds.
9511 If the list of frame parameters PARAMS contains a `left' parameters,
9512 the tooltip is displayed at that x-position. Otherwise it is
9513 displayed at the mouse position, with offset DX added (default is 5 if
9514 DX isn't specified). Likewise for the y-position; if a `top' frame
9515 parameter is specified, it determines the y-position of the tooltip
9516 window, otherwise it is displayed at the mouse position, with offset
9517 DY added (default is 10). */)
9518 (string
, frame
, parms
, timeout
, dx
, dy
)
9519 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
9524 Lisp_Object buffer
, top
, left
;
9525 struct buffer
*old_buffer
;
9526 struct text_pos pos
;
9527 int i
, width
, height
;
9528 int root_x
, root_y
, win_x
, win_y
;
9530 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
9531 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
9532 int count
= SPECPDL_INDEX ();
9534 specbind (Qinhibit_redisplay
, Qt
);
9536 GCPRO4 (string
, parms
, frame
, timeout
);
9538 CHECK_STRING (string
);
9539 f
= check_x_frame (frame
);
9541 timeout
= make_number (5);
9543 CHECK_NATNUM (timeout
);
9546 dx
= make_number (5);
9551 dy
= make_number (-10);
9555 if (NILP (last_show_tip_args
))
9556 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
9558 if (!NILP (tip_frame
))
9560 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
9561 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
9562 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
9564 if (EQ (frame
, last_frame
)
9565 && !NILP (Fequal (last_string
, string
))
9566 && !NILP (Fequal (last_parms
, parms
)))
9568 struct frame
*f
= XFRAME (tip_frame
);
9570 /* Only DX and DY have changed. */
9571 if (!NILP (tip_timer
))
9573 Lisp_Object timer
= tip_timer
;
9575 call1 (Qcancel_timer
, timer
);
9578 #if 0 /* MAC_TODO : Mac specifics */
9580 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
9581 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9582 root_x
, root_y
- PIXEL_HEIGHT (f
));
9584 #endif /* MAC_TODO */
9589 /* Hide a previous tip, if any. */
9592 ASET (last_show_tip_args
, 0, string
);
9593 ASET (last_show_tip_args
, 1, frame
);
9594 ASET (last_show_tip_args
, 2, parms
);
9596 /* Add default values to frame parameters. */
9597 if (NILP (Fassq (Qname
, parms
)))
9598 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
9599 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9600 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
9601 if (NILP (Fassq (Qborder_width
, parms
)))
9602 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
9603 if (NILP (Fassq (Qborder_color
, parms
)))
9604 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
9605 if (NILP (Fassq (Qbackground_color
, parms
)))
9606 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
9609 /* Create a frame for the tooltip, and record it in the global
9610 variable tip_frame. */
9611 frame
= x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f
), parms
);
9614 /* Set up the frame's root window. Currently we use a size of 80
9615 columns x 40 lines. If someone wants to show a larger tip, he
9616 will loose. I don't think this is a realistic case. */
9617 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
9618 w
->left
= w
->top
= make_number (0);
9619 w
->width
= make_number (80);
9620 w
->height
= make_number (40);
9622 w
->pseudo_window_p
= 1;
9624 /* Display the tooltip text in a temporary buffer. */
9625 buffer
= Fget_buffer_create (build_string (" *tip*"));
9626 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
);
9627 old_buffer
= current_buffer
;
9628 set_buffer_internal_1 (XBUFFER (buffer
));
9630 Finsert (1, &string
);
9631 clear_glyph_matrix (w
->desired_matrix
);
9632 clear_glyph_matrix (w
->current_matrix
);
9633 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
9634 try_window (FRAME_ROOT_WINDOW (f
), pos
);
9636 /* Compute width and height of the tooltip. */
9638 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
9640 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
9644 /* Stop at the first empty row at the end. */
9645 if (!row
->enabled_p
|| !row
->displays_text_p
)
9648 /* Let the row go over the full width of the frame. */
9649 row
->full_width_p
= 1;
9651 /* There's a glyph at the end of rows that is use to place
9652 the cursor there. Don't include the width of this glyph. */
9653 if (row
->used
[TEXT_AREA
])
9655 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
9656 row_width
= row
->pixel_width
- last
->pixel_width
;
9659 row_width
= row
->pixel_width
;
9661 height
+= row
->height
;
9662 width
= max (width
, row_width
);
9665 /* Add the frame's internal border to the width and height the X
9666 window should have. */
9667 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
9668 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
9670 /* Move the tooltip window where the mouse pointer is. Resize and
9672 #if 0 /* TODO : Mac specifics */
9673 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
9676 XQueryPointer (FRAME_W32_DISPLAY (f
), FRAME_W32_DISPLAY_INFO (f
)->root_window
,
9677 &root
, &child
, &root_x
, &root_y
, &win_x
, &win_y
, &pmask
);
9678 XMoveResizeWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9679 root_x
+ 5, root_y
- height
- 5, width
, height
);
9680 XMapRaised (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
9682 #endif /* MAC_TODO */
9684 /* Draw into the window. */
9685 w
->must_be_updated_p
= 1;
9686 update_single_window (w
, 1);
9688 /* Restore original current buffer. */
9689 set_buffer_internal_1 (old_buffer
);
9690 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
9693 /* Let the tip disappear after timeout seconds. */
9694 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
9695 intern ("x-hide-tip"));
9698 return unbind_to (count
, Qnil
);
9702 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
9703 doc
: /* Hide the current tooltip window, if there is any.
9704 Value is t is tooltip was open, nil otherwise. */)
9708 Lisp_Object deleted
, frame
, timer
;
9709 struct gcpro gcpro1
, gcpro2
;
9711 /* Return quickly if nothing to do. */
9712 if (NILP (tip_timer
) && NILP (tip_frame
))
9717 GCPRO2 (frame
, timer
);
9718 tip_frame
= tip_timer
= deleted
= Qnil
;
9720 count
= SPECPDL_INDEX ();
9721 specbind (Qinhibit_redisplay
, Qt
);
9722 specbind (Qinhibit_quit
, Qt
);
9725 call1 (Qcancel_timer
, timer
);
9729 Fdelete_frame (frame
, Qnil
);
9734 return unbind_to (count
, deleted
);
9739 /***********************************************************************
9740 File selection dialog
9741 ***********************************************************************/
9743 #if 0 /* MAC_TODO: can standard file dialog */
9744 extern Lisp_Object Qfile_name_history
;
9746 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
9747 doc
: /* Read file name, prompting with PROMPT in directory DIR.
9748 Use a file selection dialog.
9749 Select DEFAULT-FILENAME in the dialog's file selection box, if
9750 specified. Don't let the user enter a file name in the file
9751 selection dialog's entry field, if MUSTMATCH is non-nil. */)
9752 (prompt
, dir
, default_filename
, mustmatch
)
9753 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
9755 struct frame
*f
= SELECTED_FRAME ();
9756 Lisp_Object file
= Qnil
;
9757 int count
= SPECPDL_INDEX ();
9758 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
9759 char filename
[MAX_PATH
+ 1];
9760 char init_dir
[MAX_PATH
+ 1];
9761 int use_dialog_p
= 1;
9763 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
9764 CHECK_STRING (prompt
);
9767 /* Create the dialog with PROMPT as title, using DIR as initial
9768 directory and using "*" as pattern. */
9769 dir
= Fexpand_file_name (dir
, Qnil
);
9770 strncpy (init_dir
, SDATA (dir
), MAX_PATH
);
9771 init_dir
[MAX_PATH
] = '\0';
9772 unixtodos_filename (init_dir
);
9774 if (STRINGP (default_filename
))
9776 char *file_name_only
;
9777 char *full_path_name
= SDATA (default_filename
);
9779 unixtodos_filename (full_path_name
);
9781 file_name_only
= strrchr (full_path_name
, '\\');
9782 if (!file_name_only
)
9783 file_name_only
= full_path_name
;
9788 /* If default_file_name is a directory, don't use the open
9789 file dialog, as it does not support selecting
9791 if (!(*file_name_only
))
9795 strncpy (filename
, file_name_only
, MAX_PATH
);
9796 filename
[MAX_PATH
] = '\0';
9803 OPENFILENAME file_details
;
9804 char *filename_file
;
9806 /* Prevent redisplay. */
9807 specbind (Qinhibit_redisplay
, Qt
);
9810 bzero (&file_details
, sizeof (file_details
));
9811 file_details
.lStructSize
= sizeof (file_details
);
9812 file_details
.hwndOwner
= FRAME_W32_WINDOW (f
);
9813 file_details
.lpstrFile
= filename
;
9814 file_details
.nMaxFile
= sizeof (filename
);
9815 file_details
.lpstrInitialDir
= init_dir
;
9816 file_details
.lpstrTitle
= SDATA (prompt
);
9817 file_details
.Flags
= OFN_HIDEREADONLY
| OFN_NOCHANGEDIR
;
9819 if (!NILP (mustmatch
))
9820 file_details
.Flags
|= OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
;
9822 if (GetOpenFileName (&file_details
))
9824 dostounix_filename (filename
);
9825 file
= build_string (filename
);
9831 file
= unbind_to (count
, file
);
9833 /* Open File dialog will not allow folders to be selected, so resort
9834 to minibuffer completing reads for directories. */
9836 file
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
9837 dir
, mustmatch
, dir
, Qfile_name_history
,
9838 default_filename
, Qnil
);
9842 /* Make "Cancel" equivalent to C-g. */
9844 Fsignal (Qquit
, Qnil
);
9846 return unbind_to (count
, file
);
9848 #endif /* MAC_TODO */
9852 /***********************************************************************
9854 ***********************************************************************/
9858 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
9859 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
9863 return valid_image_p (spec
) ? Qt
: Qnil
;
9867 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
9873 if (valid_image_p (spec
))
9874 id
= lookup_image (SELECTED_FRAME (), spec
);
9877 return make_number (id
);
9880 #endif /* GLYPH_DEBUG != 0 */
9887 /* Certainly running on Mac. */
9890 /* The section below is built by the lisp expression at the top of the file,
9891 just above where these variables are declared. */
9892 /*&&& init symbols here &&&*/
9893 Qauto_raise
= intern ("auto-raise");
9894 staticpro (&Qauto_raise
);
9895 Qauto_lower
= intern ("auto-lower");
9896 staticpro (&Qauto_lower
);
9897 Qborder_color
= intern ("border-color");
9898 staticpro (&Qborder_color
);
9899 Qborder_width
= intern ("border-width");
9900 staticpro (&Qborder_width
);
9901 Qcursor_color
= intern ("cursor-color");
9902 staticpro (&Qcursor_color
);
9903 Qcursor_type
= intern ("cursor-type");
9904 staticpro (&Qcursor_type
);
9905 Qgeometry
= intern ("geometry");
9906 staticpro (&Qgeometry
);
9907 Qicon_left
= intern ("icon-left");
9908 staticpro (&Qicon_left
);
9909 Qicon_top
= intern ("icon-top");
9910 staticpro (&Qicon_top
);
9911 Qicon_type
= intern ("icon-type");
9912 staticpro (&Qicon_type
);
9913 Qicon_name
= intern ("icon-name");
9914 staticpro (&Qicon_name
);
9915 Qinternal_border_width
= intern ("internal-border-width");
9916 staticpro (&Qinternal_border_width
);
9917 Qleft
= intern ("left");
9919 Qright
= intern ("right");
9920 staticpro (&Qright
);
9921 Qmouse_color
= intern ("mouse-color");
9922 staticpro (&Qmouse_color
);
9923 Qnone
= intern ("none");
9925 Qparent_id
= intern ("parent-id");
9926 staticpro (&Qparent_id
);
9927 Qscroll_bar_width
= intern ("scroll-bar-width");
9928 staticpro (&Qscroll_bar_width
);
9929 Qsuppress_icon
= intern ("suppress-icon");
9930 staticpro (&Qsuppress_icon
);
9931 Qundefined_color
= intern ("undefined-color");
9932 staticpro (&Qundefined_color
);
9933 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
9934 staticpro (&Qvertical_scroll_bars
);
9935 Qvisibility
= intern ("visibility");
9936 staticpro (&Qvisibility
);
9937 Qwindow_id
= intern ("window-id");
9938 staticpro (&Qwindow_id
);
9939 Qx_frame_parameter
= intern ("x-frame-parameter");
9940 staticpro (&Qx_frame_parameter
);
9941 Qx_resource_name
= intern ("x-resource-name");
9942 staticpro (&Qx_resource_name
);
9943 Quser_position
= intern ("user-position");
9944 staticpro (&Quser_position
);
9945 Quser_size
= intern ("user-size");
9946 staticpro (&Quser_size
);
9947 Qscreen_gamma
= intern ("screen-gamma");
9948 staticpro (&Qscreen_gamma
);
9949 Qline_spacing
= intern ("line-spacing");
9950 staticpro (&Qline_spacing
);
9951 Qcenter
= intern ("center");
9952 staticpro (&Qcenter
);
9953 /* This is the end of symbol initialization. */
9955 Qhyper
= intern ("hyper");
9956 staticpro (&Qhyper
);
9957 Qsuper
= intern ("super");
9958 staticpro (&Qsuper
);
9959 Qmeta
= intern ("meta");
9961 Qalt
= intern ("alt");
9963 Qctrl
= intern ("ctrl");
9965 Qcontrol
= intern ("control");
9966 staticpro (&Qcontrol
);
9967 Qshift
= intern ("shift");
9968 staticpro (&Qshift
);
9970 /* Text property `display' should be nonsticky by default. */
9971 Vtext_property_default_nonsticky
9972 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
9975 Qlaplace
= intern ("laplace");
9976 staticpro (&Qlaplace
);
9978 Qface_set_after_frame_default
= intern ("face-set-after-frame-default");
9979 staticpro (&Qface_set_after_frame_default
);
9981 Fput (Qundefined_color
, Qerror_conditions
,
9982 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
9983 Fput (Qundefined_color
, Qerror_message
,
9984 build_string ("Undefined color"));
9986 init_x_parm_symbols ();
9988 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
9989 doc
: /* List of directories to search for bitmap files for w32. */);
9990 Vx_bitmap_file_path
= decode_env_path ((char *) 0, "PATH");
9992 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
9993 doc
: /* The shape of the pointer when over text.
9994 Changing the value does not affect existing frames
9995 unless you set the mouse color. */);
9996 Vx_pointer_shape
= Qnil
;
9998 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
9999 doc
: /* The name Emacs uses to look up resources; for internal use only.
10000 `x-get-resource' uses this as the first component of the instance name
10001 when requesting resource values.
10002 Emacs initially sets `x-resource-name' to the name under which Emacs
10003 was invoked, or to the value specified with the `-name' or `-rn'
10004 switches, if present. */);
10005 Vx_resource_name
= Qnil
;
10007 Vx_nontext_pointer_shape
= Qnil
;
10009 Vx_mode_pointer_shape
= Qnil
;
10011 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10012 doc
: /* The shape of the pointer when Emacs is hourglass.
10013 This variable takes effect when you create a new frame
10014 or when you set the mouse color. */);
10015 Vx_hourglass_pointer_shape
= Qnil
;
10017 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10018 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10019 display_hourglass_p
= 1;
10021 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10022 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10023 Value must be an integer or float. */);
10024 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10026 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10027 &Vx_sensitive_text_pointer_shape
,
10028 doc
: /* The shape of the pointer when over mouse-sensitive text.
10029 This variable takes effect when you create a new frame
10030 or when you set the mouse color. */);
10031 Vx_sensitive_text_pointer_shape
= Qnil
;
10033 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
10034 doc
: /* A string indicating the foreground color of the cursor box. */);
10035 Vx_cursor_fore_pixel
= Qnil
;
10037 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
10038 doc
: /* Non-nil if no window manager is in use.
10039 Emacs doesn't try to figure this out; this is always nil
10040 unless you set it to something else. */);
10041 /* We don't have any way to find this out, so set it to nil
10042 and maybe the user would like to set it to t. */
10043 Vx_no_window_manager
= Qnil
;
10045 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10046 &Vx_pixel_size_width_font_regexp
,
10047 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10049 Since Emacs gets width of a font matching with this regexp from
10050 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10051 such a font. This is especially effective for such large fonts as
10052 Chinese, Japanese, and Korean. */);
10053 Vx_pixel_size_width_font_regexp
= Qnil
;
10055 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
10056 doc
: /* Time after which cached images are removed from the cache.
10057 When an image has not been displayed this many seconds, remove it
10058 from the image cache. Value must be an integer or nil with nil
10059 meaning don't clear the cache. */);
10060 Vimage_cache_eviction_delay
= make_number (30 * 60);
10062 #if 0 /* MAC_TODO: implement get X resource */
10063 defsubr (&Sx_get_resource
);
10065 defsubr (&Sx_change_window_property
);
10066 defsubr (&Sx_delete_window_property
);
10067 defsubr (&Sx_window_property
);
10068 defsubr (&Sxw_display_color_p
);
10069 defsubr (&Sx_display_grayscale_p
);
10070 defsubr (&Sxw_color_defined_p
);
10071 defsubr (&Sxw_color_values
);
10072 defsubr (&Sx_server_max_request_size
);
10073 defsubr (&Sx_server_vendor
);
10074 defsubr (&Sx_server_version
);
10075 defsubr (&Sx_display_pixel_width
);
10076 defsubr (&Sx_display_pixel_height
);
10077 defsubr (&Sx_display_mm_width
);
10078 defsubr (&Sx_display_mm_height
);
10079 defsubr (&Sx_display_screens
);
10080 defsubr (&Sx_display_planes
);
10081 defsubr (&Sx_display_color_cells
);
10082 defsubr (&Sx_display_visual_class
);
10083 defsubr (&Sx_display_backing_store
);
10084 defsubr (&Sx_display_save_under
);
10085 #if 0 /* MAC_TODO: implement XParseGeometry */
10086 defsubr (&Sx_parse_geometry
);
10088 defsubr (&Sx_create_frame
);
10089 #if 0 /* MAC_TODO: implement network support */
10090 defsubr (&Sx_open_connection
);
10091 defsubr (&Sx_close_connection
);
10093 defsubr (&Sx_display_list
);
10094 defsubr (&Sx_synchronize
);
10096 /* Setting callback functions for fontset handler. */
10097 get_font_info_func
= x_get_font_info
;
10099 #if 0 /* This function pointer doesn't seem to be used anywhere.
10100 And the pointer assigned has the wrong type, anyway. */
10101 list_fonts_func
= x_list_fonts
;
10104 load_font_func
= x_load_font
;
10105 find_ccl_program_func
= x_find_ccl_program
;
10106 query_font_func
= x_query_font
;
10108 set_frame_fontset_func
= x_set_font
;
10109 check_window_system_func
= check_mac
;
10111 #if 0 /* MAC_TODO: Image support for Mac Images. */
10112 Qxbm
= intern ("xbm");
10114 QCtype
= intern (":type");
10115 staticpro (&QCtype
);
10116 QCconversion
= intern (":conversion");
10117 staticpro (&QCconversion
);
10118 QCheuristic_mask
= intern (":heuristic-mask");
10119 staticpro (&QCheuristic_mask
);
10120 QCcolor_symbols
= intern (":color-symbols");
10121 staticpro (&QCcolor_symbols
);
10122 QCascent
= intern (":ascent");
10123 staticpro (&QCascent
);
10124 QCmargin
= intern (":margin");
10125 staticpro (&QCmargin
);
10126 QCrelief
= intern (":relief");
10127 staticpro (&QCrelief
);
10128 Qpostscript
= intern ("postscript");
10129 staticpro (&Qpostscript
);
10130 QCloader
= intern (":loader");
10131 staticpro (&QCloader
);
10132 QCbounding_box
= intern (":bounding-box");
10133 staticpro (&QCbounding_box
);
10134 QCpt_width
= intern (":pt-width");
10135 staticpro (&QCpt_width
);
10136 QCpt_height
= intern (":pt-height");
10137 staticpro (&QCpt_height
);
10138 QCindex
= intern (":index");
10139 staticpro (&QCindex
);
10140 Qpbm
= intern ("pbm");
10144 Qxpm
= intern ("xpm");
10149 Qjpeg
= intern ("jpeg");
10150 staticpro (&Qjpeg
);
10154 Qtiff
= intern ("tiff");
10155 staticpro (&Qtiff
);
10159 Qgif
= intern ("gif");
10164 Qpng
= intern ("png");
10168 defsubr (&Sclear_image_cache
);
10171 defsubr (&Simagep
);
10172 defsubr (&Slookup_image
);
10174 #endif /* MAC_TODO */
10176 hourglass_atimer
= NULL
;
10177 hourglass_shown_p
= 0;
10179 defsubr (&Sx_show_tip
);
10180 defsubr (&Sx_hide_tip
);
10181 staticpro (&tip_timer
);
10184 #if 0 /* MAC_TODO */
10185 defsubr (&Sx_file_dialog
);
10193 image_types
= NULL
;
10194 Vimage_types
= Qnil
;
10196 define_image_type (&xbm_type
);
10197 #if 0 /* NTEMACS_TODO : Image support for W32 */
10198 define_image_type (&gs_type
);
10199 define_image_type (&pbm_type
);
10202 define_image_type (&xpm_type
);
10206 define_image_type (&jpeg_type
);
10210 define_image_type (&tiff_type
);
10214 define_image_type (&gif_type
);
10218 define_image_type (&png_type
);
10220 #endif /* NTEMACS_TODO */