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