From 571a58f02ae07fa47a40c9c1cf69c089bb722196 Mon Sep 17 00:00:00 2001
From: Kazuki Sakamoto <sakamoto@splhack.org>
Date: Sat, 25 Apr 2009 16:35:18 +0900
Subject: [PATCH] Fixed im_get_status

---
 src/MacVim/MMAtsuiTextView.h  |    1 +
 src/MacVim/MMAtsuiTextView.m  |    5 +++++
 src/MacVim/MMBackend.h        |    4 ++++
 src/MacVim/MMBackend.m        |   14 ++++++++++++++
 src/MacVim/MMTextView.h       |    1 +
 src/MacVim/MMTextView.m       |    5 +++++
 src/MacVim/MMTextViewHelper.h |    2 ++
 src/MacVim/MMTextViewHelper.m |   30 ++++++++++++++++++++++++++++++
 src/MacVim/MMVimController.m  |    8 ++++++--
 src/MacVim/MacVim.h           |    8 ++++++--
 src/MacVim/MacVim.m           |    8 ++++++--
 src/MacVim/gui_macvim.m       |   24 +++++++++++-------------
 12 files changed, 91 insertions(+), 19 deletions(-)

diff --git a/src/MacVim/MMAtsuiTextView.h b/src/MacVim/MMAtsuiTextView.h
index 0219fe4..9a358ff 100644
--- a/src/MacVim/MMAtsuiTextView.h
+++ b/src/MacVim/MMAtsuiTextView.h
@@ -68,6 +68,7 @@ enum { MMMaxCellsPerChar = 2 };
 - (void)setPreEditRow:(int)row column:(int)col;
 - (void)setMouseShape:(int)shape;
 - (void)setAntialias:(BOOL)state;
+- (void)setImControl:(BOOL)enable;
 - (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column;
 - (NSPoint)pointForRow:(int)row column:(int)col;
 - (NSRect)rectForRow:(int)row column:(int)col numRows:(int)nr
diff --git a/src/MacVim/MMAtsuiTextView.m b/src/MacVim/MMAtsuiTextView.m
index 0a42ad6..643badb 100644
--- a/src/MacVim/MMAtsuiTextView.m
+++ b/src/MacVim/MMAtsuiTextView.m
@@ -324,6 +324,11 @@ defaultLineHeightForFont(NSFont *font)
     antialias = state;
 }
 
+- (void)setImControl:(BOOL)enable
+{
+    [helper setImControl:enable];
+}
+
 - (void)keyDown:(NSEvent *)event
 {
     [helper keyDown:event];
diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h
index 2a20228..3fa4c96 100644
--- a/src/MacVim/MMBackend.h
+++ b/src/MacVim/MMBackend.h
@@ -49,6 +49,7 @@
     BOOL                flushDisabled;
     unsigned            numWholeLineChanges;
     unsigned            offsetForDrawDataPrune;
+    BOOL                imState;
 }
 
 + (MMBackend *)sharedInstance;
@@ -131,6 +132,9 @@
 - (void)setWaitForAck:(BOOL)yn;
 - (void)waitForConnectionAcknowledgement;
 
+- (BOOL)imState;
+- (void)setImState:(BOOL)activated;
+
 @end
 
 
diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m
index 50904ff..de19807 100644
--- a/src/MacVim/MMBackend.m
+++ b/src/MacVim/MMBackend.m
@@ -1462,6 +1462,16 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
     waitForAck = NO;
 }
 
+- (BOOL)imState
+{
+    return imState;
+}
+
+- (void)setImState:(BOOL)activated
+{
+    imState = activated;
+}
+
 @end // MMBackend
 
 
@@ -1784,6 +1794,10 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
         [self handleOpenWithArguments:[NSDictionary dictionaryWithData:data]];
     } else if (FindReplaceMsgID == msgid) {
         [self handleFindReplace:[NSDictionary dictionaryWithData:data]];
+    } else if (ActivatedImMsgID == msgid) {
+        [self setImState:YES];
+    } else if (DeactivatedImMsgID == msgid) {
+        [self setImState:NO];
     } else {
         NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid);
     }
diff --git a/src/MacVim/MMTextView.h b/src/MacVim/MMTextView.h
index 2547f60..fd8c450 100644
--- a/src/MacVim/MMTextView.h
+++ b/src/MacVim/MMTextView.h
@@ -32,6 +32,7 @@
 - (void)performBatchDrawWithData:(NSData *)data;
 - (void)setMouseShape:(int)shape;
 - (void)setAntialias:(BOOL)antialias;
+- (void)setImControl:(BOOL)enable;
 
 //
 // MMTextStorage methods
diff --git a/src/MacVim/MMTextView.m b/src/MacVim/MMTextView.m
index e793b77..1a8a87c 100644
--- a/src/MacVim/MMTextView.m
+++ b/src/MacVim/MMTextView.m
@@ -305,6 +305,11 @@
     antialias = state;
 }
 
+- (void)setImControl:(BOOL)enable
+{
+    [helper setImControl:enable];
+}
+
 - (NSFont *)font
 {
     return [(MMTextStorage*)[self textStorage] font];
diff --git a/src/MacVim/MMTextViewHelper.h b/src/MacVim/MMTextViewHelper.h
index 5f56fb7..f07f8d2 100644
--- a/src/MacVim/MMTextViewHelper.h
+++ b/src/MacVim/MMTextViewHelper.h
@@ -39,6 +39,7 @@ enum {
     NSMutableAttributedString  *markedText;
     int                 preEditRow;
     int                 preEditColumn;
+    BOOL                imControl;
 }
 
 - (void)setTextView:(id)view;
@@ -79,5 +80,6 @@ enum {
 - (NSRange)imRange;
 - (void)setMarkedRange:(NSRange)range;
 - (NSRect)firstRectForCharacterRange:(NSRange)range;
+- (void)setImControl:(BOOL)enable;
 
 @end
diff --git a/src/MacVim/MMTextViewHelper.m b/src/MacVim/MMTextViewHelper.m
index f293005..946b5a9 100644
--- a/src/MacVim/MMTextViewHelper.m
+++ b/src/MacVim/MMTextViewHelper.m
@@ -40,6 +40,7 @@ static float MMDragAreaSize = 73.0f;
 - (void)dispatchKeyEvent:(NSEvent *)event;
 - (void)sendKeyDown:(const char *)chars length:(int)len modifiers:(int)flags
           isARepeat:(BOOL)isARepeat;
+- (void)sendImState;
 - (void)hideMouseCursor;
 - (void)startDragTimerWithInterval:(NSTimeInterval)t;
 - (void)dragTimerFired:(NSTimer *)timer;
@@ -91,6 +92,9 @@ static float MMDragAreaSize = 73.0f;
     // TODO: Figure out a way to disable Cocoa key bindings entirely, without
     // affecting input management.
 
+    if (imControl)
+        [self sendImState];
+
     // When the Input Method is activated, some special key inputs
     // should be treated as key inputs for Input Method.
     if ([textView hasMarkedText]) {
@@ -151,6 +155,9 @@ static float MMDragAreaSize = 73.0f;
 
     NSEvent *event = [NSApp currentEvent];
 
+    if (imControl)
+        [self sendImState];
+
     // HACK!  In order to be able to bind to <S-Space>, <S-M-Tab>, etc. we have
     // to watch for them here.
     if ([event type] == NSKeyDown
@@ -202,6 +209,9 @@ static float MMDragAreaSize = 73.0f;
 
     NSEvent *event = [NSApp currentEvent];
 
+    if (imControl)
+        [self sendImState];
+
     if (selector == @selector(cancelOperation:)
             || selector == @selector(insertNewline:)) {
         // HACK! If there was marked text which got abandoned as a result of
@@ -238,6 +248,9 @@ static float MMDragAreaSize = 73.0f;
     // passed to keyDown:.  It seems as if the main menu consumes Cmd-key
     // strokes, unless the key is a function key.
 
+    if (imControl)
+        [self sendImState];
+
     // NOTE: If the event that triggered this method represents a function key
     // down then we do nothing, otherwise the input method never gets the key
     // stroke (some input methods use e.g. arrow keys).  The function key down
@@ -723,6 +736,23 @@ static float MMDragAreaSize = 73.0f;
     return rect;
 }
 
+- (void)setImControl:(BOOL)enable
+{
+    imControl = enable;
+}
+
+- (void)sendImState
+{
+    // IM is active whenever the current script is the system script and the
+    // system script isn't roman.  (Hence IM can only be active when using
+    // non-roman scripts.)
+    SInt32 currentScript = GetScriptManagerVariable(smKeyScript);
+    SInt32 systemScript = GetScriptManagerVariable(smSysScript);
+    BOOL state = currentScript != smRoman && currentScript == systemScript;
+    int msgid = state ? ActivatedImMsgID : DeactivatedImMsgID;
+    [[self vimController] sendMessage:msgid data:nil];
+}
+
 @end // MMTextViewHelper
 
 
diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m
index afdbfb3..4418f11 100644
--- a/src/MacVim/MMVimController.m
+++ b/src/MacVim/MMVimController.m
@@ -788,10 +788,14 @@ static BOOL isUnsafeMessage(int msgid);
                 showWithText:[dict objectForKey:@"text"]
                        flags:[[dict objectForKey:@"flags"] intValue]];
         }
-    } else if (ActivateKeyScriptID == msgid) {
+    } else if (ActivateKeyScriptMsgID == msgid) {
         KeyScript(smKeySysScript);
-    } else if (DeactivateKeyScriptID == msgid) {
+    } else if (DeactivateKeyScriptMsgID == msgid) {
         KeyScript(smKeyRoman);
+    } else if (EnableImControlMsgID == msgid) {
+        [[[windowController vimView] textView] setImControl:YES];
+    } else if (DisableImControlMsgID == msgid) {
+        [[[windowController vimView] textView] setImControl:NO];
     } else if (BrowseForFileMsgID == msgid) {
         NSDictionary *dict = [NSDictionary dictionaryWithData:data];
         if (dict)
diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h
index 0f0b791..359803d 100644
--- a/src/MacVim/MacVim.h
+++ b/src/MacVim/MacVim.h
@@ -169,8 +169,12 @@ enum {
     SetFullscreenColorMsgID,
     ShowFindReplaceDialogMsgID,
     FindReplaceMsgID,
-    ActivateKeyScriptID,
-    DeactivateKeyScriptID,
+    ActivateKeyScriptMsgID,
+    DeactivateKeyScriptMsgID,
+    EnableImControlMsgID,
+    DisableImControlMsgID,
+    ActivatedImMsgID,
+    DeactivatedImMsgID,
     BrowseForFileMsgID,
     ShowDialogMsgID,
     LastMsgID   // NOTE: MUST BE LAST MESSAGE IN ENUM!
diff --git a/src/MacVim/MacVim.m b/src/MacVim/MacVim.m
index a40b93f..a7c586b 100644
--- a/src/MacVim/MacVim.m
+++ b/src/MacVim/MacVim.m
@@ -84,8 +84,12 @@ char *MessageStrings[] =
     "SetFullscreenColorMsgID",
     "ShowFindReplaceDialogMsgID",
     "FindReplaceMsgID",
-    "ActivateKeyScriptID",
-    "DeactivateKeyScriptID",
+    "ActivateKeyScriptMsgID",
+    "DeactivateKeyScriptMsgID",
+    "EnableImControlMsgID",
+    "DisableImControlMsgID",
+    "ActivatedImMsgID",
+    "DeactivatedImMsgID",
     "BrowseForFileMsgID",
     "ShowDialogMsgID",
     "END OF MESSAGE IDs"     // NOTE: Must be last!
diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m
index 5ae2722..c418926 100644
--- a/src/MacVim/gui_macvim.m
+++ b/src/MacVim/gui_macvim.m
@@ -1259,14 +1259,18 @@ im_set_position(int row, int col)
 
 
     void
-im_set_active(int active)
+im_set_control(int enable)
 {
-    // Set roman or the system script if 'active' is TRUE or FALSE,
-    // respectively.
-    SInt32 systemScript = GetScriptManagerVariable(smSysScript);
+    int msgid = enable ? EnableImControlMsgID : DisableImControlMsgID;
+    [[MMBackend sharedInstance] queueMessage:msgid properties:nil];
+}
 
-    if (!p_imdisable && smRoman != systemScript) {
-        int msgid = active ? ActivateKeyScriptID : DeactivateKeyScriptID;
+    void
+im_set_active(int active)
+{
+    if (!p_imdisable) {
+        int msgid = active ? ActivateKeyScriptMsgID : DeactivateKeyScriptMsgID;
+        [[MMBackend sharedInstance] setImState:active];
         [[MMBackend sharedInstance] queueMessage:msgid properties:nil];
     }
 }
@@ -1275,13 +1279,7 @@ im_set_active(int active)
     int
 im_get_status(void)
 {
-    // IM is active whenever the current script is the system script and the
-    // system script isn't roman.  (Hence IM can only be active when using
-    // non-roman scripts.)
-    SInt32 currentScript = GetScriptManagerVariable(smKeyScript);
-    SInt32 systemScript = GetScriptManagerVariable(smSysScript);
-
-    return currentScript != smRoman && currentScript == systemScript;
+    return [[MMBackend sharedInstance] imState];
 }
 
 #endif // defined(USE_IM_CONTROL)
-- 
1.6.0.6

