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