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