summaryrefslogtreecommitdiffstats
path: root/src/gui_mac.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2005-02-22 08:49:11 +0000
committerBram Moolenaar <Bram@vim.org>2005-02-22 08:49:11 +0000
commit26a60b45245080771bc2452b2634cb1f5acd60ed (patch)
tree82a54fd6544b2c2a57b5c52cb4d64c42dcd640a3 /src/gui_mac.c
parentdf177f679e950a2ab2ad5fe7d45c1daface004d7 (diff)
updated for version 7.0051
Diffstat (limited to 'src/gui_mac.c')
-rw-r--r--src/gui_mac.c721
1 files changed, 661 insertions, 60 deletions
diff --git a/src/gui_mac.c b/src/gui_mac.c
index dbdda8a0da..b43aec0e5c 100644
--- a/src/gui_mac.c
+++ b/src/gui_mac.c
@@ -91,6 +91,19 @@ static OSType _ftype = 'TEXT';
static EventHandlerUPP mouseWheelHandlerUPP = NULL;
#endif
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+# define USE_CARBONKEYHANDLER
+static EventHandlerUPP keyEventHandlerUPP = NULL;
+/* Defined in os_mac_conv.c */
+extern char_u *mac_utf16_to_enc __ARGS((UniChar *from, size_t fromLen, size_t *actualLen));
+extern UniChar *mac_enc_to_utf16 __ARGS((char_u *from, size_t fromLen, size_t *actualLen));
+extern CFStringRef mac_enc_to_cfstring __ARGS((char_u *from, size_t fromLen));
+#endif
+
+#ifdef MACOS_X
+SInt32 gMacSystemVersion;
+#endif
+
/* Debugging feature: start Vim window OFFSETed */
#undef USE_OFFSETED_WINDOW
@@ -213,6 +226,12 @@ static struct
} gFontPanelInfo = { 0, 0, 0, false };
#endif
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+# define USE_ATSUI_DRAWING
+ATSUStyle gFontStyle;
+Boolean gIsFontFallbackSet;
+#endif
+
/*
* The Quickdraw global is predefined in CodeWarior
* but is not in Apple MPW
@@ -504,6 +523,63 @@ points_to_pixels(char_u *str, char_u **end, int vertical)
return pixels;
}
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+/*
+ * 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(menu)
+ vimmenu_T *menu;
+{
+ CFStringRef name;
+ size_t menuTitleLen;
+ CFIndex displayLen;
+ CFRange mnemonicStart;
+ CFRange mnemonicEnd;
+ CFMutableStringRef cleanedName;
+
+ menuTitleLen = STRLEN(menu->dname);
+ name = 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.
@@ -1231,20 +1307,19 @@ HandleODocAE(const AppleEvent *theAEvent, AppleEvent *theReply, long refCon)
/* Select the text if possible */
if (gotPosition)
{
- VIsual_active = TRUE;
- VIsual_select = FALSE;
- if (thePosition.lineNum < 0)
+ VIsual_active = TRUE;
+ VIsual_select = FALSE;
+ VIsual = curwin->w_cursor;
+ if (thePosition.lineNum < 0)
{
- VIsual_mode = 'v';
- VIsual = curwin->w_cursor;
- goto_byte(thePosition.endRange);
- }
- else
+ VIsual_mode = 'v';
+ goto_byte(thePosition.endRange);
+ }
+ else
{
- VIsual_mode = 'V';
- VIsual = curwin->w_cursor;
- VIsual.col = 0;
- }
+ VIsual_mode = 'V';
+ VIsual.col = 0;
+ }
}
#endif
setcursor();
@@ -1541,25 +1616,47 @@ InstallFontPanelHandler()
* 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;
- Boolean isBold = false, isItalic = false;
+ Str255 buf;
+ ByteCount fontNameLen = 0;
+ ATSUFontID fid;
+ char_u styleString[FONT_STYLE_BUFFER_SIZE];
if (!outName)
return;
- (void)FMGetFontFamilyName(gFontPanelInfo.family, buf);
- p2cstrcpy(outName, buf);
+ if (FMGetFontFamilyName(gFontPanelInfo.family, buf) == noErr)
+ {
+ /* Canonicalize localized font names */
+ if (FMGetFontFromFontFamilyInstance(gFontPanelInfo.family,
+ gFontPanelInfo.style, &fid, NULL) != noErr)
+ return;
-#if 0 /* TODO: enable when styles are supported in gui_mac_find_font() */
- isBold = (gFontPanelInfo.style & bold);
- isItalic = (gFontPanelInfo.style & italic);
-#endif
+ /* Request font name with Mac encoding (otherwise we could
+ * get an unwanted utf-16 name) */
+ if (ATSUFindFontName(fid, kFontFullName, kFontMacintoshPlatform,
+ kFontNoScriptCode, kFontNoLanguageCode,
+ 255, outName, &fontNameLen, NULL) != noErr)
+ return;
- sprintf(&outName[buf[0]], ":h%d%s%s", gFontPanelInfo.size,
- (isBold ? ":b" : ""), (isItalic ? ":i" : ""));
+ /* Only encode font size, because style (bold, italic, etc) is
+ * already part of the font full name */
+ snprintf(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 = NULL;
+ }
}
#endif
@@ -2213,7 +2310,187 @@ gui_mac_doSuspendEvent(event)
/*
* Handle the key
*/
+#ifdef USE_CARBONKEYHANDLER
+# define INLINE_KEY_BUFFER_SIZE 80
+ static pascal OSStatus
+gui_mac_doKeyEventCarbon(EventHandlerCallRef nextHandler, EventRef theEvent,
+ void *data)
+{
+ /* Multibyte-friendly key event handler */
+ OSStatus e = -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;
+ size_t encLen;
+ char_u *to = NULL;
+ Boolean isSpecial = FALSE;
+ int i;
+
+ /* Mask the mouse (as per user setting) */
+ if (p_mh)
+ ObscureCursor();
+
+ do
+ {
+ if (noErr != GetEventParameter(theEvent, kEventParamTextInputSendText,
+ typeUnicodeText, NULL, 0, &actualSize, NULL))
+ break;
+
+ text = (UniChar *)alloc(actualSize);
+
+ if (text)
+ {
+ do
+ {
+ if (noErr != GetEventParameter(theEvent,
+ kEventParamTextInputSendText,
+ typeUnicodeText, NULL, actualSize, NULL, text))
+ break;
+ EventRef keyEvent;
+ if (noErr != GetEventParameter(theEvent,
+ kEventParamTextInputSendKeyboardEvent,
+ typeEventRef, NULL, sizeof(EventRef), NULL, &keyEvent))
+ break;
+ if (noErr != GetEventParameter(keyEvent,
+ kEventParamKeyModifiers,
+ typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers))
+ break;
+ if (noErr != GetEventParameter(keyEvent,
+ kEventParamKeyCode,
+ typeUInt32, NULL, sizeof(UInt32), NULL, &key_sym))
+ break;
+ if (noErr != GetEventParameter(keyEvent,
+ kEventParamKeyMacCharCodes,
+ typeChar, NULL, sizeof(char), NULL, &charcode))
+ break;
+
+ key_char = charcode;
+
+ if (modifiers & controlKey)
+ {
+ if ((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;
+
+ text[0] = (UniChar)key_char;
+ modifiers = 0;
+ }
+ }
+
+ if (modifiers & cmdKey)
+#ifndef USE_CMD_KEY
+ break; /* Let system handle Cmd+... */
+#else
+ {
+ /* Intercept CMD-. */
+ if (key_char == '.')
+ got_int = TRUE;
+
+ /* Convert the modifiers */
+ modifiers = EventModifiers2VimModifiers(modifiers);
+
+ /* Following code to simplify and consolidate modifiers
+ * taken liberally from gui_w48.c */
+
+ key_char = simplify_key(key_char, (int *)&modifiers);
+
+ /* remove SHIFT for keys that are already shifted, e.g.,
+ * '(' and '*' */
+ if (key_char < 0x100 &&
+ !isalpha(key_char) && isprint(key_char))
+ modifiers &= ~MOD_MASK_SHIFT;
+
+ /* Interpret META, include SHIFT, etc. */
+ key_char = extract_modifiers(key_char, (int *)&modifiers);
+ if (key_char == CSI)
+ key_char = K_CSI;
+
+ if (modifiers)
+ {
+ result[len++] = CSI;
+ result[len++] = KS_MODIFIER;
+ result[len++] = modifiers;
+ }
+
+ isSpecial = TRUE;
+ }
+#endif
+ else
+ {
+ /* 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 *)&modifiers);
+ isSpecial = TRUE;
+ break;
+ }
+ }
+ }
+
+ 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);
+ e = noErr;
+ }
+ while (0);
+
+ vim_free(text);
+ if (e == noErr)
+ {
+ /* Fake event to wake up WNE (required to get
+ * key repeat working */
+ PostEvent(keyUp, 0);
+ return noErr;
+ }
+ }
+ }
+ while (0);
+
+ return CallNextEventHandler(nextHandler, theEvent);
+}
+#else
void
gui_mac_doKeyEvent(EventRecord *theEvent)
{
@@ -2387,6 +2664,7 @@ gui_mac_doKeyEvent(EventRecord *theEvent)
add_to_input_buf(string, len);
}
+#endif
/*
* Handle MouseClick
@@ -2664,11 +2942,12 @@ gui_mac_handle_event(event)
/* 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 get release */
break;
@@ -2747,7 +3026,27 @@ gui_mac_find_font(font_name)
pFontName[0] = STRLEN(font_name);
*p = c;
+ /* Get the font name, minus the style suffix (:h, etc) */
+#if defined(MACOS_X) && defined(USE_CARBONIZED)
+ 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;
+ }
+#else
GetFNum(pFontName, &font_id);
+#endif
if (font_id == 0)
{
@@ -2767,7 +3066,17 @@ gui_mac_find_font(font_name)
}
}
if (changed)
+#if defined(MACOS_X) && defined(USE_CARBONIZED)
+ if (ATSUFindFontFromName(&pFontName[1], pFontName[0],
+ kFontFullName, kFontNoPlatformCode, kFontNoScriptCode,
+ kFontNoLanguageCode, &fontRef) == noErr)
+ {
+ if (FMGetFontFamilyInstanceFromFont(fontRef, &font_id, &fontStyle) != noErr)
+ font_id = 0;
+ }
+#else
GetFNum(pFontName, &font_id);
+#endif
}
#else
@@ -2782,7 +3091,12 @@ gui_mac_find_font(font_name)
{
/* Oups, the system font was it the one the user want */
+#if defined(MACOS_X) && defined(USE_CARBONIZED)
+ if (FMGetFontFamilyName(systemFont, systemFontname) != noErr)
+ return NOFONT;
+#else
GetFontName(0, systemFontname);
+#endif
if (!EqualString(pFontName, systemFontname, false, false))
return NOFONT;
}
@@ -3079,6 +3393,15 @@ gui_mch_init()
EventTypeSpec eventTypeSpec;
EventHandlerRef mouseWheelHandlerRef;
#endif
+#ifdef USE_CARBONKEYHANDLER
+ EventHandlerRef keyEventHandlerRef;
+#endif
+
+#ifdef MACOS_X
+ if (Gestalt(gestaltSystemVersion, &gMacSystemVersion) != noErr)
+ gMacSystemVersion = 0x1000; /* Default to minimum sensible value */
+#endif
+
#if 1
InitCursor();
@@ -3238,9 +3561,24 @@ gui_mch_init()
}
#endif
+#ifdef USE_CARBONKEYHANDLER
+ eventTypeSpec.eventClass = kEventClassTextInput;
+ eventTypeSpec.eventKind = kEventUnicodeForKeyEvent;
+ keyEventHandlerUPP = NewEventHandlerUPP(gui_mac_doKeyEventCarbon);
+ if (noErr != InstallApplicationEventHandler(keyEventHandlerUPP, 1,
+ &eventTypeSpec, NULL, &keyEventHandlerRef))
+ {
+ keyEventHandlerRef = NULL;
+ DisposeEventHandlerUPP(keyEventHandlerUPP);
+ keyEventHandlerUPP = NULL;
+ }
+#endif
+
+/*
#ifdef FEAT_MBYTE
- set_option_value((char_u *)"termencoding", 0L, (char_u *)"macroman", 0);
+ set_option_value((char_u *)"encoding", 0L, (char_u *)"utf-8", 0);
#endif
+*/
/* TODO: Load bitmap if using TOOLBAR */
return OK;
@@ -3290,11 +3628,21 @@ gui_mch_exit(int rc)
/* TODO: find out all what is missing here? */
DisposeRgn(cursorRgn);
+#ifdef USE_CARBONKEYHANDLER
+ if (keyEventHandlerUPP)
+ DisposeEventHandlerUPP(keyEventHandlerUPP);
+#endif
+
#ifdef USE_MOUSEWHEEL
if (mouseWheelHandlerUPP != NULL)
DisposeEventHandlerUPP(mouseWheelHandlerUPP);
#endif
+#ifdef USE_ATSUI_DRAWING
+ if (gFontStyle)
+ ATSUDisposeStyle(gFontStyle);
+#endif
+
/* Exit to shell? */
exit(rc);
}
@@ -3466,6 +3814,14 @@ gui_mch_init_font(font_name, fontset)
GuiFont font;
char_u used_font_name[512];
+#ifdef USE_ATSUI_DRAWING
+ if (gFontStyle == NULL)
+ {
+ if (ATSUCreateStyle(&gFontStyle) != noErr)
+ gFontStyle = NULL;
+ }
+#endif
+
if (font_name == NULL)
{
/* First try to get the suggested font */
@@ -3523,6 +3879,54 @@ gui_mch_init_font(font_name, fontset)
TextSize(font >> 16);
TextFont(font & 0xFFFF);
+#ifdef USE_ATSUI_DRAWING
+ ATSUFontID fontID;
+ Fixed fontSize;
+ ATSStyleRenderingOptions fontOptions;
+
+ if (gFontStyle)
+ {
+ fontID = font & 0xFFFF;
+ fontSize = Long2Fix(font >> 16);
+
+ /* No antialiasing by default (do not attempt to touch antialising
+ * options on pre-Jaguar) */
+ fontOptions =
+#ifdef MACOS_X
+ (gMacSystemVersion >= 0x1020) ?
+ kATSStyleNoAntiAliasing :
+#endif
+ kATSStyleNoOptions;
+
+ ATSUAttributeTag attribTags[] =
+ {
+ kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag,
+ kATSUMaxATSUITagValue+1
+ };
+ ByteCount attribSizes[] =
+ {
+ sizeof(ATSUFontID), sizeof(Fixed),
+ sizeof(ATSStyleRenderingOptions), sizeof font
+ };
+ ATSUAttributeValuePtr attribValues[] =
+ {
+ &fontID, &fontSize, &fontOptions, &font
+ };
+
+ /* Convert font id to ATSUFontID */
+ if (FMGetFontFromFontFamilyInstance(fontID, 0, &fontID, NULL) == noErr)
+ {
+ if (ATSUSetAttributes(gFontStyle,
+ (sizeof attribTags)/sizeof(ATSUAttributeTag),
+ attribTags, attribSizes, attribValues) != noErr)
+ {
+ ATSUDisposeStyle(gFontStyle);
+ gFontStyle = NULL;
+ }
+ }
+ }
+#endif
+
GetFontInfo(&font_info);
gui.char_ascent = font_info.ascent;
@@ -3592,9 +3996,99 @@ gui_mch_get_fontname(font, name)
gui_mch_set_font(font)
GuiFont font;
{
- /*
- * TODO: maybe avoid set again the current font.
- */
+#ifdef USE_ATSUI_DRAWING
+ GuiFont currFont;
+ ByteCount actualFontByteCount;
+ ATSUFontID fontID;
+ Fixed fontSize;
+ ATSStyleRenderingOptions fontOptions;
+
+ if (gFontStyle)
+ {
+ /* Avoid setting same font again */
+ if (ATSUGetAttribute(gFontStyle, kATSUMaxATSUITagValue+1, sizeof font,
+ &currFont, &actualFontByteCount) == noErr &&
+ actualFontByteCount == (sizeof font))
+ {
+ if (currFont == font)
+ return;
+ }
+
+ fontID = font & 0xFFFF;
+ fontSize = Long2Fix(font >> 16);
+ /* Respect p_antialias setting only for wide font.
+ * The reason for doing this at the moment is a bit complicated,
+ * but it's mainly because a) latin (non-wide) aliased fonts
+ * look bad in OS X 10.3.x and below (due to a bug in ATS), and
+ * b) wide multibyte input does not suffer from that problem. */
+ fontOptions =
+#ifdef MACOS_X
+ (p_antialias && (font == gui.wide_font)) ?
+ kATSStyleNoOptions : kATSStyleNoAntiAliasing;
+#else
+ kATSStyleNoOptions;
+#endif
+
+ ATSUAttributeTag attribTags[] =
+ {
+ kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag,
+ kATSUMaxATSUITagValue+1
+ };
+ ByteCount attribSizes[] =
+ {
+ sizeof(ATSUFontID), sizeof(Fixed),
+ sizeof(ATSStyleRenderingOptions), sizeof font
+ };
+ ATSUAttributeValuePtr attribValues[] =
+ {
+ &fontID, &fontSize, &fontOptions, &font
+ };
+
+ if (FMGetFontFromFontFamilyInstance(fontID, 0, &fontID, NULL) == noErr)
+ {
+ if (ATSUSetAttributes(gFontStyle,
+ (sizeof attribTags)/sizeof(ATSUAttributeTag),
+ attribTags, attribSizes, attribValues) != noErr)
+ {
+#ifndef NDEBUG
+ fprintf(stderr, "couldn't set font style\n");
+#endif
+ ATSUDisposeStyle(gFontStyle);
+ gFontStyle = NULL;
+ }
+ }
+
+ }
+
+ if (!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);
}
@@ -3820,9 +4314,17 @@ gui_mch_draw_string(row, col, s, len, flags)
int flags;
{
#if defined(FEAT_GUI) && defined(MACOS_X)
+#ifndef USE_ATSUI_DRAWING
SInt32 sys_version;
#endif
+#endif
#ifdef FEAT_MBYTE
+#ifdef USE_ATSUI_DRAWING
+ /* ATSUI requires utf-16 strings */
+ UniCharCount utf16_len;
+ UniChar *tofree = mac_enc_to_utf16(s, len, (size_t *)&utf16_len);
+ utf16_len /= sizeof(UniChar);
+#else
char_u *tofree = NULL;
if (output_conv.vc_type != CONV_NONE)
@@ -3832,8 +4334,11 @@ gui_mch_draw_string(row, col, s, len, flags)
s = tofree;
}
#endif
+#endif
#if defined(FEAT_GUI) && defined(MACOS_X)
+ /* ATSUI automatically antialiases text */
+#ifndef USE_ATSUI_DRAWING
/*
* On OS X, try using Quartz-style text antialiasing.
*/
@@ -3845,8 +4350,9 @@ gui_mch_draw_string(row, col, s, len, flags)
/* Quartz antialiasing is available only in OS 10.2 and later. */
UInt32 qd_flags = (p_antialias ?
kQDUseCGTextRendering | kQDUseCGTextMetrics : 0);
- (void)SwapQDTextFlags(qd_flags);
+ QDSwapTextFlags(qd_flags);
}
+#endif
/*
* When antialiasing we're using srcOr mode, we have to clear the block
@@ -3857,18 +4363,37 @@ gui_mch_draw_string(row, col, s, len, flags)
* 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.
*/
+#ifdef USE_ATSUI_DRAWING
+ if ((flags & DRAW_TRANSP) == 0)
+#else
if (((sys_version >= 0x1020 && p_antialias) || p_linespace != 0)
&& !(flags & DRAW_TRANSP))
+#endif
{
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)
+ {
+ int cell_len = 0;
+ int n;
+
+ /* Compute the length in display cells. */
+ for (n = 0; n < len; n += MB_BYTE2LEN(s[n]))
+ cell_len += (*mb_ptr2cells)(s + n);
+ rc.right = FILL_X(col + cell_len);
+ }
+ else
+#endif
rc.right = FILL_X(col + len) + (col + len == Columns);
rc.bottom = FILL_Y(row + 1);
EraseRect(&rc);
}
+#ifndef USE_ATSUI_DRAWING
if (sys_version >= 0x1020 && p_antialias)
{
StyleParameter face;
@@ -3888,6 +4413,7 @@ gui_mch_draw_string(row, col, s, len, flags)
}
else
#endif
+#endif
{
/* Use old-style, non-antialiased QuickDraw text rendering. */
TextMode(srcCopy);
@@ -3901,6 +4427,25 @@ gui_mch_draw_string(row, col, s, len, flags)
}
MoveTo(TEXT_X(col), TEXT_Y(row));
+#ifdef USE_ATSUI_DRAWING
+ 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);
+ }
+#else
DrawText((char *)s, 0, len);
@@ -3916,6 +4461,7 @@ gui_mch_draw_string(row, col, s, len, flags)
MoveTo(FILL_X(col), FILL_Y(row + 1) - 1);
LineTo(FILL_X(col + len) - 1, FILL_Y(row + 1) - 1);
}
+#endif
}
#ifdef FEAT_MBYTE
@@ -4021,14 +4567,16 @@ gui_mch_draw_hollow_cursor(color)
{
Rect rc;
- gui_mch_set_fg_color(color);
-
/*
* 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);
@@ -4060,7 +4608,8 @@ gui_mch_draw_part_cursor(w, h, color)
gui_mch_set_fg_color(color);
- PaintRect(&rc);
+ FrameRect(&rc);
+// PaintRect(&rc);
}
@@ -4346,11 +4895,11 @@ clip_mch_request_selection(cbd)
if (flavor == 0)
{
- error = GetScrapFlavorFlags(scrap, kScrapFlavorTypeText, &scrapFlags);
+ error = GetScrapFlavorFlags(scrap, kScrapFlavorTypeUnicode, &scrapFlags);
if (error != noErr)
return;
- error = GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &scrapSize);
+ error = GetScrapFlavorSize(scrap, kScrapFlavorTypeUnicode, &scrapSize);
if (error != noErr)
return;
}
@@ -4374,7 +4923,7 @@ clip_mch_request_selection(cbd)
HLock(textOfClip);
#ifdef USE_CARBONIZED
error = GetScrapFlavorData(scrap,
- flavor ? VIMSCRAPFLAVOR : kScrapFlavorTypeText,
+ flavor ? VIMSCRAPFLAVOR : kScrapFlavorTypeUnicode,
&scrapSize, *textOfClip);
#else
scrapSize = GetScrap(textOfClip, 'TEXT', &scrapOffset);
@@ -4387,7 +4936,11 @@ clip_mch_request_selection(cbd)
type = (strchr(*textOfClip, '\r') != NULL) ? MLINE : MCHAR;
tempclip = lalloc(scrapSize + 1, TRUE);
+#if defined(FEAT_MBYTE) && defined(USE_CARBONIZED)
+ mch_memmove(tempclip, *textOfClip + flavor, scrapSize);
+#else
STRNCPY(tempclip, *textOfClip + flavor, scrapSize);
+#endif
tempclip[scrapSize] = 0;
searchCR = (char *)tempclip;
@@ -4400,19 +4953,15 @@ clip_mch_request_selection(cbd)
}
-#ifdef FEAT_MBYTE
- if (input_conv.vc_type != CONV_NONE)
+#if defined(FEAT_MBYTE) && defined(USE_CARBONIZED)
+ /* Convert from utf-16 (clipboard) */
+ size_t encLen = 0;
+ char_u *to = mac_utf16_to_enc((UniChar *)tempclip, scrapSize, &encLen);
+ if (to)
{
- char_u *to;
- int l = scrapSize;
-
- to = string_convert(&input_conv, tempclip, &l);
- if (to != NULL)
- {
- vim_free(tempclip);
- tempclip = to;
- scrapSize = l;
- }
+ scrapSize = encLen;
+ vim_free(tempclip);
+ tempclip = to;
}
#endif
clip_yank_selection(type, tempclip, scrapSize, cbd);
@@ -4471,19 +5020,14 @@ clip_mch_set_selection(cbd)
type = clip_convert_selection(&str, (long_u *) &scrapSize, cbd);
-#ifdef FEAT_MBYTE
- if (str != NULL && output_conv.vc_type != CONV_NONE)
+#if defined(FEAT_MBYTE) && defined(USE_CARBONIZED)
+ size_t utf16_len = 0;
+ UniChar *to = mac_enc_to_utf16(str, scrapSize, &utf16_len);
+ if (to)
{
- char_u *to;
- int l = scrapSize;
-
- to = string_convert(&output_conv, str, &l);
- if (to != NULL)
- {
- vim_free(str);
- str = to;
- scrapSize = l;
- }
+ scrapSize = utf16_len;
+ vim_free(str);
+ str = (char_u *)to;
}
#endif
@@ -4504,9 +5048,9 @@ clip_mch_set_selection(cbd)
#ifdef USE_CARBONIZED
**textOfClip = type;
- STRNCPY(*textOfClip + 1, str, scrapSize);
+ mch_memmove(*textOfClip + 1, str, scrapSize);
GetCurrentScrap(&scrap);
- PutScrapFlavor(scrap, kScrapFlavorTypeText, kScrapFlavorMaskNone,
+ PutScrapFlavor(scrap, kScrapFlavorTypeUnicode, kScrapFlavorMaskNone,
scrapSize, *textOfClip + 1);
PutScrapFlavor(scrap, VIMSCRAPFLAVOR, kScrapFlavorMaskNone,
scrapSize + 1, *textOfClip);
@@ -4599,7 +5143,11 @@ gui_mch_add_menu(menu, idx)
*/
static long next_avail_id = 128;
long menu_after_me = 0; /* Default to the end */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ CFStringRef name;
+#else
char_u *name;
+#endif
short index;
vimmenu_T *parent = menu->parent;
vimmenu_T *brother = menu->next;
@@ -4625,13 +5173,21 @@ gui_mch_add_menu(menu, idx)
menu_after_me = hierMenu;
/* Convert the name */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ 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 */
#ifdef USE_HELPMENU
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ if (menu->priority == 9999)
+#else
if (STRNCMP(name, "\4Help", 5) == 0)
+#endif
{
menu->submenu_id = kHMHelpMenuID;
menu->submenu_handle = gui.MacOSHelpMenu;
@@ -4644,7 +5200,12 @@ gui_mch_add_menu(menu, idx)
* OSStatus SetMenuTitle(MenuRef, ConstStr255Param title);
*/
menu->submenu_id = next_avail_id;
+#if defined(USE_CARBONIZED) && 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++;
}
@@ -4676,13 +5237,21 @@ gui_mch_add_menu(menu, idx)
* to avoid special character recognition by InsertMenuItem
*/
InsertMenuItem(parent->submenu_handle, "\p ", idx); /* afterItem */
+#if defined(USE_CARBONIZED) && 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(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ CFRelease(name);
+#else
vim_free(name);
+#endif
#if 0
/* Done by Vim later on */
@@ -4698,7 +5267,11 @@ gui_mch_add_menu_item(menu, idx)
vimmenu_T *menu;
int idx;
{
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ CFStringRef name;
+#else
char_u *name;
+#endif
vimmenu_T *parent = menu->parent;
int menu_inserted;
@@ -4710,7 +5283,11 @@ gui_mch_add_menu_item(menu, idx)
for older OS call GetMenuItemData (menu, item, isCommandID?, data) */
/* Convert the name */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ 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;
@@ -4796,15 +5373,23 @@ gui_mch_add_menu_item(menu, idx)
if (!menu_inserted)
InsertMenuItem(parent->submenu_handle, "\p ", idx); /* afterItem */
/* Set the menu item name. */
+#if defined(USE_CARBONIZED) && 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(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ CFRelease(name);
+#else
/* TODO: Can name be freed? */
vim_free(name);
+#endif
}
void
@@ -5811,17 +6396,33 @@ gui_mch_settitle(title, 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.
*/
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ CFStringRef windowTitle;
+ size_t windowTitleLen;
+#else
char_u *pascalTitle;
+#endif
if (title == NULL) /* nothing to do */
return;
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ windowTitleLen = STRLEN(title);
+ windowTitle = 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