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