(easy-menu-intern):
[emacs.git] / src / macfns.c
blob401c7011feac9f4955ea3669cd714ff33f6ab139
1 /* Graphical user interface functions for Mac OS.
2 Copyright (C) 2000, 2001, 2004 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)
9 any later version.
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). */
23 #include <config.h>
25 #include <signal.h>
26 #include <stdio.h>
27 #include <math.h>
28 #include <limits.h>
29 #include <errno.h>
31 #include "lisp.h"
32 #include "charset.h"
33 #include "macterm.h"
34 #include "frame.h"
35 #include "window.h"
36 #include "buffer.h"
37 #include "dispextern.h"
38 #include "fontset.h"
39 #include "intervals.h"
40 #include "keyboard.h"
41 #include "blockinput.h"
42 #include "epaths.h"
43 #include "termhooks.h"
44 #include "coding.h"
45 #include "systime.h"
47 /* #include "bitmaps/gray.xbm" */
48 #define gray_width 2
49 #define gray_height 2
50 static unsigned char gray_bits[] = {
51 0x01, 0x02};
53 /*#include <commdlg.h>
54 #include <shellapi.h>*/
55 #include <ctype.h>
56 #include <sys/types.h>
57 #include <sys/stat.h>
59 #include <stdlib.h>
60 #include <string.h>
62 /*extern void free_frame_menubar ();
63 extern double atof ();
64 extern int w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state);
65 extern int quit_char;*/
67 extern char *lispy_function_keys[];
69 /* The gray bitmap `bitmaps/gray'. This is done because macterm.c uses
70 it, and including `bitmaps/gray' more than once is a problem when
71 config.h defines `static' as an empty replacement string. */
73 int gray_bitmap_width = gray_width;
74 int gray_bitmap_height = gray_height;
75 unsigned char *gray_bitmap_bits = gray_bits;
77 /* Non-zero means we're allowed to display an hourglass cursor. */
79 int display_hourglass_p;
81 /* The background and shape of the mouse pointer, and shape when not
82 over text or in the modeline. */
84 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
85 Lisp_Object Vx_hourglass_pointer_shape;
87 /* The shape when over mouse-sensitive text. */
89 Lisp_Object Vx_sensitive_text_pointer_shape;
91 /* If non-nil, the pointer shape to indicate that windows can be
92 dragged horizontally. */
94 Lisp_Object Vx_window_horizontal_drag_shape;
96 /* Color of chars displayed in cursor box. */
98 Lisp_Object Vx_cursor_fore_pixel;
100 /* Nonzero if using Windows. */
102 static int mac_in_use;
104 /* Non nil if no window manager is in use. */
106 Lisp_Object Vx_no_window_manager;
108 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
110 Lisp_Object Vx_pixel_size_width_font_regexp;
112 /* Evaluate this expression to rebuild the section of syms_of_macfns
113 that initializes and staticpros the symbols declared below. Note
114 that Emacs 18 has a bug that keeps C-x C-e from being able to
115 evaluate this expression.
117 (progn
118 ;; Accumulate a list of the symbols we want to initialize from the
119 ;; declarations at the top of the file.
120 (goto-char (point-min))
121 (search-forward "/\*&&& symbols declared here &&&*\/\n")
122 (let (symbol-list)
123 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
124 (setq symbol-list
125 (cons (buffer-substring (match-beginning 1) (match-end 1))
126 symbol-list))
127 (forward-line 1))
128 (setq symbol-list (nreverse symbol-list))
129 ;; Delete the section of syms_of_... where we initialize the symbols.
130 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
131 (let ((start (point)))
132 (while (looking-at "^ Q")
133 (forward-line 2))
134 (kill-region start (point)))
135 ;; Write a new symbol initialization section.
136 (while symbol-list
137 (insert (format " %s = intern (\"" (car symbol-list)))
138 (let ((start (point)))
139 (insert (substring (car symbol-list) 1))
140 (subst-char-in-region start (point) ?_ ?-))
141 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
142 (setq symbol-list (cdr symbol-list)))))
146 /*&&& symbols declared here &&&*/
147 Lisp_Object Qnone;
148 Lisp_Object Qsuppress_icon;
149 Lisp_Object Qundefined_color;
150 Lisp_Object Qcancel_timer;
151 Lisp_Object Qhyper;
152 Lisp_Object Qsuper;
153 Lisp_Object Qmeta;
154 Lisp_Object Qalt;
155 Lisp_Object Qctrl;
156 Lisp_Object Qcontrol;
157 Lisp_Object Qshift;
159 extern Lisp_Object Vwindow_system_version;
161 extern int mac_initialized;
164 /* compare two strings ignoring case */
166 static int
167 stricmp (const char *s, const char *t)
169 for ( ; tolower (*s) == tolower (*t); s++, t++)
170 if (*s == '\0')
171 return 0;
172 return tolower (*s) - tolower (*t);
175 /* compare two strings up to n characters, ignoring case */
177 static int
178 strnicmp (const char *s, const char *t, unsigned int n)
180 for ( ; n-- > 0 && tolower (*s) == tolower (*t); s++, t++)
181 if (*s == '\0')
182 return 0;
183 return n == 0 ? 0 : tolower (*s) - tolower (*t);
187 /* Error if we are not running on Mac OS. */
189 void
190 check_mac ()
192 if (! mac_in_use)
193 error ("Mac OS not in use or not initialized");
196 /* Nonzero if we can use mouse menus.
197 You should not call this unless HAVE_MENUS is defined. */
200 have_menus_p ()
202 return mac_in_use;
205 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
206 and checking validity for Mac. */
208 FRAME_PTR
209 check_x_frame (frame)
210 Lisp_Object frame;
212 FRAME_PTR f;
214 if (NILP (frame))
215 frame = selected_frame;
216 CHECK_LIVE_FRAME (frame);
217 f = XFRAME (frame);
218 if (! FRAME_MAC_P (f))
219 error ("non-mac frame used");
220 return f;
223 /* Let the user specify a display with a frame.
224 nil stands for the selected frame--or, if that is not a mac frame,
225 the first display on the list. */
227 struct mac_display_info *
228 check_x_display_info (frame)
229 Lisp_Object frame;
231 if (!mac_initialized)
233 mac_initialize ();
234 mac_initialized = 1;
237 if (NILP (frame))
239 struct frame *sf = XFRAME (selected_frame);
241 if (FRAME_MAC_P (sf) && FRAME_LIVE_P (sf))
242 return FRAME_MAC_DISPLAY_INFO (sf);
243 else
244 return &one_mac_display_info;
246 else if (STRINGP (frame))
247 return x_display_info_for_name (frame);
248 else
250 FRAME_PTR f;
252 CHECK_LIVE_FRAME (frame);
253 f = XFRAME (frame);
254 if (! FRAME_MAC_P (f))
255 error ("non-mac frame used");
256 return FRAME_MAC_DISPLAY_INFO (f);
260 /* Return the Emacs frame-object corresponding to a mac window.
261 It could be the frame's main window or an icon window. */
263 /* This function can be called during GC, so use GC_xxx type test macros. */
265 struct frame *
266 x_window_to_frame (dpyinfo, wdesc)
267 struct mac_display_info *dpyinfo;
268 WindowPtr wdesc;
270 Lisp_Object tail, frame;
271 struct frame *f;
273 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
275 frame = XCAR (tail);
276 if (!GC_FRAMEP (frame))
277 continue;
278 f = XFRAME (frame);
279 if (!FRAME_W32_P (f) || FRAME_MAC_DISPLAY_INFO (f) != dpyinfo)
280 continue;
281 /*if (f->output_data.w32->hourglass_window == wdesc)
282 return f;*/
284 /* MAC_TODO: Check tooltips when supported. */
285 if (FRAME_MAC_WINDOW (f) == wdesc)
286 return f;
288 return 0;
292 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
294 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
295 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
296 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
297 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
298 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
299 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
300 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
301 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
302 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
303 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
304 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
305 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
306 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
307 Lisp_Object));
308 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
309 Lisp_Object));
310 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
311 Lisp_Object,
312 Lisp_Object,
313 char *, char *,
314 int));
316 extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
318 /* Store the screen positions of frame F into XPTR and YPTR.
319 These are the positions of the containing window manager window,
320 not Emacs's own window. */
322 void
323 x_real_positions (f, xptr, yptr)
324 FRAME_PTR f;
325 int *xptr, *yptr;
327 Rect inner, outer;
329 mac_get_window_bounds (f, &inner, &outer);
331 f->x_pixels_diff = inner.left - outer.left;
332 f->y_pixels_diff = inner.top - outer.top;
334 *xptr = outer.left;
335 *yptr = outer.top;
339 /* The default colors for the Mac color map */
340 typedef struct colormap_t
342 unsigned long color;
343 char *name;
344 } colormap_t;
346 colormap_t mac_color_map[] =
348 { RGB_TO_ULONG(255, 250, 250), "snow" },
349 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
350 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
351 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
352 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
353 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
354 { RGB_TO_ULONG(255, 250, 240), "floral white" },
355 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
356 { RGB_TO_ULONG(253, 245, 230), "old lace" },
357 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
358 { RGB_TO_ULONG(250, 240, 230), "linen" },
359 { RGB_TO_ULONG(250, 235, 215), "antique white" },
360 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
361 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
362 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
363 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
364 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
365 { RGB_TO_ULONG(255, 228, 196), "bisque" },
366 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
367 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
368 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
369 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
370 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
371 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
372 { RGB_TO_ULONG(255, 255, 240), "ivory" },
373 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
374 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
375 { RGB_TO_ULONG(255, 245, 238), "seashell" },
376 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
377 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
378 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
379 { RGB_TO_ULONG(240, 255, 255), "azure" },
380 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
381 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
382 { RGB_TO_ULONG(230, 230, 250), "lavender" },
383 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
384 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
385 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
386 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
387 { RGB_TO_ULONG(255, 255, 255), "white" },
388 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
389 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
390 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
391 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
392 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
393 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
394 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
395 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
396 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
397 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
398 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
399 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
400 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
401 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
402 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
403 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
404 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
405 { RGB_TO_ULONG(190, 190, 190), "gray" },
406 { RGB_TO_ULONG(190, 190, 190), "grey" },
407 { RGB_TO_ULONG(211, 211, 211), "light grey" },
408 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
409 { RGB_TO_ULONG(211, 211, 211), "light gray" },
410 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
411 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
412 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
413 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
414 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
415 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
416 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
417 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
418 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
419 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
420 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
421 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
422 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
423 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
424 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
425 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
426 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
427 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
428 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
429 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
430 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
431 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
432 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
433 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
434 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
435 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
436 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
437 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
438 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
439 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
440 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
441 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
442 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
443 { RGB_TO_ULONG(173, 216, 230), "light blue" },
444 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
445 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
446 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
447 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
448 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
449 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
450 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
451 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
452 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
453 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
454 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
455 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
456 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
457 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
458 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
459 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
460 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
461 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
462 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
463 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
464 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
465 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
466 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
467 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
468 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
469 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
470 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
471 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
472 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
473 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
474 { RGB_TO_ULONG(152, 251, 152), "pale green" },
475 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
476 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
477 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
478 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
479 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
480 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
481 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
482 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
483 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
484 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
485 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
486 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
487 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
488 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
489 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
490 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
491 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
492 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
493 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
494 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
495 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
496 { RGB_TO_ULONG(240, 230, 140), "khaki" },
497 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
498 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
499 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
500 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
501 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
502 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
503 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
504 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
505 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
506 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
507 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
508 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
509 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
510 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
511 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
512 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
513 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
514 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
515 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
516 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
517 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
518 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
519 { RGB_TO_ULONG(245, 245, 220), "beige" },
520 { RGB_TO_ULONG(245, 222, 179), "wheat" },
521 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
522 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
523 { RGB_TO_ULONG(210, 180, 140), "tan" },
524 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
525 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
526 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
527 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
528 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
529 { RGB_TO_ULONG(250, 128, 114), "salmon" },
530 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
531 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
532 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
533 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
534 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
535 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
536 { RGB_TO_ULONG(240, 128, 128), "light coral" },
537 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
538 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
539 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
540 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
541 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
542 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
543 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
544 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
545 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
546 { RGB_TO_ULONG(255, 192, 203), "pink" },
547 { RGB_TO_ULONG(255, 182, 193), "light pink" },
548 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
549 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
550 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
551 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
552 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
553 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
554 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
555 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
556 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
557 { RGB_TO_ULONG(238, 130, 238), "violet" },
558 { RGB_TO_ULONG(221, 160, 221), "plum" },
559 { RGB_TO_ULONG(218, 112, 214), "orchid" },
560 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
561 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
562 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
563 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
564 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
565 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
566 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
567 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
568 { RGB_TO_ULONG(160, 32 , 240), "purple" },
569 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
570 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
571 { RGB_TO_ULONG(216, 191, 216), "thistle" },
572 { RGB_TO_ULONG(255, 250, 250), "snow1" },
573 { RGB_TO_ULONG(238, 233, 233), "snow2" },
574 { RGB_TO_ULONG(205, 201, 201), "snow3" },
575 { RGB_TO_ULONG(139, 137, 137), "snow4" },
576 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
577 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
578 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
579 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
580 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
581 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
582 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
583 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
584 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
585 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
586 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
587 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
588 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
589 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
590 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
591 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
592 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
593 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
594 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
595 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
596 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
597 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
598 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
599 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
600 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
601 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
602 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
603 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
604 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
605 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
606 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
607 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
608 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
609 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
610 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
611 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
612 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
613 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
614 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
615 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
616 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
617 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
618 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
619 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
620 { RGB_TO_ULONG(240, 255, 255), "azure1" },
621 { RGB_TO_ULONG(224, 238, 238), "azure2" },
622 { RGB_TO_ULONG(193, 205, 205), "azure3" },
623 { RGB_TO_ULONG(131, 139, 139), "azure4" },
624 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
625 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
626 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
627 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
628 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
629 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
630 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
631 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
632 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
633 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
634 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
635 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
636 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
637 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
638 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
639 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
640 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
641 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
642 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
643 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
644 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
645 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
646 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
647 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
648 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
649 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
650 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
651 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
652 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
653 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
654 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
655 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
656 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
657 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
658 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
659 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
660 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
661 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
662 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
663 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
664 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
665 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
666 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
667 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
668 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
669 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
670 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
671 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
672 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
673 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
674 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
675 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
676 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
677 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
678 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
679 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
680 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
681 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
682 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
683 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
684 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
685 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
686 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
687 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
688 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
689 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
690 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
691 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
692 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
693 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
694 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
695 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
696 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
697 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
698 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
699 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
700 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
701 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
702 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
703 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
704 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
705 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
706 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
707 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
708 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
709 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
710 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
711 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
712 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
713 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
714 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
715 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
716 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
717 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
718 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
719 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
720 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
721 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
722 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
723 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
724 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
725 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
726 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
727 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
728 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
729 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
730 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
731 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
732 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
733 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
734 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
735 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
736 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
737 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
738 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
739 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
740 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
741 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
742 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
743 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
744 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
745 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
746 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
747 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
748 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
749 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
750 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
751 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
752 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
753 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
754 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
755 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
756 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
757 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
758 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
759 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
760 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
761 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
762 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
763 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
764 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
765 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
766 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
767 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
768 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
769 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
770 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
771 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
772 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
773 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
774 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
775 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
776 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
777 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
778 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
779 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
780 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
781 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
782 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
783 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
784 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
785 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
786 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
787 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
788 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
789 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
790 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
791 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
792 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
793 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
794 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
795 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
796 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
797 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
798 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
799 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
800 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
801 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
802 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
803 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
804 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
805 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
806 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
807 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
808 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
809 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
810 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
811 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
812 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
813 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
814 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
815 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
816 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
817 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
818 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
819 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
820 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
821 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
822 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
823 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
824 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
825 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
826 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
827 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
828 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
829 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
830 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
831 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
832 { RGB_TO_ULONG(255, 181, 197), "pink1" },
833 { RGB_TO_ULONG(238, 169, 184), "pink2" },
834 { RGB_TO_ULONG(205, 145, 158), "pink3" },
835 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
836 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
837 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
838 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
839 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
840 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
841 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
842 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
843 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
844 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
845 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
846 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
847 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
848 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
849 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
850 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
851 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
852 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
853 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
854 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
855 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
856 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
857 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
858 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
859 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
860 { RGB_TO_ULONG(255, 187, 255), "plum1" },
861 { RGB_TO_ULONG(238, 174, 238), "plum2" },
862 { RGB_TO_ULONG(205, 150, 205), "plum3" },
863 { RGB_TO_ULONG(139, 102, 139), "plum4" },
864 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
865 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
866 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
867 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
868 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
869 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
870 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
871 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
872 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
873 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
874 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
875 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
876 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
877 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
878 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
879 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
880 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
881 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
882 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
883 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
884 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
885 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
886 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
887 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
888 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
889 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
890 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
891 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
892 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
893 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
894 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
895 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
896 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
897 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
898 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
899 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
900 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
901 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
902 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
903 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
904 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
905 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
906 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
907 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
908 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
909 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
910 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
911 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
912 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
913 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
914 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
915 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
916 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
917 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
918 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
919 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
920 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
921 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
922 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
923 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
924 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
925 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
926 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
927 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
928 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
929 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
930 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
931 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
932 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
933 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
934 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
935 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
936 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
937 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
938 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
939 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
940 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
941 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
942 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
943 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
944 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
945 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
946 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
947 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
948 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
949 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
950 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
951 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
952 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
953 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
954 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
955 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
956 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
957 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
958 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
959 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
960 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
961 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
962 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
963 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
964 { RGB_TO_ULONG(102, 102, 102), "gray40" },
965 { RGB_TO_ULONG(102, 102, 102), "grey40" },
966 { RGB_TO_ULONG(105, 105, 105), "gray41" },
967 { RGB_TO_ULONG(105, 105, 105), "grey41" },
968 { RGB_TO_ULONG(107, 107, 107), "gray42" },
969 { RGB_TO_ULONG(107, 107, 107), "grey42" },
970 { RGB_TO_ULONG(110, 110, 110), "gray43" },
971 { RGB_TO_ULONG(110, 110, 110), "grey43" },
972 { RGB_TO_ULONG(112, 112, 112), "gray44" },
973 { RGB_TO_ULONG(112, 112, 112), "grey44" },
974 { RGB_TO_ULONG(115, 115, 115), "gray45" },
975 { RGB_TO_ULONG(115, 115, 115), "grey45" },
976 { RGB_TO_ULONG(117, 117, 117), "gray46" },
977 { RGB_TO_ULONG(117, 117, 117), "grey46" },
978 { RGB_TO_ULONG(120, 120, 120), "gray47" },
979 { RGB_TO_ULONG(120, 120, 120), "grey47" },
980 { RGB_TO_ULONG(122, 122, 122), "gray48" },
981 { RGB_TO_ULONG(122, 122, 122), "grey48" },
982 { RGB_TO_ULONG(125, 125, 125), "gray49" },
983 { RGB_TO_ULONG(125, 125, 125), "grey49" },
984 { RGB_TO_ULONG(127, 127, 127), "gray50" },
985 { RGB_TO_ULONG(127, 127, 127), "grey50" },
986 { RGB_TO_ULONG(130, 130, 130), "gray51" },
987 { RGB_TO_ULONG(130, 130, 130), "grey51" },
988 { RGB_TO_ULONG(133, 133, 133), "gray52" },
989 { RGB_TO_ULONG(133, 133, 133), "grey52" },
990 { RGB_TO_ULONG(135, 135, 135), "gray53" },
991 { RGB_TO_ULONG(135, 135, 135), "grey53" },
992 { RGB_TO_ULONG(138, 138, 138), "gray54" },
993 { RGB_TO_ULONG(138, 138, 138), "grey54" },
994 { RGB_TO_ULONG(140, 140, 140), "gray55" },
995 { RGB_TO_ULONG(140, 140, 140), "grey55" },
996 { RGB_TO_ULONG(143, 143, 143), "gray56" },
997 { RGB_TO_ULONG(143, 143, 143), "grey56" },
998 { RGB_TO_ULONG(145, 145, 145), "gray57" },
999 { RGB_TO_ULONG(145, 145, 145), "grey57" },
1000 { RGB_TO_ULONG(148, 148, 148), "gray58" },
1001 { RGB_TO_ULONG(148, 148, 148), "grey58" },
1002 { RGB_TO_ULONG(150, 150, 150), "gray59" },
1003 { RGB_TO_ULONG(150, 150, 150), "grey59" },
1004 { RGB_TO_ULONG(153, 153, 153), "gray60" },
1005 { RGB_TO_ULONG(153, 153, 153), "grey60" },
1006 { RGB_TO_ULONG(156, 156, 156), "gray61" },
1007 { RGB_TO_ULONG(156, 156, 156), "grey61" },
1008 { RGB_TO_ULONG(158, 158, 158), "gray62" },
1009 { RGB_TO_ULONG(158, 158, 158), "grey62" },
1010 { RGB_TO_ULONG(161, 161, 161), "gray63" },
1011 { RGB_TO_ULONG(161, 161, 161), "grey63" },
1012 { RGB_TO_ULONG(163, 163, 163), "gray64" },
1013 { RGB_TO_ULONG(163, 163, 163), "grey64" },
1014 { RGB_TO_ULONG(166, 166, 166), "gray65" },
1015 { RGB_TO_ULONG(166, 166, 166), "grey65" },
1016 { RGB_TO_ULONG(168, 168, 168), "gray66" },
1017 { RGB_TO_ULONG(168, 168, 168), "grey66" },
1018 { RGB_TO_ULONG(171, 171, 171), "gray67" },
1019 { RGB_TO_ULONG(171, 171, 171), "grey67" },
1020 { RGB_TO_ULONG(173, 173, 173), "gray68" },
1021 { RGB_TO_ULONG(173, 173, 173), "grey68" },
1022 { RGB_TO_ULONG(176, 176, 176), "gray69" },
1023 { RGB_TO_ULONG(176, 176, 176), "grey69" },
1024 { RGB_TO_ULONG(179, 179, 179), "gray70" },
1025 { RGB_TO_ULONG(179, 179, 179), "grey70" },
1026 { RGB_TO_ULONG(181, 181, 181), "gray71" },
1027 { RGB_TO_ULONG(181, 181, 181), "grey71" },
1028 { RGB_TO_ULONG(184, 184, 184), "gray72" },
1029 { RGB_TO_ULONG(184, 184, 184), "grey72" },
1030 { RGB_TO_ULONG(186, 186, 186), "gray73" },
1031 { RGB_TO_ULONG(186, 186, 186), "grey73" },
1032 { RGB_TO_ULONG(189, 189, 189), "gray74" },
1033 { RGB_TO_ULONG(189, 189, 189), "grey74" },
1034 { RGB_TO_ULONG(191, 191, 191), "gray75" },
1035 { RGB_TO_ULONG(191, 191, 191), "grey75" },
1036 { RGB_TO_ULONG(194, 194, 194), "gray76" },
1037 { RGB_TO_ULONG(194, 194, 194), "grey76" },
1038 { RGB_TO_ULONG(196, 196, 196), "gray77" },
1039 { RGB_TO_ULONG(196, 196, 196), "grey77" },
1040 { RGB_TO_ULONG(199, 199, 199), "gray78" },
1041 { RGB_TO_ULONG(199, 199, 199), "grey78" },
1042 { RGB_TO_ULONG(201, 201, 201), "gray79" },
1043 { RGB_TO_ULONG(201, 201, 201), "grey79" },
1044 { RGB_TO_ULONG(204, 204, 204), "gray80" },
1045 { RGB_TO_ULONG(204, 204, 204), "grey80" },
1046 { RGB_TO_ULONG(207, 207, 207), "gray81" },
1047 { RGB_TO_ULONG(207, 207, 207), "grey81" },
1048 { RGB_TO_ULONG(209, 209, 209), "gray82" },
1049 { RGB_TO_ULONG(209, 209, 209), "grey82" },
1050 { RGB_TO_ULONG(212, 212, 212), "gray83" },
1051 { RGB_TO_ULONG(212, 212, 212), "grey83" },
1052 { RGB_TO_ULONG(214, 214, 214), "gray84" },
1053 { RGB_TO_ULONG(214, 214, 214), "grey84" },
1054 { RGB_TO_ULONG(217, 217, 217), "gray85" },
1055 { RGB_TO_ULONG(217, 217, 217), "grey85" },
1056 { RGB_TO_ULONG(219, 219, 219), "gray86" },
1057 { RGB_TO_ULONG(219, 219, 219), "grey86" },
1058 { RGB_TO_ULONG(222, 222, 222), "gray87" },
1059 { RGB_TO_ULONG(222, 222, 222), "grey87" },
1060 { RGB_TO_ULONG(224, 224, 224), "gray88" },
1061 { RGB_TO_ULONG(224, 224, 224), "grey88" },
1062 { RGB_TO_ULONG(227, 227, 227), "gray89" },
1063 { RGB_TO_ULONG(227, 227, 227), "grey89" },
1064 { RGB_TO_ULONG(229, 229, 229), "gray90" },
1065 { RGB_TO_ULONG(229, 229, 229), "grey90" },
1066 { RGB_TO_ULONG(232, 232, 232), "gray91" },
1067 { RGB_TO_ULONG(232, 232, 232), "grey91" },
1068 { RGB_TO_ULONG(235, 235, 235), "gray92" },
1069 { RGB_TO_ULONG(235, 235, 235), "grey92" },
1070 { RGB_TO_ULONG(237, 237, 237), "gray93" },
1071 { RGB_TO_ULONG(237, 237, 237), "grey93" },
1072 { RGB_TO_ULONG(240, 240, 240), "gray94" },
1073 { RGB_TO_ULONG(240, 240, 240), "grey94" },
1074 { RGB_TO_ULONG(242, 242, 242), "gray95" },
1075 { RGB_TO_ULONG(242, 242, 242), "grey95" },
1076 { RGB_TO_ULONG(245, 245, 245), "gray96" },
1077 { RGB_TO_ULONG(245, 245, 245), "grey96" },
1078 { RGB_TO_ULONG(247, 247, 247), "gray97" },
1079 { RGB_TO_ULONG(247, 247, 247), "grey97" },
1080 { RGB_TO_ULONG(250, 250, 250), "gray98" },
1081 { RGB_TO_ULONG(250, 250, 250), "grey98" },
1082 { RGB_TO_ULONG(252, 252, 252), "gray99" },
1083 { RGB_TO_ULONG(252, 252, 252), "grey99" },
1084 { RGB_TO_ULONG(255, 255, 255), "gray100" },
1085 { RGB_TO_ULONG(255, 255, 255), "grey100" },
1086 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
1087 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
1088 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
1089 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
1090 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
1091 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
1092 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
1093 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
1094 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
1095 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
1096 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
1097 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1098 { RGB_TO_ULONG(144, 238, 144), "light green" },
1099 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1102 Lisp_Object
1103 mac_color_map_lookup (colorname)
1104 char *colorname;
1106 Lisp_Object ret = Qnil;
1107 int i;
1109 BLOCK_INPUT;
1111 for (i = 0; i < sizeof (mac_color_map) / sizeof (mac_color_map[0]); i++)
1112 if (stricmp (colorname, mac_color_map[i].name) == 0)
1114 ret = make_number (mac_color_map[i].color);
1115 break;
1118 UNBLOCK_INPUT;
1120 return ret;
1123 Lisp_Object
1124 x_to_mac_color (colorname)
1125 char * colorname;
1127 register Lisp_Object tail, ret = Qnil;
1129 BLOCK_INPUT;
1131 if (colorname[0] == '#')
1133 /* Could be an old-style RGB Device specification. */
1134 char *color;
1135 int size;
1136 color = colorname + 1;
1138 size = strlen(color);
1139 if (size == 3 || size == 6 || size == 9 || size == 12)
1141 unsigned long colorval;
1142 int i, pos;
1143 pos = 16;
1144 size /= 3;
1145 colorval = 0;
1147 for (i = 0; i < 3; i++)
1149 char *end;
1150 char t;
1151 unsigned long value;
1153 /* The check for 'x' in the following conditional takes into
1154 account the fact that strtol allows a "0x" in front of
1155 our numbers, and we don't. */
1156 if (!isxdigit(color[0]) || color[1] == 'x')
1157 break;
1158 t = color[size];
1159 color[size] = '\0';
1160 value = strtoul(color, &end, 16);
1161 color[size] = t;
1162 if (errno == ERANGE || end - color != size)
1163 break;
1164 switch (size)
1166 case 1:
1167 value = value * 0x10;
1168 break;
1169 case 2:
1170 break;
1171 case 3:
1172 value /= 0x10;
1173 break;
1174 case 4:
1175 value /= 0x100;
1176 break;
1178 colorval |= (value << pos);
1179 pos -= 8;
1180 if (i == 2)
1182 UNBLOCK_INPUT;
1183 return make_number (colorval);
1185 color = end;
1189 else if (strnicmp(colorname, "rgb:", 4) == 0)
1191 char *color;
1192 unsigned long colorval;
1193 int i, pos;
1194 pos = 0;
1196 colorval = 0;
1197 color = colorname + 4;
1198 for (i = 0; i < 3; i++)
1200 char *end;
1201 unsigned long value;
1203 /* The check for 'x' in the following conditional takes into
1204 account the fact that strtol allows a "0x" in front of
1205 our numbers, and we don't. */
1206 if (!isxdigit(color[0]) || color[1] == 'x')
1207 break;
1208 value = strtoul(color, &end, 16);
1209 if (errno == ERANGE)
1210 break;
1211 switch (end - color)
1213 case 1:
1214 value = value * 0x10 + value;
1215 break;
1216 case 2:
1217 break;
1218 case 3:
1219 value /= 0x10;
1220 break;
1221 case 4:
1222 value /= 0x100;
1223 break;
1224 default:
1225 value = ULONG_MAX;
1227 if (value == ULONG_MAX)
1228 break;
1229 colorval |= (value << pos);
1230 pos += 0x8;
1231 if (i == 2)
1233 if (*end != '\0')
1234 break;
1235 UNBLOCK_INPUT;
1236 return make_number (colorval);
1238 if (*end != '/')
1239 break;
1240 color = end + 1;
1243 else if (strnicmp(colorname, "rgbi:", 5) == 0)
1245 /* This is an RGB Intensity specification. */
1246 char *color;
1247 unsigned long colorval;
1248 int i, pos;
1249 pos = 0;
1251 colorval = 0;
1252 color = colorname + 5;
1253 for (i = 0; i < 3; i++)
1255 char *end;
1256 double value;
1257 unsigned long val;
1259 value = strtod(color, &end);
1260 if (errno == ERANGE)
1261 break;
1262 if (value < 0.0 || value > 1.0)
1263 break;
1264 val = (unsigned long)(0x100 * value);
1265 /* We used 0x100 instead of 0xFF to give a continuous
1266 range between 0.0 and 1.0 inclusive. The next statement
1267 fixes the 1.0 case. */
1268 if (val == 0x100)
1269 val = 0xFF;
1270 colorval |= (val << pos);
1271 pos += 0x8;
1272 if (i == 2)
1274 if (*end != '\0')
1275 break;
1276 UNBLOCK_INPUT;
1277 return make_number (colorval);
1279 if (*end != '/')
1280 break;
1281 color = end + 1;
1285 ret = mac_color_map_lookup (colorname);
1287 UNBLOCK_INPUT;
1288 return ret;
1291 /* Gamma-correct COLOR on frame F. */
1293 void
1294 gamma_correct (f, color)
1295 struct frame *f;
1296 unsigned long *color;
1298 if (f->gamma)
1300 unsigned long red, green, blue;
1302 red = pow (RED_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1303 green = pow (GREEN_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1304 blue = pow (BLUE_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1305 *color = RGB_TO_ULONG (red, green, blue);
1309 /* Decide if color named COLOR is valid for the display associated
1310 with the selected frame; if so, return the rgb values in COLOR_DEF.
1311 If ALLOC is nonzero, allocate a new colormap cell. */
1314 mac_defined_color (f, color, color_def, alloc)
1315 FRAME_PTR f;
1316 char *color;
1317 XColor *color_def;
1318 int alloc;
1320 register Lisp_Object tem;
1321 unsigned long mac_color_ref;
1323 tem = x_to_mac_color (color);
1325 if (!NILP (tem))
1327 if (f)
1329 /* Apply gamma correction. */
1330 mac_color_ref = XUINT (tem);
1331 gamma_correct (f, &mac_color_ref);
1332 XSETINT (tem, mac_color_ref);
1335 color_def->pixel = mac_color_ref;
1336 color_def->red = RED16_FROM_ULONG (mac_color_ref);
1337 color_def->green = GREEN16_FROM_ULONG (mac_color_ref);
1338 color_def->blue = BLUE16_FROM_ULONG (mac_color_ref);
1340 return 1;
1342 else
1344 return 0;
1348 /* Given a string ARG naming a color, compute a pixel value from it
1349 suitable for screen F.
1350 If F is not a color screen, return DEF (default) regardless of what
1351 ARG says. */
1354 x_decode_color (f, arg, def)
1355 FRAME_PTR f;
1356 Lisp_Object arg;
1357 int def;
1359 XColor cdef;
1361 CHECK_STRING (arg);
1363 if (strcmp (SDATA (arg), "black") == 0)
1364 return BLACK_PIX_DEFAULT (f);
1365 else if (strcmp (SDATA (arg), "white") == 0)
1366 return WHITE_PIX_DEFAULT (f);
1368 #if 0
1369 if (FRAME_MAC_DISPLAY_INFO (f)->n_planes) == 1)
1370 return def;
1371 #endif
1373 if (mac_defined_color (f, SDATA (arg), &cdef, 1))
1374 return cdef.pixel;
1376 /* defined_color failed; return an ultimate default. */
1377 return def;
1380 /* Functions called only from `x_set_frame_param'
1381 to set individual parameters.
1383 If FRAME_MAC_WINDOW (f) is 0,
1384 the frame is being created and its window does not exist yet.
1385 In that case, just record the parameter's new value
1386 in the standard place; do not attempt to change the window. */
1388 void
1389 x_set_foreground_color (f, arg, oldval)
1390 struct frame *f;
1391 Lisp_Object arg, oldval;
1393 unsigned long fg, old_fg;
1395 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1396 old_fg = FRAME_FOREGROUND_PIXEL (f);
1397 FRAME_FOREGROUND_PIXEL (f) = fg;
1399 if (FRAME_MAC_WINDOW (f) != 0)
1401 update_face_from_frame_parameter (f, Qforeground_color, arg);
1402 if (FRAME_VISIBLE_P (f))
1403 redraw_frame (f);
1407 void
1408 x_set_background_color (f, arg, oldval)
1409 struct frame *f;
1410 Lisp_Object arg, oldval;
1412 FRAME_BACKGROUND_PIXEL (f)
1413 = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
1415 if (FRAME_MAC_WINDOW (f) != 0)
1417 update_face_from_frame_parameter (f, Qbackground_color, arg);
1419 if (FRAME_VISIBLE_P (f))
1420 redraw_frame (f);
1424 void
1425 x_set_mouse_color (f, arg, oldval)
1426 struct frame *f;
1427 Lisp_Object arg, oldval;
1429 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
1430 int count;
1431 int mask_color;
1433 if (!EQ (Qnil, arg))
1434 f->output_data.mac->mouse_pixel
1435 = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1436 mask_color = FRAME_BACKGROUND_PIXEL (f);
1438 /* Don't let pointers be invisible. */
1439 if (mask_color == f->output_data.mac->mouse_pixel
1440 && mask_color == FRAME_BACKGROUND_PIXEL (f))
1441 f->output_data.mac->mouse_pixel = FRAME_FOREGROUND_PIXEL (f);
1443 #if 0 /* MAC_TODO : cursor changes */
1444 BLOCK_INPUT;
1446 /* It's not okay to crash if the user selects a screwy cursor. */
1447 count = x_catch_errors (FRAME_W32_DISPLAY (f));
1449 if (!EQ (Qnil, Vx_pointer_shape))
1451 CHECK_NUMBER (Vx_pointer_shape);
1452 cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XINT (Vx_pointer_shape));
1454 else
1455 cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_xterm);
1456 x_check_errors (FRAME_W32_DISPLAY (f), "bad text pointer cursor: %s");
1458 if (!EQ (Qnil, Vx_nontext_pointer_shape))
1460 CHECK_NUMBER (Vx_nontext_pointer_shape);
1461 nontext_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1462 XINT (Vx_nontext_pointer_shape));
1464 else
1465 nontext_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_left_ptr);
1466 x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s");
1468 if (!EQ (Qnil, Vx_hourglass_pointer_shape))
1470 CHECK_NUMBER (Vx_hourglass_pointer_shape);
1471 hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1472 XINT (Vx_hourglass_pointer_shape));
1474 else
1475 hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_watch);
1476 x_check_errors (FRAME_W32_DISPLAY (f), "bad busy pointer cursor: %s");
1478 x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s");
1479 if (!EQ (Qnil, Vx_mode_pointer_shape))
1481 CHECK_NUMBER (Vx_mode_pointer_shape);
1482 mode_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1483 XINT (Vx_mode_pointer_shape));
1485 else
1486 mode_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_xterm);
1487 x_check_errors (FRAME_W32_DISPLAY (f), "bad modeline pointer cursor: %s");
1489 if (!EQ (Qnil, Vx_sensitive_text_pointer_shape))
1491 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1492 hand_cursor
1493 = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1494 XINT (Vx_sensitive_text_pointer_shape));
1496 else
1497 hand_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_crosshair);
1499 if (!NILP (Vx_window_horizontal_drag_shape))
1501 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1502 horizontal_drag_cursor
1503 = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1504 XINT (Vx_window_horizontal_drag_shape));
1506 else
1507 horizontal_drag_cursor
1508 = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_sb_h_double_arrow);
1510 /* Check and report errors with the above calls. */
1511 x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s");
1512 x_uncatch_errors (FRAME_W32_DISPLAY (f), count);
1515 XColor fore_color, back_color;
1517 fore_color.pixel = f->output_data.w32->mouse_pixel;
1518 back_color.pixel = mask_color;
1519 XQueryColor (FRAME_W32_DISPLAY (f),
1520 DefaultColormap (FRAME_W32_DISPLAY (f),
1521 DefaultScreen (FRAME_W32_DISPLAY (f))),
1522 &fore_color);
1523 XQueryColor (FRAME_W32_DISPLAY (f),
1524 DefaultColormap (FRAME_W32_DISPLAY (f),
1525 DefaultScreen (FRAME_W32_DISPLAY (f))),
1526 &back_color);
1527 XRecolorCursor (FRAME_W32_DISPLAY (f), cursor,
1528 &fore_color, &back_color);
1529 XRecolorCursor (FRAME_W32_DISPLAY (f), nontext_cursor,
1530 &fore_color, &back_color);
1531 XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor,
1532 &fore_color, &back_color);
1533 XRecolorCursor (FRAME_W32_DISPLAY (f), hand_cursor,
1534 &fore_color, &back_color);
1535 XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor,
1536 &fore_color, &back_color);
1539 if (FRAME_W32_WINDOW (f) != 0)
1540 XDefineCursor (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), cursor);
1542 if (cursor != f->output_data.w32->text_cursor && f->output_data.w32->text_cursor != 0)
1543 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->text_cursor);
1544 f->output_data.w32->text_cursor = cursor;
1546 if (nontext_cursor != f->output_data.w32->nontext_cursor
1547 && f->output_data.w32->nontext_cursor != 0)
1548 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->nontext_cursor);
1549 f->output_data.w32->nontext_cursor = nontext_cursor;
1551 if (hourglass_cursor != f->output_data.w32->hourglass_cursor
1552 && f->output_data.w32->hourglass_cursor != 0)
1553 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hourglass_cursor);
1554 f->output_data.w32->hourglass_cursor = hourglass_cursor;
1556 if (mode_cursor != f->output_data.w32->modeline_cursor
1557 && f->output_data.w32->modeline_cursor != 0)
1558 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->modeline_cursor);
1559 f->output_data.w32->modeline_cursor = mode_cursor;
1561 if (hand_cursor != f->output_data.w32->hand_cursor
1562 && f->output_data.w32->hand_cursor != 0)
1563 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hand_cursor);
1564 f->output_data.w32->hand_cursor = hand_cursor;
1566 XFlush (FRAME_W32_DISPLAY (f));
1567 UNBLOCK_INPUT;
1569 update_face_from_frame_parameter (f, Qmouse_color, arg);
1570 #endif /* MAC_TODO */
1573 void
1574 x_set_cursor_color (f, arg, oldval)
1575 struct frame *f;
1576 Lisp_Object arg, oldval;
1578 unsigned long fore_pixel, pixel;
1580 if (!NILP (Vx_cursor_fore_pixel))
1581 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1582 WHITE_PIX_DEFAULT (f));
1583 else
1584 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1586 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1588 /* Make sure that the cursor color differs from the background color. */
1589 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1591 pixel = f->output_data.mac->mouse_pixel;
1592 if (pixel == fore_pixel)
1593 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1596 f->output_data.mac->cursor_foreground_pixel = fore_pixel;
1597 f->output_data.mac->cursor_pixel = pixel;
1599 if (FRAME_MAC_WINDOW (f) != 0)
1601 BLOCK_INPUT;
1602 /* Update frame's cursor_gc. */
1603 f->output_data.mac->cursor_gc->foreground = fore_pixel;
1604 f->output_data.mac->cursor_gc->background = pixel;
1606 UNBLOCK_INPUT;
1608 if (FRAME_VISIBLE_P (f))
1610 x_update_cursor (f, 0);
1611 x_update_cursor (f, 1);
1615 update_face_from_frame_parameter (f, Qcursor_color, arg);
1618 /* Set the border-color of frame F to pixel value PIX.
1619 Note that this does not fully take effect if done before
1620 F has a window. */
1622 void
1623 x_set_border_pixel (f, pix)
1624 struct frame *f;
1625 int pix;
1628 f->output_data.mac->border_pixel = pix;
1630 if (FRAME_MAC_WINDOW (f) != 0 && f->border_width > 0)
1632 if (FRAME_VISIBLE_P (f))
1633 redraw_frame (f);
1637 /* Set the border-color of frame F to value described by ARG.
1638 ARG can be a string naming a color.
1639 The border-color is used for the border that is drawn by the server.
1640 Note that this does not fully take effect if done before
1641 F has a window; it must be redone when the window is created. */
1643 void
1644 x_set_border_color (f, arg, oldval)
1645 struct frame *f;
1646 Lisp_Object arg, oldval;
1648 int pix;
1650 CHECK_STRING (arg);
1651 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1652 x_set_border_pixel (f, pix);
1653 update_face_from_frame_parameter (f, Qborder_color, arg);
1657 void
1658 x_set_cursor_type (f, arg, oldval)
1659 FRAME_PTR f;
1660 Lisp_Object arg, oldval;
1662 set_frame_cursor_types (f, arg);
1664 /* Make sure the cursor gets redrawn. */
1665 cursor_type_changed = 1;
1668 #if 0 /* MAC_TODO: really no icon for Mac */
1669 void
1670 x_set_icon_type (f, arg, oldval)
1671 struct frame *f;
1672 Lisp_Object arg, oldval;
1674 int result;
1676 if (NILP (arg) && NILP (oldval))
1677 return;
1679 if (STRINGP (arg) && STRINGP (oldval)
1680 && EQ (Fstring_equal (oldval, arg), Qt))
1681 return;
1683 if (SYMBOLP (arg) && SYMBOLP (oldval) && EQ (arg, oldval))
1684 return;
1686 BLOCK_INPUT;
1688 result = x_bitmap_icon (f, arg);
1689 if (result)
1691 UNBLOCK_INPUT;
1692 error ("No icon window available");
1695 UNBLOCK_INPUT;
1697 #endif /* MAC_TODO */
1699 void
1700 x_set_icon_name (f, arg, oldval)
1701 struct frame *f;
1702 Lisp_Object arg, oldval;
1704 int result;
1706 if (STRINGP (arg))
1708 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1709 return;
1711 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1712 return;
1714 f->icon_name = arg;
1716 #if 0 /* MAC_TODO */
1717 if (f->output_data.w32->icon_bitmap != 0)
1718 return;
1720 BLOCK_INPUT;
1722 result = x_text_icon (f,
1723 (char *) SDATA ((!NILP (f->icon_name)
1724 ? f->icon_name
1725 : !NILP (f->title)
1726 ? f->title
1727 : f->name)));
1729 if (result)
1731 UNBLOCK_INPUT;
1732 error ("No icon window available");
1735 /* If the window was unmapped (and its icon was mapped),
1736 the new icon is not mapped, so map the window in its stead. */
1737 if (FRAME_VISIBLE_P (f))
1739 #ifdef USE_X_TOOLKIT
1740 XtPopup (f->output_data.w32->widget, XtGrabNone);
1741 #endif
1742 XMapWindow (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f));
1745 XFlush (FRAME_W32_DISPLAY (f));
1746 UNBLOCK_INPUT;
1747 #endif /* MAC_TODO */
1751 void
1752 x_set_menu_bar_lines (f, value, oldval)
1753 struct frame *f;
1754 Lisp_Object value, oldval;
1756 int nlines;
1757 int olines = FRAME_MENU_BAR_LINES (f);
1759 /* Right now, menu bars don't work properly in minibuf-only frames;
1760 most of the commands try to apply themselves to the minibuffer
1761 frame itself, and get an error because you can't switch buffers
1762 in or split the minibuffer window. */
1763 if (FRAME_MINIBUF_ONLY_P (f))
1764 return;
1766 if (INTEGERP (value))
1767 nlines = XINT (value);
1768 else
1769 nlines = 0;
1771 FRAME_MENU_BAR_LINES (f) = 0;
1772 if (nlines)
1773 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1774 else
1776 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1777 free_frame_menubar (f);
1778 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1780 /* Adjust the frame size so that the client (text) dimensions
1781 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
1782 set correctly. */
1783 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
1784 do_pending_window_change (0);
1786 adjust_glyphs (f);
1790 /* Set the number of lines used for the tool bar of frame F to VALUE.
1791 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1792 is the old number of tool bar lines. This function changes the
1793 height of all windows on frame F to match the new tool bar height.
1794 The frame's height doesn't change. */
1796 void
1797 x_set_tool_bar_lines (f, value, oldval)
1798 struct frame *f;
1799 Lisp_Object value, oldval;
1801 int delta, nlines, root_height;
1802 Lisp_Object root_window;
1804 /* Treat tool bars like menu bars. */
1805 if (FRAME_MINIBUF_ONLY_P (f))
1806 return;
1808 /* Use VALUE only if an integer >= 0. */
1809 if (INTEGERP (value) && XINT (value) >= 0)
1810 nlines = XFASTINT (value);
1811 else
1812 nlines = 0;
1814 /* Make sure we redisplay all windows in this frame. */
1815 ++windows_or_buffers_changed;
1817 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1819 /* Don't resize the tool-bar to more than we have room for. */
1820 root_window = FRAME_ROOT_WINDOW (f);
1821 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1822 if (root_height - delta < 1)
1824 delta = root_height - 1;
1825 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1828 FRAME_TOOL_BAR_LINES (f) = nlines;
1829 change_window_heights (root_window, delta);
1830 adjust_glyphs (f);
1832 /* We also have to make sure that the internal border at the top of
1833 the frame, below the menu bar or tool bar, is redrawn when the
1834 tool bar disappears. This is so because the internal border is
1835 below the tool bar if one is displayed, but is below the menu bar
1836 if there isn't a tool bar. The tool bar draws into the area
1837 below the menu bar. */
1838 if (FRAME_MAC_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1840 updating_frame = f;
1841 clear_frame ();
1842 clear_current_matrices (f);
1843 updating_frame = NULL;
1846 /* If the tool bar gets smaller, the internal border below it
1847 has to be cleared. It was formerly part of the display
1848 of the larger tool bar, and updating windows won't clear it. */
1849 if (delta < 0)
1851 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1852 int width = FRAME_PIXEL_WIDTH (f);
1853 int y = nlines * FRAME_LINE_HEIGHT (f);
1855 BLOCK_INPUT;
1856 XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
1857 0, y, width, height, 0);
1858 UNBLOCK_INPUT;
1860 if (WINDOWP (f->tool_bar_window))
1861 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1866 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1867 w32_id_name.
1869 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1870 name; if NAME is a string, set F's name to NAME and set
1871 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1873 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1874 suggesting a new name, which lisp code should override; if
1875 F->explicit_name is set, ignore the new name; otherwise, set it. */
1877 void
1878 x_set_name (f, name, explicit)
1879 struct frame *f;
1880 Lisp_Object name;
1881 int explicit;
1883 /* Make sure that requests from lisp code override requests from
1884 Emacs redisplay code. */
1885 if (explicit)
1887 /* If we're switching from explicit to implicit, we had better
1888 update the mode lines and thereby update the title. */
1889 if (f->explicit_name && NILP (name))
1890 update_mode_lines = 1;
1892 f->explicit_name = ! NILP (name);
1894 else if (f->explicit_name)
1895 return;
1897 /* If NAME is nil, set the name to the w32_id_name. */
1898 if (NILP (name))
1900 /* Check for no change needed in this very common case
1901 before we do any consing. */
1902 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name,
1903 SDATA (f->name)))
1904 return;
1905 name = build_string (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name);
1907 else
1908 CHECK_STRING (name);
1910 /* Don't change the name if it's already NAME. */
1911 if (! NILP (Fstring_equal (name, f->name)))
1912 return;
1914 f->name = name;
1916 /* For setting the frame title, the title parameter should override
1917 the name parameter. */
1918 if (! NILP (f->title))
1919 name = f->title;
1921 if (FRAME_MAC_WINDOW (f))
1923 if (STRING_MULTIBYTE (name))
1924 #if TARGET_API_MAC_CARBON
1925 name = ENCODE_UTF_8 (name);
1926 #else
1927 return;
1928 #endif
1930 BLOCK_INPUT;
1933 #if TARGET_API_MAC_CARBON
1934 CFStringRef windowTitle =
1935 CFStringCreateWithCString (NULL, SDATA (name),
1936 kCFStringEncodingUTF8);
1938 SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle);
1939 CFRelease (windowTitle);
1940 #else
1941 Str255 windowTitle;
1942 if (strlen (SDATA (name)) < 255)
1944 strcpy (windowTitle, SDATA (name));
1945 c2pstr (windowTitle);
1946 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
1948 #endif
1951 UNBLOCK_INPUT;
1955 /* This function should be called when the user's lisp code has
1956 specified a name for the frame; the name will override any set by the
1957 redisplay code. */
1958 void
1959 x_explicitly_set_name (f, arg, oldval)
1960 FRAME_PTR f;
1961 Lisp_Object arg, oldval;
1963 x_set_name (f, arg, 1);
1966 /* This function should be called by Emacs redisplay code to set the
1967 name; names set this way will never override names set by the user's
1968 lisp code. */
1969 void
1970 x_implicitly_set_name (f, arg, oldval)
1971 FRAME_PTR f;
1972 Lisp_Object arg, oldval;
1974 x_set_name (f, arg, 0);
1977 /* Change the title of frame F to NAME.
1978 If NAME is nil, use the frame name as the title.
1980 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1981 name; if NAME is a string, set F's name to NAME and set
1982 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1984 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1985 suggesting a new name, which lisp code should override; if
1986 F->explicit_name is set, ignore the new name; otherwise, set it. */
1988 void
1989 x_set_title (f, name, old_name)
1990 struct frame *f;
1991 Lisp_Object name, old_name;
1993 /* Don't change the title if it's already NAME. */
1994 if (EQ (name, f->title))
1995 return;
1997 update_mode_lines = 1;
1999 f->title = name;
2001 if (NILP (name))
2002 name = f->name;
2004 if (FRAME_MAC_WINDOW (f))
2006 if (STRING_MULTIBYTE (name))
2007 #if TARGET_API_MAC_CARBON
2008 name = ENCODE_UTF_8 (name);
2009 #else
2010 return;
2011 #endif
2013 BLOCK_INPUT;
2016 #if TARGET_API_MAC_CARBON
2017 CFStringRef windowTitle =
2018 CFStringCreateWithCString (NULL, SDATA (name),
2019 kCFStringEncodingUTF8);
2021 SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle);
2022 CFRelease (windowTitle);
2023 #else
2024 Str255 windowTitle;
2025 if (strlen (SDATA (name)) < 255)
2027 strcpy (windowTitle, SDATA (name));
2028 c2pstr (windowTitle);
2029 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
2031 #endif
2034 UNBLOCK_INPUT;
2038 void
2039 x_set_scroll_bar_default_width (f)
2040 struct frame *f;
2042 /* Imitate X without X Toolkit */
2044 int wid = FRAME_COLUMN_WIDTH (f);
2046 #ifdef MAC_OSX
2047 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 16; /* Aqua scroll bars. */
2048 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
2049 wid - 1) / wid;
2050 #else /* not MAC_OSX */
2051 /* Make the actual width at least 14 pixels and a multiple of a
2052 character width. */
2053 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
2055 /* Use all of that space (aside from required margins) for the
2056 scroll bar. */
2057 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
2058 #endif /* not MAC_OSX */
2062 /* Subroutines of creating a frame. */
2064 char *
2065 x_get_string_resource (rdb, name, class)
2066 XrmDatabase rdb;
2067 char *name, *class;
2069 /* MAC_TODO: implement resource strings */
2070 return (char *)0;
2073 /* Return the value of parameter PARAM.
2075 First search ALIST, then Vdefault_frame_alist, then the X defaults
2076 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2078 Convert the resource to the type specified by desired_type.
2080 If no default is specified, return Qunbound. If you call
2081 mac_get_arg, make sure you deal with Qunbound in a reasonable way,
2082 and don't let it get stored in any Lisp-visible variables! */
2084 static Lisp_Object
2085 mac_get_arg (alist, param, attribute, class, type)
2086 Lisp_Object alist, param;
2087 char *attribute;
2088 char *class;
2089 enum resource_types type;
2091 return x_get_arg (check_x_display_info (Qnil),
2092 alist, param, attribute, class, type);
2096 /* XParseGeometry copied from w32xfns.c */
2099 * XParseGeometry parses strings of the form
2100 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
2101 * width, height, xoffset, and yoffset are unsigned integers.
2102 * Example: "=80x24+300-49"
2103 * The equal sign is optional.
2104 * It returns a bitmask that indicates which of the four values
2105 * were actually found in the string. For each value found,
2106 * the corresponding argument is updated; for each value
2107 * not found, the corresponding argument is left unchanged.
2110 static int
2111 read_integer (string, NextString)
2112 register char *string;
2113 char **NextString;
2115 register int Result = 0;
2116 int Sign = 1;
2118 if (*string == '+')
2119 string++;
2120 else if (*string == '-')
2122 string++;
2123 Sign = -1;
2125 for (; (*string >= '0') && (*string <= '9'); string++)
2127 Result = (Result * 10) + (*string - '0');
2129 *NextString = string;
2130 if (Sign >= 0)
2131 return (Result);
2132 else
2133 return (-Result);
2137 XParseGeometry (string, x, y, width, height)
2138 char *string;
2139 int *x, *y;
2140 unsigned int *width, *height; /* RETURN */
2142 int mask = NoValue;
2143 register char *strind;
2144 unsigned int tempWidth, tempHeight;
2145 int tempX, tempY;
2146 char *nextCharacter;
2148 if ((string == NULL) || (*string == '\0')) return (mask);
2149 if (*string == '=')
2150 string++; /* ignore possible '=' at beg of geometry spec */
2152 strind = (char *)string;
2153 if (*strind != '+' && *strind != '-' && *strind != 'x')
2155 tempWidth = read_integer (strind, &nextCharacter);
2156 if (strind == nextCharacter)
2157 return (0);
2158 strind = nextCharacter;
2159 mask |= WidthValue;
2162 if (*strind == 'x' || *strind == 'X')
2164 strind++;
2165 tempHeight = read_integer (strind, &nextCharacter);
2166 if (strind == nextCharacter)
2167 return (0);
2168 strind = nextCharacter;
2169 mask |= HeightValue;
2172 if ((*strind == '+') || (*strind == '-'))
2174 if (*strind == '-')
2176 strind++;
2177 tempX = -read_integer (strind, &nextCharacter);
2178 if (strind == nextCharacter)
2179 return (0);
2180 strind = nextCharacter;
2181 mask |= XNegative;
2184 else
2186 strind++;
2187 tempX = read_integer (strind, &nextCharacter);
2188 if (strind == nextCharacter)
2189 return (0);
2190 strind = nextCharacter;
2192 mask |= XValue;
2193 if ((*strind == '+') || (*strind == '-'))
2195 if (*strind == '-')
2197 strind++;
2198 tempY = -read_integer (strind, &nextCharacter);
2199 if (strind == nextCharacter)
2200 return (0);
2201 strind = nextCharacter;
2202 mask |= YNegative;
2205 else
2207 strind++;
2208 tempY = read_integer (strind, &nextCharacter);
2209 if (strind == nextCharacter)
2210 return (0);
2211 strind = nextCharacter;
2213 mask |= YValue;
2217 /* If strind isn't at the end of the string the it's an invalid
2218 geometry specification. */
2220 if (*strind != '\0') return (0);
2222 if (mask & XValue)
2223 *x = tempX;
2224 if (mask & YValue)
2225 *y = tempY;
2226 if (mask & WidthValue)
2227 *width = tempWidth;
2228 if (mask & HeightValue)
2229 *height = tempHeight;
2230 return (mask);
2234 #if 0 /* MAC_TODO */
2235 /* Create and set up the Mac window for frame F. */
2237 static void
2238 mac_window (f, window_prompting, minibuffer_only)
2239 struct frame *f;
2240 long window_prompting;
2241 int minibuffer_only;
2243 Rect r;
2245 BLOCK_INPUT;
2247 /* Use the resource name as the top-level window name
2248 for looking up resources. Make a non-Lisp copy
2249 for the window manager, so GC relocation won't bother it.
2251 Elsewhere we specify the window name for the window manager. */
2254 char *str = (char *) SDATA (Vx_resource_name);
2255 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2256 strcpy (f->namebuf, str);
2259 SetRect (&r, f->left_pos, f->top_pos,
2260 f->left_pos + FRAME_PIXEL_WIDTH (f),
2261 f->top_pos + FRAME_PIXEL_HEIGHT (f));
2262 FRAME_MAC_WINDOW (f)
2263 = NewCWindow (NULL, &r, "\p", 1, zoomDocProc, (WindowPtr) -1, 1, (long) f->output_data.mac);
2265 validate_x_resource_name ();
2267 /* x_set_name normally ignores requests to set the name if the
2268 requested name is the same as the current name. This is the one
2269 place where that assumption isn't correct; f->name is set, but
2270 the server hasn't been told. */
2272 Lisp_Object name;
2273 int explicit = f->explicit_name;
2275 f->explicit_name = 0;
2276 name = f->name;
2277 f->name = Qnil;
2278 x_set_name (f, name, explicit);
2281 ShowWindow (FRAME_MAC_WINDOW (f));
2283 UNBLOCK_INPUT;
2285 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
2286 initialize_frame_menubar (f);
2288 if (FRAME_MAC_WINDOW (f) == 0)
2289 error ("Unable to create window");
2291 #endif /* MAC_TODO */
2293 /* Handle the icon stuff for this window. Perhaps later we might
2294 want an x_set_icon_position which can be called interactively as
2295 well. */
2297 static void
2298 x_icon (f, parms)
2299 struct frame *f;
2300 Lisp_Object parms;
2302 Lisp_Object icon_x, icon_y;
2304 /* Set the position of the icon. Note that Windows 95 groups all
2305 icons in the tray. */
2306 icon_x = mac_get_arg (parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2307 icon_y = mac_get_arg (parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2308 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2310 CHECK_NUMBER (icon_x);
2311 CHECK_NUMBER (icon_y);
2313 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2314 error ("Both left and top icon corners of icon must be specified");
2316 BLOCK_INPUT;
2318 if (! EQ (icon_x, Qunbound))
2319 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2321 #if 0 /* TODO */
2322 /* Start up iconic or window? */
2323 x_wm_set_window_state
2324 (f, (EQ (w32_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL), Qicon)
2325 ? IconicState
2326 : NormalState));
2328 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2329 ? f->icon_name
2330 : f->name)));
2331 #endif
2333 UNBLOCK_INPUT;
2337 void
2338 x_make_gc (f)
2339 struct frame *f;
2341 XGCValues gc_values;
2343 BLOCK_INPUT;
2345 /* Create the GCs of this frame.
2346 Note that many default values are used. */
2348 /* Normal video */
2349 gc_values.font = FRAME_FONT (f);
2350 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2351 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2352 f->output_data.mac->normal_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2353 FRAME_MAC_WINDOW (f),
2354 GCFont | GCForeground | GCBackground,
2355 &gc_values);
2357 /* Reverse video style. */
2358 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2359 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2360 f->output_data.mac->reverse_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2361 FRAME_MAC_WINDOW (f),
2362 GCFont | GCForeground | GCBackground,
2363 &gc_values);
2365 /* Cursor has cursor-color background, background-color foreground. */
2366 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2367 gc_values.background = f->output_data.mac->cursor_pixel;
2368 f->output_data.mac->cursor_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2369 FRAME_MAC_WINDOW (f),
2370 GCFont | GCForeground | GCBackground,
2371 &gc_values);
2373 /* Reliefs. */
2374 f->output_data.mac->white_relief.gc = 0;
2375 f->output_data.mac->black_relief.gc = 0;
2377 #if 0
2378 /* Create the gray border tile used when the pointer is not in
2379 the frame. Since this depends on the frame's pixel values,
2380 this must be done on a per-frame basis. */
2381 f->output_data.x->border_tile
2382 = (XCreatePixmapFromBitmapData
2383 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2384 gray_bits, gray_width, gray_height,
2385 f->output_data.x->foreground_pixel,
2386 f->output_data.x->background_pixel,
2387 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2388 #endif
2390 UNBLOCK_INPUT;
2394 /* Free what was was allocated in x_make_gc. */
2396 void
2397 x_free_gcs (f)
2398 struct frame *f;
2400 Display *dpy = FRAME_MAC_DISPLAY (f);
2402 BLOCK_INPUT;
2404 if (f->output_data.mac->normal_gc)
2406 XFreeGC (dpy, f->output_data.mac->normal_gc);
2407 f->output_data.mac->normal_gc = 0;
2410 if (f->output_data.mac->reverse_gc)
2412 XFreeGC (dpy, f->output_data.mac->reverse_gc);
2413 f->output_data.mac->reverse_gc = 0;
2416 if (f->output_data.mac->cursor_gc)
2418 XFreeGC (dpy, f->output_data.mac->cursor_gc);
2419 f->output_data.mac->cursor_gc = 0;
2422 #if 0
2423 if (f->output_data.mac->border_tile)
2425 XFreePixmap (dpy, f->output_data.mac->border_tile);
2426 f->output_data.mac->border_tile = 0;
2428 #endif
2430 if (f->output_data.mac->white_relief.gc)
2432 XFreeGC (dpy, f->output_data.mac->white_relief.gc);
2433 f->output_data.mac->white_relief.gc = 0;
2436 if (f->output_data.mac->black_relief.gc)
2438 XFreeGC (dpy, f->output_data.mac->black_relief.gc);
2439 f->output_data.mac->black_relief.gc = 0;
2442 UNBLOCK_INPUT;
2446 /* Handler for signals raised during x_create_frame and
2447 x_create_top_frame. FRAME is the frame which is partially
2448 constructed. */
2450 static Lisp_Object
2451 unwind_create_frame (frame)
2452 Lisp_Object frame;
2454 struct frame *f = XFRAME (frame);
2456 /* If frame is ``official'', nothing to do. */
2457 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
2459 #if GLYPH_DEBUG
2460 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2461 #endif
2463 x_free_frame_resources (f);
2465 /* Check that reference counts are indeed correct. */
2466 xassert (dpyinfo->reference_count == dpyinfo_refcount);
2467 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
2468 return Qt;
2471 return Qnil;
2475 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2476 1, 1, 0,
2477 doc: /* Make a new window, which is called a \"frame\" in Emacs terms.
2478 Returns an Emacs frame object.
2479 ALIST is an alist of frame parameters.
2480 If the parameters specify that the frame should not have a minibuffer,
2481 and do not specify a specific minibuffer window to use,
2482 then `default-minibuffer-frame' must be a frame whose minibuffer can
2483 be shared by the new frame.
2485 This function is an internal primitive--use `make-frame' instead. */)
2486 (parms)
2487 Lisp_Object parms;
2489 struct frame *f;
2490 Lisp_Object frame, tem;
2491 Lisp_Object name;
2492 int minibuffer_only = 0;
2493 long window_prompting = 0;
2494 int width, height;
2495 int count = SPECPDL_INDEX ();
2496 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2497 Lisp_Object display;
2498 struct mac_display_info *dpyinfo = NULL;
2499 Lisp_Object parent;
2500 struct kboard *kb;
2501 char x_frame_name[10];
2502 static int x_frame_count = 2; /* begins at 2 because terminal frame is F1 */
2504 check_mac ();
2506 /* Use this general default value to start with
2507 until we know if this frame has a specified name. */
2508 Vx_resource_name = Vinvocation_name;
2510 display = mac_get_arg (parms, Qdisplay, 0, 0, RES_TYPE_STRING);
2511 if (EQ (display, Qunbound))
2512 display = Qnil;
2513 dpyinfo = check_x_display_info (display);
2514 #ifdef MULTI_KBOARD
2515 kb = dpyinfo->kboard;
2516 #else
2517 kb = &the_only_kboard;
2518 #endif
2520 name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
2521 if (!STRINGP (name)
2522 && ! EQ (name, Qunbound)
2523 && ! NILP (name))
2524 error ("Invalid frame name--not a string or nil");
2526 if (STRINGP (name))
2527 Vx_resource_name = name;
2529 /* See if parent window is specified. */
2530 parent = mac_get_arg (parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
2531 if (EQ (parent, Qunbound))
2532 parent = Qnil;
2533 if (! NILP (parent))
2534 CHECK_NUMBER (parent);
2536 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2537 /* No need to protect DISPLAY because that's not used after passing
2538 it to make_frame_without_minibuffer. */
2539 frame = Qnil;
2540 GCPRO4 (parms, parent, name, frame);
2541 tem = mac_get_arg (parms, Qminibuffer, "minibuffer", "Minibuffer",
2542 RES_TYPE_SYMBOL);
2543 if (EQ (tem, Qnone) || NILP (tem))
2544 f = make_frame_without_minibuffer (Qnil, kb, display);
2545 else if (EQ (tem, Qonly))
2547 f = make_minibuffer_frame ();
2548 minibuffer_only = 1;
2550 else if (WINDOWP (tem))
2551 f = make_frame_without_minibuffer (tem, kb, display);
2552 else
2553 f = make_frame (1);
2555 if (EQ (name, Qunbound) || NILP (name))
2557 sprintf (x_frame_name, "F%d", x_frame_count++);
2558 f->name = build_string (x_frame_name);
2559 f->explicit_name = 0;
2561 else
2563 f->name = name;
2564 f->explicit_name = 1;
2567 XSETFRAME (frame, f);
2569 /* Note that X Windows does support scroll bars. */
2570 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
2572 f->output_method = output_mac;
2573 f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output));
2574 bzero (f->output_data.mac, sizeof (struct mac_output));
2575 FRAME_FONTSET (f) = -1;
2576 record_unwind_protect (unwind_create_frame, frame);
2578 f->icon_name
2579 = mac_get_arg (parms, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
2580 if (! STRINGP (f->icon_name))
2581 f->icon_name = Qnil;
2583 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
2584 #ifdef MULTI_KBOARD
2585 FRAME_KBOARD (f) = kb;
2586 #endif
2588 /* Specify the parent under which to make this window. */
2590 if (!NILP (parent))
2592 f->output_data.mac->parent_desc = (Window) XFASTINT (parent);
2593 f->output_data.mac->explicit_parent = 1;
2595 else
2597 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
2598 f->output_data.mac->explicit_parent = 0;
2601 /* Set the name; the functions to which we pass f expect the name to
2602 be set. */
2603 if (EQ (name, Qunbound) || NILP (name))
2605 f->name = build_string (dpyinfo->mac_id_name);
2606 f->explicit_name = 0;
2608 else
2610 f->name = name;
2611 f->explicit_name = 1;
2612 /* use the frame's title when getting resources for this frame. */
2613 specbind (Qx_resource_name, name);
2616 /* Extract the window parameters from the supplied values
2617 that are needed to determine window geometry. */
2619 Lisp_Object font;
2621 font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
2623 BLOCK_INPUT;
2624 /* First, try whatever font the caller has specified. */
2625 if (STRINGP (font))
2627 tem = Fquery_fontset (font, Qnil);
2628 if (STRINGP (tem))
2629 font = x_new_fontset (f, SDATA (tem));
2630 else
2631 font = x_new_font (f, SDATA (font));
2634 /* Try out a font which we hope has bold and italic variations. */
2635 if (! STRINGP (font))
2636 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
2637 /* If those didn't work, look for something which will at least work. */
2638 if (! STRINGP (font))
2639 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
2640 if (! STRINGP (font))
2641 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
2642 if (! STRINGP (font))
2643 error ("Cannot find any usable font");
2644 UNBLOCK_INPUT;
2646 x_default_parameter (f, parms, Qfont, font,
2647 "font", "Font", RES_TYPE_STRING);
2650 x_default_parameter (f, parms, Qborder_width, make_number (0),
2651 "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
2652 /* This defaults to 2 in order to match xterm. We recognize either
2653 internalBorderWidth or internalBorder (which is what xterm calls
2654 it). */
2655 if (NILP (Fassq (Qinternal_border_width, parms)))
2657 Lisp_Object value;
2659 value = mac_get_arg (parms, Qinternal_border_width,
2660 "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
2661 if (! EQ (value, Qunbound))
2662 parms = Fcons (Fcons (Qinternal_border_width, value),
2663 parms);
2665 /* Default internalBorderWidth to 0 on Windows to match other programs. */
2666 x_default_parameter (f, parms, Qinternal_border_width, make_number (0),
2667 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
2668 x_default_parameter (f, parms, Qvertical_scroll_bars, Qright,
2669 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
2671 /* Also do the stuff which must be set before the window exists. */
2672 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
2673 "foreground", "Foreground", RES_TYPE_STRING);
2674 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
2675 "background", "Background", RES_TYPE_STRING);
2676 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
2677 "pointerColor", "Foreground", RES_TYPE_STRING);
2678 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
2679 "cursorColor", "Foreground", RES_TYPE_STRING);
2680 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
2681 "borderColor", "BorderColor", RES_TYPE_STRING);
2682 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
2683 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
2684 x_default_parameter (f, parms, Qline_spacing, Qnil,
2685 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
2686 x_default_parameter (f, parms, Qleft_fringe, Qnil,
2687 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
2688 x_default_parameter (f, parms, Qright_fringe, Qnil,
2689 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
2692 /* Init faces before x_default_parameter is called for scroll-bar
2693 parameters because that function calls x_set_scroll_bar_width,
2694 which calls change_frame_size, which calls Fset_window_buffer,
2695 which runs hooks, which call Fvertical_motion. At the end, we
2696 end up in init_iterator with a null face cache, which should not
2697 happen. */
2698 init_frame_faces (f);
2700 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
2701 "menuBar", "MenuBar", RES_TYPE_NUMBER);
2702 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
2703 "toolBar", "ToolBar", RES_TYPE_NUMBER);
2704 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
2705 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
2706 x_default_parameter (f, parms, Qtitle, Qnil,
2707 "title", "Title", RES_TYPE_STRING);
2709 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
2711 #if TARGET_API_MAC_CARBON
2712 f->output_data.mac->text_cursor = kThemeIBeamCursor;
2713 f->output_data.mac->nontext_cursor = kThemeArrowCursor;
2714 f->output_data.mac->modeline_cursor = kThemeArrowCursor;
2715 f->output_data.mac->hand_cursor = kThemePointingHandCursor;
2716 f->output_data.mac->hourglass_cursor = kThemeWatchCursor;
2717 f->output_data.mac->horizontal_drag_cursor = kThemeResizeLeftRightCursor;
2718 #else
2719 f->output_data.mac->text_cursor = GetCursor (iBeamCursor);
2720 f->output_data.mac->nontext_cursor = &arrow_cursor;
2721 f->output_data.mac->modeline_cursor = &arrow_cursor;
2722 f->output_data.mac->hand_cursor = &arrow_cursor;
2723 f->output_data.mac->hourglass_cursor = GetCursor (watchCursor);
2724 f->output_data.mac->horizontal_drag_cursor = &arrow_cursor;
2725 #endif
2727 /* Compute the size of the window. */
2728 window_prompting = x_figure_window_size (f, parms, 1);
2730 tem = mac_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
2731 f->no_split = minibuffer_only || EQ (tem, Qt);
2733 /* mac_window (f, window_prompting, minibuffer_only); */
2734 make_mac_frame (f);
2736 x_icon (f, parms);
2737 x_make_gc (f);
2739 /* Now consider the frame official. */
2740 FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
2741 Vframe_list = Fcons (frame, Vframe_list);
2743 /* We need to do this after creating the window, so that the
2744 icon-creation functions can say whose icon they're describing. */
2745 x_default_parameter (f, parms, Qicon_type, Qnil,
2746 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
2748 x_default_parameter (f, parms, Qauto_raise, Qnil,
2749 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2750 x_default_parameter (f, parms, Qauto_lower, Qnil,
2751 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2752 x_default_parameter (f, parms, Qcursor_type, Qbox,
2753 "cursorType", "CursorType", RES_TYPE_SYMBOL);
2754 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
2755 "scrollBarWidth", "ScrollBarWidth",
2756 RES_TYPE_NUMBER);
2758 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
2759 Change will not be effected unless different from the current
2760 FRAME_LINES (f). */
2761 width = FRAME_COLS (f);
2762 height = FRAME_LINES (f);
2764 SET_FRAME_COLS (f, 0);
2765 FRAME_LINES (f) = 0;
2766 change_frame_size (f, height, width, 1, 0, 0);
2768 #if 0 /* MAC_TODO: when we have window manager hints */
2769 /* Tell the server what size and position, etc, we want, and how
2770 badly we want them. This should be done after we have the menu
2771 bar so that its size can be taken into account. */
2772 BLOCK_INPUT;
2773 x_wm_set_size_hint (f, window_prompting, 0);
2774 UNBLOCK_INPUT;
2775 #endif
2777 /* Make the window appear on the frame and enable display, unless
2778 the caller says not to. However, with explicit parent, Emacs
2779 cannot control visibility, so don't try. */
2780 if (! f->output_data.mac->explicit_parent)
2782 Lisp_Object visibility;
2784 visibility = mac_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
2785 if (EQ (visibility, Qunbound))
2786 visibility = Qt;
2788 #if 0 /* MAC_TODO: really no iconify on Mac */
2789 if (EQ (visibility, Qicon))
2790 x_iconify_frame (f);
2791 else
2792 #endif
2793 if (! NILP (visibility))
2794 x_make_frame_visible (f);
2795 else
2796 /* Must have been Qnil. */
2799 UNGCPRO;
2801 /* Make sure windows on this frame appear in calls to next-window
2802 and similar functions. */
2803 Vwindow_list = Qnil;
2805 return unbind_to (count, frame);
2808 /* FRAME is used only to get a handle on the X display. We don't pass the
2809 display info directly because we're called from frame.c, which doesn't
2810 know about that structure. */
2811 Lisp_Object
2812 x_get_focus_frame (frame)
2813 struct frame *frame;
2815 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
2816 Lisp_Object xfocus;
2817 if (! dpyinfo->x_focus_frame)
2818 return Qnil;
2820 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
2821 return xfocus;
2824 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
2825 doc: /* Internal function called by `color-defined-p', which see. */)
2826 (color, frame)
2827 Lisp_Object color, frame;
2829 XColor foo;
2830 FRAME_PTR f = check_x_frame (frame);
2832 CHECK_STRING (color);
2834 if (mac_defined_color (f, SDATA (color), &foo, 0))
2835 return Qt;
2836 else
2837 return Qnil;
2840 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2841 doc: /* Internal function called by `color-values', which see. */)
2842 (color, frame)
2843 Lisp_Object color, frame;
2845 XColor foo;
2846 FRAME_PTR f = check_x_frame (frame);
2848 CHECK_STRING (color);
2850 if (mac_defined_color (f, SDATA (color), &foo, 0))
2852 Lisp_Object rgb[3];
2854 rgb[0] = make_number (foo.red);
2855 rgb[1] = make_number (foo.green);
2856 rgb[2] = make_number (foo.blue);
2857 return Flist (3, rgb);
2859 else
2860 return Qnil;
2863 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2864 doc: /* Internal function called by `display-color-p', which see. */)
2865 (display)
2866 Lisp_Object display;
2868 struct mac_display_info *dpyinfo = check_x_display_info (display);
2870 if (!dpyinfo->color_p)
2871 return Qnil;
2873 return Qt;
2876 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
2877 0, 1, 0,
2878 doc: /* Return t if the X display supports shades of gray.
2879 Note that color displays do support shades of gray.
2880 The optional argument DISPLAY specifies which display to ask about.
2881 DISPLAY should be either a frame or a display name (a string).
2882 If omitted or nil, that stands for the selected frame's display. */)
2883 (display)
2884 Lisp_Object display;
2886 struct mac_display_info *dpyinfo = check_x_display_info (display);
2888 if (dpyinfo->n_planes <= 1)
2889 return Qnil;
2891 return Qt;
2894 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2895 0, 1, 0,
2896 doc: /* Returns the width in pixels of the X display DISPLAY.
2897 The optional argument DISPLAY specifies which display to ask about.
2898 DISPLAY should be either a frame or a display name (a string).
2899 If omitted or nil, that stands for the selected frame's display. */)
2900 (display)
2901 Lisp_Object display;
2903 struct mac_display_info *dpyinfo = check_x_display_info (display);
2905 return make_number (dpyinfo->width);
2908 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2909 Sx_display_pixel_height, 0, 1, 0,
2910 doc: /* Returns the height in pixels of the X display DISPLAY.
2911 The optional argument DISPLAY specifies which display to ask about.
2912 DISPLAY should be either a frame or a display name (a string).
2913 If omitted or nil, that stands for the selected frame's display. */)
2914 (display)
2915 Lisp_Object display;
2917 struct mac_display_info *dpyinfo = check_x_display_info (display);
2919 return make_number (dpyinfo->height);
2922 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2923 0, 1, 0,
2924 doc: /* Returns the number of bitplanes of the display DISPLAY.
2925 The optional argument DISPLAY specifies which display to ask about.
2926 DISPLAY should be either a frame or a display name (a string).
2927 If omitted or nil, that stands for the selected frame's display. */)
2928 (display)
2929 Lisp_Object display;
2931 struct mac_display_info *dpyinfo = check_x_display_info (display);
2933 return make_number (dpyinfo->n_planes);
2936 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2937 0, 1, 0,
2938 doc: /* Returns the number of color cells of the display DISPLAY.
2939 The optional argument DISPLAY specifies which display to ask about.
2940 DISPLAY should be either a frame or a display name (a string).
2941 If omitted or nil, that stands for the selected frame's display. */)
2942 (display)
2943 Lisp_Object display;
2945 struct mac_display_info *dpyinfo = check_x_display_info (display);
2947 /* We force 24+ bit depths to 24-bit to prevent an overflow. */
2948 return make_number (1 << min (dpyinfo->n_planes, 24));
2951 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
2952 Sx_server_max_request_size,
2953 0, 1, 0,
2954 doc: /* Returns the maximum request size of the server of display DISPLAY.
2955 The optional argument DISPLAY specifies which display to ask about.
2956 DISPLAY should be either a frame or a display name (a string).
2957 If omitted or nil, that stands for the selected frame's display. */)
2958 (display)
2959 Lisp_Object display;
2961 struct mac_display_info *dpyinfo = check_x_display_info (display);
2963 return make_number (1);
2966 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
2967 doc: /* Returns the vendor ID string of the Mac OS system (Apple).
2968 The optional argument DISPLAY specifies which display to ask about.
2969 DISPLAY should be either a frame or a display name (a string).
2970 If omitted or nil, that stands for the selected frame's display. */)
2971 (display)
2972 Lisp_Object display;
2974 return build_string ("Apple Computers");
2977 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
2978 doc: /* Returns the version numbers of the server of display DISPLAY.
2979 The value is a list of three integers: the major and minor
2980 version numbers, and the vendor-specific release
2981 number. See also the function `x-server-vendor'.
2983 The optional argument DISPLAY specifies which display to ask about.
2984 DISPLAY should be either a frame or a display name (a string).
2985 If omitted or nil, that stands for the selected frame's display. */)
2986 (display)
2987 Lisp_Object display;
2989 int mac_major_version;
2990 SInt32 response;
2992 if (Gestalt (gestaltSystemVersion, &response) != noErr)
2993 error ("Cannot get Mac OS version");
2995 mac_major_version = (response >> 8) & 0xff;
2996 /* convert BCD to int */
2997 mac_major_version -= (mac_major_version >> 4) * 6;
2999 return Fcons (make_number (mac_major_version),
3000 Fcons (make_number ((response >> 4) & 0xf),
3001 Fcons (make_number (response & 0xf),
3002 Qnil)));
3005 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3006 doc: /* Return the number of screens on the server of display DISPLAY.
3007 The optional argument DISPLAY specifies which display to ask about.
3008 DISPLAY should be either a frame or a display name (a string).
3009 If omitted or nil, that stands for the selected frame's display. */)
3010 (display)
3011 Lisp_Object display;
3013 return make_number (1);
3016 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3017 doc: /* Return the height in millimeters of the X display DISPLAY.
3018 The optional argument DISPLAY specifies which display to ask about.
3019 DISPLAY should be either a frame or a display name (a string).
3020 If omitted or nil, that stands for the selected frame's display. */)
3021 (display)
3022 Lisp_Object display;
3024 /* MAC_TODO: this is an approximation, and only of the main display */
3026 struct mac_display_info *dpyinfo = check_x_display_info (display);
3028 return make_number ((int) (dpyinfo->height * 25.4 / dpyinfo->resy));
3031 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3032 doc: /* Return the width in millimeters of the X display DISPLAY.
3033 The optional argument DISPLAY specifies which display to ask about.
3034 DISPLAY should be either a frame or a display name (a string).
3035 If omitted or nil, that stands for the selected frame's display. */)
3036 (display)
3037 Lisp_Object display;
3039 /* MAC_TODO: this is an approximation, and only of the main display */
3041 struct mac_display_info *dpyinfo = check_x_display_info (display);
3043 return make_number ((int) (dpyinfo->width * 25.4 / dpyinfo->resx));
3046 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3047 Sx_display_backing_store, 0, 1, 0,
3048 doc: /* Returns an indication of whether display DISPLAY does backing store.
3049 The value may be `always', `when-mapped', or `not-useful'.
3050 The optional argument DISPLAY specifies which display to ask about.
3051 DISPLAY should be either a frame or a display name (a string).
3052 If omitted or nil, that stands for the selected frame's display. */)
3053 (display)
3054 Lisp_Object display;
3056 return intern ("not-useful");
3059 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3060 Sx_display_visual_class, 0, 1, 0,
3061 doc: /* Returns the visual class of the display DISPLAY.
3062 The value is one of the symbols `static-gray', `gray-scale',
3063 `static-color', `pseudo-color', `true-color', or `direct-color'.
3065 The optional argument DISPLAY specifies which display to ask about.
3066 DISPLAY should be either a frame or a display name (a string).
3067 If omitted or nil, that stands for the selected frame's display. */)
3068 (display)
3069 Lisp_Object display;
3071 struct mac_display_info *dpyinfo = check_x_display_info (display);
3073 #if 0
3074 switch (dpyinfo->visual->class)
3076 case StaticGray: return (intern ("static-gray"));
3077 case GrayScale: return (intern ("gray-scale"));
3078 case StaticColor: return (intern ("static-color"));
3079 case PseudoColor: return (intern ("pseudo-color"));
3080 case TrueColor: return (intern ("true-color"));
3081 case DirectColor: return (intern ("direct-color"));
3082 default:
3083 error ("Display has an unknown visual class");
3085 #endif /* 0 */
3087 return (intern ("true-color"));
3090 DEFUN ("x-display-save-under", Fx_display_save_under,
3091 Sx_display_save_under, 0, 1, 0,
3092 doc: /* Returns t if the display DISPLAY supports the save-under feature.
3093 The optional argument DISPLAY specifies which display to ask about.
3094 DISPLAY should be either a frame or a display name (a string).
3095 If omitted or nil, that stands for the selected frame's display. */)
3096 (display)
3097 Lisp_Object display;
3099 return Qnil;
3103 x_pixel_width (f)
3104 register struct frame *f;
3106 return FRAME_PIXEL_WIDTH (f);
3110 x_pixel_height (f)
3111 register struct frame *f;
3113 return FRAME_PIXEL_HEIGHT (f);
3117 x_char_width (f)
3118 register struct frame *f;
3120 return FRAME_COLUMN_WIDTH (f);
3124 x_char_height (f)
3125 register struct frame *f;
3127 return FRAME_LINE_HEIGHT (f);
3131 x_screen_planes (f)
3132 register struct frame *f;
3134 return FRAME_MAC_DISPLAY_INFO (f)->n_planes;
3137 /* Return the display structure for the display named NAME.
3138 Open a new connection if necessary. */
3140 struct mac_display_info *
3141 x_display_info_for_name (name)
3142 Lisp_Object name;
3144 Lisp_Object names;
3145 struct mac_display_info *dpyinfo;
3147 CHECK_STRING (name);
3149 for (dpyinfo = &one_mac_display_info, names = x_display_name_list;
3150 dpyinfo;
3151 dpyinfo = dpyinfo->next, names = XCDR (names))
3153 Lisp_Object tem;
3154 tem = Fstring_equal (XCAR (XCAR (names)), name);
3155 if (!NILP (tem))
3156 return dpyinfo;
3159 /* Use this general default value to start with. */
3160 Vx_resource_name = Vinvocation_name;
3162 validate_x_resource_name ();
3164 dpyinfo = mac_term_init (name, (unsigned char *) 0,
3165 (char *) SDATA (Vx_resource_name));
3167 if (dpyinfo == 0)
3168 error ("Cannot connect to server %s", SDATA (name));
3170 mac_in_use = 1;
3171 XSETFASTINT (Vwindow_system_version, 3);
3173 return dpyinfo;
3176 #if 0 /* MAC_TODO: implement network support */
3177 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
3178 1, 3, 0,
3179 doc: /* Open a connection to a server.
3180 DISPLAY is the name of the display to connect to.
3181 Optional second arg XRM-STRING is a string of resources in xrdb format.
3182 If the optional third arg MUST-SUCCEED is non-nil,
3183 terminate Emacs if we can't open the connection. */)
3184 (display, xrm_string, must_succeed)
3185 Lisp_Object display, xrm_string, must_succeed;
3187 unsigned char *xrm_option;
3188 struct mac_display_info *dpyinfo;
3190 CHECK_STRING (display);
3191 if (! NILP (xrm_string))
3192 CHECK_STRING (xrm_string);
3194 if (! EQ (Vwindow_system, intern ("mac")))
3195 error ("Not using Mac OS");
3197 if (! NILP (xrm_string))
3198 xrm_option = (unsigned char *) SDATA (xrm_string);
3199 else
3200 xrm_option = (unsigned char *) 0;
3202 validate_x_resource_name ();
3204 /* This is what opens the connection and sets x_current_display.
3205 This also initializes many symbols, such as those used for input. */
3206 dpyinfo = mac_term_init (display, xrm_option,
3207 (char *) SDATA (Vx_resource_name));
3209 if (dpyinfo == 0)
3211 if (!NILP (must_succeed))
3212 fatal ("Cannot connect to server %s.\n",
3213 SDATA (display));
3214 else
3215 error ("Cannot connect to server %s", SDATA (display));
3218 mac_in_use = 1;
3220 XSETFASTINT (Vwindow_system_version, 3);
3221 return Qnil;
3224 DEFUN ("x-close-connection", Fx_close_connection,
3225 Sx_close_connection, 1, 1, 0,
3226 doc: /* Close the connection to DISPLAY's server.
3227 For DISPLAY, specify either a frame or a display name (a string).
3228 If DISPLAY is nil, that stands for the selected frame's display. */)
3229 (display)
3230 Lisp_Object display;
3232 struct mac_display_info *dpyinfo = check_x_display_info (display);
3233 int i;
3235 if (dpyinfo->reference_count > 0)
3236 error ("Display still has frames on it");
3238 BLOCK_INPUT;
3239 /* Free the fonts in the font table. */
3240 for (i = 0; i < dpyinfo->n_fonts; i++)
3241 if (dpyinfo->font_table[i].name)
3243 if (dpyinfo->font_table[i].name != dpyinfo->font_table[i].full_name)
3244 xfree (dpyinfo->font_table[i].full_name);
3245 xfree (dpyinfo->font_table[i].name);
3246 x_unload_font (dpyinfo, dpyinfo->font_table[i].font);
3248 x_destroy_all_bitmaps (dpyinfo);
3250 x_delete_display (dpyinfo);
3251 UNBLOCK_INPUT;
3253 return Qnil;
3255 #endif /* 0 */
3257 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
3258 doc: /* Return the list of display names that Emacs has connections to. */)
3261 Lisp_Object tail, result;
3263 result = Qnil;
3264 for (tail = x_display_name_list; ! NILP (tail); tail = XCDR (tail))
3265 result = Fcons (XCAR (XCAR (tail)), result);
3267 return result;
3270 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
3271 doc: /* If ON is non-nil, report errors as soon as the erring request is made.
3272 If ON is nil, allow buffering of requests.
3273 This is a noop on Mac OS systems.
3274 The optional second argument DISPLAY specifies which display to act on.
3275 DISPLAY should be either a frame or a display name (a string).
3276 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
3277 (on, display)
3278 Lisp_Object display, on;
3280 return Qnil;
3284 /***********************************************************************
3285 Window properties
3286 ***********************************************************************/
3288 DEFUN ("x-change-window-property", Fx_change_window_property,
3289 Sx_change_window_property, 2, 6, 0,
3290 doc: /* Change window property PROP to VALUE on the X window of FRAME.
3291 VALUE may be a string or a list of conses, numbers and/or strings.
3292 If an element in the list is a string, it is converted to
3293 an Atom and the value of the Atom is used. If an element is a cons,
3294 it is converted to a 32 bit number where the car is the 16 top bits and the
3295 cdr is the lower 16 bits.
3296 FRAME nil or omitted means use the selected frame.
3297 If TYPE is given and non-nil, it is the name of the type of VALUE.
3298 If TYPE is not given or nil, the type is STRING.
3299 FORMAT gives the size in bits of each element if VALUE is a list.
3300 It must be one of 8, 16 or 32.
3301 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
3302 If OUTER_P is non-nil, the property is changed for the outer X window of
3303 FRAME. Default is to change on the edit X window.
3305 Value is VALUE. */)
3306 (prop, value, frame, type, format, outer_p)
3307 Lisp_Object prop, value, frame, type, format, outer_p;
3309 #if 0 /* MAC_TODO : port window properties to Mac */
3310 struct frame *f = check_x_frame (frame);
3311 Atom prop_atom;
3313 CHECK_STRING (prop);
3314 CHECK_STRING (value);
3316 BLOCK_INPUT;
3317 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3318 XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3319 prop_atom, XA_STRING, 8, PropModeReplace,
3320 SDATA (value), SCHARS (value));
3322 /* Make sure the property is set when we return. */
3323 XFlush (FRAME_W32_DISPLAY (f));
3324 UNBLOCK_INPUT;
3326 #endif /* MAC_TODO */
3328 return value;
3332 DEFUN ("x-delete-window-property", Fx_delete_window_property,
3333 Sx_delete_window_property, 1, 2, 0,
3334 doc: /* Remove window property PROP from X window of FRAME.
3335 FRAME nil or omitted means use the selected frame. Value is PROP. */)
3336 (prop, frame)
3337 Lisp_Object prop, frame;
3339 #if 0 /* MAC_TODO : port window properties to Mac */
3341 struct frame *f = check_x_frame (frame);
3342 Atom prop_atom;
3344 CHECK_STRING (prop);
3345 BLOCK_INPUT;
3346 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3347 XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
3349 /* Make sure the property is removed when we return. */
3350 XFlush (FRAME_W32_DISPLAY (f));
3351 UNBLOCK_INPUT;
3352 #endif /* MAC_TODO */
3354 return prop;
3358 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
3359 1, 2, 0,
3360 doc: /* Value is the value of window property PROP on FRAME.
3361 If FRAME is nil or omitted, use the selected frame. Value is nil
3362 if FRAME hasn't a property with name PROP or if PROP has no string
3363 value. */)
3364 (prop, frame)
3365 Lisp_Object prop, frame;
3367 #if 0 /* MAC_TODO : port window properties to Mac */
3369 struct frame *f = check_x_frame (frame);
3370 Atom prop_atom;
3371 int rc;
3372 Lisp_Object prop_value = Qnil;
3373 char *tmp_data = NULL;
3374 Atom actual_type;
3375 int actual_format;
3376 unsigned long actual_size, bytes_remaining;
3378 CHECK_STRING (prop);
3379 BLOCK_INPUT;
3380 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3381 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3382 prop_atom, 0, 0, False, XA_STRING,
3383 &actual_type, &actual_format, &actual_size,
3384 &bytes_remaining, (unsigned char **) &tmp_data);
3385 if (rc == Success)
3387 int size = bytes_remaining;
3389 XFree (tmp_data);
3390 tmp_data = NULL;
3392 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3393 prop_atom, 0, bytes_remaining,
3394 False, XA_STRING,
3395 &actual_type, &actual_format,
3396 &actual_size, &bytes_remaining,
3397 (unsigned char **) &tmp_data);
3398 if (rc == Success)
3399 prop_value = make_string (tmp_data, size);
3401 XFree (tmp_data);
3404 UNBLOCK_INPUT;
3406 return prop_value;
3408 #endif /* MAC_TODO */
3409 return Qnil;
3414 /***********************************************************************
3415 Hourglass cursor
3416 ***********************************************************************/
3418 /* If non-null, an asynchronous timer that, when it expires, displays
3419 an hourglass cursor on all frames. */
3421 static struct atimer *hourglass_atimer;
3423 /* Non-zero means an hourglass cursor is currently shown. */
3425 static int hourglass_shown_p;
3427 /* Number of seconds to wait before displaying an hourglass cursor. */
3429 static Lisp_Object Vhourglass_delay;
3431 /* Default number of seconds to wait before displaying an hourglass
3432 cursor. */
3434 #define DEFAULT_HOURGLASS_DELAY 1
3436 /* Function prototypes. */
3438 static void show_hourglass P_ ((struct atimer *));
3439 static void hide_hourglass P_ ((void));
3442 /* Cancel a currently active hourglass timer, and start a new one. */
3444 void
3445 start_hourglass ()
3447 #if 0 /* MAC_TODO: cursor shape changes. */
3448 EMACS_TIME delay;
3449 int secs, usecs = 0;
3451 cancel_hourglass ();
3453 if (INTEGERP (Vhourglass_delay)
3454 && XINT (Vhourglass_delay) > 0)
3455 secs = XFASTINT (Vhourglass_delay);
3456 else if (FLOATP (Vhourglass_delay)
3457 && XFLOAT_DATA (Vhourglass_delay) > 0)
3459 Lisp_Object tem;
3460 tem = Ftruncate (Vhourglass_delay, Qnil);
3461 secs = XFASTINT (tem);
3462 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
3464 else
3465 secs = DEFAULT_HOURGLASS_DELAY;
3467 EMACS_SET_SECS_USECS (delay, secs, usecs);
3468 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
3469 show_hourglass, NULL);
3470 #endif /* MAC_TODO */
3474 /* Cancel the hourglass cursor timer if active, hide an hourglass
3475 cursor if shown. */
3477 void
3478 cancel_hourglass ()
3480 if (hourglass_atimer)
3482 cancel_atimer (hourglass_atimer);
3483 hourglass_atimer = NULL;
3486 if (hourglass_shown_p)
3487 hide_hourglass ();
3491 /* Timer function of hourglass_atimer. TIMER is equal to
3492 hourglass_atimer.
3494 Display an hourglass cursor on all frames by mapping the frames'
3495 hourglass_window. Set the hourglass_p flag in the frames'
3496 output_data.x structure to indicate that an hourglass cursor is
3497 shown on the frames. */
3499 static void
3500 show_hourglass (timer)
3501 struct atimer *timer;
3503 #if 0 /* MAC_TODO: cursor shape changes. */
3504 /* The timer implementation will cancel this timer automatically
3505 after this function has run. Set hourglass_atimer to null
3506 so that we know the timer doesn't have to be canceled. */
3507 hourglass_atimer = NULL;
3509 if (!hourglass_shown_p)
3511 Lisp_Object rest, frame;
3513 BLOCK_INPUT;
3515 FOR_EACH_FRAME (rest, frame)
3516 if (FRAME_W32_P (XFRAME (frame)))
3518 struct frame *f = XFRAME (frame);
3520 f->output_data.w32->hourglass_p = 1;
3522 if (!f->output_data.w32->hourglass_window)
3524 unsigned long mask = CWCursor;
3525 XSetWindowAttributes attrs;
3527 attrs.cursor = f->output_data.w32->hourglass_cursor;
3529 f->output_data.w32->hourglass_window
3530 = XCreateWindow (FRAME_X_DISPLAY (f),
3531 FRAME_OUTER_WINDOW (f),
3532 0, 0, 32000, 32000, 0, 0,
3533 InputOnly,
3534 CopyFromParent,
3535 mask, &attrs);
3538 XMapRaised (FRAME_X_DISPLAY (f),
3539 f->output_data.w32->hourglass_window);
3540 XFlush (FRAME_X_DISPLAY (f));
3543 hourglass_shown_p = 1;
3544 UNBLOCK_INPUT;
3546 #endif /* MAC_TODO */
3550 /* Hide the hourglass cursor on all frames, if it is currently shown. */
3552 static void
3553 hide_hourglass ()
3555 #if 0 /* MAC_TODO: cursor shape changes. */
3556 if (hourglass_shown_p)
3558 Lisp_Object rest, frame;
3560 BLOCK_INPUT;
3561 FOR_EACH_FRAME (rest, frame)
3563 struct frame *f = XFRAME (frame);
3565 if (FRAME_W32_P (f)
3566 /* Watch out for newly created frames. */
3567 && f->output_data.x->hourglass_window)
3569 XUnmapWindow (FRAME_X_DISPLAY (f),
3570 f->output_data.x->hourglass_window);
3571 /* Sync here because XTread_socket looks at the
3572 hourglass_p flag that is reset to zero below. */
3573 XSync (FRAME_X_DISPLAY (f), False);
3574 f->output_data.x->hourglass_p = 0;
3578 hourglass_shown_p = 0;
3579 UNBLOCK_INPUT;
3581 #endif /* MAC_TODO */
3586 /***********************************************************************
3587 Tool tips
3588 ***********************************************************************/
3590 static Lisp_Object x_create_tip_frame P_ ((struct mac_display_info *,
3591 Lisp_Object, Lisp_Object));
3592 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
3593 Lisp_Object, int, int, int *, int *));
3595 /* The frame of a currently visible tooltip. */
3597 Lisp_Object tip_frame;
3599 /* If non-nil, a timer started that hides the last tooltip when it
3600 fires. */
3602 Lisp_Object tip_timer;
3603 Window tip_window;
3605 /* If non-nil, a vector of 3 elements containing the last args
3606 with which x-show-tip was called. See there. */
3608 Lisp_Object last_show_tip_args;
3610 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
3612 Lisp_Object Vx_max_tooltip_size;
3615 static Lisp_Object
3616 unwind_create_tip_frame (frame)
3617 Lisp_Object frame;
3619 Lisp_Object deleted;
3621 deleted = unwind_create_frame (frame);
3622 if (EQ (deleted, Qt))
3624 tip_window = NULL;
3625 tip_frame = Qnil;
3628 return deleted;
3632 /* Create a frame for a tooltip on the display described by DPYINFO.
3633 PARMS is a list of frame parameters. TEXT is the string to
3634 display in the tip frame. Value is the frame.
3636 Note that functions called here, esp. x_default_parameter can
3637 signal errors, for instance when a specified color name is
3638 undefined. We have to make sure that we're in a consistent state
3639 when this happens. */
3641 static Lisp_Object
3642 x_create_tip_frame (dpyinfo, parms, text)
3643 struct mac_display_info *dpyinfo;
3644 Lisp_Object parms, text;
3646 struct frame *f;
3647 Lisp_Object frame, tem;
3648 Lisp_Object name;
3649 long window_prompting = 0;
3650 int width, height;
3651 int count = SPECPDL_INDEX ();
3652 struct gcpro gcpro1, gcpro2, gcpro3;
3653 struct kboard *kb;
3654 int face_change_count_before = face_change_count;
3655 Lisp_Object buffer;
3656 struct buffer *old_buffer;
3658 check_mac ();
3660 /* Use this general default value to start with until we know if
3661 this frame has a specified name. */
3662 Vx_resource_name = Vinvocation_name;
3664 #ifdef MULTI_KBOARD
3665 kb = dpyinfo->kboard;
3666 #else
3667 kb = &the_only_kboard;
3668 #endif
3670 /* Get the name of the frame to use for resource lookup. */
3671 name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
3672 if (!STRINGP (name)
3673 && !EQ (name, Qunbound)
3674 && !NILP (name))
3675 error ("Invalid frame name--not a string or nil");
3676 Vx_resource_name = name;
3678 frame = Qnil;
3679 GCPRO3 (parms, name, frame);
3680 f = make_frame (1);
3681 XSETFRAME (frame, f);
3683 buffer = Fget_buffer_create (build_string (" *tip*"));
3684 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
3685 old_buffer = current_buffer;
3686 set_buffer_internal_1 (XBUFFER (buffer));
3687 current_buffer->truncate_lines = Qnil;
3688 specbind (Qinhibit_read_only, Qt);
3689 specbind (Qinhibit_modification_hooks, Qt);
3690 Ferase_buffer ();
3691 Finsert (1, &text);
3692 set_buffer_internal_1 (old_buffer);
3694 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
3695 record_unwind_protect (unwind_create_tip_frame, frame);
3697 /* By setting the output method, we're essentially saying that
3698 the frame is live, as per FRAME_LIVE_P. If we get a signal
3699 from this point on, x_destroy_window might screw up reference
3700 counts etc. */
3701 f->output_method = output_mac;
3702 f->output_data.mac =
3703 (struct mac_output *) xmalloc (sizeof (struct mac_output));
3704 bzero (f->output_data.mac, sizeof (struct mac_output));
3706 FRAME_FONTSET (f) = -1;
3707 f->icon_name = Qnil;
3709 #if 0 /* GLYPH_DEBUG TODO: image support. */
3710 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
3711 dpyinfo_refcount = dpyinfo->reference_count;
3712 #endif /* GLYPH_DEBUG */
3713 #ifdef MULTI_KBOARD
3714 FRAME_KBOARD (f) = kb;
3715 #endif
3716 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
3717 f->output_data.mac->explicit_parent = 0;
3719 /* Set the name; the functions to which we pass f expect the name to
3720 be set. */
3721 if (EQ (name, Qunbound) || NILP (name))
3723 f->name = build_string (dpyinfo->mac_id_name);
3724 f->explicit_name = 0;
3726 else
3728 f->name = name;
3729 f->explicit_name = 1;
3730 /* use the frame's title when getting resources for this frame. */
3731 specbind (Qx_resource_name, name);
3734 /* Extract the window parameters from the supplied values that are
3735 needed to determine window geometry. */
3737 Lisp_Object font;
3739 font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
3741 BLOCK_INPUT;
3742 /* First, try whatever font the caller has specified. */
3743 if (STRINGP (font))
3745 tem = Fquery_fontset (font, Qnil);
3746 if (STRINGP (tem))
3747 font = x_new_fontset (f, SDATA (tem));
3748 else
3749 font = x_new_font (f, SDATA (font));
3752 /* Try out a font which we hope has bold and italic variations. */
3753 if (! STRINGP (font))
3754 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
3755 /* If those didn't work, look for something which will at least work. */
3756 if (! STRINGP (font))
3757 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
3758 if (! STRINGP (font))
3759 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
3760 UNBLOCK_INPUT;
3761 if (! STRINGP (font))
3762 error ("Cannot find any usable font");
3764 x_default_parameter (f, parms, Qfont, font,
3765 "font", "Font", RES_TYPE_STRING);
3768 x_default_parameter (f, parms, Qborder_width, make_number (2),
3769 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3771 /* This defaults to 2 in order to match xterm. We recognize either
3772 internalBorderWidth or internalBorder (which is what xterm calls
3773 it). */
3774 if (NILP (Fassq (Qinternal_border_width, parms)))
3776 Lisp_Object value;
3778 value = mac_get_arg (parms, Qinternal_border_width,
3779 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3780 if (! EQ (value, Qunbound))
3781 parms = Fcons (Fcons (Qinternal_border_width, value),
3782 parms);
3785 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
3786 "internalBorderWidth", "internalBorderWidth",
3787 RES_TYPE_NUMBER);
3789 /* Also do the stuff which must be set before the window exists. */
3790 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3791 "foreground", "Foreground", RES_TYPE_STRING);
3792 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3793 "background", "Background", RES_TYPE_STRING);
3794 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3795 "pointerColor", "Foreground", RES_TYPE_STRING);
3796 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3797 "cursorColor", "Foreground", RES_TYPE_STRING);
3798 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3799 "borderColor", "BorderColor", RES_TYPE_STRING);
3801 /* Init faces before x_default_parameter is called for scroll-bar
3802 parameters because that function calls x_set_scroll_bar_width,
3803 which calls change_frame_size, which calls Fset_window_buffer,
3804 which runs hooks, which call Fvertical_motion. At the end, we
3805 end up in init_iterator with a null face cache, which should not
3806 happen. */
3807 init_frame_faces (f);
3809 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
3811 window_prompting = x_figure_window_size (f, parms, 0);
3814 Rect r;
3816 BLOCK_INPUT;
3817 SetRect (&r, 0, 0, 1, 1);
3818 if (CreateNewWindow (kHelpWindowClass,
3819 #ifdef MAC_OS_X_VERSION_10_2
3820 kWindowIgnoreClicksAttribute |
3821 #endif
3822 kWindowNoActivatesAttribute,
3823 &r, &tip_window) == noErr)
3825 FRAME_MAC_WINDOW (f) = tip_window;
3826 SetWRefCon (tip_window, (long) f->output_data.mac);
3827 /* so that update events can find this mac_output struct */
3828 f->output_data.mac->mFP = f;
3829 ShowWindow (tip_window);
3831 UNBLOCK_INPUT;
3834 x_make_gc (f);
3836 x_default_parameter (f, parms, Qauto_raise, Qnil,
3837 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3838 x_default_parameter (f, parms, Qauto_lower, Qnil,
3839 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3840 x_default_parameter (f, parms, Qcursor_type, Qbox,
3841 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3843 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3844 Change will not be effected unless different from the current
3845 FRAME_LINES (f). */
3846 width = FRAME_COLS (f);
3847 height = FRAME_LINES (f);
3848 SET_FRAME_COLS (f, 0);
3849 FRAME_LINES (f) = 0;
3850 change_frame_size (f, height, width, 1, 0, 0);
3852 /* Add `tooltip' frame parameter's default value. */
3853 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
3854 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
3855 Qnil));
3857 /* Set up faces after all frame parameters are known. This call
3858 also merges in face attributes specified for new frames.
3860 Frame parameters may be changed if .Xdefaults contains
3861 specifications for the default font. For example, if there is an
3862 `Emacs.default.attributeBackground: pink', the `background-color'
3863 attribute of the frame get's set, which let's the internal border
3864 of the tooltip frame appear in pink. Prevent this. */
3866 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
3868 /* Set tip_frame here, so that */
3869 tip_frame = frame;
3870 call1 (Qface_set_after_frame_default, frame);
3872 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
3873 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
3874 Qnil));
3877 f->no_split = 1;
3879 UNGCPRO;
3881 /* It is now ok to make the frame official even if we get an error
3882 below. And the frame needs to be on Vframe_list or making it
3883 visible won't work. */
3884 Vframe_list = Fcons (frame, Vframe_list);
3886 /* Now that the frame is official, it counts as a reference to
3887 its display. */
3888 FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
3890 /* Setting attributes of faces of the tooltip frame from resources
3891 and similar will increment face_change_count, which leads to the
3892 clearing of all current matrices. Since this isn't necessary
3893 here, avoid it by resetting face_change_count to the value it
3894 had before we created the tip frame. */
3895 face_change_count = face_change_count_before;
3897 /* Discard the unwind_protect. */
3898 return unbind_to (count, frame);
3902 /* Compute where to display tip frame F. PARMS is the list of frame
3903 parameters for F. DX and DY are specified offsets from the current
3904 location of the mouse. WIDTH and HEIGHT are the width and height
3905 of the tooltip. Return coordinates relative to the root window of
3906 the display in *ROOT_X, and *ROOT_Y. */
3908 static void
3909 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
3910 struct frame *f;
3911 Lisp_Object parms, dx, dy;
3912 int width, height;
3913 int *root_x, *root_y;
3915 Lisp_Object left, top;
3917 /* User-specified position? */
3918 left = Fcdr (Fassq (Qleft, parms));
3919 top = Fcdr (Fassq (Qtop, parms));
3921 /* Move the tooltip window where the mouse pointer is. Resize and
3922 show it. */
3923 if (!INTEGERP (left) || !INTEGERP (top))
3925 Point mouse_pos;
3927 BLOCK_INPUT;
3928 GetMouse (&mouse_pos);
3929 LocalToGlobal (&mouse_pos);
3930 *root_x = mouse_pos.h;
3931 *root_y = mouse_pos.v;
3932 UNBLOCK_INPUT;
3935 if (INTEGERP (top))
3936 *root_y = XINT (top);
3937 else if (*root_y + XINT (dy) - height < 0)
3938 *root_y -= XINT (dy);
3939 else
3941 *root_y -= height;
3942 *root_y += XINT (dy);
3945 if (INTEGERP (left))
3946 *root_x = XINT (left);
3947 else if (*root_x + XINT (dx) + width <= FRAME_MAC_DISPLAY_INFO (f)->width)
3948 /* It fits to the right of the pointer. */
3949 *root_x += XINT (dx);
3950 else if (width + XINT (dx) <= *root_x)
3951 /* It fits to the left of the pointer. */
3952 *root_x -= width + XINT (dx);
3953 else
3954 /* Put it left-justified on the screen -- it ought to fit that way. */
3955 *root_x = 0;
3959 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
3960 doc: /* Show STRING in a "tooltip" window on frame FRAME.
3961 A tooltip window is a small X window displaying a string.
3963 FRAME nil or omitted means use the selected frame.
3965 PARMS is an optional list of frame parameters which can be used to
3966 change the tooltip's appearance.
3968 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
3969 means use the default timeout of 5 seconds.
3971 If the list of frame parameters PARAMS contains a `left' parameters,
3972 the tooltip is displayed at that x-position. Otherwise it is
3973 displayed at the mouse position, with offset DX added (default is 5 if
3974 DX isn't specified). Likewise for the y-position; if a `top' frame
3975 parameter is specified, it determines the y-position of the tooltip
3976 window, otherwise it is displayed at the mouse position, with offset
3977 DY added (default is -10).
3979 A tooltip's maximum size is specified by `x-max-tooltip-size'.
3980 Text larger than the specified size is clipped. */)
3981 (string, frame, parms, timeout, dx, dy)
3982 Lisp_Object string, frame, parms, timeout, dx, dy;
3984 struct frame *f;
3985 struct window *w;
3986 int root_x, root_y;
3987 struct buffer *old_buffer;
3988 struct text_pos pos;
3989 int i, width, height;
3990 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3991 int old_windows_or_buffers_changed = windows_or_buffers_changed;
3992 int count = SPECPDL_INDEX ();
3994 specbind (Qinhibit_redisplay, Qt);
3996 GCPRO4 (string, parms, frame, timeout);
3998 CHECK_STRING (string);
3999 f = check_x_frame (frame);
4000 if (NILP (timeout))
4001 timeout = make_number (5);
4002 else
4003 CHECK_NATNUM (timeout);
4005 if (NILP (dx))
4006 dx = make_number (5);
4007 else
4008 CHECK_NUMBER (dx);
4010 if (NILP (dy))
4011 dy = make_number (-10);
4012 else
4013 CHECK_NUMBER (dy);
4015 if (NILP (last_show_tip_args))
4016 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
4018 if (!NILP (tip_frame))
4020 Lisp_Object last_string = AREF (last_show_tip_args, 0);
4021 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
4022 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
4024 if (EQ (frame, last_frame)
4025 && !NILP (Fequal (last_string, string))
4026 && !NILP (Fequal (last_parms, parms)))
4028 struct frame *f = XFRAME (tip_frame);
4030 /* Only DX and DY have changed. */
4031 if (!NILP (tip_timer))
4033 Lisp_Object timer = tip_timer;
4034 tip_timer = Qnil;
4035 call1 (Qcancel_timer, timer);
4038 BLOCK_INPUT;
4039 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
4040 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
4041 MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
4042 UNBLOCK_INPUT;
4043 goto start_timer;
4047 /* Hide a previous tip, if any. */
4048 Fx_hide_tip ();
4050 ASET (last_show_tip_args, 0, string);
4051 ASET (last_show_tip_args, 1, frame);
4052 ASET (last_show_tip_args, 2, parms);
4054 /* Add default values to frame parameters. */
4055 if (NILP (Fassq (Qname, parms)))
4056 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
4057 if (NILP (Fassq (Qinternal_border_width, parms)))
4058 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
4059 if (NILP (Fassq (Qborder_width, parms)))
4060 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
4061 if (NILP (Fassq (Qborder_color, parms)))
4062 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
4063 if (NILP (Fassq (Qbackground_color, parms)))
4064 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
4065 parms);
4067 /* Create a frame for the tooltip, and record it in the global
4068 variable tip_frame. */
4069 frame = x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f), parms, string);
4070 f = XFRAME (frame);
4072 /* Set up the frame's root window. */
4073 w = XWINDOW (FRAME_ROOT_WINDOW (f));
4074 w->left_col = w->top_line = make_number (0);
4076 if (CONSP (Vx_max_tooltip_size)
4077 && INTEGERP (XCAR (Vx_max_tooltip_size))
4078 && XINT (XCAR (Vx_max_tooltip_size)) > 0
4079 && INTEGERP (XCDR (Vx_max_tooltip_size))
4080 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
4082 w->total_cols = XCAR (Vx_max_tooltip_size);
4083 w->total_lines = XCDR (Vx_max_tooltip_size);
4085 else
4087 w->total_cols = make_number (80);
4088 w->total_lines = make_number (40);
4091 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
4092 adjust_glyphs (f);
4093 w->pseudo_window_p = 1;
4095 /* Display the tooltip text in a temporary buffer. */
4096 old_buffer = current_buffer;
4097 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
4098 current_buffer->truncate_lines = Qnil;
4099 clear_glyph_matrix (w->desired_matrix);
4100 clear_glyph_matrix (w->current_matrix);
4101 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
4102 try_window (FRAME_ROOT_WINDOW (f), pos);
4104 /* Compute width and height of the tooltip. */
4105 width = height = 0;
4106 for (i = 0; i < w->desired_matrix->nrows; ++i)
4108 struct glyph_row *row = &w->desired_matrix->rows[i];
4109 struct glyph *last;
4110 int row_width;
4112 /* Stop at the first empty row at the end. */
4113 if (!row->enabled_p || !row->displays_text_p)
4114 break;
4116 /* Let the row go over the full width of the frame. */
4117 row->full_width_p = 1;
4119 /* There's a glyph at the end of rows that is used to place
4120 the cursor there. Don't include the width of this glyph. */
4121 if (row->used[TEXT_AREA])
4123 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
4124 row_width = row->pixel_width - last->pixel_width;
4126 else
4127 row_width = row->pixel_width;
4129 height += row->height;
4130 width = max (width, row_width);
4133 /* Add the frame's internal border to the width and height the X
4134 window should have. */
4135 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4136 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4138 /* Move the tooltip window where the mouse pointer is. Resize and
4139 show it. */
4140 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
4142 BLOCK_INPUT;
4143 MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
4144 SizeWindow (FRAME_MAC_WINDOW (f), width, height, true);
4145 BringToFront (FRAME_MAC_WINDOW (f));
4146 UNBLOCK_INPUT;
4148 /* Draw into the window. */
4149 w->must_be_updated_p = 1;
4150 update_single_window (w, 1);
4152 /* Restore original current buffer. */
4153 set_buffer_internal_1 (old_buffer);
4154 windows_or_buffers_changed = old_windows_or_buffers_changed;
4156 start_timer:
4157 /* Let the tip disappear after timeout seconds. */
4158 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
4159 intern ("x-hide-tip"));
4161 UNGCPRO;
4162 return unbind_to (count, Qnil);
4166 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
4167 doc: /* Hide the current tooltip window, if there is any.
4168 Value is t if tooltip was open, nil otherwise. */)
4171 int count;
4172 Lisp_Object deleted, frame, timer;
4173 struct gcpro gcpro1, gcpro2;
4175 /* Return quickly if nothing to do. */
4176 if (NILP (tip_timer) && NILP (tip_frame))
4177 return Qnil;
4179 frame = tip_frame;
4180 timer = tip_timer;
4181 GCPRO2 (frame, timer);
4182 tip_frame = tip_timer = deleted = Qnil;
4184 count = SPECPDL_INDEX ();
4185 specbind (Qinhibit_redisplay, Qt);
4186 specbind (Qinhibit_quit, Qt);
4188 if (!NILP (timer))
4189 call1 (Qcancel_timer, timer);
4191 if (FRAMEP (frame))
4193 Fdelete_frame (frame, Qnil);
4194 deleted = Qt;
4197 UNGCPRO;
4198 return unbind_to (count, deleted);
4203 #ifdef TARGET_API_MAC_CARBON
4204 /***********************************************************************
4205 File selection dialog
4206 ***********************************************************************/
4209 There is a relatively standard way to do this using applescript to run
4210 a (choose file) method. However, this doesn't do "the right thing"
4211 by working only if the find-file occurred during a menu or toolbar
4212 click. So we must do the file dialog by hand, using the navigation
4213 manager. This also has more flexibility in determining the default
4214 directory and whether or not we are going to choose a file.
4217 extern Lisp_Object Qfile_name_history;
4219 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
4220 doc: /* Read file name, prompting with PROMPT in directory DIR.
4221 Use a file selection dialog.
4222 Select DEFAULT-FILENAME in the dialog's file selection box, if
4223 specified. Ensure that file exists if MUSTMATCH is non-nil.
4224 If ONLY-DIR-P is non-nil, the user can only select directories. */)
4225 (prompt, dir, default_filename, mustmatch, only_dir_p)
4226 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
4228 struct frame *f = SELECTED_FRAME ();
4229 Lisp_Object file = Qnil;
4230 int count = SPECPDL_INDEX ();
4231 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
4232 char filename[1001];
4233 int default_filter_index = 1; /* 1: All Files, 2: Directories only */
4235 GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p);
4236 CHECK_STRING (prompt);
4237 CHECK_STRING (dir);
4239 /* Create the dialog with PROMPT as title, using DIR as initial
4240 directory and using "*" as pattern. */
4241 dir = Fexpand_file_name (dir, Qnil);
4244 OSStatus status;
4245 NavDialogCreationOptions options;
4246 NavDialogRef dialogRef;
4247 NavTypeListHandle fileTypes = NULL;
4248 NavUserAction userAction;
4249 CFStringRef message=NULL, client=NULL, saveName = NULL, ok = NULL;
4250 CFStringRef title = NULL;
4252 BLOCK_INPUT;
4253 /* No need for a callback function because we are modal */
4254 NavGetDefaultDialogCreationOptions(&options);
4255 options.modality = kWindowModalityAppModal;
4256 options.location.h = options.location.v = -1;
4257 options.optionFlags = kNavDefaultNavDlogOptions;
4258 options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */
4259 options.optionFlags |= kNavSelectAllReadableItem;
4260 if (!NILP(prompt))
4262 message = CFStringCreateWithCStringNoCopy(NULL, SDATA(prompt),
4263 kCFStringEncodingUTF8,
4264 kCFAllocatorNull);
4265 options.message = message;
4267 /* Don't set the application, let it use default.
4268 client = CFStringCreateWithCStringNoCopy(NULL, "Emacs",
4269 kCFStringEncodingMacRoman, NULL);
4270 options.clientName = client;
4273 if (!NILP (only_dir_p))
4274 status = NavCreateChooseFolderDialog(&options, NULL, NULL, NULL,
4275 &dialogRef);
4276 else if (NILP (mustmatch))
4278 /* This is a save dialog */
4279 ok = CFStringCreateWithCString (NULL, "Ok", kCFStringEncodingUTF8);
4280 title = CFStringCreateWithCString (NULL, "Enter name",
4281 kCFStringEncodingUTF8);
4282 options.optionFlags |= kNavDontConfirmReplacement;
4283 options.actionButtonLabel = ok;
4284 options.windowTitle = title;
4286 if (!NILP(default_filename))
4288 saveName = CFStringCreateWithCString(NULL, SDATA(default_filename),
4289 kCFStringEncodingUTF8);
4290 options.saveFileName = saveName;
4291 options.optionFlags |= kNavSelectDefaultLocation;
4293 status = NavCreatePutFileDialog(&options,
4294 'TEXT', kNavGenericSignature,
4295 NULL, NULL, &dialogRef);
4297 else
4299 /* This is an open dialog*/
4300 status = NavCreateChooseFileDialog(&options, fileTypes,
4301 NULL, NULL, NULL, NULL,
4302 &dialogRef);
4305 /* Set the default location and continue*/
4306 if (status == noErr) {
4307 if (!NILP(dir)) {
4308 FSRef defLoc;
4309 AEDesc defLocAed;
4310 status = FSPathMakeRef(SDATA(dir), &defLoc, NULL);
4311 if (status == noErr)
4313 AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed);
4314 NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
4316 AEDisposeDesc(&defLocAed);
4319 status = NavDialogRun(dialogRef);
4322 if (saveName) CFRelease(saveName);
4323 if (client) CFRelease(client);
4324 if (message) CFRelease(message);
4325 if (ok) CFRelease(ok);
4326 if (title) CFRelease(title);
4328 if (status == noErr) {
4329 userAction = NavDialogGetUserAction(dialogRef);
4330 switch (userAction)
4332 case kNavUserActionNone:
4333 case kNavUserActionCancel:
4334 break; /* Treat cancel like C-g */
4335 case kNavUserActionOpen:
4336 case kNavUserActionChoose:
4337 case kNavUserActionSaveAs:
4339 NavReplyRecord reply;
4340 AEDesc aed;
4341 FSRef fsRef;
4342 status = NavDialogGetReply(dialogRef, &reply);
4343 AECoerceDesc(&reply.selection, typeFSRef, &aed);
4344 AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef));
4345 FSRefMakePath(&fsRef, (UInt8 *) filename, 1000);
4346 AEDisposeDesc(&aed);
4347 if (reply.saveFileName)
4349 /* If it was a saved file, we need to add the file name */
4350 int len = strlen(filename);
4351 if (len && filename[len-1] != '/')
4352 filename[len++] = '/';
4353 CFStringGetCString(reply.saveFileName, filename+len,
4354 1000-len, kCFStringEncodingUTF8);
4356 file = DECODE_FILE(build_string (filename));
4357 NavDisposeReply(&reply);
4359 break;
4361 NavDialogDispose(dialogRef);
4363 else {
4364 /* Fall back on minibuffer if there was a problem */
4365 file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
4366 dir, mustmatch, dir, Qfile_name_history,
4367 default_filename, Qnil);
4369 UNBLOCK_INPUT;
4372 UNGCPRO;
4374 /* Make "Cancel" equivalent to C-g. */
4375 if (NILP (file))
4376 Fsignal (Qquit, Qnil);
4378 return unbind_to (count, file);
4382 #endif
4384 /***********************************************************************
4385 Initialization
4386 ***********************************************************************/
4388 /* Keep this list in the same order as frame_parms in frame.c.
4389 Use 0 for unsupported frame parameters. */
4391 frame_parm_handler mac_frame_parm_handlers[] =
4393 x_set_autoraise,
4394 x_set_autolower,
4395 x_set_background_color,
4396 x_set_border_color,
4397 x_set_border_width,
4398 x_set_cursor_color,
4399 x_set_cursor_type,
4400 x_set_font,
4401 x_set_foreground_color,
4402 x_set_icon_name,
4403 0, /* MAC_TODO: x_set_icon_type, */
4404 x_set_internal_border_width,
4405 x_set_menu_bar_lines,
4406 x_set_mouse_color,
4407 x_explicitly_set_name,
4408 x_set_scroll_bar_width,
4409 x_set_title,
4410 x_set_unsplittable,
4411 x_set_vertical_scroll_bars,
4412 x_set_visibility,
4413 x_set_tool_bar_lines,
4414 0, /* MAC_TODO: x_set_scroll_bar_foreground, */
4415 0, /* MAC_TODO: x_set_scroll_bar_background, */
4416 x_set_screen_gamma,
4417 x_set_line_spacing,
4418 0, /* MAC_TODO: x_set_fringe_width, */
4419 0, /* MAC_TODO: x_set_fringe_width, */
4420 0, /* x_set_wait_for_wm, */
4421 0, /* MAC_TODO: x_set_fullscreen, */
4424 void
4425 syms_of_macfns ()
4427 /* Certainly running on Mac. */
4428 mac_in_use = 1;
4430 /* The section below is built by the lisp expression at the top of the file,
4431 just above where these variables are declared. */
4432 /*&&& init symbols here &&&*/
4433 Qnone = intern ("none");
4434 staticpro (&Qnone);
4435 Qsuppress_icon = intern ("suppress-icon");
4436 staticpro (&Qsuppress_icon);
4437 Qundefined_color = intern ("undefined-color");
4438 staticpro (&Qundefined_color);
4439 Qcancel_timer = intern ("cancel-timer");
4440 staticpro (&Qcancel_timer);
4442 Qhyper = intern ("hyper");
4443 staticpro (&Qhyper);
4444 Qsuper = intern ("super");
4445 staticpro (&Qsuper);
4446 Qmeta = intern ("meta");
4447 staticpro (&Qmeta);
4448 Qalt = intern ("alt");
4449 staticpro (&Qalt);
4450 Qctrl = intern ("ctrl");
4451 staticpro (&Qctrl);
4452 Qcontrol = intern ("control");
4453 staticpro (&Qcontrol);
4454 Qshift = intern ("shift");
4455 staticpro (&Qshift);
4456 /* This is the end of symbol initialization. */
4458 /* Text property `display' should be nonsticky by default. */
4459 Vtext_property_default_nonsticky
4460 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
4462 Qface_set_after_frame_default = intern ("face-set-after-frame-default");
4463 staticpro (&Qface_set_after_frame_default);
4465 Fput (Qundefined_color, Qerror_conditions,
4466 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
4467 Fput (Qundefined_color, Qerror_message,
4468 build_string ("Undefined color"));
4470 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
4471 doc: /* The shape of the pointer when over text.
4472 Changing the value does not affect existing frames
4473 unless you set the mouse color. */);
4474 Vx_pointer_shape = Qnil;
4476 Vx_nontext_pointer_shape = Qnil;
4478 Vx_mode_pointer_shape = Qnil;
4480 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
4481 doc: /* The shape of the pointer when Emacs is hourglass.
4482 This variable takes effect when you create a new frame
4483 or when you set the mouse color. */);
4484 Vx_hourglass_pointer_shape = Qnil;
4486 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
4487 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
4488 display_hourglass_p = 1;
4490 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
4491 doc: /* *Seconds to wait before displaying an hourglass pointer.
4492 Value must be an integer or float. */);
4493 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
4495 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
4496 &Vx_sensitive_text_pointer_shape,
4497 doc: /* The shape of the pointer when over mouse-sensitive text.
4498 This variable takes effect when you create a new frame
4499 or when you set the mouse color. */);
4500 Vx_sensitive_text_pointer_shape = Qnil;
4502 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
4503 doc: /* A string indicating the foreground color of the cursor box. */);
4504 Vx_cursor_fore_pixel = Qnil;
4506 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
4507 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
4508 Text larger than this is clipped. */);
4509 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
4511 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
4512 doc: /* Non-nil if no window manager is in use.
4513 Emacs doesn't try to figure this out; this is always nil
4514 unless you set it to something else. */);
4515 /* We don't have any way to find this out, so set it to nil
4516 and maybe the user would like to set it to t. */
4517 Vx_no_window_manager = Qnil;
4519 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
4520 &Vx_pixel_size_width_font_regexp,
4521 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
4523 Since Emacs gets width of a font matching with this regexp from
4524 PIXEL_SIZE field of the name, font finding mechanism gets faster for
4525 such a font. This is especially effective for such large fonts as
4526 Chinese, Japanese, and Korean. */);
4527 Vx_pixel_size_width_font_regexp = Qnil;
4529 /* X window properties. */
4530 defsubr (&Sx_change_window_property);
4531 defsubr (&Sx_delete_window_property);
4532 defsubr (&Sx_window_property);
4534 defsubr (&Sxw_display_color_p);
4535 defsubr (&Sx_display_grayscale_p);
4536 defsubr (&Sxw_color_defined_p);
4537 defsubr (&Sxw_color_values);
4538 defsubr (&Sx_server_max_request_size);
4539 defsubr (&Sx_server_vendor);
4540 defsubr (&Sx_server_version);
4541 defsubr (&Sx_display_pixel_width);
4542 defsubr (&Sx_display_pixel_height);
4543 defsubr (&Sx_display_mm_width);
4544 defsubr (&Sx_display_mm_height);
4545 defsubr (&Sx_display_screens);
4546 defsubr (&Sx_display_planes);
4547 defsubr (&Sx_display_color_cells);
4548 defsubr (&Sx_display_visual_class);
4549 defsubr (&Sx_display_backing_store);
4550 defsubr (&Sx_display_save_under);
4551 defsubr (&Sx_create_frame);
4552 #if 0 /* MAC_TODO: implement network support */
4553 defsubr (&Sx_open_connection);
4554 defsubr (&Sx_close_connection);
4555 #endif
4556 defsubr (&Sx_display_list);
4557 defsubr (&Sx_synchronize);
4559 /* Setting callback functions for fontset handler. */
4560 get_font_info_func = x_get_font_info;
4562 #if 0 /* This function pointer doesn't seem to be used anywhere.
4563 And the pointer assigned has the wrong type, anyway. */
4564 list_fonts_func = x_list_fonts;
4565 #endif
4567 load_font_func = x_load_font;
4568 find_ccl_program_func = x_find_ccl_program;
4569 query_font_func = x_query_font;
4570 set_frame_fontset_func = x_set_font;
4571 check_window_system_func = check_mac;
4573 hourglass_atimer = NULL;
4574 hourglass_shown_p = 0;
4576 defsubr (&Sx_show_tip);
4577 defsubr (&Sx_hide_tip);
4578 tip_timer = Qnil;
4579 staticpro (&tip_timer);
4580 tip_frame = Qnil;
4581 staticpro (&tip_frame);
4583 last_show_tip_args = Qnil;
4584 staticpro (&last_show_tip_args);
4586 #if TARGET_API_MAC_CARBON
4587 defsubr (&Sx_file_dialog);
4588 #endif
4591 /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc
4592 (do not change this comment) */