/* vi:set ts=8 sts=4 sw=4:
 *
 * 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!'
#ifdef FEAT_MBYTE
# define SCRAPTEXTFLAVOR kScrapFlavorTypeUnicode
#else
# define SCRAPTEXTFLAVOR kScrapFlavorTypeText
#endif

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;
# ifdef FEAT_MBYTE
ATSUStyle   gWideFontStyle;
# endif
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'}, */
#ifndef MACOS_X
    {vk_Delete,		'k', 'b'},
#endif
    {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);
static void gui_mac_dispose_atsui_style(void);
#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 = (char_u **) alloc(*numFiles * sizeof(char_u *));

    /* 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 (buf = firstbuf; buf != NULL; buf = buf->b_next)
	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 (buf = firstbuf; buf != NULL; buf = buf->b_next)
	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 (buf = firstbuf; buf != NULL; buf = buf->b_next)
	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
};

/* 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
	}
    }
 */


#ifdef FEAT_VISUAL
    reset_VIsual();
#endif

    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])) == OK)
	    shorten_fnames(TRUE);

	goto finished;
    }

    /* Handle the drop, :edit to get to the file */
    handle_drop(numFiles, fnames, FALSE);

    /* TODO: Handle the goto/select line more cleanly */
    if ((numFiles == 1) & (gotPosition))
    {
	if (thePosition.lineNum >= 0)
	{
	    lnum = 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(thePosition.startRange + 1);
    }

    /* Update the screen display */
    update_screen(NOT_VALID);
#ifdef FEAT_VISUAL
    /* Select the text if possible */
    if (gotPosition)
    {
	VIsual_active = TRUE;
	VIsual_select = FALSE;
	VIsual = curwin->w_cursor;
	if (thePosition.lineNum < 0)
	{
	    VIsual_mode = 'v';
	    goto_byte(thePosition.endRange);
	}
	else
	{
	    VIsual_mode = 'V';
	    VIsual.col = 0;
	}
    }
#endif
    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 */
/*  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);
*/

#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);
    if (error)
    {
	return error;
    }
#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 = W_WIDTH(curwin) - 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 (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);
	}
    }*/
}

/*
 * ------------------------------------------------------------
 * 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:
#if defined(USE_IM_CONTROL)
		im_on_window_switch(TRUE);
#endif
		return noErr;

	    case kEventWindowDeactivated:
#if defined(USE_IM_CONTROL)
		im_on_window_switch(FALSE);
#endif
		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 = (UniChar *)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);

	    /* Interpret META, include SHIFT, etc. */
	    key_char = extract_modifiers(key_char, (int *)&vimModifiers);
	    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 it's 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
	{
#ifdef FEAT_MBYTE
	    /* 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
#endif
		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
     * it's 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(event)
    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 technic return 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 = (char_u **)alloc(count * sizeof(char_u *));
    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_MBYTE
    set_option_value((char_u *)"encoding", 0L, (char_u *)"utf-8", 0);
#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);
#ifdef FEAT_MBYTE
    if (p_macatsui && gWideFontStyle)
	ATSUDisposeStyle(gWideFontStyle);
#endif
}
#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;
    }
#ifdef FEAT_MBYTE
    if (p_macatsui && gWideFontStyle == NULL)
    {
	if (ATSUCreateStyle(&gWideFontStyle) != noErr)
	    gWideFontStyle = NULL;
    }
#endif

    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)
	    EMSG2(_(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;
	}

#ifdef FEAT_MBYTE
	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
    }
}
#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. */
/*
	ATSUAttributeTag fallbackTags[] = { kATSULineFontFallbacksTag };
	ByteCount fallbackSizes[] = { sizeof(ATSUFontFallbacks) };
	ATSUCreateFontFallbacks(&gFontFallbacks);
	ATSUSetObjFontFallbacks(gFontFallbacks, );
*/
	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(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.
     */
}

    static int
hex_digit(int c)
{
    if (isdigit(c))
	return c - '0';
    c = TOLOWER_ASC(c);
    if (c >= 'a' && c <= 'f')
	return c - 'a' + 10;
    return -1000;
}

/*
 * 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;
//    guicolor_T	color = 0;

    typedef struct guicolor_tTable
    {
	char	    *name;
	guicolor_T  color;
    } guicolor_tTable;

    /*
     * The comment at the end of each line is the source
     * (Mac, Window, Unix) and the number is the unix rgb.txt value
     */
    static guicolor_tTable table[] =
    {
	{"Black",	RGB(0x00, 0x00, 0x00)},
	{"darkgray",	RGB(0x80, 0x80, 0x80)}, /*W*/
	{"darkgrey",	RGB(0x80, 0x80, 0x80)}, /*W*/
	{"Gray",	RGB(0xC0, 0xC0, 0xC0)}, /*W*/
	{"Grey",	RGB(0xC0, 0xC0, 0xC0)}, /*W*/
	{"lightgray",	RGB(0xE0, 0xE0, 0xE0)}, /*W*/
	{"lightgrey",	RGB(0xE0, 0xE0, 0xE0)}, /*W*/
	{"gray10",	RGB(0x1A, 0x1A, 0x1A)}, /*W*/
	{"grey10",	RGB(0x1A, 0x1A, 0x1A)}, /*W*/
	{"gray20",	RGB(0x33, 0x33, 0x33)}, /*W*/
	{"grey20",	RGB(0x33, 0x33, 0x33)}, /*W*/
	{"gray30",	RGB(0x4D, 0x4D, 0x4D)}, /*W*/
	{"grey30",	RGB(0x4D, 0x4D, 0x4D)}, /*W*/
	{"gray40",	RGB(0x66, 0x66, 0x66)}, /*W*/
	{"grey40",	RGB(0x66, 0x66, 0x66)}, /*W*/
	{"gray50",	RGB(0x7F, 0x7F, 0x7F)}, /*W*/
	{"grey50",	RGB(0x7F, 0x7F, 0x7F)}, /*W*/
	{"gray60",	RGB(0x99, 0x99, 0x99)}, /*W*/
	{"grey60",	RGB(0x99, 0x99, 0x99)}, /*W*/
	{"gray70",	RGB(0xB3, 0xB3, 0xB3)}, /*W*/
	{"grey70",	RGB(0xB3, 0xB3, 0xB3)}, /*W*/
	{"gray80",	RGB(0xCC, 0xCC, 0xCC)}, /*W*/
	{"grey80",	RGB(0xCC, 0xCC, 0xCC)}, /*W*/
	{"gray90",	RGB(0xE5, 0xE5, 0xE5)}, /*W*/
	{"grey90",	RGB(0xE5, 0xE5, 0xE5)}, /*W*/
	{"white",	RGB(0xFF, 0xFF, 0xFF)},
	{"darkred",	RGB(0x80, 0x00, 0x00)}, /*W*/
	{"red",		RGB(0xDD, 0x08, 0x06)}, /*M*/
	{"lightred",	RGB(0xFF, 0xA0, 0xA0)}, /*W*/
	{"DarkBlue",	RGB(0x00, 0x00, 0x80)}, /*W*/
	{"Blue",	RGB(0x00, 0x00, 0xD4)}, /*M*/
	{"lightblue",	RGB(0xA0, 0xA0, 0xFF)}, /*W*/
	{"DarkGreen",	RGB(0x00, 0x80, 0x00)}, /*W*/
	{"Green",	RGB(0x00, 0x64, 0x11)}, /*M*/
	{"lightgreen",	RGB(0xA0, 0xFF, 0xA0)}, /*W*/
	{"DarkCyan",	RGB(0x00, 0x80, 0x80)}, /*W ?0x307D7E */
	{"cyan",	RGB(0x02, 0xAB, 0xEA)}, /*M*/
	{"lightcyan",	RGB(0xA0, 0xFF, 0xFF)}, /*W*/
	{"darkmagenta",	RGB(0x80, 0x00, 0x80)}, /*W*/
	{"magenta",	RGB(0xF2, 0x08, 0x84)}, /*M*/
	{"lightmagenta",RGB(0xF0, 0xA0, 0xF0)}, /*W*/
	{"brown",	RGB(0x80, 0x40, 0x40)}, /*W*/
	{"yellow",	RGB(0xFC, 0xF3, 0x05)}, /*M*/
	{"lightyellow",	RGB(0xFF, 0xFF, 0xA0)}, /*M*/
	{"darkyellow",	RGB(0xBB, 0xBB, 0x00)}, /*U*/
	{"SeaGreen",	RGB(0x2E, 0x8B, 0x57)}, /*W 0x4E8975 */
	{"orange",	RGB(0xFC, 0x80, 0x00)}, /*W 0xF87A17 */
	{"Purple",	RGB(0xA0, 0x20, 0xF0)}, /*W 0x8e35e5 */
	{"SlateBlue",	RGB(0x6A, 0x5A, 0xCD)}, /*W 0x737CA1 */
	{"Violet",	RGB(0x8D, 0x38, 0xC9)}, /*U*/
    };

    int		r, g, b;
    int		i;

    if (name[0] == '#' && strlen((char *) name) == 7)
    {
	/* Name is in "#rrggbb" format */
	r = hex_digit(name[1]) * 16 + hex_digit(name[2]);
	g = hex_digit(name[3]) * 16 + hex_digit(name[4]);
	b = hex_digit(name[5]) * 16 + hex_digit(name[6]);
	if (r < 0 || g < 0 || b < 0)
	    return INVALCOLOR;
	return RGB(r, g, b);
    }
    else
    {
	if (STRICMP(name, "hilite") == 0)
	{
	    LMGetHiliteRGB(&MacColor);
	    return (RGB(MacColor.red >> 8, MacColor.green >> 8, MacColor.blue >> 8));
	}
	/* Check if the name is one of the colors we know */
	for (i = 0; i < sizeof(table) / sizeof(table[0]); i++)
	    if (STRICMP(name, table[i].name) == 0)
		return table[i].color;
    }

    /*
     * Last attempt. Look in the file "$VIM/rgb.txt".
     */
    {
#define LINE_LEN 100
	FILE	*fd;
	char	line[LINE_LEN];
	char_u	*fname;

	fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt");
	if (fname == NULL)
	    return INVALCOLOR;

	fd = fopen((char *)fname, "rt");
	vim_free(fname);
	if (fd == NULL)
	    return INVALCOLOR;

	while (!feof(fd))
	{
	    int		len;
	    int		pos;
	    char	*color;

	    fgets(line, LINE_LEN, fd);
	    len = strlen(line);

	    if (len <= 1 || line[len-1] != '\n')
		continue;

	    line[len-1] = '\0';

	    i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos);
	    if (i != 3)
		continue;

	    color = line + pos;

	    if (STRICMP(color, name) == 0)
	    {
		fclose(fd);
		return (guicolor_T) RGB(r, g, b);
	    }
	}
	fclose(fd);
    }

    return INVALCOLOR;
}

/*
 * 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)
{
#ifdef FEAT_MBYTE
    char_u	*tofree = NULL;

    if (output_conv.vc_type != CONV_NONE)
    {
	tofree = string_convert(&output_conv, s, &len);
	if (tofree != NULL)
	    s = tofree;
    }
#endif

    /*
     * 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);
#ifdef FEAT_MBYTE
	/* 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
#endif
	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_UNDERC)
	draw_undercurl(flags, row, col, len);

#ifdef FEAT_MBYTE
    vim_free(tofree);
#endif
}

#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;
	}

#ifdef FEAT_MBYTE
	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
#endif
	{
	    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;
#ifdef FEAT_MBYTE
    if (mb_lefthalve(gui.row, gui.col))
	rc.right += gui.char_width;
#endif
    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 (dragRectControl == kCreateEmpty)
	{
	    dragRgn = NULL;
	    dragRectControl = kNothing;
	}
	else*/ 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(VimClipboard *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 = lalloc(scrapSize+1, TRUE); */
    HLock(textOfClip);
    error = GetScrapFlavorData(scrap,
	    flavor ? VIMSCRAPFLAVOR : SCRAPTEXTFLAVOR,
	    &scrapSize, *textOfClip);
    scrapSize -= flavor;

    if (flavor)
	type = **textOfClip;
    else
	type = MAUTO;

    tempclip = lalloc(scrapSize + 1, TRUE);
    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(VimClipboard *cbd)
{
    /*
     * TODO: Really nothing to do?
     */
}

    int
clip_mch_own_selection(VimClipboard *cbd)
{
    return OK;
}

/*
 * Send the current selection to the clipboard.
 */
    void
clip_mch_set_selection(VimClipboard *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 */
#if defined(FEAT_MBYTE)
    CFStringRef name;
#else
    char_u	*name;
#endif
    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 defined(FEAT_MBYTE)
	if (CreateNewMenu(menu->submenu_id, 0, (MenuRef *)&menu->submenu_handle) == noErr)
	    SetMenuTitleWithCFString((MenuRef)menu->submenu_handle, name);
#else
	menu->submenu_handle = NewMenu(menu->submenu_id, name);
#endif
	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 */
#if defined(FEAT_MBYTE)
	SetMenuItemTextWithCFString(parent->submenu_handle, idx+1, name);
#else
	SetMenuItemText(parent->submenu_handle, idx+1, name);
#endif
	SetItemCmd(parent->submenu_handle, idx+1, 0x1B);
	SetItemMark(parent->submenu_handle, idx+1, menu->submenu_id);
	InsertMenu(menu->submenu_handle, hierMenu);
    }

#if defined(FEAT_MBYTE)
    CFRelease(name);
#else
    vim_free(name);
#endif

#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)
{
#if defined(FEAT_MBYTE)
    CFStringRef name;
#else
    char_u	*name;
#endif
    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, FALSE, FALSE);
	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. */
#if defined(FEAT_MBYTE)
    SetMenuItemTextWithCFString(parent->submenu_handle, idx+1, name);
#else
    SetMenuItemText(parent->submenu_handle, idx+1, name);
#endif

#if 0
    /* Called by Vim */
    DrawMenuBar();
#endif

#if defined(FEAT_MBYTE)
    CFRelease(name);
#else
    /* TODO: Can name be freed? */
    vim_free(name);
#endif
}

    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) %x, %x,%x\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 (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);
    }*/
    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
}

    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
}


/*
 * 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)
{
    /* TODO: TODO: TODO: TODO: */
/*    blink_waittime = wait;
    blink_ontime = on;
    blink_offtime = off;*/
}

/*
 * Stop the cursor blinking.  Show the cursor if it wasn't shown.
 */
    void
gui_mch_stop_blink(void)
{
    gui_update_cursor(TRUE, FALSE);
    /* TODO: TODO: TODO: TODO: */
/*    gui_w32_rm_blink_timer();
    if (blink_state == BLINK_OFF)
    gui_update_cursor(TRUE, FALSE);
    blink_state = BLINK_NONE;*/
}

/*
 * 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 (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);
    }*/
}

/*
 * Return the RGB value of a pixel as long.
 */
    long_u
gui_mch_get_rgb(guicolor_T pixel)
{
    return (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 */
    vim_memset(hotKeys, 0, sizeof(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_IM_CONTROL) || defined(PROTO)) && defined(USE_CARBONKEYHANDLER)
/*
 * 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 /* defined(USE_IM_CONTROL) || defined(PROTO) */




#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 (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
	++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"), 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(nr)
    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
