<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>res/xml/kbd_sym.xml</filename>
    </added>
    <added>
      <filename>res/xml/kbd_sym_alt.xml</filename>
    </added>
    <added>
      <filename>src/idv/Zero/KerKerInput/Methods/BPMFInputHelpers/ZhuYinComponentHelper.java</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1 +1 @@
-noseeing
+bin</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -82,83 +82,24 @@ public final class R {
         public static final int noseeing=0x7f050001;
     }
     public static final class string {
-        /**  Title for Latin keyboard  
- Title for Latin keyboard settings activity / dialog 
- Option to provide vibrate/haptic feedback on keypress 
- Option to play back sound on keypress in soft keyboard 
- Option to enable using nearby keys when correcting/predicting 
- Description for hit_correction  
- Option to enable using nearby keys when correcting/predicting in landscape
- Description for hit_correction in landscape 
- Option to automatically correct word on hitting space 
- Description for auto_correction 
- Option to enable text prediction 
- Category title for text prediction 
- Description for text prediction 
- Dialog title for auto complete choices 
- Option to enable text prediction in landscape 
- Description for text prediction 
- Option to enable auto capitalization of sentences 
- Description for auto cap 
- Option to enable auto punctuate 
- Description for auto punctuate 
- Option to enable quick fixes 
- Description for quick fixes 
- Option to enable showing suggestions 
- Description for show suggestions 
- Option to enable auto completion 
- Description for auto completion 
- Array of prediction modes 
- Don't translate 
- Don't translate 
- Don't translate 
- Indicates that a word has been added to the dictionary 
- Accented forms of &quot;a&quot; 
- Accented forms of &quot;e&quot; 
- Accented forms of &quot;i&quot; 
- Accented forms of &quot;o&quot; 
- Accented forms of &quot;u&quot; 
- Letters associated with &quot;s&quot; 
- Accented forms of &quot;n&quot; 
- Accented forms of &quot;c&quot; 
- Accented forms of &quot;y&quot; 
- Accented forms of &quot;z&quot; 
- Tip to long press on keys 
- Tip to dismiss keyboard 
- Tip to press ?123 to access numbers and symbols 
- Tip to long press on typed word to add to dictionary 
- Instruction to touch the bubble to continue 
- Instruction to touch the bubble to start typing 
- Tutorial tip 1 - The keyboard opens any time you touch a text field 
- Tutorial tip 2 - Touch and hold a key to view accents (examples) 
- Tutorial tip 3 - How to switch to number/symbol keyboard 
- Tutorial tip 4 - How to switch back to alphabet keyboard 
- Tutorial tip 5 - How to launch keyboard settings 
- Tutorial tip 6 - Done with the tutorial 
- Label for soft enter key when it performs GO action.  Must be short to fit on key! 
- Label for soft enter key when it performs NEXT action.  Must be short to fit on key! 
- Label for soft enter key when it performs DONE action.  Must be short to fit on key! 
- Label for soft enter key when it performs SEND action.  Must be short to fit on key! 
- Label for &quot;switch to symbols&quot; key.  Must be short to fit on key! 
- Label for &quot;switch to numeric&quot; key.  Must be short to fit on key! 
- Label for &quot;switch to alphabetic&quot; key.  Must be short to fit on key! 
- Label for ALT modifier key.  Must be short to fit on key! 
-         */
         public static final int app_name=0x7f070000;
-        public static final int cancel=0x7f070003;
-        public static final int download=0x7f070004;
-        public static final int label_symbol_key=0x7f070001;
-        public static final int no_such_mapping=0x7f070005;
-        public static final int update_str=0x7f070002;
+        public static final int cancel=0x7f070002;
+        public static final int download=0x7f070003;
+        public static final int label_abc_key=0x7f070005;
+        public static final int label_symbol_key=0x7f070004;
+        public static final int no_such_mapping=0x7f070006;
+        public static final int update_str=0x7f070001;
     }
     public static final class xml {
         public static final int kb_noseeing=0x7f040000;
         public static final int kb_zhuyin=0x7f040001;
         public static final int kbd_popup_template=0x7f040002;
         public static final int kbd_qwerty=0x7f040003;
-        public static final int method=0x7f040004;
-        public static final int popup_domains=0x7f040005;
-        public static final int popup_punctuation=0x7f040006;
-        public static final int popup_smileys=0x7f040007;
+        public static final int kbd_sym=0x7f040004;
+        public static final int kbd_sym_alt=0x7f040005;
+        public static final int method=0x7f040006;
+        public static final int popup_domains=0x7f040007;
+        public static final int popup_punctuation=0x7f040008;
+        public static final int popup_smileys=0x7f040009;
     }
 }</diff>
      <filename>gen/idv/Zero/KerKerInput/R.java</filename>
    </modified>
    <modified>
      <diff>@@ -1,188 +1,14 @@
 &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
-&lt;!--
-/*
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
---&gt;
 &lt;resources xmlns:xliff=&quot;urn:oasis:names:tc:xliff:document:1.2&quot;&gt;
-	
-	
-	
-	
-
-    &lt;!-- Title for Latin keyboard  --&gt;
-    
-    &lt;!-- Title for Latin keyboard settings activity / dialog --&gt;
-    
-
-    &lt;!-- Option to provide vibrate/haptic feedback on keypress --&gt;
-    
-    &lt;!-- Option to play back sound on keypress in soft keyboard --&gt;
-    
-    
-    &lt;!-- Option to enable using nearby keys when correcting/predicting --&gt;
-    
-    
-    &lt;!-- Description for hit_correction  --&gt;
-    
-    
-    &lt;!-- Option to enable using nearby keys when correcting/predicting in landscape--&gt;
-    
-    
-    &lt;!-- Description for hit_correction in landscape --&gt;
-    
-    
-    &lt;!-- Option to automatically correct word on hitting space --&gt;
-     
-    
-    &lt;!-- Description for auto_correction --&gt;
-    
-	
-    &lt;!-- Option to enable text prediction --&gt;
-    
-    &lt;!-- Category title for text prediction --&gt;
-    
-    &lt;!-- Description for text prediction --&gt;
-    
-	
-    &lt;!-- Dialog title for auto complete choices --&gt;
-    
-    
-    &lt;!-- Option to enable text prediction in landscape --&gt;
-     
-    &lt;!-- Description for text prediction --&gt;
-    
-	
-    &lt;!-- Option to enable auto capitalization of sentences --&gt;
-     
-    &lt;!-- Description for auto cap --&gt;
-    
-    &lt;!-- Option to enable auto punctuate --&gt;
-     
-    &lt;!-- Description for auto punctuate --&gt;
-    
-    
-    &lt;!-- Option to enable quick fixes --&gt;
-    
-    &lt;!-- Description for quick fixes --&gt;
-    
-    
-    &lt;!-- Option to enable showing suggestions --&gt;
-    
-    &lt;!-- Description for show suggestions --&gt;
-    
-    
-    &lt;!-- Option to enable auto completion --&gt;
-    
-    &lt;!-- Description for auto completion --&gt;
-    
-    
-    &lt;!-- Array of prediction modes --&gt;
-    
-    
-    &lt;!-- Don't translate --&gt;
-    
-    &lt;!-- Don't translate --&gt;
-    
-    &lt;!-- Don't translate --&gt;
-    
-
-    
-
-    &lt;!-- Indicates that a word has been added to the dictionary --&gt;
-    
-    &lt;!-- Accented forms of &quot;a&quot; --&gt;
-    
-    &lt;!-- Accented forms of &quot;e&quot; --&gt;
-    
-    &lt;!-- Accented forms of &quot;i&quot; --&gt;
-    
-    &lt;!-- Accented forms of &quot;o&quot; --&gt;
-    
-    &lt;!-- Accented forms of &quot;u&quot; --&gt;
-    
-    &lt;!-- Letters associated with &quot;s&quot; --&gt;
-    
-    &lt;!-- Accented forms of &quot;n&quot; --&gt;
-    
-    &lt;!-- Accented forms of &quot;c&quot; --&gt;
-    
-    &lt;!-- Accented forms of &quot;y&quot; --&gt;
-    
-    &lt;!-- Accented forms of &quot;z&quot; --&gt;
-    
-    
-    &lt;!-- Tip to long press on keys --&gt;
-    
-    &lt;!-- Tip to dismiss keyboard --&gt;
-    
-    &lt;!-- Tip to press ?123 to access numbers and symbols --&gt;
-        
-    &lt;!-- Tip to long press on typed word to add to dictionary --&gt;
-    
-        
-    &lt;!-- Instruction to touch the bubble to continue --&gt;
-    
-    
-    &lt;!-- Instruction to touch the bubble to start typing --&gt;
-    
-    
-    &lt;!-- Tutorial tip 1 - The keyboard opens any time you touch a text field --&gt;
-    
-    
-    &lt;!-- Tutorial tip 2 - Touch and hold a key to view accents (examples) --&gt;
-    
-    
-    &lt;!-- Tutorial tip 3 - How to switch to number/symbol keyboard --&gt;
-    
-    
-    &lt;!-- Tutorial tip 4 - How to switch back to alphabet keyboard --&gt;
-    
-    
-    &lt;!-- Tutorial tip 5 - How to launch keyboard settings --&gt;
-    
-    
-    &lt;!-- Tutorial tip 6 - Done with the tutorial --&gt;
-    
-    
-    
-    &lt;!-- Label for soft enter key when it performs GO action.  Must be short to fit on key! --&gt;
-    
-    &lt;!-- Label for soft enter key when it performs NEXT action.  Must be short to fit on key! --&gt;
-    
-    &lt;!-- Label for soft enter key when it performs DONE action.  Must be short to fit on key! --&gt;
-    
-    &lt;!-- Label for soft enter key when it performs SEND action.  Must be short to fit on key! --&gt;
-    
-    &lt;!-- Label for &quot;switch to symbols&quot; key.  Must be short to fit on key! --&gt;
-    
-    &lt;!-- Label for &quot;switch to numeric&quot; key.  Must be short to fit on key! --&gt;
-    
-    &lt;!-- Label for &quot;switch to alphabetic&quot; key.  Must be short to fit on key! --&gt;
-    
-    &lt;!-- Label for ALT modifier key.  Must be short to fit on key! --&gt;
-    
-
 
 &lt;string name=&quot;app_name&quot;&gt;&#31185;&#31185;&#36664;&#20837;&#27861;&lt;/string&gt;
 
-&lt;string name=&quot;label_symbol_key&quot;&gt;\?123&lt;/string&gt;
 &lt;string name=&quot;update_str&quot;&gt;&#31185;&#31185;&#36664;&#20837;&#27861;&#26377;&#26032;&#29256;&#26412;&#20102;&#65281;\n&#29694;&#26377;&#29256;&#26412;&#65306;{CURRENT_VER}\n&#26368;&#26032;&#29256;&#26412;&#65306;{REMOTE_VER}\n{UPDATE_MSG}&#26159;&#21542;&#35201;&#21319;&#32026;&#21602;&#65311;&lt;/string&gt;
 &lt;string name=&quot;cancel&quot;&gt;&#21462;&#28040;&lt;/string&gt;
 &lt;string name=&quot;download&quot;&gt;&#19979;&#36617;&lt;/string&gt;
 
-&lt;string name=&quot;no_such_mapping&quot;&gt;&#25214;&#19981;&#21040;&#23565;&#25033;&lt;/string&gt;
+&lt;string name=&quot;label_symbol_key&quot;&gt;\?123&lt;/string&gt;
+&lt;string name=&quot;label_abc_key&quot;&gt;ABC&lt;/string&gt;
+
+&lt;string name=&quot;no_such_mapping&quot;&gt;&#25214;&#19981;&#21040;&#23565;&#25033;&lt;/string&gt;
 &lt;/resources&gt;</diff>
      <filename>res/values/strings.xml</filename>
    </modified>
    <modified>
      <diff>@@ -42,9 +42,8 @@
     &lt;/Row&gt;
 
 	&lt;Row&gt;
-		&lt;Key android:codes=&quot;-2&quot; android:keyLabel=&quot;@string/label_symbol_key&quot; android:popupKeyboard=&quot;@xml/kbd_popup_template&quot; android:popupCharacters=&quot;&quot;
-			android:keyWidth=&quot;15%p&quot; android:keyEdgeFlags=&quot;left&quot;/&gt;
-		&lt;Key android:codes=&quot;-3&quot; android:keyLabel=&quot;ABC&quot; android:popupKeyboard=&quot;@xml/kbd_popup_template&quot; android:popupCharacters=&quot;&quot; android:keyWidth=&quot;15%p&quot; /&gt;
+		&lt;Key android:codes=&quot;-100&quot; android:keyLabel=&quot;@string/label_symbol_key&quot; android:keyWidth=&quot;15%p&quot; android:keyEdgeFlags=&quot;left&quot;/&gt;
+		&lt;Key android:codes=&quot;-102&quot; android:keyLabel=&quot;ABC&quot; android:keyWidth=&quot;15%p&quot; /&gt;
 		&lt;Key android:codes=&quot;32&quot; android:keyIcon=&quot;@drawable/sym_keyboard_space&quot; android:iconPreview=&quot;@drawable/sym_keyboard_feedback_space&quot; android:keyWidth=&quot;30%p&quot;
 			android:isRepeatable=&quot;true&quot; /&gt;
 		&lt;Key android:codes=&quot;10&quot; android:keyIcon=&quot;@drawable/sym_keyboard_return&quot; android:iconPreview=&quot;@drawable/sym_keyboard_feedback_return&quot; android:keyWidth=&quot;20%p&quot;/&gt;</diff>
      <filename>res/xml/kb_noseeing.xml</filename>
    </modified>
    <modified>
      <diff>@@ -56,9 +56,8 @@
 	&lt;/Row&gt;
 
 	&lt;Row&gt;
-		&lt;Key android:codes=&quot;-2&quot; android:keyLabel=&quot;@string/label_symbol_key&quot; android:popupKeyboard=&quot;@xml/kbd_popup_template&quot; android:popupCharacters=&quot;&quot;
-			android:keyWidth=&quot;15%p&quot; android:keyEdgeFlags=&quot;left&quot;/&gt;
-		&lt;Key android:codes=&quot;-3&quot; android:keyLabel=&quot;ABC&quot; android:popupKeyboard=&quot;@xml/kbd_popup_template&quot; android:popupCharacters=&quot;&quot; android:keyWidth=&quot;15%p&quot; /&gt;
+		&lt;Key android:codes=&quot;-100&quot; android:keyLabel=&quot;@string/label_symbol_key&quot; android:keyWidth=&quot;15%p&quot; android:keyEdgeFlags=&quot;left&quot;/&gt;
+		&lt;Key android:codes=&quot;-102&quot; android:keyLabel=&quot;@string/label_abc_key&quot; android:keyWidth=&quot;15%p&quot;/&gt;
 		&lt;Key android:codes=&quot;32&quot; android:keyIcon=&quot;@drawable/sym_keyboard_space&quot; android:iconPreview=&quot;@drawable/sym_keyboard_feedback_space&quot; android:keyWidth=&quot;30%p&quot;
 			android:isRepeatable=&quot;true&quot; /&gt;
 		&lt;Key android:codes=&quot;10&quot; android:keyIcon=&quot;@drawable/sym_keyboard_return&quot; android:iconPreview=&quot;@drawable/sym_keyboard_feedback_return&quot; android:keyWidth=&quot;20%p&quot;/&gt;</diff>
      <filename>res/xml/kb_zhuyin.xml</filename>
    </modified>
    <modified>
      <diff>@@ -62,15 +62,15 @@
         &lt;Key android:codes=&quot;98&quot; android:keyLabel=&quot;b&quot;/&gt;
         &lt;Key android:codes=&quot;110&quot; android:keyLabel=&quot;n&quot;/&gt;
         &lt;Key android:codes=&quot;109&quot; android:keyLabel=&quot;m&quot;/&gt;
-        &lt;Key android:codes=&quot;-999&quot; android:keyIcon=&quot;@drawable/globe&quot;
+        &lt;Key android:codes=&quot;-104&quot; android:keyIcon=&quot;@drawable/globe&quot;
         		android:iconPreview=&quot;@drawable/globe_feedback&quot;
                 android:keyWidth=&quot;15%p&quot; android:keyEdgeFlags=&quot;right&quot;/&gt;
     &lt;/Row&gt;
 
     &lt;Row android:keyboardMode=&quot;@+id/mode_normal&quot; android:rowEdgeFlags=&quot;bottom&quot;&gt;
-        &lt;Key android:codes=&quot;-2&quot; android:keyLabel=&quot;@string/label_symbol_key&quot; 
+        &lt;Key android:codes=&quot;-100&quot; android:keyLabel=&quot;@string/label_symbol_key&quot; 
                 android:keyWidth=&quot;15%p&quot; /&gt;
-        &lt;Key android:codes=&quot;-4&quot; android:keyLabel=&quot;&#20013;&quot; 
+        &lt;Key android:codes=&quot;-103&quot; android:keyLabel=&quot;&#20013;&quot; 
                 android:keyWidth=&quot;15%p&quot; /&gt;
         &lt;Key android:codes=&quot;32&quot; android:keyIcon=&quot;@drawable/sym_keyboard_space&quot; 
                 android:iconPreview=&quot;@drawable/sym_keyboard_feedback_space&quot;</diff>
      <filename>res/xml/kbd_qwerty.xml</filename>
    </modified>
    <modified>
      <diff>@@ -2,22 +2,28 @@ package idv.Zero.KerKerInput;
 
 import android.inputmethodservice.Keyboard;
 
-public interface IKerKerInputMethod {
+public abstract class IKerKerInputMethod {
+	protected KerKerInputCore _core;
 	
 	/* Input Method Core */
-	public void initInputMethod(KerKerInputCore core);
-	public String getName();
-	public void onEnterInputMethod();
-	public void onExitInputMethod();
+	public void initInputMethod(KerKerInputCore core) { _core = core; }
+	abstract public void onEnterInputMethod();
+	public void onLostFocus()
+	{
+		_core.clearCandidates();
+		_core.hideCandidatesView();
+	}
+	abstract public void destroyInputMethod();
+	abstract public String getName();
 
 	/* Keyboard Events */
-	public Keyboard getDesiredKeyboard();
-	public boolean wantHandleEvent(int keyCode);
-	public boolean onKeyEvent(int keyCode, int[] keyCodes);
-	public void onTextEvent(CharSequence text);
-	public void commitCandidate(int currentCandidate);
+	public Keyboard getDesiredKeyboard() { return null; }
+	public boolean wantHandleEvent(int keyCode) { return (keyCode &gt; -2); }
+	abstract public boolean onKeyEvent(int keyCode, int[] keyCodes);
+	abstract public void commitCandidate(int currentCandidate);
+	public void onTextEvent(CharSequence text) { if (_core != null) _core.getConnection().commitText(text, 1); }
 	
 	/* Candidates Handling */
-	public void setTotalPages(int totalPages);
-	public void setCurrentPage(int currentPage);
+	abstract public void setTotalPages(int totalPages);
+	abstract public void setCurrentPage(int currentPage);
 }</diff>
      <filename>src/idv/Zero/KerKerInput/IKerKerInputMethod.java</filename>
    </modified>
    <modified>
      <diff>@@ -4,6 +4,13 @@ import android.inputmethodservice.Keyboard;
 import android.inputmethodservice.KeyboardView;
 
 public class KBManager {
+	public static final int KEYCODE_SYM = -100;
+	public static final int KEYCODE_SYM_ALT = -101;
+	public static final int KEYCODE_ABC = -102;
+	public static final int KEYCODE_IME = -103;
+	public static final int KEYCODE_NEXT_IME = -104;
+	public static final int KEYCODE_DO_OUTPUT_CHARS = -105;
+	
 	private KerKerInputCore _core = null;
 	private KeyboardView _currentKBView = null;
 	private Keyboard _currentKB = null;
@@ -43,10 +50,10 @@ public class KBManager {
 			setCurrentKeyboardFromResource(R.xml.kbd_qwerty, R.id.mode_normal);
 			break;
 		case MODE_SYM:
-			setCurrentKeyboardFromResource(R.xml.kbd_qwerty, R.id.mode_normal);
+			setCurrentKeyboardFromResource(R.xml.kbd_sym, R.id.mode_normal);
 			break;
 		case MODE_SYM_ALT:
-			setCurrentKeyboardFromResource(R.xml.kbd_qwerty, R.id.mode_normal);
+			setCurrentKeyboardFromResource(R.xml.kbd_sym_alt, R.id.mode_normal);
 			break;
 		case MODE_IME:
 			setCurrentKeyboard(_core.getCurrentInputMethod().getDesiredKeyboard());</diff>
      <filename>src/idv/Zero/KerKerInput/KBManager.java</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,10 @@
 package idv.Zero.KerKerInput;
 
+import idv.Zero.KerKerInput.KBManager.NativeKeyboardTypes;
+
 import java.util.ArrayList;
 import java.util.List;
 
-import android.util.Log;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -21,10 +22,13 @@ import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
 import android.os.Handler;
 
 public class KerKerInputCore implements OnKeyboardActionListener {
+	public enum InputMode { MODE_ABC, MODE_SYM, MODE_SYM_ALT, MODE_IME };
+	
 	private KerKerInputService _frontEnd = null;
 	private KBManager _kbm = null;
 	private ArrayList&lt;IKerKerInputMethod&gt; _methods;
 	private IKerKerInputMethod _currentMethod;
+	private InputMode _currentMode;
 	private CandidatesViewContainer _candidatesContainer;
 	private Handler _handler;
 	private PopupWindow _winMsg;
@@ -36,7 +40,8 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 		_frontEnd = fe;
 		_kbm = new KBManager(this);
 		_methods = new ArrayList&lt;IKerKerInputMethod&gt;();
-		_currentMethod = null;		
+		_currentMethod = null;
+		_currentMode = InputMode.MODE_IME;
 		_handler = new Handler();
 		
 		_pntText = new Paint();
@@ -55,6 +60,7 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 		_winMsg.setContentView(_txtvMsg);
 		
 		registerAvailableInputMethods();
+
 		requestNextInputMethod();
 	}
 	
@@ -103,7 +109,7 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 		else
 		{
 			int curIndex = _methods.indexOf(_currentMethod);
-			_currentMethod.onExitInputMethod();
+			_currentMethod.destroyInputMethod();
 			if (_methods.size() &gt; curIndex + 1)
 				_currentMethod = _methods.get(curIndex + 1);
 			else
@@ -113,17 +119,7 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 		_currentMethod.initInputMethod(this);
 		_currentMethod.onEnterInputMethod();
 		_kbm.setCurrentKeyboard(_currentMethod.getDesiredKeyboard());
-		_handler.postDelayed(new Runnable(){
-			public void run() {
-				try{
-					showPopup(_currentMethod.getName());
-				}
-				catch(Exception e)
-				{
-					e.printStackTrace();
-				}
-			}
-		}, 700);
+		showIMENamePopup(_currentMethod.getName());
 	}
 	
 	public IKerKerInputMethod getCurrentInputMethod()
@@ -157,13 +153,18 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 
 	// Virtual Keyboard input
 	public void onKey(int primaryCode, int[] keyCodes) {
-		if (primaryCode == -999)
+		if (primaryCode == KBManager.KEYCODE_NEXT_IME)
+		{
+			_currentMode = InputMode.MODE_IME;
 			requestNextInputMethod();
-		else if (!_currentMethod.wantHandleEvent(primaryCode))
+		}
+		else if (primaryCode == KBManager.KEYCODE_DO_OUTPUT_CHARS)
+			return; // Let IME onText listener handle it.
+		else if (_currentMode != InputMode.MODE_IME || !_currentMethod.wantHandleEvent(primaryCode))
 		{
 			// If the IME does not want the event, we assume it's an plain-English keyboard.
 			switch(primaryCode) {
-			case -1: // Shift Key
+			case Keyboard.KEYCODE_SHIFT: // Shift Key
 				Boolean isShifted = !_kbm.getCurrentKeyboard().isShifted();
 				_kbm.getCurrentKeyboard().setShifted(isShifted);
 				KeyboardView kv = _kbm.getCurrentKeyboardView();
@@ -172,11 +173,30 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 				// Dirty Hack :( Force KeyboardView wipe out its buffer...
 				kv.onSizeChanged(kv.getWidth(), kv.getHeight(), 0, 0);
 				break;
-			case -2: // 123 Keyboard
-				
+			case KBManager.KEYCODE_SYM: // 123 Keyboard
+				_currentMode = InputMode.MODE_SYM;
+				_kbm.setNativeKeyboard(NativeKeyboardTypes.MODE_SYM);
+				showIMENamePopup(&quot;123&quot;);
+				break;
+			case KBManager.KEYCODE_SYM_ALT: // 123 Keyboard
+				_currentMode = InputMode.MODE_SYM_ALT;
+				_kbm.setNativeKeyboard(NativeKeyboardTypes.MODE_SYM_ALT);
+				showIMENamePopup(&quot;#+=&quot;);
+				break;
+			case KBManager.KEYCODE_ABC: // ABC Keyboard
+				_currentMode = InputMode.MODE_ABC;
+				_kbm.setNativeKeyboard(NativeKeyboardTypes.MODE_ABC);
+				showIMENamePopup(&quot;ABC&quot;);
+				break;
+			case KBManager.KEYCODE_IME: // IME Keyboard
+				_currentMode = InputMode.MODE_IME;
+				_kbm.setNativeKeyboard(NativeKeyboardTypes.MODE_IME);
+				_currentMethod.onEnterInputMethod();
+				showIMENamePopup(_currentMethod.getName());
 				break;
 			case Keyboard.KEYCODE_DELETE:
 				getFrontend().sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+				break;
 			default:
 				if (getKeyboardManager().getCurrentKeyboard().isShifted())
 					getFrontend().sendKeyChar(Character.toUpperCase((char) primaryCode));
@@ -189,37 +209,17 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 			_currentMethod.onKeyEvent(primaryCode, keyCodes);
 	}
 
-	public void onPress(int primaryCode) {
-		// TODO Auto-generated method stub
-		
-	}
-
-	public void onRelease(int primaryCode) {
-	}
-
 	public void onText(CharSequence text) {
 		_currentMethod.onTextEvent(text);
 	}
 
-	public void swipeDown() {
-		// TODO Auto-generated method stub
-		
-	}
-
-	public void swipeLeft() {
-		// TODO Auto-generated method stub
-		
-	}
-
-	public void swipeRight() {
-		// TODO Auto-generated method stub
-		
-	}
-
-	public void swipeUp() {
-		// TODO Auto-generated method stub
-		
-	}
+	// Currently we have nothing to do here...
+	public void onPress(int primaryCode) {}
+	public void onRelease(int primaryCode) {}
+	public void swipeDown() {}
+	public void swipeLeft() {}
+	public void swipeRight() {}
+	public void swipeUp() {}
 
 	public void commitCandidate(int selectedCandidate) {
 		_currentMethod.commitCandidate(selectedCandidate);
@@ -229,6 +229,10 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 		_candidatesContainer.setCandidates(candidates);
 	}
 
+	public void clearCandidates() {
+		_candidatesContainer.setCandidates(new ArrayList&lt;CharSequence&gt;());
+	}
+
 	public void showCandidatesView() {
 		_frontEnd.setCandidatesViewShown(true);
 	}
@@ -241,6 +245,20 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 		getConnection().setComposingText(buf, 1);
 	}
 	
+	public void showIMENamePopup(final String imeName) {
+		_handler.postDelayed(new Runnable(){
+			public void run() {
+				try{
+					showPopup(imeName);
+				}
+				catch(Exception e)
+				{
+					e.printStackTrace();
+				}
+			}
+		}, 400);
+	}
+
 	public void showPopup(int resid)
 	{
 		showPopup(getFrontend().getResources().getString(resid));
@@ -248,7 +266,6 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 	
 	public void showPopup(CharSequence msg)
     {
-		Log.i(&quot;POPUP&quot;, &quot;Going to popup: &quot; + msg);
     	_txtvMsg.setText(msg);
     	_txtvMsg.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
     	int wordWidth = (int)(_pntText.measureText(msg.toString()));
@@ -275,7 +292,7 @@ public class KerKerInputCore implements OnKeyboardActionListener {
 			public void run() {
 				hidePopup();
 			}
-    	}, 1000);
+    	}, 700);
     }
     
     private void hidePopup()</diff>
      <filename>src/idv/Zero/KerKerInput/KerKerInputCore.java</filename>
    </modified>
    <modified>
      <diff>@@ -18,15 +18,12 @@ import android.util.Log;
 import android.view.KeyEvent;
 import idv.Zero.KerKerInput.KerKerInputCore;
 import idv.Zero.KerKerInput.R;
-import idv.Zero.KerKerInput.KBManager.NativeKeyboardTypes;
+import idv.Zero.KerKerInput.Methods.BPMFInputHelpers.ZhuYinComponentHelper;
 
-public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
-	private KerKerInputCore _core;
-	private enum InputMode {MODE_ABC, MODE_SYM, MODE_SYMSHIFT, MODE_BPMF};
+public class BPMFInput extends idv.Zero.KerKerInput.IKerKerInputMethod {
 	private enum InputState {STATE_INPUT, STATE_CHOOSE};
-	private InputMode currentMode;
 	private InputState currentState;
-	private StringBuilder inputBufferRaw = new StringBuilder();
+	private String inputBufferRaw = &quot;&quot;;
 	private List&lt;CharSequence&gt; _currentCandidates;
 	private HashMap&lt;Character, String&gt; K2N;
 	private String _dbpath;
@@ -36,7 +33,8 @@ public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
 	private SQLiteDatabase db;
 	
 	public void initInputMethod(KerKerInputCore core) {
-		_core = core;
+		super.initInputMethod(core);
+		
 		initKeyNameData();
 		_currentPage = 0;
 		_currentCandidates = new ArrayList&lt;CharSequence&gt;();
@@ -48,6 +46,7 @@ public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
 		try
 		{
 			db = SQLiteDatabase.openDatabase(_dbpath, null, SQLiteDatabase.OPEN_READONLY);
+			db.setLocale(Locale.TRADITIONAL_CHINESE);
 		}
 		catch(SQLiteException ex)
 		{
@@ -71,16 +70,19 @@ public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
 			} catch (IOException e) {
 				e.printStackTrace();
 			}			
+			
+			// Copied, re-open it.
+			db = SQLiteDatabase.openDatabase(_dbpath, null, SQLiteDatabase.OPEN_READONLY);
+			db.setLocale(Locale.TRADITIONAL_CHINESE);
 		}
 	}
 	
 	public void onEnterInputMethod()
 	{
-		currentMode = InputMode.MODE_BPMF;
 		currentState = InputState.STATE_INPUT;
 	}
 	
-	public void onExitInputMethod()
+	public void destroyInputMethod()
 	{
 		db.close();
 	}
@@ -95,29 +97,9 @@ public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
 	}
 
 	public boolean onKeyEvent(int keyCode, int[] keyCodes) {
-		if (keyCode == -3)
-		{
-			currentMode = InputMode.MODE_ABC;
-			_core.getKeyboardManager().setNativeKeyboard(NativeKeyboardTypes.MODE_ABC);
-		}
-		else if (keyCode == -4)
-		{
-			currentMode = InputMode.MODE_BPMF;
-			_core.getKeyboardManager().setNativeKeyboard(NativeKeyboardTypes.MODE_IME);
-			currentState = InputState.STATE_INPUT;
-		}
-		else
-		{
-			return handleBPMFKeyEvent(keyCode, keyCodes);
-		}
-		return true;
+		return handleBPMFKeyEvent(keyCode, keyCodes);
 	}
 	
-	public boolean wantHandleEvent(int keyCode)
-	{
-		return (currentMode == InputMode.MODE_BPMF) || keyCode &lt;= -3;
-	}
-
 	private boolean handleBPMFKeyEvent(int keyCode, int[] keyCodes) {
 		if (currentState == InputState.STATE_INPUT)
 		{
@@ -125,7 +107,7 @@ public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
 			{
 				if (inputBufferRaw.length() &gt; 0)
 				{
-					inputBufferRaw.deleteCharAt(inputBufferRaw.length() - 1);
+					inputBufferRaw = inputBufferRaw.substring(0, inputBufferRaw.length() - 1);
 				}
 				else
 					_core.getFrontend().sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
@@ -143,10 +125,10 @@ public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
 			else
 			{
 				char c = (char)keyCode;
-				inputBufferRaw.append(c);
+				inputBufferRaw = ZhuYinComponentHelper.getComposedRawString(inputBufferRaw, Character.toString(c));
 				
 				// &#22914;&#26524;&#26159;&#38899;&#35519;&#31526;&#34399;&#65292;&#30452;&#25509;&#36914;&#20837;&#36984;&#23383;&#27169;&#24335;&#12290;
-				if (c == '3' || c == '4' || c == '6' || c == '7')
+				if (inputBufferRaw.length() &gt; 0 &amp;&amp; (c == '3' || c == '4' || c == '6' || c == '7'))
 					currentState = InputState.STATE_CHOOSE;
 			}
 			_core.setCompositeBuffer(getCompositeString());
@@ -159,7 +141,11 @@ public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
 			case Keyboard.KEYCODE_DELETE:
 				currentState = InputState.STATE_INPUT;
 				if (inputBufferRaw.length() &gt; 0)
-					inputBufferRaw.deleteCharAt(inputBufferRaw.length() - 1);
+				{
+					inputBufferRaw = inputBufferRaw.substring(0, inputBufferRaw.length() - 1);
+					_core.setCompositeBuffer(getCompositeString());
+					updateCandidates();
+				}
 				else
 					Log.e(&quot;BPMFInput&quot;, &quot;InputBuffer is requested to delete, but the buffer is empty&quot;);
 				
@@ -188,7 +174,7 @@ public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
 				    {
 				        commitCandidate(_currentPage * CANDIDATES_PER_PAGE + keyCode - KeyEvent.KEYCODE_0 - 1);
 				        currentState = InputState.STATE_INPUT;
-				        inputBufferRaw.delete(0, inputBufferRaw.length());
+				        inputBufferRaw = &quot;&quot;;
 				    }
 				}
 				break;
@@ -219,19 +205,16 @@ public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
 		
 		try
 		{
-			db = SQLiteDatabase.openDatabase(_dbpath, null, SQLiteDatabase.OPEN_READONLY);
-			db.setLocale(Locale.TRADITIONAL_CHINESE);
 			Cursor currentQuery = db.rawQuery(&quot;Select val from bpmf where key glob '&quot; + inputBufferRaw.toString() + &quot;*'&quot;, null);
 			if (currentQuery.getCount() == 0)
 			{
-				inputBufferRaw.deleteCharAt(inputBufferRaw.length() - 1);
+				inputBufferRaw = inputBufferRaw.substring(0, inputBufferRaw.length() - 1);
 				_currentCandidates.clear();
 				_core.setCompositeBuffer(getCompositeString());
 				_core.showPopup(R.string.no_such_mapping);
 				_core.hideCandidatesView();
 				currentState = InputState.STATE_INPUT;
 				updateCandidates();
-				return;
 			}
 			else
 			{
@@ -246,26 +229,21 @@ public class BPMFInput implements idv.Zero.KerKerInput.IKerKerInputMethod {
 					_currentCandidates.add(ca);
 					currentQuery.moveToNext();
 				}
-				
 				_core.showCandidatesView();
 				_core.setCandidates(_currentCandidates);
 			}
+			currentQuery.close();
 		}
 		catch(Exception e) {}
 		finally
 		{
-			db.close();
 		}
 	}
 
-	public void onTextEvent(CharSequence text) {
-		_core.getConnection().commitText(text, 1);
-	}
-
 	public void commitCandidate(int selectedCandidate) {
 		_core.getConnection().commitText(_currentCandidates.get(selectedCandidate), 1);
 		_core.hideCandidatesView();
-		inputBufferRaw.delete(0, inputBufferRaw.length());
+		inputBufferRaw = &quot;&quot;;
 		currentState = InputState.STATE_INPUT;
 	}
 	</diff>
      <filename>src/idv/Zero/KerKerInput/Methods/BPMFInput.java</filename>
    </modified>
    <modified>
      <diff>@@ -16,12 +16,8 @@ import android.inputmethodservice.Keyboard;
 import android.view.KeyEvent;
 import idv.Zero.KerKerInput.KerKerInputCore;
 import idv.Zero.KerKerInput.R;
-import idv.Zero.KerKerInput.KBManager.NativeKeyboardTypes;
 
-public class NoSeeing implements idv.Zero.KerKerInput.IKerKerInputMethod {
-	private KerKerInputCore _core;
-	private enum InputMode {MODE_ABC, MODE_SYM, MODE_SYMSHIFT, MODE_NOSEEING};
-	private InputMode currentMode;
+public class NoSeeing extends idv.Zero.KerKerInput.IKerKerInputMethod {
 	private StringBuilder inputBufferRaw = new StringBuilder();
 	private List&lt;CharSequence&gt; _currentCandidates;
 	private String _dbpath;
@@ -31,7 +27,8 @@ public class NoSeeing implements idv.Zero.KerKerInput.IKerKerInputMethod {
 	private SQLiteDatabase db;
 	
 	public void initInputMethod(KerKerInputCore core) {
-		_core = core;
+		super.initInputMethod(core);
+		
 		_currentPage = 0;
 		_currentCandidates = new ArrayList&lt;CharSequence&gt;();
 
@@ -74,10 +71,9 @@ public class NoSeeing implements idv.Zero.KerKerInput.IKerKerInputMethod {
 	
 	public void onEnterInputMethod()
 	{
-		currentMode = InputMode.MODE_NOSEEING;
 	}
 	
-	public void onExitInputMethod()
+	public void destroyInputMethod()
 	{
 		db.close();
 	}
@@ -92,28 +88,9 @@ public class NoSeeing implements idv.Zero.KerKerInput.IKerKerInputMethod {
 	}
 
 	public boolean onKeyEvent(int keyCode, int[] keyCodes) {
-		if (keyCode == -3)
-		{
-			currentMode = InputMode.MODE_ABC;
-			_core.getKeyboardManager().setNativeKeyboard(NativeKeyboardTypes.MODE_ABC);
-		}
-		else if (keyCode == -4)
-		{
-			currentMode = InputMode.MODE_NOSEEING;
-			_core.getKeyboardManager().setNativeKeyboard(NativeKeyboardTypes.MODE_IME);
-		}
-		else
-		{
-			return handleNoSeeingInput(keyCode, keyCodes);
-		}
-		return true;
+		return handleNoSeeingInput(keyCode, keyCodes);
 	}
 	
-	public boolean wantHandleEvent(int keyCode)
-	{
-		return (currentMode == InputMode.MODE_NOSEEING) || keyCode &lt;= -3;
-	}
-
 	private boolean handleNoSeeingInput(int keyCode, int[] keyCodes) {
 		if (keyCode == Keyboard.KEYCODE_DELETE)
 		{
@@ -130,7 +107,7 @@ public class NoSeeing implements idv.Zero.KerKerInput.IKerKerInputMethod {
 		}
 		else if((keyCode &gt;= KeyEvent.KEYCODE_0 &amp;&amp; keyCode &lt;= KeyEvent.KEYCODE_9) || keyCode == 32)
 		{
-			// Noseeing users tend to use SPACE to select first candidate...
+			// Noseeing users tend to use SPACE to select first candidate
 			if (keyCode == 32)
 			{
 				if (_currentCandidates.size() &gt; 0)
@@ -218,10 +195,6 @@ public class NoSeeing implements idv.Zero.KerKerInput.IKerKerInputMethod {
 		}
 	}
 
-	public void onTextEvent(CharSequence text) {
-		_core.getConnection().commitText(text, 1);
-	}
-
 	public void commitCandidate(int selectedCandidate) {
 		_core.getConnection().commitText(_currentCandidates.get(selectedCandidate), 1);
 		_core.hideCandidatesView();</diff>
      <filename>src/idv/Zero/KerKerInput/Methods/NoSeeing.java</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>bin/KerKerInput-IMF.apk</filename>
    </removed>
    <removed>
      <filename>bin/classes.dex</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/CandidatesView.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/CandidatesViewContainer$1.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/CandidatesViewContainer$2.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/CandidatesViewContainer.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/FileDownload.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/IKerKerInputMethod.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KBManager$NativeKeyboardTypes.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KBManager.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KerKerInputCore$1.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KerKerInputCore$2.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KerKerInputCore.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KerKerInputService$1$1$1.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KerKerInputService$1$1$2.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KerKerInputService$1$1.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KerKerInputService$1.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KerKerInputService.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/KerKerInputSettings.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/Methods/BPMFInput$InputMode.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/Methods/BPMFInput$InputState.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/Methods/BPMFInput.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/Methods/NoSeeing$1.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/Methods/NoSeeing$InputMode.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/Methods/NoSeeing.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/R$attr.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/R$dimen.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/R$drawable.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/R$id.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/R$layout.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/R$raw.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/R$string.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/R$xml.class</filename>
    </removed>
    <removed>
      <filename>bin/idv/Zero/KerKerInput/R.class</filename>
    </removed>
    <removed>
      <filename>bin/resources.ap_</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>3a806596231c3eb2c7ec7c048a7c99a5df59d1f4</id>
    </parent>
  </parents>
  <author>
    <name>itsZero (Chien-An &quot;Zero&quot; Cho)</name>
    <email>itsero@gmail.com</email>
  </author>
  <url>http://github.com/itszero/KerKerInput/commit/07288dab0807d0878fb68464d26e6cd1533a3908</url>
  <id>07288dab0807d0878fb68464d26e6cd1533a3908</id>
  <committed-date>2009-09-06T11:38:42-07:00</committed-date>
  <authored-date>2009-09-06T11:38:42-07:00</authored-date>
  <message>Add symbol keyboard. Refactor input engine, all latin-related input diverted to core. BPMF now supports in-place replace symbol. Update all KerKerInput-specified KeyCode into KBManager, code starts from -100.</message>
  <tree>e93f96d263ca08fac5f6ccb29b92032a1a6a48d8</tree>
  <committer>
    <name>itsZero (Chien-An &quot;Zero&quot; Cho)</name>
    <email>itsero@gmail.com</email>
  </committer>
</commit>
