emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to src/nsfns.m


From: Adrian Robert
Subject: [Emacs-diffs] Changes to src/nsfns.m
Date: Tue, 15 Jul 2008 18:16:05 +0000

CVSROOT:        /sources/emacs
Module name:    emacs
Changes by:     Adrian Robert <arobert> 08/07/15 18:15:19

Index: src/nsfns.m
===================================================================
RCS file: src/nsfns.m
diff -N src/nsfns.m
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ src/nsfns.m 15 Jul 2008 18:15:15 -0000      1.1
@@ -0,0 +1,2668 @@
+/* Functions for the NeXT/Open/GNUstep and MacOSX window system.
+
+   Copyright (C) 1989, 1992, 1993, 1994, 2005, 2006, 2008
+   Free Software Foundation, Inc..
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.
+
+Originally by Carl Edman
+Updated by Christian Limpach (address@hidden)
+OpenStep/Rhapsody port by Scott Bender (address@hidden)
+MacOSX/Aqua port by Christophe de Dinechin (address@hidden)
+GNUstep port and post-20 update by Adrian Robert (address@hidden)
+
+*/
+
+#include <signal.h>
+#include <math.h>
+#include "config.h"
+#include "lisp.h"
+#include "blockinput.h"
+#include "nsterm.h"
+#include "window.h"
+#include "buffer.h"
+#include "keyboard.h"
+#include "termhooks.h"
+#include "fontset.h"
+
+#include "character.h"
+#include "font.h"
+
+#if 0
+int fns_trace_num = 1;
+#define NSTRACE(x)        fprintf (stderr, "%s:%d: [%d] " #x "\n",        \
+                                  __FILE__, __LINE__, ++fns_trace_num)
+#else
+#define NSTRACE(x)
+#endif
+
+#ifdef HAVE_NS
+
+extern NSArray *ns_send_types, *ns_return_types, *ns_drag_types;
+
+extern Lisp_Object Qforeground_color;
+extern Lisp_Object Qbackground_color;
+extern Lisp_Object Qcursor_color;
+extern Lisp_Object Qinternal_border_width;
+extern Lisp_Object Qvisibility;
+extern Lisp_Object Qcursor_type;
+extern Lisp_Object Qicon_type;
+extern Lisp_Object Qicon_name;
+extern Lisp_Object Qicon_left;
+extern Lisp_Object Qicon_top;
+extern Lisp_Object Qleft;
+extern Lisp_Object Qright;
+extern Lisp_Object Qtop;
+extern Lisp_Object Qdisplay;
+extern Lisp_Object Qvertical_scroll_bars;
+extern Lisp_Object Qauto_raise;
+extern Lisp_Object Qauto_lower;
+extern Lisp_Object Qbox;
+extern Lisp_Object Qscroll_bar_width;
+extern Lisp_Object Qx_resource_name;
+extern Lisp_Object Qface_set_after_frame_default;
+extern Lisp_Object Qunderline, Qundefined;
+extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
+extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle;
+
+Lisp_Object Qnone;
+Lisp_Object Qns_frame_parameter;
+Lisp_Object Qbuffered;
+Lisp_Object Qfontsize;
+
+/* hack for OS X file panels */
+char panelOK = 0;
+
+/* Alist of elements (REGEXP . IMAGE) for images of icons associated
+   to frames.*/
+Lisp_Object Vns_icon_type_alist;
+
+EmacsTooltip *ns_tooltip;
+
+/* Need forward declaration here to preserve organizational integrity of file 
*/
+Lisp_Object Fns_open_connection (Lisp_Object, Lisp_Object, Lisp_Object);
+
+extern BOOL ns_in_resize;
+
+
+/* ==========================================================================
+
+    Internal utility functions
+
+   ========================================================================== 
*/
+
+
+void
+check_ns (void)
+{
+ if (NSApp == nil)
+   error ("OpenStep is not in use or not initialized");
+}
+
+
+/* Nonzero if we can use mouse menus. */
+int
+have_menus_p ()
+{
+  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)
+{
+  FRAME_PTR f;
+
+  if (NILP (frame))
+      f = SELECTED_FRAME ();
+  else
+    {
+      CHECK_LIVE_FRAME (frame);
+      f = XFRAME (frame);
+    }
+  if (! FRAME_NS_P (f))
+    error ("non-NS frame used");
+  return f;
+}
+
+
+/* Let the user specify an NS display with a frame.
+   nil stands for the selected frame--or, if that is not an NS frame,
+   the first NS 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);
+      else if (ns_display_list != 0)
+        return ns_display_list;
+      else
+        error ("NS windows are not in use or not initialized");
+    }
+  else if (INTEGERP (frame))
+    {
+      struct terminal *t = get_terminal (frame, 1);
+
+      if (t->type != output_ns)
+        error ("Terminal %d is not an NS display", XINT (frame));
+
+      return t->display_info.ns;
+    }
+  else if (STRINGP (frame))
+    return ns_display_info_for_name (frame);
+  else
+    {
+      FRAME_PTR f;
+
+      CHECK_LIVE_FRAME (frame);
+      f = XFRAME (frame);
+      if (! FRAME_NS_P (f))
+        error ("non-NS frame used");
+      return FRAME_NS_DISPLAY_INFO (f);
+    }
+  return NULL;  /* shut compiler up */
+}
+
+
+static id
+ns_get_window (Lisp_Object maybeFrame)
+{
+  id view =nil, window =nil;
+
+  if (!FRAMEP (maybeFrame) || !FRAME_NS_P (XFRAME (maybeFrame)))
+    maybeFrame = selected_frame;/*wrong_type_argument (Qframep, maybeFrame); */
+
+  if (!NILP (maybeFrame))
+    view = FRAME_NS_VIEW (XFRAME (maybeFrame));
+  if (view) window =[view window];
+
+  return window;
+}
+
+
+static NSScreen *
+ns_get_screen (Lisp_Object anythingUnderTheSun)
+{
+  id window =nil;
+  NSScreen *screen = 0;
+
+  struct terminal *terminal;
+  struct ns_display_info *dpyinfo;
+  struct frame *f = NULL;
+  Lisp_Object frame;
+
+  if (INTEGERP (anythingUnderTheSun)) {
+    /* we got a terminal */
+    terminal = get_terminal (anythingUnderTheSun, 1);
+    dpyinfo = terminal->display_info.ns;
+    f = dpyinfo->ns_focus_frame;
+    if (!f)
+      f = dpyinfo->ns_highlight_frame;
+
+  } else if (FRAMEP (anythingUnderTheSun) &&
+             FRAME_NS_P (XFRAME (anythingUnderTheSun))) {
+    /* we got a frame */
+    f = XFRAME (anythingUnderTheSun);
+
+  } else if (STRINGP (anythingUnderTheSun)) { /* FIXME/cl for multi-display */
+  }
+
+  if (!f)
+    f = SELECTED_FRAME ();
+  if (f)
+    {
+      XSETFRAME (frame, f);
+      window = ns_get_window (frame);
+    }
+
+  if (window)
+    screen = [window screen];
+  if (!screen)
+    screen = [NSScreen mainScreen];
+
+  return screen;
+}
+
+
+/* Return the X display structure for the display named NAME.
+   Open a new connection if necessary.  */
+struct ns_display_info *
+ns_display_info_for_name (name)
+     Lisp_Object name;
+{
+  Lisp_Object names;
+  struct ns_display_info *dpyinfo;
+
+  CHECK_STRING (name);
+
+  for (dpyinfo = ns_display_list, names = ns_display_name_list;
+       dpyinfo;
+       dpyinfo = dpyinfo->next, names = XCDR (names))
+    {
+      Lisp_Object tem;
+      tem = Fstring_equal (XCAR (XCAR (names)), name);
+      if (!NILP (tem))
+        return dpyinfo;
+    }
+
+  error ("Emacs for OpenStep does not yet support multi-display.");
+
+  Fns_open_connection (name, Qnil, Qnil);
+  dpyinfo = ns_display_list;
+
+  if (dpyinfo == 0)
+    error ("OpenStep on %s not responding.\n", XSTRING (name)->data);
+
+  return dpyinfo;
+}
+
+
+static Lisp_Object
+interpret_services_menu (NSMenu *menu, Lisp_Object prefix, Lisp_Object old)
+/* --------------------------------------------------------------------------
+   Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
+   -------------------------------------------------------------------------- 
*/
+{
+  int i, count;
+  id<NSMenuItem> item;
+  const char *name;
+  Lisp_Object nameStr;
+  unsigned short key;
+  NSString *keys;
+  Lisp_Object res;
+
+  count = [menu numberOfItems];
+  for (i = 0; i<count; i++)
+    {
+      item = [menu itemAtIndex: i];
+      name = [[item title] UTF8String];
+      if (!name) continue;
+
+      nameStr = build_string (name);
+
+      if ([item hasSubmenu])
+        {
+          old = interpret_services_menu ([item submenu],
+                                        Fcons (nameStr, prefix), old);
+        }
+      else
+        {
+          keys = [item keyEquivalent];
+          if (keys && [keys length] )
+            {
+              key = [keys characterAtIndex: 0];
+              res = make_number (key|super_modifier);
+            }
+          else
+            {
+              res = Qundefined;
+            }
+          old = Fcons (Fcons (res,
+                            Freverse (Fcons (nameStr,
+                                           prefix))),
+                    old);
+        }
+    }
+  return old;
+}
+
+
+
+/* ==========================================================================
+
+    Frame parameter setters
+
+   ========================================================================== 
*/
+
+
+static void
+ns_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  NSColor *col;
+
+  if (ns_lisp_to_color (arg, &col))
+    {
+      store_frame_param (f, Qforeground_color, oldval);
+      error ("Unknown color");
+    }
+
+  [col retain];
+  [f->output_data.ns->foreground_color release];
+  f->output_data.ns->foreground_color = col;
+
+  if (FRAME_NS_VIEW (f))
+    {
+      update_face_from_frame_parameter (f, Qforeground_color, arg);
+      /*recompute_basic_faces (f); */
+      if (FRAME_VISIBLE_P (f))
+        redraw_frame (f);
+    }
+}
+
+
+static void
+ns_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  struct face *face;
+  NSColor *col;
+  NSView *view = FRAME_NS_VIEW (f);
+  float alpha;
+
+  if (ns_lisp_to_color (arg, &col))
+    {
+      store_frame_param (f, Qbackground_color, oldval);
+      error ("Unknown color");
+    }
+
+  /* clear the frame; in some instances the NS-internal GC appears not to
+     update, or it does update and cannot clear old text properly */
+  if (FRAME_VISIBLE_P (f))
+    ns_clear_frame (f);
+
+  [col retain];
+  [f->output_data.ns->background_color release];
+  f->output_data.ns->background_color = col;
+  if (view != nil)
+    {
+      [[view window] setBackgroundColor: col];
+      alpha = [col alphaComponent];
+
+#ifdef NS_IMPL_COCOA
+      /* the alpha code below only works on 10.4, so we need to do something
+         else (albeit less good) otherwise.
+         Check NSApplication.h for useful NSAppKitVersionNumber values. */
+      if (NSAppKitVersionNumber < 744.0)
+          [[view window] setAlphaValue: alpha];
+#endif
+
+      if (alpha != 1.0)
+          [[view window] setOpaque: NO];
+      else
+          [[view window] setOpaque: YES];
+
+      face = FRAME_DEFAULT_FACE (f);
+      if (face)
+        {
+          col = NS_FACE_BACKGROUND (face);
+          face->background =
+            (EMACS_UINT) [[col colorWithAlphaComponent: alpha] retain];
+          [col release];
+
+          update_face_from_frame_parameter (f, Qbackground_color, arg);
+        }
+
+      if (FRAME_VISIBLE_P (f))
+        redraw_frame (f);
+    }
+}
+
+
+static void
+ns_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  NSColor *col;
+
+  if (ns_lisp_to_color (arg, &col))
+    {
+      store_frame_param (f, Qcursor_color, oldval);
+      error ("Unknown color");
+    }
+
+  [f->output_data.ns->desired_cursor_color release];
+  f->output_data.ns->desired_cursor_color = [col retain];
+
+  if (FRAME_VISIBLE_P (f))
+    {
+      x_update_cursor (f, 0);
+      x_update_cursor (f, 1);
+    }
+  update_face_from_frame_parameter (f, Qcursor_color, arg);
+}
+
+
+static void
+ns_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  NSTRACE (ns_set_icon_name);
+
+  if (ns_in_resize)
+    return;
+
+  /* see if it's changed */
+  if (STRINGP (arg))
+    {
+      if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
+        return;
+    }
+  else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
+    return;
+
+  f->icon_name = arg;
+
+  if (NILP (arg))
+    {
+      if (!NILP (f->title))
+        arg = f->title;
+      else
+        /* explicit name and no icon-name -> explicit_name */
+        if (f->explicit_name)
+          arg = f->name;
+        else
+          {
+            /* no explicit name and no icon-name ->
+               name has to be rebuild from icon_title_format */
+            windows_or_buffers_changed++;
+            return;
+          }
+    }
+
+  /* Don't change the name if it's already NAME.  */
+  if ([[view window] miniwindowTitle] &&
+      ([[[view window] miniwindowTitle]
+             isEqualToString: [NSString stringWithUTF8String:
+                                           XSTRING (arg)->data]]))
+    return;
+
+  [[view window] setMiniwindowTitle:
+        [NSString stringWithUTF8String: XSTRING (arg)->data]];
+}
+
+
+static void
+ns_set_name_iconic (struct frame *f, Lisp_Object name, int explicit)
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  NSTRACE (ns_set_name_iconic);
+
+  if (ns_in_resize)
+    return;
+
+  /* Make sure that requests from lisp code override requests from
+     Emacs redisplay code.  */
+  if (explicit)
+    {
+      /* If we're switching from explicit to implicit, we had better
+         update the mode lines and thereby update the title.  */
+      if (f->explicit_name && NILP (name))
+        update_mode_lines = 1;
+
+      f->explicit_name = ! NILP (name);
+    }
+  else if (f->explicit_name)
+    name = f->name;
+
+  /* title overrides explicit name */
+  if (! NILP (f->title))
+    name = f->title;
+
+  /* icon_name overrides title and explicit name */
+  if (! NILP (f->icon_name))
+    name = f->icon_name;
+
+  if (NILP (name))
+    name = build_string
+        ([[[NSProcessInfo processInfo] processName] UTF8String]);
+  else
+    CHECK_STRING (name);
+
+  /* Don't change the name if it's already NAME.  */
+  if ([[view window] miniwindowTitle] &&
+      ([[[view window] miniwindowTitle]
+             isEqualToString: [NSString stringWithUTF8String:
+                                           XSTRING (name)->data]]))
+    return;
+
+  [[view window] setMiniwindowTitle:
+        [NSString stringWithUTF8String: XSTRING (name)->data]];
+}
+
+
+static void
+ns_set_name (struct frame *f, Lisp_Object name, int explicit)
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  NSTRACE (ns_set_name);
+
+  if (ns_in_resize)
+    return;
+
+  /* Make sure that requests from lisp code override requests from
+     Emacs redisplay code.  */
+  if (explicit)
+    {
+      /* If we're switching from explicit to implicit, we had better
+         update the mode lines and thereby update the title.  */
+      if (f->explicit_name && NILP (name))
+        update_mode_lines = 1;
+
+      f->explicit_name = ! NILP (name);
+    }
+  else if (f->explicit_name)
+    return;
+
+  if (NILP (name))
+    name = build_string
+        ([[[NSProcessInfo processInfo] processName] UTF8String]);
+
+  f->name = name;
+
+  /* title overrides explicit name */
+  if (! NILP (f->title))
+    name = f->title;
+
+  CHECK_STRING (name);
+
+  /* Don't change the name if it's already NAME.  */
+  if ([[[view window] title]
+            isEqualToString: [NSString stringWithUTF8String:
+                                          XSTRING (name)->data]])
+    return;
+  [[view window] setTitle: [NSString stringWithUTF8String:
+                                        XSTRING (name)->data]];
+}
+
+
+/* This function should be called when the user's lisp code has
+   specified a name for the frame; the name will override any set by the
+   redisplay code.  */
+static void
+ns_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+{
+  NSTRACE (ns_explicitly_set_name);
+  ns_set_name_iconic (f, arg, 1);
+  ns_set_name (f, arg, 1);
+}
+
+
+/* This function should be called by Emacs redisplay code to set the
+   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)
+{
+  NSTRACE (x_implicitly_set_name);
+  if (FRAME_ICONIFIED_P (f))
+    ns_set_name_iconic (f, arg, 0);
+  else
+    ns_set_name (f, arg, 0);
+}
+
+
+/* Change the title of frame F to NAME.
+   If NAME is nil, use the frame name as the title.
+
+   If EXPLICIT is non-zero, that indicates that lisp code is setting the
+   name; if NAME is a string, set F's name to NAME and set
+   F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
+
+   If EXPLICIT is zero, that indicates that Emacs redisplay code is
+   suggesting a new name, which lisp code should override; if
+   F->explicit_name is set, ignore the new name; otherwise, set it.  */
+static void
+ns_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
+{
+  NSTRACE (ns_set_title);
+  /* Don't change the title if it's already NAME.  */
+  if (EQ (name, f->title))
+    return;
+
+  update_mode_lines = 1;
+
+  f->title = name;
+}
+
+
+void
+ns_set_name_as_filename (struct frame *f)
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  Lisp_Object name;
+  Lisp_Object buf = XWINDOW (f->selected_window)->buffer;
+  const char *title;
+  NSAutoreleasePool *pool;
+  NSTRACE (ns_set_name_as_filename);
+
+  if (f->explicit_name || ! NILP (f->title) || ns_in_resize)
+    return;
+
+  BLOCK_INPUT;
+  pool = [[NSAutoreleasePool alloc] init];
+  name =XBUFFER (buf)->filename;
+  if (NILP (name) || FRAME_ICONIFIED_P (f)) name =XBUFFER (buf)->name;
+
+  if (FRAME_ICONIFIED_P (f) && !NILP (f->icon_name))
+    name = f->icon_name;
+
+  if (NILP (name))
+    name = build_string
+        ([[[NSProcessInfo processInfo] processName] UTF8String]);
+  else
+    CHECK_STRING (name);
+
+  title = FRAME_ICONIFIED_P (f) ? [[[view window] miniwindowTitle] UTF8String]
+                                : [[[view window] title] UTF8String];
+
+  if (title && (! strcmp (title, XSTRING (name)->data)))
+    {
+      [pool release];
+      UNBLOCK_INPUT;
+      return;
+    }
+
+  if (! FRAME_ICONIFIED_P (f))
+    {
+#ifdef NS_IMPL_COCOA
+      /* work around a bug observed on 10.3 where
+         setTitleWithRepresentedFilename does not clear out previous state
+         if given filename does not exist */
+      NSString *str = [NSString stringWithUTF8String: XSTRING (name)->data];
+      if (![[NSFileManager defaultManager] fileExistsAtPath: str])
+        {
+          [[view window] setTitleWithRepresentedFilename: @""];
+          [[view window] setTitle: str];
+        }
+      else
+        {
+          [[view window] setTitleWithRepresentedFilename: str];
+        }
+#else
+      [[view window] setTitleWithRepresentedFilename:
+                         [NSString stringWithUTF8String: XSTRING 
(name)->data]];
+#endif
+      f->name = name;
+    }
+  else
+    {
+      [[view window] setMiniwindowTitle:
+            [NSString stringWithUTF8String: XSTRING (name)->data]];
+    }
+  [pool release];
+  UNBLOCK_INPUT;
+}
+
+
+void
+ns_set_doc_edited (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  NSAutoreleasePool *pool;
+  BLOCK_INPUT;
+  pool = [[NSAutoreleasePool alloc] init];
+  [[view window] setDocumentEdited: !NILP (arg)];
+  [pool release];
+  UNBLOCK_INPUT;
+}
+
+
+static void
+ns_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+  int nlines;
+  int olines = FRAME_MENU_BAR_LINES (f);
+  if (FRAME_MINIBUF_ONLY_P (f))
+    return;
+
+  if (INTEGERP (value))
+    nlines = XINT (value);
+  else
+    nlines = 0;
+
+  FRAME_MENU_BAR_LINES (f) = 0;
+  if (nlines)
+    {
+      FRAME_EXTERNAL_MENU_BAR (f) = 1;
+/* does for all frames, whereas we just want for one frame
+        [NSMenu setMenuBarVisible: YES]; */
+    }
+  else
+    {
+      if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
+        free_frame_menubar (f);
+/*      [NSMenu setMenuBarVisible: NO]; */
+      FRAME_EXTERNAL_MENU_BAR (f) = 0;
+    }
+}
+
+
+/* 23: PENDING: there is an erroneous direct call in window.c to this fn */
+void
+x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+  ns_set_menu_bar_lines (f, value, oldval);
+}
+
+
+/* 23: toolbar support */
+static void
+ns_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+  int nlines;
+  Lisp_Object root_window;
+
+  if (FRAME_MINIBUF_ONLY_P (f))
+    return;
+
+  if (INTEGERP (value) && XINT (value) >= 0)
+    nlines = XFASTINT (value);
+  else
+    nlines = 0;
+
+  if (nlines)
+    {
+      FRAME_EXTERNAL_TOOL_BAR (f) = 1;
+      update_frame_tool_bar (f);
+    }
+  else
+    {
+      if (FRAME_EXTERNAL_TOOL_BAR (f))
+        {
+          free_frame_tool_bar (f);
+          FRAME_EXTERNAL_TOOL_BAR (f) = 0;
+        }
+    }
+
+  x_set_window_size (f, 0, f->text_cols, f->text_lines);
+}
+
+
+/* 23: PENDING: there is an erroneous direct call in window.c to this fn */
+void
+x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+  ns_set_tool_bar_lines (f, value, oldval);
+}
+
+
+void
+ns_implicitly_set_icon_type (struct frame *f)
+{
+  Lisp_Object tem;
+  EmacsView *view = FRAME_NS_VIEW (f);
+  id image =nil;
+  Lisp_Object chain, elt;
+  NSAutoreleasePool *pool;
+  BOOL setMini = YES;
+
+  NSTRACE (ns_implicitly_set_icon_type);
+
+  BLOCK_INPUT;
+  pool = [[NSAutoreleasePool alloc] init];
+  if (f->output_data.ns->miniimage
+      && [[NSString stringWithUTF8String: XSTRING (f->name)->data]
+               isEqualToString: [(NSImage *)f->output_data.ns->miniimage 
name]])
+    {
+      [pool release];
+      UNBLOCK_INPUT;
+      return;
+    }
+
+  tem = assq_no_quit (Qicon_type, f->param_alist);
+  if (CONSP (tem) && ! NILP (XCDR (tem)))
+    {
+      [pool release];
+      UNBLOCK_INPUT;
+      return;
+    }
+
+  for (chain = Vns_icon_type_alist;
+       (image = nil) && CONSP (chain);
+       chain = XCDR (chain))
+    {
+      elt = XCAR (chain);
+      /* special case: 't' means go by file type */
+      if (SYMBOLP (elt) && elt == Qt && XSTRING (f->name)->data[0] == '/')
+        {
+          NSString *str =
+            [NSString stringWithUTF8String: XSTRING (f->name)->data];
+          if ([[NSFileManager defaultManager] fileExistsAtPath: str])
+            image = [[[NSWorkspace sharedWorkspace] iconForFile: str] retain];
+        }
+      else if (CONSP (elt) &&
+               STRINGP (XCAR (elt)) &&
+               STRINGP (XCDR (elt)) &&
+               fast_string_match (XCAR (elt), f->name) >= 0)
+        {
+          image = [EmacsImage allocInitFromFile: XCDR (elt)];
+          if (image == nil)
+            image = [[NSImage imageNamed:
+                               [NSString stringWithUTF8String:
+                                           XSTRING (XCDR (elt))->data]] 
retain];
+        }
+    }
+
+  if (image == nil)
+    {
+      image = [[[NSWorkspace sharedWorkspace] iconForFileType: @"text"] 
retain];
+      setMini = NO;
+    }
+
+  [f->output_data.ns->miniimage release];
+  f->output_data.ns->miniimage = image;
+  [view setMiniwindowImage: setMini];
+  [pool release];
+  UNBLOCK_INPUT;
+}
+
+
+static void
+ns_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  EmacsView *view = FRAME_NS_VIEW (f);
+  id image = nil;
+  BOOL setMini = YES;
+
+  NSTRACE (ns_set_icon_type);
+
+  if (!NILP (arg) && SYMBOLP (arg))
+    {
+      arg =build_string (XSTRING (XSYMBOL (arg)->xname)->data);
+      store_frame_param (f, Qicon_type, arg);
+    }
+
+  /* do it the implicit way */
+  if (NILP (arg))
+    {
+      ns_implicitly_set_icon_type (f);
+      return;
+    }
+
+  CHECK_STRING (arg);
+
+  image = [EmacsImage allocInitFromFile: arg];
+  if (image == nil)
+    image =[NSImage imageNamed: [NSString stringWithUTF8String:
+                                            XSTRING (arg)->data]];
+
+  if (image == nil)
+    {
+      image = [NSImage imageNamed: @"text"];
+      setMini = NO;
+    }
+
+  f->output_data.ns->miniimage = image;
+  [view setMiniwindowImage: setMini];
+}
+
+
+/* 23: added Xism; we stub out (we do implement this in ns-win.el) */
+int
+XParseGeometry (char *string, int *x, int *y,
+                unsigned int *width, unsigned int *height)
+{
+  message1 ("Warning: XParseGeometry not supported under NS.\n");
+  return 0;
+}
+
+
+/*PENDING: move to nsterm? */
+int
+ns_lisp_to_cursor_type (Lisp_Object arg)
+{
+  char *str;
+  if (XTYPE (arg) == Lisp_String)
+    str =XSTRING (arg)->data;
+  else if (XTYPE (arg) == Lisp_Symbol)
+    str =XSTRING (XSYMBOL (arg)->xname)->data;
+  else return -1;
+  if (!strcmp (str, "box"))     return filled_box;
+  if (!strcmp (str, "hollow"))  return hollow_box;
+  if (!strcmp (str, "underscore")) return underscore;
+  if (!strcmp (str, "bar"))     return bar;
+  if (!strcmp (str, "no"))      return no_highlight;
+  return -1;
+}
+
+
+Lisp_Object
+ns_cursor_type_to_lisp (int arg)
+{
+  switch (arg)
+    {
+    case filled_box: return Qbox;
+    case hollow_box: return intern ("hollow");
+    case underscore: return intern ("underscore");
+    case bar:       return intern ("bar");
+    case no_highlight:
+    default:        return intern ("no");
+    }
+}
+
+
+static void
+ns_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  int val;
+
+  val = ns_lisp_to_cursor_type (arg);
+  if (val >= 0)
+    {
+      f->output_data.ns->desired_cursor =val;
+    }
+  else
+    {
+      store_frame_param (f, Qcursor_type, oldval);
+      error ("the `cursor-type' frame parameter should be either `no', `box', \
+`hollow', `underscore' or `bar'.");
+    }
+
+  update_mode_lines++;
+}
+
+
+/* 23: called to set mouse pointer color, but all other terms use it to
+       initialize pointer types (and don't set the color ;) */
+static void
+ns_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  /* don't think we can do this on NS */
+}
+
+
+static void
+ns_icon (struct frame *f, Lisp_Object parms)
+/* --------------------------------------------------------------------------
+   Strangely-named function to set icon position parameters in frame.
+   This is irrelevant under OS X, but might be needed under GNUstep,
+   depending on the window manager used.  Note, this is not a standard
+   frame parameter-setter; it is called directly from x-create-frame.
+   -------------------------------------------------------------------------- 
*/
+{
+  Lisp_Object icon_x, icon_y;
+  struct ns_display_info *dpyinfo = check_ns_display_info (Qnil);
+
+  f->output_data.ns->icon_top = Qnil;
+  f->output_data.ns->icon_left = Qnil;
+
+  /* Set the position of the icon.  */
+  icon_x = x_get_arg (dpyinfo, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
+  icon_y = x_get_arg (dpyinfo, parms, Qicon_top, 0, 0,  RES_TYPE_NUMBER);
+  if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
+    {
+      CHECK_NUMBER (icon_x);
+      CHECK_NUMBER (icon_y);
+      f->output_data.ns->icon_top = icon_y;
+      f->output_data.ns->icon_left = icon_x;
+    }
+  else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
+    error ("Both left and top icon corners of icon must be specified");
+}
+
+
+/* 23 Note: commented out ns_... entries are no longer used in 23.
+            commented out x_... entries have not been implemented yet.
+   see frame.c for template, also where all generic OK functions are impl */
+frame_parm_handler ns_frame_parm_handlers[] =
+{
+  x_set_autoraise, /* generic OK */
+  x_set_autolower, /* generic OK */
+  ns_set_background_color,
+  0, /* x_set_border_color,  may be impossible under NS */
+  0, /* x_set_border_width,  may be impossible under NS */
+  ns_set_cursor_color,
+  ns_set_cursor_type,
+  x_set_font, /* generic OK */
+  ns_set_foreground_color,
+  ns_set_icon_name,
+  ns_set_icon_type,
+  x_set_internal_border_width, /* generic OK */
+  ns_set_menu_bar_lines,
+  ns_set_mouse_color,
+  ns_explicitly_set_name,
+  x_set_scroll_bar_width, /* generic OK */
+  ns_set_title,
+  x_set_unsplittable, /* generic OK */
+  x_set_vertical_scroll_bars, /* generic OK */
+  x_set_visibility, /* generic OK */
+  ns_set_tool_bar_lines,
+  0, /* x_set_scroll_bar_foreground, will ignore (not possible on NS) */
+  0, /* x_set_scroll_bar_background,  will ignore (not possible on NS) */
+  x_set_screen_gamma, /* generic OK */
+  x_set_line_spacing, /* generic OK, sets f->extra_line_spacing to int */
+  x_set_fringe_width, /* generic OK */
+  x_set_fringe_width, /* generic OK */
+  0, /* x_set_wait_for_wm, will ignore */
+  0,  /* x_set_fullscreen will ignore */
+  x_set_font_backend /* generic OK */
+};
+
+
+DEFUN ("x-create-frame", Fns_create_frame, Sns_create_frame,
+       1, 1, 0,
+       "Make a new NS window, which is called a \"frame\" in Emacs terms.\n\
+Return an Emacs frame object representing the X window.\n\
+ALIST is an alist of frame parameters.\n\
+If the parameters specify that the frame should not have a minibuffer,\n\
+and do not specify a specific minibuffer window to use,\n\
+then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
+be shared by the new frame.")
+     (parms)
+     Lisp_Object parms;
+{
+  static int desc_ctr = 1;
+  struct frame *f;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+  Lisp_Object frame, tem;
+  Lisp_Object name;
+  int minibuffer_only = 0;
+  int count = specpdl_ptr - specpdl;
+  Lisp_Object display;
+  struct ns_display_info *dpyinfo = NULL;
+  Lisp_Object parent;
+  struct kboard *kb;
+  Lisp_Object tfont, tfontsize;
+  int window_prompting = 0;
+  int width, height;
+
+  check_ns ();
+
+  display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_STRING);
+  if (EQ (display, Qunbound))
+    display = Qnil;
+  dpyinfo = check_ns_display_info (display);
+
+  if (!dpyinfo->terminal->name)
+    error ("Terminal is not live, can't create new frames on it");
+
+  kb = dpyinfo->terminal->kboard;
+
+  name = x_get_arg (dpyinfo, parms, Qname, 0, 0, RES_TYPE_STRING);
+  if (!STRINGP (name)
+      && ! EQ (name, Qunbound)
+      && ! NILP (name))
+    error ("Invalid frame name--not a string or nil");
+
+  if (STRINGP (name))
+    Vx_resource_name = name;
+
+  parent = x_get_arg (dpyinfo, parms, Qparent_id, 0, 0, RES_TYPE_NUMBER);
+  if (EQ (parent, Qunbound))
+    parent = Qnil;
+  if (! NILP (parent))
+    CHECK_NUMBER (parent);
+
+  frame = Qnil;
+  GCPRO4 (parms, parent, name, frame);
+
+  tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
+                  RES_TYPE_SYMBOL);
+  if (EQ (tem, Qnone) || NILP (tem))
+    {
+      f = make_frame_without_minibuffer (Qnil, kb, display);
+    }
+  else if (EQ (tem, Qonly))
+    {
+      f = make_minibuffer_frame ();
+      minibuffer_only = 1;
+    }
+  else if (WINDOWP (tem))
+    {
+      f = make_frame_without_minibuffer (tem, kb, display);
+    }
+  else
+    {
+      f = make_frame (1);
+    }
+
+  /* Set the name; the functions to which we pass f expect the name to
+     be set.  */
+  if (EQ (name, Qunbound) || NILP (name) || (XTYPE (name) != Lisp_String))
+    {
+      f->name =
+          build_string ([[[NSProcessInfo processInfo] processName] 
UTF8String]);
+      f->explicit_name =0;
+    }
+  else
+    {
+      f->name = name;
+      f->explicit_name = 1;
+      specbind (Qx_resource_name, name);
+    }
+
+  XSETFRAME (frame, f);
+  FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
+
+  f->terminal = dpyinfo->terminal;
+  f->terminal->reference_count++;
+
+  f->output_method = output_ns;
+  f->output_data.ns = (struct ns_output *)xmalloc (sizeof 
*(f->output_data.ns));
+  bzero (f->output_data.ns, sizeof (*(f->output_data.ns)));
+
+  FRAME_FONTSET (f) = -1;
+
+  /* record_unwind_protect (unwind_create_frame, frame); safety; maybe later? 
*/
+
+  f->icon_name = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
+                            RES_TYPE_STRING);
+  if (EQ (f->icon_name, Qunbound) || (XTYPE (f->icon_name) != Lisp_String))
+    f->icon_name = Qnil;
+
+  FRAME_NS_DISPLAY_INFO (f) = dpyinfo;
+
+  f->output_data.ns->window_desc = desc_ctr++;
+  if (!NILP (parent))
+    {
+      f->output_data.ns->parent_desc = (Window) XFASTINT (parent);
+      f->output_data.ns->explicit_parent = 1;
+    }
+  else
+    {
+      f->output_data.ns->parent_desc = FRAME_NS_DISPLAY_INFO (f)->root_window;
+      f->output_data.ns->explicit_parent = 0;
+    }
+
+  f->resx = dpyinfo->resx;
+  f->resy = dpyinfo->resy;
+
+  BLOCK_INPUT;
+  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,
+                                    make_number (0 /*(int)[font pointSize]*/),
+                                    "fontSize", "FontSize", RES_TYPE_NUMBER);
+    tfont = x_default_parameter (f, parms, Qfont,
+                                 build_string ([[font fontName] UTF8String]),
+                                 "font", "Font", RES_TYPE_STRING);
+  }
+  UNBLOCK_INPUT;
+
+  x_default_parameter (f, parms, Qborder_width, make_number (0),
+                      "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qinternal_border_width, make_number (2),
+                      "internalBorderWidth", "InternalBorderWidth",
+                      RES_TYPE_NUMBER);
+
+  /* default scrollbars on right on Mac */
+  {
+      Lisp_Object spos = 
+#ifdef NS_IMPL_GNUSTEP
+          Qt;
+#else
+          Qright;
+#endif
+          x_default_parameter (f, parms, Qvertical_scroll_bars, spos,
+                              "verticalScrollBars", "VerticalScrollBars",
+                              RES_TYPE_SYMBOL);
+  }
+  x_default_parameter (f, parms, Qforeground_color, build_string ("Black"),
+                      "foreground", "Foreground", RES_TYPE_STRING);
+  x_default_parameter (f, parms, Qbackground_color, build_string ("White"),
+                      "background", "Background", RES_TYPE_STRING);
+  x_default_parameter (f, parms, Qcursor_color, build_string ("grey"),
+                      "cursorColor", "CursorColor", RES_TYPE_STRING);
+  /*PENDING: not suppported yet in NS */
+  x_default_parameter (f, parms, Qline_spacing, Qnil,
+                      "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qleft_fringe, Qnil,
+                      "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qright_fringe, Qnil,
+                      "rightFringe", "RightFringe", RES_TYPE_NUMBER);
+  /* end PENDING */
+
+  init_frame_faces (f);
+
+  x_default_parameter (f, parms, Qmenu_bar_lines, make_number (0), "menuBar",
+                      "menuBar", RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qtool_bar_lines, make_number (0), "toolBar",
+                      "toolBar", RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate",
+                       "BufferPredicate", RES_TYPE_SYMBOL);
+  x_default_parameter (f, parms, Qtitle, Qnil, "title", "Title",
+                       RES_TYPE_STRING);
+
+/*PENDING: other terms seem to get away w/o this complexity.. */
+  if (NILP (Fassq (Qwidth, parms)))
+    {
+      Lisp_Object value =
+          x_get_arg (dpyinfo, parms, Qwidth, "width", "Width", 
RES_TYPE_NUMBER);
+      if (! EQ (value, Qunbound))
+       parms = Fcons (Fcons (Qwidth, value), parms);
+    }
+  if (NILP (Fassq (Qheight, parms)))
+    {
+      Lisp_Object value =
+          x_get_arg (dpyinfo, parms, Qheight, "height", "Height",
+                     RES_TYPE_NUMBER);
+      if (! EQ (value, Qunbound))
+       parms = Fcons (Fcons (Qheight, value), parms);
+    }
+  if (NILP (Fassq (Qleft, parms)))
+    {
+      Lisp_Object value =
+          x_get_arg (dpyinfo, parms, Qleft, "left", "Left", RES_TYPE_NUMBER);
+      if (! EQ (value, Qunbound))
+       parms = Fcons (Fcons (Qleft, value), parms);
+    }
+  if (NILP (Fassq (Qtop, parms)))
+    {
+      Lisp_Object value =
+          x_get_arg (dpyinfo, parms, Qtop, "top", "Top", RES_TYPE_NUMBER);
+      if (! EQ (value, Qunbound))
+       parms = Fcons (Fcons (Qtop, value), parms);
+    }
+
+  window_prompting = x_figure_window_size (f, parms, 1);
+
+  tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
+  f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !EQ (tem, Qnil));
+
+  /* NOTE: on other terms, this is done in set_mouse_color, however this
+     was not getting called under NS */
+  f->output_data.ns->text_cursor = [NSCursor IBeamCursor];
+  f->output_data.ns->nontext_cursor = [NSCursor arrowCursor];
+  f->output_data.ns->modeline_cursor = [NSCursor pointingHandCursor];
+  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 =
+    [NSCursor arrowCursor];
+  f->output_data.ns->current_pointer = f->output_data.ns->text_cursor;
+
+  [[EmacsView alloc] initFrameFromEmacs: f];
+
+  ns_icon (f, parms);
+
+  /* It is now ok to make the frame official even if we get an error below.
+     The frame needs to be on Vframe_list or making it visible won't work. */
+  Vframe_list = Fcons (frame, Vframe_list);
+  /*FRAME_NS_DISPLAY_INFO (f)->reference_count++; */
+
+  x_default_parameter (f, parms, Qcursor_type, Qbox, "cursorType", 
"CursorType",
+                      RES_TYPE_SYMBOL);
+  x_default_parameter (f, parms, Qscroll_bar_width, Qnil, "scrollBarWidth",
+                      "ScrollBarWidth", RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qicon_type, Qnil, "bitmapIcon", "BitmapIcon",
+                      RES_TYPE_SYMBOL);
+  x_default_parameter (f, parms, Qauto_raise, Qnil, "autoRaise", "AutoRaise",
+                      RES_TYPE_BOOLEAN);
+  x_default_parameter (f, parms, Qauto_lower, Qnil, "autoLower", "AutoLower",
+                      RES_TYPE_BOOLEAN);
+  x_default_parameter (f, parms, Qbuffered, Qt, "buffered", "Buffered",
+                      RES_TYPE_BOOLEAN);
+
+  width = FRAME_COLS (f);
+  height = FRAME_LINES (f);
+
+  SET_FRAME_COLS (f, 0);
+  FRAME_LINES (f) = 0;
+  change_frame_size (f, height, width, 1, 0, 0);
+
+  if (! f->output_data.ns->explicit_parent)
+    {
+        tem = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_BOOLEAN);
+        if (EQ (tem, Qunbound))
+            tem = Qnil;
+
+        x_set_visibility (f, tem, Qnil);
+        if (EQ (tem, Qt))
+            [[FRAME_NS_VIEW (f) window] makeKeyWindow];
+    }
+
+  if (FRAME_HAS_MINIBUF_P (f)
+      && (!FRAMEP (kb->Vdefault_minibuffer_frame)
+          || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
+    kb->Vdefault_minibuffer_frame = frame;
+
+  /* All remaining specified parameters, which have not been "used"
+     by x_get_arg and friends, now go in the misc. alist of the frame.  */
+  for (tem = parms; CONSP (tem); tem = XCDR (tem))
+    if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
+      f->param_alist = Fcons (XCAR (tem), f->param_alist);
+
+  UNGCPRO;
+  Vwindow_list = Qnil;
+
+  return unbind_to (count, frame);
+}
+
+
+/* ==========================================================================
+
+    Lisp definitions
+
+   ========================================================================== 
*/
+
+DEFUN ("ns-focus-frame", Fns_focus_frame, Sns_focus_frame, 1, 1, 0,
+       doc: /* Set the input focus to FRAME.
+FRAME nil means use the selected frame.  */)
+     (frame)
+     Lisp_Object frame;
+{
+  struct frame *f = check_ns_frame (frame);
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
+
+  if (dpyinfo->ns_focus_frame != f)
+    {
+      EmacsView *view = FRAME_NS_VIEW (f);
+      BLOCK_INPUT;
+      [[view window] makeKeyAndOrderFront: view];
+      UNBLOCK_INPUT;
+    }
+
+  return Qnil;
+}
+
+
+DEFUN ("ns-popup-prefs-panel", Fns_popup_prefs_panel, Sns_popup_prefs_panel,
+       0, 0, "", "Pop up the preferences panel.")
+     ()
+{
+  check_ns ();
+  [(EmacsApp *)NSApp showPreferencesWindow: NSApp];
+  return Qnil;
+}
+
+
+DEFUN ("ns-popup-font-panel", Fns_popup_font_panel, Sns_popup_font_panel,
+       0, 1, "", "Pop up the font panel.")
+     (frame)
+     Lisp_Object frame;
+{
+  id fm;
+  struct frame *f;
+
+  check_ns ();
+  fm = [NSFontManager new];
+  if (NILP (frame))
+    f = SELECTED_FRAME ();
+  else
+    {
+      CHECK_FRAME (frame);
+      f = XFRAME (frame);
+    }
+
+  [fm setSelectedFont: ((struct nsfont_info *)f->output_data.ns->font)->nsfont
+           isMultiple: NO];
+  [fm orderFrontFontPanel: NSApp];
+  return Qnil;
+}
+
+
+DEFUN ("ns-popup-color-panel", Fns_popup_color_panel, Sns_popup_color_panel, 
+       0, 1, "", "Pop up the color panel.")
+     (frame)
+     Lisp_Object frame;
+{
+  struct frame *f;
+
+  check_ns ();
+  if (NILP (frame))
+    f = SELECTED_FRAME ();
+  else
+    {
+      CHECK_FRAME (frame);
+      f = XFRAME (frame);
+    }
+
+  [NSApp orderFrontColorPanel: NSApp];
+  return Qnil;
+}
+
+
+DEFUN ("ns-read-file-name", Fns_read_file_name, Sns_read_file_name, 1, 4, 0,
+       "As read-file-name except that NS panels are used for querying, and\n\
+args are slightly different.  Nil returned if no selection made.\n\
+Set ISLOAD non-nil if file being read for a save.")
+     (prompt, dir, isLoad, init)
+     Lisp_Object prompt, dir, isLoad, init;
+{
+  static id fileDelegate = nil;
+  int ret;
+  id panel;
+  NSString *fname;
+
+  NSString *promptS = NILP (prompt) || !STRINGP (prompt) ? nil :
+    [NSString stringWithUTF8String: XSTRING (prompt)->data];
+  NSString *dirS = NILP (dir) || !STRINGP (dir) ?
+    [NSString stringWithUTF8String: XSTRING (current_buffer->directory)->data] 
:
+    [NSString stringWithUTF8String: XSTRING (dir)->data];
+  NSString *initS = NILP (init) || !STRINGP (init) ? nil :
+    [NSString stringWithUTF8String: XSTRING (init)->data];
+
+  check_ns ();
+
+  if (fileDelegate == nil)
+    fileDelegate = [EmacsFileDelegate new];
+
+  [NSCursor setHiddenUntilMouseMoves: NO];
+
+  if ([dirS characterAtIndex: 0] == '~')
+    dirS = [dirS stringByExpandingTildeInPath];
+
+  panel = NILP (isLoad) ?
+    [EmacsSavePanel savePanel] : [EmacsOpenPanel openPanel];
+
+  [panel setTitle: promptS];
+
+  /* Puma (10.1) does not have */
+  if ([panel respondsToSelector: @selector (setAllowsOtherFileTypes:)])
+    [panel setAllowsOtherFileTypes: YES];
+
+  [panel setTreatsFilePackagesAsDirectories: YES];
+  [panel setDelegate: fileDelegate];
+
+  panelOK = 0;
+  if (NILP (isLoad))
+    {
+      ret = [panel runModalForDirectory: dirS file: initS];
+    }
+  else
+    {
+      [panel setCanChooseDirectories: YES];
+      ret = [panel runModalForDirectory: dirS file: initS types: nil];
+    }
+
+  ret = (ret = NSOKButton) || panelOK;
+
+  fname = [panel filename];
+
+  [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
+
+  return ret ? build_string ([fname UTF8String]) : Qnil;
+}
+
+
+DEFUN ("ns-get-resource", Fns_get_resource, Sns_get_resource, 2, 2, 0,
+       "Return the value of the property NAME of OWNER from the defaults 
database.\n\
+If OWNER is nil, Emacs is assumed.")
+     (owner, name)
+     Lisp_Object owner, name;
+{
+  const char *value;
+
+  check_ns ();
+  if (NILP (owner))
+    owner = build_string
+        ([[[NSProcessInfo processInfo] processName] UTF8String]);
+  /* CHECK_STRING (owner);  this should be just "Emacs" */
+  CHECK_STRING (name);
+/*fprintf (stderr, "ns-get-resource checking resource '%s'\n", SDATA (name)); 
*/
+
+  value =[[[NSUserDefaults standardUserDefaults]
+            objectForKey: [NSString stringWithUTF8String: XSTRING 
(name)->data]]
+           UTF8String];
+
+  if (value)
+    return build_string (value);
+/*fprintf (stderr, "Nothing found for NS resource '%s'.\n", XSTRING 
(name)->data); */
+  return Qnil;
+}
+
+
+DEFUN ("ns-set-resource", Fns_set_resource, Sns_set_resource, 3, 3, 0,
+       "Set property NAME of OWNER to VALUE, from the defaults database.\n\
+If OWNER is nil, Emacs is assumed.\n\
+If VALUE is nil, the default is removed.")
+     (owner, name, value)
+     Lisp_Object owner, name, value;
+{
+  check_ns ();
+  if (NILP (owner))
+    owner =
+        build_string ([[[NSProcessInfo processInfo] processName] UTF8String]);
+  CHECK_STRING (owner);
+  CHECK_STRING (name);
+  if (NILP (value))
+    {
+      [[NSUserDefaults standardUserDefaults] removeObjectForKey:
+                         [NSString stringWithUTF8String: XSTRING 
(name)->data]];
+    }
+  else
+    {
+      CHECK_STRING (value);
+      [[NSUserDefaults standardUserDefaults] setObject:
+                [NSString stringWithUTF8String: XSTRING (value)->data]
+                                        forKey: [NSString stringWithUTF8String:
+                                                         XSTRING 
(name)->data]];
+    }
+
+  return Qnil;
+}
+
+
+DEFUN ("ns-set-alpha", Fns_set_alpha, Sns_set_alpha, 2, 2, 0,
+       "Return a color same as given with alpha set to given value\n\
+from 0 to 1, where 1 is fully opaque.")
+     (color, alpha)
+     Lisp_Object color;
+     Lisp_Object alpha;
+{
+  NSColor *col;
+  float a;
+
+  CHECK_STRING (color);
+  CHECK_NUMBER_OR_FLOAT (alpha);
+
+  if (ns_lisp_to_color (color, &col))
+    error ("Unknown color.");
+
+  a = XFLOATINT (alpha);
+  if (a < 0.0 || a > 1.0)
+    error ("Alpha value should be between 0 and 1 inclusive.");
+
+  col = [col colorWithAlphaComponent: a];
+  return ns_color_to_lisp (col);
+}
+
+
+DEFUN ("ns-server-max-request-size", Fns_server_max_request_size,
+       Sns_server_max_request_size,
+       0, 1, 0,
+       "This function is only present for completeness.  It does not return\n\
+a usable result for NS windows.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+  /* This function has no real equivalent under NeXTstep.  Return nil to
+     indicate this. */
+  return Qnil;
+}
+
+
+DEFUN ("ns-server-vendor", Fns_server_vendor, Sns_server_vendor, 0, 1, 0,
+       "Returns the vendor ID string of the NS server of display DISPLAY.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame or a display name (a string).\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+#ifdef NS_IMPL_GNUSTEP
+  return build_string ("GNU");
+#else
+  return build_string ("Apple");
+#endif
+}
+
+
+DEFUN ("ns-server-version", Fns_server_version, Sns_server_version, 0, 1, 0,
+       "Returns the version number of the NS release of display DISPLAY.\n\
+See also the function `ns-server-vendor'.\n\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame or a display name (a string).\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  /*PENDING: return GUI version on GNUSTEP, ?? on OS X */
+  return build_string ("1.0");
+}
+
+
+DEFUN ("ns-display-screens", Fns_display_screens, Sns_display_screens, 0, 1, 0,
+       "Returns the number of screens on the NS server of display DISPLAY.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  int num;
+
+  check_ns ();
+  num = [[NSScreen screens] count];
+
+  return (num != 0) ? make_number (num) : Qnil;
+}
+
+
+DEFUN ("ns-display-mm-height", Fns_display_mm_height, Sns_display_mm_height,
+       0, 1, 0,
+       "Returns the height in millimeters of the NS display DISPLAY.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+  return make_number ((int)
+                     ([ns_get_screen (display) 
frame].size.height/(92.0/25.4)));
+}
+
+
+DEFUN ("ns-display-mm-width", Fns_display_mm_width, Sns_display_mm_width,
+       0, 1, 0,
+       "Returns the width in millimeters of the NS display DISPLAY.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+  return make_number ((int)
+                     ([ns_get_screen (display) frame].size.width/(92.0/25.4)));
+}
+
+
+DEFUN ("ns-display-backing-store", Fns_display_backing_store,
+       Sns_display_backing_store, 0, 1, 0,
+       "Returns an indication of whether NS display DISPLAY does backing 
store.\n\
+The value may be `buffered', `retained', or `non-retained'.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.\n\
+Under NS, this may differ for each frame.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+  switch ([ns_get_window (display) backingType])
+    {
+    case NSBackingStoreBuffered:
+      return intern ("buffered");
+    case NSBackingStoreRetained:
+      return intern ("retained");
+    case NSBackingStoreNonretained:
+      return intern ("non-retained");
+    default:
+      error ("Strange value for backingType parameter of frame");
+    }
+  return Qnil;  /* not reached, shut compiler up */
+}
+
+
+DEFUN ("ns-display-visual-class", Fns_display_visual_class,
+       Sns_display_visual_class, 0, 1, 0,
+       "Returns the visual class of the NS display DISPLAY.\n\
+The value is one of the symbols `static-gray', `gray-scale',\n\
+`static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  NSWindowDepth depth;
+  check_ns ();
+  depth = [ns_get_screen (display) depth];
+
+  if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
+    return intern ("static-gray");
+  else if (depth == NSBestDepth (NSCalibratedWhiteColorSpace, 8, 8, YES, NULL))
+    return intern ("gray-scale");
+  else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 8, 8, YES, NULL))
+    return intern ("pseudo-color");
+  else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 4, 12, NO, NULL))
+    return intern ("true-color");
+  else if ( depth == NSBestDepth (NSCalibratedRGBColorSpace, 8, 24, NO, NULL))
+    return intern ("direct-color");
+  else
+    /* color mgmt as far as we do it is really handled by NS itself anyway */
+    return intern ("direct-color");
+}
+
+
+DEFUN ("ns-display-save-under", Fns_display_save_under,
+       Sns_display_save_under, 0, 1, 0,
+       "Returns t if the NS display DISPLAY supports the save-under feature.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.\n\
+Under NS, this may differ for each frame.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+  switch ([ns_get_window (display) backingType])
+    {
+    case NSBackingStoreBuffered:
+      return Qt;
+
+    case NSBackingStoreRetained:
+    case NSBackingStoreNonretained:
+      return Qnil;
+
+    default:
+      error ("Strange value for backingType parameter of frame");
+    }
+  return Qnil;  /* not reached, shut compiler up */
+}
+
+
+DEFUN ("ns-open-connection", Fns_open_connection, Sns_open_connection,
+       1, 3, 0, "Open a connection to a NS server.\n\
+DISPLAY is the name of the display to connect to.\n\
+Optional arguments XRM-STRING and MUST-SUCCEED are currently ignored.")
+     (display, resource_string, must_succeed)
+     Lisp_Object display, resource_string, must_succeed;
+{
+  struct ns_display_info *dpyinfo;
+
+  CHECK_STRING (display);
+
+  nxatoms_of_nsselect ();
+  dpyinfo = ns_term_init (display);
+  if (dpyinfo == 0)
+    {
+      if (!NILP (must_succeed))
+        fatal ("OpenStep on %s not responding.\n",
+               XSTRING (display)->data);
+      else
+        error ("OpenStep on %s not responding.\n",
+               XSTRING (display)->data);
+    }
+
+  /* Register our external input/output types, used for determining
+     applicable services and also drag/drop eligibility. */
+  ns_send_types = [[NSArray arrayWithObject: NSStringPboardType] retain];
+  ns_return_types = [[NSArray arrayWithObject: NSStringPboardType] retain];
+  ns_drag_types = [[NSArray arrayWithObjects:
+                            NSStringPboardType,
+                            NSTabularTextPboardType,
+                            NSFilenamesPboardType,
+                            NSURLPboardType,
+                            NSColorPboardType,
+                            NSFontPboardType, nil] retain];
+
+  return Qnil;
+}
+
+
+DEFUN ("ns-close-connection", Fns_close_connection, Sns_close_connection,
+       1, 1, 0, "Close the connection to the current NS server.\n\
+The second argument DISPLAY is currently ignored, but nil would stand for\n\
+the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+#ifdef NS_IMPL_COCOA
+  PSFlush ();
+#endif
+  /*ns_delete_terminal (dpyinfo->terminal); */
+  [NSApp terminate: NSApp];
+  return Qnil;
+}
+
+
+DEFUN ("ns-display-list", Fns_display_list, Sns_display_list, 0, 0, 0,
+       "Return the list of display names that Emacs has connections to.")
+     ()
+{
+  Lisp_Object tail, result;
+
+  result = Qnil;
+  for (tail = ns_display_name_list; CONSP (tail); tail = XCDR (tail))
+    result = Fcons (XCAR (XCAR (tail)), result);
+
+  return result;
+}
+
+
+DEFUN ("ns-hide-others", Fns_hide_others, Sns_hide_others,
+       0, 0, 0, "Hides all applications other than emacs.")
+     ()
+{
+  check_ns ();
+  [NSApp hideOtherApplications: NSApp];
+  return Qnil;
+}
+
+DEFUN ("ns-hide-emacs", Fns_hide_emacs, Sns_hide_emacs,
+       1, 1, 0, "If ON is non-nil, the entire emacs application is hidden.\n\
+Otherwise if emacs is hidden, it is unhidden.\n\
+If ON is equal to 'activate, emacs is unhidden and becomes\n\
+the active application.")
+     (on)
+     Lisp_Object on;
+{
+  check_ns ();
+  if (EQ (on, intern ("activate")))
+    {
+      [NSApp unhide: NSApp];
+      [NSApp activateIgnoringOtherApps: YES];
+    }
+  else if (NILP (on))
+    [NSApp unhide: NSApp];
+  else
+    [NSApp hide: NSApp];
+  return Qnil;
+}
+
+
+DEFUN ("ns-emacs-info-panel", Fns_emacs_info_panel, Sns_emacs_info_panel,
+       0, 0, 0, "Shows the 'Info' or 'About' panel for Emacs.")
+     ()
+{
+  check_ns ();
+  [NSApp orderFrontStandardAboutPanel: nil];
+  return Qnil;
+}
+
+
+DEFUN ("x-list-fonts", Fns_list_fonts, Sns_list_fonts, 1, 4, 0,
+       "Return a list of the names of available fonts matching PATTERN.\n\
+If optional arguments FACE and FRAME are specified, return only fonts\n\
+the same size as FACE on FRAME.\n\
+If optional argument MAX is specified, return at most MAX matches.\n\
+\n\
+PATTERN is a regular expression; FACE is a face name - a symbol.\n\
+\n\
+The return value is a list of strings, suitable as arguments to\n\
+set-face-font.\n\
+\n\
+The font names are _NOT_ X names.")
+     (pattern, face, frame, max)
+     Lisp_Object pattern, face, frame, max;
+{
+  Lisp_Object flist, olist = Qnil, tem;
+  struct frame *f;
+  int maxnames;
+
+  /* We can't simply call check_x_frame because this function may be
+     called before any frame is created.  */
+  if (NILP (frame))
+    f = SELECTED_FRAME ();
+  else
+    {
+      CHECK_LIVE_FRAME (frame);
+      f = XFRAME (frame);
+    }
+  if (! FRAME_WINDOW_P (f))
+    {
+      /* Perhaps we have not yet created any frame.  */
+      f = NULL;
+    }
+
+  if (NILP (max))
+    maxnames = 4;
+  else
+    {
+      CHECK_NATNUM (max);
+      maxnames = XFASTINT (max);
+    }
+
+  /* get XLFD names */
+  flist = ns_list_fonts (f, pattern, 0, maxnames);
+
+  /* convert list into regular names */
+  for (tem = flist; CONSP (tem); tem = XCDR (tem))
+    {
+      Lisp_Object fname = XCAR (tem);
+      olist = Fcons (build_string (ns_xlfd_to_fontname (XSTRING 
(fname)->data)),
+                    olist);
+    }
+
+  return olist;
+}
+
+
+DEFUN ("ns-font-name", Fns_font_name, Sns_font_name, 1, 1, 0,
+       "Determine font postscript or family name from a font name string or\n\
+XLFD string.  If string contains fontset' and not 'fontset-startup' it is\n\
+left alone.")
+     (name)
+     Lisp_Object name;
+{
+  char *nm;
+  CHECK_STRING (name);
+  nm = SDATA (name);
+
+  if (nm[0] != '-')
+    return name;
+  if (strstr (nm, "fontset") && !strstr (nm, "fontset-startup"))
+    return name;
+
+  return build_string (ns_xlfd_to_fontname (SDATA (name)));
+}
+
+
+DEFUN ("ns-list-colors", Fns_list_colors, Sns_list_colors, 0, 1, 0,
+       "Return a list of all available colors.\n\
+The optional argument FRAME is currently ignored.")
+     (frame)
+     Lisp_Object frame;
+{
+  Lisp_Object list = Qnil;
+  NSEnumerator *colorlists;
+  NSColorList *clist;
+
+  if (!NILP (frame))
+    {
+      CHECK_FRAME (frame);
+      if (! FRAME_NS_P (XFRAME (frame)))
+        error ("non-NS frame used in `ns-list-colors'");
+    }
+
+  BLOCK_INPUT;
+
+  colorlists = [[NSColorList availableColorLists] objectEnumerator];
+  while (clist = [colorlists nextObject])
+    {
+      if ([[clist name] length] < 7 ||
+          [[clist name] rangeOfString: @"PANTONE"].location == 0)
+        {
+          NSEnumerator *cnames = [[clist allKeys] reverseObjectEnumerator];
+          NSString *cname;
+          while (cname = [cnames nextObject])
+            list = Fcons (build_string ([cname UTF8String]), list);
+/*           for (i = [[clist allKeys] count] - 1; i >= 0; i--)
+               list = Fcons (build_string ([[[clist allKeys] objectAtIndex: i]
+                                             UTF8String]), list); */
+        }
+    }
+
+  UNBLOCK_INPUT;
+
+  return list;
+}
+
+
+DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0,
+       "List NS services by querying NSApp.")
+     ()
+{
+  Lisp_Object ret = Qnil;
+  NSMenu *svcs;
+  id delegate;
+
+  check_ns ();
+  svcs = [[NSMenu alloc] initWithTitle: @"Services"];
+  [NSApp setServicesMenu: svcs];  /* this and next rebuild on <10.4 */
+  [NSApp registerServicesMenuSendTypes: ns_send_types
+                           returnTypes: ns_return_types];
+
+/* On Tiger, services menu updating was made lazier (waits for user to
+   actually click on the menu), so we have to force things along: */
+#ifdef NS_IMPL_COCOA
+  if (NSAppKitVersionNumber >= 744.0)
+    {
+      delegate = [svcs delegate];
+      if (delegate != nil)
+        {
+          if ([delegate respondsToSelector: @selector (menuNeedsUpdate:)])
+              [delegate menuNeedsUpdate: svcs];
+          if ([delegate respondsToSelector:
+                            @selector (menu:updateItem:atIndex:shouldCancel:)])
+            {
+              int i, len = [delegate numberOfItemsInMenu: svcs];
+              for (i =0; i<len; i++)
+                  [svcs addItemWithTitle: @"" action: NULL keyEquivalent: @""];
+              for (i =0; i<len; i++)
+                  if (![delegate menu: svcs
+                           updateItem: (NSMenuItem *)[svcs itemAtIndex: i]
+                              atIndex: i shouldCancel: NO])
+                    break;
+            }
+        }
+    }
+#endif
+
+  [svcs setAutoenablesItems: NO];
+#ifdef NS_IMPL_COCOA
+  [svcs update]; /* on OS X, converts from '/' structure */
+#endif
+
+  ret = interpret_services_menu (svcs, Qnil, ret);
+  return ret;
+}
+
+
+DEFUN ("ns-perform-service", Fns_perform_service, Sns_perform_service,
+       2, 2, 0, "Perform NS SERVICE on SEND which is either a string or nil.\n\
+Returns result of service as string or nil if no result.")
+     (service, send)
+     Lisp_Object service, send;
+{
+  id pb;
+  NSString *svcName;
+  char *utfStr;
+  int len;
+
+  CHECK_STRING (service);
+  check_ns ();
+
+  utfStr = XSTRING (service)->data;
+  svcName = [NSString stringWithUTF8String: utfStr];
+
+  pb =[NSPasteboard pasteboardWithUniqueName];
+  ns_string_to_pasteboard (pb, send);
+
+  if (NSPerformService (svcName, pb) == NO)
+    Fsignal (Qquit, Fcons (build_string ("service not available"), Qnil));
+
+  if ([[pb types] count] == 0)
+    return build_string ("");
+  return ns_string_from_pasteboard (pb);
+}
+
+
+DEFUN ("ns-convert-utf8-nfd-to-nfc", Fns_convert_utf8_nfd_to_nfc,
+       Sns_convert_utf8_nfd_to_nfc, 1, 1, 0,
+       "Composes character sequences in UTF-8 normal form NFD string STR to 
produce a normal (composed normal form NFC) string.")
+    (str)
+    Lisp_Object str;
+{
+  NSString *utfStr;
+
+  CHECK_STRING (str);
+  utfStr = [[NSString stringWithUTF8String: XSTRING (str)->data]
+             precomposedStringWithCanonicalMapping];
+  return build_string ([utfStr UTF8String]);
+}
+
+
+/* ==========================================================================
+
+    Miscellaneous functions not called through hooks
+
+   ========================================================================== 
*/
+
+
+/* 23: call in image.c */
+FRAME_PTR
+check_x_frame (Lisp_Object frame)
+{
+  return check_ns_frame (frame);
+}
+
+/* 23: added, due to call in frame.c */
+struct ns_display_info *
+check_x_display_info (Lisp_Object frame)
+{
+  return check_ns_display_info (frame);
+}
+
+
+/* 23: new function; we don't have much in the way of flexibility though */
+void
+x_set_scroll_bar_default_width (f)
+     struct frame *f;
+{
+  int wid = FRAME_COLUMN_WIDTH (f);
+  FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = NS_SCROLL_BAR_WIDTH_DEFAULT;
+  FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
+                                      wid - 1) / wid;
+}
+
+
+/* 23: terms now impl this instead of x-get-resource directly */
+const char *
+x_get_string_resource (XrmDatabase rdb, char *name, char *class)
+{
+  /* remove appname prefix; PENDING: allow for !="Emacs" */
+  char *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
+  const char *res;
+  check_ns ();
+
+  /* Support emacs-20-style face resources for backwards compatibility */
+  if (!strncmp (toCheck, "Face", 4))
+    toCheck = name + (!strncmp (name, "emacs.", 6) ? 6 : 0);
+
+/*fprintf (stderr, "Checking '%s'\n", toCheck); */
+  
+  res = [[[NSUserDefaults standardUserDefaults] objectForKey:
+                   [NSString stringWithUTF8String: toCheck]] UTF8String];
+  return !res ? NULL :
+      (!strncasecmp (res, "YES", 3) ? "true" :
+          (!strncasecmp (res, "NO", 2) ? "false" : res));
+}
+
+
+Lisp_Object
+x_get_focus_frame (struct frame *frame)
+{
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame);
+  Lisp_Object nsfocus;
+
+  if (!dpyinfo->ns_focus_frame)
+    return Qnil;
+
+  XSETFRAME (nsfocus, dpyinfo->ns_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_char_width (struct frame *f)
+{
+  return FRAME_COLUMN_WIDTH (f);
+}
+
+
+int
+x_char_height (struct frame *f)
+{
+  return FRAME_LINE_HEIGHT (f);
+}
+
+
+int
+x_screen_planes (struct frame *f)
+{
+  return FRAME_NS_DISPLAY_INFO (f)->n_planes;
+}
+
+
+void
+x_sync (Lisp_Object frame)
+{
+  /* XXX Not implemented XXX */
+  return;
+}
+
+
+
+/* ==========================================================================
+
+    Lisp definitions that, for whatever reason, we can't alias as 'ns-XXX'.
+
+   ========================================================================== 
*/
+
+
+DEFUN ("xw-color-defined-p", Fns_color_defined_p, Sns_color_defined_p, 1, 2, 0,
+       "Return t if the current NS display supports the color named COLOR.\n\
+The optional argument FRAME is currently ignored.")
+     (color, frame)
+     Lisp_Object color, frame;
+{
+  NSColor * col;
+  check_ns ();
+  return ns_lisp_to_color (color, &col) ? Qnil : Qt;
+}
+
+
+DEFUN ("xw-color-values", Fns_color_values, Sns_color_values, 1, 2, 0,
+       "Return a description of the color named COLOR.\n\
+The value is a list of integer RGBA values--(RED GREEN BLUE ALPHA).\n\
+These values appear to range from 0 to 65280; white is (65280 65280 65280 
0).\n\
+The optional argument FRAME is currently ignored.")
+     (color, frame)
+     Lisp_Object color, frame;
+{
+  NSColor * col;
+  float red, green, blue, alpha;
+  Lisp_Object rgba[4];
+
+  check_ns ();
+  CHECK_STRING (color);
+
+  if (ns_lisp_to_color (color, &col))
+    return Qnil;
+
+  [[col colorUsingColorSpaceName: NSCalibratedRGBColorSpace]
+        getRed: &red green: &green blue: &blue alpha: &alpha];
+  rgba[0] = make_number (lrint (red*65280));
+  rgba[1] = make_number (lrint (green*65280));
+  rgba[2] = make_number (lrint (blue*65280));
+  rgba[3] = make_number (lrint (alpha*65280));
+
+  return Flist (4, rgba);
+}
+
+
+DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
+       "Return t if the NS display supports color.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  NSWindowDepth depth;
+  NSString *colorSpace;
+  check_ns ();
+  depth = [ns_get_screen (display) depth];
+  colorSpace = NSColorSpaceFromDepth (depth);
+
+  return    [colorSpace isEqualToString: NSDeviceWhiteColorSpace]
+         || [colorSpace isEqualToString: NSCalibratedWhiteColorSpace]
+      ? Qnil : Qt;
+}
+
+
+DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p,
+       Sx_display_grayscale_p, 0, 1, 0,
+       "Return t if the NS display supports shades of gray.\n\
+Note that color displays do support shades of gray.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  NSWindowDepth depth;
+  check_ns ();
+  depth = [ns_get_screen (display) depth];
+
+  return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil;
+}
+
+
+DEFUN ("x-display-pixel-width", Fns_display_pixel_width, 
Sns_display_pixel_width,
+       0, 1, 0,
+       "Returns the width in pixels of the NS display DISPLAY.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+  return make_number ((int) [ns_get_screen (display) frame].size.width);
+}
+
+
+DEFUN ("x-display-pixel-height", Fns_display_pixel_height,
+       Sns_display_pixel_height, 0, 1, 0,
+       "Returns the height in pixels of the NS display DISPLAY.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+  return make_number ((int) [ns_get_screen (display) frame].size.height);
+}
+
+DEFUN ("display-usable-bounds", Fns_display_usable_bounds,
+       Sns_display_usable_bounds, 0, 1, 0,
+       "Returns a list of integers in form (left top width height) describing 
the \
+usable screen area excluding reserved areas such as the Mac menu and doc, or \
+the Windows task bar.\n                        \
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  int top;
+  NSRect vScreen;
+
+  check_ns ();
+  vScreen = [ns_get_screen (display) visibleFrame];
+  top = vScreen.origin.y == 0.0 ?
+    (int) [ns_get_screen (display) frame].size.height - vScreen.size.height : 
0;
+
+  return list4 (make_number ((int) vScreen.origin.x),
+                make_number (top),
+                make_number ((int) vScreen.size.width),
+                make_number ((int) vScreen.size.height));
+}
+
+
+DEFUN ("x-display-planes", Fx_display_planes, Sns_display_planes,
+       0, 1, 0,
+       "Returns the number of bitplanes of the NS display DISPLAY.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+  return make_number
+    (NSBitsPerSampleFromDepth ([ns_get_screen (display) depth]));
+}
+
+
+DEFUN ("x-display-color-cells", Fns_display_color_cells,
+       Sns_display_color_cells, 0, 1, 0,
+       "Returns the number of color cells of the NS display DISPLAY.\n\
+The optional argument DISPLAY specifies which display to ask about.\n\
+DISPLAY should be either a frame, a display name (a string), or terminal ID.\n\
+If omitted or nil, that stands for the selected frame's display.")
+     (display)
+     Lisp_Object display;
+{
+  check_ns ();
+  struct ns_display_info *dpyinfo = check_ns_display_info (display);
+
+  /* We force 24+ bit depths to 24-bit to prevent an overflow.  */
+  return make_number (1 << min (dpyinfo->n_planes, 24));
+}
+
+
+/* Unused dummy def needed for compatibility. */
+Lisp_Object tip_frame;
+
+/*PENDING: move to xdisp or similar */
+static void
+compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
+     struct frame *f;
+     Lisp_Object parms, dx, dy;
+     int width, height;
+     int *root_x, *root_y;
+{
+  Lisp_Object left, top;
+  EmacsView *view = FRAME_NS_VIEW (f);
+  NSPoint pt;
+  
+  /* Start with user-specified or mouse position.  */
+  left = Fcdr (Fassq (Qleft, parms));
+  if (INTEGERP (left))
+    pt.x = XINT (left);
+  else
+    pt.x = last_mouse_motion_position.x;
+  top = Fcdr (Fassq (Qtop, parms));
+  if (INTEGERP (top))
+    pt.y = XINT (top);
+  else
+    pt.y = last_mouse_motion_position.y;
+
+  /* Convert to screen coordinates */
+  pt = [view convertPoint: pt toView: nil];
+  pt = [[view window] convertBaseToScreen: pt];
+
+  /* Ensure in bounds.  (Note, screen origin = lower left.) */
+  if (pt.x + XINT (dx) <= 0)
+    *root_x = 0; /* Can happen for negative dx */
+  else if (pt.x + XINT (dx) + width <= FRAME_NS_DISPLAY_INFO (f)->width)
+    /* It fits to the right of the pointer.  */
+    *root_x = pt.x + XINT (dx);
+  else if (width + XINT (dx) <= pt.x)
+    /* It fits to the left of the pointer.  */
+    *root_x = pt.x - width - XINT (dx);
+  else
+    /* Put it left justified on the screen -- it ought to fit that way.  */
+    *root_x = 0;
+
+  if (pt.y - XINT (dy) - height >= 0)
+    /* It fits below the pointer.  */
+    *root_y = pt.y - height - XINT (dy);
+  else if (pt.y + XINT (dy) + height <= FRAME_NS_DISPLAY_INFO (f)->height)
+    /* It fits above the pointer */
+      *root_y = pt.y + XINT (dy);
+  else
+    /* Put it on the top.  */
+    *root_y = FRAME_NS_DISPLAY_INFO (f)->height - height;
+}
+
+
+DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
+       doc: /* Show STRING in a "tooltip" window on frame FRAME.
+A tooltip window is a small window displaying a string.
+
+FRAME nil or omitted means use the selected frame.
+
+PARMS is an optional list of frame parameters which can be used to
+change the tooltip's appearance.
+
+Automatically hide the tooltip after TIMEOUT seconds.  TIMEOUT nil
+means use the default timeout of 5 seconds.
+
+If the list of frame parameters PARMS contains a `left' parameter,
+the tooltip is displayed at that x-position.  Otherwise it is
+displayed at the mouse position, with offset DX added (default is 5 if
+DX isn't specified).  Likewise for the y-position; if a `top' frame
+parameter is specified, it determines the y-position of the tooltip
+window, otherwise it is displayed at the mouse position, with offset
+DY added (default is -10).
+
+A tooltip's maximum size is specified by `x-max-tooltip-size'.
+Text larger than the specified size is clipped.  */)
+     (string, frame, parms, timeout, dx, dy)
+     Lisp_Object string, frame, parms, timeout, dx, dy;
+{
+  int root_x, root_y;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+  int count = SPECPDL_INDEX ();
+  struct frame *f;
+  char *str;
+  NSSize size;
+
+  specbind (Qinhibit_redisplay, Qt);
+
+  GCPRO4 (string, parms, frame, timeout);
+
+  CHECK_STRING (string);
+  str = XSTRING (string)->data;
+  f = check_x_frame (frame);
+  if (NILP (timeout))
+    timeout = make_number (5);
+  else
+    CHECK_NATNUM (timeout);
+
+  if (NILP (dx))
+    dx = make_number (5);
+  else
+    CHECK_NUMBER (dx);
+
+  if (NILP (dy))
+    dy = make_number (-10);
+  else
+    CHECK_NUMBER (dy);
+
+  BLOCK_INPUT;
+  if (ns_tooltip == nil)
+    ns_tooltip = [[EmacsTooltip alloc] init];
+  else
+    Fx_hide_tip ();
+
+  [ns_tooltip setText: str];
+  size = [ns_tooltip frame].size;
+
+  /* Move the tooltip window where the mouse pointer is.  Resize and
+     show it.  */
+  compute_tip_xy (f, parms, dx, dy, (int)size.width, (int)size.height,
+                 &root_x, &root_y);
+
+  [ns_tooltip showAtX: root_x Y: root_y for: XINT (timeout)];
+  UNBLOCK_INPUT;
+
+  UNGCPRO;
+  return unbind_to (count, Qnil);
+}
+
+
+DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
+       doc: /* Hide the current tooltip window, if there is any.
+Value is t if tooltip was open, nil otherwise.  */)
+     ()
+{
+  if (ns_tooltip == nil || ![ns_tooltip isActive])
+    return Qnil;
+  [ns_tooltip hide];
+  return Qt;
+}
+
+
+/* ==========================================================================
+
+    Lisp interface declaration
+
+   ========================================================================== 
*/
+
+
+void
+syms_of_nsfns ()
+{
+  int i;
+
+  Qns_frame_parameter = intern ("ns-frame-parameter");
+  staticpro (&Qns_frame_parameter);
+  Qnone = intern ("none");
+  staticpro (&Qnone);
+  Qbuffered = intern ("bufferd");
+  staticpro (&Qbuffered);
+  Qfontsize = intern ("fontsize");
+  staticpro (&Qfontsize);
+
+  DEFVAR_LISP ("ns-icon-type-alist", &Vns_icon_type_alist,
+               "Alist of elements (REGEXP . IMAGE) for images of icons 
associated to\n\
+frames.  If the title of a frame matches REGEXP, then IMAGE.tiff is\n\
+selected as the image of the icon representing the frame when it's\n\
+miniaturized.  If an element is t, then Emacs tries to select an icon\n\
+based on the filetype of the visited file.\n\
+\n\
+The images have to be installed in a folder called English.lproj in the\n\
+Emacs.app folder.  You have to restart Emacs after installing new icons.\n\
+\n\
+Example: Install an icon Gnus.tiff and execute the following code\n\
+\n\
+  (setq ns-icon-type-alist\n\
+        (append ns-icon-type-alist\n\
+                '((\"^\\\\*\\\\(Group\\\\*$\\\\|Summary 
\\\\|Article\\\\*$\\\\)\"\n\
+                   . \"Gnus\"))))\n\
+\n\
+When you miniaturize a Group, Summary or Article frame, Gnus.tiff will\n\
+be used as the image of the icon representing the frame.");
+  Vns_icon_type_alist = Fcons (Qt, Qnil);
+
+  defsubr (&Sns_read_file_name);
+  defsubr (&Sns_get_resource);
+  defsubr (&Sns_set_resource);
+  defsubr (&Sxw_display_color_p); /* this and next called directly by C code */
+  defsubr (&Sx_display_grayscale_p);
+  defsubr (&Sns_list_fonts);
+  defsubr (&Sns_font_name);
+  defsubr (&Sns_list_colors);
+  defsubr (&Sns_color_defined_p);
+  defsubr (&Sns_color_values);
+  defsubr (&Sns_server_max_request_size);
+  defsubr (&Sns_server_vendor);
+  defsubr (&Sns_server_version);
+  defsubr (&Sns_display_pixel_width);
+  defsubr (&Sns_display_pixel_height);
+  defsubr (&Sns_display_usable_bounds);
+  defsubr (&Sns_display_mm_width);
+  defsubr (&Sns_display_mm_height);
+  defsubr (&Sns_display_screens);
+  defsubr (&Sns_display_planes);
+  defsubr (&Sns_display_color_cells);
+  defsubr (&Sns_display_visual_class);
+  defsubr (&Sns_display_backing_store);
+  defsubr (&Sns_display_save_under);
+  defsubr (&Sns_create_frame);
+  defsubr (&Sns_set_alpha);
+  defsubr (&Sns_open_connection);
+  defsubr (&Sns_close_connection);
+  defsubr (&Sns_display_list);
+
+  defsubr (&Sns_hide_others);
+  defsubr (&Sns_hide_emacs);
+  defsubr (&Sns_emacs_info_panel);
+  defsubr (&Sns_list_services);
+  defsubr (&Sns_perform_service);
+  defsubr (&Sns_convert_utf8_nfd_to_nfc);
+  defsubr (&Sns_focus_frame);
+  defsubr (&Sns_popup_prefs_panel);
+  defsubr (&Sns_popup_font_panel);
+  defsubr (&Sns_popup_color_panel);
+
+  defsubr (&Sx_show_tip);
+  defsubr (&Sx_hide_tip);
+
+  /* used only in fontset.c */
+  check_window_system_func = check_ns;
+
+}
+
+
+
+/* ==========================================================================
+
+    Class implementations
+
+   ========================================================================== 
*/
+
+
address@hidden 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
address@hidden
+
+
address@hidden 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];
+  panelOK = 1;
+  [NSApp stop: self];
+}
+- (void) cancel: (id)sender
+{
+  [super cancel: sender];
+  [NSApp stop: self];
+}
+#endif
address@hidden
+
+
address@hidden EmacsFileDelegate
+/* --------------------------------------------------------------------------
+   Delegate methods for Open/Save panels
+   -------------------------------------------------------------------------- 
*/
+- (BOOL)panel: (id)sender isValidFilename: (NSString *)filename
+{
+  return YES;
+}
+- (BOOL)panel: (id)sender shouldShowFilename: (NSString *)filename
+{
+  return YES;
+}
+- (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
+          confirmed: (BOOL)okFlag
+{
+  return filename;
+}
address@hidden
+
+#endif




reply via email to

[Prev in Thread] Current Thread [Next in Thread]