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