1 /* Graphical user interface functions for Mac OS.
2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Contributed by Andrew Choi (akochoi@mac.com). */
37 #include "dispextern.h"
39 #include "intervals.h"
41 #include "blockinput.h"
43 #include "termhooks.h"
48 /* #include "bitmaps/gray.xbm" */
51 static unsigned char gray_bits
[] = {
54 /*#include <commdlg.h>
55 #include <shellapi.h>*/
71 /* Macros max and min defined in lisp.h conflict with those in
72 precompiled header Carbon.h. */
76 #include <Carbon/Carbon.h>
78 #define Z (current_buffer->text->z)
80 #define free unexec_free
82 #define malloc unexec_malloc
84 #define realloc unexec_realloc
86 #define min(a, b) ((a) < (b) ? (a) : (b))
88 #define max(a, b) ((a) > (b) ? (a) : (b))
90 #define init_process emacs_init_process
91 #else /* not MAC_OSX */
94 #include <TextUtils.h>
95 #endif /* not MAC_OSX */
97 /*extern void free_frame_menubar ();
98 extern double atof ();
99 extern int w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state);
100 extern int quit_char;*/
102 extern char *lispy_function_keys
[];
104 /* The gray bitmap `bitmaps/gray'. This is done because macterm.c uses
105 it, and including `bitmaps/gray' more than once is a problem when
106 config.h defines `static' as an empty replacement string. */
108 int gray_bitmap_width
= gray_width
;
109 int gray_bitmap_height
= gray_height
;
110 unsigned char *gray_bitmap_bits
= gray_bits
;
112 /* The name we're using in resource queries. */
114 Lisp_Object Vx_resource_name
;
116 /* Non-zero means we're allowed to display an hourglass cursor. */
118 int display_hourglass_p
;
120 /* The background and shape of the mouse pointer, and shape when not
121 over text or in the modeline. */
123 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
124 Lisp_Object Vx_hourglass_pointer_shape
;
126 /* The shape when over mouse-sensitive text. */
128 Lisp_Object Vx_sensitive_text_pointer_shape
;
130 /* If non-nil, the pointer shape to indicate that windows can be
131 dragged horizontally. */
133 Lisp_Object Vx_window_horizontal_drag_shape
;
135 /* Color of chars displayed in cursor box. */
137 Lisp_Object Vx_cursor_fore_pixel
;
139 /* Nonzero if using Windows. */
141 static int mac_in_use
;
143 /* Non nil if no window manager is in use. */
145 Lisp_Object Vx_no_window_manager
;
147 /* Search path for bitmap files. */
149 Lisp_Object Vx_bitmap_file_path
;
151 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
153 Lisp_Object Vx_pixel_size_width_font_regexp
;
155 /* Evaluate this expression to rebuild the section of syms_of_macfns
156 that initializes and staticpros the symbols declared below. Note
157 that Emacs 18 has a bug that keeps C-x C-e from being able to
158 evaluate this expression.
161 ;; Accumulate a list of the symbols we want to initialize from the
162 ;; declarations at the top of the file.
163 (goto-char (point-min))
164 (search-forward "/\*&&& symbols declared here &&&*\/\n")
166 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
168 (cons (buffer-substring (match-beginning 1) (match-end 1))
171 (setq symbol-list (nreverse symbol-list))
172 ;; Delete the section of syms_of_... where we initialize the symbols.
173 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
174 (let ((start (point)))
175 (while (looking-at "^ Q")
177 (kill-region start (point)))
178 ;; Write a new symbol initialization section.
180 (insert (format " %s = intern (\"" (car symbol-list)))
181 (let ((start (point)))
182 (insert (substring (car symbol-list) 1))
183 (subst-char-in-region start (point) ?_ ?-))
184 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
185 (setq symbol-list (cdr symbol-list)))))
189 /*&&& symbols declared here &&&*/
190 Lisp_Object Qauto_raise
;
191 Lisp_Object Qauto_lower
;
192 Lisp_Object Qborder_color
;
193 Lisp_Object Qborder_width
;
194 Lisp_Object Qcursor_color
;
195 Lisp_Object Qcursor_type
;
196 Lisp_Object Qgeometry
;
197 Lisp_Object Qicon_left
;
198 Lisp_Object Qicon_top
;
199 Lisp_Object Qicon_type
;
200 Lisp_Object Qicon_name
;
201 Lisp_Object Qinternal_border_width
;
204 Lisp_Object Qmouse_color
;
206 Lisp_Object Qparent_id
;
207 Lisp_Object Qscroll_bar_width
;
208 Lisp_Object Qsuppress_icon
;
209 Lisp_Object Qundefined_color
;
210 Lisp_Object Qvertical_scroll_bars
;
211 Lisp_Object Qvisibility
;
212 Lisp_Object Qwindow_id
;
213 Lisp_Object Qx_frame_parameter
;
214 Lisp_Object Qx_resource_name
;
215 Lisp_Object Quser_position
;
216 Lisp_Object Quser_size
;
217 Lisp_Object Qscreen_gamma
;
218 Lisp_Object Qline_spacing
;
220 Lisp_Object Qcancel_timer
;
226 Lisp_Object Qcontrol
;
229 extern Lisp_Object Qtop
;
230 extern Lisp_Object Qdisplay
;
231 Lisp_Object Qscroll_bar_foreground
, Qscroll_bar_background
;
232 extern Lisp_Object Qtool_bar_lines
;
234 /* These are defined in frame.c. */
235 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
236 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
, Qbuffer_predicate
, Qtitle
;
237 extern Lisp_Object Qtool_bar_lines
;
239 extern Lisp_Object Vwindow_system_version
;
241 extern Lisp_Object Qbox
;
243 Lisp_Object Qface_set_after_frame_default
;
245 extern int mac_initialized
;
247 /* Functions in macterm.c. */
248 extern void x_set_offset (struct frame
*, int, int, int);
249 extern void x_wm_set_icon_position (struct frame
*, int, int);
250 extern void x_display_cursor (struct window
*, int, int, int, int, int);
251 extern void x_set_window_size (struct frame
*, int, int, int);
252 extern void x_make_frame_visible (struct frame
*);
253 extern struct mac_display_info
*mac_term_init (Lisp_Object
, char *, char *);
254 extern struct font_info
*x_get_font_info (FRAME_PTR
, int);
255 extern struct font_info
*x_load_font (struct frame
*, char *, int);
256 extern void x_find_ccl_program (struct font_info
*);
257 extern struct font_info
*x_query_font (struct frame
*, char *);
258 extern void mac_initialize ();
260 /* compare two strings ignoring case */
263 stricmp (const char *s
, const char *t
)
265 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
268 return tolower (*s
) - tolower (*t
);
271 /* compare two strings up to n characters, ignoring case */
274 strnicmp (const char *s
, const char *t
, unsigned int n
)
276 for ( ; n
-- > 0 && tolower (*s
) == tolower (*t
); s
++, t
++)
279 return n
== 0 ? 0 : tolower (*s
) - tolower (*t
);
283 /* Error if we are not running on Mac OS. */
289 error ("Mac OS not in use or not initialized");
292 /* Nonzero if we can use mouse menus.
293 You should not call this unless HAVE_MENUS is defined. */
301 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
302 and checking validity for Mac. */
305 check_x_frame (frame
)
311 frame
= selected_frame
;
312 CHECK_LIVE_FRAME (frame
);
314 if (! FRAME_MAC_P (f
))
315 error ("non-mac frame used");
319 /* Let the user specify a display with a frame.
320 nil stands for the selected frame--or, if that is not a mac frame,
321 the first display on the list. */
323 static struct mac_display_info
*
324 check_x_display_info (frame
)
327 if (!mac_initialized
)
335 struct frame
*sf
= XFRAME (selected_frame
);
337 if (FRAME_MAC_P (sf
) && FRAME_LIVE_P (sf
))
338 return FRAME_MAC_DISPLAY_INFO (sf
);
340 return &one_mac_display_info
;
342 else if (STRINGP (frame
))
343 return x_display_info_for_name (frame
);
348 CHECK_LIVE_FRAME (frame
);
350 if (! FRAME_MAC_P (f
))
351 error ("non-mac frame used");
352 return FRAME_MAC_DISPLAY_INFO (f
);
356 /* Return the Emacs frame-object corresponding to a mac window.
357 It could be the frame's main window or an icon window. */
359 /* This function can be called during GC, so use GC_xxx type test macros. */
362 x_window_to_frame (dpyinfo
, wdesc
)
363 struct mac_display_info
*dpyinfo
;
366 Lisp_Object tail
, frame
;
369 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
372 if (!GC_FRAMEP (frame
))
375 if (!FRAME_W32_P (f
) || FRAME_MAC_DISPLAY_INFO (f
) != dpyinfo
)
377 /*if (f->output_data.w32->hourglass_window == wdesc)
380 /* MAC_TODO: Check tooltips when supported. */
381 if (FRAME_MAC_WINDOW (f
) == wdesc
)
389 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
390 id, which is just an int that this section returns. Bitmaps are
391 reference counted so they can be shared among frames.
393 Bitmap indices are guaranteed to be > 0, so a negative number can
394 be used to indicate no bitmap.
396 If you use x_create_bitmap_from_data, then you must keep track of
397 the bitmaps yourself. That is, creating a bitmap from the same
398 data more than once will not be caught. */
401 /* Functions to access the contents of a bitmap, given an id. */
404 x_bitmap_height (f
, id
)
408 return FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
412 x_bitmap_width (f
, id
)
416 return FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
419 #if 0 /* MAC_TODO : not used anywhere (?) */
421 x_bitmap_pixmap (f
, id
)
425 return (int) FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
429 /* Allocate a new bitmap record. Returns index of new record. */
432 x_allocate_bitmap_record (f
)
435 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
438 if (dpyinfo
->bitmaps
== NULL
)
440 dpyinfo
->bitmaps_size
= 10;
441 dpyinfo
->bitmaps
= (struct mac_bitmap_record
*)
442 xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct mac_bitmap_record
));
443 dpyinfo
->bitmaps_last
= 1;
447 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
448 return ++dpyinfo
->bitmaps_last
;
450 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
451 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
454 dpyinfo
->bitmaps_size
*= 2;
455 dpyinfo
->bitmaps
= (struct mac_bitmap_record
*)
456 xrealloc (dpyinfo
->bitmaps
,
457 dpyinfo
->bitmaps_size
* sizeof (struct mac_bitmap_record
));
458 return ++dpyinfo
->bitmaps_last
;
461 /* Add one reference to the reference count of the bitmap with id
465 x_reference_bitmap (f
, id
)
469 ++FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
472 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at
476 x_create_bitmap_from_data (f
, bits
, width
, height
)
479 unsigned int width
, height
;
481 struct x_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
484 /* MAC_TODO: for now fail if width is not mod 16 (toolbox requires it) */
486 id
= x_allocate_bitmap_record (f
);
491 dpyinfo
->bitmaps
[id
- 1].bitmap_data
= (char *) xmalloc (height
* width
);
492 if (! dpyinfo
->bitmaps
[id
- 1].bitmap_data
)
495 bcopy (bits
, dpyinfo
->bitmaps
[id
- 1].bitmap_data
, height
* width
);
497 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
498 dpyinfo
->bitmaps
[id
- 1].height
= height
;
499 dpyinfo
->bitmaps
[id
- 1].width
= width
;
504 /* Create bitmap from file FILE for frame F. */
507 x_create_bitmap_from_file (f
, file
)
512 #if 0 /* MAC_TODO : bitmap support */
513 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
514 unsigned int width
, height
;
516 int xhot
, yhot
, result
, id
;
522 /* Look for an existing bitmap with the same name. */
523 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
525 if (dpyinfo
->bitmaps
[id
].refcount
526 && dpyinfo
->bitmaps
[id
].file
527 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
529 ++dpyinfo
->bitmaps
[id
].refcount
;
534 /* Search bitmap-file-path for the file, if appropriate. */
535 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, Qnil
);
538 /* LoadLibraryEx won't handle special files handled by Emacs handler. */
543 filename
= (char *) SDATA (found
);
545 hinst
= LoadLibraryEx (filename
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
551 result
= XReadBitmapFile (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
552 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
553 if (result
!= BitmapSuccess
)
556 id
= x_allocate_bitmap_record (f
);
557 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
558 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
559 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SCHARS (file
) + 1);
560 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
561 dpyinfo
->bitmaps
[id
- 1].height
= height
;
562 dpyinfo
->bitmaps
[id
- 1].width
= width
;
563 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
566 #endif /* MAC_TODO */
569 /* Remove reference to bitmap with id number ID. */
572 x_destroy_bitmap (f
, id
)
576 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
580 --dpyinfo
->bitmaps
[id
- 1].refcount
;
581 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
584 dpyinfo
->bitmaps
[id
- 1].bitmap_data
= NULL
;
590 /* Free all the bitmaps for the display specified by DPYINFO. */
593 x_destroy_all_bitmaps (dpyinfo
)
594 struct mac_display_info
*dpyinfo
;
597 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
598 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
599 xfree (dpyinfo
->bitmaps
[i
].bitmap_data
);
600 dpyinfo
->bitmaps_last
= 0;
603 /* Connect the frame-parameter names for W32 frames
604 to the ways of passing the parameter values to the window system.
606 The name of a parameter, as a Lisp symbol,
607 has an `x-frame-parameter' property which is an integer in Lisp
608 but can be interpreted as an `enum x_frame_parm' in C. */
610 struct x_frame_parm_table
613 void (*setter
) P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
616 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
617 static void x_set_line_spacing
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
618 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
619 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
620 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
621 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
622 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
623 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
624 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
625 void x_set_font
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
626 void x_set_border_width
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
627 void x_set_internal_border_width
P_ ((struct frame
*, Lisp_Object
,
629 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
630 void x_set_autoraise
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
631 void x_set_autolower
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
632 void x_set_vertical_scroll_bars
P_ ((struct frame
*, Lisp_Object
,
634 void x_set_visibility
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
635 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
636 void x_set_scroll_bar_width
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
637 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
638 void x_set_unsplittable
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
639 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
640 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
642 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
644 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
649 static void x_set_screen_gamma
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
651 static struct x_frame_parm_table x_frame_parms
[] =
653 "auto-raise", x_set_autoraise
,
654 "auto-lower", x_set_autolower
,
655 "background-color", x_set_background_color
,
656 "border-color", x_set_border_color
,
657 "border-width", x_set_border_width
,
658 "cursor-color", x_set_cursor_color
,
659 "cursor-type", x_set_cursor_type
,
661 "foreground-color", x_set_foreground_color
,
662 "icon-name", x_set_icon_name
,
663 #if 0 /* MAC_TODO: no icons for Mac */
664 "icon-type", x_set_icon_type
,
666 "internal-border-width", x_set_internal_border_width
,
667 "menu-bar-lines", x_set_menu_bar_lines
,
668 "mouse-color", x_set_mouse_color
,
669 "name", x_explicitly_set_name
,
670 "scroll-bar-width", x_set_scroll_bar_width
,
671 "title", x_set_title
,
672 "unsplittable", x_set_unsplittable
,
673 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
674 "visibility", x_set_visibility
,
675 "tool-bar-lines", x_set_tool_bar_lines
,
676 #if 0 /* MAC_TODO: cannot set color of scroll bar on the Mac? */
677 "scroll-bar-foreground", x_set_scroll_bar_foreground
,
678 "scroll-bar-background", x_set_scroll_bar_background
,
680 "screen-gamma", x_set_screen_gamma
,
681 "line-spacing", x_set_line_spacing
684 /* Attach the `x-frame-parameter' properties to
685 the Lisp symbol names of parameters relevant to Mac. */
688 init_x_parm_symbols ()
692 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
693 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
697 /* Change the parameters of frame F as specified by ALIST.
698 If a parameter is not specially recognized, do nothing;
699 otherwise call the `x_set_...' function for that parameter. */
702 x_set_frame_parameters (f
, alist
)
708 /* If both of these parameters are present, it's more efficient to
709 set them both at once. So we wait until we've looked at the
710 entire list before we set them. */
714 Lisp_Object left
, top
;
716 /* Same with these. */
717 Lisp_Object icon_left
, icon_top
;
719 /* Record in these vectors all the parms specified. */
723 int left_no_change
= 0, top_no_change
= 0;
724 int icon_left_no_change
= 0, icon_top_no_change
= 0;
726 struct gcpro gcpro1
, gcpro2
;
729 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
732 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
733 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
735 /* Extract parm names and values into those vectors. */
738 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
743 parms
[i
] = Fcar (elt
);
744 values
[i
] = Fcdr (elt
);
747 /* TAIL and ALIST are not used again below here. */
750 GCPRO2 (*parms
, *values
);
754 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
755 because their values appear in VALUES and strings are not valid. */
756 top
= left
= Qunbound
;
757 icon_left
= icon_top
= Qunbound
;
759 /* Provide default values for HEIGHT and WIDTH. */
760 if (FRAME_NEW_WIDTH (f
))
761 width
= FRAME_NEW_WIDTH (f
);
763 width
= FRAME_WIDTH (f
);
765 if (FRAME_NEW_HEIGHT (f
))
766 height
= FRAME_NEW_HEIGHT (f
);
768 height
= FRAME_HEIGHT (f
);
770 /* Process foreground_color and background_color before anything else.
771 They are independent of other properties, but other properties (e.g.,
772 cursor_color) are dependent upon them. */
773 for (p
= 0; p
< i
; p
++)
775 Lisp_Object prop
, val
;
779 if (EQ (prop
, Qforeground_color
) || EQ (prop
, Qbackground_color
))
781 register Lisp_Object param_index
, old_value
;
783 param_index
= Fget (prop
, Qx_frame_parameter
);
784 old_value
= get_frame_param (f
, prop
);
785 store_frame_param (f
, prop
, val
);
786 if (NATNUMP (param_index
)
787 && (XFASTINT (param_index
)
788 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
789 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
793 /* Now process them in reverse of specified order. */
794 for (i
--; i
>= 0; i
--)
796 Lisp_Object prop
, val
;
801 if (EQ (prop
, Qwidth
) && NUMBERP (val
))
802 width
= XFASTINT (val
);
803 else if (EQ (prop
, Qheight
) && NUMBERP (val
))
804 height
= XFASTINT (val
);
805 else if (EQ (prop
, Qtop
))
807 else if (EQ (prop
, Qleft
))
809 else if (EQ (prop
, Qicon_top
))
811 else if (EQ (prop
, Qicon_left
))
813 else if (EQ (prop
, Qforeground_color
) || EQ (prop
, Qbackground_color
))
814 /* Processed above. */
818 register Lisp_Object param_index
, old_value
;
820 param_index
= Fget (prop
, Qx_frame_parameter
);
821 old_value
= get_frame_param (f
, prop
);
822 store_frame_param (f
, prop
, val
);
823 if (NATNUMP (param_index
)
824 && (XFASTINT (param_index
)
825 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
826 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
830 /* Don't die if just one of these was set. */
831 if (EQ (left
, Qunbound
))
834 if (f
->output_data
.mac
->left_pos
< 0)
836 Fcons (make_number (f
->output_data
.mac
->left_pos
),
839 XSETINT (left
, f
->output_data
.mac
->left_pos
);
841 if (EQ (top
, Qunbound
))
844 if (f
->output_data
.mac
->top_pos
< 0)
846 Fcons (make_number (f
->output_data
.mac
->top_pos
), Qnil
));
848 XSETINT (top
, f
->output_data
.mac
->top_pos
);
851 /* If one of the icon positions was not set, preserve or default it. */
852 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
854 icon_left_no_change
= 1;
855 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
856 if (NILP (icon_left
))
857 XSETINT (icon_left
, 0);
859 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
861 icon_top_no_change
= 1;
862 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
864 XSETINT (icon_top
, 0);
867 /* Don't set these parameters unless they've been explicitly
868 specified. The window might be mapped or resized while we're in
869 this function, and we don't want to override that unless the lisp
870 code has asked for it.
872 Don't set these parameters unless they actually differ from the
873 window's current parameters; the window may not actually exist
878 check_frame_size (f
, &height
, &width
);
880 XSETFRAME (frame
, f
);
882 if (width
!= FRAME_WIDTH (f
)
883 || height
!= FRAME_HEIGHT (f
)
884 || FRAME_NEW_HEIGHT (f
) || FRAME_NEW_WIDTH (f
))
885 Fset_frame_size (frame
, make_number (width
), make_number (height
));
887 if ((!NILP (left
) || !NILP (top
))
888 && ! (left_no_change
&& top_no_change
)
889 && ! (NUMBERP (left
) && XINT (left
) == f
->output_data
.mac
->left_pos
890 && NUMBERP (top
) && XINT (top
) == f
->output_data
.mac
->top_pos
))
895 /* Record the signs. */
896 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
897 if (EQ (left
, Qminus
))
898 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
899 else if (INTEGERP (left
))
901 leftpos
= XINT (left
);
903 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
905 else if (CONSP (left
) && EQ (XCAR (left
), Qminus
)
906 && CONSP (XCDR (left
))
907 && INTEGERP (XCAR (XCDR (left
))))
909 leftpos
= - XINT (XCAR (XCDR (left
)));
910 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
912 else if (CONSP (left
) && EQ (XCAR (left
), Qplus
)
913 && CONSP (XCDR (left
))
914 && INTEGERP (XCAR (XCDR (left
))))
916 leftpos
= XINT (XCAR (XCDR (left
)));
919 if (EQ (top
, Qminus
))
920 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
921 else if (INTEGERP (top
))
925 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
927 else if (CONSP (top
) && EQ (XCAR (top
), Qminus
)
928 && CONSP (XCDR (top
))
929 && INTEGERP (XCAR (XCDR (top
))))
931 toppos
= - XINT (XCAR (XCDR (top
)));
932 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
934 else if (CONSP (top
) && EQ (XCAR (top
), Qplus
)
935 && CONSP (XCDR (top
))
936 && INTEGERP (XCAR (XCDR (top
))))
938 toppos
= XINT (XCAR (XCDR (top
)));
942 /* Store the numeric value of the position. */
943 f
->output_data
.mac
->top_pos
= toppos
;
944 f
->output_data
.mac
->left_pos
= leftpos
;
946 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
948 /* Actually set that position, and convert to absolute. */
949 x_set_offset (f
, leftpos
, toppos
, -1);
952 if ((!NILP (icon_left
) || !NILP (icon_top
))
953 && ! (icon_left_no_change
&& icon_top_no_change
))
954 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
960 /* Store the screen positions of frame F into XPTR and YPTR.
961 These are the positions of the containing window manager window,
962 not Emacs's own window. */
965 x_real_positions (f
, xptr
, yptr
)
972 #ifdef TARGET_API_MAC_CARBON
976 GetWindowPortBounds (f
->output_data
.mac
->mWP
, &r
);
977 SetPt (&pt
, r
.left
, r
.top
);
979 #else /* not TARGET_API_MAC_CARBON */
981 f
->output_data
.mac
->mWP
->portRect
.left
,
982 f
->output_data
.mac
->mWP
->portRect
.top
);
983 #endif /* not TARGET_API_MAC_CARBON */
992 /* Insert a description of internally-recorded parameters of frame X
993 into the parameter alist *ALISTPTR that is to be given to the user.
994 Only parameters that are specific to Mac and whose values are not
995 correctly recorded in the frame's param_alist need to be considered
999 x_report_frame_params (f
, alistptr
)
1001 Lisp_Object
*alistptr
;
1006 /* Represent negative positions (off the top or left screen edge)
1007 in a way that Fmodify_frame_parameters will understand correctly. */
1008 XSETINT (tem
, f
->output_data
.mac
->left_pos
);
1009 if (f
->output_data
.mac
->left_pos
>= 0)
1010 store_in_alist (alistptr
, Qleft
, tem
);
1012 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1014 XSETINT (tem
, f
->output_data
.mac
->top_pos
);
1015 if (f
->output_data
.mac
->top_pos
>= 0)
1016 store_in_alist (alistptr
, Qtop
, tem
);
1018 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1020 store_in_alist (alistptr
, Qborder_width
,
1021 make_number (f
->output_data
.mac
->border_width
));
1022 store_in_alist (alistptr
, Qinternal_border_width
,
1023 make_number (f
->output_data
.mac
->internal_border_width
));
1024 sprintf (buf
, "%ld", (long) FRAME_MAC_WINDOW (f
));
1025 store_in_alist (alistptr
, Qwindow_id
,
1026 build_string (buf
));
1027 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
1028 FRAME_SAMPLE_VISIBILITY (f
);
1029 store_in_alist (alistptr
, Qvisibility
,
1030 (FRAME_VISIBLE_P (f
) ? Qt
1031 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1032 store_in_alist (alistptr
, Qdisplay
,
1033 XCAR (FRAME_MAC_DISPLAY_INFO (f
)->name_list_element
));
1036 /* The default colors for the Mac color map */
1037 typedef struct colormap_t
1039 unsigned long color
;
1043 colormap_t mac_color_map
[] =
1045 { RGB_TO_ULONG(255, 250, 250), "snow" },
1046 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
1047 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
1048 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
1049 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
1050 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
1051 { RGB_TO_ULONG(255, 250, 240), "floral white" },
1052 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
1053 { RGB_TO_ULONG(253, 245, 230), "old lace" },
1054 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
1055 { RGB_TO_ULONG(250, 240, 230), "linen" },
1056 { RGB_TO_ULONG(250, 235, 215), "antique white" },
1057 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
1058 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
1059 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
1060 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
1061 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
1062 { RGB_TO_ULONG(255, 228, 196), "bisque" },
1063 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
1064 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
1065 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
1066 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
1067 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
1068 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
1069 { RGB_TO_ULONG(255, 255, 240), "ivory" },
1070 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
1071 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
1072 { RGB_TO_ULONG(255, 245, 238), "seashell" },
1073 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
1074 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
1075 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
1076 { RGB_TO_ULONG(240, 255, 255), "azure" },
1077 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
1078 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
1079 { RGB_TO_ULONG(230, 230, 250), "lavender" },
1080 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
1081 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
1082 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
1083 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
1084 { RGB_TO_ULONG(255, 255, 255), "white" },
1085 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
1086 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
1087 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
1088 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
1089 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
1090 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
1091 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
1092 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
1093 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
1094 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
1095 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
1096 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
1097 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
1098 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
1099 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
1100 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
1101 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
1102 { RGB_TO_ULONG(190, 190, 190), "gray" },
1103 { RGB_TO_ULONG(190, 190, 190), "grey" },
1104 { RGB_TO_ULONG(211, 211, 211), "light grey" },
1105 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
1106 { RGB_TO_ULONG(211, 211, 211), "light gray" },
1107 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
1108 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
1109 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
1110 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
1111 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
1112 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
1113 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
1114 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
1115 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
1116 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
1117 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
1118 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
1119 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
1120 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
1121 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
1122 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
1123 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
1124 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
1125 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
1126 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
1127 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
1128 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
1129 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
1130 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
1131 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
1132 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
1133 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
1134 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
1135 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
1136 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
1137 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
1138 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
1139 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
1140 { RGB_TO_ULONG(173, 216, 230), "light blue" },
1141 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
1142 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
1143 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
1144 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
1145 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
1146 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
1147 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
1148 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
1149 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
1150 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
1151 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
1152 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
1153 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
1154 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
1155 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
1156 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
1157 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
1158 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
1159 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
1160 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
1161 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
1162 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
1163 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
1164 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
1165 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
1166 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
1167 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
1168 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
1169 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
1170 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
1171 { RGB_TO_ULONG(152, 251, 152), "pale green" },
1172 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
1173 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
1174 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
1175 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
1176 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
1177 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
1178 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
1179 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
1180 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
1181 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
1182 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
1183 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
1184 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
1185 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
1186 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
1187 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
1188 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
1189 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
1190 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
1191 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
1192 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
1193 { RGB_TO_ULONG(240, 230, 140), "khaki" },
1194 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
1195 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
1196 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
1197 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
1198 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
1199 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
1200 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
1201 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
1202 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
1203 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
1204 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
1205 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
1206 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
1207 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
1208 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
1209 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
1210 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
1211 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
1212 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
1213 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
1214 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
1215 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
1216 { RGB_TO_ULONG(245, 245, 220), "beige" },
1217 { RGB_TO_ULONG(245, 222, 179), "wheat" },
1218 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
1219 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
1220 { RGB_TO_ULONG(210, 180, 140), "tan" },
1221 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
1222 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
1223 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
1224 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
1225 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
1226 { RGB_TO_ULONG(250, 128, 114), "salmon" },
1227 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
1228 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
1229 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
1230 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
1231 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
1232 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
1233 { RGB_TO_ULONG(240, 128, 128), "light coral" },
1234 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
1235 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
1236 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
1237 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
1238 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
1239 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
1240 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
1241 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
1242 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
1243 { RGB_TO_ULONG(255, 192, 203), "pink" },
1244 { RGB_TO_ULONG(255, 182, 193), "light pink" },
1245 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
1246 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
1247 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
1248 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
1249 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
1250 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
1251 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
1252 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
1253 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
1254 { RGB_TO_ULONG(238, 130, 238), "violet" },
1255 { RGB_TO_ULONG(221, 160, 221), "plum" },
1256 { RGB_TO_ULONG(218, 112, 214), "orchid" },
1257 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
1258 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
1259 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
1260 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
1261 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
1262 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
1263 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
1264 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
1265 { RGB_TO_ULONG(160, 32 , 240), "purple" },
1266 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
1267 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
1268 { RGB_TO_ULONG(216, 191, 216), "thistle" },
1269 { RGB_TO_ULONG(255, 250, 250), "snow1" },
1270 { RGB_TO_ULONG(238, 233, 233), "snow2" },
1271 { RGB_TO_ULONG(205, 201, 201), "snow3" },
1272 { RGB_TO_ULONG(139, 137, 137), "snow4" },
1273 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
1274 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
1275 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
1276 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
1277 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
1278 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
1279 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
1280 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
1281 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
1282 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
1283 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
1284 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
1285 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
1286 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
1287 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
1288 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
1289 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
1290 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
1291 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
1292 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
1293 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
1294 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
1295 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
1296 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
1297 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
1298 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
1299 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
1300 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
1301 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
1302 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
1303 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
1304 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
1305 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
1306 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
1307 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
1308 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
1309 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
1310 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
1311 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
1312 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
1313 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
1314 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
1315 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
1316 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
1317 { RGB_TO_ULONG(240, 255, 255), "azure1" },
1318 { RGB_TO_ULONG(224, 238, 238), "azure2" },
1319 { RGB_TO_ULONG(193, 205, 205), "azure3" },
1320 { RGB_TO_ULONG(131, 139, 139), "azure4" },
1321 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
1322 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
1323 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
1324 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
1325 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
1326 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
1327 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
1328 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
1329 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
1330 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
1331 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
1332 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
1333 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
1334 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
1335 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
1336 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
1337 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
1338 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
1339 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
1340 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
1341 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
1342 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
1343 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
1344 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
1345 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
1346 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
1347 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
1348 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
1349 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
1350 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
1351 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
1352 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
1353 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
1354 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
1355 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
1356 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
1357 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
1358 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
1359 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
1360 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
1361 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
1362 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
1363 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
1364 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
1365 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
1366 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
1367 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
1368 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
1369 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
1370 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
1371 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
1372 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
1373 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
1374 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
1375 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
1376 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
1377 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
1378 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
1379 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
1380 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
1381 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
1382 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
1383 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
1384 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
1385 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
1386 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
1387 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
1388 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
1389 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
1390 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
1391 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
1392 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
1393 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
1394 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
1395 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
1396 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
1397 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
1398 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
1399 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
1400 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
1401 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
1402 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
1403 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
1404 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
1405 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
1406 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
1407 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
1408 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
1409 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
1410 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
1411 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
1412 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
1413 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
1414 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
1415 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
1416 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
1417 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
1418 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
1419 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
1420 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
1421 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
1422 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
1423 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
1424 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
1425 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
1426 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
1427 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
1428 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
1429 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
1430 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
1431 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
1432 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
1433 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
1434 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
1435 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
1436 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
1437 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
1438 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
1439 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
1440 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
1441 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
1442 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
1443 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
1444 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
1445 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
1446 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
1447 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
1448 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
1449 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
1450 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
1451 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
1452 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
1453 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
1454 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
1455 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
1456 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
1457 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
1458 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
1459 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
1460 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
1461 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
1462 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
1463 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
1464 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
1465 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
1466 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
1467 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
1468 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
1469 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
1470 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
1471 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
1472 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
1473 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
1474 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
1475 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
1476 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
1477 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
1478 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
1479 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
1480 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
1481 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
1482 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
1483 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
1484 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
1485 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
1486 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
1487 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
1488 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
1489 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
1490 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
1491 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
1492 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
1493 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
1494 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
1495 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
1496 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
1497 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
1498 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
1499 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
1500 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
1501 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
1502 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
1503 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
1504 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
1505 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
1506 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
1507 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
1508 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
1509 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
1510 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
1511 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
1512 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
1513 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
1514 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
1515 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
1516 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
1517 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
1518 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
1519 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
1520 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
1521 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
1522 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
1523 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
1524 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
1525 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
1526 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
1527 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
1528 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
1529 { RGB_TO_ULONG(255, 181, 197), "pink1" },
1530 { RGB_TO_ULONG(238, 169, 184), "pink2" },
1531 { RGB_TO_ULONG(205, 145, 158), "pink3" },
1532 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
1533 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
1534 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
1535 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
1536 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
1537 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
1538 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
1539 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
1540 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
1541 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
1542 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
1543 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
1544 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
1545 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
1546 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
1547 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
1548 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
1549 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
1550 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
1551 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
1552 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
1553 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
1554 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
1555 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
1556 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
1557 { RGB_TO_ULONG(255, 187, 255), "plum1" },
1558 { RGB_TO_ULONG(238, 174, 238), "plum2" },
1559 { RGB_TO_ULONG(205, 150, 205), "plum3" },
1560 { RGB_TO_ULONG(139, 102, 139), "plum4" },
1561 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
1562 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
1563 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
1564 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
1565 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
1566 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
1567 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
1568 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
1569 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
1570 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
1571 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
1572 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
1573 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
1574 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
1575 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
1576 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
1577 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
1578 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
1579 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
1580 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
1581 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
1582 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
1583 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
1584 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
1585 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
1586 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
1587 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
1588 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
1589 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
1590 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
1591 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
1592 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
1593 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
1594 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
1595 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
1596 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
1597 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
1598 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
1599 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
1600 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
1601 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
1602 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
1603 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
1604 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
1605 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
1606 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
1607 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
1608 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
1609 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
1610 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
1611 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
1612 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
1613 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
1614 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
1615 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
1616 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
1617 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
1618 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
1619 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
1620 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
1621 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
1622 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
1623 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
1624 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
1625 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
1626 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
1627 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
1628 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
1629 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
1630 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
1631 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
1632 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
1633 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
1634 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
1635 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
1636 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
1637 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
1638 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
1639 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
1640 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
1641 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
1642 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
1643 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
1644 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
1645 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
1646 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
1647 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
1648 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
1649 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
1650 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
1651 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
1652 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
1653 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
1654 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
1655 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
1656 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
1657 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
1658 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
1659 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
1660 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
1661 { RGB_TO_ULONG(102, 102, 102), "gray40" },
1662 { RGB_TO_ULONG(102, 102, 102), "grey40" },
1663 { RGB_TO_ULONG(105, 105, 105), "gray41" },
1664 { RGB_TO_ULONG(105, 105, 105), "grey41" },
1665 { RGB_TO_ULONG(107, 107, 107), "gray42" },
1666 { RGB_TO_ULONG(107, 107, 107), "grey42" },
1667 { RGB_TO_ULONG(110, 110, 110), "gray43" },
1668 { RGB_TO_ULONG(110, 110, 110), "grey43" },
1669 { RGB_TO_ULONG(112, 112, 112), "gray44" },
1670 { RGB_TO_ULONG(112, 112, 112), "grey44" },
1671 { RGB_TO_ULONG(115, 115, 115), "gray45" },
1672 { RGB_TO_ULONG(115, 115, 115), "grey45" },
1673 { RGB_TO_ULONG(117, 117, 117), "gray46" },
1674 { RGB_TO_ULONG(117, 117, 117), "grey46" },
1675 { RGB_TO_ULONG(120, 120, 120), "gray47" },
1676 { RGB_TO_ULONG(120, 120, 120), "grey47" },
1677 { RGB_TO_ULONG(122, 122, 122), "gray48" },
1678 { RGB_TO_ULONG(122, 122, 122), "grey48" },
1679 { RGB_TO_ULONG(125, 125, 125), "gray49" },
1680 { RGB_TO_ULONG(125, 125, 125), "grey49" },
1681 { RGB_TO_ULONG(127, 127, 127), "gray50" },
1682 { RGB_TO_ULONG(127, 127, 127), "grey50" },
1683 { RGB_TO_ULONG(130, 130, 130), "gray51" },
1684 { RGB_TO_ULONG(130, 130, 130), "grey51" },
1685 { RGB_TO_ULONG(133, 133, 133), "gray52" },
1686 { RGB_TO_ULONG(133, 133, 133), "grey52" },
1687 { RGB_TO_ULONG(135, 135, 135), "gray53" },
1688 { RGB_TO_ULONG(135, 135, 135), "grey53" },
1689 { RGB_TO_ULONG(138, 138, 138), "gray54" },
1690 { RGB_TO_ULONG(138, 138, 138), "grey54" },
1691 { RGB_TO_ULONG(140, 140, 140), "gray55" },
1692 { RGB_TO_ULONG(140, 140, 140), "grey55" },
1693 { RGB_TO_ULONG(143, 143, 143), "gray56" },
1694 { RGB_TO_ULONG(143, 143, 143), "grey56" },
1695 { RGB_TO_ULONG(145, 145, 145), "gray57" },
1696 { RGB_TO_ULONG(145, 145, 145), "grey57" },
1697 { RGB_TO_ULONG(148, 148, 148), "gray58" },
1698 { RGB_TO_ULONG(148, 148, 148), "grey58" },
1699 { RGB_TO_ULONG(150, 150, 150), "gray59" },
1700 { RGB_TO_ULONG(150, 150, 150), "grey59" },
1701 { RGB_TO_ULONG(153, 153, 153), "gray60" },
1702 { RGB_TO_ULONG(153, 153, 153), "grey60" },
1703 { RGB_TO_ULONG(156, 156, 156), "gray61" },
1704 { RGB_TO_ULONG(156, 156, 156), "grey61" },
1705 { RGB_TO_ULONG(158, 158, 158), "gray62" },
1706 { RGB_TO_ULONG(158, 158, 158), "grey62" },
1707 { RGB_TO_ULONG(161, 161, 161), "gray63" },
1708 { RGB_TO_ULONG(161, 161, 161), "grey63" },
1709 { RGB_TO_ULONG(163, 163, 163), "gray64" },
1710 { RGB_TO_ULONG(163, 163, 163), "grey64" },
1711 { RGB_TO_ULONG(166, 166, 166), "gray65" },
1712 { RGB_TO_ULONG(166, 166, 166), "grey65" },
1713 { RGB_TO_ULONG(168, 168, 168), "gray66" },
1714 { RGB_TO_ULONG(168, 168, 168), "grey66" },
1715 { RGB_TO_ULONG(171, 171, 171), "gray67" },
1716 { RGB_TO_ULONG(171, 171, 171), "grey67" },
1717 { RGB_TO_ULONG(173, 173, 173), "gray68" },
1718 { RGB_TO_ULONG(173, 173, 173), "grey68" },
1719 { RGB_TO_ULONG(176, 176, 176), "gray69" },
1720 { RGB_TO_ULONG(176, 176, 176), "grey69" },
1721 { RGB_TO_ULONG(179, 179, 179), "gray70" },
1722 { RGB_TO_ULONG(179, 179, 179), "grey70" },
1723 { RGB_TO_ULONG(181, 181, 181), "gray71" },
1724 { RGB_TO_ULONG(181, 181, 181), "grey71" },
1725 { RGB_TO_ULONG(184, 184, 184), "gray72" },
1726 { RGB_TO_ULONG(184, 184, 184), "grey72" },
1727 { RGB_TO_ULONG(186, 186, 186), "gray73" },
1728 { RGB_TO_ULONG(186, 186, 186), "grey73" },
1729 { RGB_TO_ULONG(189, 189, 189), "gray74" },
1730 { RGB_TO_ULONG(189, 189, 189), "grey74" },
1731 { RGB_TO_ULONG(191, 191, 191), "gray75" },
1732 { RGB_TO_ULONG(191, 191, 191), "grey75" },
1733 { RGB_TO_ULONG(194, 194, 194), "gray76" },
1734 { RGB_TO_ULONG(194, 194, 194), "grey76" },
1735 { RGB_TO_ULONG(196, 196, 196), "gray77" },
1736 { RGB_TO_ULONG(196, 196, 196), "grey77" },
1737 { RGB_TO_ULONG(199, 199, 199), "gray78" },
1738 { RGB_TO_ULONG(199, 199, 199), "grey78" },
1739 { RGB_TO_ULONG(201, 201, 201), "gray79" },
1740 { RGB_TO_ULONG(201, 201, 201), "grey79" },
1741 { RGB_TO_ULONG(204, 204, 204), "gray80" },
1742 { RGB_TO_ULONG(204, 204, 204), "grey80" },
1743 { RGB_TO_ULONG(207, 207, 207), "gray81" },
1744 { RGB_TO_ULONG(207, 207, 207), "grey81" },
1745 { RGB_TO_ULONG(209, 209, 209), "gray82" },
1746 { RGB_TO_ULONG(209, 209, 209), "grey82" },
1747 { RGB_TO_ULONG(212, 212, 212), "gray83" },
1748 { RGB_TO_ULONG(212, 212, 212), "grey83" },
1749 { RGB_TO_ULONG(214, 214, 214), "gray84" },
1750 { RGB_TO_ULONG(214, 214, 214), "grey84" },
1751 { RGB_TO_ULONG(217, 217, 217), "gray85" },
1752 { RGB_TO_ULONG(217, 217, 217), "grey85" },
1753 { RGB_TO_ULONG(219, 219, 219), "gray86" },
1754 { RGB_TO_ULONG(219, 219, 219), "grey86" },
1755 { RGB_TO_ULONG(222, 222, 222), "gray87" },
1756 { RGB_TO_ULONG(222, 222, 222), "grey87" },
1757 { RGB_TO_ULONG(224, 224, 224), "gray88" },
1758 { RGB_TO_ULONG(224, 224, 224), "grey88" },
1759 { RGB_TO_ULONG(227, 227, 227), "gray89" },
1760 { RGB_TO_ULONG(227, 227, 227), "grey89" },
1761 { RGB_TO_ULONG(229, 229, 229), "gray90" },
1762 { RGB_TO_ULONG(229, 229, 229), "grey90" },
1763 { RGB_TO_ULONG(232, 232, 232), "gray91" },
1764 { RGB_TO_ULONG(232, 232, 232), "grey91" },
1765 { RGB_TO_ULONG(235, 235, 235), "gray92" },
1766 { RGB_TO_ULONG(235, 235, 235), "grey92" },
1767 { RGB_TO_ULONG(237, 237, 237), "gray93" },
1768 { RGB_TO_ULONG(237, 237, 237), "grey93" },
1769 { RGB_TO_ULONG(240, 240, 240), "gray94" },
1770 { RGB_TO_ULONG(240, 240, 240), "grey94" },
1771 { RGB_TO_ULONG(242, 242, 242), "gray95" },
1772 { RGB_TO_ULONG(242, 242, 242), "grey95" },
1773 { RGB_TO_ULONG(245, 245, 245), "gray96" },
1774 { RGB_TO_ULONG(245, 245, 245), "grey96" },
1775 { RGB_TO_ULONG(247, 247, 247), "gray97" },
1776 { RGB_TO_ULONG(247, 247, 247), "grey97" },
1777 { RGB_TO_ULONG(250, 250, 250), "gray98" },
1778 { RGB_TO_ULONG(250, 250, 250), "grey98" },
1779 { RGB_TO_ULONG(252, 252, 252), "gray99" },
1780 { RGB_TO_ULONG(252, 252, 252), "grey99" },
1781 { RGB_TO_ULONG(255, 255, 255), "gray100" },
1782 { RGB_TO_ULONG(255, 255, 255), "grey100" },
1783 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
1784 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
1785 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
1786 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
1787 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
1788 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
1789 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
1790 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
1791 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
1792 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
1793 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
1794 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1795 { RGB_TO_ULONG(144, 238, 144), "light green" },
1796 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1800 mac_color_map_lookup (colorname
)
1803 Lisp_Object ret
= Qnil
;
1808 for (i
= 0; i
< sizeof (mac_color_map
) / sizeof (mac_color_map
[0]); i
++)
1809 if (stricmp (colorname
, mac_color_map
[i
].name
) == 0)
1811 ret
= mac_color_map
[i
].color
;
1821 x_to_mac_color (colorname
)
1824 register Lisp_Object tail
, ret
= Qnil
;
1828 if (colorname
[0] == '#')
1830 /* Could be an old-style RGB Device specification. */
1833 color
= colorname
+ 1;
1835 size
= strlen(color
);
1836 if (size
== 3 || size
== 6 || size
== 9 || size
== 12)
1838 unsigned long colorval
;
1844 for (i
= 0; i
< 3; i
++)
1848 unsigned long value
;
1850 /* The check for 'x' in the following conditional takes into
1851 account the fact that strtol allows a "0x" in front of
1852 our numbers, and we don't. */
1853 if (!isxdigit(color
[0]) || color
[1] == 'x')
1857 value
= strtoul(color
, &end
, 16);
1859 if (errno
== ERANGE
|| end
- color
!= size
)
1864 value
= value
* 0x10;
1875 colorval
|= (value
<< pos
);
1886 else if (strnicmp(colorname
, "rgb:", 4) == 0)
1889 unsigned long colorval
;
1894 color
= colorname
+ 4;
1895 for (i
= 0; i
< 3; i
++)
1898 unsigned long value
;
1900 /* The check for 'x' in the following conditional takes into
1901 account the fact that strtol allows a "0x" in front of
1902 our numbers, and we don't. */
1903 if (!isxdigit(color
[0]) || color
[1] == 'x')
1905 value
= strtoul(color
, &end
, 16);
1906 if (errno
== ERANGE
)
1908 switch (end
- color
)
1911 value
= value
* 0x10 + value
;
1924 if (value
== ULONG_MAX
)
1926 colorval
|= (value
<< pos
);
1940 else if (strnicmp(colorname
, "rgbi:", 5) == 0)
1942 /* This is an RGB Intensity specification. */
1944 unsigned long colorval
;
1949 color
= colorname
+ 5;
1950 for (i
= 0; i
< 3; i
++)
1956 value
= strtod(color
, &end
);
1957 if (errno
== ERANGE
)
1959 if (value
< 0.0 || value
> 1.0)
1961 val
= (unsigned long)(0x100 * value
);
1962 /* We used 0x100 instead of 0xFF to give a continuous
1963 range between 0.0 and 1.0 inclusive. The next statement
1964 fixes the 1.0 case. */
1967 colorval
|= (val
<< pos
);
1982 ret
= mac_color_map_lookup (colorname
);
1988 /* Gamma-correct COLOR on frame F. */
1991 gamma_correct (f
, color
)
1993 unsigned long *color
;
1997 unsigned long red
, green
, blue
;
1999 red
= pow (RED_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2000 green
= pow (GREEN_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2001 blue
= pow (BLUE_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2002 *color
= RGB_TO_ULONG (red
, green
, blue
);
2006 /* Decide if color named COLOR is valid for the display associated
2007 with the selected frame; if so, return the rgb values in COLOR_DEF.
2008 If ALLOC is nonzero, allocate a new colormap cell. */
2011 mac_defined_color (f
, color
, color_def
, alloc
)
2017 register Lisp_Object tem
;
2018 unsigned long mac_color_ref
;
2020 tem
= x_to_mac_color (color
);
2026 /* Apply gamma correction. */
2027 mac_color_ref
= XUINT (tem
);
2028 gamma_correct (f
, &mac_color_ref
);
2029 XSETINT (tem
, mac_color_ref
);
2032 color_def
->pixel
= mac_color_ref
;
2033 color_def
->red
= RED_FROM_ULONG (mac_color_ref
);
2034 color_def
->green
= GREEN_FROM_ULONG (mac_color_ref
);
2035 color_def
->blue
= BLUE_FROM_ULONG (mac_color_ref
);
2045 /* Given a string ARG naming a color, compute a pixel value from it
2046 suitable for screen F.
2047 If F is not a color screen, return DEF (default) regardless of what
2051 x_decode_color (f
, arg
, def
)
2060 if (strcmp (SDATA (arg
), "black") == 0)
2061 return BLACK_PIX_DEFAULT (f
);
2062 else if (strcmp (SDATA (arg
), "white") == 0)
2063 return WHITE_PIX_DEFAULT (f
);
2066 if ((FRAME_MAC_DISPLAY_INFO (f
)->n_planes
2067 * FRAME_MAC_DISPLAY_INFO (f
)->n_cbits
) == 1)
2071 if (mac_defined_color (f
, SDATA (arg
), &cdef
, 1))
2074 /* defined_color failed; return an ultimate default. */
2078 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
2079 the previous value of that parameter, NEW_VALUE is the new value. */
2082 x_set_line_spacing (f
, new_value
, old_value
)
2084 Lisp_Object new_value
, old_value
;
2086 if (NILP (new_value
))
2087 f
->extra_line_spacing
= 0;
2088 else if (NATNUMP (new_value
))
2089 f
->extra_line_spacing
= XFASTINT (new_value
);
2091 Fsignal (Qerror
, Fcons (build_string ("Illegal line-spacing"),
2092 Fcons (new_value
, Qnil
)));
2093 if (FRAME_VISIBLE_P (f
))
2098 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
2099 the previous value of that parameter, NEW_VALUE is the new value. */
2102 x_set_screen_gamma (f
, new_value
, old_value
)
2104 Lisp_Object new_value
, old_value
;
2106 if (NILP (new_value
))
2108 else if (NUMBERP (new_value
) && XFLOATINT (new_value
) > 0)
2109 /* The value 0.4545 is the normal viewing gamma. */
2110 f
->gamma
= 1.0 / (0.4545 * XFLOATINT (new_value
));
2112 Fsignal (Qerror
, Fcons (build_string ("Illegal screen-gamma"),
2113 Fcons (new_value
, Qnil
)));
2115 clear_face_cache (0);
2119 /* Functions called only from `x_set_frame_param'
2120 to set individual parameters.
2122 If FRAME_MAC_WINDOW (f) is 0,
2123 the frame is being created and its window does not exist yet.
2124 In that case, just record the parameter's new value
2125 in the standard place; do not attempt to change the window. */
2128 x_set_foreground_color (f
, arg
, oldval
)
2130 Lisp_Object arg
, oldval
;
2132 FRAME_FOREGROUND_PIXEL (f
)
2133 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2135 if (FRAME_MAC_WINDOW (f
) != 0)
2137 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
2138 if (FRAME_VISIBLE_P (f
))
2144 x_set_background_color (f
, arg
, oldval
)
2146 Lisp_Object arg
, oldval
;
2148 FRAME_BACKGROUND_PIXEL (f
)
2149 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
2151 if (FRAME_MAC_WINDOW (f
) != 0)
2153 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
2155 if (FRAME_VISIBLE_P (f
))
2161 x_set_mouse_color (f
, arg
, oldval
)
2163 Lisp_Object arg
, oldval
;
2165 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
2169 if (!EQ (Qnil
, arg
))
2170 f
->output_data
.mac
->mouse_pixel
2171 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2172 mask_color
= FRAME_BACKGROUND_PIXEL (f
);
2174 /* Don't let pointers be invisible. */
2175 if (mask_color
== f
->output_data
.mac
->mouse_pixel
2176 && mask_color
== FRAME_BACKGROUND_PIXEL (f
))
2177 f
->output_data
.mac
->mouse_pixel
= FRAME_FOREGROUND_PIXEL (f
);
2179 #if 0 /* MAC_TODO : cursor changes */
2182 /* It's not okay to crash if the user selects a screwy cursor. */
2183 count
= x_catch_errors (FRAME_W32_DISPLAY (f
));
2185 if (!EQ (Qnil
, Vx_pointer_shape
))
2187 CHECK_NUMBER (Vx_pointer_shape
);
2188 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XINT (Vx_pointer_shape
));
2191 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
2192 x_check_errors (FRAME_W32_DISPLAY (f
), "bad text pointer cursor: %s");
2194 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
2196 CHECK_NUMBER (Vx_nontext_pointer_shape
);
2197 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2198 XINT (Vx_nontext_pointer_shape
));
2201 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_left_ptr
);
2202 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
2204 if (!EQ (Qnil
, Vx_hourglass_pointer_shape
))
2206 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
2207 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2208 XINT (Vx_hourglass_pointer_shape
));
2211 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_watch
);
2212 x_check_errors (FRAME_W32_DISPLAY (f
), "bad busy pointer cursor: %s");
2214 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
2215 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
2217 CHECK_NUMBER (Vx_mode_pointer_shape
);
2218 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2219 XINT (Vx_mode_pointer_shape
));
2222 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
2223 x_check_errors (FRAME_W32_DISPLAY (f
), "bad modeline pointer cursor: %s");
2225 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
2227 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
2229 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2230 XINT (Vx_sensitive_text_pointer_shape
));
2233 cross_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_crosshair
);
2235 if (!NILP (Vx_window_horizontal_drag_shape
))
2237 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
2238 horizontal_drag_cursor
2239 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2240 XINT (Vx_window_horizontal_drag_shape
));
2243 horizontal_drag_cursor
2244 = XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_sb_h_double_arrow
);
2246 /* Check and report errors with the above calls. */
2247 x_check_errors (FRAME_W32_DISPLAY (f
), "can't set cursor shape: %s");
2248 x_uncatch_errors (FRAME_W32_DISPLAY (f
), count
);
2251 XColor fore_color
, back_color
;
2253 fore_color
.pixel
= f
->output_data
.w32
->mouse_pixel
;
2254 back_color
.pixel
= mask_color
;
2255 XQueryColor (FRAME_W32_DISPLAY (f
),
2256 DefaultColormap (FRAME_W32_DISPLAY (f
),
2257 DefaultScreen (FRAME_W32_DISPLAY (f
))),
2259 XQueryColor (FRAME_W32_DISPLAY (f
),
2260 DefaultColormap (FRAME_W32_DISPLAY (f
),
2261 DefaultScreen (FRAME_W32_DISPLAY (f
))),
2263 XRecolorCursor (FRAME_W32_DISPLAY (f
), cursor
,
2264 &fore_color
, &back_color
);
2265 XRecolorCursor (FRAME_W32_DISPLAY (f
), nontext_cursor
,
2266 &fore_color
, &back_color
);
2267 XRecolorCursor (FRAME_W32_DISPLAY (f
), mode_cursor
,
2268 &fore_color
, &back_color
);
2269 XRecolorCursor (FRAME_W32_DISPLAY (f
), cross_cursor
,
2270 &fore_color
, &back_color
);
2271 XRecolorCursor (FRAME_W32_DISPLAY (f
), hourglass_cursor
,
2272 &fore_color
, &back_color
);
2275 if (FRAME_W32_WINDOW (f
) != 0)
2276 XDefineCursor (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), cursor
);
2278 if (cursor
!= f
->output_data
.w32
->text_cursor
&& f
->output_data
.w32
->text_cursor
!= 0)
2279 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->text_cursor
);
2280 f
->output_data
.w32
->text_cursor
= cursor
;
2282 if (nontext_cursor
!= f
->output_data
.w32
->nontext_cursor
2283 && f
->output_data
.w32
->nontext_cursor
!= 0)
2284 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->nontext_cursor
);
2285 f
->output_data
.w32
->nontext_cursor
= nontext_cursor
;
2287 if (hourglass_cursor
!= f
->output_data
.w32
->hourglass_cursor
2288 && f
->output_data
.w32
->hourglass_cursor
!= 0)
2289 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hourglass_cursor
);
2290 f
->output_data
.w32
->hourglass_cursor
= hourglass_cursor
;
2292 if (mode_cursor
!= f
->output_data
.w32
->modeline_cursor
2293 && f
->output_data
.w32
->modeline_cursor
!= 0)
2294 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->modeline_cursor
);
2295 f
->output_data
.w32
->modeline_cursor
= mode_cursor
;
2297 if (cross_cursor
!= f
->output_data
.w32
->cross_cursor
2298 && f
->output_data
.w32
->cross_cursor
!= 0)
2299 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->cross_cursor
);
2300 f
->output_data
.w32
->cross_cursor
= cross_cursor
;
2302 XFlush (FRAME_W32_DISPLAY (f
));
2305 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
2306 #endif /* MAC_TODO */
2310 x_set_cursor_color (f
, arg
, oldval
)
2312 Lisp_Object arg
, oldval
;
2314 unsigned long fore_pixel
;
2316 if (!NILP (Vx_cursor_fore_pixel
))
2317 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
2318 WHITE_PIX_DEFAULT (f
));
2320 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2321 f
->output_data
.mac
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2323 /* Make sure that the cursor color differs from the background color. */
2324 if (f
->output_data
.mac
->cursor_pixel
== FRAME_BACKGROUND_PIXEL (f
))
2326 f
->output_data
.mac
->cursor_pixel
= f
->output_data
.mac
->mouse_pixel
;
2327 if (f
->output_data
.mac
->cursor_pixel
== fore_pixel
)
2328 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2330 FRAME_FOREGROUND_PIXEL (f
) = fore_pixel
;
2332 #if 0 /* MAC_TODO: cannot figure out what to do (wrong number of params) */
2333 if (FRAME_MAC_WINDOW (f
) != 0)
2335 if (FRAME_VISIBLE_P (f
))
2337 x_display_cursor (f
, 0);
2338 x_display_cursor (f
, 1);
2343 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
2346 /* Set the border-color of frame F to pixel value PIX.
2347 Note that this does not fully take effect if done before
2350 x_set_border_pixel (f
, pix
)
2354 f
->output_data
.mac
->border_pixel
= pix
;
2356 if (FRAME_MAC_WINDOW (f
) != 0 && f
->output_data
.mac
->border_width
> 0)
2358 if (FRAME_VISIBLE_P (f
))
2363 /* Set the border-color of frame F to value described by ARG.
2364 ARG can be a string naming a color.
2365 The border-color is used for the border that is drawn by the server.
2366 Note that this does not fully take effect if done before
2367 F has a window; it must be redone when the window is created. */
2370 x_set_border_color (f
, arg
, oldval
)
2372 Lisp_Object arg
, oldval
;
2377 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2378 x_set_border_pixel (f
, pix
);
2379 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
2383 x_set_cursor_type (f
, arg
, oldval
)
2385 Lisp_Object arg
, oldval
;
2387 set_frame_cursor_types (f
, arg
);
2389 /* Make sure the cursor gets redrawn. This is overkill, but how
2390 often do people change cursor types? */
2391 update_mode_lines
++;
2394 #if 0 /* MAC_TODO: really no icon for Mac */
2396 x_set_icon_type (f
, arg
, oldval
)
2398 Lisp_Object arg
, oldval
;
2402 if (NILP (arg
) && NILP (oldval
))
2405 if (STRINGP (arg
) && STRINGP (oldval
)
2406 && EQ (Fstring_equal (oldval
, arg
), Qt
))
2409 if (SYMBOLP (arg
) && SYMBOLP (oldval
) && EQ (arg
, oldval
))
2414 result
= x_bitmap_icon (f
, arg
);
2418 error ("No icon window available");
2423 #endif /* MAC_TODO */
2425 /* Return non-nil if frame F wants a bitmap icon. */
2433 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
2441 x_set_icon_name (f
, arg
, oldval
)
2443 Lisp_Object arg
, oldval
;
2449 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
2452 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
2457 #if 0 /* MAC_TODO */
2458 if (f
->output_data
.w32
->icon_bitmap
!= 0)
2463 result
= x_text_icon (f
,
2464 (char *) SDATA ((!NILP (f
->icon_name
)
2473 error ("No icon window available");
2476 /* If the window was unmapped (and its icon was mapped),
2477 the new icon is not mapped, so map the window in its stead. */
2478 if (FRAME_VISIBLE_P (f
))
2480 #ifdef USE_X_TOOLKIT
2481 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
2483 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
2486 XFlush (FRAME_W32_DISPLAY (f
));
2488 #endif /* MAC_TODO */
2491 extern Lisp_Object
x_new_font ();
2492 extern Lisp_Object
x_new_fontset();
2495 x_set_font (f
, arg
, oldval
)
2497 Lisp_Object arg
, oldval
;
2500 Lisp_Object fontset_name
;
2502 int old_fontset
= FRAME_FONTSET(f
);
2506 fontset_name
= Fquery_fontset (arg
, Qnil
);
2509 result
= (STRINGP (fontset_name
)
2510 ? x_new_fontset (f
, SDATA (fontset_name
))
2511 : x_new_font (f
, SDATA (arg
)));
2514 if (EQ (result
, Qnil
))
2515 error ("Font `%s' is not defined", SDATA (arg
));
2516 else if (EQ (result
, Qt
))
2517 error ("The characters of the given font have varying widths");
2518 else if (STRINGP (result
))
2520 if (STRINGP (fontset_name
))
2522 /* Fontset names are built from ASCII font names, so the
2523 names may be equal despite there was a change. */
2524 if (old_fontset
== FRAME_FONTSET (f
))
2527 else if (!NILP (Fequal (result
, oldval
)))
2530 store_frame_param (f
, Qfont
, result
);
2531 recompute_basic_faces (f
);
2536 do_pending_window_change (0);
2538 /* Don't call `face-set-after-frame-default' when faces haven't been
2539 initialized yet. This is the case when called from
2540 Fx_create_frame. In that case, the X widget or window doesn't
2541 exist either, and we can end up in x_report_frame_params with a
2542 null widget which gives a segfault. */
2543 if (FRAME_FACE_CACHE (f
))
2545 XSETFRAME (frame
, f
);
2546 call1 (Qface_set_after_frame_default
, frame
);
2551 x_set_border_width (f
, arg
, oldval
)
2553 Lisp_Object arg
, oldval
;
2557 if (XINT (arg
) == f
->output_data
.mac
->border_width
)
2560 #if 0 /* MAC_TODO */
2561 if (FRAME_MAC_WINDOW (f
) != 0)
2562 error ("Cannot change the border width of a window");
2565 f
->output_data
.mac
->border_width
= XINT (arg
);
2569 x_set_internal_border_width (f
, arg
, oldval
)
2571 Lisp_Object arg
, oldval
;
2573 int old
= f
->output_data
.mac
->internal_border_width
;
2576 f
->output_data
.mac
->internal_border_width
= XINT (arg
);
2577 if (f
->output_data
.mac
->internal_border_width
< 0)
2578 f
->output_data
.mac
->internal_border_width
= 0;
2580 if (f
->output_data
.mac
->internal_border_width
== old
)
2583 if (FRAME_MAC_WINDOW (f
) != 0)
2585 x_set_window_size (f
, 0, f
->width
, f
->height
);
2586 SET_FRAME_GARBAGED (f
);
2587 do_pending_window_change (0);
2590 SET_FRAME_GARBAGED (f
);
2594 x_set_visibility (f
, value
, oldval
)
2596 Lisp_Object value
, oldval
;
2599 XSETFRAME (frame
, f
);
2602 Fmake_frame_invisible (frame
, Qt
);
2603 else if (EQ (value
, Qicon
))
2604 Ficonify_frame (frame
);
2606 Fmake_frame_visible (frame
);
2610 /* Change window heights in windows rooted in WINDOW by N lines. */
2613 x_change_window_heights (window
, n
)
2617 struct window
*w
= XWINDOW (window
);
2619 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
2620 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
2622 if (INTEGERP (w
->orig_top
))
2623 XSETFASTINT (w
->orig_top
, XFASTINT (w
->orig_top
) + n
);
2624 if (INTEGERP (w
->orig_height
))
2625 XSETFASTINT (w
->orig_height
, XFASTINT (w
->orig_height
) - n
);
2627 /* Handle just the top child in a vertical split. */
2628 if (!NILP (w
->vchild
))
2629 x_change_window_heights (w
->vchild
, n
);
2631 /* Adjust all children in a horizontal split. */
2632 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
2634 w
= XWINDOW (window
);
2635 x_change_window_heights (window
, n
);
2640 x_set_menu_bar_lines (f
, value
, oldval
)
2642 Lisp_Object value
, oldval
;
2645 int olines
= FRAME_MENU_BAR_LINES (f
);
2647 /* Right now, menu bars don't work properly in minibuf-only frames;
2648 most of the commands try to apply themselves to the minibuffer
2649 frame itself, and get an error because you can't switch buffers
2650 in or split the minibuffer window. */
2651 if (FRAME_MINIBUF_ONLY_P (f
))
2654 if (INTEGERP (value
))
2655 nlines
= XINT (value
);
2659 FRAME_MENU_BAR_LINES (f
) = 0;
2661 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
2664 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
2665 free_frame_menubar (f
);
2666 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
2668 /* Adjust the frame size so that the client (text) dimensions
2669 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
2671 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2672 do_pending_window_change (0);
2678 /* Set the number of lines used for the tool bar of frame F to VALUE.
2679 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
2680 is the old number of tool bar lines. This function changes the
2681 height of all windows on frame F to match the new tool bar height.
2682 The frame's height doesn't change. */
2685 x_set_tool_bar_lines (f
, value
, oldval
)
2687 Lisp_Object value
, oldval
;
2689 int delta
, nlines
, root_height
;
2690 Lisp_Object root_window
;
2692 /* Treat tool bars like menu bars. */
2693 if (FRAME_MINIBUF_ONLY_P (f
))
2696 /* Use VALUE only if an integer >= 0. */
2697 if (INTEGERP (value
) && XINT (value
) >= 0)
2698 nlines
= XFASTINT (value
);
2702 /* Make sure we redisplay all windows in this frame. */
2703 ++windows_or_buffers_changed
;
2705 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
2707 /* Don't resize the tool-bar to more than we have room for. */
2708 root_window
= FRAME_ROOT_WINDOW (f
);
2709 root_height
= XINT (XWINDOW (root_window
)->height
);
2710 if (root_height
- delta
< 1)
2712 delta
= root_height
- 1;
2713 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
2716 FRAME_TOOL_BAR_LINES (f
) = nlines
;
2717 x_change_window_heights (root_window
, delta
);
2720 /* We also have to make sure that the internal border at the top of
2721 the frame, below the menu bar or tool bar, is redrawn when the
2722 tool bar disappears. This is so because the internal border is
2723 below the tool bar if one is displayed, but is below the menu bar
2724 if there isn't a tool bar. The tool bar draws into the area
2725 below the menu bar. */
2726 if (FRAME_MAC_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
2730 clear_current_matrices (f
);
2731 updating_frame
= NULL
;
2734 /* If the tool bar gets smaller, the internal border below it
2735 has to be cleared. It was formerly part of the display
2736 of the larger tool bar, and updating windows won't clear it. */
2739 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
2740 int width
= PIXEL_WIDTH (f
);
2741 int y
= nlines
* CANON_Y_UNIT (f
);
2744 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2745 0, y
, width
, height
, 0);
2748 if (WINDOWP (f
->tool_bar_window
))
2749 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
2754 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
2757 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2758 name; if NAME is a string, set F's name to NAME and set
2759 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2761 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2762 suggesting a new name, which lisp code should override; if
2763 F->explicit_name is set, ignore the new name; otherwise, set it. */
2766 x_set_name (f
, name
, explicit)
2771 /* Make sure that requests from lisp code override requests from
2772 Emacs redisplay code. */
2775 /* If we're switching from explicit to implicit, we had better
2776 update the mode lines and thereby update the title. */
2777 if (f
->explicit_name
&& NILP (name
))
2778 update_mode_lines
= 1;
2780 f
->explicit_name
= ! NILP (name
);
2782 else if (f
->explicit_name
)
2785 /* If NAME is nil, set the name to the w32_id_name. */
2788 /* Check for no change needed in this very common case
2789 before we do any consing. */
2790 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
,
2793 name
= build_string (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
);
2796 CHECK_STRING (name
);
2798 /* Don't change the name if it's already NAME. */
2799 if (! NILP (Fstring_equal (name
, f
->name
)))
2804 /* For setting the frame title, the title parameter should override
2805 the name parameter. */
2806 if (! NILP (f
->title
))
2809 if (FRAME_MAC_WINDOW (f
))
2811 if (STRING_MULTIBYTE (name
))
2812 #if 0 /* MAC_TODO: encoding title string */
2813 name
= ENCODE_SYSTEM (name
);
2822 if (strlen (SDATA (name
)) < 255)
2824 strcpy (windowTitle
, SDATA (name
));
2825 c2pstr (windowTitle
);
2826 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2834 /* This function should be called when the user's lisp code has
2835 specified a name for the frame; the name will override any set by the
2838 x_explicitly_set_name (f
, arg
, oldval
)
2840 Lisp_Object arg
, oldval
;
2842 x_set_name (f
, arg
, 1);
2845 /* This function should be called by Emacs redisplay code to set the
2846 name; names set this way will never override names set by the user's
2849 x_implicitly_set_name (f
, arg
, oldval
)
2851 Lisp_Object arg
, oldval
;
2853 x_set_name (f
, arg
, 0);
2856 /* Change the title of frame F to NAME.
2857 If NAME is nil, use the frame name as the title.
2859 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2860 name; if NAME is a string, set F's name to NAME and set
2861 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2863 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2864 suggesting a new name, which lisp code should override; if
2865 F->explicit_name is set, ignore the new name; otherwise, set it. */
2868 x_set_title (f
, name
, old_name
)
2870 Lisp_Object name
, old_name
;
2872 /* Don't change the title if it's already NAME. */
2873 if (EQ (name
, f
->title
))
2876 update_mode_lines
= 1;
2883 if (FRAME_MAC_WINDOW (f
))
2885 if (STRING_MULTIBYTE (name
))
2886 #if 0 /* MAC_TODO: encoding title string */
2887 name
= ENCODE_SYSTEM (name
);
2896 if (strlen (SDATA (name
)) < 255)
2898 strcpy (windowTitle
, SDATA (name
));
2899 c2pstr (windowTitle
);
2900 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2909 x_set_autoraise (f
, arg
, oldval
)
2911 Lisp_Object arg
, oldval
;
2913 f
->auto_raise
= !EQ (Qnil
, arg
);
2917 x_set_autolower (f
, arg
, oldval
)
2919 Lisp_Object arg
, oldval
;
2921 f
->auto_lower
= !EQ (Qnil
, arg
);
2925 x_set_unsplittable (f
, arg
, oldval
)
2927 Lisp_Object arg
, oldval
;
2929 f
->no_split
= !NILP (arg
);
2933 x_set_vertical_scroll_bars (f
, arg
, oldval
)
2935 Lisp_Object arg
, oldval
;
2937 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
2938 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
2939 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
2940 || (!NILP (arg
) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
2942 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
)
2944 ? vertical_scroll_bar_none
2946 ? vertical_scroll_bar_right
2947 : vertical_scroll_bar_left
);
2949 /* We set this parameter before creating the window for the
2950 frame, so we can get the geometry right from the start.
2951 However, if the window hasn't been created yet, we shouldn't
2952 call x_set_window_size. */
2953 if (FRAME_MAC_WINDOW (f
))
2954 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2955 do_pending_window_change (0);
2960 x_set_scroll_bar_width (f
, arg
, oldval
)
2962 Lisp_Object arg
, oldval
;
2964 /* Imitate X without X Toolkit */
2966 int wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
2971 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 16; /* Aqua scroll bars. */
2972 FRAME_SCROLL_BAR_COLS (f
) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) +
2974 #else /* not MAC_OSX */
2975 /* Make the actual width at least 14 pixels and a multiple of a
2977 FRAME_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2979 /* Use all of that space (aside from required margins) for the
2981 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
2982 #endif /* not MAC_OSX */
2983 if (FRAME_MAC_WINDOW (f
))
2984 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2985 do_pending_window_change (0);
2987 else if (INTEGERP (arg
) && XINT (arg
) > 0
2988 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
2990 if (XFASTINT (arg
) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
2991 XSETINT (arg
, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
+ 1);
2993 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
2994 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
2995 if (FRAME_MAC_WINDOW (f
))
2996 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2997 do_pending_window_change (0);
2999 change_frame_size (f
, 0, FRAME_WIDTH (f
), 0, 0, 0);
3000 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.hpos
= 0;
3001 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.x
= 0;
3004 /* Subroutines of creating a frame. */
3006 /* Make sure that Vx_resource_name is set to a reasonable value.
3007 Fix it up, or set it to `emacs' if it is too hopeless. */
3010 validate_x_resource_name ()
3013 /* Number of valid characters in the resource name. */
3015 /* Number of invalid characters in the resource name. */
3020 if (STRINGP (Vx_resource_name
))
3022 unsigned char *p
= SDATA (Vx_resource_name
);
3025 len
= SBYTES (Vx_resource_name
);
3027 /* Only letters, digits, - and _ are valid in resource names.
3028 Count the valid characters and count the invalid ones. */
3029 for (i
= 0; i
< len
; i
++)
3032 if (! ((c
>= 'a' && c
<= 'z')
3033 || (c
>= 'A' && c
<= 'Z')
3034 || (c
>= '0' && c
<= '9')
3035 || c
== '-' || c
== '_'))
3042 /* Not a string => completely invalid. */
3043 bad_count
= 5, good_count
= 0;
3045 /* If name is valid already, return. */
3049 /* If name is entirely invalid, or nearly so, use `emacs'. */
3051 || (good_count
== 1 && bad_count
> 0))
3053 Vx_resource_name
= build_string ("emacs");
3057 /* Name is partly valid. Copy it and replace the invalid characters
3058 with underscores. */
3060 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
3062 for (i
= 0; i
< len
; i
++)
3064 int c
= SREF (new, i
);
3065 if (! ((c
>= 'a' && c
<= 'z')
3066 || (c
>= 'A' && c
<= 'Z')
3067 || (c
>= '0' && c
<= '9')
3068 || c
== '-' || c
== '_'))
3074 #if 0 /* MAC_TODO: implement resource strings */
3075 extern char *x_get_string_resource ();
3077 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
3078 doc
: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3079 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3080 class, where INSTANCE is the name under which Emacs was invoked, or
3081 the name specified by the `-name' or `-rn' command-line arguments.
3083 The optional arguments COMPONENT and SUBCLASS add to the key and the
3084 class, respectively. You must specify both of them or neither.
3085 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3086 and the class is `Emacs.CLASS.SUBCLASS'. */)
3087 (attribute
, class, component
, subclass
)
3088 Lisp_Object attribute
, class, component
, subclass
;
3090 register char *value
;
3094 CHECK_STRING (attribute
);
3095 CHECK_STRING (class);
3097 if (!NILP (component
))
3098 CHECK_STRING (component
);
3099 if (!NILP (subclass
))
3100 CHECK_STRING (subclass
);
3101 if (NILP (component
) != NILP (subclass
))
3102 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3104 validate_x_resource_name ();
3106 /* Allocate space for the components, the dots which separate them,
3107 and the final '\0'. Make them big enough for the worst case. */
3108 name_key
= (char *) alloca (SBYTES (Vx_resource_name
)
3109 + (STRINGP (component
)
3110 ? SBYTES (component
) : 0)
3111 + SBYTES (attribute
)
3114 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
3116 + (STRINGP (subclass
)
3117 ? SBYTES (subclass
) : 0)
3120 /* Start with emacs.FRAMENAME for the name (the specific one)
3121 and with `Emacs' for the class key (the general one). */
3122 strcpy (name_key
, SDATA (Vx_resource_name
));
3123 strcpy (class_key
, EMACS_CLASS
);
3125 strcat (class_key
, ".");
3126 strcat (class_key
, SDATA (class));
3128 if (!NILP (component
))
3130 strcat (class_key
, ".");
3131 strcat (class_key
, SDATA (subclass
));
3133 strcat (name_key
, ".");
3134 strcat (name_key
, SDATA (component
));
3137 strcat (name_key
, ".");
3138 strcat (name_key
, SDATA (attribute
));
3140 value
= x_get_string_resource (Qnil
,
3141 name_key
, class_key
);
3143 if (value
!= (char *) 0)
3144 return build_string (value
);
3149 /* Used when C code wants a resource value. */
3152 x_get_resource_string (attribute
, class)
3153 char *attribute
, *class;
3157 struct frame
*sf
= SELECTED_FRAME ();
3159 /* Allocate space for the components, the dots which separate them,
3160 and the final '\0'. */
3161 name_key
= (char *) alloca (SBYTES (Vinvocation_name
)
3162 + strlen (attribute
) + 2);
3163 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
3164 + strlen (class) + 2);
3166 sprintf (name_key
, "%s.%s",
3167 SDATA (Vinvocation_name
),
3169 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
3171 return x_get_string_resource (sf
, name_key
, class_key
);
3173 #endif /* MAC_TODO */
3175 /* Types we might convert a resource string into. */
3185 /* Return the value of parameter PARAM.
3187 First search ALIST, then Vdefault_frame_alist, then the X defaults
3188 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3190 Convert the resource to the type specified by desired_type.
3192 If no default is specified, return Qunbound. If you call
3193 w32_get_arg, make sure you deal with Qunbound in a reasonable way,
3194 and don't let it get stored in any Lisp-visible variables! */
3197 mac_get_arg (alist
, param
, attribute
, class, type
)
3198 Lisp_Object alist
, param
;
3201 enum resource_types type
;
3203 register Lisp_Object tem
;
3205 tem
= Fassq (param
, alist
);
3207 tem
= Fassq (param
, Vdefault_frame_alist
);
3211 #if 0 /* MAC_TODO: search resource also */
3214 tem
= Fx_get_resource (build_string (attribute
),
3215 build_string (class),
3223 case RES_TYPE_NUMBER
:
3224 return make_number (atoi (SDATA (tem
)));
3226 case RES_TYPE_FLOAT
:
3227 return make_float (atof (SDATA (tem
)));
3229 case RES_TYPE_BOOLEAN
:
3230 tem
= Fdowncase (tem
);
3231 if (!strcmp (SDATA (tem
), "on")
3232 || !strcmp (SDATA (tem
), "true"))
3237 case RES_TYPE_STRING
:
3240 case RES_TYPE_SYMBOL
:
3241 /* As a special case, we map the values `true' and `on'
3242 to Qt, and `false' and `off' to Qnil. */
3245 lower
= Fdowncase (tem
);
3246 if (!strcmp (SDATA (lower
), "on")
3247 || !strcmp (SDATA (lower
), "true"))
3249 else if (!strcmp (SDATA (lower
), "off")
3250 || !strcmp (SDATA (lower
), "false"))
3253 return Fintern (tem
, Qnil
);
3261 #endif /* MAC_TODO */
3267 /* Record in frame F the specified or default value according to ALIST
3268 of the parameter named PROP (a Lisp symbol).
3269 If no value is specified for PROP, look for an X default for XPROP
3270 on the frame named NAME.
3271 If that is not found either, use the value DEFLT. */
3274 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
3281 enum resource_types type
;
3285 tem
= mac_get_arg (alist
, prop
, xprop
, xclass
, type
);
3286 if (EQ (tem
, Qunbound
))
3288 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
3292 /* XParseGeometry copied from w32xfns.c */
3295 * XParseGeometry parses strings of the form
3296 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
3297 * width, height, xoffset, and yoffset are unsigned integers.
3298 * Example: "=80x24+300-49"
3299 * The equal sign is optional.
3300 * It returns a bitmask that indicates which of the four values
3301 * were actually found in the string. For each value found,
3302 * the corresponding argument is updated; for each value
3303 * not found, the corresponding argument is left unchanged.
3307 read_integer (string
, NextString
)
3308 register char *string
;
3311 register int Result
= 0;
3316 else if (*string
== '-')
3321 for (; (*string
>= '0') && (*string
<= '9'); string
++)
3323 Result
= (Result
* 10) + (*string
- '0');
3325 *NextString
= string
;
3333 XParseGeometry (string
, x
, y
, width
, height
)
3336 unsigned int *width
, *height
; /* RETURN */
3339 register char *strind
;
3340 unsigned int tempWidth
, tempHeight
;
3342 char *nextCharacter
;
3344 if ((string
== NULL
) || (*string
== '\0')) return (mask
);
3346 string
++; /* ignore possible '=' at beg of geometry spec */
3348 strind
= (char *)string
;
3349 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
3351 tempWidth
= read_integer (strind
, &nextCharacter
);
3352 if (strind
== nextCharacter
)
3354 strind
= nextCharacter
;
3358 if (*strind
== 'x' || *strind
== 'X')
3361 tempHeight
= read_integer (strind
, &nextCharacter
);
3362 if (strind
== nextCharacter
)
3364 strind
= nextCharacter
;
3365 mask
|= HeightValue
;
3368 if ((*strind
== '+') || (*strind
== '-'))
3373 tempX
= -read_integer (strind
, &nextCharacter
);
3374 if (strind
== nextCharacter
)
3376 strind
= nextCharacter
;
3383 tempX
= read_integer (strind
, &nextCharacter
);
3384 if (strind
== nextCharacter
)
3386 strind
= nextCharacter
;
3389 if ((*strind
== '+') || (*strind
== '-'))
3394 tempY
= -read_integer (strind
, &nextCharacter
);
3395 if (strind
== nextCharacter
)
3397 strind
= nextCharacter
;
3404 tempY
= read_integer (strind
, &nextCharacter
);
3405 if (strind
== nextCharacter
)
3407 strind
= nextCharacter
;
3413 /* If strind isn't at the end of the string the it's an invalid
3414 geometry specification. */
3416 if (*strind
!= '\0') return (0);
3422 if (mask
& WidthValue
)
3424 if (mask
& HeightValue
)
3425 *height
= tempHeight
;
3429 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
3430 doc
: /* Parse an X-style geometry string STRING.
3431 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
3432 The properties returned may include `top', `left', `height', and `width'.
3433 The value of `left' or `top' may be an integer,
3434 or a list (+ N) meaning N pixels relative to top/left corner,
3435 or a list (- N) meaning -N pixels relative to bottom/right corner. */)
3440 unsigned int width
, height
;
3443 CHECK_STRING (string
);
3445 geometry
= XParseGeometry ((char *) SDATA (string
),
3446 &x
, &y
, &width
, &height
);
3449 if (geometry
& XValue
)
3451 Lisp_Object element
;
3453 if (x
>= 0 && (geometry
& XNegative
))
3454 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
3455 else if (x
< 0 && ! (geometry
& XNegative
))
3456 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
3458 element
= Fcons (Qleft
, make_number (x
));
3459 result
= Fcons (element
, result
);
3462 if (geometry
& YValue
)
3464 Lisp_Object element
;
3466 if (y
>= 0 && (geometry
& YNegative
))
3467 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
3468 else if (y
< 0 && ! (geometry
& YNegative
))
3469 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
3471 element
= Fcons (Qtop
, make_number (y
));
3472 result
= Fcons (element
, result
);
3475 if (geometry
& WidthValue
)
3476 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
3477 if (geometry
& HeightValue
)
3478 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
3483 /* Calculate the desired size and position of this window,
3484 and return the flags saying which aspects were specified.
3486 This function does not make the coordinates positive. */
3488 #define DEFAULT_ROWS 40
3489 #define DEFAULT_COLS 80
3492 x_figure_window_size (f
, parms
)
3496 register Lisp_Object tem0
, tem1
, tem2
;
3497 long window_prompting
= 0;
3499 /* Default values if we fall through.
3500 Actually, if that happens we should get
3501 window manager prompting. */
3502 SET_FRAME_WIDTH (f
, DEFAULT_COLS
);
3503 f
->height
= DEFAULT_ROWS
;
3504 /* Window managers expect that if program-specified
3505 positions are not (0,0), they're intentional, not defaults. */
3506 f
->output_data
.mac
->top_pos
= 0;
3507 f
->output_data
.mac
->left_pos
= 0;
3509 tem0
= mac_get_arg (parms
, Qheight
, 0, 0, RES_TYPE_NUMBER
);
3510 tem1
= mac_get_arg (parms
, Qwidth
, 0, 0, RES_TYPE_NUMBER
);
3511 tem2
= mac_get_arg (parms
, Quser_size
, 0, 0, RES_TYPE_NUMBER
);
3512 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
3514 if (!EQ (tem0
, Qunbound
))
3516 CHECK_NUMBER (tem0
);
3517 f
->height
= XINT (tem0
);
3519 if (!EQ (tem1
, Qunbound
))
3521 CHECK_NUMBER (tem1
);
3522 SET_FRAME_WIDTH (f
, XINT (tem1
));
3524 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
3525 window_prompting
|= USSize
;
3527 window_prompting
|= PSize
;
3530 f
->output_data
.mac
->vertical_scroll_bar_extra
3531 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
3533 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
3534 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
3535 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
3537 compute_fringe_widths (f
, 0);
3539 f
->output_data
.mac
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
3540 f
->output_data
.mac
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
3542 tem0
= mac_get_arg (parms
, Qtop
, 0, 0, RES_TYPE_NUMBER
);
3543 tem1
= mac_get_arg (parms
, Qleft
, 0, 0, RES_TYPE_NUMBER
);
3544 tem2
= mac_get_arg (parms
, Quser_position
, 0, 0, RES_TYPE_NUMBER
);
3545 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
3547 if (EQ (tem0
, Qminus
))
3549 f
->output_data
.mac
->top_pos
= 0;
3550 window_prompting
|= YNegative
;
3552 else if (CONSP (tem0
) && EQ (XCAR (tem0
), Qminus
)
3553 && CONSP (XCDR (tem0
))
3554 && INTEGERP (XCAR (XCDR (tem0
))))
3556 f
->output_data
.mac
->top_pos
= - XINT (XCAR (XCDR (tem0
)));
3557 window_prompting
|= YNegative
;
3559 else if (CONSP (tem0
) && EQ (XCAR (tem0
), Qplus
)
3560 && CONSP (XCDR (tem0
))
3561 && INTEGERP (XCAR (XCDR (tem0
))))
3563 f
->output_data
.mac
->top_pos
= XINT (XCAR (XCDR (tem0
)));
3565 else if (EQ (tem0
, Qunbound
))
3566 f
->output_data
.mac
->top_pos
= 0;
3569 CHECK_NUMBER (tem0
);
3570 f
->output_data
.mac
->top_pos
= XINT (tem0
);
3571 if (f
->output_data
.mac
->top_pos
< 0)
3572 window_prompting
|= YNegative
;
3575 if (EQ (tem1
, Qminus
))
3577 f
->output_data
.mac
->left_pos
= 0;
3578 window_prompting
|= XNegative
;
3580 else if (CONSP (tem1
) && EQ (XCAR (tem1
), Qminus
)
3581 && CONSP (XCDR (tem1
))
3582 && INTEGERP (XCAR (XCDR (tem1
))))
3584 f
->output_data
.mac
->left_pos
= - XINT (XCAR (XCDR (tem1
)));
3585 window_prompting
|= XNegative
;
3587 else if (CONSP (tem1
) && EQ (XCAR (tem1
), Qplus
)
3588 && CONSP (XCDR (tem1
))
3589 && INTEGERP (XCAR (XCDR (tem1
))))
3591 f
->output_data
.mac
->left_pos
= XINT (XCAR (XCDR (tem1
)));
3593 else if (EQ (tem1
, Qunbound
))
3594 f
->output_data
.mac
->left_pos
= 0;
3597 CHECK_NUMBER (tem1
);
3598 f
->output_data
.mac
->left_pos
= XINT (tem1
);
3599 if (f
->output_data
.mac
->left_pos
< 0)
3600 window_prompting
|= XNegative
;
3603 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
3604 window_prompting
|= USPosition
;
3606 window_prompting
|= PPosition
;
3609 return window_prompting
;
3613 #if 0 /* MAC_TODO */
3614 /* Create and set up the Mac window for frame F. */
3617 mac_window (f
, window_prompting
, minibuffer_only
)
3619 long window_prompting
;
3620 int minibuffer_only
;
3626 /* Use the resource name as the top-level window name
3627 for looking up resources. Make a non-Lisp copy
3628 for the window manager, so GC relocation won't bother it.
3630 Elsewhere we specify the window name for the window manager. */
3633 char *str
= (char *) SDATA (Vx_resource_name
);
3634 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
3635 strcpy (f
->namebuf
, str
);
3638 SetRect (&r
, f
->output_data
.mac
->left_pos
, f
->output_data
.mac
->top_pos
,
3639 f
->output_data
.mac
->left_pos
+ PIXEL_WIDTH (f
),
3640 f
->output_data
.mac
->top_pos
+ PIXEL_HEIGHT (f
));
3641 FRAME_MAC_WINDOW (f
)
3642 = NewCWindow (NULL
, &r
, "\p", 1, zoomDocProc
, (WindowPtr
) -1, 1, (long) f
->output_data
.mac
);
3644 validate_x_resource_name ();
3646 /* x_set_name normally ignores requests to set the name if the
3647 requested name is the same as the current name. This is the one
3648 place where that assumption isn't correct; f->name is set, but
3649 the server hasn't been told. */
3652 int explicit = f
->explicit_name
;
3654 f
->explicit_name
= 0;
3657 x_set_name (f
, name
, explicit);
3660 ShowWindow (FRAME_MAC_WINDOW (f
));
3664 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3665 initialize_frame_menubar (f
);
3667 if (FRAME_MAC_WINDOW (f
) == 0)
3668 error ("Unable to create window");
3670 #endif /* MAC_TODO */
3672 /* Handle the icon stuff for this window. Perhaps later we might
3673 want an x_set_icon_position which can be called interactively as
3681 Lisp_Object icon_x
, icon_y
;
3683 /* Set the position of the icon. Note that Windows 95 groups all
3684 icons in the tray. */
3685 icon_x
= mac_get_arg (parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
3686 icon_y
= mac_get_arg (parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
3687 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
3689 CHECK_NUMBER (icon_x
);
3690 CHECK_NUMBER (icon_y
);
3692 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
3693 error ("Both left and top icon corners of icon must be specified");
3697 if (! EQ (icon_x
, Qunbound
))
3698 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
3701 /* Start up iconic or window? */
3702 x_wm_set_window_state
3703 (f
, (EQ (w32_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
), Qicon
)
3707 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
3720 XGCValues gc_values
;
3724 /* Create the GC's of this frame.
3725 Note that many default values are used. */
3728 gc_values
.font
= f
->output_data
.mac
->font
;
3729 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
3730 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
3731 f
->output_data
.mac
->normal_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3732 FRAME_MAC_WINDOW (f
),
3733 GCFont
| GCForeground
| GCBackground
,
3736 /* Reverse video style. */
3737 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3738 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
3739 f
->output_data
.mac
->reverse_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3740 FRAME_MAC_WINDOW (f
),
3741 GCFont
| GCForeground
| GCBackground
,
3744 /* Cursor has cursor-color background, background-color foreground. */
3745 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3746 gc_values
.background
= f
->output_data
.mac
->cursor_pixel
;
3747 f
->output_data
.mac
->cursor_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3748 FRAME_MAC_WINDOW (f
),
3749 GCFont
| GCForeground
| GCBackground
,
3753 f
->output_data
.mac
->white_relief
.gc
= 0;
3754 f
->output_data
.mac
->black_relief
.gc
= 0;
3760 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3762 doc
: /* Make a new window, which is called a \"frame\" in Emacs terms.
3763 Returns an Emacs frame object.
3764 ALIST is an alist of frame parameters.
3765 If the parameters specify that the frame should not have a minibuffer,
3766 and do not specify a specific minibuffer window to use,
3767 then `default-minibuffer-frame' must be a frame whose minibuffer can
3768 be shared by the new frame.
3770 This function is an internal primitive--use `make-frame' instead. */)
3775 Lisp_Object frame
, tem
;
3777 int minibuffer_only
= 0;
3778 long window_prompting
= 0;
3780 int count
= SPECPDL_INDEX ();
3781 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3782 Lisp_Object display
;
3783 struct mac_display_info
*dpyinfo
= NULL
;
3786 char x_frame_name
[10];
3787 static int x_frame_count
= 2; /* begins at 2 because terminal frame is F1 */
3791 /* Use this general default value to start with
3792 until we know if this frame has a specified name. */
3793 Vx_resource_name
= Vinvocation_name
;
3795 display
= mac_get_arg (parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3796 if (EQ (display
, Qunbound
))
3798 dpyinfo
= check_x_display_info (display
);
3800 kb
= dpyinfo
->kboard
;
3802 kb
= &the_only_kboard
;
3805 name
= mac_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3807 && ! EQ (name
, Qunbound
)
3809 error ("Invalid frame name--not a string or nil");
3812 Vx_resource_name
= name
;
3814 /* See if parent window is specified. */
3815 parent
= mac_get_arg (parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3816 if (EQ (parent
, Qunbound
))
3818 if (! NILP (parent
))
3819 CHECK_NUMBER (parent
);
3821 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3822 /* No need to protect DISPLAY because that's not used after passing
3823 it to make_frame_without_minibuffer. */
3825 GCPRO4 (parms
, parent
, name
, frame
);
3826 tem
= mac_get_arg (parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3828 if (EQ (tem
, Qnone
) || NILP (tem
))
3829 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3830 else if (EQ (tem
, Qonly
))
3832 f
= make_minibuffer_frame ();
3833 minibuffer_only
= 1;
3835 else if (WINDOWP (tem
))
3836 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3840 if (EQ (name
, Qunbound
) || NILP (name
))
3842 sprintf (x_frame_name
, "F%d", x_frame_count
++);
3843 f
->name
= build_string (x_frame_name
);
3844 f
->explicit_name
= 0;
3849 f
->explicit_name
= 1;
3852 XSETFRAME (frame
, f
);
3854 /* Note that X Windows does support scroll bars. */
3855 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3857 f
->output_method
= output_mac
;
3858 f
->output_data
.mac
= (struct mac_output
*) xmalloc (sizeof (struct mac_output
));
3859 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
3860 FRAME_FONTSET (f
) = -1;
3861 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
3862 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
3865 FRAME_FONTSET (f
) = -1;
3869 = mac_get_arg (parms
, Qicon_name
, "iconName", "Title", RES_TYPE_STRING
);
3870 if (! STRINGP (f
->icon_name
))
3871 f
->icon_name
= Qnil
;
3873 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
3875 FRAME_KBOARD (f
) = kb
;
3878 /* Specify the parent under which to make this window. */
3882 f
->output_data
.mac
->parent_desc
= (Window
) parent
;
3883 f
->output_data
.mac
->explicit_parent
= 1;
3887 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
3888 f
->output_data
.mac
->explicit_parent
= 0;
3891 /* Set the name; the functions to which we pass f expect the name to
3893 if (EQ (name
, Qunbound
) || NILP (name
))
3895 f
->name
= build_string (dpyinfo
->mac_id_name
);
3896 f
->explicit_name
= 0;
3901 f
->explicit_name
= 1;
3902 /* use the frame's title when getting resources for this frame. */
3903 specbind (Qx_resource_name
, name
);
3906 /* Extract the window parameters from the supplied values
3907 that are needed to determine window geometry. */
3911 font
= mac_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3914 /* First, try whatever font the caller has specified. */
3917 tem
= Fquery_fontset (font
, Qnil
);
3919 font
= x_new_fontset (f
, SDATA (tem
));
3921 font
= x_new_font (f
, SDATA (font
));
3923 /* Try out a font which we hope has bold and italic variations. */
3924 if (! STRINGP (font
))
3925 font
= x_new_font (f
, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
3926 /* If those didn't work, look for something which will at least work. */
3927 if (!STRINGP (font
))
3928 font
= x_new_font (f
, "-*-monaco-*-12-*-mac-roman");
3929 if (! STRINGP (font
))
3930 font
= x_new_font (f
, "-*-courier-*-10-*-mac-roman");
3931 if (! STRINGP (font
))
3932 error ("Cannot find any usable font");
3935 x_default_parameter (f
, parms
, Qfont
, font
,
3936 "font", "Font", RES_TYPE_STRING
);
3939 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
3940 "borderwidth", "BorderWidth", RES_TYPE_NUMBER
);
3941 /* This defaults to 2 in order to match xterm. We recognize either
3942 internalBorderWidth or internalBorder (which is what xterm calls
3944 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3948 value
= mac_get_arg (parms
, Qinternal_border_width
,
3949 "internalBorder", "InternalBorder", RES_TYPE_NUMBER
);
3950 if (! EQ (value
, Qunbound
))
3951 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3954 /* Default internalBorderWidth to 0 on Windows to match other programs. */
3955 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (0),
3956 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER
);
3957 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qright
,
3958 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL
);
3960 /* Also do the stuff which must be set before the window exists. */
3961 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3962 "foreground", "Foreground", RES_TYPE_STRING
);
3963 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3964 "background", "Background", RES_TYPE_STRING
);
3965 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3966 "pointerColor", "Foreground", RES_TYPE_STRING
);
3967 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3968 "cursorColor", "Foreground", RES_TYPE_STRING
);
3969 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3970 "borderColor", "BorderColor", RES_TYPE_STRING
);
3971 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3972 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3973 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3974 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3975 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3976 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3977 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3978 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3981 /* Init faces before x_default_parameter is called for scroll-bar
3982 parameters because that function calls x_set_scroll_bar_width,
3983 which calls change_frame_size, which calls Fset_window_buffer,
3984 which runs hooks, which call Fvertical_motion. At the end, we
3985 end up in init_iterator with a null face cache, which should not
3987 init_frame_faces (f
);
3989 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3990 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3991 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (0),
3992 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3993 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3994 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL
);
3995 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3996 "title", "Title", RES_TYPE_STRING
);
3998 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
3999 window_prompting
= x_figure_window_size (f
, parms
);
4001 if (window_prompting
& XNegative
)
4003 if (window_prompting
& YNegative
)
4004 f
->output_data
.mac
->win_gravity
= SouthEastGravity
;
4006 f
->output_data
.mac
->win_gravity
= NorthEastGravity
;
4010 if (window_prompting
& YNegative
)
4011 f
->output_data
.mac
->win_gravity
= SouthWestGravity
;
4013 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
4016 f
->output_data
.mac
->size_hint_flags
= window_prompting
;
4018 tem
= mac_get_arg (parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
4019 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
4021 /* Create the window. Add the tool-bar height to the initial frame
4022 height so that the user gets a text display area of the size he
4023 specified with -g or via the registry. Later changes of the
4024 tool-bar height don't change the frame size. This is done so that
4025 users can create tall Emacs frames without having to guess how
4026 tall the tool-bar will get. */
4027 f
->height
+= FRAME_TOOL_BAR_LINES (f
);
4029 /* mac_window (f, window_prompting, minibuffer_only); */
4036 /* Now consider the frame official. */
4037 FRAME_MAC_DISPLAY_INFO (f
)->reference_count
++;
4038 Vframe_list
= Fcons (frame
, Vframe_list
);
4040 /* We need to do this after creating the window, so that the
4041 icon-creation functions can say whose icon they're describing. */
4042 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
4043 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
4045 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
4046 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4047 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
4048 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4049 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
4050 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
4051 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
4052 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER
);
4054 /* Dimensions, especially f->height, must be done via change_frame_size.
4055 Change will not be effected unless different from the current
4061 SET_FRAME_WIDTH (f
, 0);
4062 change_frame_size (f
, height
, width
, 1, 0, 0);
4064 /* Set up faces after all frame parameters are known. */
4065 call1 (Qface_set_after_frame_default
, frame
);
4067 #if 0 /* MAC_TODO: when we have window manager hints */
4068 /* Tell the server what size and position, etc, we want, and how
4069 badly we want them. This should be done after we have the menu
4070 bar so that its size can be taken into account. */
4072 x_wm_set_size_hint (f
, window_prompting
, 0);
4076 /* Make the window appear on the frame and enable display, unless
4077 the caller says not to. However, with explicit parent, Emacs
4078 cannot control visibility, so don't try. */
4079 if (! f
->output_data
.mac
->explicit_parent
)
4081 Lisp_Object visibility
;
4083 visibility
= mac_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
);
4084 if (EQ (visibility
, Qunbound
))
4087 #if 0 /* MAC_TODO: really no iconify on Mac */
4088 if (EQ (visibility
, Qicon
))
4089 x_iconify_frame (f
);
4092 if (! NILP (visibility
))
4093 x_make_frame_visible (f
);
4095 /* Must have been Qnil. */
4100 /* Make sure windows on this frame appear in calls to next-window
4101 and similar functions. */
4102 Vwindow_list
= Qnil
;
4104 return unbind_to (count
, frame
);
4107 /* FRAME is used only to get a handle on the X display. We don't pass the
4108 display info directly because we're called from frame.c, which doesn't
4109 know about that structure. */
4111 x_get_focus_frame (frame
)
4112 struct frame
*frame
;
4114 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
4116 if (! dpyinfo
->x_focus_frame
)
4119 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
4123 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
4124 doc
: /* Internal function called by `color-defined-p', which see. */)
4126 Lisp_Object color
, frame
;
4129 FRAME_PTR f
= check_x_frame (frame
);
4131 CHECK_STRING (color
);
4133 if (mac_defined_color (f
, SDATA (color
), &foo
, 0))
4139 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
4140 doc
: /* Internal function called by `color-values', which see. */)
4142 Lisp_Object color
, frame
;
4145 FRAME_PTR f
= check_x_frame (frame
);
4147 CHECK_STRING (color
);
4149 if (mac_defined_color (f
, SDATA (color
), &foo
, 0))
4153 rgb
[0] = make_number ((RED_FROM_ULONG (foo
.pixel
) << 8)
4154 | RED_FROM_ULONG (foo
.pixel
));
4155 rgb
[1] = make_number ((GREEN_FROM_ULONG (foo
.pixel
) << 8)
4156 | GREEN_FROM_ULONG (foo
.pixel
));
4157 rgb
[2] = make_number ((BLUE_FROM_ULONG (foo
.pixel
) << 8)
4158 | BLUE_FROM_ULONG (foo
.pixel
));
4159 return Flist (3, rgb
);
4165 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
4166 doc
: /* Internal function called by `display-color-p', which see. */)
4168 Lisp_Object display
;
4170 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4172 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 2)
4178 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
4180 doc
: /* Return t if the X display supports shades of gray.
4181 Note that color displays do support shades of gray.
4182 The optional argument DISPLAY specifies which display to ask about.
4183 DISPLAY should be either a frame or a display name (a string).
4184 If omitted or nil, that stands for the selected frame's display. */)
4186 Lisp_Object display
;
4188 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4190 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 1)
4196 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
4198 doc
: /* Returns the width in pixels of the X display DISPLAY.
4199 The optional argument DISPLAY specifies which display to ask about.
4200 DISPLAY should be either a frame or a display name (a string).
4201 If omitted or nil, that stands for the selected frame's display. */)
4203 Lisp_Object display
;
4205 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4207 return make_number (dpyinfo
->width
);
4210 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
4211 Sx_display_pixel_height
, 0, 1, 0,
4212 doc
: /* Returns the height in pixels of the X display DISPLAY.
4213 The optional argument DISPLAY specifies which display to ask about.
4214 DISPLAY should be either a frame or a display name (a string).
4215 If omitted or nil, that stands for the selected frame's display. */)
4217 Lisp_Object display
;
4219 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4221 return make_number (dpyinfo
->height
);
4224 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
4226 doc
: /* Returns the number of bitplanes of the display DISPLAY.
4227 The optional argument DISPLAY specifies which display to ask about.
4228 DISPLAY should be either a frame or a display name (a string).
4229 If omitted or nil, that stands for the selected frame's display. */)
4231 Lisp_Object display
;
4233 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4235 return make_number (dpyinfo
->n_planes
* dpyinfo
->n_cbits
);
4238 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
4240 doc
: /* Returns the number of color cells of the display DISPLAY.
4241 The optional argument DISPLAY specifies which display to ask about.
4242 DISPLAY should be either a frame or a display name (a string).
4243 If omitted or nil, that stands for the selected frame's display. */)
4245 Lisp_Object display
;
4247 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4249 /* MAC_TODO: check whether this is right */
4250 return make_number ((unsigned long) (pow (2, dpyinfo
->n_cbits
)));
4253 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
4254 Sx_server_max_request_size
,
4256 doc
: /* Returns the maximum request size of the server of display DISPLAY.
4257 The optional argument DISPLAY specifies which display to ask about.
4258 DISPLAY should be either a frame or a display name (a string).
4259 If omitted or nil, that stands for the selected frame's display. */)
4261 Lisp_Object display
;
4263 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4265 return make_number (1);
4268 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
4269 doc
: /* Returns the vendor ID string of the Mac OS system (Apple).
4270 The optional argument DISPLAY specifies which display to ask about.
4271 DISPLAY should be either a frame or a display name (a string).
4272 If omitted or nil, that stands for the selected frame's display. */)
4274 Lisp_Object display
;
4276 return build_string ("Apple Computers");
4279 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
4280 doc
: /* Returns the version numbers of the server of display DISPLAY.
4281 The value is a list of three integers: the major and minor
4282 version numbers, and the vendor-specific release
4283 number. See also the function `x-server-vendor'.
4285 The optional argument DISPLAY specifies which display to ask about.
4286 DISPLAY should be either a frame or a display name (a string).
4287 If omitted or nil, that stands for the selected frame's display. */)
4289 Lisp_Object display
;
4291 int mac_major_version
, mac_minor_version
;
4294 if (Gestalt (gestaltSystemVersion
, &response
) != noErr
)
4295 error ("Cannot get Mac OS version");
4297 mac_major_version
= (response
>> 8) & 0xf;
4298 mac_minor_version
= (response
>> 4) & 0xf;
4300 return Fcons (make_number (mac_major_version
),
4301 Fcons (make_number (mac_minor_version
), Qnil
));
4304 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
4305 doc
: /* Return the number of screens on the server of display DISPLAY.
4306 The optional argument DISPLAY specifies which display to ask about.
4307 DISPLAY should be either a frame or a display name (a string).
4308 If omitted or nil, that stands for the selected frame's display. */)
4310 Lisp_Object display
;
4312 return make_number (1);
4315 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
4316 doc
: /* Return the height in millimeters of the X display DISPLAY.
4317 The optional argument DISPLAY specifies which display to ask about.
4318 DISPLAY should be either a frame or a display name (a string).
4319 If omitted or nil, that stands for the selected frame's display. */)
4321 Lisp_Object display
;
4323 /* MAC_TODO: this is an approximation, and only of the main display */
4325 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4330 return make_number ((int) (v
/ 72.0 * 25.4));
4333 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
4334 doc
: /* Return the width in millimeters of the X display DISPLAY.
4335 The optional argument DISPLAY specifies which display to ask about.
4336 DISPLAY should be either a frame or a display name (a string).
4337 If omitted or nil, that stands for the selected frame's display. */)
4339 Lisp_Object display
;
4341 /* MAC_TODO: this is an approximation, and only of the main display */
4343 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4348 return make_number ((int) (h
/ 72.0 * 25.4));
4351 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
4352 Sx_display_backing_store
, 0, 1, 0,
4353 doc
: /* Returns an indication of whether display DISPLAY does backing store.
4354 The value may be `always', `when-mapped', or `not-useful'.
4355 The optional argument DISPLAY specifies which display to ask about.
4356 DISPLAY should be either a frame or a display name (a string).
4357 If omitted or nil, that stands for the selected frame's display. */)
4359 Lisp_Object display
;
4361 return intern ("not-useful");
4364 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
4365 Sx_display_visual_class
, 0, 1, 0,
4366 doc
: /* Returns the visual class of the display DISPLAY.
4367 The value is one of the symbols `static-gray', `gray-scale',
4368 `static-color', `pseudo-color', `true-color', or `direct-color'.
4370 The optional argument DISPLAY specifies which display to ask about.
4371 DISPLAY should be either a frame or a display name (a string).
4372 If omitted or nil, that stands for the selected frame's display. */)
4374 Lisp_Object display
;
4376 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4379 switch (dpyinfo
->visual
->class)
4381 case StaticGray
: return (intern ("static-gray"));
4382 case GrayScale
: return (intern ("gray-scale"));
4383 case StaticColor
: return (intern ("static-color"));
4384 case PseudoColor
: return (intern ("pseudo-color"));
4385 case TrueColor
: return (intern ("true-color"));
4386 case DirectColor
: return (intern ("direct-color"));
4388 error ("Display has an unknown visual class");
4392 return (intern ("true-color"));
4395 DEFUN ("x-display-save-under", Fx_display_save_under
,
4396 Sx_display_save_under
, 0, 1, 0,
4397 doc
: /* Returns t if the display DISPLAY supports the save-under feature.
4398 The optional argument DISPLAY specifies which display to ask about.
4399 DISPLAY should be either a frame or a display name (a string).
4400 If omitted or nil, that stands for the selected frame's display. */)
4402 Lisp_Object display
;
4409 register struct frame
*f
;
4411 return PIXEL_WIDTH (f
);
4416 register struct frame
*f
;
4418 return PIXEL_HEIGHT (f
);
4423 register struct frame
*f
;
4425 return FONT_WIDTH (f
->output_data
.mac
->font
);
4430 register struct frame
*f
;
4432 return f
->output_data
.mac
->line_height
;
4437 register struct frame
*f
;
4439 return FRAME_MAC_DISPLAY_INFO (f
)->n_planes
;
4442 /* Return the display structure for the display named NAME.
4443 Open a new connection if necessary. */
4445 struct mac_display_info
*
4446 x_display_info_for_name (name
)
4450 struct mac_display_info
*dpyinfo
;
4452 CHECK_STRING (name
);
4454 for (dpyinfo
= &one_mac_display_info
, names
= x_display_name_list
;
4456 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4459 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4464 /* Use this general default value to start with. */
4465 Vx_resource_name
= Vinvocation_name
;
4467 validate_x_resource_name ();
4469 dpyinfo
= mac_term_init (name
, (unsigned char *) 0,
4470 (char *) SDATA (Vx_resource_name
));
4473 error ("Cannot connect to server %s", SDATA (name
));
4476 XSETFASTINT (Vwindow_system_version
, 3);
4481 #if 0 /* MAC_TODO: implement network support */
4482 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4484 doc
: /* Open a connection to a server.
4485 DISPLAY is the name of the display to connect to.
4486 Optional second arg XRM-STRING is a string of resources in xrdb format.
4487 If the optional third arg MUST-SUCCEED is non-nil,
4488 terminate Emacs if we can't open the connection. */)
4489 (display
, xrm_string
, must_succeed
)
4490 Lisp_Object display
, xrm_string
, must_succeed
;
4492 unsigned char *xrm_option
;
4493 struct mac_display_info
*dpyinfo
;
4495 CHECK_STRING (display
);
4496 if (! NILP (xrm_string
))
4497 CHECK_STRING (xrm_string
);
4499 if (! EQ (Vwindow_system
, intern ("mac")))
4500 error ("Not using Mac OS");
4502 if (! NILP (xrm_string
))
4503 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4505 xrm_option
= (unsigned char *) 0;
4507 validate_x_resource_name ();
4509 /* This is what opens the connection and sets x_current_display.
4510 This also initializes many symbols, such as those used for input. */
4511 dpyinfo
= mac_term_init (display
, xrm_option
,
4512 (char *) SDATA (Vx_resource_name
));
4516 if (!NILP (must_succeed
))
4517 fatal ("Cannot connect to server %s.\n",
4520 error ("Cannot connect to server %s", SDATA (display
));
4525 XSETFASTINT (Vwindow_system_version
, 3);
4529 DEFUN ("x-close-connection", Fx_close_connection
,
4530 Sx_close_connection
, 1, 1, 0,
4531 doc
: /* Close the connection to DISPLAY's server.
4532 For DISPLAY, specify either a frame or a display name (a string).
4533 If DISPLAY is nil, that stands for the selected frame's display. */)
4535 Lisp_Object display
;
4537 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4540 if (dpyinfo
->reference_count
> 0)
4541 error ("Display still has frames on it");
4544 /* Free the fonts in the font table. */
4545 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4546 if (dpyinfo
->font_table
[i
].name
)
4548 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
4549 xfree (dpyinfo
->font_table
[i
].full_name
);
4550 xfree (dpyinfo
->font_table
[i
].name
);
4551 x_unload_font (dpyinfo
, dpyinfo
->font_table
[i
].font
);
4553 x_destroy_all_bitmaps (dpyinfo
);
4555 x_delete_display (dpyinfo
);
4562 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4563 doc
: /* Return the list of display names that Emacs has connections to. */)
4566 Lisp_Object tail
, result
;
4569 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4570 result
= Fcons (XCAR (XCAR (tail
)), result
);
4575 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4576 doc
: /* If ON is non-nil, report errors as soon as the erring request is made.
4577 If ON is nil, allow buffering of requests.
4578 This is a noop on Mac OS systems.
4579 The optional second argument DISPLAY specifies which display to act on.
4580 DISPLAY should be either a frame or a display name (a string).
4581 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4583 Lisp_Object display
, on
;
4589 /***********************************************************************
4591 ***********************************************************************/
4593 /* Value is the number of elements of vector VECTOR. */
4595 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4597 /* List of supported image types. Use define_image_type to add new
4598 types. Use lookup_image_type to find a type for a given symbol. */
4600 static struct image_type
*image_types
;
4602 /* The symbol `image' which is the car of the lists used to represent
4605 extern Lisp_Object Qimage
;
4607 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4613 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4614 extern Lisp_Object QCdata
, QCtype
;
4615 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4616 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4617 Lisp_Object QCindex
;
4619 /* Other symbols. */
4621 Lisp_Object Qlaplace
;
4623 /* Time in seconds after which images should be removed from the cache
4624 if not displayed. */
4626 Lisp_Object Vimage_cache_eviction_delay
;
4628 /* Function prototypes. */
4630 static void define_image_type
P_ ((struct image_type
*type
));
4631 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4632 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4633 static void x_laplace
P_ ((struct frame
*, struct image
*));
4634 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4638 /* Define a new image type from TYPE. This adds a copy of TYPE to
4639 image_types and adds the symbol *TYPE->type to Vimage_types. */
4642 define_image_type (type
)
4643 struct image_type
*type
;
4645 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4646 The initialized data segment is read-only. */
4647 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4648 bcopy (type
, p
, sizeof *p
);
4649 p
->next
= image_types
;
4651 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4655 /* Look up image type SYMBOL, and return a pointer to its image_type
4656 structure. Value is null if SYMBOL is not a known image type. */
4658 static INLINE
struct image_type
*
4659 lookup_image_type (symbol
)
4662 struct image_type
*type
;
4664 for (type
= image_types
; type
; type
= type
->next
)
4665 if (EQ (symbol
, *type
->type
))
4672 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4673 valid image specification is a list whose car is the symbol
4674 `image', and whose rest is a property list. The property list must
4675 contain a value for key `:type'. That value must be the name of a
4676 supported image type. The rest of the property list depends on the
4680 valid_image_p (object
)
4685 if (CONSP (object
) && EQ (XCAR (object
), Qimage
))
4687 Lisp_Object symbol
= Fplist_get (XCDR (object
), QCtype
);
4688 struct image_type
*type
= lookup_image_type (symbol
);
4691 valid_p
= type
->valid_p (object
);
4698 /* Log error message with format string FORMAT and argument ARG.
4699 Signaling an error, e.g. when an image cannot be loaded, is not a
4700 good idea because this would interrupt redisplay, and the error
4701 message display would lead to another redisplay. This function
4702 therefore simply displays a message. */
4705 image_error (format
, arg1
, arg2
)
4707 Lisp_Object arg1
, arg2
;
4709 add_to_log (format
, arg1
, arg2
);
4714 /***********************************************************************
4715 Image specifications
4716 ***********************************************************************/
4718 enum image_value_type
4720 IMAGE_DONT_CHECK_VALUE_TYPE
,
4723 IMAGE_POSITIVE_INTEGER_VALUE
,
4724 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4725 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4727 IMAGE_INTEGER_VALUE
,
4728 IMAGE_FUNCTION_VALUE
,
4733 /* Structure used when parsing image specifications. */
4735 struct image_keyword
4737 /* Name of keyword. */
4740 /* The type of value allowed. */
4741 enum image_value_type type
;
4743 /* Non-zero means key must be present. */
4746 /* Used to recognize duplicate keywords in a property list. */
4749 /* The value that was found. */
4754 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4756 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4759 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4760 has the format (image KEYWORD VALUE ...). One of the keyword/
4761 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4762 image_keywords structures of size NKEYWORDS describing other
4763 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4766 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4768 struct image_keyword
*keywords
;
4775 if (!CONSP (spec
) || !EQ (XCAR (spec
), Qimage
))
4778 plist
= XCDR (spec
);
4779 while (CONSP (plist
))
4781 Lisp_Object key
, value
;
4783 /* First element of a pair must be a symbol. */
4785 plist
= XCDR (plist
);
4789 /* There must follow a value. */
4792 value
= XCAR (plist
);
4793 plist
= XCDR (plist
);
4795 /* Find key in KEYWORDS. Error if not found. */
4796 for (i
= 0; i
< nkeywords
; ++i
)
4797 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
4803 /* Record that we recognized the keyword. If a keywords
4804 was found more than once, it's an error. */
4805 keywords
[i
].value
= value
;
4806 ++keywords
[i
].count
;
4808 if (keywords
[i
].count
> 1)
4811 /* Check type of value against allowed type. */
4812 switch (keywords
[i
].type
)
4814 case IMAGE_STRING_VALUE
:
4815 if (!STRINGP (value
))
4819 case IMAGE_SYMBOL_VALUE
:
4820 if (!SYMBOLP (value
))
4824 case IMAGE_POSITIVE_INTEGER_VALUE
:
4825 if (!INTEGERP (value
) || XINT (value
) <= 0)
4829 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4830 if (INTEGERP (value
) && XINT (value
) >= 0)
4833 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4834 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4838 case IMAGE_ASCENT_VALUE
:
4839 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4841 else if (INTEGERP (value
)
4842 && XINT (value
) >= 0
4843 && XINT (value
) <= 100)
4847 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4848 if (!INTEGERP (value
) || XINT (value
) < 0)
4852 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4855 case IMAGE_FUNCTION_VALUE
:
4856 value
= indirect_function (value
);
4858 || COMPILEDP (value
)
4859 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4863 case IMAGE_NUMBER_VALUE
:
4864 if (!INTEGERP (value
) && !FLOATP (value
))
4868 case IMAGE_INTEGER_VALUE
:
4869 if (!INTEGERP (value
))
4873 case IMAGE_BOOL_VALUE
:
4874 if (!NILP (value
) && !EQ (value
, Qt
))
4883 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4887 /* Check that all mandatory fields are present. */
4888 for (i
= 0; i
< nkeywords
; ++i
)
4889 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4892 return NILP (plist
);
4896 /* Return the value of KEY in image specification SPEC. Value is nil
4897 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4898 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4901 image_spec_value (spec
, key
, found
)
4902 Lisp_Object spec
, key
;
4907 xassert (valid_image_p (spec
));
4909 for (tail
= XCDR (spec
);
4910 CONSP (tail
) && CONSP (XCDR (tail
));
4911 tail
= XCDR (XCDR (tail
)))
4913 if (EQ (XCAR (tail
), key
))
4917 return XCAR (XCDR (tail
));
4929 /***********************************************************************
4930 Image type independent image structures
4931 ***********************************************************************/
4933 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4934 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4937 /* Allocate and return a new image structure for image specification
4938 SPEC. SPEC has a hash value of HASH. */
4940 static struct image
*
4941 make_image (spec
, hash
)
4945 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4947 xassert (valid_image_p (spec
));
4948 bzero (img
, sizeof *img
);
4949 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4950 xassert (img
->type
!= NULL
);
4952 img
->data
.lisp_val
= Qnil
;
4953 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
4959 /* Free image IMG which was used on frame F, including its resources. */
4968 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4970 /* Remove IMG from the hash table of its cache. */
4972 img
->prev
->next
= img
->next
;
4974 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
4977 img
->next
->prev
= img
->prev
;
4979 c
->images
[img
->id
] = NULL
;
4981 /* Free resources, then free IMG. */
4982 img
->type
->free (f
, img
);
4988 /* Prepare image IMG for display on frame F. Must be called before
4989 drawing an image. */
4992 prepare_image_for_display (f
, img
)
4998 /* We're about to display IMG, so set its timestamp to `now'. */
5000 img
->timestamp
= EMACS_SECS (t
);
5002 /* If IMG doesn't have a pixmap yet, load it now, using the image
5003 type dependent loader function. */
5004 if (img
->pixmap
== 0 && !img
->load_failed_p
)
5005 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5009 /* Value is the number of pixels for the ascent of image IMG when
5010 drawn in face FACE. */
5013 image_ascent (img
, face
)
5017 int height
= img
->height
+ img
->vmargin
;
5020 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
5023 ascent
= height
/ 2 - (FONT_DESCENT(face
->font
)
5024 - FONT_BASE(face
->font
)) / 2;
5026 ascent
= height
/ 2;
5029 ascent
= height
* img
->ascent
/ 100.0;
5036 /***********************************************************************
5037 Helper functions for X image types
5038 ***********************************************************************/
5040 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
5041 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
5043 Lisp_Object color_name
,
5044 unsigned long dflt
));
5046 /* Free X resources of image IMG which is used on frame F. */
5049 x_clear_image (f
, img
)
5053 #if 0 /* MAC_TODO: W32 image support */
5058 XFreePixmap (NULL
, img
->pixmap
);
5065 int class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
5067 /* If display has an immutable color map, freeing colors is not
5068 necessary and some servers don't allow it. So don't do it. */
5069 if (class != StaticColor
5070 && class != StaticGray
5071 && class != TrueColor
)
5075 cmap
= DefaultColormapOfScreen (FRAME_W32_DISPLAY_INFO (f
)->screen
);
5076 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
, img
->colors
,
5081 xfree (img
->colors
);
5085 #endif /* MAC_TODO */
5089 /* Allocate color COLOR_NAME for image IMG on frame F. If color
5090 cannot be allocated, use DFLT. Add a newly allocated color to
5091 IMG->colors, so that it can be freed again. Value is the pixel
5094 static unsigned long
5095 x_alloc_image_color (f
, img
, color_name
, dflt
)
5098 Lisp_Object color_name
;
5101 #if 0 /* MAC_TODO: allocing colors. */
5103 unsigned long result
;
5105 xassert (STRINGP (color_name
));
5107 if (w32_defined_color (f
, SDATA (color_name
), &color
, 1))
5109 /* This isn't called frequently so we get away with simply
5110 reallocating the color vector to the needed size, here. */
5113 (unsigned long *) xrealloc (img
->colors
,
5114 img
->ncolors
* sizeof *img
->colors
);
5115 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
5116 result
= color
.pixel
;
5121 #endif /* MAC_TODO */
5127 /***********************************************************************
5129 ***********************************************************************/
5131 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
5134 /* Return a new, initialized image cache that is allocated from the
5135 heap. Call free_image_cache to free an image cache. */
5137 struct image_cache
*
5140 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
5143 bzero (c
, sizeof *c
);
5145 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
5146 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
5147 c
->buckets
= (struct image
**) xmalloc (size
);
5148 bzero (c
->buckets
, size
);
5153 /* Free image cache of frame F. Be aware that X frames share images
5157 free_image_cache (f
)
5160 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5165 /* Cache should not be referenced by any frame when freed. */
5166 xassert (c
->refcount
== 0);
5168 for (i
= 0; i
< c
->used
; ++i
)
5169 free_image (f
, c
->images
[i
]);
5173 FRAME_X_IMAGE_CACHE (f
) = NULL
;
5178 /* Clear image cache of frame F. FORCE_P non-zero means free all
5179 images. FORCE_P zero means clear only images that haven't been
5180 displayed for some time. Should be called from time to time to
5181 reduce the number of loaded images. If image-eviction-seconds is
5182 non-nil, this frees images in the cache which weren't displayed for
5183 at least that many seconds. */
5186 clear_image_cache (f
, force_p
)
5190 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5192 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
5196 int i
, any_freed_p
= 0;
5199 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
5201 for (i
= 0; i
< c
->used
; ++i
)
5203 struct image
*img
= c
->images
[i
];
5206 || (img
->timestamp
> old
)))
5208 free_image (f
, img
);
5213 /* We may be clearing the image cache because, for example,
5214 Emacs was iconified for a longer period of time. In that
5215 case, current matrices may still contain references to
5216 images freed above. So, clear these matrices. */
5219 clear_current_matrices (f
);
5220 ++windows_or_buffers_changed
;
5226 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
5228 doc
: /* Clear the image cache of FRAME.
5229 FRAME nil or omitted means use the selected frame.
5230 FRAME t means clear the image caches of all frames. */)
5238 FOR_EACH_FRAME (tail
, frame
)
5239 if (FRAME_MAC_P (XFRAME (frame
)))
5240 clear_image_cache (XFRAME (frame
), 1);
5243 clear_image_cache (check_x_frame (frame
), 1);
5249 /* Return the id of image with Lisp specification SPEC on frame F.
5250 SPEC must be a valid Lisp image specification (see valid_image_p). */
5253 lookup_image (f
, spec
)
5257 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5261 struct gcpro gcpro1
;
5264 /* F must be a window-system frame, and SPEC must be a valid image
5266 xassert (FRAME_WINDOW_P (f
));
5267 xassert (valid_image_p (spec
));
5271 /* Look up SPEC in the hash table of the image cache. */
5272 hash
= sxhash (spec
, 0);
5273 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5275 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5276 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5279 /* If not found, create a new image and cache it. */
5283 img
= make_image (spec
, hash
);
5284 cache_image (f
, img
);
5285 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5286 xassert (!interrupt_input_blocked
);
5288 /* If we can't load the image, and we don't have a width and
5289 height, use some arbitrary width and height so that we can
5290 draw a rectangle for it. */
5291 if (img
->load_failed_p
)
5295 value
= image_spec_value (spec
, QCwidth
, NULL
);
5296 img
->width
= (INTEGERP (value
)
5297 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5298 value
= image_spec_value (spec
, QCheight
, NULL
);
5299 img
->height
= (INTEGERP (value
)
5300 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5304 /* Handle image type independent image attributes
5305 `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF'. */
5306 Lisp_Object ascent
, margin
, relief
;
5308 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5309 if (INTEGERP (ascent
))
5310 img
->ascent
= XFASTINT (ascent
);
5311 else if (EQ (ascent
, Qcenter
))
5312 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5314 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5315 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5316 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5317 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5318 && INTEGERP (XCDR (margin
)))
5320 if (XINT (XCAR (margin
)) > 0)
5321 img
->hmargin
= XFASTINT (XCAR (margin
));
5322 if (XINT (XCDR (margin
)) > 0)
5323 img
->vmargin
= XFASTINT (XCDR (margin
));
5326 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5327 if (INTEGERP (relief
))
5329 img
->relief
= XINT (relief
);
5330 img
->hmargin
+= abs (img
->relief
);
5331 img
->vmargin
+= abs (img
->relief
);
5336 /* We're using IMG, so set its timestamp to `now'. */
5337 EMACS_GET_TIME (now
);
5338 img
->timestamp
= EMACS_SECS (now
);
5342 /* Value is the image id. */
5347 /* Cache image IMG in the image cache of frame F. */
5350 cache_image (f
, img
)
5354 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5357 /* Find a free slot in c->images. */
5358 for (i
= 0; i
< c
->used
; ++i
)
5359 if (c
->images
[i
] == NULL
)
5362 /* If no free slot found, maybe enlarge c->images. */
5363 if (i
== c
->used
&& c
->used
== c
->size
)
5366 c
->images
= (struct image
**) xrealloc (c
->images
,
5367 c
->size
* sizeof *c
->images
);
5370 /* Add IMG to c->images, and assign IMG an id. */
5376 /* Add IMG to the cache's hash table. */
5377 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5378 img
->next
= c
->buckets
[i
];
5380 img
->next
->prev
= img
;
5382 c
->buckets
[i
] = img
;
5386 /* Call FN on every image in the image cache of frame F. Used to mark
5387 Lisp Objects in the image cache. */
5390 forall_images_in_image_cache (f
, fn
)
5392 void (*fn
) P_ ((struct image
*img
));
5394 if (FRAME_LIVE_P (f
) && FRAME_MAC_P (f
))
5396 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5400 for (i
= 0; i
< c
->used
; ++i
)
5409 /***********************************************************************
5411 ***********************************************************************/
5413 #if 0 /* MAC_TODO: Mac specific image code. */
5415 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5416 XImage
**, Pixmap
*));
5417 static void x_destroy_x_image
P_ ((XImage
*));
5418 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5421 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5422 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5423 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5424 via xmalloc. Print error messages via image_error if an error
5425 occurs. Value is non-zero if successful. */
5428 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5430 int width
, height
, depth
;
5434 #if 0 /* MAC_TODO: Image support for Mac */
5435 Display
*display
= FRAME_W32_DISPLAY (f
);
5436 Screen
*screen
= FRAME_X_SCREEN (f
);
5437 Window window
= FRAME_W32_WINDOW (f
);
5439 xassert (interrupt_input_blocked
);
5442 depth
= DefaultDepthOfScreen (screen
);
5443 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5444 depth
, ZPixmap
, 0, NULL
, width
, height
,
5445 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5448 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5452 /* Allocate image raster. */
5453 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5455 /* Allocate a pixmap of the same size. */
5456 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5459 x_destroy_x_image (*ximg
);
5461 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5464 #endif /* MAC_TODO */
5469 /* Destroy XImage XIMG. Free XIMG->data. */
5472 x_destroy_x_image (ximg
)
5475 xassert (interrupt_input_blocked
);
5480 XDestroyImage (ximg
);
5485 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5486 are width and height of both the image and pixmap. */
5489 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5496 xassert (interrupt_input_blocked
);
5497 gc
= XCreateGC (NULL
, pixmap
, 0, NULL
);
5498 XPutImage (NULL
, pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5502 #endif /* MAC_TODO */
5505 /***********************************************************************
5507 ***********************************************************************/
5509 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5511 /* Find image file FILE. Look in data-directory, then
5512 x-bitmap-file-path. Value is the full name of the file found, or
5513 nil if not found. */
5516 x_find_image_file (file
)
5519 Lisp_Object file_found
, search_path
;
5520 struct gcpro gcpro1
, gcpro2
;
5524 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5525 GCPRO2 (file_found
, search_path
);
5527 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5528 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5540 /***********************************************************************
5542 ***********************************************************************/
5544 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5545 static int xbm_load_image_from_file
P_ ((struct frame
*f
, struct image
*img
,
5547 static int xbm_image_p
P_ ((Lisp_Object object
));
5548 static int xbm_read_bitmap_file_data
P_ ((char *, int *, int *,
5552 /* Indices of image specification fields in xbm_format, below. */
5554 enum xbm_keyword_index
5571 /* Vector of image_keyword structures describing the format
5572 of valid XBM image specifications. */
5574 static struct image_keyword xbm_format
[XBM_LAST
] =
5576 {":type", IMAGE_SYMBOL_VALUE
, 1},
5577 {":file", IMAGE_STRING_VALUE
, 0},
5578 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5579 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5580 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5581 {":foreground", IMAGE_STRING_VALUE
, 0},
5582 {":background", IMAGE_STRING_VALUE
, 0},
5583 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
5584 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5585 {":relief", IMAGE_INTEGER_VALUE
, 0},
5586 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5587 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5590 /* Structure describing the image type XBM. */
5592 static struct image_type xbm_type
=
5601 /* Tokens returned from xbm_scan. */
5610 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5611 A valid specification is a list starting with the symbol `image'
5612 The rest of the list is a property list which must contain an
5615 If the specification specifies a file to load, it must contain
5616 an entry `:file FILENAME' where FILENAME is a string.
5618 If the specification is for a bitmap loaded from memory it must
5619 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5620 WIDTH and HEIGHT are integers > 0. DATA may be:
5622 1. a string large enough to hold the bitmap data, i.e. it must
5623 have a size >= (WIDTH + 7) / 8 * HEIGHT
5625 2. a bool-vector of size >= WIDTH * HEIGHT
5627 3. a vector of strings or bool-vectors, one for each line of the
5630 Both the file and data forms may contain the additional entries
5631 `:background COLOR' and `:foreground COLOR'. If not present,
5632 foreground and background of the frame on which the image is
5633 displayed, is used. */
5636 xbm_image_p (object
)
5639 struct image_keyword kw
[XBM_LAST
];
5641 bcopy (xbm_format
, kw
, sizeof kw
);
5642 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5645 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5647 if (kw
[XBM_FILE
].count
)
5649 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5657 /* Entries for `:width', `:height' and `:data' must be present. */
5658 if (!kw
[XBM_WIDTH
].count
5659 || !kw
[XBM_HEIGHT
].count
5660 || !kw
[XBM_DATA
].count
)
5663 data
= kw
[XBM_DATA
].value
;
5664 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5665 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5667 /* Check type of data, and width and height against contents of
5673 /* Number of elements of the vector must be >= height. */
5674 if (XVECTOR (data
)->size
< height
)
5677 /* Each string or bool-vector in data must be large enough
5678 for one line of the image. */
5679 for (i
= 0; i
< height
; ++i
)
5681 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5686 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5689 else if (BOOL_VECTOR_P (elt
))
5691 if (XBOOL_VECTOR (elt
)->size
< width
)
5698 else if (STRINGP (data
))
5701 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5704 else if (BOOL_VECTOR_P (data
))
5706 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5713 /* Baseline must be a value between 0 and 100 (a percentage). */
5714 if (kw
[XBM_ASCENT
].count
5715 && XFASTINT (kw
[XBM_ASCENT
].value
) > 100)
5722 /* Scan a bitmap file. FP is the stream to read from. Value is
5723 either an enumerator from enum xbm_token, or a character for a
5724 single-character token, or 0 at end of file. If scanning an
5725 identifier, store the lexeme of the identifier in SVAL. If
5726 scanning a number, store its value in *IVAL. */
5729 xbm_scan (fp
, sval
, ival
)
5736 /* Skip white space. */
5737 while ((c
= fgetc (fp
)) != EOF
&& isspace (c
))
5742 else if (isdigit (c
))
5744 int value
= 0, digit
;
5749 if (c
== 'x' || c
== 'X')
5751 while ((c
= fgetc (fp
)) != EOF
)
5755 else if (c
>= 'a' && c
<= 'f')
5756 digit
= c
- 'a' + 10;
5757 else if (c
>= 'A' && c
<= 'F')
5758 digit
= c
- 'A' + 10;
5761 value
= 16 * value
+ digit
;
5764 else if (isdigit (c
))
5767 while ((c
= fgetc (fp
)) != EOF
5769 value
= 8 * value
+ c
- '0';
5775 while ((c
= fgetc (fp
)) != EOF
5777 value
= 10 * value
+ c
- '0';
5785 else if (isalpha (c
) || c
== '_')
5788 while ((c
= fgetc (fp
)) != EOF
5789 && (isalnum (c
) || c
== '_'))
5801 /* Replacement for XReadBitmapFileData which isn't available under old
5802 X versions. FILE is the name of the bitmap file to read. Set
5803 *WIDTH and *HEIGHT to the width and height of the image. Return in
5804 *DATA the bitmap data allocated with xmalloc. Value is non-zero if
5808 xbm_read_bitmap_file_data (file
, width
, height
, data
)
5810 int *width
, *height
;
5811 unsigned char **data
;
5814 char buffer
[BUFSIZ
];
5817 int bytes_per_line
, i
, nbytes
;
5823 LA1 = xbm_scan (fp, buffer, &value)
5825 #define expect(TOKEN) \
5826 if (LA1 != (TOKEN)) \
5831 #define expect_ident(IDENT) \
5832 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
5837 fp
= fopen (file
, "r");
5841 *width
= *height
= -1;
5843 LA1
= xbm_scan (fp
, buffer
, &value
);
5845 /* Parse defines for width, height and hot-spots. */
5849 expect_ident ("define");
5850 expect (XBM_TK_IDENT
);
5852 if (LA1
== XBM_TK_NUMBER
);
5854 char *p
= strrchr (buffer
, '_');
5855 p
= p
? p
+ 1 : buffer
;
5856 if (strcmp (p
, "width") == 0)
5858 else if (strcmp (p
, "height") == 0)
5861 expect (XBM_TK_NUMBER
);
5864 if (*width
< 0 || *height
< 0)
5867 /* Parse bits. Must start with `static'. */
5868 expect_ident ("static");
5869 if (LA1
== XBM_TK_IDENT
)
5871 if (strcmp (buffer
, "unsigned") == 0)
5874 expect_ident ("char");
5876 else if (strcmp (buffer
, "short") == 0)
5880 if (*width
% 16 && *width
% 16 < 9)
5883 else if (strcmp (buffer
, "char") == 0)
5891 expect (XBM_TK_IDENT
);
5897 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
5898 nbytes
= bytes_per_line
* *height
;
5899 p
= *data
= (char *) xmalloc (nbytes
);
5904 for (i
= 0; i
< nbytes
; i
+= 2)
5907 expect (XBM_TK_NUMBER
);
5910 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
5913 if (LA1
== ',' || LA1
== '}')
5921 for (i
= 0; i
< nbytes
; ++i
)
5924 expect (XBM_TK_NUMBER
);
5928 if (LA1
== ',' || LA1
== '}')
5954 /* Load XBM image IMG which will be displayed on frame F from file
5955 SPECIFIED_FILE. Value is non-zero if successful. */
5958 xbm_load_image_from_file (f
, img
, specified_file
)
5961 Lisp_Object specified_file
;
5964 unsigned char *data
;
5967 struct gcpro gcpro1
;
5969 xassert (STRINGP (specified_file
));
5973 file
= x_find_image_file (specified_file
);
5974 if (!STRINGP (file
))
5976 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5981 rc
= xbm_read_bitmap_file_data (SDATA (file
), &img
->width
,
5982 &img
->height
, &data
);
5985 int depth
= one_mac_display_info
.n_cbits
;
5986 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
5987 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
5990 xassert (img
->width
> 0 && img
->height
> 0);
5992 /* Get foreground and background colors, maybe allocate colors. */
5993 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
5995 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
5997 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5999 background
= x_alloc_image_color (f
, img
, value
, background
);
6001 #if 0 /* MAC_TODO : Port image display to Mac */
6004 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
6005 FRAME_W32_WINDOW (f
),
6007 img
->width
, img
->height
,
6008 foreground
, background
,
6012 if (img
->pixmap
== 0)
6014 x_clear_image (f
, img
);
6015 image_error ("Unable to create X pixmap for `%s'", file
, Qnil
);
6021 #endif /* MAC_TODO */
6024 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6031 /* Fill image IMG which is used on frame F with pixmap data. Value is
6032 non-zero if successful. */
6040 Lisp_Object file_name
;
6042 xassert (xbm_image_p (img
->spec
));
6044 /* If IMG->spec specifies a file name, create a non-file spec from it. */
6045 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
6046 if (STRINGP (file_name
))
6047 success_p
= xbm_load_image_from_file (f
, img
, file_name
);
6050 struct image_keyword fmt
[XBM_LAST
];
6053 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6054 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6058 /* Parse the list specification. */
6059 bcopy (xbm_format
, fmt
, sizeof fmt
);
6060 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
6063 /* Get specified width, and height. */
6064 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
6065 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
6066 xassert (img
->width
> 0 && img
->height
> 0);
6070 if (fmt
[XBM_ASCENT
].count
)
6071 img
->ascent
= XFASTINT (fmt
[XBM_ASCENT
].value
);
6073 /* Get foreground and background colors, maybe allocate colors. */
6074 if (fmt
[XBM_FOREGROUND
].count
)
6075 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
6077 if (fmt
[XBM_BACKGROUND
].count
)
6078 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
6081 /* Set bits to the bitmap image data. */
6082 data
= fmt
[XBM_DATA
].value
;
6087 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
6089 p
= bits
= (char *) alloca (nbytes
* img
->height
);
6090 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
6092 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
6094 bcopy (SDATA (line
), p
, nbytes
);
6096 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
6099 else if (STRINGP (data
))
6100 bits
= SDATA (data
);
6102 bits
= XBOOL_VECTOR (data
)->data
;
6104 #if 0 /* MAC_TODO : port Mac display code */
6105 /* Create the pixmap. */
6106 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6108 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
6109 FRAME_W32_WINDOW (f
),
6111 img
->width
, img
->height
,
6112 foreground
, background
,
6114 #endif /* MAC_TODO */
6120 image_error ("Unable to create pixmap for XBM image `%s'",
6122 x_clear_image (f
, img
);
6133 /***********************************************************************
6135 ***********************************************************************/
6139 static int xpm_image_p
P_ ((Lisp_Object object
));
6140 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6141 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6143 #include "X11/xpm.h"
6145 /* The symbol `xpm' identifying XPM-format images. */
6149 /* Indices of image specification fields in xpm_format, below. */
6151 enum xpm_keyword_index
6165 /* Vector of image_keyword structures describing the format
6166 of valid XPM image specifications. */
6168 static struct image_keyword xpm_format
[XPM_LAST
] =
6170 {":type", IMAGE_SYMBOL_VALUE
, 1},
6171 {":file", IMAGE_STRING_VALUE
, 0},
6172 {":data", IMAGE_STRING_VALUE
, 0},
6173 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6174 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6175 {":relief", IMAGE_INTEGER_VALUE
, 0},
6176 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6177 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6178 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6181 /* Structure describing the image type XBM. */
6183 static struct image_type xpm_type
=
6193 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6194 for XPM images. Such a list must consist of conses whose car and
6198 xpm_valid_color_symbols_p (color_symbols
)
6199 Lisp_Object color_symbols
;
6201 while (CONSP (color_symbols
))
6203 Lisp_Object sym
= XCAR (color_symbols
);
6205 || !STRINGP (XCAR (sym
))
6206 || !STRINGP (XCDR (sym
)))
6208 color_symbols
= XCDR (color_symbols
);
6211 return NILP (color_symbols
);
6215 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6218 xpm_image_p (object
)
6221 struct image_keyword fmt
[XPM_LAST
];
6222 bcopy (xpm_format
, fmt
, sizeof fmt
);
6223 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6224 /* Either `:file' or `:data' must be present. */
6225 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6226 /* Either no `:color-symbols' or it's a list of conses
6227 whose car and cdr are strings. */
6228 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6229 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
))
6230 && (fmt
[XPM_ASCENT
].count
== 0
6231 || XFASTINT (fmt
[XPM_ASCENT
].value
) < 100));
6235 /* Load image IMG which will be displayed on frame F. Value is
6236 non-zero if successful. */
6244 XpmAttributes attrs
;
6245 Lisp_Object specified_file
, color_symbols
;
6247 /* Configure the XPM lib. Use the visual of frame F. Allocate
6248 close colors. Return colors allocated. */
6249 bzero (&attrs
, sizeof attrs
);
6250 attrs
.visual
= FRAME_X_VISUAL (f
);
6251 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6252 attrs
.valuemask
|= XpmVisual
;
6253 attrs
.valuemask
|= XpmColormap
;
6254 attrs
.valuemask
|= XpmReturnAllocPixels
;
6255 #ifdef XpmAllocCloseColors
6256 attrs
.alloc_close_colors
= 1;
6257 attrs
.valuemask
|= XpmAllocCloseColors
;
6259 attrs
.closeness
= 600;
6260 attrs
.valuemask
|= XpmCloseness
;
6263 /* If image specification contains symbolic color definitions, add
6264 these to `attrs'. */
6265 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6266 if (CONSP (color_symbols
))
6269 XpmColorSymbol
*xpm_syms
;
6272 attrs
.valuemask
|= XpmColorSymbols
;
6274 /* Count number of symbols. */
6275 attrs
.numsymbols
= 0;
6276 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6279 /* Allocate an XpmColorSymbol array. */
6280 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6281 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6282 bzero (xpm_syms
, size
);
6283 attrs
.colorsymbols
= xpm_syms
;
6285 /* Fill the color symbol array. */
6286 for (tail
= color_symbols
, i
= 0;
6288 ++i
, tail
= XCDR (tail
))
6290 Lisp_Object name
= XCAR (XCAR (tail
));
6291 Lisp_Object color
= XCDR (XCAR (tail
));
6292 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
6293 strcpy (xpm_syms
[i
].name
, SDATA (name
));
6294 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
6295 strcpy (xpm_syms
[i
].value
, SDATA (color
));
6299 /* Create a pixmap for the image, either from a file, or from a
6300 string buffer containing data in the same format as an XPM file. */
6302 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6303 if (STRINGP (specified_file
))
6305 Lisp_Object file
= x_find_image_file (specified_file
);
6306 if (!STRINGP (file
))
6308 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6313 rc
= XpmReadFileToPixmap (NULL
, FRAME_W32_WINDOW (f
),
6314 SDATA (file
), &img
->pixmap
, &img
->mask
,
6319 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6320 rc
= XpmCreatePixmapFromBuffer (NULL
, FRAME_W32_WINDOW (f
),
6322 &img
->pixmap
, &img
->mask
,
6327 if (rc
== XpmSuccess
)
6329 /* Remember allocated colors. */
6330 img
->ncolors
= attrs
.nalloc_pixels
;
6331 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6332 * sizeof *img
->colors
);
6333 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6334 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6336 img
->width
= attrs
.width
;
6337 img
->height
= attrs
.height
;
6338 xassert (img
->width
> 0 && img
->height
> 0);
6340 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6342 XpmFreeAttributes (&attrs
);
6350 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6353 case XpmFileInvalid
:
6354 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6358 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6361 case XpmColorFailed
:
6362 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6366 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6371 return rc
== XpmSuccess
;
6374 #endif /* HAVE_XPM != 0 */
6377 #if 0 /* MAC_TODO : Color tables on Mac. */
6378 /***********************************************************************
6380 ***********************************************************************/
6382 /* An entry in the color table mapping an RGB color to a pixel color. */
6387 unsigned long pixel
;
6389 /* Next in color table collision list. */
6390 struct ct_color
*next
;
6393 /* The bucket vector size to use. Must be prime. */
6397 /* Value is a hash of the RGB color given by R, G, and B. */
6399 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6401 /* The color hash table. */
6403 struct ct_color
**ct_table
;
6405 /* Number of entries in the color table. */
6407 int ct_colors_allocated
;
6409 /* Function prototypes. */
6411 static void init_color_table
P_ ((void));
6412 static void free_color_table
P_ ((void));
6413 static unsigned long *colors_in_color_table
P_ ((int *n
));
6414 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
6415 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
6418 /* Initialize the color table. */
6423 int size
= CT_SIZE
* sizeof (*ct_table
);
6424 ct_table
= (struct ct_color
**) xmalloc (size
);
6425 bzero (ct_table
, size
);
6426 ct_colors_allocated
= 0;
6430 /* Free memory associated with the color table. */
6436 struct ct_color
*p
, *next
;
6438 for (i
= 0; i
< CT_SIZE
; ++i
)
6439 for (p
= ct_table
[i
]; p
; p
= next
)
6450 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6451 entry for that color already is in the color table, return the
6452 pixel color of that entry. Otherwise, allocate a new color for R,
6453 G, B, and make an entry in the color table. */
6455 static unsigned long
6456 lookup_rgb_color (f
, r
, g
, b
)
6460 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6461 int i
= hash
% CT_SIZE
;
6464 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6465 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6474 color
= RGB_TO_ULONG (r
, g
, b
);
6476 ++ct_colors_allocated
;
6478 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6483 p
->next
= ct_table
[i
];
6491 /* Look up pixel color PIXEL which is used on frame F in the color
6492 table. If not already present, allocate it. Value is PIXEL. */
6494 static unsigned long
6495 lookup_pixel_color (f
, pixel
)
6497 unsigned long pixel
;
6499 int i
= pixel
% CT_SIZE
;
6502 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6503 if (p
->pixel
== pixel
)
6514 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6515 color
.pixel
= pixel
;
6516 XQueryColor (NULL
, cmap
, &color
);
6517 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6522 ++ct_colors_allocated
;
6524 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6529 p
->next
= ct_table
[i
];
6533 return FRAME_FOREGROUND_PIXEL (f
);
6539 /* Value is a vector of all pixel colors contained in the color table,
6540 allocated via xmalloc. Set *N to the number of colors. */
6542 static unsigned long *
6543 colors_in_color_table (n
)
6548 unsigned long *colors
;
6550 if (ct_colors_allocated
== 0)
6557 colors
= (unsigned long *) xmalloc (ct_colors_allocated
6559 *n
= ct_colors_allocated
;
6561 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
6562 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6563 colors
[j
++] = p
->pixel
;
6569 #endif /* MAC_TODO */
6572 /***********************************************************************
6574 ***********************************************************************/
6576 #if 0 /* MAC_TODO : Mac versions of low level algorithms */
6577 static void x_laplace_write_row
P_ ((struct frame
*, long *,
6578 int, XImage
*, int));
6579 static void x_laplace_read_row
P_ ((struct frame
*, Colormap
,
6580 XColor
*, int, XImage
*, int));
6583 /* Fill COLORS with RGB colors from row Y of image XIMG. F is the
6584 frame we operate on, CMAP is the color-map in effect, and WIDTH is
6585 the width of one row in the image. */
6588 x_laplace_read_row (f
, cmap
, colors
, width
, ximg
, y
)
6598 for (x
= 0; x
< width
; ++x
)
6599 colors
[x
].pixel
= XGetPixel (ximg
, x
, y
);
6601 XQueryColors (NULL
, cmap
, colors
, width
);
6605 /* Write row Y of image XIMG. PIXELS is an array of WIDTH longs
6606 containing the pixel colors to write. F is the frame we are
6610 x_laplace_write_row (f
, pixels
, width
, ximg
, y
)
6619 for (x
= 0; x
< width
; ++x
)
6620 XPutPixel (ximg
, x
, y
, pixels
[x
]);
6622 #endif /* MAC_TODO */
6624 /* Transform image IMG which is used on frame F with a Laplace
6625 edge-detection algorithm. The result is an image that can be used
6626 to draw disabled buttons, for example. */
6633 #if 0 /* MAC_TODO : Mac version */
6634 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6635 XImage
*ximg
, *oimg
;
6641 int in_y
, out_y
, rc
;
6646 /* Get the X image IMG->pixmap. */
6647 ximg
= XGetImage (NULL
, img
->pixmap
,
6648 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
6650 /* Allocate 3 input rows, and one output row of colors. */
6651 for (i
= 0; i
< 3; ++i
)
6652 in
[i
] = (XColor
*) alloca (img
->width
* sizeof (XColor
));
6653 out
= (long *) alloca (img
->width
* sizeof (long));
6655 /* Create an X image for output. */
6656 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
6659 /* Fill first two rows. */
6660 x_laplace_read_row (f
, cmap
, in
[0], img
->width
, ximg
, 0);
6661 x_laplace_read_row (f
, cmap
, in
[1], img
->width
, ximg
, 1);
6664 /* Write first row, all zeros. */
6665 init_color_table ();
6666 pixel
= lookup_rgb_color (f
, 0, 0, 0);
6667 for (x
= 0; x
< img
->width
; ++x
)
6669 x_laplace_write_row (f
, out
, img
->width
, oimg
, 0);
6672 for (y
= 2; y
< img
->height
; ++y
)
6675 int rowb
= (y
+ 2) % 3;
6677 x_laplace_read_row (f
, cmap
, in
[rowa
], img
->width
, ximg
, in_y
++);
6679 for (x
= 0; x
< img
->width
- 2; ++x
)
6681 int r
= in
[rowa
][x
].red
+ mv2
- in
[rowb
][x
+ 2].red
;
6682 int g
= in
[rowa
][x
].green
+ mv2
- in
[rowb
][x
+ 2].green
;
6683 int b
= in
[rowa
][x
].blue
+ mv2
- in
[rowb
][x
+ 2].blue
;
6685 out
[x
+ 1] = lookup_rgb_color (f
, r
& 0xffff, g
& 0xffff,
6689 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
++);
6692 /* Write last line, all zeros. */
6693 for (x
= 0; x
< img
->width
; ++x
)
6695 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
);
6697 /* Free the input image, and free resources of IMG. */
6698 XDestroyImage (ximg
);
6699 x_clear_image (f
, img
);
6701 /* Put the output image into pixmap, and destroy it. */
6702 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
6703 x_destroy_x_image (oimg
);
6705 /* Remember new pixmap and colors in IMG. */
6706 img
->pixmap
= pixmap
;
6707 img
->colors
= colors_in_color_table (&img
->ncolors
);
6708 free_color_table ();
6711 #endif /* MAC_TODO */
6715 /* Build a mask for image IMG which is used on frame F. FILE is the
6716 name of an image file, for error messages. HOW determines how to
6717 determine the background color of IMG. If it is a list '(R G B)',
6718 with R, G, and B being integers >= 0, take that as the color of the
6719 background. Otherwise, determine the background color of IMG
6720 heuristically. Value is non-zero if successful. */
6723 x_build_heuristic_mask (f
, img
, how
)
6728 #if 0 /* MAC_TODO : Mac version */
6729 Display
*dpy
= FRAME_W32_DISPLAY (f
);
6730 XImage
*ximg
, *mask_img
;
6731 int x
, y
, rc
, look_at_corners_p
;
6736 /* Create an image and pixmap serving as mask. */
6737 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
6738 &mask_img
, &img
->mask
);
6745 /* Get the X image of IMG->pixmap. */
6746 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
6749 /* Determine the background color of ximg. If HOW is `(R G B)'
6750 take that as color. Otherwise, try to determine the color
6752 look_at_corners_p
= 1;
6760 && NATNUMP (XCAR (how
)))
6762 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
6766 if (i
== 3 && NILP (how
))
6768 char color_name
[30];
6769 XColor exact
, color
;
6772 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
6774 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6775 if (XLookupColor (dpy
, cmap
, color_name
, &exact
, &color
))
6778 look_at_corners_p
= 0;
6783 if (look_at_corners_p
)
6785 unsigned long corners
[4];
6788 /* Get the colors at the corners of ximg. */
6789 corners
[0] = XGetPixel (ximg
, 0, 0);
6790 corners
[1] = XGetPixel (ximg
, img
->width
- 1, 0);
6791 corners
[2] = XGetPixel (ximg
, img
->width
- 1, img
->height
- 1);
6792 corners
[3] = XGetPixel (ximg
, 0, img
->height
- 1);
6794 /* Choose the most frequently found color as background. */
6795 for (i
= best_count
= 0; i
< 4; ++i
)
6799 for (j
= n
= 0; j
< 4; ++j
)
6800 if (corners
[i
] == corners
[j
])
6804 bg
= corners
[i
], best_count
= n
;
6808 /* Set all bits in mask_img to 1 whose color in ximg is different
6809 from the background color bg. */
6810 for (y
= 0; y
< img
->height
; ++y
)
6811 for (x
= 0; x
< img
->width
; ++x
)
6812 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
6814 /* Put mask_img into img->mask. */
6815 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
6816 x_destroy_x_image (mask_img
);
6817 XDestroyImage (ximg
);
6820 #endif /* MAC_TODO */
6827 /***********************************************************************
6828 PBM (mono, gray, color)
6829 ***********************************************************************/
6832 static int pbm_image_p
P_ ((Lisp_Object object
));
6833 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
6834 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
6836 /* The symbol `pbm' identifying images of this type. */
6840 /* Indices of image specification fields in gs_format, below. */
6842 enum pbm_keyword_index
6855 /* Vector of image_keyword structures describing the format
6856 of valid user-defined image specifications. */
6858 static struct image_keyword pbm_format
[PBM_LAST
] =
6860 {":type", IMAGE_SYMBOL_VALUE
, 1},
6861 {":file", IMAGE_STRING_VALUE
, 0},
6862 {":data", IMAGE_STRING_VALUE
, 0},
6863 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6864 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6865 {":relief", IMAGE_INTEGER_VALUE
, 0},
6866 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6867 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6870 /* Structure describing the image type `pbm'. */
6872 static struct image_type pbm_type
=
6882 /* Return non-zero if OBJECT is a valid PBM image specification. */
6885 pbm_image_p (object
)
6888 struct image_keyword fmt
[PBM_LAST
];
6890 bcopy (pbm_format
, fmt
, sizeof fmt
);
6892 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
)
6893 || (fmt
[PBM_ASCENT
].count
6894 && XFASTINT (fmt
[PBM_ASCENT
].value
) > 100))
6897 /* Must specify either :data or :file. */
6898 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
6902 /* Scan a decimal number from *S and return it. Advance *S while
6903 reading the number. END is the end of the string. Value is -1 at
6907 pbm_scan_number (s
, end
)
6908 unsigned char **s
, *end
;
6914 /* Skip white-space. */
6915 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
6920 /* Skip comment to end of line. */
6921 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
6924 else if (isdigit (c
))
6926 /* Read decimal number. */
6928 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
6929 val
= 10 * val
+ c
- '0';
6940 /* Read FILE into memory. Value is a pointer to a buffer allocated
6941 with xmalloc holding FILE's contents. Value is null if an error
6942 occurred. *SIZE is set to the size of the file. */
6945 pbm_read_file (file
, size
)
6953 if (stat (SDATA (file
), &st
) == 0
6954 && (fp
= fopen (SDATA (file
), "r")) != NULL
6955 && (buf
= (char *) xmalloc (st
.st_size
),
6956 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
6976 /* Load PBM image IMG for use on frame F. */
6984 int width
, height
, max_color_idx
= 0;
6986 Lisp_Object file
, specified_file
;
6987 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
6988 struct gcpro gcpro1
;
6989 unsigned char *contents
= NULL
;
6990 unsigned char *end
, *p
;
6993 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6997 if (STRINGP (specified_file
))
6999 file
= x_find_image_file (specified_file
);
7000 if (!STRINGP (file
))
7002 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7007 contents
= pbm_read_file (file
, &size
);
7008 if (contents
== NULL
)
7010 image_error ("Error reading `%s'", file
, Qnil
);
7016 end
= contents
+ size
;
7021 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7023 end
= p
+ SBYTES (data
);
7026 /* Check magic number. */
7027 if (end
- p
< 2 || *p
++ != 'P')
7029 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7039 raw_p
= 0, type
= PBM_MONO
;
7043 raw_p
= 0, type
= PBM_GRAY
;
7047 raw_p
= 0, type
= PBM_COLOR
;
7051 raw_p
= 1, type
= PBM_MONO
;
7055 raw_p
= 1, type
= PBM_GRAY
;
7059 raw_p
= 1, type
= PBM_COLOR
;
7063 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7067 /* Read width, height, maximum color-component. Characters
7068 starting with `#' up to the end of a line are ignored. */
7069 width
= pbm_scan_number (&p
, end
);
7070 height
= pbm_scan_number (&p
, end
);
7072 if (type
!= PBM_MONO
)
7074 max_color_idx
= pbm_scan_number (&p
, end
);
7075 if (raw_p
&& max_color_idx
> 255)
7076 max_color_idx
= 255;
7081 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7085 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7086 &ximg
, &img
->pixmap
))
7092 /* Initialize the color hash table. */
7093 init_color_table ();
7095 if (type
== PBM_MONO
)
7099 for (y
= 0; y
< height
; ++y
)
7100 for (x
= 0; x
< width
; ++x
)
7110 g
= pbm_scan_number (&p
, end
);
7112 XPutPixel (ximg
, x
, y
, (g
7113 ? FRAME_FOREGROUND_PIXEL (f
)
7114 : FRAME_BACKGROUND_PIXEL (f
)));
7119 for (y
= 0; y
< height
; ++y
)
7120 for (x
= 0; x
< width
; ++x
)
7124 if (type
== PBM_GRAY
)
7125 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7134 r
= pbm_scan_number (&p
, end
);
7135 g
= pbm_scan_number (&p
, end
);
7136 b
= pbm_scan_number (&p
, end
);
7139 if (r
< 0 || g
< 0 || b
< 0)
7143 XDestroyImage (ximg
);
7145 image_error ("Invalid pixel value in image `%s'",
7150 /* RGB values are now in the range 0..max_color_idx.
7151 Scale this to the range 0..0xffff supported by X. */
7152 r
= (double) r
* 65535 / max_color_idx
;
7153 g
= (double) g
* 65535 / max_color_idx
;
7154 b
= (double) b
* 65535 / max_color_idx
;
7155 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7159 /* Store in IMG->colors the colors allocated for the image, and
7160 free the color table. */
7161 img
->colors
= colors_in_color_table (&img
->ncolors
);
7162 free_color_table ();
7164 /* Put the image into a pixmap. */
7165 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7166 x_destroy_x_image (ximg
);
7170 img
->height
= height
;
7176 #endif /* HAVE_PBM */
7179 /***********************************************************************
7181 ***********************************************************************/
7187 /* Function prototypes. */
7189 static int png_image_p
P_ ((Lisp_Object object
));
7190 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7192 /* The symbol `png' identifying images of this type. */
7196 /* Indices of image specification fields in png_format, below. */
7198 enum png_keyword_index
7211 /* Vector of image_keyword structures describing the format
7212 of valid user-defined image specifications. */
7214 static struct image_keyword png_format
[PNG_LAST
] =
7216 {":type", IMAGE_SYMBOL_VALUE
, 1},
7217 {":data", IMAGE_STRING_VALUE
, 0},
7218 {":file", IMAGE_STRING_VALUE
, 0},
7219 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7220 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7221 {":relief", IMAGE_INTEGER_VALUE
, 0},
7222 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7223 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7226 /* Structure describing the image type `png'. */
7228 static struct image_type png_type
=
7238 /* Return non-zero if OBJECT is a valid PNG image specification. */
7241 png_image_p (object
)
7244 struct image_keyword fmt
[PNG_LAST
];
7245 bcopy (png_format
, fmt
, sizeof fmt
);
7247 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
)
7248 || (fmt
[PNG_ASCENT
].count
7249 && XFASTINT (fmt
[PNG_ASCENT
].value
) > 100))
7252 /* Must specify either the :data or :file keyword. */
7253 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7257 /* Error and warning handlers installed when the PNG library
7261 my_png_error (png_ptr
, msg
)
7262 png_struct
*png_ptr
;
7265 xassert (png_ptr
!= NULL
);
7266 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7267 longjmp (png_ptr
->jmpbuf
, 1);
7272 my_png_warning (png_ptr
, msg
)
7273 png_struct
*png_ptr
;
7276 xassert (png_ptr
!= NULL
);
7277 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7280 /* Memory source for PNG decoding. */
7282 struct png_memory_storage
7284 unsigned char *bytes
; /* The data */
7285 size_t len
; /* How big is it? */
7286 int index
; /* Where are we? */
7290 /* Function set as reader function when reading PNG image from memory.
7291 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7292 bytes from the input to DATA. */
7295 png_read_from_memory (png_ptr
, data
, length
)
7296 png_structp png_ptr
;
7300 struct png_memory_storage
*tbr
7301 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7303 if (length
> tbr
->len
- tbr
->index
)
7304 png_error (png_ptr
, "Read error");
7306 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7307 tbr
->index
= tbr
->index
+ length
;
7310 /* Load PNG image IMG for use on frame F. Value is non-zero if
7318 Lisp_Object file
, specified_file
;
7319 Lisp_Object specified_data
;
7321 XImage
*ximg
, *mask_img
= NULL
;
7322 struct gcpro gcpro1
;
7323 png_struct
*png_ptr
= NULL
;
7324 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7327 png_byte
*pixels
= NULL
;
7328 png_byte
**rows
= NULL
;
7329 png_uint_32 width
, height
;
7330 int bit_depth
, color_type
, interlace_type
;
7332 png_uint_32 row_bytes
;
7335 double screen_gamma
, image_gamma
;
7337 struct png_memory_storage tbr
; /* Data to be read */
7339 /* Find out what file to load. */
7340 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7341 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7345 if (NILP (specified_data
))
7347 file
= x_find_image_file (specified_file
);
7348 if (!STRINGP (file
))
7350 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7355 /* Open the image file. */
7356 fp
= fopen (SDATA (file
), "rb");
7359 image_error ("Cannot open image file `%s'", file
, Qnil
);
7365 /* Check PNG signature. */
7366 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7367 || !png_check_sig (sig
, sizeof sig
))
7369 image_error ("Not a PNG file:` %s'", file
, Qnil
);
7377 /* Read from memory. */
7378 tbr
.bytes
= SDATA (specified_data
);
7379 tbr
.len
= SBYTES (specified_data
);
7382 /* Check PNG signature. */
7383 if (tbr
.len
< sizeof sig
7384 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7386 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7391 /* Need to skip past the signature. */
7392 tbr
.bytes
+= sizeof (sig
);
7395 /* Initialize read and info structs for PNG lib. */
7396 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7397 my_png_error
, my_png_warning
);
7400 if (fp
) fclose (fp
);
7405 info_ptr
= png_create_info_struct (png_ptr
);
7408 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7409 if (fp
) fclose (fp
);
7414 end_info
= png_create_info_struct (png_ptr
);
7417 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7418 if (fp
) fclose (fp
);
7423 /* Set error jump-back. We come back here when the PNG library
7424 detects an error. */
7425 if (setjmp (png_ptr
->jmpbuf
))
7429 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7432 if (fp
) fclose (fp
);
7437 /* Read image info. */
7438 if (!NILP (specified_data
))
7439 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7441 png_init_io (png_ptr
, fp
);
7443 png_set_sig_bytes (png_ptr
, sizeof sig
);
7444 png_read_info (png_ptr
, info_ptr
);
7445 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7446 &interlace_type
, NULL
, NULL
);
7448 /* If image contains simply transparency data, we prefer to
7449 construct a clipping mask. */
7450 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7455 /* This function is easier to write if we only have to handle
7456 one data format: RGB or RGBA with 8 bits per channel. Let's
7457 transform other formats into that format. */
7459 /* Strip more than 8 bits per channel. */
7460 if (bit_depth
== 16)
7461 png_set_strip_16 (png_ptr
);
7463 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7465 png_set_expand (png_ptr
);
7467 /* Convert grayscale images to RGB. */
7468 if (color_type
== PNG_COLOR_TYPE_GRAY
7469 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7470 png_set_gray_to_rgb (png_ptr
);
7472 /* The value 2.2 is a guess for PC monitors from PNG example.c. */
7473 gamma_str
= getenv ("SCREEN_GAMMA");
7474 screen_gamma
= gamma_str
? atof (gamma_str
) : 2.2;
7476 /* Tell the PNG lib to handle gamma correction for us. */
7478 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7479 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7480 /* There is a special chunk in the image specifying the gamma. */
7481 png_set_sRGB (png_ptr
, info_ptr
, intent
);
7484 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7485 /* Image contains gamma information. */
7486 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7488 /* Use a default of 0.5 for the image gamma. */
7489 png_set_gamma (png_ptr
, screen_gamma
, 0.5);
7491 /* Handle alpha channel by combining the image with a background
7492 color. Do this only if a real alpha channel is supplied. For
7493 simple transparency, we prefer a clipping mask. */
7496 png_color_16
*image_background
;
7498 if (png_get_bKGD (png_ptr
, info_ptr
, &image_background
))
7499 /* Image contains a background color with which to
7500 combine the image. */
7501 png_set_background (png_ptr
, image_background
,
7502 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
7505 /* Image does not contain a background color with which
7506 to combine the image data via an alpha channel. Use
7507 the frame's background instead. */
7510 png_color_16 frame_background
;
7513 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
7514 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7515 XQueryColor (FRAME_W32_DISPLAY (f
), cmap
, &color
);
7518 bzero (&frame_background
, sizeof frame_background
);
7519 frame_background
.red
= color
.red
;
7520 frame_background
.green
= color
.green
;
7521 frame_background
.blue
= color
.blue
;
7523 png_set_background (png_ptr
, &frame_background
,
7524 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7528 /* Update info structure. */
7529 png_read_update_info (png_ptr
, info_ptr
);
7531 /* Get number of channels. Valid values are 1 for grayscale images
7532 and images with a palette, 2 for grayscale images with transparency
7533 information (alpha channel), 3 for RGB images, and 4 for RGB
7534 images with alpha channel, i.e. RGBA. If conversions above were
7535 sufficient we should only have 3 or 4 channels here. */
7536 channels
= png_get_channels (png_ptr
, info_ptr
);
7537 xassert (channels
== 3 || channels
== 4);
7539 /* Number of bytes needed for one row of the image. */
7540 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
7542 /* Allocate memory for the image. */
7543 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
7544 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
7545 for (i
= 0; i
< height
; ++i
)
7546 rows
[i
] = pixels
+ i
* row_bytes
;
7548 /* Read the entire image. */
7549 png_read_image (png_ptr
, rows
);
7550 png_read_end (png_ptr
, info_ptr
);
7559 /* Create the X image and pixmap. */
7560 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7567 /* Create an image and pixmap serving as mask if the PNG image
7568 contains an alpha channel. */
7571 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
7572 &mask_img
, &img
->mask
))
7574 x_destroy_x_image (ximg
);
7575 XFreePixmap (FRAME_W32_DISPLAY (f
), img
->pixmap
);
7581 /* Fill the X image and mask from PNG data. */
7582 init_color_table ();
7584 for (y
= 0; y
< height
; ++y
)
7586 png_byte
*p
= rows
[y
];
7588 for (x
= 0; x
< width
; ++x
)
7595 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7597 /* An alpha channel, aka mask channel, associates variable
7598 transparency with an image. Where other image formats
7599 support binary transparency---fully transparent or fully
7600 opaque---PNG allows up to 254 levels of partial transparency.
7601 The PNG library implements partial transparency by combining
7602 the image with a specified background color.
7604 I'm not sure how to handle this here nicely: because the
7605 background on which the image is displayed may change, for
7606 real alpha channel support, it would be necessary to create
7607 a new image for each possible background.
7609 What I'm doing now is that a mask is created if we have
7610 boolean transparency information. Otherwise I'm using
7611 the frame's background color to combine the image with. */
7616 XPutPixel (mask_img
, x
, y
, *p
> 0);
7622 /* Remember colors allocated for this image. */
7623 img
->colors
= colors_in_color_table (&img
->ncolors
);
7624 free_color_table ();
7627 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7632 img
->height
= height
;
7634 /* Put the image into the pixmap, then free the X image and its buffer. */
7635 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7636 x_destroy_x_image (ximg
);
7638 /* Same for the mask. */
7641 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7642 x_destroy_x_image (mask_img
);
7650 #endif /* HAVE_PNG != 0 */
7654 /***********************************************************************
7656 ***********************************************************************/
7660 /* Work around a warning about HAVE_STDLIB_H being redefined in
7662 #ifdef HAVE_STDLIB_H
7663 #define HAVE_STDLIB_H_1
7664 #undef HAVE_STDLIB_H
7665 #endif /* HAVE_STLIB_H */
7667 #include <jpeglib.h>
7671 #ifdef HAVE_STLIB_H_1
7672 #define HAVE_STDLIB_H 1
7675 static int jpeg_image_p
P_ ((Lisp_Object object
));
7676 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
7678 /* The symbol `jpeg' identifying images of this type. */
7682 /* Indices of image specification fields in gs_format, below. */
7684 enum jpeg_keyword_index
7693 JPEG_HEURISTIC_MASK
,
7697 /* Vector of image_keyword structures describing the format
7698 of valid user-defined image specifications. */
7700 static struct image_keyword jpeg_format
[JPEG_LAST
] =
7702 {":type", IMAGE_SYMBOL_VALUE
, 1},
7703 {":data", IMAGE_STRING_VALUE
, 0},
7704 {":file", IMAGE_STRING_VALUE
, 0},
7705 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7706 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7707 {":relief", IMAGE_INTEGER_VALUE
, 0},
7708 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7709 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7712 /* Structure describing the image type `jpeg'. */
7714 static struct image_type jpeg_type
=
7724 /* Return non-zero if OBJECT is a valid JPEG image specification. */
7727 jpeg_image_p (object
)
7730 struct image_keyword fmt
[JPEG_LAST
];
7732 bcopy (jpeg_format
, fmt
, sizeof fmt
);
7734 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
)
7735 || (fmt
[JPEG_ASCENT
].count
7736 && XFASTINT (fmt
[JPEG_ASCENT
].value
) > 100))
7739 /* Must specify either the :data or :file keyword. */
7740 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
7744 struct my_jpeg_error_mgr
7746 struct jpeg_error_mgr pub
;
7747 jmp_buf setjmp_buffer
;
7751 my_error_exit (cinfo
)
7754 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
7755 longjmp (mgr
->setjmp_buffer
, 1);
7758 /* Init source method for JPEG data source manager. Called by
7759 jpeg_read_header() before any data is actually read. See
7760 libjpeg.doc from the JPEG lib distribution. */
7763 our_init_source (cinfo
)
7764 j_decompress_ptr cinfo
;
7769 /* Fill input buffer method for JPEG data source manager. Called
7770 whenever more data is needed. We read the whole image in one step,
7771 so this only adds a fake end of input marker at the end. */
7774 our_fill_input_buffer (cinfo
)
7775 j_decompress_ptr cinfo
;
7777 /* Insert a fake EOI marker. */
7778 struct jpeg_source_mgr
*src
= cinfo
->src
;
7779 static JOCTET buffer
[2];
7781 buffer
[0] = (JOCTET
) 0xFF;
7782 buffer
[1] = (JOCTET
) JPEG_EOI
;
7784 src
->next_input_byte
= buffer
;
7785 src
->bytes_in_buffer
= 2;
7790 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
7791 is the JPEG data source manager. */
7794 our_skip_input_data (cinfo
, num_bytes
)
7795 j_decompress_ptr cinfo
;
7798 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7802 if (num_bytes
> src
->bytes_in_buffer
)
7803 ERREXIT (cinfo
, JERR_INPUT_EOF
);
7805 src
->bytes_in_buffer
-= num_bytes
;
7806 src
->next_input_byte
+= num_bytes
;
7811 /* Method to terminate data source. Called by
7812 jpeg_finish_decompress() after all data has been processed. */
7815 our_term_source (cinfo
)
7816 j_decompress_ptr cinfo
;
7821 /* Set up the JPEG lib for reading an image from DATA which contains
7822 LEN bytes. CINFO is the decompression info structure created for
7823 reading the image. */
7826 jpeg_memory_src (cinfo
, data
, len
)
7827 j_decompress_ptr cinfo
;
7831 struct jpeg_source_mgr
*src
;
7833 if (cinfo
->src
== NULL
)
7835 /* First time for this JPEG object? */
7836 cinfo
->src
= (struct jpeg_source_mgr
*)
7837 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
7838 sizeof (struct jpeg_source_mgr
));
7839 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7840 src
->next_input_byte
= data
;
7843 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7844 src
->init_source
= our_init_source
;
7845 src
->fill_input_buffer
= our_fill_input_buffer
;
7846 src
->skip_input_data
= our_skip_input_data
;
7847 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
7848 src
->term_source
= our_term_source
;
7849 src
->bytes_in_buffer
= len
;
7850 src
->next_input_byte
= data
;
7854 /* Load image IMG for use on frame F. Patterned after example.c
7855 from the JPEG lib. */
7862 struct jpeg_decompress_struct cinfo
;
7863 struct my_jpeg_error_mgr mgr
;
7864 Lisp_Object file
, specified_file
;
7865 Lisp_Object specified_data
;
7868 int row_stride
, x
, y
;
7869 XImage
*ximg
= NULL
;
7871 unsigned long *colors
;
7873 struct gcpro gcpro1
;
7875 /* Open the JPEG file. */
7876 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7877 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7881 if (NILP (specified_data
))
7883 file
= x_find_image_file (specified_file
);
7884 if (!STRINGP (file
))
7886 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7891 fp
= fopen (SDATA (file
), "r");
7894 image_error ("Cannot open `%s'", file
, Qnil
);
7900 /* Customize libjpeg's error handling to call my_error_exit when an
7901 error is detected. This function will perform a longjmp. */
7902 mgr
.pub
.error_exit
= my_error_exit
;
7903 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
7905 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
7909 /* Called from my_error_exit. Display a JPEG error. */
7910 char buffer
[JMSG_LENGTH_MAX
];
7911 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
7912 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
7913 build_string (buffer
));
7916 /* Close the input file and destroy the JPEG object. */
7919 jpeg_destroy_decompress (&cinfo
);
7923 /* If we already have an XImage, free that. */
7924 x_destroy_x_image (ximg
);
7926 /* Free pixmap and colors. */
7927 x_clear_image (f
, img
);
7934 /* Create the JPEG decompression object. Let it read from fp.
7935 Read the JPEG image header. */
7936 jpeg_create_decompress (&cinfo
);
7938 if (NILP (specified_data
))
7939 jpeg_stdio_src (&cinfo
, fp
);
7941 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
7942 SBYTES (specified_data
));
7944 jpeg_read_header (&cinfo
, TRUE
);
7946 /* Customize decompression so that color quantization will be used.
7947 Start decompression. */
7948 cinfo
.quantize_colors
= TRUE
;
7949 jpeg_start_decompress (&cinfo
);
7950 width
= img
->width
= cinfo
.output_width
;
7951 height
= img
->height
= cinfo
.output_height
;
7955 /* Create X image and pixmap. */
7956 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7960 longjmp (mgr
.setjmp_buffer
, 2);
7963 /* Allocate colors. When color quantization is used,
7964 cinfo.actual_number_of_colors has been set with the number of
7965 colors generated, and cinfo.colormap is a two-dimensional array
7966 of color indices in the range 0..cinfo.actual_number_of_colors.
7967 No more than 255 colors will be generated. */
7971 if (cinfo
.out_color_components
> 2)
7972 ir
= 0, ig
= 1, ib
= 2;
7973 else if (cinfo
.out_color_components
> 1)
7974 ir
= 0, ig
= 1, ib
= 0;
7976 ir
= 0, ig
= 0, ib
= 0;
7978 /* Use the color table mechanism because it handles colors that
7979 cannot be allocated nicely. Such colors will be replaced with
7980 a default color, and we don't have to care about which colors
7981 can be freed safely, and which can't. */
7982 init_color_table ();
7983 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
7986 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
7988 /* Multiply RGB values with 255 because X expects RGB values
7989 in the range 0..0xffff. */
7990 int r
= cinfo
.colormap
[ir
][i
] << 8;
7991 int g
= cinfo
.colormap
[ig
][i
] << 8;
7992 int b
= cinfo
.colormap
[ib
][i
] << 8;
7993 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7996 /* Remember those colors actually allocated. */
7997 img
->colors
= colors_in_color_table (&img
->ncolors
);
7998 free_color_table ();
8002 row_stride
= width
* cinfo
.output_components
;
8003 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8005 for (y
= 0; y
< height
; ++y
)
8007 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8008 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8009 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8013 jpeg_finish_decompress (&cinfo
);
8014 jpeg_destroy_decompress (&cinfo
);
8018 /* Put the image into the pixmap. */
8019 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8020 x_destroy_x_image (ximg
);
8026 #endif /* HAVE_JPEG */
8030 /***********************************************************************
8032 ***********************************************************************/
8038 static int tiff_image_p
P_ ((Lisp_Object object
));
8039 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8041 /* The symbol `tiff' identifying images of this type. */
8045 /* Indices of image specification fields in tiff_format, below. */
8047 enum tiff_keyword_index
8056 TIFF_HEURISTIC_MASK
,
8060 /* Vector of image_keyword structures describing the format
8061 of valid user-defined image specifications. */
8063 static struct image_keyword tiff_format
[TIFF_LAST
] =
8065 {":type", IMAGE_SYMBOL_VALUE
, 1},
8066 {":data", IMAGE_STRING_VALUE
, 0},
8067 {":file", IMAGE_STRING_VALUE
, 0},
8068 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8069 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8070 {":relief", IMAGE_INTEGER_VALUE
, 0},
8071 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8072 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
8075 /* Structure describing the image type `tiff'. */
8077 static struct image_type tiff_type
=
8087 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8090 tiff_image_p (object
)
8093 struct image_keyword fmt
[TIFF_LAST
];
8094 bcopy (tiff_format
, fmt
, sizeof fmt
);
8096 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
)
8097 || (fmt
[TIFF_ASCENT
].count
8098 && XFASTINT (fmt
[TIFF_ASCENT
].value
) > 100))
8101 /* Must specify either the :data or :file keyword. */
8102 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8106 /* Reading from a memory buffer for TIFF images Based on the PNG
8107 memory source, but we have to provide a lot of extra functions.
8110 We really only need to implement read and seek, but I am not
8111 convinced that the TIFF library is smart enough not to destroy
8112 itself if we only hand it the function pointers we need to
8117 unsigned char *bytes
;
8124 tiff_read_from_memory (data
, buf
, size
)
8129 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8131 if (size
> src
->len
- src
->index
)
8133 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8139 tiff_write_from_memory (data
, buf
, size
)
8148 tiff_seek_in_memory (data
, off
, whence
)
8153 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8158 case SEEK_SET
: /* Go from beginning of source. */
8162 case SEEK_END
: /* Go from end of source. */
8163 idx
= src
->len
+ off
;
8166 case SEEK_CUR
: /* Go from current position. */
8167 idx
= src
->index
+ off
;
8170 default: /* Invalid `whence'. */
8174 if (idx
> src
->len
|| idx
< 0)
8182 tiff_close_memory (data
)
8190 tiff_mmap_memory (data
, pbase
, psize
)
8195 /* It is already _IN_ memory. */
8200 tiff_unmap_memory (data
, base
, size
)
8205 /* We don't need to do this. */
8209 tiff_size_of_memory (data
)
8212 return ((tiff_memory_source
*) data
)->len
;
8215 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8223 Lisp_Object file
, specified_file
;
8224 Lisp_Object specified_data
;
8226 int width
, height
, x
, y
;
8230 struct gcpro gcpro1
;
8231 tiff_memory_source memsrc
;
8233 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8234 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8238 if (NILP (specified_data
))
8240 /* Read from a file */
8241 file
= x_find_image_file (specified_file
);
8242 if (!STRINGP (file
))
8244 image_error ("Cannot find image file `%s'", file
, Qnil
);
8249 /* Try to open the image file. */
8250 tiff
= TIFFOpen (SDATA (file
), "r");
8253 image_error ("Cannot open `%s'", file
, Qnil
);
8260 /* Memory source! */
8261 memsrc
.bytes
= SDATA (specified_data
);
8262 memsrc
.len
= SBYTES (specified_data
);
8265 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8266 (TIFFReadWriteProc
) tiff_read_from_memory
,
8267 (TIFFReadWriteProc
) tiff_write_from_memory
,
8268 tiff_seek_in_memory
,
8270 tiff_size_of_memory
,
8276 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8282 /* Get width and height of the image, and allocate a raster buffer
8283 of width x height 32-bit values. */
8284 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8285 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8286 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8288 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8292 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8300 /* Create the X image and pixmap. */
8301 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8309 /* Initialize the color table. */
8310 init_color_table ();
8312 /* Process the pixel raster. Origin is in the lower-left corner. */
8313 for (y
= 0; y
< height
; ++y
)
8315 uint32
*row
= buf
+ y
* width
;
8317 for (x
= 0; x
< width
; ++x
)
8319 uint32 abgr
= row
[x
];
8320 int r
= TIFFGetR (abgr
) << 8;
8321 int g
= TIFFGetG (abgr
) << 8;
8322 int b
= TIFFGetB (abgr
) << 8;
8323 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8327 /* Remember the colors allocated for the image. Free the color table. */
8328 img
->colors
= colors_in_color_table (&img
->ncolors
);
8329 free_color_table ();
8331 /* Put the image into the pixmap, then free the X image and its buffer. */
8332 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8333 x_destroy_x_image (ximg
);
8338 img
->height
= height
;
8344 #endif /* HAVE_TIFF != 0 */
8348 /***********************************************************************
8350 ***********************************************************************/
8354 #include <gif_lib.h>
8356 static int gif_image_p
P_ ((Lisp_Object object
));
8357 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8359 /* The symbol `gif' identifying images of this type. */
8363 /* Indices of image specification fields in gif_format, below. */
8365 enum gif_keyword_index
8379 /* Vector of image_keyword structures describing the format
8380 of valid user-defined image specifications. */
8382 static struct image_keyword gif_format
[GIF_LAST
] =
8384 {":type", IMAGE_SYMBOL_VALUE
, 1},
8385 {":data", IMAGE_STRING_VALUE
, 0},
8386 {":file", IMAGE_STRING_VALUE
, 0},
8387 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8388 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8389 {":relief", IMAGE_INTEGER_VALUE
, 0},
8390 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8391 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8392 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
8395 /* Structure describing the image type `gif'. */
8397 static struct image_type gif_type
=
8406 /* Return non-zero if OBJECT is a valid GIF image specification. */
8409 gif_image_p (object
)
8412 struct image_keyword fmt
[GIF_LAST
];
8413 bcopy (gif_format
, fmt
, sizeof fmt
);
8415 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
)
8416 || (fmt
[GIF_ASCENT
].count
8417 && XFASTINT (fmt
[GIF_ASCENT
].value
) > 100))
8420 /* Must specify either the :data or :file keyword. */
8421 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8424 /* Reading a GIF image from memory
8425 Based on the PNG memory stuff to a certain extent. */
8429 unsigned char *bytes
;
8435 /* Make the current memory source available to gif_read_from_memory.
8436 It's done this way because not all versions of libungif support
8437 a UserData field in the GifFileType structure. */
8438 static gif_memory_source
*current_gif_memory_src
;
8441 gif_read_from_memory (file
, buf
, len
)
8446 gif_memory_source
*src
= current_gif_memory_src
;
8448 if (len
> src
->len
- src
->index
)
8451 bcopy (src
->bytes
+ src
->index
, buf
, len
);
8457 /* Load GIF image IMG for use on frame F. Value is non-zero if
8465 Lisp_Object file
, specified_file
;
8466 Lisp_Object specified_data
;
8467 int rc
, width
, height
, x
, y
, i
;
8469 ColorMapObject
*gif_color_map
;
8470 unsigned long pixel_colors
[256];
8472 struct gcpro gcpro1
;
8474 int ino
, image_left
, image_top
, image_width
, image_height
;
8475 gif_memory_source memsrc
;
8476 unsigned char *raster
;
8478 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8479 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8483 if (NILP (specified_data
))
8485 file
= x_find_image_file (specified_file
);
8486 if (!STRINGP (file
))
8488 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8493 /* Open the GIF file. */
8494 gif
= DGifOpenFileName (SDATA (file
));
8497 image_error ("Cannot open `%s'", file
, Qnil
);
8504 /* Read from memory! */
8505 current_gif_memory_src
= &memsrc
;
8506 memsrc
.bytes
= SDATA (specified_data
);
8507 memsrc
.len
= SBYTES (specified_data
);
8510 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
8513 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
8519 /* Read entire contents. */
8520 rc
= DGifSlurp (gif
);
8521 if (rc
== GIF_ERROR
)
8523 image_error ("Error reading `%s'", img
->spec
, Qnil
);
8524 DGifCloseFile (gif
);
8529 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
8530 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
8531 if (ino
>= gif
->ImageCount
)
8533 image_error ("Invalid image number `%s' in image `%s'",
8535 DGifCloseFile (gif
);
8540 width
= img
->width
= gif
->SWidth
;
8541 height
= img
->height
= gif
->SHeight
;
8545 /* Create the X image and pixmap. */
8546 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8549 DGifCloseFile (gif
);
8554 /* Allocate colors. */
8555 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
8557 gif_color_map
= gif
->SColorMap
;
8558 init_color_table ();
8559 bzero (pixel_colors
, sizeof pixel_colors
);
8561 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
8563 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
8564 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
8565 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
8566 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8569 img
->colors
= colors_in_color_table (&img
->ncolors
);
8570 free_color_table ();
8572 /* Clear the part of the screen image that are not covered by
8573 the image from the GIF file. Full animated GIF support
8574 requires more than can be done here (see the gif89 spec,
8575 disposal methods). Let's simply assume that the part
8576 not covered by a sub-image is in the frame's background color. */
8577 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
8578 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
8579 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
8580 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
8582 for (y
= 0; y
< image_top
; ++y
)
8583 for (x
= 0; x
< width
; ++x
)
8584 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8586 for (y
= image_top
+ image_height
; y
< height
; ++y
)
8587 for (x
= 0; x
< width
; ++x
)
8588 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8590 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
8592 for (x
= 0; x
< image_left
; ++x
)
8593 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8594 for (x
= image_left
+ image_width
; x
< width
; ++x
)
8595 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8598 /* Read the GIF image into the X image. We use a local variable
8599 `raster' here because RasterBits below is a char *, and invites
8600 problems with bytes >= 0x80. */
8601 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
8603 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
8605 static int interlace_start
[] = {0, 4, 2, 1};
8606 static int interlace_increment
[] = {8, 8, 4, 2};
8608 int row
= interlace_start
[0];
8612 for (y
= 0; y
< image_height
; y
++)
8614 if (row
>= image_height
)
8616 row
= interlace_start
[++pass
];
8617 while (row
>= image_height
)
8618 row
= interlace_start
[++pass
];
8621 for (x
= 0; x
< image_width
; x
++)
8623 int i
= raster
[(y
* image_width
) + x
];
8624 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
8628 row
+= interlace_increment
[pass
];
8633 for (y
= 0; y
< image_height
; ++y
)
8634 for (x
= 0; x
< image_width
; ++x
)
8636 int i
= raster
[y
* image_width
+ x
];
8637 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
8641 DGifCloseFile (gif
);
8643 /* Put the image into the pixmap, then free the X image and its buffer. */
8644 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8645 x_destroy_x_image (ximg
);
8652 #endif /* HAVE_GIF != 0 */
8656 /***********************************************************************
8658 ***********************************************************************/
8660 #ifdef HAVE_GHOSTSCRIPT
8661 static int gs_image_p
P_ ((Lisp_Object object
));
8662 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
8663 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
8665 /* The symbol `postscript' identifying images of this type. */
8667 Lisp_Object Qpostscript
;
8669 /* Keyword symbols. */
8671 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
8673 /* Indices of image specification fields in gs_format, below. */
8675 enum gs_keyword_index
8691 /* Vector of image_keyword structures describing the format
8692 of valid user-defined image specifications. */
8694 static struct image_keyword gs_format
[GS_LAST
] =
8696 {":type", IMAGE_SYMBOL_VALUE
, 1},
8697 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8698 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8699 {":file", IMAGE_STRING_VALUE
, 1},
8700 {":loader", IMAGE_FUNCTION_VALUE
, 0},
8701 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
8702 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8703 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8704 {":relief", IMAGE_INTEGER_VALUE
, 0},
8705 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8706 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
8709 /* Structure describing the image type `ghostscript'. */
8711 static struct image_type gs_type
=
8721 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8724 gs_clear_image (f
, img
)
8728 /* IMG->data.ptr_val may contain a recorded colormap. */
8729 xfree (img
->data
.ptr_val
);
8730 x_clear_image (f
, img
);
8734 /* Return non-zero if OBJECT is a valid Ghostscript image
8741 struct image_keyword fmt
[GS_LAST
];
8745 bcopy (gs_format
, fmt
, sizeof fmt
);
8747 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
)
8748 || (fmt
[GS_ASCENT
].count
8749 && XFASTINT (fmt
[GS_ASCENT
].value
) > 100))
8752 /* Bounding box must be a list or vector containing 4 integers. */
8753 tem
= fmt
[GS_BOUNDING_BOX
].value
;
8756 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
8757 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
8762 else if (VECTORP (tem
))
8764 if (XVECTOR (tem
)->size
!= 4)
8766 for (i
= 0; i
< 4; ++i
)
8767 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
8777 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
8786 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
8787 struct gcpro gcpro1
, gcpro2
;
8789 double in_width
, in_height
;
8790 Lisp_Object pixel_colors
= Qnil
;
8792 /* Compute pixel size of pixmap needed from the given size in the
8793 image specification. Sizes in the specification are in pt. 1 pt
8794 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8796 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
8797 in_width
= XFASTINT (pt_width
) / 72.0;
8798 img
->width
= in_width
* FRAME_W32_DISPLAY_INFO (f
)->resx
;
8799 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
8800 in_height
= XFASTINT (pt_height
) / 72.0;
8801 img
->height
= in_height
* FRAME_W32_DISPLAY_INFO (f
)->resy
;
8803 /* Create the pixmap. */
8805 xassert (img
->pixmap
== 0);
8806 img
->pixmap
= XCreatePixmap (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
8807 img
->width
, img
->height
,
8808 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
8813 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
8817 /* Call the loader to fill the pixmap. It returns a process object
8818 if successful. We do not record_unwind_protect here because
8819 other places in redisplay like calling window scroll functions
8820 don't either. Let the Lisp loader use `unwind-protect' instead. */
8821 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
8823 sprintf (buffer
, "%lu %lu",
8824 (unsigned long) FRAME_W32_WINDOW (f
),
8825 (unsigned long) img
->pixmap
);
8826 window_and_pixmap_id
= build_string (buffer
);
8828 sprintf (buffer
, "%lu %lu",
8829 FRAME_FOREGROUND_PIXEL (f
),
8830 FRAME_BACKGROUND_PIXEL (f
));
8831 pixel_colors
= build_string (buffer
);
8833 XSETFRAME (frame
, f
);
8834 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
8836 loader
= intern ("gs-load-image");
8838 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
8839 make_number (img
->width
),
8840 make_number (img
->height
),
8841 window_and_pixmap_id
,
8844 return PROCESSP (img
->data
.lisp_val
);
8848 /* Kill the Ghostscript process that was started to fill PIXMAP on
8849 frame F. Called from XTread_socket when receiving an event
8850 telling Emacs that Ghostscript has finished drawing. */
8853 x_kill_gs_process (pixmap
, f
)
8857 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
8861 /* Find the image containing PIXMAP. */
8862 for (i
= 0; i
< c
->used
; ++i
)
8863 if (c
->images
[i
]->pixmap
== pixmap
)
8866 /* Kill the GS process. We should have found PIXMAP in the image
8867 cache and its image should contain a process object. */
8868 xassert (i
< c
->used
);
8870 xassert (PROCESSP (img
->data
.lisp_val
));
8871 Fkill_process (img
->data
.lisp_val
, Qnil
);
8872 img
->data
.lisp_val
= Qnil
;
8874 /* On displays with a mutable colormap, figure out the colors
8875 allocated for the image by looking at the pixels of an XImage for
8877 class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
8878 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
8884 /* Try to get an XImage for img->pixmep. */
8885 ximg
= XGetImage (FRAME_W32_DISPLAY (f
), img
->pixmap
,
8886 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
8891 /* Initialize the color table. */
8892 init_color_table ();
8894 /* For each pixel of the image, look its color up in the
8895 color table. After having done so, the color table will
8896 contain an entry for each color used by the image. */
8897 for (y
= 0; y
< img
->height
; ++y
)
8898 for (x
= 0; x
< img
->width
; ++x
)
8900 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8901 lookup_pixel_color (f
, pixel
);
8904 /* Record colors in the image. Free color table and XImage. */
8905 img
->colors
= colors_in_color_table (&img
->ncolors
);
8906 free_color_table ();
8907 XDestroyImage (ximg
);
8909 #if 0 /* This doesn't seem to be the case. If we free the colors
8910 here, we get a BadAccess later in x_clear_image when
8911 freeing the colors. */
8912 /* We have allocated colors once, but Ghostscript has also
8913 allocated colors on behalf of us. So, to get the
8914 reference counts right, free them once. */
8917 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
8918 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
,
8919 img
->colors
, img
->ncolors
, 0);
8924 image_error ("Cannot get X image of `%s'; colors will not be freed",
8931 #endif /* HAVE_GHOSTSCRIPT */
8934 /***********************************************************************
8936 ***********************************************************************/
8938 DEFUN ("x-change-window-property", Fx_change_window_property
,
8939 Sx_change_window_property
, 2, 3, 0,
8940 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
8941 PROP and VALUE must be strings. FRAME nil or omitted means use the
8942 selected frame. Value is VALUE. */)
8943 (prop
, value
, frame
)
8944 Lisp_Object frame
, prop
, value
;
8946 #if 0 /* MAC_TODO : port window properties to Mac */
8947 struct frame
*f
= check_x_frame (frame
);
8950 CHECK_STRING (prop
);
8951 CHECK_STRING (value
);
8954 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
8955 XChangeProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
8956 prop_atom
, XA_STRING
, 8, PropModeReplace
,
8957 SDATA (value
), SCHARS (value
));
8959 /* Make sure the property is set when we return. */
8960 XFlush (FRAME_W32_DISPLAY (f
));
8963 #endif /* MAC_TODO */
8969 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
8970 Sx_delete_window_property
, 1, 2, 0,
8971 doc
: /* Remove window property PROP from X window of FRAME.
8972 FRAME nil or omitted means use the selected frame. Value is PROP. */)
8974 Lisp_Object prop
, frame
;
8976 #if 0 /* MAC_TODO : port window properties to Mac */
8978 struct frame
*f
= check_x_frame (frame
);
8981 CHECK_STRING (prop
);
8983 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
8984 XDeleteProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), prop_atom
);
8986 /* Make sure the property is removed when we return. */
8987 XFlush (FRAME_W32_DISPLAY (f
));
8989 #endif /* MAC_TODO */
8995 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
8997 doc
: /* Value is the value of window property PROP on FRAME.
8998 If FRAME is nil or omitted, use the selected frame. Value is nil
8999 if FRAME hasn't a property with name PROP or if PROP has no string
9002 Lisp_Object prop
, frame
;
9004 #if 0 /* MAC_TODO : port window properties to Mac */
9006 struct frame
*f
= check_x_frame (frame
);
9009 Lisp_Object prop_value
= Qnil
;
9010 char *tmp_data
= NULL
;
9013 unsigned long actual_size
, bytes_remaining
;
9015 CHECK_STRING (prop
);
9017 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
9018 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9019 prop_atom
, 0, 0, False
, XA_STRING
,
9020 &actual_type
, &actual_format
, &actual_size
,
9021 &bytes_remaining
, (unsigned char **) &tmp_data
);
9024 int size
= bytes_remaining
;
9029 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9030 prop_atom
, 0, bytes_remaining
,
9032 &actual_type
, &actual_format
,
9033 &actual_size
, &bytes_remaining
,
9034 (unsigned char **) &tmp_data
);
9036 prop_value
= make_string (tmp_data
, size
);
9045 #endif /* MAC_TODO */
9051 /***********************************************************************
9053 ***********************************************************************/
9055 /* If non-null, an asynchronous timer that, when it expires, displays
9056 an hourglass cursor on all frames. */
9058 static struct atimer
*hourglass_atimer
;
9060 /* Non-zero means an hourglass cursor is currently shown. */
9062 static int hourglass_shown_p
;
9064 /* Number of seconds to wait before displaying an hourglass cursor. */
9066 static Lisp_Object Vhourglass_delay
;
9068 /* Default number of seconds to wait before displaying an hourglass
9071 #define DEFAULT_HOURGLASS_DELAY 1
9073 /* Function prototypes. */
9075 static void show_hourglass
P_ ((struct atimer
*));
9076 static void hide_hourglass
P_ ((void));
9079 /* Cancel a currently active hourglass timer, and start a new one. */
9084 #if 0 /* MAC_TODO: cursor shape changes. */
9086 int secs
, usecs
= 0;
9088 cancel_hourglass ();
9090 if (INTEGERP (Vhourglass_delay
)
9091 && XINT (Vhourglass_delay
) > 0)
9092 secs
= XFASTINT (Vhourglass_delay
);
9093 else if (FLOATP (Vhourglass_delay
)
9094 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9097 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9098 secs
= XFASTINT (tem
);
9099 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9102 secs
= DEFAULT_HOURGLASS_DELAY
;
9104 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9105 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9106 show_hourglass
, NULL
);
9107 #endif /* MAC_TODO */
9111 /* Cancel the hourglass cursor timer if active, hide an hourglass
9117 if (hourglass_atimer
)
9119 cancel_atimer (hourglass_atimer
);
9120 hourglass_atimer
= NULL
;
9123 if (hourglass_shown_p
)
9128 /* Timer function of hourglass_atimer. TIMER is equal to
9131 Display an hourglass cursor on all frames by mapping the frames'
9132 hourglass_window. Set the hourglass_p flag in the frames'
9133 output_data.x structure to indicate that an hourglass cursor is
9134 shown on the frames. */
9137 show_hourglass (timer
)
9138 struct atimer
*timer
;
9140 #if 0 /* MAC_TODO: cursor shape changes. */
9141 /* The timer implementation will cancel this timer automatically
9142 after this function has run. Set hourglass_atimer to null
9143 so that we know the timer doesn't have to be canceled. */
9144 hourglass_atimer
= NULL
;
9146 if (!hourglass_shown_p
)
9148 Lisp_Object rest
, frame
;
9152 FOR_EACH_FRAME (rest
, frame
)
9153 if (FRAME_W32_P (XFRAME (frame
)))
9155 struct frame
*f
= XFRAME (frame
);
9157 f
->output_data
.w32
->hourglass_p
= 1;
9159 if (!f
->output_data
.w32
->hourglass_window
)
9161 unsigned long mask
= CWCursor
;
9162 XSetWindowAttributes attrs
;
9164 attrs
.cursor
= f
->output_data
.w32
->hourglass_cursor
;
9166 f
->output_data
.w32
->hourglass_window
9167 = XCreateWindow (FRAME_X_DISPLAY (f
),
9168 FRAME_OUTER_WINDOW (f
),
9169 0, 0, 32000, 32000, 0, 0,
9175 XMapRaised (FRAME_X_DISPLAY (f
),
9176 f
->output_data
.w32
->hourglass_window
);
9177 XFlush (FRAME_X_DISPLAY (f
));
9180 hourglass_shown_p
= 1;
9183 #endif /* MAC_TODO */
9187 /* Hide the hourglass cursor on all frames, if it is currently shown. */
9192 #if 0 /* MAC_TODO: cursor shape changes. */
9193 if (hourglass_shown_p
)
9195 Lisp_Object rest
, frame
;
9198 FOR_EACH_FRAME (rest
, frame
)
9200 struct frame
*f
= XFRAME (frame
);
9203 /* Watch out for newly created frames. */
9204 && f
->output_data
.x
->hourglass_window
)
9206 XUnmapWindow (FRAME_X_DISPLAY (f
),
9207 f
->output_data
.x
->hourglass_window
);
9208 /* Sync here because XTread_socket looks at the
9209 hourglass_p flag that is reset to zero below. */
9210 XSync (FRAME_X_DISPLAY (f
), False
);
9211 f
->output_data
.x
->hourglass_p
= 0;
9215 hourglass_shown_p
= 0;
9218 #endif /* MAC_TODO */
9223 /***********************************************************************
9225 ***********************************************************************/
9227 static Lisp_Object x_create_tip_frame
P_ ((struct mac_display_info
*,
9230 /* The frame of a currently visible tooltip, or null. */
9232 Lisp_Object tip_frame
;
9234 /* If non-nil, a timer started that hides the last tooltip when it
9237 Lisp_Object tip_timer
;
9240 /* If non-nil, a vector of 3 elements containing the last args
9241 with which x-show-tip was called. See there. */
9243 Lisp_Object last_show_tip_args
;
9245 /* Create a frame for a tooltip on the display described by DPYINFO.
9246 PARMS is a list of frame parameters. Value is the frame. */
9249 x_create_tip_frame (dpyinfo
, parms
)
9250 struct mac_display_info
*dpyinfo
;
9253 #if 0 /* MAC_TODO : Mac version */
9255 Lisp_Object frame
, tem
;
9257 long window_prompting
= 0;
9259 int count
= SPECPDL_INDEX ();
9260 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9265 /* Use this general default value to start with until we know if
9266 this frame has a specified name. */
9267 Vx_resource_name
= Vinvocation_name
;
9270 kb
= dpyinfo
->kboard
;
9272 kb
= &the_only_kboard
;
9275 /* Get the name of the frame to use for resource lookup. */
9276 name
= w32_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9278 && !EQ (name
, Qunbound
)
9280 error ("Invalid frame name--not a string or nil");
9281 Vx_resource_name
= name
;
9284 GCPRO3 (parms
, name
, frame
);
9285 tip_frame
= f
= make_frame (1);
9286 XSETFRAME (frame
, f
);
9287 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9289 f
->output_method
= output_w32
;
9290 f
->output_data
.w32
=
9291 (struct w32_output
*) xmalloc (sizeof (struct w32_output
));
9292 bzero (f
->output_data
.w32
, sizeof (struct w32_output
));
9294 f
->output_data
.w32
->icon_bitmap
= -1;
9296 f
->output_data
.w32
->fontset
= -1;
9297 f
->icon_name
= Qnil
;
9300 FRAME_KBOARD (f
) = kb
;
9302 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
9303 f
->output_data
.w32
->explicit_parent
= 0;
9305 /* Set the name; the functions to which we pass f expect the name to
9307 if (EQ (name
, Qunbound
) || NILP (name
))
9309 f
->name
= build_string (dpyinfo
->x_id_name
);
9310 f
->explicit_name
= 0;
9315 f
->explicit_name
= 1;
9316 /* use the frame's title when getting resources for this frame. */
9317 specbind (Qx_resource_name
, name
);
9320 /* Extract the window parameters from the supplied values
9321 that are needed to determine window geometry. */
9325 font
= w32_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
9328 /* First, try whatever font the caller has specified. */
9331 tem
= Fquery_fontset (font
, Qnil
);
9333 font
= x_new_fontset (f
, SDATA (tem
));
9335 font
= x_new_font (f
, SDATA (font
));
9338 /* Try out a font which we hope has bold and italic variations. */
9339 if (!STRINGP (font
))
9340 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
9341 if (!STRINGP (font
))
9342 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9343 if (! STRINGP (font
))
9344 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9345 if (! STRINGP (font
))
9346 /* This was formerly the first thing tried, but it finds too many fonts
9347 and takes too long. */
9348 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
9349 /* If those didn't work, look for something which will at least work. */
9350 if (! STRINGP (font
))
9351 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
9353 if (! STRINGP (font
))
9354 font
= build_string ("fixed");
9356 x_default_parameter (f
, parms
, Qfont
, font
,
9357 "font", "Font", RES_TYPE_STRING
);
9360 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
9361 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
9363 /* This defaults to 2 in order to match xterm. We recognize either
9364 internalBorderWidth or internalBorder (which is what xterm calls
9366 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9370 value
= w32_get_arg (parms
, Qinternal_border_width
,
9371 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
9372 if (! EQ (value
, Qunbound
))
9373 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
9377 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
9378 "internalBorderWidth", "internalBorderWidth",
9381 /* Also do the stuff which must be set before the window exists. */
9382 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
9383 "foreground", "Foreground", RES_TYPE_STRING
);
9384 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
9385 "background", "Background", RES_TYPE_STRING
);
9386 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
9387 "pointerColor", "Foreground", RES_TYPE_STRING
);
9388 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
9389 "cursorColor", "Foreground", RES_TYPE_STRING
);
9390 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
9391 "borderColor", "BorderColor", RES_TYPE_STRING
);
9393 /* Init faces before x_default_parameter is called for scroll-bar
9394 parameters because that function calls x_set_scroll_bar_width,
9395 which calls change_frame_size, which calls Fset_window_buffer,
9396 which runs hooks, which call Fvertical_motion. At the end, we
9397 end up in init_iterator with a null face cache, which should not
9399 init_frame_faces (f
);
9401 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
9402 window_prompting
= x_figure_window_size (f
, parms
);
9404 if (window_prompting
& XNegative
)
9406 if (window_prompting
& YNegative
)
9407 f
->output_data
.w32
->win_gravity
= SouthEastGravity
;
9409 f
->output_data
.w32
->win_gravity
= NorthEastGravity
;
9413 if (window_prompting
& YNegative
)
9414 f
->output_data
.w32
->win_gravity
= SouthWestGravity
;
9416 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9419 f
->output_data
.w32
->size_hint_flags
= window_prompting
;
9421 XSetWindowAttributes attrs
;
9425 mask
= CWBackPixel
| CWOverrideRedirect
| CWSaveUnder
| CWEventMask
;
9426 /* Window managers looks at the override-redirect flag to
9427 determine whether or net to give windows a decoration (Xlib
9429 attrs
.override_redirect
= True
;
9430 attrs
.save_under
= True
;
9431 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
9432 /* Arrange for getting MapNotify and UnmapNotify events. */
9433 attrs
.event_mask
= StructureNotifyMask
;
9435 = FRAME_W32_WINDOW (f
)
9436 = XCreateWindow (FRAME_W32_DISPLAY (f
),
9437 FRAME_W32_DISPLAY_INFO (f
)->root_window
,
9438 /* x, y, width, height */
9442 CopyFromParent
, InputOutput
, CopyFromParent
,
9449 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
9450 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9451 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
9452 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9453 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
9454 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
9456 /* Dimensions, especially f->height, must be done via change_frame_size.
9457 Change will not be effected unless different from the current
9462 SET_FRAME_WIDTH (f
, 0);
9463 change_frame_size (f
, height
, width
, 1, 0, 0);
9465 /* Add `tooltip' frame parameter's default value. */
9466 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
9467 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
9474 /* It is now ok to make the frame official even if we get an error
9475 below. And the frame needs to be on Vframe_list or making it
9476 visible won't work. */
9477 Vframe_list
= Fcons (frame
, Vframe_list
);
9479 /* Now that the frame is official, it counts as a reference to
9481 FRAME_W32_DISPLAY_INFO (f
)->reference_count
++;
9483 return unbind_to (count
, frame
);
9484 #endif /* MAC_TODO */
9489 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
9490 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
9491 A tooltip window is a small window displaying a string.
9493 FRAME nil or omitted means use the selected frame.
9495 PARMS is an optional list of frame parameters which can be used to
9496 change the tooltip's appearance.
9498 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
9499 means use the default timeout of 5 seconds.
9501 If the list of frame parameters PARAMS contains a `left' parameters,
9502 the tooltip is displayed at that x-position. Otherwise it is
9503 displayed at the mouse position, with offset DX added (default is 5 if
9504 DX isn't specified). Likewise for the y-position; if a `top' frame
9505 parameter is specified, it determines the y-position of the tooltip
9506 window, otherwise it is displayed at the mouse position, with offset
9507 DY added (default is 10). */)
9508 (string
, frame
, parms
, timeout
, dx
, dy
)
9509 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
9514 Lisp_Object buffer
, top
, left
;
9515 struct buffer
*old_buffer
;
9516 struct text_pos pos
;
9517 int i
, width
, height
;
9518 int root_x
, root_y
, win_x
, win_y
;
9520 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
9521 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
9522 int count
= SPECPDL_INDEX ();
9524 specbind (Qinhibit_redisplay
, Qt
);
9526 GCPRO4 (string
, parms
, frame
, timeout
);
9528 CHECK_STRING (string
);
9529 f
= check_x_frame (frame
);
9531 timeout
= make_number (5);
9533 CHECK_NATNUM (timeout
);
9536 dx
= make_number (5);
9541 dy
= make_number (-10);
9545 if (NILP (last_show_tip_args
))
9546 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
9548 if (!NILP (tip_frame
))
9550 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
9551 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
9552 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
9554 if (EQ (frame
, last_frame
)
9555 && !NILP (Fequal (last_string
, string
))
9556 && !NILP (Fequal (last_parms
, parms
)))
9558 struct frame
*f
= XFRAME (tip_frame
);
9560 /* Only DX and DY have changed. */
9561 if (!NILP (tip_timer
))
9563 Lisp_Object timer
= tip_timer
;
9565 call1 (Qcancel_timer
, timer
);
9568 #if 0 /* MAC_TODO : Mac specifics */
9570 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
9571 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9572 root_x
, root_y
- PIXEL_HEIGHT (f
));
9574 #endif /* MAC_TODO */
9579 /* Hide a previous tip, if any. */
9582 ASET (last_show_tip_args
, 0, string
);
9583 ASET (last_show_tip_args
, 1, frame
);
9584 ASET (last_show_tip_args
, 2, parms
);
9586 /* Add default values to frame parameters. */
9587 if (NILP (Fassq (Qname
, parms
)))
9588 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
9589 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9590 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
9591 if (NILP (Fassq (Qborder_width
, parms
)))
9592 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
9593 if (NILP (Fassq (Qborder_color
, parms
)))
9594 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
9595 if (NILP (Fassq (Qbackground_color
, parms
)))
9596 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
9599 /* Create a frame for the tooltip, and record it in the global
9600 variable tip_frame. */
9601 frame
= x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f
), parms
);
9604 /* Set up the frame's root window. Currently we use a size of 80
9605 columns x 40 lines. If someone wants to show a larger tip, he
9606 will loose. I don't think this is a realistic case. */
9607 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
9608 w
->left
= w
->top
= make_number (0);
9609 w
->width
= make_number (80);
9610 w
->height
= make_number (40);
9612 w
->pseudo_window_p
= 1;
9614 /* Display the tooltip text in a temporary buffer. */
9615 buffer
= Fget_buffer_create (build_string (" *tip*"));
9616 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
);
9617 old_buffer
= current_buffer
;
9618 set_buffer_internal_1 (XBUFFER (buffer
));
9620 Finsert (1, &string
);
9621 clear_glyph_matrix (w
->desired_matrix
);
9622 clear_glyph_matrix (w
->current_matrix
);
9623 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
9624 try_window (FRAME_ROOT_WINDOW (f
), pos
);
9626 /* Compute width and height of the tooltip. */
9628 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
9630 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
9634 /* Stop at the first empty row at the end. */
9635 if (!row
->enabled_p
|| !row
->displays_text_p
)
9638 /* Let the row go over the full width of the frame. */
9639 row
->full_width_p
= 1;
9641 /* There's a glyph at the end of rows that is use to place
9642 the cursor there. Don't include the width of this glyph. */
9643 if (row
->used
[TEXT_AREA
])
9645 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
9646 row_width
= row
->pixel_width
- last
->pixel_width
;
9649 row_width
= row
->pixel_width
;
9651 height
+= row
->height
;
9652 width
= max (width
, row_width
);
9655 /* Add the frame's internal border to the width and height the X
9656 window should have. */
9657 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
9658 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
9660 /* Move the tooltip window where the mouse pointer is. Resize and
9662 #if 0 /* TODO : Mac specifics */
9663 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
9666 XQueryPointer (FRAME_W32_DISPLAY (f
), FRAME_W32_DISPLAY_INFO (f
)->root_window
,
9667 &root
, &child
, &root_x
, &root_y
, &win_x
, &win_y
, &pmask
);
9668 XMoveResizeWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9669 root_x
+ 5, root_y
- height
- 5, width
, height
);
9670 XMapRaised (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
9672 #endif /* MAC_TODO */
9674 /* Draw into the window. */
9675 w
->must_be_updated_p
= 1;
9676 update_single_window (w
, 1);
9678 /* Restore original current buffer. */
9679 set_buffer_internal_1 (old_buffer
);
9680 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
9683 /* Let the tip disappear after timeout seconds. */
9684 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
9685 intern ("x-hide-tip"));
9688 return unbind_to (count
, Qnil
);
9692 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
9693 doc
: /* Hide the current tooltip window, if there is any.
9694 Value is t is tooltip was open, nil otherwise. */)
9698 Lisp_Object deleted
, frame
, timer
;
9699 struct gcpro gcpro1
, gcpro2
;
9701 /* Return quickly if nothing to do. */
9702 if (NILP (tip_timer
) && NILP (tip_frame
))
9707 GCPRO2 (frame
, timer
);
9708 tip_frame
= tip_timer
= deleted
= Qnil
;
9710 count
= SPECPDL_INDEX ();
9711 specbind (Qinhibit_redisplay
, Qt
);
9712 specbind (Qinhibit_quit
, Qt
);
9715 call1 (Qcancel_timer
, timer
);
9719 Fdelete_frame (frame
, Qnil
);
9724 return unbind_to (count
, deleted
);
9729 /***********************************************************************
9730 File selection dialog
9731 ***********************************************************************/
9733 #if 0 /* MAC_TODO: can standard file dialog */
9734 extern Lisp_Object Qfile_name_history
;
9736 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
9737 doc
: /* Read file name, prompting with PROMPT in directory DIR.
9738 Use a file selection dialog.
9739 Select DEFAULT-FILENAME in the dialog's file selection box, if
9740 specified. Don't let the user enter a file name in the file
9741 selection dialog's entry field, if MUSTMATCH is non-nil. */)
9742 (prompt
, dir
, default_filename
, mustmatch
)
9743 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
9745 struct frame
*f
= SELECTED_FRAME ();
9746 Lisp_Object file
= Qnil
;
9747 int count
= SPECPDL_INDEX ();
9748 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
9749 char filename
[MAX_PATH
+ 1];
9750 char init_dir
[MAX_PATH
+ 1];
9751 int use_dialog_p
= 1;
9753 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
9754 CHECK_STRING (prompt
);
9757 /* Create the dialog with PROMPT as title, using DIR as initial
9758 directory and using "*" as pattern. */
9759 dir
= Fexpand_file_name (dir
, Qnil
);
9760 strncpy (init_dir
, SDATA (dir
), MAX_PATH
);
9761 init_dir
[MAX_PATH
] = '\0';
9762 unixtodos_filename (init_dir
);
9764 if (STRINGP (default_filename
))
9766 char *file_name_only
;
9767 char *full_path_name
= SDATA (default_filename
);
9769 unixtodos_filename (full_path_name
);
9771 file_name_only
= strrchr (full_path_name
, '\\');
9772 if (!file_name_only
)
9773 file_name_only
= full_path_name
;
9778 /* If default_file_name is a directory, don't use the open
9779 file dialog, as it does not support selecting
9781 if (!(*file_name_only
))
9785 strncpy (filename
, file_name_only
, MAX_PATH
);
9786 filename
[MAX_PATH
] = '\0';
9793 OPENFILENAME file_details
;
9794 char *filename_file
;
9796 /* Prevent redisplay. */
9797 specbind (Qinhibit_redisplay
, Qt
);
9800 bzero (&file_details
, sizeof (file_details
));
9801 file_details
.lStructSize
= sizeof (file_details
);
9802 file_details
.hwndOwner
= FRAME_W32_WINDOW (f
);
9803 file_details
.lpstrFile
= filename
;
9804 file_details
.nMaxFile
= sizeof (filename
);
9805 file_details
.lpstrInitialDir
= init_dir
;
9806 file_details
.lpstrTitle
= SDATA (prompt
);
9807 file_details
.Flags
= OFN_HIDEREADONLY
| OFN_NOCHANGEDIR
;
9809 if (!NILP (mustmatch
))
9810 file_details
.Flags
|= OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
;
9812 if (GetOpenFileName (&file_details
))
9814 dostounix_filename (filename
);
9815 file
= build_string (filename
);
9821 file
= unbind_to (count
, file
);
9823 /* Open File dialog will not allow folders to be selected, so resort
9824 to minibuffer completing reads for directories. */
9826 file
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
9827 dir
, mustmatch
, dir
, Qfile_name_history
,
9828 default_filename
, Qnil
);
9832 /* Make "Cancel" equivalent to C-g. */
9834 Fsignal (Qquit
, Qnil
);
9836 return unbind_to (count
, file
);
9838 #endif /* MAC_TODO */
9842 /***********************************************************************
9844 ***********************************************************************/
9848 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
9849 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
9853 return valid_image_p (spec
) ? Qt
: Qnil
;
9857 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
9863 if (valid_image_p (spec
))
9864 id
= lookup_image (SELECTED_FRAME (), spec
);
9867 return make_number (id
);
9870 #endif /* GLYPH_DEBUG != 0 */
9877 /* Certainly running on Mac. */
9880 /* The section below is built by the lisp expression at the top of the file,
9881 just above where these variables are declared. */
9882 /*&&& init symbols here &&&*/
9883 Qauto_raise
= intern ("auto-raise");
9884 staticpro (&Qauto_raise
);
9885 Qauto_lower
= intern ("auto-lower");
9886 staticpro (&Qauto_lower
);
9887 Qborder_color
= intern ("border-color");
9888 staticpro (&Qborder_color
);
9889 Qborder_width
= intern ("border-width");
9890 staticpro (&Qborder_width
);
9891 Qcursor_color
= intern ("cursor-color");
9892 staticpro (&Qcursor_color
);
9893 Qcursor_type
= intern ("cursor-type");
9894 staticpro (&Qcursor_type
);
9895 Qgeometry
= intern ("geometry");
9896 staticpro (&Qgeometry
);
9897 Qicon_left
= intern ("icon-left");
9898 staticpro (&Qicon_left
);
9899 Qicon_top
= intern ("icon-top");
9900 staticpro (&Qicon_top
);
9901 Qicon_type
= intern ("icon-type");
9902 staticpro (&Qicon_type
);
9903 Qicon_name
= intern ("icon-name");
9904 staticpro (&Qicon_name
);
9905 Qinternal_border_width
= intern ("internal-border-width");
9906 staticpro (&Qinternal_border_width
);
9907 Qleft
= intern ("left");
9909 Qright
= intern ("right");
9910 staticpro (&Qright
);
9911 Qmouse_color
= intern ("mouse-color");
9912 staticpro (&Qmouse_color
);
9913 Qnone
= intern ("none");
9915 Qparent_id
= intern ("parent-id");
9916 staticpro (&Qparent_id
);
9917 Qscroll_bar_width
= intern ("scroll-bar-width");
9918 staticpro (&Qscroll_bar_width
);
9919 Qsuppress_icon
= intern ("suppress-icon");
9920 staticpro (&Qsuppress_icon
);
9921 Qundefined_color
= intern ("undefined-color");
9922 staticpro (&Qundefined_color
);
9923 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
9924 staticpro (&Qvertical_scroll_bars
);
9925 Qvisibility
= intern ("visibility");
9926 staticpro (&Qvisibility
);
9927 Qwindow_id
= intern ("window-id");
9928 staticpro (&Qwindow_id
);
9929 Qx_frame_parameter
= intern ("x-frame-parameter");
9930 staticpro (&Qx_frame_parameter
);
9931 Qx_resource_name
= intern ("x-resource-name");
9932 staticpro (&Qx_resource_name
);
9933 Quser_position
= intern ("user-position");
9934 staticpro (&Quser_position
);
9935 Quser_size
= intern ("user-size");
9936 staticpro (&Quser_size
);
9937 Qscreen_gamma
= intern ("screen-gamma");
9938 staticpro (&Qscreen_gamma
);
9939 Qline_spacing
= intern ("line-spacing");
9940 staticpro (&Qline_spacing
);
9941 Qcenter
= intern ("center");
9942 staticpro (&Qcenter
);
9943 /* This is the end of symbol initialization. */
9945 Qhyper
= intern ("hyper");
9946 staticpro (&Qhyper
);
9947 Qsuper
= intern ("super");
9948 staticpro (&Qsuper
);
9949 Qmeta
= intern ("meta");
9951 Qalt
= intern ("alt");
9953 Qctrl
= intern ("ctrl");
9955 Qcontrol
= intern ("control");
9956 staticpro (&Qcontrol
);
9957 Qshift
= intern ("shift");
9958 staticpro (&Qshift
);
9960 /* Text property `display' should be nonsticky by default. */
9961 Vtext_property_default_nonsticky
9962 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
9965 Qlaplace
= intern ("laplace");
9966 staticpro (&Qlaplace
);
9968 Qface_set_after_frame_default
= intern ("face-set-after-frame-default");
9969 staticpro (&Qface_set_after_frame_default
);
9971 Fput (Qundefined_color
, Qerror_conditions
,
9972 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
9973 Fput (Qundefined_color
, Qerror_message
,
9974 build_string ("Undefined color"));
9976 init_x_parm_symbols ();
9978 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
9979 doc
: /* List of directories to search for window system bitmap files. */);
9980 Vx_bitmap_file_path
= decode_env_path ((char *) 0, "PATH");
9982 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
9983 doc
: /* The shape of the pointer when over text.
9984 Changing the value does not affect existing frames
9985 unless you set the mouse color. */);
9986 Vx_pointer_shape
= Qnil
;
9988 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
9989 doc
: /* The name Emacs uses to look up resources; for internal use only.
9990 `x-get-resource' uses this as the first component of the instance name
9991 when requesting resource values.
9992 Emacs initially sets `x-resource-name' to the name under which Emacs
9993 was invoked, or to the value specified with the `-name' or `-rn'
9994 switches, if present. */);
9995 Vx_resource_name
= Qnil
;
9997 Vx_nontext_pointer_shape
= Qnil
;
9999 Vx_mode_pointer_shape
= Qnil
;
10001 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10002 doc
: /* The shape of the pointer when Emacs is hourglass.
10003 This variable takes effect when you create a new frame
10004 or when you set the mouse color. */);
10005 Vx_hourglass_pointer_shape
= Qnil
;
10007 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10008 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10009 display_hourglass_p
= 1;
10011 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10012 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10013 Value must be an integer or float. */);
10014 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10016 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10017 &Vx_sensitive_text_pointer_shape
,
10018 doc
: /* The shape of the pointer when over mouse-sensitive text.
10019 This variable takes effect when you create a new frame
10020 or when you set the mouse color. */);
10021 Vx_sensitive_text_pointer_shape
= Qnil
;
10023 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
10024 doc
: /* A string indicating the foreground color of the cursor box. */);
10025 Vx_cursor_fore_pixel
= Qnil
;
10027 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
10028 doc
: /* Non-nil if no window manager is in use.
10029 Emacs doesn't try to figure this out; this is always nil
10030 unless you set it to something else. */);
10031 /* We don't have any way to find this out, so set it to nil
10032 and maybe the user would like to set it to t. */
10033 Vx_no_window_manager
= Qnil
;
10035 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10036 &Vx_pixel_size_width_font_regexp
,
10037 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10039 Since Emacs gets width of a font matching with this regexp from
10040 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10041 such a font. This is especially effective for such large fonts as
10042 Chinese, Japanese, and Korean. */);
10043 Vx_pixel_size_width_font_regexp
= Qnil
;
10045 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
10046 doc
: /* Time after which cached images are removed from the cache.
10047 When an image has not been displayed this many seconds, remove it
10048 from the image cache. Value must be an integer or nil with nil
10049 meaning don't clear the cache. */);
10050 Vimage_cache_eviction_delay
= make_number (30 * 60);
10052 #if 0 /* MAC_TODO: implement get X resource */
10053 defsubr (&Sx_get_resource
);
10055 defsubr (&Sx_change_window_property
);
10056 defsubr (&Sx_delete_window_property
);
10057 defsubr (&Sx_window_property
);
10058 defsubr (&Sxw_display_color_p
);
10059 defsubr (&Sx_display_grayscale_p
);
10060 defsubr (&Sxw_color_defined_p
);
10061 defsubr (&Sxw_color_values
);
10062 defsubr (&Sx_server_max_request_size
);
10063 defsubr (&Sx_server_vendor
);
10064 defsubr (&Sx_server_version
);
10065 defsubr (&Sx_display_pixel_width
);
10066 defsubr (&Sx_display_pixel_height
);
10067 defsubr (&Sx_display_mm_width
);
10068 defsubr (&Sx_display_mm_height
);
10069 defsubr (&Sx_display_screens
);
10070 defsubr (&Sx_display_planes
);
10071 defsubr (&Sx_display_color_cells
);
10072 defsubr (&Sx_display_visual_class
);
10073 defsubr (&Sx_display_backing_store
);
10074 defsubr (&Sx_display_save_under
);
10075 #if 0 /* MAC_TODO: implement XParseGeometry */
10076 defsubr (&Sx_parse_geometry
);
10078 defsubr (&Sx_create_frame
);
10079 #if 0 /* MAC_TODO: implement network support */
10080 defsubr (&Sx_open_connection
);
10081 defsubr (&Sx_close_connection
);
10083 defsubr (&Sx_display_list
);
10084 defsubr (&Sx_synchronize
);
10086 /* Setting callback functions for fontset handler. */
10087 get_font_info_func
= x_get_font_info
;
10089 #if 0 /* This function pointer doesn't seem to be used anywhere.
10090 And the pointer assigned has the wrong type, anyway. */
10091 list_fonts_func
= x_list_fonts
;
10094 load_font_func
= x_load_font
;
10095 find_ccl_program_func
= x_find_ccl_program
;
10096 query_font_func
= x_query_font
;
10098 set_frame_fontset_func
= x_set_font
;
10099 check_window_system_func
= check_mac
;
10101 #if 0 /* MAC_TODO: Image support for Mac Images. */
10102 Qxbm
= intern ("xbm");
10104 QCtype
= intern (":type");
10105 staticpro (&QCtype
);
10106 QCconversion
= intern (":conversion");
10107 staticpro (&QCconversion
);
10108 QCheuristic_mask
= intern (":heuristic-mask");
10109 staticpro (&QCheuristic_mask
);
10110 QCcolor_symbols
= intern (":color-symbols");
10111 staticpro (&QCcolor_symbols
);
10112 QCascent
= intern (":ascent");
10113 staticpro (&QCascent
);
10114 QCmargin
= intern (":margin");
10115 staticpro (&QCmargin
);
10116 QCrelief
= intern (":relief");
10117 staticpro (&QCrelief
);
10118 Qpostscript
= intern ("postscript");
10119 staticpro (&Qpostscript
);
10120 QCloader
= intern (":loader");
10121 staticpro (&QCloader
);
10122 QCbounding_box
= intern (":bounding-box");
10123 staticpro (&QCbounding_box
);
10124 QCpt_width
= intern (":pt-width");
10125 staticpro (&QCpt_width
);
10126 QCpt_height
= intern (":pt-height");
10127 staticpro (&QCpt_height
);
10128 QCindex
= intern (":index");
10129 staticpro (&QCindex
);
10130 Qpbm
= intern ("pbm");
10134 Qxpm
= intern ("xpm");
10139 Qjpeg
= intern ("jpeg");
10140 staticpro (&Qjpeg
);
10144 Qtiff
= intern ("tiff");
10145 staticpro (&Qtiff
);
10149 Qgif
= intern ("gif");
10154 Qpng
= intern ("png");
10158 defsubr (&Sclear_image_cache
);
10161 defsubr (&Simagep
);
10162 defsubr (&Slookup_image
);
10164 #endif /* MAC_TODO */
10166 hourglass_atimer
= NULL
;
10167 hourglass_shown_p
= 0;
10169 defsubr (&Sx_show_tip
);
10170 defsubr (&Sx_hide_tip
);
10171 staticpro (&tip_timer
);
10174 #if 0 /* MAC_TODO */
10175 defsubr (&Sx_file_dialog
);
10183 image_types
= NULL
;
10184 Vimage_types
= Qnil
;
10186 define_image_type (&xbm_type
);
10187 #if 0 /* NTEMACS_TODO : Image support for W32 */
10188 define_image_type (&gs_type
);
10189 define_image_type (&pbm_type
);
10192 define_image_type (&xpm_type
);
10196 define_image_type (&jpeg_type
);
10200 define_image_type (&tiff_type
);
10204 define_image_type (&gif_type
);
10208 define_image_type (&png_type
);
10210 #endif /* NTEMACS_TODO */