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