diff --git a/src/INSTALLmac.txt b/src/INSTALLmac.txt
index e957682..ac122c3 100644
--- a/src/INSTALLmac.txt
+++ b/src/INSTALLmac.txt
@@ -16,7 +16,7 @@
 ----------------------------------------------------------------------------
 
 1 MacOS X
- 1.1. Carbon interface
+ 1.1. Terminal version
  1.2. X (Athena, GTK, Motif) or plain text.
 
 MacOS Classic is no longer supported.  If you really want it use Vim 6.4.
@@ -27,9 +27,9 @@
 
 1.0 Considerations
 
- Only '/' supported as path separator.
+ Only '/' is supported as path separator.
 
-1.1 Carbon interface (default)
+1.1 Terminal version (default)
 
  You can compile vim with the standard Unix routine:
    cd .../src
@@ -37,14 +37,7 @@
    make test
    sudo make install
 
- "make" will create a working Vim.app application bundle in the src
- directory.  You can move this bundle (the Vim.app directory) anywhere
- you want.  Or use "make install" to move it to /Applications.
-
- You need at least Xcode 1.5 to compile Vim 7.0.
-
- Configure will create a universal binary if possible.  This requires
- installing the universal SDK (currently for 10.4).
+ You need at least Xcode 1.5.
 
  To overrule the architecture do this before running make:
 
@@ -53,17 +46,16 @@
 	./configure --with-mac-arch=ppc
 
 
-1.2 X-Windows or Plain Text
+1.2 X-Windows
 
- If you do not want the Carbon interface, you must explicitly tell
- configure to use a different GUI.
+ You must explicitly tell configure to use a GUI.
 
   cd .../src
   ./configure --disable-darwin --enable-gui=gtk2
   make; make install
 
- NOTE: The following GUI options are supported:
-	no (for text), motif, athena, nextaw
+ NOTE: The following GUI options are possible (but might not work):
+	no (for terminal only), motif, athena, nextaw
 	gtk, gtk2, gnome, gnome2,
 
  NOTE: You need to first install XFree86 and XDarwin.
diff --git a/src/Makefile b/src/Makefile
index 5d73fc9..35fe41e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1373,24 +1373,6 @@
 PHOTONGUI_TESTTARGET = gui
 PHOTONGUI_BUNDLE =
 
-# CARBON GUI
-CARBONGUI_SRC	= gui.c gui_mac.c
-CARBONGUI_OBJ	= objects/gui.o objects/gui_mac.o
-CARBONGUI_DEFS	= -DFEAT_GUI_MAC -fno-common -fpascal-strings \
-		  -Wall -Wno-unknown-pragmas \
-		  -mdynamic-no-pic -pipe
-CARBONGUI_IPATH	= -I. -Iproto
-CARBONGUI_LIBS_DIR =
-CARBONGUI_LIBS1	= -framework Carbon
-CARBONGUI_LIBS2	=
-CARBONGUI_INSTALL = install_macosx
-CARBONGUI_TARGETS =
-CARBONGUI_MAN_TARGETS =
-CARBONGUI_TESTTARGET = gui
-CARBONGUI_BUNDLE = gui_bundle
-APPDIR = $(VIMNAME).app
-CARBONGUI_TESTARG = VIMPROG=../$(APPDIR)/Contents/MacOS/$(VIMTARGET)
-
 ### Haiku GUI
 HAIKUGUI_SRC	= gui.c gui_haiku.cc
 HAIKUGUI_OBJ	= objects/gui.o objects/gui_haiku.o
diff --git a/src/auto/configure b/src/auto/configure
index 54ee35d..fcb2f40 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -829,7 +829,6 @@
 enable_motif_check
 enable_athena_check
 enable_nextaw_check
-enable_carbon_check
 enable_gtktest
 with_gnome_includes
 with_gnome_libs
@@ -1509,7 +1508,6 @@
   --enable-motif-check    If auto-select GUI, check for Motif default=yes
   --enable-athena-check   If auto-select GUI, check for Athena default=yes
   --enable-nextaw-check   If auto-select GUI, check for neXtaw default=yes
-  --enable-carbon-check   If auto-select GUI, check for Carbon default=yes
   --disable-gtktest       Do not try to compile and run a test GTK program
   --disable-icon-cache-update        update disabled
   --disable-desktop-database-update  update disabled
@@ -4746,8 +4744,18 @@
     OS_EXTRA_SRC="os_macosx.m os_mac_conv.c";
     OS_EXTRA_OBJ="objects/os_macosx.o objects/os_mac_conv.o"
             CPPFLAGS="$CPPFLAGS -DMACOS_X_DARWIN"
+  fi
 
-                # On IRIX 5.3, sys/types and inttypes.h are conflicting.
+        if test "$MACARCH" = "intel" -o "$MACARCH" = "both"; then
+    CFLAGS=`echo "$CFLAGS" | sed 's/-O[23456789]/-Oz/'`
+  fi
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
 for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
 		  inttypes.h stdint.h unistd.h
 do :
@@ -4764,28 +4772,6 @@
 done
 
 
-ac_fn_c_check_header_mongrel "$LINENO" "Carbon/Carbon.h" "ac_cv_header_Carbon_Carbon_h" "$ac_includes_default"
-if test "x$ac_cv_header_Carbon_Carbon_h" = xyes; then :
-  CARBON=yes
-fi
-
-
-    if test "x$CARBON" = "xyes"; then
-      if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk2 -a "X$enable_gui" != Xgtk3; then
-	with_x=no
-      fi
-    fi
-  fi
-
-        if test "$MACARCH" = "intel" -o "$MACARCH" = "both"; then
-    CFLAGS=`echo "$CFLAGS" | sed 's/-O[23456789]/-Oz/'`
-  fi
-
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
 for ac_header in AvailabilityMacros.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "AvailabilityMacros.h" "ac_cv_header_AvailabilityMacros_h" "$ac_includes_default"
@@ -9212,7 +9198,6 @@
 SKIP_NEXTAW=YES
 SKIP_PHOTON=YES
 SKIP_HAIKU=YES
-SKIP_CARBON=YES
 GUITYPE=NONE
 
 if test "x$HAIKU" = "xyes"; then
@@ -9247,25 +9232,6 @@
 		SKIP_PHOTON=YES ;;
   esac
 
-elif test "x$MACOS_X" = "xyes" -a "x$with_x" = "xno" ; then
-  SKIP_CARBON=
-  case "$enable_gui_canon" in
-    no)		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no GUI support" >&5
-$as_echo "no GUI support" >&6; }
-		SKIP_CARBON=YES ;;
-    yes|"")	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes - automatic GUI support" >&5
-$as_echo "yes - automatic GUI support" >&6; }
-    		gui_auto=yes ;;
-    auto)	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: auto - Carbon GUI is outdated - disable GUI support" >&5
-$as_echo "auto - Carbon GUI is outdated - disable GUI support" >&6; }
-		SKIP_CARBON=YES ;;
-    carbon)	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Carbon GUI support" >&5
-$as_echo "Carbon GUI support" >&6; } ;;
-    *)		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Sorry, $enable_gui GUI is not supported" >&5
-$as_echo "Sorry, $enable_gui GUI is not supported" >&6; }
-		SKIP_CARBON=YES ;;
-  esac
-
 else
 
   case "$enable_gui_canon" in
@@ -9278,8 +9244,7 @@
 		SKIP_GNOME=
 		SKIP_MOTIF=
 		SKIP_ATHENA=
-		SKIP_NEXTAW=
-		SKIP_CARBON=;;
+		SKIP_NEXTAW=;;
     gtk2)	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: GTK+ 2.x GUI support" >&5
 $as_echo "GTK+ 2.x GUI support" >&6; }
 		SKIP_GTK2=;;
@@ -9409,56 +9374,6 @@
   fi
 fi
 
-if test "x$SKIP_CARBON" != "xYES" -a "$enable_gui_canon" != "carbon"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether or not to look for Carbon" >&5
-$as_echo_n "checking whether or not to look for Carbon... " >&6; }
-  # Check whether --enable-carbon-check was given.
-if test "${enable_carbon_check+set}" = set; then :
-  enableval=$enable_carbon_check;
-else
-  enable_carbon_check="yes"
-fi
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_carbon_check" >&5
-$as_echo "$enable_carbon_check" >&6; };
-  if test "x$enable_carbon_check" = "xno"; then
-    SKIP_CARBON=YES
-  fi
-fi
-
-
-if test "x$MACOS_X" = "xyes" -a -z "$SKIP_CARBON" -a "x$CARBON" = "xyes"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Carbon GUI" >&5
-$as_echo_n "checking for Carbon GUI... " >&6; }
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; };
-  GUITYPE=CARBONGUI
-  if test "$VIMNAME" = "vim"; then
-    VIMNAME=Vim
-  fi
-
-  if test "x$MACARCH" = "xboth"; then
-    CPPFLAGS="$CPPFLAGS -I$DEVELOPER_DIR/SDKs/MacOSX10.4u.sdk/Developer/Headers/FlatCarbon"
-  else
-    CPPFLAGS="$CPPFLAGS -I$DEVELOPER_DIR/Headers/FlatCarbon"
-  fi
-
-    if test x$prefix = xNONE; then
-    prefix=/Applications
-  fi
-
-    datadir='${prefix}/Vim.app/Contents/Resources'
-
-    SKIP_GTK2=YES;
-  SKIP_GNOME=YES;
-  SKIP_MOTIF=YES;
-  SKIP_ATHENA=YES;
-  SKIP_NEXTAW=YES;
-  SKIP_PHOTON=YES;
-  SKIP_HAIKU=YES;
-  SKIP_CARBON=YES
-fi
-
 
 
 
@@ -14860,11 +14775,7 @@
 if test "$MACOS_X" = "yes"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need macOS frameworks" >&5
 $as_echo_n "checking whether we need macOS frameworks... " >&6; }
-  if test "$GUITYPE" = "CARBONGUI"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, we need Carbon" >&5
-$as_echo "yes, we need Carbon" >&6; }
-    LIBS="$LIBS -framework Carbon"
-  elif test "$MACOS_X_DARWIN" = "yes"; then
+  if test "$MACOS_X_DARWIN" = "yes"; then
     if test "$features" = "tiny"; then
             OS_EXTRA_SRC=`echo "$OS_EXTRA_SRC" | sed -e 's+os_macosx.m++'`
       OS_EXTRA_OBJ=`echo "$OS_EXTRA_OBJ" | sed -e 's+objects/os_macosx.o++'`
@@ -14881,9 +14792,6 @@
 $as_echo "no" >&6; }
   fi
 fi
-if test "x$MACARCH" = "xboth" && test "x$GUITYPE" = "xCARBONGUI"; then
-  LDFLAGS="$LDFLAGS -isysroot $DEVELOPER_DIR/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc"
-fi
 
 DEPEND_CFLAGS_FILTER=
 if test "$GCC" = yes; then
diff --git a/src/configure.ac b/src/configure.ac
index 054ea1d..8a5216a 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -262,16 +262,6 @@
     dnl TODO: use -arch i386 on Intel machines
     dnl Removed -no-cpp-precomp, only for very old compilers.
     CPPFLAGS="$CPPFLAGS -DMACOS_X_DARWIN"
-
-    dnl If Carbon is found, assume we don't want X11
-    dnl unless it was specifically asked for (--with-x)
-    dnl or Motif, Athena or GTK GUI is used.
-    AC_CHECK_HEADER(Carbon/Carbon.h, CARBON=yes)
-    if test "x$CARBON" = "xyes"; then
-      if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk2 -a "X$enable_gui" != Xgtk3; then
-	with_x=no
-      fi
-    fi
   fi
 
   dnl Avoid a bug with -O2 with gcc 4.0.1.  Symptom: malloc() reports double
@@ -2406,7 +2396,6 @@
 SKIP_NEXTAW=YES
 SKIP_PHOTON=YES
 SKIP_HAIKU=YES
-SKIP_CARBON=YES
 GUITYPE=NONE
 
 if test "x$HAIKU" = "xyes"; then
@@ -2432,20 +2421,6 @@
 		SKIP_PHOTON=YES ;;
   esac
 
-elif test "x$MACOS_X" = "xyes" -a "x$with_x" = "xno" ; then
-  SKIP_CARBON=
-  case "$enable_gui_canon" in
-    no)		AC_MSG_RESULT(no GUI support)
-		SKIP_CARBON=YES ;;
-    yes|"")	AC_MSG_RESULT(yes - automatic GUI support)
-    		gui_auto=yes ;;
-    auto)	AC_MSG_RESULT(auto - Carbon GUI is outdated - disable GUI support)
-		SKIP_CARBON=YES ;;
-    carbon)	AC_MSG_RESULT(Carbon GUI support) ;;
-    *)		AC_MSG_RESULT([Sorry, $enable_gui GUI is not supported])
-		SKIP_CARBON=YES ;;
-  esac
-
 else
 
   case "$enable_gui_canon" in
@@ -2456,8 +2431,7 @@
 		SKIP_GNOME=
 		SKIP_MOTIF=
 		SKIP_ATHENA=
-		SKIP_NEXTAW=
-		SKIP_CARBON=;;
+		SKIP_NEXTAW=;;
     gtk2)	AC_MSG_RESULT(GTK+ 2.x GUI support)
 		SKIP_GTK2=;;
     gnome2)	AC_MSG_RESULT(GNOME 2.x GUI support)
@@ -2544,52 +2518,6 @@
   fi
 fi
 
-if test "x$SKIP_CARBON" != "xYES" -a "$enable_gui_canon" != "carbon"; then
-  AC_MSG_CHECKING(whether or not to look for Carbon)
-  AC_ARG_ENABLE(carbon-check,
-	[  --enable-carbon-check   If auto-select GUI, check for Carbon [default=yes]],
-	, enable_carbon_check="yes")
-  AC_MSG_RESULT($enable_carbon_check);
-  if test "x$enable_carbon_check" = "xno"; then
-    SKIP_CARBON=YES
-  fi
-fi
-
-
-if test "x$MACOS_X" = "xyes" -a -z "$SKIP_CARBON" -a "x$CARBON" = "xyes"; then
-  AC_MSG_CHECKING(for Carbon GUI)
-  dnl already did the check, just give the message
-  AC_MSG_RESULT(yes);
-  GUITYPE=CARBONGUI
-  if test "$VIMNAME" = "vim"; then
-    VIMNAME=Vim
-  fi
-
-  if test "x$MACARCH" = "xboth"; then
-    CPPFLAGS="$CPPFLAGS -I$DEVELOPER_DIR/SDKs/MacOSX10.4u.sdk/Developer/Headers/FlatCarbon"
-  else
-    CPPFLAGS="$CPPFLAGS -I$DEVELOPER_DIR/Headers/FlatCarbon"
-  fi
-
-  dnl Default install directory is not /usr/local
-  if test x$prefix = xNONE; then
-    prefix=/Applications
-  fi
-
-  dnl Sorry for the hard coded default
-  datadir='${prefix}/Vim.app/Contents/Resources'
-
-  dnl skip everything else
-  SKIP_GTK2=YES;
-  SKIP_GNOME=YES;
-  SKIP_MOTIF=YES;
-  SKIP_ATHENA=YES;
-  SKIP_NEXTAW=YES;
-  SKIP_PHOTON=YES;
-  SKIP_HAIKU=YES;
-  SKIP_CARBON=YES
-fi
-
 dnl define an autoconf function to check for a specified version of GTK, and
 dnl try to compile/link a GTK program.
 dnl
@@ -4454,10 +4382,7 @@
 
 if test "$MACOS_X" = "yes"; then
   AC_MSG_CHECKING([whether we need macOS frameworks])
-  if test "$GUITYPE" = "CARBONGUI"; then
-    AC_MSG_RESULT([yes, we need Carbon])
-    LIBS="$LIBS -framework Carbon"
-  elif test "$MACOS_X_DARWIN" = "yes"; then
+  if test "$MACOS_X_DARWIN" = "yes"; then
     if test "$features" = "tiny"; then
       dnl Since no FEAT_CLIPBOARD, no longer need for os_macosx.m.
       OS_EXTRA_SRC=`echo "$OS_EXTRA_SRC" | sed -e 's+os_macosx.m++'`
@@ -4472,9 +4397,6 @@
     AC_MSG_RESULT([no])
   fi
 fi
-if test "x$MACARCH" = "xboth" && test "x$GUITYPE" = "xCARBONGUI"; then
-  LDFLAGS="$LDFLAGS -isysroot $DEVELOPER_DIR/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc"
-fi
 
 dnl gcc 3.1 changed the meaning of -MM.  The only solution appears to be to
 dnl use "-isystem" instead of "-I" for all non-Vim include dirs.
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 5607ef9..bbc3404 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -3920,13 +3920,7 @@
 		0
 #endif
 		},
-	{"gui_mac",
-#ifdef FEAT_GUI_MAC
-		1
-#else
-		0
-#endif
-		},
+	{"gui_mac", 0},
 	{"gui_motif",
 #ifdef FEAT_GUI_MOTIF
 		1
diff --git a/src/feature.h b/src/feature.h
index 4917527..0c68f79 100644
--- a/src/feature.h
+++ b/src/feature.h
@@ -632,7 +632,6 @@
 #if defined(FEAT_NORMAL) \
     && (defined(FEAT_GUI_GTK) \
 	|| (defined(FEAT_GUI_MOTIF) && defined(HAVE_XM_NOTEBOOK_H)) \
-	|| defined(FEAT_GUI_MAC) \
 	|| defined(FEAT_GUI_HAIKU) \
 	|| (defined(FEAT_GUI_MSWIN) \
 	    && (!defined(_MSC_VER) || _MSC_VER > 1020)))
@@ -646,8 +645,7 @@
 #if defined(FEAT_NORMAL)
 # define FEAT_BROWSE_CMD
 # if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) \
-	|| defined(FEAT_GUI_GTK) || defined(FEAT_GUI_HAIKU) || defined(FEAT_GUI_PHOTON) \
-	|| defined(FEAT_GUI_MAC)
+	|| defined(FEAT_GUI_GTK) || defined(FEAT_GUI_HAIKU) || defined(FEAT_GUI_PHOTON)
 #  define FEAT_BROWSE
 # endif
 #endif
@@ -657,8 +655,7 @@
  * there is no terminal version, and on Windows we can't figure out how to
  * fork one off with :gui.
  */
-#if (defined(FEAT_GUI_MSWIN) && !defined(VIMDLL)) \
-	    || (defined(FEAT_GUI_MAC) && !defined(MACOS_X_DARWIN))
+#if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL)
 # define ALWAYS_USE_GUI
 #endif
 
@@ -673,8 +670,7 @@
 	|| defined(FEAT_GUI_GTK) \
 	|| defined(FEAT_GUI_PHOTON) \
 	|| defined(FEAT_GUI_HAIKU) \
-	|| defined(FEAT_GUI_MSWIN) \
-	|| defined(FEAT_GUI_MAC)
+	|| defined(FEAT_GUI_MSWIN)
 #  define FEAT_CON_DIALOG
 #  define FEAT_GUI_DIALOG
 # else
@@ -690,7 +686,7 @@
 #if defined(FEAT_GUI_DIALOG) && \
 	(defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) \
 	 || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MSWIN) \
-	 || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) \
+	 || defined(FEAT_GUI_PHOTON) \
 	 || defined(FEAT_GUI_HAIKU))
 # define FEAT_GUI_TEXTDIALOG
 # ifndef ALWAYS_USE_GUI
@@ -705,11 +701,6 @@
 # define FEAT_TERMGUICOLORS
 #endif
 
-// Mac specific thing: Codewarrior interface.
-#ifdef FEAT_GUI_MAC
-# define FEAT_CW_EDITOR
-#endif
-
 /*
  * +vartabs		'vartabstop' and 'varsofttabstop' options.
  */
@@ -1091,8 +1082,7 @@
 #endif
 
 #if defined(FEAT_MZSCHEME) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_GTK)    \
-	|| defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)	\
-	|| defined(FEAT_GUI_MAC))
+	|| defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA))
 # define MZSCHEME_GUI_THREADS
 #endif
 
diff --git a/src/fileio.c b/src/fileio.c
index 189d4f4..3611093 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -403,11 +403,6 @@
 	     */
 	    swap_mode = (st.st_mode & 0644) | 0600;
 #endif
-#ifdef FEAT_CW_EDITOR
-	    // Get the FSSpec on MacOS
-	    // TODO: Update it properly when the buffer name changes
-	    (void)GetFSSpecFromPath(curbuf->b_ffname, &curbuf->b_FSSpec);
-#endif
 #ifdef VMS
 	    curbuf->b_fab_rfm = st.st_fab_rfm;
 	    curbuf->b_fab_rat = st.st_fab_rat;
@@ -3389,7 +3384,6 @@
 
 #if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \
 	|| defined(FEAT_GUI_MSWIN) \
-	|| defined(FEAT_GUI_MAC) \
 	|| defined(FEAT_GUI_HAIKU) \
 	|| defined(PROTO)
 /*
diff --git a/src/globals.h b/src/globals.h
index 72b8a1e..f64a874 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1569,7 +1569,7 @@
 #if defined(FEAT_GUI) && defined(FEAT_XFONTSET)
 EXTERN char e_fontset[]	INIT(= N_("E234: Unknown fontset: %s"));
 #endif
-#if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MAC) \
+#if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) \
 	|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_HAIKU)
 EXTERN char e_font[]		INIT(= N_("E235: Unknown font: %s"));
 #endif
@@ -1806,10 +1806,6 @@
 EXTERN char e_alloc_color[]	INIT(= N_("E254: Cannot allocate color %s"));
 #endif
 
-#ifdef FEAT_GUI_MAC
-EXTERN short disallow_gui	INIT(= FALSE);
-#endif
-
 EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
 EXTERN char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP"));
 
diff --git a/src/gui.c b/src/gui.c
index 5d003a3..5ae29fa 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -56,7 +56,7 @@
  * this makes the thumb indicate the part of the text that is shown.  Motif
  * can't do this.
  */
-#if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MAC)
+#if defined(FEAT_GUI_ATHENA)
 # define SCROLL_PAST_END
 #endif
 
@@ -846,7 +846,7 @@
 }
 
 #if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_MSWIN) \
-	|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(PROTO)
+	|| defined(FEAT_GUI_PHOTON) || defined(PROTO)
 # define NEED_GUI_UPDATE_SCREEN 1
 /*
  * Called when the GUI shell is closed by the user.  If there are no changed
@@ -1377,7 +1377,7 @@
 #endif
 
 # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
-	|| defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
+	|| defined(FEAT_GUI_MOTIF))
     if (gui_has_tabline())
 	text_area_y += gui.tabline_height;
 #endif
diff --git a/src/gui.h b/src/gui.h
index cfc4448..8b8b7fb 100644
--- a/src/gui.h
+++ b/src/gui.h
@@ -39,25 +39,6 @@
 # include <X11/Intrinsic.h>
 #endif
 
-#ifdef FEAT_GUI_MAC
-# include <Types.h>
-/*# include <Memory.h>*/
-# include <Quickdraw.h>
-# include <Fonts.h>
-# include <Events.h>
-# include <Menus.h>
-# if !(defined (TARGET_API_MAC_CARBON) && (TARGET_API_MAC_CARBON))
-#  include <Windows.h>
-# endif
-# include <Controls.h>
-/*# include <TextEdit.h>*/
-# include <Dialogs.h>
-# include <OSUtils.h>
-/*
-# include <ToolUtils.h>
-# include <SegLoad.h>*/
-#endif
-
 #ifdef FEAT_GUI_PHOTON
 # include <Ph.h>
 # include <Pt.h>
@@ -68,7 +49,7 @@
  * On some systems scrolling needs to be done right away instead of in the
  * main loop.
  */
-#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_GTK)
+#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_GTK)
 # define USE_ON_FLY_SCROLL
 #endif
 
@@ -77,7 +58,6 @@
  */
 #if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \
 	|| defined(FEAT_GUI_MSWIN) \
-	|| defined(FEAT_GUI_MAC) \
 	|| defined(FEAT_GUI_HAIKU)
 # define HAVE_DROP_FILE
 #endif
@@ -209,9 +189,6 @@
 #if FEAT_GUI_HAIKU
     VimScrollBar *id;		// Pointer to real scroll bar
 #endif
-#ifdef FEAT_GUI_MAC
-    ControlHandle id;		// A handle to the scrollbar
-#endif
 #ifdef FEAT_GUI_PHOTON
     PtWidget_t	*id;
 #endif
@@ -435,7 +412,7 @@
 
 #if defined(FEAT_GUI_TABLINE) \
 	&& (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) \
-		|| defined(FEAT_GUI_MAC) || defined(FEAT_GUI_HAIKU))
+		|| defined(FEAT_GUI_HAIKU))
     int		tabline_height;
 #endif
 
@@ -473,14 +450,6 @@
     int	vdcmp;			    // Vim Direct Communication Message Port
 #endif
 
-#ifdef FEAT_GUI_MAC
-    WindowPtr	VimWindow;
-    MenuHandle	MacOSHelpMenu;	    // Help menu provided by the MacOS
-    int		MacOSHelpItems;	    // Nr of help-items supplied by MacOS
-    WindowPtr	wid;		    // Window id of text area
-    int		visibility;	    // Is window partially/fully obscured?
-#endif
-
 #ifdef FEAT_GUI_PHOTON
     PtWidget_t	*vimWindow;		// PtWindow
     PtWidget_t	*vimTextArea;		// PtRaw
@@ -599,6 +568,6 @@
 # endif
 #endif // FEAT_GUI_GTK
 
-#if defined(UNIX) && !defined(FEAT_GUI_MAC)
+#if defined(UNIX)
 # define GUI_MAY_FORK
 #endif
diff --git a/src/gui_mac.c b/src/gui_mac.c
deleted file mode 100644
index b190617..0000000
--- a/src/gui_mac.c
+++ /dev/null
@@ -1,6706 +0,0 @@
-/* vi:set ts=8 sts=4 sw=4 noet:
- *
- * VIM - Vi IMproved		by Bram Moolenaar
- *				GUI/Motif support by Robert Webb
- *				Macintosh port by Dany St-Amant
- *					      and Axel Kielhorn
- *				Port to MPW by Bernhard Pruemmer
- *				Initial Carbon port by Ammon Skidmore
- *
- * Do ":help uganda"  in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
- */
-
-/*
- * NOTES: - Vim 7+ does not support classic MacOS. Please use Vim 6.x
- *	  - Comments mentioning FAQ refer to the book:
- *	    "Macworld Mac Programming FAQs" from "IDG Books"
- */
-
-/*
- * TODO: Change still to merge from the macvim's iDisk
- *
- * error_ga, mch_errmsg, Navigation's changes in gui_mch_browse
- * uses of MenuItemIndex, changes in gui_mch_set_shellsize,
- * ScrapManager error handling.
- * Comments about function remaining to Carbonize.
- *
- */
-
-/*
- * TODO (Jussi)
- *   * Clipboard does not work (at least some cases)
- *   * ATSU font rendering has some problems
- *   * Investigate and remove dead code (there is still lots of that)
- */
-
-#include <Devices.h> // included first to avoid CR problems
-#include "vim.h"
-
-#define USE_CARBONIZED
-#define USE_AEVENT		// Enable AEVENT
-#undef USE_OFFSETED_WINDOW	// Debugging feature: start Vim window OFFSETed
-
-// Compile as CodeWarrior External Editor
-#if defined(FEAT_CW_EDITOR) && !defined(USE_AEVENT)
-# define USE_AEVENT // Need Apple Event Support
-#endif
-
-// Vim's Scrap flavor.
-#define VIMSCRAPFLAVOR 'VIM!'
-#define SCRAPTEXTFLAVOR kScrapFlavorTypeUnicode
-
-static EventHandlerUPP mouseWheelHandlerUPP = NULL;
-SInt32 gMacSystemVersion;
-
-#ifdef MACOS_CONVERT
-# define USE_CARBONKEYHANDLER
-
-static int im_is_active = FALSE;
-# if 0
-    // TODO: Implement me!
-static int im_start_row = 0;
-static int im_start_col = 0;
-# endif
-
-# define NR_ELEMS(x)	(sizeof(x) / sizeof(x[0]))
-
-static TSMDocumentID gTSMDocument;
-
-static void im_on_window_switch(int active);
-static EventHandlerUPP keyEventHandlerUPP = NULL;
-static EventHandlerUPP winEventHandlerUPP = NULL;
-
-static pascal OSStatus gui_mac_handle_window_activate(
-	EventHandlerCallRef nextHandler, EventRef theEvent, void *data);
-
-static pascal OSStatus gui_mac_handle_text_input(
-	EventHandlerCallRef nextHandler, EventRef theEvent, void *data);
-
-static pascal OSStatus gui_mac_update_input_area(
-	EventHandlerCallRef nextHandler, EventRef theEvent);
-
-static pascal OSStatus gui_mac_unicode_key_event(
-	EventHandlerCallRef nextHandler, EventRef theEvent);
-
-#endif
-
-
-// Include some file. TODO: move into os_mac.h
-#include <Menus.h>
-#include <Resources.h>
-#include <Processes.h>
-#ifdef USE_AEVENT
-# include <AppleEvents.h>
-# include <AERegistry.h>
-#endif
-# include <Gestalt.h>
-#if UNIVERSAL_INTERFACES_VERSION >= 0x0330
-# include <ControlDefinitions.h>
-# include <Navigation.h>  // Navigation only part of ??
-#endif
-
-// Help Manager (balloon.h, HM prefixed functions) are not supported
-// under Carbon (Jussi)
-#  if 0
-// New Help Interface for Mac, not implemented yet.
-#    include <MacHelp.h>
-#  endif
-
-/*
- * These seem to be rectangle options. Why are they not found in
- * headers? (Jussi)
- */
-#define kNothing 0
-#define kCreateEmpty 2 //1
-#define kCreateRect 2
-#define kDestroy 3
-
-/*
- * Dany: Don't like those...
- */
-#define topLeft(r)	(((Point*)&(r))[0])
-#define botRight(r)	(((Point*)&(r))[1])
-
-
-// Time of last mouse click, to detect double-click
-static long lastMouseTick = 0;
-
-// ???
-static RgnHandle cursorRgn;
-static RgnHandle dragRgn;
-static Rect dragRect;
-static short dragRectEnbl;
-static short dragRectControl;
-
-// This variable is set when waiting for an event, which is the only moment
-// scrollbar dragging can be done directly.  It's not allowed while commands
-// are executed, because it may move the cursor and that may cause unexpected
-// problems (e.g., while ":s" is working).
-static int allow_scrollbar = FALSE;
-
-// Last mouse click caused contextual menu, (to provide proper release)
-static short clickIsPopup;
-
-// Feedback Action for Scrollbar
-ControlActionUPP gScrollAction;
-ControlActionUPP gScrollDrag;
-
-// Keeping track of which scrollbar is being dragged
-static ControlHandle dragged_sb = NULL;
-
-// Vector of char_u --> control index for hotkeys in dialogs
-static short *gDialogHotKeys;
-
-static struct
-{
-    FMFontFamily family;
-    FMFontSize size;
-    FMFontStyle style;
-    Boolean isPanelVisible;
-} gFontPanelInfo = { 0, 0, 0, false };
-
-#ifdef MACOS_CONVERT
-# define USE_ATSUI_DRAWING
-int	    p_macatsui_last;
-ATSUStyle   gFontStyle;
-ATSUStyle   gWideFontStyle;
-Boolean	    gIsFontFallbackSet;
-UInt32      useAntialias_cached = 0x0;
-#endif
-
-// Colors Macros
-#define RGB(r,g,b)	((r) << 16) + ((g) << 8) + (b)
-#define Red(c)		((c & 0x00FF0000) >> 16)
-#define Green(c)	((c & 0x0000FF00) >>  8)
-#define Blue(c)		((c & 0x000000FF) >>  0)
-
-// Key mapping
-
-#define vk_Esc		0x35	// -> 1B
-
-#define vk_F1		0x7A	// -> 10
-#define vk_F2		0x78  //0x63
-#define vk_F3		0x63  //0x76
-#define vk_F4		0x76  //0x60
-#define vk_F5		0x60  //0x61
-#define vk_F6		0x61  //0x62
-#define vk_F7		0x62  //0x63 ?
-#define vk_F8		0x64
-#define vk_F9		0x65
-#define vk_F10		0x6D
-#define vk_F11		0x67
-#define vk_F12		0x6F
-#define vk_F13		0x69
-#define vk_F14		0x6B
-#define vk_F15		0x71
-
-#define vk_Clr		0x47	// -> 1B (ESC)
-#define vk_Enter	0x4C	// -> 03
-
-#define vk_Space	0x31	// -> 20
-#define vk_Tab		0x30	// -> 09
-#define vk_Return	0x24	// -> 0D
-// This is wrong for OSX, what is it for?
-#define vk_Delete	0X08	// -> 08 BackSpace
-
-#define vk_Help		0x72	// -> 05
-#define vk_Home		0x73	// -> 01
-#define	vk_PageUp	0x74	// -> 0D
-#define vk_FwdDelete	0x75	// -> 7F
-#define	vk_End		0x77	// -> 04
-#define vk_PageDown	0x79	// -> 0C
-
-#define vk_Up		0x7E	// -> 1E
-#define vk_Down		0x7D	// -> 1F
-#define	vk_Left		0x7B	// -> 1C
-#define vk_Right	0x7C	// -> 1D
-
-#define vk_Undo		vk_F1
-#define vk_Cut		vk_F2
-#define	vk_Copy		vk_F3
-#define	vk_Paste	vk_F4
-#define vk_PrintScreen	vk_F13
-#define vk_SCrollLock	vk_F14
-#define	vk_Pause	vk_F15
-#define	vk_NumLock	vk_Clr
-#define vk_Insert	vk_Help
-
-#define KeySym	char
-
-static struct
-{
-    KeySym  key_sym;
-    char_u  vim_code0;
-    char_u  vim_code1;
-} special_keys[] =
-{
-    {vk_Up,		'k', 'u'},
-    {vk_Down,		'k', 'd'},
-    {vk_Left,		'k', 'l'},
-    {vk_Right,		'k', 'r'},
-
-    {vk_F1,		'k', '1'},
-    {vk_F2,		'k', '2'},
-    {vk_F3,		'k', '3'},
-    {vk_F4,		'k', '4'},
-    {vk_F5,		'k', '5'},
-    {vk_F6,		'k', '6'},
-    {vk_F7,		'k', '7'},
-    {vk_F8,		'k', '8'},
-    {vk_F9,		'k', '9'},
-    {vk_F10,		'k', ';'},
-
-    {vk_F11,		'F', '1'},
-    {vk_F12,		'F', '2'},
-    {vk_F13,		'F', '3'},
-    {vk_F14,		'F', '4'},
-    {vk_F15,		'F', '5'},
-
-//  {XK_Help,		'%', '1'},
-//  {XK_Undo,		'&', '8'},
-//  {XK_BackSpace,	'k', 'b'},
-//  {vk_Delete,		'k', 'b'},
-    {vk_Insert,		'k', 'I'},
-    {vk_FwdDelete,	'k', 'D'},
-    {vk_Home,		'k', 'h'},
-    {vk_End,		'@', '7'},
-//  {XK_Prior,		'k', 'P'},
-//  {XK_Next,		'k', 'N'},
-//  {XK_Print,		'%', '9'},
-
-    {vk_PageUp,		'k', 'P'},
-    {vk_PageDown,	'k', 'N'},
-
-    // End of list marker:
-    {(KeySym)0,		0, 0}
-};
-
-/*
- * ------------------------------------------------------------
- * Forward declaration (for those needed)
- * ------------------------------------------------------------
- */
-
-#ifdef USE_AEVENT
-OSErr HandleUnusedParms(const AppleEvent *theAEvent);
-#endif
-
-#ifdef FEAT_GUI_TABLINE
-static void initialise_tabline(void);
-static WindowRef drawer = NULL; // TODO: put into gui.h
-#endif
-
-#ifdef USE_ATSUI_DRAWING
-static void gui_mac_set_font_attributes(GuiFont font);
-#endif
-
-/*
- * ------------------------------------------------------------
- * Conversion Utility
- * ------------------------------------------------------------
- */
-
-/*
- * C2Pascal_save
- *
- * Allocate memory and convert the C-String passed in
- * into a pascal string
- *
- */
-
-    char_u *
-C2Pascal_save(char_u *Cstring)
-{
-    char_u  *PascalString;
-    int	    len;
-
-    if (Cstring == NULL)
-	return NULL;
-
-    len = STRLEN(Cstring);
-
-    if (len > 255) // Truncate if necessary
-	len = 255;
-
-    PascalString = alloc(len + 1);
-    if (PascalString != NULL)
-    {
-	mch_memmove(PascalString + 1, Cstring, len);
-	PascalString[0] = len;
-    }
-
-    return PascalString;
-}
-
-/*
- * C2Pascal_save_and_remove_backslash
- *
- * Allocate memory and convert the C-String passed in
- * into a pascal string. Also remove the backslash at the same time
- *
- */
-
-    char_u *
-C2Pascal_save_and_remove_backslash(char_u *Cstring)
-{
-    char_u  *PascalString;
-    int	    len;
-    char_u  *p, *c;
-
-    len = STRLEN(Cstring);
-
-    if (len > 255) // Truncate if necessary
-	len = 255;
-
-    PascalString = alloc(len + 1);
-    if (PascalString != NULL)
-    {
-	for (c = Cstring, p = PascalString+1, len = 0; (*c != 0) && (len < 255); c++)
-	{
-	    if ((*c == '\\') && (c[1] != 0))
-		c++;
-	    *p = *c;
-	    p++;
-	    len++;
-	}
-	PascalString[0] = len;
-    }
-
-    return PascalString;
-}
-
-/*
- * Convert the modifiers of an Event into vim's modifiers (mouse)
- */
-
-    int_u
-EventModifiers2VimMouseModifiers(EventModifiers macModifiers)
-{
-    int_u vimModifiers = 0x00;
-
-    if (macModifiers & (shiftKey | rightShiftKey))
-	vimModifiers |= MOUSE_SHIFT;
-    if (macModifiers & (controlKey | rightControlKey))
-	vimModifiers |= MOUSE_CTRL;
-    if (macModifiers & (optionKey | rightOptionKey))
-	vimModifiers |= MOUSE_ALT;
-#if 0
-    // Not yet supported
-    if (macModifiers & (cmdKey)) // There's no rightCmdKey
-	vimModifiers |= MOUSE_CMD;
-#endif
-    return (vimModifiers);
-}
-
-/*
- * Convert the modifiers of an Event into vim's modifiers (keys)
- */
-
-    static int_u
-EventModifiers2VimModifiers(EventModifiers macModifiers)
-{
-    int_u vimModifiers = 0x00;
-
-    if (macModifiers & (shiftKey | rightShiftKey))
-	vimModifiers |= MOD_MASK_SHIFT;
-    if (macModifiers & (controlKey | rightControlKey))
-	vimModifiers |= MOD_MASK_CTRL;
-    if (macModifiers & (optionKey | rightOptionKey))
-	vimModifiers |= MOD_MASK_ALT;
-#ifdef USE_CMD_KEY
-    if (macModifiers & (cmdKey)) // There's no rightCmdKey
-	vimModifiers |= MOD_MASK_CMD;
-#endif
-    return (vimModifiers);
-}
-
-/*
- * Convert a string representing a point size into pixels. The string should
- * be a positive decimal number, with an optional decimal point (eg, "12", or
- * "10.5"). The pixel value is returned, and a pointer to the next unconverted
- * character is stored in *end. The flag "vertical" says whether this
- * calculation is for a vertical (height) size or a horizontal (width) one.
- *
- * From gui_w48.c
- */
-    static int
-points_to_pixels(char_u *str, char_u **end, int vertical)
-{
-    int		pixels;
-    int		points = 0;
-    int		divisor = 0;
-
-    while (*str)
-    {
-	if (*str == '.' && divisor == 0)
-	{
-	    // Start keeping a divisor, for later
-	    divisor = 1;
-	    continue;
-	}
-
-	if (!isdigit(*str))
-	    break;
-
-	points *= 10;
-	points += *str - '0';
-	divisor *= 10;
-
-	++str;
-    }
-
-    if (divisor == 0)
-	divisor = 1;
-
-    pixels = points/divisor;
-    *end = str;
-    return pixels;
-}
-
-#ifdef MACOS_CONVERT
-/*
- * Deletes all traces of any Windows-style mnemonic text (including any
- * parentheses) from a menu item and returns the cleaned menu item title.
- * The caller is responsible for releasing the returned string.
- */
-    static CFStringRef
-menu_title_removing_mnemonic(vimmenu_T *menu)
-{
-    CFStringRef		name;
-    size_t		menuTitleLen;
-    CFIndex		displayLen;
-    CFRange		mnemonicStart;
-    CFRange		mnemonicEnd;
-    CFMutableStringRef	cleanedName;
-
-    menuTitleLen = STRLEN(menu->dname);
-    name = (CFStringRef) mac_enc_to_cfstring(menu->dname, menuTitleLen);
-
-    if (name)
-    {
-	// Simple mnemonic-removal algorithm, assumes single parenthesized
-	// mnemonic character towards the end of the menu text
-	mnemonicStart = CFStringFind(name, CFSTR("("), kCFCompareBackwards);
-	displayLen = CFStringGetLength(name);
-
-	if (mnemonicStart.location != kCFNotFound
-		&& (mnemonicStart.location + 2) < displayLen
-		&& CFStringGetCharacterAtIndex(name,
-		       mnemonicStart.location + 1) == (UniChar)menu->mnemonic)
-	{
-	    if (CFStringFindWithOptions(name, CFSTR(")"),
-			CFRangeMake(mnemonicStart.location + 1,
-			    displayLen - mnemonicStart.location - 1),
-			kCFCompareBackwards, &mnemonicEnd) &&
-		    (mnemonicStart.location + 2) == mnemonicEnd.location)
-	    {
-		cleanedName = CFStringCreateMutableCopy(NULL, 0, name);
-		if (cleanedName)
-		{
-		    CFStringDelete(cleanedName,
-			    CFRangeMake(mnemonicStart.location,
-				mnemonicEnd.location + 1 -
-				mnemonicStart.location));
-
-		    CFRelease(name);
-		    name = cleanedName;
-		}
-	    }
-	}
-    }
-
-    return name;
-}
-#endif
-
-/*
- * Convert a list of FSSpec aliases into a list of fullpathname
- * character strings.
- */
-
-    char_u **
-new_fnames_from_AEDesc(AEDesc *theList, long *numFiles, OSErr *error)
-{
-    char_u	**fnames = NULL;
-    OSErr	newError;
-    long	fileCount;
-    FSSpec	fileToOpen;
-    long	actualSize;
-    AEKeyword	dummyKeyword;
-    DescType	dummyType;
-
-    // Get number of files in list
-    *error = AECountItems(theList, numFiles);
-    if (*error)
-	return fnames;
-
-    // Allocate the pointer list
-    fnames = ALLOC_MULT(char_u *, *numFiles);
-
-    // Empty out the list
-    for (fileCount = 0; fileCount < *numFiles; fileCount++)
-	fnames[fileCount] = NULL;
-
-    // Scan the list of FSSpec
-    for (fileCount = 1; fileCount <= *numFiles; fileCount++)
-    {
-	// Get the alias for the nth file, convert to an FSSpec
-	newError = AEGetNthPtr(theList, fileCount, typeFSS,
-				&dummyKeyword, &dummyType,
-				(Ptr) &fileToOpen, sizeof(FSSpec), &actualSize);
-	if (newError)
-	{
-	    // Caller is able to clean up
-	    // TODO: Should be clean up or not? For safety.
-	    return fnames;
-	}
-
-	// Convert the FSSpec to a pathname
-	fnames[fileCount - 1] = FullPathFromFSSpec_save(fileToOpen);
-    }
-
-    return (fnames);
-}
-
-/*
- * ------------------------------------------------------------
- * CodeWarrior External Editor Support
- * ------------------------------------------------------------
- */
-#ifdef FEAT_CW_EDITOR
-
-/*
- * Handle the Window Search event from CodeWarrior
- *
- * Description
- * -----------
- *
- * The IDE sends the Window Search AppleEvent to the editor when it
- * needs to know whether a particular file is open in the editor.
- *
- * Event Reply
- * -----------
- *
- * None. Put data in the location specified in the structure received.
- *
- * Remarks
- * -------
- *
- * When the editor receives this event, determine whether the specified
- * file is open. If it is, return the modification date/time for that file
- * in the appropriate location specified in the structure. If the file is
- * not opened, put the value fnfErr(file not found) in that location.
- *
- */
-
-typedef struct WindowSearch WindowSearch;
-struct WindowSearch // for handling class 'KAHL', event 'SRCH', keyDirectObject typeChar
-{
-    FSSpec theFile; // identifies the file
-    long *theDate; // where to put the modification date/time
-};
-
-    pascal OSErr
-Handle_KAHL_SRCH_AE(
-	const AppleEvent    *theAEvent,
-	AppleEvent	    *theReply,
-	long		    refCon)
-{
-    OSErr	error = noErr;
-    buf_T	*buf;
-    int		foundFile = false;
-    DescType	typeCode;
-    WindowSearch SearchData;
-    Size	actualSize;
-
-    error = AEGetParamPtr(theAEvent, keyDirectObject, typeChar, &typeCode, (Ptr) &SearchData, sizeof(WindowSearch), &actualSize);
-    if (error)
-	return error;
-
-    error = HandleUnusedParms(theAEvent);
-    if (error)
-	return error;
-
-    FOR_ALL_BUFFERS(buf)
-	if (buf->b_ml.ml_mfp != NULL
-		&& SearchData.theFile.parID == buf->b_FSSpec.parID
-		&& SearchData.theFile.name[0] == buf->b_FSSpec.name[0]
-		&& STRNCMP(SearchData.theFile.name, buf->b_FSSpec.name, buf->b_FSSpec.name[0] + 1) == 0)
-	    {
-		foundFile = true;
-		break;
-	    }
-
-    if (foundFile == false)
-	*SearchData.theDate = fnfErr;
-    else
-	*SearchData.theDate = buf->b_mtime;
-
-    return error;
-};
-
-/*
- * Handle the Modified (from IDE to Editor) event from CodeWarrior
- *
- * Description
- * -----------
- *
- * The IDE sends this event to the external editor when it wants to
- * know which files that are open in the editor have been modified.
- *
- * Parameters   None.
- * ----------
- *
- * Event Reply
- * -----------
- * The reply for this event is:
- *
- * keyDirectObject typeAEList required
- *  each element in the list is a structure of typeChar
- *
- * Remarks
- * -------
- *
- * When building the reply event, include one element in the list for
- * each open file that has been modified.
- *
- */
-
-typedef struct ModificationInfo ModificationInfo;
-struct ModificationInfo // for replying to class 'KAHL', event 'MOD ', keyDirectObject typeAEList
-{
-    FSSpec theFile; // identifies the file
-    long theDate; // the date/time the file was last modified
-    short saved; // set this to zero when replying, unused
-};
-
-    pascal OSErr
-Handle_KAHL_MOD_AE(
-	const AppleEvent    *theAEvent,
-	AppleEvent	    *theReply,
-	long		    refCon)
-{
-    OSErr	error = noErr;
-    AEDescList	replyList;
-    long	numFiles;
-    ModificationInfo theFile;
-    buf_T	*buf;
-
-    theFile.saved = 0;
-
-    error = HandleUnusedParms(theAEvent);
-    if (error)
-	return error;
-
-    // Send the reply
-//  replyObject.descriptorType = typeNull;
-// replyObject.dataHandle     = nil;
-
-// AECreateDesc(typeChar, (Ptr)&title[1], title[0], &data)
-    error = AECreateList(nil, 0, false, &replyList);
-    if (error)
-	return error;
-
-#if 0
-    error = AECountItems(&replyList, &numFiles);
-
-    // AEPutKeyDesc(&replyList, keyAEPnject, &aDesc)
-    // AEPutKeyPtr(&replyList, keyAEPosition, typeChar, (Ptr)&theType,
-    // sizeof(DescType))
-
-    // AEPutDesc
-#endif
-
-    numFiles = 0;
-    FOR_ALL_BUFFERS(buf)
-	if (buf->b_ml.ml_mfp != NULL)
-	{
-	    // Add this file to the list
-	    theFile.theFile = buf->b_FSSpec;
-	    theFile.theDate = buf->b_mtime;
-//	    theFile.theDate = time(NULL) & (time_t) 0xFFFFFFF0;
-	    error = AEPutPtr(&replyList, numFiles, typeChar, (Ptr) &theFile, sizeof(theFile));
-	};
-
-#if 0
-    error = AECountItems(&replyList, &numFiles);
-#endif
-
-    // We can add data only if something to reply
-    error = AEPutParamDesc(theReply, keyDirectObject, &replyList);
-
-    if (replyList.dataHandle)
-	AEDisposeDesc(&replyList);
-
-    return error;
-};
-
-/*
- * Handle the Get Text event from CodeWarrior
- *
- * Description
- * -----------
- *
- * The IDE sends the Get Text AppleEvent to the editor when it needs
- * the source code from a file. For example, when the user issues a
- * Check Syntax or Compile command, the compiler needs access to
- * the source code contained in the file.
- *
- * Event Reply
- * -----------
- *
- * None. Put data in locations specified in the structure received.
- *
- * Remarks
- * -------
- *
- * When the editor receives this event, it must set the size of the handle
- * in theText to fit the data in the file. It must then copy the entire
- * contents of the specified file into the memory location specified in
- * theText.
- *
- */
-
-typedef struct CW_GetText CW_GetText;
-struct CW_GetText // for handling class 'KAHL', event 'GTTX', keyDirectObject typeChar
-{
-    FSSpec theFile; // identifies the file
-    Handle theText; // the location where you return the text (must be resized properly)
-    long *unused;   // 0 (not used)
-    long *theDate;  // where to put the modification date/time
-};
-
-    pascal OSErr
-Handle_KAHL_GTTX_AE(
-	const AppleEvent    *theAEvent,
-	AppleEvent	    *theReply,
-	long		    refCon)
-{
-    OSErr	error = noErr;
-    buf_T	*buf;
-    int		foundFile = false;
-    DescType	typeCode;
-    CW_GetText	GetTextData;
-    Size	actualSize;
-    char_u	*line;
-    char_u	*fullbuffer = NULL;
-    long	linesize;
-    long	lineStart;
-    long	BufferSize;
-    long	lineno;
-
-    error = AEGetParamPtr(theAEvent, keyDirectObject, typeChar, &typeCode, (Ptr) &GetTextData, sizeof(GetTextData), &actualSize);
-
-    if (error)
-	return error;
-
-    FOR_ALL_BUFFERS(buf)
-	if (buf->b_ml.ml_mfp != NULL)
-	    if (GetTextData.theFile.parID == buf->b_FSSpec.parID)
-	    {
-		foundFile = true;
-		break;
-	    }
-
-    if (foundFile)
-    {
-	BufferSize = 0; // GetHandleSize(GetTextData.theText);
-	for (lineno = 0; lineno <= buf->b_ml.ml_line_count; lineno++)
-	{
-	    // Must use the right buffer
-	    line = ml_get_buf(buf, (linenr_T) lineno, FALSE);
-	    linesize = STRLEN(line) + 1;
-	    lineStart = BufferSize;
-	    BufferSize += linesize;
-	    // Resize handle to linesize+1 to include the linefeed
-	    SetHandleSize(GetTextData.theText, BufferSize);
-	    if (GetHandleSize(GetTextData.theText) != BufferSize)
-	    {
-		break; // Simple handling for now
-	    }
-	    else
-	    {
-		HLock(GetTextData.theText);
-		fullbuffer = (char_u *) *GetTextData.theText;
-		STRCPY((char_u *)(fullbuffer + lineStart), line);
-		fullbuffer[BufferSize-1] = '\r';
-		HUnlock(GetTextData.theText);
-	    }
-	}
-	if (fullbuffer != NULL)
-	{
-	    HLock(GetTextData.theText);
-	    fullbuffer[BufferSize-1] = 0;
-	    HUnlock(GetTextData.theText);
-	}
-	if (foundFile == false)
-	    *GetTextData.theDate = fnfErr;
-	else
-//	    *GetTextData.theDate = time(NULL) & (time_t) 0xFFFFFFF0;
-	    *GetTextData.theDate = buf->b_mtime;
-    }
-
-    error = HandleUnusedParms(theAEvent);
-
-    return error;
-}
-
-/*
- *
- */
-
-/*
- * Taken from MoreAppleEvents:ProcessHelpers
- */
-    pascal	OSErr
-FindProcessBySignature(
-	const OSType		targetType,
-	const OSType		targetCreator,
-	ProcessSerialNumberPtr	psnPtr)
-{
-    OSErr	anErr = noErr;
-    Boolean	lookingForProcess = true;
-
-    ProcessInfoRec  infoRec;
-
-    infoRec.processInfoLength = sizeof(ProcessInfoRec);
-    infoRec.processName = nil;
-    infoRec.processAppSpec = nil;
-
-    psnPtr->lowLongOfPSN = kNoProcess;
-    psnPtr->highLongOfPSN = kNoProcess;
-
-    while (lookingForProcess)
-    {
-	anErr = GetNextProcess(psnPtr);
-	if (anErr != noErr)
-	    lookingForProcess = false;
-	else
-	{
-	    anErr = GetProcessInformation(psnPtr, &infoRec);
-	    if ((anErr == noErr)
-		    && (infoRec.processType == targetType)
-		    && (infoRec.processSignature == targetCreator))
-		lookingForProcess = false;
-	}
-    }
-
-    return anErr;
-}//end FindProcessBySignature
-
-    void
-Send_KAHL_MOD_AE(buf_T *buf)
-{
-    OSErr	anErr = noErr;
-    AEDesc	targetAppDesc = { typeNull, nil };
-    ProcessSerialNumber	    psn = { kNoProcess, kNoProcess };
-    AppleEvent	theReply = { typeNull, nil };
-    AESendMode	sendMode;
-    AppleEvent  theEvent = {typeNull, nil };
-    AEIdleUPP   idleProcUPP = nil;
-    ModificationInfo ModData;
-
-
-    anErr = FindProcessBySignature('APPL', 'CWIE', &psn);
-    if (anErr == noErr)
-    {
-	anErr = AECreateDesc(typeProcessSerialNumber, &psn,
-			      sizeof(ProcessSerialNumber), &targetAppDesc);
-
-	if (anErr == noErr)
-	{
-	    anErr = AECreateAppleEvent( 'KAHL', 'MOD ', &targetAppDesc,
-					kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
-	}
-
-	AEDisposeDesc(&targetAppDesc);
-
-	// Add the parms
-	ModData.theFile = buf->b_FSSpec;
-	ModData.theDate = buf->b_mtime;
-
-	if (anErr == noErr)
-	    anErr = AEPutParamPtr(&theEvent, keyDirectObject, typeChar, &ModData, sizeof(ModData));
-
-	if (idleProcUPP == nil)
-	    sendMode = kAENoReply;
-	else
-	    sendMode = kAEWaitReply;
-
-	if (anErr == noErr)
-	    anErr = AESend(&theEvent, &theReply, sendMode, kAENormalPriority, kNoTimeOut, idleProcUPP, nil);
-	if (anErr == noErr  &&  sendMode == kAEWaitReply)
-	{
-//	    anErr =  AEHGetHandlerError(&theReply);
-	}
-	(void) AEDisposeDesc(&theReply);
-    }
-}
-#endif // FEAT_CW_EDITOR
-
-/*
- * ------------------------------------------------------------
- * Apple Event Handling procedure
- * ------------------------------------------------------------
- */
-#ifdef USE_AEVENT
-
-/*
- * Handle the Unused parms of an AppleEvent
- */
-
-    OSErr
-HandleUnusedParms(const AppleEvent *theAEvent)
-{
-    OSErr	error;
-    long	actualSize;
-    DescType	dummyType;
-    AEKeyword	missedKeyword;
-
-    // Get the "missed keyword" attribute from the AppleEvent.
-    error = AEGetAttributePtr(theAEvent, keyMissedKeywordAttr,
-			      typeKeyword, &dummyType,
-			      (Ptr)&missedKeyword, sizeof(missedKeyword),
-			      &actualSize);
-
-    // If the descriptor isn't found, then we got the required parameters.
-    if (error == errAEDescNotFound)
-    {
-	error = noErr;
-    }
-    else
-    {
-#if 0
-	// Why is this removed?
-	error = errAEEventNotHandled;
-#endif
-    }
-
-    return error;
-}
-
-
-/*
- * Handle the ODoc AppleEvent
- *
- * Deals with all files dragged to the application icon.
- *
- */
-
-typedef struct SelectionRange SelectionRange;
-struct SelectionRange // for handling kCoreClassEvent:kOpenDocuments:keyAEPosition typeChar
-{
-    short unused1; // 0 (not used)
-    short lineNum; // line to select (<0 to specify range)
-    long startRange; // start of selection range (if line < 0)
-    long endRange; // end of selection range (if line < 0)
-    long unused2; // 0 (not used)
-    long theDate; // modification date/time
-};
-
-static long drop_numFiles;
-static short drop_gotPosition;
-static SelectionRange drop_thePosition;
-
-    static void
-drop_callback(void *cookie UNUSED)
-{
-    // TODO: Handle the goto/select line more cleanly
-    if ((drop_numFiles == 1) & (drop_gotPosition))
-    {
-	if (drop_thePosition.lineNum >= 0)
-	{
-	    lnum = drop_thePosition.lineNum + 1;
-	//  oap->motion_type = MLINE;
-	// setpcmark();
-	    if (lnum < 1L)
-		lnum = 1L;
-	    else if (lnum > curbuf->b_ml.ml_line_count)
-		lnum = curbuf->b_ml.ml_line_count;
-	    curwin->w_cursor.lnum = lnum;
-	    curwin->w_cursor.col = 0;
-	//  beginline(BL_SOL | BL_FIX);
-	}
-	else
-	    goto_byte(drop_thePosition.startRange + 1);
-    }
-
-    // Update the screen display
-    update_screen(NOT_VALID);
-
-    // Select the text if possible
-    if (drop_gotPosition)
-    {
-	VIsual_active = TRUE;
-	VIsual_select = FALSE;
-	VIsual = curwin->w_cursor;
-	if (drop_thePosition.lineNum < 0)
-	{
-	    VIsual_mode = 'v';
-	    goto_byte(drop_thePosition.endRange);
-	}
-	else
-	{
-	    VIsual_mode = 'V';
-	    VIsual.col = 0;
-	}
-    }
-}
-
-/*
- * The IDE uses the optional keyAEPosition parameter to tell the ed-
- * itor the selection range. If lineNum is zero or greater, scroll the text
- * to the specified line. If lineNum is less than zero, use the values in
- * startRange and endRange to select the specified characters. Scroll
- * the text to display the selection. If lineNum, startRange, and
- * endRange are all negative, there is no selection range specified.
- */
-    pascal OSErr
-HandleODocAE(const AppleEvent *theAEvent, AppleEvent *theReply, long refCon)
-{
-    /*
-     * TODO: Clean up the code with convert the AppleEvent into
-     *       a ":args"
-     */
-    OSErr	error = noErr;
-//    OSErr	firstError = noErr;
-//    short	numErrors = 0;
-    AEDesc	theList;
-    DescType	typeCode;
-    long	numFiles;
- //   long	 fileCount;
-    char_u	**fnames;
-//    char_u	fname[256];
-    Size	actualSize;
-    SelectionRange thePosition;
-    short	gotPosition = false;
-    long	lnum;
-
-    // the direct object parameter is the list of aliases to files (one or more)
-    error = AEGetParamDesc(theAEvent, keyDirectObject, typeAEList, &theList);
-    if (error)
-	return error;
-
-
-    error = AEGetParamPtr(theAEvent, keyAEPosition, typeChar, &typeCode, (Ptr) &thePosition, sizeof(SelectionRange), &actualSize);
-    if (error == noErr)
-	gotPosition = true;
-    if (error == errAEDescNotFound)
-	error = noErr;
-    if (error)
-	return error;
-
-/*
-    error = AEGetParamDesc(theAEvent, keyAEPosition, typeChar, &thePosition);
-
-    if (^error) then
-    {
-	if (thePosition.lineNum >= 0)
-	{
-	  // Goto this line
-	}
-	else
-	{
-	  // Set the range char wise
-	}
-    }
- */
-
-    reset_VIsual();
-    fnames = new_fnames_from_AEDesc(&theList, &numFiles, &error);
-
-    if (error)
-    {
-      // TODO: empty fnames[] first
-      vim_free(fnames);
-      return (error);
-    }
-
-    if (starting > 0)
-    {
-	int i;
-	char_u *p;
-	int fnum = -1;
-
-	// these are the initial files dropped on the Vim icon
-	for (i = 0 ; i < numFiles; i++)
-	{
-	    if (ga_grow(&global_alist.al_ga, 1) == FAIL
-				      || (p = vim_strsave(fnames[i])) == NULL)
-		mch_exit(2);
-	    else
-		alist_add(&global_alist, p, 2);
-	    if (fnum == -1)
-		fnum = GARGLIST[GARGCOUNT - 1].ae_fnum;
-	}
-
-	// If the file name was already in the buffer list we need to switch
-	// to it.
-	if (curbuf->b_fnum != fnum)
-	{
-	    char_u cmd[30];
-
-	    vim_snprintf((char *)cmd, 30, "silent %dbuffer", fnum);
-	    do_cmdline_cmd(cmd);
-	}
-
-	// Change directory to the location of the first file.
-	if (GARGCOUNT > 0
-		      && vim_chdirfile(alist_name(&GARGLIST[0]), "drop") == OK)
-	    shorten_fnames(TRUE);
-
-	goto finished;
-    }
-
-    // Handle the drop, :edit to get to the file
-    drop_numFiles = numFiles;
-    drop_gotPosition = gotPosition;
-    drop_thePosition = thePosition;
-    handle_drop(numFiles, fnames, FALSE, drop_callback, NULL);
-
-    setcursor();
-    out_flush();
-
-    // Fake mouse event to wake from stall
-    PostEvent(mouseUp, 0);
-
-finished:
-    AEDisposeDesc(&theList); // dispose what we allocated
-
-    error = HandleUnusedParms(theAEvent);
-    return error;
-}
-
-/*
- *
- */
-    pascal OSErr
-Handle_aevt_oapp_AE(
-	const AppleEvent    *theAEvent,
-	AppleEvent	    *theReply,
-	long		    refCon)
-{
-    OSErr	error = noErr;
-
-    error = HandleUnusedParms(theAEvent);
-    return error;
-}
-
-/*
- *
- */
-    pascal OSErr
-Handle_aevt_quit_AE(
-	const AppleEvent    *theAEvent,
-	AppleEvent	    *theReply,
-	long		    refCon)
-{
-    OSErr	error = noErr;
-
-    error = HandleUnusedParms(theAEvent);
-    if (error)
-	return error;
-
-    // Need to fake a :confirm qa
-    do_cmdline_cmd((char_u *)"confirm qa");
-
-    return error;
-}
-
-/*
- *
- */
-    pascal OSErr
-Handle_aevt_pdoc_AE(
-	const AppleEvent    *theAEvent,
-	AppleEvent	    *theReply,
-	long		    refCon)
-{
-    OSErr	error = noErr;
-
-    error = HandleUnusedParms(theAEvent);
-
-    return error;
-}
-
-/*
- * Handling of unknown AppleEvent
- *
- * (Just get rid of all the parms)
- */
-    pascal OSErr
-Handle_unknown_AE(
-	const AppleEvent    *theAEvent,
-	AppleEvent	    *theReply,
-	long		    refCon)
-{
-    OSErr	error = noErr;
-
-    error = HandleUnusedParms(theAEvent);
-
-    return error;
-}
-
-
-/*
- * Install the various AppleEvent Handlers
- */
-    OSErr
-InstallAEHandlers(void)
-{
-    OSErr   error;
-
-    // install open application handler
-    error = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
-		    NewAEEventHandlerUPP(Handle_aevt_oapp_AE), 0, false);
-    if (error)
-	return error;
-
-    // install quit application handler
-    error = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
-		    NewAEEventHandlerUPP(Handle_aevt_quit_AE), 0, false);
-    if (error)
-	return error;
-
-    // install open document handler
-    error = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
-		    NewAEEventHandlerUPP(HandleODocAE), 0, false);
-    if (error)
-	return error;
-
-    // install print document handler
-    error = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
-		    NewAEEventHandlerUPP(Handle_aevt_pdoc_AE), 0, false);
-
-// Install Core Suite
-#if 0
-    error = AEInstallEventHandler(kAECoreSuite, kAEClone,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAEClose,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAECountElements,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAECreateElement,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAEDelete,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAEDoObjectsExist,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAEGetData,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), kAEGetData, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAEGetDataSize,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), kAEGetDataSize, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAEGetClassInfo,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAEGetEventInfo,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAEMove,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAESave,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-
-    error = AEInstallEventHandler(kAECoreSuite, kAESetData,
-		    NewAEEventHandlerUPP(Handle_unknown_AE), nil, false);
-#endif
-
-#ifdef FEAT_CW_EDITOR
-    /*
-     * Bind codewarrior support handlers
-     */
-    error = AEInstallEventHandler('KAHL', 'GTTX',
-		    NewAEEventHandlerUPP(Handle_KAHL_GTTX_AE), 0, false);
-    if (error)
-	return error;
-    error = AEInstallEventHandler('KAHL', 'SRCH',
-		    NewAEEventHandlerUPP(Handle_KAHL_SRCH_AE), 0, false);
-    if (error)
-	return error;
-    error = AEInstallEventHandler('KAHL', 'MOD ',
-		    NewAEEventHandlerUPP(Handle_KAHL_MOD_AE), 0, false);
-#endif
-
-    return error;
-
-}
-#endif // USE_AEVENT
-
-
-/*
- * Callback function, installed by InstallFontPanelHandler(), below,
- * to handle Font Panel events.
- */
-    static OSStatus
-FontPanelHandler(
-	EventHandlerCallRef inHandlerCallRef,
-	EventRef inEvent,
-	void *inUserData)
-{
-    if (GetEventKind(inEvent) == kEventFontPanelClosed)
-    {
-	gFontPanelInfo.isPanelVisible = false;
-	return noErr;
-    }
-
-    if (GetEventKind(inEvent) == kEventFontSelection)
-    {
-	OSStatus status;
-	FMFontFamily newFamily;
-	FMFontSize newSize;
-	FMFontStyle newStyle;
-
-	// Retrieve the font family ID number.
-	status = GetEventParameter(inEvent, kEventParamFMFontFamily,
-		/*inDesiredType=*/typeFMFontFamily, /*outActualType=*/NULL,
-		/*inBufferSize=*/sizeof(FMFontFamily), /*outActualSize=*/NULL,
-		&newFamily);
-	if (status == noErr)
-	    gFontPanelInfo.family = newFamily;
-
-	// Retrieve the font size.
-	status = GetEventParameter(inEvent, kEventParamFMFontSize,
-		typeFMFontSize, NULL, sizeof(FMFontSize), NULL, &newSize);
-	if (status == noErr)
-	    gFontPanelInfo.size = newSize;
-
-	// Retrieve the font style (bold, etc.).  Currently unused.
-	status = GetEventParameter(inEvent, kEventParamFMFontStyle,
-		typeFMFontStyle, NULL, sizeof(FMFontStyle), NULL, &newStyle);
-	if (status == noErr)
-	    gFontPanelInfo.style = newStyle;
-    }
-    return noErr;
-}
-
-
-    static void
-InstallFontPanelHandler(void)
-{
-    EventTypeSpec eventTypes[2];
-    EventHandlerUPP handlerUPP;
-    // EventHandlerRef handlerRef;
-
-    eventTypes[0].eventClass = kEventClassFont;
-    eventTypes[0].eventKind  = kEventFontSelection;
-    eventTypes[1].eventClass = kEventClassFont;
-    eventTypes[1].eventKind  = kEventFontPanelClosed;
-
-    handlerUPP = NewEventHandlerUPP(FontPanelHandler);
-
-    InstallApplicationEventHandler(handlerUPP, /*numTypes=*/2, eventTypes,
-	    /*userData=*/NULL, /*handlerRef=*/NULL);
-}
-
-
-/*
- * Fill the buffer pointed to by outName with the name and size
- * of the font currently selected in the Font Panel.
- */
-#define FONT_STYLE_BUFFER_SIZE 32
-    static void
-GetFontPanelSelection(char_u *outName)
-{
-    Str255	    buf;
-    ByteCount	    fontNameLen = 0;
-    ATSUFontID	    fid;
-    char_u	    styleString[FONT_STYLE_BUFFER_SIZE];
-
-    if (!outName)
-	return;
-
-    if (FMGetFontFamilyName(gFontPanelInfo.family, buf) == noErr)
-    {
-	// Canonicalize localized font names
-	if (FMGetFontFromFontFamilyInstance(gFontPanelInfo.family,
-		    gFontPanelInfo.style, &fid, NULL) != noErr)
-	    return;
-
-	// Request font name with Mac encoding (otherwise we could
-	// get an unwanted utf-16 name)
-	if (ATSUFindFontName(fid, kFontFullName, kFontMacintoshPlatform,
-		    kFontNoScriptCode, kFontNoLanguageCode,
-		    255, (char *)outName, &fontNameLen, NULL) != noErr)
-	    return;
-
-	// Only encode font size, because style (bold, italic, etc) is
-	// already part of the font full name
-	vim_snprintf((char *)styleString, FONT_STYLE_BUFFER_SIZE, ":h%d",
-		gFontPanelInfo.size/*,
-		((gFontPanelInfo.style & bold)!=0 ? ":b" : ""),
-		((gFontPanelInfo.style & italic)!=0 ? ":i" : ""),
-		((gFontPanelInfo.style & underline)!=0 ? ":u" : "")*/);
-
-	if ((fontNameLen + STRLEN(styleString)) < 255)
-	    STRCPY(outName + fontNameLen, styleString);
-    }
-    else
-    {
-	*outName = NUL;
-    }
-}
-
-
-/*
- * ------------------------------------------------------------
- * Unfiled yet
- * ------------------------------------------------------------
- */
-
-/*
- *  gui_mac_get_menu_item_index
- *
- *  Returns the index inside the menu where
- */
-    short // Should we return MenuItemIndex?
-gui_mac_get_menu_item_index(vimmenu_T *pMenu)
-{
-    short	index;
-    short	itemIndex = -1;
-    vimmenu_T	*pBrother;
-
-    // Only menu without parent are the:
-    // -menu in the menubar
-    // -popup menu
-    // -toolbar (guess)
-    //
-    // Which are not items anyway.
-    if (pMenu->parent)
-    {
-	// Start from the Oldest Brother
-	pBrother = pMenu->parent->children;
-	index = 1;
-	while ((pBrother) && (itemIndex == -1))
-	{
-	    if (pBrother == pMenu)
-		itemIndex = index;
-	    index++;
-	    pBrother = pBrother->next;
-	}
-    }
-    return itemIndex;
-}
-
-    static vimmenu_T *
-gui_mac_get_vim_menu(short menuID, short itemIndex, vimmenu_T *pMenu)
-{
-    short	index;
-    vimmenu_T	*pChildMenu;
-    vimmenu_T	*pElder = pMenu->parent;
-
-
-    // Only menu without parent are the:
-    // -menu in the menubar
-    // -popup menu
-    // -toolbar (guess)
-    //
-    // Which are not items anyway.
-
-    if ((pElder) && (pElder->submenu_id == menuID))
-    {
-	for (index = 1; (index != itemIndex) && (pMenu != NULL); index++)
-	    pMenu = pMenu->next;
-    }
-    else
-    {
-	for (; pMenu != NULL; pMenu = pMenu->next)
-	{
-	    if (pMenu->children != NULL)
-	    {
-		pChildMenu = gui_mac_get_vim_menu
-			   (menuID, itemIndex, pMenu->children);
-		if (pChildMenu)
-		{
-		    pMenu = pChildMenu;
-		    break;
-		}
-	    }
-	}
-    }
-    return pMenu;
-}
-
-/*
- * ------------------------------------------------------------
- * MacOS Feedback procedures
- * ------------------------------------------------------------
- */
-    pascal
-    void
-gui_mac_drag_thumb(ControlHandle theControl, short partCode)
-{
-    scrollbar_T		*sb;
-    int			value, dragging;
-    ControlHandle	theControlToUse;
-    int			dont_scroll_save = dont_scroll;
-
-    theControlToUse = dragged_sb;
-
-    sb = gui_find_scrollbar((long) GetControlReference(theControlToUse));
-
-    if (sb == NULL)
-	return;
-
-    // Need to find value by diff between Old Poss New Pos
-    value = GetControl32BitValue(theControlToUse);
-    dragging = (partCode != 0);
-
-    // When "allow_scrollbar" is FALSE still need to remember the new
-    // position, but don't actually scroll by setting "dont_scroll".
-    dont_scroll = !allow_scrollbar;
-    gui_drag_scrollbar(sb, value, dragging);
-    dont_scroll = dont_scroll_save;
-}
-
-    pascal
-    void
-gui_mac_scroll_action(ControlHandle theControl, short partCode)
-{
-    // TODO: have live support
-    scrollbar_T *sb, *sb_info;
-    long	data;
-    long	value;
-    int		page;
-    int		dragging = FALSE;
-    int		dont_scroll_save = dont_scroll;
-
-    sb = gui_find_scrollbar((long)GetControlReference(theControl));
-
-    if (sb == NULL)
-	return;
-
-    if (sb->wp != NULL)		// Left or right scrollbar
-    {
-	/*
-	 * Careful: need to get scrollbar info out of first (left) scrollbar
-	 * for window, but keep real scrollbar too because we must pass it to
-	 * gui_drag_scrollbar().
-	 */
-	sb_info = &sb->wp->w_scrollbars[0];
-
-	if (sb_info->size > 5)
-	    page = sb_info->size - 2;	// use two lines of context
-	else
-	    page = sb_info->size;
-    }
-    else			// Bottom scrollbar
-    {
-	sb_info = sb;
-	page = curwin->w_width - 5;
-    }
-
-    switch (partCode)
-    {
-	case  kControlUpButtonPart:   data = -1;    break;
-	case  kControlDownButtonPart: data = 1;     break;
-	case  kControlPageDownPart:   data = page;  break;
-	case  kControlPageUpPart:     data = -page; break;
-		    default: data = 0; break;
-    }
-
-    value = sb_info->value + data;
-//  if (value > sb_info->max)
-//      value = sb_info->max;
-//  else if (value < 0)
-//	value = 0;
-
-    // When "allow_scrollbar" is FALSE still need to remember the new
-    // position, but don't actually scroll by setting "dont_scroll".
-    dont_scroll = !allow_scrollbar;
-    gui_drag_scrollbar(sb, value, dragging);
-    dont_scroll = dont_scroll_save;
-
-    out_flush();
-    gui_mch_set_scrollbar_thumb(sb, value, sb_info->size, sb_info->max);
-
-#if 0
-    if (sb_info->wp != NULL)
-    {
-	win_T	*wp;
-	int	sb_num;
-
-	sb_num = 0;
-	for (wp = firstwin; wp != sb->wp && wp != NULL; wp = W_NEXT(wp))
-	sb_num++;
-
-	if (wp != NULL)
-	{
-	    current_scrollbar = sb_num;
-	    scrollbar_value = value;
-	    gui_do_scroll();
-	    gui_mch_set_scrollbar_thumb(sb, value, sb_info->size, sb_info->max);
-	}
-    }
-#endif
-}
-
-/*
- * ------------------------------------------------------------
- * MacOS Click Handling procedures
- * ------------------------------------------------------------
- */
-
-
-/*
- * Handle a click inside the window, it may happens in the
- * scrollbar or the contents.
- *
- * TODO: Add support for potential TOOLBAR
- */
-    void
-gui_mac_doInContentClick(EventRecord *theEvent, WindowPtr whichWindow)
-{
-    Point		thePoint;
-    int_u		vimModifiers;
-    short		thePortion;
-    ControlHandle	theControl;
-    int			vimMouseButton;
-    short		dblClick;
-
-    thePoint = theEvent->where;
-    GlobalToLocal(&thePoint);
-    SelectWindow(whichWindow);
-
-    thePortion = FindControl(thePoint, whichWindow, &theControl);
-
-    if (theControl != NUL)
-    {
-	// We hit a scrollbar
-
-	if (thePortion != kControlIndicatorPart)
-	{
-	    dragged_sb = theControl;
-	    TrackControl(theControl, thePoint, gScrollAction);
-	    dragged_sb = NULL;
-	}
-	else
-	{
-	    dragged_sb = theControl;
-#if 1
-	    TrackControl(theControl, thePoint, gScrollDrag);
-#else
-	    TrackControl(theControl, thePoint, NULL);
-#endif
-	    // pass 0 as the part to tell gui_mac_drag_thumb, that the mouse
-	    // button has been released
-	    gui_mac_drag_thumb(theControl, 0); // Should it be thePortion ? (Dany)
-	    dragged_sb = NULL;
-	}
-    }
-    else
-    {
-	// We are inside the contents
-
-	// Convert the CTRL, OPTION, SHIFT and CMD key
-	vimModifiers = EventModifiers2VimMouseModifiers(theEvent->modifiers);
-
-	// Defaults to MOUSE_LEFT as there's only one mouse button
-	vimMouseButton = MOUSE_LEFT;
-
-	// Convert the CTRL_MOUSE_LEFT to MOUSE_RIGHT
-	// TODO: NEEDED?
-	clickIsPopup = FALSE;
-
-	if (mouse_model_popup() && IsShowContextualMenuClick(theEvent))
-	{
-	    vimMouseButton = MOUSE_RIGHT;
-	    vimModifiers &= ~MOUSE_CTRL;
-	    clickIsPopup = TRUE;
-	}
-
-	// Is it a double click ?
-	dblClick = ((theEvent->when - lastMouseTick) < GetDblTime());
-
-	// Send the mouse click to Vim
-	gui_send_mouse_event(vimMouseButton, thePoint.h,
-					  thePoint.v, dblClick, vimModifiers);
-
-	// Create the rectangle around the cursor to detect
-	// the mouse dragging
-#if 0
-	// TODO: Do we need to this even for the contextual menu?
-	// It may be require for popup_setpos, but for popup?
-	if (vimMouseButton == MOUSE_LEFT)
-#endif
-	{
-	    SetRect(&dragRect, FILL_X(X_2_COL(thePoint.h)),
-				FILL_Y(Y_2_ROW(thePoint.v)),
-				FILL_X(X_2_COL(thePoint.h)+1),
-				FILL_Y(Y_2_ROW(thePoint.v)+1));
-
-	    dragRectEnbl = TRUE;
-	    dragRectControl = kCreateRect;
-	}
-    }
-}
-
-/*
- * Handle the click in the titlebar (to move the window)
- */
-    void
-gui_mac_doInDragClick(Point where, WindowPtr whichWindow)
-{
-    Rect	movingLimits;
-    Rect	*movingLimitsPtr = &movingLimits;
-
-    // TODO: may try to prevent move outside screen?
-    movingLimitsPtr = GetRegionBounds(GetGrayRgn(), &movingLimits);
-    DragWindow(whichWindow, where, movingLimitsPtr);
-}
-
-/*
- * Handle the click in the grow box
- */
-    void
-gui_mac_doInGrowClick(Point where, WindowPtr whichWindow)
-{
-
-    long	    newSize;
-    unsigned short  newWidth;
-    unsigned short  newHeight;
-    Rect	    resizeLimits;
-    Rect	    *resizeLimitsPtr = &resizeLimits;
-    Rect	    NewContentRect;
-
-    resizeLimitsPtr = GetRegionBounds(GetGrayRgn(), &resizeLimits);
-
-    // Set the minimum size
-    // TODO: Should this come from Vim?
-    resizeLimits.top = 100;
-    resizeLimits.left = 100;
-
-    newSize = ResizeWindow(whichWindow, where, &resizeLimits, &NewContentRect);
-    newWidth  = NewContentRect.right - NewContentRect.left;
-    newHeight = NewContentRect.bottom - NewContentRect.top;
-    gui_resize_shell(newWidth, newHeight);
-    gui_mch_set_bg_color(gui.back_pixel);
-    gui_set_shellsize(TRUE, FALSE, RESIZE_BOTH);
-}
-
-/*
- * Handle the click in the zoom box
- */
-    static void
-gui_mac_doInZoomClick(EventRecord *theEvent, WindowPtr whichWindow)
-{
-    Rect	r;
-    Point	p;
-    short	thePart;
-
-    // ideal width is current
-    p.h = Columns * gui.char_width + 2 * gui.border_offset;
-    if (gui.which_scrollbars[SBAR_LEFT])
-	p.h += gui.scrollbar_width;
-    if (gui.which_scrollbars[SBAR_RIGHT])
-	p.h += gui.scrollbar_width;
-    // ideal height is as high as we can get
-    p.v = 15 * 1024;
-
-    thePart = IsWindowInStandardState(whichWindow, &p, &r)
-						       ? inZoomIn : inZoomOut;
-
-    if (!TrackBox(whichWindow, theEvent->where, thePart))
-	return;
-
-    // use returned width
-    p.h = r.right - r.left;
-    // adjust returned height
-    p.v = r.bottom - r.top - 2 * gui.border_offset;
-    if (gui.which_scrollbars[SBAR_BOTTOM])
-	p.v -= gui.scrollbar_height;
-    p.v -= p.v % gui.char_height;
-    p.v += 2 * gui.border_width;
-    if (gui.which_scrollbars[SBAR_BOTTOM])
-	p.v += gui.scrollbar_height;
-
-    ZoomWindowIdeal(whichWindow, thePart, &p);
-
-    GetWindowBounds(whichWindow, kWindowContentRgn, &r);
-    gui_resize_shell(r.right - r.left, r.bottom - r.top);
-    gui_mch_set_bg_color(gui.back_pixel);
-    gui_set_shellsize(TRUE, FALSE, RESIZE_BOTH);
-}
-
-/*
- * ------------------------------------------------------------
- * MacOS Event Handling procedure
- * ------------------------------------------------------------
- */
-
-/*
- * Handle the Update Event
- */
-
-    void
-gui_mac_doUpdateEvent(EventRecord *event)
-{
-    WindowPtr	whichWindow;
-    GrafPtr	savePort;
-    RgnHandle	updateRgn;
-    Rect	updateRect;
-    Rect	*updateRectPtr;
-    Rect	rc;
-    Rect	growRect;
-    RgnHandle	saveRgn;
-
-
-    updateRgn = NewRgn();
-    if (updateRgn == NULL)
-	return;
-
-    // This could be done by the caller as we
-    // don't require anything else out of the event
-    whichWindow = (WindowPtr) event->message;
-
-    // Save Current Port
-    GetPort(&savePort);
-
-    // Select the Window's Port
-    SetPortWindowPort(whichWindow);
-
-    // Let's update the window
-      BeginUpdate(whichWindow);
-	// Redraw the biggest rectangle covering the area
-	// to be updated.
-	GetPortVisibleRegion(GetWindowPort(whichWindow), updateRgn);
-# if 0
-	// Would be more appropriate to use the following but doesn't
-	// seem to work under MacOS X (Dany)
-	GetWindowRegion(whichWindow, kWindowUpdateRgn, updateRgn);
-# endif
-
-	// Use the HLock useless in Carbon? Is it harmful?
-	HLock((Handle) updateRgn);
-
-	  updateRectPtr = GetRegionBounds(updateRgn, &updateRect);
-# if 0
-	  // Code from original Carbon Port (using GetWindowRegion.
-	  // I believe the UpdateRgn is already in local (Dany)
-	  GlobalToLocal(&topLeft(updateRect)); // preCarbon?
-	  GlobalToLocal(&botRight(updateRect));
-# endif
-	  // Update the content (i.e. the text)
-	  gui_redraw(updateRectPtr->left, updateRectPtr->top,
-		      updateRectPtr->right - updateRectPtr->left,
-		      updateRectPtr->bottom   - updateRectPtr->top);
-	  // Clear the border areas if needed
-	  gui_mch_set_bg_color(gui.back_pixel);
-	  if (updateRectPtr->left < FILL_X(0))
-	  {
-	    SetRect(&rc, 0, 0, FILL_X(0), FILL_Y(Rows));
-	    EraseRect(&rc);
-	  }
-	  if (updateRectPtr->top < FILL_Y(0))
-	  {
-	    SetRect(&rc, 0, 0, FILL_X(Columns), FILL_Y(0));
-	    EraseRect(&rc);
-	  }
-	  if (updateRectPtr->right > FILL_X(Columns))
-	  {
-	    SetRect(&rc, FILL_X(Columns), 0,
-			   FILL_X(Columns) + gui.border_offset, FILL_Y(Rows));
-	    EraseRect(&rc);
-	  }
-	  if (updateRectPtr->bottom > FILL_Y(Rows))
-	  {
-	    SetRect(&rc, 0, FILL_Y(Rows), FILL_X(Columns) + gui.border_offset,
-					    FILL_Y(Rows) + gui.border_offset);
-	    EraseRect(&rc);
-	  }
-	HUnlock((Handle) updateRgn);
-	DisposeRgn(updateRgn);
-
-	// Update scrollbars
-	DrawControls(whichWindow);
-
-	// Update the GrowBox
-	// Taken from FAQ 33-27
-	saveRgn = NewRgn();
-	GetWindowBounds(whichWindow, kWindowGrowRgn, &growRect);
-	GetClip(saveRgn);
-	ClipRect(&growRect);
-	DrawGrowIcon(whichWindow);
-	SetClip(saveRgn);
-	DisposeRgn(saveRgn);
-      EndUpdate(whichWindow);
-
-    // Restore original Port
-    SetPort(savePort);
-}
-
-/*
- * Handle the activate/deactivate event
- * (apply to a window)
- */
-    void
-gui_mac_doActivateEvent(EventRecord *event)
-{
-    WindowPtr	whichWindow;
-
-    whichWindow = (WindowPtr) event->message;
-    // Dim scrollbars
-    if (whichWindow == gui.VimWindow)
-    {
-	ControlRef rootControl;
-	GetRootControl(gui.VimWindow, &rootControl);
-	if ((event->modifiers) & activeFlag)
-	    ActivateControl(rootControl);
-	else
-	    DeactivateControl(rootControl);
-    }
-
-    // Activate
-    gui_focus_change((event->modifiers) & activeFlag);
-}
-
-
-/*
- * Handle the suspend/resume event
- * (apply to the application)
- */
-    void
-gui_mac_doSuspendEvent(EventRecord *event)
-{
-    // The frontmost application just changed
-
-    // NOTE: the suspend may happen before the deactivate
-    //       seen on MacOS X
-
-    // May not need to change focus as the window will
-    // get an activate/deactivate event
-    if (event->message & 1)
-	// Resume
-	gui_focus_change(TRUE);
-    else
-	// Suspend
-	gui_focus_change(FALSE);
-}
-
-/*
- * Handle the key
- */
-#ifdef USE_CARBONKEYHANDLER
-    static pascal OSStatus
-gui_mac_handle_window_activate(
-	EventHandlerCallRef nextHandler,
-	EventRef	    theEvent,
-	void		    *data)
-{
-    UInt32 eventClass = GetEventClass(theEvent);
-    UInt32 eventKind  = GetEventKind(theEvent);
-
-    if (eventClass == kEventClassWindow)
-    {
-	switch (eventKind)
-	{
-	    case kEventWindowActivated:
-		im_on_window_switch(TRUE);
-		return noErr;
-
-	    case kEventWindowDeactivated:
-		im_on_window_switch(FALSE);
-		return noErr;
-	}
-    }
-
-    return eventNotHandledErr;
-}
-
-    static pascal OSStatus
-gui_mac_handle_text_input(
-	EventHandlerCallRef nextHandler,
-	EventRef	    theEvent,
-	void		    *data)
-{
-    UInt32 eventClass = GetEventClass(theEvent);
-    UInt32 eventKind  = GetEventKind(theEvent);
-
-    if (eventClass != kEventClassTextInput)
-	return eventNotHandledErr;
-
-    if ((kEventTextInputUpdateActiveInputArea != eventKind) &&
-	(kEventTextInputUnicodeForKeyEvent    != eventKind) &&
-	(kEventTextInputOffsetToPos	      != eventKind) &&
-	(kEventTextInputPosToOffset	      != eventKind) &&
-	(kEventTextInputGetSelectedText       != eventKind))
-	      return eventNotHandledErr;
-
-    switch (eventKind)
-    {
-    case kEventTextInputUpdateActiveInputArea:
-	return gui_mac_update_input_area(nextHandler, theEvent);
-    case kEventTextInputUnicodeForKeyEvent:
-	return gui_mac_unicode_key_event(nextHandler, theEvent);
-
-    case kEventTextInputOffsetToPos:
-    case kEventTextInputPosToOffset:
-    case kEventTextInputGetSelectedText:
-	break;
-    }
-
-    return eventNotHandledErr;
-}
-
-    static pascal
-OSStatus gui_mac_update_input_area(
-	EventHandlerCallRef nextHandler,
-	EventRef	    theEvent)
-{
-    return eventNotHandledErr;
-}
-
-static int dialog_busy = FALSE;	    // TRUE when gui_mch_dialog() wants the
-				    // keys
-
-# define INLINE_KEY_BUFFER_SIZE 80
-    static pascal OSStatus
-gui_mac_unicode_key_event(
-	EventHandlerCallRef nextHandler,
-	EventRef	    theEvent)
-{
-    // Multibyte-friendly key event handler
-    OSStatus	err = -1;
-    UInt32	actualSize;
-    UniChar	*text;
-    char_u	result[INLINE_KEY_BUFFER_SIZE];
-    short	len = 0;
-    UInt32	key_sym;
-    char	charcode;
-    int		key_char;
-    UInt32	modifiers, vimModifiers;
-    size_t	encLen;
-    char_u	*to = NULL;
-    Boolean	isSpecial = FALSE;
-    int		i;
-    EventRef	keyEvent;
-
-    // Mask the mouse (as per user setting)
-    if (p_mh)
-	ObscureCursor();
-
-    // Don't use the keys when the dialog wants them.
-    if (dialog_busy)
-	return eventNotHandledErr;
-
-    if (noErr != GetEventParameter(theEvent, kEventParamTextInputSendText,
-		typeUnicodeText, NULL, 0, &actualSize, NULL))
-	return eventNotHandledErr;
-
-    text = alloc(actualSize);
-    if (!text)
-	return eventNotHandledErr;
-
-    err = GetEventParameter(theEvent, kEventParamTextInputSendText,
-	    typeUnicodeText, NULL, actualSize, NULL, text);
-    require_noerr(err, done);
-
-    err = GetEventParameter(theEvent, kEventParamTextInputSendKeyboardEvent,
-	    typeEventRef, NULL, sizeof(EventRef), NULL, &keyEvent);
-    require_noerr(err, done);
-
-    err = GetEventParameter(keyEvent, kEventParamKeyModifiers,
-	    typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
-    require_noerr(err, done);
-
-    err = GetEventParameter(keyEvent, kEventParamKeyCode,
-	    typeUInt32, NULL, sizeof(UInt32), NULL, &key_sym);
-    require_noerr(err, done);
-
-    err = GetEventParameter(keyEvent, kEventParamKeyMacCharCodes,
-	    typeChar, NULL, sizeof(char), NULL, &charcode);
-    require_noerr(err, done);
-
-#ifndef USE_CMD_KEY
-    if (modifiers & cmdKey)
-	goto done;  // Let system handle Cmd+...
-#endif
-
-    key_char = charcode;
-    vimModifiers = EventModifiers2VimModifiers(modifiers);
-
-    // Find the special key (eg., for cursor keys)
-    if (actualSize <= sizeof(UniChar) &&
-	    ((text[0] < 0x20) || (text[0] == 0x7f)))
-    {
-	for (i = 0; special_keys[i].key_sym != (KeySym)0; ++i)
-	    if (special_keys[i].key_sym == key_sym)
-	    {
-		key_char = TO_SPECIAL(special_keys[i].vim_code0,
-			special_keys[i].vim_code1);
-		key_char = simplify_key(key_char,
-			(int *)&vimModifiers);
-		isSpecial = TRUE;
-		break;
-	    }
-    }
-
-    // Intercept CMD-. and CTRL-c
-    if (((modifiers & controlKey) && key_char == 'c') ||
-	    ((modifiers & cmdKey) && key_char == '.'))
-	got_int = TRUE;
-
-    if (!isSpecial)
-    {
-	// remove SHIFT for keys that are already shifted, e.g.,
-	// '(' and '*'
-	if (key_char < 0x100 && !isalpha(key_char) && isprint(key_char))
-	    vimModifiers &= ~MOD_MASK_SHIFT;
-
-	// remove CTRL from keys that already have it
-	if (key_char < 0x20)
-	    vimModifiers &= ~MOD_MASK_CTRL;
-
-	// don't process unicode characters here
-	if (!IS_SPECIAL(key_char))
-	{
-	    // Following code to simplify and consolidate vimModifiers
-	    // taken liberally from gui_w48.c
-	    key_char = simplify_key(key_char, (int *)&vimModifiers);
-
-	    // Unify modifiers somewhat.  No longer use ALT to set the 8th bit.
-	    key_char = extract_modifiers(key_char, (int *)&vimModifiers,
-								  FALSE, NULL);
-	    if (key_char == CSI)
-		key_char = K_CSI;
-
-	    if (IS_SPECIAL(key_char))
-		isSpecial = TRUE;
-	}
-    }
-
-    if (vimModifiers)
-    {
-	result[len++] = CSI;
-	result[len++] = KS_MODIFIER;
-	result[len++] = vimModifiers;
-    }
-
-    if (isSpecial && IS_SPECIAL(key_char))
-    {
-	result[len++] = CSI;
-	result[len++] = K_SECOND(key_char);
-	result[len++] = K_THIRD(key_char);
-    }
-    else
-    {
-	encLen = actualSize;
-	to = mac_utf16_to_enc(text, actualSize, &encLen);
-	if (to)
-	{
-	    // This is basically add_to_input_buf_csi()
-	    for (i = 0; i < encLen && len < (INLINE_KEY_BUFFER_SIZE-1); ++i)
-	    {
-		result[len++] = to[i];
-		if (to[i] == CSI)
-		{
-		    result[len++] = KS_EXTRA;
-		    result[len++] = (int)KE_CSI;
-		}
-	    }
-	    vim_free(to);
-	}
-    }
-
-    add_to_input_buf(result, len);
-    err = noErr;
-
-done:
-    vim_free(text);
-    if (err == noErr)
-    {
-	// Fake event to wake up WNE (required to get
-	// key repeat working
-	PostEvent(keyUp, 0);
-	return noErr;
-    }
-
-    return eventNotHandledErr;
-}
-#else
-    void
-gui_mac_doKeyEvent(EventRecord *theEvent)
-{
-    // TODO: add support for COMMAND KEY
-    long		menu;
-    unsigned char	string[20];
-    short		num, i;
-    short		len = 0;
-    KeySym		key_sym;
-    int			key_char;
-    int			modifiers;
-    int			simplify = FALSE;
-
-    // Mask the mouse (as per user setting)
-    if (p_mh)
-	ObscureCursor();
-
-    // Get the key code and its ASCII representation
-    key_sym = ((theEvent->message & keyCodeMask) >> 8);
-    key_char = theEvent->message & charCodeMask;
-    num = 1;
-
-    // Intercept CTRL-C
-    if (theEvent->modifiers & controlKey)
-    {
-	if (key_char == Ctrl_C && ctrl_c_interrupts)
-	    got_int = TRUE;
-	else if ((theEvent->modifiers & ~(controlKey|shiftKey)) == 0
-		&& (key_char == '2' || key_char == '6'))
-	{
-	    // CTRL-^ and CTRL-@ don't work in the normal way.
-	    if (key_char == '2')
-		key_char = Ctrl_AT;
-	    else
-		key_char = Ctrl_HAT;
-	    theEvent->modifiers = 0;
-	}
-    }
-
-    // Intercept CMD-.
-    if (theEvent->modifiers & cmdKey)
-	if (key_char == '.')
-	    got_int = TRUE;
-
-    // Handle command key as per menu
-    // TODO: should override be allowed? Require YAO or could use 'winaltkey'
-    if (theEvent->modifiers & cmdKey)
-	// Only accept CMD alone or with CAPLOCKS and the mouse button.
-	// Why the mouse button?
-	if ((theEvent->modifiers & (~(cmdKey | btnState | alphaLock))) == 0)
-	{
-	    menu = MenuKey(key_char);
-	    if (HiWord(menu))
-	    {
-		gui_mac_handle_menu(menu);
-		return;
-	    }
-	}
-
-    // Convert the modifiers
-    modifiers = EventModifiers2VimModifiers(theEvent->modifiers);
-
-
-    // Handle special keys.
-#if 0
-    // Why has this been removed?
-    if	(!(theEvent->modifiers & (cmdKey | controlKey | rightControlKey)))
-#endif
-    {
-	// Find the special key (for non-printable keyt_char)
-	if  ((key_char < 0x20) || (key_char == 0x7f))
-	    for (i = 0; special_keys[i].key_sym != (KeySym)0; i++)
-		if (special_keys[i].key_sym == key_sym)
-		{
-# if 0
-		    // We currently don't have not so special key
-		    if (special_keys[i].vim_code1 == NUL)
-			key_char = special_keys[i].vim_code0;
-		    else
-# endif
-			key_char = TO_SPECIAL(special_keys[i].vim_code0,
-						special_keys[i].vim_code1);
-		    simplify = TRUE;
-		    break;
-		}
-    }
-
-    // For some keys the modifier is included in the char itself.
-    if (simplify || key_char == TAB || key_char == ' ')
-	key_char = simplify_key(key_char, &modifiers);
-
-    // Add the modifier to the input bu if needed
-    // Do not want SHIFT-A or CTRL-A with modifier
-    if (!IS_SPECIAL(key_char)
-	    && key_sym != vk_Space
-	    && key_sym != vk_Tab
-	    && key_sym != vk_Return
-	    && key_sym != vk_Enter
-	    && key_sym != vk_Esc)
-    {
-#if 1
-    // Clear modifiers when only one modifier is set
-	if ((modifiers == MOD_MASK_SHIFT)
-		|| (modifiers == MOD_MASK_CTRL)
-		|| (modifiers == MOD_MASK_ALT))
-	    modifiers = 0;
-#else
-	if (modifiers & MOD_MASK_CTRL)
-	    modifiers = modifiers & ~MOD_MASK_CTRL;
-	if (modifiers & MOD_MASK_ALT)
-	    modifiers = modifiers & ~MOD_MASK_ALT;
-	if (modifiers & MOD_MASK_SHIFT)
-	    modifiers = modifiers & ~MOD_MASK_SHIFT;
-#endif
-    }
-	if (modifiers)
-	{
-	    string[len++] = CSI;
-	    string[len++] = KS_MODIFIER;
-	    string[len++] = modifiers;
-	}
-
-	if (IS_SPECIAL(key_char))
-	{
-	    string[len++] = CSI;
-	    string[len++] = K_SECOND(key_char);
-	    string[len++] = K_THIRD(key_char);
-	}
-	else
-	{
-	    // Convert characters when needed (e.g., from MacRoman to latin1).
-	    // This doesn't work for the NUL byte.
-	    if (input_conv.vc_type != CONV_NONE && key_char > 0)
-	    {
-		char_u	from[2], *to;
-		int	l;
-
-		from[0] = key_char;
-		from[1] = NUL;
-		l = 1;
-		to = string_convert(&input_conv, from, &l);
-		if (to != NULL)
-		{
-		    for (i = 0; i < l && len < 19; i++)
-		    {
-			if (to[i] == CSI)
-			{
-			    string[len++] = KS_EXTRA;
-			    string[len++] = KE_CSI;
-			}
-			else
-			    string[len++] = to[i];
-		    }
-		    vim_free(to);
-		}
-		else
-		    string[len++] = key_char;
-	    }
-	    else
-		string[len++] = key_char;
-	}
-
-	if (len == 1 && string[0] == CSI)
-	{
-	    // Turn CSI into K_CSI.
-	    string[ len++ ] = KS_EXTRA;
-	    string[ len++ ] = KE_CSI;
-	}
-
-    add_to_input_buf(string, len);
-}
-#endif
-
-/*
- * Handle MouseClick
- */
-    void
-gui_mac_doMouseDownEvent(EventRecord *theEvent)
-{
-    short		thePart;
-    WindowPtr		whichWindow;
-
-    thePart = FindWindow(theEvent->where, &whichWindow);
-
-#ifdef FEAT_GUI_TABLINE
-    // prevent that the vim window size changes if it's activated by a
-    // click into the tab pane
-    if (whichWindow == drawer)
-	return;
-#endif
-
-    switch (thePart)
-    {
-	case (inDesk):
-	    // TODO: what to do?
-	    break;
-
-	case (inMenuBar):
-	    gui_mac_handle_menu(MenuSelect(theEvent->where));
-	    break;
-
-	case (inContent):
-	    gui_mac_doInContentClick(theEvent, whichWindow);
-	    break;
-
-	case (inDrag):
-	    gui_mac_doInDragClick(theEvent->where, whichWindow);
-	    break;
-
-	case (inGrow):
-	    gui_mac_doInGrowClick(theEvent->where, whichWindow);
-	    break;
-
-	case (inGoAway):
-	    if (TrackGoAway(whichWindow, theEvent->where))
-		gui_shell_closed();
-	    break;
-
-	case (inZoomIn):
-	case (inZoomOut):
-	    gui_mac_doInZoomClick(theEvent, whichWindow);
-	    break;
-    }
-}
-
-/*
- * Handle MouseMoved
- * [this event is a moving in and out of a region]
- */
-    void
-gui_mac_doMouseMovedEvent(EventRecord *event)
-{
-    Point   thePoint;
-    int_u   vimModifiers;
-
-    thePoint = event->where;
-    GlobalToLocal(&thePoint);
-    vimModifiers = EventModifiers2VimMouseModifiers(event->modifiers);
-
-    if (!Button())
-	gui_mouse_moved(thePoint.h, thePoint.v);
-    else
-	if (!clickIsPopup)
-	    gui_send_mouse_event(MOUSE_DRAG, thePoint.h,
-					     thePoint.v, FALSE, vimModifiers);
-
-    // Reset the region from which we move in and out
-    SetRect(&dragRect, FILL_X(X_2_COL(thePoint.h)),
-			FILL_Y(Y_2_ROW(thePoint.v)),
-			FILL_X(X_2_COL(thePoint.h)+1),
-			FILL_Y(Y_2_ROW(thePoint.v)+1));
-
-    if (dragRectEnbl)
-	dragRectControl = kCreateRect;
-
-}
-
-/*
- * Handle the mouse release
- */
-    void
-gui_mac_doMouseUpEvent(EventRecord *theEvent)
-{
-    Point   thePoint;
-    int_u   vimModifiers;
-
-    // TODO: Properly convert the Contextual menu mouse-up
-    //       Potential source of the double menu
-    lastMouseTick = theEvent->when;
-    dragRectEnbl = FALSE;
-    dragRectControl = kCreateEmpty;
-    thePoint = theEvent->where;
-    GlobalToLocal(&thePoint);
-
-    vimModifiers = EventModifiers2VimMouseModifiers(theEvent->modifiers);
-    if (clickIsPopup)
-    {
-	vimModifiers &= ~MOUSE_CTRL;
-	clickIsPopup = FALSE;
-    }
-    gui_send_mouse_event(MOUSE_RELEASE, thePoint.h, thePoint.v, FALSE, vimModifiers);
-}
-
-    static pascal OSStatus
-gui_mac_mouse_wheel(EventHandlerCallRef nextHandler, EventRef theEvent,
-								   void *data)
-{
-    Point	point;
-    Rect	bounds;
-    UInt32	mod;
-    SInt32	delta;
-    int_u	vim_mod;
-    EventMouseWheelAxis axis;
-
-    if (noErr == GetEventParameter(theEvent, kEventParamMouseWheelAxis,
-			  typeMouseWheelAxis, NULL, sizeof(axis), NULL, &axis)
-	    && axis != kEventMouseWheelAxisY)
-	goto bail; // Vim only does up-down scrolling
-
-    if (noErr != GetEventParameter(theEvent, kEventParamMouseWheelDelta,
-			      typeSInt32, NULL, sizeof(SInt32), NULL, &delta))
-	goto bail;
-    if (noErr != GetEventParameter(theEvent, kEventParamMouseLocation,
-			      typeQDPoint, NULL, sizeof(Point), NULL, &point))
-	goto bail;
-    if (noErr != GetEventParameter(theEvent, kEventParamKeyModifiers,
-				typeUInt32, NULL, sizeof(UInt32), NULL, &mod))
-	goto bail;
-
-    vim_mod = 0;
-    if (mod & shiftKey)
-	vim_mod |= MOUSE_SHIFT;
-    if (mod & controlKey)
-	vim_mod |= MOUSE_CTRL;
-    if (mod & optionKey)
-	vim_mod |= MOUSE_ALT;
-
-    if (noErr == GetWindowBounds(gui.VimWindow, kWindowContentRgn, &bounds))
-    {
-	point.h -= bounds.left;
-	point.v -= bounds.top;
-    }
-
-    gui_send_mouse_event((delta > 0) ? MOUSE_4 : MOUSE_5,
-					    point.h, point.v, FALSE, vim_mod);
-
-    // post a bogus event to wake up WaitNextEvent
-    PostEvent(keyUp, 0);
-
-    return noErr;
-
-bail:
-    /*
-     * when we fail give any additional callback handler a chance to perform
-     * its actions
-     */
-    return CallNextEventHandler(nextHandler, theEvent);
-}
-
-     void
-gui_mch_mousehide(int hide)
-{
-    // TODO
-}
-
-#if 0
-
-/*
- * This would be the normal way of invoking the contextual menu
- * but the Vim API doesn't seem to a support a request to get
- * the menu that we should display
- */
-    void
-gui_mac_handle_contextual_menu(EventRecord *event)
-{
-/*
- *  Clone PopUp to use menu
- *  Create a object descriptor for the current selection
- *  Call the procedure
- */
-
-//  Call to Handle Popup
-    OSStatus status = ContextualMenuSelect(CntxMenu, event->where, false, kCMHelpItemNoHelp, "", NULL, &CntxType, &CntxMenuID, &CntxMenuItem);
-
-    if (status != noErr)
-	return;
-
-    if (CntxType == kCMMenuItemSelected)
-    {
-	// Handle the menu CntxMenuID, CntxMenuItem
-	// The submenu can be handle directly by gui_mac_handle_menu
-	// But what about the current menu, is the many changed by ContextualMenuSelect
-	gui_mac_handle_menu((CntxMenuID << 16) + CntxMenuItem);
-    }
-    else if (CntxMenuID == kCMShowHelpSelected)
-    {
-	// Should come up with the help
-    }
-
-}
-#endif
-
-/*
- * Handle menubar selection
- */
-    void
-gui_mac_handle_menu(long menuChoice)
-{
-    short	menu = HiWord(menuChoice);
-    short	item = LoWord(menuChoice);
-    vimmenu_T	*theVimMenu = root_menu;
-
-    if (menu == 256)  // TODO: use constant or gui.xyz
-    {
-	if (item == 1)
-	    gui_mch_beep(); // TODO: Popup dialog or do :intro
-    }
-    else if (item != 0)
-    {
-	theVimMenu = gui_mac_get_vim_menu(menu, item, root_menu);
-
-	if (theVimMenu)
-	    gui_menu_cb(theVimMenu);
-    }
-    HiliteMenu(0);
-}
-
-/*
- * Dispatch the event to proper handler
- */
-
-    void
-gui_mac_handle_event(EventRecord *event)
-{
-    OSErr	error;
-
-    // Handle contextual menu right now (if needed)
-    if (IsShowContextualMenuClick(event))
-    {
-# if 0
-	gui_mac_handle_contextual_menu(event);
-# else
-	gui_mac_doMouseDownEvent(event);
-# endif
-	return;
-    }
-
-    // Handle normal event
-    switch (event->what)
-    {
-#ifndef USE_CARBONKEYHANDLER
-	case (keyDown):
-	case (autoKey):
-	    gui_mac_doKeyEvent(event);
-	    break;
-#endif
-	case (keyUp):
-	    // We don't care about when the key is released
-	    break;
-
-	case (mouseDown):
-	    gui_mac_doMouseDownEvent(event);
-	    break;
-
-	case (mouseUp):
-	    gui_mac_doMouseUpEvent(event);
-	    break;
-
-	case (updateEvt):
-	    gui_mac_doUpdateEvent(event);
-	    break;
-
-	case (diskEvt):
-	    // We don't need special handling for disk insertion
-	    break;
-
-	case (activateEvt):
-	    gui_mac_doActivateEvent(event);
-	    break;
-
-	case (osEvt):
-	    switch ((event->message >> 24) & 0xFF)
-	    {
-		case (0xFA): // mouseMovedMessage
-		    gui_mac_doMouseMovedEvent(event);
-		    break;
-		case (0x01): // suspendResumeMessage
-		    gui_mac_doSuspendEvent(event);
-		    break;
-	    }
-	    break;
-
-#ifdef USE_AEVENT
-	case (kHighLevelEvent):
-	    // Someone's talking to us, through AppleEvents
-	    error = AEProcessAppleEvent(event); // TODO: Error Handling
-	    break;
-#endif
-    }
-}
-
-/*
- * ------------------------------------------------------------
- * Unknown Stuff
- * ------------------------------------------------------------
- */
-
-
-    GuiFont
-gui_mac_find_font(char_u *font_name)
-{
-    char_u	c;
-    char_u	*p;
-    char_u	pFontName[256];
-    Str255	systemFontname;
-    short	font_id;
-    short	size=9;
-    GuiFont	font;
-#if 0
-    char_u      *fontNamePtr;
-#endif
-
-    for (p = font_name; ((*p != 0) && (*p != ':')); p++)
-	;
-
-    c = *p;
-    *p = 0;
-
-#if 1
-    STRCPY(&pFontName[1], font_name);
-    pFontName[0] = STRLEN(font_name);
-    *p = c;
-
-    // Get the font name, minus the style suffix (:h, etc)
-    char_u fontName[256];
-    char_u *styleStart = vim_strchr(font_name, ':');
-    size_t fontNameLen = styleStart ? styleStart - font_name : STRLEN(fontName);
-    vim_strncpy(fontName, font_name, fontNameLen);
-
-    ATSUFontID fontRef;
-    FMFontStyle fontStyle;
-    font_id = 0;
-
-    if (ATSUFindFontFromName(&pFontName[1], pFontName[0], kFontFullName,
-		kFontMacintoshPlatform, kFontNoScriptCode, kFontNoLanguageCode,
-		&fontRef) == noErr)
-    {
-	if (FMGetFontFamilyInstanceFromFont(fontRef, &font_id, &fontStyle) != noErr)
-	    font_id = 0;
-    }
-
-    if (font_id == 0)
-    {
-	/*
-	 * Try again, this time replacing underscores in the font name
-	 * with spaces (:set guifont allows the two to be used
-	 * interchangeably; the Font Manager doesn't).
-	 */
-	int i, changed = FALSE;
-
-	for (i = pFontName[0]; i > 0; --i)
-	{
-	    if (pFontName[i] == '_')
-	    {
-		pFontName[i] = ' ';
-		changed = TRUE;
-	    }
-	}
-	if (changed)
-	    if (ATSUFindFontFromName(&pFontName[1], pFontName[0],
-			kFontFullName, kFontNoPlatformCode, kFontNoScriptCode,
-			kFontNoLanguageCode, &fontRef) == noErr)
-	    {
-		if (FMGetFontFamilyInstanceFromFont(fontRef, &font_id, &fontStyle) != noErr)
-		    font_id = 0;
-	    }
-    }
-
-#else
-    // name = C2Pascal_save(menu->dname);
-    fontNamePtr = C2Pascal_save_and_remove_backslash(font_name);
-
-    GetFNum(fontNamePtr, &font_id);
-#endif
-
-
-    if (font_id == 0)
-    {
-	// Oups, the system font was it the one the user want
-
-	if (FMGetFontFamilyName(systemFont, systemFontname) != noErr)
-	    return NOFONT;
-	if (!EqualString(pFontName, systemFontname, false, false))
-	    return NOFONT;
-    }
-    if (*p == ':')
-    {
-	p++;
-	// Set the values found after ':'
-	while (*p)
-	{
-	    switch (*p++)
-	    {
-		case 'h':
-		    size = points_to_pixels(p, &p, TRUE);
-		    break;
-		    /*
-		     * TODO: Maybe accept width and styles
-		     */
-	    }
-	    while (*p == ':')
-		p++;
-	}
-    }
-
-    if (size < 1)
-	size = 1;   // Avoid having a size of 0 with system font
-
-    font = (size << 16) + ((long) font_id & 0xFFFF);
-
-    return font;
-}
-
-/*
- * ------------------------------------------------------------
- * GUI_MCH functionality
- * ------------------------------------------------------------
- */
-
-/*
- * Parse the GUI related command-line arguments.  Any arguments used are
- * deleted from argv, and *argc is decremented accordingly.  This is called
- * when vim is started, whether or not the GUI has been started.
- */
-    void
-gui_mch_prepare(int *argc, char **argv)
-{
-    // TODO: Move most of this stuff toward gui_mch_init
-#ifdef USE_EXE_NAME
-    FSSpec	applDir;
-# ifndef USE_FIND_BUNDLE_PATH
-    short	applVRefNum;
-    long	applDirID;
-    Str255	volName;
-# else
-    ProcessSerialNumber psn;
-    FSRef	applFSRef;
-# endif
-#endif
-
-#if 0
-    InitCursor();
-
-    RegisterAppearanceClient();
-
-#ifdef USE_AEVENT
-    (void) InstallAEHandlers();
-#endif
-
-    pomme = NewMenu(256, "\p\024"); // 0x14= = Apple Menu
-
-    AppendMenu(pomme, "\pAbout VIM");
-
-    InsertMenu(pomme, 0);
-
-    DrawMenuBar();
-
-
-#ifndef USE_OFFSETED_WINDOW
-    SetRect(&windRect, 10, 48, 10+80*7 + 16, 48+24*11);
-#else
-    SetRect(&windRect, 300, 40, 300+80*7 + 16, 40+24*11);
-#endif
-
-
-    CreateNewWindow(kDocumentWindowClass,
-		kWindowResizableAttribute | kWindowCollapseBoxAttribute,
-		&windRect, &gui.VimWindow);
-    SetPortWindowPort(gui.VimWindow);
-
-    gui.char_width = 7;
-    gui.char_height = 11;
-    gui.char_ascent = 6;
-    gui.num_rows = 24;
-    gui.num_cols = 80;
-    gui.in_focus = TRUE; // For the moment -> syn. of front application
-
-    gScrollAction = NewControlActionUPP(gui_mac_scroll_action);
-    gScrollDrag   = NewControlActionUPP(gui_mac_drag_thumb);
-
-    dragRectEnbl = FALSE;
-    dragRgn = NULL;
-    dragRectControl = kCreateEmpty;
-    cursorRgn = NewRgn();
-#endif
-#ifdef USE_EXE_NAME
-# ifndef USE_FIND_BUNDLE_PATH
-    HGetVol(volName, &applVRefNum, &applDirID);
-    // TN2015: mention a possible bad VRefNum
-    FSMakeFSSpec(applVRefNum, applDirID, "\p", &applDir);
-# else
-    // OSErr GetApplicationBundleFSSpec(FSSpecPtr theFSSpecPtr)
-    // of TN2015
-    (void)GetCurrentProcess(&psn);
-    // if (err != noErr) return err;
-
-    (void)GetProcessBundleLocation(&psn, &applFSRef);
-    // if (err != noErr) return err;
-
-    (void)FSGetCatalogInfo(&applFSRef, kFSCatInfoNone, NULL, NULL, &applDir, NULL);
-
-    // This technique returns NIL when we disallow_gui
-# endif
-    exe_name = FullPathFromFSSpec_save(applDir);
-#endif
-}
-
-#ifndef ALWAYS_USE_GUI
-/*
- * Check if the GUI can be started.  Called before gvimrc is sourced.
- * Return OK or FAIL.
- */
-    int
-gui_mch_init_check(void)
-{
-    // TODO: For MacOS X find a way to return FAIL, if the user logged in
-    // using the >console
-    if (disallow_gui) // see main.c for reason to disallow
-	return FAIL;
-    return OK;
-}
-#endif
-
-    static OSErr
-receiveHandler(WindowRef theWindow, void *handlerRefCon, DragRef theDrag)
-{
-    int		x, y;
-    int_u	modifiers;
-    char_u	**fnames = NULL;
-    int		count;
-    int		i, j;
-
-    // Get drop position, modifiers and count of items
-    {
-	Point	point;
-	SInt16	mouseUpModifiers;
-	UInt16	countItem;
-
-	GetDragMouse(theDrag, &point, NULL);
-	GlobalToLocal(&point);
-	x = point.h;
-	y = point.v;
-	GetDragModifiers(theDrag, NULL, NULL, &mouseUpModifiers);
-	modifiers = EventModifiers2VimMouseModifiers(mouseUpModifiers);
-	CountDragItems(theDrag, &countItem);
-	count = countItem;
-    }
-
-    fnames = ALLOC_MULT(char_u *, count);
-    if (fnames == NULL)
-	return dragNotAcceptedErr;
-
-    // Get file names dropped
-    for (i = j = 0; i < count; ++i)
-    {
-	DragItemRef	item;
-	OSErr		err;
-	Size		size;
-	FlavorType	type = flavorTypeHFS;
-	HFSFlavor	hfsFlavor;
-
-	fnames[i] = NULL;
-	GetDragItemReferenceNumber(theDrag, i + 1, &item);
-	err = GetFlavorDataSize(theDrag, item, type, &size);
-	if (err != noErr || size > sizeof(hfsFlavor))
-	    continue;
-	err = GetFlavorData(theDrag, item, type, &hfsFlavor, &size, 0);
-	if (err != noErr)
-	    continue;
-	fnames[j++] = FullPathFromFSSpec_save(hfsFlavor.fileSpec);
-    }
-    count = j;
-
-    gui_handle_drop(x, y, modifiers, fnames, count);
-
-    // Fake mouse event to wake from stall
-    PostEvent(mouseUp, 0);
-
-    return noErr;
-}
-
-/*
- * Initialise the GUI.  Create all the windows, set up all the call-backs
- * etc.
- */
-    int
-gui_mch_init(void)
-{
-    // TODO: Move most of this stuff toward gui_mch_init
-    Rect	    windRect;
-    MenuHandle	    pomme;
-    EventHandlerRef mouseWheelHandlerRef;
-    EventTypeSpec   eventTypeSpec;
-    ControlRef	    rootControl;
-
-    if (Gestalt(gestaltSystemVersion, &gMacSystemVersion) != noErr)
-	gMacSystemVersion = 0x1000; // TODO: Default to minimum sensible value
-
-#if 1
-    InitCursor();
-
-    RegisterAppearanceClient();
-
-#ifdef USE_AEVENT
-    (void) InstallAEHandlers();
-#endif
-
-    pomme = NewMenu(256, "\p\024"); // 0x14= = Apple Menu
-
-    AppendMenu(pomme, "\pAbout VIM");
-
-    InsertMenu(pomme, 0);
-
-    DrawMenuBar();
-
-
-#ifndef USE_OFFSETED_WINDOW
-    SetRect(&windRect, 10, 48, 10+80*7 + 16, 48+24*11);
-#else
-    SetRect(&windRect, 300, 40, 300+80*7 + 16, 40+24*11);
-#endif
-
-    gui.VimWindow = NewCWindow(nil, &windRect, "\pgVim on Macintosh", true,
-			zoomDocProc,
-			(WindowPtr)-1L, true, 0);
-    CreateRootControl(gui.VimWindow, &rootControl);
-    InstallReceiveHandler((DragReceiveHandlerUPP)receiveHandler,
-	    gui.VimWindow, NULL);
-    SetPortWindowPort(gui.VimWindow);
-
-    gui.char_width = 7;
-    gui.char_height = 11;
-    gui.char_ascent = 6;
-    gui.num_rows = 24;
-    gui.num_cols = 80;
-    gui.in_focus = TRUE; // For the moment -> syn. of front application
-
-    gScrollAction = NewControlActionUPP(gui_mac_scroll_action);
-    gScrollDrag   = NewControlActionUPP(gui_mac_drag_thumb);
-
-    // Install Carbon event callbacks.
-    (void)InstallFontPanelHandler();
-
-    dragRectEnbl = FALSE;
-    dragRgn = NULL;
-    dragRectControl = kCreateEmpty;
-    cursorRgn = NewRgn();
-#endif
-    // Display any pending error messages
-    display_errors();
-
-    // Get background/foreground colors from system
-    // TODO: do the appropriate call to get real defaults
-    gui.norm_pixel = 0x00000000;
-    gui.back_pixel = 0x00FFFFFF;
-
-    // Get the colors from the "Normal" group (set in syntax.c or in a vimrc
-    // file).
-    set_normal_colors();
-
-    /*
-     * Check that none of the colors are the same as the background color.
-     * Then store the current values as the defaults.
-     */
-    gui_check_colors();
-    gui.def_norm_pixel = gui.norm_pixel;
-    gui.def_back_pixel = gui.back_pixel;
-
-    // Get the colors for the highlight groups (gui_check_colors() might have
-    // changed them)
-    highlight_gui_started();
-
-    /*
-     * Setting the gui constants
-     */
-#ifdef FEAT_MENU
-    gui.menu_height = 0;
-#endif
-    gui.scrollbar_height = gui.scrollbar_width = 15; // cheat 1 overlap
-    gui.border_offset = gui.border_width = 2;
-
-    // If Quartz-style text anti aliasing is available (see
-    // gui_mch_draw_string() below), enable it for all font sizes.
-    vim_setenv((char_u *)"QDTEXT_MINSIZE", (char_u *)"1");
-
-    eventTypeSpec.eventClass = kEventClassMouse;
-    eventTypeSpec.eventKind = kEventMouseWheelMoved;
-    mouseWheelHandlerUPP = NewEventHandlerUPP(gui_mac_mouse_wheel);
-    if (noErr != InstallApplicationEventHandler(mouseWheelHandlerUPP, 1,
-				 &eventTypeSpec, NULL, &mouseWheelHandlerRef))
-    {
-	mouseWheelHandlerRef = NULL;
-	DisposeEventHandlerUPP(mouseWheelHandlerUPP);
-	mouseWheelHandlerUPP = NULL;
-    }
-
-#ifdef USE_CARBONKEYHANDLER
-    InterfaceTypeList supportedServices = { kUnicodeDocument };
-    NewTSMDocument(1, supportedServices, &gTSMDocument, 0);
-
-    // We don't support inline input yet, use input window by default
-    UseInputWindow(gTSMDocument, TRUE);
-
-    // Should we activate the document by default?
-    // ActivateTSMDocument(gTSMDocument);
-
-    EventTypeSpec textEventTypes[] = {
-	{ kEventClassTextInput, kEventTextInputUpdateActiveInputArea },
-	{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
-	{ kEventClassTextInput, kEventTextInputPosToOffset },
-	{ kEventClassTextInput, kEventTextInputOffsetToPos },
-    };
-
-    keyEventHandlerUPP = NewEventHandlerUPP(gui_mac_handle_text_input);
-    if (noErr != InstallApplicationEventHandler(keyEventHandlerUPP,
-						NR_ELEMS(textEventTypes),
-						textEventTypes, NULL, NULL))
-    {
-	DisposeEventHandlerUPP(keyEventHandlerUPP);
-	keyEventHandlerUPP = NULL;
-    }
-
-    EventTypeSpec windowEventTypes[] = {
-	{ kEventClassWindow, kEventWindowActivated },
-	{ kEventClassWindow, kEventWindowDeactivated },
-    };
-
-    // Install window event handler to support TSMDocument activate and
-    // deactivate
-    winEventHandlerUPP = NewEventHandlerUPP(gui_mac_handle_window_activate);
-    if (noErr != InstallWindowEventHandler(gui.VimWindow,
-					   winEventHandlerUPP,
-					   NR_ELEMS(windowEventTypes),
-					   windowEventTypes, NULL, NULL))
-    {
-	DisposeEventHandlerUPP(winEventHandlerUPP);
-	winEventHandlerUPP = NULL;
-    }
-#endif
-
-#ifdef FEAT_GUI_TABLINE
-    /*
-     * Create the tabline
-     */
-    initialise_tabline();
-#endif
-
-    // TODO: Load bitmap if using TOOLBAR
-    return OK;
-}
-
-/*
- * Called when the foreground or background color has been changed.
- */
-    void
-gui_mch_new_colors(void)
-{
-    // TODO:
-    // This proc is called when Normal is set to a value
-    // so what must be done? I don't know
-}
-
-/*
- * Open the GUI window which was created by a call to gui_mch_init().
- */
-    int
-gui_mch_open(void)
-{
-    ShowWindow(gui.VimWindow);
-
-    if (gui_win_x != -1 && gui_win_y != -1)
-	gui_mch_set_winpos(gui_win_x, gui_win_y);
-
-    /*
-     * Make the GUI the foreground process (in case it was launched
-     * from the Terminal or via :gui).
-     */
-    {
-	ProcessSerialNumber psn;
-	if (GetCurrentProcess(&psn) == noErr)
-	    SetFrontProcess(&psn);
-    }
-
-    return OK;
-}
-
-#ifdef USE_ATSUI_DRAWING
-    static void
-gui_mac_dispose_atsui_style(void)
-{
-    if (p_macatsui && gFontStyle)
-	ATSUDisposeStyle(gFontStyle);
-    if (p_macatsui && gWideFontStyle)
-	ATSUDisposeStyle(gWideFontStyle);
-}
-#endif
-
-    void
-gui_mch_exit(int rc)
-{
-    // TODO: find out all what is missing here?
-    DisposeRgn(cursorRgn);
-
-#ifdef USE_CARBONKEYHANDLER
-    if (keyEventHandlerUPP)
-	DisposeEventHandlerUPP(keyEventHandlerUPP);
-#endif
-
-    if (mouseWheelHandlerUPP != NULL)
-	DisposeEventHandlerUPP(mouseWheelHandlerUPP);
-
-#ifdef USE_ATSUI_DRAWING
-    gui_mac_dispose_atsui_style();
-#endif
-
-#ifdef USE_CARBONKEYHANDLER
-    FixTSMDocument(gTSMDocument);
-    DeactivateTSMDocument(gTSMDocument);
-    DeleteTSMDocument(gTSMDocument);
-#endif
-
-    // Exit to shell?
-    exit(rc);
-}
-
-/*
- * Get the position of the top left corner of the window.
- */
-    int
-gui_mch_get_winpos(int *x, int *y)
-{
-    // TODO
-    Rect	bounds;
-    OSStatus	status;
-
-    // Carbon >= 1.0.2, MacOS >= 8.5
-    status = GetWindowBounds(gui.VimWindow, kWindowStructureRgn, &bounds);
-
-    if (status != noErr)
-	return FAIL;
-    *x = bounds.left;
-    *y = bounds.top;
-    return OK;
-}
-
-/*
- * Set the position of the top left corner of the window to the given
- * coordinates.
- */
-    void
-gui_mch_set_winpos(int x, int y)
-{
-    // TODO:  Should make sure the window is move within range
-    //	      e.g.: y > ~16 [Menu bar], x > 0, x < screen width
-    MoveWindowStructure(gui.VimWindow, x, y);
-}
-
-    void
-gui_mch_set_shellsize(
-    int		width,
-    int		height,
-    int		min_width,
-    int		min_height,
-    int		base_width,
-    int		base_height,
-    int		direction)
-{
-    CGrafPtr	VimPort;
-    Rect	VimBound;
-
-    if (gui.which_scrollbars[SBAR_LEFT])
-    {
-	VimPort = GetWindowPort(gui.VimWindow);
-	GetPortBounds(VimPort, &VimBound);
-	VimBound.left = -gui.scrollbar_width; // + 1;
-	SetPortBounds(VimPort, &VimBound);
-    //	GetWindowBounds(gui.VimWindow, kWindowGlobalPortRgn, &winPortRect); ??
-    }
-    else
-    {
-	VimPort = GetWindowPort(gui.VimWindow);
-	GetPortBounds(VimPort, &VimBound);
-	VimBound.left = 0;
-	SetPortBounds(VimPort, &VimBound);
-    }
-
-    SizeWindow(gui.VimWindow, width, height, TRUE);
-
-    gui_resize_shell(width, height);
-}
-
-/*
- * Get the screen dimensions.
- * Allow 10 pixels for horizontal borders, 40 for vertical borders.
- * Is there no way to find out how wide the borders really are?
- * TODO: Add live update of those value on suspend/resume.
- */
-    void
-gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
-{
-    GDHandle	dominantDevice = GetMainDevice();
-    Rect	screenRect = (**dominantDevice).gdRect;
-
-    *screen_w = screenRect.right - 10;
-    *screen_h = screenRect.bottom - 40;
-}
-
-
-/*
- * Open the Font Panel and wait for the user to select a font and
- * close the panel.  Then fill the buffer pointed to by font_name with
- * the name and size of the selected font and return the font's handle,
- * or NOFONT in case of an error.
- */
-    static GuiFont
-gui_mac_select_font(char_u *font_name)
-{
-    GuiFont		    selected_font = NOFONT;
-    OSStatus		    status;
-    FontSelectionQDStyle    curr_font;
-
-    // Initialize the Font Panel with the current font.
-    curr_font.instance.fontFamily = gui.norm_font & 0xFFFF;
-    curr_font.size = (gui.norm_font >> 16);
-    // TODO: set fontStyle once styles are supported in gui_mac_find_font()
-    curr_font.instance.fontStyle = 0;
-    curr_font.hasColor = false;
-    curr_font.version = 0; // version number of the style structure
-    status = SetFontInfoForSelection(kFontSelectionQDType,
-	    /*numStyles=*/1, &curr_font, /*eventTarget=*/NULL);
-
-    gFontPanelInfo.family = curr_font.instance.fontFamily;
-    gFontPanelInfo.style = curr_font.instance.fontStyle;
-    gFontPanelInfo.size = curr_font.size;
-
-    // Pop up the Font Panel.
-    status = FPShowHideFontPanel();
-    if (status == noErr)
-    {
-	/*
-	 * The Font Panel is modeless.  We really need it to be modal,
-	 * so we spin in an event loop until the panel is closed.
-	 */
-	gFontPanelInfo.isPanelVisible = true;
-	while (gFontPanelInfo.isPanelVisible)
-	{
-	    EventRecord e;
-	    WaitNextEvent(everyEvent, &e, /*sleep=*/20, /*mouseRgn=*/NULL);
-	}
-
-	GetFontPanelSelection(font_name);
-	selected_font = gui_mac_find_font(font_name);
-    }
-    return selected_font;
-}
-
-#ifdef USE_ATSUI_DRAWING
-    static void
-gui_mac_create_atsui_style(void)
-{
-    if (p_macatsui && gFontStyle == NULL)
-    {
-	if (ATSUCreateStyle(&gFontStyle) != noErr)
-	    gFontStyle = NULL;
-    }
-    if (p_macatsui && gWideFontStyle == NULL)
-    {
-	if (ATSUCreateStyle(&gWideFontStyle) != noErr)
-	    gWideFontStyle = NULL;
-    }
-
-    p_macatsui_last = p_macatsui;
-}
-#endif
-
-/*
- * Initialise vim to use the font with the given name.	Return FAIL if the font
- * could not be loaded, OK otherwise.
- */
-    int
-gui_mch_init_font(char_u *font_name, int fontset)
-{
-    // TODO: Add support for bold italic underline proportional etc...
-    Str255	suggestedFont = "\pMonaco";
-    int		suggestedSize = 10;
-    FontInfo	font_info;
-    short	font_id;
-    GuiFont	font;
-    char_u	used_font_name[512];
-
-#ifdef USE_ATSUI_DRAWING
-    gui_mac_create_atsui_style();
-#endif
-
-    if (font_name == NULL)
-    {
-	// First try to get the suggested font
-	GetFNum(suggestedFont, &font_id);
-
-	if (font_id == 0)
-	{
-	    // Then pickup the standard application font
-	    font_id = GetAppFont();
-	    STRCPY(used_font_name, "default");
-	}
-	else
-	    STRCPY(used_font_name, "Monaco");
-	font = (suggestedSize << 16) + ((long) font_id & 0xFFFF);
-    }
-    else if (STRCMP(font_name, "*") == 0)
-    {
-	char_u *new_p_guifont;
-
-	font = gui_mac_select_font(used_font_name);
-	if (font == NOFONT)
-	    return FAIL;
-
-	// Set guifont to the name of the selected font.
-	new_p_guifont = alloc(STRLEN(used_font_name) + 1);
-	if (new_p_guifont != NULL)
-	{
-	    STRCPY(new_p_guifont, used_font_name);
-	    vim_free(p_guifont);
-	    p_guifont = new_p_guifont;
-	    // Replace spaces in the font name with underscores.
-	    for ( ; *new_p_guifont; ++new_p_guifont)
-	    {
-		if (*new_p_guifont == ' ')
-		    *new_p_guifont = '_';
-	    }
-	}
-    }
-    else
-    {
-	font = gui_mac_find_font(font_name);
-	vim_strncpy(used_font_name, font_name, sizeof(used_font_name) - 1);
-
-	if (font == NOFONT)
-	    return FAIL;
-    }
-
-    gui.norm_font = font;
-
-    hl_set_font_name(used_font_name);
-
-    TextSize(font >> 16);
-    TextFont(font & 0xFFFF);
-
-    GetFontInfo(&font_info);
-
-    gui.char_ascent = font_info.ascent;
-    gui.char_width  = CharWidth('_');
-    gui.char_height = font_info.ascent + font_info.descent + p_linespace;
-
-#ifdef USE_ATSUI_DRAWING
-    if (p_macatsui && gFontStyle)
-	gui_mac_set_font_attributes(font);
-#endif
-
-    return OK;
-}
-
-/*
- * Adjust gui.char_height (after 'linespace' was changed).
- */
-    int
-gui_mch_adjust_charheight(void)
-{
-    FontInfo    font_info;
-
-    GetFontInfo(&font_info);
-    gui.char_height = font_info.ascent + font_info.descent + p_linespace;
-    gui.char_ascent = font_info.ascent + p_linespace / 2;
-    return OK;
-}
-
-/*
- * Get a font structure for highlighting.
- */
-    GuiFont
-gui_mch_get_font(char_u *name, int giveErrorIfMissing)
-{
-    GuiFont font;
-
-    font = gui_mac_find_font(name);
-
-    if (font == NOFONT)
-    {
-	if (giveErrorIfMissing)
-	    semsg(_(e_font), name);
-	return NOFONT;
-    }
-    /*
-     * TODO : Accept only monospace
-     */
-
-    return font;
-}
-
-#if defined(FEAT_EVAL) || defined(PROTO)
-/*
- * Return the name of font "font" in allocated memory.
- * Don't know how to get the actual name, thus use the provided name.
- */
-    char_u *
-gui_mch_get_fontname(GuiFont font, char_u *name)
-{
-    if (name == NULL)
-	return NULL;
-    return vim_strsave(name);
-}
-#endif
-
-#ifdef USE_ATSUI_DRAWING
-    static void
-gui_mac_set_font_attributes(GuiFont font)
-{
-    ATSUFontID	fontID;
-    Fixed	fontSize;
-    Fixed	fontWidth;
-
-    fontID    = font & 0xFFFF;
-    fontSize  = Long2Fix(font >> 16);
-    fontWidth = Long2Fix(gui.char_width);
-
-    ATSUAttributeTag attribTags[] =
-    {
-	kATSUFontTag, kATSUSizeTag, kATSUImposeWidthTag,
-	kATSUMaxATSUITagValue + 1
-    };
-
-    ByteCount attribSizes[] =
-    {
-	sizeof(ATSUFontID), sizeof(Fixed), sizeof(fontWidth),
-	sizeof(font)
-    };
-
-    ATSUAttributeValuePtr attribValues[] =
-    {
-	&fontID, &fontSize, &fontWidth, &font
-    };
-
-    if (FMGetFontFromFontFamilyInstance(fontID, 0, &fontID, NULL) == noErr)
-    {
-	if (ATSUSetAttributes(gFontStyle,
-		    (sizeof attribTags) / sizeof(ATSUAttributeTag),
-		    attribTags, attribSizes, attribValues) != noErr)
-	{
-# ifndef NDEBUG
-	    fprintf(stderr, "couldn't set font style\n");
-# endif
-	    ATSUDisposeStyle(gFontStyle);
-	    gFontStyle = NULL;
-	}
-
-	if (has_mbyte)
-	{
-	    // FIXME: we should use a more mbyte sensitive way to support
-	    // wide font drawing
-	    fontWidth = Long2Fix(gui.char_width * 2);
-
-	    if (ATSUSetAttributes(gWideFontStyle,
-			(sizeof attribTags) / sizeof(ATSUAttributeTag),
-			attribTags, attribSizes, attribValues) != noErr)
-	    {
-		ATSUDisposeStyle(gWideFontStyle);
-		gWideFontStyle = NULL;
-	    }
-	}
-    }
-}
-#endif
-
-/*
- * Set the current text font.
- */
-    void
-gui_mch_set_font(GuiFont font)
-{
-#ifdef USE_ATSUI_DRAWING
-    GuiFont			currFont;
-    ByteCount			actualFontByteCount;
-
-    if (p_macatsui && gFontStyle)
-    {
-	// Avoid setting same font again
-	if (ATSUGetAttribute(gFontStyle, kATSUMaxATSUITagValue + 1,
-		    sizeof(font), &currFont, &actualFontByteCount) == noErr
-		&& actualFontByteCount == (sizeof font))
-	{
-	    if (currFont == font)
-		return;
-	}
-
-	gui_mac_set_font_attributes(font);
-    }
-
-    if (p_macatsui && !gIsFontFallbackSet)
-    {
-	// Setup automatic font substitution. The user's guifontwide
-	// is tried first, then the system tries other fonts.
-#if 0
-	ATSUAttributeTag fallbackTags[] = { kATSULineFontFallbacksTag };
-	ByteCount fallbackSizes[] = { sizeof(ATSUFontFallbacks) };
-	ATSUCreateFontFallbacks(&gFontFallbacks);
-	ATSUSetObjFontFallbacks(gFontFallbacks, );
-#endif
-	if (gui.wide_font)
-	{
-	    ATSUFontID fallbackFonts;
-	    gIsFontFallbackSet = TRUE;
-
-	    if (FMGetFontFromFontFamilyInstance(
-			(gui.wide_font & 0xFFFF),
-			0,
-			&fallbackFonts,
-			NULL) == noErr)
-	    {
-		ATSUSetFontFallbacks((sizeof fallbackFonts)/sizeof(ATSUFontID),
-				     &fallbackFonts,
-				     kATSUSequentialFallbacksPreferred);
-	    }
-//	ATSUAttributeValuePtr fallbackValues[] = { };
-	}
-    }
-#endif
-    TextSize(font >> 16);
-    TextFont(font & 0xFFFF);
-}
-
-/*
- * If a font is not going to be used, free its structure.
- */
-    void
-gui_mch_free_font(GuiFont font)
-{
-    /*
-     * Free font when "font" is not 0.
-     * Nothing to do in the current implementation, since
-     * nothing is allocated for each font used.
-     */
-}
-
-/*
- * Return the Pixel value (color) for the given color name.  This routine was
- * pretty much taken from example code in the Silicon Graphics OSF/Motif
- * Programmer's Guide.
- * Return INVALCOLOR when failed.
- */
-    guicolor_T
-gui_mch_get_color(char_u *name)
-{
-    // TODO: Add support for the new named color of MacOS 8
-    RGBColor	MacColor;
-
-    if (STRICMP(name, "hilite") == 0)
-    {
-	LMGetHiliteRGB(&MacColor);
-	return (RGB(MacColor.red >> 8, MacColor.green >> 8, MacColor.blue >> 8));
-    }
-    return gui_get_color_cmn(name);
-}
-
-    guicolor_T
-gui_mch_get_rgb_color(int r, int g, int b)
-{
-    return gui_get_rgb_color_cmn(r, g, b);
-}
-
-/*
- * Set the current text foreground color.
- */
-    void
-gui_mch_set_fg_color(guicolor_T color)
-{
-    RGBColor TheColor;
-
-    TheColor.red = Red(color) * 0x0101;
-    TheColor.green = Green(color) * 0x0101;
-    TheColor.blue = Blue(color) * 0x0101;
-
-    RGBForeColor(&TheColor);
-}
-
-/*
- * Set the current text background color.
- */
-    void
-gui_mch_set_bg_color(guicolor_T color)
-{
-    RGBColor TheColor;
-
-    TheColor.red = Red(color) * 0x0101;
-    TheColor.green = Green(color) * 0x0101;
-    TheColor.blue = Blue(color) * 0x0101;
-
-    RGBBackColor(&TheColor);
-}
-
-RGBColor specialColor;
-
-/*
- * Set the current text special color.
- */
-    void
-gui_mch_set_sp_color(guicolor_T color)
-{
-    specialColor.red = Red(color) * 0x0101;
-    specialColor.green = Green(color) * 0x0101;
-    specialColor.blue = Blue(color) * 0x0101;
-}
-
-/*
- * Draw undercurl at the bottom of the character cell.
- */
-    static void
-draw_undercurl(int flags, int row, int col, int cells)
-{
-    int			x;
-    int			offset;
-    const static int	val[8] = {1, 0, 0, 0, 1, 2, 2, 2 };
-    int			y = FILL_Y(row + 1) - 1;
-
-    RGBForeColor(&specialColor);
-
-    offset = val[FILL_X(col) % 8];
-    MoveTo(FILL_X(col), y - offset);
-
-    for (x = FILL_X(col); x < FILL_X(col + cells); ++x)
-    {
-	offset = val[x % 8];
-	LineTo(x, y - offset);
-    }
-}
-
-
-    static void
-draw_string_QD(int row, int col, char_u *s, int len, int flags)
-{
-    char_u	*tofree = NULL;
-
-    if (output_conv.vc_type != CONV_NONE)
-    {
-	tofree = string_convert(&output_conv, s, &len);
-	if (tofree != NULL)
-	    s = tofree;
-    }
-
-    /*
-     * On OS X, try using Quartz-style text antialiasing.
-     */
-    if (gMacSystemVersion >= 0x1020)
-    {
-	// Quartz antialiasing is available only in OS 10.2 and later.
-	UInt32 qd_flags = (p_antialias ?
-			     kQDUseCGTextRendering | kQDUseCGTextMetrics : 0);
-	QDSwapTextFlags(qd_flags);
-    }
-
-    /*
-     * When antialiasing we're using srcOr mode, we have to clear the block
-     * before drawing the text.
-     * Also needed when 'linespace' is non-zero to remove the cursor and
-     * underlining.
-     * But not when drawing transparently.
-     * The following is like calling gui_mch_clear_block(row, col, row, col +
-     * len - 1), but without setting the bg color to gui.back_pixel.
-     */
-    if (((gMacSystemVersion >= 0x1020 && p_antialias) || p_linespace != 0)
-	    && !(flags & DRAW_TRANSP))
-    {
-	Rect rc;
-
-	rc.left = FILL_X(col);
-	rc.top = FILL_Y(row);
-	// Multibyte computation taken from gui_w32.c
-	if (has_mbyte)
-	{
-	    // Compute the length in display cells.
-	    rc.right = FILL_X(col + mb_string2cells(s, len));
-	}
-	else
-	    rc.right = FILL_X(col + len) + (col + len == Columns);
-	rc.bottom = FILL_Y(row + 1);
-	EraseRect(&rc);
-    }
-
-    if (gMacSystemVersion >= 0x1020 && p_antialias)
-    {
-	StyleParameter face;
-
-	face = normal;
-	if (flags & DRAW_BOLD)
-	    face |= bold;
-	if (flags & DRAW_UNDERL)
-	    face |= underline;
-	TextFace(face);
-
-	// Quartz antialiasing works only in srcOr transfer mode.
-	TextMode(srcOr);
-
-	MoveTo(TEXT_X(col), TEXT_Y(row));
-	DrawText((char*)s, 0, len);
-    }
-    else
-    {
-	// Use old-style, non-antialiased QuickDraw text rendering.
-	TextMode(srcCopy);
-	TextFace(normal);
-
-    //  SelectFont(hdc, gui.currFont);
-
-	if (flags & DRAW_TRANSP)
-	    TextMode(srcOr);
-
-	MoveTo(TEXT_X(col), TEXT_Y(row));
-	DrawText((char *)s, 0, len);
-
-	if (flags & DRAW_BOLD)
-	{
-	    TextMode(srcOr);
-	    MoveTo(TEXT_X(col) + 1, TEXT_Y(row));
-	    DrawText((char *)s, 0, len);
-	}
-
-	if (flags & DRAW_UNDERL)
-	{
-	    MoveTo(FILL_X(col), FILL_Y(row + 1) - 1);
-	    LineTo(FILL_X(col + len) - 1, FILL_Y(row + 1) - 1);
-	}
-	if (flags & DRAW_STRIKE)
-	{
-	    MoveTo(FILL_X(col), FILL_Y(row + 1) - gui.char_height/2);
-	    LineTo(FILL_X(col + len) - 1, FILL_Y(row + 1) - gui.char_height/2);
-	}
-    }
-
-    if (flags & DRAW_UNDERC)
-	draw_undercurl(flags, row, col, len);
-
-    vim_free(tofree);
-}
-
-#ifdef USE_ATSUI_DRAWING
-
-    static void
-draw_string_ATSUI(int row, int col, char_u *s, int len, int flags)
-{
-    // ATSUI requires utf-16 strings
-    UniCharCount utf16_len;
-    UniChar *tofree = mac_enc_to_utf16(s, len, (size_t *)&utf16_len);
-    utf16_len /= sizeof(UniChar);
-
-    // - ATSUI automatically antialiases text (Someone)
-    // - for some reason it does not work... (Jussi)
-#ifdef MAC_ATSUI_DEBUG
-    fprintf(stderr, "row = %d, col = %d, len = %d: '%c'\n",
-	    row, col, len, len == 1 ? s[0] : ' ');
-#endif
-    /*
-     * When antialiasing we're using srcOr mode, we have to clear the block
-     * before drawing the text.
-     * Also needed when 'linespace' is non-zero to remove the cursor and
-     * underlining.
-     * But not when drawing transparently.
-     * The following is like calling gui_mch_clear_block(row, col, row, col +
-     * len - 1), but without setting the bg color to gui.back_pixel.
-     */
-    if ((flags & DRAW_TRANSP) == 0)
-    {
-	Rect rc;
-
-	rc.left = FILL_X(col);
-	rc.top = FILL_Y(row);
-	// Multibyte computation taken from gui_w32.c
-	if (has_mbyte)
-	{
-	    // Compute the length in display cells.
-	    rc.right = FILL_X(col + mb_string2cells(s, len));
-	}
-	else
-	    rc.right = FILL_X(col + len) + (col + len == Columns);
-
-	rc.bottom = FILL_Y(row + 1);
-	EraseRect(&rc);
-    }
-
-    {
-	TextMode(srcCopy);
-	TextFace(normal);
-
-	//  SelectFont(hdc, gui.currFont);
-	if (flags & DRAW_TRANSP)
-	    TextMode(srcOr);
-
-	MoveTo(TEXT_X(col), TEXT_Y(row));
-
-	if (gFontStyle && flags & DRAW_BOLD)
-	{
-	    Boolean attValue = true;
-	    ATSUAttributeTag attribTags[] = { kATSUQDBoldfaceTag };
-	    ByteCount attribSizes[] = { sizeof(Boolean) };
-	    ATSUAttributeValuePtr attribValues[] = { &attValue };
-
-	    ATSUSetAttributes(gFontStyle, 1, attribTags, attribSizes, attribValues);
-	}
-
-	UInt32 useAntialias = p_antialias ? kATSStyleApplyAntiAliasing
-					  : kATSStyleNoAntiAliasing;
-	if (useAntialias != useAntialias_cached)
-	{
-	    ATSUAttributeTag attribTags[] = { kATSUStyleRenderingOptionsTag };
-	    ByteCount attribSizes[] = { sizeof(UInt32) };
-	    ATSUAttributeValuePtr attribValues[] = { &useAntialias };
-
-	    if (gFontStyle)
-		ATSUSetAttributes(gFontStyle, 1, attribTags,
-						   attribSizes, attribValues);
-	    if (gWideFontStyle)
-		ATSUSetAttributes(gWideFontStyle, 1, attribTags,
-						   attribSizes, attribValues);
-
-	    useAntialias_cached = useAntialias;
-	}
-
-	if (has_mbyte)
-	{
-	    int n, width_in_cell, last_width_in_cell;
-	    UniCharArrayOffset offset = 0;
-	    UniCharCount yet_to_draw = 0;
-	    ATSUTextLayout textLayout;
-	    ATSUStyle      textStyle;
-
-	    last_width_in_cell = 1;
-	    ATSUCreateTextLayout(&textLayout);
-	    ATSUSetTextPointerLocation(textLayout, tofree,
-				       kATSUFromTextBeginning,
-				       kATSUToTextEnd, utf16_len);
-	    /*
-	       ATSUSetRunStyle(textLayout, gFontStyle,
-	       kATSUFromTextBeginning, kATSUToTextEnd); */
-
-	    // Compute the length in display cells.
-	    for (n = 0; n < len; n += MB_BYTE2LEN(s[n]))
-	    {
-		width_in_cell = (*mb_ptr2cells)(s + n);
-
-		// probably we are switching from single byte character
-		// to multibyte characters (which requires more than one
-		// cell to draw)
-		if (width_in_cell != last_width_in_cell)
-		{
-#ifdef MAC_ATSUI_DEBUG
-		    fprintf(stderr, "\tn = %2d, (%d-%d), offset = %d, yet_to_draw = %d\n",
-			    n, last_width_in_cell, width_in_cell, offset, yet_to_draw);
-#endif
-		    textStyle = last_width_in_cell > 1 ? gWideFontStyle
-								 : gFontStyle;
-
-		    ATSUSetRunStyle(textLayout, textStyle, offset, yet_to_draw);
-		    offset += yet_to_draw;
-		    yet_to_draw = 0;
-		    last_width_in_cell = width_in_cell;
-		}
-
-		yet_to_draw++;
-	    }
-
-	    if (yet_to_draw)
-	    {
-#ifdef MAC_ATSUI_DEBUG
-		fprintf(stderr, "\tn = %2d, (%d-%d), offset = %d, yet_to_draw = %d\n",
-			n, last_width_in_cell, width_in_cell, offset, yet_to_draw);
-#endif
-		// finish the rest style
-		textStyle = width_in_cell > 1 ? gWideFontStyle : gFontStyle;
-		ATSUSetRunStyle(textLayout, textStyle, offset, kATSUToTextEnd);
-	    }
-
-	    ATSUSetTransientFontMatching(textLayout, TRUE);
-	    ATSUDrawText(textLayout,
-			 kATSUFromTextBeginning, kATSUToTextEnd,
-			 kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
-	    ATSUDisposeTextLayout(textLayout);
-	}
-	else
-	{
-	    ATSUTextLayout textLayout;
-
-	    if (ATSUCreateTextLayoutWithTextPtr(tofree,
-			kATSUFromTextBeginning, kATSUToTextEnd,
-			utf16_len,
-			(gFontStyle ? 1 : 0), &utf16_len,
-			(gFontStyle ? &gFontStyle : NULL),
-			&textLayout) == noErr)
-	    {
-		ATSUSetTransientFontMatching(textLayout, TRUE);
-
-		ATSUDrawText(textLayout,
-			kATSUFromTextBeginning, kATSUToTextEnd,
-			kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
-
-		ATSUDisposeTextLayout(textLayout);
-	    }
-	}
-
-	// drawing is done, now reset bold to normal
-	if (gFontStyle && flags & DRAW_BOLD)
-	{
-	    Boolean attValue = false;
-
-	    ATSUAttributeTag attribTags[] = { kATSUQDBoldfaceTag };
-	    ByteCount attribSizes[] = { sizeof(Boolean) };
-	    ATSUAttributeValuePtr attribValues[] = { &attValue };
-
-	    ATSUSetAttributes(gFontStyle, 1, attribTags, attribSizes,
-								attribValues);
-	}
-    }
-
-    if (flags & DRAW_UNDERC)
-	draw_undercurl(flags, row, col, len);
-
-    vim_free(tofree);
-}
-#endif
-
-    void
-gui_mch_draw_string(int row, int col, char_u *s, int len, int flags)
-{
-#if defined(USE_ATSUI_DRAWING)
-    if (p_macatsui == 0 && p_macatsui_last != 0)
-	// switch from macatsui to nomacatsui
-	gui_mac_dispose_atsui_style();
-    else if (p_macatsui != 0 && p_macatsui_last == 0)
-	// switch from nomacatsui to macatsui
-	gui_mac_create_atsui_style();
-
-    if (p_macatsui)
-	draw_string_ATSUI(row, col, s, len, flags);
-    else
-#endif
-	draw_string_QD(row, col, s, len, flags);
-}
-
-/*
- * Return OK if the key with the termcap name "name" is supported.
- */
-    int
-gui_mch_haskey(char_u *name)
-{
-    int i;
-
-    for (i = 0; special_keys[i].key_sym != (KeySym)0; i++)
-	if (name[0] == special_keys[i].vim_code0 &&
-					 name[1] == special_keys[i].vim_code1)
-	    return OK;
-    return FAIL;
-}
-
-    void
-gui_mch_beep(void)
-{
-    SysBeep(1); // Should this be 0? (????)
-}
-
-    void
-gui_mch_flash(int msec)
-{
-    // Do a visual beep by reversing the foreground and background colors
-    Rect    rc;
-
-    /*
-     * Note: InvertRect() excludes right and bottom of rectangle.
-     */
-    rc.left = 0;
-    rc.top = 0;
-    rc.right = gui.num_cols * gui.char_width;
-    rc.bottom = gui.num_rows * gui.char_height;
-    InvertRect(&rc);
-
-    ui_delay((long)msec, TRUE);		// wait for some msec
-
-    InvertRect(&rc);
-}
-
-/*
- * Invert a rectangle from row r, column c, for nr rows and nc columns.
- */
-    void
-gui_mch_invert_rectangle(int r, int c, int nr, int nc)
-{
-    Rect	rc;
-
-    /*
-     * Note: InvertRect() excludes right and bottom of rectangle.
-     */
-    rc.left = FILL_X(c);
-    rc.top = FILL_Y(r);
-    rc.right = rc.left + nc * gui.char_width;
-    rc.bottom = rc.top + nr * gui.char_height;
-    InvertRect(&rc);
-}
-
-/*
- * Iconify the GUI window.
- */
-    void
-gui_mch_iconify(void)
-{
-    // TODO: find out what could replace iconify
-    //	     -window shade?
-    //	     -hide application?
-}
-
-#if defined(FEAT_EVAL) || defined(PROTO)
-/*
- * Bring the Vim window to the foreground.
- */
-    void
-gui_mch_set_foreground(void)
-{
-    // TODO
-}
-#endif
-
-/*
- * Draw a cursor without focus.
- */
-    void
-gui_mch_draw_hollow_cursor(guicolor_T color)
-{
-    Rect rc;
-
-    /*
-     * Note: FrameRect() excludes right and bottom of rectangle.
-     */
-    rc.left = FILL_X(gui.col);
-    rc.top = FILL_Y(gui.row);
-    rc.right = rc.left + gui.char_width;
-    if (mb_lefthalve(gui.row, gui.col))
-	rc.right += gui.char_width;
-    rc.bottom = rc.top + gui.char_height;
-
-    gui_mch_set_fg_color(color);
-
-    FrameRect(&rc);
-}
-
-/*
- * Draw part of a cursor, only w pixels wide, and h pixels high.
- */
-    void
-gui_mch_draw_part_cursor(int w, int h, guicolor_T color)
-{
-    Rect rc;
-
-#ifdef FEAT_RIGHTLEFT
-    // vertical line should be on the right of current point
-    if (CURSOR_BAR_RIGHT)
-	rc.left = FILL_X(gui.col + 1) - w;
-    else
-#endif
-	rc.left = FILL_X(gui.col);
-    rc.top = FILL_Y(gui.row) + gui.char_height - h;
-    rc.right = rc.left + w;
-    rc.bottom = rc.top + h;
-
-    gui_mch_set_fg_color(color);
-
-    FrameRect(&rc);
-//    PaintRect(&rc);
-}
-
-
-
-/*
- * Catch up with any queued X events.  This may put keyboard input into the
- * input buffer, call resize call-backs, trigger timers etc.  If there is
- * nothing in the X event queue (& no timers pending), then we return
- * immediately.
- */
-    void
-gui_mch_update(void)
-{
-    // TODO: find what to do
-    //	     maybe call gui_mch_wait_for_chars (0)
-    //	     more like look at EventQueue then
-    //	     call heart of gui_mch_wait_for_chars;
-    //
-    //	if (eventther)
-    //	    gui_mac_handle_event(&event);
-    EventRecord theEvent;
-
-    if (EventAvail(everyEvent, &theEvent))
-	if (theEvent.what != nullEvent)
-	    gui_mch_wait_for_chars(0);
-}
-
-/*
- * Simple wrapper to neglect more easily the time
- * spent inside WaitNextEvent while profiling.
- */
-
-    pascal
-    Boolean
-WaitNextEventWrp(EventMask eventMask, EventRecord *theEvent, UInt32 sleep, RgnHandle mouseRgn)
-{
-    if (((long) sleep) < -1)
-	sleep = 32767;
-    return WaitNextEvent(eventMask, theEvent, sleep, mouseRgn);
-}
-
-/*
- * GUI input routine called by gui_wait_for_chars().  Waits for a character
- * from the keyboard.
- *  wtime == -1	    Wait forever.
- *  wtime == 0	    This should never happen.
- *  wtime > 0	    Wait wtime milliseconds for a character.
- * Returns OK if a character was found to be available within the given time,
- * or FAIL otherwise.
- */
-    int
-gui_mch_wait_for_chars(int wtime)
-{
-    EventMask	mask  = (everyEvent);
-    EventRecord event;
-    long	entryTick;
-    long	currentTick;
-    long	sleeppyTick;
-
-    // If we are providing life feedback with the scrollbar,
-    // we don't want to try to wait for an event, or else
-    // there won't be any life feedback.
-    if (dragged_sb != NULL)
-	return FAIL;
-	// TODO: Check if FAIL is the proper return code
-
-    entryTick = TickCount();
-
-    allow_scrollbar = TRUE;
-
-    do
-    {
-#if 0
-	if (dragRectControl == kCreateEmpty)
-	{
-	    dragRgn = NULL;
-	    dragRectControl = kNothing;
-	}
-	else
-#endif
-	if (dragRectControl == kCreateRect)
-	{
-	    dragRgn = cursorRgn;
-	    RectRgn(dragRgn, &dragRect);
-	    dragRectControl = kNothing;
-	}
-	/*
-	 * Don't use gui_mch_update() because then we will spin-lock until a
-	 * char arrives, instead we use WaitNextEventWrp() to hang until an
-	 * event arrives.  No need to check for input_buf_full because we are
-	 * returning as soon as it contains a single char.
-	 */
-	// TODO: reduce wtime accordingly???
-	if (wtime > -1)
-	    sleeppyTick = 60 * wtime / 1000;
-	else
-	    sleeppyTick = 32767;
-
-	if (WaitNextEventWrp(mask, &event, sleeppyTick, dragRgn))
-	{
-	    gui_mac_handle_event(&event);
-	    if (input_available())
-	    {
-		allow_scrollbar = FALSE;
-		return OK;
-	    }
-	}
-	currentTick = TickCount();
-    }
-    while ((wtime == -1) || ((currentTick - entryTick) < 60*wtime/1000));
-
-    allow_scrollbar = FALSE;
-    return FAIL;
-}
-
-/*
- * Output routines.
- */
-
-/*
- * Flush any output to the screen
- */
-    void
-gui_mch_flush(void)
-{
-    // TODO: Is anything needed here?
-}
-
-/*
- * Clear a rectangular region of the screen from text pos (row1, col1) to
- * (row2, col2) inclusive.
- */
-    void
-gui_mch_clear_block(int row1, int col1, int row2, int col2)
-{
-    Rect rc;
-
-    /*
-     * Clear one extra pixel at the far right, for when bold characters have
-     * spilled over to the next column.
-     */
-    rc.left = FILL_X(col1);
-    rc.top = FILL_Y(row1);
-    rc.right = FILL_X(col2 + 1) + (col2 == Columns - 1);
-    rc.bottom = FILL_Y(row2 + 1);
-
-    gui_mch_set_bg_color(gui.back_pixel);
-    EraseRect(&rc);
-}
-
-/*
- * Clear the whole text window.
- */
-    void
-gui_mch_clear_all(void)
-{
-    Rect	rc;
-
-    rc.left = 0;
-    rc.top = 0;
-    rc.right = Columns * gui.char_width + 2 * gui.border_width;
-    rc.bottom = Rows * gui.char_height + 2 * gui.border_width;
-
-    gui_mch_set_bg_color(gui.back_pixel);
-    EraseRect(&rc);
-//  gui_mch_set_fg_color(gui.norm_pixel);
-//    FrameRect(&rc);
-}
-
-/*
- * Delete the given number of lines from the given row, scrolling up any
- * text further down within the scroll region.
- */
-    void
-gui_mch_delete_lines(int row, int num_lines)
-{
-    Rect	rc;
-
-    // changed without checking!
-    rc.left = FILL_X(gui.scroll_region_left);
-    rc.right = FILL_X(gui.scroll_region_right + 1);
-    rc.top = FILL_Y(row);
-    rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
-
-    gui_mch_set_bg_color(gui.back_pixel);
-    ScrollRect(&rc, 0, -num_lines * gui.char_height, (RgnHandle) nil);
-
-    gui_clear_block(gui.scroll_region_bot - num_lines + 1,
-						       gui.scroll_region_left,
-	gui.scroll_region_bot, gui.scroll_region_right);
-}
-
-/*
- * Insert the given number of lines before the given row, scrolling down any
- * following text within the scroll region.
- */
-    void
-gui_mch_insert_lines(int row, int num_lines)
-{
-    Rect rc;
-
-    rc.left = FILL_X(gui.scroll_region_left);
-    rc.right = FILL_X(gui.scroll_region_right + 1);
-    rc.top = FILL_Y(row);
-    rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
-
-    gui_mch_set_bg_color(gui.back_pixel);
-
-    ScrollRect(&rc, 0, gui.char_height * num_lines, (RgnHandle) nil);
-
-    // Update gui.cursor_row if the cursor scrolled or copied over
-    if (gui.cursor_row >= gui.row
-	    && gui.cursor_col >= gui.scroll_region_left
-	    && gui.cursor_col <= gui.scroll_region_right)
-    {
-	if (gui.cursor_row <= gui.scroll_region_bot - num_lines)
-	    gui.cursor_row += num_lines;
-	else if (gui.cursor_row <= gui.scroll_region_bot)
-	    gui.cursor_is_valid = FALSE;
-    }
-
-    gui_clear_block(row, gui.scroll_region_left,
-				row + num_lines - 1, gui.scroll_region_right);
-}
-
-    /*
-     * TODO: add a vim format to the clipboard which remember
-     *	     LINEWISE, CHARWISE, BLOCKWISE
-     */
-
-    void
-clip_mch_request_selection(Clipboard_T *cbd)
-{
-
-    Handle	textOfClip;
-    int		flavor = 0;
-    Size	scrapSize;
-    ScrapFlavorFlags	scrapFlags;
-    ScrapRef    scrap = nil;
-    OSStatus	error;
-    int		type;
-    char	*searchCR;
-    char_u	*tempclip;
-
-
-    error = GetCurrentScrap(&scrap);
-    if (error != noErr)
-	return;
-
-    error = GetScrapFlavorFlags(scrap, VIMSCRAPFLAVOR, &scrapFlags);
-    if (error == noErr)
-    {
-	error = GetScrapFlavorSize(scrap, VIMSCRAPFLAVOR, &scrapSize);
-	if (error == noErr && scrapSize > 1)
-	    flavor = 1;
-    }
-
-    if (flavor == 0)
-    {
-	error = GetScrapFlavorFlags(scrap, SCRAPTEXTFLAVOR, &scrapFlags);
-	if (error != noErr)
-	    return;
-
-	error = GetScrapFlavorSize(scrap, SCRAPTEXTFLAVOR, &scrapSize);
-	if (error != noErr)
-	    return;
-    }
-
-    ReserveMem(scrapSize);
-
-    // In CARBON we don't need a Handle, a pointer is good
-    textOfClip = NewHandle(scrapSize);
-
-    // tempclip = alloc(scrapSize+1);
-    HLock(textOfClip);
-    error = GetScrapFlavorData(scrap,
-	    flavor ? VIMSCRAPFLAVOR : SCRAPTEXTFLAVOR,
-	    &scrapSize, *textOfClip);
-    scrapSize -= flavor;
-
-    if (flavor)
-	type = **textOfClip;
-    else
-	type = MAUTO;
-
-    tempclip = alloc(scrapSize + 1);
-    mch_memmove(tempclip, *textOfClip + flavor, scrapSize);
-    tempclip[scrapSize] = 0;
-
-#ifdef MACOS_CONVERT
-    {
-	// Convert from utf-16 (clipboard)
-	size_t encLen = 0;
-	char_u *to = mac_utf16_to_enc((UniChar *)tempclip, scrapSize, &encLen);
-
-	if (to != NULL)
-	{
-	    scrapSize = encLen;
-	    vim_free(tempclip);
-	    tempclip = to;
-	}
-    }
-#endif
-
-    searchCR = (char *)tempclip;
-    while (searchCR != NULL)
-    {
-	searchCR = strchr(searchCR, '\r');
-	if (searchCR != NULL)
-	    *searchCR = '\n';
-    }
-
-    clip_yank_selection(type, tempclip, scrapSize, cbd);
-
-    vim_free(tempclip);
-    HUnlock(textOfClip);
-
-    DisposeHandle(textOfClip);
-}
-
-    void
-clip_mch_lose_selection(Clipboard_T *cbd)
-{
-    /*
-     * TODO: Really nothing to do?
-     */
-}
-
-    int
-clip_mch_own_selection(Clipboard_T *cbd)
-{
-    return OK;
-}
-
-/*
- * Send the current selection to the clipboard.
- */
-    void
-clip_mch_set_selection(Clipboard_T *cbd)
-{
-    Handle	textOfClip;
-    long	scrapSize;
-    int		type;
-    ScrapRef    scrap;
-
-    char_u	*str = NULL;
-
-    if (!cbd->owned)
-	return;
-
-    clip_get_selection(cbd);
-
-    /*
-     * Once we set the clipboard, lose ownership.  If another application sets
-     * the clipboard, we don't want to think that we still own it.
-     */
-    cbd->owned = FALSE;
-
-    type = clip_convert_selection(&str, (long_u *)&scrapSize, cbd);
-
-#ifdef MACOS_CONVERT
-    size_t utf16_len = 0;
-    UniChar *to = mac_enc_to_utf16(str, scrapSize, &utf16_len);
-    if (to)
-    {
-	scrapSize = utf16_len;
-	vim_free(str);
-	str = (char_u *)to;
-    }
-#endif
-
-    if (type >= 0)
-    {
-	ClearCurrentScrap();
-
-	textOfClip = NewHandle(scrapSize + 1);
-	HLock(textOfClip);
-
-	**textOfClip = type;
-	mch_memmove(*textOfClip + 1, str, scrapSize);
-	GetCurrentScrap(&scrap);
-	PutScrapFlavor(scrap, SCRAPTEXTFLAVOR, kScrapFlavorMaskNone,
-		scrapSize, *textOfClip + 1);
-	PutScrapFlavor(scrap, VIMSCRAPFLAVOR, kScrapFlavorMaskNone,
-		scrapSize + 1, *textOfClip);
-	HUnlock(textOfClip);
-	DisposeHandle(textOfClip);
-    }
-
-    vim_free(str);
-}
-
-    void
-gui_mch_set_text_area_pos(int x, int y, int w, int h)
-{
-    Rect	VimBound;
-
-//  HideWindow(gui.VimWindow);
-    GetWindowBounds(gui.VimWindow, kWindowGlobalPortRgn, &VimBound);
-
-    if (gui.which_scrollbars[SBAR_LEFT])
-	VimBound.left = -gui.scrollbar_width + 1;
-    else
-	VimBound.left = 0;
-
-    SetWindowBounds(gui.VimWindow, kWindowGlobalPortRgn, &VimBound);
-
-    ShowWindow(gui.VimWindow);
-}
-
-/*
- * Menu stuff.
- */
-
-    void
-gui_mch_enable_menu(int flag)
-{
-    /*
-     * Menu is always active.
-     */
-}
-
-    void
-gui_mch_set_menu_pos(int x, int y, int w, int h)
-{
-    /*
-     * The menu is always at the top of the screen.
-     */
-}
-
-/*
- * Add a sub menu to the menu bar.
- */
-    void
-gui_mch_add_menu(vimmenu_T *menu, int idx)
-{
-    /*
-     * TODO: Try to use only menu_id instead of both menu_id and menu_handle.
-     * TODO: use menu->mnemonic and menu->actext
-     * TODO: Try to reuse menu id
-     *       Carbon Help suggest to use only id between 1 and 235
-     */
-    static long	 next_avail_id = 128;
-    long	 menu_after_me = 0; // Default to the end
-    CFStringRef name;
-    short	 index;
-    vimmenu_T	*parent = menu->parent;
-    vimmenu_T	*brother = menu->next;
-
-    // Cannot add a menu if ...
-    if ((parent != NULL && parent->submenu_id == 0))
-	return;
-
-    // menu ID greater than 1024 are reserved for ???
-    if (next_avail_id == 1024)
-	return;
-
-    // My brother could be the PopUp, find my real brother
-    while ((brother != NULL) && (!menu_is_menubar(brother->name)))
-	brother = brother->next;
-
-    //  Find where to insert the menu (for MenuBar)
-    if ((parent == NULL) && (brother != NULL))
-	menu_after_me = brother->submenu_id;
-
-    // If the menu is not part of the menubar (and its submenus), add it 'nowhere'
-    if (!menu_is_menubar(menu->name))
-	menu_after_me = hierMenu;
-
-    // Convert the name
-#ifdef MACOS_CONVERT
-    name = menu_title_removing_mnemonic(menu);
-#else
-    name = C2Pascal_save(menu->dname);
-#endif
-    if (name == NULL)
-	return;
-
-    // Create the menu unless it's the help menu
-    {
-	// Carbon suggest use of
-	// OSStatus CreateNewMenu(MenuID, MenuAttributes, MenuRef *);
-	// OSStatus SetMenuTitle(MenuRef, ConstStr255Param title);
-	menu->submenu_id = next_avail_id;
-	if (CreateNewMenu(menu->submenu_id, 0, (MenuRef *)&menu->submenu_handle) == noErr)
-	    SetMenuTitleWithCFString((MenuRef)menu->submenu_handle, name);
-	next_avail_id++;
-    }
-
-    if (parent == NULL)
-    {
-	// Adding a menu to the menubar, or in the no mans land (for PopUp)
-
-	// TODO: Verify if we could only Insert Menu if really part of the
-	// menubar The Inserted menu are scanned or the Command-key combos
-
-	// Insert the menu
-	InsertMenu(menu->submenu_handle, menu_after_me); // insert before
-#if 1
-	// Vim should normally update it. TODO: verify
-	DrawMenuBar();
-#endif
-    }
-    else
-    {
-	// Adding as a submenu
-
-	index = gui_mac_get_menu_item_index(menu);
-
-	// Call InsertMenuItem followed by SetMenuItemText
-	// to avoid special character recognition by InsertMenuItem
-	InsertMenuItem(parent->submenu_handle, "\p ", idx); // afterItem
-	SetMenuItemTextWithCFString(parent->submenu_handle, idx+1, name);
-	SetItemCmd(parent->submenu_handle, idx+1, 0x1B);
-	SetItemMark(parent->submenu_handle, idx+1, menu->submenu_id);
-	InsertMenu(menu->submenu_handle, hierMenu);
-    }
-
-    CFRelease(name);
-
-#if 0
-    // Done by Vim later on
-    DrawMenuBar();
-#endif
-}
-
-/*
- * Add a menu item to a menu
- */
-    void
-gui_mch_add_menu_item(vimmenu_T *menu, int idx)
-{
-    CFStringRef name;
-    vimmenu_T	*parent = menu->parent;
-    int		menu_inserted;
-
-    // Cannot add item, if the menu have not been created
-    if (parent->submenu_id == 0)
-	return;
-
-    // Could call SetMenuRefCon [CARBON] to associate with the Menu,
-    // for older OS call GetMenuItemData (menu, item, isCommandID?, data)
-
-    // Convert the name
-#ifdef MACOS_CONVERT
-    name = menu_title_removing_mnemonic(menu);
-#else
-    name = C2Pascal_save(menu->dname);
-#endif
-
-    // Where are just a menu item, so no handle, no id
-    menu->submenu_id = 0;
-    menu->submenu_handle = NULL;
-
-    menu_inserted = 0;
-    if (menu->actext)
-    {
-	// If the accelerator text for the menu item looks like it describes
-	// a command key (e.g., "<D-S-t>" or "<C-7>"), display it as the
-	// item's command equivalent.
-	int	    key = 0;
-	int	    modifiers = 0;
-	char_u	    *p_actext;
-
-	p_actext = menu->actext;
-	key = find_special_key(&p_actext, &modifiers, FSK_SIMPLIFY, NULL);
-	if (*p_actext != 0)
-	    key = 0; // error: trailing text
-	// find_special_key() returns a keycode with as many of the
-	// specified modifiers as appropriate already applied (e.g., for
-	// "<D-C-x>" it returns Ctrl-X as the keycode and MOD_MASK_CMD
-	// as the only modifier).  Since we want to display all of the
-	// modifiers, we need to convert the keycode back to a printable
-	// character plus modifiers.
-	// TODO: Write an alternative find_special_key() that doesn't
-	// apply modifiers.
-	if (key > 0 && key < 32)
-	{
-	    // Convert a control key to an uppercase letter.  Note that
-	    // by this point it is no longer possible to distinguish
-	    // between, e.g., Ctrl-S and Ctrl-Shift-S.
-	    modifiers |= MOD_MASK_CTRL;
-	    key += '@';
-	}
-	// If the keycode is an uppercase letter, set the Shift modifier.
-	// If it is a lowercase letter, don't set the modifier, but convert
-	// the letter to uppercase for display in the menu.
-	else if (key >= 'A' && key <= 'Z')
-	    modifiers |= MOD_MASK_SHIFT;
-	else if (key >= 'a' && key <= 'z')
-	    key += 'A' - 'a';
-	// Note: keycodes below 0x22 are reserved by Apple.
-	if (key >= 0x22 && vim_isprintc_strict(key))
-	{
-	    int		valid = 1;
-	    char_u      mac_mods = kMenuNoModifiers;
-	    // Convert Vim modifier codes to Menu Manager equivalents.
-	    if (modifiers & MOD_MASK_SHIFT)
-		mac_mods |= kMenuShiftModifier;
-	    if (modifiers & MOD_MASK_CTRL)
-		mac_mods |= kMenuControlModifier;
-	    if (!(modifiers & MOD_MASK_CMD))
-		mac_mods |= kMenuNoCommandModifier;
-	    if (modifiers & MOD_MASK_ALT || modifiers & MOD_MASK_MULTI_CLICK)
-		valid = 0; // TODO: will Alt someday map to Option?
-	    if (valid)
-	    {
-		char_u	    item_txt[10];
-		// Insert the menu item after idx, with its command key.
-		item_txt[0] = 3; item_txt[1] = ' '; item_txt[2] = '/';
-		item_txt[3] = key;
-		InsertMenuItem(parent->submenu_handle, item_txt, idx);
-		// Set the modifier keys.
-		SetMenuItemModifiers(parent->submenu_handle, idx+1, mac_mods);
-		menu_inserted = 1;
-	    }
-	}
-    }
-    // Call InsertMenuItem followed by SetMenuItemText
-    // to avoid special character recognition by InsertMenuItem
-    if (!menu_inserted)
-	InsertMenuItem(parent->submenu_handle, "\p ", idx); // afterItem
-    // Set the menu item name.
-    SetMenuItemTextWithCFString(parent->submenu_handle, idx+1, name);
-
-#if 0
-    // Called by Vim
-    DrawMenuBar();
-#endif
-
-    CFRelease(name);
-}
-
-    void
-gui_mch_toggle_tearoffs(int enable)
-{
-    // no tearoff menus
-}
-
-/*
- * Destroy the machine specific menu widget.
- */
-    void
-gui_mch_destroy_menu(vimmenu_T *menu)
-{
-    short	index = gui_mac_get_menu_item_index(menu);
-
-    if (index > 0)
-    {
-      if (menu->parent)
-      {
-	{
-	    // For now just don't delete help menu items. (Huh? Dany)
-	    DeleteMenuItem(menu->parent->submenu_handle, index);
-
-	    // Delete the Menu if it was a hierarchical Menu
-	    if (menu->submenu_id != 0)
-	    {
-		DeleteMenu(menu->submenu_id);
-		DisposeMenu(menu->submenu_handle);
-	    }
-	}
-      }
-#ifdef DEBUG_MAC_MENU
-      else
-      {
-	printf("gmdm 2\n");
-      }
-#endif
-    }
-    else
-    {
-	{
-	    DeleteMenu(menu->submenu_id);
-	    DisposeMenu(menu->submenu_handle);
-	}
-    }
-    // Shouldn't this be already done by Vim. TODO: Check
-    DrawMenuBar();
-}
-
-/*
- * Make a menu either grey or not grey.
- */
-    void
-gui_mch_menu_grey(vimmenu_T *menu, int grey)
-{
-    // TODO: Check if menu really exists
-    short index = gui_mac_get_menu_item_index(menu);
-/*
-    index = menu->index;
-*/
-    if (grey)
-    {
-	if (menu->children)
-	    DisableMenuItem(menu->submenu_handle, index);
-	if (menu->parent)
-	  if (menu->parent->submenu_handle)
-	    DisableMenuItem(menu->parent->submenu_handle, index);
-    }
-    else
-    {
-	if (menu->children)
-	    EnableMenuItem(menu->submenu_handle, index);
-	if (menu->parent)
-	  if (menu->parent->submenu_handle)
-	    EnableMenuItem(menu->parent->submenu_handle, index);
-    }
-}
-
-/*
- * Make menu item hidden or not hidden
- */
-    void
-gui_mch_menu_hidden(vimmenu_T *menu, int hidden)
-{
-    // There's no hidden mode on MacOS
-    gui_mch_menu_grey(menu, hidden);
-}
-
-
-/*
- * This is called after setting all the menus to grey/hidden or not.
- */
-    void
-gui_mch_draw_menubar(void)
-{
-    DrawMenuBar();
-}
-
-
-/*
- * Scrollbar stuff.
- */
-
-    void
-gui_mch_enable_scrollbar(
-	scrollbar_T	*sb,
-	int		flag)
-{
-    if (flag)
-	ShowControl(sb->id);
-    else
-	HideControl(sb->id);
-
-#ifdef DEBUG_MAC_SB
-    printf("enb_sb (%x) %x\n",sb->id, flag);
-#endif
-}
-
-    void
-gui_mch_set_scrollbar_thumb(
-	scrollbar_T *sb,
-	long val,
-	long size,
-	long max)
-{
-    SetControl32BitMaximum (sb->id, max);
-    SetControl32BitMinimum (sb->id, 0);
-    SetControl32BitValue   (sb->id, val);
-    SetControlViewSize     (sb->id, size);
-#ifdef DEBUG_MAC_SB
-    printf("thumb_sb (%x) %lx, %lx,%lx\n",sb->id, val, size, max);
-#endif
-}
-
-    void
-gui_mch_set_scrollbar_pos(
-	scrollbar_T *sb,
-	int x,
-	int y,
-	int w,
-	int h)
-{
-    gui_mch_set_bg_color(gui.back_pixel);
-#if 0
-  if (gui.which_scrollbars[SBAR_LEFT])
-    {
-	MoveControl(sb->id, x-16, y);
-	SizeControl(sb->id, w + 1, h);
-    }
-    else
-    {
-	MoveControl(sb->id, x, y);
-	SizeControl(sb->id, w + 1, h);
-    }
-#endif
-    if (sb == &gui.bottom_sbar)
-	h += 1;
-    else
-	w += 1;
-
-    if (gui.which_scrollbars[SBAR_LEFT])
-	x -= 15;
-
-    MoveControl(sb->id, x, y);
-    SizeControl(sb->id, w, h);
-#ifdef DEBUG_MAC_SB
-    printf("size_sb (%x) %x, %x, %x, %x\n",sb->id, x, y, w, h);
-#endif
-}
-
-    int
-gui_mch_get_scrollbar_xpadding(void)
-{
-    // TODO: Calculate the padding for adjust scrollbar position when the
-    // Window is maximized.
-    return 0;
-}
-
-    int
-gui_mch_get_scrollbar_ypadding(void)
-{
-    // TODO: Calculate the padding for adjust scrollbar position when the
-    // Window is maximized.
-    return 0;
-}
-
-    void
-gui_mch_create_scrollbar(
-	scrollbar_T *sb,
-	int orient)	// SBAR_VERT or SBAR_HORIZ
-{
-    Rect bounds;
-
-    bounds.top = -16;
-    bounds.bottom = -10;
-    bounds.right = -10;
-    bounds.left = -16;
-
-    sb->id = NewControl(gui.VimWindow,
-			 &bounds,
-			 "\pScrollBar",
-			 TRUE,
-			 0, // current
-			 0, // top
-			 0, // bottom
-			 kControlScrollBarLiveProc,
-			 (long) sb->ident);
-#ifdef DEBUG_MAC_SB
-    printf("create_sb (%x) %x\n",sb->id, orient);
-#endif
-}
-
-    void
-gui_mch_destroy_scrollbar(scrollbar_T *sb)
-{
-    gui_mch_set_bg_color(gui.back_pixel);
-    DisposeControl(sb->id);
-#ifdef DEBUG_MAC_SB
-    printf("dest_sb (%x) \n",sb->id);
-#endif
-}
-
-    int
-gui_mch_is_blinking(void)
-{
-    return FALSE;
-}
-
-    int
-gui_mch_is_blink_off(void)
-{
-    return FALSE;
-}
-
-/*
- * Cursor blink functions.
- *
- * This is a simple state machine:
- * BLINK_NONE	not blinking at all
- * BLINK_OFF	blinking, cursor is not shown
- * BLINK_ON blinking, cursor is shown
- */
-    void
-gui_mch_set_blinking(long wait, long on, long off)
-{
-#if 0
-    // TODO: TODO: TODO: TODO:
-    blink_waittime = wait;
-    blink_ontime = on;
-    blink_offtime = off;
-#endif
-}
-
-/*
- * Stop the cursor blinking.  Show the cursor if it wasn't shown.
- */
-    void
-gui_mch_stop_blink(int may_call_gui_update_cursor)
-{
-    if (may_call_gui_update_cursor)
-	gui_update_cursor(TRUE, FALSE);
-#if 0
-    // TODO: TODO: TODO: TODO:
-    gui_w32_rm_blink_timer();
-    if (blink_state == BLINK_OFF)
-    gui_update_cursor(TRUE, FALSE);
-    blink_state = BLINK_NONE;
-#endif
-}
-
-/*
- * Start the cursor blinking.  If it was already blinking, this restarts the
- * waiting time and shows the cursor.
- */
-    void
-gui_mch_start_blink(void)
-{
-    gui_update_cursor(TRUE, FALSE);
-    // TODO: TODO: TODO: TODO:
-//    gui_w32_rm_blink_timer();
-
-    // Only switch blinking on if none of the times is zero
-#if 0
-    if (blink_waittime && blink_ontime && blink_offtime)
-    {
-    blink_timer = SetTimer(NULL, 0, (UINT)blink_waittime,
-			    (TIMERPROC)_OnBlinkTimer);
-    blink_state = BLINK_ON;
-    gui_update_cursor(TRUE, FALSE);
-    }
-#endif
-}
-
-/*
- * Return the RGB value of a pixel as long.
- */
-    guicolor_T
-gui_mch_get_rgb(guicolor_T pixel)
-{
-    return (guicolor_T)((Red(pixel) << 16) + (Green(pixel) << 8) + Blue(pixel));
-}
-
-
-
-#ifdef FEAT_BROWSE
-/*
- * Pop open a file browser and return the file selected, in allocated memory,
- * or NULL if Cancel is hit.
- *  saving  - TRUE if the file will be saved to, FALSE if it will be opened.
- *  title   - Title message for the file browser dialog.
- *  dflt    - Default name of file.
- *  ext     - Default extension to be added to files without extensions.
- *  initdir - directory in which to open the browser (NULL = current dir)
- *  filter  - Filter for matched files to choose from.
- *  Has a format like this:
- *  "C Files (*.c)\0*.c\0"
- *  "All Files\0*.*\0\0"
- *  If these two strings were concatenated, then a choice of two file
- *  filters will be selectable to the user.  Then only matching files will
- *  be shown in the browser.  If NULL, the default allows all files.
- *
- *  *NOTE* - the filter string must be terminated with TWO nulls.
- */
-    char_u *
-gui_mch_browse(
-    int saving,
-    char_u *title,
-    char_u *dflt,
-    char_u *ext,
-    char_u *initdir,
-    char_u *filter)
-{
-    // TODO: Add Ammon's safety check (Dany)
-    NavReplyRecord	reply;
-    char_u		*fname = NULL;
-    char_u		**fnames = NULL;
-    long		numFiles;
-    NavDialogOptions	navOptions;
-    OSErr		error;
-
-    // Get Navigation Service Defaults value
-    NavGetDefaultDialogOptions(&navOptions);
-
-
-    // TODO: If we get a :browse args, set the Multiple bit.
-    navOptions.dialogOptionFlags =  kNavAllowInvisibleFiles
-				 |  kNavDontAutoTranslate
-				 |  kNavDontAddTranslateItems
-			    //	 |  kNavAllowMultipleFiles
-				 |  kNavAllowStationery;
-
-    (void) C2PascalString(title,   &navOptions.message);
-    (void) C2PascalString(dflt,    &navOptions.savedFileName);
-    // Could set clientName?
-    //		 windowTitle? (there's no title bar?)
-
-    if (saving)
-    {
-	// Change first parm AEDesc (typeFSS) *defaultLocation to match dflt
-	NavPutFile(NULL, &reply, &navOptions, NULL, 'TEXT', 'VIM!', NULL);
-	if (!reply.validRecord)
-	    return NULL;
-    }
-    else
-    {
-	// Change first parm AEDesc (typeFSS) *defaultLocation to match dflt
-	NavGetFile(NULL, &reply, &navOptions, NULL, NULL, NULL, NULL, NULL);
-	if (!reply.validRecord)
-	    return NULL;
-    }
-
-    fnames = new_fnames_from_AEDesc(&reply.selection, &numFiles, &error);
-
-    NavDisposeReply(&reply);
-
-    if (fnames)
-    {
-	fname = fnames[0];
-	vim_free(fnames);
-    }
-
-    // TODO: Shorten the file name if possible
-    return fname;
-}
-#endif // FEAT_BROWSE
-
-#ifdef FEAT_GUI_DIALOG
-/*
- * Stuff for dialogues
- */
-
-/*
- * Create a dialogue dynamically from the parameter strings.
- * type       = type of dialogue (question, alert, etc.)
- * title      = dialogue title. may be NULL for default title.
- * message    = text to display. Dialogue sizes to accommodate it.
- * buttons    = '\n' separated list of button captions, default first.
- * dfltbutton = number of default button.
- *
- * This routine returns 1 if the first button is pressed,
- *	    2 for the second, etc.
- *
- *	    0 indicates Esc was pressed.
- *	    -1 for unexpected error
- *
- * If stubbing out this fn, return 1.
- */
-
-typedef struct
-{
-    short   idx;
-    short   width;	// Size of the text in pixel
-    Rect    box;
-} vgmDlgItm; // Vim Gui_Mac.c Dialog Item
-
-#define MoveRectTo(r,x,y) OffsetRect(r,x-r->left,y-r->top)
-
-    static void
-macMoveDialogItem(
-    DialogRef	theDialog,
-    short	itemNumber,
-    short	X,
-    short	Y,
-    Rect	*inBox)
-{
-#if 0 // USE_CARBONIZED
-    // Untested
-    MoveDialogItem(theDialog, itemNumber, X, Y);
-    if (inBox != nil)
-	GetDialogItem(theDialog, itemNumber, &itemType, &itemHandle, inBox);
-#else
-    short	itemType;
-    Handle	itemHandle;
-    Rect	localBox;
-    Rect	*itemBox = &localBox;
-
-    if (inBox != nil)
-	itemBox = inBox;
-
-    GetDialogItem(theDialog, itemNumber, &itemType, &itemHandle, itemBox);
-    OffsetRect(itemBox, -itemBox->left, -itemBox->top);
-    OffsetRect(itemBox, X, Y);
-    // To move a control (like a button) we need to call both
-    // MoveControl and SetDialogItem. FAQ 6-18
-    if (1) //(itemType & kControlDialogItem)
-	MoveControl((ControlRef) itemHandle, X, Y);
-    SetDialogItem(theDialog, itemNumber, itemType, itemHandle, itemBox);
-#endif
-}
-
-    static void
-macSizeDialogItem(
-    DialogRef	theDialog,
-    short	itemNumber,
-    short	width,
-    short	height)
-{
-    short	itemType;
-    Handle	itemHandle;
-    Rect	itemBox;
-
-    GetDialogItem(theDialog, itemNumber, &itemType, &itemHandle, &itemBox);
-
-    // When width or height is zero do not change it
-    if (width  == 0)
-	width  = itemBox.right  - itemBox.left;
-    if (height == 0)
-	height = itemBox.bottom - itemBox.top;
-
-#if 0 // USE_CARBONIZED
-    SizeDialogItem(theDialog, itemNumber, width, height); // Untested
-#else
-    // Resize the bounding box
-    itemBox.right  = itemBox.left + width;
-    itemBox.bottom = itemBox.top  + height;
-
-    // To resize a control (like a button) we need to call both
-    // SizeControl and SetDialogItem. (deducted from FAQ 6-18)
-    if (itemType & kControlDialogItem)
-	SizeControl((ControlRef) itemHandle, width, height);
-
-    // Configure back the item
-    SetDialogItem(theDialog, itemNumber, itemType, itemHandle, &itemBox);
-#endif
-}
-
-    static void
-macSetDialogItemText(
-    DialogRef	theDialog,
-    short	itemNumber,
-    Str255	itemName)
-{
-    short	itemType;
-    Handle	itemHandle;
-    Rect	itemBox;
-
-    GetDialogItem(theDialog, itemNumber, &itemType, &itemHandle, &itemBox);
-
-    if (itemType & kControlDialogItem)
-	SetControlTitle((ControlRef) itemHandle, itemName);
-    else
-	SetDialogItemText(itemHandle, itemName);
-}
-
-
-/*
- * ModalDialog() handler for message dialogs that have hotkey accelerators.
- * Expects a mapping of hotkey char to control index in gDialogHotKeys;
- * setting gDialogHotKeys to NULL disables any hotkey handling.
- */
-    static pascal Boolean
-DialogHotkeyFilterProc (
-    DialogRef	    theDialog,
-    EventRecord	    *event,
-    DialogItemIndex *itemHit)
-{
-    char_u keyHit;
-
-    if (event->what == keyDown || event->what == autoKey)
-    {
-	keyHit = (event->message & charCodeMask);
-
-	if (gDialogHotKeys && gDialogHotKeys[keyHit])
-	{
-#ifdef DEBUG_MAC_DIALOG_HOTKEYS
-	    printf("user pressed hotkey '%c' --> item %d\n", keyHit, gDialogHotKeys[keyHit]);
-#endif
-	    *itemHit = gDialogHotKeys[keyHit];
-
-	    // When handing off to StdFilterProc, pretend that the user
-	    // clicked the control manually. Note that this is also supposed
-	    // to cause the button to hilite briefly (to give some user
-	    // feedback), but this seems not to actually work (or it's too
-	    // fast to be seen).
-	    event->what = kEventControlSimulateHit;
-
-	    return true; // we took care of it
-	}
-
-	// Defer to the OS's standard behavior for this event.
-	// This ensures that Enter will still activate the default button.
-	return StdFilterProc(theDialog, event, itemHit);
-    }
-    return false;      // Let ModalDialog deal with it
-}
-
-
-/*
- * TODO: There have been some crashes with dialogs, check your inbox
- * (Jussi)
- */
-    int
-gui_mch_dialog(
-    int		type,
-    char_u	*title,
-    char_u	*message,
-    char_u	*buttons,
-    int		dfltbutton,
-    char_u	*textfield,
-    int		ex_cmd)
-{
-    Handle	buttonDITL;
-    Handle	iconDITL;
-    Handle	inputDITL;
-    Handle	messageDITL;
-    Handle	itemHandle;
-    Handle	iconHandle;
-    DialogPtr	theDialog;
-    char_u	len;
-    char_u	PascalTitle[256];	// place holder for the title
-    char_u	name[256];
-    GrafPtr	oldPort;
-    short	itemHit;
-    char_u	*buttonChar;
-    short	hotKeys[256];		// map of hotkey -> control ID
-    char_u	aHotKey;
-    Rect	box;
-    short	button;
-    short	lastButton;
-    short	itemType;
-    short	useIcon;
-    short	width;
-    short	totalButtonWidth = 0;   // the width of all buttons together
-					// including spacing
-    short	widestButton = 0;
-    short	dfltButtonEdge     = 20;  // gut feeling
-    short	dfltElementSpacing = 13;  // from IM:V.2-29
-    short       dfltIconSideSpace  = 23;  // from IM:V.2-29
-    short	maximumWidth       = 400; // gut feeling
-    short	maxButtonWidth	   = 175; // gut feeling
-
-    short	vertical;
-    short	dialogHeight;
-    short	messageLines = 3;
-    FontInfo	textFontInfo;
-
-    vgmDlgItm   iconItm;
-    vgmDlgItm   messageItm;
-    vgmDlgItm   inputItm;
-    vgmDlgItm   buttonItm;
-
-    WindowRef	theWindow;
-
-    ModalFilterUPP dialogUPP;
-
-    // Check 'v' flag in 'guioptions': vertical button placement.
-    vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL);
-
-    // Create a new Dialog Box from template.
-    theDialog = GetNewDialog(129, nil, (WindowRef) -1);
-
-    // Get the WindowRef
-    theWindow = GetDialogWindow(theDialog);
-
-    // Hide the window.
-    // 1. to avoid seeing slow drawing
-    // 2. to prevent a problem seen while moving dialog item
-    //    within a visible window. (non-Carbon MacOS 9)
-    // Could be avoided by changing the resource.
-    HideWindow(theWindow);
-
-    // Change the graphical port to the dialog,
-    // so we can measure the text with the proper font
-    GetPort(&oldPort);
-    SetPortDialogPort(theDialog);
-
-    // Get the info about the default text,
-    // used to calculate the height of the message
-    // and of the  text field
-    GetFontInfo(&textFontInfo);
-
-    //	Set the dialog title
-    if (title != NULL)
-    {
-	(void) C2PascalString(title, &PascalTitle);
-	SetWTitle(theWindow, PascalTitle);
-    }
-
-    // Creates the buttons and add them to the Dialog Box.
-    buttonDITL = GetResource('DITL', 130);
-    buttonChar = buttons;
-    button = 0;
-
-    // initialize the hotkey mapping
-    CLEAR_FIELD(hotKeys);
-
-    for (;*buttonChar != 0;)
-    {
-	// Get the name of the button
-	button++;
-	len = 0;
-	for (;((*buttonChar != DLG_BUTTON_SEP) && (*buttonChar != 0) && (len < 255)); buttonChar++)
-	{
-	    if (*buttonChar != DLG_HOTKEY_CHAR)
-		name[++len] = *buttonChar;
-	    else
-	    {
-		aHotKey = (char_u)*(buttonChar+1);
-		if (aHotKey >= 'A' && aHotKey <= 'Z')
-		    aHotKey = (char_u)((int)aHotKey + (int)'a' - (int)'A');
-		hotKeys[aHotKey] = button;
-#ifdef DEBUG_MAC_DIALOG_HOTKEYS
-		printf("### hotKey for button %d is '%c'\n", button, aHotKey);
-#endif
-	    }
-	}
-
-	if (*buttonChar != 0)
-	  buttonChar++;
-	name[0] = len;
-
-	// Add the button
-	AppendDITL(theDialog, buttonDITL, overlayDITL); // appendDITLRight);
-
-	// Change the button's name
-	macSetDialogItemText(theDialog, button, name);
-
-	// Resize the button to fit its name
-	width = StringWidth(name) + 2 * dfltButtonEdge;
-	// Limit the size of any button to an acceptable value.
-	// TODO: Should be based on the message width
-	if (width > maxButtonWidth)
-	    width = maxButtonWidth;
-	macSizeDialogItem(theDialog, button, width, 0);
-
-	totalButtonWidth += width;
-
-	if (width > widestButton)
-	    widestButton = width;
-    }
-    ReleaseResource(buttonDITL);
-    lastButton = button;
-
-    // Add the icon to the Dialog Box.
-    iconItm.idx = lastButton + 1;
-    iconDITL = GetResource('DITL', 131);
-    switch (type)
-    {
-	case VIM_GENERIC:
-	case VIM_INFO:
-	case VIM_QUESTION: useIcon = kNoteIcon; break;
-	case VIM_WARNING:  useIcon = kCautionIcon; break;
-	case VIM_ERROR:    useIcon = kStopIcon; break;
-	default:	   useIcon = kStopIcon;
-    }
-    AppendDITL(theDialog, iconDITL, overlayDITL);
-    ReleaseResource(iconDITL);
-    GetDialogItem(theDialog, iconItm.idx, &itemType, &itemHandle, &box);
-    // TODO: Should the item be freed?
-    iconHandle = GetIcon(useIcon);
-    SetDialogItem(theDialog, iconItm.idx, itemType, iconHandle, &box);
-
-    // Add the message to the Dialog box.
-    messageItm.idx = lastButton + 2;
-    messageDITL = GetResource('DITL', 132);
-    AppendDITL(theDialog, messageDITL, overlayDITL);
-    ReleaseResource(messageDITL);
-    GetDialogItem(theDialog, messageItm.idx, &itemType, &itemHandle, &box);
-    (void) C2PascalString(message, &name);
-    SetDialogItemText(itemHandle, name);
-    messageItm.width = StringWidth(name);
-
-    // Add the input box if needed
-    if (textfield != NULL)
-    {
-	// Cheat for now reuse the message and convert to text edit
-	inputItm.idx = lastButton + 3;
-	inputDITL = GetResource('DITL', 132);
-	AppendDITL(theDialog, inputDITL, overlayDITL);
-	ReleaseResource(inputDITL);
-	GetDialogItem(theDialog, inputItm.idx, &itemType, &itemHandle, &box);
-//	  SetDialogItem(theDialog, inputItm.idx, kEditTextDialogItem, itemHandle, &box);
-	(void) C2PascalString(textfield, &name);
-	SetDialogItemText(itemHandle, name);
-	inputItm.width = StringWidth(name);
-
-	// Hotkeys don't make sense if there's a text field
-	gDialogHotKeys = NULL;
-    }
-    else
-	// Install hotkey table
-	gDialogHotKeys = (short *)&hotKeys;
-
-    // Set the <ENTER> and <ESC> button.
-    SetDialogDefaultItem(theDialog, dfltbutton);
-    SetDialogCancelItem(theDialog, 0);
-
-    // Reposition element
-
-    // Check if we need to force vertical
-    if (totalButtonWidth > maximumWidth)
-	vertical = TRUE;
-
-    // Place icon
-    macMoveDialogItem(theDialog, iconItm.idx, dfltIconSideSpace, dfltElementSpacing, &box);
-    iconItm.box.right = box.right;
-    iconItm.box.bottom = box.bottom;
-
-    // Place Message
-    messageItm.box.left = iconItm.box.right + dfltIconSideSpace;
-    macSizeDialogItem(theDialog, messageItm.idx, 0,  messageLines * (textFontInfo.ascent + textFontInfo.descent));
-    macMoveDialogItem(theDialog, messageItm.idx, messageItm.box.left, dfltElementSpacing, &messageItm.box);
-
-    // Place Input
-    if (textfield != NULL)
-    {
-	inputItm.box.left = messageItm.box.left;
-	inputItm.box.top  = messageItm.box.bottom + dfltElementSpacing;
-	macSizeDialogItem(theDialog, inputItm.idx, 0, textFontInfo.ascent + textFontInfo.descent);
-	macMoveDialogItem(theDialog, inputItm.idx, inputItm.box.left, inputItm.box.top, &inputItm.box);
-	// Convert the static text into a text edit.
-	// For some reason this change need to be done last (Dany)
-	GetDialogItem(theDialog, inputItm.idx, &itemType, &itemHandle, &inputItm.box);
-	SetDialogItem(theDialog, inputItm.idx, kEditTextDialogItem, itemHandle, &inputItm.box);
-	SelectDialogItemText(theDialog, inputItm.idx, 0, 32767);
-    }
-
-    // Place Button
-    if (textfield != NULL)
-    {
-	buttonItm.box.left = inputItm.box.left;
-	buttonItm.box.top  = inputItm.box.bottom + dfltElementSpacing;
-    }
-    else
-    {
-	buttonItm.box.left = messageItm.box.left;
-	buttonItm.box.top  = messageItm.box.bottom + dfltElementSpacing;
-    }
-
-    for (button=1; button <= lastButton; button++)
-    {
-
-	macMoveDialogItem(theDialog, button, buttonItm.box.left, buttonItm.box.top, &box);
-	// With vertical, it's better to have all buttons the same length
-	if (vertical)
-	{
-	    macSizeDialogItem(theDialog, button, widestButton, 0);
-	    GetDialogItem(theDialog, button, &itemType, &itemHandle, &box);
-	}
-	// Calculate position of next button
-	if (vertical)
-	    buttonItm.box.top  = box.bottom + dfltElementSpacing;
-	else
-	    buttonItm.box.left  = box.right + dfltElementSpacing;
-    }
-
-    // Resize the dialog box
-    dialogHeight = box.bottom + dfltElementSpacing;
-    SizeWindow(theWindow, maximumWidth, dialogHeight, TRUE);
-
-    // Magic resize
-    AutoSizeDialog(theDialog);
-    // Need a horizontal resize anyway so not that useful
-
-    // Display it
-    ShowWindow(theWindow);
-//  BringToFront(theWindow);
-    SelectWindow(theWindow);
-
-//  DrawDialog(theDialog);
-#if 0
-    GetPort(&oldPort);
-    SetPortDialogPort(theDialog);
-#endif
-
-#ifdef USE_CARBONKEYHANDLER
-    // Avoid that we use key events for the main window.
-    dialog_busy = TRUE;
-#endif
-
-    // Prepare the shortcut-handling filterProc for handing to the dialog
-    dialogUPP = NewModalFilterUPP(DialogHotkeyFilterProc);
-
-    // Hang until one of the button is hit
-    do
-	ModalDialog(dialogUPP, &itemHit);
-    while ((itemHit < 1) || (itemHit > lastButton));
-
-#ifdef USE_CARBONKEYHANDLER
-    dialog_busy = FALSE;
-#endif
-
-    // Copy back the text entered by the user into the param
-    if (textfield != NULL)
-    {
-	GetDialogItem(theDialog, inputItm.idx, &itemType, &itemHandle, &box);
-	GetDialogItemText(itemHandle, (char_u *) &name);
-#if IOSIZE < 256
-	// Truncate the name to IOSIZE if needed
-	if (name[0] > IOSIZE)
-	    name[0] = IOSIZE - 1;
-#endif
-	vim_strncpy(textfield, &name[1], name[0]);
-    }
-
-    // Restore the original graphical port
-    SetPort(oldPort);
-
-    // Free the modal filterProc
-    DisposeRoutineDescriptor(dialogUPP);
-
-    // Get ride of the dialog (free memory)
-    DisposeDialog(theDialog);
-
-    return itemHit;
-/*
- * Useful thing which could be used
- * SetDialogTimeout(): Auto click a button after timeout
- * SetDialogTracksCursor() : Get the I-beam cursor over input box
- * MoveDialogItem():	    Probably better than SetDialogItem
- * SizeDialogItem():		(but is it Carbon Only?)
- * AutoSizeDialog():	    Magic resize of dialog based on text length
- */
-}
-#endif // FEAT_DIALOG_GUI
-
-/*
- * Display the saved error message(s).
- */
-#ifdef USE_MCH_ERRMSG
-    void
-display_errors(void)
-{
-    char	*p;
-    char_u	pError[256];
-
-    if (error_ga.ga_data == NULL)
-	return;
-
-    // avoid putting up a message box with blanks only
-    for (p = (char *)error_ga.ga_data; *p; ++p)
-	if (!isspace(*p))
-	{
-	    if (STRLEN(p) > 255)
-		pError[0] = 255;
-	    else
-		pError[0] = STRLEN(p);
-
-	    STRNCPY(&pError[1], p, pError[0]);
-	    ParamText(pError, nil, nil, nil);
-	    Alert(128, nil);
-	    break;
-	    // TODO: handled message longer than 256 chars
-	    //	 use auto-sizeable alert
-	    //	 or dialog with scrollbars (TextEdit zone)
-	}
-    ga_clear(&error_ga);
-}
-#endif
-
-/*
- * Get current mouse coordinates in text window.
- */
-    void
-gui_mch_getmouse(int *x, int *y)
-{
-    Point where;
-
-    GetMouse(&where);
-
-    *x = where.h;
-    *y = where.v;
-}
-
-    void
-gui_mch_setmouse(int x, int y)
-{
-    // TODO
-#if 0
-    // From FAQ 3-11
-
-    CursorDevicePtr myMouse;
-    Point	    where;
-
-    if (   NGetTrapAddress(_CursorDeviceDispatch, ToolTrap)
-	!= NGetTrapAddress(_Unimplemented,   ToolTrap))
-    {
-	// New way
-
-	/*
-	 * Get first device with one button.
-	 * This will probably be the standard mouse
-	 * start at head of cursor dev list
-	 *
-	 */
-
-	myMouse = nil;
-
-	do
-	{
-	    // Get the next cursor device
-	    CursorDeviceNextDevice(&myMouse);
-	}
-	while ((myMouse != nil) && (myMouse->cntButtons != 1));
-
-	CursorDeviceMoveTo(myMouse, x, y);
-    }
-    else
-    {
-	// Old way
-	where.h = x;
-	where.v = y;
-
-	*(Point *)RawMouse = where;
-	*(Point *)MTemp    = where;
-	*(Ptr)    CrsrNew  = 0xFFFF;
-    }
-#endif
-}
-
-    void
-gui_mch_show_popupmenu(vimmenu_T *menu)
-{
-/*
- *  Clone PopUp to use menu
- *  Create a object descriptor for the current selection
- *  Call the procedure
- */
-
-    MenuHandle	CntxMenu;
-    Point	where;
-    OSStatus	status;
-    UInt32	CntxType;
-    SInt16	CntxMenuID;
-    UInt16	CntxMenuItem;
-    Str255	HelpName = "";
-    GrafPtr	savePort;
-
-    // Save Current Port: On MacOS X we seem to lose the port
-    GetPort(&savePort); //OSX
-
-    GetMouse(&where);
-    LocalToGlobal(&where); //OSX
-    CntxMenu = menu->submenu_handle;
-
-    // TODO: Get the text selection from Vim
-
-    // Call to Handle Popup
-    status = ContextualMenuSelect(CntxMenu, where, false, kCMHelpItemRemoveHelp,
-		       HelpName, NULL, &CntxType, &CntxMenuID, &CntxMenuItem);
-
-    if (status == noErr)
-    {
-	if (CntxType == kCMMenuItemSelected)
-	{
-	    // Handle the menu CntxMenuID, CntxMenuItem
-	    // The submenu can be handle directly by gui_mac_handle_menu
-	    // But what about the current menu, is the menu changed by
-	    // ContextualMenuSelect
-	    gui_mac_handle_menu((CntxMenuID << 16) + CntxMenuItem);
-	}
-	else if (CntxMenuID == kCMShowHelpSelected)
-	{
-	    // Should come up with the help
-	}
-    }
-
-    // Restore original Port
-    SetPort(savePort); //OSX
-}
-
-#if defined(FEAT_CW_EDITOR) || defined(PROTO)
-// TODO: Is it need for MACOS_X? (Dany)
-    void
-mch_post_buffer_write(buf_T *buf)
-{
-    GetFSSpecFromPath(buf->b_ffname, &buf->b_FSSpec);
-    Send_KAHL_MOD_AE(buf);
-}
-#endif
-
-#ifdef FEAT_TITLE
-/*
- * Set the window title and icon.
- * (The icon is not taken care of).
- */
-    void
-gui_mch_settitle(char_u *title, char_u *icon)
-{
-    // TODO: Get vim to make sure maxlen (from p_titlelen) is smaller
-    //       that 256. Even better get it to fit nicely in the titlebar.
-#ifdef MACOS_CONVERT
-    CFStringRef windowTitle;
-    size_t	windowTitleLen;
-#else
-    char_u   *pascalTitle;
-#endif
-
-    if (title == NULL)		// nothing to do
-	return;
-
-#ifdef MACOS_CONVERT
-    windowTitleLen = STRLEN(title);
-    windowTitle  = (CFStringRef)mac_enc_to_cfstring(title, windowTitleLen);
-
-    if (windowTitle)
-    {
-	SetWindowTitleWithCFString(gui.VimWindow, windowTitle);
-	CFRelease(windowTitle);
-    }
-#else
-    pascalTitle = C2Pascal_save(title);
-    if (pascalTitle != NULL)
-    {
-	SetWTitle(gui.VimWindow, pascalTitle);
-	vim_free(pascalTitle);
-    }
-#endif
-}
-#endif
-
-/*
- * Transferred from os_mac.c for MacOS X using os_unix.c prep work
- */
-
-    int
-C2PascalString(char_u *CString, Str255 *PascalString)
-{
-    char_u *PascalPtr = (char_u *) PascalString;
-    int    len;
-    int    i;
-
-    PascalPtr[0] = 0;
-    if (CString == NULL)
-	return 0;
-
-    len = STRLEN(CString);
-    if (len > 255)
-	len = 255;
-
-    for (i = 0; i < len; i++)
-	PascalPtr[i+1] = CString[i];
-
-    PascalPtr[0] = len;
-
-    return 0;
-}
-
-    int
-GetFSSpecFromPath(char_u *file, FSSpec *fileFSSpec)
-{
-    // From FAQ 8-12
-    Str255      filePascal;
-    CInfoPBRec	myCPB;
-    OSErr	err;
-
-    (void) C2PascalString(file, &filePascal);
-
-    myCPB.dirInfo.ioNamePtr   = filePascal;
-    myCPB.dirInfo.ioVRefNum   = 0;
-    myCPB.dirInfo.ioFDirIndex = 0;
-    myCPB.dirInfo.ioDrDirID   = 0;
-
-    err= PBGetCatInfo(&myCPB, false);
-
-    //    vRefNum, dirID, name
-    FSMakeFSSpec(0, 0, filePascal, fileFSSpec);
-
-    // TODO: Use an error code mechanism
-    return 0;
-}
-
-/*
- * Convert a FSSpec to a full path
- */
-
-char_u *FullPathFromFSSpec_save(FSSpec file)
-{
-    /*
-     * TODO: Add protection for 256 char max.
-     */
-
-    CInfoPBRec	theCPB;
-    char_u	fname[256];
-    char_u	*filenamePtr = fname;
-    OSErr	error;
-    int		folder = 1;
-#ifdef USE_UNIXFILENAME
-    SInt16	dfltVol_vRefNum;
-    SInt32	dfltVol_dirID;
-    FSRef	refFile;
-    OSStatus	status;
-    UInt32	pathSize = 256;
-    char_u	pathname[256];
-    char_u	*path = pathname;
-#else
-    Str255	directoryName;
-    char_u	temporary[255];
-    char_u	*temporaryPtr = temporary;
-#endif
-
-#ifdef USE_UNIXFILENAME
-    // Get the default volume
-    // TODO: Remove as this only work if Vim is on the Boot Volume
-    error=HGetVol(NULL, &dfltVol_vRefNum, &dfltVol_dirID);
-
-    if (error)
-      return NULL;
-#endif
-
-    // Start filling fname with file.name
-    vim_strncpy(filenamePtr, &file.name[1], file.name[0]);
-
-    // Get the info about the file specified in FSSpec
-    theCPB.dirInfo.ioFDirIndex = 0;
-    theCPB.dirInfo.ioNamePtr   = file.name;
-    theCPB.dirInfo.ioVRefNum   = file.vRefNum;
-    //theCPB.hFileInfo.ioDirID   = 0;
-    theCPB.dirInfo.ioDrDirID   = file.parID;
-
-    // As ioFDirIndex = 0, get the info of ioNamePtr,
-    // which is relative to ioVrefNum, ioDirID
-    error = PBGetCatInfo(&theCPB, false);
-
-    // If we are called for a new file we expect fnfErr
-    if ((error) && (error != fnfErr))
-      return NULL;
-
-    // Check if it's a file or folder
-    // default to file if file don't exist
-    if (((theCPB.hFileInfo.ioFlAttrib & ioDirMask) == 0) || (error))
-      folder = 0; // It's not a folder
-    else
-      folder = 1;
-
-#ifdef USE_UNIXFILENAME
-    /*
-     * The functions used here are available in Carbon, but do nothing on
-     * MacOS 8 and 9.
-     */
-    if (error == fnfErr)
-    {
-	// If the file to be saved does not already exist, it isn't possible
-	// to convert its FSSpec into an FSRef.  But we can construct an
-	// FSSpec for the file's parent folder (since we have its volume and
-	// directory IDs), and since that folder does exist, we can convert
-	// that FSSpec into an FSRef, convert the FSRef in turn into a path,
-	// and, finally, append the filename.
-	FSSpec dirSpec;
-	FSRef dirRef;
-	Str255 emptyFilename = "\p";
-	error = FSMakeFSSpec(theCPB.dirInfo.ioVRefNum,
-	    theCPB.dirInfo.ioDrDirID, emptyFilename, &dirSpec);
-	if (error)
-	    return NULL;
-
-	error = FSpMakeFSRef(&dirSpec, &dirRef);
-	if (error)
-	    return NULL;
-
-	status = FSRefMakePath(&dirRef, (UInt8*)path, pathSize);
-	if (status)
-	    return NULL;
-
-	STRCAT(path, "/");
-	STRCAT(path, filenamePtr);
-    }
-    else
-    {
-	// If the file to be saved already exists, we can get its full path
-	// by converting its FSSpec into an FSRef.
-	error=FSpMakeFSRef(&file, &refFile);
-	if (error)
-	    return NULL;
-
-	status=FSRefMakePath(&refFile, (UInt8 *) path, pathSize);
-	if (status)
-	    return NULL;
-    }
-
-    // Add a slash at the end if needed
-    if (folder)
-	STRCAT(path, "/");
-
-    return (vim_strsave(path));
-#else
-    // TODO: Get rid of all USE_UNIXFILENAME below
-    // Set ioNamePtr, it's the same area which is always reused.
-    theCPB.dirInfo.ioNamePtr = directoryName;
-
-    // Trick for first entry, set ioDrParID to the first value
-    // we want for ioDrDirID
-    theCPB.dirInfo.ioDrParID = file.parID;
-    theCPB.dirInfo.ioDrDirID = file.parID;
-
-    if ((TRUE) && (file.parID != fsRtDirID /*fsRtParID*/))
-    do
-    {
-	theCPB.dirInfo.ioFDirIndex = -1;
-     // theCPB.dirInfo.ioNamePtr   = directoryName; Already done above.
-	theCPB.dirInfo.ioVRefNum   = file.vRefNum;
-     // theCPB.dirInfo.ioDirID     = irrelevant when ioFDirIndex = -1
-	theCPB.dirInfo.ioDrDirID   = theCPB.dirInfo.ioDrParID;
-
-	// As ioFDirIndex = -1, get the info of ioDrDirID,
-	//  *ioNamePtr[0 TO 31] will be updated
-	error = PBGetCatInfo(&theCPB,false);
-
-	if (error)
-	  return NULL;
-
-	// Put the new directoryName in front of the current fname
-	STRCPY(temporaryPtr, filenamePtr);
-	vim_strncpy(filenamePtr, &directoryName[1], directoryName[0]);
-	STRCAT(filenamePtr, ":");
-	STRCAT(filenamePtr, temporaryPtr);
-    }
-#if 1 // def USE_UNIXFILENAME
-    while ((theCPB.dirInfo.ioDrParID != fsRtDirID)
-	 /* && (theCPB.dirInfo.ioDrDirID != fsRtDirID)*/);
-#else
-    while (theCPB.dirInfo.ioDrDirID != fsRtDirID);
-#endif
-
-    // Get the information about the volume on which the file reside
-    theCPB.dirInfo.ioFDirIndex = -1;
- // theCPB.dirInfo.ioNamePtr   = directoryName; Already done above.
-    theCPB.dirInfo.ioVRefNum   = file.vRefNum;
- // theCPB.dirInfo.ioDirID     = irrelevant when ioFDirIndex = -1
-    theCPB.dirInfo.ioDrDirID   = theCPB.dirInfo.ioDrParID;
-
-    // As ioFDirIndex = -1, get the info of ioDrDirID,
-    //	*ioNamePtr[0 TO 31] will be updated
-    error = PBGetCatInfo(&theCPB,false);
-
-    if (error)
-      return NULL;
-
-    // For MacOS Classic always add the volume name
-    // For MacOS X add the volume name preceded by "Volumes"
-    //	when we are not referring to the boot volume
-#ifdef USE_UNIXFILENAME
-    if (file.vRefNum != dfltVol_vRefNum)
-#endif
-    {
-	// Add the volume name
-	STRCPY(temporaryPtr, filenamePtr);
-	vim_strncpy(filenamePtr, &directoryName[1], directoryName[0]);
-	STRCAT(filenamePtr, ":");
-	STRCAT(filenamePtr, temporaryPtr);
-
-#ifdef USE_UNIXFILENAME
-	STRCPY(temporaryPtr, filenamePtr);
-	filenamePtr[0] = 0; // NULL terminate the string
-	STRCAT(filenamePtr, "Volumes:");
-	STRCAT(filenamePtr, temporaryPtr);
-#endif
-    }
-
-    // Append final path separator if it's a folder
-    if (folder)
-	STRCAT(fname, ":");
-
-    // As we use Unix File Name for MacOS X convert it
-#ifdef USE_UNIXFILENAME
-    // Need to insert leading /
-    // TODO: get the above code to use directly the /
-    STRCPY(&temporaryPtr[1], filenamePtr);
-    temporaryPtr[0] = '/';
-    STRCPY(filenamePtr, temporaryPtr);
-    {
-    char	*p;
-    for (p = fname; *p; p++)
-	if (*p == ':')
-	    *p = '/';
-    }
-#endif
-
-    return (vim_strsave(fname));
-#endif
-}
-
-#if defined(USE_CARBONKEYHANDLER) || defined(PROTO)
-/*
- * Input Method Control functions.
- */
-
-/*
- * Notify cursor position to IM.
- */
-    void
-im_set_position(int row, int col)
-{
-# if 0
-    // TODO: Implement me!
-    im_start_row = row;
-    im_start_col = col;
-# endif
-}
-
-static ScriptLanguageRecord gTSLWindow;
-static ScriptLanguageRecord gTSLInsert;
-static ScriptLanguageRecord gTSLDefault = { 0, 0 };
-
-static Component	     gTSCWindow;
-static Component	     gTSCInsert;
-static Component	     gTSCDefault;
-
-static int		     im_initialized = 0;
-
-    static void
-im_on_window_switch(int active)
-{
-    ScriptLanguageRecord *slptr = NULL;
-    OSStatus err;
-
-    if (! gui.in_use)
-	return;
-
-    if (im_initialized == 0)
-    {
-	im_initialized = 1;
-
-	// save default TSM component (should be U.S.) to default
-	GetDefaultInputMethodOfClass(&gTSCDefault, &gTSLDefault,
-				     kKeyboardInputMethodClass);
-    }
-
-    if (active == TRUE)
-    {
-	im_is_active = TRUE;
-	ActivateTSMDocument(gTSMDocument);
-	slptr = &gTSLWindow;
-
-	if (slptr)
-	{
-	    err = SetDefaultInputMethodOfClass(gTSCWindow, slptr,
-					       kKeyboardInputMethodClass);
-	    if (err == noErr)
-		err = SetTextServiceLanguage(slptr);
-
-	    if (err == noErr)
-		KeyScript(slptr->fScript | smKeyForceKeyScriptMask);
-	}
-    }
-    else
-    {
-	err = GetTextServiceLanguage(&gTSLWindow);
-	if (err == noErr)
-	    slptr = &gTSLWindow;
-
-	if (slptr)
-	    GetDefaultInputMethodOfClass(&gTSCWindow, slptr,
-					 kKeyboardInputMethodClass);
-
-	im_is_active = FALSE;
-	DeactivateTSMDocument(gTSMDocument);
-    }
-}
-
-/*
- * Set IM status on ("active" is TRUE) or off ("active" is FALSE).
- */
-    void
-im_set_active(int active)
-{
-    ScriptLanguageRecord *slptr = NULL;
-    OSStatus err;
-
-    if (!gui.in_use)
-	return;
-
-    if (im_initialized == 0)
-    {
-	im_initialized = 1;
-
-	// save default TSM component (should be U.S.) to default
-	GetDefaultInputMethodOfClass(&gTSCDefault, &gTSLDefault,
-				     kKeyboardInputMethodClass);
-    }
-
-    if (active == TRUE)
-    {
-	im_is_active = TRUE;
-	ActivateTSMDocument(gTSMDocument);
-	slptr = &gTSLInsert;
-
-	if (slptr)
-	{
-	    err = SetDefaultInputMethodOfClass(gTSCInsert, slptr,
-					       kKeyboardInputMethodClass);
-	    if (err == noErr)
-		err = SetTextServiceLanguage(slptr);
-
-	    if (err == noErr)
-		KeyScript(slptr->fScript | smKeyForceKeyScriptMask);
-	}
-    }
-    else
-    {
-	err = GetTextServiceLanguage(&gTSLInsert);
-	if (err == noErr)
-	    slptr = &gTSLInsert;
-
-	if (slptr)
-	    GetDefaultInputMethodOfClass(&gTSCInsert, slptr,
-					 kKeyboardInputMethodClass);
-
-	// restore to default when switch to normal mode, so than we could
-	// enter commands easier
-	SetDefaultInputMethodOfClass(gTSCDefault, &gTSLDefault,
-				     kKeyboardInputMethodClass);
-	SetTextServiceLanguage(&gTSLDefault);
-
-	im_is_active = FALSE;
-	DeactivateTSMDocument(gTSMDocument);
-    }
-}
-
-/*
- * Get IM status.  When IM is on, return not 0.  Else return 0.
- */
-    int
-im_get_status(void)
-{
-    if (! gui.in_use)
-	return 0;
-
-    return im_is_active;
-}
-
-#endif
-
-
-
-#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
-// drawer implementation
-static MenuRef contextMenu = NULL;
-enum
-{
-    kTabContextMenuId = 42
-};
-
-// the caller has to CFRelease() the returned string
-    static CFStringRef
-getTabLabel(tabpage_T *page)
-{
-    get_tabline_label(page, FALSE);
-#ifdef MACOS_CONVERT
-    return (CFStringRef)mac_enc_to_cfstring(NameBuff, STRLEN(NameBuff));
-#else
-    // TODO: check internal encoding?
-    return CFStringCreateWithCString(kCFAllocatorDefault, (char *)NameBuff,
-						   kCFStringEncodingMacRoman);
-#endif
-}
-
-
-#define DRAWER_SIZE 150
-#define DRAWER_INSET 16
-
-static ControlRef dataBrowser = NULL;
-
-// when the tabline is hidden, vim doesn't call update_tabline(). When
-// the tabline is shown again, show_tabline() is called before update_tabline(),
-// and because of this, the tab labels and vim's internal tabs are out of sync
-// for a very short time. to prevent inconsistent state, we store the labels
-// of the tabs, not pointers to the tabs (which are invalid for a short time).
-static CFStringRef *tabLabels = NULL;
-static int tabLabelsSize = 0;
-
-enum
-{
-    kTabsColumn = 'Tabs'
-};
-
-    static int
-getTabCount(void)
-{
-    tabpage_T	*tp;
-    int		numTabs = 0;
-
-    FOR_ALL_TABPAGES(tp)
-	++numTabs;
-    return numTabs;
-}
-
-// data browser item display callback
-    static OSStatus
-dbItemDataCallback(ControlRef browser,
-	DataBrowserItemID itemID,
-	DataBrowserPropertyID property /* column id */,
-	DataBrowserItemDataRef itemData,
-	Boolean changeValue)
-{
-    OSStatus status = noErr;
-
-    // assert(property == kTabsColumn); // why is this violated??
-
-    // changeValue is true if we have a modifiable list and data was changed.
-    // In our case, it's always false.
-    // (that is: if (changeValue) updateInternalData(); else return
-    // internalData();
-    if (!changeValue)
-    {
-	CFStringRef str;
-
-	assert(itemID - 1 >= 0 && itemID - 1 < tabLabelsSize);
-	str = tabLabels[itemID - 1];
-	status = SetDataBrowserItemDataText(itemData, str);
-    }
-    else
-	status = errDataBrowserPropertyNotSupported;
-
-    return status;
-}
-
-// data browser action callback
-    static void
-dbItemNotificationCallback(ControlRef browser,
-	DataBrowserItemID item,
-	DataBrowserItemNotification message)
-{
-    switch (message)
-    {
-	case kDataBrowserItemSelected:
-	    send_tabline_event(item);
-	    break;
-    }
-}
-
-// callbacks needed for contextual menu:
-    static void
-dbGetContextualMenuCallback(ControlRef browser,
-	MenuRef *menu,
-	UInt32 *helpType,
-	CFStringRef *helpItemString,
-	AEDesc *selection)
-{
-    // on mac os 9: kCMHelpItemNoHelp, but it's not the same
-    *helpType = kCMHelpItemRemoveHelp; // OS X only ;-)
-    *helpItemString = NULL;
-
-    *menu = contextMenu;
-}
-
-    static void
-dbSelectContextualMenuCallback(ControlRef browser,
-	MenuRef menu,
-	UInt32 selectionType,
-	SInt16 menuID,
-	MenuItemIndex menuItem)
-{
-    if (selectionType == kCMMenuItemSelected)
-    {
-	MenuCommand command;
-	GetMenuItemCommandID(menu, menuItem, &command);
-
-	// get tab that was selected when the context menu appeared
-	// (there is always one tab selected). TODO: check if the context menu
-	// isn't opened on an item but on empty space (has to be possible some
-	// way, the finder does it too ;-) )
-	Handle items = NewHandle(0);
-	if (items != NULL)
-	{
-	    int numItems;
-
-	    GetDataBrowserItems(browser, kDataBrowserNoItem, false,
-					   kDataBrowserItemIsSelected, items);
-	    numItems = GetHandleSize(items) / sizeof(DataBrowserItemID);
-	    if (numItems > 0)
-	    {
-		int idx;
-		DataBrowserItemID *itemsPtr;
-
-		HLock(items);
-		itemsPtr = (DataBrowserItemID *)*items;
-		idx = itemsPtr[0];
-		HUnlock(items);
-		send_tabline_menu_event(idx, command);
-	    }
-	    DisposeHandle(items);
-	}
-    }
-}
-
-// focus callback of the data browser to always leave focus in vim
-    static OSStatus
-dbFocusCallback(EventHandlerCallRef handler, EventRef event, void *data)
-{
-    assert(GetEventClass(event) == kEventClassControl
-	    && GetEventKind(event) == kEventControlSetFocusPart);
-
-    return paramErr;
-}
-
-
-// drawer callback to resize data browser to drawer size
-    static OSStatus
-drawerCallback(EventHandlerCallRef handler, EventRef event, void *data)
-{
-    switch (GetEventKind(event))
-    {
-	case kEventWindowBoundsChanged: // move or resize
-	    {
-		UInt32 attribs;
-		GetEventParameter(event, kEventParamAttributes, typeUInt32,
-				       NULL, sizeof(attribs), NULL, &attribs);
-		if (attribs & kWindowBoundsChangeSizeChanged) // resize
-		{
-		    Rect r;
-		    GetWindowBounds(drawer, kWindowContentRgn, &r);
-		    SetRect(&r, 0, 0, r.right - r.left, r.bottom - r.top);
-		    SetControlBounds(dataBrowser, &r);
-		    SetDataBrowserTableViewNamedColumnWidth(dataBrowser,
-							kTabsColumn, r.right);
-		}
-	    }
-	    break;
-    }
-
-    return eventNotHandledErr;
-}
-
-// Load DataBrowserChangeAttributes() dynamically on tiger (and better).
-// This way the code works on 10.2 and 10.3 as well (it doesn't have the
-// blue highlights in the list view on these systems, though. Oh well.)
-
-
-#import <mach-o/dyld.h>
-
-enum { kMyDataBrowserAttributeListViewAlternatingRowColors = (1 << 1) };
-
-    static OSStatus
-myDataBrowserChangeAttributes(ControlRef inDataBrowser,
-	OptionBits inAttributesToSet,
-	OptionBits inAttributesToClear)
-{
-    long osVersion;
-    char *symbolName;
-    NSSymbol symbol = NULL;
-    OSStatus (*dataBrowserChangeAttributes)(ControlRef inDataBrowser,
-	      OptionBits   inAttributesToSet, OptionBits inAttributesToClear);
-
-    Gestalt(gestaltSystemVersion, &osVersion);
-    if (osVersion < 0x1040) // only supported for 10.4 (and up)
-	return noErr;
-
-    // C name mangling...
-    symbolName = "_DataBrowserChangeAttributes";
-    if (!NSIsSymbolNameDefined(symbolName)
-	    || (symbol = NSLookupAndBindSymbol(symbolName)) == NULL)
-	return noErr;
-
-    dataBrowserChangeAttributes = NSAddressOfSymbol(symbol);
-    if (dataBrowserChangeAttributes == NULL)
-	return noErr; // well...
-    return dataBrowserChangeAttributes(inDataBrowser,
-				      inAttributesToSet, inAttributesToClear);
-}
-
-    static void
-initialise_tabline(void)
-{
-    Rect drawerRect = { 0, 0, 0, DRAWER_SIZE };
-    DataBrowserCallbacks dbCallbacks;
-    EventTypeSpec focusEvent = {kEventClassControl, kEventControlSetFocusPart};
-    EventTypeSpec resizeEvent = {kEventClassWindow, kEventWindowBoundsChanged};
-    DataBrowserListViewColumnDesc colDesc;
-
-    // drawers have to have compositing enabled
-    CreateNewWindow(kDrawerWindowClass,
-	    kWindowStandardHandlerAttribute
-		    | kWindowCompositingAttribute
-		    | kWindowResizableAttribute
-		    | kWindowLiveResizeAttribute,
-	    &drawerRect, &drawer);
-
-    SetThemeWindowBackground(drawer, kThemeBrushDrawerBackground, true);
-    SetDrawerParent(drawer, gui.VimWindow);
-    SetDrawerOffsets(drawer, kWindowOffsetUnchanged, DRAWER_INSET);
-
-
-    // create list view embedded in drawer
-    CreateDataBrowserControl(drawer, &drawerRect, kDataBrowserListView,
-								&dataBrowser);
-
-    dbCallbacks.version = kDataBrowserLatestCallbacks;
-    InitDataBrowserCallbacks(&dbCallbacks);
-    dbCallbacks.u.v1.itemDataCallback =
-				NewDataBrowserItemDataUPP(dbItemDataCallback);
-    dbCallbacks.u.v1.itemNotificationCallback =
-		NewDataBrowserItemNotificationUPP(dbItemNotificationCallback);
-    dbCallbacks.u.v1.getContextualMenuCallback =
-	      NewDataBrowserGetContextualMenuUPP(dbGetContextualMenuCallback);
-    dbCallbacks.u.v1.selectContextualMenuCallback =
-	NewDataBrowserSelectContextualMenuUPP(dbSelectContextualMenuCallback);
-
-    SetDataBrowserCallbacks(dataBrowser, &dbCallbacks);
-
-    SetDataBrowserListViewHeaderBtnHeight(dataBrowser, 0); // no header
-    SetDataBrowserHasScrollBars(dataBrowser, false, true); // only vertical
-    SetDataBrowserSelectionFlags(dataBrowser,
-	      kDataBrowserSelectOnlyOne | kDataBrowserNeverEmptySelectionSet);
-    SetDataBrowserTableViewHiliteStyle(dataBrowser,
-					     kDataBrowserTableViewFillHilite);
-    Boolean b = false;
-    SetControlData(dataBrowser, kControlEntireControl,
-		  kControlDataBrowserIncludesFrameAndFocusTag, sizeof(b), &b);
-
-    // enable blue background in data browser (this is only in 10.4 and vim
-    // has to support older osx versions as well, so we have to load this
-    // function dynamically)
-    myDataBrowserChangeAttributes(dataBrowser,
-		      kMyDataBrowserAttributeListViewAlternatingRowColors, 0);
-
-    // install callback that keeps focus in vim and away from the data browser
-    InstallControlEventHandler(dataBrowser, dbFocusCallback, 1, &focusEvent,
-								  NULL, NULL);
-
-    // install callback that keeps data browser at the size of the drawer
-    InstallWindowEventHandler(drawer, drawerCallback, 1, &resizeEvent,
-								  NULL, NULL);
-
-    // add "tabs" column to data browser
-    colDesc.propertyDesc.propertyID = kTabsColumn;
-    colDesc.propertyDesc.propertyType = kDataBrowserTextType;
-
-    // add if items can be selected (?): kDataBrowserListViewSelectionColumn
-    colDesc.propertyDesc.propertyFlags = kDataBrowserDefaultPropertyFlags;
-
-    colDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
-    colDesc.headerBtnDesc.minimumWidth = 100;
-    colDesc.headerBtnDesc.maximumWidth = 150;
-    colDesc.headerBtnDesc.titleOffset = 0;
-    colDesc.headerBtnDesc.titleString = CFSTR("Tabs");
-    colDesc.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing;
-    colDesc.headerBtnDesc.btnFontStyle.flags = 0; // use default font
-    colDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
-
-    AddDataBrowserListViewColumn(dataBrowser, &colDesc, 0);
-
-    // create tabline popup menu required by vim docs (see :he tabline-menu)
-    CreateNewMenu(kTabContextMenuId, 0, &contextMenu);
-    AppendMenuItemTextWithCFString(contextMenu, CFSTR("Close Tab"), 0,
-						    TABLINE_MENU_CLOSE, NULL);
-    AppendMenuItemTextWithCFString(contextMenu, CFSTR("New Tab"), 0,
-						      TABLINE_MENU_NEW, NULL);
-    AppendMenuItemTextWithCFString(contextMenu, CFSTR("Open Tab..."), 0,
-						     TABLINE_MENU_OPEN, NULL);
-}
-
-
-/*
- * Show or hide the tabline.
- */
-    void
-gui_mch_show_tabline(int showit)
-{
-    if (showit == 0)
-	CloseDrawer(drawer, true);
-    else
-	OpenDrawer(drawer, kWindowEdgeRight, true);
-}
-
-/*
- * Return TRUE when tabline is displayed.
- */
-    int
-gui_mch_showing_tabline(void)
-{
-    WindowDrawerState state = GetDrawerState(drawer);
-
-    return state == kWindowDrawerOpen || state == kWindowDrawerOpening;
-}
-
-/*
- * Update the labels of the tabline.
- */
-    void
-gui_mch_update_tabline(void)
-{
-    tabpage_T	*tp;
-    int		numTabs = getTabCount();
-    int		nr = 1;
-    int		curtabidx = 1;
-
-    // adjust data browser
-    if (tabLabels != NULL)
-    {
-	int i;
-
-	for (i = 0; i < tabLabelsSize; ++i)
-	    CFRelease(tabLabels[i]);
-	free(tabLabels);
-    }
-    tabLabels = (CFStringRef *)malloc(numTabs * sizeof(CFStringRef));
-    tabLabelsSize = numTabs;
-
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr)
-    {
-	if (tp == curtab)
-	    curtabidx = nr;
-	tabLabels[nr-1] = getTabLabel(tp);
-    }
-
-    RemoveDataBrowserItems(dataBrowser, kDataBrowserNoItem, 0, NULL,
-						  kDataBrowserItemNoProperty);
-    // data browser uses ids 1, 2, 3, ... numTabs per default, so we
-    // can pass NULL for the id array
-    AddDataBrowserItems(dataBrowser, kDataBrowserNoItem, numTabs, NULL,
-						  kDataBrowserItemNoProperty);
-
-    DataBrowserItemID item = curtabidx;
-    SetDataBrowserSelectedItems(dataBrowser, 1, &item, kDataBrowserItemsAssign);
-}
-
-/*
- * Set the current tab to "nr".  First tab is 1.
- */
-    void
-gui_mch_set_curtab(int nr)
-{
-    DataBrowserItemID item = nr;
-    SetDataBrowserSelectedItems(dataBrowser, 1, &item, kDataBrowserItemsAssign);
-
-    // TODO: call something like this?: (or restore scroll position, or...)
-    RevealDataBrowserItem(dataBrowser, item, kTabsColumn,
-						      kDataBrowserRevealOnly);
-}
-
-#endif // FEAT_GUI_TABLINE
diff --git a/src/if_mzsch.c b/src/if_mzsch.c
index bfcdbea..7b52936 100644
--- a/src/if_mzsch.c
+++ b/src/if_mzsch.c
@@ -812,10 +812,6 @@
 #elif defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)
 static void timer_proc(XtPointer, XtIntervalId *);
 static XtIntervalId timer_id = (XtIntervalId)0;
-#elif defined(FEAT_GUI_MAC)
-pascal void timer_proc(EventLoopTimerRef, void *);
-static EventLoopTimerRef timer_id = NULL;
-static EventLoopTimerUPP timerUPP;
 #endif
 
 #if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) // Win32 console and Unix
@@ -852,9 +848,6 @@
 # elif defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)
     static void
 timer_proc(XtPointer timed_out UNUSED, XtIntervalId *interval_id UNUSED)
-# elif defined(FEAT_GUI_MAC)
-    pascal void
-timer_proc(EventLoopTimerRef theTimer UNUSED, void *userData UNUSED)
 # endif
 {
     scheme_check_threads();
@@ -877,10 +870,6 @@
     timer_id = g_timeout_add((guint)p_mzq, (GSourceFunc)timer_proc, NULL);
 # elif defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)
     timer_id = XtAppAddTimeOut(app_context, p_mzq, timer_proc, NULL);
-# elif defined(FEAT_GUI_MAC)
-    timerUPP = NewEventLoopTimerUPP(timer_proc);
-    InstallEventLoopTimer(GetMainEventLoop(), p_mzq * kEventDurationMillisecond,
-		p_mzq * kEventDurationMillisecond, timerUPP, NULL, &timer_id);
 # endif
 }
 
@@ -893,9 +882,6 @@
     g_source_remove(timer_id);
 # elif defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)
     XtRemoveTimeOut(timer_id);
-# elif defined(FEAT_GUI_MAC)
-    RemoveEventLoopTimer(timer_id);
-    DisposeEventLoopTimerUPP(timerUPP);
 # endif
     timer_id = 0;
 }
diff --git a/src/main.c b/src/main.c
index 86156b7..c87fdbf 100644
--- a/src/main.c
+++ b/src/main.c
@@ -298,33 +298,6 @@
 	params.want_full_screen = FALSE;
 #endif
 
-#if defined(FEAT_GUI_MAC) && defined(MACOS_X_DARWIN)
-    // When the GUI is started from Finder, need to display messages in a
-    // message box.  isatty(2) returns TRUE anyway, thus we need to check the
-    // name to know we're not started from a terminal.
-    if (gui.starting && (!isatty(2) || strcmp("/dev/console", ttyname(2)) == 0))
-    {
-	params.want_full_screen = FALSE;
-
-	// Avoid always using "/" as the current directory.  Note that when
-	// started from Finder the arglist will be filled later in
-	// HandleODocAE() and "fname" will be NULL.
-	if (getcwd((char *)NameBuff, MAXPATHL) != NULL
-						&& STRCMP(NameBuff, "/") == 0)
-	{
-	    if (params.fname != NULL)
-		(void)vim_chdirfile(params.fname, "drop");
-	    else
-	    {
-		expand_env((char_u *)"$HOME", NameBuff, MAXPATHL);
-		vim_chdir(NameBuff);
-	    }
-	    if (start_dir != NULL)
-		mch_dirname(start_dir, MAXPATHL);
-	}
-    }
-#endif
-
     /*
      * mch_init() sets up the terminal (window) for use.  This must be
      * done after resetting full_screen, otherwise it may move the cursor.
@@ -1843,18 +1816,6 @@
 
     initstr = gettail((char_u *)parmp->argv[0]);
 
-#ifdef FEAT_GUI_MAC
-    // An issue has been seen when launching Vim in such a way that
-    // $PWD/$ARGV[0] or $ARGV[0] is not the absolute path to the
-    // executable or a symbolic link of it. Until this issue is resolved
-    // we prohibit the GUI from being used.
-    if (STRCMP(initstr, parmp->argv[0]) == 0)
-	disallow_gui = TRUE;
-
-    // TODO: On MacOS X default to gui if argv[0] ends in:
-    //       /Vim.app/Contents/MacOS/Vim
-#endif
-
 #ifdef FEAT_EVAL
     set_vim_var_string(VV_PROGNAME, initstr, -1);
     set_progpath((char_u *)parmp->argv[0]);
diff --git a/src/misc2.c b/src/misc2.c
index 3e16c36..0370bdf 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -3341,7 +3341,7 @@
 }
 
 #if defined(FEAT_SESSION) || defined(FEAT_AUTOCHDIR) \
-	|| defined(MSWIN) || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_GTK) \
+	|| defined(MSWIN) || defined(FEAT_GUI_GTK) \
 	|| defined(FEAT_NETBEANS_INTG) \
 	|| defined(PROTO)
 /*
diff --git a/src/mouse.c b/src/mouse.c
index 56472a3..7af9049 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -116,7 +116,7 @@
 
 #if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
 	    || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
-	    || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_PHOTON) \
+	    || defined(FEAT_GUI_PHOTON) \
 	    || defined(FEAT_TERM_POPUP_MENU)
 # define USE_POPUP_SETPOS
 # define NEED_VCOL2COL
@@ -532,7 +532,7 @@
 	    if (gui.in_use)
 	    {
 #  if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
-			  || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
+			  || defined(FEAT_GUI_PHOTON)
 		if (!is_click)
 		    // Ignore right button release events, only shows the popup
 		    // menu on the button down event.
diff --git a/src/option.h b/src/option.h
index 7777bd6..421ee7a 100644
--- a/src/option.h
+++ b/src/option.h
@@ -701,9 +701,6 @@
 #if defined(DYNAMIC_LUA)
 EXTERN char_u	*p_luadll;	// 'luadll'
 #endif
-#ifdef FEAT_GUI_MAC
-EXTERN int	p_macatsui;	// 'macatsui'
-#endif
 EXTERN int	p_magic;	// 'magic'
 EXTERN char_u	*p_menc;	// 'makeencoding'
 #ifdef FEAT_QUICKFIX
diff --git a/src/optiondefs.h b/src/optiondefs.h
index f1f1af3..9afa84d 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -331,13 +331,8 @@
 #endif
 					    (char_u *)0L} SCTX_INIT},
     {"antialias",   "anti", P_BOOL|P_VI_DEF|P_VIM|P_RCLR,
-#if defined(FEAT_GUI_MAC)
-			    (char_u *)&p_antialias, PV_NONE,
-			    {(char_u *)FALSE, (char_u *)FALSE}
-#else
 			    (char_u *)NULL, PV_NONE,
 			    {(char_u *)FALSE, (char_u *)FALSE}
-#endif
 			    SCTX_INIT},
     {"arabic",	    "arab", P_BOOL|P_VI_DEF|P_VIM|P_CURSWANT,
 #ifdef FEAT_ARABIC
@@ -1209,7 +1204,7 @@
     {"guioptions",  "go",   P_STRING|P_VI_DEF|P_RALL|P_FLAGLIST,
 #if defined(FEAT_GUI)
 			    (char_u *)&p_go, PV_NONE,
-# if defined(UNIX) && !defined(FEAT_GUI_MAC)
+# if defined(UNIX)
 			    {(char_u *)"aegimrLtT", (char_u *)0L}
 # else
 			    {(char_u *)"egmrLtT", (char_u *)0L}
@@ -1618,13 +1613,8 @@
 #endif
 			    SCTX_INIT},
     {"macatsui",    NULL,   P_BOOL|P_VI_DEF|P_RCLR,
-#ifdef FEAT_GUI_MAC
-			    (char_u *)&p_macatsui, PV_NONE,
-			    {(char_u *)TRUE, (char_u *)0L}
-#else
 			    (char_u *)NULL, PV_NONE,
 			    {(char_u *)"", (char_u *)0L}
-#endif
 			    SCTX_INIT},
     {"magic",	    NULL,   P_BOOL|P_VI_DEF,
 			    (char_u *)&p_magic, PV_NONE,
diff --git a/src/os_mac.h b/src/os_mac.h
index d052bb5..6524609 100644
--- a/src/os_mac.h
+++ b/src/os_mac.h
@@ -21,25 +21,6 @@
 #endif
 
 /*
- * Macintosh machine-dependent things.
- *
- * Include the Mac header files, unless also compiling with X11 (the header
- * files have many conflicts).
- */
-#ifdef FEAT_GUI_MAC
-# include <Quickdraw.h>	    // Apple calls it QuickDraw.h...
-# include <ToolUtils.h>
-# include <LowMem.h>
-# include <Scrap.h>
-# include <Sound.h>
-# include <TextUtils.h>
-# include <Memory.h>
-# include <OSUtils.h>
-# include <Files.h>
-# include <Script.h>
-#endif
-
-/*
  * Unix interface
  */
 #if defined(__APPLE_CC__) // for Project Builder and ...
diff --git a/src/os_mac_conv.c b/src/os_mac_conv.c
index 6c52e7d..3daf74a 100644
--- a/src/os_mac_conv.c
+++ b/src/os_mac_conv.c
@@ -17,7 +17,7 @@
 
 #include "vim.h"
 
-#if !defined(FEAT_GUI_MAC) && !defined(PROTO)
+#if !defined(PROTO)
 # include <CoreServices/CoreServices.h>
 #endif
 
diff --git a/src/os_unix.c b/src/os_unix.c
index c9b3f92..0f61367 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -2194,7 +2194,7 @@
     if (get_x11_windis() == OK)
 	type = 1;
 #else
-# if defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) \
+# if defined(FEAT_GUI_PHOTON) \
     || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_HAIKU)
     if (gui.in_use)
 	type = 1;
@@ -2229,7 +2229,7 @@
 	    set_x11_title(title);		// x11
 #endif
 #if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_HAIKU) \
-	|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
+	|| defined(FEAT_GUI_PHOTON)
 	else
 	    gui_mch_settitle(title, icon);
 #endif
diff --git a/src/proto.h b/src/proto.h
index e894987..e715ca4 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -323,9 +323,6 @@
 #  ifdef FEAT_GUI_HAIKU
 #   include "gui_haiku.pro"
 #  endif
-#  ifdef FEAT_GUI_MAC
-#   include "gui_mac.pro"
-#  endif
 #  ifdef FEAT_GUI_X11
 #   include "gui_x11.pro"
 #  endif
diff --git a/src/proto/gui_mac.pro b/src/proto/gui_mac.pro
deleted file mode 100644
index 1fa3453..0000000
--- a/src/proto/gui_mac.pro
+++ /dev/null
@@ -1,153 +0,0 @@
-/* gui_mac.c */
-
-/*
- * Mac specific prototypes
- */
-
-pascal Boolean WaitNextEventWrp(EventMask eventMask, EventRecord *theEvent, UInt32 sleep, RgnHandle mouseRgn);
-pascal void gui_mac_scroll_action(ControlHandle theControl, short partCode);
-pascal void gui_mac_drag_thumb (ControlHandle theControl, short partCode);
-void gui_mac_handle_event(EventRecord *event);
-void gui_mac_doMouseDown(EventRecord *theEvent);
-void gui_mac_do_key(EventRecord *theEvent);
-void gui_mac_handle_menu(long menuChoice);
-void gui_mac_focus_change(EventRecord *event);
-void gui_mac_update(EventRecord *event);
-short gui_mch_get_mac_menu_item_index(vimmenu_T *menu, vimmenu_T *parent);
-int gui_mch_is_blinking(void);
-int gui_mch_is_blink_off(void);
-void gui_mch_set_blinking(long wait, long on, long off);
-void gui_mch_stop_blink(int may_call_gui_update_cursor);
-void gui_mch_start_blink(void);
-void gui_mch_getmouse(int *x, int *y);
-void gui_mch_setmouse(int x, int y);
-void gui_mch_prepare(int *argc, char **argv);
-int gui_mch_init_check(void);
-int gui_mch_init(void);
-void gui_mch_new_colors(void);
-int gui_mch_open(void);
-void gui_mch_exit(int);
-void gui_mch_set_winsize(int width, int height, int min_width, int min_height, int base_width, int base_height);
-int gui_mch_get_winpos(int *x, int *y);
-void gui_mch_set_winpos(int x, int y);
-void gui_mch_set_shellsize(int width, int height, int min_width, int min_height, int base_width, int base_height, int direction);
-void gui_mch_get_screen_dimensions(int *screen_w, int *screen_h);
-void gui_mch_set_text_area_pos(int x, int y, int w, int h);
-void gui_mch_enable_scrollbar(scrollbar_T *sb, int flag);
-void gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max);
-void gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h);
-int gui_mch_get_scrollbar_xpadding(void);
-int gui_mch_get_scrollbar_ypadding(void);
-void gui_mch_create_scrollbar(scrollbar_T *sb, int orient);
-void gui_mch_destroy_scrollbar(scrollbar_T *sb);
-int gui_mch_adjust_charheight(void);
-int gui_mch_init_font(char_u *font_name, int fontset);
-GuiFont gui_mch_get_font(char_u *name, int giveErrorIfMissing);
-char_u *gui_mch_get_fontname(GuiFont font, char_u *name);
-GuiFont gui_mac_find_font(char_u *font_name);
-void gui_mch_set_font(GuiFont font);
-int gui_mch_same_font(GuiFont f1, GuiFont f2);
-void gui_mch_free_font(GuiFont font);
-guicolor_T gui_mch_get_color(char_u *name);
-guicolor_T gui_mch_get_rgb_color(int r, int g, int b);
-void gui_mch_set_fg_color(guicolor_T color);
-void gui_mch_set_bg_color(guicolor_T color);
-void gui_mch_set_sp_color(guicolor_T color);
-void gui_mch_draw_string(int row, int col, char_u *s, int len, int flags);
-int gui_mch_haskey(char_u *name);
-void gui_mch_beep(void);
-void gui_mch_flash(int msec);
-void gui_mch_invert_rectangle(int r, int c, int nr, int nc);
-void gui_mch_iconify(void);
-void gui_mch_settitle(char_u *title, char_u *icon);
-void gui_mch_draw_hollow_cursor(guicolor_T color);
-void gui_mch_draw_part_cursor(int w, int h, guicolor_T color);
-void gui_mch_update(void);
-int gui_mch_wait_for_chars(int wtime);
-void gui_mch_flush(void);
-void gui_mch_clear_block(int row1, int col1, int row2, int col2);
-void gui_mch_clear_all(void);
-void gui_mch_delete_lines(int row, int num_lines);
-void gui_mch_insert_lines(int row, int num_lines);
-void gui_mch_enable_menu(int flag);
-void gui_mch_set_menu_pos(int x, int y, int w, int h);
-/*void gui_mch_add_menu(vimmenu_T *menu, vimmenu_T *parent, int idx);*/
-void gui_mch_add_menu(vimmenu_T *menu, int pos);
-/*void gui_mch_add_menu_item(vimmenu_T *menu, vimmenu_T *parent, int idx);*/
-void gui_mch_add_menu_item(vimmenu_T *menu, int idx);
-void gui_mch_show_popupmenu(vimmenu_T *menu);
-void gui_mch_destroy_menu(vimmenu_T *menu);
-void gui_mch_menu_grey(vimmenu_T *menu, int grey);
-void gui_mch_menu_hidden(vimmenu_T *menu, int hidden);
-void gui_mch_draw_menubar(void);
-int gui_mch_get_lightness(guicolor_T pixel);
-guicolor_T gui_mch_get_rgb(guicolor_T pixel);
-int gui_mch_get_mouse_x(void);
-int gui_mch_get_mouse_y(void);
-void gui_mch_setmouse(int x, int y);
-void gui_mch_show_popupmenu(vimmenu_T *menu);
-int gui_mch_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton, char_u *textfield, int ex_cmd);
-char_u *gui_mch_browse(int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter);
-void gui_mch_set_foreground(void);
-void gui_mch_show_tabline(int showit);
-int gui_mch_showing_tabline(void);
-void gui_mch_update_tabline(void);
-void gui_mch_set_curtab(int nr);
-
-char_u *C2Pascal_save(char_u *Cstring);
-char_u *C2Pascal_save_and_remove_backslash(char_u *Cstring);
-int_u EventModifiers2VimMouseModifiers(EventModifiers macModifiers);
-char_u **new_fnames_from_AEDesc(AEDesc *theList, long *numFiles, OSErr *error);
-
-
-void gui_request_selection(void);
-void gui_mch_lose_selection(void);
-int gui_mch_own_selection(void);
-void gui_mch_clear_selection(void);
-
-void gui_win_new_height(win_T *wp);
-void gui_win_comp_pos(void);
-void gui_win_free(win_T *wp);
-void gui_win_alloc(win_T *wp);
-void mch_post_buffer_write (buf_T *buf);
-
-void mch_errmsg(char *str);
-void mch_display_error(void);
-void clip_mch_lose_selection(Clipboard_T *cbd);
-void clip_mch_request_selection(Clipboard_T *cbd);
-void clip_mch_set_selection(Clipboard_T *cbd);
-int clip_mch_own_selection(Clipboard_T *cbd);
-
-pascal	OSErr	FindProcessBySignature( const OSType targetType,
-					const OSType targetCreator, ProcessSerialNumberPtr psnPtr );
-OSErr   InstallAEHandlers (void);
-pascal OSErr HandleODocAE (const AppleEvent *theAEvent, AppleEvent *theReply, long refCon);
-pascal OSErr Handle_aevt_oapp_AE (const AppleEvent *theAEvent, AppleEvent *theReply, long refCon);
-pascal OSErr Handle_aevt_quit_AE (const AppleEvent *theAEvent, AppleEvent *theReply, long refCon);
-pascal OSErr Handle_aevt_pdoc_AE (const AppleEvent *theAEvent, AppleEvent *theReply, long refCon);
-pascal OSErr Handle_unknown_AE (const AppleEvent *theAEvent, AppleEvent *theReply, long refCon);
-/* Shoulde we return MenuItemIndex? IMO yes, I did that for 5.7 ak*/
-short gui_mac_get_menu_item_index (vimmenu_T *pMenu);
-
-pascal OSErr Handle_KAHL_SRCH_AE (const AppleEvent *theAEvent, AppleEvent *theReply, long refCon);
-pascal OSErr Handle_KAHL_MOD_AE  (const AppleEvent *theAEvent, AppleEvent *theReply, long refCon);
-pascal OSErr Handle_KAHL_GTTX_AE (const AppleEvent *theAEvent, AppleEvent *theReply, long refCon);
-void Send_KAHL_MOD_AE (buf_T *buf);
-
-void gui_mac_doInContentClick(EventRecord *theEvent, WindowPtr	 whichWindow);
-void gui_mac_doInDragClick(Point where, WindowPtr whichWindow);
-void gui_mac_doInGrowClick(Point where, WindowPtr whichWindow);
-void gui_mac_doUpdateEvent(EventRecord *event);
-void gui_mac_doActivateEvent(EventRecord *event);
-void gui_mac_doSuspendEvent(EventRecord *event);
-void gui_mac_doKeyEvent(EventRecord *theEvent);
-void gui_mac_doMouseDownEvent(EventRecord *theEvent);
-void gui_mac_doMouseMovedEvent(EventRecord *event);
-void gui_mac_doMouseUpEvent(EventRecord *theEvent);
-void gui_mch_mousehide(int hide);
-
-int C2PascalString (char_u *CString, Str255 *PascalString);
-int GetFSSpecFromPath ( char_u *file, FSSpec *fileFSSpec);
-char_u *FullPathFromFSSpec_save (FSSpec file);
-
-/* vim: set ft=c : */
diff --git a/src/structs.h b/src/structs.h
index a80de6a..c94fa94 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -2530,9 +2530,6 @@
     dev_t	b_dev;		// device number
     ino_t	b_ino;		// inode number
 #endif
-#ifdef FEAT_CW_EDITOR
-    FSSpec	b_FSSpec;	// MacOS File Identification
-#endif
 #ifdef VMS
     char	 b_fab_rfm;	// Record format
     char	 b_fab_rat;	// Record attribute
@@ -3790,15 +3787,6 @@
     BPictureButton *button;
 # endif
 #endif
-#ifdef FEAT_GUI_MAC
-//  MenuHandle	id;
-//  short	index;		    // the item index within the father menu
-    short	menu_id;	    // the menu id to which this item belongs
-    short	submenu_id;	    // the menu id of the children (could be
-				    // get through some tricks)
-    MenuHandle	menu_handle;
-    MenuHandle	submenu_handle;
-#endif
 #ifdef FEAT_GUI_PHOTON
     PtWidget_t	*id;
     PtWidget_t	*submenu_id;
diff --git a/src/version.c b/src/version.c
index 7411bc0..8ebd3e0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1422,
+/**/
     1421,
 /**/
     1420,
diff --git a/src/vim.h b/src/vim.h
index 1001117..a780ec9 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -97,14 +97,12 @@
 // Unless made through the Makefile enforce GUI on Mac
 #if defined(MACOS_X) && !defined(HAVE_CONFIG_H)
 # define UNIX
-# define FEAT_GUI_MAC
 #endif
 
 #if defined(FEAT_GUI_MOTIF) \
     || defined(FEAT_GUI_GTK) \
     || defined(FEAT_GUI_ATHENA) \
     || defined(FEAT_GUI_HAIKU) \
-    || defined(FEAT_GUI_MAC) \
     || defined(FEAT_GUI_MSWIN) \
     || defined(FEAT_GUI_PHOTON)
 # define FEAT_GUI_ENABLED  // also defined with NO_X11_INCLUDES
@@ -2144,7 +2142,7 @@
 // been seen at that stage.  But it must be before globals.h, where error_ga
 // is declared.
 #if !defined(MSWIN) && !defined(FEAT_GUI_X11) && !defined(FEAT_GUI_HAIKU) \
-	&& !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MAC) && !defined(PROTO)
+	&& !defined(FEAT_GUI_GTK) && !defined(PROTO)
 # define mch_errmsg(str)	fprintf(stderr, "%s", (str))
 # define display_errors()	fflush(stderr)
 # define mch_msg(str)		printf("%s", (str))
@@ -2154,8 +2152,7 @@
 
 # if defined(FEAT_EVAL) \
 	&& (!defined(FEAT_GUI_MSWIN) \
-	     || !(defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME))) \
-	&& !(defined(FEAT_GUI_MAC) && defined(MACOS_CONVERT))
+	     || !(defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME)))
 // Whether IME is supported by im_get_status() defined in mbyte.c.
 // For Win32 GUI it's in gui_w32.c when FEAT_MBYTE_IME or GLOBAL_IME is defined.
 // for Mac it is in gui_mac.c for the GUI or in os_mac_conv.c when
@@ -2166,8 +2163,7 @@
 #if defined(FEAT_XIM) \
 	|| defined(IME_WITHOUT_XIM) \
 	|| (defined(FEAT_GUI_MSWIN) \
-	    && (defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME))) \
-	|| defined(FEAT_GUI_MAC)
+	    && (defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME)))
 // im_set_active() is available
 # define HAVE_INPUT_METHOD
 #endif
