(latexenc-find-file-coding-system): Don't inherit the EOL part of the
[emacs.git] / src / macfns.c
blobd0dd9b9c072b50daeebe9bbffc769dc05d86765d
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 <stdio.h>
26 #include <math.h>
27 #include <limits.h>
28 #include <errno.h>
30 #include "lisp.h"
31 #include "charset.h"
32 #include "macterm.h"
33 #include "frame.h"
34 #include "window.h"
35 #include "buffer.h"
36 #include "dispextern.h"
37 #include "fontset.h"
38 #include "intervals.h"
39 #include "keyboard.h"
40 #include "blockinput.h"
41 #include "epaths.h"
42 #include "termhooks.h"
43 #include "coding.h"
44 #include "systime.h"
46 /* #include "bitmaps/gray.xbm" */
47 #define gray_width 2
48 #define gray_height 2
49 static unsigned char gray_bits[] = {
50 0x01, 0x02};
52 /*#include <commdlg.h>
53 #include <shellapi.h>*/
54 #include <ctype.h>
55 #include <sys/types.h>
56 #include <sys/stat.h>
57 #include <sys/param.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;
152 extern Lisp_Object Vwindow_system_version;
154 #if 0 /* Use xstricmp instead. */
155 /* compare two strings ignoring case */
157 static int
158 stricmp (const char *s, const char *t)
160 for ( ; tolower (*s) == tolower (*t); s++, t++)
161 if (*s == '\0')
162 return 0;
163 return tolower (*s) - tolower (*t);
165 #endif
167 /* compare two strings up to n characters, ignoring case */
169 static int
170 strnicmp (const char *s, const char *t, unsigned int n)
172 for ( ; n > 0 && tolower (*s) == tolower (*t); n--, s++, t++)
173 if (*s == '\0')
174 return 0;
175 return n == 0 ? 0 : tolower (*s) - tolower (*t);
179 /* Error if we are not running on Mac OS. */
181 void
182 check_mac ()
184 if (! mac_in_use)
185 error ("Mac native windows not in use or not initialized");
188 /* Nonzero if we can use mouse menus.
189 You should not call this unless HAVE_MENUS is defined. */
192 have_menus_p ()
194 return mac_in_use;
197 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
198 and checking validity for Mac. */
200 FRAME_PTR
201 check_x_frame (frame)
202 Lisp_Object frame;
204 FRAME_PTR f;
206 if (NILP (frame))
207 frame = selected_frame;
208 CHECK_LIVE_FRAME (frame);
209 f = XFRAME (frame);
210 if (! FRAME_MAC_P (f))
211 error ("non-mac frame used");
212 return f;
215 /* Let the user specify a display with a frame.
216 nil stands for the selected frame--or, if that is not a mac frame,
217 the first display on the list. */
219 struct mac_display_info *
220 check_x_display_info (frame)
221 Lisp_Object frame;
223 struct mac_display_info *dpyinfo = NULL;
225 if (NILP (frame))
227 struct frame *sf = XFRAME (selected_frame);
229 if (FRAME_MAC_P (sf) && FRAME_LIVE_P (sf))
230 dpyinfo = FRAME_MAC_DISPLAY_INFO (sf);
231 else if (x_display_list != 0)
232 dpyinfo = x_display_list;
233 else
234 error ("Mac native windows are not in use or not initialized");
236 else if (STRINGP (frame))
237 dpyinfo = x_display_info_for_name (frame);
238 else
240 FRAME_PTR f = check_x_frame (frame);
241 dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
244 return dpyinfo;
247 /* Return the Emacs frame-object corresponding to a mac window.
248 It could be the frame's main window or an icon window. */
250 /* This function can be called during GC, so use GC_xxx type test macros. */
252 struct frame *
253 x_window_to_frame (dpyinfo, wdesc)
254 struct mac_display_info *dpyinfo;
255 WindowPtr wdesc;
257 Lisp_Object tail, frame;
258 struct frame *f;
260 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
262 frame = XCAR (tail);
263 if (!GC_FRAMEP (frame))
264 continue;
265 f = XFRAME (frame);
266 if (!FRAME_W32_P (f) || FRAME_MAC_DISPLAY_INFO (f) != dpyinfo)
267 continue;
268 /*if (f->output_data.w32->hourglass_window == wdesc)
269 return f;*/
271 /* MAC_TODO: Check tooltips when supported. */
272 if (FRAME_MAC_WINDOW (f) == wdesc)
273 return f;
275 return 0;
279 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
281 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
282 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
283 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
284 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
285 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
286 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
287 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
288 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
289 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
290 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
291 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
292 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
293 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
294 Lisp_Object));
295 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
296 Lisp_Object));
297 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
298 Lisp_Object,
299 Lisp_Object,
300 char *, char *,
301 int));
303 extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
305 /* Store the screen positions of frame F into XPTR and YPTR.
306 These are the positions of the containing window manager window,
307 not Emacs's own window. */
309 void
310 x_real_positions (f, xptr, yptr)
311 FRAME_PTR f;
312 int *xptr, *yptr;
314 Rect inner, outer;
316 mac_get_window_bounds (f, &inner, &outer);
318 f->x_pixels_diff = inner.left - outer.left;
319 f->y_pixels_diff = inner.top - outer.top;
321 *xptr = outer.left;
322 *yptr = outer.top;
326 /* The default colors for the Mac color map */
327 typedef struct colormap_t
329 unsigned long color;
330 char *name;
331 } colormap_t;
333 colormap_t mac_color_map[] =
335 { RGB_TO_ULONG(255, 250, 250), "snow" },
336 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
337 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
338 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
339 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
340 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
341 { RGB_TO_ULONG(255, 250, 240), "floral white" },
342 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
343 { RGB_TO_ULONG(253, 245, 230), "old lace" },
344 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
345 { RGB_TO_ULONG(250, 240, 230), "linen" },
346 { RGB_TO_ULONG(250, 235, 215), "antique white" },
347 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
348 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
349 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
350 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
351 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
352 { RGB_TO_ULONG(255, 228, 196), "bisque" },
353 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
354 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
355 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
356 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
357 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
358 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
359 { RGB_TO_ULONG(255, 255, 240), "ivory" },
360 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
361 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
362 { RGB_TO_ULONG(255, 245, 238), "seashell" },
363 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
364 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
365 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
366 { RGB_TO_ULONG(240, 255, 255), "azure" },
367 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
368 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
369 { RGB_TO_ULONG(230, 230, 250), "lavender" },
370 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
371 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
372 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
373 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
374 { RGB_TO_ULONG(255, 255, 255), "white" },
375 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
376 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
377 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
378 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
379 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
380 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
381 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
382 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
383 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
384 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
385 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
386 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
387 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
388 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
389 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
390 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
391 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
392 { RGB_TO_ULONG(190, 190, 190), "gray" },
393 { RGB_TO_ULONG(190, 190, 190), "grey" },
394 { RGB_TO_ULONG(211, 211, 211), "light grey" },
395 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
396 { RGB_TO_ULONG(211, 211, 211), "light gray" },
397 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
398 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
399 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
400 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
401 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
402 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
403 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
404 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
405 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
406 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
407 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
408 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
409 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
410 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
411 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
412 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
413 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
414 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
415 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
416 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
417 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
418 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
419 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
420 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
421 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
422 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
423 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
424 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
425 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
426 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
427 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
428 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
429 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
430 { RGB_TO_ULONG(173, 216, 230), "light blue" },
431 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
432 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
433 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
434 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
435 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
436 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
437 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
438 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
439 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
440 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
441 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
442 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
443 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
444 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
445 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
446 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
447 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
448 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
449 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
450 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
451 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
452 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
453 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
454 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
455 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
456 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
457 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
458 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
459 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
460 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
461 { RGB_TO_ULONG(152, 251, 152), "pale green" },
462 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
463 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
464 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
465 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
466 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
467 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
468 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
469 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
470 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
471 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
472 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
473 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
474 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
475 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
476 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
477 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
478 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
479 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
480 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
481 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
482 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
483 { RGB_TO_ULONG(240, 230, 140), "khaki" },
484 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
485 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
486 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
487 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
488 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
489 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
490 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
491 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
492 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
493 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
494 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
495 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
496 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
497 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
498 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
499 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
500 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
501 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
502 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
503 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
504 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
505 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
506 { RGB_TO_ULONG(245, 245, 220), "beige" },
507 { RGB_TO_ULONG(245, 222, 179), "wheat" },
508 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
509 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
510 { RGB_TO_ULONG(210, 180, 140), "tan" },
511 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
512 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
513 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
514 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
515 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
516 { RGB_TO_ULONG(250, 128, 114), "salmon" },
517 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
518 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
519 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
520 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
521 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
522 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
523 { RGB_TO_ULONG(240, 128, 128), "light coral" },
524 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
525 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
526 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
527 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
528 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
529 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
530 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
531 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
532 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
533 { RGB_TO_ULONG(255, 192, 203), "pink" },
534 { RGB_TO_ULONG(255, 182, 193), "light pink" },
535 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
536 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
537 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
538 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
539 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
540 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
541 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
542 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
543 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
544 { RGB_TO_ULONG(238, 130, 238), "violet" },
545 { RGB_TO_ULONG(221, 160, 221), "plum" },
546 { RGB_TO_ULONG(218, 112, 214), "orchid" },
547 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
548 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
549 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
550 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
551 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
552 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
553 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
554 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
555 { RGB_TO_ULONG(160, 32 , 240), "purple" },
556 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
557 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
558 { RGB_TO_ULONG(216, 191, 216), "thistle" },
559 { RGB_TO_ULONG(255, 250, 250), "snow1" },
560 { RGB_TO_ULONG(238, 233, 233), "snow2" },
561 { RGB_TO_ULONG(205, 201, 201), "snow3" },
562 { RGB_TO_ULONG(139, 137, 137), "snow4" },
563 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
564 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
565 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
566 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
567 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
568 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
569 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
570 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
571 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
572 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
573 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
574 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
575 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
576 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
577 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
578 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
579 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
580 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
581 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
582 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
583 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
584 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
585 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
586 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
587 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
588 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
589 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
590 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
591 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
592 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
593 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
594 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
595 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
596 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
597 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
598 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
599 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
600 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
601 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
602 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
603 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
604 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
605 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
606 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
607 { RGB_TO_ULONG(240, 255, 255), "azure1" },
608 { RGB_TO_ULONG(224, 238, 238), "azure2" },
609 { RGB_TO_ULONG(193, 205, 205), "azure3" },
610 { RGB_TO_ULONG(131, 139, 139), "azure4" },
611 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
612 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
613 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
614 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
615 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
616 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
617 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
618 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
619 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
620 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
621 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
622 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
623 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
624 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
625 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
626 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
627 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
628 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
629 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
630 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
631 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
632 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
633 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
634 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
635 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
636 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
637 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
638 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
639 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
640 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
641 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
642 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
643 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
644 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
645 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
646 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
647 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
648 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
649 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
650 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
651 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
652 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
653 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
654 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
655 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
656 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
657 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
658 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
659 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
660 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
661 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
662 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
663 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
664 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
665 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
666 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
667 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
668 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
669 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
670 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
671 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
672 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
673 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
674 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
675 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
676 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
677 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
678 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
679 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
680 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
681 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
682 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
683 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
684 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
685 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
686 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
687 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
688 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
689 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
690 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
691 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
692 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
693 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
694 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
695 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
696 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
697 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
698 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
699 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
700 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
701 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
702 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
703 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
704 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
705 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
706 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
707 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
708 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
709 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
710 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
711 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
712 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
713 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
714 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
715 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
716 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
717 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
718 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
719 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
720 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
721 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
722 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
723 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
724 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
725 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
726 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
727 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
728 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
729 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
730 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
731 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
732 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
733 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
734 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
735 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
736 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
737 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
738 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
739 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
740 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
741 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
742 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
743 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
744 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
745 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
746 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
747 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
748 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
749 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
750 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
751 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
752 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
753 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
754 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
755 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
756 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
757 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
758 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
759 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
760 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
761 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
762 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
763 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
764 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
765 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
766 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
767 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
768 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
769 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
770 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
771 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
772 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
773 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
774 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
775 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
776 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
777 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
778 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
779 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
780 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
781 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
782 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
783 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
784 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
785 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
786 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
787 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
788 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
789 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
790 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
791 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
792 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
793 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
794 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
795 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
796 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
797 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
798 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
799 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
800 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
801 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
802 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
803 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
804 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
805 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
806 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
807 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
808 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
809 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
810 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
811 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
812 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
813 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
814 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
815 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
816 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
817 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
818 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
819 { RGB_TO_ULONG(255, 181, 197), "pink1" },
820 { RGB_TO_ULONG(238, 169, 184), "pink2" },
821 { RGB_TO_ULONG(205, 145, 158), "pink3" },
822 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
823 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
824 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
825 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
826 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
827 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
828 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
829 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
830 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
831 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
832 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
833 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
834 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
835 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
836 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
837 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
838 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
839 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
840 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
841 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
842 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
843 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
844 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
845 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
846 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
847 { RGB_TO_ULONG(255, 187, 255), "plum1" },
848 { RGB_TO_ULONG(238, 174, 238), "plum2" },
849 { RGB_TO_ULONG(205, 150, 205), "plum3" },
850 { RGB_TO_ULONG(139, 102, 139), "plum4" },
851 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
852 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
853 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
854 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
855 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
856 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
857 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
858 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
859 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
860 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
861 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
862 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
863 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
864 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
865 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
866 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
867 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
868 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
869 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
870 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
871 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
872 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
873 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
874 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
875 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
876 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
877 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
878 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
879 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
880 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
881 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
882 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
883 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
884 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
885 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
886 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
887 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
888 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
889 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
890 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
891 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
892 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
893 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
894 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
895 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
896 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
897 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
898 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
899 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
900 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
901 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
902 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
903 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
904 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
905 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
906 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
907 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
908 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
909 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
910 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
911 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
912 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
913 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
914 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
915 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
916 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
917 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
918 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
919 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
920 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
921 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
922 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
923 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
924 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
925 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
926 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
927 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
928 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
929 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
930 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
931 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
932 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
933 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
934 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
935 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
936 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
937 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
938 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
939 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
940 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
941 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
942 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
943 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
944 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
945 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
946 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
947 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
948 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
949 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
950 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
951 { RGB_TO_ULONG(102, 102, 102), "gray40" },
952 { RGB_TO_ULONG(102, 102, 102), "grey40" },
953 { RGB_TO_ULONG(105, 105, 105), "gray41" },
954 { RGB_TO_ULONG(105, 105, 105), "grey41" },
955 { RGB_TO_ULONG(107, 107, 107), "gray42" },
956 { RGB_TO_ULONG(107, 107, 107), "grey42" },
957 { RGB_TO_ULONG(110, 110, 110), "gray43" },
958 { RGB_TO_ULONG(110, 110, 110), "grey43" },
959 { RGB_TO_ULONG(112, 112, 112), "gray44" },
960 { RGB_TO_ULONG(112, 112, 112), "grey44" },
961 { RGB_TO_ULONG(115, 115, 115), "gray45" },
962 { RGB_TO_ULONG(115, 115, 115), "grey45" },
963 { RGB_TO_ULONG(117, 117, 117), "gray46" },
964 { RGB_TO_ULONG(117, 117, 117), "grey46" },
965 { RGB_TO_ULONG(120, 120, 120), "gray47" },
966 { RGB_TO_ULONG(120, 120, 120), "grey47" },
967 { RGB_TO_ULONG(122, 122, 122), "gray48" },
968 { RGB_TO_ULONG(122, 122, 122), "grey48" },
969 { RGB_TO_ULONG(125, 125, 125), "gray49" },
970 { RGB_TO_ULONG(125, 125, 125), "grey49" },
971 { RGB_TO_ULONG(127, 127, 127), "gray50" },
972 { RGB_TO_ULONG(127, 127, 127), "grey50" },
973 { RGB_TO_ULONG(130, 130, 130), "gray51" },
974 { RGB_TO_ULONG(130, 130, 130), "grey51" },
975 { RGB_TO_ULONG(133, 133, 133), "gray52" },
976 { RGB_TO_ULONG(133, 133, 133), "grey52" },
977 { RGB_TO_ULONG(135, 135, 135), "gray53" },
978 { RGB_TO_ULONG(135, 135, 135), "grey53" },
979 { RGB_TO_ULONG(138, 138, 138), "gray54" },
980 { RGB_TO_ULONG(138, 138, 138), "grey54" },
981 { RGB_TO_ULONG(140, 140, 140), "gray55" },
982 { RGB_TO_ULONG(140, 140, 140), "grey55" },
983 { RGB_TO_ULONG(143, 143, 143), "gray56" },
984 { RGB_TO_ULONG(143, 143, 143), "grey56" },
985 { RGB_TO_ULONG(145, 145, 145), "gray57" },
986 { RGB_TO_ULONG(145, 145, 145), "grey57" },
987 { RGB_TO_ULONG(148, 148, 148), "gray58" },
988 { RGB_TO_ULONG(148, 148, 148), "grey58" },
989 { RGB_TO_ULONG(150, 150, 150), "gray59" },
990 { RGB_TO_ULONG(150, 150, 150), "grey59" },
991 { RGB_TO_ULONG(153, 153, 153), "gray60" },
992 { RGB_TO_ULONG(153, 153, 153), "grey60" },
993 { RGB_TO_ULONG(156, 156, 156), "gray61" },
994 { RGB_TO_ULONG(156, 156, 156), "grey61" },
995 { RGB_TO_ULONG(158, 158, 158), "gray62" },
996 { RGB_TO_ULONG(158, 158, 158), "grey62" },
997 { RGB_TO_ULONG(161, 161, 161), "gray63" },
998 { RGB_TO_ULONG(161, 161, 161), "grey63" },
999 { RGB_TO_ULONG(163, 163, 163), "gray64" },
1000 { RGB_TO_ULONG(163, 163, 163), "grey64" },
1001 { RGB_TO_ULONG(166, 166, 166), "gray65" },
1002 { RGB_TO_ULONG(166, 166, 166), "grey65" },
1003 { RGB_TO_ULONG(168, 168, 168), "gray66" },
1004 { RGB_TO_ULONG(168, 168, 168), "grey66" },
1005 { RGB_TO_ULONG(171, 171, 171), "gray67" },
1006 { RGB_TO_ULONG(171, 171, 171), "grey67" },
1007 { RGB_TO_ULONG(173, 173, 173), "gray68" },
1008 { RGB_TO_ULONG(173, 173, 173), "grey68" },
1009 { RGB_TO_ULONG(176, 176, 176), "gray69" },
1010 { RGB_TO_ULONG(176, 176, 176), "grey69" },
1011 { RGB_TO_ULONG(179, 179, 179), "gray70" },
1012 { RGB_TO_ULONG(179, 179, 179), "grey70" },
1013 { RGB_TO_ULONG(181, 181, 181), "gray71" },
1014 { RGB_TO_ULONG(181, 181, 181), "grey71" },
1015 { RGB_TO_ULONG(184, 184, 184), "gray72" },
1016 { RGB_TO_ULONG(184, 184, 184), "grey72" },
1017 { RGB_TO_ULONG(186, 186, 186), "gray73" },
1018 { RGB_TO_ULONG(186, 186, 186), "grey73" },
1019 { RGB_TO_ULONG(189, 189, 189), "gray74" },
1020 { RGB_TO_ULONG(189, 189, 189), "grey74" },
1021 { RGB_TO_ULONG(191, 191, 191), "gray75" },
1022 { RGB_TO_ULONG(191, 191, 191), "grey75" },
1023 { RGB_TO_ULONG(194, 194, 194), "gray76" },
1024 { RGB_TO_ULONG(194, 194, 194), "grey76" },
1025 { RGB_TO_ULONG(196, 196, 196), "gray77" },
1026 { RGB_TO_ULONG(196, 196, 196), "grey77" },
1027 { RGB_TO_ULONG(199, 199, 199), "gray78" },
1028 { RGB_TO_ULONG(199, 199, 199), "grey78" },
1029 { RGB_TO_ULONG(201, 201, 201), "gray79" },
1030 { RGB_TO_ULONG(201, 201, 201), "grey79" },
1031 { RGB_TO_ULONG(204, 204, 204), "gray80" },
1032 { RGB_TO_ULONG(204, 204, 204), "grey80" },
1033 { RGB_TO_ULONG(207, 207, 207), "gray81" },
1034 { RGB_TO_ULONG(207, 207, 207), "grey81" },
1035 { RGB_TO_ULONG(209, 209, 209), "gray82" },
1036 { RGB_TO_ULONG(209, 209, 209), "grey82" },
1037 { RGB_TO_ULONG(212, 212, 212), "gray83" },
1038 { RGB_TO_ULONG(212, 212, 212), "grey83" },
1039 { RGB_TO_ULONG(214, 214, 214), "gray84" },
1040 { RGB_TO_ULONG(214, 214, 214), "grey84" },
1041 { RGB_TO_ULONG(217, 217, 217), "gray85" },
1042 { RGB_TO_ULONG(217, 217, 217), "grey85" },
1043 { RGB_TO_ULONG(219, 219, 219), "gray86" },
1044 { RGB_TO_ULONG(219, 219, 219), "grey86" },
1045 { RGB_TO_ULONG(222, 222, 222), "gray87" },
1046 { RGB_TO_ULONG(222, 222, 222), "grey87" },
1047 { RGB_TO_ULONG(224, 224, 224), "gray88" },
1048 { RGB_TO_ULONG(224, 224, 224), "grey88" },
1049 { RGB_TO_ULONG(227, 227, 227), "gray89" },
1050 { RGB_TO_ULONG(227, 227, 227), "grey89" },
1051 { RGB_TO_ULONG(229, 229, 229), "gray90" },
1052 { RGB_TO_ULONG(229, 229, 229), "grey90" },
1053 { RGB_TO_ULONG(232, 232, 232), "gray91" },
1054 { RGB_TO_ULONG(232, 232, 232), "grey91" },
1055 { RGB_TO_ULONG(235, 235, 235), "gray92" },
1056 { RGB_TO_ULONG(235, 235, 235), "grey92" },
1057 { RGB_TO_ULONG(237, 237, 237), "gray93" },
1058 { RGB_TO_ULONG(237, 237, 237), "grey93" },
1059 { RGB_TO_ULONG(240, 240, 240), "gray94" },
1060 { RGB_TO_ULONG(240, 240, 240), "grey94" },
1061 { RGB_TO_ULONG(242, 242, 242), "gray95" },
1062 { RGB_TO_ULONG(242, 242, 242), "grey95" },
1063 { RGB_TO_ULONG(245, 245, 245), "gray96" },
1064 { RGB_TO_ULONG(245, 245, 245), "grey96" },
1065 { RGB_TO_ULONG(247, 247, 247), "gray97" },
1066 { RGB_TO_ULONG(247, 247, 247), "grey97" },
1067 { RGB_TO_ULONG(250, 250, 250), "gray98" },
1068 { RGB_TO_ULONG(250, 250, 250), "grey98" },
1069 { RGB_TO_ULONG(252, 252, 252), "gray99" },
1070 { RGB_TO_ULONG(252, 252, 252), "grey99" },
1071 { RGB_TO_ULONG(255, 255, 255), "gray100" },
1072 { RGB_TO_ULONG(255, 255, 255), "grey100" },
1073 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
1074 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
1075 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
1076 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
1077 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
1078 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
1079 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
1080 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
1081 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
1082 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
1083 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
1084 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1085 { RGB_TO_ULONG(144, 238, 144), "light green" },
1086 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1089 Lisp_Object
1090 mac_color_map_lookup (colorname)
1091 char *colorname;
1093 Lisp_Object ret = Qnil;
1094 int i;
1096 BLOCK_INPUT;
1098 for (i = 0; i < sizeof (mac_color_map) / sizeof (mac_color_map[0]); i++)
1099 if (xstricmp (colorname, mac_color_map[i].name) == 0)
1101 ret = make_number (mac_color_map[i].color);
1102 break;
1105 UNBLOCK_INPUT;
1107 return ret;
1110 Lisp_Object
1111 x_to_mac_color (colorname)
1112 char * colorname;
1114 register Lisp_Object tail, ret = Qnil;
1116 BLOCK_INPUT;
1118 if (colorname[0] == '#')
1120 /* Could be an old-style RGB Device specification. */
1121 char *color;
1122 int size;
1123 color = colorname + 1;
1125 size = strlen(color);
1126 if (size == 3 || size == 6 || size == 9 || size == 12)
1128 unsigned long colorval;
1129 int i, pos;
1130 pos = 16;
1131 size /= 3;
1132 colorval = 0;
1134 for (i = 0; i < 3; i++)
1136 char *end;
1137 char t;
1138 unsigned long value;
1140 /* The check for 'x' in the following conditional takes into
1141 account the fact that strtol allows a "0x" in front of
1142 our numbers, and we don't. */
1143 if (!isxdigit(color[0]) || color[1] == 'x')
1144 break;
1145 t = color[size];
1146 color[size] = '\0';
1147 value = strtoul(color, &end, 16);
1148 color[size] = t;
1149 if (errno == ERANGE || end - color != size)
1150 break;
1151 switch (size)
1153 case 1:
1154 value = value * 0x10;
1155 break;
1156 case 2:
1157 break;
1158 case 3:
1159 value /= 0x10;
1160 break;
1161 case 4:
1162 value /= 0x100;
1163 break;
1165 colorval |= (value << pos);
1166 pos -= 8;
1167 if (i == 2)
1169 UNBLOCK_INPUT;
1170 return make_number (colorval);
1172 color = end;
1176 else if (strnicmp(colorname, "rgb:", 4) == 0)
1178 char *color;
1179 unsigned long colorval;
1180 int i, pos;
1181 pos = 0;
1183 colorval = 0;
1184 color = colorname + 4;
1185 for (i = 0; i < 3; i++)
1187 char *end;
1188 unsigned long value;
1190 /* The check for 'x' in the following conditional takes into
1191 account the fact that strtol allows a "0x" in front of
1192 our numbers, and we don't. */
1193 if (!isxdigit(color[0]) || color[1] == 'x')
1194 break;
1195 value = strtoul(color, &end, 16);
1196 if (errno == ERANGE)
1197 break;
1198 switch (end - color)
1200 case 1:
1201 value = value * 0x10 + value;
1202 break;
1203 case 2:
1204 break;
1205 case 3:
1206 value /= 0x10;
1207 break;
1208 case 4:
1209 value /= 0x100;
1210 break;
1211 default:
1212 value = ULONG_MAX;
1214 if (value == ULONG_MAX)
1215 break;
1216 colorval |= (value << pos);
1217 pos += 0x8;
1218 if (i == 2)
1220 if (*end != '\0')
1221 break;
1222 UNBLOCK_INPUT;
1223 return make_number (colorval);
1225 if (*end != '/')
1226 break;
1227 color = end + 1;
1230 else if (strnicmp(colorname, "rgbi:", 5) == 0)
1232 /* This is an RGB Intensity specification. */
1233 char *color;
1234 unsigned long colorval;
1235 int i, pos;
1236 pos = 0;
1238 colorval = 0;
1239 color = colorname + 5;
1240 for (i = 0; i < 3; i++)
1242 char *end;
1243 double value;
1244 unsigned long val;
1246 value = strtod(color, &end);
1247 if (errno == ERANGE)
1248 break;
1249 if (value < 0.0 || value > 1.0)
1250 break;
1251 val = (unsigned long)(0x100 * value);
1252 /* We used 0x100 instead of 0xFF to give a continuous
1253 range between 0.0 and 1.0 inclusive. The next statement
1254 fixes the 1.0 case. */
1255 if (val == 0x100)
1256 val = 0xFF;
1257 colorval |= (val << pos);
1258 pos += 0x8;
1259 if (i == 2)
1261 if (*end != '\0')
1262 break;
1263 UNBLOCK_INPUT;
1264 return make_number (colorval);
1266 if (*end != '/')
1267 break;
1268 color = end + 1;
1272 ret = mac_color_map_lookup (colorname);
1274 UNBLOCK_INPUT;
1275 return ret;
1278 /* Gamma-correct COLOR on frame F. */
1280 void
1281 gamma_correct (f, color)
1282 struct frame *f;
1283 unsigned long *color;
1285 if (f->gamma)
1287 unsigned long red, green, blue;
1289 red = pow (RED_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1290 green = pow (GREEN_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1291 blue = pow (BLUE_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1292 *color = RGB_TO_ULONG (red, green, blue);
1296 /* Decide if color named COLOR is valid for the display associated
1297 with the selected frame; if so, return the rgb values in COLOR_DEF.
1298 If ALLOC is nonzero, allocate a new colormap cell. */
1301 mac_defined_color (f, color, color_def, alloc)
1302 FRAME_PTR f;
1303 char *color;
1304 XColor *color_def;
1305 int alloc;
1307 register Lisp_Object tem;
1308 unsigned long mac_color_ref;
1310 tem = x_to_mac_color (color);
1312 if (!NILP (tem))
1314 if (f)
1316 /* Apply gamma correction. */
1317 mac_color_ref = XUINT (tem);
1318 gamma_correct (f, &mac_color_ref);
1319 XSETINT (tem, mac_color_ref);
1322 color_def->pixel = mac_color_ref;
1323 color_def->red = RED16_FROM_ULONG (mac_color_ref);
1324 color_def->green = GREEN16_FROM_ULONG (mac_color_ref);
1325 color_def->blue = BLUE16_FROM_ULONG (mac_color_ref);
1327 return 1;
1329 else
1331 return 0;
1335 /* Given a string ARG naming a color, compute a pixel value from it
1336 suitable for screen F.
1337 If F is not a color screen, return DEF (default) regardless of what
1338 ARG says. */
1341 x_decode_color (f, arg, def)
1342 FRAME_PTR f;
1343 Lisp_Object arg;
1344 int def;
1346 XColor cdef;
1348 CHECK_STRING (arg);
1350 if (strcmp (SDATA (arg), "black") == 0)
1351 return BLACK_PIX_DEFAULT (f);
1352 else if (strcmp (SDATA (arg), "white") == 0)
1353 return WHITE_PIX_DEFAULT (f);
1355 #if 0
1356 if (FRAME_MAC_DISPLAY_INFO (f)->n_planes) == 1)
1357 return def;
1358 #endif
1360 if (mac_defined_color (f, SDATA (arg), &cdef, 1))
1361 return cdef.pixel;
1363 /* defined_color failed; return an ultimate default. */
1364 return def;
1367 /* Functions called only from `x_set_frame_param'
1368 to set individual parameters.
1370 If FRAME_MAC_WINDOW (f) is 0,
1371 the frame is being created and its window does not exist yet.
1372 In that case, just record the parameter's new value
1373 in the standard place; do not attempt to change the window. */
1375 void
1376 x_set_foreground_color (f, arg, oldval)
1377 struct frame *f;
1378 Lisp_Object arg, oldval;
1380 struct mac_output *mac = f->output_data.mac;
1381 unsigned long fg, old_fg;
1383 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1384 old_fg = FRAME_FOREGROUND_PIXEL (f);
1385 FRAME_FOREGROUND_PIXEL (f) = fg;
1387 if (FRAME_MAC_WINDOW (f) != 0)
1389 Display *dpy = FRAME_MAC_DISPLAY (f);
1391 BLOCK_INPUT;
1392 XSetForeground (dpy, mac->normal_gc, fg);
1393 XSetBackground (dpy, mac->reverse_gc, fg);
1395 if (mac->cursor_pixel == old_fg)
1397 unload_color (f, mac->cursor_pixel);
1398 mac->cursor_pixel = fg;
1399 XSetBackground (dpy, mac->cursor_gc, mac->cursor_pixel);
1402 UNBLOCK_INPUT;
1404 update_face_from_frame_parameter (f, Qforeground_color, arg);
1406 if (FRAME_VISIBLE_P (f))
1407 redraw_frame (f);
1410 unload_color (f, old_fg);
1413 void
1414 x_set_background_color (f, arg, oldval)
1415 struct frame *f;
1416 Lisp_Object arg, oldval;
1418 struct mac_output *mac = f->output_data.mac;
1419 unsigned long bg;
1421 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
1422 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
1423 FRAME_BACKGROUND_PIXEL (f) = bg;
1425 if (FRAME_MAC_WINDOW (f) != 0)
1427 Display *dpy = FRAME_MAC_DISPLAY (f);
1429 BLOCK_INPUT;
1430 XSetBackground (dpy, mac->normal_gc, bg);
1431 XSetForeground (dpy, mac->reverse_gc, bg);
1432 XSetWindowBackground (dpy, FRAME_MAC_WINDOW (f), bg);
1433 XSetForeground (dpy, mac->cursor_gc, bg);
1435 UNBLOCK_INPUT;
1436 update_face_from_frame_parameter (f, Qbackground_color, arg);
1438 if (FRAME_VISIBLE_P (f))
1439 redraw_frame (f);
1443 void
1444 x_set_mouse_color (f, arg, oldval)
1445 struct frame *f;
1446 Lisp_Object arg, oldval;
1448 struct x_output *x = f->output_data.x;
1449 Display *dpy = FRAME_MAC_DISPLAY (f);
1450 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
1451 Cursor hourglass_cursor, horizontal_drag_cursor;
1452 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1453 unsigned long mask_color = x->background_pixel;
1455 /* Don't let pointers be invisible. */
1456 if (mask_color == pixel)
1457 pixel = x->foreground_pixel;
1459 f->output_data.mac->mouse_pixel = pixel;
1461 if (!NILP (Vx_pointer_shape))
1463 CHECK_NUMBER (Vx_pointer_shape);
1464 cursor = XINT (Vx_pointer_shape);
1466 else
1467 cursor = kThemeIBeamCursor;
1469 if (!NILP (Vx_nontext_pointer_shape))
1471 CHECK_NUMBER (Vx_nontext_pointer_shape);
1472 nontext_cursor = XINT (Vx_nontext_pointer_shape);
1474 else
1475 nontext_cursor = kThemeArrowCursor;
1477 if (!NILP (Vx_hourglass_pointer_shape))
1479 CHECK_NUMBER (Vx_hourglass_pointer_shape);
1480 hourglass_cursor = XINT (Vx_hourglass_pointer_shape);
1482 else
1483 hourglass_cursor = kThemeWatchCursor;
1485 if (!NILP (Vx_mode_pointer_shape))
1487 CHECK_NUMBER (Vx_mode_pointer_shape);
1488 mode_cursor = XINT (Vx_mode_pointer_shape);
1490 else
1491 mode_cursor = kThemeArrowCursor;
1493 if (!NILP (Vx_sensitive_text_pointer_shape))
1495 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1496 hand_cursor = XINT (Vx_sensitive_text_pointer_shape);
1498 else
1499 hand_cursor = kThemePointingHandCursor;
1501 if (!NILP (Vx_window_horizontal_drag_shape))
1503 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1504 horizontal_drag_cursor = XINT (Vx_window_horizontal_drag_shape);
1506 else
1507 horizontal_drag_cursor = kThemeResizeLeftRightCursor;
1509 #if 0 /* MAC_TODO: cursor color changes */
1511 XColor fore_color, back_color;
1513 fore_color.pixel = f->output_data.mac->mouse_pixel;
1514 x_query_color (f, &fore_color);
1515 back_color.pixel = mask_color;
1516 x_query_color (f, &back_color);
1518 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1519 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1520 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1521 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1522 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1523 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1525 #endif
1527 BLOCK_INPUT;
1529 rif->define_frame_cursor (f, cursor);
1531 f->output_data.mac->text_cursor = cursor;
1532 f->output_data.mac->nontext_cursor = nontext_cursor;
1533 f->output_data.mac->hourglass_cursor = hourglass_cursor;
1534 f->output_data.mac->modeline_cursor = mode_cursor;
1535 f->output_data.mac->hand_cursor = hand_cursor;
1536 f->output_data.mac->horizontal_drag_cursor = horizontal_drag_cursor;
1538 UNBLOCK_INPUT;
1540 update_face_from_frame_parameter (f, Qmouse_color, arg);
1543 void
1544 x_set_cursor_color (f, arg, oldval)
1545 struct frame *f;
1546 Lisp_Object arg, oldval;
1548 unsigned long fore_pixel, pixel;
1550 if (!NILP (Vx_cursor_fore_pixel))
1551 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1552 WHITE_PIX_DEFAULT (f));
1553 else
1554 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1556 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1558 /* Make sure that the cursor color differs from the background color. */
1559 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1561 pixel = f->output_data.mac->mouse_pixel;
1562 if (pixel == fore_pixel)
1563 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1566 f->output_data.mac->cursor_foreground_pixel = fore_pixel;
1567 f->output_data.mac->cursor_pixel = pixel;
1569 if (FRAME_MAC_WINDOW (f) != 0)
1571 BLOCK_INPUT;
1572 /* Update frame's cursor_gc. */
1573 f->output_data.mac->cursor_gc->foreground = fore_pixel;
1574 f->output_data.mac->cursor_gc->background = pixel;
1576 UNBLOCK_INPUT;
1578 if (FRAME_VISIBLE_P (f))
1580 x_update_cursor (f, 0);
1581 x_update_cursor (f, 1);
1585 update_face_from_frame_parameter (f, Qcursor_color, arg);
1588 /* Set the border-color of frame F to pixel value PIX.
1589 Note that this does not fully take effect if done before
1590 F has a window. */
1592 void
1593 x_set_border_pixel (f, pix)
1594 struct frame *f;
1595 int pix;
1598 f->output_data.mac->border_pixel = pix;
1600 if (FRAME_MAC_WINDOW (f) != 0 && f->border_width > 0)
1602 if (FRAME_VISIBLE_P (f))
1603 redraw_frame (f);
1607 /* Set the border-color of frame F to value described by ARG.
1608 ARG can be a string naming a color.
1609 The border-color is used for the border that is drawn by the server.
1610 Note that this does not fully take effect if done before
1611 F has a window; it must be redone when the window is created. */
1613 void
1614 x_set_border_color (f, arg, oldval)
1615 struct frame *f;
1616 Lisp_Object arg, oldval;
1618 int pix;
1620 CHECK_STRING (arg);
1621 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1622 x_set_border_pixel (f, pix);
1623 update_face_from_frame_parameter (f, Qborder_color, arg);
1627 void
1628 x_set_cursor_type (f, arg, oldval)
1629 FRAME_PTR f;
1630 Lisp_Object arg, oldval;
1632 set_frame_cursor_types (f, arg);
1634 /* Make sure the cursor gets redrawn. */
1635 cursor_type_changed = 1;
1638 #if 0 /* MAC_TODO: really no icon for Mac */
1639 void
1640 x_set_icon_type (f, arg, oldval)
1641 struct frame *f;
1642 Lisp_Object arg, oldval;
1644 int result;
1646 if (NILP (arg) && NILP (oldval))
1647 return;
1649 if (STRINGP (arg) && STRINGP (oldval)
1650 && EQ (Fstring_equal (oldval, arg), Qt))
1651 return;
1653 if (SYMBOLP (arg) && SYMBOLP (oldval) && EQ (arg, oldval))
1654 return;
1656 BLOCK_INPUT;
1658 result = x_bitmap_icon (f, arg);
1659 if (result)
1661 UNBLOCK_INPUT;
1662 error ("No icon window available");
1665 UNBLOCK_INPUT;
1667 #endif /* MAC_TODO */
1669 void
1670 x_set_icon_name (f, arg, oldval)
1671 struct frame *f;
1672 Lisp_Object arg, oldval;
1674 int result;
1676 if (STRINGP (arg))
1678 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1679 return;
1681 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1682 return;
1684 f->icon_name = arg;
1686 #if 0 /* MAC_TODO */
1687 if (f->output_data.w32->icon_bitmap != 0)
1688 return;
1690 BLOCK_INPUT;
1692 result = x_text_icon (f,
1693 (char *) SDATA ((!NILP (f->icon_name)
1694 ? f->icon_name
1695 : !NILP (f->title)
1696 ? f->title
1697 : f->name)));
1699 if (result)
1701 UNBLOCK_INPUT;
1702 error ("No icon window available");
1705 /* If the window was unmapped (and its icon was mapped),
1706 the new icon is not mapped, so map the window in its stead. */
1707 if (FRAME_VISIBLE_P (f))
1709 #ifdef USE_X_TOOLKIT
1710 XtPopup (f->output_data.w32->widget, XtGrabNone);
1711 #endif
1712 XMapWindow (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f));
1715 XFlush (FRAME_W32_DISPLAY (f));
1716 UNBLOCK_INPUT;
1717 #endif /* MAC_TODO */
1721 void
1722 x_set_menu_bar_lines (f, value, oldval)
1723 struct frame *f;
1724 Lisp_Object value, oldval;
1726 int nlines;
1727 int olines = FRAME_MENU_BAR_LINES (f);
1729 /* Right now, menu bars don't work properly in minibuf-only frames;
1730 most of the commands try to apply themselves to the minibuffer
1731 frame itself, and get an error because you can't switch buffers
1732 in or split the minibuffer window. */
1733 if (FRAME_MINIBUF_ONLY_P (f))
1734 return;
1736 if (INTEGERP (value))
1737 nlines = XINT (value);
1738 else
1739 nlines = 0;
1741 FRAME_MENU_BAR_LINES (f) = 0;
1742 if (nlines)
1743 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1744 else
1746 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1747 free_frame_menubar (f);
1748 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1750 /* Adjust the frame size so that the client (text) dimensions
1751 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
1752 set correctly. */
1753 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
1754 do_pending_window_change (0);
1756 adjust_glyphs (f);
1760 /* Set the number of lines used for the tool bar of frame F to VALUE.
1761 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1762 is the old number of tool bar lines. This function changes the
1763 height of all windows on frame F to match the new tool bar height.
1764 The frame's height doesn't change. */
1766 void
1767 x_set_tool_bar_lines (f, value, oldval)
1768 struct frame *f;
1769 Lisp_Object value, oldval;
1771 int delta, nlines, root_height;
1772 Lisp_Object root_window;
1774 /* Treat tool bars like menu bars. */
1775 if (FRAME_MINIBUF_ONLY_P (f))
1776 return;
1778 /* Use VALUE only if an integer >= 0. */
1779 if (INTEGERP (value) && XINT (value) >= 0)
1780 nlines = XFASTINT (value);
1781 else
1782 nlines = 0;
1784 /* Make sure we redisplay all windows in this frame. */
1785 ++windows_or_buffers_changed;
1787 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1789 /* Don't resize the tool-bar to more than we have room for. */
1790 root_window = FRAME_ROOT_WINDOW (f);
1791 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1792 if (root_height - delta < 1)
1794 delta = root_height - 1;
1795 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1798 FRAME_TOOL_BAR_LINES (f) = nlines;
1799 change_window_heights (root_window, delta);
1800 adjust_glyphs (f);
1802 /* We also have to make sure that the internal border at the top of
1803 the frame, below the menu bar or tool bar, is redrawn when the
1804 tool bar disappears. This is so because the internal border is
1805 below the tool bar if one is displayed, but is below the menu bar
1806 if there isn't a tool bar. The tool bar draws into the area
1807 below the menu bar. */
1808 if (FRAME_MAC_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1810 updating_frame = f;
1811 clear_frame ();
1812 clear_current_matrices (f);
1813 updating_frame = NULL;
1816 /* If the tool bar gets smaller, the internal border below it
1817 has to be cleared. It was formerly part of the display
1818 of the larger tool bar, and updating windows won't clear it. */
1819 if (delta < 0)
1821 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1822 int width = FRAME_PIXEL_WIDTH (f);
1823 int y = nlines * FRAME_LINE_HEIGHT (f);
1825 BLOCK_INPUT;
1826 XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
1827 0, y, width, height, 0);
1828 UNBLOCK_INPUT;
1830 if (WINDOWP (f->tool_bar_window))
1831 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1836 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1837 w32_id_name.
1839 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1840 name; if NAME is a string, set F's name to NAME and set
1841 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1843 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1844 suggesting a new name, which lisp code should override; if
1845 F->explicit_name is set, ignore the new name; otherwise, set it. */
1847 void
1848 x_set_name (f, name, explicit)
1849 struct frame *f;
1850 Lisp_Object name;
1851 int explicit;
1853 /* Make sure that requests from lisp code override requests from
1854 Emacs redisplay code. */
1855 if (explicit)
1857 /* If we're switching from explicit to implicit, we had better
1858 update the mode lines and thereby update the title. */
1859 if (f->explicit_name && NILP (name))
1860 update_mode_lines = 1;
1862 f->explicit_name = ! NILP (name);
1864 else if (f->explicit_name)
1865 return;
1867 /* If NAME is nil, set the name to the w32_id_name. */
1868 if (NILP (name))
1870 /* Check for no change needed in this very common case
1871 before we do any consing. */
1872 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name,
1873 SDATA (f->name)))
1874 return;
1875 name = build_string (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name);
1877 else
1878 CHECK_STRING (name);
1880 /* Don't change the name if it's already NAME. */
1881 if (! NILP (Fstring_equal (name, f->name)))
1882 return;
1884 f->name = name;
1886 /* For setting the frame title, the title parameter should override
1887 the name parameter. */
1888 if (! NILP (f->title))
1889 name = f->title;
1891 if (FRAME_MAC_WINDOW (f))
1893 if (STRING_MULTIBYTE (name))
1894 #if TARGET_API_MAC_CARBON
1895 name = ENCODE_UTF_8 (name);
1896 #else
1897 name = ENCODE_SYSTEM (name);
1898 #endif
1900 BLOCK_INPUT;
1903 #if TARGET_API_MAC_CARBON
1904 CFStringRef windowTitle =
1905 cfstring_create_with_utf8_cstring (SDATA (name));
1907 SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle);
1908 CFRelease (windowTitle);
1909 #else
1910 Str255 windowTitle;
1911 if (strlen (SDATA (name)) < 255)
1913 strcpy (windowTitle, SDATA (name));
1914 c2pstr (windowTitle);
1915 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
1917 #endif
1920 UNBLOCK_INPUT;
1924 /* This function should be called when the user's lisp code has
1925 specified a name for the frame; the name will override any set by the
1926 redisplay code. */
1927 void
1928 x_explicitly_set_name (f, arg, oldval)
1929 FRAME_PTR f;
1930 Lisp_Object arg, oldval;
1932 x_set_name (f, arg, 1);
1935 /* This function should be called by Emacs redisplay code to set the
1936 name; names set this way will never override names set by the user's
1937 lisp code. */
1938 void
1939 x_implicitly_set_name (f, arg, oldval)
1940 FRAME_PTR f;
1941 Lisp_Object arg, oldval;
1943 x_set_name (f, arg, 0);
1946 /* Change the title of frame F to NAME.
1947 If NAME is nil, use the frame name as the title.
1949 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1950 name; if NAME is a string, set F's name to NAME and set
1951 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1953 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1954 suggesting a new name, which lisp code should override; if
1955 F->explicit_name is set, ignore the new name; otherwise, set it. */
1957 void
1958 x_set_title (f, name, old_name)
1959 struct frame *f;
1960 Lisp_Object name, old_name;
1962 /* Don't change the title if it's already NAME. */
1963 if (EQ (name, f->title))
1964 return;
1966 update_mode_lines = 1;
1968 f->title = name;
1970 if (NILP (name))
1971 name = f->name;
1973 if (FRAME_MAC_WINDOW (f))
1975 if (STRING_MULTIBYTE (name))
1976 #if TARGET_API_MAC_CARBON
1977 name = ENCODE_UTF_8 (name);
1978 #else
1979 name = ENCODE_SYSTEM (name);
1980 #endif
1982 BLOCK_INPUT;
1985 #if TARGET_API_MAC_CARBON
1986 CFStringRef windowTitle =
1987 cfstring_create_with_utf8_cstring (SDATA (name));
1989 SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle);
1990 CFRelease (windowTitle);
1991 #else
1992 Str255 windowTitle;
1993 if (strlen (SDATA (name)) < 255)
1995 strcpy (windowTitle, SDATA (name));
1996 c2pstr (windowTitle);
1997 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
1999 #endif
2002 UNBLOCK_INPUT;
2006 void
2007 x_set_scroll_bar_default_width (f)
2008 struct frame *f;
2010 /* Imitate X without X Toolkit */
2012 int wid = FRAME_COLUMN_WIDTH (f);
2014 #ifdef MAC_OSX
2015 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 16; /* Aqua scroll bars. */
2016 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
2017 wid - 1) / wid;
2018 #else /* not MAC_OSX */
2019 /* Make the actual width at least 14 pixels and a multiple of a
2020 character width. */
2021 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
2023 /* Use all of that space (aside from required margins) for the
2024 scroll bar. */
2025 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
2026 #endif /* not MAC_OSX */
2030 /* Subroutines of creating a frame. */
2032 /* Retrieve the string resource specified by NAME with CLASS from
2033 database RDB.
2035 The return value points to the contents of a Lisp string. So it
2036 will not be valid after the next GC where string compaction will
2037 occur. */
2039 char *
2040 x_get_string_resource (rdb, name, class)
2041 XrmDatabase rdb;
2042 char *name, *class;
2044 Lisp_Object value = xrm_get_resource (rdb, name, class);
2046 if (STRINGP (value))
2047 return SDATA (value);
2048 else
2049 return NULL;
2052 /* Return the value of parameter PARAM.
2054 First search ALIST, then Vdefault_frame_alist, then the X defaults
2055 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2057 Convert the resource to the type specified by desired_type.
2059 If no default is specified, return Qunbound. If you call
2060 mac_get_arg, make sure you deal with Qunbound in a reasonable way,
2061 and don't let it get stored in any Lisp-visible variables! */
2063 static Lisp_Object
2064 mac_get_arg (alist, param, attribute, class, type)
2065 Lisp_Object alist, param;
2066 char *attribute;
2067 char *class;
2068 enum resource_types type;
2070 return x_get_arg (check_x_display_info (Qnil),
2071 alist, param, attribute, class, type);
2075 /* XParseGeometry copied from w32xfns.c */
2078 * XParseGeometry parses strings of the form
2079 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
2080 * width, height, xoffset, and yoffset are unsigned integers.
2081 * Example: "=80x24+300-49"
2082 * The equal sign is optional.
2083 * It returns a bitmask that indicates which of the four values
2084 * were actually found in the string. For each value found,
2085 * the corresponding argument is updated; for each value
2086 * not found, the corresponding argument is left unchanged.
2089 static int
2090 read_integer (string, NextString)
2091 register char *string;
2092 char **NextString;
2094 register int Result = 0;
2095 int Sign = 1;
2097 if (*string == '+')
2098 string++;
2099 else if (*string == '-')
2101 string++;
2102 Sign = -1;
2104 for (; (*string >= '0') && (*string <= '9'); string++)
2106 Result = (Result * 10) + (*string - '0');
2108 *NextString = string;
2109 if (Sign >= 0)
2110 return (Result);
2111 else
2112 return (-Result);
2116 XParseGeometry (string, x, y, width, height)
2117 char *string;
2118 int *x, *y;
2119 unsigned int *width, *height; /* RETURN */
2121 int mask = NoValue;
2122 register char *strind;
2123 unsigned int tempWidth, tempHeight;
2124 int tempX, tempY;
2125 char *nextCharacter;
2127 if ((string == NULL) || (*string == '\0')) return (mask);
2128 if (*string == '=')
2129 string++; /* ignore possible '=' at beg of geometry spec */
2131 strind = (char *)string;
2132 if (*strind != '+' && *strind != '-' && *strind != 'x')
2134 tempWidth = read_integer (strind, &nextCharacter);
2135 if (strind == nextCharacter)
2136 return (0);
2137 strind = nextCharacter;
2138 mask |= WidthValue;
2141 if (*strind == 'x' || *strind == 'X')
2143 strind++;
2144 tempHeight = read_integer (strind, &nextCharacter);
2145 if (strind == nextCharacter)
2146 return (0);
2147 strind = nextCharacter;
2148 mask |= HeightValue;
2151 if ((*strind == '+') || (*strind == '-'))
2153 if (*strind == '-')
2155 strind++;
2156 tempX = -read_integer (strind, &nextCharacter);
2157 if (strind == nextCharacter)
2158 return (0);
2159 strind = nextCharacter;
2160 mask |= XNegative;
2163 else
2165 strind++;
2166 tempX = read_integer (strind, &nextCharacter);
2167 if (strind == nextCharacter)
2168 return (0);
2169 strind = nextCharacter;
2171 mask |= XValue;
2172 if ((*strind == '+') || (*strind == '-'))
2174 if (*strind == '-')
2176 strind++;
2177 tempY = -read_integer (strind, &nextCharacter);
2178 if (strind == nextCharacter)
2179 return (0);
2180 strind = nextCharacter;
2181 mask |= YNegative;
2184 else
2186 strind++;
2187 tempY = read_integer (strind, &nextCharacter);
2188 if (strind == nextCharacter)
2189 return (0);
2190 strind = nextCharacter;
2192 mask |= YValue;
2196 /* If strind isn't at the end of the string the it's an invalid
2197 geometry specification. */
2199 if (*strind != '\0') return (0);
2201 if (mask & XValue)
2202 *x = tempX;
2203 if (mask & YValue)
2204 *y = tempY;
2205 if (mask & WidthValue)
2206 *width = tempWidth;
2207 if (mask & HeightValue)
2208 *height = tempHeight;
2209 return (mask);
2213 /* Create and set up the Mac window for frame F. */
2215 static void
2216 mac_window (f)
2217 struct frame *f;
2219 Rect r;
2221 BLOCK_INPUT;
2223 SetRect (&r, f->left_pos, f->top_pos,
2224 f->left_pos + FRAME_PIXEL_WIDTH (f),
2225 f->top_pos + FRAME_PIXEL_HEIGHT (f));
2226 #if TARGET_API_MAC_CARBON
2227 CreateNewWindow (kDocumentWindowClass,
2228 kWindowStandardDocumentAttributes
2229 /* | kWindowToolbarButtonAttribute */,
2230 &r, &FRAME_MAC_WINDOW (f));
2231 if (FRAME_MAC_WINDOW (f))
2233 SetWRefCon (FRAME_MAC_WINDOW (f), (long) f->output_data.mac);
2234 if (install_window_handler (FRAME_MAC_WINDOW (f)) != noErr)
2236 DisposeWindow (FRAME_MAC_WINDOW (f));
2237 FRAME_MAC_WINDOW (f) = NULL;
2240 #else
2241 FRAME_MAC_WINDOW (f)
2242 = NewCWindow (NULL, &r, "\p", false, zoomDocProc,
2243 (WindowPtr) -1, 1, (long) f->output_data.mac);
2244 #endif
2245 /* so that update events can find this mac_output struct */
2246 f->output_data.mac->mFP = f; /* point back to emacs frame */
2248 #ifndef MAC_OSX
2249 if (FRAME_MAC_WINDOW (f))
2251 ControlRef root_control;
2253 if (CreateRootControl (FRAME_MAC_WINDOW (f), &root_control) != noErr)
2255 DisposeWindow (FRAME_MAC_WINDOW (f));
2256 FRAME_MAC_WINDOW (f) = NULL;
2259 #endif
2260 if (FRAME_MAC_WINDOW (f))
2261 XSetWindowBackground (FRAME_MAC_DISPLAY(f), FRAME_MAC_WINDOW (f),
2262 FRAME_BACKGROUND_PIXEL (f));
2264 validate_x_resource_name ();
2266 /* x_set_name normally ignores requests to set the name if the
2267 requested name is the same as the current name. This is the one
2268 place where that assumption isn't correct; f->name is set, but
2269 the server hasn't been told. */
2271 Lisp_Object name;
2272 int explicit = f->explicit_name;
2274 f->explicit_name = 0;
2275 name = f->name;
2276 f->name = Qnil;
2277 x_set_name (f, name, explicit);
2280 UNBLOCK_INPUT;
2282 if (FRAME_MAC_WINDOW (f) == 0)
2283 error ("Unable to create window");
2286 /* Handle the icon stuff for this window. Perhaps later we might
2287 want an x_set_icon_position which can be called interactively as
2288 well. */
2290 static void
2291 x_icon (f, parms)
2292 struct frame *f;
2293 Lisp_Object parms;
2295 Lisp_Object icon_x, icon_y;
2297 /* Set the position of the icon. Note that Windows 95 groups all
2298 icons in the tray. */
2299 icon_x = mac_get_arg (parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2300 icon_y = mac_get_arg (parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2301 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2303 CHECK_NUMBER (icon_x);
2304 CHECK_NUMBER (icon_y);
2306 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2307 error ("Both left and top icon corners of icon must be specified");
2309 BLOCK_INPUT;
2311 if (! EQ (icon_x, Qunbound))
2312 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2314 #if 0 /* TODO */
2315 /* Start up iconic or window? */
2316 x_wm_set_window_state
2317 (f, (EQ (w32_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL), Qicon)
2318 ? IconicState
2319 : NormalState));
2321 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2322 ? f->icon_name
2323 : f->name)));
2324 #endif
2326 UNBLOCK_INPUT;
2330 void
2331 x_make_gc (f)
2332 struct frame *f;
2334 XGCValues gc_values;
2336 BLOCK_INPUT;
2338 /* Create the GCs of this frame.
2339 Note that many default values are used. */
2341 /* Normal video */
2342 gc_values.font = FRAME_FONT (f);
2343 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2344 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2345 f->output_data.mac->normal_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2346 FRAME_MAC_WINDOW (f),
2347 GCFont | GCForeground | GCBackground,
2348 &gc_values);
2350 /* Reverse video style. */
2351 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2352 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2353 f->output_data.mac->reverse_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2354 FRAME_MAC_WINDOW (f),
2355 GCFont | GCForeground | GCBackground,
2356 &gc_values);
2358 /* Cursor has cursor-color background, background-color foreground. */
2359 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2360 gc_values.background = f->output_data.mac->cursor_pixel;
2361 f->output_data.mac->cursor_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2362 FRAME_MAC_WINDOW (f),
2363 GCFont | GCForeground | GCBackground,
2364 &gc_values);
2366 /* Reliefs. */
2367 f->output_data.mac->white_relief.gc = 0;
2368 f->output_data.mac->black_relief.gc = 0;
2370 #if 0
2371 /* Create the gray border tile used when the pointer is not in
2372 the frame. Since this depends on the frame's pixel values,
2373 this must be done on a per-frame basis. */
2374 f->output_data.x->border_tile
2375 = (XCreatePixmapFromBitmapData
2376 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2377 gray_bits, gray_width, gray_height,
2378 f->output_data.x->foreground_pixel,
2379 f->output_data.x->background_pixel,
2380 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2381 #endif
2383 UNBLOCK_INPUT;
2387 /* Free what was was allocated in x_make_gc. */
2389 void
2390 x_free_gcs (f)
2391 struct frame *f;
2393 Display *dpy = FRAME_MAC_DISPLAY (f);
2395 BLOCK_INPUT;
2397 if (f->output_data.mac->normal_gc)
2399 XFreeGC (dpy, f->output_data.mac->normal_gc);
2400 f->output_data.mac->normal_gc = 0;
2403 if (f->output_data.mac->reverse_gc)
2405 XFreeGC (dpy, f->output_data.mac->reverse_gc);
2406 f->output_data.mac->reverse_gc = 0;
2409 if (f->output_data.mac->cursor_gc)
2411 XFreeGC (dpy, f->output_data.mac->cursor_gc);
2412 f->output_data.mac->cursor_gc = 0;
2415 #if 0
2416 if (f->output_data.mac->border_tile)
2418 XFreePixmap (dpy, f->output_data.mac->border_tile);
2419 f->output_data.mac->border_tile = 0;
2421 #endif
2423 if (f->output_data.mac->white_relief.gc)
2425 XFreeGC (dpy, f->output_data.mac->white_relief.gc);
2426 f->output_data.mac->white_relief.gc = 0;
2429 if (f->output_data.mac->black_relief.gc)
2431 XFreeGC (dpy, f->output_data.mac->black_relief.gc);
2432 f->output_data.mac->black_relief.gc = 0;
2435 UNBLOCK_INPUT;
2439 /* Handler for signals raised during x_create_frame and
2440 x_create_top_frame. FRAME is the frame which is partially
2441 constructed. */
2443 static Lisp_Object
2444 unwind_create_frame (frame)
2445 Lisp_Object frame;
2447 struct frame *f = XFRAME (frame);
2449 /* If frame is ``official'', nothing to do. */
2450 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
2452 #if GLYPH_DEBUG
2453 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2454 #endif
2456 x_free_frame_resources (f);
2458 #if GLYPH_DEBUG
2459 /* Check that reference counts are indeed correct. */
2460 xassert (dpyinfo->reference_count == dpyinfo_refcount);
2461 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
2462 #endif
2463 return Qt;
2466 return Qnil;
2470 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2471 1, 1, 0,
2472 doc: /* Make a new window, which is called a \"frame\" in Emacs terms.
2473 Returns an Emacs frame object.
2474 ALIST is an alist of frame parameters.
2475 If the parameters specify that the frame should not have a minibuffer,
2476 and do not specify a specific minibuffer window to use,
2477 then `default-minibuffer-frame' must be a frame whose minibuffer can
2478 be shared by the new frame.
2480 This function is an internal primitive--use `make-frame' instead. */)
2481 (parms)
2482 Lisp_Object parms;
2484 struct frame *f;
2485 Lisp_Object frame, tem;
2486 Lisp_Object name;
2487 int minibuffer_only = 0;
2488 long window_prompting = 0;
2489 int width, height;
2490 int count = SPECPDL_INDEX ();
2491 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2492 Lisp_Object display;
2493 struct mac_display_info *dpyinfo = NULL;
2494 Lisp_Object parent;
2495 struct kboard *kb;
2496 char x_frame_name[10];
2497 static int x_frame_count = 2; /* begins at 2 because terminal frame is F1 */
2499 check_mac ();
2501 /* Use this general default value to start with
2502 until we know if this frame has a specified name. */
2503 Vx_resource_name = Vinvocation_name;
2505 display = mac_get_arg (parms, Qdisplay, 0, 0, RES_TYPE_STRING);
2506 if (EQ (display, Qunbound))
2507 display = Qnil;
2508 dpyinfo = check_x_display_info (display);
2509 #ifdef MULTI_KBOARD
2510 kb = dpyinfo->kboard;
2511 #else
2512 kb = &the_only_kboard;
2513 #endif
2515 name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
2516 if (!STRINGP (name)
2517 && ! EQ (name, Qunbound)
2518 && ! NILP (name))
2519 error ("Invalid frame name--not a string or nil");
2521 if (STRINGP (name))
2522 Vx_resource_name = name;
2524 /* See if parent window is specified. */
2525 parent = mac_get_arg (parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
2526 if (EQ (parent, Qunbound))
2527 parent = Qnil;
2528 if (! NILP (parent))
2529 CHECK_NUMBER (parent);
2531 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2532 /* No need to protect DISPLAY because that's not used after passing
2533 it to make_frame_without_minibuffer. */
2534 frame = Qnil;
2535 GCPRO4 (parms, parent, name, frame);
2536 tem = mac_get_arg (parms, Qminibuffer, "minibuffer", "Minibuffer",
2537 RES_TYPE_SYMBOL);
2538 if (EQ (tem, Qnone) || NILP (tem))
2539 f = make_frame_without_minibuffer (Qnil, kb, display);
2540 else if (EQ (tem, Qonly))
2542 f = make_minibuffer_frame ();
2543 minibuffer_only = 1;
2545 else if (WINDOWP (tem))
2546 f = make_frame_without_minibuffer (tem, kb, display);
2547 else
2548 f = make_frame (1);
2550 if (EQ (name, Qunbound) || NILP (name))
2552 sprintf (x_frame_name, "F%d", x_frame_count++);
2553 f->name = build_string (x_frame_name);
2554 f->explicit_name = 0;
2556 else
2558 f->name = name;
2559 f->explicit_name = 1;
2562 XSETFRAME (frame, f);
2564 /* Note that X Windows does support scroll bars. */
2565 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
2567 f->output_method = output_mac;
2568 f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output));
2569 bzero (f->output_data.mac, sizeof (struct mac_output));
2570 FRAME_FONTSET (f) = -1;
2571 record_unwind_protect (unwind_create_frame, frame);
2573 f->icon_name
2574 = mac_get_arg (parms, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
2575 if (! STRINGP (f->icon_name))
2576 f->icon_name = Qnil;
2578 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
2579 #ifdef MULTI_KBOARD
2580 FRAME_KBOARD (f) = kb;
2581 #endif
2583 /* Specify the parent under which to make this window. */
2585 if (!NILP (parent))
2587 f->output_data.mac->parent_desc = (Window) XFASTINT (parent);
2588 f->output_data.mac->explicit_parent = 1;
2590 else
2592 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
2593 f->output_data.mac->explicit_parent = 0;
2596 /* Set the name; the functions to which we pass f expect the name to
2597 be set. */
2598 if (EQ (name, Qunbound) || NILP (name))
2600 f->name = build_string (dpyinfo->mac_id_name);
2601 f->explicit_name = 0;
2603 else
2605 f->name = name;
2606 f->explicit_name = 1;
2607 /* use the frame's title when getting resources for this frame. */
2608 specbind (Qx_resource_name, name);
2611 /* Extract the window parameters from the supplied values
2612 that are needed to determine window geometry. */
2614 Lisp_Object font;
2616 font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
2618 BLOCK_INPUT;
2619 /* First, try whatever font the caller has specified. */
2620 if (STRINGP (font))
2622 tem = Fquery_fontset (font, Qnil);
2623 if (STRINGP (tem))
2624 font = x_new_fontset (f, SDATA (tem));
2625 else
2626 font = x_new_font (f, SDATA (font));
2629 /* Try out a font which we hope has bold and italic variations. */
2630 if (! STRINGP (font))
2631 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
2632 /* If those didn't work, look for something which will at least work. */
2633 if (! STRINGP (font))
2634 font = x_new_fontset (f, "fontset-mac");
2635 if (! STRINGP (font))
2636 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
2637 if (! STRINGP (font))
2638 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
2639 if (! STRINGP (font))
2640 error ("Cannot find any usable font");
2641 UNBLOCK_INPUT;
2643 x_default_parameter (f, parms, Qfont, font,
2644 "font", "Font", RES_TYPE_STRING);
2647 x_default_parameter (f, parms, Qborder_width, make_number (0),
2648 "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
2649 /* This defaults to 2 in order to match xterm. We recognize either
2650 internalBorderWidth or internalBorder (which is what xterm calls
2651 it). */
2652 if (NILP (Fassq (Qinternal_border_width, parms)))
2654 Lisp_Object value;
2656 value = mac_get_arg (parms, Qinternal_border_width,
2657 "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
2658 if (! EQ (value, Qunbound))
2659 parms = Fcons (Fcons (Qinternal_border_width, value),
2660 parms);
2662 /* Default internalBorderWidth to 0 on Windows to match other programs. */
2663 x_default_parameter (f, parms, Qinternal_border_width, make_number (0),
2664 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
2665 x_default_parameter (f, parms, Qvertical_scroll_bars, Qright,
2666 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
2668 /* Also do the stuff which must be set before the window exists. */
2669 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
2670 "foreground", "Foreground", RES_TYPE_STRING);
2671 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
2672 "background", "Background", RES_TYPE_STRING);
2673 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
2674 "pointerColor", "Foreground", RES_TYPE_STRING);
2675 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
2676 "cursorColor", "Foreground", RES_TYPE_STRING);
2677 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
2678 "borderColor", "BorderColor", RES_TYPE_STRING);
2679 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
2680 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
2681 x_default_parameter (f, parms, Qline_spacing, Qnil,
2682 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
2683 x_default_parameter (f, parms, Qleft_fringe, Qnil,
2684 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
2685 x_default_parameter (f, parms, Qright_fringe, Qnil,
2686 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
2689 /* Init faces before x_default_parameter is called for scroll-bar
2690 parameters because that function calls x_set_scroll_bar_width,
2691 which calls change_frame_size, which calls Fset_window_buffer,
2692 which runs hooks, which call Fvertical_motion. At the end, we
2693 end up in init_iterator with a null face cache, which should not
2694 happen. */
2695 init_frame_faces (f);
2697 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
2698 "menuBar", "MenuBar", RES_TYPE_NUMBER);
2699 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
2700 "toolBar", "ToolBar", RES_TYPE_NUMBER);
2701 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
2702 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
2703 x_default_parameter (f, parms, Qtitle, Qnil,
2704 "title", "Title", RES_TYPE_STRING);
2705 x_default_parameter (f, parms, Qfullscreen, Qnil,
2706 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
2708 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
2710 /* Compute the size of the window. */
2711 window_prompting = x_figure_window_size (f, parms, 1);
2713 tem = mac_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
2714 f->no_split = minibuffer_only || EQ (tem, Qt);
2716 mac_window (f);
2718 x_icon (f, parms);
2719 x_make_gc (f);
2721 /* Now consider the frame official. */
2722 FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
2723 Vframe_list = Fcons (frame, Vframe_list);
2725 /* We need to do this after creating the window, so that the
2726 icon-creation functions can say whose icon they're describing. */
2727 x_default_parameter (f, parms, Qicon_type, Qnil,
2728 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
2730 x_default_parameter (f, parms, Qauto_raise, Qnil,
2731 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2732 x_default_parameter (f, parms, Qauto_lower, Qnil,
2733 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2734 x_default_parameter (f, parms, Qcursor_type, Qbox,
2735 "cursorType", "CursorType", RES_TYPE_SYMBOL);
2736 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
2737 "scrollBarWidth", "ScrollBarWidth",
2738 RES_TYPE_NUMBER);
2740 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
2741 Change will not be effected unless different from the current
2742 FRAME_LINES (f). */
2743 width = FRAME_COLS (f);
2744 height = FRAME_LINES (f);
2746 SET_FRAME_COLS (f, 0);
2747 FRAME_LINES (f) = 0;
2748 change_frame_size (f, height, width, 1, 0, 0);
2750 /* Tell the server what size and position, etc, we want, and how
2751 badly we want them. This should be done after we have the menu
2752 bar so that its size can be taken into account. */
2753 BLOCK_INPUT;
2754 x_wm_set_size_hint (f, window_prompting, 0);
2755 UNBLOCK_INPUT;
2757 /* Make the window appear on the frame and enable display, unless
2758 the caller says not to. However, with explicit parent, Emacs
2759 cannot control visibility, so don't try. */
2760 if (! f->output_data.mac->explicit_parent)
2762 Lisp_Object visibility;
2764 visibility = mac_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
2765 if (EQ (visibility, Qunbound))
2766 visibility = Qt;
2768 #if 0 /* MAC_TODO: really no iconify on Mac */
2769 if (EQ (visibility, Qicon))
2770 x_iconify_frame (f);
2771 else
2772 #endif
2773 if (! NILP (visibility))
2774 x_make_frame_visible (f);
2775 else
2776 /* Must have been Qnil. */
2779 UNGCPRO;
2781 /* Make sure windows on this frame appear in calls to next-window
2782 and similar functions. */
2783 Vwindow_list = Qnil;
2785 return unbind_to (count, frame);
2788 /* FRAME is used only to get a handle on the X display. We don't pass the
2789 display info directly because we're called from frame.c, which doesn't
2790 know about that structure. */
2791 Lisp_Object
2792 x_get_focus_frame (frame)
2793 struct frame *frame;
2795 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
2796 Lisp_Object xfocus;
2797 if (! dpyinfo->x_focus_frame)
2798 return Qnil;
2800 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
2801 return xfocus;
2804 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
2805 doc: /* Internal function called by `color-defined-p', which see. */)
2806 (color, frame)
2807 Lisp_Object color, frame;
2809 XColor foo;
2810 FRAME_PTR f = check_x_frame (frame);
2812 CHECK_STRING (color);
2814 if (mac_defined_color (f, SDATA (color), &foo, 0))
2815 return Qt;
2816 else
2817 return Qnil;
2820 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2821 doc: /* Internal function called by `color-values', which see. */)
2822 (color, frame)
2823 Lisp_Object color, frame;
2825 XColor foo;
2826 FRAME_PTR f = check_x_frame (frame);
2828 CHECK_STRING (color);
2830 if (mac_defined_color (f, SDATA (color), &foo, 0))
2832 Lisp_Object rgb[3];
2834 rgb[0] = make_number (foo.red);
2835 rgb[1] = make_number (foo.green);
2836 rgb[2] = make_number (foo.blue);
2837 return Flist (3, rgb);
2839 else
2840 return Qnil;
2843 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2844 doc: /* Internal function called by `display-color-p', which see. */)
2845 (display)
2846 Lisp_Object display;
2848 struct mac_display_info *dpyinfo = check_x_display_info (display);
2850 if (!dpyinfo->color_p)
2851 return Qnil;
2853 return Qt;
2856 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
2857 0, 1, 0,
2858 doc: /* Return t if the X display supports shades of gray.
2859 Note that color displays do support shades of gray.
2860 The optional argument DISPLAY specifies which display to ask about.
2861 DISPLAY should be either a frame or a display name (a string).
2862 If omitted or nil, that stands for the selected frame's display. */)
2863 (display)
2864 Lisp_Object display;
2866 struct mac_display_info *dpyinfo = check_x_display_info (display);
2868 if (dpyinfo->n_planes <= 1)
2869 return Qnil;
2871 return Qt;
2874 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2875 0, 1, 0,
2876 doc: /* Returns the width in pixels of the X display DISPLAY.
2877 The optional argument DISPLAY specifies which display to ask about.
2878 DISPLAY should be either a frame or a display name (a string).
2879 If omitted or nil, that stands for the selected frame's display. */)
2880 (display)
2881 Lisp_Object display;
2883 struct mac_display_info *dpyinfo = check_x_display_info (display);
2885 return make_number (dpyinfo->width);
2888 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2889 Sx_display_pixel_height, 0, 1, 0,
2890 doc: /* Returns the height in pixels of the X display DISPLAY.
2891 The optional argument DISPLAY specifies which display to ask about.
2892 DISPLAY should be either a frame or a display name (a string).
2893 If omitted or nil, that stands for the selected frame's display. */)
2894 (display)
2895 Lisp_Object display;
2897 struct mac_display_info *dpyinfo = check_x_display_info (display);
2899 return make_number (dpyinfo->height);
2902 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2903 0, 1, 0,
2904 doc: /* Returns the number of bitplanes of the display DISPLAY.
2905 The optional argument DISPLAY specifies which display to ask about.
2906 DISPLAY should be either a frame or a display name (a string).
2907 If omitted or nil, that stands for the selected frame's display. */)
2908 (display)
2909 Lisp_Object display;
2911 struct mac_display_info *dpyinfo = check_x_display_info (display);
2913 return make_number (dpyinfo->n_planes);
2916 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2917 0, 1, 0,
2918 doc: /* Returns the number of color cells of the display DISPLAY.
2919 The optional argument DISPLAY specifies which display to ask about.
2920 DISPLAY should be either a frame or a display name (a string).
2921 If omitted or nil, that stands for the selected frame's display. */)
2922 (display)
2923 Lisp_Object display;
2925 struct mac_display_info *dpyinfo = check_x_display_info (display);
2927 /* We force 24+ bit depths to 24-bit to prevent an overflow. */
2928 return make_number (1 << min (dpyinfo->n_planes, 24));
2931 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
2932 Sx_server_max_request_size,
2933 0, 1, 0,
2934 doc: /* Returns the maximum request size of the server of display DISPLAY.
2935 The optional argument DISPLAY specifies which display to ask about.
2936 DISPLAY should be either a frame or a display name (a string).
2937 If omitted or nil, that stands for the selected frame's display. */)
2938 (display)
2939 Lisp_Object display;
2941 struct mac_display_info *dpyinfo = check_x_display_info (display);
2943 return make_number (1);
2946 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
2947 doc: /* Returns the vendor ID string of the Mac OS system (Apple).
2948 The optional argument DISPLAY specifies which display to ask about.
2949 DISPLAY should be either a frame or a display name (a string).
2950 If omitted or nil, that stands for the selected frame's display. */)
2951 (display)
2952 Lisp_Object display;
2954 return build_string ("Apple Computers");
2957 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
2958 doc: /* Returns the version numbers of the server of display DISPLAY.
2959 The value is a list of three integers: the major and minor
2960 version numbers, and the vendor-specific release
2961 number. See also the function `x-server-vendor'.
2963 The optional argument DISPLAY specifies which display to ask about.
2964 DISPLAY should be either a frame or a display name (a string).
2965 If omitted or nil, that stands for the selected frame's display. */)
2966 (display)
2967 Lisp_Object display;
2969 int mac_major_version;
2970 SInt32 response;
2971 OSErr err;
2973 BLOCK_INPUT;
2974 err = Gestalt (gestaltSystemVersion, &response);
2975 UNBLOCK_INPUT;
2977 if (err != noErr)
2978 error ("Cannot get Mac OS version");
2980 mac_major_version = (response >> 8) & 0xff;
2981 /* convert BCD to int */
2982 mac_major_version -= (mac_major_version >> 4) * 6;
2984 return Fcons (make_number (mac_major_version),
2985 Fcons (make_number ((response >> 4) & 0xf),
2986 Fcons (make_number (response & 0xf),
2987 Qnil)));
2990 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
2991 doc: /* Return the number of screens on the server of display DISPLAY.
2992 The optional argument DISPLAY specifies which display to ask about.
2993 DISPLAY should be either a frame or a display name (a string).
2994 If omitted or nil, that stands for the selected frame's display. */)
2995 (display)
2996 Lisp_Object display;
2998 return make_number (1);
3001 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3002 doc: /* Return the height in millimeters of the X display DISPLAY.
3003 The optional argument DISPLAY specifies which display to ask about.
3004 DISPLAY should be either a frame or a display name (a string).
3005 If omitted or nil, that stands for the selected frame's display. */)
3006 (display)
3007 Lisp_Object display;
3009 /* MAC_TODO: this is an approximation, and only of the main display */
3011 struct mac_display_info *dpyinfo = check_x_display_info (display);
3013 return make_number ((int) (dpyinfo->height * 25.4 / dpyinfo->resy));
3016 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3017 doc: /* Return the width 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->width * 25.4 / dpyinfo->resx));
3031 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3032 Sx_display_backing_store, 0, 1, 0,
3033 doc: /* Returns an indication of whether display DISPLAY does backing store.
3034 The value may be `always', `when-mapped', or `not-useful'.
3035 The optional argument DISPLAY specifies which display to ask about.
3036 DISPLAY should be either a frame or a display name (a string).
3037 If omitted or nil, that stands for the selected frame's display. */)
3038 (display)
3039 Lisp_Object display;
3041 return intern ("not-useful");
3044 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3045 Sx_display_visual_class, 0, 1, 0,
3046 doc: /* Returns the visual class of the display DISPLAY.
3047 The value is one of the symbols `static-gray', `gray-scale',
3048 `static-color', `pseudo-color', `true-color', or `direct-color'.
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 struct mac_display_info *dpyinfo = check_x_display_info (display);
3058 #if 0
3059 switch (dpyinfo->visual->class)
3061 case StaticGray: return (intern ("static-gray"));
3062 case GrayScale: return (intern ("gray-scale"));
3063 case StaticColor: return (intern ("static-color"));
3064 case PseudoColor: return (intern ("pseudo-color"));
3065 case TrueColor: return (intern ("true-color"));
3066 case DirectColor: return (intern ("direct-color"));
3067 default:
3068 error ("Display has an unknown visual class");
3070 #endif /* 0 */
3072 return (intern ("true-color"));
3075 DEFUN ("x-display-save-under", Fx_display_save_under,
3076 Sx_display_save_under, 0, 1, 0,
3077 doc: /* Returns t if the display DISPLAY supports the save-under feature.
3078 The optional argument DISPLAY specifies which display to ask about.
3079 DISPLAY should be either a frame or a display name (a string).
3080 If omitted or nil, that stands for the selected frame's display. */)
3081 (display)
3082 Lisp_Object display;
3084 return Qnil;
3088 x_pixel_width (f)
3089 register struct frame *f;
3091 return FRAME_PIXEL_WIDTH (f);
3095 x_pixel_height (f)
3096 register struct frame *f;
3098 return FRAME_PIXEL_HEIGHT (f);
3102 x_char_width (f)
3103 register struct frame *f;
3105 return FRAME_COLUMN_WIDTH (f);
3109 x_char_height (f)
3110 register struct frame *f;
3112 return FRAME_LINE_HEIGHT (f);
3116 x_screen_planes (f)
3117 register struct frame *f;
3119 return FRAME_MAC_DISPLAY_INFO (f)->n_planes;
3122 /* Return the display structure for the display named NAME.
3123 Open a new connection if necessary. */
3125 struct mac_display_info *
3126 x_display_info_for_name (name)
3127 Lisp_Object name;
3129 Lisp_Object names;
3130 struct mac_display_info *dpyinfo;
3132 CHECK_STRING (name);
3134 if (! EQ (Vwindow_system, intern ("mac")))
3135 error ("Not using Mac native windows");
3137 for (dpyinfo = &one_mac_display_info, names = x_display_name_list;
3138 dpyinfo;
3139 dpyinfo = dpyinfo->next, names = XCDR (names))
3141 Lisp_Object tem;
3142 tem = Fstring_equal (XCAR (XCAR (names)), name);
3143 if (!NILP (tem))
3144 return dpyinfo;
3147 /* Use this general default value to start with. */
3148 Vx_resource_name = Vinvocation_name;
3150 validate_x_resource_name ();
3152 dpyinfo = mac_term_init (name, (unsigned char *) 0,
3153 (char *) SDATA (Vx_resource_name));
3155 if (dpyinfo == 0)
3156 error ("Cannot connect to server %s", SDATA (name));
3158 mac_in_use = 1;
3159 XSETFASTINT (Vwindow_system_version, 3);
3161 return dpyinfo;
3164 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
3165 1, 3, 0,
3166 doc: /* Open a connection to a server.
3167 DISPLAY is the name of the display to connect to.
3168 Optional second arg XRM-STRING is a string of resources in xrdb format.
3169 If the optional third arg MUST-SUCCEED is non-nil,
3170 terminate Emacs if we can't open the connection. */)
3171 (display, xrm_string, must_succeed)
3172 Lisp_Object display, xrm_string, must_succeed;
3174 unsigned char *xrm_option;
3175 struct mac_display_info *dpyinfo;
3177 CHECK_STRING (display);
3178 if (! NILP (xrm_string))
3179 CHECK_STRING (xrm_string);
3181 if (! EQ (Vwindow_system, intern ("mac")))
3182 error ("Not using Mac native windows");
3184 if (! NILP (xrm_string))
3185 xrm_option = (unsigned char *) SDATA (xrm_string);
3186 else
3187 xrm_option = (unsigned char *) 0;
3189 validate_x_resource_name ();
3191 /* This is what opens the connection and sets x_current_display.
3192 This also initializes many symbols, such as those used for input. */
3193 dpyinfo = mac_term_init (display, xrm_option,
3194 (char *) SDATA (Vx_resource_name));
3196 if (dpyinfo == 0)
3198 if (!NILP (must_succeed))
3199 fatal ("Cannot connect to server %s.\n",
3200 SDATA (display));
3201 else
3202 error ("Cannot connect to server %s", SDATA (display));
3205 mac_in_use = 1;
3207 XSETFASTINT (Vwindow_system_version, 3);
3208 return Qnil;
3211 DEFUN ("x-close-connection", Fx_close_connection,
3212 Sx_close_connection, 1, 1, 0,
3213 doc: /* Close the connection to DISPLAY's server.
3214 For DISPLAY, specify either a frame or a display name (a string).
3215 If DISPLAY is nil, that stands for the selected frame's display. */)
3216 (display)
3217 Lisp_Object display;
3219 struct mac_display_info *dpyinfo = check_x_display_info (display);
3220 int i;
3222 if (dpyinfo->reference_count > 0)
3223 error ("Display still has frames on it");
3225 BLOCK_INPUT;
3226 /* Free the fonts in the font table. */
3227 for (i = 0; i < dpyinfo->n_fonts; i++)
3228 if (dpyinfo->font_table[i].name)
3230 mac_unload_font (dpyinfo, dpyinfo->font_table[i].font);
3233 x_destroy_all_bitmaps (dpyinfo);
3235 x_delete_display (dpyinfo);
3236 UNBLOCK_INPUT;
3238 return Qnil;
3241 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
3242 doc: /* Return the list of display names that Emacs has connections to. */)
3245 Lisp_Object tail, result;
3247 result = Qnil;
3248 for (tail = x_display_name_list; ! NILP (tail); tail = XCDR (tail))
3249 result = Fcons (XCAR (XCAR (tail)), result);
3251 return result;
3254 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
3255 doc: /* If ON is non-nil, report errors as soon as the erring request is made.
3256 If ON is nil, allow buffering of requests.
3257 This is a noop on Mac OS systems.
3258 The optional second argument DISPLAY specifies which display to act on.
3259 DISPLAY should be either a frame or a display name (a string).
3260 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
3261 (on, display)
3262 Lisp_Object display, on;
3264 return Qnil;
3268 /***********************************************************************
3269 Window properties
3270 ***********************************************************************/
3272 DEFUN ("x-change-window-property", Fx_change_window_property,
3273 Sx_change_window_property, 2, 6, 0,
3274 doc: /* Change window property PROP to VALUE on the X window of FRAME.
3275 VALUE may be a string or a list of conses, numbers and/or strings.
3276 If an element in the list is a string, it is converted to
3277 an Atom and the value of the Atom is used. If an element is a cons,
3278 it is converted to a 32 bit number where the car is the 16 top bits and the
3279 cdr is the lower 16 bits.
3280 FRAME nil or omitted means use the selected frame.
3281 If TYPE is given and non-nil, it is the name of the type of VALUE.
3282 If TYPE is not given or nil, the type is STRING.
3283 FORMAT gives the size in bits of each element if VALUE is a list.
3284 It must be one of 8, 16 or 32.
3285 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
3286 If OUTER_P is non-nil, the property is changed for the outer X window of
3287 FRAME. Default is to change on the edit X window.
3289 Value is VALUE. */)
3290 (prop, value, frame, type, format, outer_p)
3291 Lisp_Object prop, value, frame, type, format, outer_p;
3293 #if 0 /* MAC_TODO : port window properties to Mac */
3294 struct frame *f = check_x_frame (frame);
3295 Atom prop_atom;
3297 CHECK_STRING (prop);
3298 CHECK_STRING (value);
3300 BLOCK_INPUT;
3301 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3302 XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3303 prop_atom, XA_STRING, 8, PropModeReplace,
3304 SDATA (value), SCHARS (value));
3306 /* Make sure the property is set when we return. */
3307 XFlush (FRAME_W32_DISPLAY (f));
3308 UNBLOCK_INPUT;
3310 #endif /* MAC_TODO */
3312 return value;
3316 DEFUN ("x-delete-window-property", Fx_delete_window_property,
3317 Sx_delete_window_property, 1, 2, 0,
3318 doc: /* Remove window property PROP from X window of FRAME.
3319 FRAME nil or omitted means use the selected frame. Value is PROP. */)
3320 (prop, frame)
3321 Lisp_Object prop, frame;
3323 #if 0 /* MAC_TODO : port window properties to Mac */
3325 struct frame *f = check_x_frame (frame);
3326 Atom prop_atom;
3328 CHECK_STRING (prop);
3329 BLOCK_INPUT;
3330 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3331 XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
3333 /* Make sure the property is removed when we return. */
3334 XFlush (FRAME_W32_DISPLAY (f));
3335 UNBLOCK_INPUT;
3336 #endif /* MAC_TODO */
3338 return prop;
3342 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
3343 1, 2, 0,
3344 doc: /* Value is the value of window property PROP on FRAME.
3345 If FRAME is nil or omitted, use the selected frame. Value is nil
3346 if FRAME hasn't a property with name PROP or if PROP has no string
3347 value. */)
3348 (prop, frame)
3349 Lisp_Object prop, frame;
3351 #if 0 /* MAC_TODO : port window properties to Mac */
3353 struct frame *f = check_x_frame (frame);
3354 Atom prop_atom;
3355 int rc;
3356 Lisp_Object prop_value = Qnil;
3357 char *tmp_data = NULL;
3358 Atom actual_type;
3359 int actual_format;
3360 unsigned long actual_size, bytes_remaining;
3362 CHECK_STRING (prop);
3363 BLOCK_INPUT;
3364 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3365 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3366 prop_atom, 0, 0, False, XA_STRING,
3367 &actual_type, &actual_format, &actual_size,
3368 &bytes_remaining, (unsigned char **) &tmp_data);
3369 if (rc == Success)
3371 int size = bytes_remaining;
3373 XFree (tmp_data);
3374 tmp_data = NULL;
3376 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3377 prop_atom, 0, bytes_remaining,
3378 False, XA_STRING,
3379 &actual_type, &actual_format,
3380 &actual_size, &bytes_remaining,
3381 (unsigned char **) &tmp_data);
3382 if (rc == Success)
3383 prop_value = make_string (tmp_data, size);
3385 XFree (tmp_data);
3388 UNBLOCK_INPUT;
3390 return prop_value;
3392 #endif /* MAC_TODO */
3393 return Qnil;
3398 /***********************************************************************
3399 Busy cursor
3400 ***********************************************************************/
3402 /* If non-null, an asynchronous timer that, when it expires, displays
3403 an hourglass cursor on all frames. */
3405 static struct atimer *hourglass_atimer;
3407 /* Non-zero means an hourglass cursor is currently shown. */
3409 static int hourglass_shown_p;
3411 /* Number of seconds to wait before displaying an hourglass cursor. */
3413 static Lisp_Object Vhourglass_delay;
3415 /* Default number of seconds to wait before displaying an hourglass
3416 cursor. */
3418 #define DEFAULT_HOURGLASS_DELAY 1
3420 /* Function prototypes. */
3422 static void show_hourglass P_ ((struct atimer *));
3423 static void hide_hourglass P_ ((void));
3425 /* Return non-zero if houglass timer has been started or hourglass is shown. */
3428 hourglass_started ()
3430 return hourglass_shown_p || hourglass_atimer != NULL;
3434 /* Cancel a currently active hourglass timer, and start a new one. */
3436 void
3437 start_hourglass ()
3439 #ifdef MAC_OSX
3440 EMACS_TIME delay;
3441 int secs, usecs = 0;
3443 cancel_hourglass ();
3445 if (INTEGERP (Vhourglass_delay)
3446 && XINT (Vhourglass_delay) > 0)
3447 secs = XFASTINT (Vhourglass_delay);
3448 else if (FLOATP (Vhourglass_delay)
3449 && XFLOAT_DATA (Vhourglass_delay) > 0)
3451 Lisp_Object tem;
3452 tem = Ftruncate (Vhourglass_delay, Qnil);
3453 secs = XFASTINT (tem);
3454 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
3456 else
3457 secs = DEFAULT_HOURGLASS_DELAY;
3459 EMACS_SET_SECS_USECS (delay, secs, usecs);
3460 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
3461 show_hourglass, NULL);
3462 #endif /* MAC_OSX */
3466 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
3467 shown. */
3469 void
3470 cancel_hourglass ()
3472 #ifdef MAC_OSX
3473 if (hourglass_atimer)
3475 cancel_atimer (hourglass_atimer);
3476 hourglass_atimer = NULL;
3479 if (hourglass_shown_p)
3480 hide_hourglass ();
3481 #endif /* MAC_OSX */
3485 /* Timer function of hourglass_atimer. TIMER is equal to
3486 hourglass_atimer.
3488 On Mac, busy status is shown by the progress indicator (chasing
3489 arrows) at the upper-right corner of each frame instead of the
3490 hourglass pointer. */
3492 static void
3493 show_hourglass (timer)
3494 struct atimer *timer;
3496 #if TARGET_API_MAC_CARBON
3497 /* The timer implementation will cancel this timer automatically
3498 after this function has run. Set hourglass_atimer to null
3499 so that we know the timer doesn't have to be canceled. */
3500 hourglass_atimer = NULL;
3502 if (!hourglass_shown_p)
3504 Lisp_Object rest, frame;
3506 BLOCK_INPUT;
3508 FOR_EACH_FRAME (rest, frame)
3510 struct frame *f = XFRAME (frame);
3512 if (FRAME_LIVE_P (f) && FRAME_MAC_P (f)
3513 && FRAME_MAC_WINDOW (f) != tip_window)
3515 if (!f->output_data.mac->hourglass_control)
3517 Window w = FRAME_MAC_WINDOW (f);
3518 Rect r;
3519 ControlRef c;
3521 GetWindowPortBounds (w, &r);
3522 r.left = r.right - HOURGLASS_WIDTH;
3523 r.bottom = r.top + HOURGLASS_HEIGHT;
3524 if (CreateChasingArrowsControl (w, &r, &c) == noErr)
3525 f->output_data.mac->hourglass_control = c;
3528 if (f->output_data.mac->hourglass_control)
3529 ShowControl (f->output_data.mac->hourglass_control);
3533 hourglass_shown_p = 1;
3534 UNBLOCK_INPUT;
3536 #endif /* TARGET_API_MAC_CARBON */
3540 /* Hide the progress indicators on all frames, if it is currently
3541 shown. */
3543 static void
3544 hide_hourglass ()
3546 #if TARGET_API_MAC_CARBON
3547 if (hourglass_shown_p)
3549 Lisp_Object rest, frame;
3551 BLOCK_INPUT;
3552 FOR_EACH_FRAME (rest, frame)
3554 struct frame *f = XFRAME (frame);
3556 if (FRAME_MAC_P (f)
3557 /* Watch out for newly created frames. */
3558 && f->output_data.mac->hourglass_control)
3559 HideControl (f->output_data.mac->hourglass_control);
3562 hourglass_shown_p = 0;
3563 UNBLOCK_INPUT;
3565 #endif /* TARGET_API_MAC_CARBON */
3570 /***********************************************************************
3571 Tool tips
3572 ***********************************************************************/
3574 static Lisp_Object x_create_tip_frame P_ ((struct mac_display_info *,
3575 Lisp_Object, Lisp_Object));
3576 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
3577 Lisp_Object, int, int, int *, int *));
3579 /* The frame of a currently visible tooltip. */
3581 Lisp_Object tip_frame;
3583 /* If non-nil, a timer started that hides the last tooltip when it
3584 fires. */
3586 Lisp_Object tip_timer;
3587 Window tip_window;
3589 /* If non-nil, a vector of 3 elements containing the last args
3590 with which x-show-tip was called. See there. */
3592 Lisp_Object last_show_tip_args;
3594 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
3596 Lisp_Object Vx_max_tooltip_size;
3599 static Lisp_Object
3600 unwind_create_tip_frame (frame)
3601 Lisp_Object frame;
3603 Lisp_Object deleted;
3605 deleted = unwind_create_frame (frame);
3606 if (EQ (deleted, Qt))
3608 tip_window = NULL;
3609 tip_frame = Qnil;
3612 return deleted;
3616 /* Create a frame for a tooltip on the display described by DPYINFO.
3617 PARMS is a list of frame parameters. TEXT is the string to
3618 display in the tip frame. Value is the frame.
3620 Note that functions called here, esp. x_default_parameter can
3621 signal errors, for instance when a specified color name is
3622 undefined. We have to make sure that we're in a consistent state
3623 when this happens. */
3625 static Lisp_Object
3626 x_create_tip_frame (dpyinfo, parms, text)
3627 struct mac_display_info *dpyinfo;
3628 Lisp_Object parms, text;
3630 struct frame *f;
3631 Lisp_Object frame, tem;
3632 Lisp_Object name;
3633 long window_prompting = 0;
3634 int width, height;
3635 int count = SPECPDL_INDEX ();
3636 struct gcpro gcpro1, gcpro2, gcpro3;
3637 struct kboard *kb;
3638 int face_change_count_before = face_change_count;
3639 Lisp_Object buffer;
3640 struct buffer *old_buffer;
3642 check_mac ();
3645 #ifdef MULTI_KBOARD
3646 kb = dpyinfo->kboard;
3647 #else
3648 kb = &the_only_kboard;
3649 #endif
3651 /* Get the name of the frame to use for resource lookup. */
3652 name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
3653 if (!STRINGP (name)
3654 && !EQ (name, Qunbound)
3655 && !NILP (name))
3656 error ("Invalid frame name--not a string or nil");
3658 frame = Qnil;
3659 GCPRO3 (parms, name, frame);
3660 f = make_frame (1);
3661 XSETFRAME (frame, f);
3663 buffer = Fget_buffer_create (build_string (" *tip*"));
3664 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
3665 old_buffer = current_buffer;
3666 set_buffer_internal_1 (XBUFFER (buffer));
3667 current_buffer->truncate_lines = Qnil;
3668 specbind (Qinhibit_read_only, Qt);
3669 specbind (Qinhibit_modification_hooks, Qt);
3670 Ferase_buffer ();
3671 Finsert (1, &text);
3672 set_buffer_internal_1 (old_buffer);
3674 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
3675 record_unwind_protect (unwind_create_tip_frame, frame);
3677 /* By setting the output method, we're essentially saying that
3678 the frame is live, as per FRAME_LIVE_P. If we get a signal
3679 from this point on, x_destroy_window might screw up reference
3680 counts etc. */
3681 f->output_method = output_mac;
3682 f->output_data.mac =
3683 (struct mac_output *) xmalloc (sizeof (struct mac_output));
3684 bzero (f->output_data.mac, sizeof (struct mac_output));
3686 FRAME_FONTSET (f) = -1;
3687 f->icon_name = Qnil;
3689 #if 0 /* GLYPH_DEBUG TODO: image support. */
3690 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
3691 dpyinfo_refcount = dpyinfo->reference_count;
3692 #endif /* GLYPH_DEBUG */
3693 #ifdef MULTI_KBOARD
3694 FRAME_KBOARD (f) = kb;
3695 #endif
3696 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
3697 f->output_data.mac->explicit_parent = 0;
3699 /* Set the name; the functions to which we pass f expect the name to
3700 be set. */
3701 if (EQ (name, Qunbound) || NILP (name))
3703 f->name = build_string (dpyinfo->mac_id_name);
3704 f->explicit_name = 0;
3706 else
3708 f->name = name;
3709 f->explicit_name = 1;
3710 /* use the frame's title when getting resources for this frame. */
3711 specbind (Qx_resource_name, name);
3714 /* Extract the window parameters from the supplied values that are
3715 needed to determine window geometry. */
3717 Lisp_Object font;
3719 font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
3721 BLOCK_INPUT;
3722 /* First, try whatever font the caller has specified. */
3723 if (STRINGP (font))
3725 tem = Fquery_fontset (font, Qnil);
3726 if (STRINGP (tem))
3727 font = x_new_fontset (f, SDATA (tem));
3728 else
3729 font = x_new_font (f, SDATA (font));
3732 /* Try out a font which we hope has bold and italic variations. */
3733 if (! STRINGP (font))
3734 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
3735 /* If those didn't work, look for something which will at least work. */
3736 if (! STRINGP (font))
3737 font = x_new_fontset (f, "fontset-mac");
3738 if (! STRINGP (font))
3739 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
3740 if (! STRINGP (font))
3741 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
3742 UNBLOCK_INPUT;
3743 if (! STRINGP (font))
3744 error ("Cannot find any usable font");
3746 x_default_parameter (f, parms, Qfont, font,
3747 "font", "Font", RES_TYPE_STRING);
3750 x_default_parameter (f, parms, Qborder_width, make_number (2),
3751 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3753 /* This defaults to 2 in order to match xterm. We recognize either
3754 internalBorderWidth or internalBorder (which is what xterm calls
3755 it). */
3756 if (NILP (Fassq (Qinternal_border_width, parms)))
3758 Lisp_Object value;
3760 value = mac_get_arg (parms, Qinternal_border_width,
3761 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3762 if (! EQ (value, Qunbound))
3763 parms = Fcons (Fcons (Qinternal_border_width, value),
3764 parms);
3767 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
3768 "internalBorderWidth", "internalBorderWidth",
3769 RES_TYPE_NUMBER);
3771 /* Also do the stuff which must be set before the window exists. */
3772 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3773 "foreground", "Foreground", RES_TYPE_STRING);
3774 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3775 "background", "Background", RES_TYPE_STRING);
3776 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3777 "pointerColor", "Foreground", RES_TYPE_STRING);
3778 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3779 "cursorColor", "Foreground", RES_TYPE_STRING);
3780 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3781 "borderColor", "BorderColor", RES_TYPE_STRING);
3783 /* Init faces before x_default_parameter is called for scroll-bar
3784 parameters because that function calls x_set_scroll_bar_width,
3785 which calls change_frame_size, which calls Fset_window_buffer,
3786 which runs hooks, which call Fvertical_motion. At the end, we
3787 end up in init_iterator with a null face cache, which should not
3788 happen. */
3789 init_frame_faces (f);
3791 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
3793 window_prompting = x_figure_window_size (f, parms, 0);
3796 Rect r;
3798 BLOCK_INPUT;
3799 SetRect (&r, 0, 0, 1, 1);
3800 #if TARGET_API_MAC_CARBON
3801 if (CreateNewWindow (kHelpWindowClass,
3802 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
3803 kWindowIgnoreClicksAttribute |
3804 #endif
3805 kWindowNoUpdatesAttribute |
3806 kWindowNoActivatesAttribute,
3807 &r, &tip_window) == noErr)
3808 #else
3809 if (tip_window = NewCWindow (NULL, &r, "\p", false, plainDBox,
3810 NULL, false, 0L))
3811 #endif
3813 FRAME_MAC_WINDOW (f) = tip_window;
3814 XSetWindowBackground (FRAME_MAC_DISPLAY(f), tip_window,
3815 FRAME_BACKGROUND_PIXEL (f));
3816 SetWRefCon (tip_window, (long) f->output_data.mac);
3817 /* so that update events can find this mac_output struct */
3818 f->output_data.mac->mFP = f;
3820 UNBLOCK_INPUT;
3823 x_make_gc (f);
3825 x_default_parameter (f, parms, Qauto_raise, Qnil,
3826 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3827 x_default_parameter (f, parms, Qauto_lower, Qnil,
3828 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3829 x_default_parameter (f, parms, Qcursor_type, Qbox,
3830 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3832 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3833 Change will not be effected unless different from the current
3834 FRAME_LINES (f). */
3835 width = FRAME_COLS (f);
3836 height = FRAME_LINES (f);
3837 SET_FRAME_COLS (f, 0);
3838 FRAME_LINES (f) = 0;
3839 change_frame_size (f, height, width, 1, 0, 0);
3841 /* Add `tooltip' frame parameter's default value. */
3842 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
3843 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
3844 Qnil));
3846 /* Set up faces after all frame parameters are known. This call
3847 also merges in face attributes specified for new frames.
3849 Frame parameters may be changed if .Xdefaults contains
3850 specifications for the default font. For example, if there is an
3851 `Emacs.default.attributeBackground: pink', the `background-color'
3852 attribute of the frame get's set, which let's the internal border
3853 of the tooltip frame appear in pink. Prevent this. */
3855 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
3857 /* Set tip_frame here, so that */
3858 tip_frame = frame;
3859 call1 (Qface_set_after_frame_default, frame);
3861 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
3862 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
3863 Qnil));
3866 f->no_split = 1;
3868 UNGCPRO;
3870 /* It is now ok to make the frame official even if we get an error
3871 below. And the frame needs to be on Vframe_list or making it
3872 visible won't work. */
3873 Vframe_list = Fcons (frame, Vframe_list);
3875 /* Now that the frame is official, it counts as a reference to
3876 its display. */
3877 FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
3879 /* Setting attributes of faces of the tooltip frame from resources
3880 and similar will increment face_change_count, which leads to the
3881 clearing of all current matrices. Since this isn't necessary
3882 here, avoid it by resetting face_change_count to the value it
3883 had before we created the tip frame. */
3884 face_change_count = face_change_count_before;
3886 /* Discard the unwind_protect. */
3887 return unbind_to (count, frame);
3891 /* Compute where to display tip frame F. PARMS is the list of frame
3892 parameters for F. DX and DY are specified offsets from the current
3893 location of the mouse. WIDTH and HEIGHT are the width and height
3894 of the tooltip. Return coordinates relative to the root window of
3895 the display in *ROOT_X, and *ROOT_Y. */
3897 static void
3898 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
3899 struct frame *f;
3900 Lisp_Object parms, dx, dy;
3901 int width, height;
3902 int *root_x, *root_y;
3904 Lisp_Object left, top;
3906 /* User-specified position? */
3907 left = Fcdr (Fassq (Qleft, parms));
3908 top = Fcdr (Fassq (Qtop, parms));
3910 /* Move the tooltip window where the mouse pointer is. Resize and
3911 show it. */
3912 if (!INTEGERP (left) || !INTEGERP (top))
3914 Point mouse_pos;
3916 BLOCK_INPUT;
3917 GetMouse (&mouse_pos);
3918 LocalToGlobal (&mouse_pos);
3919 *root_x = mouse_pos.h;
3920 *root_y = mouse_pos.v;
3921 UNBLOCK_INPUT;
3924 if (INTEGERP (top))
3925 *root_y = XINT (top);
3926 else if (*root_y + XINT (dy) - height < 0)
3927 *root_y -= XINT (dy);
3928 else
3930 *root_y -= height;
3931 *root_y += XINT (dy);
3934 if (INTEGERP (left))
3935 *root_x = XINT (left);
3936 else if (*root_x + XINT (dx) + width <= FRAME_MAC_DISPLAY_INFO (f)->width)
3937 /* It fits to the right of the pointer. */
3938 *root_x += XINT (dx);
3939 else if (width + XINT (dx) <= *root_x)
3940 /* It fits to the left of the pointer. */
3941 *root_x -= width + XINT (dx);
3942 else
3943 /* Put it left-justified on the screen -- it ought to fit that way. */
3944 *root_x = 0;
3948 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
3949 doc: /* Show STRING in a "tooltip" window on frame FRAME.
3950 A tooltip window is a small X window displaying a string.
3952 FRAME nil or omitted means use the selected frame.
3954 PARMS is an optional list of frame parameters which can be used to
3955 change the tooltip's appearance.
3957 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
3958 means use the default timeout of 5 seconds.
3960 If the list of frame parameters PARAMS contains a `left' parameters,
3961 the tooltip is displayed at that x-position. Otherwise it is
3962 displayed at the mouse position, with offset DX added (default is 5 if
3963 DX isn't specified). Likewise for the y-position; if a `top' frame
3964 parameter is specified, it determines the y-position of the tooltip
3965 window, otherwise it is displayed at the mouse position, with offset
3966 DY added (default is -10).
3968 A tooltip's maximum size is specified by `x-max-tooltip-size'.
3969 Text larger than the specified size is clipped. */)
3970 (string, frame, parms, timeout, dx, dy)
3971 Lisp_Object string, frame, parms, timeout, dx, dy;
3973 struct frame *f;
3974 struct window *w;
3975 int root_x, root_y;
3976 struct buffer *old_buffer;
3977 struct text_pos pos;
3978 int i, width, height;
3979 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3980 int old_windows_or_buffers_changed = windows_or_buffers_changed;
3981 int count = SPECPDL_INDEX ();
3983 specbind (Qinhibit_redisplay, Qt);
3985 GCPRO4 (string, parms, frame, timeout);
3987 CHECK_STRING (string);
3988 f = check_x_frame (frame);
3989 if (NILP (timeout))
3990 timeout = make_number (5);
3991 else
3992 CHECK_NATNUM (timeout);
3994 if (NILP (dx))
3995 dx = make_number (5);
3996 else
3997 CHECK_NUMBER (dx);
3999 if (NILP (dy))
4000 dy = make_number (-10);
4001 else
4002 CHECK_NUMBER (dy);
4004 if (NILP (last_show_tip_args))
4005 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
4007 if (!NILP (tip_frame))
4009 Lisp_Object last_string = AREF (last_show_tip_args, 0);
4010 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
4011 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
4013 if (EQ (frame, last_frame)
4014 && !NILP (Fequal (last_string, string))
4015 && !NILP (Fequal (last_parms, parms)))
4017 struct frame *f = XFRAME (tip_frame);
4019 /* Only DX and DY have changed. */
4020 if (!NILP (tip_timer))
4022 Lisp_Object timer = tip_timer;
4023 tip_timer = Qnil;
4024 call1 (Qcancel_timer, timer);
4027 BLOCK_INPUT;
4028 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
4029 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
4030 MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
4031 UNBLOCK_INPUT;
4032 goto start_timer;
4036 /* Hide a previous tip, if any. */
4037 Fx_hide_tip ();
4039 ASET (last_show_tip_args, 0, string);
4040 ASET (last_show_tip_args, 1, frame);
4041 ASET (last_show_tip_args, 2, parms);
4043 /* Add default values to frame parameters. */
4044 if (NILP (Fassq (Qname, parms)))
4045 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
4046 if (NILP (Fassq (Qinternal_border_width, parms)))
4047 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
4048 if (NILP (Fassq (Qborder_width, parms)))
4049 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
4050 if (NILP (Fassq (Qborder_color, parms)))
4051 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
4052 if (NILP (Fassq (Qbackground_color, parms)))
4053 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
4054 parms);
4056 /* Create a frame for the tooltip, and record it in the global
4057 variable tip_frame. */
4058 frame = x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f), parms, string);
4059 f = XFRAME (frame);
4061 /* Set up the frame's root window. */
4062 w = XWINDOW (FRAME_ROOT_WINDOW (f));
4063 w->left_col = w->top_line = make_number (0);
4065 if (CONSP (Vx_max_tooltip_size)
4066 && INTEGERP (XCAR (Vx_max_tooltip_size))
4067 && XINT (XCAR (Vx_max_tooltip_size)) > 0
4068 && INTEGERP (XCDR (Vx_max_tooltip_size))
4069 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
4071 w->total_cols = XCAR (Vx_max_tooltip_size);
4072 w->total_lines = XCDR (Vx_max_tooltip_size);
4074 else
4076 w->total_cols = make_number (80);
4077 w->total_lines = make_number (40);
4080 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
4081 adjust_glyphs (f);
4082 w->pseudo_window_p = 1;
4084 /* Display the tooltip text in a temporary buffer. */
4085 old_buffer = current_buffer;
4086 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
4087 current_buffer->truncate_lines = Qnil;
4088 clear_glyph_matrix (w->desired_matrix);
4089 clear_glyph_matrix (w->current_matrix);
4090 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
4091 try_window (FRAME_ROOT_WINDOW (f), pos);
4093 /* Compute width and height of the tooltip. */
4094 width = height = 0;
4095 for (i = 0; i < w->desired_matrix->nrows; ++i)
4097 struct glyph_row *row = &w->desired_matrix->rows[i];
4098 struct glyph *last;
4099 int row_width;
4101 /* Stop at the first empty row at the end. */
4102 if (!row->enabled_p || !row->displays_text_p)
4103 break;
4105 /* Let the row go over the full width of the frame. */
4106 row->full_width_p = 1;
4108 /* There's a glyph at the end of rows that is used to place
4109 the cursor there. Don't include the width of this glyph. */
4110 if (row->used[TEXT_AREA])
4112 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
4113 row_width = row->pixel_width - last->pixel_width;
4115 else
4116 row_width = row->pixel_width;
4118 height += row->height;
4119 width = max (width, row_width);
4122 /* Add the frame's internal border to the width and height the X
4123 window should have. */
4124 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4125 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4127 /* Move the tooltip window where the mouse pointer is. Resize and
4128 show it. */
4129 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
4131 BLOCK_INPUT;
4132 MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
4133 SizeWindow (FRAME_MAC_WINDOW (f), width, height, true);
4134 ShowWindow (FRAME_MAC_WINDOW (f));
4135 BringToFront (FRAME_MAC_WINDOW (f));
4136 UNBLOCK_INPUT;
4138 /* Draw into the window. */
4139 w->must_be_updated_p = 1;
4140 update_single_window (w, 1);
4142 /* Restore original current buffer. */
4143 set_buffer_internal_1 (old_buffer);
4144 windows_or_buffers_changed = old_windows_or_buffers_changed;
4146 start_timer:
4147 /* Let the tip disappear after timeout seconds. */
4148 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
4149 intern ("x-hide-tip"));
4151 UNGCPRO;
4152 return unbind_to (count, Qnil);
4156 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
4157 doc: /* Hide the current tooltip window, if there is any.
4158 Value is t if tooltip was open, nil otherwise. */)
4161 int count;
4162 Lisp_Object deleted, frame, timer;
4163 struct gcpro gcpro1, gcpro2;
4165 /* Return quickly if nothing to do. */
4166 if (NILP (tip_timer) && NILP (tip_frame))
4167 return Qnil;
4169 frame = tip_frame;
4170 timer = tip_timer;
4171 GCPRO2 (frame, timer);
4172 tip_frame = tip_timer = deleted = Qnil;
4174 count = SPECPDL_INDEX ();
4175 specbind (Qinhibit_redisplay, Qt);
4176 specbind (Qinhibit_quit, Qt);
4178 if (!NILP (timer))
4179 call1 (Qcancel_timer, timer);
4181 if (FRAMEP (frame))
4183 Fdelete_frame (frame, Qnil);
4184 deleted = Qt;
4187 UNGCPRO;
4188 return unbind_to (count, deleted);
4193 #if TARGET_API_MAC_CARBON
4194 /***********************************************************************
4195 File selection dialog
4196 ***********************************************************************/
4198 static pascal void mac_nav_event_callback P_ ((NavEventCallbackMessage,
4199 NavCBRecPtr, void *));
4202 There is a relatively standard way to do this using applescript to run
4203 a (choose file) method. However, this doesn't do "the right thing"
4204 by working only if the find-file occurred during a menu or toolbar
4205 click. So we must do the file dialog by hand, using the navigation
4206 manager. This also has more flexibility in determining the default
4207 directory and whether or not we are going to choose a file.
4210 extern Lisp_Object Qfile_name_history;
4212 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
4213 doc: /* Read file name, prompting with PROMPT in directory DIR.
4214 Use a file selection dialog.
4215 Select DEFAULT-FILENAME in the dialog's file selection box, if
4216 specified. Ensure that file exists if MUSTMATCH is non-nil.
4217 If ONLY-DIR-P is non-nil, the user can only select directories. */)
4218 (prompt, dir, default_filename, mustmatch, only_dir_p)
4219 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
4221 struct frame *f = SELECTED_FRAME ();
4222 Lisp_Object file = Qnil;
4223 int count = SPECPDL_INDEX ();
4224 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
4225 char filename[MAXPATHLEN];
4226 int default_filter_index = 1; /* 1: All Files, 2: Directories only */
4227 static NavEventUPP mac_nav_event_callbackUPP = NULL;
4229 GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p);
4230 CHECK_STRING (prompt);
4231 CHECK_STRING (dir);
4233 /* Create the dialog with PROMPT as title, using DIR as initial
4234 directory and using "*" as pattern. */
4235 dir = Fexpand_file_name (dir, Qnil);
4238 OSStatus status;
4239 NavDialogCreationOptions options;
4240 NavDialogRef dialogRef;
4241 NavTypeListHandle fileTypes = NULL;
4242 NavUserAction userAction;
4243 CFStringRef message=NULL, saveName = NULL;
4245 BLOCK_INPUT;
4246 /* No need for a callback function because we are modal */
4247 NavGetDefaultDialogCreationOptions(&options);
4248 options.modality = kWindowModalityAppModal;
4249 options.location.h = options.location.v = -1;
4250 options.optionFlags = kNavDefaultNavDlogOptions;
4251 options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */
4252 options.optionFlags |= kNavSelectAllReadableItem;
4253 if (!NILP(prompt))
4255 message = cfstring_create_with_string (prompt);
4256 options.message = message;
4258 /* Don't set the application, let it use default.
4259 options.clientName = CFSTR ("Emacs");
4262 if (mac_nav_event_callbackUPP == NULL)
4263 mac_nav_event_callbackUPP = NewNavEventUPP (mac_nav_event_callback);
4265 if (!NILP (only_dir_p))
4266 status = NavCreateChooseFolderDialog(&options, mac_nav_event_callbackUPP,
4267 NULL, NULL, &dialogRef);
4268 else if (NILP (mustmatch))
4270 /* This is a save dialog */
4271 options.optionFlags |= kNavDontConfirmReplacement;
4272 options.actionButtonLabel = CFSTR ("Ok");
4273 options.windowTitle = CFSTR ("Enter name");
4275 if (STRINGP (default_filename))
4277 Lisp_Object utf8 = ENCODE_UTF_8 (default_filename);
4278 char *begPtr = SDATA(utf8);
4279 char *filePtr = begPtr + SBYTES(utf8);
4280 while (filePtr != begPtr && !IS_DIRECTORY_SEP(filePtr[-1]))
4281 filePtr--;
4282 saveName = cfstring_create_with_utf8_cstring (filePtr);
4283 options.saveFileName = saveName;
4284 options.optionFlags |= kNavSelectDefaultLocation;
4286 status = NavCreatePutFileDialog(&options,
4287 'TEXT', kNavGenericSignature,
4288 mac_nav_event_callbackUPP, NULL,
4289 &dialogRef);
4291 else
4293 /* This is an open dialog*/
4294 status = NavCreateChooseFileDialog(&options, fileTypes,
4295 mac_nav_event_callbackUPP, NULL,
4296 NULL, NULL, &dialogRef);
4299 /* Set the default location and continue*/
4300 if (status == noErr)
4302 AEDesc defLocAed;
4303 #ifdef MAC_OSX
4304 FSRef defLoc;
4305 status = FSPathMakeRef(SDATA(ENCODE_FILE(dir)), &defLoc, NULL);
4306 #else
4307 FSSpec defLoc;
4308 status = posix_pathname_to_fsspec (SDATA (ENCODE_FILE (dir)), &defLoc);
4309 #endif
4310 if (status == noErr)
4312 #ifdef MAC_OSX
4313 AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed);
4314 #else
4315 AECreateDesc(typeFSS, &defLoc, sizeof(FSSpec), &defLocAed);
4316 #endif
4317 NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
4318 AEDisposeDesc(&defLocAed);
4320 status = NavDialogRun(dialogRef);
4323 if (saveName) CFRelease(saveName);
4324 if (message) CFRelease(message);
4326 if (status == noErr) {
4327 userAction = NavDialogGetUserAction(dialogRef);
4328 switch (userAction)
4330 case kNavUserActionNone:
4331 case kNavUserActionCancel:
4332 break; /* Treat cancel like C-g */
4333 case kNavUserActionOpen:
4334 case kNavUserActionChoose:
4335 case kNavUserActionSaveAs:
4337 NavReplyRecord reply;
4338 AEDesc aed;
4339 #ifdef MAC_OSX
4340 FSRef fsRef;
4341 #else
4342 FSSpec fs;
4343 #endif
4344 status = NavDialogGetReply(dialogRef, &reply);
4346 #ifdef MAC_OSX
4347 AECoerceDesc(&reply.selection, typeFSRef, &aed);
4348 AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef));
4349 FSRefMakePath(&fsRef, (UInt8 *) filename, sizeof (filename));
4350 #else
4351 AECoerceDesc (&reply.selection, typeFSS, &aed);
4352 AEGetDescData (&aed, (void *) &fs, sizeof (FSSpec));
4353 fsspec_to_posix_pathname (&fs, filename, sizeof (filename) - 1);
4354 #endif
4355 AEDisposeDesc(&aed);
4356 if (reply.saveFileName)
4358 /* If it was a saved file, we need to add the file name */
4359 int len = strlen(filename);
4360 if (len && filename[len-1] != '/')
4361 filename[len++] = '/';
4362 CFStringGetCString(reply.saveFileName, filename+len,
4363 sizeof (filename) - len,
4364 #if MAC_OSX
4365 kCFStringEncodingUTF8
4366 #else
4367 CFStringGetSystemEncoding ()
4368 #endif
4371 file = DECODE_FILE (make_unibyte_string (filename,
4372 strlen (filename)));
4373 NavDisposeReply(&reply);
4375 break;
4377 NavDialogDispose(dialogRef);
4379 else {
4380 /* Fall back on minibuffer if there was a problem */
4381 file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
4382 dir, mustmatch, dir, Qfile_name_history,
4383 default_filename, Qnil);
4385 UNBLOCK_INPUT;
4388 UNGCPRO;
4390 /* Make "Cancel" equivalent to C-g. */
4391 if (NILP (file))
4392 Fsignal (Qquit, Qnil);
4394 return unbind_to (count, file);
4398 /* Need to register some event callback function for enabling drag and
4399 drop in Navigation Service dialogs. */
4400 static pascal void
4401 mac_nav_event_callback (selector, parms, data)
4402 NavEventCallbackMessage selector;
4403 NavCBRecPtr parms;
4404 void *data ;
4407 #endif
4409 /***********************************************************************
4410 Initialization
4411 ***********************************************************************/
4413 /* Keep this list in the same order as frame_parms in frame.c.
4414 Use 0 for unsupported frame parameters. */
4416 frame_parm_handler mac_frame_parm_handlers[] =
4418 x_set_autoraise,
4419 x_set_autolower,
4420 x_set_background_color,
4421 x_set_border_color,
4422 x_set_border_width,
4423 x_set_cursor_color,
4424 x_set_cursor_type,
4425 x_set_font,
4426 x_set_foreground_color,
4427 x_set_icon_name,
4428 0, /* MAC_TODO: x_set_icon_type, */
4429 x_set_internal_border_width,
4430 x_set_menu_bar_lines,
4431 x_set_mouse_color,
4432 x_explicitly_set_name,
4433 x_set_scroll_bar_width,
4434 x_set_title,
4435 x_set_unsplittable,
4436 x_set_vertical_scroll_bars,
4437 x_set_visibility,
4438 x_set_tool_bar_lines,
4439 0, /* MAC_TODO: x_set_scroll_bar_foreground, */
4440 0, /* MAC_TODO: x_set_scroll_bar_background, */
4441 x_set_screen_gamma,
4442 x_set_line_spacing,
4443 x_set_fringe_width,
4444 x_set_fringe_width,
4445 0, /* x_set_wait_for_wm, */
4446 x_set_fullscreen,
4449 void
4450 syms_of_macfns ()
4452 #ifdef MAC_OSX
4453 /* This is zero if not using Mac native windows. */
4454 mac_in_use = 0;
4455 #else
4456 /* Certainly running on Mac native windows. */
4457 mac_in_use = 1;
4458 #endif
4460 /* The section below is built by the lisp expression at the top of the file,
4461 just above where these variables are declared. */
4462 /*&&& init symbols here &&&*/
4463 Qnone = intern ("none");
4464 staticpro (&Qnone);
4465 Qsuppress_icon = intern ("suppress-icon");
4466 staticpro (&Qsuppress_icon);
4467 Qundefined_color = intern ("undefined-color");
4468 staticpro (&Qundefined_color);
4469 Qcancel_timer = intern ("cancel-timer");
4470 staticpro (&Qcancel_timer);
4471 /* This is the end of symbol initialization. */
4473 /* Text property `display' should be nonsticky by default. */
4474 Vtext_property_default_nonsticky
4475 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
4478 Fput (Qundefined_color, Qerror_conditions,
4479 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
4480 Fput (Qundefined_color, Qerror_message,
4481 build_string ("Undefined color"));
4483 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
4484 doc: /* The shape of the pointer when over text.
4485 Changing the value does not affect existing frames
4486 unless you set the mouse color. */);
4487 Vx_pointer_shape = Qnil;
4489 #if 0 /* This doesn't really do anything. */
4490 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
4491 doc: /* The shape of the pointer when not over text.
4492 This variable takes effect when you create a new frame
4493 or when you set the mouse color. */);
4494 #endif
4495 Vx_nontext_pointer_shape = Qnil;
4497 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
4498 doc: /* The shape of the pointer when Emacs is busy.
4499 This variable takes effect when you create a new frame
4500 or when you set the mouse color. */);
4501 Vx_hourglass_pointer_shape = Qnil;
4503 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
4504 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
4505 display_hourglass_p = 1;
4507 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
4508 doc: /* *Seconds to wait before displaying an hourglass pointer.
4509 Value must be an integer or float. */);
4510 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
4512 #if 0 /* This doesn't really do anything. */
4513 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
4514 doc: /* The shape of the pointer when over the mode line.
4515 This variable takes effect when you create a new frame
4516 or when you set the mouse color. */);
4517 #endif
4518 Vx_mode_pointer_shape = Qnil;
4520 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
4521 &Vx_sensitive_text_pointer_shape,
4522 doc: /* The shape of the pointer when over mouse-sensitive text.
4523 This variable takes effect when you create a new frame
4524 or when you set the mouse color. */);
4525 Vx_sensitive_text_pointer_shape = Qnil;
4527 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
4528 &Vx_window_horizontal_drag_shape,
4529 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
4530 This variable takes effect when you create a new frame
4531 or when you set the mouse color. */);
4532 Vx_window_horizontal_drag_shape = Qnil;
4534 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
4535 doc: /* A string indicating the foreground color of the cursor box. */);
4536 Vx_cursor_fore_pixel = Qnil;
4538 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
4539 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
4540 Text larger than this is clipped. */);
4541 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
4543 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
4544 doc: /* Non-nil if no window manager is in use.
4545 Emacs doesn't try to figure this out; this is always nil
4546 unless you set it to something else. */);
4547 /* We don't have any way to find this out, so set it to nil
4548 and maybe the user would like to set it to t. */
4549 Vx_no_window_manager = Qnil;
4551 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
4552 &Vx_pixel_size_width_font_regexp,
4553 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
4555 Since Emacs gets width of a font matching with this regexp from
4556 PIXEL_SIZE field of the name, font finding mechanism gets faster for
4557 such a font. This is especially effective for such large fonts as
4558 Chinese, Japanese, and Korean. */);
4559 Vx_pixel_size_width_font_regexp = Qnil;
4561 /* X window properties. */
4562 defsubr (&Sx_change_window_property);
4563 defsubr (&Sx_delete_window_property);
4564 defsubr (&Sx_window_property);
4566 defsubr (&Sxw_display_color_p);
4567 defsubr (&Sx_display_grayscale_p);
4568 defsubr (&Sxw_color_defined_p);
4569 defsubr (&Sxw_color_values);
4570 defsubr (&Sx_server_max_request_size);
4571 defsubr (&Sx_server_vendor);
4572 defsubr (&Sx_server_version);
4573 defsubr (&Sx_display_pixel_width);
4574 defsubr (&Sx_display_pixel_height);
4575 defsubr (&Sx_display_mm_width);
4576 defsubr (&Sx_display_mm_height);
4577 defsubr (&Sx_display_screens);
4578 defsubr (&Sx_display_planes);
4579 defsubr (&Sx_display_color_cells);
4580 defsubr (&Sx_display_visual_class);
4581 defsubr (&Sx_display_backing_store);
4582 defsubr (&Sx_display_save_under);
4583 defsubr (&Sx_create_frame);
4584 defsubr (&Sx_open_connection);
4585 defsubr (&Sx_close_connection);
4586 defsubr (&Sx_display_list);
4587 defsubr (&Sx_synchronize);
4589 /* Setting callback functions for fontset handler. */
4590 get_font_info_func = x_get_font_info;
4592 #if 0 /* This function pointer doesn't seem to be used anywhere.
4593 And the pointer assigned has the wrong type, anyway. */
4594 list_fonts_func = x_list_fonts;
4595 #endif
4597 load_font_func = x_load_font;
4598 find_ccl_program_func = x_find_ccl_program;
4599 query_font_func = x_query_font;
4600 set_frame_fontset_func = x_set_font;
4601 check_window_system_func = check_mac;
4603 hourglass_atimer = NULL;
4604 hourglass_shown_p = 0;
4606 defsubr (&Sx_show_tip);
4607 defsubr (&Sx_hide_tip);
4608 tip_timer = Qnil;
4609 staticpro (&tip_timer);
4610 tip_frame = Qnil;
4611 staticpro (&tip_frame);
4613 last_show_tip_args = Qnil;
4614 staticpro (&last_show_tip_args);
4616 #if TARGET_API_MAC_CARBON
4617 defsubr (&Sx_file_dialog);
4618 #endif
4621 /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc
4622 (do not change this comment) */