(locate-dominating-file): Accept non-existing argument.
[emacs.git] / src / macfns.c
blob56320684a8688eb20ca835692b6b5a2e8501f681
1 /* Graphical user interface functions for Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3 2008 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 /* Contributed by Andrew Choi (akochoi@mac.com). */
22 #include <config.h>
23 #include <stdio.h>
24 #include <math.h>
26 #include "lisp.h"
27 #include "macterm.h"
28 #include "frame.h"
29 #include "window.h"
30 #include "buffer.h"
31 #include "intervals.h"
32 #include "dispextern.h"
33 #include "keyboard.h"
34 #include "blockinput.h"
35 #include <epaths.h>
36 #include "charset.h"
37 #include "coding.h"
38 #include "fontset.h"
39 #include "systime.h"
40 #include "termhooks.h"
41 #include "atimer.h"
43 #include <ctype.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <limits.h>
47 #include <errno.h>
48 #include <sys/param.h>
50 extern void free_frame_menubar ();
52 #if TARGET_API_MAC_CARBON
54 /* Carbon version info */
56 static Lisp_Object Vmac_carbon_version_string;
58 #endif /* TARGET_API_MAC_CARBON */
60 /* Non-zero means we're allowed to display an hourglass cursor. */
62 int display_hourglass_p;
64 /* The background and shape of the mouse pointer, and shape when not
65 over text or in the modeline. */
67 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
68 Lisp_Object Vx_hourglass_pointer_shape;
70 /* The shape when over mouse-sensitive text. */
72 Lisp_Object Vx_sensitive_text_pointer_shape;
74 /* If non-nil, the pointer shape to indicate that windows can be
75 dragged horizontally. */
77 Lisp_Object Vx_window_horizontal_drag_shape;
79 /* Color of chars displayed in cursor box. */
81 Lisp_Object Vx_cursor_fore_pixel;
83 /* Nonzero if using Windows. */
85 static int mac_in_use;
87 /* Non nil if no window manager is in use. */
89 Lisp_Object Vx_no_window_manager;
91 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
93 Lisp_Object Vx_pixel_size_width_font_regexp;
95 Lisp_Object Qnone;
96 Lisp_Object Qsuppress_icon;
97 Lisp_Object Qundefined_color;
98 Lisp_Object Qcancel_timer;
100 /* In dispnew.c */
102 extern Lisp_Object Vwindow_system_version;
104 #if GLYPH_DEBUG
105 int image_cache_refcount, dpyinfo_refcount;
106 #endif
108 #if 0 /* Use xstricmp instead. */
109 /* compare two strings ignoring case */
111 static int
112 stricmp (const char *s, const char *t)
114 for ( ; tolower (*s) == tolower (*t); s++, t++)
115 if (*s == '\0')
116 return 0;
117 return tolower (*s) - tolower (*t);
119 #endif
121 /* compare two strings up to n characters, ignoring case */
123 static int
124 strnicmp (const char *s, const char *t, unsigned int n)
126 for ( ; n > 0 && tolower (*s) == tolower (*t); n--, s++, t++)
127 if (*s == '\0')
128 return 0;
129 return n == 0 ? 0 : tolower (*s) - tolower (*t);
133 /* Error if we are not running on Mac OS. */
135 void
136 check_mac ()
138 if (! mac_in_use)
139 error ("Mac native windows not in use or not initialized");
142 /* Nonzero if we can use mouse menus.
143 You should not call this unless HAVE_MENUS is defined. */
146 have_menus_p ()
148 return mac_in_use;
151 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
152 and checking validity for Mac. */
154 FRAME_PTR
155 check_x_frame (frame)
156 Lisp_Object frame;
158 FRAME_PTR f;
160 if (NILP (frame))
161 frame = selected_frame;
162 CHECK_LIVE_FRAME (frame);
163 f = XFRAME (frame);
164 if (! FRAME_MAC_P (f))
165 error ("Non-Mac frame used");
166 return f;
169 /* Let the user specify a display with a frame.
170 nil stands for the selected frame--or, if that is not a mac frame,
171 the first display on the list. */
173 struct mac_display_info *
174 check_x_display_info (frame)
175 Lisp_Object frame;
177 struct mac_display_info *dpyinfo = NULL;
179 if (NILP (frame))
181 struct frame *sf = XFRAME (selected_frame);
183 if (FRAME_MAC_P (sf) && FRAME_LIVE_P (sf))
184 dpyinfo = FRAME_MAC_DISPLAY_INFO (sf);
185 else if (x_display_list != 0)
186 dpyinfo = x_display_list;
187 else
188 error ("Mac native windows are not in use or not initialized");
190 else if (STRINGP (frame))
191 dpyinfo = x_display_info_for_name (frame);
192 else
194 FRAME_PTR f = check_x_frame (frame);
195 dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
198 return dpyinfo;
203 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
204 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
206 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
207 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
208 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
209 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
210 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
211 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
212 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
213 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
214 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
215 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
216 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
217 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
220 /* Store the screen positions of frame F into XPTR and YPTR.
221 These are the positions of the containing window manager window,
222 not Emacs's own window. */
224 void
225 x_real_positions (f, xptr, yptr)
226 FRAME_PTR f;
227 int *xptr, *yptr;
229 Rect inner, outer;
231 mac_get_window_bounds (f, &inner, &outer);
233 f->x_pixels_diff = inner.left - outer.left;
234 f->y_pixels_diff = inner.top - outer.top;
236 *xptr = outer.left;
237 *yptr = outer.top;
241 /* The default colors for the Mac color map */
242 typedef struct colormap_t
244 unsigned long color;
245 char *name;
246 } colormap_t;
248 static const colormap_t mac_color_map[] =
250 { RGB_TO_ULONG(255, 250, 250), "snow" },
251 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
252 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
253 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
254 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
255 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
256 { RGB_TO_ULONG(255, 250, 240), "floral white" },
257 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
258 { RGB_TO_ULONG(253, 245, 230), "old lace" },
259 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
260 { RGB_TO_ULONG(250, 240, 230), "linen" },
261 { RGB_TO_ULONG(250, 235, 215), "antique white" },
262 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
263 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
264 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
265 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
266 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
267 { RGB_TO_ULONG(255, 228, 196), "bisque" },
268 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
269 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
270 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
271 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
272 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
273 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
274 { RGB_TO_ULONG(255, 255, 240), "ivory" },
275 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
276 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
277 { RGB_TO_ULONG(255, 245, 238), "seashell" },
278 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
279 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
280 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
281 { RGB_TO_ULONG(240, 255, 255), "azure" },
282 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
283 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
284 { RGB_TO_ULONG(230, 230, 250), "lavender" },
285 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
286 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
287 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
288 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
289 { RGB_TO_ULONG(255, 255, 255), "white" },
290 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
291 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
292 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
293 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
294 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
295 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
296 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
297 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
298 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
299 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
300 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
301 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
302 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
303 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
304 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
305 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
306 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
307 { RGB_TO_ULONG(190, 190, 190), "gray" },
308 { RGB_TO_ULONG(190, 190, 190), "grey" },
309 { RGB_TO_ULONG(211, 211, 211), "light grey" },
310 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
311 { RGB_TO_ULONG(211, 211, 211), "light gray" },
312 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
313 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
314 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
315 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
316 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
317 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
318 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
319 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
320 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
321 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
322 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
323 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
324 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
325 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
326 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
327 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
328 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
329 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
330 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
331 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
332 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
333 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
334 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
335 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
336 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
337 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
338 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
339 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
340 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
341 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
342 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
343 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
344 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
345 { RGB_TO_ULONG(173, 216, 230), "light blue" },
346 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
347 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
348 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
349 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
350 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
351 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
352 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
353 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
354 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
355 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
356 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
357 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
358 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
359 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
360 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
361 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
362 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
363 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
364 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
365 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
366 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
367 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
368 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
369 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
370 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
371 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
372 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
373 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
374 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
375 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
376 { RGB_TO_ULONG(152, 251, 152), "pale green" },
377 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
378 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
379 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
380 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
381 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
382 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
383 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
384 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
385 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
386 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
387 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
388 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
389 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
390 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
391 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
392 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
393 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
394 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
395 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
396 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
397 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
398 { RGB_TO_ULONG(240, 230, 140), "khaki" },
399 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
400 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
401 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
402 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
403 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
404 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
405 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
406 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
407 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
408 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
409 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
410 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
411 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
412 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
413 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
414 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
415 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
416 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
417 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
418 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
419 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
420 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
421 { RGB_TO_ULONG(245, 245, 220), "beige" },
422 { RGB_TO_ULONG(245, 222, 179), "wheat" },
423 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
424 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
425 { RGB_TO_ULONG(210, 180, 140), "tan" },
426 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
427 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
428 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
429 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
430 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
431 { RGB_TO_ULONG(250, 128, 114), "salmon" },
432 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
433 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
434 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
435 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
436 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
437 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
438 { RGB_TO_ULONG(240, 128, 128), "light coral" },
439 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
440 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
441 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
442 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
443 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
444 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
445 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
446 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
447 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
448 { RGB_TO_ULONG(255, 192, 203), "pink" },
449 { RGB_TO_ULONG(255, 182, 193), "light pink" },
450 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
451 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
452 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
453 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
454 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
455 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
456 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
457 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
458 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
459 { RGB_TO_ULONG(238, 130, 238), "violet" },
460 { RGB_TO_ULONG(221, 160, 221), "plum" },
461 { RGB_TO_ULONG(218, 112, 214), "orchid" },
462 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
463 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
464 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
465 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
466 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
467 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
468 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
469 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
470 { RGB_TO_ULONG(160, 32 , 240), "purple" },
471 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
472 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
473 { RGB_TO_ULONG(216, 191, 216), "thistle" },
474 { RGB_TO_ULONG(255, 250, 250), "snow1" },
475 { RGB_TO_ULONG(238, 233, 233), "snow2" },
476 { RGB_TO_ULONG(205, 201, 201), "snow3" },
477 { RGB_TO_ULONG(139, 137, 137), "snow4" },
478 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
479 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
480 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
481 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
482 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
483 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
484 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
485 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
486 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
487 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
488 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
489 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
490 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
491 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
492 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
493 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
494 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
495 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
496 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
497 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
498 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
499 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
500 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
501 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
502 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
503 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
504 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
505 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
506 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
507 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
508 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
509 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
510 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
511 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
512 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
513 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
514 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
515 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
516 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
517 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
518 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
519 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
520 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
521 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
522 { RGB_TO_ULONG(240, 255, 255), "azure1" },
523 { RGB_TO_ULONG(224, 238, 238), "azure2" },
524 { RGB_TO_ULONG(193, 205, 205), "azure3" },
525 { RGB_TO_ULONG(131, 139, 139), "azure4" },
526 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
527 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
528 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
529 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
530 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
531 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
532 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
533 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
534 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
535 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
536 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
537 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
538 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
539 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
540 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
541 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
542 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
543 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
544 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
545 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
546 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
547 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
548 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
549 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
550 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
551 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
552 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
553 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
554 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
555 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
556 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
557 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
558 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
559 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
560 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
561 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
562 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
563 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
564 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
565 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
566 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
567 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
568 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
569 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
570 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
571 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
572 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
573 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
574 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
575 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
576 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
577 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
578 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
579 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
580 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
581 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
582 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
583 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
584 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
585 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
586 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
587 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
588 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
589 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
590 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
591 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
592 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
593 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
594 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
595 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
596 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
597 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
598 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
599 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
600 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
601 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
602 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
603 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
604 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
605 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
606 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
607 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
608 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
609 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
610 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
611 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
612 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
613 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
614 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
615 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
616 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
617 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
618 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
619 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
620 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
621 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
622 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
623 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
624 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
625 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
626 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
627 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
628 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
629 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
630 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
631 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
632 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
633 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
634 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
635 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
636 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
637 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
638 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
639 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
640 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
641 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
642 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
643 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
644 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
645 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
646 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
647 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
648 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
649 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
650 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
651 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
652 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
653 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
654 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
655 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
656 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
657 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
658 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
659 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
660 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
661 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
662 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
663 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
664 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
665 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
666 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
667 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
668 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
669 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
670 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
671 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
672 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
673 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
674 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
675 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
676 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
677 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
678 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
679 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
680 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
681 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
682 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
683 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
684 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
685 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
686 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
687 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
688 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
689 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
690 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
691 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
692 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
693 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
694 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
695 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
696 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
697 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
698 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
699 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
700 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
701 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
702 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
703 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
704 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
705 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
706 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
707 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
708 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
709 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
710 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
711 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
712 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
713 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
714 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
715 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
716 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
717 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
718 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
719 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
720 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
721 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
722 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
723 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
724 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
725 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
726 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
727 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
728 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
729 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
730 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
731 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
732 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
733 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
734 { RGB_TO_ULONG(255, 181, 197), "pink1" },
735 { RGB_TO_ULONG(238, 169, 184), "pink2" },
736 { RGB_TO_ULONG(205, 145, 158), "pink3" },
737 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
738 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
739 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
740 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
741 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
742 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
743 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
744 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
745 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
746 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
747 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
748 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
749 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
750 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
751 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
752 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
753 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
754 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
755 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
756 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
757 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
758 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
759 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
760 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
761 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
762 { RGB_TO_ULONG(255, 187, 255), "plum1" },
763 { RGB_TO_ULONG(238, 174, 238), "plum2" },
764 { RGB_TO_ULONG(205, 150, 205), "plum3" },
765 { RGB_TO_ULONG(139, 102, 139), "plum4" },
766 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
767 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
768 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
769 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
770 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
771 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
772 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
773 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
774 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
775 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
776 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
777 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
778 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
779 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
780 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
781 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
782 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
783 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
784 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
785 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
786 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
787 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
788 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
789 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
790 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
791 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
792 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
793 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
794 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
795 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
796 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
797 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
798 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
799 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
800 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
801 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
802 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
803 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
804 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
805 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
806 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
807 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
808 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
809 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
810 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
811 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
812 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
813 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
814 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
815 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
816 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
817 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
818 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
819 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
820 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
821 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
822 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
823 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
824 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
825 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
826 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
827 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
828 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
829 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
830 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
831 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
832 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
833 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
834 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
835 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
836 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
837 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
838 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
839 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
840 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
841 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
842 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
843 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
844 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
845 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
846 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
847 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
848 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
849 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
850 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
851 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
852 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
853 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
854 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
855 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
856 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
857 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
858 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
859 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
860 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
861 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
862 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
863 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
864 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
865 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
866 { RGB_TO_ULONG(102, 102, 102), "gray40" },
867 { RGB_TO_ULONG(102, 102, 102), "grey40" },
868 { RGB_TO_ULONG(105, 105, 105), "gray41" },
869 { RGB_TO_ULONG(105, 105, 105), "grey41" },
870 { RGB_TO_ULONG(107, 107, 107), "gray42" },
871 { RGB_TO_ULONG(107, 107, 107), "grey42" },
872 { RGB_TO_ULONG(110, 110, 110), "gray43" },
873 { RGB_TO_ULONG(110, 110, 110), "grey43" },
874 { RGB_TO_ULONG(112, 112, 112), "gray44" },
875 { RGB_TO_ULONG(112, 112, 112), "grey44" },
876 { RGB_TO_ULONG(115, 115, 115), "gray45" },
877 { RGB_TO_ULONG(115, 115, 115), "grey45" },
878 { RGB_TO_ULONG(117, 117, 117), "gray46" },
879 { RGB_TO_ULONG(117, 117, 117), "grey46" },
880 { RGB_TO_ULONG(120, 120, 120), "gray47" },
881 { RGB_TO_ULONG(120, 120, 120), "grey47" },
882 { RGB_TO_ULONG(122, 122, 122), "gray48" },
883 { RGB_TO_ULONG(122, 122, 122), "grey48" },
884 { RGB_TO_ULONG(125, 125, 125), "gray49" },
885 { RGB_TO_ULONG(125, 125, 125), "grey49" },
886 { RGB_TO_ULONG(127, 127, 127), "gray50" },
887 { RGB_TO_ULONG(127, 127, 127), "grey50" },
888 { RGB_TO_ULONG(130, 130, 130), "gray51" },
889 { RGB_TO_ULONG(130, 130, 130), "grey51" },
890 { RGB_TO_ULONG(133, 133, 133), "gray52" },
891 { RGB_TO_ULONG(133, 133, 133), "grey52" },
892 { RGB_TO_ULONG(135, 135, 135), "gray53" },
893 { RGB_TO_ULONG(135, 135, 135), "grey53" },
894 { RGB_TO_ULONG(138, 138, 138), "gray54" },
895 { RGB_TO_ULONG(138, 138, 138), "grey54" },
896 { RGB_TO_ULONG(140, 140, 140), "gray55" },
897 { RGB_TO_ULONG(140, 140, 140), "grey55" },
898 { RGB_TO_ULONG(143, 143, 143), "gray56" },
899 { RGB_TO_ULONG(143, 143, 143), "grey56" },
900 { RGB_TO_ULONG(145, 145, 145), "gray57" },
901 { RGB_TO_ULONG(145, 145, 145), "grey57" },
902 { RGB_TO_ULONG(148, 148, 148), "gray58" },
903 { RGB_TO_ULONG(148, 148, 148), "grey58" },
904 { RGB_TO_ULONG(150, 150, 150), "gray59" },
905 { RGB_TO_ULONG(150, 150, 150), "grey59" },
906 { RGB_TO_ULONG(153, 153, 153), "gray60" },
907 { RGB_TO_ULONG(153, 153, 153), "grey60" },
908 { RGB_TO_ULONG(156, 156, 156), "gray61" },
909 { RGB_TO_ULONG(156, 156, 156), "grey61" },
910 { RGB_TO_ULONG(158, 158, 158), "gray62" },
911 { RGB_TO_ULONG(158, 158, 158), "grey62" },
912 { RGB_TO_ULONG(161, 161, 161), "gray63" },
913 { RGB_TO_ULONG(161, 161, 161), "grey63" },
914 { RGB_TO_ULONG(163, 163, 163), "gray64" },
915 { RGB_TO_ULONG(163, 163, 163), "grey64" },
916 { RGB_TO_ULONG(166, 166, 166), "gray65" },
917 { RGB_TO_ULONG(166, 166, 166), "grey65" },
918 { RGB_TO_ULONG(168, 168, 168), "gray66" },
919 { RGB_TO_ULONG(168, 168, 168), "grey66" },
920 { RGB_TO_ULONG(171, 171, 171), "gray67" },
921 { RGB_TO_ULONG(171, 171, 171), "grey67" },
922 { RGB_TO_ULONG(173, 173, 173), "gray68" },
923 { RGB_TO_ULONG(173, 173, 173), "grey68" },
924 { RGB_TO_ULONG(176, 176, 176), "gray69" },
925 { RGB_TO_ULONG(176, 176, 176), "grey69" },
926 { RGB_TO_ULONG(179, 179, 179), "gray70" },
927 { RGB_TO_ULONG(179, 179, 179), "grey70" },
928 { RGB_TO_ULONG(181, 181, 181), "gray71" },
929 { RGB_TO_ULONG(181, 181, 181), "grey71" },
930 { RGB_TO_ULONG(184, 184, 184), "gray72" },
931 { RGB_TO_ULONG(184, 184, 184), "grey72" },
932 { RGB_TO_ULONG(186, 186, 186), "gray73" },
933 { RGB_TO_ULONG(186, 186, 186), "grey73" },
934 { RGB_TO_ULONG(189, 189, 189), "gray74" },
935 { RGB_TO_ULONG(189, 189, 189), "grey74" },
936 { RGB_TO_ULONG(191, 191, 191), "gray75" },
937 { RGB_TO_ULONG(191, 191, 191), "grey75" },
938 { RGB_TO_ULONG(194, 194, 194), "gray76" },
939 { RGB_TO_ULONG(194, 194, 194), "grey76" },
940 { RGB_TO_ULONG(196, 196, 196), "gray77" },
941 { RGB_TO_ULONG(196, 196, 196), "grey77" },
942 { RGB_TO_ULONG(199, 199, 199), "gray78" },
943 { RGB_TO_ULONG(199, 199, 199), "grey78" },
944 { RGB_TO_ULONG(201, 201, 201), "gray79" },
945 { RGB_TO_ULONG(201, 201, 201), "grey79" },
946 { RGB_TO_ULONG(204, 204, 204), "gray80" },
947 { RGB_TO_ULONG(204, 204, 204), "grey80" },
948 { RGB_TO_ULONG(207, 207, 207), "gray81" },
949 { RGB_TO_ULONG(207, 207, 207), "grey81" },
950 { RGB_TO_ULONG(209, 209, 209), "gray82" },
951 { RGB_TO_ULONG(209, 209, 209), "grey82" },
952 { RGB_TO_ULONG(212, 212, 212), "gray83" },
953 { RGB_TO_ULONG(212, 212, 212), "grey83" },
954 { RGB_TO_ULONG(214, 214, 214), "gray84" },
955 { RGB_TO_ULONG(214, 214, 214), "grey84" },
956 { RGB_TO_ULONG(217, 217, 217), "gray85" },
957 { RGB_TO_ULONG(217, 217, 217), "grey85" },
958 { RGB_TO_ULONG(219, 219, 219), "gray86" },
959 { RGB_TO_ULONG(219, 219, 219), "grey86" },
960 { RGB_TO_ULONG(222, 222, 222), "gray87" },
961 { RGB_TO_ULONG(222, 222, 222), "grey87" },
962 { RGB_TO_ULONG(224, 224, 224), "gray88" },
963 { RGB_TO_ULONG(224, 224, 224), "grey88" },
964 { RGB_TO_ULONG(227, 227, 227), "gray89" },
965 { RGB_TO_ULONG(227, 227, 227), "grey89" },
966 { RGB_TO_ULONG(229, 229, 229), "gray90" },
967 { RGB_TO_ULONG(229, 229, 229), "grey90" },
968 { RGB_TO_ULONG(232, 232, 232), "gray91" },
969 { RGB_TO_ULONG(232, 232, 232), "grey91" },
970 { RGB_TO_ULONG(235, 235, 235), "gray92" },
971 { RGB_TO_ULONG(235, 235, 235), "grey92" },
972 { RGB_TO_ULONG(237, 237, 237), "gray93" },
973 { RGB_TO_ULONG(237, 237, 237), "grey93" },
974 { RGB_TO_ULONG(240, 240, 240), "gray94" },
975 { RGB_TO_ULONG(240, 240, 240), "grey94" },
976 { RGB_TO_ULONG(242, 242, 242), "gray95" },
977 { RGB_TO_ULONG(242, 242, 242), "grey95" },
978 { RGB_TO_ULONG(245, 245, 245), "gray96" },
979 { RGB_TO_ULONG(245, 245, 245), "grey96" },
980 { RGB_TO_ULONG(247, 247, 247), "gray97" },
981 { RGB_TO_ULONG(247, 247, 247), "grey97" },
982 { RGB_TO_ULONG(250, 250, 250), "gray98" },
983 { RGB_TO_ULONG(250, 250, 250), "grey98" },
984 { RGB_TO_ULONG(252, 252, 252), "gray99" },
985 { RGB_TO_ULONG(252, 252, 252), "grey99" },
986 { RGB_TO_ULONG(255, 255, 255), "gray100" },
987 { RGB_TO_ULONG(255, 255, 255), "grey100" },
988 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
989 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
990 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
991 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
992 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
993 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
994 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
995 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
996 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
997 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
998 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
999 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1000 { RGB_TO_ULONG(144, 238, 144), "light green" },
1001 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1004 Lisp_Object
1005 mac_color_map_lookup (colorname)
1006 const char *colorname;
1008 Lisp_Object ret = Qnil;
1009 int i;
1011 BLOCK_INPUT;
1013 for (i = 0; i < sizeof (mac_color_map) / sizeof (mac_color_map[0]); i++)
1014 if (xstricmp (colorname, mac_color_map[i].name) == 0)
1016 ret = make_number (mac_color_map[i].color);
1017 break;
1020 UNBLOCK_INPUT;
1022 return ret;
1025 Lisp_Object
1026 x_to_mac_color (colorname)
1027 char * colorname;
1029 register Lisp_Object ret = Qnil;
1031 BLOCK_INPUT;
1033 if (colorname[0] == '#')
1035 /* Could be an old-style RGB Device specification. */
1036 char *color;
1037 int size;
1038 color = colorname + 1;
1040 size = strlen(color);
1041 if (size == 3 || size == 6 || size == 9 || size == 12)
1043 unsigned long colorval;
1044 int i, pos;
1045 pos = 16;
1046 size /= 3;
1047 colorval = 0;
1049 for (i = 0; i < 3; i++)
1051 char *end;
1052 char t;
1053 unsigned long value;
1055 /* The check for 'x' in the following conditional takes into
1056 account the fact that strtol allows a "0x" in front of
1057 our numbers, and we don't. */
1058 if (!isxdigit(color[0]) || color[1] == 'x')
1059 break;
1060 t = color[size];
1061 color[size] = '\0';
1062 value = strtoul(color, &end, 16);
1063 color[size] = t;
1064 if (errno == ERANGE || end - color != size)
1065 break;
1066 switch (size)
1068 case 1:
1069 value = value * 0x10;
1070 break;
1071 case 2:
1072 break;
1073 case 3:
1074 value /= 0x10;
1075 break;
1076 case 4:
1077 value /= 0x100;
1078 break;
1080 colorval |= (value << pos);
1081 pos -= 8;
1082 if (i == 2)
1084 UNBLOCK_INPUT;
1085 return make_number (colorval);
1087 color = end;
1091 else if (strnicmp(colorname, "rgb:", 4) == 0)
1093 char *color;
1094 unsigned long colorval;
1095 int i, pos;
1096 pos = 16;
1098 colorval = 0;
1099 color = colorname + 4;
1100 for (i = 0; i < 3; i++)
1102 char *end;
1103 unsigned long value;
1105 /* The check for 'x' in the following conditional takes into
1106 account the fact that strtol allows a "0x" in front of
1107 our numbers, and we don't. */
1108 if (!isxdigit(color[0]) || color[1] == 'x')
1109 break;
1110 value = strtoul(color, &end, 16);
1111 if (errno == ERANGE)
1112 break;
1113 switch (end - color)
1115 case 1:
1116 value = value * 0x10 + value;
1117 break;
1118 case 2:
1119 break;
1120 case 3:
1121 value /= 0x10;
1122 break;
1123 case 4:
1124 value /= 0x100;
1125 break;
1126 default:
1127 value = ULONG_MAX;
1129 if (value == ULONG_MAX)
1130 break;
1131 colorval |= (value << pos);
1132 pos -= 0x8;
1133 if (i == 2)
1135 if (*end != '\0')
1136 break;
1137 UNBLOCK_INPUT;
1138 return make_number (colorval);
1140 if (*end != '/')
1141 break;
1142 color = end + 1;
1145 else if (strnicmp(colorname, "rgbi:", 5) == 0)
1147 /* This is an RGB Intensity specification. */
1148 char *color;
1149 unsigned long colorval;
1150 int i, pos;
1151 pos = 16;
1153 colorval = 0;
1154 color = colorname + 5;
1155 for (i = 0; i < 3; i++)
1157 char *end;
1158 double value;
1159 unsigned long val;
1161 value = strtod(color, &end);
1162 if (errno == ERANGE)
1163 break;
1164 if (value < 0.0 || value > 1.0)
1165 break;
1166 val = (unsigned long)(0x100 * value);
1167 /* We used 0x100 instead of 0xFF to give a continuous
1168 range between 0.0 and 1.0 inclusive. The next statement
1169 fixes the 1.0 case. */
1170 if (val == 0x100)
1171 val = 0xFF;
1172 colorval |= (val << pos);
1173 pos -= 0x8;
1174 if (i == 2)
1176 if (*end != '\0')
1177 break;
1178 UNBLOCK_INPUT;
1179 return make_number (colorval);
1181 if (*end != '/')
1182 break;
1183 color = end + 1;
1187 ret = mac_color_map_lookup (colorname);
1189 UNBLOCK_INPUT;
1190 return ret;
1193 /* Gamma-correct COLOR on frame F. */
1195 void
1196 gamma_correct (f, color)
1197 struct frame *f;
1198 unsigned long *color;
1200 if (f->gamma)
1202 unsigned long red, green, blue;
1204 red = pow (RED_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1205 green = pow (GREEN_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1206 blue = pow (BLUE_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1207 *color = RGB_TO_ULONG (red, green, blue);
1211 /* Decide if color named COLOR is valid for the display associated
1212 with the selected frame; if so, return the rgb values in COLOR_DEF.
1213 If ALLOC is nonzero, allocate a new colormap cell. */
1216 mac_defined_color (f, color, color_def, alloc)
1217 FRAME_PTR f;
1218 char *color;
1219 XColor *color_def;
1220 int alloc;
1222 register Lisp_Object tem;
1223 unsigned long mac_color_ref;
1225 tem = x_to_mac_color (color);
1227 if (!NILP (tem))
1229 if (f)
1231 /* Apply gamma correction. */
1232 mac_color_ref = XUINT (tem);
1233 gamma_correct (f, &mac_color_ref);
1234 XSETINT (tem, mac_color_ref);
1237 color_def->pixel = mac_color_ref;
1238 color_def->red = RED16_FROM_ULONG (mac_color_ref);
1239 color_def->green = GREEN16_FROM_ULONG (mac_color_ref);
1240 color_def->blue = BLUE16_FROM_ULONG (mac_color_ref);
1242 return 1;
1244 else
1246 return 0;
1250 /* Given a string ARG naming a color, compute a pixel value from it
1251 suitable for screen F.
1252 If F is not a color screen, return DEF (default) regardless of what
1253 ARG says. */
1256 x_decode_color (f, arg, def)
1257 FRAME_PTR f;
1258 Lisp_Object arg;
1259 int def;
1261 XColor cdef;
1263 CHECK_STRING (arg);
1265 if (strcmp (SDATA (arg), "black") == 0)
1266 return BLACK_PIX_DEFAULT (f);
1267 else if (strcmp (SDATA (arg), "white") == 0)
1268 return WHITE_PIX_DEFAULT (f);
1270 #if 0
1271 if (FRAME_MAC_DISPLAY_INFO (f)->n_planes) == 1)
1272 return def;
1273 #endif
1275 if (mac_defined_color (f, SDATA (arg), &cdef, 1))
1276 return cdef.pixel;
1278 /* defined_color failed; return an ultimate default. */
1279 return def;
1282 /* Functions called only from `x_set_frame_param'
1283 to set individual parameters.
1285 If FRAME_MAC_WINDOW (f) is 0,
1286 the frame is being created and its window does not exist yet.
1287 In that case, just record the parameter's new value
1288 in the standard place; do not attempt to change the window. */
1290 void
1291 x_set_foreground_color (f, arg, oldval)
1292 struct frame *f;
1293 Lisp_Object arg, oldval;
1295 struct mac_output *mac = f->output_data.mac;
1296 unsigned long fg, old_fg;
1298 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1299 old_fg = FRAME_FOREGROUND_PIXEL (f);
1300 FRAME_FOREGROUND_PIXEL (f) = fg;
1302 if (FRAME_MAC_WINDOW (f) != 0)
1304 Display *dpy = FRAME_MAC_DISPLAY (f);
1306 BLOCK_INPUT;
1307 XSetForeground (dpy, mac->normal_gc, fg);
1308 XSetBackground (dpy, mac->reverse_gc, fg);
1310 if (mac->cursor_pixel == old_fg)
1312 unload_color (f, mac->cursor_pixel);
1313 mac->cursor_pixel = fg;
1314 XSetBackground (dpy, mac->cursor_gc, mac->cursor_pixel);
1317 UNBLOCK_INPUT;
1319 update_face_from_frame_parameter (f, Qforeground_color, arg);
1321 if (FRAME_VISIBLE_P (f))
1322 redraw_frame (f);
1325 unload_color (f, old_fg);
1328 void
1329 x_set_background_color (f, arg, oldval)
1330 struct frame *f;
1331 Lisp_Object arg, oldval;
1333 struct mac_output *mac = f->output_data.mac;
1334 unsigned long bg;
1336 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
1337 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
1338 FRAME_BACKGROUND_PIXEL (f) = bg;
1340 if (FRAME_MAC_WINDOW (f) != 0)
1342 Display *dpy = FRAME_MAC_DISPLAY (f);
1344 BLOCK_INPUT;
1345 XSetBackground (dpy, mac->normal_gc, bg);
1346 XSetForeground (dpy, mac->reverse_gc, bg);
1347 mac_set_frame_window_background (f, bg);
1348 XSetForeground (dpy, mac->cursor_gc, bg);
1350 UNBLOCK_INPUT;
1351 update_face_from_frame_parameter (f, Qbackground_color, arg);
1353 if (FRAME_VISIBLE_P (f))
1354 redraw_frame (f);
1358 void
1359 x_set_mouse_color (f, arg, oldval)
1360 struct frame *f;
1361 Lisp_Object arg, oldval;
1363 struct x_output *x = f->output_data.x;
1364 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
1365 Cursor hourglass_cursor, horizontal_drag_cursor;
1366 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1367 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
1369 /* Don't let pointers be invisible. */
1370 if (mask_color == pixel)
1371 pixel = FRAME_FOREGROUND_PIXEL (f);
1373 f->output_data.mac->mouse_pixel = pixel;
1375 if (!NILP (Vx_pointer_shape))
1377 CHECK_NUMBER (Vx_pointer_shape);
1378 cursor = XINT (Vx_pointer_shape);
1380 else
1381 cursor = kThemeIBeamCursor;
1383 if (!NILP (Vx_nontext_pointer_shape))
1385 CHECK_NUMBER (Vx_nontext_pointer_shape);
1386 nontext_cursor = XINT (Vx_nontext_pointer_shape);
1388 else
1389 nontext_cursor = kThemeArrowCursor;
1391 if (!NILP (Vx_hourglass_pointer_shape))
1393 CHECK_NUMBER (Vx_hourglass_pointer_shape);
1394 hourglass_cursor = XINT (Vx_hourglass_pointer_shape);
1396 else
1397 hourglass_cursor = kThemeWatchCursor;
1399 if (!NILP (Vx_mode_pointer_shape))
1401 CHECK_NUMBER (Vx_mode_pointer_shape);
1402 mode_cursor = XINT (Vx_mode_pointer_shape);
1404 else
1405 mode_cursor = kThemeArrowCursor;
1407 if (!NILP (Vx_sensitive_text_pointer_shape))
1409 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1410 hand_cursor = XINT (Vx_sensitive_text_pointer_shape);
1412 else
1413 hand_cursor = kThemePointingHandCursor;
1415 if (!NILP (Vx_window_horizontal_drag_shape))
1417 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1418 horizontal_drag_cursor = XINT (Vx_window_horizontal_drag_shape);
1420 else
1421 horizontal_drag_cursor = kThemeResizeLeftRightCursor;
1423 #if 0 /* MAC_TODO: cursor color changes */
1425 XColor fore_color, back_color;
1427 fore_color.pixel = f->output_data.mac->mouse_pixel;
1428 x_query_color (f, &fore_color);
1429 back_color.pixel = mask_color;
1430 x_query_color (f, &back_color);
1432 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1433 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1434 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1435 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1436 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1437 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1439 #endif
1441 BLOCK_INPUT;
1443 if (FRAME_MAC_WINDOW (f) != 0)
1444 FRAME_TERMINAL (f)->rif->define_frame_cursor (f, cursor);
1446 f->output_data.mac->text_cursor = cursor;
1447 f->output_data.mac->nontext_cursor = nontext_cursor;
1448 f->output_data.mac->hourglass_cursor = hourglass_cursor;
1449 f->output_data.mac->modeline_cursor = mode_cursor;
1450 f->output_data.mac->hand_cursor = hand_cursor;
1451 f->output_data.mac->horizontal_drag_cursor = horizontal_drag_cursor;
1453 UNBLOCK_INPUT;
1455 update_face_from_frame_parameter (f, Qmouse_color, arg);
1458 void
1459 x_set_cursor_color (f, arg, oldval)
1460 struct frame *f;
1461 Lisp_Object arg, oldval;
1463 unsigned long fore_pixel, pixel;
1465 if (!NILP (Vx_cursor_fore_pixel))
1466 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1467 WHITE_PIX_DEFAULT (f));
1468 else
1469 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1471 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1473 /* Make sure that the cursor color differs from the background color. */
1474 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1476 pixel = f->output_data.mac->mouse_pixel;
1477 if (pixel == fore_pixel)
1478 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1481 f->output_data.mac->cursor_foreground_pixel = fore_pixel;
1482 f->output_data.mac->cursor_pixel = pixel;
1484 if (FRAME_MAC_WINDOW (f) != 0)
1486 BLOCK_INPUT;
1487 /* Update frame's cursor_gc. */
1488 XSetBackground (FRAME_MAC_DISPLAY (f),
1489 f->output_data.mac->cursor_gc, pixel);
1490 XSetForeground (FRAME_MAC_DISPLAY (f),
1491 f->output_data.mac->cursor_gc, fore_pixel);
1492 UNBLOCK_INPUT;
1494 if (FRAME_VISIBLE_P (f))
1496 x_update_cursor (f, 0);
1497 x_update_cursor (f, 1);
1501 update_face_from_frame_parameter (f, Qcursor_color, arg);
1504 /* Set the border-color of frame F to pixel value PIX.
1505 Note that this does not fully take effect if done before
1506 F has a window. */
1508 void
1509 x_set_border_pixel (f, pix)
1510 struct frame *f;
1511 int pix;
1514 f->output_data.mac->border_pixel = pix;
1516 if (FRAME_MAC_WINDOW (f) != 0 && f->border_width > 0)
1518 if (FRAME_VISIBLE_P (f))
1519 redraw_frame (f);
1523 /* Set the border-color of frame F to value described by ARG.
1524 ARG can be a string naming a color.
1525 The border-color is used for the border that is drawn by the server.
1526 Note that this does not fully take effect if done before
1527 F has a window; it must be redone when the window is created. */
1529 void
1530 x_set_border_color (f, arg, oldval)
1531 struct frame *f;
1532 Lisp_Object arg, oldval;
1534 int pix;
1536 CHECK_STRING (arg);
1537 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1538 x_set_border_pixel (f, pix);
1539 update_face_from_frame_parameter (f, Qborder_color, arg);
1543 void
1544 x_set_cursor_type (f, arg, oldval)
1545 FRAME_PTR f;
1546 Lisp_Object arg, oldval;
1548 set_frame_cursor_types (f, arg);
1550 /* Make sure the cursor gets redrawn. */
1551 cursor_type_changed = 1;
1554 #if 0 /* MAC_TODO: really no icon for Mac */
1555 void
1556 x_set_icon_type (f, arg, oldval)
1557 struct frame *f;
1558 Lisp_Object arg, oldval;
1560 int result;
1562 if (NILP (arg) && NILP (oldval))
1563 return;
1565 if (STRINGP (arg) && STRINGP (oldval)
1566 && EQ (Fstring_equal (oldval, arg), Qt))
1567 return;
1569 if (SYMBOLP (arg) && SYMBOLP (oldval) && EQ (arg, oldval))
1570 return;
1572 BLOCK_INPUT;
1574 result = x_bitmap_icon (f, arg);
1575 if (result)
1577 UNBLOCK_INPUT;
1578 error ("No icon window available");
1581 UNBLOCK_INPUT;
1583 #endif /* MAC_TODO */
1585 void
1586 x_set_icon_name (f, arg, oldval)
1587 struct frame *f;
1588 Lisp_Object arg, oldval;
1590 int result;
1592 if (STRINGP (arg))
1594 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1595 return;
1597 else if (!NILP (arg) || NILP (oldval))
1598 return;
1600 f->icon_name = arg;
1602 #if 0 /* MAC_TODO */
1603 if (f->output_data.w32->icon_bitmap != 0)
1604 return;
1606 BLOCK_INPUT;
1608 result = x_text_icon (f,
1609 (char *) SDATA ((!NILP (f->icon_name)
1610 ? f->icon_name
1611 : !NILP (f->title)
1612 ? f->title
1613 : f->name)));
1615 if (result)
1617 UNBLOCK_INPUT;
1618 error ("No icon window available");
1621 /* If the window was unmapped (and its icon was mapped),
1622 the new icon is not mapped, so map the window in its stead. */
1623 if (FRAME_VISIBLE_P (f))
1625 #ifdef USE_X_TOOLKIT
1626 XtPopup (f->output_data.w32->widget, XtGrabNone);
1627 #endif
1628 XMapWindow (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f));
1631 XFlush (FRAME_W32_DISPLAY (f));
1632 UNBLOCK_INPUT;
1633 #endif /* MAC_TODO */
1637 void
1638 x_set_menu_bar_lines (f, value, oldval)
1639 struct frame *f;
1640 Lisp_Object value, oldval;
1642 /* Make sure we redisplay all windows in this frame. */
1643 windows_or_buffers_changed++;
1645 FRAME_MENU_BAR_LINES (f) = 0;
1646 /* The menu bar is always shown. */
1647 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1648 if (FRAME_MAC_P (f) && f->output_data.mac->menubar_widget == 0)
1649 /* Make sure next redisplay shows the menu bar. */
1650 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1651 adjust_glyphs (f);
1655 /* Set the number of lines used for the tool bar of frame F to VALUE.
1656 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1657 is the old number of tool bar lines. This function changes the
1658 height of all windows on frame F to match the new tool bar height.
1659 The frame's height doesn't change. */
1661 void
1662 x_set_tool_bar_lines (f, value, oldval)
1663 struct frame *f;
1664 Lisp_Object value, oldval;
1666 int delta, nlines, root_height;
1667 Lisp_Object root_window;
1669 /* Treat tool bars like menu bars. */
1670 if (FRAME_MINIBUF_ONLY_P (f))
1671 return;
1673 /* Use VALUE only if an integer >= 0. */
1674 if (INTEGERP (value) && XINT (value) >= 0)
1675 nlines = XFASTINT (value);
1676 else
1677 nlines = 0;
1679 /* Make sure we redisplay all windows in this frame. */
1680 ++windows_or_buffers_changed;
1682 #if USE_MAC_TOOLBAR
1683 FRAME_TOOL_BAR_LINES (f) = 0;
1684 if (nlines)
1686 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1687 if (FRAME_MAC_P (f)
1688 && !mac_is_window_toolbar_visible (FRAME_MAC_WINDOW (f)))
1689 /* Make sure next redisplay shows the tool bar. */
1690 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1692 else
1694 if (FRAME_EXTERNAL_TOOL_BAR (f))
1695 free_frame_tool_bar (f);
1696 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1699 return;
1700 #endif
1702 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1704 /* Don't resize the tool-bar to more than we have room for. */
1705 root_window = FRAME_ROOT_WINDOW (f);
1706 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1707 if (root_height - delta < 1)
1709 delta = root_height - 1;
1710 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1713 FRAME_TOOL_BAR_LINES (f) = nlines;
1714 change_window_heights (root_window, delta);
1715 adjust_glyphs (f);
1717 /* We also have to make sure that the internal border at the top of
1718 the frame, below the menu bar or tool bar, is redrawn when the
1719 tool bar disappears. This is so because the internal border is
1720 below the tool bar if one is displayed, but is below the menu bar
1721 if there isn't a tool bar. The tool bar draws into the area
1722 below the menu bar. */
1723 if (FRAME_MAC_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1725 clear_frame (f);
1726 clear_current_matrices (f);
1729 /* If the tool bar gets smaller, the internal border below it
1730 has to be cleared. It was formerly part of the display
1731 of the larger tool bar, and updating windows won't clear it. */
1732 if (delta < 0)
1734 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1735 int width = FRAME_PIXEL_WIDTH (f);
1736 int y = nlines * FRAME_LINE_HEIGHT (f);
1738 BLOCK_INPUT;
1739 mac_clear_area (f, 0, y, width, height);
1740 UNBLOCK_INPUT;
1742 if (WINDOWP (f->tool_bar_window))
1743 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1749 /* Set the Mac window title to NAME for frame F. */
1751 static void
1752 x_set_name_internal (f, name)
1753 FRAME_PTR f;
1754 Lisp_Object name;
1756 if (FRAME_MAC_WINDOW (f))
1758 if (STRING_MULTIBYTE (name))
1759 #if TARGET_API_MAC_CARBON
1760 name = ENCODE_UTF_8 (name);
1761 #else
1762 name = ENCODE_SYSTEM (name);
1763 #endif
1765 BLOCK_INPUT;
1768 #if TARGET_API_MAC_CARBON
1769 CFStringRef windowTitle =
1770 cfstring_create_with_utf8_cstring (SDATA (name));
1772 mac_set_window_title (FRAME_MAC_WINDOW (f), windowTitle);
1773 CFRelease (windowTitle);
1774 #else
1775 Str255 windowTitle;
1776 if (strlen (SDATA (name)) < 255)
1778 strcpy (windowTitle, SDATA (name));
1779 c2pstr (windowTitle);
1780 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
1782 #endif
1785 UNBLOCK_INPUT;
1789 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1790 mac_id_name.
1792 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1793 name; if NAME is a string, set F's name to NAME and set
1794 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1796 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1797 suggesting a new name, which lisp code should override; if
1798 F->explicit_name is set, ignore the new name; otherwise, set it. */
1800 void
1801 x_set_name (f, name, explicit)
1802 struct frame *f;
1803 Lisp_Object name;
1804 int explicit;
1806 /* Make sure that requests from lisp code override requests from
1807 Emacs redisplay code. */
1808 if (explicit)
1810 /* If we're switching from explicit to implicit, we had better
1811 update the mode lines and thereby update the title. */
1812 if (f->explicit_name && NILP (name))
1813 update_mode_lines = 1;
1815 f->explicit_name = ! NILP (name);
1817 else if (f->explicit_name)
1818 return;
1820 /* If NAME is nil, set the name to the mac_id_name. */
1821 if (NILP (name))
1823 /* Check for no change needed in this very common case
1824 before we do any consing. */
1825 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name,
1826 SDATA (f->name)))
1827 return;
1828 name = build_string (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name);
1830 else
1831 CHECK_STRING (name);
1833 /* Don't change the name if it's already NAME. */
1834 if (! NILP (Fstring_equal (name, f->name)))
1835 return;
1837 f->name = name;
1839 /* For setting the frame title, the title parameter should override
1840 the name parameter. */
1841 if (! NILP (f->title))
1842 name = f->title;
1844 x_set_name_internal (f, name);
1847 /* This function should be called when the user's lisp code has
1848 specified a name for the frame; the name will override any set by the
1849 redisplay code. */
1850 void
1851 x_explicitly_set_name (f, arg, oldval)
1852 FRAME_PTR f;
1853 Lisp_Object arg, oldval;
1855 x_set_name (f, arg, 1);
1858 /* This function should be called by Emacs redisplay code to set the
1859 name; names set this way will never override names set by the user's
1860 lisp code. */
1861 void
1862 x_implicitly_set_name (f, arg, oldval)
1863 FRAME_PTR f;
1864 Lisp_Object arg, oldval;
1866 x_set_name (f, arg, 0);
1869 /* Change the title of frame F to NAME.
1870 If NAME is nil, use the frame name as the title. */
1872 void
1873 x_set_title (f, name, old_name)
1874 struct frame *f;
1875 Lisp_Object name, old_name;
1877 /* Don't change the title if it's already NAME. */
1878 if (EQ (name, f->title))
1879 return;
1881 update_mode_lines = 1;
1883 f->title = name;
1885 if (NILP (name))
1886 name = f->name;
1887 else
1888 CHECK_STRING (name);
1890 x_set_name_internal (f, name);
1893 void
1894 x_set_scroll_bar_default_width (f)
1895 struct frame *f;
1897 /* Imitate X without X Toolkit */
1899 int wid = FRAME_COLUMN_WIDTH (f);
1901 #ifdef MAC_OSX
1902 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH;
1903 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
1904 wid - 1) / wid;
1905 #else /* not MAC_OSX */
1906 /* Make the actual width at least 14 pixels and a multiple of a
1907 character width. */
1908 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1910 /* Use all of that space (aside from required margins) for the
1911 scroll bar. */
1912 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1913 #endif /* not MAC_OSX */
1916 static void
1917 mac_set_font (f, arg, oldval)
1918 struct frame *f;
1919 Lisp_Object arg, oldval;
1921 x_set_font (f, arg, oldval);
1922 #if USE_MAC_FONT_PANEL
1924 Lisp_Object focus_frame = x_get_focus_frame (f);
1926 if ((NILP (focus_frame) && f == SELECTED_FRAME ())
1927 || XFRAME (focus_frame) == f)
1929 BLOCK_INPUT;
1930 mac_set_font_info_for_selection (f, DEFAULT_FACE_ID, 0);
1931 UNBLOCK_INPUT;
1934 #endif
1937 void
1938 mac_update_title_bar (f, save_match_data)
1939 struct frame *f;
1940 int save_match_data;
1942 #if TARGET_API_MAC_CARBON
1943 struct window *w;
1944 int modified_p;
1946 if (!FRAME_MAC_P (f))
1947 return;
1949 w = XWINDOW (FRAME_SELECTED_WINDOW (f));
1950 modified_p = (BUF_SAVE_MODIFF (XBUFFER (w->buffer))
1951 < BUF_MODIFF (XBUFFER (w->buffer)));
1952 if (windows_or_buffers_changed
1953 /* Minibuffer modification status shown in the close button is
1954 confusing. */
1955 || (!MINI_WINDOW_P (w)
1956 && (modified_p != !NILP (w->last_had_star))))
1958 BLOCK_INPUT;
1959 mac_set_window_modified (FRAME_MAC_WINDOW (f),
1960 !MINI_WINDOW_P (w) && modified_p);
1961 mac_update_proxy_icon (f);
1962 UNBLOCK_INPUT;
1964 #endif
1968 /* Subroutines of creating a frame. */
1970 /* Retrieve the string resource specified by NAME with CLASS from
1971 database RDB.
1973 The return value points to the contents of a Lisp string. So it
1974 will not be valid after the next GC where string compaction will
1975 occur. */
1977 char *
1978 x_get_string_resource (rdb, name, class)
1979 XrmDatabase rdb;
1980 char *name, *class;
1982 Lisp_Object value = xrm_get_resource (rdb, name, class);
1984 if (STRINGP (value))
1985 return SDATA (value);
1986 else
1987 return NULL;
1990 /* Return the value of parameter PARAM.
1992 First search ALIST, then Vdefault_frame_alist, then the X defaults
1993 database, using ATTRIBUTE as the attribute name and CLASS as its class.
1995 Convert the resource to the type specified by desired_type.
1997 If no default is specified, return Qunbound. If you call
1998 mac_get_arg, make sure you deal with Qunbound in a reasonable way,
1999 and don't let it get stored in any Lisp-visible variables! */
2001 static Lisp_Object
2002 mac_get_arg (alist, param, attribute, class, type)
2003 Lisp_Object alist, param;
2004 char *attribute;
2005 char *class;
2006 enum resource_types type;
2008 return x_get_arg (check_x_display_info (Qnil),
2009 alist, param, attribute, class, type);
2013 /* XParseGeometry copied from w32xfns.c */
2016 * XParseGeometry parses strings of the form
2017 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
2018 * width, height, xoffset, and yoffset are unsigned integers.
2019 * Example: "=80x24+300-49"
2020 * The equal sign is optional.
2021 * It returns a bitmask that indicates which of the four values
2022 * were actually found in the string. For each value found,
2023 * the corresponding argument is updated; for each value
2024 * not found, the corresponding argument is left unchanged.
2027 static int
2028 read_integer (string, NextString)
2029 register char *string;
2030 char **NextString;
2032 register int Result = 0;
2033 int Sign = 1;
2035 if (*string == '+')
2036 string++;
2037 else if (*string == '-')
2039 string++;
2040 Sign = -1;
2042 for (; (*string >= '0') && (*string <= '9'); string++)
2044 Result = (Result * 10) + (*string - '0');
2046 *NextString = string;
2047 if (Sign >= 0)
2048 return (Result);
2049 else
2050 return (-Result);
2054 XParseGeometry (string, x, y, width, height)
2055 char *string;
2056 int *x, *y;
2057 unsigned int *width, *height; /* RETURN */
2059 int mask = NoValue;
2060 register char *strind;
2061 unsigned int tempWidth, tempHeight;
2062 int tempX, tempY;
2063 char *nextCharacter;
2065 if ((string == NULL) || (*string == '\0')) return (mask);
2066 if (*string == '=')
2067 string++; /* ignore possible '=' at beg of geometry spec */
2069 strind = (char *)string;
2070 if (*strind != '+' && *strind != '-' && *strind != 'x')
2072 tempWidth = read_integer (strind, &nextCharacter);
2073 if (strind == nextCharacter)
2074 return (0);
2075 strind = nextCharacter;
2076 mask |= WidthValue;
2079 if (*strind == 'x' || *strind == 'X')
2081 strind++;
2082 tempHeight = read_integer (strind, &nextCharacter);
2083 if (strind == nextCharacter)
2084 return (0);
2085 strind = nextCharacter;
2086 mask |= HeightValue;
2089 if ((*strind == '+') || (*strind == '-'))
2091 if (*strind == '-')
2093 strind++;
2094 tempX = -read_integer (strind, &nextCharacter);
2095 if (strind == nextCharacter)
2096 return (0);
2097 strind = nextCharacter;
2098 mask |= XNegative;
2101 else
2103 strind++;
2104 tempX = read_integer (strind, &nextCharacter);
2105 if (strind == nextCharacter)
2106 return (0);
2107 strind = nextCharacter;
2109 mask |= XValue;
2110 if ((*strind == '+') || (*strind == '-'))
2112 if (*strind == '-')
2114 strind++;
2115 tempY = -read_integer (strind, &nextCharacter);
2116 if (strind == nextCharacter)
2117 return (0);
2118 strind = nextCharacter;
2119 mask |= YNegative;
2122 else
2124 strind++;
2125 tempY = read_integer (strind, &nextCharacter);
2126 if (strind == nextCharacter)
2127 return (0);
2128 strind = nextCharacter;
2130 mask |= YValue;
2134 /* If strind isn't at the end of the string the it's an invalid
2135 geometry specification. */
2137 if (*strind != '\0') return (0);
2139 if (mask & XValue)
2140 *x = tempX;
2141 if (mask & YValue)
2142 *y = tempY;
2143 if (mask & WidthValue)
2144 *width = tempWidth;
2145 if (mask & HeightValue)
2146 *height = tempHeight;
2147 return (mask);
2151 /* Create and set up the Mac window for frame F. */
2153 static void
2154 mac_window (f)
2155 struct frame *f;
2157 BLOCK_INPUT;
2159 mac_create_frame_window (f, 0);
2161 if (FRAME_MAC_WINDOW (f))
2162 mac_set_frame_window_background (f, FRAME_BACKGROUND_PIXEL (f));
2164 #if USE_MAC_TOOLBAR
2165 /* At the moment, the size of the tool bar is not yet known. We
2166 record the gravity value of the newly created window and use it
2167 to adjust the position of the window (especially for a negative
2168 specification of its vertical position) when the tool bar is
2169 first redisplayed. */
2170 if (FRAME_EXTERNAL_TOOL_BAR (f))
2171 f->output_data.mac->toolbar_win_gravity = f->win_gravity;
2172 #endif
2174 validate_x_resource_name ();
2176 /* x_set_name normally ignores requests to set the name if the
2177 requested name is the same as the current name. This is the one
2178 place where that assumption isn't correct; f->name is set, but
2179 the server hasn't been told. */
2181 Lisp_Object name;
2182 int explicit = f->explicit_name;
2184 f->explicit_name = 0;
2185 name = f->name;
2186 f->name = Qnil;
2187 x_set_name (f, name, explicit);
2190 UNBLOCK_INPUT;
2192 if (FRAME_MAC_WINDOW (f) == 0)
2193 error ("Unable to create window");
2196 /* Handle the icon stuff for this window. Perhaps later we might
2197 want an x_set_icon_position which can be called interactively as
2198 well. */
2200 static void
2201 x_icon (f, parms)
2202 struct frame *f;
2203 Lisp_Object parms;
2205 Lisp_Object icon_x, icon_y;
2207 /* Set the position of the icon. Note that Windows 95 groups all
2208 icons in the tray. */
2209 icon_x = mac_get_arg (parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2210 icon_y = mac_get_arg (parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2211 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2213 CHECK_NUMBER (icon_x);
2214 CHECK_NUMBER (icon_y);
2216 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2217 error ("Both left and top icon corners of icon must be specified");
2219 BLOCK_INPUT;
2221 if (! EQ (icon_x, Qunbound))
2222 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2224 #if 0 /* TODO */
2225 /* Start up iconic or window? */
2226 x_wm_set_window_state
2227 (f, (EQ (w32_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL), Qicon)
2228 ? IconicState
2229 : NormalState));
2231 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2232 ? f->icon_name
2233 : f->name)));
2234 #endif
2236 UNBLOCK_INPUT;
2240 void
2241 x_make_gc (f)
2242 struct frame *f;
2244 XGCValues gc_values;
2246 BLOCK_INPUT;
2248 /* Create the GCs of this frame.
2249 Note that many default values are used. */
2251 /* Normal video */
2252 gc_values.font = FRAME_FONT (f);
2253 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2254 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2255 f->output_data.mac->normal_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2256 FRAME_MAC_WINDOW (f),
2257 GCFont | GCForeground | GCBackground,
2258 &gc_values);
2260 /* Reverse video style. */
2261 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2262 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2263 f->output_data.mac->reverse_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2264 FRAME_MAC_WINDOW (f),
2265 GCFont | GCForeground | GCBackground,
2266 &gc_values);
2268 /* Cursor has cursor-color background, background-color foreground. */
2269 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2270 gc_values.background = f->output_data.mac->cursor_pixel;
2271 f->output_data.mac->cursor_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2272 FRAME_MAC_WINDOW (f),
2273 GCFont | GCForeground | GCBackground,
2274 &gc_values);
2276 /* Reliefs. */
2277 f->output_data.mac->white_relief.gc = 0;
2278 f->output_data.mac->black_relief.gc = 0;
2280 #if 0
2281 /* Create the gray border tile used when the pointer is not in
2282 the frame. Since this depends on the frame's pixel values,
2283 this must be done on a per-frame basis. */
2284 f->output_data.x->border_tile
2285 = (XCreatePixmapFromBitmapData
2286 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2287 gray_bits, gray_width, gray_height,
2288 FRAME_FOREGROUND_PIXEL (f),
2289 FRAME_BACKGROUND_PIXEL (f),
2290 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2291 #endif
2293 UNBLOCK_INPUT;
2297 /* Free what was was allocated in x_make_gc. */
2299 void
2300 x_free_gcs (f)
2301 struct frame *f;
2303 Display *dpy = FRAME_MAC_DISPLAY (f);
2305 BLOCK_INPUT;
2307 if (f->output_data.mac->normal_gc)
2309 XFreeGC (dpy, f->output_data.mac->normal_gc);
2310 f->output_data.mac->normal_gc = 0;
2313 if (f->output_data.mac->reverse_gc)
2315 XFreeGC (dpy, f->output_data.mac->reverse_gc);
2316 f->output_data.mac->reverse_gc = 0;
2319 if (f->output_data.mac->cursor_gc)
2321 XFreeGC (dpy, f->output_data.mac->cursor_gc);
2322 f->output_data.mac->cursor_gc = 0;
2325 #if 0
2326 if (f->output_data.mac->border_tile)
2328 XFreePixmap (dpy, f->output_data.mac->border_tile);
2329 f->output_data.mac->border_tile = 0;
2331 #endif
2333 if (f->output_data.mac->white_relief.gc)
2335 XFreeGC (dpy, f->output_data.mac->white_relief.gc);
2336 f->output_data.mac->white_relief.gc = 0;
2339 if (f->output_data.mac->black_relief.gc)
2341 XFreeGC (dpy, f->output_data.mac->black_relief.gc);
2342 f->output_data.mac->black_relief.gc = 0;
2345 UNBLOCK_INPUT;
2349 /* Handler for signals raised during x_create_frame and
2350 x_create_top_frame. FRAME is the frame which is partially
2351 constructed. */
2353 static Lisp_Object
2354 unwind_create_frame (frame)
2355 Lisp_Object frame;
2357 struct frame *f = XFRAME (frame);
2359 /* If frame is ``official'', nothing to do. */
2360 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
2362 #if GLYPH_DEBUG
2363 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2364 #endif
2366 x_free_frame_resources (f);
2368 #if GLYPH_DEBUG
2369 /* Check that reference counts are indeed correct. */
2370 xassert (dpyinfo->reference_count == dpyinfo_refcount);
2371 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
2372 #endif
2373 return Qt;
2376 return Qnil;
2380 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2381 1, 1, 0,
2382 doc: /* Make a new window, which is called a "frame" in Emacs terms.
2383 Return an Emacs frame object.
2384 PARAMETERS is an alist of frame parameters.
2385 If the parameters specify that the frame should not have a minibuffer,
2386 and do not specify a specific minibuffer window to use,
2387 then `default-minibuffer-frame' must be a frame whose minibuffer can
2388 be shared by the new frame.
2390 This function is an internal primitive--use `make-frame' instead. */)
2391 (parameters)
2392 Lisp_Object parameters;
2394 struct frame *f;
2395 Lisp_Object frame, tem;
2396 Lisp_Object name;
2397 int minibuffer_only = 0;
2398 long window_prompting = 0;
2399 int width, height;
2400 int count = SPECPDL_INDEX ();
2401 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2402 Lisp_Object display;
2403 struct mac_display_info *dpyinfo = NULL;
2404 Lisp_Object parent;
2405 struct kboard *kb;
2407 check_mac ();
2409 parms = Fcopy_alist (parms);
2411 /* Use this general default value to start with
2412 until we know if this frame has a specified name. */
2413 Vx_resource_name = Vinvocation_name;
2415 display = mac_get_arg (parameters, Qdisplay, 0, 0, RES_TYPE_STRING);
2416 if (EQ (display, Qunbound))
2417 display = Qnil;
2418 dpyinfo = check_x_display_info (display);
2419 kb = dpyinfo->terminal->kboard;
2421 name = mac_get_arg (parameters, Qname, "name", "Name", RES_TYPE_STRING);
2422 if (!STRINGP (name)
2423 && ! EQ (name, Qunbound)
2424 && ! NILP (name))
2425 error ("Invalid frame name--not a string or nil");
2427 if (STRINGP (name))
2428 Vx_resource_name = name;
2430 /* See if parent window is specified. */
2431 parent = mac_get_arg (parameters, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
2432 if (EQ (parent, Qunbound))
2433 parent = Qnil;
2434 if (! NILP (parent))
2435 CHECK_NUMBER (parent);
2437 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2438 /* No need to protect DISPLAY because that's not used after passing
2439 it to make_frame_without_minibuffer. */
2440 frame = Qnil;
2441 GCPRO4 (parameters, parent, name, frame);
2442 tem = mac_get_arg (parameters, Qminibuffer, "minibuffer", "Minibuffer",
2443 RES_TYPE_SYMBOL);
2444 if (EQ (tem, Qnone) || NILP (tem))
2445 f = make_frame_without_minibuffer (Qnil, kb, display);
2446 else if (EQ (tem, Qonly))
2448 f = make_minibuffer_frame ();
2449 minibuffer_only = 1;
2451 else if (WINDOWP (tem))
2452 f = make_frame_without_minibuffer (tem, kb, display);
2453 else
2454 f = make_frame (1);
2456 XSETFRAME (frame, f);
2458 /* Note that X Windows does support scroll bars. */
2459 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
2461 f->terminal = dpyinfo->terminal;
2462 f->terminal->reference_count++;
2464 f->output_method = output_mac;
2465 f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output));
2466 bzero (f->output_data.mac, sizeof (struct mac_output));
2467 FRAME_FONTSET (f) = -1;
2468 record_unwind_protect (unwind_create_frame, frame);
2470 f->icon_name
2471 = mac_get_arg (parameters, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
2472 if (! STRINGP (f->icon_name))
2473 f->icon_name = Qnil;
2475 /* XXX Is this needed? */
2476 /*FRAME_MAC_DISPLAY_INFO (f) = dpyinfo;*/
2478 /* With FRAME_MAC_DISPLAY_INFO set up, this unwind-protect is safe. */
2479 #if GLYPH_DEBUG
2480 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
2481 dpyinfo_refcount = dpyinfo->reference_count;
2482 #endif /* GLYPH_DEBUG */
2483 FRAME_KBOARD (f) = kb;
2485 /* Specify the parent under which to make this window. */
2487 if (!NILP (parent))
2489 f->output_data.mac->parent_desc = (Window) XFASTINT (parent);
2490 f->output_data.mac->explicit_parent = 1;
2492 else
2494 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
2495 f->output_data.mac->explicit_parent = 0;
2498 /* Set the name; the functions to which we pass f expect the name to
2499 be set. */
2500 if (EQ (name, Qunbound) || NILP (name))
2502 f->name = build_string (dpyinfo->mac_id_name);
2503 f->explicit_name = 0;
2505 else
2507 f->name = name;
2508 f->explicit_name = 1;
2509 /* use the frame's title when getting resources for this frame. */
2510 specbind (Qx_resource_name, name);
2513 /* Extract the window parameters from the supplied values
2514 that are needed to determine window geometry. */
2516 Lisp_Object font;
2518 font = mac_get_arg (parameters, Qfont, "font", "Font", RES_TYPE_STRING);
2520 BLOCK_INPUT;
2521 /* First, try whatever font the caller has specified. */
2522 if (STRINGP (font))
2524 tem = Fquery_fontset (font, Qnil);
2525 if (STRINGP (tem))
2526 font = x_new_fontset (f, tem);
2527 else
2528 font = x_new_font (f, SDATA (font));
2530 /* Try out a font which we hope has bold and italic variations. */
2531 #if USE_ATSUI
2532 if (! STRINGP (font))
2533 font = x_new_font (f, "-*-monaco-medium-r-normal--12-*-*-*-*-*-iso10646-1");
2534 #endif
2535 if (! STRINGP (font))
2536 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
2537 /* If those didn't work, look for something which will at least work. */
2538 if (! STRINGP (font))
2539 font = x_new_fontset (f, build_string ("fontset-standard"));
2540 if (! STRINGP (font))
2541 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
2542 if (! STRINGP (font))
2543 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
2544 if (! STRINGP (font))
2545 error ("Cannot find any usable font");
2546 UNBLOCK_INPUT;
2548 x_default_parameter (f, parameters, Qfont, font,
2549 "font", "Font", RES_TYPE_STRING);
2552 /* XXX Shouldn't this be borderWidth, not borderwidth ?*/
2553 x_default_parameter (f, parameters, Qborder_width, make_number (0),
2554 "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
2555 /* This defaults to 2 in order to match xterm. We recognize either
2556 internalBorderWidth or internalBorder (which is what xterm calls
2557 it). */
2558 if (NILP (Fassq (Qinternal_border_width, parameters)))
2560 Lisp_Object value;
2562 value = mac_get_arg (parameters, Qinternal_border_width,
2563 "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
2564 if (! EQ (value, Qunbound))
2565 parameters = Fcons (Fcons (Qinternal_border_width, value),
2566 parameters);
2568 /* Default internalBorderWidth to 0 on Windows to match other programs. */
2569 x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
2570 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
2571 x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
2572 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
2574 /* Also do the stuff which must be set before the window exists. */
2575 x_default_parameter (f, parameters, Qforeground_color, build_string ("black"),
2576 "foreground", "Foreground", RES_TYPE_STRING);
2577 x_default_parameter (f, parameters, Qbackground_color, build_string ("white"),
2578 "background", "Background", RES_TYPE_STRING);
2579 x_default_parameter (f, parameters, Qmouse_color, build_string ("black"),
2580 "pointerColor", "Foreground", RES_TYPE_STRING);
2581 x_default_parameter (f, parameters, Qcursor_color, build_string ("black"),
2582 "cursorColor", "Foreground", RES_TYPE_STRING);
2583 x_default_parameter (f, parameters, Qborder_color, build_string ("black"),
2584 "borderColor", "BorderColor", RES_TYPE_STRING);
2585 x_default_parameter (f, parameters, Qscreen_gamma, Qnil,
2586 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
2587 x_default_parameter (f, parameters, Qline_spacing, Qnil,
2588 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
2589 x_default_parameter (f, parameters, Qleft_fringe, Qnil,
2590 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
2591 x_default_parameter (f, parameters, Qright_fringe, Qnil,
2592 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
2595 /* Init faces before x_default_parameter is called for scroll-bar
2596 parameters because that function calls x_set_scroll_bar_width,
2597 which calls change_frame_size, which calls Fset_window_buffer,
2598 which runs hooks, which call Fvertical_motion. At the end, we
2599 end up in init_iterator with a null face cache, which should not
2600 happen. */
2601 init_frame_faces (f);
2603 x_default_parameter (f, parameters, Qmenu_bar_lines, make_number (1),
2604 "menuBar", "MenuBar", RES_TYPE_NUMBER);
2605 x_default_parameter (f, parameters, Qtool_bar_lines, make_number (1),
2606 "toolBar", "ToolBar", RES_TYPE_NUMBER);
2608 x_default_parameter (f, parameters, Qbuffer_predicate, Qnil,
2609 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
2610 x_default_parameter (f, parameters, Qtitle, Qnil,
2611 "title", "Title", RES_TYPE_STRING);
2612 x_default_parameter (f, parameters, Qfullscreen, Qnil,
2613 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
2615 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
2617 /* Compute the size of the window. */
2618 window_prompting = x_figure_window_size (f, parameters, 1);
2620 tem = mac_get_arg (parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
2621 f->no_split = minibuffer_only || EQ (tem, Qt);
2623 mac_window (f);
2624 x_icon (f, parameters);
2626 x_make_gc (f);
2628 /* Now consider the frame official. */
2629 FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
2630 Vframe_list = Fcons (frame, Vframe_list);
2632 /* We need to do this after creating the window, so that the
2633 icon-creation functions can say whose icon they're describing. */
2634 x_default_parameter (f, parameters, Qicon_type, Qnil,
2635 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
2637 x_default_parameter (f, parameters, Qauto_raise, Qnil,
2638 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2639 x_default_parameter (f, parameters, Qauto_lower, Qnil,
2640 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2641 x_default_parameter (f, parameters, Qcursor_type, Qbox,
2642 "cursorType", "CursorType", RES_TYPE_SYMBOL);
2643 x_default_parameter (f, parameters, Qscroll_bar_width, Qnil,
2644 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
2646 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
2647 Change will not be effected unless different from the current
2648 FRAME_LINES (f). */
2649 width = FRAME_COLS (f);
2650 height = FRAME_LINES (f);
2652 FRAME_LINES (f) = 0;
2653 SET_FRAME_COLS (f, 0);
2654 change_frame_size (f, height, width, 1, 0, 0);
2656 /* Tell the server what size and position, etc, we want, and how
2657 badly we want them. This should be done after we have the menu
2658 bar so that its size can be taken into account. */
2659 BLOCK_INPUT;
2660 x_wm_set_size_hint (f, window_prompting, 0);
2661 UNBLOCK_INPUT;
2663 /* Make the window appear on the frame and enable display, unless
2664 the caller says not to. However, with explicit parent, Emacs
2665 cannot control visibility, so don't try. */
2666 if (! f->output_data.mac->explicit_parent)
2668 Lisp_Object visibility;
2670 visibility = mac_get_arg (parameters, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
2671 if (EQ (visibility, Qunbound))
2672 visibility = Qt;
2674 if (EQ (visibility, Qicon))
2675 x_iconify_frame (f);
2676 else if (! NILP (visibility))
2677 x_make_frame_visible (f);
2678 else
2679 /* Must have been Qnil. */
2683 /* Initialize `default-minibuffer-frame' in case this is the first
2684 frame on this display device. */
2685 if (FRAME_HAS_MINIBUF_P (f)
2686 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
2687 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
2688 kb->Vdefault_minibuffer_frame = frame;
2690 /* All remaining specified parameters, which have not been "used"
2691 by x_get_arg and friends, now go in the misc. alist of the frame. */
2692 for (tem = parameters; CONSP (tem); tem = XCDR (tem))
2693 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
2694 f->param_alist = Fcons (XCAR (tem), f->param_alist);
2696 UNGCPRO;
2698 /* Make sure windows on this frame appear in calls to next-window
2699 and similar functions. */
2700 Vwindow_list = Qnil;
2702 return unbind_to (count, frame);
2706 /* FRAME is used only to get a handle on the X display. We don't pass the
2707 display info directly because we're called from frame.c, which doesn't
2708 know about that structure. */
2710 Lisp_Object
2711 x_get_focus_frame (frame)
2712 struct frame *frame;
2714 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
2715 Lisp_Object xfocus;
2716 if (! dpyinfo->x_focus_frame)
2717 return Qnil;
2719 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
2720 return xfocus;
2724 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
2725 doc: /* Set the input focus to FRAME.
2726 FRAME nil means use the selected frame. */)
2727 (frame)
2728 Lisp_Object frame;
2730 OSErr err;
2731 ProcessSerialNumber front_psn;
2732 static const ProcessSerialNumber current_psn = {0, kCurrentProcess};
2733 Boolean front_p;
2734 struct frame *f = check_x_frame (frame);
2736 BLOCK_INPUT;
2737 /* Move the current process to the foreground if it is not. Don't
2738 call SetFrontProcess if the current process is already running in
2739 the foreground so as not to change the z-order of windows. */
2740 err = GetFrontProcess (&front_psn);
2741 if (err == noErr)
2742 err = SameProcess (&front_psn, &current_psn, &front_p);
2743 if (err == noErr)
2744 if (!front_p)
2746 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
2747 if (mac_front_non_floating_window () == FRAME_MAC_WINDOW (f))
2748 SetFrontProcessWithOptions (&current_psn,
2749 kSetFrontProcessFrontWindowOnly);
2750 else
2751 #endif
2752 SetFrontProcess (&current_psn);
2755 #ifdef MAC_OSX
2756 mac_activate_window (mac_active_non_floating_window (), false);
2757 mac_activate_window (FRAME_MAC_WINDOW (f), true);
2758 #else
2759 #if !TARGET_API_MAC_CARBON
2760 /* SelectWindow (Non-Carbon) does not issue deactivate events if the
2761 possibly inactive window that is to be selected is already the
2762 frontmost one. */
2763 SendBehind (FRAME_MAC_WINDOW (f), NULL);
2764 #endif
2765 /* This brings the window to the front. */
2766 SelectWindow (FRAME_MAC_WINDOW (f));
2767 #endif
2768 UNBLOCK_INPUT;
2770 return Qnil;
2774 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
2775 doc: /* Internal function called by `color-defined-p', which see. */)
2776 (color, frame)
2777 Lisp_Object color, frame;
2779 XColor foo;
2780 FRAME_PTR f = check_x_frame (frame);
2782 CHECK_STRING (color);
2784 if (mac_defined_color (f, SDATA (color), &foo, 0))
2785 return Qt;
2786 else
2787 return Qnil;
2790 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2791 doc: /* Internal function called by `color-values', which see. */)
2792 (color, frame)
2793 Lisp_Object color, frame;
2795 XColor foo;
2796 FRAME_PTR f = check_x_frame (frame);
2798 CHECK_STRING (color);
2800 if (mac_defined_color (f, SDATA (color), &foo, 0))
2801 return list3 (make_number (foo.red),
2802 make_number (foo.green),
2803 make_number (foo.blue));
2804 else
2805 return Qnil;
2808 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2809 doc: /* Internal function called by `display-color-p', which see. */)
2810 (display)
2811 Lisp_Object display;
2813 struct mac_display_info *dpyinfo = check_x_display_info (display);
2815 if (!dpyinfo->color_p)
2816 return Qnil;
2818 return Qt;
2821 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
2822 0, 1, 0,
2823 doc: /* Return t if DISPLAY supports shades of gray.
2824 Note that color displays do support shades of gray.
2825 The optional argument DISPLAY specifies which display to ask about.
2826 DISPLAY should be either a frame or a display name (a string).
2827 If omitted or nil, that stands for the selected frame's display. */)
2828 (display)
2829 Lisp_Object display;
2831 struct mac_display_info *dpyinfo = check_x_display_info (display);
2833 if (dpyinfo->n_planes <= 1)
2834 return Qnil;
2836 return Qt;
2839 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2840 0, 1, 0,
2841 doc: /* Return the width in pixels of DISPLAY.
2842 The optional argument DISPLAY specifies which display to ask about.
2843 DISPLAY should be either a frame or a display name (a string).
2844 If omitted or nil, that stands for the selected frame's display. */)
2845 (display)
2846 Lisp_Object display;
2848 struct mac_display_info *dpyinfo = check_x_display_info (display);
2850 return make_number (dpyinfo->width);
2853 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2854 Sx_display_pixel_height, 0, 1, 0,
2855 doc: /* Return the height in pixels of DISPLAY.
2856 The optional argument DISPLAY specifies which display to ask about.
2857 DISPLAY should be either a frame or a display name (a string).
2858 If omitted or nil, that stands for the selected frame's display. */)
2859 (display)
2860 Lisp_Object display;
2862 struct mac_display_info *dpyinfo = check_x_display_info (display);
2864 return make_number (dpyinfo->height);
2867 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2868 0, 1, 0,
2869 doc: /* Return the number of bitplanes of DISPLAY.
2870 The optional argument DISPLAY specifies which display to ask about.
2871 DISPLAY should be either a frame or a display name (a string).
2872 If omitted or nil, that stands for the selected frame's display. */)
2873 (display)
2874 Lisp_Object display;
2876 struct mac_display_info *dpyinfo = check_x_display_info (display);
2878 return make_number (dpyinfo->n_planes);
2881 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2882 0, 1, 0,
2883 doc: /* Return the number of color cells of DISPLAY.
2884 The optional argument DISPLAY specifies which display to ask about.
2885 DISPLAY should be either a frame or a display name (a string).
2886 If omitted or nil, that stands for the selected frame's display. */)
2887 (display)
2888 Lisp_Object display;
2890 struct mac_display_info *dpyinfo = check_x_display_info (display);
2892 /* We force 24+ bit depths to 24-bit to prevent an overflow. */
2893 return make_number (1 << min (dpyinfo->n_planes, 24));
2896 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
2897 Sx_server_max_request_size,
2898 0, 1, 0,
2899 doc: /* Return the maximum request size of the server of DISPLAY.
2900 The optional argument DISPLAY specifies which display to ask about.
2901 DISPLAY should be either a frame or a display name (a string).
2902 If omitted or nil, that stands for the selected frame's display. */)
2903 (display)
2904 Lisp_Object display;
2906 struct mac_display_info *dpyinfo = check_x_display_info (display);
2908 return make_number (1);
2911 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
2912 doc: /* Return the "vendor ID" string of the Mac OS system (Apple).
2913 The optional argument DISPLAY specifies which display to ask about.
2914 DISPLAY should be either a frame or a display name (a string).
2915 If omitted or nil, that stands for the selected frame's display. */)
2916 (display)
2917 Lisp_Object display;
2919 return build_string ("Apple Inc.");
2922 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
2923 doc: /* Return the version numbers of the Mac OS system.
2924 The value is a list of three integers: the major and minor
2925 version numbers, and the vendor-specific release
2926 number. See also the function `x-server-vendor'.
2928 The optional argument DISPLAY specifies which display to ask about.
2929 DISPLAY should be either a frame or a display name (a string).
2930 If omitted or nil, that stands for the selected frame's display. */)
2931 (display)
2932 Lisp_Object display;
2934 UInt32 response, major, minor, bugfix;
2935 OSErr err;
2937 BLOCK_INPUT;
2938 err = Gestalt (gestaltSystemVersion, &response);
2939 if (err == noErr)
2941 if (response >= 0x00001040)
2943 err = Gestalt (gestaltSystemVersionMajor, &major);
2944 if (err == noErr)
2945 err = Gestalt (gestaltSystemVersionMinor, &minor);
2946 if (err == noErr)
2947 err = Gestalt (gestaltSystemVersionBugFix, &bugfix);
2949 else
2951 bugfix = response & 0xf;
2952 response >>= 4;
2953 minor = response & 0xf;
2954 response >>= 4;
2955 /* convert BCD to int */
2956 major = response - (response >> 4) * 6;
2959 UNBLOCK_INPUT;
2961 if (err != noErr)
2962 error ("Cannot get Mac OS version");
2964 return Fcons (make_number (major),
2965 Fcons (make_number (minor),
2966 Fcons (make_number (bugfix),
2967 Qnil)));
2970 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
2971 doc: /* Return the number of screens on the server of DISPLAY.
2972 The optional argument DISPLAY specifies which display to ask about.
2973 DISPLAY should be either a frame or a display name (a string).
2974 If omitted or nil, that stands for the selected frame's display. */)
2975 (display)
2976 Lisp_Object display;
2978 return make_number (1);
2981 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
2982 doc: /* Return the height in millimeters of DISPLAY.
2983 The optional argument DISPLAY specifies which display to ask about.
2984 DISPLAY should be either a frame or a display name (a string).
2985 If omitted or nil, that stands for the selected frame's display. */)
2986 (display)
2987 Lisp_Object display;
2989 struct mac_display_info *dpyinfo = check_x_display_info (display);
2990 float mm_per_pixel;
2992 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
2993 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
2994 if (CGDisplayScreenSize != NULL)
2995 #endif
2997 CGSize size;
2999 BLOCK_INPUT;
3000 size = CGDisplayScreenSize (kCGDirectMainDisplay);
3001 mm_per_pixel = size.height / CGDisplayPixelsHigh (kCGDirectMainDisplay);
3002 UNBLOCK_INPUT;
3004 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3005 else /* CGDisplayScreenSize == NULL */
3006 #endif
3007 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
3008 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3010 /* This is an approximation. */
3011 mm_per_pixel = 25.4f / dpyinfo->resy;
3013 #endif
3015 return make_number ((int) (dpyinfo->height * mm_per_pixel + 0.5f));
3018 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3019 doc: /* Return the width in millimeters of DISPLAY.
3020 The optional argument DISPLAY specifies which display to ask about.
3021 DISPLAY should be either a frame or a display name (a string).
3022 If omitted or nil, that stands for the selected frame's display. */)
3023 (display)
3024 Lisp_Object display;
3026 struct mac_display_info *dpyinfo = check_x_display_info (display);
3027 float mm_per_pixel;
3029 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
3030 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3031 if (CGDisplayScreenSize != NULL)
3032 #endif
3034 CGSize size;
3036 BLOCK_INPUT;
3037 size = CGDisplayScreenSize (kCGDirectMainDisplay);
3038 mm_per_pixel = size.width / CGDisplayPixelsWide (kCGDirectMainDisplay);
3039 UNBLOCK_INPUT;
3041 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3042 else /* CGDisplayScreenSize == NULL */
3043 #endif
3044 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
3045 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3047 /* This is an approximation. */
3048 mm_per_pixel = 25.4f / dpyinfo->resx;
3050 #endif
3052 return make_number ((int) (dpyinfo->width * mm_per_pixel + 0.5f));
3055 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3056 Sx_display_backing_store, 0, 1, 0,
3057 doc: /* Return an indication of whether DISPLAY does backing store.
3058 The value may be `always', `when-mapped', or `not-useful'.
3059 The optional argument DISPLAY specifies which display to ask about.
3060 DISPLAY should be either a frame or a display name (a string).
3061 If omitted or nil, that stands for the selected frame's display. */)
3062 (display)
3063 Lisp_Object display;
3065 return intern ("not-useful");
3068 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3069 Sx_display_visual_class, 0, 1, 0,
3070 doc: /* Return the visual class of DISPLAY.
3071 The value is one of the symbols `static-gray', `gray-scale',
3072 `static-color', `pseudo-color', `true-color', or `direct-color'.
3074 The optional argument DISPLAY specifies which display to ask about.
3075 DISPLAY should be either a frame or a display name (a string).
3076 If omitted or nil, that stands for the selected frame's display. */)
3077 (display)
3078 Lisp_Object display;
3080 struct mac_display_info *dpyinfo = check_x_display_info (display);
3082 #if 0
3083 switch (dpyinfo->visual->class)
3085 case StaticGray: return (intern ("static-gray"));
3086 case GrayScale: return (intern ("gray-scale"));
3087 case StaticColor: return (intern ("static-color"));
3088 case PseudoColor: return (intern ("pseudo-color"));
3089 case TrueColor: return (intern ("true-color"));
3090 case DirectColor: return (intern ("direct-color"));
3091 default:
3092 error ("Display has an unknown visual class");
3094 #endif /* 0 */
3096 return (intern ("true-color"));
3099 DEFUN ("x-display-save-under", Fx_display_save_under,
3100 Sx_display_save_under, 0, 1, 0,
3101 doc: /* Return t if DISPLAY supports the save-under feature.
3102 The optional argument DISPLAY specifies which display to ask about.
3103 DISPLAY should be either a frame or a display name (a string).
3104 If omitted or nil, that stands for the selected frame's display. */)
3105 (display)
3106 Lisp_Object display;
3108 return Qnil;
3112 x_pixel_width (f)
3113 register struct frame *f;
3115 return FRAME_PIXEL_WIDTH (f);
3119 x_pixel_height (f)
3120 register struct frame *f;
3122 return FRAME_PIXEL_HEIGHT (f);
3126 x_char_width (f)
3127 register struct frame *f;
3129 return FRAME_COLUMN_WIDTH (f);
3133 x_char_height (f)
3134 register struct frame *f;
3136 return FRAME_LINE_HEIGHT (f);
3140 x_screen_planes (f)
3141 register struct frame *f;
3143 return FRAME_MAC_DISPLAY_INFO (f)->n_planes;
3146 /* Return the display structure for the display named NAME.
3147 Open a new connection if necessary. */
3149 struct mac_display_info *
3150 x_display_info_for_name (name)
3151 Lisp_Object name;
3153 Lisp_Object names;
3154 struct mac_display_info *dpyinfo;
3156 CHECK_STRING (name);
3158 for (dpyinfo = &one_mac_display_info, names = x_display_name_list;
3159 dpyinfo;
3160 dpyinfo = dpyinfo->next, names = XCDR (names))
3162 Lisp_Object tem;
3163 tem = Fstring_equal (XCAR (XCAR (names)), name);
3164 if (!NILP (tem))
3165 return dpyinfo;
3168 /* Use this general default value to start with. */
3169 Vx_resource_name = Vinvocation_name;
3171 validate_x_resource_name ();
3173 dpyinfo = mac_term_init (name, (unsigned char *) 0,
3174 (char *) SDATA (Vx_resource_name));
3176 if (dpyinfo == 0)
3177 error ("Cannot connect to server %s", SDATA (name));
3179 mac_in_use = 1;
3180 XSETFASTINT (Vwindow_system_version, 3);
3182 return dpyinfo;
3185 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
3186 1, 3, 0,
3187 doc: /* Open a connection to a server.
3188 DISPLAY is the name of the display to connect to.
3189 Optional second arg XRM-STRING is a string of resources in xrdb format.
3190 If the optional third arg MUST-SUCCEED is non-nil,
3191 terminate Emacs if we can't open the connection. */)
3192 (display, xrm_string, must_succeed)
3193 Lisp_Object display, xrm_string, must_succeed;
3195 unsigned char *xrm_option;
3196 struct mac_display_info *dpyinfo;
3198 CHECK_STRING (display);
3199 if (! NILP (xrm_string))
3200 CHECK_STRING (xrm_string);
3202 if (! NILP (xrm_string))
3203 xrm_option = (unsigned char *) SDATA (xrm_string);
3204 else
3205 xrm_option = (unsigned char *) 0;
3207 validate_x_resource_name ();
3209 /* This is what opens the connection and sets x_current_display.
3210 This also initializes many symbols, such as those used for input. */
3211 dpyinfo = mac_term_init (display, xrm_option,
3212 (char *) SDATA (Vx_resource_name));
3214 if (dpyinfo == 0)
3216 if (!NILP (must_succeed))
3217 fatal ("Cannot connect to server %s.\n",
3218 SDATA (display));
3219 else
3220 error ("Cannot connect to server %s", SDATA (display));
3223 mac_in_use = 1;
3225 XSETFASTINT (Vwindow_system_version, 3);
3226 return Qnil;
3229 DEFUN ("x-close-connection", Fx_close_connection,
3230 Sx_close_connection, 1, 1, 0,
3231 doc: /* Close the connection to DISPLAY's server.
3232 For DISPLAY, specify either a frame or a display name (a string).
3233 If DISPLAY is nil, that stands for the selected frame's display. */)
3234 (display)
3235 Lisp_Object display;
3237 struct mac_display_info *dpyinfo = check_x_display_info (display);
3238 int i;
3240 if (dpyinfo->reference_count > 0)
3241 error ("Display still has frames on it");
3243 BLOCK_INPUT;
3244 /* Free the fonts in the font table. */
3245 for (i = 0; i < dpyinfo->n_fonts; i++)
3246 if (dpyinfo->font_table[i].name)
3248 mac_unload_font (dpyinfo, dpyinfo->font_table[i].font);
3251 x_destroy_all_bitmaps (dpyinfo);
3253 x_delete_display (dpyinfo);
3254 UNBLOCK_INPUT;
3256 return Qnil;
3259 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
3260 doc: /* Return the list of display names that Emacs has connections to. */)
3263 Lisp_Object tail, result;
3265 result = Qnil;
3266 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
3267 result = Fcons (XCAR (XCAR (tail)), result);
3269 return result;
3272 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
3273 doc: /* This is a noop on Mac OS systems. */)
3274 (on, display)
3275 Lisp_Object display, on;
3277 return Qnil;
3280 /* x_sync is a no-op on Mac. */
3282 void
3283 x_sync (f)
3284 FRAME_PTR f;
3289 /***********************************************************************
3290 Window properties
3291 ***********************************************************************/
3293 DEFUN ("x-change-window-property", Fx_change_window_property,
3294 Sx_change_window_property, 2, 6, 0,
3295 doc: /* Change window property PROP to VALUE on the X window of FRAME.
3296 VALUE may be a string or a list of conses, numbers and/or strings.
3297 If an element in the list is a string, it is converted to
3298 an Atom and the value of the Atom is used. If an element is a cons,
3299 it is converted to a 32 bit number where the car is the 16 top bits and the
3300 cdr is the lower 16 bits.
3301 FRAME nil or omitted means use the selected frame.
3302 If TYPE is given and non-nil, it is the name of the type of VALUE.
3303 If TYPE is not given or nil, the type is STRING.
3304 FORMAT gives the size in bits of each element if VALUE is a list.
3305 It must be one of 8, 16 or 32.
3306 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
3307 If OUTER_P is non-nil, the property is changed for the outer X window of
3308 FRAME. Default is to change on the edit X window.
3310 Value is VALUE. */)
3311 (prop, value, frame, type, format, outer_p)
3312 Lisp_Object prop, value, frame, type, format, outer_p;
3314 #if 0 /* MAC_TODO : port window properties to Mac */
3315 struct frame *f = check_x_frame (frame);
3316 Atom prop_atom;
3318 CHECK_STRING (prop);
3319 CHECK_STRING (value);
3321 BLOCK_INPUT;
3322 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3323 XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3324 prop_atom, XA_STRING, 8, PropModeReplace,
3325 SDATA (value), SCHARS (value));
3327 /* Make sure the property is set when we return. */
3328 XFlush (FRAME_W32_DISPLAY (f));
3329 UNBLOCK_INPUT;
3331 #endif /* MAC_TODO */
3333 return value;
3337 DEFUN ("x-delete-window-property", Fx_delete_window_property,
3338 Sx_delete_window_property, 1, 2, 0,
3339 doc: /* Remove window property PROP from X window of FRAME.
3340 FRAME nil or omitted means use the selected frame. Value is PROP. */)
3341 (prop, frame)
3342 Lisp_Object prop, frame;
3344 #if 0 /* MAC_TODO : port window properties to Mac */
3346 struct frame *f = check_x_frame (frame);
3347 Atom prop_atom;
3349 CHECK_STRING (prop);
3350 BLOCK_INPUT;
3351 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3352 XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
3354 /* Make sure the property is removed when we return. */
3355 XFlush (FRAME_W32_DISPLAY (f));
3356 UNBLOCK_INPUT;
3357 #endif /* MAC_TODO */
3359 return prop;
3363 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
3364 1, 2, 0,
3365 doc: /* Value is the value of window property PROP on FRAME.
3366 If FRAME is nil or omitted, use the selected frame. Value is nil
3367 if FRAME hasn't a property with name PROP or if PROP has no string
3368 value. */)
3369 (prop, frame)
3370 Lisp_Object prop, frame;
3372 #if 0 /* MAC_TODO : port window properties to Mac */
3374 struct frame *f = check_x_frame (frame);
3375 Atom prop_atom;
3376 int rc;
3377 Lisp_Object prop_value = Qnil;
3378 char *tmp_data = NULL;
3379 Atom actual_type;
3380 int actual_format;
3381 unsigned long actual_size, bytes_remaining;
3383 CHECK_STRING (prop);
3384 BLOCK_INPUT;
3385 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3386 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3387 prop_atom, 0, 0, False, XA_STRING,
3388 &actual_type, &actual_format, &actual_size,
3389 &bytes_remaining, (unsigned char **) &tmp_data);
3390 if (rc == Success)
3392 int size = bytes_remaining;
3394 XFree (tmp_data);
3395 tmp_data = NULL;
3397 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3398 prop_atom, 0, bytes_remaining,
3399 False, XA_STRING,
3400 &actual_type, &actual_format,
3401 &actual_size, &bytes_remaining,
3402 (unsigned char **) &tmp_data);
3403 if (rc == Success)
3404 prop_value = make_string (tmp_data, size);
3406 XFree (tmp_data);
3409 UNBLOCK_INPUT;
3411 return prop_value;
3413 #endif /* MAC_TODO */
3414 return Qnil;
3419 /***********************************************************************
3420 Busy cursor
3421 ***********************************************************************/
3423 /* If non-null, an asynchronous timer that, when it expires, displays
3424 an hourglass cursor on all frames. */
3426 static struct atimer *hourglass_atimer;
3428 /* Non-zero means an hourglass cursor is currently shown. */
3430 static int hourglass_shown_p;
3432 /* Number of seconds to wait before displaying an hourglass cursor. */
3434 static Lisp_Object Vhourglass_delay;
3436 /* Default number of seconds to wait before displaying an hourglass
3437 cursor. */
3439 #define DEFAULT_HOURGLASS_DELAY 1
3441 /* Function prototypes. */
3443 static void show_hourglass P_ ((struct atimer *));
3444 static void hide_hourglass P_ ((void));
3446 /* Return non-zero if houglass timer has been started or hourglass is shown. */
3449 hourglass_started ()
3451 return hourglass_shown_p || hourglass_atimer != NULL;
3455 /* Cancel a currently active hourglass timer, and start a new one. */
3457 void
3458 start_hourglass ()
3460 #ifdef MAC_OSX
3461 EMACS_TIME delay;
3462 int secs, usecs = 0;
3464 cancel_hourglass ();
3466 if (INTEGERP (Vhourglass_delay)
3467 && XINT (Vhourglass_delay) > 0)
3468 secs = XFASTINT (Vhourglass_delay);
3469 else if (FLOATP (Vhourglass_delay)
3470 && XFLOAT_DATA (Vhourglass_delay) > 0)
3472 Lisp_Object tem;
3473 tem = Ftruncate (Vhourglass_delay, Qnil);
3474 secs = XFASTINT (tem);
3475 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
3477 else
3478 secs = DEFAULT_HOURGLASS_DELAY;
3480 EMACS_SET_SECS_USECS (delay, secs, usecs);
3481 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
3482 show_hourglass, NULL);
3483 #endif /* MAC_OSX */
3487 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
3488 shown. */
3490 void
3491 cancel_hourglass ()
3493 #ifdef MAC_OSX
3494 if (hourglass_atimer)
3496 cancel_atimer (hourglass_atimer);
3497 hourglass_atimer = NULL;
3500 if (hourglass_shown_p)
3501 hide_hourglass ();
3502 #endif /* MAC_OSX */
3506 /* Timer function of hourglass_atimer. TIMER is equal to
3507 hourglass_atimer.
3509 On Mac, busy status is shown by the progress indicator (chasing
3510 arrows) at the upper-right corner of each frame instead of the
3511 hourglass pointer. */
3513 static void
3514 show_hourglass (timer)
3515 struct atimer *timer;
3517 #if TARGET_API_MAC_CARBON
3518 /* The timer implementation will cancel this timer automatically
3519 after this function has run. Set hourglass_atimer to null
3520 so that we know the timer doesn't have to be canceled. */
3521 hourglass_atimer = NULL;
3523 if (!hourglass_shown_p)
3525 Lisp_Object rest, frame;
3527 BLOCK_INPUT;
3529 FOR_EACH_FRAME (rest, frame)
3531 struct frame *f = XFRAME (frame);
3533 if (FRAME_LIVE_P (f) && FRAME_MAC_P (f)
3534 && FRAME_MAC_WINDOW (f) != tip_window)
3535 mac_show_hourglass (f);
3538 hourglass_shown_p = 1;
3539 UNBLOCK_INPUT;
3541 #endif /* TARGET_API_MAC_CARBON */
3545 /* Hide the progress indicators on all frames, if it is currently
3546 shown. */
3548 static void
3549 hide_hourglass ()
3551 #if TARGET_API_MAC_CARBON
3552 if (hourglass_shown_p)
3554 Lisp_Object rest, frame;
3556 BLOCK_INPUT;
3557 FOR_EACH_FRAME (rest, frame)
3559 struct frame *f = XFRAME (frame);
3561 if (FRAME_MAC_P (f))
3562 mac_hide_hourglass (f);
3565 hourglass_shown_p = 0;
3566 UNBLOCK_INPUT;
3568 #endif /* TARGET_API_MAC_CARBON */
3573 /***********************************************************************
3574 Tool tips
3575 ***********************************************************************/
3577 static Lisp_Object x_create_tip_frame P_ ((struct mac_display_info *,
3578 Lisp_Object, Lisp_Object));
3579 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
3580 Lisp_Object, int, int, int *, int *));
3582 /* The frame of a currently visible tooltip. */
3584 Lisp_Object tip_frame;
3586 /* If non-nil, a timer started that hides the last tooltip when it
3587 fires. */
3589 Lisp_Object tip_timer;
3590 Window tip_window;
3592 /* If non-nil, a vector of 3 elements containing the last args
3593 with which x-show-tip was called. See there. */
3595 Lisp_Object last_show_tip_args;
3597 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
3599 Lisp_Object Vx_max_tooltip_size;
3602 static Lisp_Object
3603 unwind_create_tip_frame (frame)
3604 Lisp_Object frame;
3606 Lisp_Object deleted;
3608 deleted = unwind_create_frame (frame);
3609 if (EQ (deleted, Qt))
3611 tip_window = NULL;
3612 tip_frame = Qnil;
3615 return deleted;
3619 /* Create a frame for a tooltip on the display described by DPYINFO.
3620 PARMS is a list of frame parameters. TEXT is the string to
3621 display in the tip frame. Value is the frame.
3623 Note that functions called here, esp. x_default_parameter can
3624 signal errors, for instance when a specified color name is
3625 undefined. We have to make sure that we're in a consistent state
3626 when this happens. */
3628 static Lisp_Object
3629 x_create_tip_frame (dpyinfo, parms, text)
3630 struct mac_display_info *dpyinfo;
3631 Lisp_Object parms, text;
3633 struct frame *f;
3634 Lisp_Object frame, tem;
3635 Lisp_Object name;
3636 long window_prompting = 0;
3637 int width, height;
3638 int count = SPECPDL_INDEX ();
3639 struct gcpro gcpro1, gcpro2, gcpro3;
3640 struct kboard *kb;
3641 int face_change_count_before = face_change_count;
3642 Lisp_Object buffer;
3643 struct buffer *old_buffer;
3645 check_mac ();
3647 parms = Fcopy_alist (parms);
3649 kb = dpyinfo->terminal->kboard;
3651 /* Get the name of the frame to use for resource lookup. */
3652 name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
3653 if (!STRINGP (name)
3654 && !EQ (name, Qunbound)
3655 && !NILP (name))
3656 error ("Invalid frame name--not a string or nil");
3658 frame = Qnil;
3659 GCPRO3 (parms, name, frame);
3660 f = make_frame (1);
3661 XSETFRAME (frame, f);
3663 buffer = Fget_buffer_create (build_string (" *tip*"));
3664 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
3665 old_buffer = current_buffer;
3666 set_buffer_internal_1 (XBUFFER (buffer));
3667 current_buffer->truncate_lines = Qnil;
3668 specbind (Qinhibit_read_only, Qt);
3669 specbind (Qinhibit_modification_hooks, Qt);
3670 Ferase_buffer ();
3671 Finsert (1, &text);
3672 set_buffer_internal_1 (old_buffer);
3674 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
3675 record_unwind_protect (unwind_create_tip_frame, frame);
3677 /* By setting the output method, we're essentially saying that
3678 the frame is live, as per FRAME_LIVE_P. If we get a signal
3679 from this point on, x_destroy_window might screw up reference
3680 counts etc. */
3681 f->terminal = dpyinfo->terminal;
3682 f->terminal->reference_count++;
3683 f->output_method = output_mac;
3684 f->output_data.mac =
3685 (struct mac_output *) xmalloc (sizeof (struct mac_output));
3686 bzero (f->output_data.mac, sizeof (struct mac_output));
3688 FRAME_FONTSET (f) = -1;
3689 f->icon_name = Qnil;
3690 /* FRAME_X_DISPLAY_INFO (f) = dpyinfo; */
3691 #if GLYPH_DEBUG
3692 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3693 dpyinfo_refcount = dpyinfo->reference_count;
3694 #endif /* GLYPH_DEBUG */
3695 FRAME_KBOARD (f) = kb;
3696 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
3697 f->output_data.mac->explicit_parent = 0;
3699 /* Set the name; the functions to which we pass f expect the name to
3700 be set. */
3701 if (EQ (name, Qunbound) || NILP (name))
3703 f->name = build_string (dpyinfo->mac_id_name);
3704 f->explicit_name = 0;
3706 else
3708 f->name = name;
3709 f->explicit_name = 1;
3710 /* use the frame's title when getting resources for this frame. */
3711 specbind (Qx_resource_name, name);
3714 /* Extract the window parameters from the supplied values that are
3715 needed to determine window geometry. */
3717 Lisp_Object font;
3719 font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
3721 BLOCK_INPUT;
3722 /* First, try whatever font the caller has specified. */
3723 if (STRINGP (font))
3725 tem = Fquery_fontset (font, Qnil);
3726 if (STRINGP (tem))
3727 font = x_new_fontset (f, tem);
3728 else
3729 font = x_new_font (f, SDATA (font));
3732 /* Try out a font which we hope has bold and italic variations. */
3733 #if USE_ATSUI
3734 if (! STRINGP (font))
3735 font = x_new_font (f, "-*-monaco-medium-r-normal--12-*-*-*-*-*-iso10646-1");
3736 #endif
3737 if (! STRINGP (font))
3738 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
3739 /* If those didn't work, look for something which will at least work. */
3740 if (! STRINGP (font))
3741 font = x_new_fontset (f, build_string ("fontset-standard"));
3742 if (! STRINGP (font))
3743 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
3744 if (! STRINGP (font))
3745 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
3746 UNBLOCK_INPUT;
3747 if (! STRINGP (font))
3748 error ("Cannot find any usable font");
3750 x_default_parameter (f, parms, Qfont, font,
3751 "font", "Font", RES_TYPE_STRING);
3754 x_default_parameter (f, parms, Qborder_width, make_number (2),
3755 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3757 /* This defaults to 2 in order to match xterm. We recognize either
3758 internalBorderWidth or internalBorder (which is what xterm calls
3759 it). */
3760 if (NILP (Fassq (Qinternal_border_width, parms)))
3762 Lisp_Object value;
3764 value = mac_get_arg (parms, Qinternal_border_width,
3765 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3766 if (! EQ (value, Qunbound))
3767 parms = Fcons (Fcons (Qinternal_border_width, value),
3768 parms);
3771 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
3772 "internalBorderWidth", "internalBorderWidth",
3773 RES_TYPE_NUMBER);
3775 /* Also do the stuff which must be set before the window exists. */
3776 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3777 "foreground", "Foreground", RES_TYPE_STRING);
3778 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3779 "background", "Background", RES_TYPE_STRING);
3780 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3781 "pointerColor", "Foreground", RES_TYPE_STRING);
3782 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3783 "cursorColor", "Foreground", RES_TYPE_STRING);
3784 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3785 "borderColor", "BorderColor", RES_TYPE_STRING);
3787 /* Init faces before x_default_parameter is called for scroll-bar
3788 parameters because that function calls x_set_scroll_bar_width,
3789 which calls change_frame_size, which calls Fset_window_buffer,
3790 which runs hooks, which call Fvertical_motion. At the end, we
3791 end up in init_iterator with a null face cache, which should not
3792 happen. */
3793 init_frame_faces (f);
3795 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
3797 window_prompting = x_figure_window_size (f, parms, 0);
3799 BLOCK_INPUT;
3801 mac_create_frame_window (f, 1);
3803 if (FRAME_MAC_WINDOW (f))
3805 mac_set_frame_window_background (f, FRAME_BACKGROUND_PIXEL (f));
3806 tip_window = FRAME_MAC_WINDOW (f);
3809 UNBLOCK_INPUT;
3811 x_make_gc (f);
3813 x_default_parameter (f, parms, Qauto_raise, Qnil,
3814 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3815 x_default_parameter (f, parms, Qauto_lower, Qnil,
3816 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3817 x_default_parameter (f, parms, Qcursor_type, Qbox,
3818 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3820 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3821 Change will not be effected unless different from the current
3822 FRAME_LINES (f). */
3823 width = FRAME_COLS (f);
3824 height = FRAME_LINES (f);
3825 SET_FRAME_COLS (f, 0);
3826 FRAME_LINES (f) = 0;
3827 change_frame_size (f, height, width, 1, 0, 0);
3829 /* Add `tooltip' frame parameter's default value. */
3830 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
3831 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
3832 Qnil));
3834 /* Set up faces after all frame parameters are known. This call
3835 also merges in face attributes specified for new frames.
3837 Frame parameters may be changed if .Xdefaults contains
3838 specifications for the default font. For example, if there is an
3839 `Emacs.default.attributeBackground: pink', the `background-color'
3840 attribute of the frame get's set, which let's the internal border
3841 of the tooltip frame appear in pink. Prevent this. */
3843 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
3845 /* Set tip_frame here, so that */
3846 tip_frame = frame;
3847 call1 (Qface_set_after_frame_default, frame);
3849 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
3850 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
3851 Qnil));
3854 f->no_split = 1;
3856 UNGCPRO;
3858 /* It is now ok to make the frame official even if we get an error
3859 below. And the frame needs to be on Vframe_list or making it
3860 visible won't work. */
3861 Vframe_list = Fcons (frame, Vframe_list);
3863 /* Now that the frame is official, it counts as a reference to
3864 its display. */
3865 FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
3867 /* Setting attributes of faces of the tooltip frame from resources
3868 and similar will increment face_change_count, which leads to the
3869 clearing of all current matrices. Since this isn't necessary
3870 here, avoid it by resetting face_change_count to the value it
3871 had before we created the tip frame. */
3872 face_change_count = face_change_count_before;
3874 /* Discard the unwind_protect. */
3875 return unbind_to (count, frame);
3879 /* Compute where to display tip frame F. PARMS is the list of frame
3880 parameters for F. DX and DY are specified offsets from the current
3881 location of the mouse. WIDTH and HEIGHT are the width and height
3882 of the tooltip. Return coordinates relative to the root window of
3883 the display in *ROOT_X, and *ROOT_Y. */
3885 static void
3886 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
3887 struct frame *f;
3888 Lisp_Object parms, dx, dy;
3889 int width, height;
3890 int *root_x, *root_y;
3892 Lisp_Object left, top;
3894 /* User-specified position? */
3895 left = Fcdr (Fassq (Qleft, parms));
3896 top = Fcdr (Fassq (Qtop, parms));
3898 /* Move the tooltip window where the mouse pointer is. Resize and
3899 show it. */
3900 if (!INTEGERP (left) || !INTEGERP (top))
3902 Point mouse_pos;
3904 BLOCK_INPUT;
3905 #if TARGET_API_MAC_CARBON
3906 mac_get_global_mouse (&mouse_pos);
3907 #else
3908 GetMouse (&mouse_pos);
3909 LocalToGlobal (&mouse_pos);
3910 #endif
3911 *root_x = mouse_pos.h;
3912 *root_y = mouse_pos.v;
3913 UNBLOCK_INPUT;
3916 if (INTEGERP (top))
3917 *root_y = XINT (top);
3918 else if (*root_y + XINT (dy) <= 0)
3919 *root_y = 0; /* Can happen for negative dy */
3920 else if (*root_y + XINT (dy) + height <= FRAME_MAC_DISPLAY_INFO (f)->height)
3921 /* It fits below the pointer */
3922 *root_y += XINT (dy);
3923 else if (height + XINT (dy) <= *root_y)
3924 /* It fits above the pointer. */
3925 *root_y -= height + XINT (dy);
3926 else
3927 /* Put it on the top. */
3928 *root_y = 0;
3930 if (INTEGERP (left))
3931 *root_x = XINT (left);
3932 else if (*root_x + XINT (dx) <= 0)
3933 *root_x = 0; /* Can happen for negative dx */
3934 else if (*root_x + XINT (dx) + width <= FRAME_MAC_DISPLAY_INFO (f)->width)
3935 /* It fits to the right of the pointer. */
3936 *root_x += XINT (dx);
3937 else if (width + XINT (dx) <= *root_x)
3938 /* It fits to the left of the pointer. */
3939 *root_x -= width + XINT (dx);
3940 else
3941 /* Put it left-justified on the screen -- it ought to fit that way. */
3942 *root_x = 0;
3946 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
3947 doc: /* Show STRING in a "tooltip" window on frame FRAME.
3948 A tooltip window is a small window displaying a string.
3950 This is an internal function; Lisp code should call `tooltip-show'.
3952 FRAME nil or omitted means use the selected frame.
3954 PARMS is an optional list of frame parameters which can be used to
3955 change the tooltip's appearance.
3957 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
3958 means use the default timeout of 5 seconds.
3960 If the list of frame parameters PARMS contains a `left' parameter,
3961 the tooltip is displayed at that x-position. Otherwise it is
3962 displayed at the mouse position, with offset DX added (default is 5 if
3963 DX isn't specified). Likewise for the y-position; if a `top' frame
3964 parameter is specified, it determines the y-position of the tooltip
3965 window, otherwise it is displayed at the mouse position, with offset
3966 DY added (default is -10).
3968 A tooltip's maximum size is specified by `x-max-tooltip-size'.
3969 Text larger than the specified size is clipped. */)
3970 (string, frame, parms, timeout, dx, dy)
3971 Lisp_Object string, frame, parms, timeout, dx, dy;
3973 struct frame *f;
3974 struct window *w;
3975 int root_x, root_y;
3976 struct buffer *old_buffer;
3977 struct text_pos pos;
3978 int i, width, height;
3979 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3980 int old_windows_or_buffers_changed = windows_or_buffers_changed;
3981 int count = SPECPDL_INDEX ();
3983 specbind (Qinhibit_redisplay, Qt);
3985 GCPRO4 (string, parms, frame, timeout);
3987 CHECK_STRING (string);
3988 f = check_x_frame (frame);
3989 if (NILP (timeout))
3990 timeout = make_number (5);
3991 else
3992 CHECK_NATNUM (timeout);
3994 if (NILP (dx))
3995 dx = make_number (5);
3996 else
3997 CHECK_NUMBER (dx);
3999 if (NILP (dy))
4000 dy = make_number (-10);
4001 else
4002 CHECK_NUMBER (dy);
4004 if (NILP (last_show_tip_args))
4005 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
4007 if (!NILP (tip_frame))
4009 Lisp_Object last_string = AREF (last_show_tip_args, 0);
4010 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
4011 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
4013 if (EQ (frame, last_frame)
4014 && !NILP (Fequal (last_string, string))
4015 && !NILP (Fequal (last_parms, parms)))
4017 struct frame *f = XFRAME (tip_frame);
4019 /* Only DX and DY have changed. */
4020 if (!NILP (tip_timer))
4022 Lisp_Object timer = tip_timer;
4023 tip_timer = Qnil;
4024 call1 (Qcancel_timer, timer);
4027 BLOCK_INPUT;
4028 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
4029 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
4030 mac_move_window (FRAME_MAC_WINDOW (f), root_x, root_y, false);
4031 UNBLOCK_INPUT;
4032 goto start_timer;
4036 /* Hide a previous tip, if any. */
4037 Fx_hide_tip ();
4039 ASET (last_show_tip_args, 0, string);
4040 ASET (last_show_tip_args, 1, frame);
4041 ASET (last_show_tip_args, 2, parms);
4043 /* Add default values to frame parameters. */
4044 if (NILP (Fassq (Qname, parms)))
4045 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
4046 if (NILP (Fassq (Qinternal_border_width, parms)))
4047 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
4048 if (NILP (Fassq (Qborder_width, parms)))
4049 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
4050 if (NILP (Fassq (Qborder_color, parms)))
4051 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
4052 if (NILP (Fassq (Qbackground_color, parms)))
4053 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
4054 parms);
4056 /* Create a frame for the tooltip, and record it in the global
4057 variable tip_frame. */
4058 frame = x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f), parms, string);
4059 f = XFRAME (frame);
4061 /* Set up the frame's root window. */
4062 w = XWINDOW (FRAME_ROOT_WINDOW (f));
4063 w->left_col = w->top_line = make_number (0);
4065 if (CONSP (Vx_max_tooltip_size)
4066 && INTEGERP (XCAR (Vx_max_tooltip_size))
4067 && XINT (XCAR (Vx_max_tooltip_size)) > 0
4068 && INTEGERP (XCDR (Vx_max_tooltip_size))
4069 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
4071 w->total_cols = XCAR (Vx_max_tooltip_size);
4072 w->total_lines = XCDR (Vx_max_tooltip_size);
4074 else
4076 w->total_cols = make_number (80);
4077 w->total_lines = make_number (40);
4080 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
4081 adjust_glyphs (f);
4082 w->pseudo_window_p = 1;
4084 /* Display the tooltip text in a temporary buffer. */
4085 old_buffer = current_buffer;
4086 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
4087 current_buffer->truncate_lines = Qnil;
4088 clear_glyph_matrix (w->desired_matrix);
4089 clear_glyph_matrix (w->current_matrix);
4090 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
4091 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
4093 /* Compute width and height of the tooltip. */
4094 width = height = 0;
4095 for (i = 0; i < w->desired_matrix->nrows; ++i)
4097 struct glyph_row *row = &w->desired_matrix->rows[i];
4098 struct glyph *last;
4099 int row_width;
4101 /* Stop at the first empty row at the end. */
4102 if (!row->enabled_p || !row->displays_text_p)
4103 break;
4105 /* Let the row go over the full width of the frame. */
4106 row->full_width_p = 1;
4108 /* There's a glyph at the end of rows that is used to place
4109 the cursor there. Don't include the width of this glyph. */
4110 if (row->used[TEXT_AREA])
4112 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
4113 row_width = row->pixel_width - last->pixel_width;
4115 else
4116 row_width = row->pixel_width;
4118 height += row->height;
4119 width = max (width, row_width);
4122 /* Add the frame's internal border to the width and height the X
4123 window should have. */
4124 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4125 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4127 /* Move the tooltip window where the mouse pointer is. Resize and
4128 show it. */
4129 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
4131 BLOCK_INPUT;
4132 mac_move_window (FRAME_MAC_WINDOW (f), root_x, root_y, false);
4133 mac_size_window (FRAME_MAC_WINDOW (f), width, height, true);
4134 mac_show_window (FRAME_MAC_WINDOW (f));
4135 mac_bring_window_to_front (FRAME_MAC_WINDOW (f));
4136 UNBLOCK_INPUT;
4138 FRAME_PIXEL_WIDTH (f) = width;
4139 FRAME_PIXEL_HEIGHT (f) = height;
4141 /* Draw into the window. */
4142 w->must_be_updated_p = 1;
4143 update_single_window (w, 1);
4145 /* Restore original current buffer. */
4146 set_buffer_internal_1 (old_buffer);
4147 windows_or_buffers_changed = old_windows_or_buffers_changed;
4149 start_timer:
4150 /* Let the tip disappear after timeout seconds. */
4151 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
4152 intern ("x-hide-tip"));
4154 UNGCPRO;
4155 return unbind_to (count, Qnil);
4159 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
4160 doc: /* Hide the current tooltip window, if there is any.
4161 Value is t if tooltip was open, nil otherwise. */)
4164 int count;
4165 Lisp_Object deleted, frame, timer;
4166 struct gcpro gcpro1, gcpro2;
4168 /* Return quickly if nothing to do. */
4169 if (NILP (tip_timer) && NILP (tip_frame))
4170 return Qnil;
4172 frame = tip_frame;
4173 timer = tip_timer;
4174 GCPRO2 (frame, timer);
4175 tip_frame = tip_timer = deleted = Qnil;
4177 count = SPECPDL_INDEX ();
4178 specbind (Qinhibit_redisplay, Qt);
4179 specbind (Qinhibit_quit, Qt);
4181 if (!NILP (timer))
4182 call1 (Qcancel_timer, timer);
4184 if (FRAMEP (frame))
4186 Fdelete_frame (frame, Qnil);
4187 deleted = Qt;
4190 UNGCPRO;
4191 return unbind_to (count, deleted);
4196 /***********************************************************************
4197 File selection dialog
4198 ***********************************************************************/
4200 #if TARGET_API_MAC_CARBON
4201 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
4202 doc: /* Read file name, prompting with PROMPT in directory DIR.
4203 Use a file selection dialog.
4204 Select DEFAULT-FILENAME in the dialog's file selection box, if
4205 specified. Ensure that file exists if MUSTMATCH is non-nil.
4206 If ONLY-DIR-P is non-nil, the user can only select directories. */)
4207 (prompt, dir, default_filename, mustmatch, only_dir_p)
4208 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
4210 return mac_file_dialog (prompt, dir, default_filename, mustmatch, only_dir_p);
4212 #endif
4215 /***********************************************************************
4216 Fonts
4217 ***********************************************************************/
4219 DEFUN ("mac-clear-font-name-table", Fmac_clear_font_name_table,
4220 Smac_clear_font_name_table, 0, 0, 0,
4221 doc: /* Clear the font name table. */)
4224 check_mac ();
4225 mac_clear_font_name_table ();
4226 return Qnil;
4229 #if USE_MAC_FONT_PANEL
4230 DEFUN ("mac-set-font-panel-visible-p", Fmac_set_font_panel_visible_p,
4231 Smac_set_font_panel_visible_p, 1, 1, 0,
4232 doc: /* Make the font panel visible if and only if FLAG is non-nil.
4233 This is for internal use only. Use `mac-font-panel-mode' instead. */)
4234 (flag)
4235 Lisp_Object flag;
4237 OSStatus err = noErr;
4239 check_mac ();
4241 BLOCK_INPUT;
4242 if (NILP (flag) != !mac_font_panel_visible_p ())
4244 err = mac_show_hide_font_panel ();
4245 if (err == noErr && !NILP (flag))
4247 Lisp_Object focus_frame = x_get_focus_frame (SELECTED_FRAME ());
4248 struct frame *f = (NILP (focus_frame) ? SELECTED_FRAME ()
4249 : XFRAME (focus_frame));
4251 mac_set_font_info_for_selection (f, DEFAULT_FACE_ID, 0);
4254 UNBLOCK_INPUT;
4256 if (err != noErr)
4257 error ("Cannot change visibility of the font panel");
4258 return Qnil;
4260 #endif
4262 #if USE_ATSUI
4263 extern Lisp_Object mac_atsu_font_face_attributes P_ ((ATSUFontID));
4265 DEFUN ("mac-atsu-font-face-attributes", Fmac_atsu_font_face_attributes,
4266 Smac_atsu_font_face_attributes, 1, 1, 0,
4267 doc: /* Return plist of face attributes and values for ATSU font ID.
4268 ID is specified by either an integer or a float. */)
4269 (id)
4270 Lisp_Object id;
4272 ATSUFontID font_id;
4273 Lisp_Object result;
4275 check_mac ();
4276 CHECK_NUMBER_OR_FLOAT (id);
4277 font_id = INTEGERP (id) ? XINT (id) : XFLOAT_DATA (id);
4278 BLOCK_INPUT;
4279 result = mac_atsu_font_face_attributes (font_id);
4280 UNBLOCK_INPUT;
4281 return result;
4283 #endif
4286 /***********************************************************************
4287 Initialization
4288 ***********************************************************************/
4290 /* Keep this list in the same order as frame_parms in frame.c.
4291 Use 0 for unsupported frame parameters. */
4293 frame_parm_handler mac_frame_parm_handlers[] =
4295 x_set_autoraise,
4296 x_set_autolower,
4297 x_set_background_color,
4298 x_set_border_color,
4299 x_set_border_width,
4300 x_set_cursor_color,
4301 x_set_cursor_type,
4302 mac_set_font,
4303 x_set_foreground_color,
4304 x_set_icon_name,
4305 0, /* MAC_TODO: x_set_icon_type, */
4306 x_set_internal_border_width,
4307 x_set_menu_bar_lines,
4308 x_set_mouse_color,
4309 x_explicitly_set_name,
4310 x_set_scroll_bar_width,
4311 x_set_title,
4312 x_set_unsplittable,
4313 x_set_vertical_scroll_bars,
4314 x_set_visibility,
4315 x_set_tool_bar_lines,
4316 0, /* MAC_TODO: x_set_scroll_bar_foreground, */
4317 0, /* MAC_TODO: x_set_scroll_bar_background, */
4318 x_set_screen_gamma,
4319 x_set_line_spacing,
4320 x_set_fringe_width,
4321 x_set_fringe_width,
4322 0, /* x_set_wait_for_wm, */
4323 x_set_fullscreen,
4324 0, /* x_set_font_backend, */
4325 0 /* x_set_alpha, */
4328 void
4329 syms_of_macfns ()
4331 #ifdef MAC_OSX
4332 /* This is zero if not using Mac native windows. */
4333 mac_in_use = 0;
4334 #else
4335 /* Certainly running on Mac native windows. */
4336 mac_in_use = 1;
4337 #endif
4339 /* The section below is built by the lisp expression at the top of the file,
4340 just above where these variables are declared. */
4341 /*&&& init symbols here &&&*/
4342 Qnone = intern ("none");
4343 staticpro (&Qnone);
4344 Qsuppress_icon = intern ("suppress-icon");
4345 staticpro (&Qsuppress_icon);
4346 Qundefined_color = intern ("undefined-color");
4347 staticpro (&Qundefined_color);
4348 Qcancel_timer = intern ("cancel-timer");
4349 staticpro (&Qcancel_timer);
4350 /* This is the end of symbol initialization. */
4352 /* Text property `display' should be nonsticky by default. */
4353 Vtext_property_default_nonsticky
4354 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
4357 Fput (Qundefined_color, Qerror_conditions,
4358 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
4359 Fput (Qundefined_color, Qerror_message,
4360 build_string ("Undefined color"));
4362 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
4363 doc: /* The shape of the pointer when over text.
4364 Changing the value does not affect existing frames
4365 unless you set the mouse color. */);
4366 Vx_pointer_shape = Qnil;
4368 #if 0 /* This doesn't really do anything. */
4369 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
4370 doc: /* The shape of the pointer when not over text.
4371 This variable takes effect when you create a new frame
4372 or when you set the mouse color. */);
4373 #endif
4374 Vx_nontext_pointer_shape = Qnil;
4376 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
4377 doc: /* The shape of the pointer when Emacs is busy.
4378 This variable takes effect when you create a new frame
4379 or when you set the mouse color. */);
4380 Vx_hourglass_pointer_shape = Qnil;
4382 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
4383 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
4384 display_hourglass_p = 1;
4386 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
4387 doc: /* *Seconds to wait before displaying an hourglass pointer.
4388 Value must be an integer or float. */);
4389 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
4391 #if 0 /* This doesn't really do anything. */
4392 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
4393 doc: /* The shape of the pointer when over the mode line.
4394 This variable takes effect when you create a new frame
4395 or when you set the mouse color. */);
4396 #endif
4397 Vx_mode_pointer_shape = Qnil;
4399 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
4400 &Vx_sensitive_text_pointer_shape,
4401 doc: /* The shape of the pointer when over mouse-sensitive text.
4402 This variable takes effect when you create a new frame
4403 or when you set the mouse color. */);
4404 Vx_sensitive_text_pointer_shape = Qnil;
4406 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
4407 &Vx_window_horizontal_drag_shape,
4408 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
4409 This variable takes effect when you create a new frame
4410 or when you set the mouse color. */);
4411 Vx_window_horizontal_drag_shape = Qnil;
4413 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
4414 doc: /* A string indicating the foreground color of the cursor box. */);
4415 Vx_cursor_fore_pixel = Qnil;
4417 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
4418 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
4419 Text larger than this is clipped. */);
4420 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
4422 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
4423 doc: /* Non-nil if no window manager is in use.
4424 Emacs doesn't try to figure this out; this is always nil
4425 unless you set it to something else. */);
4426 /* We don't have any way to find this out, so set it to nil
4427 and maybe the user would like to set it to t. */
4428 Vx_no_window_manager = Qnil;
4430 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
4431 &Vx_pixel_size_width_font_regexp,
4432 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
4434 Since Emacs gets width of a font matching with this regexp from
4435 PIXEL_SIZE field of the name, font finding mechanism gets faster for
4436 such a font. This is especially effective for such large fonts as
4437 Chinese, Japanese, and Korean. */);
4438 Vx_pixel_size_width_font_regexp = Qnil;
4440 #if TARGET_API_MAC_CARBON
4441 DEFVAR_LISP ("mac-carbon-version-string", &Vmac_carbon_version_string,
4442 doc: /* Version info for Carbon API. */);
4444 OSErr err;
4445 UInt32 response;
4446 char carbon_version[16] = "Unknown";
4448 err = Gestalt (gestaltCarbonVersion, &response);
4449 if (err == noErr)
4450 sprintf (carbon_version, "%u.%u.%u",
4451 (response >> 8) & 0xf, (response >> 4) & 0xf, response & 0xf);
4452 Vmac_carbon_version_string = build_string (carbon_version);
4454 #endif /* TARGET_API_MAC_CARBON */
4456 /* X window properties. */
4457 defsubr (&Sx_change_window_property);
4458 defsubr (&Sx_delete_window_property);
4459 defsubr (&Sx_window_property);
4461 defsubr (&Sxw_display_color_p);
4462 defsubr (&Sx_display_grayscale_p);
4463 defsubr (&Sxw_color_defined_p);
4464 defsubr (&Sxw_color_values);
4465 defsubr (&Sx_server_max_request_size);
4466 defsubr (&Sx_server_vendor);
4467 defsubr (&Sx_server_version);
4468 defsubr (&Sx_display_pixel_width);
4469 defsubr (&Sx_display_pixel_height);
4470 defsubr (&Sx_display_mm_width);
4471 defsubr (&Sx_display_mm_height);
4472 defsubr (&Sx_display_screens);
4473 defsubr (&Sx_display_planes);
4474 defsubr (&Sx_display_color_cells);
4475 defsubr (&Sx_display_visual_class);
4476 defsubr (&Sx_display_backing_store);
4477 defsubr (&Sx_display_save_under);
4478 defsubr (&Sx_create_frame);
4479 defsubr (&Sx_open_connection);
4480 defsubr (&Sx_close_connection);
4481 defsubr (&Sx_display_list);
4482 defsubr (&Sx_synchronize);
4483 defsubr (&Sx_focus_frame);
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 = mac_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
4515 defsubr (&Smac_clear_font_name_table);
4516 #if USE_MAC_FONT_PANEL
4517 defsubr (&Smac_set_font_panel_visible_p);
4518 #endif
4519 #if USE_ATSUI
4520 defsubr (&Smac_atsu_font_face_attributes);
4521 #endif
4524 /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc
4525 (do not change this comment) */