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