#include "fontset.h"
#include "font.h"
+#ifdef NS_IMPL_COCOA
+#include <IOKit/graphics/IOGraphicsLib.h>
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#include "macfont.h"
+#endif
+#endif
+
#if 0
int fns_trace_num = 1;
#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \
Lisp_Object Qbuffered;
Lisp_Object Qfontsize;
-/* hack for OS X file panels */
-char panelOK = 0;
-
-EmacsTooltip *ns_tooltip;
+EmacsTooltip *ns_tooltip = nil;
/* Need forward declaration here to preserve organizational integrity of file */
Lisp_Object Fx_open_connection (Lisp_Object, Lisp_Object, Lisp_Object);
static ptrdiff_t image_cache_refcount;
#endif
+
/* ==========================================================================
Internal utility functions
========================================================================== */
+/* Let the user specify a Nextstep display with a Lisp object.
+ OBJECT may be nil, a frame or a terminal object.
+ nil stands for the selected frame--or, if that is not a Nextstep frame,
+ the first Nextstep display on the list. */
-void
-check_window_system (void)
-{
- if (NSApp == nil)
- error ("OpenStep is not in use or not initialized");
-}
-
-
-/* Nonzero if we can use mouse menus. */
-int
-have_menus_p (void)
-{
- return NSApp != nil;
-}
-
-
-/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
- and checking validity for NS. */
-static FRAME_PTR
-check_ns_frame (Lisp_Object frame)
+static struct ns_display_info *
+check_ns_display_info (Lisp_Object object)
{
- FRAME_PTR f;
+ struct ns_display_info *dpyinfo = NULL;
- if (NILP (frame))
- f = SELECTED_FRAME ();
- else
+ if (NILP (object))
{
- CHECK_LIVE_FRAME (frame);
- f = XFRAME (frame);
- }
- if (! FRAME_NS_P (f))
- error ("non-Nextstep frame used");
- return f;
-}
-
+ struct frame *sf = XFRAME (selected_frame);
-/* Let the user specify an Nextstep display with a frame.
- nil stands for the selected frame--or, if that is not an Nextstep frame,
- the first Nextstep display on the list. */
-static struct ns_display_info *
-check_ns_display_info (Lisp_Object frame)
-{
- if (NILP (frame))
- {
- struct frame *f = SELECTED_FRAME ();
- if (FRAME_NS_P (f) && FRAME_LIVE_P (f) )
- return FRAME_NS_DISPLAY_INFO (f);
+ if (FRAME_NS_P (sf) && FRAME_LIVE_P (sf))
+ dpyinfo = FRAME_DISPLAY_INFO (sf);
else if (x_display_list != 0)
- return x_display_list;
+ dpyinfo = x_display_list;
else
error ("Nextstep windows are not in use or not initialized");
}
- else if (INTEGERP (frame))
+ else if (TERMINALP (object))
{
- struct terminal *t = get_terminal (frame, 1);
+ struct terminal *t = get_terminal (object, 1);
if (t->type != output_ns)
- error ("Terminal %"pI"d is not a Nextstep display", XINT (frame));
+ error ("Terminal %d is not a Nextstep display", t->id);
- return t->display_info.ns;
+ dpyinfo = t->display_info.ns;
}
- else if (STRINGP (frame))
- return ns_display_info_for_name (frame);
+ else if (STRINGP (object))
+ dpyinfo = ns_display_info_for_name (object);
else
{
- FRAME_PTR f;
-
- CHECK_LIVE_FRAME (frame);
- f = XFRAME (frame);
- if (! FRAME_NS_P (f))
- error ("non-Nextstep frame used");
- return FRAME_NS_DISPLAY_INFO (f);
+ struct frame *f = decode_window_system_frame (object);
+ dpyinfo = FRAME_DISPLAY_INFO (f);
}
- return NULL; /* shut compiler up */
+
+ return dpyinfo;
}
}
-static NSScreen *
-ns_get_screen (Lisp_Object screen)
-{
- struct frame *f;
- struct terminal *terminal;
-
- if (EQ (Qt, screen)) /* not documented */
- return [NSScreen mainScreen];
-
- terminal = get_terminal (screen, 1);
- if (terminal->type != output_ns)
- return NULL;
-
- if (NILP (screen))
- f = SELECTED_FRAME ();
- else if (FRAMEP (screen))
- f = XFRAME (screen);
- else
- {
- struct ns_display_info *dpyinfo = terminal->display_info.ns;
- f = dpyinfo->x_focus_frame
- ? dpyinfo->x_focus_frame : dpyinfo->x_highlight_frame;
- }
-
- return ((f && FRAME_NS_P (f)) ? [[FRAME_NS_VIEW (f) window] screen]
- : NULL);
-}
-
-
/* Return the X display structure for the display named NAME.
Open a new connection if necessary. */
struct ns_display_info *
x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
NSColor *col;
- CGFloat r, g, b, alpha;
+ EmacsCGFloat r, g, b, alpha;
if (ns_lisp_to_color (arg, &col))
{
struct face *face;
NSColor *col;
NSView *view = FRAME_NS_VIEW (f);
- CGFloat r, g, b, alpha;
+ EmacsCGFloat r, g, b, alpha;
if (ns_lisp_to_color (arg, &col))
{
{
[[view window] setBackgroundColor: col];
- if (alpha != 1.0)
+ if (alpha != (EmacsCGFloat) 1.0)
[[view window] setOpaque: NO];
else
[[view window] setOpaque: YES];
}
static void
-ns_set_name_internal (FRAME_PTR f, Lisp_Object name)
+ns_set_name_internal (struct frame *f, Lisp_Object name)
{
struct gcpro gcpro1;
Lisp_Object encoded_name, encoded_icon_name;
specified a name for the frame; the name will override any set by the
redisplay code. */
static void
-x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
NSTRACE (x_explicitly_set_name);
ns_set_name (f, arg, 1);
name; names set this way will never override names set by the user's
lisp code. */
void
-x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
NSTRACE (x_implicitly_set_name);
}
-void
+static void
ns_implicitly_set_icon_type (struct frame *f)
{
Lisp_Object tem;
}
/* This is the same as the xfns.c definition. */
-void
-x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+static void
+x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
set_frame_cursor_types (f, arg);
-
- /* Make sure the cursor gets redrawn. */
- cursor_type_changed = 1;
}
-\f
/* called to set mouse pointer color, but all other terms use it to
initialize pointer types (and don't set the color ;) */
#ifdef NS_IMPL_GNUSTEP
sprintf(tmp, "gnustep-gui-%s", Xstr(GNUSTEP_GUI_VERSION));
-#elif defined(NS_IMPL_COCOA)
+#elif defined (NS_IMPL_COCOA)
sprintf(tmp, "apple-appkit-%.2f", NSAppKitVersionNumber);
#else
tmp = "ns-unknown";
{
#ifdef NS_IMPL_GNUSTEP
return GNUSTEP_GUI_MAJOR_VERSION * 100 + GNUSTEP_GUI_MINOR_VERSION;
-#elif defined(NS_IMPL_COCOA)
+#elif defined (NS_IMPL_COCOA)
return (int)NSAppKitVersionNumber;
#endif
return 0;
/* Handler for signals raised during x_create_frame.
FRAME is the frame which is partially constructed. */
-static Lisp_Object
+static void
unwind_create_frame (Lisp_Object frame)
{
struct frame *f = XFRAME (frame);
display is disconnected after the frame has become official, but
before x_create_frame removes the unwind protect. */
if (!FRAME_LIVE_P (f))
- return Qnil;
+ return;
/* If frame is ``official'', nothing to do. */
if (NILP (Fmemq (frame, Vframe_list)))
{
#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
- struct ns_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
#endif
x_free_frame_resources (f);
/* Check that reference counts are indeed correct. */
eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
#endif
- return Qt;
}
-
- return Qnil;
}
/*
Lisp_Object frame, tem;
Lisp_Object name;
int minibuffer_only = 0;
- int window_prompting = 0;
+ long window_prompting = 0;
int width, height;
ptrdiff_t count = specpdl_ptr - specpdl;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
struct ns_display_info *dpyinfo = NULL;
Lisp_Object parent;
struct kboard *kb;
- Lisp_Object tfont, tfontsize;
static int desc_ctr = 1;
- check_window_system ();
-
/* x_get_arg modifies parms. */
parms = Fcopy_alist (parms);
if (! STRINGP (f->icon_name))
fset_icon_name (f, Qnil);
- FRAME_NS_DISPLAY_INFO (f) = dpyinfo;
+ FRAME_DISPLAY_INFO (f) = dpyinfo;
- /* With FRAME_NS_DISPLAY_INFO set up, this unwind-protect is safe. */
+ /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
record_unwind_protect (unwind_create_frame, frame);
f->output_data.ns->window_desc = desc_ctr++;
}
else
{
- f->output_data.ns->parent_desc = FRAME_NS_DISPLAY_INFO (f)->root_window;
+ f->output_data.ns->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
f->output_data.ns->explicit_parent = 0;
}
}
block_input ();
+
+#ifdef NS_IMPL_COCOA
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if (CTGetCoreTextVersion != NULL
+ && CTGetCoreTextVersion () >= kCTVersionNumber10_5)
+ mac_register_font_driver (f);
+#endif
+#endif
register_font_driver (&nsfont_driver, f);
+
x_default_parameter (f, parms, Qfont_backend, Qnil,
"fontBackend", "FontBackend", RES_TYPE_STRING);
{
/* use for default font name */
id font = [NSFont userFixedPitchFontOfSize: -1.0]; /* default */
- tfontsize = x_default_parameter (f, parms, Qfontsize,
+ x_default_parameter (f, parms, Qfontsize,
make_number (0 /*(int)[font pointSize]*/),
"fontSize", "FontSize", RES_TYPE_NUMBER);
- tfont = x_default_parameter (f, parms, Qfont,
- build_string ([[font fontName] UTF8String]),
+ // Remove ' Regular', not handled by backends.
+ char *fontname = xstrdup ([[font displayName] UTF8String]);
+ int len = strlen (fontname);
+ if (len > 8 && strcmp (fontname + len - 8, " Regular") == 0)
+ fontname[len-8] = '\0';
+ x_default_parameter (f, parms, Qfont,
+ build_string (fontname),
"font", "Font", RES_TYPE_STRING);
}
unblock_input ();
f->output_data.ns->hand_cursor = [NSCursor pointingHandCursor];
f->output_data.ns->hourglass_cursor = [NSCursor disappearingItemCursor];
f->output_data.ns->horizontal_drag_cursor = [NSCursor resizeLeftRightCursor];
- FRAME_NS_DISPLAY_INFO (f)->vertical_scroll_bar_cursor
+ FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor
= [NSCursor arrowCursor];
f->output_data.ns->current_pointer = f->output_data.ns->text_cursor;
return unbind_to (count, frame);
}
-
-DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
- doc: /* Set the input focus to FRAME.
-FRAME nil means use the selected frame. */)
- (Lisp_Object frame)
+void
+x_focus_frame (struct frame *f)
{
- struct frame *f = check_ns_frame (frame);
- struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
+ struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
if (dpyinfo->x_focus_frame != f)
{
[[view window] makeKeyAndOrderFront: view];
unblock_input ();
}
-
- return Qnil;
}
doc: /* Pop up the font panel. */)
(Lisp_Object frame)
{
- id fm;
- struct frame *f;
-
- check_window_system ();
- fm = [NSFontManager sharedFontManager];
- if (NILP (frame))
- f = SELECTED_FRAME ();
+ struct frame *f = decode_window_system_frame (frame);
+ id fm = [NSFontManager sharedFontManager];
+ struct font *font = f->output_data.ns->font;
+ NSFont *nsfont;
+ if (EQ (font->driver->type, Qns))
+ nsfont = ((struct nsfont_info *)font)->nsfont;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
else
- {
- CHECK_FRAME (frame);
- f = XFRAME (frame);
- }
-
- [fm setSelectedFont: ((struct nsfont_info *)f->output_data.ns->font)->nsfont
- isMultiple: NO];
+ nsfont = (NSFont *) macfont_get_nsctfont (font);
+#endif
+ [fm setSelectedFont: nsfont isMultiple: NO];
[fm orderFrontFontPanel: NSApp];
return Qnil;
}
doc: /* Pop up the color panel. */)
(Lisp_Object frame)
{
- struct frame *f;
+ check_window_system (NULL);
+ [NSApp orderFrontColorPanel: NSApp];
+ return Qnil;
+}
+
+static struct
+{
+ id panel;
+ BOOL ret;
+#if ! defined (NS_IMPL_COCOA) || \
+ MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
+ NSString *dirS, *initS;
+ BOOL no_types;
+#endif
+} ns_fd_data;
- check_window_system ();
- if (NILP (frame))
- f = SELECTED_FRAME ();
+void
+ns_run_file_dialog (void)
+{
+ if (ns_fd_data.panel == nil) return;
+#if defined (NS_IMPL_COCOA) && \
+ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ ns_fd_data.ret = [ns_fd_data.panel runModal];
+#else
+ if (ns_fd_data.no_types)
+ {
+ ns_fd_data.ret = [ns_fd_data.panel
+ runModalForDirectory: ns_fd_data.dirS
+ file: ns_fd_data.initS];
+ }
else
{
- CHECK_FRAME (frame);
- f = XFRAME (frame);
+ ns_fd_data.ret = [ns_fd_data.panel
+ runModalForDirectory: ns_fd_data.dirS
+ file: ns_fd_data.initS
+ types: nil];
}
-
- [NSApp orderFrontColorPanel: NSApp];
- return Qnil;
+#endif
+ ns_fd_data.panel = nil;
}
-
DEFUN ("ns-read-file-name", Fns_read_file_name, Sns_read_file_name, 1, 5, 0,
doc: /* Use a graphical panel to read a file name, using prompt PROMPT.
Optional arg DIR, if non-nil, supplies a default directory.
{
static id fileDelegate = nil;
BOOL ret;
+ BOOL isSave = NILP (mustmatch) && NILP (dir_only_p);
id panel;
Lisp_Object fname;
[NSString stringWithUTF8String: SSDATA (dir)];
NSString *initS = NILP (init) || !STRINGP (init) ? nil :
[NSString stringWithUTF8String: SSDATA (init)];
+ NSEvent *nxev;
- check_window_system ();
+ check_window_system (NULL);
if (fileDelegate == nil)
fileDelegate = [EmacsFileDelegate new];
if ([dirS characterAtIndex: 0] == '~')
dirS = [dirS stringByExpandingTildeInPath];
- panel = NILP (mustmatch) && NILP (dir_only_p) ?
+ panel = isSave ?
(id)[EmacsSavePanel savePanel] : (id)[EmacsOpenPanel openPanel];
[panel setTitle: promptS];
[panel setTreatsFilePackagesAsDirectories: YES];
[panel setDelegate: fileDelegate];
- panelOK = 0;
if (! NILP (dir_only_p))
{
[panel setCanChooseDirectories: YES];
[panel setCanChooseFiles: NO];
}
- else
+ else if (! isSave)
{
/* This is not quite what the documentation says, but it is compatible
with the Gtk+ code. Also, the menu entry says "Open File...". */
}
block_input ();
+ ns_fd_data.panel = panel;
+ ns_fd_data.ret = NO;
#if defined (NS_IMPL_COCOA) && \
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
if (! NILP (mustmatch) || ! NILP (dir_only_p))
else
[panel setNameFieldStringValue: @""];
- ret = [panel runModal];
#else
- if (NILP (mustmatch) && NILP (dir_only_p))
- {
- ret = [panel runModalForDirectory: dirS file: initS];
- }
- else
- {
- ret = [panel runModalForDirectory: dirS file: initS types: nil];
- }
+ ns_fd_data.no_types = NILP (mustmatch) && NILP (dir_only_p);
+ ns_fd_data.dirS = dirS;
+ ns_fd_data.initS = initS;
#endif
- ret = (ret == NSOKButton) || panelOK;
+ /* runModalForDirectory/runModal restarts the main event loop when done,
+ so we must start an event loop and then pop up the file dialog.
+ The file dialog may pop up a confirm dialog after Ok has been pressed,
+ so we can not simply pop down on the Ok/Cancel press.
+ */
+ nxev = [NSEvent otherEventWithType: NSApplicationDefined
+ location: NSMakePoint (0, 0)
+ modifierFlags: 0
+ timestamp: 0
+ windowNumber: [[NSApp mainWindow] windowNumber]
+ context: [NSApp context]
+ subtype: 0
+ data1: 0
+ data2: NSAPP_DATA2_RUNFILEDIALOG];
+
+ [NSApp postEvent: nxev atStart: NO];
+ while (ns_fd_data.panel != nil)
+ [NSApp run];
- if (ret)
+ ret = (ns_fd_data.ret == NSOKButton);
+
+ if (ret)
{
- NSString *str = [panel getFilename];
- if (! str) str = [panel getDirectory];
+ NSString *str = ns_filename_from_panel (panel);
+ if (! str) str = ns_directory_from_panel (panel);
if (! str) ret = NO;
else fname = build_string ([str UTF8String]);
}
{
const char *value;
- check_window_system ();
+ check_window_system (NULL);
if (NILP (owner))
owner = build_string([ns_app_name UTF8String]);
CHECK_STRING (name);
-/*fprintf (stderr, "ns-get-resource checking resource '%s'\n", SSDATA (name)); */
value = ns_get_defaults_value (SSDATA (name));
If VALUE is nil, the default is removed. */)
(Lisp_Object owner, Lisp_Object name, Lisp_Object value)
{
- check_window_system ();
+ check_window_system (NULL);
if (NILP (owner))
owner = build_string ([ns_app_name UTF8String]);
CHECK_STRING (name);
Sx_server_max_request_size,
0, 1, 0,
doc: /* This function is a no-op. It is only present for completeness. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
- check_window_system ();
+ check_ns_display_info (terminal);
/* This function has no real equivalent under NeXTstep. Return nil to
indicate this. */
return Qnil;
DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
- doc: /* Return the vendor ID string of Nextstep display server DISPLAY.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+ doc: /* Return the "vendor ID" string of Nextstep display server TERMINAL.
+\(Labeling every distributor as a "vendor" embodies the false assumption
+that operating systems cannot be developed and distributed noncommercially.)
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
+ check_ns_display_info (terminal);
#ifdef NS_IMPL_GNUSTEP
return build_string ("GNU");
#else
DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
- doc: /* Return the version numbers of the server of DISPLAY.
+ doc: /* Return the version numbers of the server of display TERMINAL.
The value is a list of three integers: the major and minor
-version numbers of the X Protocol in use, and the distributor-specific
-release number. See also the function `x-server-vendor'.
+version numbers of the X Protocol in use, and the distributor-specific release
+number. See also the function `x-server-vendor'.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
+ check_ns_display_info (terminal);
/*NOTE: it is unclear what would best correspond with "protocol";
we return 10.3, meaning Panther, since this is roughly the
level that GNUstep's APIs correspond to.
DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
- doc: /* Return the number of screens on Nextstep display server DISPLAY.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
-{
- int num;
-
- check_window_system ();
- num = [[NSScreen screens] count];
+ doc: /* Return the number of screens on Nextstep display server TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
- return (num != 0) ? make_number (num) : Qnil;
+Note: "screen" here is not in Nextstep terminology but in X11's. For
+the number of physical monitors, use `(length
+(display-monitor-attributes-list TERMINAL))' instead. */)
+ (Lisp_Object terminal)
+{
+ check_ns_display_info (terminal);
+ return make_number (1);
}
-DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height,
- 0, 1, 0,
- doc: /* Return the height of Nextstep display server DISPLAY, in millimeters.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
+ doc: /* Return the height in millimeters of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the height in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_window_system ();
- return make_number ((int)
- ([ns_get_screen (display) frame].size.height/(92.0/25.4)));
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_height (dpyinfo) / (92.0/25.4));
}
-DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width,
- 0, 1, 0,
- doc: /* Return the width of Nextstep display server DISPLAY, in millimeters.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
+ doc: /* Return the width in millimeters of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the width in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_window_system ();
- return make_number ((int)
- ([ns_get_screen (display) frame].size.width/(92.0/25.4)));
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_width (dpyinfo) / (92.0/25.4));
}
DEFUN ("x-display-backing-store", Fx_display_backing_store,
Sx_display_backing_store, 0, 1, 0,
- doc: /* Return whether the Nextstep display DISPLAY supports backing store.
+ doc: /* Return an indication of whether the Nextstep display TERMINAL does backing store.
The value may be `buffered', `retained', or `non-retained'.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
- check_window_system ();
- switch ([ns_get_window (display) backingType])
+ check_ns_display_info (terminal);
+ switch ([ns_get_window (terminal) backingType])
{
case NSBackingStoreBuffered:
return intern ("buffered");
DEFUN ("x-display-visual-class", Fx_display_visual_class,
Sx_display_visual_class, 0, 1, 0,
- doc: /* Return the visual class of the Nextstep display server DISPLAY.
+ doc: /* Return the visual class of the Nextstep display TERMINAL.
The value is one of the symbols `static-gray', `gray-scale',
`static-color', `pseudo-color', `true-color', or `direct-color'.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
NSWindowDepth depth;
- check_window_system ();
- depth = [ns_get_screen (display) depth];
+
+ check_ns_display_info (terminal);
+ depth = [[[NSScreen screens] objectAtIndex:0] depth];
if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
return intern ("static-gray");
DEFUN ("x-display-save-under", Fx_display_save_under,
Sx_display_save_under, 0, 1, 0,
- doc: /* Return t if DISPLAY supports the save-under feature.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
-{
- check_window_system ();
- switch ([ns_get_window (display) backingType])
+ doc: /* Return t if TERMINAL supports the save-under feature.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
+{
+ check_ns_display_info (terminal);
+ switch ([ns_get_window (terminal) backingType])
{
case NSBackingStoreBuffered:
return Qt;
DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection,
1, 1, 0,
- doc: /* Close the connection to the current Nextstep display server.
-The argument DISPLAY is currently ignored. */)
- (Lisp_Object display)
+ doc: /* Close the connection to TERMINAL's Nextstep display server.
+For TERMINAL, specify a terminal object, a frame or a display name (a
+string). If TERMINAL is nil, that stands for the selected frame's
+terminal. */)
+ (Lisp_Object terminal)
{
- check_window_system ();
- /*ns_delete_terminal (dpyinfo->terminal); */
+ check_ns_display_info (terminal);
[NSApp terminate: NSApp];
return Qnil;
}
doc: /* Hides all applications other than Emacs. */)
(void)
{
- check_window_system ();
+ check_window_system (NULL);
[NSApp hideOtherApplications: NSApp];
return Qnil;
}
the active application. */)
(Lisp_Object on)
{
- check_window_system ();
+ check_window_system (NULL);
if (EQ (on, intern ("activate")))
{
[NSApp unhide: NSApp];
doc: /* Shows the 'Info' or 'About' panel for Emacs. */)
(void)
{
- check_window_system ();
+ check_window_system (NULL);
[NSApp orderFrontStandardAboutPanel: nil];
return Qnil;
}
#else
Lisp_Object ret = Qnil;
NSMenu *svcs;
+#ifdef NS_IMPL_COCOA
id delegate;
+#endif
- check_window_system ();
+ check_window_system (NULL);
svcs = [[NSMenu alloc] initWithTitle: @"Services"];
[NSApp setServicesMenu: svcs];
[NSApp registerServicesMenuSendTypes: ns_send_types
char *utfStr;
CHECK_STRING (service);
- check_window_system ();
+ check_window_system (NULL);
utfStr = SSDATA (service);
svcName = [NSString stringWithUTF8String: utfStr];
ns_string_to_pasteboard (pb, send);
if (NSPerformService (svcName, pb) == NO)
- Fsignal (Qquit, Fcons (build_string ("service not available"), Qnil));
+ Fsignal (Qquit, list1 (build_string ("service not available")));
if ([[pb types] count] == 0)
return build_string ("");
/* TODO: If GNUstep ever implements precomposedStringWithCanonicalMapping,
remove this. */
NSString *utfStr;
+ Lisp_Object ret;
CHECK_STRING (str);
- utfStr = [NSString stringWithUTF8String: SSDATA (str)];
- if (![utfStr respondsToSelector:
- @selector (precomposedStringWithCanonicalMapping)])
- {
- message1
- ("Warning: ns-convert-utf8-nfd-to-nfc unsupported under GNUstep.\n");
- return Qnil;
- }
- else
- utfStr = [utfStr precomposedStringWithCanonicalMapping];
- return build_string ([utfStr UTF8String]);
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ utfStr = [NSString stringWithUTF8String: SSDATA (str)];
+#ifdef NS_IMPL_COCOA
+ utfStr = [utfStr precomposedStringWithCanonicalMapping];
+#endif
+ ret = build_string ([utfStr UTF8String]);
+ [pool release];
+ return ret;
}
NSEvent *nxev;
CHECK_STRING (script);
- check_window_system ();
+ check_window_system (NULL);
block_input ();
========================================================================== */
-
-/* called from image.c */
-FRAME_PTR
-check_x_frame (Lisp_Object frame)
-{
- return check_ns_frame (frame);
-}
-
-
/* called from frame.c */
struct ns_display_info *
check_x_display_info (Lisp_Object frame)
wid - 1) / wid;
}
-
/* terms impl this instead of x-get-resource directly */
-const char *
-x_get_string_resource (XrmDatabase rdb, char *name, char *class)
+char *
+x_get_string_resource (XrmDatabase rdb, const char *name, const char *class)
{
/* remove appname prefix; TODO: allow for !="Emacs" */
- char *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
- const char *res;
- check_window_system ();
+ const char *res, *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
+
+ check_window_system (NULL);
if (inhibit_x_resources)
/* --quick was passed, so this is a no-op. */
return NULL;
res = ns_get_defaults_value (toCheck);
- return !res ? NULL :
- (!c_strncasecmp (res, "YES", 3) ? "true" :
- (!c_strncasecmp (res, "NO", 2) ? "false" : res));
+ return (!res ? NULL :
+ (!c_strncasecmp (res, "YES", 3) ? "true" :
+ (!c_strncasecmp (res, "NO", 2) ? "false" : (char *) res)));
}
Lisp_Object
x_get_focus_frame (struct frame *frame)
{
- struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame);
+ struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
Lisp_Object nsfocus;
if (!dpyinfo->x_focus_frame)
return nsfocus;
}
-
-int
-x_pixel_width (struct frame *f)
-{
- return FRAME_PIXEL_WIDTH (f);
-}
-
-
-int
-x_pixel_height (struct frame *f)
-{
- return FRAME_PIXEL_HEIGHT (f);
-}
-
-
-int
-x_screen_planes (struct frame *f)
-{
- return FRAME_NS_DISPLAY_INFO (f)->n_planes;
-}
-
-
-void
-x_sync (struct frame *f)
-{
- /* XXX Not implemented XXX */
- return;
-}
-
-
-
/* ==========================================================================
Lisp definitions that, for whatever reason, we can't alias as 'ns-XXX'.
(Lisp_Object color, Lisp_Object frame)
{
NSColor * col;
- check_window_system ();
+ check_window_system (NULL);
return ns_lisp_to_color (color, &col) ? Qnil : Qt;
}
(Lisp_Object color, Lisp_Object frame)
{
NSColor * col;
- CGFloat red, green, blue, alpha;
+ EmacsCGFloat red, green, blue, alpha;
- check_window_system ();
+ check_window_system (NULL);
CHECK_STRING (color);
if (ns_lisp_to_color (color, &col))
DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
doc: /* Internal function called by `display-color-p', which see. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
NSWindowDepth depth;
NSString *colorSpace;
- check_window_system ();
- depth = [ns_get_screen (display) depth];
+
+ check_ns_display_info (terminal);
+ depth = [[[NSScreen screens] objectAtIndex:0] depth];
colorSpace = NSColorSpaceFromDepth (depth);
return [colorSpace isEqualToString: NSDeviceWhiteColorSpace]
}
-DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p,
- Sx_display_grayscale_p, 0, 1, 0,
+DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
+ 0, 1, 0,
doc: /* Return t if the Nextstep display supports shades of gray.
Note that color displays do support shades of gray.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
-If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
NSWindowDepth depth;
- check_window_system ();
- depth = [ns_get_screen (display) depth];
+
+ check_ns_display_info (terminal);
+ depth = [[[NSScreen screens] objectAtIndex:0] depth];
return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil;
}
DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
0, 1, 0,
- doc: /* Return the width in pixels of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
-If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ doc: /* Return the width in pixels of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel width for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_window_system ();
- return make_number ((int) [ns_get_screen (display) frame].size.width);
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_width (dpyinfo));
}
DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
Sx_display_pixel_height, 0, 1, 0,
- doc: /* Return the height in pixels of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
-If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ doc: /* Return the height in pixels of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel height for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_window_system ();
- return make_number ((int) [ns_get_screen (display) frame].size.height);
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_height (dpyinfo));
+}
+
+#ifdef NS_IMPL_COCOA
+/* Returns the name for the screen that DICT came from, or NULL.
+ Caller must free return value.
+*/
+
+static char *
+ns_screen_name (CGDirectDisplayID did)
+{
+ char *name = NULL;
+ NSDictionary *info = (NSDictionary *)
+ IODisplayCreateInfoDictionary (CGDisplayIOServicePort (did),
+ kIODisplayOnlyPreferredName);
+ NSDictionary *names
+ = [info objectForKey:
+ [NSString stringWithUTF8String:kDisplayProductName]];
+
+ if ([names count] > 0) {
+ NSString *n = [names objectForKey: [[names allKeys] objectAtIndex:0]];
+ if (n != nil)
+ name = xstrdup ([n UTF8String]);
+ }
+
+ [info release];
+ return name;
+}
+#endif
+
+static Lisp_Object
+ns_make_monitor_attribute_list (struct MonitorInfo *monitors,
+ int n_monitors,
+ int primary_monitor,
+ const char *source)
+{
+ Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
+ Lisp_Object frame, rest;
+ NSArray *screens = [NSScreen screens];
+ int i;
+
+ FOR_EACH_FRAME (rest, frame)
+ {
+ struct frame *f = XFRAME (frame);
+
+ if (FRAME_NS_P (f))
+ {
+ NSView *view = FRAME_NS_VIEW (f);
+ NSScreen *screen = [[view window] screen];
+ NSUInteger k;
+
+ i = -1;
+ for (k = 0; i == -1 && k < [screens count]; ++k)
+ {
+ if ([screens objectAtIndex: k] == screen)
+ i = (int)k;
+ }
+
+ if (i > -1)
+ ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
+ }
+ }
+
+ return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
+ monitor_frames, source);
}
+DEFUN ("ns-display-monitor-attributes-list",
+ Fns_display_monitor_attributes_list,
+ Sns_display_monitor_attributes_list,
+ 0, 1, 0,
+ doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
-DEFUN ("display-usable-bounds", Fns_display_usable_bounds,
- Sns_display_usable_bounds, 0, 1, 0,
- doc: /* Return the bounds of the usable part of the screen.
-The return value is a list of integers (LEFT TOP WIDTH HEIGHT), which
-are the boundaries of the usable part of the screen, excluding areas
-reserved for the Mac menu, dock, and so forth.
+In addition to the standard attribute keys listed in
+`display-monitor-attributes-list', the following keys are contained in
+the attributes:
-The screen queried corresponds to DISPLAY, which should be either a
-frame, a display name (a string), or terminal ID. If omitted or nil,
-that stands for the selected frame's display. */)
- (Lisp_Object display)
+ source -- String describing the source from which multi-monitor
+ information is obtained, \"NS\" is always the source."
+
+Internal use only, use `display-monitor-attributes-list' instead. */)
+ (Lisp_Object terminal)
{
- NSScreen *screen;
- NSRect vScreen;
+ struct terminal *term = get_terminal (terminal, 1);
+ NSArray *screens;
+ NSUInteger i, n_monitors;
+ struct MonitorInfo *monitors;
+ Lisp_Object attributes_list = Qnil;
+ CGFloat primary_display_height = 0;
+
+ if (term->type != output_ns)
+ return Qnil;
- check_window_system ();
- screen = ns_get_screen (display);
- if (!screen)
+ screens = [NSScreen screens];
+ n_monitors = [screens count];
+ if (n_monitors == 0)
return Qnil;
- vScreen = [screen visibleFrame];
+ monitors = xzalloc (n_monitors * sizeof *monitors);
+
+ for (i = 0; i < [screens count]; ++i)
+ {
+ NSScreen *s = [screens objectAtIndex:i];
+ struct MonitorInfo *m = &monitors[i];
+ NSRect fr = [s frame];
+ NSRect vfr = [s visibleFrame];
+ short y, vy;
+
+#ifdef NS_IMPL_COCOA
+ NSDictionary *dict = [s deviceDescription];
+ NSNumber *nid = [dict objectForKey:@"NSScreenNumber"];
+ CGDirectDisplayID did = [nid unsignedIntValue];
+#endif
+ if (i == 0)
+ {
+ primary_display_height = fr.size.height;
+ y = (short) fr.origin.y;
+ vy = (short) vfr.origin.y;
+ }
+ else
+ {
+ // Flip y coordinate as NS has y starting from the bottom.
+ y = (short) (primary_display_height - fr.size.height - fr.origin.y);
+ vy = (short) (primary_display_height -
+ vfr.size.height - vfr.origin.y);
+ }
+
+ m->geom.x = (short) fr.origin.x;
+ m->geom.y = y;
+ m->geom.width = (unsigned short) fr.size.width;
+ m->geom.height = (unsigned short) fr.size.height;
+
+ m->work.x = (short) vfr.origin.x;
+ // y is flipped on NS, so vy - y are pixels missing at the bottom,
+ // and fr.size.height - vfr.size.height are pixels missing in total.
+ // Pixels missing at top are
+ // fr.size.height - vfr.size.height - vy + y.
+ // work.y is then pixels missing at top + y.
+ m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y;
+ m->work.width = (unsigned short) vfr.size.width;
+ m->work.height = (unsigned short) vfr.size.height;
+
+#ifdef NS_IMPL_COCOA
+ m->name = ns_screen_name (did);
- /* NS coordinate system is upside-down.
- Transform to screen-specific coordinates. */
- return list4i (vScreen.origin.x,
- [screen frame].size.height
- - vScreen.size.height - vScreen.origin.y,
- vScreen.size.width, vScreen.size.height);
+ {
+ CGSize mms = CGDisplayScreenSize (did);
+ m->mm_width = (int) mms.width;
+ m->mm_height = (int) mms.height;
+ }
+
+#else
+ // Assume 92 dpi as x-display-mm-height/x-display-mm-width does.
+ m->mm_width = (int) (25.4 * fr.size.width / 92.0);
+ m->mm_height = (int) (25.4 * fr.size.height / 92.0);
+#endif
+ }
+
+ // Primary monitor is always first for NS.
+ attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors,
+ 0, "NS");
+
+ free_monitors (monitors, n_monitors);
+ return attributes_list;
}
DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
0, 1, 0,
- doc: /* Return the number of bitplanes of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
+ doc: /* Return the number of bitplanes of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
- check_window_system ();
+ check_ns_display_info (terminal);
return make_number
- (NSBitsPerPixelFromDepth ([ns_get_screen (display) depth]));
+ (NSBitsPerPixelFromDepth ([[[NSScreen screens] objectAtIndex:0] depth]));
}
-DEFUN ("x-display-color-cells", Fx_display_color_cells,
- Sx_display_color_cells, 0, 1, 0,
- doc: /* Returns the number of color cells of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
+DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
+ 0, 1, 0,
+ doc: /* Returns the number of color cells of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
- struct ns_display_info *dpyinfo;
- check_window_system ();
-
- dpyinfo = check_ns_display_info (display);
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
/* We force 24+ bit depths to 24-bit to prevent an overflow. */
return make_number (1 << min (dpyinfo->n_planes, 24));
}
{
/* Absolute coordinates. */
pt.x = XINT (left);
- pt.y = x_display_pixel_height (FRAME_NS_DISPLAY_INFO (f)) - XINT (top)
+ pt.y = x_display_pixel_height (FRAME_DISPLAY_INFO (f)) - XINT (top)
- height;
}
else if (pt.x + XINT (dx) <= 0)
*root_x = 0; /* Can happen for negative dx */
else if (pt.x + XINT (dx) + width
- <= x_display_pixel_width (FRAME_NS_DISPLAY_INFO (f)))
+ <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
/* It fits to the right of the pointer. */
*root_x = pt.x + XINT (dx);
else if (width + XINT (dx) <= pt.x)
/* It fits below the pointer. */
*root_y = pt.y - height - XINT (dy);
else if (pt.y + XINT (dy) + height
- <= x_display_pixel_height (FRAME_NS_DISPLAY_INFO (f)))
+ <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
/* It fits above the pointer */
*root_y = pt.y + XINT (dy);
else
/* Put it on the top. */
- *root_y = x_display_pixel_height (FRAME_NS_DISPLAY_INFO (f)) - height;
+ *root_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f)) - height;
}
CHECK_STRING (string);
str = SSDATA (string);
- f = check_x_frame (frame);
+ f = decode_window_system_frame (frame);
if (NILP (timeout))
timeout = make_number (5);
else
========================================================================== */
-
-@implementation EmacsSavePanel
-#ifdef NS_IMPL_COCOA
-/* --------------------------------------------------------------------------
- These are overridden to intercept on OS X: ending panel restarts NSApp
- event loop if it is stopped. Not sure if this is correct behavior,
- perhaps should check if running and if so send an appdefined.
- -------------------------------------------------------------------------- */
-- (void) ok: (id)sender
-{
- [super ok: sender];
- panelOK = 1;
- [NSApp stop: self];
-}
-- (void) cancel: (id)sender
-{
- [super cancel: sender];
- [NSApp stop: self];
-}
-#endif
-- (NSString *) getFilename
-{
- return ns_filename_from_panel (self);
-}
-- (NSString *) getDirectory
+/*
+ Handle arrow/function/control keys and copy/paste/cut in file dialogs.
+ Return YES if handled, NO if not.
+ */
+static BOOL
+handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent)
{
- return ns_directory_from_panel (self);
-}
-@end
+ NSString *s;
+ int i;
+ BOOL ret = NO;
+ if ([theEvent type] != NSKeyDown) return NO;
+ s = [theEvent characters];
-@implementation EmacsOpenPanel
-#ifdef NS_IMPL_COCOA
-/* --------------------------------------------------------------------------
- These are overridden to intercept on OS X: ending panel restarts NSApp
- event loop if it is stopped. Not sure if this is correct behavior,
- perhaps should check if running and if so send an appdefined.
- -------------------------------------------------------------------------- */
-- (void) ok: (id)sender
-{
- [super ok: sender];
+ for (i = 0; i < [s length]; ++i)
+ {
+ int ch = (int) [s characterAtIndex: i];
+ switch (ch)
+ {
+ case NSHomeFunctionKey:
+ case NSDownArrowFunctionKey:
+ case NSUpArrowFunctionKey:
+ case NSLeftArrowFunctionKey:
+ case NSRightArrowFunctionKey:
+ case NSPageUpFunctionKey:
+ case NSPageDownFunctionKey:
+ case NSEndFunctionKey:
+ /* Don't send command modified keys, as those are handled in the
+ performKeyEquivalent method of the super class.
+ */
+ if (! ([theEvent modifierFlags] & NSCommandKeyMask))
+ {
+ [panel sendEvent: theEvent];
+ ret = YES;
+ }
+ break;
+ /* As we don't have the standard key commands for
+ copy/paste/cut/select-all in our edit menu, we must handle
+ them here. TODO: handle Emacs key bindings for copy/cut/select-all
+ here, paste works, because we have that in our Edit menu.
+ I.e. refactor out code in nsterm.m, keyDown: to figure out the
+ correct modifier.
+ */
+ case 'x': // Cut
+ case 'c': // Copy
+ case 'v': // Paste
+ case 'a': // Select all
+ if ([theEvent modifierFlags] & NSCommandKeyMask)
+ {
+ [NSApp sendAction:
+ (ch == 'x'
+ ? @selector(cut:)
+ : (ch == 'c'
+ ? @selector(copy:)
+ : (ch == 'v'
+ ? @selector(paste:)
+ : @selector(selectAll:))))
+ to:nil from:panel];
+ ret = YES;
+ }
+ default:
+ // Send all control keys, as the text field supports C-a, C-f, C-e
+ // C-b and more.
+ if ([theEvent modifierFlags] & NSControlKeyMask)
+ {
+ [panel sendEvent: theEvent];
+ ret = YES;
+ }
+ break;
+ }
+ }
- // If not choosing directories, and Open is pressed on a directory, return.
- if (! [self canChooseDirectories] && [self getDirectory] &&
- ! [self getFilename])
- return;
- panelOK = 1;
- [NSApp stop: self];
-}
-- (void) cancel: (id)sender
-{
- [super cancel: sender];
- [NSApp stop: self];
+ return ret;
}
-#endif
-- (NSString *) getFilename
+@implementation EmacsSavePanel
+- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
{
- return ns_filename_from_panel (self);
+ BOOL ret = handlePanelKeys (self, theEvent);
+ if (! ret)
+ ret = [super performKeyEquivalent:theEvent];
+ return ret;
}
-- (NSString *) getDirectory
+@end
+
+
+@implementation EmacsOpenPanel
+- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
{
- return ns_directory_from_panel (self);
+ // NSOpenPanel inherits NSSavePanel, so passing self is OK.
+ BOOL ret = handlePanelKeys (self, theEvent);
+ if (! ret)
+ ret = [super performKeyEquivalent:theEvent];
+ return ret;
}
-
@end
When you miniaturize a Group, Summary or Article frame, Gnus.tiff will
be used as the image of the icon representing the frame. */);
- Vns_icon_type_alist = Fcons (Qt, Qnil);
+ Vns_icon_type_alist = list1 (Qt);
DEFVAR_LISP ("ns-version-string", Vns_version_string,
doc: /* Toolkit version for NS Windowing. */);
defsubr (&Sx_server_version);
defsubr (&Sx_display_pixel_width);
defsubr (&Sx_display_pixel_height);
- defsubr (&Sns_display_usable_bounds);
+ defsubr (&Sns_display_monitor_attributes_list);
defsubr (&Sx_display_mm_width);
defsubr (&Sx_display_mm_height);
defsubr (&Sx_display_screens);
defsubr (&Sns_list_services);
defsubr (&Sns_perform_service);
defsubr (&Sns_convert_utf8_nfd_to_nfc);
- defsubr (&Sx_focus_frame);
defsubr (&Sns_popup_font_panel);
defsubr (&Sns_popup_color_panel);