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. */
75 #include <Carbon/Carbon.h>
77 #define Z (current_buffer->text->z)
79 #define free unexec_free
81 #define malloc unexec_malloc
83 #define realloc unexec_realloc
85 #define min(a, b) ((a) < (b) ? (a) : (b))
87 #define max(a, b) ((a) > (b) ? (a) : (b))
88 #else /* not MAC_OSX */
91 #include <TextUtils.h>
92 #endif /* not MAC_OSX */
94 /*extern void free_frame_menubar ();
95 extern double atof ();
96 extern int w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state);
97 extern int quit_char;*/
99 /* A definition of XColor for non-X frames. */
100 #ifndef HAVE_X_WINDOWS
103 unsigned short red
, green
, blue
;
109 extern char *lispy_function_keys
[];
111 /* The gray bitmap `bitmaps/gray'. This is done because macterm.c uses
112 it, and including `bitmaps/gray' more than once is a problem when
113 config.h defines `static' as an empty replacement string. */
115 int gray_bitmap_width
= gray_width
;
116 int gray_bitmap_height
= gray_height
;
117 unsigned char *gray_bitmap_bits
= gray_bits
;
119 /* The name we're using in resource queries. */
121 Lisp_Object Vx_resource_name
;
123 /* Non-zero means we're allowed to display an hourglass cursor. */
125 int display_hourglass_p
;
127 /* The background and shape of the mouse pointer, and shape when not
128 over text or in the modeline. */
130 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
131 Lisp_Object Vx_hourglass_pointer_shape
;
133 /* The shape when over mouse-sensitive text. */
135 Lisp_Object Vx_sensitive_text_pointer_shape
;
137 /* If non-nil, the pointer shape to indicate that windows can be
138 dragged horizontally. */
140 Lisp_Object Vx_window_horizontal_drag_shape
;
142 /* Color of chars displayed in cursor box. */
144 Lisp_Object Vx_cursor_fore_pixel
;
146 /* Nonzero if using Windows. */
148 static int mac_in_use
;
150 /* Non nil if no window manager is in use. */
152 Lisp_Object Vx_no_window_manager
;
154 /* Search path for bitmap files. */
156 Lisp_Object Vx_bitmap_file_path
;
158 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
160 Lisp_Object Vx_pixel_size_width_font_regexp
;
162 /* Evaluate this expression to rebuild the section of syms_of_macfns
163 that initializes and staticpros the symbols declared below. Note
164 that Emacs 18 has a bug that keeps C-x C-e from being able to
165 evaluate this expression.
168 ;; Accumulate a list of the symbols we want to initialize from the
169 ;; declarations at the top of the file.
170 (goto-char (point-min))
171 (search-forward "/\*&&& symbols declared here &&&*\/\n")
173 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
175 (cons (buffer-substring (match-beginning 1) (match-end 1))
178 (setq symbol-list (nreverse symbol-list))
179 ;; Delete the section of syms_of_... where we initialize the symbols.
180 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
181 (let ((start (point)))
182 (while (looking-at "^ Q")
184 (kill-region start (point)))
185 ;; Write a new symbol initialization section.
187 (insert (format " %s = intern (\"" (car symbol-list)))
188 (let ((start (point)))
189 (insert (substring (car symbol-list) 1))
190 (subst-char-in-region start (point) ?_ ?-))
191 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
192 (setq symbol-list (cdr symbol-list)))))
196 /*&&& symbols declared here &&&*/
197 Lisp_Object Qauto_raise
;
198 Lisp_Object Qauto_lower
;
200 Lisp_Object Qborder_color
;
201 Lisp_Object Qborder_width
;
203 Lisp_Object Qcursor_color
;
204 Lisp_Object Qcursor_type
;
205 Lisp_Object Qgeometry
;
206 Lisp_Object Qicon_left
;
207 Lisp_Object Qicon_top
;
208 Lisp_Object Qicon_type
;
209 Lisp_Object Qicon_name
;
210 Lisp_Object Qinternal_border_width
;
213 Lisp_Object Qmouse_color
;
215 Lisp_Object Qparent_id
;
216 Lisp_Object Qscroll_bar_width
;
217 Lisp_Object Qsuppress_icon
;
218 Lisp_Object Qundefined_color
;
219 Lisp_Object Qvertical_scroll_bars
;
220 Lisp_Object Qvisibility
;
221 Lisp_Object Qwindow_id
;
222 Lisp_Object Qx_frame_parameter
;
223 Lisp_Object Qx_resource_name
;
224 Lisp_Object Quser_position
;
225 Lisp_Object Quser_size
;
226 Lisp_Object Qscreen_gamma
;
227 Lisp_Object Qline_spacing
;
229 Lisp_Object Qcancel_timer
;
235 Lisp_Object Qcontrol
;
238 extern Lisp_Object Qtop
;
239 extern Lisp_Object Qdisplay
;
240 Lisp_Object Qscroll_bar_foreground
, Qscroll_bar_background
;
241 extern Lisp_Object Qtool_bar_lines
;
243 /* These are defined in frame.c. */
244 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
245 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
, Qbuffer_predicate
, Qtitle
;
246 extern Lisp_Object Qtool_bar_lines
;
248 extern Lisp_Object Vwindow_system_version
;
250 Lisp_Object Qface_set_after_frame_default
;
252 extern int mac_initialized
;
254 /* Functions in macterm.c. */
255 extern void x_set_offset (struct frame
*, int, int, int);
256 extern void x_wm_set_icon_position (struct frame
*, int, int);
257 extern void x_display_cursor (struct window
*, int, int, int, int, int);
258 extern void x_set_window_size (struct frame
*, int, int, int);
259 extern void x_make_frame_visible (struct frame
*);
260 extern struct mac_display_info
*mac_term_init (Lisp_Object
, char *, char *);
261 extern struct font_info
*x_get_font_info (FRAME_PTR
, int);
262 extern struct font_info
*x_load_font (struct frame
*, char *, int);
263 extern void x_find_ccl_program (struct font_info
*);
264 extern struct font_info
*x_query_font (struct frame
*, char *);
265 extern void mac_initialize ();
267 /* compare two strings ignoring case */
270 stricmp (const char *s
, const char *t
)
272 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
275 return tolower (*s
) - tolower (*t
);
278 /* compare two strings up to n characters, ignoring case */
281 strnicmp (const char *s
, const char *t
, unsigned int n
)
283 for ( ; n
-- > 0 && tolower (*s
) == tolower (*t
); s
++, t
++)
286 return n
== 0 ? 0 : tolower (*s
) - tolower (*t
);
290 /* Error if we are not running on Mac OS. */
296 error ("Mac OS not in use or not initialized");
299 /* Nonzero if we can use mouse menus.
300 You should not call this unless HAVE_MENUS is defined. */
308 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
309 and checking validity for Mac. */
312 check_x_frame (frame
)
318 frame
= selected_frame
;
319 CHECK_LIVE_FRAME (frame
);
321 if (! FRAME_MAC_P (f
))
322 error ("non-mac frame used");
326 /* Let the user specify an display with a frame.
327 nil stands for the selected frame--or, if that is not a mac frame,
328 the first display on the list. */
330 static struct mac_display_info
*
331 check_x_display_info (frame
)
334 if (!mac_initialized
)
342 struct frame
*sf
= XFRAME (selected_frame
);
344 if (FRAME_MAC_P (sf
) && FRAME_LIVE_P (sf
))
345 return FRAME_MAC_DISPLAY_INFO (sf
);
347 return &one_mac_display_info
;
349 else if (STRINGP (frame
))
350 return x_display_info_for_name (frame
);
355 CHECK_LIVE_FRAME (frame
);
357 if (! FRAME_MAC_P (f
))
358 error ("non-mac frame used");
359 return FRAME_MAC_DISPLAY_INFO (f
);
363 /* Return the Emacs frame-object corresponding to an mac window.
364 It could be the frame's main window or an icon window. */
366 /* This function can be called during GC, so use GC_xxx type test macros. */
369 x_window_to_frame (dpyinfo
, wdesc
)
370 struct mac_display_info
*dpyinfo
;
373 Lisp_Object tail
, frame
;
376 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
379 if (!GC_FRAMEP (frame
))
382 if (!FRAME_W32_P (f
) || FRAME_MAC_DISPLAY_INFO (f
) != dpyinfo
)
384 /*if (f->output_data.w32->hourglass_window == wdesc)
387 /* MAC_TODO: Check tooltips when supported. */
388 if (FRAME_MAC_WINDOW (f
) == wdesc
)
396 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
397 id, which is just an int that this section returns. Bitmaps are
398 reference counted so they can be shared among frames.
400 Bitmap indices are guaranteed to be > 0, so a negative number can
401 be used to indicate no bitmap.
403 If you use x_create_bitmap_from_data, then you must keep track of
404 the bitmaps yourself. That is, creating a bitmap from the same
405 data more than once will not be caught. */
408 /* Functions to access the contents of a bitmap, given an id. */
411 x_bitmap_height (f
, id
)
415 return FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
419 x_bitmap_width (f
, id
)
423 return FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
426 #if 0 /* MAC_TODO : not used anywhere (?) */
428 x_bitmap_pixmap (f
, id
)
432 return (int) FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
436 /* Allocate a new bitmap record. Returns index of new record. */
439 x_allocate_bitmap_record (f
)
442 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
445 if (dpyinfo
->bitmaps
== NULL
)
447 dpyinfo
->bitmaps_size
= 10;
448 dpyinfo
->bitmaps
= (struct mac_bitmap_record
*)
449 xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct mac_bitmap_record
));
450 dpyinfo
->bitmaps_last
= 1;
454 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
455 return ++dpyinfo
->bitmaps_last
;
457 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
458 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
461 dpyinfo
->bitmaps_size
*= 2;
462 dpyinfo
->bitmaps
= (struct mac_bitmap_record
*)
463 xrealloc (dpyinfo
->bitmaps
,
464 dpyinfo
->bitmaps_size
* sizeof (struct mac_bitmap_record
));
465 return ++dpyinfo
->bitmaps_last
;
468 /* Add one reference to the reference count of the bitmap with id
472 x_reference_bitmap (f
, id
)
476 ++FRAME_MAC_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
479 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at
483 x_create_bitmap_from_data (f
, bits
, width
, height
)
486 unsigned int width
, height
;
488 struct x_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
491 /* MAC_TODO: for now fail if width is not mod 16 (toolbox requires it) */
493 id
= x_allocate_bitmap_record (f
);
498 dpyinfo
->bitmaps
[id
- 1].bitmap_data
= (char *) xmalloc (height
* width
);
499 if (! dpyinfo
->bitmaps
[id
- 1].bitmap_data
)
502 bcopy (bits
, dpyinfo
->bitmaps
[id
- 1].bitmap_data
, height
* width
);
504 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
505 dpyinfo
->bitmaps
[id
- 1].height
= height
;
506 dpyinfo
->bitmaps
[id
- 1].width
= width
;
511 /* Create bitmap from file FILE for frame F. */
514 x_create_bitmap_from_file (f
, file
)
519 #if 0 /* MAC_TODO : bitmap support */
520 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
521 unsigned int width
, height
;
523 int xhot
, yhot
, result
, id
;
529 /* Look for an existing bitmap with the same name. */
530 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
532 if (dpyinfo
->bitmaps
[id
].refcount
533 && dpyinfo
->bitmaps
[id
].file
534 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
536 ++dpyinfo
->bitmaps
[id
].refcount
;
541 /* Search bitmap-file-path for the file, if appropriate. */
542 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, Qnil
);
545 /* LoadLibraryEx won't handle special files handled by Emacs handler. */
550 filename
= (char *) XSTRING (found
)->data
;
552 hinst
= LoadLibraryEx (filename
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
558 result
= XReadBitmapFile (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
559 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
560 if (result
!= BitmapSuccess
)
563 id
= x_allocate_bitmap_record (f
);
564 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
565 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
566 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
567 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
568 dpyinfo
->bitmaps
[id
- 1].height
= height
;
569 dpyinfo
->bitmaps
[id
- 1].width
= width
;
570 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
573 #endif /* MAC_TODO */
576 /* Remove reference to bitmap with id number ID. */
579 x_destroy_bitmap (f
, id
)
583 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
587 --dpyinfo
->bitmaps
[id
- 1].refcount
;
588 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
591 dpyinfo
->bitmaps
[id
- 1].bitmap_data
= NULL
;
597 /* Free all the bitmaps for the display specified by DPYINFO. */
600 x_destroy_all_bitmaps (dpyinfo
)
601 struct mac_display_info
*dpyinfo
;
604 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
605 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
606 xfree (dpyinfo
->bitmaps
[i
].bitmap_data
);
607 dpyinfo
->bitmaps_last
= 0;
610 /* Connect the frame-parameter names for W32 frames
611 to the ways of passing the parameter values to the window system.
613 The name of a parameter, as a Lisp symbol,
614 has an `x-frame-parameter' property which is an integer in Lisp
615 but can be interpreted as an `enum x_frame_parm' in C. */
617 struct x_frame_parm_table
620 void (*setter
) P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
623 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
624 static void x_set_line_spacing
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
625 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
626 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
627 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
628 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
629 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
630 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
631 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
632 void x_set_font
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
633 void x_set_border_width
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
634 void x_set_internal_border_width
P_ ((struct frame
*, Lisp_Object
,
636 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
637 void x_set_autoraise
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
638 void x_set_autolower
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
639 void x_set_vertical_scroll_bars
P_ ((struct frame
*, Lisp_Object
,
641 void x_set_visibility
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
642 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
643 void x_set_scroll_bar_width
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
644 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
645 void x_set_unsplittable
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
646 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
647 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
649 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
651 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
656 static void x_set_screen_gamma
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
658 static struct x_frame_parm_table x_frame_parms
[] =
660 "auto-raise", x_set_autoraise
,
661 "auto-lower", x_set_autolower
,
662 "background-color", x_set_background_color
,
663 "border-color", x_set_border_color
,
664 "border-width", x_set_border_width
,
665 "cursor-color", x_set_cursor_color
,
666 "cursor-type", x_set_cursor_type
,
668 "foreground-color", x_set_foreground_color
,
669 "icon-name", x_set_icon_name
,
670 #if 0 /* MAC_TODO: no icons for Mac */
671 "icon-type", x_set_icon_type
,
673 "internal-border-width", x_set_internal_border_width
,
674 "menu-bar-lines", x_set_menu_bar_lines
,
675 "mouse-color", x_set_mouse_color
,
676 "name", x_explicitly_set_name
,
677 "scroll-bar-width", x_set_scroll_bar_width
,
678 "title", x_set_title
,
679 "unsplittable", x_set_unsplittable
,
680 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
681 "visibility", x_set_visibility
,
682 "tool-bar-lines", x_set_tool_bar_lines
,
683 #if 0 /* MAC_TODO: cannot set color of scroll bar on the Mac? */
684 "scroll-bar-foreground", x_set_scroll_bar_foreground
,
685 "scroll-bar-background", x_set_scroll_bar_background
,
687 "screen-gamma", x_set_screen_gamma
,
688 "line-spacing", x_set_line_spacing
691 /* Attach the `x-frame-parameter' properties to
692 the Lisp symbol names of parameters relevant to Mac. */
695 init_x_parm_symbols ()
699 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
700 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
704 /* Change the parameters of frame F as specified by ALIST.
705 If a parameter is not specially recognized, do nothing;
706 otherwise call the `x_set_...' function for that parameter. */
709 x_set_frame_parameters (f
, alist
)
715 /* If both of these parameters are present, it's more efficient to
716 set them both at once. So we wait until we've looked at the
717 entire list before we set them. */
721 Lisp_Object left
, top
;
723 /* Same with these. */
724 Lisp_Object icon_left
, icon_top
;
726 /* Record in these vectors all the parms specified. */
730 int left_no_change
= 0, top_no_change
= 0;
731 int icon_left_no_change
= 0, icon_top_no_change
= 0;
733 struct gcpro gcpro1
, gcpro2
;
736 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
739 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
740 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
742 /* Extract parm names and values into those vectors. */
745 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
750 parms
[i
] = Fcar (elt
);
751 values
[i
] = Fcdr (elt
);
754 /* TAIL and ALIST are not used again below here. */
757 GCPRO2 (*parms
, *values
);
761 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
762 because their values appear in VALUES and strings are not valid. */
763 top
= left
= Qunbound
;
764 icon_left
= icon_top
= Qunbound
;
766 /* Provide default values for HEIGHT and WIDTH. */
767 if (FRAME_NEW_WIDTH (f
))
768 width
= FRAME_NEW_WIDTH (f
);
770 width
= FRAME_WIDTH (f
);
772 if (FRAME_NEW_HEIGHT (f
))
773 height
= FRAME_NEW_HEIGHT (f
);
775 height
= FRAME_HEIGHT (f
);
777 /* Process foreground_color and background_color before anything else.
778 They are independent of other properties, but other properties (e.g.,
779 cursor_color) are dependent upon them. */
780 for (p
= 0; p
< i
; p
++)
782 Lisp_Object prop
, val
;
786 if (EQ (prop
, Qforeground_color
) || EQ (prop
, Qbackground_color
))
788 register Lisp_Object param_index
, old_value
;
790 param_index
= Fget (prop
, Qx_frame_parameter
);
791 old_value
= get_frame_param (f
, prop
);
792 store_frame_param (f
, prop
, val
);
793 if (NATNUMP (param_index
)
794 && (XFASTINT (param_index
)
795 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
796 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
800 /* Now process them in reverse of specified order. */
801 for (i
--; i
>= 0; i
--)
803 Lisp_Object prop
, val
;
808 if (EQ (prop
, Qwidth
) && NUMBERP (val
))
809 width
= XFASTINT (val
);
810 else if (EQ (prop
, Qheight
) && NUMBERP (val
))
811 height
= XFASTINT (val
);
812 else if (EQ (prop
, Qtop
))
814 else if (EQ (prop
, Qleft
))
816 else if (EQ (prop
, Qicon_top
))
818 else if (EQ (prop
, Qicon_left
))
820 else if (EQ (prop
, Qforeground_color
) || EQ (prop
, Qbackground_color
))
821 /* Processed above. */
825 register Lisp_Object param_index
, old_value
;
827 param_index
= Fget (prop
, Qx_frame_parameter
);
828 old_value
= get_frame_param (f
, prop
);
829 store_frame_param (f
, prop
, val
);
830 if (NATNUMP (param_index
)
831 && (XFASTINT (param_index
)
832 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
833 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
837 /* Don't die if just one of these was set. */
838 if (EQ (left
, Qunbound
))
841 if (f
->output_data
.mac
->left_pos
< 0)
843 Fcons (make_number (f
->output_data
.mac
->left_pos
),
846 XSETINT (left
, f
->output_data
.mac
->left_pos
);
848 if (EQ (top
, Qunbound
))
851 if (f
->output_data
.mac
->top_pos
< 0)
853 Fcons (make_number (f
->output_data
.mac
->top_pos
), Qnil
));
855 XSETINT (top
, f
->output_data
.mac
->top_pos
);
858 /* If one of the icon positions was not set, preserve or default it. */
859 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
861 icon_left_no_change
= 1;
862 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
863 if (NILP (icon_left
))
864 XSETINT (icon_left
, 0);
866 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
868 icon_top_no_change
= 1;
869 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
871 XSETINT (icon_top
, 0);
874 /* Don't set these parameters unless they've been explicitly
875 specified. The window might be mapped or resized while we're in
876 this function, and we don't want to override that unless the lisp
877 code has asked for it.
879 Don't set these parameters unless they actually differ from the
880 window's current parameters; the window may not actually exist
885 check_frame_size (f
, &height
, &width
);
887 XSETFRAME (frame
, f
);
889 if (width
!= FRAME_WIDTH (f
)
890 || height
!= FRAME_HEIGHT (f
)
891 || FRAME_NEW_HEIGHT (f
) || FRAME_NEW_WIDTH (f
))
892 Fset_frame_size (frame
, make_number (width
), make_number (height
));
894 if ((!NILP (left
) || !NILP (top
))
895 && ! (left_no_change
&& top_no_change
)
896 && ! (NUMBERP (left
) && XINT (left
) == f
->output_data
.mac
->left_pos
897 && NUMBERP (top
) && XINT (top
) == f
->output_data
.mac
->top_pos
))
902 /* Record the signs. */
903 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
904 if (EQ (left
, Qminus
))
905 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
906 else if (INTEGERP (left
))
908 leftpos
= XINT (left
);
910 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
912 else if (CONSP (left
) && EQ (XCAR (left
), Qminus
)
913 && CONSP (XCDR (left
))
914 && INTEGERP (XCAR (XCDR (left
))))
916 leftpos
= - XINT (XCAR (XCDR (left
)));
917 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
919 else if (CONSP (left
) && EQ (XCAR (left
), Qplus
)
920 && CONSP (XCDR (left
))
921 && INTEGERP (XCAR (XCDR (left
))))
923 leftpos
= XINT (XCAR (XCDR (left
)));
926 if (EQ (top
, Qminus
))
927 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
928 else if (INTEGERP (top
))
932 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
934 else if (CONSP (top
) && EQ (XCAR (top
), Qminus
)
935 && CONSP (XCDR (top
))
936 && INTEGERP (XCAR (XCDR (top
))))
938 toppos
= - XINT (XCAR (XCDR (top
)));
939 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
941 else if (CONSP (top
) && EQ (XCAR (top
), Qplus
)
942 && CONSP (XCDR (top
))
943 && INTEGERP (XCAR (XCDR (top
))))
945 toppos
= XINT (XCAR (XCDR (top
)));
949 /* Store the numeric value of the position. */
950 f
->output_data
.mac
->top_pos
= toppos
;
951 f
->output_data
.mac
->left_pos
= leftpos
;
953 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
955 /* Actually set that position, and convert to absolute. */
956 x_set_offset (f
, leftpos
, toppos
, -1);
959 if ((!NILP (icon_left
) || !NILP (icon_top
))
960 && ! (icon_left_no_change
&& icon_top_no_change
))
961 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
967 /* Store the screen positions of frame F into XPTR and YPTR.
968 These are the positions of the containing window manager window,
969 not Emacs's own window. */
972 x_real_positions (f
, xptr
, yptr
)
979 #ifdef TARGET_API_MAC_CARBON
983 GetWindowPortBounds (f
->output_data
.mac
->mWP
, &r
);
984 SetPt (&pt
, r
.left
, r
.top
);
986 #else /* not TARGET_API_MAC_CARBON */
988 f
->output_data
.mac
->mWP
->portRect
.left
,
989 f
->output_data
.mac
->mWP
->portRect
.top
);
990 #endif /* not TARGET_API_MAC_CARBON */
999 /* Insert a description of internally-recorded parameters of frame X
1000 into the parameter alist *ALISTPTR that is to be given to the user.
1001 Only parameters that are specific to Mac and whose values are not
1002 correctly recorded in the frame's param_alist need to be considered
1006 x_report_frame_params (f
, alistptr
)
1008 Lisp_Object
*alistptr
;
1013 /* Represent negative positions (off the top or left screen edge)
1014 in a way that Fmodify_frame_parameters will understand correctly. */
1015 XSETINT (tem
, f
->output_data
.mac
->left_pos
);
1016 if (f
->output_data
.mac
->left_pos
>= 0)
1017 store_in_alist (alistptr
, Qleft
, tem
);
1019 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1021 XSETINT (tem
, f
->output_data
.mac
->top_pos
);
1022 if (f
->output_data
.mac
->top_pos
>= 0)
1023 store_in_alist (alistptr
, Qtop
, tem
);
1025 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1027 store_in_alist (alistptr
, Qborder_width
,
1028 make_number (f
->output_data
.mac
->border_width
));
1029 store_in_alist (alistptr
, Qinternal_border_width
,
1030 make_number (f
->output_data
.mac
->internal_border_width
));
1031 sprintf (buf
, "%ld", (long) FRAME_MAC_WINDOW (f
));
1032 store_in_alist (alistptr
, Qwindow_id
,
1033 build_string (buf
));
1034 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
1035 FRAME_SAMPLE_VISIBILITY (f
);
1036 store_in_alist (alistptr
, Qvisibility
,
1037 (FRAME_VISIBLE_P (f
) ? Qt
1038 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1039 store_in_alist (alistptr
, Qdisplay
,
1040 XCAR (FRAME_MAC_DISPLAY_INFO (f
)->name_list_element
));
1043 /* The default colors for the Mac color map */
1044 typedef struct colormap_t
1046 unsigned long color
;
1050 colormap_t mac_color_map
[] =
1052 { RGB_TO_ULONG(255, 250, 250), "snow" },
1053 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
1054 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
1055 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
1056 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
1057 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
1058 { RGB_TO_ULONG(255, 250, 240), "floral white" },
1059 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
1060 { RGB_TO_ULONG(253, 245, 230), "old lace" },
1061 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
1062 { RGB_TO_ULONG(250, 240, 230), "linen" },
1063 { RGB_TO_ULONG(250, 235, 215), "antique white" },
1064 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
1065 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
1066 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
1067 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
1068 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
1069 { RGB_TO_ULONG(255, 228, 196), "bisque" },
1070 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
1071 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
1072 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
1073 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
1074 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
1075 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
1076 { RGB_TO_ULONG(255, 255, 240), "ivory" },
1077 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
1078 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
1079 { RGB_TO_ULONG(255, 245, 238), "seashell" },
1080 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
1081 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
1082 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
1083 { RGB_TO_ULONG(240, 255, 255), "azure" },
1084 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
1085 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
1086 { RGB_TO_ULONG(230, 230, 250), "lavender" },
1087 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
1088 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
1089 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
1090 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
1091 { RGB_TO_ULONG(255, 255, 255), "white" },
1092 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
1093 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
1094 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
1095 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
1096 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
1097 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
1098 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
1099 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
1100 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
1101 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
1102 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
1103 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
1104 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
1105 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
1106 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
1107 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
1108 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
1109 { RGB_TO_ULONG(190, 190, 190), "gray" },
1110 { RGB_TO_ULONG(190, 190, 190), "grey" },
1111 { RGB_TO_ULONG(211, 211, 211), "light grey" },
1112 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
1113 { RGB_TO_ULONG(211, 211, 211), "light gray" },
1114 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
1115 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
1116 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
1117 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
1118 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
1119 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
1120 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
1121 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
1122 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
1123 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
1124 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
1125 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
1126 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
1127 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
1128 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
1129 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
1130 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
1131 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
1132 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
1133 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
1134 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
1135 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
1136 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
1137 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
1138 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
1139 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
1140 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
1141 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
1142 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
1143 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
1144 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
1145 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
1146 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
1147 { RGB_TO_ULONG(173, 216, 230), "light blue" },
1148 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
1149 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
1150 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
1151 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
1152 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
1153 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
1154 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
1155 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
1156 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
1157 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
1158 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
1159 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
1160 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
1161 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
1162 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
1163 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
1164 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
1165 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
1166 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
1167 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
1168 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
1169 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
1170 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
1171 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
1172 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
1173 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
1174 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
1175 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
1176 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
1177 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
1178 { RGB_TO_ULONG(152, 251, 152), "pale green" },
1179 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
1180 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
1181 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
1182 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
1183 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
1184 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
1185 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
1186 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
1187 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
1188 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
1189 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
1190 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
1191 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
1192 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
1193 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
1194 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
1195 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
1196 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
1197 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
1198 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
1199 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
1200 { RGB_TO_ULONG(240, 230, 140), "khaki" },
1201 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
1202 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
1203 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
1204 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
1205 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
1206 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
1207 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
1208 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
1209 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
1210 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
1211 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
1212 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
1213 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
1214 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
1215 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
1216 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
1217 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
1218 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
1219 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
1220 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
1221 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
1222 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
1223 { RGB_TO_ULONG(245, 245, 220), "beige" },
1224 { RGB_TO_ULONG(245, 222, 179), "wheat" },
1225 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
1226 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
1227 { RGB_TO_ULONG(210, 180, 140), "tan" },
1228 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
1229 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
1230 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
1231 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
1232 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
1233 { RGB_TO_ULONG(250, 128, 114), "salmon" },
1234 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
1235 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
1236 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
1237 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
1238 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
1239 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
1240 { RGB_TO_ULONG(240, 128, 128), "light coral" },
1241 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
1242 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
1243 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
1244 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
1245 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
1246 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
1247 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
1248 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
1249 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
1250 { RGB_TO_ULONG(255, 192, 203), "pink" },
1251 { RGB_TO_ULONG(255, 182, 193), "light pink" },
1252 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
1253 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
1254 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
1255 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
1256 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
1257 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
1258 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
1259 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
1260 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
1261 { RGB_TO_ULONG(238, 130, 238), "violet" },
1262 { RGB_TO_ULONG(221, 160, 221), "plum" },
1263 { RGB_TO_ULONG(218, 112, 214), "orchid" },
1264 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
1265 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
1266 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
1267 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
1268 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
1269 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
1270 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
1271 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
1272 { RGB_TO_ULONG(160, 32 , 240), "purple" },
1273 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
1274 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
1275 { RGB_TO_ULONG(216, 191, 216), "thistle" },
1276 { RGB_TO_ULONG(255, 250, 250), "snow1" },
1277 { RGB_TO_ULONG(238, 233, 233), "snow2" },
1278 { RGB_TO_ULONG(205, 201, 201), "snow3" },
1279 { RGB_TO_ULONG(139, 137, 137), "snow4" },
1280 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
1281 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
1282 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
1283 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
1284 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
1285 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
1286 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
1287 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
1288 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
1289 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
1290 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
1291 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
1292 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
1293 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
1294 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
1295 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
1296 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
1297 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
1298 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
1299 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
1300 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
1301 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
1302 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
1303 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
1304 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
1305 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
1306 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
1307 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
1308 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
1309 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
1310 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
1311 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
1312 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
1313 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
1314 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
1315 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
1316 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
1317 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
1318 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
1319 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
1320 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
1321 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
1322 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
1323 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
1324 { RGB_TO_ULONG(240, 255, 255), "azure1" },
1325 { RGB_TO_ULONG(224, 238, 238), "azure2" },
1326 { RGB_TO_ULONG(193, 205, 205), "azure3" },
1327 { RGB_TO_ULONG(131, 139, 139), "azure4" },
1328 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
1329 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
1330 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
1331 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
1332 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
1333 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
1334 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
1335 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
1336 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
1337 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
1338 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
1339 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
1340 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
1341 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
1342 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
1343 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
1344 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
1345 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
1346 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
1347 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
1348 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
1349 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
1350 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
1351 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
1352 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
1353 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
1354 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
1355 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
1356 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
1357 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
1358 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
1359 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
1360 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
1361 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
1362 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
1363 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
1364 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
1365 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
1366 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
1367 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
1368 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
1369 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
1370 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
1371 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
1372 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
1373 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
1374 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
1375 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
1376 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
1377 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
1378 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
1379 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
1380 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
1381 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
1382 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
1383 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
1384 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
1385 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
1386 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
1387 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
1388 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
1389 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
1390 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
1391 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
1392 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
1393 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
1394 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
1395 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
1396 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
1397 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
1398 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
1399 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
1400 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
1401 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
1402 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
1403 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
1404 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
1405 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
1406 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
1407 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
1408 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
1409 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
1410 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
1411 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
1412 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
1413 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
1414 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
1415 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
1416 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
1417 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
1418 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
1419 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
1420 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
1421 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
1422 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
1423 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
1424 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
1425 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
1426 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
1427 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
1428 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
1429 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
1430 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
1431 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
1432 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
1433 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
1434 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
1435 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
1436 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
1437 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
1438 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
1439 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
1440 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
1441 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
1442 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
1443 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
1444 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
1445 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
1446 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
1447 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
1448 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
1449 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
1450 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
1451 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
1452 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
1453 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
1454 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
1455 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
1456 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
1457 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
1458 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
1459 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
1460 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
1461 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
1462 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
1463 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
1464 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
1465 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
1466 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
1467 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
1468 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
1469 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
1470 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
1471 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
1472 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
1473 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
1474 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
1475 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
1476 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
1477 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
1478 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
1479 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
1480 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
1481 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
1482 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
1483 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
1484 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
1485 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
1486 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
1487 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
1488 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
1489 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
1490 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
1491 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
1492 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
1493 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
1494 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
1495 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
1496 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
1497 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
1498 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
1499 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
1500 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
1501 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
1502 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
1503 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
1504 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
1505 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
1506 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
1507 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
1508 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
1509 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
1510 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
1511 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
1512 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
1513 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
1514 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
1515 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
1516 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
1517 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
1518 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
1519 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
1520 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
1521 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
1522 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
1523 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
1524 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
1525 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
1526 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
1527 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
1528 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
1529 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
1530 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
1531 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
1532 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
1533 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
1534 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
1535 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
1536 { RGB_TO_ULONG(255, 181, 197), "pink1" },
1537 { RGB_TO_ULONG(238, 169, 184), "pink2" },
1538 { RGB_TO_ULONG(205, 145, 158), "pink3" },
1539 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
1540 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
1541 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
1542 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
1543 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
1544 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
1545 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
1546 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
1547 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
1548 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
1549 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
1550 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
1551 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
1552 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
1553 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
1554 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
1555 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
1556 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
1557 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
1558 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
1559 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
1560 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
1561 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
1562 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
1563 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
1564 { RGB_TO_ULONG(255, 187, 255), "plum1" },
1565 { RGB_TO_ULONG(238, 174, 238), "plum2" },
1566 { RGB_TO_ULONG(205, 150, 205), "plum3" },
1567 { RGB_TO_ULONG(139, 102, 139), "plum4" },
1568 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
1569 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
1570 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
1571 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
1572 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
1573 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
1574 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
1575 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
1576 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
1577 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
1578 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
1579 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
1580 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
1581 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
1582 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
1583 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
1584 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
1585 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
1586 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
1587 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
1588 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
1589 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
1590 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
1591 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
1592 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
1593 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
1594 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
1595 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
1596 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
1597 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
1598 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
1599 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
1600 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
1601 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
1602 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
1603 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
1604 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
1605 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
1606 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
1607 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
1608 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
1609 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
1610 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
1611 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
1612 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
1613 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
1614 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
1615 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
1616 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
1617 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
1618 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
1619 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
1620 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
1621 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
1622 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
1623 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
1624 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
1625 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
1626 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
1627 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
1628 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
1629 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
1630 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
1631 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
1632 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
1633 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
1634 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
1635 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
1636 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
1637 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
1638 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
1639 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
1640 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
1641 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
1642 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
1643 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
1644 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
1645 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
1646 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
1647 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
1648 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
1649 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
1650 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
1651 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
1652 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
1653 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
1654 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
1655 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
1656 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
1657 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
1658 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
1659 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
1660 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
1661 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
1662 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
1663 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
1664 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
1665 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
1666 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
1667 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
1668 { RGB_TO_ULONG(102, 102, 102), "gray40" },
1669 { RGB_TO_ULONG(102, 102, 102), "grey40" },
1670 { RGB_TO_ULONG(105, 105, 105), "gray41" },
1671 { RGB_TO_ULONG(105, 105, 105), "grey41" },
1672 { RGB_TO_ULONG(107, 107, 107), "gray42" },
1673 { RGB_TO_ULONG(107, 107, 107), "grey42" },
1674 { RGB_TO_ULONG(110, 110, 110), "gray43" },
1675 { RGB_TO_ULONG(110, 110, 110), "grey43" },
1676 { RGB_TO_ULONG(112, 112, 112), "gray44" },
1677 { RGB_TO_ULONG(112, 112, 112), "grey44" },
1678 { RGB_TO_ULONG(115, 115, 115), "gray45" },
1679 { RGB_TO_ULONG(115, 115, 115), "grey45" },
1680 { RGB_TO_ULONG(117, 117, 117), "gray46" },
1681 { RGB_TO_ULONG(117, 117, 117), "grey46" },
1682 { RGB_TO_ULONG(120, 120, 120), "gray47" },
1683 { RGB_TO_ULONG(120, 120, 120), "grey47" },
1684 { RGB_TO_ULONG(122, 122, 122), "gray48" },
1685 { RGB_TO_ULONG(122, 122, 122), "grey48" },
1686 { RGB_TO_ULONG(125, 125, 125), "gray49" },
1687 { RGB_TO_ULONG(125, 125, 125), "grey49" },
1688 { RGB_TO_ULONG(127, 127, 127), "gray50" },
1689 { RGB_TO_ULONG(127, 127, 127), "grey50" },
1690 { RGB_TO_ULONG(130, 130, 130), "gray51" },
1691 { RGB_TO_ULONG(130, 130, 130), "grey51" },
1692 { RGB_TO_ULONG(133, 133, 133), "gray52" },
1693 { RGB_TO_ULONG(133, 133, 133), "grey52" },
1694 { RGB_TO_ULONG(135, 135, 135), "gray53" },
1695 { RGB_TO_ULONG(135, 135, 135), "grey53" },
1696 { RGB_TO_ULONG(138, 138, 138), "gray54" },
1697 { RGB_TO_ULONG(138, 138, 138), "grey54" },
1698 { RGB_TO_ULONG(140, 140, 140), "gray55" },
1699 { RGB_TO_ULONG(140, 140, 140), "grey55" },
1700 { RGB_TO_ULONG(143, 143, 143), "gray56" },
1701 { RGB_TO_ULONG(143, 143, 143), "grey56" },
1702 { RGB_TO_ULONG(145, 145, 145), "gray57" },
1703 { RGB_TO_ULONG(145, 145, 145), "grey57" },
1704 { RGB_TO_ULONG(148, 148, 148), "gray58" },
1705 { RGB_TO_ULONG(148, 148, 148), "grey58" },
1706 { RGB_TO_ULONG(150, 150, 150), "gray59" },
1707 { RGB_TO_ULONG(150, 150, 150), "grey59" },
1708 { RGB_TO_ULONG(153, 153, 153), "gray60" },
1709 { RGB_TO_ULONG(153, 153, 153), "grey60" },
1710 { RGB_TO_ULONG(156, 156, 156), "gray61" },
1711 { RGB_TO_ULONG(156, 156, 156), "grey61" },
1712 { RGB_TO_ULONG(158, 158, 158), "gray62" },
1713 { RGB_TO_ULONG(158, 158, 158), "grey62" },
1714 { RGB_TO_ULONG(161, 161, 161), "gray63" },
1715 { RGB_TO_ULONG(161, 161, 161), "grey63" },
1716 { RGB_TO_ULONG(163, 163, 163), "gray64" },
1717 { RGB_TO_ULONG(163, 163, 163), "grey64" },
1718 { RGB_TO_ULONG(166, 166, 166), "gray65" },
1719 { RGB_TO_ULONG(166, 166, 166), "grey65" },
1720 { RGB_TO_ULONG(168, 168, 168), "gray66" },
1721 { RGB_TO_ULONG(168, 168, 168), "grey66" },
1722 { RGB_TO_ULONG(171, 171, 171), "gray67" },
1723 { RGB_TO_ULONG(171, 171, 171), "grey67" },
1724 { RGB_TO_ULONG(173, 173, 173), "gray68" },
1725 { RGB_TO_ULONG(173, 173, 173), "grey68" },
1726 { RGB_TO_ULONG(176, 176, 176), "gray69" },
1727 { RGB_TO_ULONG(176, 176, 176), "grey69" },
1728 { RGB_TO_ULONG(179, 179, 179), "gray70" },
1729 { RGB_TO_ULONG(179, 179, 179), "grey70" },
1730 { RGB_TO_ULONG(181, 181, 181), "gray71" },
1731 { RGB_TO_ULONG(181, 181, 181), "grey71" },
1732 { RGB_TO_ULONG(184, 184, 184), "gray72" },
1733 { RGB_TO_ULONG(184, 184, 184), "grey72" },
1734 { RGB_TO_ULONG(186, 186, 186), "gray73" },
1735 { RGB_TO_ULONG(186, 186, 186), "grey73" },
1736 { RGB_TO_ULONG(189, 189, 189), "gray74" },
1737 { RGB_TO_ULONG(189, 189, 189), "grey74" },
1738 { RGB_TO_ULONG(191, 191, 191), "gray75" },
1739 { RGB_TO_ULONG(191, 191, 191), "grey75" },
1740 { RGB_TO_ULONG(194, 194, 194), "gray76" },
1741 { RGB_TO_ULONG(194, 194, 194), "grey76" },
1742 { RGB_TO_ULONG(196, 196, 196), "gray77" },
1743 { RGB_TO_ULONG(196, 196, 196), "grey77" },
1744 { RGB_TO_ULONG(199, 199, 199), "gray78" },
1745 { RGB_TO_ULONG(199, 199, 199), "grey78" },
1746 { RGB_TO_ULONG(201, 201, 201), "gray79" },
1747 { RGB_TO_ULONG(201, 201, 201), "grey79" },
1748 { RGB_TO_ULONG(204, 204, 204), "gray80" },
1749 { RGB_TO_ULONG(204, 204, 204), "grey80" },
1750 { RGB_TO_ULONG(207, 207, 207), "gray81" },
1751 { RGB_TO_ULONG(207, 207, 207), "grey81" },
1752 { RGB_TO_ULONG(209, 209, 209), "gray82" },
1753 { RGB_TO_ULONG(209, 209, 209), "grey82" },
1754 { RGB_TO_ULONG(212, 212, 212), "gray83" },
1755 { RGB_TO_ULONG(212, 212, 212), "grey83" },
1756 { RGB_TO_ULONG(214, 214, 214), "gray84" },
1757 { RGB_TO_ULONG(214, 214, 214), "grey84" },
1758 { RGB_TO_ULONG(217, 217, 217), "gray85" },
1759 { RGB_TO_ULONG(217, 217, 217), "grey85" },
1760 { RGB_TO_ULONG(219, 219, 219), "gray86" },
1761 { RGB_TO_ULONG(219, 219, 219), "grey86" },
1762 { RGB_TO_ULONG(222, 222, 222), "gray87" },
1763 { RGB_TO_ULONG(222, 222, 222), "grey87" },
1764 { RGB_TO_ULONG(224, 224, 224), "gray88" },
1765 { RGB_TO_ULONG(224, 224, 224), "grey88" },
1766 { RGB_TO_ULONG(227, 227, 227), "gray89" },
1767 { RGB_TO_ULONG(227, 227, 227), "grey89" },
1768 { RGB_TO_ULONG(229, 229, 229), "gray90" },
1769 { RGB_TO_ULONG(229, 229, 229), "grey90" },
1770 { RGB_TO_ULONG(232, 232, 232), "gray91" },
1771 { RGB_TO_ULONG(232, 232, 232), "grey91" },
1772 { RGB_TO_ULONG(235, 235, 235), "gray92" },
1773 { RGB_TO_ULONG(235, 235, 235), "grey92" },
1774 { RGB_TO_ULONG(237, 237, 237), "gray93" },
1775 { RGB_TO_ULONG(237, 237, 237), "grey93" },
1776 { RGB_TO_ULONG(240, 240, 240), "gray94" },
1777 { RGB_TO_ULONG(240, 240, 240), "grey94" },
1778 { RGB_TO_ULONG(242, 242, 242), "gray95" },
1779 { RGB_TO_ULONG(242, 242, 242), "grey95" },
1780 { RGB_TO_ULONG(245, 245, 245), "gray96" },
1781 { RGB_TO_ULONG(245, 245, 245), "grey96" },
1782 { RGB_TO_ULONG(247, 247, 247), "gray97" },
1783 { RGB_TO_ULONG(247, 247, 247), "grey97" },
1784 { RGB_TO_ULONG(250, 250, 250), "gray98" },
1785 { RGB_TO_ULONG(250, 250, 250), "grey98" },
1786 { RGB_TO_ULONG(252, 252, 252), "gray99" },
1787 { RGB_TO_ULONG(252, 252, 252), "grey99" },
1788 { RGB_TO_ULONG(255, 255, 255), "gray100" },
1789 { RGB_TO_ULONG(255, 255, 255), "grey100" },
1790 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
1791 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
1792 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
1793 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
1794 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
1795 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
1796 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
1797 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
1798 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
1799 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
1800 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
1801 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1802 { RGB_TO_ULONG(144, 238, 144), "light green" },
1803 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1807 mac_color_map_lookup (colorname
)
1810 Lisp_Object ret
= Qnil
;
1815 for (i
= 0; i
< sizeof (mac_color_map
) / sizeof (mac_color_map
[0]); i
++)
1816 if (stricmp (colorname
, mac_color_map
[i
].name
) == 0)
1818 ret
= mac_color_map
[i
].color
;
1828 x_to_mac_color (colorname
)
1831 register Lisp_Object tail
, ret
= Qnil
;
1835 if (colorname
[0] == '#')
1837 /* Could be an old-style RGB Device specification. */
1840 color
= colorname
+ 1;
1842 size
= strlen(color
);
1843 if (size
== 3 || size
== 6 || size
== 9 || size
== 12)
1845 unsigned long colorval
;
1851 for (i
= 0; i
< 3; i
++)
1855 unsigned long value
;
1857 /* The check for 'x' in the following conditional takes into
1858 account the fact that strtol allows a "0x" in front of
1859 our numbers, and we don't. */
1860 if (!isxdigit(color
[0]) || color
[1] == 'x')
1864 value
= strtoul(color
, &end
, 16);
1866 if (errno
== ERANGE
|| end
- color
!= size
)
1871 value
= value
* 0x10;
1882 colorval
|= (value
<< pos
);
1893 else if (strnicmp(colorname
, "rgb:", 4) == 0)
1896 unsigned long colorval
;
1901 color
= colorname
+ 4;
1902 for (i
= 0; i
< 3; i
++)
1905 unsigned long value
;
1907 /* The check for 'x' in the following conditional takes into
1908 account the fact that strtol allows a "0x" in front of
1909 our numbers, and we don't. */
1910 if (!isxdigit(color
[0]) || color
[1] == 'x')
1912 value
= strtoul(color
, &end
, 16);
1913 if (errno
== ERANGE
)
1915 switch (end
- color
)
1918 value
= value
* 0x10 + value
;
1931 if (value
== ULONG_MAX
)
1933 colorval
|= (value
<< pos
);
1947 else if (strnicmp(colorname
, "rgbi:", 5) == 0)
1949 /* This is an RGB Intensity specification. */
1951 unsigned long colorval
;
1956 color
= colorname
+ 5;
1957 for (i
= 0; i
< 3; i
++)
1963 value
= strtod(color
, &end
);
1964 if (errno
== ERANGE
)
1966 if (value
< 0.0 || value
> 1.0)
1968 val
= (unsigned long)(0x100 * value
);
1969 /* We used 0x100 instead of 0xFF to give an continuous
1970 range between 0.0 and 1.0 inclusive. The next statement
1971 fixes the 1.0 case. */
1974 colorval
|= (val
<< pos
);
1989 ret
= mac_color_map_lookup (colorname
);
1995 /* Gamma-correct COLOR on frame F. */
1998 gamma_correct (f
, color
)
2000 unsigned long *color
;
2004 unsigned long red
, green
, blue
;
2006 red
= pow (RED_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2007 green
= pow (GREEN_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2008 blue
= pow (BLUE_FROM_ULONG (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5;
2009 *color
= RGB_TO_ULONG (red
, green
, blue
);
2013 /* Decide if color named COLOR is valid for the display associated
2014 with the selected frame; if so, return the rgb values in COLOR_DEF.
2015 If ALLOC is nonzero, allocate a new colormap cell. */
2018 mac_defined_color (f
, color
, color_def
, alloc
)
2024 register Lisp_Object tem
;
2025 unsigned long mac_color_ref
;
2027 tem
= x_to_mac_color (color
);
2033 /* Apply gamma correction. */
2034 mac_color_ref
= XUINT (tem
);
2035 gamma_correct (f
, &mac_color_ref
);
2036 XSETINT (tem
, mac_color_ref
);
2039 color_def
->pixel
= mac_color_ref
;
2040 color_def
->red
= RED_FROM_ULONG (mac_color_ref
);
2041 color_def
->green
= GREEN_FROM_ULONG (mac_color_ref
);
2042 color_def
->blue
= BLUE_FROM_ULONG (mac_color_ref
);
2052 /* Given a string ARG naming a color, compute a pixel value from it
2053 suitable for screen F.
2054 If F is not a color screen, return DEF (default) regardless of what
2058 x_decode_color (f
, arg
, def
)
2067 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
2068 return BLACK_PIX_DEFAULT (f
);
2069 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
2070 return WHITE_PIX_DEFAULT (f
);
2073 if ((FRAME_MAC_DISPLAY_INFO (f
)->n_planes
2074 * FRAME_MAC_DISPLAY_INFO (f
)->n_cbits
) == 1)
2078 if (mac_defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
2081 /* defined_color failed; return an ultimate default. */
2085 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
2086 the previous value of that parameter, NEW_VALUE is the new value. */
2089 x_set_line_spacing (f
, new_value
, old_value
)
2091 Lisp_Object new_value
, old_value
;
2093 if (NILP (new_value
))
2094 f
->extra_line_spacing
= 0;
2095 else if (NATNUMP (new_value
))
2096 f
->extra_line_spacing
= XFASTINT (new_value
);
2098 Fsignal (Qerror
, Fcons (build_string ("Illegal line-spacing"),
2099 Fcons (new_value
, Qnil
)));
2100 if (FRAME_VISIBLE_P (f
))
2105 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
2106 the previous value of that parameter, NEW_VALUE is the new value. */
2109 x_set_screen_gamma (f
, new_value
, old_value
)
2111 Lisp_Object new_value
, old_value
;
2113 if (NILP (new_value
))
2115 else if (NUMBERP (new_value
) && XFLOATINT (new_value
) > 0)
2116 /* The value 0.4545 is the normal viewing gamma. */
2117 f
->gamma
= 1.0 / (0.4545 * XFLOATINT (new_value
));
2119 Fsignal (Qerror
, Fcons (build_string ("Illegal screen-gamma"),
2120 Fcons (new_value
, Qnil
)));
2122 clear_face_cache (0);
2126 /* Functions called only from `x_set_frame_param'
2127 to set individual parameters.
2129 If FRAME_MAC_WINDOW (f) is 0,
2130 the frame is being created and its window does not exist yet.
2131 In that case, just record the parameter's new value
2132 in the standard place; do not attempt to change the window. */
2135 x_set_foreground_color (f
, arg
, oldval
)
2137 Lisp_Object arg
, oldval
;
2139 FRAME_FOREGROUND_PIXEL (f
)
2140 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2142 if (FRAME_MAC_WINDOW (f
) != 0)
2144 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
2145 if (FRAME_VISIBLE_P (f
))
2151 x_set_background_color (f
, arg
, oldval
)
2153 Lisp_Object arg
, oldval
;
2155 FRAME_BACKGROUND_PIXEL (f
)
2156 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
2158 if (FRAME_MAC_WINDOW (f
) != 0)
2160 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
2162 if (FRAME_VISIBLE_P (f
))
2168 x_set_mouse_color (f
, arg
, oldval
)
2170 Lisp_Object arg
, oldval
;
2172 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
2176 if (!EQ (Qnil
, arg
))
2177 f
->output_data
.mac
->mouse_pixel
2178 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2179 mask_color
= FRAME_BACKGROUND_PIXEL (f
);
2181 /* Don't let pointers be invisible. */
2182 if (mask_color
== f
->output_data
.mac
->mouse_pixel
2183 && mask_color
== FRAME_BACKGROUND_PIXEL (f
))
2184 f
->output_data
.mac
->mouse_pixel
= FRAME_FOREGROUND_PIXEL (f
);
2186 #if 0 /* MAC_TODO : cursor changes */
2189 /* It's not okay to crash if the user selects a screwy cursor. */
2190 count
= x_catch_errors (FRAME_W32_DISPLAY (f
));
2192 if (!EQ (Qnil
, Vx_pointer_shape
))
2194 CHECK_NUMBER (Vx_pointer_shape
);
2195 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XINT (Vx_pointer_shape
));
2198 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
2199 x_check_errors (FRAME_W32_DISPLAY (f
), "bad text pointer cursor: %s");
2201 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
2203 CHECK_NUMBER (Vx_nontext_pointer_shape
);
2204 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2205 XINT (Vx_nontext_pointer_shape
));
2208 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_left_ptr
);
2209 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
2211 if (!EQ (Qnil
, Vx_hourglass_pointer_shape
))
2213 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
2214 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2215 XINT (Vx_hourglass_pointer_shape
));
2218 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_watch
);
2219 x_check_errors (FRAME_W32_DISPLAY (f
), "bad busy pointer cursor: %s");
2221 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
2222 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
2224 CHECK_NUMBER (Vx_mode_pointer_shape
);
2225 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2226 XINT (Vx_mode_pointer_shape
));
2229 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
2230 x_check_errors (FRAME_W32_DISPLAY (f
), "bad modeline pointer cursor: %s");
2232 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
2234 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
2236 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2237 XINT (Vx_sensitive_text_pointer_shape
));
2240 cross_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_crosshair
);
2242 if (!NILP (Vx_window_horizontal_drag_shape
))
2244 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
2245 horizontal_drag_cursor
2246 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
2247 XINT (Vx_window_horizontal_drag_shape
));
2250 horizontal_drag_cursor
2251 = XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_sb_h_double_arrow
);
2253 /* Check and report errors with the above calls. */
2254 x_check_errors (FRAME_W32_DISPLAY (f
), "can't set cursor shape: %s");
2255 x_uncatch_errors (FRAME_W32_DISPLAY (f
), count
);
2258 XColor fore_color
, back_color
;
2260 fore_color
.pixel
= f
->output_data
.w32
->mouse_pixel
;
2261 back_color
.pixel
= mask_color
;
2262 XQueryColor (FRAME_W32_DISPLAY (f
),
2263 DefaultColormap (FRAME_W32_DISPLAY (f
),
2264 DefaultScreen (FRAME_W32_DISPLAY (f
))),
2266 XQueryColor (FRAME_W32_DISPLAY (f
),
2267 DefaultColormap (FRAME_W32_DISPLAY (f
),
2268 DefaultScreen (FRAME_W32_DISPLAY (f
))),
2270 XRecolorCursor (FRAME_W32_DISPLAY (f
), cursor
,
2271 &fore_color
, &back_color
);
2272 XRecolorCursor (FRAME_W32_DISPLAY (f
), nontext_cursor
,
2273 &fore_color
, &back_color
);
2274 XRecolorCursor (FRAME_W32_DISPLAY (f
), mode_cursor
,
2275 &fore_color
, &back_color
);
2276 XRecolorCursor (FRAME_W32_DISPLAY (f
), cross_cursor
,
2277 &fore_color
, &back_color
);
2278 XRecolorCursor (FRAME_W32_DISPLAY (f
), hourglass_cursor
,
2279 &fore_color
, &back_color
);
2282 if (FRAME_W32_WINDOW (f
) != 0)
2283 XDefineCursor (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), cursor
);
2285 if (cursor
!= f
->output_data
.w32
->text_cursor
&& f
->output_data
.w32
->text_cursor
!= 0)
2286 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->text_cursor
);
2287 f
->output_data
.w32
->text_cursor
= cursor
;
2289 if (nontext_cursor
!= f
->output_data
.w32
->nontext_cursor
2290 && f
->output_data
.w32
->nontext_cursor
!= 0)
2291 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->nontext_cursor
);
2292 f
->output_data
.w32
->nontext_cursor
= nontext_cursor
;
2294 if (hourglass_cursor
!= f
->output_data
.w32
->hourglass_cursor
2295 && f
->output_data
.w32
->hourglass_cursor
!= 0)
2296 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hourglass_cursor
);
2297 f
->output_data
.w32
->hourglass_cursor
= hourglass_cursor
;
2299 if (mode_cursor
!= f
->output_data
.w32
->modeline_cursor
2300 && f
->output_data
.w32
->modeline_cursor
!= 0)
2301 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->modeline_cursor
);
2302 f
->output_data
.w32
->modeline_cursor
= mode_cursor
;
2304 if (cross_cursor
!= f
->output_data
.w32
->cross_cursor
2305 && f
->output_data
.w32
->cross_cursor
!= 0)
2306 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->cross_cursor
);
2307 f
->output_data
.w32
->cross_cursor
= cross_cursor
;
2309 XFlush (FRAME_W32_DISPLAY (f
));
2312 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
2313 #endif /* MAC_TODO */
2317 x_set_cursor_color (f
, arg
, oldval
)
2319 Lisp_Object arg
, oldval
;
2321 unsigned long fore_pixel
;
2323 if (!NILP (Vx_cursor_fore_pixel
))
2324 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
2325 WHITE_PIX_DEFAULT (f
));
2327 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2328 f
->output_data
.mac
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2330 /* Make sure that the cursor color differs from the background color. */
2331 if (f
->output_data
.mac
->cursor_pixel
== FRAME_BACKGROUND_PIXEL (f
))
2333 f
->output_data
.mac
->cursor_pixel
= f
->output_data
.mac
->mouse_pixel
;
2334 if (f
->output_data
.mac
->cursor_pixel
== fore_pixel
)
2335 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2337 FRAME_FOREGROUND_PIXEL (f
) = fore_pixel
;
2339 #if 0 /* MAC_TODO: cannot figure out what to do (wrong number of params) */
2340 if (FRAME_MAC_WINDOW (f
) != 0)
2342 if (FRAME_VISIBLE_P (f
))
2344 x_display_cursor (f
, 0);
2345 x_display_cursor (f
, 1);
2350 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
2353 /* Set the border-color of frame F to pixel value PIX.
2354 Note that this does not fully take effect if done before
2357 x_set_border_pixel (f
, pix
)
2361 f
->output_data
.mac
->border_pixel
= pix
;
2363 if (FRAME_MAC_WINDOW (f
) != 0 && f
->output_data
.mac
->border_width
> 0)
2365 if (FRAME_VISIBLE_P (f
))
2370 /* Set the border-color of frame F to value described by ARG.
2371 ARG can be a string naming a color.
2372 The border-color is used for the border that is drawn by the server.
2373 Note that this does not fully take effect if done before
2374 F has a window; it must be redone when the window is created. */
2377 x_set_border_color (f
, arg
, oldval
)
2379 Lisp_Object arg
, oldval
;
2384 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2385 x_set_border_pixel (f
, pix
);
2386 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
2389 /* Value is the internal representation of the specified cursor type
2390 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
2391 of the bar cursor. */
2393 enum text_cursor_kinds
2394 x_specified_cursor_type (arg
, width
)
2398 enum text_cursor_kinds type
;
2405 else if (CONSP (arg
)
2406 && EQ (XCAR (arg
), Qbar
)
2407 && INTEGERP (XCDR (arg
))
2408 && XINT (XCDR (arg
)) >= 0)
2411 *width
= XINT (XCDR (arg
));
2413 else if (NILP (arg
))
2416 /* Treat anything unknown as "box cursor".
2417 It was bad to signal an error; people have trouble fixing
2418 .Xdefaults with Emacs, when it has something bad in it. */
2419 type
= FILLED_BOX_CURSOR
;
2425 x_set_cursor_type (f
, arg
, oldval
)
2427 Lisp_Object arg
, oldval
;
2431 FRAME_DESIRED_CURSOR (f
) = x_specified_cursor_type (arg
, &width
);
2432 f
->output_data
.mac
->cursor_width
= width
;
2434 /* Make sure the cursor gets redrawn. This is overkill, but how
2435 often do people change cursor types? */
2436 update_mode_lines
++;
2439 #if 0 /* MAC_TODO: really no icon for Mac */
2441 x_set_icon_type (f
, arg
, oldval
)
2443 Lisp_Object arg
, oldval
;
2447 if (NILP (arg
) && NILP (oldval
))
2450 if (STRINGP (arg
) && STRINGP (oldval
)
2451 && EQ (Fstring_equal (oldval
, arg
), Qt
))
2454 if (SYMBOLP (arg
) && SYMBOLP (oldval
) && EQ (arg
, oldval
))
2459 result
= x_bitmap_icon (f
, arg
);
2463 error ("No icon window available");
2468 #endif /* MAC_TODO */
2470 /* Return non-nil if frame F wants a bitmap icon. */
2478 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
2486 x_set_icon_name (f
, arg
, oldval
)
2488 Lisp_Object arg
, oldval
;
2494 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
2497 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
2502 #if 0 /* MAC_TODO */
2503 if (f
->output_data
.w32
->icon_bitmap
!= 0)
2508 result
= x_text_icon (f
,
2509 (char *) XSTRING ((!NILP (f
->icon_name
)
2518 error ("No icon window available");
2521 /* If the window was unmapped (and its icon was mapped),
2522 the new icon is not mapped, so map the window in its stead. */
2523 if (FRAME_VISIBLE_P (f
))
2525 #ifdef USE_X_TOOLKIT
2526 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
2528 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
2531 XFlush (FRAME_W32_DISPLAY (f
));
2533 #endif /* MAC_TODO */
2536 extern Lisp_Object
x_new_font ();
2537 extern Lisp_Object
x_new_fontset();
2540 x_set_font (f
, arg
, oldval
)
2542 Lisp_Object arg
, oldval
;
2545 Lisp_Object fontset_name
;
2547 int old_fontset
= FRAME_FONTSET(f
);
2551 fontset_name
= Fquery_fontset (arg
, Qnil
);
2554 result
= (STRINGP (fontset_name
)
2555 ? x_new_fontset (f
, XSTRING (fontset_name
)->data
)
2556 : x_new_font (f
, XSTRING (arg
)->data
));
2559 if (EQ (result
, Qnil
))
2560 error ("Font `%s' is not defined", XSTRING (arg
)->data
);
2561 else if (EQ (result
, Qt
))
2562 error ("The characters of the given font have varying widths");
2563 else if (STRINGP (result
))
2565 if (STRINGP (fontset_name
))
2567 /* Fontset names are built from ASCII font names, so the
2568 names may be equal despite there was a change. */
2569 if (old_fontset
== FRAME_FONTSET (f
))
2572 else if (!NILP (Fequal (result
, oldval
)))
2575 store_frame_param (f
, Qfont
, result
);
2576 recompute_basic_faces (f
);
2581 do_pending_window_change (0);
2583 /* Don't call `face-set-after-frame-default' when faces haven't been
2584 initialized yet. This is the case when called from
2585 Fx_create_frame. In that case, the X widget or window doesn't
2586 exist either, and we can end up in x_report_frame_params with a
2587 null widget which gives a segfault. */
2588 if (FRAME_FACE_CACHE (f
))
2590 XSETFRAME (frame
, f
);
2591 call1 (Qface_set_after_frame_default
, frame
);
2596 x_set_border_width (f
, arg
, oldval
)
2598 Lisp_Object arg
, oldval
;
2602 if (XINT (arg
) == f
->output_data
.mac
->border_width
)
2605 #if 0 /* MAC_TODO */
2606 if (FRAME_MAC_WINDOW (f
) != 0)
2607 error ("Cannot change the border width of a window");
2610 f
->output_data
.mac
->border_width
= XINT (arg
);
2614 x_set_internal_border_width (f
, arg
, oldval
)
2616 Lisp_Object arg
, oldval
;
2618 int old
= f
->output_data
.mac
->internal_border_width
;
2621 f
->output_data
.mac
->internal_border_width
= XINT (arg
);
2622 if (f
->output_data
.mac
->internal_border_width
< 0)
2623 f
->output_data
.mac
->internal_border_width
= 0;
2625 if (f
->output_data
.mac
->internal_border_width
== old
)
2628 if (FRAME_MAC_WINDOW (f
) != 0)
2630 x_set_window_size (f
, 0, f
->width
, f
->height
);
2631 SET_FRAME_GARBAGED (f
);
2632 do_pending_window_change (0);
2635 SET_FRAME_GARBAGED (f
);
2639 x_set_visibility (f
, value
, oldval
)
2641 Lisp_Object value
, oldval
;
2644 XSETFRAME (frame
, f
);
2647 Fmake_frame_invisible (frame
, Qt
);
2648 else if (EQ (value
, Qicon
))
2649 Ficonify_frame (frame
);
2651 Fmake_frame_visible (frame
);
2655 /* Change window heights in windows rooted in WINDOW by N lines. */
2658 x_change_window_heights (window
, n
)
2662 struct window
*w
= XWINDOW (window
);
2664 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
2665 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
2667 if (INTEGERP (w
->orig_top
))
2668 XSETFASTINT (w
->orig_top
, XFASTINT (w
->orig_top
) + n
);
2669 if (INTEGERP (w
->orig_height
))
2670 XSETFASTINT (w
->orig_height
, XFASTINT (w
->orig_height
) - n
);
2672 /* Handle just the top child in a vertical split. */
2673 if (!NILP (w
->vchild
))
2674 x_change_window_heights (w
->vchild
, n
);
2676 /* Adjust all children in a horizontal split. */
2677 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
2679 w
= XWINDOW (window
);
2680 x_change_window_heights (window
, n
);
2685 x_set_menu_bar_lines (f
, value
, oldval
)
2687 Lisp_Object value
, oldval
;
2690 int olines
= FRAME_MENU_BAR_LINES (f
);
2692 /* Right now, menu bars don't work properly in minibuf-only frames;
2693 most of the commands try to apply themselves to the minibuffer
2694 frame itself, and get an error because you can't switch buffers
2695 in or split the minibuffer window. */
2696 if (FRAME_MINIBUF_ONLY_P (f
))
2699 if (INTEGERP (value
))
2700 nlines
= XINT (value
);
2704 FRAME_MENU_BAR_LINES (f
) = 0;
2706 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
2709 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
2710 free_frame_menubar (f
);
2711 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
2713 /* Adjust the frame size so that the client (text) dimensions
2714 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
2716 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2717 do_pending_window_change (0);
2723 /* Set the number of lines used for the tool bar of frame F to VALUE.
2724 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
2725 is the old number of tool bar lines. This function changes the
2726 height of all windows on frame F to match the new tool bar height.
2727 The frame's height doesn't change. */
2730 x_set_tool_bar_lines (f
, value
, oldval
)
2732 Lisp_Object value
, oldval
;
2734 int delta
, nlines
, root_height
;
2735 Lisp_Object root_window
;
2737 /* Treat tool bars like menu bars. */
2738 if (FRAME_MINIBUF_ONLY_P (f
))
2741 /* Use VALUE only if an integer >= 0. */
2742 if (INTEGERP (value
) && XINT (value
) >= 0)
2743 nlines
= XFASTINT (value
);
2747 /* Make sure we redisplay all windows in this frame. */
2748 ++windows_or_buffers_changed
;
2750 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
2752 /* Don't resize the tool-bar to more than we have room for. */
2753 root_window
= FRAME_ROOT_WINDOW (f
);
2754 root_height
= XINT (XWINDOW (root_window
)->height
);
2755 if (root_height
- delta
< 1)
2757 delta
= root_height
- 1;
2758 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
2761 FRAME_TOOL_BAR_LINES (f
) = nlines
;
2762 x_change_window_heights (root_window
, delta
);
2765 /* We also have to make sure that the internal border at the top of
2766 the frame, below the menu bar or tool bar, is redrawn when the
2767 tool bar disappears. This is so because the internal border is
2768 below the tool bar if one is displayed, but is below the menu bar
2769 if there isn't a tool bar. The tool bar draws into the area
2770 below the menu bar. */
2771 if (FRAME_MAC_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
2775 clear_current_matrices (f
);
2776 updating_frame
= NULL
;
2779 /* If the tool bar gets smaller, the internal border below it
2780 has to be cleared. It was formerly part of the display
2781 of the larger tool bar, and updating windows won't clear it. */
2784 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
2785 int width
= PIXEL_WIDTH (f
);
2786 int y
= nlines
* CANON_Y_UNIT (f
);
2789 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2790 0, y
, width
, height
, 0);
2793 if (WINDOWP (f
->tool_bar_window
))
2794 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
2799 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
2802 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2803 name; if NAME is a string, set F's name to NAME and set
2804 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2806 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2807 suggesting a new name, which lisp code should override; if
2808 F->explicit_name is set, ignore the new name; otherwise, set it. */
2811 x_set_name (f
, name
, explicit)
2816 /* Make sure that requests from lisp code override requests from
2817 Emacs redisplay code. */
2820 /* If we're switching from explicit to implicit, we had better
2821 update the mode lines and thereby update the title. */
2822 if (f
->explicit_name
&& NILP (name
))
2823 update_mode_lines
= 1;
2825 f
->explicit_name
= ! NILP (name
);
2827 else if (f
->explicit_name
)
2830 /* If NAME is nil, set the name to the w32_id_name. */
2833 /* Check for no change needed in this very common case
2834 before we do any consing. */
2835 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
,
2836 XSTRING (f
->name
)->data
))
2838 name
= build_string (FRAME_MAC_DISPLAY_INFO (f
)->mac_id_name
);
2841 CHECK_STRING (name
);
2843 /* Don't change the name if it's already NAME. */
2844 if (! NILP (Fstring_equal (name
, f
->name
)))
2849 /* For setting the frame title, the title parameter should override
2850 the name parameter. */
2851 if (! NILP (f
->title
))
2854 if (FRAME_MAC_WINDOW (f
))
2856 if (STRING_MULTIBYTE (name
))
2857 #if 0 /* MAC_TODO: encoding title string */
2858 name
= ENCODE_SYSTEM (name
);
2867 if (strlen (XSTRING (name
)->data
) < 255)
2869 strcpy (windowTitle
, XSTRING (name
)->data
);
2870 c2pstr (windowTitle
);
2871 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2879 /* This function should be called when the user's lisp code has
2880 specified a name for the frame; the name will override any set by the
2883 x_explicitly_set_name (f
, arg
, oldval
)
2885 Lisp_Object arg
, oldval
;
2887 x_set_name (f
, arg
, 1);
2890 /* This function should be called by Emacs redisplay code to set the
2891 name; names set this way will never override names set by the user's
2894 x_implicitly_set_name (f
, arg
, oldval
)
2896 Lisp_Object arg
, oldval
;
2898 x_set_name (f
, arg
, 0);
2901 /* Change the title of frame F to NAME.
2902 If NAME is nil, use the frame name as the title.
2904 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2905 name; if NAME is a string, set F's name to NAME and set
2906 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2908 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2909 suggesting a new name, which lisp code should override; if
2910 F->explicit_name is set, ignore the new name; otherwise, set it. */
2913 x_set_title (f
, name
, old_name
)
2915 Lisp_Object name
, old_name
;
2917 /* Don't change the title if it's already NAME. */
2918 if (EQ (name
, f
->title
))
2921 update_mode_lines
= 1;
2928 if (FRAME_MAC_WINDOW (f
))
2930 if (STRING_MULTIBYTE (name
))
2931 #if 0 /* MAC_TODO: encoding title string */
2932 name
= ENCODE_SYSTEM (name
);
2941 if (strlen (XSTRING (name
)->data
) < 255)
2943 strcpy (windowTitle
, XSTRING (name
)->data
);
2944 c2pstr (windowTitle
);
2945 SetWTitle (FRAME_MAC_WINDOW (f
), windowTitle
);
2954 x_set_autoraise (f
, arg
, oldval
)
2956 Lisp_Object arg
, oldval
;
2958 f
->auto_raise
= !EQ (Qnil
, arg
);
2962 x_set_autolower (f
, arg
, oldval
)
2964 Lisp_Object arg
, oldval
;
2966 f
->auto_lower
= !EQ (Qnil
, arg
);
2970 x_set_unsplittable (f
, arg
, oldval
)
2972 Lisp_Object arg
, oldval
;
2974 f
->no_split
= !NILP (arg
);
2978 x_set_vertical_scroll_bars (f
, arg
, oldval
)
2980 Lisp_Object arg
, oldval
;
2982 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
2983 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
2984 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
2985 || (!NILP (arg
) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
2987 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
)
2989 ? vertical_scroll_bar_none
2991 ? vertical_scroll_bar_right
2992 : vertical_scroll_bar_left
);
2994 /* We set this parameter before creating the window for the
2995 frame, so we can get the geometry right from the start.
2996 However, if the window hasn't been created yet, we shouldn't
2997 call x_set_window_size. */
2998 if (FRAME_MAC_WINDOW (f
))
2999 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
3000 do_pending_window_change (0);
3005 x_set_scroll_bar_width (f
, arg
, oldval
)
3007 Lisp_Object arg
, oldval
;
3009 /* Imitate X without X Toolkit */
3011 int wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
3016 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 16; /* Aqua scroll bars. */
3017 FRAME_SCROLL_BAR_COLS (f
) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) +
3019 #else /* not MAC_OSX */
3020 /* Make the actual width at least 14 pixels and a multiple of a
3022 FRAME_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
3024 /* Use all of that space (aside from required margins) for the
3026 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
3027 #endif /* not MAC_OSX */
3028 if (FRAME_MAC_WINDOW (f
))
3029 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
3030 do_pending_window_change (0);
3032 else if (INTEGERP (arg
) && XINT (arg
) > 0
3033 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
3035 if (XFASTINT (arg
) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
3036 XSETINT (arg
, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
+ 1);
3038 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
3039 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
3040 if (FRAME_MAC_WINDOW (f
))
3041 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
3042 do_pending_window_change (0);
3044 change_frame_size (f
, 0, FRAME_WIDTH (f
), 0, 0, 0);
3045 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.hpos
= 0;
3046 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.x
= 0;
3049 /* Subroutines of creating an frame. */
3051 /* Make sure that Vx_resource_name is set to a reasonable value.
3052 Fix it up, or set it to `emacs' if it is too hopeless. */
3055 validate_x_resource_name ()
3058 /* Number of valid characters in the resource name. */
3060 /* Number of invalid characters in the resource name. */
3065 if (STRINGP (Vx_resource_name
))
3067 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
3070 len
= STRING_BYTES (XSTRING (Vx_resource_name
));
3072 /* Only letters, digits, - and _ are valid in resource names.
3073 Count the valid characters and count the invalid ones. */
3074 for (i
= 0; i
< len
; i
++)
3077 if (! ((c
>= 'a' && c
<= 'z')
3078 || (c
>= 'A' && c
<= 'Z')
3079 || (c
>= '0' && c
<= '9')
3080 || c
== '-' || c
== '_'))
3087 /* Not a string => completely invalid. */
3088 bad_count
= 5, good_count
= 0;
3090 /* If name is valid already, return. */
3094 /* If name is entirely invalid, or nearly so, use `emacs'. */
3096 || (good_count
== 1 && bad_count
> 0))
3098 Vx_resource_name
= build_string ("emacs");
3102 /* Name is partly valid. Copy it and replace the invalid characters
3103 with underscores. */
3105 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
3107 for (i
= 0; i
< len
; i
++)
3109 int c
= XSTRING (new)->data
[i
];
3110 if (! ((c
>= 'a' && c
<= 'z')
3111 || (c
>= 'A' && c
<= 'Z')
3112 || (c
>= '0' && c
<= '9')
3113 || c
== '-' || c
== '_'))
3114 XSTRING (new)->data
[i
] = '_';
3119 #if 0 /* MAC_TODO: implement resource strings */
3120 extern char *x_get_string_resource ();
3122 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
3123 doc
: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3124 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3125 class, where INSTANCE is the name under which Emacs was invoked, or
3126 the name specified by the `-name' or `-rn' command-line arguments.
3128 The optional arguments COMPONENT and SUBCLASS add to the key and the
3129 class, respectively. You must specify both of them or neither.
3130 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3131 and the class is `Emacs.CLASS.SUBCLASS'. */)
3132 (attribute
, class, component
, subclass
)
3133 Lisp_Object attribute
, class, component
, subclass
;
3135 register char *value
;
3139 CHECK_STRING (attribute
);
3140 CHECK_STRING (class);
3142 if (!NILP (component
))
3143 CHECK_STRING (component
);
3144 if (!NILP (subclass
))
3145 CHECK_STRING (subclass
);
3146 if (NILP (component
) != NILP (subclass
))
3147 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3149 validate_x_resource_name ();
3151 /* Allocate space for the components, the dots which separate them,
3152 and the final '\0'. Make them big enough for the worst case. */
3153 name_key
= (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name
))
3154 + (STRINGP (component
)
3155 ? STRING_BYTES (XSTRING (component
)) : 0)
3156 + STRING_BYTES (XSTRING (attribute
))
3159 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
3160 + STRING_BYTES (XSTRING (class))
3161 + (STRINGP (subclass
)
3162 ? STRING_BYTES (XSTRING (subclass
)) : 0)
3165 /* Start with emacs.FRAMENAME for the name (the specific one)
3166 and with `Emacs' for the class key (the general one). */
3167 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
3168 strcpy (class_key
, EMACS_CLASS
);
3170 strcat (class_key
, ".");
3171 strcat (class_key
, XSTRING (class)->data
);
3173 if (!NILP (component
))
3175 strcat (class_key
, ".");
3176 strcat (class_key
, XSTRING (subclass
)->data
);
3178 strcat (name_key
, ".");
3179 strcat (name_key
, XSTRING (component
)->data
);
3182 strcat (name_key
, ".");
3183 strcat (name_key
, XSTRING (attribute
)->data
);
3185 value
= x_get_string_resource (Qnil
,
3186 name_key
, class_key
);
3188 if (value
!= (char *) 0)
3189 return build_string (value
);
3194 /* Used when C code wants a resource value. */
3197 x_get_resource_string (attribute
, class)
3198 char *attribute
, *class;
3202 struct frame
*sf
= SELECTED_FRAME ();
3204 /* Allocate space for the components, the dots which separate them,
3205 and the final '\0'. */
3206 name_key
= (char *) alloca (STRING_BYTES (XSTRING (Vinvocation_name
))
3207 + strlen (attribute
) + 2);
3208 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
3209 + strlen (class) + 2);
3211 sprintf (name_key
, "%s.%s",
3212 XSTRING (Vinvocation_name
)->data
,
3214 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
3216 return x_get_string_resource (sf
, name_key
, class_key
);
3218 #endif /* MAC_TODO */
3220 /* Types we might convert a resource string into. */
3230 /* Return the value of parameter PARAM.
3232 First search ALIST, then Vdefault_frame_alist, then the X defaults
3233 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3235 Convert the resource to the type specified by desired_type.
3237 If no default is specified, return Qunbound. If you call
3238 w32_get_arg, make sure you deal with Qunbound in a reasonable way,
3239 and don't let it get stored in any Lisp-visible variables! */
3242 mac_get_arg (alist
, param
, attribute
, class, type
)
3243 Lisp_Object alist
, param
;
3246 enum resource_types type
;
3248 register Lisp_Object tem
;
3250 tem
= Fassq (param
, alist
);
3252 tem
= Fassq (param
, Vdefault_frame_alist
);
3256 #if 0 /* MAC_TODO: search resource also */
3259 tem
= Fx_get_resource (build_string (attribute
),
3260 build_string (class),
3268 case RES_TYPE_NUMBER
:
3269 return make_number (atoi (XSTRING (tem
)->data
));
3271 case RES_TYPE_FLOAT
:
3272 return make_float (atof (XSTRING (tem
)->data
));
3274 case RES_TYPE_BOOLEAN
:
3275 tem
= Fdowncase (tem
);
3276 if (!strcmp (XSTRING (tem
)->data
, "on")
3277 || !strcmp (XSTRING (tem
)->data
, "true"))
3282 case RES_TYPE_STRING
:
3285 case RES_TYPE_SYMBOL
:
3286 /* As a special case, we map the values `true' and `on'
3287 to Qt, and `false' and `off' to Qnil. */
3290 lower
= Fdowncase (tem
);
3291 if (!strcmp (XSTRING (lower
)->data
, "on")
3292 || !strcmp (XSTRING (lower
)->data
, "true"))
3294 else if (!strcmp (XSTRING (lower
)->data
, "off")
3295 || !strcmp (XSTRING (lower
)->data
, "false"))
3298 return Fintern (tem
, Qnil
);
3306 #endif /* MAC_TODO */
3312 /* Record in frame F the specified or default value according to ALIST
3313 of the parameter named PROP (a Lisp symbol).
3314 If no value is specified for PROP, look for an X default for XPROP
3315 on the frame named NAME.
3316 If that is not found either, use the value DEFLT. */
3319 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
3326 enum resource_types type
;
3330 tem
= mac_get_arg (alist
, prop
, xprop
, xclass
, type
);
3331 if (EQ (tem
, Qunbound
))
3333 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
3337 /* XParseGeometry copied from w32xfns.c */
3340 * XParseGeometry parses strings of the form
3341 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
3342 * width, height, xoffset, and yoffset are unsigned integers.
3343 * Example: "=80x24+300-49"
3344 * The equal sign is optional.
3345 * It returns a bitmask that indicates which of the four values
3346 * were actually found in the string. For each value found,
3347 * the corresponding argument is updated; for each value
3348 * not found, the corresponding argument is left unchanged.
3352 read_integer (string
, NextString
)
3353 register char *string
;
3356 register int Result
= 0;
3361 else if (*string
== '-')
3366 for (; (*string
>= '0') && (*string
<= '9'); string
++)
3368 Result
= (Result
* 10) + (*string
- '0');
3370 *NextString
= string
;
3378 XParseGeometry (string
, x
, y
, width
, height
)
3381 unsigned int *width
, *height
; /* RETURN */
3384 register char *strind
;
3385 unsigned int tempWidth
, tempHeight
;
3387 char *nextCharacter
;
3389 if ((string
== NULL
) || (*string
== '\0')) return (mask
);
3391 string
++; /* ignore possible '=' at beg of geometry spec */
3393 strind
= (char *)string
;
3394 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
3396 tempWidth
= read_integer (strind
, &nextCharacter
);
3397 if (strind
== nextCharacter
)
3399 strind
= nextCharacter
;
3403 if (*strind
== 'x' || *strind
== 'X')
3406 tempHeight
= read_integer (strind
, &nextCharacter
);
3407 if (strind
== nextCharacter
)
3409 strind
= nextCharacter
;
3410 mask
|= HeightValue
;
3413 if ((*strind
== '+') || (*strind
== '-'))
3418 tempX
= -read_integer (strind
, &nextCharacter
);
3419 if (strind
== nextCharacter
)
3421 strind
= nextCharacter
;
3428 tempX
= read_integer (strind
, &nextCharacter
);
3429 if (strind
== nextCharacter
)
3431 strind
= nextCharacter
;
3434 if ((*strind
== '+') || (*strind
== '-'))
3439 tempY
= -read_integer (strind
, &nextCharacter
);
3440 if (strind
== nextCharacter
)
3442 strind
= nextCharacter
;
3449 tempY
= read_integer (strind
, &nextCharacter
);
3450 if (strind
== nextCharacter
)
3452 strind
= nextCharacter
;
3458 /* If strind isn't at the end of the string the it's an invalid
3459 geometry specification. */
3461 if (*strind
!= '\0') return (0);
3467 if (mask
& WidthValue
)
3469 if (mask
& HeightValue
)
3470 *height
= tempHeight
;
3474 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
3475 doc
: /* Parse an X-style geometry string STRING.
3476 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
3477 The properties returned may include `top', `left', `height', and `width'.
3478 The value of `left' or `top' may be an integer,
3479 or a list (+ N) meaning N pixels relative to top/left corner,
3480 or a list (- N) meaning -N pixels relative to bottom/right corner. */)
3485 unsigned int width
, height
;
3488 CHECK_STRING (string
);
3490 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
3491 &x
, &y
, &width
, &height
);
3494 if (geometry
& XValue
)
3496 Lisp_Object element
;
3498 if (x
>= 0 && (geometry
& XNegative
))
3499 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
3500 else if (x
< 0 && ! (geometry
& XNegative
))
3501 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
3503 element
= Fcons (Qleft
, make_number (x
));
3504 result
= Fcons (element
, result
);
3507 if (geometry
& YValue
)
3509 Lisp_Object element
;
3511 if (y
>= 0 && (geometry
& YNegative
))
3512 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
3513 else if (y
< 0 && ! (geometry
& YNegative
))
3514 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
3516 element
= Fcons (Qtop
, make_number (y
));
3517 result
= Fcons (element
, result
);
3520 if (geometry
& WidthValue
)
3521 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
3522 if (geometry
& HeightValue
)
3523 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
3528 /* Calculate the desired size and position of this window,
3529 and return the flags saying which aspects were specified.
3531 This function does not make the coordinates positive. */
3533 #define DEFAULT_ROWS 40
3534 #define DEFAULT_COLS 80
3537 x_figure_window_size (f
, parms
)
3541 register Lisp_Object tem0
, tem1
, tem2
;
3542 long window_prompting
= 0;
3544 /* Default values if we fall through.
3545 Actually, if that happens we should get
3546 window manager prompting. */
3547 SET_FRAME_WIDTH (f
, DEFAULT_COLS
);
3548 f
->height
= DEFAULT_ROWS
;
3549 /* Window managers expect that if program-specified
3550 positions are not (0,0), they're intentional, not defaults. */
3551 f
->output_data
.mac
->top_pos
= 0;
3552 f
->output_data
.mac
->left_pos
= 0;
3554 tem0
= mac_get_arg (parms
, Qheight
, 0, 0, RES_TYPE_NUMBER
);
3555 tem1
= mac_get_arg (parms
, Qwidth
, 0, 0, RES_TYPE_NUMBER
);
3556 tem2
= mac_get_arg (parms
, Quser_size
, 0, 0, RES_TYPE_NUMBER
);
3557 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
3559 if (!EQ (tem0
, Qunbound
))
3561 CHECK_NUMBER (tem0
);
3562 f
->height
= XINT (tem0
);
3564 if (!EQ (tem1
, Qunbound
))
3566 CHECK_NUMBER (tem1
);
3567 SET_FRAME_WIDTH (f
, XINT (tem1
));
3569 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
3570 window_prompting
|= USSize
;
3572 window_prompting
|= PSize
;
3575 f
->output_data
.mac
->vertical_scroll_bar_extra
3576 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
3578 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
3579 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
3580 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
3582 x_compute_fringe_widths (f
, 0);
3584 f
->output_data
.mac
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
3585 f
->output_data
.mac
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
3587 tem0
= mac_get_arg (parms
, Qtop
, 0, 0, RES_TYPE_NUMBER
);
3588 tem1
= mac_get_arg (parms
, Qleft
, 0, 0, RES_TYPE_NUMBER
);
3589 tem2
= mac_get_arg (parms
, Quser_position
, 0, 0, RES_TYPE_NUMBER
);
3590 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
3592 if (EQ (tem0
, Qminus
))
3594 f
->output_data
.mac
->top_pos
= 0;
3595 window_prompting
|= YNegative
;
3597 else if (CONSP (tem0
) && EQ (XCAR (tem0
), Qminus
)
3598 && CONSP (XCDR (tem0
))
3599 && INTEGERP (XCAR (XCDR (tem0
))))
3601 f
->output_data
.mac
->top_pos
= - XINT (XCAR (XCDR (tem0
)));
3602 window_prompting
|= YNegative
;
3604 else if (CONSP (tem0
) && EQ (XCAR (tem0
), Qplus
)
3605 && CONSP (XCDR (tem0
))
3606 && INTEGERP (XCAR (XCDR (tem0
))))
3608 f
->output_data
.mac
->top_pos
= XINT (XCAR (XCDR (tem0
)));
3610 else if (EQ (tem0
, Qunbound
))
3611 f
->output_data
.mac
->top_pos
= 0;
3614 CHECK_NUMBER (tem0
);
3615 f
->output_data
.mac
->top_pos
= XINT (tem0
);
3616 if (f
->output_data
.mac
->top_pos
< 0)
3617 window_prompting
|= YNegative
;
3620 if (EQ (tem1
, Qminus
))
3622 f
->output_data
.mac
->left_pos
= 0;
3623 window_prompting
|= XNegative
;
3625 else if (CONSP (tem1
) && EQ (XCAR (tem1
), Qminus
)
3626 && CONSP (XCDR (tem1
))
3627 && INTEGERP (XCAR (XCDR (tem1
))))
3629 f
->output_data
.mac
->left_pos
= - XINT (XCAR (XCDR (tem1
)));
3630 window_prompting
|= XNegative
;
3632 else if (CONSP (tem1
) && EQ (XCAR (tem1
), Qplus
)
3633 && CONSP (XCDR (tem1
))
3634 && INTEGERP (XCAR (XCDR (tem1
))))
3636 f
->output_data
.mac
->left_pos
= XINT (XCAR (XCDR (tem1
)));
3638 else if (EQ (tem1
, Qunbound
))
3639 f
->output_data
.mac
->left_pos
= 0;
3642 CHECK_NUMBER (tem1
);
3643 f
->output_data
.mac
->left_pos
= XINT (tem1
);
3644 if (f
->output_data
.mac
->left_pos
< 0)
3645 window_prompting
|= XNegative
;
3648 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
3649 window_prompting
|= USPosition
;
3651 window_prompting
|= PPosition
;
3654 return window_prompting
;
3658 #if 0 /* MAC_TODO */
3659 /* Create and set up the Mac window for frame F. */
3662 mac_window (f
, window_prompting
, minibuffer_only
)
3664 long window_prompting
;
3665 int minibuffer_only
;
3671 /* Use the resource name as the top-level window name
3672 for looking up resources. Make a non-Lisp copy
3673 for the window manager, so GC relocation won't bother it.
3675 Elsewhere we specify the window name for the window manager. */
3678 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
3679 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
3680 strcpy (f
->namebuf
, str
);
3683 SetRect (&r
, f
->output_data
.mac
->left_pos
, f
->output_data
.mac
->top_pos
,
3684 f
->output_data
.mac
->left_pos
+ PIXEL_WIDTH (f
),
3685 f
->output_data
.mac
->top_pos
+ PIXEL_HEIGHT (f
));
3686 FRAME_MAC_WINDOW (f
)
3687 = NewCWindow (NULL
, &r
, "\p", 1, zoomDocProc
, (WindowPtr
) -1, 1, (long) f
->output_data
.mac
);
3689 validate_x_resource_name ();
3691 /* x_set_name normally ignores requests to set the name if the
3692 requested name is the same as the current name. This is the one
3693 place where that assumption isn't correct; f->name is set, but
3694 the server hasn't been told. */
3697 int explicit = f
->explicit_name
;
3699 f
->explicit_name
= 0;
3702 x_set_name (f
, name
, explicit);
3705 ShowWindow (FRAME_MAC_WINDOW (f
));
3709 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3710 initialize_frame_menubar (f
);
3712 if (FRAME_MAC_WINDOW (f
) == 0)
3713 error ("Unable to create window");
3715 #endif /* MAC_TODO */
3717 /* Handle the icon stuff for this window. Perhaps later we might
3718 want an x_set_icon_position which can be called interactively as
3726 Lisp_Object icon_x
, icon_y
;
3728 /* Set the position of the icon. Note that Windows 95 groups all
3729 icons in the tray. */
3730 icon_x
= mac_get_arg (parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
3731 icon_y
= mac_get_arg (parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
3732 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
3734 CHECK_NUMBER (icon_x
);
3735 CHECK_NUMBER (icon_y
);
3737 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
3738 error ("Both left and top icon corners of icon must be specified");
3742 if (! EQ (icon_x
, Qunbound
))
3743 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
3746 /* Start up iconic or window? */
3747 x_wm_set_window_state
3748 (f
, (EQ (w32_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
), Qicon
)
3752 x_text_icon (f
, (char *) XSTRING ((!NILP (f
->icon_name
)
3765 XGCValues gc_values
;
3769 /* Create the GC's of this frame.
3770 Note that many default values are used. */
3773 gc_values
.font
= f
->output_data
.mac
->font
;
3774 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
3775 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
3776 f
->output_data
.mac
->normal_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3777 FRAME_MAC_WINDOW (f
),
3778 GCFont
| GCForeground
| GCBackground
,
3781 /* Reverse video style. */
3782 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3783 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
3784 f
->output_data
.mac
->reverse_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3785 FRAME_MAC_WINDOW (f
),
3786 GCFont
| GCForeground
| GCBackground
,
3789 /* Cursor has cursor-color background, background-color foreground. */
3790 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3791 gc_values
.background
= f
->output_data
.mac
->cursor_pixel
;
3792 f
->output_data
.mac
->cursor_gc
= XCreateGC (FRAME_MAC_DISPLAY (f
),
3793 FRAME_MAC_WINDOW (f
),
3794 GCFont
| GCForeground
| GCBackground
,
3798 f
->output_data
.mac
->white_relief
.gc
= 0;
3799 f
->output_data
.mac
->black_relief
.gc
= 0;
3805 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3807 doc
: /* Make a new window, which is called a \"frame\" in Emacs terms.
3808 Returns an Emacs frame object.
3809 ALIST is an alist of frame parameters.
3810 If the parameters specify that the frame should not have a minibuffer,
3811 and do not specify a specific minibuffer window to use,
3812 then `default-minibuffer-frame' must be a frame whose minibuffer can
3813 be shared by the new frame.
3815 This function is an internal primitive--use `make-frame' instead. */)
3820 Lisp_Object frame
, tem
;
3822 int minibuffer_only
= 0;
3823 long window_prompting
= 0;
3825 int count
= BINDING_STACK_SIZE ();
3826 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3827 Lisp_Object display
;
3828 struct mac_display_info
*dpyinfo
= NULL
;
3831 char x_frame_name
[10];
3832 static int x_frame_count
= 2; /* begins at 2 because terminal frame is F1 */
3836 /* Use this general default value to start with
3837 until we know if this frame has a specified name. */
3838 Vx_resource_name
= Vinvocation_name
;
3840 display
= mac_get_arg (parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3841 if (EQ (display
, Qunbound
))
3843 dpyinfo
= check_x_display_info (display
);
3845 kb
= dpyinfo
->kboard
;
3847 kb
= &the_only_kboard
;
3850 name
= mac_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3852 && ! EQ (name
, Qunbound
)
3854 error ("Invalid frame name--not a string or nil");
3857 Vx_resource_name
= name
;
3859 /* See if parent window is specified. */
3860 parent
= mac_get_arg (parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3861 if (EQ (parent
, Qunbound
))
3863 if (! NILP (parent
))
3864 CHECK_NUMBER (parent
);
3866 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3867 /* No need to protect DISPLAY because that's not used after passing
3868 it to make_frame_without_minibuffer. */
3870 GCPRO4 (parms
, parent
, name
, frame
);
3871 tem
= mac_get_arg (parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3873 if (EQ (tem
, Qnone
) || NILP (tem
))
3874 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3875 else if (EQ (tem
, Qonly
))
3877 f
= make_minibuffer_frame ();
3878 minibuffer_only
= 1;
3880 else if (WINDOWP (tem
))
3881 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3885 if (EQ (name
, Qunbound
) || NILP (name
))
3887 sprintf (x_frame_name
, "F%d", x_frame_count
++);
3888 f
->name
= build_string (x_frame_name
);
3889 f
->explicit_name
= 0;
3894 f
->explicit_name
= 1;
3897 XSETFRAME (frame
, f
);
3899 /* Note that X Windows does support scroll bars. */
3900 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3902 f
->output_method
= output_mac
;
3903 f
->output_data
.mac
= (struct mac_output
*) xmalloc (sizeof (struct mac_output
));
3904 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
3905 FRAME_FONTSET (f
) = -1;
3906 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
3907 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
3910 FRAME_FONTSET (f
) = -1;
3914 = mac_get_arg (parms
, Qicon_name
, "iconName", "Title", RES_TYPE_STRING
);
3915 if (! STRINGP (f
->icon_name
))
3916 f
->icon_name
= Qnil
;
3918 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
3920 FRAME_KBOARD (f
) = kb
;
3923 /* Specify the parent under which to make this window. */
3927 f
->output_data
.mac
->parent_desc
= (Window
) parent
;
3928 f
->output_data
.mac
->explicit_parent
= 1;
3932 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
3933 f
->output_data
.mac
->explicit_parent
= 0;
3936 /* Set the name; the functions to which we pass f expect the name to
3938 if (EQ (name
, Qunbound
) || NILP (name
))
3940 f
->name
= build_string (dpyinfo
->mac_id_name
);
3941 f
->explicit_name
= 0;
3946 f
->explicit_name
= 1;
3947 /* use the frame's title when getting resources for this frame. */
3948 specbind (Qx_resource_name
, name
);
3951 /* Extract the window parameters from the supplied values
3952 that are needed to determine window geometry. */
3956 font
= mac_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3959 /* First, try whatever font the caller has specified. */
3962 tem
= Fquery_fontset (font
, Qnil
);
3964 font
= x_new_fontset (f
, XSTRING (tem
)->data
);
3966 font
= x_new_font (f
, XSTRING (font
)->data
);
3968 /* Try out a font which we hope has bold and italic variations. */
3969 if (! STRINGP (font
))
3970 font
= x_new_font (f
, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
3971 /* If those didn't work, look for something which will at least work. */
3972 if (!STRINGP (font
))
3973 font
= x_new_font (f
, "-*-monaco-*-12-*-mac-roman");
3974 if (! STRINGP (font
))
3975 font
= x_new_font (f
, "-*-courier-*-10-*-mac-roman");
3976 if (! STRINGP (font
))
3977 error ("Cannot find any usable font");
3980 x_default_parameter (f
, parms
, Qfont
, font
,
3981 "font", "Font", RES_TYPE_STRING
);
3984 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
3985 "borderwidth", "BorderWidth", RES_TYPE_NUMBER
);
3986 /* This defaults to 2 in order to match xterm. We recognize either
3987 internalBorderWidth or internalBorder (which is what xterm calls
3989 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3993 value
= mac_get_arg (parms
, Qinternal_border_width
,
3994 "internalBorder", "InternalBorder", RES_TYPE_NUMBER
);
3995 if (! EQ (value
, Qunbound
))
3996 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3999 /* Default internalBorderWidth to 0 on Windows to match other programs. */
4000 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (0),
4001 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER
);
4002 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qright
,
4003 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL
);
4005 /* Also do the stuff which must be set before the window exists. */
4006 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
4007 "foreground", "Foreground", RES_TYPE_STRING
);
4008 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
4009 "background", "Background", RES_TYPE_STRING
);
4010 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
4011 "pointerColor", "Foreground", RES_TYPE_STRING
);
4012 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
4013 "cursorColor", "Foreground", RES_TYPE_STRING
);
4014 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
4015 "borderColor", "BorderColor", RES_TYPE_STRING
);
4016 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
4017 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
4018 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
4019 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
4020 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
4021 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
4022 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
4023 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
4026 /* Init faces before x_default_parameter is called for scroll-bar
4027 parameters because that function calls x_set_scroll_bar_width,
4028 which calls change_frame_size, which calls Fset_window_buffer,
4029 which runs hooks, which call Fvertical_motion. At the end, we
4030 end up in init_iterator with a null face cache, which should not
4032 init_frame_faces (f
);
4034 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
4035 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
4036 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (0),
4037 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
4038 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
4039 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL
);
4040 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
4041 "title", "Title", RES_TYPE_STRING
);
4043 f
->output_data
.mac
->parent_desc
= FRAME_MAC_DISPLAY_INFO (f
)->root_window
;
4044 window_prompting
= x_figure_window_size (f
, parms
);
4046 if (window_prompting
& XNegative
)
4048 if (window_prompting
& YNegative
)
4049 f
->output_data
.mac
->win_gravity
= SouthEastGravity
;
4051 f
->output_data
.mac
->win_gravity
= NorthEastGravity
;
4055 if (window_prompting
& YNegative
)
4056 f
->output_data
.mac
->win_gravity
= SouthWestGravity
;
4058 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
4061 f
->output_data
.mac
->size_hint_flags
= window_prompting
;
4063 tem
= mac_get_arg (parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
4064 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
4066 /* Create the window. Add the tool-bar height to the initial frame
4067 height so that the user gets a text display area of the size he
4068 specified with -g or via the registry. Later changes of the
4069 tool-bar height don't change the frame size. This is done so that
4070 users can create tall Emacs frames without having to guess how
4071 tall the tool-bar will get. */
4072 f
->height
+= FRAME_TOOL_BAR_LINES (f
);
4074 /* mac_window (f, window_prompting, minibuffer_only); */
4081 /* Now consider the frame official. */
4082 FRAME_MAC_DISPLAY_INFO (f
)->reference_count
++;
4083 Vframe_list
= Fcons (frame
, Vframe_list
);
4085 /* We need to do this after creating the window, so that the
4086 icon-creation functions can say whose icon they're describing. */
4087 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
4088 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
4090 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
4091 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4092 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
4093 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4094 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
4095 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
4096 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
4097 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER
);
4099 /* Dimensions, especially f->height, must be done via change_frame_size.
4100 Change will not be effected unless different from the current
4106 SET_FRAME_WIDTH (f
, 0);
4107 change_frame_size (f
, height
, width
, 1, 0, 0);
4109 /* Set up faces after all frame parameters are known. */
4110 call1 (Qface_set_after_frame_default
, frame
);
4112 #if 0 /* MAC_TODO: when we have window manager hints */
4113 /* Tell the server what size and position, etc, we want, and how
4114 badly we want them. This should be done after we have the menu
4115 bar so that its size can be taken into account. */
4117 x_wm_set_size_hint (f
, window_prompting
, 0);
4121 /* Make the window appear on the frame and enable display, unless
4122 the caller says not to. However, with explicit parent, Emacs
4123 cannot control visibility, so don't try. */
4124 if (! f
->output_data
.mac
->explicit_parent
)
4126 Lisp_Object visibility
;
4128 visibility
= mac_get_arg (parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
);
4129 if (EQ (visibility
, Qunbound
))
4132 #if 0 /* MAC_TODO: really no iconify on Mac */
4133 if (EQ (visibility
, Qicon
))
4134 x_iconify_frame (f
);
4137 if (! NILP (visibility
))
4138 x_make_frame_visible (f
);
4140 /* Must have been Qnil. */
4145 /* Make sure windows on this frame appear in calls to next-window
4146 and similar functions. */
4147 Vwindow_list
= Qnil
;
4149 return unbind_to (count
, frame
);
4152 /* FRAME is used only to get a handle on the X display. We don't pass the
4153 display info directly because we're called from frame.c, which doesn't
4154 know about that structure. */
4156 x_get_focus_frame (frame
)
4157 struct frame
*frame
;
4159 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
4161 if (! dpyinfo
->x_focus_frame
)
4164 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
4168 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
4169 doc
: /* Internal function called by `color-defined-p', which see. */)
4171 Lisp_Object color
, frame
;
4174 FRAME_PTR f
= check_x_frame (frame
);
4176 CHECK_STRING (color
);
4178 if (mac_defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
4184 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
4185 doc
: /* Internal function called by `color-values', which see. */)
4187 Lisp_Object color
, frame
;
4190 FRAME_PTR f
= check_x_frame (frame
);
4192 CHECK_STRING (color
);
4194 if (mac_defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
4198 rgb
[0] = make_number ((RED_FROM_ULONG (foo
.pixel
) << 8)
4199 | RED_FROM_ULONG (foo
.pixel
));
4200 rgb
[1] = make_number ((GREEN_FROM_ULONG (foo
.pixel
) << 8)
4201 | GREEN_FROM_ULONG (foo
.pixel
));
4202 rgb
[2] = make_number ((BLUE_FROM_ULONG (foo
.pixel
) << 8)
4203 | BLUE_FROM_ULONG (foo
.pixel
));
4204 return Flist (3, rgb
);
4210 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
4211 doc
: /* Internal function called by `display-color-p', which see. */)
4213 Lisp_Object display
;
4215 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4217 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 2)
4223 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
4225 doc
: /* Return t if the X display supports shades of gray.
4226 Note that color displays do support shades of gray.
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 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 1)
4241 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
4243 doc
: /* Returns the width in pixels of the X display DISPLAY.
4244 The optional argument DISPLAY specifies which display to ask about.
4245 DISPLAY should be either a frame or a display name (a string).
4246 If omitted or nil, that stands for the selected frame's display. */)
4248 Lisp_Object display
;
4250 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4252 return make_number (dpyinfo
->width
);
4255 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
4256 Sx_display_pixel_height
, 0, 1, 0,
4257 doc
: /* Returns the height in pixels of the X display DISPLAY.
4258 The optional argument DISPLAY specifies which display to ask about.
4259 DISPLAY should be either a frame or a display name (a string).
4260 If omitted or nil, that stands for the selected frame's display. */)
4262 Lisp_Object display
;
4264 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4266 return make_number (dpyinfo
->height
);
4269 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
4271 doc
: /* Returns the number of bitplanes of the display DISPLAY.
4272 The optional argument DISPLAY specifies which display to ask about.
4273 DISPLAY should be either a frame or a display name (a string).
4274 If omitted or nil, that stands for the selected frame's display. */)
4276 Lisp_Object display
;
4278 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4280 return make_number (dpyinfo
->n_planes
* dpyinfo
->n_cbits
);
4283 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
4285 doc
: /* Returns the number of color cells of the display DISPLAY.
4286 The optional argument DISPLAY specifies which display to ask about.
4287 DISPLAY should be either a frame or a display name (a string).
4288 If omitted or nil, that stands for the selected frame's display. */)
4290 Lisp_Object display
;
4292 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4294 /* MAC_TODO: check whether this is right */
4295 return make_number ((unsigned long) (pow (2, dpyinfo
->n_cbits
)));
4298 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
4299 Sx_server_max_request_size
,
4301 doc
: /* Returns the maximum request size of the server of display DISPLAY.
4302 The optional argument DISPLAY specifies which display to ask about.
4303 DISPLAY should be either a frame or a display name (a string).
4304 If omitted or nil, that stands for the selected frame's display. */)
4306 Lisp_Object display
;
4308 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4310 return make_number (1);
4313 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
4314 doc
: /* Returns the vendor ID string of the Mac OS system (Apple).
4315 The optional argument DISPLAY specifies which display to ask about.
4316 DISPLAY should be either a frame or a display name (a string).
4317 If omitted or nil, that stands for the selected frame's display. */)
4319 Lisp_Object display
;
4321 return build_string ("Apple Computers");
4324 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
4325 doc
: /* Returns the version numbers of the server of display DISPLAY.
4326 The value is a list of three integers: the major and minor
4327 version numbers, and the vendor-specific release
4328 number. See also the function `x-server-vendor'.
4330 The optional argument DISPLAY specifies which display to ask about.
4331 DISPLAY should be either a frame or a display name (a string).
4332 If omitted or nil, that stands for the selected frame's display. */)
4334 Lisp_Object display
;
4336 int mac_major_version
, mac_minor_version
;
4339 if (Gestalt (gestaltSystemVersion
, &response
) != noErr
)
4340 error ("Cannot get Mac OS version");
4342 mac_major_version
= (response
>> 8) & 0xf;
4343 mac_minor_version
= (response
>> 4) & 0xf;
4345 return Fcons (make_number (mac_major_version
),
4346 Fcons (make_number (mac_minor_version
), Qnil
));
4349 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
4350 doc
: /* Return the number of screens on the server of display DISPLAY.
4351 The optional argument DISPLAY specifies which display to ask about.
4352 DISPLAY should be either a frame or a display name (a string).
4353 If omitted or nil, that stands for the selected frame's display. */)
4355 Lisp_Object display
;
4357 return make_number (1);
4360 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
4361 doc
: /* Return the height in millimeters of the X display DISPLAY.
4362 The optional argument DISPLAY specifies which display to ask about.
4363 DISPLAY should be either a frame or a display name (a string).
4364 If omitted or nil, that stands for the selected frame's display. */)
4366 Lisp_Object display
;
4368 /* MAC_TODO: this is an approximation, and only of the main display */
4370 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4375 return make_number ((int) (v
/ 72.0 * 25.4));
4378 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
4379 doc
: /* Return the width in millimeters of the X display DISPLAY.
4380 The optional argument DISPLAY specifies which display to ask about.
4381 DISPLAY should be either a frame or a display name (a string).
4382 If omitted or nil, that stands for the selected frame's display. */)
4384 Lisp_Object display
;
4386 /* MAC_TODO: this is an approximation, and only of the main display */
4388 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4393 return make_number ((int) (h
/ 72.0 * 25.4));
4396 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
4397 Sx_display_backing_store
, 0, 1, 0,
4398 doc
: /* Returns an indication of whether display DISPLAY does backing store.
4399 The value may be `always', `when-mapped', or `not-useful'.
4400 The optional argument DISPLAY specifies which display to ask about.
4401 DISPLAY should be either a frame or a display name (a string).
4402 If omitted or nil, that stands for the selected frame's display. */)
4404 Lisp_Object display
;
4406 return intern ("not-useful");
4409 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
4410 Sx_display_visual_class
, 0, 1, 0,
4411 doc
: /* Returns the visual class of the display DISPLAY.
4412 The value is one of the symbols `static-gray', `gray-scale',
4413 `static-color', `pseudo-color', `true-color', or `direct-color'.
4415 The optional argument DISPLAY specifies which display to ask about.
4416 DISPLAY should be either a frame or a display name (a string).
4417 If omitted or nil, that stands for the selected frame's display. */)
4419 Lisp_Object display
;
4421 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4424 switch (dpyinfo
->visual
->class)
4426 case StaticGray
: return (intern ("static-gray"));
4427 case GrayScale
: return (intern ("gray-scale"));
4428 case StaticColor
: return (intern ("static-color"));
4429 case PseudoColor
: return (intern ("pseudo-color"));
4430 case TrueColor
: return (intern ("true-color"));
4431 case DirectColor
: return (intern ("direct-color"));
4433 error ("Display has an unknown visual class");
4437 error ("Display has an unknown visual class");
4440 DEFUN ("x-display-save-under", Fx_display_save_under
,
4441 Sx_display_save_under
, 0, 1, 0,
4442 doc
: /* Returns t if the display DISPLAY supports the save-under feature.
4443 The optional argument DISPLAY specifies which display to ask about.
4444 DISPLAY should be either a frame or a display name (a string).
4445 If omitted or nil, that stands for the selected frame's display. */)
4447 Lisp_Object display
;
4454 register struct frame
*f
;
4456 return PIXEL_WIDTH (f
);
4461 register struct frame
*f
;
4463 return PIXEL_HEIGHT (f
);
4468 register struct frame
*f
;
4470 return FONT_WIDTH (f
->output_data
.mac
->font
);
4475 register struct frame
*f
;
4477 return f
->output_data
.mac
->line_height
;
4482 register struct frame
*f
;
4484 return FRAME_MAC_DISPLAY_INFO (f
)->n_planes
;
4487 /* Return the display structure for the display named NAME.
4488 Open a new connection if necessary. */
4490 struct mac_display_info
*
4491 x_display_info_for_name (name
)
4495 struct mac_display_info
*dpyinfo
;
4497 CHECK_STRING (name
);
4499 for (dpyinfo
= &one_mac_display_info
, names
= x_display_name_list
;
4501 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4504 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4509 /* Use this general default value to start with. */
4510 Vx_resource_name
= Vinvocation_name
;
4512 validate_x_resource_name ();
4514 dpyinfo
= mac_term_init (name
, (unsigned char *) 0,
4515 (char *) XSTRING (Vx_resource_name
)->data
);
4518 error ("Cannot connect to server %s", XSTRING (name
)->data
);
4521 XSETFASTINT (Vwindow_system_version
, 3);
4526 #if 0 /* MAC_TODO: implement network support */
4527 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4529 doc
: /* Open a connection to a server.
4530 DISPLAY is the name of the display to connect to.
4531 Optional second arg XRM-STRING is a string of resources in xrdb format.
4532 If the optional third arg MUST-SUCCEED is non-nil,
4533 terminate Emacs if we can't open the connection. */)
4534 (display
, xrm_string
, must_succeed
)
4535 Lisp_Object display
, xrm_string
, must_succeed
;
4537 unsigned char *xrm_option
;
4538 struct mac_display_info
*dpyinfo
;
4540 CHECK_STRING (display
);
4541 if (! NILP (xrm_string
))
4542 CHECK_STRING (xrm_string
);
4544 if (! EQ (Vwindow_system
, intern ("mac")))
4545 error ("Not using Mac OS");
4547 if (! NILP (xrm_string
))
4548 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
4550 xrm_option
= (unsigned char *) 0;
4552 validate_x_resource_name ();
4554 /* This is what opens the connection and sets x_current_display.
4555 This also initializes many symbols, such as those used for input. */
4556 dpyinfo
= mac_term_init (display
, xrm_option
,
4557 (char *) XSTRING (Vx_resource_name
)->data
);
4561 if (!NILP (must_succeed
))
4562 fatal ("Cannot connect to server %s.\n",
4563 XSTRING (display
)->data
);
4565 error ("Cannot connect to server %s", XSTRING (display
)->data
);
4570 XSETFASTINT (Vwindow_system_version
, 3);
4574 DEFUN ("x-close-connection", Fx_close_connection
,
4575 Sx_close_connection
, 1, 1, 0,
4576 doc
: /* Close the connection to DISPLAY's server.
4577 For DISPLAY, specify either a frame or a display name (a string).
4578 If DISPLAY is nil, that stands for the selected frame's display. */)
4580 Lisp_Object display
;
4582 struct mac_display_info
*dpyinfo
= check_x_display_info (display
);
4585 if (dpyinfo
->reference_count
> 0)
4586 error ("Display still has frames on it");
4589 /* Free the fonts in the font table. */
4590 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4591 if (dpyinfo
->font_table
[i
].name
)
4593 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
4594 xfree (dpyinfo
->font_table
[i
].full_name
);
4595 xfree (dpyinfo
->font_table
[i
].name
);
4596 x_unload_font (dpyinfo
, dpyinfo
->font_table
[i
].font
);
4598 x_destroy_all_bitmaps (dpyinfo
);
4600 x_delete_display (dpyinfo
);
4607 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4608 doc
: /* Return the list of display names that Emacs has connections to. */)
4611 Lisp_Object tail
, result
;
4614 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4615 result
= Fcons (XCAR (XCAR (tail
)), result
);
4620 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4621 doc
: /* If ON is non-nil, report errors as soon as the erring request is made.
4622 If ON is nil, allow buffering of requests.
4623 This is a noop on Mac OS systems.
4624 The optional second argument DISPLAY specifies which display to act on.
4625 DISPLAY should be either a frame or a display name (a string).
4626 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4628 Lisp_Object display
, on
;
4634 /***********************************************************************
4636 ***********************************************************************/
4638 /* Value is the number of elements of vector VECTOR. */
4640 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4642 /* List of supported image types. Use define_image_type to add new
4643 types. Use lookup_image_type to find a type for a given symbol. */
4645 static struct image_type
*image_types
;
4647 /* The symbol `image' which is the car of the lists used to represent
4650 extern Lisp_Object Qimage
;
4652 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4658 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4659 extern Lisp_Object QCdata
, QCtype
;
4660 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4661 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4662 Lisp_Object QCindex
;
4664 /* Other symbols. */
4666 Lisp_Object Qlaplace
;
4668 /* Time in seconds after which images should be removed from the cache
4669 if not displayed. */
4671 Lisp_Object Vimage_cache_eviction_delay
;
4673 /* Function prototypes. */
4675 static void define_image_type
P_ ((struct image_type
*type
));
4676 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4677 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4678 static void x_laplace
P_ ((struct frame
*, struct image
*));
4679 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4683 /* Define a new image type from TYPE. This adds a copy of TYPE to
4684 image_types and adds the symbol *TYPE->type to Vimage_types. */
4687 define_image_type (type
)
4688 struct image_type
*type
;
4690 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4691 The initialized data segment is read-only. */
4692 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4693 bcopy (type
, p
, sizeof *p
);
4694 p
->next
= image_types
;
4696 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4700 /* Look up image type SYMBOL, and return a pointer to its image_type
4701 structure. Value is null if SYMBOL is not a known image type. */
4703 static INLINE
struct image_type
*
4704 lookup_image_type (symbol
)
4707 struct image_type
*type
;
4709 for (type
= image_types
; type
; type
= type
->next
)
4710 if (EQ (symbol
, *type
->type
))
4717 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4718 valid image specification is a list whose car is the symbol
4719 `image', and whose rest is a property list. The property list must
4720 contain a value for key `:type'. That value must be the name of a
4721 supported image type. The rest of the property list depends on the
4725 valid_image_p (object
)
4730 if (CONSP (object
) && EQ (XCAR (object
), Qimage
))
4732 Lisp_Object symbol
= Fplist_get (XCDR (object
), QCtype
);
4733 struct image_type
*type
= lookup_image_type (symbol
);
4736 valid_p
= type
->valid_p (object
);
4743 /* Log error message with format string FORMAT and argument ARG.
4744 Signaling an error, e.g. when an image cannot be loaded, is not a
4745 good idea because this would interrupt redisplay, and the error
4746 message display would lead to another redisplay. This function
4747 therefore simply displays a message. */
4750 image_error (format
, arg1
, arg2
)
4752 Lisp_Object arg1
, arg2
;
4754 add_to_log (format
, arg1
, arg2
);
4759 /***********************************************************************
4760 Image specifications
4761 ***********************************************************************/
4763 enum image_value_type
4765 IMAGE_DONT_CHECK_VALUE_TYPE
,
4768 IMAGE_POSITIVE_INTEGER_VALUE
,
4769 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4770 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4772 IMAGE_INTEGER_VALUE
,
4773 IMAGE_FUNCTION_VALUE
,
4778 /* Structure used when parsing image specifications. */
4780 struct image_keyword
4782 /* Name of keyword. */
4785 /* The type of value allowed. */
4786 enum image_value_type type
;
4788 /* Non-zero means key must be present. */
4791 /* Used to recognize duplicate keywords in a property list. */
4794 /* The value that was found. */
4799 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4801 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4804 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4805 has the format (image KEYWORD VALUE ...). One of the keyword/
4806 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4807 image_keywords structures of size NKEYWORDS describing other
4808 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4811 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4813 struct image_keyword
*keywords
;
4820 if (!CONSP (spec
) || !EQ (XCAR (spec
), Qimage
))
4823 plist
= XCDR (spec
);
4824 while (CONSP (plist
))
4826 Lisp_Object key
, value
;
4828 /* First element of a pair must be a symbol. */
4830 plist
= XCDR (plist
);
4834 /* There must follow a value. */
4837 value
= XCAR (plist
);
4838 plist
= XCDR (plist
);
4840 /* Find key in KEYWORDS. Error if not found. */
4841 for (i
= 0; i
< nkeywords
; ++i
)
4842 if (strcmp (keywords
[i
].name
, XSTRING (SYMBOL_NAME (key
))->data
) == 0)
4848 /* Record that we recognized the keyword. If a keywords
4849 was found more than once, it's an error. */
4850 keywords
[i
].value
= value
;
4851 ++keywords
[i
].count
;
4853 if (keywords
[i
].count
> 1)
4856 /* Check type of value against allowed type. */
4857 switch (keywords
[i
].type
)
4859 case IMAGE_STRING_VALUE
:
4860 if (!STRINGP (value
))
4864 case IMAGE_SYMBOL_VALUE
:
4865 if (!SYMBOLP (value
))
4869 case IMAGE_POSITIVE_INTEGER_VALUE
:
4870 if (!INTEGERP (value
) || XINT (value
) <= 0)
4874 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4875 if (INTEGERP (value
) && XINT (value
) >= 0)
4878 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4879 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4883 case IMAGE_ASCENT_VALUE
:
4884 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4886 else if (INTEGERP (value
)
4887 && XINT (value
) >= 0
4888 && XINT (value
) <= 100)
4892 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4893 if (!INTEGERP (value
) || XINT (value
) < 0)
4897 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4900 case IMAGE_FUNCTION_VALUE
:
4901 value
= indirect_function (value
);
4903 || COMPILEDP (value
)
4904 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4908 case IMAGE_NUMBER_VALUE
:
4909 if (!INTEGERP (value
) && !FLOATP (value
))
4913 case IMAGE_INTEGER_VALUE
:
4914 if (!INTEGERP (value
))
4918 case IMAGE_BOOL_VALUE
:
4919 if (!NILP (value
) && !EQ (value
, Qt
))
4928 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4932 /* Check that all mandatory fields are present. */
4933 for (i
= 0; i
< nkeywords
; ++i
)
4934 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4937 return NILP (plist
);
4941 /* Return the value of KEY in image specification SPEC. Value is nil
4942 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4943 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4946 image_spec_value (spec
, key
, found
)
4947 Lisp_Object spec
, key
;
4952 xassert (valid_image_p (spec
));
4954 for (tail
= XCDR (spec
);
4955 CONSP (tail
) && CONSP (XCDR (tail
));
4956 tail
= XCDR (XCDR (tail
)))
4958 if (EQ (XCAR (tail
), key
))
4962 return XCAR (XCDR (tail
));
4974 /***********************************************************************
4975 Image type independent image structures
4976 ***********************************************************************/
4978 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4979 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4982 /* Allocate and return a new image structure for image specification
4983 SPEC. SPEC has a hash value of HASH. */
4985 static struct image
*
4986 make_image (spec
, hash
)
4990 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4992 xassert (valid_image_p (spec
));
4993 bzero (img
, sizeof *img
);
4994 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4995 xassert (img
->type
!= NULL
);
4997 img
->data
.lisp_val
= Qnil
;
4998 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
5004 /* Free image IMG which was used on frame F, including its resources. */
5013 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5015 /* Remove IMG from the hash table of its cache. */
5017 img
->prev
->next
= img
->next
;
5019 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
5022 img
->next
->prev
= img
->prev
;
5024 c
->images
[img
->id
] = NULL
;
5026 /* Free resources, then free IMG. */
5027 img
->type
->free (f
, img
);
5033 /* Prepare image IMG for display on frame F. Must be called before
5034 drawing an image. */
5037 prepare_image_for_display (f
, img
)
5043 /* We're about to display IMG, so set its timestamp to `now'. */
5045 img
->timestamp
= EMACS_SECS (t
);
5047 /* If IMG doesn't have a pixmap yet, load it now, using the image
5048 type dependent loader function. */
5049 if (img
->pixmap
== 0 && !img
->load_failed_p
)
5050 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5054 /* Value is the number of pixels for the ascent of image IMG when
5055 drawn in face FACE. */
5058 image_ascent (img
, face
)
5062 int height
= img
->height
+ img
->vmargin
;
5065 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
5068 ascent
= height
/ 2 - (FONT_DESCENT(face
->font
)
5069 - FONT_BASE(face
->font
)) / 2;
5071 ascent
= height
/ 2;
5074 ascent
= height
* img
->ascent
/ 100.0;
5081 /***********************************************************************
5082 Helper functions for X image types
5083 ***********************************************************************/
5085 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
5086 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
5088 Lisp_Object color_name
,
5089 unsigned long dflt
));
5091 /* Free X resources of image IMG which is used on frame F. */
5094 x_clear_image (f
, img
)
5098 #if 0 /* MAC_TODO: W32 image support */
5103 XFreePixmap (NULL
, img
->pixmap
);
5110 int class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
5112 /* If display has an immutable color map, freeing colors is not
5113 necessary and some servers don't allow it. So don't do it. */
5114 if (class != StaticColor
5115 && class != StaticGray
5116 && class != TrueColor
)
5120 cmap
= DefaultColormapOfScreen (FRAME_W32_DISPLAY_INFO (f
)->screen
);
5121 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
, img
->colors
,
5126 xfree (img
->colors
);
5130 #endif /* MAC_TODO */
5134 /* Allocate color COLOR_NAME for image IMG on frame F. If color
5135 cannot be allocated, use DFLT. Add a newly allocated color to
5136 IMG->colors, so that it can be freed again. Value is the pixel
5139 static unsigned long
5140 x_alloc_image_color (f
, img
, color_name
, dflt
)
5143 Lisp_Object color_name
;
5146 #if 0 /* MAC_TODO: allocing colors. */
5148 unsigned long result
;
5150 xassert (STRINGP (color_name
));
5152 if (w32_defined_color (f
, XSTRING (color_name
)->data
, &color
, 1))
5154 /* This isn't called frequently so we get away with simply
5155 reallocating the color vector to the needed size, here. */
5158 (unsigned long *) xrealloc (img
->colors
,
5159 img
->ncolors
* sizeof *img
->colors
);
5160 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
5161 result
= color
.pixel
;
5166 #endif /* MAC_TODO */
5172 /***********************************************************************
5174 ***********************************************************************/
5176 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
5179 /* Return a new, initialized image cache that is allocated from the
5180 heap. Call free_image_cache to free an image cache. */
5182 struct image_cache
*
5185 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
5188 bzero (c
, sizeof *c
);
5190 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
5191 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
5192 c
->buckets
= (struct image
**) xmalloc (size
);
5193 bzero (c
->buckets
, size
);
5198 /* Free image cache of frame F. Be aware that X frames share images
5202 free_image_cache (f
)
5205 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5210 /* Cache should not be referenced by any frame when freed. */
5211 xassert (c
->refcount
== 0);
5213 for (i
= 0; i
< c
->used
; ++i
)
5214 free_image (f
, c
->images
[i
]);
5218 FRAME_X_IMAGE_CACHE (f
) = NULL
;
5223 /* Clear image cache of frame F. FORCE_P non-zero means free all
5224 images. FORCE_P zero means clear only images that haven't been
5225 displayed for some time. Should be called from time to time to
5226 reduce the number of loaded images. If image-eviction-seconds is
5227 non-nil, this frees images in the cache which weren't displayed for
5228 at least that many seconds. */
5231 clear_image_cache (f
, force_p
)
5235 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5237 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
5241 int i
, any_freed_p
= 0;
5244 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
5246 for (i
= 0; i
< c
->used
; ++i
)
5248 struct image
*img
= c
->images
[i
];
5251 || (img
->timestamp
> old
)))
5253 free_image (f
, img
);
5258 /* We may be clearing the image cache because, for example,
5259 Emacs was iconified for a longer period of time. In that
5260 case, current matrices may still contain references to
5261 images freed above. So, clear these matrices. */
5264 clear_current_matrices (f
);
5265 ++windows_or_buffers_changed
;
5271 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
5273 doc
: /* Clear the image cache of FRAME.
5274 FRAME nil or omitted means use the selected frame.
5275 FRAME t means clear the image caches of all frames. */)
5283 FOR_EACH_FRAME (tail
, frame
)
5284 if (FRAME_MAC_P (XFRAME (frame
)))
5285 clear_image_cache (XFRAME (frame
), 1);
5288 clear_image_cache (check_x_frame (frame
), 1);
5294 /* Return the id of image with Lisp specification SPEC on frame F.
5295 SPEC must be a valid Lisp image specification (see valid_image_p). */
5298 lookup_image (f
, spec
)
5302 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5306 struct gcpro gcpro1
;
5309 /* F must be a window-system frame, and SPEC must be a valid image
5311 xassert (FRAME_WINDOW_P (f
));
5312 xassert (valid_image_p (spec
));
5316 /* Look up SPEC in the hash table of the image cache. */
5317 hash
= sxhash (spec
, 0);
5318 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5320 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5321 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5324 /* If not found, create a new image and cache it. */
5328 img
= make_image (spec
, hash
);
5329 cache_image (f
, img
);
5330 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5331 xassert (!interrupt_input_blocked
);
5333 /* If we can't load the image, and we don't have a width and
5334 height, use some arbitrary width and height so that we can
5335 draw a rectangle for it. */
5336 if (img
->load_failed_p
)
5340 value
= image_spec_value (spec
, QCwidth
, NULL
);
5341 img
->width
= (INTEGERP (value
)
5342 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5343 value
= image_spec_value (spec
, QCheight
, NULL
);
5344 img
->height
= (INTEGERP (value
)
5345 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5349 /* Handle image type independent image attributes
5350 `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF'. */
5351 Lisp_Object ascent
, margin
, relief
;
5353 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5354 if (INTEGERP (ascent
))
5355 img
->ascent
= XFASTINT (ascent
);
5356 else if (EQ (ascent
, Qcenter
))
5357 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5359 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5360 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5361 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5362 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5363 && INTEGERP (XCDR (margin
)))
5365 if (XINT (XCAR (margin
)) > 0)
5366 img
->hmargin
= XFASTINT (XCAR (margin
));
5367 if (XINT (XCDR (margin
)) > 0)
5368 img
->vmargin
= XFASTINT (XCDR (margin
));
5371 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5372 if (INTEGERP (relief
))
5374 img
->relief
= XINT (relief
);
5375 img
->hmargin
+= abs (img
->relief
);
5376 img
->vmargin
+= abs (img
->relief
);
5381 /* We're using IMG, so set its timestamp to `now'. */
5382 EMACS_GET_TIME (now
);
5383 img
->timestamp
= EMACS_SECS (now
);
5387 /* Value is the image id. */
5392 /* Cache image IMG in the image cache of frame F. */
5395 cache_image (f
, img
)
5399 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5402 /* Find a free slot in c->images. */
5403 for (i
= 0; i
< c
->used
; ++i
)
5404 if (c
->images
[i
] == NULL
)
5407 /* If no free slot found, maybe enlarge c->images. */
5408 if (i
== c
->used
&& c
->used
== c
->size
)
5411 c
->images
= (struct image
**) xrealloc (c
->images
,
5412 c
->size
* sizeof *c
->images
);
5415 /* Add IMG to c->images, and assign IMG an id. */
5421 /* Add IMG to the cache's hash table. */
5422 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5423 img
->next
= c
->buckets
[i
];
5425 img
->next
->prev
= img
;
5427 c
->buckets
[i
] = img
;
5431 /* Call FN on every image in the image cache of frame F. Used to mark
5432 Lisp Objects in the image cache. */
5435 forall_images_in_image_cache (f
, fn
)
5437 void (*fn
) P_ ((struct image
*img
));
5439 if (FRAME_LIVE_P (f
) && FRAME_MAC_P (f
))
5441 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5445 for (i
= 0; i
< c
->used
; ++i
)
5454 /***********************************************************************
5456 ***********************************************************************/
5458 #if 0 /* MAC_TODO: Mac specific image code. */
5460 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5461 XImage
**, Pixmap
*));
5462 static void x_destroy_x_image
P_ ((XImage
*));
5463 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5466 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5467 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5468 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5469 via xmalloc. Print error messages via image_error if an error
5470 occurs. Value is non-zero if successful. */
5473 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5475 int width
, height
, depth
;
5479 #if 0 /* MAC_TODO: Image support for Mac */
5480 Display
*display
= FRAME_W32_DISPLAY (f
);
5481 Screen
*screen
= FRAME_X_SCREEN (f
);
5482 Window window
= FRAME_W32_WINDOW (f
);
5484 xassert (interrupt_input_blocked
);
5487 depth
= DefaultDepthOfScreen (screen
);
5488 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5489 depth
, ZPixmap
, 0, NULL
, width
, height
,
5490 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5493 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5497 /* Allocate image raster. */
5498 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5500 /* Allocate a pixmap of the same size. */
5501 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5504 x_destroy_x_image (*ximg
);
5506 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5509 #endif /* MAC_TODO */
5514 /* Destroy XImage XIMG. Free XIMG->data. */
5517 x_destroy_x_image (ximg
)
5520 xassert (interrupt_input_blocked
);
5525 XDestroyImage (ximg
);
5530 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5531 are width and height of both the image and pixmap. */
5534 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5541 xassert (interrupt_input_blocked
);
5542 gc
= XCreateGC (NULL
, pixmap
, 0, NULL
);
5543 XPutImage (NULL
, pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5547 #endif /* MAC_TODO */
5550 /***********************************************************************
5552 ***********************************************************************/
5554 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5556 /* Find image file FILE. Look in data-directory, then
5557 x-bitmap-file-path. Value is the full name of the file found, or
5558 nil if not found. */
5561 x_find_image_file (file
)
5564 Lisp_Object file_found
, search_path
;
5565 struct gcpro gcpro1
, gcpro2
;
5569 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5570 GCPRO2 (file_found
, search_path
);
5572 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5573 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5585 /***********************************************************************
5587 ***********************************************************************/
5589 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5590 static int xbm_load_image_from_file
P_ ((struct frame
*f
, struct image
*img
,
5592 static int xbm_image_p
P_ ((Lisp_Object object
));
5593 static int xbm_read_bitmap_file_data
P_ ((char *, int *, int *,
5597 /* Indices of image specification fields in xbm_format, below. */
5599 enum xbm_keyword_index
5616 /* Vector of image_keyword structures describing the format
5617 of valid XBM image specifications. */
5619 static struct image_keyword xbm_format
[XBM_LAST
] =
5621 {":type", IMAGE_SYMBOL_VALUE
, 1},
5622 {":file", IMAGE_STRING_VALUE
, 0},
5623 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5624 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5625 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5626 {":foreground", IMAGE_STRING_VALUE
, 0},
5627 {":background", IMAGE_STRING_VALUE
, 0},
5628 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
5629 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5630 {":relief", IMAGE_INTEGER_VALUE
, 0},
5631 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5632 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5635 /* Structure describing the image type XBM. */
5637 static struct image_type xbm_type
=
5646 /* Tokens returned from xbm_scan. */
5655 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5656 A valid specification is a list starting with the symbol `image'
5657 The rest of the list is a property list which must contain an
5660 If the specification specifies a file to load, it must contain
5661 an entry `:file FILENAME' where FILENAME is a string.
5663 If the specification is for a bitmap loaded from memory it must
5664 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5665 WIDTH and HEIGHT are integers > 0. DATA may be:
5667 1. a string large enough to hold the bitmap data, i.e. it must
5668 have a size >= (WIDTH + 7) / 8 * HEIGHT
5670 2. a bool-vector of size >= WIDTH * HEIGHT
5672 3. a vector of strings or bool-vectors, one for each line of the
5675 Both the file and data forms may contain the additional entries
5676 `:background COLOR' and `:foreground COLOR'. If not present,
5677 foreground and background of the frame on which the image is
5678 displayed, is used. */
5681 xbm_image_p (object
)
5684 struct image_keyword kw
[XBM_LAST
];
5686 bcopy (xbm_format
, kw
, sizeof kw
);
5687 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5690 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5692 if (kw
[XBM_FILE
].count
)
5694 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5702 /* Entries for `:width', `:height' and `:data' must be present. */
5703 if (!kw
[XBM_WIDTH
].count
5704 || !kw
[XBM_HEIGHT
].count
5705 || !kw
[XBM_DATA
].count
)
5708 data
= kw
[XBM_DATA
].value
;
5709 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5710 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5712 /* Check type of data, and width and height against contents of
5718 /* Number of elements of the vector must be >= height. */
5719 if (XVECTOR (data
)->size
< height
)
5722 /* Each string or bool-vector in data must be large enough
5723 for one line of the image. */
5724 for (i
= 0; i
< height
; ++i
)
5726 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5730 if (XSTRING (elt
)->size
5731 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5734 else if (BOOL_VECTOR_P (elt
))
5736 if (XBOOL_VECTOR (elt
)->size
< width
)
5743 else if (STRINGP (data
))
5745 if (XSTRING (data
)->size
5746 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5749 else if (BOOL_VECTOR_P (data
))
5751 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5758 /* Baseline must be a value between 0 and 100 (a percentage). */
5759 if (kw
[XBM_ASCENT
].count
5760 && XFASTINT (kw
[XBM_ASCENT
].value
) > 100)
5767 /* Scan a bitmap file. FP is the stream to read from. Value is
5768 either an enumerator from enum xbm_token, or a character for a
5769 single-character token, or 0 at end of file. If scanning an
5770 identifier, store the lexeme of the identifier in SVAL. If
5771 scanning a number, store its value in *IVAL. */
5774 xbm_scan (fp
, sval
, ival
)
5781 /* Skip white space. */
5782 while ((c
= fgetc (fp
)) != EOF
&& isspace (c
))
5787 else if (isdigit (c
))
5789 int value
= 0, digit
;
5794 if (c
== 'x' || c
== 'X')
5796 while ((c
= fgetc (fp
)) != EOF
)
5800 else if (c
>= 'a' && c
<= 'f')
5801 digit
= c
- 'a' + 10;
5802 else if (c
>= 'A' && c
<= 'F')
5803 digit
= c
- 'A' + 10;
5806 value
= 16 * value
+ digit
;
5809 else if (isdigit (c
))
5812 while ((c
= fgetc (fp
)) != EOF
5814 value
= 8 * value
+ c
- '0';
5820 while ((c
= fgetc (fp
)) != EOF
5822 value
= 10 * value
+ c
- '0';
5830 else if (isalpha (c
) || c
== '_')
5833 while ((c
= fgetc (fp
)) != EOF
5834 && (isalnum (c
) || c
== '_'))
5846 /* Replacement for XReadBitmapFileData which isn't available under old
5847 X versions. FILE is the name of the bitmap file to read. Set
5848 *WIDTH and *HEIGHT to the width and height of the image. Return in
5849 *DATA the bitmap data allocated with xmalloc. Value is non-zero if
5853 xbm_read_bitmap_file_data (file
, width
, height
, data
)
5855 int *width
, *height
;
5856 unsigned char **data
;
5859 char buffer
[BUFSIZ
];
5862 int bytes_per_line
, i
, nbytes
;
5868 LA1 = xbm_scan (fp, buffer, &value)
5870 #define expect(TOKEN) \
5871 if (LA1 != (TOKEN)) \
5876 #define expect_ident(IDENT) \
5877 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
5882 fp
= fopen (file
, "r");
5886 *width
= *height
= -1;
5888 LA1
= xbm_scan (fp
, buffer
, &value
);
5890 /* Parse defines for width, height and hot-spots. */
5894 expect_ident ("define");
5895 expect (XBM_TK_IDENT
);
5897 if (LA1
== XBM_TK_NUMBER
);
5899 char *p
= strrchr (buffer
, '_');
5900 p
= p
? p
+ 1 : buffer
;
5901 if (strcmp (p
, "width") == 0)
5903 else if (strcmp (p
, "height") == 0)
5906 expect (XBM_TK_NUMBER
);
5909 if (*width
< 0 || *height
< 0)
5912 /* Parse bits. Must start with `static'. */
5913 expect_ident ("static");
5914 if (LA1
== XBM_TK_IDENT
)
5916 if (strcmp (buffer
, "unsigned") == 0)
5919 expect_ident ("char");
5921 else if (strcmp (buffer
, "short") == 0)
5925 if (*width
% 16 && *width
% 16 < 9)
5928 else if (strcmp (buffer
, "char") == 0)
5936 expect (XBM_TK_IDENT
);
5942 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
5943 nbytes
= bytes_per_line
* *height
;
5944 p
= *data
= (char *) xmalloc (nbytes
);
5949 for (i
= 0; i
< nbytes
; i
+= 2)
5952 expect (XBM_TK_NUMBER
);
5955 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
5958 if (LA1
== ',' || LA1
== '}')
5966 for (i
= 0; i
< nbytes
; ++i
)
5969 expect (XBM_TK_NUMBER
);
5973 if (LA1
== ',' || LA1
== '}')
5999 /* Load XBM image IMG which will be displayed on frame F from file
6000 SPECIFIED_FILE. Value is non-zero if successful. */
6003 xbm_load_image_from_file (f
, img
, specified_file
)
6006 Lisp_Object specified_file
;
6009 unsigned char *data
;
6012 struct gcpro gcpro1
;
6014 xassert (STRINGP (specified_file
));
6018 file
= x_find_image_file (specified_file
);
6019 if (!STRINGP (file
))
6021 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6026 rc
= xbm_read_bitmap_file_data (XSTRING (file
)->data
, &img
->width
,
6027 &img
->height
, &data
);
6030 int depth
= one_mac_display_info
.n_cbits
;
6031 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6032 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6035 xassert (img
->width
> 0 && img
->height
> 0);
6037 /* Get foreground and background colors, maybe allocate colors. */
6038 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
6040 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
6042 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
6044 background
= x_alloc_image_color (f
, img
, value
, background
);
6046 #if 0 /* MAC_TODO : Port image display to Mac */
6049 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
6050 FRAME_W32_WINDOW (f
),
6052 img
->width
, img
->height
,
6053 foreground
, background
,
6057 if (img
->pixmap
== 0)
6059 x_clear_image (f
, img
);
6060 image_error ("Unable to create X pixmap for `%s'", file
, Qnil
);
6066 #endif /* MAC_TODO */
6069 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6076 /* Fill image IMG which is used on frame F with pixmap data. Value is
6077 non-zero if successful. */
6085 Lisp_Object file_name
;
6087 xassert (xbm_image_p (img
->spec
));
6089 /* If IMG->spec specifies a file name, create a non-file spec from it. */
6090 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
6091 if (STRINGP (file_name
))
6092 success_p
= xbm_load_image_from_file (f
, img
, file_name
);
6095 struct image_keyword fmt
[XBM_LAST
];
6098 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6099 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6103 /* Parse the list specification. */
6104 bcopy (xbm_format
, fmt
, sizeof fmt
);
6105 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
6108 /* Get specified width, and height. */
6109 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
6110 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
6111 xassert (img
->width
> 0 && img
->height
> 0);
6115 if (fmt
[XBM_ASCENT
].count
)
6116 img
->ascent
= XFASTINT (fmt
[XBM_ASCENT
].value
);
6118 /* Get foreground and background colors, maybe allocate colors. */
6119 if (fmt
[XBM_FOREGROUND
].count
)
6120 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
6122 if (fmt
[XBM_BACKGROUND
].count
)
6123 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
6126 /* Set bits to the bitmap image data. */
6127 data
= fmt
[XBM_DATA
].value
;
6132 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
6134 p
= bits
= (char *) alloca (nbytes
* img
->height
);
6135 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
6137 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
6139 bcopy (XSTRING (line
)->data
, p
, nbytes
);
6141 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
6144 else if (STRINGP (data
))
6145 bits
= XSTRING (data
)->data
;
6147 bits
= XBOOL_VECTOR (data
)->data
;
6149 #if 0 /* MAC_TODO : port Mac display code */
6150 /* Create the pixmap. */
6151 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6153 = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f
),
6154 FRAME_W32_WINDOW (f
),
6156 img
->width
, img
->height
,
6157 foreground
, background
,
6159 #endif /* MAC_TODO */
6165 image_error ("Unable to create pixmap for XBM image `%s'",
6167 x_clear_image (f
, img
);
6178 /***********************************************************************
6180 ***********************************************************************/
6184 static int xpm_image_p
P_ ((Lisp_Object object
));
6185 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6186 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6188 #include "X11/xpm.h"
6190 /* The symbol `xpm' identifying XPM-format images. */
6194 /* Indices of image specification fields in xpm_format, below. */
6196 enum xpm_keyword_index
6210 /* Vector of image_keyword structures describing the format
6211 of valid XPM image specifications. */
6213 static struct image_keyword xpm_format
[XPM_LAST
] =
6215 {":type", IMAGE_SYMBOL_VALUE
, 1},
6216 {":file", IMAGE_STRING_VALUE
, 0},
6217 {":data", IMAGE_STRING_VALUE
, 0},
6218 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6219 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6220 {":relief", IMAGE_INTEGER_VALUE
, 0},
6221 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6222 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6223 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6226 /* Structure describing the image type XBM. */
6228 static struct image_type xpm_type
=
6238 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6239 for XPM images. Such a list must consist of conses whose car and
6243 xpm_valid_color_symbols_p (color_symbols
)
6244 Lisp_Object color_symbols
;
6246 while (CONSP (color_symbols
))
6248 Lisp_Object sym
= XCAR (color_symbols
);
6250 || !STRINGP (XCAR (sym
))
6251 || !STRINGP (XCDR (sym
)))
6253 color_symbols
= XCDR (color_symbols
);
6256 return NILP (color_symbols
);
6260 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6263 xpm_image_p (object
)
6266 struct image_keyword fmt
[XPM_LAST
];
6267 bcopy (xpm_format
, fmt
, sizeof fmt
);
6268 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6269 /* Either `:file' or `:data' must be present. */
6270 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6271 /* Either no `:color-symbols' or it's a list of conses
6272 whose car and cdr are strings. */
6273 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6274 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
))
6275 && (fmt
[XPM_ASCENT
].count
== 0
6276 || XFASTINT (fmt
[XPM_ASCENT
].value
) < 100));
6280 /* Load image IMG which will be displayed on frame F. Value is
6281 non-zero if successful. */
6289 XpmAttributes attrs
;
6290 Lisp_Object specified_file
, color_symbols
;
6292 /* Configure the XPM lib. Use the visual of frame F. Allocate
6293 close colors. Return colors allocated. */
6294 bzero (&attrs
, sizeof attrs
);
6295 attrs
.visual
= FRAME_X_VISUAL (f
);
6296 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6297 attrs
.valuemask
|= XpmVisual
;
6298 attrs
.valuemask
|= XpmColormap
;
6299 attrs
.valuemask
|= XpmReturnAllocPixels
;
6300 #ifdef XpmAllocCloseColors
6301 attrs
.alloc_close_colors
= 1;
6302 attrs
.valuemask
|= XpmAllocCloseColors
;
6304 attrs
.closeness
= 600;
6305 attrs
.valuemask
|= XpmCloseness
;
6308 /* If image specification contains symbolic color definitions, add
6309 these to `attrs'. */
6310 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6311 if (CONSP (color_symbols
))
6314 XpmColorSymbol
*xpm_syms
;
6317 attrs
.valuemask
|= XpmColorSymbols
;
6319 /* Count number of symbols. */
6320 attrs
.numsymbols
= 0;
6321 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6324 /* Allocate an XpmColorSymbol array. */
6325 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6326 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6327 bzero (xpm_syms
, size
);
6328 attrs
.colorsymbols
= xpm_syms
;
6330 /* Fill the color symbol array. */
6331 for (tail
= color_symbols
, i
= 0;
6333 ++i
, tail
= XCDR (tail
))
6335 Lisp_Object name
= XCAR (XCAR (tail
));
6336 Lisp_Object color
= XCDR (XCAR (tail
));
6337 xpm_syms
[i
].name
= (char *) alloca (XSTRING (name
)->size
+ 1);
6338 strcpy (xpm_syms
[i
].name
, XSTRING (name
)->data
);
6339 xpm_syms
[i
].value
= (char *) alloca (XSTRING (color
)->size
+ 1);
6340 strcpy (xpm_syms
[i
].value
, XSTRING (color
)->data
);
6344 /* Create a pixmap for the image, either from a file, or from a
6345 string buffer containing data in the same format as an XPM file. */
6347 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6348 if (STRINGP (specified_file
))
6350 Lisp_Object file
= x_find_image_file (specified_file
);
6351 if (!STRINGP (file
))
6353 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6358 rc
= XpmReadFileToPixmap (NULL
, FRAME_W32_WINDOW (f
),
6359 XSTRING (file
)->data
, &img
->pixmap
, &img
->mask
,
6364 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6365 rc
= XpmCreatePixmapFromBuffer (NULL
, FRAME_W32_WINDOW (f
),
6366 XSTRING (buffer
)->data
,
6367 &img
->pixmap
, &img
->mask
,
6372 if (rc
== XpmSuccess
)
6374 /* Remember allocated colors. */
6375 img
->ncolors
= attrs
.nalloc_pixels
;
6376 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6377 * sizeof *img
->colors
);
6378 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6379 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6381 img
->width
= attrs
.width
;
6382 img
->height
= attrs
.height
;
6383 xassert (img
->width
> 0 && img
->height
> 0);
6385 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6387 XpmFreeAttributes (&attrs
);
6395 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6398 case XpmFileInvalid
:
6399 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6403 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6406 case XpmColorFailed
:
6407 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6411 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6416 return rc
== XpmSuccess
;
6419 #endif /* HAVE_XPM != 0 */
6422 #if 0 /* MAC_TODO : Color tables on Mac. */
6423 /***********************************************************************
6425 ***********************************************************************/
6427 /* An entry in the color table mapping an RGB color to a pixel color. */
6432 unsigned long pixel
;
6434 /* Next in color table collision list. */
6435 struct ct_color
*next
;
6438 /* The bucket vector size to use. Must be prime. */
6442 /* Value is a hash of the RGB color given by R, G, and B. */
6444 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6446 /* The color hash table. */
6448 struct ct_color
**ct_table
;
6450 /* Number of entries in the color table. */
6452 int ct_colors_allocated
;
6454 /* Function prototypes. */
6456 static void init_color_table
P_ ((void));
6457 static void free_color_table
P_ ((void));
6458 static unsigned long *colors_in_color_table
P_ ((int *n
));
6459 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
6460 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
6463 /* Initialize the color table. */
6468 int size
= CT_SIZE
* sizeof (*ct_table
);
6469 ct_table
= (struct ct_color
**) xmalloc (size
);
6470 bzero (ct_table
, size
);
6471 ct_colors_allocated
= 0;
6475 /* Free memory associated with the color table. */
6481 struct ct_color
*p
, *next
;
6483 for (i
= 0; i
< CT_SIZE
; ++i
)
6484 for (p
= ct_table
[i
]; p
; p
= next
)
6495 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6496 entry for that color already is in the color table, return the
6497 pixel color of that entry. Otherwise, allocate a new color for R,
6498 G, B, and make an entry in the color table. */
6500 static unsigned long
6501 lookup_rgb_color (f
, r
, g
, b
)
6505 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6506 int i
= hash
% CT_SIZE
;
6509 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6510 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6519 color
= RGB_TO_ULONG (r
, g
, b
);
6521 ++ct_colors_allocated
;
6523 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6528 p
->next
= ct_table
[i
];
6536 /* Look up pixel color PIXEL which is used on frame F in the color
6537 table. If not already present, allocate it. Value is PIXEL. */
6539 static unsigned long
6540 lookup_pixel_color (f
, pixel
)
6542 unsigned long pixel
;
6544 int i
= pixel
% CT_SIZE
;
6547 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6548 if (p
->pixel
== pixel
)
6559 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6560 color
.pixel
= pixel
;
6561 XQueryColor (NULL
, cmap
, &color
);
6562 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6567 ++ct_colors_allocated
;
6569 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6574 p
->next
= ct_table
[i
];
6578 return FRAME_FOREGROUND_PIXEL (f
);
6584 /* Value is a vector of all pixel colors contained in the color table,
6585 allocated via xmalloc. Set *N to the number of colors. */
6587 static unsigned long *
6588 colors_in_color_table (n
)
6593 unsigned long *colors
;
6595 if (ct_colors_allocated
== 0)
6602 colors
= (unsigned long *) xmalloc (ct_colors_allocated
6604 *n
= ct_colors_allocated
;
6606 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
6607 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6608 colors
[j
++] = p
->pixel
;
6614 #endif /* MAC_TODO */
6617 /***********************************************************************
6619 ***********************************************************************/
6621 #if 0 /* MAC_TODO : Mac versions of low level algorithms */
6622 static void x_laplace_write_row
P_ ((struct frame
*, long *,
6623 int, XImage
*, int));
6624 static void x_laplace_read_row
P_ ((struct frame
*, Colormap
,
6625 XColor
*, int, XImage
*, int));
6628 /* Fill COLORS with RGB colors from row Y of image XIMG. F is the
6629 frame we operate on, CMAP is the color-map in effect, and WIDTH is
6630 the width of one row in the image. */
6633 x_laplace_read_row (f
, cmap
, colors
, width
, ximg
, y
)
6643 for (x
= 0; x
< width
; ++x
)
6644 colors
[x
].pixel
= XGetPixel (ximg
, x
, y
);
6646 XQueryColors (NULL
, cmap
, colors
, width
);
6650 /* Write row Y of image XIMG. PIXELS is an array of WIDTH longs
6651 containing the pixel colors to write. F is the frame we are
6655 x_laplace_write_row (f
, pixels
, width
, ximg
, y
)
6664 for (x
= 0; x
< width
; ++x
)
6665 XPutPixel (ximg
, x
, y
, pixels
[x
]);
6667 #endif /* MAC_TODO */
6669 /* Transform image IMG which is used on frame F with a Laplace
6670 edge-detection algorithm. The result is an image that can be used
6671 to draw disabled buttons, for example. */
6678 #if 0 /* MAC_TODO : Mac version */
6679 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6680 XImage
*ximg
, *oimg
;
6686 int in_y
, out_y
, rc
;
6691 /* Get the X image IMG->pixmap. */
6692 ximg
= XGetImage (NULL
, img
->pixmap
,
6693 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
6695 /* Allocate 3 input rows, and one output row of colors. */
6696 for (i
= 0; i
< 3; ++i
)
6697 in
[i
] = (XColor
*) alloca (img
->width
* sizeof (XColor
));
6698 out
= (long *) alloca (img
->width
* sizeof (long));
6700 /* Create an X image for output. */
6701 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
6704 /* Fill first two rows. */
6705 x_laplace_read_row (f
, cmap
, in
[0], img
->width
, ximg
, 0);
6706 x_laplace_read_row (f
, cmap
, in
[1], img
->width
, ximg
, 1);
6709 /* Write first row, all zeros. */
6710 init_color_table ();
6711 pixel
= lookup_rgb_color (f
, 0, 0, 0);
6712 for (x
= 0; x
< img
->width
; ++x
)
6714 x_laplace_write_row (f
, out
, img
->width
, oimg
, 0);
6717 for (y
= 2; y
< img
->height
; ++y
)
6720 int rowb
= (y
+ 2) % 3;
6722 x_laplace_read_row (f
, cmap
, in
[rowa
], img
->width
, ximg
, in_y
++);
6724 for (x
= 0; x
< img
->width
- 2; ++x
)
6726 int r
= in
[rowa
][x
].red
+ mv2
- in
[rowb
][x
+ 2].red
;
6727 int g
= in
[rowa
][x
].green
+ mv2
- in
[rowb
][x
+ 2].green
;
6728 int b
= in
[rowa
][x
].blue
+ mv2
- in
[rowb
][x
+ 2].blue
;
6730 out
[x
+ 1] = lookup_rgb_color (f
, r
& 0xffff, g
& 0xffff,
6734 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
++);
6737 /* Write last line, all zeros. */
6738 for (x
= 0; x
< img
->width
; ++x
)
6740 x_laplace_write_row (f
, out
, img
->width
, oimg
, out_y
);
6742 /* Free the input image, and free resources of IMG. */
6743 XDestroyImage (ximg
);
6744 x_clear_image (f
, img
);
6746 /* Put the output image into pixmap, and destroy it. */
6747 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
6748 x_destroy_x_image (oimg
);
6750 /* Remember new pixmap and colors in IMG. */
6751 img
->pixmap
= pixmap
;
6752 img
->colors
= colors_in_color_table (&img
->ncolors
);
6753 free_color_table ();
6756 #endif /* MAC_TODO */
6760 /* Build a mask for image IMG which is used on frame F. FILE is the
6761 name of an image file, for error messages. HOW determines how to
6762 determine the background color of IMG. If it is a list '(R G B)',
6763 with R, G, and B being integers >= 0, take that as the color of the
6764 background. Otherwise, determine the background color of IMG
6765 heuristically. Value is non-zero if successful. */
6768 x_build_heuristic_mask (f
, img
, how
)
6773 #if 0 /* MAC_TODO : Mac version */
6774 Display
*dpy
= FRAME_W32_DISPLAY (f
);
6775 XImage
*ximg
, *mask_img
;
6776 int x
, y
, rc
, look_at_corners_p
;
6781 /* Create an image and pixmap serving as mask. */
6782 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
6783 &mask_img
, &img
->mask
);
6790 /* Get the X image of IMG->pixmap. */
6791 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
6794 /* Determine the background color of ximg. If HOW is `(R G B)'
6795 take that as color. Otherwise, try to determine the color
6797 look_at_corners_p
= 1;
6805 && NATNUMP (XCAR (how
)))
6807 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
6811 if (i
== 3 && NILP (how
))
6813 char color_name
[30];
6814 XColor exact
, color
;
6817 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
6819 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
6820 if (XLookupColor (dpy
, cmap
, color_name
, &exact
, &color
))
6823 look_at_corners_p
= 0;
6828 if (look_at_corners_p
)
6830 unsigned long corners
[4];
6833 /* Get the colors at the corners of ximg. */
6834 corners
[0] = XGetPixel (ximg
, 0, 0);
6835 corners
[1] = XGetPixel (ximg
, img
->width
- 1, 0);
6836 corners
[2] = XGetPixel (ximg
, img
->width
- 1, img
->height
- 1);
6837 corners
[3] = XGetPixel (ximg
, 0, img
->height
- 1);
6839 /* Choose the most frequently found color as background. */
6840 for (i
= best_count
= 0; i
< 4; ++i
)
6844 for (j
= n
= 0; j
< 4; ++j
)
6845 if (corners
[i
] == corners
[j
])
6849 bg
= corners
[i
], best_count
= n
;
6853 /* Set all bits in mask_img to 1 whose color in ximg is different
6854 from the background color bg. */
6855 for (y
= 0; y
< img
->height
; ++y
)
6856 for (x
= 0; x
< img
->width
; ++x
)
6857 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
6859 /* Put mask_img into img->mask. */
6860 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
6861 x_destroy_x_image (mask_img
);
6862 XDestroyImage (ximg
);
6865 #endif /* MAC_TODO */
6872 /***********************************************************************
6873 PBM (mono, gray, color)
6874 ***********************************************************************/
6877 static int pbm_image_p
P_ ((Lisp_Object object
));
6878 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
6879 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
6881 /* The symbol `pbm' identifying images of this type. */
6885 /* Indices of image specification fields in gs_format, below. */
6887 enum pbm_keyword_index
6900 /* Vector of image_keyword structures describing the format
6901 of valid user-defined image specifications. */
6903 static struct image_keyword pbm_format
[PBM_LAST
] =
6905 {":type", IMAGE_SYMBOL_VALUE
, 1},
6906 {":file", IMAGE_STRING_VALUE
, 0},
6907 {":data", IMAGE_STRING_VALUE
, 0},
6908 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6909 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6910 {":relief", IMAGE_INTEGER_VALUE
, 0},
6911 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6912 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
6915 /* Structure describing the image type `pbm'. */
6917 static struct image_type pbm_type
=
6927 /* Return non-zero if OBJECT is a valid PBM image specification. */
6930 pbm_image_p (object
)
6933 struct image_keyword fmt
[PBM_LAST
];
6935 bcopy (pbm_format
, fmt
, sizeof fmt
);
6937 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
)
6938 || (fmt
[PBM_ASCENT
].count
6939 && XFASTINT (fmt
[PBM_ASCENT
].value
) > 100))
6942 /* Must specify either :data or :file. */
6943 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
6947 /* Scan a decimal number from *S and return it. Advance *S while
6948 reading the number. END is the end of the string. Value is -1 at
6952 pbm_scan_number (s
, end
)
6953 unsigned char **s
, *end
;
6959 /* Skip white-space. */
6960 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
6965 /* Skip comment to end of line. */
6966 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
6969 else if (isdigit (c
))
6971 /* Read decimal number. */
6973 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
6974 val
= 10 * val
+ c
- '0';
6985 /* Read FILE into memory. Value is a pointer to a buffer allocated
6986 with xmalloc holding FILE's contents. Value is null if an error
6987 occured. *SIZE is set to the size of the file. */
6990 pbm_read_file (file
, size
)
6998 if (stat (XSTRING (file
)->data
, &st
) == 0
6999 && (fp
= fopen (XSTRING (file
)->data
, "r")) != NULL
7000 && (buf
= (char *) xmalloc (st
.st_size
),
7001 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
7021 /* Load PBM image IMG for use on frame F. */
7029 int width
, height
, max_color_idx
= 0;
7031 Lisp_Object file
, specified_file
;
7032 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
7033 struct gcpro gcpro1
;
7034 unsigned char *contents
= NULL
;
7035 unsigned char *end
, *p
;
7038 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7042 if (STRINGP (specified_file
))
7044 file
= x_find_image_file (specified_file
);
7045 if (!STRINGP (file
))
7047 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7052 contents
= pbm_read_file (file
, &size
);
7053 if (contents
== NULL
)
7055 image_error ("Error reading `%s'", file
, Qnil
);
7061 end
= contents
+ size
;
7066 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7067 p
= XSTRING (data
)->data
;
7068 end
= p
+ STRING_BYTES (XSTRING (data
));
7071 /* Check magic number. */
7072 if (end
- p
< 2 || *p
++ != 'P')
7074 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7084 raw_p
= 0, type
= PBM_MONO
;
7088 raw_p
= 0, type
= PBM_GRAY
;
7092 raw_p
= 0, type
= PBM_COLOR
;
7096 raw_p
= 1, type
= PBM_MONO
;
7100 raw_p
= 1, type
= PBM_GRAY
;
7104 raw_p
= 1, type
= PBM_COLOR
;
7108 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7112 /* Read width, height, maximum color-component. Characters
7113 starting with `#' up to the end of a line are ignored. */
7114 width
= pbm_scan_number (&p
, end
);
7115 height
= pbm_scan_number (&p
, end
);
7117 if (type
!= PBM_MONO
)
7119 max_color_idx
= pbm_scan_number (&p
, end
);
7120 if (raw_p
&& max_color_idx
> 255)
7121 max_color_idx
= 255;
7126 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7130 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7131 &ximg
, &img
->pixmap
))
7137 /* Initialize the color hash table. */
7138 init_color_table ();
7140 if (type
== PBM_MONO
)
7144 for (y
= 0; y
< height
; ++y
)
7145 for (x
= 0; x
< width
; ++x
)
7155 g
= pbm_scan_number (&p
, end
);
7157 XPutPixel (ximg
, x
, y
, (g
7158 ? FRAME_FOREGROUND_PIXEL (f
)
7159 : FRAME_BACKGROUND_PIXEL (f
)));
7164 for (y
= 0; y
< height
; ++y
)
7165 for (x
= 0; x
< width
; ++x
)
7169 if (type
== PBM_GRAY
)
7170 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7179 r
= pbm_scan_number (&p
, end
);
7180 g
= pbm_scan_number (&p
, end
);
7181 b
= pbm_scan_number (&p
, end
);
7184 if (r
< 0 || g
< 0 || b
< 0)
7188 XDestroyImage (ximg
);
7190 image_error ("Invalid pixel value in image `%s'",
7195 /* RGB values are now in the range 0..max_color_idx.
7196 Scale this to the range 0..0xffff supported by X. */
7197 r
= (double) r
* 65535 / max_color_idx
;
7198 g
= (double) g
* 65535 / max_color_idx
;
7199 b
= (double) b
* 65535 / max_color_idx
;
7200 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7204 /* Store in IMG->colors the colors allocated for the image, and
7205 free the color table. */
7206 img
->colors
= colors_in_color_table (&img
->ncolors
);
7207 free_color_table ();
7209 /* Put the image into a pixmap. */
7210 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7211 x_destroy_x_image (ximg
);
7215 img
->height
= height
;
7221 #endif /* HAVE_PBM */
7224 /***********************************************************************
7226 ***********************************************************************/
7232 /* Function prototypes. */
7234 static int png_image_p
P_ ((Lisp_Object object
));
7235 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7237 /* The symbol `png' identifying images of this type. */
7241 /* Indices of image specification fields in png_format, below. */
7243 enum png_keyword_index
7256 /* Vector of image_keyword structures describing the format
7257 of valid user-defined image specifications. */
7259 static struct image_keyword png_format
[PNG_LAST
] =
7261 {":type", IMAGE_SYMBOL_VALUE
, 1},
7262 {":data", IMAGE_STRING_VALUE
, 0},
7263 {":file", IMAGE_STRING_VALUE
, 0},
7264 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7265 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7266 {":relief", IMAGE_INTEGER_VALUE
, 0},
7267 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7268 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7271 /* Structure describing the image type `png'. */
7273 static struct image_type png_type
=
7283 /* Return non-zero if OBJECT is a valid PNG image specification. */
7286 png_image_p (object
)
7289 struct image_keyword fmt
[PNG_LAST
];
7290 bcopy (png_format
, fmt
, sizeof fmt
);
7292 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
)
7293 || (fmt
[PNG_ASCENT
].count
7294 && XFASTINT (fmt
[PNG_ASCENT
].value
) > 100))
7297 /* Must specify either the :data or :file keyword. */
7298 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7302 /* Error and warning handlers installed when the PNG library
7306 my_png_error (png_ptr
, msg
)
7307 png_struct
*png_ptr
;
7310 xassert (png_ptr
!= NULL
);
7311 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7312 longjmp (png_ptr
->jmpbuf
, 1);
7317 my_png_warning (png_ptr
, msg
)
7318 png_struct
*png_ptr
;
7321 xassert (png_ptr
!= NULL
);
7322 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7325 /* Memory source for PNG decoding. */
7327 struct png_memory_storage
7329 unsigned char *bytes
; /* The data */
7330 size_t len
; /* How big is it? */
7331 int index
; /* Where are we? */
7335 /* Function set as reader function when reading PNG image from memory.
7336 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7337 bytes from the input to DATA. */
7340 png_read_from_memory (png_ptr
, data
, length
)
7341 png_structp png_ptr
;
7345 struct png_memory_storage
*tbr
7346 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7348 if (length
> tbr
->len
- tbr
->index
)
7349 png_error (png_ptr
, "Read error");
7351 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7352 tbr
->index
= tbr
->index
+ length
;
7355 /* Load PNG image IMG for use on frame F. Value is non-zero if
7363 Lisp_Object file
, specified_file
;
7364 Lisp_Object specified_data
;
7366 XImage
*ximg
, *mask_img
= NULL
;
7367 struct gcpro gcpro1
;
7368 png_struct
*png_ptr
= NULL
;
7369 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7372 png_byte
*pixels
= NULL
;
7373 png_byte
**rows
= NULL
;
7374 png_uint_32 width
, height
;
7375 int bit_depth
, color_type
, interlace_type
;
7377 png_uint_32 row_bytes
;
7380 double screen_gamma
, image_gamma
;
7382 struct png_memory_storage tbr
; /* Data to be read */
7384 /* Find out what file to load. */
7385 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7386 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7390 if (NILP (specified_data
))
7392 file
= x_find_image_file (specified_file
);
7393 if (!STRINGP (file
))
7395 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7400 /* Open the image file. */
7401 fp
= fopen (XSTRING (file
)->data
, "rb");
7404 image_error ("Cannot open image file `%s'", file
, Qnil
);
7410 /* Check PNG signature. */
7411 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7412 || !png_check_sig (sig
, sizeof sig
))
7414 image_error ("Not a PNG file:` %s'", file
, Qnil
);
7422 /* Read from memory. */
7423 tbr
.bytes
= XSTRING (specified_data
)->data
;
7424 tbr
.len
= STRING_BYTES (XSTRING (specified_data
));
7427 /* Check PNG signature. */
7428 if (tbr
.len
< sizeof sig
7429 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7431 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7436 /* Need to skip past the signature. */
7437 tbr
.bytes
+= sizeof (sig
);
7440 /* Initialize read and info structs for PNG lib. */
7441 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7442 my_png_error
, my_png_warning
);
7445 if (fp
) fclose (fp
);
7450 info_ptr
= png_create_info_struct (png_ptr
);
7453 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7454 if (fp
) fclose (fp
);
7459 end_info
= png_create_info_struct (png_ptr
);
7462 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7463 if (fp
) fclose (fp
);
7468 /* Set error jump-back. We come back here when the PNG library
7469 detects an error. */
7470 if (setjmp (png_ptr
->jmpbuf
))
7474 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7477 if (fp
) fclose (fp
);
7482 /* Read image info. */
7483 if (!NILP (specified_data
))
7484 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7486 png_init_io (png_ptr
, fp
);
7488 png_set_sig_bytes (png_ptr
, sizeof sig
);
7489 png_read_info (png_ptr
, info_ptr
);
7490 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7491 &interlace_type
, NULL
, NULL
);
7493 /* If image contains simply transparency data, we prefer to
7494 construct a clipping mask. */
7495 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7500 /* This function is easier to write if we only have to handle
7501 one data format: RGB or RGBA with 8 bits per channel. Let's
7502 transform other formats into that format. */
7504 /* Strip more than 8 bits per channel. */
7505 if (bit_depth
== 16)
7506 png_set_strip_16 (png_ptr
);
7508 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7510 png_set_expand (png_ptr
);
7512 /* Convert grayscale images to RGB. */
7513 if (color_type
== PNG_COLOR_TYPE_GRAY
7514 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7515 png_set_gray_to_rgb (png_ptr
);
7517 /* The value 2.2 is a guess for PC monitors from PNG example.c. */
7518 gamma_str
= getenv ("SCREEN_GAMMA");
7519 screen_gamma
= gamma_str
? atof (gamma_str
) : 2.2;
7521 /* Tell the PNG lib to handle gamma correction for us. */
7523 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7524 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7525 /* There is a special chunk in the image specifying the gamma. */
7526 png_set_sRGB (png_ptr
, info_ptr
, intent
);
7529 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7530 /* Image contains gamma information. */
7531 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7533 /* Use a default of 0.5 for the image gamma. */
7534 png_set_gamma (png_ptr
, screen_gamma
, 0.5);
7536 /* Handle alpha channel by combining the image with a background
7537 color. Do this only if a real alpha channel is supplied. For
7538 simple transparency, we prefer a clipping mask. */
7541 png_color_16
*image_background
;
7543 if (png_get_bKGD (png_ptr
, info_ptr
, &image_background
))
7544 /* Image contains a background color with which to
7545 combine the image. */
7546 png_set_background (png_ptr
, image_background
,
7547 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
7550 /* Image does not contain a background color with which
7551 to combine the image data via an alpha channel. Use
7552 the frame's background instead. */
7555 png_color_16 frame_background
;
7558 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
7559 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7560 XQueryColor (FRAME_W32_DISPLAY (f
), cmap
, &color
);
7563 bzero (&frame_background
, sizeof frame_background
);
7564 frame_background
.red
= color
.red
;
7565 frame_background
.green
= color
.green
;
7566 frame_background
.blue
= color
.blue
;
7568 png_set_background (png_ptr
, &frame_background
,
7569 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7573 /* Update info structure. */
7574 png_read_update_info (png_ptr
, info_ptr
);
7576 /* Get number of channels. Valid values are 1 for grayscale images
7577 and images with a palette, 2 for grayscale images with transparency
7578 information (alpha channel), 3 for RGB images, and 4 for RGB
7579 images with alpha channel, i.e. RGBA. If conversions above were
7580 sufficient we should only have 3 or 4 channels here. */
7581 channels
= png_get_channels (png_ptr
, info_ptr
);
7582 xassert (channels
== 3 || channels
== 4);
7584 /* Number of bytes needed for one row of the image. */
7585 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
7587 /* Allocate memory for the image. */
7588 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
7589 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
7590 for (i
= 0; i
< height
; ++i
)
7591 rows
[i
] = pixels
+ i
* row_bytes
;
7593 /* Read the entire image. */
7594 png_read_image (png_ptr
, rows
);
7595 png_read_end (png_ptr
, info_ptr
);
7604 /* Create the X image and pixmap. */
7605 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7612 /* Create an image and pixmap serving as mask if the PNG image
7613 contains an alpha channel. */
7616 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
7617 &mask_img
, &img
->mask
))
7619 x_destroy_x_image (ximg
);
7620 XFreePixmap (FRAME_W32_DISPLAY (f
), img
->pixmap
);
7626 /* Fill the X image and mask from PNG data. */
7627 init_color_table ();
7629 for (y
= 0; y
< height
; ++y
)
7631 png_byte
*p
= rows
[y
];
7633 for (x
= 0; x
< width
; ++x
)
7640 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7642 /* An alpha channel, aka mask channel, associates variable
7643 transparency with an image. Where other image formats
7644 support binary transparency---fully transparent or fully
7645 opaque---PNG allows up to 254 levels of partial transparency.
7646 The PNG library implements partial transparency by combining
7647 the image with a specified background color.
7649 I'm not sure how to handle this here nicely: because the
7650 background on which the image is displayed may change, for
7651 real alpha channel support, it would be necessary to create
7652 a new image for each possible background.
7654 What I'm doing now is that a mask is created if we have
7655 boolean transparency information. Otherwise I'm using
7656 the frame's background color to combine the image with. */
7661 XPutPixel (mask_img
, x
, y
, *p
> 0);
7667 /* Remember colors allocated for this image. */
7668 img
->colors
= colors_in_color_table (&img
->ncolors
);
7669 free_color_table ();
7672 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7677 img
->height
= height
;
7679 /* Put the image into the pixmap, then free the X image and its buffer. */
7680 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7681 x_destroy_x_image (ximg
);
7683 /* Same for the mask. */
7686 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7687 x_destroy_x_image (mask_img
);
7695 #endif /* HAVE_PNG != 0 */
7699 /***********************************************************************
7701 ***********************************************************************/
7705 /* Work around a warning about HAVE_STDLIB_H being redefined in
7707 #ifdef HAVE_STDLIB_H
7708 #define HAVE_STDLIB_H_1
7709 #undef HAVE_STDLIB_H
7710 #endif /* HAVE_STLIB_H */
7712 #include <jpeglib.h>
7716 #ifdef HAVE_STLIB_H_1
7717 #define HAVE_STDLIB_H 1
7720 static int jpeg_image_p
P_ ((Lisp_Object object
));
7721 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
7723 /* The symbol `jpeg' identifying images of this type. */
7727 /* Indices of image specification fields in gs_format, below. */
7729 enum jpeg_keyword_index
7738 JPEG_HEURISTIC_MASK
,
7742 /* Vector of image_keyword structures describing the format
7743 of valid user-defined image specifications. */
7745 static struct image_keyword jpeg_format
[JPEG_LAST
] =
7747 {":type", IMAGE_SYMBOL_VALUE
, 1},
7748 {":data", IMAGE_STRING_VALUE
, 0},
7749 {":file", IMAGE_STRING_VALUE
, 0},
7750 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7751 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7752 {":relief", IMAGE_INTEGER_VALUE
, 0},
7753 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7754 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7757 /* Structure describing the image type `jpeg'. */
7759 static struct image_type jpeg_type
=
7769 /* Return non-zero if OBJECT is a valid JPEG image specification. */
7772 jpeg_image_p (object
)
7775 struct image_keyword fmt
[JPEG_LAST
];
7777 bcopy (jpeg_format
, fmt
, sizeof fmt
);
7779 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
)
7780 || (fmt
[JPEG_ASCENT
].count
7781 && XFASTINT (fmt
[JPEG_ASCENT
].value
) > 100))
7784 /* Must specify either the :data or :file keyword. */
7785 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
7789 struct my_jpeg_error_mgr
7791 struct jpeg_error_mgr pub
;
7792 jmp_buf setjmp_buffer
;
7796 my_error_exit (cinfo
)
7799 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
7800 longjmp (mgr
->setjmp_buffer
, 1);
7803 /* Init source method for JPEG data source manager. Called by
7804 jpeg_read_header() before any data is actually read. See
7805 libjpeg.doc from the JPEG lib distribution. */
7808 our_init_source (cinfo
)
7809 j_decompress_ptr cinfo
;
7814 /* Fill input buffer method for JPEG data source manager. Called
7815 whenever more data is needed. We read the whole image in one step,
7816 so this only adds a fake end of input marker at the end. */
7819 our_fill_input_buffer (cinfo
)
7820 j_decompress_ptr cinfo
;
7822 /* Insert a fake EOI marker. */
7823 struct jpeg_source_mgr
*src
= cinfo
->src
;
7824 static JOCTET buffer
[2];
7826 buffer
[0] = (JOCTET
) 0xFF;
7827 buffer
[1] = (JOCTET
) JPEG_EOI
;
7829 src
->next_input_byte
= buffer
;
7830 src
->bytes_in_buffer
= 2;
7835 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
7836 is the JPEG data source manager. */
7839 our_skip_input_data (cinfo
, num_bytes
)
7840 j_decompress_ptr cinfo
;
7843 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7847 if (num_bytes
> src
->bytes_in_buffer
)
7848 ERREXIT (cinfo
, JERR_INPUT_EOF
);
7850 src
->bytes_in_buffer
-= num_bytes
;
7851 src
->next_input_byte
+= num_bytes
;
7856 /* Method to terminate data source. Called by
7857 jpeg_finish_decompress() after all data has been processed. */
7860 our_term_source (cinfo
)
7861 j_decompress_ptr cinfo
;
7866 /* Set up the JPEG lib for reading an image from DATA which contains
7867 LEN bytes. CINFO is the decompression info structure created for
7868 reading the image. */
7871 jpeg_memory_src (cinfo
, data
, len
)
7872 j_decompress_ptr cinfo
;
7876 struct jpeg_source_mgr
*src
;
7878 if (cinfo
->src
== NULL
)
7880 /* First time for this JPEG object? */
7881 cinfo
->src
= (struct jpeg_source_mgr
*)
7882 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
7883 sizeof (struct jpeg_source_mgr
));
7884 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7885 src
->next_input_byte
= data
;
7888 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
7889 src
->init_source
= our_init_source
;
7890 src
->fill_input_buffer
= our_fill_input_buffer
;
7891 src
->skip_input_data
= our_skip_input_data
;
7892 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
7893 src
->term_source
= our_term_source
;
7894 src
->bytes_in_buffer
= len
;
7895 src
->next_input_byte
= data
;
7899 /* Load image IMG for use on frame F. Patterned after example.c
7900 from the JPEG lib. */
7907 struct jpeg_decompress_struct cinfo
;
7908 struct my_jpeg_error_mgr mgr
;
7909 Lisp_Object file
, specified_file
;
7910 Lisp_Object specified_data
;
7913 int row_stride
, x
, y
;
7914 XImage
*ximg
= NULL
;
7916 unsigned long *colors
;
7918 struct gcpro gcpro1
;
7920 /* Open the JPEG file. */
7921 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7922 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7926 if (NILP (specified_data
))
7928 file
= x_find_image_file (specified_file
);
7929 if (!STRINGP (file
))
7931 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7936 fp
= fopen (XSTRING (file
)->data
, "r");
7939 image_error ("Cannot open `%s'", file
, Qnil
);
7945 /* Customize libjpeg's error handling to call my_error_exit when an
7946 error is detected. This function will perform a longjmp. */
7947 mgr
.pub
.error_exit
= my_error_exit
;
7948 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
7950 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
7954 /* Called from my_error_exit. Display a JPEG error. */
7955 char buffer
[JMSG_LENGTH_MAX
];
7956 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
7957 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
7958 build_string (buffer
));
7961 /* Close the input file and destroy the JPEG object. */
7964 jpeg_destroy_decompress (&cinfo
);
7968 /* If we already have an XImage, free that. */
7969 x_destroy_x_image (ximg
);
7971 /* Free pixmap and colors. */
7972 x_clear_image (f
, img
);
7979 /* Create the JPEG decompression object. Let it read from fp.
7980 Read the JPEG image header. */
7981 jpeg_create_decompress (&cinfo
);
7983 if (NILP (specified_data
))
7984 jpeg_stdio_src (&cinfo
, fp
);
7986 jpeg_memory_src (&cinfo
, XSTRING (specified_data
)->data
,
7987 STRING_BYTES (XSTRING (specified_data
)));
7989 jpeg_read_header (&cinfo
, TRUE
);
7991 /* Customize decompression so that color quantization will be used.
7992 Start decompression. */
7993 cinfo
.quantize_colors
= TRUE
;
7994 jpeg_start_decompress (&cinfo
);
7995 width
= img
->width
= cinfo
.output_width
;
7996 height
= img
->height
= cinfo
.output_height
;
8000 /* Create X image and pixmap. */
8001 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
8005 longjmp (mgr
.setjmp_buffer
, 2);
8008 /* Allocate colors. When color quantization is used,
8009 cinfo.actual_number_of_colors has been set with the number of
8010 colors generated, and cinfo.colormap is a two-dimensional array
8011 of color indices in the range 0..cinfo.actual_number_of_colors.
8012 No more than 255 colors will be generated. */
8016 if (cinfo
.out_color_components
> 2)
8017 ir
= 0, ig
= 1, ib
= 2;
8018 else if (cinfo
.out_color_components
> 1)
8019 ir
= 0, ig
= 1, ib
= 0;
8021 ir
= 0, ig
= 0, ib
= 0;
8023 /* Use the color table mechanism because it handles colors that
8024 cannot be allocated nicely. Such colors will be replaced with
8025 a default color, and we don't have to care about which colors
8026 can be freed safely, and which can't. */
8027 init_color_table ();
8028 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
8031 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
8033 /* Multiply RGB values with 255 because X expects RGB values
8034 in the range 0..0xffff. */
8035 int r
= cinfo
.colormap
[ir
][i
] << 8;
8036 int g
= cinfo
.colormap
[ig
][i
] << 8;
8037 int b
= cinfo
.colormap
[ib
][i
] << 8;
8038 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8041 /* Remember those colors actually allocated. */
8042 img
->colors
= colors_in_color_table (&img
->ncolors
);
8043 free_color_table ();
8047 row_stride
= width
* cinfo
.output_components
;
8048 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8050 for (y
= 0; y
< height
; ++y
)
8052 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8053 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8054 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8058 jpeg_finish_decompress (&cinfo
);
8059 jpeg_destroy_decompress (&cinfo
);
8063 /* Put the image into the pixmap. */
8064 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8065 x_destroy_x_image (ximg
);
8071 #endif /* HAVE_JPEG */
8075 /***********************************************************************
8077 ***********************************************************************/
8083 static int tiff_image_p
P_ ((Lisp_Object object
));
8084 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8086 /* The symbol `tiff' identifying images of this type. */
8090 /* Indices of image specification fields in tiff_format, below. */
8092 enum tiff_keyword_index
8101 TIFF_HEURISTIC_MASK
,
8105 /* Vector of image_keyword structures describing the format
8106 of valid user-defined image specifications. */
8108 static struct image_keyword tiff_format
[TIFF_LAST
] =
8110 {":type", IMAGE_SYMBOL_VALUE
, 1},
8111 {":data", IMAGE_STRING_VALUE
, 0},
8112 {":file", IMAGE_STRING_VALUE
, 0},
8113 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8114 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8115 {":relief", IMAGE_INTEGER_VALUE
, 0},
8116 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8117 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
8120 /* Structure describing the image type `tiff'. */
8122 static struct image_type tiff_type
=
8132 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8135 tiff_image_p (object
)
8138 struct image_keyword fmt
[TIFF_LAST
];
8139 bcopy (tiff_format
, fmt
, sizeof fmt
);
8141 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
)
8142 || (fmt
[TIFF_ASCENT
].count
8143 && XFASTINT (fmt
[TIFF_ASCENT
].value
) > 100))
8146 /* Must specify either the :data or :file keyword. */
8147 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8151 /* Reading from a memory buffer for TIFF images Based on the PNG
8152 memory source, but we have to provide a lot of extra functions.
8155 We really only need to implement read and seek, but I am not
8156 convinced that the TIFF library is smart enough not to destroy
8157 itself if we only hand it the function pointers we need to
8162 unsigned char *bytes
;
8169 tiff_read_from_memory (data
, buf
, size
)
8174 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8176 if (size
> src
->len
- src
->index
)
8178 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8184 tiff_write_from_memory (data
, buf
, size
)
8193 tiff_seek_in_memory (data
, off
, whence
)
8198 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8203 case SEEK_SET
: /* Go from beginning of source. */
8207 case SEEK_END
: /* Go from end of source. */
8208 idx
= src
->len
+ off
;
8211 case SEEK_CUR
: /* Go from current position. */
8212 idx
= src
->index
+ off
;
8215 default: /* Invalid `whence'. */
8219 if (idx
> src
->len
|| idx
< 0)
8227 tiff_close_memory (data
)
8235 tiff_mmap_memory (data
, pbase
, psize
)
8240 /* It is already _IN_ memory. */
8245 tiff_unmap_memory (data
, base
, size
)
8250 /* We don't need to do this. */
8254 tiff_size_of_memory (data
)
8257 return ((tiff_memory_source
*) data
)->len
;
8260 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8268 Lisp_Object file
, specified_file
;
8269 Lisp_Object specified_data
;
8271 int width
, height
, x
, y
;
8275 struct gcpro gcpro1
;
8276 tiff_memory_source memsrc
;
8278 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8279 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8283 if (NILP (specified_data
))
8285 /* Read from a file */
8286 file
= x_find_image_file (specified_file
);
8287 if (!STRINGP (file
))
8289 image_error ("Cannot find image file `%s'", file
, Qnil
);
8294 /* Try to open the image file. */
8295 tiff
= TIFFOpen (XSTRING (file
)->data
, "r");
8298 image_error ("Cannot open `%s'", file
, Qnil
);
8305 /* Memory source! */
8306 memsrc
.bytes
= XSTRING (specified_data
)->data
;
8307 memsrc
.len
= STRING_BYTES (XSTRING (specified_data
));
8310 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8311 (TIFFReadWriteProc
) tiff_read_from_memory
,
8312 (TIFFReadWriteProc
) tiff_write_from_memory
,
8313 tiff_seek_in_memory
,
8315 tiff_size_of_memory
,
8321 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8327 /* Get width and height of the image, and allocate a raster buffer
8328 of width x height 32-bit values. */
8329 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8330 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8331 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8333 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8337 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8345 /* Create the X image and pixmap. */
8346 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8354 /* Initialize the color table. */
8355 init_color_table ();
8357 /* Process the pixel raster. Origin is in the lower-left corner. */
8358 for (y
= 0; y
< height
; ++y
)
8360 uint32
*row
= buf
+ y
* width
;
8362 for (x
= 0; x
< width
; ++x
)
8364 uint32 abgr
= row
[x
];
8365 int r
= TIFFGetR (abgr
) << 8;
8366 int g
= TIFFGetG (abgr
) << 8;
8367 int b
= TIFFGetB (abgr
) << 8;
8368 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8372 /* Remember the colors allocated for the image. Free the color table. */
8373 img
->colors
= colors_in_color_table (&img
->ncolors
);
8374 free_color_table ();
8376 /* Put the image into the pixmap, then free the X image and its buffer. */
8377 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8378 x_destroy_x_image (ximg
);
8383 img
->height
= height
;
8389 #endif /* HAVE_TIFF != 0 */
8393 /***********************************************************************
8395 ***********************************************************************/
8399 #include <gif_lib.h>
8401 static int gif_image_p
P_ ((Lisp_Object object
));
8402 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8404 /* The symbol `gif' identifying images of this type. */
8408 /* Indices of image specification fields in gif_format, below. */
8410 enum gif_keyword_index
8424 /* Vector of image_keyword structures describing the format
8425 of valid user-defined image specifications. */
8427 static struct image_keyword gif_format
[GIF_LAST
] =
8429 {":type", IMAGE_SYMBOL_VALUE
, 1},
8430 {":data", IMAGE_STRING_VALUE
, 0},
8431 {":file", IMAGE_STRING_VALUE
, 0},
8432 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8433 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8434 {":relief", IMAGE_INTEGER_VALUE
, 0},
8435 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8436 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8437 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
8440 /* Structure describing the image type `gif'. */
8442 static struct image_type gif_type
=
8451 /* Return non-zero if OBJECT is a valid GIF image specification. */
8454 gif_image_p (object
)
8457 struct image_keyword fmt
[GIF_LAST
];
8458 bcopy (gif_format
, fmt
, sizeof fmt
);
8460 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
)
8461 || (fmt
[GIF_ASCENT
].count
8462 && XFASTINT (fmt
[GIF_ASCENT
].value
) > 100))
8465 /* Must specify either the :data or :file keyword. */
8466 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8469 /* Reading a GIF image from memory
8470 Based on the PNG memory stuff to a certain extent. */
8474 unsigned char *bytes
;
8480 /* Make the current memory source available to gif_read_from_memory.
8481 It's done this way because not all versions of libungif support
8482 a UserData field in the GifFileType structure. */
8483 static gif_memory_source
*current_gif_memory_src
;
8486 gif_read_from_memory (file
, buf
, len
)
8491 gif_memory_source
*src
= current_gif_memory_src
;
8493 if (len
> src
->len
- src
->index
)
8496 bcopy (src
->bytes
+ src
->index
, buf
, len
);
8502 /* Load GIF image IMG for use on frame F. Value is non-zero if
8510 Lisp_Object file
, specified_file
;
8511 Lisp_Object specified_data
;
8512 int rc
, width
, height
, x
, y
, i
;
8514 ColorMapObject
*gif_color_map
;
8515 unsigned long pixel_colors
[256];
8517 struct gcpro gcpro1
;
8519 int ino
, image_left
, image_top
, image_width
, image_height
;
8520 gif_memory_source memsrc
;
8521 unsigned char *raster
;
8523 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8524 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8528 if (NILP (specified_data
))
8530 file
= x_find_image_file (specified_file
);
8531 if (!STRINGP (file
))
8533 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8538 /* Open the GIF file. */
8539 gif
= DGifOpenFileName (XSTRING (file
)->data
);
8542 image_error ("Cannot open `%s'", file
, Qnil
);
8549 /* Read from memory! */
8550 current_gif_memory_src
= &memsrc
;
8551 memsrc
.bytes
= XSTRING (specified_data
)->data
;
8552 memsrc
.len
= STRING_BYTES (XSTRING (specified_data
));
8555 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
8558 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
8564 /* Read entire contents. */
8565 rc
= DGifSlurp (gif
);
8566 if (rc
== GIF_ERROR
)
8568 image_error ("Error reading `%s'", img
->spec
, Qnil
);
8569 DGifCloseFile (gif
);
8574 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
8575 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
8576 if (ino
>= gif
->ImageCount
)
8578 image_error ("Invalid image number `%s' in image `%s'",
8580 DGifCloseFile (gif
);
8585 width
= img
->width
= gif
->SWidth
;
8586 height
= img
->height
= gif
->SHeight
;
8590 /* Create the X image and pixmap. */
8591 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8594 DGifCloseFile (gif
);
8599 /* Allocate colors. */
8600 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
8602 gif_color_map
= gif
->SColorMap
;
8603 init_color_table ();
8604 bzero (pixel_colors
, sizeof pixel_colors
);
8606 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
8608 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
8609 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
8610 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
8611 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8614 img
->colors
= colors_in_color_table (&img
->ncolors
);
8615 free_color_table ();
8617 /* Clear the part of the screen image that are not covered by
8618 the image from the GIF file. Full animated GIF support
8619 requires more than can be done here (see the gif89 spec,
8620 disposal methods). Let's simply assume that the part
8621 not covered by a sub-image is in the frame's background color. */
8622 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
8623 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
8624 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
8625 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
8627 for (y
= 0; y
< image_top
; ++y
)
8628 for (x
= 0; x
< width
; ++x
)
8629 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8631 for (y
= image_top
+ image_height
; y
< height
; ++y
)
8632 for (x
= 0; x
< width
; ++x
)
8633 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8635 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
8637 for (x
= 0; x
< image_left
; ++x
)
8638 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8639 for (x
= image_left
+ image_width
; x
< width
; ++x
)
8640 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8643 /* Read the GIF image into the X image. We use a local variable
8644 `raster' here because RasterBits below is a char *, and invites
8645 problems with bytes >= 0x80. */
8646 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
8648 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
8650 static int interlace_start
[] = {0, 4, 2, 1};
8651 static int interlace_increment
[] = {8, 8, 4, 2};
8653 int row
= interlace_start
[0];
8657 for (y
= 0; y
< image_height
; y
++)
8659 if (row
>= image_height
)
8661 row
= interlace_start
[++pass
];
8662 while (row
>= image_height
)
8663 row
= interlace_start
[++pass
];
8666 for (x
= 0; x
< image_width
; x
++)
8668 int i
= raster
[(y
* image_width
) + x
];
8669 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
8673 row
+= interlace_increment
[pass
];
8678 for (y
= 0; y
< image_height
; ++y
)
8679 for (x
= 0; x
< image_width
; ++x
)
8681 int i
= raster
[y
* image_width
+ x
];
8682 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
8686 DGifCloseFile (gif
);
8688 /* Put the image into the pixmap, then free the X image and its buffer. */
8689 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8690 x_destroy_x_image (ximg
);
8697 #endif /* HAVE_GIF != 0 */
8701 /***********************************************************************
8703 ***********************************************************************/
8705 #ifdef HAVE_GHOSTSCRIPT
8706 static int gs_image_p
P_ ((Lisp_Object object
));
8707 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
8708 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
8710 /* The symbol `postscript' identifying images of this type. */
8712 Lisp_Object Qpostscript
;
8714 /* Keyword symbols. */
8716 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
8718 /* Indices of image specification fields in gs_format, below. */
8720 enum gs_keyword_index
8736 /* Vector of image_keyword structures describing the format
8737 of valid user-defined image specifications. */
8739 static struct image_keyword gs_format
[GS_LAST
] =
8741 {":type", IMAGE_SYMBOL_VALUE
, 1},
8742 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8743 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8744 {":file", IMAGE_STRING_VALUE
, 1},
8745 {":loader", IMAGE_FUNCTION_VALUE
, 0},
8746 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
8747 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8748 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8749 {":relief", IMAGE_INTEGER_VALUE
, 0},
8750 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8751 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
8754 /* Structure describing the image type `ghostscript'. */
8756 static struct image_type gs_type
=
8766 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8769 gs_clear_image (f
, img
)
8773 /* IMG->data.ptr_val may contain a recorded colormap. */
8774 xfree (img
->data
.ptr_val
);
8775 x_clear_image (f
, img
);
8779 /* Return non-zero if OBJECT is a valid Ghostscript image
8786 struct image_keyword fmt
[GS_LAST
];
8790 bcopy (gs_format
, fmt
, sizeof fmt
);
8792 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
)
8793 || (fmt
[GS_ASCENT
].count
8794 && XFASTINT (fmt
[GS_ASCENT
].value
) > 100))
8797 /* Bounding box must be a list or vector containing 4 integers. */
8798 tem
= fmt
[GS_BOUNDING_BOX
].value
;
8801 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
8802 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
8807 else if (VECTORP (tem
))
8809 if (XVECTOR (tem
)->size
!= 4)
8811 for (i
= 0; i
< 4; ++i
)
8812 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
8822 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
8831 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
8832 struct gcpro gcpro1
, gcpro2
;
8834 double in_width
, in_height
;
8835 Lisp_Object pixel_colors
= Qnil
;
8837 /* Compute pixel size of pixmap needed from the given size in the
8838 image specification. Sizes in the specification are in pt. 1 pt
8839 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8841 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
8842 in_width
= XFASTINT (pt_width
) / 72.0;
8843 img
->width
= in_width
* FRAME_W32_DISPLAY_INFO (f
)->resx
;
8844 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
8845 in_height
= XFASTINT (pt_height
) / 72.0;
8846 img
->height
= in_height
* FRAME_W32_DISPLAY_INFO (f
)->resy
;
8848 /* Create the pixmap. */
8850 xassert (img
->pixmap
== 0);
8851 img
->pixmap
= XCreatePixmap (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
8852 img
->width
, img
->height
,
8853 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
8858 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
8862 /* Call the loader to fill the pixmap. It returns a process object
8863 if successful. We do not record_unwind_protect here because
8864 other places in redisplay like calling window scroll functions
8865 don't either. Let the Lisp loader use `unwind-protect' instead. */
8866 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
8868 sprintf (buffer
, "%lu %lu",
8869 (unsigned long) FRAME_W32_WINDOW (f
),
8870 (unsigned long) img
->pixmap
);
8871 window_and_pixmap_id
= build_string (buffer
);
8873 sprintf (buffer
, "%lu %lu",
8874 FRAME_FOREGROUND_PIXEL (f
),
8875 FRAME_BACKGROUND_PIXEL (f
));
8876 pixel_colors
= build_string (buffer
);
8878 XSETFRAME (frame
, f
);
8879 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
8881 loader
= intern ("gs-load-image");
8883 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
8884 make_number (img
->width
),
8885 make_number (img
->height
),
8886 window_and_pixmap_id
,
8889 return PROCESSP (img
->data
.lisp_val
);
8893 /* Kill the Ghostscript process that was started to fill PIXMAP on
8894 frame F. Called from XTread_socket when receiving an event
8895 telling Emacs that Ghostscript has finished drawing. */
8898 x_kill_gs_process (pixmap
, f
)
8902 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
8906 /* Find the image containing PIXMAP. */
8907 for (i
= 0; i
< c
->used
; ++i
)
8908 if (c
->images
[i
]->pixmap
== pixmap
)
8911 /* Kill the GS process. We should have found PIXMAP in the image
8912 cache and its image should contain a process object. */
8913 xassert (i
< c
->used
);
8915 xassert (PROCESSP (img
->data
.lisp_val
));
8916 Fkill_process (img
->data
.lisp_val
, Qnil
);
8917 img
->data
.lisp_val
= Qnil
;
8919 /* On displays with a mutable colormap, figure out the colors
8920 allocated for the image by looking at the pixels of an XImage for
8922 class = FRAME_W32_DISPLAY_INFO (f
)->visual
->class;
8923 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
8929 /* Try to get an XImage for img->pixmep. */
8930 ximg
= XGetImage (FRAME_W32_DISPLAY (f
), img
->pixmap
,
8931 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
8936 /* Initialize the color table. */
8937 init_color_table ();
8939 /* For each pixel of the image, look its color up in the
8940 color table. After having done so, the color table will
8941 contain an entry for each color used by the image. */
8942 for (y
= 0; y
< img
->height
; ++y
)
8943 for (x
= 0; x
< img
->width
; ++x
)
8945 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8946 lookup_pixel_color (f
, pixel
);
8949 /* Record colors in the image. Free color table and XImage. */
8950 img
->colors
= colors_in_color_table (&img
->ncolors
);
8951 free_color_table ();
8952 XDestroyImage (ximg
);
8954 #if 0 /* This doesn't seem to be the case. If we free the colors
8955 here, we get a BadAccess later in x_clear_image when
8956 freeing the colors. */
8957 /* We have allocated colors once, but Ghostscript has also
8958 allocated colors on behalf of us. So, to get the
8959 reference counts right, free them once. */
8962 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
8963 XFreeColors (FRAME_W32_DISPLAY (f
), cmap
,
8964 img
->colors
, img
->ncolors
, 0);
8969 image_error ("Cannot get X image of `%s'; colors will not be freed",
8976 #endif /* HAVE_GHOSTSCRIPT */
8979 /***********************************************************************
8981 ***********************************************************************/
8983 DEFUN ("x-change-window-property", Fx_change_window_property
,
8984 Sx_change_window_property
, 2, 3, 0,
8985 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
8986 PROP and VALUE must be strings. FRAME nil or omitted means use the
8987 selected frame. Value is VALUE. */)
8988 (prop
, value
, frame
)
8989 Lisp_Object frame
, prop
, value
;
8991 #if 0 /* MAC_TODO : port window properties to Mac */
8992 struct frame
*f
= check_x_frame (frame
);
8995 CHECK_STRING (prop
);
8996 CHECK_STRING (value
);
8999 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), XSTRING (prop
)->data
, False
);
9000 XChangeProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9001 prop_atom
, XA_STRING
, 8, PropModeReplace
,
9002 XSTRING (value
)->data
, XSTRING (value
)->size
);
9004 /* Make sure the property is set when we return. */
9005 XFlush (FRAME_W32_DISPLAY (f
));
9008 #endif /* MAC_TODO */
9014 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
9015 Sx_delete_window_property
, 1, 2, 0,
9016 doc
: /* Remove window property PROP from X window of FRAME.
9017 FRAME nil or omitted means use the selected frame. Value is PROP. */)
9019 Lisp_Object prop
, frame
;
9021 #if 0 /* MAC_TODO : port window properties to Mac */
9023 struct frame
*f
= check_x_frame (frame
);
9026 CHECK_STRING (prop
);
9028 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), XSTRING (prop
)->data
, False
);
9029 XDeleteProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), prop_atom
);
9031 /* Make sure the property is removed when we return. */
9032 XFlush (FRAME_W32_DISPLAY (f
));
9034 #endif /* MAC_TODO */
9040 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9042 doc
: /* Value is the value of window property PROP on FRAME.
9043 If FRAME is nil or omitted, use the selected frame. Value is nil
9044 if FRAME hasn't a property with name PROP or if PROP has no string
9047 Lisp_Object prop
, frame
;
9049 #if 0 /* MAC_TODO : port window properties to Mac */
9051 struct frame
*f
= check_x_frame (frame
);
9054 Lisp_Object prop_value
= Qnil
;
9055 char *tmp_data
= NULL
;
9058 unsigned long actual_size
, bytes_remaining
;
9060 CHECK_STRING (prop
);
9062 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), XSTRING (prop
)->data
, False
);
9063 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9064 prop_atom
, 0, 0, False
, XA_STRING
,
9065 &actual_type
, &actual_format
, &actual_size
,
9066 &bytes_remaining
, (unsigned char **) &tmp_data
);
9069 int size
= bytes_remaining
;
9074 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9075 prop_atom
, 0, bytes_remaining
,
9077 &actual_type
, &actual_format
,
9078 &actual_size
, &bytes_remaining
,
9079 (unsigned char **) &tmp_data
);
9081 prop_value
= make_string (tmp_data
, size
);
9090 #endif /* MAC_TODO */
9096 /***********************************************************************
9098 ***********************************************************************/
9100 /* If non-null, an asynchronous timer that, when it expires, displays
9101 an hourglass cursor on all frames. */
9103 static struct atimer
*hourglass_atimer
;
9105 /* Non-zero means an hourglass cursor is currently shown. */
9107 static int hourglass_shown_p
;
9109 /* Number of seconds to wait before displaying an hourglass cursor. */
9111 static Lisp_Object Vhourglass_delay
;
9113 /* Default number of seconds to wait before displaying an hourglass
9116 #define DEFAULT_HOURGLASS_DELAY 1
9118 /* Function prototypes. */
9120 static void show_hourglass
P_ ((struct atimer
*));
9121 static void hide_hourglass
P_ ((void));
9124 /* Cancel a currently active hourglass timer, and start a new one. */
9129 #if 0 /* MAC_TODO: cursor shape changes. */
9131 int secs
, usecs
= 0;
9133 cancel_hourglass ();
9135 if (INTEGERP (Vhourglass_delay
)
9136 && XINT (Vhourglass_delay
) > 0)
9137 secs
= XFASTINT (Vhourglass_delay
);
9138 else if (FLOATP (Vhourglass_delay
)
9139 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9142 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9143 secs
= XFASTINT (tem
);
9144 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9147 secs
= DEFAULT_HOURGLASS_DELAY
;
9149 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9150 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9151 show_hourglass
, NULL
);
9152 #endif /* MAC_TODO */
9156 /* Cancel the hourglass cursor timer if active, hide an hourglass
9162 if (hourglass_atimer
)
9164 cancel_atimer (hourglass_atimer
);
9165 hourglass_atimer
= NULL
;
9168 if (hourglass_shown_p
)
9173 /* Timer function of hourglass_atimer. TIMER is equal to
9176 Display an hourglass cursor on all frames by mapping the frames'
9177 hourglass_window. Set the hourglass_p flag in the frames'
9178 output_data.x structure to indicate that an hourglass cursor is
9179 shown on the frames. */
9182 show_hourglass (timer
)
9183 struct atimer
*timer
;
9185 #if 0 /* MAC_TODO: cursor shape changes. */
9186 /* The timer implementation will cancel this timer automatically
9187 after this function has run. Set hourglass_atimer to null
9188 so that we know the timer doesn't have to be canceled. */
9189 hourglass_atimer
= NULL
;
9191 if (!hourglass_shown_p
)
9193 Lisp_Object rest
, frame
;
9197 FOR_EACH_FRAME (rest
, frame
)
9198 if (FRAME_W32_P (XFRAME (frame
)))
9200 struct frame
*f
= XFRAME (frame
);
9202 f
->output_data
.w32
->hourglass_p
= 1;
9204 if (!f
->output_data
.w32
->hourglass_window
)
9206 unsigned long mask
= CWCursor
;
9207 XSetWindowAttributes attrs
;
9209 attrs
.cursor
= f
->output_data
.w32
->hourglass_cursor
;
9211 f
->output_data
.w32
->hourglass_window
9212 = XCreateWindow (FRAME_X_DISPLAY (f
),
9213 FRAME_OUTER_WINDOW (f
),
9214 0, 0, 32000, 32000, 0, 0,
9220 XMapRaised (FRAME_X_DISPLAY (f
),
9221 f
->output_data
.w32
->hourglass_window
);
9222 XFlush (FRAME_X_DISPLAY (f
));
9225 hourglass_shown_p
= 1;
9228 #endif /* MAC_TODO */
9232 /* Hide the hourglass cursor on all frames, if it is currently shown. */
9237 #if 0 /* MAC_TODO: cursor shape changes. */
9238 if (hourglass_shown_p
)
9240 Lisp_Object rest
, frame
;
9243 FOR_EACH_FRAME (rest
, frame
)
9245 struct frame
*f
= XFRAME (frame
);
9248 /* Watch out for newly created frames. */
9249 && f
->output_data
.x
->hourglass_window
)
9251 XUnmapWindow (FRAME_X_DISPLAY (f
),
9252 f
->output_data
.x
->hourglass_window
);
9253 /* Sync here because XTread_socket looks at the
9254 hourglass_p flag that is reset to zero below. */
9255 XSync (FRAME_X_DISPLAY (f
), False
);
9256 f
->output_data
.x
->hourglass_p
= 0;
9260 hourglass_shown_p
= 0;
9263 #endif /* MAC_TODO */
9268 /***********************************************************************
9270 ***********************************************************************/
9272 static Lisp_Object x_create_tip_frame
P_ ((struct mac_display_info
*,
9275 /* The frame of a currently visible tooltip, or null. */
9277 Lisp_Object tip_frame
;
9279 /* If non-nil, a timer started that hides the last tooltip when it
9282 Lisp_Object tip_timer
;
9285 /* If non-nil, a vector of 3 elements containing the last args
9286 with which x-show-tip was called. See there. */
9288 Lisp_Object last_show_tip_args
;
9290 /* Create a frame for a tooltip on the display described by DPYINFO.
9291 PARMS is a list of frame parameters. Value is the frame. */
9294 x_create_tip_frame (dpyinfo
, parms
)
9295 struct mac_display_info
*dpyinfo
;
9298 #if 0 /* MAC_TODO : Mac version */
9300 Lisp_Object frame
, tem
;
9302 long window_prompting
= 0;
9304 int count
= specpdl_ptr
- specpdl
;
9305 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9310 /* Use this general default value to start with until we know if
9311 this frame has a specified name. */
9312 Vx_resource_name
= Vinvocation_name
;
9315 kb
= dpyinfo
->kboard
;
9317 kb
= &the_only_kboard
;
9320 /* Get the name of the frame to use for resource lookup. */
9321 name
= w32_get_arg (parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9323 && !EQ (name
, Qunbound
)
9325 error ("Invalid frame name--not a string or nil");
9326 Vx_resource_name
= name
;
9329 GCPRO3 (parms
, name
, frame
);
9330 tip_frame
= f
= make_frame (1);
9331 XSETFRAME (frame
, f
);
9332 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9334 f
->output_method
= output_w32
;
9335 f
->output_data
.w32
=
9336 (struct w32_output
*) xmalloc (sizeof (struct w32_output
));
9337 bzero (f
->output_data
.w32
, sizeof (struct w32_output
));
9339 f
->output_data
.w32
->icon_bitmap
= -1;
9341 f
->output_data
.w32
->fontset
= -1;
9342 f
->icon_name
= Qnil
;
9345 FRAME_KBOARD (f
) = kb
;
9347 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
9348 f
->output_data
.w32
->explicit_parent
= 0;
9350 /* Set the name; the functions to which we pass f expect the name to
9352 if (EQ (name
, Qunbound
) || NILP (name
))
9354 f
->name
= build_string (dpyinfo
->x_id_name
);
9355 f
->explicit_name
= 0;
9360 f
->explicit_name
= 1;
9361 /* use the frame's title when getting resources for this frame. */
9362 specbind (Qx_resource_name
, name
);
9365 /* Extract the window parameters from the supplied values
9366 that are needed to determine window geometry. */
9370 font
= w32_get_arg (parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
9373 /* First, try whatever font the caller has specified. */
9376 tem
= Fquery_fontset (font
, Qnil
);
9378 font
= x_new_fontset (f
, XSTRING (tem
)->data
);
9380 font
= x_new_font (f
, XSTRING (font
)->data
);
9383 /* Try out a font which we hope has bold and italic variations. */
9384 if (!STRINGP (font
))
9385 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
9386 if (!STRINGP (font
))
9387 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9388 if (! STRINGP (font
))
9389 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9390 if (! STRINGP (font
))
9391 /* This was formerly the first thing tried, but it finds too many fonts
9392 and takes too long. */
9393 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
9394 /* If those didn't work, look for something which will at least work. */
9395 if (! STRINGP (font
))
9396 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
9398 if (! STRINGP (font
))
9399 font
= build_string ("fixed");
9401 x_default_parameter (f
, parms
, Qfont
, font
,
9402 "font", "Font", RES_TYPE_STRING
);
9405 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
9406 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
9408 /* This defaults to 2 in order to match xterm. We recognize either
9409 internalBorderWidth or internalBorder (which is what xterm calls
9411 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9415 value
= w32_get_arg (parms
, Qinternal_border_width
,
9416 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
9417 if (! EQ (value
, Qunbound
))
9418 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
9422 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
9423 "internalBorderWidth", "internalBorderWidth",
9426 /* Also do the stuff which must be set before the window exists. */
9427 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
9428 "foreground", "Foreground", RES_TYPE_STRING
);
9429 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
9430 "background", "Background", RES_TYPE_STRING
);
9431 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
9432 "pointerColor", "Foreground", RES_TYPE_STRING
);
9433 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
9434 "cursorColor", "Foreground", RES_TYPE_STRING
);
9435 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
9436 "borderColor", "BorderColor", RES_TYPE_STRING
);
9438 /* Init faces before x_default_parameter is called for scroll-bar
9439 parameters because that function calls x_set_scroll_bar_width,
9440 which calls change_frame_size, which calls Fset_window_buffer,
9441 which runs hooks, which call Fvertical_motion. At the end, we
9442 end up in init_iterator with a null face cache, which should not
9444 init_frame_faces (f
);
9446 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
9447 window_prompting
= x_figure_window_size (f
, parms
);
9449 if (window_prompting
& XNegative
)
9451 if (window_prompting
& YNegative
)
9452 f
->output_data
.w32
->win_gravity
= SouthEastGravity
;
9454 f
->output_data
.w32
->win_gravity
= NorthEastGravity
;
9458 if (window_prompting
& YNegative
)
9459 f
->output_data
.w32
->win_gravity
= SouthWestGravity
;
9461 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9464 f
->output_data
.w32
->size_hint_flags
= window_prompting
;
9466 XSetWindowAttributes attrs
;
9470 mask
= CWBackPixel
| CWOverrideRedirect
| CWSaveUnder
| CWEventMask
;
9471 /* Window managers looks at the override-redirect flag to
9472 determine whether or net to give windows a decoration (Xlib
9474 attrs
.override_redirect
= True
;
9475 attrs
.save_under
= True
;
9476 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
9477 /* Arrange for getting MapNotify and UnmapNotify events. */
9478 attrs
.event_mask
= StructureNotifyMask
;
9480 = FRAME_W32_WINDOW (f
)
9481 = XCreateWindow (FRAME_W32_DISPLAY (f
),
9482 FRAME_W32_DISPLAY_INFO (f
)->root_window
,
9483 /* x, y, width, height */
9487 CopyFromParent
, InputOutput
, CopyFromParent
,
9494 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
9495 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9496 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
9497 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9498 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
9499 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
9501 /* Dimensions, especially f->height, must be done via change_frame_size.
9502 Change will not be effected unless different from the current
9507 SET_FRAME_WIDTH (f
, 0);
9508 change_frame_size (f
, height
, width
, 1, 0, 0);
9514 /* It is now ok to make the frame official even if we get an error
9515 below. And the frame needs to be on Vframe_list or making it
9516 visible won't work. */
9517 Vframe_list
= Fcons (frame
, Vframe_list
);
9519 /* Now that the frame is official, it counts as a reference to
9521 FRAME_W32_DISPLAY_INFO (f
)->reference_count
++;
9523 return unbind_to (count
, frame
);
9524 #endif /* MAC_TODO */
9529 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
9530 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
9531 A tooltip window is a small window displaying a string.
9533 FRAME nil or omitted means use the selected frame.
9535 PARMS is an optional list of frame parameters which can be used to
9536 change the tooltip's appearance.
9538 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
9539 means use the default timeout of 5 seconds.
9541 If the list of frame parameters PARAMS contains a `left' parameters,
9542 the tooltip is displayed at that x-position. Otherwise it is
9543 displayed at the mouse position, with offset DX added (default is 5 if
9544 DX isn't specified). Likewise for the y-position; if a `top' frame
9545 parameter is specified, it determines the y-position of the tooltip
9546 window, otherwise it is displayed at the mouse position, with offset
9547 DY added (default is 10). */)
9548 (string
, frame
, parms
, timeout
, dx
, dy
)
9549 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
9554 Lisp_Object buffer
, top
, left
;
9555 struct buffer
*old_buffer
;
9556 struct text_pos pos
;
9557 int i
, width
, height
;
9558 int root_x
, root_y
, win_x
, win_y
;
9560 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
9561 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
9562 int count
= specpdl_ptr
- specpdl
;
9564 specbind (Qinhibit_redisplay
, Qt
);
9566 GCPRO4 (string
, parms
, frame
, timeout
);
9568 CHECK_STRING (string
);
9569 f
= check_x_frame (frame
);
9571 timeout
= make_number (5);
9573 CHECK_NATNUM (timeout
);
9576 dx
= make_number (5);
9581 dy
= make_number (-10);
9585 if (NILP (last_show_tip_args
))
9586 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
9588 if (!NILP (tip_frame
))
9590 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
9591 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
9592 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
9594 if (EQ (frame
, last_frame
)
9595 && !NILP (Fequal (last_string
, string
))
9596 && !NILP (Fequal (last_parms
, parms
)))
9598 struct frame
*f
= XFRAME (tip_frame
);
9600 /* Only DX and DY have changed. */
9601 if (!NILP (tip_timer
))
9603 Lisp_Object timer
= tip_timer
;
9605 call1 (Qcancel_timer
, timer
);
9608 #if 0 /* MAC_TODO : Mac specifics */
9610 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
9611 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9612 root_x
, root_y
- PIXEL_HEIGHT (f
));
9614 #endif /* MAC_TODO */
9619 /* Hide a previous tip, if any. */
9622 ASET (last_show_tip_args
, 0, string
);
9623 ASET (last_show_tip_args
, 1, frame
);
9624 ASET (last_show_tip_args
, 2, parms
);
9626 /* Add default values to frame parameters. */
9627 if (NILP (Fassq (Qname
, parms
)))
9628 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
9629 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9630 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
9631 if (NILP (Fassq (Qborder_width
, parms
)))
9632 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
9633 if (NILP (Fassq (Qborder_color
, parms
)))
9634 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
9635 if (NILP (Fassq (Qbackground_color
, parms
)))
9636 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
9639 /* Create a frame for the tooltip, and record it in the global
9640 variable tip_frame. */
9641 frame
= x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f
), parms
);
9644 /* Set up the frame's root window. Currently we use a size of 80
9645 columns x 40 lines. If someone wants to show a larger tip, he
9646 will loose. I don't think this is a realistic case. */
9647 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
9648 w
->left
= w
->top
= make_number (0);
9649 w
->width
= make_number (80);
9650 w
->height
= make_number (40);
9652 w
->pseudo_window_p
= 1;
9654 /* Display the tooltip text in a temporary buffer. */
9655 buffer
= Fget_buffer_create (build_string (" *tip*"));
9656 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
);
9657 old_buffer
= current_buffer
;
9658 set_buffer_internal_1 (XBUFFER (buffer
));
9660 Finsert (1, &string
);
9661 clear_glyph_matrix (w
->desired_matrix
);
9662 clear_glyph_matrix (w
->current_matrix
);
9663 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
9664 try_window (FRAME_ROOT_WINDOW (f
), pos
);
9666 /* Compute width and height of the tooltip. */
9668 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
9670 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
9674 /* Stop at the first empty row at the end. */
9675 if (!row
->enabled_p
|| !row
->displays_text_p
)
9678 /* Let the row go over the full width of the frame. */
9679 row
->full_width_p
= 1;
9681 /* There's a glyph at the end of rows that is use to place
9682 the cursor there. Don't include the width of this glyph. */
9683 if (row
->used
[TEXT_AREA
])
9685 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
9686 row_width
= row
->pixel_width
- last
->pixel_width
;
9689 row_width
= row
->pixel_width
;
9691 height
+= row
->height
;
9692 width
= max (width
, row_width
);
9695 /* Add the frame's internal border to the width and height the X
9696 window should have. */
9697 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
9698 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
9700 /* Move the tooltip window where the mouse pointer is. Resize and
9702 #if 0 /* TODO : Mac specifics */
9703 compute_tip_xy (f
, parms
, dx
, dy
, &root_x
, &root_y
);
9706 XQueryPointer (FRAME_W32_DISPLAY (f
), FRAME_W32_DISPLAY_INFO (f
)->root_window
,
9707 &root
, &child
, &root_x
, &root_y
, &win_x
, &win_y
, &pmask
);
9708 XMoveResizeWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
9709 root_x
+ 5, root_y
- height
- 5, width
, height
);
9710 XMapRaised (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
9712 #endif /* MAC_TODO */
9714 /* Draw into the window. */
9715 w
->must_be_updated_p
= 1;
9716 update_single_window (w
, 1);
9718 /* Restore original current buffer. */
9719 set_buffer_internal_1 (old_buffer
);
9720 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
9723 /* Let the tip disappear after timeout seconds. */
9724 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
9725 intern ("x-hide-tip"));
9728 return unbind_to (count
, Qnil
);
9732 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
9733 doc
: /* Hide the current tooltip window, if there is any.
9734 Value is t is tooltip was open, nil otherwise. */)
9738 Lisp_Object deleted
, frame
, timer
;
9739 struct gcpro gcpro1
, gcpro2
;
9741 /* Return quickly if nothing to do. */
9742 if (NILP (tip_timer
) && NILP (tip_frame
))
9747 GCPRO2 (frame
, timer
);
9748 tip_frame
= tip_timer
= deleted
= Qnil
;
9750 count
= BINDING_STACK_SIZE ();
9751 specbind (Qinhibit_redisplay
, Qt
);
9752 specbind (Qinhibit_quit
, Qt
);
9755 call1 (Qcancel_timer
, timer
);
9759 Fdelete_frame (frame
, Qnil
);
9764 return unbind_to (count
, deleted
);
9769 /***********************************************************************
9770 File selection dialog
9771 ***********************************************************************/
9773 #if 0 /* MAC_TODO: can standard file dialog */
9774 extern Lisp_Object Qfile_name_history
;
9776 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
9777 doc
: /* Read file name, prompting with PROMPT in directory DIR.
9778 Use a file selection dialog.
9779 Select DEFAULT-FILENAME in the dialog's file selection box, if
9780 specified. Don't let the user enter a file name in the file
9781 selection dialog's entry field, if MUSTMATCH is non-nil. */)
9782 (prompt
, dir
, default_filename
, mustmatch
)
9783 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
9785 struct frame
*f
= SELECTED_FRAME ();
9786 Lisp_Object file
= Qnil
;
9787 int count
= specpdl_ptr
- specpdl
;
9788 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
9789 char filename
[MAX_PATH
+ 1];
9790 char init_dir
[MAX_PATH
+ 1];
9791 int use_dialog_p
= 1;
9793 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
9794 CHECK_STRING (prompt
);
9797 /* Create the dialog with PROMPT as title, using DIR as initial
9798 directory and using "*" as pattern. */
9799 dir
= Fexpand_file_name (dir
, Qnil
);
9800 strncpy (init_dir
, XSTRING (dir
)->data
, MAX_PATH
);
9801 init_dir
[MAX_PATH
] = '\0';
9802 unixtodos_filename (init_dir
);
9804 if (STRINGP (default_filename
))
9806 char *file_name_only
;
9807 char *full_path_name
= XSTRING (default_filename
)->data
;
9809 unixtodos_filename (full_path_name
);
9811 file_name_only
= strrchr (full_path_name
, '\\');
9812 if (!file_name_only
)
9813 file_name_only
= full_path_name
;
9818 /* If default_file_name is a directory, don't use the open
9819 file dialog, as it does not support selecting
9821 if (!(*file_name_only
))
9825 strncpy (filename
, file_name_only
, MAX_PATH
);
9826 filename
[MAX_PATH
] = '\0';
9833 OPENFILENAME file_details
;
9834 char *filename_file
;
9836 /* Prevent redisplay. */
9837 specbind (Qinhibit_redisplay
, Qt
);
9840 bzero (&file_details
, sizeof (file_details
));
9841 file_details
.lStructSize
= sizeof (file_details
);
9842 file_details
.hwndOwner
= FRAME_W32_WINDOW (f
);
9843 file_details
.lpstrFile
= filename
;
9844 file_details
.nMaxFile
= sizeof (filename
);
9845 file_details
.lpstrInitialDir
= init_dir
;
9846 file_details
.lpstrTitle
= XSTRING (prompt
)->data
;
9847 file_details
.Flags
= OFN_HIDEREADONLY
| OFN_NOCHANGEDIR
;
9849 if (!NILP (mustmatch
))
9850 file_details
.Flags
|= OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
;
9852 if (GetOpenFileName (&file_details
))
9854 dostounix_filename (filename
);
9855 file
= build_string (filename
);
9861 file
= unbind_to (count
, file
);
9863 /* Open File dialog will not allow folders to be selected, so resort
9864 to minibuffer completing reads for directories. */
9866 file
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
9867 dir
, mustmatch
, dir
, Qfile_name_history
,
9868 default_filename
, Qnil
);
9872 /* Make "Cancel" equivalent to C-g. */
9874 Fsignal (Qquit
, Qnil
);
9876 return unbind_to (count
, file
);
9878 #endif /* MAC_TODO */
9882 /***********************************************************************
9884 ***********************************************************************/
9888 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
9889 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
9893 return valid_image_p (spec
) ? Qt
: Qnil
;
9897 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
9903 if (valid_image_p (spec
))
9904 id
= lookup_image (SELECTED_FRAME (), spec
);
9907 return make_number (id
);
9910 #endif /* GLYPH_DEBUG != 0 */
9917 /* Certainly running on Mac. */
9920 /* The section below is built by the lisp expression at the top of the file,
9921 just above where these variables are declared. */
9922 /*&&& init symbols here &&&*/
9923 Qauto_raise
= intern ("auto-raise");
9924 staticpro (&Qauto_raise
);
9925 Qauto_lower
= intern ("auto-lower");
9926 staticpro (&Qauto_lower
);
9927 Qbar
= intern ("bar");
9929 Qborder_color
= intern ("border-color");
9930 staticpro (&Qborder_color
);
9931 Qborder_width
= intern ("border-width");
9932 staticpro (&Qborder_width
);
9933 Qbox
= intern ("box");
9935 Qcursor_color
= intern ("cursor-color");
9936 staticpro (&Qcursor_color
);
9937 Qcursor_type
= intern ("cursor-type");
9938 staticpro (&Qcursor_type
);
9939 Qgeometry
= intern ("geometry");
9940 staticpro (&Qgeometry
);
9941 Qicon_left
= intern ("icon-left");
9942 staticpro (&Qicon_left
);
9943 Qicon_top
= intern ("icon-top");
9944 staticpro (&Qicon_top
);
9945 Qicon_type
= intern ("icon-type");
9946 staticpro (&Qicon_type
);
9947 Qicon_name
= intern ("icon-name");
9948 staticpro (&Qicon_name
);
9949 Qinternal_border_width
= intern ("internal-border-width");
9950 staticpro (&Qinternal_border_width
);
9951 Qleft
= intern ("left");
9953 Qright
= intern ("right");
9954 staticpro (&Qright
);
9955 Qmouse_color
= intern ("mouse-color");
9956 staticpro (&Qmouse_color
);
9957 Qnone
= intern ("none");
9959 Qparent_id
= intern ("parent-id");
9960 staticpro (&Qparent_id
);
9961 Qscroll_bar_width
= intern ("scroll-bar-width");
9962 staticpro (&Qscroll_bar_width
);
9963 Qsuppress_icon
= intern ("suppress-icon");
9964 staticpro (&Qsuppress_icon
);
9965 Qundefined_color
= intern ("undefined-color");
9966 staticpro (&Qundefined_color
);
9967 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
9968 staticpro (&Qvertical_scroll_bars
);
9969 Qvisibility
= intern ("visibility");
9970 staticpro (&Qvisibility
);
9971 Qwindow_id
= intern ("window-id");
9972 staticpro (&Qwindow_id
);
9973 Qx_frame_parameter
= intern ("x-frame-parameter");
9974 staticpro (&Qx_frame_parameter
);
9975 Qx_resource_name
= intern ("x-resource-name");
9976 staticpro (&Qx_resource_name
);
9977 Quser_position
= intern ("user-position");
9978 staticpro (&Quser_position
);
9979 Quser_size
= intern ("user-size");
9980 staticpro (&Quser_size
);
9981 Qscreen_gamma
= intern ("screen-gamma");
9982 staticpro (&Qscreen_gamma
);
9983 Qline_spacing
= intern ("line-spacing");
9984 staticpro (&Qline_spacing
);
9985 Qcenter
= intern ("center");
9986 staticpro (&Qcenter
);
9987 /* This is the end of symbol initialization. */
9989 Qhyper
= intern ("hyper");
9990 staticpro (&Qhyper
);
9991 Qsuper
= intern ("super");
9992 staticpro (&Qsuper
);
9993 Qmeta
= intern ("meta");
9995 Qalt
= intern ("alt");
9997 Qctrl
= intern ("ctrl");
9999 Qcontrol
= intern ("control");
10000 staticpro (&Qcontrol
);
10001 Qshift
= intern ("shift");
10002 staticpro (&Qshift
);
10004 /* Text property `display' should be nonsticky by default. */
10005 Vtext_property_default_nonsticky
10006 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
10009 Qlaplace
= intern ("laplace");
10010 staticpro (&Qlaplace
);
10012 Qface_set_after_frame_default
= intern ("face-set-after-frame-default");
10013 staticpro (&Qface_set_after_frame_default
);
10015 Fput (Qundefined_color
, Qerror_conditions
,
10016 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
10017 Fput (Qundefined_color
, Qerror_message
,
10018 build_string ("Undefined color"));
10020 init_x_parm_symbols ();
10022 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
10023 doc
: /* List of directories to search for bitmap files for w32. */);
10024 Vx_bitmap_file_path
= decode_env_path ((char *) 0, "PATH");
10026 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
10027 doc
: /* The shape of the pointer when over text.
10028 Changing the value does not affect existing frames
10029 unless you set the mouse color. */);
10030 Vx_pointer_shape
= Qnil
;
10032 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
10033 doc
: /* The name Emacs uses to look up resources; for internal use only.
10034 `x-get-resource' uses this as the first component of the instance name
10035 when requesting resource values.
10036 Emacs initially sets `x-resource-name' to the name under which Emacs
10037 was invoked, or to the value specified with the `-name' or `-rn'
10038 switches, if present. */);
10039 Vx_resource_name
= Qnil
;
10041 Vx_nontext_pointer_shape
= Qnil
;
10043 Vx_mode_pointer_shape
= Qnil
;
10045 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10046 doc
: /* The shape of the pointer when Emacs is hourglass.
10047 This variable takes effect when you create a new frame
10048 or when you set the mouse color. */);
10049 Vx_hourglass_pointer_shape
= Qnil
;
10051 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10052 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10053 display_hourglass_p
= 1;
10055 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10056 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10057 Value must be an integer or float. */);
10058 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10060 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10061 &Vx_sensitive_text_pointer_shape
,
10062 doc
: /* The shape of the pointer when over mouse-sensitive text.
10063 This variable takes effect when you create a new frame
10064 or when you set the mouse color. */);
10065 Vx_sensitive_text_pointer_shape
= Qnil
;
10067 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
10068 doc
: /* A string indicating the foreground color of the cursor box. */);
10069 Vx_cursor_fore_pixel
= Qnil
;
10071 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
10072 doc
: /* Non-nil if no window manager is in use.
10073 Emacs doesn't try to figure this out; this is always nil
10074 unless you set it to something else. */);
10075 /* We don't have any way to find this out, so set it to nil
10076 and maybe the user would like to set it to t. */
10077 Vx_no_window_manager
= Qnil
;
10079 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10080 &Vx_pixel_size_width_font_regexp
,
10081 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10083 Since Emacs gets width of a font matching with this regexp from
10084 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10085 such a font. This is especially effective for such large fonts as
10086 Chinese, Japanese, and Korean. */);
10087 Vx_pixel_size_width_font_regexp
= Qnil
;
10089 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
10090 doc
: /* Time after which cached images are removed from the cache.
10091 When an image has not been displayed this many seconds, remove it
10092 from the image cache. Value must be an integer or nil with nil
10093 meaning don't clear the cache. */);
10094 Vimage_cache_eviction_delay
= make_number (30 * 60);
10096 #if 0 /* MAC_TODO: implement get X resource */
10097 defsubr (&Sx_get_resource
);
10099 defsubr (&Sx_change_window_property
);
10100 defsubr (&Sx_delete_window_property
);
10101 defsubr (&Sx_window_property
);
10102 defsubr (&Sxw_display_color_p
);
10103 defsubr (&Sx_display_grayscale_p
);
10104 defsubr (&Sxw_color_defined_p
);
10105 defsubr (&Sxw_color_values
);
10106 defsubr (&Sx_server_max_request_size
);
10107 defsubr (&Sx_server_vendor
);
10108 defsubr (&Sx_server_version
);
10109 defsubr (&Sx_display_pixel_width
);
10110 defsubr (&Sx_display_pixel_height
);
10111 defsubr (&Sx_display_mm_width
);
10112 defsubr (&Sx_display_mm_height
);
10113 defsubr (&Sx_display_screens
);
10114 defsubr (&Sx_display_planes
);
10115 defsubr (&Sx_display_color_cells
);
10116 defsubr (&Sx_display_visual_class
);
10117 defsubr (&Sx_display_backing_store
);
10118 defsubr (&Sx_display_save_under
);
10119 #if 0 /* MAC_TODO: implement XParseGeometry */
10120 defsubr (&Sx_parse_geometry
);
10122 defsubr (&Sx_create_frame
);
10123 #if 0 /* MAC_TODO: implement network support */
10124 defsubr (&Sx_open_connection
);
10125 defsubr (&Sx_close_connection
);
10127 defsubr (&Sx_display_list
);
10128 defsubr (&Sx_synchronize
);
10130 /* Setting callback functions for fontset handler. */
10131 get_font_info_func
= x_get_font_info
;
10133 #if 0 /* This function pointer doesn't seem to be used anywhere.
10134 And the pointer assigned has the wrong type, anyway. */
10135 list_fonts_func
= x_list_fonts
;
10138 load_font_func
= x_load_font
;
10139 find_ccl_program_func
= x_find_ccl_program
;
10140 query_font_func
= x_query_font
;
10142 set_frame_fontset_func
= x_set_font
;
10143 check_window_system_func
= check_mac
;
10145 #if 0 /* MAC_TODO: Image support for Mac Images. */
10146 Qxbm
= intern ("xbm");
10148 QCtype
= intern (":type");
10149 staticpro (&QCtype
);
10150 QCconversion
= intern (":conversion");
10151 staticpro (&QCconversion
);
10152 QCheuristic_mask
= intern (":heuristic-mask");
10153 staticpro (&QCheuristic_mask
);
10154 QCcolor_symbols
= intern (":color-symbols");
10155 staticpro (&QCcolor_symbols
);
10156 QCascent
= intern (":ascent");
10157 staticpro (&QCascent
);
10158 QCmargin
= intern (":margin");
10159 staticpro (&QCmargin
);
10160 QCrelief
= intern (":relief");
10161 staticpro (&QCrelief
);
10162 Qpostscript
= intern ("postscript");
10163 staticpro (&Qpostscript
);
10164 QCloader
= intern (":loader");
10165 staticpro (&QCloader
);
10166 QCbounding_box
= intern (":bounding-box");
10167 staticpro (&QCbounding_box
);
10168 QCpt_width
= intern (":pt-width");
10169 staticpro (&QCpt_width
);
10170 QCpt_height
= intern (":pt-height");
10171 staticpro (&QCpt_height
);
10172 QCindex
= intern (":index");
10173 staticpro (&QCindex
);
10174 Qpbm
= intern ("pbm");
10178 Qxpm
= intern ("xpm");
10183 Qjpeg
= intern ("jpeg");
10184 staticpro (&Qjpeg
);
10188 Qtiff
= intern ("tiff");
10189 staticpro (&Qtiff
);
10193 Qgif
= intern ("gif");
10198 Qpng
= intern ("png");
10202 defsubr (&Sclear_image_cache
);
10205 defsubr (&Simagep
);
10206 defsubr (&Slookup_image
);
10208 #endif /* MAC_TODO */
10210 hourglass_atimer
= NULL
;
10211 hourglass_shown_p
= 0;
10213 defsubr (&Sx_show_tip
);
10214 defsubr (&Sx_hide_tip
);
10215 staticpro (&tip_timer
);
10218 #if 0 /* MAC_TODO */
10219 defsubr (&Sx_file_dialog
);
10227 image_types
= NULL
;
10228 Vimage_types
= Qnil
;
10230 define_image_type (&xbm_type
);
10231 #if 0 /* NTEMACS_TODO : Image support for W32 */
10232 define_image_type (&gs_type
);
10233 define_image_type (&pbm_type
);
10236 define_image_type (&xpm_type
);
10240 define_image_type (&jpeg_type
);
10244 define_image_type (&tiff_type
);
10248 define_image_type (&gif_type
);
10252 define_image_type (&png_type
);
10254 #endif /* NTEMACS_TODO */