(x-pointer-crosshair): Add defvar.
[emacs.git] / src / macfns.c
blob160eb1f77744d15229f517633b62df0a6b329d67
1 /* Graphical user interface functions for Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 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., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA. */
21 /* Contributed by Andrew Choi (akochoi@mac.com). */
23 #include <config.h>
24 #include <stdio.h>
25 #include <math.h>
27 #include "lisp.h"
28 #include "macterm.h"
29 #include "frame.h"
30 #include "window.h"
31 #include "buffer.h"
32 #include "intervals.h"
33 #include "dispextern.h"
34 #include "keyboard.h"
35 #include "blockinput.h"
36 #include <epaths.h>
37 #include "charset.h"
38 #include "coding.h"
39 #include "fontset.h"
40 #include "systime.h"
41 #include "termhooks.h"
42 #include "atimer.h"
44 #include <ctype.h>
45 #include <sys/types.h>
46 #include <sys/stat.h>
47 #include <limits.h>
48 #include <errno.h>
49 #include <sys/param.h>
51 extern void free_frame_menubar ();
53 /* Non-zero means we're allowed to display an hourglass cursor. */
55 int display_hourglass_p;
57 /* The background and shape of the mouse pointer, and shape when not
58 over text or in the modeline. */
60 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
61 Lisp_Object Vx_hourglass_pointer_shape;
63 /* The shape when over mouse-sensitive text. */
65 Lisp_Object Vx_sensitive_text_pointer_shape;
67 /* If non-nil, the pointer shape to indicate that windows can be
68 dragged horizontally. */
70 Lisp_Object Vx_window_horizontal_drag_shape;
72 /* Color of chars displayed in cursor box. */
74 Lisp_Object Vx_cursor_fore_pixel;
76 /* Nonzero if using Windows. */
78 static int mac_in_use;
80 /* Non nil if no window manager is in use. */
82 Lisp_Object Vx_no_window_manager;
84 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
86 Lisp_Object Vx_pixel_size_width_font_regexp;
88 Lisp_Object Qnone;
89 Lisp_Object Qsuppress_icon;
90 Lisp_Object Qundefined_color;
91 Lisp_Object Qcancel_timer;
93 /* In dispnew.c */
95 extern Lisp_Object Vwindow_system_version;
97 #if 0 /* Use xstricmp instead. */
98 /* compare two strings ignoring case */
100 static int
101 stricmp (const char *s, const char *t)
103 for ( ; tolower (*s) == tolower (*t); s++, t++)
104 if (*s == '\0')
105 return 0;
106 return tolower (*s) - tolower (*t);
108 #endif
110 /* compare two strings up to n characters, ignoring case */
112 static int
113 strnicmp (const char *s, const char *t, unsigned int n)
115 for ( ; n > 0 && tolower (*s) == tolower (*t); n--, s++, t++)
116 if (*s == '\0')
117 return 0;
118 return n == 0 ? 0 : tolower (*s) - tolower (*t);
122 /* Error if we are not running on Mac OS. */
124 void
125 check_mac ()
127 if (! mac_in_use)
128 error ("Mac native windows not in use or not initialized");
131 /* Nonzero if we can use mouse menus.
132 You should not call this unless HAVE_MENUS is defined. */
135 have_menus_p ()
137 return mac_in_use;
140 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
141 and checking validity for Mac. */
143 FRAME_PTR
144 check_x_frame (frame)
145 Lisp_Object frame;
147 FRAME_PTR f;
149 if (NILP (frame))
150 frame = selected_frame;
151 CHECK_LIVE_FRAME (frame);
152 f = XFRAME (frame);
153 if (! FRAME_MAC_P (f))
154 error ("Non-Mac frame used");
155 return f;
158 /* Let the user specify a display with a frame.
159 nil stands for the selected frame--or, if that is not a mac frame,
160 the first display on the list. */
162 struct mac_display_info *
163 check_x_display_info (frame)
164 Lisp_Object frame;
166 struct mac_display_info *dpyinfo = NULL;
168 if (NILP (frame))
170 struct frame *sf = XFRAME (selected_frame);
172 if (FRAME_MAC_P (sf) && FRAME_LIVE_P (sf))
173 dpyinfo = FRAME_MAC_DISPLAY_INFO (sf);
174 else if (x_display_list != 0)
175 dpyinfo = x_display_list;
176 else
177 error ("Mac native windows are not in use or not initialized");
179 else if (STRINGP (frame))
180 dpyinfo = x_display_info_for_name (frame);
181 else
183 FRAME_PTR f = check_x_frame (frame);
184 dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
187 return dpyinfo;
192 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
193 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
195 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
196 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
197 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
198 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
199 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
200 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
201 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
202 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
203 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
204 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
205 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
206 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
207 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
208 Lisp_Object));
209 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
210 Lisp_Object));
211 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
212 Lisp_Object,
213 Lisp_Object,
214 char *, char *,
215 int));
217 extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
221 /* Store the screen positions of frame F into XPTR and YPTR.
222 These are the positions of the containing window manager window,
223 not Emacs's own window. */
225 void
226 x_real_positions (f, xptr, yptr)
227 FRAME_PTR f;
228 int *xptr, *yptr;
230 Rect inner, outer;
232 mac_get_window_bounds (f, &inner, &outer);
234 f->x_pixels_diff = inner.left - outer.left;
235 f->y_pixels_diff = inner.top - outer.top;
237 *xptr = outer.left;
238 *yptr = outer.top;
242 /* The default colors for the Mac color map */
243 typedef struct colormap_t
245 unsigned long color;
246 char *name;
247 } colormap_t;
249 colormap_t mac_color_map[] =
251 { RGB_TO_ULONG(255, 250, 250), "snow" },
252 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
253 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
254 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
255 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
256 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
257 { RGB_TO_ULONG(255, 250, 240), "floral white" },
258 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
259 { RGB_TO_ULONG(253, 245, 230), "old lace" },
260 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
261 { RGB_TO_ULONG(250, 240, 230), "linen" },
262 { RGB_TO_ULONG(250, 235, 215), "antique white" },
263 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
264 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
265 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
266 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
267 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
268 { RGB_TO_ULONG(255, 228, 196), "bisque" },
269 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
270 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
271 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
272 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
273 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
274 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
275 { RGB_TO_ULONG(255, 255, 240), "ivory" },
276 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
277 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
278 { RGB_TO_ULONG(255, 245, 238), "seashell" },
279 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
280 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
281 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
282 { RGB_TO_ULONG(240, 255, 255), "azure" },
283 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
284 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
285 { RGB_TO_ULONG(230, 230, 250), "lavender" },
286 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
287 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
288 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
289 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
290 { RGB_TO_ULONG(255, 255, 255), "white" },
291 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
292 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
293 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
294 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
295 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
296 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
297 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
298 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
299 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
300 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
301 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
302 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
303 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
304 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
305 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
306 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
307 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
308 { RGB_TO_ULONG(190, 190, 190), "gray" },
309 { RGB_TO_ULONG(190, 190, 190), "grey" },
310 { RGB_TO_ULONG(211, 211, 211), "light grey" },
311 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
312 { RGB_TO_ULONG(211, 211, 211), "light gray" },
313 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
314 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
315 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
316 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
317 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
318 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
319 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
320 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
321 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
322 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
323 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
324 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
325 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
326 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
327 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
328 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
329 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
330 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
331 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
332 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
333 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
334 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
335 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
336 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
337 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
338 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
339 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
340 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
341 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
342 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
343 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
344 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
345 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
346 { RGB_TO_ULONG(173, 216, 230), "light blue" },
347 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
348 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
349 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
350 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
351 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
352 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
353 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
354 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
355 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
356 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
357 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
358 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
359 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
360 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
361 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
362 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
363 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
364 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
365 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
366 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
367 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
368 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
369 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
370 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
371 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
372 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
373 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
374 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
375 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
376 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
377 { RGB_TO_ULONG(152, 251, 152), "pale green" },
378 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
379 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
380 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
381 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
382 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
383 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
384 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
385 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
386 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
387 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
388 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
389 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
390 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
391 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
392 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
393 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
394 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
395 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
396 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
397 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
398 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
399 { RGB_TO_ULONG(240, 230, 140), "khaki" },
400 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
401 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
402 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
403 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
404 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
405 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
406 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
407 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
408 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
409 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
410 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
411 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
412 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
413 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
414 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
415 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
416 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
417 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
418 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
419 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
420 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
421 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
422 { RGB_TO_ULONG(245, 245, 220), "beige" },
423 { RGB_TO_ULONG(245, 222, 179), "wheat" },
424 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
425 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
426 { RGB_TO_ULONG(210, 180, 140), "tan" },
427 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
428 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
429 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
430 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
431 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
432 { RGB_TO_ULONG(250, 128, 114), "salmon" },
433 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
434 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
435 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
436 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
437 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
438 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
439 { RGB_TO_ULONG(240, 128, 128), "light coral" },
440 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
441 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
442 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
443 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
444 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
445 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
446 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
447 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
448 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
449 { RGB_TO_ULONG(255, 192, 203), "pink" },
450 { RGB_TO_ULONG(255, 182, 193), "light pink" },
451 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
452 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
453 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
454 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
455 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
456 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
457 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
458 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
459 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
460 { RGB_TO_ULONG(238, 130, 238), "violet" },
461 { RGB_TO_ULONG(221, 160, 221), "plum" },
462 { RGB_TO_ULONG(218, 112, 214), "orchid" },
463 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
464 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
465 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
466 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
467 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
468 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
469 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
470 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
471 { RGB_TO_ULONG(160, 32 , 240), "purple" },
472 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
473 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
474 { RGB_TO_ULONG(216, 191, 216), "thistle" },
475 { RGB_TO_ULONG(255, 250, 250), "snow1" },
476 { RGB_TO_ULONG(238, 233, 233), "snow2" },
477 { RGB_TO_ULONG(205, 201, 201), "snow3" },
478 { RGB_TO_ULONG(139, 137, 137), "snow4" },
479 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
480 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
481 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
482 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
483 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
484 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
485 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
486 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
487 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
488 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
489 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
490 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
491 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
492 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
493 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
494 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
495 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
496 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
497 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
498 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
499 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
500 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
501 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
502 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
503 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
504 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
505 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
506 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
507 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
508 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
509 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
510 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
511 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
512 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
513 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
514 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
515 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
516 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
517 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
518 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
519 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
520 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
521 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
522 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
523 { RGB_TO_ULONG(240, 255, 255), "azure1" },
524 { RGB_TO_ULONG(224, 238, 238), "azure2" },
525 { RGB_TO_ULONG(193, 205, 205), "azure3" },
526 { RGB_TO_ULONG(131, 139, 139), "azure4" },
527 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
528 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
529 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
530 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
531 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
532 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
533 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
534 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
535 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
536 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
537 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
538 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
539 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
540 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
541 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
542 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
543 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
544 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
545 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
546 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
547 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
548 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
549 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
550 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
551 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
552 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
553 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
554 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
555 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
556 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
557 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
558 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
559 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
560 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
561 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
562 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
563 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
564 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
565 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
566 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
567 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
568 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
569 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
570 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
571 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
572 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
573 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
574 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
575 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
576 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
577 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
578 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
579 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
580 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
581 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
582 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
583 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
584 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
585 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
586 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
587 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
588 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
589 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
590 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
591 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
592 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
593 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
594 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
595 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
596 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
597 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
598 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
599 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
600 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
601 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
602 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
603 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
604 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
605 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
606 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
607 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
608 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
609 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
610 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
611 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
612 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
613 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
614 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
615 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
616 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
617 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
618 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
619 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
620 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
621 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
622 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
623 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
624 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
625 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
626 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
627 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
628 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
629 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
630 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
631 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
632 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
633 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
634 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
635 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
636 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
637 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
638 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
639 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
640 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
641 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
642 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
643 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
644 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
645 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
646 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
647 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
648 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
649 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
650 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
651 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
652 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
653 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
654 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
655 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
656 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
657 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
658 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
659 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
660 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
661 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
662 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
663 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
664 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
665 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
666 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
667 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
668 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
669 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
670 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
671 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
672 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
673 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
674 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
675 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
676 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
677 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
678 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
679 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
680 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
681 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
682 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
683 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
684 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
685 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
686 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
687 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
688 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
689 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
690 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
691 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
692 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
693 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
694 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
695 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
696 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
697 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
698 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
699 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
700 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
701 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
702 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
703 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
704 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
705 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
706 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
707 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
708 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
709 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
710 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
711 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
712 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
713 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
714 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
715 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
716 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
717 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
718 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
719 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
720 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
721 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
722 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
723 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
724 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
725 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
726 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
727 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
728 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
729 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
730 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
731 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
732 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
733 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
734 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
735 { RGB_TO_ULONG(255, 181, 197), "pink1" },
736 { RGB_TO_ULONG(238, 169, 184), "pink2" },
737 { RGB_TO_ULONG(205, 145, 158), "pink3" },
738 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
739 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
740 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
741 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
742 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
743 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
744 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
745 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
746 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
747 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
748 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
749 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
750 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
751 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
752 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
753 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
754 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
755 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
756 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
757 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
758 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
759 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
760 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
761 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
762 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
763 { RGB_TO_ULONG(255, 187, 255), "plum1" },
764 { RGB_TO_ULONG(238, 174, 238), "plum2" },
765 { RGB_TO_ULONG(205, 150, 205), "plum3" },
766 { RGB_TO_ULONG(139, 102, 139), "plum4" },
767 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
768 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
769 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
770 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
771 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
772 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
773 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
774 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
775 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
776 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
777 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
778 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
779 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
780 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
781 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
782 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
783 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
784 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
785 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
786 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
787 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
788 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
789 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
790 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
791 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
792 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
793 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
794 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
795 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
796 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
797 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
798 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
799 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
800 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
801 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
802 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
803 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
804 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
805 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
806 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
807 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
808 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
809 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
810 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
811 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
812 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
813 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
814 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
815 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
816 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
817 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
818 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
819 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
820 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
821 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
822 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
823 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
824 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
825 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
826 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
827 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
828 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
829 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
830 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
831 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
832 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
833 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
834 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
835 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
836 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
837 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
838 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
839 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
840 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
841 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
842 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
843 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
844 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
845 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
846 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
847 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
848 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
849 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
850 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
851 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
852 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
853 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
854 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
855 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
856 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
857 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
858 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
859 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
860 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
861 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
862 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
863 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
864 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
865 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
866 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
867 { RGB_TO_ULONG(102, 102, 102), "gray40" },
868 { RGB_TO_ULONG(102, 102, 102), "grey40" },
869 { RGB_TO_ULONG(105, 105, 105), "gray41" },
870 { RGB_TO_ULONG(105, 105, 105), "grey41" },
871 { RGB_TO_ULONG(107, 107, 107), "gray42" },
872 { RGB_TO_ULONG(107, 107, 107), "grey42" },
873 { RGB_TO_ULONG(110, 110, 110), "gray43" },
874 { RGB_TO_ULONG(110, 110, 110), "grey43" },
875 { RGB_TO_ULONG(112, 112, 112), "gray44" },
876 { RGB_TO_ULONG(112, 112, 112), "grey44" },
877 { RGB_TO_ULONG(115, 115, 115), "gray45" },
878 { RGB_TO_ULONG(115, 115, 115), "grey45" },
879 { RGB_TO_ULONG(117, 117, 117), "gray46" },
880 { RGB_TO_ULONG(117, 117, 117), "grey46" },
881 { RGB_TO_ULONG(120, 120, 120), "gray47" },
882 { RGB_TO_ULONG(120, 120, 120), "grey47" },
883 { RGB_TO_ULONG(122, 122, 122), "gray48" },
884 { RGB_TO_ULONG(122, 122, 122), "grey48" },
885 { RGB_TO_ULONG(125, 125, 125), "gray49" },
886 { RGB_TO_ULONG(125, 125, 125), "grey49" },
887 { RGB_TO_ULONG(127, 127, 127), "gray50" },
888 { RGB_TO_ULONG(127, 127, 127), "grey50" },
889 { RGB_TO_ULONG(130, 130, 130), "gray51" },
890 { RGB_TO_ULONG(130, 130, 130), "grey51" },
891 { RGB_TO_ULONG(133, 133, 133), "gray52" },
892 { RGB_TO_ULONG(133, 133, 133), "grey52" },
893 { RGB_TO_ULONG(135, 135, 135), "gray53" },
894 { RGB_TO_ULONG(135, 135, 135), "grey53" },
895 { RGB_TO_ULONG(138, 138, 138), "gray54" },
896 { RGB_TO_ULONG(138, 138, 138), "grey54" },
897 { RGB_TO_ULONG(140, 140, 140), "gray55" },
898 { RGB_TO_ULONG(140, 140, 140), "grey55" },
899 { RGB_TO_ULONG(143, 143, 143), "gray56" },
900 { RGB_TO_ULONG(143, 143, 143), "grey56" },
901 { RGB_TO_ULONG(145, 145, 145), "gray57" },
902 { RGB_TO_ULONG(145, 145, 145), "grey57" },
903 { RGB_TO_ULONG(148, 148, 148), "gray58" },
904 { RGB_TO_ULONG(148, 148, 148), "grey58" },
905 { RGB_TO_ULONG(150, 150, 150), "gray59" },
906 { RGB_TO_ULONG(150, 150, 150), "grey59" },
907 { RGB_TO_ULONG(153, 153, 153), "gray60" },
908 { RGB_TO_ULONG(153, 153, 153), "grey60" },
909 { RGB_TO_ULONG(156, 156, 156), "gray61" },
910 { RGB_TO_ULONG(156, 156, 156), "grey61" },
911 { RGB_TO_ULONG(158, 158, 158), "gray62" },
912 { RGB_TO_ULONG(158, 158, 158), "grey62" },
913 { RGB_TO_ULONG(161, 161, 161), "gray63" },
914 { RGB_TO_ULONG(161, 161, 161), "grey63" },
915 { RGB_TO_ULONG(163, 163, 163), "gray64" },
916 { RGB_TO_ULONG(163, 163, 163), "grey64" },
917 { RGB_TO_ULONG(166, 166, 166), "gray65" },
918 { RGB_TO_ULONG(166, 166, 166), "grey65" },
919 { RGB_TO_ULONG(168, 168, 168), "gray66" },
920 { RGB_TO_ULONG(168, 168, 168), "grey66" },
921 { RGB_TO_ULONG(171, 171, 171), "gray67" },
922 { RGB_TO_ULONG(171, 171, 171), "grey67" },
923 { RGB_TO_ULONG(173, 173, 173), "gray68" },
924 { RGB_TO_ULONG(173, 173, 173), "grey68" },
925 { RGB_TO_ULONG(176, 176, 176), "gray69" },
926 { RGB_TO_ULONG(176, 176, 176), "grey69" },
927 { RGB_TO_ULONG(179, 179, 179), "gray70" },
928 { RGB_TO_ULONG(179, 179, 179), "grey70" },
929 { RGB_TO_ULONG(181, 181, 181), "gray71" },
930 { RGB_TO_ULONG(181, 181, 181), "grey71" },
931 { RGB_TO_ULONG(184, 184, 184), "gray72" },
932 { RGB_TO_ULONG(184, 184, 184), "grey72" },
933 { RGB_TO_ULONG(186, 186, 186), "gray73" },
934 { RGB_TO_ULONG(186, 186, 186), "grey73" },
935 { RGB_TO_ULONG(189, 189, 189), "gray74" },
936 { RGB_TO_ULONG(189, 189, 189), "grey74" },
937 { RGB_TO_ULONG(191, 191, 191), "gray75" },
938 { RGB_TO_ULONG(191, 191, 191), "grey75" },
939 { RGB_TO_ULONG(194, 194, 194), "gray76" },
940 { RGB_TO_ULONG(194, 194, 194), "grey76" },
941 { RGB_TO_ULONG(196, 196, 196), "gray77" },
942 { RGB_TO_ULONG(196, 196, 196), "grey77" },
943 { RGB_TO_ULONG(199, 199, 199), "gray78" },
944 { RGB_TO_ULONG(199, 199, 199), "grey78" },
945 { RGB_TO_ULONG(201, 201, 201), "gray79" },
946 { RGB_TO_ULONG(201, 201, 201), "grey79" },
947 { RGB_TO_ULONG(204, 204, 204), "gray80" },
948 { RGB_TO_ULONG(204, 204, 204), "grey80" },
949 { RGB_TO_ULONG(207, 207, 207), "gray81" },
950 { RGB_TO_ULONG(207, 207, 207), "grey81" },
951 { RGB_TO_ULONG(209, 209, 209), "gray82" },
952 { RGB_TO_ULONG(209, 209, 209), "grey82" },
953 { RGB_TO_ULONG(212, 212, 212), "gray83" },
954 { RGB_TO_ULONG(212, 212, 212), "grey83" },
955 { RGB_TO_ULONG(214, 214, 214), "gray84" },
956 { RGB_TO_ULONG(214, 214, 214), "grey84" },
957 { RGB_TO_ULONG(217, 217, 217), "gray85" },
958 { RGB_TO_ULONG(217, 217, 217), "grey85" },
959 { RGB_TO_ULONG(219, 219, 219), "gray86" },
960 { RGB_TO_ULONG(219, 219, 219), "grey86" },
961 { RGB_TO_ULONG(222, 222, 222), "gray87" },
962 { RGB_TO_ULONG(222, 222, 222), "grey87" },
963 { RGB_TO_ULONG(224, 224, 224), "gray88" },
964 { RGB_TO_ULONG(224, 224, 224), "grey88" },
965 { RGB_TO_ULONG(227, 227, 227), "gray89" },
966 { RGB_TO_ULONG(227, 227, 227), "grey89" },
967 { RGB_TO_ULONG(229, 229, 229), "gray90" },
968 { RGB_TO_ULONG(229, 229, 229), "grey90" },
969 { RGB_TO_ULONG(232, 232, 232), "gray91" },
970 { RGB_TO_ULONG(232, 232, 232), "grey91" },
971 { RGB_TO_ULONG(235, 235, 235), "gray92" },
972 { RGB_TO_ULONG(235, 235, 235), "grey92" },
973 { RGB_TO_ULONG(237, 237, 237), "gray93" },
974 { RGB_TO_ULONG(237, 237, 237), "grey93" },
975 { RGB_TO_ULONG(240, 240, 240), "gray94" },
976 { RGB_TO_ULONG(240, 240, 240), "grey94" },
977 { RGB_TO_ULONG(242, 242, 242), "gray95" },
978 { RGB_TO_ULONG(242, 242, 242), "grey95" },
979 { RGB_TO_ULONG(245, 245, 245), "gray96" },
980 { RGB_TO_ULONG(245, 245, 245), "grey96" },
981 { RGB_TO_ULONG(247, 247, 247), "gray97" },
982 { RGB_TO_ULONG(247, 247, 247), "grey97" },
983 { RGB_TO_ULONG(250, 250, 250), "gray98" },
984 { RGB_TO_ULONG(250, 250, 250), "grey98" },
985 { RGB_TO_ULONG(252, 252, 252), "gray99" },
986 { RGB_TO_ULONG(252, 252, 252), "grey99" },
987 { RGB_TO_ULONG(255, 255, 255), "gray100" },
988 { RGB_TO_ULONG(255, 255, 255), "grey100" },
989 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
990 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
991 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
992 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
993 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
994 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
995 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
996 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
997 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
998 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
999 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
1000 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1001 { RGB_TO_ULONG(144, 238, 144), "light green" },
1002 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1005 Lisp_Object
1006 mac_color_map_lookup (colorname)
1007 char *colorname;
1009 Lisp_Object ret = Qnil;
1010 int i;
1012 BLOCK_INPUT;
1014 for (i = 0; i < sizeof (mac_color_map) / sizeof (mac_color_map[0]); i++)
1015 if (xstricmp (colorname, mac_color_map[i].name) == 0)
1017 ret = make_number (mac_color_map[i].color);
1018 break;
1021 UNBLOCK_INPUT;
1023 return ret;
1026 Lisp_Object
1027 x_to_mac_color (colorname)
1028 char * colorname;
1030 register Lisp_Object tail, ret = Qnil;
1032 BLOCK_INPUT;
1034 if (colorname[0] == '#')
1036 /* Could be an old-style RGB Device specification. */
1037 char *color;
1038 int size;
1039 color = colorname + 1;
1041 size = strlen(color);
1042 if (size == 3 || size == 6 || size == 9 || size == 12)
1044 unsigned long colorval;
1045 int i, pos;
1046 pos = 16;
1047 size /= 3;
1048 colorval = 0;
1050 for (i = 0; i < 3; i++)
1052 char *end;
1053 char t;
1054 unsigned long value;
1056 /* The check for 'x' in the following conditional takes into
1057 account the fact that strtol allows a "0x" in front of
1058 our numbers, and we don't. */
1059 if (!isxdigit(color[0]) || color[1] == 'x')
1060 break;
1061 t = color[size];
1062 color[size] = '\0';
1063 value = strtoul(color, &end, 16);
1064 color[size] = t;
1065 if (errno == ERANGE || end - color != size)
1066 break;
1067 switch (size)
1069 case 1:
1070 value = value * 0x10;
1071 break;
1072 case 2:
1073 break;
1074 case 3:
1075 value /= 0x10;
1076 break;
1077 case 4:
1078 value /= 0x100;
1079 break;
1081 colorval |= (value << pos);
1082 pos -= 8;
1083 if (i == 2)
1085 UNBLOCK_INPUT;
1086 return make_number (colorval);
1088 color = end;
1092 else if (strnicmp(colorname, "rgb:", 4) == 0)
1094 char *color;
1095 unsigned long colorval;
1096 int i, pos;
1097 pos = 0;
1099 colorval = 0;
1100 color = colorname + 4;
1101 for (i = 0; i < 3; i++)
1103 char *end;
1104 unsigned long value;
1106 /* The check for 'x' in the following conditional takes into
1107 account the fact that strtol allows a "0x" in front of
1108 our numbers, and we don't. */
1109 if (!isxdigit(color[0]) || color[1] == 'x')
1110 break;
1111 value = strtoul(color, &end, 16);
1112 if (errno == ERANGE)
1113 break;
1114 switch (end - color)
1116 case 1:
1117 value = value * 0x10 + value;
1118 break;
1119 case 2:
1120 break;
1121 case 3:
1122 value /= 0x10;
1123 break;
1124 case 4:
1125 value /= 0x100;
1126 break;
1127 default:
1128 value = ULONG_MAX;
1130 if (value == ULONG_MAX)
1131 break;
1132 colorval |= (value << pos);
1133 pos += 0x8;
1134 if (i == 2)
1136 if (*end != '\0')
1137 break;
1138 UNBLOCK_INPUT;
1139 return make_number (colorval);
1141 if (*end != '/')
1142 break;
1143 color = end + 1;
1146 else if (strnicmp(colorname, "rgbi:", 5) == 0)
1148 /* This is an RGB Intensity specification. */
1149 char *color;
1150 unsigned long colorval;
1151 int i, pos;
1152 pos = 0;
1154 colorval = 0;
1155 color = colorname + 5;
1156 for (i = 0; i < 3; i++)
1158 char *end;
1159 double value;
1160 unsigned long val;
1162 value = strtod(color, &end);
1163 if (errno == ERANGE)
1164 break;
1165 if (value < 0.0 || value > 1.0)
1166 break;
1167 val = (unsigned long)(0x100 * value);
1168 /* We used 0x100 instead of 0xFF to give a continuous
1169 range between 0.0 and 1.0 inclusive. The next statement
1170 fixes the 1.0 case. */
1171 if (val == 0x100)
1172 val = 0xFF;
1173 colorval |= (val << pos);
1174 pos += 0x8;
1175 if (i == 2)
1177 if (*end != '\0')
1178 break;
1179 UNBLOCK_INPUT;
1180 return make_number (colorval);
1182 if (*end != '/')
1183 break;
1184 color = end + 1;
1188 ret = mac_color_map_lookup (colorname);
1190 UNBLOCK_INPUT;
1191 return ret;
1194 /* Gamma-correct COLOR on frame F. */
1196 void
1197 gamma_correct (f, color)
1198 struct frame *f;
1199 unsigned long *color;
1201 if (f->gamma)
1203 unsigned long red, green, blue;
1205 red = pow (RED_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1206 green = pow (GREEN_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1207 blue = pow (BLUE_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1208 *color = RGB_TO_ULONG (red, green, blue);
1212 /* Decide if color named COLOR is valid for the display associated
1213 with the selected frame; if so, return the rgb values in COLOR_DEF.
1214 If ALLOC is nonzero, allocate a new colormap cell. */
1217 mac_defined_color (f, color, color_def, alloc)
1218 FRAME_PTR f;
1219 char *color;
1220 XColor *color_def;
1221 int alloc;
1223 register Lisp_Object tem;
1224 unsigned long mac_color_ref;
1226 tem = x_to_mac_color (color);
1228 if (!NILP (tem))
1230 if (f)
1232 /* Apply gamma correction. */
1233 mac_color_ref = XUINT (tem);
1234 gamma_correct (f, &mac_color_ref);
1235 XSETINT (tem, mac_color_ref);
1238 color_def->pixel = mac_color_ref;
1239 color_def->red = RED16_FROM_ULONG (mac_color_ref);
1240 color_def->green = GREEN16_FROM_ULONG (mac_color_ref);
1241 color_def->blue = BLUE16_FROM_ULONG (mac_color_ref);
1243 return 1;
1245 else
1247 return 0;
1251 /* Given a string ARG naming a color, compute a pixel value from it
1252 suitable for screen F.
1253 If F is not a color screen, return DEF (default) regardless of what
1254 ARG says. */
1257 x_decode_color (f, arg, def)
1258 FRAME_PTR f;
1259 Lisp_Object arg;
1260 int def;
1262 XColor cdef;
1264 CHECK_STRING (arg);
1266 if (strcmp (SDATA (arg), "black") == 0)
1267 return BLACK_PIX_DEFAULT (f);
1268 else if (strcmp (SDATA (arg), "white") == 0)
1269 return WHITE_PIX_DEFAULT (f);
1271 #if 0
1272 if (FRAME_MAC_DISPLAY_INFO (f)->n_planes) == 1)
1273 return def;
1274 #endif
1276 if (mac_defined_color (f, SDATA (arg), &cdef, 1))
1277 return cdef.pixel;
1279 /* defined_color failed; return an ultimate default. */
1280 return def;
1283 /* Functions called only from `x_set_frame_param'
1284 to set individual parameters.
1286 If FRAME_MAC_WINDOW (f) is 0,
1287 the frame is being created and its window does not exist yet.
1288 In that case, just record the parameter's new value
1289 in the standard place; do not attempt to change the window. */
1291 void
1292 x_set_foreground_color (f, arg, oldval)
1293 struct frame *f;
1294 Lisp_Object arg, oldval;
1296 struct mac_output *mac = f->output_data.mac;
1297 unsigned long fg, old_fg;
1299 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1300 old_fg = FRAME_FOREGROUND_PIXEL (f);
1301 FRAME_FOREGROUND_PIXEL (f) = fg;
1303 if (FRAME_MAC_WINDOW (f) != 0)
1305 Display *dpy = FRAME_MAC_DISPLAY (f);
1307 BLOCK_INPUT;
1308 XSetForeground (dpy, mac->normal_gc, fg);
1309 XSetBackground (dpy, mac->reverse_gc, fg);
1311 if (mac->cursor_pixel == old_fg)
1313 unload_color (f, mac->cursor_pixel);
1314 mac->cursor_pixel = fg;
1315 XSetBackground (dpy, mac->cursor_gc, mac->cursor_pixel);
1318 UNBLOCK_INPUT;
1320 update_face_from_frame_parameter (f, Qforeground_color, arg);
1322 if (FRAME_VISIBLE_P (f))
1323 redraw_frame (f);
1326 unload_color (f, old_fg);
1329 void
1330 x_set_background_color (f, arg, oldval)
1331 struct frame *f;
1332 Lisp_Object arg, oldval;
1334 struct mac_output *mac = f->output_data.mac;
1335 unsigned long bg;
1337 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
1338 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
1339 FRAME_BACKGROUND_PIXEL (f) = bg;
1341 if (FRAME_MAC_WINDOW (f) != 0)
1343 Display *dpy = FRAME_MAC_DISPLAY (f);
1345 BLOCK_INPUT;
1346 XSetBackground (dpy, mac->normal_gc, bg);
1347 XSetForeground (dpy, mac->reverse_gc, bg);
1348 XSetWindowBackground (dpy, FRAME_MAC_WINDOW (f), bg);
1349 XSetForeground (dpy, mac->cursor_gc, bg);
1351 UNBLOCK_INPUT;
1352 update_face_from_frame_parameter (f, Qbackground_color, arg);
1354 if (FRAME_VISIBLE_P (f))
1355 redraw_frame (f);
1359 void
1360 x_set_mouse_color (f, arg, oldval)
1361 struct frame *f;
1362 Lisp_Object arg, oldval;
1364 struct x_output *x = f->output_data.x;
1365 Display *dpy = FRAME_MAC_DISPLAY (f);
1366 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
1367 Cursor hourglass_cursor, horizontal_drag_cursor;
1368 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1369 unsigned long mask_color = x->background_pixel;
1371 /* Don't let pointers be invisible. */
1372 if (mask_color == pixel)
1373 pixel = x->foreground_pixel;
1375 f->output_data.mac->mouse_pixel = pixel;
1377 if (!NILP (Vx_pointer_shape))
1379 CHECK_NUMBER (Vx_pointer_shape);
1380 cursor = XINT (Vx_pointer_shape);
1382 else
1383 cursor = kThemeIBeamCursor;
1385 if (!NILP (Vx_nontext_pointer_shape))
1387 CHECK_NUMBER (Vx_nontext_pointer_shape);
1388 nontext_cursor = XINT (Vx_nontext_pointer_shape);
1390 else
1391 nontext_cursor = kThemeArrowCursor;
1393 if (!NILP (Vx_hourglass_pointer_shape))
1395 CHECK_NUMBER (Vx_hourglass_pointer_shape);
1396 hourglass_cursor = XINT (Vx_hourglass_pointer_shape);
1398 else
1399 hourglass_cursor = kThemeWatchCursor;
1401 if (!NILP (Vx_mode_pointer_shape))
1403 CHECK_NUMBER (Vx_mode_pointer_shape);
1404 mode_cursor = XINT (Vx_mode_pointer_shape);
1406 else
1407 mode_cursor = kThemeArrowCursor;
1409 if (!NILP (Vx_sensitive_text_pointer_shape))
1411 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1412 hand_cursor = XINT (Vx_sensitive_text_pointer_shape);
1414 else
1415 hand_cursor = kThemePointingHandCursor;
1417 if (!NILP (Vx_window_horizontal_drag_shape))
1419 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1420 horizontal_drag_cursor = XINT (Vx_window_horizontal_drag_shape);
1422 else
1423 horizontal_drag_cursor = kThemeResizeLeftRightCursor;
1425 #if 0 /* MAC_TODO: cursor color changes */
1427 XColor fore_color, back_color;
1429 fore_color.pixel = f->output_data.mac->mouse_pixel;
1430 x_query_color (f, &fore_color);
1431 back_color.pixel = mask_color;
1432 x_query_color (f, &back_color);
1434 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1435 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1436 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1437 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1438 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1439 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1441 #endif
1443 BLOCK_INPUT;
1445 rif->define_frame_cursor (f, cursor);
1447 f->output_data.mac->text_cursor = cursor;
1448 f->output_data.mac->nontext_cursor = nontext_cursor;
1449 f->output_data.mac->hourglass_cursor = hourglass_cursor;
1450 f->output_data.mac->modeline_cursor = mode_cursor;
1451 f->output_data.mac->hand_cursor = hand_cursor;
1452 f->output_data.mac->horizontal_drag_cursor = horizontal_drag_cursor;
1454 UNBLOCK_INPUT;
1456 update_face_from_frame_parameter (f, Qmouse_color, arg);
1459 void
1460 x_set_cursor_color (f, arg, oldval)
1461 struct frame *f;
1462 Lisp_Object arg, oldval;
1464 unsigned long fore_pixel, pixel;
1466 if (!NILP (Vx_cursor_fore_pixel))
1467 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1468 WHITE_PIX_DEFAULT (f));
1469 else
1470 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1472 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1474 /* Make sure that the cursor color differs from the background color. */
1475 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1477 pixel = f->output_data.mac->mouse_pixel;
1478 if (pixel == fore_pixel)
1479 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1482 f->output_data.mac->cursor_foreground_pixel = fore_pixel;
1483 f->output_data.mac->cursor_pixel = pixel;
1485 if (FRAME_MAC_WINDOW (f) != 0)
1487 BLOCK_INPUT;
1488 /* Update frame's cursor_gc. */
1489 XSetBackground (FRAME_MAC_DISPLAY (f),
1490 f->output_data.mac->cursor_gc, pixel);
1491 XSetForeground (FRAME_MAC_DISPLAY (f),
1492 f->output_data.mac->cursor_gc, fore_pixel);
1493 UNBLOCK_INPUT;
1495 if (FRAME_VISIBLE_P (f))
1497 x_update_cursor (f, 0);
1498 x_update_cursor (f, 1);
1502 update_face_from_frame_parameter (f, Qcursor_color, arg);
1505 /* Set the border-color of frame F to pixel value PIX.
1506 Note that this does not fully take effect if done before
1507 F has a window. */
1509 void
1510 x_set_border_pixel (f, pix)
1511 struct frame *f;
1512 int pix;
1515 f->output_data.mac->border_pixel = pix;
1517 if (FRAME_MAC_WINDOW (f) != 0 && f->border_width > 0)
1519 if (FRAME_VISIBLE_P (f))
1520 redraw_frame (f);
1524 /* Set the border-color of frame F to value described by ARG.
1525 ARG can be a string naming a color.
1526 The border-color is used for the border that is drawn by the server.
1527 Note that this does not fully take effect if done before
1528 F has a window; it must be redone when the window is created. */
1530 void
1531 x_set_border_color (f, arg, oldval)
1532 struct frame *f;
1533 Lisp_Object arg, oldval;
1535 int pix;
1537 CHECK_STRING (arg);
1538 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1539 x_set_border_pixel (f, pix);
1540 update_face_from_frame_parameter (f, Qborder_color, arg);
1544 void
1545 x_set_cursor_type (f, arg, oldval)
1546 FRAME_PTR f;
1547 Lisp_Object arg, oldval;
1549 set_frame_cursor_types (f, arg);
1551 /* Make sure the cursor gets redrawn. */
1552 cursor_type_changed = 1;
1555 #if 0 /* MAC_TODO: really no icon for Mac */
1556 void
1557 x_set_icon_type (f, arg, oldval)
1558 struct frame *f;
1559 Lisp_Object arg, oldval;
1561 int result;
1563 if (NILP (arg) && NILP (oldval))
1564 return;
1566 if (STRINGP (arg) && STRINGP (oldval)
1567 && EQ (Fstring_equal (oldval, arg), Qt))
1568 return;
1570 if (SYMBOLP (arg) && SYMBOLP (oldval) && EQ (arg, oldval))
1571 return;
1573 BLOCK_INPUT;
1575 result = x_bitmap_icon (f, arg);
1576 if (result)
1578 UNBLOCK_INPUT;
1579 error ("No icon window available");
1582 UNBLOCK_INPUT;
1584 #endif /* MAC_TODO */
1586 void
1587 x_set_icon_name (f, arg, oldval)
1588 struct frame *f;
1589 Lisp_Object arg, oldval;
1591 int result;
1593 if (STRINGP (arg))
1595 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1596 return;
1598 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1599 return;
1601 f->icon_name = arg;
1603 #if 0 /* MAC_TODO */
1604 if (f->output_data.w32->icon_bitmap != 0)
1605 return;
1607 BLOCK_INPUT;
1609 result = x_text_icon (f,
1610 (char *) SDATA ((!NILP (f->icon_name)
1611 ? f->icon_name
1612 : !NILP (f->title)
1613 ? f->title
1614 : f->name)));
1616 if (result)
1618 UNBLOCK_INPUT;
1619 error ("No icon window available");
1622 /* If the window was unmapped (and its icon was mapped),
1623 the new icon is not mapped, so map the window in its stead. */
1624 if (FRAME_VISIBLE_P (f))
1626 #ifdef USE_X_TOOLKIT
1627 XtPopup (f->output_data.w32->widget, XtGrabNone);
1628 #endif
1629 XMapWindow (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f));
1632 XFlush (FRAME_W32_DISPLAY (f));
1633 UNBLOCK_INPUT;
1634 #endif /* MAC_TODO */
1638 void
1639 x_set_menu_bar_lines (f, value, oldval)
1640 struct frame *f;
1641 Lisp_Object value, oldval;
1643 int nlines;
1644 int olines = FRAME_MENU_BAR_LINES (f);
1646 /* Right now, menu bars don't work properly in minibuf-only frames;
1647 most of the commands try to apply themselves to the minibuffer
1648 frame itself, and get an error because you can't switch buffers
1649 in or split the minibuffer window. */
1650 if (FRAME_MINIBUF_ONLY_P (f))
1651 return;
1653 if (INTEGERP (value))
1654 nlines = XINT (value);
1655 else
1656 nlines = 0;
1658 FRAME_MENU_BAR_LINES (f) = 0;
1659 if (nlines)
1660 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1661 else
1663 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1664 free_frame_menubar (f);
1665 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1667 /* Adjust the frame size so that the client (text) dimensions
1668 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
1669 set correctly. */
1670 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
1671 do_pending_window_change (0);
1673 adjust_glyphs (f);
1677 /* Set the number of lines used for the tool bar of frame F to VALUE.
1678 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1679 is the old number of tool bar lines. This function changes the
1680 height of all windows on frame F to match the new tool bar height.
1681 The frame's height doesn't change. */
1683 void
1684 x_set_tool_bar_lines (f, value, oldval)
1685 struct frame *f;
1686 Lisp_Object value, oldval;
1688 int delta, nlines, root_height;
1689 Lisp_Object root_window;
1691 /* Treat tool bars like menu bars. */
1692 if (FRAME_MINIBUF_ONLY_P (f))
1693 return;
1695 /* Use VALUE only if an integer >= 0. */
1696 if (INTEGERP (value) && XINT (value) >= 0)
1697 nlines = XFASTINT (value);
1698 else
1699 nlines = 0;
1701 /* Make sure we redisplay all windows in this frame. */
1702 ++windows_or_buffers_changed;
1704 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1706 /* Don't resize the tool-bar to more than we have room for. */
1707 root_window = FRAME_ROOT_WINDOW (f);
1708 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1709 if (root_height - delta < 1)
1711 delta = root_height - 1;
1712 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1715 FRAME_TOOL_BAR_LINES (f) = nlines;
1716 change_window_heights (root_window, delta);
1717 adjust_glyphs (f);
1719 /* We also have to make sure that the internal border at the top of
1720 the frame, below the menu bar or tool bar, is redrawn when the
1721 tool bar disappears. This is so because the internal border is
1722 below the tool bar if one is displayed, but is below the menu bar
1723 if there isn't a tool bar. The tool bar draws into the area
1724 below the menu bar. */
1725 if (FRAME_MAC_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1727 updating_frame = f;
1728 clear_frame ();
1729 clear_current_matrices (f);
1730 updating_frame = NULL;
1733 /* If the tool bar gets smaller, the internal border below it
1734 has to be cleared. It was formerly part of the display
1735 of the larger tool bar, and updating windows won't clear it. */
1736 if (delta < 0)
1738 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1739 int width = FRAME_PIXEL_WIDTH (f);
1740 int y = nlines * FRAME_LINE_HEIGHT (f);
1742 BLOCK_INPUT;
1743 XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
1744 0, y, width, height, 0);
1745 UNBLOCK_INPUT;
1747 if (WINDOWP (f->tool_bar_window))
1748 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1754 /* Set the Mac window title to NAME for frame F. */
1756 static void
1757 x_set_name_internal (f, name)
1758 FRAME_PTR f;
1759 Lisp_Object name;
1761 if (FRAME_MAC_WINDOW (f))
1763 if (STRING_MULTIBYTE (name))
1764 #if TARGET_API_MAC_CARBON
1765 name = ENCODE_UTF_8 (name);
1766 #else
1767 name = ENCODE_SYSTEM (name);
1768 #endif
1770 BLOCK_INPUT;
1773 #if TARGET_API_MAC_CARBON
1774 CFStringRef windowTitle =
1775 cfstring_create_with_utf8_cstring (SDATA (name));
1777 SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle);
1778 CFRelease (windowTitle);
1779 #else
1780 Str255 windowTitle;
1781 if (strlen (SDATA (name)) < 255)
1783 strcpy (windowTitle, SDATA (name));
1784 c2pstr (windowTitle);
1785 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
1787 #endif
1790 UNBLOCK_INPUT;
1794 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1795 mac_id_name.
1797 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1798 name; if NAME is a string, set F's name to NAME and set
1799 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1801 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1802 suggesting a new name, which lisp code should override; if
1803 F->explicit_name is set, ignore the new name; otherwise, set it. */
1805 void
1806 x_set_name (f, name, explicit)
1807 struct frame *f;
1808 Lisp_Object name;
1809 int explicit;
1811 /* Make sure that requests from lisp code override requests from
1812 Emacs redisplay code. */
1813 if (explicit)
1815 /* If we're switching from explicit to implicit, we had better
1816 update the mode lines and thereby update the title. */
1817 if (f->explicit_name && NILP (name))
1818 update_mode_lines = 1;
1820 f->explicit_name = ! NILP (name);
1822 else if (f->explicit_name)
1823 return;
1825 /* If NAME is nil, set the name to the mac_id_name. */
1826 if (NILP (name))
1828 /* Check for no change needed in this very common case
1829 before we do any consing. */
1830 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name,
1831 SDATA (f->name)))
1832 return;
1833 name = build_string (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name);
1835 else
1836 CHECK_STRING (name);
1838 /* Don't change the name if it's already NAME. */
1839 if (! NILP (Fstring_equal (name, f->name)))
1840 return;
1842 f->name = name;
1844 /* For setting the frame title, the title parameter should override
1845 the name parameter. */
1846 if (! NILP (f->title))
1847 name = f->title;
1849 x_set_name_internal (f, name);
1852 /* This function should be called when the user's lisp code has
1853 specified a name for the frame; the name will override any set by the
1854 redisplay code. */
1855 void
1856 x_explicitly_set_name (f, arg, oldval)
1857 FRAME_PTR f;
1858 Lisp_Object arg, oldval;
1860 x_set_name (f, arg, 1);
1863 /* This function should be called by Emacs redisplay code to set the
1864 name; names set this way will never override names set by the user's
1865 lisp code. */
1866 void
1867 x_implicitly_set_name (f, arg, oldval)
1868 FRAME_PTR f;
1869 Lisp_Object arg, oldval;
1871 x_set_name (f, arg, 0);
1874 /* Change the title of frame F to NAME.
1875 If NAME is nil, use the frame name as the title.
1877 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1878 name; if NAME is a string, set F's name to NAME and set
1879 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1881 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1882 suggesting a new name, which lisp code should override; if
1883 F->explicit_name is set, ignore the new name; otherwise, set it. */
1885 void
1886 x_set_title (f, name, old_name)
1887 struct frame *f;
1888 Lisp_Object name, old_name;
1890 /* Don't change the title if it's already NAME. */
1891 if (EQ (name, f->title))
1892 return;
1894 update_mode_lines = 1;
1896 f->title = name;
1898 if (NILP (name))
1899 name = f->name;
1900 else
1901 CHECK_STRING (name);
1903 x_set_name_internal (f, name);
1906 void
1907 x_set_scroll_bar_default_width (f)
1908 struct frame *f;
1910 /* Imitate X without X Toolkit */
1912 int wid = FRAME_COLUMN_WIDTH (f);
1914 #ifdef MAC_OSX
1915 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 16; /* Aqua scroll bars. */
1916 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
1917 wid - 1) / wid;
1918 #else /* not MAC_OSX */
1919 /* Make the actual width at least 14 pixels and a multiple of a
1920 character width. */
1921 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1923 /* Use all of that space (aside from required margins) for the
1924 scroll bar. */
1925 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1926 #endif /* not MAC_OSX */
1930 /* Subroutines of creating a frame. */
1932 /* Retrieve the string resource specified by NAME with CLASS from
1933 database RDB.
1935 The return value points to the contents of a Lisp string. So it
1936 will not be valid after the next GC where string compaction will
1937 occur. */
1939 char *
1940 x_get_string_resource (rdb, name, class)
1941 XrmDatabase rdb;
1942 char *name, *class;
1944 Lisp_Object value = xrm_get_resource (rdb, name, class);
1946 if (STRINGP (value))
1947 return SDATA (value);
1948 else
1949 return NULL;
1952 /* Return the value of parameter PARAM.
1954 First search ALIST, then Vdefault_frame_alist, then the X defaults
1955 database, using ATTRIBUTE as the attribute name and CLASS as its class.
1957 Convert the resource to the type specified by desired_type.
1959 If no default is specified, return Qunbound. If you call
1960 mac_get_arg, make sure you deal with Qunbound in a reasonable way,
1961 and don't let it get stored in any Lisp-visible variables! */
1963 static Lisp_Object
1964 mac_get_arg (alist, param, attribute, class, type)
1965 Lisp_Object alist, param;
1966 char *attribute;
1967 char *class;
1968 enum resource_types type;
1970 return x_get_arg (check_x_display_info (Qnil),
1971 alist, param, attribute, class, type);
1975 /* XParseGeometry copied from w32xfns.c */
1978 * XParseGeometry parses strings of the form
1979 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
1980 * width, height, xoffset, and yoffset are unsigned integers.
1981 * Example: "=80x24+300-49"
1982 * The equal sign is optional.
1983 * It returns a bitmask that indicates which of the four values
1984 * were actually found in the string. For each value found,
1985 * the corresponding argument is updated; for each value
1986 * not found, the corresponding argument is left unchanged.
1989 static int
1990 read_integer (string, NextString)
1991 register char *string;
1992 char **NextString;
1994 register int Result = 0;
1995 int Sign = 1;
1997 if (*string == '+')
1998 string++;
1999 else if (*string == '-')
2001 string++;
2002 Sign = -1;
2004 for (; (*string >= '0') && (*string <= '9'); string++)
2006 Result = (Result * 10) + (*string - '0');
2008 *NextString = string;
2009 if (Sign >= 0)
2010 return (Result);
2011 else
2012 return (-Result);
2016 XParseGeometry (string, x, y, width, height)
2017 char *string;
2018 int *x, *y;
2019 unsigned int *width, *height; /* RETURN */
2021 int mask = NoValue;
2022 register char *strind;
2023 unsigned int tempWidth, tempHeight;
2024 int tempX, tempY;
2025 char *nextCharacter;
2027 if ((string == NULL) || (*string == '\0')) return (mask);
2028 if (*string == '=')
2029 string++; /* ignore possible '=' at beg of geometry spec */
2031 strind = (char *)string;
2032 if (*strind != '+' && *strind != '-' && *strind != 'x')
2034 tempWidth = read_integer (strind, &nextCharacter);
2035 if (strind == nextCharacter)
2036 return (0);
2037 strind = nextCharacter;
2038 mask |= WidthValue;
2041 if (*strind == 'x' || *strind == 'X')
2043 strind++;
2044 tempHeight = read_integer (strind, &nextCharacter);
2045 if (strind == nextCharacter)
2046 return (0);
2047 strind = nextCharacter;
2048 mask |= HeightValue;
2051 if ((*strind == '+') || (*strind == '-'))
2053 if (*strind == '-')
2055 strind++;
2056 tempX = -read_integer (strind, &nextCharacter);
2057 if (strind == nextCharacter)
2058 return (0);
2059 strind = nextCharacter;
2060 mask |= XNegative;
2063 else
2065 strind++;
2066 tempX = read_integer (strind, &nextCharacter);
2067 if (strind == nextCharacter)
2068 return (0);
2069 strind = nextCharacter;
2071 mask |= XValue;
2072 if ((*strind == '+') || (*strind == '-'))
2074 if (*strind == '-')
2076 strind++;
2077 tempY = -read_integer (strind, &nextCharacter);
2078 if (strind == nextCharacter)
2079 return (0);
2080 strind = nextCharacter;
2081 mask |= YNegative;
2084 else
2086 strind++;
2087 tempY = read_integer (strind, &nextCharacter);
2088 if (strind == nextCharacter)
2089 return (0);
2090 strind = nextCharacter;
2092 mask |= YValue;
2096 /* If strind isn't at the end of the string the it's an invalid
2097 geometry specification. */
2099 if (*strind != '\0') return (0);
2101 if (mask & XValue)
2102 *x = tempX;
2103 if (mask & YValue)
2104 *y = tempY;
2105 if (mask & WidthValue)
2106 *width = tempWidth;
2107 if (mask & HeightValue)
2108 *height = tempHeight;
2109 return (mask);
2113 /* Create and set up the Mac window for frame F. */
2115 static void
2116 mac_window (f)
2117 struct frame *f;
2119 Rect r;
2121 BLOCK_INPUT;
2123 SetRect (&r, f->left_pos, f->top_pos,
2124 f->left_pos + FRAME_PIXEL_WIDTH (f),
2125 f->top_pos + FRAME_PIXEL_HEIGHT (f));
2126 #if TARGET_API_MAC_CARBON
2127 CreateNewWindow (kDocumentWindowClass,
2128 kWindowStandardDocumentAttributes
2129 /* | kWindowToolbarButtonAttribute */,
2130 &r, &FRAME_MAC_WINDOW (f));
2131 if (FRAME_MAC_WINDOW (f))
2133 SetWRefCon (FRAME_MAC_WINDOW (f), (long) f->output_data.mac);
2134 if (install_window_handler (FRAME_MAC_WINDOW (f)) != noErr)
2136 DisposeWindow (FRAME_MAC_WINDOW (f));
2137 FRAME_MAC_WINDOW (f) = NULL;
2140 #else
2141 FRAME_MAC_WINDOW (f)
2142 = NewCWindow (NULL, &r, "\p", false, zoomDocProc,
2143 (WindowPtr) -1, 1, (long) f->output_data.mac);
2144 #endif
2145 /* so that update events can find this mac_output struct */
2146 f->output_data.mac->mFP = f; /* point back to emacs frame */
2148 #ifndef MAC_OSX
2149 if (FRAME_MAC_WINDOW (f))
2151 ControlRef root_control;
2153 if (CreateRootControl (FRAME_MAC_WINDOW (f), &root_control) != noErr)
2155 DisposeWindow (FRAME_MAC_WINDOW (f));
2156 FRAME_MAC_WINDOW (f) = NULL;
2159 #endif
2160 if (FRAME_MAC_WINDOW (f))
2161 XSetWindowBackground (FRAME_MAC_DISPLAY(f), FRAME_MAC_WINDOW (f),
2162 FRAME_BACKGROUND_PIXEL (f));
2164 validate_x_resource_name ();
2166 /* x_set_name normally ignores requests to set the name if the
2167 requested name is the same as the current name. This is the one
2168 place where that assumption isn't correct; f->name is set, but
2169 the server hasn't been told. */
2171 Lisp_Object name;
2172 int explicit = f->explicit_name;
2174 f->explicit_name = 0;
2175 name = f->name;
2176 f->name = Qnil;
2177 x_set_name (f, name, explicit);
2180 UNBLOCK_INPUT;
2182 if (FRAME_MAC_WINDOW (f) == 0)
2183 error ("Unable to create window");
2186 /* Handle the icon stuff for this window. Perhaps later we might
2187 want an x_set_icon_position which can be called interactively as
2188 well. */
2190 static void
2191 x_icon (f, parms)
2192 struct frame *f;
2193 Lisp_Object parms;
2195 Lisp_Object icon_x, icon_y;
2197 /* Set the position of the icon. Note that Windows 95 groups all
2198 icons in the tray. */
2199 icon_x = mac_get_arg (parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2200 icon_y = mac_get_arg (parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2201 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2203 CHECK_NUMBER (icon_x);
2204 CHECK_NUMBER (icon_y);
2206 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2207 error ("Both left and top icon corners of icon must be specified");
2209 BLOCK_INPUT;
2211 if (! EQ (icon_x, Qunbound))
2212 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2214 #if 0 /* TODO */
2215 /* Start up iconic or window? */
2216 x_wm_set_window_state
2217 (f, (EQ (w32_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL), Qicon)
2218 ? IconicState
2219 : NormalState));
2221 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2222 ? f->icon_name
2223 : f->name)));
2224 #endif
2226 UNBLOCK_INPUT;
2230 void
2231 x_make_gc (f)
2232 struct frame *f;
2234 XGCValues gc_values;
2236 BLOCK_INPUT;
2238 /* Create the GCs of this frame.
2239 Note that many default values are used. */
2241 /* Normal video */
2242 gc_values.font = FRAME_FONT (f);
2243 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2244 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2245 f->output_data.mac->normal_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2246 FRAME_MAC_WINDOW (f),
2247 GCFont | GCForeground | GCBackground,
2248 &gc_values);
2250 /* Reverse video style. */
2251 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2252 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2253 f->output_data.mac->reverse_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2254 FRAME_MAC_WINDOW (f),
2255 GCFont | GCForeground | GCBackground,
2256 &gc_values);
2258 /* Cursor has cursor-color background, background-color foreground. */
2259 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2260 gc_values.background = f->output_data.mac->cursor_pixel;
2261 f->output_data.mac->cursor_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2262 FRAME_MAC_WINDOW (f),
2263 GCFont | GCForeground | GCBackground,
2264 &gc_values);
2266 /* Reliefs. */
2267 f->output_data.mac->white_relief.gc = 0;
2268 f->output_data.mac->black_relief.gc = 0;
2270 #if 0
2271 /* Create the gray border tile used when the pointer is not in
2272 the frame. Since this depends on the frame's pixel values,
2273 this must be done on a per-frame basis. */
2274 f->output_data.x->border_tile
2275 = (XCreatePixmapFromBitmapData
2276 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2277 gray_bits, gray_width, gray_height,
2278 f->output_data.x->foreground_pixel,
2279 f->output_data.x->background_pixel,
2280 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2281 #endif
2283 UNBLOCK_INPUT;
2287 /* Free what was was allocated in x_make_gc. */
2289 void
2290 x_free_gcs (f)
2291 struct frame *f;
2293 Display *dpy = FRAME_MAC_DISPLAY (f);
2295 BLOCK_INPUT;
2297 if (f->output_data.mac->normal_gc)
2299 XFreeGC (dpy, f->output_data.mac->normal_gc);
2300 f->output_data.mac->normal_gc = 0;
2303 if (f->output_data.mac->reverse_gc)
2305 XFreeGC (dpy, f->output_data.mac->reverse_gc);
2306 f->output_data.mac->reverse_gc = 0;
2309 if (f->output_data.mac->cursor_gc)
2311 XFreeGC (dpy, f->output_data.mac->cursor_gc);
2312 f->output_data.mac->cursor_gc = 0;
2315 #if 0
2316 if (f->output_data.mac->border_tile)
2318 XFreePixmap (dpy, f->output_data.mac->border_tile);
2319 f->output_data.mac->border_tile = 0;
2321 #endif
2323 if (f->output_data.mac->white_relief.gc)
2325 XFreeGC (dpy, f->output_data.mac->white_relief.gc);
2326 f->output_data.mac->white_relief.gc = 0;
2329 if (f->output_data.mac->black_relief.gc)
2331 XFreeGC (dpy, f->output_data.mac->black_relief.gc);
2332 f->output_data.mac->black_relief.gc = 0;
2335 UNBLOCK_INPUT;
2339 /* Handler for signals raised during x_create_frame and
2340 x_create_top_frame. FRAME is the frame which is partially
2341 constructed. */
2343 static Lisp_Object
2344 unwind_create_frame (frame)
2345 Lisp_Object frame;
2347 struct frame *f = XFRAME (frame);
2349 /* If frame is ``official'', nothing to do. */
2350 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
2352 #if GLYPH_DEBUG
2353 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2354 #endif
2356 x_free_frame_resources (f);
2358 #if GLYPH_DEBUG
2359 /* Check that reference counts are indeed correct. */
2360 xassert (dpyinfo->reference_count == dpyinfo_refcount);
2361 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
2362 #endif
2363 return Qt;
2366 return Qnil;
2370 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2371 1, 1, 0,
2372 doc: /* Make a new window, which is called a "frame" in Emacs terms.
2373 Returns an Emacs frame object.
2374 ALIST is an alist of frame parameters.
2375 If the parameters specify that the frame should not have a minibuffer,
2376 and do not specify a specific minibuffer window to use,
2377 then `default-minibuffer-frame' must be a frame whose minibuffer can
2378 be shared by the new frame.
2380 This function is an internal primitive--use `make-frame' instead. */)
2381 (parms)
2382 Lisp_Object parms;
2384 struct frame *f;
2385 Lisp_Object frame, tem;
2386 Lisp_Object name;
2387 int minibuffer_only = 0;
2388 long window_prompting = 0;
2389 int width, height;
2390 int count = SPECPDL_INDEX ();
2391 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2392 Lisp_Object display;
2393 struct mac_display_info *dpyinfo = NULL;
2394 Lisp_Object parent;
2395 struct kboard *kb;
2396 char x_frame_name[10];
2397 static int x_frame_count = 2; /* begins at 2 because terminal frame is F1 */
2399 check_mac ();
2401 /* Use this general default value to start with
2402 until we know if this frame has a specified name. */
2403 Vx_resource_name = Vinvocation_name;
2405 display = mac_get_arg (parms, Qdisplay, 0, 0, RES_TYPE_STRING);
2406 if (EQ (display, Qunbound))
2407 display = Qnil;
2408 dpyinfo = check_x_display_info (display);
2409 #ifdef MULTI_KBOARD
2410 kb = dpyinfo->kboard;
2411 #else
2412 kb = &the_only_kboard;
2413 #endif
2415 name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
2416 if (!STRINGP (name)
2417 && ! EQ (name, Qunbound)
2418 && ! NILP (name))
2419 error ("Invalid frame name--not a string or nil");
2421 if (STRINGP (name))
2422 Vx_resource_name = name;
2424 /* See if parent window is specified. */
2425 parent = mac_get_arg (parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
2426 if (EQ (parent, Qunbound))
2427 parent = Qnil;
2428 if (! NILP (parent))
2429 CHECK_NUMBER (parent);
2431 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2432 /* No need to protect DISPLAY because that's not used after passing
2433 it to make_frame_without_minibuffer. */
2434 frame = Qnil;
2435 GCPRO4 (parms, parent, name, frame);
2436 tem = mac_get_arg (parms, Qminibuffer, "minibuffer", "Minibuffer",
2437 RES_TYPE_SYMBOL);
2438 if (EQ (tem, Qnone) || NILP (tem))
2439 f = make_frame_without_minibuffer (Qnil, kb, display);
2440 else if (EQ (tem, Qonly))
2442 f = make_minibuffer_frame ();
2443 minibuffer_only = 1;
2445 else if (WINDOWP (tem))
2446 f = make_frame_without_minibuffer (tem, kb, display);
2447 else
2448 f = make_frame (1);
2450 if (EQ (name, Qunbound) || NILP (name))
2452 sprintf (x_frame_name, "F%d", x_frame_count++);
2453 f->name = build_string (x_frame_name);
2454 f->explicit_name = 0;
2456 else
2458 f->name = name;
2459 f->explicit_name = 1;
2462 XSETFRAME (frame, f);
2464 /* Note that X Windows does support scroll bars. */
2465 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
2467 f->output_method = output_mac;
2468 f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output));
2469 bzero (f->output_data.mac, sizeof (struct mac_output));
2470 FRAME_FONTSET (f) = -1;
2471 record_unwind_protect (unwind_create_frame, frame);
2473 f->icon_name
2474 = mac_get_arg (parms, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
2475 if (! STRINGP (f->icon_name))
2476 f->icon_name = Qnil;
2478 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
2479 #ifdef MULTI_KBOARD
2480 FRAME_KBOARD (f) = kb;
2481 #endif
2483 /* Specify the parent under which to make this window. */
2485 if (!NILP (parent))
2487 f->output_data.mac->parent_desc = (Window) XFASTINT (parent);
2488 f->output_data.mac->explicit_parent = 1;
2490 else
2492 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
2493 f->output_data.mac->explicit_parent = 0;
2496 /* Set the name; the functions to which we pass f expect the name to
2497 be set. */
2498 if (EQ (name, Qunbound) || NILP (name))
2500 f->name = build_string (dpyinfo->mac_id_name);
2501 f->explicit_name = 0;
2503 else
2505 f->name = name;
2506 f->explicit_name = 1;
2507 /* use the frame's title when getting resources for this frame. */
2508 specbind (Qx_resource_name, name);
2511 /* Extract the window parameters from the supplied values
2512 that are needed to determine window geometry. */
2514 Lisp_Object font;
2516 font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
2518 BLOCK_INPUT;
2519 /* First, try whatever font the caller has specified. */
2520 if (STRINGP (font))
2522 tem = Fquery_fontset (font, Qnil);
2523 if (STRINGP (tem))
2524 font = x_new_fontset (f, SDATA (tem));
2525 else
2526 font = x_new_font (f, SDATA (font));
2529 /* Try out a font which we hope has bold and italic variations. */
2530 if (! STRINGP (font))
2531 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
2532 /* If those didn't work, look for something which will at least work. */
2533 if (! STRINGP (font))
2534 font = x_new_fontset (f, "fontset-mac");
2535 if (! STRINGP (font))
2536 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
2537 if (! STRINGP (font))
2538 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
2539 if (! STRINGP (font))
2540 error ("Cannot find any usable font");
2541 UNBLOCK_INPUT;
2543 x_default_parameter (f, parms, Qfont, font,
2544 "font", "Font", RES_TYPE_STRING);
2547 x_default_parameter (f, parms, Qborder_width, make_number (0),
2548 "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
2549 /* This defaults to 2 in order to match xterm. We recognize either
2550 internalBorderWidth or internalBorder (which is what xterm calls
2551 it). */
2552 if (NILP (Fassq (Qinternal_border_width, parms)))
2554 Lisp_Object value;
2556 value = mac_get_arg (parms, Qinternal_border_width,
2557 "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
2558 if (! EQ (value, Qunbound))
2559 parms = Fcons (Fcons (Qinternal_border_width, value),
2560 parms);
2562 /* Default internalBorderWidth to 0 on Windows to match other programs. */
2563 x_default_parameter (f, parms, Qinternal_border_width, make_number (0),
2564 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
2565 x_default_parameter (f, parms, Qvertical_scroll_bars, Qright,
2566 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
2568 /* Also do the stuff which must be set before the window exists. */
2569 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
2570 "foreground", "Foreground", RES_TYPE_STRING);
2571 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
2572 "background", "Background", RES_TYPE_STRING);
2573 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
2574 "pointerColor", "Foreground", RES_TYPE_STRING);
2575 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
2576 "cursorColor", "Foreground", RES_TYPE_STRING);
2577 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
2578 "borderColor", "BorderColor", RES_TYPE_STRING);
2579 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
2580 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
2581 x_default_parameter (f, parms, Qline_spacing, Qnil,
2582 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
2583 x_default_parameter (f, parms, Qleft_fringe, Qnil,
2584 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
2585 x_default_parameter (f, parms, Qright_fringe, Qnil,
2586 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
2589 /* Init faces before x_default_parameter is called for scroll-bar
2590 parameters because that function calls x_set_scroll_bar_width,
2591 which calls change_frame_size, which calls Fset_window_buffer,
2592 which runs hooks, which call Fvertical_motion. At the end, we
2593 end up in init_iterator with a null face cache, which should not
2594 happen. */
2595 init_frame_faces (f);
2597 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
2598 "menuBar", "MenuBar", RES_TYPE_NUMBER);
2599 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
2600 "toolBar", "ToolBar", RES_TYPE_NUMBER);
2601 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
2602 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
2603 x_default_parameter (f, parms, Qtitle, Qnil,
2604 "title", "Title", RES_TYPE_STRING);
2605 x_default_parameter (f, parms, Qfullscreen, Qnil,
2606 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
2608 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
2610 /* Compute the size of the window. */
2611 window_prompting = x_figure_window_size (f, parms, 1);
2613 tem = mac_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
2614 f->no_split = minibuffer_only || EQ (tem, Qt);
2616 mac_window (f);
2618 x_icon (f, parms);
2619 x_make_gc (f);
2621 /* Now consider the frame official. */
2622 FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
2623 Vframe_list = Fcons (frame, Vframe_list);
2625 /* We need to do this after creating the window, so that the
2626 icon-creation functions can say whose icon they're describing. */
2627 x_default_parameter (f, parms, Qicon_type, Qnil,
2628 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
2630 x_default_parameter (f, parms, Qauto_raise, Qnil,
2631 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2632 x_default_parameter (f, parms, Qauto_lower, Qnil,
2633 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2634 x_default_parameter (f, parms, Qcursor_type, Qbox,
2635 "cursorType", "CursorType", RES_TYPE_SYMBOL);
2636 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
2637 "scrollBarWidth", "ScrollBarWidth",
2638 RES_TYPE_NUMBER);
2640 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
2641 Change will not be effected unless different from the current
2642 FRAME_LINES (f). */
2643 width = FRAME_COLS (f);
2644 height = FRAME_LINES (f);
2646 SET_FRAME_COLS (f, 0);
2647 FRAME_LINES (f) = 0;
2648 change_frame_size (f, height, width, 1, 0, 0);
2650 /* Tell the server what size and position, etc, we want, and how
2651 badly we want them. This should be done after we have the menu
2652 bar so that its size can be taken into account. */
2653 BLOCK_INPUT;
2654 x_wm_set_size_hint (f, window_prompting, 0);
2655 UNBLOCK_INPUT;
2657 /* Make the window appear on the frame and enable display, unless
2658 the caller says not to. However, with explicit parent, Emacs
2659 cannot control visibility, so don't try. */
2660 if (! f->output_data.mac->explicit_parent)
2662 Lisp_Object visibility;
2664 visibility = mac_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
2665 if (EQ (visibility, Qunbound))
2666 visibility = Qt;
2668 #if 0 /* MAC_TODO: really no iconify on Mac */
2669 if (EQ (visibility, Qicon))
2670 x_iconify_frame (f);
2671 else
2672 #endif
2673 if (! NILP (visibility))
2674 x_make_frame_visible (f);
2675 else
2676 /* Must have been Qnil. */
2679 UNGCPRO;
2681 /* Make sure windows on this frame appear in calls to next-window
2682 and similar functions. */
2683 Vwindow_list = Qnil;
2685 return unbind_to (count, frame);
2688 /* FRAME is used only to get a handle on the X display. We don't pass the
2689 display info directly because we're called from frame.c, which doesn't
2690 know about that structure. */
2691 Lisp_Object
2692 x_get_focus_frame (frame)
2693 struct frame *frame;
2695 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
2696 Lisp_Object xfocus;
2697 if (! dpyinfo->x_focus_frame)
2698 return Qnil;
2700 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
2701 return xfocus;
2704 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
2705 doc: /* Internal function called by `color-defined-p', which see. */)
2706 (color, frame)
2707 Lisp_Object color, frame;
2709 XColor foo;
2710 FRAME_PTR f = check_x_frame (frame);
2712 CHECK_STRING (color);
2714 if (mac_defined_color (f, SDATA (color), &foo, 0))
2715 return Qt;
2716 else
2717 return Qnil;
2720 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2721 doc: /* Internal function called by `color-values', which see. */)
2722 (color, frame)
2723 Lisp_Object color, frame;
2725 XColor foo;
2726 FRAME_PTR f = check_x_frame (frame);
2728 CHECK_STRING (color);
2730 if (mac_defined_color (f, SDATA (color), &foo, 0))
2732 Lisp_Object rgb[3];
2734 rgb[0] = make_number (foo.red);
2735 rgb[1] = make_number (foo.green);
2736 rgb[2] = make_number (foo.blue);
2737 return Flist (3, rgb);
2739 else
2740 return Qnil;
2743 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2744 doc: /* Internal function called by `display-color-p', which see. */)
2745 (display)
2746 Lisp_Object display;
2748 struct mac_display_info *dpyinfo = check_x_display_info (display);
2750 if (!dpyinfo->color_p)
2751 return Qnil;
2753 return Qt;
2756 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
2757 0, 1, 0,
2758 doc: /* Return t if DISPLAY supports shades of gray.
2759 Note that color displays do support shades of gray.
2760 The optional argument DISPLAY specifies which display to ask about.
2761 DISPLAY should be either a frame or a display name (a string).
2762 If omitted or nil, that stands for the selected frame's display. */)
2763 (display)
2764 Lisp_Object display;
2766 struct mac_display_info *dpyinfo = check_x_display_info (display);
2768 if (dpyinfo->n_planes <= 1)
2769 return Qnil;
2771 return Qt;
2774 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2775 0, 1, 0,
2776 doc: /* Returns the width in pixels of DISPLAY.
2777 The optional argument DISPLAY specifies which display to ask about.
2778 DISPLAY should be either a frame or a display name (a string).
2779 If omitted or nil, that stands for the selected frame's display. */)
2780 (display)
2781 Lisp_Object display;
2783 struct mac_display_info *dpyinfo = check_x_display_info (display);
2785 return make_number (dpyinfo->width);
2788 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2789 Sx_display_pixel_height, 0, 1, 0,
2790 doc: /* Returns the height in pixels of DISPLAY.
2791 The optional argument DISPLAY specifies which display to ask about.
2792 DISPLAY should be either a frame or a display name (a string).
2793 If omitted or nil, that stands for the selected frame's display. */)
2794 (display)
2795 Lisp_Object display;
2797 struct mac_display_info *dpyinfo = check_x_display_info (display);
2799 return make_number (dpyinfo->height);
2802 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2803 0, 1, 0,
2804 doc: /* Returns the number of bitplanes of DISPLAY.
2805 The optional argument DISPLAY specifies which display to ask about.
2806 DISPLAY should be either a frame or a display name (a string).
2807 If omitted or nil, that stands for the selected frame's display. */)
2808 (display)
2809 Lisp_Object display;
2811 struct mac_display_info *dpyinfo = check_x_display_info (display);
2813 return make_number (dpyinfo->n_planes);
2816 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2817 0, 1, 0,
2818 doc: /* Returns the number of color cells of DISPLAY.
2819 The optional argument DISPLAY specifies which display to ask about.
2820 DISPLAY should be either a frame or a display name (a string).
2821 If omitted or nil, that stands for the selected frame's display. */)
2822 (display)
2823 Lisp_Object display;
2825 struct mac_display_info *dpyinfo = check_x_display_info (display);
2827 /* We force 24+ bit depths to 24-bit to prevent an overflow. */
2828 return make_number (1 << min (dpyinfo->n_planes, 24));
2831 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
2832 Sx_server_max_request_size,
2833 0, 1, 0,
2834 doc: /* Returns the maximum request size of the server of DISPLAY.
2835 The optional argument DISPLAY specifies which display to ask about.
2836 DISPLAY should be either a frame or a display name (a string).
2837 If omitted or nil, that stands for the selected frame's display. */)
2838 (display)
2839 Lisp_Object display;
2841 struct mac_display_info *dpyinfo = check_x_display_info (display);
2843 return make_number (1);
2846 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
2847 doc: /* Returns the "vendor ID" string of the Mac OS system (Apple).
2848 The optional argument DISPLAY specifies which display to ask about.
2849 DISPLAY should be either a frame or a display name (a string).
2850 If omitted or nil, that stands for the selected frame's display. */)
2851 (display)
2852 Lisp_Object display;
2854 return build_string ("Apple Computers");
2857 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
2858 doc: /* Returns the version numbers of the Mac OS system.
2859 The value is a list of three integers: the major and minor
2860 version numbers, and the vendor-specific release
2861 number. See also the function `x-server-vendor'.
2863 The optional argument DISPLAY specifies which display to ask about.
2864 DISPLAY should be either a frame or a display name (a string).
2865 If omitted or nil, that stands for the selected frame's display. */)
2866 (display)
2867 Lisp_Object display;
2869 int mac_major_version;
2870 SInt32 response;
2871 OSErr err;
2873 BLOCK_INPUT;
2874 err = Gestalt (gestaltSystemVersion, &response);
2875 UNBLOCK_INPUT;
2877 if (err != noErr)
2878 error ("Cannot get Mac OS version");
2880 mac_major_version = (response >> 8) & 0xff;
2881 /* convert BCD to int */
2882 mac_major_version -= (mac_major_version >> 4) * 6;
2884 return Fcons (make_number (mac_major_version),
2885 Fcons (make_number ((response >> 4) & 0xf),
2886 Fcons (make_number (response & 0xf),
2887 Qnil)));
2890 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
2891 doc: /* Return the number of screens on the server of DISPLAY.
2892 The optional argument DISPLAY specifies which display to ask about.
2893 DISPLAY should be either a frame or a display name (a string).
2894 If omitted or nil, that stands for the selected frame's display. */)
2895 (display)
2896 Lisp_Object display;
2898 return make_number (1);
2901 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
2902 doc: /* Return the height in millimeters of DISPLAY.
2903 The optional argument DISPLAY specifies which display to ask about.
2904 DISPLAY should be either a frame or a display name (a string).
2905 If omitted or nil, that stands for the selected frame's display. */)
2906 (display)
2907 Lisp_Object display;
2909 /* MAC_TODO: this is an approximation, and only of the main display */
2911 struct mac_display_info *dpyinfo = check_x_display_info (display);
2913 return make_number ((int) (dpyinfo->height * 25.4 / dpyinfo->resy));
2916 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
2917 doc: /* Return the width in millimeters of DISPLAY.
2918 The optional argument DISPLAY specifies which display to ask about.
2919 DISPLAY should be either a frame or a display name (a string).
2920 If omitted or nil, that stands for the selected frame's display. */)
2921 (display)
2922 Lisp_Object display;
2924 /* MAC_TODO: this is an approximation, and only of the main display */
2926 struct mac_display_info *dpyinfo = check_x_display_info (display);
2928 return make_number ((int) (dpyinfo->width * 25.4 / dpyinfo->resx));
2931 DEFUN ("x-display-backing-store", Fx_display_backing_store,
2932 Sx_display_backing_store, 0, 1, 0,
2933 doc: /* Returns an indication of whether DISPLAY does backing store.
2934 The value may be `always', `when-mapped', or `not-useful'.
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 return intern ("not-useful");
2944 DEFUN ("x-display-visual-class", Fx_display_visual_class,
2945 Sx_display_visual_class, 0, 1, 0,
2946 doc: /* Returns the visual class of DISPLAY.
2947 The value is one of the symbols `static-gray', `gray-scale',
2948 `static-color', `pseudo-color', `true-color', or `direct-color'.
2950 The optional argument DISPLAY specifies which display to ask about.
2951 DISPLAY should be either a frame or a display name (a string).
2952 If omitted or nil, that stands for the selected frame's display. */)
2953 (display)
2954 Lisp_Object display;
2956 struct mac_display_info *dpyinfo = check_x_display_info (display);
2958 #if 0
2959 switch (dpyinfo->visual->class)
2961 case StaticGray: return (intern ("static-gray"));
2962 case GrayScale: return (intern ("gray-scale"));
2963 case StaticColor: return (intern ("static-color"));
2964 case PseudoColor: return (intern ("pseudo-color"));
2965 case TrueColor: return (intern ("true-color"));
2966 case DirectColor: return (intern ("direct-color"));
2967 default:
2968 error ("Display has an unknown visual class");
2970 #endif /* 0 */
2972 return (intern ("true-color"));
2975 DEFUN ("x-display-save-under", Fx_display_save_under,
2976 Sx_display_save_under, 0, 1, 0,
2977 doc: /* Returns t if DISPLAY supports the save-under feature.
2978 The optional argument DISPLAY specifies which display to ask about.
2979 DISPLAY should be either a frame or a display name (a string).
2980 If omitted or nil, that stands for the selected frame's display. */)
2981 (display)
2982 Lisp_Object display;
2984 return Qnil;
2988 x_pixel_width (f)
2989 register struct frame *f;
2991 return FRAME_PIXEL_WIDTH (f);
2995 x_pixel_height (f)
2996 register struct frame *f;
2998 return FRAME_PIXEL_HEIGHT (f);
3002 x_char_width (f)
3003 register struct frame *f;
3005 return FRAME_COLUMN_WIDTH (f);
3009 x_char_height (f)
3010 register struct frame *f;
3012 return FRAME_LINE_HEIGHT (f);
3016 x_screen_planes (f)
3017 register struct frame *f;
3019 return FRAME_MAC_DISPLAY_INFO (f)->n_planes;
3022 /* Return the display structure for the display named NAME.
3023 Open a new connection if necessary. */
3025 struct mac_display_info *
3026 x_display_info_for_name (name)
3027 Lisp_Object name;
3029 Lisp_Object names;
3030 struct mac_display_info *dpyinfo;
3032 CHECK_STRING (name);
3034 if (! EQ (Vwindow_system, intern ("mac")))
3035 error ("Not using Mac native windows");
3037 for (dpyinfo = &one_mac_display_info, names = x_display_name_list;
3038 dpyinfo;
3039 dpyinfo = dpyinfo->next, names = XCDR (names))
3041 Lisp_Object tem;
3042 tem = Fstring_equal (XCAR (XCAR (names)), name);
3043 if (!NILP (tem))
3044 return dpyinfo;
3047 /* Use this general default value to start with. */
3048 Vx_resource_name = Vinvocation_name;
3050 validate_x_resource_name ();
3052 dpyinfo = mac_term_init (name, (unsigned char *) 0,
3053 (char *) SDATA (Vx_resource_name));
3055 if (dpyinfo == 0)
3056 error ("Cannot connect to server %s", SDATA (name));
3058 mac_in_use = 1;
3059 XSETFASTINT (Vwindow_system_version, 3);
3061 return dpyinfo;
3064 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
3065 1, 3, 0,
3066 doc: /* Open a connection to a server.
3067 DISPLAY is the name of the display to connect to.
3068 Optional second arg XRM-STRING is a string of resources in xrdb format.
3069 If the optional third arg MUST-SUCCEED is non-nil,
3070 terminate Emacs if we can't open the connection. */)
3071 (display, xrm_string, must_succeed)
3072 Lisp_Object display, xrm_string, must_succeed;
3074 unsigned char *xrm_option;
3075 struct mac_display_info *dpyinfo;
3077 CHECK_STRING (display);
3078 if (! NILP (xrm_string))
3079 CHECK_STRING (xrm_string);
3081 if (! EQ (Vwindow_system, intern ("mac")))
3082 error ("Not using Mac native windows");
3084 if (! NILP (xrm_string))
3085 xrm_option = (unsigned char *) SDATA (xrm_string);
3086 else
3087 xrm_option = (unsigned char *) 0;
3089 validate_x_resource_name ();
3091 /* This is what opens the connection and sets x_current_display.
3092 This also initializes many symbols, such as those used for input. */
3093 dpyinfo = mac_term_init (display, xrm_option,
3094 (char *) SDATA (Vx_resource_name));
3096 if (dpyinfo == 0)
3098 if (!NILP (must_succeed))
3099 fatal ("Cannot connect to server %s.\n",
3100 SDATA (display));
3101 else
3102 error ("Cannot connect to server %s", SDATA (display));
3105 mac_in_use = 1;
3107 XSETFASTINT (Vwindow_system_version, 3);
3108 return Qnil;
3111 DEFUN ("x-close-connection", Fx_close_connection,
3112 Sx_close_connection, 1, 1, 0,
3113 doc: /* Close the connection to DISPLAY's server.
3114 For DISPLAY, specify either a frame or a display name (a string).
3115 If DISPLAY is nil, that stands for the selected frame's display. */)
3116 (display)
3117 Lisp_Object display;
3119 struct mac_display_info *dpyinfo = check_x_display_info (display);
3120 int i;
3122 if (dpyinfo->reference_count > 0)
3123 error ("Display still has frames on it");
3125 BLOCK_INPUT;
3126 /* Free the fonts in the font table. */
3127 for (i = 0; i < dpyinfo->n_fonts; i++)
3128 if (dpyinfo->font_table[i].name)
3130 mac_unload_font (dpyinfo, dpyinfo->font_table[i].font);
3133 x_destroy_all_bitmaps (dpyinfo);
3135 x_delete_display (dpyinfo);
3136 UNBLOCK_INPUT;
3138 return Qnil;
3141 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
3142 doc: /* Return the list of display names that Emacs has connections to. */)
3145 Lisp_Object tail, result;
3147 result = Qnil;
3148 for (tail = x_display_name_list; ! NILP (tail); tail = XCDR (tail))
3149 result = Fcons (XCAR (XCAR (tail)), result);
3151 return result;
3154 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
3155 doc: /* This is a noop on Mac OS systems. */)
3156 (on, display)
3157 Lisp_Object display, on;
3159 return Qnil;
3163 /***********************************************************************
3164 Window properties
3165 ***********************************************************************/
3167 DEFUN ("x-change-window-property", Fx_change_window_property,
3168 Sx_change_window_property, 2, 6, 0,
3169 doc: /* Change window property PROP to VALUE on the X window of FRAME.
3170 VALUE may be a string or a list of conses, numbers and/or strings.
3171 If an element in the list is a string, it is converted to
3172 an Atom and the value of the Atom is used. If an element is a cons,
3173 it is converted to a 32 bit number where the car is the 16 top bits and the
3174 cdr is the lower 16 bits.
3175 FRAME nil or omitted means use the selected frame.
3176 If TYPE is given and non-nil, it is the name of the type of VALUE.
3177 If TYPE is not given or nil, the type is STRING.
3178 FORMAT gives the size in bits of each element if VALUE is a list.
3179 It must be one of 8, 16 or 32.
3180 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
3181 If OUTER_P is non-nil, the property is changed for the outer X window of
3182 FRAME. Default is to change on the edit X window.
3184 Value is VALUE. */)
3185 (prop, value, frame, type, format, outer_p)
3186 Lisp_Object prop, value, frame, type, format, outer_p;
3188 #if 0 /* MAC_TODO : port window properties to Mac */
3189 struct frame *f = check_x_frame (frame);
3190 Atom prop_atom;
3192 CHECK_STRING (prop);
3193 CHECK_STRING (value);
3195 BLOCK_INPUT;
3196 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3197 XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3198 prop_atom, XA_STRING, 8, PropModeReplace,
3199 SDATA (value), SCHARS (value));
3201 /* Make sure the property is set when we return. */
3202 XFlush (FRAME_W32_DISPLAY (f));
3203 UNBLOCK_INPUT;
3205 #endif /* MAC_TODO */
3207 return value;
3211 DEFUN ("x-delete-window-property", Fx_delete_window_property,
3212 Sx_delete_window_property, 1, 2, 0,
3213 doc: /* Remove window property PROP from X window of FRAME.
3214 FRAME nil or omitted means use the selected frame. Value is PROP. */)
3215 (prop, frame)
3216 Lisp_Object prop, frame;
3218 #if 0 /* MAC_TODO : port window properties to Mac */
3220 struct frame *f = check_x_frame (frame);
3221 Atom prop_atom;
3223 CHECK_STRING (prop);
3224 BLOCK_INPUT;
3225 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3226 XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
3228 /* Make sure the property is removed when we return. */
3229 XFlush (FRAME_W32_DISPLAY (f));
3230 UNBLOCK_INPUT;
3231 #endif /* MAC_TODO */
3233 return prop;
3237 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
3238 1, 2, 0,
3239 doc: /* Value is the value of window property PROP on FRAME.
3240 If FRAME is nil or omitted, use the selected frame. Value is nil
3241 if FRAME hasn't a property with name PROP or if PROP has no string
3242 value. */)
3243 (prop, frame)
3244 Lisp_Object prop, frame;
3246 #if 0 /* MAC_TODO : port window properties to Mac */
3248 struct frame *f = check_x_frame (frame);
3249 Atom prop_atom;
3250 int rc;
3251 Lisp_Object prop_value = Qnil;
3252 char *tmp_data = NULL;
3253 Atom actual_type;
3254 int actual_format;
3255 unsigned long actual_size, bytes_remaining;
3257 CHECK_STRING (prop);
3258 BLOCK_INPUT;
3259 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3260 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3261 prop_atom, 0, 0, False, XA_STRING,
3262 &actual_type, &actual_format, &actual_size,
3263 &bytes_remaining, (unsigned char **) &tmp_data);
3264 if (rc == Success)
3266 int size = bytes_remaining;
3268 XFree (tmp_data);
3269 tmp_data = NULL;
3271 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3272 prop_atom, 0, bytes_remaining,
3273 False, XA_STRING,
3274 &actual_type, &actual_format,
3275 &actual_size, &bytes_remaining,
3276 (unsigned char **) &tmp_data);
3277 if (rc == Success)
3278 prop_value = make_string (tmp_data, size);
3280 XFree (tmp_data);
3283 UNBLOCK_INPUT;
3285 return prop_value;
3287 #endif /* MAC_TODO */
3288 return Qnil;
3293 /***********************************************************************
3294 Busy cursor
3295 ***********************************************************************/
3297 /* If non-null, an asynchronous timer that, when it expires, displays
3298 an hourglass cursor on all frames. */
3300 static struct atimer *hourglass_atimer;
3302 /* Non-zero means an hourglass cursor is currently shown. */
3304 static int hourglass_shown_p;
3306 /* Number of seconds to wait before displaying an hourglass cursor. */
3308 static Lisp_Object Vhourglass_delay;
3310 /* Default number of seconds to wait before displaying an hourglass
3311 cursor. */
3313 #define DEFAULT_HOURGLASS_DELAY 1
3315 /* Function prototypes. */
3317 static void show_hourglass P_ ((struct atimer *));
3318 static void hide_hourglass P_ ((void));
3320 /* Return non-zero if houglass timer has been started or hourglass is shown. */
3323 hourglass_started ()
3325 return hourglass_shown_p || hourglass_atimer != NULL;
3329 /* Cancel a currently active hourglass timer, and start a new one. */
3331 void
3332 start_hourglass ()
3334 #ifdef MAC_OSX
3335 EMACS_TIME delay;
3336 int secs, usecs = 0;
3338 cancel_hourglass ();
3340 if (INTEGERP (Vhourglass_delay)
3341 && XINT (Vhourglass_delay) > 0)
3342 secs = XFASTINT (Vhourglass_delay);
3343 else if (FLOATP (Vhourglass_delay)
3344 && XFLOAT_DATA (Vhourglass_delay) > 0)
3346 Lisp_Object tem;
3347 tem = Ftruncate (Vhourglass_delay, Qnil);
3348 secs = XFASTINT (tem);
3349 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
3351 else
3352 secs = DEFAULT_HOURGLASS_DELAY;
3354 EMACS_SET_SECS_USECS (delay, secs, usecs);
3355 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
3356 show_hourglass, NULL);
3357 #endif /* MAC_OSX */
3361 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
3362 shown. */
3364 void
3365 cancel_hourglass ()
3367 #ifdef MAC_OSX
3368 if (hourglass_atimer)
3370 cancel_atimer (hourglass_atimer);
3371 hourglass_atimer = NULL;
3374 if (hourglass_shown_p)
3375 hide_hourglass ();
3376 #endif /* MAC_OSX */
3380 /* Timer function of hourglass_atimer. TIMER is equal to
3381 hourglass_atimer.
3383 On Mac, busy status is shown by the progress indicator (chasing
3384 arrows) at the upper-right corner of each frame instead of the
3385 hourglass pointer. */
3387 static void
3388 show_hourglass (timer)
3389 struct atimer *timer;
3391 #if TARGET_API_MAC_CARBON
3392 /* The timer implementation will cancel this timer automatically
3393 after this function has run. Set hourglass_atimer to null
3394 so that we know the timer doesn't have to be canceled. */
3395 hourglass_atimer = NULL;
3397 if (!hourglass_shown_p)
3399 Lisp_Object rest, frame;
3401 BLOCK_INPUT;
3403 FOR_EACH_FRAME (rest, frame)
3405 struct frame *f = XFRAME (frame);
3407 if (FRAME_LIVE_P (f) && FRAME_MAC_P (f)
3408 && FRAME_MAC_WINDOW (f) != tip_window)
3410 if (!f->output_data.mac->hourglass_control)
3412 Window w = FRAME_MAC_WINDOW (f);
3413 Rect r;
3414 ControlRef c;
3416 GetWindowPortBounds (w, &r);
3417 r.left = r.right - HOURGLASS_WIDTH;
3418 r.bottom = r.top + HOURGLASS_HEIGHT;
3419 if (CreateChasingArrowsControl (w, &r, &c) == noErr)
3420 f->output_data.mac->hourglass_control = c;
3423 if (f->output_data.mac->hourglass_control)
3424 ShowControl (f->output_data.mac->hourglass_control);
3428 hourglass_shown_p = 1;
3429 UNBLOCK_INPUT;
3431 #endif /* TARGET_API_MAC_CARBON */
3435 /* Hide the progress indicators on all frames, if it is currently
3436 shown. */
3438 static void
3439 hide_hourglass ()
3441 #if TARGET_API_MAC_CARBON
3442 if (hourglass_shown_p)
3444 Lisp_Object rest, frame;
3446 BLOCK_INPUT;
3447 FOR_EACH_FRAME (rest, frame)
3449 struct frame *f = XFRAME (frame);
3451 if (FRAME_MAC_P (f)
3452 /* Watch out for newly created frames. */
3453 && f->output_data.mac->hourglass_control)
3454 HideControl (f->output_data.mac->hourglass_control);
3457 hourglass_shown_p = 0;
3458 UNBLOCK_INPUT;
3460 #endif /* TARGET_API_MAC_CARBON */
3465 /***********************************************************************
3466 Tool tips
3467 ***********************************************************************/
3469 static Lisp_Object x_create_tip_frame P_ ((struct mac_display_info *,
3470 Lisp_Object, Lisp_Object));
3471 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
3472 Lisp_Object, int, int, int *, int *));
3474 /* The frame of a currently visible tooltip. */
3476 Lisp_Object tip_frame;
3478 /* If non-nil, a timer started that hides the last tooltip when it
3479 fires. */
3481 Lisp_Object tip_timer;
3482 Window tip_window;
3484 /* If non-nil, a vector of 3 elements containing the last args
3485 with which x-show-tip was called. See there. */
3487 Lisp_Object last_show_tip_args;
3489 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
3491 Lisp_Object Vx_max_tooltip_size;
3494 static Lisp_Object
3495 unwind_create_tip_frame (frame)
3496 Lisp_Object frame;
3498 Lisp_Object deleted;
3500 deleted = unwind_create_frame (frame);
3501 if (EQ (deleted, Qt))
3503 tip_window = NULL;
3504 tip_frame = Qnil;
3507 return deleted;
3511 /* Create a frame for a tooltip on the display described by DPYINFO.
3512 PARMS is a list of frame parameters. TEXT is the string to
3513 display in the tip frame. Value is the frame.
3515 Note that functions called here, esp. x_default_parameter can
3516 signal errors, for instance when a specified color name is
3517 undefined. We have to make sure that we're in a consistent state
3518 when this happens. */
3520 static Lisp_Object
3521 x_create_tip_frame (dpyinfo, parms, text)
3522 struct mac_display_info *dpyinfo;
3523 Lisp_Object parms, text;
3525 struct frame *f;
3526 Lisp_Object frame, tem;
3527 Lisp_Object name;
3528 long window_prompting = 0;
3529 int width, height;
3530 int count = SPECPDL_INDEX ();
3531 struct gcpro gcpro1, gcpro2, gcpro3;
3532 struct kboard *kb;
3533 int face_change_count_before = face_change_count;
3534 Lisp_Object buffer;
3535 struct buffer *old_buffer;
3537 check_mac ();
3540 #ifdef MULTI_KBOARD
3541 kb = dpyinfo->kboard;
3542 #else
3543 kb = &the_only_kboard;
3544 #endif
3546 /* Get the name of the frame to use for resource lookup. */
3547 name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
3548 if (!STRINGP (name)
3549 && !EQ (name, Qunbound)
3550 && !NILP (name))
3551 error ("Invalid frame name--not a string or nil");
3553 frame = Qnil;
3554 GCPRO3 (parms, name, frame);
3555 f = make_frame (1);
3556 XSETFRAME (frame, f);
3558 buffer = Fget_buffer_create (build_string (" *tip*"));
3559 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
3560 old_buffer = current_buffer;
3561 set_buffer_internal_1 (XBUFFER (buffer));
3562 current_buffer->truncate_lines = Qnil;
3563 specbind (Qinhibit_read_only, Qt);
3564 specbind (Qinhibit_modification_hooks, Qt);
3565 Ferase_buffer ();
3566 Finsert (1, &text);
3567 set_buffer_internal_1 (old_buffer);
3569 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
3570 record_unwind_protect (unwind_create_tip_frame, frame);
3572 /* By setting the output method, we're essentially saying that
3573 the frame is live, as per FRAME_LIVE_P. If we get a signal
3574 from this point on, x_destroy_window might screw up reference
3575 counts etc. */
3576 f->output_method = output_mac;
3577 f->output_data.mac =
3578 (struct mac_output *) xmalloc (sizeof (struct mac_output));
3579 bzero (f->output_data.mac, sizeof (struct mac_output));
3581 FRAME_FONTSET (f) = -1;
3582 f->icon_name = Qnil;
3584 #if 0 /* GLYPH_DEBUG TODO: image support. */
3585 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
3586 dpyinfo_refcount = dpyinfo->reference_count;
3587 #endif /* GLYPH_DEBUG */
3588 #ifdef MULTI_KBOARD
3589 FRAME_KBOARD (f) = kb;
3590 #endif
3591 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
3592 f->output_data.mac->explicit_parent = 0;
3594 /* Set the name; the functions to which we pass f expect the name to
3595 be set. */
3596 if (EQ (name, Qunbound) || NILP (name))
3598 f->name = build_string (dpyinfo->mac_id_name);
3599 f->explicit_name = 0;
3601 else
3603 f->name = name;
3604 f->explicit_name = 1;
3605 /* use the frame's title when getting resources for this frame. */
3606 specbind (Qx_resource_name, name);
3609 /* Extract the window parameters from the supplied values that are
3610 needed to determine window geometry. */
3612 Lisp_Object font;
3614 font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
3616 BLOCK_INPUT;
3617 /* First, try whatever font the caller has specified. */
3618 if (STRINGP (font))
3620 tem = Fquery_fontset (font, Qnil);
3621 if (STRINGP (tem))
3622 font = x_new_fontset (f, SDATA (tem));
3623 else
3624 font = x_new_font (f, SDATA (font));
3627 /* Try out a font which we hope has bold and italic variations. */
3628 if (! STRINGP (font))
3629 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
3630 /* If those didn't work, look for something which will at least work. */
3631 if (! STRINGP (font))
3632 font = x_new_fontset (f, "fontset-mac");
3633 if (! STRINGP (font))
3634 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
3635 if (! STRINGP (font))
3636 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
3637 UNBLOCK_INPUT;
3638 if (! STRINGP (font))
3639 error ("Cannot find any usable font");
3641 x_default_parameter (f, parms, Qfont, font,
3642 "font", "Font", RES_TYPE_STRING);
3645 x_default_parameter (f, parms, Qborder_width, make_number (2),
3646 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3648 /* This defaults to 2 in order to match xterm. We recognize either
3649 internalBorderWidth or internalBorder (which is what xterm calls
3650 it). */
3651 if (NILP (Fassq (Qinternal_border_width, parms)))
3653 Lisp_Object value;
3655 value = mac_get_arg (parms, Qinternal_border_width,
3656 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3657 if (! EQ (value, Qunbound))
3658 parms = Fcons (Fcons (Qinternal_border_width, value),
3659 parms);
3662 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
3663 "internalBorderWidth", "internalBorderWidth",
3664 RES_TYPE_NUMBER);
3666 /* Also do the stuff which must be set before the window exists. */
3667 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3668 "foreground", "Foreground", RES_TYPE_STRING);
3669 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3670 "background", "Background", RES_TYPE_STRING);
3671 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3672 "pointerColor", "Foreground", RES_TYPE_STRING);
3673 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3674 "cursorColor", "Foreground", RES_TYPE_STRING);
3675 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3676 "borderColor", "BorderColor", RES_TYPE_STRING);
3678 /* Init faces before x_default_parameter is called for scroll-bar
3679 parameters because that function calls x_set_scroll_bar_width,
3680 which calls change_frame_size, which calls Fset_window_buffer,
3681 which runs hooks, which call Fvertical_motion. At the end, we
3682 end up in init_iterator with a null face cache, which should not
3683 happen. */
3684 init_frame_faces (f);
3686 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
3688 window_prompting = x_figure_window_size (f, parms, 0);
3691 Rect r;
3693 BLOCK_INPUT;
3694 SetRect (&r, 0, 0, 1, 1);
3695 #if TARGET_API_MAC_CARBON
3696 if (CreateNewWindow (kHelpWindowClass,
3697 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
3698 kWindowIgnoreClicksAttribute |
3699 #endif
3700 kWindowNoUpdatesAttribute |
3701 kWindowNoActivatesAttribute,
3702 &r, &tip_window) == noErr)
3703 #else
3704 if (tip_window = NewCWindow (NULL, &r, "\p", false, plainDBox,
3705 NULL, false, 0L))
3706 #endif
3708 FRAME_MAC_WINDOW (f) = tip_window;
3709 XSetWindowBackground (FRAME_MAC_DISPLAY(f), tip_window,
3710 FRAME_BACKGROUND_PIXEL (f));
3711 SetWRefCon (tip_window, (long) f->output_data.mac);
3712 /* so that update events can find this mac_output struct */
3713 f->output_data.mac->mFP = f;
3715 UNBLOCK_INPUT;
3718 x_make_gc (f);
3720 x_default_parameter (f, parms, Qauto_raise, Qnil,
3721 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3722 x_default_parameter (f, parms, Qauto_lower, Qnil,
3723 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3724 x_default_parameter (f, parms, Qcursor_type, Qbox,
3725 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3727 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3728 Change will not be effected unless different from the current
3729 FRAME_LINES (f). */
3730 width = FRAME_COLS (f);
3731 height = FRAME_LINES (f);
3732 SET_FRAME_COLS (f, 0);
3733 FRAME_LINES (f) = 0;
3734 change_frame_size (f, height, width, 1, 0, 0);
3736 /* Add `tooltip' frame parameter's default value. */
3737 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
3738 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
3739 Qnil));
3741 /* Set up faces after all frame parameters are known. This call
3742 also merges in face attributes specified for new frames.
3744 Frame parameters may be changed if .Xdefaults contains
3745 specifications for the default font. For example, if there is an
3746 `Emacs.default.attributeBackground: pink', the `background-color'
3747 attribute of the frame get's set, which let's the internal border
3748 of the tooltip frame appear in pink. Prevent this. */
3750 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
3752 /* Set tip_frame here, so that */
3753 tip_frame = frame;
3754 call1 (Qface_set_after_frame_default, frame);
3756 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
3757 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
3758 Qnil));
3761 f->no_split = 1;
3763 UNGCPRO;
3765 /* It is now ok to make the frame official even if we get an error
3766 below. And the frame needs to be on Vframe_list or making it
3767 visible won't work. */
3768 Vframe_list = Fcons (frame, Vframe_list);
3770 /* Now that the frame is official, it counts as a reference to
3771 its display. */
3772 FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
3774 /* Setting attributes of faces of the tooltip frame from resources
3775 and similar will increment face_change_count, which leads to the
3776 clearing of all current matrices. Since this isn't necessary
3777 here, avoid it by resetting face_change_count to the value it
3778 had before we created the tip frame. */
3779 face_change_count = face_change_count_before;
3781 /* Discard the unwind_protect. */
3782 return unbind_to (count, frame);
3786 /* Compute where to display tip frame F. PARMS is the list of frame
3787 parameters for F. DX and DY are specified offsets from the current
3788 location of the mouse. WIDTH and HEIGHT are the width and height
3789 of the tooltip. Return coordinates relative to the root window of
3790 the display in *ROOT_X, and *ROOT_Y. */
3792 static void
3793 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
3794 struct frame *f;
3795 Lisp_Object parms, dx, dy;
3796 int width, height;
3797 int *root_x, *root_y;
3799 Lisp_Object left, top;
3801 /* User-specified position? */
3802 left = Fcdr (Fassq (Qleft, parms));
3803 top = Fcdr (Fassq (Qtop, parms));
3805 /* Move the tooltip window where the mouse pointer is. Resize and
3806 show it. */
3807 if (!INTEGERP (left) || !INTEGERP (top))
3809 Point mouse_pos;
3811 BLOCK_INPUT;
3812 GetMouse (&mouse_pos);
3813 LocalToGlobal (&mouse_pos);
3814 *root_x = mouse_pos.h;
3815 *root_y = mouse_pos.v;
3816 UNBLOCK_INPUT;
3819 if (INTEGERP (top))
3820 *root_y = XINT (top);
3821 else if (*root_y + XINT (dy) - height < 0)
3822 *root_y -= XINT (dy);
3823 else
3825 *root_y -= height;
3826 *root_y += XINT (dy);
3829 if (INTEGERP (left))
3830 *root_x = XINT (left);
3831 else if (*root_x + XINT (dx) + width <= FRAME_MAC_DISPLAY_INFO (f)->width)
3832 /* It fits to the right of the pointer. */
3833 *root_x += XINT (dx);
3834 else if (width + XINT (dx) <= *root_x)
3835 /* It fits to the left of the pointer. */
3836 *root_x -= width + XINT (dx);
3837 else
3838 /* Put it left-justified on the screen -- it ought to fit that way. */
3839 *root_x = 0;
3843 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
3844 doc: /* Show STRING in a "tooltip" window on frame FRAME.
3845 A tooltip window is a small window displaying a string.
3847 FRAME nil or omitted means use the selected frame.
3849 PARMS is an optional list of frame parameters which can be used to
3850 change the tooltip's appearance.
3852 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
3853 means use the default timeout of 5 seconds.
3855 If the list of frame parameters PARMS contains a `left' parameter,
3856 the tooltip is displayed at that x-position. Otherwise it is
3857 displayed at the mouse position, with offset DX added (default is 5 if
3858 DX isn't specified). Likewise for the y-position; if a `top' frame
3859 parameter is specified, it determines the y-position of the tooltip
3860 window, otherwise it is displayed at the mouse position, with offset
3861 DY added (default is -10).
3863 A tooltip's maximum size is specified by `x-max-tooltip-size'.
3864 Text larger than the specified size is clipped. */)
3865 (string, frame, parms, timeout, dx, dy)
3866 Lisp_Object string, frame, parms, timeout, dx, dy;
3868 struct frame *f;
3869 struct window *w;
3870 int root_x, root_y;
3871 struct buffer *old_buffer;
3872 struct text_pos pos;
3873 int i, width, height;
3874 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3875 int old_windows_or_buffers_changed = windows_or_buffers_changed;
3876 int count = SPECPDL_INDEX ();
3878 specbind (Qinhibit_redisplay, Qt);
3880 GCPRO4 (string, parms, frame, timeout);
3882 CHECK_STRING (string);
3883 f = check_x_frame (frame);
3884 if (NILP (timeout))
3885 timeout = make_number (5);
3886 else
3887 CHECK_NATNUM (timeout);
3889 if (NILP (dx))
3890 dx = make_number (5);
3891 else
3892 CHECK_NUMBER (dx);
3894 if (NILP (dy))
3895 dy = make_number (-10);
3896 else
3897 CHECK_NUMBER (dy);
3899 if (NILP (last_show_tip_args))
3900 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
3902 if (!NILP (tip_frame))
3904 Lisp_Object last_string = AREF (last_show_tip_args, 0);
3905 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
3906 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
3908 if (EQ (frame, last_frame)
3909 && !NILP (Fequal (last_string, string))
3910 && !NILP (Fequal (last_parms, parms)))
3912 struct frame *f = XFRAME (tip_frame);
3914 /* Only DX and DY have changed. */
3915 if (!NILP (tip_timer))
3917 Lisp_Object timer = tip_timer;
3918 tip_timer = Qnil;
3919 call1 (Qcancel_timer, timer);
3922 BLOCK_INPUT;
3923 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
3924 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
3925 MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
3926 UNBLOCK_INPUT;
3927 goto start_timer;
3931 /* Hide a previous tip, if any. */
3932 Fx_hide_tip ();
3934 ASET (last_show_tip_args, 0, string);
3935 ASET (last_show_tip_args, 1, frame);
3936 ASET (last_show_tip_args, 2, parms);
3938 /* Add default values to frame parameters. */
3939 if (NILP (Fassq (Qname, parms)))
3940 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
3941 if (NILP (Fassq (Qinternal_border_width, parms)))
3942 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
3943 if (NILP (Fassq (Qborder_width, parms)))
3944 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
3945 if (NILP (Fassq (Qborder_color, parms)))
3946 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
3947 if (NILP (Fassq (Qbackground_color, parms)))
3948 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
3949 parms);
3951 /* Create a frame for the tooltip, and record it in the global
3952 variable tip_frame. */
3953 frame = x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f), parms, string);
3954 f = XFRAME (frame);
3956 /* Set up the frame's root window. */
3957 w = XWINDOW (FRAME_ROOT_WINDOW (f));
3958 w->left_col = w->top_line = make_number (0);
3960 if (CONSP (Vx_max_tooltip_size)
3961 && INTEGERP (XCAR (Vx_max_tooltip_size))
3962 && XINT (XCAR (Vx_max_tooltip_size)) > 0
3963 && INTEGERP (XCDR (Vx_max_tooltip_size))
3964 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
3966 w->total_cols = XCAR (Vx_max_tooltip_size);
3967 w->total_lines = XCDR (Vx_max_tooltip_size);
3969 else
3971 w->total_cols = make_number (80);
3972 w->total_lines = make_number (40);
3975 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
3976 adjust_glyphs (f);
3977 w->pseudo_window_p = 1;
3979 /* Display the tooltip text in a temporary buffer. */
3980 old_buffer = current_buffer;
3981 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
3982 current_buffer->truncate_lines = Qnil;
3983 clear_glyph_matrix (w->desired_matrix);
3984 clear_glyph_matrix (w->current_matrix);
3985 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
3986 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
3988 /* Compute width and height of the tooltip. */
3989 width = height = 0;
3990 for (i = 0; i < w->desired_matrix->nrows; ++i)
3992 struct glyph_row *row = &w->desired_matrix->rows[i];
3993 struct glyph *last;
3994 int row_width;
3996 /* Stop at the first empty row at the end. */
3997 if (!row->enabled_p || !row->displays_text_p)
3998 break;
4000 /* Let the row go over the full width of the frame. */
4001 row->full_width_p = 1;
4003 /* There's a glyph at the end of rows that is used to place
4004 the cursor there. Don't include the width of this glyph. */
4005 if (row->used[TEXT_AREA])
4007 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
4008 row_width = row->pixel_width - last->pixel_width;
4010 else
4011 row_width = row->pixel_width;
4013 height += row->height;
4014 width = max (width, row_width);
4017 /* Add the frame's internal border to the width and height the X
4018 window should have. */
4019 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4020 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4022 /* Move the tooltip window where the mouse pointer is. Resize and
4023 show it. */
4024 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
4026 BLOCK_INPUT;
4027 MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
4028 SizeWindow (FRAME_MAC_WINDOW (f), width, height, true);
4029 ShowWindow (FRAME_MAC_WINDOW (f));
4030 BringToFront (FRAME_MAC_WINDOW (f));
4031 UNBLOCK_INPUT;
4033 /* Draw into the window. */
4034 w->must_be_updated_p = 1;
4035 update_single_window (w, 1);
4037 /* Restore original current buffer. */
4038 set_buffer_internal_1 (old_buffer);
4039 windows_or_buffers_changed = old_windows_or_buffers_changed;
4041 start_timer:
4042 /* Let the tip disappear after timeout seconds. */
4043 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
4044 intern ("x-hide-tip"));
4046 UNGCPRO;
4047 return unbind_to (count, Qnil);
4051 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
4052 doc: /* Hide the current tooltip window, if there is any.
4053 Value is t if tooltip was open, nil otherwise. */)
4056 int count;
4057 Lisp_Object deleted, frame, timer;
4058 struct gcpro gcpro1, gcpro2;
4060 /* Return quickly if nothing to do. */
4061 if (NILP (tip_timer) && NILP (tip_frame))
4062 return Qnil;
4064 frame = tip_frame;
4065 timer = tip_timer;
4066 GCPRO2 (frame, timer);
4067 tip_frame = tip_timer = deleted = Qnil;
4069 count = SPECPDL_INDEX ();
4070 specbind (Qinhibit_redisplay, Qt);
4071 specbind (Qinhibit_quit, Qt);
4073 if (!NILP (timer))
4074 call1 (Qcancel_timer, timer);
4076 if (FRAMEP (frame))
4078 Fdelete_frame (frame, Qnil);
4079 deleted = Qt;
4082 UNGCPRO;
4083 return unbind_to (count, deleted);
4088 #if TARGET_API_MAC_CARBON
4089 /***********************************************************************
4090 File selection dialog
4091 ***********************************************************************/
4093 static pascal void mac_nav_event_callback P_ ((NavEventCallbackMessage,
4094 NavCBRecPtr, void *));
4097 There is a relatively standard way to do this using applescript to run
4098 a (choose file) method. However, this doesn't do "the right thing"
4099 by working only if the find-file occurred during a menu or toolbar
4100 click. So we must do the file dialog by hand, using the navigation
4101 manager. This also has more flexibility in determining the default
4102 directory and whether or not we are going to choose a file.
4105 extern Lisp_Object Qfile_name_history;
4107 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
4108 doc: /* Read file name, prompting with PROMPT in directory DIR.
4109 Use a file selection dialog.
4110 Select DEFAULT-FILENAME in the dialog's file selection box, if
4111 specified. Ensure that file exists if MUSTMATCH is non-nil.
4112 If ONLY-DIR-P is non-nil, the user can only select directories. */)
4113 (prompt, dir, default_filename, mustmatch, only_dir_p)
4114 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
4116 struct frame *f = SELECTED_FRAME ();
4117 Lisp_Object file = Qnil;
4118 int count = SPECPDL_INDEX ();
4119 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
4120 char filename[MAXPATHLEN];
4121 int default_filter_index = 1; /* 1: All Files, 2: Directories only */
4122 static NavEventUPP mac_nav_event_callbackUPP = NULL;
4124 GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p);
4125 CHECK_STRING (prompt);
4126 CHECK_STRING (dir);
4128 /* Create the dialog with PROMPT as title, using DIR as initial
4129 directory and using "*" as pattern. */
4130 dir = Fexpand_file_name (dir, Qnil);
4133 OSStatus status;
4134 NavDialogCreationOptions options;
4135 NavDialogRef dialogRef;
4136 NavTypeListHandle fileTypes = NULL;
4137 NavUserAction userAction;
4138 CFStringRef message=NULL, saveName = NULL;
4140 BLOCK_INPUT;
4141 /* No need for a callback function because we are modal */
4142 NavGetDefaultDialogCreationOptions(&options);
4143 options.modality = kWindowModalityAppModal;
4144 options.location.h = options.location.v = -1;
4145 options.optionFlags = kNavDefaultNavDlogOptions;
4146 options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */
4147 options.optionFlags |= kNavSelectAllReadableItem;
4148 if (!NILP(prompt))
4150 message = cfstring_create_with_string (prompt);
4151 options.message = message;
4153 /* Don't set the application, let it use default.
4154 options.clientName = CFSTR ("Emacs");
4157 if (mac_nav_event_callbackUPP == NULL)
4158 mac_nav_event_callbackUPP = NewNavEventUPP (mac_nav_event_callback);
4160 if (!NILP (only_dir_p))
4161 status = NavCreateChooseFolderDialog(&options, mac_nav_event_callbackUPP,
4162 NULL, NULL, &dialogRef);
4163 else if (NILP (mustmatch))
4165 /* This is a save dialog */
4166 options.optionFlags |= kNavDontConfirmReplacement;
4167 options.actionButtonLabel = CFSTR ("Ok");
4168 options.windowTitle = CFSTR ("Enter name");
4170 if (STRINGP (default_filename))
4172 Lisp_Object utf8 = ENCODE_UTF_8 (default_filename);
4173 char *begPtr = SDATA(utf8);
4174 char *filePtr = begPtr + SBYTES(utf8);
4175 while (filePtr != begPtr && !IS_DIRECTORY_SEP(filePtr[-1]))
4176 filePtr--;
4177 saveName = cfstring_create_with_utf8_cstring (filePtr);
4178 options.saveFileName = saveName;
4179 options.optionFlags |= kNavSelectDefaultLocation;
4181 status = NavCreatePutFileDialog(&options,
4182 'TEXT', kNavGenericSignature,
4183 mac_nav_event_callbackUPP, NULL,
4184 &dialogRef);
4186 else
4188 /* This is an open dialog*/
4189 status = NavCreateChooseFileDialog(&options, fileTypes,
4190 mac_nav_event_callbackUPP, NULL,
4191 NULL, NULL, &dialogRef);
4194 /* Set the default location and continue*/
4195 if (status == noErr)
4197 AEDesc defLocAed;
4198 #ifdef MAC_OSX
4199 FSRef defLoc;
4200 status = FSPathMakeRef(SDATA(ENCODE_FILE(dir)), &defLoc, NULL);
4201 #else
4202 FSSpec defLoc;
4203 status = posix_pathname_to_fsspec (SDATA (ENCODE_FILE (dir)), &defLoc);
4204 #endif
4205 if (status == noErr)
4207 #ifdef MAC_OSX
4208 AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed);
4209 #else
4210 AECreateDesc(typeFSS, &defLoc, sizeof(FSSpec), &defLocAed);
4211 #endif
4212 NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
4213 AEDisposeDesc(&defLocAed);
4215 status = NavDialogRun(dialogRef);
4218 if (saveName) CFRelease(saveName);
4219 if (message) CFRelease(message);
4221 if (status == noErr) {
4222 userAction = NavDialogGetUserAction(dialogRef);
4223 switch (userAction)
4225 case kNavUserActionNone:
4226 case kNavUserActionCancel:
4227 break; /* Treat cancel like C-g */
4228 case kNavUserActionOpen:
4229 case kNavUserActionChoose:
4230 case kNavUserActionSaveAs:
4232 NavReplyRecord reply;
4233 AEDesc aed;
4234 #ifdef MAC_OSX
4235 FSRef fsRef;
4236 #else
4237 FSSpec fs;
4238 #endif
4239 status = NavDialogGetReply(dialogRef, &reply);
4241 #ifdef MAC_OSX
4242 AECoerceDesc(&reply.selection, typeFSRef, &aed);
4243 AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef));
4244 FSRefMakePath(&fsRef, (UInt8 *) filename, sizeof (filename));
4245 #else
4246 AECoerceDesc (&reply.selection, typeFSS, &aed);
4247 AEGetDescData (&aed, (void *) &fs, sizeof (FSSpec));
4248 fsspec_to_posix_pathname (&fs, filename, sizeof (filename) - 1);
4249 #endif
4250 AEDisposeDesc(&aed);
4251 if (reply.saveFileName)
4253 /* If it was a saved file, we need to add the file name */
4254 int len = strlen(filename);
4255 if (len && filename[len-1] != '/')
4256 filename[len++] = '/';
4257 CFStringGetCString(reply.saveFileName, filename+len,
4258 sizeof (filename) - len,
4259 #if MAC_OSX
4260 kCFStringEncodingUTF8
4261 #else
4262 CFStringGetSystemEncoding ()
4263 #endif
4266 file = DECODE_FILE (make_unibyte_string (filename,
4267 strlen (filename)));
4268 NavDisposeReply(&reply);
4270 break;
4272 NavDialogDispose(dialogRef);
4273 UNBLOCK_INPUT;
4275 else {
4276 UNBLOCK_INPUT;
4277 /* Fall back on minibuffer if there was a problem */
4278 file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
4279 dir, mustmatch, dir, Qfile_name_history,
4280 default_filename, Qnil);
4284 UNGCPRO;
4286 /* Make "Cancel" equivalent to C-g. */
4287 if (NILP (file))
4288 Fsignal (Qquit, Qnil);
4290 return unbind_to (count, file);
4294 /* Need to register some event callback function for enabling drag and
4295 drop in Navigation Service dialogs. */
4296 static pascal void
4297 mac_nav_event_callback (selector, parms, data)
4298 NavEventCallbackMessage selector;
4299 NavCBRecPtr parms;
4300 void *data ;
4303 #endif
4305 /***********************************************************************
4306 Initialization
4307 ***********************************************************************/
4309 /* Keep this list in the same order as frame_parms in frame.c.
4310 Use 0 for unsupported frame parameters. */
4312 frame_parm_handler mac_frame_parm_handlers[] =
4314 x_set_autoraise,
4315 x_set_autolower,
4316 x_set_background_color,
4317 x_set_border_color,
4318 x_set_border_width,
4319 x_set_cursor_color,
4320 x_set_cursor_type,
4321 x_set_font,
4322 x_set_foreground_color,
4323 x_set_icon_name,
4324 0, /* MAC_TODO: x_set_icon_type, */
4325 x_set_internal_border_width,
4326 x_set_menu_bar_lines,
4327 x_set_mouse_color,
4328 x_explicitly_set_name,
4329 x_set_scroll_bar_width,
4330 x_set_title,
4331 x_set_unsplittable,
4332 x_set_vertical_scroll_bars,
4333 x_set_visibility,
4334 x_set_tool_bar_lines,
4335 0, /* MAC_TODO: x_set_scroll_bar_foreground, */
4336 0, /* MAC_TODO: x_set_scroll_bar_background, */
4337 x_set_screen_gamma,
4338 x_set_line_spacing,
4339 x_set_fringe_width,
4340 x_set_fringe_width,
4341 0, /* x_set_wait_for_wm, */
4342 x_set_fullscreen,
4345 void
4346 syms_of_macfns ()
4348 #ifdef MAC_OSX
4349 /* This is zero if not using Mac native windows. */
4350 mac_in_use = 0;
4351 #else
4352 /* Certainly running on Mac native windows. */
4353 mac_in_use = 1;
4354 #endif
4356 /* The section below is built by the lisp expression at the top of the file,
4357 just above where these variables are declared. */
4358 /*&&& init symbols here &&&*/
4359 Qnone = intern ("none");
4360 staticpro (&Qnone);
4361 Qsuppress_icon = intern ("suppress-icon");
4362 staticpro (&Qsuppress_icon);
4363 Qundefined_color = intern ("undefined-color");
4364 staticpro (&Qundefined_color);
4365 Qcancel_timer = intern ("cancel-timer");
4366 staticpro (&Qcancel_timer);
4367 /* This is the end of symbol initialization. */
4369 /* Text property `display' should be nonsticky by default. */
4370 Vtext_property_default_nonsticky
4371 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
4374 Fput (Qundefined_color, Qerror_conditions,
4375 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
4376 Fput (Qundefined_color, Qerror_message,
4377 build_string ("Undefined color"));
4379 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
4380 doc: /* The shape of the pointer when over text.
4381 Changing the value does not affect existing frames
4382 unless you set the mouse color. */);
4383 Vx_pointer_shape = Qnil;
4385 #if 0 /* This doesn't really do anything. */
4386 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
4387 doc: /* The shape of the pointer when not over text.
4388 This variable takes effect when you create a new frame
4389 or when you set the mouse color. */);
4390 #endif
4391 Vx_nontext_pointer_shape = Qnil;
4393 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
4394 doc: /* The shape of the pointer when Emacs is busy.
4395 This variable takes effect when you create a new frame
4396 or when you set the mouse color. */);
4397 Vx_hourglass_pointer_shape = Qnil;
4399 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
4400 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
4401 display_hourglass_p = 1;
4403 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
4404 doc: /* *Seconds to wait before displaying an hourglass pointer.
4405 Value must be an integer or float. */);
4406 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
4408 #if 0 /* This doesn't really do anything. */
4409 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
4410 doc: /* The shape of the pointer when over the mode line.
4411 This variable takes effect when you create a new frame
4412 or when you set the mouse color. */);
4413 #endif
4414 Vx_mode_pointer_shape = Qnil;
4416 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
4417 &Vx_sensitive_text_pointer_shape,
4418 doc: /* The shape of the pointer when over mouse-sensitive text.
4419 This variable takes effect when you create a new frame
4420 or when you set the mouse color. */);
4421 Vx_sensitive_text_pointer_shape = Qnil;
4423 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
4424 &Vx_window_horizontal_drag_shape,
4425 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
4426 This variable takes effect when you create a new frame
4427 or when you set the mouse color. */);
4428 Vx_window_horizontal_drag_shape = Qnil;
4430 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
4431 doc: /* A string indicating the foreground color of the cursor box. */);
4432 Vx_cursor_fore_pixel = Qnil;
4434 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
4435 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
4436 Text larger than this is clipped. */);
4437 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
4439 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
4440 doc: /* Non-nil if no window manager is in use.
4441 Emacs doesn't try to figure this out; this is always nil
4442 unless you set it to something else. */);
4443 /* We don't have any way to find this out, so set it to nil
4444 and maybe the user would like to set it to t. */
4445 Vx_no_window_manager = Qnil;
4447 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
4448 &Vx_pixel_size_width_font_regexp,
4449 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
4451 Since Emacs gets width of a font matching with this regexp from
4452 PIXEL_SIZE field of the name, font finding mechanism gets faster for
4453 such a font. This is especially effective for such large fonts as
4454 Chinese, Japanese, and Korean. */);
4455 Vx_pixel_size_width_font_regexp = Qnil;
4457 /* X window properties. */
4458 defsubr (&Sx_change_window_property);
4459 defsubr (&Sx_delete_window_property);
4460 defsubr (&Sx_window_property);
4462 defsubr (&Sxw_display_color_p);
4463 defsubr (&Sx_display_grayscale_p);
4464 defsubr (&Sxw_color_defined_p);
4465 defsubr (&Sxw_color_values);
4466 defsubr (&Sx_server_max_request_size);
4467 defsubr (&Sx_server_vendor);
4468 defsubr (&Sx_server_version);
4469 defsubr (&Sx_display_pixel_width);
4470 defsubr (&Sx_display_pixel_height);
4471 defsubr (&Sx_display_mm_width);
4472 defsubr (&Sx_display_mm_height);
4473 defsubr (&Sx_display_screens);
4474 defsubr (&Sx_display_planes);
4475 defsubr (&Sx_display_color_cells);
4476 defsubr (&Sx_display_visual_class);
4477 defsubr (&Sx_display_backing_store);
4478 defsubr (&Sx_display_save_under);
4479 defsubr (&Sx_create_frame);
4480 defsubr (&Sx_open_connection);
4481 defsubr (&Sx_close_connection);
4482 defsubr (&Sx_display_list);
4483 defsubr (&Sx_synchronize);
4485 /* Setting callback functions for fontset handler. */
4486 get_font_info_func = x_get_font_info;
4488 #if 0 /* This function pointer doesn't seem to be used anywhere.
4489 And the pointer assigned has the wrong type, anyway. */
4490 list_fonts_func = x_list_fonts;
4491 #endif
4493 load_font_func = x_load_font;
4494 find_ccl_program_func = x_find_ccl_program;
4495 query_font_func = x_query_font;
4496 set_frame_fontset_func = x_set_font;
4497 check_window_system_func = check_mac;
4499 hourglass_atimer = NULL;
4500 hourglass_shown_p = 0;
4502 defsubr (&Sx_show_tip);
4503 defsubr (&Sx_hide_tip);
4504 tip_timer = Qnil;
4505 staticpro (&tip_timer);
4506 tip_frame = Qnil;
4507 staticpro (&tip_frame);
4509 last_show_tip_args = Qnil;
4510 staticpro (&last_show_tip_args);
4512 #if TARGET_API_MAC_CARBON
4513 defsubr (&Sx_file_dialog);
4514 #endif
4517 /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc
4518 (do not change this comment) */