/* 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 CodeWarior 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 wher
 */
    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 scollbar */

	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 meny 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 msut 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;
    return FAIL;
}

/*
 * 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 checl (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;
	/* Limite 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 th edialog (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 devoice with one button.
	 * This will probably be the standad mouse
	 * startat 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 fuill 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 function used here are available in Carbon, but
     * do nothing une 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 vims 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 modifieable 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
