pointers = mPointerTrackers;
- final Key[] keys = mKeys;
- final OnKeyboardActionListener listener = mKeyboardActionListener;
-
- // Create pointer trackers until we can get 'id+1'-th tracker, if needed.
- for (int i = pointers.size(); i <= id; i++) {
- final PointerTracker tracker =
- new PointerTracker(i, mHandler, mKeyDetector, this, getResources());
- if (keys != null)
- tracker.setKeyboard(keys, mKeyHysteresisDistance);
- if (listener != null)
- tracker.setOnKeyboardActionListener(listener);
- pointers.add(tracker);
- }
-
- return pointers.get(id);
- }
-
- public boolean isInSlidingKeyInput() {
- if (mMiniKeyboard != null) {
- return mMiniKeyboard.isInSlidingKeyInput();
- } else {
- return mPointerQueue.isInSlidingKeyInput();
- }
- }
-
- public int getPointerCount() {
- return mOldPointerCount;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent me) {
- final int action = me.getActionMasked();
- final int pointerCount = me.getPointerCount();
- final int oldPointerCount = mOldPointerCount;
- mOldPointerCount = pointerCount;
-
- // TODO: cleanup this code into a multi-touch to single-touch event converter class?
- // If the device does not have distinct multi-touch support panel, ignore all multi-touch
- // events except a transition from/to single-touch.
- if (!mHasDistinctMultitouch && pointerCount > 1 && oldPointerCount > 1) {
- return true;
- }
-
- // Track the last few movements to look for spurious swipes.
- mSwipeTracker.addMovement(me);
-
- // Gesture detector must be enabled only when mini-keyboard is not on the screen.
- if (mMiniKeyboard == null
- && mGestureDetector != null && mGestureDetector.onTouchEvent(me)) {
- dismissKeyPreview();
- mHandler.cancelKeyTimers();
- return true;
- }
-
- final long eventTime = me.getEventTime();
- final int index = me.getActionIndex();
- final int id = me.getPointerId(index);
- final int x = (int)me.getX(index);
- final int y = (int)me.getY(index);
-
- // Needs to be called after the gesture detector gets a turn, as it may have
- // displayed the mini keyboard
- if (mMiniKeyboard != null) {
- final int miniKeyboardPointerIndex = me.findPointerIndex(mMiniKeyboardTrackerId);
- if (miniKeyboardPointerIndex >= 0 && miniKeyboardPointerIndex < pointerCount) {
- final int miniKeyboardX = (int)me.getX(miniKeyboardPointerIndex);
- final int miniKeyboardY = (int)me.getY(miniKeyboardPointerIndex);
- MotionEvent translated = generateMiniKeyboardMotionEvent(action,
- miniKeyboardX, miniKeyboardY, eventTime);
- mMiniKeyboard.onTouchEvent(translated);
- translated.recycle();
- }
- return true;
- }
-
- if (mHandler.isInKeyRepeat()) {
- // It will keep being in the key repeating mode while the key is being pressed.
- if (action == MotionEvent.ACTION_MOVE) {
- return true;
- }
- final PointerTracker tracker = getPointerTracker(id);
- // Key repeating timer will be canceled if 2 or more keys are in action, and current
- // event (UP or DOWN) is non-modifier key.
- if (pointerCount > 1 && !tracker.isModifier()) {
- mHandler.cancelKeyRepeatTimer();
- }
- // Up event will pass through.
- }
-
- // TODO: cleanup this code into a multi-touch to single-touch event converter class?
- // Translate mutli-touch event to single-touch events on the device that has no distinct
- // multi-touch panel.
- if (!mHasDistinctMultitouch) {
- // Use only main (id=0) pointer tracker.
- PointerTracker tracker = getPointerTracker(0);
- if (pointerCount == 1 && oldPointerCount == 2) {
- // Multi-touch to single touch transition.
- // Send a down event for the latest pointer.
- tracker.onDownEvent(x, y, eventTime);
- } else if (pointerCount == 2 && oldPointerCount == 1) {
- // Single-touch to multi-touch transition.
- // Send an up event for the last pointer.
- tracker.onUpEvent(tracker.getLastX(), tracker.getLastY(), eventTime);
- } else if (pointerCount == 1 && oldPointerCount == 1) {
- tracker.onTouchEvent(action, x, y, eventTime);
- } else {
- Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
- + " (old " + oldPointerCount + ")");
- }
- return true;
- }
-
- if (action == MotionEvent.ACTION_MOVE) {
- for (int i = 0; i < pointerCount; i++) {
- PointerTracker tracker = getPointerTracker(me.getPointerId(i));
- tracker.onMoveEvent((int)me.getX(i), (int)me.getY(i), eventTime);
- }
- } else {
- PointerTracker tracker = getPointerTracker(id);
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- case MotionEvent.ACTION_POINTER_DOWN:
- onDownEvent(tracker, x, y, eventTime);
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_POINTER_UP:
- onUpEvent(tracker, x, y, eventTime);
- break;
- case MotionEvent.ACTION_CANCEL:
- onCancelEvent(tracker, x, y, eventTime);
- break;
- }
- }
-
- return true;
- }
-
- private void onDownEvent(PointerTracker tracker, int x, int y, long eventTime) {
- if (tracker.isOnModifierKey(x, y)) {
- // Before processing a down event of modifier key, all pointers already being tracked
- // should be released.
- mPointerQueue.releaseAllPointersExcept(null, eventTime);
- }
- tracker.onDownEvent(x, y, eventTime);
- mPointerQueue.add(tracker);
- }
-
- private void onUpEvent(PointerTracker tracker, int x, int y, long eventTime) {
- if (tracker.isModifier()) {
- // Before processing an up event of modifier key, all pointers already being tracked
- // should be released.
- mPointerQueue.releaseAllPointersExcept(tracker, eventTime);
- } else {
- int index = mPointerQueue.lastIndexOf(tracker);
- if (index >= 0) {
- mPointerQueue.releaseAllPointersOlderThan(tracker, eventTime);
- } else {
- Log.w(TAG, "onUpEvent: corresponding down event not found for pointer "
- + tracker.mPointerId);
- }
- }
- tracker.onUpEvent(x, y, eventTime);
- mPointerQueue.remove(tracker);
- }
-
- private void onCancelEvent(PointerTracker tracker, int x, int y, long eventTime) {
- tracker.onCancelEvent(x, y, eventTime);
- mPointerQueue.remove(tracker);
- }
-
- protected void swipeRight() {
- mKeyboardActionListener.swipeRight();
- }
-
- protected void swipeLeft() {
- mKeyboardActionListener.swipeLeft();
- }
-
- protected void swipeUp() {
- mKeyboardActionListener.swipeUp();
- }
-
- protected void swipeDown() {
- mKeyboardActionListener.swipeDown();
- }
-
- public void closing() {
- mPreviewPopup.dismiss();
- mHandler.cancelAllMessages();
-
- dismissPopupKeyboard();
- mBuffer = null;
- mCanvas = null;
- mMiniKeyboardCache.clear();
- }
-
- @Override
- public void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- closing();
- }
-
- private void dismissPopupKeyboard() {
- if (mMiniKeyboardPopup.isShowing()) {
- mMiniKeyboardPopup.dismiss();
- mMiniKeyboard = null;
- mMiniKeyboardOriginX = 0;
- mMiniKeyboardOriginY = 0;
- invalidateAllKeys();
- }
- }
-
- public boolean handleBack() {
- if (mMiniKeyboardPopup.isShowing()) {
- dismissPopupKeyboard();
- return true;
- }
- return false;
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinKeyboardView.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinKeyboardView.java
deleted file mode 100644
index edc87fe0..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinKeyboardView.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.inputmethodservice.Keyboard;
-import android.inputmethodservice.Keyboard.Key;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-
-import java.util.List;
-
-public class LatinKeyboardView extends LatinKeyboardBaseView {
-
- static final int KEYCODE_OPTIONS = -100;
- static final int KEYCODE_OPTIONS_LONGPRESS = -101;
- static final int KEYCODE_F1 = -103;
- static final int KEYCODE_NEXT_LANGUAGE = -104;
- static final int KEYCODE_PREV_LANGUAGE = -105;
- static final int KEYCODE_KP2A = -200;
- static final int KEYCODE_KP2A_USER = -201;
- static final int KEYCODE_KP2A_PASSWORD = -202;
- static final int KEYCODE_KP2A_ALPHA = -203;
- static final int KEYCODE_KP2A_SWITCH = -204;
- static final int KEYCODE_KP2A_LOCK = -205;
-
- private Keyboard mPhoneKeyboard;
-
- /** Whether we've started dropping move events because we found a big jump */
- private boolean mDroppingEvents;
- /**
- * Whether multi-touch disambiguation needs to be disabled if a real multi-touch event has
- * occured
- */
- private boolean mDisableDisambiguation;
- /** The distance threshold at which we start treating the touch session as a multi-touch */
- private int mJumpThresholdSquare = Integer.MAX_VALUE;
- /** The y coordinate of the last row */
- private int mLastRowY;
-
- public LatinKeyboardView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- public void setPhoneKeyboard(Keyboard phoneKeyboard) {
- mPhoneKeyboard = phoneKeyboard;
- }
-
- @Override
- public void setPreviewEnabled(boolean previewEnabled) {
- if (getKeyboard() == mPhoneKeyboard) {
- // Phone keyboard never shows popup preview (except language switch).
- super.setPreviewEnabled(false);
- } else {
- super.setPreviewEnabled(previewEnabled);
- }
- }
-
- @Override
- public void setKeyboard(Keyboard newKeyboard) {
- final Keyboard oldKeyboard = getKeyboard();
- if (oldKeyboard instanceof LatinKeyboard) {
- // Reset old keyboard state before switching to new keyboard.
- ((LatinKeyboard)oldKeyboard).keyReleased();
- }
- super.setKeyboard(newKeyboard);
- // One-seventh of the keyboard width seems like a reasonable threshold
- mJumpThresholdSquare = newKeyboard.getMinWidth() / 7;
- mJumpThresholdSquare *= mJumpThresholdSquare;
- // Assuming there are 4 rows, this is the coordinate of the last row
- mLastRowY = (newKeyboard.getHeight() * 3) / 4;
- setKeyboardLocal(newKeyboard);
- }
-
- @Override
- protected boolean onLongPress(Key key) {
- int primaryCode = key.codes[0];
- if (primaryCode == KEYCODE_OPTIONS) {
- return invokeOnKey(KEYCODE_OPTIONS_LONGPRESS);
- } else if (primaryCode == '0' && getKeyboard() == mPhoneKeyboard) {
- // Long pressing on 0 in phone number keypad gives you a '+'.
- return invokeOnKey('+');
- } else {
- return super.onLongPress(key);
- }
- }
-
- private boolean invokeOnKey(int primaryCode) {
- getOnKeyboardActionListener().onKey(primaryCode, null,
- LatinKeyboardBaseView.NOT_A_TOUCH_COORDINATE,
- LatinKeyboardBaseView.NOT_A_TOUCH_COORDINATE);
- return true;
- }
-
- @Override
- protected CharSequence adjustCase(CharSequence label) {
- Keyboard keyboard = getKeyboard();
- if (keyboard.isShifted()
- && keyboard instanceof LatinKeyboard
- && ((LatinKeyboard) keyboard).isAlphaKeyboard()
- && !TextUtils.isEmpty(label) && label.length() < 3
- && Character.isLowerCase(label.charAt(0))) {
- return label.toString().toUpperCase(getKeyboardLocale());
- }
- return label;
- }
-
- public boolean setShiftLocked(boolean shiftLocked) {
- Keyboard keyboard = getKeyboard();
- if (keyboard instanceof LatinKeyboard) {
- ((LatinKeyboard)keyboard).setShiftLocked(shiftLocked);
- invalidateAllKeys();
- return true;
- }
- return false;
- }
-
- /**
- * This function checks to see if we need to handle any sudden jumps in the pointer location
- * that could be due to a multi-touch being treated as a move by the firmware or hardware.
- * Once a sudden jump is detected, all subsequent move events are discarded
- * until an UP is received.
- * When a sudden jump is detected, an UP event is simulated at the last position and when
- * the sudden moves subside, a DOWN event is simulated for the second key.
- * @param me the motion event
- * @return true if the event was consumed, so that it doesn't continue to be handled by
- * KeyboardView.
- */
- private boolean handleSuddenJump(MotionEvent me) {
- final int action = me.getAction();
- final int x = (int) me.getX();
- final int y = (int) me.getY();
- boolean result = false;
-
- // Real multi-touch event? Stop looking for sudden jumps
- if (me.getPointerCount() > 1) {
- mDisableDisambiguation = true;
- }
- if (mDisableDisambiguation) {
- // If UP, reset the multi-touch flag
- if (action == MotionEvent.ACTION_UP) mDisableDisambiguation = false;
- return false;
- }
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- // Reset the "session"
- mDroppingEvents = false;
- mDisableDisambiguation = false;
- break;
- case MotionEvent.ACTION_MOVE:
- // Is this a big jump?
- final int distanceSquare = (mLastX - x) * (mLastX - x) + (mLastY - y) * (mLastY - y);
- // Check the distance and also if the move is not entirely within the bottom row
- // If it's only in the bottom row, it might be an intentional slide gesture
- // for language switching
- if (distanceSquare > mJumpThresholdSquare
- && (mLastY < mLastRowY || y < mLastRowY)) {
- // If we're not yet dropping events, start dropping and send an UP event
- if (!mDroppingEvents) {
- mDroppingEvents = true;
- // Send an up event
- MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
- MotionEvent.ACTION_UP,
- mLastX, mLastY, me.getMetaState());
- super.onTouchEvent(translated);
- translated.recycle();
- }
- result = true;
- } else if (mDroppingEvents) {
- // If moves are small and we're already dropping events, continue dropping
- result = true;
- }
- break;
- case MotionEvent.ACTION_UP:
- if (mDroppingEvents) {
- // Send a down event first, as we dropped a bunch of sudden jumps and assume that
- // the user is releasing the touch on the second key.
- MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
- MotionEvent.ACTION_DOWN,
- x, y, me.getMetaState());
- super.onTouchEvent(translated);
- translated.recycle();
- mDroppingEvents = false;
- // Let the up event get processed as well, result = false
- }
- break;
- }
- // Track the previous coordinate
- mLastX = x;
- mLastY = y;
- return result;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent me) {
- LatinKeyboard keyboard = (LatinKeyboard) getKeyboard();
- if (DEBUG_LINE) {
- mLastX = (int) me.getX();
- mLastY = (int) me.getY();
- invalidate();
- }
-
- // If there was a sudden jump, return without processing the actual motion event.
- if (handleSuddenJump(me))
- return true;
-
- // Reset any bounding box controls in the keyboard
- if (me.getAction() == MotionEvent.ACTION_DOWN) {
- keyboard.keyReleased();
- }
-
- if (me.getAction() == MotionEvent.ACTION_UP) {
- int languageDirection = keyboard.getLanguageChangeDirection();
- if (languageDirection != 0) {
- getOnKeyboardActionListener().onKey(
- languageDirection == 1 ? KEYCODE_NEXT_LANGUAGE : KEYCODE_PREV_LANGUAGE,
- null, mLastX, mLastY);
- me.setAction(MotionEvent.ACTION_CANCEL);
- keyboard.keyReleased();
- return super.onTouchEvent(me);
- }
- }
-
- return super.onTouchEvent(me);
- }
-
- /**************************** INSTRUMENTATION *******************************/
-
- static final boolean DEBUG_AUTO_PLAY = false;
- static final boolean DEBUG_LINE = false;
- private static final int MSG_TOUCH_DOWN = 1;
- private static final int MSG_TOUCH_UP = 2;
-
- Handler mHandler2;
-
- private String mStringToPlay;
- private int mStringIndex;
- private boolean mDownDelivered;
- private Key[] mAsciiKeys = new Key[256];
- private boolean mPlaying;
- private int mLastX;
- private int mLastY;
- private Paint mPaint;
-
- private void setKeyboardLocal(Keyboard k) {
- if (DEBUG_AUTO_PLAY) {
- findKeys();
- if (mHandler2 == null) {
- mHandler2 = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- removeMessages(MSG_TOUCH_DOWN);
- removeMessages(MSG_TOUCH_UP);
- if (mPlaying == false) return;
-
- switch (msg.what) {
- case MSG_TOUCH_DOWN:
- if (mStringIndex >= mStringToPlay.length()) {
- mPlaying = false;
- return;
- }
- char c = mStringToPlay.charAt(mStringIndex);
- while (c > 255 || mAsciiKeys[c] == null) {
- mStringIndex++;
- if (mStringIndex >= mStringToPlay.length()) {
- mPlaying = false;
- return;
- }
- c = mStringToPlay.charAt(mStringIndex);
- }
- int x = mAsciiKeys[c].x + 10;
- int y = mAsciiKeys[c].y + 26;
- MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(),
- SystemClock.uptimeMillis(),
- MotionEvent.ACTION_DOWN, x, y, 0);
- LatinKeyboardView.this.dispatchTouchEvent(me);
- me.recycle();
- sendEmptyMessageDelayed(MSG_TOUCH_UP, 500); // Deliver up in 500ms if nothing else
- // happens
- mDownDelivered = true;
- break;
- case MSG_TOUCH_UP:
- char cUp = mStringToPlay.charAt(mStringIndex);
- int x2 = mAsciiKeys[cUp].x + 10;
- int y2 = mAsciiKeys[cUp].y + 26;
- mStringIndex++;
-
- MotionEvent me2 = MotionEvent.obtain(SystemClock.uptimeMillis(),
- SystemClock.uptimeMillis(),
- MotionEvent.ACTION_UP, x2, y2, 0);
- LatinKeyboardView.this.dispatchTouchEvent(me2);
- me2.recycle();
- sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 500); // Deliver up in 500ms if nothing else
- // happens
- mDownDelivered = false;
- break;
- }
- }
- };
-
- }
- }
- }
-
- private void findKeys() {
- List keys = getKeyboard().getKeys();
- // Get the keys on this keyboard
- for (int i = 0; i < keys.size(); i++) {
- int code = keys.get(i).codes[0];
- if (code >= 0 && code <= 255) {
- mAsciiKeys[code] = keys.get(i);
- }
- }
- }
-
- public void startPlaying(String s) {
- if (DEBUG_AUTO_PLAY) {
- if (s == null) return;
- mStringToPlay = s.toLowerCase();
- mPlaying = true;
- mDownDelivered = false;
- mStringIndex = 0;
- mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 10);
- }
- }
-
- @Override
- public void draw(Canvas c) {
- LatinIMEUtil.GCUtils.getInstance().reset();
- boolean tryGC = true;
- for (int i = 0; i < LatinIMEUtil.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
- try {
- super.draw(c);
- tryGC = false;
- } catch (OutOfMemoryError e) {
- tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait("LatinKeyboardView", e);
- }
- }
- if (DEBUG_AUTO_PLAY) {
- if (mPlaying) {
- mHandler2.removeMessages(MSG_TOUCH_DOWN);
- mHandler2.removeMessages(MSG_TOUCH_UP);
- if (mDownDelivered) {
- mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_UP, 20);
- } else {
- mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 20);
- }
- }
- }
- if (DEBUG_LINE) {
- if (mPaint == null) {
- mPaint = new Paint();
- mPaint.setColor(0x80FFFFFF);
- mPaint.setAntiAlias(false);
- }
- c.drawLine(mLastX, 0, mLastX, getHeight(), mPaint);
- c.drawLine(0, mLastY, getWidth(), mLastY, mPaint);
- }
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/MiniKeyboardKeyDetector.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/MiniKeyboardKeyDetector.java
deleted file mode 100644
index 00ee995b..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/MiniKeyboardKeyDetector.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import android.inputmethodservice.Keyboard.Key;
-
-class MiniKeyboardKeyDetector extends KeyDetector {
- private static final int MAX_NEARBY_KEYS = 1;
-
- private final int mSlideAllowanceSquare;
- private final int mSlideAllowanceSquareTop;
-
- public MiniKeyboardKeyDetector(float slideAllowance) {
- super();
- mSlideAllowanceSquare = (int)(slideAllowance * slideAllowance);
- // Top slide allowance is slightly longer (sqrt(2) times) than other edges.
- mSlideAllowanceSquareTop = mSlideAllowanceSquare * 2;
- }
-
- @Override
- protected int getMaxNearbyKeys() {
- return MAX_NEARBY_KEYS;
- }
-
- @Override
- public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) {
- final Key[] keys = getKeys();
- final int touchX = getTouchX(x);
- final int touchY = getTouchY(y);
- int closestKeyIndex = LatinKeyboardBaseView.NOT_A_KEY;
- int closestKeyDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
- final int keyCount = keys.length;
- for (int i = 0; i < keyCount; i++) {
- final Key key = keys[i];
- int dist = key.squaredDistanceFrom(touchX, touchY);
- if (dist < closestKeyDist) {
- closestKeyIndex = i;
- closestKeyDist = dist;
- }
- }
- if (allKeys != null && closestKeyIndex != LatinKeyboardBaseView.NOT_A_KEY)
- allKeys[0] = keys[closestKeyIndex].codes[0];
- return closestKeyIndex;
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ModifierKeyState.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ModifierKeyState.java
deleted file mode 100644
index 5da00d2e..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ModifierKeyState.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-class ModifierKeyState {
- private static final int RELEASING = 0;
- private static final int PRESSING = 1;
- private static final int MOMENTARY = 2;
-
- private int mState = RELEASING;
-
- public void onPress() {
- mState = PRESSING;
- }
-
- public void onRelease() {
- mState = RELEASING;
- }
-
- public void onOtherKeyPressed() {
- if (mState == PRESSING)
- mState = MOMENTARY;
- }
-
- public boolean isMomentary() {
- return mState == MOMENTARY;
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/PluginManager.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/PluginManager.java
deleted file mode 100644
index f24328f8..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/PluginManager.java
+++ /dev/null
@@ -1,259 +0,0 @@
-package keepass2android.softkeyboard;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-import android.util.Log;
-
-public class PluginManager extends BroadcastReceiver {
- private static String TAG = "PCKeyboard";
- private static String HK_INTENT_DICT = "org.pocketworkstation.DICT";
- private static String SOFTKEYBOARD_INTENT_DICT = "com.menny.android.anysoftkeyboard.DICTIONARY";
- private KP2AKeyboard mIME;
-
- // Apparently anysoftkeyboard doesn't use ISO 639-1 language codes for its locales?
- // Add exceptions as needed.
- private static Map SOFTKEYBOARD_LANG_MAP = new HashMap();
- static {
- SOFTKEYBOARD_LANG_MAP.put("dk", "da");
- }
-
- PluginManager(KP2AKeyboard ime) {
- super();
- mIME = ime;
- }
-
- private static Map mPluginDicts =
- new HashMap();
-
- static interface DictPluginSpec {
- BinaryDictionary getDict(Context context);
- }
-
- static private abstract class DictPluginSpecBase
- implements DictPluginSpec {
- String mPackageName;
-
- Resources getResources(Context context) {
- PackageManager packageManager = context.getPackageManager();
- Resources res = null;
- try {
- ApplicationInfo appInfo = packageManager.getApplicationInfo(mPackageName, 0);
- res = packageManager.getResourcesForApplication(appInfo);
- } catch (NameNotFoundException e) {
- Log.i(TAG, "couldn't get resources");
- }
- return res;
- }
-
- abstract InputStream[] getStreams(Resources res);
-
- public BinaryDictionary getDict(Context context) {
- Resources res = getResources(context);
- if (res == null) return null;
-
- InputStream[] dicts = getStreams(res);
- if (dicts == null) return null;
- BinaryDictionary dict = new BinaryDictionary(
- context, dicts, Suggest.DIC_MAIN);
- if (dict.getSize() == 0) return null;
- //Log.i(TAG, "dict size=" + dict.getSize());
- return dict;
- }
- }
-
- static private class DictPluginSpecHK
- extends DictPluginSpecBase {
-
- int[] mRawIds;
-
- public DictPluginSpecHK(String pkg, int[] ids) {
- mPackageName = pkg;
- mRawIds = ids;
- }
-
- @Override
- InputStream[] getStreams(Resources res) {
- if (mRawIds == null || mRawIds.length == 0) return null;
- InputStream[] streams = new InputStream[mRawIds.length];
- for (int i = 0; i < mRawIds.length; ++i) {
- streams[i] = res.openRawResource(mRawIds[i]);
- }
- return streams;
- }
- }
-
- static private class DictPluginSpecSoftKeyboard
- extends DictPluginSpecBase {
-
- String mAssetName;
-
- public DictPluginSpecSoftKeyboard(String pkg, String asset) {
- mPackageName = pkg;
- mAssetName = asset;
- }
-
- @Override
- InputStream[] getStreams(Resources res) {
- if (mAssetName == null) return null;
- try {
- InputStream in = res.getAssets().open(mAssetName);
- return new InputStream[] {in};
- } catch (IOException e) {
- Log.e(TAG, "Dictionary asset loading failure");
- return null;
- }
- }
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.i(TAG, "Package information changed, updating dictionaries.");
- getPluginDictionaries(context);
- Log.i(TAG, "Finished updating dictionaries.");
- mIME.toggleLanguage(true, true);
- }
-
- static void getSoftKeyboardDictionaries(PackageManager packageManager) {
- Intent dictIntent = new Intent(SOFTKEYBOARD_INTENT_DICT);
- List dictPacks = packageManager.queryBroadcastReceivers(
- dictIntent, PackageManager.GET_RECEIVERS);
- for (ResolveInfo ri : dictPacks) {
- ApplicationInfo appInfo = ri.activityInfo.applicationInfo;
- String pkgName = appInfo.packageName;
- boolean success = false;
- try {
- Resources res = packageManager.getResourcesForApplication(appInfo);
- Log.i("KP2AK", "Found dictionary plugin package: " + pkgName);
- int dictId = res.getIdentifier("dictionaries", "xml", pkgName);
- if (dictId == 0) continue;
- XmlResourceParser xrp = res.getXml(dictId);
-
- String assetName = null;
- String lang = null;
- try {
- int current = xrp.getEventType();
- while (current != XmlResourceParser.END_DOCUMENT) {
- if (current == XmlResourceParser.START_TAG) {
- String tag = xrp.getName();
- if (tag != null) {
- if (tag.equals("Dictionary")) {
- lang = xrp.getAttributeValue(null, "locale");
- String convLang = SOFTKEYBOARD_LANG_MAP.get(lang);
- if (convLang != null) lang = convLang;
- String type = xrp.getAttributeValue(null, "type");
- if (type == null || type.equals("raw") || type.equals("binary")) {
- assetName = xrp.getAttributeValue(null, "dictionaryAssertName"); // sic
- } else {
- Log.w(TAG, "Unsupported AnySoftKeyboard dict type " + type);
- }
- //Log.i(TAG, "asset=" + assetName + " lang=" + lang);
- }
- }
- }
- xrp.next();
- current = xrp.getEventType();
- }
- } catch (XmlPullParserException e) {
- Log.e(TAG, "Dictionary XML parsing failure");
- } catch (IOException e) {
- Log.e(TAG, "Dictionary XML IOException");
- }
-
- if (assetName == null || lang == null) continue;
- DictPluginSpec spec = new DictPluginSpecSoftKeyboard(pkgName, assetName);
- mPluginDicts.put(lang, spec);
- Log.i("KP2AK", "Found plugin dictionary: lang=" + lang + ", pkg=" + pkgName);
- success = true;
- } catch (NameNotFoundException e) {
- Log.i("KP2AK", "bad");
- } finally {
- if (!success) {
- Log.i("KP2AK", "failed to load plugin dictionary spec from " + pkgName);
- }
- }
- }
- }
-
- static void getHKDictionaries(PackageManager packageManager) {
- Intent dictIntent = new Intent(HK_INTENT_DICT);
- List dictPacks = packageManager.queryIntentActivities(dictIntent, 0);
- for (ResolveInfo ri : dictPacks) {
- ApplicationInfo appInfo = ri.activityInfo.applicationInfo;
- String pkgName = appInfo.packageName;
- boolean success = false;
- try {
- Resources res = packageManager.getResourcesForApplication(appInfo);
- Log.i("KP2AK", "Found dictionary plugin package: " + pkgName);
- int langId = res.getIdentifier("dict_language", "string", pkgName);
- if (langId == 0) continue;
- String lang = res.getString(langId);
- int[] rawIds = null;
-
- // Try single-file version first
- int rawId = res.getIdentifier("main", "raw", pkgName);
- if (rawId != 0) {
- rawIds = new int[] { rawId };
- } else {
- // try multi-part version
- int parts = 0;
- List ids = new ArrayList();
- while (true) {
- int id = res.getIdentifier("main" + parts, "raw", pkgName);
- if (id == 0) break;
- ids.add(id);
- ++parts;
- }
- if (parts == 0) continue; // no parts found
- rawIds = new int[parts];
- for (int i = 0; i < parts; ++i) rawIds[i] = ids.get(i);
- }
- DictPluginSpec spec = new DictPluginSpecHK(pkgName, rawIds);
- mPluginDicts.put(lang, spec);
- Log.i("KP2AK", "Found plugin dictionary: lang=" + lang + ", pkg=" + pkgName);
- success = true;
- } catch (NameNotFoundException e) {
- Log.i("KP2AK", "bad");
- } finally {
- if (!success) {
- Log.i("KP2AK", "failed to load plugin dictionary spec from " + pkgName);
- }
- }
- }
- }
-
- static void getPluginDictionaries(Context context) {
- mPluginDicts.clear();
- PackageManager packageManager = context.getPackageManager();
- getSoftKeyboardDictionaries(packageManager);
- getHKDictionaries(packageManager);
- }
-
- static BinaryDictionary getDictionary(Context context, String lang) {
- Log.i("KP2AK", "Looking for plugin dictionary for lang=" + lang);
- DictPluginSpec spec = mPluginDicts.get(lang);
- if (spec == null) spec = mPluginDicts.get(lang.substring(0, 2));
- if (spec == null) {
- Log.i("KP2AK", "No plugin found.");
- return null;
- }
- BinaryDictionary dict = spec.getDict(context);
- Log.i("KP2AK", "Found plugin dictionary for " + lang + (dict == null ? " is null" : ", size=" + dict.getSize()));
- return dict;
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/PointerTracker.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/PointerTracker.java
deleted file mode 100644
index 54ca0c2e..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/PointerTracker.java
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import keepass2android.softkeyboard.LatinKeyboardBaseView.OnKeyboardActionListener;
-import keepass2android.softkeyboard.LatinKeyboardBaseView.UIHandler;
-
-import android.content.res.Resources;
-import android.inputmethodservice.Keyboard;
-import android.inputmethodservice.Keyboard.Key;
-import android.util.Log;
-import android.view.MotionEvent;
-
-public class PointerTracker {
- private static final String TAG = "PointerTracker";
- private static final boolean DEBUG = false;
- private static final boolean DEBUG_MOVE = false;
-
- public interface UIProxy {
- public void invalidateKey(Key key);
- public void showPreview(int keyIndex, PointerTracker tracker);
- public boolean hasDistinctMultitouch();
- }
-
- public final int mPointerId;
-
- // Timing constants
- private final int mDelayBeforeKeyRepeatStart;
- private final int mLongPressKeyTimeout;
- private final int mMultiTapKeyTimeout;
-
- // Miscellaneous constants
- private static final int NOT_A_KEY = LatinKeyboardBaseView.NOT_A_KEY;
- private static final int[] KEY_DELETE = { Keyboard.KEYCODE_DELETE };
-
- private final UIProxy mProxy;
- private final UIHandler mHandler;
- private final KeyDetector mKeyDetector;
- private OnKeyboardActionListener mListener;
- private final KeyboardSwitcher mKeyboardSwitcher;
- private final boolean mHasDistinctMultitouch;
-
- private Key[] mKeys;
- private int mKeyHysteresisDistanceSquared = -1;
-
- private final KeyState mKeyState;
-
- // true if keyboard layout has been changed.
- private boolean mKeyboardLayoutHasBeenChanged;
-
- // true if event is already translated to a key action (long press or mini-keyboard)
- private boolean mKeyAlreadyProcessed;
-
- // true if this pointer is repeatable key
- private boolean mIsRepeatableKey;
-
- // true if this pointer is in sliding key input
- private boolean mIsInSlidingKeyInput;
-
- // For multi-tap
- private int mLastSentIndex;
- private int mTapCount;
- private long mLastTapTime;
- private boolean mInMultiTap;
- private final StringBuilder mPreviewLabel = new StringBuilder(1);
-
- // pressed key
- private int mPreviousKey = NOT_A_KEY;
-
- // This class keeps track of a key index and a position where this pointer is.
- private static class KeyState {
- private final KeyDetector mKeyDetector;
-
- // The position and time at which first down event occurred.
- private int mStartX;
- private int mStartY;
- private long mDownTime;
-
- // The current key index where this pointer is.
- private int mKeyIndex = NOT_A_KEY;
- // The position where mKeyIndex was recognized for the first time.
- private int mKeyX;
- private int mKeyY;
-
- // Last pointer position.
- private int mLastX;
- private int mLastY;
-
- public KeyState(KeyDetector keyDetecor) {
- mKeyDetector = keyDetecor;
- }
-
- public int getKeyIndex() {
- return mKeyIndex;
- }
-
- public int getKeyX() {
- return mKeyX;
- }
-
- public int getKeyY() {
- return mKeyY;
- }
-
- public int getStartX() {
- return mStartX;
- }
-
- public int getStartY() {
- return mStartY;
- }
-
- public long getDownTime() {
- return mDownTime;
- }
-
- public int getLastX() {
- return mLastX;
- }
-
- public int getLastY() {
- return mLastY;
- }
-
- public int onDownKey(int x, int y, long eventTime) {
- mStartX = x;
- mStartY = y;
- mDownTime = eventTime;
-
- return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
- }
-
- private int onMoveKeyInternal(int x, int y) {
- mLastX = x;
- mLastY = y;
- return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
- }
-
- public int onMoveKey(int x, int y) {
- return onMoveKeyInternal(x, y);
- }
-
- public int onMoveToNewKey(int keyIndex, int x, int y) {
- mKeyIndex = keyIndex;
- mKeyX = x;
- mKeyY = y;
- return keyIndex;
- }
-
- public int onUpKey(int x, int y) {
- return onMoveKeyInternal(x, y);
- }
- }
-
- public PointerTracker(int id, UIHandler handler, KeyDetector keyDetector, UIProxy proxy,
- Resources res) {
- if (proxy == null || handler == null || keyDetector == null)
- throw new NullPointerException();
- mPointerId = id;
- mProxy = proxy;
- mHandler = handler;
- mKeyDetector = keyDetector;
- mKeyboardSwitcher = KeyboardSwitcher.getInstance();
- mKeyState = new KeyState(keyDetector);
- mHasDistinctMultitouch = proxy.hasDistinctMultitouch();
- mDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start);
- mLongPressKeyTimeout = res.getInteger(R.integer.config_long_press_key_timeout);
- mMultiTapKeyTimeout = res.getInteger(R.integer.config_multi_tap_key_timeout);
- resetMultiTap();
- }
-
- public void setOnKeyboardActionListener(OnKeyboardActionListener listener) {
- mListener = listener;
- }
-
- public void setKeyboard(Key[] keys, float keyHysteresisDistance) {
- if (keys == null || keyHysteresisDistance < 0)
- throw new IllegalArgumentException();
- mKeys = keys;
- mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance);
- // Mark that keyboard layout has been changed.
- mKeyboardLayoutHasBeenChanged = true;
- }
-
- public boolean isInSlidingKeyInput() {
- return mIsInSlidingKeyInput;
- }
-
- private boolean isValidKeyIndex(int keyIndex) {
- return keyIndex >= 0 && keyIndex < mKeys.length;
- }
-
- public Key getKey(int keyIndex) {
- return isValidKeyIndex(keyIndex) ? mKeys[keyIndex] : null;
- }
-
- private boolean isModifierInternal(int keyIndex) {
- Key key = getKey(keyIndex);
- if (key == null)
- return false;
- int primaryCode = key.codes[0];
- return primaryCode == Keyboard.KEYCODE_SHIFT
- || primaryCode == Keyboard.KEYCODE_MODE_CHANGE;
- }
-
- public boolean isModifier() {
- return isModifierInternal(mKeyState.getKeyIndex());
- }
-
- public boolean isOnModifierKey(int x, int y) {
- return isModifierInternal(mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null));
- }
-
- public boolean isSpaceKey(int keyIndex) {
- Key key = getKey(keyIndex);
- return key != null && key.codes[0] == KP2AKeyboard.KEYCODE_SPACE;
- }
-
- public void updateKey(int keyIndex) {
- if (mKeyAlreadyProcessed)
- return;
- int oldKeyIndex = mPreviousKey;
- mPreviousKey = keyIndex;
- if (keyIndex != oldKeyIndex) {
- if (isValidKeyIndex(oldKeyIndex)) {
- // if new key index is not a key, old key was just released inside of the key.
- final boolean inside = (keyIndex == NOT_A_KEY);
- mKeys[oldKeyIndex].onReleased(inside);
- mProxy.invalidateKey(mKeys[oldKeyIndex]);
- }
- if (isValidKeyIndex(keyIndex)) {
- mKeys[keyIndex].onPressed();
- mProxy.invalidateKey(mKeys[keyIndex]);
- }
- }
- }
-
- public void setAlreadyProcessed() {
- mKeyAlreadyProcessed = true;
- }
-
- public void onTouchEvent(int action, int x, int y, long eventTime) {
- switch (action) {
- case MotionEvent.ACTION_MOVE:
- onMoveEvent(x, y, eventTime);
- break;
- case MotionEvent.ACTION_DOWN:
- case MotionEvent.ACTION_POINTER_DOWN:
- onDownEvent(x, y, eventTime);
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_POINTER_UP:
- onUpEvent(x, y, eventTime);
- break;
- case MotionEvent.ACTION_CANCEL:
- onCancelEvent(x, y, eventTime);
- break;
- }
- }
-
- public void onDownEvent(int x, int y, long eventTime) {
- if (DEBUG)
- debugLog("onDownEvent:", x, y);
- int keyIndex = mKeyState.onDownKey(x, y, eventTime);
- mKeyboardLayoutHasBeenChanged = false;
- mKeyAlreadyProcessed = false;
- mIsRepeatableKey = false;
- mIsInSlidingKeyInput = false;
- checkMultiTap(eventTime, keyIndex);
- if (mListener != null) {
- if (isValidKeyIndex(keyIndex)) {
- mListener.onPress(mKeys[keyIndex].codes[0]);
- // This onPress call may have changed keyboard layout. Those cases are detected at
- // {@link #setKeyboard}. In those cases, we should update keyIndex according to the
- // new keyboard layout.
- if (mKeyboardLayoutHasBeenChanged) {
- mKeyboardLayoutHasBeenChanged = false;
- keyIndex = mKeyState.onDownKey(x, y, eventTime);
- }
- }
- }
- if (isValidKeyIndex(keyIndex)) {
- if (mKeys[keyIndex].repeatable) {
- repeatKey(keyIndex);
- mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this);
- mIsRepeatableKey = true;
- }
- startLongPressTimer(keyIndex);
- }
- showKeyPreviewAndUpdateKey(keyIndex);
- }
-
- public void onMoveEvent(int x, int y, long eventTime) {
- if (DEBUG_MOVE)
- debugLog("onMoveEvent:", x, y);
- if (mKeyAlreadyProcessed)
- return;
- final KeyState keyState = mKeyState;
- int keyIndex = keyState.onMoveKey(x, y);
- final Key oldKey = getKey(keyState.getKeyIndex());
- if (isValidKeyIndex(keyIndex)) {
- if (oldKey == null) {
- // The pointer has been slid in to the new key, but the finger was not on any keys.
- // In this case, we must call onPress() to notify that the new key is being pressed.
- if (mListener != null) {
- mListener.onPress(getKey(keyIndex).codes[0]);
- // This onPress call may have changed keyboard layout. Those cases are detected
- // at {@link #setKeyboard}. In those cases, we should update keyIndex according
- // to the new keyboard layout.
- if (mKeyboardLayoutHasBeenChanged) {
- mKeyboardLayoutHasBeenChanged = false;
- keyIndex = keyState.onMoveKey(x, y);
- }
- }
- keyState.onMoveToNewKey(keyIndex, x, y);
- startLongPressTimer(keyIndex);
- } else if (!isMinorMoveBounce(x, y, keyIndex)) {
- // The pointer has been slid in to the new key from the previous key, we must call
- // onRelease() first to notify that the previous key has been released, then call
- // onPress() to notify that the new key is being pressed.
- mIsInSlidingKeyInput = true;
- if (mListener != null)
- mListener.onRelease(oldKey.codes[0]);
- resetMultiTap();
- if (mListener != null) {
- mListener.onPress(getKey(keyIndex).codes[0]);
- // This onPress call may have changed keyboard layout. Those cases are detected
- // at {@link #setKeyboard}. In those cases, we should update keyIndex according
- // to the new keyboard layout.
- if (mKeyboardLayoutHasBeenChanged) {
- mKeyboardLayoutHasBeenChanged = false;
- keyIndex = keyState.onMoveKey(x, y);
- }
- }
- keyState.onMoveToNewKey(keyIndex, x, y);
- startLongPressTimer(keyIndex);
- }
- } else {
- if (oldKey != null && !isMinorMoveBounce(x, y, keyIndex)) {
- // The pointer has been slid out from the previous key, we must call onRelease() to
- // notify that the previous key has been released.
- mIsInSlidingKeyInput = true;
- if (mListener != null)
- mListener.onRelease(oldKey.codes[0]);
- resetMultiTap();
- keyState.onMoveToNewKey(keyIndex, x ,y);
- mHandler.cancelLongPressTimer();
- }
- }
- showKeyPreviewAndUpdateKey(keyState.getKeyIndex());
- }
-
- public void onUpEvent(int x, int y, long eventTime) {
- if (DEBUG)
- debugLog("onUpEvent :", x, y);
- mHandler.cancelKeyTimers();
- mHandler.cancelPopupPreview();
- showKeyPreviewAndUpdateKey(NOT_A_KEY);
- mIsInSlidingKeyInput = false;
- if (mKeyAlreadyProcessed)
- return;
- int keyIndex = mKeyState.onUpKey(x, y);
- if (isMinorMoveBounce(x, y, keyIndex)) {
- // Use previous fixed key index and coordinates.
- keyIndex = mKeyState.getKeyIndex();
- x = mKeyState.getKeyX();
- y = mKeyState.getKeyY();
- }
- if (!mIsRepeatableKey) {
- detectAndSendKey(keyIndex, x, y, eventTime);
- }
-
- if (isValidKeyIndex(keyIndex))
- mProxy.invalidateKey(mKeys[keyIndex]);
- }
-
- public void onCancelEvent(int x, int y, long eventTime) {
- if (DEBUG)
- debugLog("onCancelEvt:", x, y);
- mHandler.cancelKeyTimers();
- mHandler.cancelPopupPreview();
- showKeyPreviewAndUpdateKey(NOT_A_KEY);
- mIsInSlidingKeyInput = false;
- int keyIndex = mKeyState.getKeyIndex();
- if (isValidKeyIndex(keyIndex))
- mProxy.invalidateKey(mKeys[keyIndex]);
- }
-
- public void repeatKey(int keyIndex) {
- Key key = getKey(keyIndex);
- if (key != null) {
- // While key is repeating, because there is no need to handle multi-tap key, we can
- // pass -1 as eventTime argument.
- detectAndSendKey(keyIndex, key.x, key.y, -1);
- }
- }
-
- public int getLastX() {
- return mKeyState.getLastX();
- }
-
- public int getLastY() {
- return mKeyState.getLastY();
- }
-
- public long getDownTime() {
- return mKeyState.getDownTime();
- }
-
- // These package scope methods are only for debugging purpose.
- /* package */ int getStartX() {
- return mKeyState.getStartX();
- }
-
- /* package */ int getStartY() {
- return mKeyState.getStartY();
- }
-
- private boolean isMinorMoveBounce(int x, int y, int newKey) {
- if (mKeys == null || mKeyHysteresisDistanceSquared < 0)
- throw new IllegalStateException("keyboard and/or hysteresis not set");
- int curKey = mKeyState.getKeyIndex();
- if (newKey == curKey) {
- return true;
- } else if (isValidKeyIndex(curKey)) {
- return getSquareDistanceToKeyEdge(x, y, mKeys[curKey]) < mKeyHysteresisDistanceSquared;
- } else {
- return false;
- }
- }
-
- private static int getSquareDistanceToKeyEdge(int x, int y, Key key) {
- final int left = key.x;
- final int right = key.x + key.width;
- final int top = key.y;
- final int bottom = key.y + key.height;
- final int edgeX = x < left ? left : (x > right ? right : x);
- final int edgeY = y < top ? top : (y > bottom ? bottom : y);
- final int dx = x - edgeX;
- final int dy = y - edgeY;
- return dx * dx + dy * dy;
- }
-
- private void showKeyPreviewAndUpdateKey(int keyIndex) {
- updateKey(keyIndex);
- // The modifier key, such as shift key, should not be shown as preview when multi-touch is
- // supported. On the other hand, if multi-touch is not supported, the modifier key should
- // be shown as preview.
- if (mHasDistinctMultitouch && isModifier()) {
- mProxy.showPreview(NOT_A_KEY, this);
- } else {
- mProxy.showPreview(keyIndex, this);
- }
- }
-
- private void startLongPressTimer(int keyIndex) {
- if (mKeyboardSwitcher.isInMomentaryAutoModeSwitchState()) {
- // We use longer timeout for sliding finger input started from the symbols mode key.
- mHandler.startLongPressTimer(mLongPressKeyTimeout * 3, keyIndex, this);
- } else {
- mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this);
- }
- }
-
- private void detectAndSendKey(int index, int x, int y, long eventTime) {
- final OnKeyboardActionListener listener = mListener;
- final Key key = getKey(index);
-
- if (key == null) {
- if (listener != null)
- listener.onCancel();
- } else {
- if (key.text != null) {
- if (listener != null) {
- listener.onText(key.text);
- listener.onRelease(0); // dummy key code
- }
- } else {
- int code = key.codes[0];
- int[] codes = mKeyDetector.newCodeArray();
- mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
- // Multi-tap
- if (mInMultiTap) {
- if (mTapCount != -1) {
- mListener.onKey(Keyboard.KEYCODE_DELETE, KEY_DELETE, x, y);
- } else {
- mTapCount = 0;
- }
- code = key.codes[mTapCount];
- }
- /*
- * Swap the first and second values in the codes array if the primary code is not
- * the first value but the second value in the array. This happens when key
- * debouncing is in effect.
- */
- if (codes.length >= 2 && codes[0] != code && codes[1] == code) {
- codes[1] = codes[0];
- codes[0] = code;
- }
- if (listener != null) {
- listener.onKey(code, codes, x, y);
- listener.onRelease(code);
- }
- }
- mLastSentIndex = index;
- mLastTapTime = eventTime;
- }
- }
-
- /**
- * Handle multi-tap keys by producing the key label for the current multi-tap state.
- */
- public CharSequence getPreviewText(Key key) {
- if (mInMultiTap) {
- // Multi-tap
- mPreviewLabel.setLength(0);
- mPreviewLabel.append((char) key.codes[mTapCount < 0 ? 0 : mTapCount]);
- return mPreviewLabel;
- } else {
- return key.label;
- }
- }
-
- private void resetMultiTap() {
- mLastSentIndex = NOT_A_KEY;
- mTapCount = 0;
- mLastTapTime = -1;
- mInMultiTap = false;
- }
-
- private void checkMultiTap(long eventTime, int keyIndex) {
- Key key = getKey(keyIndex);
- if (key == null)
- return;
-
- final boolean isMultiTap =
- (eventTime < mLastTapTime + mMultiTapKeyTimeout && keyIndex == mLastSentIndex);
- if (key.codes.length > 1) {
- mInMultiTap = true;
- if (isMultiTap) {
- mTapCount = (mTapCount + 1) % key.codes.length;
- return;
- } else {
- mTapCount = -1;
- return;
- }
- }
- if (!isMultiTap) {
- resetMultiTap();
- }
- }
-
- private void debugLog(String title, int x, int y) {
- int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
- Key key = getKey(keyIndex);
- final String code;
- if (key == null) {
- code = "----";
- } else {
- int primaryCode = key.codes[0];
- code = String.format((primaryCode < 0) ? "%4d" : "0x%02x", primaryCode);
- }
- Log.d(TAG, String.format("%s%s[%d] %3d,%3d %3d(%s) %s", title,
- (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, keyIndex, code,
- (isModifier() ? "modifier" : "")));
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ProximityKeyDetector.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ProximityKeyDetector.java
deleted file mode 100644
index 5c20c798..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ProximityKeyDetector.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import android.inputmethodservice.Keyboard.Key;
-
-import java.util.Arrays;
-
-class ProximityKeyDetector extends KeyDetector {
- private static final int MAX_NEARBY_KEYS = 12;
-
- // working area
- private int[] mDistances = new int[MAX_NEARBY_KEYS];
-
- @Override
- protected int getMaxNearbyKeys() {
- return MAX_NEARBY_KEYS;
- }
-
- @Override
- public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) {
- final Key[] keys = getKeys();
- final int touchX = getTouchX(x);
- final int touchY = getTouchY(y);
- int primaryIndex = LatinKeyboardBaseView.NOT_A_KEY;
- int closestKey = LatinKeyboardBaseView.NOT_A_KEY;
- int closestKeyDist = mProximityThresholdSquare + 1;
- int[] distances = mDistances;
- Arrays.fill(distances, Integer.MAX_VALUE);
- int [] nearestKeyIndices = mKeyboard.getNearestKeys(touchX, touchY);
- final int keyCount = nearestKeyIndices.length;
- for (int i = 0; i < keyCount; i++) {
- final Key key = keys[nearestKeyIndices[i]];
- int dist = 0;
- boolean isInside = key.isInside(touchX, touchY);
- if (isInside) {
- primaryIndex = nearestKeyIndices[i];
- }
-
- if (((mProximityCorrectOn
- && (dist = key.squaredDistanceFrom(touchX, touchY)) < mProximityThresholdSquare)
- || isInside)
- && key.codes[0] > 32) {
- // Find insertion point
- final int nCodes = key.codes.length;
- if (dist < closestKeyDist) {
- closestKeyDist = dist;
- closestKey = nearestKeyIndices[i];
- }
-
- if (allKeys == null) continue;
-
- for (int j = 0; j < distances.length; j++) {
- if (distances[j] > dist) {
- // Make space for nCodes codes
- System.arraycopy(distances, j, distances, j + nCodes,
- distances.length - j - nCodes);
- System.arraycopy(allKeys, j, allKeys, j + nCodes,
- allKeys.length - j - nCodes);
- System.arraycopy(key.codes, 0, allKeys, j, nCodes);
- Arrays.fill(distances, j, j + nCodes, dist);
- break;
- }
- }
- }
- }
- if (primaryIndex == LatinKeyboardBaseView.NOT_A_KEY) {
- primaryIndex = closestKey;
- }
- return primaryIndex;
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/SharedPreferencesCompat.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/SharedPreferencesCompat.java
deleted file mode 100644
index ee7e65ab..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/SharedPreferencesCompat.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import android.content.SharedPreferences;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Reflection utils to call SharedPreferences$Editor.apply when possible,
- * falling back to commit when apply isn't available.
- */
-public class SharedPreferencesCompat {
- private static final Method sApplyMethod = findApplyMethod();
-
- private static Method findApplyMethod() {
- try {
- return SharedPreferences.Editor.class.getMethod("apply");
- } catch (NoSuchMethodException unused) {
- // fall through
- }
- return null;
- }
-
- public static void apply(SharedPreferences.Editor editor) {
- if (sApplyMethod != null) {
- try {
- sApplyMethod.invoke(editor);
- return;
- } catch (InvocationTargetException unused) {
- // fall through
- } catch (IllegalAccessException unused) {
- // fall through
- }
- }
- editor.commit();
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Suggest.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Suggest.java
deleted file mode 100644
index 8b6883e8..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Suggest.java
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import android.content.Context;
-import android.text.AutoText;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * This class loads a dictionary and provides a list of suggestions for a given sequence of
- * characters. This includes corrections and completions.
- * @hide pending API Council Approval
- */
-public class Suggest implements Dictionary.WordCallback {
-
- public static final int APPROX_MAX_WORD_LENGTH = 32;
-
- public static final int CORRECTION_NONE = 0;
- public static final int CORRECTION_BASIC = 1;
- public static final int CORRECTION_FULL = 2;
- public static final int CORRECTION_FULL_BIGRAM = 3;
-
- /**
- * Words that appear in both bigram and unigram data gets multiplier ranging from
- * BIGRAM_MULTIPLIER_MIN to BIGRAM_MULTIPLIER_MAX depending on the frequency score from
- * bigram data.
- */
- public static final double BIGRAM_MULTIPLIER_MIN = 1.2;
- public static final double BIGRAM_MULTIPLIER_MAX = 1.5;
-
- /**
- * Maximum possible bigram frequency. Will depend on how many bits are being used in data
- * structure. Maximum bigram freqeuncy will get the BIGRAM_MULTIPLIER_MAX as the multiplier.
- */
- public static final int MAXIMUM_BIGRAM_FREQUENCY = 127;
-
- public static final int DIC_USER_TYPED = 0;
- public static final int DIC_MAIN = 1;
- public static final int DIC_USER = 2;
- public static final int DIC_AUTO = 3;
- public static final int DIC_CONTACTS = 4;
- // If you add a type of dictionary, increment DIC_TYPE_LAST_ID
- public static final int DIC_TYPE_LAST_ID = 4;
-
- static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
-
- private BinaryDictionary mMainDict;
-/*
- private Dictionary mUserDictionary;
-
- private Dictionary mAutoDictionary;
-
- private Dictionary mContactsDictionary;
-
- private Dictionary mUserBigramDictionary;
-*/
- private int mPrefMaxSuggestions = 12;
-
- private static final int PREF_MAX_BIGRAMS = 60;
-
- private boolean mAutoTextEnabled;
-
- private int[] mPriorities = new int[mPrefMaxSuggestions];
- private int[] mBigramPriorities = new int[PREF_MAX_BIGRAMS];
-
- // Handle predictive correction for only the first 1280 characters for performance reasons
- // If we support scripts that need latin characters beyond that, we should probably use some
- // kind of a sparse array or language specific list with a mapping lookup table.
- // 1280 is the size of the BASE_CHARS array in ExpandableDictionary, which is a basic set of
- // latin characters.
- private int[] mNextLettersFrequencies = new int[1280];
- private ArrayList mSuggestions = new ArrayList();
- ArrayList mBigramSuggestions = new ArrayList();
- private ArrayList mStringPool = new ArrayList();
- private boolean mHaveCorrection;
- private CharSequence mOriginalWord;
- private String mLowerOriginalWord;
-
- // TODO: Remove these member variables by passing more context to addWord() callback method
- private boolean mIsFirstCharCapitalized;
- private boolean mIsAllUpperCase;
-
- private int mCorrectionMode = CORRECTION_BASIC;
-
- public Suggest(Context context, int[] dictionaryResId) {
- mMainDict = new BinaryDictionary(context, dictionaryResId, DIC_MAIN);
-
-
- Locale locale = context.getResources().getConfiguration().locale;
- Log.d("KP2AK", "locale: " + locale.getISO3Language());
-
- if (!hasMainDictionary()
- || (!"eng".equals(locale.getISO3Language())))
- {
- Log.d("KP2AK", "try get plug");
- BinaryDictionary plug = PluginManager.getDictionary(context, locale.getLanguage());
- if (plug != null) {
- Log.d("KP2AK", "ok");
- mMainDict.close();
- mMainDict = plug;
- }
- }
-
-
- initPool();
- }
-
-
-
- private void initPool() {
- for (int i = 0; i < mPrefMaxSuggestions; i++) {
- StringBuilder sb = new StringBuilder(getApproxMaxWordLength());
- mStringPool.add(sb);
- }
- }
-
- public void setAutoTextEnabled(boolean enabled) {
- mAutoTextEnabled = enabled;
- }
-
- public int getCorrectionMode() {
- return mCorrectionMode;
- }
-
- public void setCorrectionMode(int mode) {
- mCorrectionMode = mode;
- }
-
- public boolean hasMainDictionary() {
- return mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD;
- }
-
- public int getApproxMaxWordLength() {
- return APPROX_MAX_WORD_LENGTH;
- }
-/*
- *//**
- * Sets an optional user dictionary resource to be loaded. The user dictionary is consulted
- * before the main dictionary, if set.
- *//*
- public void setUserDictionary(Dictionary userDictionary) {
- mUserDictionary = userDictionary;
- }
-
- *//**
- * Sets an optional contacts dictionary resource to be loaded.
- *//*
- public void setContactsDictionary(Dictionary userDictionary) {
- mContactsDictionary = userDictionary;
- }
-
- public void setAutoDictionary(Dictionary autoDictionary) {
- mAutoDictionary = autoDictionary;
- }
-
- public void setUserBigramDictionary(Dictionary userBigramDictionary) {
- mUserBigramDictionary = userBigramDictionary;
- }
-*/
- /**
- * Number of suggestions to generate from the input key sequence. This has
- * to be a number between 1 and 100 (inclusive).
- * @param maxSuggestions
- * @throws IllegalArgumentException if the number is out of range
- */
- public void setMaxSuggestions(int maxSuggestions) {
- if (maxSuggestions < 1 || maxSuggestions > 100) {
- throw new IllegalArgumentException("maxSuggestions must be between 1 and 100");
- }
- mPrefMaxSuggestions = maxSuggestions;
- mPriorities = new int[mPrefMaxSuggestions];
- mBigramPriorities = new int[PREF_MAX_BIGRAMS];
- collectGarbage(mSuggestions, mPrefMaxSuggestions);
- while (mStringPool.size() < mPrefMaxSuggestions) {
- StringBuilder sb = new StringBuilder(getApproxMaxWordLength());
- mStringPool.add(sb);
- }
- }
-
- private boolean haveSufficientCommonality(String original, CharSequence suggestion) {
- final int originalLength = original.length();
- final int suggestionLength = suggestion.length();
- final int minLength = Math.min(originalLength, suggestionLength);
- if (minLength <= 2) return true;
- int matching = 0;
- int lessMatching = 0; // Count matches if we skip one character
- int i;
- for (i = 0; i < minLength; i++) {
- final char origChar = ExpandableDictionary.toLowerCase(original.charAt(i));
- if (origChar == ExpandableDictionary.toLowerCase(suggestion.charAt(i))) {
- matching++;
- lessMatching++;
- } else if (i + 1 < suggestionLength
- && origChar == ExpandableDictionary.toLowerCase(suggestion.charAt(i + 1))) {
- lessMatching++;
- }
- }
- matching = Math.max(matching, lessMatching);
-
- if (minLength <= 4) {
- return matching >= 2;
- } else {
- return matching > minLength / 2;
- }
- }
-
- /**
- * Returns a list of words that match the list of character codes passed in.
- * This list will be overwritten the next time this function is called.
- * @param view a view for retrieving the context for AutoText
- * @param wordComposer contains what is currently being typed
- * @param prevWordForBigram previous word (used only for bigram)
- * @return list of suggestions.
- */
- public List getSuggestions(View view, WordComposer wordComposer,
- boolean includeTypedWordIfValid, CharSequence prevWordForBigram) {
- LatinImeLogger.onStartSuggestion(prevWordForBigram);
- mHaveCorrection = false;
- mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
- mIsAllUpperCase = wordComposer.isAllUpperCase();
- collectGarbage(mSuggestions, mPrefMaxSuggestions);
- Arrays.fill(mPriorities, 0);
- Arrays.fill(mNextLettersFrequencies, 0);
-
- // Save a lowercase version of the original word
- mOriginalWord = wordComposer.getTypedWord();
- if (mOriginalWord != null) {
- final String mOriginalWordString = mOriginalWord.toString();
- mOriginalWord = mOriginalWordString;
- mLowerOriginalWord = mOriginalWordString.toLowerCase();
- // Treating USER_TYPED as UNIGRAM suggestion for logging now.
- LatinImeLogger.onAddSuggestedWord(mOriginalWordString, Suggest.DIC_USER_TYPED,
- Dictionary.DataType.UNIGRAM);
- } else {
- mLowerOriginalWord = "";
- }
-
- if (wordComposer.size() == 1 && (mCorrectionMode == CORRECTION_FULL_BIGRAM
- || mCorrectionMode == CORRECTION_BASIC)) {
- // At first character typed, search only the bigrams
- Arrays.fill(mBigramPriorities, 0);
- collectGarbage(mBigramSuggestions, PREF_MAX_BIGRAMS);
-
- if (!TextUtils.isEmpty(prevWordForBigram)) {
- CharSequence lowerPrevWord = prevWordForBigram.toString().toLowerCase();
- if (mMainDict.isValidWord(lowerPrevWord)) {
- prevWordForBigram = lowerPrevWord;
- }
- /*if (mUserBigramDictionary != null) {
- mUserBigramDictionary.getBigrams(wordComposer, prevWordForBigram, this,
- mNextLettersFrequencies);
- }
- if (mContactsDictionary != null) {
- mContactsDictionary.getBigrams(wordComposer, prevWordForBigram, this,
- mNextLettersFrequencies);
- }*/
- if (mMainDict != null) {
- mMainDict.getBigrams(wordComposer, prevWordForBigram, this,
- mNextLettersFrequencies);
- }
- char currentChar = wordComposer.getTypedWord().charAt(0);
- // TODO: Must pay attention to locale when changing case.
- char currentCharUpper = Character.toUpperCase(currentChar);
- int count = 0;
- int bigramSuggestionSize = mBigramSuggestions.size();
- for (int i = 0; i < bigramSuggestionSize; i++) {
- if (mBigramSuggestions.get(i).charAt(0) == currentChar
- || mBigramSuggestions.get(i).charAt(0) == currentCharUpper) {
- int poolSize = mStringPool.size();
- StringBuilder sb = poolSize > 0 ?
- (StringBuilder) mStringPool.remove(poolSize - 1)
- : new StringBuilder(getApproxMaxWordLength());
- sb.setLength(0);
- sb.append(mBigramSuggestions.get(i));
- mSuggestions.add(count++, sb);
- if (count > mPrefMaxSuggestions) break;
- }
- }
- }
-
- } else if (wordComposer.size() > 1) {
- // At second character typed, search the unigrams (scores being affected by bigrams)
- /*if (mUserDictionary != null || mContactsDictionary != null) {
- if (mUserDictionary != null) {
- mUserDictionary.getWords(wordComposer, this, mNextLettersFrequencies);
- }
- if (mContactsDictionary != null) {
- mContactsDictionary.getWords(wordComposer, this, mNextLettersFrequencies);
- }
-
- if (mSuggestions.size() > 0 && isValidWord(mOriginalWord)
- && (mCorrectionMode == CORRECTION_FULL
- || mCorrectionMode == CORRECTION_FULL_BIGRAM)) {
- mHaveCorrection = true;
- }
- }*/
- mMainDict.getWords(wordComposer, this, mNextLettersFrequencies);
- if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)
- && mSuggestions.size() > 0) {
- mHaveCorrection = true;
- }
- }
- if (mOriginalWord != null) {
- mSuggestions.add(0, mOriginalWord.toString());
- }
-
- // Check if the first suggestion has a minimum number of characters in common
- if (wordComposer.size() > 1 && mSuggestions.size() > 1
- && (mCorrectionMode == CORRECTION_FULL
- || mCorrectionMode == CORRECTION_FULL_BIGRAM)) {
- if (!haveSufficientCommonality(mLowerOriginalWord, mSuggestions.get(1))) {
- mHaveCorrection = false;
- }
- }
- if (mAutoTextEnabled) {
- int i = 0;
- int max = 6;
- // Don't autotext the suggestions from the dictionaries
- if (mCorrectionMode == CORRECTION_BASIC) max = 1;
- while (i < mSuggestions.size() && i < max) {
- String suggestedWord = mSuggestions.get(i).toString().toLowerCase();
- CharSequence autoText =
- AutoText.get(suggestedWord, 0, suggestedWord.length(), view);
- // Is there an AutoText correction?
- boolean canAdd = autoText != null;
- // Is that correction already the current prediction (or original word)?
- canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i));
- // Is that correction already the next predicted word?
- if (canAdd && i + 1 < mSuggestions.size() && mCorrectionMode != CORRECTION_BASIC) {
- canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i + 1));
- }
- if (canAdd) {
- mHaveCorrection = true;
- mSuggestions.add(i + 1, autoText);
- i++;
- }
- i++;
- }
- }
- removeDupes();
- return mSuggestions;
- }
-
- public int[] getNextLettersFrequencies() {
- return mNextLettersFrequencies;
- }
-
- private void removeDupes() {
- final ArrayList suggestions = mSuggestions;
- if (suggestions.size() < 2) return;
- int i = 1;
- // Don't cache suggestions.size(), since we may be removing items
- while (i < suggestions.size()) {
- final CharSequence cur = suggestions.get(i);
- // Compare each candidate with each previous candidate
- for (int j = 0; j < i; j++) {
- CharSequence previous = suggestions.get(j);
- if (TextUtils.equals(cur, previous)) {
- removeFromSuggestions(i);
- i--;
- break;
- }
- }
- i++;
- }
- }
-
- private void removeFromSuggestions(int index) {
- CharSequence garbage = mSuggestions.remove(index);
- if (garbage != null && garbage instanceof StringBuilder) {
- mStringPool.add(garbage);
- }
- }
-
- public boolean hasMinimalCorrection() {
- return mHaveCorrection;
- }
-
- private boolean compareCaseInsensitive(final String mLowerOriginalWord,
- final char[] word, final int offset, final int length) {
- final int originalLength = mLowerOriginalWord.length();
- if (originalLength == length && Character.isUpperCase(word[offset])) {
- for (int i = 0; i < originalLength; i++) {
- if (mLowerOriginalWord.charAt(i) != Character.toLowerCase(word[offset+i])) {
- return false;
- }
- }
- return true;
- }
- return false;
- }
-
- public boolean addWord(final char[] word, final int offset, final int length, int freq,
- final int dicTypeId, final Dictionary.DataType dataType) {
- Dictionary.DataType dataTypeForLog = dataType;
- ArrayList suggestions;
- int[] priorities;
- int prefMaxSuggestions;
- if(dataType == Dictionary.DataType.BIGRAM) {
- suggestions = mBigramSuggestions;
- priorities = mBigramPriorities;
- prefMaxSuggestions = PREF_MAX_BIGRAMS;
- } else {
- suggestions = mSuggestions;
- priorities = mPriorities;
- prefMaxSuggestions = mPrefMaxSuggestions;
- }
-
- int pos = 0;
-
- // Check if it's the same word, only caps are different
- if (compareCaseInsensitive(mLowerOriginalWord, word, offset, length)) {
- pos = 0;
- } else {
- if (dataType == Dictionary.DataType.UNIGRAM) {
- // Check if the word was already added before (by bigram data)
- int bigramSuggestion = searchBigramSuggestion(word,offset,length);
- if(bigramSuggestion >= 0) {
- dataTypeForLog = Dictionary.DataType.BIGRAM;
- // turn freq from bigram into multiplier specified above
- double multiplier = (((double) mBigramPriorities[bigramSuggestion])
- / MAXIMUM_BIGRAM_FREQUENCY)
- * (BIGRAM_MULTIPLIER_MAX - BIGRAM_MULTIPLIER_MIN)
- + BIGRAM_MULTIPLIER_MIN;
- /* Log.d(TAG,"bigram num: " + bigramSuggestion
- + " wordB: " + mBigramSuggestions.get(bigramSuggestion).toString()
- + " currentPriority: " + freq + " bigramPriority: "
- + mBigramPriorities[bigramSuggestion]
- + " multiplier: " + multiplier); */
- freq = (int)Math.round((freq * multiplier));
- }
- }
-
- // Check the last one's priority and bail
- if (priorities[prefMaxSuggestions - 1] >= freq) return true;
- while (pos < prefMaxSuggestions) {
- if (priorities[pos] < freq
- || (priorities[pos] == freq && length < suggestions.get(pos).length())) {
- break;
- }
- pos++;
- }
- }
- if (pos >= prefMaxSuggestions) {
- return true;
- }
-
- System.arraycopy(priorities, pos, priorities, pos + 1,
- prefMaxSuggestions - pos - 1);
- priorities[pos] = freq;
- int poolSize = mStringPool.size();
- StringBuilder sb = poolSize > 0 ? (StringBuilder) mStringPool.remove(poolSize - 1)
- : new StringBuilder(getApproxMaxWordLength());
- sb.setLength(0);
- // TODO: Must pay attention to locale when changing case.
- if (mIsAllUpperCase) {
- sb.append(new String(word, offset, length).toUpperCase());
- } else if (mIsFirstCharCapitalized) {
- sb.append(Character.toUpperCase(word[offset]));
- if (length > 1) {
- sb.append(word, offset + 1, length - 1);
- }
- } else {
- sb.append(word, offset, length);
- }
- suggestions.add(pos, sb);
- if (suggestions.size() > prefMaxSuggestions) {
- CharSequence garbage = suggestions.remove(prefMaxSuggestions);
- if (garbage instanceof StringBuilder) {
- mStringPool.add(garbage);
- }
- } else {
- LatinImeLogger.onAddSuggestedWord(sb.toString(), dicTypeId, dataTypeForLog);
- }
- return true;
- }
-
- private int searchBigramSuggestion(final char[] word, final int offset, final int length) {
- // TODO This is almost O(n^2). Might need fix.
- // search whether the word appeared in bigram data
- int bigramSuggestSize = mBigramSuggestions.size();
- for(int i = 0; i < bigramSuggestSize; i++) {
- if(mBigramSuggestions.get(i).length() == length) {
- boolean chk = true;
- for(int j = 0; j < length; j++) {
- if(mBigramSuggestions.get(i).charAt(j) != word[offset+j]) {
- chk = false;
- break;
- }
- }
- if(chk) return i;
- }
- }
-
- return -1;
- }
-
- public boolean isValidWord(final CharSequence word) {
- if (word == null || word.length() == 0) {
- return false;
- }
- return mMainDict.isValidWord(word)
- /*|| (mUserDictionary != null && mUserDictionary.isValidWord(word))
- || (mAutoDictionary != null && mAutoDictionary.isValidWord(word))
- || (mContactsDictionary != null && mContactsDictionary.isValidWord(word))*/;
- }
-
- private void collectGarbage(ArrayList suggestions, int prefMaxSuggestions) {
- int poolSize = mStringPool.size();
- int garbageSize = suggestions.size();
- while (poolSize < prefMaxSuggestions && garbageSize > 0) {
- CharSequence garbage = suggestions.get(garbageSize - 1);
- if (garbage != null && garbage instanceof StringBuilder) {
- mStringPool.add(garbage);
- poolSize++;
- }
- garbageSize--;
- }
- if (poolSize == prefMaxSuggestions + 1) {
- Log.w("Suggest", "String pool got too big: " + poolSize);
- }
- suggestions.clear();
- }
-
- public void close() {
- if (mMainDict != null) {
- mMainDict.close();
- }
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/SwipeTracker.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/SwipeTracker.java
deleted file mode 100644
index c5a522e1..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/SwipeTracker.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import android.view.MotionEvent;
-
-class SwipeTracker {
- private static final int NUM_PAST = 4;
- private static final int LONGEST_PAST_TIME = 200;
-
- final EventRingBuffer mBuffer = new EventRingBuffer(NUM_PAST);
-
- private float mYVelocity;
- private float mXVelocity;
-
- public void addMovement(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mBuffer.clear();
- return;
- }
- long time = ev.getEventTime();
- final int count = ev.getHistorySize();
- for (int i = 0; i < count; i++) {
- addPoint(ev.getHistoricalX(i), ev.getHistoricalY(i), ev.getHistoricalEventTime(i));
- }
- addPoint(ev.getX(), ev.getY(), time);
- }
-
- private void addPoint(float x, float y, long time) {
- final EventRingBuffer buffer = mBuffer;
- while (buffer.size() > 0) {
- long lastT = buffer.getTime(0);
- if (lastT >= time - LONGEST_PAST_TIME)
- break;
- buffer.dropOldest();
- }
- buffer.add(x, y, time);
- }
-
- public void computeCurrentVelocity(int units) {
- computeCurrentVelocity(units, Float.MAX_VALUE);
- }
-
- public void computeCurrentVelocity(int units, float maxVelocity) {
- final EventRingBuffer buffer = mBuffer;
- final float oldestX = buffer.getX(0);
- final float oldestY = buffer.getY(0);
- final long oldestTime = buffer.getTime(0);
-
- float accumX = 0;
- float accumY = 0;
- final int count = buffer.size();
- for (int pos = 1; pos < count; pos++) {
- final int dur = (int)(buffer.getTime(pos) - oldestTime);
- if (dur == 0) continue;
- float dist = buffer.getX(pos) - oldestX;
- float vel = (dist / dur) * units; // pixels/frame.
- if (accumX == 0) accumX = vel;
- else accumX = (accumX + vel) * .5f;
-
- dist = buffer.getY(pos) - oldestY;
- vel = (dist / dur) * units; // pixels/frame.
- if (accumY == 0) accumY = vel;
- else accumY = (accumY + vel) * .5f;
- }
- mXVelocity = accumX < 0.0f ? Math.max(accumX, -maxVelocity)
- : Math.min(accumX, maxVelocity);
- mYVelocity = accumY < 0.0f ? Math.max(accumY, -maxVelocity)
- : Math.min(accumY, maxVelocity);
- }
-
- public float getXVelocity() {
- return mXVelocity;
- }
-
- public float getYVelocity() {
- return mYVelocity;
- }
-
- static class EventRingBuffer {
- private final int bufSize;
- private final float xBuf[];
- private final float yBuf[];
- private final long timeBuf[];
- private int top; // points new event
- private int end; // points oldest event
- private int count; // the number of valid data
-
- public EventRingBuffer(int max) {
- this.bufSize = max;
- xBuf = new float[max];
- yBuf = new float[max];
- timeBuf = new long[max];
- clear();
- }
-
- public void clear() {
- top = end = count = 0;
- }
-
- public int size() {
- return count;
- }
-
- // Position 0 points oldest event
- private int index(int pos) {
- return (end + pos) % bufSize;
- }
-
- private int advance(int index) {
- return (index + 1) % bufSize;
- }
-
- public void add(float x, float y, long time) {
- xBuf[top] = x;
- yBuf[top] = y;
- timeBuf[top] = time;
- top = advance(top);
- if (count < bufSize) {
- count++;
- } else {
- end = advance(end);
- }
- }
-
- public float getX(int pos) {
- return xBuf[index(pos)];
- }
-
- public float getY(int pos) {
- return yBuf[index(pos)];
- }
-
- public long getTime(int pos) {
- return timeBuf[index(pos)];
- }
-
- public void dropOldest() {
- count--;
- end = advance(end);
- }
- }
-}
\ No newline at end of file
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/TextEntryState.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/TextEntryState.java
deleted file mode 100644
index 4950425f..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/TextEntryState.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import android.content.Context;
-import android.inputmethodservice.Keyboard.Key;
-import android.text.format.DateFormat;
-import android.util.Log;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Calendar;
-
-public class TextEntryState {
-
- private static final boolean DBG = false;
-
- private static final String TAG = "TextEntryState";
-
- private static boolean LOGGING = false;
-
- private static int sBackspaceCount = 0;
-
- private static int sAutoSuggestCount = 0;
-
- private static int sAutoSuggestUndoneCount = 0;
-
- private static int sManualSuggestCount = 0;
-
- private static int sWordNotInDictionaryCount = 0;
-
- private static int sSessionCount = 0;
-
- private static int sTypedChars;
-
- private static int sActualChars;
-
- public enum State {
- UNKNOWN,
- START,
- IN_WORD,
- ACCEPTED_DEFAULT,
- PICKED_SUGGESTION,
- PUNCTUATION_AFTER_WORD,
- PUNCTUATION_AFTER_ACCEPTED,
- SPACE_AFTER_ACCEPTED,
- SPACE_AFTER_PICKED,
- UNDO_COMMIT,
- CORRECTING,
- PICKED_CORRECTION;
- }
-
- private static State sState = State.UNKNOWN;
-
- private static FileOutputStream sKeyLocationFile;
- private static FileOutputStream sUserActionFile;
-
- public static void newSession(Context context) {
- sSessionCount++;
- sAutoSuggestCount = 0;
- sBackspaceCount = 0;
- sAutoSuggestUndoneCount = 0;
- sManualSuggestCount = 0;
- sWordNotInDictionaryCount = 0;
- sTypedChars = 0;
- sActualChars = 0;
- sState = State.START;
-
- if (LOGGING) {
- try {
- sKeyLocationFile = context.openFileOutput("key.txt", Context.MODE_APPEND);
- sUserActionFile = context.openFileOutput("action.txt", Context.MODE_APPEND);
- } catch (IOException ioe) {
- Log.e("TextEntryState", "Couldn't open file for output: " + ioe);
- }
- }
- }
-
- public static void endSession() {
- if (sKeyLocationFile == null) {
- return;
- }
- try {
- sKeyLocationFile.close();
- // Write to log file
- // Write timestamp, settings,
- String out = DateFormat.format("MM:dd hh:mm:ss", Calendar.getInstance().getTime())
- .toString()
- + " BS: " + sBackspaceCount
- + " auto: " + sAutoSuggestCount
- + " manual: " + sManualSuggestCount
- + " typed: " + sWordNotInDictionaryCount
- + " undone: " + sAutoSuggestUndoneCount
- + " saved: " + ((float) (sActualChars - sTypedChars) / sActualChars)
- + "\n";
- sUserActionFile.write(out.getBytes());
- sUserActionFile.close();
- sKeyLocationFile = null;
- sUserActionFile = null;
- } catch (IOException ioe) {
-
- }
- }
-
- public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord) {
- if (typedWord == null) return;
- if (!typedWord.equals(actualWord)) {
- sAutoSuggestCount++;
- }
- sTypedChars += typedWord.length();
- sActualChars += actualWord.length();
- sState = State.ACCEPTED_DEFAULT;
- LatinImeLogger.logOnAutoSuggestion(typedWord.toString(), actualWord.toString());
- displayState();
- }
-
- // State.ACCEPTED_DEFAULT will be changed to other sub-states
- // (see "case ACCEPTED_DEFAULT" in typedCharacter() below),
- // and should be restored back to State.ACCEPTED_DEFAULT after processing for each sub-state.
- public static void backToAcceptedDefault(CharSequence typedWord) {
- if (typedWord == null) return;
- switch (sState) {
- case SPACE_AFTER_ACCEPTED:
- case PUNCTUATION_AFTER_ACCEPTED:
- case IN_WORD:
- sState = State.ACCEPTED_DEFAULT;
- break;
- }
- displayState();
- }
-
- public static void acceptedTyped(CharSequence typedWord) {
- sWordNotInDictionaryCount++;
- sState = State.PICKED_SUGGESTION;
- displayState();
- }
-
- public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) {
- sManualSuggestCount++;
- State oldState = sState;
- if (typedWord.equals(actualWord)) {
- acceptedTyped(typedWord);
- }
- if (oldState == State.CORRECTING || oldState == State.PICKED_CORRECTION) {
- sState = State.PICKED_CORRECTION;
- } else {
- sState = State.PICKED_SUGGESTION;
- }
- displayState();
- }
-
- public static void selectedForCorrection() {
- sState = State.CORRECTING;
- displayState();
- }
-
- public static void typedCharacter(char c, boolean isSeparator) {
- boolean isSpace = c == ' ';
- switch (sState) {
- case IN_WORD:
- if (isSpace || isSeparator) {
- sState = State.START;
- } else {
- // State hasn't changed.
- }
- break;
- case ACCEPTED_DEFAULT:
- case SPACE_AFTER_PICKED:
- if (isSpace) {
- sState = State.SPACE_AFTER_ACCEPTED;
- } else if (isSeparator) {
- sState = State.PUNCTUATION_AFTER_ACCEPTED;
- } else {
- sState = State.IN_WORD;
- }
- break;
- case PICKED_SUGGESTION:
- case PICKED_CORRECTION:
- if (isSpace) {
- sState = State.SPACE_AFTER_PICKED;
- } else if (isSeparator) {
- // Swap
- sState = State.PUNCTUATION_AFTER_ACCEPTED;
- } else {
- sState = State.IN_WORD;
- }
- break;
- case START:
- case UNKNOWN:
- case SPACE_AFTER_ACCEPTED:
- case PUNCTUATION_AFTER_ACCEPTED:
- case PUNCTUATION_AFTER_WORD:
- if (!isSpace && !isSeparator) {
- sState = State.IN_WORD;
- } else {
- sState = State.START;
- }
- break;
- case UNDO_COMMIT:
- if (isSpace || isSeparator) {
- sState = State.ACCEPTED_DEFAULT;
- } else {
- sState = State.IN_WORD;
- }
- break;
- case CORRECTING:
- sState = State.START;
- break;
- }
- displayState();
- }
-
- public static void backspace() {
- if (sState == State.ACCEPTED_DEFAULT) {
- sState = State.UNDO_COMMIT;
- sAutoSuggestUndoneCount++;
- LatinImeLogger.logOnAutoSuggestionCanceled();
- } else if (sState == State.UNDO_COMMIT) {
- sState = State.IN_WORD;
- }
- sBackspaceCount++;
- displayState();
- }
-
- public static void reset() {
- sState = State.START;
- displayState();
- }
-
- public static State getState() {
- if (DBG) {
- Log.d(TAG, "Returning state = " + sState);
- }
- return sState;
- }
-
- public static boolean isCorrecting() {
- return sState == State.CORRECTING || sState == State.PICKED_CORRECTION;
- }
-
- public static void keyPressedAt(Key key, int x, int y) {
- if (LOGGING && sKeyLocationFile != null && key.codes[0] >= 32) {
- String out =
- "KEY: " + (char) key.codes[0]
- + " X: " + x
- + " Y: " + y
- + " MX: " + (key.x + key.width / 2)
- + " MY: " + (key.y + key.height / 2)
- + "\n";
- try {
- sKeyLocationFile.write(out.getBytes());
- } catch (IOException ioe) {
- // TODO: May run out of space
- }
- }
- }
-
- private static void displayState() {
- if (DBG) {
- Log.d(TAG, "State = " + sState);
- }
- }
-}
-
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/UserBigramDictionary.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/UserBigramDictionary.java
deleted file mode 100644
index 820c2a8d..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/UserBigramDictionary.java
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.os.AsyncTask;
-import android.provider.BaseColumns;
-import android.util.Log;
-
-/**
- * Stores all the pairs user types in databases. Prune the database if the size
- * gets too big. Unlike AutoDictionary, it even stores the pairs that are already
- * in the dictionary.
- */
-public class UserBigramDictionary extends ExpandableDictionary {
- private static final String TAG = "UserBigramDictionary";
-
- /** Any pair being typed or picked */
- private static final int FREQUENCY_FOR_TYPED = 2;
-
- /** Maximum frequency for all pairs */
- private static final int FREQUENCY_MAX = 127;
-
- /**
- * If this pair is typed 6 times, it would be suggested.
- * Should be smaller than ContactsDictionary.FREQUENCY_FOR_CONTACTS_BIGRAM
- */
- protected static final int SUGGEST_THRESHOLD = 6 * FREQUENCY_FOR_TYPED;
-
- /** Maximum number of pairs. Pruning will start when databases goes above this number. */
- private static int sMaxUserBigrams = 10000;
-
- /**
- * When it hits maximum bigram pair, it will delete until you are left with
- * only (sMaxUserBigrams - sDeleteUserBigrams) pairs.
- * Do not keep this number small to avoid deleting too often.
- */
- private static int sDeleteUserBigrams = 1000;
-
- /**
- * Database version should increase if the database structure changes
- */
- private static final int DATABASE_VERSION = 1;
-
- private static final String DATABASE_NAME = "userbigram_dict.db";
-
- /** Name of the words table in the database */
- private static final String MAIN_TABLE_NAME = "main";
- // TODO: Consume less space by using a unique id for locale instead of the whole
- // 2-5 character string. (Same TODO from AutoDictionary)
- private static final String MAIN_COLUMN_ID = BaseColumns._ID;
- private static final String MAIN_COLUMN_WORD1 = "word1";
- private static final String MAIN_COLUMN_WORD2 = "word2";
- private static final String MAIN_COLUMN_LOCALE = "locale";
-
- /** Name of the frequency table in the database */
- private static final String FREQ_TABLE_NAME = "frequency";
- private static final String FREQ_COLUMN_ID = BaseColumns._ID;
- private static final String FREQ_COLUMN_PAIR_ID = "pair_id";
- private static final String FREQ_COLUMN_FREQUENCY = "freq";
-
- private final KP2AKeyboard mIme;
-
- /** Locale for which this auto dictionary is storing words */
- private String mLocale;
-
- private HashSet mPendingWrites = new HashSet();
- private final Object mPendingWritesLock = new Object();
- private static volatile boolean sUpdatingDB = false;
-
- private final static HashMap sDictProjectionMap;
-
- static {
- sDictProjectionMap = new HashMap();
- sDictProjectionMap.put(MAIN_COLUMN_ID, MAIN_COLUMN_ID);
- sDictProjectionMap.put(MAIN_COLUMN_WORD1, MAIN_COLUMN_WORD1);
- sDictProjectionMap.put(MAIN_COLUMN_WORD2, MAIN_COLUMN_WORD2);
- sDictProjectionMap.put(MAIN_COLUMN_LOCALE, MAIN_COLUMN_LOCALE);
-
- sDictProjectionMap.put(FREQ_COLUMN_ID, FREQ_COLUMN_ID);
- sDictProjectionMap.put(FREQ_COLUMN_PAIR_ID, FREQ_COLUMN_PAIR_ID);
- sDictProjectionMap.put(FREQ_COLUMN_FREQUENCY, FREQ_COLUMN_FREQUENCY);
- }
-
- private static DatabaseHelper sOpenHelper = null;
-
- private static class Bigram {
- String word1;
- String word2;
- int frequency;
-
- Bigram(String word1, String word2, int frequency) {
- this.word1 = word1;
- this.word2 = word2;
- this.frequency = frequency;
- }
-
- @Override
- public boolean equals(Object bigram) {
- Bigram bigram2 = (Bigram) bigram;
- return (word1.equals(bigram2.word1) && word2.equals(bigram2.word2));
- }
-
- @Override
- public int hashCode() {
- return (word1 + " " + word2).hashCode();
- }
- }
-
- public void setDatabaseMax(int maxUserBigram) {
- sMaxUserBigrams = maxUserBigram;
- }
-
- public void setDatabaseDelete(int deleteUserBigram) {
- sDeleteUserBigrams = deleteUserBigram;
- }
-
- public UserBigramDictionary(Context context, KP2AKeyboard ime, String locale, int dicTypeId) {
- super(context, dicTypeId);
- mIme = ime;
- mLocale = locale;
- if (sOpenHelper == null) {
- sOpenHelper = new DatabaseHelper(getContext());
- }
- if (mLocale != null && mLocale.length() > 1) {
- loadDictionary();
- }
- }
-
- @Override
- public void close() {
- flushPendingWrites();
- // Don't close the database as locale changes will require it to be reopened anyway
- // Also, the database is written to somewhat frequently, so it needs to be kept alive
- // throughout the life of the process.
- // mOpenHelper.close();
- super.close();
- }
-
- /**
- * Pair will be added to the userbigram database.
- */
- public int addBigrams(String word1, String word2) {
- // remove caps
- if (mIme != null && mIme.getCurrentWord().isAutoCapitalized()) {
- word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1);
- }
-
- int freq = super.addBigram(word1, word2, FREQUENCY_FOR_TYPED);
- if (freq > FREQUENCY_MAX) freq = FREQUENCY_MAX;
- synchronized (mPendingWritesLock) {
- if (freq == FREQUENCY_FOR_TYPED || mPendingWrites.isEmpty()) {
- mPendingWrites.add(new Bigram(word1, word2, freq));
- } else {
- Bigram bi = new Bigram(word1, word2, freq);
- mPendingWrites.remove(bi);
- mPendingWrites.add(bi);
- }
- }
-
- return freq;
- }
-
- /**
- * Schedules a background thread to write any pending words to the database.
- */
- public void flushPendingWrites() {
- synchronized (mPendingWritesLock) {
- // Nothing pending? Return
- if (mPendingWrites.isEmpty()) return;
- // Create a background thread to write the pending entries
- new UpdateDbTask(getContext(), sOpenHelper, mPendingWrites, mLocale).execute();
- // Create a new map for writing new entries into while the old one is written to db
- mPendingWrites = new HashSet();
- }
- }
-
- /** Used for testing purpose **/
- void waitUntilUpdateDBDone() {
- synchronized (mPendingWritesLock) {
- while (sUpdatingDB) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- }
- }
- return;
- }
- }
-
- @Override
- public void loadDictionaryAsync() {
- // Load the words that correspond to the current input locale
- Cursor cursor = query(MAIN_COLUMN_LOCALE + "=?", new String[] { mLocale });
- try {
- if (cursor.moveToFirst()) {
- int word1Index = cursor.getColumnIndex(MAIN_COLUMN_WORD1);
- int word2Index = cursor.getColumnIndex(MAIN_COLUMN_WORD2);
- int frequencyIndex = cursor.getColumnIndex(FREQ_COLUMN_FREQUENCY);
- while (!cursor.isAfterLast()) {
- String word1 = cursor.getString(word1Index);
- String word2 = cursor.getString(word2Index);
- int frequency = cursor.getInt(frequencyIndex);
- // Safeguard against adding really long words. Stack may overflow due
- // to recursive lookup
- if (word1.length() < MAX_WORD_LENGTH && word2.length() < MAX_WORD_LENGTH) {
- super.setBigram(word1, word2, frequency);
- }
- cursor.moveToNext();
- }
- }
- } finally {
- cursor.close();
- }
- }
-
- /**
- * Query the database
- */
- private Cursor query(String selection, String[] selectionArgs) {
- SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-
- // main INNER JOIN frequency ON (main._id=freq.pair_id)
- qb.setTables(MAIN_TABLE_NAME + " INNER JOIN " + FREQ_TABLE_NAME + " ON ("
- + MAIN_TABLE_NAME + "." + MAIN_COLUMN_ID + "=" + FREQ_TABLE_NAME + "."
- + FREQ_COLUMN_PAIR_ID +")");
-
- qb.setProjectionMap(sDictProjectionMap);
-
- // Get the database and run the query
- SQLiteDatabase db = sOpenHelper.getReadableDatabase();
- Cursor c = qb.query(db,
- new String[] { MAIN_COLUMN_WORD1, MAIN_COLUMN_WORD2, FREQ_COLUMN_FREQUENCY },
- selection, selectionArgs, null, null, null);
- return c;
- }
-
- /**
- * This class helps open, create, and upgrade the database file.
- */
- private static class DatabaseHelper extends SQLiteOpenHelper {
-
- DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL("PRAGMA foreign_keys = ON;");
- db.execSQL("CREATE TABLE " + MAIN_TABLE_NAME + " ("
- + MAIN_COLUMN_ID + " INTEGER PRIMARY KEY,"
- + MAIN_COLUMN_WORD1 + " TEXT,"
- + MAIN_COLUMN_WORD2 + " TEXT,"
- + MAIN_COLUMN_LOCALE + " TEXT"
- + ");");
- db.execSQL("CREATE TABLE " + FREQ_TABLE_NAME + " ("
- + FREQ_COLUMN_ID + " INTEGER PRIMARY KEY,"
- + FREQ_COLUMN_PAIR_ID + " INTEGER,"
- + FREQ_COLUMN_FREQUENCY + " INTEGER,"
- + "FOREIGN KEY(" + FREQ_COLUMN_PAIR_ID + ") REFERENCES " + MAIN_TABLE_NAME
- + "(" + MAIN_COLUMN_ID + ")" + " ON DELETE CASCADE"
- + ");");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
- + newVersion + ", which will destroy all old data");
- db.execSQL("DROP TABLE IF EXISTS " + MAIN_TABLE_NAME);
- db.execSQL("DROP TABLE IF EXISTS " + FREQ_TABLE_NAME);
- onCreate(db);
- }
- }
-
- /**
- * Async task to write pending words to the database so that it stays in sync with
- * the in-memory trie.
- */
- private static class UpdateDbTask extends AsyncTask {
- private final HashSet mMap;
- private final DatabaseHelper mDbHelper;
- private final String mLocale;
-
- public UpdateDbTask(Context context, DatabaseHelper openHelper,
- HashSet pendingWrites, String locale) {
- mMap = pendingWrites;
- mLocale = locale;
- mDbHelper = openHelper;
- }
-
- /** Prune any old data if the database is getting too big. */
- private void checkPruneData(SQLiteDatabase db) {
- db.execSQL("PRAGMA foreign_keys = ON;");
- Cursor c = db.query(FREQ_TABLE_NAME, new String[] { FREQ_COLUMN_PAIR_ID },
- null, null, null, null, null);
- try {
- int totalRowCount = c.getCount();
- // prune out old data if we have too much data
- if (totalRowCount > sMaxUserBigrams) {
- int numDeleteRows = (totalRowCount - sMaxUserBigrams) + sDeleteUserBigrams;
- int pairIdColumnId = c.getColumnIndex(FREQ_COLUMN_PAIR_ID);
- c.moveToFirst();
- int count = 0;
- while (count < numDeleteRows && !c.isAfterLast()) {
- String pairId = c.getString(pairIdColumnId);
- // Deleting from MAIN table will delete the frequencies
- // due to FOREIGN KEY .. ON DELETE CASCADE
- db.delete(MAIN_TABLE_NAME, MAIN_COLUMN_ID + "=?",
- new String[] { pairId });
- c.moveToNext();
- count++;
- }
- }
- } finally {
- c.close();
- }
- }
-
- @Override
- protected void onPreExecute() {
- sUpdatingDB = true;
- }
-
- @Override
- protected Void doInBackground(Void... v) {
- SQLiteDatabase db = mDbHelper.getWritableDatabase();
- db.execSQL("PRAGMA foreign_keys = ON;");
- // Write all the entries to the db
- Iterator iterator = mMap.iterator();
- while (iterator.hasNext()) {
- Bigram bi = iterator.next();
-
- // find pair id
- Cursor c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID },
- MAIN_COLUMN_WORD1 + "=? AND " + MAIN_COLUMN_WORD2 + "=? AND "
- + MAIN_COLUMN_LOCALE + "=?",
- new String[] { bi.word1, bi.word2, mLocale }, null, null, null);
-
- int pairId;
- if (c.moveToFirst()) {
- // existing pair
- pairId = c.getInt(c.getColumnIndex(MAIN_COLUMN_ID));
- db.delete(FREQ_TABLE_NAME, FREQ_COLUMN_PAIR_ID + "=?",
- new String[] { Integer.toString(pairId) });
- } else {
- // new pair
- Long pairIdLong = db.insert(MAIN_TABLE_NAME, null,
- getContentValues(bi.word1, bi.word2, mLocale));
- pairId = pairIdLong.intValue();
- }
- c.close();
-
- // insert new frequency
- db.insert(FREQ_TABLE_NAME, null, getFrequencyContentValues(pairId, bi.frequency));
- }
- checkPruneData(db);
- sUpdatingDB = false;
-
- return null;
- }
-
- private ContentValues getContentValues(String word1, String word2, String locale) {
- ContentValues values = new ContentValues(3);
- values.put(MAIN_COLUMN_WORD1, word1);
- values.put(MAIN_COLUMN_WORD2, word2);
- values.put(MAIN_COLUMN_LOCALE, locale);
- return values;
- }
-
- private ContentValues getFrequencyContentValues(int pairId, int frequency) {
- ContentValues values = new ContentValues(2);
- values.put(FREQ_COLUMN_PAIR_ID, pairId);
- values.put(FREQ_COLUMN_FREQUENCY, frequency);
- return values;
- }
- }
-
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/UserDictionary.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/UserDictionary.java
deleted file mode 100644
index 5366d6f0..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/UserDictionary.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.provider.UserDictionary.Words;
-
-public class UserDictionary extends ExpandableDictionary {
-
- private static final String[] PROJECTION = {
- Words._ID,
- Words.WORD,
- Words.FREQUENCY
- };
-
- private static final int INDEX_WORD = 1;
- private static final int INDEX_FREQUENCY = 2;
-
- private ContentObserver mObserver;
- private String mLocale;
-
- public UserDictionary(Context context, String locale) {
- super(context, Suggest.DIC_USER);
- mLocale = locale;
- // Perform a managed query. The Activity will handle closing and requerying the cursor
- // when needed.
- ContentResolver cres = context.getContentResolver();
-
- cres.registerContentObserver(Words.CONTENT_URI, true, mObserver = new ContentObserver(null) {
- @Override
- public void onChange(boolean self) {
- setRequiresReload(true);
- }
- });
-
- loadDictionary();
- }
-
- @Override
- public synchronized void close() {
- if (mObserver != null) {
- getContext().getContentResolver().unregisterContentObserver(mObserver);
- mObserver = null;
- }
- super.close();
- }
-
- @Override
- public void loadDictionaryAsync() {
- //Cursor cursor = getContext().getContentResolver()
- // .query(Words.CONTENT_URI, PROJECTION, "(locale IS NULL) or (locale=?)",
- // new String[] { mLocale }, null);
- //addWords(cursor);
- }
-
- /**
- * Adds a word to the dictionary and makes it persistent.
- * @param word the word to add. If the word is capitalized, then the dictionary will
- * recognize it as a capitalized word when searched.
- * @param frequency the frequency of occurrence of the word. A frequency of 255 is considered
- * the highest.
- * @TODO use a higher or float range for frequency
- */
- @Override
- public synchronized void addWord(String word, int frequency) {
- // Force load the dictionary here synchronously
- if (getRequiresReload()) loadDictionaryAsync();
- // Safeguard against adding long words. Can cause stack overflow.
- if (word.length() >= getMaxWordLength()) return;
-
- super.addWord(word, frequency);
-
- // Update the user dictionary provider
- final ContentValues values = new ContentValues(5);
- values.put(Words.WORD, word);
- values.put(Words.FREQUENCY, frequency);
- values.put(Words.LOCALE, mLocale);
- values.put(Words.APP_ID, 0);
-
- final ContentResolver contentResolver = getContext().getContentResolver();
- new Thread("addWord") {
- public void run() {
- contentResolver.insert(Words.CONTENT_URI, values);
- }
- }.start();
-
- // In case the above does a synchronous callback of the change observer
- setRequiresReload(false);
- }
-
- @Override
- public synchronized void getWords(final WordComposer codes, final WordCallback callback,
- int[] nextLettersFrequencies) {
- super.getWords(codes, callback, nextLettersFrequencies);
- }
-
- @Override
- public synchronized boolean isValidWord(CharSequence word) {
- return super.isValidWord(word);
- }
-
- private void addWords(Cursor cursor) {
- clearDictionary();
-
- final int maxWordLength = getMaxWordLength();
- if (cursor.moveToFirst()) {
- while (!cursor.isAfterLast()) {
- String word = cursor.getString(INDEX_WORD);
- int frequency = cursor.getInt(INDEX_FREQUENCY);
- // Safeguard against adding really long words. Stack may overflow due
- // to recursion
- if (word.length() < maxWordLength) {
- super.addWord(word, frequency);
- }
- cursor.moveToNext();
- }
- }
- cursor.close();
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/WordComposer.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/WordComposer.java
deleted file mode 100644
index 47cd4ece..00000000
--- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/WordComposer.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 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 "AS IS" 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.
- */
-
-package keepass2android.softkeyboard;
-
-import java.util.ArrayList;
-
-/**
- * A place to store the currently composing word with information such as adjacent key codes as well
- */
-public class WordComposer {
- /**
- * The list of unicode values for each keystroke (including surrounding keys)
- */
- private final ArrayList mCodes;
-
- /**
- * The word chosen from the candidate list, until it is committed.
- */
- private String mPreferredWord;
-
- private final StringBuilder mTypedWord;
-
- private int mCapsCount;
-
- private boolean mAutoCapitalized;
-
- /**
- * Whether the user chose to capitalize the first char of the word.
- */
- private boolean mIsFirstCharCapitalized;
-
- public WordComposer() {
- mCodes = new ArrayList(12);
- mTypedWord = new StringBuilder(20);
- }
-
- WordComposer(WordComposer copy) {
- mCodes = new ArrayList(copy.mCodes);
- mPreferredWord = copy.mPreferredWord;
- mTypedWord = new StringBuilder(copy.mTypedWord);
- mCapsCount = copy.mCapsCount;
- mAutoCapitalized = copy.mAutoCapitalized;
- mIsFirstCharCapitalized = copy.mIsFirstCharCapitalized;
- }
-
- /**
- * Clear out the keys registered so far.
- */
- public void reset() {
- mCodes.clear();
- mIsFirstCharCapitalized = false;
- mPreferredWord = null;
- mTypedWord.setLength(0);
- mCapsCount = 0;
- }
-
- /**
- * Number of keystrokes in the composing word.
- * @return the number of keystrokes
- */
- public int size() {
- return mCodes.size();
- }
-
- /**
- * Returns the codes at a particular position in the word.
- * @param index the position in the word
- * @return the unicode for the pressed and surrounding keys
- */
- public int[] getCodesAt(int index) {
- return mCodes.get(index);
- }
-
- /**
- * Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of
- * the array containing unicode for adjacent keys, sorted by reducing probability/proximity.
- * @param codes the array of unicode values
- */
- public void add(int primaryCode, int[] codes) {
- mTypedWord.append((char) primaryCode);
- correctPrimaryJuxtapos(primaryCode, codes);
- mCodes.add(codes);
- if (Character.isUpperCase((char) primaryCode)) mCapsCount++;
- }
-
- /**
- * Swaps the first and second values in the codes array if the primary code is not the first
- * value in the array but the second. This happens when the preferred key is not the key that
- * the user released the finger on.
- * @param primaryCode the preferred character
- * @param codes array of codes based on distance from touch point
- */
- private void correctPrimaryJuxtapos(int primaryCode, int[] codes) {
- if (codes.length < 2) return;
- if (codes[0] > 0 && codes[1] > 0 && codes[0] != primaryCode && codes[1] == primaryCode) {
- codes[1] = codes[0];
- codes[0] = primaryCode;
- }
- }
-
- /**
- * Delete the last keystroke as a result of hitting backspace.
- */
- public void deleteLast() {
- final int codesSize = mCodes.size();
- if (codesSize > 0) {
- mCodes.remove(codesSize - 1);
- final int lastPos = mTypedWord.length() - 1;
- char last = mTypedWord.charAt(lastPos);
- mTypedWord.deleteCharAt(lastPos);
- if (Character.isUpperCase(last)) mCapsCount--;
- }
- }
-
- /**
- * Returns the word as it was typed, without any correction applied.
- * @return the word that was typed so far
- */
- public CharSequence getTypedWord() {
- int wordSize = mCodes.size();
- if (wordSize == 0) {
- return null;
- }
- return mTypedWord;
- }
-
- public void setFirstCharCapitalized(boolean capitalized) {
- mIsFirstCharCapitalized = capitalized;
- }
-
- /**
- * Whether or not the user typed a capital letter as the first letter in the word
- * @return capitalization preference
- */
- public boolean isFirstCharCapitalized() {
- return mIsFirstCharCapitalized;
- }
-
- /**
- * Whether or not all of the user typed chars are upper case
- * @return true if all user typed chars are upper case, false otherwise
- */
- public boolean isAllUpperCase() {
- return (mCapsCount > 0) && (mCapsCount == size());
- }
-
- /**
- * Stores the user's selected word, before it is actually committed to the text field.
- * @param preferred
- */
- public void setPreferredWord(String preferred) {
- mPreferredWord = preferred;
- }
-
- /**
- * Return the word chosen by the user, or the typed word if no other word was chosen.
- * @return the preferred word
- */
- public CharSequence getPreferredWord() {
- return mPreferredWord != null ? mPreferredWord : getTypedWord();
- }
-
- /**
- * Returns true if more than one character is upper case, otherwise returns false.
- */
- public boolean isMostlyCaps() {
- return mCapsCount > 1;
- }
-
- /**
- * Saves the reason why the word is capitalized - whether it was automatic or
- * due to the user hitting shift in the middle of a sentence.
- * @param auto whether it was an automatic capitalization due to start of sentence
- */
- public void setAutoCapitalized(boolean auto) {
- mAutoCapitalized = auto;
- }
-
- /**
- * Returns whether the word was automatically capitalized.
- * @return whether the word was automatically capitalized
- */
- public boolean isAutoCapitalized() {
- return mAutoCapitalized;
- }
-}
diff --git a/src/java/KP2ASoftKeyboard2/native/howtobuild.txt b/src/java/KP2ASoftKeyboard2/native/howtobuild.txt
deleted file mode 100644
index 775dff24..00000000
--- a/src/java/KP2ASoftKeyboard2/native/howtobuild.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-in Cygwin-Console:
-cd /cygdrive/c/users/Philipp/Documents/keepass2android//repo/externalstuff/LatinIME-gingerbread/native
-/cygdrive/c/Users/Philipp/Downloads/android-ndk-r9c-windows-x86_64/android-ndk-r9c/ndk-build
-native/libs kopieren nach java/libs
\ No newline at end of file
diff --git a/src/java/KP2ASoftKeyboard2/native/jni/Android.mk b/src/java/KP2ASoftKeyboard2/native/jni/Android.mk
deleted file mode 100644
index 57ebee70..00000000
--- a/src/java/KP2ASoftKeyboard2/native/jni/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
-
-LOCAL_SRC_FILES := \
- keepass2android_softkeyboard_BinaryDictionary.cpp \
- dictionary.cpp \
- char_utils.cpp
-
-ifneq ($(TARGET_ARCH),x86)
-LOCAL_NDK_VERSION := 4
-LOCAL_SDK_VERSION := 8
-endif
-
-LOCAL_MODULE := libjni_latinime
-
-LOCAL_MODULE_TAGS := user
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/src/java/KP2ASoftKeyboard2/native/jni/Application.mk b/src/java/KP2ASoftKeyboard2/native/jni/Application.mk
deleted file mode 100644
index 7bc5d257..00000000
--- a/src/java/KP2ASoftKeyboard2/native/jni/Application.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-APP_MODULES := libjni_latinime
-APP_OPTIM := release
-APP_ABI := armeabi armeabi-v7a x86 mips
diff --git a/src/java/KP2ASoftKeyboard2/native/jni/basechars.h b/src/java/KP2ASoftKeyboard2/native/jni/basechars.h
deleted file mode 100644
index 5a440660..00000000
--- a/src/java/KP2ASoftKeyboard2/native/jni/basechars.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * Table mapping most combined Latin, Greek, and Cyrillic characters
- * to their base characters. If c is in range, BASE_CHARS[c] == c
- * if c is not a combined character, or the base character if it
- * is combined.
- */
-static unsigned short BASE_CHARS[] = {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
- 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
- 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x0020, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
- 0x0020, 0x00a9, 0x0061, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0020,
- 0x00b0, 0x00b1, 0x0032, 0x0033, 0x0020, 0x03bc, 0x00b6, 0x00b7,
- 0x0020, 0x0031, 0x006f, 0x00bb, 0x0031, 0x0031, 0x0033, 0x00bf,
- 0x0041, 0x0041, 0x0041, 0x0041, 0x0041, 0x0041, 0x00c6, 0x0043,
- 0x0045, 0x0045, 0x0045, 0x0045, 0x0049, 0x0049, 0x0049, 0x0049,
- 0x00d0, 0x004e, 0x004f, 0x004f, 0x004f, 0x004f, 0x004f, 0x00d7,
- 0x004f, 0x0055, 0x0055, 0x0055, 0x0055, 0x0059, 0x00de, 0x0073, // Manually changed d8 to 4f
- // Manually changed df to 73
- 0x0061, 0x0061, 0x0061, 0x0061, 0x0061, 0x0061, 0x00e6, 0x0063,
- 0x0065, 0x0065, 0x0065, 0x0065, 0x0069, 0x0069, 0x0069, 0x0069,
- 0x00f0, 0x006e, 0x006f, 0x006f, 0x006f, 0x006f, 0x006f, 0x00f7,
- 0x006f, 0x0075, 0x0075, 0x0075, 0x0075, 0x0079, 0x00fe, 0x0079, // Manually changed f8 to 6f
- 0x0041, 0x0061, 0x0041, 0x0061, 0x0041, 0x0061, 0x0043, 0x0063,
- 0x0043, 0x0063, 0x0043, 0x0063, 0x0043, 0x0063, 0x0044, 0x0064,
- 0x0110, 0x0111, 0x0045, 0x0065, 0x0045, 0x0065, 0x0045, 0x0065,
- 0x0045, 0x0065, 0x0045, 0x0065, 0x0047, 0x0067, 0x0047, 0x0067,
- 0x0047, 0x0067, 0x0047, 0x0067, 0x0048, 0x0068, 0x0126, 0x0127,
- 0x0049, 0x0069, 0x0049, 0x0069, 0x0049, 0x0069, 0x0049, 0x0069,
- 0x0049, 0x0131, 0x0049, 0x0069, 0x004a, 0x006a, 0x004b, 0x006b,
- 0x0138, 0x004c, 0x006c, 0x004c, 0x006c, 0x004c, 0x006c, 0x004c,
- 0x006c, 0x0141, 0x0142, 0x004e, 0x006e, 0x004e, 0x006e, 0x004e,
- 0x006e, 0x02bc, 0x014a, 0x014b, 0x004f, 0x006f, 0x004f, 0x006f,
- 0x004f, 0x006f, 0x0152, 0x0153, 0x0052, 0x0072, 0x0052, 0x0072,
- 0x0052, 0x0072, 0x0053, 0x0073, 0x0053, 0x0073, 0x0053, 0x0073,
- 0x0053, 0x0073, 0x0054, 0x0074, 0x0054, 0x0074, 0x0166, 0x0167,
- 0x0055, 0x0075, 0x0055, 0x0075, 0x0055, 0x0075, 0x0055, 0x0075,
- 0x0055, 0x0075, 0x0055, 0x0075, 0x0057, 0x0077, 0x0059, 0x0079,
- 0x0059, 0x005a, 0x007a, 0x005a, 0x007a, 0x005a, 0x007a, 0x0073,
- 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, 0x0187,
- 0x0188, 0x0189, 0x018a, 0x018b, 0x018c, 0x018d, 0x018e, 0x018f,
- 0x0190, 0x0191, 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, 0x0197,
- 0x0198, 0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e, 0x019f,
- 0x004f, 0x006f, 0x01a2, 0x01a3, 0x01a4, 0x01a5, 0x01a6, 0x01a7,
- 0x01a8, 0x01a9, 0x01aa, 0x01ab, 0x01ac, 0x01ad, 0x01ae, 0x0055,
- 0x0075, 0x01b1, 0x01b2, 0x01b3, 0x01b4, 0x01b5, 0x01b6, 0x01b7,
- 0x01b8, 0x01b9, 0x01ba, 0x01bb, 0x01bc, 0x01bd, 0x01be, 0x01bf,
- 0x01c0, 0x01c1, 0x01c2, 0x01c3, 0x0044, 0x0044, 0x0064, 0x004c,
- 0x004c, 0x006c, 0x004e, 0x004e, 0x006e, 0x0041, 0x0061, 0x0049,
- 0x0069, 0x004f, 0x006f, 0x0055, 0x0075, 0x00dc, 0x00fc, 0x00dc,
- 0x00fc, 0x00dc, 0x00fc, 0x00dc, 0x00fc, 0x01dd, 0x00c4, 0x00e4,
- 0x0226, 0x0227, 0x00c6, 0x00e6, 0x01e4, 0x01e5, 0x0047, 0x0067,
- 0x004b, 0x006b, 0x004f, 0x006f, 0x01ea, 0x01eb, 0x01b7, 0x0292,
- 0x006a, 0x0044, 0x0044, 0x0064, 0x0047, 0x0067, 0x01f6, 0x01f7,
- 0x004e, 0x006e, 0x00c5, 0x00e5, 0x00c6, 0x00e6, 0x00d8, 0x00f8,
- 0x0041, 0x0061, 0x0041, 0x0061, 0x0045, 0x0065, 0x0045, 0x0065,
- 0x0049, 0x0069, 0x0049, 0x0069, 0x004f, 0x006f, 0x004f, 0x006f,
- 0x0052, 0x0072, 0x0052, 0x0072, 0x0055, 0x0075, 0x0055, 0x0075,
- 0x0053, 0x0073, 0x0054, 0x0074, 0x021c, 0x021d, 0x0048, 0x0068,
- 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0041, 0x0061,
- 0x0045, 0x0065, 0x00d6, 0x00f6, 0x00d5, 0x00f5, 0x004f, 0x006f,
- 0x022e, 0x022f, 0x0059, 0x0079, 0x0234, 0x0235, 0x0236, 0x0237,
- 0x0238, 0x0239, 0x023a, 0x023b, 0x023c, 0x023d, 0x023e, 0x023f,
- 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247,
- 0x0248, 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f,
- 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257,
- 0x0258, 0x0259, 0x025a, 0x025b, 0x025c, 0x025d, 0x025e, 0x025f,
- 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267,
- 0x0268, 0x0269, 0x026a, 0x026b, 0x026c, 0x026d, 0x026e, 0x026f,
- 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277,
- 0x0278, 0x0279, 0x027a, 0x027b, 0x027c, 0x027d, 0x027e, 0x027f,
- 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287,
- 0x0288, 0x0289, 0x028a, 0x028b, 0x028c, 0x028d, 0x028e, 0x028f,
- 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297,
- 0x0298, 0x0299, 0x029a, 0x029b, 0x029c, 0x029d, 0x029e, 0x029f,
- 0x02a0, 0x02a1, 0x02a2, 0x02a3, 0x02a4, 0x02a5, 0x02a6, 0x02a7,
- 0x02a8, 0x02a9, 0x02aa, 0x02ab, 0x02ac, 0x02ad, 0x02ae, 0x02af,
- 0x0068, 0x0266, 0x006a, 0x0072, 0x0279, 0x027b, 0x0281, 0x0077,
- 0x0079, 0x02b9, 0x02ba, 0x02bb, 0x02bc, 0x02bd, 0x02be, 0x02bf,
- 0x02c0, 0x02c1, 0x02c2, 0x02c3, 0x02c4, 0x02c5, 0x02c6, 0x02c7,
- 0x02c8, 0x02c9, 0x02ca, 0x02cb, 0x02cc, 0x02cd, 0x02ce, 0x02cf,
- 0x02d0, 0x02d1, 0x02d2, 0x02d3, 0x02d4, 0x02d5, 0x02d6, 0x02d7,
- 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x02de, 0x02df,
- 0x0263, 0x006c, 0x0073, 0x0078, 0x0295, 0x02e5, 0x02e6, 0x02e7,
- 0x02e8, 0x02e9, 0x02ea, 0x02eb, 0x02ec, 0x02ed, 0x02ee, 0x02ef,
- 0x02f0, 0x02f1, 0x02f2, 0x02f3, 0x02f4, 0x02f5, 0x02f6, 0x02f7,
- 0x02f8, 0x02f9, 0x02fa, 0x02fb, 0x02fc, 0x02fd, 0x02fe, 0x02ff,
- 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307,
- 0x0308, 0x0309, 0x030a, 0x030b, 0x030c, 0x030d, 0x030e, 0x030f,
- 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
- 0x0318, 0x0319, 0x031a, 0x031b, 0x031c, 0x031d, 0x031e, 0x031f,
- 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327,
- 0x0328, 0x0329, 0x032a, 0x032b, 0x032c, 0x032d, 0x032e, 0x032f,
- 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337,
- 0x0338, 0x0339, 0x033a, 0x033b, 0x033c, 0x033d, 0x033e, 0x033f,
- 0x0300, 0x0301, 0x0342, 0x0313, 0x0308, 0x0345, 0x0346, 0x0347,
- 0x0348, 0x0349, 0x034a, 0x034b, 0x034c, 0x034d, 0x034e, 0x034f,
- 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357,
- 0x0358, 0x0359, 0x035a, 0x035b, 0x035c, 0x035d, 0x035e, 0x035f,
- 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
- 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f,
- 0x0370, 0x0371, 0x0372, 0x0373, 0x02b9, 0x0375, 0x0376, 0x0377,
- 0x0378, 0x0379, 0x0020, 0x037b, 0x037c, 0x037d, 0x003b, 0x037f,
- 0x0380, 0x0381, 0x0382, 0x0383, 0x0020, 0x00a8, 0x0391, 0x00b7,
- 0x0395, 0x0397, 0x0399, 0x038b, 0x039f, 0x038d, 0x03a5, 0x03a9,
- 0x03ca, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
- 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
- 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
- 0x03a8, 0x03a9, 0x0399, 0x03a5, 0x03b1, 0x03b5, 0x03b7, 0x03b9,
- 0x03cb, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
- 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
- 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
- 0x03c8, 0x03c9, 0x03b9, 0x03c5, 0x03bf, 0x03c5, 0x03c9, 0x03cf,
- 0x03b2, 0x03b8, 0x03a5, 0x03d2, 0x03d2, 0x03c6, 0x03c0, 0x03d7,
- 0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df,
- 0x03e0, 0x03e1, 0x03e2, 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x03e7,
- 0x03e8, 0x03e9, 0x03ea, 0x03eb, 0x03ec, 0x03ed, 0x03ee, 0x03ef,
- 0x03ba, 0x03c1, 0x03c2, 0x03f3, 0x0398, 0x03b5, 0x03f6, 0x03f7,
- 0x03f8, 0x03a3, 0x03fa, 0x03fb, 0x03fc, 0x03fd, 0x03fe, 0x03ff,
- 0x0415, 0x0415, 0x0402, 0x0413, 0x0404, 0x0405, 0x0406, 0x0406,
- 0x0408, 0x0409, 0x040a, 0x040b, 0x041a, 0x0418, 0x0423, 0x040f,
- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
- 0x0418, 0x0418, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
- 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
- 0x0438, 0x0438, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
- 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
- 0x0435, 0x0435, 0x0452, 0x0433, 0x0454, 0x0455, 0x0456, 0x0456,
- 0x0458, 0x0459, 0x045a, 0x045b, 0x043a, 0x0438, 0x0443, 0x045f,
- 0x0460, 0x0461, 0x0462, 0x0463, 0x0464, 0x0465, 0x0466, 0x0467,
- 0x0468, 0x0469, 0x046a, 0x046b, 0x046c, 0x046d, 0x046e, 0x046f,
- 0x0470, 0x0471, 0x0472, 0x0473, 0x0474, 0x0475, 0x0474, 0x0475,
- 0x0478, 0x0479, 0x047a, 0x047b, 0x047c, 0x047d, 0x047e, 0x047f,
- 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487,
- 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f,
- 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497,
- 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x049f,
- 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7,
- 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af,
- 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7,
- 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x04be, 0x04bf,
- 0x04c0, 0x0416, 0x0436, 0x04c3, 0x04c4, 0x04c5, 0x04c6, 0x04c7,
- 0x04c8, 0x04c9, 0x04ca, 0x04cb, 0x04cc, 0x04cd, 0x04ce, 0x04cf,
- 0x0410, 0x0430, 0x0410, 0x0430, 0x04d4, 0x04d5, 0x0415, 0x0435,
- 0x04d8, 0x04d9, 0x04d8, 0x04d9, 0x0416, 0x0436, 0x0417, 0x0437,
- 0x04e0, 0x04e1, 0x0418, 0x0438, 0x0418, 0x0438, 0x041e, 0x043e,
- 0x04e8, 0x04e9, 0x04e8, 0x04e9, 0x042d, 0x044d, 0x0423, 0x0443,
- 0x0423, 0x0443, 0x0423, 0x0443, 0x0427, 0x0447, 0x04f6, 0x04f7,
- 0x042b, 0x044b, 0x04fa, 0x04fb, 0x04fc, 0x04fd, 0x04fe, 0x04ff,
-};
-
-// generated with:
-// cat UnicodeData.txt | perl -e 'while (<>) { @foo = split(/;/); $foo[5] =~ s/<.*> //; $base[hex($foo[0])] = hex($foo[5]);} for ($i = 0; $i < 0x500; $i += 8) { for ($j = $i; $j < $i + 8; $j++) { printf("0x%04x, ", $base[$j] ? $base[$j] : $j)}; print "\n"; }'
diff --git a/src/java/KP2ASoftKeyboard2/native/jni/char_utils.cpp b/src/java/KP2ASoftKeyboard2/native/jni/char_utils.cpp
deleted file mode 100644
index a31a0632..00000000
--- a/src/java/KP2ASoftKeyboard2/native/jni/char_utils.cpp
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * 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 "AS IS" 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.
- */
-
-#include
-
-namespace latinime {
-
-struct LatinCapitalSmallPair {
- unsigned short capital;
- unsigned short small;
-};
-
-// Generated from http://unicode.org/Public/UNIDATA/UnicodeData.txt
-//
-// 1. Run the following code. Bascially taken from
-// Dictionary::toLowerCase(unsigned short c) in dictionary.cpp.
-// Then, get the list of chars where cc != ccc.
-//
-// unsigned short c, cc, ccc, ccc2;
-// for (c = 0; c < 0xFFFF ; c++) {
-// if (c < sizeof(BASE_CHARS) / sizeof(BASE_CHARS[0])) {
-// cc = BASE_CHARS[c];
-// } else {
-// cc = c;
-// }
-//
-// // tolower
-// int isBase = 0;
-// if (cc >='A' && cc <= 'Z') {
-// ccc = (cc | 0x20);
-// ccc2 = ccc;
-// isBase = 1;
-// } else if (cc > 0x7F) {
-// ccc = u_tolower(cc);
-// ccc2 = latin_tolower(cc);
-// } else {
-// ccc = cc;
-// ccc2 = ccc;
-// }
-// if (!isBase && cc != ccc) {
-// wprintf(L" 0x%04X => 0x%04X => 0x%04X %lc => %lc => %lc \n",
-// c, cc, ccc, c, cc, ccc);
-// //assert(ccc == ccc2);
-// }
-// }
-//
-// Initially, started with an empty latin_tolower() as below.
-//
-// unsigned short latin_tolower(unsigned short c) {
-// return c;
-// }
-//
-//
-// 2. Process the list obtained by 1 by the following perl script and apply
-// 'sort -u' as well. Get the SORTED_CHAR_MAP[].
-// Note that '$1' in the perl script is 'cc' in the above C code.
-//
-// while(<>) {
-// / 0x\w* => 0x(\w*) =/;
-// open(HDL, "grep -iw ^" . $1 . " UnicodeData.txt | ");
-// $line = ;
-// chomp $line;
-// @cols = split(/;/, $line);
-// print " { 0x$1, 0x$cols[13] }, // $cols[1]\n";
-// }
-//
-//
-// 3. Update the latin_tolower() function above with SORTED_CHAR_MAP. Enable
-// the assert(ccc == ccc2) above and confirm the function exits successfully.
-//
-static const struct LatinCapitalSmallPair SORTED_CHAR_MAP[] = {
- { 0x00C4, 0x00E4 }, // LATIN CAPITAL LETTER A WITH DIAERESIS
- { 0x00C5, 0x00E5 }, // LATIN CAPITAL LETTER A WITH RING ABOVE
- { 0x00C6, 0x00E6 }, // LATIN CAPITAL LETTER AE
- { 0x00D0, 0x00F0 }, // LATIN CAPITAL LETTER ETH
- { 0x00D5, 0x00F5 }, // LATIN CAPITAL LETTER O WITH TILDE
- { 0x00D6, 0x00F6 }, // LATIN CAPITAL LETTER O WITH DIAERESIS
- { 0x00D8, 0x00F8 }, // LATIN CAPITAL LETTER O WITH STROKE
- { 0x00DC, 0x00FC }, // LATIN CAPITAL LETTER U WITH DIAERESIS
- { 0x00DE, 0x00FE }, // LATIN CAPITAL LETTER THORN
- { 0x0110, 0x0111 }, // LATIN CAPITAL LETTER D WITH STROKE
- { 0x0126, 0x0127 }, // LATIN CAPITAL LETTER H WITH STROKE
- { 0x0141, 0x0142 }, // LATIN CAPITAL LETTER L WITH STROKE
- { 0x014A, 0x014B }, // LATIN CAPITAL LETTER ENG
- { 0x0152, 0x0153 }, // LATIN CAPITAL LIGATURE OE
- { 0x0166, 0x0167 }, // LATIN CAPITAL LETTER T WITH STROKE
- { 0x0181, 0x0253 }, // LATIN CAPITAL LETTER B WITH HOOK
- { 0x0182, 0x0183 }, // LATIN CAPITAL LETTER B WITH TOPBAR
- { 0x0184, 0x0185 }, // LATIN CAPITAL LETTER TONE SIX
- { 0x0186, 0x0254 }, // LATIN CAPITAL LETTER OPEN O
- { 0x0187, 0x0188 }, // LATIN CAPITAL LETTER C WITH HOOK
- { 0x0189, 0x0256 }, // LATIN CAPITAL LETTER AFRICAN D
- { 0x018A, 0x0257 }, // LATIN CAPITAL LETTER D WITH HOOK
- { 0x018B, 0x018C }, // LATIN CAPITAL LETTER D WITH TOPBAR
- { 0x018E, 0x01DD }, // LATIN CAPITAL LETTER REVERSED E
- { 0x018F, 0x0259 }, // LATIN CAPITAL LETTER SCHWA
- { 0x0190, 0x025B }, // LATIN CAPITAL LETTER OPEN E
- { 0x0191, 0x0192 }, // LATIN CAPITAL LETTER F WITH HOOK
- { 0x0193, 0x0260 }, // LATIN CAPITAL LETTER G WITH HOOK
- { 0x0194, 0x0263 }, // LATIN CAPITAL LETTER GAMMA
- { 0x0196, 0x0269 }, // LATIN CAPITAL LETTER IOTA
- { 0x0197, 0x0268 }, // LATIN CAPITAL LETTER I WITH STROKE
- { 0x0198, 0x0199 }, // LATIN CAPITAL LETTER K WITH HOOK
- { 0x019C, 0x026F }, // LATIN CAPITAL LETTER TURNED M
- { 0x019D, 0x0272 }, // LATIN CAPITAL LETTER N WITH LEFT HOOK
- { 0x019F, 0x0275 }, // LATIN CAPITAL LETTER O WITH MIDDLE TILDE
- { 0x01A2, 0x01A3 }, // LATIN CAPITAL LETTER OI
- { 0x01A4, 0x01A5 }, // LATIN CAPITAL LETTER P WITH HOOK
- { 0x01A6, 0x0280 }, // LATIN LETTER YR
- { 0x01A7, 0x01A8 }, // LATIN CAPITAL LETTER TONE TWO
- { 0x01A9, 0x0283 }, // LATIN CAPITAL LETTER ESH
- { 0x01AC, 0x01AD }, // LATIN CAPITAL LETTER T WITH HOOK
- { 0x01AE, 0x0288 }, // LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
- { 0x01B1, 0x028A }, // LATIN CAPITAL LETTER UPSILON
- { 0x01B2, 0x028B }, // LATIN CAPITAL LETTER V WITH HOOK
- { 0x01B3, 0x01B4 }, // LATIN CAPITAL LETTER Y WITH HOOK
- { 0x01B5, 0x01B6 }, // LATIN CAPITAL LETTER Z WITH STROKE
- { 0x01B7, 0x0292 }, // LATIN CAPITAL LETTER EZH
- { 0x01B8, 0x01B9 }, // LATIN CAPITAL LETTER EZH REVERSED
- { 0x01BC, 0x01BD }, // LATIN CAPITAL LETTER TONE FIVE
- { 0x01E4, 0x01E5 }, // LATIN CAPITAL LETTER G WITH STROKE
- { 0x01EA, 0x01EB }, // LATIN CAPITAL LETTER O WITH OGONEK
- { 0x01F6, 0x0195 }, // LATIN CAPITAL LETTER HWAIR
- { 0x01F7, 0x01BF }, // LATIN CAPITAL LETTER WYNN
- { 0x021C, 0x021D }, // LATIN CAPITAL LETTER YOGH
- { 0x0220, 0x019E }, // LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
- { 0x0222, 0x0223 }, // LATIN CAPITAL LETTER OU
- { 0x0224, 0x0225 }, // LATIN CAPITAL LETTER Z WITH HOOK
- { 0x0226, 0x0227 }, // LATIN CAPITAL LETTER A WITH DOT ABOVE
- { 0x022E, 0x022F }, // LATIN CAPITAL LETTER O WITH DOT ABOVE
- { 0x023A, 0x2C65 }, // LATIN CAPITAL LETTER A WITH STROKE
- { 0x023B, 0x023C }, // LATIN CAPITAL LETTER C WITH STROKE
- { 0x023D, 0x019A }, // LATIN CAPITAL LETTER L WITH BAR
- { 0x023E, 0x2C66 }, // LATIN CAPITAL LETTER T WITH DIAGONAL STROKE
- { 0x0241, 0x0242 }, // LATIN CAPITAL LETTER GLOTTAL STOP
- { 0x0243, 0x0180 }, // LATIN CAPITAL LETTER B WITH STROKE
- { 0x0244, 0x0289 }, // LATIN CAPITAL LETTER U BAR
- { 0x0245, 0x028C }, // LATIN CAPITAL LETTER TURNED V
- { 0x0246, 0x0247 }, // LATIN CAPITAL LETTER E WITH STROKE
- { 0x0248, 0x0249 }, // LATIN CAPITAL LETTER J WITH STROKE
- { 0x024A, 0x024B }, // LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL
- { 0x024C, 0x024D }, // LATIN CAPITAL LETTER R WITH STROKE
- { 0x024E, 0x024F }, // LATIN CAPITAL LETTER Y WITH STROKE
- { 0x0370, 0x0371 }, // GREEK CAPITAL LETTER HETA
- { 0x0372, 0x0373 }, // GREEK CAPITAL LETTER ARCHAIC SAMPI
- { 0x0376, 0x0377 }, // GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA
- { 0x0391, 0x03B1 }, // GREEK CAPITAL LETTER ALPHA
- { 0x0392, 0x03B2 }, // GREEK CAPITAL LETTER BETA
- { 0x0393, 0x03B3 }, // GREEK CAPITAL LETTER GAMMA
- { 0x0394, 0x03B4 }, // GREEK CAPITAL LETTER DELTA
- { 0x0395, 0x03B5 }, // GREEK CAPITAL LETTER EPSILON
- { 0x0396, 0x03B6 }, // GREEK CAPITAL LETTER ZETA
- { 0x0397, 0x03B7 }, // GREEK CAPITAL LETTER ETA
- { 0x0398, 0x03B8 }, // GREEK CAPITAL LETTER THETA
- { 0x0399, 0x03B9 }, // GREEK CAPITAL LETTER IOTA
- { 0x039A, 0x03BA }, // GREEK CAPITAL LETTER KAPPA
- { 0x039B, 0x03BB }, // GREEK CAPITAL LETTER LAMDA
- { 0x039C, 0x03BC }, // GREEK CAPITAL LETTER MU
- { 0x039D, 0x03BD }, // GREEK CAPITAL LETTER NU
- { 0x039E, 0x03BE }, // GREEK CAPITAL LETTER XI
- { 0x039F, 0x03BF }, // GREEK CAPITAL LETTER OMICRON
- { 0x03A0, 0x03C0 }, // GREEK CAPITAL LETTER PI
- { 0x03A1, 0x03C1 }, // GREEK CAPITAL LETTER RHO
- { 0x03A3, 0x03C3 }, // GREEK CAPITAL LETTER SIGMA
- { 0x03A4, 0x03C4 }, // GREEK CAPITAL LETTER TAU
- { 0x03A5, 0x03C5 }, // GREEK CAPITAL LETTER UPSILON
- { 0x03A6, 0x03C6 }, // GREEK CAPITAL LETTER PHI
- { 0x03A7, 0x03C7 }, // GREEK CAPITAL LETTER CHI
- { 0x03A8, 0x03C8 }, // GREEK CAPITAL LETTER PSI
- { 0x03A9, 0x03C9 }, // GREEK CAPITAL LETTER OMEGA
- { 0x03CF, 0x03D7 }, // GREEK CAPITAL KAI SYMBOL
- { 0x03D8, 0x03D9 }, // GREEK LETTER ARCHAIC KOPPA
- { 0x03DA, 0x03DB }, // GREEK LETTER STIGMA
- { 0x03DC, 0x03DD }, // GREEK LETTER DIGAMMA
- { 0x03DE, 0x03DF }, // GREEK LETTER KOPPA
- { 0x03E0, 0x03E1 }, // GREEK LETTER SAMPI
- { 0x03E2, 0x03E3 }, // COPTIC CAPITAL LETTER SHEI
- { 0x03E4, 0x03E5 }, // COPTIC CAPITAL LETTER FEI
- { 0x03E6, 0x03E7 }, // COPTIC CAPITAL LETTER KHEI
- { 0x03E8, 0x03E9 }, // COPTIC CAPITAL LETTER HORI
- { 0x03EA, 0x03EB }, // COPTIC CAPITAL LETTER GANGIA
- { 0x03EC, 0x03ED }, // COPTIC CAPITAL LETTER SHIMA
- { 0x03EE, 0x03EF }, // COPTIC CAPITAL LETTER DEI
- { 0x03F7, 0x03F8 }, // GREEK CAPITAL LETTER SHO
- { 0x03FA, 0x03FB }, // GREEK CAPITAL LETTER SAN
- { 0x03FD, 0x037B }, // GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL
- { 0x03FE, 0x037C }, // GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL
- { 0x03FF, 0x037D }, // GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
- { 0x0402, 0x0452 }, // CYRILLIC CAPITAL LETTER DJE
- { 0x0404, 0x0454 }, // CYRILLIC CAPITAL LETTER UKRAINIAN IE
- { 0x0405, 0x0455 }, // CYRILLIC CAPITAL LETTER DZE
- { 0x0406, 0x0456 }, // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
- { 0x0408, 0x0458 }, // CYRILLIC CAPITAL LETTER JE
- { 0x0409, 0x0459 }, // CYRILLIC CAPITAL LETTER LJE
- { 0x040A, 0x045A }, // CYRILLIC CAPITAL LETTER NJE
- { 0x040B, 0x045B }, // CYRILLIC CAPITAL LETTER TSHE
- { 0x040F, 0x045F }, // CYRILLIC CAPITAL LETTER DZHE
- { 0x0410, 0x0430 }, // CYRILLIC CAPITAL LETTER A
- { 0x0411, 0x0431 }, // CYRILLIC CAPITAL LETTER BE
- { 0x0412, 0x0432 }, // CYRILLIC CAPITAL LETTER VE
- { 0x0413, 0x0433 }, // CYRILLIC CAPITAL LETTER GHE
- { 0x0414, 0x0434 }, // CYRILLIC CAPITAL LETTER DE
- { 0x0415, 0x0435 }, // CYRILLIC CAPITAL LETTER IE
- { 0x0416, 0x0436 }, // CYRILLIC CAPITAL LETTER ZHE
- { 0x0417, 0x0437 }, // CYRILLIC CAPITAL LETTER ZE
- { 0x0418, 0x0438 }, // CYRILLIC CAPITAL LETTER I
- { 0x041A, 0x043A }, // CYRILLIC CAPITAL LETTER KA
- { 0x041B, 0x043B }, // CYRILLIC CAPITAL LETTER EL
- { 0x041C, 0x043C }, // CYRILLIC CAPITAL LETTER EM
- { 0x041D, 0x043D }, // CYRILLIC CAPITAL LETTER EN
- { 0x041E, 0x043E }, // CYRILLIC CAPITAL LETTER O
- { 0x041F, 0x043F }, // CYRILLIC CAPITAL LETTER PE
- { 0x0420, 0x0440 }, // CYRILLIC CAPITAL LETTER ER
- { 0x0421, 0x0441 }, // CYRILLIC CAPITAL LETTER ES
- { 0x0422, 0x0442 }, // CYRILLIC CAPITAL LETTER TE
- { 0x0423, 0x0443 }, // CYRILLIC CAPITAL LETTER U
- { 0x0424, 0x0444 }, // CYRILLIC CAPITAL LETTER EF
- { 0x0425, 0x0445 }, // CYRILLIC CAPITAL LETTER HA
- { 0x0426, 0x0446 }, // CYRILLIC CAPITAL LETTER TSE
- { 0x0427, 0x0447 }, // CYRILLIC CAPITAL LETTER CHE
- { 0x0428, 0x0448 }, // CYRILLIC CAPITAL LETTER SHA
- { 0x0429, 0x0449 }, // CYRILLIC CAPITAL LETTER SHCHA
- { 0x042A, 0x044A }, // CYRILLIC CAPITAL LETTER HARD SIGN
- { 0x042B, 0x044B }, // CYRILLIC CAPITAL LETTER YERU
- { 0x042C, 0x044C }, // CYRILLIC CAPITAL LETTER SOFT SIGN
- { 0x042D, 0x044D }, // CYRILLIC CAPITAL LETTER E
- { 0x042E, 0x044E }, // CYRILLIC CAPITAL LETTER YU
- { 0x042F, 0x044F }, // CYRILLIC CAPITAL LETTER YA
- { 0x0460, 0x0461 }, // CYRILLIC CAPITAL LETTER OMEGA
- { 0x0462, 0x0463 }, // CYRILLIC CAPITAL LETTER YAT
- { 0x0464, 0x0465 }, // CYRILLIC CAPITAL LETTER IOTIFIED E
- { 0x0466, 0x0467 }, // CYRILLIC CAPITAL LETTER LITTLE YUS
- { 0x0468, 0x0469 }, // CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
- { 0x046A, 0x046B }, // CYRILLIC CAPITAL LETTER BIG YUS
- { 0x046C, 0x046D }, // CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
- { 0x046E, 0x046F }, // CYRILLIC CAPITAL LETTER KSI
- { 0x0470, 0x0471 }, // CYRILLIC CAPITAL LETTER PSI
- { 0x0472, 0x0473 }, // CYRILLIC CAPITAL LETTER FITA
- { 0x0474, 0x0475 }, // CYRILLIC CAPITAL LETTER IZHITSA
- { 0x0478, 0x0479 }, // CYRILLIC CAPITAL LETTER UK
- { 0x047A, 0x047B }, // CYRILLIC CAPITAL LETTER ROUND OMEGA
- { 0x047C, 0x047D }, // CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
- { 0x047E, 0x047F }, // CYRILLIC CAPITAL LETTER OT
- { 0x0480, 0x0481 }, // CYRILLIC CAPITAL LETTER KOPPA
- { 0x048A, 0x048B }, // CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
- { 0x048C, 0x048D }, // CYRILLIC CAPITAL LETTER SEMISOFT SIGN
- { 0x048E, 0x048F }, // CYRILLIC CAPITAL LETTER ER WITH TICK
- { 0x0490, 0x0491 }, // CYRILLIC CAPITAL LETTER GHE WITH UPTURN
- { 0x0492, 0x0493 }, // CYRILLIC CAPITAL LETTER GHE WITH STROKE
- { 0x0494, 0x0495 }, // CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
- { 0x0496, 0x0497 }, // CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
- { 0x0498, 0x0499 }, // CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
- { 0x049A, 0x049B }, // CYRILLIC CAPITAL LETTER KA WITH DESCENDER
- { 0x049C, 0x049D }, // CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
- { 0x049E, 0x049F }, // CYRILLIC CAPITAL LETTER KA WITH STROKE
- { 0x04A0, 0x04A1 }, // CYRILLIC CAPITAL LETTER BASHKIR KA
- { 0x04A2, 0x04A3 }, // CYRILLIC CAPITAL LETTER EN WITH DESCENDER
- { 0x04A4, 0x04A5 }, // CYRILLIC CAPITAL LIGATURE EN GHE
- { 0x04A6, 0x04A7 }, // CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
- { 0x04A8, 0x04A9 }, // CYRILLIC CAPITAL LETTER ABKHASIAN HA
- { 0x04AA, 0x04AB }, // CYRILLIC CAPITAL LETTER ES WITH DESCENDER
- { 0x04AC, 0x04AD }, // CYRILLIC CAPITAL LETTER TE WITH DESCENDER
- { 0x04AE, 0x04AF }, // CYRILLIC CAPITAL LETTER STRAIGHT U
- { 0x04B0, 0x04B1 }, // CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
- { 0x04B2, 0x04B3 }, // CYRILLIC CAPITAL LETTER HA WITH DESCENDER
- { 0x04B4, 0x04B5 }, // CYRILLIC CAPITAL LIGATURE TE TSE
- { 0x04B6, 0x04B7 }, // CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
- { 0x04B8, 0x04B9 }, // CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
- { 0x04BA, 0x04BB }, // CYRILLIC CAPITAL LETTER SHHA
- { 0x04BC, 0x04BD }, // CYRILLIC CAPITAL LETTER ABKHASIAN CHE
- { 0x04BE, 0x04BF }, // CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
- { 0x04C0, 0x04CF }, // CYRILLIC LETTER PALOCHKA
- { 0x04C3, 0x04C4 }, // CYRILLIC CAPITAL LETTER KA WITH HOOK
- { 0x04C5, 0x04C6 }, // CYRILLIC CAPITAL LETTER EL WITH TAIL
- { 0x04C7, 0x04C8 }, // CYRILLIC CAPITAL LETTER EN WITH HOOK
- { 0x04C9, 0x04CA }, // CYRILLIC CAPITAL LETTER EN WITH TAIL
- { 0x04CB, 0x04CC }, // CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
- { 0x04CD, 0x04CE }, // CYRILLIC CAPITAL LETTER EM WITH TAIL
- { 0x04D4, 0x04D5 }, // CYRILLIC CAPITAL LIGATURE A IE
- { 0x04D8, 0x04D9 }, // CYRILLIC CAPITAL LETTER SCHWA
- { 0x04E0, 0x04E1 }, // CYRILLIC CAPITAL LETTER ABKHASIAN DZE
- { 0x04E8, 0x04E9 }, // CYRILLIC CAPITAL LETTER BARRED O
- { 0x04F6, 0x04F7 }, // CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
- { 0x04FA, 0x04FB }, // CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK
- { 0x04FC, 0x04FD }, // CYRILLIC CAPITAL LETTER HA WITH HOOK
- { 0x04FE, 0x04FF }, // CYRILLIC CAPITAL LETTER HA WITH STROKE
- { 0x0500, 0x0501 }, // CYRILLIC CAPITAL LETTER KOMI DE
- { 0x0502, 0x0503 }, // CYRILLIC CAPITAL LETTER KOMI DJE
- { 0x0504, 0x0505 }, // CYRILLIC CAPITAL LETTER KOMI ZJE
- { 0x0506, 0x0507 }, // CYRILLIC CAPITAL LETTER KOMI DZJE
- { 0x0508, 0x0509 }, // CYRILLIC CAPITAL LETTER KOMI LJE
- { 0x050A, 0x050B }, // CYRILLIC CAPITAL LETTER KOMI NJE
- { 0x050C, 0x050D }, // CYRILLIC CAPITAL LETTER KOMI SJE
- { 0x050E, 0x050F }, // CYRILLIC CAPITAL LETTER KOMI TJE
- { 0x0510, 0x0511 }, // CYRILLIC CAPITAL LETTER REVERSED ZE
- { 0x0512, 0x0513 }, // CYRILLIC CAPITAL LETTER EL WITH HOOK
- { 0x0514, 0x0515 }, // CYRILLIC CAPITAL LETTER LHA
- { 0x0516, 0x0517 }, // CYRILLIC CAPITAL LETTER RHA
- { 0x0518, 0x0519 }, // CYRILLIC CAPITAL LETTER YAE
- { 0x051A, 0x051B }, // CYRILLIC CAPITAL LETTER QA
- { 0x051C, 0x051D }, // CYRILLIC CAPITAL LETTER WE
- { 0x051E, 0x051F }, // CYRILLIC CAPITAL LETTER ALEUT KA
- { 0x0520, 0x0521 }, // CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK
- { 0x0522, 0x0523 }, // CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK
- { 0x0524, 0x0525 }, // CYRILLIC CAPITAL LETTER PE WITH DESCENDER
- { 0x0531, 0x0561 }, // ARMENIAN CAPITAL LETTER AYB
- { 0x0532, 0x0562 }, // ARMENIAN CAPITAL LETTER BEN
- { 0x0533, 0x0563 }, // ARMENIAN CAPITAL LETTER GIM
- { 0x0534, 0x0564 }, // ARMENIAN CAPITAL LETTER DA
- { 0x0535, 0x0565 }, // ARMENIAN CAPITAL LETTER ECH
- { 0x0536, 0x0566 }, // ARMENIAN CAPITAL LETTER ZA
- { 0x0537, 0x0567 }, // ARMENIAN CAPITAL LETTER EH
- { 0x0538, 0x0568 }, // ARMENIAN CAPITAL LETTER ET
- { 0x0539, 0x0569 }, // ARMENIAN CAPITAL LETTER TO
- { 0x053A, 0x056A }, // ARMENIAN CAPITAL LETTER ZHE
- { 0x053B, 0x056B }, // ARMENIAN CAPITAL LETTER INI
- { 0x053C, 0x056C }, // ARMENIAN CAPITAL LETTER LIWN
- { 0x053D, 0x056D }, // ARMENIAN CAPITAL LETTER XEH
- { 0x053E, 0x056E }, // ARMENIAN CAPITAL LETTER CA
- { 0x053F, 0x056F }, // ARMENIAN CAPITAL LETTER KEN
- { 0x0540, 0x0570 }, // ARMENIAN CAPITAL LETTER HO
- { 0x0541, 0x0571 }, // ARMENIAN CAPITAL LETTER JA
- { 0x0542, 0x0572 }, // ARMENIAN CAPITAL LETTER GHAD
- { 0x0543, 0x0573 }, // ARMENIAN CAPITAL LETTER CHEH
- { 0x0544, 0x0574 }, // ARMENIAN CAPITAL LETTER MEN
- { 0x0545, 0x0575 }, // ARMENIAN CAPITAL LETTER YI
- { 0x0546, 0x0576 }, // ARMENIAN CAPITAL LETTER NOW
- { 0x0547, 0x0577 }, // ARMENIAN CAPITAL LETTER SHA
- { 0x0548, 0x0578 }, // ARMENIAN CAPITAL LETTER VO
- { 0x0549, 0x0579 }, // ARMENIAN CAPITAL LETTER CHA
- { 0x054A, 0x057A }, // ARMENIAN CAPITAL LETTER PEH
- { 0x054B, 0x057B }, // ARMENIAN CAPITAL LETTER JHEH
- { 0x054C, 0x057C }, // ARMENIAN CAPITAL LETTER RA
- { 0x054D, 0x057D }, // ARMENIAN CAPITAL LETTER SEH
- { 0x054E, 0x057E }, // ARMENIAN CAPITAL LETTER VEW
- { 0x054F, 0x057F }, // ARMENIAN CAPITAL LETTER TIWN
- { 0x0550, 0x0580 }, // ARMENIAN CAPITAL LETTER REH
- { 0x0551, 0x0581 }, // ARMENIAN CAPITAL LETTER CO
- { 0x0552, 0x0582 }, // ARMENIAN CAPITAL LETTER YIWN
- { 0x0553, 0x0583 }, // ARMENIAN CAPITAL LETTER PIWR
- { 0x0554, 0x0584 }, // ARMENIAN CAPITAL LETTER KEH
- { 0x0555, 0x0585 }, // ARMENIAN CAPITAL LETTER OH
- { 0x0556, 0x0586 }, // ARMENIAN CAPITAL LETTER FEH
- { 0x10A0, 0x2D00 }, // GEORGIAN CAPITAL LETTER AN
- { 0x10A1, 0x2D01 }, // GEORGIAN CAPITAL LETTER BAN
- { 0x10A2, 0x2D02 }, // GEORGIAN CAPITAL LETTER GAN
- { 0x10A3, 0x2D03 }, // GEORGIAN CAPITAL LETTER DON
- { 0x10A4, 0x2D04 }, // GEORGIAN CAPITAL LETTER EN
- { 0x10A5, 0x2D05 }, // GEORGIAN CAPITAL LETTER VIN
- { 0x10A6, 0x2D06 }, // GEORGIAN CAPITAL LETTER ZEN
- { 0x10A7, 0x2D07 }, // GEORGIAN CAPITAL LETTER TAN
- { 0x10A8, 0x2D08 }, // GEORGIAN CAPITAL LETTER IN
- { 0x10A9, 0x2D09 }, // GEORGIAN CAPITAL LETTER KAN
- { 0x10AA, 0x2D0A }, // GEORGIAN CAPITAL LETTER LAS
- { 0x10AB, 0x2D0B }, // GEORGIAN CAPITAL LETTER MAN
- { 0x10AC, 0x2D0C }, // GEORGIAN CAPITAL LETTER NAR
- { 0x10AD, 0x2D0D }, // GEORGIAN CAPITAL LETTER ON
- { 0x10AE, 0x2D0E }, // GEORGIAN CAPITAL LETTER PAR
- { 0x10AF, 0x2D0F }, // GEORGIAN CAPITAL LETTER ZHAR
- { 0x10B0, 0x2D10 }, // GEORGIAN CAPITAL LETTER RAE
- { 0x10B1, 0x2D11 }, // GEORGIAN CAPITAL LETTER SAN
- { 0x10B2, 0x2D12 }, // GEORGIAN CAPITAL LETTER TAR
- { 0x10B3, 0x2D13 }, // GEORGIAN CAPITAL LETTER UN
- { 0x10B4, 0x2D14 }, // GEORGIAN CAPITAL LETTER PHAR
- { 0x10B5, 0x2D15 }, // GEORGIAN CAPITAL LETTER KHAR
- { 0x10B6, 0x2D16 }, // GEORGIAN CAPITAL LETTER GHAN
- { 0x10B7, 0x2D17 }, // GEORGIAN CAPITAL LETTER QAR
- { 0x10B8, 0x2D18 }, // GEORGIAN CAPITAL LETTER SHIN
- { 0x10B9, 0x2D19 }, // GEORGIAN CAPITAL LETTER CHIN
- { 0x10BA, 0x2D1A }, // GEORGIAN CAPITAL LETTER CAN
- { 0x10BB, 0x2D1B }, // GEORGIAN CAPITAL LETTER JIL
- { 0x10BC, 0x2D1C }, // GEORGIAN CAPITAL LETTER CIL
- { 0x10BD, 0x2D1D }, // GEORGIAN CAPITAL LETTER CHAR
- { 0x10BE, 0x2D1E }, // GEORGIAN CAPITAL LETTER XAN
- { 0x10BF, 0x2D1F }, // GEORGIAN CAPITAL LETTER JHAN
- { 0x10C0, 0x2D20 }, // GEORGIAN CAPITAL LETTER HAE
- { 0x10C1, 0x2D21 }, // GEORGIAN CAPITAL LETTER HE
- { 0x10C2, 0x2D22 }, // GEORGIAN CAPITAL LETTER HIE
- { 0x10C3, 0x2D23 }, // GEORGIAN CAPITAL LETTER WE
- { 0x10C4, 0x2D24 }, // GEORGIAN CAPITAL LETTER HAR
- { 0x10C5, 0x2D25 }, // GEORGIAN CAPITAL LETTER HOE
- { 0x1E00, 0x1E01 }, // LATIN CAPITAL LETTER A WITH RING BELOW
- { 0x1E02, 0x1E03 }, // LATIN CAPITAL LETTER B WITH DOT ABOVE
- { 0x1E04, 0x1E05 }, // LATIN CAPITAL LETTER B WITH DOT BELOW
- { 0x1E06, 0x1E07 }, // LATIN CAPITAL LETTER B WITH LINE BELOW
- { 0x1E08, 0x1E09 }, // LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
- { 0x1E0A, 0x1E0B }, // LATIN CAPITAL LETTER D WITH DOT ABOVE
- { 0x1E0C, 0x1E0D }, // LATIN CAPITAL LETTER D WITH DOT BELOW
- { 0x1E0E, 0x1E0F }, // LATIN CAPITAL LETTER D WITH LINE BELOW
- { 0x1E10, 0x1E11 }, // LATIN CAPITAL LETTER D WITH CEDILLA
- { 0x1E12, 0x1E13 }, // LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
- { 0x1E14, 0x1E15 }, // LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
- { 0x1E16, 0x1E17 }, // LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
- { 0x1E18, 0x1E19 }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
- { 0x1E1A, 0x1E1B }, // LATIN CAPITAL LETTER E WITH TILDE BELOW
- { 0x1E1C, 0x1E1D }, // LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
- { 0x1E1E, 0x1E1F }, // LATIN CAPITAL LETTER F WITH DOT ABOVE
- { 0x1E20, 0x1E21 }, // LATIN CAPITAL LETTER G WITH MACRON
- { 0x1E22, 0x1E23 }, // LATIN CAPITAL LETTER H WITH DOT ABOVE
- { 0x1E24, 0x1E25 }, // LATIN CAPITAL LETTER H WITH DOT BELOW
- { 0x1E26, 0x1E27 }, // LATIN CAPITAL LETTER H WITH DIAERESIS
- { 0x1E28, 0x1E29 }, // LATIN CAPITAL LETTER H WITH CEDILLA
- { 0x1E2A, 0x1E2B }, // LATIN CAPITAL LETTER H WITH BREVE BELOW
- { 0x1E2C, 0x1E2D }, // LATIN CAPITAL LETTER I WITH TILDE BELOW
- { 0x1E2E, 0x1E2F }, // LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
- { 0x1E30, 0x1E31 }, // LATIN CAPITAL LETTER K WITH ACUTE
- { 0x1E32, 0x1E33 }, // LATIN CAPITAL LETTER K WITH DOT BELOW
- { 0x1E34, 0x1E35 }, // LATIN CAPITAL LETTER K WITH LINE BELOW
- { 0x1E36, 0x1E37 }, // LATIN CAPITAL LETTER L WITH DOT BELOW
- { 0x1E38, 0x1E39 }, // LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
- { 0x1E3A, 0x1E3B }, // LATIN CAPITAL LETTER L WITH LINE BELOW
- { 0x1E3C, 0x1E3D }, // LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
- { 0x1E3E, 0x1E3F }, // LATIN CAPITAL LETTER M WITH ACUTE
- { 0x1E40, 0x1E41 }, // LATIN CAPITAL LETTER M WITH DOT ABOVE
- { 0x1E42, 0x1E43 }, // LATIN CAPITAL LETTER M WITH DOT BELOW
- { 0x1E44, 0x1E45 }, // LATIN CAPITAL LETTER N WITH DOT ABOVE
- { 0x1E46, 0x1E47 }, // LATIN CAPITAL LETTER N WITH DOT BELOW
- { 0x1E48, 0x1E49 }, // LATIN CAPITAL LETTER N WITH LINE BELOW
- { 0x1E4A, 0x1E4B }, // LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
- { 0x1E4C, 0x1E4D }, // LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
- { 0x1E4E, 0x1E4F }, // LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
- { 0x1E50, 0x1E51 }, // LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
- { 0x1E52, 0x1E53 }, // LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
- { 0x1E54, 0x1E55 }, // LATIN CAPITAL LETTER P WITH ACUTE
- { 0x1E56, 0x1E57 }, // LATIN CAPITAL LETTER P WITH DOT ABOVE
- { 0x1E58, 0x1E59 }, // LATIN CAPITAL LETTER R WITH DOT ABOVE
- { 0x1E5A, 0x1E5B }, // LATIN CAPITAL LETTER R WITH DOT BELOW
- { 0x1E5C, 0x1E5D }, // LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
- { 0x1E5E, 0x1E5F }, // LATIN CAPITAL LETTER R WITH LINE BELOW
- { 0x1E60, 0x1E61 }, // LATIN CAPITAL LETTER S WITH DOT ABOVE
- { 0x1E62, 0x1E63 }, // LATIN CAPITAL LETTER S WITH DOT BELOW
- { 0x1E64, 0x1E65 }, // LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
- { 0x1E66, 0x1E67 }, // LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
- { 0x1E68, 0x1E69 }, // LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
- { 0x1E6A, 0x1E6B }, // LATIN CAPITAL LETTER T WITH DOT ABOVE
- { 0x1E6C, 0x1E6D }, // LATIN CAPITAL LETTER T WITH DOT BELOW
- { 0x1E6E, 0x1E6F }, // LATIN CAPITAL LETTER T WITH LINE BELOW
- { 0x1E70, 0x1E71 }, // LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
- { 0x1E72, 0x1E73 }, // LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
- { 0x1E74, 0x1E75 }, // LATIN CAPITAL LETTER U WITH TILDE BELOW
- { 0x1E76, 0x1E77 }, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
- { 0x1E78, 0x1E79 }, // LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
- { 0x1E7A, 0x1E7B }, // LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
- { 0x1E7C, 0x1E7D }, // LATIN CAPITAL LETTER V WITH TILDE
- { 0x1E7E, 0x1E7F }, // LATIN CAPITAL LETTER V WITH DOT BELOW
- { 0x1E80, 0x1E81 }, // LATIN CAPITAL LETTER W WITH GRAVE
- { 0x1E82, 0x1E83 }, // LATIN CAPITAL LETTER W WITH ACUTE
- { 0x1E84, 0x1E85 }, // LATIN CAPITAL LETTER W WITH DIAERESIS
- { 0x1E86, 0x1E87 }, // LATIN CAPITAL LETTER W WITH DOT ABOVE
- { 0x1E88, 0x1E89 }, // LATIN CAPITAL LETTER W WITH DOT BELOW
- { 0x1E8A, 0x1E8B }, // LATIN CAPITAL LETTER X WITH DOT ABOVE
- { 0x1E8C, 0x1E8D }, // LATIN CAPITAL LETTER X WITH DIAERESIS
- { 0x1E8E, 0x1E8F }, // LATIN CAPITAL LETTER Y WITH DOT ABOVE
- { 0x1E90, 0x1E91 }, // LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
- { 0x1E92, 0x1E93 }, // LATIN CAPITAL LETTER Z WITH DOT BELOW
- { 0x1E94, 0x1E95 }, // LATIN CAPITAL LETTER Z WITH LINE BELOW
- { 0x1E9E, 0x00DF }, // LATIN CAPITAL LETTER SHARP S
- { 0x1EA0, 0x1EA1 }, // LATIN CAPITAL LETTER A WITH DOT BELOW
- { 0x1EA2, 0x1EA3 }, // LATIN CAPITAL LETTER A WITH HOOK ABOVE
- { 0x1EA4, 0x1EA5 }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
- { 0x1EA6, 0x1EA7 }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
- { 0x1EA8, 0x1EA9 }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
- { 0x1EAA, 0x1EAB }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
- { 0x1EAC, 0x1EAD }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
- { 0x1EAE, 0x1EAF }, // LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
- { 0x1EB0, 0x1EB1 }, // LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
- { 0x1EB2, 0x1EB3 }, // LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
- { 0x1EB4, 0x1EB5 }, // LATIN CAPITAL LETTER A WITH BREVE AND TILDE
- { 0x1EB6, 0x1EB7 }, // LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
- { 0x1EB8, 0x1EB9 }, // LATIN CAPITAL LETTER E WITH DOT BELOW
- { 0x1EBA, 0x1EBB }, // LATIN CAPITAL LETTER E WITH HOOK ABOVE
- { 0x1EBC, 0x1EBD }, // LATIN CAPITAL LETTER E WITH TILDE
- { 0x1EBE, 0x1EBF }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
- { 0x1EC0, 0x1EC1 }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
- { 0x1EC2, 0x1EC3 }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
- { 0x1EC4, 0x1EC5 }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
- { 0x1EC6, 0x1EC7 }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
- { 0x1EC8, 0x1EC9 }, // LATIN CAPITAL LETTER I WITH HOOK ABOVE
- { 0x1ECA, 0x1ECB }, // LATIN CAPITAL LETTER I WITH DOT BELOW
- { 0x1ECC, 0x1ECD }, // LATIN CAPITAL LETTER O WITH DOT BELOW
- { 0x1ECE, 0x1ECF }, // LATIN CAPITAL LETTER O WITH HOOK ABOVE
- { 0x1ED0, 0x1ED1 }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
- { 0x1ED2, 0x1ED3 }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
- { 0x1ED4, 0x1ED5 }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
- { 0x1ED6, 0x1ED7 }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
- { 0x1ED8, 0x1ED9 }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
- { 0x1EDA, 0x1EDB }, // LATIN CAPITAL LETTER O WITH HORN AND ACUTE
- { 0x1EDC, 0x1EDD }, // LATIN CAPITAL LETTER O WITH HORN AND GRAVE
- { 0x1EDE, 0x1EDF }, // LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
- { 0x1EE0, 0x1EE1 }, // LATIN CAPITAL LETTER O WITH HORN AND TILDE
- { 0x1EE2, 0x1EE3 }, // LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
- { 0x1EE4, 0x1EE5 }, // LATIN CAPITAL LETTER U WITH DOT BELOW
- { 0x1EE6, 0x1EE7 }, // LATIN CAPITAL LETTER U WITH HOOK ABOVE
- { 0x1EE8, 0x1EE9 }, // LATIN CAPITAL LETTER U WITH HORN AND ACUTE
- { 0x1EEA, 0x1EEB }, // LATIN CAPITAL LETTER U WITH HORN AND GRAVE
- { 0x1EEC, 0x1EED }, // LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
- { 0x1EEE, 0x1EEF }, // LATIN CAPITAL LETTER U WITH HORN AND TILDE
- { 0x1EF0, 0x1EF1 }, // LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
- { 0x1EF2, 0x1EF3 }, // LATIN CAPITAL LETTER Y WITH GRAVE
- { 0x1EF4, 0x1EF5 }, // LATIN CAPITAL LETTER Y WITH DOT BELOW
- { 0x1EF6, 0x1EF7 }, // LATIN CAPITAL LETTER Y WITH HOOK ABOVE
- { 0x1EF8, 0x1EF9 }, // LATIN CAPITAL LETTER Y WITH TILDE
- { 0x1EFA, 0x1EFB }, // LATIN CAPITAL LETTER MIDDLE-WELSH LL
- { 0x1EFC, 0x1EFD }, // LATIN CAPITAL LETTER MIDDLE-WELSH V
- { 0x1EFE, 0x1EFF }, // LATIN CAPITAL LETTER Y WITH LOOP
- { 0x1F08, 0x1F00 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI
- { 0x1F09, 0x1F01 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA
- { 0x1F0A, 0x1F02 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
- { 0x1F0B, 0x1F03 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
- { 0x1F0C, 0x1F04 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
- { 0x1F0D, 0x1F05 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
- { 0x1F0E, 0x1F06 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
- { 0x1F0F, 0x1F07 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
- { 0x1F18, 0x1F10 }, // GREEK CAPITAL LETTER EPSILON WITH PSILI
- { 0x1F19, 0x1F11 }, // GREEK CAPITAL LETTER EPSILON WITH DASIA
- { 0x1F1A, 0x1F12 }, // GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
- { 0x1F1B, 0x1F13 }, // GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
- { 0x1F1C, 0x1F14 }, // GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
- { 0x1F1D, 0x1F15 }, // GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
- { 0x1F28, 0x1F20 }, // GREEK CAPITAL LETTER ETA WITH PSILI
- { 0x1F29, 0x1F21 }, // GREEK CAPITAL LETTER ETA WITH DASIA
- { 0x1F2A, 0x1F22 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
- { 0x1F2B, 0x1F23 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
- { 0x1F2C, 0x1F24 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
- { 0x1F2D, 0x1F25 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
- { 0x1F2E, 0x1F26 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
- { 0x1F2F, 0x1F27 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
- { 0x1F38, 0x1F30 }, // GREEK CAPITAL LETTER IOTA WITH PSILI
- { 0x1F39, 0x1F31 }, // GREEK CAPITAL LETTER IOTA WITH DASIA
- { 0x1F3A, 0x1F32 }, // GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
- { 0x1F3B, 0x1F33 }, // GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
- { 0x1F3C, 0x1F34 }, // GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
- { 0x1F3D, 0x1F35 }, // GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
- { 0x1F3E, 0x1F36 }, // GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
- { 0x1F3F, 0x1F37 }, // GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
- { 0x1F48, 0x1F40 }, // GREEK CAPITAL LETTER OMICRON WITH PSILI
- { 0x1F49, 0x1F41 }, // GREEK CAPITAL LETTER OMICRON WITH DASIA
- { 0x1F4A, 0x1F42 }, // GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
- { 0x1F4B, 0x1F43 }, // GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
- { 0x1F4C, 0x1F44 }, // GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
- { 0x1F4D, 0x1F45 }, // GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
- { 0x1F59, 0x1F51 }, // GREEK CAPITAL LETTER UPSILON WITH DASIA
- { 0x1F5B, 0x1F53 }, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
- { 0x1F5D, 0x1F55 }, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
- { 0x1F5F, 0x1F57 }, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
- { 0x1F68, 0x1F60 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI
- { 0x1F69, 0x1F61 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA
- { 0x1F6A, 0x1F62 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
- { 0x1F6B, 0x1F63 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
- { 0x1F6C, 0x1F64 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
- { 0x1F6D, 0x1F65 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
- { 0x1F6E, 0x1F66 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
- { 0x1F6F, 0x1F67 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
- { 0x1F88, 0x1F80 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
- { 0x1F89, 0x1F81 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
- { 0x1F8A, 0x1F82 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
- { 0x1F8B, 0x1F83 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
- { 0x1F8C, 0x1F84 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
- { 0x1F8D, 0x1F85 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
- { 0x1F8E, 0x1F86 }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
- { 0x1F8F, 0x1F87 }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
- { 0x1F98, 0x1F90 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
- { 0x1F99, 0x1F91 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
- { 0x1F9A, 0x1F92 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
- { 0x1F9B, 0x1F93 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
- { 0x1F9C, 0x1F94 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
- { 0x1F9D, 0x1F95 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
- { 0x1F9E, 0x1F96 }, // GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
- { 0x1F9F, 0x1F97 }, // GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
- { 0x1FA8, 0x1FA0 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
- { 0x1FA9, 0x1FA1 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
- { 0x1FAA, 0x1FA2 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
- { 0x1FAB, 0x1FA3 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
- { 0x1FAC, 0x1FA4 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
- { 0x1FAD, 0x1FA5 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
- { 0x1FAE, 0x1FA6 }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
- { 0x1FAF, 0x1FA7 }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
- { 0x1FB8, 0x1FB0 }, // GREEK CAPITAL LETTER ALPHA WITH VRACHY
- { 0x1FB9, 0x1FB1 }, // GREEK CAPITAL LETTER ALPHA WITH MACRON
- { 0x1FBA, 0x1F70 }, // GREEK CAPITAL LETTER ALPHA WITH VARIA
- { 0x1FBB, 0x1F71 }, // GREEK CAPITAL LETTER ALPHA WITH OXIA
- { 0x1FBC, 0x1FB3 }, // GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
- { 0x1FC8, 0x1F72 }, // GREEK CAPITAL LETTER EPSILON WITH VARIA
- { 0x1FC9, 0x1F73 }, // GREEK CAPITAL LETTER EPSILON WITH OXIA
- { 0x1FCA, 0x1F74 }, // GREEK CAPITAL LETTER ETA WITH VARIA
- { 0x1FCB, 0x1F75 }, // GREEK CAPITAL LETTER ETA WITH OXIA
- { 0x1FCC, 0x1FC3 }, // GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
- { 0x1FD8, 0x1FD0 }, // GREEK CAPITAL LETTER IOTA WITH VRACHY
- { 0x1FD9, 0x1FD1 }, // GREEK CAPITAL LETTER IOTA WITH MACRON
- { 0x1FDA, 0x1F76 }, // GREEK CAPITAL LETTER IOTA WITH VARIA
- { 0x1FDB, 0x1F77 }, // GREEK CAPITAL LETTER IOTA WITH OXIA
- { 0x1FE8, 0x1FE0 }, // GREEK CAPITAL LETTER UPSILON WITH VRACHY
- { 0x1FE9, 0x1FE1 }, // GREEK CAPITAL LETTER UPSILON WITH MACRON
- { 0x1FEA, 0x1F7A }, // GREEK CAPITAL LETTER UPSILON WITH VARIA
- { 0x1FEB, 0x1F7B }, // GREEK CAPITAL LETTER UPSILON WITH OXIA
- { 0x1FEC, 0x1FE5 }, // GREEK CAPITAL LETTER RHO WITH DASIA
- { 0x1FF8, 0x1F78 }, // GREEK CAPITAL LETTER OMICRON WITH VARIA
- { 0x1FF9, 0x1F79 }, // GREEK CAPITAL LETTER OMICRON WITH OXIA
- { 0x1FFA, 0x1F7C }, // GREEK CAPITAL LETTER OMEGA WITH VARIA
- { 0x1FFB, 0x1F7D }, // GREEK CAPITAL LETTER OMEGA WITH OXIA
- { 0x1FFC, 0x1FF3 }, // GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
- { 0x2126, 0x03C9 }, // OHM SIGN
- { 0x212A, 0x006B }, // KELVIN SIGN
- { 0x212B, 0x00E5 }, // ANGSTROM SIGN
- { 0x2132, 0x214E }, // TURNED CAPITAL F
- { 0x2160, 0x2170 }, // ROMAN NUMERAL ONE
- { 0x2161, 0x2171 }, // ROMAN NUMERAL TWO
- { 0x2162, 0x2172 }, // ROMAN NUMERAL THREE
- { 0x2163, 0x2173 }, // ROMAN NUMERAL FOUR
- { 0x2164, 0x2174 }, // ROMAN NUMERAL FIVE
- { 0x2165, 0x2175 }, // ROMAN NUMERAL SIX
- { 0x2166, 0x2176 }, // ROMAN NUMERAL SEVEN
- { 0x2167, 0x2177 }, // ROMAN NUMERAL EIGHT
- { 0x2168, 0x2178 }, // ROMAN NUMERAL NINE
- { 0x2169, 0x2179 }, // ROMAN NUMERAL TEN
- { 0x216A, 0x217A }, // ROMAN NUMERAL ELEVEN
- { 0x216B, 0x217B }, // ROMAN NUMERAL TWELVE
- { 0x216C, 0x217C }, // ROMAN NUMERAL FIFTY
- { 0x216D, 0x217D }, // ROMAN NUMERAL ONE HUNDRED
- { 0x216E, 0x217E }, // ROMAN NUMERAL FIVE HUNDRED
- { 0x216F, 0x217F }, // ROMAN NUMERAL ONE THOUSAND
- { 0x2183, 0x2184 }, // ROMAN NUMERAL REVERSED ONE HUNDRED
- { 0x24B6, 0x24D0 }, // CIRCLED LATIN CAPITAL LETTER A
- { 0x24B7, 0x24D1 }, // CIRCLED LATIN CAPITAL LETTER B
- { 0x24B8, 0x24D2 }, // CIRCLED LATIN CAPITAL LETTER C
- { 0x24B9, 0x24D3 }, // CIRCLED LATIN CAPITAL LETTER D
- { 0x24BA, 0x24D4 }, // CIRCLED LATIN CAPITAL LETTER E
- { 0x24BB, 0x24D5 }, // CIRCLED LATIN CAPITAL LETTER F
- { 0x24BC, 0x24D6 }, // CIRCLED LATIN CAPITAL LETTER G
- { 0x24BD, 0x24D7 }, // CIRCLED LATIN CAPITAL LETTER H
- { 0x24BE, 0x24D8 }, // CIRCLED LATIN CAPITAL LETTER I
- { 0x24BF, 0x24D9 }, // CIRCLED LATIN CAPITAL LETTER J
- { 0x24C0, 0x24DA }, // CIRCLED LATIN CAPITAL LETTER K
- { 0x24C1, 0x24DB }, // CIRCLED LATIN CAPITAL LETTER L
- { 0x24C2, 0x24DC }, // CIRCLED LATIN CAPITAL LETTER M
- { 0x24C3, 0x24DD }, // CIRCLED LATIN CAPITAL LETTER N
- { 0x24C4, 0x24DE }, // CIRCLED LATIN CAPITAL LETTER O
- { 0x24C5, 0x24DF }, // CIRCLED LATIN CAPITAL LETTER P
- { 0x24C6, 0x24E0 }, // CIRCLED LATIN CAPITAL LETTER Q
- { 0x24C7, 0x24E1 }, // CIRCLED LATIN CAPITAL LETTER R
- { 0x24C8, 0x24E2 }, // CIRCLED LATIN CAPITAL LETTER S
- { 0x24C9, 0x24E3 }, // CIRCLED LATIN CAPITAL LETTER T
- { 0x24CA, 0x24E4 }, // CIRCLED LATIN CAPITAL LETTER U
- { 0x24CB, 0x24E5 }, // CIRCLED LATIN CAPITAL LETTER V
- { 0x24CC, 0x24E6 }, // CIRCLED LATIN CAPITAL LETTER W
- { 0x24CD, 0x24E7 }, // CIRCLED LATIN CAPITAL LETTER X
- { 0x24CE, 0x24E8 }, // CIRCLED LATIN CAPITAL LETTER Y
- { 0x24CF, 0x24E9 }, // CIRCLED LATIN CAPITAL LETTER Z
- { 0x2C00, 0x2C30 }, // GLAGOLITIC CAPITAL LETTER AZU
- { 0x2C01, 0x2C31 }, // GLAGOLITIC CAPITAL LETTER BUKY
- { 0x2C02, 0x2C32 }, // GLAGOLITIC CAPITAL LETTER VEDE
- { 0x2C03, 0x2C33 }, // GLAGOLITIC CAPITAL LETTER GLAGOLI
- { 0x2C04, 0x2C34 }, // GLAGOLITIC CAPITAL LETTER DOBRO
- { 0x2C05, 0x2C35 }, // GLAGOLITIC CAPITAL LETTER YESTU
- { 0x2C06, 0x2C36 }, // GLAGOLITIC CAPITAL LETTER ZHIVETE
- { 0x2C07, 0x2C37 }, // GLAGOLITIC CAPITAL LETTER DZELO
- { 0x2C08, 0x2C38 }, // GLAGOLITIC CAPITAL LETTER ZEMLJA
- { 0x2C09, 0x2C39 }, // GLAGOLITIC CAPITAL LETTER IZHE
- { 0x2C0A, 0x2C3A }, // GLAGOLITIC CAPITAL LETTER INITIAL IZHE
- { 0x2C0B, 0x2C3B }, // GLAGOLITIC CAPITAL LETTER I
- { 0x2C0C, 0x2C3C }, // GLAGOLITIC CAPITAL LETTER DJERVI
- { 0x2C0D, 0x2C3D }, // GLAGOLITIC CAPITAL LETTER KAKO
- { 0x2C0E, 0x2C3E }, // GLAGOLITIC CAPITAL LETTER LJUDIJE
- { 0x2C0F, 0x2C3F }, // GLAGOLITIC CAPITAL LETTER MYSLITE
- { 0x2C10, 0x2C40 }, // GLAGOLITIC CAPITAL LETTER NASHI
- { 0x2C11, 0x2C41 }, // GLAGOLITIC CAPITAL LETTER ONU
- { 0x2C12, 0x2C42 }, // GLAGOLITIC CAPITAL LETTER POKOJI
- { 0x2C13, 0x2C43 }, // GLAGOLITIC CAPITAL LETTER RITSI
- { 0x2C14, 0x2C44 }, // GLAGOLITIC CAPITAL LETTER SLOVO
- { 0x2C15, 0x2C45 }, // GLAGOLITIC CAPITAL LETTER TVRIDO
- { 0x2C16, 0x2C46 }, // GLAGOLITIC CAPITAL LETTER UKU
- { 0x2C17, 0x2C47 }, // GLAGOLITIC CAPITAL LETTER FRITU
- { 0x2C18, 0x2C48 }, // GLAGOLITIC CAPITAL LETTER HERU
- { 0x2C19, 0x2C49 }, // GLAGOLITIC CAPITAL LETTER OTU
- { 0x2C1A, 0x2C4A }, // GLAGOLITIC CAPITAL LETTER PE
- { 0x2C1B, 0x2C4B }, // GLAGOLITIC CAPITAL LETTER SHTA
- { 0x2C1C, 0x2C4C }, // GLAGOLITIC CAPITAL LETTER TSI
- { 0x2C1D, 0x2C4D }, // GLAGOLITIC CAPITAL LETTER CHRIVI
- { 0x2C1E, 0x2C4E }, // GLAGOLITIC CAPITAL LETTER SHA
- { 0x2C1F, 0x2C4F }, // GLAGOLITIC CAPITAL LETTER YERU
- { 0x2C20, 0x2C50 }, // GLAGOLITIC CAPITAL LETTER YERI
- { 0x2C21, 0x2C51 }, // GLAGOLITIC CAPITAL LETTER YATI
- { 0x2C22, 0x2C52 }, // GLAGOLITIC CAPITAL LETTER SPIDERY HA
- { 0x2C23, 0x2C53 }, // GLAGOLITIC CAPITAL LETTER YU
- { 0x2C24, 0x2C54 }, // GLAGOLITIC CAPITAL LETTER SMALL YUS
- { 0x2C25, 0x2C55 }, // GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL
- { 0x2C26, 0x2C56 }, // GLAGOLITIC CAPITAL LETTER YO
- { 0x2C27, 0x2C57 }, // GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS
- { 0x2C28, 0x2C58 }, // GLAGOLITIC CAPITAL LETTER BIG YUS
- { 0x2C29, 0x2C59 }, // GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS
- { 0x2C2A, 0x2C5A }, // GLAGOLITIC CAPITAL LETTER FITA
- { 0x2C2B, 0x2C5B }, // GLAGOLITIC CAPITAL LETTER IZHITSA
- { 0x2C2C, 0x2C5C }, // GLAGOLITIC CAPITAL LETTER SHTAPIC
- { 0x2C2D, 0x2C5D }, // GLAGOLITIC CAPITAL LETTER TROKUTASTI A
- { 0x2C2E, 0x2C5E }, // GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
- { 0x2C60, 0x2C61 }, // LATIN CAPITAL LETTER L WITH DOUBLE BAR
- { 0x2C62, 0x026B }, // LATIN CAPITAL LETTER L WITH MIDDLE TILDE
- { 0x2C63, 0x1D7D }, // LATIN CAPITAL LETTER P WITH STROKE
- { 0x2C64, 0x027D }, // LATIN CAPITAL LETTER R WITH TAIL
- { 0x2C67, 0x2C68 }, // LATIN CAPITAL LETTER H WITH DESCENDER
- { 0x2C69, 0x2C6A }, // LATIN CAPITAL LETTER K WITH DESCENDER
- { 0x2C6B, 0x2C6C }, // LATIN CAPITAL LETTER Z WITH DESCENDER
- { 0x2C6D, 0x0251 }, // LATIN CAPITAL LETTER ALPHA
- { 0x2C6E, 0x0271 }, // LATIN CAPITAL LETTER M WITH HOOK
- { 0x2C6F, 0x0250 }, // LATIN CAPITAL LETTER TURNED A
- { 0x2C70, 0x0252 }, // LATIN CAPITAL LETTER TURNED ALPHA
- { 0x2C72, 0x2C73 }, // LATIN CAPITAL LETTER W WITH HOOK
- { 0x2C75, 0x2C76 }, // LATIN CAPITAL LETTER HALF H
- { 0x2C7E, 0x023F }, // LATIN CAPITAL LETTER S WITH SWASH TAIL
- { 0x2C7F, 0x0240 }, // LATIN CAPITAL LETTER Z WITH SWASH TAIL
- { 0x2C80, 0x2C81 }, // COPTIC CAPITAL LETTER ALFA
- { 0x2C82, 0x2C83 }, // COPTIC CAPITAL LETTER VIDA
- { 0x2C84, 0x2C85 }, // COPTIC CAPITAL LETTER GAMMA
- { 0x2C86, 0x2C87 }, // COPTIC CAPITAL LETTER DALDA
- { 0x2C88, 0x2C89 }, // COPTIC CAPITAL LETTER EIE
- { 0x2C8A, 0x2C8B }, // COPTIC CAPITAL LETTER SOU
- { 0x2C8C, 0x2C8D }, // COPTIC CAPITAL LETTER ZATA
- { 0x2C8E, 0x2C8F }, // COPTIC CAPITAL LETTER HATE
- { 0x2C90, 0x2C91 }, // COPTIC CAPITAL LETTER THETHE
- { 0x2C92, 0x2C93 }, // COPTIC CAPITAL LETTER IAUDA
- { 0x2C94, 0x2C95 }, // COPTIC CAPITAL LETTER KAPA
- { 0x2C96, 0x2C97 }, // COPTIC CAPITAL LETTER LAULA
- { 0x2C98, 0x2C99 }, // COPTIC CAPITAL LETTER MI
- { 0x2C9A, 0x2C9B }, // COPTIC CAPITAL LETTER NI
- { 0x2C9C, 0x2C9D }, // COPTIC CAPITAL LETTER KSI
- { 0x2C9E, 0x2C9F }, // COPTIC CAPITAL LETTER O
- { 0x2CA0, 0x2CA1 }, // COPTIC CAPITAL LETTER PI
- { 0x2CA2, 0x2CA3 }, // COPTIC CAPITAL LETTER RO
- { 0x2CA4, 0x2CA5 }, // COPTIC CAPITAL LETTER SIMA
- { 0x2CA6, 0x2CA7 }, // COPTIC CAPITAL LETTER TAU
- { 0x2CA8, 0x2CA9 }, // COPTIC CAPITAL LETTER UA
- { 0x2CAA, 0x2CAB }, // COPTIC CAPITAL LETTER FI
- { 0x2CAC, 0x2CAD }, // COPTIC CAPITAL LETTER KHI
- { 0x2CAE, 0x2CAF }, // COPTIC CAPITAL LETTER PSI
- { 0x2CB0, 0x2CB1 }, // COPTIC CAPITAL LETTER OOU
- { 0x2CB2, 0x2CB3 }, // COPTIC CAPITAL LETTER DIALECT-P ALEF
- { 0x2CB4, 0x2CB5 }, // COPTIC CAPITAL LETTER OLD COPTIC AIN
- { 0x2CB6, 0x2CB7 }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
- { 0x2CB8, 0x2CB9 }, // COPTIC CAPITAL LETTER DIALECT-P KAPA
- { 0x2CBA, 0x2CBB }, // COPTIC CAPITAL LETTER DIALECT-P NI
- { 0x2CBC, 0x2CBD }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
- { 0x2CBE, 0x2CBF }, // COPTIC CAPITAL LETTER OLD COPTIC OOU
- { 0x2CC0, 0x2CC1 }, // COPTIC CAPITAL LETTER SAMPI
- { 0x2CC2, 0x2CC3 }, // COPTIC CAPITAL LETTER CROSSED SHEI
- { 0x2CC4, 0x2CC5 }, // COPTIC CAPITAL LETTER OLD COPTIC SHEI
- { 0x2CC6, 0x2CC7 }, // COPTIC CAPITAL LETTER OLD COPTIC ESH
- { 0x2CC8, 0x2CC9 }, // COPTIC CAPITAL LETTER AKHMIMIC KHEI
- { 0x2CCA, 0x2CCB }, // COPTIC CAPITAL LETTER DIALECT-P HORI
- { 0x2CCC, 0x2CCD }, // COPTIC CAPITAL LETTER OLD COPTIC HORI
- { 0x2CCE, 0x2CCF }, // COPTIC CAPITAL LETTER OLD COPTIC HA
- { 0x2CD0, 0x2CD1 }, // COPTIC CAPITAL LETTER L-SHAPED HA
- { 0x2CD2, 0x2CD3 }, // COPTIC CAPITAL LETTER OLD COPTIC HEI
- { 0x2CD4, 0x2CD5 }, // COPTIC CAPITAL LETTER OLD COPTIC HAT
- { 0x2CD6, 0x2CD7 }, // COPTIC CAPITAL LETTER OLD COPTIC GANGIA
- { 0x2CD8, 0x2CD9 }, // COPTIC CAPITAL LETTER OLD COPTIC DJA
- { 0x2CDA, 0x2CDB }, // COPTIC CAPITAL LETTER OLD COPTIC SHIMA
- { 0x2CDC, 0x2CDD }, // COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
- { 0x2CDE, 0x2CDF }, // COPTIC CAPITAL LETTER OLD NUBIAN NGI
- { 0x2CE0, 0x2CE1 }, // COPTIC CAPITAL LETTER OLD NUBIAN NYI
- { 0x2CE2, 0x2CE3 }, // COPTIC CAPITAL LETTER OLD NUBIAN WAU
- { 0x2CEB, 0x2CEC }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI
- { 0x2CED, 0x2CEE }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA
- { 0xA640, 0xA641 }, // CYRILLIC CAPITAL LETTER ZEMLYA
- { 0xA642, 0xA643 }, // CYRILLIC CAPITAL LETTER DZELO
- { 0xA644, 0xA645 }, // CYRILLIC CAPITAL LETTER REVERSED DZE
- { 0xA646, 0xA647 }, // CYRILLIC CAPITAL LETTER IOTA
- { 0xA648, 0xA649 }, // CYRILLIC CAPITAL LETTER DJERV
- { 0xA64A, 0xA64B }, // CYRILLIC CAPITAL LETTER MONOGRAPH UK
- { 0xA64C, 0xA64D }, // CYRILLIC CAPITAL LETTER BROAD OMEGA
- { 0xA64E, 0xA64F }, // CYRILLIC CAPITAL LETTER NEUTRAL YER
- { 0xA650, 0xA651 }, // CYRILLIC CAPITAL LETTER YERU WITH BACK YER
- { 0xA652, 0xA653 }, // CYRILLIC CAPITAL LETTER IOTIFIED YAT
- { 0xA654, 0xA655 }, // CYRILLIC CAPITAL LETTER REVERSED YU
- { 0xA656, 0xA657 }, // CYRILLIC CAPITAL LETTER IOTIFIED A
- { 0xA658, 0xA659 }, // CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS
- { 0xA65A, 0xA65B }, // CYRILLIC CAPITAL LETTER BLENDED YUS
- { 0xA65C, 0xA65D }, // CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS
- { 0xA65E, 0xA65F }, // CYRILLIC CAPITAL LETTER YN
- { 0xA662, 0xA663 }, // CYRILLIC CAPITAL LETTER SOFT DE
- { 0xA664, 0xA665 }, // CYRILLIC CAPITAL LETTER SOFT EL
- { 0xA666, 0xA667 }, // CYRILLIC CAPITAL LETTER SOFT EM
- { 0xA668, 0xA669 }, // CYRILLIC CAPITAL LETTER MONOCULAR O
- { 0xA66A, 0xA66B }, // CYRILLIC CAPITAL LETTER BINOCULAR O
- { 0xA66C, 0xA66D }, // CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O
- { 0xA680, 0xA681 }, // CYRILLIC CAPITAL LETTER DWE
- { 0xA682, 0xA683 }, // CYRILLIC CAPITAL LETTER DZWE
- { 0xA684, 0xA685 }, // CYRILLIC CAPITAL LETTER ZHWE
- { 0xA686, 0xA687 }, // CYRILLIC CAPITAL LETTER CCHE
- { 0xA688, 0xA689 }, // CYRILLIC CAPITAL LETTER DZZE
- { 0xA68A, 0xA68B }, // CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK
- { 0xA68C, 0xA68D }, // CYRILLIC CAPITAL LETTER TWE
- { 0xA68E, 0xA68F }, // CYRILLIC CAPITAL LETTER TSWE
- { 0xA690, 0xA691 }, // CYRILLIC CAPITAL LETTER TSSE
- { 0xA692, 0xA693 }, // CYRILLIC CAPITAL LETTER TCHE
- { 0xA694, 0xA695 }, // CYRILLIC CAPITAL LETTER HWE
- { 0xA696, 0xA697 }, // CYRILLIC CAPITAL LETTER SHWE
- { 0xA722, 0xA723 }, // LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF
- { 0xA724, 0xA725 }, // LATIN CAPITAL LETTER EGYPTOLOGICAL AIN
- { 0xA726, 0xA727 }, // LATIN CAPITAL LETTER HENG
- { 0xA728, 0xA729 }, // LATIN CAPITAL LETTER TZ
- { 0xA72A, 0xA72B }, // LATIN CAPITAL LETTER TRESILLO
- { 0xA72C, 0xA72D }, // LATIN CAPITAL LETTER CUATRILLO
- { 0xA72E, 0xA72F }, // LATIN CAPITAL LETTER CUATRILLO WITH COMMA
- { 0xA732, 0xA733 }, // LATIN CAPITAL LETTER AA
- { 0xA734, 0xA735 }, // LATIN CAPITAL LETTER AO
- { 0xA736, 0xA737 }, // LATIN CAPITAL LETTER AU
- { 0xA738, 0xA739 }, // LATIN CAPITAL LETTER AV
- { 0xA73A, 0xA73B }, // LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR
- { 0xA73C, 0xA73D }, // LATIN CAPITAL LETTER AY
- { 0xA73E, 0xA73F }, // LATIN CAPITAL LETTER REVERSED C WITH DOT
- { 0xA740, 0xA741 }, // LATIN CAPITAL LETTER K WITH STROKE
- { 0xA742, 0xA743 }, // LATIN CAPITAL LETTER K WITH DIAGONAL STROKE
- { 0xA744, 0xA745 }, // LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE
- { 0xA746, 0xA747 }, // LATIN CAPITAL LETTER BROKEN L
- { 0xA748, 0xA749 }, // LATIN CAPITAL LETTER L WITH HIGH STROKE
- { 0xA74A, 0xA74B }, // LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY
- { 0xA74C, 0xA74D }, // LATIN CAPITAL LETTER O WITH LOOP
- { 0xA74E, 0xA74F }, // LATIN CAPITAL LETTER OO
- { 0xA750, 0xA751 }, // LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER
- { 0xA752, 0xA753 }, // LATIN CAPITAL LETTER P WITH FLOURISH
- { 0xA754, 0xA755 }, // LATIN CAPITAL LETTER P WITH SQUIRREL TAIL
- { 0xA756, 0xA757 }, // LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER
- { 0xA758, 0xA759 }, // LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE
- { 0xA75A, 0xA75B }, // LATIN CAPITAL LETTER R ROTUNDA
- { 0xA75C, 0xA75D }, // LATIN CAPITAL LETTER RUM ROTUNDA
- { 0xA75E, 0xA75F }, // LATIN CAPITAL LETTER V WITH DIAGONAL STROKE
- { 0xA760, 0xA761 }, // LATIN CAPITAL LETTER VY
- { 0xA762, 0xA763 }, // LATIN CAPITAL LETTER VISIGOTHIC Z
- { 0xA764, 0xA765 }, // LATIN CAPITAL LETTER THORN WITH STROKE
- { 0xA766, 0xA767 }, // LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER
- { 0xA768, 0xA769 }, // LATIN CAPITAL LETTER VEND
- { 0xA76A, 0xA76B }, // LATIN CAPITAL LETTER ET
- { 0xA76C, 0xA76D }, // LATIN CAPITAL LETTER IS
- { 0xA76E, 0xA76F }, // LATIN CAPITAL LETTER CON
- { 0xA779, 0xA77A }, // LATIN CAPITAL LETTER INSULAR D
- { 0xA77B, 0xA77C }, // LATIN CAPITAL LETTER INSULAR F
- { 0xA77D, 0x1D79 }, // LATIN CAPITAL LETTER INSULAR G
- { 0xA77E, 0xA77F }, // LATIN CAPITAL LETTER TURNED INSULAR G
- { 0xA780, 0xA781 }, // LATIN CAPITAL LETTER TURNED L
- { 0xA782, 0xA783 }, // LATIN CAPITAL LETTER INSULAR R
- { 0xA784, 0xA785 }, // LATIN CAPITAL LETTER INSULAR S
- { 0xA786, 0xA787 }, // LATIN CAPITAL LETTER INSULAR T
- { 0xA78B, 0xA78C }, // LATIN CAPITAL LETTER SALTILLO
- { 0xFF21, 0xFF41 }, // FULLWIDTH LATIN CAPITAL LETTER A
- { 0xFF22, 0xFF42 }, // FULLWIDTH LATIN CAPITAL LETTER B
- { 0xFF23, 0xFF43 }, // FULLWIDTH LATIN CAPITAL LETTER C
- { 0xFF24, 0xFF44 }, // FULLWIDTH LATIN CAPITAL LETTER D
- { 0xFF25, 0xFF45 }, // FULLWIDTH LATIN CAPITAL LETTER E
- { 0xFF26, 0xFF46 }, // FULLWIDTH LATIN CAPITAL LETTER F
- { 0xFF27, 0xFF47 }, // FULLWIDTH LATIN CAPITAL LETTER G
- { 0xFF28, 0xFF48 }, // FULLWIDTH LATIN CAPITAL LETTER H
- { 0xFF29, 0xFF49 }, // FULLWIDTH LATIN CAPITAL LETTER I
- { 0xFF2A, 0xFF4A }, // FULLWIDTH LATIN CAPITAL LETTER J
- { 0xFF2B, 0xFF4B }, // FULLWIDTH LATIN CAPITAL LETTER K
- { 0xFF2C, 0xFF4C }, // FULLWIDTH LATIN CAPITAL LETTER L
- { 0xFF2D, 0xFF4D }, // FULLWIDTH LATIN CAPITAL LETTER M
- { 0xFF2E, 0xFF4E }, // FULLWIDTH LATIN CAPITAL LETTER N
- { 0xFF2F, 0xFF4F }, // FULLWIDTH LATIN CAPITAL LETTER O
- { 0xFF30, 0xFF50 }, // FULLWIDTH LATIN CAPITAL LETTER P
- { 0xFF31, 0xFF51 }, // FULLWIDTH LATIN CAPITAL LETTER Q
- { 0xFF32, 0xFF52 }, // FULLWIDTH LATIN CAPITAL LETTER R
- { 0xFF33, 0xFF53 }, // FULLWIDTH LATIN CAPITAL LETTER S
- { 0xFF34, 0xFF54 }, // FULLWIDTH LATIN CAPITAL LETTER T
- { 0xFF35, 0xFF55 }, // FULLWIDTH LATIN CAPITAL LETTER U
- { 0xFF36, 0xFF56 }, // FULLWIDTH LATIN CAPITAL LETTER V
- { 0xFF37, 0xFF57 }, // FULLWIDTH LATIN CAPITAL LETTER W
- { 0xFF38, 0xFF58 }, // FULLWIDTH LATIN CAPITAL LETTER X
- { 0xFF39, 0xFF59 }, // FULLWIDTH LATIN CAPITAL LETTER Y
- { 0xFF3A, 0xFF5A } // FULLWIDTH LATIN CAPITAL LETTER Z
-};
-
-static int compare_pair_capital(const void *a, const void *b) {
- return (int)(*(unsigned short *)a)
- - (int)((struct LatinCapitalSmallPair*)b)->capital;
-}
-
-unsigned short latin_tolower(unsigned short c) {
- struct LatinCapitalSmallPair *p =
- (struct LatinCapitalSmallPair *)bsearch(&c, SORTED_CHAR_MAP,
- sizeof(SORTED_CHAR_MAP) / sizeof(SORTED_CHAR_MAP[0]),
- sizeof(SORTED_CHAR_MAP[0]),
- compare_pair_capital);
- return p ? p->small : c;
-}
-
-} // namespace latinime
diff --git a/src/java/KP2ASoftKeyboard2/native/jni/char_utils.h b/src/java/KP2ASoftKeyboard2/native/jni/char_utils.h
deleted file mode 100644
index 921ecb4a..00000000
--- a/src/java/KP2ASoftKeyboard2/native/jni/char_utils.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * 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 "AS IS" 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.
- */
-
-#ifndef LATINIME_CHAR_UTILS_H
-#define LATINIME_CHAR_UTILS_H
-
-namespace latinime {
-
-unsigned short latin_tolower(unsigned short c);
-
-}; // namespace latinime
-
-#endif // LATINIME_CHAR_UTILS_H
diff --git a/src/java/KP2ASoftKeyboard2/native/jni/dictionary.cpp b/src/java/KP2ASoftKeyboard2/native/jni/dictionary.cpp
deleted file mode 100644
index 1a39f585..00000000
--- a/src/java/KP2ASoftKeyboard2/native/jni/dictionary.cpp
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** 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 "AS IS" 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.
-*/
-
-#include
-#include
-#include
-#include
-//#define LOG_TAG "dictionary.cpp"
-//#include
-#define LOGI
-
-#include "dictionary.h"
-#include "basechars.h"
-#include "char_utils.h"
-
-#define DEBUG_DICT 0
-#define DICTIONARY_VERSION_MIN 200
-#define DICTIONARY_HEADER_SIZE 2
-#define NOT_VALID_WORD -99
-
-namespace latinime {
-
-Dictionary::Dictionary(void *dict, int typedLetterMultiplier, int fullWordMultiplier)
-{
- mDict = (unsigned char*) dict;
- mTypedLetterMultiplier = typedLetterMultiplier;
- mFullWordMultiplier = fullWordMultiplier;
- getVersionNumber();
-}
-
-Dictionary::~Dictionary()
-{
-}
-
-int Dictionary::getSuggestions(int *codes, int codesSize, unsigned short *outWords, int *frequencies,
- int maxWordLength, int maxWords, int maxAlternatives, int skipPos,
- int *nextLetters, int nextLettersSize)
-{
- int suggWords;
- mFrequencies = frequencies;
- mOutputChars = outWords;
- mInputCodes = codes;
- mInputLength = codesSize;
- mMaxAlternatives = maxAlternatives;
- mMaxWordLength = maxWordLength;
- mMaxWords = maxWords;
- mSkipPos = skipPos;
- mMaxEditDistance = mInputLength < 5 ? 2 : mInputLength / 2;
- mNextLettersFrequencies = nextLetters;
- mNextLettersSize = nextLettersSize;
-
- if (checkIfDictVersionIsLatest()) {
- getWordsRec(DICTIONARY_HEADER_SIZE, 0, mInputLength * 3, false, 1, 0, 0);
- } else {
- getWordsRec(0, 0, mInputLength * 3, false, 1, 0, 0);
- }
-
- // Get the word count
- suggWords = 0;
- while (suggWords < mMaxWords && mFrequencies[suggWords] > 0) suggWords++;
- if (DEBUG_DICT) LOGI("Returning %d words", suggWords);
-
- if (DEBUG_DICT) {
- LOGI("Next letters: ");
- for (int k = 0; k < nextLettersSize; k++) {
- if (mNextLettersFrequencies[k] > 0) {
- LOGI("%c = %d,", k, mNextLettersFrequencies[k]);
- }
- }
- LOGI("\n");
- }
- return suggWords;
-}
-
-void
-Dictionary::registerNextLetter(unsigned short c)
-{
- if (c < mNextLettersSize) {
- mNextLettersFrequencies[c]++;
- }
-}
-
-void
-Dictionary::getVersionNumber()
-{
- mVersion = (mDict[0] & 0xFF);
- mBigram = (mDict[1] & 0xFF);
- LOGI("IN NATIVE SUGGEST Version: %d Bigram : %d \n", mVersion, mBigram);
-}
-
-// Checks whether it has the latest dictionary or the old dictionary
-bool
-Dictionary::checkIfDictVersionIsLatest()
-{
- return (mVersion >= DICTIONARY_VERSION_MIN) && (mBigram == 1 || mBigram == 0);
-}
-
-unsigned short
-Dictionary::getChar(int *pos)
-{
- unsigned short ch = (unsigned short) (mDict[(*pos)++] & 0xFF);
- // If the code is 255, then actual 16 bit code follows (in big endian)
- if (ch == 0xFF) {
- ch = ((mDict[*pos] & 0xFF) << 8) | (mDict[*pos + 1] & 0xFF);
- (*pos) += 2;
- }
- return ch;
-}
-
-int
-Dictionary::getAddress(int *pos)
-{
- int address = 0;
- if ((mDict[*pos] & FLAG_ADDRESS_MASK) == 0) {
- *pos += 1;
- } else {
- address += (mDict[*pos] & (ADDRESS_MASK >> 16)) << 16;
- address += (mDict[*pos + 1] & 0xFF) << 8;
- address += (mDict[*pos + 2] & 0xFF);
- *pos += 3;
- }
- return address;
-}
-
-int
-Dictionary::getFreq(int *pos)
-{
- int freq = mDict[(*pos)++] & 0xFF;
-
- if (checkIfDictVersionIsLatest()) {
- // skipping bigram
- int bigramExist = (mDict[*pos] & FLAG_BIGRAM_READ);
- if (bigramExist > 0) {
- int nextBigramExist = 1;
- while (nextBigramExist > 0) {
- (*pos) += 3;
- nextBigramExist = (mDict[(*pos)++] & FLAG_BIGRAM_CONTINUED);
- }
- } else {
- (*pos)++;
- }
- }
-
- return freq;
-}
-
-int
-Dictionary::wideStrLen(unsigned short *str)
-{
- if (!str) return 0;
- unsigned short *end = str;
- while (*end)
- end++;
- return end - str;
-}
-
-bool
-Dictionary::addWord(unsigned short *word, int length, int frequency)
-{
- word[length] = 0;
- if (DEBUG_DICT) {
- char s[length + 1];
- for (int i = 0; i <= length; i++) s[i] = word[i];
- LOGI("Found word = %s, freq = %d : \n", s, frequency);
- }
-
- // Find the right insertion point
- int insertAt = 0;
- while (insertAt < mMaxWords) {
- if (frequency > mFrequencies[insertAt]
- || (mFrequencies[insertAt] == frequency
- && length < wideStrLen(mOutputChars + insertAt * mMaxWordLength))) {
- break;
- }
- insertAt++;
- }
- if (insertAt < mMaxWords) {
- memmove((char*) mFrequencies + (insertAt + 1) * sizeof(mFrequencies[0]),
- (char*) mFrequencies + insertAt * sizeof(mFrequencies[0]),
- (mMaxWords - insertAt - 1) * sizeof(mFrequencies[0]));
- mFrequencies[insertAt] = frequency;
- memmove((char*) mOutputChars + (insertAt + 1) * mMaxWordLength * sizeof(short),
- (char*) mOutputChars + (insertAt ) * mMaxWordLength * sizeof(short),
- (mMaxWords - insertAt - 1) * sizeof(short) * mMaxWordLength);
- unsigned short *dest = mOutputChars + (insertAt ) * mMaxWordLength;
- while (length--) {
- *dest++ = *word++;
- }
- *dest = 0; // NULL terminate
- if (DEBUG_DICT) LOGI("Added word at %d\n", insertAt);
- return true;
- }
- return false;
-}
-
-bool
-Dictionary::addWordBigram(unsigned short *word, int length, int frequency)
-{
- word[length] = 0;
- if (DEBUG_DICT) {
- char s[length + 1];
- for (int i = 0; i <= length; i++) s[i] = word[i];
- LOGI("Bigram: Found word = %s, freq = %d : \n", s, frequency);
- }
-
- // Find the right insertion point
- int insertAt = 0;
- while (insertAt < mMaxBigrams) {
- if (frequency > mBigramFreq[insertAt]
- || (mBigramFreq[insertAt] == frequency
- && length < wideStrLen(mBigramChars + insertAt * mMaxWordLength))) {
- break;
- }
- insertAt++;
- }
- LOGI("Bigram: InsertAt -> %d maxBigrams: %d\n", insertAt, mMaxBigrams);
- if (insertAt < mMaxBigrams) {
- memmove((char*) mBigramFreq + (insertAt + 1) * sizeof(mBigramFreq[0]),
- (char*) mBigramFreq + insertAt * sizeof(mBigramFreq[0]),
- (mMaxBigrams - insertAt - 1) * sizeof(mBigramFreq[0]));
- mBigramFreq[insertAt] = frequency;
- memmove((char*) mBigramChars + (insertAt + 1) * mMaxWordLength * sizeof(short),
- (char*) mBigramChars + (insertAt ) * mMaxWordLength * sizeof(short),
- (mMaxBigrams - insertAt - 1) * sizeof(short) * mMaxWordLength);
- unsigned short *dest = mBigramChars + (insertAt ) * mMaxWordLength;
- while (length--) {
- *dest++ = *word++;
- }
- *dest = 0; // NULL terminate
- if (DEBUG_DICT) LOGI("Bigram: Added word at %d\n", insertAt);
- return true;
- }
- return false;
-}
-
-unsigned short
-Dictionary::toLowerCase(unsigned short c) {
- if (c < sizeof(BASE_CHARS) / sizeof(BASE_CHARS[0])) {
- c = BASE_CHARS[c];
- }
- if (c >='A' && c <= 'Z') {
- c |= 32;
- } else if (c > 127) {
- c = latin_tolower(c);
- }
- return c;
-}
-
-bool
-Dictionary::sameAsTyped(unsigned short *word, int length)
-{
- if (length != mInputLength) {
- return false;
- }
- int *inputCodes = mInputCodes;
- while (length--) {
- if ((unsigned int) *inputCodes != (unsigned int) *word) {
- return false;
- }
- inputCodes += mMaxAlternatives;
- word++;
- }
- return true;
-}
-
-static char QUOTE = '\'';
-
-void
-Dictionary::getWordsRec(int pos, int depth, int maxDepth, bool completion, int snr, int inputIndex,
- int diffs)
-{
- // Optimization: Prune out words that are too long compared to how much was typed.
- if (depth > maxDepth) {
- return;
- }
- if (diffs > mMaxEditDistance) {
- return;
- }
- int count = getCount(&pos);
- int *currentChars = NULL;
- if (mInputLength <= inputIndex) {
- completion = true;
- } else {
- currentChars = mInputCodes + (inputIndex * mMaxAlternatives);
- }
-
- for (int i = 0; i < count; i++) {
- // -- at char
- unsigned short c = getChar(&pos);
- // -- at flag/add
- unsigned short lowerC = toLowerCase(c);
- bool terminal = getTerminal(&pos);
- int childrenAddress = getAddress(&pos);
- // -- after address or flag
- int freq = 1;
- if (terminal) freq = getFreq(&pos);
- // -- after add or freq
-
- // If we are only doing completions, no need to look at the typed characters.
- if (completion) {
- mWord[depth] = c;
- if (terminal) {
- addWord(mWord, depth + 1, freq * snr);
- if (depth >= mInputLength && mSkipPos < 0) {
- registerNextLetter(mWord[mInputLength]);
- }
- }
- if (childrenAddress != 0) {
- getWordsRec(childrenAddress, depth + 1, maxDepth,
- completion, snr, inputIndex, diffs);
- }
- } else if ((c == QUOTE && currentChars[0] != QUOTE) || mSkipPos == depth) {
- // Skip the ' or other letter and continue deeper
- mWord[depth] = c;
- if (childrenAddress != 0) {
- getWordsRec(childrenAddress, depth + 1, maxDepth, false, snr, inputIndex, diffs);
- }
- } else {
- int j = 0;
- while (currentChars[j] > 0) {
- if (currentChars[j] == lowerC || currentChars[j] == c) {
- int addedWeight = j == 0 ? mTypedLetterMultiplier : 1;
- mWord[depth] = c;
- if (mInputLength == inputIndex + 1) {
- if (terminal) {
- if (//INCLUDE_TYPED_WORD_IF_VALID ||
- !sameAsTyped(mWord, depth + 1)) {
- int finalFreq = freq * snr * addedWeight;
- if (mSkipPos < 0) finalFreq *= mFullWordMultiplier;
- addWord(mWord, depth + 1, finalFreq);
- }
- }
- if (childrenAddress != 0) {
- getWordsRec(childrenAddress, depth + 1,
- maxDepth, true, snr * addedWeight, inputIndex + 1,
- diffs + (j > 0));
- }
- } else if (childrenAddress != 0) {
- getWordsRec(childrenAddress, depth + 1, maxDepth,
- false, snr * addedWeight, inputIndex + 1, diffs + (j > 0));
- }
- }
- j++;
- if (mSkipPos >= 0) break;
- }
- }
- }
-}
-
-int
-Dictionary::getBigramAddress(int *pos, bool advance)
-{
- int address = 0;
-
- address += (mDict[*pos] & 0x3F) << 16;
- address += (mDict[*pos + 1] & 0xFF) << 8;
- address += (mDict[*pos + 2] & 0xFF);
-
- if (advance) {
- *pos += 3;
- }
-
- return address;
-}
-
-int
-Dictionary::getBigramFreq(int *pos)
-{
- int freq = mDict[(*pos)++] & FLAG_BIGRAM_FREQ;
-
- return freq;
-}
-
-
-int
-Dictionary::getBigrams(unsigned short *prevWord, int prevWordLength, int *codes, int codesSize,
- unsigned short *bigramChars, int *bigramFreq, int maxWordLength, int maxBigrams,
- int maxAlternatives)
-{
- mBigramFreq = bigramFreq;
- mBigramChars = bigramChars;
- mInputCodes = codes;
- mInputLength = codesSize;
- mMaxWordLength = maxWordLength;
- mMaxBigrams = maxBigrams;
- mMaxAlternatives = maxAlternatives;
-
- if (mBigram == 1 && checkIfDictVersionIsLatest()) {
- int pos = isValidWordRec(DICTIONARY_HEADER_SIZE, prevWord, 0, prevWordLength);
- LOGI("Pos -> %d\n", pos);
- if (pos < 0) {
- return 0;
- }
-
- int bigramCount = 0;
- int bigramExist = (mDict[pos] & FLAG_BIGRAM_READ);
- if (bigramExist > 0) {
- int nextBigramExist = 1;
- while (nextBigramExist > 0 && bigramCount < maxBigrams) {
- int bigramAddress = getBigramAddress(&pos, true);
- int frequency = (FLAG_BIGRAM_FREQ & mDict[pos]);
- // search for all bigrams and store them
- searchForTerminalNode(bigramAddress, frequency);
- nextBigramExist = (mDict[pos++] & FLAG_BIGRAM_CONTINUED);
- bigramCount++;
- }
- }
-
- return bigramCount;
- }
- return 0;
-}
-
-void
-Dictionary::searchForTerminalNode(int addressLookingFor, int frequency)
-{
- // track word with such address and store it in an array
- unsigned short word[mMaxWordLength];
-
- int pos;
- int followDownBranchAddress = DICTIONARY_HEADER_SIZE;
- bool found = false;
- char followingChar = ' ';
- int depth = -1;
-
- while(!found) {
- bool followDownAddressSearchStop = false;
- bool firstAddress = true;
- bool haveToSearchAll = true;
-
- if (depth >= 0) {
- word[depth] = (unsigned short) followingChar;
- }
- pos = followDownBranchAddress; // pos start at count
- int count = mDict[pos] & 0xFF;
- LOGI("count - %d\n",count);
- pos++;
- for (int i = 0; i < count; i++) {
- // pos at data
- pos++;
- // pos now at flag
- if (!getFirstBitOfByte(&pos)) { // non-terminal
- if (!followDownAddressSearchStop) {
- int addr = getBigramAddress(&pos, false);
- if (addr > addressLookingFor) {
- followDownAddressSearchStop = true;
- if (firstAddress) {
- firstAddress = false;
- haveToSearchAll = true;
- } else if (!haveToSearchAll) {
- break;
- }
- } else {
- followDownBranchAddress = addr;
- followingChar = (char)(0xFF & mDict[pos-1]);
- if (firstAddress) {
- firstAddress = false;
- haveToSearchAll = false;
- }
- }
- }
- pos += 3;
- } else if (getFirstBitOfByte(&pos)) { // terminal
- if (addressLookingFor == (pos-1)) { // found !!
- depth++;
- word[depth] = (0xFF & mDict[pos-1]);
- found = true;
- break;
- }
- if (getSecondBitOfByte(&pos)) { // address + freq (4 byte)
- if (!followDownAddressSearchStop) {
- int addr = getBigramAddress(&pos, false);
- if (addr > addressLookingFor) {
- followDownAddressSearchStop = true;
- if (firstAddress) {
- firstAddress = false;
- haveToSearchAll = true;
- } else if (!haveToSearchAll) {
- break;
- }
- } else {
- followDownBranchAddress = addr;
- followingChar = (char)(0xFF & mDict[pos-1]);
- if (firstAddress) {
- firstAddress = false;
- haveToSearchAll = true;
- }
- }
- }
- pos += 4;
- } else { // freq only (2 byte)
- pos += 2;
- }
-
- // skipping bigram
- int bigramExist = (mDict[pos] & FLAG_BIGRAM_READ);
- if (bigramExist > 0) {
- int nextBigramExist = 1;
- while (nextBigramExist > 0) {
- pos += 3;
- nextBigramExist = (mDict[pos++] & FLAG_BIGRAM_CONTINUED);
- }
- } else {
- pos++;
- }
- }
- }
- depth++;
- if (followDownBranchAddress == 0) {
- LOGI("ERROR!!! Cannot find bigram!!");
- break;
- }
- }
- if (checkFirstCharacter(word)) {
- addWordBigram(word, depth, frequency);
- }
-}
-
-bool
-Dictionary::checkFirstCharacter(unsigned short *word)
-{
- // Checks whether this word starts with same character or neighboring characters of
- // what user typed.
-
- int *inputCodes = mInputCodes;
- int maxAlt = mMaxAlternatives;
- while (maxAlt > 0) {
- if ((unsigned int) *inputCodes == (unsigned int) *word) {
- return true;
- }
- inputCodes++;
- maxAlt--;
- }
- return false;
-}
-
-bool
-Dictionary::isValidWord(unsigned short *word, int length)
-{
- if (checkIfDictVersionIsLatest()) {
- return (isValidWordRec(DICTIONARY_HEADER_SIZE, word, 0, length) != NOT_VALID_WORD);
- } else {
- return (isValidWordRec(0, word, 0, length) != NOT_VALID_WORD);
- }
-}
-
-int
-Dictionary::isValidWordRec(int pos, unsigned short *word, int offset, int length) {
- // returns address of bigram data of that word
- // return -99 if not found
-
- int count = getCount(&pos);
- unsigned short currentChar = (unsigned short) word[offset];
- for (int j = 0; j < count; j++) {
- unsigned short c = getChar(&pos);
- int terminal = getTerminal(&pos);
- int childPos = getAddress(&pos);
- if (c == currentChar) {
- if (offset == length - 1) {
- if (terminal) {
- return (pos+1);
- }
- } else {
- if (childPos != 0) {
- int t = isValidWordRec(childPos, word, offset + 1, length);
- if (t > 0) {
- return t;
- }
- }
- }
- }
- if (terminal) {
- getFreq(&pos);
- }
- // There could be two instances of each alphabet - upper and lower case. So continue
- // looking ...
- }
- return NOT_VALID_WORD;
-}
-
-
-} // namespace latinime
diff --git a/src/java/KP2ASoftKeyboard2/native/jni/dictionary.h b/src/java/KP2ASoftKeyboard2/native/jni/dictionary.h
deleted file mode 100644
index d13496e0..00000000
--- a/src/java/KP2ASoftKeyboard2/native/jni/dictionary.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * 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 "AS IS" 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.
- */
-
-#ifndef LATINIME_DICTIONARY_H
-#define LATINIME_DICTIONARY_H
-
-namespace latinime {
-
-// 22-bit address = ~4MB dictionary size limit, which on average would be about 200k-300k words
-#define ADDRESS_MASK 0x3FFFFF
-
-// The bit that decides if an address follows in the next 22 bits
-#define FLAG_ADDRESS_MASK 0x40
-// The bit that decides if this is a terminal node for a word. The node could still have children,
-// if the word has other endings.
-#define FLAG_TERMINAL_MASK 0x80
-
-#define FLAG_BIGRAM_READ 0x80
-#define FLAG_BIGRAM_CHILDEXIST 0x40
-#define FLAG_BIGRAM_CONTINUED 0x80
-#define FLAG_BIGRAM_FREQ 0x7F
-
-class Dictionary {
-public:
- Dictionary(void *dict, int typedLetterMultipler, int fullWordMultiplier);
- int getSuggestions(int *codes, int codesSize, unsigned short *outWords, int *frequencies,
- int maxWordLength, int maxWords, int maxAlternatives, int skipPos,
- int *nextLetters, int nextLettersSize);
- int getBigrams(unsigned short *word, int length, int *codes, int codesSize,
- unsigned short *outWords, int *frequencies, int maxWordLength, int maxBigrams,
- int maxAlternatives);
- bool isValidWord(unsigned short *word, int length);
- void setAsset(void *asset) { mAsset = asset; }
- void *getAsset() { return mAsset; }
- ~Dictionary();
-
-private:
-
- void getVersionNumber();
- bool checkIfDictVersionIsLatest();
- int getAddress(int *pos);
- int getBigramAddress(int *pos, bool advance);
- int getFreq(int *pos);
- int getBigramFreq(int *pos);
- void searchForTerminalNode(int address, int frequency);
-
- bool getFirstBitOfByte(int *pos) { return (mDict[*pos] & 0x80) > 0; }
- bool getSecondBitOfByte(int *pos) { return (mDict[*pos] & 0x40) > 0; }
- bool getTerminal(int *pos) { return (mDict[*pos] & FLAG_TERMINAL_MASK) > 0; }
- int getCount(int *pos) { return mDict[(*pos)++] & 0xFF; }
- unsigned short getChar(int *pos);
- int wideStrLen(unsigned short *str);
-
- bool sameAsTyped(unsigned short *word, int length);
- bool checkFirstCharacter(unsigned short *word);
- bool addWord(unsigned short *word, int length, int frequency);
- bool addWordBigram(unsigned short *word, int length, int frequency);
- unsigned short toLowerCase(unsigned short c);
- void getWordsRec(int pos, int depth, int maxDepth, bool completion, int frequency,
- int inputIndex, int diffs);
- int isValidWordRec(int pos, unsigned short *word, int offset, int length);
- void registerNextLetter(unsigned short c);
-
- unsigned char *mDict;
- void *mAsset;
-
- int *mFrequencies;
- int *mBigramFreq;
- int mMaxWords;
- int mMaxBigrams;
- int mMaxWordLength;
- unsigned short *mOutputChars;
- unsigned short *mBigramChars;
- int *mInputCodes;
- int mInputLength;
- int mMaxAlternatives;
- unsigned short mWord[128];
- int mSkipPos;
- int mMaxEditDistance;
-
- int mFullWordMultiplier;
- int mTypedLetterMultiplier;
- int *mNextLettersFrequencies;
- int mNextLettersSize;
- int mVersion;
- int mBigram;
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace latinime
-
-#endif // LATINIME_DICTIONARY_H
diff --git a/src/java/KP2ASoftKeyboard2/native/jni/keepass2android_softkeyboard_BinaryDictionary.cpp b/src/java/KP2ASoftKeyboard2/native/jni/keepass2android_softkeyboard_BinaryDictionary.cpp
deleted file mode 100644
index e5799130..00000000
--- a/src/java/KP2ASoftKeyboard2/native/jni/keepass2android_softkeyboard_BinaryDictionary.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** 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 "AS IS" 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.
-*/
-
-#include
-#include
-#include
-#include
-
-#include
-#include "dictionary.h"
-
-// ----------------------------------------------------------------------------
-
-using namespace latinime;
-
-//
-// helper function to throw an exception
-//
-static void throwException(JNIEnv *env, const char* ex, const char* fmt, int data)
-{
- if (jclass cls = env->FindClass(ex)) {
- char msg[1000];
- sprintf(msg, fmt, data);
- env->ThrowNew(cls, msg);
- env->DeleteLocalRef(cls);
- }
-}
-
-static jint latinime_BinaryDictionary_open
- (JNIEnv *env, jobject object, jobject dictDirectBuffer,
- jint typedLetterMultiplier, jint fullWordMultiplier)
-{
- void *dict = env->GetDirectBufferAddress(dictDirectBuffer);
- if (dict == NULL) {
- fprintf(stderr, "DICT: Dictionary buffer is null\n");
- return 0;
- }
- Dictionary *dictionary = new Dictionary(dict, typedLetterMultiplier, fullWordMultiplier);
- return (jint) dictionary;
-}
-
-static int latinime_BinaryDictionary_getSuggestions(
- JNIEnv *env, jobject object, jint dict, jintArray inputArray, jint arraySize,
- jcharArray outputArray, jintArray frequencyArray, jint maxWordLength, jint maxWords,
- jint maxAlternatives, jint skipPos, jintArray nextLettersArray, jint nextLettersSize)
-{
- Dictionary *dictionary = (Dictionary*) dict;
- if (dictionary == NULL) return 0;
-
- int *frequencies = env->GetIntArrayElements(frequencyArray, NULL);
- int *inputCodes = env->GetIntArrayElements(inputArray, NULL);
- jchar *outputChars = env->GetCharArrayElements(outputArray, NULL);
- int *nextLetters = nextLettersArray != NULL ? env->GetIntArrayElements(nextLettersArray, NULL)
- : NULL;
-
- int count = dictionary->getSuggestions(inputCodes, arraySize, (unsigned short*) outputChars,
- frequencies, maxWordLength, maxWords, maxAlternatives, skipPos, nextLetters,
- nextLettersSize);
-
- env->ReleaseIntArrayElements(frequencyArray, frequencies, 0);
- env->ReleaseIntArrayElements(inputArray, inputCodes, JNI_ABORT);
- env->ReleaseCharArrayElements(outputArray, outputChars, 0);
- if (nextLetters) {
- env->ReleaseIntArrayElements(nextLettersArray, nextLetters, 0);
- }
-
- return count;
-}
-
-static int latinime_BinaryDictionary_getBigrams
- (JNIEnv *env, jobject object, jint dict, jcharArray prevWordArray, jint prevWordLength,
- jintArray inputArray, jint inputArraySize, jcharArray outputArray,
- jintArray frequencyArray, jint maxWordLength, jint maxBigrams, jint maxAlternatives)
-{
- Dictionary *dictionary = (Dictionary*) dict;
- if (dictionary == NULL) return 0;
-
- jchar *prevWord = env->GetCharArrayElements(prevWordArray, NULL);
- int *inputCodes = env->GetIntArrayElements(inputArray, NULL);
- jchar *outputChars = env->GetCharArrayElements(outputArray, NULL);
- int *frequencies = env->GetIntArrayElements(frequencyArray, NULL);
-
- int count = dictionary->getBigrams((unsigned short*) prevWord, prevWordLength, inputCodes,
- inputArraySize, (unsigned short*) outputChars, frequencies, maxWordLength, maxBigrams,
- maxAlternatives);
-
- env->ReleaseCharArrayElements(prevWordArray, prevWord, JNI_ABORT);
- env->ReleaseIntArrayElements(inputArray, inputCodes, JNI_ABORT);
- env->ReleaseCharArrayElements(outputArray, outputChars, 0);
- env->ReleaseIntArrayElements(frequencyArray, frequencies, 0);
-
- return count;
-}
-
-
-static jboolean latinime_BinaryDictionary_isValidWord
- (JNIEnv *env, jobject object, jint dict, jcharArray wordArray, jint wordLength)
-{
- Dictionary *dictionary = (Dictionary*) dict;
- if (dictionary == NULL) return (jboolean) false;
-
- jchar *word = env->GetCharArrayElements(wordArray, NULL);
- jboolean result = dictionary->isValidWord((unsigned short*) word, wordLength);
- env->ReleaseCharArrayElements(wordArray, word, JNI_ABORT);
-
- return result;
-}
-
-static void latinime_BinaryDictionary_close
- (JNIEnv *env, jobject object, jint dict)
-{
- Dictionary *dictionary = (Dictionary*) dict;
- delete (Dictionary*) dict;
-}
-
-// ----------------------------------------------------------------------------
-
-static JNINativeMethod gMethods[] = {
- {"openNative", "(Ljava/nio/ByteBuffer;II)I",
- (void*)latinime_BinaryDictionary_open},
- {"closeNative", "(I)V", (void*)latinime_BinaryDictionary_close},
- {"getSuggestionsNative", "(I[II[C[IIIII[II)I", (void*)latinime_BinaryDictionary_getSuggestions},
- {"isValidWordNative", "(I[CI)Z", (void*)latinime_BinaryDictionary_isValidWord},
- {"getBigramsNative", "(I[CI[II[C[IIII)I", (void*)latinime_BinaryDictionary_getBigrams}
-};
-
-static int registerNativeMethods(JNIEnv* env, const char* className,
- JNINativeMethod* gMethods, int numMethods)
-{
- jclass clazz;
-
- clazz = env->FindClass(className);
- if (clazz == NULL) {
- fprintf(stderr,
- "Native registration unable to find class '%s'\n", className);
- return JNI_FALSE;
- }
- if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
- fprintf(stderr, "RegisterNatives failed for '%s'\n", className);
- return JNI_FALSE;
- }
-
- return JNI_TRUE;
-}
-
-static int registerNatives(JNIEnv *env)
-{
- const char* const kClassPathName = "keepass2android/softkeyboard/BinaryDictionary";
- return registerNativeMethods(env,
- kClassPathName, gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
-}
-
-/*
- * Returns the JNI version on success, -1 on failure.
- */
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
- JNIEnv* env = NULL;
- jint result = -1;
-
- if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
- fprintf(stderr, "ERROR: GetEnv failed\n");
- goto bail;
- }
- assert(env != NULL);
-
- if (!registerNatives(env)) {
- fprintf(stderr, "ERROR: BinaryDictionary native registration failed\n");
- goto bail;
- }
-
- /* success -- return valid version number */
- result = JNI_VERSION_1_4;
-
-bail:
- return result;
-}
diff --git a/src/java/KP2ASoftKeyboard2/native/libs/armeabi-v7a/libjni_latinime.so b/src/java/KP2ASoftKeyboard2/native/libs/armeabi-v7a/libjni_latinime.so
deleted file mode 100644
index fce10f89..00000000
Binary files a/src/java/KP2ASoftKeyboard2/native/libs/armeabi-v7a/libjni_latinime.so and /dev/null differ
diff --git a/src/java/KP2ASoftKeyboard2/native/libs/armeabi/libjni_latinime.so b/src/java/KP2ASoftKeyboard2/native/libs/armeabi/libjni_latinime.so
deleted file mode 100644
index 3f97a516..00000000
Binary files a/src/java/KP2ASoftKeyboard2/native/libs/armeabi/libjni_latinime.so and /dev/null differ
diff --git a/src/java/KP2ASoftKeyboard2/native/libs/x86/libjni_latinime.so b/src/java/KP2ASoftKeyboard2/native/libs/x86/libjni_latinime.so
deleted file mode 100644
index 7dc1bbe4..00000000
Binary files a/src/java/KP2ASoftKeyboard2/native/libs/x86/libjni_latinime.so and /dev/null differ
diff --git a/src/java/KP2ASoftkeyboard_AS/.idea/workspace.xml b/src/java/KP2ASoftkeyboard_AS/.idea/workspace.xml
index a86b6bf9..6b2bba03 100644
--- a/src/java/KP2ASoftkeyboard_AS/.idea/workspace.xml
+++ b/src/java/KP2ASoftkeyboard_AS/.idea/workspace.xml
@@ -1775,7 +1775,7 @@
-
+
diff --git a/src/java/PluginInputStick/.classpath b/src/java/PluginInputStick/.classpath
deleted file mode 100644
index 7bc01d9a..00000000
--- a/src/java/PluginInputStick/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/src/java/PluginInputStick/.project b/src/java/PluginInputStick/.project
deleted file mode 100644
index cca1dea2..00000000
--- a/src/java/PluginInputStick/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- PluginInputStick
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/src/java/PluginInputStick/.settings/org.eclipse.jdt.core.prefs b/src/java/PluginInputStick/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index b080d2dd..00000000
--- a/src/java/PluginInputStick/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/src/java/PluginInputStick/gen/keepass2android/plugin/inputstick/BuildConfig.java b/src/java/PluginInputStick/gen/keepass2android/plugin/inputstick/BuildConfig.java
deleted file mode 100644
index 0c6ce6d6..00000000
--- a/src/java/PluginInputStick/gen/keepass2android/plugin/inputstick/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package keepass2android.plugin.inputstick;
-
-public final class BuildConfig {
- public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/src/java/PluginInputStick/ic_launcher-web.png b/src/java/PluginInputStick/ic_launcher-web.png
deleted file mode 100644
index 69fadd12..00000000
Binary files a/src/java/PluginInputStick/ic_launcher-web.png and /dev/null differ
diff --git a/src/java/PluginInputStick/proguard-project.txt b/src/java/PluginInputStick/proguard-project.txt
deleted file mode 100644
index f2fe1559..00000000
--- a/src/java/PluginInputStick/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/src/java/PluginInputStick/project.properties b/src/java/PluginInputStick/project.properties
deleted file mode 100644
index 0206c251..00000000
--- a/src/java/PluginInputStick/project.properties
+++ /dev/null
@@ -1,16 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
-android.library.reference.1=../InputStickAPI
-android.library.reference.2=../Keepass2AndroidPluginSDK
diff --git a/src/java/PluginInputStick/res/layout/activity_quick_settings.xml b/src/java/PluginInputStick/res/layout/activity_quick_settings.xml
deleted file mode 100644
index dbf59b93..00000000
--- a/src/java/PluginInputStick/res/layout/activity_quick_settings.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/java/PluginInputStick/res/values-pl/strings.xml b/src/java/PluginInputStick/res/values-pl/strings.xml
deleted file mode 100644
index dc797d11..00000000
--- a/src/java/PluginInputStick/res/values-pl/strings.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- InputStick Plugin dla KP2A
- Ustawienia
- InputStick Plugin
- Pozwól na przesyłanie tekstu z KP2A do Twojego PC poprzez InputStick.
- Philipp Crocoll
-
- Włączony
-
- Wpisz
- Wpisz (powoli)
- Tab
- Enter
- Login/hasło
- Login/hasło/Enter
- Ustawienia
- OSX konfiguracja
- Maskowane hasło
-
- Wpisz maskowane hasło
- Plugin Init
- Plugin Configuration
- Poświęć moment na konfigurację pluginu.\n\Ustaw jako plugin-> Akceptuj\n\nUpewnij się, że wybrany układ klawiatury odpowiada układowi z którego korzysta host USB (Twój PC).\nWłącz dodatkowy układ klawiatury, jeżeli często korzystasz z różnych układów.\n\nWŁĄCZ automatyczne łączenie, jeżeli korzystasz z InputStick w większości przypadków. Aplikacja rozpocznie nawiązywanie połączenia z InputStick gdy tylko wpis zostanie otwarty.\nWYŁĄCZ automatyczne łączenie, jeżeli planujesz korzystać z InputStick okazjonalnie . Aplikacja nie będzie nawiązywać połączenia dopóki nie wybierzesz opcji wpisywania tekstu.\n\nPamiętaj: aplikacja InputStickUtility musi być zainstalowana.
- Historia zmian
- Ostatnie zmiany
- OK
- więcej…
- Konfiguracja Mac OSX
- Hello world!
-
- InputStick NIE jest gotowy!
-
- Pokaż hasło
- Wybrany układ klawiatury:
- Ważne: skorzystaj z tego ekranu, gdy OSX poprosi o naciśnięcie klawisza na prawo od lewego Shifta
-
-
diff --git a/src/java/PluginInputStick/res/values-pl/strings_activity_settings.xml b/src/java/PluginInputStick/res/values-pl/strings_activity_settings.xml
deleted file mode 100644
index 436807e0..00000000
--- a/src/java/PluginInputStick/res/values-pl/strings_activity_settings.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
- KP2A InputStick Ustawienia
-
-
- Ustaw jako plugin
-
- Pokaż zmiany
- Otwórz stronę z pomocą
-
- Układ klawiatury hosta USB
- Połączenie z InputStick
-
- Układ klawiatury (główny)
-
- Układ klawiatury (dodatkowy)
-
- Dodatkowy układ klawiatury
- Dodatkowy układ klawiatury jest włączony. Możesz wybrać jakie akcje będą dostępne dla tego układu (zobacz niżej)
- Dodatkowy układ klawiatury jest wyłączony
-
- Enter po URL
- Zawsze dodaj Enter po wpisaniu pola URL
- Nic nie rób po wpisaniu pola URL
-
- Łącz automatycznie
- Łącz z InputStick za każdym razem gdy otwierany jest wpis. Użyj tego trybu gdy korzystasz z InputStick przez większość czasu.
- Łącz z InputStick tuż przed wpisywaniem tekstu LUB gdy wpis otwierany jest w okresie \"Timeout\" (zobacz poniżej) od ostatniej akcji wpisywania tekstu. Użyj tego trybu gdy rzadko korzystasz z InputStick.
-
- Timeout
-
-
- Widoczne elementy interfejsu (Ogólne, zakres dla wpisu)
- Skrót: ustawienia
- Skrót: konfiguracja OSX
- Pozwala poprawnie zidentyfikować układ klawiatury na OSX
- Akcje: Tab i Enter
-
- Widoczne elementy interfejsu (Główny układ klawiatury, zakres dla wpisu)
- Widoczne elementy interfejsu (Dodatkowy układ klawiatury, zakres dla wpisu)
- Login/hasło
- Login/hasło/enter
- "Maskowane" hasło
-
- Widoczne elementy interfejsu (Główny układ klawiatury, zakres dla pola)
- Widoczne elementy interfejsu (Dodatkowy układ klawiatury, zakres dla pola)
- Wpisz
- Wpisz (powoli)
- Wpisywanie ze zredukowaną szybkością: 0.1x standardowej. Użyj gdy host USB nie akceptuje szybko wprowadzanego tekstu (np: BIOS)
-
-
-
- Szybkość wpisywania
-
- Utrzymuj połączenie
- Połaczenie NIE zostanie zakończone gdy wpis jest zamykany. Musisz zakończyć połączenie ręcznie lub ustawić maks okres bezczynności w aplikacji InputStickUtility
- Połaczenie zostanie zakończone gdy wpis jest zamykany.
-
-
- OK
- Ważne!
- Ustawienia elementów interfejsu będą widoczne dopiero po załadowaniu nowego wpisu
- Nie przypominaj
-
-
- - Brak
- - 1 min
- - 3 min
- - 10 min
- - 30 min
- - 60 min
-
-
-
- - Standardowa (1.0)
- - Wolno (0.5)
- - Wolniej (0.2)
- - Najwolniej (0.1)
-
-
-
- - Duński
- - Angielski (US)
- - Angielski (UK)
- - Fiński
- - Francuski
- - Francuski (Swiss)
- - Niemiecki
- - Niemiecki (Mac)
- - Niemiecki (Swiss)
- - Hebrajski
- - Włoski
- - Norweski
- - Polski
- - Portugalski (BR)
- - Rosyjski
- - Słowacki
- - Hiszpański
- - Szwedzki
- - Angielski (Dvorak)
-
-
-
-
-
diff --git a/src/java/PluginInputStick/res/values/strings.xml b/src/java/PluginInputStick/res/values/strings.xml
deleted file mode 100644
index 75b37bcd..00000000
--- a/src/java/PluginInputStick/res/values/strings.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- InputStick Plugin for KP2A
- Settings
- InputStick Plugin
- Allows to send text from KP2A via InputStick to your PC.
- Philipp Crocoll
-
- Enabled
-
- Type
- Type (slow)
- Tab
- Enter
- Username/password
- Username/password/Enter
- Settings
- OSX setup
- Masked Password
-
- Type Masked Password
- Plugin Init
- Plugin Configuration
- Please take a minute to configure the plugin.\n\nConfigure as plugin -> Accept\n\nMake sure that host keyboard layout matches the one used by USB host (your PC).\nEnable and set secondary layout if you work with different keyboard layouts.\n\nENABLE autoconnect if InputStick is used most of the time. Application will try to connect to InputStick every time entry is opened.\nDISABLE autoconnect when InputStick is used occasionally. Application will not connect unless you request typing.\n\nRemember: this plugin requires InputStickUtility app to be installed.
- Change Log
- What\'s New
- OK
- more…
- Mac OSX Setup
- Hello world!
-
- InputStick is NOT ready!
-
- Show password
- Selected keyboard layout:
- Note: use this screen when OSX "Keyboard Setup Assistant" asks you to: "Press the key immediatelly to the right of the Shift key on the left side of the keyboard that can't be identified"
-
-
diff --git a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/ActionReceiver.java b/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/ActionReceiver.java
deleted file mode 100644
index c158826e..00000000
--- a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/ActionReceiver.java
+++ /dev/null
@@ -1,327 +0,0 @@
-package keepass2android.plugin.inputstick;
-
-import keepass2android.pluginsdk.KeepassDefs;
-import keepass2android.pluginsdk.PluginAccessException;
-import keepass2android.pluginsdk.Strings;
-import sheetrock.panda.changelog.ChangeLog;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-
-public class ActionReceiver extends keepass2android.pluginsdk.PluginActionBroadcastReceiver {
-
- private static final String ACTION_MASKED_PASSWORD = "masked_password";
- private static final String ACTION_SETTINGS = "settings";
- private static final String ACTION_USER_PASS = "user_pass";
- private static final String ACTION_USER_PASS_ENTER = "user_pass_enter";
- private static final String ACTION_MAC_SETUP = "mac_setup";
-
- private static final int IC = R.drawable.ic_launcher;
-
- private static long lastTypingTime = 0;
- private static final long AUTOCONNECT_TIMEOUT = 600000; //10min,
-
- private static boolean enterAfterURL;
-
- @Override
- protected void openEntry(OpenEntryAction oe) {
- Context ctx = oe.getContext();
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
- try {
- enterAfterURL = prefs.getBoolean("enter_after_url", true);
- boolean showSecondary = prefs.getBoolean("show_secondary", false);
- String layoutPrimary = prefs.getString("kbd_layout", "en-US"); //layout code used when typing
- String layoutSecondary = prefs.getString("secondary_kbd_layout", "en-US");
-
- String layoutPrimaryDisplayCode = null; //only for displaying layout code
- String layoutSecondaryDisplayCode = null;
- if (showSecondary) {
- //display layout code only if secondary layout is enabled
- layoutPrimaryDisplayCode = layoutPrimary;
- layoutSecondaryDisplayCode = layoutSecondary;
- }
- Bundle b;
- String displayText;
-
- boolean showType = prefs.getBoolean("show_field_type", true);
- boolean showTypeSlow = prefs.getBoolean("show_field_type_slow", false);
- boolean showTypeSec = prefs.getBoolean("show_field_type_secondary", false);
- boolean showTypeSlowSec = prefs.getBoolean("show_field_type_slow_secondary", false);
- for (String field: oe.getEntryFields().keySet()) {
- if (showType) {
- displayText = getActionString(ctx, R.string.action_type, layoutPrimaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
- oe.addEntryFieldAction("keepass2android.plugin.inputstick.type", Strings.PREFIX_STRING + field, displayText, IC, b);
- }
- if (showTypeSlow) {
- displayText = getActionString(ctx, R.string.action_type_slow, layoutPrimaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
- b.putString(Const.EXTRA_PARAMS, Const.PARAM_SLOW_TYPING);
- oe.addEntryFieldAction("keepass2android.plugin.inputstick.typeslow", Strings.PREFIX_STRING + field, displayText, IC, b);
- }
-
- if (showSecondary) {
- if (showTypeSec) {
- displayText = getActionString(ctx, R.string.action_type, layoutSecondaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_LAYOUT, layoutSecondary);
- oe.addEntryFieldAction("keepass2android.plugin.inputstick.typesecondary", Strings.PREFIX_STRING + field, displayText, IC, b);
- }
- if (showTypeSlowSec) {
- displayText = getActionString(ctx, R.string.action_type_slow, layoutSecondaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_LAYOUT, layoutSecondary);
- b.putString(Const.EXTRA_PARAMS, Const.PARAM_SLOW_TYPING);
- oe.addEntryFieldAction("keepass2android.plugin.inputstick.typeslowsecondary", Strings.PREFIX_STRING + field, displayText, IC, b);
- }
- }
- }
-
-
-
-
- //GENERAL
- if (prefs.getBoolean("show_settings", true)) {
- b = new Bundle();
- b.putString(Const.EXTRA_TEXT, ACTION_SETTINGS);
- oe.addEntryAction(getActionString(ctx, R.string.action_open_settings, null, true), IC, b);
- }
-
- if (prefs.getBoolean("show_mac_setup", true)) {
- b = new Bundle();
- b.putString(Const.EXTRA_TEXT, ACTION_MAC_SETUP);
- oe.addEntryAction(getActionString(ctx, R.string.action_open_mac_setup, null, true), IC, b);
- }
- if (prefs.getBoolean("show_tab_enter", true)) {
- b = new Bundle();
- b.putString(Const.EXTRA_TEXT, "\t");
- oe.addEntryAction(getActionString(ctx, R.string.action_type_tab, null, true), IC, b);
- b = new Bundle();
- b.putString(Const.EXTRA_TEXT, "\n");
- oe.addEntryAction(getActionString(ctx, R.string.action_type_enter, null, true), IC, b);
- }
-
- //ENTRY SCOPE
- if (prefs.getBoolean("show_user_pass", true)) {
- displayText = getActionString(ctx, R.string.action_type_user_tab_pass, layoutPrimaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_TEXT, ACTION_USER_PASS);
- b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
- oe.addEntryAction(displayText, IC, b);
- }
- if (prefs.getBoolean("show_user_pass_enter", true)) {
- displayText = getActionString(ctx, R.string.action_type_user_tab_pass_enter, layoutPrimaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_TEXT, ACTION_USER_PASS_ENTER);
- b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
- oe.addEntryAction(displayText, IC, b);
- }
- if (prefs.getBoolean("show_masked", true)) {
- displayText = getActionString(ctx, R.string.action_masked_password, layoutPrimaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_TEXT, ACTION_MASKED_PASSWORD);
- b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
- oe.addEntryAction(displayText, IC, b);
- }
-
- if (showSecondary) {
- if (prefs.getBoolean("show_user_pass_secondary", true)) {
- displayText = getActionString(ctx, R.string.action_type_user_tab_pass, layoutSecondaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_TEXT, ACTION_USER_PASS);
- b.putString(Const.EXTRA_LAYOUT, layoutSecondary);
- oe.addEntryAction(displayText, IC, b);
- }
- if (prefs.getBoolean("show_user_pass_enter_secondary", false)) {
- displayText = getActionString(ctx, R.string.action_type_user_tab_pass_enter, layoutSecondaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_TEXT, ACTION_USER_PASS_ENTER);
- b.putString(Const.EXTRA_LAYOUT, layoutSecondary);
- oe.addEntryAction(displayText, IC, b);
- }
- if (prefs.getBoolean("show_masked_secondary", false)) {
- displayText = getActionString(ctx, R.string.action_masked_password, layoutSecondaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_TEXT, ACTION_MASKED_PASSWORD);
- b.putString(Const.EXTRA_LAYOUT, layoutSecondary);
- oe.addEntryAction(displayText, IC, b);
- }
- }
- } catch (PluginAccessException e) {
- e.printStackTrace();
- }
-
- if (prefs.getBoolean("autoconnect", true)) {
- typeText(ctx, "", "en-US");
- } else {
- int autoconnectTimeout = (int)AUTOCONNECT_TIMEOUT;
- try {
- autoconnectTimeout = Integer.parseInt(prefs.getString("autoconnect_timeout", "600000"));
- } catch (Exception e) {
- autoconnectTimeout = (int)AUTOCONNECT_TIMEOUT;
- }
-
- if ((lastTypingTime != 0) && ((System.currentTimeMillis() - autoconnectTimeout) < lastTypingTime)) {
- //System.out.println("AUTOCONNECT (NO TIMEOUT)");
- typeText(ctx, "", "en-US");
- }
- }
-
- ChangeLog cl = new ChangeLog(ctx.getApplicationContext());
- if (cl.firstRun()) {
- Intent i = new Intent(ctx.getApplicationContext(), SettingsActivity.class);
- i.putExtra(Const.EXTRA_CHANGELOG, true);
- i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
- ctx.getApplicationContext().startActivity(i);
- }
- }
-
- private String getActionString(Context ctx, int id, String layoutCode, boolean addInputStickInfo) {
- String s = ctx.getString(id);
- if (layoutCode != null) {
- s += " (" + layoutCode + ")";
- }
- if (addInputStickInfo) {
- s += " (InputStick)";
- }
- return s;
- }
-
- @Override
- protected void closeEntryView(CloseEntryViewAction closeEntryView) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(closeEntryView.getContext());
- boolean doNotDisconnect = prefs.getBoolean("do_not_disconnect", false);
- if ( !doNotDisconnect) {
- Intent serviceIntent = new Intent(closeEntryView.getContext(), InputStickService.class);
- serviceIntent.setAction(InputStickService.DISCONNECT);
- closeEntryView.getContext().startService(serviceIntent);
- }
- };
-
- @Override
- protected void actionSelected(ActionSelectedAction actionSelected) {
- Context ctx = actionSelected.getContext();
- String layoutName = actionSelected.getActionData().getString(Const.EXTRA_LAYOUT, "en-US");
- String params = actionSelected.getActionData().getString(Const.EXTRA_PARAMS, null);
-
- if (actionSelected.isEntryAction()) {
- String text = actionSelected.getActionData().getString(Const.EXTRA_TEXT);
-
- if (ACTION_MASKED_PASSWORD.equals(text)) {
- typeText(ctx, "", "en-US"); //will connect if not already connected
- Intent i = new Intent(ctx.getApplicationContext(), MaskedPasswordActivity.class);
- i.putExtra(Const.EXTRA_TEXT, actionSelected.getEntryFields().get(KeepassDefs.PasswordField));
- i.putExtra(Const.EXTRA_LAYOUT, layoutName);
- i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
- ctx.getApplicationContext().startActivity(i);
- } else if (ACTION_SETTINGS.equals(text)) {
- Intent i = new Intent(ctx.getApplicationContext(), SettingsActivity.class);
- i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
- ctx.getApplicationContext().startActivity(i);
- } else if (ACTION_USER_PASS.equals(text)) {
- typeText(ctx, actionSelected.getEntryFields().get(KeepassDefs.UserNameField), layoutName);
- typeText(ctx, "\t", layoutName);
- typeText(ctx, actionSelected.getEntryFields().get(KeepassDefs.PasswordField), layoutName);
- } else if (ACTION_USER_PASS_ENTER.equals(text)) {
- typeText(ctx, actionSelected.getEntryFields().get(KeepassDefs.UserNameField), layoutName);
- typeText(ctx, "\t", layoutName);
- typeText(ctx, actionSelected.getEntryFields().get(KeepassDefs.PasswordField), layoutName);
- typeText(ctx, "\n", layoutName);
- } else if (ACTION_MAC_SETUP.equals(text)) {
- typeText(ctx, "", "en-US"); //will connect if not already connected
- Intent i = new Intent(ctx.getApplicationContext(), MacSetupActivity.class);
- i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
- ctx.getApplicationContext().startActivity(i);
- } else {
- typeText(ctx, text, layoutName);
- }
- } else {
- String fieldKey = actionSelected.getFieldId().substring(Strings.PREFIX_STRING.length());
- String text = actionSelected.getEntryFields().get(fieldKey);
- typeText(ctx, text, layoutName, params);
-
- if ((enterAfterURL) && ("URL".equals(fieldKey))) {
- typeText(ctx, "\n", layoutName, params);
- }
- }
- }
-
- private void typeText(Context ctx, String text, String layout) {
- typeText(ctx, text, layout, null);
- }
-
- private void typeText(Context ctx, String text, String layout, String params) {
- if ( !("".equals(text))) { //only if text is actually being typed
- lastTypingTime = System.currentTimeMillis();
- }
- Intent serviceIntent = new Intent(ctx, InputStickService.class);
- serviceIntent.setAction(InputStickService.TYPE);
- Bundle b = new Bundle();
- b.putString(Const.EXTRA_TEXT, text);
- b.putString(Const.EXTRA_LAYOUT, layout);
- b.putString(Const.EXTRA_PARAMS, params);
- serviceIntent.putExtras(b);
- ctx.startService(serviceIntent);
- }
-
-
- @Override
- protected void entryOutputModified(EntryOutputModifiedAction eom) {
- Context ctx = eom.getContext();
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
- try {
- boolean showSecondary = prefs.getBoolean("show_secondary", false);
- String layoutPrimary = prefs.getString("kbd_layout", "en-US");
- String layoutSecondary = prefs.getString("secondary_kbd_layout", "en-US");
-
- String layoutPrimaryDisplayCode = null; //only for displaying layout code
- String layoutSecondaryDisplayCode = null;
- if (showSecondary) {
- //display layout code only if secondary layout is enabled
- layoutPrimaryDisplayCode = layoutPrimary;
- layoutSecondaryDisplayCode = layoutSecondary;
- }
-
- Bundle b;
- String displayText;
-
- if (prefs.getBoolean("show_field_type", true)) {
- displayText = getActionString(ctx, R.string.action_type, layoutPrimaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
- eom.addEntryFieldAction("keepass2android.plugin.inputstick.type", eom.getModifiedFieldId(), displayText, IC, b);
- }
-
- if (prefs.getBoolean("show_field_type_slow", false)) {
- displayText = getActionString(ctx, R.string.action_type_slow, layoutPrimaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
- b.putString(Const.EXTRA_PARAMS, Const.PARAM_SLOW_TYPING);
- eom.addEntryFieldAction("keepass2android.plugin.inputstick.typeslow", eom.getModifiedFieldId(), displayText, IC, b);
- }
-
- if (showSecondary) {
- if (prefs.getBoolean("show_field_type_secondary", false)) {
- displayText = getActionString(ctx, R.string.action_type, layoutSecondaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_LAYOUT, layoutSecondary);
- eom.addEntryFieldAction("keepass2android.plugin.inputstick.typesecondary", eom.getModifiedFieldId(), displayText, IC, b);
- }
- if (prefs.getBoolean("show_field_type_slow_secondary", false)) {
- displayText = getActionString(ctx, R.string.action_type, layoutSecondaryDisplayCode, true);
- b = new Bundle();
- b.putString(Const.EXTRA_LAYOUT, layoutSecondary);
- b.putString(Const.EXTRA_PARAMS, Const.PARAM_SLOW_TYPING);
- eom.addEntryFieldAction("keepass2android.plugin.inputstick.typeslowsecondary", eom.getModifiedFieldId(), displayText, IC, b);
- }
- }
- } catch (PluginAccessException e) {
- e.printStackTrace();
- }
- }
-
-}
diff --git a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/Const.java b/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/Const.java
deleted file mode 100644
index 39815315..00000000
--- a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/Const.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package keepass2android.plugin.inputstick;
-
-
-public class Const {
-
- public static final String EXTRA_TEXT = "text";
- public static final String EXTRA_LAYOUT = "layout";
- public static final String EXTRA_PARAMS = "params";
- public static final String EXTRA_CHANGELOG = "changelog";
-
- public static final String PARAM_SLOW_TYPING = "%s";
-
-}
diff --git a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/InputStickService.java b/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/InputStickService.java
deleted file mode 100644
index 93ecfb95..00000000
--- a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/InputStickService.java
+++ /dev/null
@@ -1,222 +0,0 @@
-package keepass2android.plugin.inputstick;
-
-import java.util.ArrayList;
-
-import android.app.AlertDialog;
-import android.app.Service;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.AsyncTask;
-import android.os.IBinder;
-import android.preference.PreferenceManager;
-import android.util.Log;
-import android.widget.Toast;
-
-import com.inputstick.api.ConnectionManager;
-import com.inputstick.api.InputStickStateListener;
-import com.inputstick.api.basic.InputStickHID;
-import com.inputstick.api.basic.InputStickKeyboard;
-import com.inputstick.api.hid.HIDKeycodes;
-import com.inputstick.api.layout.KeyboardLayout;
-
-public class InputStickService extends Service implements InputStickStateListener {
-
- private class ItemToType {
- public String mText;
- public String mLayout;
- public String mParams;
-
- ItemToType(String text, String layout, String params) {
- mText = text;
- mLayout = layout;
- mParams = params;
- }
-
- public void type() {
- typeString(mText, mLayout, mParams);
- }
- }
-
- private ArrayList items = new ArrayList();
-
- private static final String _TAG = "KP2AINPUTSTICK";
- public static final String DISCONNECT = "disconnect";
- public static final String TYPE = "type";
-
- @Override
- public void onCreate() {
- InputStickHID.addStateListener(this);
- super.onCreate();
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
-
- if (intent != null)
- Log.d(_TAG, "starting with "+intent.getAction());
- else
- Log.d(_TAG, "starting with null intent");
-
- if (DISCONNECT.equals(intent.getAction())) {
- Log.d(_TAG, "disconnecting");
- try {
- int state = InputStickHID.getState();
- switch (state) {
- case ConnectionManager.STATE_CONNECTED:
- case ConnectionManager.STATE_CONNECTING:
- case ConnectionManager.STATE_READY:
- InputStickHID.disconnect();
- break;
- case ConnectionManager.STATE_DISCONNECTED:
- case ConnectionManager.STATE_FAILURE:
- break;
- default:
- InputStickHID.disconnect();
- }
- } catch (NullPointerException e) {
- Log.d(_TAG, "couldn't disconnect. Probably we never connected.");
- }
-
- stopSelf();
- return Service.START_NOT_STICKY;
- }
-
- if (TYPE.equals(intent.getAction())) {
- int state = InputStickHID.getState();
- String stringToType = intent.getStringExtra(Const.EXTRA_TEXT);
- String layoutToUse = intent.getStringExtra(Const.EXTRA_LAYOUT);
- String params = intent.getStringExtra(Const.EXTRA_PARAMS);
- //Toast.makeText(this, "type params: "+params, Toast.LENGTH_LONG).show();
- //Log.d(_TAG, "type params: "+params);
-
- switch (state) {
- case ConnectionManager.STATE_CONNECTED:
- case ConnectionManager.STATE_CONNECTING:
- synchronized (items) {
- items.add(new ItemToType(stringToType, layoutToUse, params));
- }
- break;
- case ConnectionManager.STATE_READY:
- typeString(stringToType, layoutToUse, params);
- break;
- case ConnectionManager.STATE_DISCONNECTED:
- case ConnectionManager.STATE_FAILURE:
- synchronized (items) {
- items.add(new ItemToType(stringToType, layoutToUse, params));
- }
- Log.d(_TAG, "trigger connect");
- InputStickHID.connect(getApplication());
-
- break;
- }
- }
- return Service.START_NOT_STICKY;
-
- }
-
- private void typeString(String stringToType, String layoutToUse, String params) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- int reportMultiplier = 1;
- try {
- reportMultiplier = Integer.parseInt(prefs.getString("typing_speed", "1"));
- } catch (Exception e) {
- reportMultiplier = 1;
- }
-
- if (params != null) {
- //override typing speed
- if (params.contains(Const.PARAM_SLOW_TYPING)) {
- reportMultiplier = 10;
- }
- }
-
- InputStickHID.setKeyboardReportMultiplier(reportMultiplier);
-
- if (InputStickHID.getState() == ConnectionManager.STATE_READY) {
- //Log.d(_TAG, "typing "+stringToType + " @ " + layoutToUse + " @mul: " + reportMultiplier);
- if (stringToType.equals("\n")) {
- InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER);
- return;
- } else if (stringToType.equals("\t")) {
- InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_TAB);
- return;
- } else {
- KeyboardLayout l = KeyboardLayout.getLayout(layoutToUse);
- l.type(stringToType);
- }
- } else {
- Log.d(_TAG, "typing NOT READY");
- }
- InputStickHID.setKeyboardReportMultiplier(1);
- }
-
- private void typeQueue() {
- synchronized (items) {
- for (ItemToType itt : items)
- {
- Log.d(_TAG, "typing (after callback) " + itt.mText);
- itt.type();
- }
- items.clear();
- }
- }
-
- @Override
- public IBinder onBind(Intent arg0) {
- return null;
- }
-
- @Override
- public void onDestroy() {
- InputStickHID.removeStateListener(this);
- super.onDestroy();
- }
-
- @Override
- public void onStateChanged(int state) {
- Log.d(_TAG, "state changed: "+state);
- switch (state) {
- case ConnectionManager.STATE_READY:
- /*
- Intent typeQueue = new Intent(this, InputStickService.class);
- typeQueue.setAction(TYPE_QUEUE);
- startService(typeQueue);
- */
- new AsyncTask