changeset 96675:d45acf0c8d23

merging Emacs.app (NeXTstep port)
author Adrian Robert <Adrian.B.Robert@gmail.com>
date Tue, 15 Jul 2008 18:15:18 +0000
parents ff312a846b25
children 336d4f3f5eca
files ChangeLog Makefile.in admin/CPP-DEFINES admin/ChangeLog configure configure.in doc/emacs/ChangeLog doc/emacs/ns-emacs.texi etc/ChangeLog etc/Emacs.clr lib-src/.cvsignore lib-src/ChangeLog lib-src/Makefile.in lib-src/mac-fix-env.m lib-src/make-docfile.c lisp/ChangeLog lisp/Makefile.in lisp/cus-edit.el lisp/cus-face.el lisp/disp-table.el lisp/emulation/viper-util.el lisp/facemenu.el lisp/faces.el lisp/frame.el lisp/gnus/gnus-util.el lisp/info.el lisp/international/mule-cmds.el lisp/loadup.el lisp/mouse.el lisp/mwheel.el lisp/ns-carbon-compat.el lisp/ns-grabenv.el lisp/simple.el lisp/startup.el lisp/term/ns-win.el lisp/version.el lisp/woman.el nextstep/AUTHORS nextstep/ChangeLog nextstep/Cocoa/Emacs.base/Contents/Info.plist nextstep/Cocoa/Emacs.base/Contents/PkgInfo nextstep/Cocoa/Emacs.base/Contents/Resources/Credits.html nextstep/Cocoa/Emacs.base/Contents/Resources/Emacs.icns nextstep/Cocoa/Emacs.base/Contents/Resources/English.lproj/InfoPlist.strings nextstep/Cocoa/Emacs.base/Contents/Resources/preferences.nib/classes.nib nextstep/Cocoa/Emacs.base/Contents/Resources/preferences.nib/info.nib nextstep/Cocoa/Emacs.base/Contents/Resources/preferences.nib/keyedobjects.nib nextstep/Cocoa/Emacs.xcodeproj/project.pbxproj nextstep/FOR-RELEASE nextstep/GNUstep/Emacs.base/Resources/Emacs.desktop nextstep/GNUstep/Emacs.base/Resources/Info-gnustep.plist nextstep/GNUstep/Emacs.base/Resources/emacs.tiff nextstep/GNUstep/Emacs.base/Resources/preferences.gorm/data.classes nextstep/GNUstep/Emacs.base/Resources/preferences.gorm/data.info nextstep/GNUstep/Emacs.base/Resources/preferences.gorm/objects.gorm nextstep/README.txt nextstep/compile src/ChangeLog src/Makefile.in src/blockinput.h src/callproc.c src/config.in src/dispextern.h src/dispnew.c src/emacs.c src/font.c src/font.h src/fontset.c src/frame.c src/frame.h src/fringe.c src/getloadavg.c src/image.c src/keyboard.c src/keyboard.h src/keymap.c src/lisp.h src/lread.c src/menu.c src/nsfns.m src/nsgui.h src/nsimage.m src/nsmenu.m src/nsselect.m src/nsterm.h src/nsterm.m src/process.c src/s/darwin.h src/syntax.c src/sysselect.h src/termhooks.h src/terminal.c src/terminfo.c src/w32gui.h src/window.c src/xdisp.c src/xfaces.c
diffstat 97 files changed, 20898 insertions(+), 313 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Jul 15 15:45:05 2008 +0000
+++ b/ChangeLog	Tue Jul 15 18:15:18 2008 +0000
@@ -1,3 +1,15 @@
+2008-07-15  Adrian Robert <Adrian.B.Robert@gmail.com>
+
+	Changes and additions for NeXTstep windowing system (Cocoa and
+	GNUstep) support.
+
+	* configure.in: Add support for NS window system: --with-ns (default
+	off), --enable-ns-app, --enable-cocoa-experimental-ctrl-g; improve add
+	sparc detection for FreeBSD variants, checks for Cocoa and GNUstep,
+	disable font backend if window system is "none", not if !HAVE_X11.
+	* Makefile.in: Add ns-emacs to INFO_FILES, add ns_appdir variable.
+	(install-arch-dep): Add commands to assemble NS .app package.
+
 2008-07-10  Dan Nicolaescu  <dann@ics.uci.edu>
 
 	* configure.in: Use macppc for Darwin.  Remove references to
--- a/Makefile.in	Tue Jul 15 15:45:05 2008 +0000
+++ b/Makefile.in	Tue Jul 15 18:15:18 2008 +0000
@@ -137,7 +137,7 @@
 infodir=@infodir@
 INFO_FILES=ada-mode autotype calc ccmode cl dbus dired-x ebrowse ediff	\
            efaq eintr elisp emacs emacs-mime epa erc eshell eudc	\
-           flymake forms gnus idlwave info message mh-e newsticker	\
+           flymake forms gnus idlwave info message mh-e newsticker ns-emacs \
            nxml-mode org pcl-cvs pgg rcirc reftex remember sasl sc ses	\
            sieve speedbar tramp vip viper widget woman smtpmail url
 
@@ -167,6 +167,9 @@
 # Location to install Emacs.app on Mac OS X
 carbon_appdir=@carbon_appdir@
 
+# Location to install Emacs.app under NeXT/Open/GNUstep / Cocoa
+ns_appdir=@ns_appdir@
+
 # Where the etc/emacs.desktop file is to be installed.
 desktopdir=$(datarootdir)/applications
 
@@ -411,6 +414,14 @@
 		(cd $(DESTDIR)${carbon_appdir}/Emacs.app; umask 022; tar -xvf - \
 			&& cat > /dev/null))) || exit 1; \
 	fi
+	if test "${ns_appdir}" != ""; then \
+	  umask 022; mkdir -p ${ns_appdir}/Emacs.app; \
+	  (cd nextstep/build/Emacs.app; (tar -chf - . | \
+		(cd ${ns_appdir}/Emacs.app; umask 022; tar -xvf - \
+			&& cat > /dev/null))) || exit 1; \
+	  ( cd site-lisp ; tar chf - . ) | \
+	      ( cd ${datadir}/$(EMACSFULL)/site-lisp ; tar xf - ) \
+	fi
 
 ## http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg01672.html
 ## Needs to be the user running install, so configure can't set it.
--- a/admin/CPP-DEFINES	Tue Jul 15 15:45:05 2008 +0000
+++ b/admin/CPP-DEFINES	Tue Jul 15 18:15:18 2008 +0000
@@ -3,7 +3,6 @@
 
 ** Distinguishing OSes **
 
-MAC_OS		Compiling for the `mac' window-system.
 MAC_OS8		Compiling for Mac OS Classic (v8 or v9). No longer supported, all code using it can be removed.
 MAC_OSX		Compiling for Mac OS X.  Not bare Darwin.
 CYGWIN		Compiling the Cygwin port.
@@ -23,7 +22,11 @@
 ** Distinguishing GUIs **
 
 HAVE_NTGUI	Use the native W32 GUI for windows, frames, menus&scrollbars.
+MAC_OS		Compiling for the `mac' window-system.
 HAVE_CARBON	Compile support for the Carbon GUI.  Requires MAC_OS?
+HAVE_NS	Use the NeXT/OpenStep/Cocoa UI under Mac OS X or GNUstep.
+NS_IMPL_GNUSTEP	Compile support for GNUSTEP implementation of NS GUI API.
+NS_IMPL_COCOA	Compile support for Cocoa (Apple) implementation of NS GUI API.
 HAVE_X11	Compile support for the X11 GUI.
 HAVE_X_WINDOWS	Compile support for X Window system
 X11		??  Makefile.in suggests it's equivalent to HAVE_X11
--- a/admin/ChangeLog	Tue Jul 15 15:45:05 2008 +0000
+++ b/admin/ChangeLog	Tue Jul 15 18:15:18 2008 +0000
@@ -1,3 +1,7 @@
+2008-07-15  Adrian Robert <Adrian.B.Robert@gmail.com>
+
+	* CPP_DEFINES: Add NS port related defines.
+
 2008-06-16  Glenn Morris  <rgm@gnu.org>
 
 	* admin.el (set-version): Add doc/lispref/vol1.texi,vol2.texi,
--- a/configure	Tue Jul 15 15:45:05 2008 +0000
+++ b/configure	Tue Jul 15 18:15:18 2008 +0000
@@ -734,6 +734,7 @@
 machfile
 opsysfile
 carbon_appdir
+ns_appdir
 LTLIBOBJS'
 ac_subst_files=''
       ac_precious_vars='build_alias
@@ -1332,6 +1333,9 @@
   --enable-carbon-app[=DIR]
                           specify install directory for Emacs.app on Mac OS X
                           [DIR=/Application]
+  --enable-ns-app[=DIR]  [DIR=/Applications]
+                          specify install directory for Emacs.app under NS
+  --enable-cocoa-experimental-ctrl-g        enable experimental improved ctrl-g recognition
   --enable-asserts        compile code with asserts enabled
   --enable-maintainer-mode
                           enable make rules and dependencies not useful (and
@@ -1367,6 +1371,7 @@
   --without-xaw3d         don't use Xaw3d
   --without-xim           don't use X11 XIM
   --with-carbon           use Carbon GUI on Mac OS X. This is unsupported!
+  --with-ns               use nextstep (Cocoa or GNUstep) windowing system
   --without-gpm           don't use -lgpm for mouse support on a GNU/Linux
                           console
   --without-dbus          don't compile with D-Bus support
@@ -2087,6 +2092,14 @@
 fi
 
 
+# Check whether --with-ns was given.
+if test "${with_ns+set}" = set; then
+  withval=$with_ns;
+else
+      with_ns=no
+fi
+
+
 
 # Check whether --with-gpm was given.
 if test "${with_gpm+set}" = set; then
@@ -2155,6 +2168,20 @@
 fi
 
 
+# Check whether --enable-ns-app was given.
+if test "${enable_ns_app+set}" = set; then
+  enableval=$enable_ns_app;  ns_appdir_x=${enableval}
+fi
+
+
+# Check whether --enable-cocoa-experimental-ctrl-g was given.
+if test "${enable_cocoa_experimental_ctrl_g+set}" = set; then
+  enableval=$enable_cocoa_experimental_ctrl_g; EN_COCOA_EXPERIMENTAL_CTRL_G=yes
+else
+  EN_COCOA_EXPERIMENTAL_CTRL_G=no
+fi
+
+
 # Check whether --enable-asserts was given.
 if test "${enable_asserts+set}" = set; then
   enableval=$enable_asserts; USE_XASSERTS=$enableval
@@ -2378,16 +2405,17 @@
 case "${canonical}" in
 
   ## FreeBSD ports
-  *-*-freebsd* )
+  *-*-*freebsd* )
     opsys=freebsd
     case "${canonical}" in
       alpha*-*-freebsd*)	machine=alpha ;;
       arm*-*-freebsd*)          machine=arm ;;
       ia64-*-freebsd*)		machine=ia64 ;;
+      sparc-*-freebsd*)         machine=sparc ;;
       sparc64-*-freebsd*)	machine=sparc ;;
       powerpc-*-freebsd*)	machine=macppc ;;
       i[3456]86-*-freebsd*)	machine=intel386 ;;
-      amd64-*-freebsd*|x86_64-*-freebsd*) machine=amdx86-64 ;;
+      amd64-*-freebsd*|x86_64-*-*freebsd*) machine=amdx86-64 ;;
     esac
   ;;
 
@@ -2397,6 +2425,7 @@
     case "${canonical}" in
       alpha*-*-kfreebsd*)	machine=alpha ;;
       ia64-*-kfreebsd*)		machine=ia64 ;;
+      sparc-*-kfreebsd*)	machine=sparc ;;
       sparc64-*-kfreebsd*)	machine=sparc ;;
       powerpc-*-kfreebsd*)	machine=macppc ;;
       i[3456]86-*-kfreebsd*)	machine=intel386 ;;
@@ -9308,6 +9337,179 @@
   window_system=mac
 fi
 
+HAVE_NS=no
+COCOA=no
+GNUSTEP=no
+tmp_CPPFLAGS="$CPPFLAGS"
+tmp_CFLAGS="$CFLAGS"
+CPPFLAGS="$CPPFLAGS -x objective-c"
+CFLAGS="$CFLAGS -x objective-c"
+if test "${with_ns}" != no; then
+  if test "${opsys}" = darwin; then
+     COCOA=yes
+  elif test -f /etc/GNUstep/GNUstep.conf; then
+     GNUSTEP=yes
+     GNUSTEP_SYSTEM_HEADERS="$(source /etc/GNUstep/GNUstep.conf; echo $GNUSTEP_SYSTEM_HEADERS)"
+     GNUSTEP_SYSTEM_LIBRARIES="$(source /etc/GNUstep/GNUstep.conf; echo $GNUSTEP_SYSTEM_LIBRARIES)"
+     CPPFLAGS="$CPPFLAGS -I${GNUSTEP_SYSTEM_HEADERS}"
+     CFLAGS="$CFLAGS -I${GNUSTEP_SYSTEM_HEADERS}"
+     REAL_CFLAGS="$REAL_CFLAGS -I${GNUSTEP_SYSTEM_HEADERS}"
+     LDFLAGS="$LDFLAGS -L${GNUSTEP_SYSTEM_LIBRARIES}"
+  fi
+  if test "${ac_cv_header_AppKit_AppKit_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for AppKit/AppKit.h" >&5
+echo $ECHO_N "checking for AppKit/AppKit.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_AppKit_AppKit_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_AppKit_AppKit_h" >&5
+echo "${ECHO_T}$ac_cv_header_AppKit_AppKit_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking AppKit/AppKit.h usability" >&5
+echo $ECHO_N "checking AppKit/AppKit.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <AppKit/AppKit.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking AppKit/AppKit.h presence" >&5
+echo $ECHO_N "checking AppKit/AppKit.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <AppKit/AppKit.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: AppKit/AppKit.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: AppKit/AppKit.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: AppKit/AppKit.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: AppKit/AppKit.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: AppKit/AppKit.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: AppKit/AppKit.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: AppKit/AppKit.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: AppKit/AppKit.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: AppKit/AppKit.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: AppKit/AppKit.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: AppKit/AppKit.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: AppKit/AppKit.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: AppKit/AppKit.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: AppKit/AppKit.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: AppKit/AppKit.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: AppKit/AppKit.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for AppKit/AppKit.h" >&5
+echo $ECHO_N "checking for AppKit/AppKit.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_AppKit_AppKit_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_AppKit_AppKit_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_AppKit_AppKit_h" >&5
+echo "${ECHO_T}$ac_cv_header_AppKit_AppKit_h" >&6; }
+
+fi
+if test $ac_cv_header_AppKit_AppKit_h = yes; then
+  HAVE_NS=yes
+fi
+
+
+fi
+if test "${window_system}" = x11 && test "${HAVE_NS}" = yes; then
+  if test "${with_ns+set}" != set \
+     && test "${ns_appdir_x+set}" != set; then
+    HAVE_NS=no
+  fi
+fi
+
+if test "${window_system}" = mac && test "${HAVE_NS}" = yes; then
+  if test "${with_ns+set}" != set \
+     && test "${ns_appdir_x+set}" != set; then
+    HAVE_NS=no
+  else
+    HAVE_CARBON=no
+  fi
+fi
+if test "${HAVE_NS}" = yes; then
+  window_system=nextstep
+  with_xft=no
+  with_freetype=no
+fi
+CFLAGS="$tmp_CFLAGS"
+CPPFLAGS="$tmp_CPPFLAGS"
+
 case "${window_system}" in
   x11 )
     HAVE_X_WINDOWS=yes
@@ -9321,7 +9523,7 @@
       * ) USE_X_TOOLKIT=maybe ;;
     esac
   ;;
-  mac | none )
+  nextstep | mac | none )
     HAVE_X_WINDOWS=no
     HAVE_X11=no
     USE_X_TOOLKIT=none
@@ -9396,9 +9598,6 @@
   yes ) HAVE_MENUS=yes ;;
 esac
 
-### Compute the unexec source name from the object name.
-UNEXEC_SRC="`echo ${unexec} | sed 's/\.o/.c/'`"
-
 # Do the opsystem or machine files prohibit the use of the GNU malloc?
 # Assume not, until told otherwise.
 GNU_MALLOC=yes
@@ -12316,6 +12515,12 @@
 _ACEOF
 
     USE_TOOLKIT_SCROLL_BARS=yes
+  elif test "${HAVE_NS}" = "yes"; then
+    cat >>confdefs.h <<\_ACEOF
+#define USE_TOOLKIT_SCROLL_BARS 1
+_ACEOF
+
+    USE_TOOLKIT_SCROLL_BARS=yes
   fi
 fi
 
@@ -14943,6 +15148,46 @@
   # We also have mouse menus.
   HAVE_MENUS=yes
 fi
+### Use NeXTstep API to implement GUI.
+if test "${HAVE_NS}" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_NS 1
+_ACEOF
+
+  ## Specify the install directory
+  ns_appdir=
+  if test "${ns_appdir_x}" != ""; then
+    case ${ns_appdir_x} in
+      y | ye | yes)  ns_appdir=/Applications ;;
+      * ) ns_appdir=${ns_appdir_x} ;;
+    esac
+  fi
+  if test "${COCOA}" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NS_IMPL_COCOA 1
+_ACEOF
+
+  fi
+  if test "${EN_COCOA_EXPERIMENTAL_CTRL_G}" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define COCOA_EXPERIMENTAL_CTRL_G 1
+_ACEOF
+
+  fi
+  if test "${GNUSTEP}" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NS_IMPL_GNUSTEP 1
+_ACEOF
+
+  fi
+  # We also have mouse menus.
+  HAVE_MENUS=yes
+fi
+
 
 ### Use session management (-lSM -lICE) if available
 HAVE_X_SM=no
@@ -16688,7 +16933,6 @@
 # endif
 #endif
 
-#include <limits.h>
 #include <stdlib.h>
 
 #ifdef HAVE_UNISTD_H
@@ -16837,15 +17081,12 @@
      isn't worth using anyway.  */
   alarm (60);
 
-  for (;;)
-    {
-      t = (time_t_max << 1) + 1;
-      if (t <= time_t_max)
-	break;
-      time_t_max = t;
-    }
-  time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max;
-
+  for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2)
+    continue;
+  time_t_max--;
+  if ((time_t) -1 < 0)
+    for (time_t_min = -1; (time_t) (time_t_min * 2) < 0; time_t_min *= 2)
+      continue;
   delta = time_t_max / 997; /* a suitable prime number */
   for (i = 0; i < N_STRINGS; i++)
     {
@@ -16860,12 +17101,10 @@
 	     && mktime_test ((time_t) (60 * 60 * 24))))
 	return 1;
 
-      for (j = 1; ; j <<= 1)
+      for (j = 1; 0 < j; j *= 2)
 	if (! bigtime_test (j))
 	  return 1;
-	else if (INT_MAX / 2 < j)
-	  break;
-      if (! bigtime_test (INT_MAX))
+      if (! bigtime_test (j - 1))
 	return 1;
     }
   return ! (irix_6_4_bug () && spring_forward_gap () && year_2050_test ());
@@ -18774,13 +19013,11 @@
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <sys/types.h> /* for off_t */
-     #include <stdio.h>
-int
-main ()
-{
-int (*fp) (FILE *, off_t, int) = fseeko;
-     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+#include <stdio.h>
+int
+main ()
+{
+return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
   ;
   return 0;
 }
@@ -18820,13 +19057,11 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #define _LARGEFILE_SOURCE 1
-#include <sys/types.h> /* for off_t */
-     #include <stdio.h>
-int
-main ()
-{
-int (*fp) (FILE *, off_t, int) = fseeko;
-     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+#include <stdio.h>
+int
+main ()
+{
+return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
   ;
   return 0;
 }
@@ -23963,6 +24198,7 @@
 
 
 
+
 cat >>confdefs.h <<_ACEOF
 #define EMACS_CONFIGURATION "${canonical}"
 _ACEOF
@@ -24106,12 +24342,11 @@
 echo "  Does Emacs use -lgpm?                                   ${HAVE_GPM}"
 echo "  Does Emacs use -ldbus?                                  ${HAVE_DBUS}"
 
-if test "${USE_FONT_BACKEND}" = "yes"; then
-  echo "  Does Emacs use -lfreetype?                              ${HAVE_FREETYPE}"
-  echo "  Does Emacs use -lm17n-flt?                              ${HAVE_M17N_FLT}"
-  echo "  Does Emacs use -lotf?                                   ${HAVE_LIBOTF}"
-  echo "  Does Emacs use -lxft?                                   ${HAVE_XFT}"
-fi
+echo "  Does Emacs use -lfreetype?                              ${HAVE_FREETYPE}"
+echo "  Does Emacs use -lm17n-flt?                              ${HAVE_M17N_FLT}"
+echo "  Does Emacs use -lotf?                                   ${HAVE_LIBOTF}"
+echo "  Does Emacs use -lxft?                                   ${HAVE_XFT}"
+
 echo "  Does Emacs use X toolkit scroll bars?                   ${USE_TOOLKIT_SCROLL_BARS}"
 echo
 
@@ -24985,10 +25220,11 @@
 machfile!$machfile$ac_delim
 opsysfile!$opsysfile$ac_delim
 carbon_appdir!$carbon_appdir$ac_delim
+ns_appdir!$ns_appdir$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 22; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 23; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -25449,9 +25685,6 @@
   echo source $srcdir/src/.gdbinit > src/.gdbinit
 fi
 
-# This is how we know whether to re-run configure in certain cases.
-touch src/config.stamp
-
  ;;
 
   esac
--- a/configure.in	Tue Jul 15 15:45:05 2008 +0000
+++ b/configure.in	Tue Jul 15 18:15:18 2008 +0000
@@ -21,7 +21,7 @@
 dnl  You should have received a copy of the GNU General Public License
 dnl  along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
-AC_PREREQ(2.61)dnl
+AC_PREREQ(2.61)
 AC_INIT(emacs, 23.0.60)
 AC_CONFIG_HEADER(src/config.h:src/config.in)
 AC_CONFIG_SRCDIR(src/lisp.h)
@@ -142,6 +142,7 @@
 OPTION_DEFAULT_ON([xaw3d],[don't use Xaw3d])
 OPTION_DEFAULT_ON([xim],[don't use X11 XIM])
 OPTION_DEFAULT_OFF([carbon],[use Carbon GUI on Mac OS X.  This is unsupported!])
+OPTION_DEFAULT_OFF([ns],[use nextstep (Cocoa or GNUstep) windowing system])
 
 OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console])
 OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support])
@@ -175,6 +176,16 @@
 		 [DIR=/Application]])],
 [ carbon_appdir_x=${enableval}])
 
+AC_ARG_ENABLE(ns-app,
+[[  --enable-ns-app[=DIR]  [DIR=/Applications]
+                          specify install directory for Emacs.app under NS]],
+[ ns_appdir_x=${enableval}])
+
+AC_ARG_ENABLE(cocoa-experimental-ctrl-g,
+[  --enable-cocoa-experimental-ctrl-g        enable experimental improved ctrl-g recognition],
+   EN_COCOA_EXPERIMENTAL_CTRL_G=yes,
+   EN_COCOA_EXPERIMENTAL_CTRL_G=no)
+
 AC_ARG_ENABLE(asserts,
 [AS_HELP_STRING([--enable-asserts], [compile code with asserts enabled])],
       USE_XASSERTS=$enableval,
@@ -283,16 +294,17 @@
 case "${canonical}" in
 
   ## FreeBSD ports
-  *-*-freebsd* )
+  *-*-*freebsd* )
     opsys=freebsd
     case "${canonical}" in
       alpha*-*-freebsd*)	machine=alpha ;;
       arm*-*-freebsd*)          machine=arm ;;
       ia64-*-freebsd*)		machine=ia64 ;;
+      sparc-*-freebsd*)         machine=sparc ;;
       sparc64-*-freebsd*)	machine=sparc ;;
       powerpc-*-freebsd*)	machine=macppc ;;
       i[3456]86-*-freebsd*)	machine=intel386 ;;
-      amd64-*-freebsd*|x86_64-*-freebsd*) machine=amdx86-64 ;;
+      amd64-*-freebsd*|x86_64-*-*freebsd*) machine=amdx86-64 ;;
     esac
   ;;
 
@@ -302,6 +314,7 @@
     case "${canonical}" in
       alpha*-*-kfreebsd*)	machine=alpha ;;
       ia64-*-kfreebsd*)		machine=ia64 ;;
+      sparc-*-kfreebsd*)	machine=sparc ;;
       sparc64-*-kfreebsd*)	machine=sparc ;;
       powerpc-*-kfreebsd*)	machine=macppc ;;
       i[3456]86-*-kfreebsd*)	machine=intel386 ;;
@@ -1221,6 +1234,50 @@
   window_system=mac
 fi
 
+HAVE_NS=no
+COCOA=no
+GNUSTEP=no
+tmp_CPPFLAGS="$CPPFLAGS"
+tmp_CFLAGS="$CFLAGS"
+CPPFLAGS="$CPPFLAGS -x objective-c"
+CFLAGS="$CFLAGS -x objective-c"
+if test "${with_ns}" != no; then
+  if test "${opsys}" = darwin; then
+     COCOA=yes
+  elif test -f /etc/GNUstep/GNUstep.conf; then
+     GNUSTEP=yes
+     GNUSTEP_SYSTEM_HEADERS="$(source /etc/GNUstep/GNUstep.conf; echo $GNUSTEP_SYSTEM_HEADERS)"
+     GNUSTEP_SYSTEM_LIBRARIES="$(source /etc/GNUstep/GNUstep.conf; echo $GNUSTEP_SYSTEM_LIBRARIES)"
+     CPPFLAGS="$CPPFLAGS -I${GNUSTEP_SYSTEM_HEADERS}"
+     CFLAGS="$CFLAGS -I${GNUSTEP_SYSTEM_HEADERS}"
+     REAL_CFLAGS="$REAL_CFLAGS -I${GNUSTEP_SYSTEM_HEADERS}"
+     LDFLAGS="$LDFLAGS -L${GNUSTEP_SYSTEM_LIBRARIES}"
+  fi
+  AC_CHECK_HEADER(AppKit/AppKit.h, HAVE_NS=yes)
+fi
+if test "${window_system}" = x11 && test "${HAVE_NS}" = yes; then
+  if test "${with_ns+set}" != set \
+     && test "${ns_appdir_x+set}" != set; then
+    HAVE_NS=no
+  fi
+fi
+
+if test "${window_system}" = mac && test "${HAVE_NS}" = yes; then
+  if test "${with_ns+set}" != set \
+     && test "${ns_appdir_x+set}" != set; then
+    HAVE_NS=no
+  else
+    HAVE_CARBON=no
+  fi
+fi
+if test "${HAVE_NS}" = yes; then
+  window_system=nextstep
+  with_xft=no
+  with_freetype=no
+fi
+CFLAGS="$tmp_CFLAGS"
+CPPFLAGS="$tmp_CPPFLAGS"
+
 case "${window_system}" in
   x11 )
     HAVE_X_WINDOWS=yes
@@ -1238,7 +1295,7 @@
       * ) USE_X_TOOLKIT=maybe ;;
     esac
   ;;
-  mac | none )
+  nextstep | mac | none )
     HAVE_X_WINDOWS=no
     HAVE_X11=no
     USE_X_TOOLKIT=none
@@ -1710,6 +1767,9 @@
   elif test "${HAVE_CARBON}" = "yes"; then
     AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
     USE_TOOLKIT_SCROLL_BARS=yes
+  elif test "${HAVE_NS}" = "yes"; then
+    AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
+    USE_TOOLKIT_SCROLL_BARS=yes
   fi
 fi
 
@@ -2019,6 +2079,30 @@
   # We also have mouse menus.
   HAVE_MENUS=yes
 fi
+### Use NeXTstep API to implement GUI.
+if test "${HAVE_NS}" = "yes"; then
+  AC_DEFINE(HAVE_NS, 1, [Define to 1 if you are using the NeXTstep API, either GNUstep or Cocoa on Mac OS X.])
+  ## Specify the install directory
+  ns_appdir=
+  if test "${ns_appdir_x}" != ""; then
+    case ${ns_appdir_x} in
+      y | ye | yes)  ns_appdir=/Applications ;;
+      * ) ns_appdir=${ns_appdir_x} ;;
+    esac
+  fi
+  if test "${COCOA}" = "yes"; then
+    AC_DEFINE(NS_IMPL_COCOA, 1, [Define to 1 if you are using NS windowing under MacOS X.])
+  fi
+  if test "${EN_COCOA_EXPERIMENTAL_CTRL_G}" = "yes"; then
+    AC_DEFINE(COCOA_EXPERIMENTAL_CTRL_G, 1, [Define to 1 if you are trying experimental enhanced Ctrl-g support using NS windowing under MacOS X.])
+  fi
+  if test "${GNUSTEP}" = "yes"; then
+    AC_DEFINE(NS_IMPL_GNUSTEP, 1, [Define to 1 if you are using NS windowing under GNUstep.])
+  fi
+  # We also have mouse menus.
+  HAVE_MENUS=yes
+fi
+
 
 ### Use session management (-lSM -lICE) if available
 HAVE_X_SM=no
@@ -2414,6 +2498,7 @@
 AC_SUBST(opsysfile)
 AC_SUBST(GETLOADAVG_LIBS)
 AC_SUBST(carbon_appdir)
+AC_SUBST(ns_appdir)
 
 AC_DEFINE_UNQUOTED(EMACS_CONFIGURATION,  "${canonical}",
 		   [Define to the canonical Emacs configuration name.])
@@ -2503,8 +2588,8 @@
 ])dnl
 
 AH_BOTTOM([
-/* If we're using any sort of window system, define some consequences.  */
-#ifdef HAVE_X_WINDOWS
+/* If we're using X11/Carbon/GNUstep, define some consequences.  */
+#if defined HAVE_X_WINDOWS || defined(HAVE_CARBON) || defined(HAVE_NS)
 #define HAVE_WINDOW_SYSTEM
 #define MULTI_KBOARD
 #define HAVE_MOUSE
@@ -2516,13 +2601,15 @@
 #define MULTI_KBOARD
 #endif
 
-/* If we're using the Carbon API on Mac OS X, define a few more
-   variables as well.  */
-#ifdef HAVE_CARBON
-#define HAVE_WINDOW_SYSTEM
-#define HAVE_MOUSE
+/* Sadly for now, GNUstep dump does not work.  */
+#ifdef NS_IMPL_GNUSTEP
+#define CANNOT_DUMP
 #endif
 
+/* PENDING: These are used for the Carbon port only. */
+#undef MAC_OS
+#undef MAC_OSX
+
 /* Define USER_FULL_NAME to return a string
    that is the user's full name.
    It can assume that the variable `pw'
@@ -2575,6 +2662,28 @@
 #include config_opsysfile
 #include config_machfile
 
+/* Set up some defines, C and LD flags for NeXTstep interface on GNUstep.
+  (There is probably a better place to do this, but right now the Cocoa
+   side does this in s/darwin.h, following the Carbon port, and we cannot
+   parallel this exactly since GNUstep is multi-OS. */
+#ifdef HAVE_NS
+# ifdef C_SWITCH_SYSTEM
+# undef C_SWITCH_SYSTEM
+# endif
+# ifdef NS_IMPL_GNUSTEP
+/* See also .m.o rule in Makefile.in */
+#  define C_SWITCH_X_SYSTEM -MMD -MP -D_REENTRANT -fPIC -fno-strict-aliasing
+#  define LD_SWITCH_SITE -lgnustep-gui -lgnustep-base -lobjc $(CONFIG_SYSTEM_LIBS) -lpthread
+#  define GNU_OBJC_CFLAGS -fgnu-runtime -Wno-import -fconstant-string-class=NSConstantString -DGNUSTEP_BASE_LIBRARY=1 -DGNU_GUI_LIBRARY=1 -DGNU_RUNTIME=1 -DGSWARN -DGSDIAGNOSE
+#  define OTHER_FILES ns-app
+# else /* COCOA */
+#  define C_SWITCH_X_SYSTEM
+#  define GNU_OBJC_CFLAGS
+# endif /* COCOA */
+#endif /* HAVE_NS */
+
+
+
 /* If no remapping takes place, static variables cannot be dumped as
    pure, so don't worry about the `static' keyword. */
 #ifdef NO_REMAP
--- a/doc/emacs/ChangeLog	Tue Jul 15 15:45:05 2008 +0000
+++ b/doc/emacs/ChangeLog	Tue Jul 15 18:15:18 2008 +0000
@@ -1,3 +1,8 @@
+2008-07-15  Adrian Robert <Adrian.B.Robert@gmail.com>
+
+	* ns-emacs.texi: New file, documents features of Emacs port under
+	NeXTstep windowing.
+
 2008-07-15  Chong Yidong  <cyd@stupidchicken.com>
 
 	* entering.texi (Entering Emacs): Update prev node.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/emacs/ns-emacs.texi	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,1019 @@
+\input texinfo @c -*-texinfo-*-
+
+@setfilename ../info/ns-emacs
+@settitle Emacs.app
+
+@iftex
+@finalout
+@end iftex
+
+@titlepage
+@sp 10
+@center @titlefont{Emacs.app}
+
+@center (Version 9.0-rc1, April, 2006)
+
+@sp 2
+@center Carl Edman
+@sp 2
+@center Christian Limpach
+@sp 2
+@center Scott Bender
+@sp 2
+@center Christophe de Dinechin
+@sp 2
+@center Adrian Robert
+@sp 2
+
+@end titlepage
+
+@unnumbered Distribution
+@*
+Copyright @copyright{} 1994 Carl Edman.@*
+Copyright @copyright{} 1997 Christian Limpach.
+Copyright @copyright{} 1997 Scott Bender.
+Copyright @copyright{} 2001 Christophe de Dinechin.
+Copyright @copyright{} 2005-07 Adrian Robert.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the same conditions as for modified versions.
+
+@ignore
+@menu
+* Introduction::                
+* Events::                      
+* Preferences Panel::
+* Preferences::                    
+* Tips and Tricks::             
+* Thanks::                      
+@end menu
+@end ignore
+
+@node Top, Introduction, (dir), (dir)
+@top Emacs.app
+
+Emacs.app for GNUstep and MacOS X (http://emacs-app.sf.net) is a version of
+GNU Emacs CVS unicode-2 branch (currently planned to be released as Emacs 23)
+which adds support for the GNUstep and MacOS X systems via the OpenStep APIs
+(referred to as "Cocoa" under OS X).  Support for NeXTstep, OpenStep, and
+Rhapsody systems has been dropped.  For those systems, use "Emacs-on-Aqua",
+available at http://emacs-on-aqua.sf.net.
+
+This port leaves most of the core functions of Emacs unchanged and is
+fully-compatible with all Emacs Lisp packages, however it has a number of
+step-ish features which do not have any equivalent in Emacs's X11 interface.
+The design aim was to make it look as similar as possible to an X application
+to Emacs Lisp programs and to make it look like a normal GNUstep or MacOS X
+application to users.
+
+(From here on out we refer to this port as "Emacs.app", and the systems
+supported by this port as "NeXTstep", "NS", or "OpenStep", because saying
+GNUstep / MacOS X is too clumsy.  Both systems were derived from the NeXTstep
+libraries developed by NeXT, Inc. for its NeXT computer and operating system,
+whose APIs were later published as the OpenStep specification.  All classes
+and functions in these APIs start with the letters 'NS' for this historical
+reason.)
+
+Comments and bug reports relating to the window system interface are welcome.
+To report a bug please use the @samp{Help/Report Emacs.app bug...}  menu item.
+This sends messages to the maintainer.  (Note, please include your email
+address if you don't usually send email from this machine.)
+
+Problems and bugs which do not relate to the NS support (i.e. which can be
+reproduced even in a dumb terminal or under the Carbon port or X11) should be
+reported through the normal Emacs channels.
+
+Also, please inspect the ``Known Issues'' contained in the README file you may
+have received with this distribution or listed at the web site
+http://emacs-app.sf.net .
+
+There is also a developer mailing list for Emacs.app,
+<emacs-app-dev-@@lists.sourceforge.net>.  Sign up through the project page at
+http://emacs-app.sf.net.  A user mailing list will be added in time and if
+warranted.
+
+
+@menu
+* Introduction::	What you need to know to use and program.
+* Events::              How NS window system events are handled.
+* Preferences Panel::   Using the Preferences Panel to customize Emacs.
+* Customization::       Customization for Emacs.app.
+* Tips and Tricks::     Collected hints from Emacs users
+* Thanks::              The people who helped create Emacs.app
+@end menu
+
+@node Introduction, Events, Top, Top
+@section Introduction
+
+Despite the size and complexity of GNU Emacs, NeXTstep and the NeXTstep
+support code, this manual can be kept mercifully short by saying that
+everything written in the Emacs and the Emacs Lisp manuals about GNU Emacs
+applies equally to this Emacs except as noted here.
+
+@itemize @bullet
+@item
+The ``right-click'' button (usually the right-hand button on a two-button
+mouse) is mapped to Mouse-3, instead of Mouse-2 as earlier versions of
+Emacs.app.  This is for compatibility with X versions of emacs.  To get some
+of the old behavior back, you can put in your .emacs:
+
+@lisp
+(global-set-key [mouse-3] 'mouse-yank-at-click)
+@end lisp
+
+The other functionality of mouse-3 in a buffer of extending a selection is
+available via shift-click as in other NS applications.  To pop up a context
+menu, 
+
+@item
+The Alt or Opt key is bound to the traditional emacs "meta" by default, while
+the NS "command" key is bound to 'super', for which a set of keybindings are
+set to mimic other NeXTstep applications.  (See @ref{Events}.)  You can change
+either of these bindings using the preferences panel (see @ref{Preferences
+Panel}).
+
+@item
+The standard NeXTstep font and color panels are accessible through the Windows
+menu, or through the standard Cmd-t and Cmd-C.  These are easier to use than
+Emacs's own methods for setting these items.  To use the color panel, drag
+from it to an emacs frame.  The foreground (or background, if shift is held
+down) of the face at that point will be changed.  To finalize settings for
+either color or font, choose 'Save Preferences' from under the Help menu.  To
+discard these settings, create a new frame and close the altered one.
+
+@item
+Opening files / directories and 'Save Buffer As' operated from the menus use
+the standard NS file panels.  Likewise if you use Cmd-o or Cmd-S.  However,
+if you use the regular Emacs key combinations Ctrl-x,Ctrl-f and Ctrl-x,w for
+these functions, the normal Emacs mode of typing filenames into the minibuffer
+is used.
+
+@item
+On GNUstep, in an X-windows environment you need to use Cmd-c instead of one
+of the Ctrl-w or Meta-w commands to transfer text to the X primary selection.
+(Ordinarily the "clipboard" selection is used, for compatibility with more
+modern Gnome and KDE programs.)  Likewise, Cmd-y (instead of Ctrl-y) will
+yank/paste in the X primary selection instead of the kill-ring / clipboard.
+
+@item
+The @code{window-system} variable can now have the value @code{ns} in addition
+to, e.g., @code{x} or @code{nil}.  You can use this in your .emacs file:
+
+If you just want to distinguish between cases in which there is a
+window system and in which there isn't, this construct is useful.
+@lisp
+(if window-system
+    ...       ;;; evaluate if any window system is running
+  ...)        ;;; evaluate only when running on a dumb terminal
+@end lisp
+
+For more detailed control, use this.
+@lisp
+(cond
+ ((eq window-system 'ns)         ;;; NS specific instructions
+  ...)        
+ ((eq window-system 'x)          ;;; X specific instructions
+  ...)
+ (t      ;;; Instructions for dumb terminal or other window systems
+  ...))
+@end lisp
+
+@item
+Likewise, you can detect whether you are running in emacs-23 or an earlier
+version with:
+
+@lisp
+   (if (eq emacs-major-version '23) <emacs-23 code> <emacs-22- code>)
+@end lisp
+
+@item
+Most NS specific functions begin with 'ns-'.  Do "C-h f ns-[TAB]" to list
+these.  Many of these replace equivalent 'x-' functions, while others perform
+uniquely NS things, such as Service invocation.
+
+@item
+There are also NS variables beginning with 'ns-', however in most cases users
+need not pay attention to them since the customizability they provide is also
+available through the defaults system and preferences panel (see
+@ref{Preferences Panel} and @ref{Customization}).
+
+@item
+When Emacs is called by a name which ends in @file{-nw} it will always
+start in terminal mode.  For example, a user who needs a terminal only
+emacs would create a symbolic link from @file{emacs} to @file{emacs-nw}.
+When he launches @file{emacs-nw} from the command line, the window
+system will never be involved.  (Note, as of rc2, terminal mode is still not
+working under OS X.)
+@end itemize
+
+@node Events, Preferences Panel, Introduction, Top
+@section Events
+
+Under Emacs.app the NeXTstep command key works as the @dfn{super} modifier
+key.  In principle users can bind their command keys to whatever function they
+want, but to make the transition for NS users easier the default NS startup
+files bind the most commonly used NS command keys to work just like they do in
+most other NS applications.  Some are shown in the menus.  Choose "List
+Keybindings" from the Help menu and scroll down to the keys labeled starting
+with 's-' to see all of them.
+
+NS applications receive a number of special events which have no X equivalent.
+These are sent as specially defined ``keys'' (which don't correspond to any
+keyboard stroke combination).  Under Emacs these ``key'' events can be bound
+to functions just like ordinary keystrokes.  Here is a list of these events.
+
+@table @code
+@item ns-open-file
+This event occurs when another NeXTstep application requests that Emacs
+open a file.  A typical reason for this would be a user double-clicking
+a file in the Finder.  When this event is registered the
+name of the file to open is found in the variable @code{ns-input-file}.
+
+The behaviour of the default binding is controlled by the variable
+@code{ns-pop-up-frames}.  It's default value @code{'fresh} causes Emacs
+to open the new file in the selected frame if the selected buffer is a
+scratch buffer.  Otherwise Emacs opens a new frame and displays the file
+in that.
+
+To always get a new frame one would change @code{ns-pop-up-frames} to
+@code{t}.  To get the opposite behaviour (i.e. always putting the file into
+the selected frame), change @code{ns-pop-up-frames} to @code{nil}.
+
+@item ns-open-temp-file
+This event occurs when another application requests that Emacs open a
+temporary file.  The file name is again in @code{ns-input-file}.  By
+default this is handled by just generating a @code{ns-open-file} event
+(which then causes the @code{ns-open-file} function to be called
+whatever that may be).
+
+@lisp
+(define-key global-map [ns-open-temp-file] [ns-open-file])
+@end lisp
+
+@item ns-open-file-line
+Some applications (like e.g. ProjectBuilder or gdb) request not only a
+particular file, but also a particular line or sequence of lines in the
+file.  The file name is in @code{ns-input-file}, and
+@code{ns-input-line} is either the line or a cons cell the car of which
+contains the beginning line and the cdr of which the ending line.
+
+@lisp
+(define-key global-map [ns-open-file-line] 'ns-open-file-select-line)
+@end lisp
+
+@item ns-drag-file
+When a user drags files from another application into an Emacs frame
+this event is triggered.  Here @code{ns-input-file} is a list of all
+dragged files.  The default binding inserts all the dragged files into
+the current buffer.
+
+@lisp
+(define-key global-map [ns-drag-file] 'ns-insert-files)
+@end lisp
+
+@item ns-drag-color
+When a user drags a color from the color well (or some other source)
+Emacs sees this event and @code{ns-input-color} contains the name of the
+dragged color.  The default bindings alter the foreground color of the
+area the color was dragged onto (or background color if the color was
+shift dragged).
+
+@lisp
+(define-key global-map [ns-drag-color]  
+            'ns-set-foreground-at-mouse)
+(define-key global-map [S-ns-drag-color]
+            'ns-set-background-at-mouse)
+@end lisp
+
+@item ns-change-font
+Emacs.app allows the user to open a standard NS font panel (by default that
+function is bound to @kbd{Cmd-t}).  When the user selects a font in that
+panel this event occurs.  @code{ns-input-font} will contain the name of
+the selected font and @code{ns-input-fontsize} is its size.  The
+default binding causes Emacs to adjust the font of the selected frame.
+
+@lisp
+(define-key global-map [ns-change-font] 'ns-respond-to-changefont)
+@end lisp
+
+@item ns-power-off
+Finally when the user logs out and Emacs is still running it receives
+this event so that it has a chance to save its files before it dies.
+
+@lisp
+(define-key global-map [ns-power-off]
+  '(lambda () (interactive) (save-buffers-kill-emacs t)))
+@end lisp
+
+@end table
+
+Emacs.app also allows users to make use of NeXTstep services programatically,
+in addition to via the Services menu.  On the most basic level programmers can
+use the @code{ns-perform-service} to pass arbitrary strings to arbitrary
+services and receive the results back.  However convenience functions are
+automatically provided for all services so there should be no need to use
+this.  These function names begin with 'ns-service-', and they will either
+operate on marked text (replacing it with the result) or take a string
+argument and return the result as a string.  Type "M-x ns-service-[TAB][TAB]"
+to see those currently defined.  Note that Emacs may require a restart to
+access newly available services.
+
+
+@node Preferences Panel, Customization, Events, Top
+@section Preferences Panel
+
+The Preferences Panel can be used to set or change some of the settings for
+Emacs such as the text appearance, cursor settings, and key bindings.
+
+To save any settings changed through the Preferences Panel, hit OK;
+this has the same effect as if you had explicitly chosen Help > Save
+Preferences.
+
+To restore Emacs to use its default settings click Reset to Defaults from
+the Preferences Panel.
+
+Additional GNUstep/OS X preferences may be set from the command line using
+the @command{defaults} command. (See @ref{Customization}.)
+
+
+@section Text Rendering Preferences
+
+Font and color settings can be set using the standard NeXTstep font
+and color panels.
+
+@itemize @bullet
+@item
+To set the default font used by Emacs click the Default Font... button
+to launch the Font Panel.  Click on a frame before selecting the font
+family, typeface, and size of the default font from the Font Panel.
+
+Note that the default font will not be changed if a frame hasn't been
+selected first.
+
+@item
+To set the default foreground or background color click the
+Colors... button to launch the Color Panel.  Choose the color you want
+using any of the color models (color wheel, sliders, palette, image,
+or crayons) available from the Colors toolbar.  To apply the color
+drag a swatch from the color bar at the top of the panel to text on
+an Emacs frame.  Holding down shift will change the background color
+instead of the foreground.
+
+@item
+To use antialiased text check the Smooth Fonts option.  Lighter font
+smoothing can be achieved by checking the Use Quickdraw (lighter)
+smoothing option.
+
+@item
+To change the line height that text is displayed at drag the Expand
+Line Spacing slider.  When the slider is set to 0.0 Emacs will use the
+same line height as other Mac OS X applications.  To increase the line
+height (and decrease the number of lines that can be displayed on the
+screen) drag the slider towards 1.0.  To decrease the line height
+(increases the number of lines that can be displayed) drag the slider
+towards -1.0.
+
+After the line spacing setting has been changed Emacs must be restarted
+to take account of the change.
+
+@end itemize
+
+@section Display Preferences
+
+The Display Preferences can be used to change the appearance of the
+default cursor used by Emacs.
+
+@itemize @bullet
+@item
+The Cursor Type radio buttons can be used to select the style used for the cursor:
+
+@itemize
+@item
+Box - the cursor is displayed as a box
+@item
+Underscore - the cursor is displayed as a horizontal bar
+@item
+Bar - the cursor is displayed as a vertical bar
+@item
+Hollow - the cursor is displayed as a box with an outline but no fill
+@end itemize
+
+@item
+Use the Cursor Blink Rate slider to set the frequency at which the cursor blinks.
+
+@item
+Check the Use System Highlight Color option to use the system default
+color for highlighted text.
+
+@end itemize
+
+@section Modifier Interpretation Preferences
+
+The Modifier Preferences can be used to change the behaviour of the
+Alt/Opt and Command keys.  By default the Alt or Opt key is bound to
+the Emacs 'Meta' key, and the Command key is bound to 'super' which
+allows the Command key to function in a way similar to other
+NeXTstep/OS X applications.
+
+@itemize @bullet
+@item
+To re-bind the Alt or Opt key select a keybinding from the Alt/Opt Key
+combo box.
+@item
+To re-bind the Command key select a keybinding from the Command Key
+combo box.
+@end itemize
+
+
+@node Customization, Tips and Tricks, Preferences Panel, Top
+@section Customization
+
+Under X, resources are used to customize the behavior of Emacs to the needs of
+the user.  These resources are queried programmatically with the
+@code{x-get-resource} function.  Under NS defaults fulfill a similar function.
+They can be read using the @code{ns-get-resource} function.  Calls to
+@code{x-get-resource} are automatically mapped to @code{ns-get-resource}.
+From the command line, the command `@code{defaults read Emacs}' will show
+these resources as of last Emacs quit, and individual resources can be
+read/written by commands like `@code{defaults read Emacs Foo}' and
+`@code{defaults write Emacs Foo barvalue}'.
+
+Calling the function @code{ns-save-preferences} in lisp, or selecting ``Save
+Options'' from the 'Options' menu will automatically write out the defaults
+corresponding to the selected window.
+
+In addition, it is also possible to set many of the following customizations
+by setting the @code{default-frame-alist} in the @file{~/.emacs} file.
+
+Many of the preferences relating specifically to the NS windowing system (font
+rendering, cursor type, etc.) can be set using a @ref{Preferences Panel}
+accessed in the standard fashion from the menubar or Cmd-,.  It is important
+to note that when you hit 'OK' on this panel, @emph{all} NS settings are saved
+(including font and colors) just as if you had called
+@code{ns-save-preferences}.
+
+Note that if you use the 'Default Font' button on the Preferences panel, you
+must click on a frame before selecting a font, otherwise nothing will happen.
+If you pop up the color panel, you must drag colors to a frame for them to
+have an effect.  (Remember to hold down 'shift' to change background instead
+of foreground.)
+
+This is a listing of some of the more useful defaults (and their default
+values).  Several of these defaults accept the names of colors as values.  For
+a list of all available colors pull up the color panel and look at the color
+list called ``Emacs''.  Emacs also accepts color specifications of the form
+@samp{ARGBaarrggbb} where @var{aa}, @var{rr}, @var{gg}, and @var{bb} are two
+hexadecimal digits describing the alpha, red, green, and blue content of the
+color respectively.  @samp{HSBhhssbbaa}, @samp{CMYKccmmyykkaa} and
+@samp{GRAYggaa} are the equivalents in @samp{HSB}, @samp{CMYK} and gray
+scales.
+
+@table @samp
+@item InternalBorderWidth
+Width in pixels of the internal border of the NS frame.  This acts to separate
+the text area of the window from the fringes, scrollbars, and/or edges.
+
+@example
+defaults write Emacs InternalBorderWidth 2
+@end example
+
+@item VerticalScrollBars
+@samp{YES} or @samp{NO} to enable or disable scroll bars, @samp{left} or
+@samp{right} to explicitly set the side.
+
+@example
+defaults write Emacs VerticalScrollBars YES
+@end example
+
+@item Font
+Name of the default font to be used for new frames (which can be overriden by
+various faces).  If this font is not set, Emacs.app will use the system
+wide fixed pitch font.  For most users the system fixed pitch font will be
+@samp{Monaco} which doesn't have any bold or italic versions.  (Italic will be
+synthesized.)
+
+@item FontSize
+Size of the font to be used for new frames.  If not set Emacs for NS will use
+the default size of the system wide fixed pitch font.
+
+@item Foreground
+The default foreground (text) color for new frames.
+
+@example
+defaults write Emacs Foreground "Black"
+@end example
+
+@item Background
+The default background color for new frames.
+
+@example
+defaults write Emacs Background "White"
+@end example
+
+@item Height
+Height in rows of the default window.
+
+@example
+defaults write Emacs Height 48
+@end example
+
+@item Width
+Width in columns of the default window.
+
+@example
+defaults write Emacs Width 80
+@end example
+
+@item CursorType
+Name of the default cursor type for Emacs.  Allowed values are
+@samp{box}, @samp{hollow}, @samp{underscore}, @samp{bar},  @samp{line} and @samp{no}.
+
+@example
+defaults write Emacs CursorType box
+@end example
+
+@item CursorBlinkRate
+Users who want their cursor to blink can set the rate (in seconds) with
+this defaults write.  Setting it to @samp{NO} disables cursor blinking.
+
+@example
+defaults write Emacs CursorBlinkRate NO
+@end example
+
+@item CursorColor
+Name of the default cursor color for Emacs.  Of a particular use for this
+setting is the @samp{Highlight} "color".  When it is the cursor color,
+Emacs will draw the cursor using the standard NS highlighting operator.
+
+@example
+defaults write Emacs CursorColor Highlight
+@end example
+
+@item Top
+Distance in pixels from the top of the screen of the upper left corner
+of the default window.
+
+@example
+defaults write Emacs Top 100
+@end example
+
+@item Left
+Distance in pixels from the left edge of the screen to the upper left
+corner of the default window.
+
+@example
+defaults write Emacs Left 100
+@end example
+
+@item HideOnAutoLaunch
+@samp{YES} or @samp{NO} to determine whether Emacs will hide itself when
+autolaunched from the dock.
+
+@example
+defaults write Emacs HideOnAutoLaunch NO
+@end example
+
+@item ExpandSpace
+This lets you expand or shrink the line height used for displaying text.  When
+this is set to 0.0, display should look like other NS apps.  If you set it
+higher than 0, Emacs will spread the text lines apart, less than 0, compress
+them together.  (With settings below zero parts of characters may be chopped
+off in certain fonts.)  When using the @ref{Preferences Panel}, this is
+controlled by a slider.  You must OK the panel and then restart Emacs.app for
+this default to take effect.
+
+When setting this using @code{"defaults write"}, you can either set a floating
+point value, or @samp{YES}, which is equivalent 0.5, or @samp{NO}, which is
+equivalent to 0.0.
+
+@example
+defaults write Emacs ExpandSpace -0.125
+@end example
+
+@item GSFontAntiAlias
+This turns antialiasing on and off on.  Note that, on OS X, even if
+antialiasing is on, Emacs will not antialias text of a size below the system
+preference setting.
+
+@example
+defaults write Emacs GSFontAntiAlias NO
+@end example
+
+@item UseQuickdrawSmoothing
+On OS X 10.3 and higher, this will render fonts using Quickdraw antialiasing,
+which is less heavy than the Quartz antialiasing used by default.  Whether
+this is on or off, the system font size threshold for antialiasing (see above)
+is respected.
+
+@example
+defaults write Emacs UseQuickdrawSmoothing YES
+@end example
+
+@item AlternateModifier
+This allows you to set the effect of the Alt or Opt key.  The default is
+@samp{meta}, meaning to use as the Emacs 'meta' key.  You can also set this to
+@samp{command}, @samp{hyper}, @samp{alt}, or @samp{none}.  The last is useful
+for Continental users who normally use this key to enter accented and other
+special characters.
+
+@example
+defaults write Emacs AlternateModifier "none"
+@end example
+
+@item CommandModifier
+This allows you to set the effect of the Command key.  The default is
+@samp{super}, which is used in a set of keybindings such as @code{s-o} for
+``open file'' and @code{s-z} for ``undo'' that are similar to other NeXTstep
+applications.  On the other hand, some people who use the Alt/Opt key for
+accent entry like to set this to @samp{meta} so they still have easy access to
+Emacs functionality bound to meta keys.  You can also set this, like Alt/Opt,
+to @samp{hyper} or @samp{alt}, though there are no bindings to combinations
+using these keys by default.  The @samp{none} option is not available for the
+Command key.
+
+@example
+defaults write Emacs CommandModifier "meta"
+@end example
+
+@item fooFrame
+Position and size to use for the frame named @var{foo} when it is
+created.  The position and size have to be specified as a space
+separated list: @samp{top}, @samp{left}, @samp{height} and
+@samp{width}. @samp{top} and @samp{left} are expressed in pixels,
+@samp{height} is given in rows and @samp{width} is given in columns.
+Named frames can be created by e.g. @code{(make-frame '((name
+. "FOO")))}.
+
+@example
+defaults write Emacs TestFrame "100 200 30 70"
+@end example
+
+Another default previouly used by many Emacs users is this.
+
+@example
+defaults write Workspace DefaultOpenApp Emacs
+@end example
+
+It caused the NeXTstep Workspace to open files without a registered extension
+in Emacs instead of as usual Edit.  For this default to work, Emacs needed to
+be in the application search path of the Workspace (which usually includes
+@file{~/Applications} and @file{~/Applications}).  If anyone knows the current
+way to do this under OS X please contact the authors.
+
+@end table
+
+@node Tips and Tricks, Thanks, Customization, Top
+@section Tips and Tricks
+
+Emacs is an extremely customizable editor.  You can make it conform to
+virtually any conceivable user idiosyncrasy (and some which are not) by adding
+a few well-chosen lines of emacs lisp to your @file{~/.emacs}.  Unfortunately
+even many experienced C developers are unfamiliar with Emacs Lisp.  For that
+reason many Emacs.app defaults have been chosen to make it behave as similar
+to TextEdit as possible.  But there are some customizations which a majority
+of users probably would hate as much as a minority would love them.  This
+section contains a cookbook of such customizations.  New contributions by
+Emacs users are very welcome.
+
+@menu
+* Grabbing environment variables::  
+* Miscellaneous useful variables::  
+* Color adjustments::           
+* Evaling in the minibuffer::   
+* Highlighting matching parentheses::  
+* Dealing with X specific packages::  
+* Rebinding the numeric keypad::  
+* Improving C mode::            
+* Custom menu items::           
+* Single line scrolling::       
+* Open files by dragging to an Emacs window:: 
+@ignore
+* Extended font customization::  
+@end ignore
+@end menu
+
+@node Grabbing environment variables, Miscellaneous useful variables, Tips and Tricks, Tips and Tricks
+@subsection Grabbing environment variables
+
+Many programs which may run under Emacs like latex or man depend on the
+settings of environment variables.  If Emacs is launched from the shell, it
+will automatically inherit these environment variables and its subprocesses
+will inherit them from it.  But if Emacs.app is launched from the Finder it
+is not a descendant of any shell, so its environment variables haven't been
+set which often causes the subprocesses it launches to behave differently than
+they would when launched from the shell.
+
+To solve this problem for Emacs.app, there are two solutions.  First is to
+run, from the command line:
+
+@example
+.../Emacs.app/Contents/MacOS/bin/mac-fix-env
+@end example
+
+This will pick up your environment settings and save them into a special file
+@file{~/.MacOSX/environment.plist}, which the desktop environment will use to
+set the environment for all launched applications.  The drawback of this
+method is it needs to be run again whenever something changes.
+
+The other approach is to use the @code{ns-grabenv} command inside Emacs.  This
+function will run a subshell and copy its environment variables into Emacs.
+
+Adding this line to your @file{~/.emacs} will grab the csh environment
+whenever emacs runs under a window system.
+
+@lisp
+(if window-system (ns-grabenv))
+@end lisp
+
+If you have a different shell you will have to give @code{ns-grabenv} some
+arguments.  For zsh you would do this.
+
+@lisp
+(if window-system (ns-grabenv "/usr/bin/zsh"
+                           "source /etc/zshenv"
+                           "source ~/.zshenv"))
+@end lisp
+
+The reason that @code{ns-grabenv} is not done by default is that it adds up
+to a second or two to the Emacs startup time.
+
+@node Miscellaneous useful variables, Color adjustments, Grabbing environment variables, Tips and Tricks
+@subsection Miscellaneous useful variables
+
+This section describes a few variables you might want to set in your
+@file{~/.emacs} each of which doesn't warrant its own section.
+
+There is a conflict between the way the region behaved in emacs in the
+pre-GUI days and the way GUI users expect the selection to work.  By
+default that conflict is resolved by having the former adopt the
+behaviour of the latter which most people prefer.  However if you are a
+die-hard emacs user you may prefer things the other way around and add
+this line to your @file{~/.emacs}.  Experiment with both settings.
+
+@lisp
+(setq transient-mark-mode nil)
+@end lisp
+
+When you try to move beyond the end of a file Emacs used to add newlines as
+needed, however from Emacs-21 on, this was no longer done.  If you prefer the
+old behavior, this line in your @file{~/.emacs} will restore it.
+
+@lisp
+(setq next-line-add-newlines t)
+@end lisp
+
+By default when you kill a line with text on it, only the text is
+removed while the line itself remains.  You have to kill twice to really
+get rid of the whole line.  When this variable is set and you kill a
+line while at the beginning of the line it will go at once.
+
+@lisp
+(setq kill-whole-line t)
+@end lisp
+
+Annoyed by the Emacs startup message ?  Add this and you start with a
+tabula rasa.
+
+@lisp
+(setq inhibit-startup-message t)
+@end lisp
+
+@node Color adjustments, Evaling in the minibuffer, Miscellaneous useful variables, Tips and Tricks
+@subsection Color adjustments
+
+A non-elisp hint: The easiest way to adjust your emacs color scheme is to
+bring up a color panel (with @key{Cmd-C}) and drag the color you want over the
+emacs face you want to change.  Normal dragging will alter the foreground
+color.  Shift dragging will alter the background color.  To make the changes
+permanent select the "Save Options" item in the "Options" menu, or run
+@code{ns-save-preferences}.  Useful in this context is the listing of all
+faces obtained by @key{M-x} @code{list-faces-display}.
+
+@node Evaling in the minibuffer, Highlighting matching parentheses, Color adjustments, Tips and Tricks
+@subsection Evaling in the minibuffer
+
+Often you (at least if you are an elisp hacker) want to quickly evaluate
+an elisp expression.  To accomodate this desire Emacs provides the
+@code{eval-expression} command bound to @key{M-:}.  By default it is
+disabled to protect novice users from themselves.  These commands
+re-enable it and turn on an extremely powerful completion facility.
+
+@lisp
+(put 'eval-expression 'disabled nil)
+
+(define-key read-expression-map "\t" 'lisp-complete-symbol)
+@end lisp
+
+@node Highlighting matching parentheses, Dealing with X specific packages, Evaling in the minibuffer, Tips and Tricks
+@subsection Highlighting matching parentheses
+
+I doubt that there is anybody who doesn't use this already, but just in
+case:
+
+@lisp
+(show-paren-mode 't)
+@end lisp
+
+In Emacs.app this is currently enhanced by use of the @code{mic-paren} package
+from http://www.docs.uu.se/~mic/emacs.html.
+
+@node Dealing with X specific packages, Rebinding the numeric keypad, Highlighting matching parentheses, Tips and Tricks
+@subsection Dealing with X specific packages
+
+Some emacs lisp packages explicitly call X specific functions instead of
+calling generic functions which call the NS or X versions as appropriate.
+Typically such packages will result in error messages like @samp{Symbol's
+function definition is void: x-foo-bar}.  The proper way of dealing with this
+is to have the author fix the code to call the generic functions.  Generally
+all that requires is removing the @samp{x-} prefix from all function calls.
+
+However, sometimes that is not possible, or it may be a package internal to
+emacs itself.  In this case please report a bug to the Emacs.app maintainers
+(not the main GNU emacs maintainers).
+
+A related problem is font names.  For historical reasons, Emacs assumes all
+font names are given ``X style'', as in ``-adobe-courier-....-iso8859-1''.
+Emacs.app tries to work around this as well as possible, and the best thing to
+do is never rely on functions to set font names yourself but to always use the
+font panel.
+
+@node Rebinding the numeric keypad, Improving C mode, Dealing with X specific packages, Tips and Tricks
+@subsection Rebinding the numeric keypad
+
+By default in Emacs the numeric keypad keys are bound to the same
+characters they are in all other NS applications.  But it is easy to
+change these bindings to commands many will find more useful.  As an
+example here is the code which rebinds the numeric keypad for me.
+
+@lisp
+(global-set-key [kp-0] 'other-window)
+(global-set-key [kp-1] 'end-of-buffer)
+(global-set-key [kp-2] [down])
+(global-set-key [kp-3] 'scroll-up)
+(global-set-key [kp-4] [left])
+(global-set-key [kp-5] 'set-mark-command)
+(global-set-key [kp-6] [right])
+(global-set-key [kp-7] 'beginning-of-buffer)
+(global-set-key [kp-8] [up])
+(global-set-key [kp-9] 'scroll-down)
+(global-set-key [kp-decimal] 'yank)
+(global-set-key [kp-enter] 'set-mark-command)
+(global-set-key [kp-add] 'copy-region-as-kill)
+(global-set-key [kp-subtract] 'kill-region)
+@end lisp
+
+On machines with function keys they can be bound as well.  This for example
+would bind @key{F12} to run gnus.
+
+@lisp
+(global-set-key [f12] 'gnus)
+@end lisp
+
+@node Improving C mode, Custom menu items, Rebinding the numeric keypad, Tips and Tricks
+@subsection Improving C mode
+
+That underscores are considered to break words in C mode has been driving me
+insane for a long time.  This line fixes the problem.
+
+@lisp
+(modify-syntax-entry ?_ "w" c-mode-syntax-table)
+@end lisp
+
+@node Custom menu items, Single line scrolling, Improving C mode, Tips and Tricks
+@subsection Custom menu items
+
+The tools menu is intended for customization.  Adding items to it is
+relatively painless as this example illustrates.
+
+@lisp
+(define-key global-map [menu-bar tools www] '("WWW" . w3-use-hotlist))
+@end lisp
+
+@node Single line scrolling, Open files by dragging to an Emacs window, Custom menu items, Tips and Tricks
+@subsection Single line scrolling
+
+The meta-arrow keys will perform single-line scrolling in Emacs
+just like they did in the old NeXT/OpenStep Stuart.app.
+
+@node Open files by dragging to an Emacs window, , Single line scrolling, Tips and Tricks
+@subsection Open files by dragging to an Emacs window
+
+The default behaviour when a user drags files from another application
+into an Emacs frame is to insert the contents of all the dragged files
+into the current buffer.  To remap the @code{ns-drag-file} event to
+open the dragged files in the current frame use the following line:
+
+@lisp
+(define-key global-map [ns-drag-file] 'ns-find-file)
+@end lisp
+
+@ignore
+@node Extended font customization,  , Single line scrolling, Tips and Tricks
+@subsection Extended font customization
+
+By default Emacs tries to guess the right font when you ask for a bold,
+italic or bold-italic face.  Unfortunately this fails sometimes, for
+example Emacs won't guess that it should use @samp{Courier-Bold} as the
+font for the bold face of @samp{Ohlfs}.  As an example here is the code
+which sets up @samp{Courier-Bold}, @samp{Courier-Oblique} and
+@samp{Courier-BoldOblique} as the fonts to be used with @samp{Ohlfs}.
+
+@lisp
+(setq ns-convert-font-trait-alist
+      '(("Ohlfs" "Courier-Bold" "Courier-Oblique"
+         "Courier-BoldOblique")))
+@end lisp
+
+You will still have to set the @samp{DefaultFont}, @samp{BoldFont},
+@samp{ItalicFont} and @samp{Bold-ItalicFont} defaults as Emacs
+initializes the default faces before it reads your @file{~/.emacs}.
+Also Emacs initializes @code{ns-convert-font-trait-alist} from these
+defaults so that normally it's sufficient to set these defaults to get
+correct faces.
+
+@example
+defaults write Emacs DefaultFont Ohlfs
+defaults write Emacs BoldFont Courier-Bold
+defaults write Emacs ItalicFont Courier-Oblique
+defaults write Emacs Bold-ItalicFont Courier-BoldOblique
+@end example
+@end ignore
+
+
+@node Thanks,  , Tips and Tricks, Top
+@section Thanks
+A signficant number of people have been involved in the creation of Emacs.app.
+Carl Edman <cedman@@lynx.ps.uci.edu> created and maintained Emacs up to
+version 4.1 and it's reasonable to say that without his work, Emacs.app
+wouldn't exist.  Michael Brouwer <michael@@thi.nl> wrote the original version
+(up to and including version 3.x) and was a constant contributor to Emacs.app
+version 4 and above.  Christian Limpach <chris@@nice.ch> took over maintenance
+and updating at version 4.2, and made substantial contributions in a number of
+areas.  Scott Bender <sbender@@harmony-ds.com> ported the code to OpenStep and
+Rhapsody for version 6.0.  Christophe de Dinechin <ddd@@cup.hp.com> ported the
+code to MacOS X for version 7.0 and moved the code base to SourceForge.  Leigh
+Smith <leigh@@leighsmith.com> maintained the SourceForge project for a period.
+Adrian Robert <arobert@@cogsci.ucsd.edu> ported the code to GNUstep
+(http://gnustep.org), updated it for post-emacs-20, and maintains it for the
+present.
+
+Also a number of others have contributed code.  Steve Nygard
+<nygard@@telusplanet.net> got emacs to dump under OpenStep.  The font panel
+code was Andrew Athan's <athan@@object.com> work.  Joe Reiss
+<jreiss@@magnus.acs.ohio-state.edu> both created the beautiful icons you see
+and wrote the popup menu and dialog box code as well as much else.  (Actually,
+Joe's icon became the one used for the Mac Carbon port..)
+
+Finally, suggestions from Darcy Brockbank, Timothy Bissell, Scott Byer, David
+Griffiths, Scott Hess, Eberhard Mandler, John C. Randolph, and Bradley Taylor
+all helped things along at one point or another.  Axel Seibert
+<seiberta@@informatik.tu-muenchen.de> and Paul J. Sanchez
+<paul@@whimsy.umsl.edu> offered their time and machines to make a binary
+release possible.
+
+The GNUstep port was made possible through the assistance of Adam Fedor, Fred
+Kiefer, M. Uli Klusterer, Alexander Malmberg, and Jonas Matton.  Gürkan Sengün
+made it accessible to a wider community.
+
+Riccardo Mottola helped with compatibility with MacOS versions 10.1 and 10.2,
+and GNUstep on platforms other than Linux.
+
+Peter Dyballa kept things honest with multilingual support.  Rahul Abrol, Adam
+Ratcliffe, David M. Cooke, and Carsten Bormann provided various small patches.
+
+Then there were a number of people who kept up the constant supply of bug
+reports, suggested features and praise (which is the main fuel which the
+development of a project like this runs) and so helped ensure that this
+program is as bug free (hah !)  and feature rich as you see it today.  First
+among them were Hardy Mayer <hardy@@golem.ps.uci.edu>, Gisli Ottarsson
+<gisli@@timoshenko.eecs.umich.edu>, Anthony Heading <ajrh@@signal.dra.hmg.gb>,
+David Bau <bau@@cs.cornell.edu>, Jamie Zawinski <jwz@@lucid.com>, Martin
+Moncrieffe <moncrief@@mayo.edu>, Simson L. Garfinkel
+<simsong@@next.cambridge.ma.us>, Richard Stallman <rms@@gnu.ai.mit.edu>,
+Stephen Anderson <anderson@@sapir.cog.jhu.edu>, Ivo Welch
+<ivo@@next.agsm.ucla.edu>, Magnus Nordborg <magnus@@fisher.Stanford.EDU>, Tom
+Epperly <epperly@@valeron.che.wisc.edu>, Andreas Koenig
+<k@@franz.ww.tu-berlin.de>, Yves Arrouye <Yves.Arrouye@@imag.fr>, Anil
+Somayaji <soma@@hotspur.mit.edu>, Gregor Hoffleit
+<flight@@mathi.uni-heidelberg.DE> and doubtlessly many more.
+
+Finally, let us also thank those few hundred other people on the mailing list
+from whom we didn't hear much, but the presence of which assured us that maybe
+this project was actually worth doing.
+@bye
--- a/etc/ChangeLog	Tue Jul 15 15:45:05 2008 +0000
+++ b/etc/ChangeLog	Tue Jul 15 18:15:18 2008 +0000
@@ -1,3 +1,8 @@
+2008-07-15  Adrian Robert <Adrian.B.Robert@gmail.com>
+
+	* Emacs.clr: New file, add support for X color names to NS display
+	implementations.
+
 2008-07-12  Juri Linkov  <juri@jurta.org>
 
 	* HELLO: Use more correct IPA characters for English pronunciation.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/etc/Emacs.clr	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,758 @@
+757
+0 1.000 0.980 0.980 1.0 snow
+0 0.973 0.973 1.000 1.0 ghost white
+0 0.973 0.973 1.000 1.0 GhostWhite
+0 0.961 0.961 0.961 1.0 white smoke
+0 0.961 0.961 0.961 1.0 WhiteSmoke
+0 0.863 0.863 0.863 1.0 gainsboro
+0 1.000 0.980 0.941 1.0 floral white
+0 1.000 0.980 0.941 1.0 FloralWhite
+0 0.992 0.961 0.902 1.0 old lace
+0 0.992 0.961 0.902 1.0 OldLace
+0 0.980 0.941 0.902 1.0 linen
+0 0.980 0.922 0.843 1.0 antique white
+0 0.980 0.922 0.843 1.0 AntiqueWhite
+0 1.000 0.937 0.835 1.0 papaya whip
+0 1.000 0.937 0.835 1.0 PapayaWhip
+0 1.000 0.922 0.804 1.0 blanched almond
+0 1.000 0.922 0.804 1.0 BlanchedAlmond
+0 1.000 0.894 0.769 1.0 bisque
+0 1.000 0.855 0.725 1.0 peach puff
+0 1.000 0.855 0.725 1.0 PeachPuff
+0 1.000 0.871 0.678 1.0 navajo white
+0 1.000 0.871 0.678 1.0 NavajoWhite
+0 1.000 0.894 0.710 1.0 moccasin
+0 1.000 0.973 0.863 1.0 cornsilk
+0 1.000 1.000 0.941 1.0 ivory
+0 1.000 0.980 0.804 1.0 lemon chiffon
+0 1.000 0.980 0.804 1.0 LemonChiffon
+0 1.000 0.961 0.933 1.0 seashell
+0 0.941 1.000 0.941 1.0 honeydew
+0 0.961 1.000 0.980 1.0 mint cream
+0 0.961 1.000 0.980 1.0 MintCream
+0 0.941 1.000 1.000 1.0 azure
+0 0.941 0.973 1.000 1.0 alice blue
+0 0.941 0.973 1.000 1.0 AliceBlue
+0 0.902 0.902 0.980 1.0 lavender
+0 1.000 0.941 0.961 1.0 lavender blush
+0 1.000 0.941 0.961 1.0 LavenderBlush
+0 1.000 0.894 0.882 1.0 misty rose
+0 1.000 0.894 0.882 1.0 MistyRose
+0 1.000 1.000 1.000 1.0 white
+0 0.000 0.000 0.000 1.0 black
+0 0.184 0.310 0.310 1.0 dark slate gray
+0 0.184 0.310 0.310 1.0 DarkSlateGray
+0 0.184 0.310 0.310 1.0 dark slate grey
+0 0.184 0.310 0.310 1.0 DarkSlateGrey
+0 0.412 0.412 0.412 1.0 dim gray
+0 0.412 0.412 0.412 1.0 DimGray
+0 0.412 0.412 0.412 1.0 dim grey
+0 0.412 0.412 0.412 1.0 DimGrey
+0 0.439 0.502 0.565 1.0 slate gray
+0 0.439 0.502 0.565 1.0 SlateGray
+0 0.439 0.502 0.565 1.0 slate grey
+0 0.439 0.502 0.565 1.0 SlateGrey
+0 0.467 0.533 0.600 1.0 light slate gray
+0 0.467 0.533 0.600 1.0 LightSlateGray
+0 0.467 0.533 0.600 1.0 light slate grey
+0 0.467 0.533 0.600 1.0 LightSlateGrey
+0 0.745 0.745 0.745 1.0 gray
+0 0.745 0.745 0.745 1.0 grey
+0 0.827 0.827 0.827 1.0 light grey
+0 0.827 0.827 0.827 1.0 LightGrey
+0 0.827 0.827 0.827 1.0 light gray
+0 0.827 0.827 0.827 1.0 LightGray
+0 0.098 0.098 0.439 1.0 midnight blue
+0 0.098 0.098 0.439 1.0 MidnightBlue
+0 0.000 0.000 0.502 1.0 navy
+0 0.000 0.000 0.502 1.0 navy blue
+0 0.000 0.000 0.502 1.0 NavyBlue
+0 0.392 0.584 0.929 1.0 cornflower blue
+0 0.392 0.584 0.929 1.0 CornflowerBlue
+0 0.282 0.239 0.545 1.0 dark slate blue
+0 0.282 0.239 0.545 1.0 DarkSlateBlue
+0 0.416 0.353 0.804 1.0 slate blue
+0 0.416 0.353 0.804 1.0 SlateBlue
+0 0.482 0.408 0.933 1.0 medium slate blue
+0 0.482 0.408 0.933 1.0 MediumSlateBlue
+0 0.518 0.439 1.000 1.0 light slate blue
+0 0.518 0.439 1.000 1.0 LightSlateBlue
+0 0.000 0.000 0.804 1.0 medium blue
+0 0.000 0.000 0.804 1.0 MediumBlue
+0 0.255 0.412 0.882 1.0 royal blue
+0 0.255 0.412 0.882 1.0 RoyalBlue
+0 0.000 0.000 1.000 1.0 blue
+0 0.118 0.565 1.000 1.0 dodger blue
+0 0.118 0.565 1.000 1.0 DodgerBlue
+0 0.000 0.749 1.000 1.0 deep sky blue
+0 0.000 0.749 1.000 1.0 DeepSkyBlue
+0 0.529 0.808 0.922 1.0 sky blue
+0 0.529 0.808 0.922 1.0 SkyBlue
+0 0.529 0.808 0.980 1.0 light sky blue
+0 0.529 0.808 0.980 1.0 LightSkyBlue
+0 0.275 0.510 0.706 1.0 steel blue
+0 0.275 0.510 0.706 1.0 SteelBlue
+0 0.690 0.769 0.871 1.0 light steel blue
+0 0.690 0.769 0.871 1.0 LightSteelBlue
+0 0.678 0.847 0.902 1.0 light blue
+0 0.678 0.847 0.902 1.0 LightBlue
+0 0.690 0.878 0.902 1.0 powder blue
+0 0.690 0.878 0.902 1.0 PowderBlue
+0 0.686 0.933 0.933 1.0 pale turquoise
+0 0.686 0.933 0.933 1.0 PaleTurquoise
+0 0.000 0.808 0.820 1.0 dark turquoise
+0 0.000 0.808 0.820 1.0 DarkTurquoise
+0 0.282 0.820 0.800 1.0 medium turquoise
+0 0.282 0.820 0.800 1.0 MediumTurquoise
+0 0.251 0.878 0.816 1.0 turquoise
+0 0.000 1.000 1.000 1.0 cyan
+0 0.878 1.000 1.000 1.0 light cyan
+0 0.878 1.000 1.000 1.0 LightCyan
+0 0.373 0.620 0.627 1.0 cadet blue
+0 0.373 0.620 0.627 1.0 CadetBlue
+0 0.400 0.804 0.667 1.0 medium aquamarine
+0 0.400 0.804 0.667 1.0 MediumAquamarine
+0 0.498 1.000 0.831 1.0 aquamarine
+0 0.000 0.392 0.000 1.0 dark green
+0 0.000 0.392 0.000 1.0 DarkGreen
+0 0.333 0.420 0.184 1.0 dark olive green
+0 0.333 0.420 0.184 1.0 DarkOliveGreen
+0 0.561 0.737 0.561 1.0 dark sea green
+0 0.561 0.737 0.561 1.0 DarkSeaGreen
+0 0.180 0.545 0.341 1.0 sea green
+0 0.180 0.545 0.341 1.0 SeaGreen
+0 0.235 0.702 0.443 1.0 medium sea green
+0 0.235 0.702 0.443 1.0 MediumSeaGreen
+0 0.125 0.698 0.667 1.0 light sea green
+0 0.125 0.698 0.667 1.0 LightSeaGreen
+0 0.596 0.984 0.596 1.0 pale green
+0 0.596 0.984 0.596 1.0 PaleGreen
+0 0.000 1.000 0.498 1.0 spring green
+0 0.000 1.000 0.498 1.0 SpringGreen
+0 0.486 0.988 0.000 1.0 lawn green
+0 0.486 0.988 0.000 1.0 LawnGreen
+0 0.000 1.000 0.000 1.0 green
+0 0.498 1.000 0.000 1.0 chartreuse
+0 0.000 0.980 0.604 1.0 medium spring green
+0 0.000 0.980 0.604 1.0 MediumSpringGreen
+0 0.678 1.000 0.184 1.0 green yellow
+0 0.678 1.000 0.184 1.0 GreenYellow
+0 0.196 0.804 0.196 1.0 lime green
+0 0.196 0.804 0.196 1.0 LimeGreen
+0 0.604 0.804 0.196 1.0 yellow green
+0 0.604 0.804 0.196 1.0 YellowGreen
+0 0.133 0.545 0.133 1.0 forest green
+0 0.133 0.545 0.133 1.0 ForestGreen
+0 0.420 0.557 0.137 1.0 olive drab
+0 0.420 0.557 0.137 1.0 OliveDrab
+0 0.741 0.718 0.420 1.0 dark khaki
+0 0.741 0.718 0.420 1.0 DarkKhaki
+0 0.941 0.902 0.549 1.0 khaki
+0 0.933 0.910 0.667 1.0 pale goldenrod
+0 0.933 0.910 0.667 1.0 PaleGoldenrod
+0 0.980 0.980 0.824 1.0 light goldenrod yellow
+0 0.980 0.980 0.824 1.0 LightGoldenrodYellow
+0 1.000 1.000 0.878 1.0 light yellow
+0 1.000 1.000 0.878 1.0 LightYellow
+0 1.000 1.000 0.000 1.0 yellow
+0 1.000 0.843 0.000 1.0 gold
+0 0.933 0.867 0.510 1.0 light goldenrod
+0 0.933 0.867 0.510 1.0 LightGoldenrod
+0 0.855 0.647 0.125 1.0 goldenrod
+0 0.722 0.525 0.043 1.0 dark goldenrod
+0 0.722 0.525 0.043 1.0 DarkGoldenrod
+0 0.737 0.561 0.561 1.0 rosy brown
+0 0.737 0.561 0.561 1.0 RosyBrown
+0 0.804 0.361 0.361 1.0 indian red
+0 0.804 0.361 0.361 1.0 IndianRed
+0 0.545 0.271 0.075 1.0 saddle brown
+0 0.545 0.271 0.075 1.0 SaddleBrown
+0 0.627 0.322 0.176 1.0 sienna
+0 0.804 0.522 0.247 1.0 peru
+0 0.871 0.722 0.529 1.0 burlywood
+0 0.961 0.961 0.863 1.0 beige
+0 0.961 0.871 0.702 1.0 wheat
+0 0.957 0.643 0.376 1.0 sandy brown
+0 0.957 0.643 0.376 1.0 SandyBrown
+0 0.824 0.706 0.549 1.0 tan
+0 0.824 0.412 0.118 1.0 chocolate
+0 0.698 0.133 0.133 1.0 firebrick
+0 0.647 0.165 0.165 1.0 brown
+0 0.914 0.588 0.478 1.0 dark salmon
+0 0.914 0.588 0.478 1.0 DarkSalmon
+0 0.980 0.502 0.447 1.0 salmon
+0 1.000 0.627 0.478 1.0 light salmon
+0 1.000 0.627 0.478 1.0 LightSalmon
+0 1.000 0.647 0.000 1.0 orange
+0 1.000 0.549 0.000 1.0 dark orange
+0 1.000 0.549 0.000 1.0 DarkOrange
+0 1.000 0.498 0.314 1.0 coral
+0 0.941 0.502 0.502 1.0 light coral
+0 0.941 0.502 0.502 1.0 LightCoral
+0 1.000 0.388 0.278 1.0 tomato
+0 1.000 0.271 0.000 1.0 orange red
+0 1.000 0.271 0.000 1.0 OrangeRed
+0 1.000 0.000 0.000 1.0 red
+0 1.000 0.412 0.706 1.0 hot pink
+0 1.000 0.412 0.706 1.0 HotPink
+0 1.000 0.078 0.576 1.0 deep pink
+0 1.000 0.078 0.576 1.0 DeepPink
+0 1.000 0.753 0.796 1.0 pink
+0 1.000 0.714 0.757 1.0 light pink
+0 1.000 0.714 0.757 1.0 LightPink
+0 0.859 0.439 0.576 1.0 pale violet red
+0 0.859 0.439 0.576 1.0 PaleVioletRed
+0 0.690 0.188 0.376 1.0 maroon
+0 0.780 0.082 0.522 1.0 medium violet red
+0 0.780 0.082 0.522 1.0 MediumVioletRed
+0 0.816 0.125 0.565 1.0 violet red
+0 0.816 0.125 0.565 1.0 VioletRed
+0 1.000 0.000 1.000 1.0 magenta
+0 0.933 0.510 0.933 1.0 violet
+0 0.867 0.627 0.867 1.0 plum
+0 0.855 0.439 0.839 1.0 orchid
+0 0.729 0.333 0.827 1.0 medium orchid
+0 0.729 0.333 0.827 1.0 MediumOrchid
+0 0.600 0.196 0.800 1.0 dark orchid
+0 0.600 0.196 0.800 1.0 DarkOrchid
+0 0.580 0.000 0.827 1.0 dark violet
+0 0.580 0.000 0.827 1.0 DarkViolet
+0 0.541 0.169 0.886 1.0 blue violet
+0 0.541 0.169 0.886 1.0 BlueViolet
+0 0.627 0.125 0.941 1.0 purple
+0 0.576 0.439 0.859 1.0 medium purple
+0 0.576 0.439 0.859 1.0 MediumPurple
+0 0.847 0.749 0.847 1.0 thistle
+0 1.000 0.980 0.980 1.0 snow1
+0 0.933 0.914 0.914 1.0 snow2
+0 0.804 0.788 0.788 1.0 snow3
+0 0.545 0.537 0.537 1.0 snow4
+0 1.000 0.961 0.933 1.0 seashell1
+0 0.933 0.898 0.871 1.0 seashell2
+0 0.804 0.773 0.749 1.0 seashell3
+0 0.545 0.525 0.510 1.0 seashell4
+0 1.000 0.937 0.859 1.0 AntiqueWhite1
+0 0.933 0.875 0.800 1.0 AntiqueWhite2
+0 0.804 0.753 0.690 1.0 AntiqueWhite3
+0 0.545 0.514 0.471 1.0 AntiqueWhite4
+0 1.000 0.894 0.769 1.0 bisque1
+0 0.933 0.835 0.718 1.0 bisque2
+0 0.804 0.718 0.620 1.0 bisque3
+0 0.545 0.490 0.420 1.0 bisque4
+0 1.000 0.855 0.725 1.0 PeachPuff1
+0 0.933 0.796 0.678 1.0 PeachPuff2
+0 0.804 0.686 0.584 1.0 PeachPuff3
+0 0.545 0.467 0.396 1.0 PeachPuff4
+0 1.000 0.871 0.678 1.0 NavajoWhite1
+0 0.933 0.812 0.631 1.0 NavajoWhite2
+0 0.804 0.702 0.545 1.0 NavajoWhite3
+0 0.545 0.475 0.369 1.0 NavajoWhite4
+0 1.000 0.980 0.804 1.0 LemonChiffon1
+0 0.933 0.914 0.749 1.0 LemonChiffon2
+0 0.804 0.788 0.647 1.0 LemonChiffon3
+0 0.545 0.537 0.439 1.0 LemonChiffon4
+0 1.000 0.973 0.863 1.0 cornsilk1
+0 0.933 0.910 0.804 1.0 cornsilk2
+0 0.804 0.784 0.694 1.0 cornsilk3
+0 0.545 0.533 0.471 1.0 cornsilk4
+0 1.000 1.000 0.941 1.0 ivory1
+0 0.933 0.933 0.878 1.0 ivory2
+0 0.804 0.804 0.757 1.0 ivory3
+0 0.545 0.545 0.514 1.0 ivory4
+0 0.941 1.000 0.941 1.0 honeydew1
+0 0.878 0.933 0.878 1.0 honeydew2
+0 0.757 0.804 0.757 1.0 honeydew3
+0 0.514 0.545 0.514 1.0 honeydew4
+0 1.000 0.941 0.961 1.0 LavenderBlush1
+0 0.933 0.878 0.898 1.0 LavenderBlush2
+0 0.804 0.757 0.773 1.0 LavenderBlush3
+0 0.545 0.514 0.525 1.0 LavenderBlush4
+0 1.000 0.894 0.882 1.0 MistyRose1
+0 0.933 0.835 0.824 1.0 MistyRose2
+0 0.804 0.718 0.710 1.0 MistyRose3
+0 0.545 0.490 0.482 1.0 MistyRose4
+0 0.941 1.000 1.000 1.0 azure1
+0 0.878 0.933 0.933 1.0 azure2
+0 0.757 0.804 0.804 1.0 azure3
+0 0.514 0.545 0.545 1.0 azure4
+0 0.514 0.435 1.000 1.0 SlateBlue1
+0 0.478 0.404 0.933 1.0 SlateBlue2
+0 0.412 0.349 0.804 1.0 SlateBlue3
+0 0.278 0.235 0.545 1.0 SlateBlue4
+0 0.282 0.463 1.000 1.0 RoyalBlue1
+0 0.263 0.431 0.933 1.0 RoyalBlue2
+0 0.227 0.373 0.804 1.0 RoyalBlue3
+0 0.153 0.251 0.545 1.0 RoyalBlue4
+0 0.000 0.000 1.000 1.0 blue1
+0 0.000 0.000 0.933 1.0 blue2
+0 0.000 0.000 0.804 1.0 blue3
+0 0.000 0.000 0.545 1.0 blue4
+0 0.118 0.565 1.000 1.0 DodgerBlue1
+0 0.110 0.525 0.933 1.0 DodgerBlue2
+0 0.094 0.455 0.804 1.0 DodgerBlue3
+0 0.063 0.306 0.545 1.0 DodgerBlue4
+0 0.388 0.722 1.000 1.0 SteelBlue1
+0 0.361 0.675 0.933 1.0 SteelBlue2
+0 0.310 0.580 0.804 1.0 SteelBlue3
+0 0.212 0.392 0.545 1.0 SteelBlue4
+0 0.000 0.749 1.000 1.0 DeepSkyBlue1
+0 0.000 0.698 0.933 1.0 DeepSkyBlue2
+0 0.000 0.604 0.804 1.0 DeepSkyBlue3
+0 0.000 0.408 0.545 1.0 DeepSkyBlue4
+0 0.529 0.808 1.000 1.0 SkyBlue1
+0 0.494 0.753 0.933 1.0 SkyBlue2
+0 0.424 0.651 0.804 1.0 SkyBlue3
+0 0.290 0.439 0.545 1.0 SkyBlue4
+0 0.690 0.886 1.000 1.0 LightSkyBlue1
+0 0.643 0.827 0.933 1.0 LightSkyBlue2
+0 0.553 0.714 0.804 1.0 LightSkyBlue3
+0 0.376 0.482 0.545 1.0 LightSkyBlue4
+0 0.776 0.886 1.000 1.0 SlateGray1
+0 0.725 0.827 0.933 1.0 SlateGray2
+0 0.624 0.714 0.804 1.0 SlateGray3
+0 0.424 0.482 0.545 1.0 SlateGray4
+0 0.792 0.882 1.000 1.0 LightSteelBlue1
+0 0.737 0.824 0.933 1.0 LightSteelBlue2
+0 0.635 0.710 0.804 1.0 LightSteelBlue3
+0 0.431 0.482 0.545 1.0 LightSteelBlue4
+0 0.749 0.937 1.000 1.0 LightBlue1
+0 0.698 0.875 0.933 1.0 LightBlue2
+0 0.604 0.753 0.804 1.0 LightBlue3
+0 0.408 0.514 0.545 1.0 LightBlue4
+0 0.878 1.000 1.000 1.0 LightCyan1
+0 0.820 0.933 0.933 1.0 LightCyan2
+0 0.706 0.804 0.804 1.0 LightCyan3
+0 0.478 0.545 0.545 1.0 LightCyan4
+0 0.733 1.000 1.000 1.0 PaleTurquoise1
+0 0.682 0.933 0.933 1.0 PaleTurquoise2
+0 0.588 0.804 0.804 1.0 PaleTurquoise3
+0 0.400 0.545 0.545 1.0 PaleTurquoise4
+0 0.596 0.961 1.000 1.0 CadetBlue1
+0 0.557 0.898 0.933 1.0 CadetBlue2
+0 0.478 0.773 0.804 1.0 CadetBlue3
+0 0.325 0.525 0.545 1.0 CadetBlue4
+0 0.000 0.961 1.000 1.0 turquoise1
+0 0.000 0.898 0.933 1.0 turquoise2
+0 0.000 0.773 0.804 1.0 turquoise3
+0 0.000 0.525 0.545 1.0 turquoise4
+0 0.000 1.000 1.000 1.0 cyan1
+0 0.000 0.933 0.933 1.0 cyan2
+0 0.000 0.804 0.804 1.0 cyan3
+0 0.000 0.545 0.545 1.0 cyan4
+0 0.592 1.000 1.000 1.0 DarkSlateGray1
+0 0.553 0.933 0.933 1.0 DarkSlateGray2
+0 0.475 0.804 0.804 1.0 DarkSlateGray3
+0 0.322 0.545 0.545 1.0 DarkSlateGray4
+0 0.498 1.000 0.831 1.0 aquamarine1
+0 0.463 0.933 0.776 1.0 aquamarine2
+0 0.400 0.804 0.667 1.0 aquamarine3
+0 0.271 0.545 0.455 1.0 aquamarine4
+0 0.757 1.000 0.757 1.0 DarkSeaGreen1
+0 0.706 0.933 0.706 1.0 DarkSeaGreen2
+0 0.608 0.804 0.608 1.0 DarkSeaGreen3
+0 0.412 0.545 0.412 1.0 DarkSeaGreen4
+0 0.329 1.000 0.624 1.0 SeaGreen1
+0 0.306 0.933 0.580 1.0 SeaGreen2
+0 0.263 0.804 0.502 1.0 SeaGreen3
+0 0.180 0.545 0.341 1.0 SeaGreen4
+0 0.604 1.000 0.604 1.0 PaleGreen1
+0 0.565 0.933 0.565 1.0 PaleGreen2
+0 0.486 0.804 0.486 1.0 PaleGreen3
+0 0.329 0.545 0.329 1.0 PaleGreen4
+0 0.000 1.000 0.498 1.0 SpringGreen1
+0 0.000 0.933 0.463 1.0 SpringGreen2
+0 0.000 0.804 0.400 1.0 SpringGreen3
+0 0.000 0.545 0.271 1.0 SpringGreen4
+0 0.000 1.000 0.000 1.0 green1
+0 0.000 0.933 0.000 1.0 green2
+0 0.000 0.804 0.000 1.0 green3
+0 0.000 0.545 0.000 1.0 green4
+0 0.498 1.000 0.000 1.0 chartreuse1
+0 0.463 0.933 0.000 1.0 chartreuse2
+0 0.400 0.804 0.000 1.0 chartreuse3
+0 0.271 0.545 0.000 1.0 chartreuse4
+0 0.753 1.000 0.243 1.0 OliveDrab1
+0 0.702 0.933 0.227 1.0 OliveDrab2
+0 0.604 0.804 0.196 1.0 OliveDrab3
+0 0.412 0.545 0.133 1.0 OliveDrab4
+0 0.792 1.000 0.439 1.0 DarkOliveGreen1
+0 0.737 0.933 0.408 1.0 DarkOliveGreen2
+0 0.635 0.804 0.353 1.0 DarkOliveGreen3
+0 0.431 0.545 0.239 1.0 DarkOliveGreen4
+0 1.000 0.965 0.561 1.0 khaki1
+0 0.933 0.902 0.522 1.0 khaki2
+0 0.804 0.776 0.451 1.0 khaki3
+0 0.545 0.525 0.306 1.0 khaki4
+0 1.000 0.925 0.545 1.0 LightGoldenrod1
+0 0.933 0.863 0.510 1.0 LightGoldenrod2
+0 0.804 0.745 0.439 1.0 LightGoldenrod3
+0 0.545 0.506 0.298 1.0 LightGoldenrod4
+0 1.000 1.000 0.878 1.0 LightYellow1
+0 0.933 0.933 0.820 1.0 LightYellow2
+0 0.804 0.804 0.706 1.0 LightYellow3
+0 0.545 0.545 0.478 1.0 LightYellow4
+0 1.000 1.000 0.000 1.0 yellow1
+0 0.933 0.933 0.000 1.0 yellow2
+0 0.804 0.804 0.000 1.0 yellow3
+0 0.545 0.545 0.000 1.0 yellow4
+0 1.000 0.843 0.000 1.0 gold1
+0 0.933 0.788 0.000 1.0 gold2
+0 0.804 0.678 0.000 1.0 gold3
+0 0.545 0.459 0.000 1.0 gold4
+0 1.000 0.757 0.145 1.0 goldenrod1
+0 0.933 0.706 0.133 1.0 goldenrod2
+0 0.804 0.608 0.114 1.0 goldenrod3
+0 0.545 0.412 0.078 1.0 goldenrod4
+0 1.000 0.725 0.059 1.0 DarkGoldenrod1
+0 0.933 0.678 0.055 1.0 DarkGoldenrod2
+0 0.804 0.584 0.047 1.0 DarkGoldenrod3
+0 0.545 0.396 0.031 1.0 DarkGoldenrod4
+0 1.000 0.757 0.757 1.0 RosyBrown1
+0 0.933 0.706 0.706 1.0 RosyBrown2
+0 0.804 0.608 0.608 1.0 RosyBrown3
+0 0.545 0.412 0.412 1.0 RosyBrown4
+0 1.000 0.416 0.416 1.0 IndianRed1
+0 0.933 0.388 0.388 1.0 IndianRed2
+0 0.804 0.333 0.333 1.0 IndianRed3
+0 0.545 0.227 0.227 1.0 IndianRed4
+0 1.000 0.510 0.278 1.0 sienna1
+0 0.933 0.475 0.259 1.0 sienna2
+0 0.804 0.408 0.224 1.0 sienna3
+0 0.545 0.278 0.149 1.0 sienna4
+0 1.000 0.827 0.608 1.0 burlywood1
+0 0.933 0.773 0.569 1.0 burlywood2
+0 0.804 0.667 0.490 1.0 burlywood3
+0 0.545 0.451 0.333 1.0 burlywood4
+0 1.000 0.906 0.729 1.0 wheat1
+0 0.933 0.847 0.682 1.0 wheat2
+0 0.804 0.729 0.588 1.0 wheat3
+0 0.545 0.494 0.400 1.0 wheat4
+0 1.000 0.647 0.310 1.0 tan1
+0 0.933 0.604 0.286 1.0 tan2
+0 0.804 0.522 0.247 1.0 tan3
+0 0.545 0.353 0.169 1.0 tan4
+0 1.000 0.498 0.141 1.0 chocolate1
+0 0.933 0.463 0.129 1.0 chocolate2
+0 0.804 0.400 0.114 1.0 chocolate3
+0 0.545 0.271 0.075 1.0 chocolate4
+0 1.000 0.188 0.188 1.0 firebrick1
+0 0.933 0.173 0.173 1.0 firebrick2
+0 0.804 0.149 0.149 1.0 firebrick3
+0 0.545 0.102 0.102 1.0 firebrick4
+0 1.000 0.251 0.251 1.0 brown1
+0 0.933 0.231 0.231 1.0 brown2
+0 0.804 0.200 0.200 1.0 brown3
+0 0.545 0.137 0.137 1.0 brown4
+0 1.000 0.549 0.412 1.0 salmon1
+0 0.933 0.510 0.384 1.0 salmon2
+0 0.804 0.439 0.329 1.0 salmon3
+0 0.545 0.298 0.224 1.0 salmon4
+0 1.000 0.627 0.478 1.0 LightSalmon1
+0 0.933 0.584 0.447 1.0 LightSalmon2
+0 0.804 0.506 0.384 1.0 LightSalmon3
+0 0.545 0.341 0.259 1.0 LightSalmon4
+0 1.000 0.647 0.000 1.0 orange1
+0 0.933 0.604 0.000 1.0 orange2
+0 0.804 0.522 0.000 1.0 orange3
+0 0.545 0.353 0.000 1.0 orange4
+0 1.000 0.498 0.000 1.0 DarkOrange1
+0 0.933 0.463 0.000 1.0 DarkOrange2
+0 0.804 0.400 0.000 1.0 DarkOrange3
+0 0.545 0.271 0.000 1.0 DarkOrange4
+0 1.000 0.447 0.337 1.0 coral1
+0 0.933 0.416 0.314 1.0 coral2
+0 0.804 0.357 0.271 1.0 coral3
+0 0.545 0.243 0.184 1.0 coral4
+0 1.000 0.388 0.278 1.0 tomato1
+0 0.933 0.361 0.259 1.0 tomato2
+0 0.804 0.310 0.224 1.0 tomato3
+0 0.545 0.212 0.149 1.0 tomato4
+0 1.000 0.271 0.000 1.0 OrangeRed1
+0 0.933 0.251 0.000 1.0 OrangeRed2
+0 0.804 0.216 0.000 1.0 OrangeRed3
+0 0.545 0.145 0.000 1.0 OrangeRed4
+0 1.000 0.000 0.000 1.0 red1
+0 0.933 0.000 0.000 1.0 red2
+0 0.804 0.000 0.000 1.0 red3
+0 0.545 0.000 0.000 1.0 red4
+0 1.000 0.078 0.576 1.0 DeepPink1
+0 0.933 0.071 0.537 1.0 DeepPink2
+0 0.804 0.063 0.463 1.0 DeepPink3
+0 0.545 0.039 0.314 1.0 DeepPink4
+0 1.000 0.431 0.706 1.0 HotPink1
+0 0.933 0.416 0.655 1.0 HotPink2
+0 0.804 0.376 0.565 1.0 HotPink3
+0 0.545 0.227 0.384 1.0 HotPink4
+0 1.000 0.710 0.773 1.0 pink1
+0 0.933 0.663 0.722 1.0 pink2
+0 0.804 0.569 0.620 1.0 pink3
+0 0.545 0.388 0.424 1.0 pink4
+0 1.000 0.682 0.725 1.0 LightPink1
+0 0.933 0.635 0.678 1.0 LightPink2
+0 0.804 0.549 0.584 1.0 LightPink3
+0 0.545 0.373 0.396 1.0 LightPink4
+0 1.000 0.510 0.671 1.0 PaleVioletRed1
+0 0.933 0.475 0.624 1.0 PaleVioletRed2
+0 0.804 0.408 0.537 1.0 PaleVioletRed3
+0 0.545 0.278 0.365 1.0 PaleVioletRed4
+0 1.000 0.204 0.702 1.0 maroon1
+0 0.933 0.188 0.655 1.0 maroon2
+0 0.804 0.161 0.565 1.0 maroon3
+0 0.545 0.110 0.384 1.0 maroon4
+0 1.000 0.243 0.588 1.0 VioletRed1
+0 0.933 0.227 0.549 1.0 VioletRed2
+0 0.804 0.196 0.471 1.0 VioletRed3
+0 0.545 0.133 0.322 1.0 VioletRed4
+0 1.000 0.000 1.000 1.0 magenta1
+0 0.933 0.000 0.933 1.0 magenta2
+0 0.804 0.000 0.804 1.0 magenta3
+0 0.545 0.000 0.545 1.0 magenta4
+0 1.000 0.514 0.980 1.0 orchid1
+0 0.933 0.478 0.914 1.0 orchid2
+0 0.804 0.412 0.788 1.0 orchid3
+0 0.545 0.278 0.537 1.0 orchid4
+0 1.000 0.733 1.000 1.0 plum1
+0 0.933 0.682 0.933 1.0 plum2
+0 0.804 0.588 0.804 1.0 plum3
+0 0.545 0.400 0.545 1.0 plum4
+0 0.878 0.400 1.000 1.0 MediumOrchid1
+0 0.820 0.373 0.933 1.0 MediumOrchid2
+0 0.706 0.322 0.804 1.0 MediumOrchid3
+0 0.478 0.216 0.545 1.0 MediumOrchid4
+0 0.749 0.243 1.000 1.0 DarkOrchid1
+0 0.698 0.227 0.933 1.0 DarkOrchid2
+0 0.604 0.196 0.804 1.0 DarkOrchid3
+0 0.408 0.133 0.545 1.0 DarkOrchid4
+0 0.608 0.188 1.000 1.0 purple1
+0 0.569 0.173 0.933 1.0 purple2
+0 0.490 0.149 0.804 1.0 purple3
+0 0.333 0.102 0.545 1.0 purple4
+0 0.671 0.510 1.000 1.0 MediumPurple1
+0 0.624 0.475 0.933 1.0 MediumPurple2
+0 0.537 0.408 0.804 1.0 MediumPurple3
+0 0.365 0.278 0.545 1.0 MediumPurple4
+0 1.000 0.882 1.000 1.0 thistle1
+0 0.933 0.824 0.933 1.0 thistle2
+0 0.804 0.710 0.804 1.0 thistle3
+0 0.545 0.482 0.545 1.0 thistle4
+0 0.000 0.000 0.000 1.0 gray0
+0 0.000 0.000 0.000 1.0 grey0
+0 0.012 0.012 0.012 1.0 gray1
+0 0.012 0.012 0.012 1.0 grey1
+0 0.020 0.020 0.020 1.0 gray2
+0 0.020 0.020 0.020 1.0 grey2
+0 0.031 0.031 0.031 1.0 gray3
+0 0.031 0.031 0.031 1.0 grey3
+0 0.039 0.039 0.039 1.0 gray4
+0 0.039 0.039 0.039 1.0 grey4
+0 0.051 0.051 0.051 1.0 gray5
+0 0.051 0.051 0.051 1.0 grey5
+0 0.059 0.059 0.059 1.0 gray6
+0 0.059 0.059 0.059 1.0 grey6
+0 0.071 0.071 0.071 1.0 gray7
+0 0.071 0.071 0.071 1.0 grey7
+0 0.078 0.078 0.078 1.0 gray8
+0 0.078 0.078 0.078 1.0 grey8
+0 0.090 0.090 0.090 1.0 gray9
+0 0.090 0.090 0.090 1.0 grey9
+0 0.102 0.102 0.102 1.0 gray10
+0 0.102 0.102 0.102 1.0 grey10
+0 0.110 0.110 0.110 1.0 gray11
+0 0.110 0.110 0.110 1.0 grey11
+0 0.122 0.122 0.122 1.0 gray12
+0 0.122 0.122 0.122 1.0 grey12
+0 0.129 0.129 0.129 1.0 gray13
+0 0.129 0.129 0.129 1.0 grey13
+0 0.141 0.141 0.141 1.0 gray14
+0 0.141 0.141 0.141 1.0 grey14
+0 0.149 0.149 0.149 1.0 gray15
+0 0.149 0.149 0.149 1.0 grey15
+0 0.161 0.161 0.161 1.0 gray16
+0 0.161 0.161 0.161 1.0 grey16
+0 0.169 0.169 0.169 1.0 gray17
+0 0.169 0.169 0.169 1.0 grey17
+0 0.180 0.180 0.180 1.0 gray18
+0 0.180 0.180 0.180 1.0 grey18
+0 0.188 0.188 0.188 1.0 gray19
+0 0.188 0.188 0.188 1.0 grey19
+0 0.200 0.200 0.200 1.0 gray20
+0 0.200 0.200 0.200 1.0 grey20
+0 0.212 0.212 0.212 1.0 gray21
+0 0.212 0.212 0.212 1.0 grey21
+0 0.220 0.220 0.220 1.0 gray22
+0 0.220 0.220 0.220 1.0 grey22
+0 0.231 0.231 0.231 1.0 gray23
+0 0.231 0.231 0.231 1.0 grey23
+0 0.239 0.239 0.239 1.0 gray24
+0 0.239 0.239 0.239 1.0 grey24
+0 0.251 0.251 0.251 1.0 gray25
+0 0.251 0.251 0.251 1.0 grey25
+0 0.259 0.259 0.259 1.0 gray26
+0 0.259 0.259 0.259 1.0 grey26
+0 0.271 0.271 0.271 1.0 gray27
+0 0.271 0.271 0.271 1.0 grey27
+0 0.278 0.278 0.278 1.0 gray28
+0 0.278 0.278 0.278 1.0 grey28
+0 0.290 0.290 0.290 1.0 gray29
+0 0.290 0.290 0.290 1.0 grey29
+0 0.302 0.302 0.302 1.0 gray30
+0 0.302 0.302 0.302 1.0 grey30
+0 0.310 0.310 0.310 1.0 gray31
+0 0.310 0.310 0.310 1.0 grey31
+0 0.322 0.322 0.322 1.0 gray32
+0 0.322 0.322 0.322 1.0 grey32
+0 0.329 0.329 0.329 1.0 gray33
+0 0.329 0.329 0.329 1.0 grey33
+0 0.341 0.341 0.341 1.0 gray34
+0 0.341 0.341 0.341 1.0 grey34
+0 0.349 0.349 0.349 1.0 gray35
+0 0.349 0.349 0.349 1.0 grey35
+0 0.361 0.361 0.361 1.0 gray36
+0 0.361 0.361 0.361 1.0 grey36
+0 0.369 0.369 0.369 1.0 gray37
+0 0.369 0.369 0.369 1.0 grey37
+0 0.380 0.380 0.380 1.0 gray38
+0 0.380 0.380 0.380 1.0 grey38
+0 0.388 0.388 0.388 1.0 gray39
+0 0.388 0.388 0.388 1.0 grey39
+0 0.400 0.400 0.400 1.0 gray40
+0 0.400 0.400 0.400 1.0 grey40
+0 0.412 0.412 0.412 1.0 gray41
+0 0.412 0.412 0.412 1.0 grey41
+0 0.420 0.420 0.420 1.0 gray42
+0 0.420 0.420 0.420 1.0 grey42
+0 0.431 0.431 0.431 1.0 gray43
+0 0.431 0.431 0.431 1.0 grey43
+0 0.439 0.439 0.439 1.0 gray44
+0 0.439 0.439 0.439 1.0 grey44
+0 0.451 0.451 0.451 1.0 gray45
+0 0.451 0.451 0.451 1.0 grey45
+0 0.459 0.459 0.459 1.0 gray46
+0 0.459 0.459 0.459 1.0 grey46
+0 0.471 0.471 0.471 1.0 gray47
+0 0.471 0.471 0.471 1.0 grey47
+0 0.478 0.478 0.478 1.0 gray48
+0 0.478 0.478 0.478 1.0 grey48
+0 0.490 0.490 0.490 1.0 gray49
+0 0.490 0.490 0.490 1.0 grey49
+0 0.498 0.498 0.498 1.0 gray50
+0 0.498 0.498 0.498 1.0 grey50
+0 0.510 0.510 0.510 1.0 gray51
+0 0.510 0.510 0.510 1.0 grey51
+0 0.522 0.522 0.522 1.0 gray52
+0 0.522 0.522 0.522 1.0 grey52
+0 0.529 0.529 0.529 1.0 gray53
+0 0.529 0.529 0.529 1.0 grey53
+0 0.541 0.541 0.541 1.0 gray54
+0 0.541 0.541 0.541 1.0 grey54
+0 0.549 0.549 0.549 1.0 gray55
+0 0.549 0.549 0.549 1.0 grey55
+0 0.561 0.561 0.561 1.0 gray56
+0 0.561 0.561 0.561 1.0 grey56
+0 0.569 0.569 0.569 1.0 gray57
+0 0.569 0.569 0.569 1.0 grey57
+0 0.580 0.580 0.580 1.0 gray58
+0 0.580 0.580 0.580 1.0 grey58
+0 0.588 0.588 0.588 1.0 gray59
+0 0.588 0.588 0.588 1.0 grey59
+0 0.600 0.600 0.600 1.0 gray60
+0 0.600 0.600 0.600 1.0 grey60
+0 0.612 0.612 0.612 1.0 gray61
+0 0.612 0.612 0.612 1.0 grey61
+0 0.620 0.620 0.620 1.0 gray62
+0 0.620 0.620 0.620 1.0 grey62
+0 0.631 0.631 0.631 1.0 gray63
+0 0.631 0.631 0.631 1.0 grey63
+0 0.639 0.639 0.639 1.0 gray64
+0 0.639 0.639 0.639 1.0 grey64
+0 0.651 0.651 0.651 1.0 gray65
+0 0.651 0.651 0.651 1.0 grey65
+0 0.659 0.659 0.659 1.0 gray66
+0 0.659 0.659 0.659 1.0 grey66
+0 0.671 0.671 0.671 1.0 gray67
+0 0.671 0.671 0.671 1.0 grey67
+0 0.678 0.678 0.678 1.0 gray68
+0 0.678 0.678 0.678 1.0 grey68
+0 0.690 0.690 0.690 1.0 gray69
+0 0.690 0.690 0.690 1.0 grey69
+0 0.702 0.702 0.702 1.0 gray70
+0 0.702 0.702 0.702 1.0 grey70
+0 0.710 0.710 0.710 1.0 gray71
+0 0.710 0.710 0.710 1.0 grey71
+0 0.722 0.722 0.722 1.0 gray72
+0 0.722 0.722 0.722 1.0 grey72
+0 0.729 0.729 0.729 1.0 gray73
+0 0.729 0.729 0.729 1.0 grey73
+0 0.741 0.741 0.741 1.0 gray74
+0 0.741 0.741 0.741 1.0 grey74
+0 0.749 0.749 0.749 1.0 gray75
+0 0.749 0.749 0.749 1.0 grey75
+0 0.761 0.761 0.761 1.0 gray76
+0 0.761 0.761 0.761 1.0 grey76
+0 0.769 0.769 0.769 1.0 gray77
+0 0.769 0.769 0.769 1.0 grey77
+0 0.780 0.780 0.780 1.0 gray78
+0 0.780 0.780 0.780 1.0 grey78
+0 0.788 0.788 0.788 1.0 gray79
+0 0.788 0.788 0.788 1.0 grey79
+0 0.800 0.800 0.800 1.0 gray80
+0 0.800 0.800 0.800 1.0 grey80
+0 0.812 0.812 0.812 1.0 gray81
+0 0.812 0.812 0.812 1.0 grey81
+0 0.820 0.820 0.820 1.0 gray82
+0 0.820 0.820 0.820 1.0 grey82
+0 0.831 0.831 0.831 1.0 gray83
+0 0.831 0.831 0.831 1.0 grey83
+0 0.839 0.839 0.839 1.0 gray84
+0 0.839 0.839 0.839 1.0 grey84
+0 0.851 0.851 0.851 1.0 gray85
+0 0.851 0.851 0.851 1.0 grey85
+0 0.859 0.859 0.859 1.0 gray86
+0 0.859 0.859 0.859 1.0 grey86
+0 0.871 0.871 0.871 1.0 gray87
+0 0.871 0.871 0.871 1.0 grey87
+0 0.878 0.878 0.878 1.0 gray88
+0 0.878 0.878 0.878 1.0 grey88
+0 0.890 0.890 0.890 1.0 gray89
+0 0.890 0.890 0.890 1.0 grey89
+0 0.898 0.898 0.898 1.0 gray90
+0 0.898 0.898 0.898 1.0 grey90
+0 0.910 0.910 0.910 1.0 gray91
+0 0.910 0.910 0.910 1.0 grey91
+0 0.922 0.922 0.922 1.0 gray92
+0 0.922 0.922 0.922 1.0 grey92
+0 0.929 0.929 0.929 1.0 gray93
+0 0.929 0.929 0.929 1.0 grey93
+0 0.941 0.941 0.941 1.0 gray94
+0 0.941 0.941 0.941 1.0 grey94
+0 0.949 0.949 0.949 1.0 gray95
+0 0.949 0.949 0.949 1.0 grey95
+0 0.961 0.961 0.961 1.0 gray96
+0 0.961 0.961 0.961 1.0 grey96
+0 0.969 0.969 0.969 1.0 gray97
+0 0.969 0.969 0.969 1.0 grey97
+0 0.980 0.980 0.980 1.0 gray98
+0 0.980 0.980 0.980 1.0 grey98
+0 0.988 0.988 0.988 1.0 gray99
+0 0.988 0.988 0.988 1.0 grey99
+0 1.000 1.000 1.000 1.0 gray100
+0 1.000 1.000 1.000 1.0 grey100
+0 0.663 0.663 0.663 1.0 dark grey
+0 0.663 0.663 0.663 1.0 DarkGrey
+0 0.663 0.663 0.663 1.0 dark gray
+0 0.663 0.663 0.663 1.0 DarkGray
+0 0.000 0.000 0.545 1.0 dark blue
+0 0.000 0.000 0.545 1.0 DarkBlue
+0 0.000 0.545 0.545 1.0 dark cyan
+0 0.000 0.545 0.545 1.0 DarkCyan
+0 0.545 0.000 0.545 1.0 dark magenta
+0 0.545 0.000 0.545 1.0 DarkMagenta
+0 0.545 0.000 0.000 1.0 dark red
+0 0.545 0.000 0.000 1.0 DarkRed
+0 0.565 0.933 0.565 1.0 light green
+0 0.565 0.933 0.565 1.0 LightGreen
+0 0.500 0.500 0.500 1.0 Gray
+0 0.500 0.500 0.500 1.0 Grey
+0 0.667 0.667 0.667 1.0 Light Gray
+0 0.667 0.667 0.667 1.0 Light Grey
+0 0.000 0.000 0.000 0.0 Highlight
--- a/lib-src/.cvsignore	Tue Jul 15 15:45:05 2008 +0000
+++ b/lib-src/.cvsignore	Tue Jul 15 18:15:18 2008 +0000
@@ -11,6 +11,7 @@
 fakemail
 getopt.h
 hexl
+mac-fix-env
 make-docfile
 movemail
 obj
--- a/lib-src/ChangeLog	Tue Jul 15 15:45:05 2008 +0000
+++ b/lib-src/ChangeLog	Tue Jul 15 18:15:18 2008 +0000
@@ -1,3 +1,13 @@
+2008-07-15  Adrian Robert <Adrian.B.Robert@gmail.com>
+
+	* .cvsignore: Add mac-fix-env.
+	* mac-fix-env.m: New file, automatically update
+	~/.MacOSX/environment.plist on OS X systems to expose environment
+	variables inside Emacs started from icon.
+	* Makefile.in: Add -universal to CFLAGS on OS X, add mac-fix-env to
+	programs to build.
+	* make-docfile.c: Add .m to list of file extensions.
+
 2008-07-12  Dan Nicolaescu  <dann@ics.uci.edu>
 
 	* movemail.c (main): Use int instead of WAITTYPE.
--- a/lib-src/Makefile.in	Tue Jul 15 15:45:05 2008 +0000
+++ b/lib-src/Makefile.in	Tue Jul 15 18:15:18 2008 +0000
@@ -144,6 +144,23 @@
 #define NOT_C_CODE
 #include "../src/config.h"
 
+#if defined(COCOA)
+/* Build these programs as universal binaries. */
+CFLAGS := $(CFLAGS) -universal
+/* Add mac-fix-env for OS X systems running NS version. */
+INSTALLABLES = etags${EXEEXT} ctags${EXEEXT} emacsclient${EXEEXT} b2m${EXEEXT} ebrowse${EXEEXT} mac-fix-env${EXEEXT}
+#endif
+
+/* Some platforms that the GNUstep port runs on put strip options in
+   INSTALL_PROGRAM which cause errors.  But, not being sure all other
+   platforms are setting this, we will only use the alternative
+   INSTALL_SCRIPT variable on GNUstep/Cocoa builds. */
+#ifndef HAVE_NS
+INSTALL_SCRIPT = @INSTALL_PROGRAM@
+#else
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+#endif
+
 /* Some machines don\'t find the standard C libraries in the usual place.  */
 #ifndef ORDINARY_LINK
 #ifndef LIB_STANDARD_LIBSRC
@@ -253,12 +270,22 @@
 BASE_CFLAGS = C_SWITCH_SYSTEM C_SWITCH_MACHINE -DHAVE_CONFIG_H \
    -I. -I../src -I${srcdir} -I${srcdir}/../src ${CPPFLAGS} ${CFLAGS}
 
+.SUFFIXES: .m
+
 /* This is the default compilation command.
    But we should never rely on it, because some make version
    failed to find it for getopt.o.
    Using an explicit command made it work.  */
 .c.o:
 	${CC} -c ${CPP_CFLAGS} $<
+#ifdef HAVE_NS
+.m.o:
+#ifdef GNUSTEP
+	$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -fgnu-runtime -Wno-import -fconstant-string-class=NSConstantString $<
+#else
+	$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
+#endif
+#endif
 
 all: ${DONT_INSTALL} ${UTILITIES} ${INSTALLABLES} ${SCRIPTS} ${INSTALLABLE_SCRIPTS}
 
@@ -455,3 +482,8 @@
 update-game-score.o: ${srcdir}/update-game-score.c ../src/config.h $(GETOPT_H)
 	$(CC) -c ${CPP_CFLAGS} ${srcdir}/update-game-score.c \
 	  -DHAVE_SHARED_GAME_DIR="\"$(gamedir)\""
+
+#if defined(COCOA)
+mac-fix-env: ${srcdir}/mac-fix-env.m
+	$(CC) -o mac-fix-env ${srcdir}/mac-fix-env.m -prebind -framework Foundation
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib-src/mac-fix-env.m	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,71 @@
+/* mac-fix-env: A small utility to pick up the shell environment on MacOS X
+                and insert it into the file ~/.MacOSX/environment.plist
+                creating if necessary.
+   Copyright (C) 1989, 1993, 2005, 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.
+
+ usage:
+        Run from command line (in Terminal) once or whenever path changes:
+
+ /Applications/Emacs.app/Contents/MacOS/bin/mac-fix-env
+
+ (change initial part to where you installed Emacs).
+*/
+
+#import <Foundation/Foundation.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSMutableDictionary *envPlist;
+    NSString *file = [[NSHomeDirectory()
+                         stringByAppendingPathComponent:@".MacOSX"]
+                         stringByAppendingPathComponent:@"environment.plist"];
+    NSString *path = [NSString stringWithCString: getenv("PATH")];
+
+    envPlist = [[NSDictionary dictionaryWithContentsOfFile: file] mutableCopy];
+    if (envPlist == nil)
+      {
+        // create
+        NSString *dir = [file stringByDeletingLastPathComponent];
+        envPlist = [NSMutableDictionary dictionaryWithCapacity: 5];
+
+        if ([[NSFileManager defaultManager] fileExistsAtPath: dir] == NO)
+          {
+            if ([[NSFileManager defaultManager] createDirectoryAtPath:dir
+                                                           attributes:nil]==NO)
+              {
+                NSLog(@":\nCould not create directory at '%@'; aborting.",dir);
+                return 1;
+              }
+          }
+      }
+
+    [envPlist setObject: path forKey: @"PATH"];
+
+    if ([envPlist writeToFile: file atomically: YES] == NO)
+      {
+        NSLog(@":\nCould not write file at '%@'; aborting.", file);
+        return 1;
+      }
+
+    NSLog(@":\nWrote file to '%@'.\nPlease inspect it to make sure PATH is correct.", file);
+    return 0;
+}
--- a/lib-src/make-docfile.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/lib-src/make-docfile.c	Tue Jul 15 18:15:18 2008 +0000
@@ -533,7 +533,7 @@
 }
 
 /* Read through a c file.  If a .o file is named,
-   the corresponding .c file is read instead.
+   the corresponding .c or .m file is read instead.
    Looks for DEFUN constructs such as are defined in ../src/lisp.h.
    Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED.  */
 
@@ -555,6 +555,15 @@
 
   infile = fopen (filename, mode);
 
+  if (infile == NULL && extension == 'o')
+    {
+      /* try .m */
+      filename[strlen (filename) - 1] = 'm';
+      infile = fopen (filename, mode);
+      if (infile == NULL)
+        filename[strlen (filename) - 1] = 'c'; /* don't confuse people */
+    }
+
   /* No error if non-ex input file */
   if (infile == NULL)
     {
--- a/lisp/ChangeLog	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/ChangeLog	Tue Jul 15 18:15:18 2008 +0000
@@ -1,3 +1,42 @@
+2008-07-15  Adrian Robert <Adrian.B.Robert@gmail.com>
+	* ns-carbon-compat.el: New file: user-visible compatibility of
+	NeXTstep port with Carbon port.
+	* ns-grabenv.el: New file: functionality useful on OS X platform to
+	expose environment variables inside Emacs started from icon.
+	* Makefile.in: Add above three files.
+	* cus-edit.el
+	* cus-face.el
+	* disp-table.el
+	* faces.el
+	* info.el
+	* mouse.el
+	* mwheel.el
+	* simple.el: Add ns to window systems treated as GUIs.
+	* facemenu.el (facemenu-read-color): Don't require a name match under
+	NS, to allow numeric color entry.
+	* frame.el (make-frame-on-display): Follow code for 'x in initializing
+	'ns window system if need be.
+	(various): Add 'ns as described above.
+	* loadup.el: Load ns-win.el if ns-windowing is active.
+	* startup.el (command-line-ns-option-alist): New constant to handle NS
+	windowing system specific command line args analogous to how they are
+	handled for X windows.
+	(command-line-1): Use the above where appropriate.
+	* version.el: Add NS port version.
+	* woman.el (woman-man.conf-path): Add /usr/share/misc to init path on
+	Darwin (usually OS X) systems.
+	(woman-use-own-frame): Include 'ns in list of GUI window systems.
+	* emulation/viper-util.el (ns-display-color-p)
+	(ns-color-defined-p): Remove these (caustically-commented) outdated
+	compensations for a port that was never itself integrated until now.
+	* gnus/gnus-util.el (gnus-select-frame-set-input-focus): Add support
+	for NS window system.
+	* international/mule-cmds.el: Add 'ns to list of special-cased window
+	systems (probably most of these, x/w32/mac/ns could be changed to
+	window-system non-nil).
+	* term/ns-win.el: New file: lisp-side support for NS windowing system.
+
+
 2008-07-14  Jason Rumney  <jasonr@gnu.org>
 
         * term/w32-win.el (x-handle-switch, x-handle-name-switch)
--- a/lisp/Makefile.in	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/Makefile.in	Tue Jul 15 18:15:18 2008 +0000
@@ -867,6 +867,8 @@
 	$(lisp)/net/zeroconf.elc \
 	$(lisp)/newcomment.elc \
 	$(lisp)/novice.elc \
+	$(lisp)/ns-grabenv.elc \
+	$(lisp)/ns-carbon-compat.elc \
 	$(lisp)/nxml/nxml-enc.elc \
 	$(lisp)/nxml/nxml-glyph.elc \
 	$(lisp)/nxml/nxml-maint.elc \
@@ -1110,6 +1112,7 @@
 	$(lisp)/tempo.elc \
 	$(lisp)/term.elc \
 	$(lisp)/term/mac-win.elc \
+	$(lisp)/term/ns-win.elc \
 	$(lisp)/term/pc-win.elc \
 	$(lisp)/term/rxvt.elc \
 	$(lisp)/term/sun.elc \
--- a/lisp/cus-edit.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/cus-edit.el	Tue Jul 15 18:15:18 2008 +0000
@@ -2068,7 +2068,7 @@
 ;;; The `custom' Widget.
 
 (defface custom-button
-  '((((type x w32 mac) (class color))		; Like default modeline
+  '((((type x w32 mac ns) (class color))	; Like default modeline
      (:box (:line-width 2 :style released-button)
 	   :background "lightgrey" :foreground "black"))
     (t
@@ -2080,7 +2080,7 @@
 (put 'custom-button-face 'face-alias 'custom-button)
 
 (defface custom-button-mouse
-  '((((type x w32 mac) (class color))
+  '((((type x w32 mac ns) (class color))
      (:box (:line-width 2 :style released-button)
 	   :background "grey90" :foreground "black"))
     (t
@@ -2102,7 +2102,7 @@
       (if custom-raised-buttons 'custom-button-mouse 'highlight))
 
 (defface custom-button-pressed
-  '((((type x w32 mac) (class color))
+  '((((type x w32 mac ns) (class color))
      (:box (:line-width 2 :style pressed-button)
 	   :background "lightgrey" :foreground "black"))
     (t
@@ -3163,8 +3163,12 @@
 					   w32)
 				    (const :format "MAC "
 					   :sibling-args (:help-echo "\
-Macintosh OS.")
+Macintosh OS (Carbon interface).")
 					   mac)
+				    (const :format "NS "
+					   :sibling-args (:help-echo "\
+GNUstep or Macintosh OS Cocoa interface.")
+					   ns)
 				    (const :format "DOS "
 					   :sibling-args (:help-echo "\
 Plain MS-DOS.")
--- a/lisp/cus-face.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/cus-face.el	Tue Jul 15 18:15:18 2008 +0000
@@ -44,7 +44,7 @@
 	  ;; Create frame-local faces
 	  (dolist (frame (frame-list))
 	    (face-spec-set-2 face frame value)
-	    (when (memq (window-system frame) '(x w32 mac))
+	    (when (memq (window-system frame) '(x w32 mac ns))
 	      (setq have-window-system t)))
 	  ;; When making a face after frames already exist
 	  (if have-window-system
--- a/lisp/disp-table.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/disp-table.el	Tue Jul 15 18:15:18 2008 +0000
@@ -142,7 +142,7 @@
   "Display character C as character SC in the g1 character set.
 This function assumes that your terminal uses the SO/SI characters;
 it is meaningless for an X frame."
-  (if (memq window-system '(x w32 mac))
+  (if (memq window-system '(x w32 mac ns))
       (error "Cannot use string glyphs in a windowing system"))
   (or standard-display-table
       (setq standard-display-table (make-display-table)))
@@ -154,7 +154,7 @@
   "Display character C as character GC in graphics character set.
 This function assumes VT100-compatible escapes; it is meaningless for an
 X frame."
-  (if (memq window-system '(x w32 mac))
+  (if (memq window-system '(x w32 mac ns))
       (error "Cannot use string glyphs in a windowing system"))
   (or standard-display-table
       (setq standard-display-table (make-display-table)))
@@ -243,7 +243,7 @@
 	       (equal (aref standard-display-table 161) [161])))
       (progn
 	(standard-display-default 160 255)
-	(unless (or (memq window-system '(x w32 mac)))
+	(unless (or (memq window-system '(x w32 mac ns)))
 	  (and (terminal-coding-system)
 	       (set-terminal-coding-system nil))))
 
@@ -255,7 +255,7 @@
     ;; unless some other has been specified.
     (if (equal current-language-environment "English")
 	(set-language-environment "latin-1"))
-    (unless (or noninteractive (memq window-system '(x w32 mac)))
+    (unless (or noninteractive (memq window-system '(x w32 mac ns)))
       ;; Send those codes literally to a character-based terminal.
       ;; If we are using single-byte characters,
       ;; it doesn't matter which coding system we use.
--- a/lisp/emulation/viper-util.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/emulation/viper-util.el	Tue Jul 15 18:15:18 2008 +0000
@@ -52,14 +52,6 @@
 (require 'viper-init)
 
 
-;; A fix for NeXT Step
-;; Should go away, when NS people fix the design flaw, which leaves the
-;; two x-* functions undefined.
-(if (and (not (fboundp 'x-display-color-p)) (fboundp 'ns-display-color-p))
-    (fset 'x-display-color-p (symbol-function 'ns-display-color-p)))
-(if (and (not (fboundp 'x-color-defined-p)) (fboundp 'ns-color-defined-p))
-      (fset 'x-color-defined-p (symbol-function 'ns-color-defined-p)))
-
 
 (defalias 'viper-overlay-p
   (if (featurep 'xemacs) 'extentp 'overlayp))
--- a/lisp/facemenu.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/facemenu.el	Tue Jul 15 18:15:18 2008 +0000
@@ -460,10 +460,11 @@
 (defun facemenu-read-color (&optional prompt)
   "Read a color using the minibuffer."
   (let* ((completion-ignore-case t)
+	 (require-match (not (eq window-system 'ns)))
 	 (col (completing-read (or prompt "Color: ")
 			       (or facemenu-color-alist
 				   (defined-colors))
-			       nil t)))
+			       nil require-match)))
     (if (equal "" col)
 	nil
       col)))
--- a/lisp/faces.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/faces.el	Tue Jul 15 18:15:18 2008 +0000
@@ -338,7 +338,7 @@
 
 (defun set-face-attributes-from-resources (face frame)
   "Set attributes of FACE from X resources for FRAME."
-  (when (memq (framep frame) '(x w32 mac))
+  (when (memq (framep frame) '(x w32 mac ns))
     (dolist (definition face-x-resources)
       (let ((attribute (car definition)))
 	(dolist (entry (cdr definition))
@@ -1010,7 +1010,7 @@
            ((:height)
             'integerp)
            (:stipple
-            (and (memq (window-system frame) '(x w32 mac))
+            (and (memq (window-system frame) '(x w32 mac ns))
                  (mapcar #'list
                          (apply #'nconc
                                 (mapcar (lambda (dir)
@@ -1129,7 +1129,7 @@
 	       ;; explicitly in VALID, using color approximation code
 	       ;; in tty-colors.el.
 	       (when (and (memq attribute '(:foreground :background))
-			  (not (memq (window-system frame) '(x w32 mac)))
+			  (not (memq (window-system frame) '(x w32 mac ns)))
 			  (not (member new-value
 				       '("unspecified"
 					 "unspecified-fg" "unspecified-bg"))))
@@ -1624,7 +1624,7 @@
 The value may be different for frames on different display types.
 If FRAME doesn't support colors, the value is nil.
 If FRAME is nil, that stands for the selected frame."
-  (if (memq (framep (or frame (selected-frame))) '(x w32 mac))
+  (if (memq (framep (or frame (selected-frame))) '(x w32 mac ns))
       (xw-defined-colors frame)
     (mapcar 'car (tty-color-alist frame))))
 (defalias 'x-defined-colors 'defined-colors)
@@ -1638,7 +1638,7 @@
 \"unspecified-fg\" or \"unspecified-bg\", the value is nil."
   (if (member color '(unspecified "unspecified-bg" "unspecified-fg"))
       nil
-    (if (member (framep (or frame (selected-frame))) '(x w32 mac))
+    (if (member (framep (or frame (selected-frame))) '(x w32 mac ns))
 	(xw-color-defined-p color frame)
       (numberp (tty-color-translate color frame)))))
 (defalias 'x-color-defined-p 'color-defined-p)
@@ -1656,7 +1656,7 @@
 \"unspecified-fg\" or \"unspecified-bg\", the value is nil."
   (if (member color '(unspecified "unspecified-fg" "unspecified-bg"))
       nil
-    (if (memq (framep (or frame (selected-frame))) '(x w32 mac))
+    (if (memq (framep (or frame (selected-frame))) '(x w32 mac ns))
 	(xw-color-values color frame)
       (tty-color-values color frame))))
 (defalias 'x-color-values 'color-values)
@@ -1668,7 +1668,7 @@
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display."
-  (if (memq (framep-on-display display) '(x w32 mac))
+  (if (memq (framep-on-display display) '(x w32 mac ns))
       (xw-display-color-p display)
     (tty-display-color-p display)))
 (defalias 'x-display-color-p 'display-color-p)
@@ -1679,7 +1679,7 @@
   "Return non-nil if frames on DISPLAY can display shades of gray."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 mac ns))
       (x-display-grayscale-p display))
      (t
       (> (tty-color-gray-shades display) 2)))))
@@ -2495,7 +2495,7 @@
   '((default
      :box (:line-width 1 :style released-button)
      :foreground "black")
-    (((type x w32 mac) (class color))
+    (((type x w32 mac ns) (class color))
      :background "grey75")
     (((type x) (class mono))
      :background "grey"))
--- a/lisp/frame.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/frame.el	Tue Jul 15 18:15:18 2008 +0000
@@ -610,12 +610,19 @@
   "Make a frame on X display DISPLAY.
 The optional second argument PARAMETERS specifies additional frame parameters."
   (interactive "sMake frame on display: ")
-  (or (string-match "\\`[^:]*:[0-9]+\\(\\.[0-9]+\\)?\\'" display)
-      (error "Invalid display, not HOST:SERVER or HOST:SERVER.SCREEN"))
-  (when (and (boundp 'x-initialized) (not x-initialized))
-    (setq x-display-name display)
-    (x-initialize-window-system))
-  (make-frame `((window-system . x) (display . ,display) . ,parameters)))
+  (if (featurep 'ns-windowing)
+      (progn
+	(when (and (boundp 'ns-initialized) (not ns-initialized))
+	  (setq ns-display-name display)
+	  (ns-initialize-window-system))
+	(make-frame `((window-system . ns) (display . ,display) . ,parameters)))
+    (progn
+      (or (string-match "\\`[^:]*:[0-9]+\\(\\.[0-9]+\\)?\\'" display)
+	  (error "Invalid display, not HOST:SERVER or HOST:SERVER.SCREEN"))
+      (when (and (boundp 'x-initialized) (not x-initialized))
+	(setq x-display-name display)
+	(x-initialize-window-system))
+      (make-frame `((window-system . x) (display . ,display) . ,parameters)))))
 
 (defun make-frame-on-tty (tty type &optional parameters)
   "Make a frame on terminal device TTY.
@@ -835,7 +842,7 @@
     (select-frame frame)
     (raise-frame frame)
     ;; Ensure, if possible, that frame gets input focus.
-    (when (memq (window-system frame) '(x mac w32))
+    (when (memq (window-system frame) '(x mac w32 ns))
       (x-focus-frame frame))
     (when focus-follows-mouse
       (set-mouse-position (selected-frame) (1- (frame-width)) 0)))
@@ -880,7 +887,7 @@
   (interactive)
   (let ((type (framep (selected-frame))))
     (cond
-     ((memq type '(x w32)) (iconify-or-deiconify-frame))
+     ((memq type '(x ns w32)) (iconify-or-deiconify-frame))
      ((eq type t)
       (if (controlling-tty-p)
 	  (suspend-emacs)
@@ -920,7 +927,7 @@
     (raise-frame frame)
     (select-frame frame)
     ;; Ensure, if possible, that frame gets input focus.
-    (cond ((memq (window-system frame) '(x w32))
+    (cond ((memq (window-system frame) '(x w32 ns))
 	   (x-focus-frame frame)))
     (when focus-follows-mouse
       (set-mouse-position frame (1- (frame-width frame)) 0))))
@@ -1157,8 +1164,8 @@
      ((eq system-type 'windows-nt)
       (with-no-warnings
        (> w32-num-mouse-buttons 0)))
-     ((memq frame-type '(x mac))
-      t)    ;; We assume X and Mac *always* have a pointing device
+     ((memq frame-type '(x mac ns))
+      t)    ;; We assume X, Mac, NeXTstep *always* have a pointing device
      (t
       (or (and (featurep 'xt-mouse)
 	       xterm-mouse-mode)
@@ -1173,7 +1180,7 @@
 Support for popup menus requires that the mouse be available."
   (and
    (let ((frame-type (framep-on-display display)))
-     (memq frame-type '(x w32 pc mac)))
+     (memq frame-type '(x w32 pc mac ns)))
    (display-mouse-p display)))
 
 (defun display-graphic-p (&optional display)
@@ -1183,7 +1190,7 @@
 that use a window system such as X, and false for text-only terminals.
 DISPLAY can be a display name, a frame, or nil (meaning the selected
 frame's display)."
-  (not (null (memq (framep-on-display display) '(x w32 mac)))))
+  (not (null (memq (framep-on-display display) '(x w32 mac ns)))))
 
 (defun display-images-p (&optional display)
   "Return non-nil if DISPLAY can display images.
@@ -1211,7 +1218,7 @@
       ;; the Windows' DOS Box.
       (with-no-warnings
        (not (null dos-windows-version))))
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 mac ns))
       t)    ;; FIXME?
      (t
       nil))))
@@ -1222,7 +1229,7 @@
   "Return the number of screens associated with DISPLAY."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 mac ns))
       (x-display-screens display))
      (t
       1))))
@@ -1234,7 +1241,7 @@
 For character terminals, each character counts as a single pixel."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 mac ns))
       (x-display-pixel-height display))
      (t
       (frame-height (if (framep display) display (selected-frame)))))))
@@ -1246,7 +1253,7 @@
 For character terminals, each character counts as a single pixel."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 mac ns))
       (x-display-pixel-width display))
      (t
       (frame-width (if (framep display) display (selected-frame)))))))
@@ -1275,7 +1282,7 @@
   "Return the height of DISPLAY's screen in millimeters.
 System values can be overridden by `display-mm-dimensions-alist'.
 If the information is unavailable, value is nil."
-  (and (memq (framep-on-display display) '(x w32 mac))
+  (and (memq (framep-on-display display) '(x w32 mac ns))
        (or (cddr (assoc (or display (frame-parameter nil 'display))
 			display-mm-dimensions-alist))
 	   (cddr (assoc t display-mm-dimensions-alist))
@@ -1287,7 +1294,7 @@
   "Return the width of DISPLAY's screen in millimeters.
 System values can be overridden by `display-mm-dimensions-alist'.
 If the information is unavailable, value is nil."
-  (and (memq (framep-on-display display) '(x w32 mac))
+  (and (memq (framep-on-display display) '(x w32 mac ns))
        (or (cadr (assoc (or display (frame-parameter nil 'display))
 			display-mm-dimensions-alist))
 	   (cadr (assoc t display-mm-dimensions-alist))
@@ -1301,7 +1308,7 @@
 the question is inapplicable to a certain kind of display."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 mac ns))
       (x-display-backing-store display))
      (t
       'not-useful))))
@@ -1312,7 +1319,7 @@
   "Return non-nil if DISPLAY's screen supports the SaveUnder feature."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 mac ns))
       (x-display-save-under display))
      (t
       'not-useful))))
@@ -1323,7 +1330,7 @@
   "Return the number of planes supported by DISPLAY."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 mac ns))
       (x-display-planes display))
      ((eq frame-type 'pc)
       4)
@@ -1336,7 +1343,7 @@
   "Return the number of color cells supported by DISPLAY."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 mac ns))
       (x-display-color-cells display))
      ((eq frame-type 'pc)
       16)
@@ -1351,7 +1358,7 @@
 `static-color', `pseudo-color', `true-color', or `direct-color'."
   (let ((frame-type (framep-on-display display)))
     (cond
-     ((memq frame-type '(x w32 mac))
+     ((memq frame-type '(x w32 mac ns))
       (x-display-visual-class display))
      ((and (memq frame-type '(pc t))
 	   (tty-display-color-p display))
--- a/lisp/gnus/gnus-util.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/gnus/gnus-util.el	Tue Jul 15 18:15:18 2008 +0000
@@ -1612,7 +1612,9 @@
 	 (cond ((memq window-system '(x mac))
 		(x-focus-frame frame))
 	       ((eq window-system 'w32)
-		(w32-focus-frame frame)))
+		(w32-focus-frame frame))
+	       ((eq window-system 'ns)
+		(ns-focus-frame frame)))
 	 (when focus-follows-mouse
 	   (set-mouse-position frame (1- (frame-width frame)) 0)))))
 
--- a/lisp/info.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/info.el	Tue Jul 15 18:15:18 2008 +0000
@@ -3893,7 +3893,7 @@
           ;; This is a serious problem for trying to handle multiple
           ;; frame types at once.  We want this text to be invisible
           ;; on frames that can display the font above.
-          (when (memq (framep (selected-frame)) '(x pc w32 mac))
+          (when (memq (framep (selected-frame)) '(x pc w32 mac ns))
             (add-text-properties (1- (match-beginning 2)) (match-end 2)
                                  '(invisible t front-sticky nil rear-nonsticky t)))))
 
--- a/lisp/international/mule-cmds.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/international/mule-cmds.el	Tue Jul 15 18:15:18 2008 +0000
@@ -148,7 +148,7 @@
   t)
 (define-key-after set-coding-system-map [set-terminal-coding-system]
   '(menu-item "For Terminal" set-terminal-coding-system
-	      :enable (null (memq initial-window-system '(x w32 mac)))
+	      :enable (null (memq initial-window-system '(x w32 mac ns)))
 	      :help "How to encode terminal output")
   t)
 (define-key-after set-coding-system-map [separator-3]
--- a/lisp/loadup.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/loadup.el	Tue Jul 15 18:15:18 2008 +0000
@@ -212,6 +212,11 @@
 (if (featurep 'mac-carbon)
     (progn
       (load "term/mac-win")))
+(if (featurep 'ns-windowing)
+    (progn
+      (load "emacs-lisp/easymenu")  ;; for platform-related menu adjustments
+      (load "emacs-lisp/easy-mmode")
+      (load "term/ns-win")))
 (if (fboundp 'atan)	; preload some constants and
     (progn		; floating pt. functions if we have float support.
       (load "emacs-lisp/float-sup")))
--- a/lisp/mouse.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/mouse.el	Tue Jul 15 18:15:18 2008 +0000
@@ -673,7 +673,7 @@
     ;; If mark is highlighted, no need to bounce the cursor.
     ;; On X, we highlight while dragging, thus once again no need to bounce.
     (or transient-mark-mode
-	(memq (framep (selected-frame)) '(x pc w32 mac))
+	(memq (framep (selected-frame)) '(x pc w32 mac ns))
 	(sit-for 1))
     (push-mark)
     (set-mark (point))
--- a/lisp/mwheel.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/mwheel.el	Tue Jul 15 18:15:18 2008 +0000
@@ -58,7 +58,7 @@
 			"22.1")
 (defcustom mouse-wheel-down-event
   ;; In the latest versions of XEmacs, we could just use mouse-%s as well.
-  (if (memq window-system '(w32 mac))
+  (if (memq window-system '(w32 mac ns))
       'wheel-up
     (intern (format (if (featurep 'xemacs) "button%s" "mouse-%s")
 		    mouse-wheel-down-button)))
@@ -73,7 +73,7 @@
 			"22.1")
 (defcustom mouse-wheel-up-event
   ;; In the latest versions of XEmacs, we could just use mouse-%s as well.
-  (if (memq window-system '(w32 mac))
+  (if (memq window-system '(w32 mac ns))
       'wheel-down
     (intern (format (if (featurep 'xemacs) "button%s" "mouse-%s")
 		    mouse-wheel-up-button)))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/ns-carbon-compat.el	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,37 @@
+;;; ns-carbon-compat.el ---
+;;;     Carbon compatibility layer for Mac users of NS (Cocoa) GUI.
+;;; Copyright (C) 2008 Free Software Foundation, Inc.
+
+;;; Author: Adrian Robert
+;;; Keywords: Carbon, MacOSX
+
+;;; 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 2, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;; ns-carbon-compat.el:  this file is loaded from termp/ns-win.el when
+;; run on a Mac OS X system.  It sets up a number of aliases and other
+;; layers to enable human and machine users (Mac distributions of GNU Emacs)
+;; to pretend they are using the Choi/Mitsuharu Carbon port.
+
+;;; Code:
+
+(defvaralias 'mac-allow-anti-aliasing 'ns-antialias-text)
+(defvaralias 'mac-command-modifier 'ns-command-modifier)
+(defvaralias 'mac-control-modifier 'ns-control-modifier)
+(defvaralias 'mac-option-modifier 'ns-option-modifier)
+(defvaralias 'mac-function-modifier 'ns-function-modifier)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/ns-grabenv.el	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,67 @@
+;;; ns-grabenv.el --- functions to set environment variables by running a subshell
+;;; Copyright (C) 1993, 1994, 2005, 2006, 2008 Free Software Foundation, Inc.
+
+;;; Author: Carl Edman, Christian Limpach, Scott Bender, Christophe de Dinechin,
+;;;         Adrian Robert
+;;; Keywords: terminals
+
+;;; 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.
+
+;;; Idea based on NS 4.2 distribution, this version of code based on
+;;; mac-read-environment-vars-from-shell () by David Reitter in Aquamacs dist..
+
+
+;; utility function
+(defun ns-make-command-string (cmdlist)
+  (let ((str "")
+	(cmds cmdlist))
+    (while cmds
+      (if (not (eq str "")) (setq str (format "%s ; " str)))
+      (setq str (format "%s%s" str (car cmds)))
+      (setq cmds (cdr cmds)))
+    str))
+
+
+;;;###autoload
+(defun ns-grabenv (&optional shell-path &optional startup)
+  "Run a shell subprocess, and interpret its output as a series of environment\n\
+variables to insert into the emacs environment.  The first optional argument\n\
+gives the path to the shell (defaults to the current setting of\n\
+shell-file-name).  The remaining arguments are interpreted as a list of\n\
+commands for it to execute (defaults to \"printenv\")."
+  (interactive)
+  (with-temp-buffer
+    (let ((shell-file-name (if shell-path shell-path shell-file-name))
+	  (cmd (ns-make-command-string (if startup startup '("printenv")))))
+      (shell-command cmd t)
+      (while (search-forward-regexp "^\\([A-Za-z_0-9]+\\)=\\(.*\\)$" nil t)
+	(setenv (match-string 1)
+		(if (equal (match-string 1) "PATH")
+		    (concat (getenv "PATH") ":" (match-string 2))
+		  (match-string 2)))))))
+
+(provide 'ns-grabenv)
+
+;;; ns-grabenv.el ends here
+
+; (autoload (quote ns-grabenv) "ns-grabenv" "\
+;  Run a shell subprocess, and interpret its output as a series of environment
+; variables to insert into the emacs environment.  The first optional argument
+; gives the path to the shell (defaults to the current setting of
+; shell-file-name).  The remaining arguments are interpreted as a list of
+; commands for it to execute (defaults to \"printenv\")." nil nil)
--- a/lisp/simple.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/simple.el	Tue Jul 15 18:15:18 2008 +0000
@@ -5984,7 +5984,7 @@
     (set-terminal-parameter nil 'normal-erase-is-backspace
 			    (if enabled 1 0))
 
-    (cond ((or (memq window-system '(x w32 mac pc))
+    (cond ((or (memq window-system '(x w32 mac ns pc))
 	       (memq system-type '(ms-dos windows-nt)))
 	   (let* ((bindings
 		   `(([C-delete] [C-backspace])
--- a/lisp/startup.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/startup.el	Tue Jul 15 18:15:18 2008 +0000
@@ -182,6 +182,72 @@
 and VALUE is the value which is given to that frame parameter
 \(most options use the argument for this, so VALUE is not present).")
 
+(defconst command-line-ns-option-alist
+  '(("-NSAutoLaunch" 1 ns-ignore-1-arg)
+    ("-NXAutoLaunch" 1 ns-ignore-1-arg)
+    ("-macosx" 0 ns-ignore-0-arg)
+    ("-NSHost" 1 ns-ignore-1-arg)
+    ("-_NSMachLaunch" 1 ns-ignore-1-arg)
+    ("-MachLaunch" 1 ns-ignore-1-arg)
+    ("-NXOpen" 1 ns-ignore-1-arg)
+    ("-NSOpen" 1 ns-handle-nxopen)
+    ("-NXOpenTemp" 1 ns-ignore-1-arg)
+    ("-NSOpenTemp" 1 ns-handle-nxopentemp)
+    ("-GSFilePath" 1 ns-handle-nxopen)
+    ;;("-bw" .              x-handle-numeric-switch)
+    ;;("-d" .               x-handle-display)
+    ;;("-display" .         x-handle-display)
+    ("-name" 1 ns-handle-name-switch)
+    ("-title" 1 ns-handle-switch title)
+    ("-T" 1 ns-handle-switch title)
+    ("-r" 0 ns-handle-switch reverse t)
+    ("-rv" 0 ns-handle-switch reverse t)
+    ("-reverse" 0 ns-handle-switch reverse t)
+    ("-fn" 1 ns-handle-switch font)
+    ("-font" 1 ns-handle-switch font)
+    ("-ib" 1 ns-handle-numeric-switch internal-border-width)
+    ;;("-g" .               x-handle-geometry)
+    ;;("-geometry" .        x-handle-geometry)
+    ("-fg" 1 ns-handle-switch foreground-color)
+    ("-foreground" 1 ns-handle-switch foreground-color)
+    ("-bg" 1 ns-handle-switch background-color)
+    ("-background" 1 ns-handle-switch background-color)
+;    ("-ms" 1 ns-handle-switch mouse-color)
+    ("-itype" 0 ns-handle-switch icon-type t)
+    ("-i" 0 ns-handle-switch icon-type t)
+    ("-iconic" 0 ns-handle-iconic icon-type t)
+    ;;("-xrm" .             x-handle-xrm-switch)
+    ("-cr" 1 ns-handle-switch cursor-color)
+    ("-vb" 0 ns-handle-switch vertical-scroll-bars t)
+    ("-hb" 0 ns-handle-switch horizontal-scroll-bars t)
+    ("-bd" 1 ns-handle-switch) 
+    ;; ("--border-width" 1 ns-handle-numeric-switch border-width) 
+    ;; ("--display" 1 ns-handle-display)
+    ("--name" 1 ns-handle-name-switch)
+    ("--title" 1 ns-handle-switch title)
+    ("--reverse-video" 0 ns-handle-switch reverse t)
+    ("--font" 1 ns-handle-switch font)
+    ("--internal-border" 1 ns-handle-numeric-switch internal-border-width)
+    ;; ("--geometry" 1 ns-handle-geometry)
+    ("--foreground-color" 1 ns-handle-switch foreground-color)
+    ("--background-color" 1 ns-handle-switch background-color)
+    ("--mouse-color" 1 ns-handle-switch mouse-color)
+    ("--icon-type" 0 ns-handle-switch icon-type t)
+    ("--iconic" 0 ns-handle-iconic)
+    ;; ("--xrm" 1 ns-handle-xrm-switch)
+    ("--cursor-color" 1 ns-handle-switch cursor-color)
+    ("--vertical-scroll-bars" 0 ns-handle-switch vertical-scroll-bars t)
+    ("--border-color" 1 ns-handle-switch border-width))
+  "Alist of NS options.
+Each element has the form
+  (NAME NUMARGS HANDLER FRAME-PARAM VALUE)
+where NAME is the option name string, NUMARGS is the number of arguments
+that the option accepts, HANDLER is a function to call to handle the option.
+FRAME-PARAM (optional) is the frame parameter this option specifies,
+and VALUE is the value which is given to that frame parameter
+\(most options use the argument for this, so VALUE is not present).")
+
+
 (defvar before-init-hook nil
   "Normal hook run after handling urgent options but before loading init files.")
 
@@ -820,7 +886,7 @@
   ;; only because all other settings of no-blinking-cursor are here.
   (unless (or noninteractive
 	      emacs-basic-display
-	      (and (memq window-system '(x w32 mac))
+	      (and (memq window-system '(x w32 mac ns))
 		   (not (member (x-get-resource "cursorBlink" "CursorBlink")
 				'("off" "false")))))
     (setq no-blinking-cursor t))
@@ -2021,6 +2087,13 @@
 	  (if (string-match "^--" (car tem))
 	      (push (list (car tem)) longopts)))
 
+      ;; Add the long NS options to longopts.
+      (setq tem command-line-ns-option-alist)
+      (while tem
+	(if (string-match "^--" (car (car tem)))
+	    (setq longopts (cons (list (car (car tem))) longopts)))
+	(setq tem (cdr tem)))
+
 	;; Loop, processing options.
 	(while command-line-args-left
 	  (let* ((argi (car command-line-args-left))
@@ -2131,6 +2204,11 @@
 		   (setq command-line-args-left
 			 (nthcdr (nth 1 tem) command-line-args-left)))
 
+		((setq tem (assoc argi command-line-ns-option-alist))
+		 ;; Ignore NS-windows options and their args if not using NS.
+		 (setq command-line-args-left
+		       (nthcdr (nth 1 tem) command-line-args-left)))
+
 		  ((member argi '("-find-file" "-file" "-visit"))
 		   (setq inhibit-startup-screen t)
 		   ;; An explicit option to specify visiting a file.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/term/ns-win.el	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,1608 @@
+;;; ns-win.el --- lisp side of interface with
+;;;               NeXT/Open/GNUstep/MacOS X window system
+;;; Copyright (C) 1993, 1994, 2005, 2006, 2008 Free Software Foundation, Inc.
+
+;;; Author: Carl Edman, Christian Limpach, Scott Bender, Christophe de Dinechin,
+;;;         Adrian Robert
+;;; Keywords: terminals
+
+;;; 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.
+
+;;; Commentary:
+
+;; ns-win.el:  this file is loaded from ../lisp/startup.el when it recognizes
+;; that NS windows are to be used.  Command line switches are parsed and those
+;; pertaining to NS are processed and removed from the command line.  The
+;; NS display is opened and hooks are set for popping up the initial window.
+
+;; startup.el will then examine startup files, and eventually call the hooks
+;; which create the first window (s).
+
+;; A number of other NS convenience functions are defined in this file,
+;; which works in close coordination with src/nsfns.m.
+
+;;; Code:
+
+
+(if (not (featurep 'ns-windowing))
+    (error "%s: Loading ns-win.el but not compiled for *Step/OS X"
+	   (invocation-name)))
+
+;; Documentation-purposes only: actually loaded in loadup.el
+(require 'frame)
+(require 'mouse)
+(require 'faces)
+(require 'easymenu)
+(require 'menu-bar)
+(require 'fontset)
+
+; Not needed?
+;(require 'ispell)
+
+(defun ns-submit-bug-report ()
+   "Submit via mail a bug report on Emacs 23.0.0 for GNUstep / OS X."
+   (interactive)
+   (let ((frame-parameters (frame-parameters))
+         (server-vendor (ns-server-vendor))
+         (server-version (ns-server-version)))
+     (reporter-submit-bug-report
+      "Adrian Robert <Adrian.B.Robert@gmail.com>"
+      ;;"Christophe de Dinechin <descubes@earthlink.net>"
+      ;;"Scott Bender <emacs@harmony-ds.com>" 
+      ;;"Christian Limpach <chris@nice.ch>"
+      ;;"Carl Edman <cedman@princeton.edu>"
+      (concat "Emacs for GNUstep / OS X " ns-version-string)
+      '(ns-expand-space ns-cursor-blink-rate ns-alternate-modifier
+        data-directory frame-parameters window-system window-system-version
+        server-vendor server-version system-configuration-options))))
+
+
+;;;; Command line argument handling.
+
+(defvar ns-invocation-args nil)
+(defvar ns-command-line-resources nil)
+
+;; Handler for switches of the form "-switch value" or "-switch".
+(defun ns-handle-switch (switch)
+  (let ((aelt (assoc switch command-line-ns-option-alist)))
+    (if aelt
+	(let ((param (nth 3 aelt))
+	      (value (nth 4 aelt)))
+	  (if value
+	      (setq default-frame-alist
+		    (cons (cons param value)
+			  default-frame-alist))
+	    (setq default-frame-alist
+		  (cons (cons param
+			      (car ns-invocation-args))
+			default-frame-alist)
+		  ns-invocation-args (cdr ns-invocation-args)))))))
+
+;; Handler for switches of the form "-switch n"
+(defun ns-handle-numeric-switch (switch)
+  (let ((aelt (assoc switch command-line-ns-option-alist)))
+    (if aelt
+	(let ((param (nth 3 aelt)))
+	  (setq default-frame-alist
+		(cons (cons param
+			    (string-to-number (car ns-invocation-args)))
+		      default-frame-alist)
+		ns-invocation-args
+		(cdr ns-invocation-args))))))
+
+;; Make -iconic apply only to the initial frame!
+(defun ns-handle-iconic (switch)
+  (setq initial-frame-alist
+        (cons '(visibility . icon) initial-frame-alist)))
+
+;; Handle the -name option, set the name of
+;; the initial frame.
+(defun ns-handle-name-switch (switch)
+  (or (consp ns-invocation-args)
+      (error "%s: missing argument to `%s' option" (invocation-name) switch))
+  (setq initial-frame-alist (cons (cons 'name (car ns-invocation-args))
+                                  initial-frame-alist)
+        ns-invocation-args (cdr ns-invocation-args)))
+
+(defun ns-handle-nxopen (switch)
+  (setq unread-command-events (append unread-command-events '(ns-open-file))
+        ns-input-file (append ns-input-file (list (car ns-invocation-args)))
+        ns-invocation-args (cdr ns-invocation-args)))
+
+(defun ns-handle-nxopentemp (switch)
+  (setq unread-command-events (append unread-command-events '(ns-open-temp-file))
+        ns-input-file (append ns-input-file (list (car ns-invocation-args)))
+        ns-invocation-args (cdr ns-invocation-args)))
+
+(defun ns-ignore-0-arg (switch)
+  )
+(defun ns-ignore-1-arg (switch)
+  (setq ns-invocation-args (cdr ns-invocation-args)))
+(defun ns-ignore-2-arg (switch)
+  (setq ns-invocation-args (cddr ns-invocation-args)))
+
+(defun ns-handle-args (args)
+  "Here the NS-related command line options in ARGS are processed,
+before the user's startup file is loaded.  They are copied to
+`ns-invocation-args', from which the NS related things are extracted, first
+the switch (e.g., \"-fg\") in the following code, and possible values
+\(e.g., \"black\") in the option handler code (e.g., ns-handle-switch).
+This function returns ARGS minus the arguments that have been processed."
+  ;; We use ARGS to accumulate the args that we don't handle here, to return.
+  (setq ns-invocation-args args
+        args nil)
+  (while ns-invocation-args
+    (let* ((this-switch (car ns-invocation-args))
+	   (orig-this-switch this-switch)
+	   completion argval aelt handler)
+      (setq ns-invocation-args (cdr ns-invocation-args))
+      ;; Check for long options with attached arguments
+      ;; and separate out the attached option argument into argval.
+      (if (string-match "^--[^=]*=" this-switch)
+	  (setq argval (substring this-switch (match-end 0))
+		this-switch (substring this-switch 0 (1- (match-end 0)))))
+      ;; Complete names of long options.
+      (if (string-match "^--" this-switch)
+	  (progn
+	    (setq completion (try-completion this-switch
+                                             command-line-ns-option-alist))
+	    (if (eq completion t)
+		;; Exact match for long option.
+		nil
+	      (if (stringp completion)
+		  (let ((elt (assoc completion command-line-ns-option-alist)))
+		    ;; Check for abbreviated long option.
+		    (or elt
+			(error "Option `%s' is ambiguous" this-switch))
+		    (setq this-switch completion))))))
+      (setq aelt (assoc this-switch command-line-ns-option-alist))
+      (if aelt (setq handler (nth 2 aelt)))
+      (if handler
+	  (if argval
+	      (let ((ns-invocation-args
+		     (cons argval ns-invocation-args)))
+		(funcall handler this-switch))
+	    (funcall handler this-switch))
+	(setq args (cons orig-this-switch args)))))
+  (nreverse args))
+
+(defun x-parse-geometry (geom)
+  "Parse an NS-style geometry string STRING.
+Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
+The properties returned may include `top', `left', `height', and `width'."
+  (if (string-match "\\([0-9]+\\)\\( \\([0-9]+\\)\\( \\([0-9]+\\)\\( \\([0-9]+\\) ?\\)?\\)?\\)?"
+                    geom)
+      (apply 'append
+	   (list
+	    (list (cons 'top (string-to-number (match-string 1 geom))))
+	    (if (match-string 3 geom)
+		(list (cons 'left (string-to-number (match-string 3 geom)))))
+	    (if (match-string 5 geom)
+		(list (cons 'height (string-to-number (match-string 5 geom)))))
+	    (if (match-string 7 geom)
+		(list (cons 'width (string-to-number (match-string 7 geom)))))))
+    '()))
+
+
+
+;;;; Keyboard mapping.
+
+;; These tell read-char how to convert
+;; these special chars to ASCII.
+(put 'backspace 'ascii-character 127)
+(put 'delete 'ascii-character 127)
+(put 'tab 'ascii-character ?\t)
+(put 'S-tab 'ascii-character (logior 16 ?\t))
+(put 'linefeed 'ascii-character ?\n)
+(put 'clear 'ascii-character 12)
+(put 'return 'ascii-character 13)
+(put 'escape 'ascii-character ?\e)
+
+;; Map certain keypad keys into ASCII characters
+;; that people usually expect.
+(define-key function-key-map [backspace] [127])
+(define-key function-key-map [delete] [127])
+(define-key function-key-map [tab] [?\t])
+(define-key function-key-map [S-tab] [25])
+(define-key function-key-map [linefeed] [?\n])
+(define-key function-key-map [clear] [11])
+(define-key function-key-map [return] [13])
+(define-key function-key-map [escape] [?\e])
+(define-key function-key-map [M-backspace] [?\M-\d])
+(define-key function-key-map [M-delete] [?\M-\d])
+(define-key function-key-map [M-tab] [?\M-\t])
+(define-key function-key-map [M-linefeed] [?\M-\n])
+(define-key function-key-map [M-clear] [?\M-\013])
+(define-key function-key-map [M-return] [?\M-\015])
+(define-key function-key-map [M-escape] [?\M-\e])
+
+
+;; Here are some NeXTSTEP like bindings for command key sequences.
+(define-key global-map [?\s-,] 'ns-popup-prefs-panel)
+(define-key global-map [?\s-'] 'next-multiframe-window)
+(define-key global-map [?\s-`] 'other-frame)
+(define-key global-map [?\s--] 'center-line)
+(define-key global-map [?\s-:] 'ispell)
+(define-key global-map [?\s-\;] 'ispell-next)
+(define-key global-map [?\s-?] 'info)
+(define-key global-map [?\s-^] 'kill-some-buffers)
+(define-key global-map [?\s-&] 'kill-this-buffer)
+(define-key global-map [?\s-C] 'ns-popup-color-panel)
+(define-key global-map [?\s-D] 'dired)
+(define-key global-map [?\s-E] 'edit-abbrevs)
+(define-key global-map [?\s-L] 'shell-command)
+(define-key global-map [?\s-M] 'manual-entry)
+(define-key global-map [?\s-S] 'ns-write-file-using-panel)
+(define-key global-map [?\s-a] 'mark-whole-buffer)
+(define-key global-map [?\s-c] 'ns-copy-including-secondary)
+(define-key global-map [?\s-d] 'isearch-repeat-backward)
+(define-key global-map [?\s-e] 'isearch-yank-kill)
+(define-key global-map [?\s-f] 'isearch-forward)
+(define-key global-map [?\s-g] 'isearch-repeat-forward)
+(define-key global-map [?\s-h] 'ns-do-hide-emacs)
+(define-key global-map [?\s-H] 'ns-do-hide-others)
+(define-key global-map [?\s-j] 'exchange-point-and-mark)
+(define-key global-map [?\s-k] 'kill-this-buffer)
+(define-key global-map [?\s-l] 'goto-line)
+(define-key global-map [?\s-m] 'iconify-frame)
+(define-key global-map [?\s-n] 'make-frame)
+(define-key global-map [?\s-o] 'ns-open-file-using-panel)
+(define-key global-map [?\s-p] 'ns-print-buffer)
+(define-key global-map [?\s-q] 'save-buffers-kill-emacs)
+(define-key global-map [?\s-s] 'save-buffer)
+(define-key global-map [?\s-t] 'ns-popup-font-panel)
+(define-key global-map [?\s-u] 'revert-buffer)
+(define-key global-map [?\s-v] 'yank)
+(define-key global-map [?\s-w] 'delete-frame)
+(define-key global-map [?\s-x] 'kill-region)
+(define-key global-map [?\s-y] 'ns-paste-secondary)
+(define-key global-map [?\s-z] 'undo)
+(define-key global-map [?\s-|] 'shell-command-on-region)
+(define-key global-map [s-kp-bar] 'shell-command-on-region)
+; (as in Terminal.app)
+(define-key global-map [s-right] 'ns-next-frame)
+(define-key global-map [s-left] 'ns-prev-frame)
+
+(define-key global-map [home] 'beginning-of-buffer)
+(define-key global-map [end] 'end-of-buffer)
+(define-key global-map [kp-home] 'beginning-of-buffer)
+(define-key global-map [kp-end] 'end-of-buffer)
+(define-key global-map [kp-prior] 'scroll-down)
+(define-key global-map [kp-next] 'scroll-up)
+
+
+;; Special NeXTSTEP generated events are converted to function keys.  Here
+;; are the bindings for them.
+(define-key global-map [ns-power-off]
+  '(lambda () (interactive) (save-buffers-kill-emacs t)))
+(define-key global-map [ns-open-file] 'ns-find-file)
+(define-key global-map [ns-open-temp-file] [ns-open-file])
+(define-key global-map [ns-drag-file] 'ns-insert-file)
+(define-key global-map [ns-drag-color] 'ns-set-foreground-at-mouse)
+(define-key global-map [S-ns-drag-color] 'ns-set-background-at-mouse)
+(define-key global-map [ns-drag-text] 'ns-insert-text)
+(define-key global-map [ns-change-font] 'ns-respond-to-change-font)
+(define-key global-map [ns-open-file-line] 'ns-open-file-select-line)
+(define-key global-map [ns-insert-working-text] 'ns-insert-working-text)
+(define-key global-map [ns-delete-working-text] 'ns-delete-working-text)
+(define-key global-map [ns-spi-service-call] 'ns-spi-service-call)
+
+
+
+;;;; Lisp niceties, most used only under ns-extended-platform-support-mode,
+;;;; defined below
+
+(autoload 'ns-grabenv "ns-grabenv" "Get environment from your shell." t nil)
+(load "ns-carbon-compat")
+
+;; alt-up/down scrolling a la Stuart.app
+;; only activated if ns-extended-platform-support is on
+(defun up-one () (interactive) (scroll-up 1))
+(defun down-one () (interactive) (scroll-down 1))
+(defun left-one () (interactive) (scroll-left 1))
+(defun right-one () (interactive) (scroll-right 1))
+
+;; Toggle some additional NS-like features that may interfere with users'
+;; expectations coming from emacs on other platforms.
+(define-minor-mode ns-extended-platform-support-mode
+  "Toggle NS extended platform support features.
+   When this mode is active (no modeline indicator):
+   - File menus is altered slightly in keeping with conventions.
+   - Meta-up, meta-down are bound to scroll window up and down one line.
+   - Meta-p, Meta-n navigate forwards and backwards in the mark ring."
+  :init-value nil
+  :global t
+  :group 'ns
+  (if ns-extended-platform-support-mode
+      (progn
+       (global-set-key [M-up] 'down-one)
+       (global-set-key [M-down] 'up-one)
+       ; These conflict w/word-left, word-right
+       ;;(global-set-key [M-left] 'left-one)
+       ;;(global-set-key [M-right] 'right-one)
+
+       (setq scroll-preserve-screen-position t)
+       (transient-mark-mode 1)
+
+       ;; Change file menu to simplify and add a couple of NS-specific items
+       (easy-menu-remove-item global-map '("menu-bar") 'file)
+       (easy-menu-add-item global-map '(menu-bar)
+			   (cons "File" menu-bar-ns-file-menu) 'edit))
+    (progn
+     ; undo everything above
+       (global-unset-key [M-up])
+       (global-unset-key [M-down])
+       (setq scroll-preserve-screen-position nil)
+       (transient-mark-mode 0)
+       (easy-menu-remove-item global-map '("menu-bar") 'file)
+       (easy-menu-add-item global-map '(menu-bar)
+			   (cons "File" menu-bar-file-menu) 'edit))))
+
+
+(defun x-setup-function-keys (frame)
+  "Set up function Keys for NS for given FRAME."
+  (unless (terminal-parameter frame 'x-setup-function-keys)
+    (with-selected-frame frame
+      (setq interprogram-cut-function 'ns-select-text
+	    interprogram-paste-function 'ns-pasteboard-value)
+;;;       (let ((map (copy-keymap x-alternatives-map)))
+;;; 	(set-keymap-parent map (keymap-parent local-function-key-map))
+;;; 	(set-keymap-parent local-function-key-map map))
+    (setq system-key-alist
+      (list
+       (cons (logior (lsh 0 16)   1) 'ns-power-off)
+       (cons (logior (lsh 0 16)   2) 'ns-open-file)
+       (cons (logior (lsh 0 16)   3) 'ns-open-temp-file)
+       (cons (logior (lsh 0 16)   4) 'ns-drag-file)
+       (cons (logior (lsh 0 16)   5) 'ns-drag-color)
+       (cons (logior (lsh 0 16)   6) 'ns-drag-text)
+       (cons (logior (lsh 0 16)   7) 'ns-change-font)
+       (cons (logior (lsh 0 16)   8) 'ns-open-file-line)
+       (cons (logior (lsh 0 16)   9) 'ns-insert-working-text)
+       (cons (logior (lsh 0 16)  10) 'ns-delete-working-text)
+       (cons (logior (lsh 0 16)  11) 'ns-spi-service-call)
+       (cons (logior (lsh 1 16)  32) 'f1)
+       (cons (logior (lsh 1 16)  33) 'f2)
+       (cons (logior (lsh 1 16)  34) 'f3)
+       (cons (logior (lsh 1 16)  35) 'f4)
+       (cons (logior (lsh 1 16)  36) 'f5)
+       (cons (logior (lsh 1 16)  37) 'f6)
+       (cons (logior (lsh 1 16)  38) 'f7)
+       (cons (logior (lsh 1 16)  39) 'f8)
+       (cons (logior (lsh 1 16)  40) 'f9)
+       (cons (logior (lsh 1 16)  41) 'f10)
+       (cons (logior (lsh 1 16)  42) 'f11)
+       (cons (logior (lsh 1 16)  43) 'f12)
+       (cons (logior (lsh 1 16)  44) 'kp-insert)
+       (cons (logior (lsh 1 16)  45) 'kp-delete)
+       (cons (logior (lsh 1 16)  46) 'kp-home)
+       (cons (logior (lsh 1 16)  47) 'kp-end)
+       (cons (logior (lsh 1 16)  48) 'kp-prior)
+       (cons (logior (lsh 1 16)  49) 'kp-next)
+       (cons (logior (lsh 1 16)  50) 'print-screen)
+       (cons (logior (lsh 1 16)  51) 'scroll-lock)
+       (cons (logior (lsh 1 16)  52) 'pause)
+       (cons (logior (lsh 1 16)  53) 'system)
+       (cons (logior (lsh 1 16)  54) 'break)
+       (cons (logior (lsh 1 16)  56) 'please-tell-carl-what-this-key-is-called-56)
+       (cons (logior (lsh 1 16)  61) 'please-tell-carl-what-this-key-is-called-61)
+       (cons (logior (lsh 1 16)  62) 'please-tell-carl-what-this-key-is-called-62)
+       (cons (logior (lsh 1 16)  63) 'please-tell-carl-what-this-key-is-called-63)
+       (cons (logior (lsh 1 16)  64) 'please-tell-carl-what-this-key-is-called-64)
+       (cons (logior (lsh 1 16)  69) 'please-tell-carl-what-this-key-is-called-69)
+       (cons (logior (lsh 1 16)  70) 'please-tell-carl-what-this-key-is-called-70)
+       (cons (logior (lsh 1 16)  71) 'please-tell-carl-what-this-key-is-called-71)
+       (cons (logior (lsh 1 16)  72) 'please-tell-carl-what-this-key-is-called-72)
+       (cons (logior (lsh 1 16)  73) 'please-tell-carl-what-this-key-is-called-73)
+       (cons (logior (lsh 2 16)   3) 'kp-enter)
+       (cons (logior (lsh 2 16)   9) 'kp-tab)
+       (cons (logior (lsh 2 16)  28) 'kp-quit)
+       (cons (logior (lsh 2 16)  35) 'kp-hash)
+       (cons (logior (lsh 2 16)  42) 'kp-multiply)
+       (cons (logior (lsh 2 16)  43) 'kp-add)
+       (cons (logior (lsh 2 16)  44) 'kp-separator)
+       (cons (logior (lsh 2 16)  45) 'kp-subtract)
+       (cons (logior (lsh 2 16)  46) 'kp-decimal)
+       (cons (logior (lsh 2 16)  47) 'kp-divide)
+       (cons (logior (lsh 2 16)  48) 'kp-0)
+       (cons (logior (lsh 2 16)  49) 'kp-1)
+       (cons (logior (lsh 2 16)  50) 'kp-2)
+       (cons (logior (lsh 2 16)  51) 'kp-3)
+       (cons (logior (lsh 2 16)  52) 'kp-4)
+       (cons (logior (lsh 2 16)  53) 'kp-5)
+       (cons (logior (lsh 2 16)  54) 'kp-6)
+       (cons (logior (lsh 2 16)  55) 'kp-7)
+       (cons (logior (lsh 2 16)  56) 'kp-8)
+       (cons (logior (lsh 2 16)  57) 'kp-9)
+       (cons (logior (lsh 2 16)  60) 'kp-less)
+       (cons (logior (lsh 2 16)  61) 'kp-equal)
+       (cons (logior (lsh 2 16)  62) 'kp-more)
+       (cons (logior (lsh 2 16)  64) 'kp-at)
+       (cons (logior (lsh 2 16)  92) 'kp-backslash)
+       (cons (logior (lsh 2 16)  96) 'kp-backtick)
+       (cons (logior (lsh 2 16) 124) 'kp-bar)
+       (cons (logior (lsh 2 16) 126) 'kp-tilde)
+       (cons (logior (lsh 2 16) 157) 'kp-mu)
+       (cons (logior (lsh 2 16) 165) 'kp-yen)
+       (cons (logior (lsh 2 16) 167) 'kp-paragraph)
+       (cons (logior (lsh 2 16) 172) 'left)
+       (cons (logior (lsh 2 16) 173) 'up)
+       (cons (logior (lsh 2 16) 174) 'right)
+       (cons (logior (lsh 2 16) 175) 'down)
+       (cons (logior (lsh 2 16) 176) 'kp-ring)
+       (cons (logior (lsh 2 16) 201) 'kp-square)
+       (cons (logior (lsh 2 16) 204) 'kp-cube)
+       (cons (logior (lsh 3 16)   8) 'backspace)
+       (cons (logior (lsh 3 16)   9) 'tab)
+       (cons (logior (lsh 3 16)  10) 'linefeed)
+       (cons (logior (lsh 3 16)  11) 'clear)
+       (cons (logior (lsh 3 16)  13) 'return)
+       (cons (logior (lsh 3 16)  18) 'pause)
+       (cons (logior (lsh 3 16)  25) 'S-tab)
+       (cons (logior (lsh 3 16)  27) 'escape)
+       (cons (logior (lsh 3 16) 127) 'delete)
+       ))
+    (set-terminal-parameter frame 'x-setup-function-keys t))))
+
+
+
+;;;; Miscellaneous mouse bindings.
+
+;;; Allow shift-clicks to work just like under NS
+(defun mouse-extend-region (event)
+  "Move point or mark so as to extend region.
+This should be bound to a mouse click event type."
+  (interactive "e")
+  (mouse-minibuffer-check event)
+  (let ((posn (event-end event)))
+    (if (not (windowp (posn-window posn)))
+        (error "Cursor not in text area of window"))
+    (select-window (posn-window posn))
+    (cond
+     ((not (numberp (posn-point posn))))
+     ((or (not mark-active) (> (abs (- (posn-point posn) (point)))
+                               (abs (- (posn-point posn) (mark)))))
+      (let ((point-save (point)))
+        (unwind-protect
+            (progn
+              (goto-char (posn-point posn))
+              (push-mark nil t t)
+              (or transient-mark-mode
+                  (sit-for 1)))
+          (goto-char point-save))))
+     (t
+      (goto-char (posn-point posn))))))
+
+(define-key global-map [S-mouse-1] 'mouse-extend-region)
+(global-unset-key [S-down-mouse-1])
+
+
+
+; must come after keybindings
+
+(fmakunbound 'clipboard-yank)
+(fmakunbound 'clipboard-kill-ring-save)
+(fmakunbound 'clipboard-kill-region)
+(fmakunbound 'menu-bar-enable-clipboard)
+
+;; Add a couple of menus and rearrange some others; easiest just to redo toplvl
+;; Note keymap defns must be given last-to-first
+(define-key global-map [menu-bar] (make-sparse-keymap "menu-bar"))
+
+(cond ((eq system-type 'darwin)
+       (setq menu-bar-final-items '(buffer windows services help-menu)))
+      ;; otherwise, gnustep
+      (t
+       (setq menu-bar-final-items '(buffer windows services hide-app quit)) )
+)
+
+;; add standard top-level items to GNUstep menu
+(cond ((not (eq system-type 'darwin))
+      (define-key global-map [menu-bar quit] '("Quit" . save-buffers-kill-emacs))
+      (define-key global-map [menu-bar hide-app] '("Hide" . ns-do-hide-emacs))
+))
+
+(define-key global-map [menu-bar services]
+  (cons "Services" (make-sparse-keymap "Services")))
+(define-key global-map [menu-bar windows] (make-sparse-keymap "Windows"))
+(define-key global-map [menu-bar buffer]
+  (cons "Buffers" global-buffers-menu-map))
+;;  (cons "Buffers" (make-sparse-keymap "Buffers")))
+(define-key global-map [menu-bar tools] (cons "Tools" menu-bar-tools-menu))
+(define-key global-map [menu-bar options] (cons "Options" menu-bar-options-menu))
+(define-key global-map [menu-bar edit] (cons "Edit" menu-bar-edit-menu))
+(define-key global-map [menu-bar file] (cons "File" menu-bar-file-menu))
+
+;; If running under GNUstep, rename "Help" to "Info"
+(cond ((eq system-type 'darwin)
+       (define-key global-map [menu-bar help-menu]
+	 (cons "Help" menu-bar-help-menu)))
+      (t
+       (let ((contents (reverse (cdr menu-bar-help-menu))))
+	 (setq menu-bar-help-menu
+	       (append (list 'keymap) (cdr contents) (list "Info"))))
+       (define-key global-map [menu-bar help-menu]
+	 (cons "Info" menu-bar-help-menu))))
+
+
+;;;; Add to help / info menu
+(defun info-ns-emacs ()
+  "Jump to ns-emacs info item."
+  (interactive)
+  (info "ns-emacs"))
+
+(define-key menu-bar-help-menu [ns-bug-report]
+  '("Report Emacs.app bug..." . ns-submit-bug-report))
+(define-key menu-bar-help-menu [info-ns]
+  '("Emacs.app Manual" . info-ns-emacs))
+(if (not (eq system-type 'darwin))
+    ;; in OS X it's in the app menu already
+    (define-key menu-bar-help-menu [info-panel]
+      '("About Emacs..." . ns-do-emacs-info-panel)))
+
+
+;;;; File menu, replaces standard under ns-extended-platform-support
+(defvar menu-bar-ns-file-menu (make-sparse-keymap "File"))
+(define-key menu-bar-ns-file-menu [one-window]
+  '("Remove Splits" . delete-other-windows))
+(define-key menu-bar-ns-file-menu [split-window]
+  '("Split Window" . split-window-vertically))
+
+(define-key menu-bar-ns-file-menu [separator-print] '("--"))
+
+(defvar ns-ps-print-menu-map (make-sparse-keymap "Postscript Print"))
+(define-key ns-ps-print-menu-map [ps-print-region]
+  '("Region (B+W)" . ps-print-region))
+(define-key ns-ps-print-menu-map [ps-print-buffer]
+  '("Buffer (B+W)" . ps-print-buffer))
+(define-key ns-ps-print-menu-map [ps-print-region-faces]
+  '("Region" . ps-print-region-with-faces))
+(define-key ns-ps-print-menu-map [ps-print-buffer-faces]
+  '("Buffer" . ns-ps-print-buffer-with-faces))
+(define-key menu-bar-ns-file-menu [postscript-print]
+  (cons "Postscript Print" ns-ps-print-menu-map))
+
+(define-key menu-bar-ns-file-menu [print-region]
+  '("Print Region" . print-region))
+(define-key menu-bar-ns-file-menu [print-buffer]
+  '("Print Buffer" . ns-print-buffer))
+
+(define-key menu-bar-ns-file-menu [separator-save] '("--"))
+
+(define-key menu-bar-ns-file-menu [recover-session]
+  '("Recover Crashed Session" . recover-session))
+(define-key menu-bar-ns-file-menu [revert-buffer]
+  '("Revert Buffer" . revert-buffer))
+(define-key menu-bar-ns-file-menu [write-file]
+  '("Save Buffer As..." . ns-write-file-using-panel))
+(define-key menu-bar-ns-file-menu [save-buffer] '("Save Buffer" . save-buffer))
+
+(define-key menu-bar-ns-file-menu [kill-buffer]
+  '("Kill Current Buffer" . kill-this-buffer))
+(define-key menu-bar-ns-file-menu [delete-this-frame]
+  '("Close Frame" . delete-frame))
+
+(define-key menu-bar-ns-file-menu [separator-open] '("--"))
+
+(define-key menu-bar-ns-file-menu [insert-file]
+  '("Insert File..." . insert-file))
+(define-key menu-bar-ns-file-menu [dired]
+  '("Open Directory..." . ns-open-file-using-panel))
+(define-key menu-bar-ns-file-menu [open-file]
+  '("Open File..." . ns-open-file-using-panel))
+(define-key menu-bar-ns-file-menu [make-frame]
+  '("New Frame" . make-frame))
+
+
+;;;; Edit menu: Modify slightly
+
+; Substitute a Copy function that works better under X (for GNUstep)
+(easy-menu-remove-item global-map '("menu-bar" "edit") 'copy)
+(define-key-after menu-bar-edit-menu [copy]
+  '(menu-item "Copy" ns-copy-including-secondary
+	      :enable mark-active
+	      :help "Copy text in region between mark and current position")
+  'cut)
+
+; Change to same precondition as select-and-paste, as we don't have
+; 'x-selection-exists-p
+(easy-menu-remove-item global-map '("menu-bar" "edit") 'paste)
+(define-key-after menu-bar-edit-menu [paste]
+  '(menu-item "Paste" yank
+	      :enable (and (cdr yank-menu) (not buffer-read-only))
+	      :help "Paste (yank) text most recently cut/copied")
+  'copy)
+
+; Change text to be more consistent with surrounding menu items 'paste', etc.
+(easy-menu-remove-item global-map '("menu-bar" "edit") 'paste-from-menu)
+(define-key-after menu-bar-edit-menu [select-paste]
+  '(menu-item "Select and Paste" yank-menu
+	      :enable (and (cdr yank-menu) (not buffer-read-only))
+	      :help "Choose a string from the kill ring and paste it")
+  'paste)
+
+; Separate undo item from cut/paste section, add spell for platform consistency
+(define-key-after menu-bar-edit-menu [separator-undo] '("--") 'undo)
+(define-key-after menu-bar-edit-menu [spell] '("Spell" . ispell-menu-map) 'fill)
+
+
+;;;; Windows menu
+(defun menu-bar-select-frame ()
+  (interactive)
+  (make-frame-visible last-command-event)
+  (raise-frame last-command-event)
+  (select-frame last-command-event))
+
+(defun menu-bar-update-frames ()
+  ;; If user discards the Windows item, play along.
+  (and (lookup-key (current-global-map) [menu-bar windows])
+       (let ((frames (frame-list))
+	     (frames-menu (make-sparse-keymap "Select Frame")))
+	 (setcdr frames-menu
+		 (nconc
+		  (mapcar '(lambda (frame)
+			     (nconc (list frame
+					  (cdr (assq 'name (frame-parameters frame)))
+					  (cons nil nil))
+				    'menu-bar-select-frame))
+			  frames)
+		  (cdr frames-menu)))
+	 (define-key frames-menu [separator-frames] '("--"))
+	 (define-key frames-menu [popup-color-panel]
+	   '("Colors..." . ns-popup-color-panel))
+	 (define-key frames-menu [popup-font-panel]
+	   '("Font Panel..." . ns-popup-font-panel))
+	 (define-key frames-menu [separator-arrange] '("--"))
+	 (define-key frames-menu [arrange-all-frames]
+	   '("Arrange All Frames" . ns-arrange-all-frames))
+	 (define-key frames-menu [arrange-visible-frames]
+	   '("Arrange Visible Frames" . ns-arrange-visible-frames))
+	 ;; Don't use delete-frame as event name
+	 ;; because that is a special event.
+	 (define-key (current-global-map) [menu-bar windows]
+	   (cons "Windows" frames-menu)))))
+
+(defun force-menu-bar-update-buffers ()
+  ;; This is a hack to get around fact that we already checked
+  ;; frame-or-buffer-changed-p and reset it, so menu-bar-update-buffers
+  ;; does not pick up any change.
+  (menu-bar-update-buffers t))
+
+(add-hook 'menu-bar-update-fab-hook 'menu-bar-update-frames)
+(add-hook 'menu-bar-update-fab-hook 'force-menu-bar-update-buffers)
+
+(defun menu-bar-update-frames-and-buffers ()
+  (if (frame-or-buffer-changed-p)
+      (run-hooks 'menu-bar-update-fab-hook)))
+
+(setq menu-bar-update-hook
+      (delq 'menu-bar-update-buffers menu-bar-update-hook))
+(add-hook 'menu-bar-update-hook 'menu-bar-update-frames-and-buffers)
+
+(menu-bar-update-frames-and-buffers)
+
+
+;; ns-arrange functions contributed
+;; by Eberhard Mandler <mandler@dbag.ulm.DaimlerBenz.COM>
+(defun ns-arrange-all-frames ()
+  "Arranges all frames according to topline"
+  (interactive)
+  (ns-arrange-frames t))
+
+(defun ns-arrange-visible-frames ()
+  "Arranges all visible frames according to topline"
+  (interactive)
+  (ns-arrange-frames nil))
+
+(defun ns-arrange-frames ( vis)
+  (let ((frame (next-frame))
+	(end-frame (selected-frame))
+	(inc-x 20)                      ;relative position of frames
+	(inc-y 22)
+	(x-pos 100)                     ;start position
+	(y-pos 40)
+	(done nil))
+    (while (not done)                   ;cycle through all frames
+      (if (not (or vis (eq (frame-visible-p frame) t)))
+	(setq x-pos x-pos); do nothing; true case
+	(set-frame-position frame x-pos y-pos)
+	(setq x-pos (+ x-pos inc-x))
+	(setq y-pos (+ y-pos inc-y))
+	(raise-frame frame))
+      (select-frame frame)
+      (setq frame (next-frame))
+      (setq done (equal frame end-frame)))
+    (set-frame-position end-frame x-pos y-pos)
+    (raise-frame frame)
+    (select-frame frame)))
+
+
+;;;; Services
+(defun ns-define-service (path)
+  (let ((mapping [menu-bar services])
+	(service (mapconcat 'identity path "/"))
+	(name (intern
+	       (mapconcat '(lambda (s) (if (= s 32) "-" (char-to-string s)))
+			  (mapconcat 'identity (cons "ns-service" path) "-")
+			  ""))))
+    ;; This defines the function
+    (eval (append (list 'defun name)
+	  `((arg)
+	    (interactive "p")
+	    (let* ((in-string (if (stringp arg) arg (if mark-active
+			  (buffer-substring (region-beginning) (region-end)))))
+		   (out-string (ns-perform-service (,@service) in-string)))
+	      (cond
+	       ((stringp arg) out-string)
+	       ((and out-string (or (not in-string)
+				    (not (string= in-string out-string))))
+		(if mark-active (delete-region (region-beginning) (region-end)))
+		(insert out-string)
+		(setq deactivate-mark nil)))))))
+    (cond
+     ((lookup-key global-map mapping)
+      (while (cdr path)
+	(setq mapping (vconcat mapping (list (intern (car path)))))
+	(if (not (keymapp (lookup-key global-map mapping)))
+	    (define-key global-map mapping
+	      (cons (car path) (make-sparse-keymap (car path)))))
+	(setq path (cdr path)))
+      (setq mapping (vconcat mapping (list (intern (car path)))))
+      (define-key global-map mapping (cons (car path) name))))
+    name))
+
+(precompute-menubar-bindings)
+
+(defun ns-spi-service-call ()
+  "Respond to a service request to Emacs.app."
+  (interactive)
+  (cond ((string-equal ns-input-spi-name "open-selection")
+	 (switch-to-buffer (generate-new-buffer "*untitled*"))
+	 (insert ns-input-spi-arg))
+	((string-equal ns-input-spi-name "open-file")
+	 (dnd-open-file ns-input-spi-arg nil))
+	((string-equal ns-input-spi-name "mail-selection")
+	 (compose-mail)
+	 (rfc822-goto-eoh)
+	 (forward-line 1)
+	 (insert ns-input-spi-arg))
+	((string-equal ns-input-spi-name "mail-to")
+	 (compose-mail ns-input-spi-arg))
+	(t (error (concat "Service " ns-input-spi-name " not recognized")))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+
+;;;; Composed key sequence handling for NS system input methods.
+;;;; (On NS systems, input methods are provided for CJK characters,
+;;;;  etc. which require multiple keystrokes, and during entry a
+;;;;  partial ("working") result is typically shown in the editing window.)
+
+(defface ns-working-text-face
+  '((t :underline t))
+  "Face used to highlight working text during compose sequence insert."
+  :group 'ns)
+
+(defvar ns-working-overlay nil
+  "Overlay used to highlight working text during compose sequence insert.")
+(make-variable-buffer-local 'ns-working-overlay)
+(defvar ns-working-overlay-len 0
+  "Length of working text during compose sequence insert.")
+(make-variable-buffer-local 'ns-working-overlay-len)
+
+; Based on mac-win.el 2007/08/26 unicode-2.  This will fail if called
+; from an "interactive" function.
+(defun ns-in-echo-area ()
+  "Whether, for purposes of inserting working composition text, the minibuffer
+is currently being used."
+  (or isearch-mode
+      (and cursor-in-echo-area (current-message))
+      ;; Overlay strings are not shown in some cases.
+      (get-char-property (point) 'invisible)
+      (and (not (bobp))
+	   (or (and (get-char-property (point) 'display)
+		    (eq (get-char-property (1- (point)) 'display)
+			(get-char-property (point) 'display)))
+	       (and (get-char-property (point) 'composition)
+		    (eq (get-char-property (1- (point)) 'composition)
+			(get-char-property (point) 'composition)))))))
+
+; currently not used, doesn't work because the 'interactive' here stays
+; for subinvocations
+(defun ns-insert-working-text ()
+  (interactive)
+  (if (ns-in-echo-area) (ns-echo-working-text) (ns-put-working-text)))
+
+(defun ns-put-working-text ()
+  "Insert contents of ns-working-text as UTF8 string and mark with
+ns-working-overlay.  Any previously existing working text is cleared first.
+The overlay is assigned the face ns-working-text-face."
+  (interactive)
+  (if ns-working-overlay (ns-delete-working-text))
+  (let ((start (point)))
+    (insert ns-working-text)
+    (overlay-put (setq ns-working-overlay (make-overlay start (point)
+							(current-buffer) nil t))
+		 'face 'ns-working-text-face)
+    (setq ns-working-overlay-len (+ ns-working-overlay-len (- (point) start)))))
+
+(defun ns-echo-working-text ()
+  "Echo contents of ns-working-text in message display area.
+See ns-insert-working-text."
+  (if ns-working-overlay (ns-unecho-working-text))
+  (let* ((msg (current-message))
+	 (msglen (length msg))
+	 message-log-max)
+    (setq ns-working-overlay-len (length ns-working-text))
+    (setq msg (concat msg ns-working-text))
+    (put-text-property msglen (+ msglen ns-working-overlay-len) 'face 'ns-working-text-face msg)
+    (message "%s" msg)
+    (setq ns-working-overlay t)))
+
+(defun ns-delete-working-text()
+  "Delete working text and clear ns-working-overlay."
+  (interactive)
+  (delete-backward-char ns-working-overlay-len)
+  (setq ns-working-overlay-len 0)
+  (delete-overlay ns-working-overlay))
+
+(defun ns-unecho-working-text()
+  "Delete working text from echo area and clear ns-working-overlay."
+  (let ((msg (current-message))
+	message-log-max)
+    (setq msg (substring msg 0 (- (length msg) ns-working-overlay-len)))
+    (setq ns-working-overlay-len 0)
+    (setq ns-working-overlay nil)))
+
+
+;;;; OS X file system Unicode UTF-8 NFD (decomposed form) support
+;; Lisp code based on utf-8m.el, by Seiji Zenitani, Eiji Honjoh, and
+;; Carsten Bormann.
+(if (eq system-type 'darwin)
+    (progn
+
+      (defun ns-utf8-nfd-post-read-conversion (length)
+	"Calls ns-convert-utf8-nfd-to-nfc to compose char sequences."
+	(save-excursion
+	  (save-restriction
+	    (narrow-to-region (point) (+ (point) length))
+	    (let ((str (buffer-string)))
+	      (delete-region (point-min) (point-max))
+	      (insert (ns-convert-utf8-nfd-to-nfc str))
+	      (- (point-max) (point-min))
+	      ))))
+
+      (define-coding-system 'utf-8-nfd
+	"UTF-8 NFD (decomposed) encoding."
+	:coding-type 'utf-8
+	:mnemonic ?U
+	:charset-list '(unicode)
+	:post-read-conversion 'ns-utf8-nfd-post-read-conversion)
+      (set-file-name-coding-system 'utf-8-nfd)))
+
+;; PENDING: disable composition-based display for Indic scripts as it
+;;          is not working well under NS for some reason
+(set-char-table-range composition-function-table
+                     '(#x0900 . #x0DFF) nil)
+
+
+;;;; Inter-app communications support.
+
+(defun ns-insert-text ()
+  "Insert contents of ns-input-text at point."
+  (interactive)
+  (insert ns-input-text)
+  (setq ns-input-text nil))
+ 
+(defun ns-insert-file ()
+  "Insert contents of file ns-input-file like insert-file but with less
+prompting.  If file is a directory perform a find-file on it."
+  (interactive)
+  (let ((f))
+    (setq f (car ns-input-file))
+    (setq ns-input-file (cdr ns-input-file))
+    (if (file-directory-p f)
+        (find-file f)
+      (push-mark (+ (point) (car (cdr (insert-file-contents f))))))))
+
+(defvar ns-select-overlay nil
+  "Overlay used to highlight areas in files requested by NS apps.")
+(make-variable-buffer-local 'ns-select-overlay)
+
+(defun ns-open-file-select-line ()
+  "Brings up a buffer containing file ns-input-file,\n\
+and highlights lines indicated by ns-input-line."
+  (interactive)
+  (ns-find-file)
+  (cond
+   ((and ns-input-line (buffer-modified-p))
+    (if ns-select-overlay
+        (setq ns-select-overlay (delete-overlay ns-select-overlay)))
+    (deactivate-mark)
+    (goto-line (if (consp ns-input-line)
+                   (min (car ns-input-line) (cdr ns-input-line))
+                 ns-input-line)))
+   (ns-input-line
+    (if (not ns-select-overlay)
+        (overlay-put (setq ns-select-overlay (make-overlay (point-min) (point-min)))
+                     'face 'highlight))
+    (let ((beg (save-excursion
+                 (goto-line (if (consp ns-input-line)
+                                (min (car ns-input-line) (cdr ns-input-line))
+                              ns-input-line))
+                 (point)))
+          (end (save-excursion
+                 (goto-line (+ 1 (if (consp ns-input-line)
+                                     (max (car ns-input-line) (cdr ns-input-line))
+                                   ns-input-line)))
+                 (point))))
+      (move-overlay ns-select-overlay beg end)
+      (deactivate-mark)
+      (goto-char beg)))
+   (t
+    (if ns-select-overlay
+        (setq ns-select-overlay (delete-overlay ns-select-overlay))))))
+
+(defun ns-unselect-line ()
+  "Removes any NS highlight a buffer may contain."
+  (if ns-select-overlay
+      (setq ns-select-overlay (delete-overlay ns-select-overlay))))
+
+(add-hook 'first-change-hook 'ns-unselect-line)
+
+
+
+;;;; Preferences handling.
+
+(defun get-lisp-resource (arg1 arg2)
+  (let ((res (ns-get-resource arg1 arg2)))
+    (cond
+     ((not res) 'unbound)
+     ((string-equal (upcase res) "YES") t)
+     ((string-equal (upcase res) "NO")  nil)
+     (t (read res)))))
+
+(defun ns-save-preferences ()
+  "Set all the defaults."
+  (interactive)
+  ;; Global preferences
+  (ns-set-resource nil "AlternateModifier" (symbol-name ns-alternate-modifier))
+  (ns-set-resource nil "CommandModifier" (symbol-name ns-command-modifier))
+  (ns-set-resource nil "ControlModifier" (symbol-name ns-control-modifier))
+  (ns-set-resource nil "FunctionModifier" (symbol-name ns-function-modifier))
+  (ns-set-resource nil "CursorBlinkRate"
+                (if ns-cursor-blink-rate
+                    (number-to-string ns-cursor-blink-rate)
+                  "NO"))
+  (ns-set-resource nil "ExpandSpace"
+                (if ns-expand-space
+                    (number-to-string ns-expand-space)
+                  "NO"))
+  (ns-set-resource nil "GSFontAntiAlias" (if ns-antialias-text "YES" "NO"))
+  (ns-set-resource nil "UseQuickdrawSmoothing"
+		   (if ns-use-qd-smoothing "YES" "NO"))
+  (ns-set-resource nil "UseSystemHighlightColor"
+		   (if ns-use-system-highlight-color "YES" "NO"))
+  ;; Default frame parameters
+  (let ((p (frame-parameters)))
+    (let ((f (assq 'font p)))
+      (if f (ns-set-resource nil "Font" (ns-font-name (cdr f)))))
+    (let ((fs (assq 'fontsize p)))
+      (if fs (ns-set-resource nil "FontSize" (number-to-string (cdr fs)))))
+    (let ((fgc (assq 'foreground-color p)))
+      (if fgc (ns-set-resource nil "Foreground" (cdr fgc))))
+    (let ((bgc (assq 'background-color p)))
+      (if bgc (ns-set-resource nil "Background" (cdr bgc))))
+    (let ((cc (assq 'cursor-color p)))
+      (if cc (ns-set-resource nil "CursorColor" (cdr cc))))
+    (let ((ct (assq 'cursor-type p)))
+      (if ct (ns-set-resource nil "CursorType"
+                  (if (symbolp (cdr ct)) (symbol-name (cdr ct)) (cdr ct)))))
+    (let ((under (assq 'underline p)))
+      (if under (ns-set-resource nil "Underline"
+				 (cond ((eq (cdr under) t) "YES")
+				       ((eq (cdr under) nil) "NO")
+				       (t (cdr under))))))
+    (let ((ibw (assq 'internal-border-width p)))
+      (if ibw (ns-set-resource nil "InternalBorderWidth"
+                            (number-to-string (cdr ibw)))))
+     (let ((vsb (assq 'vertical-scroll-bars p)))
+       (if vsb (ns-set-resource nil "VerticalScrollBars" (cond
+                                       ((eq t (cdr vsb)) "YES")
+                                       ((eq nil (cdr vsb)) "NO")
+                                       ((eq 'left (cdr vsb)) "left")
+                                       ((eq 'right (cdr vsb)) "right")
+                                       (t nil)))))
+    (let ((height (assq 'height p)))
+      (if height (ns-set-resource nil "Height"
+                               (number-to-string (cdr height)))))
+    (let ((width (assq 'width p)))
+      (if width (ns-set-resource nil "Width"
+                              (number-to-string (cdr width)))))
+    (let ((top (assq 'top p)))
+      (if top (ns-set-resource nil "Top"
+                            (number-to-string (cdr top)))))
+    (let ((left (assq 'left p)))
+      (if left (ns-set-resource nil "Left"
+                             (number-to-string (cdr left)))))
+    ;; These not fully supported
+    (let ((ar (assq 'auto-raise p)))
+      (if ar (ns-set-resource nil "AutoRaise"
+                            (if (cdr ar) "YES" "NO"))))
+    (let ((al (assq 'auto-lower p)))
+      (if al (ns-set-resource nil "AutoLower"
+                            (if (cdr al) "YES" "NO"))))
+    (let ((mbl (assq 'menu-bar-lines p)))
+      (if mbl (ns-set-resource nil "Menus"
+                            (if (cdr mbl) "YES" "NO"))))
+    )
+  (let ((fl (face-list)))
+    (while (consp fl)
+      (or (eq 'default (car fl))
+          ;; dont save Default* since it causes all created faces to
+          ;; inherit its values.  The properties of the default face
+          ;; have already been saved from the frame-parameters anyway.
+          (let* ((name (symbol-name (car fl)))
+                 (font (face-font (car fl)))
+;                 (fontsize (face-fontsize (car fl)))
+                 (foreground (face-foreground (car fl)))
+                 (background (face-background (car fl)))
+                 (underline (face-underline-p (car fl)))
+                 (italic (face-italic-p (car fl)))
+                 (bold (face-bold-p (car fl)))
+                 (stipple (face-stipple (car fl))))
+;            (ns-set-resource nil (concat name ".attributeFont")
+;                          (if font font nil))
+;            (ns-set-resource nil (concat name ".attributeFontSize")
+;                          (if fontsize (number-to-string fontsize) nil))
+            (ns-set-resource nil (concat name ".attributeForeground")
+                          (if foreground foreground nil))
+            (ns-set-resource nil (concat name ".attributeBackground")
+                          (if background background nil))
+            (ns-set-resource nil (concat name ".attributeUnderline")
+                          (if underline "YES" nil))
+            (ns-set-resource nil (concat name ".attributeItalic")
+                          (if italic "YES" nil))
+            (ns-set-resource nil (concat name ".attributeBold")
+                          (if bold "YES" nil))
+            (and stipple
+                 (or (stringp stipple)
+                     (setq stipple (prin1-to-string stipple))))
+            (ns-set-resource nil (concat name ".attributeStipple")
+                          (if stipple stipple nil))))
+      (setq fl (cdr fl)))))
+
+;; call ns-save-preferences when menu-bar-options-save is called
+(fset 'menu-bar-options-save-orig (symbol-function 'menu-bar-options-save))
+(defun ns-save-options ()
+  (interactive)
+  (menu-bar-options-save-orig)
+  (ns-save-preferences))
+(fset 'menu-bar-options-save (symbol-function 'ns-save-options))
+
+
+;;;; File handling.
+
+(defun ns-open-file-using-panel ()
+  "Pop up open-file panel, and load the result in a buffer."
+  (interactive)
+  ; prompt dir defaultName isLoad initial
+  (setq ns-input-file (ns-read-file-name "Select File to Load" nil t nil))
+  (if ns-input-file
+      (and (setq ns-input-file (list ns-input-file)) (ns-find-file))))
+
+(defun ns-write-file-using-panel ()
+  "Pop up save-file panel, and save buffer in resulting name."
+  (interactive)
+  (let (ns-output-file)
+    ; prompt dir defaultName isLoad initial
+    (setq ns-output-file (ns-read-file-name "Save As" nil nil nil))
+    (message ns-output-file)
+    (if ns-output-file (write-file ns-output-file))))
+
+(defun ns-find-file ()
+  "Do a find-file with the ns-input-file as argument."
+  (interactive)
+  (let ((f) (file) (bufwin1) (bufwin2))
+    (setq f (file-truename (car ns-input-file)))
+    (setq ns-input-file (cdr ns-input-file))
+    (setq file (find-file-noselect f))
+    (setq bufwin1 (get-buffer-window file 'visible))
+    (setq bufwin2 (get-buffer-window "*scratch*" 'visibile))
+    (cond
+     (bufwin1
+      (select-frame (window-frame bufwin1))
+      (raise-frame (window-frame bufwin1))
+      (select-window bufwin1))
+     ((and (eq ns-pop-up-frames 'fresh) bufwin2)
+      (ns-hide-emacs 'activate)
+      (select-frame (window-frame bufwin2))
+      (raise-frame (window-frame bufwin2))
+      (select-window bufwin2)
+      (find-file f))
+     (ns-pop-up-frames
+      (ns-hide-emacs 'activate)
+      (let ((pop-up-frames t)) (pop-to-buffer file nil)))
+     (t
+      (ns-hide-emacs 'activate)
+      (find-file f)))))
+
+
+
+;;;; Frame-related functions.
+
+;; Don't show the frame name; that's redundant with NS.
+(setq-default mode-line-frame-identification '("  "))
+
+(defvar ns-pop-up-frames 'fresh
+  "* Should file opened upon request from the Workspace be opened in a new frame ?
+If t, always.  If nil, never.  Otherwise a new frame is opened
+unless the current buffer is a scratch buffer.")
+
+;; You say tomAYto, I say tomAHto..
+(defvaralias 'ns-option-modifier 'ns-alternate-modifier)
+
+(defun ns-do-hide-emacs ()
+  (interactive)
+  (ns-hide-emacs t))
+
+(defun ns-do-hide-others ()
+  (interactive)
+  (ns-hide-others))
+
+(defun ns-do-emacs-info-panel ()
+  (interactive)
+  (ns-emacs-info-panel))
+
+(defun ns-next-frame ()
+  "Switch to next visible frame."
+  (interactive)
+  (other-frame 1))
+(defun ns-prev-frame ()
+  "Switch to previous visible frame."
+  (interactive)
+  (other-frame -1))
+
+; If no position specified, make new frame offset by 25 from current.
+(add-hook 'before-make-frame-hook
+          '(lambda ()
+             (let ((left (cdr (assq 'left (frame-parameters))))
+                   (top (cdr (assq 'top (frame-parameters)))))
+	       (if (consp left) (setq left (cadr left)))
+	       (if (consp top) (setq top (cadr top)))
+               (cond
+                ((or (assq 'top parameters) (assq 'left parameters)))
+                ((or (not left) (not top)))
+                (t
+                 (setq parameters (cons (cons 'left (+ left 25))
+                                        (cons (cons 'top (+ top 25))
+                                              parameters))))))))
+
+; frame will be focused anyway, so select it
+(add-hook 'after-make-frame-functions 'select-frame)
+
+;;; (defun ns-win-suspend-error ()
+;;;   (error "Suspending an emacs running under *Step/OS X makes no sense"))
+;;; (add-hook 'suspend-hook 'ns-win-suspend-error)
+;;; (substitute-key-definition 'suspend-emacs 'iconify-or-deiconify-frame
+;;; 			   global-map)
+
+;; Based on a function by David Reitter <dreitter@inf.ed.ac.uk> ;
+;; see http://lists.gnu.org/archive/html/emacs-devel/2005-09/msg00681.html .
+(defun ns-toggle-toolbar (&optional frame)
+  "Switches the tool bar on and off in frame FRAME.
+ If FRAME is nil, the change applies to the selected frame."
+  (interactive)
+  (modify-frame-parameters frame
+	   (list (cons 'tool-bar-lines
+		       (if (> (or (frame-parameter frame 'tool-bar-lines) 0) 0)
+				   0 1)) ))
+  (if (not tool-bar-mode) (tool-bar-mode t)))
+
+; Redefine from frame.el
+(define-minor-mode blink-cursor-mode
+  "Toggle blinking cursor mode.
+With a numeric argument, turn blinking cursor mode on if ARG is positive,
+otherwise turn it off.  When blinking cursor mode is enabled, the
+cursor of the selected window blinks.
+
+Note that this command is effective only when Emacs
+displays through a window system, because then Emacs does its own
+cursor display.  On a text-only terminal, this is not implemented."
+  :init-value (not (or noninteractive
+		       no-blinking-cursor
+		       (eq ns-cursor-blink-rate nil)))
+  :initialize 'custom-initialize-safe-default
+  :group 'cursor
+  :global t
+  (if blink-cursor-mode
+      (setq ns-cursor-blink-mode t)
+      (setq ns-cursor-blink-mode nil)))
+
+
+
+;;;; Dialog-related functions.
+
+;; Ask user for confirm before printing.  Due to Kevin Rodgers.
+(defun ns-print-buffer ()
+  "Interactive front-end to `print-buffer': asks for user confirmation first."
+  (interactive)
+  (if (and (interactive-p)
+	     (or (listp last-nonmenu-event)
+		 (and (char-or-string-p (event-basic-type last-command-event))
+		      (memq 'super (event-modifiers last-command-event)))))
+    (let ((last-nonmenu-event (if (listp last-nonmenu-event)
+				  last-nonmenu-event
+				;; fake it:
+				`(mouse-1 POSITION 1))))
+      (if (y-or-n-p (format "Print buffer %s? " (buffer-name)))
+	  (print-buffer)
+	  (error "Cancelled")))
+    (print-buffer)))
+
+(defun ns-yes-or-no-p (prompt)
+  "As yes-or-no-p except that NS panel always used for querying."
+  (interactive)
+    (setq last-nonmenu-event nil)
+    (yes-or-no-p prompt))
+
+
+;;;; Font support.
+
+(defalias 'x-list-fonts 'ns-list-fonts)
+;; Needed for font listing functions under both backend and normal
+(setq scalable-fonts-allowed t)
+
+;; Set to use font panel instead
+(defalias 'generate-fontset-menu 'ns-popup-font-panel)
+(defalias 'mouse-set-font 'ns-popup-font-panel)
+
+(defun ns-respond-to-change-font ()
+  "Respond to changeFont: event, expecting ns-input-font and\n\
+ns-input-fontsize of new font."
+  (interactive)
+  (modify-frame-parameters (selected-frame)
+                           (list (cons 'font ns-input-font)
+                                 (cons 'fontsize ns-input-fontsize)))
+  (set-frame-font ns-input-font))
+
+
+;; Default fontset for Mac OS X.  This is mainly here to show how a fontset
+;; can be set up manually.  Ordinarily, fontsets are auto-created whenever
+;; a font is chosen by 
+(defvar ns-standard-fontset-spec
+; Only some code supports this so far, so use uglier XLFD version
+; "-ns-*-*-*-*-*-10-*-*-*-*-*-fontset-standard,latin:Courier,han:Kai"
+"-ns-*-*-*-*-*-10-*-*-*-*-*-fontset-standard,latin:-*-Courier-*-*-*-*-10-*-*-*-*-*-iso10646-1,han:-*-Kai-*-*-*-*-10-*-*-*-*-*-iso10646-1,cyrillic:-*-Trebuchet$MS-*-*-*-*-10-*-*-*-*-*-iso10646-1"
+ "String of fontset spec of the standard fontset.
+This defines a fontset consisting of the Courier and other fonts that
+come with OS X\".
+See the documentation of `create-fontset-from-fontset-spec for the format.")
+
+;; Conditional on new-fontset so bootstrapping works on non-GUI compiles
+(if (fboundp 'new-fontset)
+    (progn
+      ;; Setup the default fontset.
+      (setup-default-fontset)
+      ;; Create the standard fontset.
+      (create-fontset-from-fontset-spec ns-standard-fontset-spec t)
+))
+
+;(setq default-frame-alist (cons (cons 'font "-ns-*-*-*-*-*-10-*-*-*-*-*-fontset-standard") default-frame-alist))
+
+;; add some additional scripts to var we use for fontset generation
+(setq script-representative-chars
+      (cons '(kana #xff8a)
+	    (cons '(symbol #x2295 #x2287 #x25a1)
+		 script-representative-chars)))
+
+
+;;;; Pasteboard support.
+
+(defun ns-get-pasteboard ()
+  "Returns the value of the pasteboard."
+  (ns-get-cut-buffer-internal 'PRIMARY))
+
+(defun ns-set-pasteboard (string)
+  "Store STRING into the NS server's pasteboard."
+  ;; Check the data type of STRING.
+  (if (not (stringp string)) (error "Nonstring given to pasteboard"))
+  (ns-store-cut-buffer-internal 'PRIMARY string))
+
+;;; We keep track of the last text selected here, so we can check the
+;;; current selection against it, and avoid passing back our own text
+;;; from ns-pasteboard-value.
+(defvar ns-last-selected-text nil)
+
+;;; Put TEXT, a string, on the pasteboard.
+(defun ns-select-text (text &optional push)
+  ;; Don't send the pasteboard too much text.
+  ;; It becomes slow, and if really big it causes errors.
+  (ns-set-pasteboard text)
+  (setq ns-last-selected-text text))
+
+;;; Return the value of the current NS selection.  For compatibility
+;;; with older NS applications, this checks cut buffer 0 before
+;;; retrieving the value of the primary selection.
+(defun ns-pasteboard-value ()
+  (let (text)
+    
+    ;; Consult the selection, then the cut buffer.  Treat empty strings
+    ;; as if they were unset.
+    (or text (setq text (ns-get-pasteboard)))
+    (if (string= text "") (setq text nil))
+    
+    (cond
+     ((not text) nil)
+     ((eq text ns-last-selected-text) nil)
+     ((string= text ns-last-selected-text)
+      ;; Record the newer string, so subsequent calls can use the `eq' test.
+      (setq ns-last-selected-text text)
+      nil)
+     (t
+      (setq ns-last-selected-text text)))))
+
+(defun ns-copy-including-secondary ()
+  (interactive)
+  (call-interactively 'kill-ring-save)
+  (ns-store-cut-buffer-internal 'SECONDARY
+				(buffer-substring (point) (mark t))))
+(defun ns-paste-secondary ()
+  (interactive)
+  (insert (ns-get-cut-buffer-internal 'SECONDARY)))
+
+;; PENDING: not sure what to do here.. for now interprog- are set in
+;; init-fn-keys, and unsure whether these x- settings have an effect
+;;(setq interprogram-cut-function 'ns-select-text
+;;      interprogram-paste-function 'ns-pasteboard-value)
+; these only needed if above not working
+(defalias 'x-select-text 'ns-select-text)
+(defalias 'x-cut-buffer-or-selection-value 'ns-pasteboard-value)
+(defalias 'x-disown-selection-internal 'ns-disown-selection-internal)
+(defalias 'x-get-selection-internal 'ns-get-selection-internal)
+(defalias 'x-own-selection-internal 'ns-own-selection-internal)
+
+(set-face-background 'region "ns_selection_color")
+
+
+
+;;;; Scrollbar handling.
+
+(global-set-key [vertical-scroll-bar down-mouse-1] 'ns-handle-scroll-bar-event)
+(global-unset-key [vertical-scroll-bar mouse-1])
+(global-unset-key [vertical-scroll-bar drag-mouse-1])
+
+(defun ns-scroll-bar-move (event)
+  "Scroll the frame according to an NS scroller event."
+  (interactive "e")
+  (let* ((pos (event-end event))
+         (window (nth 0 pos))
+         (scale (nth 2 pos)))
+    (save-excursion
+      (set-buffer (window-buffer window))
+      (cond
+       ((eq (car scale) (cdr scale))
+	(goto-char (point-max)))
+       ((= (car scale) 0)
+	(goto-char (point-min)))
+       (t
+	(goto-char (+ (point-min) 1
+		      (scroll-bar-scale scale (- (point-max) (point-min)))))))
+      (beginning-of-line)
+      (set-window-start window (point))
+      (vertical-motion (/ (window-height window) 2) window))))
+
+(defun ns-handle-scroll-bar-event (event)
+  "Handle scroll bar EVENT to emulate Mac Toolbox style scrolling."
+  (interactive "e")
+  (let* ((position (event-start event))
+	 (bar-part (nth 4 position))
+	 (window (nth 0 position))
+	 (old-window (selected-window)))
+    (cond
+     ((eq bar-part 'ratio)
+      (ns-scroll-bar-move event))
+     ((eq bar-part 'handle)
+      (if (eq window (selected-window))
+	  (track-mouse (ns-scroll-bar-move event))
+	; track-mouse faster for selected window, slower for unselected
+	(ns-scroll-bar-move event)))
+     (t
+      (select-window window)
+      (cond
+       ((eq bar-part 'up)
+	(goto-char (window-start window))
+	(scroll-down 1))
+       ((eq bar-part 'above-handle)
+	(scroll-down))
+       ((eq bar-part 'below-handle)
+	(scroll-up))
+       ((eq bar-part 'down)
+	(goto-char (window-start window))
+	(scroll-up 1)))
+      (select-window old-window)))))
+
+
+;;;; Color support.
+
+(defvar x-colors (ns-list-colors)
+  "The list of colors defined in non-PANTONE color files.")
+(defvar colors x-colors
+  "The list of colors defined in non-PANTONE color files.")
+
+(defun ns-defined-colors (&optional frame)
+  "Return a list of colors supported for a particular frame.
+The argument FRAME specifies which frame to try.
+The value may be different for frames on different NS displays."
+  (or frame (setq frame (selected-frame)))
+  (let ((all-colors x-colors)
+	(this-color nil)
+	(defined-colors nil))
+    (while all-colors
+      (setq this-color (car all-colors)
+	    all-colors (cdr all-colors))
+;      (and (face-color-supported-p frame this-color t)
+      (setq defined-colors (cons this-color defined-colors)))
+;)
+    defined-colors))
+(defalias 'x-defined-colors 'ns-defined-colors)
+(defalias 'xw-defined-colors 'ns-defined-colors)
+
+;; Convenience and work-around for fact that set color fns now require named.
+(defun ns-set-background-alpha (alpha)
+  "Sets alpha (opacity) of background.
+Set from 0.0 (fully transparent) to 1.0 (fully opaque; default).
+Note, tranparency works better on Tiger (10.4) and higher."
+  (interactive "nSet background alpha to: ")
+  (let ((bgcolor (cdr (assq 'background-color (frame-parameters)))))
+    (set-frame-parameter (selected-frame)
+			 'background-color (ns-set-alpha bgcolor alpha))))
+
+;; Functions for color panel + drag
+(defun ns-face-at-pos (pos)
+  (let* ((frame (car pos))
+         (frame-pos (cons (cadr pos) (cddr pos)))
+         (window (window-at (car frame-pos) (cdr frame-pos) frame))
+         (window-pos (coordinates-in-window-p frame-pos window))
+         (buffer (window-buffer window))
+         (edges (window-edges window)))
+    (cond
+     ((not window-pos)
+      nil)
+     ((eq window-pos 'mode-line)
+      'modeline)
+     ((eq window-pos 'vertical-line)
+      'default)
+     ((consp window-pos)
+      (save-excursion
+        (set-buffer buffer)
+        (let ((p (car (compute-motion (window-start window)
+                                      (cons (nth 0 edges) (nth 1 edges))
+                                      (window-end window)
+                                      frame-pos
+                                      (- (window-width window) 1)
+                                      nil
+                                      window))))
+          (cond
+           ((eq p (window-point window))
+            'cursor)
+           ((and mark-active (< (region-beginning) p) (< p (region-end)))
+            'region)
+           (t
+	    (let ((faces (get-char-property p 'face window)))
+	      (if (consp faces) (car faces) faces)))))))
+     (t
+      nil))))
+
+(defun ns-set-foreground-at-mouse ()
+  "Set the foreground color at the mouse location to ns-input-color."
+  (interactive)
+  (let* ((pos (mouse-position))
+         (frame (car pos))
+         (face (ns-face-at-pos pos)))
+    (cond
+     ((eq face 'cursor)
+      (modify-frame-parameters frame (list (cons 'cursor-color 
+                                                 ns-input-color))))
+     ((not face)
+      (modify-frame-parameters frame (list (cons 'foreground-color
+                                                 ns-input-color))))
+     (t
+      (set-face-foreground face ns-input-color frame)))))
+
+(defun ns-set-background-at-mouse ()
+  "Set the background color at the mouse location to ns-input-color."
+  (interactive)
+  (let* ((pos (mouse-position))
+         (frame (car pos))
+         (face (ns-face-at-pos pos)))
+    (cond
+     ((eq face 'cursor)
+      (modify-frame-parameters frame (list (cons 'cursor-color
+                                                 ns-input-color))))
+     ((not face)
+      (modify-frame-parameters frame (list (cons 'background-color
+                                                 ns-input-color))))
+     (t
+      (set-face-background face ns-input-color frame)))))
+
+
+
+;; Misc aliases
+(defalias 'x-display-mm-width 'ns-display-mm-width)
+(defalias 'x-display-mm-height 'ns-display-mm-height)
+(defalias 'x-display-backing-store 'ns-display-backing-store)
+(defalias 'x-display-save-under 'ns-display-save-under)
+(defalias 'x-display-visual-class 'ns-display-visual-class)
+(defalias 'x-display-screens 'ns-display-screens)
+(defalias 'x-focus-frame 'ns-focus-frame)
+
+;; Set some options to be as NS-like as possible.
+(setq frame-title-format t
+      icon-title-format t)
+
+;; Set up browser connectivity
+(setq browse-url-browser-function 'browse-url-generic)
+(cond ((eq system-type 'darwin)
+       (setq browse-url-generic-program "open"))
+      ;; otherwise, gnustep
+      (t
+       (setq browse-url-generic-program "gopen")) )
+
+
+(defvar ns-initialized nil
+  "Non-nil if NS windowing has been initialized.")
+
+;;; Do the actual NS Windows setup here; the above code just defines
+;;; functions and variables that we use now.
+(defun ns-initialize-window-system ()
+  "Initialize Emacs for NS (Cocoa / GNUstep) windowing."
+
+  ; PENDING: not needed?
+  (setq command-line-args (ns-handle-args command-line-args))
+
+  (ns-open-connection (system-name) nil t)
+
+  (let ((services (ns-list-services)))
+    (while services
+      (if (eq (caar services) 'undefined)
+	  (ns-define-service (cdar services))
+	(define-key global-map (vector (caar services))
+	  (ns-define-service (cdar services)))
+	)
+      (setq services (cdr services))))
+
+  (if (and (eq (get-lisp-resource nil "NXAutoLaunch") t)
+	   (eq (get-lisp-resource nil "HideOnAutoLaunch") t))
+      (add-hook 'after-init-hook 'ns-do-hide-emacs))
+
+  (menu-bar-mode (if (get-lisp-resource nil "Menus") 1 -1))
+  (mouse-wheel-mode 1)
+
+  (setq ns-initialized t))
+
+(add-to-list 'handle-args-function-alist '(ns . ns-handle-args))
+(add-to-list 'frame-creation-function-alist '(ns . x-create-frame-with-faces))
+(add-to-list 'window-system-initialization-alist '(ns . ns-initialize-window-system))
+
+
+(provide 'ns-win)
+
+;;; ns-win.el ends here
--- a/lisp/version.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/version.el	Tue Jul 15 18:15:18 2008 +0000
@@ -65,6 +65,8 @@
 		       ((featurep 'gtk)
 			(concat ", GTK+ Version " gtk-version-string))
 		       ((featurep 'x-toolkit) ", X toolkit")
+		       ((featurep 'ns-windowing)
+			(format ", *Step %s" ns-version-string))
 		       ((boundp 'mac-carbon-version-string)
 			(concat ", Carbon Version " mac-carbon-version-string))
 		       (t ""))
--- a/lisp/woman.el	Tue Jul 15 15:45:05 2008 +0000
+++ b/lisp/woman.el	Tue Jul 15 18:15:18 2008 +0000
@@ -545,9 +545,11 @@
 
 (defcustom woman-man.conf-path
   (let ((path '("/usr/lib" "/etc")))
-    (if (eq system-type 'windows-nt)
-	(mapcar 'woman-Cyg-to-Win path)
-      path))
+    (cond ((eq system-type 'windows-nt)
+	   (mapcar 'woman-Cyg-to-Win path))
+	  ((eq system-type 'darwin)
+	   (cons "/usr/share/misc" path))
+	  (t path)))
   "List of dirs to search and/or files to try for man config file.
 A trailing separator (`/' for UNIX etc.) on directories is
 optional, and the filename is used if a directory specified is
@@ -860,7 +862,7 @@
 
 (defcustom woman-use-own-frame		; window-system
   (or (and (fboundp 'display-graphic-p) (display-graphic-p)) ; Emacs 21
-      (memq window-system '(x w32)))	; Emacs 20
+      (memq window-system '(x w32 ns)))	; Emacs 20
   "If non-nil then use a dedicated frame for displaying WoMan windows.
 Only useful when run on a graphic display such as X or MS-Windows."
   :type 'boolean
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/AUTHORS	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,42 @@
+In addition to the folks listed in ../AUTHORS responsible for GNU Emacs itself,
+the NeXTstep port owes to the following people:
+
+Carl Edman
+    original author and maintainer, mainly UI
+Michael Brouwer
+    heavy contributor, input handling and other areas
+Christian Limpach
+    help / maintenance on NeXTstep
+Scott Bender
+    OpenStep, Rhapsody ports
+Christophe de Dinechin
+    MacOS X port
+Adrian Robert
+    GNUstep port*, update Emacs 20 -> 21+
+
+Joe Reiss
+    popup menu, dialog boxes; icons
+Andrew Athan
+    font panel integration
+Scott Byer
+    improved rendering code
+Scott Hess
+    keyboard handling suggestions
+
+Rahul Abrol
+    "hide others" patch
+Adam Ratcliffe
+    preferences panel documentation
+Peter Dyballa
+    assistance with non-ASCII rendering and keyboard handling
+David M. Cooke
+    fix to XPM crash bug
+Carsten Bormann
+    initial patch and assistance getting dired working for non-ASCII filenames
+Andrew Moore
+    assistance on ns-mark-nav extension
+
+(*)
+The GNUstep port was made possible through the assistance of Adam Fedor, Fred
+Kiefer, M. Uli Klusterer, Alexander Malmberg, Jonas Matton, and Riccardo
+Mottola.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/ChangeLog	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,46 @@
+2008-07-15  Adrian Robert <Adrian.B.Robert@gmail.com>
+
+	New directory with support files to support NeXTstep window system.
+
+	* AUTHORS: New file: contributor information for NS port.
+	* ChangeLog.nextstep: New file: changelog info to be added to
+	various directories on merge.
+	* ChangeLog: New file: recent history of the NS port itself.
+	* Cocoa: New directory: support files for building .app
+	package on OS X systems.
+	* Cocoa/Emacs.base
+	* Cocoa/Emacs.base/Contents: New directories.
+	* Cocoa/Emacs.base/Contents/Info.plist
+	* Cocoa/Emacs.base/Contents/PkgInfo: New files.
+	* Cocoa/Emacs.base/Contents/Resources: New directory.
+	* Cocoa/Emacs.base/Contents/Resources/Credits.html: New file:
+	About popup support.
+	* Cocoa/Emacs.base/Contents/Resources/Emacs.icns: New file:
+	copied from Carbon port.
+	* Cocoa/Emacs.base/Contents/Resources/English.lproj: New
+	directory.
+	* Cocoa/Emacs.base/Contents/Resources/English.lproj/InfoPlist.strings:
+	New file.
+	* Cocoa/Emacs.base/Contents/Resources/preferences.nib: New
+	directory.
+	* Cocoa/Emacs.base/Contents/Resources/preferences.nib/classes.nib
+	* Cocoa/Emacs.base/Contents/Resources/preferences.nib/info.nib
+	* Cocoa/Emacs.base/Contents/Resources/preferences.nib/keyedobjects.nib:
+	New files.
+	* Cocoa/Emacs.xcodeproj: New directory: build support.
+	* Cocoa/Emacs.xcodeproj/project.pbxproj: New file.
+	* GNUstep: New directory: support files for building .app
+	package on GNUstep systems.
+	* GNUstep/Resources: New directory.
+	* GNUstep/Resources/Emacs.desktop
+	* GNUstep/Resources/Info-gnustep.plist
+	* GNUstep/Resources/emacs.tiff: New files.
+	* GNUstep/Resources/preferences.gorm: New directory.
+	* GNUstep/Resources/preferences.gorm/data.classes
+	* GNUstep/Resources/preferences.gorm/data.info
+	* GNUstep/Resources/preferences.gorm/objects.gorm: New
+	files.
+	* compile: New file: utility script for building Emacs.app.
+	* FOR_RELEASE: New file: release tasks specific to NeXTstep
+	port.
+	* README.txt: New file: descriptive info for NeXTstep port.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/Cocoa/Emacs.base/Contents/Info.plist	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDocumentTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>txt</string>
+			</array>
+			<key>CFBundleTypeName</key>
+			<string>Text</string>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>c</string>
+				<string>h</string>
+			</array>
+			<key>CFBundleTypeName</key>
+			<string>C</string>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>C</string>
+				<string>H</string>
+				<string>cpp</string>
+				<string>cc</string>
+				<string>hh</string>
+			</array>
+			<key>CFBundleTypeName</key>
+			<string>C++</string>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>m</string>
+			</array>
+			<key>CFBundleTypeName</key>
+			<string>Objective C</string>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>el</string>
+			</array>
+			<key>CFBundleTypeName</key>
+			<string>Lisp</string>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>xml</string>
+				<string>xhtml</string>
+				<string>xsl</string>
+				<string>xsd</string>
+				<string>xsdl</string>
+			</array>
+			<key>CFBundleTypeName</key>
+			<string>XML</string>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>java</string>
+			</array>
+			<key>CFBundleTypeName</key>
+			<string>Java</string>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>tex</string>
+				<string>ltx</string>
+				<string>bib</string>
+				<string>bbl</string>
+			</array>
+			<key>CFBundleTypeName</key>
+			<string>TeX/LaTeX</string>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>CFBundleTypeExtensions</key>
+			<array>
+				<string>*</string>
+			</array>
+			<key>CFBundleTypeName</key>
+			<string>Any</string>
+			<key>CFBundleTypeOSTypes</key>
+			<array>
+				<string>****</string>
+			</array>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+		</dict>
+	</array>
+
+	<key>NSServices</key>
+	<array>
+		<dict>
+			<key>NSMenuItem</key>
+			<dict>
+				<key>default</key>
+				<string>Emacs.app/New Buffer Containing Selection</string>
+			</dict>
+			<key>NSMessage</key>
+			<string>requestService</string>
+			<key>NSUserData</key>
+			<string>open-selection</string>
+			<key>NSPortName</key>
+			<string>Emacs</string>
+			<key>NSSendTypes</key>
+			<array>
+				<string>NSStringPboardType</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSMenuItem</key>
+			<dict>
+				<key>default</key>
+				<string>Emacs.app/Open Selected File</string>
+			</dict>
+			<key>NSMessage</key>
+			<string>requestService</string>
+			<key>NSUserData</key>
+			<string>open-file</string>
+			<key>NSPortName</key>
+			<string>Emacs</string>
+			<key>NSSendTypes</key>
+			<array>
+				<string>NSStringPboardType</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSMenuItem</key>
+			<dict>
+				<key>default</key>
+				<string>Emacs.app/Email Selection</string>
+			</dict>
+			<key>NSMessage</key>
+			<string>requestService</string>
+			<key>NSUserData</key>
+			<string>mail-selection</string>
+			<key>NSPortName</key>
+			<string>Emacs</string>
+			<key>NSSendTypes</key>
+			<array>
+				<string>NSStringPboardType</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSMenuItem</key>
+			<dict>
+				<key>default</key>
+				<string>Emacs.app/Send Email to Selected Address</string>
+			</dict>
+			<key>NSMessage</key>
+			<string>requestService</string>
+			<key>NSUserData</key>
+			<string>mail-to</string>
+			<key>NSPortName</key>
+			<string>Emacs</string>
+			<key>NSSendTypes</key>
+			<array>
+				<string>NSStringPboardType</string>
+			</array>
+		</dict>
+	</array>
+
+	<key>CFBundleExecutable</key>
+	<string>Emacs</string>
+	<key>CFBundleGetInfoString</key>
+	<string>Emacs 23.0.60 (C) Free Software Foundation</string>
+	<key>CFBundleIconFile</key>
+	<string>Emacs</string>
+	<key>CFBundleIdentifier</key>
+	<string>Emacs</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>Emacs</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>Version 23.0.60</string>
+	<key>CFBundleSignature</key>
+	<string>Emcs</string>
+	<key>CFBundleVersion</key>
+	<string>NS 9.0</string>
+	<key>NSPrincipalClass</key>
+	<string>EmacsApp</string>
+</dict>
+</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/Cocoa/Emacs.base/Contents/PkgInfo	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,1 @@
+APPLEmcs
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/Cocoa/Emacs.base/Contents/Resources/Credits.html	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,1 @@
+<font face="lucida grande" size="-1"><a href="http://emacs-app.sf.net">http://emacs-app.sf.net</a></font>
Binary file nextstep/Cocoa/Emacs.base/Contents/Resources/Emacs.icns has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/Cocoa/Emacs.base/Contents/Resources/English.lproj/InfoPlist.strings	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,6 @@
+/* Localized versions of Info.plist keys */
+
+CFBundleName = "Emacs";
+CFBundleShortVersionString = "Version 23.0.60";
+CFBundleGetInfoString = "Emacs version 23.0.60, GNUstep / MacOS X Cocoa version 9.0";
+NSHumanReadableCopyright = "Copyright 2008 Free Software Foundation.";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/Cocoa/Emacs.base/Contents/Resources/preferences.nib/classes.nib	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,32 @@
+{
+    IBClasses = (
+        {
+            ACTIONS = {
+                cancel = id; 
+                ok = id; 
+                resetToDefaults = id; 
+                runHelp = id; 
+                setColors = id; 
+                setDefaultFont = id; 
+            }; 
+            CLASS = EmacsPrefsController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                alternateModMenu = NSPopUpButton; 
+                commandModMenu = NSPopUpButton; 
+                controlModMenu = NSPopUpButton; 
+                cursorBlinkSlider = NSSlider; 
+                cursorTypeMatrix = NSMatrix; 
+                expandSpaceSlider = NSSlider; 
+                functionModMenu = NSPopUpButton; 
+                prefsWindow = NSWindow; 
+                smoothFontsCheck = NSButton; 
+                useQuickdrawCheck = NSButton; 
+                useSysHiliteCheck = NSButton; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/Cocoa/Emacs.base/Contents/Resources/preferences.nib/info.nib	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IBDocumentLocation</key>
+	<string>196 42 356 240 0 0 1440 878 </string>
+	<key>IBFramework Version</key>
+	<string>446.1</string>
+	<key>IBGroupedObjects</key>
+	<dict>
+		<key>5</key>
+		<array>
+			<string>114</string>
+			<string>110</string>
+			<string>111</string>
+			<string>112</string>
+			<string>113</string>
+		</array>
+		<key>6</key>
+		<array>
+			<string>183</string>
+			<string>176</string>
+		</array>
+		<key>7</key>
+		<array>
+			<string>191</string>
+			<string>184</string>
+		</array>
+		<key>9</key>
+		<array>
+			<string>201</string>
+			<string>194</string>
+		</array>
+	</dict>
+	<key>IBLastGroupID</key>
+	<string>10</string>
+	<key>IBOldestOS</key>
+	<integer>3</integer>
+	<key>IBOpenObjects</key>
+	<array>
+		<integer>5</integer>
+	</array>
+	<key>IBSystem Version</key>
+	<string>8R2232</string>
+</dict>
+</plist>
Binary file nextstep/Cocoa/Emacs.base/Contents/Resources/preferences.nib/keyedobjects.nib has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/Cocoa/Emacs.xcodeproj/project.pbxproj	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,848 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 42;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		3C15C0EB0902D89500A8542F /* termhooks.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C02F0902D89500A8542F /* termhooks.h */; };
+		3C15C0EC0902D89500A8542F /* termchar.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0300902D89500A8542F /* termchar.h */; };
+		3C15C0EF0902D89500A8542F /* syswait.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0330902D89500A8542F /* syswait.h */; };
+		3C15C0F00902D89500A8542F /* systty.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0340902D89500A8542F /* systty.h */; };
+		3C15C0F10902D89500A8542F /* systime.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0350902D89500A8542F /* systime.h */; };
+		3C15C0F20902D89500A8542F /* syssignal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0360902D89500A8542F /* syssignal.h */; };
+		3C15C0F30902D89500A8542F /* sysselect.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0370902D89500A8542F /* sysselect.h */; };
+		3C15C0F50902D89500A8542F /* syntax.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0390902D89500A8542F /* syntax.h */; };
+		3C15C0FD0902D89500A8542F /* region-cache.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0410902D89500A8542F /* region-cache.h */; };
+		3C15C0FF0902D89500A8542F /* regex.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0430902D89500A8542F /* regex.h */; };
+		3C15C1020902D89500A8542F /* puresize.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0460902D89500A8542F /* puresize.h */; };
+		3C15C1030902D89500A8542F /* process.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0470902D89500A8542F /* process.h */; };
+		3C15C1080902D89500A8542F /* point.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C04C0902D89500A8542F /* point.h */; };
+		3C15C1090902D89500A8542F /* param.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C04D0902D89500A8542F /* param.h */; };
+		3C15C10B0902D89500A8542F /* nsgui.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C04F0902D89500A8542F /* nsgui.h */; };
+		3C15C10C0902D89500A8542F /* ndir.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0500902D89500A8542F /* ndir.h */; };
+		3C15C1110902D89500A8542F /* mem-limits.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0550902D89500A8542F /* mem-limits.h */; };
+		3C15C1120902D89500A8542F /* md5.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0560902D89500A8542F /* md5.h */; };
+		3C15C1190902D89500A8542F /* macros.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C05D0902D89500A8542F /* macros.h */; };
+		3C15C1220902D89500A8542F /* keymap.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0660902D89500A8542F /* keymap.h */; };
+		3C15C1240902D89500A8542F /* keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0680902D89500A8542F /* keyboard.h */; };
+		3C15C1270902D89500A8542F /* intervals.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C06B0902D89500A8542F /* intervals.h */; };
+		3C15C12A0902D89500A8542F /* indent.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C06E0902D89500A8542F /* indent.h */; };
+		3C15C1320902D89500A8542F /* category.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0760902D89500A8542F /* category.h */; };
+		3C15C1330902D89500A8542F /* coding.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0770902D89500A8542F /* coding.h */; };
+		3C15C1340902D89500A8542F /* buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0780902D89500A8542F /* buffer.h */; };
+		3C15C1350902D89500A8542F /* vlimit.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0790902D89500A8542F /* vlimit.h */; };
+		3C15C1450902D89500A8542F /* cm.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0890902D89500A8542F /* cm.h */; };
+		3C15C14E0902D89500A8542F /* uaf.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0920902D89500A8542F /* uaf.h */; };
+		3C15C1510902D89500A8542F /* termopts.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0950902D89500A8542F /* termopts.h */; };
+		3C15C15C0902D89500A8542F /* window.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0A00902D89500A8542F /* window.h */; };
+		3C15C1720902D89500A8542F /* gnu.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0B60902D89500A8542F /* gnu.h */; };
+		3C15C1740902D89500A8542F /* getpagesize.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0B80902D89500A8542F /* getpagesize.h */; };
+		3C15C17B0902D89500A8542F /* disptab.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0BF0902D89500A8542F /* disptab.h */; };
+		3C15C17E0902D89500A8542F /* epaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0C20902D89500A8542F /* epaths.h */; };
+		3C15C1810902D89500A8542F /* ccl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0C50902D89500A8542F /* ccl.h */; };
+		3C15C1830902D89500A8542F /* composite.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0C70902D89500A8542F /* composite.h */; };
+		3C15C1840902D89500A8542F /* charset.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0C80902D89500A8542F /* charset.h */; };
+		3C15C1850902D89500A8542F /* fontset.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0C90902D89500A8542F /* fontset.h */; };
+		3C15C1930902D89500A8542F /* commands.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0D70902D89500A8542F /* commands.h */; };
+		3C15C1950902D89500A8542F /* dispextern.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0D90902D89500A8542F /* dispextern.h */; };
+		3C15C1970902D89500A8542F /* acldef.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0DB0902D89500A8542F /* acldef.h */; };
+		3C15C19A0902D89500A8542F /* character.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0DE0902D89500A8542F /* character.h */; };
+		3C15C19E0902D89500A8542F /* chpdef.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0E20902D89500A8542F /* chpdef.h */; };
+		3C15C1A00902D89500A8542F /* frame.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0E40902D89500A8542F /* frame.h */; };
+		3C15C1A20902D89500A8542F /* atimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0E60902D89500A8542F /* atimer.h */; };
+		3C15C1A30902D89500A8542F /* blockinput.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C15C0E70902D89500A8542F /* blockinput.h */; };
+		3C15C1A80902D97100A8542F /* nsimage.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C15C1A70902D97100A8542F /* nsimage.m */; };
+		3C4D6D6B0DE50D2300B20D4E /* font.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C4D6D660DE50D2300B20D4E /* font.c */; };
+		3C4D6D6C0DE50D2300B20D4E /* font.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C4D6D670DE50D2300B20D4E /* font.h */; };
+		3C4D6D6D0DE50D2300B20D4E /* termcap.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C4D6D680DE50D2300B20D4E /* termcap.c */; };
+		3C4D6D6E0DE50D2300B20D4E /* terminal.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C4D6D690DE50D2300B20D4E /* terminal.c */; };
+		3C4D6D6F0DE50D2300B20D4E /* tparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C4D6D6A0DE50D2300B20D4E /* tparam.c */; };
+		3C4D6D730DE50D5D00B20D4E /* nsfont.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C4D6D710DE50D5D00B20D4E /* nsfont.m */; };
+		3C7F3C3B07EB3B05003C8A4D /* nsterm.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C7F3C3A07EB3B05003C8A4D /* nsterm.h */; };
+		3CB8E29A0E2CE6BF003F3104 /* preferences.nib in Resources */ = {isa = PBXBuildFile; fileRef = 3CB8E2990E2CE6BF003F3104 /* preferences.nib */; };
+		3CB8E29E0E2CE73A003F3104 /* Emacs.icns in Resources */ = {isa = PBXBuildFile; fileRef = 3CB8E29D0E2CE73A003F3104 /* Emacs.icns */; };
+		3CB8E2A00E2CE7F5003F3104 /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = 3CB8E29F0E2CE7F5003F3104 /* Credits.html */; };
+		3CB8E2A70E2CE856003F3104 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3CB8E2A50E2CE856003F3104 /* InfoPlist.strings */; };
+		3CC5430607E2315800C271A9 /* nsfns.m in Sources */ = {isa = PBXBuildFile; fileRef = 090AF67E00C61DCD7F000001 /* nsfns.m */; };
+		3CC5430707E2315800C271A9 /* nsmenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 090AF68000C61DCD7F000001 /* nsmenu.m */; };
+		3CC5430807E2315800C271A9 /* nsselect.m in Sources */ = {isa = PBXBuildFile; fileRef = 090AF68100C61DCD7F000001 /* nsselect.m */; };
+		3CC5430907E2315800C271A9 /* nsterm.m in Sources */ = {isa = PBXBuildFile; fileRef = 090AF68300C61DCD7F000001 /* nsterm.m */; };
+		3CDCED340902E99700B2EF7E /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CDCED330902E99700B2EF7E /* config.h */; };
+		3CDCEDD00902EA8200B2EF7E /* term.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED550902EA8100B2EF7E /* term.c */; };
+		3CDCEDD10902EA8200B2EF7E /* sysdep.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED560902EA8100B2EF7E /* sysdep.c */; };
+		3CDCEDD20902EA8200B2EF7E /* syntax.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED570902EA8100B2EF7E /* syntax.c */; };
+		3CDCEDD40902EA8200B2EF7E /* strftime.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED590902EA8100B2EF7E /* strftime.c */; };
+		3CDCEDD50902EA8200B2EF7E /* sound.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED5A0902EA8100B2EF7E /* sound.c */; };
+		3CDCEDD70902EA8200B2EF7E /* search.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED5C0902EA8100B2EF7E /* search.c */; };
+		3CDCEDD80902EA8200B2EF7E /* scroll.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED5D0902EA8100B2EF7E /* scroll.c */; };
+		3CDCEDD90902EA8200B2EF7E /* region-cache.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED5E0902EA8100B2EF7E /* region-cache.c */; };
+		3CDCEDDA0902EA8200B2EF7E /* regex.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED5F0902EA8100B2EF7E /* regex.c */; };
+		3CDCEDDC0902EA8200B2EF7E /* process.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED610902EA8100B2EF7E /* process.c */; };
+		3CDCEDDD0902EA8200B2EF7E /* print.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED620902EA8100B2EF7E /* print.c */; };
+		3CDCEDDF0902EA8200B2EF7E /* pre-crt0.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED640902EA8100B2EF7E /* pre-crt0.c */; };
+		3CDCEDE20902EA8200B2EF7E /* minibuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED670902EA8100B2EF7E /* minibuf.c */; };
+		3CDCEDE30902EA8200B2EF7E /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED680902EA8100B2EF7E /* md5.c */; };
+		3CDCEDE40902EA8200B2EF7E /* marker.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED690902EA8100B2EF7E /* marker.c */; };
+		3CDCEDE80902EA8200B2EF7E /* macros.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED6D0902EA8100B2EF7E /* macros.c */; };
+		3CDCEDEC0902EA8200B2EF7E /* lread.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED710902EA8100B2EF7E /* lread.c */; };
+		3CDCEDED0902EA8200B2EF7E /* lastfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED720902EA8100B2EF7E /* lastfile.c */; };
+		3CDCEDEE0902EA8200B2EF7E /* keymap.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED730902EA8100B2EF7E /* keymap.c */; };
+		3CDCEDEF0902EA8200B2EF7E /* keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED740902EA8200B2EF7E /* keyboard.c */; };
+		3CDCEDF00902EA8200B2EF7E /* intervals.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED750902EA8200B2EF7E /* intervals.c */; };
+		3CDCEDF10902EA8200B2EF7E /* insdel.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED760902EA8200B2EF7E /* insdel.c */; };
+		3CDCEDF20902EA8200B2EF7E /* indent.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED770902EA8200B2EF7E /* indent.c */; };
+		3CDCEDF30902EA8200B2EF7E /* image.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED780902EA8200B2EF7E /* image.c */; };
+		3CDCEDF50902EA8200B2EF7E /* cmds.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED7A0902EA8200B2EF7E /* cmds.c */; };
+		3CDCEDF60902EA8200B2EF7E /* category.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED7B0902EA8200B2EF7E /* category.c */; };
+		3CDCEDF70902EA8200B2EF7E /* coding.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED7C0902EA8200B2EF7E /* coding.c */; };
+		3CDCEDFE0902EA8200B2EF7E /* unexmacosx.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED830902EA8200B2EF7E /* unexmacosx.c */; };
+		3CDCEE060902EA8200B2EF7E /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED8B0902EA8200B2EF7E /* buffer.c */; };
+		3CDCEE070902EA8200B2EF7E /* character.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED8C0902EA8200B2EF7E /* character.c */; };
+		3CDCEE0D0902EA8200B2EF7E /* undo.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED920902EA8200B2EF7E /* undo.c */; };
+		3CDCEE0F0902EA8200B2EF7E /* textprop.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED940902EA8200B2EF7E /* textprop.c */; };
+		3CDCEE100902EA8200B2EF7E /* terminfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED950902EA8200B2EF7E /* terminfo.c */; };
+		3CDCEE170902EA8200B2EF7E /* xfaces.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED9C0902EA8200B2EF7E /* xfaces.c */; };
+		3CDCEE180902EA8200B2EF7E /* xdisp.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED9D0902EA8200B2EF7E /* xdisp.c */; };
+		3CDCEE190902EA8200B2EF7E /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCED9E0902EA8200B2EF7E /* window.c */; };
+		3CDCEE2B0902EA8200B2EF7E /* doprnt.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDB00902EA8200B2EF7E /* doprnt.c */; };
+		3CDCEE2C0902EA8200B2EF7E /* doc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDB10902EA8200B2EF7E /* doc.c */; };
+		3CDCEE2D0902EA8200B2EF7E /* dired.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDB20902EA8200B2EF7E /* dired.c */; };
+		3CDCEE2E0902EA8200B2EF7E /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDB30902EA8200B2EF7E /* data.c */; };
+		3CDCEE2F0902EA8200B2EF7E /* callint.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDB40902EA8200B2EF7E /* callint.c */; };
+		3CDCEE310902EA8200B2EF7E /* ccl.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDB60902EA8200B2EF7E /* ccl.c */; };
+		3CDCEE320902EA8200B2EF7E /* fontset.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDB70902EA8200B2EF7E /* fontset.c */; };
+		3CDCEE330902EA8200B2EF7E /* fns.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDB80902EA8200B2EF7E /* fns.c */; };
+		3CDCEE340902EA8200B2EF7E /* floatfns.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDB90902EA8200B2EF7E /* floatfns.c */; };
+		3CDCEE360902EA8200B2EF7E /* filemode.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDBB0902EA8200B2EF7E /* filemode.c */; };
+		3CDCEE370902EA8200B2EF7E /* filelock.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDBC0902EA8200B2EF7E /* filelock.c */; };
+		3CDCEE380902EA8200B2EF7E /* emacs.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDBD0902EA8200B2EF7E /* emacs.c */; };
+		3CDCEE390902EA8200B2EF7E /* editfns.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDBE0902EA8200B2EF7E /* editfns.c */; };
+		3CDCEE3A0902EA8200B2EF7E /* fileio.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDBF0902EA8200B2EF7E /* fileio.c */; };
+		3CDCEE3B0902EA8200B2EF7E /* eval.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDC00902EA8200B2EF7E /* eval.c */; };
+		3CDCEE3C0902EA8200B2EF7E /* casetab.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDC10902EA8200B2EF7E /* casetab.c */; };
+		3CDCEE3D0902EA8200B2EF7E /* composite.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDC20902EA8200B2EF7E /* composite.c */; };
+		3CDCEE3E0902EA8200B2EF7E /* dispnew.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDC30902EA8200B2EF7E /* dispnew.c */; };
+		3CDCEE3F0902EA8200B2EF7E /* charset.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDC40902EA8200B2EF7E /* charset.c */; };
+		3CDCEE400902EA8200B2EF7E /* alloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDC50902EA8200B2EF7E /* alloc.c */; };
+		3CDCEE410902EA8200B2EF7E /* bytecode.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDC60902EA8200B2EF7E /* bytecode.c */; };
+		3CDCEE420902EA8200B2EF7E /* callproc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDC70902EA8200B2EF7E /* callproc.c */; };
+		3CDCEE430902EA8200B2EF7E /* cm.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDC80902EA8200B2EF7E /* cm.c */; };
+		3CDCEE440902EA8200B2EF7E /* casefiddle.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDC90902EA8200B2EF7E /* casefiddle.c */; };
+		3CDCEE450902EA8200B2EF7E /* fringe.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDCA0902EA8200B2EF7E /* fringe.c */; };
+		3CDCEE460902EA8200B2EF7E /* frame.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDCB0902EA8200B2EF7E /* frame.c */; };
+		3CDCEE470902EA8200B2EF7E /* chartab.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDCC0902EA8200B2EF7E /* chartab.c */; };
+		3CDCEE480902EA8200B2EF7E /* atimer.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CDCEDCD0902EA8200B2EF7E /* atimer.c */; };
+		3CFDFC3B08E79A6800B05918 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CFDFC3A08E79A6800B05918 /* AppKit.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		090AF67E00C61DCD7F000001 /* nsfns.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = nsfns.m; path = ../../src/nsfns.m; sourceTree = "<group>"; };
+		090AF68000C61DCD7F000001 /* nsmenu.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = nsmenu.m; path = ../../src/nsmenu.m; sourceTree = "<group>"; };
+		090AF68100C61DCD7F000001 /* nsselect.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = nsselect.m; path = ../../src/nsselect.m; sourceTree = "<group>"; };
+		090AF68300C61DCD7F000001 /* nsterm.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = nsterm.m; path = ../../src/nsterm.m; sourceTree = "<group>"; };
+		3C15C02F0902D89500A8542F /* termhooks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = termhooks.h; path = ../../src/termhooks.h; sourceTree = "<group>"; };
+		3C15C0300902D89500A8542F /* termchar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = termchar.h; path = ../../src/termchar.h; sourceTree = "<group>"; };
+		3C15C0330902D89500A8542F /* syswait.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = syswait.h; path = ../../src/syswait.h; sourceTree = "<group>"; };
+		3C15C0340902D89500A8542F /* systty.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = systty.h; path = ../../src/systty.h; sourceTree = "<group>"; };
+		3C15C0350902D89500A8542F /* systime.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = systime.h; path = ../../src/systime.h; sourceTree = "<group>"; };
+		3C15C0360902D89500A8542F /* syssignal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = syssignal.h; path = ../../src/syssignal.h; sourceTree = "<group>"; };
+		3C15C0370902D89500A8542F /* sysselect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sysselect.h; path = ../../src/sysselect.h; sourceTree = "<group>"; };
+		3C15C0390902D89500A8542F /* syntax.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = syntax.h; path = ../../src/syntax.h; sourceTree = "<group>"; };
+		3C15C0410902D89500A8542F /* region-cache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "region-cache.h"; path = "../../src/region-cache.h"; sourceTree = "<group>"; };
+		3C15C0430902D89500A8542F /* regex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = regex.h; path = ../../src/regex.h; sourceTree = "<group>"; };
+		3C15C0460902D89500A8542F /* puresize.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = puresize.h; path = ../../src/puresize.h; sourceTree = "<group>"; };
+		3C15C0470902D89500A8542F /* process.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = process.h; path = ../../src/process.h; sourceTree = "<group>"; };
+		3C15C04C0902D89500A8542F /* point.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = point.h; path = ../../src/point.h; sourceTree = "<group>"; };
+		3C15C04D0902D89500A8542F /* param.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = param.h; path = ../../src/param.h; sourceTree = "<group>"; };
+		3C15C04F0902D89500A8542F /* nsgui.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = nsgui.h; path = ../../src/nsgui.h; sourceTree = "<group>"; };
+		3C15C0500902D89500A8542F /* ndir.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ndir.h; path = ../../src/ndir.h; sourceTree = "<group>"; };
+		3C15C0550902D89500A8542F /* mem-limits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "mem-limits.h"; path = "../../src/mem-limits.h"; sourceTree = "<group>"; };
+		3C15C0560902D89500A8542F /* md5.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = md5.h; path = ../../src/md5.h; sourceTree = "<group>"; };
+		3C15C05D0902D89500A8542F /* macros.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macros.h; path = ../../src/macros.h; sourceTree = "<group>"; };
+		3C15C0660902D89500A8542F /* keymap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = keymap.h; path = ../../src/keymap.h; sourceTree = "<group>"; };
+		3C15C0680902D89500A8542F /* keyboard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = keyboard.h; path = ../../src/keyboard.h; sourceTree = "<group>"; };
+		3C15C06B0902D89500A8542F /* intervals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = intervals.h; path = ../../src/intervals.h; sourceTree = "<group>"; };
+		3C15C06E0902D89500A8542F /* indent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = indent.h; path = ../../src/indent.h; sourceTree = "<group>"; };
+		3C15C0760902D89500A8542F /* category.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = category.h; path = ../../src/category.h; sourceTree = "<group>"; };
+		3C15C0770902D89500A8542F /* coding.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = coding.h; path = ../../src/coding.h; sourceTree = "<group>"; };
+		3C15C0780902D89500A8542F /* buffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = buffer.h; path = ../../src/buffer.h; sourceTree = "<group>"; };
+		3C15C0790902D89500A8542F /* vlimit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = vlimit.h; path = ../../src/vlimit.h; sourceTree = "<group>"; };
+		3C15C0890902D89500A8542F /* cm.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cm.h; path = ../../src/cm.h; sourceTree = "<group>"; };
+		3C15C0920902D89500A8542F /* uaf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = uaf.h; path = ../../src/uaf.h; sourceTree = "<group>"; };
+		3C15C0950902D89500A8542F /* termopts.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = termopts.h; path = ../../src/termopts.h; sourceTree = "<group>"; };
+		3C15C0A00902D89500A8542F /* window.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = window.h; path = ../../src/window.h; sourceTree = "<group>"; };
+		3C15C0B60902D89500A8542F /* gnu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gnu.h; path = ../../src/gnu.h; sourceTree = "<group>"; };
+		3C15C0B80902D89500A8542F /* getpagesize.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = getpagesize.h; path = ../../src/getpagesize.h; sourceTree = "<group>"; };
+		3C15C0BF0902D89500A8542F /* disptab.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = disptab.h; path = ../../src/disptab.h; sourceTree = "<group>"; };
+		3C15C0C20902D89500A8542F /* epaths.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = epaths.h; path = ../../src/epaths.h; sourceTree = "<group>"; };
+		3C15C0C50902D89500A8542F /* ccl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ccl.h; path = ../../src/ccl.h; sourceTree = "<group>"; };
+		3C15C0C70902D89500A8542F /* composite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = composite.h; path = ../../src/composite.h; sourceTree = "<group>"; };
+		3C15C0C80902D89500A8542F /* charset.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = charset.h; path = ../../src/charset.h; sourceTree = "<group>"; };
+		3C15C0C90902D89500A8542F /* fontset.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fontset.h; path = ../../src/fontset.h; sourceTree = "<group>"; };
+		3C15C0D70902D89500A8542F /* commands.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = commands.h; path = ../../src/commands.h; sourceTree = "<group>"; };
+		3C15C0D90902D89500A8542F /* dispextern.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dispextern.h; path = ../../src/dispextern.h; sourceTree = "<group>"; };
+		3C15C0DB0902D89500A8542F /* acldef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = acldef.h; path = ../../src/acldef.h; sourceTree = "<group>"; };
+		3C15C0DE0902D89500A8542F /* character.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = character.h; path = ../../src/character.h; sourceTree = "<group>"; };
+		3C15C0E20902D89500A8542F /* chpdef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = chpdef.h; path = ../../src/chpdef.h; sourceTree = "<group>"; };
+		3C15C0E40902D89500A8542F /* frame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = frame.h; path = ../../src/frame.h; sourceTree = "<group>"; };
+		3C15C0E60902D89500A8542F /* atimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = atimer.h; path = ../../src/atimer.h; sourceTree = "<group>"; };
+		3C15C0E70902D89500A8542F /* blockinput.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = blockinput.h; path = ../../src/blockinput.h; sourceTree = "<group>"; };
+		3C15C1A70902D97100A8542F /* nsimage.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = nsimage.m; path = ../../src/nsimage.m; sourceTree = "<group>"; };
+		3C4D6D660DE50D2300B20D4E /* font.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = font.c; path = ../../src/font.c; sourceTree = SOURCE_ROOT; };
+		3C4D6D670DE50D2300B20D4E /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = font.h; path = ../../src/font.h; sourceTree = SOURCE_ROOT; };
+		3C4D6D680DE50D2300B20D4E /* termcap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = termcap.c; path = ../../src/termcap.c; sourceTree = SOURCE_ROOT; };
+		3C4D6D690DE50D2300B20D4E /* terminal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = terminal.c; path = ../../src/terminal.c; sourceTree = SOURCE_ROOT; };
+		3C4D6D6A0DE50D2300B20D4E /* tparam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tparam.c; path = ../../src/tparam.c; sourceTree = SOURCE_ROOT; };
+		3C4D6D710DE50D5D00B20D4E /* nsfont.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = nsfont.m; path = ../../src/nsfont.m; sourceTree = SOURCE_ROOT; };
+		3C7F3C3A07EB3B05003C8A4D /* nsterm.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = nsterm.h; path = ../../src/nsterm.h; sourceTree = "<group>"; };
+		3CB8E2990E2CE6BF003F3104 /* preferences.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = preferences.nib; path = Emacs.base/Contents/Resources/preferences.nib; sourceTree = "<group>"; };
+		3CB8E29D0E2CE73A003F3104 /* Emacs.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = Emacs.icns; path = Emacs.base/Contents/Resources/Emacs.icns; sourceTree = "<group>"; };
+		3CB8E29F0E2CE7F5003F3104 /* Credits.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = Credits.html; path = Emacs.base/Contents/Resources/Credits.html; sourceTree = "<group>"; };
+		3CB8E2A60E2CE856003F3104 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = InfoPlist.strings; sourceTree = "<group>"; };
+		3CC5434C07E2315800C271A9 /* Emacs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Emacs.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		3CDCED330902E99700B2EF7E /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = config.h; path = ../../src/config.h; sourceTree = "<group>"; };
+		3CDCED550902EA8100B2EF7E /* term.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = term.c; path = ../../src/term.c; sourceTree = "<group>"; };
+		3CDCED560902EA8100B2EF7E /* sysdep.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sysdep.c; path = ../../src/sysdep.c; sourceTree = "<group>"; };
+		3CDCED570902EA8100B2EF7E /* syntax.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = syntax.c; path = ../../src/syntax.c; sourceTree = "<group>"; };
+		3CDCED590902EA8100B2EF7E /* strftime.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = strftime.c; path = ../../src/strftime.c; sourceTree = "<group>"; };
+		3CDCED5A0902EA8100B2EF7E /* sound.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sound.c; path = ../../src/sound.c; sourceTree = "<group>"; };
+		3CDCED5C0902EA8100B2EF7E /* search.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = search.c; path = ../../src/search.c; sourceTree = "<group>"; };
+		3CDCED5D0902EA8100B2EF7E /* scroll.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = scroll.c; path = ../../src/scroll.c; sourceTree = "<group>"; };
+		3CDCED5E0902EA8100B2EF7E /* region-cache.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = "region-cache.c"; path = "../../src/region-cache.c"; sourceTree = "<group>"; };
+		3CDCED5F0902EA8100B2EF7E /* regex.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = regex.c; path = ../../src/regex.c; sourceTree = "<group>"; };
+		3CDCED610902EA8100B2EF7E /* process.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = process.c; path = ../../src/process.c; sourceTree = "<group>"; };
+		3CDCED620902EA8100B2EF7E /* print.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = print.c; path = ../../src/print.c; sourceTree = "<group>"; };
+		3CDCED640902EA8100B2EF7E /* pre-crt0.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = "pre-crt0.c"; path = "../../src/pre-crt0.c"; sourceTree = "<group>"; };
+		3CDCED670902EA8100B2EF7E /* minibuf.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = minibuf.c; path = ../../src/minibuf.c; sourceTree = "<group>"; };
+		3CDCED680902EA8100B2EF7E /* md5.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = md5.c; path = ../../src/md5.c; sourceTree = "<group>"; };
+		3CDCED690902EA8100B2EF7E /* marker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = marker.c; path = ../../src/marker.c; sourceTree = "<group>"; };
+		3CDCED6D0902EA8100B2EF7E /* macros.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = macros.c; path = ../../src/macros.c; sourceTree = "<group>"; };
+		3CDCED710902EA8100B2EF7E /* lread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lread.c; path = ../../src/lread.c; sourceTree = "<group>"; };
+		3CDCED720902EA8100B2EF7E /* lastfile.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lastfile.c; path = ../../src/lastfile.c; sourceTree = "<group>"; };
+		3CDCED730902EA8100B2EF7E /* keymap.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = keymap.c; path = ../../src/keymap.c; sourceTree = "<group>"; };
+		3CDCED740902EA8200B2EF7E /* keyboard.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = keyboard.c; path = ../../src/keyboard.c; sourceTree = "<group>"; };
+		3CDCED750902EA8200B2EF7E /* intervals.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = intervals.c; path = ../../src/intervals.c; sourceTree = "<group>"; };
+		3CDCED760902EA8200B2EF7E /* insdel.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = insdel.c; path = ../../src/insdel.c; sourceTree = "<group>"; };
+		3CDCED770902EA8200B2EF7E /* indent.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = indent.c; path = ../../src/indent.c; sourceTree = "<group>"; };
+		3CDCED780902EA8200B2EF7E /* image.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = image.c; path = ../../src/image.c; sourceTree = "<group>"; };
+		3CDCED7A0902EA8200B2EF7E /* cmds.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cmds.c; path = ../../src/cmds.c; sourceTree = "<group>"; };
+		3CDCED7B0902EA8200B2EF7E /* category.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = category.c; path = ../../src/category.c; sourceTree = "<group>"; };
+		3CDCED7C0902EA8200B2EF7E /* coding.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = coding.c; path = ../../src/coding.c; sourceTree = "<group>"; };
+		3CDCED830902EA8200B2EF7E /* unexmacosx.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = unexmacosx.c; path = ../../src/unexmacosx.c; sourceTree = "<group>"; };
+		3CDCED8B0902EA8200B2EF7E /* buffer.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = buffer.c; path = ../../src/buffer.c; sourceTree = "<group>"; };
+		3CDCED8C0902EA8200B2EF7E /* character.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = character.c; path = ../../src/character.c; sourceTree = "<group>"; };
+		3CDCED920902EA8200B2EF7E /* undo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = undo.c; path = ../../src/undo.c; sourceTree = "<group>"; };
+		3CDCED940902EA8200B2EF7E /* textprop.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = textprop.c; path = ../../src/textprop.c; sourceTree = "<group>"; };
+		3CDCED950902EA8200B2EF7E /* terminfo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = terminfo.c; path = ../../src/terminfo.c; sourceTree = "<group>"; };
+		3CDCED9C0902EA8200B2EF7E /* xfaces.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = xfaces.c; path = ../../src/xfaces.c; sourceTree = "<group>"; };
+		3CDCED9D0902EA8200B2EF7E /* xdisp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = xdisp.c; path = ../../src/xdisp.c; sourceTree = "<group>"; };
+		3CDCED9E0902EA8200B2EF7E /* window.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = window.c; path = ../../src/window.c; sourceTree = "<group>"; };
+		3CDCEDB00902EA8200B2EF7E /* doprnt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = doprnt.c; path = ../../src/doprnt.c; sourceTree = "<group>"; };
+		3CDCEDB10902EA8200B2EF7E /* doc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = doc.c; path = ../../src/doc.c; sourceTree = "<group>"; };
+		3CDCEDB20902EA8200B2EF7E /* dired.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dired.c; path = ../../src/dired.c; sourceTree = "<group>"; };
+		3CDCEDB30902EA8200B2EF7E /* data.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = data.c; path = ../../src/data.c; sourceTree = "<group>"; };
+		3CDCEDB40902EA8200B2EF7E /* callint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = callint.c; path = ../../src/callint.c; sourceTree = "<group>"; };
+		3CDCEDB60902EA8200B2EF7E /* ccl.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ccl.c; path = ../../src/ccl.c; sourceTree = "<group>"; };
+		3CDCEDB70902EA8200B2EF7E /* fontset.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = fontset.c; path = ../../src/fontset.c; sourceTree = "<group>"; };
+		3CDCEDB80902EA8200B2EF7E /* fns.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = fns.c; path = ../../src/fns.c; sourceTree = "<group>"; };
+		3CDCEDB90902EA8200B2EF7E /* floatfns.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = floatfns.c; path = ../../src/floatfns.c; sourceTree = "<group>"; };
+		3CDCEDBB0902EA8200B2EF7E /* filemode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = filemode.c; path = ../../src/filemode.c; sourceTree = "<group>"; };
+		3CDCEDBC0902EA8200B2EF7E /* filelock.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = filelock.c; path = ../../src/filelock.c; sourceTree = "<group>"; };
+		3CDCEDBD0902EA8200B2EF7E /* emacs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = emacs.c; path = ../../src/emacs.c; sourceTree = "<group>"; };
+		3CDCEDBE0902EA8200B2EF7E /* editfns.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = editfns.c; path = ../../src/editfns.c; sourceTree = "<group>"; };
+		3CDCEDBF0902EA8200B2EF7E /* fileio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = fileio.c; path = ../../src/fileio.c; sourceTree = "<group>"; };
+		3CDCEDC00902EA8200B2EF7E /* eval.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = eval.c; path = ../../src/eval.c; sourceTree = "<group>"; };
+		3CDCEDC10902EA8200B2EF7E /* casetab.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = casetab.c; path = ../../src/casetab.c; sourceTree = "<group>"; };
+		3CDCEDC20902EA8200B2EF7E /* composite.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = composite.c; path = ../../src/composite.c; sourceTree = "<group>"; };
+		3CDCEDC30902EA8200B2EF7E /* dispnew.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dispnew.c; path = ../../src/dispnew.c; sourceTree = "<group>"; };
+		3CDCEDC40902EA8200B2EF7E /* charset.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = charset.c; path = ../../src/charset.c; sourceTree = "<group>"; };
+		3CDCEDC50902EA8200B2EF7E /* alloc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = alloc.c; path = ../../src/alloc.c; sourceTree = "<group>"; };
+		3CDCEDC60902EA8200B2EF7E /* bytecode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bytecode.c; path = ../../src/bytecode.c; sourceTree = "<group>"; };
+		3CDCEDC70902EA8200B2EF7E /* callproc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = callproc.c; path = ../../src/callproc.c; sourceTree = "<group>"; };
+		3CDCEDC80902EA8200B2EF7E /* cm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cm.c; path = ../../src/cm.c; sourceTree = "<group>"; };
+		3CDCEDC90902EA8200B2EF7E /* casefiddle.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = casefiddle.c; path = ../../src/casefiddle.c; sourceTree = "<group>"; };
+		3CDCEDCA0902EA8200B2EF7E /* fringe.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = fringe.c; path = ../../src/fringe.c; sourceTree = "<group>"; };
+		3CDCEDCB0902EA8200B2EF7E /* frame.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = frame.c; path = ../../src/frame.c; sourceTree = "<group>"; };
+		3CDCEDCC0902EA8200B2EF7E /* chartab.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = chartab.c; path = ../../src/chartab.c; sourceTree = "<group>"; };
+		3CDCEDCD0902EA8200B2EF7E /* atimer.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = atimer.c; path = ../../src/atimer.c; sourceTree = "<group>"; };
+		3CFDFC3A08E79A6800B05918 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /Developer/SDKs/MacOSX10.3.9.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		3CC5434707E2315800C271A9 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3CFDFC3B08E79A6800B05918 /* AppKit.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				3CFDFC3A08E79A6800B05918 /* AppKit.framework */,
+			);
+			name = "Linked Frameworks";
+			sourceTree = "<group>";
+		};
+		1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+			);
+			name = "Other Frameworks";
+			sourceTree = "<group>";
+		};
+		19C28FACFE9D520D11CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				3CC5434C07E2315800C271A9 /* Emacs.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		289FC26B00C69A287F000001 /* NeXTStep */ = {
+			isa = PBXGroup;
+			children = (
+				3C4D6D710DE50D5D00B20D4E /* nsfont.m */,
+				3C15C1A70902D97100A8542F /* nsimage.m */,
+				3C15C04F0902D89500A8542F /* nsgui.h */,
+				3C7F3C3A07EB3B05003C8A4D /* nsterm.h */,
+				090AF67E00C61DCD7F000001 /* nsfns.m */,
+				090AF68000C61DCD7F000001 /* nsmenu.m */,
+				090AF68100C61DCD7F000001 /* nsselect.m */,
+				090AF68300C61DCD7F000001 /* nsterm.m */,
+			);
+			name = NeXTStep;
+			sourceTree = "<group>";
+		};
+		29B97314FDCFA39411CA2CEA /* Emacs */ = {
+			isa = PBXGroup;
+			children = (
+				289FC26B00C69A287F000001 /* NeXTStep */,
+				3C15C23E0902E6B000A8542F /* emacs-hdr */,
+				3CDCED4D0902EA6800B2EF7E /* emacs-src */,
+				29B97317FDCFA39411CA2CEA /* Resources */,
+				29B97323FDCFA39411CA2CEA /* Frameworks */,
+				19C28FACFE9D520D11CA2CBB /* Products */,
+			);
+			name = Emacs;
+			sourceTree = "<group>";
+		};
+		29B97317FDCFA39411CA2CEA /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				3CB8E2A40E2CE856003F3104 /* English.lproj */,
+				3CB8E29F0E2CE7F5003F3104 /* Credits.html */,
+				3CB8E2990E2CE6BF003F3104 /* preferences.nib */,
+				739637F200C4DF3C7F000001 /* Images */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+				1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		3C15C23E0902E6B000A8542F /* emacs-hdr */ = {
+			isa = PBXGroup;
+			children = (
+				3C4D6D670DE50D2300B20D4E /* font.h */,
+				3C15C0DB0902D89500A8542F /* acldef.h */,
+				3C15C0E60902D89500A8542F /* atimer.h */,
+				3C15C0E70902D89500A8542F /* blockinput.h */,
+				3C15C0780902D89500A8542F /* buffer.h */,
+				3C15C0760902D89500A8542F /* category.h */,
+				3C15C0C50902D89500A8542F /* ccl.h */,
+				3C15C0DE0902D89500A8542F /* character.h */,
+				3C15C0C80902D89500A8542F /* charset.h */,
+				3C15C0E20902D89500A8542F /* chpdef.h */,
+				3C15C0890902D89500A8542F /* cm.h */,
+				3CDCED330902E99700B2EF7E /* config.h */,
+				3C15C0770902D89500A8542F /* coding.h */,
+				3C15C0D70902D89500A8542F /* commands.h */,
+				3C15C0C70902D89500A8542F /* composite.h */,
+				3C15C0D90902D89500A8542F /* dispextern.h */,
+				3C15C0BF0902D89500A8542F /* disptab.h */,
+				3C15C0C20902D89500A8542F /* epaths.h */,
+				3C15C0C90902D89500A8542F /* fontset.h */,
+				3C15C0E40902D89500A8542F /* frame.h */,
+				3C15C0B80902D89500A8542F /* getpagesize.h */,
+				3C15C0B60902D89500A8542F /* gnu.h */,
+				3C15C06E0902D89500A8542F /* indent.h */,
+				3C15C06B0902D89500A8542F /* intervals.h */,
+				3C15C0660902D89500A8542F /* keymap.h */,
+				3C15C0680902D89500A8542F /* keyboard.h */,
+				3C15C05D0902D89500A8542F /* macros.h */,
+				3C15C0560902D89500A8542F /* md5.h */,
+				3C15C0550902D89500A8542F /* mem-limits.h */,
+				3C15C0500902D89500A8542F /* ndir.h */,
+				3C15C04D0902D89500A8542F /* param.h */,
+				3C15C04C0902D89500A8542F /* point.h */,
+				3C15C0470902D89500A8542F /* process.h */,
+				3C15C0460902D89500A8542F /* puresize.h */,
+				3C15C0430902D89500A8542F /* regex.h */,
+				3C15C0410902D89500A8542F /* region-cache.h */,
+				3C15C0390902D89500A8542F /* syntax.h */,
+				3C15C0370902D89500A8542F /* sysselect.h */,
+				3C15C0330902D89500A8542F /* syswait.h */,
+				3C15C0360902D89500A8542F /* syssignal.h */,
+				3C15C0350902D89500A8542F /* systime.h */,
+				3C15C0340902D89500A8542F /* systty.h */,
+				3C15C0300902D89500A8542F /* termchar.h */,
+				3C15C02F0902D89500A8542F /* termhooks.h */,
+				3C15C0950902D89500A8542F /* termopts.h */,
+				3C15C0920902D89500A8542F /* uaf.h */,
+				3C15C0790902D89500A8542F /* vlimit.h */,
+				3C15C0A00902D89500A8542F /* window.h */,
+			);
+			name = "emacs-hdr";
+			sourceTree = "<group>";
+		};
+		3CB8E2A40E2CE856003F3104 /* English.lproj */ = {
+			isa = PBXGroup;
+			children = (
+				3CB8E2A50E2CE856003F3104 /* InfoPlist.strings */,
+			);
+			name = English.lproj;
+			path = Emacs.base/Contents/Resources/English.lproj;
+			sourceTree = "<group>";
+		};
+		3CDCED4D0902EA6800B2EF7E /* emacs-src */ = {
+			isa = PBXGroup;
+			children = (
+				3C4D6D660DE50D2300B20D4E /* font.c */,
+				3C4D6D680DE50D2300B20D4E /* termcap.c */,
+				3C4D6D690DE50D2300B20D4E /* terminal.c */,
+				3C4D6D6A0DE50D2300B20D4E /* tparam.c */,
+				3CDCED550902EA8100B2EF7E /* term.c */,
+				3CDCED560902EA8100B2EF7E /* sysdep.c */,
+				3CDCED570902EA8100B2EF7E /* syntax.c */,
+				3CDCED590902EA8100B2EF7E /* strftime.c */,
+				3CDCED5A0902EA8100B2EF7E /* sound.c */,
+				3CDCED5C0902EA8100B2EF7E /* search.c */,
+				3CDCED5D0902EA8100B2EF7E /* scroll.c */,
+				3CDCED5E0902EA8100B2EF7E /* region-cache.c */,
+				3CDCED5F0902EA8100B2EF7E /* regex.c */,
+				3CDCED610902EA8100B2EF7E /* process.c */,
+				3CDCED620902EA8100B2EF7E /* print.c */,
+				3CDCED640902EA8100B2EF7E /* pre-crt0.c */,
+				3CDCED670902EA8100B2EF7E /* minibuf.c */,
+				3CDCED680902EA8100B2EF7E /* md5.c */,
+				3CDCED690902EA8100B2EF7E /* marker.c */,
+				3CDCED6D0902EA8100B2EF7E /* macros.c */,
+				3CDCED710902EA8100B2EF7E /* lread.c */,
+				3CDCED720902EA8100B2EF7E /* lastfile.c */,
+				3CDCED730902EA8100B2EF7E /* keymap.c */,
+				3CDCED740902EA8200B2EF7E /* keyboard.c */,
+				3CDCED750902EA8200B2EF7E /* intervals.c */,
+				3CDCED760902EA8200B2EF7E /* insdel.c */,
+				3CDCED770902EA8200B2EF7E /* indent.c */,
+				3CDCED780902EA8200B2EF7E /* image.c */,
+				3CDCED7A0902EA8200B2EF7E /* cmds.c */,
+				3CDCED7B0902EA8200B2EF7E /* category.c */,
+				3CDCED7C0902EA8200B2EF7E /* coding.c */,
+				3CDCED830902EA8200B2EF7E /* unexmacosx.c */,
+				3CDCED8B0902EA8200B2EF7E /* buffer.c */,
+				3CDCED8C0902EA8200B2EF7E /* character.c */,
+				3CDCED920902EA8200B2EF7E /* undo.c */,
+				3CDCED940902EA8200B2EF7E /* textprop.c */,
+				3CDCED950902EA8200B2EF7E /* terminfo.c */,
+				3CDCED9C0902EA8200B2EF7E /* xfaces.c */,
+				3CDCED9D0902EA8200B2EF7E /* xdisp.c */,
+				3CDCED9E0902EA8200B2EF7E /* window.c */,
+				3CDCEDB00902EA8200B2EF7E /* doprnt.c */,
+				3CDCEDB10902EA8200B2EF7E /* doc.c */,
+				3CDCEDB20902EA8200B2EF7E /* dired.c */,
+				3CDCEDB30902EA8200B2EF7E /* data.c */,
+				3CDCEDB40902EA8200B2EF7E /* callint.c */,
+				3CDCEDB60902EA8200B2EF7E /* ccl.c */,
+				3CDCEDB70902EA8200B2EF7E /* fontset.c */,
+				3CDCEDB80902EA8200B2EF7E /* fns.c */,
+				3CDCEDB90902EA8200B2EF7E /* floatfns.c */,
+				3CDCEDBB0902EA8200B2EF7E /* filemode.c */,
+				3CDCEDBC0902EA8200B2EF7E /* filelock.c */,
+				3CDCEDBD0902EA8200B2EF7E /* emacs.c */,
+				3CDCEDBE0902EA8200B2EF7E /* editfns.c */,
+				3CDCEDBF0902EA8200B2EF7E /* fileio.c */,
+				3CDCEDC00902EA8200B2EF7E /* eval.c */,
+				3CDCEDC10902EA8200B2EF7E /* casetab.c */,
+				3CDCEDC20902EA8200B2EF7E /* composite.c */,
+				3CDCEDC30902EA8200B2EF7E /* dispnew.c */,
+				3CDCEDC40902EA8200B2EF7E /* charset.c */,
+				3CDCEDC50902EA8200B2EF7E /* alloc.c */,
+				3CDCEDC60902EA8200B2EF7E /* bytecode.c */,
+				3CDCEDC70902EA8200B2EF7E /* callproc.c */,
+				3CDCEDC80902EA8200B2EF7E /* cm.c */,
+				3CDCEDC90902EA8200B2EF7E /* casefiddle.c */,
+				3CDCEDCA0902EA8200B2EF7E /* fringe.c */,
+				3CDCEDCB0902EA8200B2EF7E /* frame.c */,
+				3CDCEDCC0902EA8200B2EF7E /* chartab.c */,
+				3CDCEDCD0902EA8200B2EF7E /* atimer.c */,
+			);
+			name = "emacs-src";
+			sourceTree = "<group>";
+		};
+		739637F200C4DF3C7F000001 /* Images */ = {
+			isa = PBXGroup;
+			children = (
+				3CB8E29D0E2CE73A003F3104 /* Emacs.icns */,
+			);
+			name = Images;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		3CC542FF07E2315800C271A9 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3C7F3C3B07EB3B05003C8A4D /* nsterm.h in Headers */,
+				3C15C0EB0902D89500A8542F /* termhooks.h in Headers */,
+				3C15C0EC0902D89500A8542F /* termchar.h in Headers */,
+				3C15C0EF0902D89500A8542F /* syswait.h in Headers */,
+				3C15C0F00902D89500A8542F /* systty.h in Headers */,
+				3C15C0F10902D89500A8542F /* systime.h in Headers */,
+				3C15C0F20902D89500A8542F /* syssignal.h in Headers */,
+				3C15C0F30902D89500A8542F /* sysselect.h in Headers */,
+				3C15C0F50902D89500A8542F /* syntax.h in Headers */,
+				3C15C0FD0902D89500A8542F /* region-cache.h in Headers */,
+				3C15C0FF0902D89500A8542F /* regex.h in Headers */,
+				3C15C1020902D89500A8542F /* puresize.h in Headers */,
+				3C15C1030902D89500A8542F /* process.h in Headers */,
+				3C15C1080902D89500A8542F /* point.h in Headers */,
+				3C15C1090902D89500A8542F /* param.h in Headers */,
+				3C15C10B0902D89500A8542F /* nsgui.h in Headers */,
+				3C15C10C0902D89500A8542F /* ndir.h in Headers */,
+				3C15C1110902D89500A8542F /* mem-limits.h in Headers */,
+				3C15C1120902D89500A8542F /* md5.h in Headers */,
+				3C15C1190902D89500A8542F /* macros.h in Headers */,
+				3C15C1220902D89500A8542F /* keymap.h in Headers */,
+				3C15C1240902D89500A8542F /* keyboard.h in Headers */,
+				3C15C1270902D89500A8542F /* intervals.h in Headers */,
+				3C15C12A0902D89500A8542F /* indent.h in Headers */,
+				3C15C1320902D89500A8542F /* category.h in Headers */,
+				3C15C1330902D89500A8542F /* coding.h in Headers */,
+				3C15C1340902D89500A8542F /* buffer.h in Headers */,
+				3C15C1350902D89500A8542F /* vlimit.h in Headers */,
+				3C15C1450902D89500A8542F /* cm.h in Headers */,
+				3C15C14E0902D89500A8542F /* uaf.h in Headers */,
+				3C15C1510902D89500A8542F /* termopts.h in Headers */,
+				3C15C15C0902D89500A8542F /* window.h in Headers */,
+				3C15C1720902D89500A8542F /* gnu.h in Headers */,
+				3C15C1740902D89500A8542F /* getpagesize.h in Headers */,
+				3C15C17B0902D89500A8542F /* disptab.h in Headers */,
+				3C15C17E0902D89500A8542F /* epaths.h in Headers */,
+				3C15C1810902D89500A8542F /* ccl.h in Headers */,
+				3C15C1830902D89500A8542F /* composite.h in Headers */,
+				3C15C1840902D89500A8542F /* charset.h in Headers */,
+				3C15C1850902D89500A8542F /* fontset.h in Headers */,
+				3C15C1930902D89500A8542F /* commands.h in Headers */,
+				3C15C1950902D89500A8542F /* dispextern.h in Headers */,
+				3C15C1970902D89500A8542F /* acldef.h in Headers */,
+				3C15C19A0902D89500A8542F /* character.h in Headers */,
+				3C15C19E0902D89500A8542F /* chpdef.h in Headers */,
+				3C15C1A00902D89500A8542F /* frame.h in Headers */,
+				3C15C1A20902D89500A8542F /* atimer.h in Headers */,
+				3C15C1A30902D89500A8542F /* blockinput.h in Headers */,
+				3CDCED340902E99700B2EF7E /* config.h in Headers */,
+				3C4D6D6C0DE50D2300B20D4E /* font.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		3CC542FE07E2315800C271A9 /* Emacs */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 3CA115970C825A540007AFC2 /* Build configuration list for PBXNativeTarget "Emacs" */;
+			buildPhases = (
+				3CC542FF07E2315800C271A9 /* Headers */,
+				3CC5430007E2315800C271A9 /* Resources */,
+				3CC5430407E2315800C271A9 /* Sources */,
+				3CC5434707E2315800C271A9 /* Frameworks */,
+				3CC5434907E2315800C271A9 /* Rez */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Emacs;
+			productInstallPath = "$(HOME)/Applications";
+			productName = Emacs;
+			productReference = 3CC5434C07E2315800C271A9 /* Emacs.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		29B97313FDCFA39411CA2CEA /* Project object */ = {
+			isa = PBXProject;
+			buildConfigurationList = 3CA1159B0C825A540007AFC2 /* Build configuration list for PBXProject "Emacs" */;
+			compatibilityVersion = "Xcode 2.4";
+			hasScannedForEncodings = 1;
+			mainGroup = 29B97314FDCFA39411CA2CEA /* Emacs */;
+			projectDirPath = "";
+			projectRoot = ../..;
+			targets = (
+				3CC542FE07E2315800C271A9 /* Emacs */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		3CC5430007E2315800C271A9 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3CB8E29A0E2CE6BF003F3104 /* preferences.nib in Resources */,
+				3CB8E29E0E2CE73A003F3104 /* Emacs.icns in Resources */,
+				3CB8E2A00E2CE7F5003F3104 /* Credits.html in Resources */,
+				3CB8E2A70E2CE856003F3104 /* InfoPlist.strings in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXRezBuildPhase section */
+		3CC5434907E2315800C271A9 /* Rez */ = {
+			isa = PBXRezBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXRezBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		3CC5430407E2315800C271A9 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3CC5430607E2315800C271A9 /* nsfns.m in Sources */,
+				3CC5430707E2315800C271A9 /* nsmenu.m in Sources */,
+				3CC5430807E2315800C271A9 /* nsselect.m in Sources */,
+				3CC5430907E2315800C271A9 /* nsterm.m in Sources */,
+				3C15C1A80902D97100A8542F /* nsimage.m in Sources */,
+				3CDCEDD00902EA8200B2EF7E /* term.c in Sources */,
+				3CDCEDD10902EA8200B2EF7E /* sysdep.c in Sources */,
+				3CDCEDD20902EA8200B2EF7E /* syntax.c in Sources */,
+				3CDCEDD40902EA8200B2EF7E /* strftime.c in Sources */,
+				3CDCEDD50902EA8200B2EF7E /* sound.c in Sources */,
+				3CDCEDD70902EA8200B2EF7E /* search.c in Sources */,
+				3CDCEDD80902EA8200B2EF7E /* scroll.c in Sources */,
+				3CDCEDD90902EA8200B2EF7E /* region-cache.c in Sources */,
+				3CDCEDDA0902EA8200B2EF7E /* regex.c in Sources */,
+				3CDCEDDC0902EA8200B2EF7E /* process.c in Sources */,
+				3CDCEDDD0902EA8200B2EF7E /* print.c in Sources */,
+				3CDCEDDF0902EA8200B2EF7E /* pre-crt0.c in Sources */,
+				3CDCEDE20902EA8200B2EF7E /* minibuf.c in Sources */,
+				3CDCEDE30902EA8200B2EF7E /* md5.c in Sources */,
+				3CDCEDE40902EA8200B2EF7E /* marker.c in Sources */,
+				3CDCEDE80902EA8200B2EF7E /* macros.c in Sources */,
+				3CDCEDEC0902EA8200B2EF7E /* lread.c in Sources */,
+				3CDCEDED0902EA8200B2EF7E /* lastfile.c in Sources */,
+				3CDCEDEE0902EA8200B2EF7E /* keymap.c in Sources */,
+				3CDCEDEF0902EA8200B2EF7E /* keyboard.c in Sources */,
+				3CDCEDF00902EA8200B2EF7E /* intervals.c in Sources */,
+				3CDCEDF10902EA8200B2EF7E /* insdel.c in Sources */,
+				3CDCEDF20902EA8200B2EF7E /* indent.c in Sources */,
+				3CDCEDF30902EA8200B2EF7E /* image.c in Sources */,
+				3CDCEDF50902EA8200B2EF7E /* cmds.c in Sources */,
+				3CDCEDF60902EA8200B2EF7E /* category.c in Sources */,
+				3CDCEDF70902EA8200B2EF7E /* coding.c in Sources */,
+				3CDCEDFE0902EA8200B2EF7E /* unexmacosx.c in Sources */,
+				3CDCEE060902EA8200B2EF7E /* buffer.c in Sources */,
+				3CDCEE070902EA8200B2EF7E /* character.c in Sources */,
+				3CDCEE0D0902EA8200B2EF7E /* undo.c in Sources */,
+				3CDCEE0F0902EA8200B2EF7E /* textprop.c in Sources */,
+				3CDCEE100902EA8200B2EF7E /* terminfo.c in Sources */,
+				3CDCEE170902EA8200B2EF7E /* xfaces.c in Sources */,
+				3CDCEE180902EA8200B2EF7E /* xdisp.c in Sources */,
+				3CDCEE190902EA8200B2EF7E /* window.c in Sources */,
+				3CDCEE2B0902EA8200B2EF7E /* doprnt.c in Sources */,
+				3CDCEE2C0902EA8200B2EF7E /* doc.c in Sources */,
+				3CDCEE2D0902EA8200B2EF7E /* dired.c in Sources */,
+				3CDCEE2E0902EA8200B2EF7E /* data.c in Sources */,
+				3CDCEE2F0902EA8200B2EF7E /* callint.c in Sources */,
+				3CDCEE310902EA8200B2EF7E /* ccl.c in Sources */,
+				3CDCEE320902EA8200B2EF7E /* fontset.c in Sources */,
+				3CDCEE330902EA8200B2EF7E /* fns.c in Sources */,
+				3CDCEE340902EA8200B2EF7E /* floatfns.c in Sources */,
+				3CDCEE360902EA8200B2EF7E /* filemode.c in Sources */,
+				3CDCEE370902EA8200B2EF7E /* filelock.c in Sources */,
+				3CDCEE380902EA8200B2EF7E /* emacs.c in Sources */,
+				3CDCEE390902EA8200B2EF7E /* editfns.c in Sources */,
+				3CDCEE3A0902EA8200B2EF7E /* fileio.c in Sources */,
+				3CDCEE3B0902EA8200B2EF7E /* eval.c in Sources */,
+				3CDCEE3C0902EA8200B2EF7E /* casetab.c in Sources */,
+				3CDCEE3D0902EA8200B2EF7E /* composite.c in Sources */,
+				3CDCEE3E0902EA8200B2EF7E /* dispnew.c in Sources */,
+				3CDCEE3F0902EA8200B2EF7E /* charset.c in Sources */,
+				3CDCEE400902EA8200B2EF7E /* alloc.c in Sources */,
+				3CDCEE410902EA8200B2EF7E /* bytecode.c in Sources */,
+				3CDCEE420902EA8200B2EF7E /* callproc.c in Sources */,
+				3CDCEE430902EA8200B2EF7E /* cm.c in Sources */,
+				3CDCEE440902EA8200B2EF7E /* casefiddle.c in Sources */,
+				3CDCEE450902EA8200B2EF7E /* fringe.c in Sources */,
+				3CDCEE460902EA8200B2EF7E /* frame.c in Sources */,
+				3CDCEE470902EA8200B2EF7E /* chartab.c in Sources */,
+				3CDCEE480902EA8200B2EF7E /* atimer.c in Sources */,
+				3C4D6D6B0DE50D2300B20D4E /* font.c in Sources */,
+				3C4D6D6D0DE50D2300B20D4E /* termcap.c in Sources */,
+				3C4D6D6E0DE50D2300B20D4E /* terminal.c in Sources */,
+				3C4D6D6F0DE50D2300B20D4E /* tparam.c in Sources */,
+				3C4D6D730DE50D5D00B20D4E /* nsfont.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+		3CB8E2A50E2CE856003F3104 /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				3CB8E2A60E2CE856003F3104 /* English */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		3CA115980C825A540007AFC2 /* Development */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.3.0.sdk/System/Library/Frameworks\"";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_OPTIMIZATION_LEVEL = 1;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					COCOA,
+					HAVE_CONFIG_H,
+					emacs,
+				);
+				HEADER_SEARCH_PATHS = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Applications";
+				LIBRARY_SEARCH_PATHS = "";
+				MACOSX_DEPLOYMENT_TARGET = 10.3;
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-lncurses";
+				PRODUCT_NAME = Emacs;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "";
+				WRAPPER_EXTENSION = app;
+				ZERO_LINK = NO;
+			};
+			name = Development;
+		};
+		3CA115990C825A540007AFC2 /* Deployment */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.3.0.sdk/System/Library/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					COCOA,
+					HAVE_CONFIG_H,
+					emacs,
+				);
+				HEADER_SEARCH_PATHS = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Applications";
+				LIBRARY_SEARCH_PATHS = "";
+				MACOSX_DEPLOYMENT_TARGET = 10.3;
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-lncurses";
+				PRODUCT_NAME = Emacs;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "";
+				WRAPPER_EXTENSION = app;
+				ZERO_LINK = NO;
+			};
+			name = Deployment;
+		};
+		3CA1159A0C825A540007AFC2 /* Default */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.3.0.sdk/System/Library/Frameworks\"";
+				GCC_PREPROCESSOR_DEFINITIONS = "";
+				HEADER_SEARCH_PATHS = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Applications";
+				LIBRARY_SEARCH_PATHS = "";
+				MACOSX_DEPLOYMENT_TARGET = 10.3;
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				PRODUCT_NAME = Emacs;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "";
+				WRAPPER_EXTENSION = app;
+			};
+			name = Default;
+		};
+		3CA1159C0C825A540007AFC2 /* Development */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				MACOSX_DEPLOYMENT_TARGET = 10.3;
+				SDKROOT = /Developer/SDKs/MacOSX10.3.0.sdk;
+			};
+			name = Development;
+		};
+		3CA1159D0C825A540007AFC2 /* Deployment */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				MACOSX_DEPLOYMENT_TARGET = 10.3;
+				SDKROOT = /Developer/SDKs/MacOSX10.3.0.sdk;
+			};
+			name = Deployment;
+		};
+		3CA1159E0C825A540007AFC2 /* Default */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				MACOSX_DEPLOYMENT_TARGET = 10.3;
+				SDKROOT = /Developer/SDKs/MacOSX10.3.0.sdk;
+			};
+			name = Default;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		3CA115970C825A540007AFC2 /* Build configuration list for PBXNativeTarget "Emacs" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				3CA115980C825A540007AFC2 /* Development */,
+				3CA115990C825A540007AFC2 /* Deployment */,
+				3CA1159A0C825A540007AFC2 /* Default */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Default;
+		};
+		3CA1159B0C825A540007AFC2 /* Build configuration list for PBXProject "Emacs" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				3CA1159C0C825A540007AFC2 /* Development */,
+				3CA1159D0C825A540007AFC2 /* Deployment */,
+				3CA1159E0C825A540007AFC2 /* Default */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Default;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/FOR-RELEASE	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,216 @@
+-*- outline -*-
+
+* NON-SPECIFIC
+
+** Remove Feval calls relating to insert working text in isearch mode.
+
+** free_frame_resources, face colors
+
+** look at nsfont_char_width and nsfont_string_width utils (Dan C.)
+
+** config improvements (Dan C.)
+
+* Mac-related:
+
+** open file:/// URLs
+
+** finish handle terminate request (user logout)
+
+** put frame autopositioning into C code somewhere -- if loc = same, offset
+
+** automap ctrl-mouse-1 to mouse-3
+
+** deal with Finder aliases somehow
+
+** Ctrl-F2 won't pull up menus
+
+
+* Cursor:
+
+** ns_cursor_blink_rate: when set in preferences, somehow save the option (but
+  calling custom-save-all from this causes error)
+
+** cursor nonerase on certain Leopard and Tiger installations
+
+** if I do:  (mouse-avoidance-mode 'banish) and then minimize Emacs, it pops back immediately.
+  Also, it insists on being on top of other windows if they overlap.
+
+** cursor-over bugs w/some scripts (move around in HELLO to see)
+
+
+Keyboard:
+
+On a German (PowerBook?) keyboard alt-` produces the correct ˚, without alt modifier only the message “<S-268632064> is undefined” is produced. Peter Maurer’s Key codes shows:
+        * Modifier Change: ⇧ 131330/0x20102
+        * Key Down/Up event: ⇧ 24/0x18
+[note, this is += key on German KB setting on US keyboard]
+[unable to reproduce w/German KB setting -- need German laptop?]
+
+** numeric keysetting bug
+
+
+* Other:
+
+** better recog of unicode scripts / Greek / composition
+
+** Ctrl-g not picked up in all situations get --experimental-ctrl-g in 'compile' working better
+
+** Exec-dump not working on GNUstep (so slow startup).
+
+** occasional size too large for screen errors
+
+** undo for color-drag face customization
+
+
+
+
+---------
+* DONE
+
+Try font-backend mechanism (see font.h).
+
+Auto font substitution?
+
+ns-option-modifier (alias for ns-alternate-modifier)
+
+ns-control-modifier, ns-function-modifier (new)
+
+- Frame bugs:
+  - create frame on second monitor fails (due to frame-parameters).
+
+toolbar bugs
+
+fix cursor disappears on italic text bug
+
+fix scrollbar erase on Ctrl-l bug
+
+Menubar emacs-21 compatibility.  Make this and command-is-meta
+    switchable at startup.  Switch mouse handling to 3-button compatible.
+
+mouse button normalization
+
+
+[rc1 released]
+
+
+shift-alt-h does produce Ó (according C-h k), but this glyph is not
+always shown completely, it seems to depend on the font used
+
+[width estimation still off; this character is 211 = 0xD3]
+
+Another attempt at composite rendering.
+
+shift-alt-6 does not produce ^ (dead key) but &.
+[adding alt continues to pick up the '&' interpretation, but in other
+ apps this suddenly changes it to a dead key]
+
+- italic in Courier is still cut off
+
+- dead keys end isearch w/o allowing typing
+[need to insert to minibuffer if that is active]
+
+When using the Dvorak with Qwerty keyboard shortcuts keyboard layout
+(hereon in referred to as Dvorak-Qwerty), keyboard shortcuts
+erroneously use the Dvorak layout. e.g. The Qwerty H key becomes D in
+Dvorak, but with Dvorak-Qwerty the same key should be used when
+hitting Cmd-H to hide an application. In Emacs.app with a
+Dvorak-Qwerty layout I must hit Cmd-J (Qwerty J becomes H in Dvorak)
+to hide the app.
+
+- menus
+
+- consolidate FRAME_INTERNAL_BORDER extension hacks
+
+- mouse-1 activation problems (buttons, etc.): check keyboard.c HAVE_NS sections
+
+- clean up bg fill code in font->draw(), and change conditions on when called with bg=yes
+
+- clean up / optimize the metrics caching -- consider reducing memory load
+
+- non-encapsulated build
+
+- test color-drag face customization (accuracy and saving)
+
+- look at ns-mark-nav replacement
+
+- gnustep
+
+- documentation:
+  - "stipple" images, alpha, color-drag, etc.
+  - make sure everyone finds it
+
+
+[rc2 released]
+
+- recheck font width determination for variable-width non-wide fonts
+
+- resize-drag
+
+- colored bitmaps (use NSCalibratedRGBColorspace for the bitmap and
+  add a method setBitmapForegroundColor:color to twiddle the bits
+
+- resize title printing bug
+
+
+[rc2a released]
+
+- naming: cursor "line" -> "bar", "bar" -> underscore
+
+- incorporate Pete's locallisp patch
+
+- document needed sudo for compile --shared-lisp
+
+
+[patch 20071010_rc2a released]
+
+- clean up ns-menu-bar.el and try folding into ns-win.el
+
+- fix jaggedy startup screen w/black bkgrd
+
+- Pete's fringe weirdness
+
+- iconification: use shrunk image for non-finder types
+
+- toolbar updating
+
+
+[patch 20071015_rc2a released]
+
+- multi-TTY merge
+
+- terminal mode weird colors (real fix)
+
+- Frame bugs:
+  - a full-height frame will be shrunk on defocus, focus
+    [actually must be over-height, but it's a little overzealous in the
+     shrinking; probably happens in x_set_window_size]
+  - adding toolbar on full-height frame requires resize to avoid scrambling
+
+- Buffers menu brokenness
+
+- inability to use ARGB colors problem
+
+- cut buffer in TTY
+
+
+[rc3 released]
+
+- drop MULTI_KBOARD
+
+- mic-paren removal (also see http://www.emacswiki.org/cgi-bin/wiki/mic-paren.el)
+
+- describe-key problem
+
+- drop need for preload advice (print-buffer workaround)
+
+- new frame placement ignores parameters [cannot replicate]
+
+- white text on background alpha
+
+- Multi-TTY: switching input between tty and GUI frames still needs work.
+  Once ns_select() and ns_read_socket() are being called, the regular terminal
+  input route seems ineffective.  Furthermore NSApp activate events are not
+  picked up when attempting to read in terminal mode.
+  (Tests: make-frame-on-tty /dev/ttyp#, make-frame-on-display)
+
+- remove ns-yes-or-no-p, try again to improve looks of regular dialog in nsmenu.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/GNUstep/Emacs.base/Resources/Emacs.desktop	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Application
+Version=9.0
+Categories=GNUstep
+Name=Emacs
+Comment=GNU Emacs for NeXT/Open/GNUstep and OS X
+Icon=emacs.tiff
+Exec=openapp Emacs.app
+#TryExec=Emacs.app
+FilePattern=Emacs.app;Emacs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/GNUstep/Emacs.base/Resources/Info-gnustep.plist	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,137 @@
+{
+    "!" = "Generated by ProjectCenter, do not edit";
+    ApplicationDescription = "GNU Emacs for GNUstep / OS X";
+    ApplicationIcon = emacs.tiff;
+    ApplicationName = Emacs;
+    ApplicationRelease = "9.0";
+    Authors = (
+	"Adrian Robert (GNUstep)",
+	"Christophe de Dinechin (MacOS X)",
+	"Scott Bender (OpenStep)",
+	"Christian Limpach (NeXTStep)",
+	"Carl Edman (NeXTStep)",
+	"..see http://emacs-app.sf.net"
+    );
+    Copyright = "Copyright (C) 2005-2008";
+    CopyrightDescription = "Released under the GNU General Public License Version 2";
+    FullVersionID = "Emacs 23.0.60 NS 9.0";
+    NSExecutable = Emacs;
+    NSIcon = emacs.tiff;
+    NSPrincipalClass = NSApplication;
+    NSRole = Application;
+    NSTypes = (
+	{
+	    NSDocumentClass = "";
+	    NSHumanReadableName = "";
+	    NSIcon = "";
+	    NSName = "";
+	    NSRole = "";
+	    NSUnixExtensions = (
+		txt
+	    );
+	},
+	{
+	    NSDocumentClass = "";
+	    NSHumanReadableName = "";
+	    NSIcon = "";
+	    NSName = "";
+	    NSRole = "";
+	    NSUnixExtensions = (
+		c,
+		h
+	    );
+	},
+	{
+	    NSDocumentClass = "";
+	    NSHumanReadableName = "";
+	    NSIcon = "";
+	    NSName = "";
+	    NSRole = "";
+	    NSUnixExtensions = (
+		m
+	    );
+	},
+	{
+	    NSDocumentClass = "";
+	    NSHumanReadableName = "";
+	    NSIcon = "";
+	    NSName = "";
+	    NSRole = "";
+	    NSUnixExtensions = (
+		C,
+		cpp,
+		H,
+		cc
+	    );
+	},
+	{
+	    NSDocumentClass = "";
+	    NSHumanReadableName = "";
+	    NSIcon = "";
+	    NSName = "";
+	    NSRole = "";
+	    NSUnixExtensions = (
+		java
+	    );
+	},
+	{
+	    NSDocumentClass = "";
+	    NSHumanReadableName = "";
+	    NSIcon = "";
+	    NSName = "";
+	    NSRole = "";
+	    NSUnixExtensions = (
+		el
+	    );
+	},
+	{
+	    NSDocumentClass = "";
+	    NSHumanReadableName = "";
+	    NSIcon = "";
+	    NSName = "";
+	    NSRole = "";
+	    NSUnixExtensions = (
+		*
+	    );
+	}
+    );
+    NSServices = (
+	{
+	    NSPortName = Emacs;
+	    NSMessage = requestService;
+	    NSUserData = open-selection
+	    NSSendTypes = (NSStringPboardType);
+	    NSMenuItem = {
+		default = "Emacs.app/New Buffer Containing Selection";
+	    };
+	},
+	{
+	    NSPortName = Emacs;
+	    NSMessage = requestService;
+	    NSUserData = open-file
+	    NSSendTypes = (NSStringPboardType);
+	    NSMenuItem = {
+		default = "Emacs.app/Open Selected File";
+	    };
+	},
+	{
+	    NSPortName = Emacs;
+	    NSMessage = requestService;
+	    NSUserData = mail-selection
+	    NSSendTypes = (NSStringPboardType);
+	    NSMenuItem = {
+		default = "Emacs.app/Email Selection";
+	    };
+	},
+	{
+	    NSPortName = Emacs;
+	    NSMessage = requestService;
+	    NSUserData = mail-to
+	    NSSendTypes = (NSStringPboardType);
+	    NSMenuItem = {
+		default = "Emacs.app/Send Email to Selected Address";
+	    };
+	},
+    );
+    URL = "http://emacs-app.sf.net";
+}
\ No newline at end of file
Binary file nextstep/GNUstep/Emacs.base/Resources/emacs.tiff has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/GNUstep/Emacs.base/Resources/preferences.gorm/data.classes	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,31 @@
+{
+    "## Comment" = "Do NOT change this file, Gorm maintains it";
+    EmacsPrefsController = {
+	Actions = (
+	    "cancel:",
+	    "setDefaultFont:",
+	    "ok:",
+	    "resetToDefaults:",
+	    "runHelp:",
+	    "setColors:"
+	);
+	Outlets = (
+	    alternateModMenu,
+	    cursorBlinkSlider,
+	    cursorTypeMatrix,
+	    prefsWindow,
+	    expandSpaceSlider,
+	    commandModMenu
+	);
+	Super = NSObject;
+    };
+    FirstResponder = {
+	Actions = (
+	    "setDefaultFont:",
+	    "resetToDefaults:",
+	    "runHelp:",
+	    "setColors:"
+	);
+	Super = NSObject;
+    };
+}
\ No newline at end of file
Binary file nextstep/GNUstep/Emacs.base/Resources/preferences.gorm/data.info has changed
Binary file nextstep/GNUstep/Emacs.base/Resources/preferences.gorm/objects.gorm has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/README.txt	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,321 @@
+
+Emacs.app
+=========
+
+This file introduces the NeXTstep-based port of GNU Emacs, known as Emacs.app,
+ which runs on on many POSIX systems and possibly W32 using the GNUstep
+ libraries and on MacOS X systems using the Cocoa libraries.  The directory
+ "nextstep" and its subdirectories "Cocoa" and "GNUstep" contain files
+ relevant to building and running on these systems.
+
+Those primarily responsible for the port (in chronological order) were:
+
+Michael Brouwer
+Carl Edman
+Christian Limpach
+Scott Bender
+Christophe de Dinechin
+Adrian Robert
+
+See AUTHORS file and "Release History" below for more information.
+
+GNU Emacs is due to Richard Stallman and company.
+
+The GNUstep port was made possible through the assistance of Adam Fedor, Fred
+Kiefer, M. Uli Klusterer, Alexander Malmberg, Jonas Matton, and Riccardo
+Mottola.
+
+Peter Dyballa assisted in a variety of ways to improve text rendering and
+keyboard handling.  Adam Ratcliffe documented the Preferences panel.  David
+M. Cooke contributed fixes to XPM handling.  Carsten Bormann helped get dired
+working for non-ASCII filenames.
+
+
+Requirements
+------------
+MacOS X 10.3 or later
+- or -
+GNUstep "Startup 0.13" or later
+Tested on linux, should work on other systems, perhaps with minor build
+tweaking.
+
+
+Compilation
+-----------
+
+Run "./compile" in this directory, which will create a self-contained
+Emacs.app under 'build/'.  This can be moved anywhere and run.  To create a
+shared-lisp build, do "sudo ./compile -shared <install_root>".  Set
+<install_root> to where the lisp will go, for example /usr/local to end up
+with /usr/local/shared/emacs/...
+
+See the script itself for further details, and customizations.
+
+You can rerun configure and/or run 'make' manually in the top-level or src
+directories to refresh nextstep/build/Emacs.app.  (Or edit the "compile"
+script.)
+
+On OS X you can also open Cocoa/Emacs.xcodeproj and build it again there.  (Note,
+ZeroLink currently does not work with Emacs owing to the use of private_extern
+in the code as well as some other, unidentifiable problem.)  Before doing this
+you must run 'compile' once as outlined above, to set up the lisp resources.
+
+On GNUstep, you CAN'T use ProjectCenter, since PC cannot work with files
+outside of its project directory.
+
+
+Usage
+-----
+
+Please use the first entry under the help menu within Emacs.app, do
+"M-x info-ns-emacs".
+
+
+Background
+----------
+
+Internally to emacs, the port and its code are referred to using the term
+"NeXTstep", despite the fact that no system or API has been released under
+this name in more than 10 years.  Here's some background on why..
+
+NeXT, Inc. introduced the NeXTstep API with its computer and operating system
+in the late 1980's.  Later on in collaboration with Sun, this API was
+published as a specification called OpenStep.  The GNUstep project started in
+the early 1990's to provide a free implementation of this API.  Later on,
+Apple bought NeXT (some would say "NeXT bought Apple") and made OpenStep the
+basis of OS X, calling the API "Cocoa".  Since then, Cocoa has evolved beyond
+the OpenStep specification, and GNUstep has followed it.
+
+Thus, calling this port "OpenStep" is not technically accurate, and in the
+absence of any other determinant, we are using the term "NeXTstep", both
+because it signifies the original inspiration that created these APIs, and
+because all of the classes and functions still begin with the letters "NS".
+
+(See http://en.wikipedia.org/wiki/Nextstep)
+
+This Emacs port was first released in the early 1990's on the NeXT computer,
+and was successively updated to OpenStep, Rhapsody, OS X, and then finally
+GNUstep, tracking GNU emacs core releases in the meantime.
+
+
+Files specific to the port
+--------------------------
+
+src/nsfns.m
+src/nsfont.m
+src/nsgui.h
+src/nsimage.m
+src/nsmenu.m
+src/nsselect.m
+src/nsterm.h
+src/nsterm.m
+lisp/ns-grabenv.el
+lisp/ns-carbon-compat.el
+lisp/term/ns-win.el
+lib-src/mac-fix-env.m
+doc/emacs/ns-emacs.texi
+etc/Emacs.clr
+nextstep/
+
+
+Files modified for port:
+
+many -- look for HAVE_NS / NS_IMPL_... #ifdefs
+
+
+Release History
+---------------
+
+1990-1992	1.0-3.0 (?)	Michael Brouwer's socket/terminal communication 
+				based version (GUI ran as a separate process.)
+
+1993/10/25	3.0.1		Last (?) release of Brouwer version.  Supports
+				NeXTstep 3.x and below.
+
+1994/04/24	4.0		Carl Edman's version using direct API following
+				the X-Windows port.  NeXTstep 3.x only.
+
+1995/06/15	4.1        	Second (and last) Carl Edman release, based on
+				Emacs 19.28.
+
+1996/07/28	4.2		First Christian Limpach release, based on
+				Emacs 19.29.
+
+??		5.0		??
+
+1997/12/??	6.0b1		Ported to OpenStep by Scott Bender.  Updated
+				to Emacs 20.2.
+
+??		6.0b2		(?) Scott Bender: ported to Rhapsody.
+
+1999/05/??	6.0b3		Scott Bender: "OS X Server", Emacs 20.3.
+
+2001/06/25	7.0		Ported to MacOS X (10.1) by Christophe de
+				Dinechin. Release based on Emacs 20.7. Hosting
+				moved to SourceForge.
+
+2002/01/03	7.0.1		Bug fixes.
+
+2002/08/27	7.0.2		Jaguar (OS X 10.2) support. Added an autoconf
+				option for sys_nerr being in stdio. Added
+				libncurses to the build libraries. Fixed a
+				problem with ns-alternate-is-meta. Changed the
+				icon color to blue, since Jaguar is yellow.
+
+2004/10/07	8.0-pre1	Ported to GNUstep by Adrian Robert.
+
+2004/11/04	8.0-pre2	Restored functionality on OS X (menu code
+				cleanup).  Improved scrollbar handling and
+				paste from other applications.  File icons
+				obtained properly from NSWorkspace.  Dropped
+				Gorm and Nib files.  Background refresh bug
+				fixed (in GNUstep).  Various small fixes and
+				code cleanups.  Now starts up under Art.
+
+2005/01/27	8.0-pre3	Bold and italic faces supported.  Cursor and
+				mouse highlighting rendering bugs
+				fixed. Drag/drop and cut/paste interaction
+				w/external apps fixed.  File load/save panels
+				available.  Stability and rendering speed
+				improvements. Some ObjC and VC mode bugs fixed.
+
+2005/02/27	8.0-rc1		Dynamic path detection at startup so Emacs.app
+				can be moved anywhere.  Added binary packages
+				and simplified source installation to running
+				two scripts.  Thorough cleanup of menu code;
+				now fully functional.  Fixed all detected
+				memory leaks.  Minor frame focus and title
+				bugs fixed.
+
+2005/03/30	8.0-rc2		"Configure" info directory now uses dynamic
+				path setting, so info files can go under .app.
+				Improved select() handling and PTY fixes so
+				shell mode and tramp run smoothly.
+				Significant rendering optimizations under
+				GNUstep, and now works under Art backend.
+				Non-Latin text rendering works (but not
+				fontsets), and LEIM is bundled.  UTF8 is used
+				for clipboard interaction.
+				Arrow cursor now used on scrollbar.
+				objc-mode and tramp now bundled in site-lisp.
+
+2005/05/30	8.0-rc3		Fixed bug with parsing of "easymenu" menus.
+       				Many problems with modes such as SLIME, MatLab,
+				and Planner go away.  Improved scrollbar
+				handling and rendering speed.  Color panel
+				and other bug fixes. mac-fix-env utility.
+				Font handling improvements (OS X 10.3, 10.4):
+				- heed 'GSFontAntiAlias' default
+				- heed system antialiasing threshold
+				- added 'UseQuickdrawSmoothing' default to
+				  invoke less heavy antialiasing
+
+2005/07/05	8.0-rc4		Added a Preferences panel.  Cleaned up
+				rendering for synthetic italic fonts.  Further
+				improved menu parsing.  Use system highlight
+				color.  Added previous- and next-mark history
+				navigation commmands bound to M-p,M-n.
+				Miscellaneous bug fixes.
+
+2005/08/04	8.0-rc5		All internal string handling changed to UTF-8.
+				This means menu items, color and color list
+				names, and a few other things will now display
+				properly.  It does NOT mean UTF-8 filenames
+				are displayed correctly in the minibuffer.
+				Also relating to UTF-8, contents of files
+				using this coding can now be displayed (though
+				not auto-recognized; add extensions to your
+				default coding alist).  Limited mac-roman
+				support was also added (also sans recognition).
+				Certain characters are not displayed properly
+				due to a translation problem.  (UTF-8 based on
+				work by Otfried Cheong; mac-roman from
+				emacs-21.)  Partial support for "dead-key"
+				handling now added.  Transparency (e.g., M-x
+				set-background-color ARGB88FFFFFF) improved:
+				only the background is made transparent.
+				Cursor drawing glitches fixed.  Preferences 
+				handling improved.  Fixed some portability
+				problems on Tiger and Puma.
+
+2005/09/12	8.0		Bundled ispell on OS X.  Minor bug fixes and
+				stability improvements.  Compiles under gcc-4.
+
+2005/09/26	8.0.1		Correct clipped rendering for synthetic
+				italics. Include the info directory.
+				Fix grabenv. Bundle whitespace package.
+
+2005/10/27	8.0.2		Correct rendering for wide characters during
+				cursor movement.  Fix bungled hack in ispell
+				bundling.
+
+2005/11/05	9.0-pre1	Updated to latest Emacs CVS code on unicode-2
+				branch (proposed to be released 2006/2007 as
+				Emacs 23).
+
+2005/11/11	9.0-pre2	Fix crashes for deiconifying and loading
+				certain images.  Improve vertical font metrics
+				(fixes inaccurate page up/down, window size,
+				and partial lines).  Support better remapping
+				of Alt/Opt and remapping of Command.  More
+				insistent defaulting of scrollbar to right.
+				Modest improvements to build process.
+
+2006/04/22	9.0-pre2a	Stopgap interim release to sync w/latest
+				unicode-2 CVS.  Includes XPM and partial
+				toolbar support.
+
+2006/06/08	9.0-pre3	Major upgrade to keyboard handling:
+				system-selected compositional input methods
+				should now work, as well as more keys /
+				keyboards.  XPM, toolbar, and tooltip support.
+				Some improvements to scrollbars, zoom, italic
+				rendering, pasting, Color panel.  Added function
+				ns-set-background-alpha to work around
+				inability to customize with numeric colors.
+				
+2006/12/24	9.0-rc1		Reworked font handling and text rendering to
+				use Kenichi Handa's new font back-end system.
+				Font sets are now supported and automatically
+				created when a font is selected.  Added recent
+				X11 colors to Emacs.clr (remove
+				~/Library/Colors/Emacs.clr to pick up).  Added
+				ns-option-modifier, ns-control-modifier,
+				ns-function-modifier customization variables.
+				Update menus to Emacs 21+ conventions.  Right
+				mouse button now generates mouse-3 events.
+				Various bug fixes and rendering improvements.
+
+2007/09/10	9.0-rc2		Improve menubar, popup menu, and scrollbar
+				behavior, let accented char entry work in
+				isearch, follow system keymap for shortcut
+				keys, fix border and box drawing, remove
+				glitches in modeline drawing, support
+				overstrike for unavailable bold fonts, fix XPM
+				related crasher bugs.  Incremental font
+				metrics caching and other performance
+				improvements.  Shared-lisp builds now possible.
+
+2007/09/20	9.0-rc2a	Interim release.  New features: composed
+				character display, colored fringe bitmaps,
+				colored relief drawing, dynamic resizing,
+				Bug fixes: popup menu position and selection,
+				font width calculation, face color adaptation
+				to background, submenu keyboard navigation.
+				NOT TESTED ON GNUSTEP.
+
+2007/11/19	9.0-rc3		Integrated the multi-TTY functionality from
+				emacs core (however, mixed TTY and GUI
+				sessions are not working yet).  Support 10.5.
+				Give site-lisp load precedence over lisp and
+				add a compile option to prefer an additional
+				directory, use miniaturized miniwindow images
+				in some cases, rename cursor types for
+				consistency w/other emacs terms, improved font
+				selection for symbol scripts.
+				Bug fixes: fringe and bitmap, frame deletion,
+				resizing, cursor blink, workspace open-file,
+				image backgrounds, toolbar item enablement,
+				context menu positioning.
+
+2008/07/15	(none)		Merge to GNU Emacs CVS trunk.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nextstep/compile	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,223 @@
+#!/bin/sh
+
+# This script configures and builds Emacs to the subdirectory ./build .
+#
+# If --shared-lisp 'install_prefix' is given, lisp files will be installed to
+# install_prefix/share/emacs/23.0.0.  This option must be run with 'sudo'.
+#
+# Otherwise (default) lisp will be installed under Emacs.app/Contents/Resources.
+# It does this by configuring it to install there, and running "make install".
+#
+# Some setup is different for GNUstep vs. Cocoa, and it determines which one
+# it's on using 'uname'.
+
+# After it is run, Emacs can be run directly from the .app, which itself
+# can be placed anywhere.
+
+# Further C development can be done using Xcode on OS X (not tested recently),
+# or by typing './remake' in the '../src' directory.  Further Lisp
+# development can be done by either copying the files you modify
+# into install location, or running this script again.
+
+
+# Set up path and config variables.
+
+PREFIX=""
+while [ $# -gt 0 ]; do
+    case "$1" in
+	--shared-lisp=*)
+            PREFIX=`echo "$1" | sed s/--shared-lisp=//`
+            shift
+            ;;
+	--enable-local-lisp-path=*)
+            locallisppath=`echo "$1" | sed s/--enable-local-lisp-path=//`
+            shift
+            ;;
+	*)
+            echo "Usage: $0 [--shared-lisp='install_root' --enable-local-lisp-path='some path(s)']"
+            exit
+    esac
+done
+
+DISTDIR=`pwd`/..
+
+#OPTFLAGS='-g -O2'
+OPTFLAGS='-g'
+
+# MAC OS X
+if [ `uname` == "Darwin" ]; then
+    BASEDIR=`pwd`/build/Emacs.app/Contents
+    BINDIR=${BASEDIR}/MacOS
+    if [ "x$PREFIX" == "x" ]; then
+	PREFIX=${BASEDIR}/Resources
+    fi
+# If you want to try experimental enhanced Ctrl-g support, add to NS_CFG_OPTS:
+# --enable-cocoa-experimental-ctrl-g
+# (See bottom of USAGE.txt)
+    NS_CFG_OPTS="--with-ns --without-x --without-freetype --prefix=${PREFIX} --exec_prefix=${BASEDIR}/MacOS --libexecdir=${BASEDIR}/MacOS/libexec"
+# --enable-cocoa-experimental-ctrl-g"
+#    MAKE="make -j3"
+    steve=`/usr/sbin/sysctl hw.ncpu | awk '{print $NF}'`
+    MAKE="make -j`expr $steve + 1`"
+    export CC=gcc-4.0
+    export MACOSX_DEPLOYMENT_TARGET=10.3
+    export MACOSX_DEPLOYMENT_TARGET_ppc=10.3
+    export MACOSX_DEPLOYMENT_TARGET_i386=10.4
+    export CFLAGS="$OPTFLAGS -arch ppc -arch i386"
+# -universal -sdk /Developer/SDKs/MacOSX10.4u.sdk
+# -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk
+
+# GNUSTEP
+else
+
+    # Currently must pass three dirs into Make process via environment variables.
+    source /etc/GNUstep/GNUstep.conf
+    if [ "x$GNUSTEP_MAKEFILES" == "x" ]; then
+	if [ "x$GNUSTEP_SYSTEM_ROOT" == "x" ]; then
+	    echo "Failed to obtain any useful information from /etc/GNUstep/GNUstep.conf."
+	    echo "Please make sure GNUstep is installed on your system."
+	    exit
+	fi
+	GNUSTEP_MAKEFILES=${GNUSTEP_SYSTEM_ROOT}/Library/Makefiles
+	GNUSTEP_SYSTEM_HEADERS=${GNUSTEP_SYSTEM_ROOT}/Library/Headers
+	GNUSTEP_SYSTEM_LIBRARIES=${GNUSTEP_SYSTEM_ROOT}/Library/Libraries
+    fi
+    export GNUSTEP_MAKEFILES
+    export GNUSTEP_SYSTEM_HEADERS
+    export GNUSTEP_SYSTEM_LIBRARIES
+
+    BASEDIR=`pwd`/build/Emacs.app
+    BINDIR=${BASEDIR}
+    if [ "x${PREFIX}" == "x" ]; then
+	PREFIX=${BASEDIR}/Resources
+    fi
+    NS_CFG_OPTS="--with-ns --without-x --without-freetype --prefix=${PREFIX} --exec-prefix=${BASEDIR} --libexecdir=${BASEDIR}/libexec"
+# --enable-cocoa-experimental-ctrl-g
+
+    if [ "x$MAKE" == "x" ]; then
+	if [ "`gmake 2>&1`" == "gmake: *** No targets specified and no makefile found.  Stop." ]; then
+	    MAKE=gmake
+	else
+	    MAKE=make
+	fi
+	export MAKE
+	CFLAGS="$OPTFLAGS"
+	export CFLAGS
+    fi
+
+# PENDING: Not sure why this is needed
+    export EMACSLOADPATH="${DISTDIR}/lisp:${DISTDIR}/lisp/emacs-lisp:${DISTDIR}/leim"
+fi
+
+# End variable setup.
+###############################################################################
+
+# Prepare a clean slate
+rm -fr build/Emacs.app
+
+# Configure if needed
+cd ..
+if [ ! -f Makefile ]; then
+    echo "./configure ${NS_CFG_OPTS}"
+./configure <<EOF ${NS_CFG_OPTS}
+EOF
+#    ./configure ${NS_CFG_OPTS}
+    if [ $? != 0 ]; then
+        echo "*** Configure run failed. ***"
+	echo "Please examine the above output to determine what went wrong,"
+	echo "edit this script (\'compile\') to fix it, and rerun."
+         # These are written BEFORE the job is compete, then it won't get done
+         # next time, causing errors about CTLau-b5, tsang-b5, PY, etc..
+	rm -f leim/changed.misc leim/changed.tit
+        exit 1
+    fi
+fi
+
+# Pete's addition for local lisp load-path
+if [ "x$locallisppath" != "x" ]; then
+    echo " * Local lisp path is being enabled"
+    (cd src
+	if [ -r epaths.h-orig ]; then
+#           mv ../src/epaths.h-orig ../src/epaths.h
+            echo "### src/epaths.h-orig already exists, no further change ###"
+	else
+            mv epaths.h epaths.h-orig
+            printf "s,\(#define PATH_LOADSEARCH \"\),\\\1%s:,\n" "$
+{locallisppath}" > locallisppath.sed
+            cat epaths.h-orig | sed -f locallisppath.sed > epaths.h
+            rm locallisppath.sed
+	fi)
+fi
+
+# Clean up to avoid DOC-xxx and emacs-xxx out-of-controlness
+rm -f ../etc/DOC-* ../src/emacs-*
+
+
+# Go (installs binaries to ./build/Emacs.app, lisp to there or PREFIX)
+echo "make install"
+$MAKE
+status=$?
+
+if [ -f src/epaths.h-orig ]; then
+    mv src/epaths.h-orig src/epaths.h
+fi
+
+if [ $status != 0 ]; then
+    echo "*** Compilation failed. ***"
+    echo "Please examine the above output to determine what went wrong,"
+    echo "edit the configure options in this script (\'compile\') to fix it, and rerun."
+#    rm -f leim/changed.misc leim/changed.tit
+    exit 1
+fi
+
+$MAKE install
+if [ $? != 0 ]; then
+    echo "*** Compilation succeeded, but .app assembly failed. ***"
+    echo "Please examine the above output to determine what went wrong,"
+    echo "edit the configure options in this script (\'compile\') to fix it, and rerun."
+#    rm -f leim/changed.misc leim/changed.tit
+    exit 1
+fi
+
+# Move version stuff up to Resources
+cd ${BASEDIR}/Resources
+if [ -d share/emacs ]; then
+    # clean up self-contained build
+    mv -f share/emacs/*/* .
+fi
+
+if [ ! -d info ]; then
+    # happens on GNUstep, not OS X
+    mv -f share/info .
+fi
+rm -fr share
+
+# Get rid of .el.gz when .elc is present.. purists will complain, but this
+# knocks the app size down substantially.
+cd lisp
+#for f in `find . -name '*.elc' -print | sed -e s/.elc/.{el,el.gz}/`
+#do
+#    rm -f $f
+#done
+
+# Bin cleanup
+cd $BINDIR/bin
+rm -f emacs emacs-23*
+
+# Move libexec stuff up, and link it from bin
+cd ../libexec
+mv -f emacs/*/*/* .
+rm -fr emacs
+cd ../bin
+ln -sf ../libexec/* .
+
+# On OS X, install the bundled ispell
+#if [ `uname` == "Darwin" ]; then
+#    cd $DISTDIR
+#    cp ispell-3.3.01/bin/ispell* ${BINDIR}/libexec
+#    cp -R ispell-3.3.01/lib ${BINDIR}/libexec
+#fi
+
+echo ""
+echo "Build successful."
+echo ""
--- a/src/ChangeLog	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/ChangeLog	Tue Jul 15 18:15:18 2008 +0000
@@ -1,3 +1,134 @@
+2008-07-15  Adrian Robert <Adrian.B.Robert@gmail.com>
+
+	Changes and additions for NeXTstep windowing system (Cocoa and
+	GNUstep) support.
+
+	* Makefile.in
+	* config.in: Support defines and build commands for NS port.
+	* blockinput.h (BLOCK_INPUT, UNBLOCK_INPUT, TOTALLY_UNBLOCK_INPUT)
+	(UNBLOCK_INPUT_TO): Don't use under NS unless EXPERIMENTAL_CONTROL_G.
+	* callproc.c (set_initial_environment): Initialize
+	Vprocess_environment under CANNOT_DUMP (fixes crash when
+	batch-compiling for bootstrap, due to Chris Hall).
+	* dispextern.h: Include nsgui.h and add needed typedefs under NS
+	windowing.
+	(struct face): Add synth_ital field.
+	* dispnew.c: Include nsterm.h when compiling under NS windowing.
+	(init_display): Initialize Vinitial_window_system to "ns" when so
+	compiled.
+	* emacs.c: Include GSConfig.h when compiling under GNUstep.
+	(display_arg): Use under NS.
+	(main): Under NS, allocate autorelease pool and handle command line
+	args.  Move syms_of_xmenu() call under #ifdef HAVE_X_WINDOWS.
+	(standard_args): Add NS-specific args.
+	(shut_down_emacs): Shut down NS terminal if compiled under NS.
+	* font.c (DEFAULT_ENCODING): New variable.
+	(font_find_for_lface): Use it.
+	(syms_of_font): Load syms_of_nsfont under NS.
+	* font.h: Declare nsfont_driver when compiled under NS.
+	* fontset.c: When compiling under NS, include nsterm.h.
+	(fontset_from_font): Autoconstruct fontset under NS.
+	* frame.c (various): Under NS, include nsterm.h, add Qns window system
+	symbol, document and use it.
+	(make_initial_frame): Call init_frame_faces(f) in CANNOT_DUMP case --
+	patch to fix crash due to different init order, due to Chris Hall and
+	Yamamoto Mitsuharu.
+	(do_switch_frame): When for_deletion under Cocoa, add
+	Fraise_frame(Qnil).
+	(x_set_frame_parameters): Ensure font attribute changes are picked up.
+	(x_get_arg): Allow "yes" and "no" as boolean values.
+	(syms_of_frame): Declare Qns.  Init Vdefault_frame_scroll_bars to
+	Qright under Cocoa.
+	(focus-follows-mouse): Default to 0 under NS.
+	* frame.h (enum output_method): Add output_ns.
+	(external_tool_bar, external_menu_bar, FRAME_EXTERNAL_TOOLBAR)
+	(FRAME_EXTERNAL_MENU_BAR): Use under NS.
+	(FRAME_WINDOW_P): NS-specific definition.
+	* fringe.c (max_used_fringe_bitmap): Make public.
+	* getloadavg.c (mach/mach.h): Include it under NeXT descendant OS's.
+	(getloadavg): Use NeXT code under descendant OS's.
+	* image.c (includes and header section, x_create_bitmap_from_data)
+	(x_create_bitmap_from_file, free_bitmap_record, image_background)
+	(image_background_transparent, x_clear_image_1)
+	(x_create_x_image_and_pixmap, x_destroy_x_image, x_put_x_image)
+	(Create_Pixmap_From_Bitmap_Data, xpm_load_image, lookup_rgb_color)
+	(x_to_xcolors, x_from_xcolors, x_disable_image)
+	(x_build_heuristic_mask, syms_of_image): Add NS support parallel to
+	other GUIs, including XPM support using code originally written for
+	Carbon GUI.
+	(png_load, jpeg_load, tiff_load, gif_load): Added implementations
+	using NS API.
+	(image_ascent): Use font metrics macros instead of direct struct field
+	access.
+	* keyboard.c (includes): Add nsterm.h when compiling under NS.
+	(kbd_buffer_get_event): Handle NS as other GUI windowing systems.
+	Also, handle NS as GTK for menu bar purposes.
+	(make_lispy_event): Handle NS as other GUI windowing systems, and as X
+	toolkit where they differ.
+	(parse_menu_item): Prefer keybindings using 'super' modifier.  Also,
+	use cachelist, still needed under NS.
+	* keyboard.h (ENCODE_MENU_STRING, XtPointer, Boolean): Handle as
+	NTGUI.
+	(struct widget_value): Define it here for menu.c.
+	* keymap.c (includes): Include modifier internals.
+	(lisp_to_mod, modifier_sequence_p): New functions, compiled only under
+	NS.
+	(where_is_internal, Fwhere_is_internal): When compiled under NS, add
+	support for preferring sequences using certain modifiers, specified by
+	the FIRSTONLY argument.
+	* lisp.h (hash_remove): Rename to avoid name clash when compiling
+	under NS GNUstep implementation.
+	(USE_LSB_TAG): Use it under Cocoa when compiling under NS.
+	* lread.c (init_lread): Treat NS as HAVE_CARBON for turn_off_warning.
+	* menu.c: Include nsterm.h under NS.
+	(single_menu_item, parse_single_submenu, xmalloc_widget_value)
+	(free_menubar_widget_tree_value, update_submenu_strings)
+	(find_and_call_menu_selection): Treat NS as X and NT.
+	(find_and_return_menu_selection): New function, used for popup menus.
+	* nsgui.h
+	* nsterm.h
+	* nsfns.m
+	* nsimage.m
+	* nsmenu.m
+	* nsselect.m
+	* nsterm.m: New files.
+	* process.c (wait_reading_process_output): Under NS, call ns_select()
+	instead of plain select().
+	* syntax.c (char_quoted): Under NS, avoid a crash when called near
+	beginning of buffer.
+	* sysselect.h (init_process): Rename when compiling under Cocoa to
+	avoid name conflict.
+	* termhooks.h (display_info): Add ns_display_info to union.
+	* terminal.c (Fterminal_live_p): Add ns to terminal types.
+	* terminfo.c (UP, BC, PC): Don't declare when compiling under NS in
+	COCOA environment.
+	* unexnext.c: Update to work with mach API on Mac OS X, and to use new
+	unexec() signature.  (Note, this will dump, but the resulting file
+	crashes; unexosx is used instead; keeping around for reference and
+	possible aid in getting dump working under GNUstep.)
+	* w32gui.h (button_type, widget_value): Remove definitions (now in
+	keyboard.h).
+	* window.c: Include nsterm.h when compiling under NS.
+	* xdisp.c (includes): Include nsterm.h when compiling under NS.
+	(set_frame_menubar, update_menu_bar, display_menu_bar): Handle NS as
+	other GUI windowing systems.
+	(update_tool_bar, redisplay_tool_bar, redisplay_window): Handle NS as
+	GTK.
+	(x_consider_frame_title): Under NS, set icon type and frame
+	modified-state indicator; use ns_set_name_as_filename() when using
+	formatted title.
+	(update_window_cursor): Make public when compiling under NS.
+	(display_hourglass_p, syms_of_xdisp, hourglass_shown_p)
+	(hourglass_atimer, Vhourglass_delay
+	* xfaces.c (header section, init_frame_faces, clear_font_table)
+	(defined_color, unload_color, x_face_list_fonts)
+	(prepare_face_for_display): Add NS support parallel to other GUIs)
+	(emulate GCs like other non-X GUIs.
+	(split_font_name): Don't lowercase font name under NS.
+	(merge_face_ref, Finternal_set_lisp_face_attribute): Support stippling
+	under NS.
+	* s/darwin.h: Add support for compilation under NS.
+
 2008-07-15  Jason Rumney  <jasonr@gnu.org>
 
         * w32fns.c (Fx_create_frame): Remove duplicate unwind_protect.
--- a/src/Makefile.in	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/Makefile.in	Tue Jul 15 18:15:18 2008 +0000
@@ -112,6 +112,11 @@
 #endif
 #endif
 
+/* Under GNUstep, putting libc on the link line causes problems. */
+#ifdef GNUSTEP
+#define LIB_STANDARD
+#endif
+
 /* Unless inhibited or changed, use -lg to link for debugging.  */
 #ifndef LIBS_DEBUG
 #define LIBS_DEBUG -lg
@@ -229,6 +234,15 @@
 #endif /* not ORDINARY_LINK */
 
 
+#ifdef GNUSTEP
+/* Pull in stuff from GNUstep-make. */
+FOUNDATION_LIB=gnu
+GUI_LIB=gnu
+include $(GNUSTEP_MAKEFILES)/Additional/base.make
+include $(GNUSTEP_MAKEFILES)/Additional/gui.make
+shared=no
+#endif
+
 #ifdef HAVE_DBUS
 DBUS_CFLAGS = @DBUS_CFLAGS@
 DBUS_LIBS = @DBUS_LIBS@
@@ -249,8 +263,11 @@
 /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM
    since it may have -I options that should override those two.  */
 ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_SITE C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@
+.SUFFIXES: .m
 .c.o:
 	$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
+.m.o:
+	$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) GNU_OBJC_CFLAGS $<
 
 #ifndef LIBX11_SYSTEM
 #define LIBX11_SYSTEM
@@ -260,13 +277,8 @@
 #define LIB_X11_LIB -lX11
 #endif
 
-/* xmenu.c should not be compiled on OSX.  */
-#ifndef HAVE_CARBON
+#ifdef HAVE_X_WINDOWS
 XMENU_OBJ = xmenu.o
-#endif
-
-#ifdef HAVE_X_WINDOWS
-
 XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o fringe.o image.o
 
 #ifdef HAVE_MENUS
@@ -518,6 +530,21 @@
 emacsappsrc = ${srcdir}/../mac/Emacs.app/
 #endif
 
+#ifdef HAVE_NS
+/* Object files for NeXTstep */
+NS_OBJ= nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o \
+	fontset.o fringe.o image.o
+emacsapp = $(PWD)/../nextstep/build/Emacs.app/
+FONT_DRIVERS = nsfont.o
+#ifdef GNUSTEP
+emacsappsrc = ${srcdir}/../nextstep/GNUstep/Emacs.base
+emacsbindir = $(emacsapp)
+#else
+emacsappsrc = ${srcdir}/../nextstep/Cocoa/Emacs.base
+emacsbindir = $(emacsapp)/Contents/MacOS/
+#endif  /* GNUSTEP */
+#endif  /* HAVE_NS */
+
 #ifdef HAVE_WINDOW_SYSTEM
 #ifdef HAVE_X_WINDOWS
 #if defined (HAVE_XFT)
@@ -545,7 +572,7 @@
 	process.o callproc.o \
 	region-cache.o sound.o atimer.o \
 	doprnt.o strftime.o intervals.o textprop.o composite.o md5.o \
-	$(MSDOS_OBJ) $(MAC_OBJ) $(CYGWIN_OBJ) $(FONT_DRIVERS)
+	$(MSDOS_OBJ) $(MAC_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_DRIVERS)
 
 /* Object files used on some machine or other.
    These go in the DOC file on all machines
@@ -553,6 +580,7 @@
 SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
   xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \
   mac.o macterm.o macfns.o macmenu.o macselect.o fontset.o \
+  nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o \
   w32.o w32console.o w32fns.o w32heap.o w32inevt.o \
   w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o $(FONT_DRIVERS)
 
@@ -876,6 +904,7 @@
    Note that SunOS needs -lm to come before -lc; otherwise, you get
    duplicated symbols.  If the standard libraries were compiled
    with GCC, we might need gnulib again after them.  */
+
 LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \
    LIBGPM LIBRESOLV LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
    LIBS_DEBUG $(GETLOADAVG_LIBS) \
@@ -910,7 +939,10 @@
 	@: bootstrap-emacs, so let us replace it.
 	-ln -f emacs${EXEEXT} bootstrap-emacs${EXEEXT}
 #endif /* ! defined (CANNOT_DUMP) */
+/* XXX: not working under NS currently due to path shenanigans.. */
+#ifndef HAVE_NS
 	-./emacs -q -batch -f list-load-path-shadows
+#endif
 
 /* We run make-docfile twice because the command line may get too long
    on some systems.  */
@@ -935,9 +967,13 @@
 
 temacs${EXEEXT}: $(LOCALCPP) $(STARTFILES) stamp-oldxmenu ${obj} ${otherobj} OBJECTS_MACHINE prefix-args${EXEEXT}
 	echo "${obj} ${otherobj} " OBJECTS_MACHINE > buildobj.lst
+#ifdef GNUSTEP
+	$(CC) -rdynamic YMF_PASS_LDFLAGS (${TEMACS_LDFLAGS}) -o temacs ${obj} ${otherobj} OBJECTS_MACHINE ${LIBES}
+#else
 	$(LD) YMF_PASS_LDFLAGS (${STARTFLAGS} ${TEMACS_LDFLAGS}) $(LDFLAGS) \
     -o temacs ${STARTFILES} ${obj} ${otherobj}  \
     OBJECTS_MACHINE ${LIBES}
+#endif
 
 /* We do not use ALL_LDFLAGS because LD_SWITCH_SYSTEM and LD_SWITCH_MACHINE
    often contain options that have to do with using Emacs''s crt0,
@@ -1080,7 +1116,7 @@
 getloadavg.o: getloadavg.c $(config_h)
 image.o: image.c frame.h window.h dispextern.h blockinput.h atimer.h \
    systime.h xterm.h w32term.h w32gui.h macterm.h macgui.h font.h \
-   $(config_h)
+   nsterm.h nsgui.h $(config_h)
 indent.o: indent.c frame.h window.h indent.h buffer.h $(config_h) termchar.h \
    termopts.h disptab.h region-cache.h character.h category.h composite.h \
    dispextern.h keyboard.h
@@ -1089,7 +1125,8 @@
 keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h character.h \
    commands.h frame.h window.h macros.h disptab.h keyboard.h syssignal.h \
    systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h \
-   atimer.h xterm.h puresize.h msdos.h keymap.h w32term.h macterm.h $(config_h)
+   atimer.h xterm.h puresize.h msdos.h keymap.h w32term.h macterm.h nsterm.h \
+   $(config_h)
 keymap.o: keymap.c buffer.h commands.h keyboard.h termhooks.h blockinput.h \
    atimer.h systime.h puresize.h character.h intervals.h keymap.h window.h \
    $(config_h)
@@ -1155,15 +1192,15 @@
 window.o: window.c indent.h commands.h frame.h window.h buffer.h termchar.h \
    disptab.h keyboard.h dispextern.h msdos.h composite.h \
    keymap.h blockinput.h atimer.h systime.h $(INTERVAL_SRC) \
-   xterm.h w32term.h macterm.h $(config_h)
+   xterm.h w32term.h macterm.h nsterm.h $(config_h)
 xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h \
    coding.h termchar.h frame.h window.h disptab.h termhooks.h character.h     \
    charset.h $(config_h) keyboard.h $(INTERVAL_SRC) region-cache.h xterm.h    \
-   w32term.h macterm.h msdos.h composite.h fontset.h blockinput.h atimer.h    \
-   systime.h keymap.h font.h
+   w32term.h macterm.h nsterm.h msdos.h composite.h fontset.h blockinput.h \
+   atimer.h systime.h keymap.h font.h
 xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h	\
    window.h character.h charset.h msdos.h dosfns.h composite.h atimer.h	\
-   systime.h keyboard.h fontset.h w32term.h macterm.h $(INTERVAL_SRC)	\
+   systime.h keyboard.h fontset.h w32term.h macterm.h nsterm.h $(INTERVAL_SRC) \
    termchar.h termhooks.h font.h $(config_h)
 xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
    $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
@@ -1276,7 +1313,38 @@
 ${emacsapp}Contents/MacOS/Emacs: emacs${EXEEXT}
 	mkdir -p ${emacsapp}Contents/MacOS/;
 	cd ${emacsapp}Contents/MacOS/; cp ../../../../src/emacs${EXEEXT} Emacs${EXEEXT}
-#endif
+#endif /* HAVE_CARBON */
+
+#ifdef HAVE_NS
+abbrev.o buffer.o callint.o cmds.o dispnew.o editfns.o fileio.o frame.o \
+  fontset.o indent.o insdel.o keyboard.o macros.o minibuf.o msdos.o process.o \
+  scroll.o sysdep.o term.o widget.o window.o xdisp.o xfaces.o xfns.o \
+  xterm.o xselect.o sound.o: nsgui.h
+nsfns.o: nsfns.m charset.h nsterm.h nsgui.h frame.h window.h buffer.h \
+  dispextern.h nsgui.h fontset.h $(INTERVAL_SRC) keyboard.h blockinput.h \
+  atimer.h systime.h epaths.h termhooks.h coding.h systime.h $(config_h)
+nsmenu.o: nsmenu.m termhooks.h frame.h window.h dispextern.h \
+  nsgui.h keyboard.h blockinput.h atimer.h systime.h buffer.h \
+  nsterm.h $(config_h)
+nsterm.o: nsterm.m blockinput.h atimer.h systime.h syssignal.h nsterm.h \
+  nsgui.h frame.h charset.h ccl.h dispextern.h fontset.h termhooks.h \
+  termopts.h termchar.h disptab.h buffer.h window.h keyboard.h \
+  $(INTERVAL_SRC) process.h coding.h $(config_h)
+nsselect.o: nsselect.m blockinput.h nsterm.h nsgui.h frame.h $(config_h)
+nsimage.o: nsimage.m nsterm.h
+nsfont.o: nsterm.h dispextern.h frame.h lisp.h $(config_h)
+
+${emacsapp}: ${emacsappsrc}
+	mkdir -p ${emacsapp}
+	( cd ${emacsappsrc} ; tar cfh - . ) | ( cd ${emacsapp} ; tar xf - )
+
+${emacsbindir}Emacs: emacs${EXEEXT}
+	mkdir -p ${emacsbindir}
+	cp -f emacs${EXEEXT} ${emacsbindir}Emacs
+
+ns-app: ${emacsapp} ${emacsbindir}Emacs
+
+#endif /* HAVE_NS */
 
 mostlyclean:
 	rm -f temacs${EXEEXT} prefix-args${EXEEXT} core *.core \#* *.o libXMenu11.a liblw.a
@@ -1285,6 +1353,9 @@
 	rm -f buildobj.lst
 clean: mostlyclean
 	rm -f emacs-*.*.*${EXEEXT} emacs${EXEEXT}
+#ifdef GNUSTEP
+	rm -f *.d
+#endif
 /* bootstrap-clean is used to clean up just before a bootstrap.
    It should remove all files generated during a compilation/bootstrap,
    but not things like config.status or TAGS.  */
--- a/src/blockinput.h	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/blockinput.h	Tue Jul 15 18:15:18 2008 +0000
@@ -59,6 +59,16 @@
 
 extern int pending_atimers;
 
+#if defined HAVE_NS && !defined COCOA_EXPERIMENTAL_CTRL_G
+/* NS does not use interrupt-driven input processing (yet), so this is
+   unneeded and moreover was causing problems. */
+#define BLOCK_INPUT
+#define UNBLOCK_INPUT
+#define TOTALLY_UNBLOCK_INPUT
+#define UNBLOCK_INPUT_TO(LEVEL)
+
+#else
+
 /* Begin critical section. */
 #define BLOCK_INPUT (interrupt_input_blocked++)
 
@@ -115,6 +125,8 @@
     }							\
   while (0)
 
+#endif	/* defined HAVE_NS && !defined COCOA_EXPERIMENTAL_CTRL_G */
+
 #define UNBLOCK_INPUT_RESIGNAL UNBLOCK_INPUT
 
 /* In critical section ? */
--- a/src/callproc.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/callproc.c	Tue Jul 15 18:15:18 2008 +0000
@@ -1587,8 +1587,11 @@
   register char **envp;
 #ifndef CANNOT_DUMP
   if (initialized)
+    {
+#else
+    {
+      Vprocess_environment = Qnil;
 #endif
-    {
       for (envp = environ; *envp; envp++)
 	Vprocess_environment = Fcons (build_string (*envp),
 				      Vprocess_environment);
--- a/src/config.in	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/config.in	Tue Jul 15 18:15:18 2008 +0000
@@ -30,6 +30,10 @@
 /* Define to 1 if the mktime function is broken. */
 #undef BROKEN_MKTIME
 
+/* Define to 1 if you are trying experimental enhanced Ctrl-g support using NS
+   windowing under MacOS X. */
+#undef COCOA_EXPERIMENTAL_CTRL_G
+
 /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
    systems. This function is required for `alloca.c' support on those systems.
    */
@@ -472,6 +476,10 @@
 /* Define to 1 if you have the <nlist.h> header file. */
 #undef HAVE_NLIST_H
 
+/* Define to 1 if you are using the NeXTstep API, either GNUstep or Cocoa on
+   Mac OS X. */
+#undef HAVE_NS
+
 /* Define to 1 if personality LINUX32 can be set. */
 #undef HAVE_PERSONALITY_LINUX32
 
@@ -798,6 +806,12 @@
 /* Define to 1 if you don't have struct exception in math.h. */
 #undef NO_MATHERR
 
+/* Define to 1 if you are using NS windowing under MacOS X. */
+#undef NS_IMPL_COCOA
+
+/* Define to 1 if you are using NS windowing under GNUstep. */
+#undef NS_IMPL_GNUSTEP
+
 /* Define to the address where bug reports for this package should be sent. */
 #undef PACKAGE_BUGREPORT
 
@@ -965,8 +979,8 @@
 #undef volatile
 
 
-/* If we're using any sort of window system, define some consequences.  */
-#ifdef HAVE_X_WINDOWS
+/* If we're using X11/Carbon/GNUstep, define some consequences.  */
+#if defined HAVE_X_WINDOWS || defined(HAVE_CARBON) || defined(HAVE_NS)
 #define HAVE_WINDOW_SYSTEM
 #define MULTI_KBOARD
 #define HAVE_MOUSE
@@ -978,13 +992,15 @@
 #define MULTI_KBOARD
 #endif
 
-/* If we're using the Carbon API on Mac OS X, define a few more
-   variables as well.  */
-#ifdef HAVE_CARBON
-#define HAVE_WINDOW_SYSTEM
-#define HAVE_MOUSE
+/* Sadly for now, GNUstep dump does not work.  */
+#ifdef NS_IMPL_GNUSTEP
+#define CANNOT_DUMP
 #endif
 
+/* PENDING: These are used for the Carbon port only. */
+#undef MAC_OS
+#undef MAC_OSX
+
 /* Define USER_FULL_NAME to return a string
    that is the user's full name.
    It can assume that the variable `pw'
@@ -1037,6 +1053,28 @@
 #include config_opsysfile
 #include config_machfile
 
+/* Set up some defines, C and LD flags for NeXTstep interface on GNUstep.
+  (There is probably a better place to do this, but right now the Cocoa
+   side does this in s/darwin.h, following the Carbon port, and we cannot
+   parallel this exactly since GNUstep is multi-OS. */
+#ifdef HAVE_NS
+# ifdef C_SWITCH_SYSTEM
+# undef C_SWITCH_SYSTEM
+# endif
+# ifdef NS_IMPL_GNUSTEP
+/* See also .m.o rule in Makefile.in */
+#  define C_SWITCH_X_SYSTEM -MMD -MP -D_REENTRANT -fPIC -fno-strict-aliasing
+#  define LD_SWITCH_SITE -lgnustep-gui -lgnustep-base -lobjc $(CONFIG_SYSTEM_LIBS) -lpthread
+#  define GNU_OBJC_CFLAGS -fgnu-runtime -Wno-import -fconstant-string-class=NSConstantString -DGNUSTEP_BASE_LIBRARY=1 -DGNU_GUI_LIBRARY=1 -DGNU_RUNTIME=1 -DGSWARN -DGSDIAGNOSE
+#  define OTHER_FILES ns-app
+# else /* COCOA */
+#  define C_SWITCH_X_SYSTEM
+#  define GNU_OBJC_CFLAGS
+# endif /* COCOA */
+#endif /* HAVE_NS */
+
+
+
 /* If no remapping takes place, static variables cannot be dumped as
    pure, so don't worry about the `static' keyword. */
 #ifdef NO_REMAP
--- a/src/dispextern.h	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/dispextern.h	Tue Jul 15 18:15:18 2008 +0000
@@ -69,6 +69,14 @@
 typedef XImagePtr XImagePtr_or_DC;
 #endif
 
+#ifdef HAVE_NS
+#include "nsgui.h"
+/* following typedef needed to accomodate the MSDOS port, believe it or not */
+typedef struct ns_display_info Display_Info;
+typedef Pixmap XImagePtr;
+typedef XImagePtr XImagePtr_or_DC;
+#endif
+
 #ifndef NativeRectangle
 #define NativeRectangle int
 #endif
@@ -1563,6 +1571,13 @@
   /* If non-zero, use overstrike (to simulate bold-face).  */
   unsigned overstrike : 1;
 
+/* NOTE: this is not used yet, but eventually this impl should be done
+         similarly to overstrike */
+#ifdef HAVE_NS
+  /* If non-zero, use geometric rotation (to simulate italic).  */
+  unsigned synth_ital : 1;
+#endif
+
   /* Next and previous face in hash collision list of face cache.  */
   struct face *next, *prev;
 
--- a/src/dispnew.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/dispnew.c	Tue Jul 15 18:15:18 2008 +0000
@@ -63,6 +63,10 @@
 #include "macterm.h"
 #endif /* MAC_OS */
 
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
+
 /* Include systime.h after xterm.h to avoid double inclusion of time.h.  */
 
 #include "systime.h"
@@ -6895,6 +6899,20 @@
     }
 #endif /* MAC_OS */
 
+#ifdef HAVE_NS
+  if (!inhibit_window_system
+#ifndef CANNOT_DUMP
+     && initialized
+#endif
+      )
+    {
+      Vinitial_window_system = intern("ns");
+      Vwindow_system_version = make_number(10);
+      adjust_frame_glyphs_initially ();
+      return;
+    }
+#endif
+
   /* If no window system has been specified, try to use the terminal.  */
   if (! isatty (0))
     {
--- a/src/emacs.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/emacs.c	Tue Jul 15 18:15:18 2008 +0000
@@ -46,6 +46,11 @@
 #include "w32heap.h" /* for prototype of sbrk */
 #endif
 
+#ifdef NS_IMPL_GNUSTEP
+/* At least under Debian, GSConfig is in a subdirectory.  --Stef  */
+#include <GNUstepBase/GSConfig.h>
+#endif
+
 #include "lisp.h"
 #include "commands.h"
 #include "intervals.h"
@@ -193,7 +198,7 @@
 extern int inherited_pgroup;
 #endif
 
-#ifdef HAVE_X_WINDOWS
+#if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
 /* If non-zero, -d was specified, meaning we're using some window system.  */
 int display_arg;
 #endif
@@ -838,7 +843,7 @@
     run_time_remap (argv[0]);
 #endif
 
-#ifdef MAC_OSX
+#if defined (MAC_OSX) || defined (NS_IMPL_COCOA)
   if (!initialized)
     unexec_init_emacs_zone ();
 #endif
@@ -1410,6 +1415,38 @@
   no_loadup
     = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
 
+#ifdef HAVE_NS
+  ns_alloc_autorelease_pool();
+  if (!noninteractive)
+    {
+      char *tmp;
+      display_arg = 4;
+#ifdef NS_IMPL_COCOA
+      if (skip_args < argc)
+        {
+          if (!strncmp(argv[skip_args], "-psn", 4))
+            {
+              skip_args += 1;
+            }
+          else
+            {
+              if (skip_args+1 < argc && !strncmp(argv[skip_args+1], "-psn", 4))
+                  skip_args += 2;
+            }
+        }
+#endif
+      /* This used for remote operation.. not fully implemented yet. */
+      if (argmatch (argv, argc, "-_NSMachLaunch", 0, 3, &tmp, &skip_args))
+          display_arg = 4;
+      else if (argmatch (argv, argc, "-MachLaunch", 0, 3, &tmp, &skip_args))
+          display_arg = 4;
+      else if (argmatch (argv, argc, "-macosx", 0, 2, NULL, &skip_args))
+          display_arg = 4;
+      else if (argmatch (argv, argc, "-NSHost", 0, 3, &tmp, &skip_args))
+          display_arg = 4;
+    }
+#endif /* HAVE_NS */
+
 #ifdef HAVE_X_WINDOWS
   /* Stupid kludge to catch command-line display spec.  We can't
      handle this argument entirely in window system dependent code
@@ -1487,6 +1524,13 @@
     init_mac_osx_environment ();
 #endif
 
+#ifdef HAVE_NS
+#ifndef CANNOT_DUMP
+  if (initialized)
+#endif
+    ns_init_paths ();
+#endif
+
   /* egetenv is a pretty low-level facility, which may get called in
      many circumstances; it seems flimsy to put off initializing it
      until calling init_callproc.  */
@@ -1588,6 +1632,7 @@
 #ifdef HAVE_X_WINDOWS
       syms_of_xterm ();
       syms_of_xfns ();
+      syms_of_xmenu ();
       syms_of_fontset ();
 #ifdef HAVE_X_SM
       syms_of_xsmfns ();
@@ -1599,13 +1644,6 @@
 
       syms_of_menu ();
 
-#ifndef HAVE_NTGUI
-#ifndef MAC_OS
-      /* Called before init_window_once for Mac OS Classic.  */
-      syms_of_xmenu ();
-#endif
-#endif
-
 #ifdef HAVE_NTGUI
       syms_of_w32term ();
       syms_of_w32fns ();
@@ -1622,6 +1660,14 @@
       syms_of_fontset ();
 #endif /* MAC_OSX && HAVE_CARBON */
 
+#ifdef HAVE_NS
+      syms_of_nsterm ();
+      syms_of_nsfns ();
+      syms_of_nsmenu ();
+      syms_of_nsselect ();
+      syms_of_fontset ();
+#endif /* HAVE_NS */
+
 #ifdef HAVE_DBUS
       syms_of_dbusbind ();
 #endif /* HAVE_DBUS */
@@ -1843,6 +1889,15 @@
   { "-color", "--color", 5, 0},
   { "-no-splash", "--no-splash", 3, 0 },
   { "-no-desktop", "--no-desktop", 3, 0 },
+#ifdef HAVE_NS
+  { "-NSAutoLaunch", 0, 5, 1 },
+  { "-NXAutoLaunch", 0, 5, 1 },
+  { "-disable-font-backend", "--disable-font-backend", 65, 0 },
+  { "-_NSMachLaunch", 0, 85, 1 },
+  { "-MachLaunch", 0, 85, 1 },
+  { "-macosx", 0, 85, 0 },
+  { "-NSHost", 0, 85, 1 },
+#endif
   /* These have the same priority as ordinary file name args,
      so they are not reordered with respect to those.  */
   { "-L", "--directory", 0, 1 },
@@ -1862,6 +1917,13 @@
   { "-visit", "--visit", 0, 1 },
   { "-file", "--file", 0, 1 },
   { "-insert", "--insert", 0, 1 },
+#ifdef HAVE_NS
+  { "-NXOpen", 0, 0, 1 },
+  { "-NXOpenTemp", 0, 0, 1 },
+  { "-NSOpen", 0, 0, 1 },
+  { "-NSOpenTemp", 0, 0, 1 },
+  { "-GSFilePath", 0, 0, 1 },
+#endif
   /* This should be processed after ordinary file name args and the like.  */
   { "-kill", "--kill", -10, 0 },
 };
@@ -2158,6 +2220,10 @@
 #ifdef MSDOS
   dos_cleanup ();
 #endif
+
+#ifdef HAVE_NS
+  ns_term_shutdown (sig);
+#endif
 }
 
 
--- a/src/font.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/font.c	Tue Jul 15 18:15:18 2008 +0000
@@ -46,6 +46,10 @@
 #include "w32term.h"
 #endif /* HAVE_NTGUI */
 
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif /* HAVE_NS */
+
 #ifdef MAC_OS
 #include "macterm.h"
 #endif /* MAC_OS */
@@ -57,6 +61,12 @@
 /* Important character set strings.  */
 Lisp_Object Qascii_0, Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip;
 
+#ifdef HAVE_NS
+#define DEFAULT_ENCODING Qiso10646_1
+#else
+#define DEFAULT_ENCODING Qiso8859_1
+#endif
+
 /* Special vector of zero length.  This is repeatedly used by (struct
    font_driver *)->list when a specified font is not found. */
 static Lisp_Object null_vector;
@@ -3096,7 +3106,7 @@
   registry[0] = AREF (spec, FONT_REGISTRY_INDEX);
   if (NILP (registry[0]))
     {
-      registry[0] = Qiso8859_1;
+      registry[0] = DEFAULT_ENCODING;
       registry[1] = Qascii_0;
       registry[2] = null_vector;
     }
@@ -4948,6 +4958,7 @@
 extern void syms_of_bdffont P_ (());
 extern void syms_of_w32font P_ (());
 extern void syms_of_atmfont P_ (());
+extern void syms_of_nsfont P_ (());
 
 void
 syms_of_font ()
@@ -5117,6 +5128,9 @@
 #ifdef WINDOWSNT
   syms_of_w32font ();
 #endif	/* WINDOWSNT */
+#ifdef HAVE_NS
+  syms_of_nsfont ();
+#endif	/* HAVE_NS */
 #ifdef MAC_OS
   syms_of_atmfont ();
 #endif	/* MAC_OS */
--- a/src/font.h	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/font.h	Tue Jul 15 18:15:18 2008 +0000
@@ -860,6 +860,9 @@
 #ifdef MAC_OS
 extern struct font_driver atmfont_driver;
 #endif	/* MAC_OS */
+#ifdef HAVE_NS
+extern struct font_driver nsfont_driver;
+#endif	/* HAVE_NS */
 
 #ifndef FONT_DEBUG
 #define FONT_DEBUG
--- a/src/fontset.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/fontset.c	Tue Jul 15 18:15:18 2008 +0000
@@ -47,6 +47,9 @@
 #ifdef WINDOWSNT
 #include "w32term.h"
 #endif
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
 #ifdef MAC_OS
 #include "macterm.h"
 #endif
@@ -1622,6 +1625,11 @@
     ASET (font_spec, i, Qnil);
   Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qnil);
   Fset_fontset_font (name, Qnil, font_spec, Qnil, Qnil);
+
+#ifdef HAVE_NS
+  nsfont_make_fontset_for_font(name, font_object);
+#endif
+
   return XINT (FONTSET_ID (fontset));
 }
 
--- a/src/frame.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/frame.c	Tue Jul 15 18:15:18 2008 +0000
@@ -32,6 +32,9 @@
 #ifdef MAC_OS
 #include "macterm.h"
 #endif
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
 #include "buffer.h"
 /* These help us bind and responding to switch-frame events.  */
 #include "commands.h"
@@ -72,7 +75,7 @@
 Lisp_Object Qframep, Qframe_live_p;
 Lisp_Object Qicon, Qmodeline;
 Lisp_Object Qonly;
-Lisp_Object Qx, Qw32, Qmac, Qpc;
+Lisp_Object Qx, Qw32, Qmac, Qpc, Qns;
 Lisp_Object Qvisible;
 Lisp_Object Qdisplay_type;
 Lisp_Object Qbackground_mode;
@@ -203,7 +206,8 @@
 Value is t for a termcap frame (a character-only terminal),
 `x' for an Emacs frame that is really an X window,
 `w32' for an Emacs frame that is a window on MS-Windows display,
-`mac' for an Emacs frame on a Macintosh display,
+`mac' for an Emacs frame on a Macintosh 8/9 X-Carbon display,
+`ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
 `pc' for a direct-write MS-DOS frame.
 See also `frame-live-p'.  */)
      (object)
@@ -224,6 +228,8 @@
       return Qpc;
     case output_mac:
       return Qmac;
+    case output_ns:
+      return Qns;
     default:
       abort ();
     }
@@ -551,6 +557,11 @@
   FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
   FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
 
+#ifdef CANNOT_DUMP
+  if (!noninteractive)
+    init_frame_faces (f);
+#endif
+
   return f;
 }
 
@@ -880,6 +891,12 @@
 
   Fselect_window (XFRAME (frame)->selected_window, Qnil);
 
+#ifdef NS_IMPL_COCOA
+  /* term gets no other notification of this */
+  if (for_deletion)
+    Fraise_frame(Qnil);
+#endif
+
   /* We want to make sure that the next event generates a frame-switch
      event to the appropriate frame.  This seems kludgy to me, but
      before you take it out, make sure that evaluating something like
@@ -2969,8 +2986,9 @@
 
 	  old_value = get_frame_param (f, prop);
  	  fullscreen_is_being_set |= EQ (prop, Qfullscreen);
-
+#ifndef HAVE_NS  /* PENDING: ensure font attrs change goes through */
 	  if (NILP (Fequal (val, old_value)))
+#endif
 	    {
 	      store_frame_param (f, prop, val);
 
@@ -3949,6 +3967,9 @@
 	    case RES_TYPE_BOOLEAN:
 	      tem = Fdowncase (tem);
 	      if (!strcmp (SDATA (tem), "on")
+#ifdef HAVE_NS
+                  || !strcmp(SDATA(tem), "yes")
+#endif
 		  || !strcmp (SDATA (tem), "true"))
 		return Qt;
 	      else
@@ -3964,9 +3985,15 @@
 		Lisp_Object lower;
 		lower = Fdowncase (tem);
 		if (!strcmp (SDATA (lower), "on")
+#ifdef HAVE_NS
+                    || !strcmp(SDATA(lower), "yes")
+#endif
 		    || !strcmp (SDATA (lower), "true"))
 		  return Qt;
 		else if (!strcmp (SDATA (lower), "off")
+#ifdef HAVE_NS
+                      || !strcmp(SDATA(lower), "no")
+#endif
 		      || !strcmp (SDATA (lower), "false"))
 		  return Qnil;
 		else
@@ -4366,6 +4393,8 @@
   staticpro (&Qpc);
   Qmac = intern ("mac");
   staticpro (&Qmac);
+  Qns = intern ("ns");
+  staticpro (&Qns);
   Qvisible = intern ("visible");
   staticpro (&Qvisible);
   Qbuffer_predicate = intern ("buffer-predicate");
@@ -4473,8 +4502,8 @@
   DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars,
 	       doc: /* Default position of scroll bars on this window-system.  */);
 #ifdef HAVE_WINDOW_SYSTEM
-#if defined(HAVE_NTGUI) || defined(MAC_OS)
-  /* MS-Windows has scroll bars on the right by default.  */
+#if defined(HAVE_NTGUI) || defined(MAC_OS) || defined(NS_IMPL_COCOA)
+  /* MS-Windows and Mac OS X have scroll bars on the right by default.  */
   Vdefault_frame_scroll_bars = Qright;
 #else
   Vdefault_frame_scroll_bars = Qleft;
@@ -4540,7 +4569,7 @@
 handles focus, since there is no way in general for Emacs to find out
 automatically.  */);
 #ifdef HAVE_WINDOW_SYSTEM
-#if defined(HAVE_NTGUI) || defined(MAC_OS)
+#if defined(HAVE_NTGUI) || defined(MAC_OS) || defined(HAVE_NS)
   focus_follows_mouse = 0;
 #else
   focus_follows_mouse = 1;
--- a/src/frame.h	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/frame.h	Tue Jul 15 18:15:18 2008 +0000
@@ -50,7 +50,8 @@
   output_x_window,
   output_msdos_raw,
   output_w32,
-  output_mac
+  output_mac,
+  output_ns
 };
 
 enum vertical_scroll_bar_type
@@ -242,7 +243,7 @@
      auto-resize-tool-bar is set to grow-only.  */
   unsigned minimize_tool_bar_window_p : 1;
 
-#if defined (USE_GTK) || defined (MAC_OS)
+#if defined (USE_GTK) || defined (HAVE_NS) || defined (MAC_OS)
   /* Nonzero means using a tool bar that comes from the toolkit.  */
   int external_tool_bar;
 #endif
@@ -332,6 +333,7 @@
     struct x_output *x;         /* xterm.h */
     struct w32_output *w32;     /* w32term.h */
     struct mac_output *mac;     /* macterm.h */
+    struct ns_output *ns;       /* nsterm.h */
     EMACS_INT nothing;
   }
   output_data;
@@ -359,7 +361,7 @@
   int menu_bar_lines;
 
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+    || defined (HAVE_NS) || defined (USE_GTK)
   /* Nonzero means using a menu bar that comes from the X toolkit.  */
   unsigned int external_menu_bar : 1;
 #endif
@@ -519,6 +521,7 @@
 #define FRAME_W32_P(f) ((f)->output_method == output_w32)
 #define FRAME_MSDOS_P(f) ((f)->output_method == output_msdos_raw)
 #define FRAME_MAC_P(f) ((f)->output_method == output_mac)
+#define FRAME_NS_P(f) ((f)->output_method == output_ns)
 
 /* FRAME_WINDOW_P tests whether the frame is a window, and is
    defined to be the predicate for the window system being used.  */
@@ -532,6 +535,9 @@
 #ifdef MAC_OS
 #define FRAME_WINDOW_P(f) FRAME_MAC_P (f)
 #endif
+#ifdef HAVE_NS
+#define FRAME_WINDOW_P(f) FRAME_NS_P(f)
+#endif
 #ifndef FRAME_WINDOW_P
 #define FRAME_WINDOW_P(f) (0)
 #endif
@@ -570,7 +576,7 @@
 
 /* Nonzero if this frame should display a tool bar
    in a way that does not use any text lines.  */
-#if defined (USE_GTK) || defined (MAC_OS)
+#if defined (USE_GTK) || defined (HAVE_NS) || defined (MAC_OS)
 #define FRAME_EXTERNAL_TOOL_BAR(f) (f)->external_tool_bar
 #else
 #define FRAME_EXTERNAL_TOOL_BAR(f) 0
@@ -589,7 +595,7 @@
 /* Nonzero if this frame should display a menu bar
    in a way that does not use any text lines.  */
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+     || defined (HAVE_NS) || defined (USE_GTK)
 #define FRAME_EXTERNAL_MENU_BAR(f) (f)->external_menu_bar
 #else
 #define FRAME_EXTERNAL_MENU_BAR(f) 0
@@ -1044,7 +1050,7 @@
 extern Lisp_Object Qheight, Qwidth;
 extern Lisp_Object Qminibuffer, Qmodeline;
 extern Lisp_Object Qonly;
-extern Lisp_Object Qx, Qw32, Qmac, Qpc;
+extern Lisp_Object Qx, Qw32, Qmac, Qpc, Qns;
 extern Lisp_Object Qvisible;
 extern Lisp_Object Qdisplay_type;
 extern Lisp_Object Qbackground_mode;
--- a/src/fringe.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/fringe.c	Tue Jul 15 18:15:18 2008 +0000
@@ -482,7 +482,7 @@
 static Lisp_Object *fringe_faces;
 static int max_fringe_bitmaps;
 
-static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
+int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
 
 
 /* Lookup bitmap number for symbol BITMAP.
--- a/src/getloadavg.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/getloadavg.c	Tue Jul 15 18:15:18 2008 +0000
@@ -420,7 +420,7 @@
 #  define host_self mach_host_self
 # endif
 
-# ifdef NeXT
+# if defined(NeXT) || defined(RHAPSODY) || defined(DARWIN) || defined(MAC_OSX)
 #  ifdef HAVE_MACH_MACH_H
 #   include <mach/mach.h>
 #  else
@@ -467,7 +467,7 @@
 
 /* Avoid static vars inside a function since in HPUX they dump as pure.  */
 
-# ifdef NeXT
+# if defined(NeXT) || defined(RHAPSODY) || defined(DARWIN) || defined(MAC_OSX)
 static processor_set_t default_set;
 static int getloadavg_initialized;
 # endif /* NeXT */
@@ -647,7 +647,8 @@
 
 # endif /* __NetBSD__ */
 
-# if !defined (LDAV_DONE) && defined (NeXT)
+# if !defined (LDAV_DONE) && ( defined (NeXT) || defined(RHAPSODY) \
+                              || defined(DARWIN) || defined(MAC_OSX) )
 #  define LDAV_DONE
   /* The NeXT code was adapted from iscreen 3.2.  */
 
--- a/src/image.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/image.c	Tue Jul 15 18:15:18 2008 +0000
@@ -131,6 +131,32 @@
 #endif /* MAC_OS */
 
 
+#ifdef HAVE_NS
+#include "nsterm.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#undef COLOR_TABLE_SUPPORT
+
+typedef struct ns_bitmap_record Bitmap_Record;
+
+#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
+#define NO_PIXMAP 0
+
+#define RGB_PIXEL_COLOR unsigned long
+#define ZPixmap 0
+
+#define PIX_MASK_RETAIN	0
+#define PIX_MASK_DRAW	1
+
+#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
+#define x_defined_color(f, name, color_def, alloc) \
+  ns_defined_color (f, name, color_def, alloc, 0)
+#define FRAME_X_SCREEN(f) 0
+#define DefaultDepthOfScreen(screen) ns_display_list->n_planes
+#endif /* HAVE_NS */
+
+
 /* Search path for bitmap files.  */
 
 Lisp_Object Vx_bitmap_file_path;
@@ -403,6 +429,33 @@
 #endif /* USE_CG_DRAWING */
 #endif /* MAC_OS */
 
+#ifdef HAVE_NS
+XImagePtr
+XGetImage (Display *display, Pixmap pixmap, int x, int y,
+           unsigned int width, unsigned int height,
+           unsigned long plane_mask, int format)
+{
+  /* PENDING: not sure what this function is supposed to do.. */
+  ns_retain_object(pixmap);
+  return pixmap;
+}
+
+/* use with imgs created by ns_image_for_XPM */
+unsigned long
+XGetPixel (XImagePtr ximage, int x, int y)
+{
+  return ns_get_pixel(ximage, x, y);
+}
+
+/* use with imgs created by ns_image_for_XPM; alpha set to 1;
+   pixel is assumed to be in form RGB */
+void
+XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
+{
+  ns_put_pixel(ximage, x, y, pixel);
+}
+#endif /* HAVE_NS */
+
 
 /* Functions to access the contents of a bitmap, given an id.  */
 
@@ -519,12 +572,23 @@
     return -1;
 #endif
 
+#ifdef HAVE_NS
+  void *bitmap = ns_image_from_XBM(bits, width, height);
+  if (!bitmap)
+      return -1;
+#endif
+
   id = x_allocate_bitmap_record (f);
 #ifdef MAC_OS
   dpyinfo->bitmaps[id - 1].bitmap_data = (char *) xmalloc (height * width);
   bcopy (bits, dpyinfo->bitmaps[id - 1].bitmap_data, height * width);
 #endif  /* MAC_OS */
 
+#ifdef HAVE_NS
+  dpyinfo->bitmaps[id - 1].img = bitmap;
+  dpyinfo->bitmaps[id - 1].depth = 1;
+#endif
+
   dpyinfo->bitmaps[id - 1].file = NULL;
   dpyinfo->bitmaps[id - 1].height = height;
   dpyinfo->bitmaps[id - 1].width = width;
@@ -552,6 +616,8 @@
      struct frame *f;
      Lisp_Object file;
 {
+  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
 #ifdef MAC_OS
   return -1;  /* MAC_TODO : bitmap support */
 #endif  /* MAC_OS */
@@ -560,8 +626,26 @@
   return -1;  /* W32_TODO : bitmap support */
 #endif /* HAVE_NTGUI */
 
+#ifdef HAVE_NS
+  int id;
+  void *bitmap = ns_image_from_file(file);
+
+  if (!bitmap)
+      return -1;
+
+
+  id = x_allocate_bitmap_record (f);
+  dpyinfo->bitmaps[id - 1].img = bitmap;
+  dpyinfo->bitmaps[id - 1].refcount = 1;
+  dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (SBYTES (file) + 1);
+  dpyinfo->bitmaps[id - 1].depth = 1;
+  dpyinfo->bitmaps[id - 1].height = ns_image_width(bitmap);
+  dpyinfo->bitmaps[id - 1].width = ns_image_height(bitmap);
+  strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
+  return id;
+#endif
+
 #ifdef HAVE_X_WINDOWS
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   unsigned int width, height;
   Pixmap bitmap;
   int xhot, yhot, result, id;
@@ -630,6 +714,10 @@
   bm->bitmap_data = NULL;
 #endif  /* MAC_OS */
 
+#ifdef HAVE_NS
+  ns_release_object(bm->img);
+#endif
+
   if (bm->file)
     {
       xfree (bm->file);
@@ -1407,7 +1495,8 @@
 	     because a typical font is `top-heavy' (due to the presence
 	     uppercase letters), so the image placement should err towards
 	     being top-heavy too.  It also just generally looks better.  */
-	  ascent = (height + face->font->ascent - face->font->descent + 1) / 2;
+	  ascent = (height + FONT_BASE(face->font)
+                    - FONT_DESCENT(face->font) + 1) / 2;
 #endif /* HAVE_NTGUI */
 	}
       else
@@ -1476,6 +1565,14 @@
 #define Free_Pixmap(display, pixmap) \
   DeleteObject (pixmap)
 
+#elif defined (HAVE_NS)
+
+#define Destroy_Image(ximg, dummy) \
+  ns_release_object(ximg)
+
+#define Free_Pixmap(display, pixmap) \
+  ns_release_object(pixmap)
+
 #else
 
 #define Destroy_Image(ximg, dummy) \
@@ -1484,7 +1581,7 @@
 #define Free_Pixmap(display, pixmap) \
   XFreePixmap (display, pixmap)
 
-#endif /* HAVE_NTGUI */
+#endif /* !HAVE_NTGUI && !HAVE_NS */
 
 
 /* Return the `background' field of IMG.  If IMG doesn't have one yet,
@@ -1607,6 +1704,10 @@
     {
       Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
       img->pixmap = NO_PIXMAP;
+#ifdef HAVE_NS
+      if (img->background_valid)
+        ns_free_indexed_color(img->background);
+#endif
       img->background_valid = 0;
     }
 
@@ -2387,6 +2488,18 @@
   return 1;
 
 #endif  /* MAC_OS */
+
+#ifdef HAVE_NS
+  *pixmap = ns_image_for_XPM(width, height, depth);
+  if (*pixmap == 0)
+    {
+      *ximg = NULL;
+      image_error ("Unable to allocate NSImage for XPM pixmap", Qnil, Qnil);
+      return 0;
+    }
+  *ximg = *pixmap;
+  return 1;
+#endif
 }
 
 
@@ -2412,6 +2525,9 @@
 #ifdef MAC_OS
       XDestroyImage (ximg);
 #endif /* MAC_OS */
+#ifdef HAVE_NS
+      ns_release_object(ximg);
+#endif /* HAVE_NS */
     }
 }
 
@@ -2446,6 +2562,11 @@
 #ifdef MAC_OS
   xassert (ximg == pixmap);
 #endif  /* MAC_OS */
+
+#ifdef HAVE_NS
+  xassert (ximg == pixmap);
+  ns_retain_object(ximg);
+#endif
 }
 
 
@@ -3499,6 +3620,10 @@
   /* If colors were specified, transfer the bitmap to a color one.  */
   if (non_default_colors)
     convert_mono_to_color_image (f, img, fg, bg);
+
+#elif defined (HAVE_NS)
+  img->pixmap = ns_image_from_XBM(data, img->width, img->height);
+
 #else
   img->pixmap
     = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
@@ -3507,7 +3632,7 @@
 				   img->width, img->height,
 				   fg, bg,
 				   DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
-#endif /* HAVE_NTGUI */
+#endif /* !HAVE_NTGUI && !HAVE_NS */
 }
 
 
@@ -3891,13 +4016,13 @@
 			      XPM images
  ***********************************************************************/
 
-#if defined (HAVE_XPM) || defined (MAC_OS)
+#if defined (HAVE_XPM) || defined (MAC_OS) || defined (HAVE_NS)
 
 static int xpm_image_p P_ ((Lisp_Object object));
 static int xpm_load P_ ((struct frame *f, struct image *img));
 static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
 
-#endif /* HAVE_XPM || MAC_OS */
+#endif /* HAVE_XPM || MAC_OS || HAVE_NS */
 
 #ifdef HAVE_XPM
 #ifdef HAVE_NTGUI
@@ -3920,7 +4045,7 @@
 #endif /* HAVE_NTGUI */
 #endif /* HAVE_XPM */
 
-#if defined (HAVE_XPM) || defined (MAC_OS)
+#if defined (HAVE_XPM) || defined (MAC_OS) || defined (HAVE_NS)
 /* The symbol `xpm' identifying XPM-format images.  */
 
 Lisp_Object Qxpm;
@@ -4247,7 +4372,7 @@
 	      || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
 }
 
-#endif /* HAVE_XPM || MAC_OS */
+#endif /* HAVE_XPM || MAC_OS || HAVE_NS */
 
 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
 int
@@ -4526,7 +4651,7 @@
 
 #endif /* HAVE_XPM */
 
-#ifdef MAC_OS
+#if defined (MAC_OS) || ( defined (HAVE_NS) && !defined (HAVE_XPM) )
 
 /* XPM support functions for Mac OS where libxpm is not available.
    Only XPM version 3 (without any extensions) is supported.  */
@@ -4884,8 +5009,11 @@
 
   if (!x_create_x_image_and_pixmap (f, width, height, 0,
 				    &ximg, &img->pixmap)
+#ifndef HAVE_NS
       || !x_create_x_image_and_pixmap (f, width, height, 1,
-				       &mask_img, &img->mask))
+				       &mask_img, &img->mask)
+#endif
+      )
     {
       image_error ("Out of memory (%s)", img->spec, Qnil);
       goto error;
@@ -4905,9 +5033,14 @@
 	  XPutPixel (ximg, x, y,
 		     (INTEGERP (color_val) ? XINT (color_val)
 		      : FRAME_FOREGROUND_PIXEL (f)));
+#ifndef HAVE_NS
 	  XPutPixel (mask_img, x, y,
 		     (!EQ (color_val, Qt) ? PIX_MASK_DRAW
 		      : (have_mask = 1, PIX_MASK_RETAIN)));
+#else
+          if (EQ(color_val, Qt))
+            ns_set_alpha(ximg, x, y, 0);
+#endif
 	}
       if (y + 1 < height)
 	expect (',');
@@ -4922,6 +5055,7 @@
 
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
+#ifndef HAVE_NS
   if (have_mask)
     {
       /* Fill in the background_transparent field while we have the
@@ -4937,7 +5071,7 @@
       Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
       img->mask = NO_PIXMAP;
     }
-
+#endif
   return 1;
 
  failure:
@@ -5003,7 +5137,7 @@
   return success_p;
 }
 
-#endif /* MAC_OS */
+#endif /* MAC_OS || (HAVE_NS && !HAVE_XPM) */
 
 
 
@@ -5273,6 +5407,9 @@
   pixel = PALETTERGB (r >> 8, g >> 8, b >> 8);
 #endif /* HAVE_NTGUI */
 
+#ifdef HAVE_NS
+  pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
+#endif /* HAVE_NS */
   return pixel;
 }
 
@@ -5378,7 +5515,7 @@
 	  p->pixel = GET_PIXEL (ximg, x, y);
 	  if (rgb_p)
 	    {
-#ifdef MAC_OS
+#if defined (MAC_OS) || defined (HAVE_NS)
 	      p->red = RED16_FROM_ULONG (p->pixel);
 	      p->green = GREEN16_FROM_ULONG (p->pixel);
 	      p->blue = BLUE16_FROM_ULONG (p->pixel);
@@ -5459,8 +5596,8 @@
      XColor *colors;
 {
   int x, y;
-  XImagePtr oimg;
-  Pixmap pixmap;
+  XImagePtr oimg = NULL;
+  Pixmap pixmap = NULL;
   XColor *p;
 
   init_color_table ();
@@ -5673,6 +5810,8 @@
       Display *dpy = FRAME_X_DISPLAY (f);
       GC gc;
 
+#ifndef HAVE_NS  //TODO: NS support, however this not needed for toolbars
+
 #ifdef MAC_OS
 #define MaskForeground(f)  PIX_MASK_DRAW
 #else
@@ -5697,6 +5836,7 @@
 		     img->width - 1, 0);
 	  XFreeGC (dpy, gc);
 	}
+#endif /* !HAVE_NS */
 #else
       HDC hdc, bmpdc;
       HGDIOBJ prev;
@@ -5762,11 +5902,13 @@
     }
 
 #ifndef HAVE_NTGUI
+#ifndef HAVE_NS
   /* Create an image and pixmap serving as mask.  */
   rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1,
 				    &mask_img, &img->mask);
   if (!rc)
     return 0;
+#endif /* !HAVE_NS */
 
   /* Get the X image of IMG->pixmap.  */
   ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, 0, 0,
@@ -5820,16 +5962,21 @@
 #ifndef HAVE_NTGUI
   for (y = 0; y < img->height; ++y)
     for (x = 0; x < img->width; ++x)
+#ifndef HAVE_NS
       XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg
 				  ? PIX_MASK_DRAW : PIX_MASK_RETAIN));
-
+#else
+      if (XGetPixel (ximg, x, y) == bg)
+        ns_set_alpha(ximg, x, y, 0);
+#endif /* HAVE_NS */
+#ifndef HAVE_NS
   /* Fill in the background_transparent field while we have the mask handy. */
   image_background_transparent (img, f, mask_img);
 
   /* Put mask_img into img->mask.  */
   x_put_x_image (f, mask_img, img->mask, img->width, img->height);
   x_destroy_x_image (mask_img);
-
+#endif /* !HAVE_NS */
 #else
   for (y = 0; y < img->height; ++y)
     for (x = 0; x < img->width; ++x)
@@ -6280,7 +6427,7 @@
 				 PNG
  ***********************************************************************/
 
-#if defined (HAVE_PNG) || defined (MAC_OS)
+#if defined (HAVE_PNG) || defined (MAC_OS) || defined (HAVE_NS)
 
 /* Function prototypes.  */
 
@@ -6352,7 +6499,7 @@
   return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
 }
 
-#endif /* HAVE_PNG || MAC_OS */
+#endif /* HAVE_PNG || MAC_OS || HAVE_NS */
 
 
 #ifdef HAVE_PNG
@@ -6912,6 +7059,17 @@
 }
 #endif  /* MAC_OS */
 
+#ifdef HAVE_NS
+static int
+png_load (struct frame *f, struct image *img)
+{
+  return ns_load_image(f, img,
+                       image_spec_value (img->spec, QCfile, NULL),
+                       image_spec_value (img->spec, QCdata, NULL));
+}
+#endif  /* HAVE_NS */
+
+
 #endif /* !HAVE_PNG */
 
 
@@ -6920,7 +7078,7 @@
 				 JPEG
  ***********************************************************************/
 
-#if defined (HAVE_JPEG) || defined (MAC_OS)
+#if defined (HAVE_JPEG) || defined (MAC_OS) || defined (HAVE_NS)
 
 static int jpeg_image_p P_ ((Lisp_Object object));
 static int jpeg_load P_ ((struct frame *f, struct image *img));
@@ -6991,7 +7149,7 @@
   return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
 }
 
-#endif /* HAVE_JPEG || MAC_OS */
+#endif /* HAVE_JPEG || MAC_OS || HAVE_NS */
 
 #ifdef HAVE_JPEG
 
@@ -7491,6 +7649,16 @@
 }
 #endif  /* MAC_OS */
 
+#ifdef HAVE_NS
+static int
+jpeg_load (struct frame *f, struct image *img)
+{
+  return ns_load_image(f, img,
+                       image_spec_value (img->spec, QCfile, NULL),
+                       image_spec_value (img->spec, QCdata, NULL));
+}
+#endif  /* HAVE_NS */
+
 #endif /* !HAVE_JPEG */
 
 
@@ -7499,7 +7667,7 @@
 				 TIFF
  ***********************************************************************/
 
-#if defined (HAVE_TIFF) || defined (MAC_OS)
+#if defined (HAVE_TIFF) || defined (MAC_OS) || defined (HAVE_NS)
 
 static int tiff_image_p P_ ((Lisp_Object object));
 static int tiff_load P_ ((struct frame *f, struct image *img));
@@ -7569,7 +7737,7 @@
   return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
 }
 
-#endif /* HAVE_TIFF || MAC_OS */
+#endif /* HAVE_TIFF || MAC_OS || HAVE_NS */
 
 #ifdef HAVE_TIFF
 
@@ -7916,6 +8084,16 @@
 }
 #endif /* MAC_OS */
 
+#ifdef HAVE_NS
+static int
+tiff_load (struct frame *f, struct image *img)
+{
+  return ns_load_image(f, img,
+                       image_spec_value (img->spec, QCfile, NULL),
+                       image_spec_value (img->spec, QCdata, NULL));
+}
+#endif  /* HAVE_NS */
+
 #endif /* !HAVE_TIFF */
 
 
@@ -7924,7 +8102,7 @@
 				 GIF
  ***********************************************************************/
 
-#if defined (HAVE_GIF) || defined (MAC_OS)
+#if defined (HAVE_GIF) || defined (MAC_OS) || defined (HAVE_NS)
 
 static int gif_image_p P_ ((Lisp_Object object));
 static int gif_load P_ ((struct frame *f, struct image *img));
@@ -8553,6 +8731,16 @@
 }
 #endif /* MAC_OS */
 
+#ifdef HAVE_NS
+static int
+gif_load (struct frame *f, struct image *img)
+{
+  return ns_load_image(f, img,
+                       image_spec_value (img->spec, QCfile, NULL),
+                       image_spec_value (img->spec, QCdata, NULL));
+}
+#endif /* HAVE_NS */
+
 #endif /* HAVE_GIF */
 
 
@@ -9335,27 +9523,27 @@
   if (CONSP (tested))
     return XCDR (tested);
 
-#if defined (HAVE_XPM) || defined (MAC_OS)
+#if defined (HAVE_XPM) || defined (MAC_OS) || defined (HAVE_NS)
   if (EQ (type, Qxpm))
     return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries);
 #endif
 
-#if defined (HAVE_JPEG) || defined (MAC_OS)
+#if defined (HAVE_JPEG) || defined (MAC_OS) || defined (HAVE_NS)
   if (EQ (type, Qjpeg))
     return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries);
 #endif
 
-#if defined (HAVE_TIFF) || defined (MAC_OS)
+#if defined (HAVE_TIFF) || defined (MAC_OS) || defined (HAVE_NS)
   if (EQ (type, Qtiff))
     return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries);
 #endif
 
-#if defined (HAVE_GIF) || defined (MAC_OS)
+#if defined (HAVE_GIF) || defined (MAC_OS) || defined (HAVE_NS)
   if (EQ (type, Qgif))
     return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries);
 #endif
 
-#if defined (HAVE_PNG) || defined (MAC_OS)
+#if defined (HAVE_PNG) || defined (MAC_OS) || defined (HAVE_NS)
   if (EQ (type, Qpng))
     return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries);
 #endif
@@ -9480,31 +9668,31 @@
   staticpro (&QCpt_height);
 #endif /* HAVE_GHOSTSCRIPT */
 
-#if defined (HAVE_XPM) || defined (MAC_OS)
+#if defined (HAVE_XPM) || defined (MAC_OS) || defined (HAVE_NS)
   Qxpm = intern ("xpm");
   staticpro (&Qxpm);
   ADD_IMAGE_TYPE (Qxpm);
 #endif
 
-#if defined (HAVE_JPEG) || defined (MAC_OS)
+#if defined (HAVE_JPEG) || defined (MAC_OS) || defined (HAVE_NS)
   Qjpeg = intern ("jpeg");
   staticpro (&Qjpeg);
   ADD_IMAGE_TYPE (Qjpeg);
 #endif
 
-#if defined (HAVE_TIFF) || defined (MAC_OS)
+#if defined (HAVE_TIFF) || defined (MAC_OS) || defined (HAVE_NS)
   Qtiff = intern ("tiff");
   staticpro (&Qtiff);
   ADD_IMAGE_TYPE (Qtiff);
 #endif
 
-#if defined (HAVE_GIF) || defined (MAC_OS)
+#if defined (HAVE_GIF) || defined (MAC_OS) || defined (HAVE_NS)
   Qgif = intern ("gif");
   staticpro (&Qgif);
   ADD_IMAGE_TYPE (Qgif);
 #endif
 
-#if defined (HAVE_PNG) || defined (MAC_OS)
+#if defined (HAVE_PNG) || defined (MAC_OS) || defined (HAVE_NS)
   Qpng = intern ("png");
   staticpro (&Qpng);
   ADD_IMAGE_TYPE (Qpng);
--- a/src/keyboard.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/keyboard.c	Tue Jul 15 18:15:18 2008 +0000
@@ -80,6 +80,11 @@
 #include "macterm.h"
 #endif
 
+#ifdef HAVE_NS
+#include "nsterm.h"
+extern Lisp_Object Qsuper;
+#endif
+
 #ifndef USE_CRT_DLL
 extern int errno;
 #endif
@@ -4147,7 +4152,8 @@
 #endif
 	}
 
-#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS)
+#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+    || defined (HAVE_NS)
       else if (event->kind == DELETE_WINDOW_EVENT)
 	{
 	  /* Make an event (delete-frame (FRAME)).  */
@@ -4156,7 +4162,8 @@
 	  kbd_fetch_ptr = event + 1;
 	}
 #endif
-#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS)
+#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS) \
+    || defined (HAVE_NS)
       else if (event->kind == ICONIFY_EVENT)
 	{
 	  /* Make an event (iconify-frame (FRAME)).  */
@@ -4179,7 +4186,7 @@
 	  kbd_fetch_ptr = event + 1;
 	}
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+    || defined(HAVE_NS) || defined (USE_GTK)
       else if (event->kind == MENU_BAR_ACTIVATE_EVENT)
 	{
 	  kbd_fetch_ptr = event + 1;
@@ -4289,7 +4296,7 @@
 	      obj = make_lispy_event (event);
 
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined(MAC_OS) \
-    || defined (USE_GTK)
+    || defined(HAVE_NS) || defined (USE_GTK)
 	      /* If this was a menu selection, then set the flag to inhibit
 		 writing to last_nonmenu_event.  Don't do this if the event
 		 we're returning is (menu-bar), though; that indicates the
@@ -5643,7 +5650,7 @@
 	if (event->kind == MOUSE_CLICK_EVENT)
 	  {
 	    struct frame *f = XFRAME (event->frame_or_window);
-#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) && ! defined (HAVE_NS)
 	    int row, column;
 #endif
 
@@ -5652,7 +5659,7 @@
 	    if (! FRAME_LIVE_P (f))
 	      return Qnil;
 
-#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) && ! defined (HAVE_NS)
 	    /* EVENT->x and EVENT->y are frame-relative pixel
 	       coordinates at this place.  Under old redisplay, COLUMN
 	       and ROW are set to frame relative glyph coordinates
@@ -5712,7 +5719,7 @@
 
 		return Fcons (item, Fcons (position, Qnil));
 	      }
-#endif /* not USE_X_TOOLKIT && not USE_GTK */
+#endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */
 
 	    position = make_lispy_position (f, &event->x, &event->y,
 					    event->timestamp);
@@ -6092,7 +6099,7 @@
 #endif /* HAVE_MOUSE */
 
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+    || defined(HAVE_NS) || defined (USE_GTK)
     case MENU_BAR_EVENT:
       if (EQ (event->arg, event->frame_or_window))
 	/* This is the prefix key.  We translate this to
@@ -7305,6 +7312,10 @@
 void
 handle_async_input ()
 {
+#ifdef BSD4_1
+  extern int select_alarmed;
+#endif
+
   interrupt_input_pending = 0;
 
   while (1)
@@ -7317,6 +7328,9 @@
       if (nread <= 0)
 	break;
 
+#ifdef BSD4_1
+      select_alarmed = 1;  /* Force the select emulator back to life */
+#endif
     }
 }
 
@@ -7335,6 +7349,10 @@
   signal (signo, input_available_signal);
 #endif /* USG */
 
+#ifdef BSD4_1
+  sigisheld (SIGIO);
+#endif
+
 #ifdef SYNC_INPUT
   interrupt_input_pending = 1;
 #else
@@ -7348,6 +7366,9 @@
   handle_async_input ();
 #endif
 
+#ifdef BSD4_1
+  sigfree ();
+#endif
   errno = old_errno;
 }
 #endif /* SIGIO */
@@ -7975,10 +7996,15 @@
       /* With the introduction of where_is_cache, the computation
          of equivalent key bindings is sufficiently fast that we
          do not need to cache it here any more. */
-      /* CHECK_IMPURE (start);
-         XSETCDR (start, Fcons (Fcons (Qnil, Qnil), XCDR (start)));
-	 cachelist = XCAR (XCDR (start));  */
+/*PENDING: under NS this effect does not hold, perhaps due to the
+           modifier-preference changes to where-is-internal.. */
+#ifdef HAVE_NS
+       CHECK_IMPURE (start);
+       XSETCDR (start, Fcons (Fcons (Qnil, Qnil), XCDR (start)));
+       cachelist = XCAR (XCDR (start));
+#else
       cachelist = Fcons (Qnil, Qnil);
+#endif
       newcache = 1;
       tem = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
       if (!NILP (keyhint))
@@ -8044,7 +8070,12 @@
 	      && SYMBOLP (XSYMBOL (def)->function)
 	      && ! NILP (Fget (def, Qmenu_alias)))
 	    def = XSYMBOL (def)->function;
+#ifdef HAVE_NS
+          /* prefer 'super' bindings */
+	  tem = Fwhere_is_internal (def, Qnil, Qsuper, Qt, Qt);
+#else
 	  tem = Fwhere_is_internal (def, Qnil, Qt, Qnil, Qt);
+#endif
 	  XSETCAR (cachelist, tem);
 	  if (NILP (tem))
 	    {
@@ -8077,7 +8108,7 @@
   if (newcache && !NILP (tem))
     {
       tem = concat2 (build_string ("  "), tem);
-      // tem = concat3 (build_string ("  ("), tem, build_string (")"));
+      /* tem = concat3 (build_string ("  ("), tem, build_string (")")); */
       XSETCDR (cachelist, tem);
     }
 
--- a/src/keyboard.h	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/keyboard.h	Tue Jul 15 18:15:18 2008 +0000
@@ -314,8 +314,7 @@
    confined to an extended version of this with sections of code below
    using it unconditionally.  */
 #ifndef HAVE_NTGUI
-#ifdef USE_GTK
-/* gtk just uses utf-8.  */
+#if defined (USE_GTK) || defined (HAVE_NS)
 # define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str)
 #elif defined HAVE_X_I18N
 #define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str)
@@ -325,6 +324,56 @@
 #else /* HAVE_NTGUI */
 #define ENCODE_MENU_STRING(str) (str)
 #endif
+
+#if defined (HAVE_NS) || defined (HAVE_NTGUI)
+
+typedef void * XtPointer;
+typedef unsigned char Boolean;
+
+/* Definitions copied from lwlib.h */
+
+enum button_type
+{
+  BUTTON_TYPE_NONE,
+  BUTTON_TYPE_TOGGLE,
+  BUTTON_TYPE_RADIO
+};
+
+/* This structure is based on the one in ../lwlib/lwlib.h, with unused portions
+   removed.  No term uses these. */
+typedef struct _widget_value
+{
+  /* name of widget */
+  Lisp_Object   lname;
+  char*		name;
+  /* value (meaning depend on widget type) */
+  char*		value;
+  /* keyboard equivalent. no implications for XtTranslations */
+  Lisp_Object   lkey;
+  char*		key;
+  /* Help string or nil if none.
+     GC finds this string through the frame's menu_bar_vector
+     or through menu_items.  */
+  Lisp_Object	help;
+  /* true if enabled */
+  Boolean	enabled;
+  /* true if selected */
+  Boolean	selected;
+  /* The type of a button.  */
+  enum button_type button_type;
+#if defined (HAVE_NTGUI)
+  /* true if menu title */
+  Boolean       title;
+#endif
+  /* Contents of the sub-widgets, also selected slot for checkbox */
+  struct _widget_value*	contents;
+  /* data passed to callback */
+  XtPointer	call_data;
+  /* next one in the list */
+  struct _widget_value*	next;
+} widget_value;
+#endif
+
 
 /* Macros for dealing with lispy events.  */
 
--- a/src/keymap.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/keymap.c	Tue Jul 15 18:15:18 2008 +0000
@@ -111,6 +111,10 @@
 
 extern Lisp_Object Voverriding_local_map;
 
+#ifdef HAVE_NS
+extern Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper;
+#endif
+
 /* Hash table used to cache a reverse-map to speed up calls to where-is.  */
 static Lisp_Object where_is_cache;
 /* Which keymaps are reverse-stored in the cache.  */
@@ -2621,6 +2625,41 @@
   return 1;
 }
 
+#ifdef HAVE_NS
+int lisp_to_mod(Lisp_Object lmod)
+/* -------------------------------------------------------------------------
+     Convert lisp symbol to emacs modifier code.
+   ------------------------------------------------------------------------- */
+{
+  if (EQ(lmod, Qmeta))
+    return meta_modifier;
+  else if (EQ(lmod, Qsuper))
+    return super_modifier;
+  else if (EQ(lmod, Qcontrol))
+    return ctrl_modifier;
+  else if (EQ(lmod, Qalt))
+    return alt_modifier;
+  else if (EQ(lmod, Qhyper))
+    return hyper_modifier;
+  return 0;
+}
+
+/* Return non-zero if SEQ starts w/a char modified by given modifier only. */
+static int
+modifier_sequence_p (Lisp_Object seq, Lisp_Object modifier)
+{
+  Lisp_Object idx, elt;
+
+  if (XINT (Flength (seq)) == 0)
+    return 0;
+  XSETFASTINT(idx, 0);
+  elt = Faref(seq, idx);
+
+  return  (XUINT(elt) & (CHAR_MODIFIER_MASK ^ shift_modifier))
+    == lisp_to_mod(modifier);
+}
+#endif
+
 
 /* where-is - finding a command in a set of keymaps.			*/
 
@@ -2803,6 +2842,14 @@
 	     we find.  */
 	  if (EQ (firstonly, Qnon_ascii))
 	    RETURN_UNGCPRO (sequence);
+#ifdef HAVE_NS
+          /* respond to modifier preference */
+          else if ((EQ (firstonly, Qalt) || EQ (firstonly, Qcontrol)
+                    || EQ (firstonly, Qhyper) || EQ (firstonly, Qmeta)
+                    || EQ (firstonly, Qsuper)))
+            if (modifier_sequence_p(sequence, firstonly))
+              RETURN_UNGCPRO (sequence);
+#endif
 	  else if (!NILP (firstonly) && ascii_sequence_p (sequence))
 	    RETURN_UNGCPRO (sequence);
 
@@ -2836,6 +2883,10 @@
 
 If optional 3rd arg FIRSTONLY is non-nil, return the first key sequence found,
 rather than a list of all possible key sequences.
+#ifdef HAVE_NS
+If FIRSTONLY is the symbol for a modifier key, return the first binding found,
+that is modified by that modifier only.
+#endif
 If FIRSTONLY is the symbol `non-ascii', return the first binding found,
 no matter what it is.
 If FIRSTONLY has another non-nil value, prefer sequences of ASCII characters
@@ -2909,10 +2960,19 @@
       for (i = n - 1; i >= 0; --i)
 	if (EQ (shadow_lookup (keymaps, defns[i], Qnil), definition))
 	  {
-	    if (ascii_sequence_p (defns[i]))
-	      break;
-	    else if (j < 0)
-	      j = i;
+#ifdef HAVE_NS
+            if ((EQ (firstonly, Qalt) || EQ (firstonly, Qcontrol)
+                 || EQ (firstonly, Qhyper) || EQ (firstonly, Qmeta)
+                 || EQ (firstonly, Qsuper))
+                && modifier_sequence_p(defns[i], firstonly))
+              break;
+            else if (EQ (firstonly, Qt) && ascii_sequence_p (defns[i]))
+#else
+              if (ascii_sequence_p (defns[i]))
+#endif
+                break;
+              else if (j < 0)
+                j = i;
 	  }
 
       result = i >= 0 ? defns[i] : (j >= 0 ? defns[j] : Qnil);
--- a/src/lisp.h	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/lisp.h	Tue Jul 15 18:15:18 2008 +0000
@@ -28,6 +28,11 @@
 #define P_(proto) ()
 #endif
 
+#ifdef NS_IMPL_GNUSTEP
+/* This conflicts with functions in the GNUstep libraries. */
+#define hash_remove emacs_hash_remove
+#endif  /* NS_IMPL_GNUSTEP */
+
 #if 0
 /* Define this temporarily to hunt a bug.  If defined, the size of
    strings is redundantly recorded in sdata structures so that it can
@@ -157,7 +162,7 @@
 #endif
 
 /* Let's USE_LSB_TAG on systems where we know malloc returns mult-of-8.  */
-#if defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ || defined MAC_OSX
+#if defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ || defined MAC_OSX || defined(NS_IMPL_COCOA)
 /* We also need to be able to specify mult-of-8 alignment on static vars.  */
 # if defined DECL_ALIGN
 /* We currently do not support USE_LSB_TAG with a union Lisp_Object.  */
--- a/src/lread.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/lread.c	Tue Jul 15 18:15:18 2008 +0000
@@ -4095,7 +4095,7 @@
     }
 #endif
 
-#if (!(defined(WINDOWSNT) || (defined(HAVE_CARBON))))
+#if (!(defined(WINDOWSNT) || (defined(HAVE_CARBON)) || (defined(HAVE_NS))))
   /* When Emacs is invoked over network shares on NT, PATH_LOADSEARCH is
      almost never correct, thereby causing a warning to be printed out that
      confuses users.  Since PATH_LOADSEARCH is always overridden by the
@@ -4125,7 +4125,7 @@
 	    }
 	}
     }
-#endif /* !(WINDOWSNT || HAVE_CARBON) */
+#endif /* !(WINDOWSNT || HAVE_CARBON || HAVE_NS) */
 
   /* If the EMACSLOADPATH environment variable is set, use its value.
      This doesn't apply if we're dumping.  */
--- a/src/menu.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/menu.c	Tue Jul 15 18:15:18 2008 +0000
@@ -36,6 +36,10 @@
 #include "xterm.h"
 #endif
 
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
+
 #ifdef USE_GTK
 #include "gtkutil.h"
 #endif
@@ -440,7 +444,7 @@
 		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
 		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
 
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI)
   /* Display a submenu using the toolkit.  */
   if (! (NILP (map) || NILP (enabled)))
     {
@@ -580,7 +584,7 @@
 }
 
 
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI)
 
 /* Allocate a widget_value, blocking input.  */
 
@@ -956,7 +960,71 @@
     }
 }
 
-#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NTGUI */
+#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI */
+
+#ifdef HAVE_NS
+/* As above, but return the menu selection instead of storing in kb buffer.
+   If keymaps==1, return full prefixes to selection. */
+Lisp_Object
+find_and_return_menu_selection (FRAME_PTR f, int keymaps, void *client_data)
+{
+  Lisp_Object prefix, entry;
+  int i;
+  Lisp_Object *subprefix_stack;
+  int submenu_depth = 0;
+
+  prefix = entry = Qnil;
+  i = 0;
+  subprefix_stack =
+    (Lisp_Object *)alloca(menu_items_used * sizeof (Lisp_Object));
+
+  while (i < menu_items_used)
+    {
+      if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
+        {
+          subprefix_stack[submenu_depth++] = prefix;
+          prefix = entry;
+          i++;
+        }
+      else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
+        {
+          prefix = subprefix_stack[--submenu_depth];
+          i++;
+        }
+      else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+        {
+          prefix
+            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
+          i += MENU_ITEMS_PANE_LENGTH;
+        }
+      /* Ignore a nil in the item list.
+         It's meaningful only for dialog boxes.  */
+      else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+        i += 1;
+      else
+        {
+          entry
+            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
+          if ((int) (EMACS_INT)client_data == i)
+            {
+              if (keymaps != 0)
+                {
+                  int j;
+
+                  entry = Fcons (entry, Qnil);
+                  if (!NILP (prefix))
+                    entry = Fcons (prefix, entry);
+                  for (j = submenu_depth - 1; j >= 0; j--)
+                    if (!NILP (subprefix_stack[j]))
+                      entry = Fcons (subprefix_stack[j], entry);
+                }
+              return entry;
+            }
+          i += MENU_ITEMS_ITEM_LENGTH;
+        }
+    }
+}
+#endif
 
 void
 syms_of_menu ()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nsfns.m	Tue Jul 15 18:15:18 2008 +0000
@@ -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 (chris@nice.ch)
+OpenStep/Rhapsody port by Scott Bender (sbender@harmony-ds.com)
+MacOSX/Aqua port by Christophe de Dinechin (descubes@earthlink.net)
+GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
+
+*/
+
+#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
+
+   ========================================================================== */
+
+
+@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
+@end
+
+
+@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];
+  panelOK = 1;
+  [NSApp stop: self];
+}
+- (void) cancel: (id)sender
+{
+  [super cancel: sender];
+  [NSApp stop: self];
+}
+#endif
+@end
+
+
+@implementation 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;
+}
+@end
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nsgui.h	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,208 @@
+/* Definitions and headers for communication on the NeXT/Open/GNUstep API.
+   Copyright (C) 1995, 2005, 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.  */
+
+#ifndef __NSGUI_H__
+#define __NSGUI_H__
+
+/* this gets included from a couple of the plain (non-NS) .c files */
+#ifdef __OBJC__
+
+#ifdef NS_IMPL_COCOA
+#ifdef Z
+#warning "Z is defined.  If you get a later parse error in a header, check that buffer.h or other files #define-ing Z are not included."
+#endif  /* Z */
+#define Cursor FooFoo
+#undef init_process
+#endif  /* NS_IMPL_COCOA */
+
+#ifdef NS_IMPL_GNUSTEP
+#undef hash_remove
+#endif
+
+#import <AppKit/AppKit.h>
+
+#ifdef NS_IMPL_GNUSTEP
+#define hash_remove emacs_hash_remove
+#endif
+
+#ifdef NS_IMPL_COCOA
+#undef Cursor
+#define init_process emacs_init_process
+#endif /* NS_IMPL_COCOA */
+#import <Foundation/NSDistantObject.h>
+
+#ifdef NS_IMPL_COCOA
+#include <AvailabilityMacros.h>
+#endif /* NS_IMPL_COCOA */
+
+#endif /* __OBJC__ */
+
+
+/* menu-related */
+#define free_widget_value(wv) xfree (wv)
+#define malloc_widget_value() ((widget_value *) memset (xmalloc \
+    (sizeof (widget_value)), 0, sizeof (widget_value)))
+
+/* Emulate XCharStruct.  */
+typedef struct _XCharStruct
+{
+  int rbearing;
+  int lbearing;
+  int width;
+  int ascent;
+  int descent;
+} XCharStruct;
+
+/* 23: Fake tructure from Xlib.h to represent two-byte characters.  */
+#ifndef __OBJC__
+typedef unsigned short unichar;
+#endif
+typedef unichar XChar2b;
+
+#define STORE_XCHAR2B(chp, b1, b2) \
+  (*(chp) = ((XChar2b)((((b1) & 0x00ff) << 8) | ((b2) & 0x00ff))))
+
+#define XCHAR2B_BYTE1(chp) \
+ (((*chp) & 0xff00) >> 8)
+
+#define XCHAR2B_BYTE2(chp) \
+ ((*chp) & 0x00ff)
+
+#define FACE_DEFAULT (~0)
+
+
+/* PENDING: xfaces requires these structures, but the question is are we
+            forced to use them? */
+typedef struct _XGCValues
+{
+#ifdef __OBJC__
+  NSColor *foreground;
+  NSColor *background;
+  struct ns_font *font;
+#else
+  void *foreground;
+  void *background;
+  void *font;
+#endif
+} XGCValues;
+
+typedef XGCValues * GC;
+
+#define GCForeground 0x01
+#define GCBackground 0x02
+#define GCFont 0x03
+
+#ifdef __OBJC__
+typedef id Pixmap;
+#else
+typedef void *Pixmap;
+#endif
+
+#ifdef __OBJC__
+typedef NSCursor * Cursor;
+#else
+typedef void *Cursor;
+#endif
+
+#define No_Cursor (0)
+
+#ifdef __OBJC__
+typedef NSColor * Color;
+#else
+typedef void * Color;
+#endif
+typedef int Window;
+typedef int Display;
+
+/* Xism */
+typedef Lisp_Object XrmDatabase;
+
+
+/* 23: some sort of attempt to normalize rectangle handling.. seems a bit much
+       for what is accomplished */
+typedef struct {
+      int x, y;
+      unsigned width, height;
+} XRectangle;
+
+#ifndef __OBJC__
+typedef struct _NSPoint { float x, y; } NSPoint;
+typedef struct _NSSize  { float width, height; } NSSize;
+typedef struct _NSRect  { NSPoint origin; NSSize size; } NSRect;
+#endif
+
+#define NativeRectangle struct _NSRect
+
+#define CONVERT_TO_XRECT(xr, nr)		\
+  ((xr).x     = (nr).origin.x,			\
+   (xr).y     = (nr).origin.y,			\
+   (xr).width = (nr).size.width,		\
+   (xr).height = (nr).size.height)
+
+#define CONVERT_FROM_XRECT(xr, nr)		\
+  ((nr).origin.x    = (xr).x,			\
+   (nr).origin.y    = (xr).y,			\
+   (nr).size.width  = (xr).width,		\
+   (nr).size.height = (xr).height)
+
+#define STORE_NATIVE_RECT(nr, px, py, pwidth, pheight)	\
+  ((nr).origin.x    = (px),			\
+   (nr).origin.y    = (py),			\
+   (nr).size.width  = (pwidth),			\
+   (nr).size.height = (pheight))
+
+
+
+
+/* This stuff needed by frame.c. */
+#define ForgetGravity		0
+#define NorthWestGravity	1
+#define NorthGravity		2
+#define NorthEastGravity	3
+#define WestGravity		4
+#define CenterGravity		5
+#define EastGravity		6
+#define SouthWestGravity	7
+#define SouthGravity		8
+#define SouthEastGravity	9
+#define StaticGravity		10
+
+#define NoValue		0x0000
+#define XValue  	0x0001
+#define YValue		0x0002
+#define WidthValue  	0x0004
+#define HeightValue  	0x0008
+#define AllValues 	0x000F
+#define XNegative 	0x0010
+#define YNegative 	0x0020
+
+#define USPosition	(1L << 0) /* user specified x, y */
+#define USSize		(1L << 1) /* user specified width, height */
+
+#define PPosition	(1L << 2) /* program specified position */
+#define PSize		(1L << 3) /* program specified size */
+#define PMinSize	(1L << 4) /* program specified minimum size */
+#define PMaxSize	(1L << 5) /* program specified maximum size */
+#define PResizeInc	(1L << 6) /* program specified resize increments */
+#define PAspect		(1L << 7) /* program specified min, max aspect ratios */
+#define PBaseSize	(1L << 8) /* program specified base for incrementing */
+#define PWinGravity	(1L << 9) /* program specified window gravity */
+
+#endif  /* __NSGUI_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nsimage.m	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,480 @@
+/* Image support 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 (chris@nice.ch)
+OpenStep/Rhapsody port by Scott Bender (sbender@harmony-ds.com)
+MacOSX/Aqua port by Christophe de Dinechin (descubes@earthlink.net)
+GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
+
+*/
+
+#include "config.h"
+#include "lisp.h"
+#include "dispextern.h"
+#include "nsterm.h"
+#include "frame.h"
+
+extern Lisp_Object QCfile, QCdata;
+
+/* call tracing */
+#if 0
+int image_trace_num = 0;
+#define NSTRACE(x)        fprintf (stderr, "%s:%d: [%d] " #x "\n",         \
+                                __FILE__, __LINE__, ++image_trace_num)
+#else
+#define NSTRACE(x)
+#endif
+
+
+/* ==========================================================================
+
+   C interface.  This allows easy calling from C files.  We could just
+   compile everything as Objective-C, but that might mean slower
+   compilation and possible difficulties on some platforms..
+
+   ========================================================================== */
+
+void *
+ns_image_from_XBM (unsigned char *bits, int width, int height)
+{
+  NSTRACE (ns_image_from_XBM);
+  return [[EmacsImage alloc] initFromXBM: bits
+                                   width: width height: height
+                                    flip: YES];
+}
+
+void *
+ns_image_for_XPM (int width, int height, int depth)
+{
+  NSTRACE (ns_image_for_XPM);
+  return [[EmacsImage alloc] initForXPMWithDepth: depth
+                                           width: width height: height];
+}
+
+void *
+ns_image_from_file (Lisp_Object file)
+{
+  NSTRACE (ns_image_from_bitmap_file);
+  return [EmacsImage allocInitFromFile: file];
+}
+
+int
+ns_load_image (struct frame *f, struct image *img,
+               Lisp_Object spec_file, Lisp_Object spec_data)
+{
+  NSTRACE (ns_load_image);
+
+  EmacsImage *eImg;
+  NSSize size;
+
+  if (NILP (spec_data))
+    {
+      eImg = [EmacsImage allocInitFromFile: spec_file];
+    }
+  else
+    {
+      NSData *data = [NSData dataWithBytes: XSTRING (spec_data)->data
+                                    length: SBYTES (spec_data)];
+      eImg = [[EmacsImage alloc] initWithData: data];
+      [eImg setPixmapData];
+    }
+
+  if (eImg == nil)
+    {
+      add_to_log ("Unable to load image %s", img->spec, Qnil);
+      return 0;
+    }
+
+  size = [eImg size];
+  img->width = size.width;
+  img->height = size.height;
+
+  /* 4) set img->pixmap = emacsimage */
+  img->pixmap = eImg;
+  return 1;
+}
+
+
+int
+ns_image_width (void *img)
+{
+  return [(id)img size].width;
+}
+
+int
+ns_image_height (void *img)
+{
+  return [(id)img size].height;
+}
+
+unsigned long
+ns_get_pixel (void *img, int x, int y)
+{
+  return [(EmacsImage *)img getPixelAtX: x Y: y];
+}
+
+void
+ns_put_pixel (void *img, int x, int y, unsigned long argb)
+{
+  unsigned char alpha = (argb >> 24) & 0xFF;
+  if (alpha == 0)
+    alpha = 0xFF;
+  [(EmacsImage *)img setPixelAtX: x Y: y toRed: (argb >> 16) & 0xFF
+   green: (argb >> 8) & 0xFF blue: (argb & 0xFF) alpha: alpha];
+}
+
+void
+ns_set_alpha (void *img, int x, int y, unsigned char a)
+{
+  [(EmacsImage *)img setAlphaAtX: x Y: y to: a];
+}
+
+
+/* ==========================================================================
+
+   Class supporting bitmaps and images of various sorts.
+
+   ========================================================================== */
+
+@implementation EmacsImage
+
+static EmacsImage *ImageList = nil;
+
++ allocInitFromFile: (Lisp_Object)file
+{
+  EmacsImage *image = ImageList;
+  Lisp_Object found;
+
+  /* look for an existing image of the same name */
+  while (image != nil &&
+         [[image name] compare: [NSString stringWithUTF8String: SDATA (file)]]
+             != NSOrderedSame)
+    image = [image imageListNext];
+
+  if (image != nil)
+    {
+      [image reference];
+      return image;
+    }
+
+  /* Search bitmap-file-path for the file, if appropriate.  */
+  found = x_find_image_file (file);
+  if (!STRINGP (found))
+    return nil;
+
+  image = [[EmacsImage alloc] initByReferencingFile:
+                     [NSString stringWithUTF8String: SDATA (found)]];
+
+  if ([image bestRepresentationForDevice: nil] == nil)
+    {
+      [image release];
+      return nil;
+    }
+
+  [image setName: [NSString stringWithUTF8String: SDATA (file)]];
+  [image reference];
+  ImageList = [image imageListSetNext: ImageList];
+
+  return image;
+}
+
+
+- reference
+{
+  refCount++;
+  return self;
+}
+
+
+- imageListSetNext: (id)arg
+{
+  imageListNext = arg;
+  return self;
+}
+
+
+- imageListNext
+{
+  return imageListNext;
+}
+
+
+- (void)dealloc
+{
+  id list = ImageList;
+
+  if (refCount > 1)
+    {
+      refCount--;
+      return;
+    }
+
+  [stippleMask release];
+
+  if (list == self)
+    ImageList = imageListNext;
+  else
+    {
+      while (list != nil && [list imageListNext] != self)
+        list = [list imageListNext];
+      [list imageListSetNext: imageListNext];
+    }
+
+  [super dealloc];
+}
+
+
+- initFromXBM: (unsigned char *)bits width: (int)w height: (int)h
+         flip: (BOOL)flip
+{
+  return [self initFromSkipXBM: bits width: w height: h flip: flip length: 0];
+}
+
+
+- initFromSkipXBM: (unsigned char *)bits width: (int)w height: (int)h
+             flip: (BOOL)flip length: (int)length;
+{
+  int bpr = (w + 7) / 8;
+  unsigned char *planes[5];
+
+  [self initWithSize: NSMakeSize (w, h)];
+
+  bmRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
+                                    pixelsWide: w pixelsHigh: h
+                                    bitsPerSample: 8 samplesPerPixel: 4
+                                    hasAlpha: YES isPlanar: YES
+                                    colorSpaceName: NSCalibratedRGBColorSpace
+                                    bytesPerRow: w bitsPerPixel: 0];
+
+  [bmRep getBitmapDataPlanes: planes];
+  {
+    /* pull bits out to set the (bytewise) alpha mask */
+    int i, j, k;
+    unsigned char *s = bits;
+    unsigned char *alpha = planes[3];
+    unsigned char swt[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13,
+                             3, 11, 7, 15};
+    unsigned char c, bitPat;
+
+    for (j = 0; j < h; j++)
+      for (i = 0; i < bpr; i++)
+        {
+          if (length)
+            {
+              unsigned char s1, s2;
+              while (*s++ != 'x' && s < bits + length);
+              if (s >= bits + length)
+                {
+                  [bmRep release];
+                  return nil;
+                }
+#define hexchar(x) (isdigit (x) ? x - '0' : x - 'a' + 10)
+              s1 = *s++;
+              s2 = *s++;
+              c = hexchar (s1) * 0x10 + hexchar (s2);
+            }
+          else
+            c = *s++;
+
+          bitPat = flip ? swt[c >> 4] | (swt[c & 0xf] << 4) : c ^ 255;
+          for (k =0; k<8; k++)
+            {
+              *alpha++ = (bitPat & 0x80) ? 0xff : 0;
+              bitPat <<= 1;
+            }
+        }
+  }
+
+  [self addRepresentation: bmRep];
+
+  bzero (planes[0], w*h);
+  bzero (planes[1], w*h);
+  bzero (planes[2], w*h);
+  [self setXBMColor: [NSColor blackColor]];
+  return self;
+}
+
+
+/* Set color for a bitmap image (see initFromSkipXBM).  Note that the alpha
+   is used as a mask, so we just memset the entire array. */
+- setXBMColor: (NSColor *)color
+{
+  NSSize s = [self size];
+  int len = (int) s.width * s.height;
+  unsigned char *planes[5];
+  float r, g, b, a;
+  NSColor *rgbColor;
+
+  if (bmRep == nil || color == nil)
+    return;
+
+  if ([color colorSpaceName] != NSCalibratedRGBColorSpace)
+    rgbColor = [color colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
+  else
+    rgbColor = color;
+
+  [rgbColor getRed: &r green: &g blue: &b alpha: &a];
+
+  [bmRep getBitmapDataPlanes: planes];
+
+  /* we used to just do this, but Cocoa seems to have a bug when rendering
+     an alpha-masked image onto a dark background where it bloats the mask */
+   /* memset (planes[0..2], r, g, b*0xff, len); */
+  {
+    int i, len = s.width*s.height;
+    int rr = r * 0xff, gg = g * 0xff, bb = b * 0xff;
+    for (i =0; i<len; i++)
+      if (planes[3][i] != 0)
+        {
+          planes[0][i] = rr;
+          planes[1][i] = gg;
+          planes[2][i] = bb;
+        }
+  }
+}
+
+
+- initForXPMWithDepth: (int)depth width: (int)width height: (int)height
+{
+  NSSize s = {width, height};
+  int i;
+
+  [self initWithSize: s];
+
+  bmRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
+                                  pixelsWide: width pixelsHigh: height
+                                  /* keep things simple for now */
+                                  bitsPerSample: 8 samplesPerPixel: 4 /*RGB+A*/
+                                  hasAlpha: YES isPlanar: YES
+                                  colorSpaceName: NSCalibratedRGBColorSpace
+                                  bytesPerRow: width bitsPerPixel: 0];
+
+  [bmRep getBitmapDataPlanes: pixmapData];
+  for (i =0; i<4; i++)
+    bzero (pixmapData[i], width*height);
+  [self addRepresentation: bmRep];
+  return self;
+}
+
+
+/* attempt to pull out pixmap data from a BitmapImageRep; returns NO if fails */
+- (void) setPixmapData
+{
+  NSEnumerator *reps;
+  NSImageRep *rep;
+
+  reps = [[self representations] objectEnumerator];
+  while (rep = (NSImageRep *) [reps nextObject])
+    {
+      if ([rep respondsToSelector: @selector (getBitmapDataPlanes:)])
+        {
+          bmRep = (NSBitmapImageRep *) rep;
+          onTiger = [bmRep respondsToSelector: @selector (colorAtX:y:)];
+
+          if ([bmRep numberOfPlanes] >= 3)
+              [bmRep getBitmapDataPlanes: pixmapData];
+          break;
+        }
+    }
+}
+
+
+/* note; this and next work only for image created with initForXPMWithDepth,
+         initFromSkipXBM, or where setPixmapData was called successfully */
+/* return ARGB */
+- (unsigned long) getPixelAtX: (int)x Y: (int)y
+{
+  if (bmRep == nil)
+    return 0;
+
+  /* this method is faster but won't work for bitmaps */
+  if (pixmapData[0] != NULL)
+    {
+      int loc = x + y * [self size].width;
+      return (pixmapData[3][loc] << 24) /* alpha */
+       | (pixmapData[0][loc] << 16) | (pixmapData[1][loc] << 8)
+       | (pixmapData[2][loc]);
+    }
+  else if (onTiger)
+    {
+      NSColor *color = [bmRep colorAtX: x y: y];
+      float r, g, b, a;
+      [color getRed: &r green: &g blue: &b alpha: &a];
+      return ((int)(a * 255.0) << 24)
+        | ((int)(r * 255.0) << 16) | ((int)(g * 255.0) << 8)
+        | ((int)(b * 255.0));
+
+    }
+  return 0;
+}
+
+- (void) setPixelAtX: (int)x Y: (int)y toRed: (unsigned char)r
+               green: (unsigned char)g blue: (unsigned char)b
+               alpha:(unsigned char)a;
+{
+  if (bmRep == nil)
+    return;
+
+  if (pixmapData[0] != NULL)
+    {
+      int loc = x + y * [self size].width;
+      pixmapData[0][loc] = r;
+      pixmapData[1][loc] = g;
+      pixmapData[2][loc] = b;
+      pixmapData[3][loc] = a;
+    }
+  else if (onTiger)
+    {
+      [bmRep setColor:
+               [NSColor colorWithCalibratedRed: r green: g blue: b alpha: a]
+                  atX: x y: y];
+    }
+}
+
+- (void) setAlphaAtX: (int) x Y: (int) y to: (unsigned char) a
+{
+  if (bmRep == nil)
+    return;
+
+  if (pixmapData[0] != NULL)
+    {
+      int loc = x + y * [self size].width;
+
+      pixmapData[3][loc] = a;
+    }
+  else if (onTiger)
+    {
+      NSColor *color = [bmRep colorAtX: x y: y];
+      color = [color colorWithAlphaComponent: (a / 255.0)];
+      [bmRep setColor: color atX: x y: y];
+    }
+}
+
+/* returns a pattern color, which is cached here */
+- (NSColor *)stippleMask
+{
+  if (stippleMask == nil)
+      stippleMask = [[NSColor colorWithPatternImage: self] retain];
+  return stippleMask;
+}
+
+@end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nsmenu.m	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,1948 @@
+/* NeXT/Open/GNUstep and MacOSX Cocoa menu and toolbar module.
+   Copyright (C) 2007, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  
+
+By Adrian Robert, based on code from original nsmenu.m (Carl Edman,
+Christian Limpach, Scott Bender, Christophe de Dinechin) and code in the
+Carbon version by Yamamoto Mitsuharu. */
+
+#include "config.h"
+#include "lisp.h"
+#include "window.h"
+#include "buffer.h"
+#include "keymap.h"
+#include "coding.h"
+#include "commands.h"
+#include "blockinput.h"
+#include "nsterm.h"
+#include "termhooks.h"
+#include "keyboard.h"
+
+/* for profiling */
+#include <sys/timeb.h>
+#include <sys/types.h>
+
+#define MenuStagger 10.0
+
+#if 0
+int menu_trace_num = 0;
+#define NSTRACE(x)        fprintf (stderr, "%s:%d: [%d] " #x "\n",        \
+                                __FILE__, __LINE__, ++menu_trace_num)
+#else
+#define NSTRACE(x)
+#endif
+
+#if 0
+/* Include lisp -> C common menu parsing code */
+#define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str)
+#include "nsmenu_common.c"
+#endif
+
+extern struct widget_value;
+
+extern Lisp_Object Qundefined, Qmenu_enable, Qmenu_bar_update_hook;
+extern Lisp_Object QCtoggle, QCradio;
+
+extern Lisp_Object Vmenu_updating_frame;
+
+Lisp_Object Qdebug_on_next_call;
+extern Lisp_Object Voverriding_local_map, Voverriding_local_map_menu_flag,
+		   Qoverriding_local_map, Qoverriding_terminal_local_map;
+
+extern long context_menu_value;
+EmacsMenu *mainMenu, *svcsMenu;
+
+/* NOTE: toolbar implementation is at end,
+  following complete menu implementation. */
+
+
+/* ==========================================================================
+
+    Menu: Externally-called functions
+
+   ========================================================================== */
+
+
+/*23: PENDING: not currently used, but should normalize with other terms. */
+void
+x_activate_menubar (struct frame *f)
+{
+    fprintf (stderr, "XXX: Received x_activate_menubar event.\n");
+}
+
+
+/* Supposed to discard menubar and free storage.  Since we share the
+   menubar among frames and update its context for the focused window,
+   there is nothing to do here. */
+void
+free_frame_menubar (struct frame *f)
+{
+  return;
+}
+
+
+/* --------------------------------------------------------------------------
+    Update menubar.  Three cases:
+    1) deep_p = 0, submenu = nil: Fresh switch onto a frame -- either set up
+       just top-level menu strings (OS X), or goto case (2) (GNUstep).
+    2) deep_p = 1, submenu = nil: Recompute all submenus.
+    3) deep_p = 1, submenu = non-nil: Update contents of a single submenu.
+   -------------------------------------------------------------------------- */
+/*#define NSMENUPROFILE 1 */
+void
+ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu)
+{
+  NSAutoreleasePool *pool;
+  id menu = [NSApp mainMenu];
+  static EmacsMenu *last_submenu = nil;
+  BOOL needsSet = NO;
+  const char *submenuTitle = [[submenu title] UTF8String];
+  extern int waiting_for_input;
+  int owfi;
+  Lisp_Object items;
+  widget_value *wv, *first_wv, *prev_wv = 0;
+  int i;
+
+#ifdef NSMENUPROFILE
+  struct timeb tb;
+  long t;
+#endif
+
+  NSTRACE (set_frame_menubar);
+
+  if (f != SELECTED_FRAME ())
+      return;
+  XSETFRAME (Vmenu_updating_frame, f);
+/*fprintf (stderr, "ns_update_menubar: frame: %p\tdeep: %d\tsub: %p\n", f, deep_p, submenu); */
+
+  BLOCK_INPUT;
+  pool = [[NSAutoreleasePool alloc] init];
+
+  /* Menu may have been created automatically; if so, discard it. */
+  if ([menu isKindOfClass: [EmacsMenu class]] == NO)
+    {
+      [menu release];
+      menu = nil;
+    }
+
+  if (menu == nil)
+    {
+      menu = [[EmacsMenu alloc] initWithTitle: @"Emacs"];
+      needsSet = YES;
+    }
+  else
+    {  /* close up anything on there */
+      id attMenu = [menu attachedMenu];
+      if (attMenu != nil)
+        [attMenu close];
+    }
+
+#ifdef NSMENUPROFILE
+  ftime (&tb);
+  t = -(1000*tb.time+tb.millitm);
+#endif
+
+  /* widget_value is a straightforward object translation of emacs's
+     Byzantine lisp menu structures */
+  wv = xmalloc_widget_value ();
+  wv->name = "Emacs";
+  wv->value = 0;
+  wv->enabled = 1;
+  wv->button_type = BUTTON_TYPE_NONE;
+  wv->help = Qnil;
+  first_wv = wv;
+
+#ifdef NS_IMPL_GNUSTEP
+  deep_p = 1; /* until GNUstep NSMenu implements the Panther delegation model */
+#endif
+
+  if (deep_p)
+    {
+      /* Fully parse one or more of the submenus. */
+      int n = 0;
+      int *submenu_start, *submenu_end;
+      int *submenu_top_level_items, *submenu_n_panes;
+      struct buffer *prev = current_buffer;
+      Lisp_Object buffer;
+      int specpdl_count = SPECPDL_INDEX ();
+      int previous_menu_items_used = f->menu_bar_items_used;
+      Lisp_Object *previous_items
+	= (Lisp_Object *) alloca (previous_menu_items_used
+				  * sizeof (Lisp_Object));
+
+      /* lisp preliminaries */
+      buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer;
+      specbind (Qinhibit_quit, Qt);
+      specbind (Qdebug_on_next_call, Qnil);
+      record_unwind_save_match_data ();
+      if (NILP (Voverriding_local_map_menu_flag))
+	{
+	  specbind (Qoverriding_terminal_local_map, Qnil);
+	  specbind (Qoverriding_local_map, Qnil);
+	}
+      set_buffer_internal_1 (XBUFFER (buffer));
+
+      /* PENDING: for some reason this is not needed in other terms,
+         but some menu updates call Info-extract-pointer which causes
+         abort-on-error if waiting-for-input.  Needs further investigation. */
+      owfi = waiting_for_input;
+      waiting_for_input = 0;
+
+      /* lucid hook and possible reset */
+      safe_run_hooks (Qactivate_menubar_hook);
+      if (! NILP (Vlucid_menu_bar_dirty_flag))
+	call0 (Qrecompute_lucid_menubar);
+      safe_run_hooks (Qmenu_bar_update_hook);
+      FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
+
+      /* Now ready to go */
+      items = FRAME_MENU_BAR_ITEMS (f);
+
+      /* Save the frame's previous menu bar contents data */
+      if (previous_menu_items_used)
+	bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
+	       previous_menu_items_used * sizeof (Lisp_Object));
+
+      /* parse stage 1: extract from lisp */
+      save_menu_items ();
+
+      menu_items = f->menu_bar_vector;
+      menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
+      submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
+      submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
+      submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int));
+      submenu_top_level_items
+	= (int *) alloca (XVECTOR (items)->size * sizeof (int *));
+      init_menu_items ();
+      for (i = 0; i < XVECTOR (items)->size; i += 4)
+	{
+	  Lisp_Object key, string, maps;
+
+	  key = XVECTOR (items)->contents[i];
+	  string = XVECTOR (items)->contents[i + 1];
+	  maps = XVECTOR (items)->contents[i + 2];
+	  if (NILP (string))
+	    break;
+
+          /* PENDING: we'd like to only parse the needed submenu, but this
+             was causing crashes in the _common parsing code.. need to make
+             sure proper initialization done.. */
+/*             if (submenu && strcmp (submenuTitle, SDATA (string)))
+             continue; */
+
+	  submenu_start[i] = menu_items_used;
+
+	  menu_items_n_panes = 0;
+	  submenu_top_level_items[i] = parse_single_submenu (key, string, maps);
+	  submenu_n_panes[i] = menu_items_n_panes;
+	  submenu_end[i] = menu_items_used;
+          n++;
+	}
+
+      finish_menu_items ();
+      waiting_for_input = owfi;
+
+
+      if (submenu && n == 0)
+        {
+          /* should have found a menu for this one but didn't */
+          fprintf (stderr, "ERROR: did not find lisp menu for submenu '%s'.\n",
+                  submenuTitle);
+	  discard_menu_items ();
+	  unbind_to (specpdl_count, Qnil);
+          [pool release];
+          UNBLOCK_INPUT;
+	  return;
+        }
+
+      /* parse stage 2: insert into lucid 'widget_value' structures
+         [comments in other terms say not to evaluate lisp code here] */
+      wv = xmalloc_widget_value ();
+      wv->name = "menubar";
+      wv->value = 0;
+      wv->enabled = 1;
+      wv->button_type = BUTTON_TYPE_NONE;
+      wv->help = Qnil;
+      first_wv = wv;
+
+      for (i = 0; i < 4*n; i += 4)
+	{
+	  menu_items_n_panes = submenu_n_panes[i];
+	  wv = digest_single_submenu (submenu_start[i], submenu_end[i],
+				      submenu_top_level_items[i]);
+	  if (prev_wv)
+	    prev_wv->next = wv;
+	  else
+	    first_wv->contents = wv;
+	  /* Don't set wv->name here; GC during the loop might relocate it.  */
+	  wv->enabled = 1;
+	  wv->button_type = BUTTON_TYPE_NONE;
+	  prev_wv = wv;
+	}
+
+      set_buffer_internal_1 (prev);
+
+      /* Compare the new menu items with previous, and leave off if no change */
+      /* PENDING: following other terms here, but seems like this should be
+         done before parse stage 2 above, since its results aren't used */
+      if (previous_menu_items_used
+          && (!submenu || (submenu && submenu == last_submenu))
+          && menu_items_used == previous_menu_items_used)
+        {
+          for (i = 0; i < previous_menu_items_used; i++)
+            /* PENDING: this ALWAYS fails on Buffers menu items.. something
+               about their strings causes them to change every time, so we
+               double-check failures */
+            if (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))
+              if (!(STRINGP (previous_items[i])
+                    && STRINGP (XVECTOR (menu_items)->contents[i])
+                    && !strcmp (SDATA (previous_items[i]),
+                               SDATA (XVECTOR (menu_items)->contents[i]))))
+                  break;
+          if (i == previous_menu_items_used)
+            {
+              /* No change.. */
+
+#ifdef NSMENUPROFILE
+              ftime (&tb);
+              t += 1000*tb.time+tb.millitm;
+              fprintf (stderr, "NO CHANGE!  CUTTING OUT after %ld msec.\n", t);
+#endif
+
+              free_menubar_widget_value_tree (first_wv);
+              discard_menu_items ();
+              unbind_to (specpdl_count, Qnil);
+              [pool release];
+              UNBLOCK_INPUT;
+              return;
+            }
+        }
+      /* The menu items are different, so store them in the frame */
+      /* PENDING: this is not correct for single-submenu case */
+      f->menu_bar_vector = menu_items;
+      f->menu_bar_items_used = menu_items_used;
+
+      /* Calls restore_menu_items, etc., as they were outside */
+      unbind_to (specpdl_count, Qnil);
+
+      /* Parse stage 2a: now GC cannot happen during the lifetime of the
+         widget_value, so it's safe to store data from a Lisp_String */
+      wv = first_wv->contents;
+      for (i = 0; i < XVECTOR (items)->size; i += 4)
+	{
+	  Lisp_Object string;
+	  string = XVECTOR (items)->contents[i + 1];
+	  if (NILP (string))
+	    break;
+/*           if (submenu && strcmp (submenuTitle, SDATA (string)))
+               continue; */
+
+	  wv->name = (char *) SDATA (string);
+          update_submenu_strings (wv->contents);
+	  wv = wv->next;
+	}
+
+      /* Now, update the NS menu; if we have a submenu, use that, otherwise
+         create a new menu for each sub and fill it. */
+      if (submenu)
+        {
+          for (wv = first_wv->contents; wv; wv = wv->next)
+            {
+              if (!strcmp (submenuTitle, wv->name))
+                {
+                  [submenu fillWithWidgetValue: wv->contents];
+                  last_submenu = submenu;
+                  break;
+                }
+            }
+        }
+      else
+        {
+          [menu fillWithWidgetValue: first_wv->contents];
+        }
+
+    }
+  else
+    {
+      static int n_previous_strings = 0;
+      static char previous_strings[100][10];
+      static struct frame *last_f = NULL;
+      int n;
+      Lisp_Object string;
+
+      /* Make widget-value tree w/ just the top level menu bar strings */
+      items = FRAME_MENU_BAR_ITEMS (f);
+      if (NILP (items))
+        {
+          [pool release];
+          UNBLOCK_INPUT;
+          return;
+        }
+
+
+      /* check if no change.. this mechanism is a bit rough, but ready */
+      n = XVECTOR (items)->size / 4;
+      if (f == last_f && n_previous_strings == n)
+        {
+          for (i = 0; i<n; i++)
+            {
+              string = XVECTOR (items)->contents[4*i+1];
+
+              if (!string)
+                continue;
+              if (NILP (string))
+                if (previous_strings[i][0])
+                  break;
+              else
+                continue;
+              if (strncmp (previous_strings[i], SDATA (string), 10))
+                break;
+            }
+
+          if (i == n)
+            {
+              [pool release];
+              UNBLOCK_INPUT;
+              return;
+            }
+        }
+
+      [menu clear];
+      for (i = 0; i < XVECTOR (items)->size; i += 4)
+	{
+	  string = XVECTOR (items)->contents[i + 1];
+	  if (NILP (string))
+	    break;
+
+          if (n < 100)
+            strncpy (previous_strings[i/4], SDATA (string), 10);
+
+	  wv = xmalloc_widget_value ();
+	  wv->name = (char *) SDATA (string);
+	  wv->value = 0;
+	  wv->enabled = 1;
+	  wv->button_type = BUTTON_TYPE_NONE;
+	  wv->help = Qnil;
+	  wv->call_data = (void *) (EMACS_INT) (-1);
+
+#ifdef NS_IMPL_COCOA
+          /* we'll update the real copy under app menu when time comes */
+          if (!strcmp ("Services", wv->name))
+            {
+              /* but we need to make sure it will update on demand */
+              [svcsMenu setFrame: f];
+              [svcsMenu setDelegate: svcsMenu];
+            }
+          else
+#endif
+          [menu addSubmenuWithTitle: wv->name forFrame: f];
+
+	  if (prev_wv)
+	    prev_wv->next = wv;
+	  else
+	    first_wv->contents = wv;
+	  prev_wv = wv;
+	}
+
+      last_f = f;
+      if (n < 100)
+        n_previous_strings = n;
+      else
+        n_previous_strings = 0;
+
+    }
+  free_menubar_widget_value_tree (first_wv);
+
+
+#ifdef NSMENUPROFILE
+  ftime (&tb);
+  t += 1000*tb.time+tb.millitm;
+  fprintf (stderr, "Menu update took %ld msec.\n", t);
+#endif
+
+  /* set main menu */
+  if (needsSet)
+    [NSApp setMainMenu: menu];
+
+  [pool release];
+  UNBLOCK_INPUT;
+
+}
+
+
+/* Main emacs core entry point for menubar menus: called to indicate that the
+   frame's menus have changed, and the *step representation should be updated
+   from Lisp. */
+void
+set_frame_menubar (struct frame *f, int first_time, int deep_p)
+{
+  ns_update_menubar (f, deep_p, nil);
+}
+
+
+/* Utility (from macmenu.c): is this item a separator? */
+static int
+name_is_separator (name)
+     const char *name;
+{
+  const char *start = name;
+
+  /* Check if name string consists of only dashes ('-').  */
+  while (*name == '-') name++;
+  /* Separators can also be of the form "--:TripleSuperMegaEtched"
+     or "--deep-shadow".  We don't implement them yet, se we just treat
+     them like normal separators.  */
+  return (*name == '\0' || start + 2 == name);
+}
+
+
+/* ==========================================================================
+
+    Menu: class implementation
+
+   ========================================================================== */
+
+
+/* Menu that can define itself from Emacs "widget_value"s and will lazily
+   update itself when user clicked.  Based on Carbon/AppKit implementation
+   by Yamamoto Mitsuharu. */
+@implementation EmacsMenu
+
+/* override designated initializer */
+- initWithTitle: (NSString *)title
+{
+  if (self = [super initWithTitle: title])
+    [self setAutoenablesItems: NO];
+  return self;
+}
+
+
+/* used for top-level */
+- initWithTitle: (NSString *)title frame: (struct frame *)f
+{
+  [self initWithTitle: title];
+  frame = f;
+#ifdef NS_IMPL_COCOA
+  [self setDelegate: self];
+#endif
+  return self;
+}
+
+
+- (void)setFrame: (struct frame *)f
+{
+  frame = f;
+}
+
+
+/* delegate method called when a submenu is being opened: run a 'deep' call
+   to set_frame_menubar */
+- (void)menuNeedsUpdate: (NSMenu *)menu
+{
+  NSEvent *event = [[FRAME_NS_VIEW (frame) window] currentEvent];
+  /* HACK: Cocoa/Carbon will request update on every keystroke
+     via IsMenuKeyEvent -> CheckMenusForKeyEvent.  These are not needed
+     since key equivalents are handled through emacs.
+     On Leopard, even keystroke events generate SystemDefined events, but
+     their subtype is 8. */
+  if ([event type] != NSSystemDefined || [event subtype] == 8)
+    return;
+/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */
+  ns_update_menubar (frame, 1, self);
+}
+
+
+- (BOOL)performKeyEquivalent: (NSEvent *)theEvent
+{
+  if (SELECTED_FRAME () && FRAME_NS_P (SELECTED_FRAME ())
+      && FRAME_NS_VIEW (SELECTED_FRAME ()))
+    [FRAME_NS_VIEW (SELECTED_FRAME ()) keyDown: theEvent];
+  return YES;
+}
+
+
+/* parse a wdiget_value's key rep (examples: 's-p', 's-S', '(C-x C-s)', '<f13>')
+   into an accelerator string */
+-(NSString *)parseKeyEquiv: (char *)key
+{
+  char *tpos = key;
+  keyEquivModMask = 0;
+  /* currently we just parse 'super' combinations;
+     later we'll set keyEquivModMask */
+  if (!key || !strlen (key))
+    return @"";
+  
+  while (*tpos == ' ' || *tpos == '(')
+    tpos++;
+  if (*tpos != 's'/* || tpos[3] != ')'*/)
+    return @"";
+  return [NSString stringWithFormat: @"%c", tpos[2]];
+}
+
+- (id <NSMenuItem>)addItemWithWidgetValue: (void *)wvptr
+{
+  id <NSMenuItem> item;
+  widget_value *wv = (widget_value *)wvptr;
+
+  if (name_is_separator (wv->name))
+    {
+      item = [NSMenuItem separatorItem];
+      [self addItem: item];
+    }
+  else
+    {
+      NSString *title, *keyEq;
+      title = [NSString stringWithUTF8String: wv->name];
+      if (title == nil)
+        title = @"< ? >";  /* (get out in the open so we know about it) */
+
+      keyEq = [self parseKeyEquiv: wv->key];
+
+      item = [self addItemWithTitle: (NSString *)title
+                             action: @selector (menuDown:)
+                      keyEquivalent: keyEq];
+      if (keyEquivModMask)
+        [item setKeyEquivalentModifierMask: keyEquivModMask];
+
+      [item setEnabled: wv->enabled];
+
+      /* Draw radio buttons and tickboxes */
+      if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE ||
+                           wv->button_type == BUTTON_TYPE_RADIO))
+        [item setState: NSOnState];
+      else
+        [item setState: NSOffState];
+
+      [item setTag: (int)wv->call_data];
+    }
+
+  return item;
+}
+
+
+/* convenience */
+-(void) clear
+{
+  int n;
+  
+  for (n = [self numberOfItems]-1; n >= 0; n--)
+    {
+      NSMenuItem *item = [self itemAtIndex: n];
+      NSString *title = [item title];
+      if (([title length] == 0 || [@"Apple" isEqualToString: title])
+          && ![item isSeparatorItem])
+        continue;
+      [self removeItemAtIndex: n];
+    }
+}
+
+
+- (void)fillWithWidgetValue: (void *)wvptr
+{
+  widget_value *wv = (widget_value *)wvptr;
+
+  /* clear existing contents */
+  [self setMenuChangedMessagesEnabled: NO];
+  [self clear];
+
+  /* add new contents */
+  for (; wv != NULL; wv = wv->next)
+    {
+      id <NSMenuItem> item = [self addItemWithWidgetValue: wv];
+
+      if (wv->contents)
+        {
+          EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: @"Submenu"];
+
+          [self setSubmenu: submenu forItem: item];
+          [submenu fillWithWidgetValue: wv->contents];
+          [submenu release];
+          [item setAction: nil];
+        }
+    }
+
+  [self setMenuChangedMessagesEnabled: YES];
+#ifdef NS_IMPL_GNUSTEP
+  if ([[self window] isVisible])
+    [self sizeToFit];
+#else
+  if ([self supermenu] == nil)
+    [self sizeToFit];
+#endif
+}
+
+
+/* adds an empty submenu and returns it */
+- (EmacsMenu *)addSubmenuWithTitle: (char *)title forFrame: (struct frame *)f
+{
+  NSString *titleStr = [NSString stringWithUTF8String: title];
+  id <NSMenuItem> item =
+    [self addItemWithTitle: titleStr
+                    action: nil /*@selector (menuDown:) */
+             keyEquivalent: @""];
+  EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr frame: f];
+  [self setSubmenu: submenu forItem: item];
+  [submenu release];
+  return submenu;
+}
+
+/* run a menu in popup mode */
+- (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f
+                 keymaps: (int)keymaps
+{
+  EmacsView *view = FRAME_NS_VIEW (f);
+/*   p = [view convertPoint:p fromView: nil]; */
+  p.y = NSHeight ([view frame]) - p.y;
+  NSEvent *e = [[view window] currentEvent];
+  NSEvent *event = [NSEvent mouseEventWithType: NSRightMouseDown
+                                      location: p
+                                 modifierFlags: 0
+                                     timestamp: [e timestamp]
+                                  windowNumber: [[view window] windowNumber]
+                                       context: [e context]
+                                   eventNumber: 0/*[e eventNumber] */
+                                    clickCount: 1
+                                      pressure: 0];
+  long retVal;
+
+  context_menu_value = -1;
+  [NSMenu popUpContextMenu: self withEvent: event forView: view];
+  retVal = context_menu_value;
+  context_menu_value = 0;
+  return retVal > 0 ?
+    find_and_return_menu_selection (f, keymaps, (void *)retVal) : Qnil;
+}
+
+@end  /* EmacsMenu */
+
+
+
+/* ==========================================================================
+
+    Context Menu: implementing functions
+
+   ========================================================================== */
+
+static Lisp_Object
+cleanup_popup_menu (Lisp_Object arg)
+{
+  discard_menu_items ();
+  return Qnil;
+}
+
+
+static Lisp_Object
+ns_popup_menu (Lisp_Object position, Lisp_Object menu)
+{
+  EmacsMenu *pmenu;
+  struct frame *f = NULL;
+  NSPoint p;
+  Lisp_Object window, x, y, tem, keymap, title;
+  struct gcpro gcpro1;
+  int specpdl_count = SPECPDL_INDEX (), specpdl_count2;
+  char *error_name = NULL;
+  int keymaps = 0;
+  widget_value *wv, *first_wv = 0;
+
+  NSTRACE (ns_popup_menu);
+
+  if (!NILP (position))
+    {
+      check_ns ();
+  
+      if (EQ (position, Qt)
+          || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
+                                   || EQ (XCAR (position), Qtool_bar))))
+        {
+          /* Use the mouse's current position.  */
+          struct frame *new_f = SELECTED_FRAME ();
+
+          if (FRAME_TERMINAL (new_f)->mouse_position_hook)
+            (*FRAME_TERMINAL (new_f)->mouse_position_hook)
+              (&new_f, 0, 0, 0, &x, &y, 0);
+          if (new_f != 0)
+            XSETFRAME (window, new_f);
+          else
+            {
+              window = selected_window;
+              x = make_number (0);
+              y = make_number (0);
+            }
+        }
+      else
+        {
+          CHECK_CONS (position);
+          tem = Fcar (position);
+          if (XTYPE (tem) == Lisp_Cons)
+            {
+              window = Fcar (Fcdr (position));
+              x = Fcar (tem);
+              y = Fcar (Fcdr (tem));
+            }
+          else
+            {
+              tem = Fcar (Fcdr (position));
+              window = Fcar (tem);
+              tem = Fcar (Fcdr (Fcdr (tem)));
+              x = Fcar (tem);
+              y = Fcdr (tem);
+            }
+        }
+  
+      CHECK_NUMBER (x);
+      CHECK_NUMBER (y);
+
+      if (FRAMEP (window))
+        {
+          f = XFRAME (window);
+      
+          p.x = 0;
+          p.y = 0;
+        }
+      else
+        {
+          struct window *win = XWINDOW (window);
+          CHECK_LIVE_WINDOW (window);
+          f = XFRAME (WINDOW_FRAME (win));
+          p.x = FRAME_COLUMN_WIDTH (f) * WINDOW_LEFT_EDGE_COL (win);
+          p.y = FRAME_LINE_HEIGHT (f) * WINDOW_TOP_EDGE_LINE (win);
+        }
+
+      p.x += XINT (x); p.y += XINT (y);
+
+      XSETFRAME (Vmenu_updating_frame, f);
+    }
+  else
+    {      /* no position given */
+      /* PENDING: if called during dump, we need to stop precomputation of
+         key equivalents (see below) because the keydefs in ns-win.el have
+         not been loaded yet. */
+      if (noninteractive)
+        return Qnil;
+      Vmenu_updating_frame = Qnil;
+    }
+
+  /* now parse the lisp menus */
+  record_unwind_protect (unuse_menu_items, Qnil);
+  title = Qnil;
+  GCPRO1 (title);
+
+  /* Decode the menu items from what was specified.  */
+
+  keymap = get_keymap (menu, 0, 0);
+  if (CONSP (keymap))
+    {
+      /* We were given a keymap.  Extract menu info from the keymap.  */
+      Lisp_Object prompt;
+
+      /* Extract the detailed info to make one pane.  */
+      keymap_panes (&menu, 1, NILP (position));
+
+      /* Search for a string appearing directly as an element of the keymap.
+	 That string is the title of the menu.  */
+      prompt = Fkeymap_prompt (keymap);
+      title = NILP (prompt) ? build_string ("Select") : prompt;
+
+      /* Make that be the pane title of the first pane.  */
+      if (!NILP (prompt) && menu_items_n_panes >= 0)
+	XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = prompt;
+
+      keymaps = 1;
+    }
+  else if (CONSP (menu) && KEYMAPP (XCAR (menu)))
+    {
+      /* We were given a list of keymaps.  */
+      int nmaps = XFASTINT (Flength (menu));
+      Lisp_Object *maps
+	= (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
+      int i;
+
+      title = Qnil;
+
+      /* The first keymap that has a prompt string
+	 supplies the menu title.  */
+      for (tem = menu, i = 0; CONSP (tem); tem = XCDR (tem))
+	{
+	  Lisp_Object prompt;
+
+	  maps[i++] = keymap = get_keymap (XCAR (tem), 1, 0);
+
+	  prompt = Fkeymap_prompt (keymap);
+	  if (NILP (title) && !NILP (prompt))
+	    title = prompt;
+	}
+
+      /* Extract the detailed info to make one pane.  */
+      keymap_panes (maps, nmaps, NILP (position));
+
+      /* Make the title be the pane title of the first pane.  */
+      if (!NILP (title) && menu_items_n_panes >= 0)
+	XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = title;
+
+      keymaps = 1;
+    }
+  else
+    {
+      /* We were given an old-fashioned menu.  */
+      title = Fcar (menu);
+      CHECK_STRING (title);
+
+      list_of_panes (Fcdr (menu));
+
+      keymaps = 0;
+    }
+
+  unbind_to (specpdl_count, Qnil);
+
+  /* If no position given, that was a signal to just precompute and cache
+     key equivalents, which was a side-effect of what we just did. */
+  if (NILP (position))
+    {
+      discard_menu_items ();
+      UNGCPRO;
+      return Qnil;
+    }
+
+  record_unwind_protect (cleanup_popup_menu, Qnil);
+  BLOCK_INPUT;
+
+  /* now parse stage 2 as in ns_update_menubar */
+  wv = xmalloc_widget_value ();
+  wv->name = "contextmenu";
+  wv->value = 0;
+  wv->enabled = 1;
+  wv->button_type = BUTTON_TYPE_NONE;
+  wv->help = Qnil;
+  first_wv = wv;
+
+  specpdl_count2 = SPECPDL_INDEX ();
+
+#if 0
+  /*PENDING: a couple of one-line differences prevent reuse */
+  wv = digest_single_submenu (0, menu_items_used, Qnil);
+#else
+  {
+  widget_value *save_wv = 0, *prev_wv = 0;
+  widget_value **submenu_stack
+    = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
+/*   Lisp_Object *subprefix_stack
+       = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); */
+  int submenu_depth = 0;
+  int first_pane = 1;
+  int i;
+
+  /* Loop over all panes and items, filling in the tree.  */
+  i = 0;
+  while (i < menu_items_used)
+    {
+      if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
+	{
+	  submenu_stack[submenu_depth++] = save_wv;
+	  save_wv = prev_wv;
+	  prev_wv = 0;
+	  first_pane = 1;
+	  i++;
+	}
+      else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
+	{
+	  prev_wv = save_wv;
+	  save_wv = submenu_stack[--submenu_depth];
+	  first_pane = 0;
+	  i++;
+	}
+      else if (EQ (XVECTOR (menu_items)->contents[i], Qt)
+	       && submenu_depth != 0)
+	i += MENU_ITEMS_PANE_LENGTH;
+      /* Ignore a nil in the item list.
+	 It's meaningful only for dialog boxes.  */
+      else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+	i += 1;
+      else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+	{
+	  /* Create a new pane.  */
+	  Lisp_Object pane_name, prefix;
+	  char *pane_string;
+
+	  pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
+	  prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
+
+#ifndef HAVE_MULTILINGUAL_MENU
+	  if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
+	    {
+	      pane_name = ENCODE_MENU_STRING (pane_name);
+	      ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
+	    }
+#endif
+	  pane_string = (NILP (pane_name)
+			 ? "" : (char *) SDATA (pane_name));
+	  /* If there is just one top-level pane, put all its items directly
+	     under the top-level menu.  */
+	  if (menu_items_n_panes == 1)
+	    pane_string = "";
+
+	  /* If the pane has a meaningful name,
+	     make the pane a top-level menu item
+	     with its items as a submenu beneath it.  */
+	  if (!keymaps && strcmp (pane_string, ""))
+	    {
+	      wv = xmalloc_widget_value ();
+	      if (save_wv)
+		save_wv->next = wv;
+	      else
+		first_wv->contents = wv;
+	      wv->name = pane_string;
+	      if (keymaps && !NILP (prefix))
+		wv->name++;
+	      wv->value = 0;
+	      wv->enabled = 1;
+	      wv->button_type = BUTTON_TYPE_NONE;
+	      wv->help = Qnil;
+	      save_wv = wv;
+	      prev_wv = 0;
+	    }
+	  else if (first_pane)
+	    {
+	      save_wv = wv;
+	      prev_wv = 0;
+	    }
+	  first_pane = 0;
+	  i += MENU_ITEMS_PANE_LENGTH;
+	}
+      else
+	{
+	  /* Create a new item within current pane.  */
+	  Lisp_Object item_name, enable, descrip, def, type, selected, help;
+	  item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
+	  enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
+	  descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
+	  def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
+	  type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
+	  selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
+	  help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
+
+#ifndef HAVE_MULTILINGUAL_MENU
+          if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
+	    {
+	      item_name = ENCODE_MENU_STRING (item_name);
+	      ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
+	    }
+
+          if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
+	    {
+	      descrip = ENCODE_MENU_STRING (descrip);
+	      ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
+	    }
+#endif /* not HAVE_MULTILINGUAL_MENU */
+
+	  wv = xmalloc_widget_value ();
+	  if (prev_wv)
+	    prev_wv->next = wv;
+	  else
+	    save_wv->contents = wv;
+	  wv->name = (char *) SDATA (item_name);
+	  if (!NILP (descrip))
+	    wv->key = (char *) SDATA (descrip);
+	  wv->value = 0;
+	  /* If this item has a null value,
+	     make the call_data null so that it won't display a box
+	     when the mouse is on it.  */
+	  wv->call_data =
+            !NILP (def) ? (void *) &XVECTOR (menu_items)->contents[i] : 0;
+	  wv->enabled = !NILP (enable);
+
+	  if (NILP (type))
+	    wv->button_type = BUTTON_TYPE_NONE;
+	  else if (EQ (type, QCtoggle))
+	    wv->button_type = BUTTON_TYPE_TOGGLE;
+	  else if (EQ (type, QCradio))
+	    wv->button_type = BUTTON_TYPE_RADIO;
+	  else
+	    abort ();
+
+	  wv->selected = !NILP (selected);
+
+          if (! STRINGP (help))
+	    help = Qnil;
+
+	  wv->help = help;
+
+	  prev_wv = wv;
+
+	  i += MENU_ITEMS_ITEM_LENGTH;
+	}
+    }
+  }
+#endif
+
+  if (!NILP (title))
+    {
+      widget_value *wv_title = xmalloc_widget_value ();
+      widget_value *wv_sep = xmalloc_widget_value ();
+
+      /* Maybe replace this separator with a bitmap or owner-draw item
+	 so that it looks better.  Having two separators looks odd.  */
+      wv_sep->name = "--";
+      wv_sep->next = first_wv->contents;
+      wv_sep->help = Qnil;
+
+#ifndef HAVE_MULTILINGUAL_MENU
+      if (STRING_MULTIBYTE (title))
+	title = ENCODE_MENU_STRING (title);
+#endif
+
+      wv_title->name = (char *) SDATA (title);
+      wv_title->enabled = NULL;
+      wv_title->button_type = BUTTON_TYPE_NONE;
+      wv_title->help = Qnil;
+      wv_title->next = wv_sep;
+      first_wv->contents = wv_title;
+    }
+
+  pmenu = [[EmacsMenu alloc] initWithTitle:
+                               [NSString stringWithUTF8String: SDATA (title)]];
+  [pmenu fillWithWidgetValue: first_wv->contents];
+  free_menubar_widget_value_tree (first_wv);
+  unbind_to (specpdl_count2, Qnil);
+
+  tem = [pmenu runMenuAt: p forFrame: f keymaps: keymaps];
+  [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
+
+  UNBLOCK_INPUT;
+  unbind_to (specpdl_count, Qnil);
+  UNGCPRO;
+
+  if (error_name) error (error_name);
+  return tem;
+}
+
+
+
+
+/* ==========================================================================
+
+    Toolbar: externally-called functions
+
+   ========================================================================== */
+
+void
+free_frame_tool_bar (FRAME_PTR f)
+/* --------------------------------------------------------------------------
+    Under NS we just hide the toolbar until it might be needed again.
+   -------------------------------------------------------------------------- */
+{
+  [[FRAME_NS_VIEW (f) toolbar] setVisible: NO];
+}
+
+void
+update_frame_tool_bar (FRAME_PTR f)
+/* --------------------------------------------------------------------------
+    Update toolbar contents
+   -------------------------------------------------------------------------- */
+{
+  int i;
+  EmacsToolbar *toolbar = [FRAME_NS_VIEW (f) toolbar];
+
+  if (NILP (f->tool_bar_lines) || !INTEGERP (f->tool_bar_lines))
+    return;
+
+  [toolbar clearActive];
+
+  /* update EmacsToolbar as in GtkUtils, build items list */
+  for (i = 0; i < f->n_tool_bar_items; ++i)
+    {
+#define TOOLPROP(IDX) AREF (f->tool_bar_items, \
+                            i * TOOL_BAR_ITEM_NSLOTS + (IDX))
+
+      BOOL enabled_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_ENABLED_P));
+      BOOL selected_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_SELECTED_P));
+      int idx;
+      int img_id;
+      struct image *img;
+      Lisp_Object image;
+      Lisp_Object helpObj;
+      char *helpText;
+
+      /* If image is a vector, choose the image according to the
+	 button state.  */
+      image = TOOLPROP (TOOL_BAR_ITEM_IMAGES);
+      if (VECTORP (image))
+	{
+          /* NS toolbar auto-computes disabled and selected images */
+          idx = TOOL_BAR_IMAGE_ENABLED_SELECTED;
+	  xassert (ASIZE (image) >= idx);
+	  image = AREF (image, idx);
+	}
+      else
+        {
+          idx = -1;
+        }
+      /* Ignore invalid image specifications.  */
+      if (!valid_image_p (image))
+        {
+          NSLog (@"Invalid image for toolbar item");
+          continue;
+        }
+
+      img_id = lookup_image (f, image);
+      img = IMAGE_FROM_ID (f, img_id);
+      prepare_image_for_display (f, img);
+
+      if (img->load_failed_p || img->pixmap == nil)
+        {
+          NSLog (@"Could not prepare toolbar image for display.");
+          continue;
+        }
+
+      helpObj = TOOLPROP (TOOL_BAR_ITEM_HELP);
+      if (NILP (helpObj))
+        helpObj = TOOLPROP (TOOL_BAR_ITEM_CAPTION);
+      helpText = NILP (helpObj) ? "" : (char *)SDATA (helpObj);
+
+      [toolbar addDisplayItemWithImage: img->pixmap idx: i helpText: helpText
+                               enabled: enabled_p];
+#undef TOOLPROP
+    }
+
+  if (![toolbar isVisible])
+      [toolbar setVisible: YES];
+
+  if ([toolbar changed])
+    {
+      /* inform app that toolbar has changed */
+      NSDictionary *dict = [toolbar configurationDictionary];
+      NSMutableDictionary *newDict = [dict mutableCopy];
+      NSEnumerator *keys = [[dict allKeys] objectEnumerator];
+      NSObject *key;
+      while ((key = [keys nextObject]) != nil)
+        {
+          NSObject *val = [dict objectForKey: key];
+          if ([val isKindOfClass: [NSArray class]])
+            {
+              [newDict setObject:
+                         [toolbar toolbarDefaultItemIdentifiers: toolbar]
+                          forKey: key];
+              break;
+            }
+        }
+      [toolbar setConfigurationFromDictionary: newDict];
+      [newDict release];
+    }
+
+}
+
+
+/* ==========================================================================
+
+    Toolbar: class implementation
+
+   ========================================================================== */
+
+@implementation EmacsToolbar
+
+- initForView: (EmacsView *)view withIdentifier: (NSString *)identifier
+{
+  self = [super initWithIdentifier: identifier];
+  emacsView = view;
+  [self setDisplayMode: NSToolbarDisplayModeIconOnly];
+  [self setSizeMode: NSToolbarSizeModeSmall];
+  [self setDelegate: self];
+  identifierToItem = [[NSMutableDictionary alloc] initWithCapacity: 10];
+  activeIdentifiers = [[NSMutableArray alloc] initWithCapacity: 8];
+  prevEnablement = enablement = 0L;
+  return self;
+}
+
+- (void)dealloc
+{
+  [prevIdentifiers release];
+  [activeIdentifiers release];
+  [identifierToItem release];
+  [super dealloc];
+}
+
+- (void) clearActive
+{
+  [prevIdentifiers release];
+  prevIdentifiers = [activeIdentifiers copy];
+  [activeIdentifiers removeAllObjects];
+  prevEnablement = enablement;
+  enablement = 0L;
+}
+
+- (BOOL) changed
+{
+  return [activeIdentifiers isEqualToArray: prevIdentifiers] &&
+    enablement == prevEnablement ? NO : YES;
+}
+
+- (void) addDisplayItemWithImage: (EmacsImage *)img idx: (int)idx
+                        helpText: (char *)help enabled: (BOOL)enabled
+{
+  /* 1) come up w/identifier */
+  NSString *identifier =
+    [NSString stringWithFormat: @"%u", [img hash]];
+
+  /* 2) create / reuse item */
+  NSToolbarItem *item = [identifierToItem objectForKey: identifier];
+  if (item == nil)
+    {
+      item = [[[NSToolbarItem alloc] initWithItemIdentifier: identifier]
+               autorelease];
+      [item setImage: img];
+      [item setToolTip: [NSString stringWithCString: help]];
+      [item setTarget: emacsView];
+      [item setAction: @selector (toolbarClicked:)];
+    }
+
+  [item setTag: idx];
+  [item setEnabled: enabled];
+
+  /* 3) update state */
+  [identifierToItem setObject: item forKey: identifier];
+  [activeIdentifiers addObject: identifier];
+  enablement = (enablement << 1) | (enabled == YES);
+}
+
+/* This overrides super's implementation, which automatically sets
+   all items to enabled state (for some reason). */
+- (void)validateVisibleItems { }
+
+
+/* delegate methods */
+
+- (NSToolbarItem *)toolbar: (NSToolbar *)toolbar
+      itemForItemIdentifier: (NSString *)itemIdentifier
+  willBeInsertedIntoToolbar: (BOOL)flag
+{
+  /* look up NSToolbarItem by identifier and return... */
+  return [identifierToItem objectForKey: itemIdentifier];
+}
+
+- (NSArray *)toolbarDefaultItemIdentifiers: (NSToolbar *)toolbar
+{
+  /* return entire set.. */
+  return activeIdentifiers;
+}
+
+/* for configuration palette (not yet supported) */
+- (NSArray *)toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar
+{
+  /* return entire set... */
+  return [identifierToItem allKeys];
+}
+
+/* optional and unneeded */
+/* - toolbarWillAddItem: (NSNotification *)notification { } */
+/* - toolbarDidRemoveItem: (NSNotification *)notification { } */
+/* - (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar */
+
+@end  /* EmacsToolbar */
+
+
+
+/* ==========================================================================
+
+    Tooltip: class implementation
+
+   ========================================================================== */
+
+/* Needed because NeXTstep does not provide enough control over tooltip
+   display. */
+@implementation EmacsTooltip
+
+- init
+{
+  NSColor *col = [NSColor colorWithCalibratedRed: 1.0 green: 1.0
+                                            blue: 0.792 alpha: 0.95];
+  NSFont *font = [NSFont toolTipsFontOfSize: 0];
+  NSFont *sfont = [font screenFont];
+  int height = [sfont ascender] - [sfont descender];
+/*[font boundingRectForFont].size.height; */
+  NSRect r = NSMakeRect (0, 0, 100, height+6);
+
+  textField = [[NSTextField alloc] initWithFrame: r];
+  [textField setFont: font];
+  [textField setBackgroundColor: col];
+
+  [textField setEditable: NO];
+  [textField setSelectable: NO];
+  [textField setBordered: YES];
+  [textField setBezeled: YES];
+  [textField setDrawsBackground: YES];
+
+  win = [[NSWindow alloc]
+            initWithContentRect: [textField frame]
+                      styleMask: 0
+                        backing: NSBackingStoreBuffered
+                          defer: YES];
+  [win setReleasedWhenClosed: NO];
+  [win setDelegate: self];
+  [[win contentView] addSubview: textField];
+/*  [win setBackgroundColor: col]; */
+  [win setOpaque: NO];
+
+  return self;
+}
+
+- (void) dealloc
+{
+  [win close];
+  [win release];
+  [textField release];
+  [super dealloc];
+}
+
+- (void) setText: (char *)text
+{
+  NSString *str = [NSString stringWithUTF8String: text];
+  NSRect r = [textField frame];
+  r.size.width = [[[textField font] screenFont] widthOfString: str] + 8;
+  [textField setFrame: r];
+  [textField setStringValue: str];
+}
+
+- (void) showAtX: (int)x Y: (int)y for: (int)seconds
+{
+  NSRect wr = [win frame];
+
+  wr.origin = NSMakePoint (x, y);
+  wr.size = [textField frame].size;
+
+  [win setFrame: wr display: YES];
+  [win orderFront: self];
+  [win display];
+  timer = [NSTimer scheduledTimerWithTimeInterval: (float)seconds target: self
+                                         selector: @selector (hide)
+                                         userInfo: nil repeats: NO];
+  [timer retain];
+}
+
+- (void) hide
+{
+  [win close];
+  if (timer != nil)
+    {
+      if ([timer isValid])
+        [timer invalidate];
+      [timer release];
+      timer = nil;
+    }
+}
+
+- (BOOL) isActive
+{
+  return timer != nil;
+}
+
+- (NSRect) frame
+{
+  return [textField frame];
+}
+
+@end  /* EmacsTooltip */
+
+
+
+/* ==========================================================================
+
+    Popup Dialog: implementing functions
+
+   ========================================================================== */
+
+Lisp_Object
+ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
+{
+  id dialog;
+  Lisp_Object window, tem;
+  struct frame *f;
+  NSPoint p;
+  BOOL isQ;
+
+  NSTRACE (x-popup-dialog);
+  
+  check_ns ();
+
+  isQ = NILP (header);
+
+  if (EQ (position, Qt))
+    {
+      window = selected_window;
+    }
+  else if (CONSP (position))
+    {
+      Lisp_Object tem;
+      tem = Fcar (position);
+      if (XTYPE (tem) == Lisp_Cons)
+        window = Fcar (Fcdr (position));
+      else
+        {
+          tem = Fcar (Fcdr (position));  /* EVENT_START (position) */
+          window = Fcar (tem);	     /* POSN_WINDOW (tem) */
+        }
+    }
+  else if (FRAMEP (position))
+    {
+      window = position;
+    }
+  else
+    {
+      CHECK_LIVE_WINDOW (position);
+      window = position;
+    }
+  
+  if (FRAMEP (window))
+    f = XFRAME (window);
+  else
+    {
+      CHECK_LIVE_WINDOW (window);
+      f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
+    }
+  p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2;
+  p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2;
+  dialog = [[EmacsDialogPanel alloc] initFromContents: contents
+                                           isQuestion: isQ];
+
+  tem = [dialog runDialogAt: p];
+
+  [dialog close];
+
+  [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
+  return tem;
+}
+
+
+/* ==========================================================================
+
+    Popup Dialog: class implementation
+
+   ========================================================================== */
+
+@interface FlippedView : NSView
+{
+}
+@end
+
+@implementation FlippedView
+- (BOOL)isFlipped
+{
+  return YES;
+}
+@end
+
+@implementation EmacsDialogPanel
+
+#define SPACER		8.0
+#define ICONSIZE	64.0
+#define TEXTHEIGHT	20.0
+#define MINCELLWIDTH	90.0
+
+- initWithContentRect: (NSRect)contentRect styleMask: (unsigned int)aStyle
+              backing: (NSBackingStoreType)backingType defer: (BOOL)flag
+{
+  NSSize spacing = {SPACER, SPACER};
+  NSRect area;
+  char this_cmd_name[80];
+  id cell, tem;
+  static NSImageView *imgView;
+  static FlippedView *contentView;
+
+  if (imgView == nil)
+    {
+      NSImage *img;
+      area.origin.x   = 3*SPACER;
+      area.origin.y   = 2*SPACER;
+      area.size.width = ICONSIZE;
+      area.size.height= ICONSIZE;
+      img = [[NSImage imageNamed: @"NSApplicationIcon"] copy];
+      [img setScalesWhenResized: YES];
+      [img setSize: NSMakeSize (ICONSIZE, ICONSIZE)];
+      imgView = [[NSImageView alloc] initWithFrame: area];
+      [imgView setImage: img];
+      [imgView setEditable: NO];
+      [img release];
+    }
+
+  aStyle = NSTitledWindowMask;
+  flag = YES;
+  rows = 0;
+  cols = 1;
+  [super initWithContentRect: contentRect styleMask: aStyle
+                     backing: backingType defer: flag];
+  contentView = [[FlippedView alloc] initWithFrame: [[self contentView] frame]];
+  [self setContentView: contentView];
+
+  [[self contentView] setAutoresizesSubviews: YES];
+
+  [[self contentView] addSubview: imgView];
+  [self setTitle: @""];
+
+  area.origin.x   += ICONSIZE+2*SPACER;
+/*  area.origin.y   = TEXTHEIGHT; ICONSIZE/2-10+SPACER; */
+  area.size.width = 400;
+  area.size.height= TEXTHEIGHT;
+  command = [[[NSTextField alloc] initWithFrame: area] autorelease];
+  [[self contentView] addSubview: command];
+  [command setStringValue: @"Emacs"];
+  [command setDrawsBackground: NO];
+  [command setBezeled: NO];
+  [command setSelectable: NO];
+  [command setFont: [NSFont boldSystemFontOfSize: 13.0]];
+
+/*  area.origin.x   = ICONSIZE+2*SPACER;
+  area.origin.y   = TEXTHEIGHT + 2*SPACER;
+  area.size.width = 400;
+  area.size.height= 2;
+  tem = [[[NSBox alloc] initWithFrame: area] autorelease];
+  [[self contentView] addSubview: tem];
+  [tem setTitlePosition: NSNoTitle];
+  [tem setAutoresizingMask: NSViewWidthSizable];*/
+
+/*  area.origin.x = ICONSIZE+2*SPACER; */
+  area.origin.y += TEXTHEIGHT+SPACER;
+  area.size.width = 400;
+  area.size.height= TEXTHEIGHT;
+  title = [[[NSTextField alloc] initWithFrame: area] autorelease];
+  [[self contentView] addSubview: title];
+  [title setDrawsBackground: NO];
+  [title setBezeled: NO];
+  [title setSelectable: NO];
+  [title setFont: [NSFont systemFontOfSize: 11.0]];
+
+  cell = [[[NSButtonCell alloc] initTextCell: @""] autorelease];
+  [cell setBordered: NO];
+  [cell setEnabled: NO];
+  [cell setCellAttribute: NSCellIsInsetButton to: 8];
+  [cell setBezelStyle: NSRoundedBezelStyle];
+
+  matrix = [[NSMatrix alloc] initWithFrame: contentRect 
+                                      mode: NSHighlightModeMatrix 
+                                 prototype: cell 
+                              numberOfRows: 0 
+                           numberOfColumns: 1];
+  [[self contentView] addSubview: matrix];
+  [matrix release];
+  [matrix setFrameOrigin: NSMakePoint (area.origin.x,
+                                      area.origin.y + (TEXTHEIGHT+3*SPACER))];
+  [matrix setIntercellSpacing: spacing];
+
+  [self setOneShot: YES];
+  [self setReleasedWhenClosed: YES];
+  [self setHidesOnDeactivate: YES];
+  return self;
+}
+
+
+- (BOOL)windowShouldClose: (id)sender
+{
+  [NSApp stopModalWithCode: Qnil];
+  return NO;
+}
+
+
+void process_dialog (id window, Lisp_Object list)
+{
+  Lisp_Object item;
+  int row = 0;
+
+  for (; XTYPE (list) == Lisp_Cons; list = XCDR (list))
+    {
+      item = XCAR (list);
+      if (XTYPE (item) == Lisp_String)
+        {
+          [window addString: XSTRING (item)->data row: row++];
+        }
+      else if (XTYPE (item) == Lisp_Cons)
+        {
+          [window addButton: XSTRING (XCAR (item))->data
+                      value: XCDR (item) row: row++];
+        }
+      else if (NILP (item))
+        {
+          [window addSplit];
+          row = 0;
+        }
+    }
+}
+
+
+- addButton: (char *)str value: (Lisp_Object)val row: (int)row
+{
+  id cell;
+       
+  if (row >= rows)
+    {
+      [matrix addRow];
+      rows++;
+    }
+  cell = [matrix cellAtRow: row column: cols-1];
+  [cell setTarget: self];
+  [cell setAction: @selector (clicked: )];
+  [cell setTitle: [NSString stringWithUTF8String: str]];
+  [cell setTag: (int)val];
+  [cell setBordered: YES];
+  [cell setEnabled: YES];
+
+  return self;
+}
+
+
+- addString: (char *)str row: (int)row
+{
+  id cell;
+       
+  if (row >= rows)
+    {
+      [matrix addRow];
+      rows++;
+    }
+  cell = [matrix cellAtRow: row column: cols-1];
+  [cell setTitle: [NSString stringWithUTF8String: str]];
+  [cell setBordered: YES];
+  [cell setEnabled: NO];
+
+  return self;
+}
+
+
+- addSplit
+{
+  [matrix addColumn];
+  cols++;
+  return self;
+}
+
+
+- clicked: sender
+{
+  NSArray *sellist = nil;
+  Lisp_Object seltag;
+
+  sellist = [sender selectedCells];
+  if ([sellist count]<1) 
+    return self;
+
+  seltag = (Lisp_Object)[[sellist objectAtIndex: 0] tag];
+  if (! EQ (seltag, Qundefined))
+    [NSApp stopModalWithCode: seltag];
+  return self;
+}
+
+
+- initFromContents: (Lisp_Object)contents isQuestion: (BOOL)isQ
+{
+  Lisp_Object head;
+  [super init];
+
+  if (XTYPE (contents) == Lisp_Cons)
+    {
+      head = Fcar (contents);
+      process_dialog (self, Fcdr (contents));
+    }
+  else
+    head = contents;
+
+  if (XTYPE (head) == Lisp_String)
+      [title setStringValue:
+                 [NSString stringWithUTF8String: XSTRING (head)->data]];
+  else if (isQ == YES)
+      [title setStringValue: @"Question"];
+  else
+      [title setStringValue: @"Information"];
+
+  {
+    int i;
+    NSRect r, s, t;
+
+    if (cols == 1 && rows > 1)	/* Never told where to split */
+      {
+        [matrix addColumn];
+        for (i = 0; i<rows/2; i++)
+          {
+            [matrix putCell: [matrix cellAtRow: (rows+1)/2 column: 0]
+                      atRow: i column: 1];
+            [matrix removeRow: (rows+1)/2];
+          }
+      }
+
+    [matrix sizeToFit];
+    {
+      NSSize csize = [matrix cellSize];
+      if (csize.width < MINCELLWIDTH)
+        {
+          csize.width = MINCELLWIDTH;
+          [matrix setCellSize: csize];
+          [matrix sizeToCells];
+        }
+    }
+
+    [title sizeToFit];
+    [command sizeToFit];
+
+    t = [matrix frame];
+    r = [title frame];
+    if (r.size.width+r.origin.x > t.size.width+t.origin.x)
+      {
+        t.origin.x   = r.origin.x;
+        t.size.width = r.size.width;
+      }
+    r = [command frame];
+    if (r.size.width+r.origin.x > t.size.width+t.origin.x)
+      {
+        t.origin.x   = r.origin.x;
+        t.size.width = r.size.width;
+      }
+
+    r = [self frame];
+    s = [(NSView *)[self contentView] frame];
+    r.size.width  += t.origin.x+t.size.width +2*SPACER-s.size.width;
+    r.size.height += t.origin.y+t.size.height+SPACER-s.size.height;
+    [self setFrame: r display: NO];
+  }
+
+  return self;
+}
+
+
+- (void)dealloc
+{
+  { [super dealloc]; return; };
+}
+
+
+- (Lisp_Object)runDialogAt: (NSPoint)p
+{
+  NSEvent *e;
+  NSModalSession session;
+  int ret;
+
+  [self center];  /*XXX p ignored? */
+  [self orderFront: NSApp];
+
+  session = [NSApp beginModalSessionForWindow: self];
+  while ((ret = [NSApp runModalSession: session]) == NSRunContinuesResponse)
+    {
+    (e = [NSApp nextEventMatchingMask: NSAnyEventMask
+                            untilDate: [NSDate distantFuture]
+                               inMode: NSEventTrackingRunLoopMode
+                              dequeue: NO]);
+/*fprintf (stderr, "ret = %d\te = %p\n", ret, e); */
+    }
+  [NSApp endModalSession: session];
+
+  return (Lisp_Object)ret;
+}
+
+@end
+
+
+
+/* ==========================================================================
+
+    Lisp definitions
+
+   ========================================================================== */
+
+DEFUN ("ns-reset-menu", Fns_reset_menu, Sns_reset_menu, 0, 0, 0,
+       "Cause the NS menu to be re-calculated.")
+     ()
+{
+  set_frame_menubar (SELECTED_FRAME (), 1, 0);
+  return Qnil;
+}
+
+
+DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
+       "Pop up a deck-of-cards menu and return user's selection.\n\
+POSITION is a position specification.  This is either a mouse button event\n\
+or a list ((XOFFSET YOFFSET) WINDOW)\n\
+where XOFFSET and YOFFSET are positions in pixels from the top left\n\
+corner of WINDOW's frame. (WINDOW may be a frame object instead of a window.)\n\
+This controls the position of the center of the first line\n\
+in the first pane of the menu, not the top left of the menu as a whole.\n\
+\n\
+MENU is a specifier for a menu.  For the simplest case, MENU is a keymap.\n\
+The menu items come from key bindings that have a menu string as well as\n\
+a definition; actually, the \"definition\" in such a key binding looks like\n\
+\(STRING . REAL-DEFINITION).  To give the menu a title, put a string into\n\
+the keymap as a top-level element.\n\n\
+You can also use a list of keymaps as MENU.\n\
+  Then each keymap makes a separate pane.\n\
+When MENU is a keymap or a list of keymaps, the return value\n\
+is a list of events.\n\n\
+Alternatively, you can specify a menu of multiple panes\n\
+  with a list of the form (TITLE PANE1 PANE2...),\n\
+where each pane is a list of form (TITLE ITEM1 ITEM2...).\n\
+Each ITEM is normally a cons cell (STRING . VALUE);\n\
+but a string can appear as an item--that makes a nonselectable line\n\
+in the menu.\n\
+With this form of menu, the return value is VALUE from the chosen item.")
+     (position, menu)
+     Lisp_Object position, menu;
+{
+  return ns_popup_menu (position, menu);
+}
+
+
+DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0,
+       doc: /* Pop up a dialog box and return user's selection.
+POSITION specifies which frame to use.
+This is normally a mouse button event or a window or frame.
+If POSITION is t, it means to use the frame the mouse is on.
+The dialog box appears in the middle of the specified frame.
+
+CONTENTS specifies the alternatives to display in the dialog box.
+It is a list of the form (DIALOG ITEM1 ITEM2...).
+Each ITEM is a cons cell (STRING . VALUE).
+The return value is VALUE from the chosen item.
+
+An ITEM may also be just a string--that makes a nonselectable item.
+An ITEM may also be nil--that means to put all preceding items
+on the left of the dialog box and all following items on the right.
+\(By default, approximately half appear on each side.)
+
+If HEADER is non-nil, the frame title for the box is "Information",
+otherwise it is "Question".
+
+If the user gets rid of the dialog box without making a valid choice,
+for instance using the window manager, then this produces a quit and
+`x-popup-dialog' does not return.  */)
+     (position, contents, header)
+     Lisp_Object position, contents, header;
+{
+  return ns_popup_dialog (position, contents, header);
+}
+
+
+/* ==========================================================================
+
+    Lisp interface declaration
+
+   ========================================================================== */
+
+void
+syms_of_nsmenu ()
+{
+  defsubr (&Sx_popup_menu);
+  defsubr (&Sx_popup_dialog);
+  defsubr (&Sns_reset_menu);
+  staticpro (&menu_items);
+  menu_items = Qnil;
+
+  Qdebug_on_next_call = intern ("debug-on-next-call");
+  staticpro (&Qdebug_on_next_call);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nsselect.m	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,624 @@
+/* NeXT/Open/GNUstep / MacOSX Cocoa selection processing for emacs.
+   Copyright (C) 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 (chris@nice.ch)
+OpenStep/Rhapsody port by Scott Bender (sbender@harmony-ds.com)
+MacOSX/Aqua port by Christophe de Dinechin (descubes@earthlink.net)
+GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
+
+*/
+
+#include "config.h"
+#include "lisp.h"
+#include "nsterm.h"
+#include "termhooks.h"
+
+#define CUT_BUFFER_SUPPORT
+
+Lisp_Object QPRIMARY, QSECONDARY, QTEXT, QFILE_NAME;
+
+static Lisp_Object Vns_sent_selection_hooks;
+static Lisp_Object Vns_lost_selection_hooks;
+static Lisp_Object Vselection_alist;
+static Lisp_Object Vselection_converter_alist;
+
+/* 23: new */
+/* Coding system for communicating with other programs. */
+static Lisp_Object Vselection_coding_system;
+/* Coding system for the next communicating with other programs. */
+static Lisp_Object Vnext_selection_coding_system;
+static Lisp_Object Qforeign_selection;
+
+NSString *NXSecondaryPboard;
+
+
+
+/* ==========================================================================
+
+    Internal utility functions
+
+   ========================================================================== */
+
+
+static NSString *
+symbol_to_nsstring (Lisp_Object sym)
+{
+  CHECK_SYMBOL (sym);
+  if (EQ (sym, QPRIMARY))     return NSGeneralPboard;
+  if (EQ (sym, QSECONDARY))   return NXSecondaryPboard;
+  if (EQ (sym, QTEXT))        return NSStringPboardType;
+  return [NSString stringWithUTF8String: XSTRING (XSYMBOL (sym)->xname)->data];
+}
+
+
+static Lisp_Object
+ns_string_to_symbol (NSString *t)
+{
+  if ([t isEqualToString: NSGeneralPboard])
+    return QPRIMARY;
+  if ([t isEqualToString: NXSecondaryPboard])
+    return QSECONDARY;
+  if ([t isEqualToString: NSStringPboardType])
+    return QTEXT;
+  if ([t isEqualToString: NSFilenamesPboardType])
+    return QFILE_NAME;
+  if ([t isEqualToString: NSTabularTextPboardType])
+    return QTEXT;
+  return intern ([t UTF8String]);
+}
+
+
+static Lisp_Object
+clean_local_selection_data (Lisp_Object obj)
+{
+  if (CONSP (obj)
+      && INTEGERP (XCAR (obj))
+      && CONSP (XCDR (obj))
+      && INTEGERP (XCAR (XCDR (obj)))
+      && NILP (XCDR (XCDR (obj))))
+    obj = Fcons (XCAR (obj), XCDR (obj));
+
+  if (CONSP (obj)
+      && INTEGERP (XCAR (obj))
+      && INTEGERP (XCDR (obj)))
+    {
+      if (XINT (XCAR (obj)) == 0)
+        return XCDR (obj);
+      if (XINT (XCAR (obj)) == -1)
+        return make_number (- XINT (XCDR (obj)));
+    }
+
+  if (VECTORP (obj))
+    {
+      int i;
+      int size = XVECTOR (obj)->size;
+      Lisp_Object copy;
+
+      if (size == 1)
+        return clean_local_selection_data (XVECTOR (obj)->contents [0]);
+      copy = Fmake_vector (size, Qnil);
+      for (i = 0; i < size; i++)
+        XVECTOR (copy)->contents [i]
+          = clean_local_selection_data (XVECTOR (obj)->contents [i]);
+      return copy;
+    }
+
+  return obj;
+}
+
+
+static void
+ns_declare_pasteboard (id pb)
+{
+  [pb declareTypes: ns_send_types owner: NSApp];
+}
+
+
+static void
+ns_undeclare_pasteboard (id pb)
+{
+  [pb declareTypes: [NSArray array] owner: nil];
+}
+
+
+static void
+ns_string_to_pasteboard_internal (id pb, Lisp_Object str, NSString *gtype)
+{
+  if (EQ (str, Qnil))
+    {
+      [pb declareTypes: [NSArray array] owner: nil];
+    }
+  else
+    {
+      char *utfStr;
+      NSString *type, *nsStr;
+      NSEnumerator *tenum;
+
+      CHECK_STRING (str);
+
+      utfStr = XSTRING (str)->data;
+      nsStr = [NSString stringWithUTF8String: utfStr];
+
+      if (gtype == nil)
+        {
+          [pb declareTypes: ns_send_types owner: nil];
+          tenum = [ns_send_types objectEnumerator];
+          while ( (type = [tenum nextObject]) )
+            [pb setString: nsStr forType: type];
+        }
+      else
+        {
+          [pb setString: nsStr forType: gtype];
+        }
+    }
+}
+
+
+static Lisp_Object
+ns_get_local_selection (Lisp_Object selection_name,
+                       Lisp_Object target_type)
+{
+  Lisp_Object local_value;
+  Lisp_Object handler_fn, value, type, check;
+  int count;
+
+  local_value = assq_no_quit (selection_name, Vselection_alist);
+
+  if (NILP (local_value)) return Qnil;
+
+  count = specpdl_ptr - specpdl;
+  specbind (Qinhibit_quit, Qt);
+  CHECK_SYMBOL (target_type);
+  handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist));
+  if (!NILP (handler_fn))
+    value =call3 (handler_fn, selection_name, target_type,
+                XCAR (XCDR (local_value)));
+  else
+    value =Qnil;
+  unbind_to (count, Qnil);
+
+  check =value;
+  if (CONSP (value) && SYMBOLP (XCAR (value)))
+    {
+      type = XCAR (value);
+      check = XCDR (value);
+    }
+
+  if (STRINGP (check) || VECTORP (check) || SYMBOLP (check)
+      || INTEGERP (check) || NILP (value))
+    return value;
+
+  if (CONSP (check)
+      && INTEGERP (XCAR (check))
+      && (INTEGERP (XCDR (check))||
+          (CONSP (XCDR (check))
+           && INTEGERP (XCAR (XCDR (check)))
+           && NILP (XCDR (XCDR (check))))))
+    return value;
+
+  Fsignal (Qquit, Fcons (build_string (
+      "invalid data returned by selection-conversion function"),
+                        Fcons (handler_fn, Fcons (value, Qnil))));
+}
+
+
+static Lisp_Object
+ns_get_foreign_selection (Lisp_Object symbol, Lisp_Object target)
+{
+  id pb;
+  pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (symbol)];
+  return ns_string_from_pasteboard (pb);
+}
+
+
+static void
+ns_handle_selection_request (struct input_event *event)
+{
+  id pb =(id)event->x;
+  NSString *type =(NSString *)event->y;
+  Lisp_Object selection_name, selection_data, target_symbol, data;
+  Lisp_Object successful_p, rest;
+
+  selection_name =ns_string_to_symbol ([(NSPasteboard *)pb name]);
+  target_symbol =ns_string_to_symbol (type);
+  selection_data = assq_no_quit (selection_name, Vselection_alist);
+  successful_p =Qnil;
+
+  if (!NILP (selection_data))
+    {
+      data = ns_get_local_selection (selection_name, target_symbol);
+      if (!NILP (data))
+        {
+          if (STRINGP (data))
+            ns_string_to_pasteboard_internal (pb, data, type);
+          successful_p =Qt;
+        }
+    }
+
+  if (!EQ (Vns_sent_selection_hooks, Qunbound))
+    {
+      for (rest =Vns_sent_selection_hooks;CONSP (rest); rest =Fcdr (rest))
+        call3 (Fcar (rest), selection_name, target_symbol, successful_p);
+    }
+}
+
+
+static void
+ns_handle_selection_clear (struct input_event *event)
+{
+  id pb = (id)event->x;
+  Lisp_Object selection_name, selection_data, rest;
+
+  selection_name =ns_string_to_symbol ([(NSPasteboard *)pb name]);
+  selection_data =assq_no_quit (selection_name, Vselection_alist);
+  if (NILP (selection_data)) return;
+
+  if (EQ (selection_data, Fcar (Vselection_alist)))
+    Vselection_alist = Fcdr (Vselection_alist);
+  else
+    {
+      for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
+        if (EQ (selection_data, Fcar (Fcdr (rest))))
+          Fsetcdr (rest, Fcdr (Fcdr (rest)));
+    }
+
+  if (!EQ (Vns_lost_selection_hooks, Qunbound))
+    {
+      for (rest =Vns_lost_selection_hooks;CONSP (rest); rest =Fcdr (rest))
+        call1 (Fcar (rest), selection_name);
+    }
+}
+
+
+
+/* ==========================================================================
+
+    Functions used externally
+
+   ========================================================================== */
+
+
+Lisp_Object
+ns_string_from_pasteboard (id pb)
+{
+  NSString *type, *str;
+  const char *utfStr;
+
+  type = [pb availableTypeFromArray: ns_return_types];
+  if (type == nil)
+    {
+      Fsignal (Qquit,
+              Fcons (build_string ("empty or unsupported pasteboard type"),
+                    Qnil));
+    return Qnil;
+    }
+
+  /* get the string */
+  if (! (str = [pb stringForType: type]))
+    {
+      NSData *data = [pb dataForType: type];
+      if (data != nil)
+        str = [[NSString alloc] initWithData: data
+                                    encoding: NSUTF8StringEncoding];
+      if (str != nil)
+        {
+          [str autorelease];
+        }
+      else
+        {
+          Fsignal (Qquit,
+                  Fcons (build_string ("pasteboard doesn't contain valid data"),
+                        Qnil));
+          return Qnil;
+        }
+    }
+
+  /* assume UTF8 */
+  NS_DURING
+    {
+      /* EOL conversion: PENDING- is this too simple? */
+      NSMutableString *mstr = [[str mutableCopy] autorelease];
+      [mstr replaceOccurrencesOfString: @"\r\n" withString: @"\n"
+            options: NSLiteralSearch range: NSMakeRange (0, [mstr length])];
+      [mstr replaceOccurrencesOfString: @"\r" withString: @"\n"
+            options: NSLiteralSearch range: NSMakeRange (0, [mstr length])];
+
+      utfStr = [mstr UTF8String];
+      if (!utfStr)
+        utfStr = [mstr cString];
+    }
+  NS_HANDLER
+    {
+      message1 ("ns_string_from_pasteboard: UTF8String failed\n");
+      utfStr = [str lossyCString];
+    }
+  NS_ENDHANDLER
+
+  return build_string (utfStr);
+}
+
+
+void
+ns_string_to_pasteboard (id pb, Lisp_Object str)
+{
+  ns_string_to_pasteboard_internal (pb, str, nil);
+}
+
+
+
+/* ==========================================================================
+
+    Lisp Defuns
+
+   ========================================================================== */
+
+
+DEFUN ("ns-own-selection-internal", Fns_own_selection_internal,
+       Sns_own_selection_internal, 2, 2, 0, "Assert a selection.")
+     (selection_name, selection_value)
+     Lisp_Object selection_name, selection_value;
+{
+  id pb;
+  Lisp_Object old_value, new_value;
+
+  check_ns ();
+  CHECK_SYMBOL (selection_name);
+  if (NILP (selection_value))
+      error ("selection-value may not be nil.");
+  pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (selection_name)];
+  ns_declare_pasteboard (pb);
+  old_value =assq_no_quit (selection_name, Vselection_alist);
+  new_value = Fcons (selection_name, Fcons (selection_value, Qnil));
+  if (NILP (old_value))
+    Vselection_alist =Fcons (new_value, Vselection_alist);
+  else
+    Fsetcdr (old_value, Fcdr (new_value));
+  /* XXX An evil hack, but a necessary one I fear XXX */
+  {
+    struct input_event ev;
+    ev.kind = SELECTION_REQUEST_EVENT;
+    ev.modifiers = 0;
+    ev.code = 0;
+    ev.x = (int)pb;
+    ev.y = (int)NSStringPboardType;
+    ns_handle_selection_request (&ev);
+  }
+  return selection_value;
+}
+
+
+DEFUN ("ns-disown-selection-internal", Fns_disown_selection_internal,
+       Sns_disown_selection_internal, 1, 2, 0,
+       "If we own the selection SELECTION, disown it.")
+     (selection_name, time)
+     Lisp_Object selection_name, time;
+{
+  id pb;
+  check_ns ();
+  CHECK_SYMBOL (selection_name);
+  if (NILP (assq_no_quit (selection_name, Vselection_alist))) return Qnil;
+
+  pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (selection_name)];
+  ns_undeclare_pasteboard (pb);
+  return Qt;
+}
+
+
+DEFUN ("ns-selection-exists-p", Fns_selection_exists_p, Sns_selection_exists_p,
+       0, 1, 0, "Whether there is an owner for the given selection.\n\
+The arg should be the name of the selection in question, typically one of\n\
+the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
+\(Those are literal upper-case symbol names.)\n\
+For convenience, the symbol nil is the same as `PRIMARY',\n\
+and t is the same as `SECONDARY'.)")
+     (selection)
+     Lisp_Object selection;
+{
+  id pb;
+  NSArray *types;
+
+  check_ns ();
+  CHECK_SYMBOL (selection);
+  if (EQ (selection, Qnil)) selection = QPRIMARY;
+  if (EQ (selection, Qt)) selection = QSECONDARY;
+  pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (selection)];
+  types =[pb types];
+  return ([types count] == 0) ? Qnil : Qt;
+}
+
+
+DEFUN ("ns-selection-owner-p", Fns_selection_owner_p, Sns_selection_owner_p,
+       0, 1, 0,
+       "Whether the current Emacs process owns the given selection.\n\
+The arg should be the name of the selection in question, typically one of\n\
+the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
+\(Those are literal upper-case symbol names.)\n\
+For convenience, the symbol nil is the same as `PRIMARY',\n\
+and t is the same as `SECONDARY'.)")
+     (selection)
+     Lisp_Object selection;
+{
+  check_ns ();
+  CHECK_SYMBOL (selection);
+  if (EQ (selection, Qnil)) selection = QPRIMARY;
+  if (EQ (selection, Qt)) selection = QSECONDARY;
+  return (NILP (Fassq (selection, Vselection_alist))) ? Qnil : Qt;
+}
+
+
+DEFUN ("ns-get-selection-internal", Fns_get_selection_internal,
+       Sns_get_selection_internal, 2, 2, 0,
+       "Return text selected from some pasteboard.\n\
+SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
+\(Those are literal upper-case symbol names.)\n\
+TYPE is the type of data desired, typically `STRING'.")
+     (selection_name, target_type)
+     Lisp_Object selection_name, target_type;
+{
+  Lisp_Object val;
+
+  check_ns ();
+  CHECK_SYMBOL (selection_name);
+  CHECK_SYMBOL (target_type);
+  val = ns_get_local_selection (selection_name, target_type);
+  if (NILP (val))
+    val = ns_get_foreign_selection (selection_name, target_type);
+  if (CONSP (val) && SYMBOLP (Fcar (val)))
+    {
+      val = Fcdr (val);
+      if (CONSP (val) && NILP (Fcdr (val)))
+        val = Fcar (val);
+    }
+  val = clean_local_selection_data (val);
+  return val;
+}
+
+
+#ifdef CUT_BUFFER_SUPPORT
+DEFUN ("ns-get-cut-buffer-internal", Fns_get_cut_buffer_internal,
+       Sns_get_cut_buffer_internal, 1, 1, 0,
+       "Returns the value of the named cut buffer.")
+     (buffer)
+     Lisp_Object buffer;
+{
+  id pb;
+  check_ns ();
+  pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (buffer)];
+  return ns_string_from_pasteboard (pb);
+}
+
+
+DEFUN ("ns-rotate-cut-buffers-internal", Fns_rotate_cut_buffers_internal,
+       Sns_rotate_cut_buffers_internal, 1, 1, 0,
+       "Rotate the values of the cut buffers by the given number of steps;\n\
+ positive means move values forward, negative means backward. CURRENTLY NOT IMPLEMENTED UNDER NeXTstep.")
+     (n)
+     Lisp_Object n;
+{
+  /* XXX This function is unimplemented under NeXTstep XXX */
+  Fsignal (Qquit, Fcons (build_string (
+      "Warning: ns-rotate-cut-buffers-internal not implemented\n"), Qnil));
+  return Qnil;
+}
+
+
+DEFUN ("ns-store-cut-buffer-internal", Fns_store_cut_buffer_internal,
+       Sns_store_cut_buffer_internal, 2, 2, 0,
+       "Sets the value of the named cut buffer (typically CUT_BUFFER0).")
+     (buffer, string)
+     Lisp_Object buffer, string;
+{
+  id pb;
+  check_ns ();
+  pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (buffer)];
+  ns_string_to_pasteboard (pb, string);
+  return Qnil;
+}
+#endif
+
+
+void
+nxatoms_of_nsselect (void)
+{
+  NXSecondaryPboard = @"Selection";
+}
+
+void
+syms_of_nsselect (void)
+{
+  QPRIMARY   = intern ("PRIMARY");	staticpro (&QPRIMARY);
+  QSECONDARY = intern ("SECONDARY");	staticpro (&QSECONDARY);
+  QTEXT      = intern ("TEXT"); 	staticpro (&QTEXT);
+  QFILE_NAME = intern ("FILE_NAME"); 	staticpro (&QFILE_NAME);
+
+  defsubr (&Sns_disown_selection_internal);
+  defsubr (&Sns_get_selection_internal);
+  defsubr (&Sns_own_selection_internal);
+  defsubr (&Sns_selection_exists_p);
+  defsubr (&Sns_selection_owner_p);
+#ifdef CUT_BUFFER_SUPPORT
+  defsubr (&Sns_get_cut_buffer_internal);
+  defsubr (&Sns_rotate_cut_buffers_internal);
+  defsubr (&Sns_store_cut_buffer_internal);
+#endif
+
+  Vselection_alist = Qnil;
+  staticpro (&Vselection_alist);
+
+  DEFVAR_LISP ("ns-sent-selection-hooks", &Vns_sent_selection_hooks,
+               "A list of functions to be called when Emacs answers a selection request.\n\
+The functions are called with four arguments:\n\
+  - the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');\n\
+  - the selection-type which Emacs was asked to convert the\n\
+    selection into before sending (for example, `STRING' or `LENGTH');\n\
+  - a flag indicating success or failure for responding to the request.\n\
+We might have failed (and declined the request) for any number of reasons,\n\
+including being asked for a selection that we no longer own, or being asked\n\
+to convert into a type that we don't know about or that is inappropriate.\n\
+This hook doesn't let you change the behavior of Emacs's selection replies,\n\
+it merely informs you that they have happened.");
+  Vns_sent_selection_hooks = Qnil;
+
+  DEFVAR_LISP ("selection-converter-alist", &Vselection_converter_alist,
+               "An alist associating X Windows selection-types with functions.\n\
+These functions are called to convert the selection, with three args:\n\
+the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');\n\
+a desired type to which the selection should be converted;\n\
+and the local selection value (whatever was given to `x-own-selection').\n\
+\n\
+The function should return the value to send to the X server\n\
+\(typically a string).  A return value of nil\n\
+means that the conversion could not be done.\n\
+A return value which is the symbol `NULL'\n\
+means that a side-effect was executed,\n\
+and there is no meaningful selection value.");
+  Vselection_converter_alist = Qnil;
+
+  DEFVAR_LISP ("ns-lost-selection-hooks", &Vns_lost_selection_hooks,
+               "A list of functions to be called when Emacs loses an X selection.\n\
+\(This happens when some other X client makes its own selection\n\
+or when a Lisp program explicitly clears the selection.)\n\
+The functions are called with one argument, the selection type\n\
+\(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD').");
+  Vns_lost_selection_hooks = Qnil;
+
+/* 23: { */
+  DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
+	       doc: /* Coding system for communicating with other programs.
+When sending or receiving text via cut_buffer, selection, and clipboard,
+the text is encoded or decoded by this coding system.
+The default value is determined by the system script code.  */);
+  Vselection_coding_system = Qnil;
+
+  DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
+	       doc: /* Coding system for the next communication with other programs.
+Usually, `selection-coding-system' is used for communicating with
+other programs.  But, if this variable is set, it is used for the
+next communication only.  After the communication, this variable is
+set to nil.  */);
+  Vnext_selection_coding_system = Qnil;
+
+  Qforeign_selection = intern ("foreign-selection");
+  staticpro (&Qforeign_selection);
+/* } */
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nsterm.h	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,827 @@
+/* Definitions and headers for communication with NeXT/Open/GNUstep API.
+   Copyright (C) 1989, 1993, 2005, 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.  */
+
+#include "dispextern.h"
+#include "frame.h"
+#include "character.h"
+#include "font.h"
+
+#ifdef HAVE_NS
+
+#ifdef __OBJC__
+
+/* ==========================================================================
+
+   The Emacs application
+
+   ========================================================================== */
+
+/* We override sendEvent: as a means to stop/start the event loop */
+@interface EmacsApp : NSApplication
+{
+}
+- (void)sendEvent: (NSEvent *)theEvent;
+- (void)showPreferencesWindow: (id)sender;
+@end
+
+
+/* ==========================================================================
+
+   The main Emacs view
+
+   ========================================================================== */
+
+@class EmacsToolbar;
+
+@interface EmacsView : NSView <NSTextInput>
+   {
+   char *old_title;
+   BOOL windowClosing;
+   NSString *workingText;
+   BOOL processingCompose;
+@public
+   struct frame *emacsframe;
+   int rows, cols;
+   int scrollbarsNeedingUpdate;
+   EmacsToolbar *toolbar;
+   }
+
+/* AppKit-side interface */
+- menuDown: sender;
+- toolbarClicked: (id)item;
+- toggleToolbar: (id)sender;
+- (void)keyDown: (NSEvent *)theEvent;
+- (void)mouseDown: (NSEvent *)theEvent;
+- (void)mouseUp: (NSEvent *)theEvent;
+- setMiniwindowImage: (BOOL)setMini;
+
+/* Emacs-side interface */
+- initFrameFromEmacs: (struct frame *) f;
+- (void) setRows: (int) r andColumns: (int) c;
+- (void) setWindowClosing: (BOOL)closing;
+- (EmacsToolbar *) toolbar;
+- (void) deleteWorkingText;
+@end
+
+
+/* Small utility used for processing resize events under Cocoa. */
+@interface EmacsWindow : NSWindow
+{
+  NSPoint grabOffset;
+}
+@end
+
+
+/* ==========================================================================
+
+   The main menu implementation
+
+   ========================================================================== */
+
+@interface EmacsMenu : NSMenu
+{
+  struct frame *frame;
+  unsigned long keyEquivModMask;
+}
+
+- initWithTitle: (NSString *)title frame: (struct frame *)f;
+- (void)setFrame: (struct frame *)f;
+- (void)menuNeedsUpdate: (NSMenu *)menu; /* (delegate method) */
+- (NSString *)parseKeyEquiv: (char *)key;
+- (id <NSMenuItem>)addItemWithWidgetValue: (void *)wvptr;
+- (void)fillWithWidgetValue: (void *)wvptr;
+- (EmacsMenu *)addSubmenuWithTitle: (char *)title forFrame: (struct frame *)f;
+- (void) clear;
+- (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f
+                 keymaps: (int)keymaps;
+@end
+
+
+/* ==========================================================================
+
+   Toolbar
+
+   ========================================================================== */
+
+@class EmacsImage;
+
+@interface EmacsToolbar : NSToolbar
+   {
+     EmacsView *emacsView;
+     NSMutableDictionary *identifierToItem;
+     NSMutableArray *activeIdentifiers;
+     NSArray *prevIdentifiers;
+     unsigned long enablement, prevEnablement;
+   }
+- initForView: (EmacsView *)view withIdentifier: (NSString *)identifier;
+- (void) clearActive;
+- (BOOL) changed;
+- (void) addDisplayItemWithImage: (EmacsImage *)img idx: (int)idx
+                        helpText: (char *)help
+                         enabled: (BOOL)enabled;
+/* delegate methods */
+- (NSToolbarItem *)toolbar: (NSToolbar *)toolbar
+     itemForItemIdentifier: (NSString *)itemIdentifier
+ willBeInsertedIntoToolbar: (BOOL)flag;
+- (NSArray *)toolbarDefaultItemIdentifiers: (NSToolbar *)toolbar;
+- (NSArray *)toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar;
+@end
+
+
+/* ==========================================================================
+
+   Message / question windows
+
+   ========================================================================== */
+
+@interface EmacsDialogPanel : NSPanel
+   {
+   NSTextField *command;
+   NSTextField *title;
+   NSMatrix *matrix;
+   int rows, cols;
+   }
+- initFromContents: (Lisp_Object)menu isQuestion: (BOOL)isQ;
+- addButton: (char *)str value: (Lisp_Object)val row: (int)row;
+- addString: (char *)str row: (int)row;
+- addSplit;
+- (Lisp_Object)runDialogAt: (NSPoint)p;
+@end
+
+@interface EmacsTooltip : NSObject
+  {
+    NSWindow *win;
+    NSTextField *textField;
+    NSTimer *timer;
+  }
+- init;
+- (void) setText: (char *)text;
+- (void) showAtX: (int)x Y: (int)y for: (int)seconds;
+- (void) hide;
+- (BOOL) isActive;
+- (NSRect) frame;
+@end
+
+
+/* ==========================================================================
+
+   File open/save panels
+   This and next override methods to work around OS X behavior of
+   restarting application loop when user dismisses panel.
+
+   ========================================================================== */
+
+@interface EmacsSavePanel : NSSavePanel
+{
+}
+@end
+@interface EmacsOpenPanel : NSOpenPanel
+{
+}
+@end
+
+@interface EmacsFileDelegate : NSObject
+{
+}
+- (BOOL)panel: (id)sender isValidFilename: (NSString *)filename;
+- (BOOL)panel: (id)sender shouldShowFilename: (NSString *)filename;
+- (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
+          confirmed: (BOOL)okFlag;
+@end
+
+
+/* ==========================================================================
+
+   Images and stippling
+
+   ========================================================================== */
+
+@interface EmacsImage : NSImage
+{
+  id imageListNext;
+  int refCount;
+  NSBitmapImageRep *bmRep; /* used for accessing pixel data */
+  unsigned char *pixmapData[5]; /* shortcut to access pixel data */
+  BOOL onTiger;
+  NSColor *stippleMask;
+}
++ allocInitFromFile: (Lisp_Object)file;
+- reference;
+- imageListSetNext: (id)arg;
+- imageListNext;
+- (void)dealloc;
+- initFromXBM: (unsigned char *)bits width: (int)w height: (int)h
+         flip: (BOOL)flip;
+- initFromSkipXBM: (unsigned char *)bits width: (int)w height: (int)h
+             flip: (BOOL)flip length: (int)length;
+- setXBMColor: (NSColor *)color;
+- initForXPMWithDepth: (int)depth width: (int)width height: (int)height;
+- (void)setPixmapData;
+- (unsigned long)getPixelAtX: (int)x Y: (int)y;
+- (void)setPixelAtX: (int)x Y: (int)y toRed: (unsigned char)r
+               green: (unsigned char)g blue: (unsigned char)b
+              alpha:(unsigned char)a;
+- (void)setAlphaAtX: (int)x Y: (int)y to: (unsigned char)a;
+- (NSColor *)stippleMask;
+@end
+
+
+/* ==========================================================================
+
+   Scrollbars
+
+   ========================================================================== */
+
+@interface EmacsScroller : NSScroller
+  {
+   Lisp_Object win;
+   struct frame *frame;
+   NSResponder *prevResponder;
+
+   /* offset to the bottom of knob of last mouse down */
+   float last_mouse_offset;
+   float min_portion;
+   int pixel_height;
+   int last_hit_part;
+
+   BOOL condemned;
+
+   /* optimize against excessive positioning calls generated by emacs */
+   int em_position;
+   int em_portion;
+   int em_whole;
+   }
+
+- initFrame: (NSRect )r window: (Lisp_Object)win;
+- (void)setFrame: (NSRect)r;
+- (void)dealloc;
+
+- setPosition: (int) position portion: (int) portion whole: (int) whole;
+- (int) checkSamePosition: (int)position portion: (int)portion
+                    whole: (int)whole;
+- (void) getMouseMotionPart: (int *)part window: (Lisp_Object *)window
+                          x: (Lisp_Object *)x y: ( Lisp_Object *)y;
+- (void) sendScrollEventAtLoc: (float)loc fromEvent: (NSEvent *)e;
+- repeatScroll: (NSTimer *)sender;
+- condemn;
+- reprieve;
+- judge;
+@end
+
+
+/* ==========================================================================
+
+   Rendering on Panther and above
+
+   ========================================================================== */
+
+#ifdef NS_IMPL_COCOA
+/* rendering util */
+@interface EmacsGlyphStorage : NSObject <NSGlyphStorage>
+{
+@public
+  NSAttributedString *attrStr;
+  NSMutableDictionary *dict;
+  CGGlyph *cglyphs;
+  unsigned long maxChar, maxGlyph;
+  long i, len;
+}
+- initWithCapacity: (unsigned long) c;
+- (void) setString: (NSString *)str font: (NSFont *)font;
+@end
+#endif	/* NS_IMPL_COCOA */
+
+
+/* ==========================================================================
+
+   Running the preferences window
+
+   ========================================================================== */
+
+@interface EmacsPrefsController : NSObject
+{
+    struct frame *frame;
+    IBOutlet NSWindow *prefsWindow;
+    IBOutlet NSPopUpButton *alternateModMenu;
+    IBOutlet NSPopUpButton *commandModMenu;
+#ifdef NS_IMPL_COCOA
+    IBOutlet NSPopUpButton *controlModMenu;
+    IBOutlet NSPopUpButton *functionModMenu;
+#endif
+    IBOutlet NSMatrix *cursorTypeMatrix;
+    IBOutlet NSSlider *cursorBlinkSlider;
+    IBOutlet NSSlider *expandSpaceSlider;
+#ifdef NS_IMPL_COCOA
+    IBOutlet NSButton *smoothFontsCheck;
+    IBOutlet NSButton *useQuickdrawCheck;
+    IBOutlet NSButton *useSysHiliteCheck;
+    BOOL prevUseHighlightColor;
+#endif
+    float prevExpandSpace;
+    float prevBlinkRate;
+}
+- (IBAction)cancel: (id)sender;
+- (IBAction)ok: (id)sender;
+- (IBAction)resetToDefaults: (id)sender;
+- (IBAction)runHelp: (id)sender;
+- (IBAction)setColors: (id)sender;
+- (IBAction)setDefaultFont: (id)sender;
+
+- (void) showForFrame: (struct frame *)f;
+- (void) setPanelFromValues;
+- (void) setValuesFromPanel;
+@end
+
+extern NSArray *ns_send_types, *ns_return_types;
+extern EmacsMenu *mainMenu, *svcsMenu;
+
+/* Apple removed the declaration, but kept the implementation */
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
+@interface NSApplication (EmacsApp)
+- (void)setAppleMenu: (NSMenu *)menu;
+@end
+#endif
+
+#endif  /* __OBJC__ */
+
+
+
+/* ==========================================================================
+
+   Non-OO stuff
+
+   ========================================================================== */
+
+enum ns_cursor_types
+{
+   no_highlight =0,
+   filled_box,
+   hollow_box,
+   underscore,
+   bar
+};
+
+
+/* could use list to store these, but rest of emacs has a big infrastructure
+   for managing a table of bitmap "records" */
+struct ns_bitmap_record
+{
+#ifdef __OBJC__
+  EmacsImage *img;
+#else
+  void *img;
+#endif
+  char *file;
+  int refcount;
+  int height, width, depth;
+};
+
+/* this to map between emacs color indices and NSColor objects */
+struct ns_color_table
+{
+  unsigned int size;
+  unsigned int avail;
+#ifdef __OBJC__
+  NSColor **colors;
+  NSMutableSet *empty_indices;
+#else
+  void **items;
+  void *availIndices;
+#endif
+};
+#define NS_COLOR_CAPACITY 256
+
+#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
+#define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+#define ALPHA_FROM_ULONG(color) ((color) >> 24)
+#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
+#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
+#define BLUE_FROM_ULONG(color) ((color) & 0xff)
+
+/* Do not change `* 0x101' in the following lines to `<< 8'.  If
+   changed, image masks in 1-bit depth will not work. */
+#define RED16_FROM_ULONG(color) (RED_FROM_ULONG(color) * 0x101)
+#define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG(color) * 0x101)
+#define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG(color) * 0x101)
+
+/* this extends font backend font */
+struct nsfont_info
+{
+  struct font font;
+
+  char *name;  /* postscript name, uniquely identifies on NS systems */
+  float width;  /* this and following metrics stored as float rather than int */
+  float height;
+  float underpos;
+  float underwidth;
+  float size;
+#ifdef __OBJC__
+  NSFont *nsfont;
+  /* cgfont and synthItal are used only on OS X 10.3+ */
+#if defined (NS_IMPL_COCOA) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
+  CGFontRef cgfont;
+#else /* GNUstep or OS X < 10.3 */
+  void *cgfont;
+#endif
+#else /* ! OBJC */
+  void *nsfont;
+  void *cgfont;
+#endif
+  char bold, ital;  /* convenience flags */
+  char synthItal;
+  float voffset;  /* mean of ascender/descender offsets */
+  XCharStruct max_bounds; /* 23 */
+  /* we compute glyph codes and metrics on-demand in blocks of 256 indexed
+     by hibyte, lobyte */
+  unsigned short **glyphs; /* map unicode index to glyph */
+  struct font_metrics **metrics;
+};
+
+
+/* init'd in ns_initialize_display_info () */
+struct ns_display_info
+{
+  /* Chain of all ns_display_info structures.  */
+  struct ns_display_info *next;
+
+  /* The generic display parameters corresponding to this NS display. */
+  struct terminal *terminal;
+
+  /* This is a cons cell of the form (NAME . FONT-LIST-CACHE).
+     The same cons cell also appears in ns_display_name_list.  */
+  Lisp_Object name_list_element;
+
+  /* The number of fonts loaded. */
+  int n_fonts;
+
+  /* Minimum width over all characters in all fonts in font_table.  */
+  int smallest_char_width;
+
+  /* Minimum font height over all fonts in font_table.  */
+  int smallest_font_height;
+
+  struct kboard *kboard;
+
+  /*/23 */
+  struct ns_bitmap_record *bitmaps;
+  int bitmaps_size;
+  int bitmaps_last;
+
+  /* 23 */
+  struct image_cache *image_cache;
+
+  struct ns_color_table *color_table;
+
+  /* 23: Dimensions and DPI resolution of this screen */
+  int height, width;
+  double resx, resy;
+
+  /* 23: Mask of things that cause the mouse to be grabbed */
+  int grabbed;
+
+  /* 23 */
+  int n_planes;
+
+  /* 23 */
+  int color_p;
+
+  /* 23 */
+  Window root_window;
+
+  /* 23: Xism */
+  XrmDatabase xrdb;
+
+  /* 23: The cursor to use for vertical scroll bars. */
+  Cursor vertical_scroll_bar_cursor;
+
+  /* 23: most mouse face stuff moved in here (and reasonably so) */
+  int mouse_face_beg_row, mouse_face_beg_col;
+  int mouse_face_end_row, mouse_face_end_col;
+  int mouse_face_beg_x, mouse_face_beg_y;
+  int mouse_face_end_x, mouse_face_end_y;
+  int mouse_face_past_end;
+  Lisp_Object mouse_face_window;
+  int mouse_face_face_id;
+  int mouse_face_deferred_gc;
+  Lisp_Object mouse_face_overlay;
+  FRAME_PTR mouse_face_mouse_frame;
+  int mouse_face_mouse_x, mouse_face_mouse_y;
+  int mouse_face_defer;
+  int mouse_face_hidden;
+  int mouse_face_image_state;
+
+  /* these are general, but we redefine due to Xism */
+  struct frame *ns_highlight_frame;
+  struct frame *ns_focus_frame;
+#define x_highlight_frame ns_highlight_frame
+#define x_focus_frame ns_focus_frame
+};
+
+/* This is a chain of structures for all the NS displays currently in use.  */
+extern struct ns_display_info *ns_display_list;
+/* handle Xism */
+#define x_display_list ns_display_list
+
+extern Lisp_Object ns_display_name_list;
+extern struct ns_display_info *ns_display_info_for_name ();
+
+/* 23: PENDING: these functions (we defined in nsfns) are used in various
+       places, but no prototypes are provided */
+struct ns_display_info *check_x_display_info (Lisp_Object frame);
+FRAME_PTR check_x_frame (Lisp_Object frame);
+
+
+struct ns_output
+{
+#ifdef __OBJC__
+  EmacsView *view;
+  id miniimage;
+  NSColor *current_cursor_color;
+  NSColor *desired_cursor_color;
+  NSColor *foreground_color;
+  NSColor *background_color;
+  EmacsToolbar *toolbar;
+#else
+  void *view;
+  void *miniimage;
+  void *current_cursor_color;
+  void *desired_cursor_color;
+  void *foreground_color;
+  void *background_color;
+  void *toolbar;
+#endif
+
+  /* 23: NSCursors init'ed in initFrameFromEmacs */
+  Cursor text_cursor;
+  Cursor nontext_cursor;
+  Cursor modeline_cursor;
+  Cursor hand_cursor;
+  Cursor hourglass_cursor;
+  Cursor horizontal_drag_cursor;
+
+  /* 23: NS-specific */
+  Cursor current_pointer;
+
+  /* 23: lord knows why Emacs needs to know about our Window ids.. */
+  Window window_desc, parent_desc;
+  char explicit_parent;
+
+  struct font *font;
+  int baseline_offset;
+
+  /* If a fontset is specified for this frame instead of font, this
+     value contains an ID of the fontset, else -1.  */
+  int fontset; /* only used with font_backend */
+
+  Lisp_Object icon_top;
+  Lisp_Object icon_left;
+  enum ns_cursor_types current_cursor, desired_cursor;
+  unsigned char last_inactive;
+
+  /* The size of the extra width currently allotted for vertical
+     scroll bars, in pixels.  */
+  int vertical_scroll_bar_extra;
+
+  /* The height of the titlebar decoration (included in NSWindow's frame). */
+  int titlebar_height;
+
+  /* The height of the toolbar if displayed, else 0. */
+  int toolbar_height;
+
+  /* This is the Emacs structure for the NS display this frame is on.  */
+  struct ns_display_info *display_info;
+};
+
+/* 23: this dummy decl now needed to support TTYs */
+struct x_output
+{
+  unsigned long background_pixel;
+  unsigned long foreground_pixel;
+};
+
+
+/* This gives the ns_display_info structure for the display F is on.  */
+#define FRAME_NS_DISPLAY_INFO(f) ((f)->output_data.ns->display_info)
+/* the primacy of X must be constantly worked with... */
+#define FRAME_X_DISPLAY_INFO(f) ((f)->output_data.ns->display_info)
+#define FRAME_X_OUTPUT(f) ((f)->output_data.ns)
+#define FRAME_NS_WINDOW(f) ((f)->output_data.ns->window_desc)
+#define FRAME_X_WINDOW(f) ((f)->output_data.ns->window_desc)
+
+/* This is the `Display *' which frame F is on.  */
+#define FRAME_NS_DISPLAY(f) (0)
+#define FRAME_X_DISPLAY(f) (0)
+
+#define FRAME_FOREGROUND_COLOR(f) ((f)->output_data.ns->foreground_color)
+#define FRAME_BACKGROUND_COLOR(f) ((f)->output_data.ns->background_color)
+
+#define FRAME_X_IMAGE_CACHE(F) FRAME_NS_DISPLAY_INFO ((F))->image_cache
+
+#define NS_FACE_FOREGROUND(f) ((f)->foreground)
+#define NS_FACE_BACKGROUND(f) ((f)->background)
+#define FRAME_NS_TITLEBAR_HEIGHT(f) ((f)->output_data.ns->titlebar_height)
+#define FRAME_NS_TOOLBAR_HEIGHT(f) ((f)->output_data.ns->toolbar_height)
+
+#define FONT_WIDTH(f)	((f)->max_width)
+#define FONT_HEIGHT(f)	((f)->height)
+/*#define FONT_BASE(f)    ((f)->ascent) */
+#define FONT_BASE(f)    (((struct nsfont_info *)f)->max_bounds.ascent)
+/*#define FONT_DESCENT(f) ((f)->descent) */
+#define FONT_DESCENT(f) (((struct nsfont_info *)f)->max_bounds.descent)
+
+#define FRAME_DEFAULT_FACE(f) FACE_FROM_ID (f, DEFAULT_FACE_ID)
+
+#define FRAME_NS_VIEW(f) ((f)->output_data.ns->view)
+#define FRAME_CURSOR(f)  ((f)->output_data.ns->current_cursor)
+#define FRAME_CURSOR_COLOR(f) ((f)->output_data.ns->current_cursor_color)
+#define FRAME_NEW_CURSOR_COLOR(f) ((f)->output_data.ns->desired_cursor_color)
+#define FRAME_NEW_CURSOR(f)  ((f)->output_data.ns->desired_cursor)
+#define FRAME_POINTER_TYPE(f) ((f)->output_data.ns->current_pointer)
+#define FRAME_LAST_INACTIVE(f) ((f)->output_data.ns->last_inactive)
+
+#define FRAME_FONT(f) ((f)->output_data.ns->font)
+
+#ifdef __OBJC__
+#define XNS_SCROLL_BAR(vec) ((id) XSAVE_VALUE (vec)->pointer)
+#else
+#define XNS_SCROLL_BAR(vec) XSAVE_VALUE (vec)->pointer
+#endif
+
+/* Compute pixel size for vertical scroll bars */
+#define NS_SCROLL_BAR_WIDTH(f)                              \
+(FRAME_HAS_VERTICAL_SCROLL_BARS (f)                          \
+ ? rint (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0               \
+        ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f)                 \
+        : (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)))   \
+ : 0)
+
+/* Difference btwn char-column-calculated and actual SB widths.
+   This is only a concern for rendering when SB on left. */
+#define NS_SCROLL_BAR_ADJUST(w, f)		\
+(WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) ?	\
+    (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)	\
+        - NS_SCROLL_BAR_WIDTH (f)) : 0)
+
+/*PENDING: fix for GNUstep inconsistent accounting for titlebar */
+#ifdef NS_IMPL_GNUSTEP
+#define NS_TOP_POS(f) ((f)->top_pos + 18)
+#else
+#define NS_TOP_POS(f) ((f)->top_pos)
+#endif
+
+#define FRAME_NS_FONT_TABLE(f) (FRAME_NS_DISPLAY_INFO (f)->font_table)
+
+#define FRAME_FONTSET(f) ((f)->output_data.ns->fontset)
+
+/* 23 */
+#define FRAME_SMALLEST_CHAR_WIDTH(f)  \
+  (FRAME_NS_DISPLAY_INFO (f)->smallest_char_width)
+#define FRAME_SMALLEST_FONT_HEIGHT(f) \
+  (FRAME_NS_DISPLAY_INFO (f)->smallest_font_height)
+#define FONT_TYPE_FOR_UNIBYTE(font, ch)   0
+#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
+#define FRAME_BASELINE_OFFSET(f) ((f)->output_data.ns->baseline_offset)
+#define BLACK_PIX_DEFAULT(f) 0x000000
+#define WHITE_PIX_DEFAULT(f) 0xFFFFFF
+
+/* First position where characters can be shown (instead of scrollbar, if
+   it is on left. */
+#define FIRST_CHAR_POSITION(f) \
+  (! (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) ? 0 \
+   : FRAME_SCROLL_BAR_COLS (f))
+
+extern struct ns_display_info *ns_term_init ();
+extern void ns_term_shutdown (int sig);
+
+/* constants for text rendering */
+#define NS_DUMPGLYPH_NORMAL             0
+#define NS_DUMPGLYPH_CURSOR             1
+#define NS_DUMPGLYPH_FOREGROUND         2
+#define NS_DUMPGLYPH_MOUSEFACE          3
+
+
+/* In nsfont, called from fontset.c */
+extern void nsfont_make_fontset_for_font (Lisp_Object name,
+                                         Lisp_Object font_object);
+
+/* In nsfont, for debugging */
+struct glyph_string;
+void dump_glyphstring (struct glyph_string *s);
+
+/* Implemented in nsterm, published in or needed from nsfns. */
+extern Lisp_Object Qfontsize;
+extern Lisp_Object ns_list_fonts (FRAME_PTR f, Lisp_Object pattern,
+                                  int size, int maxnames);
+extern void ns_clear_frame (struct frame *f);
+
+#ifdef __OBJC__
+extern const char *ns_font_to_xlfd (NSFont *font);
+#endif
+extern const char *ns_fontname_to_xlfd (const char *name);
+extern const char *ns_xlfd_to_fontname (const char *xlfd);
+
+extern void check_ns (void);
+extern Lisp_Object ns_map_event_to_object ();
+extern Lisp_Object ns_string_from_pasteboard ();
+extern void ns_string_to_pasteboard ();
+extern void nxatoms_of_nsselect ();
+extern int ns_lisp_to_cursor_type ();
+extern Lisp_Object ns_cursor_type_to_lisp (int arg);
+extern Lisp_Object Qnone;
+
+/* XColor defined in dispextern.h (we use color_def->pixel = NSColor id), but
+   this causes an #include snafu, so we can't declare it.
+    extern int ns_defined_color (struct frame *f, char *name, XColor *color_def,
+                                int alloc); */
+
+#ifdef __OBJC__
+extern int ns_lisp_to_color (Lisp_Object color, NSColor **col);
+extern NSColor *ns_lookup_indexed_color (unsigned long idx, struct frame *f);
+extern unsigned long ns_index_color (NSColor *color, struct frame *f);
+extern void ns_free_indexed_color (unsigned long idx, struct frame *f);
+#endif
+
+/* C access to ObjC functionality */
+extern void  ns_release_object (void *obj);
+extern void  ns_retain_object (void *obj);
+extern void *ns_alloc_autorelease_pool ();
+extern void ns_release_autorelease_pool ();
+
+/* in nsmenu */
+extern void update_frame_tool_bar (FRAME_PTR f);
+extern void free_frame_tool_bar (FRAME_PTR f);
+extern void find_and_call_menu_selection (FRAME_PTR f,
+    EMACS_INT menu_bar_items_used, Lisp_Object vector, void *client_data);
+extern Lisp_Object find_and_return_menu_selection (FRAME_PTR f,
+                                                   int keymaps,
+                                                   void *client_data);
+extern Lisp_Object ns_popup_dialog (Lisp_Object position, Lisp_Object contents,
+                                    Lisp_Object header);
+
+/* two more prototypes that should be moved to a more general include file */
+extern void set_frame_menubar (struct frame *f, int first_time, int deep_p);
+extern void x_set_window_size (struct frame *f, int change_grav,
+                              int cols, int rows);
+
+/* From nsimage.m, needed in image.c */
+struct image;
+extern void *ns_image_from_XBM (unsigned char *bits, int width, int height);
+extern void *ns_image_for_XPM (int width, int height, int depth);
+extern void *ns_image_from_file (Lisp_Object file);
+extern int ns_load_image (struct frame *f, struct image *img,
+                          Lisp_Object spec_file, Lisp_Object spec_data);
+extern int ns_image_width (void *img);
+extern int ns_image_height (void *img);
+extern unsigned long ns_get_pixel (void *img, int x, int y);
+extern void ns_put_pixel (void *img, int x, int y, unsigned long argb);
+extern void ns_set_alpha (void *img, int x, int y, unsigned char a);
+
+/* This in nsterm.m */
+extern unsigned long ns_get_rgb_color (struct frame *f,
+                                       float r, float g, float b, float a);
+extern NSPoint last_mouse_motion_position;
+
+#ifdef NS_IMPL_GNUSTEP
+extern char gnustep_base_version[];  /* version tracking */
+#endif
+
+#define MINWIDTH 10
+#define MINHEIGHT 10
+
+/* Screen max coordinate
+ Using larger coordinates causes movewindow/placewindow to abort */
+#define SCREENMAX 16000
+
+#define NS_SCROLL_BAR_WIDTH_DEFAULT     [EmacsScroller scrollerWidth]
+/* This is to match emacs on other platforms, ugly though it is. */
+#define NS_SELECTION_COLOR_DEFAULT	@"LightGoldenrod2";
+#define RESIZE_HANDLE_SIZE 12
+
+/* Little utility macros */
+#define IN_BOUND(min, x, max) (((x) < (min)) \
+                                ? (min) : (((x)>(max)) ? (max) : (x)))
+#define SCREENMAXBOUND(x) (IN_BOUND (-SCREENMAX, x, SCREENMAX))
+
+/* 23: needed somewhere... */
+#define VERTICAL_SCROLL_BAR_WIDTH_TRIM (0)
+
+
+#endif	/* HAVE_NS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nsterm.m	Tue Jul 15 18:15:18 2008 +0000
@@ -0,0 +1,6598 @@
+/* NeXT/Open/GNUstep / MacOSX communication module.
+   Copyright (C) 1989, 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 (chris@nice.ch)
+OpenStep/Rhapsody port by Scott Bender (sbender@harmony-ds.com)
+MacOSX/Aqua port by Christophe de Dinechin (descubes@earthlink.net)
+GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
+*/
+
+#include <math.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "config.h"
+#include "lisp.h"
+#include "blockinput.h"
+#include "sysselect.h"
+#include "nsterm.h"
+#include "systime.h"
+#include "character.h"
+#include "fontset.h"
+#include "composite.h"
+#include "ccl.h"
+
+#include "termhooks.h"
+#include "termopts.h"
+#include "termchar.h"
+
+#include "window.h"
+#include "keyboard.h"
+
+#include "font.h"
+
+/* call tracing */
+#if 0
+int term_trace_num = 0;
+#define NSTRACE(x)        fprintf (stderr, "%s:%d: [%d] " #x "\n",         \
+                                __FILE__, __LINE__, ++term_trace_num)
+#else
+#define NSTRACE(x)
+#endif
+
+
+/* ==========================================================================
+
+    Local declarations
+
+   ========================================================================== */
+
+/* Special keycodes that we pass down the event chain */
+#define KEY_NS_POWER_OFF               ((1<<28)|(0<<16)|1)
+#define KEY_NS_OPEN_FILE               ((1<<28)|(0<<16)|2)
+#define KEY_NS_OPEN_TEMP_FILE          ((1<<28)|(0<<16)|3)
+#define KEY_NS_DRAG_FILE               ((1<<28)|(0<<16)|4)
+#define KEY_NS_DRAG_COLOR              ((1<<28)|(0<<16)|5)
+#define KEY_NS_DRAG_TEXT               ((1<<28)|(0<<16)|6)
+#define KEY_NS_CHANGE_FONT             ((1<<28)|(0<<16)|7)
+#define KEY_NS_OPEN_FILE_LINE          ((1<<28)|(0<<16)|8)
+#define KEY_NS_INSERT_WORKING_TEXT     ((1<<28)|(0<<16)|9)
+#define KEY_NS_DELETE_WORKING_TEXT     ((1<<28)|(0<<16)|10)
+#define KEY_NS_SPI_SERVICE_CALL        ((1<<28)|(0<<16)|11)
+
+/* Convert a symbol indexed with an NSxxx value to a value as defined
+   in keyboard.c (lispy_function_key). I hope this is a correct way
+   of doing things... */
+static unsigned convert_ns_to_X_keysym[] =
+{
+  NSHomeFunctionKey,            0x50,
+  NSLeftArrowFunctionKey,       0x51,
+  NSUpArrowFunctionKey,         0x52,
+  NSRightArrowFunctionKey,      0x53,
+  NSDownArrowFunctionKey,       0x54,
+  NSPageUpFunctionKey,          0x55,
+  NSPageDownFunctionKey,        0x56,
+  NSEndFunctionKey,             0x57,
+  NSBeginFunctionKey,           0x58,
+  NSSelectFunctionKey,          0x60,
+  NSPrintFunctionKey,           0x61,
+  NSExecuteFunctionKey,         0x62,
+  NSInsertFunctionKey,          0x63,
+  NSUndoFunctionKey,            0x65,
+  NSRedoFunctionKey,            0x66,
+  NSMenuFunctionKey,            0x67,
+  NSFindFunctionKey,            0x68,
+  NSHelpFunctionKey,            0x6A,
+  NSBreakFunctionKey,           0x6B,
+
+  NSF1FunctionKey,              0xBE,
+  NSF2FunctionKey,              0xBF,
+  NSF3FunctionKey,              0xC0,
+  NSF4FunctionKey,              0xC1,
+  NSF5FunctionKey,              0xC2,
+  NSF6FunctionKey,              0xC3,
+  NSF7FunctionKey,              0xC4,
+  NSF8FunctionKey,              0xC5,
+  NSF9FunctionKey,              0xC6,
+  NSF10FunctionKey,             0xC7,
+  NSF11FunctionKey,             0xC8,
+  NSF12FunctionKey,             0xC9,
+  NSF13FunctionKey,             0xCA,
+  NSF14FunctionKey,             0xCB,
+  NSF15FunctionKey,             0xCC,
+
+  NSBackspaceCharacter,         0x08,  /* 8: Not on some KBs. */
+  NSDeleteCharacter,            0xFF,  /* 127: Big 'delete' key upper right. */
+  NSDeleteFunctionKey,          0x9F,  /* 63272: Del forw key off main array. */
+
+  NSTabCharacter,		0x09,
+  0x19,				0x09,  /* left tab->regular since pass shift */
+  NSCarriageReturnCharacter,	0x0D,
+  NSNewlineCharacter,		0x0D,
+  NSEnterCharacter,		0x8D,
+
+  0x1B,				0x1B   /* escape */
+};
+
+
+/* Lisp communications */
+Lisp_Object ns_input_file, ns_input_font, ns_input_fontsize, ns_input_line;
+Lisp_Object ns_input_color, ns_input_text, ns_working_text;
+Lisp_Object ns_input_spi_name, ns_input_spi_arg;
+Lisp_Object Vx_toolkit_scroll_bars;
+static Lisp_Object Qmodifier_value;
+/*PENDING: unsure why these defined in term files, anyway we need in keymap.c */
+Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper;
+extern Lisp_Object Qcursor_color, Qcursor_type, Qns;
+extern int lisp_to_mod (Lisp_Object lmod);
+
+
+EmacsPrefsController *prefsController;
+
+/* Defaults managed through the OpenStep defaults system.  These pertain to
+   the NS interface specifically.  Although a customization group could be
+   created, it's more natural to manage them via defaults. */
+
+/* Specifies which emacs modifier should be generated when NS receives
+   the Alternate modifer.  May be Qnone or any of the modifier lisp symbols. */
+Lisp_Object ns_alternate_modifier;
+
+/* Specifies which emacs modifier should be generated when NS receives
+   the Command modifer.  May be any of the modifier lisp symbols. */
+Lisp_Object ns_command_modifier;
+
+/* Specifies which emacs modifier should be generated when NS receives
+   the Control modifer.  May be any of the modifier lisp symbols. */
+Lisp_Object ns_control_modifier;
+
+/* Specifies which emacs modifier should be generated when NS receives
+   the Function modifer (laptops).  May be any of the modifier lisp symbols. */
+Lisp_Object ns_function_modifier;
+
+/* A floating point value specifying the rate at which to blink the cursor.
+   YES indicates 0.5, NO indicates no blinking. */
+Lisp_Object ns_cursor_blink_rate;
+
+/* Used for liason with core emacs cursor-blink-mode. */
+Lisp_Object ns_cursor_blink_mode;
+
+/* A floating point value specifying vertical stretch (positive) or shrink
+  (negative) of text line spacing.  Zero means default spacing.
+  YES indicates 0.5, NO indicates 0.0. */
+Lisp_Object ns_expand_space;
+
+/* Control via default 'GSFontAntiAlias' on OS X and GNUstep. */
+int ns_antialias_text;
+
+/* On OS X picks up the default NSGlobalDomain AppleAntiAliasingThreshold,
+   the maximum font size to NOT antialias.  On GNUstep there is currently
+   no way to control this behavior. */
+float ns_antialias_threshold;
+
+/* Controls use of an undocumented CG function to do Quickdraw-style font
+   smoothing (less heavy) instead of regular Quartz smoothing. */
+int ns_use_qd_smoothing;
+
+/* Used to pick up AppleHighlightColor on OS X */
+int ns_use_system_highlight_color;
+NSString *ns_selection_color;
+
+
+NSArray *ns_send_types =0, *ns_return_types =0, *ns_drag_types =0;
+
+/* Display variables */
+struct ns_display_info *ns_display_list; /* Chain of existing displays */
+Lisp_Object ns_display_name_list;
+long context_menu_value = 0;
+
+/* display update */
+NSPoint last_mouse_motion_position;
+static NSRect last_mouse_glyph;
+static unsigned long last_mouse_movement_time = 0;
+static Lisp_Object last_mouse_motion_frame;
+static EmacsScroller *last_mouse_scroll_bar = nil;
+static struct frame *ns_updating_frame;
+static NSView *focus_view = NULL;
+static int ns_window_num =0;
+static NSRect uRect;
+static BOOL gsaved = NO;
+BOOL ns_in_resize = NO;
+int ns_tmp_flags; /*PENDING */
+struct nsfont_info *ns_tmp_font; /*PENDING */
+/*static int debug_lock = 0; */
+
+#ifdef NS_IMPL_COCOA
+/* This undocumented Quartz function controls how fonts are anti-aliased.
+   (Found from code in Mac wxWindows impl, discovered by running `nm' on
+   the "QD" framework.)
+   Mode 0 is normal anti-aliasing, mode 1 is no anti-aliasing, and mode 2 is
+   4-bit pixel-aligned anti-aliasing (the old QuickDraw standard). */
+extern void CGContextSetFontRenderingMode (CGContextRef cg, int v);
+#endif
+
+
+/* event loop */
+static BOOL send_appdefined = YES;
+static NSEvent *last_appdefined_event = 0;
+static NSTimer *timed_entry = 0;
+static NSTimer *fd_entry = nil;
+static NSTimer *cursor_blink_entry = nil;
+static NSTimer *scroll_repeat_entry = nil;
+static fd_set select_readfds, t_readfds;
+static struct timeval select_timeout;
+static int select_nfds;
+static NSAutoreleasePool *outerpool;
+static BOOL ns_shutdown_properly = NO;
+static struct input_event *emacs_event = NULL;
+static struct input_event *q_event_ptr = NULL;
+static int n_emacs_events_pending = 0;
+static NSMutableArray *ns_pending_files, *ns_pending_service_names,
+  *ns_pending_service_args;
+static BOOL inNsSelect = 0;
+
+/* Convert modifiers in a NeXTSTEP event to emacs style modifiers.  */
+#define NS_FUNCTION_KEY_MASK 0x800000
+#define EV_MODIFIERS(e)                               \
+    ((([e modifierFlags] & NSHelpKeyMask) ?           \
+           hyper_modifier : 0)                        \
+     | (([e modifierFlags] & NSAlternateKeyMask) ?    \
+           lisp_to_mod (ns_alternate_modifier) : 0)   \
+     | (([e modifierFlags] & NSShiftKeyMask) ?        \
+           shift_modifier : 0)                        \
+     | (([e modifierFlags] & NSControlKeyMask) ?      \
+           lisp_to_mod (ns_control_modifier) : 0)     \
+     | (([e modifierFlags] & NS_FUNCTION_KEY_MASK) ?  \
+           lisp_to_mod (ns_function_modifier) : 0)    \
+     | (([e modifierFlags] & NSCommandKeyMask) ?      \
+           lisp_to_mod (ns_command_modifier):0))
+
+#define EV_UDMODIFIERS(e)                                      \
+    ((([e type] == NSLeftMouseDown) ? down_modifier : 0)       \
+     | (([e type] == NSRightMouseDown) ? down_modifier : 0)    \
+     | (([e type] == NSLeftMouseDragged) ? down_modifier : 0)  \
+     | (([e type] == NSRightMouseDragged) ? down_modifier : 0) \
+     | (([e type] == NSLeftMouseUp)   ? up_modifier   : 0)     \
+     | (([e type] == NSRightMouseUp)   ? up_modifier   : 0))
+
+#define EV_BUTTON(e)                                                         \
+    ((([e type] == NSLeftMouseDown) || ([e type] == NSLeftMouseUp)) ? 0 :    \
+      (([e type] == NSRightMouseDown) || ([e type] == NSRightMouseUp)) ? 2 : 1)
+
+/* Convert the time field to a timestamp in milliseconds. */
+#ifdef NS_IMPL_GNUSTEP
+/* Apple says timestamp is in seconds, but GNUstep seems to be returning msec */
+#define EV_TIMESTAMP(e) ([e timestamp])
+#else
+#define EV_TIMESTAMP(e) ([e timestamp] * 1000)
+#endif /* not gnustep */
+
+/* This is a piece of code which is common to all the event handling
+   methods.  Maybe it should even be a function.  */
+#define EV_TRAILER(e)                                         \
+  {                                                           \
+  XSETFRAME (emacs_event->frame_or_window, [NSApp isActive] ? \
+             emacsframe : SELECTED_FRAME ());                 \
+  if (e) emacs_event->timestamp = EV_TIMESTAMP (e);           \
+  n_emacs_events_pending++;                                   \
+  kbd_buffer_store_event_hold (emacs_event, q_event_ptr);     \
+  EVENT_INIT (*emacs_event);                                  \
+  ns_send_appdefined (-1);                                    \
+  }
+
+/*PENDING: get rid of need for these forward declarations */
+static void ns_condemn_scroll_bars (struct frame *f),
+            ns_judge_scroll_bars (struct frame *f);
+
+/* unused variables needed for compatibility reasons */
+int x_use_underline_position_properties, x_underline_at_descent_line;
+/* PENDING: figure out what to do with underline_minimum_offset. */
+
+
+/* ==========================================================================
+
+    Utilities
+
+   ========================================================================== */
+
+
+static Lisp_Object
+append2 (Lisp_Object list, Lisp_Object item)
+/* --------------------------------------------------------------------------
+   Utility to append to a list
+   -------------------------------------------------------------------------- */
+{
+  Lisp_Object array[2];
+  array[0] = list;
+  array[1] = Fcons (item, Qnil);
+  return Fnconc (2, &array[0]);
+}
+
+
+void
+ns_init_paths ()
+/* --------------------------------------------------------------------------
+   Used to allow emacs to find its resources under Emacs.app
+   Called from emacs.c at startup.
+   -------------------------------------------------------------------------- */
+{
+  NSBundle *bundle = [NSBundle mainBundle];
+  NSString *binDir = [bundle bundlePath], *resourceDir = [bundle resourcePath];
+  NSString *resourcePath, *resourcePaths;
+  NSRange range;
+  BOOL onWindows = NO; /* how do I determine this? */
+  NSString *pathSeparator = onWindows ? @";" : @":";
+  NSFileManager *fileManager = [NSFileManager defaultManager];
+  BOOL isDir;
+/*NSLog (@"ns_init_paths: '%@'\n%@\n", [[NSBundle mainBundle] bundlePath], [[NSBundle mainBundle] resourcePath]); */
+
+  /* get bindir from base */
+  range = [resourceDir rangeOfString: @"Contents"];
+  if (range.location != NSNotFound)
+    {
+      binDir = [binDir stringByAppendingPathComponent: @"Contents"];
+#ifdef NS_IMPL_COCOA
+      binDir = [binDir stringByAppendingPathComponent: @"MacOS"];
+#endif
+    }
+
+  /* the following based on Andrew Choi's init_mac_osx_environment () */
+  if (!getenv ("EMACSLOADPATH"))
+    {
+      NSArray *paths = [resourceDir stringsByAppendingPaths:
+                                  [NSArray arrayWithObjects:
+                                         @"site-lisp", @"lisp", @"leim", nil]];
+      NSEnumerator *pathEnum = [paths objectEnumerator];
+      resourcePaths = @"";
+      while (resourcePath = [pathEnum nextObject])
+        {
+          if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
+            if (isDir)
+              {
+                if ([resourcePaths length] > 0)
+                  resourcePaths =
+                    [resourcePaths stringByAppendingString: pathSeparator];
+                resourcePaths =
+                  [resourcePaths stringByAppendingString: resourcePath];
+              }
+        }
+      if ([resourcePaths length] > 0)
+        setenv ("EMACSLOADPATH", [resourcePaths UTF8String], 1);
+/*NSLog (@"loadPath: '%s'\n", resourcePaths); */
+    }
+
+  if (!getenv ("EMACSPATH"))
+    {
+      NSArray *paths = [binDir stringsByAppendingPaths:
+                                  [NSArray arrayWithObjects: @"bin",
+                                                             @"lib-exec", nil]];
+      NSEnumerator *pathEnum = [paths objectEnumerator];
+      resourcePaths = @"";
+      while (resourcePath = [pathEnum nextObject])
+        {
+          if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
+            if (isDir)
+              {
+                if ([resourcePaths length] > 0)
+                  resourcePaths =
+                    [resourcePaths stringByAppendingString: pathSeparator];
+                resourcePaths =
+                  [resourcePaths stringByAppendingString: resourcePath];
+              }
+        }
+      if ([resourcePaths length] > 0)
+        setenv ("EMACSPATH", [resourcePaths UTF8String], 1);
+    }
+
+  resourcePath = [resourceDir stringByAppendingPathComponent: @"etc"];
+  if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
+    {
+      if (isDir)
+        {
+          if (!getenv ("EMACSDATA"))
+            setenv ("EMACSDATA", [resourcePath UTF8String], 1);
+          if (!getenv ("EMACSDOC"))
+            setenv ("EMACSDOC", [resourcePath UTF8String], 1);
+        }
+    }
+
+  /*PENDING: append to INFOPATH... */
+  if (!getenv ("INFOPATH"))
+    {
+      resourcePath = [resourceDir stringByAppendingPathComponent: @"info"];
+      if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
+        if (isDir)
+          setenv ("INFOPATH", [resourcePath UTF8String], 1);
+    }
+}
+
+
+static int
+timeval_subtract (struct timeval *result, struct timeval x, struct timeval y)
+/* --------------------------------------------------------------------------
+   Subtract the `struct timeval' values X and Y, storing the result in RESULT.
+   Return 1 if the difference is negative, otherwise 0.
+   -------------------------------------------------------------------------- */
+{
+  /* Perform the carry for the later subtraction by updating y.
+     This is safer because on some systems
+     the tv_sec member is unsigned.  */
+  if (x.tv_usec < y.tv_usec)
+    {
+      int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
+      y.tv_usec -= 1000000 * nsec;
+      y.tv_sec += nsec;
+    }
+  if (x.tv_usec - y.tv_usec > 1000000)
+    {
+      int nsec = (y.tv_usec - x.tv_usec) / 1000000;
+      y.tv_usec += 1000000 * nsec;
+      y.tv_sec -= nsec;
+    }
+
+  /* Compute the time remaining to wait.  tv_usec is certainly positive.  */
+  result->tv_sec = x.tv_sec - y.tv_sec;
+  result->tv_usec = x.tv_usec - y.tv_usec;
+
+  /* Return indication of whether the result should be considered negative.  */
+  return x.tv_sec < y.tv_sec;
+}
+
+static void
+ns_timeout (int usecs)
+/* --------------------------------------------------------------------------
+     Blocking timer utility used by ns_ring_bell
+   -------------------------------------------------------------------------- */
+{
+  struct timeval wakeup;
+
+  EMACS_GET_TIME (wakeup);
+
+  /* Compute time to wait until, propagating carry from usecs.  */
+  wakeup.tv_usec += usecs;
+  wakeup.tv_sec += (wakeup.tv_usec / 1000000);
+  wakeup.tv_usec %= 1000000;
+
+  /* Keep waiting until past the time wakeup.  */
+  while (1)
+    {
+      struct timeval timeout;
+
+      EMACS_GET_TIME (timeout);
+
+      /* In effect, timeout = wakeup - timeout.
+	 Break if result would be negative.  */
+      if (timeval_subtract (&timeout, wakeup, timeout))
+	break;
+
+      /* Try to wait that long--but we might wake up sooner.  */
+      select (0, NULL, NULL, NULL, &timeout);
+    }
+}
+
+
+void
+ns_release_object (void *obj)
+/* --------------------------------------------------------------------------
+    Release an object (callable from C)
+   -------------------------------------------------------------------------- */
+{
+    [(id)obj release];
+}
+
+
+void
+ns_retain_object (void *obj)
+/* --------------------------------------------------------------------------
+    Retain an object (callable from C)
+   -------------------------------------------------------------------------- */
+{
+    [(id)obj retain];
+}
+
+
+void *
+ns_alloc_autorelease_pool ()
+/* --------------------------------------------------------------------------
+     Allocate a pool for temporary objects (callable from C)
+   -------------------------------------------------------------------------- */
+{
+  return [[NSAutoreleasePool alloc] init];
+}
+
+
+void
+ns_release_autorelease_pool (void *pool)
+/* --------------------------------------------------------------------------
+     Free a pool and temporary objects it refers to (callable from C)
+   -------------------------------------------------------------------------- */
+{
+  ns_release_object (pool);
+}
+
+
+
+/* ==========================================================================
+
+    Focus (clipping) and screen update
+
+   ========================================================================== */
+
+static NSRect
+ns_resize_handle_rect (NSWindow *window)
+{
+  NSRect r = [window frame];
+  r.origin.x = r.size.width - RESIZE_HANDLE_SIZE;
+  r.origin.y = 0;
+  r.size.width = r.size.height = RESIZE_HANDLE_SIZE;
+  return r;
+}
+
+
+static void
+ns_update_begin (struct frame *f)
+/* --------------------------------------------------------------------------
+   Prepare for a grouped sequence of drawing calls
+   23: external (RIF) call; now split w/ and called before update_window_begin
+   -------------------------------------------------------------------------- */
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  NSTRACE (ns_update_begin);
+/*fprintf (stderr, "\\%p\n", f); */
+
+  ns_updating_frame = f;
+  [view lockFocus];
+
+#ifdef NS_IMPL_GNUSTEP
+  uRect = NSMakeRect (0, 0, 0, 0);
+#endif
+}
+
+
+static void
+ns_update_window_begin (struct window *w)
+/* --------------------------------------------------------------------------
+   Prepare for a grouped sequence of drawing calls
+   23: external (RIF) call; now split with and called after update_begin
+   -------------------------------------------------------------------------- */
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
+  NSTRACE (ns_update_window_begin);
+
+  updated_window = w;
+  set_output_cursor (&w->cursor);
+
+  BLOCK_INPUT;
+
+  if (f == dpyinfo->mouse_face_mouse_frame)
+    {
+      /* Don't do highlighting for mouse motion during the update.  */
+      dpyinfo->mouse_face_defer = 1;
+
+        /* If the frame needs to be redrawn,
+           simply forget about any prior mouse highlighting.  */
+      if (FRAME_GARBAGED_P (f))
+        dpyinfo->mouse_face_window = Qnil;
+
+      /* (further code for mouse faces ifdef'd out in other terms elided) */
+    }
+
+  UNBLOCK_INPUT;
+}
+
+
+static void
+ns_update_window_end (struct window *w, int cursor_on_p,
+                      int mouse_face_overwritten_p)
+/* --------------------------------------------------------------------------
+   Finished a grouped sequence of drawing calls
+   23: external (RIF) call; now split with and called before update_window_end
+   -------------------------------------------------------------------------- */
+{
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (XFRAME (w->frame));
+
+  /* note: this fn is nearly identical in all terms */
+  if (!w->pseudo_window_p)
+    {
+      BLOCK_INPUT;
+
+      if (cursor_on_p)
+	display_and_set_cursor (w, 1,
+                                output_cursor.hpos, output_cursor.vpos,
+				output_cursor.x, output_cursor.y);
+
+      if (draw_window_fringes (w, 1))
+	x_draw_vertical_border (w);
+
+      UNBLOCK_INPUT;
+    }
+
+  /* If a row with mouse-face was overwritten, arrange for
+     frame_up_to_date to redisplay the mouse highlight.  */
+  if (mouse_face_overwritten_p)
+    {
+      dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
+      dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
+      dpyinfo->mouse_face_window = Qnil;
+    }
+
+  updated_window = NULL;
+  NSTRACE (update_window_end);
+}
+
+
+static void
+ns_update_end (struct frame *f)
+/* --------------------------------------------------------------------------
+   Finished a grouped sequence of drawing calls
+   23: external (RIF) call; now split with and called after update_window_end
+   -------------------------------------------------------------------------- */
+{
+  NSView *view = FRAME_NS_VIEW (f);
+
+/*   if (f == FRAME_NS_DISPLAY_INFO (f)->mouse_face_mouse_frame) */
+    FRAME_NS_DISPLAY_INFO (f)->mouse_face_defer = 0;
+
+  BLOCK_INPUT;
+
+#ifdef NS_IMPL_GNUSTEP
+  /* trigger flush only in the rectangle we tracked as being drawn */
+  [view unlockFocusNeedsFlush: NO];
+/*fprintf (stderr, " (%.0f, %.0f : %.0f x %.0f)", uRect.origin.x, uRect.origin.y, uRect.size.width, uRect.size.height); */
+  [view lockFocusInRect: uRect];
+#endif
+
+  [view unlockFocus];
+  [[view window] flushWindow];
+
+  UNBLOCK_INPUT;
+  ns_updating_frame = NULL;
+  NSTRACE (ns_update_end);
+}
+
+
+static void
+ns_flush (struct frame *f)
+/* --------------------------------------------------------------------------
+   23: external (RIF) call
+   NS impl is no-op since currently we flush in ns_update_end and elsewhere
+   -------------------------------------------------------------------------- */
+{
+    NSTRACE (ns_flush);
+}
+
+
+static void
+ns_focus (struct frame *f, NSRect *r, int n)
+/* --------------------------------------------------------------------------
+   Internal: Focus on given frame.  During small local updates this is used to
+     draw, however during large updates, ns_update_begin and ns_update_end are
+     called to wrap the whole thing, in which case these calls are stubbed out.
+     Except, on GNUstep, we accumulate the rectangle being drawn into, because
+     the back end won't do this automatically, and will just end up flushing
+     the entire window.
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (ns_focus);
+#ifdef NS_IMPL_GNUSTEP
+  NSRect u;
+    if (n == 2)
+      u = NSUnionRect (r[0], r[1]);
+    else if (r)
+      u = *r;
+#endif
+/* static int c =0;
+   fprintf (stderr, "focus: %d", c++);
+   if (r) fprintf (stderr, " (%.0f, %.0f : %.0f x %.0f)", r->origin.x, r->origin.y, r->size.width, r->size.height);
+   fprintf (stderr, "\n"); */
+
+  if (f != ns_updating_frame)
+    {
+      NSView *view = FRAME_NS_VIEW (f);
+      if (view != focus_view)
+        {
+          if (focus_view != NULL)
+            {
+              [focus_view unlockFocus];
+              [[focus_view window] flushWindow];
+/*debug_lock--; */
+            }
+
+          if (view)
+#ifdef NS_IMPL_GNUSTEP
+            r ? [view lockFocusInRect: u] : [view lockFocus];
+#else
+            [view lockFocus];
+#endif
+          focus_view = view;
+/*if (view) debug_lock++; */
+        }
+#ifdef NS_IMPL_GNUSTEP
+      else
+        {
+          /* more than one rect being drawn into */
+          if (view && r)
+            {
+              [view unlockFocus]; /* add prev rect to redraw list */
+              [view lockFocusInRect: u]; /* focus for draw in new rect */
+            }
+        }
+#endif
+    }
+#ifdef NS_IMPL_GNUSTEP
+  else
+    {
+      /* in batch mode, but in GNUstep must still track rectangles explicitly */
+      uRect = (r ? NSUnionRect (uRect, u) : [FRAME_NS_VIEW (f) visibleRect]);
+    }
+#endif
+
+  /*23: clipping */
+  if (r)
+    {
+      [[NSGraphicsContext currentContext] saveGraphicsState];
+      if (n == 2)
+        NSRectClipList (r, 2);
+      else
+        NSRectClip (*r);
+      gsaved = YES;
+    }
+}
+
+
+static void
+ns_unfocus (struct frame *f)
+/* --------------------------------------------------------------------------
+     Internal: Remove focus on given frame
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (ns_unfocus);
+
+  if (gsaved)
+    {
+      [[NSGraphicsContext currentContext] restoreGraphicsState];
+      gsaved = NO;
+    }
+
+  if (f != ns_updating_frame)
+    {
+      if (focus_view != NULL)
+        {
+          [focus_view unlockFocus];
+          [[focus_view window] flushWindow];
+          focus_view = NULL;
+/*debug_lock--; */
+        }
+    }
+}
+
+
+static void
+ns_clip_to_row (struct window *w, struct glyph_row *row, int area, GC gc)
+/* --------------------------------------------------------------------------
+     23: Internal (but parallels other terms): Focus drawing on given row
+   -------------------------------------------------------------------------- */
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  NSRect clip_rect;
+  int window_x, window_y, window_width;
+
+  window_box (w, area, &window_x, &window_y, &window_width, 0);
+
+  clip_rect.origin.x = window_x - FRAME_INTERNAL_BORDER_WIDTH (f);
+  clip_rect.origin.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
+  clip_rect.origin.y = max (clip_rect.origin.y, window_y);
+  clip_rect.size.width = window_width + 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
+  clip_rect.size.height = row->visible_height;
+
+  /* allow a full-height row at the top when requested
+     (used to draw fringe all the way through internal border area) */
+  if (gc && clip_rect.origin.y < 5)
+    {
+      clip_rect.origin.y -= FRAME_INTERNAL_BORDER_WIDTH (f);
+      clip_rect.size.height += FRAME_INTERNAL_BORDER_WIDTH (f);
+    }
+
+  /* likewise at bottom */
+  if (gc &&
+      FRAME_PIXEL_HEIGHT (f) - (clip_rect.origin.y + clip_rect.size.height) < 5)
+    clip_rect.size.height += FRAME_INTERNAL_BORDER_WIDTH (f);
+
+  ns_focus (f, &clip_rect, 1);
+}
+
+
+static void
+ns_ring_bell ()
+/* --------------------------------------------------------------------------
+     "Beep" routine
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (ns_ring_bell);
+  if (visible_bell)
+    {
+      NSAutoreleasePool *pool;
+      struct frame *frame = SELECTED_FRAME ();
+      NSView *view;
+
+      BLOCK_INPUT;
+      pool = [[NSAutoreleasePool alloc] init];
+
+      view = FRAME_NS_VIEW (frame);
+      if (view != nil)
+        {
+          NSRect r, surr;
+          NSPoint dim = NSMakePoint (128, 128);
+
+          r = [view bounds];
+          r.origin.x += (r.size.width - dim.x) / 2;
+          r.origin.y += (r.size.height - dim.y) / 2;
+          r.size.width = dim.x;
+          r.size.height = dim.y;
+          /* PENDING: cacheImageInRect under GNUSTEP does not account for
+             offset in x_set_window_size, so overestimate (4 fine on Cocoa) */
+          surr = NSInsetRect (r, -10, -10);
+          ns_focus (frame, &surr, 1);
+          [[view window] cacheImageInRect: surr];
+          [ns_lookup_indexed_color (NS_FACE_FOREGROUND
+                                      (FRAME_DEFAULT_FACE (frame)), frame) set];
+          NSRectFill (r);
+          [[view window] flushWindow];
+          ns_timeout (150000);
+          [[view window] restoreCachedImage];
+          [[view window] flushWindow];
+          ns_unfocus (frame);
+        }
+      [pool release];
+      UNBLOCK_INPUT;
+    }
+  else
+    {
+      NSBeep ();
+    }
+}
+
+
+static void
+ns_reset_terminal_modes (struct terminal *terminal)
+/*  Externally called as hook */
+{
+  NSTRACE (ns_reset_terminal_modes);
+}
+
+static void
+ns_set_terminal_modes (struct terminal *terminal)
+/*  Externally called as hook */
+{
+  NSTRACE (ns_set_terminal_modes);
+}
+
+
+
+/* ==========================================================================
+
+    Frame / window manager related functions
+
+   ========================================================================== */
+
+
+static void
+ns_raise_frame (struct frame *f)
+/* --------------------------------------------------------------------------
+     Bring window to foreground and make it active
+   -------------------------------------------------------------------------- */
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  check_ns ();
+  BLOCK_INPUT;
+  [[view window] makeKeyAndOrderFront: NSApp];
+  UNBLOCK_INPUT;
+}
+
+
+static void
+ns_lower_frame (struct frame *f)
+/* --------------------------------------------------------------------------
+     Send window to back
+   -------------------------------------------------------------------------- */
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  check_ns ();
+  BLOCK_INPUT;
+  [[view window] orderBack: NSApp];
+  UNBLOCK_INPUT;
+}
+
+
+static void
+ns_frame_raise_lower (struct frame *f, int raise)
+/* --------------------------------------------------------------------------
+     External (hook)
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (ns_frame_raise_lower);
+
+  if (raise)
+    ns_raise_frame (f);
+  else
+    ns_lower_frame (f);
+}
+
+
+static void
+ns_frame_rehighlight (struct frame *frame)
+/* --------------------------------------------------------------------------
+     External (hook): called on things like window switching within frame
+   -------------------------------------------------------------------------- */
+{
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame);
+  struct frame *old_highlight = dpyinfo->ns_highlight_frame;
+
+  NSTRACE (ns_frame_rehighlight);
+  if (dpyinfo->ns_focus_frame)
+    {
+      dpyinfo->ns_highlight_frame =
+        (FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->ns_focus_frame))
+           ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->ns_focus_frame))
+           : dpyinfo->ns_focus_frame);
+      if (!FRAME_LIVE_P (dpyinfo->ns_highlight_frame))
+        {
+          FRAME_FOCUS_FRAME (dpyinfo->ns_focus_frame) = Qnil;
+          dpyinfo->ns_highlight_frame = dpyinfo->ns_focus_frame;
+        }
+    }
+  else
+      dpyinfo->ns_highlight_frame = 0;
+
+  if (dpyinfo->ns_highlight_frame &&
+         dpyinfo->ns_highlight_frame != old_highlight)
+    {
+      /* as of 20080602 the lower and raise are superfluous */
+      if (old_highlight)
+        {
+          /*ns_lower_frame (old_highlight); */
+          x_update_cursor (old_highlight, 1);
+        }
+      if (dpyinfo->ns_highlight_frame)
+        {
+          /*ns_raise_frame (dpyinfo->ns_highlight_frame); */
+          x_update_cursor (dpyinfo->ns_highlight_frame, 1);
+        }
+    }
+}
+
+
+void
+x_make_frame_visible (struct frame *f)
+/* --------------------------------------------------------------------------
+     External: Show the window (X11 semantics)
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (x_make_frame_visible);
+  /* PENDING: at some points in past this was not needed, as the only place that
+     called this (frame.c:Fraise_frame ()) also called raise_lower;
+     if this ends up the case again, comment this out again. */
+  if (!FRAME_VISIBLE_P (f))
+    ns_raise_frame (f);
+}
+
+
+void
+x_make_frame_invisible (struct frame *f)
+/* --------------------------------------------------------------------------
+     External: Hide the window (X11 semantics)
+   -------------------------------------------------------------------------- */
+{
+  NSView * view = FRAME_NS_VIEW (f);
+  NSTRACE (x_make_frame_invisible);
+  check_ns ();
+  [[view window] orderOut: NSApp];
+}
+
+
+void
+x_iconify_frame (struct frame *f)
+/* --------------------------------------------------------------------------
+     External: Iconify window
+   -------------------------------------------------------------------------- */
+{
+  NSView * view = FRAME_NS_VIEW (f);
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
+  NSTRACE (x_iconify_frame);
+  check_ns ();
+
+  if (dpyinfo->ns_highlight_frame == f)
+    dpyinfo->ns_highlight_frame = 0;
+
+  if ([[view window] windowNumber] <= 0)
+    {
+      /* the window is still deferred.  Make it very small, bring it
+         on screen and order it out. */
+      NSRect s = { { 100, 100}, {0, 0} };
+      NSRect t;
+      t = [[view window] frame];
+      [[view window] setFrame: s display: NO];
+      [[view window] orderBack: NSApp];
+      [[view window] orderOut: NSApp];
+      [[view window] setFrame: t display: NO];
+    }
+  [[view window] miniaturize: NSApp];
+}
+
+
+void
+x_destroy_window (struct frame *f)
+/* --------------------------------------------------------------------------
+     External: Delete the window
+   -------------------------------------------------------------------------- */
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
+  NSTRACE (x_destroy_window);
+  check_ns ();
+
+  [(EmacsView *)view setWindowClosing: YES]; /* may not have been informed */
+
+  BLOCK_INPUT;
+
+  free_frame_menubar (f);
+
+  if (FRAME_FACE_CACHE (f))
+    free_frame_faces (f);
+
+  if (f == dpyinfo->ns_focus_frame)
+    dpyinfo->ns_focus_frame = 0;
+  if (f == dpyinfo->ns_highlight_frame)
+    dpyinfo->ns_highlight_frame = 0;
+  if (f == dpyinfo->mouse_face_mouse_frame)
+    {
+      dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
+      dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
+      dpyinfo->mouse_face_window = Qnil;
+      dpyinfo->mouse_face_deferred_gc = 0;
+      dpyinfo->mouse_face_mouse_frame = 0;
+    }
+
+  xfree (f->output_data.ns);
+
+  [[view window] close];
+  [view release];
+
+  ns_window_num--;
+  UNBLOCK_INPUT;
+}
+
+
+void
+x_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
+/* --------------------------------------------------------------------------
+     External: Position the window
+   -------------------------------------------------------------------------- */
+{
+  NSScreen *screen;
+  NSView *view = FRAME_NS_VIEW (f);
+
+  NSTRACE (x_set_offset);
+
+  BLOCK_INPUT;
+
+  f->left_pos = xoff;
+  f->top_pos = yoff;
+#ifdef NS_IMPL_GNUSTEP
+  if (xoff < 100)
+    f->left_pos = 100;  /* don't overlap menu */
+#endif
+  if (view != nil && (screen = [[view window] screen]))
+    [[view window] setFrameTopLeftPoint:
+        NSMakePoint (SCREENMAXBOUND (f->left_pos),
+                     SCREENMAXBOUND ([screen frame].size.height
+                                     - NS_TOP_POS (f)))];
+  UNBLOCK_INPUT;
+}
+
+
+void
+x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
+/* --------------------------------------------------------------------------
+     Adjust window pixel size based on given character grid size
+     Impl is a bit more complex than other terms, need to do some
+     internal clipping and also pay attention to screen constraints.
+   -------------------------------------------------------------------------- */
+{
+  EmacsView *view = FRAME_NS_VIEW (f);
+  EmacsToolbar *toolbar = [view toolbar];
+  NSWindow *window = [view window];
+  NSScreen *screen = [window screen];
+  NSRect wr = [window frame];
+  int tb = FRAME_EXTERNAL_TOOL_BAR (f);
+  int pixelwidth, pixelheight;
+  static int oldRows, oldCols, oldFontWidth, oldFontHeight;
+  static int oldTB;
+  static struct frame *oldF;
+
+  NSTRACE (x_set_window_size);
+
+  if (view == nil ||
+      (f == oldF
+       && rows == oldRows && cols == oldCols
+       && oldFontWidth == FRAME_COLUMN_WIDTH (f)
+       && oldFontHeight == FRAME_LINE_HEIGHT (f)
+       && oldTB == tb))
+    return;
+
+/*fprintf (stderr, "\tsetWindowSize: %d x %d, font size %d x %d\n", cols, rows, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f)); */
+
+  BLOCK_INPUT;
+
+  check_frame_size (f, &rows, &cols);
+  oldF = f;
+  oldRows = rows;
+  oldCols = cols;
+  oldFontWidth = FRAME_COLUMN_WIDTH (f);
+  oldFontHeight = FRAME_LINE_HEIGHT (f);
+  oldTB = tb;
+
+  f->scroll_bar_actual_width = NS_SCROLL_BAR_WIDTH (f);
+  compute_fringe_widths (f, 0);
+
+  pixelwidth =  FRAME_TEXT_COLS_TO_PIXEL_WIDTH   (f, cols);
+  pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+  
+  /* If we have a change in toolbar display, calculate height */
+  if (tb)
+    /* PENDING: GNUstep has not yet implemented the first method below, added
+                in Panther, however the second is incorrect under Cocoa. */
+#ifdef NS_IMPL_GNUSTEP
+    FRAME_NS_TOOLBAR_HEIGHT (f) =
+      NSHeight ([NSWindow frameRectForContentRect: NSMakeRect (0, 0, 0, 0)
+                                       styleMask: [window styleMask]])
+          - FRAME_NS_TITLEBAR_HEIGHT (f);
+#else
+    FRAME_NS_TOOLBAR_HEIGHT (f) = 32;
+      /* actually get wrong result here if toolbar not yet displayed
+         NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)])
+         - FRAME_NS_TITLEBAR_HEIGHT (f); */
+#endif
+  else
+    FRAME_NS_TOOLBAR_HEIGHT (f) = 0;
+
+  wr.size.width = pixelwidth + f->border_width;
+  wr.size.height = pixelheight + FRAME_NS_TITLEBAR_HEIGHT (f) 
+                  + FRAME_NS_TOOLBAR_HEIGHT (f);
+
+  /* constrain to screen if we can */
+  if (screen)
+    {
+      NSSize sz = [screen visibleFrame].size;
+      NSSize ez = { wr.size.width - sz.width, wr.size.height - sz.height };
+      if (ez.width > 0)
+        {
+          int cr = ez.width / FRAME_COLUMN_WIDTH (f) + 1;
+          cols -= cr;
+          oldCols = cols;
+          wr.size.width -= cr * FRAME_COLUMN_WIDTH (f);
+          pixelwidth -= cr * FRAME_COLUMN_WIDTH (f);
+        }
+      if (ez.height > 0)
+        {
+          int rr = ez.height / FRAME_LINE_HEIGHT (f) + 1;
+          rows -= rr;
+          oldRows = rows;
+          wr.size.height -= rr * FRAME_LINE_HEIGHT (f);
+          pixelheight -= rr * FRAME_LINE_HEIGHT (f);
+        }
+      wr.origin.x = f->left_pos;
+      wr.origin.y = [screen frame].size.height - NS_TOP_POS (f)
+        - wr.size.height;
+    }
+
+  [view setRows: rows andColumns: cols];
+  [window setFrame: wr display: YES];
+
+/*fprintf (stderr, "\tx_set_window_size %d, %d\t%d, %d\n", cols, rows, pixelwidth, pixelheight); */
+
+  /* This is a trick to compensate for Emacs' managing the scrollbar area
+     as a fixed number of standard character columns.  Instead of leaving
+     blank space for the extra, we chopped it off above.  Now for
+     left-hand scrollbars, we shift all rendering to the left by the
+     difference between the real width and Emacs' imagined one.  For
+     right-hand bars, don't worry about it since the extra is never used.
+     (Obviously doesn't work for vertically split windows tho..) */
+  NSPoint origin = FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)
+    ? NSMakePoint (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)
+                  - NS_SCROLL_BAR_WIDTH (f), 0)
+    : NSMakePoint (0, 0);
+  [view setFrame: NSMakeRect (0, 0, pixelwidth, pixelheight)];
+  [view setBoundsOrigin: origin];
+
+  change_frame_size (f, rows, cols, 0, 1, 0); /* pretend, delay, safe */
+  FRAME_PIXEL_WIDTH (f) = pixelwidth;
+  FRAME_PIXEL_HEIGHT (f) = pixelheight;
+/*  SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */
+
+  mark_window_cursors_off (XWINDOW (f->root_window));
+  cancel_mouse_face (f);
+
+  UNBLOCK_INPUT;
+}
+
+
+/* ==========================================================================
+
+    Color management
+
+   ========================================================================== */
+
+NSColor *
+ns_lookup_indexed_color (unsigned long idx, struct frame *f)
+{
+  struct ns_color_table *color_table = FRAME_NS_DISPLAY_INFO (f)->color_table;
+  return color_table->colors[idx];
+}
+
+
+unsigned long
+ns_index_color (NSColor *color, struct frame *f)
+{
+  struct ns_color_table *color_table = FRAME_NS_DISPLAY_INFO (f)->color_table;
+  int idx;
+  NSNumber *index;
+
+  if (!color_table->colors)
+    {
+      color_table->size = NS_COLOR_CAPACITY;
+      color_table->avail = 1; /* skip idx=0 as marker */
+      color_table->colors =
+        (NSColor **)xmalloc (color_table->size * sizeof (NSColor *));
+      color_table->empty_indices = [[NSMutableSet alloc] init];
+    }
+
+  /* do we already have this color ? */
+  {
+    int i;
+    for (i = 1; i < color_table->avail; i++)
+      {
+        if (color_table->colors[i] && [color_table->colors[i] isEqual: color])
+          {
+            [color_table->colors[i] retain];
+            return i;
+          }
+      }
+  }
+
+  if ([color_table->empty_indices count] > 0)
+    {
+      index = [color_table->empty_indices anyObject];
+      [color_table->empty_indices removeObject: index];
+      idx = [index unsignedIntValue];
+    }
+  else
+    {
+      if (color_table->avail == color_table->size)
+        {
+          color_table->size += NS_COLOR_CAPACITY;
+          color_table->colors = 
+            (NSColor **)xrealloc (color_table->colors,
+                                  color_table->size * sizeof (NSColor *));
+        }
+      idx = color_table->avail++;
+      index = [NSNumber numberWithUnsignedInt: idx];
+    }
+
+  color_table->colors[idx] = color;
+  [color retain];
+/*fprintf(stderr, "color_table: allocated %d\n",idx);*/
+  return idx;
+}
+
+
+void
+ns_free_indexed_color (unsigned long idx, struct frame *f)
+{
+  struct ns_color_table *color_table = FRAME_NS_DISPLAY_INFO (f)->color_table;
+  NSColor *color;
+  if (!idx)
+    return;
+  color = color_table->colors[idx];
+  [color release];
+  color_table->colors[idx] = nil;
+  [color_table->empty_indices addObject: [NSNumber numberWithUnsignedInt: idx]];
+/*fprintf(stderr, "color_table: FREED %d\n",idx);*/
+}
+
+
+static int
+ns_get_color (const char *name, NSColor **col)
+/* --------------------------------------------------------------------------
+     Parse a color name
+/* --------------------------------------------------------------------------
+/* On *Step, we recognize several color formats, in addition to a catalog
+   of colors found in the file Emacs.clr. Color formats include:
+   - #rrggbb or RGBrrggbb where rr, gg, bb specify red, green and blue in hex
+   - ARGBaarrggbb is similar, with aa being the alpha channel (FF = opaque)
+   - HSVhhssvv and AHSVaahhssvv are similar for hue, saturation, value
+   - CMYKccmmyykk is similar for cyan, magenta, yellow, black. */
+{
+  NSColor * new = nil;
+  const char *hex = NULL;
+  enum { rgb, argb, hsv, ahsv, cmyk, gray } color_space;
+  NSString *nsname = [NSString stringWithUTF8String: name];
+
+/*fprintf (stderr, "ns_get_color: '%s'\n", name); */
+  BLOCK_INPUT;
+
+  if ([nsname isEqualToString: @"ns_selection_color"])
+    {
+      nsname = ns_selection_color;
+      name = [ns_selection_color UTF8String];
+    }
+
+  if (name[0] == '0' || name[0] == '1' || name[0] == '.')
+    {
+      /* RGB decimal */
+      NSScanner *scanner = [NSScanner scannerWithString: nsname];
+      float r, g, b;
+      [scanner scanFloat: &r];
+      [scanner scanFloat: &g];
+      [scanner scanFloat: &b];
+      *col = [NSColor colorWithCalibratedRed: r green: g blue: b alpha: 1.0];
+      UNBLOCK_INPUT;
+      return 0;
+    }
+
+  /* 23: PENDING: emacs seems to downcase everything before passing it here,
+     which we can work around, except for GRAY, since gray##, where ## is
+     decimal between 0 and 99, is also an X11 colorname. */
+  if (name[0] == '#')             /* X11 format */
+    {
+      hex = name + 1;
+      color_space = rgb;
+    }
+  else if (!memcmp (name, "RGB", 3) || !memcmp (name, "rgb", 3))
+    {
+      hex = name + 3;
+      color_space = rgb;
+    }
+  else if (!memcmp (name, "ARGB", 4) || !memcmp (name, "argb", 4))
+    {
+      hex = name + 4;
+      color_space = argb;
+    }
+  else if (!memcmp (name, "HSV", 3) || !memcmp (name, "hsv", 3))
+    {
+      hex = name + 3;
+      color_space = hsv;
+    }
+  else if (!memcmp (name, "AHSV", 4) || !memcmp (name, "ahsv", 4))
+    {
+      hex = name + 4;
+      color_space = ahsv;
+    }
+  else if (!memcmp (name, "CMYK", 4) || !memcmp (name, "cmyk", 4))
+    {
+      hex = name + 4;
+      color_space = cmyk;
+    }
+  else if (!memcmp (name, "GRAY", 4) /*|| !memcmp (name, "gray", 4)*/)
+    {
+      hex = name + 4;
+      color_space = gray;
+    }
+
+  /* Direct colors (hex values) */
+  if (hex)
+    {
+      unsigned int color = 0;
+      if (sscanf (hex, "%x", &color))
+        {
+          float f1 = ((color >> 24) & 0xff) / 255.0;
+          float f2 = ((color >> 16) & 0xff) / 255.0;
+          float f3 = ((color >>  8) & 0xff) / 255.0;
+          float f4 = ((color      ) & 0xff) / 255.0;
+
+          switch (color_space)
+            {
+            case rgb:
+              *col = [NSColor colorWithCalibratedRed: f2
+                                               green: f3
+                                                blue: f4
+                                               alpha: 1.0];
+              break;
+            case argb:
+              *col = [NSColor colorWithCalibratedRed: f2
+                                               green: f3
+                                                blue: f4
+                                               alpha: f1];
+              break;
+            case hsv:
+              *col = [NSColor colorWithCalibratedHue: f2
+                                          saturation: f3
+                                          brightness: f4
+                                               alpha: 1.0];
+              break;
+            case ahsv:
+              *col = [NSColor colorWithCalibratedHue: f2
+                                          saturation: f3
+                                          brightness: f4
+                                               alpha: f1];
+              break;
+            case gray:
+              *col = [NSColor colorWithCalibratedWhite: f3 alpha: f4];
+              break;
+            case cmyk:
+              *col = [NSColor colorWithDeviceCyan: f1
+                                          magenta: f2
+                                           yellow: f3
+                                            black: f4
+                                            alpha: 1.0];
+              break;
+            }
+          *col = [*col colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
+          UNBLOCK_INPUT;
+          return 0;
+        }
+    }
+
+  /* Otherwise, color is expected to be from a list */
+  {
+    NSEnumerator *lenum, *cenum;
+    NSString *name;
+    NSColorList *clist;
+#ifdef NS_IMPL_GNUSTEP
+    /* PENDING: who is wrong, the requestor or the implementation? */
+    if ([nsname compare: @"Highlight" options: NSCaseInsensitiveSearch]
+        == NSOrderedSame)
+      nsname = @"highlightColor";
+#endif
+    if ([nsname compare: @"dark blue" options: NSCaseInsensitiveSearch]
+        == NSOrderedSame
+      || [nsname compare: @"darkblue" options: NSCaseInsensitiveSearch]
+        == NSOrderedSame)
+      nsname = @"navy blue";
+
+    lenum = [[NSColorList availableColorLists] objectEnumerator];
+    while ( (clist = [lenum nextObject]) && new == nil)
+      {
+        cenum = [[clist allKeys] objectEnumerator];
+        while ( (name = [cenum nextObject]) && new == nil )
+          {
+            if ([name compare: nsname
+                      options: NSCaseInsensitiveSearch] == NSOrderedSame )
+              new = [clist colorWithKey: name];
+          }
+      }
+  }
+
+  if ( new )
+    *col = [new colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
+/*     else
+       NSLog (@"Failed to find color '%@'", nsname); */
+  UNBLOCK_INPUT;
+  return new ? 0 : 1;
+}
+
+
+static NSColor *
+ns_get_color_default (const char *name, NSColor *dflt)
+/* --------------------------------------------------------------------------
+     Parse a color or use a default value
+   -------------------------------------------------------------------------- */
+{
+  NSColor * col;
+
+  if (ns_get_color (name, &col))
+    return dflt;
+  else
+    return col;
+}
+
+
+int
+ns_lisp_to_color (Lisp_Object color, NSColor **col)
+/* --------------------------------------------------------------------------
+     Convert a Lisp string object to a NS color
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (ns_lisp_to_color);
+  if (XTYPE (color) == Lisp_String)
+    return ns_get_color (XSTRING (color)->data, col);
+  else if (XTYPE (color) == Lisp_Symbol)
+    return ns_get_color (XSTRING (XSYMBOL (color)->xname)->data, col);
+  return 1;
+}
+
+
+Lisp_Object
+ns_color_to_lisp (NSColor *col)
+/* --------------------------------------------------------------------------
+     Convert a color to a lisp string with the RGB equivalent
+   -------------------------------------------------------------------------- */
+{
+  float red, green, blue, alpha, gray;
+  char buf[1024];
+  const char *str;
+  NSTRACE (ns_color_to_lisp);
+
+  BLOCK_INPUT;
+  if ([[col colorSpaceName] isEqualToString: NSNamedColorSpace])
+
+      if ((str =[[col colorNameComponent] UTF8String]))
+        {
+          UNBLOCK_INPUT;
+          return build_string ((char *)str);
+        }
+
+    [[col colorUsingColorSpaceName: NSCalibratedRGBColorSpace]
+        getRed: &red green: &green blue: &blue alpha: &alpha];
+  if (red ==green && red ==blue)
+    {
+      [[col colorUsingColorSpaceName: NSCalibratedWhiteColorSpace]
+            getWhite: &gray alpha: &alpha];
+      snprintf (buf, sizeof (buf), "GRAY%02.2lx%02.2lx",
+               lrint (gray * 0xff), lrint (alpha * 0xff));
+      UNBLOCK_INPUT;
+      return build_string (buf);
+    }
+
+  snprintf (buf, sizeof (buf), "ARGB%02.2lx%02.2lx%02.2lx%02.2lx",
+            lrint (alpha*0xff),
+            lrint (red*0xff), lrint (green*0xff), lrint (blue*0xff));
+
+  UNBLOCK_INPUT;
+  return build_string (buf);
+}
+
+
+int
+ns_defined_color (struct frame *f, char *name, XColor *color_def, int alloc,
+                  char makeIndex)
+/* --------------------------------------------------------------------------
+   23:   Return 1 if named color found, and set color_def rgb accordingly.
+         If makeIndex and alloc are nonzero put the color in the color_table,
+         and set color_def pixel to the resulting index.
+         If makeIndex is zero, set color_def pixel to ARGB.
+         Return 0 if not found
+   -------------------------------------------------------------------------- */
+{
+  NSColor *temp;
+  float r, g, b, a;
+  int notFound = ns_get_color (name, &temp);
+
+  NSTRACE (ns_defined_color);
+
+  if (notFound)
+    return 0;
+
+  if (makeIndex && alloc)
+      color_def->pixel = ns_index_color(temp, f);//[temp retain];
+
+  [temp getRed: &r green: &g blue: &b alpha: &a];
+  color_def->red   = r * 256;
+  color_def->green = g * 256;
+  color_def->blue  = b * 256;
+
+  if (!makeIndex)
+    color_def->pixel =
+      ARGB_TO_ULONG((int)(a*256),
+                    color_def->red, color_def->green, color_def->blue);
+
+  return 1;
+}
+
+
+unsigned long
+ns_get_rgb_color (struct frame *f, float r, float g, float b, float a)
+/* --------------------------------------------------------------------------
+    return an autoreleased RGB color
+   -------------------------------------------------------------------------- */
+{
+/*static int c = 1; fprintf (stderr, "color request %d\n", c++); */
+  if (r < 0.0) r = 0.0;
+  else if (r > 1.0) r = 1.0;
+  if (g < 0.0) g = 0.0;
+  else if (g > 1.0) g = 1.0;
+  if (b < 0.0) b = 0.0;
+  else if (b > 1.0) b = 1.0;
+  if (a < 0.0) a = 0.0;
+  else if (a > 1.0) a = 1.0;
+  return (unsigned long) ns_index_color(
+    [NSColor colorWithCalibratedRed: r green: g blue: b alpha: a], f);
+}
+
+
+
+/* ==========================================================================
+
+    Mouse handling
+
+   ========================================================================== */
+
+
+void
+x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
+/* --------------------------------------------------------------------------
+     Programmatically reposition mouse pointer in pixel coordinates
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (x_set_mouse_pixel_position);
+  ns_raise_frame (f);
+#if 0
+  /*PENDING: this does not work, and what about GNUstep? */
+#ifdef NS_IMPL_COCOA
+  [FRAME_NS_VIEW (f) lockFocus];
+  PSsetmouse ((float)pix_x, (float)pix_y);
+  [FRAME_NS_VIEW (f) unlockFocus];
+#endif
+#endif
+}
+
+
+void
+x_set_mouse_position (struct frame *f, int h, int v)
+/* --------------------------------------------------------------------------
+     Programmatically reposition mouse pointer in character coordinates
+   -------------------------------------------------------------------------- */
+{
+  int pix_x, pix_y;
+
+  pix_x = FRAME_COL_TO_PIXEL_X (f, h) + FRAME_COLUMN_WIDTH (f) / 2;
+  pix_y = FRAME_LINE_TO_PIXEL_Y (f, v) + FRAME_LINE_HEIGHT (f) / 2;
+
+  if (pix_x < 0) pix_x = 0;
+  if (pix_x > FRAME_PIXEL_WIDTH (f)) pix_x = FRAME_PIXEL_WIDTH (f);
+
+  if (pix_y < 0) pix_y = 0;
+  if (pix_y > FRAME_PIXEL_HEIGHT (f)) pix_y = FRAME_PIXEL_HEIGHT (f);
+
+  x_set_mouse_pixel_position (f, pix_x, pix_y);
+}
+
+
+static int
+note_mouse_movement (struct frame *frame, float x, float y)
+/*   ------------------------------------------------------------------------
+     Called by EmacsView on mouseMovement events.  Passes on
+     to emacs mainstream code if we moved off of a rect of interest
+     known as last_mouse_glyph.
+     ------------------------------------------------------------------------ */
+{
+  NSTRACE (note_mouse_movement);
+
+  XSETFRAME (last_mouse_motion_frame, frame);
+  
+  /* Note, this doesn't get called for enter/leave, since we don't have a
+     position.  Those are taken care of in the corresponding NSView methods. */
+
+  /* has movement gone beyond last rect we were tracking? */
+  if (x < last_mouse_glyph.origin.x ||
+      x >= (last_mouse_glyph.origin.x + last_mouse_glyph.size.width) ||
+      y < last_mouse_glyph.origin.y ||
+      y >= (last_mouse_glyph.origin.y + last_mouse_glyph.size.height))
+    {
+      frame->mouse_moved = 1;
+      note_mouse_highlight (frame, x, y);
+      remember_mouse_glyph (frame, x, y, &last_mouse_glyph);
+      return 1;
+    }
+
+  return 0;
+}
+
+
+static void
+ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
+                   enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
+                   unsigned long *time)
+/* --------------------------------------------------------------------------
+    External (hook): inform emacs about mouse position and hit parts.
+    If a scrollbar is being dragged, set bar_window, part, x, y, time.
+    x & y should be position in the scrollbar (the whole bar, not the handle)
+    and length of scrollbar respectively
+   -------------------------------------------------------------------------- */
+{
+  id view;
+  NSPoint position;
+  int xchar, ychar;
+  Lisp_Object frame, tail;
+  struct frame *f;
+  struct ns_display_info *dpyinfo;
+
+  NSTRACE (ns_mouse_position);
+
+  if (*fp == NULL)
+    {
+      fprintf (stderr, "Warning: ns_mouse_position () called with null *fp.\n");
+      return;
+    }
+
+  dpyinfo = FRAME_NS_DISPLAY_INFO (*fp);
+
+  BLOCK_INPUT;
+
+  if (last_mouse_scroll_bar != nil && insist == 0)
+    {
+      /* PENDING: we do not use this path at the moment because drag events will
+         go directly to the EmacsScroller.  Leaving code in for now. */
+      [last_mouse_scroll_bar getMouseMotionPart: (int *)part window: bar_window
+                                              x: x y: y];
+      if (time) *time = last_mouse_movement_time;
+      last_mouse_scroll_bar = nil;
+    }
+  else
+    {
+      /* Clear the mouse-moved flag for every frame on this display.  */
+      FOR_EACH_FRAME (tail, frame)
+        if (FRAME_NS_P (XFRAME (frame))
+            && FRAME_NS_DISPLAY (XFRAME (frame)) == FRAME_NS_DISPLAY (*fp))
+          XFRAME (frame)->mouse_moved = 0;
+
+      last_mouse_scroll_bar = nil;
+      if (last_mouse_frame && FRAME_LIVE_P (last_mouse_frame))
+        f = last_mouse_frame;
+      else
+        f = dpyinfo->ns_focus_frame ? dpyinfo->ns_focus_frame
+                                    : SELECTED_FRAME ();
+
+      if (f && f->output_data.ns)  /*PENDING: 2nd check no longer needed? */
+        {
+          view = FRAME_NS_VIEW (*fp);
+
+          position = [[view window] mouseLocationOutsideOfEventStream];
+          position = [view convertPoint: position fromView: nil];
+          remember_mouse_glyph (f, position.x, position.y, &last_mouse_glyph);
+/*fprintf (stderr, "ns_mouse_position: %.0f, %.0f\n", position.x, position.y); */
+
+          if (bar_window) *bar_window = Qnil;
+          if (part) *part = 0; /*scroll_bar_handle; */
+
+          if (x) XSETINT (*x, lrint (position.x));
+          if (y) XSETINT (*y, lrint (position.y));
+          if (time) *time = last_mouse_movement_time;
+          *fp = f;
+        }
+    }
+
+  UNBLOCK_INPUT;
+}
+
+
+static void
+ns_frame_up_to_date (struct frame *f)
+/* --------------------------------------------------------------------------
+    External (hook): Fix up mouse highlighting right after a full update.
+    Some highlighting was deferred if GC was happening during
+    note_mouse_highlight (), while other highlighting was deferred for update.
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (ns_frame_up_to_date);
+
+  if (FRAME_NS_P (f))
+    {
+      struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
+      if ((dpyinfo->mouse_face_deferred_gc||f ==dpyinfo->mouse_face_mouse_frame)
+      /*&& dpyinfo->mouse_face_mouse_frame*/)
+        {
+          BLOCK_INPUT;
+          if (dpyinfo->mouse_face_mouse_frame)
+            note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
+                                  dpyinfo->mouse_face_mouse_x,
+                                  dpyinfo->mouse_face_mouse_y);
+          dpyinfo->mouse_face_deferred_gc = 0;
+          UNBLOCK_INPUT;
+        }
+    }
+}
+
+
+void
+ns_define_frame_cursor (struct frame *f, Cursor cursor)
+/* --------------------------------------------------------------------------
+    External (RIF): set frame mouse pointer type.
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (ns_define_frame_cursor);
+  if (FRAME_POINTER_TYPE (f) != cursor)
+    {
+      EmacsView *view = FRAME_NS_VIEW (f);
+      FRAME_POINTER_TYPE (f) = cursor;
+      [[view window] invalidateCursorRectsForView: view];
+    }
+}
+
+
+
+/* ==========================================================================
+
+    Keyboard handling
+
+   ========================================================================== */
+
+
+static unsigned
+ns_convert_key (unsigned code)
+/* --------------------------------------------------------------------------
+    Internal call used by NSView-keyDown.
+   -------------------------------------------------------------------------- */
+{
+  const unsigned last_keysym = (sizeof (convert_ns_to_X_keysym)
+                                / sizeof (convert_ns_to_X_keysym[0]));
+  unsigned keysym;
+  /* An array would be faster, but less easy to read. */
+  for (keysym = 0; keysym < last_keysym; keysym += 2)
+    if (code == convert_ns_to_X_keysym[keysym])
+      return 0xFF00 | convert_ns_to_X_keysym[keysym+1];
+  return 0;
+/* if decide to use keyCode and Carbon table, use this line:
+     return code > 0xff ? 0 : 0xFF00 | ns_keycode_to_xkeysym_table[code]; */
+}
+
+
+char *
+x_get_keysym_name (int keysym)
+/* --------------------------------------------------------------------------
+    Called by keyboard.c.  Not sure if the return val is important, except
+    that it be unique.
+   -------------------------------------------------------------------------- */
+{
+  static char value[16];
+  NSTRACE (x_get_keysym_name);
+  sprintf (value, "%d", keysym);
+  return value;
+}
+
+
+
+/* ==========================================================================
+
+    Block drawing operations
+
+   ========================================================================== */
+
+
+static void
+ns_redraw_scroll_bars (struct frame *f)
+{
+  int i;
+  id view;
+  NSArray *subviews = [[FRAME_NS_VIEW (f) superview] subviews];
+  NSTRACE (ns_judge_scroll_bars);
+  for (i =[subviews count]-1; i >= 0; i--)
+    {
+      view = [subviews objectAtIndex: i];
+      if (![view isKindOfClass: [EmacsScroller class]]) continue;
+      [view display];
+    }
+}
+
+
+void
+ns_clear_frame (struct frame *f)
+/* --------------------------------------------------------------------------
+      External (hook): Erase the entire frame
+   -------------------------------------------------------------------------- */
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  NSRect r;
+
+  NSTRACE (ns_clear_frame);
+  if (ns_in_resize)
+    return;
+
+ /* comes on initial frame because we have
+    after-make-frame-functions = select-frame */
+ if (!FRAME_DEFAULT_FACE (f))
+   return;
+
+  mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
+
+  output_cursor.hpos = output_cursor.vpos = 0;
+  output_cursor.x = -1;
+
+  r = [view bounds];
+
+  BLOCK_INPUT;
+  ns_focus (f, &r, 1);
+  [ns_lookup_indexed_color (NS_FACE_BACKGROUND (FRAME_DEFAULT_FACE (f)), f) set];
+  NSRectFill (r);
+  ns_unfocus (f);
+
+#ifdef NS_IMPL_COCOA
+  [[view window] display];  /* redraw resize handle */
+#endif
+
+  /* as of 2006/11 or so this is now needed */
+  ns_redraw_scroll_bars (f);
+  UNBLOCK_INPUT;
+}
+
+
+void
+ns_clear_frame_area (struct frame *f, int x, int y, int width, int height)
+/* --------------------------------------------------------------------------
+   23: External (RIF):  Clear section of frame
+   -------------------------------------------------------------------------- */
+{
+  NSRect r = NSMakeRect (x, y, width, height);
+  NSView *view = FRAME_NS_VIEW (f);
+  struct face *face = FRAME_DEFAULT_FACE (f);
+
+  if (!view || !face)
+    return;
+
+  r = NSIntersectionRect (r, [view frame]);
+  ns_focus (f, &r, 1);
+  [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
+
+#ifdef NS_IMPL_COCOA
+  {
+    /* clip out the resize handle */
+    NSWindow *window = [FRAME_NS_VIEW (f) window];
+    NSRect ir =
+      [view convertRect: ns_resize_handle_rect (window) fromView: nil];
+
+    ir = NSIntersectionRect (r, ir);
+    if (NSIsEmptyRect (ir))
+      {
+#endif
+
+  NSRectFill (r);
+
+#ifdef NS_IMPL_COCOA
+      }
+    else
+      {
+        NSRect r1 = r, r2 = r; /* upper and lower non-intersecting */
+        r1.size.height -= ir.size.height;
+        r2.origin.y += r1.size.height;
+        r2.size.width -= ir.size.width;
+        r2.size.height = ir.size.height;
+        NSRectFill (r1);
+        NSRectFill (r2);
+      }
+  }
+#endif
+
+  ns_unfocus (f);
+  return;
+}
+
+
+static void
+ns_scroll_run (struct window *w, struct run *run)
+/* --------------------------------------------------------------------------
+   23: External (RIF):  Insert or delete n lines at line vpos
+   -------------------------------------------------------------------------- */
+{
+  struct frame *f = XFRAME (w->frame);
+  int x, y, width, height, from_y, to_y, bottom_y;
+
+  NSTRACE (ns_scroll_run);
+
+  /* begin copy from other terms */
+  /* Get frame-relative bounding box of the text display area of W,
+     without mode lines.  Include in this box the left and right
+     fringe of W.  */
+  window_box (w, -1, &x, &y, &width, &height);
+
+  from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
+  to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
+  bottom_y = y + height;
+
+  if (to_y < from_y)
+    {
+      /* Scrolling up.  Make sure we don't copy part of the mode
+	 line at the bottom.  */
+      if (from_y + run->height > bottom_y)
+	height = bottom_y - from_y;
+      else
+	height = run->height;
+    }
+  else
+    {
+      /* Scolling down.  Make sure we don't copy over the mode line.
+	 at the bottom.  */
+      if (to_y + run->height > bottom_y)
+	height = bottom_y - to_y;
+      else
+	height = run->height;
+    }
+  /* end copy from other terms */
+
+  if (height == 0)
+      return;
+
+  BLOCK_INPUT;
+
+  updated_window = w;
+  x_clear_cursor (w);
+
+  {
+    NSRect srcRect = NSMakeRect (x, from_y, width, height);
+    NSRect dstRect = NSMakeRect (x, to_y, width, height);
+    NSPoint dstOrigin = NSMakePoint (x, to_y);
+
+    ns_focus (f, &dstRect, 1);
+    NSCopyBits (0, srcRect , dstOrigin);
+    ns_unfocus (f);
+  }
+
+  UNBLOCK_INPUT;
+}
+
+
+static void
+ns_after_update_window_line (struct glyph_row *desired_row)
+/* --------------------------------------------------------------------------
+   23: External (RIF): preparatory to fringe update after text was updated
+   -------------------------------------------------------------------------- */
+{
+  struct window *w = updated_window;
+  struct frame *f;
+  int width, height;
+
+  NSTRACE (ns_after_update_window_line);
+
+  /* begin copy from other terms */
+  xassert (w);
+
+  if (!desired_row->mode_line_p && !w->pseudo_window_p)
+    desired_row->redraw_fringe_bitmaps_p = 1;
+
+  /* When a window has disappeared, make sure that no rest of
+     full-width rows stays visible in the internal border.
+     Under NS this is drawn inside the fringes. */
+  if (windows_or_buffers_changed
+      && (f = XFRAME (w->frame),
+	  width = FRAME_INTERNAL_BORDER_WIDTH (f),
+	  width != 0)
+      && (height = desired_row->visible_height,
+	  height > 0))
+    {
+      int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
+
+      /* Internal border is drawn below the tool bar.  */
+      if (WINDOWP (f->tool_bar_window)
+	  && w == XWINDOW (f->tool_bar_window))
+	y -= width;
+      /* end copy from other terms */
+
+      BLOCK_INPUT;
+      if (!desired_row->full_width_p)
+        {
+          int x1 = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
+            + WINDOW_LEFT_FRINGE_WIDTH (w);
+          int x2 = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
+            + FRAME_PIXEL_WIDTH (f) - NS_SCROLL_BAR_WIDTH (f)
+            - WINDOW_RIGHT_FRINGE_WIDTH (w)
+            - FRAME_INTERNAL_BORDER_WIDTH (f);
+          ns_clear_frame_area (f, x1, y, width, height);
+          ns_clear_frame_area (f, x2, y, width, height);
+        }
+      UNBLOCK_INPUT;
+    }
+}
+
+
+static void
+ns_shift_glyphs_for_insert (struct frame *f,
+                           int x, int y, int width, int height,
+                           int shift_by)
+/* --------------------------------------------------------------------------
+   23: External (RIF): copy an area horizontally, don't worry about clearing src
+   -------------------------------------------------------------------------- */
+{
+  NSRect srcRect = NSMakeRect (x, y, width, height);
+  NSRect dstRect = NSMakeRect (x+shift_by, y, width, height);
+  NSPoint dstOrigin = dstRect.origin;
+
+  NSTRACE (ns_shift_glyphs_for_insert);
+
+  ns_focus (f, &dstRect, 1);
+  NSCopyBits (0, srcRect, dstOrigin);
+  ns_unfocus (f);
+}
+
+
+
+/* ==========================================================================
+
+    Character encoding and metrics
+
+   ========================================================================== */
+
+
+static inline void
+ns_compute_glyph_string_overhangs (struct glyph_string *s)
+/* --------------------------------------------------------------------------
+   23:  External (RIF); compute left/right overhang of whole string and set in s
+   -------------------------------------------------------------------------- */
+{
+  struct face *face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+  struct font *font = s->font; /*face->font; */
+
+  if (s->char2b)
+    {
+      struct font_metrics metrics;
+      unsigned int codes[2];
+      codes[0] = *(s->char2b);
+      codes[1] = *(s->char2b + s->nchars - 1);
+
+      font->driver->text_extents (font, codes, 2, &metrics);
+      s->left_overhang = -metrics.lbearing;
+      s->right_overhang =
+        metrics.rbearing > metrics.width ? metrics.rbearing - metrics.width : 0;
+    }
+  else
+    {
+      s->left_overhang = 0;
+      s->right_overhang = ((struct nsfont_info *)font)->ital ?
+        FONT_HEIGHT (font) * 0.2 : 0;
+    }
+}
+
+
+
+/* ==========================================================================
+
+    Fringe and cursor drawing
+
+   ========================================================================== */
+
+
+extern int max_used_fringe_bitmap;
+static void
+ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
+                      struct draw_fringe_bitmap_params *p)
+/* --------------------------------------------------------------------------
+   23: External (RIF); fringe-related
+   -------------------------------------------------------------------------- */
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct face *face = p->face;
+  int rowY;
+  static EmacsImage **bimgs = NULL;
+  static int nBimgs = 0;
+  /* NS-specific: move internal border inside fringe */
+  int x = p->bx < 0 ? p->x : p->bx;
+  int wd = p->bx < 0 ? p->wd : p->nx;
+  BOOL fringeOnVeryLeft =
+      x - WINDOW_LEFT_SCROLL_BAR_COLS (w) * WINDOW_FRAME_COLUMN_WIDTH (w)
+      - FRAME_INTERNAL_BORDER_WIDTH (f) < 10;
+  BOOL fringeOnVeryRight =
+      FRAME_PIXEL_WIDTH (f) - x - wd - FRAME_INTERNAL_BORDER_WIDTH (f)
+      - WINDOW_RIGHT_SCROLL_BAR_COLS (w) * WINDOW_FRAME_COLUMN_WIDTH (w) < 10;
+  int xAdjust = FRAME_INTERNAL_BORDER_WIDTH (f) *
+    (fringeOnVeryLeft ? -1 : (fringeOnVeryRight ? 1 : 0));
+
+  /* grow bimgs if needed */
+  if (nBimgs < max_used_fringe_bitmap)
+    {
+      EmacsImage **newBimgs =
+        xmalloc (max_used_fringe_bitmap * sizeof (EmacsImage *));
+      bzero (newBimgs, max_used_fringe_bitmap * sizeof (EmacsImage *));
+
+      if (nBimgs)
+        {
+          bcopy (bimgs, newBimgs, nBimgs * sizeof (EmacsImage *));
+          xfree (bimgs);
+        }
+
+      bimgs = newBimgs;
+      nBimgs = max_used_fringe_bitmap;
+    }
+
+  /* Must clip because of partially visible lines.  */
+  rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+  if (p->y < rowY)
+    {
+      /* Adjust position of "bottom aligned" bitmap on partially
+	 visible last row.  */
+      int oldY = row->y;
+      int oldVH = row->visible_height;
+      row->visible_height = p->h;
+      row->y -= rowY - p->y;
+      ns_clip_to_row (w, row, -1, NULL);
+      row->y = oldY;
+      row->visible_height = oldVH;
+    }
+  else
+    ns_clip_to_row (w, row, -1, YES);
+
+  if (p->bx >= 0 && !p->overlay_p)
+    {
+      int yAdjust = rowY - FRAME_INTERNAL_BORDER_WIDTH (f) < 5 ?
+        -FRAME_INTERNAL_BORDER_WIDTH (f) : 0;
+      int yIncr = FRAME_PIXEL_HEIGHT (f) - (p->by+yAdjust + p->ny) < 5 ?
+        FRAME_INTERNAL_BORDER_WIDTH (f) : 0;
+      if (yAdjust)
+        yIncr += FRAME_INTERNAL_BORDER_WIDTH (f);
+      NSRect r = NSMakeRect (p->bx+xAdjust, p->by+yAdjust, p->nx, p->ny+yIncr);
+      NSRectClip (r);
+      [ns_lookup_indexed_color(face->background, f) set];
+      NSRectFill (r);
+    }
+
+  if (p->which)
+    {
+      NSRect r = NSMakeRect (p->x+xAdjust, p->y, p->wd, p->h);
+      NSPoint pt = r.origin;
+      EmacsImage *img = bimgs[p->which - 1];
+
+      if (!img)
+        {
+          unsigned short *bits = p->bits + p->dh;
+          int len = 8 * p->h/8;
+          int i;
+          unsigned char *cbits = xmalloc (len);
+
+          for (i =0; i<len; i++)
+            cbits[i] = ~(bits[i] & 0xff);
+          img = [[EmacsImage alloc] initFromXBM: cbits width: 8 height: p->h
+                                           flip: NO];
+          bimgs[p->which - 1] = img;
+          xfree (cbits);
+        }
+
+      NSRectClip (r);
+      /* Since we composite the bitmap instead of just blitting it, we need
+         to erase the whole background. */
+      [ns_lookup_indexed_color(face->background, f) set];
+      NSRectFill (r);
+      pt.y += p->h;
+      [img setXBMColor: ns_lookup_indexed_color(face->foreground, f)];
+      [img compositeToPoint: pt operation: NSCompositeSourceOver];
+    }
+  ns_unfocus (f);
+}
+
+
+void
+ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
+                       int x, int y, int cursor_type, int cursor_width,
+                       int on_p, int active_p)
+/* --------------------------------------------------------------------------
+     External call (RIF): draw cursor
+   -------------------------------------------------------------------------- */
+{
+  NSRect r, s;
+  int fx, fy, h;
+  struct frame *f = WINDOW_XFRAME (w);
+  struct glyph *phys_cursor_glyph;
+  int overspill;
+  unsigned char drawGlyph = 0, cursorType, oldCursorType;
+
+  NSTRACE (dumpcursor);
+
+  if (!on_p)
+      return;
+
+  w->phys_cursor_type = cursor_type;
+  w->phys_cursor_on_p = 1;
+
+  if (cursor_type == NO_CURSOR)
+    {
+      w->phys_cursor_width = 0;
+      return;
+    }
+
+  if ((phys_cursor_glyph = get_phys_cursor_glyph (w)) == NULL)
+    {
+      if (glyph_row->exact_window_width_line_p
+          && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
+        {
+          glyph_row->cursor_in_fringe_p = 1;
+          draw_fringe_bitmap (w, glyph_row, 0);
+        }
+      return;
+    }
+
+  get_phys_cursor_geometry (w, glyph_row, phys_cursor_glyph, &fx, &fy, &h);
+
+  r.origin.x = fx, r.origin.y = fy;
+  r.size.height = h;
+  r.size.width = w->phys_cursor_width;
+
+  /* PENDING: if we overwrite the internal border area, it does not get erased;
+     fix by truncating cursor, but better would be to erase properly */
+  overspill = r.origin.x + r.size.width -
+    WINDOW_TEXT_TO_FRAME_PIXEL_X (w, WINDOW_BOX_RIGHT_EDGE_X (w) 
+      - WINDOW_TOTAL_FRINGE_WIDTH (w) - FRAME_INTERNAL_BORDER_WIDTH (f));
+  if (overspill > 0)
+    r.size.width -= overspill;
+
+  /* PENDING: 23: use emacs stored f->cursor_type instead of ns-specific */
+  oldCursorType = FRAME_CURSOR (f);
+  cursorType = FRAME_CURSOR (f) = FRAME_NEW_CURSOR (f);
+  f->output_data.ns->current_cursor_color =
+     f->output_data.ns->desired_cursor_color;
+
+  /* PENDING: only needed in rare cases with last-resort font in HELLO..
+     should we do this more efficiently? */
+  ns_clip_to_row (w, glyph_row, -1, NULL);
+/*  ns_focus (f, &r, 1); */
+
+  if (FRAME_LAST_INACTIVE (f))
+    {
+      /* previously hollow box; clear entire area */
+      [FRAME_BACKGROUND_COLOR (f) set];
+      NSRectFill (r);
+      drawGlyph = 1;
+      FRAME_LAST_INACTIVE (f) = NO;
+    }
+
+  /* prepare to draw */
+  if (cursorType == no_highlight || cursor_type == NO_CURSOR)
+    {
+      /* clearing for blink: erase the cursor itself */
+      [FRAME_BACKGROUND_COLOR (f) set];
+      cursorType = oldCursorType; /* just clear what we had before */
+    }
+  else
+      [FRAME_CURSOR_COLOR (f) set];
+
+  if (!active_p)
+    {
+      /* inactive window: ignore what we just set and use a hollow box */
+      cursorType = hollow_box;
+      [FRAME_CURSOR_COLOR (f) set];
+    }
+
+  switch (cursorType)
+    {
+    case no_highlight:
+      break;
+    case filled_box:
+      NSRectFill (r);
+      drawGlyph = 1;
+      break;
+    case hollow_box:
+      NSRectFill (r);
+      [FRAME_BACKGROUND_COLOR (f) set];
+      NSRectFill (NSInsetRect (r, 1, 1));
+      [FRAME_CURSOR_COLOR (f) set];
+      drawGlyph = 1;
+      break;
+    case underscore:
+      s = r;
+      s.origin.y += lrint (0.75 * s.size.height);
+      s.size.height = lrint (s.size.height * 0.25);
+      NSRectFill (s);
+      break;
+    case bar:
+      s = r;
+      s.size.width = 1;
+      NSRectFill (s);
+      break;
+    }
+  ns_unfocus (f);
+
+  /* if needed, draw the character under the cursor */
+  if (drawGlyph)
+    draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+}
+
+
+static void
+ns_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
+/* --------------------------------------------------------------------------
+     External (RIF): Draw a vertical line.
+   -------------------------------------------------------------------------- */
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct face *face;
+  NSRect r = NSMakeRect (x, y0, 2, y1-y0);
+
+  face = FACE_FROM_ID (f, VERTICAL_BORDER_FACE_ID);
+  if (face)
+      [ns_lookup_indexed_color(face->foreground, f) set];
+
+  ns_focus (f, &r, 1);
+  NSDrawGroove (r, r);
+  ns_unfocus (f);
+}
+
+
+void
+show_hourglass (struct atimer *timer)
+{
+  if (hourglass_shown_p)
+    return;
+
+  BLOCK_INPUT;
+
+  /*PENDING: add NSProgressIndicator to selected frame (see macfns.c) */
+
+  hourglass_shown_p = 1;
+  UNBLOCK_INPUT;
+}
+
+
+void
+hide_hourglass ()
+{
+  if (!hourglass_shown_p)
+    return;
+
+  /*PENDING: remove NSProgressIndicator from all frames */
+
+  hourglass_shown_p = 0;
+  UNBLOCK_INPUT;
+}
+
+
+
+/* ==========================================================================
+
+    Glyph drawing operations
+
+   ========================================================================== */
+
+
+static inline NSRect
+/* --------------------------------------------------------------------------
+    Under NS we draw internal borders inside fringes, and want full-width
+    rendering to go all the way to edge.  This function makes that correction.
+   -------------------------------------------------------------------------- */
+ns_fix_rect_ibw (NSRect r, int fibw, int frame_pixel_width)
+{
+  if (r.origin.y <= fibw+1)
+    {
+      r.size.height += r.origin.y;
+      r.origin.y = 0;
+    }
+  if (r.origin.x <= fibw+1)
+    {
+      r.size.width += r.origin.x;
+      r.origin.x = 0;
+    }
+  if (frame_pixel_width - (r.origin.x+r.size.width) <= fibw+1)
+    r.size.width += fibw;
+
+  return r;
+}
+
+
+static int
+ns_get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
+/* --------------------------------------------------------------------------
+    Wrapper utility to account for internal border width on full-width lines,
+    and allow top full-width rows to hit the frame top.  nr should be pointer
+    to two successive NSRects.  Number of rects actually used is returned.
+   -------------------------------------------------------------------------- */
+{
+  int n = get_glyph_string_clip_rects (s, nr, 2);
+  if (s->row->full_width_p)
+    {
+      *nr = ns_fix_rect_ibw (*nr, FRAME_INTERNAL_BORDER_WIDTH (s->f),
+                            FRAME_PIXEL_WIDTH (s->f));
+      if (n == 2)
+        *nr = ns_fix_rect_ibw (*(nr+1), FRAME_INTERNAL_BORDER_WIDTH (s->f),
+                              FRAME_PIXEL_WIDTH (s->f));
+    }
+  return n;
+}
+
+
+static void
+ns_draw_box (NSRect r, float thickness, NSColor *col, char left_p, char right_p)
+/* --------------------------------------------------------------------------
+    Draw an unfilled rect inside r, optionally leaving left and/or right open.
+    Note we can't just use an NSDrawRect command, because of the possibility
+    of some sides not being drawn, and because the rect will be filled.
+   -------------------------------------------------------------------------- */
+{
+  NSRect s = r;
+  [col set];
+
+  /* top, bottom */
+  s.size.height = thickness;
+  NSRectFill (s);
+  s.origin.y += r.size.height - thickness;
+  NSRectFill (s);
+
+  s.size.height = r.size.height;
+  s.origin.y = r.origin.y;
+
+  /* left, right (optional) */
+  s.size.width = thickness;
+  if (left_p)
+    NSRectFill (s);
+  if (right_p)
+    {
+      s.origin.x += r.size.width - thickness;
+      NSRectFill (s);
+    }
+}
+
+
+static void
+ns_draw_relief (NSRect r, int thickness, char raised_p,
+               char top_p, char bottom_p, char left_p, char right_p,
+               struct glyph_string *s)
+/* --------------------------------------------------------------------------
+    Draw a relief rect inside r, optionally leaving some sides open.
+    Note we can't just use an NSDrawBezel command, because of the possibility
+    of some sides not being drawn, and because the rect will be filled.
+   -------------------------------------------------------------------------- */
+{
+  static NSColor *baseCol = nil, *lightCol = nil, *darkCol = nil;
+  NSColor *newBaseCol = nil;
+  NSRect sr = r;
+
+  NSTRACE (ns_draw_relief);
+
+  /* set up colors */
+
+  if (s->face->use_box_color_for_shadows_p)
+    {
+      newBaseCol = ns_lookup_indexed_color (s->face->box_color, s->f);
+    }
+/*     else if (s->first_glyph->type == IMAGE_GLYPH
+	   && s->img->pixmap
+   	   && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
+       {
+         newBaseCol = IMAGE_BACKGROUND  (s->img, s->f, 0);
+       } */
+  else
+    {
+      newBaseCol = ns_lookup_indexed_color (s->face->background, s->f);
+    }
+
+  if (newBaseCol == nil)
+    newBaseCol = [NSColor grayColor];
+
+  if (newBaseCol != baseCol)  /* PENDING: better check */
+    {
+      [baseCol release];
+      baseCol = [newBaseCol retain];
+      [lightCol release];
+      lightCol = [[baseCol highlightWithLevel: 0.2] retain];
+      [darkCol release];
+      darkCol = [[baseCol shadowWithLevel: 0.3] retain];
+    }
+
+  [(raised_p ? lightCol : darkCol) set];
+
+  /* TODO: mitering. Using NSBezierPath doesn't work because of color switch. */
+
+  /* top */
+  sr.size.height = thickness;
+  if (top_p) NSRectFill (sr);
+
+  /* left */
+  sr.size.height = r.size.height;
+  sr.size.width = thickness;
+  if (left_p) NSRectFill (sr);
+
+  [(raised_p ? darkCol : lightCol) set];
+
+  /* bottom */
+  sr.size.width = r.size.width;
+  sr.size.height = thickness;
+  sr.origin.y += r.size.height - thickness;
+  if (bottom_p) NSRectFill (sr);
+
+  /* right */
+  sr.size.height = r.size.height;
+  sr.origin.y = r.origin.y;
+  sr.size.width = thickness;
+  sr.origin.x += r.size.width - thickness;
+  if (right_p) NSRectFill (sr);
+}
+
+
+static void
+ns_dumpglyphs_box_or_relief (struct glyph_string *s)
+/* --------------------------------------------------------------------------
+      Function modeled after x_draw_glyph_string_box ().
+      Sets up parameters for drawing.
+   -------------------------------------------------------------------------- */
+{
+  int right_x, last_x;
+  char left_p, right_p;
+  struct glyph *last_glyph;
+  NSRect r;
+  int thickness;
+  struct face *face;
+
+  if (s->hl == DRAW_MOUSE_FACE)
+    {
+      face = FACE_FROM_ID
+        (s->f, FRAME_NS_DISPLAY_INFO (s->f)->mouse_face_face_id);
+      if (!face)
+        face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+    }
+  else
+    face = s->face;
+
+  thickness = face->box_line_width;
+
+  NSTRACE (ns_dumpglyphs_box_or_relief);
+
+  last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
+	    ? WINDOW_RIGHT_EDGE_X (s->w)
+	    : window_box_right (s->w, s->area));
+  last_glyph = (s->cmp || s->img
+                ? s->first_glyph : s->first_glyph + s->nchars-1);
+
+  right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
+	      ? last_x - 1 : min (last_x, s->x + s->background_width) - 1));
+
+  left_p = (s->first_glyph->left_box_line_p
+	    || (s->hl == DRAW_MOUSE_FACE
+		&& (s->prev == NULL || s->prev->hl != s->hl)));
+  right_p = (last_glyph->right_box_line_p
+	     || (s->hl == DRAW_MOUSE_FACE
+		 && (s->next == NULL || s->next->hl != s->hl)));
+
+  r = NSMakeRect (s->x, s->y, right_x - s->x + 1, s->height);
+
+  /* expand full-width row over internal borders */
+  if (s->row->full_width_p)
+    r = ns_fix_rect_ibw (r, FRAME_INTERNAL_BORDER_WIDTH (s->f),
+                        FRAME_PIXEL_WIDTH (s->f));
+
+  if (s->face->box == FACE_SIMPLE_BOX)
+    {
+      xassert (s->face->box_color != nil);
+      ns_draw_box (r, abs (thickness),
+                   ns_lookup_indexed_color (face->box_color, s->f),
+                  left_p, right_p);
+    }
+  else
+    {
+      ns_draw_relief (r, abs (thickness), s->face->box == FACE_RAISED_BOX,
+                     1, 1, left_p, right_p, s);
+    }
+}
+
+
+static void
+ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p)
+/* --------------------------------------------------------------------------
+      Modeled after x_draw_glyph_string_background, which draws BG in
+      certain cases.  Others are left to the text rendering routine.
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (ns_maybe_dumpglyphs_background);
+
+  if (!s->background_filled_p/* || s->hl == DRAW_MOUSE_FACE*/)
+    {
+      int box_line_width = max (s->face->box_line_width, 0);
+      if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
+          || s->font_not_found_p || s->extends_to_end_of_line_p || force_p)
+	{
+          struct face *face;
+          if (s->hl == DRAW_MOUSE_FACE)
+            {
+              face = FACE_FROM_ID
+                (s->f, FRAME_NS_DISPLAY_INFO (s->f)->mouse_face_face_id);
+              if (!face)
+                face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+            }
+          else
+            face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+          if (!face->stipple)
+            [(NS_FACE_BACKGROUND (face) != nil
+              ? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
+              : FRAME_BACKGROUND_COLOR (s->f)) set];
+          else
+            {
+              struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (s->f);
+              [[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set];
+            }
+
+          if (s->hl != DRAW_CURSOR)
+            {
+              NSRect r = NSMakeRect (s->x, s->y + box_line_width,
+                                    s->background_width,
+                                    s->height-2*box_line_width);
+
+              /* expand full-width row over internal borders */
+              if (s->row->full_width_p)
+                {
+                  int fibw = FRAME_INTERNAL_BORDER_WIDTH (s->f);
+                  if (r.origin.y <= fibw+1 + box_line_width)
+                    {
+                      r.size.height += r.origin.y;
+                      r.origin.y = 0;
+                    }
+                  if (r.origin.x <= fibw+1)
+                    {
+                      r.size.width += 2*r.origin.x;
+                      r.origin.x = 0;
+                    }
+                  if (FRAME_PIXEL_WIDTH (s->f) - (r.origin.x + r.size.width)
+                      <= fibw+1)
+                    r.size.width += fibw;
+                }
+
+              NSRectFill (r);
+            }
+
+	  s->background_filled_p = 1;
+	}
+    }
+}
+
+
+static void
+ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
+/* --------------------------------------------------------------------------
+      Renders an image and associated borders.
+   -------------------------------------------------------------------------- */
+{
+  EmacsImage *img = s->img->pixmap;
+  int box_line_vwidth = max (s->face->box_line_width, 0);
+  int x = s->x, y = s->ybase - image_ascent (s->img, s->face, &s->slice);
+  int bg_x, bg_y, bg_height;
+  int th;
+  char raised_p;
+  NSRect br;
+
+  NSTRACE (ns_dumpglyphs_image);
+
+  if (s->face->box != FACE_NO_BOX
+      && s->first_glyph->left_box_line_p && s->slice.x == 0)
+    x += abs (s->face->box_line_width);
+
+  bg_x = x;
+  bg_y =  s->slice.y == 0 ? s->y : s->y + box_line_vwidth;
+  bg_height = s->height;
+  /* other terms have this, but was causing problems w/tabbar mode */
+  /* - 2 * box_line_vwidth; */
+
+  if (s->slice.x == 0) x += s->img->hmargin;
+  if (s->slice.y == 0) y += s->img->vmargin;
+
+  /* Draw BG: if we need larger area than image itself cleared, do that,
+     otherwise, since we composite the image under NS (instead of mucking
+     with its background color), we must clear just the image area. */
+  [ns_lookup_indexed_color (NS_FACE_BACKGROUND
+            (FACE_FROM_ID (s->f, s->first_glyph->face_id)), s->f) set];
+
+  if (bg_height > s->slice.height || s->img->hmargin || s->img->vmargin
+      || s->img->mask || s->img->pixmap == 0 || s->width != s->background_width)
+    {
+      br = NSMakeRect (bg_x, bg_y, s->background_width, bg_height);
+      s->background_filled_p = 1;
+    }
+  else
+    {
+      br = NSMakeRect (x, y, s->slice.width, s->slice.height);
+    }
+
+  /* expand full-width row over internal borders */
+  if (s->row->full_width_p)
+    {
+      int fibw = FRAME_INTERNAL_BORDER_WIDTH (s->f);
+      if (br.origin.y <= fibw+1 + box_line_vwidth)
+        {
+          br.size.height += br.origin.y;
+          br.origin.y = 0;
+        }
+      if (br.origin.x <= fibw+1 + box_line_vwidth)
+        {
+          br.size.width += br.origin.x;
+          br.origin.x = 0;
+        }
+      if (FRAME_PIXEL_WIDTH (s->f) - (br.origin.x + br.size.width) <= fibw+1)
+        br.size.width += fibw;
+    }
+
+  NSRectFill (br);
+
+  /* Draw the image.. do we need to draw placeholder if img ==nil? */
+  if (img != nil)
+    [img compositeToPoint: NSMakePoint (x, y + s->slice.height)
+                operation: NSCompositeSourceOver];
+
+  /* Draw relief, if requested */
+  if (s->img->relief || s->hl ==DRAW_IMAGE_RAISED || s->hl ==DRAW_IMAGE_SUNKEN)
+    {
+      if (s->hl == DRAW_IMAGE_SUNKEN || s->hl == DRAW_IMAGE_RAISED)
+        {
+          th = tool_bar_button_relief >= 0 ?
+            tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
+          raised_p = (s->hl == DRAW_IMAGE_RAISED);
+        }
+      else
+        {
+          th = abs (s->img->relief);
+          raised_p = (s->img->relief > 0);
+        }
+
+      r.origin.x = x - th;
+      r.origin.y = y - th;
+      r.size.width = s->slice.width + 2*th-1;
+      r.size.height = s->slice.height + 2*th-1;
+      ns_draw_relief (r, th, raised_p,
+                     s->slice.y == 0,
+                     s->slice.y + s->slice.height == s->img->height,
+                     s->slice.x == 0,
+                     s->slice.x + s->slice.width == s->img->width, s);
+    }
+}
+
+
+static void
+ns_draw_glyph_string (struct glyph_string *s)
+/* --------------------------------------------------------------------------
+      External (RIF): Main draw-text call.
+   -------------------------------------------------------------------------- */
+{
+  /*PENDING (optimize): focus for box and contents draw */
+  NSRect r[2];
+  int n;
+  char box_drawn_p = 0;
+
+  NSTRACE (ns_draw_glyph_string);
+
+  if (s->next && s->right_overhang && !s->for_overlaps && s->hl != DRAW_CURSOR)
+    {
+      xassert (s->next->img == NULL);
+      n = ns_get_glyph_string_clip_rect (s->next, r);
+      ns_focus (s->f, r, n);
+      ns_maybe_dumpglyphs_background (s->next, 1);
+      ns_unfocus (s->f);
+    }
+
+  if (!s->for_overlaps && s->face->box != FACE_NO_BOX
+        && (s->first_glyph->type == CHAR_GLYPH
+	    || s->first_glyph->type == COMPOSITE_GLYPH))
+    {
+      n = ns_get_glyph_string_clip_rect (s, r);
+      ns_focus (s->f, r, n);
+      ns_maybe_dumpglyphs_background (s, 1);
+      ns_dumpglyphs_box_or_relief (s);
+      ns_unfocus (s->f);
+      box_drawn_p = 1;
+    }
+
+  switch (s->first_glyph->type)
+    {
+
+    case IMAGE_GLYPH:
+      n = ns_get_glyph_string_clip_rect (s, r);
+      ns_focus (s->f, r, n);
+      ns_dumpglyphs_image (s, r[0]);
+      ns_unfocus (s->f);
+      break;
+
+    case STRETCH_GLYPH:
+      if (!s->background_filled_p)
+        {
+          *r = NSMakeRect (s->x, s->y, s->background_width, s->height);
+
+          if (!s->row->full_width_p)
+            {
+              /* truncate to avoid overwriting fringe and/or scrollbar */
+              int overrun = max (0, (s->x + s->background_width)
+                                 - (WINDOW_BOX_RIGHT_EDGE_X (s->w)
+                                    - WINDOW_RIGHT_FRINGE_WIDTH (s->w)));
+              r[0].size.width -= overrun;
+
+              /* PENDING: Try to work between problem where a stretch glyph on
+                 a partially-visible bottom row will clear part of the
+                 modeline, and another where list-buffers headers and similar
+                 rows erroneously have visible_height set to 0.  Not sure
+                 where this is coming from as other terms seem not to show. */
+              r[0].size.height = min (s->height, s->row->visible_height);
+            }
+
+          /* expand full-width rows over internal borders */
+          else
+            {
+              r[0] = ns_fix_rect_ibw (r[0], FRAME_INTERNAL_BORDER_WIDTH (s->f),
+                                     FRAME_PIXEL_WIDTH (s->f));
+            }
+
+          /* NOTE: under NS this is NOT used to draw cursors, but we must avoid
+             overwriting cursor (usually when cursor on a tab) */
+          if (s->hl == DRAW_CURSOR)
+            {
+              r[0].origin.x += s->width;
+              r[0].size.width -= s->width;
+            }
+
+          ns_focus (s->f, r, 1);
+          [ns_lookup_indexed_color (NS_FACE_BACKGROUND
+               (FACE_FROM_ID (s->f, s->first_glyph->face_id)), s->f) set];
+          NSRectFill (r[0]);
+          ns_unfocus (s->f);
+          s->background_filled_p = 1;
+        }
+      break;
+
+    case CHAR_GLYPH:
+    case COMPOSITE_GLYPH:
+      n = ns_get_glyph_string_clip_rect (s, r);
+      ns_focus (s->f, r, n);
+
+      if (s->for_overlaps || s->gidx > 0)
+        s->background_filled_p = 1;
+      else      /* 1 */
+        ns_maybe_dumpglyphs_background
+          (s, s->first_glyph->type == COMPOSITE_GLYPH);
+
+      ns_tmp_flags = s->hl == DRAW_CURSOR ? NS_DUMPGLYPH_CURSOR :
+                    (s->hl == DRAW_MOUSE_FACE ? NS_DUMPGLYPH_MOUSEFACE :
+                     (s->for_overlaps ? NS_DUMPGLYPH_FOREGROUND :
+                      NS_DUMPGLYPH_NORMAL));
+      ns_tmp_font = (struct nsfont_info *)s->face->font;
+      if (ns_tmp_font == ~0 || ns_tmp_font == NULL)
+          ns_tmp_font = FRAME_FONT (s->f);
+
+      ns_tmp_font->font.driver->draw
+        (s, 0, s->nchars, s->x, s->y,
+         (ns_tmp_flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p)
+         || ns_tmp_flags == NS_DUMPGLYPH_MOUSEFACE);
+
+      ns_unfocus (s->f);
+      break;
+
+    default:
+      abort ();
+    }
+
+  /* Draw box if not done already. */
+  if (!s->for_overlaps && !box_drawn_p && s->face->box != FACE_NO_BOX)
+    {
+      n = ns_get_glyph_string_clip_rect (s, r);
+      ns_focus (s->f, r, n);
+      ns_dumpglyphs_box_or_relief (s);
+      ns_unfocus (s->f);
+    }
+
+}
+
+
+
+/* ==========================================================================
+
+    Event loop
+
+   ========================================================================== */
+
+
+static void
+ns_send_appdefined (int value)
+/* --------------------------------------------------------------------------
+    Internal: post an appdefined event which EmacsApp-sendEvent will
+              recognize and take as a command to halt the event loop.
+   -------------------------------------------------------------------------- */
+{
+  /*NSTRACE (ns_send_appdefined); */
+
+  /* Only post this event if we haven't already posted one.  This will end
+       the [NXApp run] main loop after having processed all events queued at
+       this moment.  */
+  if (send_appdefined)
+    {
+      NSEvent *nxev;
+
+      /* We only need one NX_APPDEFINED event to stop NXApp from running.  */
+      send_appdefined = NO;
+
+      /* Don't need wakeup timer any more */
+      if (timed_entry)
+        {
+          [timed_entry invalidate];
+          [timed_entry release];
+          timed_entry = nil;
+        }
+
+      /* Ditto for file descriptor poller */
+      if (fd_entry)
+        {
+          [fd_entry invalidate];
+          [fd_entry release];
+          fd_entry = nil;
+        }
+
+      nxev = [NSEvent otherEventWithType: NSApplicationDefined
+                                location: NSMakePoint (0, 0)
+                           modifierFlags: 0
+                               timestamp: 0
+                            windowNumber: [[NSApp mainWindow] windowNumber]
+                                 context: [NSApp context]
+                                 subtype: 0
+                                   data1: value
+                                   data2: 0];
+
+      /* Post an application defined event on the event queue.  When this is
+         received the [NXApp run] will return, thus having processed all
+         events which are currently queued.  */
+      [NSApp postEvent: nxev atStart: NO];
+    }
+}
+
+
+static int
+ns_read_socket (struct terminal *terminal, int expected,
+                struct input_event *hold_quit)
+/* --------------------------------------------------------------------------
+     External (hook): Post an event to ourself and keep reading events until
+     we read it back again.  In effect process all events which were waiting.
+   23: Now we have to manage the event buffer ourselves.
+   -------------------------------------------------------------------------- */
+{
+  struct input_event ev;
+  int nevents;
+  static NSDate *lastCheck = nil;
+/*  NSTRACE (ns_read_socket); */
+
+  if (interrupt_input_blocked)
+    {
+      interrupt_input_pending = 1;
+      return -1;
+    }
+
+  interrupt_input_pending = 0;
+  BLOCK_INPUT;
+
+#ifdef COCOA_EXPERIMENTAL_CTRL_G
+  /* causes Feval to abort; unclear on why this isn't in calling code */
+  ++handling_signal;
+#endif
+
+  n_emacs_events_pending = 0;
+  EVENT_INIT (ev);
+  emacs_event = &ev;
+  q_event_ptr = hold_quit;
+
+  /* we manage autorelease pools by allocate/reallocate each time around
+     the loop; strict nesting is occasionally violated but seems not to
+     matter.. earlier methods using full nesting caused major memory leaks */
+  [outerpool release];
+  outerpool = [[NSAutoreleasePool alloc] init];
+
+  /* If have pending open-file requests, attend to the next one of those. */
+  if (ns_pending_files && [ns_pending_files count] != 0
+      && [NSApp openFile: [ns_pending_files objectAtIndex: 0]])
+    {
+      [ns_pending_files removeObjectAtIndex: 0];
+    }
+  /* Deal with pending service requests. */
+  else if (ns_pending_service_names && [ns_pending_service_names count] != 0
+    && [NSApp fulfillService: [ns_pending_service_names objectAtIndex: 0]
+                     withArg: [ns_pending_service_args objectAtIndex: 0]])
+    {
+      [ns_pending_service_names removeObjectAtIndex: 0];
+      [ns_pending_service_args removeObjectAtIndex: 0];
+    }
+  else
+    {
+      /* Run and wait for events.  We must always send one NX_APPDEFINED event
+         to ourself, otherwise [NXApp run] will never exit.  */
+      send_appdefined = YES;
+
+      /*PENDING: from termhooks.h: */
+      /* XXX Please note that a non-zero value of EXPECTED only means that
+     there is available input on at least one of the currently opened
+     terminal devices -- but not necessarily on this device.
+     Therefore, in most cases EXPECTED should be simply ignored. */
+      /* However, if in ns_select, this is called from gobble_input, which
+         appears to set it correctly for our purposes, and always assuming
+         !expected causes 100% CPU usage. */
+      if (!inNsSelect || !expected)
+        {
+          /* Post an application defined event on the event queue.  When this is
+             received the [NXApp run] will return, thus having processed all
+             events which are currently queued, if any.  */
+          ns_send_appdefined (-1);
+        }
+
+      [NSApp run];
+    }
+
+  nevents = n_emacs_events_pending;
+  n_emacs_events_pending = 0;
+  emacs_event = q_event_ptr = NULL;
+
+#ifdef COCOA_EXPERIMENTAL_CTRL_G
+  --handling_signal;
+#endif
+  UNBLOCK_INPUT;
+  return nevents;
+}
+
+
+int
+ns_select (int nfds, fd_set *readfds, fd_set *writefds,
+           fd_set *exceptfds, struct timeval *timeout)
+/* --------------------------------------------------------------------------
+     Replacement for select, checking for events
+   -------------------------------------------------------------------------- */
+{
+  int result;
+  double time;
+  NSEvent *ev;
+/*  NSTRACE (ns_select); */
+
+  if (NSApp == nil /* || ([NSApp isActive] == NO &&
+                      [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil
+ inMode:NSDefaultRunLoopMode dequeue:NO] == nil) */)
+    return select (nfds, readfds, writefds, exceptfds, timeout);
+
+  /* Save file descriptor set, which gets overwritten in calls to select ()
+     Note, this is called from process.c, and only readfds is ever set */
+  if (readfds)
+    {
+      memcpy (&select_readfds, readfds, sizeof (fd_set));
+      select_nfds = nfds;
+    }
+  else
+    select_nfds = 0;
+
+    /* Try an initial select for pending data on input files */
+  select_timeout.tv_sec = select_timeout.tv_usec = 0;
+  result = select (nfds, readfds, writefds, exceptfds, &select_timeout);
+  if (result)
+    return result;
+
+  /* if (!timeout || timed_entry || fd_entry)
+       fprintf (stderr, "assertion failed: timeout null or timed_entry/fd_entry non-null in ns_select\n"); */
+
+    /* set a timeout and run the main AppKit event loop while continuing
+       to monitor the files */
+  time = ((double) timeout->tv_sec) + ((double) timeout->tv_usec)/1000000.0;
+  timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time
+                                           target: NSApp
+                                         selector: @selector (timeout_handler:)
+                                         userInfo: 0
+                                          repeats: YES] /* for safe removal */
+                                                         retain];
+
+  /* set a periodic task to try the select () again */
+  fd_entry = [[NSTimer scheduledTimerWithTimeInterval: 0.1
+                                               target: NSApp
+                                             selector: @selector (fd_handler:)
+                                             userInfo: 0
+                                              repeats: YES]
+               retain];
+
+  if (!NILP (ns_cursor_blink_mode) && !cursor_blink_entry)
+    {
+      if (!NUMBERP (ns_cursor_blink_rate))
+        ns_cursor_blink_rate = make_float (0.5);
+      cursor_blink_entry = [[NSTimer
+        scheduledTimerWithTimeInterval: XFLOATINT (ns_cursor_blink_rate)
+                                target: NSApp
+                              selector: @selector (cursor_blink_handler:)
+                              userInfo: 0
+                               repeats: YES]
+                             retain];
+    }
+  else if (NILP (ns_cursor_blink_mode) && cursor_blink_entry)
+    {
+      if (NUMBERP (ns_cursor_blink_rate))
+          ns_cursor_blink_rate = Qnil;
+      struct ns_display_info *dpyinfo = ns_display_list; /* HACK */
+      [cursor_blink_entry invalidate];
+      [cursor_blink_entry release];
+      cursor_blink_entry = 0;
+      if (dpyinfo->ns_highlight_frame)
+        {
+          Lisp_Object tem = 
+            get_frame_param (dpyinfo->ns_highlight_frame, Qcursor_type);
+          dpyinfo->ns_highlight_frame->output_data.ns->desired_cursor =
+            ns_lisp_to_cursor_type (tem);
+        }
+    }
+
+  /* Let Application dispatch events until it receives an event of the type
+       NX_APPDEFINED, which should only be sent by timeout_handler.  */
+  inNsSelect = 1;
+  gobble_input (timeout ? 1 : 0);
+  ev = last_appdefined_event;
+  inNsSelect = 0;
+
+  if (ev)
+    {
+      int t;
+      if ([ev type] != NSApplicationDefined)
+        abort ();
+
+      t = [ev data1];
+      last_appdefined_event = 0;
+
+      if (t == -2)
+        {
+          /* The NX_APPDEFINED event we received was a timeout. */
+          return 0;
+        }
+      else if (t == -1)
+        {
+          /* The NX_APPDEFINED event we received was the result of
+             at least one real input event arriving.  */
+          errno = EINTR;
+          return -1;
+        }
+      else
+        {
+          /* Received back from select () in fd_handler; copy the results */
+          if (readfds)
+            memcpy (readfds, &select_readfds, sizeof (fd_set));
+          return t;
+        }
+    }
+  /* never reached, shut compiler up */
+  return 0;
+}
+
+
+
+/* ==========================================================================
+
+    Scrollbar handling
+
+   ========================================================================== */
+
+
+static void
+ns_set_vertical_scroll_bar (struct window *window,
+                           int portion, int whole, int position)
+/* --------------------------------------------------------------------------
+      External (hook): Update or add scrollbar
+   -------------------------------------------------------------------------- */
+{
+  Lisp_Object win;
+  NSRect r, v;
+  struct frame *f = XFRAME (WINDOW_FRAME (window));
+  EmacsView *view = FRAME_NS_VIEW (f);
+  int window_y, window_height;
+  BOOL barOnVeryLeft, barOnVeryRight;
+  int top, left, height, width, sb_width, sb_left;
+  EmacsScroller *bar;
+static int count = 0;
+
+  /* optimization; display engine sends WAY too many of these.. */
+  if (!NILP (window->vertical_scroll_bar))
+    {
+      bar = XNS_SCROLL_BAR (window->vertical_scroll_bar);
+      if ([bar checkSamePosition: position portion: portion whole: whole])
+        {
+          if (view->scrollbarsNeedingUpdate == 0)
+            {
+              if (!windows_or_buffers_changed)
+                  return;
+            }
+          else
+            view->scrollbarsNeedingUpdate--;
+        }
+    }
+
+  NSTRACE (ns_set_vertical_scroll_bar);
+
+  /* Get dimensions.  */
+  window_box (window, -1, 0, &window_y, 0, &window_height);
+  top = window_y;
+  height = window_height;
+  width = WINDOW_CONFIG_SCROLL_BAR_COLS (window) * FRAME_COLUMN_WIDTH (f);
+  left = WINDOW_SCROLL_BAR_AREA_X (window);
+
+  if (top < 5) /* top scrollbar adjustment */
+    {
+      top -= FRAME_INTERNAL_BORDER_WIDTH (f);
+      height += FRAME_INTERNAL_BORDER_WIDTH (f);
+    }
+
+  /* allow for displaying a skinnier scrollbar than char area allotted */
+  sb_width = (WINDOW_CONFIG_SCROLL_BAR_WIDTH (window) > 0) ?
+    WINDOW_CONFIG_SCROLL_BAR_WIDTH (window) : width;
+
+  barOnVeryLeft = left < 5;
+  barOnVeryRight = FRAME_PIXEL_WIDTH (f) - left - width < 5;
+  sb_left = left + FRAME_INTERNAL_BORDER_WIDTH (f)
+      * (barOnVeryLeft ? -1 : (barOnVeryRight ? 1 : 0));
+
+  r = NSMakeRect (sb_left, top, sb_width, height);
+  /* the parent view is flipped, so we need to flip y value */
+  v = [view frame];
+  r.origin.y = (v.size.height - r.size.height - r.origin.y);
+
+  XSETWINDOW (win, window);
+  BLOCK_INPUT;
+
+  /* we want at least 5 lines to display a scrollbar */
+  if (WINDOW_TOTAL_LINES (window) < 5)
+    {
+      if (!NILP (window->vertical_scroll_bar))
+        {
+          bar = XNS_SCROLL_BAR (window->vertical_scroll_bar);
+          [bar removeFromSuperview];
+          window->vertical_scroll_bar = Qnil;
+        }
+      ns_clear_frame_area (f, sb_left, top, width, height);
+      UNBLOCK_INPUT;
+      return;
+    }
+
+  if (NILP (window->vertical_scroll_bar))
+    {
+      ns_clear_frame_area (f, sb_left, top, width, height);
+      bar = [[EmacsScroller alloc] initFrame: r window: win];
+      window->vertical_scroll_bar = make_save_value (bar, 0);
+    }
+  else
+    {
+      NSRect oldRect;
+      bar = XNS_SCROLL_BAR (window->vertical_scroll_bar);
+      oldRect = [bar frame];
+      r.size.width = oldRect.size.width;
+      if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r))
+        {
+          if (oldRect.origin.x != r.origin.x)
+              ns_clear_frame_area (f, sb_left, top, width, height);
+          [bar setFrame: r];
+        }
+    }
+
+  [bar setPosition: position portion: portion whole: whole];
+  UNBLOCK_INPUT;
+}
+
+
+static void
+ns_condemn_scroll_bars (struct frame *f)
+/* --------------------------------------------------------------------------
+     External (hook): arrange for all frame's scrollbars to be removed
+     at next call to judge_scroll_bars, except for those redeemed.
+   -------------------------------------------------------------------------- */
+{
+  int i;
+  id view;
+  NSArray *subviews = [[FRAME_NS_VIEW (f) superview] subviews];
+
+  NSTRACE (ns_condemn_scroll_bars);
+
+  for (i =[subviews count]-1; i >= 0; i--)
+    {
+      view = [subviews objectAtIndex: i];
+      if ([view isKindOfClass: [EmacsScroller class]])
+        [view condemn];
+    }
+}
+
+
+static void
+ns_redeem_scroll_bar (struct window *window)
+/* --------------------------------------------------------------------------
+     External (hook): arrange to spare this window's scrollbar
+     at next call to judge_scroll_bars.
+   -------------------------------------------------------------------------- */
+{
+  id bar;
+  NSTRACE (ns_redeem_scroll_bar);
+  if (!NILP (window->vertical_scroll_bar))
+    {
+      bar =XNS_SCROLL_BAR (window->vertical_scroll_bar);
+      [bar reprieve];
+    }
+}
+
+
+static void
+ns_judge_scroll_bars (struct frame *f)
+/* --------------------------------------------------------------------------
+     External (hook): destroy all scrollbars on frame that weren't
+     redeemed after call to condemn_scroll_bars.
+   -------------------------------------------------------------------------- */
+{
+  int i;
+  id view;
+  NSArray *subviews = [[FRAME_NS_VIEW (f) superview] subviews];
+  NSTRACE (ns_judge_scroll_bars);
+  for (i =[subviews count]-1; i >= 0; i--)
+    {
+      view = [subviews objectAtIndex: i];
+      if (![view isKindOfClass: [EmacsScroller class]]) continue;
+      [view judge];
+    }
+}
+
+
+
+/* ==========================================================================
+
+    Miscellaneous, mainly stubbed-out functions added in 23
+
+   ========================================================================== */
+
+
+void
+x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
+{
+}
+
+
+
+/* ==========================================================================
+
+    Initialization
+
+   ========================================================================== */
+
+static Lisp_Object ns_string_to_lispmod (char *s)
+/* --------------------------------------------------------------------------
+     Convert modifier name to lisp symbol
+   -------------------------------------------------------------------------- */
+{
+  if (!strncmp (SDATA (SYMBOL_NAME (Qmeta)), s, 10))
+    return Qmeta;
+  else if (!strncmp (SDATA (SYMBOL_NAME (Qsuper)), s, 10))
+    return Qsuper;
+  else if (!strncmp (SDATA (SYMBOL_NAME (Qcontrol)), s, 10))
+    return Qcontrol;
+  else if (!strncmp (SDATA (SYMBOL_NAME (Qalt)), s, 10))
+    return Qalt;
+  else if (!strncmp (SDATA (SYMBOL_NAME (Qhyper)), s, 10))
+    return Qhyper;
+  else if (!strncmp (SDATA (SYMBOL_NAME (Qnone)), s, 10))
+    return Qnone;
+  else
+    return Qnil;
+}
+
+
+static Lisp_Object ns_mod_to_lisp (int m)
+/* --------------------------------------------------------------------------
+     Convert modifier code (see lisp.h) to lisp symbol
+   -------------------------------------------------------------------------- */
+{
+  if (m == CHAR_META)
+    return Qmeta;
+  else if (m == CHAR_SUPER)
+    return Qsuper;
+  else if (m == CHAR_CTL)
+    return Qcontrol;
+  else if (m == CHAR_ALT)
+    return Qalt;
+  else if (m == CHAR_HYPER)
+    return Qhyper;
+  else /* if (m == 0) */
+    return Qnone;
+}
+
+
+static void
+ns_set_default_prefs ()
+/* --------------------------------------------------------------------------
+      Initialize preference variables to defaults
+   -------------------------------------------------------------------------- */
+{
+  ns_alternate_modifier = Qmeta;
+  ns_command_modifier = Qsuper;
+  ns_control_modifier = Qcontrol;
+  ns_function_modifier = Qnone;
+  ns_cursor_blink_rate = Qnil;
+  ns_cursor_blink_mode = Qnil;
+  ns_expand_space = make_float (0.0);
+  ns_antialias_text = YES;
+  ns_antialias_threshold = 10.0;
+  ns_use_qd_smoothing = NO;
+  ns_use_system_highlight_color = YES;
+}
+
+
+static void
+ns_default (const char *parameter, Lisp_Object *result,
+           Lisp_Object yesval, Lisp_Object noval,
+           BOOL is_float, BOOL is_modstring)
+/* --------------------------------------------------------------------------
+      Check a parameter value in user's preferences
+   -------------------------------------------------------------------------- */
+{
+  const char *value;
+
+  if ( (value =[[[NSUserDefaults standardUserDefaults]
+                   stringForKey: [NSString stringWithUTF8String: parameter]]
+                UTF8String]) )
+    {
+      double f;
+      char *pos;
+      if (strcasecmp (value, "YES") == 0)
+        *result = yesval;
+      else if (strcasecmp (value, "NO") == 0)
+        *result = noval;
+      else if (is_float && (f = strtod (value, &pos), pos != value))
+        *result = make_float (f);
+      else if (is_modstring && value)
+        *result = ns_string_to_lispmod (value);
+      else fprintf (stderr,
+                   "Bad value for default \"%s\": \"%s\"\n", parameter, value);
+    }
+}
+
+
+void
+ns_initialize_display_info (struct ns_display_info *dpyinfo)
+/* --------------------------------------------------------------------------
+      Initialize global info and storage for display.
+   -------------------------------------------------------------------------- */
+{
+    NSScreen *screen = [NSScreen mainScreen];
+    NSWindowDepth depth = [screen depth];
+
+    dpyinfo->width = [screen frame].size.width;
+    dpyinfo->height = [screen frame].size.height;
+    dpyinfo->resx = 72.27; /* used 75.0, but this makes pt == pixel, expected */
+    dpyinfo->resy = 72.27;
+    dpyinfo->color_p = ![NSDeviceWhiteColorSpace isEqualToString:
+                                                  NSColorSpaceFromDepth (depth)]
+                && ![NSCalibratedWhiteColorSpace isEqualToString:
+                                                 NSColorSpaceFromDepth (depth)];
+    dpyinfo->n_planes = NSBitsPerPixelFromDepth (depth);
+    dpyinfo->image_cache = make_image_cache ();
+    dpyinfo->color_table =
+      (struct ns_color_table *)xmalloc (sizeof (struct ns_color_table));
+    dpyinfo->color_table->colors = NULL;
+    dpyinfo->root_window = 42; /* a placeholder.. */
+
+    dpyinfo->mouse_face_mouse_frame = NULL;
+    dpyinfo->mouse_face_deferred_gc = 0;
+    dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
+    dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
+    dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
+    dpyinfo->mouse_face_window = dpyinfo->mouse_face_overlay = Qnil;
+    dpyinfo->mouse_face_hidden = 0;
+
+    dpyinfo->mouse_face_mouse_x = dpyinfo->mouse_face_mouse_y = 0;
+    dpyinfo->mouse_face_defer = 0;
+
+    dpyinfo->ns_highlight_frame = dpyinfo->ns_focus_frame = NULL;
+
+    dpyinfo->n_fonts = 0;
+    dpyinfo->smallest_font_height = 1;
+    dpyinfo->smallest_char_width = 1;
+}
+
+
+/* 23: Needed as new part of display engine; this and next define public
+      functions in this file (well, many of them, anyway). */
+/* x_... are generic versions in xdisp.c that we, and other terms, get away
+         with using despite presence in the "system dependent" redisplay
+         interface.  In addition, many of the ns_ methods have code that is
+         shared with all terms, indicating need for further refactoring. */
+extern frame_parm_handler ns_frame_parm_handlers[];
+static struct redisplay_interface ns_redisplay_interface =
+{
+  ns_frame_parm_handlers,
+  x_produce_glyphs, /*generic OK */
+  x_write_glyphs, /*generic OK */
+  x_insert_glyphs, /*generic OK */
+  x_clear_end_of_line, /*generic OK */
+  ns_scroll_run, /*23 */
+  ns_after_update_window_line, /*23: added */
+  ns_update_window_begin, /*23: split from update_begin */
+  ns_update_window_end, /*23: split from update_end */
+  x_cursor_to, /*generic OK */
+  ns_flush,
+  0, /* flush_display_optional */
+  x_clear_window_mouse_face, /*generic OK */
+  x_get_glyph_overhangs, /*23: generic OK */
+  x_fix_overlapping_area, /*generic OK */
+  ns_draw_fringe_bitmap, /*23 */
+  0, /* define_fringe_bitmap */ /*PENDING: simplify ns_draw_fringe_bitmap? */
+  0, /* destroy_fringe_bitmap */
+  ns_compute_glyph_string_overhangs, /*23 */
+  ns_draw_glyph_string, /*23: interface to nsfont.m */
+  ns_define_frame_cursor, /*23 */
+  ns_clear_frame_area, /*23 */
+  ns_draw_window_cursor, /*23: revamped ns_dumpcursor */
+  ns_draw_vertical_window_border,
+  ns_shift_glyphs_for_insert
+};
+
+
+static void
+ns_delete_display (struct ns_display_info *dpyinfo)
+{
+  /*PENDING... */
+}
+
+
+/* This function is called when the last frame on a display is deleted. */
+static void
+ns_delete_terminal (struct terminal *terminal)
+{
+  struct ns_display_info *dpyinfo = terminal->display_info.ns;
+  int i;
+
+  /* Protect against recursive calls.  Fdelete_frame in
+     delete_terminal calls us back when it deletes our last frame.  */
+  if (!terminal->name)
+    return;
+
+  BLOCK_INPUT;
+
+  x_destroy_all_bitmaps (dpyinfo);
+  ns_delete_display (dpyinfo);
+  UNBLOCK_INPUT;
+}
+
+
+static struct terminal *
+ns_create_terminal (struct ns_display_info *dpyinfo)
+/* --------------------------------------------------------------------------
+      Set up use of NS before we make the first connection.
+   -------------------------------------------------------------------------- */
+{
+  struct terminal *terminal;
+
+  NSTRACE (ns_create_terminal);
+
+  terminal = create_terminal ();
+
+  terminal->type = output_ns;
+  terminal->display_info.ns = dpyinfo;
+  dpyinfo->terminal = terminal;
+
+  terminal->rif = &ns_redisplay_interface;
+
+  terminal->clear_frame_hook = ns_clear_frame;
+  terminal->ins_del_lines_hook = 0; /* 23: vestigial? */
+  terminal->delete_glyphs_hook = 0; /* 23: vestigial? */
+  terminal->ring_bell_hook = ns_ring_bell;
+  terminal->reset_terminal_modes_hook = ns_reset_terminal_modes;
+  terminal->set_terminal_modes_hook = ns_set_terminal_modes;
+  terminal->update_begin_hook = ns_update_begin;
+  terminal->update_end_hook = ns_update_end;
+  terminal->set_terminal_window_hook = NULL; /* 23: vestigial? */
+  terminal->read_socket_hook = ns_read_socket;
+  terminal->frame_up_to_date_hook = ns_frame_up_to_date;
+  terminal->mouse_position_hook = ns_mouse_position;
+  terminal->frame_rehighlight_hook = ns_frame_rehighlight;
+  terminal->frame_raise_lower_hook = ns_frame_raise_lower;
+
+  terminal->fullscreen_hook = 0; /*XTfullscreen_hook;//23.50 */
+
+  terminal->set_vertical_scroll_bar_hook = ns_set_vertical_scroll_bar;
+  terminal->condemn_scroll_bars_hook = ns_condemn_scroll_bars;
+  terminal->redeem_scroll_bar_hook = ns_redeem_scroll_bar;
+  terminal->judge_scroll_bars_hook = ns_judge_scroll_bars;
+
+  terminal->delete_frame_hook = x_destroy_window;
+  terminal->delete_terminal_hook = ns_delete_terminal;
+
+  terminal->scroll_region_ok = 1;
+  terminal->char_ins_del_ok = 1;
+  terminal->line_ins_del_ok = 1;
+  terminal->fast_clear_end_of_line = 1;
+  terminal->memory_below_frame = 0;
+
+  return terminal;
+}
+
+
+void
+ns_initialize ()
+/* --------------------------------------------------------------------------
+   Mainly vestigial under NS now that ns_create_terminal () does most things.
+   -------------------------------------------------------------------------- */
+{
+  baud_rate = 38400;
+  Fset_input_interrupt_mode (Qt);
+}
+
+
+struct ns_display_info *
+ns_term_init (Lisp_Object display_name)
+/* --------------------------------------------------------------------------
+     Start the Application and get things rolling.
+   -------------------------------------------------------------------------- */
+{
+  extern Lisp_Object Fset_input_mode (Lisp_Object, Lisp_Object,
+                                     Lisp_Object, Lisp_Object);
+  struct terminal *terminal;
+  struct ns_display_info *dpyinfo;
+  static int ns_initialized = 0;
+  Lisp_Object tmp;
+
+  NSTRACE (ns_term_init);
+
+  /* count object allocs (About, click icon); on OS X use ObjectAlloc tool */
+  /*GSDebugAllocationActive (YES); */
+  BLOCK_INPUT;
+handling_signal = 0;
+
+  if (!ns_initialized)
+    {
+      ns_initialize ();
+      ns_initialized = 1;
+    }
+
+  ns_pending_files = [[NSMutableArray alloc] init];
+  ns_pending_service_names = [[NSMutableArray alloc] init];
+  ns_pending_service_args = [[NSMutableArray alloc] init];
+
+  /* Start app and create the main menu, window, view.
+     Needs to be here because ns_initialize_display_info () uses AppKit classes.
+     The view will then ask the NSApp to stop and return to Emacs. */
+  [EmacsApp sharedApplication];
+  if (NSApp == nil)
+    return NULL;
+  [NSApp setDelegate: NSApp];
+
+  /* debugging: log all notifications */
+  /*   [[NSNotificationCenter defaultCenter] addObserver: NSApp
+                                         selector: @selector (logNotification:)
+                                             name: nil object: nil]; */
+
+  dpyinfo = (struct ns_display_info *)xmalloc (sizeof (struct ns_display_info));
+  bzero (dpyinfo, sizeof (struct ns_display_info));
+
+  ns_initialize_display_info (dpyinfo);
+  terminal = ns_create_terminal (dpyinfo);
+
+  terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+  init_kboard (terminal->kboard);
+  terminal->kboard->Vwindow_system = Qns;
+  terminal->kboard->next_kboard = all_kboards;
+  all_kboards = terminal->kboard;
+  /* Don't let the initial kboard remain current longer than necessary.
+     That would cause problems if a file loaded on startup tries to
+     prompt in the mini-buffer.  */
+  if (current_kboard == initial_kboard)
+    current_kboard = terminal->kboard;
+  terminal->kboard->reference_count++;
+
+  dpyinfo->next = ns_display_list;
+  ns_display_list = dpyinfo;
+
+  /* Put it on ns_display_name_list */
+  ns_display_name_list = Fcons (Fcons (display_name, Qnil),
+                                ns_display_name_list);
+/*      ns_display_name_list = Fcons (Fcons (display_name,
+                                           Fcons (Qnil, dpyinfo->xrdb)),
+                                    ns_display_name_list); */
+  dpyinfo->name_list_element = XCAR (ns_display_name_list);
+
+  /* Set the name of the terminal. */
+  terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+  strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+  terminal->name[SBYTES (display_name)] = 0;
+
+  UNBLOCK_INPUT; 
+
+  /* Read various user defaults. */
+  ns_set_default_prefs ();
+  ns_default ("AlternateModifier", &ns_alternate_modifier,
+             Qnil, Qnil, NO, YES);
+  if (NILP (ns_alternate_modifier))
+    ns_alternate_modifier = Qmeta;
+  ns_default ("CommandModifier", &ns_command_modifier,
+             Qnil, Qnil, NO, YES);
+  if (NILP (ns_command_modifier))
+    ns_command_modifier = Qsuper;
+  ns_default ("ControlModifier", &ns_control_modifier,
+             Qnil, Qnil, NO, YES);
+  if (NILP (ns_control_modifier))
+    ns_control_modifier = Qcontrol;
+  ns_default ("FunctionModifier", &ns_function_modifier,
+             Qnil, Qnil, NO, YES);
+  if (NILP (ns_function_modifier))
+    ns_function_modifier = Qnone;
+  ns_default ("CursorBlinkRate", &ns_cursor_blink_rate,
+             make_float (0.5), Qnil, YES, NO);
+  if (NUMBERP (ns_cursor_blink_rate))
+    ns_cursor_blink_mode = Qt;
+  ns_default ("ExpandSpace", &ns_expand_space,
+             make_float (0.5), make_float (0.0), YES, NO);
+  ns_default ("GSFontAntiAlias", &ns_antialias_text,
+             YES, NO, NO, NO);
+  tmp = Qnil;
+  ns_default ("AppleAntiAliasingThreshold", &tmp,
+             make_float (10.0), make_float (6.0), YES, NO);
+  ns_antialias_threshold = NILP (tmp) ? 10.0 : XFLOATINT (tmp);
+  ns_default ("UseQuickdrawSmoothing", &ns_use_qd_smoothing,
+             YES, NO, NO, NO);
+  ns_default ("UseSystemHighlightColor", &ns_use_system_highlight_color,
+             YES, NO, NO, NO);
+  if (ns_use_system_highlight_color == YES)
+    {
+      ns_selection_color = [[NSUserDefaults standardUserDefaults]
+                               stringForKey: @"AppleHighlightColor"];
+      if (ns_selection_color == nil)
+        ns_selection_color = NS_SELECTION_COLOR_DEFAULT;
+    }
+  else
+    ns_selection_color = NS_SELECTION_COLOR_DEFAULT;
+
+  {
+    id cl;
+    Lisp_Object tem, tem1;
+    extern Lisp_Object Vsource_directory;
+
+    cl = [NSColorList colorListNamed: @"Emacs"];
+
+    if ( cl == nil )
+      {
+        /* first try data_dir, then invocation-dir
+           and finally source-directory/etc */
+        tem1 = tem =
+          Fexpand_file_name (build_string ("Emacs.clr"), Vdata_directory);
+        if (NILP (Ffile_exists_p (tem)))
+          {
+            tem = Fexpand_file_name (build_string ("Emacs.clr"),
+                                     Vinvocation_directory);
+            if (NILP (Ffile_exists_p (tem)))
+              {
+                Lisp_Object newdir =
+                  Fexpand_file_name (build_string ("etc/"),
+                                     Vsource_directory);
+                tem = Fexpand_file_name (build_string ("Emacs.clr"),
+                                         newdir);
+              }
+          }
+
+        cl = [[NSColorList alloc]
+               initWithName: @"Emacs"
+                   fromFile: [NSString stringWithCString: XSTRING (tem)->data]];
+        if (cl ==nil)
+          fatal ("Could not find %s.\n", XSTRING (tem1)->data);
+        [cl writeToFile: nil];
+      }
+  }
+
+  {
+    char c[128];
+#ifdef NS_IMPL_GNUSTEP
+    strncpy (c, gnustep_base_version, sizeof (c));
+#else
+    /*PSnextrelease (128, c); */
+    snprintf (c, sizeof (c), "%g", NSAppKitVersionNumber);
+#endif
+    Vwindow_system_version = build_string (c);
+  }
+
+  delete_keyboard_wait_descriptor (0);
+
+/* Set up OS X app menu */
+#ifdef NS_IMPL_COCOA
+  {
+    NSMenu *appMenu;
+    id<NSMenuItem> item;
+    /* set up the application menu */
+    svcsMenu = [[EmacsMenu alloc] initWithTitle: @"Services"];
+    [svcsMenu setAutoenablesItems: NO];
+    appMenu = [[EmacsMenu alloc] initWithTitle: @"Emacs"];
+    [appMenu setAutoenablesItems: NO];
+    mainMenu = [[EmacsMenu alloc] initWithTitle: @""];
+
+    [appMenu insertItemWithTitle: @"About Emacs"
+                          action: @selector (orderFrontStandardAboutPanel:)
+                   keyEquivalent: @""
+                         atIndex: 0];
+    [appMenu insertItem: [NSMenuItem separatorItem] atIndex: 1];
+    [appMenu insertItemWithTitle: @"Preferences..."
+                          action: @selector (showPreferencesWindow:)
+                   keyEquivalent: @","
+                         atIndex: 2];
+    [appMenu insertItem: [NSMenuItem separatorItem] atIndex: 3];
+    item = [appMenu insertItemWithTitle: @"Services"
+                                 action: @selector (menuDown:)
+                          keyEquivalent: @""
+                                atIndex: 4];
+    [appMenu setSubmenu: svcsMenu forItem: item];
+/*    [svcsMenu setSupercell: item]; */
+    [appMenu insertItem: [NSMenuItem separatorItem] atIndex: 5];
+    [appMenu insertItemWithTitle: @"Hide Emacs"
+                          action: @selector (hide:)
+                   keyEquivalent: @"h"
+                         atIndex: 6];
+    item =  [appMenu insertItemWithTitle: @"Hide Others"
+                          action: @selector (hideOtherApplications:)
+                   keyEquivalent: @"h"
+                         atIndex: 7];
+    [item setKeyEquivalentModifierMask: NSCommandKeyMask | NSAlternateKeyMask];
+    [appMenu insertItem: [NSMenuItem separatorItem] atIndex: 8];
+    [appMenu insertItemWithTitle: @"Quit Emacs"
+                          action: @selector (terminate:)
+                   keyEquivalent: @"q"
+                         atIndex: 9];
+
+    item = [mainMenu insertItemWithTitle: @"Emacs"
+                                  action: @selector (menuDown:)
+                           keyEquivalent: @""
+                                 atIndex: 0];
+    [mainMenu setSubmenu: appMenu forItem: item];
+
+    [NSApp setMainMenu: mainMenu];
+    [NSApp setAppleMenu: appMenu];
+    [NSApp setServicesMenu: svcsMenu];
+    /* Needed at least on Cocoa, to get dock menu to show windows */
+    [NSApp setWindowsMenu: [[NSMenu alloc] init]];
+  }
+#endif /* MAC OS X menu setup */
+
+  [NSApp run];
+
+  return dpyinfo;
+}
+
+
+extern Lisp_Object Vauto_save_list_file_name;
+void
+ns_term_shutdown (int sig)
+{
+  /* code not reached in emacs.c after this is called by shut_down_emacs: */
+  if (STRINGP (Vauto_save_list_file_name))
+    unlink (XSTRING (Vauto_save_list_file_name)->data);
+
+  ns_shutdown_properly = YES;
+  [NSApp terminate: NSApp];
+}
+
+
+void
+syms_of_nsterm ()
+{
+  NSTRACE (syms_of_nsterm);
+  DEFVAR_LISP ("ns-input-file", &ns_input_file,
+              "The file specified in the last NS event.");
+  ns_input_file =Qnil;
+
+  DEFVAR_LISP ("ns-input-text", &ns_input_text,
+              "The data received in the last NS text drag event.");
+  ns_input_text =Qnil;
+
+  DEFVAR_LISP ("ns-working-text", &ns_working_text,
+              "String for visualizing working composition sequence.");
+  ns_working_text =Qnil;
+
+  DEFVAR_LISP ("ns-input-font", &ns_input_font,
+              "The font specified in the last NS event.");
+  ns_input_font =Qnil;
+
+  DEFVAR_LISP ("ns-input-fontsize", &ns_input_fontsize,
+              "The fontsize specified in the last NS event.");
+  ns_input_fontsize =Qnil;
+
+  DEFVAR_LISP ("ns-input-line", &ns_input_line,
+               "The line specified in the last NS event.");
+  ns_input_line =Qnil;
+
+  DEFVAR_LISP ("ns-input-color", &ns_input_color,
+               "The color specified in the last NS event.");
+  ns_input_color =Qnil;
+
+  DEFVAR_LISP ("ns-input-spi-name", &ns_input_spi_name,
+               "The service name specified in the last NS event.");
+  ns_input_spi_name =Qnil;
+
+  DEFVAR_LISP ("ns-input-spi-arg", &ns_input_spi_arg,
+               "The service argument specified in the last NS event.");
+  ns_input_spi_arg =Qnil;
+
+  DEFVAR_LISP ("ns-alternate-modifier", &ns_alternate_modifier,
+               "This variable describes the behavior of the alternate or option key.\n\
+Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\
+Set to none means that the alternate / option key is not interpreted by Emacs\n\
+at all, allowing it to be used at a lower level for accented character entry.");
+
+  DEFVAR_LISP ("ns-command-modifier", &ns_command_modifier,
+               "This variable describes the behavior of the command key.\n\
+Set to control, meta, alt, super, or hyper means it is taken to be that key.");
+
+  DEFVAR_LISP ("ns-control-modifier", &ns_control_modifier,
+               "This variable describes the behavior of the control key.\n\
+Set to control, meta, alt, super, or hyper means it is taken to be that key.");
+
+  DEFVAR_LISP ("ns-function-modifier", &ns_function_modifier,
+               "This variable describes the behavior of the function key (on laptops).\n\
+Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\
+Set to none means that the function key is not interpreted by Emacs at all,\n\
+allowing it to be used at a lower level for accented character entry.");
+
+  DEFVAR_LISP ("ns-cursor-blink-rate", &ns_cursor_blink_rate,
+               "Rate at which the Emacs cursor blinks (in seconds).\n\
+Set to nil to disable blinking.");
+
+  DEFVAR_LISP ("ns-cursor-blink-mode", &ns_cursor_blink_mode,
+               "Internal variable -- use M-x blink-cursor-mode or preferences\n\
+panel to control this setting.");
+
+  DEFVAR_LISP ("ns-expand-space", &ns_expand_space,
+               "Amount by which spacing between lines is expanded (positive)\n\
+or shrunk (negative).  Zero (the default) means standard line height.\n\
+(This variable should only be read, never set.)");
+
+  DEFVAR_BOOL ("ns-antialias-text", &ns_antialias_text,
+               "Non-nil (the default) means to render text antialiased. Only has an effect on OS X Panther and above.");
+
+  DEFVAR_BOOL ("ns-use-qd-smoothing", &ns_use_qd_smoothing,
+               "Whether to render text using QuickDraw (less heavy) antialiasing. Only has an effect on OS X Panther and above.  Default is nil (use Quartz smoothing).");
+
+  DEFVAR_BOOL ("ns-use-system-highlight-color",
+               &ns_use_system_highlight_color,
+               "Whether to use the system default (on OS X only) for the highlight color.  Nil means to use standard emacs (prior to version 21) 'grey'.");
+
+  staticpro (&ns_display_name_list);
+  ns_display_name_list = Qnil;
+
+  staticpro (&last_mouse_motion_frame);
+  last_mouse_motion_frame = Qnil;
+
+/*23: now apparently we need to tell emacs what modifiers there are.. */
+  Qmodifier_value = intern ("modifier-value");
+  Qalt = intern ("alt");
+  Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
+  Qhyper = intern ("hyper");
+  Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
+  Qmeta = intern ("meta");
+  Fput (Qmeta, Qmodifier_value, make_number (meta_modifier));
+  Qsuper = intern ("super");
+  Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
+  Qcontrol = intern ("control");
+  Fput (Qcontrol, Qmodifier_value, make_number (ctrl_modifier));
+
+  /*PENDING: move to common code */
+  DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
+	       doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+  Vx_toolkit_scroll_bars = Qt; 
+#else
+  Vx_toolkit_scroll_bars = Qnil;
+#endif
+
+  /* these are unsupported but we need the declarations to avoid whining
+     messages from cus-start.el */
+  DEFVAR_BOOL ("x-use-underline-position-properties",
+	       &x_use_underline_position_properties,
+     doc: /* NOT SUPPORTED UNDER NS.
+*Non-nil means make use of UNDERLINE_POSITION font properties.
+A value of nil means ignore them.  If you encounter fonts with bogus
+UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
+to 4.1, set this to nil.
+
+NOTE: Not supported on Mac yet.  */);
+  x_use_underline_position_properties = 0;
+
+  DEFVAR_BOOL ("x-underline-at-descent-line",
+	       &x_underline_at_descent_line,
+     doc: /* NOT SUPPORTED UNDER NS.
+*Non-nil means to draw the underline at the same place as the descent line.
+A value of nil means to draw the underline according to the value of the
+variable `x-use-underline-position-properties', which is usually at the
+baseline level.  The default value is nil.  */);
+  x_underline_at_descent_line = 0;
+
+  /* Tell emacs about this window system. */
+  Fprovide (intern ("ns-windowing"), Qnil);
+  /* PENDING: try to move this back into lisp (ns-win.el loaded too late
+              right now */
+  {
+    Lisp_Object args[3] = { intern ("ns-version-string"), build_string ("9.0"),
+                    build_string ("NS Window system port version number.") };
+    Fdefconst (Flist (3, args));
+  }
+}
+
+
+
+/* ==========================================================================
+
+    EmacsApp implementation
+
+   ========================================================================== */
+
+
+@implementation EmacsApp
+
+- (void)logNotification: (NSNotification *)notification
+{
+  const char *name = [[notification name] UTF8String];
+  if (!strstr (name, "Update") && !strstr (name, "NSMenu")
+      && !strstr (name, "WindowNumber"))
+    NSLog (@"notification: '%@'", [notification name]);
+}
+
+
+- (void)sendEvent: (NSEvent *)theEvent
+/* --------------------------------------------------------------------------
+     Events posted by ns_send_appdefined interrupt the run loop here
+   -------------------------------------------------------------------------- */
+{
+  int type = [theEvent type];
+  NSWindow *window = [theEvent window];
+/*  NSTRACE (sendEvent); */
+/*fprintf (stderr, "received event of type %d\n", [theEvent type]); */
+
+  if (type == NSCursorUpdate && window == nil)
+    {
+      fprintf (stderr, "Dropping external cursor update event.\n");
+      return;
+    }
+
+#ifdef NS_IMPL_COCOA
+  /* pass mouse down in resize handle and subsequent drags directly to
+     EmacsWindow so we can generate continuous redisplays */
+  if (ns_in_resize)
+    {
+      if (type == NSLeftMouseDragged)
+        {
+          [window mouseDragged: theEvent];
+          return;
+        }
+      else if (type == NSLeftMouseUp)
+        {
+          [window mouseUp: theEvent];
+          return;
+        }
+    }
+  else if (type == NSLeftMouseDown)
+    {
+      NSRect r = ns_resize_handle_rect (window);
+      if (NSPointInRect ([theEvent locationInWindow], r))
+        {
+          ns_in_resize = YES;
+          [window mouseDown: theEvent];
+          return;
+        }
+    }
+#endif
+
+  if (type == NSApplicationDefined)
+    {
+      last_appdefined_event = theEvent;
+      [self stop: self];
+    }
+
+  [super sendEvent: theEvent];
+}
+
+
+- (void)showPreferencesWindow: (id)sender
+{
+  if (prefsController == nil)
+    prefsController = [[EmacsPrefsController alloc] init];
+  [prefsController showForFrame: SELECTED_FRAME ()];
+}
+
+
+/* **************************************************************************
+
+      EmacsApp delegate implementation
+
+   ************************************************************************** */
+
+- (void)applicationDidFinishLaunching: (NSNotification *)notification
+/* --------------------------------------------------------------------------
+     When application is loaded, terminate event loop in ns_term_init
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (applicationDidFinishLaunching);
+  [NSApp setServicesProvider: NSApp];
+  ns_send_appdefined (-2);
+}
+ 
+
+- (void) terminate: (id)sender
+{
+  BLOCK_INPUT;
+  if (ns_shutdown_properly)
+    [super terminate: sender];
+  else
+    {
+/*    Fkill_emacs (Qnil); */
+      ns_shutdown_properly = YES;
+      Feval (Fcons (intern ("save-buffers-kill-emacs"), Qnil));
+    }
+  UNBLOCK_INPUT;
+}
+
+
+- (NSApplicationTerminateReply)applicationShouldTerminate: (id)sender
+{
+  if (ns_shutdown_properly)
+    return NSTerminateNow;
+
+  Lisp_Object contents = list3 (build_string ("Exit requested.  Would you like to Save Buffers and Exit, or Cancel the request?"),
+      Fcons (build_string ("Cancel"), Qnil),
+      Fcons (build_string ("Save and Exit"), Qt));
+  Lisp_Object res = ns_popup_dialog (Qt, contents, Qnil);
+fprintf (stderr, "res = %d\n", res ==Qt);
+  if (res == Qt)
+    {
+      Feval (Fcons (intern ("save-buffers-kill-emacs"), Qnil));
+      return NSTerminateNow;
+    }
+  return NSTerminateCancel;
+}
+
+
+/* Open a file (used by below, after going into queue read by ns_read_socket) */
+-(BOOL) openFile: (NSString *)fileName
+{
+  struct frame *emacsframe = SELECTED_FRAME ();
+  NSEvent *theEvent = [NSApp currentEvent];
+
+  if (!emacs_event)
+    return NO;
+
+  emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+  emacs_event->code = KEY_NS_OPEN_FILE_LINE;
+  ns_input_file = append2 (ns_input_file, build_string ([fileName UTF8String]));
+  ns_input_line = Qnil; /* can be start or cons start,end */
+  emacs_event->modifiers =0;
+  EV_TRAILER (theEvent);
+
+  return YES;
+}
+
+
+/*   Notification from the Workspace to open a file */
+- (BOOL)application: sender openFile: (NSString *)file
+{
+  [ns_pending_files addObject: file];
+  return YES;
+}
+
+
+/*   Open a file as a temporary file */
+- (BOOL)application: sender openTempFile: (NSString *)file
+{
+  [ns_pending_files addObject: file];
+  return YES;
+}
+
+
+/*   Notification from the Workspace to open a file noninteractively (?) */
+- (BOOL)application: sender openFileWithoutUI: (NSString *)file
+{
+  [ns_pending_files addObject: file];
+  return YES;
+}
+
+
+/*   Notification from the Workspace to open multiple files */
+- (void)application: sender openFiles: (NSArray *)fileList
+{
+  NSEnumerator *files = [fileList objectEnumerator];
+  NSString *file;
+  while ((file = [files nextObject]) != nil)
+    [ns_pending_files addObject: file];
+  return YES;
+}
+
+/*PENDING: these may help w/IO switching btwn terminal and NSApp */
+- (void)applicationDidBecomeActive: (NSNotification *)notification
+{
+}
+- (void)applicationDidResignActive: (NSNotification *)notification
+{
+  ns_send_appdefined (-1);
+}
+
+
+
+/* ==========================================================================
+
+    EmacsApp aux handlers for managing event loop
+
+   ========================================================================== */
+
+
+- (void)timeout_handler: (NSTimer *)timedEntry
+/* --------------------------------------------------------------------------
+     The timeout specified to ns_select has passed.
+   -------------------------------------------------------------------------- */
+{
+  /*NSTRACE (timeout_handler); */
+  ns_send_appdefined (-2);
+}
+
+extern void update_window_cursor (struct window *w, int on);
+
+- (void)cursor_blink_handler: (NSTimer *)cursorEntry
+/* --------------------------------------------------------------------------
+     Flash the cursor
+   -------------------------------------------------------------------------- */
+{
+  struct ns_display_info *dpyinfo = ns_display_list; /*HACK, but OK for now */
+  struct frame *f = dpyinfo->ns_highlight_frame;
+  NSTRACE (cursor_blink_handler);
+
+  if (!f)
+    return;
+  if (f->output_data.ns->current_cursor == no_highlight)
+    {
+      Lisp_Object tem = get_frame_param (f, Qcursor_type);
+      f->output_data.ns->desired_cursor = ns_lisp_to_cursor_type (tem);
+    }
+  else
+    {
+      f->output_data.ns->desired_cursor = no_highlight;
+    }
+  update_window_cursor (XWINDOW (FRAME_SELECTED_WINDOW (f)), 1);
+  /*x_update_cursor (f, 1); */
+}
+
+
+- (void)fd_handler: (NSTimer *) fdEntry
+/* --------------------------------------------------------------------------
+     Check data waiting on file descriptors and terminate if so
+   -------------------------------------------------------------------------- */
+{
+  int result;
+  /* NSTRACE (fd_handler); */
+
+  if (select_nfds == 0)
+    return;
+
+  memcpy (&t_readfds, &select_readfds, sizeof (fd_set));
+
+  select_timeout.tv_sec = select_timeout.tv_usec = 0;
+  result = select (select_nfds, &t_readfds, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
+                  &select_timeout);
+  if (result)
+    {
+      memcpy (&select_readfds, &t_readfds, sizeof (fd_set));
+      ns_send_appdefined (result);
+    }
+}
+
+
+
+/* ==========================================================================
+
+    Service provision
+
+   ========================================================================== */
+
+/* called from system: queue for next pass through event loop */
+- (void)requestService: (NSPasteboard *)pboard
+              userData: (NSString *)userData
+                 error: (NSString **)error
+{
+  [ns_pending_service_names addObject: userData];
+  [ns_pending_service_args addObject: [NSString stringWithUTF8String:
+      SDATA (ns_string_from_pasteboard (pboard))]];
+}
+
+
+/* called from ns_read_socket to clear queue */
+- (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg
+{
+  struct frame *emacsframe = SELECTED_FRAME ();
+  NSEvent *theEvent = [NSApp currentEvent];
+
+  if (!emacs_event)
+    return NO;
+
+  emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+  emacs_event->code = KEY_NS_SPI_SERVICE_CALL;
+  ns_input_spi_name = build_string ([name UTF8String]);
+  ns_input_spi_arg = build_string ([arg UTF8String]);
+  emacs_event->modifiers = EV_MODIFIERS (theEvent);
+  EV_TRAILER (theEvent);
+
+  return YES;
+}
+
+
+@end  /* EmacsApp */
+
+
+
+/* ==========================================================================
+
+    EmacsView implementation
+
+   ========================================================================== */
+
+
+@implementation EmacsView
+
+/* needed to inform when window closed from LISP */
+- (void) setWindowClosing: (BOOL)closing
+{
+  windowClosing = closing;
+}
+
+
+- (void)dealloc
+{
+  NSTRACE (EmacsView_dealloc);
+  [toolbar release];
+  [super dealloc];
+}
+
+
+/* called on font panel selection */
+- (void)changeFont: (id)sender
+{
+  NSEvent *e =[[self window] currentEvent];
+  struct face *face =FRAME_DEFAULT_FACE (emacsframe);
+  id newFont;
+  float size;
+
+  NSTRACE (changeFont);
+  if (!emacs_event)
+    return;
+
+  if (newFont = [sender convertFont:
+                           ((struct nsfont_info *)face->font)->nsfont])
+    {
+      emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+      emacs_event->modifiers = 0;
+      emacs_event->code = KEY_NS_CHANGE_FONT;
+
+      size = [newFont pointSize];
+      /* PENDING: stick w/integer sizes for now. */
+/*        if (size == lrint (size)) */
+        ns_input_fontsize = make_number (lrint (size));
+/*          else
+            ns_input_fontsize = make_float (size); */
+      ns_input_font = build_string ([[newFont familyName] UTF8String]);
+      EV_TRAILER (e);
+    }
+}
+
+
+- (BOOL)acceptsFirstResponder
+{
+  NSTRACE (acceptsFirstResponder);
+  return YES;
+}
+
+
+- (void)resetCursorRects
+{
+  NSRect visible = [self visibleRect];
+  NSCursor *currentCursor = FRAME_POINTER_TYPE (emacsframe);
+  NSTRACE (resetCursorRects);
+
+  if (currentCursor == nil)
+    currentCursor = [NSCursor arrowCursor];
+
+  if (!NSIsEmptyRect (visible))
+    [self addCursorRect: visible cursor: currentCursor];
+  [currentCursor setOnMouseEntered: YES];
+}
+
+
+/*****************************************************************************/
+/* Keyboard handling. */
+#define NS_KEYLOG 0
+
+- (void)keyDown: (NSEvent *)theEvent
+{
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
+  int code;
+  unsigned fnKeysym = 0;
+  int flags;
+  static NSMutableArray *nsEvArray;
+  static BOOL firstTime = YES;
+
+  NSTRACE (keyDown);
+
+  /* Rhapsody and OS X give up and down events for the arrow keys */
+  if ([theEvent type] != NSKeyDown)
+    return;
+
+  if (!emacs_event)
+    return;
+
+/*#if defined (COCOA_EXPERIMENTAL_CTRL_G) */
+ if (![[self window] isKeyWindow])
+   {
+     /* PENDING: Using NO_SOCK_SIGIO like Carbon causes a condition in which,
+        when Emacs display updates a different frame from the current one,
+        and temporarily selects it, then processes some interrupt-driven
+        input (dispnew.c:3878), OS will send the event to the correct NSWindow,
+        but for some reason that window has its first responder set to the
+        NSView most recently updated (I guess), which is not the correct one.
+        UPDATE: After multi-TTY merge this happens even w/o NO_SOCK_SIGIO */
+     if ([[theEvent window] isKindOfClass: [EmacsWindow class]])
+         [[(EmacsView *)[theEvent window] delegate] keyDown: theEvent];
+     return;
+   }
+/*#endif */
+
+  if (nsEvArray == nil)
+    nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
+
+  [NSCursor setHiddenUntilMouseMoves: YES];
+
+  if (dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+    {
+      clear_mouse_face (dpyinfo);
+      dpyinfo->mouse_face_hidden = 1;
+    }
+
+  if (!processingCompose)
+    {
+      code = ([[theEvent charactersIgnoringModifiers] length] == 0) ?
+        0 : [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];
+      /* (Carbon way: [theEvent keyCode]) */
+
+      /* is it a "function key"? */
+      fnKeysym = ns_convert_key (code);
+      if (fnKeysym)
+        {
+          /* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace',
+             because Emacs treats Delete and KP-Delete same (in simple.el). */
+          if (fnKeysym == 0xFFFF && [theEvent keyCode] == 0x33)
+            code = 0xFF08; /* backspace */
+          else
+            code = fnKeysym;
+        }
+
+      /* are there modifiers? */
+      emacs_event->modifiers = 0;
+      flags = [theEvent modifierFlags];
+
+      if (flags & NSHelpKeyMask)
+          emacs_event->modifiers |= hyper_modifier;
+
+      if (flags & NSShiftKeyMask)
+        emacs_event->modifiers |= shift_modifier;
+
+      if (flags & NSCommandKeyMask)
+        {
+          emacs_event->modifiers |= lisp_to_mod (ns_command_modifier);
+          /* if super (default), take input manager's word so things like
+             dvorak / qwerty layout work */
+          if (EQ (ns_command_modifier, Qsuper)
+              && !fnKeysym
+              && [[theEvent characters] length] != 0)
+            {
+              /* PENDING: the code we get will be unshifted, so if we have
+                 a shift modifier, must convert ourselves */
+              if (!(flags & NSShiftKeyMask))
+                code = [[theEvent characters] characterAtIndex: 0];
+#if 0
+              /* this is ugly and also requires linking w/Carbon framework
+                 (for LMGetKbdType) so for now leave this rare (?) case
+                 undealt with.. in future look into CGEvent methods */
+              else
+                {
+                  long smv = GetScriptManagerVariable (smKeyScript);
+                  Handle uchrHandle = GetResource
+                    ('uchr', GetScriptVariable (smv, smScriptKeys));
+                  UInt32 dummy = 0;
+                  UCKeyTranslate ((UCKeyboardLayout*)*uchrHandle,
+                                 [[theEvent characters] characterAtIndex: 0],
+                                 kUCKeyActionDisplay,
+                                 (flags & ~NSCommandKeyMask) >> 8,
+                                 LMGetKbdType (), kUCKeyTranslateNoDeadKeysMask,
+                                 &dummy, 1, &dummy, &code);
+                  code &= 0xFF;
+                }
+#endif
+            }
+        }
+
+      if (flags & NSControlKeyMask)
+          emacs_event->modifiers |= lisp_to_mod (ns_control_modifier);
+
+      if (flags & NS_FUNCTION_KEY_MASK && !fnKeysym)
+          emacs_event->modifiers |= lisp_to_mod (ns_function_modifier);
+
+      if (flags & NSAlternateKeyMask) /* default = meta */
+        {
+          if (EQ (ns_alternate_modifier, Qnone) && !fnKeysym)
+            {   /* accept pre-interp alt comb */
+              if ([[theEvent characters] length] > 0)
+                code = [[theEvent characters] characterAtIndex: 0];
+              /*HACK: clear lone shift modifier to stop next if from firing */
+              if (emacs_event->modifiers == shift_modifier)
+                emacs_event->modifiers = 0;
+            }
+          else
+              emacs_event->modifiers |= lisp_to_mod (ns_alternate_modifier);
+        }
+
+/*fprintf (stderr,"code =%x\tfnKey =%x\tflags = %x\tmods = %x\n",code,fnKeysym,flags,emacs_event->modifiers); */
+
+      /* if it was a function key or had modifiers, pass it directly to emacs */
+      if (fnKeysym || (emacs_event->modifiers
+                       && [[theEvent charactersIgnoringModifiers] length] > 0))
+/*[[theEvent characters] length] */
+        {
+          emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+          if (code < 0x20)
+            code |= (1<<28)|(3<<16);
+          else if (code == 0x7f)
+            code |= (1<<28)|(3<<16);
+          else if (!fnKeysym)
+            emacs_event->kind = code > 0xFF
+              ? MULTIBYTE_CHAR_KEYSTROKE_EVENT : ASCII_KEYSTROKE_EVENT;
+
+          emacs_event->code = code;
+          EV_TRAILER (theEvent);
+          return;
+        }
+    }
+
+  /* if we get here we should send the key for input manager processing */
+  if (firstTime && [[NSInputManager currentInputManager]
+                     wantsToDelayTextChangeNotifications] == NO)
+    fprintf (stderr,
+          "Emacs: WARNING: TextInput mgr wants marked text to be permanent!\n");
+  firstTime = NO;
+
+  if (NS_KEYLOG && !processingCompose)
+    fprintf (stderr, "Begin compose sequence.\n");
+
+  processingCompose = YES;
+  [nsEvArray addObject: theEvent];
+  [self interpretKeyEvents: nsEvArray];
+  [nsEvArray removeObject: theEvent];
+}
+
+
+/* <NSTextInput> implementation (called through super interpretKeyEvents:]). */
+
+
+/* <NSTextInput>: called through when done composing */
+- (void)insertText: (id)aString
+{
+  int code;
+  int len = [(NSString *)aString length];
+  int i;
+
+if (NS_KEYLOG) NSLog (@"insertText '%@'\tlen = %d", aString, len);
+  processingCompose = NO;
+
+  if (!emacs_event)
+    return;
+
+  /* first, clear any working text */
+  if (workingText != nil)
+    [self deleteWorkingText];
+
+  /* now insert the string as keystrokes */
+  for (i =0; i<len; i++)
+    {
+      code = [aString characterAtIndex: i];
+      /* PENDING: still need this? */
+      if (code == 0x2DC)
+        code = '~'; /* 0x7E */
+      emacs_event->modifiers = 0;
+      emacs_event->kind =
+        code > 0xFF ? MULTIBYTE_CHAR_KEYSTROKE_EVENT : ASCII_KEYSTROKE_EVENT;
+      emacs_event->code = code;
+      EV_TRAILER ((id)nil);
+    }
+}
+
+
+/* <NSTextInput>: inserts display of composing characters */
+- (void)setMarkedText: (id)aString selectedRange: (NSRange)selRange
+{
+  NSString *str = [aString respondsToSelector: @selector (string)] ?
+    [aString string] : aString;
+  if (NS_KEYLOG)
+    NSLog (@"setMarkedText '%@' len =%d range %d from %d", str, [str length],
+           selRange.length, selRange.location);
+
+  if (workingText != nil)
+    [self deleteWorkingText];
+  if ([str length] == 0)
+    return;
+
+  if (!emacs_event)
+    return;
+
+  processingCompose = YES;
+  workingText = [str copy];
+  ns_working_text = build_string ([workingText UTF8String]);
+
+  /* if in "echo area", not true minibuffer, can't show chars in interactive
+     mode, so call using eval; otherwise we send a key event, which was the
+     original way this was done */
+  if (!EQ (Feval (Fcons (intern ("ns-in-echo-area"), Qnil)), Qnil))
+    {
+      Feval (Fcons (intern ("ns-echo-working-text"), Qnil));
+      ns_send_appdefined (-1);
+    }
+  else
+    {
+      emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+      emacs_event->code = KEY_NS_INSERT_WORKING_TEXT;
+      EV_TRAILER ((id)nil);
+    }
+}
+
+
+/* delete display of composing characters [not in <NSTextInput>] */
+- (void)deleteWorkingText
+{
+  if (workingText == nil)
+    return;
+  if (NS_KEYLOG)
+    fprintf (stderr, "deleteWorkingText len =%d\n", [workingText length]);
+  [workingText release];
+  workingText = nil;
+  processingCompose = NO;
+
+  if (!emacs_event)
+    return;
+
+  if (!EQ (Feval (Fcons (intern ("ns-in-echo-area"), Qnil)), Qnil))
+    {
+      Feval (Fcons (intern ("ns-unecho-working-text"), Qnil));
+      ns_send_appdefined (-1);
+    }
+  else
+    {
+      emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+      emacs_event->code = KEY_NS_DELETE_WORKING_TEXT;
+      EV_TRAILER ((id)nil);
+    }
+ }
+
+
+- (BOOL)hasMarkedText
+{
+  return workingText != nil;
+}
+
+- (NSRange)markedRange
+{
+  NSRange rng = workingText != nil
+    ? NSMakeRange (0, [workingText length]) : NSMakeRange (NSNotFound, 0);
+if (NS_KEYLOG) NSLog (@"markedRange request");
+  return rng;
+}
+
+- (void)unmarkText
+{
+if (NS_KEYLOG) NSLog (@"unmark (accept) text");
+  [self deleteWorkingText];
+  processingCompose = NO;
+}
+
+/* used to position char selection windows, etc. */
+- (NSRect)firstRectForCharacterRange: (NSRange)theRange
+{
+  NSRect rect;
+  NSPoint pt;
+  struct window *win = XWINDOW (FRAME_SELECTED_WINDOW (emacsframe));
+if (NS_KEYLOG) NSLog (@"firstRectForCharRange request");
+
+  rect.size.width = theRange.length * FRAME_COLUMN_WIDTH (emacsframe);
+  rect.size.height = FRAME_LINE_HEIGHT (emacsframe);
+  pt.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (win, win->phys_cursor.x);
+  pt.y = WINDOW_TO_FRAME_PIXEL_Y (win, win->phys_cursor.y
+                                       +FRAME_LINE_HEIGHT (emacsframe));
+
+  pt = [self convertPoint: pt toView: nil];
+  pt = [[self window] convertBaseToScreen: pt];
+  rect.origin = pt;
+  return rect;
+}
+
+- (long)conversationIdentifier
+{
+  return (long)self;
+}
+
+/*PENDING: below here not yet implemented correctly, but may not be needed */
+
+- (void)doCommandBySelector: (SEL)aSelector
+{
+  if (NS_KEYLOG) NSLog (@"Do command by selector: %@",
+                       NSStringFromSelector (aSelector));
+
+  if (aSelector == @selector (deleteBackward:))
+    {
+      /* happens when user backspaces over an ongoing composition:
+         throw a 'delete' into the event queue */
+      if (!emacs_event)
+        return;
+      emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+      emacs_event->code = 0xFF08;
+      EV_TRAILER ((id)nil);
+    }
+}
+
+- (NSArray *)validAttributesForMarkedText
+{
+  static NSArray *arr = nil;
+  if (arr == nil) arr = [NSArray new];
+ /* [[NSArray arrayWithObject: NSUnderlineStyleAttributeName] retain]; */
+  return arr;
+}
+
+- (NSRange)selectedRange
+{
+if (NS_KEYLOG) NSLog (@"selectedRange request");
+  return NSMakeRange (NSNotFound, 0);
+}
+
+- (unsigned int)characterIndexForPoint: (NSPoint)thePoint
+{
+if (NS_KEYLOG) NSLog (@"characterIndexForPoint request");
+  return 0;
+}
+
+- (NSAttributedString *)attributedSubstringFromRange: (NSRange)theRange
+{
+  static NSAttributedString *str = nil;
+  if (str == nil) str = [NSAttributedString new];
+if (NS_KEYLOG) NSLog (@"attributedSubstringFromRange request");
+  return str;
+}
+
+/* End <NSTextInput> impl. */
+/*****************************************************************************/
+
+
+/* This is what happens when the user presses a mouse button.  */
+- (void)mouseDown: (NSEvent *)theEvent
+{
+  NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
+  Lisp_Object window;
+
+  NSTRACE (mouseDown);
+
+  [self deleteWorkingText];
+
+  if (!emacs_event)
+    return;
+
+  last_mouse_frame = emacsframe;
+  /* appears to be needed to prevent spurious movement events generated on
+     button clicks */
+  last_mouse_frame->mouse_moved = 0;
+
+  if ([theEvent type] == NSScrollWheel)
+    {
+      float delta = [theEvent deltaY];
+      /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
+      if (delta == 0)
+        return;
+      emacs_event->kind = WHEEL_EVENT;
+      emacs_event->code = 0;
+      emacs_event->modifiers = EV_MODIFIERS (theEvent) |
+        ((delta > 0) ? up_modifier : down_modifier);
+    }
+  else
+    {
+      emacs_event->kind = MOUSE_CLICK_EVENT;
+      emacs_event->code = EV_BUTTON (theEvent);
+      emacs_event->modifiers = EV_MODIFIERS (theEvent)
+                             | EV_UDMODIFIERS (theEvent);
+    }
+  XSETINT (emacs_event->x, lrint (p.x));
+  XSETINT (emacs_event->y, lrint (p.y));
+  EV_TRAILER (theEvent);
+}
+
+
+- (void)mouseUp: (NSEvent *)theEvent
+{
+  NSTRACE (mouseUp);
+  [self mouseDown: theEvent];
+}
+
+
+- (void)rightMouseDown: (NSEvent *)theEvent
+{
+  NSTRACE (rightMouseDown);
+  [self mouseDown: theEvent];
+}
+
+
+- (void)rightMouseUp: (NSEvent *)theEvent
+{
+  NSTRACE (rightMouseUp);
+  [self mouseDown: theEvent];
+}
+
+
+- (void) scrollWheel: (NSEvent *)theEvent
+{
+  NSTRACE (scrollWheel);
+  [self mouseDown: theEvent];
+}
+
+
+/* Tell emacs the mouse has moved. */
+- (void)mouseMoved: (NSEvent *)e
+{
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
+  Lisp_Object frame;
+
+  NSTRACE (mouseMoved);
+
+  last_mouse_movement_time = EV_TIMESTAMP (e);
+  last_mouse_motion_position =
+    [self convertPoint: [e locationInWindow] fromView: nil];
+
+  /* update any mouse face */
+  if (dpyinfo->mouse_face_hidden)
+    {
+      dpyinfo->mouse_face_hidden = 0;
+      clear_mouse_face (dpyinfo);
+    }
+
+  /* tooltip handling */
+  previous_help_echo_string = help_echo_string;
+  help_echo_string = Qnil;
+
+  if (!note_mouse_movement (emacsframe, last_mouse_motion_position.x,
+                            last_mouse_motion_position.y))
+    help_echo_string = previous_help_echo_string;
+
+  XSETFRAME (frame, emacsframe);
+  if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
+    {
+      /* NOTE: help_echo_{window,pos,object} are set in xdisp.c
+         (note_mouse_highlight), which is called through the
+         note_mouse_movement () call above */
+      gen_help_event (help_echo_string, frame, help_echo_window,
+                      help_echo_object, help_echo_pos);
+    }
+  else
+    {
+      help_echo_string = Qnil;
+      gen_help_event (Qnil, frame, Qnil, Qnil, 0);
+    }
+
+  if (emacsframe->mouse_moved && send_appdefined)
+    ns_send_appdefined (-1);
+}
+
+
+- (void)mouseDragged: (NSEvent *)e
+{
+  NSTRACE (mouseDragged);
+  [self mouseMoved: e];
+}
+
+
+- (void)rightMouseDragged: (NSEvent *)e
+{
+  NSTRACE (rightMouseDragged);
+  [self mouseMoved: e];
+}
+
+
+- (BOOL)windowShouldClose: (id)sender
+{
+  NSEvent *e =[[self window] currentEvent];
+
+  NSTRACE (windowShouldClose);
+  windowClosing = YES;
+  if (ns_window_num <= 1)
+    return NO;
+  if (!emacs_event)
+    return NO;
+  emacs_event->kind = DELETE_WINDOW_EVENT;
+  emacs_event->modifiers = 0;
+  emacs_event->code = 0;
+  EV_TRAILER (e);
+  /* Don't close this window, let this be done from lisp code.  */
+  return NO;
+}
+
+
+- (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize
+/* normalize frame to gridded text size */
+{
+  NSTRACE (windowWillResize);
+/*fprintf (stderr,"Window will resize: %.0f x %.0f\n",frameSize.width,frameSize.height); */
+
+  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe,
+#ifdef NS_IMPL_GNUSTEP
+                                        frameSize.width + 3);
+#else
+                                        frameSize.width);
+#endif
+  if (cols < MINWIDTH)
+    cols = MINWIDTH;
+  frameSize.width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (emacsframe, cols);
+
+  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, frameSize.height
+#ifdef NS_IMPL_GNUSTEP
+      - FRAME_NS_TITLEBAR_HEIGHT (emacsframe) + 3
+        - FRAME_NS_TOOLBAR_HEIGHT (emacsframe));
+#else
+      - FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
+        - FRAME_NS_TOOLBAR_HEIGHT (emacsframe));
+#endif
+  if (rows < MINHEIGHT)
+    rows = MINHEIGHT;
+  frameSize.height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (emacsframe, rows)
+                       + FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
+                       + FRAME_NS_TOOLBAR_HEIGHT (emacsframe);
+#ifdef NS_IMPL_COCOA
+  {
+    /* this sets window title to have size in it; the wm does this under GS */
+    NSRect r = [[self window] frame];
+    if (r.size.height == frameSize.height && r.size.width == frameSize.width)
+      {
+        if (old_title != 0)
+          {
+            xfree (old_title);
+            old_title = 0;
+          }
+      }
+    else
+      {
+        char *size_title;
+        NSWindow *window = [self window];
+        if (old_title == 0)
+          {
+            const char *t = [[[self window] title] UTF8String];
+            char *pos = strstr (t, "  —  ");
+            if (pos)
+              *pos = '\0';
+            old_title = (char *) xmalloc (strlen (t) + 1);
+            strcpy (old_title, t);
+          }
+        size_title = xmalloc (strlen (old_title) + 40);
+        sprintf (size_title, "%s  —  (%d x %d)", old_title, cols, rows);
+        [window setTitle: [NSString stringWithUTF8String: size_title]];
+        [window display];
+        xfree (size_title);
+      }
+  }
+#endif /* NS_IMPL_COCOA */
+/*fprintf (stderr,"    ...size became %.0f x %.0f  (%d x %d)\n",frameSize.width,frameSize.height,cols,rows); */
+
+  return frameSize;
+}
+
+
+- (void)windowDidResize: (NSNotification *)notification
+{
+  NSWindow *theWindow = [notification object];
+
+#ifdef NS_IMPL_GNUSTEP
+   /* in GNUstep, at least currently, it's possible to get a didResize
+      without getting a willResize.. therefore we need to act as if we got
+      the willResize now */
+  NSSize sz = [theWindow frame].size;
+  sz = [self windowWillResize: theWindow toSize: sz];
+#endif /* NS_IMPL_GNUSTEP */
+
+  NSTRACE (windowDidResize);
+/*fprintf (stderr,"windowDidResize: %.0f\n",[theWindow frame].size.height); */
+
+#ifdef NS_IMPL_COCOA
+  if (old_title != 0)
+    {
+      xfree (old_title);
+      old_title = 0;
+    }
+#endif /* NS_IMPL_COCOA */
+
+  if (cols > 0 && rows > 0)
+    x_set_window_size (emacsframe, 0, cols, rows);
+
+  ns_send_appdefined (-1);
+  [NSApp stopModal];
+}
+
+
+- (void)windowDidBecomeKey: (NSNotification *)notification
+{
+  int val = ns_lisp_to_cursor_type (get_frame_param (emacsframe, Qcursor_type));
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
+  struct frame *old_focus = dpyinfo->ns_focus_frame;
+
+  NSTRACE (windowDidBecomeKey);
+
+  if (emacsframe != old_focus)
+    dpyinfo->ns_focus_frame = emacsframe;
+  /*/last_mouse_frame = emacsframe;? */
+
+  if (val >= 0)
+    {
+      FRAME_NEW_CURSOR (emacsframe) = val;
+/*    x_update_cursor (emacsframe, 1); // will happen in ns_frame_rehighlight */
+    }
+
+  ns_frame_rehighlight (emacsframe);
+
+  if (emacs_event)
+    {
+      emacs_event->kind = FOCUS_IN_EVENT;
+      EV_TRAILER ((id)nil);
+    }
+}
+
+
+- (void)windowDidResignKey: (NSNotification *)notification
+{
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
+  NSTRACE (windowDidResignKey);
+
+  if (!windowClosing && [[self window] isVisible] == YES)
+    {
+      FRAME_NEW_CURSOR (emacsframe) = hollow_box;
+      x_update_cursor (emacsframe, 1);
+      FRAME_LAST_INACTIVE (emacsframe) = YES;
+    }
+
+  if (dpyinfo->ns_highlight_frame == emacsframe)
+    dpyinfo->ns_highlight_frame = 0;
+  if (dpyinfo->ns_focus_frame == emacsframe)
+    dpyinfo->ns_focus_frame = 0;
+
+  if (dpyinfo->mouse_face_mouse_frame == emacsframe)
+    {
+      clear_mouse_face (dpyinfo);
+      dpyinfo->mouse_face_mouse_frame = 0;
+    }
+
+  if (emacs_event)
+    {
+      [self deleteWorkingText];
+      emacs_event->kind = FOCUS_IN_EVENT;
+      EV_TRAILER ((id)nil);
+    }
+}
+
+
+- (void)windowWillMiniaturize: sender
+{
+  NSTRACE (windowWillMiniaturize);
+}
+
+
+- (BOOL)isFlipped
+{
+  return YES;
+}
+
+
+- (BOOL)isOpaque
+{
+  return NO;
+}
+
+
+- initFrameFromEmacs: (struct frame *)f
+{
+  NSRect r, wr;
+  Lisp_Object tem;
+  NSWindow *win;
+  NSButton *toggleButton;
+  int vbextra = NS_SCROLL_BAR_WIDTH (f);
+  NSSize sz;
+  NSColor *col;
+  NSString *name;
+
+  NSTRACE (initFrameFromEmacs);
+
+  windowClosing = NO;
+  processingCompose = NO;
+  scrollbarsNeedingUpdate = 0;
+
+/*fprintf (stderr,"init with %d, %d\n",f->text_cols, f->text_lines); */
+
+  r = NSMakeRect (0, 0, FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, f->text_cols),
+                 FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, f->text_lines));
+  [self initWithFrame: r];
+
+  FRAME_NS_VIEW (f) = self;
+  emacsframe = f;
+  old_title = 0;
+
+  win = [[EmacsWindow alloc]
+            initWithContentRect: r
+                      styleMask: (NSResizableWindowMask |
+                                  NSMiniaturizableWindowMask |
+                                  NSClosableWindowMask)
+                        backing: NSBackingStoreBuffered
+                          defer: YES];
+
+  wr = [win frame];
+  f->border_width = wr.size.width - r.size.width;
+  FRAME_NS_TITLEBAR_HEIGHT (f) = wr.size.height - r.size.height;
+
+  [win setAcceptsMouseMovedEvents: YES];
+  [win setDelegate: self];
+  [win useOptimizedDrawing: YES];
+
+  sz.width = FRAME_COLUMN_WIDTH (f);
+  sz.height = FRAME_LINE_HEIGHT (f);
+  [win setResizeIncrements: sz];
+
+  [[win contentView] addSubview: self];
+
+  if (ns_drag_types)
+    [self registerForDraggedTypes: ns_drag_types];
+
+  tem = f->name;
+  name = [NSString stringWithUTF8String:
+                   NILP (tem) ? (unsigned char *)"Emacs" : XSTRING (tem)->data];
+  [win setTitle: name];
+
+  /* toolbar support */
+  toolbar = [[EmacsToolbar alloc] initForView: self withIdentifier:
+                         [NSString stringWithFormat: @"Emacs Frame %d",
+                                   ns_window_num]];
+  [win setToolbar: toolbar];
+  [toolbar setVisible: NO];
+#ifdef NS_IMPL_COCOA
+  toggleButton = [win standardWindowButton: NSWindowToolbarButton];
+  [toggleButton setTarget: self];
+  [toggleButton setAction: @selector (toggleToolbar: )];
+#endif
+  FRAME_NS_TOOLBAR_HEIGHT (f) = 0;
+
+  tem = f->icon_name;
+  if (!NILP (tem))
+    [win setMiniwindowTitle:
+           [NSString stringWithUTF8String: XSTRING (tem)->data]];
+
+  {
+    NSScreen *screen = [win screen];
+
+    if (screen != 0)
+      [win setFrameTopLeftPoint: NSMakePoint
+           (IN_BOUND (-SCREENMAX, f->left_pos, SCREENMAX),
+            IN_BOUND (-SCREENMAX,
+                     [screen frame].size.height - NS_TOP_POS (f), SCREENMAX))];
+  }
+
+  [win makeFirstResponder: self];
+
+  col = ns_lookup_indexed_color (NS_FACE_BACKGROUND
+                                  (FRAME_DEFAULT_FACE (emacsframe)), emacsframe);
+  [win setBackgroundColor: col];
+  if ([col alphaComponent] != 1.0)
+    [win setOpaque: NO];
+
+  [self allocateGState];
+
+  ns_window_num++;
+  return self;
+}
+
+
+- (void)windowDidMove: sender
+{
+  NSWindow *win = [self window];
+  NSRect r = [win frame];
+  NSScreen *screen = [win screen];
+  NSRect sr = [screen frame];
+
+  NSTRACE (windowDidMove);
+
+  if (!emacsframe->output_data.ns)
+    return;
+  if (screen != nil)
+    {
+      emacsframe->left_pos = r.origin.x; /* - sr.origin.x; */
+      emacsframe->top_pos = sr.size.height -
+        (r.origin.y + r.size.height); /* + sr.origin.y; */
+    }
+}
+
+#ifdef NS_IMPL_COCOA
+/* if we don't do this manually, the window will resize but not move */
+- (BOOL)windowShouldZoom: (NSWindow *)sender toFrame: (NSRect)newFrame
+{
+  [[self window] setFrame: newFrame display: NO];
+  return YES;
+}
+#endif
+
+/* Implement this to control size of frame on zoom.
+- (NSRect)windowWillUseStandardFrame:(NSWindow *)sender
+                        defaultFrame:(NSRect)defaultFrame; */
+
+
+- (void)windowDidDeminiaturize: sender
+{
+  NSTRACE (windowDidDeminiaturize);
+  if (!emacsframe->output_data.ns)
+    return;
+  emacsframe->async_visible   = 1;
+  emacsframe->async_iconified = 0;
+  windows_or_buffers_changed++;
+
+  if (emacs_event)
+    {
+      emacs_event->kind = ICONIFY_EVENT;
+      EV_TRAILER ((id)nil);
+    }
+}
+
+
+- (void)windowDidExpose: sender
+{
+  NSTRACE (windowDidExpose);
+  if (!emacsframe->output_data.ns)
+    return;
+  emacsframe->async_visible = 1;
+  SET_FRAME_GARBAGED (emacsframe);
+
+  if (send_appdefined)
+    ns_send_appdefined (-1);
+}
+
+
+- (void)windowDidMiniaturize: sender
+{
+  NSTRACE (windowDidMiniaturize);
+  if (!emacsframe->output_data.ns)
+    return;
+
+  emacsframe->async_iconified = 1;
+
+  if (emacs_event)
+    {
+      emacs_event->kind = ICONIFY_EVENT;
+      EV_TRAILER ((id)nil);
+    }
+}
+
+
+- (void)mouseEntered: (NSEvent *)theEvent
+{
+  NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
+  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
+  NSTRACE (mouseEntered);
+
+  last_mouse_movement_time = EV_TIMESTAMP (theEvent);
+}
+
+
+- (void)mouseExited: (NSEvent *)theEvent
+{
+  NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
+  NSRect r;
+  struct ns_display_info *dpyinfo =
+      emacsframe ? FRAME_NS_DISPLAY_INFO (emacsframe) : NULL;
+
+  NSTRACE (mouseExited);
+
+  if (dpyinfo || !emacsframe)
+    return;
+
+  last_mouse_movement_time = EV_TIMESTAMP (theEvent);
+
+  if (emacsframe == dpyinfo->mouse_face_mouse_frame)
+    {
+      clear_mouse_face (dpyinfo);
+      dpyinfo->mouse_face_mouse_frame = 0;
+    }
+}
+
+
+- menuDown: sender
+{
+  NSTRACE (menuDown);
+  if (context_menu_value == -1)
+    context_menu_value = [sender tag];
+  else
+    find_and_call_menu_selection (emacsframe, emacsframe->menu_bar_items_used,
+                                  emacsframe->menu_bar_vector, [sender tag]);
+  ns_send_appdefined (-1);
+  return self;
+}
+
+
+- (EmacsToolbar *)toolbar
+{
+  return toolbar;
+}
+
+
+/* this gets called on toolbar button click */
+- toolbarClicked: (id)item
+{
+  NSEvent *theEvent;
+  int idx = [item tag] * TOOL_BAR_ITEM_NSLOTS;
+
+  NSTRACE (toolbarClicked);
+
+  if (!emacs_event)
+    return self;
+
+  /* send first event (for some reason two needed) */
+  theEvent =[[self window] currentEvent];
+  emacs_event->kind = TOOL_BAR_EVENT;
+  XSETFRAME (emacs_event->arg, emacsframe);
+  EV_TRAILER (theEvent);
+
+  emacs_event->kind = TOOL_BAR_EVENT;
+/*   XSETINT (emacs_event->code, 0); */
+  emacs_event->arg = AREF (emacsframe->tool_bar_items,
+                          idx + TOOL_BAR_ITEM_KEY);
+  emacs_event->modifiers = EV_MODIFIERS (theEvent);
+  EV_TRAILER (theEvent);
+  return self;
+}
+
+
+- toggleToolbar: (id)sender
+{
+  Lisp_Object lispFrame;
+  XSETFRAME (lispFrame, emacsframe);
+  Feval (Fcons (intern ("ns-toggle-toolbar"), Fcons (lispFrame, Qnil)));
+  SET_FRAME_GARBAGED (emacsframe);
+  ns_send_appdefined (-1);
+}
+
+
+- (void)drawRect: (NSRect)rect
+{
+  int x = NSMinX (rect), y = NSMinY (rect);
+  int width = NSWidth (rect), height = NSHeight (rect);
+
+  NSTRACE (drawRect);
+
+  if (!emacsframe || !emacsframe->output_data.ns)
+    return;
+
+  if (!ns_in_resize)
+    ns_clear_frame_area (emacsframe, x, y, width, height);
+  expose_frame (emacsframe, x, y, width, height);
+
+  emacsframe->async_visible = 1;
+  emacsframe->async_iconified = 0;
+
+/*    SET_FRAME_GARBAGED (emacsframe);
+      ns_send_appdefined (-1); */
+}
+
+
+/* NSDraggingDestination protocol methods.  Actually this is not really a
+   protocol, but a category of Object.  O well...  */
+
+-(unsigned int) draggingEntered: (id <NSDraggingInfo>) sender
+{
+  NSTRACE (draggingEntered);
+  return NSDragOperationGeneric;
+}
+
+
+-(BOOL)prepareForDragOperation: (id <NSDraggingInfo>) sender
+{
+  return YES;
+}
+
+
+-(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
+{
+  id pb;
+  int x, y;
+  NSString *type;
+  NSEvent *theEvent = [[self window] currentEvent];
+  NSPoint position;
+
+  NSTRACE (performDragOperation);
+
+  if (!emacs_event)
+    return;
+
+  position = [self convertPoint: [sender draggingLocation] fromView: nil];
+  x = lrint (position.x);  y = lrint (position.y);
+
+  pb = [sender draggingPasteboard];
+  type = [pb availableTypeFromArray: ns_drag_types];
+  if (type == 0)
+    {
+      return NO;
+    }
+  else if ([type isEqualToString: NSFilenamesPboardType])
+    {
+      NSArray *files;
+      NSEnumerator *fenum;
+      NSString *file;
+
+      if (!(files = [pb propertyListForType: type]))
+        return NO;
+
+      fenum = [files objectEnumerator];
+      while ( (file = [fenum nextObject]) )
+        {
+          emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+          emacs_event->code = KEY_NS_DRAG_FILE;
+          XSETINT (emacs_event->x, x);
+          XSETINT (emacs_event->y, y);
+          ns_input_file = append2 (ns_input_file,
+                                   build_string ([file UTF8String]));
+          emacs_event->modifiers = EV_MODIFIERS (theEvent);
+          EV_TRAILER (theEvent);
+        }
+      return YES;
+    }
+  else if ([type isEqualToString: NSURLPboardType])
+    {
+      NSString *file;
+      NSURL *fileURL;
+
+      if (!(fileURL = [NSURL URLFromPasteboard: pb]) ||
+          [fileURL isFileURL] == NO)
+        return NO;
+
+      file = [fileURL path];
+      emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+      emacs_event->code = KEY_NS_DRAG_FILE;
+      XSETINT (emacs_event->x, x);
+      XSETINT (emacs_event->y, y);
+      ns_input_file = append2 (ns_input_file, build_string ([file UTF8String]));
+      emacs_event->modifiers = EV_MODIFIERS (theEvent);
+      EV_TRAILER (theEvent);
+      return YES;
+    }
+  else if ([type isEqualToString: NSStringPboardType]
+           || [type isEqualToString: NSTabularTextPboardType])
+    {
+      NSString *data;
+
+      if (! (data = [pb stringForType: type]))
+        return NO;
+
+      emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+      emacs_event->code = KEY_NS_DRAG_TEXT;
+      XSETINT (emacs_event->x, x);
+      XSETINT (emacs_event->y, y);
+      ns_input_text = build_string ([data UTF8String]);
+      emacs_event->modifiers = EV_MODIFIERS (theEvent);
+      EV_TRAILER (theEvent);
+      return YES;
+    }
+  else if ([type isEqualToString: NSColorPboardType])
+    {
+      NSColor *c = [NSColor colorFromPasteboard: pb];
+      emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+      emacs_event->code = KEY_NS_DRAG_COLOR;
+      XSETINT (emacs_event->x, x);
+      XSETINT (emacs_event->y, y);
+      ns_input_color = ns_color_to_lisp (c);
+      emacs_event->modifiers = EV_MODIFIERS (theEvent);
+      EV_TRAILER (theEvent);
+      return YES;
+    }
+  else if ([type isEqualToString: NSFontPboardType])
+    {
+      /* impl based on GNUstep NSTextView.m */
+      NSData *data = [pb dataForType: NSFontPboardType];
+      NSDictionary *dict = [NSUnarchiver unarchiveObjectWithData: data];
+      NSFont *font = [dict objectForKey: NSFontAttributeName];
+      char fontSize[10];
+
+      if (font == nil)
+        return NO;
+
+      emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT;
+      emacs_event->code = KEY_NS_CHANGE_FONT;
+      XSETINT (emacs_event->x, x);
+      XSETINT (emacs_event->y, y);
+      ns_input_font = build_string ([[font fontName] UTF8String]);
+      snprintf (fontSize, 10, "%f", [font pointSize]);
+      ns_input_fontsize = build_string (fontSize);
+      emacs_event->modifiers = EV_MODIFIERS (theEvent);
+      EV_TRAILER (theEvent);
+      return YES;
+    }
+  else
+    {
+      error ("Invalid data type in dragging pasteboard.");
+      return NO;
+    }
+}
+
+
+- validRequestorForSendType: (NSString *)typeSent
+                 returnType: (NSString *)typeReturned
+{
+  NSTRACE (validRequestorForSendType);
+  if ([ns_send_types indexOfObjectIdenticalTo: typeSent] != NSNotFound &&
+      [ns_return_types indexOfObjectIdenticalTo: typeSent] != NSNotFound)
+    return self;
+
+  return [super validRequestorForSendType: typeSent
+                               returnType: typeReturned];
+}
+
+
+/* setMini =YES means set from internal (gives a finder icon), NO means set nil
+   (gives a miniaturized version of the window); currently we use the latter for
+   frames whose active buffer doesn't correspond to any file
+   (e.g., '*scratch*') */
+- setMiniwindowImage: (BOOL) setMini
+{
+  id image = [[self window] miniwindowImage];
+  NSTRACE (setMiniwindowImage);
+
+  /* NOTE: under Cocoa miniwindowImage always returns nil, documentation
+     about "AppleDockIconEnabled" notwithstanding, however the set message
+     below has its effect nonetheless. */
+  if (image != emacsframe->output_data.ns->miniimage)
+    {
+      if (image && [image isKindOfClass: [EmacsImage class]])
+        [image release];
+      [[self window] setMiniwindowImage:
+                       setMini ? emacsframe->output_data.ns->miniimage : nil];
+    }
+
+  return self;
+}
+
+
+- (void) setRows: (int) r andColumns: (int) c
+{
+  rows = r;
+  cols = c;
+}
+
+@end  /* EmacsView */
+
+
+
+/* ==========================================================================
+
+    EmacsWindow implementation
+
+   ========================================================================== */
+
+@implementation EmacsWindow
+
+/* called only on resize clicks by special case in EmacsApp-sendEvent */
+- (void)mouseDown: (NSEvent *)theEvent
+{
+  if (ns_in_resize)
+    {
+      NSSize size = [[theEvent window] frame].size;
+      grabOffset = [theEvent locationInWindow];
+      grabOffset.x = size.width - grabOffset.x;
+    }
+  else
+    [super mouseDown: theEvent];
+}
+
+
+/* stop resizing */
+- (void)mouseUp: (NSEvent *)theEvent
+{
+  if (ns_in_resize)
+    {
+      struct frame *f = ((EmacsView *)[self delegate])->emacsframe;
+      ns_in_resize = NO;
+      ns_set_name_as_filename (f);
+      [self display];
+      ns_send_appdefined (-1);
+    }
+  else
+    [super mouseUp: theEvent];
+}
+
+
+/* send resize events */
+- (void)mouseDragged: (NSEvent *)theEvent
+{
+  if (ns_in_resize)
+    {
+      NSPoint p = [theEvent locationInWindow];
+      NSSize size, vettedSize, origSize = [self frame].size;
+
+      size.width = p.x + grabOffset.x;
+      size.height = origSize.height - p.y + grabOffset.y;
+
+      if (size.width == origSize.width && size.height == origSize.height)
+        return;
+
+      vettedSize = [[self delegate] windowWillResize: self toSize: size];
+      if (vettedSize.width != size.width || vettedSize.height != size.height)
+        {
+          [[NSNotificationCenter defaultCenter]
+            postNotificationName: NSWindowDidResizeNotification
+                          object: self];
+        }
+    }
+  else
+    [super mouseDragged: theEvent];
+}
+
+@end /* EmacsWindow */
+
+
+/* ==========================================================================
+
+    EmacsScroller implementation
+
+   ========================================================================== */
+
+
+@implementation EmacsScroller
+
+/* for repeat button push */
+#define SCROLL_BAR_FIRST_DELAY 0.5
+#define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
+
++ (float) scrollerWidth
+{
+  /* PENDING: if we want to allow variable widths, this is the place to do it,
+     however neither GNUstep nor Cocoa support it very well */
+  return [NSScroller scrollerWidth];
+}
+
+
+- initFrame: (NSRect )r window: (Lisp_Object)nwin
+{
+  NSTRACE (EmacsScroller_initFrame);
+
+  r.size.width = [EmacsScroller scrollerWidth];
+  [super initWithFrame: r/*NSMakeRect (0, 0, 0, 0)*/];
+  [self setContinuous: YES];
+  [self setEnabled: YES];
+
+  /* Ensure auto resizing of scrollbars occurs within the emacs frame's view
+     locked against the right, top and bottom edges. */
+  [self setAutoresizingMask: NSViewMinXMargin | NSViewHeightSizable];
+
+  win = nwin;
+  condemned = NO;
+  pixel_height = NSHeight (r);
+  min_portion = 20 / pixel_height;
+
+  frame = XFRAME (XWINDOW (win)->frame);
+  if (FRAME_LIVE_P (frame))
+    {
+      int i;
+      EmacsView *view = FRAME_NS_VIEW (frame);
+      NSView *sview = [[view window] contentView];
+      NSArray *subs = [sview subviews];
+
+      /* disable optimization stopping redraw of other scrollbars */
+      view->scrollbarsNeedingUpdate = 0;
+      for (i =[subs count]-1; i >= 0; i--)
+        if ([[subs objectAtIndex: i] isKindOfClass: [EmacsScroller class]])
+          view->scrollbarsNeedingUpdate++;
+      [sview addSubview: self];
+    }
+
+/*  [self setFrame: r]; */
+
+  return self;
+}
+
+
+- (void)setFrame: (NSRect)newRect
+{
+  NSTRACE (EmacsScroller_setFrame);
+/*  BLOCK_INPUT; */
+  pixel_height = NSHeight (newRect);
+  min_portion = 20 / pixel_height;
+  [super setFrame: newRect];
+  [self display];
+/*  UNBLOCK_INPUT; */
+}
+
+
+- (void)dealloc
+{
+  NSTRACE (EmacsScroller_dealloc);
+  if (!NILP (win))
+    XWINDOW (win)->vertical_scroll_bar = Qnil;
+  [super dealloc];
+}
+
+
+- condemn
+{
+  NSTRACE (condemn);
+  condemned =YES;
+  return self;
+}
+
+
+- reprieve
+{
+  NSTRACE (reprieve);
+  condemned =NO;
+  return self;
+}
+
+
+- judge
+{
+  NSTRACE (judge);
+  if (condemned)
+    {
+      BLOCK_INPUT;
+      /* ensure other scrollbar updates after deletion */
+      EmacsView *view = (EmacsView *)FRAME_NS_VIEW (frame);
+      if (view != nil)
+        view->scrollbarsNeedingUpdate++;
+      [self removeFromSuperview];
+      [self release];
+      UNBLOCK_INPUT;
+    }
+  return self;
+}
+
+
+- (void)resetCursorRects
+{
+  NSRect visible = [self visibleRect];
+  NSTRACE (resetCursorRects);
+
+  if (!NSIsEmptyRect (visible))
+    [self addCursorRect: visible cursor: [NSCursor arrowCursor]];
+  [[NSCursor arrowCursor] setOnMouseEntered: YES];
+}
+
+
+- (int) checkSamePosition: (int) position portion: (int) portion
+                    whole: (int) whole
+{
+  return em_position ==position && em_portion ==portion && em_whole ==whole
+    && portion != whole; /* needed for resize empty buf */
+}
+
+
+- setPosition: (int)position portion: (int)portion whole: (int)whole
+{
+  NSTRACE (setPosition);
+
+  em_position = position;
+  em_portion = portion;
+  em_whole = whole;
+
+  if (portion >= whole)
+    [self setFloatValue: 0.0 knobProportion: 1.0];
+  else
+    {
+      float pos, por;
+      portion = max ((float)whole*min_portion/pixel_height, portion);
+      pos = (float)position / (whole - portion);
+      por = (float)portion/whole;
+      [self setFloatValue: pos knobProportion: por];
+    }
+#ifdef NS_IMPL_GNUSTEP
+  [self display];
+#endif
+  return self;
+}
+
+/* PENDING: unused at moment (see ns_mouse_position) at the moment because
+   drag events will go directly to the EmacsScroller.  Leaving in for now. */
+-(void)getMouseMotionPart: (int *)part window: (Lisp_Object *)window
+                        x: (Lisp_Object *)x y: ( Lisp_Object *)y
+{
+  *part = last_hit_part;
+  *window = win;
+  XSETINT (*y, pixel_height);
+  if ([self floatValue] > 0.999)
+    XSETINT (*x, pixel_height);
+  else
+    XSETINT (*x, pixel_height * [self floatValue]);
+}
+
+
+/* set up emacs_event */
+- (void) sendScrollEventAtLoc: (float)loc fromEvent: (NSEvent *)e
+{
+  if (!emacs_event)
+    return;
+
+  emacs_event->part = last_hit_part;
+  emacs_event->code = 0;
+  emacs_event->modifiers = EV_MODIFIERS (e) | down_modifier;
+  emacs_event->frame_or_window = win;
+  emacs_event->timestamp = EV_TIMESTAMP (e);
+  emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
+  emacs_event->arg = Qnil;
+  XSETINT (emacs_event->x, loc * pixel_height);
+  XSETINT (emacs_event->y, pixel_height-20);
+
+  n_emacs_events_pending++;
+  kbd_buffer_store_event_hold (emacs_event, q_event_ptr);
+  EVENT_INIT (*emacs_event);
+  ns_send_appdefined (-1);
+}
+
+
+/* called manually thru timer to implement repeated button action w/hold-down */
+- repeatScroll: (NSTimer *)scrollEntry
+{
+  NSEvent *e = [[self window] currentEvent];
+  NSPoint p =  [[self window] mouseLocationOutsideOfEventStream];
+  BOOL inKnob = [self testPart: p] == NSScrollerKnob;
+
+  /* clear timer if need be */
+  if (inKnob || [scroll_repeat_entry timeInterval] == SCROLL_BAR_FIRST_DELAY)
+    {
+        [scroll_repeat_entry invalidate];
+        [scroll_repeat_entry release];
+        scroll_repeat_entry = nil;
+
+        if (inKnob)
+          return self;
+
+        scroll_repeat_entry =
+          [[NSTimer scheduledTimerWithTimeInterval:
+                      SCROLL_BAR_CONTINUOUS_DELAY
+                                            target: self
+                                          selector: @selector (repeatScroll:)
+                                          userInfo: 0
+                                           repeats: YES]
+            retain];
+    }
+
+  [self sendScrollEventAtLoc: 0 fromEvent: e];
+  return self;
+}
+
+
+/* Asynchronous mouse tracking for scroller.  This allows us to dispatch
+   mouseDragged events without going into a modal loop. */
+- (void)mouseDown: (NSEvent *)e
+{
+  NSRect sr, kr;
+  /* hitPart is only updated AFTER event is passed on */
+  NSScrollerPart part = [self testPart: [e locationInWindow]];
+  double inc = 0.0, loc, kloc, pos;
+  int edge = 0;
+
+  NSTRACE (EmacsScroller_mouseDown);
+
+  switch (part)
+    {
+    case NSScrollerDecrementPage:
+        last_hit_part = scroll_bar_above_handle; inc = -1.0; break;
+    case NSScrollerIncrementPage:
+        last_hit_part = scroll_bar_below_handle; inc = 1.0; break;
+    case NSScrollerDecrementLine:
+      last_hit_part = scroll_bar_up_arrow; inc = -0.1; break;
+    case NSScrollerIncrementLine:
+      last_hit_part = scroll_bar_down_arrow; inc = 0.1; break;
+    case NSScrollerKnob:
+      last_hit_part = scroll_bar_handle; break;
+    case NSScrollerKnobSlot:  /* GNUstep-only */
+      last_hit_part = scroll_bar_move_ratio; break;
+    default:  /* NSScrollerNoPart? */
+      fprintf (stderr, "EmacsScoller-mouseDown: unexpected part %d\n", part);
+      return;
+    }
+
+  if (inc != 0.0)
+    {
+      pos = 0;      /* ignored */
+
+      /* set a timer to repeat, as we can't let superclass do this modally */
+      scroll_repeat_entry =
+        [[NSTimer scheduledTimerWithTimeInterval: 0.5
+                                          target: self
+                                        selector: @selector (repeatScroll:)
+                                        userInfo: 0
+                                         repeats: YES]
+          retain];
+    }
+  else
+    {
+      /* handle, or on GNUstep possibly slot */
+      NSEvent *fake_event;
+
+      /* compute float loc in slot and mouse offset on knob */
+      sr = [self convertRect: [self rectForPart: NSScrollerKnobSlot]
+                      toView: nil];
+      loc = NSHeight (sr) - ([e locationInWindow].y - NSMinY (sr));
+      if (loc <= 0.0)
+        {
+          loc = 0.0;
+          edge = -1;
+        }
+      else if (loc >= NSHeight (sr))
+        {
+          loc = NSHeight (sr);
+          edge = 1;
+        }
+
+      if (edge)
+        kloc = 0.5 * edge;
+      else
+        {
+          kr = [self convertRect: [self rectForPart: NSScrollerKnob]
+                          toView: nil];
+          kloc = NSHeight (kr) - ([e locationInWindow].y - NSMinY (kr));
+        }
+      last_mouse_offset = kloc;
+
+      /* if knob, tell emacs a location offset by knob pos
+         (to indicate top of handle) */
+      if (part == NSScrollerKnob)
+          pos = (loc - last_mouse_offset) / NSHeight (sr);
+      else
+        /* else this is a slot click on GNUstep: go straight there */
+        pos = loc / NSHeight (sr);
+
+      /* send a fake mouse-up to super to preempt modal -trackKnob: mode */
+      fake_event = [NSEvent mouseEventWithType: NSLeftMouseUp
+                                      location: [e locationInWindow]
+                                 modifierFlags: [e modifierFlags]
+                                     timestamp: [e timestamp]
+                                  windowNumber: [e windowNumber]
+                                       context: [e context]
+                                   eventNumber: [e eventNumber]
+                                    clickCount: [e clickCount]
+                                      pressure: [e pressure]];
+      [super mouseUp: fake_event];
+    }
+
+  if (part != NSScrollerKnob)
+    [self sendScrollEventAtLoc: pos fromEvent: e];
+}
+
+
+/* Called as we manually track scroller drags, rather than superclass. */
+- (void)mouseDragged: (NSEvent *)e
+{
+    NSRect sr;
+    double loc, pos;
+    int edge = 0;
+
+    NSTRACE (EmacsScroller_mouseDragged);
+
+      sr = [self convertRect: [self rectForPart: NSScrollerKnobSlot]
+                      toView: nil];
+      loc = NSHeight (sr) - ([e locationInWindow].y - NSMinY (sr));
+
+      if (loc <= 0.0)
+        {
+          loc = 0.0;
+          edge = -1;
+        }
+      else if (loc >= NSHeight (sr) + last_mouse_offset)
+        {
+          loc = NSHeight (sr) + last_mouse_offset;
+          edge = 1;
+        }
+
+      pos = /*(edge ? loc :*/ (loc - last_mouse_offset) / NSHeight (sr);
+      [self sendScrollEventAtLoc: pos fromEvent: e];
+}
+
+
+- (void)mouseUp: (NSEvent *)e
+{
+  if (scroll_repeat_entry)
+    {
+      [scroll_repeat_entry invalidate];
+      [scroll_repeat_entry release];
+      scroll_repeat_entry = nil;
+    }
+  last_hit_part = 0;
+}
+
+
+/* treat scrollwheel events in the bar as though they were in the main window */
+- (void) scrollWheel: (NSEvent *)theEvent
+{
+  EmacsView *view = (EmacsView *)FRAME_NS_VIEW (frame);
+  [view mouseDown: theEvent];
+}
+
+@end  /* EmacsScroller */
+
+
+
+/* ==========================================================================
+
+    EmacsPrefsController implementation
+
+   ========================================================================== */
+
+
+@implementation EmacsPrefsController
+
+/* in Tiger+, can just do [popup selectItemWithTag: tag]; */
+static void selectItemWithTag (NSPopUpButton *popup, int tag)
+{
+  NSEnumerator *items = [[popup itemArray] objectEnumerator];
+  NSMenuItem *item;
+  while (item = [items nextObject])
+    {
+      if ([item tag] == tag)
+        {
+          [popup selectItem: item];
+          return;
+        }
+    }
+}
+
+- init
+{
+  [NSBundle loadNibNamed: @"preferences" owner: self];
+  return self;
+}
+
+
+- (void) showForFrame: (struct frame *)f
+{
+  frame = f;
+  [self setPanelFromValues];
+  [prefsWindow makeKeyAndOrderFront: self];
+  [prefsWindow display];
+}
+
+
+- (void) setPanelFromValues
+{
+  int cursorType =
+    ns_lisp_to_cursor_type (get_frame_param (frame, Qcursor_type));
+  prevExpandSpace = XFLOATINT (ns_expand_space);
+  prevBlinkRate = NILP (ns_cursor_blink_rate)
+    ? 0 : XFLOATINT (ns_cursor_blink_rate);
+
+#ifdef NS_IMPL_COCOA
+  prevUseHighlightColor = ns_use_system_highlight_color;
+#endif
+
+  [expandSpaceSlider setFloatValue: prevExpandSpace];
+  [cursorBlinkSlider setFloatValue: prevBlinkRate];
+  [cursorTypeMatrix selectCellWithTag: (cursorType == filled_box ? 1 :
+                                        (cursorType == bar ? 2 :
+                                         (cursorType == underscore ? 3 : 4)))];
+  selectItemWithTag (alternateModMenu, lisp_to_mod (ns_alternate_modifier));
+  selectItemWithTag (commandModMenu, lisp_to_mod (ns_command_modifier));
+#ifdef NS_IMPL_COCOA
+  selectItemWithTag (controlModMenu, lisp_to_mod (ns_control_modifier));
+  selectItemWithTag (functionModMenu, lisp_to_mod (ns_function_modifier));
+  [smoothFontsCheck setState: ns_antialias_text ? YES : NO];
+  [useQuickdrawCheck setState: ns_use_qd_smoothing ? YES : NO];
+  [useSysHiliteCheck setState: prevUseHighlightColor ? YES : NO];
+#endif
+}
+
+
+- (void) setValuesFromPanel
+{
+  int cursorTag = [[cursorTypeMatrix selectedCell] tag];
+  int altTag = [[alternateModMenu selectedItem] tag];
+  int cmdTag = [[commandModMenu selectedItem] tag];
+#ifdef NS_IMPL_COCOA
+  int ctrlTag = [[controlModMenu selectedItem] tag];
+  int fnTag = [[functionModMenu selectedItem] tag];
+#endif
+  float blinkRate = [cursorBlinkSlider floatValue];
+  float expandSpace = [expandSpaceSlider floatValue];
+  Lisp_Object old_cursor_blink_mode;
+
+  if (expandSpace != prevExpandSpace)
+    {
+      ns_expand_space = make_float (expandSpace);
+      /* PENDING: more needed: store needed metrics in nsfont_info, update
+         frame default font max_bounds and fontp, recompute faces */
+/*         FRAME_LINE_HEIGHT (frame) *= (expandSpace / prevExpandSpace);
+           x_set_window_size (frame, 0, frame->text_cols, frame->text_lines); */
+      prevExpandSpace = expandSpace;
+    }
+  if (blinkRate != prevBlinkRate)
+    {
+      old_cursor_blink_mode = ns_cursor_blink_mode;
+      if (blinkRate == 0.0)
+        {
+          ns_cursor_blink_rate = Qnil;
+          ns_cursor_blink_mode = Qnil;
+        }
+      else
+        {
+          ns_cursor_blink_rate = make_float (blinkRate);
+          ns_cursor_blink_mode = Qt;
+        }
+      if (ns_cursor_blink_mode != old_cursor_blink_mode)
+          Feval (Fcons (intern ("blink-cursor-mode"), Qnil));
+
+      if (blinkRate != 0.0 && prevBlinkRate != 0.0)
+        {  /* if changed rates, remove blink handler so change picked up */
+          struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame);
+          [cursor_blink_entry invalidate];
+          [cursor_blink_entry release];
+          cursor_blink_entry = 0;
+          if (dpyinfo->ns_highlight_frame)
+            {
+              Lisp_Object tem =
+                get_frame_param (dpyinfo->ns_highlight_frame, Qcursor_type);
+              dpyinfo->ns_highlight_frame->output_data.ns->desired_cursor =
+                ns_lisp_to_cursor_type (tem);
+            }
+        }
+      prevBlinkRate = blinkRate;
+    }
+  FRAME_NEW_CURSOR (frame) =
+                         (cursorTag == 1 ? filled_box :
+                          (cursorTag == 2 ? bar :
+                           (cursorTag == 3 ? underscore : hollow_box)));
+  store_frame_param (frame, Qcursor_type,
+                    ns_cursor_type_to_lisp (FRAME_NEW_CURSOR (frame)));
+  ns_alternate_modifier = ns_mod_to_lisp (altTag);
+  ns_command_modifier = ns_mod_to_lisp (cmdTag);
+#ifdef NS_IMPL_COCOA
+  ns_control_modifier = ns_mod_to_lisp (ctrlTag);
+  ns_function_modifier = ns_mod_to_lisp (fnTag);
+  ns_antialias_text = [smoothFontsCheck state];
+  ns_use_qd_smoothing = [useQuickdrawCheck state];
+  ns_use_system_highlight_color = [useSysHiliteCheck state];
+  if (ns_use_system_highlight_color != prevUseHighlightColor)
+    {
+      prevUseHighlightColor = ns_use_system_highlight_color;
+      if (ns_use_system_highlight_color == YES)
+        {
+          ns_selection_color = [[NSUserDefaults standardUserDefaults]
+                                 stringForKey: @"AppleHighlightColor"];
+          if (ns_selection_color == nil)
+            ns_selection_color = NS_SELECTION_COLOR_DEFAULT;
+        }
+      else
+        ns_selection_color = NS_SELECTION_COLOR_DEFAULT;
+    }
+#endif /* NS_IMPL_COCOA */
+  Fcall_interactively (intern ("ns-save-preferences"), Qnil, Qnil);
+}
+
+
+/* buttons */
+- (IBAction)cancel: (id)sender
+{
+  [prefsWindow close];
+}
+
+
+- (IBAction)ok: (id)sender
+{
+  [self setValuesFromPanel];
+  [prefsWindow close];
+}
+
+
+- (IBAction)resetToDefaults: (id)sender
+{
+  ns_set_default_prefs ();
+  [self setPanelFromValues];
+}
+
+
+- (IBAction)runHelp: (id)sender
+{
+  Feval (Fcons (intern ("info"),
+              Fcons (build_string ("(ns-emacs)Preferences Panel"), Qnil)));
+  SET_FRAME_GARBAGED (frame);
+  ns_send_appdefined (-1);
+}
+
+
+- (IBAction)setColors: (id)sender
+{
+  Lisp_Object lispFrame;
+  XSETFRAME (lispFrame, frame);
+  Fns_popup_color_panel (lispFrame);
+}
+
+
+- (IBAction)setDefaultFont: (id)sender
+{
+  Lisp_Object lispFrame;
+  XSETFRAME (lispFrame, frame);
+  Fns_popup_font_panel (lispFrame);
+}
+
+@end  /* EmacsPrefsController */
+
+
+
+
+/* ==========================================================================
+
+   Font-related functions; these used to be in nsfaces.m
+
+   ========================================================================== */
+
+
+Lisp_Object
+x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
+{
+  struct font *font = XFONT_OBJECT (font_object);
+
+  if (fontset < 0)
+    fontset = fontset_from_font (font_object);
+  FRAME_FONTSET (f) = fontset;
+
+  if (FRAME_FONT (f) == font)
+    /* This font is already set in frame F.  There's nothing more to
+       do.  */
+    return font_object;
+
+  FRAME_FONT (f) = font;
+
+  FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
+  FRAME_COLUMN_WIDTH (f) = font->average_width;
+  FRAME_SPACE_WIDTH (f) = font->space_width;
+  FRAME_LINE_HEIGHT (f) = font->height;
+
+  compute_fringe_widths (f, 1);
+
+  /* Compute the scroll bar width in character columns.  */
+  if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
+    {
+      int wid = FRAME_COLUMN_WIDTH (f);
+      FRAME_CONFIG_SCROLL_BAR_COLS (f)
+	= (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid;
+    }
+  else
+    {
+      int wid = FRAME_COLUMN_WIDTH (f);
+      FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
+    }
+
+  /* Now make the frame display the given font.  */
+  if (FRAME_NS_WINDOW (f) != 0)
+	x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+
+  return font_object;
+}
+
+
+Lisp_Object
+ns_list_fonts (FRAME_PTR f, Lisp_Object pattern, int size, int maxnames)
+/* --------------------------------------------------------------------------
+     This is used by the xfaces system.  It is expected to speak XLFD.
+   -------------------------------------------------------------------------- */
+{
+  Lisp_Object list = Qnil,
+    rpattern,
+    key,
+    tem,
+    args[2];
+  struct re_pattern_buffer *bufp;
+  id fm = [NSFontManager sharedFontManager];
+  NSEnumerator *fenum, *senum;
+  NSArray *membInfo;
+  NSString *fontname;
+  const char *xlfdName;
+  char *pattFam;
+  char *patt;
+  NSString *famName;
+
+  NSTRACE (ns_list_fonts);
+
+  CHECK_STRING (pattern);
+  patt = XSTRING (pattern)->data;
+
+#if 0
+/* temporary: for font_backend, we use fontsets, and when these are defined,
+   the old XLFD-based system is used; eventually this will be replaced by
+   backend code, but for now we allow specs that are just family names */
+      /* if pattern is not XLFD, panic now */
+      if (patt[0] != '-')
+        error ("ns_list_fonts: X font name (XLFD) expected.");
+
+      /* if unicode encoding not requested, also die */
+      if (!strstr (patt, "iso10646") && patt[strlen (patt)-3] != '*')
+        return Qnil;
+#endif /* 0 */
+
+  key = f ? Fcons (pattern, make_number (maxnames)) : Qnil;
+  tem = f ? XCDR (FRAME_NS_DISPLAY_INFO (f)->name_list_element) : Qnil;
+
+  /* See if we cached the result for this particular query.
+     The cache is an alist of the form:
+     ((((PATTERN . MAXNAMES) FONTNAME) ...) ...)
+  */
+  if (f && !NILP (list = Fassoc (key, tem)))
+    {
+      list = Fcdr_safe (list);
+      /* We have a cached list.  Don't have to get the list again.  */
+      if (!NILP (list))
+        return list;
+    }
+
+  if (patt[0] != '-')
+      pattFam = patt;
+  else
+      pattFam = ns_xlfd_to_fontname (patt);
+  /*PENDING: '*' at beginning matches literally.. */
+  if (pattFam[0] == '*')
+    pattFam[0] = '.';
+
+  /* must start w/family name, but can have other stuff afterwards
+    (usually bold and italic specifiers) */
+  args[0] = build_string ("^");
+  args[1] = build_string (pattFam);
+  rpattern = Fconcat (2, args);
+  bufp = compile_pattern (rpattern, 0, Vascii_canon_table, 0, 0);
+
+  list = Qnil;
+  fenum = [[fm availableFontFamilies] objectEnumerator];
+  while ( (famName = [fenum nextObject]) )
+    {
+      NSMutableString *tmp = [famName mutableCopy];
+      const char *fname;
+      NSRange r;
+
+      /* remove spaces, to look like postscript name */
+      while ((r = [tmp rangeOfString: @" "]).location != NSNotFound)
+        [tmp deleteCharactersInRange: r];
+
+      fname = [tmp UTF8String];
+      int len = strlen (fname);
+      BOOL foundItal;
+      const char *synthItalFont;
+
+      if (re_search (bufp, fname, len, 0, len, 0) >= 0)
+        {
+          /* Found a family.  Add all variants.  If we have no italic variant,
+             add a synthItal. */
+          senum =[[fm availableMembersOfFontFamily: famName] objectEnumerator];
+          foundItal = NO;
+          synthItalFont = NULL;
+          while (membInfo = [senum nextObject])
+            {
+              xlfdName =
+                ns_fontname_to_xlfd ([[membInfo objectAtIndex: 0] UTF8String]);
+              list = Fcons (build_string (xlfdName), list);
+              if (!synthItalFont)
+                {
+                  NSString *synthName =
+                    [[membInfo objectAtIndex: 0]
+                      stringByAppendingString: @"-synthItal"];
+                  synthItalFont = [synthName UTF8String];
+                }
+              else if ([[membInfo objectAtIndex: 3] intValue]
+                         & NSItalicFontMask)
+                foundItal = YES;
+            }
+          if (foundItal == NO)
+            {
+              xlfdName = ns_fontname_to_xlfd (synthItalFont);
+              list = Fcons (build_string (xlfdName), list);
+            }
+        }
+      [tmp release];
+    }
+
+  /* fallback */
+  if (XFASTINT (Flength (list)) == 0)
+      list = Fcons (build_string (ns_fontname_to_xlfd ("Monaco")), list);
+
+  /* store result in cache */
+  if (f != NULL)
+    XCDR_AS_LVALUE (FRAME_NS_DISPLAY_INFO (f)->name_list_element)
+      = Fcons (Fcons (key, list),
+               XCDR (FRAME_NS_DISPLAY_INFO (f)->name_list_element));
+  return list;
+}
+
+
+/* XLFD: -foundry-family-weight-slant-swidth-adstyle-pxlsz-ptSz-resx-resy-spc-avgWidth-rgstry-encoding */
+
+const char *
+ns_font_to_xlfd (NSFont *nsfont)
+/* --------------------------------------------------------------------------
+    Convert an NS font name to an X font name (XLFD).
+    The string returned is temporarily allocated.
+   -------------------------------------------------------------------------- */
+{
+  NSFontManager *mgr = [NSFontManager sharedFontManager];
+  NSString *sname = [nsfont /*familyName*/fontName];
+  char *famName = [sname UTF8String];
+  char *weightStr = [mgr fontNamed: sname hasTraits: NSBoldFontMask] ?
+      "bold" : "medium";
+  char *slantStr = [mgr fontNamed: sname hasTraits: NSItalicFontMask] ?
+      "i" : "r";
+  int size = [nsfont pointSize];
+  int aWidth = lrint (10.0 * [nsfont widthOfString: @"a"]);
+  const char *xlfd;
+  int i, len;
+
+  /* change '-' to '$' to avoid messing w/XLFD separator */
+  for (len =strlen (famName), i =0; i<len; i++)
+    if (famName[i] == '-')
+      {
+        famName[i] = '\0';
+        break;
+      }
+
+  xlfd = [[NSString stringWithFormat:
+                       @"-apple-%s-%s-%s-normal--%d-%d-75-75-m-%d-iso10646-1",
+                       famName, weightStr, slantStr, size, 10*size, aWidth]
+                  UTF8String];
+/*fprintf (stderr, "converted '%s' to '%s'\n",name,xlfd); */
+  return xlfd;
+}
+
+const char *
+ns_fontname_to_xlfd (const char *name)
+/* --------------------------------------------------------------------------
+    Convert an NS font name to an X font name (XLFD).
+    Sizes are set to 0.
+    The string returned is temporarily allocated.
+   -------------------------------------------------------------------------- */
+{
+  char famName[180];
+  char *weightStr = strcasestr (name, "bold") ? "bold" : "medium";
+  char *slantStr = strcasestr (name, "italic") || strcasestr (name, "oblique")
+    || strcasestr (name, "synthital") ? "i" : "r";
+  int i, len;
+  const char *xlfd;
+
+  /* change '-' to '$' to avoid messing w/XLFD separator, and ' ' to '_' */
+  bzero (famName, 180);
+  bcopy (name, famName, max (strlen (name), 179));
+  for (len =strlen (famName), i =0; i<len; i++)
+    {
+      if (famName[i] == '-')
+        famName[i] = '$';
+      else if (famName[i] == ' ')
+        famName[i] = '_';
+    }
+
+  xlfd = [[NSString stringWithFormat:
+                           @"-apple-%s-%s-%s-normal--0-0-75-75-m-0-iso10646-1",
+                           famName, weightStr, slantStr]
+                  UTF8String];
+/*fprintf (stderr, "converted '%s' to '%s'\n",name,xlfd); */
+  return xlfd;
+}
+
+
+const char *
+ns_xlfd_to_fontname (const char *xlfd)
+/* --------------------------------------------------------------------------
+    Convert an X font name (XLFD) to an NS font name.
+    Only family is used.
+    The string returned is temporarily allocated.
+   -------------------------------------------------------------------------- */
+{
+  char *name = xmalloc (180);
+  int i, len;
+  const char *ret;
+  
+  if (!strncmp (xlfd, "--", 2))
+    sscanf (xlfd, "--%*[^-]-%[^-]179-", name);
+  else
+    sscanf (xlfd, "-%*[^-]-%[^-]179-", name);
+
+  /* stopgap for malformed XLFD input */
+  if (strlen (name) == 0)
+    strcpy (name, "Monaco");
+
+  /* undo hack in ns_fontname_to_xlfd, converting '$' to '-', '_' to ' '
+     also uppercase after '-' or ' ' */
+  name[0] = toupper (name[0]);
+  for (len =strlen (name), i =0; i<len; i++)
+    {
+      if (name[i] == '$')
+        {
+          name[i] = '-';
+          if (i+1<len)
+            name[i+1] = toupper (name[i+1]);
+        }
+      else if (name[i] == '_')
+        {
+          name[i] = ' ';
+          if (i+1<len)
+            name[i+1] = toupper (name[i+1]);
+        }
+    }
+/*fprintf (stderr, "converted '%s' to '%s'\n",xlfd,name);  */
+  ret = [[NSString stringWithUTF8String: name] UTF8String];
+  xfree (name);
+  return ret;
+}
--- a/src/process.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/process.c	Tue Jul 15 18:15:18 2008 +0000
@@ -4877,8 +4877,12 @@
 	      process_output_skip = 0;
 	    }
 #endif
-
-	  nfds = select (max (max (max_process_desc, max_keyboard_desc),
+#ifdef HAVE_NS
+          nfds = ns_select
+#else
+          nfds = select
+#endif
+                        (max (max (max_process_desc, max_keyboard_desc),
 			      max_gpm_desc) + 1,
 			 &Available,
 #ifdef NON_BLOCKING_CONNECT
--- a/src/s/darwin.h	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/s/darwin.h	Tue Jul 15 18:15:18 2008 +0000
@@ -221,7 +221,9 @@
 /* In Carbon, asynchronous I/O (using SIGIO) can't be used for window
    events because they don't come from sockets, even though it works
    fine on tty's.  */
-#ifdef HAVE_CARBON
+/* This seems to help in Ctrl-G detection under Cocoa, however at the cost
+   of some quirks that may or may not bother a given user. */
+#if defined (HAVE_CARBON) || defined (COCOA_EXPERIMENTAL_CTRL_G)
 #define NO_SOCK_SIGIO
 #endif
 
@@ -247,8 +249,21 @@
 
 /* Definitions for how to compile & link.  */
 
-/* Indicate that we are compiling for Mac OS X.  */
+/* This is for the Carbon port.  Under the NeXTstep port, this is still picked
+   up during preprocessing, but is undone in config.in. */
+#ifndef HAVE_NS
 #define C_SWITCH_SYSTEM -fpascal-strings -DMAC_OSX
+#endif
+
+/* Link in the Carbon or AppKit lib. */
+#ifdef HAVE_NS
+/* PENDING: lresolv is here because configure when testing #undefs res_init,
+            a macro in /usr/include/resolv.h for res_9_init, not in stdc lib. */
+#define LIBS_MACGUI -framework AppKit -lresolv
+#define SYSTEM_PURESIZE_EXTRA 200000
+#define HEADERPAD_EXTRA 6C8
+#else
+#define HEADERPAD_EXTRA 690
 
 #ifdef HAVE_CARBON
 
@@ -274,16 +289,17 @@
 
 /* Link in the Carbon lib. */
 #ifdef HAVE_CARBON
-#define LIBS_CARBON -framework Carbon LIBS_IMAGE
+#define LIBS_MACGUI -framework Carbon LIBS_IMAGE
 #else
-#define LIBS_CARBON
-#endif
+#define LIBS_MACGUI
+#endif /* !HAVE_CARBON */
+#endif /* !HAVE_NS */
 
 /* The -headerpad option tells ld (see man page) to leave room at the
    end of the header for adding load commands.  Needed for dumping.
    0x690 is the total size of 30 segment load commands (at 56
-   each).  */
-#define LD_SWITCH_SYSTEM_TEMACS -prebind LIBS_CARBON -Xlinker -headerpad -Xlinker 690
+   each); under Cocoa 31 commands are required.  */
+#define LD_SWITCH_SYSTEM_TEMACS -prebind LIBS_MACGUI -Xlinker -headerpad -Xlinker HEADERPAD_EXTRA
 
 #define C_SWITCH_SYSTEM_TEMACS -Dtemacs
 
@@ -312,6 +328,11 @@
 #define OTHER_FILES macosx-app
 #endif
 
+/* PENDING: can this target be specified in a clearer way? */
+#ifdef HAVE_NS
+#define OTHER_FILES ns-app
+#endif
+
 
 /* Define the following so emacs symbols will not conflict with those
    in the System framework.  Otherwise -prebind will not work.  */
--- a/src/syntax.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/syntax.c	Tue Jul 15 18:15:18 2008 +0000
@@ -1,3 +1,4 @@
+#include <stdio.h>
 /* GNU Emacs routines to deal with syntax tables; also word and list parsing.
    Copyright (C) 1985, 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2001,
                  2002, 2003, 2004, 2005, 2006, 2007, 2008
@@ -298,6 +299,18 @@
   register int quoted = 0;
   int orig = charpos;
 
+#ifdef HAVE_NS
+  /* For some reason keeps getting called w/both 1, then segfaulting
+     due to the definitions of DEC_BOTH and DEC_POS in character.h,
+     which lead to decrementing below initial address and then examining
+     character there.  Need to investigate further.. */
+  if (charpos < 2 || bytepos < 2)
+    {
+      //fprintf(stderr,"Returning because charpos = %d, bytepos = %d\n",charpos, bytepos);
+      return 0;
+    }
+#endif
+
   DEC_BOTH (charpos, bytepos);
 
   while (charpos >= beg)
--- a/src/sysselect.h	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/sysselect.h	Tue Jul 15 18:15:18 2008 +0000
@@ -18,11 +18,11 @@
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifdef HAVE_SYS_SELECT_H
-#if defined (DARWIN) || defined (MAC_OSX)
+#if defined (DARWIN) || defined (MAC_OSX) || defined (NS_IMPL_COCOA)
 #undef init_process
 #endif
 #include <sys/select.h>
-#if defined (DARWIN) || defined (MAC_OSX)
+#if defined (DARWIN) || defined (MAC_OSX) || defined (NS_IMPL_COCOA)
 #define init_process emacs_init_process
 #endif
 #endif
--- a/src/termhooks.h	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/termhooks.h	Tue Jul 15 18:15:18 2008 +0000
@@ -318,6 +318,8 @@
 
 
 struct mac_display_info;
+struct ns_display_info;
+struct x_display_info;
 struct w32_display_info;
 
 /* Terminal-local parameters. */
@@ -368,6 +370,7 @@
     struct x_display_info *x;         /* xterm.h */
     struct w32_display_info *w32;     /* w32term.h */
     struct mac_display_info *mac;     /* macterm.h */
+    struct ns_display_info *ns;       /* nsterm.h */
   } display_info;
 
 
--- a/src/terminal.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/terminal.c	Tue Jul 15 18:15:18 2008 +0000
@@ -397,6 +397,8 @@
       return Qpc;
     case output_mac:
       return Qmac;
+    case output_ns:
+      return Qns;
     default:
       abort ();
     }
--- a/src/terminfo.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/terminfo.c	Tue Jul 15 18:15:18 2008 +0000
@@ -24,7 +24,10 @@
    so that we do not need to conditionalize the places in Emacs
    that set them.  */
 
+/* Causes a conflict on OS X 10.3 .*/
+#ifndef NS_IMPL_COCOA
 char *UP, *BC, PC;
+#endif
 
 /* Interface to curses/terminfo library.
    Turns out that all of the terminfo-level routines look
--- a/src/w32gui.h	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/w32gui.h	Tue Jul 15 18:15:18 2008 +0000
@@ -21,66 +21,19 @@
 #define EMACS_W32GUI_H
 #include <windows.h>
 
+#include "w32bdf.h"
 
-/* Emulate widget_value from ../lwlib/lwlib.h, modified for Windows.  */
-typedef void * XtPointer;
-typedef char Boolean;
-enum button_type
-{
-  BUTTON_TYPE_NONE,
-  BUTTON_TYPE_TOGGLE,
-  BUTTON_TYPE_RADIO
-};
-typedef struct _widget_value
+/* Emulate XCharStruct.  */
+typedef struct _XCharStruct
 {
-  /* name of widget */
-  Lisp_Object   lname;
-  char*		name;
-  /* value (meaning depend on widget type) */
-  char*		value;
-  /* keyboard equivalent. no implications for XtTranslations */
-  Lisp_Object   lkey;
-  char*		key;
-  /* Help string or nil if none.
-     GC finds this string through the frame's menu_bar_vector
-     or through menu_items.  */
-  Lisp_Object	help;
-  /* true if enabled */
-  Boolean	enabled;
-  /* true if selected */
-  Boolean	selected;
-  /* The type of a button.  */
-  enum button_type button_type;
-  /* true if menu title */
-  Boolean       title;
-#if 0
-  /* true if was edited (maintained by get_value) */
-  Boolean	edited;
-  /* true if has changed (maintained by lw library) */
-  change_type	change;
-  /* true if this widget itself has changed,
-     but not counting the other widgets found in the `next' field.  */
-  change_type   this_one_change;
-#endif
-  /* Contents of the sub-widgets, also selected slot for checkbox */
-  struct _widget_value*	contents;
-  /* data passed to callback */
-  XtPointer	call_data;
-  /* next one in the list */
-  struct _widget_value*	next;
-#if 0
-  /* slot for the toolkit dependent part.  Always initialize to NULL. */
-  void* toolkit_data;
-  /* tell us if we should free the toolkit data slot when freeing the
-     widget_value itself. */
-  Boolean free_toolkit_data;
+  short rbearing;
+  short lbearing;
+  short width;
+  short ascent;
+  short descent;
+} XCharStruct;
 
-  /* we resource the widget_value structures; this points to the next
-     one on the free list if this one has been deallocated.
-   */
-  struct _widget_value *free_list;
-#endif
-} widget_value;
+
 /* Local memory management for menus.  */
 #define local_heap (GetProcessHeap ())
 #define local_alloc(n) (HeapAlloc (local_heap, HEAP_ZERO_MEMORY, (n)))
@@ -89,6 +42,30 @@
 #define malloc_widget_value() ((widget_value *) local_alloc (sizeof (widget_value)))
 #define free_widget_value(wv) (local_free ((wv)))
 
+
+enum w32_char_font_type
+{
+  UNKNOWN_FONT = 0 /* FONT_TYPE_UNKNOWN */,
+  ANSI_FONT,
+  UNICODE_FONT,
+  BDF_1D_FONT,
+  BDF_2D_FONT
+};
+
+typedef struct W32FontStruct {
+  enum w32_char_font_type font_type;
+  TEXTMETRIC tm;
+  HFONT hfont;
+  bdffont *bdf;
+  int double_byte_p;
+  XCharStruct max_bounds;
+  XCharStruct scratch;
+  /* Only store info for ascii chars, if not fixed pitch.  */
+  XCharStruct * per_char;
+} W32FontStruct;
+
+typedef struct W32FontStruct XFontStruct;
+
 /* Emulate X GC's by keeping color and font info in a structure.  */
 typedef struct _XGCValues
 {
--- a/src/window.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/window.c	Tue Jul 15 18:15:18 2008 +0000
@@ -49,6 +49,9 @@
 #ifdef MAC_OS
 #include "macterm.h"
 #endif
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
 
 
 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
--- a/src/xdisp.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/xdisp.c	Tue Jul 15 18:15:18 2008 +0000
@@ -199,6 +199,9 @@
 #ifdef MAC_OS
 #include "macterm.h"
 #endif
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
 
 #include "font.h"
 
@@ -209,7 +212,7 @@
 #define INFINITY 10000000
 
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+    || defined(HAVE_NS) || defined (USE_GTK)
 extern void set_frame_menubar P_ ((struct frame *f, int, int));
 extern int pending_menu_activation;
 #endif
@@ -861,7 +864,7 @@
 int hourglass_shown_p;
 
 /* If non-null, an asynchronous timer that, when it expires, displays
-    an hourglass cursor on all frames.  */
+   an hourglass cursor on all frames.  */
 struct atimer *hourglass_atimer;
 
 /* Number of seconds to wait before displaying an hourglass cursor.  */
@@ -9462,7 +9465,32 @@
       if (! STRINGP (f->name)
 	  || SBYTES (f->name) != len
 	  || bcmp (title, SDATA (f->name), len) != 0)
-	x_implicitly_set_name (f, make_string (title, len), Qnil);
+        {
+#ifdef HAVE_NS
+          if (FRAME_NS_P (f))
+            {
+              if (!MINI_WINDOW_P(XWINDOW(f->selected_window)))
+                {
+                  if (EQ (fmt, Qt))
+                    ns_set_name_as_filename (f);
+                  else
+                    x_implicitly_set_name (f, make_string(title, len),
+                                           Qnil);
+                }
+            }
+          else
+#endif
+	    x_implicitly_set_name (f, make_string (title, len), Qnil);
+        }
+#ifdef HAVE_NS
+      if (FRAME_NS_P (f))
+        {
+          /* do this also for frames with explicit names */
+          ns_implicitly_set_icon_type(f);
+          ns_set_doc_edited(f, Fbuffer_modified_p
+                            (XWINDOW (f->selected_window)->buffer), Qnil);
+        }
+#endif
     }
 }
 
@@ -9627,7 +9655,7 @@
   if (FRAME_WINDOW_P (f)
       ?
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+    || defined (HAVE_NS) || defined (USE_GTK)
       FRAME_EXTERNAL_MENU_BAR (f)
 #else
       FRAME_MENU_BAR_LINES (f) > 0
@@ -9686,10 +9714,10 @@
 
 	  /* Redisplay the menu bar in case we changed it.  */
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+    || defined (HAVE_NS) || defined (USE_GTK)
 	  if (FRAME_WINDOW_P (f))
-	    {
-#ifdef MAC_OS
+            {
+#if defined (MAC_OS) || defined (HAVE_NS)
               /* All frames on Mac OS share the same menubar.  So only
                  the selected frame should be allowed to set it.  */
               if (f == SELECTED_FRAME ())
@@ -9700,11 +9728,11 @@
 	    /* On a terminal screen, the menu bar is an ordinary screen
 	       line, and this makes it get updated.  */
 	    w->update_mode_line = Qt;
-#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
+#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || HAVE_NS || USE_GTK) */
 	  /* In the non-toolkit version, the menu bar is an ordinary screen
 	     line, and this makes it get updated.  */
 	  w->update_mode_line = Qt;
-#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
+#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || HAVE_NS || USE_GTK) */
 
 	  unbind_to (count, Qnil);
 	  set_buffer_internal_1 (prev);
@@ -9815,7 +9843,7 @@
      struct frame *f;
      int save_match_data;
 {
-#if defined (USE_GTK) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
   int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
 #else
   int do_update = WINDOWP (f->tool_bar_window)
@@ -10281,7 +10309,7 @@
   struct it it;
   struct glyph_row *row;
 
-#if defined (USE_GTK) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
   if (FRAME_EXTERNAL_TOOL_BAR (f))
     update_frame_tool_bar (f);
   return 0;
@@ -11501,6 +11529,10 @@
       /* Resized active mini-window to fit the size of what it is
          showing if its contents might have changed.  */
       must_finish = 1;
+/* PENDING: this causes all frames to be updated, which seems unnecessary
+   since only the current frame needs to be considered.  This function needs
+   to be rewritten with two variables, consider_all_windows and
+   consider_all_frames. */
       consider_all_windows_p = 1;
       ++windows_or_buffers_changed;
       ++update_mode_lines;
@@ -13913,7 +13945,7 @@
       if (FRAME_WINDOW_P (f))
 	{
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
-    || defined (USE_GTK)
+    || defined (HAVE_NS) || defined (USE_GTK)
 	  redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
 #else
 	  redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
@@ -13928,7 +13960,7 @@
 #ifdef HAVE_WINDOW_SYSTEM
       if (FRAME_WINDOW_P (f))
         {
-#if defined (USE_GTK) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
           redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
 #else
           redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
@@ -17072,6 +17104,11 @@
     return;
 #endif
 
+#ifdef HAVE_NS
+  if (FRAME_NS_P (f))
+    return;
+#endif /* HAVE_NS */
+
 #ifdef USE_X_TOOLKIT
   xassert (!FRAME_WINDOW_P (f));
   init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
@@ -22539,7 +22576,10 @@
 /* Switch the display of W's cursor on or off, according to the value
    of ON.  */
 
-static void
+#ifndef HAVE_NS
+static
+#endif
+void
 update_window_cursor (w, on)
      struct window *w;
      int on;
--- a/src/xfaces.c	Tue Jul 15 15:45:05 2008 +0000
+++ b/src/xfaces.c	Tue Jul 15 18:15:18 2008 +0000
@@ -244,6 +244,17 @@
 #define check_x check_mac
 #endif /* MAC_OS */
 
+#ifdef HAVE_NS
+#include "nsterm.h"
+#undef FRAME_X_DISPLAY_INFO
+#define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO
+#define x_display_info ns_display_info
+#define FRAME_X_FONT_TABLE FRAME_NS_FONT_TABLE
+#define check_x check_ns
+#define x_list_fonts ns_list_fonts
+#define GCGraphicsExposures 0
+#endif /* HAVE_NS */
+
 #include "buffer.h"
 #include "dispextern.h"
 #include "blockinput.h"
@@ -556,6 +567,10 @@
 extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
 #endif /* WINDOWSNT */
 
+#ifdef HAVE_NS
+extern Lisp_Object ns_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
+#endif /* HAVE_NS */
+
 #ifdef USE_X_TOOLKIT
 static void x_update_menu_appearance P_ ((struct frame *));
 
@@ -766,6 +781,31 @@
 
 #endif  /* WINDOWSNT */
 
+#ifdef HAVE_NS
+/* NS emulation of GCs */
+
+static INLINE GC
+x_create_gc (f, mask, xgcv)
+     struct frame *f;
+     unsigned long mask;
+     XGCValues *xgcv;
+{
+  GC gc = xmalloc (sizeof (*gc));
+  if (gc)
+      bcopy(xgcv, gc, sizeof(XGCValues));
+  return gc;
+}
+
+static INLINE void
+x_free_gc (f, gc)
+     struct frame *f;
+     GC gc;
+{
+  if (gc)
+      xfree (gc);
+}
+#endif  /* HAVE_NS */
+
 #ifdef MAC_OS
 /* Mac OS emulation of GCs */
 
@@ -872,8 +912,11 @@
 #ifdef MAC_OS
   if (!FRAME_MAC_P (f) || FRAME_MAC_WINDOW (f))
 #endif
+#ifdef HAVE_NS
+  if (!FRAME_NS_P (f) || FRAME_NS_WINDOW (f))
+#endif
     if (!realize_basic_faces (f))
-      abort ();
+        abort ();
 }
 
 
@@ -1269,6 +1312,10 @@
   else if (FRAME_MAC_P (f))
     return mac_defined_color (f, color_name, color_def, alloc);
 #endif
+#ifdef HAVE_NS
+  else if (FRAME_NS_P (f))
+    return ns_defined_color (f, color_name, color_def, alloc, 1);
+#endif
   else
     abort ();
 }
@@ -1558,6 +1605,7 @@
      struct frame *f;
      struct face *face;
 {
+/* PENDING(NS): need to do something here? */
 #ifdef HAVE_X_WINDOWS
   if (face->colors_copied_bitwise_p)
     return;
@@ -2754,7 +2802,7 @@
 		}
 	      else if (EQ (keyword, QCstipple))
 		{
-#ifdef HAVE_X_WINDOWS
+#if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
 		  Lisp_Object pixmap_p = Fbitmap_spec_p (value);
 		  if (!NILP (pixmap_p))
 		    to[LFACE_STIPPLE_INDEX] = value;
@@ -3262,14 +3310,14 @@
     }
   else if (EQ (attr, QCstipple))
     {
-#ifdef HAVE_X_WINDOWS
+#if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
       if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
 	  && !NILP (value)
 	  && NILP (Fbitmap_spec_p (value)))
 	signal_error ("Invalid stipple attribute", value);
       old_value = LFACE_STIPPLE (lface);
       LFACE_STIPPLE (lface) = value;
-#endif /* HAVE_X_WINDOWS */
+#endif /* HAVE_X_WINDOWS || HAVE_NS */
     }
   else if (EQ (attr, QCwidth))
     {