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