diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-08-11 21:58:20 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-08-11 21:58:20 +0200 |
commit | 097148e849136b49052b1b5123c714fb1d74db9b (patch) | |
tree | d5b0bf4ce9b435be94de3ff7b87e85ae99c1e484 | |
parent | 4301a729eabafee388aaf8465cf780d3f84cec95 (diff) | |
download | vim-git-097148e849136b49052b1b5123c714fb1d74db9b.tar.gz |
patch 8.2.1422: the Mac GUI implementation is outdatedv8.2.1422
Problem: The Mac GUI implementation is outdated and probably doesn't even
work.
Solution: Remove the Mac GUI code. The MacVim project provides the
supported Vim GUI version.
-rw-r--r-- | Filelist | 2 | ||||
-rw-r--r-- | src/INSTALLmac.txt | 24 | ||||
-rw-r--r-- | src/Makefile | 18 | ||||
-rwxr-xr-x | src/auto/configure | 118 | ||||
-rw-r--r-- | src/configure.ac | 82 | ||||
-rw-r--r-- | src/evalfunc.c | 8 | ||||
-rw-r--r-- | src/feature.h | 20 | ||||
-rw-r--r-- | src/fileio.c | 6 | ||||
-rw-r--r-- | src/globals.h | 6 | ||||
-rw-r--r-- | src/gui.c | 6 | ||||
-rw-r--r-- | src/gui.h | 37 | ||||
-rw-r--r-- | src/gui_mac.c | 6706 | ||||
-rw-r--r-- | src/if_mzsch.c | 14 | ||||
-rw-r--r-- | src/main.c | 39 | ||||
-rw-r--r-- | src/misc2.c | 2 | ||||
-rw-r--r-- | src/mouse.c | 4 | ||||
-rw-r--r-- | src/option.h | 3 | ||||
-rw-r--r-- | src/optiondefs.h | 12 | ||||
-rw-r--r-- | src/os_mac.h | 19 | ||||
-rw-r--r-- | src/os_mac_conv.c | 2 | ||||
-rw-r--r-- | src/os_unix.c | 4 | ||||
-rw-r--r-- | src/proto.h | 3 | ||||
-rw-r--r-- | src/proto/gui_mac.pro | 153 | ||||
-rw-r--r-- | src/structs.h | 12 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 10 |
26 files changed, 48 insertions, 7264 deletions
@@ -642,13 +642,11 @@ SRC_HAIKU = \ SRC_MAC = \ src/INSTALLmac.txt \ src/dehqx.py \ - src/gui_mac.c \ src/os_mac_rsrc/*.icns \ src/os_mac.h \ src/os_mac.rsr.hqx \ src/os_mac_conv.c \ src/os_macosx.m \ - src/proto/gui_mac.pro \ src/proto/os_mac_conv.pro \ # source files for VMS (in the extra archive) diff --git a/src/INSTALLmac.txt b/src/INSTALLmac.txt index e957682a1..ac122c351 100644 --- a/src/INSTALLmac.txt +++ b/src/INSTALLmac.txt @@ -16,7 +16,7 @@ Summary ---------------------------------------------------------------------------- 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 @@ MacOS Classic is no longer supported. If you really want it use Vim 6.4. 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 @@ MacOS Classic is no longer supported. If you really want it use Vim 6.4. 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 @@ MacOS Classic is no longer supported. If you really want it use Vim 6.4. ./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 5d73fc91a..35fe41e74 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1373,24 +1373,6 @@ PHOTONGUI_MAN_TARGETS = yes 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 54ee35d87..fcb2f40e8 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -829,7 +829,6 @@ enable_gtk3_check enable_motif_check enable_athena_check enable_nextaw_check -enable_carbon_check enable_gtktest with_gnome_includes with_gnome_libs @@ -1509,7 +1508,6 @@ Optional Features: --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 @@ rm -f core conftest.err conftest.$ac_objext \ 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 + + 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. +# 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 @@ fi 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_ATHENA=YES SKIP_NEXTAW=YES SKIP_PHOTON=YES SKIP_HAIKU=YES -SKIP_CARBON=YES GUITYPE=NONE if test "x$HAIKU" = "xyes"; then @@ -9247,25 +9232,6 @@ $as_echo "Sorry, $enable_gui GUI is not supported" >&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 @@ $as_echo "yes/auto - automatic GUI support" >&6; } 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 @@ $as_echo "$enable_nextaw_check" >&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 @@ fi 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 "yes, we need AppKit" >&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 054ea1dcb..8a5216a8a 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -262,16 +262,6 @@ if test "`(uname) 2>/dev/null`" = Darwin; then 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_ATHENA=YES SKIP_NEXTAW=YES SKIP_PHOTON=YES SKIP_HAIKU=YES -SKIP_CARBON=YES GUITYPE=NONE if test "x$HAIKU" = "xyes"; then @@ -2432,20 +2421,6 @@ elif test "x$QNX" = "xyes" -a "x$with_x" = "xno" ; then 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 @@ else 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 @@ if test "x$SKIP_NEXTAW" != "xYES" -a "$enable_gui_canon" != "nextaw"; then 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 @@ fi 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 @@ if test "$MACOS_X" = "yes"; then 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 5607ef9e5..bbc3404e5 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -3920,13 +3920,7 @@ f_has(typval_T *argvars, typval_T *rettv) 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 49175272f..0c68f79f2 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 189d4f41a..361109313 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -403,11 +403,6 @@ readfile( */ 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 @@ shorten_fnames(int force) #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 72b8a1e46..f64a874e4 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1569,7 +1569,7 @@ EXTERN char e_failed[] INIT(= N_("E472: Command failed")); #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_colon_required[] INIT(= N_("E1050: Colon required before a range") 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")); @@ -56,7 +56,7 @@ static int disable_flush = 0; // If > 0, gui_mch_flush() is disabled. * 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 @@ gui_exit(int rc) } #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 @@ gui_position_components(int total_width UNUSED) #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 @@ -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 @@ typedef struct GuiScrollbar #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 @@ typedef struct Gui #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 @@ typedef struct Gui 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 @@ typedef enum # 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 b19061705..000000000 --- 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 bfcdbea97..7b5293670 100644 --- a/src/if_mzsch.c +++ b/src/if_mzsch.c @@ -812,10 +812,6 @@ static guint timer_id = 0; #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 @@ timer_proc(gpointer data UNUSED) # 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 @@ setup_timer(void) 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 @@ remove_timer(void) 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 86156b728..c87fdbfb5 100644 --- a/src/main.c +++ b/src/main.c @@ -298,33 +298,6 @@ main 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 @@ parse_command_name(mparm_T *parmp) 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 3e16c3633..0370bdf0d 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -3341,7 +3341,7 @@ same_directory(char_u *f1, char_u *f2) } #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 56472a3f0..7af90494f 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -116,7 +116,7 @@ find_end_of_word(pos_T *pos) #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 @@ do_mouse( 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 7777bd689..421ee7acd 100644 --- a/src/option.h +++ b/src/option.h @@ -701,9 +701,6 @@ EXTERN int p_lpl; // 'loadplugins' #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 f1f1af309..9afa84df5 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -331,13 +331,8 @@ static struct vimoption options[] = #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 @@ static struct vimoption options[] = {"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 @@ static struct vimoption options[] = #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 d052bb5d2..652460915 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 6c52e7d20..3daf74a48 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 c9b3f92ff..0f61367f2 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -2194,7 +2194,7 @@ mch_settitle(char_u *title, char_u *icon) 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 @@ mch_settitle(char_u *title, char_u *icon) 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 e894987ba..e715ca41b 100644 --- a/src/proto.h +++ b/src/proto.h @@ -323,9 +323,6 @@ extern char *vim_SelFile(Widget toplevel, char *prompt, char *init_path, int (*s # 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 1fa34532b..000000000 --- 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 a80de6a71..c94fa94e2 100644 --- a/src/structs.h +++ b/src/structs.h @@ -2530,9 +2530,6 @@ struct file_buffer 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 @@ struct VimMenu 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 7411bc0d8..8ebd3e0ad 100644 --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1422, +/**/ 1421, /**/ 1420, @@ -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 @@ typedef enum { // 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 @@ typedef enum { # 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 @@ typedef enum { #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 |