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