1 /* Functions for the NeXT/Open/GNUstep and macOS window system.
3 Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2018 Free Software
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or (at
11 your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
22 Originally by Carl Edman
23 Updated by Christian Limpach (chris@nice.ch)
24 OpenStep/Rhapsody port by Scott Bender (sbender@harmony-ds.com)
25 macOS/Aqua port by Christophe de Dinechin (descubes@earthlink.net)
26 GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
29 /* This should be the first include, as it may set up #defines affecting
30 interpretation of even the system includes. */
34 #include <c-strcase.h>
37 #include "blockinput.h"
40 #include "character.h"
43 #include "termhooks.h"
48 #include <IOKit/graphics/IOGraphicsLib.h>
55 static EmacsTooltip *ns_tooltip = nil;
57 /* Static variables to handle AppleScript execution. */
58 static Lisp_Object as_script, *as_result;
61 static ptrdiff_t image_cache_refcount;
63 static struct ns_display_info *ns_display_info_for_name (Lisp_Object);
65 /* ==========================================================================
67 Internal utility functions
69 ========================================================================== */
71 /* Let the user specify a Nextstep display with a Lisp object.
72 OBJECT may be nil, a frame or a terminal object.
73 nil stands for the selected frame--or, if that is not a Nextstep frame,
74 the first Nextstep display on the list. */
76 static struct ns_display_info *
77 check_ns_display_info (Lisp_Object object)
79 struct ns_display_info *dpyinfo = NULL;
83 struct frame *sf = XFRAME (selected_frame);
85 if (FRAME_NS_P (sf) && FRAME_LIVE_P (sf))
86 dpyinfo = FRAME_DISPLAY_INFO (sf);
87 else if (x_display_list != 0)
88 dpyinfo = x_display_list;
90 error ("Nextstep windows are not in use or not initialized");
92 else if (TERMINALP (object))
94 struct terminal *t = decode_live_terminal (object);
96 if (t->type != output_ns)
97 error ("Terminal %d is not a Nextstep display", t->id);
99 dpyinfo = t->display_info.ns;
101 else if (STRINGP (object))
102 dpyinfo = ns_display_info_for_name (object);
105 struct frame *f = decode_window_system_frame (object);
106 dpyinfo = FRAME_DISPLAY_INFO (f);
114 ns_get_window (Lisp_Object maybeFrame)
116 id view =nil, window =nil;
118 if (!FRAMEP (maybeFrame) || !FRAME_NS_P (XFRAME (maybeFrame)))
119 maybeFrame = selected_frame; /* wrong_type_argument (Qframep, maybeFrame); */
121 if (!NILP (maybeFrame))
122 view = FRAME_NS_VIEW (XFRAME (maybeFrame));
123 if (view) window =[view window];
129 /* Return the X display structure for the display named NAME.
130 Open a new connection if necessary. */
131 static struct ns_display_info *
132 ns_display_info_for_name (Lisp_Object name)
134 struct ns_display_info *dpyinfo;
138 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
139 if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
142 error ("Emacs for Nextstep does not yet support multi-display");
144 Fx_open_connection (name, Qnil, Qnil);
145 dpyinfo = x_display_list;
148 error ("Display on %s not responding.\n", SDATA (name));
154 ns_filename_from_panel (NSSavePanel *panel)
157 NSURL *url = [panel URL];
158 NSString *str = [url path];
161 return [panel filename];
166 ns_directory_from_panel (NSSavePanel *panel)
169 NSURL *url = [panel directoryURL];
170 NSString *str = [url path];
173 return [panel directory];
177 #ifndef NS_IMPL_COCOA
179 interpret_services_menu (NSMenu *menu, Lisp_Object prefix, Lisp_Object old)
180 /* --------------------------------------------------------------------------
181 Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
182 -------------------------------------------------------------------------- */
192 count = [menu numberOfItems];
193 for (i = 0; i<count; i++)
195 item = [menu itemAtIndex: i];
196 name = [[item title] UTF8String];
199 nameStr = build_string (name);
201 if ([item hasSubmenu])
203 old = interpret_services_menu ([item submenu],
204 Fcons (nameStr, prefix), old);
208 keys = [item keyEquivalent];
209 if (keys && [keys length] )
211 key = [keys characterAtIndex: 0];
212 res = make_number (key|super_modifier);
218 old = Fcons (Fcons (res,
219 Freverse (Fcons (nameStr,
229 /* ==========================================================================
231 Frame parameter setters
233 ========================================================================== */
237 x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
240 EmacsCGFloat r, g, b, alpha;
242 /* Must block_input, because ns_lisp_to_color does block/unblock_input
243 which means that col may be deallocated in its unblock_input if there
244 is user input, unless we also block_input. */
246 if (ns_lisp_to_color (arg, &col))
248 store_frame_param (f, Qforeground_color, oldval);
250 error ("Unknown color");
254 [f->output_data.ns->foreground_color release];
255 f->output_data.ns->foreground_color = col;
257 [col getRed: &r green: &g blue: &b alpha: &alpha];
258 FRAME_FOREGROUND_PIXEL (f) =
259 ARGB_TO_ULONG ((int)(alpha*0xff), (int)(r*0xff), (int)(g*0xff), (int)(b*0xff));
261 if (FRAME_NS_VIEW (f))
263 update_face_from_frame_parameter (f, Qforeground_color, arg);
264 /* recompute_basic_faces (f); */
265 if (FRAME_VISIBLE_P (f))
266 SET_FRAME_GARBAGED (f);
273 x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
277 NSView *view = FRAME_NS_VIEW (f);
278 EmacsCGFloat r, g, b, alpha;
281 if (ns_lisp_to_color (arg, &col))
283 store_frame_param (f, Qbackground_color, oldval);
285 error ("Unknown color");
288 /* Clear the frame; in some instances the NS-internal GC appears not
289 to update, or it does update and cannot clear old text
291 if (FRAME_VISIBLE_P (f))
295 [f->output_data.ns->background_color release];
296 f->output_data.ns->background_color = col;
298 [col getRed: &r green: &g blue: &b alpha: &alpha];
299 FRAME_BACKGROUND_PIXEL (f) =
300 ARGB_TO_ULONG ((int)(alpha*0xff), (int)(r*0xff), (int)(g*0xff), (int)(b*0xff));
304 [[view window] setBackgroundColor: col];
306 if (alpha != (EmacsCGFloat) 1.0)
307 [[view window] setOpaque: NO];
309 [[view window] setOpaque: YES];
311 face = FRAME_DEFAULT_FACE (f);
314 col = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f);
315 face->background = ns_index_color
316 ([col colorWithAlphaComponent: alpha], f);
318 update_face_from_frame_parameter (f, Qbackground_color, arg);
321 if (FRAME_VISIBLE_P (f))
322 SET_FRAME_GARBAGED (f);
329 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
334 if (ns_lisp_to_color (arg, &col))
336 store_frame_param (f, Qcursor_color, oldval);
338 error ("Unknown color");
341 [FRAME_CURSOR_COLOR (f) release];
342 FRAME_CURSOR_COLOR (f) = [col retain];
344 if (FRAME_VISIBLE_P (f))
346 x_update_cursor (f, 0);
347 x_update_cursor (f, 1);
349 update_face_from_frame_parameter (f, Qcursor_color, arg);
355 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
357 NSView *view = FRAME_NS_VIEW (f);
358 NSTRACE ("x_set_icon_name");
360 /* See if it's changed. */
363 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
366 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
369 fset_icon_name (f, arg);
373 if (!NILP (f->title))
376 /* Explicit name and no icon-name -> explicit_name. */
377 if (f->explicit_name)
381 /* No explicit name and no icon-name ->
382 name has to be rebuild from icon_title_format. */
383 windows_or_buffers_changed = 62;
388 /* Don't change the name if it's already NAME. */
389 if ([[view window] miniwindowTitle]
390 && ([[[view window] miniwindowTitle]
391 isEqualToString: [NSString stringWithUTF8String:
395 [[view window] setMiniwindowTitle:
396 [NSString stringWithUTF8String: SSDATA (arg)]];
400 ns_set_name_internal (struct frame *f, Lisp_Object name)
402 Lisp_Object encoded_name, encoded_icon_name;
404 NSView *view = FRAME_NS_VIEW (f);
407 encoded_name = ENCODE_UTF_8 (name);
409 str = [NSString stringWithUTF8String: SSDATA (encoded_name)];
412 /* Don't change the name if it's already NAME. */
413 if (! [[[view window] title] isEqualToString: str])
414 [[view window] setTitle: str];
416 if (!STRINGP (f->icon_name))
417 encoded_icon_name = encoded_name;
419 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
421 str = [NSString stringWithUTF8String: SSDATA (encoded_icon_name)];
423 if ([[view window] miniwindowTitle]
424 && ! [[[view window] miniwindowTitle] isEqualToString: str])
425 [[view window] setMiniwindowTitle: str];
430 ns_set_name (struct frame *f, Lisp_Object name, int explicit)
432 NSTRACE ("ns_set_name");
434 /* Make sure that requests from lisp code override requests from
435 Emacs redisplay code. */
438 /* If we're switching from explicit to implicit, we had better
439 update the mode lines and thereby update the title. */
440 if (f->explicit_name && NILP (name))
441 update_mode_lines = 21;
443 f->explicit_name = ! NILP (name);
445 else if (f->explicit_name)
449 name = build_string ([ns_app_name UTF8String]);
453 /* Don't change the name if it's already NAME. */
454 if (! NILP (Fstring_equal (name, f->name)))
459 /* Title overrides explicit name. */
460 if (! NILP (f->title))
463 ns_set_name_internal (f, name);
467 /* This function should be called when the user's lisp code has
468 specified a name for the frame; the name will override any set by the
471 x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
473 NSTRACE ("x_explicitly_set_name");
474 ns_set_name (f, arg, 1);
478 /* This function should be called by Emacs redisplay code to set the
479 name; names set this way will never override names set by the user's
482 x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
484 NSTRACE ("x_implicitly_set_name");
486 if (ns_use_proxy_icon)
487 ns_set_represented_filename (f);
489 ns_set_name (f, arg, 0);
493 /* Change the title of frame F to NAME.
494 If NAME is nil, use the frame name as the title. */
497 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
499 NSTRACE ("x_set_title");
500 /* Don't change the title if it's already NAME. */
501 if (EQ (name, f->title))
504 update_mode_lines = 22;
506 fset_title (f, name);
513 ns_set_name_internal (f, name);
517 ns_set_doc_edited (void)
519 NSAutoreleasePool *pool;
520 Lisp_Object tail, frame;
522 pool = [[NSAutoreleasePool alloc] init];
523 FOR_EACH_FRAME (tail, frame)
526 struct frame *f = XFRAME (frame);
530 if (! FRAME_NS_P (f)) continue;
531 w = XWINDOW (FRAME_SELECTED_WINDOW (f));
532 view = FRAME_NS_VIEW (f);
533 if (!MINI_WINDOW_P (w))
534 edited = ! NILP (Fbuffer_modified_p (w->contents)) &&
535 ! NILP (Fbuffer_file_name (w->contents));
536 [[view window] setDocumentEdited: edited];
545 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
548 if (FRAME_MINIBUF_ONLY_P (f))
551 if (TYPE_RANGED_INTEGERP (int, value))
552 nlines = XINT (value);
556 FRAME_MENU_BAR_LINES (f) = 0;
559 FRAME_EXTERNAL_MENU_BAR (f) = 1;
560 /* Does for all frames, whereas we just want for one frame
561 [NSMenu setMenuBarVisible: YES]; */
565 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
566 free_frame_menubar (f);
567 /* [NSMenu setMenuBarVisible: NO]; */
568 FRAME_EXTERNAL_MENU_BAR (f) = 0;
573 /* toolbar support */
575 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
577 /* Currently, when the tool bar changes state, the frame is resized.
579 TODO: It would be better if this didn't occur when 1) the frame
580 is full height or maximized or 2) when specified by
581 `frame-inhibit-implied-resize'. */
584 NSTRACE ("x_set_tool_bar_lines");
586 if (FRAME_MINIBUF_ONLY_P (f))
589 if (RANGED_INTEGERP (0, value, INT_MAX))
590 nlines = XFASTINT (value);
596 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
597 update_frame_tool_bar (f);
601 if (FRAME_EXTERNAL_TOOL_BAR (f))
603 free_frame_tool_bar (f);
604 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
607 EmacsView *view = FRAME_NS_VIEW (f);
608 int fs_state = [view fullscreenState];
610 if (fs_state == FULLSCREEN_MAXIMIZED)
612 [view setFSValue:FULLSCREEN_WIDTH];
614 else if (fs_state == FULLSCREEN_HEIGHT)
616 [view setFSValue:FULLSCREEN_NONE];
624 = ((f->after_make_frame
625 && !f->tool_bar_resized
626 && (EQ (frame_inhibit_implied_resize, Qt)
627 || (CONSP (frame_inhibit_implied_resize)
628 && !NILP (Fmemq (Qtool_bar_lines,
629 frame_inhibit_implied_resize))))
630 && NILP (get_frame_param (f, Qfullscreen)))
634 NSTRACE_MSG ("inhibit:%d", inhibit);
636 frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
637 adjust_frame_size (f, -1, -1, inhibit, 0, Qtool_bar_lines);
643 x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
645 int old_width = FRAME_INTERNAL_BORDER_WIDTH (f);
647 CHECK_TYPE_RANGED_INTEGER (int, arg);
648 f->internal_border_width = XINT (arg);
649 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
650 f->internal_border_width = 0;
652 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old_width)
655 if (FRAME_X_WINDOW (f) != 0)
656 adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
658 SET_FRAME_GARBAGED (f);
663 ns_implicitly_set_icon_type (struct frame *f)
666 EmacsView *view = FRAME_NS_VIEW (f);
668 Lisp_Object chain, elt;
669 NSAutoreleasePool *pool;
672 NSTRACE ("ns_implicitly_set_icon_type");
675 pool = [[NSAutoreleasePool alloc] init];
676 if (f->output_data.ns->miniimage
677 && [[NSString stringWithUTF8String: SSDATA (f->name)]
678 isEqualToString: [(NSImage *)f->output_data.ns->miniimage name]])
685 tem = assq_no_quit (Qicon_type, f->param_alist);
686 if (CONSP (tem) && ! NILP (XCDR (tem)))
693 for (chain = Vns_icon_type_alist;
694 image == nil && CONSP (chain);
695 chain = XCDR (chain))
698 /* Special case: t means go by file type. */
699 if (SYMBOLP (elt) && EQ (elt, Qt) && SSDATA (f->name)[0] == '/')
702 = [NSString stringWithUTF8String: SSDATA (f->name)];
703 if ([[NSFileManager defaultManager] fileExistsAtPath: str])
704 image = [[[NSWorkspace sharedWorkspace] iconForFile: str] retain];
706 else if (CONSP (elt) &&
707 STRINGP (XCAR (elt)) &&
708 STRINGP (XCDR (elt)) &&
709 fast_string_match (XCAR (elt), f->name) >= 0)
711 image = [EmacsImage allocInitFromFile: XCDR (elt)];
713 image = [[NSImage imageNamed:
714 [NSString stringWithUTF8String:
715 SSDATA (XCDR (elt))]] retain];
721 image = [[[NSWorkspace sharedWorkspace] iconForFileType: @"text"] retain];
725 [f->output_data.ns->miniimage release];
726 f->output_data.ns->miniimage = image;
727 [view setMiniwindowImage: setMini];
734 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
736 EmacsView *view = FRAME_NS_VIEW (f);
740 NSTRACE ("x_set_icon_type");
742 if (!NILP (arg) && SYMBOLP (arg))
744 arg =build_string (SSDATA (SYMBOL_NAME (arg)));
745 store_frame_param (f, Qicon_type, arg);
748 /* Do it the implicit way. */
751 ns_implicitly_set_icon_type (f);
757 image = [EmacsImage allocInitFromFile: arg];
759 image =[NSImage imageNamed: [NSString stringWithUTF8String:
764 image = [NSImage imageNamed: @"text"];
768 f->output_data.ns->miniimage = image;
769 [view setMiniwindowImage: setMini];
772 /* This is the same as the xfns.c definition. */
774 x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
776 set_frame_cursor_types (f, arg);
779 /* called to set mouse pointer color, but all other terms use it to
780 initialize pointer types (and don't set the color ;) */
782 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
784 /* Don't think we can do this on Nextstep. */
789 #define Xstr(x) Str(x)
792 ns_appkit_version_str (void)
796 #ifdef NS_IMPL_GNUSTEP
797 sprintf(tmp, "gnustep-gui-%s", Xstr(GNUSTEP_GUI_VERSION));
798 #elif defined (NS_IMPL_COCOA)
800 = [[NSProcessInfo processInfo] operatingSystemVersionString];
801 sprintf(tmp, "appkit-%.2f %s",
802 NSAppKitVersionNumber,
803 [osversion UTF8String]);
807 return build_string (tmp);
811 /* This is for use by x-server-version and collapses all version info we
812 have into a single int. For a better picture of the implementation
813 running, use ns_appkit_version_str. */
815 ns_appkit_version_int (void)
817 #ifdef NS_IMPL_GNUSTEP
818 return GNUSTEP_GUI_MAJOR_VERSION * 100 + GNUSTEP_GUI_MINOR_VERSION;
819 #elif defined (NS_IMPL_COCOA)
820 return (int)NSAppKitVersionNumber;
827 x_icon (struct frame *f, Lisp_Object parms)
828 /* --------------------------------------------------------------------------
829 Strangely-named function to set icon position parameters in frame.
830 This is irrelevant under macOS, but might be needed under GNUstep,
831 depending on the window manager used. Note, this is not a standard
832 frame parameter-setter; it is called directly from x-create-frame.
833 -------------------------------------------------------------------------- */
835 Lisp_Object icon_x, icon_y;
836 struct ns_display_info *dpyinfo = check_ns_display_info (Qnil);
838 f->output_data.ns->icon_top = -1;
839 f->output_data.ns->icon_left = -1;
841 /* Set the position of the icon. */
842 icon_x = x_get_arg (dpyinfo, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
843 icon_y = x_get_arg (dpyinfo, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
844 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
846 CHECK_NUMBER (icon_x);
847 CHECK_NUMBER (icon_y);
848 f->output_data.ns->icon_top = XINT (icon_y);
849 f->output_data.ns->icon_left = XINT (icon_x);
851 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
852 error ("Both left and top icon corners of icon must be specified");
856 /* Note: see frame.c for template, also where generic functions are
858 frame_parm_handler ns_frame_parm_handlers[] =
860 x_set_autoraise, /* generic OK */
861 x_set_autolower, /* generic OK */
862 x_set_background_color,
863 0, /* x_set_border_color, may be impossible under Nextstep */
864 0, /* x_set_border_width, may be impossible under Nextstep */
867 x_set_font, /* generic OK */
868 x_set_foreground_color,
871 x_set_internal_border_width, /* generic OK */
872 x_set_right_divider_width,
873 x_set_bottom_divider_width,
874 x_set_menu_bar_lines,
876 x_explicitly_set_name,
877 x_set_scroll_bar_width, /* generic OK */
878 x_set_scroll_bar_height, /* generic OK */
880 x_set_unsplittable, /* generic OK */
881 x_set_vertical_scroll_bars, /* generic OK */
882 x_set_horizontal_scroll_bars, /* generic OK */
883 x_set_visibility, /* generic OK */
884 x_set_tool_bar_lines,
885 0, /* x_set_scroll_bar_foreground, will ignore (not possible on NS) */
886 0, /* x_set_scroll_bar_background, will ignore (not possible on NS) */
887 x_set_screen_gamma, /* generic OK */
888 x_set_line_spacing, /* generic OK, sets f->extra_line_spacing to int */
889 x_set_left_fringe, /* generic OK */
890 x_set_right_fringe, /* generic OK */
891 0, /* x_set_wait_for_wm, will ignore */
892 x_set_fullscreen, /* generic OK */
893 x_set_font_backend, /* generic OK */
895 0, /* x_set_sticky */
896 0, /* x_set_tool_bar_position */
897 0, /* x_set_inhibit_double_buffering */
901 0, /* x_set_undecorated */
904 0, /* x_set_skip_taskbar */
905 x_set_no_focus_on_map,
906 x_set_no_accept_focus,
907 x_set_z_group, /* x_set_z_group */
908 0, /* x_set_override_redirect */
909 x_set_no_special_glyphs,
912 ns_set_transparent_titlebar,
917 /* Handler for signals raised during x_create_frame.
918 FRAME is the frame which is partially constructed. */
921 unwind_create_frame (Lisp_Object frame)
923 struct frame *f = XFRAME (frame);
925 /* If frame is already dead, nothing to do. This can happen if the
926 display is disconnected after the frame has become official, but
927 before x_create_frame removes the unwind protect. */
928 if (!FRAME_LIVE_P (f))
931 /* If frame is ``official'', nothing to do. */
932 if (NILP (Fmemq (frame, Vframe_list)))
934 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
935 struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
938 /* If the frame's image cache refcount is still the same as our
939 private shadow variable, it means we are unwinding a frame
940 for which we didn't yet call init_frame_faces, where the
941 refcount is incremented. Therefore, we increment it here, so
942 that free_frame_faces, called in x_free_frame_resources
943 below, will not mistakenly decrement the counter that was not
944 incremented yet to account for this new frame. */
945 if (FRAME_IMAGE_CACHE (f) != NULL
946 && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount)
947 FRAME_IMAGE_CACHE (f)->refcount++;
949 x_free_frame_resources (f);
952 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
953 /* Check that reference counts are indeed correct. */
954 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
960 * Read geometry related parameters from preferences if not in PARMS.
961 * Returns the union of parms and any preferences read.
965 get_geometry_from_preferences (struct ns_display_info *dpyinfo,
973 { "width", "Width", Qwidth },
974 { "height", "Height", Qheight },
975 { "left", "Left", Qleft },
976 { "top", "Top", Qtop },
980 for (i = 0; i < ARRAYELTS (r); ++i)
982 if (NILP (Fassq (r[i].tem, parms)))
985 = x_get_arg (dpyinfo, parms, r[i].tem, r[i].val, r[i].cls,
987 if (! EQ (value, Qunbound))
988 parms = Fcons (Fcons (r[i].tem, value), parms);
995 /* ==========================================================================
999 ========================================================================== */
1001 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1003 doc: /* SKIP: real doc in xfns.c. */)
1007 Lisp_Object frame, tem;
1009 int minibuffer_only = 0;
1010 long window_prompting = 0;
1011 ptrdiff_t count = specpdl_ptr - specpdl;
1012 Lisp_Object display;
1013 struct ns_display_info *dpyinfo = NULL;
1014 Lisp_Object parent, parent_frame;
1016 static int desc_ctr = 1;
1017 int x_width = 0, x_height = 0;
1019 /* x_get_arg modifies parms. */
1020 parms = Fcopy_alist (parms);
1022 /* Use this general default value to start with
1023 until we know if this frame has a specified name. */
1024 Vx_resource_name = Vinvocation_name;
1026 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_STRING);
1027 if (EQ (display, Qunbound))
1029 dpyinfo = check_ns_display_info (display);
1030 kb = dpyinfo->terminal->kboard;
1032 if (!dpyinfo->terminal->name)
1033 error ("Terminal is not live, can't create new frames on it");
1035 name = x_get_arg (dpyinfo, parms, Qname, 0, 0, RES_TYPE_STRING);
1037 && ! EQ (name, Qunbound)
1039 error ("Invalid frame name--not a string or nil");
1042 Vx_resource_name = name;
1044 parent = x_get_arg (dpyinfo, parms, Qparent_id, 0, 0, RES_TYPE_NUMBER);
1045 if (EQ (parent, Qunbound))
1047 if (! NILP (parent))
1048 CHECK_NUMBER (parent);
1050 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
1051 /* No need to protect DISPLAY because that's not used after passing
1052 it to make_frame_without_minibuffer. */
1054 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
1056 if (EQ (tem, Qnone) || NILP (tem))
1057 f = make_frame_without_minibuffer (Qnil, kb, display);
1058 else if (EQ (tem, Qonly))
1060 f = make_minibuffer_frame ();
1061 minibuffer_only = 1;
1063 else if (WINDOWP (tem))
1064 f = make_frame_without_minibuffer (tem, kb, display);
1068 XSETFRAME (frame, f);
1070 f->terminal = dpyinfo->terminal;
1072 f->output_method = output_ns;
1073 f->output_data.ns = xzalloc (sizeof *f->output_data.ns);
1075 FRAME_FONTSET (f) = -1;
1077 fset_icon_name (f, x_get_arg (dpyinfo, parms, Qicon_name,
1078 "iconName", "Title",
1080 if (! STRINGP (f->icon_name))
1081 fset_icon_name (f, Qnil);
1083 FRAME_DISPLAY_INFO (f) = dpyinfo;
1085 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
1086 record_unwind_protect (unwind_create_frame, frame);
1088 f->output_data.ns->window_desc = desc_ctr++;
1089 if (TYPE_RANGED_INTEGERP (Window, parent))
1091 f->output_data.ns->parent_desc = XFASTINT (parent);
1092 f->output_data.ns->explicit_parent = 1;
1096 f->output_data.ns->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
1097 f->output_data.ns->explicit_parent = 0;
1100 /* Set the name; the functions to which we pass f expect the name to
1102 if (EQ (name, Qunbound) || NILP (name) || ! STRINGP (name))
1104 fset_name (f, build_string ([ns_app_name UTF8String]));
1105 f->explicit_name = 0;
1109 fset_name (f, name);
1110 f->explicit_name = 1;
1111 specbind (Qx_resource_name, name);
1116 #ifdef NS_IMPL_COCOA
1117 mac_register_font_driver (f);
1119 register_font_driver (&nsfont_driver, f);
1122 image_cache_refcount =
1123 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
1125 x_default_parameter (f, parms, Qfont_backend, Qnil,
1126 "fontBackend", "FontBackend", RES_TYPE_STRING);
1129 /* use for default font name */
1130 id font = [NSFont userFixedPitchFontOfSize: -1.0]; /* default */
1131 x_default_parameter (f, parms, Qfontsize,
1132 make_number (0 /* (int)[font pointSize] */),
1133 "fontSize", "FontSize", RES_TYPE_NUMBER);
1134 // Remove ' Regular', not handled by backends.
1135 char *fontname = xstrdup ([[font displayName] UTF8String]);
1136 int len = strlen (fontname);
1137 if (len > 8 && strcmp (fontname + len - 8, " Regular") == 0)
1138 fontname[len-8] = '\0';
1139 x_default_parameter (f, parms, Qfont,
1140 build_string (fontname),
1141 "font", "Font", RES_TYPE_STRING);
1146 x_default_parameter (f, parms, Qborder_width, make_number (0),
1147 "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
1148 x_default_parameter (f, parms, Qinternal_border_width, make_number (2),
1149 "internalBorderWidth", "InternalBorderWidth",
1151 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
1152 NULL, NULL, RES_TYPE_NUMBER);
1153 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
1154 NULL, NULL, RES_TYPE_NUMBER);
1156 /* default vertical scrollbars on right on Mac */
1159 #ifdef NS_IMPL_GNUSTEP
1164 x_default_parameter (f, parms, Qvertical_scroll_bars, spos,
1165 "verticalScrollBars", "VerticalScrollBars",
1168 x_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
1169 "horizontalScrollBars", "HorizontalScrollBars",
1171 x_default_parameter (f, parms, Qforeground_color, build_string ("Black"),
1172 "foreground", "Foreground", RES_TYPE_STRING);
1173 x_default_parameter (f, parms, Qbackground_color, build_string ("White"),
1174 "background", "Background", RES_TYPE_STRING);
1175 x_default_parameter (f, parms, Qline_spacing, Qnil,
1176 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
1177 x_default_parameter (f, parms, Qleft_fringe, Qnil,
1178 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
1179 x_default_parameter (f, parms, Qright_fringe, Qnil,
1180 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
1181 x_default_parameter (f, parms, Qno_special_glyphs, Qnil,
1182 NULL, NULL, RES_TYPE_BOOLEAN);
1184 init_frame_faces (f);
1186 /* Read comment about this code in corresponding place in xfns.c. */
1187 tem = x_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL, RES_TYPE_NUMBER);
1189 store_frame_param (f, Qmin_width, tem);
1190 tem = x_get_arg (dpyinfo, parms, Qmin_height, NULL, NULL, RES_TYPE_NUMBER);
1192 store_frame_param (f, Qmin_height, tem);
1193 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
1194 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1,
1197 tem = x_get_arg (dpyinfo, parms, Qundecorated, NULL, NULL, RES_TYPE_BOOLEAN);
1198 FRAME_UNDECORATED (f) = !NILP (tem) && !EQ (tem, Qunbound);
1199 store_frame_param (f, Qundecorated, FRAME_UNDECORATED (f) ? Qt : Qnil);
1201 #ifdef NS_IMPL_COCOA
1202 tem = x_get_arg (dpyinfo, parms, Qns_appearance, NULL, NULL, RES_TYPE_SYMBOL);
1203 FRAME_NS_APPEARANCE (f) = EQ (tem, Qdark)
1204 ? ns_appearance_vibrant_dark : ns_appearance_aqua;
1205 store_frame_param (f, Qns_appearance, tem);
1207 tem = x_get_arg (dpyinfo, parms, Qns_transparent_titlebar,
1208 NULL, NULL, RES_TYPE_BOOLEAN);
1209 FRAME_NS_TRANSPARENT_TITLEBAR (f) = !NILP (tem) && !EQ (tem, Qunbound);
1210 store_frame_param (f, Qns_transparent_titlebar, tem);
1213 parent_frame = x_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL,
1215 /* Accept parent-frame iff parent-id was not specified. */
1217 || EQ (parent_frame, Qunbound)
1218 || NILP (parent_frame)
1219 || !FRAMEP (parent_frame)
1220 || !FRAME_LIVE_P (XFRAME (parent_frame)))
1221 parent_frame = Qnil;
1223 fset_parent_frame (f, parent_frame);
1224 store_frame_param (f, Qparent_frame, parent_frame);
1226 x_default_parameter (f, parms, Qz_group, Qnil, NULL, NULL, RES_TYPE_SYMBOL);
1227 x_default_parameter (f, parms, Qno_focus_on_map, Qnil,
1228 NULL, NULL, RES_TYPE_BOOLEAN);
1229 x_default_parameter (f, parms, Qno_accept_focus, Qnil,
1230 NULL, NULL, RES_TYPE_BOOLEAN);
1232 /* The resources controlling the menu-bar and tool-bar are
1233 processed specially at startup, and reflected in the mode
1234 variables; ignore them here. */
1235 x_default_parameter (f, parms, Qmenu_bar_lines,
1236 NILP (Vmenu_bar_mode)
1237 ? make_number (0) : make_number (1),
1238 NULL, NULL, RES_TYPE_NUMBER);
1239 x_default_parameter (f, parms, Qtool_bar_lines,
1240 NILP (Vtool_bar_mode)
1241 ? make_number (0) : make_number (1),
1242 NULL, NULL, RES_TYPE_NUMBER);
1244 x_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate",
1245 "BufferPredicate", RES_TYPE_SYMBOL);
1246 x_default_parameter (f, parms, Qtitle, Qnil, "title", "Title",
1249 parms = get_geometry_from_preferences (dpyinfo, parms);
1250 window_prompting = x_figure_window_size (f, parms, true, &x_width, &x_height);
1252 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
1253 f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !EQ (tem, Qnil));
1255 /* NOTE: on other terms, this is done in set_mouse_color, however this
1256 was not getting called under Nextstep. */
1257 f->output_data.ns->text_cursor = [NSCursor IBeamCursor];
1258 f->output_data.ns->nontext_cursor = [NSCursor arrowCursor];
1259 f->output_data.ns->modeline_cursor = [NSCursor pointingHandCursor];
1260 f->output_data.ns->hand_cursor = [NSCursor pointingHandCursor];
1261 f->output_data.ns->hourglass_cursor = [NSCursor disappearingItemCursor];
1262 f->output_data.ns->horizontal_drag_cursor = [NSCursor resizeLeftRightCursor];
1263 f->output_data.ns->vertical_drag_cursor = [NSCursor resizeUpDownCursor];
1264 f->output_data.ns->left_edge_cursor = [NSCursor resizeLeftRightCursor];
1265 f->output_data.ns->top_left_corner_cursor = [NSCursor arrowCursor];
1266 f->output_data.ns->top_edge_cursor = [NSCursor resizeUpDownCursor];
1267 f->output_data.ns->top_right_corner_cursor = [NSCursor arrowCursor];
1268 f->output_data.ns->right_edge_cursor = [NSCursor resizeLeftRightCursor];
1269 f->output_data.ns->bottom_right_corner_cursor = [NSCursor arrowCursor];
1270 f->output_data.ns->bottom_edge_cursor = [NSCursor resizeUpDownCursor];
1271 f->output_data.ns->bottom_left_corner_cursor = [NSCursor arrowCursor];
1273 FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor
1274 = [NSCursor arrowCursor];
1275 FRAME_DISPLAY_INFO (f)->horizontal_scroll_bar_cursor
1276 = [NSCursor arrowCursor];
1277 f->output_data.ns->current_pointer = f->output_data.ns->text_cursor;
1279 f->output_data.ns->in_animation = NO;
1281 [[EmacsView alloc] initFrameFromEmacs: f];
1285 /* ns_display_info does not have a reference_count. */
1286 f->terminal->reference_count++;
1288 /* It is now ok to make the frame official even if we get an error
1289 below. The frame needs to be on Vframe_list or making it visible
1291 Vframe_list = Fcons (frame, Vframe_list);
1293 x_default_parameter (f, parms, Qicon_type, Qnil,
1294 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
1296 x_default_parameter (f, parms, Qauto_raise, Qnil,
1297 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
1298 x_default_parameter (f, parms, Qauto_lower, Qnil,
1299 "autoLower", "AutoLower", RES_TYPE_BOOLEAN);
1300 x_default_parameter (f, parms, Qcursor_type, Qbox,
1301 "cursorType", "CursorType", RES_TYPE_SYMBOL);
1302 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
1303 "scrollBarWidth", "ScrollBarWidth",
1305 x_default_parameter (f, parms, Qscroll_bar_height, Qnil,
1306 "scrollBarHeight", "ScrollBarHeight",
1308 x_default_parameter (f, parms, Qalpha, Qnil,
1309 "alpha", "Alpha", RES_TYPE_NUMBER);
1310 x_default_parameter (f, parms, Qfullscreen, Qnil,
1311 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
1313 /* Allow x_set_window_size, now. */
1314 f->can_x_set_window_size = true;
1317 SET_FRAME_WIDTH (f, x_width);
1319 SET_FRAME_HEIGHT (f, x_height);
1321 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1,
1324 if (! f->output_data.ns->explicit_parent)
1326 Lisp_Object visibility;
1328 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
1330 if (EQ (visibility, Qunbound))
1333 if (EQ (visibility, Qicon))
1334 x_iconify_frame (f);
1335 else if (! NILP (visibility))
1337 x_make_frame_visible (f);
1338 [[FRAME_NS_VIEW (f) window] makeKeyWindow];
1342 /* Must have been Qnil. */
1346 if (FRAME_HAS_MINIBUF_P (f)
1347 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
1348 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
1349 kset_default_minibuffer_frame (kb, frame);
1351 /* All remaining specified parameters, which have not been "used"
1352 by x_get_arg and friends, now go in the misc. alist of the frame. */
1353 for (tem = parms; CONSP (tem); tem = XCDR (tem))
1354 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
1355 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
1357 if (window_prompting & USPosition)
1358 x_set_offset (f, f->left_pos, f->top_pos, 1);
1360 /* Make sure windows on this frame appear in calls to next-window
1361 and similar functions. */
1362 Vwindow_list = Qnil;
1364 return unbind_to (count, frame);
1368 x_focus_frame (struct frame *f, bool noactivate)
1370 struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1372 if (dpyinfo->x_focus_frame != f)
1374 EmacsView *view = FRAME_NS_VIEW (f);
1376 [NSApp activateIgnoringOtherApps: YES];
1377 [[view window] makeKeyAndOrderFront: view];
1383 ns_window_is_ancestor (NSWindow *win, NSWindow *candidate)
1384 /* Test whether CANDIDATE is an ancestor window of WIN. */
1386 if (candidate == NULL)
1388 else if (win == candidate)
1391 return ns_window_is_ancestor(win, [candidate parentWindow]);
1394 DEFUN ("ns-frame-list-z-order", Fns_frame_list_z_order,
1395 Sns_frame_list_z_order, 0, 1, 0,
1396 doc: /* Return list of Emacs' frames, in Z (stacking) order.
1397 If TERMINAL is non-nil and specifies a live frame, return the child
1398 frames of that frame in Z (stacking) order.
1400 Frames are listed from topmost (first) to bottommost (last). */)
1401 (Lisp_Object terminal)
1403 Lisp_Object frames = Qnil;
1404 NSWindow *parent = nil;
1406 if (FRAMEP (terminal) && FRAME_LIVE_P (XFRAME (terminal)))
1407 parent = [FRAME_NS_VIEW (XFRAME (terminal)) window];
1409 for (NSWindow *win in [[NSApp orderedWindows] reverseObjectEnumerator])
1413 /* Check against [win parentWindow] so that it doesn't match
1415 if (parent == nil || ns_window_is_ancestor (parent, [win parentWindow]))
1417 XSETFRAME (frame, ((EmacsView *)[win delegate])->emacsframe);
1418 frames = Fcons(frame, frames);
1425 DEFUN ("ns-frame-restack", Fns_frame_restack, Sns_frame_restack, 2, 3, 0,
1426 doc: /* Restack FRAME1 below FRAME2.
1427 This means that if both frames are visible and the display areas of
1428 these frames overlap, FRAME2 (partially) obscures FRAME1. If optional
1429 third argument ABOVE is non-nil, restack FRAME1 above FRAME2. This
1430 means that if both frames are visible and the display areas of these
1431 frames overlap, FRAME1 (partially) obscures FRAME2.
1433 Some window managers may refuse to restack windows. */)
1434 (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above)
1436 struct frame *f1 = decode_live_frame (frame1);
1437 struct frame *f2 = decode_live_frame (frame2);
1439 if (FRAME_NS_VIEW (f1) && FRAME_NS_VIEW (f2))
1441 NSWindow *window = [FRAME_NS_VIEW (f1) window];
1442 NSInteger window2 = [[FRAME_NS_VIEW (f2) window] windowNumber];
1443 NSWindowOrderingMode flag = NILP (above) ? NSWindowBelow : NSWindowAbove;
1445 [window orderWindow: flag
1446 relativeTo: window2];
1452 error ("Cannot restack frames");
1457 DEFUN ("ns-popup-font-panel", Fns_popup_font_panel, Sns_popup_font_panel,
1459 doc: /* Pop up the font panel. */)
1462 struct frame *f = decode_window_system_frame (frame);
1463 id fm = [NSFontManager sharedFontManager];
1464 struct font *font = f->output_data.ns->font;
1466 #ifdef NS_IMPL_GNUSTEP
1467 nsfont = ((struct nsfont_info *)font)->nsfont;
1469 #ifdef NS_IMPL_COCOA
1470 nsfont = (NSFont *) macfont_get_nsctfont (font);
1472 [fm setSelectedFont: nsfont isMultiple: NO];
1473 [fm orderFrontFontPanel: NSApp];
1478 DEFUN ("ns-popup-color-panel", Fns_popup_color_panel, Sns_popup_color_panel,
1480 doc: /* Pop up the color panel. */)
1483 check_window_system (NULL);
1484 [NSApp orderFrontColorPanel: NSApp];
1492 #ifdef NS_IMPL_GNUSTEP
1493 NSString *dirS, *initS;
1499 ns_run_file_dialog (void)
1501 if (ns_fd_data.panel == nil) return;
1502 #ifdef NS_IMPL_COCOA
1503 ns_fd_data.ret = [ns_fd_data.panel runModal];
1505 if (ns_fd_data.no_types)
1507 ns_fd_data.ret = [ns_fd_data.panel
1508 runModalForDirectory: ns_fd_data.dirS
1509 file: ns_fd_data.initS];
1513 ns_fd_data.ret = [ns_fd_data.panel
1514 runModalForDirectory: ns_fd_data.dirS
1515 file: ns_fd_data.initS
1519 ns_fd_data.panel = nil;
1522 #ifdef NS_IMPL_COCOA
1523 #if MAC_OS_X_VERSION_MAX_ALLOWED > 1090
1524 #define MODAL_OK_RESPONSE NSModalResponseOK
1527 #ifndef MODAL_OK_RESPONSE
1528 #define MODAL_OK_RESPONSE NSOKButton
1531 DEFUN ("ns-read-file-name", Fns_read_file_name, Sns_read_file_name, 1, 5, 0,
1532 doc: /* Use a graphical panel to read a file name, using prompt PROMPT.
1533 Optional arg DIR, if non-nil, supplies a default directory.
1534 Optional arg MUSTMATCH, if non-nil, means the returned file or
1535 directory must exist.
1536 Optional arg INIT, if non-nil, provides a default file name to use.
1537 Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1538 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object mustmatch,
1539 Lisp_Object init, Lisp_Object dir_only_p)
1541 static id fileDelegate = nil;
1542 BOOL isSave = NILP (mustmatch) && NILP (dir_only_p);
1544 Lisp_Object fname = Qnil;
1546 NSString *promptS = NILP (prompt) || !STRINGP (prompt) ? nil :
1547 [NSString stringWithUTF8String: SSDATA (prompt)];
1548 NSString *dirS = NILP (dir) || !STRINGP (dir) ?
1549 [NSString stringWithUTF8String: SSDATA (BVAR (current_buffer, directory))] :
1550 [NSString stringWithUTF8String: SSDATA (dir)];
1551 NSString *initS = NILP (init) || !STRINGP (init) ? nil :
1552 [NSString stringWithUTF8String: SSDATA (init)];
1555 check_window_system (NULL);
1557 if (fileDelegate == nil)
1558 fileDelegate = [EmacsFileDelegate new];
1560 [NSCursor setHiddenUntilMouseMoves: NO];
1562 if ([dirS characterAtIndex: 0] == '~')
1563 dirS = [dirS stringByExpandingTildeInPath];
1566 (id)[EmacsSavePanel savePanel] : (id)[EmacsOpenPanel openPanel];
1568 [panel setTitle: promptS];
1570 [panel setAllowsOtherFileTypes: YES];
1571 [panel setTreatsFilePackagesAsDirectories: YES];
1572 [panel setDelegate: fileDelegate];
1574 if (! NILP (dir_only_p))
1576 [panel setCanChooseDirectories: YES];
1577 [panel setCanChooseFiles: NO];
1581 /* This is not quite what the documentation says, but it is compatible
1582 with the Gtk+ code. Also, the menu entry says "Open File...". */
1583 [panel setCanChooseDirectories: NO];
1584 [panel setCanChooseFiles: YES];
1588 ns_fd_data.panel = panel;
1589 ns_fd_data.ret = NO;
1590 #ifdef NS_IMPL_COCOA
1591 if (! NILP (mustmatch) || ! NILP (dir_only_p))
1592 [panel setAllowedFileTypes: nil];
1593 if (dirS) [panel setDirectoryURL: [NSURL fileURLWithPath: dirS]];
1594 if (initS && NILP (Ffile_directory_p (init)))
1595 [panel setNameFieldStringValue: [initS lastPathComponent]];
1597 [panel setNameFieldStringValue: @""];
1600 ns_fd_data.no_types = NILP (mustmatch) && NILP (dir_only_p);
1601 ns_fd_data.dirS = dirS;
1602 ns_fd_data.initS = initS;
1605 /* runModalForDirectory/runModal restarts the main event loop when done,
1606 so we must start an event loop and then pop up the file dialog.
1607 The file dialog may pop up a confirm dialog after Ok has been pressed,
1608 so we can not simply pop down on the Ok/Cancel press.
1610 nxev = [NSEvent otherEventWithType: NSEventTypeApplicationDefined
1611 location: NSMakePoint (0, 0)
1614 windowNumber: [[NSApp mainWindow] windowNumber]
1615 context: [NSApp context]
1618 data2: NSAPP_DATA2_RUNFILEDIALOG];
1620 [NSApp postEvent: nxev atStart: NO];
1621 while (ns_fd_data.panel != nil)
1624 if (ns_fd_data.ret == MODAL_OK_RESPONSE)
1626 NSString *str = ns_filename_from_panel (panel);
1627 if (! str) str = ns_directory_from_panel (panel);
1628 if (str) fname = build_string ([str UTF8String]);
1631 [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
1638 ns_get_defaults_value (const char *key)
1640 NSObject *obj = [[NSUserDefaults standardUserDefaults]
1641 objectForKey: [NSString stringWithUTF8String: key]];
1643 if (!obj) return NULL;
1645 return [[NSString stringWithFormat: @"%@", obj] UTF8String];
1649 DEFUN ("ns-get-resource", Fns_get_resource, Sns_get_resource, 2, 2, 0,
1650 doc: /* Return the value of the property NAME of OWNER from the defaults database.
1651 If OWNER is nil, Emacs is assumed. */)
1652 (Lisp_Object owner, Lisp_Object name)
1656 check_window_system (NULL);
1658 owner = build_string([ns_app_name UTF8String]);
1659 CHECK_STRING (name);
1661 value = ns_get_defaults_value (SSDATA (name));
1664 return build_string (value);
1669 DEFUN ("ns-set-resource", Fns_set_resource, Sns_set_resource, 3, 3, 0,
1670 doc: /* Set property NAME of OWNER to VALUE, from the defaults database.
1671 If OWNER is nil, Emacs is assumed.
1672 If VALUE is nil, the default is removed. */)
1673 (Lisp_Object owner, Lisp_Object name, Lisp_Object value)
1675 check_window_system (NULL);
1677 owner = build_string ([ns_app_name UTF8String]);
1678 CHECK_STRING (name);
1681 [[NSUserDefaults standardUserDefaults] removeObjectForKey:
1682 [NSString stringWithUTF8String: SSDATA (name)]];
1686 CHECK_STRING (value);
1687 [[NSUserDefaults standardUserDefaults] setObject:
1688 [NSString stringWithUTF8String: SSDATA (value)]
1689 forKey: [NSString stringWithUTF8String:
1697 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
1698 Sx_server_max_request_size,
1700 doc: /* SKIP: real doc in xfns.c. */)
1701 (Lisp_Object terminal)
1703 check_ns_display_info (terminal);
1704 /* This function has no real equivalent under Nextstep. Return nil to
1710 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
1711 doc: /* SKIP: real doc in xfns.c. */)
1712 (Lisp_Object terminal)
1714 check_ns_display_info (terminal);
1715 #ifdef NS_IMPL_GNUSTEP
1716 return build_string ("GNU");
1718 return build_string ("Apple");
1723 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
1724 doc: /* SKIP: real doc in xfns.c. */)
1725 (Lisp_Object terminal)
1727 check_ns_display_info (terminal);
1728 /* NOTE: it is unclear what would best correspond with "protocol";
1729 we return 10.3, meaning Panther, since this is roughly the
1730 level that GNUstep's APIs correspond to. The last number
1731 is where we distinguish between the Apple and GNUstep
1732 implementations ("distributor-specific release number") and
1733 give int'ized versions of major.minor. */
1734 return list3i (10, 3, ns_appkit_version_int ());
1738 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
1739 doc: /* SKIP: real doc in xfns.c. */)
1740 (Lisp_Object terminal)
1742 check_ns_display_info (terminal);
1743 return make_number (1);
1747 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
1748 doc: /* SKIP: real doc in xfns.c. */)
1749 (Lisp_Object terminal)
1751 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
1753 return make_number (x_display_pixel_height (dpyinfo) / (92.0/25.4));
1757 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
1758 doc: /* SKIP: real doc in xfns.c. */)
1759 (Lisp_Object terminal)
1761 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
1763 return make_number (x_display_pixel_width (dpyinfo) / (92.0/25.4));
1767 DEFUN ("x-display-backing-store", Fx_display_backing_store,
1768 Sx_display_backing_store, 0, 1, 0,
1769 doc: /* SKIP: real doc in xfns.c. */)
1770 (Lisp_Object terminal)
1772 check_ns_display_info (terminal);
1773 /* Note that the xfns.c version has different return values. */
1774 switch ([ns_get_window (terminal) backingType])
1776 case NSBackingStoreBuffered:
1777 return intern ("buffered");
1778 #if defined (NS_IMPL_GNUSTEP) || MAC_OS_X_VERSION_MIN_REQUIRED < 101300
1779 case NSBackingStoreRetained:
1780 return intern ("retained");
1781 case NSBackingStoreNonretained:
1782 return intern ("non-retained");
1785 error ("Strange value for backingType parameter of frame");
1787 return Qnil; /* not reached, shut compiler up */
1791 DEFUN ("x-display-visual-class", Fx_display_visual_class,
1792 Sx_display_visual_class, 0, 1, 0,
1793 doc: /* SKIP: real doc in xfns.c. */)
1794 (Lisp_Object terminal)
1796 NSWindowDepth depth;
1798 check_ns_display_info (terminal);
1799 depth = [[[NSScreen screens] objectAtIndex:0] depth];
1801 if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
1802 return intern ("static-gray");
1803 else if (depth == NSBestDepth (NSCalibratedWhiteColorSpace, 8, 8, YES, NULL))
1804 return intern ("gray-scale");
1805 else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 8, 8, YES, NULL))
1806 return intern ("pseudo-color");
1807 else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 4, 12, NO, NULL))
1808 return intern ("true-color");
1809 else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 8, 24, NO, NULL))
1810 return intern ("direct-color");
1812 /* Color management as far as we do it is really handled by
1813 Nextstep itself anyway. */
1814 return intern ("direct-color");
1818 DEFUN ("x-display-save-under", Fx_display_save_under,
1819 Sx_display_save_under, 0, 1, 0,
1820 doc: /* SKIP: real doc in xfns.c. */)
1821 (Lisp_Object terminal)
1823 check_ns_display_info (terminal);
1824 switch ([ns_get_window (terminal) backingType])
1826 case NSBackingStoreBuffered:
1829 #if defined (NS_IMPL_GNUSTEP) || MAC_OS_X_VERSION_MIN_REQUIRED < 101300
1830 case NSBackingStoreRetained:
1831 case NSBackingStoreNonretained:
1836 error ("Strange value for backingType parameter of frame");
1838 return Qnil; /* not reached, shut compiler up */
1842 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
1844 doc: /* SKIP: real doc in xfns.c. */)
1845 (Lisp_Object display, Lisp_Object resource_string, Lisp_Object must_succeed)
1847 struct ns_display_info *dpyinfo;
1849 CHECK_STRING (display);
1851 nxatoms_of_nsselect ();
1852 dpyinfo = ns_term_init (display);
1855 if (!NILP (must_succeed))
1856 fatal ("Display on %s not responding.\n",
1859 error ("Display on %s not responding.\n",
1867 DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection,
1869 doc: /* SKIP: real doc in xfns.c. */)
1870 (Lisp_Object terminal)
1872 check_ns_display_info (terminal);
1873 [NSApp terminate: NSApp];
1878 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
1879 doc: /* SKIP: real doc in xfns.c. */)
1882 Lisp_Object result = Qnil;
1883 struct ns_display_info *ndi;
1885 for (ndi = x_display_list; ndi; ndi = ndi->next)
1886 result = Fcons (XCAR (ndi->name_list_element), result);
1892 DEFUN ("ns-hide-others", Fns_hide_others, Sns_hide_others,
1894 doc: /* Hides all applications other than Emacs. */)
1897 check_window_system (NULL);
1898 [NSApp hideOtherApplications: NSApp];
1902 DEFUN ("ns-hide-emacs", Fns_hide_emacs, Sns_hide_emacs,
1904 doc: /* If ON is non-nil, the entire Emacs application is hidden.
1905 Otherwise if Emacs is hidden, it is unhidden.
1906 If ON is equal to `activate', Emacs is unhidden and becomes
1907 the active application. */)
1910 check_window_system (NULL);
1911 if (EQ (on, intern ("activate")))
1913 [NSApp unhide: NSApp];
1914 [NSApp activateIgnoringOtherApps: YES];
1917 [NSApp unhide: NSApp];
1919 [NSApp hide: NSApp];
1924 DEFUN ("ns-emacs-info-panel", Fns_emacs_info_panel, Sns_emacs_info_panel,
1926 doc: /* Shows the 'Info' or 'About' panel for Emacs. */)
1929 check_window_system (NULL);
1930 [NSApp orderFrontStandardAboutPanel: nil];
1935 DEFUN ("ns-font-name", Fns_font_name, Sns_font_name, 1, 1, 0,
1936 doc: /* Determine font PostScript or family name for font NAME.
1937 NAME should be a string containing either the font name or an XLFD
1938 font descriptor. If string contains `fontset' and not
1939 `fontset-startup', it is left alone. */)
1943 CHECK_STRING (name);
1948 if (strstr (nm, "fontset") && !strstr (nm, "fontset-startup"))
1951 return build_string (ns_xlfd_to_fontname (SSDATA (name)));
1955 DEFUN ("ns-list-colors", Fns_list_colors, Sns_list_colors, 0, 1, 0,
1956 doc: /* Return a list of all available colors.
1957 The optional argument FRAME is currently ignored. */)
1960 Lisp_Object list = Qnil;
1961 NSEnumerator *colorlists;
1966 CHECK_FRAME (frame);
1967 if (! FRAME_NS_P (XFRAME (frame)))
1968 error ("non-Nextstep frame used in `ns-list-colors'");
1973 colorlists = [[NSColorList availableColorLists] objectEnumerator];
1974 while ((clist = [colorlists nextObject]))
1976 if ([[clist name] length] < 7 ||
1977 [[clist name] rangeOfString: @"PANTONE"].location == 0)
1979 NSEnumerator *cnames = [[clist allKeys] reverseObjectEnumerator];
1981 while ((cname = [cnames nextObject]))
1982 list = Fcons (build_string ([cname UTF8String]), list);
1983 /* for (i = [[clist allKeys] count] - 1; i >= 0; i--)
1984 list = Fcons (build_string ([[[clist allKeys] objectAtIndex: i]
1985 UTF8String]), list); */
1995 DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0,
1996 doc: /* List available Nextstep services by querying NSApp. */)
1999 #ifdef NS_IMPL_COCOA
2000 /* You can't get services like this in 10.6+. */
2003 Lisp_Object ret = Qnil;
2006 check_window_system (NULL);
2007 svcs = [[NSMenu alloc] initWithTitle: @"Services"];
2008 [NSApp setServicesMenu: svcs];
2009 [NSApp registerServicesMenuSendTypes: ns_send_types
2010 returnTypes: ns_return_types];
2012 [svcs setAutoenablesItems: NO];
2014 ret = interpret_services_menu (svcs, Qnil, ret);
2020 DEFUN ("ns-perform-service", Fns_perform_service, Sns_perform_service,
2022 doc: /* Perform Nextstep SERVICE on SEND.
2023 SEND should be either a string or nil.
2024 The return value is the result of the service, as string, or nil if
2025 there was no result. */)
2026 (Lisp_Object service, Lisp_Object send)
2032 CHECK_STRING (service);
2033 check_window_system (NULL);
2035 utfStr = SSDATA (service);
2036 svcName = [NSString stringWithUTF8String: utfStr];
2038 pb =[NSPasteboard pasteboardWithUniqueName];
2039 ns_string_to_pasteboard (pb, send);
2041 if (NSPerformService (svcName, pb) == NO)
2042 Fsignal (Qquit, list1 (build_string ("service not available")));
2044 if ([[pb types] count] == 0)
2045 return build_string ("");
2046 return ns_string_from_pasteboard (pb);
2050 #ifdef NS_IMPL_COCOA
2052 /* Compile and execute the AppleScript SCRIPT and return the error
2053 status as function value. A zero is returned if compilation and
2054 execution is successful, in which case *RESULT is set to a Lisp
2055 string or a number containing the resulting script value. Otherwise,
2058 ns_do_applescript (Lisp_Object script, Lisp_Object *result)
2060 NSAppleEventDescriptor *desc;
2061 NSDictionary *errorDict;
2062 NSAppleEventDescriptor *returnDescriptor = NULL;
2064 NSAppleScript *scriptObject =
2065 [[NSAppleScript alloc] initWithSource:
2066 [NSString stringWithUTF8String: SSDATA (script)]];
2068 returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
2069 [scriptObject release];
2072 if (returnDescriptor != NULL)
2074 // successful execution
2075 if (kAENullEvent != [returnDescriptor descriptorType])
2078 // script returned an AppleScript result
2079 if ((typeUnicodeText == [returnDescriptor descriptorType]) ||
2080 #if defined (NS_IMPL_COCOA)
2081 (typeUTF16ExternalRepresentation
2082 == [returnDescriptor descriptorType]) ||
2084 (typeUTF8Text == [returnDescriptor descriptorType]) ||
2085 (typeCString == [returnDescriptor descriptorType]))
2087 desc = [returnDescriptor coerceToDescriptorType: typeUTF8Text];
2089 *result = build_string([[desc stringValue] UTF8String]);
2093 /* use typeUTF16ExternalRepresentation? */
2094 // coerce the result to the appropriate ObjC type
2095 desc = [returnDescriptor coerceToDescriptorType: typeUTF8Text];
2097 *result = make_number([desc int32Value]);
2103 // no script result, return error
2109 /* Helper function called from sendEvent to run AppleScript
2110 from within the main event loop. */
2113 ns_run_ascript (void)
2115 if (! NILP (as_script))
2116 as_status = ns_do_applescript (as_script, as_result);
2120 DEFUN ("ns-do-applescript", Fns_do_applescript, Sns_do_applescript, 1, 1, 0,
2121 doc: /* Execute AppleScript SCRIPT and return the result.
2122 If compilation and execution are successful, the resulting script value
2123 is returned as a string, a number or, in the case of other constructs, t.
2124 In case the execution fails, an error is signaled. */)
2125 (Lisp_Object script)
2130 struct input_event ev;
2132 CHECK_STRING (script);
2133 check_window_system (NULL);
2138 as_result = &result;
2140 /* Executing AppleScript requires the event loop to run, otherwise
2141 errors aren't returned and executeAndReturnError hangs forever.
2142 Post an event that runs AppleScript and then start the event
2143 loop. The event loop is exited when the script is done. */
2144 nxev = [NSEvent otherEventWithType: NSEventTypeApplicationDefined
2145 location: NSMakePoint (0, 0)
2148 windowNumber: [[NSApp mainWindow] windowNumber]
2149 context: [NSApp context]
2152 data2: NSAPP_DATA2_RUNASSCRIPT];
2154 [NSApp postEvent: nxev atStart: NO];
2156 /* If there are other events, the event loop may exit. Keep running
2157 until the script has been handled. */
2158 ns_init_events (&ev);
2159 while (! NILP (as_script))
2161 ns_finish_events ();
2169 else if (!STRINGP (result))
2170 error ("AppleScript error %d", status);
2172 error ("%s", SSDATA (result));
2178 /* ==========================================================================
2180 Miscellaneous functions not called through hooks
2182 ========================================================================== */
2184 /* called from frame.c */
2185 struct ns_display_info *
2186 check_x_display_info (Lisp_Object frame)
2188 return check_ns_display_info (frame);
2193 x_set_scroll_bar_default_width (struct frame *f)
2195 int wid = FRAME_COLUMN_WIDTH (f);
2196 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = NS_SCROLL_BAR_WIDTH_DEFAULT;
2197 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
2202 x_set_scroll_bar_default_height (struct frame *f)
2204 int height = FRAME_LINE_HEIGHT (f);
2205 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = NS_SCROLL_BAR_WIDTH_DEFAULT;
2206 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) +
2207 height - 1) / height;
2210 /* Terms implement this instead of x-get-resource directly. */
2212 x_get_string_resource (XrmDatabase rdb, const char *name, const char *class)
2214 /* remove appname prefix; TODO: allow for !="Emacs" */
2215 const char *res, *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
2217 check_window_system (NULL);
2219 if (inhibit_x_resources)
2220 /* --quick was passed, so this is a no-op. */
2223 res = ns_get_defaults_value (toCheck);
2224 return (char *) (!res ? NULL
2225 : !c_strncasecmp (res, "YES", 3) ? "true"
2226 : !c_strncasecmp (res, "NO", 2) ? "false"
2232 x_get_focus_frame (struct frame *frame)
2234 struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
2235 Lisp_Object nsfocus;
2237 if (!dpyinfo->x_focus_frame)
2240 XSETFRAME (nsfocus, dpyinfo->x_focus_frame);
2244 /* ==========================================================================
2246 Lisp definitions that, for whatever reason, we can't alias as 'ns-XXX'.
2248 ========================================================================== */
2251 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
2252 doc: /* SKIP: real doc in xfns.c. */)
2253 (Lisp_Object color, Lisp_Object frame)
2256 check_window_system (NULL);
2257 return ns_lisp_to_color (color, &col) ? Qnil : Qt;
2261 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2262 doc: /* SKIP: real doc in xfns.c. */)
2263 (Lisp_Object color, Lisp_Object frame)
2266 EmacsCGFloat red, green, blue, alpha;
2268 check_window_system (NULL);
2269 CHECK_STRING (color);
2272 if (ns_lisp_to_color (color, &col))
2278 [[col colorUsingDefaultColorSpace]
2279 getRed: &red green: &green blue: &blue alpha: &alpha];
2281 return list3i (lrint (red * 65280), lrint (green * 65280),
2282 lrint (blue * 65280));
2286 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2287 doc: /* SKIP: real doc in xfns.c. */)
2288 (Lisp_Object terminal)
2290 NSWindowDepth depth;
2291 NSString *colorSpace;
2293 check_ns_display_info (terminal);
2294 depth = [[[NSScreen screens] objectAtIndex:0] depth];
2295 colorSpace = NSColorSpaceFromDepth (depth);
2297 return [colorSpace isEqualToString: NSDeviceWhiteColorSpace]
2298 || [colorSpace isEqualToString: NSCalibratedWhiteColorSpace]
2303 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
2305 doc: /* SKIP: real doc in xfns.c. */)
2306 (Lisp_Object terminal)
2308 NSWindowDepth depth;
2310 check_ns_display_info (terminal);
2311 depth = [[[NSScreen screens] objectAtIndex:0] depth];
2313 return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil;
2317 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2319 doc: /* SKIP: real doc in xfns.c. */)
2320 (Lisp_Object terminal)
2322 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2324 return make_number (x_display_pixel_width (dpyinfo));
2328 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2329 Sx_display_pixel_height, 0, 1, 0,
2330 doc: /* SKIP: real doc in xfns.c. */)
2331 (Lisp_Object terminal)
2333 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2335 return make_number (x_display_pixel_height (dpyinfo));
2338 #ifdef NS_IMPL_COCOA
2340 /* Returns the name for the screen that OBJ represents, or NULL.
2341 Caller must free return value.
2345 ns_get_name_from_ioreg (io_object_t obj)
2349 NSDictionary *info = (NSDictionary *)
2350 IODisplayCreateInfoDictionary (obj, kIODisplayOnlyPreferredName);
2351 NSDictionary *names = [info objectForKey:
2352 [NSString stringWithUTF8String:
2353 kDisplayProductName]];
2355 if ([names count] > 0)
2357 NSString *n = [names objectForKey: [[names allKeys]
2359 if (n != nil) name = xstrdup ([n UTF8String]);
2367 /* Returns the name for the screen that DID came from, or NULL.
2368 Caller must free return value.
2372 ns_screen_name (CGDirectDisplayID did)
2376 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
2377 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
2378 if (CGDisplayIOServicePort == NULL)
2381 mach_port_t masterPort;
2385 /* CGDisplayIOServicePort is deprecated. Do it another (harder) way.
2387 Is this code OK for macOS < 10.9, and GNUstep? I suspect it is,
2388 in which case is it worth keeping the other method in here? */
2390 if (IOMasterPort (MACH_PORT_NULL, &masterPort) != kIOReturnSuccess
2391 || IOServiceGetMatchingServices (masterPort,
2392 IOServiceMatching ("IONDRVDevice"),
2393 &it) != kIOReturnSuccess)
2396 /* Must loop until we find a name. Many devices can have the same unit
2397 number (represents different GPU parts), but only one has a name. */
2398 while (! name && (obj = IOIteratorNext (it)))
2400 CFMutableDictionaryRef props;
2403 if (IORegistryEntryCreateCFProperties (obj,
2405 kCFAllocatorDefault,
2406 kNilOptions) == kIOReturnSuccess
2408 && (val = CFDictionaryGetValue(props, @"IOFBDependentIndex")))
2410 unsigned nr = [(NSNumber *)val unsignedIntegerValue];
2411 if (nr == CGDisplayUnitNumber (did))
2412 name = ns_get_name_from_ioreg (obj);
2416 IOObjectRelease (obj);
2419 IOObjectRelease (it);
2421 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
2424 #endif /* #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 */
2425 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
2426 name = ns_get_name_from_ioreg (CGDisplayIOServicePort (did));
2430 #endif /* NS_IMPL_COCOA */
2433 ns_make_monitor_attribute_list (struct MonitorInfo *monitors,
2435 int primary_monitor,
2438 Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
2439 Lisp_Object frame, rest;
2440 NSArray *screens = [NSScreen screens];
2443 FOR_EACH_FRAME (rest, frame)
2445 struct frame *f = XFRAME (frame);
2449 NSView *view = FRAME_NS_VIEW (f);
2450 NSScreen *screen = [[view window] screen];
2454 for (k = 0; i == -1 && k < [screens count]; ++k)
2456 if ([screens objectAtIndex: k] == screen)
2461 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
2465 return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
2466 monitor_frames, source);
2469 DEFUN ("ns-display-monitor-attributes-list",
2470 Fns_display_monitor_attributes_list,
2471 Sns_display_monitor_attributes_list,
2473 doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
2475 The optional argument TERMINAL specifies which display to ask about.
2476 TERMINAL should be a terminal object, a frame or a display name (a string).
2477 If omitted or nil, that stands for the selected frame's display.
2479 In addition to the standard attribute keys listed in
2480 `display-monitor-attributes-list', the following keys are contained in
2483 source -- String describing the source from which multi-monitor
2484 information is obtained, \"NS\" is always the source."
2486 Internal use only, use `display-monitor-attributes-list' instead. */)
2487 (Lisp_Object terminal)
2489 struct terminal *term = decode_live_terminal (terminal);
2491 NSUInteger i, n_monitors;
2492 struct MonitorInfo *monitors;
2493 Lisp_Object attributes_list = Qnil;
2494 CGFloat primary_display_height = 0;
2496 if (term->type != output_ns)
2499 screens = [NSScreen screens];
2500 n_monitors = [screens count];
2501 if (n_monitors == 0)
2504 monitors = xzalloc (n_monitors * sizeof *monitors);
2506 for (i = 0; i < [screens count]; ++i)
2508 NSScreen *s = [screens objectAtIndex:i];
2509 struct MonitorInfo *m = &monitors[i];
2510 NSRect fr = [s frame];
2511 NSRect vfr = [s visibleFrame];
2514 #ifdef NS_IMPL_COCOA
2515 NSDictionary *dict = [s deviceDescription];
2516 NSNumber *nid = [dict objectForKey:@"NSScreenNumber"];
2517 CGDirectDisplayID did = [nid unsignedIntValue];
2521 primary_display_height = fr.size.height;
2522 y = (short) fr.origin.y;
2523 vy = (short) vfr.origin.y;
2527 // Flip y coordinate as NS has y starting from the bottom.
2528 y = (short) (primary_display_height - fr.size.height - fr.origin.y);
2529 vy = (short) (primary_display_height -
2530 vfr.size.height - vfr.origin.y);
2533 m->geom.x = (short) fr.origin.x;
2535 m->geom.width = (unsigned short) fr.size.width;
2536 m->geom.height = (unsigned short) fr.size.height;
2538 m->work.x = (short) vfr.origin.x;
2539 // y is flipped on NS, so vy - y are pixels missing at the bottom,
2540 // and fr.size.height - vfr.size.height are pixels missing in total.
2541 // Pixels missing at top are
2542 // fr.size.height - vfr.size.height - vy + y.
2543 // work.y is then pixels missing at top + y.
2544 m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y;
2545 m->work.width = (unsigned short) vfr.size.width;
2546 m->work.height = (unsigned short) vfr.size.height;
2548 #ifdef NS_IMPL_COCOA
2549 m->name = ns_screen_name (did);
2552 CGSize mms = CGDisplayScreenSize (did);
2553 m->mm_width = (int) mms.width;
2554 m->mm_height = (int) mms.height;
2558 // Assume 92 dpi as x-display-mm-height/x-display-mm-width does.
2559 m->mm_width = (int) (25.4 * fr.size.width / 92.0);
2560 m->mm_height = (int) (25.4 * fr.size.height / 92.0);
2564 // Primary monitor is always first for NS.
2565 attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors,
2568 free_monitors (monitors, n_monitors);
2569 return attributes_list;
2573 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2575 doc: /* SKIP: real doc in xfns.c. */)
2576 (Lisp_Object terminal)
2578 check_ns_display_info (terminal);
2580 (NSBitsPerPixelFromDepth ([[[NSScreen screens] objectAtIndex:0] depth]));
2584 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2586 doc: /* SKIP: real doc in xfns.c. */)
2587 (Lisp_Object terminal)
2589 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2590 /* We force 24+ bit depths to 24-bit to prevent an overflow. */
2591 return make_number (1 << min (dpyinfo->n_planes, 24));
2594 /* TODO: move to xdisp or similar */
2596 compute_tip_xy (struct frame *f,
2605 Lisp_Object left, top, right, bottom;
2609 /* Start with user-specified or mouse position. */
2610 left = Fcdr (Fassq (Qleft, parms));
2611 top = Fcdr (Fassq (Qtop, parms));
2612 right = Fcdr (Fassq (Qright, parms));
2613 bottom = Fcdr (Fassq (Qbottom, parms));
2615 if ((!INTEGERP (left) && !INTEGERP (right))
2616 || (!INTEGERP (top) && !INTEGERP (bottom)))
2617 pt = [NSEvent mouseLocation];
2620 /* Absolute coordinates. */
2621 pt.x = INTEGERP (left) ? XINT (left) : XINT (right);
2622 pt.y = (x_display_pixel_height (FRAME_DISPLAY_INFO (f))
2623 - (INTEGERP (top) ? XINT (top) : XINT (bottom))
2627 /* Find the screen that pt is on. */
2628 for (screen in [NSScreen screens])
2629 if (pt.x >= screen.frame.origin.x
2630 && pt.x < screen.frame.origin.x + screen.frame.size.width
2631 && pt.y >= screen.frame.origin.y
2632 && pt.y < screen.frame.origin.y + screen.frame.size.height)
2635 /* We could use this instead of the if above:
2637 if (CGRectContainsPoint ([screen frame], pt))
2639 which would be neater, but it causes problems building on old
2640 versions of macOS and in GNUstep. */
2642 /* Ensure in bounds. (Note, screen origin = lower left.) */
2643 if (INTEGERP (left) || INTEGERP (right))
2645 else if (pt.x + XINT (dx) <= screen.frame.origin.x)
2646 *root_x = screen.frame.origin.x;
2647 else if (pt.x + XINT (dx) + width
2648 <= screen.frame.origin.x + screen.frame.size.width)
2649 /* It fits to the right of the pointer. */
2650 *root_x = pt.x + XINT (dx);
2651 else if (width + XINT (dx) <= pt.x)
2652 /* It fits to the left of the pointer. */
2653 *root_x = pt.x - width - XINT (dx);
2655 /* Put it left justified on the screen -- it ought to fit that way. */
2656 *root_x = screen.frame.origin.x;
2658 if (INTEGERP (top) || INTEGERP (bottom))
2660 else if (pt.y - XINT (dy) - height >= screen.frame.origin.y)
2661 /* It fits below the pointer. */
2662 *root_y = pt.y - height - XINT (dy);
2663 else if (pt.y + XINT (dy) + height
2664 <= screen.frame.origin.y + screen.frame.size.height)
2665 /* It fits above the pointer. */
2666 *root_y = pt.y + XINT (dy);
2668 /* Put it on the top. */
2669 *root_y = screen.frame.origin.y + screen.frame.size.height - height;
2673 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
2674 doc: /* SKIP: real doc in xfns.c. */)
2675 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
2678 ptrdiff_t count = SPECPDL_INDEX ();
2685 specbind (Qinhibit_redisplay, Qt);
2687 CHECK_STRING (string);
2688 str = SSDATA (string);
2689 f = decode_window_system_frame (frame);
2691 timeout = make_number (5);
2693 CHECK_NATNUM (timeout);
2696 dx = make_number (5);
2701 dy = make_number (-10);
2706 if (ns_tooltip == nil)
2707 ns_tooltip = [[EmacsTooltip alloc] init];
2711 t = x_get_arg (NULL, parms, Qbackground_color, NULL, NULL, RES_TYPE_STRING);
2712 if (ns_lisp_to_color (t, &color) == 0)
2713 [ns_tooltip setBackgroundColor: color];
2715 t = x_get_arg (NULL, parms, Qforeground_color, NULL, NULL, RES_TYPE_STRING);
2716 if (ns_lisp_to_color (t, &color) == 0)
2717 [ns_tooltip setForegroundColor: color];
2719 [ns_tooltip setText: str];
2720 size = [ns_tooltip frame].size;
2722 /* Move the tooltip window where the mouse pointer is. Resize and
2724 compute_tip_xy (f, parms, dx, dy, (int)size.width, (int)size.height,
2727 [ns_tooltip showAtX: root_x Y: root_y for: XINT (timeout)];
2730 return unbind_to (count, Qnil);
2734 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
2735 doc: /* SKIP: real doc in xfns.c. */)
2738 if (ns_tooltip == nil || ![ns_tooltip isActive])
2744 /* Return geometric attributes of FRAME. According to the value of
2745 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the inner
2746 edges of FRAME, the root window edges of frame (Qroot_edges). Any
2747 other value means to return the geometry as returned by
2748 Fx_frame_geometry. */
2750 frame_geometry (Lisp_Object frame, Lisp_Object attribute)
2752 struct frame *f = decode_live_frame (frame);
2753 Lisp_Object fullscreen_symbol = Fframe_parameter (frame, Qfullscreen);
2754 bool fullscreen = (EQ (fullscreen_symbol, Qfullboth)
2755 || EQ (fullscreen_symbol, Qfullscreen));
2756 int border = fullscreen ? 0 : f->border_width;
2757 int title_height = fullscreen ? 0 : FRAME_NS_TITLEBAR_HEIGHT (f);
2758 int native_width = FRAME_PIXEL_WIDTH (f);
2759 int native_height = FRAME_PIXEL_HEIGHT (f);
2760 int outer_width = native_width + 2 * border;
2761 int outer_height = native_height + 2 * border + title_height;
2762 int native_left = f->left_pos + border;
2763 int native_top = f->top_pos + border + title_height;
2764 int native_right = f->left_pos + outer_width - border;
2765 int native_bottom = f->top_pos + outer_height - border;
2766 int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
2767 int tool_bar_height = FRAME_TOOLBAR_HEIGHT (f);
2768 int tool_bar_width = (tool_bar_height
2769 ? outer_width - 2 * internal_border_width
2772 /* Construct list. */
2773 if (EQ (attribute, Qouter_edges))
2774 return list4 (make_number (f->left_pos), make_number (f->top_pos),
2775 make_number (f->left_pos + outer_width),
2776 make_number (f->top_pos + outer_height));
2777 else if (EQ (attribute, Qnative_edges))
2778 return list4 (make_number (native_left), make_number (native_top),
2779 make_number (native_right), make_number (native_bottom));
2780 else if (EQ (attribute, Qinner_edges))
2781 return list4 (make_number (native_left + internal_border_width),
2782 make_number (native_top
2784 + internal_border_width),
2785 make_number (native_right - internal_border_width),
2786 make_number (native_bottom - internal_border_width));
2789 listn (CONSTYPE_HEAP, 10,
2790 Fcons (Qouter_position,
2791 Fcons (make_number (f->left_pos),
2792 make_number (f->top_pos))),
2794 Fcons (make_number (outer_width),
2795 make_number (outer_height))),
2796 Fcons (Qexternal_border_size,
2798 ? Fcons (make_number (0), make_number (0))
2799 : Fcons (make_number (border), make_number (border)))),
2800 Fcons (Qtitle_bar_size,
2801 Fcons (make_number (0), make_number (title_height))),
2802 Fcons (Qmenu_bar_external, Qnil),
2803 Fcons (Qmenu_bar_size, Fcons (make_number (0), make_number (0))),
2804 Fcons (Qtool_bar_external,
2805 FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil),
2806 Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
2807 Fcons (Qtool_bar_size,
2808 Fcons (make_number (tool_bar_width),
2809 make_number (tool_bar_height))),
2810 Fcons (Qinternal_border_width,
2811 make_number (internal_border_width)));
2814 DEFUN ("ns-frame-geometry", Fns_frame_geometry, Sns_frame_geometry, 0, 1, 0,
2815 doc: /* Return geometric attributes of FRAME.
2816 FRAME must be a live frame and defaults to the selected one. The return
2817 value is an association list of the attributes listed below. All height
2818 and width values are in pixels.
2820 `outer-position' is a cons of the outer left and top edges of FRAME
2821 relative to the origin - the position (0, 0) - of FRAME's display.
2823 `outer-size' is a cons of the outer width and height of FRAME. The
2824 outer size includes the title bar and the external borders as well as
2825 any menu and/or tool bar of frame.
2827 `external-border-size' is a cons of the horizontal and vertical width of
2828 FRAME's external borders as supplied by the window manager.
2830 `title-bar-size' is a cons of the width and height of the title bar of
2831 FRAME as supplied by the window manager. If both of them are zero,
2832 FRAME has no title bar. If only the width is zero, Emacs was not
2833 able to retrieve the width information.
2835 `menu-bar-external', if non-nil, means the menu bar is external (never
2836 included in the inner edges of FRAME).
2838 `menu-bar-size' is a cons of the width and height of the menu bar of
2841 `tool-bar-external', if non-nil, means the tool bar is external (never
2842 included in the inner edges of FRAME).
2844 `tool-bar-position' tells on which side the tool bar on FRAME is and can
2845 be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
2848 `tool-bar-size' is a cons of the width and height of the tool bar of
2851 `internal-border-width' is the width of the internal border of
2855 return frame_geometry (frame, Qnil);
2858 DEFUN ("ns-frame-edges", Fns_frame_edges, Sns_frame_edges, 0, 2, 0,
2859 doc: /* Return edge coordinates of FRAME.
2860 FRAME must be a live frame and defaults to the selected one. The return
2861 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
2862 in pixels relative to the origin - the position (0, 0) - of FRAME's
2865 If optional argument TYPE is the symbol `outer-edges', return the outer
2866 edges of FRAME. The outer edges comprise the decorations of the window
2867 manager (like the title bar or external borders) as well as any external
2868 menu or tool bar of FRAME. If optional argument TYPE is the symbol
2869 `native-edges' or nil, return the native edges of FRAME. The native
2870 edges exclude the decorations of the window manager and any external
2871 menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
2872 the inner edges of FRAME. These edges exclude title bar, any borders,
2873 menu bar or tool bar of FRAME. */)
2874 (Lisp_Object frame, Lisp_Object type)
2876 return frame_geometry (frame, ((EQ (type, Qouter_edges)
2877 || EQ (type, Qinner_edges))
2882 DEFUN ("ns-set-mouse-absolute-pixel-position",
2883 Fns_set_mouse_absolute_pixel_position,
2884 Sns_set_mouse_absolute_pixel_position, 2, 2, 0,
2885 doc: /* Move mouse pointer to absolute pixel position (X, Y).
2886 The coordinates X and Y are interpreted in pixels relative to a position
2887 \(0, 0) of the selected frame's display. */)
2888 (Lisp_Object x, Lisp_Object y)
2890 #ifdef NS_IMPL_COCOA
2891 /* GNUstep doesn't support CGWarpMouseCursorPosition, so none of
2893 struct frame *f = SELECTED_FRAME ();
2894 EmacsView *view = FRAME_NS_VIEW (f);
2895 NSScreen *screen = [[view window] screen];
2896 NSRect screen_frame = [screen frame];
2897 int mouse_x, mouse_y;
2899 NSScreen *primary_screen = [[NSScreen screens] objectAtIndex:0];
2900 NSRect primary_screen_frame = [primary_screen frame];
2901 CGFloat primary_screen_height = primary_screen_frame.size.height;
2903 if (FRAME_INITIAL_P (f) || !FRAME_NS_P (f))
2906 CHECK_TYPE_RANGED_INTEGER (int, x);
2907 CHECK_TYPE_RANGED_INTEGER (int, y);
2909 mouse_x = screen_frame.origin.x + XINT (x);
2911 if (screen == primary_screen)
2912 mouse_y = screen_frame.origin.y + XINT (y);
2914 mouse_y = (primary_screen_height - screen_frame.size.height
2915 - screen_frame.origin.y) + XINT (y);
2917 CGPoint mouse_pos = CGPointMake(mouse_x, mouse_y);
2918 CGWarpMouseCursorPosition (mouse_pos);
2919 #endif /* NS_IMPL_COCOA */
2924 DEFUN ("ns-mouse-absolute-pixel-position",
2925 Fns_mouse_absolute_pixel_position,
2926 Sns_mouse_absolute_pixel_position, 0, 0, 0,
2927 doc: /* Return absolute position of mouse cursor in pixels.
2928 The position is returned as a cons cell (X . Y) of the
2929 coordinates of the mouse cursor position in pixels relative to a
2930 position (0, 0) of the selected frame's terminal. */)
2933 struct frame *f = SELECTED_FRAME ();
2934 EmacsView *view = FRAME_NS_VIEW (f);
2935 NSScreen *screen = [[view window] screen];
2936 NSPoint pt = [NSEvent mouseLocation];
2938 return Fcons(make_number(pt.x - screen.frame.origin.x),
2939 make_number(screen.frame.size.height -
2940 (pt.y - screen.frame.origin.y)));
2943 DEFUN ("ns-show-character-palette",
2944 Fns_show_character_palette,
2945 Sns_show_character_palette, 0, 0, 0,
2946 doc: /* Show the macOS character palette. */)
2949 struct frame *f = SELECTED_FRAME ();
2950 EmacsView *view = FRAME_NS_VIEW (f);
2951 [NSApp orderFrontCharacterPalette:view];
2956 /* ==========================================================================
2958 Class implementations
2960 ========================================================================== */
2963 Handle arrow/function/control keys and copy/paste/cut in file dialogs.
2964 Return YES if handled, NO if not.
2967 handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent)
2973 if ([theEvent type] != NSEventTypeKeyDown) return NO;
2974 s = [theEvent characters];
2976 for (i = 0; i < [s length]; ++i)
2978 int ch = (int) [s characterAtIndex: i];
2981 case NSHomeFunctionKey:
2982 case NSDownArrowFunctionKey:
2983 case NSUpArrowFunctionKey:
2984 case NSLeftArrowFunctionKey:
2985 case NSRightArrowFunctionKey:
2986 case NSPageUpFunctionKey:
2987 case NSPageDownFunctionKey:
2988 case NSEndFunctionKey:
2989 /* Don't send command modified keys, as those are handled in the
2990 performKeyEquivalent method of the super class. */
2991 if (! ([theEvent modifierFlags] & NSEventModifierFlagCommand))
2993 [panel sendEvent: theEvent];
2997 /* As we don't have the standard key commands for
2998 copy/paste/cut/select-all in our edit menu, we must handle
2999 them here. TODO: handle Emacs key bindings for copy/cut/select-all
3000 here, paste works, because we have that in our Edit menu.
3001 I.e. refactor out code in nsterm.m, keyDown: to figure out the
3002 correct modifier. */
3006 case 'a': // Select all
3007 if ([theEvent modifierFlags] & NSEventModifierFlagCommand)
3016 : @selector(selectAll:))))
3021 // Send all control keys, as the text field supports C-a, C-f, C-e
3023 if ([theEvent modifierFlags] & NSEventModifierFlagControl)
3025 [panel sendEvent: theEvent];
3036 @implementation EmacsSavePanel
3037 - (BOOL)performKeyEquivalent:(NSEvent *)theEvent
3039 BOOL ret = handlePanelKeys (self, theEvent);
3041 ret = [super performKeyEquivalent:theEvent];
3047 @implementation EmacsOpenPanel
3048 - (BOOL)performKeyEquivalent:(NSEvent *)theEvent
3050 // NSOpenPanel inherits NSSavePanel, so passing self is OK.
3051 BOOL ret = handlePanelKeys (self, theEvent);
3053 ret = [super performKeyEquivalent:theEvent];
3059 @implementation EmacsFileDelegate
3060 /* --------------------------------------------------------------------------
3061 Delegate methods for Open/Save panels
3062 -------------------------------------------------------------------------- */
3063 - (BOOL)panel: (id)sender isValidFilename: (NSString *)filename
3067 - (BOOL)panel: (id)sender shouldShowFilename: (NSString *)filename
3071 - (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
3072 confirmed: (BOOL)okFlag
3081 /* ==========================================================================
3083 Lisp interface declaration
3085 ========================================================================== */
3089 syms_of_nsfns (void)
3091 DEFSYM (Qfontsize, "fontsize");
3092 DEFSYM (Qframe_title_format, "frame-title-format");
3093 DEFSYM (Qicon_title_format, "icon-title-format");
3094 DEFSYM (Qdark, "dark");
3096 DEFVAR_LISP ("ns-icon-type-alist", Vns_icon_type_alist,
3097 doc: /* Alist of elements (REGEXP . IMAGE) for images of icons associated to frames.
3098 If the title of a frame matches REGEXP, then IMAGE.tiff is
3099 selected as the image of the icon representing the frame when it's
3100 miniaturized. If an element is t, then Emacs tries to select an icon
3101 based on the filetype of the visited file.
3103 The images have to be installed in a folder called English.lproj in the
3104 Emacs folder. You have to restart Emacs after installing new icons.
3106 Example: Install an icon Gnus.tiff and execute the following code
3108 (setq ns-icon-type-alist
3109 (append ns-icon-type-alist
3110 \\='((\"^\\\\*\\\\(Group\\\\*$\\\\|Summary \\\\|Article\\\\*$\\\\)\"
3113 When you miniaturize a Group, Summary or Article frame, Gnus.tiff will
3114 be used as the image of the icon representing the frame. */);
3115 Vns_icon_type_alist = list1 (Qt);
3117 DEFVAR_LISP ("ns-version-string", Vns_version_string,
3118 doc: /* Toolkit version for NS Windowing. */);
3119 Vns_version_string = ns_appkit_version_str ();
3121 DEFVAR_BOOL ("ns-use-proxy-icon", ns_use_proxy_icon,
3122 doc: /* When non-nil display a proxy icon in the titlebar.
3124 ns_use_proxy_icon = true;
3126 defsubr (&Sns_read_file_name);
3127 defsubr (&Sns_get_resource);
3128 defsubr (&Sns_set_resource);
3129 defsubr (&Sxw_display_color_p); /* this and next called directly by C code */
3130 defsubr (&Sx_display_grayscale_p);
3131 defsubr (&Sns_font_name);
3132 defsubr (&Sns_list_colors);
3133 #ifdef NS_IMPL_COCOA
3134 defsubr (&Sns_do_applescript);
3136 defsubr (&Sxw_color_defined_p);
3137 defsubr (&Sxw_color_values);
3138 defsubr (&Sx_server_max_request_size);
3139 defsubr (&Sx_server_vendor);
3140 defsubr (&Sx_server_version);
3141 defsubr (&Sx_display_pixel_width);
3142 defsubr (&Sx_display_pixel_height);
3143 defsubr (&Sns_display_monitor_attributes_list);
3144 defsubr (&Sns_frame_geometry);
3145 defsubr (&Sns_frame_edges);
3146 defsubr (&Sns_frame_list_z_order);
3147 defsubr (&Sns_frame_restack);
3148 defsubr (&Sns_set_mouse_absolute_pixel_position);
3149 defsubr (&Sns_mouse_absolute_pixel_position);
3150 defsubr (&Sns_show_character_palette);
3151 defsubr (&Sx_display_mm_width);
3152 defsubr (&Sx_display_mm_height);
3153 defsubr (&Sx_display_screens);
3154 defsubr (&Sx_display_planes);
3155 defsubr (&Sx_display_color_cells);
3156 defsubr (&Sx_display_visual_class);
3157 defsubr (&Sx_display_backing_store);
3158 defsubr (&Sx_display_save_under);
3159 defsubr (&Sx_create_frame);
3160 defsubr (&Sx_open_connection);
3161 defsubr (&Sx_close_connection);
3162 defsubr (&Sx_display_list);
3164 defsubr (&Sns_hide_others);
3165 defsubr (&Sns_hide_emacs);
3166 defsubr (&Sns_emacs_info_panel);
3167 defsubr (&Sns_list_services);
3168 defsubr (&Sns_perform_service);
3169 defsubr (&Sns_popup_font_panel);
3170 defsubr (&Sns_popup_color_panel);
3172 defsubr (&Sx_show_tip);
3173 defsubr (&Sx_hide_tip);