1 /* Functions for the NeXT/Open/GNUstep and macOS window system.
3 Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2017 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 <http://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);
64 static void ns_set_name_as_filename (struct frame *);
66 /* ==========================================================================
68 Internal utility functions
70 ========================================================================== */
72 /* Let the user specify a Nextstep display with a Lisp object.
73 OBJECT may be nil, a frame or a terminal object.
74 nil stands for the selected frame--or, if that is not a Nextstep frame,
75 the first Nextstep display on the list. */
77 static struct ns_display_info *
78 check_ns_display_info (Lisp_Object object)
80 struct ns_display_info *dpyinfo = NULL;
84 struct frame *sf = XFRAME (selected_frame);
86 if (FRAME_NS_P (sf) && FRAME_LIVE_P (sf))
87 dpyinfo = FRAME_DISPLAY_INFO (sf);
88 else if (x_display_list != 0)
89 dpyinfo = x_display_list;
91 error ("Nextstep windows are not in use or not initialized");
93 else if (TERMINALP (object))
95 struct terminal *t = decode_live_terminal (object);
97 if (t->type != output_ns)
98 error ("Terminal %d is not a Nextstep display", t->id);
100 dpyinfo = t->display_info.ns;
102 else if (STRINGP (object))
103 dpyinfo = ns_display_info_for_name (object);
106 struct frame *f = decode_window_system_frame (object);
107 dpyinfo = FRAME_DISPLAY_INFO (f);
115 ns_get_window (Lisp_Object maybeFrame)
117 id view =nil, window =nil;
119 if (!FRAMEP (maybeFrame) || !FRAME_NS_P (XFRAME (maybeFrame)))
120 maybeFrame = selected_frame;/*wrong_type_argument (Qframep, maybeFrame); */
122 if (!NILP (maybeFrame))
123 view = FRAME_NS_VIEW (XFRAME (maybeFrame));
124 if (view) window =[view window];
130 /* Return the X display structure for the display named NAME.
131 Open a new connection if necessary. */
132 static struct ns_display_info *
133 ns_display_info_for_name (Lisp_Object name)
135 struct ns_display_info *dpyinfo;
139 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
140 if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
143 error ("Emacs for Nextstep does not yet support multi-display");
145 Fx_open_connection (name, Qnil, Qnil);
146 dpyinfo = x_display_list;
149 error ("Display on %s not responding.\n", SDATA (name));
155 ns_filename_from_panel (NSSavePanel *panel)
158 NSURL *url = [panel URL];
159 NSString *str = [url path];
162 return [panel filename];
167 ns_directory_from_panel (NSSavePanel *panel)
170 NSURL *url = [panel directoryURL];
171 NSString *str = [url path];
174 return [panel directory];
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 to
289 update, or it does update and cannot clear old text properly */
290 if (FRAME_VISIBLE_P (f))
294 [f->output_data.ns->background_color release];
295 f->output_data.ns->background_color = col;
297 [col getRed: &r green: &g blue: &b alpha: &alpha];
298 FRAME_BACKGROUND_PIXEL (f) =
299 ARGB_TO_ULONG ((int)(alpha*0xff), (int)(r*0xff), (int)(g*0xff), (int)(b*0xff));
303 [[view window] setBackgroundColor: col];
305 if (alpha != (EmacsCGFloat) 1.0)
306 [[view window] setOpaque: NO];
308 [[view window] setOpaque: YES];
310 face = FRAME_DEFAULT_FACE (f);
313 col = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f);
314 face->background = ns_index_color
315 ([col colorWithAlphaComponent: alpha], f);
317 update_face_from_frame_parameter (f, Qbackground_color, arg);
320 if (FRAME_VISIBLE_P (f))
321 SET_FRAME_GARBAGED (f);
328 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
333 if (ns_lisp_to_color (arg, &col))
335 store_frame_param (f, Qcursor_color, oldval);
337 error ("Unknown color");
340 [FRAME_CURSOR_COLOR (f) release];
341 FRAME_CURSOR_COLOR (f) = [col retain];
343 if (FRAME_VISIBLE_P (f))
345 x_update_cursor (f, 0);
346 x_update_cursor (f, 1);
348 update_face_from_frame_parameter (f, Qcursor_color, arg);
354 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
356 NSView *view = FRAME_NS_VIEW (f);
357 NSTRACE ("x_set_icon_name");
359 /* see if it's changed */
362 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
365 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
368 fset_icon_name (f, arg);
372 if (!NILP (f->title))
375 /* Explicit name and no icon-name -> explicit_name. */
376 if (f->explicit_name)
380 /* No explicit name and no icon-name ->
381 name has to be rebuild from icon_title_format. */
382 windows_or_buffers_changed = 62;
387 /* Don't change the name if it's already NAME. */
388 if ([[view window] miniwindowTitle]
389 && ([[[view window] miniwindowTitle]
390 isEqualToString: [NSString stringWithUTF8String:
394 [[view window] setMiniwindowTitle:
395 [NSString stringWithUTF8String: SSDATA (arg)]];
399 ns_set_name_internal (struct frame *f, Lisp_Object name)
401 Lisp_Object encoded_name, encoded_icon_name;
403 NSView *view = FRAME_NS_VIEW (f);
406 encoded_name = ENCODE_UTF_8 (name);
408 str = [NSString stringWithUTF8String: SSDATA (encoded_name)];
411 /* Don't change the name if it's already NAME. */
412 if (! [[[view window] title] isEqualToString: str])
413 [[view window] setTitle: str];
415 if (!STRINGP (f->icon_name))
416 encoded_icon_name = encoded_name;
418 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
420 str = [NSString stringWithUTF8String: SSDATA (encoded_icon_name)];
422 if ([[view window] miniwindowTitle]
423 && ! [[[view window] miniwindowTitle] isEqualToString: str])
424 [[view window] setMiniwindowTitle: str];
429 ns_set_name (struct frame *f, Lisp_Object name, int explicit)
431 NSTRACE ("ns_set_name");
433 /* Make sure that requests from lisp code override requests from
434 Emacs redisplay code. */
437 /* If we're switching from explicit to implicit, we had better
438 update the mode lines and thereby update the title. */
439 if (f->explicit_name && NILP (name))
440 update_mode_lines = 21;
442 f->explicit_name = ! NILP (name);
444 else if (f->explicit_name)
448 name = build_string ([ns_app_name UTF8String]);
452 /* Don't change the name if it's already NAME. */
453 if (! NILP (Fstring_equal (name, f->name)))
458 /* Title overrides explicit name. */
459 if (! NILP (f->title))
462 ns_set_name_internal (f, name);
466 /* This function should be called when the user's lisp code has
467 specified a name for the frame; the name will override any set by the
470 x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
472 NSTRACE ("x_explicitly_set_name");
473 ns_set_name (f, arg, 1);
477 /* This function should be called by Emacs redisplay code to set the
478 name; names set this way will never override names set by the user's
481 x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
483 NSTRACE ("x_implicitly_set_name");
485 Lisp_Object frame_title = buffer_local_value
486 (Qframe_title_format, XWINDOW (f->selected_window)->contents);
487 Lisp_Object icon_title = buffer_local_value
488 (Qicon_title_format, XWINDOW (f->selected_window)->contents);
490 /* Deal with NS specific format t. */
491 if (FRAME_NS_P (f) && ((FRAME_ICONIFIED_P (f) && EQ (icon_title, Qt))
492 || EQ (frame_title, Qt)))
493 ns_set_name_as_filename (f);
495 ns_set_name (f, arg, 0);
499 /* Change the title of frame F to NAME.
500 If NAME is nil, use the frame name as the title. */
503 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
505 NSTRACE ("x_set_title");
506 /* Don't change the title if it's already NAME. */
507 if (EQ (name, f->title))
510 update_mode_lines = 22;
512 fset_title (f, name);
519 ns_set_name_internal (f, name);
524 ns_set_name_as_filename (struct frame *f)
527 Lisp_Object name, filename;
528 Lisp_Object buf = XWINDOW (f->selected_window)->contents;
530 NSAutoreleasePool *pool;
531 Lisp_Object encoded_name, encoded_filename;
533 NSTRACE ("ns_set_name_as_filename");
535 if (f->explicit_name || ! NILP (f->title))
539 pool = [[NSAutoreleasePool alloc] init];
540 filename = BVAR (XBUFFER (buf), filename);
541 name = BVAR (XBUFFER (buf), name);
545 if (! NILP (filename))
546 name = Ffile_name_nondirectory (filename);
548 name = build_string ([ns_app_name UTF8String]);
551 encoded_name = ENCODE_UTF_8 (name);
553 view = FRAME_NS_VIEW (f);
555 title = FRAME_ICONIFIED_P (f) ? [[[view window] miniwindowTitle] UTF8String]
556 : [[[view window] title] UTF8String];
558 if (title && (! strcmp (title, SSDATA (encoded_name))))
565 str = [NSString stringWithUTF8String: SSDATA (encoded_name)];
566 if (str == nil) str = @"Bad coding";
568 if (FRAME_ICONIFIED_P (f))
569 [[view window] setMiniwindowTitle: str];
574 if (! NILP (filename))
576 encoded_filename = ENCODE_UTF_8 (filename);
578 fstr = [NSString stringWithUTF8String: SSDATA (encoded_filename)];
579 if (fstr == nil) fstr = @"";
584 ns_set_represented_filename (fstr, f);
585 [[view window] setTitle: str];
595 ns_set_doc_edited (void)
597 NSAutoreleasePool *pool;
598 Lisp_Object tail, frame;
600 pool = [[NSAutoreleasePool alloc] init];
601 FOR_EACH_FRAME (tail, frame)
604 struct frame *f = XFRAME (frame);
608 if (! FRAME_NS_P (f)) continue;
609 w = XWINDOW (FRAME_SELECTED_WINDOW (f));
610 view = FRAME_NS_VIEW (f);
611 if (!MINI_WINDOW_P (w))
612 edited = ! NILP (Fbuffer_modified_p (w->contents)) &&
613 ! NILP (Fbuffer_file_name (w->contents));
614 [[view window] setDocumentEdited: edited];
623 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
626 if (FRAME_MINIBUF_ONLY_P (f))
629 if (TYPE_RANGED_INTEGERP (int, value))
630 nlines = XINT (value);
634 FRAME_MENU_BAR_LINES (f) = 0;
637 FRAME_EXTERNAL_MENU_BAR (f) = 1;
638 /* does for all frames, whereas we just want for one frame
639 [NSMenu setMenuBarVisible: YES]; */
643 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
644 free_frame_menubar (f);
645 /* [NSMenu setMenuBarVisible: NO]; */
646 FRAME_EXTERNAL_MENU_BAR (f) = 0;
651 /* toolbar support */
653 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
655 /* Currently, when the tool bar change state, the frame is resized.
657 TODO: It would be better if this didn't occur when 1) the frame
658 is full height or maximized or 2) when specified by
659 `frame-inhibit-implied-resize'. */
662 NSTRACE ("x_set_tool_bar_lines");
664 if (FRAME_MINIBUF_ONLY_P (f))
667 if (RANGED_INTEGERP (0, value, INT_MAX))
668 nlines = XFASTINT (value);
674 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
675 update_frame_tool_bar (f);
679 if (FRAME_EXTERNAL_TOOL_BAR (f))
681 free_frame_tool_bar (f);
682 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
685 EmacsView *view = FRAME_NS_VIEW (f);
686 int fs_state = [view fullscreenState];
688 if (fs_state == FULLSCREEN_MAXIMIZED)
690 [view setFSValue:FULLSCREEN_WIDTH];
692 else if (fs_state == FULLSCREEN_HEIGHT)
694 [view setFSValue:FULLSCREEN_NONE];
702 = ((f->after_make_frame
703 && !f->tool_bar_resized
704 && (EQ (frame_inhibit_implied_resize, Qt)
705 || (CONSP (frame_inhibit_implied_resize)
706 && !NILP (Fmemq (Qtool_bar_lines,
707 frame_inhibit_implied_resize))))
708 && NILP (get_frame_param (f, Qfullscreen)))
712 NSTRACE_MSG ("inhibit:%d", inhibit);
714 frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
715 adjust_frame_size (f, -1, -1, inhibit, 0, Qtool_bar_lines);
721 x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
723 int old_width = FRAME_INTERNAL_BORDER_WIDTH (f);
725 CHECK_TYPE_RANGED_INTEGER (int, arg);
726 f->internal_border_width = XINT (arg);
727 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
728 f->internal_border_width = 0;
730 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old_width)
733 if (FRAME_X_WINDOW (f) != 0)
734 adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
736 SET_FRAME_GARBAGED (f);
741 ns_implicitly_set_icon_type (struct frame *f)
744 EmacsView *view = FRAME_NS_VIEW (f);
746 Lisp_Object chain, elt;
747 NSAutoreleasePool *pool;
750 NSTRACE ("ns_implicitly_set_icon_type");
753 pool = [[NSAutoreleasePool alloc] init];
754 if (f->output_data.ns->miniimage
755 && [[NSString stringWithUTF8String: SSDATA (f->name)]
756 isEqualToString: [(NSImage *)f->output_data.ns->miniimage name]])
763 tem = assq_no_quit (Qicon_type, f->param_alist);
764 if (CONSP (tem) && ! NILP (XCDR (tem)))
771 for (chain = Vns_icon_type_alist;
772 image == nil && CONSP (chain);
773 chain = XCDR (chain))
776 /* special case: t means go by file type */
777 if (SYMBOLP (elt) && EQ (elt, Qt) && SSDATA (f->name)[0] == '/')
780 = [NSString stringWithUTF8String: SSDATA (f->name)];
781 if ([[NSFileManager defaultManager] fileExistsAtPath: str])
782 image = [[[NSWorkspace sharedWorkspace] iconForFile: str] retain];
784 else if (CONSP (elt) &&
785 STRINGP (XCAR (elt)) &&
786 STRINGP (XCDR (elt)) &&
787 fast_string_match (XCAR (elt), f->name) >= 0)
789 image = [EmacsImage allocInitFromFile: XCDR (elt)];
791 image = [[NSImage imageNamed:
792 [NSString stringWithUTF8String:
793 SSDATA (XCDR (elt))]] retain];
799 image = [[[NSWorkspace sharedWorkspace] iconForFileType: @"text"] retain];
803 [f->output_data.ns->miniimage release];
804 f->output_data.ns->miniimage = image;
805 [view setMiniwindowImage: setMini];
812 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
814 EmacsView *view = FRAME_NS_VIEW (f);
818 NSTRACE ("x_set_icon_type");
820 if (!NILP (arg) && SYMBOLP (arg))
822 arg =build_string (SSDATA (SYMBOL_NAME (arg)));
823 store_frame_param (f, Qicon_type, arg);
826 /* do it the implicit way */
829 ns_implicitly_set_icon_type (f);
835 image = [EmacsImage allocInitFromFile: arg];
837 image =[NSImage imageNamed: [NSString stringWithUTF8String:
842 image = [NSImage imageNamed: @"text"];
846 f->output_data.ns->miniimage = image;
847 [view setMiniwindowImage: setMini];
850 /* This is the same as the xfns.c definition. */
852 x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
854 set_frame_cursor_types (f, arg);
857 /* called to set mouse pointer color, but all other terms use it to
858 initialize pointer types (and don't set the color ;) */
860 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
862 /* don't think we can do this on Nextstep */
867 #define Xstr(x) Str(x)
870 ns_appkit_version_str (void)
874 #ifdef NS_IMPL_GNUSTEP
875 sprintf(tmp, "gnustep-gui-%s", Xstr(GNUSTEP_GUI_VERSION));
876 #elif defined (NS_IMPL_COCOA)
878 = [[NSProcessInfo processInfo] operatingSystemVersionString];
879 sprintf(tmp, "appkit-%.2f %s",
880 NSAppKitVersionNumber,
881 [osversion UTF8String]);
885 return build_string (tmp);
889 /* This is for use by x-server-version and collapses all version info we
890 have into a single int. For a better picture of the implementation
891 running, use ns_appkit_version_str.*/
893 ns_appkit_version_int (void)
895 #ifdef NS_IMPL_GNUSTEP
896 return GNUSTEP_GUI_MAJOR_VERSION * 100 + GNUSTEP_GUI_MINOR_VERSION;
897 #elif defined (NS_IMPL_COCOA)
898 return (int)NSAppKitVersionNumber;
905 x_icon (struct frame *f, Lisp_Object parms)
906 /* --------------------------------------------------------------------------
907 Strangely-named function to set icon position parameters in frame.
908 This is irrelevant under macOS, but might be needed under GNUstep,
909 depending on the window manager used. Note, this is not a standard
910 frame parameter-setter; it is called directly from x-create-frame.
911 -------------------------------------------------------------------------- */
913 Lisp_Object icon_x, icon_y;
914 struct ns_display_info *dpyinfo = check_ns_display_info (Qnil);
916 f->output_data.ns->icon_top = -1;
917 f->output_data.ns->icon_left = -1;
919 /* Set the position of the icon. */
920 icon_x = x_get_arg (dpyinfo, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
921 icon_y = x_get_arg (dpyinfo, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
922 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
924 CHECK_NUMBER (icon_x);
925 CHECK_NUMBER (icon_y);
926 f->output_data.ns->icon_top = XINT (icon_y);
927 f->output_data.ns->icon_left = XINT (icon_x);
929 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
930 error ("Both left and top icon corners of icon must be specified");
934 /* Note: see frame.c for template, also where generic functions are impl */
935 frame_parm_handler ns_frame_parm_handlers[] =
937 x_set_autoraise, /* generic OK */
938 x_set_autolower, /* generic OK */
939 x_set_background_color,
940 0, /* x_set_border_color, may be impossible under Nextstep */
941 0, /* x_set_border_width, may be impossible under Nextstep */
944 x_set_font, /* generic OK */
945 x_set_foreground_color,
948 x_set_internal_border_width, /* generic OK */
949 x_set_right_divider_width,
950 x_set_bottom_divider_width,
951 x_set_menu_bar_lines,
953 x_explicitly_set_name,
954 x_set_scroll_bar_width, /* generic OK */
955 x_set_scroll_bar_height, /* generic OK */
957 x_set_unsplittable, /* generic OK */
958 x_set_vertical_scroll_bars, /* generic OK */
959 x_set_horizontal_scroll_bars, /* generic OK */
960 x_set_visibility, /* generic OK */
961 x_set_tool_bar_lines,
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_left_fringe, /* generic OK */
967 x_set_right_fringe, /* generic OK */
968 0, /* x_set_wait_for_wm, will ignore */
969 x_set_fullscreen, /* generic OK */
970 x_set_font_backend, /* generic OK */
972 0, /* x_set_sticky */
973 0, /* x_set_tool_bar_position */
974 0, /* x_set_inhibit_double_buffering */
978 /* Handler for signals raised during x_create_frame.
979 FRAME is the frame which is partially constructed. */
982 unwind_create_frame (Lisp_Object frame)
984 struct frame *f = XFRAME (frame);
986 /* If frame is already dead, nothing to do. This can happen if the
987 display is disconnected after the frame has become official, but
988 before x_create_frame removes the unwind protect. */
989 if (!FRAME_LIVE_P (f))
992 /* If frame is ``official'', nothing to do. */
993 if (NILP (Fmemq (frame, Vframe_list)))
995 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
996 struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
999 /* If the frame's image cache refcount is still the same as our
1000 private shadow variable, it means we are unwinding a frame
1001 for which we didn't yet call init_frame_faces, where the
1002 refcount is incremented. Therefore, we increment it here, so
1003 that free_frame_faces, called in x_free_frame_resources
1004 below, will not mistakenly decrement the counter that was not
1005 incremented yet to account for this new frame. */
1006 if (FRAME_IMAGE_CACHE (f) != NULL
1007 && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount)
1008 FRAME_IMAGE_CACHE (f)->refcount++;
1010 x_free_frame_resources (f);
1013 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
1014 /* Check that reference counts are indeed correct. */
1015 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
1021 * Read geometry related parameters from preferences if not in PARMS.
1022 * Returns the union of parms and any preferences read.
1026 get_geometry_from_preferences (struct ns_display_info *dpyinfo,
1034 { "width", "Width", Qwidth },
1035 { "height", "Height", Qheight },
1036 { "left", "Left", Qleft },
1037 { "top", "Top", Qtop },
1041 for (i = 0; i < ARRAYELTS (r); ++i)
1043 if (NILP (Fassq (r[i].tem, parms)))
1046 = x_get_arg (dpyinfo, parms, r[i].tem, r[i].val, r[i].cls,
1048 if (! EQ (value, Qunbound))
1049 parms = Fcons (Fcons (r[i].tem, value), parms);
1056 /* ==========================================================================
1060 ========================================================================== */
1062 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1064 doc: /* Make a new Nextstep window, called a "frame" in Emacs terms.
1065 Return an Emacs frame object.
1066 PARMS is an alist of frame parameters.
1067 If the parameters specify that the frame should not have a minibuffer,
1068 and do not specify a specific minibuffer window to use,
1069 then `default-minibuffer-frame' must be a frame whose minibuffer can
1070 be shared by the new frame.
1072 This function is an internal primitive--use `make-frame' instead. */)
1076 Lisp_Object frame, tem;
1078 int minibuffer_only = 0;
1079 long window_prompting = 0;
1080 ptrdiff_t count = specpdl_ptr - specpdl;
1081 Lisp_Object display;
1082 struct ns_display_info *dpyinfo = NULL;
1085 static int desc_ctr = 1;
1086 int x_width = 0, x_height = 0;
1088 /* x_get_arg modifies parms. */
1089 parms = Fcopy_alist (parms);
1091 /* Use this general default value to start with
1092 until we know if this frame has a specified name. */
1093 Vx_resource_name = Vinvocation_name;
1095 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_STRING);
1096 if (EQ (display, Qunbound))
1098 dpyinfo = check_ns_display_info (display);
1099 kb = dpyinfo->terminal->kboard;
1101 if (!dpyinfo->terminal->name)
1102 error ("Terminal is not live, can't create new frames on it");
1104 name = x_get_arg (dpyinfo, parms, Qname, 0, 0, RES_TYPE_STRING);
1106 && ! EQ (name, Qunbound)
1108 error ("Invalid frame name--not a string or nil");
1111 Vx_resource_name = name;
1113 parent = x_get_arg (dpyinfo, parms, Qparent_id, 0, 0, RES_TYPE_NUMBER);
1114 if (EQ (parent, Qunbound))
1116 if (! NILP (parent))
1117 CHECK_NUMBER (parent);
1119 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
1120 /* No need to protect DISPLAY because that's not used after passing
1121 it to make_frame_without_minibuffer. */
1123 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
1125 if (EQ (tem, Qnone) || NILP (tem))
1126 f = make_frame_without_minibuffer (Qnil, kb, display);
1127 else if (EQ (tem, Qonly))
1129 f = make_minibuffer_frame ();
1130 minibuffer_only = 1;
1132 else if (WINDOWP (tem))
1133 f = make_frame_without_minibuffer (tem, kb, display);
1137 XSETFRAME (frame, f);
1139 f->terminal = dpyinfo->terminal;
1141 f->output_method = output_ns;
1142 f->output_data.ns = xzalloc (sizeof *f->output_data.ns);
1144 FRAME_FONTSET (f) = -1;
1146 fset_icon_name (f, x_get_arg (dpyinfo, parms, Qicon_name,
1147 "iconName", "Title",
1149 if (! STRINGP (f->icon_name))
1150 fset_icon_name (f, Qnil);
1152 FRAME_DISPLAY_INFO (f) = dpyinfo;
1154 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
1155 record_unwind_protect (unwind_create_frame, frame);
1157 f->output_data.ns->window_desc = desc_ctr++;
1158 if (TYPE_RANGED_INTEGERP (Window, parent))
1160 f->output_data.ns->parent_desc = XFASTINT (parent);
1161 f->output_data.ns->explicit_parent = 1;
1165 f->output_data.ns->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
1166 f->output_data.ns->explicit_parent = 0;
1169 /* Set the name; the functions to which we pass f expect the name to
1171 if (EQ (name, Qunbound) || NILP (name) || ! STRINGP (name))
1173 fset_name (f, build_string ([ns_app_name UTF8String]));
1174 f->explicit_name = 0;
1178 fset_name (f, name);
1179 f->explicit_name = 1;
1180 specbind (Qx_resource_name, name);
1185 #ifdef NS_IMPL_COCOA
1186 mac_register_font_driver (f);
1188 register_font_driver (&nsfont_driver, f);
1191 image_cache_refcount =
1192 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
1194 x_default_parameter (f, parms, Qfont_backend, Qnil,
1195 "fontBackend", "FontBackend", RES_TYPE_STRING);
1198 /* use for default font name */
1199 id font = [NSFont userFixedPitchFontOfSize: -1.0]; /* default */
1200 x_default_parameter (f, parms, Qfontsize,
1201 make_number (0 /*(int)[font pointSize]*/),
1202 "fontSize", "FontSize", RES_TYPE_NUMBER);
1203 // Remove ' Regular', not handled by backends.
1204 char *fontname = xstrdup ([[font displayName] UTF8String]);
1205 int len = strlen (fontname);
1206 if (len > 8 && strcmp (fontname + len - 8, " Regular") == 0)
1207 fontname[len-8] = '\0';
1208 x_default_parameter (f, parms, Qfont,
1209 build_string (fontname),
1210 "font", "Font", RES_TYPE_STRING);
1215 x_default_parameter (f, parms, Qborder_width, make_number (0),
1216 "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
1217 x_default_parameter (f, parms, Qinternal_border_width, make_number (2),
1218 "internalBorderWidth", "InternalBorderWidth",
1221 /* default vertical scrollbars on right on Mac */
1224 #ifdef NS_IMPL_GNUSTEP
1229 x_default_parameter (f, parms, Qvertical_scroll_bars, spos,
1230 "verticalScrollBars", "VerticalScrollBars",
1233 x_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
1234 "horizontalScrollBars", "HorizontalScrollBars",
1236 x_default_parameter (f, parms, Qforeground_color, build_string ("Black"),
1237 "foreground", "Foreground", RES_TYPE_STRING);
1238 x_default_parameter (f, parms, Qbackground_color, build_string ("White"),
1239 "background", "Background", RES_TYPE_STRING);
1240 /* FIXME: not supported yet in Nextstep */
1241 x_default_parameter (f, parms, Qline_spacing, Qnil,
1242 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
1243 x_default_parameter (f, parms, Qleft_fringe, Qnil,
1244 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
1245 x_default_parameter (f, parms, Qright_fringe, Qnil,
1246 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
1248 init_frame_faces (f);
1250 /* Read comment about this code in corresponding place in xfns.c. */
1251 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
1252 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1,
1255 /* The resources controlling the menu-bar and tool-bar are
1256 processed specially at startup, and reflected in the mode
1257 variables; ignore them here. */
1258 x_default_parameter (f, parms, Qmenu_bar_lines,
1259 NILP (Vmenu_bar_mode)
1260 ? make_number (0) : make_number (1),
1261 NULL, NULL, RES_TYPE_NUMBER);
1262 x_default_parameter (f, parms, Qtool_bar_lines,
1263 NILP (Vtool_bar_mode)
1264 ? make_number (0) : make_number (1),
1265 NULL, NULL, RES_TYPE_NUMBER);
1267 x_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate",
1268 "BufferPredicate", RES_TYPE_SYMBOL);
1269 x_default_parameter (f, parms, Qtitle, Qnil, "title", "Title",
1272 parms = get_geometry_from_preferences (dpyinfo, parms);
1273 window_prompting = x_figure_window_size (f, parms, true, &x_width, &x_height);
1275 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
1276 f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !EQ (tem, Qnil));
1278 /* NOTE: on other terms, this is done in set_mouse_color, however this
1279 was not getting called under Nextstep */
1280 f->output_data.ns->text_cursor = [NSCursor IBeamCursor];
1281 f->output_data.ns->nontext_cursor = [NSCursor arrowCursor];
1282 f->output_data.ns->modeline_cursor = [NSCursor pointingHandCursor];
1283 f->output_data.ns->hand_cursor = [NSCursor pointingHandCursor];
1284 f->output_data.ns->hourglass_cursor = [NSCursor disappearingItemCursor];
1285 f->output_data.ns->horizontal_drag_cursor = [NSCursor resizeLeftRightCursor];
1286 f->output_data.ns->vertical_drag_cursor = [NSCursor resizeUpDownCursor];
1287 FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor
1288 = [NSCursor arrowCursor];
1289 FRAME_DISPLAY_INFO (f)->horizontal_scroll_bar_cursor
1290 = [NSCursor arrowCursor];
1291 f->output_data.ns->current_pointer = f->output_data.ns->text_cursor;
1293 f->output_data.ns->in_animation = NO;
1295 [[EmacsView alloc] initFrameFromEmacs: f];
1299 /* ns_display_info does not have a reference_count. */
1300 f->terminal->reference_count++;
1302 /* It is now ok to make the frame official even if we get an error below.
1303 The frame needs to be on Vframe_list or making it visible won't work. */
1304 Vframe_list = Fcons (frame, Vframe_list);
1306 x_default_parameter (f, parms, Qicon_type, Qnil,
1307 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
1309 x_default_parameter (f, parms, Qauto_raise, Qnil,
1310 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
1311 x_default_parameter (f, parms, Qauto_lower, Qnil,
1312 "autoLower", "AutoLower", RES_TYPE_BOOLEAN);
1313 x_default_parameter (f, parms, Qcursor_type, Qbox,
1314 "cursorType", "CursorType", RES_TYPE_SYMBOL);
1315 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
1316 "scrollBarWidth", "ScrollBarWidth",
1318 x_default_parameter (f, parms, Qscroll_bar_height, Qnil,
1319 "scrollBarHeight", "ScrollBarHeight",
1321 x_default_parameter (f, parms, Qalpha, Qnil,
1322 "alpha", "Alpha", RES_TYPE_NUMBER);
1323 x_default_parameter (f, parms, Qfullscreen, Qnil,
1324 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
1326 /* Allow x_set_window_size, now. */
1327 f->can_x_set_window_size = true;
1330 SET_FRAME_WIDTH (f, x_width);
1332 SET_FRAME_HEIGHT (f, x_height);
1334 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1,
1337 if (! f->output_data.ns->explicit_parent)
1339 Lisp_Object visibility;
1341 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
1343 if (EQ (visibility, Qunbound))
1346 if (EQ (visibility, Qicon))
1347 x_iconify_frame (f);
1348 else if (! NILP (visibility))
1350 x_make_frame_visible (f);
1351 [[FRAME_NS_VIEW (f) window] makeKeyWindow];
1355 /* Must have been Qnil. */
1359 if (FRAME_HAS_MINIBUF_P (f)
1360 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
1361 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
1362 kset_default_minibuffer_frame (kb, frame);
1364 /* All remaining specified parameters, which have not been "used"
1365 by x_get_arg and friends, now go in the misc. alist of the frame. */
1366 for (tem = parms; CONSP (tem); tem = XCDR (tem))
1367 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
1368 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
1370 if (window_prompting & USPosition)
1371 x_set_offset (f, f->left_pos, f->top_pos, 1);
1373 /* Make sure windows on this frame appear in calls to next-window
1374 and similar functions. */
1375 Vwindow_list = Qnil;
1377 return unbind_to (count, frame);
1381 x_focus_frame (struct frame *f)
1383 struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1385 if (dpyinfo->x_focus_frame != f)
1387 EmacsView *view = FRAME_NS_VIEW (f);
1389 [NSApp activateIgnoringOtherApps: YES];
1390 [[view window] makeKeyAndOrderFront: view];
1396 DEFUN ("ns-popup-font-panel", Fns_popup_font_panel, Sns_popup_font_panel,
1398 doc: /* Pop up the font panel. */)
1401 struct frame *f = decode_window_system_frame (frame);
1402 id fm = [NSFontManager sharedFontManager];
1403 struct font *font = f->output_data.ns->font;
1405 #ifdef NS_IMPL_GNUSTEP
1406 nsfont = ((struct nsfont_info *)font)->nsfont;
1408 #ifdef NS_IMPL_COCOA
1409 nsfont = (NSFont *) macfont_get_nsctfont (font);
1411 [fm setSelectedFont: nsfont isMultiple: NO];
1412 [fm orderFrontFontPanel: NSApp];
1417 DEFUN ("ns-popup-color-panel", Fns_popup_color_panel, Sns_popup_color_panel,
1419 doc: /* Pop up the color panel. */)
1422 check_window_system (NULL);
1423 [NSApp orderFrontColorPanel: NSApp];
1431 #ifdef NS_IMPL_GNUSTEP
1432 NSString *dirS, *initS;
1438 ns_run_file_dialog (void)
1440 if (ns_fd_data.panel == nil) return;
1441 #ifdef NS_IMPL_COCOA
1442 ns_fd_data.ret = [ns_fd_data.panel runModal];
1444 if (ns_fd_data.no_types)
1446 ns_fd_data.ret = [ns_fd_data.panel
1447 runModalForDirectory: ns_fd_data.dirS
1448 file: ns_fd_data.initS];
1452 ns_fd_data.ret = [ns_fd_data.panel
1453 runModalForDirectory: ns_fd_data.dirS
1454 file: ns_fd_data.initS
1458 ns_fd_data.panel = nil;
1461 #ifdef NS_IMPL_COCOA
1462 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9
1463 #define MODAL_OK_RESPONSE NSModalResponseOK
1466 #ifndef MODAL_OK_RESPONSE
1467 #define MODAL_OK_RESPONSE NSOKButton
1470 DEFUN ("ns-read-file-name", Fns_read_file_name, Sns_read_file_name, 1, 5, 0,
1471 doc: /* Use a graphical panel to read a file name, using prompt PROMPT.
1472 Optional arg DIR, if non-nil, supplies a default directory.
1473 Optional arg MUSTMATCH, if non-nil, means the returned file or
1474 directory must exist.
1475 Optional arg INIT, if non-nil, provides a default file name to use.
1476 Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1477 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object mustmatch,
1478 Lisp_Object init, Lisp_Object dir_only_p)
1480 static id fileDelegate = nil;
1481 BOOL isSave = NILP (mustmatch) && NILP (dir_only_p);
1483 Lisp_Object fname = Qnil;
1485 NSString *promptS = NILP (prompt) || !STRINGP (prompt) ? nil :
1486 [NSString stringWithUTF8String: SSDATA (prompt)];
1487 NSString *dirS = NILP (dir) || !STRINGP (dir) ?
1488 [NSString stringWithUTF8String: SSDATA (BVAR (current_buffer, directory))] :
1489 [NSString stringWithUTF8String: SSDATA (dir)];
1490 NSString *initS = NILP (init) || !STRINGP (init) ? nil :
1491 [NSString stringWithUTF8String: SSDATA (init)];
1494 check_window_system (NULL);
1496 if (fileDelegate == nil)
1497 fileDelegate = [EmacsFileDelegate new];
1499 [NSCursor setHiddenUntilMouseMoves: NO];
1501 if ([dirS characterAtIndex: 0] == '~')
1502 dirS = [dirS stringByExpandingTildeInPath];
1505 (id)[EmacsSavePanel savePanel] : (id)[EmacsOpenPanel openPanel];
1507 [panel setTitle: promptS];
1509 [panel setAllowsOtherFileTypes: YES];
1510 [panel setTreatsFilePackagesAsDirectories: YES];
1511 [panel setDelegate: fileDelegate];
1513 if (! NILP (dir_only_p))
1515 [panel setCanChooseDirectories: YES];
1516 [panel setCanChooseFiles: NO];
1520 /* This is not quite what the documentation says, but it is compatible
1521 with the Gtk+ code. Also, the menu entry says "Open File...". */
1522 [panel setCanChooseDirectories: NO];
1523 [panel setCanChooseFiles: YES];
1527 ns_fd_data.panel = panel;
1528 ns_fd_data.ret = NO;
1529 #ifdef NS_IMPL_COCOA
1530 if (! NILP (mustmatch) || ! NILP (dir_only_p))
1531 [panel setAllowedFileTypes: nil];
1532 if (dirS) [panel setDirectoryURL: [NSURL fileURLWithPath: dirS]];
1533 if (initS && NILP (Ffile_directory_p (init)))
1534 [panel setNameFieldStringValue: [initS lastPathComponent]];
1536 [panel setNameFieldStringValue: @""];
1539 ns_fd_data.no_types = NILP (mustmatch) && NILP (dir_only_p);
1540 ns_fd_data.dirS = dirS;
1541 ns_fd_data.initS = initS;
1544 /* runModalForDirectory/runModal restarts the main event loop when done,
1545 so we must start an event loop and then pop up the file dialog.
1546 The file dialog may pop up a confirm dialog after Ok has been pressed,
1547 so we can not simply pop down on the Ok/Cancel press.
1549 nxev = [NSEvent otherEventWithType: NSEventTypeApplicationDefined
1550 location: NSMakePoint (0, 0)
1553 windowNumber: [[NSApp mainWindow] windowNumber]
1554 context: [NSApp context]
1557 data2: NSAPP_DATA2_RUNFILEDIALOG];
1559 [NSApp postEvent: nxev atStart: NO];
1560 while (ns_fd_data.panel != nil)
1563 if (ns_fd_data.ret == MODAL_OK_RESPONSE)
1565 NSString *str = ns_filename_from_panel (panel);
1566 if (! str) str = ns_directory_from_panel (panel);
1567 if (str) fname = build_string ([str UTF8String]);
1570 [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
1577 ns_get_defaults_value (const char *key)
1579 NSObject *obj = [[NSUserDefaults standardUserDefaults]
1580 objectForKey: [NSString stringWithUTF8String: key]];
1582 if (!obj) return NULL;
1584 return [[NSString stringWithFormat: @"%@", obj] UTF8String];
1588 DEFUN ("ns-get-resource", Fns_get_resource, Sns_get_resource, 2, 2, 0,
1589 doc: /* Return the value of the property NAME of OWNER from the defaults database.
1590 If OWNER is nil, Emacs is assumed. */)
1591 (Lisp_Object owner, Lisp_Object name)
1595 check_window_system (NULL);
1597 owner = build_string([ns_app_name UTF8String]);
1598 CHECK_STRING (name);
1600 value = ns_get_defaults_value (SSDATA (name));
1603 return build_string (value);
1608 DEFUN ("ns-set-resource", Fns_set_resource, Sns_set_resource, 3, 3, 0,
1609 doc: /* Set property NAME of OWNER to VALUE, from the defaults database.
1610 If OWNER is nil, Emacs is assumed.
1611 If VALUE is nil, the default is removed. */)
1612 (Lisp_Object owner, Lisp_Object name, Lisp_Object value)
1614 check_window_system (NULL);
1616 owner = build_string ([ns_app_name UTF8String]);
1617 CHECK_STRING (name);
1620 [[NSUserDefaults standardUserDefaults] removeObjectForKey:
1621 [NSString stringWithUTF8String: SSDATA (name)]];
1625 CHECK_STRING (value);
1626 [[NSUserDefaults standardUserDefaults] setObject:
1627 [NSString stringWithUTF8String: SSDATA (value)]
1628 forKey: [NSString stringWithUTF8String:
1636 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
1637 Sx_server_max_request_size,
1639 doc: /* This function is a no-op. It is only present for completeness. */)
1640 (Lisp_Object terminal)
1642 check_ns_display_info (terminal);
1643 /* This function has no real equivalent under NeXTstep. Return nil to
1649 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
1650 doc: /* Return the "vendor ID" string of Nextstep display server TERMINAL.
1651 \(Labeling every distributor as a "vendor" embodies the false assumption
1652 that operating systems cannot be developed and distributed noncommercially.)
1653 The optional argument TERMINAL specifies which display to ask about.
1654 TERMINAL should be a terminal object, a frame or a display name (a string).
1655 If omitted or nil, that stands for the selected frame's display. */)
1656 (Lisp_Object terminal)
1658 check_ns_display_info (terminal);
1659 #ifdef NS_IMPL_GNUSTEP
1660 return build_string ("GNU");
1662 return build_string ("Apple");
1667 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
1668 doc: /* Return the version numbers of the server of display TERMINAL.
1669 The value is a list of three integers: the major and minor
1670 version numbers of the X Protocol in use, and the distributor-specific release
1671 number. See also the function `x-server-vendor'.
1673 The optional argument TERMINAL specifies which display to ask about.
1674 TERMINAL should be a terminal object, a frame or a display name (a string).
1675 If omitted or nil, that stands for the selected frame's display. */)
1676 (Lisp_Object terminal)
1678 check_ns_display_info (terminal);
1679 /*NOTE: it is unclear what would best correspond with "protocol";
1680 we return 10.3, meaning Panther, since this is roughly the
1681 level that GNUstep's APIs correspond to.
1682 The last number is where we distinguish between the Apple
1683 and GNUstep implementations ("distributor-specific release
1684 number") and give int'ized versions of major.minor. */
1685 return list3i (10, 3, ns_appkit_version_int ());
1689 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
1690 doc: /* Return the number of screens on Nextstep display server TERMINAL.
1691 The optional argument TERMINAL specifies which display to ask about.
1692 TERMINAL should be a terminal object, a frame or a display name (a string).
1693 If omitted or nil, that stands for the selected frame's display.
1695 Note: "screen" here is not in Nextstep terminology but in X11's. For
1696 the number of physical monitors, use `(length
1697 \(display-monitor-attributes-list TERMINAL))' instead. */)
1698 (Lisp_Object terminal)
1700 check_ns_display_info (terminal);
1701 return make_number (1);
1705 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
1706 doc: /* Return the height in millimeters of the Nextstep display TERMINAL.
1707 The optional argument TERMINAL specifies which display to ask about.
1708 TERMINAL should be a terminal object, a frame or a display name (a string).
1709 If omitted or nil, that stands for the selected frame's display.
1711 On \"multi-monitor\" setups this refers to the height in millimeters for
1712 all physical monitors associated with TERMINAL. To get information
1713 for each physical monitor, use `display-monitor-attributes-list'. */)
1714 (Lisp_Object terminal)
1716 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
1718 return make_number (x_display_pixel_height (dpyinfo) / (92.0/25.4));
1722 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
1723 doc: /* Return the width in millimeters of the Nextstep display TERMINAL.
1724 The optional argument TERMINAL specifies which display to ask about.
1725 TERMINAL should be a terminal object, a frame or a display name (a string).
1726 If omitted or nil, that stands for the selected frame's display.
1728 On \"multi-monitor\" setups this refers to the width in millimeters for
1729 all physical monitors associated with TERMINAL. To get information
1730 for each physical monitor, use `display-monitor-attributes-list'. */)
1731 (Lisp_Object terminal)
1733 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
1735 return make_number (x_display_pixel_width (dpyinfo) / (92.0/25.4));
1739 DEFUN ("x-display-backing-store", Fx_display_backing_store,
1740 Sx_display_backing_store, 0, 1, 0,
1741 doc: /* Return an indication of whether the Nextstep display TERMINAL does backing store.
1742 The value may be `buffered', `retained', or `non-retained'.
1743 The optional argument TERMINAL specifies which display to ask about.
1744 TERMINAL should be a terminal object, a frame or a display name (a string).
1745 If omitted or nil, that stands for the selected frame's display. */)
1746 (Lisp_Object terminal)
1748 check_ns_display_info (terminal);
1749 switch ([ns_get_window (terminal) backingType])
1751 case NSBackingStoreBuffered:
1752 return intern ("buffered");
1753 case NSBackingStoreRetained:
1754 return intern ("retained");
1755 case NSBackingStoreNonretained:
1756 return intern ("non-retained");
1758 error ("Strange value for backingType parameter of frame");
1760 return Qnil; /* not reached, shut compiler up */
1764 DEFUN ("x-display-visual-class", Fx_display_visual_class,
1765 Sx_display_visual_class, 0, 1, 0,
1766 doc: /* Return the visual class of the Nextstep display TERMINAL.
1767 The value is one of the symbols `static-gray', `gray-scale',
1768 `static-color', `pseudo-color', `true-color', or `direct-color'.
1770 The optional argument TERMINAL specifies which display to ask about.
1771 TERMINAL should a terminal object, a frame or a display name (a string).
1772 If omitted or nil, that stands for the selected frame's display. */)
1773 (Lisp_Object terminal)
1775 NSWindowDepth depth;
1777 check_ns_display_info (terminal);
1778 depth = [[[NSScreen screens] objectAtIndex:0] depth];
1780 if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
1781 return intern ("static-gray");
1782 else if (depth == NSBestDepth (NSCalibratedWhiteColorSpace, 8, 8, YES, NULL))
1783 return intern ("gray-scale");
1784 else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 8, 8, YES, NULL))
1785 return intern ("pseudo-color");
1786 else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 4, 12, NO, NULL))
1787 return intern ("true-color");
1788 else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 8, 24, NO, NULL))
1789 return intern ("direct-color");
1791 /* color mgmt as far as we do it is really handled by Nextstep itself anyway */
1792 return intern ("direct-color");
1796 DEFUN ("x-display-save-under", Fx_display_save_under,
1797 Sx_display_save_under, 0, 1, 0,
1798 doc: /* Return t if TERMINAL supports the save-under feature.
1799 The optional argument TERMINAL specifies which display to ask about.
1800 TERMINAL should be a terminal object, a frame or a display name (a string).
1801 If omitted or nil, that stands for the selected frame's display. */)
1802 (Lisp_Object terminal)
1804 check_ns_display_info (terminal);
1805 switch ([ns_get_window (terminal) backingType])
1807 case NSBackingStoreBuffered:
1810 case NSBackingStoreRetained:
1811 case NSBackingStoreNonretained:
1815 error ("Strange value for backingType parameter of frame");
1817 return Qnil; /* not reached, shut compiler up */
1821 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
1823 doc: /* Open a connection to a display server.
1824 DISPLAY is the name of the display to connect to.
1825 Optional second arg XRM-STRING is a string of resources in xrdb format.
1826 If the optional third arg MUST-SUCCEED is non-nil,
1827 terminate Emacs if we can't open the connection.
1828 \(In the Nextstep version, the last two arguments are currently ignored.) */)
1829 (Lisp_Object display, Lisp_Object resource_string, Lisp_Object must_succeed)
1831 struct ns_display_info *dpyinfo;
1833 CHECK_STRING (display);
1835 nxatoms_of_nsselect ();
1836 dpyinfo = ns_term_init (display);
1839 if (!NILP (must_succeed))
1840 fatal ("Display on %s not responding.\n",
1843 error ("Display on %s not responding.\n",
1851 DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection,
1853 doc: /* Close the connection to TERMINAL's Nextstep display server.
1854 For TERMINAL, specify a terminal object, a frame or a display name (a
1855 string). If TERMINAL is nil, that stands for the selected frame's
1857 (Lisp_Object terminal)
1859 check_ns_display_info (terminal);
1860 [NSApp terminate: NSApp];
1865 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
1866 doc: /* Return the list of display names that Emacs has connections to. */)
1869 Lisp_Object result = Qnil;
1870 struct ns_display_info *ndi;
1872 for (ndi = x_display_list; ndi; ndi = ndi->next)
1873 result = Fcons (XCAR (ndi->name_list_element), result);
1879 DEFUN ("ns-hide-others", Fns_hide_others, Sns_hide_others,
1881 doc: /* Hides all applications other than Emacs. */)
1884 check_window_system (NULL);
1885 [NSApp hideOtherApplications: NSApp];
1889 DEFUN ("ns-hide-emacs", Fns_hide_emacs, Sns_hide_emacs,
1891 doc: /* If ON is non-nil, the entire Emacs application is hidden.
1892 Otherwise if Emacs is hidden, it is unhidden.
1893 If ON is equal to `activate', Emacs is unhidden and becomes
1894 the active application. */)
1897 check_window_system (NULL);
1898 if (EQ (on, intern ("activate")))
1900 [NSApp unhide: NSApp];
1901 [NSApp activateIgnoringOtherApps: YES];
1904 [NSApp unhide: NSApp];
1906 [NSApp hide: NSApp];
1911 DEFUN ("ns-emacs-info-panel", Fns_emacs_info_panel, Sns_emacs_info_panel,
1913 doc: /* Shows the 'Info' or 'About' panel for Emacs. */)
1916 check_window_system (NULL);
1917 [NSApp orderFrontStandardAboutPanel: nil];
1922 DEFUN ("ns-font-name", Fns_font_name, Sns_font_name, 1, 1, 0,
1923 doc: /* Determine font PostScript or family name for font NAME.
1924 NAME should be a string containing either the font name or an XLFD
1925 font descriptor. If string contains `fontset' and not
1926 `fontset-startup', it is left alone. */)
1930 CHECK_STRING (name);
1935 if (strstr (nm, "fontset") && !strstr (nm, "fontset-startup"))
1938 return build_string (ns_xlfd_to_fontname (SSDATA (name)));
1942 DEFUN ("ns-list-colors", Fns_list_colors, Sns_list_colors, 0, 1, 0,
1943 doc: /* Return a list of all available colors.
1944 The optional argument FRAME is currently ignored. */)
1947 Lisp_Object list = Qnil;
1948 NSEnumerator *colorlists;
1953 CHECK_FRAME (frame);
1954 if (! FRAME_NS_P (XFRAME (frame)))
1955 error ("non-Nextstep frame used in `ns-list-colors'");
1960 colorlists = [[NSColorList availableColorLists] objectEnumerator];
1961 while ((clist = [colorlists nextObject]))
1963 if ([[clist name] length] < 7 ||
1964 [[clist name] rangeOfString: @"PANTONE"].location == 0)
1966 NSEnumerator *cnames = [[clist allKeys] reverseObjectEnumerator];
1968 while ((cname = [cnames nextObject]))
1969 list = Fcons (build_string ([cname UTF8String]), list);
1970 /* for (i = [[clist allKeys] count] - 1; i >= 0; i--)
1971 list = Fcons (build_string ([[[clist allKeys] objectAtIndex: i]
1972 UTF8String]), list); */
1982 DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0,
1983 doc: /* List available Nextstep services by querying NSApp. */)
1986 #ifdef NS_IMPL_COCOA
1987 /* You can't get services like this in 10.6+. */
1990 Lisp_Object ret = Qnil;
1992 #ifdef NS_IMPL_COCOA
1996 check_window_system (NULL);
1997 svcs = [[NSMenu alloc] initWithTitle: @"Services"];
1998 [NSApp setServicesMenu: svcs];
1999 [NSApp registerServicesMenuSendTypes: ns_send_types
2000 returnTypes: ns_return_types];
2002 /* On Tiger, services menu updating was made lazier (waits for user to
2003 actually click on the menu), so we have to force things along: */
2004 #ifdef NS_IMPL_COCOA
2005 delegate = [svcs delegate];
2006 if (delegate != nil)
2008 if ([delegate respondsToSelector: @selector (menuNeedsUpdate:)])
2009 [delegate menuNeedsUpdate: svcs];
2010 if ([delegate respondsToSelector:
2011 @selector (menu:updateItem:atIndex:shouldCancel:)])
2013 int i, len = [delegate numberOfItemsInMenu: svcs];
2014 for (i =0; i<len; i++)
2015 [svcs addItemWithTitle: @"" action: NULL keyEquivalent: @""];
2016 for (i =0; i<len; i++)
2017 if (![delegate menu: svcs
2018 updateItem: (NSMenuItem *)[svcs itemAtIndex: i]
2019 atIndex: i shouldCancel: NO])
2025 [svcs setAutoenablesItems: NO];
2026 #ifdef NS_IMPL_COCOA
2027 [svcs update]; /* on macOS, converts from '/' structure */
2030 ret = interpret_services_menu (svcs, Qnil, ret);
2036 DEFUN ("ns-perform-service", Fns_perform_service, Sns_perform_service,
2038 doc: /* Perform Nextstep SERVICE on SEND.
2039 SEND should be either a string or nil.
2040 The return value is the result of the service, as string, or nil if
2041 there was no result. */)
2042 (Lisp_Object service, Lisp_Object send)
2048 CHECK_STRING (service);
2049 check_window_system (NULL);
2051 utfStr = SSDATA (service);
2052 svcName = [NSString stringWithUTF8String: utfStr];
2054 pb =[NSPasteboard pasteboardWithUniqueName];
2055 ns_string_to_pasteboard (pb, send);
2057 if (NSPerformService (svcName, pb) == NO)
2058 Fsignal (Qquit, list1 (build_string ("service not available")));
2060 if ([[pb types] count] == 0)
2061 return build_string ("");
2062 return ns_string_from_pasteboard (pb);
2066 #ifdef NS_IMPL_COCOA
2068 /* Compile and execute the AppleScript SCRIPT and return the error
2069 status as function value. A zero is returned if compilation and
2070 execution is successful, in which case *RESULT is set to a Lisp
2071 string or a number containing the resulting script value. Otherwise,
2074 ns_do_applescript (Lisp_Object script, Lisp_Object *result)
2076 NSAppleEventDescriptor *desc;
2077 NSDictionary* errorDict;
2078 NSAppleEventDescriptor* returnDescriptor = NULL;
2080 NSAppleScript* scriptObject =
2081 [[NSAppleScript alloc] initWithSource:
2082 [NSString stringWithUTF8String: SSDATA (script)]];
2084 returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
2085 [scriptObject release];
2088 if (returnDescriptor != NULL)
2090 // successful execution
2091 if (kAENullEvent != [returnDescriptor descriptorType])
2094 // script returned an AppleScript result
2095 if ((typeUnicodeText == [returnDescriptor descriptorType]) ||
2096 #if defined (NS_IMPL_COCOA)
2097 (typeUTF16ExternalRepresentation
2098 == [returnDescriptor descriptorType]) ||
2100 (typeUTF8Text == [returnDescriptor descriptorType]) ||
2101 (typeCString == [returnDescriptor descriptorType]))
2103 desc = [returnDescriptor coerceToDescriptorType: typeUTF8Text];
2105 *result = build_string([[desc stringValue] UTF8String]);
2109 /* use typeUTF16ExternalRepresentation? */
2110 // coerce the result to the appropriate ObjC type
2111 desc = [returnDescriptor coerceToDescriptorType: typeUTF8Text];
2113 *result = make_number([desc int32Value]);
2119 // no script result, return error
2125 /* Helper function called from sendEvent to run applescript
2126 from within the main event loop. */
2129 ns_run_ascript (void)
2131 if (! NILP (as_script))
2132 as_status = ns_do_applescript (as_script, as_result);
2136 DEFUN ("ns-do-applescript", Fns_do_applescript, Sns_do_applescript, 1, 1, 0,
2137 doc: /* Execute AppleScript SCRIPT and return the result.
2138 If compilation and execution are successful, the resulting script value
2139 is returned as a string, a number or, in the case of other constructs, t.
2140 In case the execution fails, an error is signaled. */)
2141 (Lisp_Object script)
2146 struct input_event ev;
2148 CHECK_STRING (script);
2149 check_window_system (NULL);
2154 as_result = &result;
2156 /* executing apple script requires the event loop to run, otherwise
2157 errors aren't returned and executeAndReturnError hangs forever.
2158 Post an event that runs applescript and then start the event loop.
2159 The event loop is exited when the script is done. */
2160 nxev = [NSEvent otherEventWithType: NSEventTypeApplicationDefined
2161 location: NSMakePoint (0, 0)
2164 windowNumber: [[NSApp mainWindow] windowNumber]
2165 context: [NSApp context]
2168 data2: NSAPP_DATA2_RUNASSCRIPT];
2170 [NSApp postEvent: nxev atStart: NO];
2172 // If there are other events, the event loop may exit. Keep running
2173 // until the script has been handled. */
2174 ns_init_events (&ev);
2175 while (! NILP (as_script))
2177 ns_finish_events ();
2185 else if (!STRINGP (result))
2186 error ("AppleScript error %d", status);
2188 error ("%s", SSDATA (result));
2194 /* ==========================================================================
2196 Miscellaneous functions not called through hooks
2198 ========================================================================== */
2200 /* called from frame.c */
2201 struct ns_display_info *
2202 check_x_display_info (Lisp_Object frame)
2204 return check_ns_display_info (frame);
2209 x_set_scroll_bar_default_width (struct frame *f)
2211 int wid = FRAME_COLUMN_WIDTH (f);
2212 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = NS_SCROLL_BAR_WIDTH_DEFAULT;
2213 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
2218 x_set_scroll_bar_default_height (struct frame *f)
2220 int height = FRAME_LINE_HEIGHT (f);
2221 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = NS_SCROLL_BAR_WIDTH_DEFAULT;
2222 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) +
2223 height - 1) / height;
2226 /* terms impl this instead of x-get-resource directly */
2228 x_get_string_resource (XrmDatabase rdb, const char *name, const char *class)
2230 /* remove appname prefix; TODO: allow for !="Emacs" */
2231 const char *res, *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
2233 check_window_system (NULL);
2235 if (inhibit_x_resources)
2236 /* --quick was passed, so this is a no-op. */
2239 res = ns_get_defaults_value (toCheck);
2240 return (char *) (!res ? NULL
2241 : !c_strncasecmp (res, "YES", 3) ? "true"
2242 : !c_strncasecmp (res, "NO", 2) ? "false"
2248 x_get_focus_frame (struct frame *frame)
2250 struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
2251 Lisp_Object nsfocus;
2253 if (!dpyinfo->x_focus_frame)
2256 XSETFRAME (nsfocus, dpyinfo->x_focus_frame);
2260 /* ==========================================================================
2262 Lisp definitions that, for whatever reason, we can't alias as 'ns-XXX'.
2264 ========================================================================== */
2267 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
2268 doc: /* Internal function called by `color-defined-p', which see.
2269 \(Note that the Nextstep version of this function ignores FRAME.) */)
2270 (Lisp_Object color, Lisp_Object frame)
2273 check_window_system (NULL);
2274 return ns_lisp_to_color (color, &col) ? Qnil : Qt;
2278 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2279 doc: /* Internal function called by `color-values', which see. */)
2280 (Lisp_Object color, Lisp_Object frame)
2283 EmacsCGFloat red, green, blue, alpha;
2285 check_window_system (NULL);
2286 CHECK_STRING (color);
2289 if (ns_lisp_to_color (color, &col))
2295 [[col colorUsingDefaultColorSpace]
2296 getRed: &red green: &green blue: &blue alpha: &alpha];
2298 return list3i (lrint (red * 65280), lrint (green * 65280),
2299 lrint (blue * 65280));
2303 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2304 doc: /* Internal function called by `display-color-p', which see. */)
2305 (Lisp_Object terminal)
2307 NSWindowDepth depth;
2308 NSString *colorSpace;
2310 check_ns_display_info (terminal);
2311 depth = [[[NSScreen screens] objectAtIndex:0] depth];
2312 colorSpace = NSColorSpaceFromDepth (depth);
2314 return [colorSpace isEqualToString: NSDeviceWhiteColorSpace]
2315 || [colorSpace isEqualToString: NSCalibratedWhiteColorSpace]
2320 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
2322 doc: /* Return t if the Nextstep display supports shades of gray.
2323 Note that color displays do support shades of gray.
2324 The optional argument TERMINAL specifies which display to ask about.
2325 TERMINAL should be a terminal object, a frame or a display name (a string).
2326 If omitted or nil, that stands for the selected frame's display. */)
2327 (Lisp_Object terminal)
2329 NSWindowDepth depth;
2331 check_ns_display_info (terminal);
2332 depth = [[[NSScreen screens] objectAtIndex:0] depth];
2334 return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil;
2338 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2340 doc: /* Return the width in pixels of the Nextstep display TERMINAL.
2341 The optional argument TERMINAL specifies which display to ask about.
2342 TERMINAL should be a terminal object, a frame or a display name (a string).
2343 If omitted or nil, that stands for the selected frame's display.
2345 On \"multi-monitor\" setups this refers to the pixel width for all
2346 physical monitors associated with TERMINAL. To get information for
2347 each physical monitor, use `display-monitor-attributes-list'. */)
2348 (Lisp_Object terminal)
2350 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2352 return make_number (x_display_pixel_width (dpyinfo));
2356 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2357 Sx_display_pixel_height, 0, 1, 0,
2358 doc: /* Return the height in pixels of the Nextstep display TERMINAL.
2359 The optional argument TERMINAL specifies which display to ask about.
2360 TERMINAL should be a terminal object, a frame or a display name (a string).
2361 If omitted or nil, that stands for the selected frame's display.
2363 On \"multi-monitor\" setups this refers to the pixel height for all
2364 physical monitors associated with TERMINAL. To get information for
2365 each physical monitor, use `display-monitor-attributes-list'. */)
2366 (Lisp_Object terminal)
2368 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2370 return make_number (x_display_pixel_height (dpyinfo));
2373 #ifdef NS_IMPL_COCOA
2375 /* Returns the name for the screen that OBJ represents, or NULL.
2376 Caller must free return value.
2380 ns_get_name_from_ioreg (io_object_t obj)
2384 NSDictionary *info = (NSDictionary *)
2385 IODisplayCreateInfoDictionary (obj, kIODisplayOnlyPreferredName);
2386 NSDictionary *names = [info objectForKey:
2387 [NSString stringWithUTF8String:
2388 kDisplayProductName]];
2390 if ([names count] > 0)
2392 NSString *n = [names objectForKey: [[names allKeys]
2394 if (n != nil) name = xstrdup ([n UTF8String]);
2402 /* Returns the name for the screen that DID came from, or NULL.
2403 Caller must free return value.
2407 ns_screen_name (CGDirectDisplayID did)
2411 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
2412 mach_port_t masterPort;
2416 // CGDisplayIOServicePort is deprecated. Do it another (harder) way.
2418 if (IOMasterPort (MACH_PORT_NULL, &masterPort) != kIOReturnSuccess
2419 || IOServiceGetMatchingServices (masterPort,
2420 IOServiceMatching ("IONDRVDevice"),
2421 &it) != kIOReturnSuccess)
2424 /* Must loop until we find a name. Many devices can have the same unit
2425 number (represents different GPU parts), but only one has a name. */
2426 while (! name && (obj = IOIteratorNext (it)))
2428 CFMutableDictionaryRef props;
2431 if (IORegistryEntryCreateCFProperties (obj,
2433 kCFAllocatorDefault,
2434 kNilOptions) == kIOReturnSuccess
2436 && (val = CFDictionaryGetValue(props, @"IOFBDependentIndex")))
2438 unsigned nr = [(NSNumber *)val unsignedIntegerValue];
2439 if (nr == CGDisplayUnitNumber (did))
2440 name = ns_get_name_from_ioreg (obj);
2444 IOObjectRelease (obj);
2447 IOObjectRelease (it);
2451 name = ns_get_name_from_ioreg (CGDisplayIOServicePort (did));
2459 ns_make_monitor_attribute_list (struct MonitorInfo *monitors,
2461 int primary_monitor,
2464 Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
2465 Lisp_Object frame, rest;
2466 NSArray *screens = [NSScreen screens];
2469 FOR_EACH_FRAME (rest, frame)
2471 struct frame *f = XFRAME (frame);
2475 NSView *view = FRAME_NS_VIEW (f);
2476 NSScreen *screen = [[view window] screen];
2480 for (k = 0; i == -1 && k < [screens count]; ++k)
2482 if ([screens objectAtIndex: k] == screen)
2487 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
2491 return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
2492 monitor_frames, source);
2495 DEFUN ("ns-display-monitor-attributes-list",
2496 Fns_display_monitor_attributes_list,
2497 Sns_display_monitor_attributes_list,
2499 doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
2501 The optional argument TERMINAL specifies which display to ask about.
2502 TERMINAL should be a terminal object, a frame or a display name (a string).
2503 If omitted or nil, that stands for the selected frame's display.
2505 In addition to the standard attribute keys listed in
2506 `display-monitor-attributes-list', the following keys are contained in
2509 source -- String describing the source from which multi-monitor
2510 information is obtained, \"NS\" is always the source."
2512 Internal use only, use `display-monitor-attributes-list' instead. */)
2513 (Lisp_Object terminal)
2515 struct terminal *term = decode_live_terminal (terminal);
2517 NSUInteger i, n_monitors;
2518 struct MonitorInfo *monitors;
2519 Lisp_Object attributes_list = Qnil;
2520 CGFloat primary_display_height = 0;
2522 if (term->type != output_ns)
2525 screens = [NSScreen screens];
2526 n_monitors = [screens count];
2527 if (n_monitors == 0)
2530 monitors = xzalloc (n_monitors * sizeof *monitors);
2532 for (i = 0; i < [screens count]; ++i)
2534 NSScreen *s = [screens objectAtIndex:i];
2535 struct MonitorInfo *m = &monitors[i];
2536 NSRect fr = [s frame];
2537 NSRect vfr = [s visibleFrame];
2540 #ifdef NS_IMPL_COCOA
2541 NSDictionary *dict = [s deviceDescription];
2542 NSNumber *nid = [dict objectForKey:@"NSScreenNumber"];
2543 CGDirectDisplayID did = [nid unsignedIntValue];
2547 primary_display_height = fr.size.height;
2548 y = (short) fr.origin.y;
2549 vy = (short) vfr.origin.y;
2553 // Flip y coordinate as NS has y starting from the bottom.
2554 y = (short) (primary_display_height - fr.size.height - fr.origin.y);
2555 vy = (short) (primary_display_height -
2556 vfr.size.height - vfr.origin.y);
2559 m->geom.x = (short) fr.origin.x;
2561 m->geom.width = (unsigned short) fr.size.width;
2562 m->geom.height = (unsigned short) fr.size.height;
2564 m->work.x = (short) vfr.origin.x;
2565 // y is flipped on NS, so vy - y are pixels missing at the bottom,
2566 // and fr.size.height - vfr.size.height are pixels missing in total.
2567 // Pixels missing at top are
2568 // fr.size.height - vfr.size.height - vy + y.
2569 // work.y is then pixels missing at top + y.
2570 m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y;
2571 m->work.width = (unsigned short) vfr.size.width;
2572 m->work.height = (unsigned short) vfr.size.height;
2574 #ifdef NS_IMPL_COCOA
2575 m->name = ns_screen_name (did);
2578 CGSize mms = CGDisplayScreenSize (did);
2579 m->mm_width = (int) mms.width;
2580 m->mm_height = (int) mms.height;
2584 // Assume 92 dpi as x-display-mm-height/x-display-mm-width does.
2585 m->mm_width = (int) (25.4 * fr.size.width / 92.0);
2586 m->mm_height = (int) (25.4 * fr.size.height / 92.0);
2590 // Primary monitor is always first for NS.
2591 attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors,
2594 free_monitors (monitors, n_monitors);
2595 return attributes_list;
2599 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2601 doc: /* Return the number of bitplanes of the Nextstep display TERMINAL.
2602 The optional argument TERMINAL specifies which display to ask about.
2603 TERMINAL should be a terminal object, a frame or a display name (a string).
2604 If omitted or nil, that stands for the selected frame's display. */)
2605 (Lisp_Object terminal)
2607 check_ns_display_info (terminal);
2609 (NSBitsPerPixelFromDepth ([[[NSScreen screens] objectAtIndex:0] depth]));
2613 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2615 doc: /* Returns the number of color cells of the Nextstep display TERMINAL.
2616 The optional argument TERMINAL specifies which display to ask about.
2617 TERMINAL should be a terminal object, a frame or a display name (a string).
2618 If omitted or nil, that stands for the selected frame's display. */)
2619 (Lisp_Object terminal)
2621 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2622 /* We force 24+ bit depths to 24-bit to prevent an overflow. */
2623 return make_number (1 << min (dpyinfo->n_planes, 24));
2627 /* Unused dummy def needed for compatibility. */
2628 Lisp_Object tip_frame;
2630 /* TODO: move to xdisp or similar */
2632 compute_tip_xy (struct frame *f,
2641 Lisp_Object left, top, right, bottom;
2642 EmacsView *view = FRAME_NS_VIEW (f);
2643 struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2646 /* Start with user-specified or mouse position. */
2647 left = Fcdr (Fassq (Qleft, parms));
2648 top = Fcdr (Fassq (Qtop, parms));
2649 right = Fcdr (Fassq (Qright, parms));
2650 bottom = Fcdr (Fassq (Qbottom, parms));
2652 if ((!INTEGERP (left) && !INTEGERP (right))
2653 || (!INTEGERP (top) && !INTEGERP (bottom)))
2655 pt.x = dpyinfo->last_mouse_motion_x;
2656 pt.y = dpyinfo->last_mouse_motion_y;
2657 /* Convert to screen coordinates */
2658 pt = [view convertPoint: pt toView: nil];
2659 #if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
2660 pt = [[view window] convertBaseToScreen: pt];
2663 NSRect r = NSMakeRect (pt.x, pt.y, 0, 0);
2664 r = [[view window] convertRectToScreen: r];
2672 /* Absolute coordinates. */
2673 pt.x = INTEGERP (left) ? XINT (left) : XINT (right);
2674 pt.y = (x_display_pixel_height (FRAME_DISPLAY_INFO (f))
2675 - (INTEGERP (top) ? XINT (top) : XINT (bottom))
2679 /* Ensure in bounds. (Note, screen origin = lower left.) */
2680 if (INTEGERP (left) || INTEGERP (right))
2682 else if (pt.x + XINT (dx) <= 0)
2683 *root_x = 0; /* Can happen for negative dx */
2684 else if (pt.x + XINT (dx) + width
2685 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
2686 /* It fits to the right of the pointer. */
2687 *root_x = pt.x + XINT (dx);
2688 else if (width + XINT (dx) <= pt.x)
2689 /* It fits to the left of the pointer. */
2690 *root_x = pt.x - width - XINT (dx);
2692 /* Put it left justified on the screen -- it ought to fit that way. */
2695 if (INTEGERP (top) || INTEGERP (bottom))
2697 else if (pt.y - XINT (dy) - height >= 0)
2698 /* It fits below the pointer. */
2699 *root_y = pt.y - height - XINT (dy);
2700 else if (pt.y + XINT (dy) + height
2701 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
2702 /* It fits above the pointer */
2703 *root_y = pt.y + XINT (dy);
2705 /* Put it on the top. */
2706 *root_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f)) - height;
2710 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
2711 doc: /* Show STRING in a \"tooltip\" window on frame FRAME.
2712 A tooltip window is a small window displaying a string.
2714 This is an internal function; Lisp code should call `tooltip-show'.
2716 FRAME nil or omitted means use the selected frame.
2718 PARMS is an optional list of frame parameters which can be used to
2719 change the tooltip's appearance.
2721 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
2722 means use the default timeout of 5 seconds.
2724 If the list of frame parameters PARMS contains a `left' parameter,
2725 display the tooltip at that x-position. If the list of frame parameters
2726 PARMS contains no `left' but a `right' parameter, display the tooltip
2727 right-adjusted at that x-position. Otherwise display it at the
2728 x-position of the mouse, with offset DX added (default is 5 if DX isn't
2731 Likewise for the y-position: If a `top' frame parameter is specified, it
2732 determines the position of the upper edge of the tooltip window. If a
2733 `bottom' parameter but no `top' frame parameter is specified, it
2734 determines the position of the lower edge of the tooltip window.
2735 Otherwise display the tooltip window at the y-position of the mouse,
2736 with offset DY added (default is -10).
2738 A tooltip's maximum size is specified by `x-max-tooltip-size'.
2739 Text larger than the specified size is clipped. */)
2740 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
2743 ptrdiff_t count = SPECPDL_INDEX ();
2748 specbind (Qinhibit_redisplay, Qt);
2750 CHECK_STRING (string);
2751 str = SSDATA (string);
2752 f = decode_window_system_frame (frame);
2754 timeout = make_number (5);
2756 CHECK_NATNUM (timeout);
2759 dx = make_number (5);
2764 dy = make_number (-10);
2769 if (ns_tooltip == nil)
2770 ns_tooltip = [[EmacsTooltip alloc] init];
2774 [ns_tooltip setText: str];
2775 size = [ns_tooltip frame].size;
2777 /* Move the tooltip window where the mouse pointer is. Resize and
2779 compute_tip_xy (f, parms, dx, dy, (int)size.width, (int)size.height,
2782 [ns_tooltip showAtX: root_x Y: root_y for: XINT (timeout)];
2785 return unbind_to (count, Qnil);
2789 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
2790 doc: /* Hide the current tooltip window, if there is any.
2791 Value is t if tooltip was open, nil otherwise. */)
2794 if (ns_tooltip == nil || ![ns_tooltip isActive])
2800 /* Return geometric attributes of FRAME. According to the value of
2801 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the inner
2802 edges of FRAME, the root window edges of frame (Qroot_edges). Any
2803 other value means to return the geometry as returned by
2804 Fx_frame_geometry. */
2806 frame_geometry (Lisp_Object frame, Lisp_Object attribute)
2808 struct frame *f = decode_live_frame (frame);
2809 Lisp_Object fullscreen_symbol = Fframe_parameter (frame, Qfullscreen);
2810 bool fullscreen = (EQ (fullscreen_symbol, Qfullboth)
2811 || EQ (fullscreen_symbol, Qfullscreen));
2812 int border = fullscreen ? 0 : f->border_width;
2813 int title_height = fullscreen ? 0 : FRAME_NS_TITLEBAR_HEIGHT (f);
2814 int native_width = FRAME_PIXEL_WIDTH (f);
2815 int native_height = FRAME_PIXEL_HEIGHT (f);
2816 int outer_width = native_width + 2 * border;
2817 int outer_height = native_height + 2 * border + title_height;
2818 int native_left = f->left_pos + border;
2819 int native_top = f->top_pos + border + title_height;
2820 int native_right = f->left_pos + outer_width - border;
2821 int native_bottom = f->top_pos + outer_height - border;
2822 int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
2823 int tool_bar_height = FRAME_TOOLBAR_HEIGHT (f);
2824 int tool_bar_width = (tool_bar_height
2825 ? outer_width - 2 * internal_border_width
2828 /* Construct list. */
2829 if (EQ (attribute, Qouter_edges))
2830 return list4 (make_number (f->left_pos), make_number (f->top_pos),
2831 make_number (f->left_pos + outer_width),
2832 make_number (f->top_pos + outer_height));
2833 else if (EQ (attribute, Qnative_edges))
2834 return list4 (make_number (native_left), make_number (native_top),
2835 make_number (native_right), make_number (native_bottom));
2836 else if (EQ (attribute, Qinner_edges))
2837 return list4 (make_number (native_left + internal_border_width),
2838 make_number (native_top
2840 + internal_border_width),
2841 make_number (native_right - internal_border_width),
2842 make_number (native_bottom - internal_border_width));
2845 listn (CONSTYPE_HEAP, 10,
2846 Fcons (Qouter_position,
2847 Fcons (make_number (f->left_pos),
2848 make_number (f->top_pos))),
2850 Fcons (make_number (outer_width),
2851 make_number (outer_height))),
2852 Fcons (Qexternal_border_size,
2854 ? Fcons (make_number (0), make_number (0))
2855 : Fcons (make_number (border), make_number (border)))),
2856 Fcons (Qtitle_bar_size,
2857 Fcons (make_number (0), make_number (title_height))),
2858 Fcons (Qmenu_bar_external, Qnil),
2859 Fcons (Qmenu_bar_size, Fcons (make_number (0), make_number (0))),
2860 Fcons (Qtool_bar_external,
2861 FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil),
2862 Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
2863 Fcons (Qtool_bar_size,
2864 Fcons (make_number (tool_bar_width),
2865 make_number (tool_bar_height))),
2866 Fcons (Qinternal_border_width,
2867 make_number (internal_border_width)));
2870 DEFUN ("ns-frame-geometry", Fns_frame_geometry, Sns_frame_geometry, 0, 1, 0,
2871 doc: /* Return geometric attributes of FRAME.
2872 FRAME must be a live frame and defaults to the selected one. The return
2873 value is an association list of the attributes listed below. All height
2874 and width values are in pixels.
2876 `outer-position' is a cons of the outer left and top edges of FRAME
2877 relative to the origin - the position (0, 0) - of FRAME's display.
2879 `outer-size' is a cons of the outer width and height of FRAME. The
2880 outer size includes the title bar and the external borders as well as
2881 any menu and/or tool bar of frame.
2883 `external-border-size' is a cons of the horizontal and vertical width of
2884 FRAME's external borders as supplied by the window manager.
2886 `title-bar-size' is a cons of the width and height of the title bar of
2887 FRAME as supplied by the window manager. If both of them are zero,
2888 FRAME has no title bar. If only the width is zero, Emacs was not
2889 able to retrieve the width information.
2891 `menu-bar-external', if non-nil, means the menu bar is external (never
2892 included in the inner edges of FRAME).
2894 `menu-bar-size' is a cons of the width and height of the menu bar of
2897 `tool-bar-external', if non-nil, means the tool bar is external (never
2898 included in the inner edges of FRAME).
2900 `tool-bar-position' tells on which side the tool bar on FRAME is and can
2901 be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
2904 `tool-bar-size' is a cons of the width and height of the tool bar of
2907 `internal-border-width' is the width of the internal border of
2911 return frame_geometry (frame, Qnil);
2914 DEFUN ("ns-frame-edges", Fns_frame_edges, Sns_frame_edges, 0, 2, 0,
2915 doc: /* Return edge coordinates of FRAME.
2916 FRAME must be a live frame and defaults to the selected one. The return
2917 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
2918 in pixels relative to the origin - the position (0, 0) - of FRAME's
2921 If optional argument TYPE is the symbol `outer-edges', return the outer
2922 edges of FRAME. The outer edges comprise the decorations of the window
2923 manager (like the title bar or external borders) as well as any external
2924 menu or tool bar of FRAME. If optional argument TYPE is the symbol
2925 `native-edges' or nil, return the native edges of FRAME. The native
2926 edges exclude the decorations of the window manager and any external
2927 menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
2928 the inner edges of FRAME. These edges exclude title bar, any borders,
2929 menu bar or tool bar of FRAME. */)
2930 (Lisp_Object frame, Lisp_Object type)
2932 return frame_geometry (frame, ((EQ (type, Qouter_edges)
2933 || EQ (type, Qinner_edges))
2938 /* ==========================================================================
2940 Class implementations
2942 ========================================================================== */
2945 Handle arrow/function/control keys and copy/paste/cut in file dialogs.
2946 Return YES if handled, NO if not.
2949 handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent)
2955 if ([theEvent type] != NSEventTypeKeyDown) return NO;
2956 s = [theEvent characters];
2958 for (i = 0; i < [s length]; ++i)
2960 int ch = (int) [s characterAtIndex: i];
2963 case NSHomeFunctionKey:
2964 case NSDownArrowFunctionKey:
2965 case NSUpArrowFunctionKey:
2966 case NSLeftArrowFunctionKey:
2967 case NSRightArrowFunctionKey:
2968 case NSPageUpFunctionKey:
2969 case NSPageDownFunctionKey:
2970 case NSEndFunctionKey:
2971 /* Don't send command modified keys, as those are handled in the
2972 performKeyEquivalent method of the super class.
2974 if (! ([theEvent modifierFlags] & NSEventModifierFlagCommand))
2976 [panel sendEvent: theEvent];
2980 /* As we don't have the standard key commands for
2981 copy/paste/cut/select-all in our edit menu, we must handle
2982 them here. TODO: handle Emacs key bindings for copy/cut/select-all
2983 here, paste works, because we have that in our Edit menu.
2984 I.e. refactor out code in nsterm.m, keyDown: to figure out the
2990 case 'a': // Select all
2991 if ([theEvent modifierFlags] & NSEventModifierFlagCommand)
3000 : @selector(selectAll:))))
3005 // Send all control keys, as the text field supports C-a, C-f, C-e
3007 if ([theEvent modifierFlags] & NSEventModifierFlagControl)
3009 [panel sendEvent: theEvent];
3020 @implementation EmacsSavePanel
3021 - (BOOL)performKeyEquivalent:(NSEvent *)theEvent
3023 BOOL ret = handlePanelKeys (self, theEvent);
3025 ret = [super performKeyEquivalent:theEvent];
3031 @implementation EmacsOpenPanel
3032 - (BOOL)performKeyEquivalent:(NSEvent *)theEvent
3034 // NSOpenPanel inherits NSSavePanel, so passing self is OK.
3035 BOOL ret = handlePanelKeys (self, theEvent);
3037 ret = [super performKeyEquivalent:theEvent];
3043 @implementation EmacsFileDelegate
3044 /* --------------------------------------------------------------------------
3045 Delegate methods for Open/Save panels
3046 -------------------------------------------------------------------------- */
3047 - (BOOL)panel: (id)sender isValidFilename: (NSString *)filename
3051 - (BOOL)panel: (id)sender shouldShowFilename: (NSString *)filename
3055 - (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
3056 confirmed: (BOOL)okFlag
3065 /* ==========================================================================
3067 Lisp interface declaration
3069 ========================================================================== */
3073 syms_of_nsfns (void)
3075 DEFSYM (Qfontsize, "fontsize");
3076 DEFSYM (Qframe_title_format, "frame-title-format");
3077 DEFSYM (Qicon_title_format, "icon-title-format");
3079 DEFVAR_LISP ("ns-icon-type-alist", Vns_icon_type_alist,
3080 doc: /* Alist of elements (REGEXP . IMAGE) for images of icons associated to frames.
3081 If the title of a frame matches REGEXP, then IMAGE.tiff is
3082 selected as the image of the icon representing the frame when it's
3083 miniaturized. If an element is t, then Emacs tries to select an icon
3084 based on the filetype of the visited file.
3086 The images have to be installed in a folder called English.lproj in the
3087 Emacs folder. You have to restart Emacs after installing new icons.
3089 Example: Install an icon Gnus.tiff and execute the following code
3091 (setq ns-icon-type-alist
3092 (append ns-icon-type-alist
3093 \\='((\"^\\\\*\\\\(Group\\\\*$\\\\|Summary \\\\|Article\\\\*$\\\\)\"
3096 When you miniaturize a Group, Summary or Article frame, Gnus.tiff will
3097 be used as the image of the icon representing the frame. */);
3098 Vns_icon_type_alist = list1 (Qt);
3100 DEFVAR_LISP ("ns-version-string", Vns_version_string,
3101 doc: /* Toolkit version for NS Windowing. */);
3102 Vns_version_string = ns_appkit_version_str ();
3104 defsubr (&Sns_read_file_name);
3105 defsubr (&Sns_get_resource);
3106 defsubr (&Sns_set_resource);
3107 defsubr (&Sxw_display_color_p); /* this and next called directly by C code */
3108 defsubr (&Sx_display_grayscale_p);
3109 defsubr (&Sns_font_name);
3110 defsubr (&Sns_list_colors);
3111 #ifdef NS_IMPL_COCOA
3112 defsubr (&Sns_do_applescript);
3114 defsubr (&Sxw_color_defined_p);
3115 defsubr (&Sxw_color_values);
3116 defsubr (&Sx_server_max_request_size);
3117 defsubr (&Sx_server_vendor);
3118 defsubr (&Sx_server_version);
3119 defsubr (&Sx_display_pixel_width);
3120 defsubr (&Sx_display_pixel_height);
3121 defsubr (&Sns_display_monitor_attributes_list);
3122 defsubr (&Sns_frame_geometry);
3123 defsubr (&Sns_frame_edges);
3124 defsubr (&Sx_display_mm_width);
3125 defsubr (&Sx_display_mm_height);
3126 defsubr (&Sx_display_screens);
3127 defsubr (&Sx_display_planes);
3128 defsubr (&Sx_display_color_cells);
3129 defsubr (&Sx_display_visual_class);
3130 defsubr (&Sx_display_backing_store);
3131 defsubr (&Sx_display_save_under);
3132 defsubr (&Sx_create_frame);
3133 defsubr (&Sx_open_connection);
3134 defsubr (&Sx_close_connection);
3135 defsubr (&Sx_display_list);
3137 defsubr (&Sns_hide_others);
3138 defsubr (&Sns_hide_emacs);
3139 defsubr (&Sns_emacs_info_panel);
3140 defsubr (&Sns_list_services);
3141 defsubr (&Sns_perform_service);
3142 defsubr (&Sns_popup_font_panel);
3143 defsubr (&Sns_popup_color_panel);
3145 defsubr (&Sx_show_tip);
3146 defsubr (&Sx_hide_tip);