*** empty log message ***
[emacs.git] / src / macfns.c
blobd66c56e6d84e80ece2d20d6c914345909b07f2b6
1 /* Graphical user interface functions for Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 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, or (at your option)
10 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; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* Contributed by Andrew Choi (akochoi@mac.com). */
24 #include <config.h>
25 #include <stdio.h>
26 #include <math.h>
28 #include "lisp.h"
29 #include "macterm.h"
30 #include "frame.h"
31 #include "window.h"
32 #include "buffer.h"
33 #include "intervals.h"
34 #include "dispextern.h"
35 #include "keyboard.h"
36 #include "blockinput.h"
37 #include <epaths.h>
38 #include "charset.h"
39 #include "coding.h"
40 #include "fontset.h"
41 #include "systime.h"
42 #include "termhooks.h"
43 #include "atimer.h"
45 #include <ctype.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <limits.h>
49 #include <errno.h>
50 #include <sys/param.h>
52 extern void free_frame_menubar ();
54 #if TARGET_API_MAC_CARBON
56 /* Carbon version info */
58 static Lisp_Object Vmac_carbon_version_string;
60 #endif /* TARGET_API_MAC_CARBON */
62 /* Non-zero means we're allowed to display an hourglass cursor. */
64 int display_hourglass_p;
66 /* The background and shape of the mouse pointer, and shape when not
67 over text or in the modeline. */
69 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
70 Lisp_Object Vx_hourglass_pointer_shape;
72 /* The shape when over mouse-sensitive text. */
74 Lisp_Object Vx_sensitive_text_pointer_shape;
76 /* If non-nil, the pointer shape to indicate that windows can be
77 dragged horizontally. */
79 Lisp_Object Vx_window_horizontal_drag_shape;
81 /* Color of chars displayed in cursor box. */
83 Lisp_Object Vx_cursor_fore_pixel;
85 /* Nonzero if using Windows. */
87 static int mac_in_use;
89 /* Non nil if no window manager is in use. */
91 Lisp_Object Vx_no_window_manager;
93 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
95 Lisp_Object Vx_pixel_size_width_font_regexp;
97 Lisp_Object Qnone;
98 Lisp_Object Qsuppress_icon;
99 Lisp_Object Qundefined_color;
100 Lisp_Object Qcancel_timer;
102 /* In dispnew.c */
104 extern Lisp_Object Vwindow_system_version;
106 #if GLYPH_DEBUG
107 int image_cache_refcount, dpyinfo_refcount;
108 #endif
111 #if 0 /* Use xstricmp instead. */
112 /* compare two strings ignoring case */
114 static int
115 stricmp (const char *s, const char *t)
117 for ( ; tolower (*s) == tolower (*t); s++, t++)
118 if (*s == '\0')
119 return 0;
120 return tolower (*s) - tolower (*t);
122 #endif
124 /* compare two strings up to n characters, ignoring case */
126 static int
127 strnicmp (const char *s, const char *t, unsigned int n)
129 for ( ; n > 0 && tolower (*s) == tolower (*t); n--, s++, t++)
130 if (*s == '\0')
131 return 0;
132 return n == 0 ? 0 : tolower (*s) - tolower (*t);
136 /* Error if we are not running on Mac OS. */
138 void
139 check_mac ()
141 if (! mac_in_use)
142 error ("Mac native windows not in use or not initialized");
145 /* Nonzero if we can use mouse menus.
146 You should not call this unless HAVE_MENUS is defined. */
149 have_menus_p ()
151 return mac_in_use;
154 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
155 and checking validity for Mac. */
157 FRAME_PTR
158 check_x_frame (frame)
159 Lisp_Object frame;
161 FRAME_PTR f;
163 if (NILP (frame))
164 frame = selected_frame;
165 CHECK_LIVE_FRAME (frame);
166 f = XFRAME (frame);
167 if (! FRAME_MAC_P (f))
168 error ("Non-Mac frame used");
169 return f;
172 /* Let the user specify a display with a frame.
173 nil stands for the selected frame--or, if that is not a mac frame,
174 the first display on the list. */
176 struct mac_display_info *
177 check_x_display_info (frame)
178 Lisp_Object frame;
180 struct mac_display_info *dpyinfo = NULL;
182 if (NILP (frame))
184 struct frame *sf = XFRAME (selected_frame);
186 if (FRAME_MAC_P (sf) && FRAME_LIVE_P (sf))
187 dpyinfo = FRAME_MAC_DISPLAY_INFO (sf);
188 else if (x_display_list != 0)
189 dpyinfo = x_display_list;
190 else
191 error ("Mac native windows are not in use or not initialized");
193 else if (STRINGP (frame))
194 dpyinfo = x_display_info_for_name (frame);
195 else
197 FRAME_PTR f = check_x_frame (frame);
198 dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
201 return dpyinfo;
206 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
207 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
209 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
210 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
211 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
212 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
213 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
214 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
215 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
216 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
217 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
218 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
219 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
220 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
223 /* Store the screen positions of frame F into XPTR and YPTR.
224 These are the positions of the containing window manager window,
225 not Emacs's own window. */
227 void
228 x_real_positions (f, xptr, yptr)
229 FRAME_PTR f;
230 int *xptr, *yptr;
232 Rect inner, outer;
234 mac_get_window_bounds (f, &inner, &outer);
236 f->x_pixels_diff = inner.left - outer.left;
237 f->y_pixels_diff = inner.top - outer.top;
239 *xptr = outer.left;
240 *yptr = outer.top;
244 /* The default colors for the Mac color map */
245 typedef struct colormap_t
247 unsigned long color;
248 char *name;
249 } colormap_t;
251 static const colormap_t mac_color_map[] =
253 { RGB_TO_ULONG(255, 250, 250), "snow" },
254 { RGB_TO_ULONG(248, 248, 255), "ghost white" },
255 { RGB_TO_ULONG(248, 248, 255), "GhostWhite" },
256 { RGB_TO_ULONG(245, 245, 245), "white smoke" },
257 { RGB_TO_ULONG(245, 245, 245), "WhiteSmoke" },
258 { RGB_TO_ULONG(220, 220, 220), "gainsboro" },
259 { RGB_TO_ULONG(255, 250, 240), "floral white" },
260 { RGB_TO_ULONG(255, 250, 240), "FloralWhite" },
261 { RGB_TO_ULONG(253, 245, 230), "old lace" },
262 { RGB_TO_ULONG(253, 245, 230), "OldLace" },
263 { RGB_TO_ULONG(250, 240, 230), "linen" },
264 { RGB_TO_ULONG(250, 235, 215), "antique white" },
265 { RGB_TO_ULONG(250, 235, 215), "AntiqueWhite" },
266 { RGB_TO_ULONG(255, 239, 213), "papaya whip" },
267 { RGB_TO_ULONG(255, 239, 213), "PapayaWhip" },
268 { RGB_TO_ULONG(255, 235, 205), "blanched almond" },
269 { RGB_TO_ULONG(255, 235, 205), "BlanchedAlmond" },
270 { RGB_TO_ULONG(255, 228, 196), "bisque" },
271 { RGB_TO_ULONG(255, 218, 185), "peach puff" },
272 { RGB_TO_ULONG(255, 218, 185), "PeachPuff" },
273 { RGB_TO_ULONG(255, 222, 173), "navajo white" },
274 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite" },
275 { RGB_TO_ULONG(255, 228, 181), "moccasin" },
276 { RGB_TO_ULONG(255, 248, 220), "cornsilk" },
277 { RGB_TO_ULONG(255, 255, 240), "ivory" },
278 { RGB_TO_ULONG(255, 250, 205), "lemon chiffon" },
279 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon" },
280 { RGB_TO_ULONG(255, 245, 238), "seashell" },
281 { RGB_TO_ULONG(240, 255, 240), "honeydew" },
282 { RGB_TO_ULONG(245, 255, 250), "mint cream" },
283 { RGB_TO_ULONG(245, 255, 250), "MintCream" },
284 { RGB_TO_ULONG(240, 255, 255), "azure" },
285 { RGB_TO_ULONG(240, 248, 255), "alice blue" },
286 { RGB_TO_ULONG(240, 248, 255), "AliceBlue" },
287 { RGB_TO_ULONG(230, 230, 250), "lavender" },
288 { RGB_TO_ULONG(255, 240, 245), "lavender blush" },
289 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush" },
290 { RGB_TO_ULONG(255, 228, 225), "misty rose" },
291 { RGB_TO_ULONG(255, 228, 225), "MistyRose" },
292 { RGB_TO_ULONG(255, 255, 255), "white" },
293 { RGB_TO_ULONG(0 , 0 , 0 ), "black" },
294 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate gray" },
295 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGray" },
296 { RGB_TO_ULONG(47 , 79 , 79 ), "dark slate grey" },
297 { RGB_TO_ULONG(47 , 79 , 79 ), "DarkSlateGrey" },
298 { RGB_TO_ULONG(105, 105, 105), "dim gray" },
299 { RGB_TO_ULONG(105, 105, 105), "DimGray" },
300 { RGB_TO_ULONG(105, 105, 105), "dim grey" },
301 { RGB_TO_ULONG(105, 105, 105), "DimGrey" },
302 { RGB_TO_ULONG(112, 128, 144), "slate gray" },
303 { RGB_TO_ULONG(112, 128, 144), "SlateGray" },
304 { RGB_TO_ULONG(112, 128, 144), "slate grey" },
305 { RGB_TO_ULONG(112, 128, 144), "SlateGrey" },
306 { RGB_TO_ULONG(119, 136, 153), "light slate gray" },
307 { RGB_TO_ULONG(119, 136, 153), "LightSlateGray" },
308 { RGB_TO_ULONG(119, 136, 153), "light slate grey" },
309 { RGB_TO_ULONG(119, 136, 153), "LightSlateGrey" },
310 { RGB_TO_ULONG(190, 190, 190), "gray" },
311 { RGB_TO_ULONG(190, 190, 190), "grey" },
312 { RGB_TO_ULONG(211, 211, 211), "light grey" },
313 { RGB_TO_ULONG(211, 211, 211), "LightGrey" },
314 { RGB_TO_ULONG(211, 211, 211), "light gray" },
315 { RGB_TO_ULONG(211, 211, 211), "LightGray" },
316 { RGB_TO_ULONG(25 , 25 , 112), "midnight blue" },
317 { RGB_TO_ULONG(25 , 25 , 112), "MidnightBlue" },
318 { RGB_TO_ULONG(0 , 0 , 128), "navy" },
319 { RGB_TO_ULONG(0 , 0 , 128), "navy blue" },
320 { RGB_TO_ULONG(0 , 0 , 128), "NavyBlue" },
321 { RGB_TO_ULONG(100, 149, 237), "cornflower blue" },
322 { RGB_TO_ULONG(100, 149, 237), "CornflowerBlue" },
323 { RGB_TO_ULONG(72 , 61 , 139), "dark slate blue" },
324 { RGB_TO_ULONG(72 , 61 , 139), "DarkSlateBlue" },
325 { RGB_TO_ULONG(106, 90 , 205), "slate blue" },
326 { RGB_TO_ULONG(106, 90 , 205), "SlateBlue" },
327 { RGB_TO_ULONG(123, 104, 238), "medium slate blue" },
328 { RGB_TO_ULONG(123, 104, 238), "MediumSlateBlue" },
329 { RGB_TO_ULONG(132, 112, 255), "light slate blue" },
330 { RGB_TO_ULONG(132, 112, 255), "LightSlateBlue" },
331 { RGB_TO_ULONG(0 , 0 , 205), "medium blue" },
332 { RGB_TO_ULONG(0 , 0 , 205), "MediumBlue" },
333 { RGB_TO_ULONG(65 , 105, 225), "royal blue" },
334 { RGB_TO_ULONG(65 , 105, 225), "RoyalBlue" },
335 { RGB_TO_ULONG(0 , 0 , 255), "blue" },
336 { RGB_TO_ULONG(30 , 144, 255), "dodger blue" },
337 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue" },
338 { RGB_TO_ULONG(0 , 191, 255), "deep sky blue" },
339 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue" },
340 { RGB_TO_ULONG(135, 206, 235), "sky blue" },
341 { RGB_TO_ULONG(135, 206, 235), "SkyBlue" },
342 { RGB_TO_ULONG(135, 206, 250), "light sky blue" },
343 { RGB_TO_ULONG(135, 206, 250), "LightSkyBlue" },
344 { RGB_TO_ULONG(70 , 130, 180), "steel blue" },
345 { RGB_TO_ULONG(70 , 130, 180), "SteelBlue" },
346 { RGB_TO_ULONG(176, 196, 222), "light steel blue" },
347 { RGB_TO_ULONG(176, 196, 222), "LightSteelBlue" },
348 { RGB_TO_ULONG(173, 216, 230), "light blue" },
349 { RGB_TO_ULONG(173, 216, 230), "LightBlue" },
350 { RGB_TO_ULONG(176, 224, 230), "powder blue" },
351 { RGB_TO_ULONG(176, 224, 230), "PowderBlue" },
352 { RGB_TO_ULONG(175, 238, 238), "pale turquoise" },
353 { RGB_TO_ULONG(175, 238, 238), "PaleTurquoise" },
354 { RGB_TO_ULONG(0 , 206, 209), "dark turquoise" },
355 { RGB_TO_ULONG(0 , 206, 209), "DarkTurquoise" },
356 { RGB_TO_ULONG(72 , 209, 204), "medium turquoise" },
357 { RGB_TO_ULONG(72 , 209, 204), "MediumTurquoise" },
358 { RGB_TO_ULONG(64 , 224, 208), "turquoise" },
359 { RGB_TO_ULONG(0 , 255, 255), "cyan" },
360 { RGB_TO_ULONG(224, 255, 255), "light cyan" },
361 { RGB_TO_ULONG(224, 255, 255), "LightCyan" },
362 { RGB_TO_ULONG(95 , 158, 160), "cadet blue" },
363 { RGB_TO_ULONG(95 , 158, 160), "CadetBlue" },
364 { RGB_TO_ULONG(102, 205, 170), "medium aquamarine" },
365 { RGB_TO_ULONG(102, 205, 170), "MediumAquamarine" },
366 { RGB_TO_ULONG(127, 255, 212), "aquamarine" },
367 { RGB_TO_ULONG(0 , 100, 0 ), "dark green" },
368 { RGB_TO_ULONG(0 , 100, 0 ), "DarkGreen" },
369 { RGB_TO_ULONG(85 , 107, 47 ), "dark olive green" },
370 { RGB_TO_ULONG(85 , 107, 47 ), "DarkOliveGreen" },
371 { RGB_TO_ULONG(143, 188, 143), "dark sea green" },
372 { RGB_TO_ULONG(143, 188, 143), "DarkSeaGreen" },
373 { RGB_TO_ULONG(46 , 139, 87 ), "sea green" },
374 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen" },
375 { RGB_TO_ULONG(60 , 179, 113), "medium sea green" },
376 { RGB_TO_ULONG(60 , 179, 113), "MediumSeaGreen" },
377 { RGB_TO_ULONG(32 , 178, 170), "light sea green" },
378 { RGB_TO_ULONG(32 , 178, 170), "LightSeaGreen" },
379 { RGB_TO_ULONG(152, 251, 152), "pale green" },
380 { RGB_TO_ULONG(152, 251, 152), "PaleGreen" },
381 { RGB_TO_ULONG(0 , 255, 127), "spring green" },
382 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen" },
383 { RGB_TO_ULONG(124, 252, 0 ), "lawn green" },
384 { RGB_TO_ULONG(124, 252, 0 ), "LawnGreen" },
385 { RGB_TO_ULONG(0 , 255, 0 ), "green" },
386 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse" },
387 { RGB_TO_ULONG(0 , 250, 154), "medium spring green" },
388 { RGB_TO_ULONG(0 , 250, 154), "MediumSpringGreen" },
389 { RGB_TO_ULONG(173, 255, 47 ), "green yellow" },
390 { RGB_TO_ULONG(173, 255, 47 ), "GreenYellow" },
391 { RGB_TO_ULONG(50 , 205, 50 ), "lime green" },
392 { RGB_TO_ULONG(50 , 205, 50 ), "LimeGreen" },
393 { RGB_TO_ULONG(154, 205, 50 ), "yellow green" },
394 { RGB_TO_ULONG(154, 205, 50 ), "YellowGreen" },
395 { RGB_TO_ULONG(34 , 139, 34 ), "forest green" },
396 { RGB_TO_ULONG(34 , 139, 34 ), "ForestGreen" },
397 { RGB_TO_ULONG(107, 142, 35 ), "olive drab" },
398 { RGB_TO_ULONG(107, 142, 35 ), "OliveDrab" },
399 { RGB_TO_ULONG(189, 183, 107), "dark khaki" },
400 { RGB_TO_ULONG(189, 183, 107), "DarkKhaki" },
401 { RGB_TO_ULONG(240, 230, 140), "khaki" },
402 { RGB_TO_ULONG(238, 232, 170), "pale goldenrod" },
403 { RGB_TO_ULONG(238, 232, 170), "PaleGoldenrod" },
404 { RGB_TO_ULONG(250, 250, 210), "light goldenrod yellow" },
405 { RGB_TO_ULONG(250, 250, 210), "LightGoldenrodYellow" },
406 { RGB_TO_ULONG(255, 255, 224), "light yellow" },
407 { RGB_TO_ULONG(255, 255, 224), "LightYellow" },
408 { RGB_TO_ULONG(255, 255, 0 ), "yellow" },
409 { RGB_TO_ULONG(255, 215, 0 ), "gold" },
410 { RGB_TO_ULONG(238, 221, 130), "light goldenrod" },
411 { RGB_TO_ULONG(238, 221, 130), "LightGoldenrod" },
412 { RGB_TO_ULONG(218, 165, 32 ), "goldenrod" },
413 { RGB_TO_ULONG(184, 134, 11 ), "dark goldenrod" },
414 { RGB_TO_ULONG(184, 134, 11 ), "DarkGoldenrod" },
415 { RGB_TO_ULONG(188, 143, 143), "rosy brown" },
416 { RGB_TO_ULONG(188, 143, 143), "RosyBrown" },
417 { RGB_TO_ULONG(205, 92 , 92 ), "indian red" },
418 { RGB_TO_ULONG(205, 92 , 92 ), "IndianRed" },
419 { RGB_TO_ULONG(139, 69 , 19 ), "saddle brown" },
420 { RGB_TO_ULONG(139, 69 , 19 ), "SaddleBrown" },
421 { RGB_TO_ULONG(160, 82 , 45 ), "sienna" },
422 { RGB_TO_ULONG(205, 133, 63 ), "peru" },
423 { RGB_TO_ULONG(222, 184, 135), "burlywood" },
424 { RGB_TO_ULONG(245, 245, 220), "beige" },
425 { RGB_TO_ULONG(245, 222, 179), "wheat" },
426 { RGB_TO_ULONG(244, 164, 96 ), "sandy brown" },
427 { RGB_TO_ULONG(244, 164, 96 ), "SandyBrown" },
428 { RGB_TO_ULONG(210, 180, 140), "tan" },
429 { RGB_TO_ULONG(210, 105, 30 ), "chocolate" },
430 { RGB_TO_ULONG(178, 34 , 34 ), "firebrick" },
431 { RGB_TO_ULONG(165, 42 , 42 ), "brown" },
432 { RGB_TO_ULONG(233, 150, 122), "dark salmon" },
433 { RGB_TO_ULONG(233, 150, 122), "DarkSalmon" },
434 { RGB_TO_ULONG(250, 128, 114), "salmon" },
435 { RGB_TO_ULONG(255, 160, 122), "light salmon" },
436 { RGB_TO_ULONG(255, 160, 122), "LightSalmon" },
437 { RGB_TO_ULONG(255, 165, 0 ), "orange" },
438 { RGB_TO_ULONG(255, 140, 0 ), "dark orange" },
439 { RGB_TO_ULONG(255, 140, 0 ), "DarkOrange" },
440 { RGB_TO_ULONG(255, 127, 80 ), "coral" },
441 { RGB_TO_ULONG(240, 128, 128), "light coral" },
442 { RGB_TO_ULONG(240, 128, 128), "LightCoral" },
443 { RGB_TO_ULONG(255, 99 , 71 ), "tomato" },
444 { RGB_TO_ULONG(255, 69 , 0 ), "orange red" },
445 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed" },
446 { RGB_TO_ULONG(255, 0 , 0 ), "red" },
447 { RGB_TO_ULONG(255, 105, 180), "hot pink" },
448 { RGB_TO_ULONG(255, 105, 180), "HotPink" },
449 { RGB_TO_ULONG(255, 20 , 147), "deep pink" },
450 { RGB_TO_ULONG(255, 20 , 147), "DeepPink" },
451 { RGB_TO_ULONG(255, 192, 203), "pink" },
452 { RGB_TO_ULONG(255, 182, 193), "light pink" },
453 { RGB_TO_ULONG(255, 182, 193), "LightPink" },
454 { RGB_TO_ULONG(219, 112, 147), "pale violet red" },
455 { RGB_TO_ULONG(219, 112, 147), "PaleVioletRed" },
456 { RGB_TO_ULONG(176, 48 , 96 ), "maroon" },
457 { RGB_TO_ULONG(199, 21 , 133), "medium violet red" },
458 { RGB_TO_ULONG(199, 21 , 133), "MediumVioletRed" },
459 { RGB_TO_ULONG(208, 32 , 144), "violet red" },
460 { RGB_TO_ULONG(208, 32 , 144), "VioletRed" },
461 { RGB_TO_ULONG(255, 0 , 255), "magenta" },
462 { RGB_TO_ULONG(238, 130, 238), "violet" },
463 { RGB_TO_ULONG(221, 160, 221), "plum" },
464 { RGB_TO_ULONG(218, 112, 214), "orchid" },
465 { RGB_TO_ULONG(186, 85 , 211), "medium orchid" },
466 { RGB_TO_ULONG(186, 85 , 211), "MediumOrchid" },
467 { RGB_TO_ULONG(153, 50 , 204), "dark orchid" },
468 { RGB_TO_ULONG(153, 50 , 204), "DarkOrchid" },
469 { RGB_TO_ULONG(148, 0 , 211), "dark violet" },
470 { RGB_TO_ULONG(148, 0 , 211), "DarkViolet" },
471 { RGB_TO_ULONG(138, 43 , 226), "blue violet" },
472 { RGB_TO_ULONG(138, 43 , 226), "BlueViolet" },
473 { RGB_TO_ULONG(160, 32 , 240), "purple" },
474 { RGB_TO_ULONG(147, 112, 219), "medium purple" },
475 { RGB_TO_ULONG(147, 112, 219), "MediumPurple" },
476 { RGB_TO_ULONG(216, 191, 216), "thistle" },
477 { RGB_TO_ULONG(255, 250, 250), "snow1" },
478 { RGB_TO_ULONG(238, 233, 233), "snow2" },
479 { RGB_TO_ULONG(205, 201, 201), "snow3" },
480 { RGB_TO_ULONG(139, 137, 137), "snow4" },
481 { RGB_TO_ULONG(255, 245, 238), "seashell1" },
482 { RGB_TO_ULONG(238, 229, 222), "seashell2" },
483 { RGB_TO_ULONG(205, 197, 191), "seashell3" },
484 { RGB_TO_ULONG(139, 134, 130), "seashell4" },
485 { RGB_TO_ULONG(255, 239, 219), "AntiqueWhite1" },
486 { RGB_TO_ULONG(238, 223, 204), "AntiqueWhite2" },
487 { RGB_TO_ULONG(205, 192, 176), "AntiqueWhite3" },
488 { RGB_TO_ULONG(139, 131, 120), "AntiqueWhite4" },
489 { RGB_TO_ULONG(255, 228, 196), "bisque1" },
490 { RGB_TO_ULONG(238, 213, 183), "bisque2" },
491 { RGB_TO_ULONG(205, 183, 158), "bisque3" },
492 { RGB_TO_ULONG(139, 125, 107), "bisque4" },
493 { RGB_TO_ULONG(255, 218, 185), "PeachPuff1" },
494 { RGB_TO_ULONG(238, 203, 173), "PeachPuff2" },
495 { RGB_TO_ULONG(205, 175, 149), "PeachPuff3" },
496 { RGB_TO_ULONG(139, 119, 101), "PeachPuff4" },
497 { RGB_TO_ULONG(255, 222, 173), "NavajoWhite1" },
498 { RGB_TO_ULONG(238, 207, 161), "NavajoWhite2" },
499 { RGB_TO_ULONG(205, 179, 139), "NavajoWhite3" },
500 { RGB_TO_ULONG(139, 121, 94), "NavajoWhite4" },
501 { RGB_TO_ULONG(255, 250, 205), "LemonChiffon1" },
502 { RGB_TO_ULONG(238, 233, 191), "LemonChiffon2" },
503 { RGB_TO_ULONG(205, 201, 165), "LemonChiffon3" },
504 { RGB_TO_ULONG(139, 137, 112), "LemonChiffon4" },
505 { RGB_TO_ULONG(255, 248, 220), "cornsilk1" },
506 { RGB_TO_ULONG(238, 232, 205), "cornsilk2" },
507 { RGB_TO_ULONG(205, 200, 177), "cornsilk3" },
508 { RGB_TO_ULONG(139, 136, 120), "cornsilk4" },
509 { RGB_TO_ULONG(255, 255, 240), "ivory1" },
510 { RGB_TO_ULONG(238, 238, 224), "ivory2" },
511 { RGB_TO_ULONG(205, 205, 193), "ivory3" },
512 { RGB_TO_ULONG(139, 139, 131), "ivory4" },
513 { RGB_TO_ULONG(240, 255, 240), "honeydew1" },
514 { RGB_TO_ULONG(224, 238, 224), "honeydew2" },
515 { RGB_TO_ULONG(193, 205, 193), "honeydew3" },
516 { RGB_TO_ULONG(131, 139, 131), "honeydew4" },
517 { RGB_TO_ULONG(255, 240, 245), "LavenderBlush1" },
518 { RGB_TO_ULONG(238, 224, 229), "LavenderBlush2" },
519 { RGB_TO_ULONG(205, 193, 197), "LavenderBlush3" },
520 { RGB_TO_ULONG(139, 131, 134), "LavenderBlush4" },
521 { RGB_TO_ULONG(255, 228, 225), "MistyRose1" },
522 { RGB_TO_ULONG(238, 213, 210), "MistyRose2" },
523 { RGB_TO_ULONG(205, 183, 181), "MistyRose3" },
524 { RGB_TO_ULONG(139, 125, 123), "MistyRose4" },
525 { RGB_TO_ULONG(240, 255, 255), "azure1" },
526 { RGB_TO_ULONG(224, 238, 238), "azure2" },
527 { RGB_TO_ULONG(193, 205, 205), "azure3" },
528 { RGB_TO_ULONG(131, 139, 139), "azure4" },
529 { RGB_TO_ULONG(131, 111, 255), "SlateBlue1" },
530 { RGB_TO_ULONG(122, 103, 238), "SlateBlue2" },
531 { RGB_TO_ULONG(105, 89 , 205), "SlateBlue3" },
532 { RGB_TO_ULONG(71 , 60 , 139), "SlateBlue4" },
533 { RGB_TO_ULONG(72 , 118, 255), "RoyalBlue1" },
534 { RGB_TO_ULONG(67 , 110, 238), "RoyalBlue2" },
535 { RGB_TO_ULONG(58 , 95 , 205), "RoyalBlue3" },
536 { RGB_TO_ULONG(39 , 64 , 139), "RoyalBlue4" },
537 { RGB_TO_ULONG(0 , 0 , 255), "blue1" },
538 { RGB_TO_ULONG(0 , 0 , 238), "blue2" },
539 { RGB_TO_ULONG(0 , 0 , 205), "blue3" },
540 { RGB_TO_ULONG(0 , 0 , 139), "blue4" },
541 { RGB_TO_ULONG(30 , 144, 255), "DodgerBlue1" },
542 { RGB_TO_ULONG(28 , 134, 238), "DodgerBlue2" },
543 { RGB_TO_ULONG(24 , 116, 205), "DodgerBlue3" },
544 { RGB_TO_ULONG(16 , 78 , 139), "DodgerBlue4" },
545 { RGB_TO_ULONG(99 , 184, 255), "SteelBlue1" },
546 { RGB_TO_ULONG(92 , 172, 238), "SteelBlue2" },
547 { RGB_TO_ULONG(79 , 148, 205), "SteelBlue3" },
548 { RGB_TO_ULONG(54 , 100, 139), "SteelBlue4" },
549 { RGB_TO_ULONG(0 , 191, 255), "DeepSkyBlue1" },
550 { RGB_TO_ULONG(0 , 178, 238), "DeepSkyBlue2" },
551 { RGB_TO_ULONG(0 , 154, 205), "DeepSkyBlue3" },
552 { RGB_TO_ULONG(0 , 104, 139), "DeepSkyBlue4" },
553 { RGB_TO_ULONG(135, 206, 255), "SkyBlue1" },
554 { RGB_TO_ULONG(126, 192, 238), "SkyBlue2" },
555 { RGB_TO_ULONG(108, 166, 205), "SkyBlue3" },
556 { RGB_TO_ULONG(74 , 112, 139), "SkyBlue4" },
557 { RGB_TO_ULONG(176, 226, 255), "LightSkyBlue1" },
558 { RGB_TO_ULONG(164, 211, 238), "LightSkyBlue2" },
559 { RGB_TO_ULONG(141, 182, 205), "LightSkyBlue3" },
560 { RGB_TO_ULONG(96 , 123, 139), "LightSkyBlue4" },
561 { RGB_TO_ULONG(198, 226, 255), "SlateGray1" },
562 { RGB_TO_ULONG(185, 211, 238), "SlateGray2" },
563 { RGB_TO_ULONG(159, 182, 205), "SlateGray3" },
564 { RGB_TO_ULONG(108, 123, 139), "SlateGray4" },
565 { RGB_TO_ULONG(202, 225, 255), "LightSteelBlue1" },
566 { RGB_TO_ULONG(188, 210, 238), "LightSteelBlue2" },
567 { RGB_TO_ULONG(162, 181, 205), "LightSteelBlue3" },
568 { RGB_TO_ULONG(110, 123, 139), "LightSteelBlue4" },
569 { RGB_TO_ULONG(191, 239, 255), "LightBlue1" },
570 { RGB_TO_ULONG(178, 223, 238), "LightBlue2" },
571 { RGB_TO_ULONG(154, 192, 205), "LightBlue3" },
572 { RGB_TO_ULONG(104, 131, 139), "LightBlue4" },
573 { RGB_TO_ULONG(224, 255, 255), "LightCyan1" },
574 { RGB_TO_ULONG(209, 238, 238), "LightCyan2" },
575 { RGB_TO_ULONG(180, 205, 205), "LightCyan3" },
576 { RGB_TO_ULONG(122, 139, 139), "LightCyan4" },
577 { RGB_TO_ULONG(187, 255, 255), "PaleTurquoise1" },
578 { RGB_TO_ULONG(174, 238, 238), "PaleTurquoise2" },
579 { RGB_TO_ULONG(150, 205, 205), "PaleTurquoise3" },
580 { RGB_TO_ULONG(102, 139, 139), "PaleTurquoise4" },
581 { RGB_TO_ULONG(152, 245, 255), "CadetBlue1" },
582 { RGB_TO_ULONG(142, 229, 238), "CadetBlue2" },
583 { RGB_TO_ULONG(122, 197, 205), "CadetBlue3" },
584 { RGB_TO_ULONG(83 , 134, 139), "CadetBlue4" },
585 { RGB_TO_ULONG(0 , 245, 255), "turquoise1" },
586 { RGB_TO_ULONG(0 , 229, 238), "turquoise2" },
587 { RGB_TO_ULONG(0 , 197, 205), "turquoise3" },
588 { RGB_TO_ULONG(0 , 134, 139), "turquoise4" },
589 { RGB_TO_ULONG(0 , 255, 255), "cyan1" },
590 { RGB_TO_ULONG(0 , 238, 238), "cyan2" },
591 { RGB_TO_ULONG(0 , 205, 205), "cyan3" },
592 { RGB_TO_ULONG(0 , 139, 139), "cyan4" },
593 { RGB_TO_ULONG(151, 255, 255), "DarkSlateGray1" },
594 { RGB_TO_ULONG(141, 238, 238), "DarkSlateGray2" },
595 { RGB_TO_ULONG(121, 205, 205), "DarkSlateGray3" },
596 { RGB_TO_ULONG(82 , 139, 139), "DarkSlateGray4" },
597 { RGB_TO_ULONG(127, 255, 212), "aquamarine1" },
598 { RGB_TO_ULONG(118, 238, 198), "aquamarine2" },
599 { RGB_TO_ULONG(102, 205, 170), "aquamarine3" },
600 { RGB_TO_ULONG(69 , 139, 116), "aquamarine4" },
601 { RGB_TO_ULONG(193, 255, 193), "DarkSeaGreen1" },
602 { RGB_TO_ULONG(180, 238, 180), "DarkSeaGreen2" },
603 { RGB_TO_ULONG(155, 205, 155), "DarkSeaGreen3" },
604 { RGB_TO_ULONG(105, 139, 105), "DarkSeaGreen4" },
605 { RGB_TO_ULONG(84 , 255, 159), "SeaGreen1" },
606 { RGB_TO_ULONG(78 , 238, 148), "SeaGreen2" },
607 { RGB_TO_ULONG(67 , 205, 128), "SeaGreen3" },
608 { RGB_TO_ULONG(46 , 139, 87 ), "SeaGreen4" },
609 { RGB_TO_ULONG(154, 255, 154), "PaleGreen1" },
610 { RGB_TO_ULONG(144, 238, 144), "PaleGreen2" },
611 { RGB_TO_ULONG(124, 205, 124), "PaleGreen3" },
612 { RGB_TO_ULONG(84 , 139, 84 ), "PaleGreen4" },
613 { RGB_TO_ULONG(0 , 255, 127), "SpringGreen1" },
614 { RGB_TO_ULONG(0 , 238, 118), "SpringGreen2" },
615 { RGB_TO_ULONG(0 , 205, 102), "SpringGreen3" },
616 { RGB_TO_ULONG(0 , 139, 69 ), "SpringGreen4" },
617 { RGB_TO_ULONG(0 , 255, 0 ), "green1" },
618 { RGB_TO_ULONG(0 , 238, 0 ), "green2" },
619 { RGB_TO_ULONG(0 , 205, 0 ), "green3" },
620 { RGB_TO_ULONG(0 , 139, 0 ), "green4" },
621 { RGB_TO_ULONG(127, 255, 0 ), "chartreuse1" },
622 { RGB_TO_ULONG(118, 238, 0 ), "chartreuse2" },
623 { RGB_TO_ULONG(102, 205, 0 ), "chartreuse3" },
624 { RGB_TO_ULONG(69 , 139, 0 ), "chartreuse4" },
625 { RGB_TO_ULONG(192, 255, 62 ), "OliveDrab1" },
626 { RGB_TO_ULONG(179, 238, 58 ), "OliveDrab2" },
627 { RGB_TO_ULONG(154, 205, 50 ), "OliveDrab3" },
628 { RGB_TO_ULONG(105, 139, 34 ), "OliveDrab4" },
629 { RGB_TO_ULONG(202, 255, 112), "DarkOliveGreen1" },
630 { RGB_TO_ULONG(188, 238, 104), "DarkOliveGreen2" },
631 { RGB_TO_ULONG(162, 205, 90 ), "DarkOliveGreen3" },
632 { RGB_TO_ULONG(110, 139, 61 ), "DarkOliveGreen4" },
633 { RGB_TO_ULONG(255, 246, 143), "khaki1" },
634 { RGB_TO_ULONG(238, 230, 133), "khaki2" },
635 { RGB_TO_ULONG(205, 198, 115), "khaki3" },
636 { RGB_TO_ULONG(139, 134, 78 ), "khaki4" },
637 { RGB_TO_ULONG(255, 236, 139), "LightGoldenrod1" },
638 { RGB_TO_ULONG(238, 220, 130), "LightGoldenrod2" },
639 { RGB_TO_ULONG(205, 190, 112), "LightGoldenrod3" },
640 { RGB_TO_ULONG(139, 129, 76 ), "LightGoldenrod4" },
641 { RGB_TO_ULONG(255, 255, 224), "LightYellow1" },
642 { RGB_TO_ULONG(238, 238, 209), "LightYellow2" },
643 { RGB_TO_ULONG(205, 205, 180), "LightYellow3" },
644 { RGB_TO_ULONG(139, 139, 122), "LightYellow4" },
645 { RGB_TO_ULONG(255, 255, 0 ), "yellow1" },
646 { RGB_TO_ULONG(238, 238, 0 ), "yellow2" },
647 { RGB_TO_ULONG(205, 205, 0 ), "yellow3" },
648 { RGB_TO_ULONG(139, 139, 0 ), "yellow4" },
649 { RGB_TO_ULONG(255, 215, 0 ), "gold1" },
650 { RGB_TO_ULONG(238, 201, 0 ), "gold2" },
651 { RGB_TO_ULONG(205, 173, 0 ), "gold3" },
652 { RGB_TO_ULONG(139, 117, 0 ), "gold4" },
653 { RGB_TO_ULONG(255, 193, 37 ), "goldenrod1" },
654 { RGB_TO_ULONG(238, 180, 34 ), "goldenrod2" },
655 { RGB_TO_ULONG(205, 155, 29 ), "goldenrod3" },
656 { RGB_TO_ULONG(139, 105, 20 ), "goldenrod4" },
657 { RGB_TO_ULONG(255, 185, 15 ), "DarkGoldenrod1" },
658 { RGB_TO_ULONG(238, 173, 14 ), "DarkGoldenrod2" },
659 { RGB_TO_ULONG(205, 149, 12 ), "DarkGoldenrod3" },
660 { RGB_TO_ULONG(139, 101, 8 ), "DarkGoldenrod4" },
661 { RGB_TO_ULONG(255, 193, 193), "RosyBrown1" },
662 { RGB_TO_ULONG(238, 180, 180), "RosyBrown2" },
663 { RGB_TO_ULONG(205, 155, 155), "RosyBrown3" },
664 { RGB_TO_ULONG(139, 105, 105), "RosyBrown4" },
665 { RGB_TO_ULONG(255, 106, 106), "IndianRed1" },
666 { RGB_TO_ULONG(238, 99 , 99 ), "IndianRed2" },
667 { RGB_TO_ULONG(205, 85 , 85 ), "IndianRed3" },
668 { RGB_TO_ULONG(139, 58 , 58 ), "IndianRed4" },
669 { RGB_TO_ULONG(255, 130, 71 ), "sienna1" },
670 { RGB_TO_ULONG(238, 121, 66 ), "sienna2" },
671 { RGB_TO_ULONG(205, 104, 57 ), "sienna3" },
672 { RGB_TO_ULONG(139, 71 , 38 ), "sienna4" },
673 { RGB_TO_ULONG(255, 211, 155), "burlywood1" },
674 { RGB_TO_ULONG(238, 197, 145), "burlywood2" },
675 { RGB_TO_ULONG(205, 170, 125), "burlywood3" },
676 { RGB_TO_ULONG(139, 115, 85 ), "burlywood4" },
677 { RGB_TO_ULONG(255, 231, 186), "wheat1" },
678 { RGB_TO_ULONG(238, 216, 174), "wheat2" },
679 { RGB_TO_ULONG(205, 186, 150), "wheat3" },
680 { RGB_TO_ULONG(139, 126, 102), "wheat4" },
681 { RGB_TO_ULONG(255, 165, 79 ), "tan1" },
682 { RGB_TO_ULONG(238, 154, 73 ), "tan2" },
683 { RGB_TO_ULONG(205, 133, 63 ), "tan3" },
684 { RGB_TO_ULONG(139, 90 , 43 ), "tan4" },
685 { RGB_TO_ULONG(255, 127, 36 ), "chocolate1" },
686 { RGB_TO_ULONG(238, 118, 33 ), "chocolate2" },
687 { RGB_TO_ULONG(205, 102, 29 ), "chocolate3" },
688 { RGB_TO_ULONG(139, 69 , 19 ), "chocolate4" },
689 { RGB_TO_ULONG(255, 48 , 48 ), "firebrick1" },
690 { RGB_TO_ULONG(238, 44 , 44 ), "firebrick2" },
691 { RGB_TO_ULONG(205, 38 , 38 ), "firebrick3" },
692 { RGB_TO_ULONG(139, 26 , 26 ), "firebrick4" },
693 { RGB_TO_ULONG(255, 64 , 64 ), "brown1" },
694 { RGB_TO_ULONG(238, 59 , 59 ), "brown2" },
695 { RGB_TO_ULONG(205, 51 , 51 ), "brown3" },
696 { RGB_TO_ULONG(139, 35 , 35 ), "brown4" },
697 { RGB_TO_ULONG(255, 140, 105), "salmon1" },
698 { RGB_TO_ULONG(238, 130, 98 ), "salmon2" },
699 { RGB_TO_ULONG(205, 112, 84 ), "salmon3" },
700 { RGB_TO_ULONG(139, 76 , 57 ), "salmon4" },
701 { RGB_TO_ULONG(255, 160, 122), "LightSalmon1" },
702 { RGB_TO_ULONG(238, 149, 114), "LightSalmon2" },
703 { RGB_TO_ULONG(205, 129, 98 ), "LightSalmon3" },
704 { RGB_TO_ULONG(139, 87 , 66 ), "LightSalmon4" },
705 { RGB_TO_ULONG(255, 165, 0 ), "orange1" },
706 { RGB_TO_ULONG(238, 154, 0 ), "orange2" },
707 { RGB_TO_ULONG(205, 133, 0 ), "orange3" },
708 { RGB_TO_ULONG(139, 90 , 0 ), "orange4" },
709 { RGB_TO_ULONG(255, 127, 0 ), "DarkOrange1" },
710 { RGB_TO_ULONG(238, 118, 0 ), "DarkOrange2" },
711 { RGB_TO_ULONG(205, 102, 0 ), "DarkOrange3" },
712 { RGB_TO_ULONG(139, 69 , 0 ), "DarkOrange4" },
713 { RGB_TO_ULONG(255, 114, 86 ), "coral1" },
714 { RGB_TO_ULONG(238, 106, 80 ), "coral2" },
715 { RGB_TO_ULONG(205, 91 , 69 ), "coral3" },
716 { RGB_TO_ULONG(139, 62 , 47 ), "coral4" },
717 { RGB_TO_ULONG(255, 99 , 71 ), "tomato1" },
718 { RGB_TO_ULONG(238, 92 , 66 ), "tomato2" },
719 { RGB_TO_ULONG(205, 79 , 57 ), "tomato3" },
720 { RGB_TO_ULONG(139, 54 , 38 ), "tomato4" },
721 { RGB_TO_ULONG(255, 69 , 0 ), "OrangeRed1" },
722 { RGB_TO_ULONG(238, 64 , 0 ), "OrangeRed2" },
723 { RGB_TO_ULONG(205, 55 , 0 ), "OrangeRed3" },
724 { RGB_TO_ULONG(139, 37 , 0 ), "OrangeRed4" },
725 { RGB_TO_ULONG(255, 0 , 0 ), "red1" },
726 { RGB_TO_ULONG(238, 0 , 0 ), "red2" },
727 { RGB_TO_ULONG(205, 0 , 0 ), "red3" },
728 { RGB_TO_ULONG(139, 0 , 0 ), "red4" },
729 { RGB_TO_ULONG(255, 20 , 147), "DeepPink1" },
730 { RGB_TO_ULONG(238, 18 , 137), "DeepPink2" },
731 { RGB_TO_ULONG(205, 16 , 118), "DeepPink3" },
732 { RGB_TO_ULONG(139, 10 , 80 ), "DeepPink4" },
733 { RGB_TO_ULONG(255, 110, 180), "HotPink1" },
734 { RGB_TO_ULONG(238, 106, 167), "HotPink2" },
735 { RGB_TO_ULONG(205, 96 , 144), "HotPink3" },
736 { RGB_TO_ULONG(139, 58 , 98 ), "HotPink4" },
737 { RGB_TO_ULONG(255, 181, 197), "pink1" },
738 { RGB_TO_ULONG(238, 169, 184), "pink2" },
739 { RGB_TO_ULONG(205, 145, 158), "pink3" },
740 { RGB_TO_ULONG(139, 99 , 108), "pink4" },
741 { RGB_TO_ULONG(255, 174, 185), "LightPink1" },
742 { RGB_TO_ULONG(238, 162, 173), "LightPink2" },
743 { RGB_TO_ULONG(205, 140, 149), "LightPink3" },
744 { RGB_TO_ULONG(139, 95 , 101), "LightPink4" },
745 { RGB_TO_ULONG(255, 130, 171), "PaleVioletRed1" },
746 { RGB_TO_ULONG(238, 121, 159), "PaleVioletRed2" },
747 { RGB_TO_ULONG(205, 104, 137), "PaleVioletRed3" },
748 { RGB_TO_ULONG(139, 71 , 93 ), "PaleVioletRed4" },
749 { RGB_TO_ULONG(255, 52 , 179), "maroon1" },
750 { RGB_TO_ULONG(238, 48 , 167), "maroon2" },
751 { RGB_TO_ULONG(205, 41 , 144), "maroon3" },
752 { RGB_TO_ULONG(139, 28 , 98 ), "maroon4" },
753 { RGB_TO_ULONG(255, 62 , 150), "VioletRed1" },
754 { RGB_TO_ULONG(238, 58 , 140), "VioletRed2" },
755 { RGB_TO_ULONG(205, 50 , 120), "VioletRed3" },
756 { RGB_TO_ULONG(139, 34 , 82 ), "VioletRed4" },
757 { RGB_TO_ULONG(255, 0 , 255), "magenta1" },
758 { RGB_TO_ULONG(238, 0 , 238), "magenta2" },
759 { RGB_TO_ULONG(205, 0 , 205), "magenta3" },
760 { RGB_TO_ULONG(139, 0 , 139), "magenta4" },
761 { RGB_TO_ULONG(255, 131, 250), "orchid1" },
762 { RGB_TO_ULONG(238, 122, 233), "orchid2" },
763 { RGB_TO_ULONG(205, 105, 201), "orchid3" },
764 { RGB_TO_ULONG(139, 71 , 137), "orchid4" },
765 { RGB_TO_ULONG(255, 187, 255), "plum1" },
766 { RGB_TO_ULONG(238, 174, 238), "plum2" },
767 { RGB_TO_ULONG(205, 150, 205), "plum3" },
768 { RGB_TO_ULONG(139, 102, 139), "plum4" },
769 { RGB_TO_ULONG(224, 102, 255), "MediumOrchid1" },
770 { RGB_TO_ULONG(209, 95 , 238), "MediumOrchid2" },
771 { RGB_TO_ULONG(180, 82 , 205), "MediumOrchid3" },
772 { RGB_TO_ULONG(122, 55 , 139), "MediumOrchid4" },
773 { RGB_TO_ULONG(191, 62 , 255), "DarkOrchid1" },
774 { RGB_TO_ULONG(178, 58 , 238), "DarkOrchid2" },
775 { RGB_TO_ULONG(154, 50 , 205), "DarkOrchid3" },
776 { RGB_TO_ULONG(104, 34 , 139), "DarkOrchid4" },
777 { RGB_TO_ULONG(155, 48 , 255), "purple1" },
778 { RGB_TO_ULONG(145, 44 , 238), "purple2" },
779 { RGB_TO_ULONG(125, 38 , 205), "purple3" },
780 { RGB_TO_ULONG(85 , 26 , 139), "purple4" },
781 { RGB_TO_ULONG(171, 130, 255), "MediumPurple1" },
782 { RGB_TO_ULONG(159, 121, 238), "MediumPurple2" },
783 { RGB_TO_ULONG(137, 104, 205), "MediumPurple3" },
784 { RGB_TO_ULONG(93 , 71 , 139), "MediumPurple4" },
785 { RGB_TO_ULONG(255, 225, 255), "thistle1" },
786 { RGB_TO_ULONG(238, 210, 238), "thistle2" },
787 { RGB_TO_ULONG(205, 181, 205), "thistle3" },
788 { RGB_TO_ULONG(139, 123, 139), "thistle4" },
789 { RGB_TO_ULONG(0 , 0 , 0 ), "gray0" },
790 { RGB_TO_ULONG(0 , 0 , 0 ), "grey0" },
791 { RGB_TO_ULONG(3 , 3 , 3 ), "gray1" },
792 { RGB_TO_ULONG(3 , 3 , 3 ), "grey1" },
793 { RGB_TO_ULONG(5 , 5 , 5 ), "gray2" },
794 { RGB_TO_ULONG(5 , 5 , 5 ), "grey2" },
795 { RGB_TO_ULONG(8 , 8 , 8 ), "gray3" },
796 { RGB_TO_ULONG(8 , 8 , 8 ), "grey3" },
797 { RGB_TO_ULONG(10 , 10 , 10 ), "gray4" },
798 { RGB_TO_ULONG(10 , 10 , 10 ), "grey4" },
799 { RGB_TO_ULONG(13 , 13 , 13 ), "gray5" },
800 { RGB_TO_ULONG(13 , 13 , 13 ), "grey5" },
801 { RGB_TO_ULONG(15 , 15 , 15 ), "gray6" },
802 { RGB_TO_ULONG(15 , 15 , 15 ), "grey6" },
803 { RGB_TO_ULONG(18 , 18 , 18 ), "gray7" },
804 { RGB_TO_ULONG(18 , 18 , 18 ), "grey7" },
805 { RGB_TO_ULONG(20 , 20 , 20 ), "gray8" },
806 { RGB_TO_ULONG(20 , 20 , 20 ), "grey8" },
807 { RGB_TO_ULONG(23 , 23 , 23 ), "gray9" },
808 { RGB_TO_ULONG(23 , 23 , 23 ), "grey9" },
809 { RGB_TO_ULONG(26 , 26 , 26 ), "gray10" },
810 { RGB_TO_ULONG(26 , 26 , 26 ), "grey10" },
811 { RGB_TO_ULONG(28 , 28 , 28 ), "gray11" },
812 { RGB_TO_ULONG(28 , 28 , 28 ), "grey11" },
813 { RGB_TO_ULONG(31 , 31 , 31 ), "gray12" },
814 { RGB_TO_ULONG(31 , 31 , 31 ), "grey12" },
815 { RGB_TO_ULONG(33 , 33 , 33 ), "gray13" },
816 { RGB_TO_ULONG(33 , 33 , 33 ), "grey13" },
817 { RGB_TO_ULONG(36 , 36 , 36 ), "gray14" },
818 { RGB_TO_ULONG(36 , 36 , 36 ), "grey14" },
819 { RGB_TO_ULONG(38 , 38 , 38 ), "gray15" },
820 { RGB_TO_ULONG(38 , 38 , 38 ), "grey15" },
821 { RGB_TO_ULONG(41 , 41 , 41 ), "gray16" },
822 { RGB_TO_ULONG(41 , 41 , 41 ), "grey16" },
823 { RGB_TO_ULONG(43 , 43 , 43 ), "gray17" },
824 { RGB_TO_ULONG(43 , 43 , 43 ), "grey17" },
825 { RGB_TO_ULONG(46 , 46 , 46 ), "gray18" },
826 { RGB_TO_ULONG(46 , 46 , 46 ), "grey18" },
827 { RGB_TO_ULONG(48 , 48 , 48 ), "gray19" },
828 { RGB_TO_ULONG(48 , 48 , 48 ), "grey19" },
829 { RGB_TO_ULONG(51 , 51 , 51 ), "gray20" },
830 { RGB_TO_ULONG(51 , 51 , 51 ), "grey20" },
831 { RGB_TO_ULONG(54 , 54 , 54 ), "gray21" },
832 { RGB_TO_ULONG(54 , 54 , 54 ), "grey21" },
833 { RGB_TO_ULONG(56 , 56 , 56 ), "gray22" },
834 { RGB_TO_ULONG(56 , 56 , 56 ), "grey22" },
835 { RGB_TO_ULONG(59 , 59 , 59 ), "gray23" },
836 { RGB_TO_ULONG(59 , 59 , 59 ), "grey23" },
837 { RGB_TO_ULONG(61 , 61 , 61 ), "gray24" },
838 { RGB_TO_ULONG(61 , 61 , 61 ), "grey24" },
839 { RGB_TO_ULONG(64 , 64 , 64 ), "gray25" },
840 { RGB_TO_ULONG(64 , 64 , 64 ), "grey25" },
841 { RGB_TO_ULONG(66 , 66 , 66 ), "gray26" },
842 { RGB_TO_ULONG(66 , 66 , 66 ), "grey26" },
843 { RGB_TO_ULONG(69 , 69 , 69 ), "gray27" },
844 { RGB_TO_ULONG(69 , 69 , 69 ), "grey27" },
845 { RGB_TO_ULONG(71 , 71 , 71 ), "gray28" },
846 { RGB_TO_ULONG(71 , 71 , 71 ), "grey28" },
847 { RGB_TO_ULONG(74 , 74 , 74 ), "gray29" },
848 { RGB_TO_ULONG(74 , 74 , 74 ), "grey29" },
849 { RGB_TO_ULONG(77 , 77 , 77 ), "gray30" },
850 { RGB_TO_ULONG(77 , 77 , 77 ), "grey30" },
851 { RGB_TO_ULONG(79 , 79 , 79 ), "gray31" },
852 { RGB_TO_ULONG(79 , 79 , 79 ), "grey31" },
853 { RGB_TO_ULONG(82 , 82 , 82 ), "gray32" },
854 { RGB_TO_ULONG(82 , 82 , 82 ), "grey32" },
855 { RGB_TO_ULONG(84 , 84 , 84 ), "gray33" },
856 { RGB_TO_ULONG(84 , 84 , 84 ), "grey33" },
857 { RGB_TO_ULONG(87 , 87 , 87 ), "gray34" },
858 { RGB_TO_ULONG(87 , 87 , 87 ), "grey34" },
859 { RGB_TO_ULONG(89 , 89 , 89 ), "gray35" },
860 { RGB_TO_ULONG(89 , 89 , 89 ), "grey35" },
861 { RGB_TO_ULONG(92 , 92 , 92 ), "gray36" },
862 { RGB_TO_ULONG(92 , 92 , 92 ), "grey36" },
863 { RGB_TO_ULONG(94 , 94 , 94 ), "gray37" },
864 { RGB_TO_ULONG(94 , 94 , 94 ), "grey37" },
865 { RGB_TO_ULONG(97 , 97 , 97 ), "gray38" },
866 { RGB_TO_ULONG(97 , 97 , 97 ), "grey38" },
867 { RGB_TO_ULONG(99 , 99 , 99 ), "gray39" },
868 { RGB_TO_ULONG(99 , 99 , 99 ), "grey39" },
869 { RGB_TO_ULONG(102, 102, 102), "gray40" },
870 { RGB_TO_ULONG(102, 102, 102), "grey40" },
871 { RGB_TO_ULONG(105, 105, 105), "gray41" },
872 { RGB_TO_ULONG(105, 105, 105), "grey41" },
873 { RGB_TO_ULONG(107, 107, 107), "gray42" },
874 { RGB_TO_ULONG(107, 107, 107), "grey42" },
875 { RGB_TO_ULONG(110, 110, 110), "gray43" },
876 { RGB_TO_ULONG(110, 110, 110), "grey43" },
877 { RGB_TO_ULONG(112, 112, 112), "gray44" },
878 { RGB_TO_ULONG(112, 112, 112), "grey44" },
879 { RGB_TO_ULONG(115, 115, 115), "gray45" },
880 { RGB_TO_ULONG(115, 115, 115), "grey45" },
881 { RGB_TO_ULONG(117, 117, 117), "gray46" },
882 { RGB_TO_ULONG(117, 117, 117), "grey46" },
883 { RGB_TO_ULONG(120, 120, 120), "gray47" },
884 { RGB_TO_ULONG(120, 120, 120), "grey47" },
885 { RGB_TO_ULONG(122, 122, 122), "gray48" },
886 { RGB_TO_ULONG(122, 122, 122), "grey48" },
887 { RGB_TO_ULONG(125, 125, 125), "gray49" },
888 { RGB_TO_ULONG(125, 125, 125), "grey49" },
889 { RGB_TO_ULONG(127, 127, 127), "gray50" },
890 { RGB_TO_ULONG(127, 127, 127), "grey50" },
891 { RGB_TO_ULONG(130, 130, 130), "gray51" },
892 { RGB_TO_ULONG(130, 130, 130), "grey51" },
893 { RGB_TO_ULONG(133, 133, 133), "gray52" },
894 { RGB_TO_ULONG(133, 133, 133), "grey52" },
895 { RGB_TO_ULONG(135, 135, 135), "gray53" },
896 { RGB_TO_ULONG(135, 135, 135), "grey53" },
897 { RGB_TO_ULONG(138, 138, 138), "gray54" },
898 { RGB_TO_ULONG(138, 138, 138), "grey54" },
899 { RGB_TO_ULONG(140, 140, 140), "gray55" },
900 { RGB_TO_ULONG(140, 140, 140), "grey55" },
901 { RGB_TO_ULONG(143, 143, 143), "gray56" },
902 { RGB_TO_ULONG(143, 143, 143), "grey56" },
903 { RGB_TO_ULONG(145, 145, 145), "gray57" },
904 { RGB_TO_ULONG(145, 145, 145), "grey57" },
905 { RGB_TO_ULONG(148, 148, 148), "gray58" },
906 { RGB_TO_ULONG(148, 148, 148), "grey58" },
907 { RGB_TO_ULONG(150, 150, 150), "gray59" },
908 { RGB_TO_ULONG(150, 150, 150), "grey59" },
909 { RGB_TO_ULONG(153, 153, 153), "gray60" },
910 { RGB_TO_ULONG(153, 153, 153), "grey60" },
911 { RGB_TO_ULONG(156, 156, 156), "gray61" },
912 { RGB_TO_ULONG(156, 156, 156), "grey61" },
913 { RGB_TO_ULONG(158, 158, 158), "gray62" },
914 { RGB_TO_ULONG(158, 158, 158), "grey62" },
915 { RGB_TO_ULONG(161, 161, 161), "gray63" },
916 { RGB_TO_ULONG(161, 161, 161), "grey63" },
917 { RGB_TO_ULONG(163, 163, 163), "gray64" },
918 { RGB_TO_ULONG(163, 163, 163), "grey64" },
919 { RGB_TO_ULONG(166, 166, 166), "gray65" },
920 { RGB_TO_ULONG(166, 166, 166), "grey65" },
921 { RGB_TO_ULONG(168, 168, 168), "gray66" },
922 { RGB_TO_ULONG(168, 168, 168), "grey66" },
923 { RGB_TO_ULONG(171, 171, 171), "gray67" },
924 { RGB_TO_ULONG(171, 171, 171), "grey67" },
925 { RGB_TO_ULONG(173, 173, 173), "gray68" },
926 { RGB_TO_ULONG(173, 173, 173), "grey68" },
927 { RGB_TO_ULONG(176, 176, 176), "gray69" },
928 { RGB_TO_ULONG(176, 176, 176), "grey69" },
929 { RGB_TO_ULONG(179, 179, 179), "gray70" },
930 { RGB_TO_ULONG(179, 179, 179), "grey70" },
931 { RGB_TO_ULONG(181, 181, 181), "gray71" },
932 { RGB_TO_ULONG(181, 181, 181), "grey71" },
933 { RGB_TO_ULONG(184, 184, 184), "gray72" },
934 { RGB_TO_ULONG(184, 184, 184), "grey72" },
935 { RGB_TO_ULONG(186, 186, 186), "gray73" },
936 { RGB_TO_ULONG(186, 186, 186), "grey73" },
937 { RGB_TO_ULONG(189, 189, 189), "gray74" },
938 { RGB_TO_ULONG(189, 189, 189), "grey74" },
939 { RGB_TO_ULONG(191, 191, 191), "gray75" },
940 { RGB_TO_ULONG(191, 191, 191), "grey75" },
941 { RGB_TO_ULONG(194, 194, 194), "gray76" },
942 { RGB_TO_ULONG(194, 194, 194), "grey76" },
943 { RGB_TO_ULONG(196, 196, 196), "gray77" },
944 { RGB_TO_ULONG(196, 196, 196), "grey77" },
945 { RGB_TO_ULONG(199, 199, 199), "gray78" },
946 { RGB_TO_ULONG(199, 199, 199), "grey78" },
947 { RGB_TO_ULONG(201, 201, 201), "gray79" },
948 { RGB_TO_ULONG(201, 201, 201), "grey79" },
949 { RGB_TO_ULONG(204, 204, 204), "gray80" },
950 { RGB_TO_ULONG(204, 204, 204), "grey80" },
951 { RGB_TO_ULONG(207, 207, 207), "gray81" },
952 { RGB_TO_ULONG(207, 207, 207), "grey81" },
953 { RGB_TO_ULONG(209, 209, 209), "gray82" },
954 { RGB_TO_ULONG(209, 209, 209), "grey82" },
955 { RGB_TO_ULONG(212, 212, 212), "gray83" },
956 { RGB_TO_ULONG(212, 212, 212), "grey83" },
957 { RGB_TO_ULONG(214, 214, 214), "gray84" },
958 { RGB_TO_ULONG(214, 214, 214), "grey84" },
959 { RGB_TO_ULONG(217, 217, 217), "gray85" },
960 { RGB_TO_ULONG(217, 217, 217), "grey85" },
961 { RGB_TO_ULONG(219, 219, 219), "gray86" },
962 { RGB_TO_ULONG(219, 219, 219), "grey86" },
963 { RGB_TO_ULONG(222, 222, 222), "gray87" },
964 { RGB_TO_ULONG(222, 222, 222), "grey87" },
965 { RGB_TO_ULONG(224, 224, 224), "gray88" },
966 { RGB_TO_ULONG(224, 224, 224), "grey88" },
967 { RGB_TO_ULONG(227, 227, 227), "gray89" },
968 { RGB_TO_ULONG(227, 227, 227), "grey89" },
969 { RGB_TO_ULONG(229, 229, 229), "gray90" },
970 { RGB_TO_ULONG(229, 229, 229), "grey90" },
971 { RGB_TO_ULONG(232, 232, 232), "gray91" },
972 { RGB_TO_ULONG(232, 232, 232), "grey91" },
973 { RGB_TO_ULONG(235, 235, 235), "gray92" },
974 { RGB_TO_ULONG(235, 235, 235), "grey92" },
975 { RGB_TO_ULONG(237, 237, 237), "gray93" },
976 { RGB_TO_ULONG(237, 237, 237), "grey93" },
977 { RGB_TO_ULONG(240, 240, 240), "gray94" },
978 { RGB_TO_ULONG(240, 240, 240), "grey94" },
979 { RGB_TO_ULONG(242, 242, 242), "gray95" },
980 { RGB_TO_ULONG(242, 242, 242), "grey95" },
981 { RGB_TO_ULONG(245, 245, 245), "gray96" },
982 { RGB_TO_ULONG(245, 245, 245), "grey96" },
983 { RGB_TO_ULONG(247, 247, 247), "gray97" },
984 { RGB_TO_ULONG(247, 247, 247), "grey97" },
985 { RGB_TO_ULONG(250, 250, 250), "gray98" },
986 { RGB_TO_ULONG(250, 250, 250), "grey98" },
987 { RGB_TO_ULONG(252, 252, 252), "gray99" },
988 { RGB_TO_ULONG(252, 252, 252), "grey99" },
989 { RGB_TO_ULONG(255, 255, 255), "gray100" },
990 { RGB_TO_ULONG(255, 255, 255), "grey100" },
991 { RGB_TO_ULONG(169, 169, 169), "dark grey" },
992 { RGB_TO_ULONG(169, 169, 169), "DarkGrey" },
993 { RGB_TO_ULONG(169, 169, 169), "dark gray" },
994 { RGB_TO_ULONG(169, 169, 169), "DarkGray" },
995 { RGB_TO_ULONG(0 , 0 , 139), "dark blue" },
996 { RGB_TO_ULONG(0 , 0 , 139), "DarkBlue" },
997 { RGB_TO_ULONG(0 , 139, 139), "dark cyan" },
998 { RGB_TO_ULONG(0 , 139, 139), "DarkCyan" },
999 { RGB_TO_ULONG(139, 0 , 139), "dark magenta" },
1000 { RGB_TO_ULONG(139, 0 , 139), "DarkMagenta" },
1001 { RGB_TO_ULONG(139, 0 , 0 ), "dark red" },
1002 { RGB_TO_ULONG(139, 0 , 0 ), "DarkRed" },
1003 { RGB_TO_ULONG(144, 238, 144), "light green" },
1004 { RGB_TO_ULONG(144, 238, 144), "LightGreen" }
1007 Lisp_Object
1008 mac_color_map_lookup (colorname)
1009 const char *colorname;
1011 Lisp_Object ret = Qnil;
1012 int i;
1014 BLOCK_INPUT;
1016 for (i = 0; i < sizeof (mac_color_map) / sizeof (mac_color_map[0]); i++)
1017 if (xstricmp (colorname, mac_color_map[i].name) == 0)
1019 ret = make_number (mac_color_map[i].color);
1020 break;
1023 UNBLOCK_INPUT;
1025 return ret;
1028 Lisp_Object
1029 x_to_mac_color (colorname)
1030 char * colorname;
1032 register Lisp_Object ret = Qnil;
1034 BLOCK_INPUT;
1036 if (colorname[0] == '#')
1038 /* Could be an old-style RGB Device specification. */
1039 char *color;
1040 int size;
1041 color = colorname + 1;
1043 size = strlen(color);
1044 if (size == 3 || size == 6 || size == 9 || size == 12)
1046 unsigned long colorval;
1047 int i, pos;
1048 pos = 16;
1049 size /= 3;
1050 colorval = 0;
1052 for (i = 0; i < 3; i++)
1054 char *end;
1055 char t;
1056 unsigned long value;
1058 /* The check for 'x' in the following conditional takes into
1059 account the fact that strtol allows a "0x" in front of
1060 our numbers, and we don't. */
1061 if (!isxdigit(color[0]) || color[1] == 'x')
1062 break;
1063 t = color[size];
1064 color[size] = '\0';
1065 value = strtoul(color, &end, 16);
1066 color[size] = t;
1067 if (errno == ERANGE || end - color != size)
1068 break;
1069 switch (size)
1071 case 1:
1072 value = value * 0x10;
1073 break;
1074 case 2:
1075 break;
1076 case 3:
1077 value /= 0x10;
1078 break;
1079 case 4:
1080 value /= 0x100;
1081 break;
1083 colorval |= (value << pos);
1084 pos -= 8;
1085 if (i == 2)
1087 UNBLOCK_INPUT;
1088 return make_number (colorval);
1090 color = end;
1094 else if (strnicmp(colorname, "rgb:", 4) == 0)
1096 char *color;
1097 unsigned long colorval;
1098 int i, pos;
1099 pos = 16;
1101 colorval = 0;
1102 color = colorname + 4;
1103 for (i = 0; i < 3; i++)
1105 char *end;
1106 unsigned long value;
1108 /* The check for 'x' in the following conditional takes into
1109 account the fact that strtol allows a "0x" in front of
1110 our numbers, and we don't. */
1111 if (!isxdigit(color[0]) || color[1] == 'x')
1112 break;
1113 value = strtoul(color, &end, 16);
1114 if (errno == ERANGE)
1115 break;
1116 switch (end - color)
1118 case 1:
1119 value = value * 0x10 + value;
1120 break;
1121 case 2:
1122 break;
1123 case 3:
1124 value /= 0x10;
1125 break;
1126 case 4:
1127 value /= 0x100;
1128 break;
1129 default:
1130 value = ULONG_MAX;
1132 if (value == ULONG_MAX)
1133 break;
1134 colorval |= (value << pos);
1135 pos -= 0x8;
1136 if (i == 2)
1138 if (*end != '\0')
1139 break;
1140 UNBLOCK_INPUT;
1141 return make_number (colorval);
1143 if (*end != '/')
1144 break;
1145 color = end + 1;
1148 else if (strnicmp(colorname, "rgbi:", 5) == 0)
1150 /* This is an RGB Intensity specification. */
1151 char *color;
1152 unsigned long colorval;
1153 int i, pos;
1154 pos = 16;
1156 colorval = 0;
1157 color = colorname + 5;
1158 for (i = 0; i < 3; i++)
1160 char *end;
1161 double value;
1162 unsigned long val;
1164 value = strtod(color, &end);
1165 if (errno == ERANGE)
1166 break;
1167 if (value < 0.0 || value > 1.0)
1168 break;
1169 val = (unsigned long)(0x100 * value);
1170 /* We used 0x100 instead of 0xFF to give a continuous
1171 range between 0.0 and 1.0 inclusive. The next statement
1172 fixes the 1.0 case. */
1173 if (val == 0x100)
1174 val = 0xFF;
1175 colorval |= (val << pos);
1176 pos -= 0x8;
1177 if (i == 2)
1179 if (*end != '\0')
1180 break;
1181 UNBLOCK_INPUT;
1182 return make_number (colorval);
1184 if (*end != '/')
1185 break;
1186 color = end + 1;
1190 ret = mac_color_map_lookup (colorname);
1192 UNBLOCK_INPUT;
1193 return ret;
1196 /* Gamma-correct COLOR on frame F. */
1198 void
1199 gamma_correct (f, color)
1200 struct frame *f;
1201 unsigned long *color;
1203 if (f->gamma)
1205 unsigned long red, green, blue;
1207 red = pow (RED_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1208 green = pow (GREEN_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1209 blue = pow (BLUE_FROM_ULONG (*color) / 255.0, f->gamma) * 255.0 + 0.5;
1210 *color = RGB_TO_ULONG (red, green, blue);
1214 /* Decide if color named COLOR is valid for the display associated
1215 with the selected frame; if so, return the rgb values in COLOR_DEF.
1216 If ALLOC is nonzero, allocate a new colormap cell. */
1219 mac_defined_color (f, color, color_def, alloc)
1220 FRAME_PTR f;
1221 char *color;
1222 XColor *color_def;
1223 int alloc;
1225 register Lisp_Object tem;
1226 unsigned long mac_color_ref;
1228 tem = x_to_mac_color (color);
1230 if (!NILP (tem))
1232 if (f)
1234 /* Apply gamma correction. */
1235 mac_color_ref = XUINT (tem);
1236 gamma_correct (f, &mac_color_ref);
1237 XSETINT (tem, mac_color_ref);
1240 color_def->pixel = mac_color_ref;
1241 color_def->red = RED16_FROM_ULONG (mac_color_ref);
1242 color_def->green = GREEN16_FROM_ULONG (mac_color_ref);
1243 color_def->blue = BLUE16_FROM_ULONG (mac_color_ref);
1245 return 1;
1247 else
1249 return 0;
1253 /* Given a string ARG naming a color, compute a pixel value from it
1254 suitable for screen F.
1255 If F is not a color screen, return DEF (default) regardless of what
1256 ARG says. */
1259 x_decode_color (f, arg, def)
1260 FRAME_PTR f;
1261 Lisp_Object arg;
1262 int def;
1264 XColor cdef;
1266 CHECK_STRING (arg);
1268 if (strcmp (SDATA (arg), "black") == 0)
1269 return BLACK_PIX_DEFAULT (f);
1270 else if (strcmp (SDATA (arg), "white") == 0)
1271 return WHITE_PIX_DEFAULT (f);
1273 #if 0
1274 if (FRAME_MAC_DISPLAY_INFO (f)->n_planes) == 1)
1275 return def;
1276 #endif
1278 if (mac_defined_color (f, SDATA (arg), &cdef, 1))
1279 return cdef.pixel;
1281 /* defined_color failed; return an ultimate default. */
1282 return def;
1285 /* Functions called only from `x_set_frame_param'
1286 to set individual parameters.
1288 If FRAME_MAC_WINDOW (f) is 0,
1289 the frame is being created and its window does not exist yet.
1290 In that case, just record the parameter's new value
1291 in the standard place; do not attempt to change the window. */
1293 void
1294 x_set_foreground_color (f, arg, oldval)
1295 struct frame *f;
1296 Lisp_Object arg, oldval;
1298 struct mac_output *mac = f->output_data.mac;
1299 unsigned long fg, old_fg;
1301 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1302 old_fg = FRAME_FOREGROUND_PIXEL (f);
1303 FRAME_FOREGROUND_PIXEL (f) = fg;
1305 if (FRAME_MAC_WINDOW (f) != 0)
1307 Display *dpy = FRAME_MAC_DISPLAY (f);
1309 BLOCK_INPUT;
1310 XSetForeground (dpy, mac->normal_gc, fg);
1311 XSetBackground (dpy, mac->reverse_gc, fg);
1313 if (mac->cursor_pixel == old_fg)
1315 unload_color (f, mac->cursor_pixel);
1316 mac->cursor_pixel = fg;
1317 XSetBackground (dpy, mac->cursor_gc, mac->cursor_pixel);
1320 UNBLOCK_INPUT;
1322 update_face_from_frame_parameter (f, Qforeground_color, arg);
1324 if (FRAME_VISIBLE_P (f))
1325 redraw_frame (f);
1328 unload_color (f, old_fg);
1331 void
1332 x_set_background_color (f, arg, oldval)
1333 struct frame *f;
1334 Lisp_Object arg, oldval;
1336 struct mac_output *mac = f->output_data.mac;
1337 unsigned long bg;
1339 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
1340 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
1341 FRAME_BACKGROUND_PIXEL (f) = bg;
1343 if (FRAME_MAC_WINDOW (f) != 0)
1345 Display *dpy = FRAME_MAC_DISPLAY (f);
1347 BLOCK_INPUT;
1348 XSetBackground (dpy, mac->normal_gc, bg);
1349 XSetForeground (dpy, mac->reverse_gc, bg);
1350 mac_set_frame_window_background (f, bg);
1351 XSetForeground (dpy, mac->cursor_gc, bg);
1353 UNBLOCK_INPUT;
1354 update_face_from_frame_parameter (f, Qbackground_color, arg);
1356 if (FRAME_VISIBLE_P (f))
1357 redraw_frame (f);
1361 void
1362 x_set_mouse_color (f, arg, oldval)
1363 struct frame *f;
1364 Lisp_Object arg, oldval;
1366 struct x_output *x = f->output_data.x;
1367 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
1368 Cursor hourglass_cursor, horizontal_drag_cursor;
1369 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1370 unsigned long mask_color = x->background_pixel;
1372 /* Don't let pointers be invisible. */
1373 if (mask_color == pixel)
1374 pixel = x->foreground_pixel;
1376 f->output_data.mac->mouse_pixel = pixel;
1378 if (!NILP (Vx_pointer_shape))
1380 CHECK_NUMBER (Vx_pointer_shape);
1381 cursor = XINT (Vx_pointer_shape);
1383 else
1384 cursor = kThemeIBeamCursor;
1386 if (!NILP (Vx_nontext_pointer_shape))
1388 CHECK_NUMBER (Vx_nontext_pointer_shape);
1389 nontext_cursor = XINT (Vx_nontext_pointer_shape);
1391 else
1392 nontext_cursor = kThemeArrowCursor;
1394 if (!NILP (Vx_hourglass_pointer_shape))
1396 CHECK_NUMBER (Vx_hourglass_pointer_shape);
1397 hourglass_cursor = XINT (Vx_hourglass_pointer_shape);
1399 else
1400 hourglass_cursor = kThemeWatchCursor;
1402 if (!NILP (Vx_mode_pointer_shape))
1404 CHECK_NUMBER (Vx_mode_pointer_shape);
1405 mode_cursor = XINT (Vx_mode_pointer_shape);
1407 else
1408 mode_cursor = kThemeArrowCursor;
1410 if (!NILP (Vx_sensitive_text_pointer_shape))
1412 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1413 hand_cursor = XINT (Vx_sensitive_text_pointer_shape);
1415 else
1416 hand_cursor = kThemePointingHandCursor;
1418 if (!NILP (Vx_window_horizontal_drag_shape))
1420 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1421 horizontal_drag_cursor = XINT (Vx_window_horizontal_drag_shape);
1423 else
1424 horizontal_drag_cursor = kThemeResizeLeftRightCursor;
1426 #if 0 /* MAC_TODO: cursor color changes */
1428 XColor fore_color, back_color;
1430 fore_color.pixel = f->output_data.mac->mouse_pixel;
1431 x_query_color (f, &fore_color);
1432 back_color.pixel = mask_color;
1433 x_query_color (f, &back_color);
1435 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1436 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1437 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1438 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1439 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1440 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1442 #endif
1444 BLOCK_INPUT;
1446 if (FRAME_MAC_WINDOW (f) != 0)
1447 rif->define_frame_cursor (f, cursor);
1449 f->output_data.mac->text_cursor = cursor;
1450 f->output_data.mac->nontext_cursor = nontext_cursor;
1451 f->output_data.mac->hourglass_cursor = hourglass_cursor;
1452 f->output_data.mac->modeline_cursor = mode_cursor;
1453 f->output_data.mac->hand_cursor = hand_cursor;
1454 f->output_data.mac->horizontal_drag_cursor = horizontal_drag_cursor;
1456 UNBLOCK_INPUT;
1458 update_face_from_frame_parameter (f, Qmouse_color, arg);
1461 void
1462 x_set_cursor_color (f, arg, oldval)
1463 struct frame *f;
1464 Lisp_Object arg, oldval;
1466 unsigned long fore_pixel, pixel;
1468 if (!NILP (Vx_cursor_fore_pixel))
1469 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1470 WHITE_PIX_DEFAULT (f));
1471 else
1472 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1474 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1476 /* Make sure that the cursor color differs from the background color. */
1477 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1479 pixel = f->output_data.mac->mouse_pixel;
1480 if (pixel == fore_pixel)
1481 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1484 f->output_data.mac->cursor_foreground_pixel = fore_pixel;
1485 f->output_data.mac->cursor_pixel = pixel;
1487 if (FRAME_MAC_WINDOW (f) != 0)
1489 BLOCK_INPUT;
1490 /* Update frame's cursor_gc. */
1491 XSetBackground (FRAME_MAC_DISPLAY (f),
1492 f->output_data.mac->cursor_gc, pixel);
1493 XSetForeground (FRAME_MAC_DISPLAY (f),
1494 f->output_data.mac->cursor_gc, fore_pixel);
1495 UNBLOCK_INPUT;
1497 if (FRAME_VISIBLE_P (f))
1499 x_update_cursor (f, 0);
1500 x_update_cursor (f, 1);
1504 update_face_from_frame_parameter (f, Qcursor_color, arg);
1507 /* Set the border-color of frame F to pixel value PIX.
1508 Note that this does not fully take effect if done before
1509 F has a window. */
1511 void
1512 x_set_border_pixel (f, pix)
1513 struct frame *f;
1514 int pix;
1517 f->output_data.mac->border_pixel = pix;
1519 if (FRAME_MAC_WINDOW (f) != 0 && f->border_width > 0)
1521 if (FRAME_VISIBLE_P (f))
1522 redraw_frame (f);
1526 /* Set the border-color of frame F to value described by ARG.
1527 ARG can be a string naming a color.
1528 The border-color is used for the border that is drawn by the server.
1529 Note that this does not fully take effect if done before
1530 F has a window; it must be redone when the window is created. */
1532 void
1533 x_set_border_color (f, arg, oldval)
1534 struct frame *f;
1535 Lisp_Object arg, oldval;
1537 int pix;
1539 CHECK_STRING (arg);
1540 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1541 x_set_border_pixel (f, pix);
1542 update_face_from_frame_parameter (f, Qborder_color, arg);
1546 void
1547 x_set_cursor_type (f, arg, oldval)
1548 FRAME_PTR f;
1549 Lisp_Object arg, oldval;
1551 set_frame_cursor_types (f, arg);
1553 /* Make sure the cursor gets redrawn. */
1554 cursor_type_changed = 1;
1557 #if 0 /* MAC_TODO: really no icon for Mac */
1558 void
1559 x_set_icon_type (f, arg, oldval)
1560 struct frame *f;
1561 Lisp_Object arg, oldval;
1563 int result;
1565 if (NILP (arg) && NILP (oldval))
1566 return;
1568 if (STRINGP (arg) && STRINGP (oldval)
1569 && EQ (Fstring_equal (oldval, arg), Qt))
1570 return;
1572 if (SYMBOLP (arg) && SYMBOLP (oldval) && EQ (arg, oldval))
1573 return;
1575 BLOCK_INPUT;
1577 result = x_bitmap_icon (f, arg);
1578 if (result)
1580 UNBLOCK_INPUT;
1581 error ("No icon window available");
1584 UNBLOCK_INPUT;
1586 #endif /* MAC_TODO */
1588 void
1589 x_set_icon_name (f, arg, oldval)
1590 struct frame *f;
1591 Lisp_Object arg, oldval;
1593 int result;
1595 if (STRINGP (arg))
1597 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1598 return;
1600 else if (!NILP (arg) || NILP (oldval))
1601 return;
1603 f->icon_name = arg;
1605 #if 0 /* MAC_TODO */
1606 if (f->output_data.w32->icon_bitmap != 0)
1607 return;
1609 BLOCK_INPUT;
1611 result = x_text_icon (f,
1612 (char *) SDATA ((!NILP (f->icon_name)
1613 ? f->icon_name
1614 : !NILP (f->title)
1615 ? f->title
1616 : f->name)));
1618 if (result)
1620 UNBLOCK_INPUT;
1621 error ("No icon window available");
1624 /* If the window was unmapped (and its icon was mapped),
1625 the new icon is not mapped, so map the window in its stead. */
1626 if (FRAME_VISIBLE_P (f))
1628 #ifdef USE_X_TOOLKIT
1629 XtPopup (f->output_data.w32->widget, XtGrabNone);
1630 #endif
1631 XMapWindow (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f));
1634 XFlush (FRAME_W32_DISPLAY (f));
1635 UNBLOCK_INPUT;
1636 #endif /* MAC_TODO */
1640 void
1641 x_set_menu_bar_lines (f, value, oldval)
1642 struct frame *f;
1643 Lisp_Object value, oldval;
1645 /* Make sure we redisplay all windows in this frame. */
1646 windows_or_buffers_changed++;
1648 FRAME_MENU_BAR_LINES (f) = 0;
1649 /* The menu bar is always shown. */
1650 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1651 if (FRAME_MAC_P (f) && f->output_data.mac->menubar_widget == 0)
1652 /* Make sure next redisplay shows the menu bar. */
1653 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1654 adjust_glyphs (f);
1658 /* Set the number of lines used for the tool bar of frame F to VALUE.
1659 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1660 is the old number of tool bar lines. This function changes the
1661 height of all windows on frame F to match the new tool bar height.
1662 The frame's height doesn't change. */
1664 void
1665 x_set_tool_bar_lines (f, value, oldval)
1666 struct frame *f;
1667 Lisp_Object value, oldval;
1669 int delta, nlines, root_height;
1670 Lisp_Object root_window;
1672 /* Treat tool bars like menu bars. */
1673 if (FRAME_MINIBUF_ONLY_P (f))
1674 return;
1676 /* Use VALUE only if an integer >= 0. */
1677 if (INTEGERP (value) && XINT (value) >= 0)
1678 nlines = XFASTINT (value);
1679 else
1680 nlines = 0;
1682 /* Make sure we redisplay all windows in this frame. */
1683 ++windows_or_buffers_changed;
1685 #if USE_MAC_TOOLBAR
1686 FRAME_TOOL_BAR_LINES (f) = 0;
1687 if (nlines)
1689 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1690 if (FRAME_MAC_P (f)
1691 && !mac_is_window_toolbar_visible (FRAME_MAC_WINDOW (f)))
1692 /* Make sure next redisplay shows the tool bar. */
1693 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1695 else
1697 if (FRAME_EXTERNAL_TOOL_BAR (f))
1698 free_frame_tool_bar (f);
1699 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1702 return;
1703 #endif
1705 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1707 /* Don't resize the tool-bar to more than we have room for. */
1708 root_window = FRAME_ROOT_WINDOW (f);
1709 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1710 if (root_height - delta < 1)
1712 delta = root_height - 1;
1713 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1716 FRAME_TOOL_BAR_LINES (f) = nlines;
1717 change_window_heights (root_window, delta);
1718 adjust_glyphs (f);
1720 /* We also have to make sure that the internal border at the top of
1721 the frame, below the menu bar or tool bar, is redrawn when the
1722 tool bar disappears. This is so because the internal border is
1723 below the tool bar if one is displayed, but is below the menu bar
1724 if there isn't a tool bar. The tool bar draws into the area
1725 below the menu bar. */
1726 if (FRAME_MAC_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1728 updating_frame = f;
1729 clear_frame ();
1730 clear_current_matrices (f);
1731 updating_frame = NULL;
1734 /* If the tool bar gets smaller, the internal border below it
1735 has to be cleared. It was formerly part of the display
1736 of the larger tool bar, and updating windows won't clear it. */
1737 if (delta < 0)
1739 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1740 int width = FRAME_PIXEL_WIDTH (f);
1741 int y = nlines * FRAME_LINE_HEIGHT (f);
1743 BLOCK_INPUT;
1744 mac_clear_area (f, 0, y, width, height);
1745 UNBLOCK_INPUT;
1747 if (WINDOWP (f->tool_bar_window))
1748 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1754 /* Set the Mac window title to NAME for frame F. */
1756 static void
1757 x_set_name_internal (f, name)
1758 FRAME_PTR f;
1759 Lisp_Object name;
1761 if (FRAME_MAC_WINDOW (f))
1763 if (STRING_MULTIBYTE (name))
1764 #if TARGET_API_MAC_CARBON
1765 name = ENCODE_UTF_8 (name);
1766 #else
1767 name = ENCODE_SYSTEM (name);
1768 #endif
1770 BLOCK_INPUT;
1773 #if TARGET_API_MAC_CARBON
1774 CFStringRef windowTitle =
1775 cfstring_create_with_utf8_cstring (SDATA (name));
1777 mac_set_window_title (FRAME_MAC_WINDOW (f), windowTitle);
1778 CFRelease (windowTitle);
1779 #else
1780 Str255 windowTitle;
1781 if (strlen (SDATA (name)) < 255)
1783 strcpy (windowTitle, SDATA (name));
1784 c2pstr (windowTitle);
1785 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
1787 #endif
1790 UNBLOCK_INPUT;
1794 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1795 mac_id_name.
1797 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1798 name; if NAME is a string, set F's name to NAME and set
1799 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1801 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1802 suggesting a new name, which lisp code should override; if
1803 F->explicit_name is set, ignore the new name; otherwise, set it. */
1805 void
1806 x_set_name (f, name, explicit)
1807 struct frame *f;
1808 Lisp_Object name;
1809 int explicit;
1811 /* Make sure that requests from lisp code override requests from
1812 Emacs redisplay code. */
1813 if (explicit)
1815 /* If we're switching from explicit to implicit, we had better
1816 update the mode lines and thereby update the title. */
1817 if (f->explicit_name && NILP (name))
1818 update_mode_lines = 1;
1820 f->explicit_name = ! NILP (name);
1822 else if (f->explicit_name)
1823 return;
1825 /* If NAME is nil, set the name to the mac_id_name. */
1826 if (NILP (name))
1828 /* Check for no change needed in this very common case
1829 before we do any consing. */
1830 if (!strcmp (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name,
1831 SDATA (f->name)))
1832 return;
1833 name = build_string (FRAME_MAC_DISPLAY_INFO (f)->mac_id_name);
1835 else
1836 CHECK_STRING (name);
1838 /* Don't change the name if it's already NAME. */
1839 if (! NILP (Fstring_equal (name, f->name)))
1840 return;
1842 f->name = name;
1844 /* For setting the frame title, the title parameter should override
1845 the name parameter. */
1846 if (! NILP (f->title))
1847 name = f->title;
1849 x_set_name_internal (f, name);
1852 /* This function should be called when the user's lisp code has
1853 specified a name for the frame; the name will override any set by the
1854 redisplay code. */
1855 void
1856 x_explicitly_set_name (f, arg, oldval)
1857 FRAME_PTR f;
1858 Lisp_Object arg, oldval;
1860 x_set_name (f, arg, 1);
1863 /* This function should be called by Emacs redisplay code to set the
1864 name; names set this way will never override names set by the user's
1865 lisp code. */
1866 void
1867 x_implicitly_set_name (f, arg, oldval)
1868 FRAME_PTR f;
1869 Lisp_Object arg, oldval;
1871 x_set_name (f, arg, 0);
1874 /* Change the title of frame F to NAME.
1875 If NAME is nil, use the frame name as the title. */
1877 void
1878 x_set_title (f, name, old_name)
1879 struct frame *f;
1880 Lisp_Object name, old_name;
1882 /* Don't change the title if it's already NAME. */
1883 if (EQ (name, f->title))
1884 return;
1886 update_mode_lines = 1;
1888 f->title = name;
1890 if (NILP (name))
1891 name = f->name;
1892 else
1893 CHECK_STRING (name);
1895 x_set_name_internal (f, name);
1898 void
1899 x_set_scroll_bar_default_width (f)
1900 struct frame *f;
1902 /* Imitate X without X Toolkit */
1904 int wid = FRAME_COLUMN_WIDTH (f);
1906 #ifdef MAC_OSX
1907 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH;
1908 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
1909 wid - 1) / wid;
1910 #else /* not MAC_OSX */
1911 /* Make the actual width at least 14 pixels and a multiple of a
1912 character width. */
1913 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1915 /* Use all of that space (aside from required margins) for the
1916 scroll bar. */
1917 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1918 #endif /* not MAC_OSX */
1921 static void
1922 mac_set_font (f, arg, oldval)
1923 struct frame *f;
1924 Lisp_Object arg, oldval;
1926 x_set_font (f, arg, oldval);
1927 #if USE_MAC_FONT_PANEL
1929 Lisp_Object focus_frame = x_get_focus_frame (f);
1931 if ((NILP (focus_frame) && f == SELECTED_FRAME ())
1932 || XFRAME (focus_frame) == f)
1934 BLOCK_INPUT;
1935 mac_set_font_info_for_selection (f, DEFAULT_FACE_ID, 0);
1936 UNBLOCK_INPUT;
1939 #endif
1942 void
1943 mac_update_title_bar (f, save_match_data)
1944 struct frame *f;
1945 int save_match_data;
1947 #if TARGET_API_MAC_CARBON
1948 struct window *w;
1949 int modified_p;
1951 if (!FRAME_MAC_P (f))
1952 return;
1954 w = XWINDOW (FRAME_SELECTED_WINDOW (f));
1955 modified_p = (BUF_SAVE_MODIFF (XBUFFER (w->buffer))
1956 < BUF_MODIFF (XBUFFER (w->buffer)));
1957 if (windows_or_buffers_changed
1958 /* Minibuffer modification status shown in the close button is
1959 confusing. */
1960 || (!MINI_WINDOW_P (w)
1961 && (modified_p != !NILP (w->last_had_star))))
1963 BLOCK_INPUT;
1964 mac_set_window_modified (FRAME_MAC_WINDOW (f),
1965 !MINI_WINDOW_P (w) && modified_p);
1966 mac_update_proxy_icon (f);
1967 UNBLOCK_INPUT;
1969 #endif
1973 /* Subroutines of creating a frame. */
1975 /* Retrieve the string resource specified by NAME with CLASS from
1976 database RDB.
1978 The return value points to the contents of a Lisp string. So it
1979 will not be valid after the next GC where string compaction will
1980 occur. */
1982 char *
1983 x_get_string_resource (rdb, name, class)
1984 XrmDatabase rdb;
1985 char *name, *class;
1987 Lisp_Object value = xrm_get_resource (rdb, name, class);
1989 if (STRINGP (value))
1990 return SDATA (value);
1991 else
1992 return NULL;
1995 /* Return the value of parameter PARAM.
1997 First search ALIST, then Vdefault_frame_alist, then the X defaults
1998 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2000 Convert the resource to the type specified by desired_type.
2002 If no default is specified, return Qunbound. If you call
2003 mac_get_arg, make sure you deal with Qunbound in a reasonable way,
2004 and don't let it get stored in any Lisp-visible variables! */
2006 static Lisp_Object
2007 mac_get_arg (alist, param, attribute, class, type)
2008 Lisp_Object alist, param;
2009 char *attribute;
2010 char *class;
2011 enum resource_types type;
2013 return x_get_arg (check_x_display_info (Qnil),
2014 alist, param, attribute, class, type);
2018 /* XParseGeometry copied from w32xfns.c */
2021 * XParseGeometry parses strings of the form
2022 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
2023 * width, height, xoffset, and yoffset are unsigned integers.
2024 * Example: "=80x24+300-49"
2025 * The equal sign is optional.
2026 * It returns a bitmask that indicates which of the four values
2027 * were actually found in the string. For each value found,
2028 * the corresponding argument is updated; for each value
2029 * not found, the corresponding argument is left unchanged.
2032 static int
2033 read_integer (string, NextString)
2034 register char *string;
2035 char **NextString;
2037 register int Result = 0;
2038 int Sign = 1;
2040 if (*string == '+')
2041 string++;
2042 else if (*string == '-')
2044 string++;
2045 Sign = -1;
2047 for (; (*string >= '0') && (*string <= '9'); string++)
2049 Result = (Result * 10) + (*string - '0');
2051 *NextString = string;
2052 if (Sign >= 0)
2053 return (Result);
2054 else
2055 return (-Result);
2059 XParseGeometry (string, x, y, width, height)
2060 char *string;
2061 int *x, *y;
2062 unsigned int *width, *height; /* RETURN */
2064 int mask = NoValue;
2065 register char *strind;
2066 unsigned int tempWidth, tempHeight;
2067 int tempX, tempY;
2068 char *nextCharacter;
2070 if ((string == NULL) || (*string == '\0')) return (mask);
2071 if (*string == '=')
2072 string++; /* ignore possible '=' at beg of geometry spec */
2074 strind = (char *)string;
2075 if (*strind != '+' && *strind != '-' && *strind != 'x')
2077 tempWidth = read_integer (strind, &nextCharacter);
2078 if (strind == nextCharacter)
2079 return (0);
2080 strind = nextCharacter;
2081 mask |= WidthValue;
2084 if (*strind == 'x' || *strind == 'X')
2086 strind++;
2087 tempHeight = read_integer (strind, &nextCharacter);
2088 if (strind == nextCharacter)
2089 return (0);
2090 strind = nextCharacter;
2091 mask |= HeightValue;
2094 if ((*strind == '+') || (*strind == '-'))
2096 if (*strind == '-')
2098 strind++;
2099 tempX = -read_integer (strind, &nextCharacter);
2100 if (strind == nextCharacter)
2101 return (0);
2102 strind = nextCharacter;
2103 mask |= XNegative;
2106 else
2108 strind++;
2109 tempX = read_integer (strind, &nextCharacter);
2110 if (strind == nextCharacter)
2111 return (0);
2112 strind = nextCharacter;
2114 mask |= XValue;
2115 if ((*strind == '+') || (*strind == '-'))
2117 if (*strind == '-')
2119 strind++;
2120 tempY = -read_integer (strind, &nextCharacter);
2121 if (strind == nextCharacter)
2122 return (0);
2123 strind = nextCharacter;
2124 mask |= YNegative;
2127 else
2129 strind++;
2130 tempY = read_integer (strind, &nextCharacter);
2131 if (strind == nextCharacter)
2132 return (0);
2133 strind = nextCharacter;
2135 mask |= YValue;
2139 /* If strind isn't at the end of the string the it's an invalid
2140 geometry specification. */
2142 if (*strind != '\0') return (0);
2144 if (mask & XValue)
2145 *x = tempX;
2146 if (mask & YValue)
2147 *y = tempY;
2148 if (mask & WidthValue)
2149 *width = tempWidth;
2150 if (mask & HeightValue)
2151 *height = tempHeight;
2152 return (mask);
2156 /* Create and set up the Mac window for frame F. */
2158 static void
2159 mac_window (f)
2160 struct frame *f;
2162 BLOCK_INPUT;
2164 mac_create_frame_window (f, 0);
2166 if (FRAME_MAC_WINDOW (f))
2167 mac_set_frame_window_background (f, FRAME_BACKGROUND_PIXEL (f));
2169 #if USE_MAC_TOOLBAR
2170 /* At the moment, the size of the tool bar is not yet known. We
2171 record the gravity value of the newly created window and use it
2172 to adjust the position of the window (especially for a negative
2173 specification of its vertical position) when the tool bar is
2174 first redisplayed. */
2175 if (FRAME_EXTERNAL_TOOL_BAR (f))
2176 f->output_data.mac->toolbar_win_gravity = f->win_gravity;
2177 #endif
2179 validate_x_resource_name ();
2181 /* x_set_name normally ignores requests to set the name if the
2182 requested name is the same as the current name. This is the one
2183 place where that assumption isn't correct; f->name is set, but
2184 the server hasn't been told. */
2186 Lisp_Object name;
2187 int explicit = f->explicit_name;
2189 f->explicit_name = 0;
2190 name = f->name;
2191 f->name = Qnil;
2192 x_set_name (f, name, explicit);
2195 UNBLOCK_INPUT;
2197 if (FRAME_MAC_WINDOW (f) == 0)
2198 error ("Unable to create window");
2201 /* Handle the icon stuff for this window. Perhaps later we might
2202 want an x_set_icon_position which can be called interactively as
2203 well. */
2205 static void
2206 x_icon (f, parms)
2207 struct frame *f;
2208 Lisp_Object parms;
2210 Lisp_Object icon_x, icon_y;
2212 /* Set the position of the icon. Note that Windows 95 groups all
2213 icons in the tray. */
2214 icon_x = mac_get_arg (parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2215 icon_y = mac_get_arg (parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2216 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2218 CHECK_NUMBER (icon_x);
2219 CHECK_NUMBER (icon_y);
2221 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2222 error ("Both left and top icon corners of icon must be specified");
2224 BLOCK_INPUT;
2226 if (! EQ (icon_x, Qunbound))
2227 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2229 #if 0 /* TODO */
2230 /* Start up iconic or window? */
2231 x_wm_set_window_state
2232 (f, (EQ (w32_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL), Qicon)
2233 ? IconicState
2234 : NormalState));
2236 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2237 ? f->icon_name
2238 : f->name)));
2239 #endif
2241 UNBLOCK_INPUT;
2245 void
2246 x_make_gc (f)
2247 struct frame *f;
2249 XGCValues gc_values;
2251 BLOCK_INPUT;
2253 /* Create the GCs of this frame.
2254 Note that many default values are used. */
2256 /* Normal video */
2257 gc_values.font = FRAME_FONT (f);
2258 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2259 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2260 f->output_data.mac->normal_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2261 FRAME_MAC_WINDOW (f),
2262 GCFont | GCForeground | GCBackground,
2263 &gc_values);
2265 /* Reverse video style. */
2266 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2267 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2268 f->output_data.mac->reverse_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2269 FRAME_MAC_WINDOW (f),
2270 GCFont | GCForeground | GCBackground,
2271 &gc_values);
2273 /* Cursor has cursor-color background, background-color foreground. */
2274 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2275 gc_values.background = f->output_data.mac->cursor_pixel;
2276 f->output_data.mac->cursor_gc = XCreateGC (FRAME_MAC_DISPLAY (f),
2277 FRAME_MAC_WINDOW (f),
2278 GCFont | GCForeground | GCBackground,
2279 &gc_values);
2281 /* Reliefs. */
2282 f->output_data.mac->white_relief.gc = 0;
2283 f->output_data.mac->black_relief.gc = 0;
2285 #if 0
2286 /* Create the gray border tile used when the pointer is not in
2287 the frame. Since this depends on the frame's pixel values,
2288 this must be done on a per-frame basis. */
2289 f->output_data.x->border_tile
2290 = (XCreatePixmapFromBitmapData
2291 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2292 gray_bits, gray_width, gray_height,
2293 f->output_data.x->foreground_pixel,
2294 f->output_data.x->background_pixel,
2295 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2296 #endif
2298 UNBLOCK_INPUT;
2302 /* Free what was was allocated in x_make_gc. */
2304 void
2305 x_free_gcs (f)
2306 struct frame *f;
2308 Display *dpy = FRAME_MAC_DISPLAY (f);
2310 BLOCK_INPUT;
2312 if (f->output_data.mac->normal_gc)
2314 XFreeGC (dpy, f->output_data.mac->normal_gc);
2315 f->output_data.mac->normal_gc = 0;
2318 if (f->output_data.mac->reverse_gc)
2320 XFreeGC (dpy, f->output_data.mac->reverse_gc);
2321 f->output_data.mac->reverse_gc = 0;
2324 if (f->output_data.mac->cursor_gc)
2326 XFreeGC (dpy, f->output_data.mac->cursor_gc);
2327 f->output_data.mac->cursor_gc = 0;
2330 #if 0
2331 if (f->output_data.mac->border_tile)
2333 XFreePixmap (dpy, f->output_data.mac->border_tile);
2334 f->output_data.mac->border_tile = 0;
2336 #endif
2338 if (f->output_data.mac->white_relief.gc)
2340 XFreeGC (dpy, f->output_data.mac->white_relief.gc);
2341 f->output_data.mac->white_relief.gc = 0;
2344 if (f->output_data.mac->black_relief.gc)
2346 XFreeGC (dpy, f->output_data.mac->black_relief.gc);
2347 f->output_data.mac->black_relief.gc = 0;
2350 UNBLOCK_INPUT;
2354 /* Handler for signals raised during x_create_frame and
2355 x_create_top_frame. FRAME is the frame which is partially
2356 constructed. */
2358 static Lisp_Object
2359 unwind_create_frame (frame)
2360 Lisp_Object frame;
2362 struct frame *f = XFRAME (frame);
2364 /* If frame is ``official'', nothing to do. */
2365 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
2367 #if GLYPH_DEBUG
2368 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2369 #endif
2371 x_free_frame_resources (f);
2373 #if GLYPH_DEBUG
2374 /* Check that reference counts are indeed correct. */
2375 xassert (dpyinfo->reference_count == dpyinfo_refcount);
2376 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
2377 #endif
2378 return Qt;
2381 return Qnil;
2385 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2386 1, 1, 0,
2387 doc: /* Make a new window, which is called a "frame" in Emacs terms.
2388 Return an Emacs frame object.
2389 ALIST is an alist of frame parameters.
2390 If the parameters specify that the frame should not have a minibuffer,
2391 and do not specify a specific minibuffer window to use,
2392 then `default-minibuffer-frame' must be a frame whose minibuffer can
2393 be shared by the new frame.
2395 This function is an internal primitive--use `make-frame' instead. */)
2396 (parms)
2397 Lisp_Object parms;
2399 struct frame *f;
2400 Lisp_Object frame, tem;
2401 Lisp_Object name;
2402 int minibuffer_only = 0;
2403 long window_prompting = 0;
2404 int width, height;
2405 int count = SPECPDL_INDEX ();
2406 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2407 Lisp_Object display;
2408 struct mac_display_info *dpyinfo = NULL;
2409 Lisp_Object parent;
2410 struct kboard *kb;
2412 check_mac ();
2414 parms = Fcopy_alist (parms);
2416 /* Use this general default value to start with
2417 until we know if this frame has a specified name. */
2418 Vx_resource_name = Vinvocation_name;
2420 display = mac_get_arg (parms, Qdisplay, 0, 0, RES_TYPE_STRING);
2421 if (EQ (display, Qunbound))
2422 display = Qnil;
2423 dpyinfo = check_x_display_info (display);
2424 #ifdef MULTI_KBOARD
2425 kb = dpyinfo->kboard;
2426 #else
2427 kb = &the_only_kboard;
2428 #endif
2430 name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
2431 if (!STRINGP (name)
2432 && ! EQ (name, Qunbound)
2433 && ! NILP (name))
2434 error ("Invalid frame name--not a string or nil");
2436 if (STRINGP (name))
2437 Vx_resource_name = name;
2439 /* See if parent window is specified. */
2440 parent = mac_get_arg (parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
2441 if (EQ (parent, Qunbound))
2442 parent = Qnil;
2443 if (! NILP (parent))
2444 CHECK_NUMBER (parent);
2446 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2447 /* No need to protect DISPLAY because that's not used after passing
2448 it to make_frame_without_minibuffer. */
2449 frame = Qnil;
2450 GCPRO4 (parms, parent, name, frame);
2451 tem = mac_get_arg (parms, Qminibuffer, "minibuffer", "Minibuffer",
2452 RES_TYPE_SYMBOL);
2453 if (EQ (tem, Qnone) || NILP (tem))
2454 f = make_frame_without_minibuffer (Qnil, kb, display);
2455 else if (EQ (tem, Qonly))
2457 f = make_minibuffer_frame ();
2458 minibuffer_only = 1;
2460 else if (WINDOWP (tem))
2461 f = make_frame_without_minibuffer (tem, kb, display);
2462 else
2463 f = make_frame (1);
2465 XSETFRAME (frame, f);
2467 /* Note that X Windows does support scroll bars. */
2468 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
2470 f->output_method = output_mac;
2471 f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output));
2472 bzero (f->output_data.mac, sizeof (struct mac_output));
2473 FRAME_FONTSET (f) = -1;
2475 f->icon_name
2476 = mac_get_arg (parms, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
2477 if (! STRINGP (f->icon_name))
2478 f->icon_name = Qnil;
2480 /* FRAME_MAC_DISPLAY_INFO (f) = dpyinfo; */
2482 /* With FRAME_MAC_DISPLAY_INFO set up, this unwind-protect is safe. */
2483 record_unwind_protect (unwind_create_frame, frame);
2484 #if GLYPH_DEBUG
2485 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
2486 dpyinfo_refcount = dpyinfo->reference_count;
2487 #endif /* GLYPH_DEBUG */
2488 #ifdef MULTI_KBOARD
2489 FRAME_KBOARD (f) = kb;
2490 #endif
2492 /* Specify the parent under which to make this window. */
2494 if (!NILP (parent))
2496 f->output_data.mac->parent_desc = (Window) XFASTINT (parent);
2497 f->output_data.mac->explicit_parent = 1;
2499 else
2501 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
2502 f->output_data.mac->explicit_parent = 0;
2505 /* Set the name; the functions to which we pass f expect the name to
2506 be set. */
2507 if (EQ (name, Qunbound) || NILP (name))
2509 f->name = build_string (dpyinfo->mac_id_name);
2510 f->explicit_name = 0;
2512 else
2514 f->name = name;
2515 f->explicit_name = 1;
2516 /* use the frame's title when getting resources for this frame. */
2517 specbind (Qx_resource_name, name);
2520 /* Extract the window parameters from the supplied values
2521 that are needed to determine window geometry. */
2523 Lisp_Object font;
2525 font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
2527 BLOCK_INPUT;
2528 /* First, try whatever font the caller has specified. */
2529 if (STRINGP (font))
2531 tem = Fquery_fontset (font, Qnil);
2532 if (STRINGP (tem))
2533 font = x_new_fontset (f, SDATA (tem));
2534 else
2535 font = x_new_font (f, SDATA (font));
2538 /* Try out a font which we hope has bold and italic variations. */
2539 #if USE_ATSUI
2540 if (! STRINGP (font))
2541 font = x_new_font (f, "-*-monaco-medium-r-normal--12-*-*-*-*-*-iso10646-1");
2542 #endif
2543 if (! STRINGP (font))
2544 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
2545 /* If those didn't work, look for something which will at least work. */
2546 if (! STRINGP (font))
2547 font = x_new_fontset (f, "fontset-standard");
2548 if (! STRINGP (font))
2549 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
2550 if (! STRINGP (font))
2551 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
2552 if (! STRINGP (font))
2553 error ("Cannot find any usable font");
2554 UNBLOCK_INPUT;
2556 x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil));
2559 x_default_parameter (f, parms, Qborder_width, make_number (0),
2560 "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
2561 /* This defaults to 2 in order to match xterm. We recognize either
2562 internalBorderWidth or internalBorder (which is what xterm calls
2563 it). */
2564 if (NILP (Fassq (Qinternal_border_width, parms)))
2566 Lisp_Object value;
2568 value = mac_get_arg (parms, Qinternal_border_width,
2569 "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
2570 if (! EQ (value, Qunbound))
2571 parms = Fcons (Fcons (Qinternal_border_width, value),
2572 parms);
2574 /* Default internalBorderWidth to 0 on Windows to match other programs. */
2575 x_default_parameter (f, parms, Qinternal_border_width, make_number (0),
2576 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
2577 x_default_parameter (f, parms, Qvertical_scroll_bars, Qright,
2578 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
2580 /* Also do the stuff which must be set before the window exists. */
2581 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
2582 "foreground", "Foreground", RES_TYPE_STRING);
2583 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
2584 "background", "Background", RES_TYPE_STRING);
2585 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
2586 "pointerColor", "Foreground", RES_TYPE_STRING);
2587 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
2588 "cursorColor", "Foreground", RES_TYPE_STRING);
2589 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
2590 "borderColor", "BorderColor", RES_TYPE_STRING);
2591 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
2592 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
2593 x_default_parameter (f, parms, Qline_spacing, Qnil,
2594 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
2595 x_default_parameter (f, parms, Qleft_fringe, Qnil,
2596 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
2597 x_default_parameter (f, parms, Qright_fringe, Qnil,
2598 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
2601 /* Init faces before x_default_parameter is called for scroll-bar
2602 parameters because that function calls x_set_scroll_bar_width,
2603 which calls change_frame_size, which calls Fset_window_buffer,
2604 which runs hooks, which call Fvertical_motion. At the end, we
2605 end up in init_iterator with a null face cache, which should not
2606 happen. */
2607 init_frame_faces (f);
2609 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
2610 "menuBar", "MenuBar", RES_TYPE_NUMBER);
2611 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
2612 "toolBar", "ToolBar", RES_TYPE_NUMBER);
2613 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
2614 "bufferPredicate", "BufferPredicate",
2615 RES_TYPE_SYMBOL);
2616 x_default_parameter (f, parms, Qtitle, Qnil,
2617 "title", "Title", RES_TYPE_STRING);
2618 x_default_parameter (f, parms, Qfullscreen, Qnil,
2619 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
2621 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
2623 /* Compute the size of the window. */
2624 window_prompting = x_figure_window_size (f, parms, 1);
2626 tem = mac_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
2627 f->no_split = minibuffer_only || EQ (tem, Qt);
2629 mac_window (f);
2631 x_icon (f, parms);
2632 x_make_gc (f);
2634 /* Now consider the frame official. */
2635 FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
2636 Vframe_list = Fcons (frame, Vframe_list);
2638 /* We need to do this after creating the window, so that the
2639 icon-creation functions can say whose icon they're describing. */
2640 x_default_parameter (f, parms, Qicon_type, Qnil,
2641 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
2643 x_default_parameter (f, parms, Qauto_raise, Qnil,
2644 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2645 x_default_parameter (f, parms, Qauto_lower, Qnil,
2646 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
2647 x_default_parameter (f, parms, Qcursor_type, Qbox,
2648 "cursorType", "CursorType", RES_TYPE_SYMBOL);
2649 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
2650 "scrollBarWidth", "ScrollBarWidth",
2651 RES_TYPE_NUMBER);
2653 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
2654 Change will not be effected unless different from the current
2655 FRAME_LINES (f). */
2656 width = FRAME_COLS (f);
2657 height = FRAME_LINES (f);
2659 SET_FRAME_COLS (f, 0);
2660 FRAME_LINES (f) = 0;
2661 change_frame_size (f, height, width, 1, 0, 0);
2663 /* Tell the server what size and position, etc, we want, and how
2664 badly we want them. This should be done after we have the menu
2665 bar so that its size can be taken into account. */
2666 BLOCK_INPUT;
2667 x_wm_set_size_hint (f, window_prompting, 0);
2668 UNBLOCK_INPUT;
2670 /* Make the window appear on the frame and enable display, unless
2671 the caller says not to. However, with explicit parent, Emacs
2672 cannot control visibility, so don't try. */
2673 if (! f->output_data.mac->explicit_parent)
2675 Lisp_Object visibility;
2677 visibility = mac_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
2678 if (EQ (visibility, Qunbound))
2679 visibility = Qt;
2681 if (EQ (visibility, Qicon))
2682 x_iconify_frame (f);
2683 else if (! NILP (visibility))
2684 x_make_frame_visible (f);
2685 else
2686 /* Must have been Qnil. */
2690 /* Initialize `default-minibuffer-frame' in case this is the first
2691 frame on this display device. */
2692 if (FRAME_HAS_MINIBUF_P (f)
2693 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
2694 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
2695 kb->Vdefault_minibuffer_frame = frame;
2697 /* All remaining specified parameters, which have not been "used"
2698 by x_get_arg and friends, now go in the misc. alist of the frame. */
2699 for (tem = parms; !NILP (tem); tem = XCDR (tem))
2700 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
2701 f->param_alist = Fcons (XCAR (tem), f->param_alist);
2703 UNGCPRO;
2705 /* Make sure windows on this frame appear in calls to next-window
2706 and similar functions. */
2707 Vwindow_list = Qnil;
2709 return unbind_to (count, frame);
2713 /* FRAME is used only to get a handle on the X display. We don't pass the
2714 display info directly because we're called from frame.c, which doesn't
2715 know about that structure. */
2717 Lisp_Object
2718 x_get_focus_frame (frame)
2719 struct frame *frame;
2721 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
2722 Lisp_Object xfocus;
2723 if (! dpyinfo->x_focus_frame)
2724 return Qnil;
2726 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
2727 return xfocus;
2731 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
2732 doc: /* Set the input focus to FRAME.
2733 FRAME nil means use the selected frame. */)
2734 (frame)
2735 Lisp_Object frame;
2737 OSErr err;
2738 ProcessSerialNumber front_psn;
2739 static const ProcessSerialNumber current_psn = {0, kCurrentProcess};
2740 Boolean front_p;
2741 struct frame *f = check_x_frame (frame);
2743 BLOCK_INPUT;
2744 /* Move the current process to the foreground if it is not. Don't
2745 call SetFrontProcess if the current process is already running in
2746 the foreground so as not to change the z-order of windows. */
2747 err = GetFrontProcess (&front_psn);
2748 if (err == noErr)
2749 err = SameProcess (&front_psn, &current_psn, &front_p);
2750 if (err == noErr)
2751 if (!front_p)
2753 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
2754 if (mac_front_non_floating_window () == FRAME_MAC_WINDOW (f))
2755 SetFrontProcessWithOptions (&current_psn,
2756 kSetFrontProcessFrontWindowOnly);
2757 else
2758 #endif
2759 SetFrontProcess (&current_psn);
2762 #ifdef MAC_OSX
2763 mac_activate_window (mac_active_non_floating_window (), false);
2764 mac_activate_window (FRAME_MAC_WINDOW (f), true);
2765 #else
2766 #if !TARGET_API_MAC_CARBON
2767 /* SelectWindow (Non-Carbon) does not issue deactivate events if the
2768 possibly inactive window that is to be selected is already the
2769 frontmost one. */
2770 SendBehind (FRAME_MAC_WINDOW (f), NULL);
2771 #endif
2772 /* This brings the window to the front. */
2773 SelectWindow (FRAME_MAC_WINDOW (f));
2774 #endif
2775 UNBLOCK_INPUT;
2777 return Qnil;
2781 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
2782 doc: /* Internal function called by `color-defined-p', which see. */)
2783 (color, frame)
2784 Lisp_Object color, frame;
2786 XColor foo;
2787 FRAME_PTR f = check_x_frame (frame);
2789 CHECK_STRING (color);
2791 if (mac_defined_color (f, SDATA (color), &foo, 0))
2792 return Qt;
2793 else
2794 return Qnil;
2797 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2798 doc: /* Internal function called by `color-values', which see. */)
2799 (color, frame)
2800 Lisp_Object color, frame;
2802 XColor foo;
2803 FRAME_PTR f = check_x_frame (frame);
2805 CHECK_STRING (color);
2807 if (mac_defined_color (f, SDATA (color), &foo, 0))
2808 return list3 (make_number (foo.red),
2809 make_number (foo.green),
2810 make_number (foo.blue));
2811 else
2812 return Qnil;
2815 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2816 doc: /* Internal function called by `display-color-p', which see. */)
2817 (display)
2818 Lisp_Object display;
2820 struct mac_display_info *dpyinfo = check_x_display_info (display);
2822 if (!dpyinfo->color_p)
2823 return Qnil;
2825 return Qt;
2828 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
2829 0, 1, 0,
2830 doc: /* Return t if DISPLAY supports shades of gray.
2831 Note that color displays do support shades of gray.
2832 The optional argument DISPLAY specifies which display to ask about.
2833 DISPLAY should be either a frame or a display name (a string).
2834 If omitted or nil, that stands for the selected frame's display. */)
2835 (display)
2836 Lisp_Object display;
2838 struct mac_display_info *dpyinfo = check_x_display_info (display);
2840 if (dpyinfo->n_planes <= 1)
2841 return Qnil;
2843 return Qt;
2846 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2847 0, 1, 0,
2848 doc: /* Return the width in pixels of DISPLAY.
2849 The optional argument DISPLAY specifies which display to ask about.
2850 DISPLAY should be either a frame or a display name (a string).
2851 If omitted or nil, that stands for the selected frame's display. */)
2852 (display)
2853 Lisp_Object display;
2855 struct mac_display_info *dpyinfo = check_x_display_info (display);
2857 return make_number (dpyinfo->width);
2860 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2861 Sx_display_pixel_height, 0, 1, 0,
2862 doc: /* Return the height in pixels of DISPLAY.
2863 The optional argument DISPLAY specifies which display to ask about.
2864 DISPLAY should be either a frame or a display name (a string).
2865 If omitted or nil, that stands for the selected frame's display. */)
2866 (display)
2867 Lisp_Object display;
2869 struct mac_display_info *dpyinfo = check_x_display_info (display);
2871 return make_number (dpyinfo->height);
2874 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2875 0, 1, 0,
2876 doc: /* Return the number of bitplanes of DISPLAY.
2877 The optional argument DISPLAY specifies which display to ask about.
2878 DISPLAY should be either a frame or a display name (a string).
2879 If omitted or nil, that stands for the selected frame's display. */)
2880 (display)
2881 Lisp_Object display;
2883 struct mac_display_info *dpyinfo = check_x_display_info (display);
2885 return make_number (dpyinfo->n_planes);
2888 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2889 0, 1, 0,
2890 doc: /* Return the number of color cells of DISPLAY.
2891 The optional argument DISPLAY specifies which display to ask about.
2892 DISPLAY should be either a frame or a display name (a string).
2893 If omitted or nil, that stands for the selected frame's display. */)
2894 (display)
2895 Lisp_Object display;
2897 struct mac_display_info *dpyinfo = check_x_display_info (display);
2899 /* We force 24+ bit depths to 24-bit to prevent an overflow. */
2900 return make_number (1 << min (dpyinfo->n_planes, 24));
2903 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
2904 Sx_server_max_request_size,
2905 0, 1, 0,
2906 doc: /* Return the maximum request size of the server of DISPLAY.
2907 The optional argument DISPLAY specifies which display to ask about.
2908 DISPLAY should be either a frame or a display name (a string).
2909 If omitted or nil, that stands for the selected frame's display. */)
2910 (display)
2911 Lisp_Object display;
2913 struct mac_display_info *dpyinfo = check_x_display_info (display);
2915 return make_number (1);
2918 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
2919 doc: /* Return the "vendor ID" string of the Mac OS system (Apple).
2920 The optional argument DISPLAY specifies which display to ask about.
2921 DISPLAY should be either a frame or a display name (a string).
2922 If omitted or nil, that stands for the selected frame's display. */)
2923 (display)
2924 Lisp_Object display;
2926 return build_string ("Apple Inc.");
2929 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
2930 doc: /* Return the version numbers of the Mac OS system.
2931 The value is a list of three integers: the major and minor
2932 version numbers, and the vendor-specific release
2933 number. See also the function `x-server-vendor'.
2935 The optional argument DISPLAY specifies which display to ask about.
2936 DISPLAY should be either a frame or a display name (a string).
2937 If omitted or nil, that stands for the selected frame's display. */)
2938 (display)
2939 Lisp_Object display;
2941 UInt32 response, major, minor, bugfix;
2942 OSErr err;
2944 BLOCK_INPUT;
2945 err = Gestalt (gestaltSystemVersion, &response);
2946 if (err == noErr)
2948 if (response >= 0x00001040)
2950 err = Gestalt (gestaltSystemVersionMajor, &major);
2951 if (err == noErr)
2952 err = Gestalt (gestaltSystemVersionMinor, &minor);
2953 if (err == noErr)
2954 err = Gestalt (gestaltSystemVersionBugFix, &bugfix);
2956 else
2958 bugfix = response & 0xf;
2959 response >>= 4;
2960 minor = response & 0xf;
2961 response >>= 4;
2962 /* convert BCD to int */
2963 major = response - (response >> 4) * 6;
2966 UNBLOCK_INPUT;
2968 if (err != noErr)
2969 error ("Cannot get Mac OS version");
2971 return Fcons (make_number (major),
2972 Fcons (make_number (minor),
2973 Fcons (make_number (bugfix),
2974 Qnil)));
2977 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
2978 doc: /* Return the number of screens on the server of DISPLAY.
2979 The optional argument DISPLAY specifies which display to ask about.
2980 DISPLAY should be either a frame or a display name (a string).
2981 If omitted or nil, that stands for the selected frame's display. */)
2982 (display)
2983 Lisp_Object display;
2985 return make_number (1);
2988 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
2989 doc: /* Return the height in millimeters of DISPLAY.
2990 The optional argument DISPLAY specifies which display to ask about.
2991 DISPLAY should be either a frame or a display name (a string).
2992 If omitted or nil, that stands for the selected frame's display. */)
2993 (display)
2994 Lisp_Object display;
2996 struct mac_display_info *dpyinfo = check_x_display_info (display);
2997 float mm_per_pixel;
2999 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
3000 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3001 if (CGDisplayScreenSize != NULL)
3002 #endif
3004 CGSize size;
3006 BLOCK_INPUT;
3007 size = CGDisplayScreenSize (kCGDirectMainDisplay);
3008 mm_per_pixel = size.height / CGDisplayPixelsHigh (kCGDirectMainDisplay);
3009 UNBLOCK_INPUT;
3011 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3012 else /* CGDisplayScreenSize == NULL */
3013 #endif
3014 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
3015 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3017 /* This is an approximation. */
3018 mm_per_pixel = 25.4f / dpyinfo->resy;
3020 #endif
3022 return make_number ((int) (dpyinfo->height * mm_per_pixel + 0.5f));
3025 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3026 doc: /* Return the width in millimeters of DISPLAY.
3027 The optional argument DISPLAY specifies which display to ask about.
3028 DISPLAY should be either a frame or a display name (a string).
3029 If omitted or nil, that stands for the selected frame's display. */)
3030 (display)
3031 Lisp_Object display;
3033 struct mac_display_info *dpyinfo = check_x_display_info (display);
3034 float mm_per_pixel;
3036 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
3037 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3038 if (CGDisplayScreenSize != NULL)
3039 #endif
3041 CGSize size;
3043 BLOCK_INPUT;
3044 size = CGDisplayScreenSize (kCGDirectMainDisplay);
3045 mm_per_pixel = size.width / CGDisplayPixelsWide (kCGDirectMainDisplay);
3046 UNBLOCK_INPUT;
3048 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3049 else /* CGDisplayScreenSize == NULL */
3050 #endif
3051 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
3052 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
3054 /* This is an approximation. */
3055 mm_per_pixel = 25.4f / dpyinfo->resx;
3057 #endif
3059 return make_number ((int) (dpyinfo->width * mm_per_pixel + 0.5f));
3062 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3063 Sx_display_backing_store, 0, 1, 0,
3064 doc: /* Return an indication of whether DISPLAY does backing store.
3065 The value may be `always', `when-mapped', or `not-useful'.
3066 The optional argument DISPLAY specifies which display to ask about.
3067 DISPLAY should be either a frame or a display name (a string).
3068 If omitted or nil, that stands for the selected frame's display. */)
3069 (display)
3070 Lisp_Object display;
3072 return intern ("not-useful");
3075 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3076 Sx_display_visual_class, 0, 1, 0,
3077 doc: /* Return the visual class of DISPLAY.
3078 The value is one of the symbols `static-gray', `gray-scale',
3079 `static-color', `pseudo-color', `true-color', or `direct-color'.
3081 The optional argument DISPLAY specifies which display to ask about.
3082 DISPLAY should be either a frame or a display name (a string).
3083 If omitted or nil, that stands for the selected frame's display. */)
3084 (display)
3085 Lisp_Object display;
3087 struct mac_display_info *dpyinfo = check_x_display_info (display);
3089 #if 0
3090 switch (dpyinfo->visual->class)
3092 case StaticGray: return (intern ("static-gray"));
3093 case GrayScale: return (intern ("gray-scale"));
3094 case StaticColor: return (intern ("static-color"));
3095 case PseudoColor: return (intern ("pseudo-color"));
3096 case TrueColor: return (intern ("true-color"));
3097 case DirectColor: return (intern ("direct-color"));
3098 default:
3099 error ("Display has an unknown visual class");
3101 #endif /* 0 */
3103 return (intern ("true-color"));
3106 DEFUN ("x-display-save-under", Fx_display_save_under,
3107 Sx_display_save_under, 0, 1, 0,
3108 doc: /* Return t if DISPLAY supports the save-under feature.
3109 The optional argument DISPLAY specifies which display to ask about.
3110 DISPLAY should be either a frame or a display name (a string).
3111 If omitted or nil, that stands for the selected frame's display. */)
3112 (display)
3113 Lisp_Object display;
3115 return Qnil;
3119 x_pixel_width (f)
3120 register struct frame *f;
3122 return FRAME_PIXEL_WIDTH (f);
3126 x_pixel_height (f)
3127 register struct frame *f;
3129 return FRAME_PIXEL_HEIGHT (f);
3133 x_char_width (f)
3134 register struct frame *f;
3136 return FRAME_COLUMN_WIDTH (f);
3140 x_char_height (f)
3141 register struct frame *f;
3143 return FRAME_LINE_HEIGHT (f);
3147 x_screen_planes (f)
3148 register struct frame *f;
3150 return FRAME_MAC_DISPLAY_INFO (f)->n_planes;
3153 /* Return the display structure for the display named NAME.
3154 Open a new connection if necessary. */
3156 struct mac_display_info *
3157 x_display_info_for_name (name)
3158 Lisp_Object name;
3160 Lisp_Object names;
3161 struct mac_display_info *dpyinfo;
3163 CHECK_STRING (name);
3165 if (! EQ (Vwindow_system, intern ("mac")))
3166 error ("Not using Mac native windows");
3168 for (dpyinfo = &one_mac_display_info, names = x_display_name_list;
3169 dpyinfo;
3170 dpyinfo = dpyinfo->next, names = XCDR (names))
3172 Lisp_Object tem;
3173 tem = Fstring_equal (XCAR (XCAR (names)), name);
3174 if (!NILP (tem))
3175 return dpyinfo;
3178 /* Use this general default value to start with. */
3179 Vx_resource_name = Vinvocation_name;
3181 validate_x_resource_name ();
3183 dpyinfo = mac_term_init (name, (unsigned char *) 0,
3184 (char *) SDATA (Vx_resource_name));
3186 if (dpyinfo == 0)
3187 error ("Cannot connect to server %s", SDATA (name));
3189 mac_in_use = 1;
3190 XSETFASTINT (Vwindow_system_version, 3);
3192 return dpyinfo;
3195 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
3196 1, 3, 0,
3197 doc: /* Open a connection to a server.
3198 DISPLAY is the name of the display to connect to.
3199 Optional second arg XRM-STRING is a string of resources in xrdb format.
3200 If the optional third arg MUST-SUCCEED is non-nil,
3201 terminate Emacs if we can't open the connection. */)
3202 (display, xrm_string, must_succeed)
3203 Lisp_Object display, xrm_string, must_succeed;
3205 unsigned char *xrm_option;
3206 struct mac_display_info *dpyinfo;
3208 CHECK_STRING (display);
3209 if (! NILP (xrm_string))
3210 CHECK_STRING (xrm_string);
3212 if (! EQ (Vwindow_system, intern ("mac")))
3213 error ("Not using Mac native windows");
3215 if (! NILP (xrm_string))
3216 xrm_option = (unsigned char *) SDATA (xrm_string);
3217 else
3218 xrm_option = (unsigned char *) 0;
3220 validate_x_resource_name ();
3222 /* This is what opens the connection and sets x_current_display.
3223 This also initializes many symbols, such as those used for input. */
3224 dpyinfo = mac_term_init (display, xrm_option,
3225 (char *) SDATA (Vx_resource_name));
3227 if (dpyinfo == 0)
3229 if (!NILP (must_succeed))
3230 fatal ("Cannot connect to server %s.\n",
3231 SDATA (display));
3232 else
3233 error ("Cannot connect to server %s", SDATA (display));
3236 mac_in_use = 1;
3238 XSETFASTINT (Vwindow_system_version, 3);
3239 return Qnil;
3242 DEFUN ("x-close-connection", Fx_close_connection,
3243 Sx_close_connection, 1, 1, 0,
3244 doc: /* Close the connection to DISPLAY's server.
3245 For DISPLAY, specify either a frame or a display name (a string).
3246 If DISPLAY is nil, that stands for the selected frame's display. */)
3247 (display)
3248 Lisp_Object display;
3250 struct mac_display_info *dpyinfo = check_x_display_info (display);
3251 int i;
3253 if (dpyinfo->reference_count > 0)
3254 error ("Display still has frames on it");
3256 BLOCK_INPUT;
3257 /* Free the fonts in the font table. */
3258 for (i = 0; i < dpyinfo->n_fonts; i++)
3259 if (dpyinfo->font_table[i].name)
3261 mac_unload_font (dpyinfo, dpyinfo->font_table[i].font);
3264 x_destroy_all_bitmaps (dpyinfo);
3266 x_delete_display (dpyinfo);
3267 UNBLOCK_INPUT;
3269 return Qnil;
3272 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
3273 doc: /* Return the list of display names that Emacs has connections to. */)
3276 Lisp_Object tail, result;
3278 result = Qnil;
3279 for (tail = x_display_name_list; ! NILP (tail); tail = XCDR (tail))
3280 result = Fcons (XCAR (XCAR (tail)), result);
3282 return result;
3285 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
3286 doc: /* This is a noop on Mac OS systems. */)
3287 (on, display)
3288 Lisp_Object display, on;
3290 return Qnil;
3293 /* x_sync is a no-op on Mac. */
3295 void
3296 x_sync (f)
3297 FRAME_PTR f;
3302 /***********************************************************************
3303 Window properties
3304 ***********************************************************************/
3306 DEFUN ("x-change-window-property", Fx_change_window_property,
3307 Sx_change_window_property, 2, 6, 0,
3308 doc: /* Change window property PROP to VALUE on the X window of FRAME.
3309 VALUE may be a string or a list of conses, numbers and/or strings.
3310 If an element in the list is a string, it is converted to
3311 an Atom and the value of the Atom is used. If an element is a cons,
3312 it is converted to a 32 bit number where the car is the 16 top bits and the
3313 cdr is the lower 16 bits.
3314 FRAME nil or omitted means use the selected frame.
3315 If TYPE is given and non-nil, it is the name of the type of VALUE.
3316 If TYPE is not given or nil, the type is STRING.
3317 FORMAT gives the size in bits of each element if VALUE is a list.
3318 It must be one of 8, 16 or 32.
3319 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
3320 If OUTER_P is non-nil, the property is changed for the outer X window of
3321 FRAME. Default is to change on the edit X window.
3323 Value is VALUE. */)
3324 (prop, value, frame, type, format, outer_p)
3325 Lisp_Object prop, value, frame, type, format, outer_p;
3327 #if 0 /* MAC_TODO : port window properties to Mac */
3328 struct frame *f = check_x_frame (frame);
3329 Atom prop_atom;
3331 CHECK_STRING (prop);
3332 CHECK_STRING (value);
3334 BLOCK_INPUT;
3335 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3336 XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3337 prop_atom, XA_STRING, 8, PropModeReplace,
3338 SDATA (value), SCHARS (value));
3340 /* Make sure the property is set when we return. */
3341 XFlush (FRAME_W32_DISPLAY (f));
3342 UNBLOCK_INPUT;
3344 #endif /* MAC_TODO */
3346 return value;
3350 DEFUN ("x-delete-window-property", Fx_delete_window_property,
3351 Sx_delete_window_property, 1, 2, 0,
3352 doc: /* Remove window property PROP from X window of FRAME.
3353 FRAME nil or omitted means use the selected frame. Value is PROP. */)
3354 (prop, frame)
3355 Lisp_Object prop, frame;
3357 #if 0 /* MAC_TODO : port window properties to Mac */
3359 struct frame *f = check_x_frame (frame);
3360 Atom prop_atom;
3362 CHECK_STRING (prop);
3363 BLOCK_INPUT;
3364 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3365 XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
3367 /* Make sure the property is removed when we return. */
3368 XFlush (FRAME_W32_DISPLAY (f));
3369 UNBLOCK_INPUT;
3370 #endif /* MAC_TODO */
3372 return prop;
3376 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
3377 1, 2, 0,
3378 doc: /* Value is the value of window property PROP on FRAME.
3379 If FRAME is nil or omitted, use the selected frame. Value is nil
3380 if FRAME hasn't a property with name PROP or if PROP has no string
3381 value. */)
3382 (prop, frame)
3383 Lisp_Object prop, frame;
3385 #if 0 /* MAC_TODO : port window properties to Mac */
3387 struct frame *f = check_x_frame (frame);
3388 Atom prop_atom;
3389 int rc;
3390 Lisp_Object prop_value = Qnil;
3391 char *tmp_data = NULL;
3392 Atom actual_type;
3393 int actual_format;
3394 unsigned long actual_size, bytes_remaining;
3396 CHECK_STRING (prop);
3397 BLOCK_INPUT;
3398 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
3399 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3400 prop_atom, 0, 0, False, XA_STRING,
3401 &actual_type, &actual_format, &actual_size,
3402 &bytes_remaining, (unsigned char **) &tmp_data);
3403 if (rc == Success)
3405 int size = bytes_remaining;
3407 XFree (tmp_data);
3408 tmp_data = NULL;
3410 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
3411 prop_atom, 0, bytes_remaining,
3412 False, XA_STRING,
3413 &actual_type, &actual_format,
3414 &actual_size, &bytes_remaining,
3415 (unsigned char **) &tmp_data);
3416 if (rc == Success)
3417 prop_value = make_string (tmp_data, size);
3419 XFree (tmp_data);
3422 UNBLOCK_INPUT;
3424 return prop_value;
3426 #endif /* MAC_TODO */
3427 return Qnil;
3432 /***********************************************************************
3433 Busy cursor
3434 ***********************************************************************/
3436 /* If non-null, an asynchronous timer that, when it expires, displays
3437 an hourglass cursor on all frames. */
3439 static struct atimer *hourglass_atimer;
3441 /* Non-zero means an hourglass cursor is currently shown. */
3443 static int hourglass_shown_p;
3445 /* Number of seconds to wait before displaying an hourglass cursor. */
3447 static Lisp_Object Vhourglass_delay;
3449 /* Default number of seconds to wait before displaying an hourglass
3450 cursor. */
3452 #define DEFAULT_HOURGLASS_DELAY 1
3454 /* Function prototypes. */
3456 static void show_hourglass P_ ((struct atimer *));
3457 static void hide_hourglass P_ ((void));
3459 /* Return non-zero if houglass timer has been started or hourglass is shown. */
3462 hourglass_started ()
3464 return hourglass_shown_p || hourglass_atimer != NULL;
3468 /* Cancel a currently active hourglass timer, and start a new one. */
3470 void
3471 start_hourglass ()
3473 #ifdef MAC_OSX
3474 EMACS_TIME delay;
3475 int secs, usecs = 0;
3477 /* Don't bother for ttys. */
3478 if (NILP (Vwindow_system))
3479 return;
3481 cancel_hourglass ();
3483 if (INTEGERP (Vhourglass_delay)
3484 && XINT (Vhourglass_delay) > 0)
3485 secs = XFASTINT (Vhourglass_delay);
3486 else if (FLOATP (Vhourglass_delay)
3487 && XFLOAT_DATA (Vhourglass_delay) > 0)
3489 Lisp_Object tem;
3490 tem = Ftruncate (Vhourglass_delay, Qnil);
3491 secs = XFASTINT (tem);
3492 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
3494 else
3495 secs = DEFAULT_HOURGLASS_DELAY;
3497 EMACS_SET_SECS_USECS (delay, secs, usecs);
3498 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
3499 show_hourglass, NULL);
3500 #endif /* MAC_OSX */
3504 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
3505 shown. */
3507 void
3508 cancel_hourglass ()
3510 #ifdef MAC_OSX
3511 if (hourglass_atimer)
3513 cancel_atimer (hourglass_atimer);
3514 hourglass_atimer = NULL;
3517 if (hourglass_shown_p)
3518 hide_hourglass ();
3519 #endif /* MAC_OSX */
3523 /* Timer function of hourglass_atimer. TIMER is equal to
3524 hourglass_atimer.
3526 On Mac, busy status is shown by the progress indicator (chasing
3527 arrows) at the upper-right corner of each frame instead of the
3528 hourglass pointer. */
3530 static void
3531 show_hourglass (timer)
3532 struct atimer *timer;
3534 #if TARGET_API_MAC_CARBON
3535 /* The timer implementation will cancel this timer automatically
3536 after this function has run. Set hourglass_atimer to null
3537 so that we know the timer doesn't have to be canceled. */
3538 hourglass_atimer = NULL;
3540 if (!hourglass_shown_p)
3542 Lisp_Object rest, frame;
3544 BLOCK_INPUT;
3546 FOR_EACH_FRAME (rest, frame)
3548 struct frame *f = XFRAME (frame);
3550 if (FRAME_LIVE_P (f) && FRAME_MAC_P (f)
3551 && FRAME_MAC_WINDOW (f) != tip_window)
3552 mac_show_hourglass (f);
3555 hourglass_shown_p = 1;
3556 UNBLOCK_INPUT;
3558 #endif /* TARGET_API_MAC_CARBON */
3562 /* Hide the progress indicators on all frames, if it is currently
3563 shown. */
3565 static void
3566 hide_hourglass ()
3568 #if TARGET_API_MAC_CARBON
3569 if (hourglass_shown_p)
3571 Lisp_Object rest, frame;
3573 BLOCK_INPUT;
3574 FOR_EACH_FRAME (rest, frame)
3576 struct frame *f = XFRAME (frame);
3578 if (FRAME_MAC_P (f))
3579 mac_hide_hourglass (f);
3582 hourglass_shown_p = 0;
3583 UNBLOCK_INPUT;
3585 #endif /* TARGET_API_MAC_CARBON */
3590 /***********************************************************************
3591 Tool tips
3592 ***********************************************************************/
3594 static Lisp_Object x_create_tip_frame P_ ((struct mac_display_info *,
3595 Lisp_Object, Lisp_Object));
3596 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
3597 Lisp_Object, int, int, int *, int *));
3599 /* The frame of a currently visible tooltip. */
3601 Lisp_Object tip_frame;
3603 /* If non-nil, a timer started that hides the last tooltip when it
3604 fires. */
3606 Lisp_Object tip_timer;
3607 Window tip_window;
3609 /* If non-nil, a vector of 3 elements containing the last args
3610 with which x-show-tip was called. See there. */
3612 Lisp_Object last_show_tip_args;
3614 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
3616 Lisp_Object Vx_max_tooltip_size;
3619 static Lisp_Object
3620 unwind_create_tip_frame (frame)
3621 Lisp_Object frame;
3623 Lisp_Object deleted;
3625 deleted = unwind_create_frame (frame);
3626 if (EQ (deleted, Qt))
3628 tip_window = NULL;
3629 tip_frame = Qnil;
3632 return deleted;
3636 /* Create a frame for a tooltip on the display described by DPYINFO.
3637 PARMS is a list of frame parameters. TEXT is the string to
3638 display in the tip frame. Value is the frame.
3640 Note that functions called here, esp. x_default_parameter can
3641 signal errors, for instance when a specified color name is
3642 undefined. We have to make sure that we're in a consistent state
3643 when this happens. */
3645 static Lisp_Object
3646 x_create_tip_frame (dpyinfo, parms, text)
3647 struct mac_display_info *dpyinfo;
3648 Lisp_Object parms, text;
3650 struct frame *f;
3651 Lisp_Object frame, tem;
3652 Lisp_Object name;
3653 long window_prompting = 0;
3654 int width, height;
3655 int count = SPECPDL_INDEX ();
3656 struct gcpro gcpro1, gcpro2, gcpro3;
3657 struct kboard *kb;
3658 int face_change_count_before = face_change_count;
3659 Lisp_Object buffer;
3660 struct buffer *old_buffer;
3662 check_mac ();
3664 parms = Fcopy_alist (parms);
3666 #ifdef MULTI_KBOARD
3667 kb = dpyinfo->kboard;
3668 #else
3669 kb = &the_only_kboard;
3670 #endif
3672 /* Get the name of the frame to use for resource lookup. */
3673 name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
3674 if (!STRINGP (name)
3675 && !EQ (name, Qunbound)
3676 && !NILP (name))
3677 error ("Invalid frame name--not a string or nil");
3679 frame = Qnil;
3680 GCPRO3 (parms, name, frame);
3681 f = make_frame (1);
3682 XSETFRAME (frame, f);
3684 buffer = Fget_buffer_create (build_string (" *tip*"));
3685 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
3686 old_buffer = current_buffer;
3687 set_buffer_internal_1 (XBUFFER (buffer));
3688 current_buffer->truncate_lines = Qnil;
3689 specbind (Qinhibit_read_only, Qt);
3690 specbind (Qinhibit_modification_hooks, Qt);
3691 Ferase_buffer ();
3692 Finsert (1, &text);
3693 set_buffer_internal_1 (old_buffer);
3695 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
3696 record_unwind_protect (unwind_create_tip_frame, frame);
3698 /* By setting the output method, we're essentially saying that
3699 the frame is live, as per FRAME_LIVE_P. If we get a signal
3700 from this point on, x_destroy_window might screw up reference
3701 counts etc. */
3702 f->output_method = output_mac;
3703 f->output_data.mac =
3704 (struct mac_output *) xmalloc (sizeof (struct mac_output));
3705 bzero (f->output_data.mac, sizeof (struct mac_output));
3707 FRAME_FONTSET (f) = -1;
3708 f->icon_name = Qnil;
3709 /* FRAME_X_DISPLAY_INFO (f) = dpyinfo; */
3710 #if GLYPH_DEBUG
3711 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
3712 dpyinfo_refcount = dpyinfo->reference_count;
3713 #endif /* GLYPH_DEBUG */
3714 #ifdef MULTI_KBOARD
3715 FRAME_KBOARD (f) = kb;
3716 #endif
3717 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
3718 f->output_data.mac->explicit_parent = 0;
3720 /* Set the name; the functions to which we pass f expect the name to
3721 be set. */
3722 if (EQ (name, Qunbound) || NILP (name))
3724 f->name = build_string (dpyinfo->mac_id_name);
3725 f->explicit_name = 0;
3727 else
3729 f->name = name;
3730 f->explicit_name = 1;
3731 /* use the frame's title when getting resources for this frame. */
3732 specbind (Qx_resource_name, name);
3735 /* Extract the window parameters from the supplied values that are
3736 needed to determine window geometry. */
3738 Lisp_Object font;
3740 font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
3742 BLOCK_INPUT;
3743 /* First, try whatever font the caller has specified. */
3744 if (STRINGP (font))
3746 tem = Fquery_fontset (font, Qnil);
3747 if (STRINGP (tem))
3748 font = x_new_fontset (f, SDATA (tem));
3749 else
3750 font = x_new_font (f, SDATA (font));
3753 /* Try out a font which we hope has bold and italic variations. */
3754 #if USE_ATSUI
3755 if (! STRINGP (font))
3756 font = x_new_font (f, "-*-monaco-medium-r-normal--12-*-*-*-*-*-iso10646-1");
3757 #endif
3758 if (! STRINGP (font))
3759 font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
3760 /* If those didn't work, look for something which will at least work. */
3761 if (! STRINGP (font))
3762 font = x_new_fontset (f, "fontset-standard");
3763 if (! STRINGP (font))
3764 font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
3765 if (! STRINGP (font))
3766 font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
3767 UNBLOCK_INPUT;
3768 if (! STRINGP (font))
3769 error ("Cannot find any usable font");
3771 x_default_parameter (f, parms, Qfont, font,
3772 "font", "Font", RES_TYPE_STRING);
3775 x_default_parameter (f, parms, Qborder_width, make_number (2),
3776 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3778 /* This defaults to 2 in order to match xterm. We recognize either
3779 internalBorderWidth or internalBorder (which is what xterm calls
3780 it). */
3781 if (NILP (Fassq (Qinternal_border_width, parms)))
3783 Lisp_Object value;
3785 value = mac_get_arg (parms, Qinternal_border_width,
3786 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3787 if (! EQ (value, Qunbound))
3788 parms = Fcons (Fcons (Qinternal_border_width, value),
3789 parms);
3792 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
3793 "internalBorderWidth", "internalBorderWidth",
3794 RES_TYPE_NUMBER);
3796 /* Also do the stuff which must be set before the window exists. */
3797 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3798 "foreground", "Foreground", RES_TYPE_STRING);
3799 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3800 "background", "Background", RES_TYPE_STRING);
3801 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3802 "pointerColor", "Foreground", RES_TYPE_STRING);
3803 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3804 "cursorColor", "Foreground", RES_TYPE_STRING);
3805 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3806 "borderColor", "BorderColor", RES_TYPE_STRING);
3808 /* Init faces before x_default_parameter is called for scroll-bar
3809 parameters because that function calls x_set_scroll_bar_width,
3810 which calls change_frame_size, which calls Fset_window_buffer,
3811 which runs hooks, which call Fvertical_motion. At the end, we
3812 end up in init_iterator with a null face cache, which should not
3813 happen. */
3814 init_frame_faces (f);
3816 f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
3818 window_prompting = x_figure_window_size (f, parms, 0);
3820 BLOCK_INPUT;
3822 mac_create_frame_window (f, 1);
3824 if (FRAME_MAC_WINDOW (f))
3826 mac_set_frame_window_background (f, FRAME_BACKGROUND_PIXEL (f));
3827 tip_window = FRAME_MAC_WINDOW (f);
3830 UNBLOCK_INPUT;
3832 x_make_gc (f);
3834 x_default_parameter (f, parms, Qauto_raise, Qnil,
3835 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3836 x_default_parameter (f, parms, Qauto_lower, Qnil,
3837 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3838 x_default_parameter (f, parms, Qcursor_type, Qbox,
3839 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3841 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3842 Change will not be effected unless different from the current
3843 FRAME_LINES (f). */
3844 width = FRAME_COLS (f);
3845 height = FRAME_LINES (f);
3846 SET_FRAME_COLS (f, 0);
3847 FRAME_LINES (f) = 0;
3848 change_frame_size (f, height, width, 1, 0, 0);
3850 /* Add `tooltip' frame parameter's default value. */
3851 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
3852 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
3853 Qnil));
3855 /* Set up faces after all frame parameters are known. This call
3856 also merges in face attributes specified for new frames.
3858 Frame parameters may be changed if .Xdefaults contains
3859 specifications for the default font. For example, if there is an
3860 `Emacs.default.attributeBackground: pink', the `background-color'
3861 attribute of the frame get's set, which let's the internal border
3862 of the tooltip frame appear in pink. Prevent this. */
3864 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
3866 /* Set tip_frame here, so that */
3867 tip_frame = frame;
3868 call1 (Qface_set_after_frame_default, frame);
3870 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
3871 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
3872 Qnil));
3875 f->no_split = 1;
3877 UNGCPRO;
3879 /* It is now ok to make the frame official even if we get an error
3880 below. And the frame needs to be on Vframe_list or making it
3881 visible won't work. */
3882 Vframe_list = Fcons (frame, Vframe_list);
3884 /* Now that the frame is official, it counts as a reference to
3885 its display. */
3886 FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
3888 /* Setting attributes of faces of the tooltip frame from resources
3889 and similar will increment face_change_count, which leads to the
3890 clearing of all current matrices. Since this isn't necessary
3891 here, avoid it by resetting face_change_count to the value it
3892 had before we created the tip frame. */
3893 face_change_count = face_change_count_before;
3895 /* Discard the unwind_protect. */
3896 return unbind_to (count, frame);
3900 /* Compute where to display tip frame F. PARMS is the list of frame
3901 parameters for F. DX and DY are specified offsets from the current
3902 location of the mouse. WIDTH and HEIGHT are the width and height
3903 of the tooltip. Return coordinates relative to the root window of
3904 the display in *ROOT_X, and *ROOT_Y. */
3906 static void
3907 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
3908 struct frame *f;
3909 Lisp_Object parms, dx, dy;
3910 int width, height;
3911 int *root_x, *root_y;
3913 Lisp_Object left, top;
3915 /* User-specified position? */
3916 left = Fcdr (Fassq (Qleft, parms));
3917 top = Fcdr (Fassq (Qtop, parms));
3919 /* Move the tooltip window where the mouse pointer is. Resize and
3920 show it. */
3921 if (!INTEGERP (left) || !INTEGERP (top))
3923 Point mouse_pos;
3925 BLOCK_INPUT;
3926 #if TARGET_API_MAC_CARBON
3927 mac_get_global_mouse (&mouse_pos);
3928 #else
3929 GetMouse (&mouse_pos);
3930 LocalToGlobal (&mouse_pos);
3931 #endif
3932 *root_x = mouse_pos.h;
3933 *root_y = mouse_pos.v;
3934 UNBLOCK_INPUT;
3937 if (INTEGERP (top))
3938 *root_y = XINT (top);
3939 else if (*root_y + XINT (dy) <= 0)
3940 *root_y = 0; /* Can happen for negative dy */
3941 else if (*root_y + XINT (dy) + height <= FRAME_MAC_DISPLAY_INFO (f)->height)
3942 /* It fits below the pointer */
3943 *root_y += XINT (dy);
3944 else if (height + XINT (dy) <= *root_y)
3945 /* It fits above the pointer. */
3946 *root_y -= height + XINT (dy);
3947 else
3948 /* Put it on the top. */
3949 *root_y = 0;
3951 if (INTEGERP (left))
3952 *root_x = XINT (left);
3953 else if (*root_x + XINT (dx) <= 0)
3954 *root_x = 0; /* Can happen for negative dx */
3955 else if (*root_x + XINT (dx) + width <= FRAME_MAC_DISPLAY_INFO (f)->width)
3956 /* It fits to the right of the pointer. */
3957 *root_x += XINT (dx);
3958 else if (width + XINT (dx) <= *root_x)
3959 /* It fits to the left of the pointer. */
3960 *root_x -= width + XINT (dx);
3961 else
3962 /* Put it left-justified on the screen -- it ought to fit that way. */
3963 *root_x = 0;
3967 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
3968 doc: /* Show STRING in a "tooltip" window on frame FRAME.
3969 A tooltip window is a small window displaying a string.
3971 This is an internal function; Lisp code should call `tooltip-show'.
3973 FRAME nil or omitted means use the selected frame.
3975 PARMS is an optional list of frame parameters which can be used to
3976 change the tooltip's appearance.
3978 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
3979 means use the default timeout of 5 seconds.
3981 If the list of frame parameters PARMS contains a `left' parameter,
3982 the tooltip is displayed at that x-position. Otherwise it is
3983 displayed at the mouse position, with offset DX added (default is 5 if
3984 DX isn't specified). Likewise for the y-position; if a `top' frame
3985 parameter is specified, it determines the y-position of the tooltip
3986 window, otherwise it is displayed at the mouse position, with offset
3987 DY added (default is -10).
3989 A tooltip's maximum size is specified by `x-max-tooltip-size'.
3990 Text larger than the specified size is clipped. */)
3991 (string, frame, parms, timeout, dx, dy)
3992 Lisp_Object string, frame, parms, timeout, dx, dy;
3994 struct frame *f;
3995 struct window *w;
3996 int root_x, root_y;
3997 struct buffer *old_buffer;
3998 struct text_pos pos;
3999 int i, width, height;
4000 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4001 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4002 int count = SPECPDL_INDEX ();
4004 specbind (Qinhibit_redisplay, Qt);
4006 GCPRO4 (string, parms, frame, timeout);
4008 CHECK_STRING (string);
4009 f = check_x_frame (frame);
4010 if (NILP (timeout))
4011 timeout = make_number (5);
4012 else
4013 CHECK_NATNUM (timeout);
4015 if (NILP (dx))
4016 dx = make_number (5);
4017 else
4018 CHECK_NUMBER (dx);
4020 if (NILP (dy))
4021 dy = make_number (-10);
4022 else
4023 CHECK_NUMBER (dy);
4025 if (NILP (last_show_tip_args))
4026 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
4028 if (!NILP (tip_frame))
4030 Lisp_Object last_string = AREF (last_show_tip_args, 0);
4031 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
4032 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
4034 if (EQ (frame, last_frame)
4035 && !NILP (Fequal (last_string, string))
4036 && !NILP (Fequal (last_parms, parms)))
4038 struct frame *f = XFRAME (tip_frame);
4040 /* Only DX and DY have changed. */
4041 if (!NILP (tip_timer))
4043 Lisp_Object timer = tip_timer;
4044 tip_timer = Qnil;
4045 call1 (Qcancel_timer, timer);
4048 BLOCK_INPUT;
4049 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
4050 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
4051 mac_move_window (FRAME_MAC_WINDOW (f), root_x, root_y, false);
4052 UNBLOCK_INPUT;
4053 goto start_timer;
4057 /* Hide a previous tip, if any. */
4058 Fx_hide_tip ();
4060 ASET (last_show_tip_args, 0, string);
4061 ASET (last_show_tip_args, 1, frame);
4062 ASET (last_show_tip_args, 2, parms);
4064 /* Add default values to frame parameters. */
4065 if (NILP (Fassq (Qname, parms)))
4066 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
4067 if (NILP (Fassq (Qinternal_border_width, parms)))
4068 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
4069 if (NILP (Fassq (Qborder_width, parms)))
4070 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
4071 if (NILP (Fassq (Qborder_color, parms)))
4072 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
4073 if (NILP (Fassq (Qbackground_color, parms)))
4074 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
4075 parms);
4077 /* Create a frame for the tooltip, and record it in the global
4078 variable tip_frame. */
4079 frame = x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f), parms, string);
4080 f = XFRAME (frame);
4082 /* Set up the frame's root window. */
4083 w = XWINDOW (FRAME_ROOT_WINDOW (f));
4084 w->left_col = w->top_line = make_number (0);
4086 if (CONSP (Vx_max_tooltip_size)
4087 && INTEGERP (XCAR (Vx_max_tooltip_size))
4088 && XINT (XCAR (Vx_max_tooltip_size)) > 0
4089 && INTEGERP (XCDR (Vx_max_tooltip_size))
4090 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
4092 w->total_cols = XCAR (Vx_max_tooltip_size);
4093 w->total_lines = XCDR (Vx_max_tooltip_size);
4095 else
4097 w->total_cols = make_number (80);
4098 w->total_lines = make_number (40);
4101 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
4102 adjust_glyphs (f);
4103 w->pseudo_window_p = 1;
4105 /* Display the tooltip text in a temporary buffer. */
4106 old_buffer = current_buffer;
4107 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
4108 current_buffer->truncate_lines = Qnil;
4109 clear_glyph_matrix (w->desired_matrix);
4110 clear_glyph_matrix (w->current_matrix);
4111 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
4112 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
4114 /* Compute width and height of the tooltip. */
4115 width = height = 0;
4116 for (i = 0; i < w->desired_matrix->nrows; ++i)
4118 struct glyph_row *row = &w->desired_matrix->rows[i];
4119 struct glyph *last;
4120 int row_width;
4122 /* Stop at the first empty row at the end. */
4123 if (!row->enabled_p || !row->displays_text_p)
4124 break;
4126 /* Let the row go over the full width of the frame. */
4127 row->full_width_p = 1;
4129 /* There's a glyph at the end of rows that is used to place
4130 the cursor there. Don't include the width of this glyph. */
4131 if (row->used[TEXT_AREA])
4133 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
4134 row_width = row->pixel_width - last->pixel_width;
4136 else
4137 row_width = row->pixel_width;
4139 height += row->height;
4140 width = max (width, row_width);
4143 /* Add the frame's internal border to the width and height the X
4144 window should have. */
4145 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4146 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4148 /* Move the tooltip window where the mouse pointer is. Resize and
4149 show it. */
4150 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
4152 BLOCK_INPUT;
4153 mac_move_window (FRAME_MAC_WINDOW (f), root_x, root_y, false);
4154 mac_size_window (FRAME_MAC_WINDOW (f), width, height, true);
4155 mac_show_window (FRAME_MAC_WINDOW (f));
4156 mac_bring_window_to_front (FRAME_MAC_WINDOW (f));
4157 UNBLOCK_INPUT;
4159 FRAME_PIXEL_WIDTH (f) = width;
4160 FRAME_PIXEL_HEIGHT (f) = height;
4162 /* Draw into the window. */
4163 w->must_be_updated_p = 1;
4164 update_single_window (w, 1);
4166 /* Restore original current buffer. */
4167 set_buffer_internal_1 (old_buffer);
4168 windows_or_buffers_changed = old_windows_or_buffers_changed;
4170 start_timer:
4171 /* Let the tip disappear after timeout seconds. */
4172 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
4173 intern ("x-hide-tip"));
4175 UNGCPRO;
4176 return unbind_to (count, Qnil);
4180 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
4181 doc: /* Hide the current tooltip window, if there is any.
4182 Value is t if tooltip was open, nil otherwise. */)
4185 int count;
4186 Lisp_Object deleted, frame, timer;
4187 struct gcpro gcpro1, gcpro2;
4189 /* Return quickly if nothing to do. */
4190 if (NILP (tip_timer) && NILP (tip_frame))
4191 return Qnil;
4193 frame = tip_frame;
4194 timer = tip_timer;
4195 GCPRO2 (frame, timer);
4196 tip_frame = tip_timer = deleted = Qnil;
4198 count = SPECPDL_INDEX ();
4199 specbind (Qinhibit_redisplay, Qt);
4200 specbind (Qinhibit_quit, Qt);
4202 if (!NILP (timer))
4203 call1 (Qcancel_timer, timer);
4205 if (FRAMEP (frame))
4207 Fdelete_frame (frame, Qnil);
4208 deleted = Qt;
4211 UNGCPRO;
4212 return unbind_to (count, deleted);
4217 /***********************************************************************
4218 File selection dialog
4219 ***********************************************************************/
4221 #if TARGET_API_MAC_CARBON
4222 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
4223 doc: /* Read file name, prompting with PROMPT in directory DIR.
4224 Use a file selection dialog.
4225 Select DEFAULT-FILENAME in the dialog's file selection box, if
4226 specified. Ensure that file exists if MUSTMATCH is non-nil.
4227 If ONLY-DIR-P is non-nil, the user can only select directories. */)
4228 (prompt, dir, default_filename, mustmatch, only_dir_p)
4229 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
4231 return mac_file_dialog (prompt, dir, default_filename, mustmatch, only_dir_p);
4233 #endif
4236 /***********************************************************************
4237 Fonts
4238 ***********************************************************************/
4240 DEFUN ("mac-clear-font-name-table", Fmac_clear_font_name_table,
4241 Smac_clear_font_name_table, 0, 0, 0,
4242 doc: /* Clear the font name table. */)
4245 check_mac ();
4246 mac_clear_font_name_table ();
4247 return Qnil;
4250 #if USE_MAC_FONT_PANEL
4251 DEFUN ("mac-set-font-panel-visible-p", Fmac_set_font_panel_visible_p,
4252 Smac_set_font_panel_visible_p, 1, 1, 0,
4253 doc: /* Make the font panel visible if and only if FLAG is non-nil.
4254 This is for internal use only. Use `mac-font-panel-mode' instead. */)
4255 (flag)
4256 Lisp_Object flag;
4258 OSStatus err = noErr;
4260 check_mac ();
4262 BLOCK_INPUT;
4263 if (NILP (flag) != !mac_font_panel_visible_p ())
4265 err = mac_show_hide_font_panel ();
4266 if (err == noErr && !NILP (flag))
4268 Lisp_Object focus_frame = x_get_focus_frame (SELECTED_FRAME ());
4269 struct frame *f = (NILP (focus_frame) ? SELECTED_FRAME ()
4270 : XFRAME (focus_frame));
4272 mac_set_font_info_for_selection (f, DEFAULT_FACE_ID, 0);
4275 UNBLOCK_INPUT;
4277 if (err != noErr)
4278 error ("Cannot change visibility of the font panel");
4279 return Qnil;
4281 #endif
4283 #if USE_ATSUI
4284 extern Lisp_Object mac_atsu_font_face_attributes P_ ((ATSUFontID));
4286 DEFUN ("mac-atsu-font-face-attributes", Fmac_atsu_font_face_attributes,
4287 Smac_atsu_font_face_attributes, 1, 1, 0,
4288 doc: /* Return plist of face attributes and values for ATSU font ID.
4289 ID is specified by either an integer or a float. */)
4290 (id)
4291 Lisp_Object id;
4293 ATSUFontID font_id;
4294 Lisp_Object result;
4296 check_mac ();
4297 CHECK_NUMBER_OR_FLOAT (id);
4298 font_id = INTEGERP (id) ? XINT (id) : XFLOAT_DATA (id);
4299 BLOCK_INPUT;
4300 result = mac_atsu_font_face_attributes (font_id);
4301 UNBLOCK_INPUT;
4302 return result;
4304 #endif
4307 /***********************************************************************
4308 Initialization
4309 ***********************************************************************/
4311 /* Keep this list in the same order as frame_parms in frame.c.
4312 Use 0 for unsupported frame parameters. */
4314 frame_parm_handler mac_frame_parm_handlers[] =
4316 x_set_autoraise,
4317 x_set_autolower,
4318 x_set_background_color,
4319 x_set_border_color,
4320 x_set_border_width,
4321 x_set_cursor_color,
4322 x_set_cursor_type,
4323 mac_set_font,
4324 x_set_foreground_color,
4325 x_set_icon_name,
4326 0, /* MAC_TODO: x_set_icon_type, */
4327 x_set_internal_border_width,
4328 x_set_menu_bar_lines,
4329 x_set_mouse_color,
4330 x_explicitly_set_name,
4331 x_set_scroll_bar_width,
4332 x_set_title,
4333 x_set_unsplittable,
4334 x_set_vertical_scroll_bars,
4335 x_set_visibility,
4336 x_set_tool_bar_lines,
4337 0, /* MAC_TODO: x_set_scroll_bar_foreground, */
4338 0, /* MAC_TODO: x_set_scroll_bar_background, */
4339 x_set_screen_gamma,
4340 x_set_line_spacing,
4341 x_set_fringe_width,
4342 x_set_fringe_width,
4343 0, /* x_set_wait_for_wm, */
4344 x_set_fullscreen,
4347 void
4348 syms_of_macfns ()
4350 #ifdef MAC_OSX
4351 /* This is zero if not using Mac native windows. */
4352 mac_in_use = 0;
4353 #else
4354 /* Certainly running on Mac native windows. */
4355 mac_in_use = 1;
4356 #endif
4358 /* The section below is built by the lisp expression at the top of the file,
4359 just above where these variables are declared. */
4360 /*&&& init symbols here &&&*/
4361 Qnone = intern ("none");
4362 staticpro (&Qnone);
4363 Qsuppress_icon = intern ("suppress-icon");
4364 staticpro (&Qsuppress_icon);
4365 Qundefined_color = intern ("undefined-color");
4366 staticpro (&Qundefined_color);
4367 Qcancel_timer = intern ("cancel-timer");
4368 staticpro (&Qcancel_timer);
4369 /* This is the end of symbol initialization. */
4371 /* Text property `display' should be nonsticky by default. */
4372 Vtext_property_default_nonsticky
4373 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
4376 Fput (Qundefined_color, Qerror_conditions,
4377 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
4378 Fput (Qundefined_color, Qerror_message,
4379 build_string ("Undefined color"));
4381 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
4382 doc: /* The shape of the pointer when over text.
4383 Changing the value does not affect existing frames
4384 unless you set the mouse color. */);
4385 Vx_pointer_shape = Qnil;
4387 #if 0 /* This doesn't really do anything. */
4388 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
4389 doc: /* The shape of the pointer when not over text.
4390 This variable takes effect when you create a new frame
4391 or when you set the mouse color. */);
4392 #endif
4393 Vx_nontext_pointer_shape = Qnil;
4395 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
4396 doc: /* The shape of the pointer when Emacs is busy.
4397 This variable takes effect when you create a new frame
4398 or when you set the mouse color. */);
4399 Vx_hourglass_pointer_shape = Qnil;
4401 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
4402 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
4403 display_hourglass_p = 1;
4405 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
4406 doc: /* *Seconds to wait before displaying an hourglass pointer.
4407 Value must be an integer or float. */);
4408 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
4410 #if 0 /* This doesn't really do anything. */
4411 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
4412 doc: /* The shape of the pointer when over the mode line.
4413 This variable takes effect when you create a new frame
4414 or when you set the mouse color. */);
4415 #endif
4416 Vx_mode_pointer_shape = Qnil;
4418 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
4419 &Vx_sensitive_text_pointer_shape,
4420 doc: /* The shape of the pointer when over mouse-sensitive text.
4421 This variable takes effect when you create a new frame
4422 or when you set the mouse color. */);
4423 Vx_sensitive_text_pointer_shape = Qnil;
4425 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
4426 &Vx_window_horizontal_drag_shape,
4427 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
4428 This variable takes effect when you create a new frame
4429 or when you set the mouse color. */);
4430 Vx_window_horizontal_drag_shape = Qnil;
4432 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
4433 doc: /* A string indicating the foreground color of the cursor box. */);
4434 Vx_cursor_fore_pixel = Qnil;
4436 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
4437 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
4438 Text larger than this is clipped. */);
4439 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
4441 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
4442 doc: /* Non-nil if no window manager is in use.
4443 Emacs doesn't try to figure this out; this is always nil
4444 unless you set it to something else. */);
4445 /* We don't have any way to find this out, so set it to nil
4446 and maybe the user would like to set it to t. */
4447 Vx_no_window_manager = Qnil;
4449 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
4450 &Vx_pixel_size_width_font_regexp,
4451 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
4453 Since Emacs gets width of a font matching with this regexp from
4454 PIXEL_SIZE field of the name, font finding mechanism gets faster for
4455 such a font. This is especially effective for such large fonts as
4456 Chinese, Japanese, and Korean. */);
4457 Vx_pixel_size_width_font_regexp = Qnil;
4459 #if TARGET_API_MAC_CARBON
4460 DEFVAR_LISP ("mac-carbon-version-string", &Vmac_carbon_version_string,
4461 doc: /* Version info for Carbon API. */);
4463 OSErr err;
4464 UInt32 response;
4465 char carbon_version[16] = "Unknown";
4467 err = Gestalt (gestaltCarbonVersion, &response);
4468 if (err == noErr)
4469 sprintf (carbon_version, "%u.%u.%u",
4470 (response >> 8) & 0xf, (response >> 4) & 0xf, response & 0xf);
4471 Vmac_carbon_version_string = build_string (carbon_version);
4473 #endif /* TARGET_API_MAC_CARBON */
4475 /* X window properties. */
4476 defsubr (&Sx_change_window_property);
4477 defsubr (&Sx_delete_window_property);
4478 defsubr (&Sx_window_property);
4480 defsubr (&Sxw_display_color_p);
4481 defsubr (&Sx_display_grayscale_p);
4482 defsubr (&Sxw_color_defined_p);
4483 defsubr (&Sxw_color_values);
4484 defsubr (&Sx_server_max_request_size);
4485 defsubr (&Sx_server_vendor);
4486 defsubr (&Sx_server_version);
4487 defsubr (&Sx_display_pixel_width);
4488 defsubr (&Sx_display_pixel_height);
4489 defsubr (&Sx_display_mm_width);
4490 defsubr (&Sx_display_mm_height);
4491 defsubr (&Sx_display_screens);
4492 defsubr (&Sx_display_planes);
4493 defsubr (&Sx_display_color_cells);
4494 defsubr (&Sx_display_visual_class);
4495 defsubr (&Sx_display_backing_store);
4496 defsubr (&Sx_display_save_under);
4497 defsubr (&Sx_create_frame);
4498 defsubr (&Sx_open_connection);
4499 defsubr (&Sx_close_connection);
4500 defsubr (&Sx_display_list);
4501 defsubr (&Sx_synchronize);
4502 defsubr (&Sx_focus_frame);
4504 /* Setting callback functions for fontset handler. */
4505 get_font_info_func = x_get_font_info;
4507 #if 0 /* This function pointer doesn't seem to be used anywhere.
4508 And the pointer assigned has the wrong type, anyway. */
4509 list_fonts_func = x_list_fonts;
4510 #endif
4512 load_font_func = x_load_font;
4513 find_ccl_program_func = x_find_ccl_program;
4514 query_font_func = x_query_font;
4515 set_frame_fontset_func = mac_set_font;
4516 check_window_system_func = check_mac;
4518 hourglass_atimer = NULL;
4519 hourglass_shown_p = 0;
4521 defsubr (&Sx_show_tip);
4522 defsubr (&Sx_hide_tip);
4523 tip_timer = Qnil;
4524 staticpro (&tip_timer);
4525 tip_frame = Qnil;
4526 staticpro (&tip_frame);
4528 last_show_tip_args = Qnil;
4529 staticpro (&last_show_tip_args);
4531 #if TARGET_API_MAC_CARBON
4532 defsubr (&Sx_file_dialog);
4533 #endif
4534 defsubr (&Smac_clear_font_name_table);
4535 #if USE_MAC_FONT_PANEL
4536 defsubr (&Smac_set_font_panel_visible_p);
4537 #endif
4538 #if USE_ATSUI
4539 defsubr (&Smac_atsu_font_face_attributes);
4540 #endif
4543 /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc
4544 (do not change this comment) */