Fix minor problems found by static checking.
[bpt/emacs.git] / src / nsfns.m
CommitLineData
edfda783 1/* Functions for the NeXT/Open/GNUstep and MacOSX window system.
e9bffc61 2
ab422c4d
PE
3Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2013 Free Software
4Foundation, Inc.
edfda783
AR
5
6This file is part of GNU Emacs.
7
32d235f8 8GNU Emacs is free software: you can redistribute it and/or modify
edfda783 9it under the terms of the GNU General Public License as published by
32d235f8
GM
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
edfda783
AR
12
13GNU Emacs is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
32d235f8 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
edfda783 20
32d235f8 21/*
edfda783
AR
22Originally by Carl Edman
23Updated by Christian Limpach (chris@nice.ch)
24OpenStep/Rhapsody port by Scott Bender (sbender@harmony-ds.com)
25MacOSX/Aqua port by Christophe de Dinechin (descubes@earthlink.net)
26GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
edfda783
AR
27*/
28
5a06864f
AR
29/* This should be the first include, as it may set up #defines affecting
30 interpretation of even the system includes. */
08a494a3 31#include <config.h>
5a06864f 32
edfda783 33#include <math.h>
fee5959d 34#include <c-strcase.h>
5a06864f 35
edfda783
AR
36#include "lisp.h"
37#include "blockinput.h"
38#include "nsterm.h"
39#include "window.h"
e5560ff7 40#include "character.h"
edfda783
AR
41#include "buffer.h"
42#include "keyboard.h"
43#include "termhooks.h"
44#include "fontset.h"
edfda783
AR
45#include "font.h"
46
4465bfb4
JD
47#ifdef NS_IMPL_COCOA
48#include <IOKit/graphics/IOGraphicsLib.h>
49#endif
50
edfda783
AR
51#if 0
52int fns_trace_num = 1;
53#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \
54 __FILE__, __LINE__, ++fns_trace_num)
55#else
56#define NSTRACE(x)
57#endif
58
59#ifdef HAVE_NS
60
61extern NSArray *ns_send_types, *ns_return_types, *ns_drag_types;
62
63extern Lisp_Object Qforeground_color;
64extern Lisp_Object Qbackground_color;
65extern Lisp_Object Qcursor_color;
66extern Lisp_Object Qinternal_border_width;
67extern Lisp_Object Qvisibility;
68extern Lisp_Object Qcursor_type;
69extern Lisp_Object Qicon_type;
70extern Lisp_Object Qicon_name;
71extern Lisp_Object Qicon_left;
72extern Lisp_Object Qicon_top;
73extern Lisp_Object Qleft;
74extern Lisp_Object Qright;
75extern Lisp_Object Qtop;
76extern Lisp_Object Qdisplay;
77extern Lisp_Object Qvertical_scroll_bars;
78extern Lisp_Object Qauto_raise;
79extern Lisp_Object Qauto_lower;
80extern Lisp_Object Qbox;
81extern Lisp_Object Qscroll_bar_width;
82extern Lisp_Object Qx_resource_name;
83extern Lisp_Object Qface_set_after_frame_default;
84extern Lisp_Object Qunderline, Qundefined;
85extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
86extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle;
87
5d1d3d04 88
edfda783
AR
89Lisp_Object Qbuffered;
90Lisp_Object Qfontsize;
91
92/* hack for OS X file panels */
93char panelOK = 0;
94
0fb0a4f3 95EmacsTooltip *ns_tooltip = nil;
edfda783
AR
96
97/* Need forward declaration here to preserve organizational integrity of file */
9e50ff0c 98Lisp_Object Fx_open_connection (Lisp_Object, Lisp_Object, Lisp_Object);
edfda783 99
08e3161a
JD
100/* Static variables to handle applescript execution. */
101static Lisp_Object as_script, *as_result;
102static int as_status;
edfda783 103
ef884f23 104#ifdef GLYPH_DEBUG
a97f8f3f
JD
105static ptrdiff_t image_cache_refcount;
106#endif
107
4465bfb4 108
edfda783
AR
109/* ==========================================================================
110
111 Internal utility functions
112
113 ========================================================================== */
114
91e8418b
YM
115/* Let the user specify a Nextstep display with a Lisp object.
116 OBJECT may be nil, a frame or a terminal object.
117 nil stands for the selected frame--or, if that is not a Nextstep frame,
d26fbe1a 118 the first Nextstep display on the list. */
91e8418b 119
edfda783 120static struct ns_display_info *
91e8418b 121check_ns_display_info (Lisp_Object object)
edfda783 122{
91e8418b
YM
123 struct ns_display_info *dpyinfo = NULL;
124
125 if (NILP (object))
edfda783 126 {
91e8418b
YM
127 struct frame *sf = XFRAME (selected_frame);
128
129 if (FRAME_NS_P (sf) && FRAME_LIVE_P (sf))
130 dpyinfo = FRAME_NS_DISPLAY_INFO (sf);
9e50ff0c 131 else if (x_display_list != 0)
91e8418b 132 dpyinfo = x_display_list;
edfda783 133 else
d26fbe1a 134 error ("Nextstep windows are not in use or not initialized");
edfda783 135 }
91e8418b 136 else if (TERMINALP (object))
edfda783 137 {
91e8418b 138 struct terminal *t = get_terminal (object, 1);
edfda783
AR
139
140 if (t->type != output_ns)
91e8418b 141 error ("Terminal %d is not a Nextstep display", t->id);
edfda783 142
91e8418b 143 dpyinfo = t->display_info.ns;
edfda783 144 }
91e8418b
YM
145 else if (STRINGP (object))
146 dpyinfo = ns_display_info_for_name (object);
edfda783
AR
147 else
148 {
91e8418b
YM
149 FRAME_PTR f = decode_window_system_frame (object);
150 dpyinfo = FRAME_NS_DISPLAY_INFO (f);
edfda783 151 }
91e8418b
YM
152
153 return dpyinfo;
edfda783
AR
154}
155
156
157static id
158ns_get_window (Lisp_Object maybeFrame)
159{
160 id view =nil, window =nil;
161
162 if (!FRAMEP (maybeFrame) || !FRAME_NS_P (XFRAME (maybeFrame)))
163 maybeFrame = selected_frame;/*wrong_type_argument (Qframep, maybeFrame); */
164
165 if (!NILP (maybeFrame))
166 view = FRAME_NS_VIEW (XFRAME (maybeFrame));
167 if (view) window =[view window];
168
169 return window;
170}
171
172
edfda783
AR
173/* Return the X display structure for the display named NAME.
174 Open a new connection if necessary. */
175struct ns_display_info *
3d608a86 176ns_display_info_for_name (Lisp_Object name)
edfda783
AR
177{
178 Lisp_Object names;
179 struct ns_display_info *dpyinfo;
180
181 CHECK_STRING (name);
182
9e50ff0c 183 for (dpyinfo = x_display_list, names = ns_display_name_list;
edfda783
AR
184 dpyinfo;
185 dpyinfo = dpyinfo->next, names = XCDR (names))
186 {
187 Lisp_Object tem;
188 tem = Fstring_equal (XCAR (XCAR (names)), name);
189 if (!NILP (tem))
190 return dpyinfo;
191 }
192
193 error ("Emacs for OpenStep does not yet support multi-display.");
194
9e50ff0c
DN
195 Fx_open_connection (name, Qnil, Qnil);
196 dpyinfo = x_display_list;
edfda783
AR
197
198 if (dpyinfo == 0)
facfbbbd 199 error ("OpenStep on %s not responding.\n", SDATA (name));
edfda783
AR
200
201 return dpyinfo;
202}
203
8f2906f5
JD
204static NSString *
205ns_filename_from_panel (NSSavePanel *panel)
206{
207#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
208 NSURL *url = [panel URL];
209 NSString *str = [url path];
210 return str;
211#else
212 return [panel filename];
213#endif
214}
215
216static NSString *
217ns_directory_from_panel (NSSavePanel *panel)
218{
219#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
220 NSURL *url = [panel directoryURL];
221 NSString *str = [url path];
222 return str;
223#else
224 return [panel directory];
225#endif
226}
edfda783
AR
227
228static Lisp_Object
229interpret_services_menu (NSMenu *menu, Lisp_Object prefix, Lisp_Object old)
230/* --------------------------------------------------------------------------
231 Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
232 -------------------------------------------------------------------------- */
233{
234 int i, count;
15034960 235 NSMenuItem *item;
edfda783
AR
236 const char *name;
237 Lisp_Object nameStr;
238 unsigned short key;
239 NSString *keys;
240 Lisp_Object res;
241
242 count = [menu numberOfItems];
243 for (i = 0; i<count; i++)
244 {
245 item = [menu itemAtIndex: i];
246 name = [[item title] UTF8String];
247 if (!name) continue;
248
249 nameStr = build_string (name);
250
251 if ([item hasSubmenu])
252 {
253 old = interpret_services_menu ([item submenu],
254 Fcons (nameStr, prefix), old);
255 }
256 else
257 {
258 keys = [item keyEquivalent];
259 if (keys && [keys length] )
260 {
261 key = [keys characterAtIndex: 0];
262 res = make_number (key|super_modifier);
263 }
264 else
265 {
266 res = Qundefined;
267 }
268 old = Fcons (Fcons (res,
269 Freverse (Fcons (nameStr,
270 prefix))),
271 old);
272 }
273 }
274 return old;
275}
276
277
278
279/* ==========================================================================
280
281 Frame parameter setters
282
283 ========================================================================== */
284
285
286static void
89e2438a 287x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
edfda783
AR
288{
289 NSColor *col;
c0342369 290 EmacsCGFloat r, g, b, alpha;
edfda783
AR
291
292 if (ns_lisp_to_color (arg, &col))
293 {
294 store_frame_param (f, Qforeground_color, oldval);
295 error ("Unknown color");
296 }
297
298 [col retain];
299 [f->output_data.ns->foreground_color release];
300 f->output_data.ns->foreground_color = col;
301
d8c2fa78
AA
302 [col getRed: &r green: &g blue: &b alpha: &alpha];
303 FRAME_FOREGROUND_PIXEL (f) =
304 ARGB_TO_ULONG ((int)(alpha*0xff), (int)(r*0xff), (int)(g*0xff), (int)(b*0xff));
305
edfda783
AR
306 if (FRAME_NS_VIEW (f))
307 {
308 update_face_from_frame_parameter (f, Qforeground_color, arg);
309 /*recompute_basic_faces (f); */
310 if (FRAME_VISIBLE_P (f))
311 redraw_frame (f);
312 }
313}
314
315
316static void
89e2438a 317x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
edfda783
AR
318{
319 struct face *face;
320 NSColor *col;
321 NSView *view = FRAME_NS_VIEW (f);
c0342369 322 EmacsCGFloat r, g, b, alpha;
edfda783
AR
323
324 if (ns_lisp_to_color (arg, &col))
325 {
326 store_frame_param (f, Qbackground_color, oldval);
327 error ("Unknown color");
328 }
329
330 /* clear the frame; in some instances the NS-internal GC appears not to
331 update, or it does update and cannot clear old text properly */
332 if (FRAME_VISIBLE_P (f))
333 ns_clear_frame (f);
334
335 [col retain];
336 [f->output_data.ns->background_color release];
337 f->output_data.ns->background_color = col;
d8c2fa78
AA
338
339 [col getRed: &r green: &g blue: &b alpha: &alpha];
340 FRAME_BACKGROUND_PIXEL (f) =
341 ARGB_TO_ULONG ((int)(alpha*0xff), (int)(r*0xff), (int)(g*0xff), (int)(b*0xff));
342
edfda783
AR
343 if (view != nil)
344 {
345 [[view window] setBackgroundColor: col];
edfda783 346
c0342369 347 if (alpha != (EmacsCGFloat) 1.0)
edfda783
AR
348 [[view window] setOpaque: NO];
349 else
350 [[view window] setOpaque: YES];
351
352 face = FRAME_DEFAULT_FACE (f);
353 if (face)
354 {
45d325c4 355 col = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f);
204ee57f
JD
356 face->background = ns_index_color
357 ([col colorWithAlphaComponent: alpha], f);
edfda783
AR
358
359 update_face_from_frame_parameter (f, Qbackground_color, arg);
360 }
361
362 if (FRAME_VISIBLE_P (f))
363 redraw_frame (f);
364 }
365}
366
367
368static void
89e2438a 369x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
edfda783
AR
370{
371 NSColor *col;
372
373 if (ns_lisp_to_color (arg, &col))
374 {
375 store_frame_param (f, Qcursor_color, oldval);
376 error ("Unknown color");
377 }
378
c8c057de
AR
379 [FRAME_CURSOR_COLOR (f) release];
380 FRAME_CURSOR_COLOR (f) = [col retain];
edfda783
AR
381
382 if (FRAME_VISIBLE_P (f))
383 {
384 x_update_cursor (f, 0);
385 x_update_cursor (f, 1);
386 }
387 update_face_from_frame_parameter (f, Qcursor_color, arg);
388}
389
c8c057de 390
edfda783 391static void
89e2438a 392x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
edfda783
AR
393{
394 NSView *view = FRAME_NS_VIEW (f);
89e2438a 395 NSTRACE (x_set_icon_name);
edfda783 396
edfda783
AR
397 /* see if it's changed */
398 if (STRINGP (arg))
399 {
400 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
401 return;
402 }
403 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
404 return;
405
f00af5b1 406 fset_icon_name (f, arg);
edfda783
AR
407
408 if (NILP (arg))
409 {
e69b0960
DA
410 if (!NILP (f->title))
411 arg = f->title;
edfda783
AR
412 else
413 /* explicit name and no icon-name -> explicit_name */
414 if (f->explicit_name)
e69b0960 415 arg = f->name;
edfda783
AR
416 else
417 {
418 /* no explicit name and no icon-name ->
419 name has to be rebuild from icon_title_format */
420 windows_or_buffers_changed++;
421 return;
422 }
423 }
424
425 /* Don't change the name if it's already NAME. */
426 if ([[view window] miniwindowTitle] &&
427 ([[[view window] miniwindowTitle]
428 isEqualToString: [NSString stringWithUTF8String:
0dc8cf50 429 SSDATA (arg)]]))
edfda783
AR
430 return;
431
432 [[view window] setMiniwindowTitle:
0dc8cf50 433 [NSString stringWithUTF8String: SSDATA (arg)]];
edfda783
AR
434}
435
edfda783 436static void
5bbb4727 437ns_set_name_internal (FRAME_PTR f, Lisp_Object name)
edfda783 438{
5bbb4727
JD
439 struct gcpro gcpro1;
440 Lisp_Object encoded_name, encoded_icon_name;
441 NSString *str;
edfda783 442 NSView *view = FRAME_NS_VIEW (f);
edfda783 443
5bbb4727
JD
444 GCPRO1 (name);
445 encoded_name = ENCODE_UTF_8 (name);
446 UNGCPRO;
edfda783 447
0dc8cf50 448 str = [NSString stringWithUTF8String: SSDATA (encoded_name)];
edfda783 449
5bbb4727
JD
450 /* Don't change the name if it's already NAME. */
451 if (! [[[view window] title] isEqualToString: str])
452 [[view window] setTitle: str];
edfda783 453
e69b0960 454 if (!STRINGP (f->icon_name))
5bbb4727 455 encoded_icon_name = encoded_name;
edfda783 456 else
e69b0960 457 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
5bbb4727 458
0dc8cf50 459 str = [NSString stringWithUTF8String: SSDATA (encoded_icon_name)];
edfda783 460
edfda783 461 if ([[view window] miniwindowTitle] &&
5bbb4727
JD
462 ! [[[view window] miniwindowTitle] isEqualToString: str])
463 [[view window] setMiniwindowTitle: str];
edfda783 464
edfda783
AR
465}
466
edfda783
AR
467static void
468ns_set_name (struct frame *f, Lisp_Object name, int explicit)
469{
edfda783
AR
470 NSTRACE (ns_set_name);
471
edfda783
AR
472 /* Make sure that requests from lisp code override requests from
473 Emacs redisplay code. */
474 if (explicit)
475 {
476 /* If we're switching from explicit to implicit, we had better
477 update the mode lines and thereby update the title. */
478 if (f->explicit_name && NILP (name))
479 update_mode_lines = 1;
480
481 f->explicit_name = ! NILP (name);
482 }
483 else if (f->explicit_name)
484 return;
485
486 if (NILP (name))
56d513e6 487 name = build_string([ns_app_name UTF8String]);
5bbb4727
JD
488 else
489 CHECK_STRING (name);
490
491 /* Don't change the name if it's already NAME. */
e69b0960 492 if (! NILP (Fstring_equal (name, f->name)))
5bbb4727 493 return;
edfda783 494
f00af5b1 495 fset_name (f, name);
edfda783
AR
496
497 /* title overrides explicit name */
e69b0960
DA
498 if (! NILP (f->title))
499 name = f->title;
edfda783 500
5bbb4727 501 ns_set_name_internal (f, name);
edfda783
AR
502}
503
504
505/* This function should be called when the user's lisp code has
506 specified a name for the frame; the name will override any set by the
507 redisplay code. */
508static void
89e2438a 509x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
edfda783 510{
89e2438a 511 NSTRACE (x_explicitly_set_name);
edfda783
AR
512 ns_set_name (f, arg, 1);
513}
514
515
516/* This function should be called by Emacs redisplay code to set the
517 name; names set this way will never override names set by the user's
518 lisp code. */
519void
520x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
521{
522 NSTRACE (x_implicitly_set_name);
5bbb4727
JD
523
524 /* Deal with NS specific format t. */
525 if (FRAME_NS_P (f) && ((FRAME_ICONIFIED_P (f) && EQ (Vicon_title_format, Qt))
526 || EQ (Vframe_title_format, Qt)))
9ae6e189 527 ns_set_name_as_filename (f);
edfda783
AR
528 else
529 ns_set_name (f, arg, 0);
530}
531
532
533/* Change the title of frame F to NAME.
5bbb4727 534 If NAME is nil, use the frame name as the title. */
edfda783 535
edfda783 536static void
89e2438a 537x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
edfda783 538{
89e2438a 539 NSTRACE (x_set_title);
edfda783 540 /* Don't change the title if it's already NAME. */
e69b0960 541 if (EQ (name, f->title))
edfda783
AR
542 return;
543
544 update_mode_lines = 1;
545
f00af5b1 546 fset_title (f, name);
5bbb4727
JD
547
548 if (NILP (name))
e69b0960 549 name = f->name;
5bbb4727
JD
550 else
551 CHECK_STRING (name);
552
553 ns_set_name_internal (f, name);
edfda783
AR
554}
555
556
557void
558ns_set_name_as_filename (struct frame *f)
559{
fec8f0fe 560 NSView *view;
aeb7e951 561 Lisp_Object name, filename;
e74aeda8 562 Lisp_Object buf = XWINDOW (f->selected_window)->contents;
edfda783
AR
563 const char *title;
564 NSAutoreleasePool *pool;
5bbb4727 565 struct gcpro gcpro1;
aeb7e951
JD
566 Lisp_Object encoded_name, encoded_filename;
567 NSString *str;
edfda783
AR
568 NSTRACE (ns_set_name_as_filename);
569
3bc0a2f7 570 if (f->explicit_name || ! NILP (f->title))
edfda783
AR
571 return;
572
4d7e6e51 573 block_input ();
edfda783 574 pool = [[NSAutoreleasePool alloc] init];
124c9ff0
JD
575 filename = BVAR (XBUFFER (buf), filename);
576 name = BVAR (XBUFFER (buf), name);
edfda783
AR
577
578 if (NILP (name))
aeb7e951
JD
579 {
580 if (! NILP (filename))
581 name = Ffile_name_nondirectory (filename);
582 else
583 name = build_string ([ns_app_name UTF8String]);
584 }
edfda783 585
5bbb4727
JD
586 GCPRO1 (name);
587 encoded_name = ENCODE_UTF_8 (name);
588 UNGCPRO;
589
fec8f0fe
CY
590 view = FRAME_NS_VIEW (f);
591
edfda783
AR
592 title = FRAME_ICONIFIED_P (f) ? [[[view window] miniwindowTitle] UTF8String]
593 : [[[view window] title] UTF8String];
594
0dc8cf50 595 if (title && (! strcmp (title, SSDATA (encoded_name))))
edfda783
AR
596 {
597 [pool release];
4d7e6e51 598 unblock_input ();
edfda783
AR
599 return;
600 }
601
0dc8cf50 602 str = [NSString stringWithUTF8String: SSDATA (encoded_name)];
aeb7e951
JD
603 if (str == nil) str = @"Bad coding";
604
605 if (FRAME_ICONIFIED_P (f))
606 [[view window] setMiniwindowTitle: str];
5fdb398c 607 else
edfda783 608 {
aeb7e951
JD
609 NSString *fstr;
610
611 if (! NILP (filename))
edfda783 612 {
aeb7e951
JD
613 GCPRO1 (filename);
614 encoded_filename = ENCODE_UTF_8 (filename);
615 UNGCPRO;
616
0dc8cf50 617 fstr = [NSString stringWithUTF8String: SSDATA (encoded_filename)];
aeb7e951
JD
618 if (fstr == nil) fstr = @"";
619#ifdef NS_IMPL_COCOA
620 /* work around a bug observed on 10.3 and later where
621 setTitleWithRepresentedFilename does not clear out previous state
622 if given filename does not exist */
623 if (! [[NSFileManager defaultManager] fileExistsAtPath: fstr])
624 [[view window] setRepresentedFilename: @""];
625#endif
edfda783
AR
626 }
627 else
aeb7e951
JD
628 fstr = @"";
629
630 [[view window] setRepresentedFilename: fstr];
631 [[view window] setTitle: str];
f00af5b1 632 fset_name (f, name);
edfda783 633 }
aeb7e951 634
edfda783 635 [pool release];
4d7e6e51 636 unblock_input ();
edfda783
AR
637}
638
639
640void
6521c534 641ns_set_doc_edited (struct frame *f, Lisp_Object arg)
edfda783
AR
642{
643 NSView *view = FRAME_NS_VIEW (f);
644 NSAutoreleasePool *pool;
e69b0960 645 if (!MINI_WINDOW_P (XWINDOW (f->selected_window)))
9ae6e189 646 {
4d7e6e51 647 block_input ();
9ae6e189
CY
648 pool = [[NSAutoreleasePool alloc] init];
649 [[view window] setDocumentEdited: !NILP (arg)];
650 [pool release];
4d7e6e51 651 unblock_input ();
9ae6e189 652 }
edfda783
AR
653}
654
655
cc98b6a0
DN
656void
657x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
edfda783
AR
658{
659 int nlines;
edfda783
AR
660 if (FRAME_MINIBUF_ONLY_P (f))
661 return;
662
d311d28c 663 if (TYPE_RANGED_INTEGERP (int, value))
edfda783
AR
664 nlines = XINT (value);
665 else
666 nlines = 0;
667
668 FRAME_MENU_BAR_LINES (f) = 0;
669 if (nlines)
670 {
671 FRAME_EXTERNAL_MENU_BAR (f) = 1;
cc98b6a0
DN
672 /* does for all frames, whereas we just want for one frame
673 [NSMenu setMenuBarVisible: YES]; */
edfda783
AR
674 }
675 else
676 {
677 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
678 free_frame_menubar (f);
cc98b6a0 679 /* [NSMenu setMenuBarVisible: NO]; */
edfda783
AR
680 FRAME_EXTERNAL_MENU_BAR (f) = 0;
681 }
682}
683
684
3fe53a83 685/* toolbar support */
cc98b6a0
DN
686void
687x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
edfda783
AR
688{
689 int nlines;
edfda783
AR
690
691 if (FRAME_MINIBUF_ONLY_P (f))
692 return;
693
d311d28c 694 if (RANGED_INTEGERP (0, value, INT_MAX))
edfda783
AR
695 nlines = XFASTINT (value);
696 else
697 nlines = 0;
698
699 if (nlines)
700 {
701 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
702 update_frame_tool_bar (f);
703 }
704 else
705 {
706 if (FRAME_EXTERNAL_TOOL_BAR (f))
707 {
708 free_frame_tool_bar (f);
709 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
710 }
711 }
712
713 x_set_window_size (f, 0, f->text_cols, f->text_lines);
714}
715
716
c0342369 717static void
edfda783
AR
718ns_implicitly_set_icon_type (struct frame *f)
719{
720 Lisp_Object tem;
721 EmacsView *view = FRAME_NS_VIEW (f);
204ee57f 722 id image = nil;
edfda783
AR
723 Lisp_Object chain, elt;
724 NSAutoreleasePool *pool;
725 BOOL setMini = YES;
726
727 NSTRACE (ns_implicitly_set_icon_type);
728
4d7e6e51 729 block_input ();
edfda783
AR
730 pool = [[NSAutoreleasePool alloc] init];
731 if (f->output_data.ns->miniimage
e69b0960 732 && [[NSString stringWithUTF8String: SSDATA (f->name)]
edfda783
AR
733 isEqualToString: [(NSImage *)f->output_data.ns->miniimage name]])
734 {
735 [pool release];
4d7e6e51 736 unblock_input ();
edfda783
AR
737 return;
738 }
739
e69b0960 740 tem = assq_no_quit (Qicon_type, f->param_alist);
edfda783
AR
741 if (CONSP (tem) && ! NILP (XCDR (tem)))
742 {
743 [pool release];
4d7e6e51 744 unblock_input ();
edfda783
AR
745 return;
746 }
747
748 for (chain = Vns_icon_type_alist;
204ee57f 749 image == nil && CONSP (chain);
edfda783
AR
750 chain = XCDR (chain))
751 {
752 elt = XCAR (chain);
753 /* special case: 't' means go by file type */
e69b0960 754 if (SYMBOLP (elt) && EQ (elt, Qt) && SSDATA (f->name)[0] == '/')
edfda783 755 {
facfbbbd 756 NSString *str
e69b0960 757 = [NSString stringWithUTF8String: SSDATA (f->name)];
edfda783
AR
758 if ([[NSFileManager defaultManager] fileExistsAtPath: str])
759 image = [[[NSWorkspace sharedWorkspace] iconForFile: str] retain];
760 }
761 else if (CONSP (elt) &&
762 STRINGP (XCAR (elt)) &&
763 STRINGP (XCDR (elt)) &&
e69b0960 764 fast_string_match (XCAR (elt), f->name) >= 0)
edfda783
AR
765 {
766 image = [EmacsImage allocInitFromFile: XCDR (elt)];
767 if (image == nil)
768 image = [[NSImage imageNamed:
769 [NSString stringWithUTF8String:
0dc8cf50 770 SSDATA (XCDR (elt))]] retain];
edfda783
AR
771 }
772 }
773
774 if (image == nil)
775 {
776 image = [[[NSWorkspace sharedWorkspace] iconForFileType: @"text"] retain];
777 setMini = NO;
778 }
779
780 [f->output_data.ns->miniimage release];
781 f->output_data.ns->miniimage = image;
782 [view setMiniwindowImage: setMini];
783 [pool release];
4d7e6e51 784 unblock_input ();
edfda783
AR
785}
786
787
788static void
89e2438a 789x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
edfda783
AR
790{
791 EmacsView *view = FRAME_NS_VIEW (f);
792 id image = nil;
793 BOOL setMini = YES;
794
89e2438a 795 NSTRACE (x_set_icon_type);
edfda783
AR
796
797 if (!NILP (arg) && SYMBOLP (arg))
798 {
0dc8cf50 799 arg =build_string (SSDATA (SYMBOL_NAME (arg)));
edfda783
AR
800 store_frame_param (f, Qicon_type, arg);
801 }
802
803 /* do it the implicit way */
804 if (NILP (arg))
805 {
806 ns_implicitly_set_icon_type (f);
807 return;
808 }
809
810 CHECK_STRING (arg);
811
812 image = [EmacsImage allocInitFromFile: arg];
813 if (image == nil)
814 image =[NSImage imageNamed: [NSString stringWithUTF8String:
0dc8cf50 815 SSDATA (arg)]];
edfda783
AR
816
817 if (image == nil)
818 {
819 image = [NSImage imageNamed: @"text"];
820 setMini = NO;
821 }
822
823 f->output_data.ns->miniimage = image;
824 [view setMiniwindowImage: setMini];
825}
826
827
6fb5f7da 828/* TODO: move to nsterm? */
edfda783
AR
829int
830ns_lisp_to_cursor_type (Lisp_Object arg)
831{
832 char *str;
833 if (XTYPE (arg) == Lisp_String)
0dc8cf50 834 str = SSDATA (arg);
edfda783 835 else if (XTYPE (arg) == Lisp_Symbol)
0dc8cf50 836 str = SSDATA (SYMBOL_NAME (arg));
edfda783 837 else return -1;
c8c057de
AR
838 if (!strcmp (str, "box")) return FILLED_BOX_CURSOR;
839 if (!strcmp (str, "hollow")) return HOLLOW_BOX_CURSOR;
840 if (!strcmp (str, "hbar")) return HBAR_CURSOR;
841 if (!strcmp (str, "bar")) return BAR_CURSOR;
842 if (!strcmp (str, "no")) return NO_CURSOR;
edfda783
AR
843 return -1;
844}
845
846
847Lisp_Object
848ns_cursor_type_to_lisp (int arg)
849{
850 switch (arg)
851 {
c8c057de
AR
852 case FILLED_BOX_CURSOR: return Qbox;
853 case HOLLOW_BOX_CURSOR: return intern ("hollow");
854 case HBAR_CURSOR: return intern ("hbar");
855 case BAR_CURSOR: return intern ("bar");
856 case NO_CURSOR:
857 default: return intern ("no");
edfda783
AR
858 }
859}
860
89e2438a 861/* This is the same as the xfns.c definition. */
c0342369 862static void
3d608a86 863x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
edfda783 864{
06197b17 865 set_frame_cursor_types (f, arg);
edfda783 866
06197b17
DR
867 /* Make sure the cursor gets redrawn. */
868 cursor_type_changed = 1;
edfda783 869}
06197b17 870\f
edfda783 871
3fe53a83
AR
872/* called to set mouse pointer color, but all other terms use it to
873 initialize pointer types (and don't set the color ;) */
edfda783 874static void
89e2438a 875x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
edfda783 876{
d26fbe1a 877 /* don't think we can do this on Nextstep */
edfda783
AR
878}
879
880
cb83c00b
AR
881#define Str(x) #x
882#define Xstr(x) Str(x)
883
884static Lisp_Object
3d608a86 885ns_appkit_version_str (void)
cb83c00b
AR
886{
887 char tmp[80];
888
889#ifdef NS_IMPL_GNUSTEP
890 sprintf(tmp, "gnustep-gui-%s", Xstr(GNUSTEP_GUI_VERSION));
891#elif defined(NS_IMPL_COCOA)
892 sprintf(tmp, "apple-appkit-%.2f", NSAppKitVersionNumber);
893#else
894 tmp = "ns-unknown";
895#endif
896 return build_string (tmp);
897}
898
899
f5497e45
AR
900/* This is for use by x-server-version and collapses all version info we
901 have into a single int. For a better picture of the implementation
902 running, use ns_appkit_version_str.*/
903static int
3d608a86 904ns_appkit_version_int (void)
f5497e45
AR
905{
906#ifdef NS_IMPL_GNUSTEP
13cd8a29 907 return GNUSTEP_GUI_MAJOR_VERSION * 100 + GNUSTEP_GUI_MINOR_VERSION;
f5497e45
AR
908#elif defined(NS_IMPL_COCOA)
909 return (int)NSAppKitVersionNumber;
910#endif
911 return 0;
912}
913
914
edfda783 915static void
952913d4 916x_icon (struct frame *f, Lisp_Object parms)
edfda783
AR
917/* --------------------------------------------------------------------------
918 Strangely-named function to set icon position parameters in frame.
919 This is irrelevant under OS X, but might be needed under GNUstep,
920 depending on the window manager used. Note, this is not a standard
921 frame parameter-setter; it is called directly from x-create-frame.
922 -------------------------------------------------------------------------- */
923{
924 Lisp_Object icon_x, icon_y;
925 struct ns_display_info *dpyinfo = check_ns_display_info (Qnil);
926
927 f->output_data.ns->icon_top = Qnil;
928 f->output_data.ns->icon_left = Qnil;
929
930 /* Set the position of the icon. */
931 icon_x = x_get_arg (dpyinfo, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
932 icon_y = x_get_arg (dpyinfo, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
933 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
934 {
935 CHECK_NUMBER (icon_x);
936 CHECK_NUMBER (icon_y);
937 f->output_data.ns->icon_top = icon_y;
938 f->output_data.ns->icon_left = icon_x;
939 }
940 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
941 error ("Both left and top icon corners of icon must be specified");
942}
943
944
3fe53a83 945/* Note: see frame.c for template, also where generic functions are impl */
edfda783
AR
946frame_parm_handler ns_frame_parm_handlers[] =
947{
948 x_set_autoraise, /* generic OK */
949 x_set_autolower, /* generic OK */
89e2438a 950 x_set_background_color,
d26fbe1a
CY
951 0, /* x_set_border_color, may be impossible under Nextstep */
952 0, /* x_set_border_width, may be impossible under Nextstep */
89e2438a
DN
953 x_set_cursor_color,
954 x_set_cursor_type,
edfda783 955 x_set_font, /* generic OK */
89e2438a
DN
956 x_set_foreground_color,
957 x_set_icon_name,
958 x_set_icon_type,
edfda783 959 x_set_internal_border_width, /* generic OK */
cc98b6a0 960 x_set_menu_bar_lines,
89e2438a
DN
961 x_set_mouse_color,
962 x_explicitly_set_name,
edfda783 963 x_set_scroll_bar_width, /* generic OK */
89e2438a 964 x_set_title,
edfda783
AR
965 x_set_unsplittable, /* generic OK */
966 x_set_vertical_scroll_bars, /* generic OK */
967 x_set_visibility, /* generic OK */
cc98b6a0 968 x_set_tool_bar_lines,
edfda783
AR
969 0, /* x_set_scroll_bar_foreground, will ignore (not possible on NS) */
970 0, /* x_set_scroll_bar_background, will ignore (not possible on NS) */
971 x_set_screen_gamma, /* generic OK */
972 x_set_line_spacing, /* generic OK, sets f->extra_line_spacing to int */
973 x_set_fringe_width, /* generic OK */
974 x_set_fringe_width, /* generic OK */
975 0, /* x_set_wait_for_wm, will ignore */
dd946752 976 x_set_fullscreen, /* generic OK */
dee721c0 977 x_set_font_backend, /* generic OK */
cad9ef74 978 x_set_alpha,
5fdb398c
PE
979 0, /* x_set_sticky */
980 0, /* x_set_tool_bar_position */
edfda783
AR
981};
982
983
a97f8f3f
JD
984/* Handler for signals raised during x_create_frame.
985 FRAME is the frame which is partially constructed. */
986
987static Lisp_Object
988unwind_create_frame (Lisp_Object frame)
989{
990 struct frame *f = XFRAME (frame);
991
992 /* If frame is already dead, nothing to do. This can happen if the
993 display is disconnected after the frame has become official, but
994 before x_create_frame removes the unwind protect. */
995 if (!FRAME_LIVE_P (f))
996 return Qnil;
997
998 /* If frame is ``official'', nothing to do. */
97f18cc8 999 if (NILP (Fmemq (frame, Vframe_list)))
a97f8f3f 1000 {
ef884f23 1001#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
a97f8f3f
JD
1002 struct ns_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1003#endif
1004
1005 x_free_frame_resources (f);
1006 free_glyphs (f);
1007
ef884f23 1008#ifdef GLYPH_DEBUG
a97f8f3f 1009 /* Check that reference counts are indeed correct. */
ef884f23 1010 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
a97f8f3f
JD
1011#endif
1012 return Qt;
1013 }
1014
1015 return Qnil;
1016}
1017
a0c3fad0
JD
1018/*
1019 * Read geometry related parameters from preferences if not in PARMS.
1020 * Returns the union of parms and any preferences read.
1021 */
a97f8f3f 1022
a0c3fad0
JD
1023static Lisp_Object
1024get_geometry_from_preferences (struct ns_display_info *dpyinfo,
1025 Lisp_Object parms)
1026{
1027 struct {
1028 const char *val;
1029 const char *cls;
1030 Lisp_Object tem;
1031 } r[] = {
1032 { "width", "Width", Qwidth },
1033 { "height", "Height", Qheight },
1034 { "left", "Left", Qleft },
1035 { "top", "Top", Qtop },
1036 };
1037
1038 int i;
1039 for (i = 0; i < sizeof (r)/sizeof (r[0]); ++i)
1040 {
1041 if (NILP (Fassq (r[i].tem, parms)))
1042 {
1043 Lisp_Object value
1044 = x_get_arg (dpyinfo, parms, r[i].tem, r[i].val, r[i].cls,
1045 RES_TYPE_NUMBER);
1046 if (! EQ (value, Qunbound))
1047 parms = Fcons (Fcons (r[i].tem, value), parms);
1048 }
1049 }
a97f8f3f 1050
a0c3fad0
JD
1051 return parms;
1052}
cb83c00b
AR
1053
1054/* ==========================================================================
1055
1056 Lisp definitions
1057
1058 ========================================================================== */
1059
9e50ff0c 1060DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
edfda783 1061 1, 1, 0,
a97f8f3f 1062 doc: /* Make a new Nextstep window, called a "frame" in Emacs terms.
d26fbe1a
CY
1063Return an Emacs frame object.
1064PARMS is an alist of frame parameters.
1065If the parameters specify that the frame should not have a minibuffer,
1066and do not specify a specific minibuffer window to use,
1067then `default-minibuffer-frame' must be a frame whose minibuffer can
a97f8f3f
JD
1068be shared by the new frame.
1069
1070This function is an internal primitive--use `make-frame' instead. */)
5842a27b 1071 (Lisp_Object parms)
edfda783 1072{
edfda783 1073 struct frame *f;
edfda783
AR
1074 Lisp_Object frame, tem;
1075 Lisp_Object name;
1076 int minibuffer_only = 0;
a97f8f3f
JD
1077 int window_prompting = 0;
1078 int width, height;
d311d28c 1079 ptrdiff_t count = specpdl_ptr - specpdl;
a97f8f3f 1080 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
edfda783
AR
1081 Lisp_Object display;
1082 struct ns_display_info *dpyinfo = NULL;
1083 Lisp_Object parent;
1084 struct kboard *kb;
a97f8f3f 1085 static int desc_ctr = 1;
edfda783 1086
a97f8f3f 1087 /* x_get_arg modifies parms. */
bd6ce2ba
AR
1088 parms = Fcopy_alist (parms);
1089
a97f8f3f
JD
1090 /* Use this general default value to start with
1091 until we know if this frame has a specified name. */
1092 Vx_resource_name = Vinvocation_name;
1093
edfda783
AR
1094 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_STRING);
1095 if (EQ (display, Qunbound))
1096 display = Qnil;
1097 dpyinfo = check_ns_display_info (display);
a97f8f3f 1098 kb = dpyinfo->terminal->kboard;
edfda783
AR
1099
1100 if (!dpyinfo->terminal->name)
1101 error ("Terminal is not live, can't create new frames on it");
1102
edfda783
AR
1103 name = x_get_arg (dpyinfo, parms, Qname, 0, 0, RES_TYPE_STRING);
1104 if (!STRINGP (name)
1105 && ! EQ (name, Qunbound)
1106 && ! NILP (name))
1107 error ("Invalid frame name--not a string or nil");
1108
1109 if (STRINGP (name))
1110 Vx_resource_name = name;
1111
1112 parent = x_get_arg (dpyinfo, parms, Qparent_id, 0, 0, RES_TYPE_NUMBER);
1113 if (EQ (parent, Qunbound))
1114 parent = Qnil;
1115 if (! NILP (parent))
1116 CHECK_NUMBER (parent);
1117
a97f8f3f
JD
1118 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
1119 /* No need to protect DISPLAY because that's not used after passing
1120 it to make_frame_without_minibuffer. */
edfda783
AR
1121 frame = Qnil;
1122 GCPRO4 (parms, parent, name, frame);
edfda783
AR
1123 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
1124 RES_TYPE_SYMBOL);
1125 if (EQ (tem, Qnone) || NILP (tem))
edfda783 1126 f = make_frame_without_minibuffer (Qnil, kb, display);
edfda783
AR
1127 else if (EQ (tem, Qonly))
1128 {
1129 f = make_minibuffer_frame ();
1130 minibuffer_only = 1;
1131 }
1132 else if (WINDOWP (tem))
edfda783 1133 f = make_frame_without_minibuffer (tem, kb, display);
edfda783 1134 else
edfda783 1135 f = make_frame (1);
edfda783
AR
1136
1137 XSETFRAME (frame, f);
edfda783
AR
1138
1139 f->terminal = dpyinfo->terminal;
edfda783
AR
1140
1141 f->output_method = output_ns;
38182d90 1142 f->output_data.ns = xzalloc (sizeof *f->output_data.ns);
edfda783
AR
1143
1144 FRAME_FONTSET (f) = -1;
1145
f00af5b1
PE
1146 fset_icon_name (f, x_get_arg (dpyinfo, parms, Qicon_name,
1147 "iconName", "Title",
1148 RES_TYPE_STRING));
e69b0960 1149 if (! STRINGP (f->icon_name))
f00af5b1 1150 fset_icon_name (f, Qnil);
edfda783
AR
1151
1152 FRAME_NS_DISPLAY_INFO (f) = dpyinfo;
1153
a97f8f3f
JD
1154 /* With FRAME_NS_DISPLAY_INFO set up, this unwind-protect is safe. */
1155 record_unwind_protect (unwind_create_frame, frame);
1156
edfda783 1157 f->output_data.ns->window_desc = desc_ctr++;
d311d28c 1158 if (TYPE_RANGED_INTEGERP (Window, parent))
edfda783 1159 {
d311d28c 1160 f->output_data.ns->parent_desc = XFASTINT (parent);
edfda783
AR
1161 f->output_data.ns->explicit_parent = 1;
1162 }
1163 else
1164 {
1165 f->output_data.ns->parent_desc = FRAME_NS_DISPLAY_INFO (f)->root_window;
1166 f->output_data.ns->explicit_parent = 0;
1167 }
1168
a97f8f3f
JD
1169 /* Set the name; the functions to which we pass f expect the name to
1170 be set. */
1171 if (EQ (name, Qunbound) || NILP (name) || ! STRINGP (name))
1172 {
f00af5b1 1173 fset_name (f, build_string ([ns_app_name UTF8String]));
a97f8f3f
JD
1174 f->explicit_name = 0;
1175 }
1176 else
1177 {
f00af5b1 1178 fset_name (f, name);
a97f8f3f
JD
1179 f->explicit_name = 1;
1180 specbind (Qx_resource_name, name);
1181 }
1182
4d7e6e51 1183 block_input ();
edfda783
AR
1184 register_font_driver (&nsfont_driver, f);
1185 x_default_parameter (f, parms, Qfont_backend, Qnil,
1186 "fontBackend", "FontBackend", RES_TYPE_STRING);
1187
1188 {
1189 /* use for default font name */
1190 id font = [NSFont userFixedPitchFontOfSize: -1.0]; /* default */
c0342369 1191 x_default_parameter (f, parms, Qfontsize,
edfda783
AR
1192 make_number (0 /*(int)[font pointSize]*/),
1193 "fontSize", "FontSize", RES_TYPE_NUMBER);
c0342369 1194 x_default_parameter (f, parms, Qfont,
edfda783
AR
1195 build_string ([[font fontName] UTF8String]),
1196 "font", "Font", RES_TYPE_STRING);
1197 }
4d7e6e51 1198 unblock_input ();
edfda783
AR
1199
1200 x_default_parameter (f, parms, Qborder_width, make_number (0),
1201 "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
1202 x_default_parameter (f, parms, Qinternal_border_width, make_number (2),
1203 "internalBorderWidth", "InternalBorderWidth",
1204 RES_TYPE_NUMBER);
1205
1206 /* default scrollbars on right on Mac */
1207 {
facfbbbd 1208 Lisp_Object spos
edfda783 1209#ifdef NS_IMPL_GNUSTEP
facfbbbd 1210 = Qt;
edfda783 1211#else
facfbbbd 1212 = Qright;
edfda783 1213#endif
facfbbbd
SM
1214 x_default_parameter (f, parms, Qvertical_scroll_bars, spos,
1215 "verticalScrollBars", "VerticalScrollBars",
1216 RES_TYPE_SYMBOL);
edfda783
AR
1217 }
1218 x_default_parameter (f, parms, Qforeground_color, build_string ("Black"),
1219 "foreground", "Foreground", RES_TYPE_STRING);
1220 x_default_parameter (f, parms, Qbackground_color, build_string ("White"),
1221 "background", "Background", RES_TYPE_STRING);
22bcf204 1222 /* FIXME: not supported yet in Nextstep */
edfda783
AR
1223 x_default_parameter (f, parms, Qline_spacing, Qnil,
1224 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
1225 x_default_parameter (f, parms, Qleft_fringe, Qnil,
1226 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
1227 x_default_parameter (f, parms, Qright_fringe, Qnil,
1228 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
edfda783 1229
ef884f23 1230#ifdef GLYPH_DEBUG
a97f8f3f
JD
1231 image_cache_refcount =
1232 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
1233#endif
edfda783
AR
1234
1235 init_frame_faces (f);
1236
a97f8f3f 1237 /* The resources controlling the menu-bar and tool-bar are
6431f2e6
CY
1238 processed specially at startup, and reflected in the mode
1239 variables; ignore them here. */
1240 x_default_parameter (f, parms, Qmenu_bar_lines,
1241 NILP (Vmenu_bar_mode)
1242 ? make_number (0) : make_number (1),
1243 NULL, NULL, RES_TYPE_NUMBER);
1244 x_default_parameter (f, parms, Qtool_bar_lines,
1245 NILP (Vtool_bar_mode)
1246 ? make_number (0) : make_number (1),
1247 NULL, NULL, RES_TYPE_NUMBER);
1248
edfda783
AR
1249 x_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate",
1250 "BufferPredicate", RES_TYPE_SYMBOL);
1251 x_default_parameter (f, parms, Qtitle, Qnil, "title", "Title",
1252 RES_TYPE_STRING);
1253
a0c3fad0 1254 parms = get_geometry_from_preferences (dpyinfo, parms);
edfda783
AR
1255 window_prompting = x_figure_window_size (f, parms, 1);
1256
1257 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
1258 f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !EQ (tem, Qnil));
1259
1260 /* NOTE: on other terms, this is done in set_mouse_color, however this
d26fbe1a 1261 was not getting called under Nextstep */
edfda783
AR
1262 f->output_data.ns->text_cursor = [NSCursor IBeamCursor];
1263 f->output_data.ns->nontext_cursor = [NSCursor arrowCursor];
1264 f->output_data.ns->modeline_cursor = [NSCursor pointingHandCursor];
1265 f->output_data.ns->hand_cursor = [NSCursor pointingHandCursor];
1266 f->output_data.ns->hourglass_cursor = [NSCursor disappearingItemCursor];
1267 f->output_data.ns->horizontal_drag_cursor = [NSCursor resizeLeftRightCursor];
facfbbbd
SM
1268 FRAME_NS_DISPLAY_INFO (f)->vertical_scroll_bar_cursor
1269 = [NSCursor arrowCursor];
edfda783
AR
1270 f->output_data.ns->current_pointer = f->output_data.ns->text_cursor;
1271
1272 [[EmacsView alloc] initFrameFromEmacs: f];
1273
952913d4 1274 x_icon (f, parms);
edfda783 1275
a97f8f3f
JD
1276 /* ns_display_info does not have a reference_count. */
1277 f->terminal->reference_count++;
1278
edfda783
AR
1279 /* It is now ok to make the frame official even if we get an error below.
1280 The frame needs to be on Vframe_list or making it visible won't work. */
1281 Vframe_list = Fcons (frame, Vframe_list);
a97f8f3f
JD
1282
1283 x_default_parameter (f, parms, Qicon_type, Qnil,
1284 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
1285
1286 x_default_parameter (f, parms, Qauto_raise, Qnil,
1287 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
1288 x_default_parameter (f, parms, Qauto_lower, Qnil,
1289 "autoLower", "AutoLower", RES_TYPE_BOOLEAN);
1290 x_default_parameter (f, parms, Qcursor_type, Qbox,
1291 "cursorType", "CursorType", RES_TYPE_SYMBOL);
1292 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
1293 "scrollBarWidth", "ScrollBarWidth",
1294 RES_TYPE_NUMBER);
1295 x_default_parameter (f, parms, Qalpha, Qnil,
1296 "alpha", "Alpha", RES_TYPE_NUMBER);
04fafa46
JD
1297 x_default_parameter (f, parms, Qfullscreen, Qnil,
1298 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
edfda783
AR
1299
1300 width = FRAME_COLS (f);
1301 height = FRAME_LINES (f);
1302
1303 SET_FRAME_COLS (f, 0);
1304 FRAME_LINES (f) = 0;
1305 change_frame_size (f, height, width, 1, 0, 0);
1306
1307 if (! f->output_data.ns->explicit_parent)
1308 {
a97f8f3f
JD
1309 Lisp_Object visibility;
1310
1311 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
1312 RES_TYPE_SYMBOL);
1313 if (EQ (visibility, Qunbound))
1314 visibility = Qt;
1315
1316 if (EQ (visibility, Qicon))
15891144 1317 x_iconify_frame (f);
a97f8f3f 1318 else if (! NILP (visibility))
15891144
DR
1319 {
1320 x_make_frame_visible (f);
15891144
DR
1321 [[FRAME_NS_VIEW (f) window] makeKeyWindow];
1322 }
1323 else
a97f8f3f
JD
1324 {
1325 /* Must have been Qnil. */
1326 }
edfda783
AR
1327 }
1328
1329 if (FRAME_HAS_MINIBUF_P (f)
124c9ff0
JD
1330 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
1331 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
15dbb4d6 1332 kset_default_minibuffer_frame (kb, frame);
edfda783
AR
1333
1334 /* All remaining specified parameters, which have not been "used"
1335 by x_get_arg and friends, now go in the misc. alist of the frame. */
1336 for (tem = parms; CONSP (tem); tem = XCDR (tem))
1337 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
f00af5b1 1338 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
edfda783
AR
1339
1340 UNGCPRO;
a97f8f3f 1341
e543ae91
JD
1342 if (window_prompting & USPosition)
1343 x_set_offset (f, f->left_pos, f->top_pos, 1);
1344
a97f8f3f
JD
1345 /* Make sure windows on this frame appear in calls to next-window
1346 and similar functions. */
edfda783
AR
1347 Vwindow_list = Qnil;
1348
1349 return unbind_to (count, frame);
1350}
1351
1352
9e50ff0c 1353DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
edfda783
AR
1354 doc: /* Set the input focus to FRAME.
1355FRAME nil means use the selected frame. */)
5842a27b 1356 (Lisp_Object frame)
edfda783 1357{
7452b7bd 1358 struct frame *f = decode_window_system_frame (frame);
edfda783
AR
1359 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
1360
9e50ff0c 1361 if (dpyinfo->x_focus_frame != f)
edfda783
AR
1362 {
1363 EmacsView *view = FRAME_NS_VIEW (f);
4d7e6e51 1364 block_input ();
4acaaa2b 1365 [NSApp activateIgnoringOtherApps: YES];
edfda783 1366 [[view window] makeKeyAndOrderFront: view];
4d7e6e51 1367 unblock_input ();
edfda783
AR
1368 }
1369
1370 return Qnil;
1371}
1372
1373
edfda783 1374DEFUN ("ns-popup-font-panel", Fns_popup_font_panel, Sns_popup_font_panel,
51d5ef9f
AR
1375 0, 1, "",
1376 doc: /* Pop up the font panel. */)
5842a27b 1377 (Lisp_Object frame)
edfda783 1378{
7452b7bd
DA
1379 struct frame *f = decode_window_system_frame (frame);
1380 id fm = [NSFontManager sharedFontManager];
edfda783
AR
1381
1382 [fm setSelectedFont: ((struct nsfont_info *)f->output_data.ns->font)->nsfont
1383 isMultiple: NO];
1384 [fm orderFrontFontPanel: NSApp];
1385 return Qnil;
1386}
1387
1388
b066e6b6 1389DEFUN ("ns-popup-color-panel", Fns_popup_color_panel, Sns_popup_color_panel,
51d5ef9f
AR
1390 0, 1, "",
1391 doc: /* Pop up the color panel. */)
5842a27b 1392 (Lisp_Object frame)
edfda783 1393{
7452b7bd 1394 check_window_system (NULL);
edfda783
AR
1395 [NSApp orderFrontColorPanel: NSApp];
1396 return Qnil;
1397}
1398
1399
d7e642cc 1400DEFUN ("ns-read-file-name", Fns_read_file_name, Sns_read_file_name, 1, 5, 0,
51d5ef9f 1401 doc: /* Use a graphical panel to read a file name, using prompt PROMPT.
d26fbe1a 1402Optional arg DIR, if non-nil, supplies a default directory.
45cb8994
CY
1403Optional arg MUSTMATCH, if non-nil, means the returned file or
1404directory must exist.
d7e642cc
JD
1405Optional arg INIT, if non-nil, provides a default file name to use.
1406Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1407 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object mustmatch,
1408 Lisp_Object init, Lisp_Object dir_only_p)
edfda783
AR
1409{
1410 static id fileDelegate = nil;
8f2906f5 1411 BOOL ret;
c0342369 1412 BOOL isSave = NILP (mustmatch) && NILP (dir_only_p);
edfda783 1413 id panel;
ba301db3 1414 Lisp_Object fname;
edfda783
AR
1415
1416 NSString *promptS = NILP (prompt) || !STRINGP (prompt) ? nil :
0dc8cf50 1417 [NSString stringWithUTF8String: SSDATA (prompt)];
edfda783 1418 NSString *dirS = NILP (dir) || !STRINGP (dir) ?
0dc8cf50
JD
1419 [NSString stringWithUTF8String: SSDATA (BVAR (current_buffer, directory))] :
1420 [NSString stringWithUTF8String: SSDATA (dir)];
edfda783 1421 NSString *initS = NILP (init) || !STRINGP (init) ? nil :
0dc8cf50 1422 [NSString stringWithUTF8String: SSDATA (init)];
edfda783 1423
7452b7bd 1424 check_window_system (NULL);
edfda783
AR
1425
1426 if (fileDelegate == nil)
1427 fileDelegate = [EmacsFileDelegate new];
1428
1429 [NSCursor setHiddenUntilMouseMoves: NO];
1430
1431 if ([dirS characterAtIndex: 0] == '~')
1432 dirS = [dirS stringByExpandingTildeInPath];
1433
c0342369 1434 panel = isSave ?
f2f7f42c 1435 (id)[EmacsSavePanel savePanel] : (id)[EmacsOpenPanel openPanel];
edfda783
AR
1436
1437 [panel setTitle: promptS];
1438
d7e642cc 1439 [panel setAllowsOtherFileTypes: YES];
edfda783
AR
1440 [panel setTreatsFilePackagesAsDirectories: YES];
1441 [panel setDelegate: fileDelegate];
1442
1443 panelOK = 0;
677d5c92 1444 if (! NILP (dir_only_p))
d7e642cc
JD
1445 {
1446 [panel setCanChooseDirectories: YES];
1447 [panel setCanChooseFiles: NO];
1448 }
c0342369 1449 else if (! isSave)
8f2906f5
JD
1450 {
1451 /* This is not quite what the documentation says, but it is compatible
1452 with the Gtk+ code. Also, the menu entry says "Open File...". */
1453 [panel setCanChooseDirectories: NO];
1454 [panel setCanChooseFiles: YES];
1455 }
677d5c92 1456
edbdcec0 1457 block_input ();
d7e642cc
JD
1458#if defined (NS_IMPL_COCOA) && \
1459 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
1460 if (! NILP (mustmatch) || ! NILP (dir_only_p))
1461 [panel setAllowedFileTypes: nil];
1462 if (dirS) [panel setDirectoryURL: [NSURL fileURLWithPath: dirS]];
1463 if (initS && NILP (Ffile_directory_p (init)))
1464 [panel setNameFieldStringValue: [initS lastPathComponent]];
1465 else
1466 [panel setNameFieldStringValue: @""];
677d5c92 1467
d7e642cc
JD
1468 ret = [panel runModal];
1469#else
1470 if (NILP (mustmatch) && NILP (dir_only_p))
edfda783
AR
1471 {
1472 ret = [panel runModalForDirectory: dirS file: initS];
1473 }
1474 else
1475 {
edfda783
AR
1476 ret = [panel runModalForDirectory: dirS file: initS types: nil];
1477 }
d7e642cc 1478#endif
edfda783 1479
575fb8bd 1480 ret = (ret == NSOKButton) || panelOK;
edfda783 1481
a37d34f3 1482 if (ret)
8f2906f5 1483 {
c0342369
JD
1484 NSString *str = ns_filename_from_panel (panel);
1485 if (! str) str = ns_directory_from_panel (panel);
8f2906f5
JD
1486 if (! str) ret = NO;
1487 else fname = build_string ([str UTF8String]);
1488 }
b066e6b6 1489
edfda783 1490 [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
4d7e6e51 1491 unblock_input ();
edfda783 1492
ba301db3 1493 return ret ? fname : Qnil;
edfda783
AR
1494}
1495
f7dfe5d6
JD
1496const char *
1497ns_get_defaults_value (const char *key)
1498{
1499 NSObject *obj = [[NSUserDefaults standardUserDefaults]
1500 objectForKey: [NSString stringWithUTF8String: key]];
1501
1502 if (!obj) return NULL;
1503
1504 return [[NSString stringWithFormat: @"%@", obj] UTF8String];
1505}
1506
edfda783
AR
1507
1508DEFUN ("ns-get-resource", Fns_get_resource, Sns_get_resource, 2, 2, 0,
51d5ef9f
AR
1509 doc: /* Return the value of the property NAME of OWNER from the defaults database.
1510If OWNER is nil, Emacs is assumed. */)
5842a27b 1511 (Lisp_Object owner, Lisp_Object name)
edfda783
AR
1512{
1513 const char *value;
1514
7452b7bd 1515 check_window_system (NULL);
edfda783 1516 if (NILP (owner))
56d513e6 1517 owner = build_string([ns_app_name UTF8String]);
edfda783 1518 CHECK_STRING (name);
edfda783 1519
0dc8cf50 1520 value = ns_get_defaults_value (SSDATA (name));
edfda783
AR
1521
1522 if (value)
1523 return build_string (value);
edfda783
AR
1524 return Qnil;
1525}
1526
1527
1528DEFUN ("ns-set-resource", Fns_set_resource, Sns_set_resource, 3, 3, 0,
51d5ef9f 1529 doc: /* Set property NAME of OWNER to VALUE, from the defaults database.
d26fbe1a 1530If OWNER is nil, Emacs is assumed.
51d5ef9f 1531If VALUE is nil, the default is removed. */)
5842a27b 1532 (Lisp_Object owner, Lisp_Object name, Lisp_Object value)
edfda783 1533{
7452b7bd 1534 check_window_system (NULL);
edfda783 1535 if (NILP (owner))
56d513e6 1536 owner = build_string ([ns_app_name UTF8String]);
edfda783
AR
1537 CHECK_STRING (name);
1538 if (NILP (value))
1539 {
1540 [[NSUserDefaults standardUserDefaults] removeObjectForKey:
0dc8cf50 1541 [NSString stringWithUTF8String: SSDATA (name)]];
edfda783
AR
1542 }
1543 else
1544 {
1545 CHECK_STRING (value);
1546 [[NSUserDefaults standardUserDefaults] setObject:
0dc8cf50 1547 [NSString stringWithUTF8String: SSDATA (value)]
edfda783 1548 forKey: [NSString stringWithUTF8String:
0dc8cf50 1549 SSDATA (name)]];
edfda783
AR
1550 }
1551
1552 return Qnil;
1553}
1554
1555
952913d4
DN
1556DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
1557 Sx_server_max_request_size,
edfda783 1558 0, 1, 0,
51d5ef9f 1559 doc: /* This function is a no-op. It is only present for completeness. */)
91e8418b 1560 (Lisp_Object terminal)
edfda783 1561{
91e8418b 1562 check_ns_display_info (terminal);
edfda783
AR
1563 /* This function has no real equivalent under NeXTstep. Return nil to
1564 indicate this. */
1565 return Qnil;
1566}
1567
1568
9e50ff0c 1569DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
91e8418b
YM
1570 doc: /* Return the "vendor ID" string of Nextstep display server TERMINAL.
1571\(Labeling every distributor as a "vendor" embodies the false assumption
1572that operating systems cannot be developed and distributed noncommercially.)
1573The optional argument TERMINAL specifies which display to ask about.
1574TERMINAL should be a terminal object, a frame or a display name (a string).
1575If omitted or nil, that stands for the selected frame's display. */)
1576 (Lisp_Object terminal)
edfda783 1577{
91e8418b 1578 check_ns_display_info (terminal);
edfda783
AR
1579#ifdef NS_IMPL_GNUSTEP
1580 return build_string ("GNU");
1581#else
1582 return build_string ("Apple");
1583#endif
1584}
1585
1586
9e50ff0c 1587DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
91e8418b 1588 doc: /* Return the version numbers of the server of display TERMINAL.
f5497e45 1589The value is a list of three integers: the major and minor
91e8418b
YM
1590version numbers of the X Protocol in use, and the distributor-specific release
1591number. See also the function `x-server-vendor'.
f5497e45 1592
91e8418b
YM
1593The optional argument TERMINAL specifies which display to ask about.
1594TERMINAL should be a terminal object, a frame or a display name (a string).
f5497e45 1595If omitted or nil, that stands for the selected frame's display. */)
91e8418b 1596 (Lisp_Object terminal)
edfda783 1597{
91e8418b 1598 check_ns_display_info (terminal);
f5497e45
AR
1599 /*NOTE: it is unclear what would best correspond with "protocol";
1600 we return 10.3, meaning Panther, since this is roughly the
1601 level that GNUstep's APIs correspond to.
1602 The last number is where we distinguish between the Apple
1603 and GNUstep implementations ("distributor-specific release
1604 number") and give int'ized versions of major.minor. */
3de717bd 1605 return list3i (10, 3, ns_appkit_version_int ());
edfda783
AR
1606}
1607
1608
9e50ff0c 1609DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
91e8418b
YM
1610 doc: /* Return the number of screens on Nextstep display server TERMINAL.
1611The optional argument TERMINAL specifies which display to ask about.
1612TERMINAL should be a terminal object, a frame or a display name (a string).
1613If omitted or nil, that stands for the selected frame's display.
edfda783 1614
91e8418b
YM
1615Note: "screen" here is not in Nextstep terminology but in X11's. For
1616the number of physical monitors, use `(length
1617(display-monitor-attributes-list TERMINAL))' instead. */)
1618 (Lisp_Object terminal)
1619{
1620 check_ns_display_info (terminal);
1621 return make_number (1);
edfda783
AR
1622}
1623
1624
91e8418b
YM
1625DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
1626 doc: /* Return the height in millimeters of the Nextstep display TERMINAL.
1627The optional argument TERMINAL specifies which display to ask about.
1628TERMINAL should be a terminal object, a frame or a display name (a string).
1629If omitted or nil, that stands for the selected frame's display.
1630
1631On \"multi-monitor\" setups this refers to the height in millimeters for
1632all physical monitors associated with TERMINAL. To get information
1633for each physical monitor, use `display-monitor-attributes-list'. */)
1634 (Lisp_Object terminal)
edfda783 1635{
91e8418b
YM
1636 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
1637
1638 return make_number (x_display_pixel_height (dpyinfo) / (92.0/25.4));
edfda783
AR
1639}
1640
1641
91e8418b
YM
1642DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
1643 doc: /* Return the width in millimeters of the Nextstep display TERMINAL.
1644The optional argument TERMINAL specifies which display to ask about.
1645TERMINAL should be a terminal object, a frame or a display name (a string).
1646If omitted or nil, that stands for the selected frame's display.
1647
1648On \"multi-monitor\" setups this refers to the width in millimeters for
1649all physical monitors associated with TERMINAL. To get information
1650for each physical monitor, use `display-monitor-attributes-list'. */)
1651 (Lisp_Object terminal)
edfda783 1652{
91e8418b
YM
1653 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
1654
1655 return make_number (x_display_pixel_width (dpyinfo) / (92.0/25.4));
edfda783
AR
1656}
1657
1658
9e50ff0c 1659DEFUN ("x-display-backing-store", Fx_display_backing_store,
51d5ef9f 1660 Sx_display_backing_store, 0, 1, 0,
91e8418b 1661 doc: /* Return an indication of whether the Nextstep display TERMINAL does backing store.
d26fbe1a 1662The value may be `buffered', `retained', or `non-retained'.
91e8418b
YM
1663The optional argument TERMINAL specifies which display to ask about.
1664TERMINAL should be a terminal object, a frame or a display name (a string).
1665If omitted or nil, that stands for the selected frame's display. */)
1666 (Lisp_Object terminal)
edfda783 1667{
91e8418b
YM
1668 check_ns_display_info (terminal);
1669 switch ([ns_get_window (terminal) backingType])
edfda783
AR
1670 {
1671 case NSBackingStoreBuffered:
1672 return intern ("buffered");
1673 case NSBackingStoreRetained:
1674 return intern ("retained");
1675 case NSBackingStoreNonretained:
1676 return intern ("non-retained");
1677 default:
1678 error ("Strange value for backingType parameter of frame");
1679 }
1680 return Qnil; /* not reached, shut compiler up */
1681}
1682
1683
9e50ff0c 1684DEFUN ("x-display-visual-class", Fx_display_visual_class,
51d5ef9f 1685 Sx_display_visual_class, 0, 1, 0,
91e8418b 1686 doc: /* Return the visual class of the Nextstep display TERMINAL.
d26fbe1a
CY
1687The value is one of the symbols `static-gray', `gray-scale',
1688`static-color', `pseudo-color', `true-color', or `direct-color'.
91e8418b
YM
1689
1690The optional argument TERMINAL specifies which display to ask about.
1691TERMINAL should a terminal object, a frame or a display name (a string).
1692If omitted or nil, that stands for the selected frame's display. */)
1693 (Lisp_Object terminal)
edfda783
AR
1694{
1695 NSWindowDepth depth;
a37d34f3 1696
91e8418b
YM
1697 check_ns_display_info (terminal);
1698 depth = [[[NSScreen screens] objectAtIndex:0] depth];
edfda783
AR
1699
1700 if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
1701 return intern ("static-gray");
1702 else if (depth == NSBestDepth (NSCalibratedWhiteColorSpace, 8, 8, YES, NULL))
1703 return intern ("gray-scale");
1704 else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 8, 8, YES, NULL))
1705 return intern ("pseudo-color");
1706 else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 4, 12, NO, NULL))
1707 return intern ("true-color");
1708 else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 8, 24, NO, NULL))
1709 return intern ("direct-color");
1710 else
d26fbe1a 1711 /* color mgmt as far as we do it is really handled by Nextstep itself anyway */
edfda783
AR
1712 return intern ("direct-color");
1713}
1714
1715
9e50ff0c 1716DEFUN ("x-display-save-under", Fx_display_save_under,
51d5ef9f 1717 Sx_display_save_under, 0, 1, 0,
91e8418b
YM
1718 doc: /* Return t if TERMINAL supports the save-under feature.
1719The optional argument TERMINAL specifies which display to ask about.
1720TERMINAL should be a terminal object, a frame or a display name (a string).
1721If omitted or nil, that stands for the selected frame's display. */)
1722 (Lisp_Object terminal)
1723{
1724 check_ns_display_info (terminal);
1725 switch ([ns_get_window (terminal) backingType])
edfda783
AR
1726 {
1727 case NSBackingStoreBuffered:
1728 return Qt;
1729
1730 case NSBackingStoreRetained:
1731 case NSBackingStoreNonretained:
1732 return Qnil;
1733
1734 default:
1735 error ("Strange value for backingType parameter of frame");
1736 }
1737 return Qnil; /* not reached, shut compiler up */
1738}
1739
1740
9e50ff0c 1741DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
51d5ef9f 1742 1, 3, 0,
4f4f2973 1743 doc: /* Open a connection to a display server.
d26fbe1a 1744DISPLAY is the name of the display to connect to.
4f4f2973
GM
1745Optional second arg XRM-STRING is a string of resources in xrdb format.
1746If the optional third arg MUST-SUCCEED is non-nil,
1747terminate Emacs if we can't open the connection.
1748\(In the Nextstep version, the last two arguments are currently ignored.) */)
5842a27b 1749 (Lisp_Object display, Lisp_Object resource_string, Lisp_Object must_succeed)
edfda783
AR
1750{
1751 struct ns_display_info *dpyinfo;
1752
1753 CHECK_STRING (display);
1754
1755 nxatoms_of_nsselect ();
1756 dpyinfo = ns_term_init (display);
1757 if (dpyinfo == 0)
1758 {
1759 if (!NILP (must_succeed))
1760 fatal ("OpenStep on %s not responding.\n",
0dc8cf50 1761 SSDATA (display));
edfda783
AR
1762 else
1763 error ("OpenStep on %s not responding.\n",
0dc8cf50 1764 SSDATA (display));
edfda783
AR
1765 }
1766
edfda783
AR
1767 return Qnil;
1768}
1769
1770
9e50ff0c 1771DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection,
51d5ef9f 1772 1, 1, 0,
91e8418b
YM
1773 doc: /* Close the connection to TERMINAL's Nextstep display server.
1774For TERMINAL, specify a terminal object, a frame or a display name (a
1775string). If TERMINAL is nil, that stands for the selected frame's
1776terminal. */)
1777 (Lisp_Object terminal)
edfda783 1778{
91e8418b 1779 check_ns_display_info (terminal);
edfda783
AR
1780 [NSApp terminate: NSApp];
1781 return Qnil;
1782}
1783
1784
9e50ff0c 1785DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
51d5ef9f 1786 doc: /* Return the list of display names that Emacs has connections to. */)
5842a27b 1787 (void)
edfda783
AR
1788{
1789 Lisp_Object tail, result;
1790
1791 result = Qnil;
1792 for (tail = ns_display_name_list; CONSP (tail); tail = XCDR (tail))
1793 result = Fcons (XCAR (XCAR (tail)), result);
1794
1795 return result;
1796}
1797
1798
1799DEFUN ("ns-hide-others", Fns_hide_others, Sns_hide_others,
51d5ef9f 1800 0, 0, 0,
b066e6b6 1801 doc: /* Hides all applications other than Emacs. */)
5842a27b 1802 (void)
edfda783 1803{
7452b7bd 1804 check_window_system (NULL);
edfda783
AR
1805 [NSApp hideOtherApplications: NSApp];
1806 return Qnil;
1807}
1808
1809DEFUN ("ns-hide-emacs", Fns_hide_emacs, Sns_hide_emacs,
51d5ef9f 1810 1, 1, 0,
b066e6b6
JB
1811 doc: /* If ON is non-nil, the entire Emacs application is hidden.
1812Otherwise if Emacs is hidden, it is unhidden.
1813If ON is equal to `activate', Emacs is unhidden and becomes
51d5ef9f 1814the active application. */)
5842a27b 1815 (Lisp_Object on)
edfda783 1816{
7452b7bd 1817 check_window_system (NULL);
edfda783
AR
1818 if (EQ (on, intern ("activate")))
1819 {
1820 [NSApp unhide: NSApp];
1821 [NSApp activateIgnoringOtherApps: YES];
1822 }
1823 else if (NILP (on))
1824 [NSApp unhide: NSApp];
1825 else
1826 [NSApp hide: NSApp];
1827 return Qnil;
1828}
1829
1830
1831DEFUN ("ns-emacs-info-panel", Fns_emacs_info_panel, Sns_emacs_info_panel,
51d5ef9f
AR
1832 0, 0, 0,
1833 doc: /* Shows the 'Info' or 'About' panel for Emacs. */)
5842a27b 1834 (void)
edfda783 1835{
7452b7bd 1836 check_window_system (NULL);
edfda783
AR
1837 [NSApp orderFrontStandardAboutPanel: nil];
1838 return Qnil;
1839}
1840
1841
edfda783 1842DEFUN ("ns-font-name", Fns_font_name, Sns_font_name, 1, 1, 0,
7877f373 1843 doc: /* Determine font PostScript or family name for font NAME.
d26fbe1a
CY
1844NAME should be a string containing either the font name or an XLFD
1845font descriptor. If string contains `fontset' and not
51d5ef9f 1846`fontset-startup', it is left alone. */)
5842a27b 1847 (Lisp_Object name)
edfda783
AR
1848{
1849 char *nm;
1850 CHECK_STRING (name);
0dc8cf50 1851 nm = SSDATA (name);
edfda783
AR
1852
1853 if (nm[0] != '-')
1854 return name;
1855 if (strstr (nm, "fontset") && !strstr (nm, "fontset-startup"))
1856 return name;
1857
0dc8cf50 1858 return build_string (ns_xlfd_to_fontname (SSDATA (name)));
edfda783
AR
1859}
1860
1861
1862DEFUN ("ns-list-colors", Fns_list_colors, Sns_list_colors, 0, 1, 0,
51d5ef9f
AR
1863 doc: /* Return a list of all available colors.
1864The optional argument FRAME is currently ignored. */)
5842a27b 1865 (Lisp_Object frame)
edfda783
AR
1866{
1867 Lisp_Object list = Qnil;
1868 NSEnumerator *colorlists;
1869 NSColorList *clist;
1870
1871 if (!NILP (frame))
1872 {
1873 CHECK_FRAME (frame);
1874 if (! FRAME_NS_P (XFRAME (frame)))
d26fbe1a 1875 error ("non-Nextstep frame used in `ns-list-colors'");
edfda783
AR
1876 }
1877
4d7e6e51 1878 block_input ();
edfda783
AR
1879
1880 colorlists = [[NSColorList availableColorLists] objectEnumerator];
0dc8cf50 1881 while ((clist = [colorlists nextObject]))
edfda783
AR
1882 {
1883 if ([[clist name] length] < 7 ||
1884 [[clist name] rangeOfString: @"PANTONE"].location == 0)
1885 {
1886 NSEnumerator *cnames = [[clist allKeys] reverseObjectEnumerator];
1887 NSString *cname;
0dc8cf50 1888 while ((cname = [cnames nextObject]))
edfda783
AR
1889 list = Fcons (build_string ([cname UTF8String]), list);
1890/* for (i = [[clist allKeys] count] - 1; i >= 0; i--)
1891 list = Fcons (build_string ([[[clist allKeys] objectAtIndex: i]
1892 UTF8String]), list); */
1893 }
1894 }
1895
4d7e6e51 1896 unblock_input ();
edfda783
AR
1897
1898 return list;
1899}
1900
1901
1902DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0,
51d5ef9f 1903 doc: /* List available Nextstep services by querying NSApp. */)
5842a27b 1904 (void)
edfda783 1905{
699c10bd
JD
1906#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
1907 /* You can't get services like this in 10.6+. */
1908 return Qnil;
1909#else
edfda783
AR
1910 Lisp_Object ret = Qnil;
1911 NSMenu *svcs;
c0342369 1912#ifdef NS_IMPL_COCOA
edfda783 1913 id delegate;
c0342369 1914#endif
edfda783 1915
7452b7bd 1916 check_window_system (NULL);
edfda783 1917 svcs = [[NSMenu alloc] initWithTitle: @"Services"];
335f5ae4 1918 [NSApp setServicesMenu: svcs];
edfda783
AR
1919 [NSApp registerServicesMenuSendTypes: ns_send_types
1920 returnTypes: ns_return_types];
1921
1922/* On Tiger, services menu updating was made lazier (waits for user to
1923 actually click on the menu), so we have to force things along: */
1924#ifdef NS_IMPL_COCOA
335f5ae4
JD
1925 delegate = [svcs delegate];
1926 if (delegate != nil)
edfda783 1927 {
335f5ae4
JD
1928 if ([delegate respondsToSelector: @selector (menuNeedsUpdate:)])
1929 [delegate menuNeedsUpdate: svcs];
1930 if ([delegate respondsToSelector:
1931 @selector (menu:updateItem:atIndex:shouldCancel:)])
edfda783 1932 {
335f5ae4
JD
1933 int i, len = [delegate numberOfItemsInMenu: svcs];
1934 for (i =0; i<len; i++)
1935 [svcs addItemWithTitle: @"" action: NULL keyEquivalent: @""];
1936 for (i =0; i<len; i++)
1937 if (![delegate menu: svcs
1938 updateItem: (NSMenuItem *)[svcs itemAtIndex: i]
1939 atIndex: i shouldCancel: NO])
1940 break;
edfda783
AR
1941 }
1942 }
1943#endif
1944
1945 [svcs setAutoenablesItems: NO];
1946#ifdef NS_IMPL_COCOA
1947 [svcs update]; /* on OS X, converts from '/' structure */
1948#endif
1949
1950 ret = interpret_services_menu (svcs, Qnil, ret);
1951 return ret;
699c10bd 1952#endif
edfda783
AR
1953}
1954
1955
1956DEFUN ("ns-perform-service", Fns_perform_service, Sns_perform_service,
51d5ef9f
AR
1957 2, 2, 0,
1958 doc: /* Perform Nextstep SERVICE on SEND.
d26fbe1a
CY
1959SEND should be either a string or nil.
1960The return value is the result of the service, as string, or nil if
51d5ef9f 1961there was no result. */)
5842a27b 1962 (Lisp_Object service, Lisp_Object send)
edfda783
AR
1963{
1964 id pb;
1965 NSString *svcName;
1966 char *utfStr;
edfda783
AR
1967
1968 CHECK_STRING (service);
7452b7bd 1969 check_window_system (NULL);
edfda783 1970
0dc8cf50 1971 utfStr = SSDATA (service);
edfda783
AR
1972 svcName = [NSString stringWithUTF8String: utfStr];
1973
1974 pb =[NSPasteboard pasteboardWithUniqueName];
1975 ns_string_to_pasteboard (pb, send);
1976
1977 if (NSPerformService (svcName, pb) == NO)
1978 Fsignal (Qquit, Fcons (build_string ("service not available"), Qnil));
1979
1980 if ([[pb types] count] == 0)
1981 return build_string ("");
1982 return ns_string_from_pasteboard (pb);
1983}
1984
1985
1986DEFUN ("ns-convert-utf8-nfd-to-nfc", Fns_convert_utf8_nfd_to_nfc,
1987 Sns_convert_utf8_nfd_to_nfc, 1, 1, 0,
b066e6b6 1988 doc: /* Return an NFC string that matches the UTF-8 NFD string STR. */)
5842a27b 1989 (Lisp_Object str)
edfda783 1990{
f2f7f42c
AR
1991/* TODO: If GNUstep ever implements precomposedStringWithCanonicalMapping,
1992 remove this. */
edfda783
AR
1993 NSString *utfStr;
1994
1995 CHECK_STRING (str);
0dc8cf50 1996 utfStr = [NSString stringWithUTF8String: SSDATA (str)];
c0342369 1997#ifdef NS_IMPL_COCOA
f2f7f42c 1998 utfStr = [utfStr precomposedStringWithCanonicalMapping];
c0342369 1999#endif
edfda783
AR
2000 return build_string ([utfStr UTF8String]);
2001}
2002
2003
583ff3c3
AR
2004#ifdef NS_IMPL_COCOA
2005
2006/* Compile and execute the AppleScript SCRIPT and return the error
2007 status as function value. A zero is returned if compilation and
2008 execution is successful, in which case *RESULT is set to a Lisp
2009 string or a number containing the resulting script value. Otherwise,
2010 1 is returned. */
2011static int
3d608a86 2012ns_do_applescript (Lisp_Object script, Lisp_Object *result)
583ff3c3
AR
2013{
2014 NSAppleEventDescriptor *desc;
2015 NSDictionary* errorDict;
2016 NSAppleEventDescriptor* returnDescriptor = NULL;
2017
2018 NSAppleScript* scriptObject =
2019 [[NSAppleScript alloc] initWithSource:
0dc8cf50 2020 [NSString stringWithUTF8String: SSDATA (script)]];
583ff3c3
AR
2021
2022 returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
2023 [scriptObject release];
b066e6b6 2024
583ff3c3 2025 *result = Qnil;
b066e6b6 2026
583ff3c3
AR
2027 if (returnDescriptor != NULL)
2028 {
2029 // successful execution
2030 if (kAENullEvent != [returnDescriptor descriptorType])
2031 {
2032 *result = Qt;
2033 // script returned an AppleScript result
2034 if ((typeUnicodeText == [returnDescriptor descriptorType]) ||
335f5ae4 2035#if defined (NS_IMPL_COCOA)
b066e6b6 2036 (typeUTF16ExternalRepresentation
583ff3c3 2037 == [returnDescriptor descriptorType]) ||
a39e2539 2038#endif
583ff3c3
AR
2039 (typeUTF8Text == [returnDescriptor descriptorType]) ||
2040 (typeCString == [returnDescriptor descriptorType]))
2041 {
2042 desc = [returnDescriptor coerceToDescriptorType: typeUTF8Text];
2043 if (desc)
2044 *result = build_string([[desc stringValue] UTF8String]);
2045 }
2046 else
2047 {
2048 /* use typeUTF16ExternalRepresentation? */
2049 // coerce the result to the appropriate ObjC type
2050 desc = [returnDescriptor coerceToDescriptorType: typeUTF8Text];
2051 if (desc)
2052 *result = make_number([desc int32Value]);
2053 }
2054 }
2055 }
2056 else
2057 {
2058 // no script result, return error
2059 return 1;
2060 }
2061 return 0;
2062}
2063
08e3161a
JD
2064/* Helper function called from sendEvent to run applescript
2065 from within the main event loop. */
2066
2067void
2068ns_run_ascript (void)
2069{
cf162aee
JD
2070 if (! NILP (as_script))
2071 as_status = ns_do_applescript (as_script, as_result);
2072 as_script = Qnil;
08e3161a
JD
2073}
2074
583ff3c3 2075DEFUN ("ns-do-applescript", Fns_do_applescript, Sns_do_applescript, 1, 1, 0,
b066e6b6
JB
2076 doc: /* Execute AppleScript SCRIPT and return the result.
2077If compilation and execution are successful, the resulting script value
2078is returned as a string, a number or, in the case of other constructs, t.
2079In case the execution fails, an error is signaled. */)
5842a27b 2080 (Lisp_Object script)
583ff3c3
AR
2081{
2082 Lisp_Object result;
5fdb398c 2083 int status;
08e3161a 2084 NSEvent *nxev;
583ff3c3
AR
2085
2086 CHECK_STRING (script);
7452b7bd 2087 check_window_system (NULL);
583ff3c3 2088
4d7e6e51 2089 block_input ();
08e3161a
JD
2090
2091 as_script = script;
2092 as_result = &result;
2093
2094 /* executing apple script requires the event loop to run, otherwise
2095 errors aren't returned and executeAndReturnError hangs forever.
2096 Post an event that runs applescript and then start the event loop.
2097 The event loop is exited when the script is done. */
2098 nxev = [NSEvent otherEventWithType: NSApplicationDefined
2099 location: NSMakePoint (0, 0)
2100 modifierFlags: 0
2101 timestamp: 0
2102 windowNumber: [[NSApp mainWindow] windowNumber]
2103 context: [NSApp context]
2104 subtype: 0
2105 data1: 0
2106 data2: NSAPP_DATA2_RUNASSCRIPT];
2107
2108 [NSApp postEvent: nxev atStart: NO];
cf162aee
JD
2109
2110 // If there are other events, the event loop may exit. Keep running
677d5c92 2111 // until the script has been handled. */
cf162aee
JD
2112 while (! NILP (as_script))
2113 [NSApp run];
08e3161a
JD
2114
2115 status = as_status;
2116 as_status = 0;
08e3161a 2117 as_result = 0;
4d7e6e51 2118 unblock_input ();
583ff3c3
AR
2119 if (status == 0)
2120 return result;
2121 else if (!STRINGP (result))
2122 error ("AppleScript error %d", status);
2123 else
0dc8cf50 2124 error ("%s", SSDATA (result));
583ff3c3
AR
2125}
2126#endif
2127
2128
2129
edfda783
AR
2130/* ==========================================================================
2131
2132 Miscellaneous functions not called through hooks
2133
2134 ========================================================================== */
2135
3fe53a83 2136/* called from frame.c */
edfda783
AR
2137struct ns_display_info *
2138check_x_display_info (Lisp_Object frame)
2139{
2140 return check_ns_display_info (frame);
2141}
2142
2143
edfda783 2144void
3d608a86 2145x_set_scroll_bar_default_width (struct frame *f)
edfda783
AR
2146{
2147 int wid = FRAME_COLUMN_WIDTH (f);
2148 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = NS_SCROLL_BAR_WIDTH_DEFAULT;
2149 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
2150 wid - 1) / wid;
2151}
2152
2153
c0342369
JD
2154extern const char *x_get_string_resource (XrmDatabase, char *, char *);
2155
2156
3fe53a83 2157/* terms impl this instead of x-get-resource directly */
edfda783
AR
2158const char *
2159x_get_string_resource (XrmDatabase rdb, char *name, char *class)
2160{
6fb5f7da 2161 /* remove appname prefix; TODO: allow for !="Emacs" */
edfda783
AR
2162 char *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
2163 const char *res;
7452b7bd 2164 check_window_system (NULL);
edfda783 2165
386a49d3
AR
2166 if (inhibit_x_resources)
2167 /* --quick was passed, so this is a no-op. */
2168 return NULL;
edfda783 2169
f7dfe5d6 2170 res = ns_get_defaults_value (toCheck);
edfda783 2171 return !res ? NULL :
fee5959d
PE
2172 (!c_strncasecmp (res, "YES", 3) ? "true" :
2173 (!c_strncasecmp (res, "NO", 2) ? "false" : res));
edfda783
AR
2174}
2175
2176
2177Lisp_Object
2178x_get_focus_frame (struct frame *frame)
2179{
2180 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame);
2181 Lisp_Object nsfocus;
2182
9e50ff0c 2183 if (!dpyinfo->x_focus_frame)
edfda783
AR
2184 return Qnil;
2185
9e50ff0c 2186 XSETFRAME (nsfocus, dpyinfo->x_focus_frame);
edfda783
AR
2187 return nsfocus;
2188}
2189
2190
2191int
2192x_pixel_width (struct frame *f)
2193{
2194 return FRAME_PIXEL_WIDTH (f);
2195}
2196
2197
2198int
2199x_pixel_height (struct frame *f)
2200{
2201 return FRAME_PIXEL_HEIGHT (f);
2202}
2203
2204
edfda783 2205void
3d608a86 2206x_sync (struct frame *f)
edfda783
AR
2207{
2208 /* XXX Not implemented XXX */
2209 return;
2210}
2211
2212
2213
2214/* ==========================================================================
2215
2216 Lisp definitions that, for whatever reason, we can't alias as 'ns-XXX'.
2217
2218 ========================================================================== */
2219
2220
952913d4 2221DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
4f4f2973
GM
2222 doc: /* Internal function called by `color-defined-p', which see.
2223\(Note that the Nextstep version of this function ignores FRAME.) */)
5842a27b 2224 (Lisp_Object color, Lisp_Object frame)
edfda783
AR
2225{
2226 NSColor * col;
7452b7bd 2227 check_window_system (NULL);
edfda783
AR
2228 return ns_lisp_to_color (color, &col) ? Qnil : Qt;
2229}
2230
2231
952913d4 2232DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
fb67c21b 2233 doc: /* Internal function called by `color-values', which see. */)
5842a27b 2234 (Lisp_Object color, Lisp_Object frame)
edfda783
AR
2235{
2236 NSColor * col;
c0342369 2237 EmacsCGFloat red, green, blue, alpha;
edfda783 2238
7452b7bd 2239 check_window_system (NULL);
edfda783
AR
2240 CHECK_STRING (color);
2241
2242 if (ns_lisp_to_color (color, &col))
2243 return Qnil;
2244
2245 [[col colorUsingColorSpaceName: NSCalibratedRGBColorSpace]
2246 getRed: &red green: &green blue: &blue alpha: &alpha];
3de717bd
DA
2247 return list3i (lrint (red * 65280), lrint (green * 65280),
2248 lrint (blue * 65280));
edfda783
AR
2249}
2250
2251
2252DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
4f4f2973 2253 doc: /* Internal function called by `display-color-p', which see. */)
91e8418b 2254 (Lisp_Object terminal)
edfda783
AR
2255{
2256 NSWindowDepth depth;
2257 NSString *colorSpace;
a37d34f3 2258
91e8418b
YM
2259 check_ns_display_info (terminal);
2260 depth = [[[NSScreen screens] objectAtIndex:0] depth];
edfda783
AR
2261 colorSpace = NSColorSpaceFromDepth (depth);
2262
2263 return [colorSpace isEqualToString: NSDeviceWhiteColorSpace]
2264 || [colorSpace isEqualToString: NSCalibratedWhiteColorSpace]
2265 ? Qnil : Qt;
2266}
2267
2268
91e8418b
YM
2269DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
2270 0, 1, 0,
51d5ef9f 2271 doc: /* Return t if the Nextstep display supports shades of gray.
d26fbe1a 2272Note that color displays do support shades of gray.
91e8418b
YM
2273The optional argument TERMINAL specifies which display to ask about.
2274TERMINAL should be a terminal object, a frame or a display name (a string).
2275If omitted or nil, that stands for the selected frame's display. */)
2276 (Lisp_Object terminal)
edfda783
AR
2277{
2278 NSWindowDepth depth;
7452b7bd 2279
91e8418b
YM
2280 check_ns_display_info (terminal);
2281 depth = [[[NSScreen screens] objectAtIndex:0] depth];
edfda783
AR
2282
2283 return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil;
2284}
2285
2286
952913d4 2287DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
edfda783 2288 0, 1, 0,
91e8418b
YM
2289 doc: /* Return the width in pixels of the Nextstep display TERMINAL.
2290The optional argument TERMINAL specifies which display to ask about.
2291TERMINAL should be a terminal object, a frame or a display name (a string).
2292If omitted or nil, that stands for the selected frame's display.
2293
2294On \"multi-monitor\" setups this refers to the pixel width for all
2295physical monitors associated with TERMINAL. To get information for
2296each physical monitor, use `display-monitor-attributes-list'. */)
2297 (Lisp_Object terminal)
edfda783 2298{
91e8418b
YM
2299 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2300
2301 return make_number (x_display_pixel_width (dpyinfo));
edfda783
AR
2302}
2303
2304
952913d4
DN
2305DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2306 Sx_display_pixel_height, 0, 1, 0,
91e8418b
YM
2307 doc: /* Return the height in pixels of the Nextstep display TERMINAL.
2308The optional argument TERMINAL specifies which display to ask about.
2309TERMINAL should be a terminal object, a frame or a display name (a string).
2310If omitted or nil, that stands for the selected frame's display.
2311
2312On \"multi-monitor\" setups this refers to the pixel height for all
2313physical monitors associated with TERMINAL. To get information for
2314each physical monitor, use `display-monitor-attributes-list'. */)
2315 (Lisp_Object terminal)
edfda783 2316{
91e8418b
YM
2317 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2318
2319 return make_number (x_display_pixel_height (dpyinfo));
edfda783
AR
2320}
2321
4465bfb4
JD
2322#ifdef NS_IMPL_COCOA
2323/* Returns the name for the screen that DICT came from, or NULL.
2324 Caller must free return value.
2325*/
583ff3c3 2326
6799bb26 2327static char *
4465bfb4
JD
2328ns_screen_name (CGDirectDisplayID did)
2329{
2330 char *name = NULL;
2331 NSDictionary *info = (NSDictionary *)
2332 IODisplayCreateInfoDictionary (CGDisplayIOServicePort (did),
2333 kIODisplayOnlyPreferredName);
2334 NSDictionary *names
2335 = [info objectForKey:
2336 [NSString stringWithUTF8String:kDisplayProductName]];
2337
2338 if ([names count] > 0) {
2339 NSString *n = [names objectForKey: [[names allKeys] objectAtIndex:0]];
2340 if (n != nil)
2341 name = xstrdup ([n UTF8String]);
2342 }
d26fbe1a 2343
4465bfb4
JD
2344 [info release];
2345 return name;
2346}
2347#endif
2348
2349static Lisp_Object
2350ns_make_monitor_attribute_list (struct MonitorInfo *monitors,
2351 int n_monitors,
2352 int primary_monitor,
2353 const char *source)
2354{
2355 Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
6799bb26 2356 Lisp_Object frame, rest;
4465bfb4
JD
2357 NSArray *screens = [NSScreen screens];
2358 int i;
2359
2360 FOR_EACH_FRAME (rest, frame)
2361 {
2362 struct frame *f = XFRAME (frame);
2363
2364 if (FRAME_NS_P (f))
2365 {
2366 NSView *view = FRAME_NS_VIEW (f);
2367 NSScreen *screen = [[view window] screen];
2368 NSUInteger k;
2369
2370 i = -1;
2371 for (k = 0; i == -1 && k < [screens count]; ++k)
2372 {
2373 if ([screens objectAtIndex: k] == screen)
2374 i = (int)k;
2375 }
2376
2377 if (i > -1)
2378 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
2379 }
2380 }
2381
6799bb26
JD
2382 return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
2383 monitor_frames, source);
4465bfb4
JD
2384}
2385
2386DEFUN ("ns-display-monitor-attributes-list",
2387 Fns_display_monitor_attributes_list,
2388 Sns_display_monitor_attributes_list,
2389 0, 1, 0,
2390 doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
2391
2392The optional argument TERMINAL specifies which display to ask about.
2393TERMINAL should be a terminal object, a frame or a display name (a string).
2394If omitted or nil, that stands for the selected frame's display.
2395
2396In addition to the standard attribute keys listed in
2397`display-monitor-attributes-list', the following keys are contained in
2398the attributes:
2399
2400 source -- String describing the source from which multi-monitor
2401 information is obtained, \"NS\" is always the source."
2402
2403Internal use only, use `display-monitor-attributes-list' instead. */)
2404 (Lisp_Object terminal)
edfda783 2405{
4465bfb4
JD
2406 struct terminal *term = get_terminal (terminal, 1);
2407 NSArray *screens;
2408 NSUInteger i, n_monitors;
2409 struct MonitorInfo *monitors;
2410 Lisp_Object attributes_list = Qnil;
2411 CGFloat primary_display_height = 0;
edfda783 2412
4465bfb4
JD
2413 if (term->type != output_ns)
2414 return Qnil;
2415
2416 screens = [NSScreen screens];
2417 n_monitors = [screens count];
2418 if (n_monitors == 0)
474217c8
CY
2419 return Qnil;
2420
4465bfb4
JD
2421 monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
2422
2423 for (i = 0; i < [screens count]; ++i)
2424 {
2425 NSScreen *s = [screens objectAtIndex:i];
2426 struct MonitorInfo *m = &monitors[i];
2427 NSRect fr = [s frame];
2428 NSRect vfr = [s visibleFrame];
4465bfb4
JD
2429 short y, vy;
2430
2431#ifdef NS_IMPL_COCOA
c0342369 2432 NSDictionary *dict = [s deviceDescription];
4465bfb4
JD
2433 NSNumber *nid = [dict objectForKey:@"NSScreenNumber"];
2434 CGDirectDisplayID did = [nid unsignedIntValue];
2435#endif
2436 if (i == 0)
2437 {
2438 primary_display_height = fr.size.height;
2439 y = (short) fr.origin.y;
2440 vy = (short) vfr.origin.y;
2441 }
2442 else
2443 {
2444 // Flip y coordinate as NS has y starting from the bottom.
2445 y = (short) (primary_display_height - fr.size.height - fr.origin.y);
2446 vy = (short) (primary_display_height -
2447 vfr.size.height - vfr.origin.y);
2448 }
2449
2450 m->geom.x = (short) fr.origin.x;
2451 m->geom.y = y;
2452 m->geom.width = (unsigned short) fr.size.width;
2453 m->geom.height = (unsigned short) fr.size.height;
2454
2455 m->work.x = (short) vfr.origin.x;
2456 // y is flipped on NS, so vy - y are pixels missing at the bottom,
2457 // and fr.size.height - vfr.size.height are pixels missing in total.
2458 // Pixels missing at top are
2459 // fr.size.height - vfr.size.height - vy + y.
2460 // work.y is then pixels missing at top + y.
2461 m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y;
2462 m->work.width = (unsigned short) vfr.size.width;
2463 m->work.height = (unsigned short) vfr.size.height;
2464
2465#ifdef NS_IMPL_COCOA
2466 m->name = ns_screen_name (did);
2467
2468 {
2469 CGSize mms = CGDisplayScreenSize (did);
2470 m->mm_width = (int) mms.width;
2471 m->mm_height = (int) mms.height;
2472 }
2473
2474#else
2475 // Assume 92 dpi as x-display-mm-height/x-display-mm-width does.
2476 m->mm_width = (int) (25.4 * fr.size.width / 92.0);
2477 m->mm_height = (int) (25.4 * fr.size.height / 92.0);
2478#endif
2479 }
2480
2481 // Primary monitor is always first for NS.
2482 attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors,
2483 0, "NS");
edfda783 2484
4465bfb4
JD
2485 free_monitors (monitors, n_monitors);
2486 return attributes_list;
edfda783
AR
2487}
2488
2489
952913d4 2490DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
edfda783 2491 0, 1, 0,
91e8418b
YM
2492 doc: /* Return the number of bitplanes of the Nextstep display TERMINAL.
2493The optional argument TERMINAL specifies which display to ask about.
2494TERMINAL should be a terminal object, a frame or a display name (a string).
51d5ef9f 2495If omitted or nil, that stands for the selected frame's display. */)
91e8418b 2496 (Lisp_Object terminal)
edfda783 2497{
91e8418b 2498 check_ns_display_info (terminal);
edfda783 2499 return make_number
91e8418b 2500 (NSBitsPerPixelFromDepth ([[[NSScreen screens] objectAtIndex:0] depth]));
edfda783
AR
2501}
2502
2503
91e8418b
YM
2504DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2505 0, 1, 0,
2506 doc: /* Returns the number of color cells of the Nextstep display TERMINAL.
2507The optional argument TERMINAL specifies which display to ask about.
2508TERMINAL should be a terminal object, a frame or a display name (a string).
51d5ef9f 2509If omitted or nil, that stands for the selected frame's display. */)
91e8418b 2510 (Lisp_Object terminal)
edfda783 2511{
91e8418b 2512 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
edfda783
AR
2513 /* We force 24+ bit depths to 24-bit to prevent an overflow. */
2514 return make_number (1 << min (dpyinfo->n_planes, 24));
2515}
2516
2517
2518/* Unused dummy def needed for compatibility. */
2519Lisp_Object tip_frame;
2520
6fb5f7da 2521/* TODO: move to xdisp or similar */
edfda783 2522static void
3d608a86
J
2523compute_tip_xy (struct frame *f,
2524 Lisp_Object parms,
2525 Lisp_Object dx,
2526 Lisp_Object dy,
2527 int width,
2528 int height,
2529 int *root_x,
2530 int *root_y)
edfda783
AR
2531{
2532 Lisp_Object left, top;
2533 EmacsView *view = FRAME_NS_VIEW (f);
2534 NSPoint pt;
b066e6b6 2535
edfda783
AR
2536 /* Start with user-specified or mouse position. */
2537 left = Fcdr (Fassq (Qleft, parms));
edfda783 2538 top = Fcdr (Fassq (Qtop, parms));
edfda783 2539
7a18115b
J
2540 if (!INTEGERP (left) || !INTEGERP (top))
2541 {
2542 pt = last_mouse_motion_position;
2543 /* Convert to screen coordinates */
2544 pt = [view convertPoint: pt toView: nil];
2545 pt = [[view window] convertBaseToScreen: pt];
2546 }
2547 else
2548 {
2549 /* Absolute coordinates. */
2550 pt.x = XINT (left);
2551 pt.y = x_display_pixel_height (FRAME_NS_DISPLAY_INFO (f)) - XINT (top)
2552 - height;
2553 }
5fdb398c 2554
edfda783 2555 /* Ensure in bounds. (Note, screen origin = lower left.) */
7a18115b
J
2556 if (INTEGERP (left))
2557 *root_x = pt.x;
2558 else if (pt.x + XINT (dx) <= 0)
edfda783 2559 *root_x = 0; /* Can happen for negative dx */
889bd438
CY
2560 else if (pt.x + XINT (dx) + width
2561 <= x_display_pixel_width (FRAME_NS_DISPLAY_INFO (f)))
edfda783
AR
2562 /* It fits to the right of the pointer. */
2563 *root_x = pt.x + XINT (dx);
2564 else if (width + XINT (dx) <= pt.x)
2565 /* It fits to the left of the pointer. */
2566 *root_x = pt.x - width - XINT (dx);
2567 else
2568 /* Put it left justified on the screen -- it ought to fit that way. */
2569 *root_x = 0;
2570
7a18115b
J
2571 if (INTEGERP (top))
2572 *root_y = pt.y;
2573 else if (pt.y - XINT (dy) - height >= 0)
edfda783
AR
2574 /* It fits below the pointer. */
2575 *root_y = pt.y - height - XINT (dy);
889bd438
CY
2576 else if (pt.y + XINT (dy) + height
2577 <= x_display_pixel_height (FRAME_NS_DISPLAY_INFO (f)))
edfda783
AR
2578 /* It fits above the pointer */
2579 *root_y = pt.y + XINT (dy);
2580 else
2581 /* Put it on the top. */
889bd438 2582 *root_y = x_display_pixel_height (FRAME_NS_DISPLAY_INFO (f)) - height;
edfda783
AR
2583}
2584
2585
2586DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
b066e6b6 2587 doc: /* Show STRING in a \"tooltip\" window on frame FRAME.
edfda783
AR
2588A tooltip window is a small window displaying a string.
2589
4f4f2973
GM
2590This is an internal function; Lisp code should call `tooltip-show'.
2591
edfda783
AR
2592FRAME nil or omitted means use the selected frame.
2593
2594PARMS is an optional list of frame parameters which can be used to
2595change the tooltip's appearance.
2596
2597Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
2598means use the default timeout of 5 seconds.
2599
2600If the list of frame parameters PARMS contains a `left' parameter,
2601the tooltip is displayed at that x-position. Otherwise it is
2602displayed at the mouse position, with offset DX added (default is 5 if
2603DX isn't specified). Likewise for the y-position; if a `top' frame
2604parameter is specified, it determines the y-position of the tooltip
2605window, otherwise it is displayed at the mouse position, with offset
2606DY added (default is -10).
2607
2608A tooltip's maximum size is specified by `x-max-tooltip-size'.
2609Text larger than the specified size is clipped. */)
5842a27b 2610 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
edfda783
AR
2611{
2612 int root_x, root_y;
2613 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
d311d28c 2614 ptrdiff_t count = SPECPDL_INDEX ();
edfda783
AR
2615 struct frame *f;
2616 char *str;
2617 NSSize size;
2618
2619 specbind (Qinhibit_redisplay, Qt);
2620
2621 GCPRO4 (string, parms, frame, timeout);
2622
2623 CHECK_STRING (string);
0dc8cf50 2624 str = SSDATA (string);
7452b7bd 2625 f = decode_window_system_frame (frame);
edfda783
AR
2626 if (NILP (timeout))
2627 timeout = make_number (5);
2628 else
2629 CHECK_NATNUM (timeout);
2630
2631 if (NILP (dx))
2632 dx = make_number (5);
2633 else
2634 CHECK_NUMBER (dx);
2635
2636 if (NILP (dy))
2637 dy = make_number (-10);
2638 else
2639 CHECK_NUMBER (dy);
2640
4d7e6e51 2641 block_input ();
edfda783
AR
2642 if (ns_tooltip == nil)
2643 ns_tooltip = [[EmacsTooltip alloc] init];
2644 else
2645 Fx_hide_tip ();
2646
2647 [ns_tooltip setText: str];
2648 size = [ns_tooltip frame].size;
2649
2650 /* Move the tooltip window where the mouse pointer is. Resize and
2651 show it. */
2652 compute_tip_xy (f, parms, dx, dy, (int)size.width, (int)size.height,
2653 &root_x, &root_y);
2654
2655 [ns_tooltip showAtX: root_x Y: root_y for: XINT (timeout)];
4d7e6e51 2656 unblock_input ();
edfda783
AR
2657
2658 UNGCPRO;
2659 return unbind_to (count, Qnil);
2660}
2661
2662
2663DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
2664 doc: /* Hide the current tooltip window, if there is any.
2665Value is t if tooltip was open, nil otherwise. */)
5842a27b 2666 (void)
edfda783
AR
2667{
2668 if (ns_tooltip == nil || ![ns_tooltip isActive])
2669 return Qnil;
2670 [ns_tooltip hide];
2671 return Qt;
2672}
2673
2674
cc98b6a0
DN
2675/* ==========================================================================
2676
2677 Class implementations
2678
2679 ========================================================================== */
2680
edbdcec0
JD
2681/*
2682 Handle arrow/function/control keys and copy/paste/cut in file dialogs.
a37d34f3 2683 Return YES if handled, NO if not.
edbdcec0
JD
2684 */
2685static BOOL
2686handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent)
2687{
2688 NSString *s;
2689 int i;
2690 BOOL ret = NO;
2691
2692 if ([theEvent type] != NSKeyDown) return NO;
2693 s = [theEvent characters];
2694
2695 for (i = 0; i < [s length]; ++i)
2696 {
2697 int ch = (int) [s characterAtIndex: i];
2698 switch (ch)
2699 {
2700 case NSHomeFunctionKey:
2701 case NSDownArrowFunctionKey:
2702 case NSUpArrowFunctionKey:
2703 case NSLeftArrowFunctionKey:
2704 case NSRightArrowFunctionKey:
2705 case NSPageUpFunctionKey:
2706 case NSPageDownFunctionKey:
2707 case NSEndFunctionKey:
2708 [panel sendEvent: theEvent];
2709 ret = YES;
2710 break;
2711 /* As we don't have the standard key commands for
2712 copy/paste/cut/select-all in our edit menu, we must handle
2713 them here. TODO: handle Emacs key bindings for copy/cut/select-all
2714 here, paste works, because we have that in our Edit menu.
2715 I.e. refactor out code in nsterm.m, keyDown: to figure out the
2716 correct modifier.
2717 */
2718 case 'x': // Cut
2719 case 'c': // Copy
2720 case 'v': // Paste
2721 case 'a': // Select all
2722 if ([theEvent modifierFlags] & NSCommandKeyMask)
2723 {
2724 [NSApp sendAction:
2725 (ch == 'x'
2726 ? @selector(cut:)
2727 : (ch == 'c'
2728 ? @selector(copy:)
2729 : (ch == 'v'
2730 ? @selector(paste:)
2731 : @selector(selectAll:))))
2732 to:nil from:panel];
2733 ret = YES;
2734 }
2735 default:
2736 // Send all control keys, as the text field supports C-a, C-f, C-e
2737 // C-b and more.
2738 if ([theEvent modifierFlags] & NSControlKeyMask)
2739 {
2740 [panel sendEvent: theEvent];
2741 ret = YES;
2742 }
2743 break;
2744 }
2745 }
2746
2747
2748 return ret;
2749}
cc98b6a0
DN
2750
2751@implementation EmacsSavePanel
2752#ifdef NS_IMPL_COCOA
2753/* --------------------------------------------------------------------------
2754 These are overridden to intercept on OS X: ending panel restarts NSApp
2755 event loop if it is stopped. Not sure if this is correct behavior,
2756 perhaps should check if running and if so send an appdefined.
2757 -------------------------------------------------------------------------- */
2758- (void) ok: (id)sender
2759{
2760 [super ok: sender];
2761 panelOK = 1;
2762 [NSApp stop: self];
2763}
2764- (void) cancel: (id)sender
2765{
2766 [super cancel: sender];
2767 [NSApp stop: self];
2768}
2769#endif
edbdcec0
JD
2770
2771- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
2772{
2773 BOOL ret = handlePanelKeys (self, theEvent);
2774 if (! ret)
2775 ret = [super performKeyEquivalent:theEvent];
2776 return ret;
2777}
cc98b6a0
DN
2778@end
2779
2780
2781@implementation EmacsOpenPanel
2782#ifdef NS_IMPL_COCOA
2783/* --------------------------------------------------------------------------
2784 These are overridden to intercept on OS X: ending panel restarts NSApp
2785 event loop if it is stopped. Not sure if this is correct behavior,
2786 perhaps should check if running and if so send an appdefined.
2787 -------------------------------------------------------------------------- */
2788- (void) ok: (id)sender
2789{
2790 [super ok: sender];
8f2906f5
JD
2791
2792 // If not choosing directories, and Open is pressed on a directory, return.
c0342369
JD
2793 if (! [self canChooseDirectories] && ns_directory_from_panel (self) &&
2794 ! ns_filename_from_panel (self))
8f2906f5
JD
2795 return;
2796
cc98b6a0
DN
2797 panelOK = 1;
2798 [NSApp stop: self];
2799}
2800- (void) cancel: (id)sender
2801{
2802 [super cancel: sender];
2803 [NSApp stop: self];
2804}
8f2906f5 2805
cc98b6a0 2806#endif
edbdcec0
JD
2807- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
2808{
2809 // NSOpenPanel inherits NSSavePanel, so passing self is OK.
2810 BOOL ret = handlePanelKeys (self, theEvent);
2811 if (! ret)
2812 ret = [super performKeyEquivalent:theEvent];
2813 return ret;
2814}
cc98b6a0
DN
2815@end
2816
2817
2818@implementation EmacsFileDelegate
2819/* --------------------------------------------------------------------------
2820 Delegate methods for Open/Save panels
2821 -------------------------------------------------------------------------- */
2822- (BOOL)panel: (id)sender isValidFilename: (NSString *)filename
2823{
2824 return YES;
2825}
2826- (BOOL)panel: (id)sender shouldShowFilename: (NSString *)filename
2827{
2828 return YES;
2829}
2830- (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
2831 confirmed: (BOOL)okFlag
2832{
2833 return filename;
2834}
2835@end
2836
2837#endif
2838
ba301db3 2839
edfda783
AR
2840/* ==========================================================================
2841
2842 Lisp interface declaration
2843
2844 ========================================================================== */
2845
2846
2847void
3d608a86 2848syms_of_nsfns (void)
edfda783 2849{
088dcc3e 2850 Qfontsize = intern_c_string ("fontsize");
edfda783
AR
2851 staticpro (&Qfontsize);
2852
fb9d0f5a 2853 DEFVAR_LISP ("ns-icon-type-alist", Vns_icon_type_alist,
51d5ef9f 2854 doc: /* Alist of elements (REGEXP . IMAGE) for images of icons associated to frames.
d26fbe1a
CY
2855If the title of a frame matches REGEXP, then IMAGE.tiff is
2856selected as the image of the icon representing the frame when it's
2857miniaturized. If an element is t, then Emacs tries to select an icon
2858based on the filetype of the visited file.
2859
2860The images have to be installed in a folder called English.lproj in the
2861Emacs folder. You have to restart Emacs after installing new icons.
2862
2863Example: Install an icon Gnus.tiff and execute the following code
2864
2865 (setq ns-icon-type-alist
2866 (append ns-icon-type-alist
2867 '((\"^\\\\*\\\\(Group\\\\*$\\\\|Summary \\\\|Article\\\\*$\\\\)\"
2868 . \"Gnus\"))))
2869
2870When you miniaturize a Group, Summary or Article frame, Gnus.tiff will
51d5ef9f 2871be used as the image of the icon representing the frame. */);
edfda783
AR
2872 Vns_icon_type_alist = Fcons (Qt, Qnil);
2873
fb9d0f5a 2874 DEFVAR_LISP ("ns-version-string", Vns_version_string,
cb83c00b 2875 doc: /* Toolkit version for NS Windowing. */);
f5497e45 2876 Vns_version_string = ns_appkit_version_str ();
cb83c00b 2877
edfda783
AR
2878 defsubr (&Sns_read_file_name);
2879 defsubr (&Sns_get_resource);
2880 defsubr (&Sns_set_resource);
2881 defsubr (&Sxw_display_color_p); /* this and next called directly by C code */
2882 defsubr (&Sx_display_grayscale_p);
edfda783
AR
2883 defsubr (&Sns_font_name);
2884 defsubr (&Sns_list_colors);
74876614 2885#ifdef NS_IMPL_COCOA
583ff3c3 2886 defsubr (&Sns_do_applescript);
74876614 2887#endif
952913d4
DN
2888 defsubr (&Sxw_color_defined_p);
2889 defsubr (&Sxw_color_values);
2890 defsubr (&Sx_server_max_request_size);
9e50ff0c
DN
2891 defsubr (&Sx_server_vendor);
2892 defsubr (&Sx_server_version);
952913d4
DN
2893 defsubr (&Sx_display_pixel_width);
2894 defsubr (&Sx_display_pixel_height);
4465bfb4 2895 defsubr (&Sns_display_monitor_attributes_list);
9e50ff0c
DN
2896 defsubr (&Sx_display_mm_width);
2897 defsubr (&Sx_display_mm_height);
2898 defsubr (&Sx_display_screens);
952913d4
DN
2899 defsubr (&Sx_display_planes);
2900 defsubr (&Sx_display_color_cells);
9e50ff0c
DN
2901 defsubr (&Sx_display_visual_class);
2902 defsubr (&Sx_display_backing_store);
2903 defsubr (&Sx_display_save_under);
2904 defsubr (&Sx_create_frame);
9e50ff0c
DN
2905 defsubr (&Sx_open_connection);
2906 defsubr (&Sx_close_connection);
2907 defsubr (&Sx_display_list);
edfda783
AR
2908
2909 defsubr (&Sns_hide_others);
2910 defsubr (&Sns_hide_emacs);
2911 defsubr (&Sns_emacs_info_panel);
2912 defsubr (&Sns_list_services);
2913 defsubr (&Sns_perform_service);
2914 defsubr (&Sns_convert_utf8_nfd_to_nfc);
9e50ff0c 2915 defsubr (&Sx_focus_frame);
edfda783
AR
2916 defsubr (&Sns_popup_font_panel);
2917 defsubr (&Sns_popup_color_panel);
2918
2919 defsubr (&Sx_show_tip);
2920 defsubr (&Sx_hide_tip);
2921
08e3161a
JD
2922 as_status = 0;
2923 as_script = Qnil;
2924 as_result = 0;
edfda783 2925}