diff --git a/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/cache.properties b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/cache.properties new file mode 100644 index 00000000..c77eabac --- /dev/null +++ b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/cache.properties @@ -0,0 +1 @@ +#Wed Jan 27 05:35:46 CET 2016 diff --git a/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/cache.properties.lock b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/cache.properties.lock new file mode 100644 index 00000000..e858d1c1 Binary files /dev/null and b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/cache.properties.lock differ diff --git a/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/fileHashes.bin b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/fileHashes.bin new file mode 100644 index 00000000..07c09264 Binary files /dev/null and b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/fileHashes.bin differ diff --git a/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin new file mode 100644 index 00000000..4331fd9a Binary files /dev/null and b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin differ diff --git a/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/outputFileStates.bin b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/outputFileStates.bin new file mode 100644 index 00000000..c153f916 Binary files /dev/null and b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/outputFileStates.bin differ diff --git a/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin new file mode 100644 index 00000000..f2b357cc Binary files /dev/null and b/src/java/InputStickAPI/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin differ diff --git a/src/java/InputStickAPI/app/build.gradle b/src/java/InputStickAPI/app/build.gradle new file mode 100644 index 00000000..d8f9011c --- /dev/null +++ b/src/java/InputStickAPI/app/build.gradle @@ -0,0 +1,23 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 19 + buildToolsVersion "23.0.0" + + defaultConfig { + minSdkVersion 9 + targetSdkVersion 19 + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } +} + +dependencies { + compile 'com.android.support:support-v4:19.1.0' + compile 'com.android.support:appcompat-v7:19.1.0' +} diff --git a/src/java/InputStickAPI/app/src/main/AndroidManifest.xml b/src/java/InputStickAPI/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..1f241d8d --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/AES.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/AES.java new file mode 100644 index 00000000..e07cadb2 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/AES.java @@ -0,0 +1,57 @@ +package com.inputstick.api; + +import java.security.MessageDigest; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public class AES { + + private Cipher mCipherEncr; + private Cipher mCipherDecr; + private SecretKeySpec mKey; + private boolean ready; + + public AES() { + ready = false; + } + + public static byte[] getMD5(String s) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + return md.digest(s.getBytes("UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public byte[] init(byte[] key) { + byte[] iv = null; + try { + mKey = new SecretKeySpec(key, "AES"); + mCipherEncr = Cipher.getInstance("AES/CBC/NoPadding"); + mCipherEncr.init(Cipher.ENCRYPT_MODE, mKey); + iv = mCipherEncr.getIV(); + Util.printHex(iv, "AES IV: "); + mCipherDecr = Cipher.getInstance("AES/CBC/NoPadding"); + mCipherDecr.init(Cipher.DECRYPT_MODE, mKey, new IvParameterSpec(iv)); + ready = true; + } catch (Exception e) { + e.printStackTrace(); + } + return iv; + } + + public byte[] encrypt(byte[] data) { + return mCipherEncr.update(data); + } + + public byte[] decrypt(byte[] data) { + return mCipherDecr.update(data); + } + + public boolean isReady() { + return ready; + } +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/BTConnectionManager.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/BTConnectionManager.java new file mode 100644 index 00000000..9c818ec8 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/BTConnectionManager.java @@ -0,0 +1,159 @@ +package com.inputstick.api; + +import java.lang.ref.WeakReference; + +import android.app.Application; +import android.os.Handler; +import android.os.Message; + +import com.inputstick.api.bluetooth.BTService; +import com.inputstick.api.init.InitManager; +import com.inputstick.api.init.InitManagerListener; + +public class BTConnectionManager extends ConnectionManager implements InitManagerListener { + + //private static final String mTag = "BTConnectionManager"; + + private String mMac; + private byte[] mKey; + private boolean mIsBT40; + + private InitManager mInitManager; + private Application mApp; + protected BTService mBTService; + private PacketManager mPacketManager; + private final BTHandler mBTHandler = new BTHandler(this); + + + + private static class BTHandler extends Handler { + private final WeakReference ref; + + BTHandler(BTConnectionManager manager) { + ref = new WeakReference(manager); + } + + @Override + public void handleMessage(Message msg) { + BTConnectionManager manager = ref.get(); + switch (msg.what) { + case BTService.EVENT_DATA: + manager.onData((byte[])msg.obj); + break; + case BTService.EVENT_CONNECTED: + manager.onConnected(); + break; + case BTService.EVENT_CANCELLED: + manager.onDisconnected(); + break; + case BTService.EVENT_ERROR: + manager.onFailure(msg.arg1); + break; + default: + manager.onFailure(InputStickError.ERROR_BLUETOOTH); + } + } + } + + private void onConnecting() { + stateNotify(ConnectionManager.STATE_CONNECTING); + } + + private void onConnected() { + stateNotify(ConnectionManager.STATE_CONNECTED); + //mInitManager.startTimeoutCountdown(InitManager.DEFAULT_INIT_TIMEOUT); + mInitManager.onConnected(); + } + + private void onDisconnected() { + stateNotify(ConnectionManager.STATE_DISCONNECTED); + mInitManager.onDisconnected(); + } + + private void onFailure(int code) { + mErrorCode = code; + stateNotify(ConnectionManager.STATE_FAILURE); + disconnect(); + } + + @Override + protected void onData(byte[] rawData) { + byte[] data; + data = mPacketManager.bytesToPacket(rawData); + if (data == null) { + //TODO failure? + return; + } + + mInitManager.onData(data); + super.onData(data); + } + + public BTConnectionManager(InitManager initManager, Application app, String mac, byte[] key, boolean isBT40) { + mInitManager = initManager; + mMac = mac; + mKey = key; + mApp = app; + mIsBT40 = isBT40; + } + + public BTConnectionManager(InitManager initManager, Application app, String mac, byte[] key) { + this(initManager, app, mac, key, false); + } + + @Override + public void connect() { + connect(false, BTService.DEFAULT_CONNECT_TIMEOUT); + } + + public void connect(boolean reflection, int timeout, boolean doNotAsk) { + mErrorCode = InputStickError.ERROR_NONE; + if (mBTService == null) { + mBTService = new BTService(mApp, mBTHandler); + mPacketManager = new PacketManager(mBTService, mKey); + mInitManager.init(this, mPacketManager); + } + mBTService.setConnectTimeout(timeout); + mBTService.enableReflection(reflection); + mBTService.connect(mMac, doNotAsk, mIsBT40); + onConnecting(); + } + + public void connect(boolean reflection, int timeout) { + connect(reflection, timeout, false); + } + + @Override + public void disconnect() { + if (mBTService != null) { + mBTService.disconnect(); + } + } + + public void disconnect(int failureCode) { + onFailure(failureCode); + } + + + @Override + public void sendPacket(Packet p) { + mPacketManager.sendPacket(p); + } + + + @Override + public void onInitReady() { + stateNotify(ConnectionManager.STATE_READY); + } + + @Override + public void onInitNotReady() { + stateNotify(ConnectionManager.STATE_CONNECTED); + } + + @Override + public void onInitFailure(int code) { + onFailure(code); + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/ConnectionManager.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/ConnectionManager.java new file mode 100644 index 00000000..82f7cc67 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/ConnectionManager.java @@ -0,0 +1,99 @@ +package com.inputstick.api; + +import java.util.Vector; + +public abstract class ConnectionManager { + + public static final int STATE_DISCONNECTED = 0; + public static final int STATE_FAILURE = 1; + public static final int STATE_CONNECTING = 2; + public static final int STATE_CONNECTED = 3; + public static final int STATE_READY = 4; + + + protected Vector mStateListeners = new Vector(); + protected Vector mDataListeners = new Vector(); + + protected int mState; + protected int mErrorCode; + + public abstract void connect(); + public abstract void disconnect(); + public abstract void sendPacket(Packet p); + + protected void stateNotify(int state) { + stateNotify(state, false); + } + + protected void stateNotify(int state, boolean forceNotification) { + if (( !forceNotification) && (mState == state )) { + //do nothing + } else { + //notify all listeners + mState = state; + for (InputStickStateListener listener : mStateListeners) { + listener.onStateChanged(state); + } + } + } + + public int getState() { + return mState; + } + + public boolean isReady() { + if (mState == STATE_READY) { + return true; + } else { + return false; + } + } + + public boolean isConnected() { + if ((mState == STATE_READY) || (mState == STATE_CONNECTED)) { + return true; + } else { + return false; + } + } + + public int getErrorCode() { + return mErrorCode; + } + + + protected void onData(byte[] data) { + for (InputStickDataListener listener : mDataListeners) { + listener.onInputStickData(data); + } + } + + public void addStateListener(InputStickStateListener listener) { + if (listener != null) { + if ( !mStateListeners.contains(listener)) { + mStateListeners.add(listener); + } + } + } + + public void removeStateListener(InputStickStateListener listener) { + if (listener != null) { + mStateListeners.remove(listener); + } + } + + public void addDataListener(InputStickDataListener listener) { + if (listener != null) { + if ( !mDataListeners.contains(listener)) { + mDataListeners.add(listener); + } + } + } + + public void removeDataListener(InputStickDataListener listener) { + if (listener != null) { + mDataListeners.remove(listener); + } + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/DownloadDialog.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/DownloadDialog.java new file mode 100644 index 00000000..423d205b --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/DownloadDialog.java @@ -0,0 +1,53 @@ +package com.inputstick.api; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; + +public class DownloadDialog { + + public static final int NOT_INSTALLED = 0; + public static final int NOT_UPDATED = 1; + + + public static AlertDialog getDialog(final Context ctx, final int messageCode) { + AlertDialog.Builder downloadDialog = new AlertDialog.Builder(ctx); + + if (messageCode == NOT_UPDATED) { + downloadDialog.setTitle("InputStickUtility app must be updated"); + downloadDialog.setMessage("It appears that you are using older version of InputStickUtility application. Update now (GoolePlay)?"); + } else { + downloadDialog.setTitle("InputStickUtility app NOT installed"); + downloadDialog.setMessage("InputStickUtility is required to complete this action. Download now (GoolePlay)?\nNote: InputStick USB receiver (HARDWARE!) is also required."); + } + downloadDialog.setPositiveButton("Yes", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + final String appPackageName = "com.inputstick.apps.inputstickutility"; + try { + ctx.startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("market://details?id=" + + appPackageName))); + } catch (android.content.ActivityNotFoundException anfe) { + ctx.startActivity(new Intent( + Intent.ACTION_VIEW, + Uri.parse("http://play.google.com/store/apps/details?id=" + + appPackageName))); + } + } + }); + downloadDialog.setNegativeButton("No", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + } + }); + return downloadDialog.show(); + } + + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/HIDInfo.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/HIDInfo.java new file mode 100644 index 00000000..908e4e11 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/HIDInfo.java @@ -0,0 +1,149 @@ +package com.inputstick.api; + +public class HIDInfo { + + private int state; + + private boolean numLock; + private boolean capsLock; + private boolean scrollLock; + + private boolean keyboardReportProtocol; + private boolean mouseReportProtocol; + + private boolean keyboardReady; + private boolean mouseReady; + private boolean consumerReady; + + // >= 0.93 + private boolean sentToHostInfo; + private int keyboardReportsSentToHost; + private int mouseReportsSentToHost; + private int consumerReportsSentToHost; + + public HIDInfo() { + keyboardReportProtocol = true; + mouseReportProtocol = true; + sentToHostInfo = false; + } + + public void update(byte[] data) { + state = data[1]; + + int leds = data[2]; + if ((leds & 0x01) != 0) { + numLock = true; + } else { + numLock = false; + } + if ((leds & 0x02) != 0) { + capsLock = true; + } else { + capsLock = false; + } + if ((leds & 0x04) != 0) { + scrollLock = true; + } else { + scrollLock = false; + } + + if (data[3] == 0) { + keyboardReportProtocol = true; + } else { + keyboardReportProtocol = false; + } + + if (data[4] == 0) { + keyboardReady = false; + } else { + keyboardReady = true; + } + + if (data[5] == 0) { + mouseReportProtocol = true; + } else { + mouseReportProtocol = false; + } + + if (data[6] == 0) { + mouseReady = false; + } else { + mouseReady = true; + } + + if (data[7] == 0) { + consumerReady = false; + } else { + consumerReady = true; + } + if (data.length >= 12) { + if (data[11] == (byte)0xFF) { + sentToHostInfo = true; + keyboardReportsSentToHost = data[8] & 0xFF; + mouseReportsSentToHost = data[9] & 0xFF; + consumerReportsSentToHost = data[10] & 0xFF; + } + } + } + + public void setKeyboardBusy() { + keyboardReady = false; + } + + public int getState() { + return state; + } + + public boolean getNumLock() { + return numLock; + } + + public boolean getCapsLock() { + return capsLock; + } + + public boolean getScrollLock() { + return scrollLock; + } + + public boolean isKeyboardReportProtocol() { + return keyboardReportProtocol; + } + + public boolean isMouseReportProtocol() { + return mouseReportProtocol; + } + + public boolean isKeyboardReady() { + return keyboardReady; + } + + public boolean isMouseReady() { + return mouseReady; + } + + public boolean isConsumerReady() { + return consumerReady; + } + + + + // > v0.93 firmware only + + public boolean isSentToHostInfoAvailable() { + return sentToHostInfo; + } + + public int getKeyboardReportsSentToHost() { + return keyboardReportsSentToHost; + } + + public int getMouseReportsSentToHost() { + return mouseReportsSentToHost; + } + + public int getConsumerReportsSentToHost() { + return consumerReportsSentToHost; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/IPCConnectionManager.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/IPCConnectionManager.java new file mode 100644 index 00000000..1d459727 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/IPCConnectionManager.java @@ -0,0 +1,180 @@ +package com.inputstick.api; + +import java.lang.ref.WeakReference; + +import android.app.Application; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; + +public class IPCConnectionManager extends ConnectionManager { + + //private static final String mTag = "IPCConnectionManager"; + + public static final int SERVICE_CMD_CONNECT = 1; + public static final int SERVICE_CMD_DISCONNECT = 2; + public static final int SERVICE_CMD_DATA = 3; + public static final int SERVICE_CMD_STATE = 4; + + Context mCtx; + Messenger mService = null; + boolean mBound; + boolean initSent; + final Messenger mMessenger = new Messenger(new IncomingHandler(this)); + + private static class IncomingHandler extends Handler { + private final WeakReference ref; + + IncomingHandler(IPCConnectionManager manager) { + ref = new WeakReference(manager); + } + + @Override + public void handleMessage(Message msg) { + if (ref == null) return; + IPCConnectionManager manager = ref.get(); + if (manager != null) { + switch (msg.what) { + case SERVICE_CMD_DATA: + byte[] data = null; + Bundle b = msg.getData(); + if (b != null) { + data = b.getByteArray("data"); + manager.onData(data); + } + break; + case SERVICE_CMD_STATE: + manager.stateNotify(msg.arg1); + break; + } + } + } + } + + private ServiceConnection mConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, IBinder service) { + mService = new Messenger(service); + mBound = true; + sendConnectMessage(); + } + + public void onServiceDisconnected(ComponentName className) { + // unexpectedly disconnected from service + mService = null; + mBound = false; + mErrorCode = InputStickError.ERROR_ANDROID_SERVICE_DISCONNECTED; + stateNotify(STATE_FAILURE); + stateNotify(STATE_DISCONNECTED); + } + }; + //SERVICE========================================================= + + + + + + private void sendConnectMessage() { + Bundle b = new Bundle(); + b.putLong("TIME", System.currentTimeMillis()); + sendMessage(SERVICE_CMD_CONNECT, 0, 0, b); + } + + + private void sendMessage(int what, int arg1, int arg2, Bundle b) { + Message msg; + try { + msg = Message.obtain(null, what, arg1, 0, null); + msg.replyTo = mMessenger; + msg.setData(b); + mService.send(msg); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void sendMessage(int what, int arg1, int arg2, byte[] data) { + Bundle b; + b = new Bundle(); + b.putByteArray("data", data); + sendMessage(what, arg1, arg2, b); + } + + private void sendMessage(int what, int arg1, int arg2) { + sendMessage(what, arg1, arg2, (Bundle)null); + } + + @Override + protected void onData(byte[] data) { + super.onData(data); + } + + + public IPCConnectionManager(Application app) { + mCtx = app.getApplicationContext(); + } + + @Override + public void connect() { + PackageManager pm = mCtx.getPackageManager(); + boolean exists = true; + try { + pm.getPackageInfo("com.inputstick.apps.inputstickutility", PackageManager.GET_META_DATA); + } catch (NameNotFoundException e) { + exists = false; + } + + if (exists) { + mErrorCode = InputStickError.ERROR_NONE; + Intent intent = new Intent(); + intent.setComponent(new ComponentName("com.inputstick.apps.inputstickutility","com.inputstick.apps.inputstickutility.service.InputStickService")); + intent.putExtra("TIME", System.currentTimeMillis()); + mCtx.startService(intent); + mCtx.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + if (mBound) { + //already bound + sendConnectMessage(); + } + } else { + mErrorCode = InputStickError.ERROR_ANDROID_NO_UTILITY_APP; + stateNotify(STATE_FAILURE); + stateNotify(STATE_DISCONNECTED); + } + } + + @Override + public void disconnect() { + if (mBound) { + sendMessage(SERVICE_CMD_DISCONNECT, 0, 0); + Intent intent = new Intent(); + intent.setComponent(new ComponentName("com.inputstick.apps.inputstickutility","com.inputstick.apps.inputstickutility.service.InputStickService")); + mCtx.unbindService(mConnection); + mCtx.stopService(intent); + mBound = false; + //service will pass notification message (disconnected) + } else { + //just set state, there is nothing else to do + stateNotify(STATE_DISCONNECTED); + } + } + + @Override + public void sendPacket(Packet p) { + if ((mState == ConnectionManager.STATE_READY) || (mState == ConnectionManager.STATE_CONNECTED)) { + if (p.getRespond()) { + sendMessage(IPCConnectionManager.SERVICE_CMD_DATA, 1, 0, p.getBytes()); + } else { + sendMessage(IPCConnectionManager.SERVICE_CMD_DATA, 0, 0, p.getBytes()); + } + } + } + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickDataListener.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickDataListener.java new file mode 100644 index 00000000..1496db85 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickDataListener.java @@ -0,0 +1,7 @@ +package com.inputstick.api; + +public interface InputStickDataListener { + + public void onInputStickData(byte[] data); + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickError.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickError.java new file mode 100644 index 00000000..d9bbbc6f --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickError.java @@ -0,0 +1,144 @@ +package com.inputstick.api; + +import android.util.SparseArray; + +public class InputStickError { + + public static String ERROR_UNKNOWN_MSG = "Unknown"; + + public static final int ERROR_NONE = 0; + public static final int ERROR_UNKNOWN = 1; + + //Bluetooth comm errors: + public static final int ERROR_BLUETOOTH = 0x0100; + public static final int ERROR_BLUETOOTH_CONNECTION_FAILED = ERROR_BLUETOOTH | 0x01; + public static final int ERROR_BLUETOOTH_CONNECTION_LOST = ERROR_BLUETOOTH | 0x02; + public static final int ERROR_BLUETOOTH_NOT_SUPPORTED = ERROR_BLUETOOTH | 0x03; + public static final int ERROR_BLUETOOTH_INVALID_MAC = ERROR_BLUETOOTH | 0x04; + public static final int ERROR_BLUETOOTH_ECHO_TIMEDOUT = ERROR_BLUETOOTH | 0x05; + public static final int ERROR_BLUETOOTH_NO_REMOTE_DEVICE = ERROR_BLUETOOTH | 0x06; + public static final int ERROR_BLUETOOTH_BT40_NOT_SUPPRTED = ERROR_BLUETOOTH | 0x07; + public static final int ERROR_BLUETOOTH_BT40_NO_SPP_SERVICE = ERROR_BLUETOOTH | 0x08; + + //Hardware-related errors: + public static final int ERROR_HARDWARE = 0x0200; + public static final int ERROR_HARDWARE_WDG_RESET = ERROR_HARDWARE | 0x01; + + //Packet + public static final int ERROR_PACKET = 0x0300; + public static final int ERROR_PACKET_INVALID_CRC = ERROR_PACKET | 0x01; + public static final int ERROR_PACKET_INVALID_LENGTH = ERROR_PACKET | 0x02; + public static final int ERROR_PACKET_INVALID_HEADER = ERROR_PACKET | 0x03; + + //Init + public static final int ERROR_INIT = 0x0400; + public static final int ERROR_INIT_UNSUPPORTED_CMD = ERROR_INIT | 0x01; + public static final int ERROR_INIT_TIMEDOUT = ERROR_INIT | 0x02; + public static final int ERROR_INIT_FW_TYPE_NOT_SUPPORTED = ERROR_INIT | 0x03; + public static final int ERROR_INIT_FW_VERSION_NOT_SUPPORTED = ERROR_INIT | 0x04; + + //Security + public static final int ERROR_SECURITY = 0x0500; + public static final int ERROR_SECURITY_NOT_SUPPORTED = ERROR_SECURITY | 0x01; + public static final int ERROR_SECURITY_NO_KEY = ERROR_SECURITY | 0x02; + public static final int ERROR_SECURITY_INVALID_KEY = ERROR_SECURITY | 0x03; + public static final int ERROR_SECURITY_CHALLENGE = ERROR_SECURITY | 0x04; + public static final int ERROR_SECURITY_NOT_PROTECTED = ERROR_SECURITY | 0x05; + + //Android + public static final int ERROR_ANDROID = 0x1000; + public static final int ERROR_ANDROID_NO_UTILITY_APP = ERROR_ANDROID | 0x01; + public static final int ERROR_ANDROID_SERVICE_DISCONNECTED = ERROR_ANDROID | 0x02; + public static final int ERROR_ANDROID_UTIL_FORCE_DISC = ERROR_ANDROID | 0x03; + public static final int ERROR_ANDROID_UTIL_IDLE_DISC = ERROR_ANDROID | 0x04; + + // 0000 - ERROR_NONE + // xx00 - Category / Unknown + // xxyy - Category / Details + + private static final SparseArray errorCodeMap; + static + { + errorCodeMap = new SparseArray(); + errorCodeMap.put(ERROR_NONE, "None"); + errorCodeMap.put(ERROR_UNKNOWN, "Unknown"); + //Bluetooth + errorCodeMap.put(ERROR_BLUETOOTH, "Bluetooth"); + errorCodeMap.put(ERROR_BLUETOOTH_CONNECTION_FAILED, "Failed to connect"); + errorCodeMap.put(ERROR_BLUETOOTH_CONNECTION_LOST, "Connection lost"); + errorCodeMap.put(ERROR_BLUETOOTH_NOT_SUPPORTED, "Not supported"); + errorCodeMap.put(ERROR_BLUETOOTH_INVALID_MAC, "Invalid MAC"); + errorCodeMap.put(ERROR_BLUETOOTH_ECHO_TIMEDOUT, "Echo timedout"); + errorCodeMap.put(ERROR_BLUETOOTH_NO_REMOTE_DEVICE, "Can't find remote device"); + errorCodeMap.put(ERROR_BLUETOOTH_BT40_NOT_SUPPRTED, "BT 4.0 is not supported"); + errorCodeMap.put(ERROR_BLUETOOTH_BT40_NO_SPP_SERVICE, "BT 4.0 RXTX not found"); + + //Hardware + errorCodeMap.put(ERROR_HARDWARE, "Hardware"); + errorCodeMap.put(ERROR_HARDWARE_WDG_RESET, "WDG reset"); + + //Packet + errorCodeMap.put(ERROR_PACKET, "Invalid packet"); + errorCodeMap.put(ERROR_PACKET_INVALID_CRC, "Invalid CRC"); + errorCodeMap.put(ERROR_PACKET_INVALID_LENGTH, "Invalid length"); + errorCodeMap.put(ERROR_PACKET_INVALID_HEADER, "Invalid header"); + + //Init + errorCodeMap.put(ERROR_INIT, "Init"); + errorCodeMap.put(ERROR_INIT_UNSUPPORTED_CMD, "Command not supported"); + errorCodeMap.put(ERROR_INIT_TIMEDOUT, "Timedout"); + errorCodeMap.put(ERROR_INIT_FW_TYPE_NOT_SUPPORTED, "FW type not supported"); + errorCodeMap.put(ERROR_INIT_FW_VERSION_NOT_SUPPORTED, "FW version not supported"); + + //Security + errorCodeMap.put(ERROR_SECURITY, "Security"); + errorCodeMap.put(ERROR_SECURITY_NOT_SUPPORTED, "Not supported"); + errorCodeMap.put(ERROR_SECURITY_NO_KEY, "No key provided"); + errorCodeMap.put(ERROR_SECURITY_INVALID_KEY, "Invalid key"); + errorCodeMap.put(ERROR_SECURITY_CHALLENGE, "Challenge failed"); + errorCodeMap.put(ERROR_SECURITY_NOT_PROTECTED, "Key was provided, but device is not password protected"); + + //Android + errorCodeMap.put(ERROR_ANDROID, "Android"); + errorCodeMap.put(ERROR_ANDROID_NO_UTILITY_APP, "InputStickUtility app not installed"); + errorCodeMap.put(ERROR_ANDROID_SERVICE_DISCONNECTED, "Service connection lost"); + errorCodeMap.put(ERROR_ANDROID_UTIL_FORCE_DISC, "Connection closed by InputStickUtility"); + errorCodeMap.put(ERROR_ANDROID_UTIL_IDLE_DISC, "Connection closed due to inactivity"); + + } + + public static String getErrorType(int errorCode) { + String result; + errorCode &= 0xFF00; + result = errorCodeMap.get(errorCode); + if (result != null) { + return result; + } else { + return ERROR_UNKNOWN_MSG; + } + } + + public static String getErrorMessage(int errorCode) { + String result; + if (errorCode == ERROR_NONE) { + return errorCodeMap.get(ERROR_NONE); + } + + //handle case: "Bluetooth: Unknown" etc + if ((errorCode & 0x00FF) == 0) { + return ERROR_UNKNOWN_MSG; + } + + result = errorCodeMap.get(errorCode); + if (result != null) { + return result; + } else { + return ERROR_UNKNOWN_MSG; + } + } + + public static String getFullErrorMessage(int errorCode) { + return getErrorType(errorCode) + " - " + getErrorMessage(errorCode); + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickKeyboardListener.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickKeyboardListener.java new file mode 100644 index 00000000..c0508417 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickKeyboardListener.java @@ -0,0 +1,7 @@ +package com.inputstick.api; + +public interface InputStickKeyboardListener { + + public void onLEDsChanged(boolean numLock, boolean capsLock, boolean scrollLock); + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickStateListener.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickStateListener.java new file mode 100644 index 00000000..16a7df8e --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/InputStickStateListener.java @@ -0,0 +1,7 @@ +package com.inputstick.api; + +public interface InputStickStateListener { + + public void onStateChanged(int state); + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/OnEmptyBufferListener.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/OnEmptyBufferListener.java new file mode 100644 index 00000000..9b84b954 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/OnEmptyBufferListener.java @@ -0,0 +1,8 @@ +package com.inputstick.api; + +public interface OnEmptyBufferListener { + + public void onLocalBufferEmpty(int interfaceId); + public void onRemoteBufferEmpty(int interfaceId); + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/Packet.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/Packet.java new file mode 100644 index 00000000..7b4c2fff --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/Packet.java @@ -0,0 +1,144 @@ +package com.inputstick.api; + +public class Packet { + + public static final byte NONE = 0x00; + + public static final byte START_TAG = 0x55; + public static final byte FLAG_RESPOND = (byte)0x80; + public static final byte FLAG_ENCRYPTED = 0x40; + + public static final int MAX_SUBPACKETS = 17; + public static final int MAX_LENGTH = MAX_SUBPACKETS * 16; + + public static final byte CMD_IDENTIFY = 0x01; + public static final byte CMD_LED = 0x02; + public static final byte CMD_RUN_BL = 0x03; + public static final byte CMD_RUN_FW = 0x04; + public static final byte CMD_GET_INFO = 0x05; + public static final byte CMD_BL_ERASE = 0x06; + public static final byte CMD_ADD_DATA = 0x07; + public static final byte CMD_BL_WRITE = 0x08; + + public static final byte CMD_FW_INFO = 0x10; + public static final byte CMD_INIT = 0x11; + public static final byte CMD_INIT_AUTH = 0x12; + public static final byte CMD_INIT_CON = 0x13; + public static final byte CMD_SET_VALUE = 0x14; + public static final byte CMD_RESTORE_DEFAULTS = 0x15; + public static final byte CMD_RESTORE_STATUS = 0x16; + public static final byte CMD_GET_VALUE = 0x17; + public static final byte CMD_SET_PIN = 0x18; + public static final byte CMD_USB_RESUME = 0x19; + public static final byte CMD_USB_POWER = 0x1A; + + public static final byte CMD_SYSTEM_NOTIFICATION = 0x1F; + + + + public static final byte CMD_HID_STATUS_REPORT = 0x20; + public static final byte CMD_HID_DATA_KEYB = 0x21; + public static final byte CMD_HID_DATA_CONSUMER = 0x22; + public static final byte CMD_HID_DATA_MOUSE = 0x23; + public static final byte CMD_HID_DATA_GAMEPAD = 0x24; + + public static final byte CMD_HID_DATA_ENDP = 0x2B; + public static final byte CMD_HID_DATA_KEYB_FAST = 0x2C; + public static final byte CMD_HID_DATA_KEYB_FASTEST = 0x2D; + //out + public static final byte CMD_HID_STATUS = 0x2F; + + + + public static final byte CMD_DUMMY = (byte)0xFF; + + + public static final byte RESP_OK = 0x01; + public static final byte RESP_UNKNOWN_CMD = (byte)0xFF; + + + public static final byte[] RAW_OLD_BOOTLOADER = new byte[] {START_TAG, (byte)0x00, (byte)0x02, (byte)0x83, (byte)0x00, (byte)0xDA}; + public static final byte[] RAW_DELAY_1_MS = new byte[] {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; + + private byte[] mData; + private int mPos; + private boolean mRespond; + + //do not modify + public Packet(boolean respond, byte[] data) { + mRespond = respond; + mData = data; + mPos = data.length; + } + + public Packet(boolean respond, byte cmd, byte param, byte[] data) { + mRespond = respond; + mData = new byte[MAX_LENGTH]; + mData[0] = cmd; + mData[1] = param; + mPos = 2; + if (data != null) { + addBytes(data); + } + } + + public Packet(boolean respond, byte cmd, byte param) { + this(respond, cmd, param, null); + } + + public Packet(boolean respond, byte cmd) { + mRespond = respond; + mData = new byte[MAX_LENGTH]; + mData[0] = cmd; + mPos = 1; + } + + public void modifyByte(int pos, byte b) { + mData[pos] = b; + } + + public void addBytes(byte[] data) { + //TODO check null pointer / available size (MAX_PAYLOAD - mPos) + System.arraycopy(data, 0, mData, mPos, data.length); + mPos += data.length; + } + + public void addByte(byte b) { + mData[mPos++] = b; + } + + public void addInt16(int val) { + mData[mPos + 0] = Util.getMSB(val); + mData[mPos + 1] = Util.getLSB(val); + mPos += 2; + } + + public void addInt32(long val) { + mData[mPos + 3] = (byte)val; + val >>= 8; + mData[mPos + 2] = (byte)val; + val >>= 8; + mData[mPos + 1] = (byte)val; + val >>= 8; + mData[mPos + 0] = (byte)val; + val >>= 8; + mPos += 4; + } + + + public byte[] getBytes() { + byte[] result; + result = new byte[mPos]; + System.arraycopy(mData, 0, result, 0, mPos); + return result; + } + + public boolean getRespond() { + return mRespond; + } + + public void print() { + Util.printHex(mData, "PACKET DATA:"); + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/PacketManager.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/PacketManager.java new file mode 100644 index 00000000..eea81f04 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/PacketManager.java @@ -0,0 +1,185 @@ +package com.inputstick.api; + +import java.util.Arrays; +import java.util.Random; +import java.util.zip.CRC32; + +import com.inputstick.api.bluetooth.BTService; + +public class PacketManager { + + public static final int MAX_PAYLAOD = 64; + public static final int HEADER_OFFSET = 2; + public static final int CRC_OFFSET = 4; + public static final int PACKET_SIZE = 16; + + private final BTService mBTService; + private final AES mAes; + private final byte[] mKey; + private byte[] cmpData; + private final CRC32 mCrc; + private boolean mEncryption; + + public PacketManager(BTService btService, byte[] key) { + mBTService = btService; + mCrc = new CRC32(); + mAes = new AES(); + mKey = key; + mEncryption = false; + } + + public boolean setEncryption(byte[] cmp, boolean encryptOut) { + byte[] cmpDec = mAes.decrypt(cmp); + if (Arrays.equals(cmpDec, cmpData)) { + mEncryption = encryptOut; + return true; + } else { + mEncryption = false; + return false; + } + } + + public boolean isEncrypted() { + return mEncryption; + } + + public Packet encPacket(boolean enable) { + Random r = new Random(); + Packet p = new Packet(true, Packet.CMD_INIT_AUTH); + if (enable) { + p.addByte((byte)1); + } else { + p.addByte((byte)0); + } + + byte[] iv = mAes.init(mKey); + p.addBytes(iv); + + //Util.printHex(mKey, "key: "); // TODO prnt + + //Util.printHex(iv, "IV: "); + + byte[] initData = new byte[16]; + r.nextBytes(initData); + mCrc.reset(); + mCrc.update(initData, 4, 12); //only 12 bytes! + long crcValue = mCrc.getValue(); + initData[3] = (byte)crcValue; + crcValue >>= 8; + initData[2] = (byte)crcValue; + crcValue >>= 8; + initData[1] = (byte)crcValue; + crcValue >>= 8; + initData[0] = (byte)crcValue; + initData = mAes.encrypt(initData); + p.addBytes(initData); + + //Util.printHex(initData, "InitData: "); + + cmpData = new byte[16]; + r.nextBytes(cmpData); + p.addBytes(cmpData); + + //Util.printHex(cmpData, "CmpData: "); + return p; + } + + + + public byte[] bytesToPacket(byte[] data) { + byte[] payload; + //boolean decrypt = false; + long crcValue, crcCompare; + + //Util.printHex(data, "RX DATA: "); // TODO prnt + + payload = Arrays.copyOfRange(data, 2, data.length); //remove TAG, info + if ((data[1] & Packet.FLAG_ENCRYPTED) != 0) { + //Util.log("DECRYPT"); + if (mAes.isReady()) { + payload = mAes.decrypt(payload); + //Util.printHex(payload, "RX DECR: "); // TODO prnt + } else { + return null; + } + } + + //Util.printHex(payload, "DATA IN: "); + + //check CRC + crcCompare = Util.getLong(payload[0], payload[1], payload[2], payload[3]); + mCrc.reset(); + mCrc.update(payload, CRC_OFFSET, payload.length - CRC_OFFSET); + crcValue = mCrc.getValue(); + //System.out.println("CMP: " + crcCompare + " VAL: " + crcValue); + + if (crcValue == crcCompare) { + payload = Arrays.copyOfRange(payload, 4, payload.length); //remove CRC + //Util.printHex(payload, "RX PAYLOAD FINAL: "); // TODO prnt + return payload; + } else { + return null; //TODO + } + + } + + public void sendRAW(byte[] data) { + mBTService.write(data); + } + + public void sendPacket(Packet p) { + if (p != null) { + sendPacket(p, mEncryption); + } + } + + public void sendPacket(Packet p, boolean encrypt) { + byte[] result, header, data; + int length; + int packets; + long crcValue; + + //if data > MAX_PAYLAOD -> error + + data = p.getBytes(); + + length = data.length + CRC_OFFSET; //include 4bytes for CRC32 + packets = ((length - 1) >> 4) + 1; //how many 16 bytes data sub-packets are necessary + + result = new byte[packets * PACKET_SIZE]; + System.arraycopy(data, 0, result, CRC_OFFSET, data.length); + + //add CRC32 + mCrc.reset(); + mCrc.update(result, CRC_OFFSET, result.length - CRC_OFFSET); + crcValue = mCrc.getValue(); + //Util.log("CRC: "+crcValue); + result[3] = (byte)crcValue; + crcValue >>= 8; + result[2] = (byte)crcValue; + crcValue >>= 8; + result[1] = (byte)crcValue; + crcValue >>= 8; + result[0] = (byte)crcValue; + + //Util.printHex(result, "TX DATA: "); // TODO prnt + if (encrypt) { + result = mAes.encrypt(result); + //Util.printHex(result, "ENC DATA: "); // TODO prnt + } + + header = new byte[2]; + header[0] = Packet.START_TAG; + header[1] = (byte)packets; + if (encrypt) { + header[1] |= Packet.FLAG_ENCRYPTED; + } + if (p.getRespond()) { + header[1] |= Packet.FLAG_RESPOND; + } + //Util.printHex(header, "TX HEADER: "); // TODO prnt + mBTService.write(header); + mBTService.write(result); + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/Util.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/Util.java new file mode 100644 index 00000000..155448bb --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/Util.java @@ -0,0 +1,121 @@ +package com.inputstick.api; + +import android.annotation.SuppressLint; +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + + +public abstract class Util { + + public static boolean debug = false; + public static boolean flashingToolMode = false; + + public static void log(String msg) { + log(msg, false); + } + + public static void log(String msg, boolean displayTime) { + if (debug) { + System.out.print("LOG: " + msg); + if (displayTime) { + System.out.print(" @ " + System.currentTimeMillis()); + } + System.out.println(); + } + } + + public static void printHex(byte[] toPrint, String info) { + if (debug) { + System.out.println(info); + printHex(toPrint); + } + } + + @SuppressLint("DefaultLocale") + public static String byteToHexString(byte b) { + String s; + //0x0..0xF = 0x00..0x0F + if ((b < 0x10) && (b >= 0)) { + s = Integer.toHexString((int)b); + s = "0" + s; + } else { + s = Integer.toHexString((int)b); + if (s.length() > 2) { + s = s.substring(s.length() - 2); + } + } + s = s.toUpperCase(); + return s; + } + + public static void printHex(byte[] toPrint) { + if (debug) { + if (toPrint != null) { + int cnt = 0; + byte b; + for (int i = 0; i < toPrint.length; i++) { + b = toPrint[i]; + + System.out.print("0x" + byteToHexString(b) + " "); + cnt++; + if (cnt == 8) { + System.out.println(""); + cnt = 0; + } + } + + } else { + System.out.println("null"); + } + System.out.println("\n#####"); + } + } + + + public static byte getLSB(int n) { + return (byte)(n & 0x00FF); + } + + public static byte getMSB(int n) { + return (byte)((n & 0xFF00) >> 8); + } + + public static int getInt(byte b) { + int bInt = b & 0xFF; + return bInt; + } + + public static int getInt(byte msb, byte lsb) { + int msbInt = msb & 0xFF; + int lsbInt = lsb & 0xFF; + return (msbInt << 8) + lsbInt; + } + + public static long getLong(byte b0, byte b1, byte b2, byte b3) { + long result; + result = (b0) & 0xFF; + result <<= 8; + result += (b1) & 0xFF; + result <<= 8; + result += (b2) & 0xFF; + result <<= 8; + result += (b3) & 0xFF; + return result; + } + + + public static byte[] getPasswordBytes(String plainText) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + return md.digest(plainText.getBytes("UTF-8")); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return null; + } + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickConsumer.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickConsumer.java new file mode 100644 index 00000000..5274592c --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickConsumer.java @@ -0,0 +1,89 @@ +package com.inputstick.api.basic; + +import com.inputstick.api.hid.ConsumerReport; +import com.inputstick.api.hid.HIDTransaction; + +public class InputStickConsumer { + + //CONSUMER PAGE (consumerAction) + public static final int VOL_UP = 0x00E9; + public static final int VOL_DOWN = 0x00EA; + public static final int VOL_MUTE = 0x00E2; + public static final int TRACK_NEXT = 0x00B5; + public static final int TRACK_PREV = 0x00B6; + public static final int STOP = 0x00B7; + public static final int PLAY_PAUSE = 0x00CD; + + public static final int LAUNCH_BROWSER = 0x0196; + public static final int LAUNCH_EMAIL = 0x018A; + public static final int LAUNCH_CALC = 0x0192; + + //Android OS (consumer): + public static final int HOME = 0x0223; + public static final int BACK = 0x0224; + public static final int SEARCH = 0x0221; + + + //SYSTEM PAGE (systemAction) + public static final byte SYSTEM_POWER_DOWN = 0x01; + public static final byte SYSTEM_SLEEP = 0x02; + public static final byte SYSTEM_WAKEUP = 0x03; + + private InputStickConsumer() { + + } + + + /* + * Use only for system actions SYSTEM_POWER_DOWN, SYSTEM_SLEEP and SYSTEM_WAKEUP + * + * @param action code of system action + */ + public static void systemAction(byte action) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new ConsumerReport(ConsumerReport.SYSTEM_REPORT_ID, action, (byte)0)); + t.addReport(new ConsumerReport(ConsumerReport.SYSTEM_REPORT_ID, (byte)0, (byte)0)); + InputStickHID.addConsumerTransaction(t); + } + + + /* + * Requests USB host to power down. Must be supported and enabled by USB host. + */ + public static void systemPowerDown() { + systemAction(SYSTEM_POWER_DOWN); + } + + + /* + * Requests USB host to go into sleep/standby mode. Must be supported and enabled by USB host. + */ + public static void systemSleep() { + systemAction(SYSTEM_SLEEP); + } + + + /* + * Requests USB host to resume from sleep/standby mode. Must be supported and enabled by USB host. + * Note: USB host must supply USB power when suspended. Otherwise InputStick will not work. + */ + public static void systemWakeUp() { + systemAction(SYSTEM_WAKEUP); + } + + + /* + * Consumer control action: media playback, volume etc. + * See http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (consumer page). + * USB host may not support certain action codes + * + * @param action code of consumer control action + */ + public static void consumerAction(int action) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new ConsumerReport(action)); + t.addReport(new ConsumerReport()); + InputStickHID.addConsumerTransaction(t); + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickGamepad.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickGamepad.java new file mode 100644 index 00000000..c042a610 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickGamepad.java @@ -0,0 +1,38 @@ +package com.inputstick.api.basic; + +import com.inputstick.api.Packet; + + +public class InputStickGamepad { + + private InputStickGamepad() { + + } + + + /* + * Sends custom HID gamepad report + * + * @param buttons1 state (on/off) of buttons0..7 + * @param buttons2 state (on/off) of buttons8..15 + * @param x value of X axis + * @param y value of Y axis + * @param z value of Z axis + * @param rx value of rX axis + */ + public static void customReport(byte buttons1, byte buttons2, byte x, byte y, byte z, byte rX) { + if (InputStickHID.isReady()) { + Packet p = new Packet(false, (byte)0x2B, (byte)0x03); //write directly to endp3in, no buffering + p.addByte((byte)0x07); //report bytes cnt + p.addByte((byte)0x03); //report ID + p.addByte(buttons1); + p.addByte(buttons2); + p.addByte(x); + p.addByte(y); + p.addByte(z); + p.addByte(rX); + InputStickHID.sendPacket(p); + } + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickHID.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickHID.java new file mode 100644 index 00000000..659debd0 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickHID.java @@ -0,0 +1,602 @@ +package com.inputstick.api.basic; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.Vector; + +import android.app.AlertDialog; +import android.app.Application; +import android.content.Context; + +import com.inputstick.api.BTConnectionManager; +import com.inputstick.api.ConnectionManager; +import com.inputstick.api.DownloadDialog; +import com.inputstick.api.HIDInfo; +import com.inputstick.api.IPCConnectionManager; +import com.inputstick.api.InputStickDataListener; +import com.inputstick.api.InputStickError; +import com.inputstick.api.InputStickStateListener; +import com.inputstick.api.OnEmptyBufferListener; +import com.inputstick.api.Packet; +import com.inputstick.api.hid.HIDReport; +import com.inputstick.api.hid.HIDTransaction; +import com.inputstick.api.hid.HIDTransactionQueue; +import com.inputstick.api.init.BasicInitManager; +import com.inputstick.api.init.DeviceInfo; +import com.inputstick.api.init.InitManager; + +public class InputStickHID implements InputStickStateListener, InputStickDataListener { + + public static final int INTERFACE_KEYBOARD = 0; + public static final int INTERFACE_CONSUMER = 1; + public static final int INTERFACE_MOUSE = 2; + + private static ConnectionManager mConnectionManager; + + private static Vector mStateListeners = new Vector(); + protected static Vector mBufferEmptyListeners = new Vector(); + + private static InputStickHID instance = new InputStickHID(); + private static HIDInfo mHIDInfo; + private static DeviceInfo mDeviceInfo; + + private static HIDTransactionQueue keyboardQueue; + private static HIDTransactionQueue mouseQueue; + private static HIDTransactionQueue consumerQueue; + + + //FW 0.93 - 0.95 + private static Timer updateQueueTimer; + + + private static int mKeyboardReportMultiplier; //enables "slow" typing by multiplying HID reports + + private InputStickHID() { + } + + public static InputStickHID getInstance() { + return instance; + } + + private static void init() { + mHIDInfo = new HIDInfo(); + keyboardQueue = new HIDTransactionQueue(INTERFACE_KEYBOARD, mConnectionManager); + mouseQueue = new HIDTransactionQueue(INTERFACE_MOUSE, mConnectionManager); + consumerQueue = new HIDTransactionQueue(INTERFACE_CONSUMER, mConnectionManager); + + mConnectionManager.addStateListener(instance); + mConnectionManager.addDataListener(instance); + mConnectionManager.connect(); + } + + /* + * Returns download InputStickUtility AlertDialog if InputStickUtility is not installed. Returns null is InputStickUtility application is installed. + * Should be called when your application is started or before InputStick functionality is about to be used. + * + * @return download InputStickUtility AlertDialog or null + */ + public static AlertDialog getDownloadDialog(final Context ctx) { + if (mConnectionManager.getErrorCode() == InputStickError.ERROR_ANDROID_NO_UTILITY_APP) { + return DownloadDialog.getDialog(ctx, DownloadDialog.NOT_INSTALLED); + } else { + return null; + } + } + + + /* + * Connect using InputStickUtility application. + * IN MOST CASES THIS METHOD SHOULD BE USED TO INITIATE CONNECTION! + * + * @param app Application + */ + public static void connect(Application app) { + mConnectionManager = new IPCConnectionManager(app); + init(); + } + + + /* + * Close connection + */ + public static void disconnect() { + if (mConnectionManager != null) { + mConnectionManager.disconnect(); + } + } + + + /* + * Direct connection to InputStick (BT2.1 only!). InputStickUtility application is not required in this case. + * TIP: use Util.getPasswordBytes(plainText) to get key. + * + * @param app Application + * @param mac Bluetooth MAC address + * @param key MD5(password) - must be provided if InputStick is password protected. Use null otherwise + * @param initManager custom init manager + */ + public static void connect(Application app, String mac, byte[] key, InitManager initManager) { + connect(app, mac, key, initManager, false); + } + + + /* + * Direct connection to InputStick. InputStickUtility application is not required in this case. + * TIP: use Util.getPasswordBytes(plainText) to get key. + * + * @param app Application + * @param mac Bluetooth MAC address + * @param key MD5(password) - must be provided if InputStick is password protected. Use null otherwise + * @param initManager custom init manager + * @param isBT40 specify Bluetooth version. Must match your hardware (InputStick BT2.1 or BT4.0)! + */ + public static void connect(Application app, String mac, byte[] key, InitManager initManager, boolean isBT40) { + mConnectionManager = new BTConnectionManager(initManager, app, mac, key, isBT40); + init(); + } + + + /* + * Direct connection to InputStick. InputStickUtility application is not required in this case. + * TIP: use Util.getPasswordBytes(plainText) to get key. + * + * @param app Application + * @param mac Bluetooth MAC address + * @param key MD5(password) - must be provided if InputStick is password protected. Use null otherwise + * @param initManager custom init manager + * @param isBT40 specify Bluetooth version. Must match your hardware (InputStick BT2.1 or BT4.0)! + */ + public static void connect(Application app, String mac, byte[] key, boolean isBT40) { + mConnectionManager = new BTConnectionManager(new BasicInitManager(key), app, mac, key, isBT40); + init(); + } + + + /* + * Direct connection to InputStick (BT2.1 only!). InputStickUtility application is not required in this case. + * TIP: use Util.getPasswordBytes(plainText) to get key. + * + * @param app Application + * @param mac Bluetooth MAC address + * @param key MD5(password) - must be provided if InputStick is password protected. Use null otherwise + */ + public static void connect(Application app, String mac, byte[] key) { + connect(app, mac, key, false); + } + + + /* + * When keyboard transactions are queued, each individual HID keyboard report is duplicated by reportMultiplier. + * Allows to control typing speed. Can help with missing characters (for example in BIOS). + * Important! Value of multiplier should be manually restored back to 1, when slow typing is no longer needed! + * + * Example: press and release "a" key: + * 1) Multiplier = 1 + * "a" key presses, all keys released + * 2 HID reports, fastest typing speed + * 2) Multiplier = 2 + * "a" key presses, "a" key presses, all keys released, all keys released + * 4 HID reports, 50% slower typing speed + * + * + * @param reportMultiplier number by which each HID report will be duplicated + */ + public static void setKeyboardReportMultiplier(int reportMultiplier) { + mKeyboardReportMultiplier = reportMultiplier; + } + + + /* + * Returns value of keyboard report multiplier + * + * @return keyboard report multiplier + */ + public static int getKeyboardReportMultiplier(int reportMultiplier) { + return mKeyboardReportMultiplier; + } + + + /* + * Requests USB host to resume from sleep / suspended state. Feature must be supported and enabled by USB host. + * Note 1: when USB host is suspended, device state will be STATE_CONNECTED. + * Note 2: some USB hosts may cut off USB power when suspended. + */ + public static void wakeUpUSBHost() { + if (isConnected()) { + Packet p = new Packet(false, Packet.CMD_USB_RESUME); + InputStickHID.sendPacket(p); + mConnectionManager.sendPacket(p); + } + } + + + /* + * Get device info of connected device + * + * @return Device info of connected device. Null if info is not available + */ + public static DeviceInfo getDeviceInfo() { + if ((isReady()) && (mDeviceInfo != null)) { + return mDeviceInfo; + } else { + return null; + } + } + + + /* + * Get latest status update received from InputStick. + * + * @return latest status update + */ + public static HIDInfo getHIDInfo() { + return mHIDInfo; + } + + + /* + * Returns current state of the connection. + * + * @return state of the connection + */ + public static int getState() { + if (mConnectionManager != null) { + return mConnectionManager.getState(); + } else { + return ConnectionManager.STATE_DISCONNECTED; + } + } + + + /* + * Returns last error code. See class InputStickError. + * + * @return last error code + */ + public static int getErrorCode() { + if (mConnectionManager != null) { + return mConnectionManager.getErrorCode(); + } else { + return InputStickError.ERROR_UNKNOWN; + } + } + + + /* + * Checks if Bluetooth connection between Android device and InputStick is established. + * Note - InputStick may be not ready yet to accept keyboard/mouse data. + * + * @return true if Bluetooth connection is established + */ + public static boolean isConnected() { + if ((getState() == ConnectionManager.STATE_READY) || (getState() == ConnectionManager.STATE_CONNECTED)) { + return true; + } else { + return false; + } + } + + + /* + * Checks if InputStick is ready to accept keyboard/mouse/etc. data. + * + * @return true if InputStick is ready to accept data + */ + public static boolean isReady() { + if (getState() == ConnectionManager.STATE_READY) { + return true; + } else { + return false; + } + } + + + /* + * Adds InputStickStateListener. Listener will be notified when connection state changes. + * + * @param listener listener to add + */ + public static void addStateListener(InputStickStateListener listener) { + if (listener != null) { + if ( !mStateListeners.contains(listener)) { + mStateListeners.add(listener); + } + } + } + + + /* + * Removes InputStickStateListener. Listener will no longer be notified when connection state changes. + * + * @param listener listener to remove + */ + public static void removeStateListener(InputStickStateListener listener) { + if (listener != null) { + mStateListeners.remove(listener); + } + } + + + /* + * Adds OnEmptyBufferListener. Listeners will be notified when local (application) or remote (InputStick) HID report buffer is empty. + * + * @param listener listener to add + */ + public static void addBufferEmptyListener(OnEmptyBufferListener listener) { + if (listener != null) { + if ( !mBufferEmptyListeners.contains(listener)) { + mBufferEmptyListeners.add(listener); + } + } + } + + + /* + * Removes OnEmptyBufferListener. + * + * @param listener listener to remove + */ + public static void removeBufferEmptyListener(OnEmptyBufferListener listener) { + if (listener != null) { + mBufferEmptyListeners.remove(listener); + } + } + + + /* + * Returns vector with registered OnEmptyBuffer listeners. + * + * @return vector with OnEmptyBuffer listeners + */ + public static Vector getBufferEmptyListeners() { + return mBufferEmptyListeners; + } + + + /* + * Adds transaction to keyboard queue. + * If possible, all reports form a single transactions will be sent in a single packet. + * This should prevent from key being stuck in pressed position when connection is suddenly lost. + * + * @param transaction transaction to be queued + */ + public static void addKeyboardTransaction(HIDTransaction transaction) { + if ((transaction != null) && (keyboardQueue != null)) { + //keyboardQueue.addTransaction(transaction); + + if (mKeyboardReportMultiplier > 1) { + HIDTransaction multipliedTransaction = new HIDTransaction(); + HIDReport r; + for (int i = 0; i < transaction.getReportsCount(); i++) { + r = transaction.getHIDReportAt(i); + for (int j = 0; j < mKeyboardReportMultiplier; j++) { + multipliedTransaction.addReport(r); + } + } + keyboardQueue.addTransaction(multipliedTransaction); + } else { + keyboardQueue.addTransaction(transaction); + } + } + } + + + /* + * Adds transaction to mouse queue. + * If possible, all reports form a single transactions will be sent in a single packet. + * + * @param transaction transaction to be queued + */ + public static void addMouseTransaction(HIDTransaction transaction) { + if ((transaction != null) && (mouseQueue != null)) { + mouseQueue.addTransaction(transaction); + } + } + + + /* + * Adds transaction to consumer control queue. + * If possible, all reports form a single transactions will be sent in a single packet. + * + * @param transaction transaction to be queued + */ + public static void addConsumerTransaction(HIDTransaction transaction) { + if ((transaction != null) && (consumerQueue != null)) { + consumerQueue.addTransaction(transaction); + } + } + + + /* + * Removes all reports from keyboard buffer. + */ + public static void clearKeyboardBuffer() { + if (keyboardQueue != null) { + keyboardQueue.clearBuffer(); + } + } + + + /* + * Removes all reports from mouse buffer. + */ + public static void clearMouseBuffer() { + if (mouseQueue != null) { + mouseQueue.clearBuffer(); + } + } + + + /* + * Removes all reports from consumer control buffer. + */ + public static void clearConsumerBuffer() { + if (consumerQueue != null) { + consumerQueue.clearBuffer(); + } + } + + + /* + * Sends custom packet to InputStick. + * + * @param p packet to send. + */ + public static boolean sendPacket(Packet p) { + if (mConnectionManager != null) { + mConnectionManager.sendPacket(p); + return true; + } else { + return false; + } + } + + + /* + * Checks if local (Android device) keyboard report buffer is empty. It is possible that there are reports queued in InputStick's buffer. + * + * @return true if local keyboard buffer is empty, false otherwise + */ + public static boolean isKeyboardLocalBufferEmpty() { + if (keyboardQueue != null) { + return keyboardQueue.isLocalBufferEmpty(); + } else { + return true; + } + } + + + /* + * Checks if local (Android device) mouse report buffer is empty. It is possible that there are reports queued in InputStick's buffer. + * + * @return true if local mouse buffer is empty, false otherwise + */ + public static boolean isMouseLocalBufferEmpty() { + if (mouseQueue != null) { + return mouseQueue.isLocalBufferEmpty(); + } else { + return true; + } + } + + + /* + * Checks if local (Android device) consumer control report buffer is empty. It is possible that there are reports queued in InputStick's buffer. + * + * @return true if local consumer control buffer is empty, false otherwise + */ + public static boolean isConsumerLocalBufferEmpty() { + if (consumerQueue != null) { + return consumerQueue.isLocalBufferEmpty(); + } else { + return true; + } + } + + + /* + * Checks if local (Android device) AND remote (InputStick) keyboard report buffers are empty. + * + * @return true if local and remote keyboard buffers are empty, false otherwise + */ + public static boolean isKeyboardRemoteBufferEmpty() { + if (keyboardQueue != null) { + return keyboardQueue.isRemoteBufferEmpty(); + } else { + return true; + } + } + + + /* + * Checks if local (Android device) AND remote (InputStick) mouse report buffers are empty. + * + * @return true if local and remote mouse buffers are empty, false otherwise + */ + public static boolean isMouseRemoteBufferEmpty() { + if (mouseQueue != null) { + return mouseQueue.isRemoteBufferEmpty(); + } else { + return true; + } + } + + + /* + * Checks if local (Android device) AND remote (InputStick) consumer control report buffers are empty. + * + * @return true if local and remote consumer control buffers are empty, false otherwise + */ + public static boolean isConsumerRemoteBufferEmpty() { + if (consumerQueue != null) { + return consumerQueue.isRemoteBufferEmpty(); + } else { + return true; + } + } + + + + + + + @Override + public void onStateChanged(int state) { + if ((state == ConnectionManager.STATE_DISCONNECTED) && (updateQueueTimer != null)) { + updateQueueTimer.cancel(); + updateQueueTimer = null; + } + for (InputStickStateListener listener : mStateListeners) { + listener.onStateChanged(state); + } + } + + @Override + public void onInputStickData(byte[] data) { + byte cmd = data[0]; + if (cmd == Packet.CMD_FW_INFO) { + mDeviceInfo = new DeviceInfo(data); + } + + if (cmd == Packet.CMD_HID_STATUS) { + mHIDInfo.update(data); + + if (mHIDInfo.isSentToHostInfoAvailable()) { + // >= FW 0.93 + keyboardQueue.deviceReady(mHIDInfo, mHIDInfo.getKeyboardReportsSentToHost()); + mouseQueue.deviceReady(mHIDInfo, mHIDInfo.getMouseReportsSentToHost()); + consumerQueue.deviceReady(mHIDInfo, mHIDInfo.getConsumerReportsSentToHost()); + + if (mDeviceInfo != null) { + if ((updateQueueTimer == null) && (mDeviceInfo.getFirmwareVersion() < 97)) { + updateQueueTimer = new Timer(); + updateQueueTimer.schedule(new TimerTask() { + @Override + public void run() { + keyboardQueue.sendToBuffer(false); + mouseQueue.sendToBuffer(false); + consumerQueue.sendToBuffer(false); + } + }, 5, 5); + } + } + } else { + //previous FW versions + if (mHIDInfo.isKeyboardReady()) { + keyboardQueue.deviceReady(null, 0); + } + if (mHIDInfo.isMouseReady()) { + mouseQueue.deviceReady(null, 0); + } + if (mHIDInfo.isConsumerReady()) { + consumerQueue.deviceReady(null, 0); + } + } + + InputStickKeyboard.setLEDs(mHIDInfo.getNumLock(), mHIDInfo.getCapsLock(), mHIDInfo.getScrollLock()); + } + } + + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickKeyboard.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickKeyboard.java new file mode 100644 index 00000000..b310bebf --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickKeyboard.java @@ -0,0 +1,263 @@ +package com.inputstick.api.basic; + +import java.util.Vector; + +import android.util.SparseArray; + +import com.inputstick.api.InputStickKeyboardListener; +import com.inputstick.api.hid.HIDKeycodes; +import com.inputstick.api.hid.HIDTransaction; +import com.inputstick.api.hid.KeyboardReport; +import com.inputstick.api.layout.KeyboardLayout; + +public class InputStickKeyboard { + + private static final byte NONE = (byte)0; + + private static final byte LED_NUM_LOCK = 1; + private static final byte LED_CAPS_LOCK = 2; + private static final byte LED_SCROLL_LOCK = 4; + + private static boolean mReportProtocol; + private static boolean mNumLock; + private static boolean mCapsLock; + private static boolean mScrollLock; + + private static Vector mKeyboardListeners = new Vector(); + + private static final SparseArray ledsMap; + static + { + ledsMap = new SparseArray(); + ledsMap.put(LED_NUM_LOCK, "NumLock"); + ledsMap.put(LED_CAPS_LOCK, "CapsLock"); + ledsMap.put(LED_SCROLL_LOCK, "ScrollLock"); + } + + private InputStickKeyboard() { + } + + + /* + * Uses InputStick to press and then immediately release key combination specified by parameters. + * + * @param modifier state of modifier keys (CTRL_LEFT .. GUI_RIGHT, see HIDKeycodes) + * @param key non-modifier key (see HIDKeycodes) + */ + public static void pressAndRelease(byte modifier, byte key) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new KeyboardReport(modifier, NONE)); + t.addReport(new KeyboardReport(modifier, key)); + t.addReport(new KeyboardReport(NONE, NONE)); + InputStickHID.addKeyboardTransaction(t); + } + + + /* + * Type text via InputStick, using selected keyboard layout. USB host must use matching keyboard layout. + * For available keyboard layouts see: com.inputstick.api.layout. + * If layout is null or not found, en-US will be used. + * + * @param toType text to type + * @param layoutCode code of keyboard layout ("en-US", "de-DE", etc.) + */ + public static void type(String toType, String layoutCode) { + KeyboardLayout layout = KeyboardLayout.getLayout(layoutCode); + layout.type(toType); + } + + + /* + * Type text via InputStick. ASCII characters only! It is assumed that USB host uses en-US keyboard layout. + * + * @param toType text to type + */ + public static void typeASCII(String toType) { + int keyCode; + int index; + + for (int i = 0; i < toType.length(); i++) { + index = toType.charAt(i); + if (index == '\n') { + pressAndRelease(NONE, HIDKeycodes.KEY_ENTER); + } else if (index == '\t') { + pressAndRelease(NONE, HIDKeycodes.KEY_TAB); + } else { + if (index > 127) { + index = 127; + } + keyCode = HIDKeycodes.getKeyCode(index); + if (keyCode > 128) { + keyCode -= 128; + pressAndRelease(HIDKeycodes.SHIFT_LEFT, (byte)keyCode); + } else { + pressAndRelease(NONE, (byte)keyCode); + } + } + } + } + + + /* + * Sends custom keyboard HID report. + * Note: keys must be "manually" released by sending next custom HID report (with 0x00s as key0..key5). + * + * @param modifier state of modifier keys (CTRL_LEFT .. GUI_RIGHT, see HIDKeycodes) + * @param key0 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + * @param key1 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + * @param key2 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + * @param key3 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + * @param key4 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + * @param key5 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + */ + public static void customReport(byte modifier, byte key0, byte key1, byte key2, byte key3, byte key4, byte key5) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new KeyboardReport(modifier, key0, key1, key2, key3, key4, key5)); + InputStickHID.addKeyboardTransaction(t); + } + + + /* + * Checks is report protocol is used. + * Report protocol is in most cases used by OS + * Boot protocol is used by BIOS, or when OS is booting + * + * @return true if USB host uses report protocol, false if USB host uses boot protocol + */ + public boolean isReportProtocol() { + return mReportProtocol; + } + + + /* + * Checks states of NumLock keyboard LED + * + * @return true if NumLock LED is on, false if off. + */ + public static boolean isNumLock() { + return mNumLock; + } + + + /* + * Checks states of CapsLock keyboard LED + * + * @return true if CapsLock LED is on, false if off. + */ + public static boolean isCapsLock() { + return mCapsLock; + } + + + /* + * Checks states of ScrollLock keyboard LED + * + * @return true if ScrollLock LED is on, false if off. + */ + public static boolean isScrollLock() { + return mScrollLock; + } + + + /* + * Toggle state of NumLock by press and release NumLock key. + */ + public static void toggleNumLock() { + pressAndRelease(NONE, HIDKeycodes.KEY_NUM_LOCK); + } + + + /* + * Toggle state of CapsLock by press and release CapsLock key. + */ + public static void toggleCapsLock() { + pressAndRelease(NONE, HIDKeycodes.KEY_CAPS_LOCK); + } + + + /* + * Toggle state of ScrollLock by press and release ScrollLock key. + */ + public static void toggleScrollLock() { + pressAndRelease(NONE, HIDKeycodes.KEY_SCROLL_LOCK); + } + + + + + + + /* + * Converts state of keyboard LEDs to String. Example: "CapsLock, ScrollLock". + * + * @return String description of keyboard LEDs. + */ + public static String ledsToString(byte leds) { + String result = "None"; + boolean first = true; + byte mod; + for (int i = 0; i < 8; i++) { + mod = (byte)(LED_NUM_LOCK << i); + if ((leds & mod) != 0) { + if ( !first) { + result += ", "; + } else { + result = ""; + } + first = false; + result += ledsMap.get(mod); + } + } + + return result; + } + + + /* + * Adds InputStickKeyboardListener. Listener will be notified when state of keyboard LEDs changes (NumLock, CapsLock, ScrollLock). + * + * @param listener listener to add + */ + public static void addKeyboardListener(InputStickKeyboardListener listener) { + if (listener != null) { + if ( !mKeyboardListeners.contains(listener)) { + mKeyboardListeners.add(listener); + } + } + } + + + /* + * Removes InputStickKeyboardListener. + * + * @param listener listener to remove + */ + public static void removeKeyboardListener(InputStickKeyboardListener listener) { + if (listener != null) { + mKeyboardListeners.remove(listener); + } + } + + + + protected void setReportProtocol(boolean reportProtocol) { + mReportProtocol = reportProtocol; + } + + protected static void setLEDs(boolean numLock, boolean capsLock, boolean scrollLock) { + boolean mustUpdate = false; + if ((numLock != mNumLock) || (capsLock != mCapsLock) || (scrollLock != mScrollLock)) { + mustUpdate = true; + } + mNumLock = numLock; + mCapsLock = capsLock; + mScrollLock = scrollLock; + + if (mustUpdate) { + for (InputStickKeyboardListener listener : mKeyboardListeners) { + listener.onLEDsChanged(mNumLock, mCapsLock, mScrollLock); + } + } + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickMouse.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickMouse.java new file mode 100644 index 00000000..412d67a4 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/basic/InputStickMouse.java @@ -0,0 +1,131 @@ +package com.inputstick.api.basic; + +import android.util.SparseArray; + +import com.inputstick.api.hid.HIDTransaction; +import com.inputstick.api.hid.MouseReport; + +public class InputStickMouse { + + private static final byte NONE = 0x00; + + public static final byte BUTTON_NONE = 0x00; + public static final byte BUTTON_LEFT = 0x01; + public static final byte BUTTON_RIGHT = 0x02; + public static final byte BUTTON_MIDDLE = 0x04; + + private static final SparseArray buttonsMap; + static + { + buttonsMap = new SparseArray(); + buttonsMap.put(BUTTON_LEFT, "Left"); + buttonsMap.put(BUTTON_RIGHT, "Right"); + buttonsMap.put(BUTTON_MIDDLE, "Middle"); + } + + private static boolean mReportProtocol; + + private InputStickMouse() { + + } + + + /* + * Clicks selected mouse button (BUTTON_LEFT etc) N times + * + * @param button code of mouse button + * @param n number of button clicks (press and release events) + */ + public static void click(byte button, int n) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new MouseReport()); //release + for (int i = 0; i < n; i++) { + t.addReport(new MouseReport(button, NONE, NONE, NONE)); //press + t.addReport(new MouseReport()); //release + } + InputStickHID.addMouseTransaction(t); + } + + /* + * Move mouse pointer + * + * @param x x displacement + * @param y y dispalcement + */ + public static void move(byte x, byte y) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new MouseReport(NONE, x, y, NONE)); + InputStickHID.addMouseTransaction(t); + } + + /* + * Moves mouse scroll wheel + * + * @param wheel scroll wheel displacement + */ + public static void scroll(byte wheel) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new MouseReport(NONE, NONE, NONE, wheel)); + InputStickHID.addMouseTransaction(t); + } + + //sends custom mouse report (buttons will remain in pressed state until released by next report) + + /* + * Sends custom HID mouse report. Mouse buttons will remain in selected state until new report is received. + * + * @param buttons state of mouse buttons + * @param x x displacement + * @param y y dispalcement + * @param wheel scroll wheel displacement + */ + public static void customReport(byte buttons, byte x, byte y, byte wheel) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new MouseReport(buttons, x, y, wheel)); + InputStickHID.addMouseTransaction(t); + } + + + /* + * Returns names of buttons in "pressed" state + * + * @param buttons state of mouse buttons + */ + public static String buttonsToString(byte buttons) { + String result = "None"; + boolean first = true; + byte mod; + for (int i = 0; i < 8; i++) { + mod = (byte)(BUTTON_LEFT << i); + if ((buttons & mod) != 0) { + if ( !first) { + result += ", "; + } else { + result = ""; + } + first = false; + result += buttonsMap.get(mod); + } + } + + return result; + } + + + /* + * When report protocol is used, scroll wheel is enabled. Otherwise, simplified boot protocol is selected by USB host. + * Report protocol is in most cases used by OS. + * Boot protocol is used by BIOS, or when OS is booting. + * + * @return true if USB host uses report protocol, false if USB host uses boot protocol + */ + public boolean isReportProtocol() { + return mReportProtocol; + } + + + protected void setReportProtocol(boolean reportProtocol) { + mReportProtocol = reportProtocol; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BT20Connection.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BT20Connection.java new file mode 100644 index 00000000..8f982035 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BT20Connection.java @@ -0,0 +1,198 @@ +package com.inputstick.api.bluetooth; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Method; +import java.util.UUID; + +import android.app.Application; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Util; + +public class BT20Connection extends BTConnection { + + private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //SPP + + private final BluetoothAdapter mAdapter; + + private ConnectThread mConnectThread; + private ConnectedThread mConnectedThread; + + + public BT20Connection(Application app, BTService btService, String mac, boolean reflections) { + super(app, btService, mac, reflections); + mAdapter = BluetoothAdapter.getDefaultAdapter(); + } + + @Override + public void connect() { + if (mConnectThread != null) { + mConnectThread.cancel(); + mConnectThread = null; + } + if (mConnectedThread != null) { + mConnectedThread.cancel(); + mConnectedThread = null; + } + final BluetoothDevice device = mAdapter.getRemoteDevice(mMac); + if (device != null) { + mConnectThread = new ConnectThread(device, mReflections); + mConnectThread.start(); + } else { + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_NO_REMOTE_DEVICE); + } + } + + @Override + public void disconnect() { + cancelThreads(); + } + + @Override + public void write(byte[] out) { + mConnectedThread.write(out); + } + + + + + + //################################ + + private synchronized void cancelThreads() { + if (mConnectThread != null) { + mConnectThread.cancel(); + mConnectThread = null; + } + if (mConnectedThread != null) { + mConnectedThread.cancel(); + mConnectedThread = null; + } + } + + + private class ConnectThread extends Thread { + + private final BluetoothSocket mmSocket; + //private final BluetoothDevice mmDevice; + + public ConnectThread(BluetoothDevice device, boolean useReflection) { + //mmDevice = device; + BluetoothSocket tmp = null; + + try { + if (useReflection) { + Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}); + tmp = (BluetoothSocket) m.invoke(device, 1); + } else { + tmp = device.createRfcommSocketToServiceRecord(MY_UUID); + } + + } catch (IOException e) { + Util.log("Socket create() failed"); + } catch (Exception e) { + Util.log("Socket create() REFLECTION failed"); + e.printStackTrace(); + } + mmSocket = tmp; + } + + public void run() { + Util.log("BEGIN mConnectThread"); + + mAdapter.cancelDiscovery(); //else it will slow down connection + + try { + mmSocket.connect(); + } catch (IOException e) { + try { + mmSocket.close(); + } catch (IOException e2) { + Util.log("unable to close() socket during connection failure"); + } + mBTservice.connectionFailed(true, 0); + return; + } + + mConnectThread = null; + cancelThreads(); + + //now connected: + mConnectedThread = new ConnectedThread(mmSocket); + mConnectedThread.start(); + mBTservice.connectedEstablished(); + } + + public void cancel() { + try { + mmSocket.close(); + } catch (IOException e) { + Util.log("close() of connect socket failed"); + } + } + } + + + + private class ConnectedThread extends Thread { + + private final BluetoothSocket mmSocket; + private final InputStream mmInStream; + private final OutputStream mmOutStream; + + public ConnectedThread(BluetoothSocket socket) { + Util.log("create ConnectedThread"); + mmSocket = socket; + InputStream tmpIn = null; + OutputStream tmpOut = null; + + try { + tmpIn = socket.getInputStream(); + tmpOut = socket.getOutputStream(); + } catch (IOException e) { + Util.log("temp sockets not created"); + } + + mmInStream = tmpIn; + mmOutStream = tmpOut; + } + + + public void run() { + Util.log("BEGIN mConnectedThread"); + int rxTmp; + while (true) { + try { + rxTmp = mmInStream.read(); + mBTservice.onByteRx(rxTmp); + } catch (IOException e) { + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_CONNECTION_LOST); + break; + } + } + } + + public void write(byte[] buffer) { + try { + mmOutStream.write(buffer); + mmOutStream.flush(); + } catch (IOException e) { + Util.log("write() exception"); + } + } + + public void cancel() { + try { + mmSocket.close(); + } catch (IOException e) { + Util.log("socket close() exception"); + } + } + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BT40Connection.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BT40Connection.java new file mode 100644 index 00000000..eb0b1baf --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BT40Connection.java @@ -0,0 +1,286 @@ +package com.inputstick.api.bluetooth; + +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import android.annotation.SuppressLint; +import android.app.Application; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Handler; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Util; + +@SuppressLint("NewApi") +public class BT40Connection extends BTConnection { + + private static final int CONNECTION_TIMEOUT = 10000; + + private static final String MOD_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + private static final String MOD_CONF = "0000ffe0-0000-1000-8000-00805f9b34fb"; + private static final String MOD_RX_TX = "0000ffe1-0000-1000-8000-00805f9b34fb"; + private static final UUID UUID_HM_RX_TX = UUID.fromString(MOD_RX_TX); + + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothGatt mBluetoothGatt; + private BluetoothGattCharacteristic characteristicTX; + private BluetoothGattCharacteristic characteristicRX; + + private LinkedList txBuffer; + private boolean canSend; + + private boolean isConnecting; + private Handler handler; + + public BT40Connection(Application app, BTService btService, String mac, boolean reflections) { + super(app, btService, mac, reflections); + mBluetoothManager = (BluetoothManager) (mCtx.getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + + } + + @Override + public void connect() { + final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mMac); + if (device != null) { + mBluetoothGatt = device.connectGatt(mCtx, false, mGattCallback); + + isConnecting = true; + handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + if (isConnecting) { + disconnect(); + mBTservice.connectionFailed(true, 0); + } + } + }, CONNECTION_TIMEOUT); + } else { + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_NO_REMOTE_DEVICE); + } + } + + @Override + public void disconnect() { + txBuffer = null; + try { + if (mBluetoothGatt != null) { + mBluetoothGatt.close(); + mBluetoothGatt.disconnect(); + mBluetoothGatt = null; + } + } catch (Exception e) { + + } + } + + + + @Override + public void write(byte[] out) { + byte[] tmp; + int offset = 0; + + //SPECIAL CASES for flashing utility + if (Util.flashingToolMode) { + //txBuffer.add(out); + //return; + if (out.length == 1) { + txBuffer.add(out); + return; + } + if (out.length == 1026) { + tmp = new byte[2]; + tmp[0] = out[0]; + tmp[1] = out[1]; + txBuffer.add(tmp); + offset = 2; + for (int i = 0; i < 64; i++) { + tmp = new byte[16]; + System.arraycopy(out, offset, tmp, 0, 16); + offset += 16; + txBuffer.add(tmp); + } + return; + } + } + + if (out.length == 2) { + addHeader(out); + } else { + Util.log("ADDING: " + out.length); + int loops = out.length / 16; + offset = 0; + for (int i = 0; i < loops; i++) { + tmp = new byte[16]; + System.arraycopy(out, offset, tmp, 0, 16); + offset += 16; + addData16(tmp); + } + sendNext(); + } + } + + + private byte h0; + private byte h1; + private boolean header; + + private synchronized void addHeader(byte[] data) { + h0 = data[0]; + h1 = data[1]; + header = true; + } + + private synchronized void addData16(byte[] data) { + byte[] tmp; + int offset = 0; + if (txBuffer != null) { + if (header) { + header = false; + + tmp = new byte[18]; + offset = 2; + + tmp[0] = h0; + tmp[1] = h1; + } else { + tmp = new byte[16]; + offset = 0; + } + System.arraycopy(data, 0, tmp, offset, 16); + txBuffer.add(tmp); + } + } + + private synchronized byte[] getData() { + if (txBuffer != null) { + if (!txBuffer.isEmpty()) { + byte[] data = txBuffer.poll(); + return data; + } + } + return null; + } + + private synchronized void sendNext() { + if (canSend) { + byte[] data = getData(); + if (data != null) { + canSend = false; + characteristicTX.setValue(data); + characteristicTX.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); //TODO + //characteristicTX.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); //TODO + mBluetoothGatt.writeCharacteristic(characteristicTX); + } + } + } + + + + private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + isConnecting = false; + Util.log("Connected to GATT server."); + Util.log("Attempting to start service discovery:" + mBluetoothGatt.discoverServices()); + } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { + isConnecting = false; + Util.log("Disconnected from GATT server."); + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_CONNECTION_LOST); + } + } + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + Util.log("GATT onServicesDiscovered"); + List gattServices = null; + boolean serviceDiscovered = false; + if (mBluetoothGatt != null) { + gattServices = mBluetoothGatt.getServices(); + } + if (gattServices != null) { + String uuid = null; + characteristicRX = null; + for (BluetoothGattService gattService : gattServices) { + uuid = gattService.getUuid().toString(); + if (MOD_CONF.equals(uuid)) { + Util.log("BT LE - Serial Service Discovered"); + + characteristicTX = gattService.getCharacteristic(UUID_HM_RX_TX); + characteristicRX = gattService.getCharacteristic(UUID_HM_RX_TX); + if (characteristicRX == null) { + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_BT40_NO_SPP_SERVICE); + } else { + serviceDiscovered = true; + } + } + } + } + if (serviceDiscovered) { + //enable notifications + mBluetoothGatt.setCharacteristicNotification(characteristicRX, true); + if (UUID_HM_RX_TX.equals(characteristicRX.getUuid())) { + Util.log("RXTX SERVICE DISCOVERED!"); + BluetoothGattDescriptor descriptor = characteristicRX.getDescriptor(UUID.fromString(MOD_CHARACTERISTIC_CONFIG)); + descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + mBluetoothGatt.writeDescriptor(descriptor); + + txBuffer = new LinkedList(); + canSend = true; + sendNext(); + + mBTservice.connectedEstablished(); + } else { + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_BT40_NO_SPP_SERVICE); + } + } else { + Util.log("BT LE - Serial Service NOT FOUND"); + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_BT40_NO_SPP_SERVICE); + } + } else { + Util.log("onServicesDiscovered received: " + status); + } + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + } + } + + @Override + public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + byte b[] = characteristic.getValue(); + if (b != null) { + mBTservice.onByteRx(b); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + Util.log("GATT onCharacteristicWrite"); + if (status == BluetoothGatt.GATT_SUCCESS) { + canSend = true; + sendNext(); + } //TODO error code? + } + + }; + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BTConnection.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BTConnection.java new file mode 100644 index 00000000..a23e1e38 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BTConnection.java @@ -0,0 +1,26 @@ +package com.inputstick.api.bluetooth; + +import android.app.Application; +import android.content.Context; + + +public abstract class BTConnection { + + protected final Application mApp; + protected final Context mCtx; + protected final String mMac; + protected boolean mReflections; + protected final BTService mBTservice; + + public BTConnection(Application app, BTService btService, String mac, boolean reflections) { + mApp = app; + mCtx = app.getApplicationContext(); + mMac = mac; + mReflections = reflections; + mBTservice = btService; + } + + public abstract void connect(); + public abstract void disconnect(); + public abstract void write(byte[] out); +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BTService.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BTService.java new file mode 100644 index 00000000..2faddf35 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/BTService.java @@ -0,0 +1,231 @@ +package com.inputstick.api.bluetooth; + +import android.app.Application; +import android.bluetooth.BluetoothAdapter; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Handler; +import android.os.Message; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Util; + +public class BTService { + + public static final int DEFAULT_CONNECT_TIMEOUT = 30000; + + public static final int EVENT_NONE = 0; + public static final int EVENT_DATA = 1; + public static final int EVENT_CONNECTED = 2; + public static final int EVENT_CANCELLED = 3; + public static final int EVENT_ERROR = 4; + + + private final Handler mHandler; + private int mLastEvent; + + private String mMac; + private final Application mApp; + private final Context mCtx; + + private boolean mUseReflection; + private int mConnectTimeout; + + private long timeout; + private int retryCnt; + + private boolean disconnecting; + private boolean connected; + + private PacketReader mPacketReader; + private BTConnection mBTConnection; + + private boolean turnBluetoothOn; + private boolean receiverRegistered; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { + final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); + if ((state == BluetoothAdapter.STATE_ON) && (turnBluetoothOn)) { + turnBluetoothOn = false; + connect(false); + } + } + } + }; + + + + public BTService(Application app, Handler handler) { + mLastEvent = EVENT_NONE; + mHandler = handler; + mApp = app; + mCtx = app.getApplicationContext(); + mConnectTimeout = DEFAULT_CONNECT_TIMEOUT; + } + + public void setConnectTimeout(int timeout) { + mConnectTimeout = timeout; + } + + public void enableReflection(boolean enabled) { + mUseReflection = enabled; + } + + + protected synchronized void event(int event, int arg1) { + Util.log("event() " + mLastEvent + " -> " + event); + mLastEvent = event; + Message msg = Message.obtain(null, mLastEvent, arg1, 0); + mHandler.sendMessage(msg); + } + + public synchronized int getLastEvent() { + return mLastEvent; + } + + private void connect(boolean reconnecting) { + if (reconnecting) { + retryCnt++; + } else { + retryCnt = 0; + timeout = System.currentTimeMillis() + mConnectTimeout; + } + + mBTConnection.connect(); + } + + + public synchronized void connect(String mac) { + connect(mac, false); + } + + public synchronized void connect(String mac, boolean doNotAsk) { + connect(mac, doNotAsk, false); + } + + public synchronized void connect(String mac, boolean doNotAsk, boolean bt40) { + try { + Util.log("connect to: " + mac + " REFLECTION: " + mUseReflection); + disconnecting = false; + connected = false; + mMac = mac; + if (BluetoothAdapter.checkBluetoothAddress(mac)) { + BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (mBluetoothAdapter == null) { + event(BTService.EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_NOT_SUPPORTED); + } else { + if (bt40) { + mBTConnection = new BT40Connection(mApp, this, mMac, mUseReflection); + } else { + mBTConnection = new BT20Connection(mApp, this, mMac, mUseReflection); + } + + if (mBluetoothAdapter.isEnabled()) { + connect(false); + } else { + //enableBluetooth(doNotAsk); : + if (mApp != null) { + turnBluetoothOn = true; + + if ( !receiverRegistered) { + IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); + mCtx.registerReceiver(mReceiver, filter); + receiverRegistered = true; + } + + if (doNotAsk) { + BluetoothAdapter.getDefaultAdapter().enable(); + } else { + Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); + enableBtIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mApp.startActivity(enableBtIntent); + } + } + } + } + } else { + event(BTService.EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_INVALID_MAC); + } + } catch (NoClassDefFoundError e) { + event(BTService.EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_BT40_NOT_SUPPRTED); + } + } + + public synchronized void disconnect() { + Util.log("disconnect"); + disconnecting = true; + if (mBTConnection != null) { + mBTConnection.disconnect(); + } + event(EVENT_CANCELLED, 0); + } + + + public synchronized void write(byte[] out) { + if (connected) { + mBTConnection.write(out); + } + } + + + + + protected synchronized void connectedEstablished() { + removeReceiver(); //TODO + mPacketReader = new PacketReader(this, mHandler); + timeout = 0; + connected = true; + event(EVENT_CONNECTED, 0); + } + + + protected void connectionFailed(boolean canRetry, int errorCode) { + removeReceiver(); //TODO + connected = false; + if (disconnecting) { + disconnecting = false; + } else { + if (canRetry) { + if ((timeout > 0) && (System.currentTimeMillis() < timeout)) { + Util.log("RETRY: "+retryCnt + " time left: " + (timeout - System.currentTimeMillis())); + connect(true); + } else { + event(EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_CONNECTION_FAILED); + } + } else { + event(EVENT_ERROR, errorCode); + } + } + } + + + protected synchronized void onByteRx(int rxByte) { + mPacketReader.rxByte((byte)rxByte); + } + + protected synchronized void onByteRx(byte[] rxBytes) { + for (int i = 0; i < rxBytes.length; i++) { + mPacketReader.rxByte(rxBytes[i]); + } + } + + + private void removeReceiver() { + if (receiverRegistered) { + mCtx.unregisterReceiver(mReceiver); + receiverRegistered = false; + } + } + + + + public static boolean isBT40Supported() { + return (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR2); + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/PacketReader.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/PacketReader.java new file mode 100644 index 00000000..f8f66727 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/bluetooth/PacketReader.java @@ -0,0 +1,88 @@ +package com.inputstick.api.bluetooth; + +import android.os.Handler; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Packet; +import com.inputstick.api.Util; + +public class PacketReader { + + private static final int RX_TIMEOUT = 3000; + + private static final int RX_TAG = 0; + private static final int RX_LENGTH = 1; + private static final int RX_DATA = 2; + + private long lastRxTime; + private int rxState; + private int rxPos; + private int rxLength; + private byte[] rxData; + private int rxWdgCnt; + + private final BTService mBTService; + private final Handler mHandler; + + public PacketReader(BTService btService, Handler handler) { + mBTService = btService; + mHandler = handler; + } + + + public void rxByte(byte b) { + //byte b = (byte)rxByte; + long time = System.currentTimeMillis(); + if (time > lastRxTime + RX_TIMEOUT) { + rxState = RX_TAG; + } + + + switch (rxState) { + case RX_TAG: + if (b == Packet.START_TAG) { + rxState = RX_LENGTH; + } else { + Util.log("Unexpected RX byte" + b); + if (b == 0xAF) { + rxWdgCnt++; + } + if (rxWdgCnt > 1024) { + rxWdgCnt = 0; + mBTService.event(BTService.EVENT_ERROR, InputStickError.ERROR_HARDWARE_WDG_RESET); + } + } + break; + case RX_LENGTH: + rxLength = b; + rxLength &= 0x3F; + rxLength *= 16; + rxLength += 2; + rxPos = 2; + + rxData = new byte[rxLength]; + rxData[0] = Packet.START_TAG; + rxData[1] = (byte)b; + + rxState = RX_DATA; + break; + case RX_DATA: + if (rxPos < rxLength) { + rxData[rxPos] = b; + rxPos++; + if (rxPos == rxLength) { + //done! + mHandler.obtainMessage(BTService.EVENT_DATA, 0, 0, rxData).sendToTarget(); + rxState = RX_TAG; + } + } else { + //buffer overrun! + rxState = RX_TAG; + } + break; + } + + lastRxTime = time; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/broadcast/InputStickBroadcast.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/broadcast/InputStickBroadcast.java new file mode 100644 index 00000000..f8736bdc --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/broadcast/InputStickBroadcast.java @@ -0,0 +1,430 @@ +package com.inputstick.api.broadcast; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager.NameNotFoundException; + +import com.inputstick.api.DownloadDialog; + + +/* + * IMPORTANT: + * + * Using InputStickBroadcast is the easiest and fastest way to use InputStick with your application. + * InputStickUility takes care of almost everything: + * -enabling Bluetooth if necessary, + * -selecting InputStick device (if more than one is available), + * -establishing connection, + * -deals with potential connection problems (connection failed, lost), + * -user preferences (keyboard layout, typing speed). + * + * as a result of that, your application has little to no control over: + * -connection, + * -buffers + * -timing, + * + * + * Using InputStickBroadcast is recommended only for simple use cases: typing strings. + * Example: barcode scanner app, assuming that user will use InputStick to type only some of scanned codes. + * + * Using InputStickBroadcast is NOT recommended if + * -timing is critical, + * -low latency is necessary, + * -many actions can be executed in a short period of time + * + * Example: remote control app. + * + * In such case use classes from com.inputstick.api.hid package and implement all necessary callbacks. + * + */ + + +public class InputStickBroadcast { + + private static boolean AUTO_SUPPORT_CHECK; + + public static final String PARAM_REQUEST = "REQUEST"; + public static final String PARAM_RELEASE = "RELEASE"; + public static final String PARAM_CLEAR = "CLEAR"; + + public static final String PARAM_TEXT = "TEXT"; + public static final String PARAM_LAYOUT = "LAYOUT"; + public static final String PARAM_MULTIPLIER = "MULTIPLIER"; + public static final String PARAM_KEY = "KEY"; + public static final String PARAM_MODIFIER = "MODIFIER"; + public static final String PARAM_REPORT_KEYB = "REPORT_KEYB"; + public static final String PARAM_REPORT_EMPTY = "REPORT_EMPTY"; + + public static final String PARAM_REPORT_MOUSE = "REPORT_MOUSE"; + public static final String PARAM_MOUSE_BUTTONS ="MOUSE_BUTTONS"; + public static final String PARAM_MOUSE_CLICKS = "MOUSE_CLICKS"; + + public static final String PARAM_CONSUMER = "CONSUMER"; + + + + + /* + * Checks whether InputStickUtility is installed and supports intents (version code >= 11). + * Optionally download dialog can be displayed if InputStickUtility is not installed. + * + * @param ctx context + * @param allowMessages when true, download dialog will be displayed if necessary + * + */ + public static boolean isSupported(Context ctx, boolean allowMessages) { + PackageInfo pInfo; + try { + pInfo = ctx.getPackageManager().getPackageInfo("com.inputstick.apps.inputstickutility", 0); + //System.out.println("ver: " + pInfo.versionName + " code: " + pInfo.versionCode); + if (pInfo.versionCode < 11) { + if (allowMessages) { + DownloadDialog.getDialog(ctx, DownloadDialog.NOT_UPDATED).show(); + } + return false; + } else { + return true; + } + } catch (NameNotFoundException e) { + //e.printStackTrace(); + //InputStickUtility not installed + if (allowMessages) { + DownloadDialog.getDialog(ctx, DownloadDialog.NOT_INSTALLED).show(); + } + return false; + } + } + + + /* + * When Auto Support Check is enabled, isSupported(ctx, true) will be called each time before sending broadcast. + * You do not have to check support manually. Download dialog will be displayed if InputStickUtility is not installed. + * + * WARNING: checking support each time after sending broadcast can be very time consuming!!! + * + * @param enabled true to enable Auto Support Check, false to disable + */ + public static void setAutoSupportCheck(boolean enabled) { + AUTO_SUPPORT_CHECK = enabled; + } + + + /* + * Indicates that it is very likely that this application will want to use InputStick within next few seconds. + * Depending on user preferences this action may be ignored! In such case InputStickUtility will wait until some data arrives (text etc.). + * In many cases this will allow to reduce delay between requesting some action and executing it (typing text etc). + * + * @param ctx context used to send broadcast. + */ + public static void requestConnection(Context ctx) { + Intent intent = new Intent(); + intent.putExtra(PARAM_REQUEST, true); + send(ctx, intent); + } + + + /* + * Indicates that application will no longer need InputStick in nearest future. + * Allows to save power. + * Depending on user preferences this action may be ignored! + * Ignored if not connected. + * + * @param ctx context used to send broadcast. + */ + public static void releaseConnection(Context ctx) { + Intent intent = new Intent(); + intent.putExtra(PARAM_RELEASE, true); + send(ctx, intent); + } + + + /* + * Removes all actions from queue. Clears all interface buffers. + * Use to immediately stop all actions + * Depending on user preferences this action may be ignored! + * + * @param ctx context used to send broadcast. + */ + public static void clearQueue(Context ctx) { + Intent intent = new Intent(); + intent.putExtra(PARAM_CLEAR, true); + send(ctx, intent); + } + + + + + //####################################################################################################### + //##### KEYBOARD INTERFACE ############################################################################## + //####################################################################################################### + + + /* + * Puts "type text" action into queue. Fastest typing speed, use en-US layout. + * + * @param ctx context used to send broadcast. + * @param text text to be typed. \n and \t characters are allowed. + */ + public static void type(Context ctx, String text) { + type(ctx, text, null, 1); + } + + + /* + * Puts "type text" action into queue. Fastest typing speed. + * + * Keyboard layout must match layout used by USB host. en-US is used by default. + * Depending on user preferences value of layoutCode may be ignored! + * + * @param ctx context used to send broadcast + * @param text text to be typed. \n and \t characters are allowed. + * @param layoutCode keyboard layout to be used: en-US, de-DE, pl-PL etc. + */ + public static void type(Context ctx, String text, String layoutCode) { + type(ctx, text, layoutCode, 1); + } + + + /* + * Puts "type text" action into queue. + * + * Keyboard layout must match layout used by USB host. en-US is used by default. + * Depending on user preferences value of layoutCode may be ignored! + * + * When multiplier is set to 1, keys will be "pressed" at fastest possible speed. Increase value of this parameter to obtain slower typing speed, by multiplying number of HID keyboard reports. + * Depending on user preferences value of multiplier may be ignored! + * + * @param ctx context used to send broadcast + * @param text text to be typed. \n and \t characters are allowed. + * @param layoutCode keyboard layout to be used: en-US, de-DE, pl-PL etc. + * @param multiplier controls typing speed. + */ + public static void type(Context ctx, String text, String layoutCode, int multiplier) { + Intent intent = new Intent(); + + intent.putExtra(PARAM_TEXT, text); + if (layoutCode != null) { + intent.putExtra(PARAM_LAYOUT, layoutCode); + } + if (multiplier > 1) { + intent.putExtra(PARAM_MULTIPLIER, multiplier); + } + send(ctx, intent); + } + + + /* + * Puts "press and release key" action into queue. + * + * @param ctx context used to send broadcast. + * @param modifiers modifier keys: Shift, Alt, Ctrl, Gui/Win/Command keys, (see HIDKeycodes class. + * @param key any non-modifier key, see HIDKeycodes class. + */ + public static void pressAndRelease(Context ctx, byte modifiers, byte key) { + pressAndRelease(ctx, modifiers, key, 1); + } + + + /* + * Puts "press and release key" action into queue. + * When multiplier is set to 1, keys will be "pressed" at fastest possible speed. Increase value of this parameter to obtain slower typing speed, by multiplying number of HID reports. + * + * @param ctx context used to send broadcast. + * @param modifiers modifier keys: Shift, Alt, Ctrl, Gui/Win/Command keys, (see HIDKeycodes class). + * @param key any non-modifier key, see HIDKeycodes class. + * @param multiplier controls typing speed. + */ + public static void pressAndRelease(Context ctx, byte modifiers, byte key, int multiplier) { + Intent intent = new Intent(); + + intent.putExtra(PARAM_MODIFIER, modifiers); + intent.putExtra(PARAM_KEY, key); + if (multiplier > 1) { + intent.putExtra(PARAM_MULTIPLIER, multiplier); + } + send(ctx, intent); + } + + + /* + * Puts single HID keyboard report into queue. + * HID keyboard report represents state of keyboard (which keys are pressed) at a given moment. + * Must be 8 bytes long: + * report[0] = modifier keys + * report[1] = 0x00 + * report[2] = key1 + * report[3] = key2 + * report[4] = key3 + * report[5] = key4 + * report[6] = key5 + * report[7] = key6 + * To avoid keys getting "stuck" they should be released (by adding empty report). + * + * @param ctx context used to send broadcast. + * @param report HID keyboard report. + * @param addEmptyReport empty keyboard report (all keys released) will be added if true. + */ + public static void keyboardReport(Context ctx, byte[] report, boolean addEmptyReport) { + Intent intent = new Intent(); + intent.putExtra(PARAM_REPORT_KEYB, report); + if (addEmptyReport) { + intent.putExtra(PARAM_REPORT_EMPTY, true); + } + send(ctx, intent); + } + + + /* + * Puts single HID keyboard report into queue. + * HID keyboard report represents state of keyboard (which keys are pressed) at a given moment. + * To avoid keys getting "stuck" they should be released (by adding empty report). + * + * @param ctx context used to send broadcast. + * @param modifiers modifier keys: Shift, Alt, Ctrl, Gui/Win/Command keys, (see HIDKeycodes class). + * @param key1 any non-modifier key, see HIDKeycodes class. + * @param key2 any non-modifier key, see HIDKeycodes class. + * @param key3 any non-modifier key, see HIDKeycodes class. + * @param key4 any non-modifier key, see HIDKeycodes class. + * @param key5 any non-modifier key, see HIDKeycodes class. + * @param key6 any non-modifier key, see HIDKeycodes class. + * @param addEmptyReport empty keyboard report (all keys released) will be added if true. + */ + public static void keyboardReport(Context ctx, byte modifiers, byte key1, byte key2, byte key3, byte key4, byte key5, byte key6, boolean addEmptyReport) { + byte[] report = new byte[8]; + report[0] = modifiers; + report[2] = key1; + report[3] = key2; + report[4] = key3; + report[5] = key4; + report[6] = key5; + report[7] = key6; + keyboardReport(ctx, report, addEmptyReport); + } + + + + + //####################################################################################################### + //##### MOUSE INTERFACE ################################################################################# + //####################################################################################################### + + + /* + * Puts single HID mouse report into queue. + * HID mouse report represents change in state of a mouse. + * Must be 4 bytes long: + * report[0] = buttons + * report[1] = x axis displacement + * report[2] = y axis displacement + * report[3] = scroll wheel displacement + * + * @param ctx context used to send broadcast. + * @param report HID mouse report. + */ + public static void mouseReport(Context ctx, byte[] report) { + Intent intent = new Intent(); + intent.putExtra(PARAM_REPORT_MOUSE, report); + send(ctx, intent); + } + + + /* + * Puts single HID mouse report into queue. + * Left mouse button = 0x01 + * Right mouse button = 0x02 + * Middle mouse button = 0x04 + * + * @param ctx context used to send broadcast. + * @param buttons mouse buttons to click. + * @param dx x axis displacement. + * @param dy y axis displacement. + * @param scroll scroll wheel displacement. + */ + public static void mouseReport(Context ctx, byte buttons, byte dx, byte dy, byte scroll) { + byte[] report = new byte[4]; + report[0] = buttons; + report[1] = dx; + report[2] = dy; + report[3] = scroll; + mouseReport(ctx, report); + } + + + /* + * Puts mouse click (button(s) press-release) action into queue. + * Left mouse button = 0x01 + * Right mouse button = 0x02 + * Middle mouse button = 0x04 + * + * @param ctx context used to send broadcast. + * @param buttons mouse buttons to click. + * @param n number of clicks. + */ + public static void mouseClick(Context ctx, byte buttons, int n) { + Intent intent = new Intent(); + intent.putExtra(PARAM_MOUSE_BUTTONS, buttons); + intent.putExtra(PARAM_MOUSE_CLICKS, n); + send(ctx, intent); + } + + + /* + * Puts mouse move action into queue. + * + * @param ctx context used to send broadcast. + * @param dx x axis displacement. + * @param dy y axis displacement. + */ + public static void mouseMove(Context ctx, byte dx, byte dy) { + mouseReport(ctx, (byte)0x00, dx, dy, (byte)0x00); + } + + + /* + * Puts mouse scroll action into queue. + * Positive values: scroll up; negative values: scroll down + * + * @param ctx context used to send broadcast. + * @param scroll scroll wheel displacement. + */ + public static void mouseScroll(Context ctx, byte scroll) { + mouseReport(ctx, (byte)0x00, (byte)0x00, (byte)0x00, scroll); + } + + + + + //####################################################################################################### + //##### CONSUMER CONTROL INTERFACE ###################################################################### + //####################################################################################################### + + /* + * Puts "consumer" action into queue. See InputStickConsumer class for list available actions. + * + * @param ctx context used to send broadcast. + * @param action code of consumer action. + */ + public static void consumerControlAction(Context ctx, int action) { + Intent intent = new Intent(); + intent.putExtra(PARAM_CONSUMER, action); + send(ctx, intent); + } + + + private static void send(Context ctx, Intent intent) { + intent.setAction("com.inputstick.apps.inputstickutility.HID"); + intent.setClassName("com.inputstick.apps.inputstickutility", "com.inputstick.apps.inputstickutility.service.HIDReceiver"); + + //if necessary, show download dialog message + if (AUTO_SUPPORT_CHECK) { + if (isSupported(ctx, true)) { + ctx.sendBroadcast(intent); + } + } else { + ctx.sendBroadcast(intent); + } + } + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/ConsumerReport.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/ConsumerReport.java new file mode 100644 index 00000000..b13ae68b --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/ConsumerReport.java @@ -0,0 +1,43 @@ +package com.inputstick.api.hid; + +import com.inputstick.api.Util; + +public class ConsumerReport extends HIDReport { + + public static final byte CONSUMER_REPORT_ID = 1; + public static final byte SYSTEM_REPORT_ID = 2; + public static final byte GAMEPAD_REPORT_ID = 3; + + public static final int SIZE = 3; + + private byte[] data; + + public ConsumerReport(byte id, byte b1, byte b2) { + data = new byte[SIZE]; + data[0] = id; + data[1] = b1; + data[2] = b2; + } + + public ConsumerReport(int usage) { + data = new byte[SIZE]; + data[0] = CONSUMER_REPORT_ID; + data[1] = Util.getLSB(usage); + data[2] = Util.getMSB(usage); + } + + public ConsumerReport() { + this(0); + } + + public byte[] getBytes() { + return data; + } + + public int getBytesCount() { + return SIZE; + } + + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/GamepadReport.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/GamepadReport.java new file mode 100644 index 00000000..242d4d9d --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/GamepadReport.java @@ -0,0 +1,32 @@ +package com.inputstick.api.hid; + +public class GamepadReport extends HIDReport { + + public static final int SIZE = 7; + + private byte[] data; + + public GamepadReport(byte b1, byte b2, byte x, byte y, byte z, byte rx) { + data = new byte[SIZE]; + data[0] = 3; + data[1] = b1; + data[2] = b2; + data[3] = x; + data[4] = y; + data[5] = z; + data[6] = rx; + } + + public GamepadReport() { + this((byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0); + } + + public byte[] getBytes() { + return data; + } + + public int getBytesCount() { + return SIZE; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDKeycodes.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDKeycodes.java new file mode 100644 index 00000000..3decb11e --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDKeycodes.java @@ -0,0 +1,436 @@ +package com.inputstick.api.hid; + +import android.util.SparseArray; + +public class HIDKeycodes { + + public static final byte NONE = 0x00; + + public static final byte CTRL_LEFT = 0x01; + public static final byte SHIFT_LEFT = 0x02; + public static final byte ALT_LEFT = 0x04; + public static final byte GUI_LEFT = 0x08; + public static final byte CTRL_RIGHT = 0x10; + public static final byte SHIFT_RIGHT = 0x20; + public static final byte ALT_RIGHT = 0x40; + public static final byte GUI_RIGHT = (byte)0x80; + + + public static final byte KEY_ENTER = 0x28; + public static final byte KEY_ESCAPE = 0x29; + public static final byte KEY_BACKSPACE = 0x2A; + public static final byte KEY_TAB = 0x2B; + public static final byte KEY_SPACEBAR = 0x2C; + + public static final byte KEY_CAPS_LOCK = 0x39; + + + public static final byte KEY_1 = 0x1E; + public static final byte KEY_2 = 0x1F; + public static final byte KEY_3 = 0x20; + public static final byte KEY_4 = 0x21; + public static final byte KEY_5 = 0x22; + public static final byte KEY_6 = 0x23; + public static final byte KEY_7 = 0x24; + public static final byte KEY_8 = 0x25; + public static final byte KEY_9 = 0x26; + public static final byte KEY_0 = 0x27; + + public static final byte KEY_F1 = 0x3A; + public static final byte KEY_F2 = 0x3B; + public static final byte KEY_F3 = 0x3C; + public static final byte KEY_F4 = 0x3D; + public static final byte KEY_F5 = 0x3E; + public static final byte KEY_F6 = 0x3F; + public static final byte KEY_F7 = 0x40; + public static final byte KEY_F8 = 0x41; + public static final byte KEY_F9 = 0x42; + public static final byte KEY_F10 = 0x43; + public static final byte KEY_F11 = 0x44; + public static final byte KEY_F12 = 0x45; + + public static final byte KEY_PRINT_SCREEN = 0x46; + public static final byte KEY_SCROLL_LOCK = 0x47; + public static final byte KEY_PASUE = 0x48; + public static final byte KEY_INSERT = 0x49; + public static final byte KEY_HOME = 0x4A; + public static final byte KEY_PAGE_UP = 0x4B; + public static final byte KEY_DELETE = 0x4C; + public static final byte KEY_END = 0x4D; + public static final byte KEY_PAGE_DOWN = 0x4E; + + public static final byte KEY_ARROW_RIGHT = 0x4F; + public static final byte KEY_ARROW_LEFT = 0x50; + public static final byte KEY_ARROW_DOWN = 0x51; + public static final byte KEY_ARROW_UP = 0x52; + + public static final byte KEY_NUM_LOCK = 0x53; + public static final byte KEY_NUM_SLASH = 0x54; + public static final byte KEY_NUM_STAR = 0x55; + public static final byte KEY_NUM_MINUS = 0x56; + public static final byte KEY_NUM_PLUS = 0x57; + public static final byte KEY_NUM_ENTER = 0x58; + public static final byte KEY_NUM_1 = 0x59; + public static final byte KEY_NUM_2 = 0x5A; + public static final byte KEY_NUM_3 = 0x5B; + public static final byte KEY_NUM_4 = 0x5C; + public static final byte KEY_NUM_5 = 0x5D; + public static final byte KEY_NUM_6 = 0x5E; + public static final byte KEY_NUM_7 = 0x5F; + public static final byte KEY_NUM_8 = 0x60; + public static final byte KEY_NUM_9 = 0x61; + public static final byte KEY_NUM_0 = 0x62; + public static final byte KEY_NUM_DOT = 0x63; + + public static final byte KEY_BACKSLASH_NON_US = 0x64; + + public static final byte KEY_A = 0x04; + public static final byte KEY_B = 0x05; + public static final byte KEY_C = 0x06; + public static final byte KEY_D = 0x07; + public static final byte KEY_E = 0x08; + public static final byte KEY_F = 0x09; + public static final byte KEY_G = 0x0A; + public static final byte KEY_H = 0x0B; + public static final byte KEY_I = 0x0C; + public static final byte KEY_J = 0x0D; + public static final byte KEY_K = 0x0E; + public static final byte KEY_L = 0x0F; + public static final byte KEY_M = 0x10; + public static final byte KEY_N = 0x11; + public static final byte KEY_O = 0x12; + public static final byte KEY_P = 0x13; + public static final byte KEY_Q = 0x14; + public static final byte KEY_R = 0x15; + public static final byte KEY_S = 0x16; + public static final byte KEY_T = 0x17; + public static final byte KEY_U = 0x18; + public static final byte KEY_V = 0x19; + public static final byte KEY_W = 0x1A; + public static final byte KEY_X = 0x1B; + public static final byte KEY_Y = 0x1C; + public static final byte KEY_Z = 0x1D; + + + + public static final byte KEY_MINUS = 0x2D; + public static final byte KEY_EQUALS = 0x2E; + public static final byte KEY_LEFT_BRACKET = 0x2F; + public static final byte KEY_RIGHT_BRACKET = 0x30; + public static final byte KEY_BACKSLASH = 0x31; + //public static final byte KEY_GRAVE = 0x32; + public static final byte KEY_SEMICOLON = 0x33; + public static final byte KEY_APOSTROPHE = 0x34; + public static final byte KEY_GRAVE = 0x35; + public static final byte KEY_COMA = 0x36; + public static final byte KEY_DOT = 0x37; + public static final byte KEY_SLASH = 0x38; + + + public static final byte KEY_APPLICATION = 0x65; + + + + public static final SparseArray modifiersMap; + static + { + modifiersMap = new SparseArray(); + modifiersMap.put(CTRL_LEFT, "Left Ctrl"); + modifiersMap.put(SHIFT_LEFT, "Left Shift"); + modifiersMap.put(ALT_LEFT, "Left Alt"); + modifiersMap.put(GUI_LEFT, "Left GUI"); + modifiersMap.put(CTRL_RIGHT, "Right Ctrl"); + modifiersMap.put(SHIFT_RIGHT, "Right Shift"); + modifiersMap.put(ALT_RIGHT, "Right Alt"); + modifiersMap.put(GUI_RIGHT, "Right GUI"); + } + + public static final SparseArray keyMap; + static + { + keyMap = new SparseArray(); + keyMap.put(0, "None"); + keyMap.put(KEY_ENTER, "Enter"); + keyMap.put(KEY_ESCAPE , "Esc"); + keyMap.put(KEY_BACKSPACE , "Backspace"); + keyMap.put(KEY_TAB , "Tab"); + keyMap.put(KEY_SPACEBAR , "Space"); + + keyMap.put(KEY_CAPS_LOCK , "CapsLock"); + + keyMap.put(KEY_1 , "1"); + keyMap.put(KEY_2 , "2"); + keyMap.put(KEY_3 , "3"); + keyMap.put(KEY_4 , "4"); + keyMap.put(KEY_5 , "5"); + keyMap.put(KEY_6 , "6"); + keyMap.put(KEY_7 , "7"); + keyMap.put(KEY_8 , "8"); + keyMap.put(KEY_9 , "9"); + keyMap.put(KEY_0 , "0"); + + keyMap.put(KEY_F1 , "F1"); + keyMap.put(KEY_F2 , "F2"); + keyMap.put(KEY_F3 , "F3"); + keyMap.put(KEY_F4 , "F4"); + keyMap.put(KEY_F5 , "F5"); + keyMap.put(KEY_F6 , "F6"); + keyMap.put(KEY_F7 , "F7"); + keyMap.put(KEY_F8 , "F8"); + keyMap.put(KEY_F9 , "F9"); + keyMap.put(KEY_F10 , "F10"); + keyMap.put(KEY_F11 , "F11"); + keyMap.put(KEY_F12 , "F12"); + + keyMap.put(KEY_PRINT_SCREEN , "Print Scrn"); + keyMap.put(KEY_SCROLL_LOCK , "ScrollLock"); + keyMap.put(KEY_PASUE , "Pause Break"); + keyMap.put(KEY_INSERT , "Insert"); + keyMap.put(KEY_HOME , "Home"); + keyMap.put(KEY_PAGE_UP , "PageUp"); + keyMap.put(KEY_DELETE , "Delete"); + keyMap.put(KEY_END , "End"); + keyMap.put(KEY_PAGE_DOWN , "PageDown"); + + keyMap.put(KEY_ARROW_RIGHT , "Right Arrow"); + keyMap.put(KEY_ARROW_LEFT , "Left Arrow"); + keyMap.put(KEY_ARROW_DOWN , "Down Arrow"); + keyMap.put(KEY_ARROW_UP , "Up Arrow"); + + keyMap.put(KEY_NUM_LOCK , "NumLock"); + keyMap.put(KEY_NUM_SLASH , "Num /"); + keyMap.put(KEY_NUM_STAR , "Num *"); + keyMap.put(KEY_NUM_MINUS , "Num -"); + keyMap.put(KEY_NUM_PLUS , "Num +"); + keyMap.put(KEY_NUM_ENTER , "Num Enter"); + keyMap.put(KEY_NUM_1 , "Num 1"); + keyMap.put(KEY_NUM_2 , "Num 2"); + keyMap.put(KEY_NUM_3 , "Num 3"); + keyMap.put(KEY_NUM_4 , "Num 4"); + keyMap.put(KEY_NUM_5 , "Num 5"); + keyMap.put(KEY_NUM_6 , "Num 6"); + keyMap.put(KEY_NUM_7 , "Num 7"); + keyMap.put(KEY_NUM_8 , "Num 8"); + keyMap.put(KEY_NUM_9 , "Num 9"); + keyMap.put(KEY_NUM_0 , "Num 0"); + keyMap.put(KEY_NUM_DOT , "Num ."); + + keyMap.put(KEY_A , "A"); + keyMap.put(KEY_B , "B"); + keyMap.put(KEY_C , "C"); + keyMap.put(KEY_D , "D"); + keyMap.put(KEY_E , "E"); + keyMap.put(KEY_F , "F"); + keyMap.put(KEY_G , "G"); + keyMap.put(KEY_H , "H"); + keyMap.put(KEY_I , "I"); + keyMap.put(KEY_J , "J"); + keyMap.put(KEY_K , "K"); + keyMap.put(KEY_L , "L"); + keyMap.put(KEY_M , "M"); + keyMap.put(KEY_N , "N"); + keyMap.put(KEY_O , "O"); + keyMap.put(KEY_P , "P"); + keyMap.put(KEY_Q , "Q"); + keyMap.put(KEY_R , "R"); + keyMap.put(KEY_S , "S"); + keyMap.put(KEY_T , "T"); + keyMap.put(KEY_U , "U"); + keyMap.put(KEY_V , "V"); + keyMap.put(KEY_W , "W"); + keyMap.put(KEY_X , "X"); + keyMap.put(KEY_Y , "Y"); + keyMap.put(KEY_Z , "Z"); + + keyMap.put(KEY_MINUS , "-"); + keyMap.put(KEY_EQUALS , "="); + keyMap.put(KEY_LEFT_BRACKET , "["); + keyMap.put(KEY_RIGHT_BRACKET , "]"); + keyMap.put(KEY_BACKSLASH , "\\"); + //keyMap.put(KEY_GRAVE , "`"); + keyMap.put(KEY_SEMICOLON , ";"); + keyMap.put(KEY_APOSTROPHE , "'"); + keyMap.put(KEY_GRAVE , "`"); + keyMap.put(KEY_COMA , ","); + keyMap.put(KEY_DOT , "."); + keyMap.put(KEY_SLASH , "/"); + + keyMap.put(KEY_APPLICATION , "Application"); + } + + public static final int[] ASCIItoHID = { + 0, //000 + 0, //001 + 0, //002 + 0, //003 + 0, //004 + 0, //005 + 0, //006 + 0, //007 + 0, //008 + 0, //009 + 0, //010 + 0, //011 + 0, //012 + 0, //013 + 0, //014 + 0, //015 + 0, //016 + 0, //017 + 0, //018 + 0, //019 + 0, //020 + 0, //021 + 0, //022 + 0, //023 + 0, //024 + 0, //025 + 0, //026 + 0, //027 + 0, //028 + 0, //029 + 0, //030 + 0, //031 + 44, //032 space + 128 + 30, //033 ! [SHIFT] + 128 + 52, //034 " [SHIFT] + 128 + 32, //035 # [SHIFT] + 128 + 33, //036 $ [SHIFT] + 128 + 34, //037 % [SHIFT] + 128 + 36, //038 & [SHIFT] + 52, //039 ' + 128 + 38, //040 ( [SHIFT] + 128 + 39, //041 ) [SHIFT] + 128 + 37, //042 * [SHIFT] + 128 + 46, //043 + [SHIFT] + 54, //044 , + 45, //045 - (-) + 55, //046 . (.) + 56, //047 / + 39, //048 0 + 30, //049 1 + 31, //050 2 + 32, //051 3 + 33, //052 4 + 34, //053 5 + 35, //054 6 + 36, //055 7 + 37, //056 8 + 38, //057 9 + 128 + 51, //058 : [SHIFT] + 51, //059 ; + 128 + 54, //060 < [SHIFT] + 46, //061 = + 128 + 55, //062 > [SHIFT] + 128 + 56, //063 ? [SHIFT] + 128 + 31, //064 @ [SHIFT] + 128 + 4, //065 A [SHIFT] + 128 + 5, //066 B [SHIFT] + 128 + 6, //067 C [SHIFT] + 128 + 7, //068 D [SHIFT] + 128 + 8, //069 E [SHIFT] + 128 + 9, //070 F [SHIFT] + 128 + 10, //071 G [SHIFT] + 128 + 11, //072 H [SHIFT] + 128 + 12, //073 I [SHIFT] + 128 + 13, //074 J [SHIFT] + 128 + 14, //075 K [SHIFT] + 128 + 15, //076 L [SHIFT] + 128 + 16, //077 M [SHIFT] + 128 + 17, //078 N [SHIFT] + 128 + 18, //079 O [SHIFT] + 128 + 19, //080 P [SHIFT] + 128 + 20, //081 Q [SHIFT] + 128 + 21, //082 R [SHIFT] + 128 + 22, //083 S [SHIFT] + 128 + 23, //084 T [SHIFT] + 128 + 24, //085 U [SHIFT] + 128 + 25, //086 V [SHIFT] + 128 + 26, //087 W [SHIFT] + 128 + 27, //088 X [SHIFT] + 128 + 28, //089 Y [SHIFT] + 128 + 29, //090 Z [SHIFT] + 47, //091 [ + 49, /*092 \ */ + 48, //093 ] + 128 + 35, //094 ^ [SHIFT] + 128 + 45, //095 _ [SHIFT] (underscore) + 128 + 53, //096 ` [SHIFT] (grave accent) + 4, //097 a + 5, //098 b + 6, //099 c + 7, //100 d + 8, //101 e + 9, //102 f + 10, //103 g + 11, //104 h + 12, //105 i + 13, //106 j + 14, //107 k + 15, //108 l + 16, //109 m + 17, //110 n + 18, //111 o + 19, //112 p + 20, //113 q + 21, //114 r + 22, //115 s + 23, //116 t + 24, //117 u + 25, //118 v + 26, //119 w + 27, //120 x + 28, //121 y + 29, //122 z + 128 + 47, //123 { [SHIFT] + 128 + 49, //124 | [SHIFT] + 128 + 48, //125 } [SHIFT] + 128 + 53, //126 ~ [SHIFT] + 0 //127 just in case... + }; + + public static char getChar(byte keyCode) { + for (int i = 0; i < ASCIItoHID.length; i++) { + if (ASCIItoHID[i] == keyCode) { + return (char)i; + } + } + return 0; + } + + public static byte getKeyCode(char c) { + return (byte)ASCIItoHID[c]; //TODO range + } + + public static int getKeyCode(int c) { + return ASCIItoHID[c]; //TODO range + } + + public static String modifiersToString(byte modifiers) { + String result = "None"; + boolean first = true; + byte mod; + for (int i = 0; i < 8; i++) { + mod = (byte)(CTRL_LEFT << i); + if ((modifiers & mod) != 0) { + if ( !first) { + result += ", "; + } else { + result = ""; + } + first = false; + result += modifiersMap.get(mod); + } + } + + return result; + } + + public static String keyToString(byte key) { + String result = keyMap.get(key); + if (result == null) { + result = "Unknown"; + } + return result; + } +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDReport.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDReport.java new file mode 100644 index 00000000..28cce791 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDReport.java @@ -0,0 +1,8 @@ +package com.inputstick.api.hid; + +public abstract class HIDReport { + + public abstract byte[] getBytes(); + public abstract int getBytesCount(); + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDTransaction.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDTransaction.java new file mode 100644 index 00000000..39de4683 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDTransaction.java @@ -0,0 +1,56 @@ +package com.inputstick.api.hid; + +import java.util.LinkedList; + +public class HIDTransaction { + + private int mID; + private LinkedList reports; + + public HIDTransaction() { + reports = new LinkedList(); + } + + public void addReport(HIDReport report) { + reports.add(report); + } + + public int getReportsCount() { + return reports.size(); + } + + public void setID(int id) { + mID = id; + } + + public int getID() { + return mID; + } + + public boolean hasNext() { + return !reports.isEmpty(); + } + + public byte[] getNextReport() { + return reports.poll().getBytes(); + } + + public HIDReport getHIDReportAt(int pos) { + return reports.get(pos); + } + + public HIDTransaction split(int n) { + HIDTransaction result = new HIDTransaction(); + HIDReport report; + if (n <= reports.size()) { + while(n > 0) { + report = reports.poll(); + result.addReport(report); + n--; + } + } + + return result; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDTransactionQueue.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDTransactionQueue.java new file mode 100644 index 00000000..f0cecdbd --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/HIDTransactionQueue.java @@ -0,0 +1,324 @@ +package com.inputstick.api.hid; + +import java.util.LinkedList; +import java.util.Timer; +import java.util.TimerTask; +import java.util.Vector; + +import com.inputstick.api.ConnectionManager; +import com.inputstick.api.HIDInfo; +import com.inputstick.api.OnEmptyBufferListener; +import com.inputstick.api.Packet; +import com.inputstick.api.basic.InputStickHID; + +public class HIDTransactionQueue { + + private static final int BUFFER_SIZE = 32; + private static final int BT_DELAY = 50; //additional delay for BT overhead + + private static final int MAX_PACKETS_PER_UPDATE = 10; + private static final int MAX_IMMEDIATE_PACKETS = 3; + + private final LinkedList queue; + private final ConnectionManager mConnectionManager; + private final byte cmd; + private boolean ready; + + private int mInterfaceType; + private boolean mustNotify; + + private Timer t; + private boolean timerCancelled; + private boolean sentAhead; + private long lastTime; + private long minNextTime; + private int lastReports; + + + // >= FW 0.93 + private boolean bufferInitDone; + private boolean constantUpdateMode; + private int bufferFreeSpace; + private int immediatePacketsLeft; + private int packetsSentSinceLastUpdate; + + private int interfaceReadyCnt; //fix BT4.0 lost packet problem + + public HIDTransactionQueue(int interfaceType, ConnectionManager connectionManager) { + constantUpdateMode = false; + bufferFreeSpace = BUFFER_SIZE; + interfaceReadyCnt = 0; + + queue = new LinkedList(); + mConnectionManager = connectionManager; + ready = false; + sentAhead = false; + minNextTime = 0; + + mustNotify = false; + + mInterfaceType = interfaceType; + switch (interfaceType) { + case InputStickHID.INTERFACE_KEYBOARD: + cmd = Packet.CMD_HID_DATA_KEYB; + //TODO mod + //cmd = Packet.CMD_HID_DATA_KEYB_FAST; + break; + case InputStickHID.INTERFACE_MOUSE: + cmd = Packet.CMD_HID_DATA_MOUSE; + break; + case InputStickHID.INTERFACE_CONSUMER: + cmd = Packet.CMD_HID_DATA_CONSUMER; + break; + default: + cmd = Packet.CMD_DUMMY; + } + } + + private int sendNext(int maxReports) { + HIDTransaction transaction; + + //assume there is at least 1 element in queue + transaction = queue.peek(); + if (transaction.getReportsCount() > maxReports) { + // v0.92 + if (maxReports < BUFFER_SIZE) { + //don't split transactions until there is no other way left! + return 0; + } + + //transaction too big to fit single packet! split + transaction = transaction.split(BUFFER_SIZE); + } else { + queue.removeFirst(); + } + + byte reports = 0; + ready = false; + Packet p = new Packet(false, cmd, reports); + + while (transaction.hasNext()) { + p.addBytes(transaction.getNextReport()); + //TODO mod + //byte[] r = transaction.getNextReport(); + //p.addByte(r[0]); + //p.addByte(r[2]); + + reports++; + } + + while(true) { + if (queue.isEmpty()) { + break; + } + + transaction = queue.peek(); + if (reports + transaction.getReportsCount() < maxReports) { + queue.removeFirst(); + while (transaction.hasNext()) { + p.addBytes(transaction.getNextReport()); + //TODO mod + //byte[] r = transaction.getNextReport(); + //p.addByte(r[0]); + //p.addByte(r[2]); + + reports++; + } + } else { + break; + } + } + + //!! total number of reports must be < 32 ! (max packet limitation) + p.modifyByte(1, reports); //set reports count + mConnectionManager.sendPacket(p); + + interfaceReadyCnt = 0; + lastReports = reports; + lastTime = System.currentTimeMillis(); + minNextTime = lastTime + (lastReports * 4) + BT_DELAY; + + if (queue.isEmpty()) { + notifyOnLocalBufferEmpty(); + } + + return reports; + } + + private void notifyOnRemoteBufferEmpty() { + Vector listeners = InputStickHID.getBufferEmptyListeners(); + for (OnEmptyBufferListener listener : listeners) { + listener.onRemoteBufferEmpty(mInterfaceType); + } + } + + private void notifyOnLocalBufferEmpty() { + Vector listeners = InputStickHID.getBufferEmptyListeners(); + for (OnEmptyBufferListener listener : listeners) { + listener.onLocalBufferEmpty(mInterfaceType); + } + } + + public synchronized boolean isLocalBufferEmpty() { + return queue.isEmpty(); + } + + public synchronized boolean isRemoteBufferEmpty() { + if ((queue.isEmpty()) && (bufferFreeSpace == BUFFER_SIZE)) { + return true; + } + + if (queue.isEmpty() && ( !mustNotify)) { + return true; + } else { + return false; + } + } + + public synchronized void clearBuffer() { + queue.clear(); + } + + public synchronized void addTransaction(HIDTransaction transaction) { + if ( !bufferInitDone) { + queue.add(transaction); + return; + } + + + if (constantUpdateMode) { + queue.add(transaction); + sendToBuffer(true); + return; + } + + + mustNotify = true; + //using sentAhead will slow down mouse. FW0.92 will solve the problems + if ((queue.isEmpty()) && (System.currentTimeMillis() > minNextTime) /*&& ( !sentAhead)*/) { + sentAhead = true; + ready = true; + } + + queue.add(transaction); + if (ready) { + sendNext(BUFFER_SIZE); + } + } + + private synchronized void timerAction() { + if ( !timerCancelled) { + if (sentAhead) { + deviceReady(null, 0); //will set sentAhead to false; + sentAhead = true; //restore value + } else { + deviceReady(null, 0); + } + } + } + + public synchronized void deviceReady(HIDInfo hidInfo, int reportsSentToHost) { + //it is possible that in the meantime some packets has been sent to IS!!! + + bufferInitDone = true; + + if (hidInfo != null) { + if (hidInfo.isSentToHostInfoAvailable()) { + + //BT4.0 lost packets fix: + if (bufferFreeSpace < BUFFER_SIZE) { + boolean interfaceReady = false; + if (mInterfaceType == InputStickHID.INTERFACE_KEYBOARD) { + interfaceReady = hidInfo.isKeyboardReady(); + } + if (mInterfaceType == InputStickHID.INTERFACE_MOUSE) { + interfaceReady = hidInfo.isMouseReady(); + } + if (mInterfaceType == InputStickHID.INTERFACE_CONSUMER) { + interfaceReady = hidInfo.isConsumerReady(); + } + if (interfaceReady) { + interfaceReadyCnt++; + if (interfaceReadyCnt == 10) { + bufferFreeSpace = BUFFER_SIZE; + } + } else { + interfaceReadyCnt = 0; + } + } + + + constantUpdateMode = true; + // >= FW 0.93 + bufferFreeSpace += reportsSentToHost; + if ((bufferFreeSpace == BUFFER_SIZE) && (queue.isEmpty())) { + notifyOnRemoteBufferEmpty(); + } + immediatePacketsLeft = MAX_IMMEDIATE_PACKETS; + //reportsSentSinceLastUpdate = 0; + packetsSentSinceLastUpdate = 0; + sendToBuffer(false); + return; + } + } + + + + long now = System.currentTimeMillis(); + //System.out.println("v90 HID update"); + if (now < minNextTime) { + //set timer, just in case if deviceReady won't be called again + timerCancelled = false; + t = new Timer(); + t.schedule(new TimerTask() { + @Override + public void run() { + timerAction(); + } + }, (minNextTime - now + 1)); + } else { + timerCancelled = true; + sentAhead = false; + if (!queue.isEmpty()) { + sendNext(BUFFER_SIZE); + } else { + ready = true; + //queue is empty, InputStick reported that buffer is empty, data was added since last notification + if (mustNotify) { + notifyOnRemoteBufferEmpty(); + mustNotify = false; + } + } + } + } + + public synchronized void sendToBuffer(boolean justAdded) { + if ((justAdded) && (immediatePacketsLeft <= 0)) { + return; + } + + if ( !InputStickHID.isReady()) { + return; + } + + if (queue.isEmpty()) { + return; + } + if (bufferFreeSpace <= 0) { + return; + } + if (packetsSentSinceLastUpdate >= MAX_PACKETS_PER_UPDATE) { + return; + } + + int reportsSent = sendNext(bufferFreeSpace); + if (reportsSent > 0) { + if (justAdded) { + immediatePacketsLeft --; + } + bufferFreeSpace -= reportsSent; + packetsSentSinceLastUpdate ++; + } + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/KeyboardReport.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/KeyboardReport.java new file mode 100644 index 00000000..7ece9b62 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/KeyboardReport.java @@ -0,0 +1,36 @@ +package com.inputstick.api.hid; + +public class KeyboardReport extends HIDReport { + + public static final int SIZE = 8; + + private byte[] data; + + public KeyboardReport(byte modifier, byte key0, byte key1, byte key2, byte key3, byte key4, byte key5) { + data = new byte[SIZE]; + data[0] = modifier; + data[2] = key0; + data[3] = key1; + data[4] = key2; + data[5] = key3; + data[6] = key4; + data[7] = key5; + } + + public KeyboardReport() { + this((byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0); + } + + public KeyboardReport(byte modifier, byte key) { + this(modifier, key, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0); + } + + public byte[] getBytes() { + return data; + } + + public int getBytesCount() { + return SIZE; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/MouseReport.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/MouseReport.java new file mode 100644 index 00000000..8454513e --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/hid/MouseReport.java @@ -0,0 +1,29 @@ +package com.inputstick.api.hid; + +public class MouseReport extends HIDReport { + + public static final int SIZE = 4; + + private byte[] data; + + public MouseReport(byte buttons, byte x, byte y, byte wheel) { + data = new byte[SIZE]; + data[0] = buttons; + data[1] = x; + data[2] = y; + data[3] = wheel; + } + + public MouseReport() { + this((byte)0, (byte)0, (byte)0, (byte)0); + } + + public byte[] getBytes() { + return data; + } + + public int getBytesCount() { + return SIZE; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/BasicInitManager.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/BasicInitManager.java new file mode 100644 index 00000000..a2082406 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/BasicInitManager.java @@ -0,0 +1,97 @@ +package com.inputstick.api.init; + +import android.os.Handler; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Packet; + + +public class BasicInitManager extends InitManager { + + private int lastStatusParam; + private Handler handler; + private boolean cancelled; + + public BasicInitManager(byte[] key) { + super(key); + lastStatusParam = 0; + } + + + @Override + public void onConnected() { + lastStatusParam = 0; + cancelled = false; + initDone = false; + sendPacket(new Packet(true, Packet.CMD_RUN_FW)); + + handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + if ((!cancelled) && ( !initDone)) { + sendPacket(new Packet(true, Packet.CMD_RUN_FW)); + } + } + }, 1000); + + handler.postDelayed(new Runnable() { + @Override + public void run() { + if ((!cancelled) && ( !initDone)) { + mListener.onInitFailure(InputStickError.ERROR_INIT_TIMEDOUT); + } + } + }, 2000); + } + + @Override + public void onDisconnected() { + cancelled = true; + } + + @Override + public void onData(byte[] data) { + byte cmd = data[0]; + byte respCode = data[1]; + byte param = data[1]; + + switch (cmd) { + case Packet.CMD_RUN_FW: + sendPacket(new Packet(true, Packet.CMD_FW_INFO)); + break; + case Packet.CMD_FW_INFO: + onFWInfo(data, true, true, new Packet(true, Packet.CMD_INIT)); //TODO next FW: params! + break; + case Packet.CMD_INIT: + if (respCode == Packet.RESP_OK) { + initDone = true; + sendPacket(new Packet(true, Packet.CMD_HID_STATUS_REPORT)); + } else { + mListener.onInitFailure(respCode); + } + break; + case Packet.CMD_INIT_AUTH: + initDone = onAuth(data, true, new Packet(true, Packet.CMD_INIT)); //TODO next FW: params! + break; + case Packet.CMD_HID_STATUS: + if (mKey == null) { + initDone = true; + } + + if (initDone) { + if (param != lastStatusParam) { + lastStatusParam = param; + if (param == 0x05) { + mListener.onInitReady(); + } else { + mListener.onInitNotReady(); + } + } + } + break; + } + } + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/DeviceInfo.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/DeviceInfo.java new file mode 100644 index 00000000..9e1dc49e --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/DeviceInfo.java @@ -0,0 +1,93 @@ +package com.inputstick.api.init; + +public class DeviceInfo { + + private int firmwareType; + private int versionMajor; + private int versionMinor; + private int versionHardware; + private int securityStatus; + + private boolean passwordProtected; + + public DeviceInfo(byte[] data) { + //cmd, param + firmwareType = data[2]; + versionMajor = data[3]; + versionMinor = data[4]; + versionHardware = data[5]; + + + //6,7,8,9 + //10,11,12,13 + //14,15,16,17 + + //18,19 + securityStatus = data[19]; + if (data[20] == 0) { + passwordProtected = false; + } else { + passwordProtected = true; + } + } + + public int getSecurityStatus() { + return securityStatus; + } + + public boolean isAuthenticated() { + return ((securityStatus & 0x10) != 0); + } + + public boolean isUnlocked() { + if (getFirmwareVersion() < 96) { + return true; + } else { + return ((securityStatus & 0x08) != 0); + } + } + + public int getFirmwareType() { + return firmwareType; + } + + public boolean isPasswordProtected() { + return passwordProtected; + } + + public int getVersionMinor() { + return versionMinor; + } + + public int getVersionMajor() { + return versionMajor; + } + + public int getHardwareVersion() { + return versionHardware; + } + + public int getFirmwareVersion() { + return (versionMajor) * 100 + versionMinor; + } + + + + public boolean supportsEncryption() { + return (getFirmwareVersion() >= 91); + } + + public boolean supportsPinChange() { + return (getFirmwareVersion() >= 97); + } + + public boolean supportsGamepad() { + return (getFirmwareVersion() >= 97); + } + + public boolean supportsRestoreOptions() { + return (getFirmwareVersion() >= 98); + } + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/InitManager.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/InitManager.java new file mode 100644 index 00000000..d4f8e445 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/InitManager.java @@ -0,0 +1,112 @@ +package com.inputstick.api.init; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Packet; +import com.inputstick.api.PacketManager; + +public class InitManager { + + public static final int DEFAULT_INIT_TIMEOUT = 60000; //60s init timeout + + protected PacketManager mPacketManager; + protected InitManagerListener mListener; + protected byte[] mKey; + protected DeviceInfo mInfo; + protected boolean initDone; + + public InitManager(byte[] key) { + mKey = key; + } + + + public DeviceInfo getDeviceInfo() { + return mInfo; + } + + public boolean isEncrypted() { + return mPacketManager.isEncrypted(); + } + + + public void init(InitManagerListener listener, PacketManager packetManager) { + mListener = listener; + mPacketManager = packetManager; + + initDone = false; + } + + public void onConnected() { + mListener.onInitReady(); + } + + public void onDisconnected() { + } + + public void onData(byte[] data) { + //byte cmd = data[0]; + //byte param = data[1]; + } + + public void sendPacket(Packet p) { + mPacketManager.sendPacket(p); + } + + public void onFWInfo(byte[] data, boolean authenticate, boolean enableEncryption, Packet sendNext) { + mInfo = new DeviceInfo(data); + + if (authenticate) { + if (mInfo.isPasswordProtected()) { + if (mKey != null) { + //authenticate + sendPacket(mPacketManager.encPacket(enableEncryption)); + } else { + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NO_KEY); + } + } else { + if (mKey != null) { + //possible scenarios: FW upgrade / password removed using other device/app / tampering! + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_PROTECTED); + } + sendPacket(sendNext); + } + } else { + sendPacket(sendNext); + } + } + + public boolean onAuth(byte[] data, boolean enableOutEncryption, Packet sendNext) { + byte respCode = data[1]; + + switch (respCode) { + case Packet.RESP_OK: + byte[] cmp = new byte[16]; + //TODO check length! + System.arraycopy(data, 2, cmp, 0, 16); + if (mPacketManager.setEncryption(cmp, enableOutEncryption)) { + sendPacket(sendNext); + return true; + } else { + mListener.onInitFailure(InputStickError.ERROR_SECURITY_CHALLENGE); + } + break; + + case 0x20: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_INVALID_KEY); + break; + + case 0x21: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_PROTECTED); + break; + + case Packet.RESP_UNKNOWN_CMD: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_SUPPORTED); + break; + + default: + mListener.onInitFailure(InputStickError.ERROR_SECURITY); + } + return false; + + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/InitManagerListener.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/InitManagerListener.java new file mode 100644 index 00000000..10cff787 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/init/InitManagerListener.java @@ -0,0 +1,9 @@ +package com.inputstick.api.init; + +public interface InitManagerListener { + + public void onInitReady(); + public void onInitNotReady(); + public void onInitFailure(int code); + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/DanishLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/DanishLayout.java new file mode 100644 index 00000000..6d79ea63 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/DanishLayout.java @@ -0,0 +1,390 @@ +package com.inputstick.api.layout; + +public class DanishLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "da-DK"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //da-DK + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 53, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 64, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 0, 49, 0, 0 }, // ' + { 40, 2, 37, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 49, 0, 0 }, // * + { 43, 0, 45, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 64, 37, 0, 0 }, // [ + { 92, 64, 100, 0, 0 }, // \ + { 93, 64, 38, 0, 0 }, // ] + { 94, 0, 44, 2, 48 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 0, 44, 2, 46 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 64, 36, 0, 0 }, // { + { 124, 64, 46, 0, 0 }, // | + { 125, 64, 39, 0, 0 }, // } + { 126, 0, 44, 64, 48 }, // ~ + { 163, 64, 32, 0, 0 }, // ? + { 164, 2, 33, 0, 0 }, // + { 167, 2, 53, 0, 0 }, // + { 168, 0, 44, 0, 48 }, // + { 180, 0, 44, 0, 46 }, // + { 181, 64, 16, 0, 0 }, // + { 189, 0, 53, 0, 0 }, // ? + { 192, 2, 4, 2, 46 }, // ? + { 193, 2, 4, 0, 46 }, // + { 194, 2, 4, 2, 48 }, // + { 195, 2, 4, 64, 48 }, // ? + { 196, 2, 4, 0, 48 }, // + { 197, 2, 47, 0, 0 }, // ? + { 198, 2, 51, 0, 0 }, // ? + { 200, 2, 8, 2, 46 }, // ? + { 201, 2, 8, 0, 46 }, // + { 202, 2, 8, 2, 48 }, // ? + { 203, 2, 8, 0, 48 }, // + { 204, 2, 12, 2, 46 }, // ? + { 205, 2, 12, 0, 46 }, // + { 206, 2, 12, 2, 48 }, // + { 207, 2, 12, 0, 48 }, // ? + { 209, 2, 17, 64, 48 }, // ? + { 210, 2, 18, 2, 46 }, // ? + { 211, 2, 18, 0, 46 }, // + { 212, 2, 18, 2, 48 }, // + { 213, 2, 18, 64, 48 }, // ? + { 214, 2, 18, 0, 48 }, // + { 216, 2, 52, 0, 0 }, // ? + { 217, 2, 24, 2, 46 }, // ? + { 218, 2, 24, 0, 46 }, // + { 219, 2, 24, 2, 48 }, // ? + { 220, 2, 24, 0, 48 }, // + { 221, 2, 28, 0, 46 }, // + { 224, 0, 4, 2, 46 }, // ? + { 225, 0, 4, 0, 46 }, // + { 226, 0, 4, 2, 48 }, // + { 227, 0, 4, 64, 48 }, // ? + { 228, 0, 4, 0, 48 }, // + { 229, 0, 47, 0, 0 }, // ? + { 230, 0, 51, 0, 0 }, // ? + { 232, 0, 8, 2, 46 }, // ? + { 233, 0, 8, 0, 46 }, // + { 234, 0, 8, 2, 48 }, // ? + { 235, 0, 8, 0, 48 }, // + { 236, 0, 12, 2, 46 }, // ? + { 237, 0, 12, 0, 46 }, // + { 238, 0, 12, 2, 48 }, // + { 239, 0, 12, 0, 48 }, // ? + { 241, 0, 17, 64, 48 }, // ? + { 242, 0, 18, 2, 46 }, // ? + { 243, 0, 18, 0, 46 }, // + { 244, 0, 18, 2, 48 }, // + { 245, 0, 18, 64, 48 }, // ? + { 246, 0, 18, 0, 48 }, // + { 248, 0, 52, 0, 0 }, // ? + { 249, 0, 24, 2, 46 }, // ? + { 250, 0, 24, 0, 46 }, // + { 251, 0, 24, 2, 48 }, // ? + { 252, 0, 24, 0, 48 }, // + { 253, 0, 28, 0, 46 }, // + { 255, 0, 28, 0, 48 }, // ? + { 8364, 64, 34, 0, 0 }, // + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x0021 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x0022 , -1 , 0x0040 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x0023 , -1 , 0x00a3 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x00a4 , -1 , 0x0024 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x0025 , -1 , 0x20ac , -1 } , + /* 7 */ { 0 , (int)'6' , 0x0026 , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , 0x007b , -1 } , + /* 9 */ { 0 , (int)'8' , 0x0028 , -1 , 0x005b , -1 } , + /* 0a */ { 0 , (int)'9' , 0x0029 , -1 , 0x005d , -1 } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , 0x007d , -1 } , + /* 0c */ { 0 , 0x002b , 0x003f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x00b4 , 0x0060 , -1 , 0x007c , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 1 , 0x00e5 , 0x00c5 , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x00a8 , 0x005e , 0x001d , 0x007e , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 1 , 0x00e6 , 0x00c6 , -1 , -1 , -1 } , + /* 28 */ { 1 , 0x00f8 , 0x00d8 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x00bd , 0x00a7 , 0x001c , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x0027 , 0x002a , -1 , -1 , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , 0x001c , 0x005c , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x00b4, 0x0060, 0x00a8, 0x005e, 0x007e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0061 , 0x00e1 }, + { 0x00b4 , 0x0065 , 0x00e9 }, + { 0x00b4 , 0x0075 , 0x00fa }, + { 0x00b4 , 0x0069 , 0x00ed }, + { 0x00b4 , 0x0079 , 0x00fd }, + { 0x00b4 , 0x006f , 0x00f3 }, + { 0x00b4 , 0x0041 , 0x00c1 }, + { 0x00b4 , 0x0045 , 0x00c9 }, + { 0x00b4 , 0x0055 , 0x00da }, + { 0x00b4 , 0x0049 , 0x00cd }, + { 0x00b4 , 0x0059 , 0x00dd }, + { 0x00b4 , 0x004f , 0x00d3 }, + { 0x00b4 , 0x0020 , 0x00b4 }, + { 0x0060 , 0x0061 , 0x00e0 }, + { 0x0060 , 0x0065 , 0x00e8 }, + { 0x0060 , 0x0075 , 0x00f9 }, + { 0x0060 , 0x0069 , 0x00ec }, + { 0x0060 , 0x006f , 0x00f2 }, + { 0x0060 , 0x0041 , 0x00c0 }, + { 0x0060 , 0x0045 , 0x00c8 }, + { 0x0060 , 0x0055 , 0x00d9 }, + { 0x0060 , 0x0049 , 0x00cc }, + { 0x0060 , 0x004f , 0x00d2 }, + { 0x0060 , 0x0020 , 0x0060 }, + { 0x00a8 , 0x0061 , 0x00e4 }, + { 0x00a8 , 0x0065 , 0x00eb }, + { 0x00a8 , 0x0075 , 0x00fc }, + { 0x00a8 , 0x0069 , 0x00ef }, + { 0x00a8 , 0x0079 , 0x00ff }, + { 0x00a8 , 0x006f , 0x00f6 }, + { 0x00a8 , 0x0041 , 0x00c4 }, + { 0x00a8 , 0x0045 , 0x00cb }, + { 0x00a8 , 0x0055 , 0x00dc }, + { 0x00a8 , 0x0049 , 0x00cf }, + { 0x00a8 , 0x004f , 0x00d6 }, + { 0x00a8 , 0x0020 , 0x00a8 }, + { 0x005e , 0x0061 , 0x00e2 }, + { 0x005e , 0x0065 , 0x00ea }, + { 0x005e , 0x0075 , 0x00fb }, + { 0x005e , 0x0069 , 0x00ee }, + { 0x005e , 0x006f , 0x00f4 }, + { 0x005e , 0x0041 , 0x00c2 }, + { 0x005e , 0x0045 , 0x00ca }, + { 0x005e , 0x0055 , 0x00db }, + { 0x005e , 0x0049 , 0x00ce }, + { 0x005e , 0x004f , 0x00d4 }, + { 0x005e , 0x0020 , 0x005e }, + { 0x007e , 0x006e , 0x00f1 }, + { 0x007e , 0x0061 , 0x00e3 }, + { 0x007e , 0x006f , 0x00f5 }, + { 0x007e , 0x004e , 0x00d1 }, + { 0x007e , 0x0041 , 0x00c3 }, + { 0x007e , 0x004f , 0x00d5 }, + { 0x007e , 0x0020 , 0x007e }, + + }; + + private static DanishLayout instance = new DanishLayout(); + + private DanishLayout() { + } + + public static DanishLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} \ No newline at end of file diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/DvorakLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/DvorakLayout.java new file mode 100644 index 00000000..a5cd6306 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/DvorakLayout.java @@ -0,0 +1,269 @@ +package com.inputstick.api.layout; + +public class DvorakLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "en-DV"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //en-DV + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 45, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 46, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 20, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 36, 0, 0 }, // & + { 39, 0, 20, 0, 0 }, // ' + { 40, 2, 38, 0, 0 }, // ( + { 41, 2, 39, 0, 0 }, // ) + { 42, 2, 37, 0, 0 }, // * + { 43, 2, 48, 0, 0 }, // + + { 44, 0, 26, 0, 0 }, // , + { 45, 0, 52, 0, 0 }, // - + { 46, 0, 8, 0, 0 }, // . + { 47, 0, 47, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 29, 0, 0 }, // : + { 59, 0, 29, 0, 0 }, // ; + { 60, 2, 26, 0, 0 }, // < + { 61, 0, 48, 0, 0 }, // = + { 62, 2, 8, 0, 0 }, // > + { 63, 2, 47, 0, 0 }, // ? + { 64, 2, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 17, 0, 0 }, // B + { 67, 2, 12, 0, 0 }, // C + { 68, 2, 11, 0, 0 }, // D + { 69, 2, 7, 0, 0 }, // E + { 70, 2, 28, 0, 0 }, // F + { 71, 2, 24, 0, 0 }, // G + { 72, 2, 13, 0, 0 }, // H + { 73, 2, 10, 0, 0 }, // I + { 74, 2, 6, 0, 0 }, // J + { 75, 2, 25, 0, 0 }, // K + { 76, 2, 19, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 15, 0, 0 }, // N + { 79, 2, 22, 0, 0 }, // O + { 80, 2, 21, 0, 0 }, // P + { 81, 2, 27, 0, 0 }, // Q + { 82, 2, 18, 0, 0 }, // R + { 83, 2, 51, 0, 0 }, // S + { 84, 2, 14, 0, 0 }, // T + { 85, 2, 9, 0, 0 }, // U + { 86, 2, 55, 0, 0 }, // V + { 87, 2, 54, 0, 0 }, // W + { 88, 2, 5, 0, 0 }, // X + { 89, 2, 23, 0, 0 }, // Y + { 90, 2, 56, 0, 0 }, // Z + { 91, 0, 45, 0, 0 }, // [ + { 92, 0, 49, 0, 0 }, // \ + { 93, 0, 46, 0, 0 }, // ] + { 94, 2, 35, 0, 0 }, // ^ + { 95, 2, 52, 0, 0 }, // _ + { 96, 0, 53, 0, 0 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 17, 0, 0 }, // b + { 99, 0, 12, 0, 0 }, // c + { 100, 0, 11, 0, 0 }, // d + { 101, 0, 7, 0, 0 }, // e + { 102, 0, 28, 0, 0 }, // f + { 103, 0, 24, 0, 0 }, // g + { 104, 0, 13, 0, 0 }, // h + { 105, 0, 10, 0, 0 }, // i + { 106, 0, 6, 0, 0 }, // j + { 107, 0, 25, 0, 0 }, // k + { 108, 0, 19, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 15, 0, 0 }, // n + { 111, 0, 22, 0, 0 }, // o + { 112, 0, 21, 0, 0 }, // p + { 113, 0, 27, 0, 0 }, // q + { 114, 0, 18, 0, 0 }, // r + { 115, 0, 51, 0, 0 }, // s + { 116, 0, 14, 0, 0 }, // t + { 117, 0, 9, 0, 0 }, // u + { 118, 0, 55, 0, 0 }, // v + { 119, 0, 54, 0, 0 }, // w + { 120, 0, 5, 0, 0 }, // x + { 121, 0, 23, 0, 0 }, // y + { 122, 0, 56, 0, 0 }, // z + { 123, 2, 45, 0, 0 }, // { + { 124, 2, 49, 0, 0 }, // | + { 125, 2, 46, 0, 0 }, // } + { 126, 2, 53, 0, 0 }, // ~ + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x021 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x040 , -1 , -1 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x023 , -1 , -1 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x024 , -1 , -1 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x025 , -1 , -1 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x05e , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x026 , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x02a , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x028 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x029 , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x05b , 0x07b , 0x01b , -1 , -1 } , + /* 0d */ { 0 , 0x05d , 0x07d , 0x01d , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 0 , 0x027 , 0x022 , -1 , -1 , -1 } , + /* 11 */ { 0 , 0x02c , 0x03c , -1 , -1 , -1 } , + /* 12 */ { 0 , 0x02e , 0x03e , -1 , -1 , -1 } , + /* 13 */ { 1 , 'p' , 'P' , -1 , -1 , -1 } , + /* 14 */ { 1 , 'y' , 'Y' , -1 , -1 , -1 } , + /* 15 */ { 1 , 'f' , 'F' , -1 , -1 , -1 } , + /* 16 */ { 1 , 'g' , 'G' , -1 , -1 , -1 } , + /* 17 */ { 1 , 'c' , 'C' , -1 , -1 , -1 } , + /* 18 */ { 1 , 'r' , 'R' , -1 , -1 , -1 } , + /* 19 */ { 1 , 'l' , 'L' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x02f , 0x03f , -1 , -1 , -1 } , + /* 1b */ { 0 , 0x03d , 0x02b , -1 , -1 , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , 'a' , 'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , 'o' , 'O' , -1 , -1 , -1 } , + + /* 20 */ { 1 , 'e' , 'E' , -1 , -1 , -1 } , + /* 21 */ { 1 , 'u' , 'U' , -1 , -1 , -1 } , + /* 22 */ { 1 , 'i' , 'I' , -1 , -1 , -1 } , + /* 23 */ { 1 , 'd' , 'D' , -1 , -1 , -1 } , + /* 24 */ { 1 , 'h' , 'H' , -1 , -1 , -1 } , + /* 25 */ { 1 , 't' , 'T' , -1 , -1 , -1 } , + /* 26 */ { 1 , 'n' , 'N' , -1 , -1 , -1 } , + /* 27 */ { 1 , 's' , 'S' , -1 , -1 , -1 } , + /* 28 */ { 0 , 0x02d , 0x05f , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x060 , 0x07e , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x005c , 0x07c , 0x01c , -1 , -1 } , + /* 2c */ { 0 , 0x003b , 0x03a , -1 , -1 , -1 } , + /* 2d */ { 1 , 'q' , 'Q' , -1 , -1 , -1 } , + /* 2e */ { 1 , 'j' , 'J' , -1 , -1 , -1 } , + /* 2f */ { 1 , 'k' , 'K' , -1 , -1 , -1 } , + + /* 30 */ { 1 , 'x' , 'X' , -1 , -1 , -1 } , + /* 31 */ { 1 , 'b' , 'B' , -1 , -1 , -1 } , + /* 32 */ { 1 , 'm' , 'M' , -1 , -1 , -1 } , + /* 33 */ { 1 , 'w' , 'W' , -1 , -1 , -1 } , + /* 34 */ { 1 , 'v' , 'V' , -1 , -1 , -1 } , + /* 35 */ { 1 , 'z' , 'Z' , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x020 , 0x020 , 0x020 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x02e , 0x02e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x05c , 0x07c , 0x01c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static DvorakLayout instance = new DvorakLayout(); + + private DvorakLayout() { + } + + public static DvorakLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} \ No newline at end of file diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/FinnishLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/FinnishLayout.java new file mode 100644 index 00000000..c0d6e154 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/FinnishLayout.java @@ -0,0 +1,388 @@ +package com.inputstick.api.layout; + +public class FinnishLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "fi-FI"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //fi-FI + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 24, 64, 33, 0, 0 }, //  + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 53, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 0, 49, 0, 0 }, // ' + { 40, 2, 37, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 49, 0, 0 }, // * + { 43, 0, 45, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 64, 37, 0, 0 }, // [ + { 92, 64, 45, 0, 0 }, // \ + { 93, 64, 38, 0, 0 }, // ] + { 94, 0, 44, 2, 48 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 0, 44, 2, 46 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 64, 36, 0, 0 }, // { + { 124, 64, 100, 0, 0 }, // | + { 125, 64, 39, 0, 0 }, // } + { 126, 0, 44, 64, 48 }, // ~ + { 163, 64, 32, 0, 0 }, // ? + { 164, 2, 33, 0, 0 }, // + { 167, 0, 53, 0, 0 }, // + { 168, 0, 44, 0, 48 }, // + { 180, 0, 44, 0, 46 }, // + { 181, 64, 16, 0, 0 }, // + { 189, 2, 53, 0, 0 }, // ? + { 192, 2, 4, 2, 46 }, // ? + { 193, 2, 4, 0, 46 }, // + { 194, 2, 4, 2, 48 }, // + { 195, 2, 4, 64, 48 }, // ? + { 196, 2, 52, 0, 0 }, // + { 197, 2, 47, 0, 0 }, // ? + { 200, 2, 8, 2, 46 }, // ? + { 201, 2, 8, 0, 46 }, // + { 202, 2, 8, 2, 48 }, // ? + { 203, 2, 8, 0, 48 }, // + { 204, 2, 12, 2, 46 }, // ? + { 205, 2, 12, 0, 46 }, // + { 206, 2, 12, 2, 48 }, // + { 207, 2, 12, 0, 48 }, // ? + { 209, 2, 17, 64, 48 }, // ? + { 210, 2, 18, 2, 46 }, // ? + { 211, 2, 18, 0, 46 }, // + { 212, 2, 18, 2, 48 }, // + { 213, 2, 18, 64, 48 }, // ? + { 214, 2, 51, 0, 0 }, // + { 217, 2, 24, 2, 46 }, // ? + { 218, 2, 24, 0, 46 }, // + { 219, 2, 24, 2, 48 }, // ? + { 220, 2, 24, 0, 48 }, // + { 221, 2, 28, 0, 46 }, // + { 224, 0, 4, 2, 46 }, // ? + { 225, 0, 4, 0, 46 }, // + { 226, 0, 4, 2, 48 }, // + { 227, 0, 4, 64, 48 }, // ? + { 228, 0, 52, 0, 0 }, // + { 229, 0, 47, 0, 0 }, // ? + { 232, 0, 8, 2, 46 }, // ? + { 233, 0, 8, 0, 46 }, // + { 234, 0, 8, 2, 48 }, // ? + { 235, 0, 8, 0, 48 }, // + { 236, 0, 12, 2, 46 }, // ? + { 237, 0, 12, 0, 46 }, // + { 238, 0, 12, 2, 48 }, // + { 239, 0, 12, 0, 48 }, // ? + { 241, 0, 17, 64, 48 }, // ? + { 242, 0, 18, 2, 46 }, // ? + { 243, 0, 18, 0, 46 }, // + { 244, 0, 18, 2, 48 }, // + { 245, 0, 18, 64, 48 }, // ? + { 246, 0, 51, 0, 0 }, // + { 249, 0, 24, 2, 46 }, // ? + { 250, 0, 24, 0, 46 }, // + { 251, 0, 24, 2, 48 }, // ? + { 252, 0, 24, 0, 48 }, // + { 253, 0, 28, 0, 46 }, // + { 255, 0, 28, 0, 48 }, // ? + { 8364, 64, 34, 0, 0 }, // + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x0021 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x0022 , -1 , 0x0040 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x0023 , -1 , 0x00a3 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x00a4 , -1 , 24 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x0025 , -1 , 0x20ac , -1 } , + /* 7 */ { 0 , (int)'6' , 0x0026 , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , 0x007b , -1 } , + /* 9 */ { 0 , (int)'8' , 0x0028 , -1 , 0x005b , -1 } , + /* 0a */ { 0 , (int)'9' , 0x0029 , -1 , 0x005d , -1 } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , 0x007d , -1 } , + /* 0c */ { 0 , 0x002b , 0x003f , -1 , 0x005c , -1 } , + /* 0d */ { 0 , 0x00b4 , 0x0060 , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x020ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 1 , 0x00e5 , 0x00c5 , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x00a8 , 0x005e , 0x001d , 0x007e , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 1 , 0x00f6 , 0x00d6 , -1 , -1 , -1 } , + /* 28 */ { 1 , 0x00e4 , 0x00c4 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x00a7 , 0x00bd , 0x001c , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x0027 , 0x002a , -1 , -1 , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , 0x001c , 0x007c , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x00b4, 0x0060, 0x00a8, 0x005e, 0x007e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + + + }; + + private static FinnishLayout instance = new FinnishLayout(); + + private FinnishLayout() { + } + + public static FinnishLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/FrenchLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/FrenchLayout.java new file mode 100644 index 00000000..84a62cfc --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/FrenchLayout.java @@ -0,0 +1,362 @@ +package com.inputstick.api.layout; + +public class FrenchLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "fr-FR"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //fr-FR + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 0, 56, 0, 0 }, // ! + { 34, 0, 32, 0, 0 }, // " + { 35, 64, 32, 0, 0 }, // # + { 36, 0, 48, 0, 0 }, // $ + { 37, 2, 52, 0, 0 }, // % + { 38, 0, 30, 0, 0 }, // & + { 39, 0, 33, 0, 0 }, // ' + { 40, 0, 34, 0, 0 }, // ( + { 41, 0, 45, 0, 0 }, // ) + { 42, 0, 49, 0, 0 }, // * + { 43, 2, 46, 0, 0 }, // + + { 44, 0, 16, 0, 0 }, // , + { 45, 0, 35, 0, 0 }, // - + { 46, 2, 54, 0, 0 }, // . + { 47, 2, 55, 0, 0 }, // / + { 48, 2, 39, 0, 0 }, // 0 + { 49, 2, 30, 0, 0 }, // 1 + { 50, 2, 31, 0, 0 }, // 2 + { 51, 2, 32, 0, 0 }, // 3 + { 52, 2, 33, 0, 0 }, // 4 + { 53, 2, 34, 0, 0 }, // 5 + { 54, 2, 35, 0, 0 }, // 6 + { 55, 2, 36, 0, 0 }, // 7 + { 56, 2, 37, 0, 0 }, // 8 + { 57, 2, 38, 0, 0 }, // 9 + { 58, 0, 55, 0, 0 }, // : + { 59, 0, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 0, 46, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 16, 0, 0 }, // ? + { 64, 64, 39, 0, 0 }, // @ + { 65, 2, 20, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 51, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 4, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 29, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 26, 0, 0 }, // Z + { 91, 64, 34, 0, 0 }, // [ + { 92, 64, 37, 0, 0 }, // \ + { 93, 64, 45, 0, 0 }, // ] + { 94, 0, 44, 64, 38 }, // ^ + { 95, 0, 37, 0, 0 }, // _ + { 96, 0, 44, 64, 36 }, // ` + { 97, 0, 20, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 51, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 4, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 29, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 26, 0, 0 }, // z + { 123, 64, 33, 0, 0 }, // { + { 124, 64, 35, 0, 0 }, // | + { 125, 64, 46, 0, 0 }, // } + { 126, 0, 44, 64, 31 }, // ~ + { 163, 2, 48, 0, 0 }, // ? + { 164, 64, 48, 0, 0 }, // + { 167, 2, 56, 0, 0 }, // + { 168, 0, 44, 2, 47 }, // + { 176, 2, 45, 0, 0 }, // + { 178, 0, 53, 0, 0 }, // ? + { 181, 2, 49, 0, 0 }, // + { 192, 2, 20, 64, 36 }, // ? + { 194, 2, 20, 64, 38 }, // + { 195, 2, 20, 64, 31 }, // ? + { 196, 2, 20, 2, 47 }, // + { 200, 2, 8, 64, 36 }, // ? + { 202, 2, 8, 64, 38 }, // ? + { 203, 2, 8, 2, 47 }, // + { 204, 2, 12, 64, 36 }, // ? + { 206, 2, 12, 64, 38 }, // + { 207, 2, 12, 2, 47 }, // ? + { 209, 2, 17, 64, 31 }, // ? + { 210, 2, 18, 64, 36 }, // ? + { 212, 2, 18, 64, 38 }, // + { 213, 2, 18, 64, 31 }, // ? + { 214, 2, 18, 2, 47 }, // + { 217, 2, 24, 64, 36 }, // ? + { 219, 2, 24, 64, 38 }, // ? + { 220, 2, 24, 2, 47 }, // + { 224, 0, 39, 0, 0 }, // ? + { 226, 0, 20, 64, 38 }, // + { 227, 0, 20, 64, 31 }, // ? + { 228, 0, 20, 2, 47 }, // + { 231, 0, 38, 0, 0 }, // + { 232, 0, 36, 0, 0 }, // ? + { 233, 0, 31, 0, 0 }, // + { 234, 0, 8, 64, 38 }, // ? + { 235, 0, 8, 2, 47 }, // + { 236, 0, 12, 64, 36 }, // ? + { 238, 0, 12, 64, 38 }, // + { 239, 0, 12, 2, 47 }, // ? + { 241, 0, 17, 64, 31 }, // ? + { 242, 0, 18, 64, 36 }, // ? + { 244, 0, 18, 64, 38 }, // + { 245, 0, 18, 64, 31 }, // ? + { 246, 0, 18, 2, 47 }, // + { 249, 0, 52, 0, 0 }, // ? + { 251, 0, 24, 64, 38 }, // ? + { 252, 0, 24, 2, 47 }, // + { 255, 0, 28, 2, 47 }, // ? + { 8364, 64, 8, 0, 0 }, // + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 1 , 0x26 , (int)'1' , -1 , -1 , -1 } , + /* 3 */ { 1 , 0x00e9 , (int)'2' , -1 , 0x007e , -1 } , + /* 4 */ { 1 , 0x22 , (int)'3' , -1 , 0x23 , -1 } , + /* 5 */ { 1 , 0x27 , (int)'4' , -1 , 0x007b , -1 } , + /* 6 */ { 1 , 0x28 , (int)'5' , -1 , 0x005b , -1 } , + /* 7 */ { 1 , 0x002d , (int)'6' , -1 , 0x007c , -1 } , + /* 8 */ { 1 , 0x00e8 , (int)'7' , -1 , 0x0060 , -1 } , + /* 9 */ { 1 , 0x005f , (int)'8' , -1 , 0x005c , -1 } , + /* 0a */ { 1 , 0x00e7 , (int)'9' , -1 , 0x005e , -1 } , + /* 0b */ { 1 , 0x00e0 , (int)'0' , -1 , 0x40 , -1 } , + /* 0c */ { 1 , 0x29 , 0x00b0 , -1 , 0x005d , -1 } , + /* 0d */ { 1 , 0x003d , 0x002b , -1 , 0x007d , -1 } , + /* 1e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 1 , 0x005e , 0x00a8 , 0x001b , -1 , -1 } , + /* 1b */ { 1 , 0x24 , 0x00a3 , 0x001d , 0x00a4 , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + /* 28 */ { 1 , 0x00f9 , 0x25 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x00b2 , -1 , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 1 , 0x002a , 0x00b5 , 0x001c , -1 , -1 } , + /* 2c */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , 0x002c , 0x003f , -1 , -1 , -1 } , + /* 33 */ { 1 , 0x003b , 0x002e , -1 , -1 , -1 } , + /* 34 */ { 1 , 0x003a , 0x002f , -1 , -1 , -1 } , + /* 35 */ { 1 , 0x21 , 0x00a7 , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x007e, 0x0060, 0x005e, 0x00a8, 0x007e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x0020 , 0x007e } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + }; + + private static FrenchLayout instance = new FrenchLayout(); + + private FrenchLayout() { + } + + public static FrenchLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} + diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/GermanLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/GermanLayout.java new file mode 100644 index 00000000..b083a986 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/GermanLayout.java @@ -0,0 +1,355 @@ +package com.inputstick.api.layout; + +public class GermanLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "de-DE"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //de-DE + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 0, 49, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 2, 49, 0, 0 }, // ' + { 40, 2, 37, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 48, 0, 0 }, // * + { 43, 0, 48, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 20, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 29, 0, 0 }, // Y + { 90, 2, 28, 0, 0 }, // Z + { 91, 64, 37, 0, 0 }, // [ + { 92, 64, 45, 0, 0 }, // \ + { 93, 64, 38, 0, 0 }, // ] + { 94, 0, 44, 0, 53 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 0, 44, 2, 46 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 29, 0, 0 }, // y + { 122, 0, 28, 0, 0 }, // z + { 123, 64, 36, 0, 0 }, // { + { 124, 64, 100, 0, 0 }, // | + { 125, 64, 39, 0, 0 }, // } + { 126, 64, 48, 0, 0 }, // ~ + { 167, 2, 32, 0, 0 }, // + { 176, 2, 53, 0, 0 }, // + { 178, 64, 31, 0, 0 }, // ? + { 179, 64, 32, 0, 0 }, // ? + { 180, 0, 44, 0, 46 }, // + { 181, 64, 16, 0, 0 }, // + { 192, 2, 4, 2, 46 }, // ? + { 193, 2, 4, 0, 46 }, // + { 194, 2, 4, 0, 53 }, // + { 196, 2, 52, 0, 0 }, // + { 200, 2, 8, 2, 46 }, // ? + { 201, 2, 8, 0, 46 }, // + { 202, 2, 8, 0, 53 }, // ? + { 204, 2, 12, 2, 46 }, // ? + { 205, 2, 12, 0, 46 }, // + { 206, 2, 12, 0, 53 }, // + { 210, 2, 18, 2, 46 }, // ? + { 211, 2, 18, 0, 46 }, // + { 212, 2, 18, 0, 53 }, // + { 214, 2, 51, 0, 0 }, // + { 217, 2, 24, 2, 46 }, // ? + { 218, 2, 24, 0, 46 }, // + { 219, 2, 24, 0, 53 }, // ? + { 220, 2, 47, 0, 0 }, // + { 221, 2, 29, 0, 46 }, // + { 223, 0, 45, 0, 0 }, // + { 224, 0, 4, 2, 46 }, // ? + { 225, 0, 4, 0, 46 }, // + { 226, 0, 4, 0, 53 }, // + { 228, 0, 52, 0, 0 }, // + { 232, 0, 8, 2, 46 }, // ? + { 233, 0, 8, 0, 46 }, // + { 234, 0, 8, 0, 53 }, // ? + { 236, 0, 12, 2, 46 }, // ? + { 237, 0, 12, 0, 46 }, // + { 238, 0, 12, 0, 53 }, // + { 242, 0, 18, 2, 46 }, // ? + { 243, 0, 18, 0, 46 }, // + { 244, 0, 18, 0, 53 }, // + { 246, 0, 51, 0, 0 }, // + { 249, 0, 24, 2, 46 }, // ? + { 250, 0, 24, 0, 46 }, // + { 251, 0, 24, 0, 53 }, // ? + { 252, 0, 47, 0, 0 }, // + { 253, 0, 29, 0, 46 }, // + { 8364, 64, 8, 0, 0 }, // + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x22 , -1 , 0x00b2 , 0x00b2 } , + /* 4 */ { 0 , (int)'3' , 0x00a7 , -1 , 0x00b3 , 0x00b3 } , + /* 5 */ { 0 , (int)'4' , 0x24 , -1 , -1 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , -1 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x26 , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , 0x007b , 0x007b } , + /* 9 */ { 0 , (int)'8' , 0x28 , -1 , 0x005b , 0x005b } , + /* 0a */ { 0 , (int)'9' , 0x29 , -1 , 0x005d , 0x005d } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , 0x007d , 0x007d } , + /* 0c */ { 0 , 0x00df , 0x003f , -1 , 0x005c , 0x005c } , + /* 0d */ { 0 , 0x00b4 , 0x0060 , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , 0x40 , 0x40 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 1 , 0x00fc , 0x00dc , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x002b , 0x002a , 0x001d , 0x007e , 0x007e } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 1 , 0x00f6 , 0x00d6 , -1 , -1 , -1 } , + /* 28 */ { 1 , 0x00e4 , 0x00c4 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x005e , 0x00b0 , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x23 , 0x27 , 0x001c , -1 , -1 } , + /* 2c */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , 0x00b5 } , + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , -1 , 0x007c , 0x007c } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x0060, 0x00b4, 0x005e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + + }; + + private static GermanLayout instance = new GermanLayout(); + + private GermanLayout() { + } + + public static GermanLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/GermanMacLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/GermanMacLayout.java new file mode 100644 index 00000000..74788dba --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/GermanMacLayout.java @@ -0,0 +1,353 @@ +package com.inputstick.api.layout; + +public class GermanMacLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "de-DE-mac"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //de-DE-mac + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 0, 49, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 2, 49, 0, 0 }, // ' + { 40, 2, 37, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 48, 0, 0 }, // * + { 43, 0, 48, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 15, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 29, 0, 0 }, // Y + { 90, 2, 28, 0, 0 }, // Z + { 91, 64, 34, 0, 0 }, // [ + { 93, 64, 35, 0, 0 }, // ] + { 94, 0, 44, 0, 53 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 0, 44, 2, 46 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 29, 0, 0 }, // y + { 122, 0, 28, 0, 0 }, // z + { 123, 64, 37, 0, 0 }, // { + { 124, 64, 36, 0, 0 }, // | + { 125, 64, 38, 0, 0 }, // } + { 126, 64, 17, 0, 0 }, // ~ + { 167, 2, 32, 0, 0 }, // + { 176, 2, 53, 0, 0 }, // + { 180, 0, 44, 0, 46 }, // + { 181, 64, 16, 0, 0 }, // + { 192, 2, 4, 2, 46 }, // ? + { 193, 2, 4, 0, 46 }, // + { 194, 2, 4, 0, 53 }, // + { 196, 2, 52, 0, 0 }, // + { 200, 2, 8, 2, 46 }, // ? + { 201, 2, 8, 0, 46 }, // + { 202, 2, 8, 0, 53 }, // ? + { 204, 2, 12, 2, 46 }, // ? + { 205, 2, 12, 0, 46 }, // + { 206, 2, 12, 0, 53 }, // + { 210, 2, 18, 2, 46 }, // ? + { 211, 2, 18, 0, 46 }, // + { 212, 2, 18, 0, 53 }, // + { 214, 2, 51, 0, 0 }, // + { 217, 2, 24, 2, 46 }, // ? + { 218, 2, 24, 0, 46 }, // + { 219, 2, 24, 0, 53 }, // ? + { 220, 2, 47, 0, 0 }, // + { 221, 2, 29, 0, 46 }, // + { 223, 0, 45, 0, 0 }, // + { 224, 0, 4, 2, 46 }, // ? + { 225, 0, 4, 0, 46 }, // + { 226, 0, 4, 0, 53 }, // + { 228, 0, 52, 0, 0 }, // + { 232, 0, 8, 2, 46 }, // ? + { 233, 0, 8, 0, 46 }, // + { 234, 0, 8, 0, 53 }, // ? + { 236, 0, 12, 2, 46 }, // ? + { 237, 0, 12, 0, 46 }, // + { 238, 0, 12, 0, 53 }, // + { 242, 0, 18, 2, 46 }, // ? + { 243, 0, 18, 0, 46 }, // + { 244, 0, 18, 0, 53 }, // + { 246, 0, 51, 0, 0 }, // + { 249, 0, 24, 2, 46 }, // ? + { 250, 0, 24, 0, 46 }, // + { 251, 0, 24, 0, 53 }, // ? + { 252, 0, 47, 0, 0 }, // + { 253, 0, 29, 0, 46 }, // + { 8364, 64, 8, 0, 0 }, // + }; + + public static final int LUT[][] = { + // CAPSLOCK, NORMAL , SHIFT , CTRL , ALTGR , SHIFT + ALTGR + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x22 , -1 , -1 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x00a7 , -1 , -1 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x24 , -1 , -1 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , 0x005b , 0x005b } , + /* 7 */ { 0 , (int)'6' , 0x26 , -1 , 0x005d , 0x005d } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , 0x007c , 0x007c } , + /* 9 */ { 0 , (int)'8' , 0x28 , -1 , 0x007b , 0x007b } , + /* 0a */ { 0 , (int)'9' , 0x29 , -1 , 0x007d , 0x007d } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x00df , 0x003f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x00b4 , 0x0060 , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , //euro, same as Windows layout + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 1 , 0x00fc , 0x00dc , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x002b , 0x002a , 0x001d , -1 , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , 0x0040 , -1 } , + /* 27 */ { 1 , 0x00f6 , 0x00d6 , -1 , -1 , -1 } , + /* 28 */ { 1 , 0x00e4 , 0x00c4 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x005e , 0x00b0 , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x23 , 0x27 , 0x001c , -1 , -1 } , + /* 2c */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , 0x007e , 0x007e } , //MAC ~ + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , 0x00b5 } , //"micro" - same as Windwos + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , -1 , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x0060, 0x00b4, 0x005e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + + }; + + private static GermanMacLayout instance = new GermanMacLayout(); + + private GermanMacLayout() { + } + + public static GermanMacLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/HebrewLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/HebrewLayout.java new file mode 100644 index 00000000..69b992e8 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/HebrewLayout.java @@ -0,0 +1,275 @@ +package com.inputstick.api.layout; + +public class HebrewLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "he-IL"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //he-IL + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 28, 1, 49, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 52, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 36, 0, 0 }, // & + { 39, 0, 26, 0, 0 }, // ' + { 40, 2, 39, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 37, 0, 0 }, // * + { 43, 2, 46, 0, 0 }, // + + { 44, 0, 52, 0, 0 }, // , + { 45, 0, 45, 0, 0 }, // - + { 46, 0, 56, 0, 0 }, // . + { 47, 0, 20, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 51, 0, 0 }, // : + { 59, 0, 53, 0, 0 }, // ; + { 60, 2, 55, 0, 0 }, // < + { 61, 0, 46, 0, 0 }, // = + { 62, 2, 54, 0, 0 }, // > + { 63, 2, 56, 0, 0 }, // ? + { 64, 2, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 0, 48, 0, 0 }, // [ + { 92, 0, 49, 0, 0 }, // \ + { 93, 0, 47, 0, 0 }, // ] + { 94, 2, 35, 0, 0 }, // ^ + { 95, 2, 45, 0, 0 }, // _ + { 123, 2, 48, 0, 0 }, // { + { 124, 2, 49, 0, 0 }, // | + { 125, 2, 47, 0, 0 }, // } + { 126, 2, 53, 0, 0 }, // ~ + { 1471, 66, 45, 0, 0 }, // ? + { 1488, 0, 23, 0, 0 }, // ? + { 1489, 0, 6, 0, 0 }, // ? + { 1490, 0, 7, 0, 0 }, // ? + { 1491, 0, 22, 0, 0 }, // ? + { 1492, 0, 25, 0, 0 }, // ? + { 1493, 0, 24, 0, 0 }, // ? + { 1494, 0, 29, 0, 0 }, // ? + { 1495, 0, 13, 0, 0 }, // ? + { 1496, 0, 28, 0, 0 }, // ? + { 1497, 0, 11, 0, 0 }, // ? + { 1498, 0, 15, 0, 0 }, // ? + { 1499, 0, 9, 0, 0 }, // ? + { 1500, 0, 14, 0, 0 }, // ? + { 1501, 0, 18, 0, 0 }, // ? + { 1502, 0, 17, 0, 0 }, // ? + { 1503, 0, 12, 0, 0 }, // ? + { 1504, 0, 5, 0, 0 }, // ? + { 1505, 0, 27, 0, 0 }, // ? + { 1506, 0, 10, 0, 0 }, // ? + { 1507, 0, 51, 0, 0 }, // ? + { 1508, 0, 19, 0, 0 }, // ? + { 1509, 0, 55, 0, 0 }, // ? + { 1510, 0, 16, 0, 0 }, // ? + { 1511, 0, 8, 0, 0 }, // ? + { 1512, 0, 21, 0, 0 }, // ? + { 1513, 0, 4, 0, 0 }, // ? + { 1514, 0, 54, 0, 0 }, // ? + { 1520, 66, 24, 0, 0 }, // ? + { 1521, 66, 13, 0, 0 }, // ? + { 1522, 66, 11, 0, 0 }, // ? + { 8206, 64, 32, 0, 0 }, // ? + { 8207, 64, 33, 0, 0 }, // ? + { 8362, 66, 33, 0, 0 }, // ? + { 8364, 66, 8, 0, 0 }, // + }; + + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x0021 , -1 , -1 , -1 } , // TODO SGCap + /* 3 */ { 0 , (int)'2' , 0x0040 , -1 , -1 , -1 } , // TODO SGCap + /* 4 */ { 0 , (int)'3' , 0x0023 , -1 , 0x200e , -1 } , // TODO SGCap + /* 5 */ { 0 , (int)'4' , 0x0024 , -1 , 0x200f , 0x20aa } , // TODO SGCap + /* 6 */ { 0 , (int)'5' , 0x0025 , -1 , -1 , -1 } , // TODO SGCap + /* 7 */ { 0 , (int)'6' , 0x005e , -1 , -1 , -1 } , // TODO SGCap + /* 8 */ { 0 , (int)'7' , 0x0026 , -1 , -1 , -1 } , // TODO SGCap + /* 9 */ { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , // TODO SGCap + /* 0a */ { 0 , (int)'9' , 0x0029 , -1 , -1 , -1 } , // TODO SGCap + /* 0b */ { 0 , (int)'0' , 0x0028 , -1 , -1 , -1 } , // TODO SGCap + /* 0c */ { 0 , 0x002d , 0x005f , -1 , -1 , 0x05bf } , // TODO SGCap + /* 0d */ { 0 , 0x003d , 0x002b , -1 , -1 , -1 } , // TODO SGCap + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , 0x002f , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , 0x0027 , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , 0x05e7 , (int)'E' , -1 , -1 , 0x20ac } , + /* 13 */ { 1 , 0x05e8 , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , 0x05d0 , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , 0x05d8 , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , 0x05d5 , (int)'U' , -1 , -1 , 0x05f0 } , + /* 17 */ { 1 , 0x05df , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , 0x05dd , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , 0x05e4 , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x005d , 0x007d , 0x200e , -1 , -1 } , // TODO SGCap + /* 1b */ { 0 , 0x005b , 0x007b , 0x200f , -1 , -1 } , // TODO SGCap + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , 0x05e9 , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , 0x05d3 , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , 0x05d2 , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , 0x05db , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , 0x05e2 , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , 0x05d9 , (int)'H' , -1 , -1 , 0x05f2 } , + /* 24 */ { 1 , 0x05d7 , (int)'J' , -1 , -1 , 0x05f1 } , + /* 25 */ { 1 , 0x05dc , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , 0x05da , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 0 , 0x05e3 , 0x003a , -1 , -1 , -1 } , // TODO SGCap + /* 28 */ { 0 , 0x002c , 0x0022 , -1 , -1 , -1 } , // TODO SGCap + /* 29 */ { 0 , 0x003b , 0x007e , -1 , -1 , -1 } , // TODO SGCap + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , // TODO SGCap + /* 2c */ { 1 , 0x05d6 , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , 0x05e1 , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , 0x05d1 , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , 0x05d4 , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , 0x05e0 , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , 0x05de , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , 0x05e6 , (int)'M' , -1 , -1 , -1 } , + /* 33 */ { 0 , 0x05ea , 0x003e , -1 , -1 , -1 } , // TODO SGCap + /* 34 */ { 0 , 0x05e5 , 0x003c , -1 , -1 , -1 } , // TODO SGCap + /* 35 */ { 0 , 0x002e , 0x003f , -1 , -1 , -1 } , // TODO SGCap + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static HebrewLayout instance = new HebrewLayout(); + + private HebrewLayout() { + } + + public static HebrewLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/ItalianLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/ItalianLayout.java new file mode 100644 index 00000000..7de9ad6c --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/ItalianLayout.java @@ -0,0 +1,279 @@ +package com.inputstick.api.layout; + +public class ItalianLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "it-IT"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //it-IT + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 64, 52, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 0, 45, 0, 0 }, // ' + { 40, 2, 37, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 48, 0, 0 }, // * + { 43, 0, 48, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 51, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 64, 47, 0, 0 }, // [ + { 92, 0, 53, 0, 0 }, // \ + { 93, 64, 48, 0, 0 }, // ] + { 94, 2, 46, 0, 0 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 66, 47, 0, 0 }, // { + { 124, 2, 53, 0, 0 }, // | + { 125, 66, 48, 0, 0 }, // } + { 163, 2, 32, 0, 0 }, // ? + { 167, 2, 49, 0, 0 }, // + { 176, 2, 52, 0, 0 }, // + { 224, 0, 52, 0, 0 }, // ? + { 231, 2, 51, 0, 0 }, // + { 232, 0, 47, 0, 0 }, // ? + { 233, 2, 47, 0, 0 }, // + { 236, 0, 46, 0, 0 }, // ? + { 242, 0, 51, 0, 0 }, // ? + { 249, 0, 49, 0, 0 }, // ? + { 8364, 64, 34, 0, 0 }, // + }; + + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x0021 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x0022 , -1 , -1 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x00a3 , -1 , -1 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x0024 , -1 , -1 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x0025 , -1 , 0x20ac , -1 } , + /* 7 */ { 0 , (int)'6' , 0x0026 , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x0028 , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x0029 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x0027 , 0x003f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x00ec , 0x005e , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x00e8 , 0x00e9 , 0x001b , 0x005b , 0x007b } , + /* 1b */ { 0 , 0x002b , 0x002a , 0x001d , 0x005d , 0x007d } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 0 , 0x00f2 , 0x00e7 , -1 , 0x0040 , -1 } , + /* 28 */ { 0 , 0x00e0 , 0x00b0 , -1 , 0x0023 , -1 } , + /* 29 */ { 0 , 0x005c , 0x007c , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x00f9 , 0x00a7 , 0x001c , -1 , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static ItalianLayout instance = new ItalianLayout(); + + private ItalianLayout() { + } + + public static ItalianLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/KeyboardLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/KeyboardLayout.java new file mode 100644 index 00000000..e418cf9e --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/KeyboardLayout.java @@ -0,0 +1,432 @@ +package com.inputstick.api.layout; + +import com.inputstick.api.ConnectionManager; +import com.inputstick.api.basic.InputStickHID; +import com.inputstick.api.basic.InputStickKeyboard; +import com.inputstick.api.hid.HIDKeycodes; +import com.inputstick.api.hid.HIDTransaction; +import com.inputstick.api.hid.KeyboardReport; + +public abstract class KeyboardLayout { + + public static final int MAX_SCANCODE = 0x60; + + public static final byte[] scanCodeToHID = { + /* 0x00 */ 0, + /* 0x01 */ HIDKeycodes.KEY_ESCAPE, + /* 0x02 */ HIDKeycodes.KEY_1, + /* 0x03 */ HIDKeycodes.KEY_2, + /* 0x04 */ HIDKeycodes.KEY_3, + /* 0x05 */ HIDKeycodes.KEY_4, + /* 0x06 */ HIDKeycodes.KEY_5, + /* 0x07 */ HIDKeycodes.KEY_6, + /* 0x08 */ HIDKeycodes.KEY_7, + /* 0x09 */ HIDKeycodes.KEY_8, + /* 0x0a */ HIDKeycodes.KEY_9, + /* 0x0b */ HIDKeycodes.KEY_0, + /* 0x0c */ HIDKeycodes.KEY_MINUS, + /* 0x0d */ HIDKeycodes.KEY_EQUALS, + /* 0x0e */ HIDKeycodes.KEY_BACKSPACE, + /* 0x0f */ HIDKeycodes.KEY_TAB, + + + /* 0x10 */ HIDKeycodes.KEY_Q, + /* 0x11 */ HIDKeycodes.KEY_W, + /* 0x12 */ HIDKeycodes.KEY_E, + /* 0x13 */ HIDKeycodes.KEY_R, + /* 0x14 */ HIDKeycodes.KEY_T, + /* 0x15 */ HIDKeycodes.KEY_Y, + /* 0x16 */ HIDKeycodes.KEY_U, + /* 0x17 */ HIDKeycodes.KEY_I, + /* 0x18 */ HIDKeycodes.KEY_O, + /* 0x19 */ HIDKeycodes.KEY_P, + /* 0x1a */ HIDKeycodes.KEY_LEFT_BRACKET, + /* 0x1b */ HIDKeycodes.KEY_RIGHT_BRACKET, + /* 0x1c */ HIDKeycodes.KEY_ENTER, + /* 0x1d */ 0, //RL CTRL + /* 0x1e */ HIDKeycodes.KEY_A, + /* 0x1f */ HIDKeycodes.KEY_S, + + /* 0x20 */ HIDKeycodes.KEY_D, + /* 0x21 */ HIDKeycodes.KEY_F, + /* 0x22 */ HIDKeycodes.KEY_G, + /* 0x23 */ HIDKeycodes.KEY_H, + /* 0x24 */ HIDKeycodes.KEY_J, + /* 0x25 */ HIDKeycodes.KEY_K, + /* 0x26 */ HIDKeycodes.KEY_L, + /* 0x27 */ HIDKeycodes.KEY_SEMICOLON, + /* 0x28 */ HIDKeycodes.KEY_APOSTROPHE, + /* 0x29 */ HIDKeycodes.KEY_GRAVE, + /* 0x2a */ 0, //L SHIFT + /* 0x2b */ HIDKeycodes.KEY_BACKSLASH, + /* 0x2c */ HIDKeycodes.KEY_Z, + /* 0x2d */ HIDKeycodes.KEY_X, + /* 0x2e */ HIDKeycodes.KEY_C, + /* 0x2f */ HIDKeycodes.KEY_V, + + /* 0x30 */ HIDKeycodes.KEY_B, + /* 0x31 */ HIDKeycodes.KEY_N, + /* 0x32 */ HIDKeycodes.KEY_M, + /* 0x33 */ HIDKeycodes.KEY_COMA, + /* 0x34 */ HIDKeycodes.KEY_DOT, + /* 0x35 */ HIDKeycodes.KEY_SLASH, + /* 0x36 */ 0, //R SHIFT + /* 0x37 */ HIDKeycodes.KEY_PRINT_SCREEN, + /* 0x38 */ 0, //RL ALT + /* 0x39 */ HIDKeycodes.KEY_SPACEBAR, + /* 0x3a */ HIDKeycodes.KEY_CAPS_LOCK, + /* 0x3b */ HIDKeycodes.KEY_F1, + /* 0x3c */ HIDKeycodes.KEY_F2, + /* 0x3d */ HIDKeycodes.KEY_F3, + /* 0x3e */ HIDKeycodes.KEY_F4, + /* 0x3f */ HIDKeycodes.KEY_F5, + + /* 0x40 */ HIDKeycodes.KEY_F6, + /* 0x41 */ HIDKeycodes.KEY_F7, + /* 0x42 */ HIDKeycodes.KEY_F8, + /* 0x43 */ HIDKeycodes.KEY_F9, + /* 0x44 */ HIDKeycodes.KEY_F10, + /* 0x45 */ HIDKeycodes.KEY_NUM_LOCK, + /* 0x46 */ HIDKeycodes.KEY_SCROLL_LOCK, + /* 0x47 */ HIDKeycodes.KEY_HOME, + /* 0x48 */ HIDKeycodes.KEY_ARROW_UP, + /* 0x49 */ HIDKeycodes.KEY_PAGE_UP, + /* 0x4a */ 0, //- + /* 0x4b */ HIDKeycodes.KEY_ARROW_LEFT, + /* 0x4c */ 0, //CENTER + /* 0x4d */ HIDKeycodes.KEY_ARROW_RIGHT, + /* 0x4e */ 0, //+ + /* 0x4f */ HIDKeycodes.KEY_END, + + /* 0x50 */ HIDKeycodes.KEY_ARROW_DOWN, + /* 0x51 */ HIDKeycodes.KEY_PAGE_DOWN, + /* 0x52 */ HIDKeycodes.KEY_INSERT, + /* 0x53 */ HIDKeycodes.KEY_DELETE, + /* 0x54 */ 0, + /* 0x55 */ 0, + /* 0x56 */ HIDKeycodes.KEY_BACKSLASH_NON_US, //GERMAN LAYOUT! + /* 0x57 */ HIDKeycodes.KEY_F11, + /* 0x58 */ HIDKeycodes.KEY_F12, + /* 0x59 */ 0, + /* 0x5a */ 0, + /* 0x5b */ 0, + /* 0x5c */ 0, + /* 0x5d */ 0, + /* 0x5e */ 0, + /* 0x5f */ 0, + + }; + + public static final int LAYOUT_CODE = 0; + + public abstract int[][] getLUT(); + public abstract int[][] getFastLUT(); + public abstract int[][] getDeadkeyLUT(); + public abstract int[] getDeadkeys(); + public abstract String getLocaleName(); + + /* + * Type text using InputStick. Assumes that USB host uses matching keyboard layout. + * + * @param text text to type + */ + public abstract void type(String text); + + + /* + * Type text using InputStick. Assumes that USB host uses matching keyboard layout. + * Note: use only if you are certain that specified modifier keys will not cause any side effects during typing. + * + * @param text text to type + * @param modifiers state of keyboard modifier keys (CTRL_LEFT .. GUI_RIGHT, see HIDKeycodes) + */ + public abstract void type(String text, byte modifiers); + + public abstract char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr); + + public void type(int[][] fastLUT, String text, byte modifiers) { + if (InputStickHID.getState() == ConnectionManager.STATE_READY) { + char[] chars = text.toCharArray(); + HIDTransaction t; + for (char c : chars) { + if (c == '\n') { + InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER); + } else if (c == '\t') { + InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_TAB); + } else { + t = getHIDTransaction(fastLUT, c, modifiers); + if (t != null) { + InputStickHID.addKeyboardTransaction(t); + } + } + } + } + } + + /*public void type(int[][] lut, int[][] deadkeyLUT, int[] deadkeys, String text, byte modifiers) { + if (InputStickHID.getState() == ConnectionManager.STATE_READY) { + char[] chars = text.toCharArray(); + HIDTransaction t; + for (char c : chars) { + if (c == '\n') { + InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER); + } else if (c == '\t') { + InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_TAB); + } else { + t = getHIDTransaction(lut, deadkeyLUT, deadkeys, c, modifiers); + if (t != null) { + InputStickHID.addKeyboardTransaction(t); + } + } + } + } + } */ + + public static int hidToScanCode(byte key) { + for (int scanCode = 0; scanCode < MAX_SCANCODE; scanCode++) { + if (scanCodeToHID[scanCode] == key) { + return scanCode; + } + } + return -1; + } + + public static char getChar(int[][] lut, int scanCode, boolean capsLock, boolean shift, boolean altGr) { + if ((scanCode >= MAX_SCANCODE) || (scanCode < 0)) { + return (char)0; + } + + int index = 1; + + if ((capsLock) && (lut[scanCode][0] > 0)) { + //capslock is on and it affects current key + if (lut[scanCode][0] == 1) { + if (shift) { + index = 1; //caps + shift = default + } else { + index = 2; //shift + } + } else { + // >1 + if (shift) { + if (altGr) { + index = 4; //caps + shift + alt = alt + } else { + index = 1; //caps + shift = default + } + } else { + if (altGr) { + index = 5; //caps + alt = shift + alt + } else { + index = 2; //caps = shift + } + } + } + } else { + if (shift) { + index = 2; + } + if (altGr) { + if (shift) { + index = 5; + } else { + index = 4; + } + } + } + + if (lut[scanCode][index] == -1) { + index = 1; + } + return (char)lut[scanCode][index]; + } + + public static int getScanCode(int[][] lut, char c) { + for (int scanCode = 0; scanCode < MAX_SCANCODE; scanCode++) { + if (lut[scanCode][0] == -1) { + continue; + } else { + for (int i = 1; i < 6; i++) { + if (lut[scanCode][i] == (int)c) { + return scanCode; + } + } + } + } + return -1; + } + + public static byte getKey(int scanCode) { + return scanCodeToHID[scanCode]; + } + + public static byte getModifiers(int[][] lut, int scanCode, char c) { + if (lut[scanCode][1] == (int)c) { + return 0; + } + if (lut[scanCode][2] == (int)c) { + return HIDKeycodes.SHIFT_LEFT; + } + if (lut[scanCode][3] == (int)c) { + return HIDKeycodes.CTRL_LEFT; + } + if (lut[scanCode][4] == (int)c) { + return HIDKeycodes.ALT_RIGHT; + } + if (lut[scanCode][5] == (int)c) { + return HIDKeycodes.SHIFT_LEFT | HIDKeycodes.ALT_RIGHT; + } + + return 0; + } + + + public static boolean isDeadkey(int[] deadkeys, char c) { + if (deadkeys != null) { + for (int key : deadkeys) { + if (key == (int)c) { + return true; + } + } + } + return false; + } + + public static int searchLUT(int[][] deadkeyLUT, char c, int returnIndex) { + if (deadkeyLUT != null) { + for (int i = 0; i < deadkeyLUT.length; i++) { + if (deadkeyLUT[i][2] == (int)c) { + return deadkeyLUT[i][returnIndex]; + } + } + } + return -1; + } + + public static int findDeadKey(int[][] deadkeyLUT, char c) { + return searchLUT(deadkeyLUT, c, 0); + } + + public static int findFollowingKey(int[][] deadkeyLUT, char c) { + return searchLUT(deadkeyLUT, c, 1); + } + + public static HIDTransaction getHIDTransaction(int[][] fastLUT, char c, byte additionalModifierKeys) { + byte modifiers, key, deadKey, deadKeyModifiers; + HIDTransaction t = new HIDTransaction(); + + for (int i = 0; i < fastLUT.length; i++) { + if (fastLUT[i][0] == c) { + modifiers = (byte)fastLUT[i][1]; + key = (byte)fastLUT[i][2]; + deadKeyModifiers = (byte)fastLUT[i][3]; + deadKey = (byte)fastLUT[i][4]; + + if (deadKey > 0) { + t.addReport(new KeyboardReport(deadKeyModifiers, (byte)0)); + t.addReport(new KeyboardReport(deadKeyModifiers, deadKey)); + t.addReport(new KeyboardReport()); + } + t.addReport(new KeyboardReport(modifiers, (byte)0)); + t.addReport(new KeyboardReport(modifiers, key)); + t.addReport(new KeyboardReport()); + } + } + return t; + } + + public static HIDTransaction getHIDTransaction(int[][] lut, int[][] deadkeyLUT, int[] deadkeys, char c, byte additionalModifierKeys) { + byte modifiers, key; + int scanCode; + + HIDTransaction t = new HIDTransaction(); + scanCode = getScanCode(lut, c); + if (scanCode > 0) { + key = getKey(scanCode); + modifiers = getModifiers(lut, scanCode, c); + modifiers |= additionalModifierKeys; + + t.addReport(new KeyboardReport(modifiers, (byte)0)); + t.addReport(new KeyboardReport(modifiers, key)); + t.addReport(new KeyboardReport()); + + //add space after deadkey! + if (isDeadkey(deadkeys, c)) { + t.addReport(new KeyboardReport((byte)0, HIDKeycodes.KEY_SPACEBAR)); //this won't work if modifiers are present! + t.addReport(new KeyboardReport()); + } + + } else { + //check if character can be obtained using deadkey: + int deadkey = findDeadKey(deadkeyLUT, c); + if (deadkey > 0) { + //yes it can + int following = findFollowingKey(deadkeyLUT, c); + + scanCode = getScanCode(lut, (char)deadkey); + key = getKey(scanCode); + modifiers = getModifiers(lut, scanCode, (char)deadkey); + t.addReport(new KeyboardReport(modifiers, (byte)0)); + t.addReport(new KeyboardReport(modifiers, key)); + t.addReport(new KeyboardReport()); + + scanCode = getScanCode(lut, (char)following); + key = getKey(scanCode); + modifiers = getModifiers(lut, scanCode, (char)following); + t.addReport(new KeyboardReport(modifiers, (byte)0)); + t.addReport(new KeyboardReport(modifiers, key)); + t.addReport(new KeyboardReport()); + } + + } + return t; + } + + //returns layout sepcified by locale (example: "de-DE"). If specified layout is not available, en=US will be returned. + public static KeyboardLayout getLayout(String locale) { + if (locale != null) { + if (locale.equalsIgnoreCase(UnitedStatesLayout.LOCALE_NAME)) { + return UnitedStatesLayout.getInstance(); + } else if (locale.equalsIgnoreCase(PolishLayout.LOCALE_NAME)) { + return PolishLayout.getInstance(); + } else if (locale.equalsIgnoreCase(RussianLayout.LOCALE_NAME)) { + return RussianLayout.getInstance(); + } else if (locale.equalsIgnoreCase(GermanLayout.LOCALE_NAME)) { + return GermanLayout.getInstance(); + } else if (locale.equalsIgnoreCase(SlovakLayout.LOCALE_NAME)) { + return SlovakLayout.getInstance(); + } else if (locale.equalsIgnoreCase(PortugueseBrazilianLayout.LOCALE_NAME)) { + return PortugueseBrazilianLayout.getInstance(); + } else if (locale.equalsIgnoreCase(DvorakLayout.LOCALE_NAME)) { + return DvorakLayout.getInstance(); + } else if (locale.equalsIgnoreCase(NorwegianLayout.LOCALE_NAME)) { + return NorwegianLayout.getInstance(); + } else if (locale.equalsIgnoreCase(SwedishLayout.LOCALE_NAME)) { + return SwedishLayout.getInstance(); + } else if (locale.equalsIgnoreCase(FrenchLayout.LOCALE_NAME)) { + return FrenchLayout.getInstance(); + } else if (locale.equalsIgnoreCase(SpanishLayout.LOCALE_NAME)) { + return SpanishLayout.getInstance(); + } else if (locale.equalsIgnoreCase(UnitedKingdomLayout.LOCALE_NAME)) { + return UnitedKingdomLayout.getInstance(); + } else if (locale.equalsIgnoreCase(GermanMacLayout.LOCALE_NAME)) { + return GermanMacLayout.getInstance(); // TODO + } else if (locale.equalsIgnoreCase(ItalianLayout.LOCALE_NAME)) { + return ItalianLayout.getInstance(); + } else if (locale.equalsIgnoreCase(FinnishLayout.LOCALE_NAME)) { + return FinnishLayout.getInstance(); + } else if (locale.equalsIgnoreCase(SwissFrenchLayout.LOCALE_NAME)) { + return SwissFrenchLayout.getInstance(); + } else if (locale.equalsIgnoreCase(SwissGermanLayout.LOCALE_NAME)) { + return SwissGermanLayout.getInstance(); + } else if (locale.equalsIgnoreCase(HebrewLayout.LOCALE_NAME)) { + return HebrewLayout.getInstance(); + } else if (locale.equalsIgnoreCase(DanishLayout.LOCALE_NAME)) { + return DanishLayout.getInstance(); + } + } + + return UnitedStatesLayout.getInstance(); + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/NorwegianLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/NorwegianLayout.java new file mode 100644 index 00000000..109ddfe0 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/NorwegianLayout.java @@ -0,0 +1,392 @@ +package com.inputstick.api.layout; + +public class NorwegianLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "nb-NO"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //nb-NO + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 53, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 64, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 0, 49, 0, 0 }, // ' + { 40, 2, 37, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 49, 0, 0 }, // * + { 43, 0, 45, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 64, 37, 0, 0 }, // [ + { 92, 0, 46, 0, 0 }, // \ + { 93, 64, 38, 0, 0 }, // ] + { 94, 0, 44, 2, 48 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 0, 44, 2, 46 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 64, 36, 0, 0 }, // { + { 124, 0, 53, 0, 0 }, // | + { 125, 64, 39, 0, 0 }, // } + { 126, 0, 44, 64, 48 }, // ~ + { 163, 64, 32, 0, 0 }, // ? + { 164, 2, 33, 0, 0 }, // ¤ + { 167, 2, 53, 0, 0 }, // § + { 168, 0, 44, 0, 48 }, // ¨ + { 180, 0, 44, 64, 46 }, // ´ + { 181, 64, 16, 0, 0 }, // µ + { 192, 2, 4, 2, 46 }, // ? + { 193, 2, 4, 64, 46 }, // Á + { 194, 2, 4, 2, 48 }, //  + { 195, 2, 4, 64, 48 }, // ? + { 196, 2, 4, 0, 48 }, // Ä + { 197, 2, 47, 0, 0 }, // ? + { 198, 2, 52, 0, 0 }, // ? + { 200, 2, 8, 2, 46 }, // ? + { 201, 2, 8, 64, 46 }, // É + { 202, 2, 8, 2, 48 }, // ? + { 203, 2, 8, 0, 48 }, // Ë + { 204, 2, 12, 2, 46 }, // ? + { 205, 2, 12, 64, 46 }, // Í + { 206, 2, 12, 2, 48 }, // Î + { 207, 2, 12, 0, 48 }, // ? + { 209, 2, 17, 64, 48 }, // ? + { 210, 2, 18, 2, 46 }, // ? + { 211, 2, 18, 64, 46 }, // Ó + { 212, 2, 18, 2, 48 }, // Ô + { 213, 2, 18, 64, 48 }, // ? + { 214, 2, 18, 0, 48 }, // Ö + { 216, 2, 51, 0, 0 }, // ? + { 217, 2, 24, 2, 46 }, // ? + { 218, 2, 24, 64, 46 }, // Ú + { 219, 2, 24, 2, 48 }, // ? + { 220, 2, 24, 0, 48 }, // Ü + { 221, 2, 28, 64, 46 }, // Ý + { 224, 0, 4, 2, 46 }, // ? + { 225, 0, 4, 64, 46 }, // á + { 226, 0, 4, 2, 48 }, // â + { 227, 0, 4, 64, 48 }, // ? + { 228, 0, 4, 0, 48 }, // ä + { 229, 0, 47, 0, 0 }, // ? + { 230, 0, 52, 0, 0 }, // ? + { 232, 0, 8, 2, 46 }, // ? + { 233, 0, 8, 64, 46 }, // é + { 234, 0, 8, 2, 48 }, // ? + { 235, 0, 8, 0, 48 }, // ë + { 236, 0, 12, 2, 46 }, // ? + { 237, 0, 12, 64, 46 }, // í + { 238, 0, 12, 2, 48 }, // î + { 239, 0, 12, 0, 48 }, // ? + { 241, 0, 17, 64, 48 }, // ? + { 242, 0, 18, 2, 46 }, // ? + { 243, 0, 18, 64, 46 }, // ó + { 244, 0, 18, 2, 48 }, // ô + { 245, 0, 18, 64, 48 }, // ? + { 246, 0, 18, 0, 48 }, // ö + { 248, 0, 51, 0, 0 }, // ? + { 249, 0, 24, 2, 46 }, // ? + { 250, 0, 24, 64, 46 }, // ú + { 251, 0, 24, 2, 48 }, // ? + { 252, 0, 24, 0, 48 }, // ü + { 253, 0, 28, 64, 46 }, // ý + { 255, 0, 28, 0, 48 }, // ? + { 8364, 64, 34, 0, 0 }, // € + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x22 , -1 , 0x40 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x23 , -1 , 0x00a3 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x00a4 , -1 , 0x24 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , 0x20ac , -1 } , + /* 7 */ { 0 , (int)'6' , 0x26 , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , 0x007b , -1 } , + /* 9 */ { 0 , (int)'8' , 0x28 , -1 , 0x005b , -1 } , + /* 0a */ { 0 , (int)'9' , 0x29 , -1 , 0x005d , -1 } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , 0x007d , -1 } , + /* 0c */ { 0 , 0x002b , 0x003f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x005c , 0x0060 , -1 , 0x00b4 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 1 , 0x00e5 , 0x00c5 , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x00a8 , 0x005e , 0x001d , 0x007e , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 1 , 0x00f8 , 0x00d8 , -1 , -1 , -1 } , + /* 28 */ { 1 , 0x00e6 , 0x00c6 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x007c , 0x00a7 , 0x001c , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x27 , 0x002a , -1 , -1 , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x0060, 0x00b4, 0x00a8, 0x005e, 0x007e + }; + + //0x0060 => 0061 00e0 // a -> à + public static final int DEADKEY_LUT[][] = { + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + }; + + + + private static NorwegianLayout instance = new NorwegianLayout(); + + private NorwegianLayout() { + } + + public static NorwegianLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} + diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/PolishLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/PolishLayout.java new file mode 100644 index 00000000..d7b9a223 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/PolishLayout.java @@ -0,0 +1,312 @@ +package com.inputstick.api.layout; + + +public class PolishLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "pl-PL"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //pl-PL + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 52, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 36, 0, 0 }, // & + { 39, 0, 52, 0, 0 }, // ' + { 40, 2, 38, 0, 0 }, // ( + { 41, 2, 39, 0, 0 }, // ) + { 42, 2, 37, 0, 0 }, // * + { 43, 2, 46, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 45, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 0, 56, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 51, 0, 0 }, // : + { 59, 0, 51, 0, 0 }, // ; + { 60, 2, 54, 0, 0 }, // < + { 61, 0, 46, 0, 0 }, // = + { 62, 2, 55, 0, 0 }, // > + { 63, 2, 56, 0, 0 }, // ? + { 64, 2, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 0, 47, 0, 0 }, // [ + { 92, 0, 49, 0, 0 }, // \ + { 93, 0, 48, 0, 0 }, // ] + { 94, 2, 35, 0, 0 }, // ^ + { 95, 2, 45, 0, 0 }, // _ + { 96, 0, 53, 0, 0 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 2, 47, 0, 0 }, // { + { 124, 2, 49, 0, 0 }, // | + { 125, 2, 48, 0, 0 }, // } + { 126, 0, 44, 2, 53 }, // ~ + { 211, 66, 18, 0, 0 }, // + { 243, 64, 18, 0, 0 }, // + { 260, 66, 4, 0, 0 }, // + { 261, 64, 4, 0, 0 }, // + { 262, 66, 6, 0, 0 }, // + { 263, 64, 6, 0, 0 }, // + { 280, 66, 8, 0, 0 }, // + { 281, 64, 8, 0, 0 }, // + { 321, 66, 15, 0, 0 }, // + { 322, 64, 15, 0, 0 }, // + { 323, 66, 17, 0, 0 }, // + { 324, 64, 17, 0, 0 }, // + { 346, 66, 22, 0, 0 }, // + { 347, 64, 22, 0, 0 }, // + { 377, 66, 27, 0, 0 }, // + { 378, 64, 27, 0, 0 }, // + { 379, 66, 29, 0, 0 }, // + { 380, 64, 29, 0, 0 }, // + { 8364, 64, 24, 0, 0 }, // + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x40 , -1 , -1 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x23 , -1 , -1 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x24 , -1 , -1 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , -1 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x005e , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x26 , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x28 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x29 , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x003d , 0x002b , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 5 , (int)'e' , (int)'E' , -1 , 0x119 , 0x118 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , 0x20ac , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 5 , (int)'o' , (int)'O' , -1 , 0x00f3 , 0x00d3 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x005b , 0x007b , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x005d , 0x007d , 0x001d , -1 , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 5 , (int)'a' , (int)'A' , -1 , 0x105 , 0x104 } , + /* 1f */ { 5 , (int)'s' , (int)'S' , -1 , 0x015b , 0x015a } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 5 , (int)'l' , (int)'L' , -1 , 0x142 , 0x141 } , + /* 27 */ { 0 , 0x003b , 0x003a , 0x001d , -1 , -1 } , + /* 28 */ { 0 , 0x27 , 0x22 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x60 , 0x007e , -1 , -1 , -1 } , //@ + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + /* 2c */ { 5 , (int)'z' , (int)'Z' , -1 , 0x017c , 0x017b } , + /* 2d */ { 5 , (int)'x' , (int)'X' , -1 , 0x017a , 0x179 } , + /* 2e */ { 5 , (int)'c' , (int)'C' , -1 , 0x107 , 0x106 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 5 , (int)'n' , (int)'N' , -1 , 0x144 , 0x143 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003c , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003e , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002f , 0x003f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + }; + + public static final int DEADKEYS[] = { + 0x007e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x007e , 0x006e , 0x0144 } , + { 0x007e , 0x0063 , 0x0107 } , + { 0x007e , 0x0078 , 0x017a } , + { 0x007e , 0x007a , 0x017c } , + { 0x007e , 0x0061 , 0x0105 } , + { 0x007e , 0x0073 , 0x015b } , + { 0x007e , 0x006c , 0x0142 } , + { 0x007e , 0x0065 , 0x0119 } , + { 0x007e , 0x006f , 0x00f3 } , + { 0x007e , 0x004e , 0x0143 } , + { 0x007e , 0x0043 , 0x0106 } , + { 0x007e , 0x0058 , 0x0179 } , + { 0x007e , 0x005a , 0x017b } , + { 0x007e , 0x0041 , 0x0104 } , + { 0x007e , 0x0053 , 0x015a } , + { 0x007e , 0x004c , 0x0141 } , + { 0x007e , 0x0045 , 0x0118 } , + { 0x007e , 0x004f , 0x00d3 } , + { 0x007e , 0x0020 , 0x007e } , + }; + + private static PolishLayout instance = new PolishLayout(); + + private PolishLayout() { + } + + public static PolishLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/PortugueseBrazilianLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/PortugueseBrazilianLayout.java new file mode 100644 index 00000000..953ce76a --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/PortugueseBrazilianLayout.java @@ -0,0 +1,399 @@ +package com.inputstick.api.layout; + +public class PortugueseBrazilianLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "pt-BR"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //pt-BR + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 48, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 51, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 53, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 36, 0, 0 }, // & + { 39, 0, 53, 0, 0 }, // ' + { 40, 2, 38, 0, 0 }, // ( + { 41, 2, 39, 0, 0 }, // ) + { 42, 2, 37, 0, 0 }, // * + { 43, 2, 46, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 45, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 64, 20, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 56, 0, 0 }, // : + { 59, 0, 56, 0, 0 }, // ; + { 60, 2, 54, 0, 0 }, // < + { 61, 0, 46, 0, 0 }, // = + { 62, 2, 55, 0, 0 }, // > + { 63, 64, 26, 0, 0 }, // ? + { 64, 2, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 0, 48, 0, 0 }, // [ + { 92, 0, 100, 0, 0 }, // \ + { 93, 0, 49, 0, 0 }, // ] + { 94, 0, 44, 2, 52 }, // ^ + { 95, 2, 45, 0, 0 }, // _ + { 96, 0, 44, 2, 47 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 2, 48, 0, 0 }, // { + { 124, 2, 100, 0, 0 }, // | + { 125, 2, 49, 0, 0 }, // } + { 126, 0, 44, 0, 52 }, // ~ + { 162, 64, 34, 0, 0 }, // ? + { 163, 64, 33, 0, 0 }, // ? + { 167, 64, 46, 0, 0 }, // + { 168, 0, 44, 2, 35 }, // + { 170, 64, 48, 0, 0 }, // ? + { 172, 64, 35, 0, 0 }, // + { 176, 64, 8, 0, 0 }, // + { 178, 64, 31, 0, 0 }, // ? + { 179, 64, 32, 0, 0 }, // ? + { 180, 0, 44, 0, 47 }, // + { 185, 64, 30, 0, 0 }, // ? + { 186, 64, 49, 0, 0 }, // ? + { 192, 2, 4, 2, 47 }, // ? + { 193, 2, 4, 0, 47 }, // + { 194, 2, 4, 2, 52 }, // + { 195, 2, 4, 0, 52 }, // ? + { 196, 2, 4, 2, 35 }, // + { 199, 2, 51, 0, 0 }, // + { 200, 2, 8, 2, 47 }, // ? + { 201, 2, 8, 0, 47 }, // + { 202, 2, 8, 2, 52 }, // ? + { 203, 2, 8, 2, 35 }, // + { 204, 2, 12, 2, 47 }, // ? + { 205, 2, 12, 0, 47 }, // + { 206, 2, 12, 2, 52 }, // + { 207, 2, 12, 2, 35 }, // ? + { 209, 2, 17, 0, 52 }, // ? + { 210, 2, 18, 2, 47 }, // ? + { 211, 2, 18, 0, 47 }, // + { 212, 2, 18, 2, 52 }, // + { 213, 2, 18, 0, 52 }, // ? + { 214, 2, 18, 2, 35 }, // + { 217, 2, 24, 2, 47 }, // ? + { 218, 2, 24, 0, 47 }, // + { 219, 2, 24, 2, 52 }, // ? + { 220, 2, 24, 2, 35 }, // + { 221, 2, 28, 0, 47 }, // + { 224, 0, 4, 2, 47 }, // ? + { 225, 0, 4, 0, 47 }, // + { 226, 0, 4, 2, 52 }, // + { 227, 0, 4, 0, 52 }, // ? + { 228, 0, 4, 2, 35 }, // + { 231, 0, 51, 0, 0 }, // + { 232, 0, 8, 2, 47 }, // ? + { 233, 0, 8, 0, 47 }, // + { 234, 0, 8, 2, 52 }, // ? + { 235, 0, 8, 2, 35 }, // + { 236, 0, 12, 2, 47 }, // ? + { 237, 0, 12, 0, 47 }, // + { 238, 0, 12, 2, 52 }, // + { 239, 0, 12, 2, 35 }, // ? + { 241, 0, 17, 0, 52 }, // ? + { 242, 0, 18, 2, 47 }, // ? + { 243, 0, 18, 0, 47 }, // + { 244, 0, 18, 2, 52 }, // + { 245, 0, 18, 0, 52 }, // ? + { 246, 0, 18, 2, 35 }, // + { 249, 0, 24, 2, 47 }, // ? + { 250, 0, 24, 0, 47 }, // + { 251, 0, 24, 2, 52 }, // ? + { 252, 0, 24, 2, 35 }, // + { 253, 0, 28, 0, 47 }, // + { 255, 0, 28, 2, 35 }, // ? + { 8354, 64, 6, 0, 0 }, // ? + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , 0x00b9 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x40 , -1 , 0x00b2 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x23 , -1 , 0x00b3 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x24 , -1 , 0x00a3 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , 0x00a2 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x00a8 , -1 , 0x00ac , -1 } , + /* 8 */ { 0 , (int)'7' , 0x26 , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x28 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x29 , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x003d , 0x002b , -1 , 0x00a7 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , 0x002f , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , 0x003f , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x00b0 , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x00b4 , 0x0060 , -1 , -1 , -1 } , + /* 1b */ { 0 , 0x005b , 0x007b , 0x001b , 0x00aa , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 1 , 0x00e7 , 0x00c7 , 0x001d , -1 , -1 } , + /* 28 */ { 0 , 0x007e , 0x005e , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x27 , 0x22 , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x005d , 0x007d , 0x001c , 0x00ba , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , 0x20a2 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003c , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003e , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x003b , 0x003a , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + /* 73 */ /*{ 0 , 002f , 003f , -1 , 00b0 , -1 } ,*/ + /* 7e */ /*{ 0 , 002e , 002e , -1 , -1 , -1 } ,*/ + + + + + }; + + public static final int DEADKEYS[] = { + 0x00a8, 0x00b4, 0x0060, 0x007e, 0x005e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + + }; + + private static PortugueseBrazilianLayout instance = new PortugueseBrazilianLayout(); + + private PortugueseBrazilianLayout() { + } + + public static PortugueseBrazilianLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/RussianLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/RussianLayout.java new file mode 100644 index 00000000..0c2c7d0c --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/RussianLayout.java @@ -0,0 +1,269 @@ +package com.inputstick.api.layout; + +public class RussianLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "ru-RU"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //ru-RU + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 28, 1, 49, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 37, 2, 34, 0, 0 }, // % + { 40, 2, 38, 0, 0 }, // ( + { 41, 2, 39, 0, 0 }, // ) + { 42, 2, 37, 0, 0 }, // * + { 43, 2, 46, 0, 0 }, // + + { 44, 2, 56, 0, 0 }, // , + { 45, 0, 45, 0, 0 }, // - + { 46, 0, 56, 0, 0 }, // . + { 47, 2, 49, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 35, 0, 0 }, // : + { 59, 2, 33, 0, 0 }, // ; + { 61, 0, 46, 0, 0 }, // = + { 63, 2, 36, 0, 0 }, // ? + { 92, 0, 49, 0, 0 }, // \ + { 95, 2, 45, 0, 0 }, // _ + { 1025, 2, 53, 0, 0 }, // ? + { 1040, 2, 9, 0, 0 }, // ? + { 1041, 2, 54, 0, 0 }, // ? + { 1042, 2, 7, 0, 0 }, // ? + { 1043, 2, 24, 0, 0 }, // ? + { 1044, 2, 15, 0, 0 }, // ? + { 1045, 2, 23, 0, 0 }, // ? + { 1046, 2, 51, 0, 0 }, // ? + { 1047, 2, 19, 0, 0 }, // ? + { 1048, 2, 5, 0, 0 }, // ? + { 1049, 2, 20, 0, 0 }, // ? + { 1050, 2, 21, 0, 0 }, // ? + { 1051, 2, 14, 0, 0 }, // ? + { 1052, 2, 25, 0, 0 }, // ? + { 1053, 2, 28, 0, 0 }, // ? + { 1054, 2, 13, 0, 0 }, // ? + { 1055, 2, 10, 0, 0 }, // ? + { 1056, 2, 11, 0, 0 }, // ? + { 1057, 2, 6, 0, 0 }, // ? + { 1058, 2, 17, 0, 0 }, // ? + { 1059, 2, 8, 0, 0 }, // ? + { 1060, 2, 4, 0, 0 }, // ? + { 1061, 2, 47, 0, 0 }, // ? + { 1062, 2, 26, 0, 0 }, // ? + { 1063, 2, 27, 0, 0 }, // ? + { 1064, 2, 12, 0, 0 }, // ? + { 1065, 2, 18, 0, 0 }, // ? + { 1066, 2, 48, 0, 0 }, // ? + { 1067, 2, 22, 0, 0 }, // ? + { 1068, 2, 16, 0, 0 }, // ? + { 1069, 2, 52, 0, 0 }, // ? + { 1070, 2, 55, 0, 0 }, // ? + { 1071, 2, 29, 0, 0 }, // ? + { 1072, 0, 9, 0, 0 }, // ? + { 1073, 0, 54, 0, 0 }, // ? + { 1074, 0, 7, 0, 0 }, // ? + { 1075, 0, 24, 0, 0 }, // ? + { 1076, 0, 15, 0, 0 }, // ? + { 1077, 0, 23, 0, 0 }, // ? + { 1078, 0, 51, 0, 0 }, // ? + { 1079, 0, 19, 0, 0 }, // ? + { 1080, 0, 5, 0, 0 }, // ? + { 1081, 0, 20, 0, 0 }, // ? + { 1082, 0, 21, 0, 0 }, // ? + { 1083, 0, 14, 0, 0 }, // ? + { 1084, 0, 25, 0, 0 }, // ? + { 1085, 0, 28, 0, 0 }, // ? + { 1086, 0, 13, 0, 0 }, // ? + { 1087, 0, 10, 0, 0 }, // ? + { 1088, 0, 11, 0, 0 }, // ? + { 1089, 0, 6, 0, 0 }, // ? + { 1090, 0, 17, 0, 0 }, // ? + { 1091, 0, 8, 0, 0 }, // ? + { 1092, 0, 4, 0, 0 }, // ? + { 1093, 0, 47, 0, 0 }, // ? + { 1094, 0, 26, 0, 0 }, // ? + { 1095, 0, 27, 0, 0 }, // ? + { 1096, 0, 12, 0, 0 }, // ? + { 1097, 0, 18, 0, 0 }, // ? + { 1098, 0, 48, 0, 0 }, // ? + { 1099, 0, 22, 0, 0 }, // ? + { 1100, 0, 16, 0, 0 }, // ? + { 1101, 0, 52, 0, 0 }, // ? + { 1102, 0, 55, 0, 0 }, // ? + { 1103, 0, 29, 0, 0 }, // ? + { 1105, 0, 53, 0, 0 }, // ? + { 8470, 2, 32, 0, 0 }, // ? + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x22 , -1 , -1 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x2116 , -1 , -1 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x003b , -1 , -1 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , -1 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x003a , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x003f , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x28 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x29 , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x003d , 0x002b , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , 0x439 , 0x419 , -1 , -1 , -1 } , + /* 11 */ { 1 , 0x446 , 0x426 , -1 , -1 , -1 } , + /* 12 */ { 1 , 0x443 , 0x423 , -1 , -1 , -1 } , + /* 13 */ { 1 , 0x043a , 0x041a , -1 , -1 , -1 } , + /* 14 */ { 1 , 0x435 , 0x415 , -1 , -1 , -1 } , + /* 15 */ { 1 , 0x043d , 0x041d , -1 , -1 , -1 } , + /* 16 */ { 1 , 0x433 , 0x413 , -1 , -1 , -1 } , + /* 17 */ { 1 , 0x448 , 0x428 , -1 , -1 , -1 } , + /* 18 */ { 1 , 0x449 , 0x429 , -1 , -1 , -1 } , + /* 19 */ { 1 , 0x437 , 0x417 , -1 , -1 , -1 } , + /* 1a */ { 1 , 0x445 , 0x425 , -1 , -1 , -1 } , + /* 1b */ { 1 , 0x044a , 0x042a , -1 , -1 , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , 0x444 , 0x424 , -1 , -1 , -1 } , + /* 1f */ { 1 , 0x044b , 0x042b , -1 , -1 , -1 } , + + + /* 20 */ { 1 , 0x432 , 0x412 , -1 , -1 , -1 } , + /* 21 */ { 1 , 0x430 , 0x410 , -1 , -1 , -1 } , + /* 22 */ { 1 , 0x043f , 0x041f , -1 , -1 , -1 } , + /* 23 */ { 1 , 0x440 , 0x420 , -1 , -1 , -1 } , + /* 24 */ { 1 , 0x043e , 0x041e , -1 , -1 , -1 } , + /* 25 */ { 1 , 0x043b , 0x041b , -1 , -1 , -1 } , + /* 26 */ { 1 , 0x434 , 0x414 , -1 , -1 , -1 } , + /* 27 */ { 1 , 0x436 , 0x416 , -1 , -1 , -1 } , + /* 28 */ { 1 , 0x044d , 0x042d , -1 , -1 , -1 } , + /* 29 */ { 1 , 0x451 , 0x401 , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x005c , 0x002f , 0x001c , -1 , -1 } , + /* 2c */ { 1 , 0x044f , 0x042f , -1 , -1 , -1 } , + /* 2d */ { 1 , 0x447 , 0x427 , -1 , -1 , -1 } , + /* 2e */ { 1 , 0x441 , 0x421 , -1 , -1 , -1 } , + /* 2f */ { 1 , 0x043c , 0x041c , -1 , -1 , -1 } , + + + /* 30 */ { 1 , 0x438 , 0x418 , -1 , -1 , -1 } , + /* 31 */ { 1 , 0x442 , 0x422 , -1 , -1 , -1 } , + /* 32 */ { 1 , 0x044c , 0x042c , -1 , -1 , -1 } , + /* 33 */ { 1 , 0x431 , 0x411 , -1 , -1 , -1 } , + /* 34 */ { 1 , 0x044e , 0x042e , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002e , 0x002c , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x005c , 0x002f , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static RussianLayout instance = new RussianLayout(); + + private RussianLayout() { + } + + public static RussianLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SlovakLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SlovakLayout.java new file mode 100644 index 00000000..d70f7020 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SlovakLayout.java @@ -0,0 +1,505 @@ +package com.inputstick.api.layout; + +public class SlovakLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "sk-SK"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //sk-SK + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 0, 66, 30, 0, 0 }, // + { 7, 64, 30, 0, 0 }, //  + { 27, 1, 48, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 51, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 52, 0, 0 }, // ! + { 34, 2, 51, 0, 0 }, // " + { 35, 64, 27, 0, 0 }, // # + { 36, 64, 51, 0, 0 }, // $ + { 37, 2, 45, 0, 0 }, // % + { 38, 64, 6, 0, 0 }, // & + { 39, 64, 19, 0, 0 }, // ' + { 40, 2, 48, 0, 0 }, // ( + { 41, 2, 49, 0, 0 }, // ) + { 42, 64, 56, 0, 0 }, // * + { 43, 0, 30, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 47, 0, 0 }, // / + { 48, 2, 39, 0, 0 }, // 0 + { 49, 2, 30, 0, 0 }, // 1 + { 50, 2, 31, 0, 0 }, // 2 + { 51, 2, 32, 0, 0 }, // 3 + { 52, 2, 33, 0, 0 }, // 4 + { 53, 2, 34, 0, 0 }, // 5 + { 54, 2, 35, 0, 0 }, // 6 + { 55, 2, 36, 0, 0 }, // 7 + { 56, 2, 37, 0, 0 }, // 8 + { 57, 2, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 0, 53, 0, 0 }, // ; + { 60, 64, 54, 0, 0 }, // < + { 61, 0, 45, 0, 0 }, // = + { 62, 64, 29, 0, 0 }, // > + { 63, 2, 54, 0, 0 }, // ? + { 64, 64, 25, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 64, 9, 0, 0 }, // [ + { 92, 64, 20, 0, 0 }, // \ + { 93, 64, 10, 0, 0 }, // ] + { 94, 0, 44, 64, 32 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 64, 36, 0, 0 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 64, 5, 0, 0 }, // { + { 124, 64, 26, 0, 0 }, // | + { 125, 64, 17, 0, 0 }, // } + { 164, 64, 49, 0, 0 }, // + { 167, 0, 52, 0, 0 }, // + { 168, 0, 44, 64, 45 }, // + { 176, 0, 44, 64, 34 }, // + { 180, 0, 44, 64, 38 }, // + { 184, 0, 44, 64, 46 }, // + { 193, 2, 4, 64, 38 }, // + { 194, 2, 4, 64, 32 }, // + { 196, 2, 4, 64, 45 }, // + { 199, 2, 6, 64, 46 }, // + { 201, 2, 8, 64, 38 }, // + { 203, 2, 8, 64, 45 }, // + { 205, 2, 12, 64, 38 }, // + { 206, 2, 12, 64, 32 }, // + { 211, 2, 18, 64, 38 }, // + { 212, 2, 18, 64, 32 }, // + { 214, 2, 18, 64, 45 }, // + { 215, 64, 48, 0, 0 }, // + { 218, 2, 24, 64, 38 }, // + { 220, 2, 24, 64, 45 }, // + { 221, 2, 28, 64, 38 }, // + { 223, 64, 52, 0, 0 }, // + { 225, 0, 37, 0, 0 }, // + { 226, 0, 4, 64, 32 }, // + { 228, 0, 48, 0, 0 }, // + { 231, 0, 6, 64, 46 }, // + { 233, 0, 39, 0, 0 }, // + { 235, 0, 8, 64, 45 }, // + { 237, 0, 38, 0, 0 }, // + { 238, 0, 12, 64, 32 }, // + { 243, 0, 18, 64, 38 }, // + { 244, 0, 51, 0, 0 }, // + { 246, 0, 18, 64, 45 }, // + { 247, 64, 47, 0, 0 }, // + { 250, 0, 47, 0, 0 }, // + { 252, 0, 24, 64, 45 }, // + { 253, 0, 36, 0, 0 }, // + { 258, 2, 4, 64, 32 }, // + { 259, 0, 4, 64, 32 }, // + { 260, 2, 4, 64, 35 }, // + { 261, 0, 4, 64, 35 }, // + { 262, 2, 6, 64, 38 }, // + { 263, 0, 6, 64, 38 }, // + { 268, 2, 6, 64, 31 }, // + { 269, 0, 33, 0, 0 }, // + { 270, 2, 7, 64, 31 }, // + { 271, 0, 7, 64, 31 }, // + { 272, 64, 7, 0, 0 }, // + { 273, 64, 22, 0, 0 }, // + { 280, 2, 8, 64, 35 }, // + { 281, 0, 8, 64, 35 }, // + { 282, 2, 8, 64, 31 }, // + { 283, 0, 8, 64, 31 }, // + { 313, 2, 15, 64, 38 }, // + { 314, 0, 15, 64, 38 }, // + { 317, 2, 15, 64, 31 }, // + { 318, 0, 31, 0, 0 }, // + { 321, 64, 15, 0, 0 }, // + { 322, 64, 14, 0, 0 }, // + { 323, 2, 17, 64, 38 }, // + { 324, 0, 17, 64, 38 }, // + { 327, 2, 17, 64, 31 }, // + { 328, 0, 49, 0, 0 }, // + { 336, 2, 18, 64, 39 }, // + { 337, 0, 18, 64, 39 }, // + { 340, 2, 21, 64, 38 }, // + { 341, 0, 21, 64, 38 }, // + { 344, 2, 21, 64, 31 }, // + { 345, 0, 21, 64, 31 }, // + { 346, 2, 22, 64, 38 }, // + { 347, 0, 22, 64, 38 }, // + { 350, 2, 22, 64, 46 }, // + { 351, 0, 22, 64, 46 }, // + { 352, 2, 22, 64, 31 }, // + { 353, 0, 32, 0, 0 }, // + { 354, 2, 23, 64, 46 }, // + { 355, 0, 23, 64, 46 }, // + { 356, 2, 23, 64, 31 }, // + { 357, 0, 34, 0, 0 }, // + { 366, 2, 24, 64, 34 }, // + { 367, 0, 24, 64, 34 }, // + { 368, 2, 24, 64, 39 }, // + { 369, 0, 24, 64, 39 }, // + { 377, 2, 29, 64, 38 }, // + { 378, 0, 29, 64, 38 }, // + { 379, 2, 29, 64, 37 }, // + { 380, 0, 29, 64, 37 }, // + { 381, 2, 29, 64, 31 }, // + { 382, 0, 35, 0, 0 }, // + { 711, 0, 44, 64, 31 }, // + { 728, 0, 44, 64, 33 }, // + { 729, 0, 44, 64, 37 }, // + { 731, 0, 44, 64, 35 }, // + { 733, 0, 44, 64, 39 }, // + { 8364, 64, 8, 0, 0 }, // + }; + + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , 0x02b , (int)'1' , -1 , 0x007 , 0 } , + /* 3 */ { 0 , 0x13e , (int)'2' , -1 , 0x2c7 , 0 } , + /* 4 */ { 0 , 0x161 , (int)'3' , -1 , 0x05e , 0 } , + /* 5 */ { 0 , 0x10d , (int)'4' , -1 , 0x2d8 , 0 } , + /* 6 */ { 0 , 0x165 , (int)'5' , -1 , 0x0b0 , 0 } , + /* 7 */ { 0 , 0x17e , (int)'6' , -1 , 0x2db , 0 } , + /* 8 */ { 0 , 0x0fd , (int)'7' , -1 , 0x060 , 0 } , + /* 9 */ { 0 , 0x0e1 , (int)'8' , -1 , 0x2d9 , 0 } , + /* 0a */ { 0 , 0x0ed , (int)'9' , -1 , 0x0b4 , 0 } , + /* 0b */ { 0 , 0x0e9 , (int)'0' , -1 , 0x2dd , 0 } , + /* 0c */ { 0 , 0x03d , 0x025 , -1 , 0x0a8 , 0 } , + /* 0d */ { 0 , 0x0b4 , 0x2c7 , -1 , 0x0b8 , 0 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , 'q' , 'Q' , -1 , 0x05c , 0 } , + /* 11 */ { 1 , 'w' , 'W' , -1 , 0x07c , 0 } , + /* 12 */ { 1 , 'e' , 'E' , -1 , 0x20ac , 0 } , + /* 13 */ { 1 , 'r' , 'R' , -1 , -1 , 0 } , + /* 14 */ { 1 , 't' , 'T' , -1 , -1 , 0 } , + /* 15 */ { 1 , 'y' , 'Y' , -1 , -1 , 0 } , + /* 16 */ { 1 , 'u' , 'U' , -1 , -1 , 0 } , + /* 17 */ { 1 , 'i' , 'I' , -1 , -1 , 0 } , + /* 18 */ { 1 , 'o' , 'O' , -1 , -1 , 0 } , + /* 19 */ { 1 , 'p' , 'P' , -1 , 0x027 , 0 } , + /* 1a */ { 0 , 0x0fa , 0x02f , -1 , 0x0f7 , 0 } , + /* 1b */ { 0 , 0x0e4 , 0x028 , 0x01b , 0x0d7 , 0 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , 'a' , 'A' , -1 , -1 , 0 } , + /* 1f */ { 1 , 's' , 'S' , -1 , 0x111 , 0 } , + + /* 20 */ { 1 , 'd' , 'D' , -1 , 0x110 , 0 } , + /* 21 */ { 1 , 'f' , 'F' , -1 , 0x05b , 0 } , + /* 22 */ { 1 , 'g' , 'G' , -1 , 0x05d , 0 } , + /* 23 */ { 1 , 'h' , 'H' , -1 , -1 , 0 } , + /* 24 */ { 1 , 'j' , 'J' , -1 , -1 , 0 } , + /* 25 */ { 1 , 'k' , 'K' , -1 , 0x142 , 0 } , + /* 26 */ { 1 , 'l' , 'L' , -1 , 0x141 , 0 } , + /* 27 */ { 0 , 0x0f4 , 0x022 , 0x01d , 0x024 , 0 } , + /* 28 */ { 0 , 0x0a7 , 0x021 , -1 , 0x0df , 0 } , + /* 29 */ { 0 , 0x03b , 0x0b0 , -1 , -1 , 0 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x148 , 0x029 , 0x01c , 0x0a4 , 0 } , + /* 2c */ { 1 , 'z' , 'Z' , -1 , 0x03e , 0 } , + /* 2d */ { 1 , 'x' , 'X' , -1 , 0x023 , 0 } , + /* 2e */ { 1 , 'c' , 'C' , -1 , 0x026 , 0 } , + /* 2f */ { 1 , 'v' , 'V' , -1 , 0x040 , 0 } , + + /* 30 */ { 1 , 'b' , 'B' , -1 , 0x07b , 0 } , + /* 31 */ { 1 , 'n' , 'N' , -1 , 0x07d , 0 } , + /* 32 */ { 1 , 'm' , 'M' , -1 , -1 , 0 } , + /* 33 */ { 0 , 0x02c , 0x03f , -1 , 0x03c , 0 } , + /* 34 */ { 0 , 0x02e , 0x03a , -1 , 0x03e , 0 } , + /* 35 */ { 0 , 0x02d , 0x05f , -1 , 0x02a , 0 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x020 , 0x020 , 0x020 , -1 , 0 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x02c , 0x02c , -1 , -1 , 0 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x026 , 0x02a , 0x01c , 0x03c , 0 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + + }; + + public static final int DEADKEYS[] = { + 0x02c7, 0x005e, 0x02d8, 0x00b0, 0x02db, 0x02d9, 0x00b4, 0x02dd, 0x00a8, 0x00b4, 0x02c7, 0x00b8, 0x00b0 + }; + + public static final int DEADKEY_LUT[][] = { + { 0x02c7 , 0x006e , 0x0148 } , + { 0x02c7 , 0x0063 , 0x010d } , + { 0x02c7 , 0x007a , 0x017e } , + { 0x02c7 , 0x0064 , 0x010f } , + { 0x02c7 , 0x0073 , 0x0161 } , + { 0x02c7 , 0x006c , 0x013e } , + { 0x02c7 , 0x0065 , 0x011b } , + { 0x02c7 , 0x0072 , 0x0159 } , + { 0x02c7 , 0x0074 , 0x0165 } , + { 0x02c7 , 0x004e , 0x0147 } , + { 0x02c7 , 0x0043 , 0x010c } , + { 0x02c7 , 0x005a , 0x017d } , + { 0x02c7 , 0x0044 , 0x010e } , + { 0x02c7 , 0x0053 , 0x0160 } , + { 0x02c7 , 0x004c , 0x013d } , + { 0x02c7 , 0x0045 , 0x011a } , + { 0x02c7 , 0x0052 , 0x0158 } , + { 0x02c7 , 0x0054 , 0x0164 } , + { 0x02c7 , 0x0020 , 0x02c7 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x005e , 0x0061 , 0x0103 } , + { 0x005e , 0x0041 , 0x0102 } , + { 0x005e , 0x0020 , 0x02d8 } , + { 0x00b0 , 0x0075 , 0x016f } , + { 0x00b0 , 0x0055 , 0x016e } , + { 0x00b0 , 0x0020 , 0x00b0 } , + { 0x02db , 0x0061 , 0x0105 } , + { 0x02db , 0x0065 , 0x0119 } , + { 0x02db , 0x0041 , 0x0104 } , + { 0x02db , 0x0045 , 0x0118 } , + { 0x02db , 0x0020 , 0x02db } , + { 0x02d9 , 0x007a , 0x017c } , + { 0x02d9 , 0x005a , 0x017b } , + { 0x02d9 , 0x0020 , 0x02d9 } , + { 0x00b4 , 0x006e , 0x0144 } , + { 0x00b4 , 0x0063 , 0x0107 } , + { 0x00b4 , 0x007a , 0x017a } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0073 , 0x015b } , + { 0x00b4 , 0x006c , 0x013a } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0072 , 0x0155 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x004e , 0x0143 } , + { 0x00b4 , 0x0043 , 0x0106 } , + { 0x00b4 , 0x005a , 0x0179 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0053 , 0x015a } , + { 0x00b4 , 0x004c , 0x0139 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0052 , 0x0154 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x02dd , 0x0075 , 0x0171 } , + { 0x02dd , 0x006f , 0x0151 } , + { 0x02dd , 0x0055 , 0x0170 } , + { 0x02dd , 0x004f , 0x0150 } , + { 0x02dd , 0x0020 , 0x02dd } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + { 0x00b4 , 0x006e , 0x0144 } , + { 0x00b4 , 0x0063 , 0x0107 } , + { 0x00b4 , 0x007a , 0x017a } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0073 , 0x015b } , + { 0x00b4 , 0x006c , 0x013a } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0072 , 0x0155 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x004e , 0x0143 } , + { 0x00b4 , 0x0043 , 0x0106 } , + { 0x00b4 , 0x005a , 0x0179 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0053 , 0x015a } , + { 0x00b4 , 0x004c , 0x0139 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0052 , 0x0154 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x02c7 , 0x006e , 0x0148 } , + { 0x02c7 , 0x0063 , 0x010d } , + { 0x02c7 , 0x007a , 0x017e } , + { 0x02c7 , 0x0064 , 0x010f } , + { 0x02c7 , 0x0073 , 0x0161 } , + { 0x02c7 , 0x006c , 0x013e } , + { 0x02c7 , 0x0065 , 0x011b } , + { 0x02c7 , 0x0072 , 0x0159 } , + { 0x02c7 , 0x0074 , 0x0165 } , + { 0x02c7 , 0x004e , 0x0147 } , + { 0x02c7 , 0x0043 , 0x010c } , + { 0x02c7 , 0x005a , 0x017d } , + { 0x02c7 , 0x0044 , 0x010e } , + { 0x02c7 , 0x0053 , 0x0160 } , + { 0x02c7 , 0x004c , 0x013d } , + { 0x02c7 , 0x0045 , 0x011a } , + { 0x02c7 , 0x0052 , 0x0158 } , + { 0x02c7 , 0x0054 , 0x0164 } , + { 0x02c7 , 0x0020 , 0x02c7 } , + { 0x00b8 , 0x0063 , 0x00e7 } , + { 0x00b8 , 0x0073 , 0x015f } , + { 0x00b8 , 0x0074 , 0x0163 } , + { 0x00b8 , 0x0043 , 0x00c7 } , + { 0x00b8 , 0x0053 , 0x015e } , + { 0x00b8 , 0x0054 , 0x0162 } , + { 0x00b8 , 0x0020 , 0x00b8 } , + { 0x00b0 , 0x0075 , 0x016f } , + { 0x00b0 , 0x0055 , 0x016e } , + { 0x00b0 , 0x0020 , 0x00b0 } , + + }; + + private static SlovakLayout instance = new SlovakLayout(); + + private SlovakLayout() { + } + + public static SlovakLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SpanishLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SpanishLayout.java new file mode 100644 index 00000000..1561cb16 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SpanishLayout.java @@ -0,0 +1,392 @@ +package com.inputstick.api.layout; + +public class SpanishLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "es-ES"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //es-ES + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 20, 1, 44, 0, 0 }, //  + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 64, 32, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 0, 45, 0, 0 }, // ' + { 40, 2, 37, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 48, 0, 0 }, // * + { 43, 0, 48, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 64, 47, 0, 0 }, // [ + { 92, 64, 53, 0, 0 }, // \ + { 93, 64, 48, 0, 0 }, // ] + { 94, 0, 44, 2, 47 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 0, 44, 0, 47 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 64, 52, 0, 0 }, // { + { 124, 64, 30, 0, 0 }, // | + { 125, 64, 49, 0, 0 }, // } + { 126, 0, 44, 64, 33 }, // ~ + { 161, 0, 46, 0, 0 }, // ? + { 168, 0, 44, 2, 52 }, // + { 170, 2, 53, 0, 0 }, // ? + { 172, 64, 35, 0, 0 }, // + { 180, 0, 44, 0, 52 }, // + { 183, 2, 32, 0, 0 }, // + { 186, 0, 53, 0, 0 }, // ? + { 191, 2, 46, 0, 0 }, // ? + { 192, 2, 4, 0, 47 }, // ? + { 193, 2, 4, 0, 52 }, // + { 194, 2, 4, 2, 47 }, // + { 195, 2, 4, 64, 33 }, // ? + { 196, 2, 4, 2, 52 }, // + { 199, 2, 49, 0, 0 }, // + { 200, 2, 8, 0, 47 }, // ? + { 201, 2, 8, 0, 52 }, // + { 202, 2, 8, 2, 47 }, // ? + { 203, 2, 8, 2, 52 }, // + { 204, 2, 12, 0, 47 }, // ? + { 205, 2, 12, 0, 52 }, // + { 206, 2, 12, 2, 47 }, // + { 207, 2, 12, 2, 52 }, // ? + { 209, 2, 51, 0, 0 }, // ? + { 210, 2, 18, 0, 47 }, // ? + { 211, 2, 18, 0, 52 }, // + { 212, 2, 18, 2, 47 }, // + { 213, 2, 18, 64, 33 }, // ? + { 214, 2, 18, 2, 52 }, // + { 217, 2, 24, 0, 47 }, // ? + { 218, 2, 24, 0, 52 }, // + { 219, 2, 24, 2, 47 }, // ? + { 220, 2, 24, 2, 52 }, // + { 221, 2, 28, 0, 52 }, // + { 224, 0, 4, 0, 47 }, // ? + { 225, 0, 4, 0, 52 }, // + { 226, 0, 4, 2, 47 }, // + { 227, 0, 4, 64, 33 }, // ? + { 228, 0, 4, 2, 52 }, // + { 231, 0, 49, 0, 0 }, // + { 232, 0, 8, 0, 47 }, // ? + { 233, 0, 8, 0, 52 }, // + { 234, 0, 8, 2, 47 }, // ? + { 235, 0, 8, 2, 52 }, // + { 236, 0, 12, 0, 47 }, // ? + { 237, 0, 12, 0, 52 }, // + { 238, 0, 12, 2, 47 }, // + { 239, 0, 12, 2, 52 }, // ? + { 241, 0, 51, 0, 0 }, // ? + { 242, 0, 18, 0, 47 }, // ? + { 243, 0, 18, 0, 52 }, // + { 244, 0, 18, 2, 47 }, // + { 245, 0, 18, 64, 33 }, // ? + { 246, 0, 18, 2, 52 }, // + { 249, 0, 24, 0, 47 }, // ? + { 250, 0, 24, 0, 52 }, // + { 251, 0, 24, 2, 47 }, // ? + { 252, 0, 24, 2, 52 }, // + { 253, 0, 28, 0, 52 }, // + { 255, 0, 28, 2, 52 }, // ? + { 8364, 64, 34, 0, 0 }, // + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , 0x007c , -1 } , + /* 3 */ { 0 , (int)'2' , 0x22 , -1 , 0x40 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x00b7 , -1 , 0x23 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x24 , -1 , 0x007e , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , 0x20ac , -1 } , + /* 7 */ { 0 , (int)'6' , 0x26 , -1 , 0x00ac , -1 } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x28 , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x29 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x27 , 0x003f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x00a1 , 0x00bf , -1 , -1 , -1 } , + /* 1e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x0060 , 0x005e , 0x001b , 0x005b , -1 } , + /* 1b */ { 0 , 0x002b , 0x002a , 0x001d , 0x005d , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 1 , 0x00f1 , 0x00d1 , -1 , -1 , -1 } , + /* 28 */ { 0 , 0x00b4 , 0x00a8 , -1 , 0x007b , -1 } , + /* 29 */ { 0 , 0x00ba , 0x00aa , -1 , 0x005c , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 1 , 0x00e7 , 0x00c7 , 0x001c , 0x007d , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x007e, 0x0060, 0x005e, 0x00b4,0x00a8 + }; + + public static final int DEADKEY_LUT[][] = { + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + }; + + private static SpanishLayout instance = new SpanishLayout(); + + private SpanishLayout() { + } + + public static SpanishLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} + diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SwedishLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SwedishLayout.java new file mode 100644 index 00000000..6e56eb03 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SwedishLayout.java @@ -0,0 +1,386 @@ +package com.inputstick.api.layout; + +public class SwedishLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "sv-SE"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //sv-SE + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 53, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 64, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 0, 49, 0, 0 }, // ' + { 40, 2, 37, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 49, 0, 0 }, // * + { 43, 0, 45, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 64, 37, 0, 0 }, // [ + { 92, 64, 45, 0, 0 }, // \ + { 93, 64, 38, 0, 0 }, // ] + { 94, 0, 44, 2, 48 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 0, 44, 2, 46 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 64, 36, 0, 0 }, // { + { 124, 64, 100, 0, 0 }, // | + { 125, 64, 39, 0, 0 }, // } + { 126, 0, 44, 64, 48 }, // ~ + { 163, 64, 32, 0, 0 }, // ? + { 164, 2, 33, 0, 0 }, // + { 167, 0, 53, 0, 0 }, // + { 168, 0, 44, 0, 48 }, // + { 180, 0, 44, 0, 46 }, // + { 181, 64, 16, 0, 0 }, // + { 189, 2, 53, 0, 0 }, // ? + { 192, 2, 4, 2, 46 }, // ? + { 193, 2, 4, 0, 46 }, // + { 194, 2, 4, 2, 48 }, // + { 195, 2, 4, 64, 48 }, // ? + { 196, 2, 52, 0, 0 }, // + { 197, 2, 47, 0, 0 }, // ? + { 200, 2, 8, 2, 46 }, // ? + { 201, 2, 8, 0, 46 }, // + { 202, 2, 8, 2, 48 }, // ? + { 203, 2, 8, 0, 48 }, // + { 204, 2, 12, 2, 46 }, // ? + { 205, 2, 12, 0, 46 }, // + { 206, 2, 12, 2, 48 }, // + { 207, 2, 12, 0, 48 }, // ? + { 209, 2, 17, 64, 48 }, // ? + { 210, 2, 18, 2, 46 }, // ? + { 211, 2, 18, 0, 46 }, // + { 212, 2, 18, 2, 48 }, // + { 213, 2, 18, 64, 48 }, // ? + { 214, 2, 51, 0, 0 }, // + { 217, 2, 24, 2, 46 }, // ? + { 218, 2, 24, 0, 46 }, // + { 219, 2, 24, 2, 48 }, // ? + { 220, 2, 24, 0, 48 }, // + { 221, 2, 28, 0, 46 }, // + { 224, 0, 4, 2, 46 }, // ? + { 225, 0, 4, 0, 46 }, // + { 226, 0, 4, 2, 48 }, // + { 227, 0, 4, 64, 48 }, // ? + { 228, 0, 52, 0, 0 }, // + { 229, 0, 47, 0, 0 }, // ? + { 232, 0, 8, 2, 46 }, // ? + { 233, 0, 8, 0, 46 }, // + { 234, 0, 8, 2, 48 }, // ? + { 235, 0, 8, 0, 48 }, // + { 236, 0, 12, 2, 46 }, // ? + { 237, 0, 12, 0, 46 }, // + { 238, 0, 12, 2, 48 }, // + { 239, 0, 12, 0, 48 }, // ? + { 241, 0, 17, 64, 48 }, // ? + { 242, 0, 18, 2, 46 }, // ? + { 243, 0, 18, 0, 46 }, // + { 244, 0, 18, 2, 48 }, // + { 245, 0, 18, 64, 48 }, // ? + { 246, 0, 51, 0, 0 }, // + { 249, 0, 24, 2, 46 }, // ? + { 250, 0, 24, 0, 46 }, // + { 251, 0, 24, 2, 48 }, // ? + { 252, 0, 24, 0, 48 }, // + { 253, 0, 28, 0, 46 }, // + { 255, 0, 28, 0, 48 }, // ? + { 8364, 64, 34, 0, 0 }, // + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x22 , -1 , 0x40 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x23 , -1 , 0x00a3 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x00a4 , -1 , 0x24 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , 0x20ac , -1 } , + /* 7 */ { 0 , (int)'6' , 0x26 , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , 0x007b , -1 } , + /* 9 */ { 0 , (int)'8' , 0x28 , -1 , 0x005b , -1 } , + /* 0a */ { 0 , (int)'9' , 0x29 , -1 , 0x005d , -1 } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , 0x007d , -1 } , + /* 0c */ { 0 , 0x002b , 0x003f , -1 , 0x005c , -1 } , + /* 0d */ { 0 , 0x00b4 , 0x0060 , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 1 , 0x00e5 , 0x00c5 , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x00a8 , 0x005e , 0x001d , 0x007e , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 1 , 0x00f6 , 0x00d6 , -1 , -1 , -1 } , + /* 28 */ { 1 , 0x00e4 , 0x00c4 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x00a7 , 0x00bd , 0x001c , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x27 , 0x002a , -1 , -1 , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , 0x001c , 0x007c , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x0060, 0x00b4, 0x005e, 0x00a8, 0x007e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + }; + + private static SwedishLayout instance = new SwedishLayout(); + + private SwedishLayout() { + } + + public static SwedishLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} + diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SwissFrenchLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SwissFrenchLayout.java new file mode 100644 index 00000000..4b91d06d --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SwissFrenchLayout.java @@ -0,0 +1,353 @@ +package com.inputstick.api.layout; + +public class SwissFrenchLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "fr-CH"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //fr-CH + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 8, 2, 37, 0, 0 }, //  + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 48, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 64, 32, 0, 0 }, // # + { 36, 0, 49, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 0, 45, 0, 0 }, // ' + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 32, 0, 0 }, // * + { 43, 2, 30, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 29, 0, 0 }, // Y + { 90, 2, 28, 0, 0 }, // Z + { 91, 64, 47, 0, 0 }, // [ + { 92, 64, 100, 0, 0 }, // \ + { 93, 64, 48, 0, 0 }, // ] + { 94, 0, 44, 0, 46 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 0, 44, 2, 46 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 29, 0, 0 }, // y + { 122, 0, 28, 0, 0 }, // z + { 123, 64, 52, 0, 0 }, // { + { 124, 64, 36, 0, 0 }, // | + { 125, 64, 49, 0, 0 }, // } + { 126, 64, 46, 0, 0 }, // ~ + { 162, 64, 37, 0, 0 }, // ? + { 163, 2, 49, 0, 0 }, // ? + { 166, 64, 30, 0, 0 }, // + { 167, 64, 34, 0, 0 }, // + { 168, 0, 48, 0, 0 }, // + { 172, 64, 35, 0, 0 }, // + { 176, 64, 33, 0, 0 }, // + { 180, 0, 44, 64, 45 }, // + { 192, 2, 4, 2, 46 }, // ? + { 193, 2, 4, 64, 45 }, // + { 194, 2, 4, 0, 46 }, // + { 200, 2, 8, 2, 46 }, // ? + { 201, 2, 8, 64, 45 }, // + { 202, 2, 8, 0, 46 }, // ? + { 204, 2, 12, 2, 46 }, // ? + { 205, 2, 12, 64, 45 }, // + { 206, 2, 12, 0, 46 }, // + { 210, 2, 18, 2, 46 }, // ? + { 211, 2, 18, 64, 45 }, // + { 212, 2, 18, 0, 46 }, // + { 217, 2, 24, 2, 46 }, // ? + { 218, 2, 24, 64, 45 }, // + { 219, 2, 24, 0, 46 }, // ? + { 221, 2, 29, 64, 45 }, // + { 224, 0, 52, 0, 0 }, // ? + { 225, 0, 4, 64, 45 }, // + { 226, 0, 4, 0, 46 }, // + { 228, 2, 52, 0, 0 }, // + { 231, 2, 33, 0, 0 }, // + { 232, 0, 47, 0, 0 }, // ? + { 233, 0, 51, 0, 0 }, // + { 234, 0, 8, 0, 46 }, // ? + { 236, 0, 12, 2, 46 }, // ? + { 237, 0, 12, 64, 45 }, // + { 238, 0, 12, 0, 46 }, // + { 242, 0, 18, 2, 46 }, // ? + { 243, 0, 18, 64, 45 }, // + { 244, 0, 18, 0, 46 }, // + { 246, 2, 51, 0, 0 }, // + { 249, 0, 24, 2, 46 }, // ? + { 250, 0, 24, 64, 45 }, // + { 251, 0, 24, 0, 46 }, // ? + { 252, 2, 47, 0, 0 }, // + { 253, 0, 29, 64, 45 }, // + { 8364, 64, 8, 0, 0 }, // + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x002b , -1 , 0x00a6 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x0022 , -1 , 0x0040 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x002a , -1 , 0x0023 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x00e7 , -1 , 0x00b0 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x0025 , -1 , 0x00a7 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x0026 , -1 , 0x00ac , -1 } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , 0x007c , -1 } , + /* 9 */ { 0 , (int)'8' , 0x008 , -1 , 0x00a2 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x0029 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x0027 , 0x003f , -1 , 0x00b4 , -1 } , + /* 0d */ { 0 , 0x005e , 0x0060 , -1 , 0x007e , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x00e8 , 0x00fc , 0x001b , 0x005b , -1 } , + /* 1b */ { 0 , 0x00a8 , 0x0021 , 0x001d , 0x005d , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 0 , 0x00e9 , 0x00f6 , -1 , -1 , -1 } , + /* 28 */ { 0 , 0x00e0 , 0x00e4 , -1 , 0x007b , -1 } , + /* 29 */ { 0 , 0x00a7 , 0x00b0 , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x0024 , 0x00a3 , 0x001c , 0x007d , -1 } , + /* 2c */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , 0x001c , 0x005c , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x0060, 0x00b4, 0x005e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + + }; + + private static SwissFrenchLayout instance = new SwissFrenchLayout(); + + private SwissFrenchLayout() { + } + + public static SwissFrenchLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SwissGermanLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SwissGermanLayout.java new file mode 100644 index 00000000..3f5067a9 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/SwissGermanLayout.java @@ -0,0 +1,388 @@ +package com.inputstick.api.layout; + +public class SwissGermanLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "de-CH"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //de-CH + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 48, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 64, 32, 0, 0 }, // # + { 36, 0, 49, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 0, 45, 0, 0 }, // ' + { 40, 2, 37, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 32, 0, 0 }, // * + { 43, 2, 30, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 29, 0, 0 }, // Y + { 90, 2, 28, 0, 0 }, // Z + { 91, 64, 47, 0, 0 }, // [ + { 92, 64, 100, 0, 0 }, // \ + { 93, 64, 48, 0, 0 }, // ] + { 94, 0, 44, 0, 46 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 0, 44, 2, 46 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 29, 0, 0 }, // y + { 122, 0, 28, 0, 0 }, // z + { 123, 64, 52, 0, 0 }, // { + { 124, 64, 36, 0, 0 }, // | + { 125, 64, 49, 0, 0 }, // } + { 126, 0, 44, 64, 46 }, // ~ + { 162, 64, 37, 0, 0 }, // ? + { 163, 2, 49, 0, 0 }, // ? + { 166, 64, 30, 0, 0 }, // + { 167, 64, 34, 0, 0 }, // + { 168, 0, 44, 0, 48 }, // + { 172, 64, 35, 0, 0 }, // + { 176, 64, 33, 0, 0 }, // + { 180, 0, 44, 64, 45 }, // + { 192, 2, 4, 2, 46 }, // ? + { 193, 2, 4, 64, 45 }, // + { 194, 2, 4, 0, 46 }, // + { 195, 2, 4, 64, 46 }, // ? + { 196, 2, 4, 0, 48 }, // + { 200, 2, 8, 2, 46 }, // ? + { 201, 2, 8, 64, 45 }, // + { 202, 2, 8, 0, 46 }, // ? + { 203, 2, 8, 0, 48 }, // + { 204, 2, 12, 2, 46 }, // ? + { 205, 2, 12, 64, 45 }, // + { 206, 2, 12, 0, 46 }, // + { 207, 2, 12, 0, 48 }, // ? + { 209, 2, 17, 64, 46 }, // ? + { 210, 2, 18, 2, 46 }, // ? + { 211, 2, 18, 64, 45 }, // + { 212, 2, 18, 0, 46 }, // + { 213, 2, 18, 64, 46 }, // ? + { 214, 2, 18, 0, 48 }, // + { 217, 2, 24, 2, 46 }, // ? + { 218, 2, 24, 64, 45 }, // + { 219, 2, 24, 0, 46 }, // ? + { 220, 2, 24, 0, 48 }, // + { 221, 2, 29, 64, 45 }, // + { 224, 2, 52, 0, 0 }, // ? + { 225, 0, 4, 64, 45 }, // + { 226, 0, 4, 0, 46 }, // + { 227, 0, 4, 64, 46 }, // ? + { 228, 0, 52, 0, 0 }, // + { 231, 2, 33, 0, 0 }, // + { 232, 2, 47, 0, 0 }, // ? + { 233, 2, 51, 0, 0 }, // + { 234, 0, 8, 0, 46 }, // ? + { 235, 0, 8, 0, 48 }, // + { 236, 0, 12, 2, 46 }, // ? + { 237, 0, 12, 64, 45 }, // + { 238, 0, 12, 0, 46 }, // + { 239, 0, 12, 0, 48 }, // ? + { 241, 0, 17, 64, 46 }, // ? + { 242, 0, 18, 2, 46 }, // ? + { 243, 0, 18, 64, 45 }, // + { 244, 0, 18, 0, 46 }, // + { 245, 0, 18, 64, 46 }, // ? + { 246, 0, 51, 0, 0 }, // + { 249, 0, 24, 2, 46 }, // ? + { 250, 0, 24, 64, 45 }, // + { 251, 0, 24, 0, 46 }, // ? + { 252, 0, 47, 0, 0 }, // + { 253, 0, 29, 64, 45 }, // + { 255, 0, 29, 0, 48 }, // ? + { 8364, 64, 8, 0, 0 }, // + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x002b , -1 , 0x00a6 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x0022 , -1 , 0x0040 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x002a , -1 , 0x0023 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x00e7 , -1 , 0x00b0 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x0025 , -1 , 0x00a7 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x0026 , -1 , 0x00ac , -1 } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , 0x007c , -1 } , + /* 9 */ { 0 , (int)'8' , 0x0028 , -1 , 0x00a2 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x0029 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x0027 , 0x003f , -1 , 0x00b4 , -1 } , + /* 0d */ { 0 , 0x005e , 0x0060 , -1 , 0x007e , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x00fc , 0x00e8 , 0x001b , 0x005b , -1 } , // TODO SGCap + /* 1b */ { 0 , 0x00a8 , 0x0021 , 0x001d , 0x005d , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 0 , 0x00f6 , 0x00e9 , -1 , -1 , -1 } , // TODO SGCap + /* 28 */ { 0 , 0x00e4 , 0x00e0 , -1 , 0x007b , -1 } , // TODO SGCap + /* 29 */ { 0 , 0x00a7 , 0x00b0 , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x0024 , 0x00a3 , 0x001c , 0x007d , -1 } , + /* 2c */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , 0x001c , 0x005c , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x00b4, 0x005e, 0x0060, 0x007e, 0x00a8 + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + }; + + + + private static SwissGermanLayout instance = new SwissGermanLayout(); + + private SwissGermanLayout() { + } + + public static SwissGermanLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} + diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/UnitedKingdomLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/UnitedKingdomLayout.java new file mode 100644 index 00000000..040db75b --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/UnitedKingdomLayout.java @@ -0,0 +1,283 @@ +package com.inputstick.api.layout; + +public class UnitedKingdomLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "en-GB"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //en-GB + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 0, 49, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 36, 0, 0 }, // & + { 39, 0, 52, 0, 0 }, // ' + { 40, 2, 38, 0, 0 }, // ( + { 41, 2, 39, 0, 0 }, // ) + { 42, 2, 37, 0, 0 }, // * + { 43, 2, 46, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 45, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 0, 56, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 51, 0, 0 }, // : + { 59, 0, 51, 0, 0 }, // ; + { 60, 2, 54, 0, 0 }, // < + { 61, 0, 46, 0, 0 }, // = + { 62, 2, 55, 0, 0 }, // > + { 63, 2, 56, 0, 0 }, // ? + { 64, 2, 52, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 0, 47, 0, 0 }, // [ + { 92, 0, 100, 0, 0 }, // \ + { 93, 0, 48, 0, 0 }, // ] + { 94, 2, 35, 0, 0 }, // ^ + { 95, 2, 45, 0, 0 }, // _ + { 96, 0, 53, 0, 0 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 2, 47, 0, 0 }, // { + { 124, 2, 100, 0, 0 }, // | + { 125, 2, 48, 0, 0 }, // } + { 126, 2, 49, 0, 0 }, // ~ + { 163, 2, 32, 0, 0 }, // ? + { 166, 64, 53, 0, 0 }, // + { 172, 2, 53, 0, 0 }, // + { 193, 66, 4, 0, 0 }, // + { 201, 66, 8, 0, 0 }, // + { 205, 66, 12, 0, 0 }, // + { 211, 66, 18, 0, 0 }, // + { 218, 66, 24, 0, 0 }, // + { 225, 64, 4, 0, 0 }, // + { 233, 64, 8, 0, 0 }, // + { 237, 64, 12, 0, 0 }, // + { 243, 64, 18, 0, 0 }, // + { 250, 64, 24, 0, 0 }, // + { 8364, 64, 33, 0, 0 }, // + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x22 , -1 , -1 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x00a3 , -1 , -1 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x24 , -1 , 0x20ac , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , -1 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x005e , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x26 , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x28 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x29 , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x003d , 0x002b , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 5 , (int)'e' , (int)'E' , -1 , 0x00e9 , 0x00c9 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 5 , (int)'u' , (int)'U' , -1 , 0x00fa , 0x00da } , + /* 17 */ { 5 , (int)'i' , (int)'I' , -1 , 0x00ed , 0x00cd } , + /* 18 */ { 5 , (int)'o' , (int)'O' , -1 , 0x00f3 , 0x00d3 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x005b , 0x007b , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x005d , 0x007d , 0x001d , -1 , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 5 , (int)'a' , (int)'A' , -1 , 0x00e1 , 0x00c1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 0 , 0x003b , 0x003a , -1 , -1 , -1 } , + /* 28 */ { 0 , 0x27 , 0x40 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x60 , 0x00ac , -1 , 0x00a6 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x23 , 0x007e , 0x001c , -1 , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003c , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003e , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002f , 0x003f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static UnitedKingdomLayout instance = new UnitedKingdomLayout(); + + private UnitedKingdomLayout() { + } + + public static UnitedKingdomLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/UnitedStatesLayout.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/UnitedStatesLayout.java new file mode 100644 index 00000000..62097466 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/api/layout/UnitedStatesLayout.java @@ -0,0 +1,268 @@ +package com.inputstick.api.layout; + +public class UnitedStatesLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "en-US"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //en-US + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 52, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 36, 0, 0 }, // & + { 39, 0, 52, 0, 0 }, // ' + { 40, 2, 38, 0, 0 }, // ( + { 41, 2, 39, 0, 0 }, // ) + { 42, 2, 37, 0, 0 }, // * + { 43, 2, 46, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 45, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 0, 56, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 51, 0, 0 }, // : + { 59, 0, 51, 0, 0 }, // ; + { 60, 2, 54, 0, 0 }, // < + { 61, 0, 46, 0, 0 }, // = + { 62, 2, 55, 0, 0 }, // > + { 63, 2, 56, 0, 0 }, // ? + { 64, 2, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 0, 47, 0, 0 }, // [ + { 92, 0, 49, 0, 0 }, // \ + { 93, 0, 48, 0, 0 }, // ] + { 94, 2, 35, 0, 0 }, // ^ + { 95, 2, 45, 0, 0 }, // _ + { 96, 0, 53, 0, 0 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 2, 47, 0, 0 }, // { + { 124, 2, 49, 0, 0 }, // | + { 125, 2, 48, 0, 0 }, // } + { 126, 2, 53, 0, 0 }, // ~ + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x40 , -1 , -1 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x23 , -1 , -1 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x24 , -1 , -1 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , -1 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x005e , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x26 , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x28 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x29 , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x003d , 0x002b , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , -1 , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x005b , 0x007b , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x005d , 0x007d , 0x001d , -1 , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 0 , 0x003b , 0x003a , -1 , -1 , -1 } , + /* 28 */ { 0 , 0x27 , 0x22 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x60 , 0x007e , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003c , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003e , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002f , 0x003f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static UnitedStatesLayout instance = new UnitedStatesLayout(); + + private UnitedStatesLayout() { + } + + public static UnitedStatesLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/BasicInitManager.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/BasicInitManager.java new file mode 100644 index 00000000..9af6e902 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/BasicInitManager.java @@ -0,0 +1,78 @@ +package com.inputstick.init; + +import com.inputstick.api.Packet; + + +public class BasicInitManager extends InitManager { + + private static final int UPDATES_LIMIT = 50; + private static final int RETRY_LIMIT = 3; + + + private int lastStatusParam; + private int noInitUpdatesCnt; + private int noInitRetryCnt; + + public BasicInitManager(byte[] key) { + super(key); + lastStatusParam = 0; + } + + + @Override + public void onConnected() { + sendPacket(new Packet(true, Packet.CMD_RUN_FW)); + } + + @Override + public void onData(byte[] data) { + byte cmd = data[0]; + byte respCode = data[1]; + byte param = data[1]; + + switch (cmd) { + case Packet.CMD_RUN_FW: + sendPacket(new Packet(true, Packet.CMD_FW_INFO)); + break; + case Packet.CMD_FW_INFO: + onFWInfo(data, true, true, new Packet(true, Packet.CMD_INIT)); //TODO next FW: params! + break; + case Packet.CMD_INIT: + if (respCode == Packet.RESP_OK) { + initDone = true; + noInitUpdatesCnt = 0; + noInitRetryCnt = 0; + sendPacket(new Packet(true, Packet.CMD_HID_STATUS_REPORT)); + } else { + mListener.onInitFailure(respCode); + } + break; + case Packet.CMD_INIT_AUTH: + onAuth(data, true, new Packet(true, Packet.CMD_INIT)); //TODO next FW: params! + break; + case Packet.CMD_HID_STATUS: + if (initDone) { + if (param != lastStatusParam) { + lastStatusParam = param; + if (param == 0x05) { + mListener.onInitReady(); + } else { + mListener.onInitNotReady(); + } + } + } else { + noInitUpdatesCnt++; + if (noInitUpdatesCnt == UPDATES_LIMIT) { + noInitUpdatesCnt = 0; + if (noInitRetryCnt < RETRY_LIMIT) { + sendPacket(new Packet(true, Packet.CMD_RUN_FW)); + noInitRetryCnt++; + } + } + } + break; + } + } + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/BootloaderInitManager.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/BootloaderInitManager.java new file mode 100644 index 00000000..ea49b56d --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/BootloaderInitManager.java @@ -0,0 +1,28 @@ +package com.inputstick.init; + +import com.inputstick.api.Packet; + +public class BootloaderInitManager extends InitManager { + + public BootloaderInitManager(byte[] key) { + super(key); + } + + @Override + public void onConnected() { + //TODO key + sendPacket(new Packet(true, Packet.CMD_RUN_BL)); + } + + @Override + public void onData(byte[] data) { + byte cmd = data[0]; + //byte respCode = data[1]; + //byte param = data[1]; + + if (cmd == Packet.CMD_RUN_BL) { + mListener.onInitReady(); + } + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/DeviceInfo.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/DeviceInfo.java new file mode 100644 index 00000000..286bed75 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/DeviceInfo.java @@ -0,0 +1,89 @@ +package com.inputstick.init; + +public class DeviceInfo { + + private int firmwareType; + private int versionMajor; + private int versionMinor; + private int versionHardware; + private int securityStatus; + + private boolean passwordProtected; + + public DeviceInfo(byte[] data) { + //cmd, param + firmwareType = data[2]; + versionMajor = data[3]; + versionMinor = data[4]; + versionHardware = data[5]; + + + //6,7,8,9 + //10,11,12,13 + //14,15,16,17 + + //18,19 + securityStatus = data[19]; + if (data[20] == 0) { + passwordProtected = false; + } else { + passwordProtected = true; + } + } + + public int getSecurityStatus() { + return securityStatus; + } + + public boolean isAuthenticated() { + return ((securityStatus & 0x10) != 0); + } + + public boolean isUnlocked() { + if (getFirmwareVersion() < 96) { + return true; + } else { + return ((securityStatus & 0x08) != 0); + } + } + + public int getFirmwareType() { + return firmwareType; + } + + public boolean isPasswordProtected() { + return passwordProtected; + } + + public int getVersionMinor() { + return versionMinor; + } + + public int getVersionMajor() { + return versionMajor; + } + + public int getHardwareVersion() { + return versionHardware; + } + + public int getFirmwareVersion() { + return (versionMajor) * 100 + versionMinor; + } + + + + public boolean supportsEncryption() { + return (getFirmwareVersion() >= 91); + } + + public boolean supportsPinChange() { + return (getFirmwareVersion() >= 97); + } + + public boolean supportsGamepad() { + return (getFirmwareVersion() >= 97); + } + + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/InitManager.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/InitManager.java new file mode 100644 index 00000000..c3c62256 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/InitManager.java @@ -0,0 +1,107 @@ +package com.inputstick.init; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Packet; +import com.inputstick.api.PacketManager; + +public class InitManager { + + public static final int DEFAULT_INIT_TIMEOUT = 60000; //60s init timeout + + protected PacketManager mPacketManager; + protected InitManagerListener mListener; + protected byte[] mKey; + protected DeviceInfo mInfo; + protected boolean initDone; + + public InitManager(byte[] key) { + mKey = key; + } + + + public DeviceInfo getDeviceInfo() { + return mInfo; + } + + public boolean isEncrypted() { + return mPacketManager.isEncrypted(); + } + + + public void init(InitManagerListener listener, PacketManager packetManager) { + mListener = listener; + mPacketManager = packetManager; + + initDone = false; + } + + public void onConnected() { + mListener.onInitReady(); + } + + public void onData(byte[] data) { + //byte cmd = data[0]; + //byte param = data[1]; + } + + public void sendPacket(Packet p) { + mPacketManager.sendPacket(p); + } + + public void onFWInfo(byte[] data, boolean authenticate, boolean enableEncryption, Packet sendNext) { + mInfo = new DeviceInfo(data); + + if (authenticate) { + if (mInfo.isPasswordProtected()) { + if (mKey != null) { + //authenticate + sendPacket(mPacketManager.encPacket(enableEncryption)); + } else { + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NO_KEY); + } + } else { + if (mKey != null) { + //possible scenarios: FW upgrade / password removed using other device/app / tampering! + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_PROTECTED); + } + sendPacket(sendNext); + } + } else { + sendPacket(sendNext); + } + } + + public void onAuth(byte[] data, boolean enableOutEncryption, Packet sendNext) { + byte respCode = data[1]; + + switch (respCode) { + case Packet.RESP_OK: + byte[] cmp = new byte[16]; + //TODO check length! + System.arraycopy(data, 2, cmp, 0, 16); + if (mPacketManager.setEncryption(cmp, enableOutEncryption)) { + sendPacket(sendNext); + } else { + mListener.onInitFailure(InputStickError.ERROR_SECURITY_CHALLENGE); + } + break; + + case 0x20: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_INVALID_KEY); + break; + + case 0x21: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_PROTECTED); + break; + + case Packet.RESP_UNKNOWN_CMD: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_SUPPORTED); + break; + + default: + mListener.onInitFailure(InputStickError.ERROR_SECURITY); + } + + } + +} diff --git a/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/InitManagerListener.java b/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/InitManagerListener.java new file mode 100644 index 00000000..fee3c21a --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/java/com/inputstick/init/InitManagerListener.java @@ -0,0 +1,9 @@ +package com.inputstick.init; + +public interface InitManagerListener { + + public void onInitReady(); + public void onInitNotReady(); + public void onInitFailure(int code); + +} diff --git a/src/java/InputStickAPI/app/src/main/res/drawable-hdpi/ic_launcher.png b/src/java/InputStickAPI/app/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 00000000..96a442e5 Binary files /dev/null and b/src/java/InputStickAPI/app/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/src/java/InputStickAPI/app/src/main/res/drawable-mdpi/ic_launcher.png b/src/java/InputStickAPI/app/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 00000000..359047df Binary files /dev/null and b/src/java/InputStickAPI/app/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/src/java/InputStickAPI/app/src/main/res/drawable-xhdpi/ic_launcher.png b/src/java/InputStickAPI/app/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 00000000..71c6d760 Binary files /dev/null and b/src/java/InputStickAPI/app/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/src/java/InputStickAPI/app/src/main/res/menu/install_utility.xml b/src/java/InputStickAPI/app/src/main/res/menu/install_utility.xml new file mode 100644 index 00000000..c0020282 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/res/menu/install_utility.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/src/java/InputStickAPI/app/src/main/res/values-sw600dp/dimens.xml b/src/java/InputStickAPI/app/src/main/res/values-sw600dp/dimens.xml new file mode 100644 index 00000000..44f01db7 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/res/values-sw600dp/dimens.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/src/java/InputStickAPI/app/src/main/res/values-sw720dp-land/dimens.xml b/src/java/InputStickAPI/app/src/main/res/values-sw720dp-land/dimens.xml new file mode 100644 index 00000000..61e3fa8f --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/res/values-sw720dp-land/dimens.xml @@ -0,0 +1,9 @@ + + + + 128dp + + diff --git a/src/java/PluginInputStick/res/values-v11/styles.xml b/src/java/InputStickAPI/app/src/main/res/values-v11/styles.xml similarity index 100% rename from src/java/PluginInputStick/res/values-v11/styles.xml rename to src/java/InputStickAPI/app/src/main/res/values-v11/styles.xml diff --git a/src/java/PluginInputStick/res/values-v14/styles.xml b/src/java/InputStickAPI/app/src/main/res/values-v14/styles.xml similarity index 100% rename from src/java/PluginInputStick/res/values-v14/styles.xml rename to src/java/InputStickAPI/app/src/main/res/values-v14/styles.xml diff --git a/src/java/PluginInputStick/res/values/dimens.xml b/src/java/InputStickAPI/app/src/main/res/values/dimens.xml similarity index 100% rename from src/java/PluginInputStick/res/values/dimens.xml rename to src/java/InputStickAPI/app/src/main/res/values/dimens.xml diff --git a/src/java/InputStickAPI/app/src/main/res/values/strings.xml b/src/java/InputStickAPI/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..fbe60928 --- /dev/null +++ b/src/java/InputStickAPI/app/src/main/res/values/strings.xml @@ -0,0 +1,9 @@ + + + + InputStickAPI + Download InputStickUtility + Settings + Hello world! + + diff --git a/src/java/PluginInputStick/res/values/styles.xml b/src/java/InputStickAPI/app/src/main/res/values/styles.xml similarity index 100% rename from src/java/PluginInputStick/res/values/styles.xml rename to src/java/InputStickAPI/app/src/main/res/values/styles.xml diff --git a/src/java/InputStickAPI/build.gradle b/src/java/InputStickAPI/build.gradle new file mode 100644 index 00000000..88d246d4 --- /dev/null +++ b/src/java/InputStickAPI/build.gradle @@ -0,0 +1,15 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.2.3' + } +} + +allprojects { + repositories { + jcenter() + } +} diff --git a/src/java/InputStickAPI/build/intermediates/gradle_project_sync_data.bin b/src/java/InputStickAPI/build/intermediates/gradle_project_sync_data.bin new file mode 100644 index 00000000..40ef7efd Binary files /dev/null and b/src/java/InputStickAPI/build/intermediates/gradle_project_sync_data.bin differ diff --git a/src/java/InputStickAPI/gradle/wrapper/gradle-wrapper.jar b/src/java/InputStickAPI/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..8c0fb64a Binary files /dev/null and b/src/java/InputStickAPI/gradle/wrapper/gradle-wrapper.jar differ diff --git a/src/java/InputStickAPI/gradle/wrapper/gradle-wrapper.properties b/src/java/InputStickAPI/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..0c71e760 --- /dev/null +++ b/src/java/InputStickAPI/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Apr 10 15:27:10 PDT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/src/java/InputStickAPI/gradlew b/src/java/InputStickAPI/gradlew new file mode 100644 index 00000000..91a7e269 --- /dev/null +++ b/src/java/InputStickAPI/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/src/java/InputStickAPI/gradlew.bat b/src/java/InputStickAPI/gradlew.bat new file mode 100644 index 00000000..8a0b282a --- /dev/null +++ b/src/java/InputStickAPI/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/java/InputStickAPI/import-summary.txt b/src/java/InputStickAPI/import-summary.txt new file mode 100644 index 00000000..52f4974d --- /dev/null +++ b/src/java/InputStickAPI/import-summary.txt @@ -0,0 +1,60 @@ +ECLIPSE ANDROID PROJECT IMPORT SUMMARY +====================================== + +Ignored Files: +-------------- +The following files were *not* copied into the new Gradle project; you +should evaluate whether these are still needed in your project and if +so manually move them: + +* .gitignore +* .idea\ +* .idea\.name +* .idea\InputStickAPI.iml +* .idea\compiler.xml +* .idea\copyright\ +* .idea\copyright\profiles_settings.xml +* .idea\misc.xml +* .idea\modules.xml +* .idea\vcs.xml +* .idea\workspace.xml +* LICENSE +* README.md +* proguard-project.txt + +Replaced Jars with Dependencies: +-------------------------------- +The importer recognized the following .jar files as third party +libraries and replaced them with Gradle dependencies instead. This has +the advantage that more explicit version information is known, and the +libraries can be updated automatically. However, it is possible that +the .jar file in your project was of an older version than the +dependency we picked, which could render the project not compileable. +You can disable the jar replacement in the import wizard and try again: + +android-support-v4.jar => com.android.support:support-v4:19.1.0 +android-support-v7-appcompat.jar => com.android.support:appcompat-v7:19.1.0 + +Moved Files: +------------ +Android Gradle projects use a different directory structure than ADT +Eclipse projects. Here's how the projects were restructured: + +* AndroidManifest.xml => app\src\main\AndroidManifest.xml +* res\ => app\src\main\res\ +* src\ => app\src\main\java\ + +Next Steps: +----------- +You can now build the project. The Gradle project needs network +connectivity to download dependencies. + +Bugs: +----- +If for some reason your project does not build, and you determine that +it is due to a bug or limitation of the Eclipse to Gradle importer, +please file a bug at http://b.android.com with category +Component-Tools. + +(This import summary is for your information only, and can be deleted +after import once you are satisfied with the results.) diff --git a/src/java/InputStickAPI/settings.gradle b/src/java/InputStickAPI/settings.gradle new file mode 100644 index 00000000..e7b4def4 --- /dev/null +++ b/src/java/InputStickAPI/settings.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/src/java/KP2ASoftKeyboard/.classpath b/src/java/KP2ASoftKeyboard/.classpath deleted file mode 100644 index 51769745..00000000 --- a/src/java/KP2ASoftKeyboard/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard/.project b/src/java/KP2ASoftKeyboard/.project deleted file mode 100644 index 7f9482b1..00000000 --- a/src/java/KP2ASoftKeyboard/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - KP2ASoftKeyboard - - - - - - 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/KP2ASoftKeyboard/.settings/org.eclipse.core.resources.prefs b/src/java/KP2ASoftKeyboard/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 754811a1..00000000 --- a/src/java/KP2ASoftKeyboard/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/keepass2android/softkeyboard/KP2AKeyboard.java=UTF-8 diff --git a/src/java/KP2ASoftKeyboard/AndroidManifest.xml b/src/java/KP2ASoftKeyboard/AndroidManifest.xml deleted file mode 100644 index 71182870..00000000 --- a/src/java/KP2ASoftKeyboard/AndroidManifest.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard/lint.xml b/src/java/KP2ASoftKeyboard/lint.xml deleted file mode 100644 index bbe34965..00000000 --- a/src/java/KP2ASoftKeyboard/lint.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/java/KP2ASoftKeyboard/project.properties b/src/java/KP2ASoftKeyboard/project.properties deleted file mode 100644 index 484dab07..00000000 --- a/src/java/KP2ASoftKeyboard/project.properties +++ /dev/null @@ -1,15 +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-17 -android.library=true diff --git a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard.png b/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard.png deleted file mode 100644 index b57ae665..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_delete.png b/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_delete.png deleted file mode 100644 index 5139c717..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_delete.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_done.png b/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_done.png deleted file mode 100644 index 471c5021..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_done.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_kp2a.png b/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_kp2a.png deleted file mode 100644 index 0947c238..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_kp2a.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_return.png b/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_return.png deleted file mode 100644 index 5a5670c3..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_return.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_search.png b/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_search.png deleted file mode 100644 index e72cde3b..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_search.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_shift.png b/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_shift.png deleted file mode 100644 index 27576961..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_shift.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_space.png b/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_space.png deleted file mode 100644 index cef2daa5..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-hdpi/sym_keyboard_space.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard.png b/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard.png deleted file mode 100644 index 33d68ccc..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_delete.png b/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_delete.png deleted file mode 100644 index 6cee5968..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_delete.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_done.png b/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_done.png deleted file mode 100644 index c0d6d139..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_done.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_kp2a.png b/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_kp2a.png deleted file mode 100644 index 707b62d9..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_kp2a.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_return.png b/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_return.png deleted file mode 100644 index cbe2b152..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_return.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_search.png b/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_search.png deleted file mode 100644 index 127755d6..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_search.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_shift.png b/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_shift.png deleted file mode 100644 index d0596284..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_shift.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_space.png b/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_space.png deleted file mode 100644 index 09b94d9e..00000000 Binary files a/src/java/KP2ASoftKeyboard/res/drawable-mdpi/sym_keyboard_space.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard/res/layout/input.xml b/src/java/KP2ASoftKeyboard/res/layout/input.xml deleted file mode 100644 index d16b2b2e..00000000 --- a/src/java/KP2ASoftKeyboard/res/layout/input.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-ar/strings.xml b/src/java/KP2ASoftKeyboard/res/values-ar/strings.xml deleted file mode 100644 index de3dba77..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-ar/strings.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - اختر مُدخل آخر - اختر مُدخل - البحث عن مُدخل يحتوي على \"%1$s\" - بحث - التالي - إرسال - diff --git a/src/java/KP2ASoftKeyboard/res/values-bg-rBG/strings.xml b/src/java/KP2ASoftKeyboard/res/values-bg-rBG/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-bg-rBG/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-ca/strings.xml b/src/java/KP2ASoftKeyboard/res/values-ca/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-ca/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-cs/strings.xml b/src/java/KP2ASoftKeyboard/res/values-cs/strings.xml deleted file mode 100644 index 4f5ebe00..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-cs/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Vyberte další položku - Vybrat položku - Hledat položky s \"%1$s\" - Jít - Další - Odeslat - diff --git a/src/java/KP2ASoftKeyboard/res/values-da/strings.xml b/src/java/KP2ASoftKeyboard/res/values-da/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-da/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-de/strings.xml b/src/java/KP2ASoftKeyboard/res/values-de/strings.xml deleted file mode 100644 index ad5fc831..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-de/strings.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - Keepass2Android - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Anderen Eintrag wählen - Eintrag wählen - Suche Eintrag mit \"%1$s\" - Los - Weiter - Senden - %s - diff --git a/src/java/KP2ASoftKeyboard/res/values-el/strings.xml b/src/java/KP2ASoftKeyboard/res/values-el/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-el/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-es/strings.xml b/src/java/KP2ASoftKeyboard/res/values-es/strings.xml deleted file mode 100644 index 6158762b..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-es/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - ¿\u0020.,:?[de \n()] * & @ {} / < > _ += | \" - Seleccione otra entrada - Seleccione una entrada - Buscar entrada con \"%1$s\" - Ir - Siguiente - Enviar - diff --git a/src/java/KP2ASoftKeyboard/res/values-fi/strings.xml b/src/java/KP2ASoftKeyboard/res/values-fi/strings.xml deleted file mode 100644 index f096a18d..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-fi/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Valitse toinen merkintä - Valitse merkintä - Etsi merkintä \"%1$s\" - Mene - Seuraava - Lähetä - diff --git a/src/java/KP2ASoftKeyboard/res/values-fr/strings.xml b/src/java/KP2ASoftKeyboard/res/values-fr/strings.xml deleted file mode 100644 index 8c42dbc6..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-fr/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Choisir une autre entrée - Choisir une entrée - Rechercher une entrée avec \"%1$s\" - Go - Suivant - Envoyer - diff --git a/src/java/KP2ASoftKeyboard/res/values-hu/strings.xml b/src/java/KP2ASoftKeyboard/res/values-hu/strings.xml deleted file mode 100644 index e727856d..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-hu/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Válasszon egy másik bejegyzést - Válasszon bejegyzést - Bejegyzés keresése: \"%1$s\" - Go - Következő - Küldés - diff --git a/src/java/KP2ASoftKeyboard/res/values-in/strings.xml b/src/java/KP2ASoftKeyboard/res/values-in/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-in/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-it/strings.xml b/src/java/KP2ASoftKeyboard/res/values-it/strings.xml deleted file mode 100644 index a82de10e..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-it/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Seleziona un\'altra voce - Seleziona una voce - Cerca la voce \"%1$s\" - Vai - Avanti - Invia - diff --git a/src/java/KP2ASoftKeyboard/res/values-iw/strings.xml b/src/java/KP2ASoftKeyboard/res/values-iw/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-iw/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-ja/strings.xml b/src/java/KP2ASoftKeyboard/res/values-ja/strings.xml deleted file mode 100644 index c95d6f53..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-ja/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - 別のエントリを選択 - エントリの選択 - エントリを\"%1$s\"で検索します。 - Go - - 送信 - diff --git a/src/java/KP2ASoftKeyboard/res/values-ko/strings.xml b/src/java/KP2ASoftKeyboard/res/values-ko/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-ko/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-land/dimens.xml b/src/java/KP2ASoftKeyboard/res/values-land/dimens.xml deleted file mode 100644 index b5f3bc12..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-land/dimens.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - 46dip - diff --git a/src/java/KP2ASoftKeyboard/res/values-nb/strings.xml b/src/java/KP2ASoftKeyboard/res/values-nb/strings.xml deleted file mode 100644 index 7fb47938..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-nb/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Velg en annen oppføring - Velg oppføring - Søke etter oppføringen med \"%1$s\" - Kjør - Neste - Send - diff --git a/src/java/KP2ASoftKeyboard/res/values-nl/strings.xml b/src/java/KP2ASoftKeyboard/res/values-nl/strings.xml deleted file mode 100644 index 9da5541f..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-nl/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Kies een andere regel - Kies regel - Zoek voor regel met \"%1$s\" - Ga - Volgende - Zend - diff --git a/src/java/KP2ASoftKeyboard/res/values-nn/strings.xml b/src/java/KP2ASoftKeyboard/res/values-nn/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-nn/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-pl/strings.xml b/src/java/KP2ASoftKeyboard/res/values-pl/strings.xml deleted file mode 100644 index efee50cb..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-pl/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Wybierz inną pozycję - Wybierz pozycję - Wyszukaj pozycję z \"%1$s\" - Idź - Dalej - Wyślij - diff --git a/src/java/KP2ASoftKeyboard/res/values-pt-rBR/strings.xml b/src/java/KP2ASoftKeyboard/res/values-pt-rBR/strings.xml deleted file mode 100644 index f4a970e9..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-pt-rBR/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Selecione outra entrada - Selecione uma entrada - Localizar entrada com \"%1$s\" - Ir - Próximo - Enviar - diff --git a/src/java/KP2ASoftKeyboard/res/values-pt-rPT/strings.xml b/src/java/KP2ASoftKeyboard/res/values-pt-rPT/strings.xml deleted file mode 100644 index 927f1817..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-pt-rPT/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Selecionar outra entrada - Selecionar a entrada - Procurar entrada com \"%1$s\" - Ir - Seguinte - Enviar - diff --git a/src/java/KP2ASoftKeyboard/res/values-ro/strings.xml b/src/java/KP2ASoftKeyboard/res/values-ro/strings.xml deleted file mode 100644 index a59025ca..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-ro/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Selectaţi o altă înregistrare - Alegeți înregistraea - Căutaţi înregistrarea \"%1$s\" - Go - Următoarea - Trimite - diff --git a/src/java/KP2ASoftKeyboard/res/values-ru/strings.xml b/src/java/KP2ASoftKeyboard/res/values-ru/strings.xml deleted file mode 100644 index 930d304a..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-ru/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Выбрать другую запись - Выбрать запись - Поиск записи с \"%1$s\" - Перейти - Вперёд - Отправить - diff --git a/src/java/KP2ASoftKeyboard/res/values-sk/strings.xml b/src/java/KP2ASoftKeyboard/res/values-sk/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-sk/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-sl/strings.xml b/src/java/KP2ASoftKeyboard/res/values-sl/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-sl/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-sr/strings.xml b/src/java/KP2ASoftKeyboard/res/values-sr/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-sr/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values-sv/strings.xml b/src/java/KP2ASoftKeyboard/res/values-sv/strings.xml deleted file mode 100644 index 814ea337..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-sv/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Välj en annan post - Välj post - Sök efter post med \"%1$s\" - - Nästa - Skicka - diff --git a/src/java/KP2ASoftKeyboard/res/values-tr/strings.xml b/src/java/KP2ASoftKeyboard/res/values-tr/strings.xml deleted file mode 100644 index 32b14f7d..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-tr/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Başka bir kayıt seçin - Kayıt seçin - Kayıt \"%1$s\" ile arama - Başla - Sonraki - Gönder - diff --git a/src/java/KP2ASoftKeyboard/res/values-uk/strings.xml b/src/java/KP2ASoftKeyboard/res/values-uk/strings.xml deleted file mode 100644 index 2d9ade75..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-uk/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,:!?[\n()] * & @ {} / <> _ + = | \" - Вибрати інший запис - Вибрати запис - Пошук запису з \'%1$s\' - Перейти - Наступний - Відправити - diff --git a/src/java/KP2ASoftKeyboard/res/values-vi/strings.xml b/src/java/KP2ASoftKeyboard/res/values-vi/strings.xml deleted file mode 100644 index ee9ef2d3..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-vi/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - Chọn mục khác - Chọn mục - Tìm kiếm các mục nhập với \"%1$s\" - Đi - Tiếp theo - Gởi - diff --git a/src/java/KP2ASoftKeyboard/res/values-zh-rCN/strings.xml b/src/java/KP2ASoftKeyboard/res/values-zh-rCN/strings.xml deleted file mode 100644 index 226a7c3b..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-zh-rCN/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|\" - 选择另一条目 - 选择条目 - 搜索带有\"%1$s\" 的条目 - 转到 - 下一步 - 发送 - diff --git a/src/java/KP2ASoftKeyboard/res/values-zh-rTW/strings.xml b/src/java/KP2ASoftKeyboard/res/values-zh-rTW/strings.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard/res/values-zh-rTW/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard/res/values/colors.xml b/src/java/KP2ASoftKeyboard/res/values/colors.xml deleted file mode 100644 index 74d103af..00000000 --- a/src/java/KP2ASoftKeyboard/res/values/colors.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - #FF000000 - #FFE35900 - #ff808080 - #bbffffff - \ No newline at end of file diff --git a/src/java/KP2ASoftKeyboard/res/values/dimens.xml b/src/java/KP2ASoftKeyboard/res/values/dimens.xml deleted file mode 100644 index caf615cf..00000000 --- a/src/java/KP2ASoftKeyboard/res/values/dimens.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - 50dip - 16sp - 6sp - \ No newline at end of file diff --git a/src/java/KP2ASoftKeyboard/res/values/strings.xml b/src/java/KP2ASoftKeyboard/res/values/strings.xml deleted file mode 100644 index 3c6260c8..00000000 --- a/src/java/KP2ASoftKeyboard/res/values/strings.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Keepass2Android - - - \u0020.,;:!?\n()[]*&@{}/<>_+=|" - - Select another entry - Select entry - Search for entry with "%1$s" - - - Go - Next - Send - - - %s - diff --git a/src/java/KP2ASoftKeyboard/res/xml/method.xml b/src/java/KP2ASoftKeyboard/res/xml/method.xml deleted file mode 100644 index 95d61e41..00000000 --- a/src/java/KP2ASoftKeyboard/res/xml/method.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard/res/xml/qwerty.xml b/src/java/KP2ASoftKeyboard/res/xml/qwerty.xml deleted file mode 100644 index 839b5dbe..00000000 --- a/src/java/KP2ASoftKeyboard/res/xml/qwerty.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/java/KP2ASoftKeyboard/res/xml/symbols.xml b/src/java/KP2ASoftKeyboard/res/xml/symbols.xml deleted file mode 100644 index a28d752b..00000000 --- a/src/java/KP2ASoftKeyboard/res/xml/symbols.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/java/KP2ASoftKeyboard/res/xml/symbols_shift.xml b/src/java/KP2ASoftKeyboard/res/xml/symbols_shift.xml deleted file mode 100644 index d7139f34..00000000 --- a/src/java/KP2ASoftKeyboard/res/xml/symbols_shift.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsFragment.java b/src/java/KP2ASoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsFragment.java deleted file mode 100644 index b3b7c8c0..00000000 --- a/src/java/KP2ASoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsFragment.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/** - * This is a part of the inputmethod-common static Java library. - * The original source code can be found at frameworks/opt/inputmethodcommon of Android Open Source - * Project. - */ - -package com.android.inputmethodcommon; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.preference.PreferenceFragment; - -/** - * This is a helper class for an IME's settings preference fragment. It's recommended for every - * IME to have its own settings preference fragment which inherits this class. - */ -public abstract class InputMethodSettingsFragment extends PreferenceFragment - implements InputMethodSettingsInterface { - private final InputMethodSettingsImpl mSettings = new InputMethodSettingsImpl(); - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - final Context context = getActivity(); - setPreferenceScreen(getPreferenceManager().createPreferenceScreen(context)); - mSettings.init(context, getPreferenceScreen()); - } - - /** - * {@inheritDoc} - */ - @Override - public void setInputMethodSettingsCategoryTitle(int resId) { - mSettings.setInputMethodSettingsCategoryTitle(resId); - } - - /** - * {@inheritDoc} - */ - @Override - public void setInputMethodSettingsCategoryTitle(CharSequence title) { - mSettings.setInputMethodSettingsCategoryTitle(title); - } - - /** - * {@inheritDoc} - */ - @Override - public void setSubtypeEnablerTitle(int resId) { - mSettings.setSubtypeEnablerTitle(resId); - } - - /** - * {@inheritDoc} - */ - @Override - public void setSubtypeEnablerTitle(CharSequence title) { - mSettings.setSubtypeEnablerTitle(title); - } - - /** - * {@inheritDoc} - */ - @Override - public void setSubtypeEnablerIcon(int resId) { - mSettings.setSubtypeEnablerIcon(resId); - } - - /** - * {@inheritDoc} - */ - @Override - public void setSubtypeEnablerIcon(Drawable drawable) { - mSettings.setSubtypeEnablerIcon(drawable); - } - - /** - * {@inheritDoc} - */ - @Override - public void onResume() { - super.onResume(); - mSettings.updateSubtypeEnabler(); - } -} diff --git a/src/java/KP2ASoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsImpl.java b/src/java/KP2ASoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsImpl.java deleted file mode 100644 index 722148d8..00000000 --- a/src/java/KP2ASoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsImpl.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/** - * This is a part of the inputmethod-common static Java library. - * The original source code can be found at frameworks/opt/inputmethodcommon of Android Open Source - * Project. - */ - -package com.android.inputmethodcommon; - -import android.content.Context; -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceClickListener; -import android.preference.PreferenceScreen; -import android.provider.Settings; -import android.text.TextUtils; -import android.view.inputmethod.InputMethodInfo; -import android.view.inputmethod.InputMethodManager; -import android.view.inputmethod.InputMethodSubtype; - -import java.util.List; - -/* package private */ class InputMethodSettingsImpl implements InputMethodSettingsInterface { - private Preference mSubtypeEnablerPreference; - private int mInputMethodSettingsCategoryTitleRes; - private CharSequence mInputMethodSettingsCategoryTitle; - private int mSubtypeEnablerTitleRes; - private CharSequence mSubtypeEnablerTitle; - private int mSubtypeEnablerIconRes; - private Drawable mSubtypeEnablerIcon; - private InputMethodManager mImm; - private InputMethodInfo mImi; - private Context mContext; - - /** - * Initialize internal states of this object. - * @param context the context for this application. - * @param prefScreen a PreferenceScreen of PreferenceActivity or PreferenceFragment. - * @return true if this application is an IME and has two or more subtypes, false otherwise. - */ - public boolean init(final Context context, final PreferenceScreen prefScreen) { - mContext = context; - mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); - mImi = getMyImi(context, mImm); - if (mImi == null || mImi.getSubtypeCount() <= 1) { - return false; - } - mSubtypeEnablerPreference = new Preference(context); - mSubtypeEnablerPreference - .setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - final CharSequence title = getSubtypeEnablerTitle(context); - final Intent intent = - new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS); - intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, mImi.getId()); - if (!TextUtils.isEmpty(title)) { - intent.putExtra(Intent.EXTRA_TITLE, title); - } - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED - | Intent.FLAG_ACTIVITY_CLEAR_TOP); - context.startActivity(intent); - return true; - } - }); - prefScreen.addPreference(mSubtypeEnablerPreference); - updateSubtypeEnabler(); - return true; - } - - private static InputMethodInfo getMyImi(Context context, InputMethodManager imm) { - final List imis = imm.getInputMethodList(); - for (int i = 0; i < imis.size(); ++i) { - final InputMethodInfo imi = imis.get(i); - if (imis.get(i).getPackageName().equals(context.getPackageName())) { - return imi; - } - } - return null; - } - - private static String getEnabledSubtypesLabel( - Context context, InputMethodManager imm, InputMethodInfo imi) { - if (context == null || imm == null || imi == null) return null; - final List subtypes = imm.getEnabledInputMethodSubtypeList(imi, true); - final StringBuilder sb = new StringBuilder(); - final int N = subtypes.size(); - for (int i = 0; i < N; ++i) { - final InputMethodSubtype subtype = subtypes.get(i); - if (sb.length() > 0) { - sb.append(", "); - } - sb.append(subtype.getDisplayName(context, imi.getPackageName(), - imi.getServiceInfo().applicationInfo)); - } - return sb.toString(); - } - /** - * {@inheritDoc} - */ - @Override - public void setInputMethodSettingsCategoryTitle(int resId) { - mInputMethodSettingsCategoryTitleRes = resId; - updateSubtypeEnabler(); - } - - /** - * {@inheritDoc} - */ - @Override - public void setInputMethodSettingsCategoryTitle(CharSequence title) { - mInputMethodSettingsCategoryTitleRes = 0; - mInputMethodSettingsCategoryTitle = title; - updateSubtypeEnabler(); - } - - /** - * {@inheritDoc} - */ - @Override - public void setSubtypeEnablerTitle(int resId) { - mSubtypeEnablerTitleRes = resId; - updateSubtypeEnabler(); - } - - /** - * {@inheritDoc} - */ - @Override - public void setSubtypeEnablerTitle(CharSequence title) { - mSubtypeEnablerTitleRes = 0; - mSubtypeEnablerTitle = title; - updateSubtypeEnabler(); - } - - /** - * {@inheritDoc} - */ - @Override - public void setSubtypeEnablerIcon(int resId) { - mSubtypeEnablerIconRes = resId; - updateSubtypeEnabler(); - } - - /** - * {@inheritDoc} - */ - @Override - public void setSubtypeEnablerIcon(Drawable drawable) { - mSubtypeEnablerIconRes = 0; - mSubtypeEnablerIcon = drawable; - updateSubtypeEnabler(); - } - - private CharSequence getSubtypeEnablerTitle(Context context) { - if (mSubtypeEnablerTitleRes != 0) { - return context.getString(mSubtypeEnablerTitleRes); - } else { - return mSubtypeEnablerTitle; - } - } - - public void updateSubtypeEnabler() { - if (mSubtypeEnablerPreference != null) { - if (mSubtypeEnablerTitleRes != 0) { - mSubtypeEnablerPreference.setTitle(mSubtypeEnablerTitleRes); - } else if (!TextUtils.isEmpty(mSubtypeEnablerTitle)) { - mSubtypeEnablerPreference.setTitle(mSubtypeEnablerTitle); - } - final String summary = getEnabledSubtypesLabel(mContext, mImm, mImi); - if (!TextUtils.isEmpty(summary)) { - mSubtypeEnablerPreference.setSummary(summary); - } - if (mSubtypeEnablerIconRes != 0) { - mSubtypeEnablerPreference.setIcon(mSubtypeEnablerIconRes); - } else if (mSubtypeEnablerIcon != null) { - mSubtypeEnablerPreference.setIcon(mSubtypeEnablerIcon); - } - } - } -} diff --git a/src/java/KP2ASoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsInterface.java b/src/java/KP2ASoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsInterface.java deleted file mode 100644 index f41e224d..00000000 --- a/src/java/KP2ASoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsInterface.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2011 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 - */ - -/** - * This is a part of the inputmethod-common static Java library. - * The original source code can be found at frameworks/opt/inputmethodcommon of Android Open Source - * Project. - */ - -package com.android.inputmethodcommon; - -import android.graphics.drawable.Drawable; - -/** - * InputMethodSettingsInterface is the interface for adding IME related preferences to - * PreferenceActivity or PreferenceFragment. - */ -public interface InputMethodSettingsInterface { - /** - * Sets the title for the input method settings category with a resource ID. - * @param resId The resource ID of the title. - */ - public void setInputMethodSettingsCategoryTitle(int resId); - - /** - * Sets the title for the input method settings category with a CharSequence. - * @param title The title for this preference. - */ - public void setInputMethodSettingsCategoryTitle(CharSequence title); - - /** - * Sets the title for the input method enabler preference for launching subtype enabler with a - * resource ID. - * @param resId The resource ID of the title. - */ - public void setSubtypeEnablerTitle(int resId); - - /** - * Sets the title for the input method enabler preference for launching subtype enabler with a - * CharSequence. - * @param title The title for this preference. - */ - public void setSubtypeEnablerTitle(CharSequence title); - - /** - * Sets the icon for the preference for launching subtype enabler with a resource ID. - * @param resId The resource id of an optional icon for the preference. - */ - public void setSubtypeEnablerIcon(int resId); - - /** - * Sets the icon for the Preference for launching subtype enabler with a Drawable. - * @param drawable The drawable of an optional icon for the preference. - */ - public void setSubtypeEnablerIcon(Drawable drawable); -} diff --git a/src/java/KP2ASoftKeyboard/src/keepass2android/kbbridge/KeyboardData.java b/src/java/KP2ASoftKeyboard/src/keepass2android/kbbridge/KeyboardData.java deleted file mode 100644 index 57c2b10e..00000000 --- a/src/java/KP2ASoftKeyboard/src/keepass2android/kbbridge/KeyboardData.java +++ /dev/null @@ -1,17 +0,0 @@ - -package keepass2android.kbbridge; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -public class KeyboardData -{ - public static List availableFields = new ArrayList(); - public static String entryName; - public static String entryId; - - public static void clear() - { - availableFields.clear(); - entryName = entryId = ""; - } -} diff --git a/src/java/KP2ASoftKeyboard/src/keepass2android/kbbridge/KeyboardDataBuilder.java b/src/java/KP2ASoftKeyboard/src/keepass2android/kbbridge/KeyboardDataBuilder.java deleted file mode 100644 index 32afc347..00000000 --- a/src/java/KP2ASoftKeyboard/src/keepass2android/kbbridge/KeyboardDataBuilder.java +++ /dev/null @@ -1,19 +0,0 @@ -package keepass2android.kbbridge; -import java.util.ArrayList; -import java.util.HashMap; -public class KeyboardDataBuilder { - private ArrayList availableFields = new ArrayList(); - - public void addPair(String displayName, String valueToType) - { - StringForTyping pair = new StringForTyping(); - pair.displayName = displayName; - pair.value = valueToType; - availableFields.add(pair); - } - - public void commit() - { - KeyboardData.availableFields = this.availableFields; - } -} diff --git a/src/java/KP2ASoftKeyboard/src/keepass2android/kbbridge/StringForTyping.java b/src/java/KP2ASoftKeyboard/src/keepass2android/kbbridge/StringForTyping.java deleted file mode 100644 index 9348dad2..00000000 --- a/src/java/KP2ASoftKeyboard/src/keepass2android/kbbridge/StringForTyping.java +++ /dev/null @@ -1,20 +0,0 @@ -package keepass2android.kbbridge; - -public class StringForTyping { - public String key; //internal identifier (PwEntry string field key) - public String displayName; //display name for displaying the key (might be translated) - public String value; - - @Override - public StringForTyping clone(){ - - StringForTyping theClone = new StringForTyping(); - theClone.key = key; - theClone.displayName = displayName; - theClone.value = value; - - return theClone; - } - - -} diff --git a/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/CandidateView.java b/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/CandidateView.java deleted file mode 100644 index ab6a53ba..00000000 --- a/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/CandidateView.java +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (C) 2008-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. - */ - -package keepass2android.softkeyboard; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.View; - -import java.util.ArrayList; -import java.util.List; - -import keepass2android.softkeyboard.R; - -public class CandidateView extends View { - - private static final int OUT_OF_BOUNDS = -1; - - private KP2AKeyboard mService; - private List mSuggestions; - private int mSelectedIndex; - private int mTouchX = OUT_OF_BOUNDS; - private Drawable mSelectionHighlight; - private boolean mTypedWordValid; - - private Rect mBgPadding; - - private static final int MAX_SUGGESTIONS = 32; - private static final int SCROLL_PIXELS = 20; - - private int[] mWordWidth = new int[MAX_SUGGESTIONS]; - private int[] mWordX = new int[MAX_SUGGESTIONS]; - - private static final int X_GAP = 10; - - private static final List EMPTY_LIST = new ArrayList(); - - private int mColorNormal; - private int mColorRecommended; - private int mColorOther; - private int mVerticalPadding; - private Paint mPaint; - private boolean mScrolled; - private int mTargetScrollX; - - private int mTotalWidth; - - private GestureDetector mGestureDetector; - - /** - * Construct a CandidateView for showing suggested words for completion. - * @param context - * @param attrs - */ - public CandidateView(Context context) { - super(context); - mSelectionHighlight = context.getResources().getDrawable( - android.R.drawable.list_selector_background); - mSelectionHighlight.setState(new int[] { - android.R.attr.state_enabled, - android.R.attr.state_focused, - android.R.attr.state_window_focused, - android.R.attr.state_pressed - }); - - Resources r = context.getResources(); - - setBackgroundColor(r.getColor(R.color.candidate_background)); - - mColorNormal = r.getColor(R.color.candidate_normal); - mColorRecommended = r.getColor(R.color.candidate_recommended); - mColorOther = r.getColor(R.color.candidate_other); - mVerticalPadding = r.getDimensionPixelSize(R.dimen.candidate_vertical_padding); - - mPaint = new Paint(); - mPaint.setColor(mColorNormal); - mPaint.setAntiAlias(true); - mPaint.setTextSize(r.getDimensionPixelSize(R.dimen.candidate_font_height)); - mPaint.setStrokeWidth(0); - - mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() { - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, - float distanceX, float distanceY) { - mScrolled = true; - int sx = getScrollX(); - sx += distanceX; - if (sx < 0) { - sx = 0; - } - if (sx + getWidth() > mTotalWidth) { - sx -= distanceX; - } - mTargetScrollX = sx; - scrollTo(sx, getScrollY()); - invalidate(); - return true; - } - }); - setHorizontalFadingEdgeEnabled(true); - setWillNotDraw(false); - setHorizontalScrollBarEnabled(false); - setVerticalScrollBarEnabled(false); - } - - /** - * A connection back to the service to communicate with the text field - * @param listener - */ - public void setService(KP2AKeyboard listener) { - mService = listener; - } - - @Override - public int computeHorizontalScrollRange() { - return mTotalWidth; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int measuredWidth = resolveSize(50, widthMeasureSpec); - - // Get the desired height of the icon menu view (last row of items does - // not have a divider below) - Rect padding = new Rect(); - mSelectionHighlight.getPadding(padding); - final int desiredHeight = ((int)mPaint.getTextSize()) + mVerticalPadding - + padding.top + padding.bottom; - - // Maximum possible width and desired height - setMeasuredDimension(measuredWidth, - resolveSize(desiredHeight, heightMeasureSpec)); - } - - /** - * If the canvas is null, then only touch calculations are performed to pick the target - * candidate. - */ - @Override - protected void onDraw(Canvas canvas) { - if (canvas != null) { - super.onDraw(canvas); - } - mTotalWidth = 0; - if (mSuggestions == null) return; - - if (mBgPadding == null) { - mBgPadding = new Rect(0, 0, 0, 0); - if (getBackground() != null) { - getBackground().getPadding(mBgPadding); - } - } - int x = 0; - final int count = mSuggestions.size(); - final int height = getHeight(); - final Rect bgPadding = mBgPadding; - final Paint paint = mPaint; - final int touchX = mTouchX; - final int scrollX = getScrollX(); - final boolean scrolled = mScrolled; - final boolean typedWordValid = mTypedWordValid; - final int y = (int) (((height - mPaint.getTextSize()) / 2) - mPaint.ascent()); - - for (int i = 0; i < count; i++) { - String suggestion = mSuggestions.get(i); - float textWidth = paint.measureText(suggestion); - final int wordWidth = (int) textWidth + X_GAP * 2; - - mWordX[i] = x; - mWordWidth[i] = wordWidth; - paint.setColor(mColorNormal); - if (touchX + scrollX >= x && touchX + scrollX < x + wordWidth && !scrolled) { - if (canvas != null) { - canvas.translate(x, 0); - mSelectionHighlight.setBounds(0, bgPadding.top, wordWidth, height); - mSelectionHighlight.draw(canvas); - canvas.translate(-x, 0); - } - mSelectedIndex = i; - } - - if (canvas != null) { - if ((i == 1 && !typedWordValid) || (i == 0 && typedWordValid)) { - paint.setFakeBoldText(true); - paint.setColor(mColorRecommended); - } else if (i != 0) { - paint.setColor(mColorOther); - } - canvas.drawText(suggestion, x + X_GAP, y, paint); - paint.setColor(mColorOther); - canvas.drawLine(x + wordWidth + 0.5f, bgPadding.top, - x + wordWidth + 0.5f, height + 1, paint); - paint.setFakeBoldText(false); - } - x += wordWidth; - } - mTotalWidth = x; - if (mTargetScrollX != getScrollX()) { - scrollToTarget(); - } - } - - private void scrollToTarget() { - int sx = getScrollX(); - if (mTargetScrollX > sx) { - sx += SCROLL_PIXELS; - if (sx >= mTargetScrollX) { - sx = mTargetScrollX; - requestLayout(); - } - } else { - sx -= SCROLL_PIXELS; - if (sx <= mTargetScrollX) { - sx = mTargetScrollX; - requestLayout(); - } - } - scrollTo(sx, getScrollY()); - invalidate(); - } - - public void setSuggestions(List suggestions, boolean completions, - boolean typedWordValid) { - clear(); - if (suggestions != null) { - mSuggestions = new ArrayList(suggestions); - } - mTypedWordValid = typedWordValid; - scrollTo(0, 0); - mTargetScrollX = 0; - // Compute the total width - onDraw(null); - invalidate(); - requestLayout(); - } - - public void clear() { - mSuggestions = EMPTY_LIST; - mTouchX = OUT_OF_BOUNDS; - mSelectedIndex = -1; - invalidate(); - } - - @Override - public boolean onTouchEvent(MotionEvent me) { - - if (mGestureDetector.onTouchEvent(me)) { - return true; - } - - int action = me.getAction(); - int x = (int) me.getX(); - int y = (int) me.getY(); - mTouchX = x; - - switch (action) { - case MotionEvent.ACTION_DOWN: - mScrolled = false; - invalidate(); - break; - case MotionEvent.ACTION_MOVE: - if (y <= 0) { - // Fling up!? - if (mSelectedIndex >= 0) { - mService.pickSuggestionManually(mSelectedIndex); - mSelectedIndex = -1; - } - } - invalidate(); - break; - case MotionEvent.ACTION_UP: - if (!mScrolled) { - if (mSelectedIndex >= 0) { - mService.pickSuggestionManually(mSelectedIndex); - } - } - mSelectedIndex = -1; - removeHighlight(); - requestLayout(); - break; - } - return true; - } - - /** - * For flick through from keyboard, call this method with the x coordinate of the flick - * gesture. - * @param x - */ - public void takeSuggestionAt(float x) { - mTouchX = (int) x; - // To detect candidate - onDraw(null); - if (mSelectedIndex >= 0) { - mService.pickSuggestionManually(mSelectedIndex); - } - invalidate(); - } - - private void removeHighlight() { - mTouchX = OUT_OF_BOUNDS; - invalidate(); - } -} diff --git a/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/KP2AKeyboard.java b/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/KP2AKeyboard.java deleted file mode 100644 index 1f5ae22b..00000000 --- a/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/KP2AKeyboard.java +++ /dev/null @@ -1,835 +0,0 @@ -/* - * Copyright (C) 2008-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. - */ - -package keepass2android.softkeyboard; - -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.inputmethodservice.InputMethodService; -import android.inputmethodservice.Keyboard; -import android.inputmethodservice.KeyboardView; -import android.text.InputType; -import android.util.Log; -import android.util.Printer; -import android.view.KeyEvent; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.view.inputmethod.CompletionInfo; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.ExtractedText; -import android.view.inputmethod.ExtractedTextRequest; -import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; -import android.view.inputmethod.InputMethodSubtype; - -import java.util.ArrayList; -import java.util.List; - -import keepass2android.kbbridge.StringForTyping; -import keepass2android.softkeyboard.R; - -/** - * Example of writing an input method for a soft keyboard. This code is focused - * on simplicity over completeness, so it should in no way be considered to be a - * complete soft keyboard implementation. Its purpose is to provide a basic - * example for how you would get started writing an input method, to be fleshed - * out as appropriate. - */ -public class KP2AKeyboard extends InputMethodService implements - KeyboardView.OnKeyboardActionListener { - static final boolean DEBUG = false; - - private InputMethodManager mInputMethodManager; - - private LatinKeyboardView mInputView; - private CandidateView mCandidateView; - private CompletionInfo[] mCompletions; - - private StringBuilder mComposing = new StringBuilder(); - private boolean mPredictionOn; - private boolean mCompletionOn; - private int mLastDisplayWidth; - private boolean mCapsLock; - private long mLastShiftTime; - private long mMetaState; - - private LatinKeyboard mSymbolsKeyboard; - private LatinKeyboard mSymbolsShiftedKeyboard; - private LatinKeyboard mQwertyKeyboard; - - private LatinKeyboard mCurKeyboard; - - private String mWordSeparators; - - private String mClientPackageName; - - /** - * Main initialization of the input method component. Be sure to call to - * super class. - */ - @Override - public void onCreate() { - super.onCreate(); - mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); - mWordSeparators = getResources().getString(R.string.word_separators); - } - - /** - * This is the point where you can do all of your UI initialization. It is - * called after creation and any configuration change. - */ - @Override - public void onInitializeInterface() { - if (mQwertyKeyboard != null) { - // Configuration changes can happen after the keyboard gets - // recreated, - // so we need to be able to re-build the keyboards if the available - // space has changed. - int displayWidth = getMaxWidth(); - if (displayWidth == mLastDisplayWidth) - return; - mLastDisplayWidth = displayWidth; - } - mQwertyKeyboard = new LatinKeyboard(this, R.xml.qwerty); - mSymbolsKeyboard = new LatinKeyboard(this, R.xml.symbols); - mSymbolsShiftedKeyboard = new LatinKeyboard(this, R.xml.symbols_shift); - } - - /** - * Called by the framework when your view for creating input needs to be - * generated. This will be called the first time your input method is - * displayed, and every time it needs to be re-created such as due to a - * configuration change. - */ - @Override - public View onCreateInputView() { - mInputView = (LatinKeyboardView) getLayoutInflater().inflate( - R.layout.input, null); - mInputView.setOnKeyboardActionListener(this); - mInputView.setKeyboard(mQwertyKeyboard); - return mInputView; - } - - /** - * Called by the framework when your view for showing candidates needs to be - * generated, like {@link #onCreateInputView}. - */ - @Override - public View onCreateCandidatesView() { - mCandidateView = new CandidateView(this); - mCandidateView.setService(this); - return mCandidateView; - } - - /** - * This is the main point where we do our initialization of the input method - * to begin operating on an application. At this point we have been bound to - * the client, and are now receiving all of the detailed information about - * the target of our edits. - */ - @Override - public void onStartInput(EditorInfo attribute, boolean restarting) { - super.onStartInput(attribute, restarting); - - // Reset our state. We want to do this even if restarting, because - // the underlying state of the text editor could have changed in any - // way. - mComposing.setLength(0); - updateCandidates(); - - if (!restarting) { - // Clear shift states. - mMetaState = 0; - } - - mClientPackageName = attribute.packageName; - - mPredictionOn = false; - mCompletionOn = false; - mCompletions = null; - - // We are now going to initialize our state based on the type of - // text being edited. - switch (attribute.inputType & InputType.TYPE_MASK_CLASS) { - case InputType.TYPE_CLASS_NUMBER: - case InputType.TYPE_CLASS_DATETIME: - // Numbers and dates default to the symbols keyboard, with - // no extra features. - mCurKeyboard = mSymbolsKeyboard; - break; - - case InputType.TYPE_CLASS_PHONE: - // Phones will also default to the symbols keyboard, though - // often you will want to have a dedicated phone keyboard. - mCurKeyboard = mSymbolsKeyboard; - break; - - case InputType.TYPE_CLASS_TEXT: - // This is general text editing. We will default to the - // normal alphabetic keyboard, and assume that we should - // be doing predictive text (showing candidates as the - // user types). - mCurKeyboard = mQwertyKeyboard; - mPredictionOn = true; - - // We now look for a few special variations of text that will - // modify our behavior. - int variation = attribute.inputType & InputType.TYPE_MASK_VARIATION; - if (variation == InputType.TYPE_TEXT_VARIATION_PASSWORD - || variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) { - // Do not display predictions / what the user is typing - // when they are entering a password. - mPredictionOn = false; - } - - if (variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS - || variation == InputType.TYPE_TEXT_VARIATION_URI - || variation == InputType.TYPE_TEXT_VARIATION_FILTER) { - // Our predictions are not useful for e-mail addresses - // or URIs. - mPredictionOn = false; - } - - if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { - // If this is an auto-complete text view, then our predictions - // will not be shown and instead we will allow the editor - // to supply their own. We only show the editor's - // candidates when in fullscreen mode, otherwise relying - // own it displaying its own UI. - mPredictionOn = false; - mCompletionOn = isFullscreenMode(); - } - - // We also want to look at the current state of the editor - // to decide whether our alphabetic keyboard should start out - // shifted. - updateShiftKeyState(attribute); - break; - - default: - // For all unknown input types, default to the alphabetic - // keyboard with no special features. - mCurKeyboard = mQwertyKeyboard; - updateShiftKeyState(attribute); - } - - // Update the label on the enter key, depending on what the application - // says it will do. - mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions); - - tryAutoFillIn(attribute); - - } - - private boolean tryAutoFillIn(final EditorInfo attribute) { - //auto fill in? - //TODO: make this inside an AsyncTask: getText* might be slow - CharSequence textAfter = getCurrentInputConnection().getTextAfterCursor(1 /*length*/, 0 /*flags*/); - CharSequence textBefore = getCurrentInputConnection().getTextBeforeCursor(1 /*length*/, 0 /*flags*/); - boolean hasTextInField = ((textAfter != null) && (textAfter.length() > 0)) - || ((textBefore != null) && (textBefore.length()> 0)); - if (!hasTextInField) - { - //try to look up saved field ids: - if (attribute.fieldId > -1) - { - SharedPreferences prefs = getApplicationContext().getSharedPreferences("savedFieldIds", MODE_PRIVATE); - - String key = attribute.packageName+"/"+attribute.fieldId; - Log.d("KP2AK", "looking up saved field for "+key); - - String fieldKey = prefs.getString(key, ""); - - if ("".equals(fieldKey) == false) - { - Log.d("KP2AK","Found field "+fieldKey); - if (commitTextForKey(attribute, fieldKey)) - return true; - } - } - - //try to look up saved field hint: - if ((attribute.hintText != null) && (attribute.hintText.length() > 0)) - { - SharedPreferences prefs = getApplicationContext().getSharedPreferences("savedFieldHints", MODE_PRIVATE); - - String key = attribute.packageName+"/"+keepass2android.kbbridge.KeyboardData.entryId+"/"+attribute.hintText; - Log.d("KP2AK", "looking up saved field hint for "+key); - - String displayName = prefs.getString(key, ""); - - if ("".equals(displayName) == false) - { - Log.d("KP2AK","Found field "+displayName); - if (commitTextForKey(attribute, displayName)) - return true; - } - } - - //try to look up by hint - if ((attribute.hintText != null) && (attribute.hintText.length() > 0)) - { - if (commitTextForKey(attribute, attribute.hintText.toString())) - return true; - } - - } - return false; - } - - private boolean commitTextForKey(final EditorInfo attribute, String key) { - List availableFields = keepass2android.kbbridge.KeyboardData.availableFields; - for (StringForTyping str: availableFields) - { - if (str.key.equals(key)) - { - Log.d("KP2AK", "Typing!"); - commitKp2aString(str.value, attribute); - return true; - } - } - return false; - } - - private void commitKp2aString(String value, EditorInfo editorInfo) { - getCurrentInputConnection().commitText( - value, 0); - - if ((editorInfo.imeOptions&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) == EditorInfo.IME_ACTION_NEXT) - { - Log.d("KP2AK", "action is NEXT"); - getCurrentInputConnection().performEditorAction(editorInfo.actionId); - } - - - } - - /** - * This is called when the user is done editing a field. We can use this to - * reset our state. - */ - @Override - public void onFinishInput() { - super.onFinishInput(); - - // Clear current composing text and candidates. - mComposing.setLength(0); - updateCandidates(); - - // We only hide the candidates window when finishing input on - // a particular editor, to avoid popping the underlying application - // up and down if the user is entering text into the bottom of - // its window. - setCandidatesViewShown(false); - - mCurKeyboard = mQwertyKeyboard; - if (mInputView != null) { - mInputView.closing(); - } - } - - @Override - public void onStartInputView(EditorInfo attribute, boolean restarting) { - super.onStartInputView(attribute, restarting); - // Apply the selected keyboard to the input view. - mInputView.setKeyboard(mCurKeyboard); - mInputView.closing(); - // final InputMethodSubtype subtype = - // mInputMethodManager.getCurrentInputMethodSubtype(); - // mInputView.setSubtypeOnSpaceKey(subtype); - } - - @Override - public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) { - mInputView.setSubtypeOnSpaceKey(subtype); - } - - /** - * Deal with the editor reporting movement of its cursor. - */ - @Override - public void onUpdateSelection(int oldSelStart, int oldSelEnd, - int newSelStart, int newSelEnd, int candidatesStart, - int candidatesEnd) { - super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, - candidatesStart, candidatesEnd); - - // If the current selection in the text view changes, we should - // clear whatever candidate text we have. - if (mComposing.length() > 0 - && (newSelStart != candidatesEnd || newSelEnd != candidatesEnd)) { - mComposing.setLength(0); - updateCandidates(); - InputConnection ic = getCurrentInputConnection(); - - if (ic != null) { - ic.finishComposingText(); - } - } - } - - /** - * This tells us about completions that the editor has determined based on - * the current text in it. We want to use this in fullscreen mode to show - * the completions ourself, since the editor can not be seen in that - * situation. - */ - @Override - public void onDisplayCompletions(CompletionInfo[] completions) { - if (mCompletionOn) { - mCompletions = completions; - if (completions == null) { - setSuggestions(null, false, false); - return; - } - - List stringList = new ArrayList(); - for (int i = 0; i < completions.length; i++) { - CompletionInfo ci = completions[i]; - if (ci != null) - stringList.add(ci.getText().toString()); - } - setSuggestions(stringList, true, true); - } - } - - /** - * Use this to monitor key events being delivered to the application. We get - * first crack at them, and can either resume them or let them continue to - * the app. - */ - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_BACK: - // The InputMethodService already takes care of the back - // key for us, to dismiss the input method if it is shown. - // However, our keyboard could be showing a pop-up window - // that back should dismiss, so we first allow it to do that. - if (event.getRepeatCount() == 0 && mInputView != null) { - if (mInputView.handleBack()) { - return true; - } - } - break; - - case KeyEvent.KEYCODE_DEL: - // Special handling of the delete key: if we currently are - // composing text for the user, we want to modify that instead - // of let the application to the delete itself. - if (mComposing.length() > 0) { - onKey(Keyboard.KEYCODE_DELETE, null); - return true; - } - break; - - case KeyEvent.KEYCODE_ENTER: - // Let the underlying text editor always handle these. - return false; - - default: - - } - - return super.onKeyDown(keyCode, event); - } - - /** - * Helper function to commit any text being composed in to the editor. - */ - private void commitTyped(InputConnection inputConnection) { - if (mComposing.length() > 0) { - inputConnection.commitText(mComposing, mComposing.length()); - mComposing.setLength(0); - updateCandidates(); - } - } - - /** - * Helper to update the shift state of our keyboard based on the initial - * editor state. - */ - private void updateShiftKeyState(EditorInfo attr) { - if (attr != null && mInputView != null - && mQwertyKeyboard == mInputView.getKeyboard()) { - int caps = 0; - EditorInfo ei = getCurrentInputEditorInfo(); - if (ei != null && ei.inputType != InputType.TYPE_NULL) { - caps = getCurrentInputConnection().getCursorCapsMode( - attr.inputType); - } - mInputView.setShifted(mCapsLock || caps != 0); - } - } - - /** - * Helper to determine if a given character code is alphabetic. - */ - private boolean isAlphabet(int code) { - if (Character.isLetter(code)) { - return true; - } else { - return false; - } - } - - /** - * Helper to send a key down / key up pair to the current editor. - */ - private void keyDownUp(int keyEventCode) { - getCurrentInputConnection().sendKeyEvent( - new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode)); - getCurrentInputConnection().sendKeyEvent( - new KeyEvent(KeyEvent.ACTION_UP, keyEventCode)); - } - - /** - * Helper to send a character to the editor as raw key events. - */ - private void sendKey(int keyCode) { - switch (keyCode) { - case '\n': - keyDownUp(KeyEvent.KEYCODE_ENTER); - break; - default: - if (keyCode >= '0' && keyCode <= '9') { - keyDownUp(keyCode - '0' + KeyEvent.KEYCODE_0); - } else { - getCurrentInputConnection().commitText( - String.valueOf((char) keyCode), 1); - } - break; - } - } - - // Implementation of KeyboardViewListener - - public void onKey(int primaryCode, int[] keyCodes) { - if (isWordSeparator(primaryCode)) { - // Handle separator - if (mComposing.length() > 0) { - commitTyped(getCurrentInputConnection()); - } - sendKey(primaryCode); - updateShiftKeyState(getCurrentInputEditorInfo()); - } else if (primaryCode == Keyboard.KEYCODE_DELETE) { - android.util.Log.d("DEBUG", "DELETE"); - handleBackspace(); - } else if (primaryCode == Keyboard.KEYCODE_SHIFT) { - android.util.Log.d("DEBUG", "SHIFT"); - handleShift(); - } else if (primaryCode == Keyboard.KEYCODE_CANCEL) { - android.util.Log.d("DEBUG", "CANCEL"); - handleClose(); - return; - } else if (primaryCode == LatinKeyboardView.KEYCODE_KP2A) { - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - String title = "Keepass2Android"; - List availableFields = keepass2android.kbbridge.KeyboardData.availableFields; - - Log.d("KP2AK", "hint: "+getCurrentInputEditorInfo().hintText); - Log.d("KP2AK", "field name: "+getCurrentInputEditorInfo().fieldName); - Log.d("KP2AK", "label: "+getCurrentInputEditorInfo().label); - getCurrentInputEditorInfo().dump(new Printer() { - - @Override - public void println(String x) { - Log.d("KP2AK", x); - - } - },""); - final ArrayList items = new ArrayList(); - for (StringForTyping entry : availableFields) - { - items.add(entry.clone()); - } - - - if (keepass2android.kbbridge.KeyboardData.entryName == null) - { - StringForTyping openEntry = new StringForTyping(); - openEntry.displayName = openEntry.key = getString(R.string.open_entry); - openEntry.value = "KP2ASPECIAL_SelectEntryTask"; - items.add(openEntry); - } - else - { - StringForTyping changeEntry = new StringForTyping(); - changeEntry.displayName = changeEntry.key = getString(R.string.change_entry); - changeEntry.value = "KP2ASPECIAL_SelectEntryTask"; - items.add(changeEntry); - } - - if ((mClientPackageName != null) && (mClientPackageName != "")) - { - StringForTyping searchEntry = new StringForTyping(); - searchEntry.key = searchEntry.displayName - = getString(R.string.open_entry_for_app,mClientPackageName); - searchEntry.value = "KP2ASPECIAL_SearchUrlTask"; - items.add(searchEntry); - } - - builder.setTitle(title); - - builder.setItems(items.toArray(new CharSequence[items.size()]), - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int item) { - - if (items.get(item).value.startsWith("KP2ASPECIAL")) { - //change entry - Intent startKp2aIntent = getPackageManager().getLaunchIntentForPackage(getApplicationContext().getPackageName()); - if (startKp2aIntent != null) - { - startKp2aIntent.addCategory(Intent.CATEGORY_LAUNCHER); - startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - String value = items.get(item).value; - String taskName = value.substring("KP2ASPECIAL_".length()); - startKp2aIntent.putExtra("KP2A_APPTASK", taskName); - if (taskName.equals("SearchUrlTask")) - { - startKp2aIntent.putExtra("UrlToSearch", "androidapp://"+mClientPackageName); - } - startActivity(startKp2aIntent); - } - } else { - - - if (getCurrentInputEditorInfo().fieldId > 0) - { - SharedPreferences savedFieldIds = getApplicationContext().getSharedPreferences("savedFieldIds", MODE_PRIVATE); - Editor edit = savedFieldIds.edit(); - - edit.putString(getCurrentInputEditorInfo().packageName+"/"+getCurrentInputEditorInfo().fieldId, items.get(item).key); - edit.commit(); - } - - commitKp2aString(items.get(item).value, getCurrentInputEditorInfo()); - - } - } - }); - - builder.setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // User cancelled the dialog - } - }); - - // Create the AlertDialog - AlertDialog dialog = builder.create(); - Window window = dialog.getWindow(); - WindowManager.LayoutParams lp = window.getAttributes(); - lp.token = mInputView.getWindowToken(); - lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; - window.setAttributes(lp); - window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - - dialog.show(); - } else if (primaryCode == LatinKeyboardView.KEYCODE_SELECT_IME) { - mInputMethodManager.showInputMethodPicker(); - } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE - && mInputView != null) { - Keyboard current = mInputView.getKeyboard(); - if (current == mSymbolsKeyboard - || current == mSymbolsShiftedKeyboard) { - current = mQwertyKeyboard; - } else { - current = mSymbolsKeyboard; - } - mInputView.setKeyboard(current); - if (current == mSymbolsKeyboard) { - current.setShifted(false); - } - } else { - handleCharacter(primaryCode, keyCodes); - // mCapsLock = false; - // mInputView.setShifted(mCapsLock); - updateShiftKeyState(getCurrentInputEditorInfo()); - } - } - - public void onText(CharSequence text) { - InputConnection ic = getCurrentInputConnection(); - if (ic == null) - return; - ic.beginBatchEdit(); - if (mComposing.length() > 0) { - commitTyped(ic); - } - ic.commitText(text, 0); - ic.endBatchEdit(); - updateShiftKeyState(getCurrentInputEditorInfo()); - } - - /** - * Update the list of available candidates from the current composing text. - * This will need to be filled in by however you are determining candidates. - */ - private void updateCandidates() { - if (!mCompletionOn) { - if (mComposing.length() > 0) { - ArrayList list = new ArrayList(); - list.add(mComposing.toString()); - setSuggestions(list, true, true); - } else { - setSuggestions(null, false, false); - } - } - } - - public void setSuggestions(List suggestions, boolean completions, - boolean typedWordValid) { - if (suggestions != null && suggestions.size() > 0) { - setCandidatesViewShown(true); - } else if (isExtractViewShown()) { - setCandidatesViewShown(true); - } - if (mCandidateView != null) { - mCandidateView.setSuggestions(suggestions, completions, - typedWordValid); - } - } - - private void handleBackspace() { - final int length = mComposing.length(); - if (length > 1) { - mComposing.delete(length - 1, length); - getCurrentInputConnection().setComposingText(mComposing, 1); - updateCandidates(); - } else if (length > 0) { - mComposing.setLength(0); - getCurrentInputConnection().commitText("", 0); - updateCandidates(); - } else { - keyDownUp(KeyEvent.KEYCODE_DEL); - } - updateShiftKeyState(getCurrentInputEditorInfo()); - } - - private void handleShift() { - if (mInputView == null) { - return; - } - - Keyboard currentKeyboard = mInputView.getKeyboard(); - if (mQwertyKeyboard == currentKeyboard) { - // Alphabet keyboard - checkToggleCapsLock(); - mInputView.setShifted(mCapsLock || !mInputView.isShifted()); - - } else if (currentKeyboard == mSymbolsKeyboard) { - mSymbolsKeyboard.setShifted(true); - mInputView.setKeyboard(mSymbolsShiftedKeyboard); - mSymbolsShiftedKeyboard.setShifted(true); - } else if (currentKeyboard == mSymbolsShiftedKeyboard) { - mSymbolsShiftedKeyboard.setShifted(false); - mInputView.setKeyboard(mSymbolsKeyboard); - mSymbolsKeyboard.setShifted(false); - } - } - - private void handleCharacter(int primaryCode, int[] keyCodes) { - if (isInputViewShown()) { - if (mInputView.isShifted()) { - primaryCode = Character.toUpperCase(primaryCode); - } - } - if (isAlphabet(primaryCode) && mPredictionOn) { - mComposing.append((char) primaryCode); - getCurrentInputConnection().setComposingText(mComposing, 1); - updateShiftKeyState(getCurrentInputEditorInfo()); - updateCandidates(); - } else { - getCurrentInputConnection().commitText( - String.valueOf((char) primaryCode), 1); - } - } - - private void handleClose() { - commitTyped(getCurrentInputConnection()); - requestHideSelf(0); - mInputView.closing(); - } - - private void checkToggleCapsLock() { - long now = System.currentTimeMillis(); - if (mLastShiftTime + 800 > now) { - mCapsLock = !mCapsLock; - mLastShiftTime = 0; - } else { - mLastShiftTime = now; - } - } - - private String getWordSeparators() { - return mWordSeparators; - } - - public boolean isWordSeparator(int code) { - String separators = getWordSeparators(); - return separators.contains(String.valueOf((char) code)); - } - - public void pickDefaultCandidate() { - pickSuggestionManually(0); - } - - public void pickSuggestionManually(int index) { - if (mCompletionOn && mCompletions != null && index >= 0 - && index < mCompletions.length) { - CompletionInfo ci = mCompletions[index]; - getCurrentInputConnection().commitCompletion(ci); - if (mCandidateView != null) { - mCandidateView.clear(); - } - updateShiftKeyState(getCurrentInputEditorInfo()); - } else if (mComposing.length() > 0) { - // If we were generating candidate suggestions for the current - // text, we would commit one of them here. But for this sample, - // we will just commit the current text. - commitTyped(getCurrentInputConnection()); - } - } - - public void swipeRight() { - if (mCompletionOn) { - pickDefaultCandidate(); - } - } - - public void swipeLeft() { - handleBackspace(); - } - - public void swipeDown() { - handleClose(); - } - - public void swipeUp() { - } - - public void onPress(int primaryCode) { - } - - public void onRelease(int primaryCode) { - } -} diff --git a/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/LatinKeyboard.java b/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/LatinKeyboard.java deleted file mode 100644 index 9a2f58a0..00000000 --- a/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/LatinKeyboard.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2008-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. - */ - -package keepass2android.softkeyboard; - -import keepass2android.softkeyboard.R; - -import android.content.Context; -import android.content.res.Resources; -import android.content.res.XmlResourceParser; -import android.graphics.drawable.Drawable; -import android.inputmethodservice.Keyboard; -import android.view.inputmethod.EditorInfo; - -public class LatinKeyboard extends Keyboard { - - private Key mEnterKey; - private Key mSpaceKey; - - public LatinKeyboard(Context context, int xmlLayoutResId) { - super(context, xmlLayoutResId); - } - - public LatinKeyboard(Context context, int layoutTemplateResId, - CharSequence characters, int columns, int horizontalPadding) { - super(context, layoutTemplateResId, characters, columns, horizontalPadding); - } - - @Override - protected Key createKeyFromXml(Resources res, Row parent, int x, int y, - XmlResourceParser parser) { - Key key = new LatinKey(res, parent, x, y, parser); - if (key.codes[0] == 10) { - mEnterKey = key; - } else if (key.codes[0] == ' ') { - mSpaceKey = key; - } - return key; - } - - /** - * This looks at the ime options given by the current editor, to set the - * appropriate label on the keyboard's enter key (if it has one). - */ - void setImeOptions(Resources res, int options) { - if (mEnterKey == null) { - return; - } - - switch (options&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) { - case EditorInfo.IME_ACTION_GO: - mEnterKey.iconPreview = null; - mEnterKey.icon = null; - mEnterKey.label = res.getText(R.string.label_go_key); - break; - case EditorInfo.IME_ACTION_NEXT: - mEnterKey.iconPreview = null; - mEnterKey.icon = null; - mEnterKey.label = res.getText(R.string.label_next_key); - break; - case EditorInfo.IME_ACTION_SEARCH: - mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_search); - mEnterKey.label = null; - break; - case EditorInfo.IME_ACTION_SEND: - mEnterKey.iconPreview = null; - mEnterKey.icon = null; - mEnterKey.label = res.getText(R.string.label_send_key); - break; - default: - mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_return); - mEnterKey.label = null; - break; - } - } - - void setSpaceIcon(final Drawable icon) { - if (mSpaceKey != null) { - mSpaceKey.icon = icon; - } - } - - static class LatinKey extends Keyboard.Key { - - public LatinKey(Resources res, Keyboard.Row parent, int x, int y, XmlResourceParser parser) { - super(res, parent, x, y, parser); - } - - /** - * Overriding this method so that we can reduce the target area for the key that - * closes the keyboard. - */ - @Override - public boolean isInside(int x, int y) { - return super.isInside(x, codes[0] == KEYCODE_CANCEL ? y - 10 : y); - } - } - -} diff --git a/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/LatinKeyboardView.java b/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/LatinKeyboardView.java deleted file mode 100644 index a1854da8..00000000 --- a/src/java/KP2ASoftKeyboard/src/keepass2android/softkeyboard/LatinKeyboardView.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2008-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. - */ - -package keepass2android.softkeyboard; - -import android.content.Context; -import android.inputmethodservice.Keyboard; -import android.inputmethodservice.Keyboard.Key; -import android.inputmethodservice.KeyboardView; -import android.util.AttributeSet; -import android.view.inputmethod.InputMethodSubtype; - -public class LatinKeyboardView extends KeyboardView { - - static final int KEYCODE_OPTIONS = -100; - static final int KEYCODE_KP2A = -101; - static final int KEYCODE_SELECT_IME = -102; - - public LatinKeyboardView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - @Override - protected boolean onLongPress(Key key) { - if (key.codes[0] == Keyboard.KEYCODE_CANCEL) { - getOnKeyboardActionListener().onKey(KEYCODE_OPTIONS, null); - return true; - } else { - return super.onLongPress(key); - } - } - - void setSubtypeOnSpaceKey(final InputMethodSubtype subtype) { - //final LatinKeyboard keyboard = (LatinKeyboard)getKeyboard(); - //keyboard.setSpaceIcon(getResources().getDrawable(subtype.getIconResId())); - //invalidateAllKeys(); - } -} diff --git a/src/java/KP2ASoftKeyboard2/.gitignore b/src/java/KP2ASoftKeyboard2/.gitignore deleted file mode 100644 index d45006d9..00000000 --- a/src/java/KP2ASoftKeyboard2/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/native/obj -/native/libs - -/java/bin -/tests/bin diff --git a/src/java/KP2ASoftKeyboard2/java/.classpath b/src/java/KP2ASoftKeyboard2/java/.classpath deleted file mode 100644 index 51769745..00000000 --- a/src/java/KP2ASoftKeyboard2/java/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/.project b/src/java/KP2ASoftKeyboard2/java/.project deleted file mode 100644 index 2f557768..00000000 --- a/src/java/KP2ASoftKeyboard2/java/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - KP2ASoftKeyboard2 - - - - - - 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/KP2ASoftKeyboard2/java/.settings/org.eclipse.jdt.core.prefs b/src/java/KP2ASoftKeyboard2/java/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index b080d2dd..00000000 --- a/src/java/KP2ASoftKeyboard2/java/.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/KP2ASoftKeyboard2/java/Android.mk b/src/java/KP2ASoftKeyboard2/java/Android.mk deleted file mode 100644 index 03d48aaa..00000000 --- a/src/java/KP2ASoftKeyboard2/java/Android.mk +++ /dev/null @@ -1,22 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := LatinIME - -LOCAL_CERTIFICATE := shared - -LOCAL_JNI_SHARED_LIBRARIES := libjni_latinime - -LOCAL_STATIC_JAVA_LIBRARIES := android-common - -#LOCAL_AAPT_FLAGS := -0 .dict - -LOCAL_SDK_VERSION := current - -LOCAL_PROGUARD_FLAG_FILES := proguard.flags - -include $(BUILD_PACKAGE) diff --git a/src/java/KP2ASoftKeyboard2/java/AndroidManifest.xml b/src/java/KP2ASoftKeyboard2/java/AndroidManifest.xml deleted file mode 100644 index 4101f662..00000000 --- a/src/java/KP2ASoftKeyboard2/java/AndroidManifest.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/MODULE_LICENSE_APACHE2 b/src/java/KP2ASoftKeyboard2/java/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29b..00000000 diff --git a/src/java/KP2ASoftKeyboard2/java/NOTICE b/src/java/KP2ASoftKeyboard2/java/NOTICE deleted file mode 100644 index 7340b9e3..00000000 --- a/src/java/KP2ASoftKeyboard2/java/NOTICE +++ /dev/null @@ -1,190 +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. - - 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. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/src/java/KP2ASoftKeyboard2/java/createProjectZip.bat b/src/java/KP2ASoftKeyboard2/java/createProjectZip.bat deleted file mode 100644 index 82b33699..00000000 --- a/src/java/KP2ASoftKeyboard2/java/createProjectZip.bat +++ /dev/null @@ -1,11 +0,0 @@ -rmdir projectzip /s /q -mkdir projectzip -del project.zip -xcopy bin projectzip\bin\ /E -xcopy res projectzip\res\ /E -rmdir projectzip\bin\res\crunch /s /q -cd projectzip -"c:\Program Files\7-Zip\7z.exe" a -tzip project.zip bin -"c:\Program Files\7-Zip\7z.exe" a -tzip project.zip res -cd .. -xcopy projectzip\project.zip project.zip \ No newline at end of file diff --git a/src/java/KP2ASoftKeyboard2/java/gen/keepass2android/softkeyboard/BuildConfig.java b/src/java/KP2ASoftKeyboard2/java/gen/keepass2android/softkeyboard/BuildConfig.java deleted file mode 100644 index 80eada24..00000000 --- a/src/java/KP2ASoftKeyboard2/java/gen/keepass2android/softkeyboard/BuildConfig.java +++ /dev/null @@ -1,8 +0,0 @@ -/*___Generated_by_IDEA___*/ - -package keepass2android.softkeyboard; - -/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ -public final class BuildConfig { - public final static boolean DEBUG = Boolean.parseBoolean(null); -} \ No newline at end of file diff --git a/src/java/KP2ASoftKeyboard2/java/libs/armeabi-v7a/libjni_latinime.so b/src/java/KP2ASoftKeyboard2/java/libs/armeabi-v7a/libjni_latinime.so deleted file mode 100644 index fce10f89..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/libs/armeabi-v7a/libjni_latinime.so and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/libs/armeabi/libjni_latinime.so b/src/java/KP2ASoftKeyboard2/java/libs/armeabi/libjni_latinime.so deleted file mode 100644 index 3f97a516..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/libs/armeabi/libjni_latinime.so and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/libs/x86/libjni_latinime.so b/src/java/KP2ASoftKeyboard2/java/libs/x86/libjni_latinime.so deleted file mode 100644 index 7dc1bbe4..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/libs/x86/libjni_latinime.so and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/proguard.flags b/src/java/KP2ASoftKeyboard2/java/proguard.flags deleted file mode 100644 index 95c153fd..00000000 --- a/src/java/KP2ASoftKeyboard2/java/proguard.flags +++ /dev/null @@ -1,8 +0,0 @@ --keep class keepass2android.softkeyboard.BinaryDictionary { - int mDictLength; - (...); -} - --keep class keepass2android.softkeyboard.Suggest { - (...); -} diff --git a/src/java/KP2ASoftKeyboard2/java/project.properties b/src/java/KP2ASoftKeyboard2/java/project.properties deleted file mode 100644 index 484dab07..00000000 --- a/src/java/KP2ASoftKeyboard2/java/project.properties +++ /dev/null @@ -1,15 +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-17 -android.library=true diff --git a/src/java/KP2ASoftKeyboard2/java/res/anim/key_preview_fadein.xml b/src/java/KP2ASoftKeyboard2/java/res/anim/key_preview_fadein.xml deleted file mode 100644 index 9fad7b9a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/anim/key_preview_fadein.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/anim/key_preview_fadeout.xml b/src/java/KP2ASoftKeyboard2/java/res/anim/key_preview_fadeout.xml deleted file mode 100644 index 7de5123c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/anim/key_preview_fadeout.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/anim/mini_keyboard_fadein.xml b/src/java/KP2ASoftKeyboard2/java/res/anim/mini_keyboard_fadein.xml deleted file mode 100644 index 9fad7b9a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/anim/mini_keyboard_fadein.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/anim/mini_keyboard_fadeout.xml b/src/java/KP2ASoftKeyboard2/java/res/anim/mini_keyboard_fadeout.xml deleted file mode 100644 index 7de5123c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/anim/mini_keyboard_fadeout.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png deleted file mode 100644 index 01fc8ca7..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png deleted file mode 100644 index af4017e2..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png deleted file mode 100644 index 4c35aca9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png deleted file mode 100644 index 174f3452..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png deleted file mode 100644 index 1fcbd9a8..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png deleted file mode 100644 index 072753f3..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png deleted file mode 100644 index b6c234c0..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png deleted file mode 100644 index 73a8cd1c..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png deleted file mode 100644 index 1ad74605..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.9.png deleted file mode 100644 index e3a77d61..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png deleted file mode 100644 index 431c4496..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png deleted file mode 100644 index ccd59d5f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png deleted file mode 100644 index 42c7c146..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png deleted file mode 100644 index 01e2506b..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png deleted file mode 100644 index fad0ec45..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png deleted file mode 100644 index 83c6eb3f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png deleted file mode 100644 index 215f8157..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png deleted file mode 100644 index 88acdd74..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png deleted file mode 100644 index e047eaff..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png deleted file mode 100644 index 218a2d29..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png deleted file mode 100644 index afe49512..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/cancel.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/cancel.png deleted file mode 100644 index 506cf99d..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/cancel.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/candidate_feedback_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/candidate_feedback_background.9.png deleted file mode 100644 index 203c4e64..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/candidate_feedback_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/caution.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/caution.png deleted file mode 100644 index 5cb6c54b..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/caution.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/dialog_bubble_step02.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/dialog_bubble_step02.9.png deleted file mode 100644 index b338364c..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/dialog_bubble_step02.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/dialog_bubble_step07.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/dialog_bubble_step07.9.png deleted file mode 100644 index 94b91543..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/dialog_bubble_step07.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/highlight_pressed.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/highlight_pressed.png deleted file mode 100644 index ae04901a..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/highlight_pressed.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/hint_popup.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/hint_popup.9.png deleted file mode 100644 index b5ec003e..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/hint_popup.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_dialog_keyboard.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_dialog_keyboard.png deleted file mode 100644 index c7729566..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_dialog_keyboard.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_mic_dialog.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_mic_dialog.png deleted file mode 100644 index 349dc4b3..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_mic_dialog.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_subtype_keyboard.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_subtype_keyboard.png deleted file mode 100644 index 7015e266..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_subtype_keyboard.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_subtype_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_subtype_mic.png deleted file mode 100644 index cb86a559..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_subtype_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_suggest_strip_microphone.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_suggest_strip_microphone.png deleted file mode 100644 index c00b4aaa..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_suggest_strip_microphone.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png deleted file mode 100644 index 256dc3d6..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_background.9.png deleted file mode 100644 index edffac5b..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_dark_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_dark_background.9.png deleted file mode 100644 index f315cbdd..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_dark_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_0.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_0.9.png deleted file mode 100644 index 271264e9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_0.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_1.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_1.9.png deleted file mode 100644 index eaf37426..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_1.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_2.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_2.9.png deleted file mode 100644 index 8a165711..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_2.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_3.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_3.9.png deleted file mode 100644 index 34b50110..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_3.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_4.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_4.9.png deleted file mode 100644 index d4cc250d..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_4.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_5.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_5.9.png deleted file mode 100644 index 6a054b42..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_5.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_6.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_6.9.png deleted file mode 100644 index 66e91400..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_6.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_7.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_7.9.png deleted file mode 100644 index 5eae24f4..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_7.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_8.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_8.9.png deleted file mode 100644 index ea7f512f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_8.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_9.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_9.9.png deleted file mode 100644 index 0bf85de9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_hint_9.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_key_feedback_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_key_feedback_background.9.png deleted file mode 100644 index 762a2570..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_key_feedback_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_key_feedback_more_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_key_feedback_more_background.9.png deleted file mode 100644 index 141d2d6b..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_key_feedback_more_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png deleted file mode 100644 index d6b2c793..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_suggest_strip.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_suggest_strip.9.png deleted file mode 100644 index 0ccdb6ab..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_suggest_strip.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png deleted file mode 100644 index 7ca3e613..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/list_selector_background_pressed.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/list_selector_background_pressed.9.png deleted file mode 100644 index ba79cf7f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/list_selector_background_pressed.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/mic_slash.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/mic_slash.png deleted file mode 100644 index dc8da625..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/mic_slash.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ok_cancel.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ok_cancel.png deleted file mode 100644 index f11e57a3..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/ok_cancel.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level0.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level0.png deleted file mode 100644 index 342849cf..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level0.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level1.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level1.png deleted file mode 100644 index 8947a430..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level1.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level2.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level2.png deleted file mode 100644 index 44fc58c4..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level2.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level3.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level3.png deleted file mode 100644 index cfa5c1b8..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level3.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level4.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level4.png deleted file mode 100644 index a050d883..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level4.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level5.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level5.png deleted file mode 100644 index 8cd5ae7a..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level5.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level6.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level6.png deleted file mode 100644 index 9f4481eb..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/speak_now_level6.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png deleted file mode 100644 index 3e4eff69..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_delete.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_delete.png deleted file mode 100644 index 1d24cc85..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_delete.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_done.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_done.png deleted file mode 100644 index b77803d2..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_done.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_kp2a.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_kp2a.png deleted file mode 100644 index 66608769..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_kp2a.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_mic.png deleted file mode 100644 index 512f4608..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num0.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num0.png deleted file mode 100644 index 678a790d..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num0.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num1.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num1.png deleted file mode 100644 index 4e68e35b..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num1.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num2.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num2.png deleted file mode 100644 index 546663fd..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num2.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num3.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num3.png deleted file mode 100644 index 57f9a8d8..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num3.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num4.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num4.png deleted file mode 100644 index de504388..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num4.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num5.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num5.png deleted file mode 100644 index 1d2e1ef8..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num5.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num6.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num6.png deleted file mode 100644 index 39788b72..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num6.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num7.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num7.png deleted file mode 100644 index fff6f27b..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num7.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num8.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num8.png deleted file mode 100644 index 8cc1a955..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num8.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num9.png deleted file mode 100644 index 02174250..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_num9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_numalt.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_numalt.png deleted file mode 100644 index 200714f6..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_numalt.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_numpound.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_numpound.png deleted file mode 100644 index 0a46122b..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_numpound.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_numstar.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_numstar.png deleted file mode 100644 index ca22bd53..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_numstar.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_return.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_return.png deleted file mode 100644 index 426e1599..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_return.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_search.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_search.png deleted file mode 100644 index 1b6f884f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_search.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_settings.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_settings.png deleted file mode 100644 index 08ba18f2..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_settings.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_shift.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_shift.png deleted file mode 100644 index 5a22dd30..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_shift.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png deleted file mode 100644 index 56644912..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_space.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_space.png deleted file mode 100644 index cd0ebe2f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_space.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_tab.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_tab.png deleted file mode 100644 index 3466e127..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_bkeyboard_tab.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard.png deleted file mode 100644 index b57ae665..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_123_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_123_mic.png deleted file mode 100644 index 62669803..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_123_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_delete.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_delete.png deleted file mode 100644 index 459ebcff..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_delete.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_done.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_done.png deleted file mode 100644 index 471c5021..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_done.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png deleted file mode 100644 index eef78968..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png deleted file mode 100644 index 8322e8e1..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_done.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_done.png deleted file mode 100644 index 7015e266..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_done.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_kp2a.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_kp2a.png deleted file mode 100644 index d4616218..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_kp2a.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png deleted file mode 100644 index 889477cf..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png deleted file mode 100644 index b0f6d7fe..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png deleted file mode 100644 index f82c33ae..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png deleted file mode 100644 index 819236c8..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_return.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_return.png deleted file mode 100644 index f038d3ab..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_return.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_search.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_search.png deleted file mode 100644 index 337f9e4f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_search.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_settings.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_settings.png deleted file mode 100644 index 8a02be07..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_settings.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png deleted file mode 100644 index abf15f8f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png deleted file mode 100644 index 1fd822ea..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_space.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_space.png deleted file mode 100644 index 70debca9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_space.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png deleted file mode 100644 index d2efb161..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_kp2a.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_kp2a.png deleted file mode 100644 index f3cfbd4e..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_kp2a.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png deleted file mode 100644 index dcc4bd59..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png deleted file mode 100644 index ecf61a98..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_mic.png deleted file mode 100644 index c8dca62a..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num0.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num0.png deleted file mode 100644 index 10ac70b9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num0.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num1.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num1.png deleted file mode 100644 index 0fc03efa..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num1.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num2.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num2.png deleted file mode 100644 index 283560b3..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num2.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num3.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num3.png deleted file mode 100644 index 9a3b3294..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num3.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num4.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num4.png deleted file mode 100644 index f13ff1ae..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num4.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num5.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num5.png deleted file mode 100644 index c251329f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num5.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num6.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num6.png deleted file mode 100644 index 4acba4c9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num6.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num7.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num7.png deleted file mode 100644 index 14931c18..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num7.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num8.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num8.png deleted file mode 100644 index d4973fdc..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num8.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num9.png deleted file mode 100644 index 49cec66f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_num9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_numalt.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_numalt.png deleted file mode 100644 index 3cc5311c..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_numalt.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_numpound.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_numpound.png deleted file mode 100644 index d0913392..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_numpound.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_numstar.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_numstar.png deleted file mode 100644 index e838e169..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_numstar.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_return.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_return.png deleted file mode 100644 index 9d97e1ef..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_return.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_search.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_search.png deleted file mode 100644 index 1aa22d7e..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_search.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_settings.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_settings.png deleted file mode 100644 index 35d1ed6e..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_settings.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_shift.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_shift.png deleted file mode 100644 index bf217d14..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_shift.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_shift_locked.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_shift_locked.png deleted file mode 100644 index d11b3971..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_shift_locked.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_space.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_space.png deleted file mode 100644 index fcd20de7..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_space.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_space_led.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_space_led.9.png deleted file mode 100644 index 2c6f4a92..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_space_led.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_tab.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_tab.png deleted file mode 100644 index 51d17d98..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/sym_keyboard_tab.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/voice_ime_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/voice_ime_background.9.png deleted file mode 100644 index 42868522..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/voice_ime_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/voice_swipe_hint.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/voice_swipe_hint.png deleted file mode 100644 index 130f83a9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/voice_swipe_hint.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/working.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/working.png deleted file mode 100644 index 5ea70230..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-hdpi/working.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-land/btn_keyboard_key.xml b/src/java/KP2ASoftKeyboard2/java/res/drawable-land/btn_keyboard_key.xml deleted file mode 100644 index 45578e58..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/drawable-land/btn_keyboard_key.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png deleted file mode 100644 index 4e337fa0..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png deleted file mode 100644 index fe18497d..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png deleted file mode 100644 index 00aab3d5..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png deleted file mode 100644 index ac0bfd3c..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png deleted file mode 100644 index ea2f3578..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png deleted file mode 100644 index 6195ac0d..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png deleted file mode 100644 index 20f3d508..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png deleted file mode 100644 index 1ed3065c..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png deleted file mode 100644 index 50cd06ae..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_popup_normal.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_popup_normal.9.png deleted file mode 100644 index 02d0fcf9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_popup_normal.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png deleted file mode 100644 index 125ff133..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png deleted file mode 100644 index 7ce52f0f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png deleted file mode 100644 index 7ba18dd2..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png deleted file mode 100644 index bda9b839..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png deleted file mode 100644 index fad0ec45..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png deleted file mode 100644 index 0c16ed50..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png deleted file mode 100644 index 215f8157..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png deleted file mode 100644 index 88acdd74..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png deleted file mode 100644 index 39b9314a..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png deleted file mode 100644 index bdcf06e1..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png deleted file mode 100644 index 79621a9e..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/cancel.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/cancel.png deleted file mode 100644 index 713a3787..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/cancel.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/candidate_feedback_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/candidate_feedback_background.9.png deleted file mode 100644 index 2a80f096..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/candidate_feedback_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/caution.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/caution.png deleted file mode 100644 index eaef5342..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/caution.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/dialog_bubble_step02.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/dialog_bubble_step02.9.png deleted file mode 100644 index d77f85fe..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/dialog_bubble_step02.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/dialog_bubble_step07.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/dialog_bubble_step07.9.png deleted file mode 100644 index 80f4a0ea..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/dialog_bubble_step07.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/highlight_pressed.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/highlight_pressed.png deleted file mode 100644 index d27f1061..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/highlight_pressed.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/hint_popup.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/hint_popup.9.png deleted file mode 100644 index 444cc26e..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/hint_popup.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_dialog_keyboard.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_dialog_keyboard.png deleted file mode 100644 index 9a5aada8..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_dialog_keyboard.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_mic_dialog.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_mic_dialog.png deleted file mode 100644 index 77613ca0..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_mic_dialog.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_subtype_keyboard.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_subtype_keyboard.png deleted file mode 100644 index 0d7ebd4e..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_subtype_keyboard.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_subtype_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_subtype_mic.png deleted file mode 100644 index 247d5b3a..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_subtype_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_suggest_strip_microphone.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_suggest_strip_microphone.png deleted file mode 100644 index 18f314a6..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_suggest_strip_microphone.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png deleted file mode 100644 index ff629b67..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_background.9.png deleted file mode 100644 index 2bd4b628..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_dark_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_dark_background.9.png deleted file mode 100644 index 4f81704c..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_dark_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_0.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_0.9.png deleted file mode 100644 index 61ad1b50..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_0.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_1.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_1.9.png deleted file mode 100644 index cd7772e7..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_1.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_2.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_2.9.png deleted file mode 100644 index fa5f8b79..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_2.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_3.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_3.9.png deleted file mode 100644 index 0c7336cb..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_3.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_4.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_4.9.png deleted file mode 100644 index 73ef06c0..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_4.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_5.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_5.9.png deleted file mode 100644 index aea460e1..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_5.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_6.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_6.9.png deleted file mode 100644 index 16a9237e..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_6.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_7.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_7.9.png deleted file mode 100644 index 6747a19c..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_7.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_8.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_8.9.png deleted file mode 100644 index 28be2fb8..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_8.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_9.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_9.9.png deleted file mode 100644 index 731d63b1..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_hint_9.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_key_feedback_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_key_feedback_background.9.png deleted file mode 100644 index a84c19c3..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_key_feedback_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_key_feedback_more_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_key_feedback_more_background.9.png deleted file mode 100644 index 82513aad..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_key_feedback_more_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_popup_panel_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_popup_panel_background.9.png deleted file mode 100644 index 0d9ab97f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_popup_panel_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_suggest_strip.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_suggest_strip.9.png deleted file mode 100644 index fa6c0fef..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_suggest_strip.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png deleted file mode 100644 index 36393636..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/list_selector_background_pressed.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/list_selector_background_pressed.9.png deleted file mode 100644 index 02b4e9a5..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/list_selector_background_pressed.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/mic_slash.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/mic_slash.png deleted file mode 100644 index d04b5634..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/mic_slash.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ok_cancel.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ok_cancel.png deleted file mode 100644 index 20d10f98..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/ok_cancel.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level0.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level0.png deleted file mode 100644 index 5bd13603..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level0.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level1.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level1.png deleted file mode 100644 index ccb76b87..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level1.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level2.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level2.png deleted file mode 100644 index 715f9008..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level2.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level3.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level3.png deleted file mode 100644 index 725248a2..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level3.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level4.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level4.png deleted file mode 100644 index ff6c50b4..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level4.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level5.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level5.png deleted file mode 100644 index a5d6b89d..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level5.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level6.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level6.png deleted file mode 100644 index dcdb48d0..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/speak_now_level6.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_123_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_123_mic.png deleted file mode 100644 index 0749b5fc..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_123_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_delete.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_delete.png deleted file mode 100644 index 1a5ff439..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_delete.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_done.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_done.png deleted file mode 100644 index 05ce7c64..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_done.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_kp2a.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_kp2a.png deleted file mode 100644 index 300d6b88..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_kp2a.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_mic.png deleted file mode 100644 index a6cb1cc0..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num0.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num0.png deleted file mode 100644 index 7188f9ca..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num0.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num1.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num1.png deleted file mode 100644 index 2a31bd45..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num1.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num2.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num2.png deleted file mode 100644 index c1e9cc9b..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num2.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num3.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num3.png deleted file mode 100644 index e9987668..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num3.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num4.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num4.png deleted file mode 100644 index 7f0f3ccc..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num4.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num5.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num5.png deleted file mode 100644 index 5f748b41..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num5.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num6.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num6.png deleted file mode 100644 index 78aae74a..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num6.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num7.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num7.png deleted file mode 100644 index 5bb874c4..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num7.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num8.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num8.png deleted file mode 100644 index 6b58fdc8..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num8.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num9.png deleted file mode 100644 index f348c92a..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_num9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_numalt.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_numalt.png deleted file mode 100644 index 4fa410b6..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_numalt.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_numpound.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_numpound.png deleted file mode 100644 index 9126eed0..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_numpound.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_numstar.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_numstar.png deleted file mode 100644 index 9b9f1b98..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_numstar.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_return.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_return.png deleted file mode 100644 index e76225d0..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_return.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_search.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_search.png deleted file mode 100644 index 1f180155..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_search.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_settings.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_settings.png deleted file mode 100644 index 08ba18f2..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_settings.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_shift.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_shift.png deleted file mode 100644 index c981188d..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_shift.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_shift_locked.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_shift_locked.png deleted file mode 100644 index b8cebd06..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_shift_locked.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_space.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_space.png deleted file mode 100644 index 4da7ee86..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_space.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_tab.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_tab.png deleted file mode 100644 index 2cb991cb..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_bkeyboard_tab.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard.png deleted file mode 100644 index 33d68ccc..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_123_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_123_mic.png deleted file mode 100644 index 35afe082..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_123_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_delete.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_delete.png deleted file mode 100644 index 1b0f3f83..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_delete.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_done.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_done.png deleted file mode 100644 index c0d6d139..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_done.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png deleted file mode 100644 index c556c35c..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png deleted file mode 100644 index a79f1585..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_done.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_done.png deleted file mode 100644 index 0d7ebd4e..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_done.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_kp2a.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_kp2a.png deleted file mode 100644 index c3dc5a9c..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_kp2a.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.png deleted file mode 100644 index eecb0269..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.png deleted file mode 100644 index 7e10ae3a..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_mic.png deleted file mode 100644 index 3ed0782d..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png deleted file mode 100644 index bc8f1cfc..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_return.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_return.png deleted file mode 100644 index dd99ff38..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_return.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_search.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_search.png deleted file mode 100644 index 6b8e01d9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_search.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_settings.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_settings.png deleted file mode 100644 index 03bad184..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_settings.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png deleted file mode 100644 index d5635755..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png deleted file mode 100644 index 494524a6..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_space.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_space.png deleted file mode 100644 index 36eb60c1..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_space.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_tab.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_tab.png deleted file mode 100644 index a10dc8fa..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_feedback_tab.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_kp2a.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_kp2a.png deleted file mode 100644 index db54e0ba..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_kp2a.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png deleted file mode 100644 index 7067a8bf..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png deleted file mode 100644 index f7a133d9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_mic.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_mic.png deleted file mode 100644 index e926b3fa..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_mic.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num0.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num0.png deleted file mode 100644 index e7007c87..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num0.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num1.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num1.png deleted file mode 100644 index aaac11b0..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num1.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num2.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num2.png deleted file mode 100644 index 4372eb8f..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num2.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num3.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num3.png deleted file mode 100644 index 6f54c850..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num3.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num4.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num4.png deleted file mode 100644 index 3e50bb95..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num4.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num5.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num5.png deleted file mode 100644 index c39ef440..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num5.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num6.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num6.png deleted file mode 100644 index ea88ceb9..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num6.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num7.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num7.png deleted file mode 100644 index ce800ba4..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num7.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num8.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num8.png deleted file mode 100644 index 1a8ff94b..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num8.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num9.png deleted file mode 100644 index 8b344c0a..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_num9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_numalt.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_numalt.png deleted file mode 100644 index 32a2cf3c..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_numalt.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_numpound.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_numpound.png deleted file mode 100644 index b2419d9a..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_numpound.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_numstar.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_numstar.png deleted file mode 100644 index cb66f968..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_numstar.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_return.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_return.png deleted file mode 100644 index 0c10f004..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_return.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_search.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_search.png deleted file mode 100644 index 614f85f5..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_search.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_settings.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_settings.png deleted file mode 100644 index ad7618fa..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_settings.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_shift.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_shift.png deleted file mode 100644 index 5109b047..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_shift.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_shift_lock.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_shift_lock.png deleted file mode 100644 index 244179c2..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_shift_lock.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_shift_locked.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_shift_locked.png deleted file mode 100644 index 244179c2..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_shift_locked.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_space.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_space.png deleted file mode 100644 index cbe4a88d..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_space.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_space_led.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_space_led.9.png deleted file mode 100644 index 1c1ca2cc..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_space_led.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_tab.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_tab.png deleted file mode 100644 index eddb9a59..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/sym_keyboard_tab.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/voice_ime_background.9.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/voice_ime_background.9.png deleted file mode 100644 index 9b15bc25..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/voice_ime_background.9.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/voice_swipe_hint.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/voice_swipe_hint.png deleted file mode 100644 index bb887325..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/voice_swipe_hint.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/working.png b/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/working.png deleted file mode 100644 index 4a930c52..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/drawable-mdpi/working.png and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key.xml b/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key.xml deleted file mode 100644 index 45578e58..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key2.xml b/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key2.xml deleted file mode 100644 index bd745b76..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key2.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key3.xml b/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key3.xml deleted file mode 100644 index dbe82d5f..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key3.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_fulltrans.xml b/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_fulltrans.xml deleted file mode 100644 index bad2a931..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_fulltrans.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_gingerbread.xml b/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_gingerbread.xml deleted file mode 100644 index 4a113a8a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_gingerbread.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_gingerbread_popup.xml b/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_gingerbread_popup.xml deleted file mode 100644 index 9b6d23be..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_gingerbread_popup.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_stone.xml b/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_stone.xml deleted file mode 100644 index a6040a04..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/drawable/btn_keyboard_key_stone.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable/ic_suggest_scroll_background.xml b/src/java/KP2ASoftKeyboard2/java/res/drawable/ic_suggest_scroll_background.xml deleted file mode 100644 index 9d246e40..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/drawable/ic_suggest_scroll_background.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/java/KP2ASoftKeyboard2/java/res/drawable/keyboard_key_feedback.xml b/src/java/KP2ASoftKeyboard2/java/res/drawable/keyboard_key_feedback.xml deleted file mode 100644 index 159ba868..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/drawable/keyboard_key_feedback.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/bubble_text.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/bubble_text.xml deleted file mode 100644 index c3957b65..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/bubble_text.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/candidate_preview.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/candidate_preview.xml deleted file mode 100644 index fe2002d4..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/candidate_preview.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/candidates.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/candidates.xml deleted file mode 100644 index f30b817e..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/candidates.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/input_basic.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/input_basic.xml deleted file mode 100644 index 0176565a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/input_basic.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/input_basic_highcontrast.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/input_basic_highcontrast.xml deleted file mode 100644 index b85eb2ba..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/input_basic_highcontrast.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/input_gingerbread.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/input_gingerbread.xml deleted file mode 100644 index 164fc0b7..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/input_gingerbread.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/input_stone_bold.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/input_stone_bold.xml deleted file mode 100644 index 1eac195c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/input_stone_bold.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/input_stone_normal.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/input_stone_normal.xml deleted file mode 100644 index 6669dfff..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/input_stone_normal.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/input_stone_popup.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/input_stone_popup.xml deleted file mode 100644 index 7b876b66..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/input_stone_popup.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/key_preview.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/key_preview.xml deleted file mode 100644 index de03506a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/key_preview.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/keyboard_popup.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/keyboard_popup.xml deleted file mode 100644 index ee997290..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/keyboard_popup.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/recognition_status.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/recognition_status.xml deleted file mode 100644 index 49af7736..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/recognition_status.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/voice_punctuation_hint.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/voice_punctuation_hint.xml deleted file mode 100644 index 629a7f2b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/voice_punctuation_hint.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/layout/voice_swipe_hint.xml b/src/java/KP2ASoftKeyboard2/java/res/layout/voice_swipe_hint.xml deleted file mode 100644 index 4e8859a7..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/layout/voice_swipe_hint.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/raw/main.dict b/src/java/KP2ASoftKeyboard2/java/res/raw/main.dict deleted file mode 100644 index 472c23a2..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/raw/main.dict and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/raw/type3.ogg b/src/java/KP2ASoftKeyboard2/java/res/raw/type3.ogg deleted file mode 100644 index 20e67080..00000000 Binary files a/src/java/KP2ASoftKeyboard2/java/res/raw/type3.ogg and /dev/null differ diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ar/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ar/strings.xml deleted file mode 100644 index 69f7f846..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ar/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "لوحة مفاتيح Keepass2Android" - "إعدادات لوحة مفاتيح Keepass2Android" - "خيارات الإرسال" - "اهتزاز عند الضغط على مفتاح" - "صوت عند الضغط على مفتاح" - "انبثاق عند الضغط على المفاتيح" - "تصحيح أخطاء الكتابة" - "تمكين تصحيح خطأ الإدخال" - "أخطاء في الإدخال الأفقي" - "تمكين تصحيح خطأ الإدخال" - "اقتراحات الكلمات" - "تصحيح الكلمة السابقة تلقائيًا" - "اقتراحات الكلمات" - "إعدادات اقتراحات الكلمات" - "تمكين الإكمال التلقائي أثناء الكتابة" - "إكمال تلقائي" - "زيادة حجم الحقل النصي" - "إخفاء اقتراحات الكلمات في طريقة العرض الأفقية" - "استخدام الأحرف الكبيرة تلقائيًا" - "استخدام الأحرف الكبيرة في بداية الجملة" - "ترقيم تلقائي" - - "إصلاحات سريعة" - "تصحيح الأخطاء المكتوبة الشائعة" - "عرض الاقتراحات" - "عرض الكلمات المقترحة أثناء الكتابة" - "إكمال تلقائي" - "مفتاح المسافة والترقيم لإدخال كلمة محددة تلقائيًا" - "عرض مفتاح الإعدادات" - "تلقائي" - "إظهار بشكل دائم" - "إخفاء دومًا" - - - - "اقتراحات ثنائية" - "استخدام الكلمة السابقة لتحسين الاقتراح" - - "لا شيء" - "أساسي" - "متقدم" - - "%s : تم الحفظ" - "اضغط باستمرار على أحد المفاتيح لأسفل لمشاهدة علامات التشكيل" - "اضغط على مفتاح الرجوع ↶ لإغلاق لوحة المفاتيح في أي نقطة" - "الدخول إلى الأرقام والرموز" - "اضغط مع الاستمرار على أقصى يمين الكلمة لإضافتها إلى القاموس" - "المس هذا التلميح للمتابعة »" - "المس هنا لإغلاق هذا التلميح وبدء الكتابة!" - "تفتح لوحة المفاتيح في أي وقت تلمس فيه حقلًا نصيًا" - "المس مع الاستمرار أحد المفاتيح لعرض علامات التشكيل"\n"(ø, ö, ô, ó, وهكذا)" - "التبديل إلى الأرقام والرموز من خلال لمس هذا الزر" - "يمكنك الرجوع إلى الأحرف من خلال لمس هذا المفتاح مرة أخرى" - "المس هذا المفتاح مع الاستمرار لتغيير إعدادات لوحة المفاتيح، مثل الإكمال التلقائي" - "جربه!" - "تنفيذ" - "التالي" - "تم" - "إرسال" - "?123" - "123" - "ب ت ث" - "ALT" - "الإدخال الصوتي" - "الإدخال الصوتي غير معتمد حاليًا للغتك، ولكنه يعمل باللغة الإنجليزية." - "الإدخال الصوتي هو ميزة تجريبية تستخدم التعرف على الكلام المتصل في Google." - "لتشغيل الإدخال الصوتي، انتقل إلى إعدادات لوحة المفاتيح." - "لاستخدام الإدخال الصوتي، اضغط على زر الميكروفون أو مرر إصبعك عبر لوحة المفاتيح على الشاشة." - "تحدث الآن" - "العمل" - - "خطأ. الرجاء المحاولة مرة أخرى." - "تعذر الاتصال" - "خطأ، كلام أكثر مما ينبغي." - "مشكلة بالإعدادات الصوتية" - "خطأ في الخادم" - "لم يتم سماع كلام" - "لم يتمّ العثور على أية تطابقات" - "لم يتم تثبيت البحث الصوتي" - "تلميح:"" مرر عبر لوحة المفاتيح للتحدث" - "تلميح:"" جرب في المرة التالية نطق الترقيم مثل \"نقطة\" أو \"فاصلة\" أو \"علامة استفهام\"." - "إلغاء" - "موافق" - "الإدخال الصوتي" - - "في لوحة المفاتيح الرئيسية" - "على لوحة مفاتيح الرموز" - "إيقاف" - - - "الميكروفون في لوحة المفاتيح الرئيسية" - "الميكروفون على لوحة مفاتيح الرموز" - "تم تعطيل الإدخال الصوتي" - - "إرسال تلقائي بعد الصوت" - "الضغط تلقائيًا على المفتاح enter عند البحث أو الانتقال إلى الحقل التالي." - "افتح لوحة المفاتيح"\n\n"المس أي حقل نصي." - "إغلاق لوحة المفاتيح"\n\n"اضغط على المفتاح \"رجوع\"." - "المس أحد مفاتيح الخيارات مع الاستمرار"\n\n"الدخول إلى الترقيم والحركات." - "إعدادات لوحة المفاتيح"\n\n"المس مع الاستمرار المفتاح ""?123""." - "com." - "net." - "org." - "gov." - "edu." - "تحديد طريقة الإرسال" - "لغات الإدخال" - "مرر إصبعك على مفتاح المسافة لتغيير اللغة" - "← المس مرة أخرى للحفظ" - "القاموس متاح" - "تمكين ملاحظات المستخدم" - "المساعدة في تحسين محرر طريقة الإرسال هذا من خلال إرسال إحصاءات الاستخدام وتقارير الأعطال تلقائيًا إلى Google." - "المس لتصحيح الكلمات" - "المس الكلمات المدخلة لتصحيحها" - "مظهر لوحة المفاتيح" - "لوحة مفاتيح" - "صوت" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ar/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ar/strings_kp2a.xml deleted file mode 100644 index 7845cbac..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ar/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - اختر مُدخل آخر - اختر مُدخل - البحث عن مُدخل يحتوي على \"%1$s\" - المستخدم - كلمة السر - اعدادات ادخال البيانات السرية - التعبئة الاوتوماتيكية مفعلة - ملئ البيانات تلقائيا عند وجود حقل فارغ اذا وجد keePass2 Android ان البيانات متوفرة للوحة المفاتيح. - تذكر نصوص حقول التلميح - اذا عبئ الحقل يدويا عن طريق استخدام قيم keepass2Android، تذكر اي قيمة استخدمت و استخدم نص التلميح لذلك الحقل حتى تعاد تعبئتها تلقائيا. - لوحة المفاتيح بسيطة - إظهار لوحة المفاتيح ذات الصف الواحد إذا وجد إدخال متاح للوحة المفاتيح. في حالة التعطيل، يظهر صندوق حوار عند الضغط على مفتاح Keepass2Android. - اقفال قاعدة البيانات عند الانتهاء - عند الضغط على مفتاح \'ذهاب\' على لوحة المفاتيح البسيطة، اقفل قاعدة بيانات. - بدل لوحة المفاتيح عند الانتهاء - عند الضغط على مفتاح \'ذهاب\' على لوحة المفاتيح البسيطة، ابدل لوحة المفاتيح. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-bg-rBG/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-bg-rBG/strings_kp2a.xml deleted file mode 100644 index b5d5f436..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-bg-rBG/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Изберете друг запис - Изберете стойност - Търсене за въведено с \"%1$s\" - Потребител - Парола - Входни настройки на данни - Автоматично попълване е включено - Автоматично попълване при въведено празно поле, ако е Keepass2Android запис е на разположение за клавиатурата и има стойност, която съответства на полето на подсказване. - Запомни скрития текст в полето - Ако текстово поле е попълнено чрез ръчно избиране на стойност от Keepass2Android, запомни коя стойност е въведена в текстовото поле. Полето по-късно ще бъде сравнено със скритата стойност. - Проста клавиатура - Покажи простата 1 редова клавиатура ако стойноста е налична. Ако е изключена се показва диалог при натискане на бутон на Keepass2Android - Заключване на базата данни, когато е готово - При натискане на клавиша Done/Send/Go на простата 1-редова клавиатура, автоматично се заключва на базата данни. - Превключване на клавиатурата, когато свършиш - При натискане на клавиша Done/Send/Go на простата 1-редова клавиатура, превключи клавиатурата. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-bg/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-bg/strings.xml deleted file mode 100644 index 9184fc62..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-bg/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Клавиатура на Keepass2Android" - "Настройки на клавиатурата на Keepass2Android" - "Опции за въвеждане" - "Да вибрира при натискане на клавиш" - "Звук при натискане на клавиш" - "Изскачащ прозорец при натискане на клавиш" - "Коригиране на грешките при въвеждане" - "Активиране на корекция на грешки при въвеждане" - "Грешки при въвеждане в хоризонтален изглед" - "Активиране на корекция на грешки при въвеждане" - "Предложения на думи" - "Автоматично коригиране на предишната дума" - "Предложения на думи" - "Настройки за предложения на думи" - "Активиране на автодовършване, докато пишете" - "Автодовършване" - "Размерът на текстовото поле да се увеличи" - "Скриване на предложенията на думи в хоризонтален изглед" - "Автоматично поставяне на главни букви" - "Поставя главна буква в началото на изреченията" - "Автоматично поставяне на пунктуация" - - "Бързи корекции" - "Коригира най-честите грешки при въвеждане" - "Показване на предложения" - "Показване на предложения, докато пишете" - "Автоматично завършване" - "Клавишът за интервал и пунктуация поставя автоматично откроена дума" - "Показване на клавиша за настройки" - "Автоматично" - "Да се показва винаги" - "Да се скрива винаги" - - - - "Предложения за биграми" - "Използване на предишната дума за подобряване на предложението" - - "Няма" - "Основен" - "Разширени" - - "%s : Запазено" - "Задръжте клавиша, за да видите ударенията (ø, ö и т.н.)" - "Натиснете клавиша „Назад“ ↶, за да затворите клавиатурата във всяка една точка" - "Достъп до номера и символи" - "Натиснете и задръжте върху най-лявата дума, за да я добавите към речника" - "Докоснете съвета, за да продължите »" - "Докоснете тук, за да затворите този съвет и да започнете да пишете!" - "Клавиатурата се отваря при всяко докосване на текстово поле" - "Докоснете и задръжте клавиша, за да видите ударенията"\n"(ø, ö, ô, ó и т.н.)" - "Докосването на този клавиш води до преминаване към цифри и символи" - "Върнете се към използване на букви чрез повторно докосване на този клавиш" - "Докоснете и задръжте клавиша за промяна на настройките на клавиатурата, напр. автодовършване" - "Пробвайте!" - "Старт" - "Напред" - "Готово" - "Изпращане" - "?123" - "123" - "АБВГ" - "ALT" - "Гласово въвеждане" - "За вашия език понастоящем не се поддържа гласово въвеждане, но можете да го използвате на английски." - "Гласовото въвеждане е експериментална функция, използваща разпознаването на реч в мрежата на Google." - "За да изключите гласовото въвеждане, отворете настройките на клавиатурата." - "За да използвате гласово въвеждане, натиснете бутона на микрофона или плъзнете пръст през екранната клавиатура." - "Говорете сега" - "Обработва се" - - "Грешка. Моля, опитайте отново." - "Не можа да се свърже" - "Грешка, твърде много речева информация." - "Аудиопроблем" - "Грешка в сървъра" - "Не се чува реч" - "Нямаше съответствия" - "Не е инсталирано гласово търсене" - "Съвет:"" Прокарайте палец през клавиатурата, за да говорите" - "Съвет:"" Следващия път опитайте да произнесете знаците за пунктуация, напр. „точка“, „запетая“ или „въпросителен знак“." - "Отказ" - "OK" - "Гласово въвеждане" - - "На основната клавиатура" - "На клавиатурата на символите" - "Изкл." - - - "Микрофон на основната клавиатура" - "Микрофон на клавиатурата на символите" - "Гласовото въвеждане е деактивирано" - - "Автоматично изпращане след глас" - "Да се натиска автоматично „Enter“ при търсене или преминаване към следващото поле." - "Отворете клавиатурата"\n\n"Докоснете текстово поле." - "Затваряне на клавиатурата"\n\n"Натиснете клавиша „Назад“." - "Докоснете и задръжте клавиш за опции"\n\n"Използвайте пунктуация и акценти." - "Настройки на клавиатурата"\n\n"Докоснете и задръжте клавиша ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Избор на метод на въвеждане" - "Входни езици" - "Плъзнете пръст по клавиша за интервал за промяна на езика" - "← Докоснете отново, за да запазите" - "Има достъп до речник" - "Активиране на отзивите от потребителите" - "Помогнете за подобряването на този редактор за въвеждане чрез автоматично изпращане до Google на статистически данни за употребата и сигнали за сривове." - "Докоснете, за да поправите думите" - "Докоснете въведените думи, за да ги поправите" - "Тема на клавиатурата" - "клавиатура" - "гласово" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ca/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ca/strings.xml deleted file mode 100644 index 8a31daa4..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ca/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Teclat Keepass2Android" - "Configuració del teclat d\'Keepass2Android" - "Opcions d\'entrada" - "Vibra en prémer tecles" - "So en prémer una tecla" - "Finestra emergent en prémer un botó" - "Corregeix els errors ortogràfics" - "Activa la correcció d\'errors d\'entrada" - "Errors d\'entrada en horitzontal" - "Activa la correcció d\'errors d\'entrada" - "Suggeriments de paraules" - "Corregeix automàticament la paraula anterior" - "Suggeriments de paraules" - "Configuració de suggeriment de paraules" - "Activa l\'emplenament automàtic mentre s\'escriu" - "Emplenament automàtic" - "Augmenta la mida del camp de text" - "Amaga els suggeriments de paraules en visualització horitzontal" - "Majúscules automàtiques" - "Posa l\'inici d\'una frase en majúscula" - "Puntuació automàtica" - - "Correccions ràpides" - "Corregeix els errors d\'ortografia habituals" - "Mostra els suggeriments" - "Visualitza paraules suggerides mentre s\'escriu" - "Emplenament automàtic" - "La barra espaiadora i la puntuació insereixen automàticament la paraula ressaltada" - "Mostra la tecla de configuració" - "Automàtic" - "Mostra sempre" - "Amaga sempre" - - - - "Suggeriments Bigram" - "Utilitza la paraula anterior per millorar el suggeriment" - - "Cap" - "Bàsic" - "Avançat" - - "%s: desada" - "Manteniu una tecla premuda per veure\'n les variants (ø, ö, etc.)" - "Premeu la tecla Enrere ↶ per tancar el teclat en qualsevol moment" - "Accedeix a números i símbols" - "Manteniu premuda la paraula de l\'extrem esquerre per afegir-la al diccionari" - "Toqueu aquest suggeriment per continuar »" - "Toqueu aquí per tancar aquest suggeriment i començar a escriure." - "S\'obre el teclat cada vegada que toqueu un camp de text" - "Manteniu premuda una tecla per veure\'n les variants"\n"(ø, ö, ô, ó, etc.)" - "Toqueu aquesta tecla per canviar als números i als símbols" - "Torneu a tocar aquesta tecla per tornar a les lletres" - "Manteniu premuda aquesta tecla per canviar la configuració del teclat, com ara l\'emplenament automàtic" - "Proveu-ho!" - "Vés" - "Següent" - "Fet" - "Envia" - "?123" - "123" - "ABC" - "ALT" - "Entrada de veu" - "Actualment, l\'entrada de veu no és compatible amb el vostre idioma, però funciona en anglès." - "L\'entrada de veu és una funció experimental que utilitza el reconeixement de la parla en xarxa de Google." - "Per desactivar l\'entada de veu, aneu a la configuració del teclat." - "Per utilitzar l\'entrada de veu, premeu el botó del micròfon o feu lliscar el dit pel teclat en pantalla." - "Parleu ara" - "S\'està treballant" - - "Error. Torneu-ho a provar." - "No s\'ha pogut connectar" - "Error; s\'ha parlat massa." - "Problema d\'àudio" - "Error del servidor" - "No s\'escolten paraules" - "No hi ha resultats" - "Cerca per veu no instal·lada" - "Consell:"" Feu lliscar el dit pel teclat per parlar" - "Suggeriment:"" La propera vegada, proveu de dir la puntuació, com ara \"punt\", \"coma\" o \"interrogant\"." - "Cancel·la" - "D\'acord" - "Entrada de veu" - - "Al teclat principal" - "Al teclat de símbols" - "Desactivat" - - - "Micròfon al teclat principal" - "Micròfon al teclat de símbols" - "L\'entrada de veu està desactivada" - - "Enviament automàtic després de la veu" - "Prem automàticament Retorn en cercar o en anar al camp següent." - "Obrir el teclat"\n\n"Toqueu qualsevol camp de text." - "Tancar el teclat"\n\n"Premeu la tecla Enrere." - "Manteniu premuda una tecla per veure les opcions"\n\n"Accediu a la puntuació i als accents." - "Configuració del teclat"\n\n"Manteniu premuda la tecla ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Selecciona el mètode d\'entrada" - "Idiomes d\'entrada" - "Feu lliscar el dit a la barra espaiadora per canviar l\'idioma" - "← Torna a tocar per desar" - "Diccionari disponible" - "Activa els comentaris de l\'usuari" - "Ajuda a millorar aquest editor de mètodes d\'entrada enviant automàticament estadístiques d\'ús i informes de bloqueigs a Google." - "Toca per corregir paraules" - "Toca les paraules introduïdes per corregir-les" - "Tema del teclat" - "teclat" - "veu" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ca/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ca/strings_kp2a.xml deleted file mode 100644 index 8747d275..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ca/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Selecciona una altra entrada - Seleccioneu entrada - Cerca d\'entrada amb \"%1$s\" - Usuari - Contrasenya - Configuració de credencials d\'entrada - Emplenat automàtic activat - Emplenar automàticament en text quan un camp buit s\'introdueix, si una entrada Keepass2Android està disponible per al teclat i hi ha un valor que coincideix amb el text de pista del camp. - Recordar textos de pista de camp - Si un camp de text s\'omple manualment seleccionant el valor Keepass2Android, recordar quin valor va entrar al camp de text. El camp de text més tard és detectat pel seu text de pista. - Teclat senzill - Mostrar el teclat d\'1 línia si una pàgina està disponible per al teclat. Si està desactivat, es mostra un quadre de diàleg quan es prem la tecla Keepass2Android. - Bloquejar la base de dades quan s\'ha acabat - En prémer la tecla Fet/Enviar/Anar en el teclat d\'1 línia, automàticament bloca la base de dades. - Canviar teclat quan s\'ha acabat - En prémer la tecla Fet/Enviar/Anar en el teclat d\'1 línia, canviar el teclat. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-cs/bools.xml b/src/java/KP2ASoftKeyboard2/java/res/values-cs/bools.xml deleted file mode 100644 index 897f4b3d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-cs/bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - true - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-cs/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-cs/donottranslate-altchars.xml deleted file mode 100644 index d91a0e44..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-cs/donottranslate-altchars.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - áàâãäåæ - 3éěèêë - íìîï8 - óòôõöœø9 - ůúùûü7 - š§ß - ňñ - čç - ýÿ6 - ď - ř4 - ť5 - ž - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-cs/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-cs/strings.xml deleted file mode 100644 index da860124..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-cs/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Klávesnice Keepass2Android" - "Nastavení klávesnice Keepass2Android" - "Možnosti zadávání textu a dat" - "Při stisku klávesy vibrovat" - "Zvuk při stisku klávesy" - "Zobrazit znaky při stisku klávesy" - "Opravovat překlepy" - "Povolit opravu chyb vstupu" - "Chyby vstupu v zobrazení na šířku" - "Povolit opravu chyb vstupu" - "Návrhy slov" - "Automaticky opravit předchozí slovo" - "Návrhy slov" - "Nastavení návrhů slov" - "Povolit automatické dokončování při psaní" - "Automatické dokončování" - "Zvětšit textové pole" - "Skrýt návrhy slov v zobrazení na šířku" - "Velká písmena automaticky" - "Zahájit větu velkým písmenem" - "Automatická interpunkce" - - "Rychlé opravy" - "Opravuje nejčastější chyby při psaní" - "Zobrazit návrhy" - "Zobrazovat navržená slova během psaní" - "Automatické dokončování" - "Stisknutím mezerníku nebo interpunkčního znaménka automaticky vložíte zvýrazněné slovo." - "Zobrazit klávesu Nastavení" - "Automaticky" - "Vždy zobrazovat" - "Vždy skrývat" - - - - "Návrh Bigram" - "Použít předchozí slovo ke zlepšení návrhu" - - "Žádný" - "Základní" - "Pokročilé" - - "%s: Uloženo" - "Podržením klávesy zobrazíte diakritiku (á, ž apod.)" - "Stisknutím klávesy Zpět ↶ můžete klávesnici kdykoli zavřít." - "Přístup k číslům a symbolům" - "Stisknutím a podržením slova zcela vlevo toto slovo přidáte do slovníku." - "Chcete-li pokračovat, dotkněte se tohoto tipu »" - "Chcete-li tento tip zavřít a začít psát, dotkněte se zde." - "Klávesnice se otevře vždy, když se dotknete textového pole." - "Přidržením klávesy zobrazíte diakritiku"\n"(ó, ø, ö, ô apod.)" - "Chcete-li přepnout na režim zadávání číslic a symbolů, dotkněte se této klávesy." - "Chcete-li přejít zpět k zadávání písmen, dotkněte se této klávesy znovu." - "Přidržením této klávesy změníte nastavení klávesnice (např. automatické dokončování)." - "Vyzkoušejte si to." - "Přejít" - "Další" - "Hotovo" - "Odeslat" - "?123" - "123" - "ABC" - "Alt" - "Hlasový vstup" - "Pro váš jazyk aktuálně není hlasový vstup podporován, ale funguje v angličtině." - "Hlasový vstup je experimentální funkce, která využívá síťové rozpoznávání řeči společnosti Google." - "Chcete-li vypnout hlasový vstup, přejděte do nastavení klávesnice." - "Chcete-li použít hlasový vstup, stiskněte tlačítko mikrofonu nebo přejeďte prstem přes klávesnici na obrazovce." - "Mluvte" - "Probíhá zpracování" - - "Chyba. Zkuste to prosím znovu." - "Připojení se nezdařilo." - "Chyba, řeč je příliš dlouhá." - "Problém se zvukem" - "Chyba serveru" - "Nebyla detekována žádná řeč." - "Nebyly nalezeny žádné shody" - "Hlasové vyhledávání není nainstalováno" - "Nápověda:"" Chcete-li aktivovat hlasový vstup, přejeďte prstem přes klávesnici." - "Nápověda:"" Příště zkuste vyslovit interpunkci, například „tečka“, „čárka“ nebo „otazník“." - "Zrušit" - "OK" - "Hlasový vstup" - - "Na hlavní klávesnici" - "Na klávesnici se symboly" - "Vypnout" - - - "Mikrofon na hlavní klávesnici" - "Mikrofon na klávesnici se symboly" - "Hlasový vstup je deaktivován" - - "Po hlasovém vstupu automaticky odeslat" - "Při vyhledávání nebo přechodu na další pole automaticky stisknout Enter." - "Otevřete klávesnici"\n\n"Dotkněte se libovolného textového pole." - "Zavřete klávesnici"\n\n"Stiskněte tlačítko Zpět." - "Přidržením klávesy zobrazte možnosti"\n\n"Přístup k interpunkčním znaménkům a diakritice." - "Nastavení klávesnice"\n\n"Dotkněte se klávesy ""?123"" a přidržte ji." - ".com" - ".cz" - ".org" - ".net" - ".eu" - "Výběr metody zadávání dat" - "Vstupní jazyky" - "Jazyk můžete změnit posunutím prstu po mezerníku." - "← Dalším dotykem slovo uložíte" - "K dispozici je slovník" - "Aktivovat zasílání statistik užívání a zpráv o selhání" - "Automatickým zasíláním statistik o užívání editoru zadávání dat a zpráv o jeho selhání do Googlu můžete přispět k vylepšení tohoto nástroje." - "Dotykem aktivovat opravy" - "Opravy napsaných slov dotykem" - "Motiv klávesnice" - "klávesnice" - "hlas" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-cs/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-cs/strings_kp2a.xml deleted file mode 100644 index 95b5ec40..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-cs/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Vyberte další položku - Vybrat položku - Hledat položky s \"%1$s\" - Uživatel - Heslo - Nastavení vstupních metod pověření - Automatické vyplňování povoleno - Při vstupu do prázdného pole automaticky doplnit text, pokud je pro klávesnici dostupná položka v Keepass2Android a obsahuje hodnotu odpovídající nápovědě pro toto pole. - Pamatovat si nápovědy pole - Je-li pole ručně vyplněno výběrem položky z Keepass2Android, pamatovat si, která položka byla do pole zadána. Pole je později znovu rozpoznáno podle jeho nápovědy. - Jednoduchá klávesnice - Zobrazit jednoduchou jednořádkovou klávesnici, je-li položka k dispozici. Je-li klávesnice zakázána, dialogové okno se zobrazí při stisknutí klávesy Keepass2Android. - Uzamknout databázi po dokončení - Po stisknutí klávesy Hotovo/Odeslat/Dále na jednoduché jednořádkové klávesnici automaticky uzamknout databázi. - Přepnout klávesnice po dokončení - Po stisknutí klávesy Hotovo/Odeslat/Dále na jednoduché jednořádkové klávesnici přepnout klávesnici. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-da/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-da/donottranslate-altchars.xml deleted file mode 100644 index b1cc8b62..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-da/donottranslate-altchars.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - áàâąã - 3éèêëę€ - íìîï8 - óòôõ9 - úùûū7 - śšşß - ńñň - çćč - ýÿü6 - ðď - ř4 - ťþ5 - źžż - ł - w - ä - öœ - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-da/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-da/strings.xml deleted file mode 100644 index 96588ab5..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-da/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android-tastatur" - "Indstillinger for Keepass2Android-tastatur" - "Indstillinger for input" - "Vibration ved tastetryk" - "Lyd ved tastetryk" - "Popup ved tastetryk" - "Ret stavefejl" - "Aktiver fejlretning af input" - "Inputfejl i landskab" - "Aktiver fejlretning af input" - "Ordforslag" - "Ret automatisk det forrige ord" - "Ordforslag" - "Indstillinger for ordforslag" - "Aktiver automatisk udfyldelse, når du indtaster" - "Automatisk udfyldelse" - "Forøg tekstfeltets størrelse" - "Skjul ordforslag i landskabsvisning" - "Skriv aut. med stort" - "Første bogstav i en sætning skrives med stort" - "Foretag automatisk tegnsætning" - - "Hurtige løsninger" - "Retter almindelige stavefejl" - "Vis forslag" - "Vis ordforslag under indtastning" - "Udfyld automatisk" - "Mellemrumstast og tegnsætning indsætter automatisk fremhævet ord" - "Vis indstillingsnøgle" - "Automatisk" - "Vis altid" - "Skjul altid" - - - - "Bigram-forslag" - "Brug forrige ord for at forbedre forslag" - - "Ingen" - "Grundlæggende" - "Avanceret" - - "%s: Gemt" - "Hold en tast nede for at se accenter (ø, ö osv.)" - "Tryk på knappen Tilbage ↶ for når som helst at lukke for tastaturet" - "Få adgang til tal og symboler" - "Tryk og hold på ordet længst til venstre for at føje det til ordbogen" - "Berør dette tip for at fortsætte »" - "Berør her for at lukke dette tip og begynde at indtaste!" - "Tastaturet åbner når som helst, du berører et tekstfelt" - "Tryk på en tast, og hold den nede for a vise accenter"\n"(ø, ö, ô, ó osv.)" - "Skift til tal og symboler ved at røre denne tast" - "Gå tilbage til bogstaver ved at berøre denne tast igen" - "Tryk på denne tast, og hold den nede for at ændre tastaturindstillingerne, som f.eks. automatisk udfyldelse" - "Prøv det!" - "Gå" - "Næste" - "Udfør" - "Send" - "?123" - "123" - "ABC" - "ALT" - "Stemmeinput" - "Stemmeinput understøttes i øjeblikket ikke for dit sprog, men fungerer på engelsk." - "Stemme-input er en funktion på forsøgsbasis, som bruger Googles netværksstemmegenkendelse." - "Slå stemmeinput fra i indstillingerne for tastaturet." - "For at bruge stemme-input skal du trykke på knappen mikrofon eller lade glide fingeren hen over skærmtastaturet." - "Tal nu" - "Arbejder" - - "Fejl. Prøv igen." - "Kunne ikke oprette forbindelse" - "Fejl. For meget tale." - "Lydproblem" - "Serverfejl" - "Der høres ingen tale" - "Der blev ikke fundet nogen matches" - "Stemmesøgning er ikke installeret" - "Tip:"" Glid hen over tastaturet for at tale" - "Tip:"" Næste gang kan du forsøge at sige tegnsætning, f.eks. \"punktum\", \"komma\" eller \"spørgsmålstegn\"." - "Annuller" - "OK" - "Stemmeinput" - - "På hovedtastatur" - "På symboltastatur" - "Fra" - - - "Mikrofon på hovedtastatur" - "Mikrofon på symboltastatur" - "Stemmeinput er deaktiveret" - - "Send automatisk efter stemme" - "Tryk automatisk på enter, når du søger eller går til det næste felt." - "Åbn tastaturet"\n\n"Tryk på et hvilket som helst tekstfelt." - "Luk tastaturet"\n\n"Tryk på knappen Tilbage." - "Tryk på en tast, og hold den nede for valgmuligheder"\n\n"Få adgang til tegnsætning og accenter." - "Tastaturindstillinger"\n\n"Tryk på tasten ""?123"", og hold den nede." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Vælg inputmetode" - "Inputsprog" - "Træk fingeren på mellemrumstasten for at skifte sprog" - "← Tryk igen for at gemme" - "Ordbog er tilgængelig" - "Aktiver brugerfeedback" - "Vær med til at forbedre denne inputmetode ved at sende anvendelsesstatistikker og rapporter om nedbrud til Google." - "Tryk for at rette ord" - "Tryk på de indtastede ord for at rette dem" - "Tastaturtema" - "tastatur" - "stemme" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-da/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-da/strings_kp2a.xml deleted file mode 100644 index 1382d946..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-da/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Vælg en anden post - Vælg post - Søg efter post med \"%1$s\" - Bruger - Adg.kode - Indstillinger for indtastning af login-oplysninger - Autoudfylding aktiveret - Udfyld automatisk tekst, når fokus går til et tomt felt, hvis en Keepass2Android-post er tilgængeig for tastaturet og der er en værdi, som svarer til feltets tiptekst. - Gem tiptekster for felter - Gem den værdi, som blev indtastet i feltet, hvis et tekstfelt bliver udfyldt ved manuelt at vælge Keepass2Android-værdien. Tekstfeltet bliver senere genkendt via dets tiptekst. - Enkeltrækketastatur - Vis det simple enkelt-række-tastatur, hvis en post er tilgængelig for tastaturet. Hvis dette er slået fra, vil en dialogboks blive vist, når der trykkes på Keepass2Android-tasten. - Lås databasen, når du er færdig - Lås automatisk databasen, når tasten Udfør/Send/Gå trykkes på det simple enkeltrækketastatur. - Skift tastatur når du er færdig - Skift tastatur, når du trykker på tasten Udfør/Send/Gå på enkeltrækketastaturet. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-de/bools.xml b/src/java/KP2ASoftKeyboard2/java/res/values-de/bools.xml deleted file mode 100644 index 897f4b3d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-de/bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - true - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-de/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-de/donottranslate-altchars.xml deleted file mode 100644 index df27bce2..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-de/donottranslate-altchars.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - ä - 3èéêë - ìíîï8 - ö9 - ùúûü7 - §ß - ñ - ç - ýÿ - 6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-de/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-de/strings.xml deleted file mode 100644 index c09adddf..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-de/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android-Tastatur" - "Keepass2Android-Tastatureinstellungen" - "Eingabeoptionen" - "Vibrieren b. Tastendruck" - "Ton bei Tastendruck" - "Pop-up bei Tastendruck" - "Eingabefehler korrigieren" - "Korrektur von Eingabefehlern aktivieren" - "Eingabefehler im Querformat" - "Korrektur von Eingabefehlern aktivieren" - "Wortvorschläge" - "Vorheriges Wort automatisch korrigieren" - "Wortvorschläge" - "Einstellungen für Wortvorschläge" - "Automatische Vervollständigung während der Eingabe aktivieren" - "Autom. vervollständigen" - "Textfeld vergrößern" - "Wortvorschläge in Querformat ausblenden" - "Autom. Groß-/Kleinschr." - "Sätze mit Großbuchstaben beginnen" - "Autom. Zeichensetzung" - - "Quick Fixes" - "Korrigiert gängige Tippfehler" - "Vorschläge anzeigen" - "Vorgeschlagene Wörter während des Tippens anzeigen" - "Autom. vervollständigen" - "Leertaste und Interpunktion fügen autom. ein markiertes Wort ein" - "Einstellungstaste anz." - "Automatisch" - "Immer anzeigen" - "Immer ausblenden" - - - - "Bigramm-Vorschläge" - "Zur Verbesserung des Vorschlags vorheriges Wort verwenden" - - "Kein" - "Standard" - "Erweitert" - - "%s: gespeichert" - "Zur Anzeige von Umlauten (ä, ö usw.) Taste gedrückt halten" - "Zum Schließen der Tastatur ↶ drücken" - "Auf Zahlen und Symbole zugreifen" - "Lange auf das Wort ganz links außen drücken, um es zum Wörterbuch hinzuzufügen" - "Diesen Hinweis berühren, um fortzufahren »" - "Hier berühren, um diesen Hinweis zu schließen und mit dem Tippen zu beginnen!" - "Die Tastatur wird immer dann geöffnet, wenn Sie ein Textfeld berühren." - "Halten Sie eine Taste gedrückt, um Akzente anzuzeigen"\n"(ø, ö, ô, ó usw.)." - "Wechseln Sie zu Ziffern und Symbolen, indem Sie diese Taste berühren." - "Durch erneutes Drücken dieser Taste gelangen Sie zurück zu den Buchstaben." - "Halten Sie diese Taste gedrückt, um die Tastatureinstellungen, wie beispielsweise die automatische Vervollständigung, zu ändern." - "Probieren Sie es aus!" - "Los" - "Weiter" - "Fertig" - "Senden" - "?123" - "123" - "ABC" - "ALT" - "Spracheingabe" - "Spracheingaben werden derzeit nicht für Ihre Sprache unterstützt, funktionieren jedoch in Englisch." - "Die Spracheingabe ist eine Funktion im Versuchsstadium, die die vernetzte Spracherkennung von Google verwendet." - "Wenn Sie die Spracheingabe deaktivieren möchten, rufen Sie die Tastatureinstellungen auf." - "Um die Spracheingabe zu verwenden, drücken Sie die Mikrofontaste oder ziehen Sie Ihren Finger über die Bildschirmtastatur." - "Jetzt sprechen" - "Vorgang läuft" - - "Fehler. Versuchen Sie es erneut.." - "Keine Verbindung" - "Fehler – Text zu lang" - "Audio-Problem" - "Serverfehler" - "Keine Sprache zu hören" - "Keine Treffer gefunden" - "Sprachsuche nicht installiert" - "Hinweis:"" Ziehen Sie zum Sprechen den Finger über die Tastatur." - "Hinweis:"" Versuchen Sie beim nächsten Mal, Satzzeichen wie \"Punkt\", \"Komma\" oder \"Fragezeichen\" per Sprachbefehl einzugeben." - "Abbrechen" - "OK" - "Spracheingabe" - - "Auf Haupttastatur" - "Auf Symboltastatur" - "Aus" - - - "Mikrofon auf Haupttastatur" - "Mikrofon auf Symboltastatur" - "Spracheingabe ist deaktiviert" - - "Nach Sprachaufnahme automatisch senden" - "Drücken Sie auf die Eingabetaste, wenn Sie einen Suchvorgang durchführen oder zum nächsten Feld wechseln." - "Tastatur öffnen"\n\n"Berühren Sie ein beliebiges Textfeld." - "Tastatur schließen"\n\n"Drücken Sie die Zurücktaste." - "Für Optionen eine Taste berühren und gedrückt halten"\n\n"Greifen Sie auf Satzzeichen und Akzente zu." - "Tastatureinstellungen"\n\n"Berühren und halten Sie die Taste ""?123"" gedrückt." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Eingabemethode auswählen" - "Eingabesprachen" - "Finger über die Leertaste bewegen, um die Eingabesprache zu wechseln" - "← Zum Speichern erneut berühren" - "Wörterbuch verfügbar" - "Nutzer-Feedback aktivieren" - "Tragen Sie zur Verbesserung dieses Eingabemethodeneditors bei, indem Sie automatisch Nutzungsstatistiken und Absturzberichte an Google senden." - "Wortkorrektur" - "Zum Korrigieren auf eingegebene Wörter tippen" - "Tastaturdesign" - "Tastatur" - "Sprache" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-de/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-de/strings_kp2a.xml deleted file mode 100644 index 2b0f0f58..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-de/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Anderen Eintrag wählen - Eintrag wählen - Suche Eintrag mit \"%1$s\" - Benutzer - Passwort - Zugangsdaten-Eingabe-Einstellungen - Auto-Ausfüllen aktiviert - Wenn auf ein leeres Feld gedrückt wird, dieses automatisch ausfüllen falls ein Keepass2Android Eintrag verfügbar ist und ein Wert existiert, der dem Hinweistext im Feld entspricht. - Hinweistexte der Felder merken - Wenn ein Textfeld ausgefüllt wird, indem manuell ein Keepass2Android-Wert ausgewählt wird: Merken, welcher Wert ins Textfeld eingetragen wurde. Das Textfeld wird dann später an seinem Hinweistext wiedererkannt. - Einfache Tastatur - Zeige die einfache einzeilige Tastatur an, wenn ein Eintrag für die Tastatur verfügbar ist. Wenn deaktiviert, wird ein Dialog angezeigt, wenn die Keepass2Android-Taste gedrückt wird. - Datenbank sperren wenn fertig - Wenn die Fertig/Senden/Los-Taste auf der einfachen einzeiligen Tastatur gedrückt wird: Datenbank automatisch sperren. - Tastatur wechseln wenn fertig - Wenn die Fertig/Senden/Los-Taste auf der einfachen einzeiligen Tastatur gedrückt wird: Zu einer anderen Tastatur wechseln. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-el/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-el/donottranslate-altchars.xml deleted file mode 100644 index d3beafad..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-el/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àáâãäåæ - 3èéêë - ìíîï8 - òóôõöœø9 - ùúûü7 - §ß - ñ - ç - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-el/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-el/strings.xml deleted file mode 100644 index cd2a9e49..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-el/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Πληκτρολόγιο Keepass2Android" - "Ρυθμίσεις πληκτρολογίου Keepass2Android" - "Επιλογές εισόδου" - "Δόνηση κατά το πάτημα πλήκτρων" - "Ήχος κατά το πάτημα πλήκτρων" - "Εμφάνιση με το πάτημα πλήκτρου" - "Διόρθωση σφαλμάτων πληκτρολόγησης" - "Ενεργοποίηση διόρθωσης σφαλμάτων εισόδου" - "Σφάλματα οριζόντιας εισαγωγής" - "Ενεργοποίηση διόρθωσης σφαλμάτων εισόδου" - "Υποδείξεις λέξεων" - "Αυτόματη διόρθωση της προηγούμενης λέξης" - "Υποδείξεις λέξεων" - "Ρυθμίσεις υποδείξεων λέξεων" - "Ενεργοποίηση αυτόματης συμπλήρωσης κατά την πληκτρολόγηση" - "Αυτόματη συμπλήρωση" - "Αυξήστε το μέγεθος του πεδίου κειμένου" - "Απόκρυψη υποδείξεων λέξεων στην οριζόντια προβολή" - "Αυτόματη χρήση κεφαλαίων" - "Κεφαλαίο το πρώτο γράμμα της πρότασης" - "Αυτόματος τονισμός" - - "Γρήγορες διορθώσεις" - "Διορθώνει συνηθισμένα λάθη πληκτρολόγησης" - "Εμφάνιση υποδείξεων" - "Προβολή προτεινόμενων λέξεων κατά την πληκτρολόγηση" - "Αυτόματη συμπλήρωση" - "Τα πλήκ.διαστήμ.και τονισμού εισάγ.αυτόμ.την επιλ.λέξη" - "Εμφάνιση πλήκτρου ρυθμίσεων" - "Αυτόματο" - "Να εμφανίζεται πάντα" - "Πάντα απόκρυψη" - - - - "Προτάσεις bigram" - "Χρήση προηγούμενης λέξης για τη βελτίωση πρότασης" - - "Καμία" - "Βασική" - "Σύνθετη" - - "%s : Αποθηκεύτηκε" - "Κρατήστε πατημένο ένα πλήκτρο για να δείτε τους τονισμένους χαρακτήρες (ø, ö, κ.τ.λ.)" - "Πατήστε το πλήκτρο Πίσω ↶ για να κλείσετε το πληκτρολόγιο ανά πάσα στιγμή" - "Πρόσβαση σε αριθμούς και σύμβολα" - "Κρατήστε πατημένη τη λέξη στην άκρη αριστερά, για να την προσθέσετε στο λεξικό" - "Αγγίξτε αυτή τη συμβουλή για να συνεχίσετε »" - "Αγγίξτε εδώ για να κλείσετε τη συμβουλή και να ξεκινήσετε την πληκτρολόγηση!" - "Το πληκτρολόγιο ανοίγει κάθε φορά που αγγίζετε ένα πεδίο κειμένου" - "Αγγίξτε και κρατήστε κάποιο πλήκτρο για να προβάλετε τους τονισμένους χαρακτήρες"\n"(ø, ö, ô, ó κ.τ.λ.)" - "Αλλαγή σε αριθμούς και σύμβολα με το πάτημα αυτού του πλήκτρου" - "Επιστρέψτε στα γράμματα αγγίζοντας ξανά αυτό το πλήκτρο" - "Αγγίξτε και κρατήστε πατημένο αυτό το πληκτρολόγιο για να αλλάξετε τις ρυθμίσεις πληκτρολογίου, όπως η αυτόματη συμπλήρωση" - "Δοκιμάστε το!" - "Μετ." - "Επόμενο" - "Τέλος" - "Αποστολή" - "?123" - "123" - "ΑΒΓ" - "ALT" - "Φωνητική είσοδος" - "Η φωνητική είσοδος δεν υποστηρίζεται αυτή τη στιγμή για τη γλώσσα σας, ωστόσο λειτουργεί στα Αγγλικά." - "Οι φωνητικές εντολές είναι μια πειραματική λειτουργία, η οποία χρησιμοποιεί τη δικτυακή αναγνώριση ομιλίας της Google." - "Για να απενεργοποιήσετε τη φωνητική είσοδο, μεταβείτε στις ρυθμίσεις πληκτρολογίου." - "Για να χρησιμοποιήσετε τις φωνητικές εντολές, πιέστε το κουμπί μικροφώνου ή σύρετε το δάχτυλό σας κατά μήκος του πληκτρολογίου της οθόνης." - "Μιλήστε τώρα" - "Σε λειτουργία" - - "Σφάλμα. Δοκιμάστε ξανά." - "Δεν ήταν δυνατή η σύνδεση" - "Σφάλμα, πολλές λέξεις." - "Πρόβλημα ήχου" - "Σφάλμα διακομιστή" - "Δεν ακούγεται ομιλία" - "Δεν βρέθηκε καμία αντιστοίχιση" - "Η Φωνητική αναζήτηση δεν εγκαταστάθηκε" - "Υπόδειξη:"" Σύρετε κατά μήκος του πληκτρολογίου για να μιλήσετε" - "Υπόδειξη:"" Την επόμενη φορά, προσπαθήστε να προφέρετε σημεία στίξης, όπως \"τελεία\", \"κόμμα\" ή \"ερωτηματικό\"." - "Ακύρωση" - "ΟΚ" - "Φωνητική είσοδος" - - "Στο κύριο πληκτρολόγιο" - "Πληκτρολόγιο συμβόλων ενεργοποίησης" - "Απενεργοποίηση" - - - "Μικρόφωνο στο κύριο πληκτρολόγιο" - "Μικρόφωνο στο πληκτρολόγιο συμβόλων" - "Η φωνητική είσοδος είναι απενεργοποιημένη" - - "Αυτόματη υποβολή μετά από ήχο" - "Πατήστε enter αυτόματα κατά την αναζήτηση ή τη μετάβαση στο επόμενο πεδίο." - "Ανοίξτε το πληκτρολόγιο"\n\n"Αγγίξτε οποιοδήποτε πεδίο κειμένου." - "Κλείστε το πληκτρολόγιο"\n\n"Πατήστε το πλήκτρο Πίσω." - "Αγγίξτε και κρατήστε ένα πλήκτρο για ορισμό επιλογών"\n\n"Πρόσβαση στα σημεία στίξης και τονισμού." - "Ρυθμίσεις πληκτρολογίου"\n\n"Αγγίξτε και κρατήστε το πλήκτρο ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Επιλογή μεθόδου εισόδου" - "Γλώσσες εισόδου" - "Σύρετε το δάχτυλο στο πλήκτρο διαστήματος για να αλλάξετε γλώσσα" - "← Αγγίξτε ξανά για αποθήκευση" - "Λεξικό διαθέσιμο" - "Ενεργοποίηση σχολίων χρηστών" - "Βοηθήστε μας να βελτιώσουμε αυτό το πρόγραμμα επεξεργασίας μεθόδου εισόδου στέλνοντας αυτόματα στατιστικά στοιχεία και αναφορές σφαλμάτων στην Google." - "Αγγίξτε για διόρθωση λέξεων" - "Αγγίξτε τις λέξεις που εισάγετε για να τις διορθώσετε" - "Θέμα πληκτρολογίου" - "πληκτρολόγιο" - "φωνητική" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-el/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-el/strings_kp2a.xml deleted file mode 100644 index f428f208..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-el/strings_kp2a.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - Επιλέξτε μια άλλη εγγραφή - Επιλέξτε καταχώρηση - Αναζήτηση για καταχώρηση με \"%1$s\" - Χρήστης - Κωδικός Πρόσβασης - Απλό πληκτρολόγιο - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-en-rGB/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-en-rGB/strings.xml deleted file mode 100644 index 46a52e7f..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-en-rGB/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android keyboard" - "Keepass2Android keyboard settings" - "Input options" - "Vibrate on key-press" - "Sound on key-press" - "Pop-up on key press" - "Correct typing errors" - "Enable input error correction" - "Landscape input errors" - "Enable input error correction" - "Word suggestions" - "Automatically correct the previous word" - "Word suggestions" - "Word suggestion settings" - "Enable auto-completion while typing" - "Auto-completion" - "Increase text field size" - "Hide word suggestions in landscape view" - "Auto-capitalisation" - "Capitalise the start of a sentence" - "Auto-punctuate" - - "Quick fixes" - "Corrects commonly typed mistakes" - "Show suggestions" - "Display suggested words while typing" - "Auto-complete" - "Spacebar and punctuation automatically insert highlighted word" - "Show settings key" - "Automatic" - "Always show" - "Always hide" - - - - "Bigram Suggestions" - "Use previous word to improve suggestion" - - "None" - "Basic" - "Advanced" - - "%s : Saved" - "Hold a key down to see accents (ø, ö, etc.)" - "Press the back key ↶ to close the keyboard at any point" - "Access numbers and symbols" - "press and hold the left-most word to add it to the dictionary" - "Touch this hint to continue »" - "Touch here to close this hint and start typing!" - "The keyboard opens any time you touch a text field" - "Touch & hold a key to view accents"\n"(ø, ö, ô, ó and so on)" - "Switch to numbers and symbols by touching this key" - "Go back to letters by touching this key again" - "Touch & hold this key to change keyboard settings, like auto-complete" - "Try it!" - "Go" - "Next" - "Done" - "Send" - "?123" - "123" - "ABC" - "ALT" - "Voice input" - "Voice input is not currently supported for your language, but does work in English." - "Voice input is an experimental feature using Google\'s networked speech recognition." - "To turn off voice input, go to keyboard settings." - "To use voice input, press the microphone button or slide your finger across the on-screen keyboard." - "Speak now" - "Working" - - "Error: Please try again." - "Couldn\'t connect" - "Error, too much speech." - "Audio problem" - "Server error" - "No speech heard" - "No matches found" - "Voice search not installed" - "Hint:"" Swipe across keyboard to speak" - "Hint:"" Next time, try speaking punctuation marks, like \"full stop\", \"comma\" or \"question mark\"." - "Cancel" - "OK" - "Voice input" - - "On main keyboard" - "On symbols keyboard" - "Off" - - - "Mic on main keyboard" - "Mic on symbols keyboard" - "Voice input is disabled" - - "Auto-submit after voice" - "Automatically press enter when searching or going to the next field." - "Open the keyboard"\n\n"Touch any text field." - "Close the keyboard"\n\n"Press the Back key." - "Touch & hold a key for options"\n\n"Access punctuation and accents." - "Keyboard settings"\n\n"Touch & hold the ""?123"" key." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Select input method" - "Input languages" - "Slide finger on spacebar to change language" - "← Touch again to save" - "Dictionary available" - "Enable user feedback" - "Help improve this input method editor by sending usage statistics and crash reports automatically to Google." - "Touch to correct words" - "Touch words entered to correct them" - "Keyboard Theme" - "keyboard" - "voice" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-en/bools.xml b/src/java/KP2ASoftKeyboard2/java/res/values-en/bools.xml deleted file mode 100644 index 897f4b3d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-en/bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - true - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-en/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-en/donottranslate-altchars.xml deleted file mode 100644 index 083befa1..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-en/donottranslate-altchars.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - àáâãäåāæ - 3èéêëē - ìíîïī8 - òóôõöōœø9 - ùúûüū7 - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-es-rUS/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-es-rUS/donottranslate-altchars.xml deleted file mode 100644 index d3beafad..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-es-rUS/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àáâãäåæ - 3èéêë - ìíîï8 - òóôõöœø9 - ùúûü7 - §ß - ñ - ç - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-es-rUS/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-es-rUS/strings.xml deleted file mode 100644 index f4d8df02..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-es-rUS/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Teclado de Keepass2Android" - "Configuración de teclado de Keepass2Android" - "Opciones de entrada" - "Vibrar al pulsar teclas" - "Sonar al pulsar las teclas" - "Aviso emergente al pulsar tecla" - "Corregir errores de escritura" - "Habilitar corrección de error de entrada" - "Errores de entrada apaisada" - "Habilitar corrección de error de entrada" - "Sugerencias de palabras" - "Corregir automáticamente la palabra anterior" - "Sugerencias de palabras" - "Configuración de sugerencia de palabra" - "Habilitar finalización automática al escribir" - "Finalización automática" - "Aumentar el tamaño del campo de texto" - "Ocultar sugerencias de palabras en vista apaisada" - "Mayúsculas automáticas" - "Poner en mayúscula el inicio de una oración" - "Puntuación automática" - - "Arreglos rápidos" - "Corrige errores de escritura comunes" - "Mostrar sugerencias" - "Mostrar palabras sugeridas mientras escribe" - "Completar automát." - "La barra espaciadora o la puntuación insertan automáticamente la palabra resaltada." - "Mostrar tecla de configuración" - "Automático" - "Mostrar siempre" - "Ocultar siempre" - - - - "Sugerencias de Vigoran" - "Utiliza la palabra anterior para mejorar la sugerencia" - - "Ninguno" - "Básico" - "Avanzado" - - "%s: guardada" - "Mantén una tecla presionada para ver los acentos (ø, ö, etc.)" - "Pulsa la tecla hacia atrás ↶ para cerrar el teclado en cualquier momento" - "Acceder a números y símbolos" - "Presiona y mantén presionada la palabra de la izquierda para agregarla al diccionario" - "Toca esta sugerencia para continuar »" - "Toca aquí para cerrar esta sugerencia y comenzar a escribir." - "El teclado se abre cada vez que tocas un campo de texto." - "Toca y mantén presionada una tecla para ver los acentos"\n"(ø, ö, ô, ó, y así sucesivamente)." - "Cambia de números a símbolos tocando esta tecla." - "Vuelve a letras tocando esta tecla nuevamente." - "Toca y mantén presionada esta tecla para cambiar la configuración del teclado, como completar automáticamente." - "¡Pruébalo!" - "Ir" - "Siguiente" - "Hecho" - "Enviar" - "?123" - "123" - "ABC" - "ALT" - "Entrada por voz" - "La entrada por voz no está admitida en tu idioma, pero sí funciona en inglés." - "La entrada por voz es una característica experimental que utiliza la red de reconocimiento de voz de Google." - "Para desactivar la entrada por voz, ve a configuración del teclado." - "Para realizar entrada por voz, presiona el botón del micrófono o desliza tus dedos por el teclado en pantalla." - "Habla ahora" - "Procesando" - - "Error. Vuelve a intentarlo." - "No se pudo establecer la conexión." - "Error, demasiado discurso." - "Problema de audio" - "Error del servidor" - "No se oyó la voz" - "No se encontraron coincidencias" - "Búsqueda por voz no instalada" - "Sugerencia:"" Deslizar en el teclado para hablar" - "Sugerencia:"" La próxima vez intenta decir la puntuación como \"punto\", \"coma\" o \"signo de pregunta\"." - "Cancelar" - "Aceptar" - "Entrada por voz" - - "En el teclado principal" - "En el teclado de símbolos" - "Apagado" - - - "Micrófono en el teclado principal" - "Micrófono en el teclado de símbolos" - "La entrada por voz está inhabilitada." - - "Enviar automáticamente después del audio" - "Presionar automáticamente Ingresar al buscar o ir al campo siguiente." - "Abrir el teclado"\n\n"Tocar cualquier campo de texto." - "Cerrar el teclado"\n\n"Presionar la tecla Atrás." - "Tocar & y mantener presionada una tecla para las opciones"\n\n"Acceder a puntuación y acentos." - "Configuración del teclado"\n\n"Tocar & y mantener presionada la tecla ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Seleccionar método de entrada" - "Idiomas de entrada" - "Deslizarse manualmente por la barra espaciadora para cambiar el idioma" - "← Tocar de nuevo para guardar" - "Diccionario disponible" - "Habilitar los comentarios del usuario" - "Ayuda a mejorar este editor de método de introducción de texto al enviar las estadísticas de uso y los informes de error a Google." - "Tocar para corregir palabras" - "Toca las palabras ingresadas que desees corregir" - "Tema del teclado" - "Teclado" - "Voz" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-es/bools.xml b/src/java/KP2ASoftKeyboard2/java/res/values-es/bools.xml deleted file mode 100644 index 897f4b3d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-es/bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - true - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-es/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-es/donottranslate-altchars.xml deleted file mode 100644 index 721062d2..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-es/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - á - - ìíîï8 - ó9 - ùúûü7 - §ß - ñ - ç - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-es/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-es/strings.xml deleted file mode 100644 index 5479cc23..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-es/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Teclado de Keepass2Android" - "Ajustes del teclado de Keepass2Android" - "Opciones introducción texto" - "Vibrar al pulsar tecla" - "Sonido al pulsar tecla" - "Popup al pulsar tecla" - "Corregir errores de escritura" - "Habilitar la introducción de corrección de errores" - "Errores de introducción de datos en vista horizontal" - "Habilitar la introducción de corrección de errores" - "Sugerencias de palabras" - "Corregir automáticamente la palabra anterior" - "Sugerencias de palabras" - "Ajustes de sugerencia de palabras" - "Habilitar Autocompletar al escribir" - "Autocompletar" - "Aumentar el tamaño del campo de texto" - "Ocultar sugerencias de palabras en la vista horizontal" - "Mayúsculas automáticas" - "Escribir en mayúscula el principio de la frase" - "Puntuación automática" - - "Correcciones rápidas" - "Corrige los errores tipográficos que se cometen con más frecuencia." - "Mostrar sugerencias" - "Muestra las palabras sugeridas mientras se escribe." - "Autocompletar" - "La barra espaciadora y los signos de puntuación insertan automáticamente la palabra resaltada." - "Mostrar tecla de ajustes" - "Automáticamente" - "Mostrar siempre" - "Ocultar siempre" - - - - "Sugerencias de bigramas" - "Usar palabra anterior para mejorar sugerencias" - - "Ninguno" - "Básico" - "Avanzado" - - "%s: guardada" - "Mantén pulsada una tecla para ver los caracteres acentuados (ø, ö, etc.)." - "Pulsa la tecla \"Atrás\" ↶ para cerrar el teclado en cualquier momento." - "Acceso a números y símbolos" - "Mantén pulsada la palabra situada más a la izquierda para añadirla al diccionario." - "Toca esta sugerencia para continuar »" - "Toca aquí para cerrar la sugerencia y comenzar a escribir." - "El teclado se abre cada vez que tocas un campo de texto""." - "Mantén pulsada una tecla para ver los caracteres acentuados"\n"(ø, ö, ô, ó, etc.)." - "Cambiar a números y a símbolos tocando esta tecla" - "Volver a las letras tocando esta tecla de nuevo" - "Mantén pulsada esta tecla para cambiar la configuración de teclado a, por ejemplo, autocompletar""." - "¡Pruébalo!" - "Ir" - "Sig." - "Listo" - "Enviar" - "?123" - "123" - "ABC" - "ALT" - "Introducción de voz" - "Actualmente la introducción de voz no está disponible en tu idioma, pero se puede utilizar en inglés." - "La introducción de voz es una función en fase experimental que utiliza la tecnología de reconocimiento de voz en red de Google." - "Para desactivar la función de introducción de voz, accede a la configuración del teclado." - "Para utilizar la función de introducción de voz, pulsa el botón de micrófono o desliza el dedo por el teclado en pantalla." - "Habla ahora" - "En curso" - - "Se ha producido un error. Inténtalo de nuevo." - "No se ha podido establecer conexión." - "Se ha producido un error debido a un exceso de introducción de datos de voz." - "Problema de audio" - "Error del servidor" - "Ninguna conversación escuchada" - "No se ha encontrado ninguna coincidencia." - "La búsqueda por voz no está instalada." - "Sugerencia:"" muévete por el teclado para hablar." - "Sugerencia:"" la próxima vez, prueba a indicar signos de puntuación como, por ejemplo, \"punto\", \"coma\" o \"signo de interrogación\"." - "Cancelar" - "Aceptar" - "Introducción de voz" - - "En teclado principal" - "En teclado de símbolos" - "Desactivado" - - - "Micrófono en teclado principal" - "Micrófono en teclado de símbolos" - "La función de introducción de voz no está habilitada." - - "Enviar automáticamente después de la introducción de voz" - "Pulsar Intro automáticamente al buscar o al pasar al siguiente campo" - "Abrir el teclado"\n\n"Toca cualquier campo de texto." - "Cerrar el teclado"\n\n"Pulsa la tecla \"Atrás\"." - "Mantén pulsada una tecla para acceder a las opciones."\n\n"Accede a los signos de puntuación y a los acentos." - "Ajustes del teclado"\n\n"Mantén pulsada la tecla ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Seleccionar método de introducción de texto" - "Idiomas" - "Deslizar el dedo por la barra espaciadora para cambiar el idioma" - "← Volver a tocar para guardar" - "Hay un diccionario disponible." - "Habilitar comentarios de usuarios" - "Ayuda a mejorar este editor de método de introducción de texto enviando estadísticas de uso e informes de error a Google." - "Tocar para corregir palabras" - "Tocar palabras introducidas para corregirlas" - "Tema de teclado" - "teclado" - "voz" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-es/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-es/strings_kp2a.xml deleted file mode 100644 index 0cfc171d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-es/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Seleccione otra entrada - Seleccione una entrada - Buscar entrada con \"%1$s\" - Usuario - Contraseña - Configuración de credenciales - Auto completado habilitado - Completar automáticamente el campo vacío actual, si hay disponible una entrada de Keepass2Android para el teclado y hay un valor que coincide con el texto de indicio del campo. - Recordar textos de ayuda - Si un campo de texto se llena seleccionando manualmente el valor de Keepass2Android, recordar qué valor ha sido elegido para este campo. El campo de texto se vuelve a detectar en el futuro por el texto de ayuda. - Teclado simple - Mostrar el teclado simple de una fila si hay una entrada disponible para el teclado. Si está deshabilitado, se muestra un diálogo cuando se presiona la tecla Keepass2Android. - Bloquear base de datos al finalizar - Bloquea automáticamente la base de datos al presionar Hecho/Enviar/Adelante en el teclado simple de una fila. - Cambiar de teclado al finalizar - Cambiar de teclado al presionar Hecho/Enviar/Adelante en el teclado simple de una fila. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-fa/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-fa/strings.xml deleted file mode 100644 index 9bd45bb6..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-fa/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "صفحه کلید Keepass2Android" - "تنظیمات صفحه کلید Keepass2Android" - "گزینه های ورودی" - "لرزش با فشار کلید" - "صدا با فشار کلید" - "بازشو با فشار کلید" - "تصحیح خطاهای تایپی" - "فعال کردن تصحیح خطای ورودی" - "خطاهای ورود افقی" - "فعال کردن تصحیح خطای ورودی" - "پیشنهادات کلمه" - "تصحیح خودکار کلمه قبلی" - "پیشنهادات کلمه" - "تنظیمات پیشنهاد کلمه" - "فعال کردن تکمیل خودکار در حین تایپ" - "تکمیل خودکار" - "افزایش اندازه قسمت متنی" - "پنهان کردن پیشنهادات کلمه در نمای افقی" - "نوشتن با حروف بزرگ خودکار" - "بزرگ کردن اول هر جمله" - "نشان گذاری خودکار" - - "راه حل های سریع" - "تصحیح خطاهای تایپی رایج" - "نمایش پیشنهادات" - "نمایش واژه های پیشنهادی در حین تایپ" - "تکمیل خودکار" - "کلید خط فاصله و علائم نگارشی به صورت خودکار کلمه برجسته شده را وارد می کنند." - "نمایش کلید تنظیمات" - "خودکار" - "همیشه نمایش" - "همیشه پنهان" - - - - "توضیحات بیگرام" - "برای بهبود پیشنهاد از کلمه قبلی استفاده شود" - - "هیچکدام" - "پایه" - "پیشرفته" - - "%s : ذخیره شد" - "برای مشاهده علائم تکیه (ø، ö و موارد دیگر) کلیدی را پایین نگه دارید" - "برای بستن صفحه کلید در هر نقطه که بخواهید، کلید برگشت ↶ را فشار دهید" - "دسترسی به اعداد و نمادها" - "انتهای سمت چپ واژه را برای افزودن آن به فرهنگ لغت فشار داده و نگه دارید" - "این نکته را برای ادامه لمس کنید »" - "برای بستن این نکته و شروع تایپ، اینجا را لمس کنید!" - "هر زمان که قسمت متنی را لمس می کنید، صفحه کلید باز می شود" - "یک کلید را برای مشاهده تکیه های صدا لمس کرده و نگه دارید (ø، ö، ô، ó و موارد دیگر)"\n - "تغییر شماره ها و نمادها با لمس این کلید" - "با لمس مجدد این کلید، به حروف برگردید" - "این کلید را برای تغییر تنظیمات صفحه کلید مانند تکمیل خودکار لمس کرده و فشار دهید" - "امتحان کنید!" - "برو" - "بعدی" - "انجام شد" - "ارسال" - "?123" - "123" - "ABC" - "ALT" - "ورودی صوتی" - "ورودی صوتی در حال حاضر برای زبان شما پشتیبانی نمی شود اما برای زبان انگلیسی فعال است." - "ورودی صوتی یک ویژگی آزمایشی با استفاده از تشخیص گفتار شبکه Google است." - "برای خاموش کردن ورودی صدا، به تنظیمات صفحه کلید بروید." - "برای استفاده از ورودی صوتی، دکمه میکروفن را فشار دهید یا انگشت خود را روی صفحه کلید روی صفحه حرکت دهید." - "اکنون صحبت کنید" - "در حال کار" - - "خطا: لطفاً دوباره امتحان کنید." - "متصل نشد" - "خطا، گفتار بسیار زیاد است." - "مشکل صوتی" - "خطای سرور" - "گفتاری شنیده نشد" - "مورد منطبقی یافت نشد" - "جستجوی صوتی نصب نشده است" - "نکته: "" برای صحبت روی صفحه کلید ضربه بزنید" - "نکته: دفعه دیگر، از نشانه گذاری های گفتاری مانند \"نقطه\"، \"کاما\" یا \"علامت سؤال\" استفاده کنید." - "لغو" - "تأیید" - "ورودی صوتی" - - "در صفحه کلید اصلی" - "در صفحه کلید نمادها" - "خاموش" - - - "میکروفن در صفحه کلید اصلی" - "میکروفن در صفحه کلید نمادها" - "ورودی صوتی غیر فعال شده است" - - "ارائه خودکار بعد از صدا" - "هنگام جستجو یا رفتن به قسمت بعدی، Enter را به صورت خودکار فشار دهید." - "صفحه کلید را باز کنید"\n\n"هر قسمت متنی را لمس کنید." - "بستن صفحه کلید"\n\n"کلید برگشت را فشار دهید." - "یک کلید را برای گزینه های"\n\n" دسترسی به علائم نگارشی و تکیه های صدا لمس کرده و نگه دارید." - "تنظیمات صفحه کلید"\n\n"کلید ""?123"" را لمس کرده و نگهدارید." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "انتخاب روش ورودی" - "زبان های ورودی" - "برای تغییر زبان انگشت را روی کلید فاصله بلغزانید" - "← جهت ذخیره دوباره لمس کنید" - "دیکشنری موجود است" - "فعال کردن بازخورد کاربر" - "با ارسال خودکار آمارهای کاربرد و گزارش های خرابی به Google، به بهبود این ویرایشگر روش ورودی کمک کنید." - "برای تصحیح کلمات لمس کنید" - "برای تصحیح کلمات وارد شده آنها را لمس کنید" - "طرح زمینه صفحه کلید" - "صفحه کلید" - "صوتی" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-fi/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-fi/strings.xml deleted file mode 100644 index 8c316852..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-fi/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android-näppäimistö" - "Keepass2Android-näppäimistön asetukset" - "Syöttövalinnat" - "Käytä värinää näppäimiä painettaessa" - "Toista ääni näppäimiä painettaessa" - "Ponnahdusikkuna painalluksella" - "Korjaa kirjoitusvirheet" - "Ota syöttövirheen korjaus käyttöön" - "Vaakasuunnan syöttövirheet" - "Ota syöttövirheen korjaus käyttöön" - "Sanaehdotukset" - "Korjaa edellinen sana automaattisesti" - "Sanaehdotukset" - "Sanaehdotusasetukset" - "Ota automaattinen täydennys käyttöön kirjoitettaessa" - "Automaattinen täydennys" - "Suurenna tekstikenttää" - "Piilota sanaehdotukset vaakasuuntaisessa näkymässä" - "Automaattiset isot kirjaimet" - "Aloittaa lauseet isolla kirjaimella" - "Automaattiset välimerkit" - - "Pikakorjaukset" - "Korjaa yleiset kirjoitusvirheet" - "Näytä ehdotukset" - "Näytä sanaehdotukset kirjoitettaessa" - "Automaattinen täydennys" - "Välilyönti ja välimerkki lisäävät automaattisesti korostetun sanan" - "Näytä asetukset-näppäin" - "Automaattinen" - "Näytä aina" - "Piilota aina" - - - - "Bigram-ehdotukset" - "Paranna ehdotusta aiemman sanan avulla" - - "Ei mitään" - "Tavallinen" - "Edistynyt" - - "%s : Tallennettu" - "Näet aksenttimerkit (ø, ö jne.) pitämällä näppäintä painettuna." - "Voit sulkea näppäimistön milloin tahansa painamalla Takaisin-painiketta ↶" - "Käytä numeroita ja symboleita" - "Lisää vasemmanpuoleinen sana sanakirjaan pitämällä sitä painettuna" - "Jatka koskettamalla tätä vihjettä »" - "Sulje tämä vihje ja aloita kirjoittaa koskettamalla tätä!" - "Näppäimistö avautuu, kun kosketat tekstikenttää" - "Näytä aksenttimerkit pitämällä näppäintä painettuna"\n"(ø, ö, ô, ó ja niin edelleen" - "Vaihda numeroihin ja symboleihin koskettamalla tätä näppäintä" - "Siirry takaisin kirjaimiin koskettamalla tätä näppäintä uudelleen" - "Muuta näppäimistön asetuksia, kuten automaattista täydentämistä, pitämällä tätä näppäintä painettuna" - "Kokeile!" - "Siirry" - "Seuraava" - "Valmis" - "Lähetä" - "?123" - "123" - "ABC" - "ALT" - "Äänisyöte" - "Äänisyötettä ei vielä tueta kielelläsi, mutta voit käyttää sitä englanniksi." - "Äänisyöte on kokeellinen Googlen puheentunnistusta käyttävä ominaisuus." - "Siirry näppäimistön asetuksiin poistaaksesi äänisyötteen käytöstä." - "Käytä äänisyötettä painamalla mikrofonipainiketta tai liu\'uttamalla sormeasi näytön näppäimistön poikki." - "Puhu nyt" - "Työstetään" - - "Virhe. Yritä uudelleen." - "Ei yhteyttä" - "Virhe, liikaa puhetta." - "Ääniongelma" - "Palvelinvirhe" - "Puhetta ei kuulu" - "Ei vastineita" - "Äänihakua ei asennettu" - "Vihje:"" liu\'uta sormea näppäimistöllä ja puhu" - "Vihje:"" kokeile seuraavalla kerralla puhua välimerkit, kuten \"period\" (piste), \"comma\" (pilkku) tai \"question mark\" (kysymysmerkki)." - "Peruuta" - "OK" - "Äänisyöte" - - "Päänäppäimistössä" - "Symbolinäppäimistössä" - "Pois käytöstä" - - - "Päänäppäimistön mikrofoni" - "Symbolinäppäimistön mikrofoni" - "Äänisyöte ei ole käytössä" - - "Lähetä automaattisesti puheen jälkeen" - "Paina automaattisesti enter-näppäintä tehdessäsi hakuja tai siirtyessäsi seuraavaan kenttään." - "Avaa näppäimistö"\n\n"Kosketa tekstikenttää." - "Sulje näppäimistö"\n\n"Paina Takaisin-näppäintä." - "Näet asetukset pitämällä näppäintä painettuna"\n\n"Käytä välimerkkejä ja aksenttimerkkejä." - "Näppäimistön asetukset"\n\n"Pidä painettuna""?123""-näppäintä." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Valitse syöttötapa" - "Syöttökielet" - "Vaihda kieltä liu\'uttamalla sormea välilyöntinäppäimellä" - "← Tallenna koskettamalla uudelleen" - "Sanakirja saatavilla" - "Ota käyttäjäpalaute käyttöön" - "Auta parantamaan tätä syöttötavan muokkausohjelmaa lähettämällä automaattisesti käyttötietoja ja kaatumisraportteja Googlelle." - "Korjaa sanoja koskettamalla" - "Korjaa sanoja koskettamalla niitä" - "Näppäimistön teema" - "näppäimistö" - "ääni" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-fi/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-fi/strings_kp2a.xml deleted file mode 100644 index 7fe2faf7..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-fi/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Valitse toinen merkintä - Valitse merkintä - Etsi merkintä \"%1$s\" - Käyttäjä - Salasana - Tietojen syötön asetukset - Automaattinen täyttö - Täytä kenttä automaattisesti kun se havaitaan tyhjänä. Jos merkintä on saatavana Keepass2Android näppäimistölle ja kentän vihjearvo löytyy. - Muista kenttien vihjeet - Jos tekstikenttä täytetään manuaalisesti valitsemalla Keepass2Androidin tarjoama arvo, muista mikä arvo kenttään syötettiin. Kenttä tunnistetaan uudelleen myöhemmin vihjetekstin perusteella. - 1-rivinen näppäimistö - Näytä 1-rivinen näppäimistö jos merkintä on saatavilla. Jos asetus ei ole käytössä, näytetään valintaruutu Keepass2Android näppäimistön kuvaketta painettaessa. - Lukitse tietokanta kun on valmis - Lukitse tietokanta automaattisesti kun painetaan yksinkertaisen 1-rivisen näppäimistön Valmis/Lähetä/Mene näppäintä. - Näppäimistön vaihto - Vaihda näppäimistö kun painetaan yksinkertaisen 1-rivisen näppäimistön Valmis/Lähetä/Siirry näppäintä. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-fr-rCA/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-fr-rCA/strings.xml deleted file mode 100644 index d53274a1..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-fr-rCA/strings.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - "Clavier Keepass2Android" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-fr/bools.xml b/src/java/KP2ASoftKeyboard2/java/res/values-fr/bools.xml deleted file mode 100644 index 897f4b3d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-fr/bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - true - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-fr/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-fr/donottranslate-altchars.xml deleted file mode 100644 index 874d89da..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-fr/donottranslate-altchars.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - 1àáâãäåæ - 3èéêë - ìíîï8 - òóôõöœø9 - ùúûü7 - §ß - ñ - ç - ýÿ6 - - - 2 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-fr/donottranslate.xml b/src/java/KP2ASoftKeyboard2/java/res/values-fr/donottranslate.xml deleted file mode 100644 index b79df7b3..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-fr/donottranslate.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - .\u0009\u0020,;:!?\'\n()[]*&@{}/<>_+=|\u0022 - - ., - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-fr/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-fr/strings.xml deleted file mode 100644 index f2458275..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-fr/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Clavier Keepass2Android" - "Paramètres du clavier Keepass2Android" - "Options de saisie" - "Vibrer à chaque touche" - "Son à chaque touche" - "Agrandir les caractères" - "Corriger les fautes de frappe" - "Activer la correction des erreurs de saisie" - "Erreurs de saisie en mode paysage" - "Activer la correction des erreurs de saisie" - "Saisie prédictive" - "Corriger automatiquement le mot précédent" - "Saisie prédictive" - "Paramètres de la saisie prédictive" - "Activer la saisie semi-automatique" - "Saisie semi-automatique" - "Agrandir le champ de texte" - "Masquer la saisie prédictive en mode paysage" - "Majuscules auto" - "Mettre en majuscule la première lettre de chaque phrase" - "Ponctuation automatique" - - "Corrections rapides" - "Corrige les fautes de frappe courantes" - "Afficher les suggestions" - "Afficher les suggestions de terme lors de la saisie" - "Saisie semi-automatique" - "Insérer autom. terme surligné (pression sur barre espace/ponctuation)" - "Afficher touche param." - "Automatique" - "Toujours afficher" - "Toujours masquer" - - - - "Suggestions de type bigramme" - "Améliorer la suggestion en fonction du mot précédent" - - "Aucun" - "Simple" - "Avancé" - - "%s : enregistré" - "Maintenir une touche enfoncée pour afficher les accents (à, é, etc.)" - "Appuyez sur la touche Retour ↶ pour fermer le clavier à tout moment." - "Accéder aux chiffres et symboles" - "Appuyer et maintenir le doigt sur le mot le plus à gauche pour l\'ajouter au dictionnaire" - "Touchez ce conseil pour continuer »" - "Touchez ici pour fermer ce conseil et commencer à saisir votre texte." - "Le clavier s\'affiche à chaque fois que vous touchez une zone de texte." - "Maintenez une touche enfoncée pour afficher les accents"\n"(ø, ö, ô, ó, etc.)""." - "Appuyez sur cette touche pour basculer vers les chiffres et les symboles." - "Appuyez de nouveau sur cette touche pour retourner aux lettres." - "Maintenez cette touche enfoncée afin de modifier les paramètres du clavier, tels que la saisie semi-automatique." - "Essayez !" - "OK" - "Suivant" - "OK" - "Envoyer" - "?123" - "123" - "ABC" - "ALT" - "Saisie vocale" - "La saisie vocale n\'est pas encore prise en charge pour votre langue, mais elle fonctionne en anglais." - "La saisie vocale est une fonctionnalité expérimentale qui fait appel à la reconnaissance vocale en réseau de Google." - "Pour désactiver la saisie vocale, accédez aux paramètres du clavier." - "Pour utiliser la saisie vocale, appuyez sur la touche du microphone ou faites glisser votre doigt sur le clavier à l\'écran." - "Parlez maintenant" - "Traitement en cours" - - "Erreur. Veuillez réessayer." - "Connexion impossible" - "Erreur, discours trop long." - "Problème audio" - "Erreur serveur" - "Aucune requête vocale détectée" - "Aucune correspondance n\'a été trouvée." - "Recherche vocale non installée" - "Astuce :"" Faites glisser votre doigt sur le clavier pour parler." - "Astuce :"" La prochaine fois, essayez de prononcer la ponctuation, en énonçant des termes tels que \"point\", \"virgule\" ou \"point d\'interrogation\"." - "Annuler" - "OK" - "Saisie vocale" - - "Sur le clavier principal" - "Sur le clavier des symboles" - "Désactivée" - - - "Micro sur le clavier principal" - "Micro sur le clavier des symboles" - "Saisie vocale désactivée" - - "Envoi automatique après la saisie vocale" - "Appuyez automatiquement sur Entrée pour effectuer une recherche ou accéder au champ suivant." - "Ouvrir le clavier"\n\n"Appuyez sur un champ de texte." - "Fermer le clavier"\n\n"Appuyez sur la touche Retour." - "Appuyez sur une touche de manière prolongée pour accéder aux options"\n\n"Accédez aux signes de ponctuation et aux accents." - "Paramètres du clavier"\n\n"Appuyez sur la touche ""?123"" de manière prolongée." - ".com" - ".net" - ".org" - ".gouv" - ".edu" - "Sélectionner un mode de saisie." - "Langues de saisie" - "Faites glisser votre doigt sur la barre d\'espacement pour changer la langue." - "← Appuyer de nouveau pour enregistrer" - "Dictionnaire disponible" - "Autoriser les commentaires des utilisateurs" - "Contribuer à l\'amélioration de cet éditeur du mode de saisie grâce à l\'envoi automatique de statistiques d\'utilisation et de rapports d\'incident à Google." - "Appuyer pour corriger" - "Appuyer sur les mots saisis pour les corriger" - "Thème du clavier" - "clavier" - "voix" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-fr/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-fr/strings_kp2a.xml deleted file mode 100644 index 868b991a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-fr/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Choisir une autre entrée - Choisir une entrée - Rechercher une entrée avec \"%1$s\" - Utilisateur - Mot de passe - Paramètres d\'entrée des identifiants - Remplissage automatique activé - Renseigner automatiquement le texte lorsqu\'un champ vide est saisi, si une entrée Keepass2Android est disponible pour le clavier et qu\'il y a un champ qui correspond au texte d\'indication du champ. - Rappeler le texte du champ d\'information - Si un champ est rempli en sélectionnant manuellement le champ de Keepass2Android, n\'oubliez pas le champ qui a été entré dans le champ. Le champ est à nouveau détecté plus tard grâce à son texte d\'indication. - Clavier simple - Afficher le clavier simple 1-ligne si une entrée est disponible pour le clavier. Si désactivé, une boîte de dialogue apparaît lorsque vous appuyez sur la touche Keepass2Android. - Verrouiller la base de données lorsque terminé - Lorsque vous appuyez sur la touche Terminé/Envoyé/Go sur le clavier simple 1-ligne, verrouille automatiquement la base de données. - Changer de clavier lorsque terminé - Lorsque vous appuyez sur la touche Terminé/Envoyé/Go sur le clavier simple 1-ligne, changer le clavier. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-hr/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-hr/strings.xml deleted file mode 100644 index 834318b0..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-hr/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android tipkovnica" - "Postavke tipkovnice za Keepass2Android" - "Opcije ulaza" - "Vibracija pri pritisku na tipku" - "Zvuk pri pritisku tipke" - "Povećanja na pritisak tipke" - "Ispravi pogreške u pisanju" - "Omogućavanje ispravka pogreške pri unosu" - "Pogreške pri pejzažnom unosu" - "Omogućavanje ispravka pogreške pri unosu" - "Prijedlozi riječi" - "Automatsko ispravljanje prethodne riječi" - "Prijedlozi riječi" - "Postavke prijedloga riječi" - "Omogućavanje automatskog dovršavanja pri upisivanju" - "Automatsko dovršavanje" - "Povećaj tekstualno polje" - "Sakrij prijedloge riječi u pejzažnom prikazu" - "Automatsko pisanje velikih slova" - "Stavi veliko slovo na početku rečenice" - "Automatsko stavljanje interpunkcije" - - "Brzi popravci" - "Ispravlja uobičajene pogreške u pisanju" - "Pokaži prijedloge" - "Prikazivanje predloženih riječi prilikom upisivanja" - "Automatsko dovršavanje" - "Razmaknica i interpunkcija automatski umeću istaknutu riječ" - "Prikaži tipku postavki" - "Automatski" - "Uvijek prikaži" - "Uvijek sakrij" - - - - "Bigram prijedlozi" - "Upotrijebi prethodnu riječ radi poboljšanja prijedloga" - - "Nijedan" - "Osnovni" - "Napredno" - - "%s : Spremljeno" - "Pritisnite i držite tipku da biste vidjeli naglaske (ø, ö itd.)" - "Pritisnite tipku \"Natrag\" ↶ za zatvaranje tipkovnice" - "Pristup brojevima i simbolima" - "Pritisnite i držite krajnju lijevu riječ da biste je dodali u rječnik." - "Dodirnite ovaj savjet za nastavak »" - "Dodirnite ovdje da biste zatvorili savjet i počeli upisivati!" - "Tipkovnica se otvara svaki put kada dodirnete tekstualno polje" - "Dodirnite i držite tipku da biste vidjeli naglaske"\n"(ø, ö, ô, ó i tako dalje)" - "Prijeđite na brojeve i simbole dodirom na ovu tipku" - "Dodirnite ponovo ovu tipku za povratak na slova" - "Dodirnite i držite ovu tipku da biste promijenili postavke tipkovnice, poput automatskog dovršavanja" - "Isprobajte!" - "Idi" - "Dalje" - "Gotovo" - "Pošalji" - "?123" - "123" - "ABC" - "ALT" - "Glasovni ulaz" - "Vaš jezik trenutno nije podržan za glasovni unos, ali radi za engleski." - "Glasovni unos je pokusna značajka koja koristi Googleovo umreženo prepoznavanje govora." - "Za isključivanje glasovnog unosa idite na postavke tipkovnice." - "Da biste koristili glasovni unos pritisnite gumb mikrofona ili kliznite prstom preko tipkovnice na zaslonu." - "Govorite sad" - "Obrada" - - "Pogreška. Pokušajte ponovo." - "Spajanje nije bilo moguće" - "Pogreška, predugi govor." - "Problem sa zvukom" - "Pogreška na poslužitelju" - "Nije se čuo govor" - "Nisu pronađeni rezultati" - "Glasovno pretraživanje nije instalirano" - "Savjet:"" Prijeđite preko tipkovnice pa govorite" - "Savjet:"" Sljedeći put pokušajte izgovoriti znakove interpunkcije poput \"točka, \"zarez\" ili \"upitnik\"." - "Odustani" - "U redu" - "Glasovni ulaz" - - "Na glavnoj tipkovnici" - "Na tipkovnici sa simbolima" - "Isključeno" - - - "Mikrofon na glavnoj tipkovnici" - "Mikrofon na tipkovnici sa simbolima" - "Glasovni unos je onemogućen" - - "Automatski pošalji nakon glasovnog unosa" - "Automatski se pritišće \"Enter\" kad pretražujete ili idete na sljedeće polje." - "Otvaranje tipkovnice"\n\n"Dodirnite bilo koje tekstualno polje" - "Zatvaranje tipkovnice"\n\n"Pritisnite tipku \"Natrag\"." - "Dodirnite i držite tipku da biste vidjeli opcije"\n\n"Pristup interpunkciji i naglascima." - "Postavke tipkovnice"\n\n"Dodirnite i držite tipku ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Odabir ulazne metode" - "Jezici unosa" - "Kliznite prstom po razmaknici za promjenu jezika" - "← Dodirnite opet za spremanje" - "Rječnik je dostupan" - "Omogući korisničke povratne informacije" - "Pomozite u poboljšanju ovog urednika ulazne metode automatskim slanjem statistike upotrebe i padova Googleu." - "Dodirnite za ispravak riječi" - "Dodirnite unesene riječi radi ispravka" - "Tema tipkovnice" - "tipkovnica" - "glas" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-hu/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-hu/strings.xml deleted file mode 100644 index 1c261fd5..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-hu/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android-billentyűzet" - "Keepass2Android billentyűzetbeállítások" - "Beviteli beállítások" - "Rezgés billentyű megnyomása esetén" - "Hangjelzés billentyű megnyomása esetén" - "Legyen nagyobb billentyű lenyomásakor" - "Gépelési hibák kijavítása" - "Beviteli hibák javításának engedélyezése" - "Fekvő beviteli hibák" - "Beviteli hibák javításának engedélyezése" - "Szójavaslatok" - "Az előző szó automatikus kijavítása" - "Szójavaslatok" - "Szójavaslati beállítások" - "Automatikus kiegészítés engedélyezése gépelés közben" - "Automatikus kiegészítés" - "A szövegmező méretének növelése" - "Szójavaslatok elrejtése fekvő nézetben" - "Automatikusan nagy kezdőbetű" - "Nagybetűvel kezdi a mondatot" - "Automatikus központozás" - - "Gyorsjavítások" - "Kijavítja a gyakori gépelési hibákat" - "Javaslatok megjelenítése" - "A javasolt szavak megjelenítése gépelés közben" - "Automatikus kiegészítés" - "A szóköz és az írásjelek használata automatikusan beszúrja a kiemelt szót" - "Beállítások billentyű megjelenítése" - "Automatikus" - "Mindig látszik" - "Mindig rejtve" - - - - "Bigram javaslatok" - "Előző szó használata a javaslatok javításához" - - "Nincs" - "Alap" - "Speciális" - - "%s : mentve" - "Az ékezetes betűk megtekintéséhez tartsa lenyomva valamelyik billentyűt (ø, ö stb.)" - "A vissza gomb ↶ megnyomásával bármikor elrejtheti a billentyűzetet" - "Számok és szimbólumok elérése" - "A szótárhoz történő hozzáadásához nyomja meg hosszan a bal oldali legszélső szót" - "A folytatáshoz érintse meg ezt a tippet »" - "Érintse meg itt a tipp bezárásához és a gépelés megkezdéséhez." - "Szövegmező megérintésekor a billentyűzet mindig megjelenik" - "Érintse meg és tartsa lenyomva valamelyik billentyűt az ékezetes betűk megtekintéséhez"\n"(ø, ö, ô, ó stb.)" - "Számokra és szimbólumokra ennek a billentyűnek a megérintésével válthat" - "A billentyű újbóli megérintésével visszatérhet a betűkhöz" - "Érintse meg és tartsa lenyomva ezt a billentyűt a billentyűzet-beállítások (pl. az automatikus kiegészítés) módosításához" - "Próbálja ki!" - "Ugrás" - "Tovább" - "Kész" - "Küldés" - "?123" - "123" - "ABC" - "ALT" - "Hangbevitel" - "A hangbevitel szolgáltatás jelenleg nem támogatja az Ön nyelvét, ám angolul működik." - "A hangbevitel a Google hálózati beszédfelismerését alkalmazó kísérleti funkció." - "A hangbevitelt a billentyűzet beállításai között lehet kikapcsolni." - "A hangbevitel használatához nyomja meg a mikrofon gombját vagy húzza végig az ujját a képernyő-billentyűzeten." - "Most beszéljen" - "Feldolgozás" - - "Hiba történt. Kérjük, próbálja újra." - "Nem sikerült kapcsolódni" - "Hiba történt; túl sokat beszélt." - "Hangprobléma" - "Szerverhiba" - "Nem hallatszott beszéd" - "Nem található egyezés" - "A hangalapú keresés nincs telepítve" - "Tipp:"" húzza végig az ujját a billentyűzeten a beszédhez" - "Tipp:"" következő alkalommal próbálja ki az írásjelek kimondását is, pl. \"period\", \"comma\" vagy \"question mark\"." - "Mégse" - "OK" - "Hangbevitel" - - "Főbillentyűzeten" - "Szimbólumbillentyűzeten" - "Ki" - - - "Mikrofon a főbillentyűzeten" - "Mikrofon a szimbólumbillentyűzeten" - "A hangbevitel ki van kapcsolva" - - "Automatikus küldés a beszéd után" - "Az Enter automatikus megnyomása keresés vagy a következő mezőre ugrás során." - "A billentyűzet megjelenítése"\n\n"Érintse meg valamelyik szövegmezőt." - "A billentyűzet bezárása"\n\n"Nyomja meg a Vissza billentyűt." - "A lehetőségek megjelenítéséhez érintse meg és tartsa lenyomva valamelyik billentyűt"\n\n"Az írásjelek és az ékezetes betűk elérése." - "Billentyűzetbeállítások"\n\n"Érintse meg és tartsa lenyomva a ""?123"" billentyűt." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Beviteli mód kiválasztása" - "Beviteli nyelvek" - "A nyelv módosításához húzza végig az ujját a szóköz billentyűn" - "← Érintse meg újra a mentéshez" - "Van elérhető szótár" - "Felhasználói visszajelzés engedélyezése" - "Segíthet ennek a beviteli módszernek a javításában, ha engedélyezi a használati statisztikák és a hibajelentések elküldését a Google-nak." - "Javítás a szavak megérintésével" - "A beírt szavakat megérintve kijavíthatja őket" - "Billentyűzettéma" - "billentyűzet" - "hang" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-hu/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-hu/strings_kp2a.xml deleted file mode 100644 index a7b171b3..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-hu/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Válasszon egy másik bejegyzést - Válasszon bejegyzést - Bejegyzés keresése: \"%1$s\" - Felhasználó - Jelszó - Hitelesítő adatok bevitele - Automatikus kitöltés engedélyezve - Egy üres mezőbe lépve annak automatikus kitöltése, ha a billentyűzet számára van elérhető Keepass2Android bejegyzés és az tartalmaz a mezőhöz megadott útmutatásnak megfelelő értéket. - A mezők útmutatásának tárolása - Ha egy mezőt egy Keepass2Android érték manuális kiválasztásával tölt ki, rendelődjön hozzá a Keepass2Android értékhez a mezőhöz megadott útmutatás, hogy legközelebb ennek alapján a mezőt automatikusan ki lehessen tölteni. - Egyszerű billentyűzet - Az egyszerű egysoros billentyűzet használata, ha a billentyűzet számára van elérhető Keepass2Android bejegyzés. Ha le van tiltva, egy párbeszédpanel jelenik meg a Keepass2Android billentyű megnyomásakor. - Adatbázis lezárása, ha kész - Az egysoros billentyűzet Kész/Küldés/Ugrás gombjának megnyomásakor az adatbázis automatikus zárolása. - Billentyűzetváltás, ha kész - Az egysoros billentyűzet Kész/Küldés/Ugrás gombjának megnyomásakor automatikus billentyűzet-váltás. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-in/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-in/strings.xml deleted file mode 100644 index fbc22ac6..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-in/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keyboard Keepass2Android" - "Setelan Keepass2Android Android" - "Opsi masukan" - "Getar jika tombol ditekan" - "Berbunyi jika tombol ditekan" - "Muncul saat tombol ditekan" - "Perbaiki kesalahan ketik" - "Aktifkan perbaikan galat masukan" - "Galat masukan lanskap" - "Aktifkan perbaikan galat masukan" - "Saran kata" - "Perbaiki kata sebelumnya secara otomatis" - "Saran kata" - "Setelan saran kata" - "Aktifkan pengisian otomatis saat mengetik" - "Pengisian otomatis" - "Tambah ukuran bidang teks" - "Sembunyikan saran kata dalam tampilan melintang" - "Kapitalisasi otomatis" - "Kapitalisasi awal kalimat" - "Beri tanda baca otomatis" - - "Perbaikan cepat" - "Memperbaiki kesalahan ketik umum" - "Perlihatkan saran" - "Tampilkan kata yang disarankan ketika mengetik" - "Pengisian otomatis" - "Bilah spasi dan tanda baca secara otomatis memasukkan kata yang disorot" - "Lihat tombol setelan" - "Otomatis" - "Selalu tampilkan" - "Selalu sembunyikan" - - - - "Saran Bigram" - "Gunakan kata sebelumnya untuk meningkatkan sara" - - "Tak Satu Pun" - "Dasar" - "Lanjutan" - - "%s : Telah disimpan" - "Tahan tombol untuk melihat aksen (ø, ö, dll.)" - "Tekan tombol kembali ↶ untuk menutup keyboard kapan saja" - "Akses angka dan simbol" - "Tekan terus kata yang paling kiri untuk menambahkannya ke kamus" - "Sentuh petunjuk ini untuk melanjutkan »" - "Sentuh di sini untuk menutup petunjuk dan mulailah mengetik!" - "Keyboard terbuka setiap kali Anda menyentuh bidang teks" - "Sentuh & tahan tombol untuk melihat aksen"\n"(ø, ö, ô, ó, dan seterusnya)" - "Beralih ke angka dan simbol dengan menekan tombol ini" - "Kembali ke huruf dengan menekan tombol ini lagi" - "Sentuh & tahan tombol ini untuk mengubah setelan keyboard, seperti lengkapi otomatis" - "Cobalah!" - "Buka" - "Berikutnya" - "Selesai" - "Kirimkan" - "?123" - "123" - "ABC" - "ALT" - "Masukan suara" - "Masukan suara saat ini tidak didukung untuk bahasa Anda, tetapi bekerja dalam Bahasa Inggris." - "Masukan suara adalah fitur eksperimental yang menggunakan pengenal suara berjaringan Google." - "Untuk mematikan masukan suara, buka setelan keyboard." - "Untuk menggunakan masukan suara, tekan tombol mikrofon atau geser jari Anda di sepanjang keyboard pada layar." - "Ucapkan sekarang" - "Bekerja" - - "Galat: Coba lagi." - "Tidak dapat menyambung" - "Galat, terlalu banyak ucapan." - "Masalah audio" - "Galat server" - "Tidak terdengar ucapan" - "Tak ditemukan yang cocok" - "Penelusuran suara tidak terpasang" - "Petunjuk:"" Gesek keyboard untuk berbicara" - "Petunjuk:"" Selanjutnya, coba ucapkan tanda baca seperti \"titik\", \"koma\", atau \"tanda tanya\"." - "Batal" - "OK" - "Masukan suara" - - "Di keyboard utama" - "Di keyboard simbol" - "Mati" - - - "Mik di keyboard utama" - "Mik di keyboard simbol" - "Masukan suara dinonaktifkan" - - "Kirim otomatis setelah suara" - "Tekan enter secara otomatis saat menelusuri atau menuju ke bidang berikutnya." - "Buka keyboard"\n\n"Sentuh bidang teks mana pun." - "Tutup keyboard"\n\n"Tekan tombol Kembali." - "Sentuh & tahan tombol tertentu untuk opsi"\n\n"Akses tanda baca dan aksen." - "Setelan keyboard"\n\n"Sentuh & tahan tombol ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Pilih metode masukan" - "Bahasa masukan" - "Geser jari pada bilah spasi untuk mengubah bahasa" - "← Sentuh sekali lagi untuk menyimpan" - "Kamus yang tersedia" - "Aktifkan umpan balik pengguna" - "Bantu tingkatkan metode editor masukan dengan mengirim statistik penggunaan dan laporan kerusakan ke Google secara otomatis." - "Sentuh untuk memperbaiki kata" - "Sentuh kata yang dimasukkan untuk memperbaikinya" - "Tema Keyboard" - "keyboard" - "suara" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-in/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-in/strings_kp2a.xml deleted file mode 100644 index 345f4413..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-in/strings_kp2a.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - Pilih entri lain - Pilih entri - Mencari entri dengan \"%1$s\" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-it/bools.xml b/src/java/KP2ASoftKeyboard2/java/res/values-it/bools.xml deleted file mode 100644 index 897f4b3d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-it/bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - true - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-it/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-it/donottranslate-altchars.xml deleted file mode 100644 index 23960171..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-it/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àá - 3èé - ìíîï8 - òó9 - ùúûü7 - § - ñ - ç - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-it/donottranslate.xml b/src/java/KP2ASoftKeyboard2/java/res/values-it/donottranslate.xml deleted file mode 100644 index 3e3f3ef2..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-it/donottranslate.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - .\u0009\u0020,;:!?\'\n()[]*&@{}/<>_+=|\u0022 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-it/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-it/strings.xml deleted file mode 100644 index 7cb43892..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-it/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Tastiera Keepass2Android" - "Impostazioni tastiera Keepass2Android" - "Opzioni inserimento" - "Vibrazione tasti" - "Suono tasti" - "Popup sui tasti" - "Correggi errori di digitazione" - "Attiva la correzione degli errori di inserimento" - "Errori di inserimento in visualizzazione orizzontale" - "Attiva la correzione degli errori di inserimento" - "Suggerimenti parola" - "Correggi automaticamente la parola precedente" - "Suggerimenti parola" - "Impostazioni suggerimento parole" - "Attiva il completamento automatico durante la digitazione" - "Completamento automatico" - "Aumenta dimensioni campo di testo" - "Nascondi i suggerimenti delle parole in visualizzazione orizzontale" - "Maiuscole automatiche" - "Rendi maiuscole le iniziali delle frasi" - "Punteggiatura automat." - - "Correzioni veloci" - "Corregge gli errori di digitazione più comuni" - "Mostra suggerimenti" - "Visualizza le parole suggerite durante la digitazione" - "Completamento autom." - "Barra spaziatrice e punteggiatura inseriscono la parola evidenziata" - "Mostra tasto impostaz." - "Automatico" - "Mostra sempre" - "Nascondi sempre" - - - - "Suggerimenti sui bigrammi" - "Utilizza parola precedente per migliorare il suggerimento" - - "Nessuna" - "Base" - "Avanzate" - - "%s : parola salvata" - "Tieni premuto un tasto per vedere le lettere con segni diacritici (ø, ö etc.)" - "Premi il tasto Indietro ↶ per chiudere la tastiera" - "Accedi a numeri e simboli" - "Tieni premuto sulla parola all\'estrema sinistra per aggiungerla al dizionario" - "Tocca questo suggerimento per continuare »" - "Tocca qui per chiudere questo suggerimento e iniziare a digitare." - "La tastiera si apre ogni volta che tocchi un campo di testo" - "Tocca e tieni premuto un pulsante per visualizzare le lettere con segni diacritici"\n"(ø, ö, ô, ó e così via)" - "Passa a numeri e simboli toccando questo pulsante" - "Torna alle lettere toccando di nuovo questo pulsante" - "Tocca e tieni premuto questo pulsante per modificare le impostazioni della tastiera, come il completamento automatico" - "Prova!" - "Vai" - "Avanti" - "Fine" - "Invia" - "?123" - "123" - "ABC" - "ALT" - "Comandi vocali" - "I comandi vocali non sono attualmente supportati per la tua lingua ma funzionano in inglese." - "I comandi vocali sono una funzione sperimentale che utilizza il riconoscimento vocale in rete di Google." - "Per disattivare i comandi vocali, vai alle impostazioni della tastiera." - "Per utilizzare i comandi vocali, premi il pulsante del microfono o fai scorrere il dito sulla tastiera sullo schermo." - "Parla ora" - "Elaborazione in corso" - - "Errore. Riprova più tardi." - "Impossibile connettersi." - "Errore: conversazione troppo lunga." - "Problema audio" - "Errore del server" - "Nessuna frase vocale rilevata" - "Nessuna corrispondenza trovata" - "Ricerca vocale non installata" - "Suggerimento."" Fai scorrere il dito sulla tastiera per parlare" - "Suggerimento."" La prossima volta, prova a pronunciare termini relativi alla punteggiatura come \"punto\", \"virgola\" o \"punto di domanda\"." - "Annulla" - "OK" - "Comandi vocali" - - "Su tastiera principale" - "Su tastiera simboli" - "Non attivi" - - - "Microfono su tastiera principale" - "Microfono su tastiera simboli" - "Comandi vocali disabilitati" - - "Invia automaticamente dopo comando vocale" - "Premi automaticamente \"Invio\" durante una ricerca o un passaggio al campo successivo." - "Apertura tastiera"\n\n"Tocca qualsiasi campo di testo." - "Chiusura tastiera"\n\n"Premi il tasto Indietro." - "Tocca e tieni premuto un pulsante per le opzioni"\n\n"Accesso a punteggiatura e accenti." - "Impostazioni tastiera"\n\n"Tocca e tieni premuto il pulsante ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Seleziona metodo di inserimento" - "Lingue comandi" - "Scorri il dito sulla barra spaziatrice per cambiare la lingua" - "← Tocca di nuovo per salvare" - "Dizionario disponibile" - "Attiva commenti degli utenti" - "Aiuta a migliorare l\'editor del metodo di inserimento inviando automaticamente a Google statistiche sull\'utilizzo e segnalazioni sugli arresti anomali." - "Tocca per correggere" - "Tocca le parole inserite per correggerle" - "Tema della tastiera" - "tastiera" - "vocale" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-it/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-it/strings_kp2a.xml deleted file mode 100644 index 079889d7..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-it/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Seleziona un\'altra voce - Seleziona una voce - Cerca la voce \"%1$s\" - Utente - Password - Impostazioni delle credenziali di ingresso - Auto-Compilazione abilitata - Inserisci automaticamente il testo, quando si entra in un campo vuoto, se è selezionata una voce di Keepass2Android per la tastiera ed esiste un valore che corrisponde al testo di suggerimento del campo. - Ricorda i testi di suggerimento del campo - Se un campo di testo viene compilato selezionando manualmente il valore di Keepass2Android, ricorda quale valore è stato immesso nel campo. In seguito il campo di testo verrà rilevato tramite il suo testo di suggerimento. - Tastiera semplice - Mostra la tastiera a una riga se è disponibile una voce per la tastiera. Se disabilitato, verrà mostrata una finestra di dialogo alla pressione del tasto Keepass2Android. - Blocca il database quando terminato - Premendo il tasto Fatto/Invia/Vai sulla tastiera a una riga, blocca automaticamente il database. - Cambia tastiera quando terminato - Premendo il tasto Fatto/Invia/Vai sulla tastiera a una riga, cambia la tastiera. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-iw/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-iw/strings.xml deleted file mode 100644 index 7c5b494a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-iw/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "מקלדת Keepass2Android" - "הגדרות מקלדת של Keepass2Android" - "אפשרויות קלט" - "רטט עם לחיצה על מקשים" - "צלילים עם לחיצה על מקשים" - "חלון קופץ עם לחיצה על מקשים" - "תקן שגיאות הקלדה" - "הפוך תיקון שגיאות קלט לפעיל" - "שגיאות קלט בפריסה לרוחב" - "הפוך תיקון שגיאות קלט לפעיל" - "הצעות למילים" - "תקן באופן אוטומטי את המילה הקודמת" - "הצעות למילים" - "הגדרות של הצעות מילים" - "הפוך השלמה אוטומטית לפעילה בעת הקלדה" - "השלמה אוטומטית" - "הגדל את הגודל של שדה הטקסט" - "הסתר הצעות למילים בתצוגה לרוחב" - "הפיכה אוטומטית של אותיות לרישיות" - "הוסף אות רישית בתחילת משפט" - "פיסוק אוטומטי" - - "תיקונים מהירים" - "מתקן שגיאות הקלדה נפוצות" - "הצג הצעות" - "הצג הצעות למילים בעת הקלדה" - "השלמה אוטומטית" - "הקשה על מקש הרווח וסימני הפיסוק תוסיף באופן אוטומטי את המילה המסומנת" - "הצג מקש הגדרות" - "אוטומטי" - "הצג תמיד" - "הסתר תמיד" - - - - "הצעות של צמדי אותיות (Bigram)" - "השתמש במילה הקודמת כדי לשפר את ההצעה" - - "ללא" - "בסיסי" - "מתקדם" - - "%s : נשמרה" - "החזק מקש לחוץ כדי לראות אקצנטים (ø, ö וכדומה)" - "לחץ על המקש \'הקודם\' ↶ כדי לסגור את המקלדת בכל עת" - "גישה למספרים וסמלים" - "לחץ על המילה השמאלית הקיצונית והחזק אותה לחוצה כדי להוסיף למילון" - "גע ברמז זה כדי להמשיך »" - "גע כאן כדי לסגור רמז זה ולהתחיל בהקלדה!" - "המקלדת נפתחת בכל פעם שאתה נוגע בשדה טקסט" - "גע במקש והחזק אותו לחוץ כדי להציג אקצנטים"\n"(ø, ö, ô, ó וכדומה)" - "עבור למספרים וסמלים על ידי נגיעה במקש זה" - "חזור לאותיות על ידי מגע במקש זה שוב" - "גע במקש זה והחזק אותו לחוץ כדי לשנות את הגדרות המקלדת, כגון השלמה אוטומטית" - "נסה אותו!" - "בצע" - "הבא" - "בוצע" - "שלח" - "?123" - "123" - "ABC" - "ALT" - "קלט קולי" - "קלט קולי אינו נתמך בשלב זה בשפתך, אך הוא פועל באנגלית." - "קלט קולי הוא תכונה ניסיונית של זיהוי הדיבור ברשת של Google." - "כדי לכבות את הקלט הקולי, עבור להגדרות מקלדת." - "כדי להשתמש בקלט הקולי, לחץ על לחצן המיקרופון או החלק את האצבע על המקלדת שבמסך." - "דבר כעת" - "פועל" - - "שגיאה. נסה שוב." - "אין אפשרות להתחבר" - "שגיאה, דיבור רב מדי." - "בעיה באודיו" - "שגיאת שרת" - "לא נשמע דיבור" - "לא נמצאו התאמות" - "חיפוש קולי לא מותקן" - "רמז:"" העבר על המקלדת כדי לדבר" - "רמז:"" בפעם הבאה, נסה לומר את סימני הפיסוק כגון \"נקודה\", \"פסיק\" או \"סימן שאלה\"." - "ביטול" - "אישור" - "קלט קולי" - - "במקלדת הראשית" - "מקלדת סמלים מופעלת" - "כבוי" - - - "מיקרופון במקלדת הראשית" - "מיקרופון במקלדת סמלים" - "הקלט הקולי מושבת" - - "שליחה אוטומטית לאחר הקלטת קול" - "הקש על Enter באופן אוטומטי בעת חיפוש או מעבר לשדה הבא." - "פתח את המקלדת"\n\n"גע בשדה טקסט כלשהו." - "סגור את המקלדת"\n\n"לחץ על הלחצן \'הקודם\'." - "גע במקש והחזק אותו לחוץ לקבלת אפשרויות"\n\n"קבל גישה לסימני פיסוק ואקצנטים." - "הגדרות מקלדת"\n\n"גע במקש ""?123"" והחזק אותו לחוץ." - "‎.com" - "‎.net" - "‎.org" - "‎.gov" - "‎.edu" - "בחר שיטת קלט" - "שפות קלט" - "החלק את האצבע על מקש הרווח כדי לשנות שפה" - "← גע שוב כדי לשמור" - "מילון זמין" - "הפוך משוב ממשתמשים לפעיל" - "עזור לשפר שיטת קלט זו על ידי שליחה אוטומטית של סטטיסטיקת שימוש ודוחות קריסת מחשב ל-Google." - "גע כדי לתקן מילים" - "גע במילים שהוזנו כדי לתקן אותן" - "עיצוב מקלדת" - "מקלדת" - "קולי" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-iw/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-iw/strings_kp2a.xml deleted file mode 100644 index 1db547b9..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-iw/strings_kp2a.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - בחר ערך אחר - בחר ערך - חפש ערך עם \'%1$s\' - משתמש - סיסמה - הגדרות קלט האימות - השלמה-אוטומאטית מאופשרת - זכור את שדה טקסט הרמזים - מקלדת פשוטה - נעל מסד הנתונים בסיום - החלף מקלדת בסיום - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ja/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ja/donottranslate-altchars.xml deleted file mode 100644 index d3beafad..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ja/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àáâãäåæ - 3èéêë - ìíîï8 - òóôõöœø9 - ùúûü7 - §ß - ñ - ç - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ja/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ja/strings.xml deleted file mode 100644 index 85a6e31c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ja/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Androidキーボード" - "Keepass2Androidキーボードの設定" - "入力オプション" - "キー操作バイブ" - "キー操作音" - "キー押下時ポップアップ" - "入力ミス補正" - "入力間違いを自動修正する" - "横表示での入力修正" - "入力間違いを自動修正する" - "入力候補表示" - "前の単語を自動修正する" - "入力候補表示" - "入力候補の設定" - "オートコンプリートを使用する" - "オートコンプリート" - "入力作業スペースを広げる" - "横表示では入力候補を表示しない" - "自動大文字変換" - "英字入力で文頭文字を大文字にする" - "句読点を自動入力" - - "クイックフィックス" - "よくある誤字・脱字を修正します" - "入力候補を表示" - "入力時に入力候補を表示する" - "オートコンプリート" - "誤入力をスペースまたは句読点キーで修正する" - "設定キーを表示" - "自動" - "常に表示" - "常に非表示" - - - - "バイグラム入力候補表示" - "直前の単語から入力候補を予測します" - - "なし" - "基本" - "高度" - - "%s:保存しました" - "キー長押しでアクセント文字を表示(ø、öなど)" - "戻るキーでキーボードを閉じます" - "数字と記号" - "一番左の単語を長押しすると辞書に追加されます" - "続けるにはここをタッチ" - "タッチしてこのヒントを終了し、入力を開始してください。" - "テキストフィールドを選択するとキーボードが表示されます" - "キーを長押しするとアクセント付き文字"\n"(ø、ö、ô、óなど)が表示されます" - "このキーを押すと、数字/記号入力に切り替わります" - "このキーを押すと、文字入力に再度切り替わります" - "オートコンプリートなどのキーボードの設定を変更するには、このキーを長押しします" - "試してみてください。" - "実行" - "次へ" - "完了" - "送信" - "?123" - "123" - "ABC" - "ALT" - "音声入力" - "音声入力は現在英語には対応していますが、日本語には対応していません。" - "音声入力はGoogleのネットワーク音声認識技術を利用した試験段階の機能です。" - "音声入力をOFFにするには、キーボードの設定を開きます。" - "音声入力するには、マイクボタンを押すか画面キーボードをスワイプしてください。" - "お話しください" - "処理中" - - "エラーです。もう一度お試しください。" - "接続できませんでした" - "音声が長すぎてエラーになりました。" - "オーディオエラー" - "サーバーエラー" - "音声が聞き取れません" - "該当なし" - "Voice Searchはインストールされていません" - "ヒント:"" 音声入力するにはキーボードをスワイプします" - "ヒント:"" 次回は句読点として「period」、「comma」、「question mark」などの音声入力を試してみてください。" - "キャンセル" - "OK" - "音声入力" - - "メインキーボード上" - "記号キーボード上" - "OFF" - - - "メインキーボードのマイク" - "記号キーボードのマイク" - "音声入力は無効です" - - "入力後に自動送信する" - "検索または次のフィールドに進む際、Enterキーが自動的に押されます。" - "キーボードを開く"\n\n"テキストフィールドをタップします。" - "キーボードを閉じる"\n\n"[戻る]キーを押します。" - "キーを長押しして選択する"\n\n"句読点キーとアクセント文字を表示します。" - "キーボードの設定"\n\n"[""?123""]キーを長押しします。" - ".com" - ".net" - ".org" - ".gov" - ".edu" - "入力方法の選択" - "入力言語" - "スペースバーで指をスライドさせて言語を変更する" - "←保存するにはもう一度タップ" - "辞書を利用できます" - "ユーザーフィードバックを有効にする" - "IMEの機能向上のため、使用統計状況やクラッシュレポートをGoogleに自動送信します。" - "タップして語句を修正" - "入力した語句をタップして修正" - "キーボードテーマ" - "キーボード" - "音声" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ja/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ja/strings_kp2a.xml deleted file mode 100644 index 7dc5a795..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ja/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - 別のエントリを選択 - エントリの選択 - エントリを\"%1$s\"で検索します。 - ユーザー - パスワード - 資格情報の入力の設定 - オートフィルを有効にする - Keepass2Android のエントリーでキーボードが使用可能で、フィールドのヒントのテキストに一致する値がある場合、空のフィールドに自動的にテキストが入力されます。 - フィールドのヒントのテキストを保存 - Keepass2Android の値を手動で選択してテキスト フィールドを入力する場合、テキスト フィールドに入力された値を保存します。後でそのヒント テキストを使用してテキスト フィールドを検出します。 - シンプルキーボード - エントリがキーボードで利用できる場合シンプルな1行のキーボードをを表示します。もし無効にした場合、Keepass2Androidキーが押されたときにダイアログが表示されます。 - 完了時にデーターベースをロックする - シンプルな1行のキーボードで完了/送信/実行キーを押したときにデーターベースを自動でロックします。 - 完了時にキーボードを切り替える - シンプルな1行のキーボードで完了/送信/実行キーを押したときにキーボードを切り替えます。 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ko/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ko/donottranslate-altchars.xml deleted file mode 100644 index d3beafad..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ko/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àáâãäåæ - 3èéêë - ìíîï8 - òóôõöœø9 - ùúûü7 - §ß - ñ - ç - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ko/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ko/strings.xml deleted file mode 100644 index dc3fbb77..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ko/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android 키보드" - "Keepass2Android 키보드 설정" - "입력 옵션" - "키를 누를 때 진동 발생" - "키를 누를 때 소리 발생" - "키를 누를 때 팝업" - "입력 오류 수정" - "입력 오류 수정 사용" - "가로 입력 오류" - "입력 오류 수정 사용" - "단어 추천" - "이전 단어를 자동으로 수정" - "단어 추천" - "단어 추천 설정" - "입력할 때 자동 완성 사용" - "자동 완성" - "입력란 크기 늘리기" - "가로 보기에서 추천 단어 숨기기" - "자동 대문자화" - "문장의 첫 글자를 대문자로 표시" - "자동 구두점 입력" - - "빠른 수정" - "자주 발생하는 오타를 수정합니다." - "추천 단어 표시" - "글자를 입력하는 동안 추천 단어를 표시" - "자동 완성" - "스페이스바와 문장부호 키로 강조 표시된 단어를 자동 삽입" - "설정 키 표시" - "자동" - "항상 표시" - "항상 숨기기" - - - - "Bigram 추천" - "이전 단어를 사용하여 추천 기능 개선" - - "없음" - "기본" - "고급" - - "%s: 저장됨" - "키를 길게 누르면 악센트(ø, ö 등)가 표시됩니다." - "키보드를 닫으려면 언제든지 뒤로 키(↶)를 누르세요." - "숫자 및 기호 사용" - "맨 왼쪽에 있는 단어를 길게 누르면 사전에 추가됩니다." - "계속하려면 힌트를 터치하세요. »" - "힌트를 닫고 입력을 시작하려면 여기를 터치하세요." - "언제든지 입력란을 터치하면 키보드가 열립니다." - "키를 길게 터치하면 악센트"\n"(ø, ö, ô, ó 등)가 표시됩니다." - "이 키를 터치하면 숫자 및 기호 키보드로 전환됩니다." - "이 키를 다시 터치하면 문자 키보드로 돌아갑니다." - "자동 완성과 같은 키보드 설정을 변경하려면 이 키를 길게 터치하세요." - "이제 사용해 보세요." - "이동" - "다음" - "완료" - "전송" - "?123" - "123" - "ABC" - "ALT" - "음성 입력" - "음성 입력은 현재 자국어로 지원되지 않으며 영어로 작동됩니다." - "음성 입력은 Google의 네트워크화된 음성 인식을 사용하는 실험적 기능입니다." - "음성 입력을 사용하지 않으려면 키보드 설정으로 이동하세요." - "음성 입력을 사용하려면 마이크 버튼을 누르거나 터치 키보드 위로 손가락을 미끄러지듯 움직이세요." - "지금 말하세요." - "인식 중" - - "오류가 발생했습니다. 다시 시도해 보세요." - "연결할 수 없습니다." - "음성을 너무 많이 입력했습니다." - "오디오 문제" - "서버 오류" - "음성이 인식되지 않았습니다." - "일치하는 항목 없음" - "음성 검색이 설치되지 않았습니다." - "도움말:"" 키보드 위로 손가락을 미끄러지듯 움직이고 나서 말하세요." - "도움말:"" 다음 번에는 \'마침표\', \'쉼표\', \'물음표\'와 같은 구두점을 말해 보세요." - "취소" - "확인" - "음성 입력" - - "기본 키보드" - "기호 키보드" - "사용 안함" - - - "기본 키보드의 마이크" - "기호 키보드의 마이크" - "음성 입력이 사용 중지됨" - - "음성을 입력한 다음 자동 제출" - "검색하거나 다음 입력란으로 이동할 때 자동으로 Enter 키를 누릅니다." - "키보드 열기"\n\n"아무 텍스트 입력란이나 터치하세요." - "키보드 닫기"\n\n"\'뒤로\' 키를 누르세요." - "키를 길게 눌러 옵션 보기"\n\n"문장 부호 및 악센트 기호 입력창이 열립니다." - "키보드 설정"\n\n"?123"" 키를 길게 누르세요." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "입력 방법 선택" - "입력 언어" - "손가락을 스페이스바에서 미끄러지듯 움직여 언어 변경" - "← 저장하려면 다시 터치하세요." - "사전 사용 가능" - "사용자 의견 사용" - "사용 통계 및 충돌 보고서를 Google에 자동으로 전송하여 입력 방법 편집기의 개선에 도움을 줍니다." - "터치하여 단어 수정" - "입력한 단어를 터치하여 수정" - "키보드 테마" - "키보드" - "음성" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ko/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ko/strings_kp2a.xml deleted file mode 100644 index 10025055..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ko/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - 다른 항목 선택 - 항목 선택 - \"%1$ s\" 항목 검색 - 사용자 - 비밀번호 - 자격증명 입력 설정 - 자동채우기 사용 - Keepass2Android 키보드가 가진 항목의 값이 빈 필드의 힌트 텍스트와 일치하는 경우, 빈 필드를 자동으로 채움 - 필드의 힌트 텍스트 기억하기 - Keepass2Androd의 값을 선택하여 수동으로 필드를 채울 경우, 해당 텍스드 필드 기억하기. 해당 텍스트 필드는 나중에 힌트 텍스트에 의해 다시 감지되게 됨. - 간편 키보드 - 만약 사용가능한 항목이 있다면 1열 간편 키보드를 띄움. 만약 이 옵션이 비활성상태라 하더라도 Keepass2Android 키를 눌러 대화상자에 표시됨. - 완료시 데이테베이스 잠금 - 완료/보내기/엔터 키를 누르면 자동으로 데이터베이스 잠금 - 완료 시 키보드 바꾸기 - 1열 간편키보드 상태에서 완료/보내기/이동 키를 누르면 키보드 전환되기. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-land/dimens.xml b/src/java/KP2ASoftKeyboard2/java/res/values-land/dimens.xml deleted file mode 100644 index df8333e8..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-land/dimens.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - 42.329987dip - 2.0dip - 43.19998dip - 0.0dip - 38.0dip - 63.0dip - 2.0dip - 73.44dip - -43.19998dip - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-lt/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-lt/strings.xml deleted file mode 100644 index ef3b67b5..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-lt/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "„Keepass2Android“ klaviatūra" - "„Keepass2Android“ klaviatūros nustatymai" - "Įvesties parinktys" - "Vibruoti, kai paspaudžiami klavišai" - "Klavišo paspaudimo garsas" - "Iššoka paspaudus klavišą" - "Taisyti rašybos klaidas" - "Įgalinti įvesties klaidos taisymą" - "Gulsčia įvestis" - "Įgalinti įvesties klaidos taisymą" - "Žodžių pasiūlymai" - "Automatiškai taisyti ankstesnį žodį" - "Žodžių pasiūlymai" - "Žodžių pasiūlymo nustatymai" - "Įgalinti automatinį užbaigimą, kai įvedinėjamas tekstas" - "Automatinis užbaigimas" - "Padidinti teksto lauko dydį" - "Gulsčiame rodinyje slėpti žodžių pasiūlymus" - "Automatinis didžiųjų raidžių rašymas" - "Sakinio pradžią rašyti didžiąja raide" - "Automatiškai dėti skyrybos ženklus" - - "Greiti pataisymai" - "Taiso dažnai padarytas rašybos klaidas" - "Rodyti pasiūlymus" - "Įvedant tekstą pateikti siūlomus žodžius" - "Automatiškai užbaigti" - "Tarpo klavišas ir skyrybos ženklai automatiškai įterpia paryškintą žodį" - "Rodyti nustatymų raktą" - "Automatinis" - "Visada rodyti" - "Visada slėpti" - - - - "Digramų pasiūlymai" - "Naudoti ankstesnį žodį pasiūlymui patobulinti" - - "Nėra" - "Paprastas" - "Išplėstinis" - - "%s: išsaugota" - "Laikykite klavišą nuspaudę, kad pamatytumėte kirčius (ø, ö ir t. t.)" - "Paspauskite klavišą „Atgal“ ↶, kad uždarytumėte klaviatūrą" - "Pasiekti skaičius ir simbolius" - "Paspauskite ir laikykite nuspaudę kairiausią žodį, kad pridėtumėte jį prie žodyno" - "Palieskite šią užuominą, jei norite tęsti »" - "Paleiskite čia, kad uždarytumėte šią užuominą ir pradėtumėte įvedinėti tekstą!" - "Klaviatūra atsidarys kaskart, kai paliesite teksto lauką" - "Palieskite ir laikykite klavišą, kad pamatytumėte kirčius"\n"(ø, ö, ô, ó, and so on)" - "Perjunkite į skaičius ir simbolius, paliesdami šį klavišą" - "Grįžkite prie raidžių dar kartą paliesdami šį klavišą" - "Palieskite ir laikykite šį klavišą, kad pakeistumėte klaviatūros nustatymus, pvz., automatinį užbaigimą" - "Išbandykite tai!" - "Pradėti" - "Kitas" - "Atlikta" - "Siųsti" - "?123" - "123" - "ABC" - "ALT" - "Balso įvestis" - "Šiuo metu balso įvestis jūsų kompiuteryje nepalaikoma, bet ji veikia anglų k." - "Balso įvestis – tai eksperimentinė funkcija, naudojanti „Google“ tinklo kalbos atpažinimą." - "Jei norite išjungti balso įvestį, eikite į klaviatūros nustatymus." - "Jei norite naudoti balso įvestį, paspauskite mikrofono mygtuką arba pirštu slyskite ekranine klaviatūra." - "Kalbėkite dabar" - "Veikia" - - "Klaida. Bandykite dar kartą." - "Nepavyko prijungti" - "Klaida, per daug kalbos." - "Problema su garsu" - "Serverio klaida" - "Negirdima jokia kalba" - "Atitikmenų nerasta" - "Balso paieška neįdiegta" - "Užuomina:"" perbraukite klaviatūra, kad galėtumėte kalbėti" - "Užuomina:"" kitą kartą pabandykite sakyti skyrybos ženklų pavadinimus, pvz., „taškas“, „kablelis“ arba „klaustukas“." - "Atšaukti" - "Gerai" - "Balso įvestis" - - "Pagrindinėje klaviatūroje" - "Simbolių klaviatūroje" - "Išjungta" - - - "Pagrindinės klaviatūros mikrofonas" - "Mikrofonas simbolių klaviatūroje" - "Balso įvestis išjungta" - - "Automatiškai pateikti po balso" - "Automatiškai spausti „Įvesti“ ieškant ar einant į kitą lauką." - "Atidarykite klaviatūrą"\n\n"Palieskite bet kurį teksto lauką." - "Uždarykite klaviatūrą"\n\n"Paspauskite klavišą „Atgal“." - "Palieskite ir laikykite klavišą, kad pamatytumėte parinktis"\n\n"Pasiekite skyrybos ženklus ir kirčius." - "Klaviatūros nustatymai"\n\n"Palieskite ir laikykite klavišą ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Pasirinkti įvesties metodą" - "Įvesties kalbos" - "Pirštu slyskite tarpo klavišu, kad pakeistumėte kalbą" - "← Kad išsaugotumėte, dar kartą palieskite" - "Žodynas galimas" - "Įgalinti naudotojų atsiliepimus" - "Padėkite patobulinti šią įvesties metodo redagavimo programą automatiškai „Google“ siųsdami naudojimo statistiką ir strigčių ataskaitas." - "Jei norite ištais. žodž., paliesk." - "Jei norite ištaisyti įvestus žodžius, palieskite juos" - "Klaviatūros tema" - "klaviatūra" - "Voice" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-lv/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-lv/strings.xml deleted file mode 100644 index f5694a37..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-lv/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android tastatūra" - "Keepass2Android tastatūras iestatījumi" - "Ievades opcijas" - "Vibrēt, nospiežot taustiņu" - "Skaņa, nospiežot taustiņu" - "Nospiežot taustiņu, parādīt uznirstošo izvēlni" - "Labot drukas kļūdas" - "Iespējot ievades kļūdu labošanu" - "Ainavas orientācijas ievades kļūdas" - "Iespējot ievades kļūdu labošanu" - "Vārdu ieteikumi" - "Automātiski labot iepriekšējo vārdu" - "Vārdu ieteikumi" - "Vārdu ieteikumu iestatījumi" - "Iespējot automātisko pabeigšanu ievades laikā" - "Automātiska pabeigšana" - "Palielināt teksta lauka lielumu" - "Ainavas skatījumā slēpt vārdu ieteikumus" - "Automātiska lielo burtu lietošana" - "Sākt teikumu ar lielo burtu" - "Automātiska pieturzīmju lietošana" - - "Ātrie labojumi" - "Nodrošina izplatītu drukas kļūdu labošanu." - "Rādīt ieteikumus" - "Ievades laikā attēlot ieteiktos vārdus" - "Automātiska pabeigšana" - "Automātiski ievietot iezīmēto vārdu, izmantojot atstarpes taustiņu un pieturzīmes" - "Rādīt iestatījumu taustiņu" - "Automātiski" - "Vienmēr rādīt" - "Vienmēr slēpt" - - - - "Bigram ieteikumi" - "Ieteikuma uzlabošanai izmantot iepriekšējo vārdu" - - "Nav" - "Pamata" - "Uzlabots" - - "%s: saglabāts" - "Turiet taustiņu nospiestu, lai skatītu uzsvēruma zīmes (ø, ö u.c.)." - "Jebkurā brīdī nospiediet taustiņu Atpakaļ ↶, lai aizvērtu tastatūru." - "Piekļūt cipariem un simboliem" - "Nospiediet kreisajā pusē esošo vārdu un turiet, lai pievienotu to vārdnīcai." - "Pieskarieties šim ieteikumam, lai turpinātu »" - "Pieskarieties šeit, lai aizvērtu šo ieteikumu un sāktu ievadi." - "Tastatūra tiek atvērta ikreiz, kad pieskaraties teksta laukam""." - "Pieskarieties taustiņam un turiet, lai skatītu uzsvara zīmes"\n"(ø, ö, ô, ó utt.)." - "Pieskarieties šim taustiņam, lai izmantotu ciparus un simbolus." - "Vēlreiz pieskarieties šim taustiņam, lai atkal izmantotu burtus." - "Pieskarieties taustiņam un turiet, lai mainītu tastatūras iestatījumus, piemēram, automātisko pabeigšanu." - "Izmēģiniet to!" - "Sākt" - "Tālāk" - "Gatavs" - "Sūtīt" - "?123" - "123" - "ABC" - "ALT" - "Balss ievade" - "Balss ievade jūsu valodā pašlaik netiek atbalstīta, taču tā ir pieejama angļu valodā." - "Balss ievade ir izmēģinājuma funkcija, kuras pamatā ir Google tīkla runas atpazīšanas līdzeklis." - "Lai izslēgtu balss ievadi, atveriet tastatūras iestatījumus." - "Lai izmantotu balss ievadi, nospiediet mikrofona pogu vai slidiniet pirkstus pāri ekrāna tastatūrai." - "Runājiet!" - "Notiek apstrāde" - - "Kļūda. Lūdzu, mēģiniet vēlreiz." - "Nevar izveidot savienojumu." - "Kļūda, pārāk ilga balss ievade." - "Audio problēma" - "Servera kļūda" - "Nekas nav dzirdams." - "Nav atrasta neviena atbilstība." - "Balss meklēšana nav instalēta." - "Ieteikums:"" slidiniet pirkstu pār tastatūru, lai veiktu balss ievadi." - "Ieteikums:"" nākamreiz mēģiniet izrunāt pieturzīmes, piemēram, “punkts”, “komats” vai “jautājuma zīme”." - "Atcelt" - "Labi" - "Balss ievade" - - "Izmantojot galveno tastatūru" - "Izmantojot simbolu tastatūru" - "Izsl." - - - "Galvenās tastatūras mikrofons" - "Simbolu tastatūras mikrofons" - "Balss ievade ir atspējota" - - "Automātiski iesniegt pēc balss ievades" - "Automātiski nospiest ievades taustiņu, meklējot vai pārejot uz nākamo lauku." - "Tastatūras atvēršana"\n\n"Pieskarieties jebkuram teksta laukam." - "Tastatūras aizvēršana"\n\n"Nospiediet taustiņu Atpakaļ." - "Pieskarieties taustiņam un turiet, lai skatītu opcijas."\n\n"Piekļūstiet pieturzīmēm un uzsvara zīmēm." - "Tastatūras iestatījumi"\n\n"Pieskarieties taustiņam ""?123"" un turiet." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Atlasīt ievades metodi" - "Ievades valodas" - "Slidiniet pirkstu uz atstarpes taustiņa, lai mainītu valodu" - "← Pieskarieties vēlreiz, lai saglabātu" - "Ir pieejama vārdnīca." - "Iespējot lietotāju atsauksmes" - "Palīdziet uzlabot šo ievades metodes redaktoru, automātiski nosūtot lietojuma statistiku un pārskatus par avārijām uzņēmumam Google." - "Pieskarties, lai izlabotu vārdus" - "Pieskarties ievadītajiem vārdiem, lai tos labotu" - "Tastatūras motīvs" - "tastatūra" - "balss" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-nb/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-nb/donottranslate-altchars.xml deleted file mode 100644 index 6257dfc3..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-nb/donottranslate-altchars.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - äáàâąã - 3éèêëę€ - íìîï8 - öóòôõ9 - üúùûū7 - śšşß - ńñň - çćč - ýÿ6 - ðď - ř4 - ťþ5 - źžż - ł - w - œ - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-nb/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-nb/strings.xml deleted file mode 100644 index 24326b69..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-nb/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android tastatur" - "Innstillinger for Keepass2Android tastatur" - "Inndataalternativer" - "Vibrer ved tastetrykk" - "Lyd ved tastetrykk" - "Hurtigvindu ved tastetrykk" - "Rett opp skrivefeil" - "Slå på retting av skrivefeil" - "Rett opp skrivefeil i breddeformat" - "Slå på retting av skrivefeil" - "Autokorrektur" - "Autokorriger forrige ord" - "Ordforslag" - "Innstillinger for ordforslag" - "Skru på autofullføring under skriving" - "Autofullfør" - "Større tekstfelt" - "Skjul ordforslag i breddeformat" - "Stor forbokstav" - "Start automatisk setninger med stor bokstav" - "Automatisk punktum" - - "Autokorrektur" - "Retter vanlige stavefeil" - "Vis forslag" - "Vis foreslåtte ord under skriving" - "Autofullføring" - "Mellomrom og punktum setter automatisk inn valgt ord" - "Vis innstillingsnøkkel" - "Automatisk" - "Vis alltid" - "Skjul alltid" - - - - "Bigram-forslag" - "Bruk forrige ord til å forbedre forslaget" - - "Ingen" - "Grunnleggende" - "Avansert" - - "%s: Lagret" - "Hold en tast nede for å se aksenterte tegn (ø, ö, osv.)" - "Trykk tilbakeknappen, ↶, for å lukke tastaturet" - "Få tilgang til tall og symboler" - "Trykk lenge på ordet lengst til venstre for å legge det til i ordlisten" - "Trykk på dette hintet for å forsette »" - "Trykk her for å lukke dette hintet og begynne å skrive!" - "Tastaturet åpnes når du tar på et tekstfelt" - "Trykk på og hold nede en tast for å se aksenter"\n"(ø, ö, ô, ó, osv.)" - "Bytt til tall og symboler ved å trykke på denne tasten" - "Gå tilbake til bokstaver igjen ved å trykke på denne tasten" - "Trykk på og hold nede denne tasten for å endre tastaturinnstillinger, som autofullføring" - "Prøv det!" - "Gå" - "Neste" - "Utfør" - "Send" - "?123" - "123" - "ABC" - "ALT" - "Stemmedata" - "Stemmedata håndteres foreløpig ikke på ditt språk, men fungerer på engelsk." - "Talekommandoer er en eksperimentell funksjon som bruker Googles nettverksbaserte talegjenkjenning." - "Gå til innstillinger for tastatur for å slå av stemmedata." - "Du bruker talekommandoer ved å trykke på mikrofonknappen eller skyve fingeren over tastaturet på skjermen." - "Snakk nå" - "Arbeider" - - "Feil. Prøv på nytt." - "Kunne ikke koble til" - "Feil – for mye tale" - "Lydproblem" - "Tjenerfeil" - "Ingen tale høres" - "Ingen treff" - "Talesøk ikke installert" - "Hint:"" Sveip over tastaturet for å snakke" - "Hint:"" Neste gang kan du prøve å tale inn tegnsettingen ved for eksempel å si «punktum», «komma» eller «spørsmålstegn»." - "Avbryt" - "OK" - "Talekommando" - - "På hovedtastatur" - "På talltastatur" - "Av" - - - "Mikrofon på hovedtastatur" - "Mikrofon på talltastatur" - "Talekommando er deaktivert" - - "Send inn automatisk etter tale" - "Trykk Enter automatisk ved søk eller flytting til neste felt." - "Åpne tastaturet"\n\n"Trykk på et tekstfelt." - "Lukke tastaturet"\n\n"Trykk på tilbaketasten." - "Trykk og hold nede en tast for flere valg"\n\n"Få tilgang til skilletegn og aksenter." - "Innstillinger for tastatur"\n\n"Trykk på & hold ""?123""-tasten." - ".no" - ".com" - ".net" - ".org" - ".info" - "Velg inndatametode" - "Inndataspråk" - "Dra fingeren på mellomromstasten for å endre språk" - "Trykk på nytt for å lagre" - "Ordbok tilgjengelig" - "Aktiver brukertilbakemelding" - "Ved å sende bruksstatistikk og programstopprapporter til Google automatisk, hjelper du oss med å gjøre redigeringsfunksjonen for denne inndatametoden enda bedre." - "Trykk for å endre ord" - "Trykk på ord du har skrevet inn, for å endre dem" - "Tastaturtema" - "tastatur" - "stemme" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-nb/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-nb/strings_kp2a.xml deleted file mode 100644 index ef6df9b9..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-nb/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Velg en annen oppføring - Velg oppføring - Søke etter oppføringen med \"%1$s\" - Bruker - Passord - Innstillinger for innloggingsdetaljer - Autofyll aktivert - Fyll inn tomme felter automatisk dersom det fins en oppføring for tastaturet til Keepass2Android, og det fins en verdi som samsvarer med feltets hinttekst. - Husk feltenes hinttekster - Dersom feltet fylles manuelt ved å velge en verdi fra Keepass2Android, husk verdien som ble skrevet inn i tekstfeltet. Tekstfeltet vil senere bli gjenkjent av dets hinttekst. - Enkelt tastatur - Vis det enkle 1 rad tastaturet hvis det finnes en oppføring for tastaturet. Hvis deaktivert, vises en dialogboks når Keepass2Android tasten trykkes. - Lås databasen når ferdig - Når du trykker tasten for Ferdig/Send/Gå på det enkle enlinjers tastturet, lås databasen automatisk. - Bytt tastatur når ferdig - Når du trykker tasten for Ferdig/Send/Gå på det enkle enlinjers tastturet, bytt tastatur. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-nl/bools.xml b/src/java/KP2ASoftKeyboard2/java/res/values-nl/bools.xml deleted file mode 100644 index 897f4b3d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-nl/bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - true - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-nl/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-nl/donottranslate-altchars.xml deleted file mode 100644 index d3beafad..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-nl/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àáâãäåæ - 3èéêë - ìíîï8 - òóôõöœø9 - ùúûü7 - §ß - ñ - ç - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-nl/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-nl/strings.xml deleted file mode 100644 index 753a5140..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-nl/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android-toetsenbord" - "Instellingen voor Keepass2Android-toetsenbord" - "Invoeropties" - "Trillen bij toetsaanslag" - "Geluid bij toetsaanslag" - "Pop-up bij toetsaanslag" - "Typefouten corrigeren" - "Foutcorrectie tijdens invoer inschakelen" - "Invoerfouten in liggende weergave" - "Foutcorrectie tijdens invoer inschakelen" - "Woordsuggesties" - "Het vorige woord automatisch corrigeren" - "Woordsuggesties" - "Instellingen voor woordsuggesties" - "Automatisch voltooien tijdens typen inschakelen" - "Automatisch voltooien" - "Tekstveld vergroten" - "Woordsuggesties verbergen in liggende weergave" - "Auto-hoofdlettergebruik" - "Hoofdletter gebruiken aan het begin van een zin" - "Automatische interpunctie" - - "Snelle oplossingen" - "Hiermee worden veelvoorkomende typefouten gecorrigeerd" - "Suggesties weergeven" - "Voorgestelde woorden weergeven tijdens typen" - "Auto-aanvullen" - "Gemarkeerd woord automatisch invoegen met spatiebalk en interpunctie" - "Instellingscode weergeven" - "Automatisch" - "Altijd weergeven" - "Altijd verbergen" - - - - "Digram-suggesties" - "Vorig woord gebruiken om suggestie te verbeteren" - - "Geen" - "Basis" - "Geavanceerd" - - "%s: opgeslagen" - "Houd een toets ingedrukt om diakritische tekens weer te geven (ø, ö, enzovoort)" - "Druk op elk gewenst moment op de toets Terug ↶ om het toetsenbord te sluiten" - "Toegang tot cijfers en symbolen" - "Blijf drukken op het meest linkse woord om het toe te voegen aan het woordenboek" - "Raak deze tip aan om door te gaan »" - "Raak dit punt aan om deze tip te sluiten en te beginnen met typen." - "Het toetsenbord wordt geopend wanneer u een tekstveld aanraakt" - "Blijf een toets aanraken om diakritische tekens weer te geven"\n"(ø, ö, ô, ó, enzovoort)" - "Schakel over naar cijfers en symbolen door deze toets aan te raken" - "Ga terug naar letters door deze toets nogmaals aan te raken" - "Blijf deze toets aanraken om toetsenbordinstellingen te wijzigen, zoals auto-aanvullen" - "Probeer het zelf!" - "Start" - "Volgende" - "Gereed" - "Verzenden" - "?123" - "123" - "ABC" - "Alt" - "Spraakinvoer" - "Spraakinvoer wordt momenteel niet ondersteund in uw taal, maar is wel beschikbaar in het Engels." - "Spraakinvoer is een experimentele functie met de spraakherkenning van het Google-netwerk." - "Als u spraakinvoer wilt uitschakelen, gaat u naar de toetsenbordinstellingen." - "Als u spraakinvoer gebruikt, drukt u op de microfoonknop of schuift u uw vinger over het schermtoetsenbord." - "Nu spreken" - "Wordt uitgevoerd" - - "Fout. Probeer het opnieuw." - "Kan geen verbinding maken" - "Fout, te lange spraakinvoer." - "Audioprobleem" - "Serverfout" - "Geen spraak te horen" - "Geen resultaten gevonden" - "Spraakgestuurd zoeken is niet geïnstalleerd" - "Hint:"" schuif over het toetsenbord om te spreken" - "Hint:"" spreek de volgende keer interpunctie uit, zoals \'period\' (punt), \'comma\' (komma) of \'question mark\' (vraagteken)." - "Annuleren" - "OK" - "Spraakinvoer" - - "Op hoofdtoetsenbord" - "Op toetsenbord voor symbolen" - "Uit" - - - "Microfoon op hoofdtoetsenbord" - "Microfoon op toetsenbord voor symbolen" - "Spraakinvoer is uitgeschakeld" - - "Automatisch verzenden na spraak" - "Drukt automatisch op Enter tijdens het zoeken of wanneer u naar het volgende veld wilt gaan." - "Het toetsenbord openen"\n\n"Raak een tekstveld aan." - "Het toetsenbord sluiten"\n\n"Druk op de terugtoets." - "Een toets blijven aanraken voor opties"\n\n"Toegang tot interpunctie en diakritische tekens." - "Toetsenbordinstellingen"\n\n"Blijf de toets \'""?123""\' aanraken." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Invoermethode selecteren" - "Invoertalen" - "Schuif uw vinger over de spatiebalk om de taal te wijzigen" - "← Raak nogmaals aan om op te slaan" - "Woordenboek beschikbaar" - "Gebruikersfeedback inschakelen." - "Help deze invoermethode te verbeteren door automatisch gebruiksstatistieken en crashmeldingen naar Google te verzenden." - "Raak aan om woorden te corrigeren" - "Raak ingevoerde woorden aan om ze te corrigeren" - "Toetsenbordthema" - "toetsenbord" - "spraak" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-nl/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-nl/strings_kp2a.xml deleted file mode 100644 index 0cf38faf..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-nl/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Kies een andere regel - Kies regel - Zoek voor regel met \"%1$s\" - Gebruiker - Wachtwoord - Referentie invoer instellingen - Automatisch-vullen ingeschakeld - Vult automatisch tekst in een leeg tekstveld in, als een Keepass2Android regel beschikbaar is voor het toetsenbord en als het veld overeenkomt met de opgeslagen veld hint-tekst. - Onthoud veld hint-teksten - Als een tekst veld gevuld is door handmatig een Keepass2Android waarde te kiezen, onthoud welke KP2A waarde was gebruikt voor het tekst veld. Het tekst veld word later herkend d.m.v. de hint-tekst. - Eenvoudig toetsenbord - Toon het eenvoudige toetsenbord als een KP2A regel beschikbaar is voor het toetsenbord. Wanneer uitgeschakeld, een venster word getoond als de Keepass2Android toets is ingedrukt. - Vergrendel de database na voltooiing - Als de Gedaan/Verzenden/Gaan toets op het eenvoudige toetsenbord is ingedrukt, vergrendel automatisch de database. - Wissel toetsenbord na voltooiing - Als de Gedaan/Verzenden/Gaan toets op het eenvoudige toetsenbord is ingedrukt, verwissel het toetsenbord. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-nn/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-nn/strings_kp2a.xml deleted file mode 100644 index 351dfe74..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-nn/strings_kp2a.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-pl/bools.xml b/src/java/KP2ASoftKeyboard2/java/res/values-pl/bools.xml deleted file mode 100644 index 897f4b3d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-pl/bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - true - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-pl/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-pl/donottranslate-altchars.xml deleted file mode 100644 index da6b5fd5..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-pl/donottranslate-altchars.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - ą - ę3 - ìíîï8 - ó9 - ùúûü7 - ś - ń - ć - ýÿ6 - źż - ł - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-pl/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-pl/strings.xml deleted file mode 100644 index 0782098b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-pl/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Klawiatura Keepass2Android" - "Ustawienia klawiatury Keepass2Android" - "Opcje wprowadzania" - "Wibracja przy naciśnięciu" - "Dźwięk przy naciśnięciu" - "Powiększ po naciśnięciu" - "Popraw błędy pisowni" - "Włącz poprawianie błędów wprowadzania" - "Błędy wprowadzania w orientacji poziomej" - "Włącz poprawianie błędów wprowadzania" - "Sugestie słów" - "Automatycznie poprawiaj poprzednie słowo" - "Sugestie słów" - "Ustawienia propozycji słów" - "Włącz autouzupełnianie podczas wpisywania" - "Autouzupełnianie" - "Zwiększ rozmiar pola tekstowego" - "Wyłącz sugestie słów w orientacji poziomej" - "Wstawiaj wielkie litery" - "Zamieniaj na wielką pierwszą literę zdania" - "Automatyczna interpunkcja" - - "Szybkie poprawki" - "Poprawia częste błędy wpisywania" - "Pokaż sugestie" - "Wyświetl sugerowane słowa podczas wpisywania" - "Autouzupełnianie" - "Spacja i znaki przestankowe wstawiają podświetlone słowo" - "Pokaż klawisz ustawień" - "Automatycznie" - "Zawsze pokazuj" - "Zawsze ukrywaj" - - - - "Sugestie dla bigramów" - "Używaj poprzedniego wyrazu, aby polepszyć sugestię" - - "Brak" - "Podstawowy" - "Zaawansowany" - - "%s : Zapisano" - "Przytrzymaj klawisz, aby wyświetlić znaki akcentowane (ą, ó itp.)" - "Naciśnij klawisz cofania ↶, aby zamknąć klawiaturę w dowolnym momencie" - "Przejdź do cyfr i symboli" - "Naciśnij i przytrzymaj słowo po lewej stronie w celu dodania go do słownika" - "Dotknij tej podpowiedzi, aby kontynuować »" - "Dotknij tutaj, aby zamknąć tę podpowiedź i zacząć pisać!" - "Klawiatura jest otwierana po każdym dotknięciu pola tekstowego." - "Dotknij i przytrzymaj klawisz, aby wyświetlić znaki akcentowane"\n"(ą, ę, ł, ó itd.)." - "Przełącz na cyfry i symbole, dotykając tego klawisza." - "Wróć do trybu liter, dotykając ponownie tego klawisza." - "Dotknij i przytrzymaj ten klawisz, aby zmienić ustawienia klawiatury, takie jak autouzupełnianie." - "Wypróbuj!" - "OK" - "Dalej" - "OK" - "Wyślij" - "?123" - "123" - "ABC" - "ALT" - "Wprowadzanie głosowe" - "Wprowadzanie głosowe obecnie nie jest obsługiwane w Twoim języku, ale działa w języku angielskim." - "Wprowadzanie głosowe to funkcja eksperymentalna wykorzystująca funkcję firmy Google umożliwiającą rozpoznawanie mowy przy użyciu sieci." - "Aby wyłączyć wprowadzanie głosowe, przejdź do ustawień klawiatury." - "Aby skorzystać z wprowadzania głosowego, naciśnij przycisk mikrofonu lub przesuń palcem po klawiaturze ekranowej." - "Mów teraz" - "W toku" - - "Błąd. Spróbuj ponownie." - "Nie można nawiązać połączenia" - "Błąd, zbyt długa wypowiedź." - "Problem z dźwiękiem" - "Błąd serwera" - "Nie wykryto mowy" - "Brak wyników" - "Wyszukiwanie głosowe nie jest zainstalowane" - "Wskazówka:"" przesuń palcem po klawiaturze, aby mówić." - "Wskazówka:"" następnym razem spróbuj wypowiadać nazwy znaków interpunkcyjnych: „kropka”, „przecinek” lub „pytajnik”." - "Anuluj" - "OK" - "Wprowadzanie głosowe" - - "Na klawiaturze głównej" - "Na klawiaturze z symbolami" - "Wyłączone" - - - "Mikrofon na klawiaturze głównej" - "Mikrofon na klawiaturze z symbolami" - "Wprowadzanie głosowe jest wyłączone" - - "Automatyczne przesyłanie uruchamiane głosem" - "Podczas wyszukiwania lub przechodzenia do następnego pola automatycznie naciśnij klawisz Enter." - "Otwórz klawiaturę"\n\n"Dotknij dowolnego pola tekstowego." - "Zamknij klawiaturę"\n\n"Naciśnij klawisz Wróć." - "Dotknij klawisza i przytrzymaj go, aby wyświetlić opcje"\n\n"Dostęp do znaków przestankowych i akcentowanych." - "Ustawienia klawiatury"\n\n"Dotknij klawisza ""?123"" i przytrzymaj go." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Wybierz sposób wprowadzania tekstu" - "Języki wprowadzania" - "Przesuń palcem po spacji, aby zmienić język" - "← Dotknij ponownie, aby zapisać" - "Słownik dostępny" - "Włącz przesyłanie opinii użytkownika" - "Pomóż ulepszyć edytor wprowadzania tekstu, automatycznie wysyłając do Google statystyki użycia i raporty o awariach." - "Popraw dotknięte słowo" - "Dotknięte słowo zostanie poprawione" - "Motyw klawiatury" - "klawiatura" - "głosowe" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-pl/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-pl/strings_kp2a.xml deleted file mode 100644 index e0cd7338..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-pl/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Wybierz inną pozycję - Wybierz pozycję - Wyszukaj pozycję z \"%1$s\" - Użytkownik - Hasło - Ustawienia wprowadzania poświadczeń - Automatyczne wprowadzanie włączone - Automatycznie wypełnij tekstem, jeżeli zostanie wprowadzone puste pole, gdy z klawiatury dostępny jest wpis Keepass2Android i istnieje pole, które odpowiada podpowiedzi pola. - Pamiętaj podpowiedź pola - Jeżeli pole zostało wypełnione ręcznie wybierając pole Keepass2Android, pamiętaj które pole zostało wprowadzone do pola. Pole jest później wykrywane ponownie przez jego podpowiedź. - Prosta klawiatura - Wyświetl prostą 1-wierszową klawiaturę jeżeli wpis jest dostępny dla klawiatury. Jeżeli wyłączone, zostanie wyświetlony dialog gdy przycisk Keepass2Android zostanie wciśnięty. - Zablokuj bazę danych po zakończeniu - Po naciśnięciu klawisza Gotowe/Wyślij/Idź na prostej klawiaturze 1-wierszowej, automatycznie zablokuj bazę danych. - Przełącz klawiaturę po zakończeniu - Po naciśnięciu przycisku Gotowe/Wyślij/Idź na prostej klawiaturze 1-wierszowej, przełącz klawiaturę. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-pt-rBR/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-pt-rBR/strings_kp2a.xml deleted file mode 100644 index 56f47c1f..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-pt-rBR/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Selecione outra entrada - Selecione uma entrada - Localizar entrada com \"%1$s\" - Usuário - Senha - Configurações de entrada de credencial - Auto-preenchimento habilitado - Preenche automaticamente um campo vazio quando selecionado, se uma entrada de Keepass2Android estiver disponível para o teclado e houver um valor que coincide com o texto de dica do campo. - Lembrar de textos de dica de campo - Se um campo de texto for preenchido manualmente selecionando um valor de Keepass2Android, lembrar qual valor foi inserido no campo de texto. O campo de texto é detectado novamente pelo seu texto de dica. - Teclado simples - Mostrar o teclado simples de 1 linha se uma entrada estiver disponível para o teclado. Se desabilitado, uma caixa de diálogo é mostrada quando é pressionada a tecla Keepass2Android. - Bloquear banco de dados quando concluído - Ao pressionar a tecla Feito/Enviar/Ir no teclado simples de 1 linha, bloquear automaticamente o banco de dados. - Trocar teclado quando concluído - Ao pressionar a tecla Feito/Enviar/Ir no teclado simples de 1 linha, trocar o teclado. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-pt-rPT/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-pt-rPT/donottranslate-altchars.xml deleted file mode 100644 index d3beafad..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-pt-rPT/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àáâãäåæ - 3èéêë - ìíîï8 - òóôõöœø9 - ùúûü7 - §ß - ñ - ç - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-pt-rPT/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-pt-rPT/strings.xml deleted file mode 100644 index 6e4a5e52..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-pt-rPT/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Teclado do Keepass2Android" - "Definições de teclado do Keepass2Android" - "Opções de introdução" - "Vibrar ao primir as teclas" - "Som ao premir as teclas" - "Mostrar popup ao premir tecla" - "Corrigir erros de escrita" - "Activar a correcção de erros de entrada" - "Erros de entrada na horizontal" - "Activar a correcção de erros de entrada" - "Sugestões de palavras" - "Corrigir automaticamente a palavra anterior" - "Sugestões de palavras" - "Definições de sugestão de palavras" - "Activar a conclusão automática durante a escrita" - "Conclusão automática" - "Aumentar o tamanho do campo de texto" - "Ocultar sugestões de palavras na vista horizontal" - "Letras maiúsculas automáticas" - "Colocar inicial maiúscula no início de uma frase" - "Pontuação automática" - - "Correcções rápidas" - "Corrige os erros de escrita comuns" - "Mostrar sugestões" - "Apresentar sugestões de palavras ao escrever" - "Conclusão automática" - "A barra de espaços e a pontuação inserem automaticamente uma palavra realçada" - "Mostrar tecla das definições" - "Automático" - "Mostrar sempre" - "Ocultar sempre" - - - - "Sugestões Bigram" - "Utilizar a palavra anterior para melhorar a sugestão" - - "Nenhum" - "Básico" - "Avançados" - - "%s: guardada" - "Mantenha uma tecla premida para ver os acentos (ø, ö, etc.)" - "Prima a tecla de retrocesso ↶ para fechar o teclado a qualquer momento" - "Aceder a números e símbolos" - "Prima e mantenha premida a palavra mais à esquerda para a adicionar ao dicionário" - "Toque nesta sugestão para continuar »" - "Toque aqui para fechar esta sugestão e começar a escrever!" - "O teclado abre quando tocar num campo de texto" - "Mantenha premida uma tecla para ver os acentos"\n"(ø, ö, ô, ó, etc.)" - "Mude para números e símbolos tocando nesta tecla" - "Regresse às letras tocando novamente nesta tecla" - "Mantenha premida esta tecla para alterar definições do teclado, tais como a conclusão automática" - "Experimente!" - "Ir" - "Seguinte" - "Feito" - "Enviar" - "?123" - "123" - "ABC" - "ALT" - "Entrada de voz" - "Actualmente, a entrada de voz não é suportada para o seu idioma, mas funciona em inglês." - "A entrada de voz é uma funcionalidade experimental que utiliza o reconhecimento de voz em rede da Google." - "Para desactivar a entrada de voz, aceda às definições do teclado." - "Para utilizar a entrada de voz, prima o botão do microfone ou deslize o dedo no teclado do ecrã." - "Falar agora" - "A executar" - - "Erro. Tente novamente." - "Não foi possível ligar" - "Erro, discurso demasiado longo." - "Problema de áudio" - "Erro no servidor" - "Nenhuma voz ouvida" - "Não foram encontradas correspondências" - "Pesquisa de voz não instalada" - "Sugestão:"" Deslize no teclado para falar" - "Sugestão:"" Da próxima vez, experimente dizer a pontuação como \"ponto final\", \"vírgula\" ou \"ponto de interrogação\"." - "Cancelar" - "OK" - "Entrada de voz" - - "No teclado principal" - "No teclado de símbolos" - "Desactivada" - - - "Microfone no teclado principal" - "Microfone no teclado de símbolos" - "A entrada de voz está desactivada" - - "Enviar automaticamente depois da voz" - "Premir automaticamente ENTER ao pesquisar ou avançar para o campo seguinte." - "Abra o teclado"\n\n"Toque em qualquer campo de texto." - "Feche o teclado"\n\n"Prima a tecla \"Anterior\"." - "Mantenha premida uma tecla para as opções"\n\n"Aceder a pontuação e acentos." - "Definições do teclado"\n\n"Mantenha premida a tecla ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Seleccionar método de entrada" - "Idiomas de entrada" - "Deslize o dedo pela barra de espaço para alterar o idioma" - "← Toque novamente para guardar" - "Dicionário disponível" - "Activar comentários do utilizador" - "Envie automaticamente estatísticas de utilização e relatórios de falhas para a Google e ajude-nos a melhor este editor de método de introdução." - "Tocar para corrigir palavras" - "Tocar nas palavras introduzidas para as corrigir" - "Tema do teclado" - "teclado" - "voz" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-pt-rPT/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-pt-rPT/strings_kp2a.xml deleted file mode 100644 index 67f16418..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-pt-rPT/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Selecionar outra entrada - Selecionar entrada - Procurar entrada com \"%1$s\" - Utilizador - Palavra-passe - Definições de introdução de cvredenciais - Auto-preenchimento ativado - Preenche automaticamente o texto ao inserir um campo vazio, se uma entrada de Keepass2Android estiver disponível para o teclado e existir um valor que coincida com a dica do campo. - Memorizar dicas de campo - Se um campo de texto for preenchido manualmente selecionando um valor Keepass2Android, lembra-se o valor que foi inserido no campo de texto. Posteriormente, o campo de texto é detetado novamente pelo seu texto de dica. - Teclado simples - Mostrar teclado simples de 1 linha, se existir uma entrada disponível para o teclado. Se desativada, será mostrada uma caixa de diálogo ao premir a tecla Keepass2Android. - Bloquear base de dados ao terminar - Ao premir a tecla Terminado/Enviar/Ir no teclado de 1 linha, bloquear base de dados automaticamente. - Trocar teclado ao terminar - Ao premir a tecla Terminado/Enviar/Ir no teclado de 1 linha, trocar de teclado. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-pt/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-pt/donottranslate-altchars.xml deleted file mode 100644 index d3beafad..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-pt/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àáâãäåæ - 3èéêë - ìíîï8 - òóôõöœø9 - ùúûü7 - §ß - ñ - ç - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-pt/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-pt/strings.xml deleted file mode 100644 index d9d71665..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-pt/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Teclado Keepass2Android" - "Configurações de teclado Keepass2Android" - "Opções de entrada" - "Vibrar ao tocar a tecla" - "Som ao tocar a tecla" - "Exibir pop-up ao digitar" - "Corrigir erros de digitação" - "Ativar a correção de erro de entrada" - "Erros de entrada de paisagem" - "Ativar a correção de erro de entrada" - "Sugestões de palavra" - "Corrigir automaticamente a palavra anterior" - "Sugestões de palavra" - "Configurações de sugestão de palavra" - "Ativar a conclusão automática durante a digitação" - "Conclusão automática" - "Aumentar o tamanho do arquivo de texto" - "Ocultar sugestões de palavra na visualização da paisagem" - "Capitaliz. automática" - "Colocar em maiúscula o início de uma frase" - "Pontuação automática" - - "Reparos rápidos" - "Corrige erros comuns de digitação" - "Mostrar sugestões" - "Exibir sugestões de palavras durante a digitação" - "Conclusão automática" - "Barra de espaço e pontuação inserem a palavra destacada" - "Mostrar tecla de config." - "Automático" - "Mostrar sempre" - "Sempre ocultar" - - - - "Sugestões de bigrama" - "Usar palavra anterior para melhorar a sugestão" - - "Nenhum" - "Básico" - "Avançado" - - "%s : Salvo" - "Segure uma tecla pressionada para ver os acentos (ø, ö, etc.)" - "Apertar a tecla voltar ↶ para fechar o teclado, em qualquer ponto" - "Acessar números e símbolos" - "Pressione e segure a palavra mais à esquerda para adicioná-la ao dicionário" - "Toque nesta dica para continuar »" - "Toque aqui para fechar esta dica e começar a digitar!" - "O teclado abre toda vez que você tocar em um campo de texto" - "Tocar e segurar uma tecla para visualizar acentos"\n"(ø, ö, ô, ó e assim por diante)" - "Alternar para números e símbolos tocando nessa tecla" - "Voltar às letras tocando novamente nessa tecla" - "Tocar e segurar esta tecla para alterar as configurações do teclado, como a conclusão automática" - "Experimente!" - "Ir" - "Avançar" - "Feito" - "Enviar" - "?123" - "123" - "ABC" - "ALT" - "Entrada de voz" - "A entrada de voz não é suportada no momento para o seu idioma, mas funciona em inglês." - "A entrada de voz é um recurso experimental que usa o reconhecimento de fala de rede do Google." - "Para desativar a entrada de voz, vá para as configurações do teclado." - "Para usar a entrada de voz, pressione o botão com o microfone ou deslize o dedo sobre o teclado na tela." - "Fale agora" - "Trabalhando" - - "Erro. Tente novamente." - "Não foi possível conectar" - "Erro, fala muito longa." - "Problema com o áudio" - "Erro do servidor" - "Nenhuma fala ouvida" - "Não há resultados compatíveis" - "A pesquisa por voz não está instalada" - "Dica:"" Deslize sobre o teclado para falar" - "Dica:"" Da próxima vez, tente falar o nome da pontuação como \"ponto\", \"vírgula\" ou \"ponto de interrogação\"." - "Cancelar" - "OK" - "Entrada de voz" - - "No teclado principal" - "No teclado de símbolos" - "Desativado" - - - "Microfone no teclado principal" - "Microfone no teclado de símbolos" - "Entrada de voz desativada" - - "Enviar automaticamente depois de falar" - "Pressione Enter automaticamente ao pesquisar ou ir para o próximo campo." - "Abra o teclado"\n\n"Toque em qualquer campo de texto." - "Feche o teclado"\n\n"Pressione a tecla Voltar." - "Toque e mantenha pressionada uma tecla para ver as opções"\n\n"Acesse a pontuação e as pronúncias." - "Configurações de teclado"\n\n"Toque e mantenha pressionada a tecla ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Selecionar método de entrada" - "Idiomas de entrada" - "Deslize o dedo na barra de espaços para alterar o idioma" - "← Toque novamente para salvar" - "Dicionário disponível" - "Ativar comentário do usuário" - "Ajude a melhorar este editor de método de entrada enviando automaticamente ao Google estatísticas de uso e relatórios de falhas." - "Tocar para corrigir" - "Toque as palavras para corrigi-las" - "Tema do teclado" - "teclado" - "voz" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-rm/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-rm/donottranslate-altchars.xml deleted file mode 100644 index f17026fa..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-rm/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àáâãäåæ - 3èéêë - ìíîï8 - òóöôõœø9 - ùúûü7 - §ß - ñ - ç - ýÿ6 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-rm/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-rm/strings.xml deleted file mode 100644 index fb5f443f..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-rm/strings.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - - - "Tastatura Keepass2Android" - "Parameters da la tastatura Keepass2Android" - - - "Vibrar cun smatgar in buttun" - "Tun cun smatgar in buttun" - "Pop-up cun smatgar ina tasta" - "Curreger sbagls d\'endataziun" - "Activar la correctura da sbagls d\'endataziun" - "Sbagls d\'endataziun en il format orizontal" - "Activar la correctura da sbagls d\'endataziun" - "Propostas da pleds" - "Curreger automaticamain il pled precedent" - "Propostas da pleds" - "Parameters da las propostas per pleds" - "Activar la cumplettaziun automatica durant l\'endataziun" - "Cumplettaziun automatica" - "Engrondir il champ da text" - "Zuppentar propostas da pleds en il format orizontal" - "Maiusclas automaticas" - "Scriver grond l\'entschatta da mintga frasa" - "Interpuncziun automatica" - - "Correcturas sveltas" - "Curregia sbagls da tippar currents" - "Mussar las propostas" - "Mussar pleds proponids durant l\'endataziun" - "Cumplettaziun automatica" - "Inserir auto. il pled marcà cun la tasta da vid/interpuncziun" - - - - - - - - - - - - "Propostas da tip bigram" - "Meglierar la proposta cun agid dal pled precedent" - - "Nagin" - "Simpel" - "Avanzà" - - "%s : Memorisà" - "\"Tegnair smatgà per mussar ils accents (à, é, etc.)\"" - "Smatgar ↶ per serrar la tastatura" - "Acceder a cifras e simbols" - "Smatgar ditg sin il pled dal tut a sanestra per l\'agiuntar al dicziunari" - "Tutgar quest commentari per cuntinuar »" - "\"Tutgar qua, per serrar quest commentari e cumenzar a tippar!\"" - "La tastatura vegn adina averta sche Vus tutgais in champ da text." - "\"""Tegnai smatgà ina tasta per mussar ils segns spezials"\n"(ø, ö, ô, ó etc.).""\"" - "Midai a numers e simbols cun tutgar quest buttun." - "Turnai a letras cun smatgar danovamain quest buttun." - "\"""Tegnai smatgà quest buttun per midar ils parameters da tastatura, sco p. ex. la cumplettaziun automatica.""\"" - "Empruvai!" - "Dai" - "Vinavant" - "Finì" - "Trametter" - "?123" - "123" - "ABC" - "ALT" - "Cumonds vocals" - "\"Cumonds vocals en Vossa lingua na vegnan actualmain betg sustegnids, ma la funcziun è disponibla per englais.\"" - "Ils cumonds vocals èn ina funcziunalitad experimentala che utilisescha la renconuschientscha vocala da rait da Google." - "\"Per deactivar ils cumonds vocals, avri ils parameters da tastatura.\"" - "\"Per utilisar ils cumonds vocals, smatgai il buttun dal microfon u stritgai cun il det sur la tastatura dal visur.\"" - "Ussa discurrer" - "Operaziun en progress" - - "Errur. Empruvai anc ina giada." - "Impussibel da connectar." - "Errur - discurrì memia ditg." - "Problem audio" - "Errur dal server" - "Betg udì ina frasa vocala" - "Betg chattà correspundenzas" - "Betg installà la tschertga vocala" - "Commentari:"" Stritgai cun il det sur la tastatura per discurrer." - "\"""Commentari:"" Empruvai la proxima giada d\'agiuntar segns d\'interpuncziun sco \"\"punct\"\", \"\"comma\"\" u \"\"segn da dumonda\"\" cun cumonds vocals.\"" - "Interrumper" - "OK" - "Cumonds vocals" - - "Sin la tastatura principala" - "Sin la tastatura da simbols" - "Deactivà" - - - "Microfon sin la tastatura principala" - "Microfon sin la tastatura da simbols" - "Ils cumonds vocals èn deactivads" - - "Trametter automaticamain suenter il cumond vocal" - "Smatgai sin la tasta enter sche Vus exequis ina tschertga u siglis al proxim champ." - "Avrir la tastatura"\n\n"Tutgai inqual champ da text." - "\"""Serrar la tastatura"\n\n"Smatgai il buttun \"\"Enavos\"\".\"" - "Tutgar e tegnair smatgà in buttun per acceder a las opziuns"\n\n"Accedi a segns d\'interpuncziun ed accents." - "Parameters da tastatura"\n\n"Tutgai e tegnai smatgà il buttun ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - - - "Linguas da cumonds vocals" - "Stritgar cun il det sur la tasta da vid per midar la lingua" - "← Tippar danovamain per memorisar" - "Dicziunari disponibel" - "Activar il feedback da l\'utilisader" - "Gidai a meglierar quest editur da la metoda d\'endataziun cun trametter automaticamain datas statisticas davart l\'utilisaziun e rapports da collaps a Google." - - - - - "Design da la tastatura" - "tastatura" - "vusch" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ro/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ro/strings.xml deleted file mode 100644 index 05f92d81..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ro/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Tastatură Keepass2Android" - "Setările tastaturii Keepass2Android" - "Opţiuni de introducere text" - "Vibrare la apăsarea tastei" - "Sunet la apăsarea tastei" - "Fereastră pop-up la apăsarea tastei" - "Corectaţi erorile de dactilografiere" - "Activaţi corectarea erorii de intrare" - "Erori de introducere în modul peisaj" - "Activaţi corectarea erorii de intrare" - "Sugestii de cuvinte" - "Corecţie automată a cuvântului anterior" - "Sugestii de cuvinte" - "Setările sugestiei de cuvinte" - "Activaţi completarea automată în timpul introducerii textului" - "Completare automată" - "Măriţi dimensiunea câmpului text" - "Ascundeţi sugestiile de cuvinte în vizualizarea de tip peisaj" - "Auto-capitalizare" - "Doresc să se scrie cu majusculă începutul propoziţiilor" - "Punctuaţie automată" - - "Remedieri rapide" - "Corectează greşelile introduse frecvent" - "Afişaţi sugestiile" - "Afişare sugestii de cuvinte în timpul introducerii de text" - "Completare automată" - "Bara de spaţiu şi punctuaţia inserează automat un cuvânt evidenţiat" - "Afişaţi tasta setări" - "Automat" - "Afişaţi întotdeauna" - "Ascundeţi întotdeauna" - - - - "Sugestii pentru cuvinte de două litere" - "Utilizaţi cuvântul anterior pentru a îmbunătăţi sugestia" - - "Niciunul" - "De bază" - "Avansat" - - "%s: salvat" - "Ţineţi o tastă apăsată pentru a vedea accentele (ø, ö, etc.)" - "Apăsaţi tasta Înapoi ↶ pentru a închide oricând tastatura" - "Accesaţi numere şi simboluri" - "Apăsaţi şi ţineţi apăsat pe cuvântul cel mai din stânga, pentru a-l adăuga la dicţionar" - "Atingeţi acest indiciu pentru a continua »" - "Atingeţi aici pentru a închide acest indiciu şi începeţi să introduceţi text!" - "Tastatura se deschide de fiecare dată când atingeţi un câmp text" - "Atingeţi şi ţineţi apăsată o tastă pentru a vizualiza accentele"\n"(ø, ö, ô, ó etc.)" - "Comutaţi între numere şi simboluri atingând această tastă" - "Reveniţi la litere prin atingerea acestei taste din nou" - "Apăsaţi şi ţineţi apăsată această tastă pentru a schimba setările tastaturii, cum ar fi completarea automată" - "Încercaţi!" - "OK" - "Înainte" - "Terminat" - "Trimiteţi" - "?123" - "123" - "ABC" - "ALT" - "Intrare voce" - "Intrarea vocală nu este acceptată în prezent pentru limba dvs., însă funcţionează în limba engleză." - "Intrarea vocală este o funcţie experimentală ce utilizează recunoaşterea vocală în reţea oferită de Google." - "Pentru a dezactiva intrarea vocală, accesaţi setările tastaturii." - "Pentru a utiliza intrarea vocală, apăsaţi butonul de microfon sau glisaţi degetul de-a lungul tastaturii de pe ecran." - "Vorbiţi acum" - "Se analizează" - - "Eroare. Încercaţi din nou." - "Conectare imposibilă" - "Eroare, discurs prea lung." - "Problemă audio" - "Eroare de server" - "Nu s-a auzit vorbirea" - "Nicio potrivire" - "Căutarea vocală nu este instalată" - "Indiciu:"" glisaţi de-a lungul tastaturii pentru a vorbi" - "Indiciu:"" data viitoare, încercaţi să rostiţi şi punctuaţia, cum ar fi „punct”, „virgulă”, sau „semn de întrebare”." - "Anulaţi" - "OK" - "Intrare voce" - - "Pe tastatura principală" - "Pe tastatura de simboluri" - "Dezactivat" - - - "Microfon pe tastatura principală" - "Microfon pe tastatura de simboluri" - "Intrarea vocală este dezactivată" - - "Trimitere automată după intrarea vocală" - "Apăsaţi automat tasta Enter atunci când se face o căutare sau când se trece la câmpul următor." - "Deschideţi tastatura"\n\n"Atingeţi orice câmp de text." - "Închideţi tastatura"\n\n"Apăsaţi pe tasta Înapoi." - "Atingeţi şi ţineţi apăsată o tastă pentru opţiuni"\n\n"Accesaţi punctuaţia şi accentele." - "Setările tastaturii"\n\n"Atingeţi şi ţineţi apăsată tasta ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Selectaţi metoda de introducere a textului" - "Selectaţi limba" - "Glisaţi degetul pe bara de spaţiu pentru a schimba limba" - "← Atingeţi din nou pentru a salva" - "Dicţionar disponibil" - "Activaţi feedback de la utilizatori" - "Ajutaţi la îmbunătăţirea acestui instrument de editare a metodelor de introducere a textului trimiţând în mod automat la Google statistici de utilizare şi rapoarte de blocare." - "Atingeţi pentru a corecta cuvintele" - "Atingeţi cuvintele introduse pentru a le corecta" - "Temă pentru tastatură" - "tastatură" - "voce" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ro/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ro/strings_kp2a.xml deleted file mode 100644 index df9110c5..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ro/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Selectaţi o altă înregistrare - Alegeți înregistrarea - Căutaţi înregistrarea \"%1$s\" - Utilizator - Parolă - Setări pentru introducerea datelor - Completarea-auto activată - Completează automat când un câmp gol este selectat, dacă o înregistrare Keepass2Android este disponibilă pentru tastatură și există o valoare care corespunde textului sugestie al câmpului. - Memorează textul de sugestie al câmpurilor - Dacă un câmp text este completat prin selectarea manuală a valorii Keepass2Android, memorează valoarea care era introdusă în câmpul de text. Câmpul de text este redetectat mai târziu de textul său de sugestie. - Tastatură simplă - Arată tastatura simplă de un rând dacă o înregistrare este disponibilă pentru tastatură. Dacă este dezactivat, se afișează un dialog când tasta Keepass2Android este apăsată. - Blochează baza de date când ai terminat - Când apeși tasta Done/Send/Go de pe tastatura simplă de un rând, blochează automat baza de date. - Comută tastatura când ai terminat - După ce ai apăsat tasta Gata/Trimite/Mergi de pe tastatura simplă cu un rând, comută tastatura. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ru/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ru/donottranslate-altchars.xml deleted file mode 100644 index 46241a62..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ru/donottranslate-altchars.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - àáâãäåæ - èéêë - ìíîï - òóôõöœø - ùúûü - §ß - ñ - ç - ýÿ - ё5 - ъ - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ru/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ru/strings.xml deleted file mode 100644 index 5cf85df5..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ru/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Клавиатура Keepass2Android" - "Настройки клавиатуры Keepass2Android" - "Параметры ввода" - "Виброотклик клавиш" - "Звук клавиш" - "Увеличение нажатых" - "Исправлять опечатки" - "Включить исправление ошибок при вводе" - "Ошибки при вводе в горизонтальной ориентации" - "Включить исправление ошибок при вводе" - "Предложение слов" - "Автоматически исправлять предыдущее слово" - "Предложение слов" - "Настройки подсказок" - "Включить автоматическое завершение слов при вводе" - "Автоматическое завершение" - "Увеличить размер текстового поля" - "Скрывать предложение слов в горизонтальной ориентации" - "Заглавные автоматически" - "Делать заглавной первую букву предложения" - "Автопунктуация" - - "Быстрое исправление" - "Исправлять распространенные опечатки" - "Предлагать варианты" - "Предлагать варианты слов во время ввода" - "Автозавершение" - "При нажатии пробела вставлять предложенное слово" - "Кнопка настроек" - "Автоматически" - "Всегда показывать" - "Всегда скрывать" - - - - "Биграммные подсказки" - "Используйте предыдущее слово, чтобы исправить подсказку" - - "Нет" - "Основной" - "Дополнительно" - - "%s: сохранено" - "Удерживайте клавишу, чтобы увидеть варианты с диакритическими знаками (ø, ö и т.д.)" - "Нажмите клавишу \"Назад\" ↶, чтобы закрыть клавиатуру в любой момент" - "Открыть цифры и символы" - "Нажмите и удерживайте слово слева, чтобы добавить его в словарь" - "Чтобы продолжить, нажмите на эту подсказку »" - "Нажмите здесь, чтобы закрыть подсказку и начать вводить текст." - "Клавиатура появляется автоматически при касании текстового поля" - "Нажмите и удерживайте клавишу для отображения вариантов с диакритическими знаками "\n"(ø, ö, ô, ó и т. п.)" - "Для переключения между вводом цифр и символов используйте эту клавишу" - "Чтобы вернуться к буквенной клавиатуре, снова нажмите на эту клавишу" - "Чтобы изменить настройки клавиатуры (такие как автозавершение), нажмите и удерживайте эту клавишу" - "Попробуйте!" - "Поиск" - "Далее" - "Готово" - "Отправить" - "?123" - "123" - "АБВ" - "ALT" - "Голосовой ввод" - "В настоящее время функция голосового ввода не поддерживает ваш язык, но вы можете пользоваться ей на английском." - "Голосовой ввод – экспериментальная функция на основе технологии сетевого распознавания речи от Google." - "Функция голосового ввода отключается в настройках клавиатуры." - "Чтобы использовать голосовой ввод, нажмите кнопку микрофона или проведите пальцем по экранной клавиатуре." - "Говорите" - "Обработка запроса" - - "Ошибка. Повторите попытку." - "Ошибка подключения" - "Слишком длинная фраза" - "Неполадка со звуком" - "Ошибка сервера" - "Речи не слышно" - "Соответствий не найдено" - "Голосовой поиск не установлен" - "Совет"". Проведите пальцем по клавиатуре для голосового ввода." - "Совет"". В следующий раз проговаривайте знаки препинания, например \"точка\", \"запятая\", \"вопросительный знак\"." - "Отмена" - "ОК" - "Голосовой ввод" - - "Значок на основной клавиатуре" - "Значок на клавиатуре символов" - "Отключить голосовой ввод" - - - "Значок на основной клавиатуре" - "Значок на клавиатуре символов" - "Голосовой ввод отключен" - - "Автоматически отправлять по окончании голосового ввода" - "Автоматически нажимать \"Ввод\" при поиске или переходе к следующему полю." - "Открытие клавиатуры"\n\n"Нажмите на любое текстовое поле." - "Закрытие клавиатуры"\n\n"Нажмите клавишу \"Назад\"." - "Нажмите и удерживайте клавишу для вызова параметров"\n\n"Доступ к пунктуационным и диакритическим знакам." - "Настройки клавиатуры"\n\n"Нажмите и удерживайте клавишу ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Выбрать способ ввода" - "Языки ввода" - "Для изменения языка проведите пальцем по пробелу" - "← Нажмите еще раз, чтобы сохранить" - "Доступен словарь" - "Включить отправку сведений" - "Помогите усовершенствовать редактор способа ввода, разрешив отправку статистики и отчетов о сбоях в Google." - "Исправление нажатием" - "Нажмите на слово, чтобы исправить его" - "Вид клавиатуры" - "клавиатура" - "голосовой" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-ru/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-ru/strings_kp2a.xml deleted file mode 100644 index 9f95c31a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-ru/strings_kp2a.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - Выбрать другую запись - Выбрать запись - Поиск записи с \"%1$s\" - Пользователь - Пароль - Параметры ввода учетных данных - Автозаполнение включено - Автоматически заполняет текст при входе в пустое поле, если запись Keepass2Android доступна для клавиатуры и есть значение, соответствующее тексту подсказки для поля. - Запоминать тексты подсказки для полей - При ручном заполнении текстового поля выбором значения Keepass2Android запоминает, какое значение было введено в текстовое поле. -Текстовое поле в дальнейшем будет определено по его тексту подсказки. - Простая клавиатура - Показать простую 1-рядную клавиатуру, если элемент доступен для клавиатуры. Если отключено, диалоговое окно отображается при нажатии клавиши Keepass2Android. - Блокировать базу данных после завершения - При нажатии клавиши Готово/Отправить/Перейти на простой 1-рядной клавиатуре, автоматически блокировать базу данных. - Сменить клавиатуру после завершения - При нажатии клавиши Готово/Отправить/Перейти на простой 1-рядной клавиатуре сменить клавиатуру. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-sk/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-sk/strings.xml deleted file mode 100644 index 15293d30..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-sk/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Klávesnica Keepass2Android" - "Nastavenia klávesnice Keepass2Android" - "Možnosti zadávania textu a údajov" - "Pri stlačení klávesu vibrovať" - "Zvuk pri stlačení klávesu" - "Zobraziť znaky pri stlačení klávesu" - "Opravovať preklepy" - "Povoliť opravu chýb vstupu" - "Chyby vstupu v zobrazení na šírku" - "Povoliť opravu chýb vstupu" - "Návrhy slov" - "Automaticky opraviť predchádzajúce slovo" - "Návrhy slov" - "Nastavenia návrhov slov" - "Povoliť automatické dokončovanie pri písaní" - "Automatické dokončovanie" - "Zväčšiť textové pole" - "Skryť návrhy slov v zobrazení na šírku" - "Veľké písmená automaticky" - "Začať vetu veľkým písmenom" - "Automatická interpunkcia" - - "Rýchle opravy" - "Opravuje najčastejšie chyby pri písaní" - "Zobraziť návrhy" - "Zobrazovať navrhované slová počas písania" - "Automatické dokončovanie" - "Stlačením medzerníka alebo interpunkčného znamienka automaticky vložíte zvýraznené slovo." - "Zobraziť kláves Nastavenia" - "Automaticky" - "Vždy zobrazovať" - "Vždy skrývať" - - - - "Návrh Bigram" - "Na zlepšenie návrhu použiť predchádzajúce slovo" - - "Žiadne" - "Základné" - "Rozšírené" - - "%s : Uložené" - "Podržaním klávesu zobrazíte diakritiku (á, ž atď.)" - "Stlačením klávesu Späť ↶ môžete klávesnicu kedykoľvek zavrieť." - "Prístup k číslam a symbolom" - "Stlačením a podržaním slova úplne vľavo toto slovo pridáte do slovníka." - "Ak chcete pokračovať, dotknite sa tohto tipu »" - "Ak chcete tento tip zavrieť a začať písať, dotknite sa tu." - "Klávesnica sa otvorí vždy, keď sa dotknete textového poľa." - "Pridržaním klávesu zobrazíte diakritiku"\n"(ó, ø, ö, ô apod.)" - "Ak chcete prepnúť na režim zadávania číslic a symbolov, dotknite sa tohto klávesu." - "Ak chcete prejsť späť na zadávanie písmen, dotknite sa znova tohto klávesu." - "Pridržaním tohto klávesu zmeníte nastavenia klávesnice (napr. automatické dokončovanie)." - "Skúste si to." - "Hľadať" - "Ďalej" - "Hotovo" - "Odoslať" - "?123" - "123" - "ABC" - "ALT" - "Hlasový vstup" - "Pre váš jazyk aktuálne nie je hlasový vstup podporovaný, ale funguje v angličtine." - "Hlasový vstup je experimentálna funkcia, ktorá využíva sieťové rozpoznanie reči spoločnosti Google." - "Ak chcete vypnúť hlasový vstup, prejdite na nastavenia klávesnice." - "Ak chcete použiť hlasový vstup, stlačte tlačidlo mikrofónu alebo prejdite prstom po klávesnici na obrazovke." - "Hovorte" - "Prebieha spracovanie" - - "Chyba. Skúste to znova." - "Pripojenie sa nepodarilo." - "Chyba, reč je príliš dlhá." - "Problém so zvukom" - "Chyba servera" - "Nebola zistená žiadna reč." - "Nenašli sa žiadne zhody" - "Hlasové vyhľadávanie nie je nainštalované" - "Tip:"" Ak chcete aktivovať hlasový vstup, prejdite prstom po klávesnici." - "Tip:"" Nabudúce skúste vysloviť interpunkciu, napríklad „bodka“, „čiarka“ alebo „otáznik“." - "Zrušiť" - "OK" - "Hlasový vstup" - - "Na hlavnej klávesnici" - "Na klávesnici so symbolmi" - "Vypnuté" - - - "Mikrofón na hlavnej klávesnici" - "Mikrofón na klávesnici so symbolmi" - "Hlasový vstup je zakázaný" - - "Po hlasovom vstupe automaticky odoslať" - "Pri vyhľadávaní alebo prechode na ďalšie pole automaticky stlačiť kláves Enter." - "Otvorte klávesnicu"\n\n"Dotknite sa ľubovoľného textového poľa." - "Zatvorte klávesnicu"\n\n"Stlačte tlačidlo Späť." - "Dotknutím a pridržaním klávesu zobrazíte možnosti"\n\n"Prístup k interpunkčným znamienkam a diakritike." - "Nastavenia klávesnice"\n\n"Dotknite sa klávesu ""?123"" a podržte ho." - ".com" - ".sk" - ".org" - ".net" - ".eu" - "Výber metódy vstupu" - "Jazyky vstupu" - "Jazyk môžete zmeniť posunutím prsta po medzerníku." - "← Ďalším dotykom slovo uložíte" - "K dispozícii je slovník" - "Povoliť spätnú väzbu od používateľov" - "Automatickým zasielaním štatistík o využívaní editora metódy vstupu a správ o jeho zlyhaní do služby Google môžete prispieť k vylepšeniu tohto nástroja." - "Dotykom opravíte slová" - "Dotykom zadaným slov ich opravíte" - "Motív klávesnice" - "klávesnica" - "hlasová" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-sk/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-sk/strings_kp2a.xml deleted file mode 100644 index cd580cc3..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-sk/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Vybrať ďalší záznam - Vybrať záznam - Vyhľadať záznam s \"%1$s\" - Používateľ - Heslo - Nastavenia zadávania údajov - Autom. dopĺňanie zap. - Pri vstupe do prázdneho políčka automaticky doplniť text, ak je dostupný záznam Keepass2Android pre klávesnicu a aj pole ktoré je v zhode s pomocným textom pre pole. - Pamätať si nápovedu poľa - Ak je textové pole vyplnené manuálnym vybraním hodnoty Keepass2Android, pamätať si hodnotu zadanú do poľa. Textové pole bude neskôr detegované podľa pomocného textu. - Jednoduchá klávesnica - Ak je dostupný záznam pre klávesnicu, zobraziť klávesnicu s 1 riadkom. Ak je vypnutá, pri stlačení tlač. Keepass2Android sa zobrazí dialóg. - Po skončení uzamknúť datab. - Automaticky uzamknúť databázu po stlačení tlač. Hotovo/Odoslať/Prejsť na 1-riadkovej klávesnici. - Po skončení prepnúť kláv. - Prepnúť klávesnicu naspäť po stlačení tlačidla Hotovo/Odoslať/Prejsť na 1-riadkovej klávesnici. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-sl/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-sl/strings.xml deleted file mode 100644 index 015ecf43..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-sl/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Tipkovnica Keepass2Android" - "Nastavitve tipkovnice Keepass2Android" - "Možnosti vnosa" - "Vibriranje ob pritisku tipke" - "Zvok ob pritisku tipke" - "Pojavno okno ob pritisku tipke" - "Popravljanje tipkarskih napak" - "Omogoči popravljanje napak pri vnosu" - "Napake pri vnosu v ležečem položaju" - "Omogoči popravljanje napak pri vnosu" - "Predlogi besed" - "Samodejno popravi prejšnjo besedo" - "Predlogi besed" - "Nastavitve za predlaganje besede" - "Omogoči samodokončanje med tipkanjem" - "Samodokončanje" - "Povečaj velikost besedilnega polja" - "Skrij predloge besed v ležečem pogledu" - "Samodejne velike začetnice" - "Napiši začetek stavka z veliko začetnico" - "Samodejno vstavljanje ločil" - - "Hitri popravki" - "Popravi pogoste tipkarske napake" - "Pokaži predloge" - "Prikaži predlagane besede med tipkanjem" - "Samodokončanje" - "Preslednica in ločila samodejno vnesejo označeno besedo" - "Pokaži tipko za nastavitve" - "Samodejno" - "Vedno pokaži" - "Vedno skrij" - - - - "Bigramni predlogi" - "Predlog izboljšaj s prejšnjo besedo" - - "Brez" - "Osnovni" - "Dodatno" - - "%s: shranjeno" - "Držite tipko, da prikažete poudarke (ø, ö itd.)" - "Kadar koli lahko pritisnete tipko »Nazaj« ↶, da zaprete tipkovnico" - "Dostop do številk in simbolov" - "Če besedo želite dodati v slovar, jo pridržite" - "Dotaknite se tega nasveta za nadaljevanje »" - "Dotaknite se tukaj, da zaprete nasvet in začnete tipkati!" - "Tipkovnice se odpre, kadar se dotaknete besedilnega polja" - "Za ogled poudarkov pridržite tipko"\n"(ø, ö, ô, ó itd.)" - "Preklopite na številke in simbole z dotikom te tipke" - "Na črke se vrnete, če se še enkrat dotaknete te tipke" - "Pridržite to tipko, če želite spremeniti nastavitve tipkovnice, npr. samodokončanje" - "Poskusite!" - "Pojdi" - "Naprej" - "Dokončano" - "Pošlji" - "?123" - "123" - "ABC" - "ALT" - "Glasovni vnos" - "Glasovni vnos trenutno ni podprt v vašem jeziku, deluje pa v angleščini." - "Glasovni vnos je poskusna funkcija, ki uporablja Googlovo omrežno prepoznavanje govora." - "Če želite izklopiti glasovni vnos, pojdite na nastavitve tipkovnice." - "Če želite uporabiti glasovni vnos, pritisnite gumb z mikrofonom ali podrsajte s prstom po zaslonski tipkovnici." - "Začnite govoriti" - "Obdelava" - - "Napaka. Poskusite znova." - "Povezava ni mogoča" - "Napaka, preveč govora." - "Težave z zvokom" - "Napaka strežnika" - "Govora se ne sliši" - "Ni rezultatov" - "Glasovno iskanje ni nameščeno" - "Nasvet:"" za govorjenje s prstom povlecite po tipkovnici" - "Nasvet:"" naslednjič poskusite ločila izgovoriti, npr. »pika«, »vejica« ali »vprašaj«." - "Prekliči" - "V redu" - "Glasovni vnos" - - "Na glavni tipkovnici" - "Na tipkovnici s simboli" - "Izklopljeno" - - - "Mikrofon na glavni tipkovnici" - "Mikrofon na tipkovnici s simboli" - "Glasovni vnos je onemogočen" - - "Samodejno pošlji po govoru" - "Samodejno pritisni »Enter« pri iskanju ali prehodu na naslednje polje." - "Odprite tipkovnico"\n\n"Dotaknite se katerega koli besedilnega polja." - "Zaprite tipkovnico"\n\n"Pritisnite tipko »Nazaj«." - "Pridržite tipko za ogled možnosti"\n\n"Dostop do ločil in poudarkov." - "Nastavitve "\n\n"Pridržite tipko ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Izberite način vnosa" - "Jeziki vnosa" - "Podrsajte s prstom po preslednici, da zamenjate jezik" - "← Še enkrat se dotaknite, da shranite" - "Slovar je na voljo" - "Omogoči povratne informacije uporabnikov" - "S samodejnim pošiljanjem statističnih podatkov o uporabi in poročil o zrušitvah Googlu nam lahko pomagate izboljšati urejevalnik načina vnosa." - "Dotaknite se besed in jih popravite" - "Dotaknite se vnesenih besed in jih popravite" - "Tema tipkovnice" - "tipkovnica" - "govor" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-sl/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-sl/strings_kp2a.xml deleted file mode 100644 index 80f2b8ce..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-sl/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Izberite drug vnos - Izberite vnos - Poišči vnos s/z \"%1$s\" - Uporabnik - Geslo - Nastavitve za vnos poveril - Sam. izpolnjevanje omog. - Samodejno izpolni besedilo, ko izbrano prazno polje, če je za tipkovnico na voljo vnos Keepass2Android in obstaja vrednost, ki se ujema z besedilom namiga polja. - Zap. si bes. namigov polj - Če je besedilo izpolnjeno z ročno izbiro vrednosti Keepass2Android, si zapomni, katera vrednost je bila vnesena v besedilno polje. To polje kasneje ponovno zazna njegovo besedilo namiga. - Preprosta tipkovnica - Prikaži preprosto enovrstično tipkovnico, če je za tipkovnico vnos na voljo vnos. Če je onemogočeno, se ob pritisku na tipko Keepass2Android prikaže pogovorno okno. - Zak. pod. zbirko, ko je kon. - Ob pritisku na tipko Končano/Pošlji/Pojdi na preprosti enovrstični tipkovnici samodejno zakleni podatkovno zbirko. - Pre. tipk., ko je končano - Ob pritisku na tipko Končano/Pošlji/Pojdi na preprosti enovrstični tipkovnici preklopi tipkovnico. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-sr/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-sr/strings.xml deleted file mode 100644 index 52f5376c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-sr/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android тастатура" - "Подешавања Keepass2Android тастатуре" - "Опције уноса" - "Вибрирај на притисак тастера" - "Звук на притисак тастера" - "Искачући прозор приликом притиска тастера" - "Исправи грешке у куцању" - "Омогућавање исправљања грешака током уноса" - "Грешке приликом уноса у положеном приказу" - "Омогућавање исправљања грешака током уноса" - "Предлагање речи" - "Аутоматско исправљање претходне речи" - "Предлагање речи" - "Подешавања за предлагање речи" - "Омогућавање аутоматског довршавања током уноса текста" - "Аутоматско довршавање" - "Повећај величину поља за текст" - "Скривање предложених речи у положеном приказу" - "Аутоматски унос великих слова" - "Унос великог слова на почетку реченице" - "Аутоматска интерпункција" - - "Брзе исправке" - "Исправља честе грешке у куцању" - "Прикажи предлоге" - "Приказивање предложених речи током уноса текста" - "Аутоматско довршавање" - "Означена реч се аутоматски умеће када притиснете размак или знак интерпункције" - "Прикажи тастер за подешавања" - "Аутоматски" - "Увек прикажи" - "Увек сакриј" - - - - "Bigram предлози" - "Користи претходну реч за побољшање предлога" - - "Ништа" - "Основни" - "Напредно" - - "%s : Сачувано" - "Држите тастер да бисте видели акценте (ø, ö итд.)" - "Притисните тастер „Назад“ ↶ у било ком тренутку да бисте затворили тастатуру" - "Приступите бројевима и симболима" - "Притисните и држите прву реч са леве стране да бисте је додали у речник" - "Додирните овај савет да бисте наставили »" - "Додирните овде да бисте затворили овај савет и почели да уносите текст!" - "Тастатура се отвара сваки пут када додирнете поље за текст" - "Додирните и држите тастер да бисте видели акценте"\n"(ø, ö, ô, ó, и тако даље)" - "Пређите на бројеве и симболе тако што ћете додирнути овај тастер" - "Вратите се на слова тако што ћете поново додирнути овај тастер" - "Додирните и држите овај тастер да бисте променили подешавања тастатуре, као што је аутоматско довршавање" - "Пробајте!" - "Иди" - "Следеће" - "Готово" - "Пошаљи" - "?123" - "123" - "ABC" - "ALT" - "Гласовни унос" - "Гласовни унос тренутно није подржан за ваш језик, али функционише на енглеском." - "Гласовни унос је експериментална функција која користи Google-ово мрежно препознавање гласа." - "Да бисте искључили гласовни унос, идите на подешавања тастатуре." - "Да бисте користили гласовни унос, притисните дугме за микрофон или превуците прст преко тастатуре на екрану." - "Говорите сада" - "Обрада" - - "Грешка. Покушајте поново." - "Повезивање није могуће" - "Грешка, говорите предуго." - "Проблем са звуком" - "Грешка сервера" - "Не чује се говор" - "Нема подударања" - "Гласовна претрага није инсталирана" - "Савет:"" Превуците прстом преко тастатуре за гласовни унос" - "Савет:"" Следећи пут покушајте да изговорите знакове интерпункције као што су „тачка“, „зарез“ или „знак питања“." - "Откажи" - "Потврди" - "Гласовни унос" - - "На главној тастатури" - "На тастатури са симболима" - "Искључено" - - - "Микрофон на главној тастатури" - "Микрофон на тастатури са симболима" - "Гласовни унос је онемогућен" - - "Аутоматски пошаљи после гласа" - "Аутоматски притисак на enter приликом претраге или преласка на следеће поље." - "Активирање тастатуре"\n\n"Додирните било које поље за текст." - "Затварање тастатуре"\n\n"Притисните тастер „Назад“." - "Додирните и држите тастер да би се приказале опције"\n\n"Приступ знаковима интерпункције и акцентима." - "Подешавања тастатуре"\n\n"Додирните и држите тастер ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Изаберите метод уноса" - "Језици за унос" - "Превуците прст преко тастера за размак да бисте променили језик" - "← Поново додирните да бисте сачували" - "Речник је доступан" - "Омогући повратну информацију корисника" - "Помозите да се побољша овај уређивач режима уноса тако што ће се аутоматски послати статистика о коришћењу и извештаји о грешкама компанији Google." - "Додирните да бисте исправили речи" - "Додирните унете речи да бисте их исправили" - "Тема тастатуре" - "тастатура" - "глас" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-sr/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-sr/strings_kp2a.xml deleted file mode 100644 index 0fb28b48..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-sr/strings_kp2a.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-sv/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-sv/donottranslate-altchars.xml deleted file mode 100644 index 4d26e6c4..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-sv/donottranslate-altchars.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - áàâąã - 3éèêëę€ - íìîï8 - óòôõ9 - úùûū7 - śšşß - ńñň - çćč - ýÿü6 - ðď - ř4 - ťþ5 - źžż - ł - w - æ - øœ - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-sv/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-sv/strings.xml deleted file mode 100644 index 85349c7a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-sv/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Androids tangentbord" - "Inställningar för Keepass2Androids tangentbord" - "Inmatningsalternativ" - "Vibrera vid tangenttryck" - "Knappljud" - "Popup vid knapptryck" - "Rätta skrivfel" - "Aktivera rättning av felaktiga inmatningar" - "Inmatningsfel i liggande vy" - "Aktivera rättning av felaktiga inmatningar" - "Ordförslag" - "Rätta automatiskt föregående ord" - "Ordförslag" - "Inställningar för ordförslag" - "Aktivera Komplettera automatiskt när du skriver" - "Komplettera automatiskt" - "Gör textfältet större" - "Dölj ordförslag i liggande vy" - "Automatiska versaler" - "Använd versal i början av mening" - "Automatiska punkter" - - "Snabba lösningar" - "Åtgärdar automatiskt vanliga misstag" - "Visa förslag" - "Visar ordförslag när du skriver" - "Komplettera automatiskt" - "Blanksteg och punkt infogar automatiskt markerat ord" - "Visa inställningsknapp" - "Automatiskt" - "Visa alltid" - "Dölj alltid" - - - - "Bigramförslag" - "Förbättra förslaget med föregående ord" - - "Inget" - "Grundinställningar" - "Avancerade" - - "%s: sparat" - "Håll nere en tangent om du vill visa accenter (ø, ö, etc.)" - "Tryck på Tillbaka ↶ om du vill stänga tangentbordet" - "För siffror och symboler" - "Tryck och håll ned ordet längst till vänster om du vill lägga till det i ordlistan" - "Tryck på tipset för att fortsätta »" - "Tryck här om du vill stänga tipset och börja skriva!" - "Tangentbordet öppnas när du trycker på ett textfält" - "Tryck och håll nere en tangent om du vill visa accenter"\n"(ø, ö, ô, ó och så vidare)" - "Växla till siffror och symboler med den här tangenten" - "Återvänd till bokstäver genom att trycka på tangenten en gång till" - "Tryck och håll ned tangenten om du vill ändra inställningarna för tangentbordet, till exempel Komplettera automatiskt" - "Testa!" - "Kör" - "Nästa" - "Färdig" - "Skicka" - "?123" - "123" - "ABC" - "ALT" - "Röstindata" - "Röstindata stöds inte på ditt språk än, men tjänsten fungerar på engelska." - "Röstinmatning är en funktion på experimentstadiet som använder Googles nätverks taligenkänning." - "Om du vill stänga av röstindata öppnar du inställningarna för tangentbordet." - "Om du vill använda röstinmatning trycker du på mikrofonknappen eller drar fingret över tangentbordet på skärmen." - "Tala nu" - "Fungerar" - - "Fel. Försök igen." - "Det gick inte att ansluta" - "Fel, för mycket tal." - "Ljudproblem" - "Serverfel" - "Hörde inget tal" - "Inga träffar hittades" - "Voice Search är inte installerat" - "Tips!"" Dra över tangentbordet om du vill tala" - "Tips!"" Nästa gång testar du att säga skiljetecknen, som \"punkt\", \"komma\" eller \"frågetecken\"." - "Avbryt" - "OK" - "Röstindata" - - "På huvudtangentbordet" - "På symboltangentbordet" - "Av" - - - "Mikrofon på huvudtangentbordet" - "Mikrofon på symboltangentbordet" - "Röstindata är inaktiverat" - - "Skicka automatiskt efter röst" - "Tryck automatiskt på retur vid sökning eller när du fortsätter till nästa fält." - "Öppna tangentbordet"\n\n"Tryck på ett textfält." - "Stäng tangentbordet"\n\n"Tryck på Tillbaka." - "Tryck länge på en tangent om du vill se alternativ"\n\n"Använda skiljetecken och accenter." - "Tangentbordsinställningar"\n\n"Tryck länge på tangenten""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Välj inmatningsmetod" - "Inmatningsspråk" - "Dra med fingret på blanksteg om du vill ändra språk" - "← Tryck igen för att spara" - "En ordlista är tillgänglig" - "Aktivera synpunkter från användare" - "Du kan hjälpa till att förbättra inmatningsmetoden genom att automatiskt skicka användningsstatistik och felrapporter till Google." - "Tryck om du vill korrigera ord" - "Tryck på skrivna ord om du vill korrigera dem" - "Tangentbordstema" - "tangentbord" - "röst" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-sv/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-sv/strings_kp2a.xml deleted file mode 100644 index 6c12cfd7..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-sv/strings_kp2a.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - Välj en annan post - Välj post - Sök efter post med \"%1$s\" - Användare - Lösenord - Auto-ifyllning aktiverad - Enkelt tangentbord - Lås databasen när jag är klar - Växla tangentbord när jag är klar - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-th/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-th/strings.xml deleted file mode 100644 index 099ddb48..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-th/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "แป้นพิมพ์ Keepass2Android" - "การตั้งค่าแป้นพิมพ์ Keepass2Android" - "ตัวเลือกการป้อนข้อมูล" - "สั่นเมื่อกดปุ่ม" - "ส่งเสียงเมื่อกดปุ่ม" - "ป๊อปอัปเมื่อกดแป้น" - "แก้ไขข้อผิดพลาดในการพิมพ์" - "เปิดการใช้งานการแก้ไขข้อผิดพลาดในการป้อนข้อมูล" - "ข้อผิดพลาดในการป้อนข้อมูลแนวนอน" - "เปิดการใช้งานการแก้ไขข้อผิดพลาดในการป้อนข้อมูล" - "การแนะนำคำ" - "แก้ไขคำก่อนหน้าอัตโนมัติ" - "การแนะนำคำ" - "การตั้งค่าการแนะนำคำ" - "เปิดใช้งานการเติมคำอัตโนมัติขณะพิมพ์" - "เติมคำอัตโนมัติ" - "เพิ่มขนาดฟิลด์ข้อความ" - "ซ่อนการแนะนำคำในมุมมองแนวนอน" - "ปรับเป็นตัวพิมพ์ใหญ่อัตโนมัติ" - "ใช้ตัวพิมพ์ใหญ่เมื่อขึ้นต้นประโยค" - "ใส่เครื่องหมายวรรคตอนอัตโนมัติ" - - "แก้ไขด่วน" - "แก้ไขข้อผิดพลาดในการพิมพ์ที่พบบ่อย" - "แสดงคำแนะนำ" - "แสดงคำที่แนะนำขณะพิมพ์" - "เติมคำอัตโนมัติ" - "ใช้แป้นเคาะวรรคและเครื่องหมายวรรคตอนเพื่อแทรกคำที่ไฮไลต์โดยอัตโนมัติ" - "แสดงแป้นการตั้งค่า" - "อัตโนมัติ" - "แสดงตลอดเวลา" - "ซ่อนตลอดเวลา" - - - - "คำแนะนำ Bigram" - "ใช้คำก่อนหน้านี้เพื่อปรับปรุงคำแนะนำ" - - "ไม่มี" - "พื้นฐาน" - "ขั้นสูง" - - "%s : บันทึกแล้ว" - "กดปุ่มค้างไว้เพื่อดูการออกเสียง (ø, ö, ฯลฯ)" - "กดปุ่ม ย้อนกลับ เพื่อปิดแป้นพิมพ์เมื่อใดก็ได้" - "เข้าถึงหมายเลขและสัญลักษณ์" - "กดคำซ้ายสุดค้างไว้เพื่อเพิ่มลงในพจนานุกรม" - "แตะคำแนะนำนี้เพื่อทำงานต่อ »" - "แตะที่นี่เพื่อปิดคำแนะนำนี้และเริ่มพิมพ์!" - "แป้นพิมพ์จะเปิดขึ้นเมื่อคุณแตะฟิลด์ข้อความ" - "แตะปุ่มค้างไว้เพื่อดูการออกเสียง"\n"(ø, ö, ô, ó และอื่นๆ)" - "เปลี่ยนเป็นตัวเลขและสัญลักษณ์เมื่อแตะปุ่มนี้" - "กลับไปที่ตัวอักษรโดยการแตะปุ่มนี้อีกครั้ง" - "แตะปุ่มนี้ค้างไว้เพื่อเปลี่ยนการตั้งค่าแป้นพิมพ์ เช่น การเติมคำอัตโนมัติ" - "ลองดูสิ!" - "ไป" - "ถัดไป" - "เสร็จสิ้น" - "ส่ง" - "?123" - "123" - "ABC" - "ALT" - "การป้อนข้อมูลด้วยเสียง" - "ขณะนี้การป้อนข้อมูลด้วยเสียงยังไม่ได้รับการสนับสนุนในภาษาของคุณ แต่ใช้ได้ในภาษาอังกฤษ" - "การป้อนข้อมูลด้วยเสียงเป็นคุณลักษณะทดลองที่ใช้การจดจำเสียงที่มีการสร้างเครือข่ายไว้ของ Google" - "หากต้องการปิดการป้อนข้อมูลด้วยเสียง ไปที่การตั้งค่าแป้นพิมพ์" - "หากต้องการใช้การป้อนข้อมูลด้วยเสียง กดปุ่มไมโครโฟนหรือเลื่อนนิ้วผ่านแป้นพิมพ์บนหน้าจอ" - "พูดได้เลย" - "กำลังทำงาน" - - "ข้อผิดพลาด โปรดลองอีกครั้ง" - "ไม่สามารถเชื่อมต่อได้" - "ข้อผิดพลาด คำพูดยาวเกินไป" - "ปัญหาด้านเสียง" - "ข้อผิดพลาดของเซิร์ฟเวอร์" - "ไม่ได้ยินเสียง" - "ไม่พบรายการที่ตรงกัน" - "ไม่ได้ติดตั้ง Voice Search" - "คำแนะนำ:"" กวาดผ่านแป้นพิมพ์เพื่อพูด" - "คำแนะนำ:"" ครั้งต่อไป ให้ลองเอ่ยถึงเครื่องหมายวรรคตอน เช่น \"มหัพภาค\" \"จุลภาค\" หรือ \"เครื่องหมายคำถาม\"" - "ยกเลิก" - "ตกลง" - "การป้อนข้อมูลด้วยเสียง" - - "บนแป้นพิมพ์หลัก" - "บนแป้นพิมพ์สัญลักษณ์" - "ปิด" - - - "ไมโครโฟนบนแป้นพิมพ์หลัก" - "ไมโครโฟนบนแป้นพิมพ์สัญลักษณ์" - "การป้อนข้อมูลด้วยเสียงถูกปิดการใช้งาน" - - "ส่งอัตโนมัติหลังบันทึกเสียง" - "กด Enter อัตโนมัติเมื่อค้นหาหรือไปที่ฟิลด์ถัดไป" - "เปิดแป้นพิมพ์"\n\n"แตะฟิลด์ข้อความใดก็ได้" - "ปิดแป้นพิมพ์"\n\n"กดปุ่ม ย้อนกลับ" - "แตะปุ่มค้างไว้เพื่อดูตัวเลือก "\n\n"เข้าถึงเครื่องหมายวรรคตอนและการออกเสียง" - "การตั้งค่าแป้นพิมพ์"\n\n"แตะปุ่ม ""?123""ค้างไว้" - ".com" - ".net" - ".org" - ".gov" - ".edu" - "เลือกวิธีการป้อนข้อมูล" - "ภาษาในการป้อนข้อมูล" - "เลื่อนนิ้วไปบนแป้นเคาะวรรคเพื่อเปลี่ยนภาษา" - "← แตะอีกครั้งเพื่อบันทึก" - "มีพจนานุกรมให้ใช้งาน" - "เปิดใช้งานการแสดงความคิดเห็นจากผู้ใช้" - "ช่วยปรับปรุงตัวแก้ไขวิธีการป้อนข้อมูลนี้โดยการส่งสถิติการใช้งานและรายงานการขัดข้องถึง Google โดยอัตโนมัติ" - "แตะเพื่อแก้ไขคำ" - "แตะคำที่ป้อนไว้เพื่อแก้ไข" - "ชุดรูปแบบแป้นพิมพ์" - "แป้นพิมพ์" - "เสียง" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-tl/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-tl/strings.xml deleted file mode 100644 index f3f39229..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-tl/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android keyboard" - "Mga setting ng Keepass2Android keyboard" - "Mga pagpipilian sa input" - "Mag-vibrate sa keypress" - "Tunog sa keypress" - "Popup sa keypress" - "Itama ang mga error sa pag-type" - "Paganahin ang pagtatama ng error sa pag-input" - "Mga error sa pag-input ng landscape" - "Paganahin ang pagtatama ng error sa pag-input" - "Mga suhestiyon ng salita" - "Awtomatikong itama ang nakaraang salita" - "Mga suhestiyon ng salita" - "Mga setting ng suhestiyon ng salita" - "Paganahin ang awtomatikong pagkumpleto habang nagta-type" - "Awtomatikong pagkumpleto" - "Taasan ang laki ng field ng teksto" - "Itago ang mga suhestiyon ng salita sa lanscape na view" - "Auto-capitalization" - "I-capitalize ang simula ng isang pangungusap" - "I-auto-punctuate" - - "Mga mabilisang pagsasaayos" - "Itinatama ang mga karaniwang na-type na mali" - "Ipakita ang mga suhestiyon" - "Ipakita ang mga iminumungkahing salita habang nagta-type" - "I-auto-complete" - "Awtomatikong ipinapasok ng spacebar at bantas ang naka-highlight na salita" - "Ipakita ang key ng mga setting" - "Awtomatiko" - "Palaging ipakita" - "Palaging itago" - - - - "Mga Suhestiyon na Bigram" - "Gamitin ang nakaraang salita upang pahusayin ang suhestiyon" - - "Wala" - "Batayan" - "Advanced" - - "%s : Na-save" - "Pinduting nang matagal ang isang key pababa upang makita ang mga accent (ø, ö, atbp.)" - "Pindutin ang key na bumalik ↶ upang isara ang keyboard anumang oras" - "I-access ang mga numero at simbolo" - "Pindutin nang matagal ang salita sa kaliwang bahagi upang idagdag ito sa diksyunaryo" - "Galawin ang pahiwatig na ito upang magpatuloy »" - "Galawin dito upang isara ang pahiwatig na ito at simulan ang pag-type!" - "Nagbubukas ang keyboard anumang oras na galawin mo ang field ng teksto" - "Galawin & pinduting nang matagal ang isang key upang tingnan ang mga accent"\n"(ø, ö, ô, ó, at iba pa)" - "Lumipat sa mga numero at simbolo sa pamamagitan ng paggalaw sa key na "" na ito" - "Pumunta muli sa mga titik sa pamamagitan ng muling paggalaw sa key na ito" - "Galawin & pinduting nang matagal ang key na ito upang baguhin ang mga setting ng keyboard, tulad ng awtomatikong pagkumpleto" - "Subukan ito!" - "Punta" - "Susunod" - "Tapos na" - "Ipadala" - "?123" - "123" - "ABC" - "ALT" - "Pag-input ng boses" - "Hindi kasalukuyang suportado ang pag-input ng boses para sa iyong wika, ngunit gumagana sa Ingles." - "Ang pag-input ng boses ay isang tampok na pang-eksperimento na gumagamit ng naka-network na pagkilala sa pananalita ng Google." - "Upang i-off ang pag-input ng boses, pumunta sa mga setting ng keyboard." - "Upang gumamit ng pag-input ng boses, pindutin ang pindutang microphone o i-slide ang iyong daliri sa screen keyboard." - "Magsalita ngayon" - "Nagtatrabaho" - - "Error. Pakisubukang muli." - "Hindi makakonekta" - "Error, masyadong maraming pananalita." - "Problema sa audio" - "Error sa server" - "Walang narinig na pananalita" - "Walang nakitang mga tugma" - "Hindi naka-install ang paghahanap ng boses" - "Pahiwatig:"" Mag-swipe sa keyboard upang magsalita" - "Pahiwatig:"" Sa susunod, subukang magsalita ng bantas tulad ng \"tuldok\", \"kuwit\", o \"tandang pananong\"." - "Kanselahin" - "OK" - "Pag-input ng boses" - - "I-on ang pangunahing keyboard" - "Sa mga simbolo ng keyboard" - "Naka-off" - - - "Mic sa pangunahing keyboard" - "Mic sa keyboard ng mga simbolo" - "Hindi pinagana ang pag-input ng boses" - - "Awtomatikong isumite pagkatapos ng boses" - "Awtomatikong pindutin ang enter kapag naghahanap o pupunta sa susunod na field." - "Buksan ang keyboard"\n\n"Galawin ang kahit anong field ng teksto." - "Isara ang keyboard"\n\n"Pindutin ang key na Bumalik." - "Galawin & pinduting nang matagal ang isang key para sa mga pagpipilian"\n\n"I-access ang bantas at mga accent." - "Mga setting ng keyboard"\n\n"Galawin & pindutin nang matagal ang ""?123"" na key." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Pumili ng paraan ng pag-input" - "Mag-input ng mga wika" - "I-slide ang daliri sa spacebar upang palitan ang wika" - "← Pinduting muli upang i-save" - "Available ang diksyunaryo" - "Paganahin ang feedback ng user" - "Tumulong na pahusayin ang editor ng paraan ng pag-input na ito sa pamamagitan ng awtomatikong pagpapadala ng mga istatistika ng paggamit at mga ulat ng crash sa Google." - "Pindutin upang itama ang mga salita" - "Pindutin ang mga ipinasok na salita upang itama ang mga ito" - "Tema ng Keyboard" - "keyboard" - "boses" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-tr/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-tr/donottranslate-altchars.xml deleted file mode 100644 index fb2419c1..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-tr/donottranslate-altchars.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - â - 3 - īįíìïîı8 - ōøõóòœôö9 - ūúùûü7 - śşßš - - čćç - 6 - ğ - \ No newline at end of file diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-tr/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-tr/strings.xml deleted file mode 100644 index cd7e28e4..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-tr/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android klavyesi" - "Keepass2Android klavye ayarları" - "Giriş seçenekleri" - "Tuşa basıldığında titret" - "Tuşa basıldığında ses çıkar" - "Tuşa basıldığında pop-up aç" - "Yazım hatalarını düzelt" - "Giriş hatası düzeltmeyi etkinleştir" - "Yatay giriş hataları" - "Giriş hatası düzeltmeyi etkinleştir" - "Kelime önerileri" - "Önceki kelimeyi otomatik olarak düzelt" - "Kelime önerileri" - "Kelime önerme ayarları" - "Yazarken otomatik tamamlamayı etkinleştir" - "Otomatik tamamlama" - "Metin alanı boyutunu artır" - "Yatay görünümde kelime önerilerini gizle" - "Otomatik olarak büyük harf yap" - "Cümlenin baş harfini büyük yap" - "Otomatik noktalama" - - "Hızlı onarımlar" - "Yaygın olarak yapılan yazım hatalarını düzeltir" - "Önerileri göster" - "Yazarken önerilen kelimeleri görüntüle" - "Otomatik tamamla" - "Boşluk tuşu ve noktalama vurgulanan kelimeyi otomatik ekler" - "Ayarları göster tuşu" - "Otomatik" - "Her zaman göster" - "Her zaman gizle" - - - - "Bigram Önerileri" - "Öneriyi geliştirmek için önceki kelimeyi kullanın" - - "Yok" - "Temel" - "Gelişmiş" - - "%s : Kaydedildi" - "Vurguları görmek için bir tuşu basılı tutun (ø, ö, v.b.)" - "Klavyeyi herhangi bir anda kapatmak için geri tuşuna ↶ basın" - "Sayılara ve simgelere erişin" - "Sözlüğe eklemek için en soldaki kelimeye basın ve basılı tutun" - "Devam etmek için bu ipucuna dokunun »" - "Bu ipucunu kapatmak için buraya dokunun ve yazmaya başlayın!" - "Bir metin alanına dokunduğunuzda klavye açılır" - "Vurguları görüntülemek için bir tuşa basın ve basılı tutun"\n"(ø, ö, ô, ó v.b.)" - "Bu tuşa dokunarak sayılar ve simgeler arasında geçiş yap" - "Bu tuşa tekrar dokunarak harflere geri dönün" - "Otomatik tamamlama gibi klavye ayarlarını değiştirmek için bu tuşa basın ve basılı tutun" - "Deneyin!" - "Git" - "İleri" - "Bitti" - "Gönder" - "?123" - "123" - "ABC" - "ALT" - "Ses girişi" - "Ses girişi, şu anda sizin diliniz için desteklenmiyor ama İngilizce dilinde kullanılabilir." - "Ses girişi, Google\'ın ağ bağlantılı ses tanıma işlevini kullanan deneysel bir özelliktir." - "Ses girişini kapatmak için klavye ayarlarına gidin." - "Ses girişini kullanmak için mikrofon düğmesine basın veya parmağınızı dokunmatik klavye üzerinde kaydırın." - "Şimdi konuşun" - "Çalışıyor" - - "Hata. Lütfen tekrar deneyin." - "Bağlanamadı" - "Hata, çok uzun konuşma." - "Ses sorunu" - "Sunucu hatası" - "Konuşma duyulmadı" - "Eşleşme bulunamadı" - "Sesle arama yüklenmedi" - "İpucu:"" Konuşmak için parmağınızı klavye üzerinde kaydırın" - "İpucu:"" Sonraki sefer, \"nokta\", \"virgül\" veya \"soru işareti\" gibi noktalama işaretlerini telaffuz etmeyi deneyin." - "İptal" - "Tamam" - "Ses girişi" - - "Ana klavyede" - "Simge klavyesinde" - "Kapalı" - - - "Ana klavyedeki mikrofon" - "Simge klavyesindeki mikrofon" - "Sesle giriş devre dışı bırakıldı" - - "Sesten sonra otomatik gönder" - "Arama yaparken veya bir sonraki alana giderken enter tuşuna otomatik olarak basın." - "Klavyeyi açın"\n\n"Herhangi bir metin alanına dokunun." - "Klavyeyi kapatın"\n\n"Geri tuşuna basın." - "Seçenekler için bir tuşa dokunun ve basılı tutun"\n\n"Noktalama ve vurgulama işaretlerine erişin." - "Klavye ayarları"\n\n"?123"" tuşuna dokunun ve basılı tutun." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Giriş yöntemini seç" - "Giriş dilleri" - "Dili değiştirmek için parmağınızı boşluk çubuğu üzerinde kaydırın" - "← Kaydetmek için tekrar dokunun" - "Sözlük kullanılabilir" - "Kullanıcı geri bildirimini etkinleştir" - "Kullanım istatistiklerini ve kilitlenme raporlarını Google\'a otomatik olarak göndererek bu giriş yöntemi düzenleyicisinin iyileştirilmesine yardımcı olun." - "Kelimeleri düzeltmek için dokunun" - "Düzeltmek için, girilen kelimelere dokunun" - "Klavye Teması" - "klavye" - "ses" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-tr/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-tr/strings_kp2a.xml deleted file mode 100644 index 8f47826c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-tr/strings_kp2a.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - Başka bir kayıt seçin - Kayıt seçin - Kayıt \"%1$s\" ile arama - Kullanıcı - Şifre - Giriş kimlik bilgisi ayarları - Otomatik doldurma etkin - Basit klavye - İşiniz bittiğinde veritabanı kilitlensin - İşiniz bittiğinde klavyeyi değiştir - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-uk/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-uk/strings.xml deleted file mode 100644 index e1d7b978..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-uk/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Клавіатура Keepass2Android" - "Налашт-ня клавіат. Keepass2Android" - "Парам. введення" - "Вібр при натиску клав." - "Звук при натиску клав." - "Сплив. при нат.клав." - "Виправ. помилки вводу" - "Увімкн. виправл. помилок вводу" - "Помилки альбомного вводу" - "Увімкн. виправл. помилок вводу" - "Пропозиції слів" - "Автоматично виправляти попереднє слово" - "Пропозиції слів" - "Налашт-ня пропозицій слів" - "Увімкн. автозаповнення при вводі" - "Автозаповнення" - "Збільш. розмір текст. поля" - "Сховати пропозиції слів в альбом. режимі" - "Авто викор. вел. літер" - "Поч. писати речення з великої літери" - "Авто пунктуація" - - "Шв. виправлення" - "Виправляє поширені помилки" - "Показати пропозиції" - "Відображати при вводі пропоновані слова" - "Автозаповнення" - "Пробіл і пунктуація автоматично вставляє виділене слово" - "Показ. клав. налашт." - "Автоматично" - "Завжди показ." - "Завжди ховати" - - - - "Двобуквені пропозиції" - "Викор. попер. слово для покращ. пропозиції" - - "Немає" - "Базовий" - "Розшир." - - "%s : збережено" - "Утр. клав. натис., щоб див. нагол. (ø, ö, тощо)" - "Натисн. клавішу назад ↶, щоб будь-коли закрити клавіат." - "Доступ до цифр і символів" - "Натисн. і утримуйте ліве крайнє слово, щоб додати його до словн." - "Натис. цю підказку для продовж.»" - "Натисн. тут, щоб закрити цю підказку і почати ввод." - "Клавіатура відривається при торканні текстового поля" - "Натис. і утрим. клавішу для перегл. наголосів"\n"(ø, ö, ô, ó тощо)" - "Перемк. до цифр і символів, натиснувши цю кнопку " - "Поверніться до літер, знову натиснувши цю клавішу" - "Натис. і утрим. клавішу, щоб змін. налашт-ння клавіат., такі як автозапов." - "Спробуйте!" - "Іти" - "Далі" - "Готово" - "Надісл." - "?123" - "123" - "ABC" - "ALT" - "Голос. ввід" - "Голос. ввід наразі не підтрим. для вашої мови, але можна користуватися англійською." - "Голос. ввід є експеремент. ф-цією, яка викор. мережеве розпізнавання голосу Google." - "Щоб вимкн. голос ввід, йдіть до налашт-нь клавіатури." - "Щоб викор. голос. ввід, натисніть кнопку мікрофона або пересуньте палець на екранній клавіатурі." - "Диктуйте" - "Працює" - - "Помилка. Спробуйте ще раз." - "Неможл. під\'єднатися" - "Помилка. Забагато продикт." - "Проблема з аудіо" - "Помилка сервера" - "Не чути диктув." - "Збігів не знайдено" - "Голос. пошук не встановлено" - "Підк:"" горт. на клавіат., щоб продикт." - "Підказка:"" наступного разу продикт. знаки пункт. такі як \"крапка\", \"кома\" чи \"знак пит\"." - "Скасувати" - "OK" - "Голос. ввід" - - "На осн. клавіатурі" - "Символьна клавіатура" - "Вимк." - - - "Miкр. на осн. клавіатурі" - "Miкр. на символ. клавіатурі" - "Голос. ввід вимкнуто" - - "Авто подав. після гол. пош." - "Автомат. натиск. enter під час пошуку або переходу до наступного поля." - "Відкр. клавіатуру"\n\n"Натисн. якесь текст. поле." - "Закрити клавіатуру"\n\n"Натисн. клавішу Назад." - "Натис.і утрим. клавішк для отрим. парам."\n\n"Доступ до пункт. та наголос." - "Налашт-ння клавіатури"\n\n"Натисн. і утрим. клавішу ""?123" - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Вибрати метод введення" - "Мови вводу" - "Переміст. палець на пробіл, щоб змін. мову" - "← Торкн. ще, щоб збер." - "Словник доступний" - "Увімк. відгуки корист." - "Допоможіть покращ. редактор методу введ., автомат. надсилаючи в Google статистику використ. та звіти про збої." - "Торкн., щоб виправ. слова" - "Торкн. введених слів, щоб виправити їх" - "Тема клавіатури" - "клавіатура" - "голос." - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-uk/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-uk/strings_kp2a.xml deleted file mode 100644 index 27ea1536..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-uk/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Вибрати інший запис - Вибрати запис - Пошук запису з \'%1$s\' - Користувач - Пароль - Налаштування вводу облікових даних - Автозаповнення увімкнуте - Автоматично заповнює текст, коли введене порожнє поле, якщо запис Keepass2Android є доступним для клавіатури та існує значення, що відповідає тексту підказки поля. - Запам\'ятати тексти підказки для полів - Якщо текстове поле заповнене значенням Keepass2Android, що було вибране вручну, запам\'ятовувати, яке значення було введене в текстове поле. Наступного разу це поле буде визначене за його текстом підказки. - Проста клавіатура - Показувати просту 1-рядну клавіатуру, якщо запис є доступним для клавіатури. Якщо вимкнено, відкривається діалог, коли натискається кнопка Keepass2Android. - Блокувати базу даних після завершення - При натисканні кнопки Виконано/Відправити/Перейти на простій 1-рядній клавіатурі, автоматично блокувати базу даних. - Змінити клавіатуру після завершення - При натисканні кнопки Виконано/Відправити/Перейти на простій 1-рядній клавіатурі, змінити клавіатуру. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-vi/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-vi/strings.xml deleted file mode 100644 index da4011e4..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-vi/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Bàn phím Keepass2Android" - "Cài đặt bàn phím Keepass2Android" - "Tùy chọn nhập" - "Rung khi nhấn phím" - "Âm thanh khi nhấn phím" - "Cửa sổ bật lên khi nhấn phím" - "Sửa lỗi đánh máy" - "Bật sửa lỗi nhập" - "Lỗi nhập theo khổ ngang" - "Bật sửa lỗi nhập" - "Đề xuất từ" - "Tự động sửa từ trước đó" - "Đề xuất từ" - "Cài đặt đề xuất từ" - "Bật tự động hoàn tất khi nhập" - "Tự động hoàn tất" - "Tăng kích cỡ trường văn bản" - "Ẩn đề xuất từ trong chế độ xem ngang" - "Tự động viết hoa" - "Viết hoa chữ cái đầu câu" - "Tự động chấm câu" - - "Sửa nhanh" - "Sửa lỗi nhập thông thường" - "Hiển thị đề xuất" - "Hiển thị từ được đề xuất khi nhập" - "Tự động hoàn tất" - "Dấu cách và dấu câu tự động chèn vào từ được đánh dấu" - "Hiển thị phím cài đặt" - "Tự động" - "Luôn hiển thị" - "Luôn ẩn" - - - - "Đề xuất Bigram" - "Sử dụng từ trước đó để cải tiến đề xuất" - - "Không" - "Cơ bản" - "Nâng cao" - - "%s : Đã lưu" - "Giữ phím xuống để xem dấu trọng âm (ø, ö, v.v...)" - "Nhấn phím quay lại ↶ để đóng bàn phím bất kỳ lúc nào" - "Truy cập các số và ký hiệu" - "Nhấn và giữ từ ngoài cùng bên trái để thêm từ đó vào từ điển" - "Chạm vào gợi ý này để tiếp tục »" - "Chạm vào đây để đóng gợi ý này và bắt đầu nhập" - "Bàn phím mở ra bất cứ khi nào bạn chạm vào trường văn bản" - "Chạm & giữ phím để xem dấu trọng âm"\n"(ø, ö, ô, ó, v.v...)" - "Chuyển sang số và ký hiệu bằng cách chạm vào phím này" - "Quay lại các chữ cái bằng cách chạm vào phím này lần nữa" - "Chạm & giữ phím này để thay đổi cài đặt bàn phím, như tự động hoàn tất" - "Hãy dùng thử!" - "Đến" - "Tiếp theo" - "Xong" - "Gửi" - "?123" - "123" - "ABC" - "ALT" - "Nhập liệu bằng giọng nói" - "Nhập liệu bằng giọng nói hiện không được hỗ trợ cho ngôn ngữ của bạn nhưng hoạt động với ngôn ngữ tiếng Anh." - "Nhập liệu bằng giọng nói là tính năng thử nghiệm sử dụng nhận dạng tiếng nói được kết nối mạng của Google." - "Để tắt nhập liệu bằng giọng nói, đi tới cài đặt bàn phím." - "Để sử dụng nhập liệu bằng giọng nói, hãy nhấn nút micrô hoặc trượt ngón tay trên bàn phím ảo." - "Xin mời nói" - "Đang hoạt động" - - "Lỗi. Vui lòng thử lại." - "Không thể kết nối" - "Lỗi, quá nhiều câu thoại." - "Sự cố âm thanh" - "Lỗi máy chủ" - "Không nghe thấy tiếng nói nào" - "Không tìm thấy kết quả phù hợp" - "Tìm kiếm bằng giọng nói chưa được cài đặt" - "Gợi ý:"" Trượt qua bàn phím để nói" - "Gợi ý:"" Lần tới, thử nói dấu câu như \"dấu chấm\", \"dấu phẩy\" hoặc \"dấu hỏi\"." - "Huỷ" - "OK" - "Nhập liệu bằng giọng nói" - - "Trên bàn phím chính" - "Trên bàn phím có biểu tượng" - "Tắt" - - - "Micrô trên bàn phím chính" - "Micrô trên bàn phím có biểu tượng" - "Nhập liệu bằng giọng nói đã bị vô hiệu hoá" - - "Tự động gửi sau thoại" - "Tự đông nhấn enter khi tìm kiếm hoặc đi tới trường tiếp theo." - "Mở bàn phím"\n\n"Chạm vào bất kỳ trường văn bản nào." - "Đóng bàn phím"\n\n"Nhấn phím Quay lại." - "Chạm & giữ phím cho các tuỳ chọn"\n\n"Truy cập dấu câu và dấu trọng âm." - "Cài đặt bàn phím"\n\n"Chạm & giữ phím ""?123""." - ".com" - ".net" - ".org" - ".gov" - ".edu" - "Chọn phương thức nhập" - "Ngôn ngữ nhập" - "Trượt ngón tay trên phím cách để thay đổi ngôn ngữ" - "← Chạm lại để lưu" - "Có sẵn từ điển" - "Bật phản hồi của người dùng" - "Giúp nâng cao trình chỉnh sửa phương thức nhập này bằng cách tự động gửi thống kê sử dụng và báo cáo sự cố cho Google." - "Chạm để sửa từ" - "Chạm các từ đã nhập để sửa" - "Chủ đề bàn phím" - "bàn phím" - "thoại" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-vi/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-vi/strings_kp2a.xml deleted file mode 100644 index 1563927a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-vi/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Chọn mục khác - Chọn mục - Tìm kiếm các mục nhập với \"%1$s\" - Người dùng - Mật mã - Cài đặt ủy quyền đăng nhập - Bật Tự động điền - Tự động điền văn bản khi một mục rỗng được nhập, nếu một mục Keepass2Android có sẵn cho bàn phím và có một giá trị phù hợp với văn bản gợi ý của mục đó. - Nhớ văn bản gợi ý của mục - Nếu một mục văn bản được nhập bằng cách chọn thủ công giá trị từ Keepass2Android, hãy nhớ rằng giá trị đó đã được nhập vô mục văn bản. Mục văn bản sau đó được phát hiện lại bởi văn bản gợi ý của nó. - Bàn phím đơn giản - Hiển thị bàn phím 1-hàng đơn giản nếu mục có sẵn cho bàn phím. Nếu vô hiệu hoá, một hộp thoại được hiển thị khi bấm phím Keepass2Android. - Khóa cơ sở dữ liệu chừng nào xong - Khi bấm phím Thực hiện/Gởi/Đi trên bàn phím 1-hàng đơn giản, tự động khóa cơ sở dữ liệu. - Chuyển đổi bàn phím chừng nào xong - Khi bấm phím Thực hiện/Gởi/Đi trên bàn phím 1-hàng đơn giản, chuyển đổi bàn phím. - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rCN/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-zh-rCN/donottranslate-altchars.xml deleted file mode 100644 index b3486f4e..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rCN/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àáâãäåæ - 3èéêë - 8ìíîï - 9òóôõöœø - 7ùúûü - §ß - ñ - ç - 6ýÿ - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rCN/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-zh-rCN/strings.xml deleted file mode 100644 index 936b05f1..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rCN/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android 键盘" - "Keepass2Android 键盘设置" - "输入选项" - "按键时振动" - "按键时播放音效" - "按键时显示弹出窗口" - "纠正输入错误" - "启用输入错误纠正功能" - "横向输入错误" - "启用输入错误纠正功能" - "字词建议" - "自动纠正前面的字词" - "字词建议" - "字词建议设置" - "输入时启用自动填写功能" - "自动完成" - "扩大文字字段" - "在横向视图中隐藏字词建议" - "自动大写" - "句首字母大写" - "自动加标点" - - "快速纠正" - "纠正常见的输入错误" - "显示建议" - "输入时启用联想提示" - "自动填写" - "按空格键和标点符号时自动插入突出显示的字词" - "显示设置键" - "自动" - "始终显示" - "始终隐藏" - - - - "双连词建议" - "使用以前的字词改进建议" - - "无" - "基本模式" - "高级" - - "%s:已保存" - "按住某个键可看到重音符号(例如 ø、ö 等)" - "随时可以通过按后退键 ↶ 关闭键盘" - "访问数字和符号" - "长按最左侧的字可将其添加到词典中" - "轻触此提示继续 »" - "轻触此处可关闭该提示,然后便可开始输入内容!" - "您可以随时通过触摸文字字段打开键盘" - "轻触并按住某个键可以查看重音符号"\n"(ø、ö、ô、ó 等)" - "轻触该键即可切换到数字和符号键盘" - "再次轻触该键即可返回字母键盘" - "触摸并按住该键可更改键盘设置,例如自动完成" - "试试吧!" - "开始" - "下一步" - "完成" - "发送" - "?123" - "123" - "ABC" - "ALT" - "语音输入" - "语音输入功能当前还不支持您的语言,您只能输入英语语音。" - "语音输入是一项试验性的功能,它采用了 Google 的网络语音识别功能。" - "要关闭语音输入功能,请转至键盘设置。" - "要使用语音输入,请按麦克风按钮或者在屏幕键盘上滑动手指。" - "请开始说话" - "正在处理" - - "出错,请重试。" - "无法连接" - "出错,语音过长。" - "音频问题" - "服务器出错" - "未听到语音" - "未找到匹配项" - "未安装语音搜索" - "提示:""在键盘上滑动手指可激活语音功能" - "提示:""稍后,请尝试使用语音输入标点符号,如“句号”、“逗号”或“问号”。" - "取消" - "确定" - "语音输入" - - "主键盘上" - "符号键盘上" - "关" - - - "主键盘上的麦克风" - "符号键盘上的麦克风" - "已停用语音输入" - - "语音结束后自动提交" - "搜索或转到下一字段时自动按 Enter。" - "打开键盘"\n\n"触摸任意文本字段。" - "关闭键盘"\n\n"按“返回”键。" - "触摸并按住选项键"\n\n"进入标点/重音符号界面。" - "键盘设置"\n\n"触摸并按住 ""?123"" 键。" - ".com" - ".net" - ".org" - ".gov" - ".edu" - "选择输入法" - "输入语言" - "在空格键上滑动手指可更改语言" - "← 再次触摸即可保存" - "提供字典" - "启用用户反馈" - "自动向 Google 发送使用情况统计信息和崩溃报告,帮助改进该输入法编辑器。" - "触摸以更正字词" - "触摸所输入字词以进行更正" - "键盘主题" - "键盘" - "语音" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rCN/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-zh-rCN/strings_kp2a.xml deleted file mode 100644 index ad92a758..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rCN/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - 选择另一条目 - 选择条目 - 搜索带有「%1$s」的条目 - 用户名 - 密码 - 输入凭据设置 - 自动填充已启用 - 当进入一个空白字段时自动填充文字,如果 Keepass2Android 是激活键盘,且有一个相匹配字段的提示文本。 - 记忆字段提示文本 - 如果通过手动选择 Keepass2Android 填充字段,请记住哪个字段在对应字段中输入。该字段是后来由其提示文本重新检测到。 - 简单键盘 - 当一个条目是可用时显示单行键盘。如果禁用,当按 Keepass2Android 键时则是显示一个对话框。 - 完成时锁定数据库 - 当点击单行键盘上的完成或发送键时,自动锁定数据库。 - 完成后切换键盘 - 当点击单行键盘上的完成或发送键时,自动切换键盘。 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rTW/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values-zh-rTW/donottranslate-altchars.xml deleted file mode 100644 index b3486f4e..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rTW/donottranslate-altchars.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - àáâãäåæ - 3èéêë - 8ìíîï - 9òóôõöœø - 7ùúûü - §ß - ñ - ç - 6ýÿ - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rTW/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values-zh-rTW/strings.xml deleted file mode 100644 index 7ebfc668..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rTW/strings.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - "Keepass2Android 鍵盤" - "Keepass2Android 鍵盤設定" - "輸入選項" - "按鍵時震動" - "按鍵時播放音效" - "按鍵時顯示彈出式視窗" - "修正輸入錯誤" - "啟用輸入錯誤修正功能" - "橫向輸入錯誤" - "啟用輸入錯誤修正功能" - "字詞建議" - "自動修正前一個字詞" - "字詞建議" - "字詞建議設定" - "輸入時啟用自動完成" - "自動完成" - "放大文字欄位大小" - "在橫向檢視模式中隱藏字詞建議" - "自動大寫" - "句首字母大寫" - "自動標點" - - "快速修正" - "修正一般打字錯誤" - "顯示建議" - "打字時顯示建議字詞" - "自動完成" - "在反白顯示的字詞處自動插入空白鍵和標點符號鍵盤" - "顯示設定金鑰" - "自動" - "一律顯示" - "永遠隱藏" - - - - "雙連詞建議" - "根據前一個字詞自動找出更適合的建議" - - "無" - "基本模式" - "進階模式" - - "%s:已儲存" - "按住按鍵可查看重音符號 (ø、ö 等)" - "隨時可以透過按後退鍵 ↶ 關閉鍵盤" - "使用數字和符號" - "按住最左邊的字詞,將其新增到字典中" - "輕觸此提示繼續 »" - "輕觸此處以關閉提示,並開始打字!" - "輕觸文字欄位時即會開啟鍵盤" - "輕觸並按住某個鍵即可查看聲調"\n"(ø、ö、ô、ó 等)" - "輕觸此鍵即可切換到數字和符號鍵盤" - "再次輕觸此鍵即可返回到字母鍵盤" - "輕觸並按住此鍵即可變更鍵盤設定,例如自動完成" - "試試看!" - "開始" - "繼續" - "完成" - "傳送" - "?123" - "123" - "ABC" - "ALT" - "語音輸入" - "語音輸入目前不支援您的語言,但是可以辨識英文。" - "語音輸入這項實驗功能運用了 Google 的網路語音辨識系統。" - "請前往鍵盤設定來關閉語音輸入。" - "如要使用語音輸入,按下 [麥克風] 按鈕,或將手指滑過螢幕小鍵盤即可。" - "請說話" - "辨識中" - - "發生錯誤,請再試一次。" - "無法連線" - "錯誤:語音內容過長。" - "音訊問題" - "伺服器錯誤" - "沒有聽到任何聲音" - "找不到相符的項目" - "未安裝語音搜尋" - "提示:""滑過鍵盤即可說話" - "提示:""下次可嘗試說出標點符號,例如「句號」、「逗號」或「問號」。" - "取消" - "確定" - "語音輸入" - - "於主鍵盤" - "符號鍵盤上" - "關閉" - - - "主鍵盤上的麥克風" - "符號鍵盤上的麥克風" - "已停用語音輸入" - - "說話後自動提交" - "搜尋或前往下一個欄位時自動按下輸入。" - "開啟鍵盤"\n\n"輕觸任何文字欄位。" - "關閉鍵盤"\n\n"按下 Back 鍵。" - \n"輕觸並按住按鍵開啟選項"\n"輸入標點與輕重音。" - "鍵盤設定"\n\n"輕觸並按住 ""?123"" 鍵。" - ".com" - ".net" - ".org" - ".gov" - ".edu" - "選取輸入法" - "輸入語言" - "以手指在空白鍵上滑動可變更語言" - "← 再次輕觸即可儲存" - "可使用字典" - "啟用使用者意見回饋" - "自動將使用統計資料和當機報告傳送給 Google,協助改善這個輸入法編輯器。" - "輕觸此處可修正字詞" - "輕觸輸入的字詞即可加以修正" - "鍵盤主題" - "鍵盤" - "語音" - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rTW/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values-zh-rTW/strings_kp2a.xml deleted file mode 100644 index 2bccb9b5..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values-zh-rTW/strings_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - 請選擇另一輸入項 - 選擇輸入項 - 搜索有\"%1$s\"的輸入項 - 使用者 - 密碼 - 憑證輸入設置 - 自動輸入啟用 - 當選擇空白欄位時,若有可用鍵盤的 Keepass2Android 輸入項且當值符合欄位關鍵字,自動填入文字。 - 記得欄位提示文字 - 如果通過手動選擇 Keepass2Android 值填充文字欄位,請記住哪個值被輸入到文字欄位。文字欄位將由其提示文字重新檢偵測。 - 簡易鍵盤 - 若輸入項可使用鍵盤則顯示簡單的 1 行鍵盤。若禁用,按下 Keepass2Android 鍵會顯示一個對話方塊。 - 完成後鎖定資料庫 - 使用簡單的 1 行鍵盤上按 完成/發送/好 鍵後,自動鎖定資料庫。 - 完成後切換鍵盤 - 使用簡單的 1 行鍵盤上按做/發送/好 鍵,切換鍵盤。 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/attrs.xml b/src/java/KP2ASoftKeyboard2/java/res/values/attrs.xml deleted file mode 100644 index 995373e8..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/attrs.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/bools.xml b/src/java/KP2ASoftKeyboard2/java/res/values/bools.xml deleted file mode 100644 index 5a24e4c6..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/bools.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - true - - false - - true - true - - true - true - true - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/colors.xml b/src/java/KP2ASoftKeyboard2/java/res/values/colors.xml deleted file mode 100644 index 0161589a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/colors.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - #FFFFFFFF - #FFFCAE00 - #FFFCAE00 - #00000000 - #80000000 - #80FFFFFF - #FFC0C0C0 - #A0000000 - #FFFFFFFF - #FFFFFFFF - #FF000000 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/config.xml b/src/java/KP2ASoftKeyboard2/java/res/values/config.xml deleted file mode 100644 index edb6cd84..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/config.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - 0 - 10 - 0 - 70 - 0 - 100 - 400 - 50 - 400 - 800 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/dimens.xml b/src/java/KP2ASoftKeyboard2/java/res/values/dimens.xml deleted file mode 100644 index 86eb55f0..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/dimens.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - 49.109985dip - 5.0dip - 52.0dip - 9.599976dip - 22.0dip - 42.0dip - 63.0dip - 4.0dip - 423.32812dip - 22.00998sp - 14.049988sp - 40.0sp - 0.0dip - 80.0sp - 88.47998dip - -52.0dip - 8.0dip - -8.0dip - 48.0dip - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/donottranslate-altchars.xml b/src/java/KP2ASoftKeyboard2/java/res/values/donottranslate-altchars.xml deleted file mode 100644 index bba7282c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/donottranslate-altchars.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - àáâãäåæ - èéêë - ìíîï - òóôõöœø - ùúûü - §ß - ñ - ç - ýÿ - 1 - 2 - - 4 - 5 - - - - 0 - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/donottranslate.xml b/src/java/KP2ASoftKeyboard2/java/res/values/donottranslate.xml deleted file mode 100644 index 93660992..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/donottranslate.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - .\u0009\u0020,;:!?\n()[]*&@{}/<>_+=|\u0022 - - .,!?) - - !?,\u0022\u0027:()-/@_ - - - - 0 - - 1 - - 2 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/durations.xml b/src/java/KP2ASoftKeyboard2/java/res/values/durations.xml deleted file mode 100644 index 92af68e3..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/durations.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - 40 - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/keycodes.xml b/src/java/KP2ASoftKeyboard2/java/res/values/keycodes.xml deleted file mode 100644 index 3dd1f36f..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/keycodes.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - 9 - 10 - 32 - -1 - -2 - -5 - - -100 - -102 - -103 - -200 - -201 - -202 - -203 - -204 - -205 - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/strings.xml b/src/java/KP2ASoftKeyboard2/java/res/values/strings.xml deleted file mode 100644 index 314dd261..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/strings.xml +++ /dev/null @@ -1,379 +0,0 @@ - - - - - Keepass2Android keyboard - - Android keyboard settings - - Input options - - - Vibrate on keypress - - - Sound on keypress - - - Popup on keypress - - - Correct typing errors - - - Enable input error correction - - - Landscape input errors - - - Enable input error correction - - - Word suggestions - - - Automatically correct the previous word - - - Word suggestions - - Word suggestion settings - - Enable auto completion while typing - - - Auto completion - - - Increase text field size - - Hide word suggestions in landscape view - - - Auto-capitalization - - Capitalize the start of a sentence - - Auto-punctuate - - - - - Quick fixes - - Corrects commonly typed mistakes - - - Show suggestions - - Display suggested words while typing - - - Auto-complete - - Spacebar and punctuation automatically insert highlighted word - - - Show settings key - - - @string/settings_key_mode_auto - @string/settings_key_mode_always_show - @string/settings_key_mode_always_hide - - - Automatic - - Always show - - Always hide - - - @string/settings_key_mode_auto_name - @string/settings_key_mode_always_show_name - @string/settings_key_mode_always_hide_name - - - - Bigram Suggestions - - Use previous word to improve suggestion - - - - None - Basic - Advanced - - - - 0 - - 1 - - 2 - - - @string/prediction_none - @string/prediction_basic - @string/prediction_full - - - - %s : Saved - - - Hold a key down to see accents (ø, ö, etc.) - - Press the back key \u21B6 to close the keyboard at any point - - Access numbers and symbols - - Press and hold the left-most word to add it to the dictionary - - - - Touch this hint to continue » - - - Touch here to close this hint and start typing! - - - The keyboard opens any time you touch a text field - - - Touch & hold a key to view accents\n(ø, ö, ô, ó, and so on) - - - - Switch to numbers and symbols by touching this key - - - Go back to letters by touching this key again - - - Touch & hold this key to change keyboard settings, like auto complete - - - Try it! - - - - Go - - Next - - Done - - Send - - \?123 - - 123 - - ABC - - ALT - - - - - Voice input - - - Voice input is not currently supported for your language, but does work in English. - - - Voice input is an experimental feature using Google\'s networked speech recognition. - - - To turn off voice input, go to keyboard settings. - - - To use voice input, press the microphone button or slide your finger across the on-screen keyboard. - - - Speak now - - - Working - - - - - - Error. Please try again. - - - Couldn\'t connect - - - Error, too much speech. - - - Audio problem - - - Server error - - - No speech heard - - - No matches found - - - Voice search not installed - - - Hint: Swipe across keyboard to speak - - - Hint: Next time, try speaking punctuation like \"period\", \"comma\", or \"question mark\". - - - Cancel - - - OK - - - Voice input - - - - On main keyboard - On symbols keyboard - Off - - - - 0 - - 1 - - 2 - - - @string/voice_mode_main - @string/voice_mode_symbols - @string/voice_mode_off - - - - - Mic on main keyboard - Mic on symbols keyboard - Voice input is disabled - - - - Auto submit after voice - - - Automatically press enter when searching or going to the next field. - - - - Open the keyboard\n\nTouch any text field. - - - Close the keyboard\n\nPress the Back key. - - - Touch \u0026 hold a key for options\n\nAccess punctuation and accents. - - - Keyboard settings\n\nTouch \u0026 hold the \?123\ key. - - - ".com" - - ".net" - - ".org" - - ".gov" - - ".edu" - - - Select input method - - - Input languages - - Slide finger on spacebar to change language - - - \u2190 Touch again to save - - - Dictionary available - - - Enable user feedback - - Help improve this input method editor by automatically sending usage statistics and crash reports to Google. - - Touch to correct words - - Touch entered words to correct them - - - Keyboard Theme - Basic - Basic (High Contrast) - Stone (bold) - Stone (normal) - Gingerbread - - - @string/layout_basic - @string/layout_high_contrast - @string/layout_stone_normal - @string/layout_stone_bold - @string/layout_gingerbread - - - - 0 - 1 - 2 - 3 - 4 - - - keyboard - voice - - - Android keyboard Debug settings - Debug Mode - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/strings_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/values/strings_kp2a.xml deleted file mode 100644 index b6303c0a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/strings_kp2a.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - Select another entry - Select entry - Search for entry with "%1$s" - User - Password - - Credential input settings - Auto-Fill enabled - Automatically fill in text when an empty field is entered, if a Keepass2Android entry is available for the keyboard and there is a value which matches the field\'s hint text. - Remember field hint texts - If a text field is filled by manually selecting the Keepass2Android value, remember which value was entered into the text field. The text field is later redetected by its hint text. - Simple keyboard - Show the simple 1-row keyboard if an entry is available for the keyboard. If disabled, a dialog is shown when the Keepass2Android key is pressed. - - Lock database when done - When pressing the Done/Send/Go key on the simple 1-row keyboard, automatically lock the database. - - Switch keyboard when done - When pressing the Done/Send/Go key on the simple 1-row keyboard, switch the keyboard. - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/values/styles.xml b/src/java/KP2ASoftKeyboard2/java/res/values/styles.xml deleted file mode 100644 index 0372b07c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/values/styles.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-da/kbd_qwerty.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-da/kbd_qwerty.xml deleted file mode 100644 index bec5e04e..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-da/kbd_qwerty.xml +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-da/kbd_qwerty_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-da/kbd_qwerty_black.xml deleted file mode 100644 index c25c23d5..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-da/kbd_qwerty_black.xml +++ /dev/null @@ -1,478 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-de/kbd_qwerty.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-de/kbd_qwerty.xml deleted file mode 100644 index 2c281a68..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-de/kbd_qwerty.xml +++ /dev/null @@ -1,520 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-de/kbd_qwerty_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-de/kbd_qwerty_black.xml deleted file mode 100644 index f8143c44..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-de/kbd_qwerty_black.xml +++ /dev/null @@ -1,457 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-fr/kbd_qwerty.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-fr/kbd_qwerty.xml deleted file mode 100644 index fb65db8b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-fr/kbd_qwerty.xml +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-fr/kbd_qwerty_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-fr/kbd_qwerty_black.xml deleted file mode 100644 index d32ae757..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-fr/kbd_qwerty_black.xml +++ /dev/null @@ -1,458 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-iw/kbd_qwerty.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-iw/kbd_qwerty.xml deleted file mode 100644 index f84e1619..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-iw/kbd_qwerty.xml +++ /dev/null @@ -1,479 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-iw/kbd_qwerty_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-iw/kbd_qwerty_black.xml deleted file mode 100644 index ecf4e3d6..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-iw/kbd_qwerty_black.xml +++ /dev/null @@ -1,416 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-nb/kbd_qwerty.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-nb/kbd_qwerty.xml deleted file mode 100644 index 0774af33..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-nb/kbd_qwerty.xml +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-nb/kbd_qwerty_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-nb/kbd_qwerty_black.xml deleted file mode 100644 index 951837c4..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-nb/kbd_qwerty_black.xml +++ /dev/null @@ -1,478 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-pl/kbd_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-pl/kbd_kp2a.xml deleted file mode 100644 index 98a37c8c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-pl/kbd_kp2a.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-ru/kbd_qwerty.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-ru/kbd_qwerty.xml deleted file mode 100644 index 8e7feab5..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-ru/kbd_qwerty.xml +++ /dev/null @@ -1,519 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-ru/kbd_qwerty_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-ru/kbd_qwerty_black.xml deleted file mode 100644 index 4e17d488..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-ru/kbd_qwerty_black.xml +++ /dev/null @@ -1,456 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-sr/kbd_qwerty.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-sr/kbd_qwerty.xml deleted file mode 100644 index 34caa1dc..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-sr/kbd_qwerty.xml +++ /dev/null @@ -1,512 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-sr/kbd_qwerty_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-sr/kbd_qwerty_black.xml deleted file mode 100644 index 8a740bd0..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-sr/kbd_qwerty_black.xml +++ /dev/null @@ -1,449 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-sv/kbd_qwerty.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-sv/kbd_qwerty.xml deleted file mode 100644 index e43e5702..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-sv/kbd_qwerty.xml +++ /dev/null @@ -1,542 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml-sv/kbd_qwerty_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml-sv/kbd_qwerty_black.xml deleted file mode 100644 index 9a62e43a..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml-sv/kbd_qwerty_black.xml +++ /dev/null @@ -1,480 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/dictionary.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/dictionary.xml deleted file mode 100644 index 7b770a8b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/dictionary.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_kp2a.xml deleted file mode 100644 index 2a2c3029..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_kp2a.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_kp2a_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_kp2a_black.xml deleted file mode 100644 index cba42bf1..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_kp2a_black.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone.xml deleted file mode 100644 index 01010774..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone.xml +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone_black.xml deleted file mode 100644 index 4b50be37..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone_black.xml +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone_symbols.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone_symbols.xml deleted file mode 100644 index 4c928a8d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone_symbols.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone_symbols_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone_symbols_black.xml deleted file mode 100644 index 4d686e14..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_phone_symbols_black.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_popup_narrow_template.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_popup_narrow_template.xml deleted file mode 100644 index 23c686e8..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_popup_narrow_template.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_popup_template.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_popup_template.xml deleted file mode 100644 index a287be1f..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_popup_template.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_qwerty.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_qwerty.xml deleted file mode 100644 index 16abbc9b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_qwerty.xml +++ /dev/null @@ -1,515 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_qwerty_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_qwerty_black.xml deleted file mode 100644 index 6c9a071e..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_qwerty_black.xml +++ /dev/null @@ -1,452 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols.xml deleted file mode 100644 index e9781786..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols.xml +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols_black.xml deleted file mode 100644 index 7a245b28..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols_black.xml +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols_shift.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols_shift.xml deleted file mode 100644 index 6a900d7c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols_shift.xml +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols_shift_black.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols_shift_black.xml deleted file mode 100644 index 7cbebfc7..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/kbd_symbols_shift_black.xml +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/language_prefs.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/language_prefs.xml deleted file mode 100644 index b7a4c07d..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/language_prefs.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/method.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/method.xml deleted file mode 100644 index 3cf8d2dd..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/method.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_at.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/popup_at.xml deleted file mode 100644 index 197eea44..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_at.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_comma.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/popup_comma.xml deleted file mode 100644 index 7666f4b6..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_comma.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_domains.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/popup_domains.xml deleted file mode 100644 index 4e9789ff..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_domains.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_kp2a.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/popup_kp2a.xml deleted file mode 100644 index a06eee1e..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_kp2a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_mic.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/popup_mic.xml deleted file mode 100644 index 5bbd7dfa..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_mic.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_punctuation.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/popup_punctuation.xml deleted file mode 100644 index c429e38b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_punctuation.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_slash.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/popup_slash.xml deleted file mode 100644 index a38fde0e..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_slash.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_smileys.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/popup_smileys.xml deleted file mode 100644 index 1a14e1df..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/popup_smileys.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/prefs.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/prefs.xml deleted file mode 100644 index d748765e..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/prefs.xml +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/res/xml/prefs_for_debug.xml b/src/java/KP2ASoftKeyboard2/java/res/xml/prefs_for_debug.xml deleted file mode 100644 index 8177d3c6..00000000 --- a/src/java/KP2ASoftKeyboard2/java/res/xml/prefs_for_debug.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/ImeSwitcher.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/ImeSwitcher.java deleted file mode 100644 index 4232e424..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/ImeSwitcher.java +++ /dev/null @@ -1,110 +0,0 @@ -package keepass2android.kbbridge; - -import java.util.List; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.pm.ActivityInfo; -import android.content.pm.ResolveInfo; -import android.inputmethodservice.InputMethodService; -import android.os.Bundle; -import android.os.IBinder; -import android.preference.PreferenceManager; -import android.util.Log; -import android.view.inputmethod.InputMethod; -import android.view.inputmethod.InputMethodManager; -import android.widget.Toast; - -public class ImeSwitcher { - private static final String SECURE_SETTINGS_PACKAGE_NAME = "com.intangibleobject.securesettings.plugin"; - private static final String PREVIOUS_KEYBOARD = "previous_keyboard"; - private static final String KP2A_SWITCHER = "KP2A_Switcher"; - private static final String Tag = "KP2A_SWITCHER"; - - public static void switchToPreviousKeyboard(InputMethodService ims, boolean silent) - { - try { - InputMethodManager imm = (InputMethodManager) ims.getSystemService(Context.INPUT_METHOD_SERVICE); - final IBinder token = ims.getWindow().getWindow().getAttributes().token; - //imm.setInputMethod(token, LATIN); - imm.switchToLastInputMethod(token); - } catch (Throwable t) { // java.lang.NoSuchMethodError if API_level<11 - Log.e("KP2A","cannot set the previous input method:"); - t.printStackTrace(); - SharedPreferences prefs = ims.getSharedPreferences(KP2A_SWITCHER, Context.MODE_PRIVATE); - switchToKeyboard(ims, prefs.getString(PREVIOUS_KEYBOARD, null), silent); - } - - } - - //silent: if true, do not show picker, only switch in background. Don't do anything if switching fails. - public static void switchToKeyboard(Context ctx, String newImeName, boolean silent) - { - Log.d(Tag,"silent: "+silent); - if ((newImeName == null) || (!autoSwitchEnabled(ctx))) - { - Log.d(Tag, "(newImeName == null): "+(newImeName == null)); - Log.d(Tag, "autoSwitchEnabled(ctx)"+autoSwitchEnabled(ctx)); - if (!silent) - { - showPicker(ctx); - } - return; - } - Intent qi = new Intent("com.twofortyfouram.locale.intent.action.FIRE_SETTING"); - List pkgAppsList = ctx.getPackageManager().queryBroadcastReceivers(qi, 0); - boolean sentBroadcast = false; - for (ResolveInfo ri: pkgAppsList) - { - if (ri.activityInfo.packageName.equals(SECURE_SETTINGS_PACKAGE_NAME)) - { - - String currentIme = android.provider.Settings.Secure.getString( - ctx.getContentResolver(), - android.provider.Settings.Secure.DEFAULT_INPUT_METHOD); - currentIme += ";"+String.valueOf( - android.provider.Settings.Secure.getInt( - ctx.getContentResolver(), - android.provider.Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, - -1) - ); - SharedPreferences prefs = ctx.getSharedPreferences(KP2A_SWITCHER, Context.MODE_PRIVATE); - Editor edit = prefs.edit(); - - edit.putString(PREVIOUS_KEYBOARD, currentIme); - edit.commit(); - - Intent i=new Intent("com.twofortyfouram.locale.intent.action.FIRE_SETTING"); - Bundle b = new Bundle(); - - b.putString("com.intangibleobject.securesettings.plugin.extra.BLURB", "Input Method/SwitchIME"); - b.putString("com.intangibleobject.securesettings.plugin.extra.INPUT_METHOD", newImeName); - b.putString("com.intangibleobject.securesettings.plugin.extra.SETTING","default_input_method"); - i.putExtra("com.twofortyfouram.locale.intent.extra.BUNDLE", b); - i.setPackage(SECURE_SETTINGS_PACKAGE_NAME); - Log.d(Tag,"trying to switch by broadcast to SecureSettings"); - ctx.sendBroadcast(i); - sentBroadcast = true; - break; - } - } - if ((!sentBroadcast) && (!silent)) - { - showPicker(ctx); - } - - } - - private static boolean autoSwitchEnabled(Context ctx) { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(ctx); - return sp.getBoolean("kp2a_switch_rooted", false); - } - - private static void showPicker(Context ctx) { - ((InputMethodManager) ctx.getSystemService(InputMethodService.INPUT_METHOD_SERVICE)) - .showInputMethodPicker(); - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/KeyboardData.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/KeyboardData.java deleted file mode 100644 index 15055895..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/KeyboardData.java +++ /dev/null @@ -1,24 +0,0 @@ - -package keepass2android.kbbridge; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import android.text.TextUtils; -public class KeyboardData -{ - public static List availableFields = new ArrayList(); - public static String entryName; - public static String entryId; - - public static boolean hasData() - { - return !TextUtils.isEmpty(entryId); - } - - public static void clear() - { - availableFields.clear(); - entryName = entryId = ""; - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/KeyboardDataBuilder.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/KeyboardDataBuilder.java deleted file mode 100644 index e2dee9f6..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/KeyboardDataBuilder.java +++ /dev/null @@ -1,20 +0,0 @@ -package keepass2android.kbbridge; -import java.util.ArrayList; -import java.util.HashMap; -public class KeyboardDataBuilder { - private ArrayList availableFields = new ArrayList(); - - public void addString(String key, String displayName, String valueToType) - { - StringForTyping stringToType = new StringForTyping(); - stringToType.key = key; - stringToType.displayName = displayName; - stringToType.value = valueToType; - availableFields.add(stringToType); - } - - public void commit() - { - KeyboardData.availableFields = this.availableFields; - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/StringForTyping.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/StringForTyping.java deleted file mode 100644 index 9348dad2..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/kbbridge/StringForTyping.java +++ /dev/null @@ -1,20 +0,0 @@ -package keepass2android.kbbridge; - -public class StringForTyping { - public String key; //internal identifier (PwEntry string field key) - public String displayName; //display name for displaying the key (might be translated) - public String value; - - @Override - public StringForTyping clone(){ - - StringForTyping theClone = new StringForTyping(); - theClone.key = key; - theClone.displayName = displayName; - theClone.value = value; - - return theClone; - } - - -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/AutoDictionary.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/AutoDictionary.java deleted file mode 100644 index cb427a2c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/AutoDictionary.java +++ /dev/null @@ -1,259 +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.Set; -import java.util.Map.Entry; - -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 new words temporarily until they are promoted to the user dictionary - * for longevity. Words in the auto dictionary are used to determine if it's ok - * to accept a word that's not in the main or user dictionary. Using a new word - * repeatedly will promote it to the user dictionary. - */ -public class AutoDictionary extends ExpandableDictionary { - // Weight added to a user picking a new word from the suggestion strip - static final int FREQUENCY_FOR_PICKED = 3; - // Weight added to a user typing a new word that doesn't get corrected (or is reverted) - static final int FREQUENCY_FOR_TYPED = 1; - // A word that is frequently typed and gets promoted to the user dictionary, uses this - // frequency. - static final int FREQUENCY_FOR_AUTO_ADD = 250; - // If the user touches a typed word 2 times or more, it will become valid. - private static final int VALIDITY_THRESHOLD = 2 * FREQUENCY_FOR_PICKED; - // If the user touches a typed word 4 times or more, it will be added to the user dict. - private static final int PROMOTION_THRESHOLD = 4 * FREQUENCY_FOR_PICKED; - - private KP2AKeyboard mIme; - // Locale for which this auto dictionary is storing words - private String mLocale; - - private HashMap mPendingWrites = new HashMap(); - private final Object mPendingWritesLock = new Object(); - - private static final String DATABASE_NAME = "auto_dict.db"; - private static final int DATABASE_VERSION = 1; - - // These are the columns in the dictionary - // TODO: Consume less space by using a unique id for locale instead of the whole - // 2-5 character string. - private static final String COLUMN_ID = BaseColumns._ID; - private static final String COLUMN_WORD = "word"; - private static final String COLUMN_FREQUENCY = "freq"; - private static final String COLUMN_LOCALE = "locale"; - - /** Sort by descending order of frequency. */ - public static final String DEFAULT_SORT_ORDER = COLUMN_FREQUENCY + " DESC"; - - /** Name of the words table in the auto_dict.db */ - private static final String AUTODICT_TABLE_NAME = "words"; - - private static HashMap sDictProjectionMap; - - static { - sDictProjectionMap = new HashMap(); - sDictProjectionMap.put(COLUMN_ID, COLUMN_ID); - sDictProjectionMap.put(COLUMN_WORD, COLUMN_WORD); - sDictProjectionMap.put(COLUMN_FREQUENCY, COLUMN_FREQUENCY); - sDictProjectionMap.put(COLUMN_LOCALE, COLUMN_LOCALE); - } - - private static DatabaseHelper sOpenHelper = null; - - public AutoDictionary(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 boolean isValidWord(CharSequence word) { - final int frequency = getWordFrequency(word); - return frequency >= VALIDITY_THRESHOLD; - } - - @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(); - } - - @Override - public void loadDictionaryAsync() { - // Load the words that correspond to the current input locale - Cursor cursor = query(COLUMN_LOCALE + "=?", new String[] { mLocale }); - try { - if (cursor.moveToFirst()) { - int wordIndex = cursor.getColumnIndex(COLUMN_WORD); - int frequencyIndex = cursor.getColumnIndex(COLUMN_FREQUENCY); - while (!cursor.isAfterLast()) { - String word = cursor.getString(wordIndex); - int frequency = cursor.getInt(frequencyIndex); - // Safeguard against adding really long words. Stack may overflow due - // to recursive lookup - if (word.length() < getMaxWordLength()) { - super.addWord(word, frequency); - } - cursor.moveToNext(); - } - } - } finally { - cursor.close(); - } - } - - @Override - public void addWord(String word, int addFrequency) { - final int length = word.length(); - // Don't add very short or very long words. - if (length < 2 || length > getMaxWordLength()) return; - if (mIme.getCurrentWord().isAutoCapitalized()) { - // Remove caps before adding - word = Character.toLowerCase(word.charAt(0)) + word.substring(1); - } - int freq = getWordFrequency(word); - freq = freq < 0 ? addFrequency : freq + addFrequency; - super.addWord(word, freq); - - if (freq >= PROMOTION_THRESHOLD) { - mIme.promoteToUserDictionary(word, FREQUENCY_FOR_AUTO_ADD); - freq = 0; - } - - synchronized (mPendingWritesLock) { - // Write a null frequency if it is to be deleted from the db - mPendingWrites.put(word, freq == 0 ? null : new Integer(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 HashMap(); - } - } - - /** - * 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("CREATE TABLE " + AUTODICT_TABLE_NAME + " (" - + COLUMN_ID + " INTEGER PRIMARY KEY," - + COLUMN_WORD + " TEXT," - + COLUMN_FREQUENCY + " INTEGER," - + COLUMN_LOCALE + " TEXT" - + ");"); - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - Log.w("AutoDictionary", "Upgrading database from version " + oldVersion + " to " - + newVersion + ", which will destroy all old data"); - db.execSQL("DROP TABLE IF EXISTS " + AUTODICT_TABLE_NAME); - onCreate(db); - } - } - - private Cursor query(String selection, String[] selectionArgs) { - SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); - qb.setTables(AUTODICT_TABLE_NAME); - qb.setProjectionMap(sDictProjectionMap); - - // Get the database and run the query - SQLiteDatabase db = sOpenHelper.getReadableDatabase(); - Cursor c = qb.query(db, null, selection, selectionArgs, null, null, - DEFAULT_SORT_ORDER); - return c; - } - - /** - * 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 HashMap mMap; - private final DatabaseHelper mDbHelper; - private final String mLocale; - - public UpdateDbTask(Context context, DatabaseHelper openHelper, - HashMap pendingWrites, String locale) { - mMap = pendingWrites; - mLocale = locale; - mDbHelper = openHelper; - } - - @Override - protected Void doInBackground(Void... v) { - SQLiteDatabase db = mDbHelper.getWritableDatabase(); - // Write all the entries to the db - Set> mEntries = mMap.entrySet(); - for (Entry entry : mEntries) { - Integer freq = entry.getValue(); - db.delete(AUTODICT_TABLE_NAME, COLUMN_WORD + "=? AND " + COLUMN_LOCALE + "=?", - new String[] { entry.getKey(), mLocale }); - if (freq != null) { - db.insert(AUTODICT_TABLE_NAME, null, - getContentValues(entry.getKey(), freq, mLocale)); - } - } - return null; - } - - private ContentValues getContentValues(String word, int frequency, String locale) { - ContentValues values = new ContentValues(4); - values.put(COLUMN_WORD, word); - values.put(COLUMN_FREQUENCY, frequency); - values.put(COLUMN_LOCALE, locale); - return values; - } - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/BinaryDictionary.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/BinaryDictionary.java deleted file mode 100644 index c4598c5b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/BinaryDictionary.java +++ /dev/null @@ -1,300 +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.io.InputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.Channels; -import java.util.Arrays; - -import android.content.Context; -import android.util.Log; - -/** - * Implements a static, compacted, binary dictionary of standard words. - */ -public class BinaryDictionary extends Dictionary { - - /** - * There is difference between what java and native code can handle. - * This value should only be used in BinaryDictionary.java - * It is necessary to keep it at this value because some languages e.g. German have - * really long words. - */ - protected static final int MAX_WORD_LENGTH = 48; - - private static final String TAG = "BinaryDictionary"; - private static final int MAX_ALTERNATIVES = 16; - private static final int MAX_WORDS = 18; - private static final int MAX_BIGRAMS = 60; - - private static final int TYPED_LETTER_MULTIPLIER = 2; - private static final boolean ENABLE_MISSED_CHARACTERS = true; - - private int mDicTypeId; - private int mNativeDict; - private int mDictLength; - private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES]; - private char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS]; - private char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS]; - private int[] mFrequencies = new int[MAX_WORDS]; - private int[] mFrequencies_bigrams = new int[MAX_BIGRAMS]; - // Keep a reference to the native dict direct buffer in Java to avoid - // unexpected deallocation of the direct buffer. - private ByteBuffer mNativeDictDirectBuffer; - - static { - try { - System.loadLibrary("jni_latinime"); - } catch (UnsatisfiedLinkError ule) { - Log.e("BinaryDictionary", "Could not load native library jni_latinime"); - } - } - - /** - * Create a dictionary from a raw resource file - * @param context application context for reading resources - * @param resId the resource containing the raw binary dictionary - */ - public BinaryDictionary(Context context, int[] resId, int dicTypeId) { - if (resId != null && resId.length > 0 && resId[0] != 0) { - loadDictionary(context, resId); - } - mDicTypeId = dicTypeId; - } - - /** - * Create a dictionary from input streams - * @param context application context for reading resources - * @param streams the resource streams containing the raw binary dictionary - */ - public BinaryDictionary(Context context, InputStream[] streams, int dicTypeId) { - if (streams != null && streams.length > 0) { - loadDictionary(context, streams); - } - mDicTypeId = dicTypeId; - } - - - /** - * Create a dictionary from a byte buffer. This is used for testing. - * @param context application context for reading resources - * @param byteBuffer a ByteBuffer containing the binary dictionary - */ - public BinaryDictionary(Context context, ByteBuffer byteBuffer, int dicTypeId) { - if (byteBuffer != null) { - if (byteBuffer.isDirect()) { - mNativeDictDirectBuffer = byteBuffer; - } else { - mNativeDictDirectBuffer = ByteBuffer.allocateDirect(byteBuffer.capacity()); - byteBuffer.rewind(); - mNativeDictDirectBuffer.put(byteBuffer); - } - mDictLength = byteBuffer.capacity(); - mNativeDict = openNative(mNativeDictDirectBuffer, - TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER); - } - mDicTypeId = dicTypeId; - } - - private native int openNative(ByteBuffer bb, int typedLetterMultiplier, - int fullWordMultiplier); - private native void closeNative(int dict); - private native boolean isValidWordNative(int nativeData, char[] word, int wordLength); - private native int getSuggestionsNative(int dict, int[] inputCodes, int codesSize, - char[] outputChars, int[] frequencies, int maxWordLength, int maxWords, - int maxAlternatives, int skipPos, int[] nextLettersFrequencies, int nextLettersSize); - private native int getBigramsNative(int dict, char[] prevWord, int prevWordLength, - int[] inputCodes, int inputCodesLength, char[] outputChars, int[] frequencies, - int maxWordLength, int maxBigrams, int maxAlternatives); - - private final void loadDictionary(Context context, int[] resId) { - InputStream[] is = null; - try { - // merging separated dictionary into one if dictionary is separated - is = new InputStream[resId.length]; - for (int i = 0; i < resId.length; i++) { - is[i] = context.getResources().openRawResource(resId[i]); - } - loadDictionary(context, is); - - - } finally { - try { - if (is != null) { - for (int i = 0; i < is.length; i++) { - is[i].close(); - } - } - } catch (IOException e) { - Log.w(TAG, "Failed to close input stream"); - } - } - } - - - private void loadDictionary(Context context, InputStream[] is) - { - try - { - int total = 0; - for (int i = 0; i < is.length; i++) - total += is[i].available(); - - mNativeDictDirectBuffer = - ByteBuffer.allocateDirect(total).order(ByteOrder.nativeOrder()); - int got = 0; - for (int i = 0; i < is.length; i++) { - got += Channels.newChannel(is[i]).read(mNativeDictDirectBuffer); - } - if (got != total) { - Log.e(TAG, "Read " + got + " bytes, expected " + total); - } else { - mNativeDict = openNative(mNativeDictDirectBuffer, - TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER); - mDictLength = total; - } - - } - catch (IOException e) { - Log.w(TAG, "No available memory for binary dictionary"); - } catch (UnsatisfiedLinkError e) { - Log.w(TAG, "Failed to load native dictionary", e); - } finally { - try { - if (is != null) { - for (int i = 0; i < is.length; i++) { - is[i].close(); - } - } - } catch (IOException e) { - Log.w(TAG, "Failed to close input stream"); - } - } - - } - - @Override - public void getBigrams(final WordComposer codes, final CharSequence previousWord, - final WordCallback callback, int[] nextLettersFrequencies) { - - char[] chars = previousWord.toString().toCharArray(); - Arrays.fill(mOutputChars_bigrams, (char) 0); - Arrays.fill(mFrequencies_bigrams, 0); - - int codesSize = codes.size(); - Arrays.fill(mInputCodes, -1); - int[] alternatives = codes.getCodesAt(0); - System.arraycopy(alternatives, 0, mInputCodes, 0, - Math.min(alternatives.length, MAX_ALTERNATIVES)); - - int count = getBigramsNative(mNativeDict, chars, chars.length, mInputCodes, codesSize, - mOutputChars_bigrams, mFrequencies_bigrams, MAX_WORD_LENGTH, MAX_BIGRAMS, - MAX_ALTERNATIVES); - - for (int j = 0; j < count; j++) { - if (mFrequencies_bigrams[j] < 1) break; - int start = j * MAX_WORD_LENGTH; - int len = 0; - while (mOutputChars_bigrams[start + len] != 0) { - len++; - } - if (len > 0) { - callback.addWord(mOutputChars_bigrams, start, len, mFrequencies_bigrams[j], - mDicTypeId, DataType.BIGRAM); - } - } - } - - @Override - public void getWords(final WordComposer codes, final WordCallback callback, - int[] nextLettersFrequencies) { - final int codesSize = codes.size(); - // Won't deal with really long words. - if (codesSize > MAX_WORD_LENGTH - 1) return; - - Arrays.fill(mInputCodes, -1); - for (int i = 0; i < codesSize; i++) { - int[] alternatives = codes.getCodesAt(i); - System.arraycopy(alternatives, 0, mInputCodes, i * MAX_ALTERNATIVES, - Math.min(alternatives.length, MAX_ALTERNATIVES)); - } - Arrays.fill(mOutputChars, (char) 0); - Arrays.fill(mFrequencies, 0); - - int count = getSuggestionsNative(mNativeDict, mInputCodes, codesSize, - mOutputChars, mFrequencies, - MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, -1, - nextLettersFrequencies, - nextLettersFrequencies != null ? nextLettersFrequencies.length : 0); - - // If there aren't sufficient suggestions, search for words by allowing wild cards at - // the different character positions. This feature is not ready for prime-time as we need - // to figure out the best ranking for such words compared to proximity corrections and - // completions. - if (ENABLE_MISSED_CHARACTERS && count < 5) { - for (int skip = 0; skip < codesSize; skip++) { - int tempCount = getSuggestionsNative(mNativeDict, mInputCodes, codesSize, - mOutputChars, mFrequencies, - MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, skip, - null, 0); - count = Math.max(count, tempCount); - if (tempCount > 0) break; - } - } - - for (int j = 0; j < count; j++) { - if (mFrequencies[j] < 1) break; - int start = j * MAX_WORD_LENGTH; - int len = 0; - while (mOutputChars[start + len] != 0) { - len++; - } - if (len > 0) { - callback.addWord(mOutputChars, start, len, mFrequencies[j], mDicTypeId, - DataType.UNIGRAM); - } - } - } - - @Override - public boolean isValidWord(CharSequence word) { - if (word == null) return false; - char[] chars = word.toString().toCharArray(); - return isValidWordNative(mNativeDict, chars, chars.length); - } - - public int getSize() { - return mDictLength; // This value is initialized on the call to openNative() - } - - @Override - public synchronized void close() { - if (mNativeDict != 0) { - closeNative(mNativeDict); - mNativeDict = 0; - } - } - - @Override - protected void finalize() throws Throwable { - close(); - super.finalize(); - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/CandidateView.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/CandidateView.java deleted file mode 100644 index 9b83ea3b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/CandidateView.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * Copyright (C) 2014 Philipp Crocoll - * Copyright (C) 2014 Wiktor Lawski - * - * 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.annotation.SuppressLint; -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Align; -import android.graphics.Rect; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.GestureDetector; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.widget.PopupWindow; -import android.widget.TextView; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class CandidateView extends View { - - private static final int OUT_OF_BOUNDS_WORD_INDEX = -1; - private static final int OUT_OF_BOUNDS_X_COORD = -1; - - private KP2AKeyboard mService; - private final ArrayList mSuggestions = new ArrayList(); - private boolean mShowingCompletions; - private CharSequence mSelectedString; - private int mSelectedIndex; - private int mTouchX = OUT_OF_BOUNDS_X_COORD; - private final Drawable mSelectionHighlight; - private boolean mTypedWordValid; - - private boolean mHaveMinimalSuggestion; - - private Rect mBgPadding; - - private final TextView mPreviewText; - private final PopupWindow mPreviewPopup; - private int mCurrentWordIndex; - private Drawable mDivider; - - private static final int MAX_SUGGESTIONS = 32; - private static final int SCROLL_PIXELS = 20; - - private final int[] mWordWidth = new int[MAX_SUGGESTIONS]; - private final int[] mWordX = new int[MAX_SUGGESTIONS]; - private int mPopupPreviewX; - private int mPopupPreviewY; - - private static final int X_GAP = 10; - - private final int mColorNormal; - private final int mColorRecommended; - private final int mColorOther; - private final Paint mPaint; - private final int mDescent; - private boolean mScrolled; - private boolean mShowingAddToDictionary; - private CharSequence mAddToDictionaryHint; - - private int mTargetScrollX; - - private final int mMinTouchableWidth; - - private int mTotalWidth; - - private final GestureDetector mGestureDetector; - - /** - * Construct a CandidateView for showing suggested words for completion. - * @param context - * @param attrs - */ - public CandidateView(Context context, AttributeSet attrs) { - super(context, attrs); - mSelectionHighlight = context.getResources().getDrawable( - R.drawable.list_selector_background_pressed); - - LayoutInflater inflate = - (LayoutInflater) context - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - Resources res = context.getResources(); - mPreviewPopup = new PopupWindow(context); - mPreviewText = (TextView) inflate.inflate(R.layout.candidate_preview, null); - mPreviewPopup.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); - mPreviewPopup.setContentView(mPreviewText); - mPreviewPopup.setBackgroundDrawable(null); - mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation); - mColorNormal = res.getColor(R.color.candidate_normal); - mColorRecommended = res.getColor(R.color.candidate_recommended); - mColorOther = res.getColor(R.color.candidate_other); - mDivider = res.getDrawable(R.drawable.keyboard_suggest_strip_divider); - mAddToDictionaryHint = res.getString(R.string.hint_add_to_dictionary); - - mPaint = new Paint(); - mPaint.setColor(mColorNormal); - mPaint.setAntiAlias(true); - mPaint.setTextSize(mPreviewText.getTextSize()); - mPaint.setStrokeWidth(0); - mPaint.setTextAlign(Align.CENTER); - mDescent = (int) mPaint.descent(); - mMinTouchableWidth = (int)res.getDimension(R.dimen.candidate_min_touchable_width); - - mGestureDetector = new GestureDetector( - new CandidateStripGestureListener(mMinTouchableWidth)); - setWillNotDraw(false); - setHorizontalScrollBarEnabled(false); - setVerticalScrollBarEnabled(false); - scrollTo(0, getScrollY()); - } - - private class CandidateStripGestureListener extends GestureDetector.SimpleOnGestureListener { - private final int mTouchSlopSquare; - - public CandidateStripGestureListener(int touchSlop) { - // Slightly reluctant to scroll to be able to easily choose the suggestion - mTouchSlopSquare = touchSlop * touchSlop; - } - - @Override - public void onLongPress(MotionEvent me) { - if (mSuggestions.size() > 0) { - if (me.getX() + getScrollX() < mWordWidth[0] && getScrollX() < 10) { - longPressFirstWord(); - } - } - } - - @Override - public boolean onDown(MotionEvent e) { - mScrolled = false; - return false; - } - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, - float distanceX, float distanceY) { - if (!mScrolled) { - // This is applied only when we recognize that scrolling is starting. - final int deltaX = (int) (e2.getX() - e1.getX()); - final int deltaY = (int) (e2.getY() - e1.getY()); - final int distance = (deltaX * deltaX) + (deltaY * deltaY); - if (distance < mTouchSlopSquare) { - return true; - } - mScrolled = true; - } - - final int width = getWidth(); - mScrolled = true; - int scrollX = getScrollX(); - scrollX += (int) distanceX; - if (scrollX < 0) { - scrollX = 0; - } - if (distanceX > 0 && scrollX + width > mTotalWidth) { - scrollX -= (int) distanceX; - } - mTargetScrollX = scrollX; - scrollTo(scrollX, getScrollY()); - hidePreview(); - invalidate(); - return true; - } - } - - /** - * A connection back to the service to communicate with the text field - * @param listener - */ - public void setService(KP2AKeyboard listener) { - mService = listener; - } - - @Override - public int computeHorizontalScrollRange() { - return mTotalWidth; - } - - /** - * If the canvas is null, then only touch calculations are performed to pick the target - * candidate. - */ - @Override - protected void onDraw(Canvas canvas) { - if (canvas != null) { - super.onDraw(canvas); - } - mTotalWidth = 0; - - final int height = getHeight(); - if (mBgPadding == null) { - mBgPadding = new Rect(0, 0, 0, 0); - if (getBackground() != null) { - getBackground().getPadding(mBgPadding); - } - mDivider.setBounds(0, 0, mDivider.getIntrinsicWidth(), - mDivider.getIntrinsicHeight()); - } - - final int count = mSuggestions.size(); - final Rect bgPadding = mBgPadding; - final Paint paint = mPaint; - final int touchX = mTouchX; - final int scrollX = getScrollX(); - final boolean scrolled = mScrolled; - final boolean typedWordValid = mTypedWordValid; - final int y = (int) (height + mPaint.getTextSize() - mDescent) / 2; - - boolean existsAutoCompletion = false; - - int x = 0; - for (int i = 0; i < count; i++) { - CharSequence suggestion = mSuggestions.get(i); - if (suggestion == null) continue; - final int wordLength = suggestion.length(); - - paint.setColor(mColorNormal); - if (mHaveMinimalSuggestion - && ((i == 1 && !typedWordValid) || (i == 0 && typedWordValid))) { - paint.setTypeface(Typeface.DEFAULT_BOLD); - paint.setColor(mColorRecommended); - existsAutoCompletion = true; - } else if (i != 0 || (wordLength == 1 && count > 1)) { - // HACK: even if i == 0, we use mColorOther when this suggestion's length is 1 and - // there are multiple suggestions, such as the default punctuation list. - paint.setColor(mColorOther); - } - int wordWidth; - if ((wordWidth = mWordWidth[i]) == 0) { - float textWidth = paint.measureText(suggestion, 0, wordLength); - wordWidth = Math.max(mMinTouchableWidth, (int) textWidth + X_GAP * 2); - mWordWidth[i] = wordWidth; - } - - mWordX[i] = x; - - if (touchX != OUT_OF_BOUNDS_X_COORD && !scrolled - && touchX + scrollX >= x && touchX + scrollX < x + wordWidth) { - if (canvas != null && !mShowingAddToDictionary) { - canvas.translate(x, 0); - mSelectionHighlight.setBounds(0, bgPadding.top, wordWidth, height); - mSelectionHighlight.draw(canvas); - canvas.translate(-x, 0); - } - mSelectedString = suggestion; - mSelectedIndex = i; - } - - if (canvas != null) { - canvas.drawText(suggestion, 0, wordLength, x + wordWidth / 2, y, paint); - paint.setColor(mColorOther); - canvas.translate(x + wordWidth, 0); - // Draw a divider unless it's after the hint - if (!(mShowingAddToDictionary && i == 1)) { - mDivider.draw(canvas); - } - canvas.translate(-x - wordWidth, 0); - } - paint.setTypeface(Typeface.DEFAULT); - x += wordWidth; - } - mService.onAutoCompletionStateChanged(existsAutoCompletion); - mTotalWidth = x; - if (mTargetScrollX != scrollX) { - scrollToTarget(); - } - } - - private void scrollToTarget() { - int scrollX = getScrollX(); - if (mTargetScrollX > scrollX) { - scrollX += SCROLL_PIXELS; - if (scrollX >= mTargetScrollX) { - scrollX = mTargetScrollX; - scrollTo(scrollX, getScrollY()); - requestLayout(); - } else { - scrollTo(scrollX, getScrollY()); - } - } else { - scrollX -= SCROLL_PIXELS; - if (scrollX <= mTargetScrollX) { - scrollX = mTargetScrollX; - scrollTo(scrollX, getScrollY()); - requestLayout(); - } else { - scrollTo(scrollX, getScrollY()); - } - } - invalidate(); - } - - @SuppressLint("WrongCall") - public void setSuggestions(List suggestions, boolean completions, - boolean typedWordValid, boolean haveMinimalSuggestion) { - clear(); - if (suggestions != null) { - int insertCount = Math.min(suggestions.size(), MAX_SUGGESTIONS); - for (CharSequence suggestion : suggestions) { - mSuggestions.add(suggestion); - if (--insertCount == 0) - break; - } - } - mShowingCompletions = completions; - mTypedWordValid = typedWordValid; - scrollTo(0, getScrollY()); - mTargetScrollX = 0; - mHaveMinimalSuggestion = haveMinimalSuggestion; - // Compute the total width - onDraw(null); - invalidate(); - requestLayout(); - } - - public boolean isShowingAddToDictionaryHint() { - return mShowingAddToDictionary; - } - - public void showAddToDictionaryHint(CharSequence word) { - ArrayList suggestions = new ArrayList(); - suggestions.add(word); - suggestions.add(mAddToDictionaryHint); - setSuggestions(suggestions, false, false, false); - mShowingAddToDictionary = true; - } - - public boolean dismissAddToDictionaryHint() { - if (!mShowingAddToDictionary) return false; - clear(); - return true; - } - - /* package */ List getSuggestions() { - return mSuggestions; - } - - public void clear() { - // Don't call mSuggestions.clear() because it's being used for logging - // in LatinIME.pickSuggestionManually(). - mSuggestions.clear(); - mTouchX = OUT_OF_BOUNDS_X_COORD; - mSelectedString = null; - mSelectedIndex = -1; - mShowingAddToDictionary = false; - invalidate(); - Arrays.fill(mWordWidth, 0); - Arrays.fill(mWordX, 0); - } - - @Override - public boolean onTouchEvent(MotionEvent me) { - - if (mGestureDetector.onTouchEvent(me)) { - return true; - } - - int action = me.getAction(); - int x = (int) me.getX(); - int y = (int) me.getY(); - mTouchX = x; - - switch (action) { - case MotionEvent.ACTION_DOWN: - invalidate(); - break; - case MotionEvent.ACTION_MOVE: - if (y <= 0) { - // Fling up!? - if (mSelectedString != null) { - // If there are completions from the application, we don't change the state to - // STATE_PICKED_SUGGESTION - if (!mShowingCompletions) { - // This "acceptedSuggestion" will not be counted as a word because - // it will be counted in pickSuggestion instead. - TextEntryState.acceptedSuggestion(mSuggestions.get(0), - mSelectedString); - } - mService.pickSuggestionManually(mSelectedIndex, mSelectedString); - mSelectedString = null; - mSelectedIndex = -1; - } - } - break; - case MotionEvent.ACTION_UP: - if (!mScrolled) { - if (mSelectedString != null) { - if (mShowingAddToDictionary) { - longPressFirstWord(); - clear(); - } else { - if (!mShowingCompletions) { - TextEntryState.acceptedSuggestion(mSuggestions.get(0), - mSelectedString); - } - mService.pickSuggestionManually(mSelectedIndex, mSelectedString); - } - } - } - mSelectedString = null; - mSelectedIndex = -1; - requestLayout(); - hidePreview(); - invalidate(); - break; - } - return true; - } - - private void hidePreview() { - mTouchX = OUT_OF_BOUNDS_X_COORD; - mCurrentWordIndex = OUT_OF_BOUNDS_WORD_INDEX; - mPreviewPopup.dismiss(); - } - - private void showPreview(int wordIndex, String altText) { - int oldWordIndex = mCurrentWordIndex; - mCurrentWordIndex = wordIndex; - // If index changed or changing text - if (oldWordIndex != mCurrentWordIndex || altText != null) { - if (wordIndex == OUT_OF_BOUNDS_WORD_INDEX) { - hidePreview(); - } else { - CharSequence word = altText != null? altText : mSuggestions.get(wordIndex); - mPreviewText.setText(word); - mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - int wordWidth = (int) (mPaint.measureText(word, 0, word.length()) + X_GAP * 2); - final int popupWidth = wordWidth - + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight(); - final int popupHeight = mPreviewText.getMeasuredHeight(); - //mPreviewText.setVisibility(INVISIBLE); - mPopupPreviewX = mWordX[wordIndex] - mPreviewText.getPaddingLeft() - getScrollX() - + (mWordWidth[wordIndex] - wordWidth) / 2; - mPopupPreviewY = - popupHeight; - int [] offsetInWindow = new int[2]; - getLocationInWindow(offsetInWindow); - if (mPreviewPopup.isShowing()) { - mPreviewPopup.update(mPopupPreviewX, mPopupPreviewY + offsetInWindow[1], - popupWidth, popupHeight); - } else { - mPreviewPopup.setWidth(popupWidth); - mPreviewPopup.setHeight(popupHeight); - mPreviewPopup.showAtLocation(this, Gravity.NO_GRAVITY, mPopupPreviewX, - mPopupPreviewY + offsetInWindow[1]); - } - mPreviewText.setVisibility(VISIBLE); - } - } - } - - private void longPressFirstWord() { - CharSequence word = mSuggestions.get(0); - if (word.length() < 2) return; - if (mService.addWordToDictionary(word.toString())) { - showPreview(0, getContext().getResources().getString(R.string.added_word, word)); - } - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - hidePreview(); - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ContactsDictionary.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ContactsDictionary.java deleted file mode 100644 index 247f8bad..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ContactsDictionary.java +++ /dev/null @@ -1,152 +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. - */ - -package keepass2android.softkeyboard; - -import android.content.ContentResolver; -import android.content.Context; -import android.database.ContentObserver; -import android.database.Cursor; -import android.os.SystemClock; -import android.provider.ContactsContract.Contacts; -import android.text.TextUtils; -import android.util.Log; - -public class ContactsDictionary extends ExpandableDictionary { - - private static final String[] PROJECTION = { - Contacts._ID, - Contacts.DISPLAY_NAME, - }; - - private static final String TAG = "ContactsDictionary"; - - /** - * Frequency for contacts information into the dictionary - */ - private static final int FREQUENCY_FOR_CONTACTS = 128; - private static final int FREQUENCY_FOR_CONTACTS_BIGRAM = 90; - - private static final int INDEX_NAME = 1; - - private ContentObserver mObserver; - - private long mLastLoadedContacts; - - public ContactsDictionary(Context context, int dicTypeId) { - super(context, dicTypeId); - // Perform a managed query. The Activity will handle closing and requerying the cursor - // when needed. - ContentResolver cres = context.getContentResolver(); - - cres.registerContentObserver( - Contacts.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 startDictionaryLoadingTaskLocked() { - long now = SystemClock.uptimeMillis(); - if (mLastLoadedContacts == 0 - || now - mLastLoadedContacts > 30 * 60 * 1000 /* 30 minutes */) { - super.startDictionaryLoadingTaskLocked(); - } - } - - @Override - public void loadDictionaryAsync() { - /*try { - Cursor cursor = getContext().getContentResolver() - .query(Contacts.CONTENT_URI, PROJECTION, null, null, null); - if (cursor != null) { - addWords(cursor); - } - } catch(IllegalStateException e) { - Log.e(TAG, "Contacts DB is having problems"); - } - mLastLoadedContacts = SystemClock.uptimeMillis();*/ - } - - private void addWords(Cursor cursor) { - clearDictionary(); - - final int maxWordLength = getMaxWordLength(); - try { - if (cursor.moveToFirst()) { - while (!cursor.isAfterLast()) { - String name = cursor.getString(INDEX_NAME); - - if (name != null) { - int len = name.length(); - String prevWord = null; - - // TODO: Better tokenization for non-Latin writing systems - for (int i = 0; i < len; i++) { - if (Character.isLetter(name.charAt(i))) { - int j; - for (j = i + 1; j < len; j++) { - char c = name.charAt(j); - - if (!(c == '-' || c == '\'' || - Character.isLetter(c))) { - break; - } - } - - String word = name.substring(i, j); - i = j - 1; - - // Safeguard against adding really long words. Stack - // may overflow due to recursion - // Also don't add single letter words, possibly confuses - // capitalization of i. - final int wordLen = word.length(); - if (wordLen < maxWordLength && wordLen > 1) { - super.addWord(word, FREQUENCY_FOR_CONTACTS); - if (!TextUtils.isEmpty(prevWord)) { - // TODO Do not add email address - // Not so critical - super.setBigram(prevWord, word, - FREQUENCY_FOR_CONTACTS_BIGRAM); - } - prevWord = word; - } - } - } - } - cursor.moveToNext(); - } - } - cursor.close(); - } catch(IllegalStateException e) { - Log.e(TAG, "Contacts DB is having problems"); - } - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Design.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Design.java deleted file mode 100644 index c8e22ba9..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Design.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2014 Wiktor Lawski - * - * 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.annotation.SuppressLint; -import android.app.Activity; -import android.content.SharedPreferences; - -public class Design { - @SuppressLint("InlinedApi") - public static void updateTheme(Activity activity, SharedPreferences prefs) { - - if (android.os.Build.VERSION.SDK_INT >= 11 - /* android.os.Build.VERSION_CODES.HONEYCOMB */) { - String design = prefs.getString("design_key", "Light"); - - if (design.equals("Light")) { - activity.setTheme(android.R.style.Theme_Holo_Light); - } else { - activity.setTheme(android.R.style.Theme_Holo); - } - } - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Dictionary.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Dictionary.java deleted file mode 100644 index 2b93599b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Dictionary.java +++ /dev/null @@ -1,120 +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; - -/** - * Abstract base class for a dictionary that can do a fuzzy search for words based on a set of key - * strokes. - */ -abstract public class Dictionary { - /** - * Whether or not to replicate the typed word in the suggested list, even if it's valid. - */ - protected static final boolean INCLUDE_TYPED_WORD_IF_VALID = false; - - /** - * The weight to give to a word if it's length is the same as the number of typed characters. - */ - protected static final int FULL_WORD_FREQ_MULTIPLIER = 2; - - public static enum DataType { - UNIGRAM, BIGRAM - } - - /** - * Interface to be implemented by classes requesting words to be fetched from the dictionary. - * @see #getWords(WordComposer, WordCallback) - */ - public interface WordCallback { - /** - * Adds a word to a list of suggestions. The word is expected to be ordered based on - * the provided frequency. - * @param word the character array containing the word - * @param wordOffset starting offset of the word in the character array - * @param wordLength length of valid characters in the character array - * @param frequency the frequency of occurence. This is normalized between 1 and 255, but - * can exceed those limits - * @param dicTypeId of the dictionary where word was from - * @param dataType tells type of this data - * @return true if the word was added, false if no more words are required - */ - boolean addWord(char[] word, int wordOffset, int wordLength, int frequency, int dicTypeId, - DataType dataType); - } - - /** - * Searches for words in the dictionary that match the characters in the composer. Matched - * words are added through the callback object. - * @param composer the key sequence to match - * @param callback the callback object to send matched words to as possible candidates - * @param nextLettersFrequencies array of frequencies of next letters that could follow the - * word so far. For instance, "bracke" can be followed by "t", so array['t'] will have - * a non-zero value on returning from this method. - * Pass in null if you don't want the dictionary to look up next letters. - * @see WordCallback#addWord(char[], int, int) - */ - abstract public void getWords(final WordComposer composer, final WordCallback callback, - int[] nextLettersFrequencies); - - /** - * Searches for pairs in the bigram dictionary that matches the previous word and all the - * possible words following are added through the callback object. - * @param composer the key sequence to match - * @param callback the callback object to send possible word following previous word - * @param nextLettersFrequencies array of frequencies of next letters that could follow the - * word so far. For instance, "bracke" can be followed by "t", so array['t'] will have - * a non-zero value on returning from this method. - * Pass in null if you don't want the dictionary to look up next letters. - */ - public void getBigrams(final WordComposer composer, final CharSequence previousWord, - final WordCallback callback, int[] nextLettersFrequencies) { - // empty base implementation - } - - /** - * Checks if the given word occurs in the dictionary - * @param word the word to search for. The search should be case-insensitive. - * @return true if the word exists, false otherwise - */ - abstract public boolean isValidWord(CharSequence word); - - /** - * Compares the contents of the character array with the typed word and returns true if they - * are the same. - * @param word the array of characters that make up the word - * @param length the number of valid characters in the character array - * @param typedWord the word to compare with - * @return true if they are the same, false otherwise. - */ - protected boolean same(final char[] word, final int length, final CharSequence typedWord) { - if (typedWord.length() != length) { - return false; - } - for (int i = 0; i < length; i++) { - if (word[i] != typedWord.charAt(i)) { - return false; - } - } - return true; - } - - /** - * Override to clean up any resources. - */ - public void close() { - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/EditingUtil.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/EditingUtil.java deleted file mode 100644 index 3f3df704..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/EditingUtil.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (C) 2009 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.text.TextUtils; -import android.view.inputmethod.ExtractedText; -import android.view.inputmethod.ExtractedTextRequest; -import android.view.inputmethod.InputConnection; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.regex.Pattern; - -/** - * Utility methods to deal with editing text through an InputConnection. - */ -public class EditingUtil { - /** - * Number of characters we want to look back in order to identify the previous word - */ - private static final int LOOKBACK_CHARACTER_NUM = 15; - - // Cache Method pointers - private static boolean sMethodsInitialized; - private static Method sMethodGetSelectedText; - private static Method sMethodSetComposingRegion; - - private EditingUtil() {}; - - /** - * Append newText to the text field represented by connection. - * The new text becomes selected. - */ - public static void appendText(InputConnection connection, String newText) { - if (connection == null) { - return; - } - - // Commit the composing text - connection.finishComposingText(); - - // Add a space if the field already has text. - CharSequence charBeforeCursor = connection.getTextBeforeCursor(1, 0); - if (charBeforeCursor != null - && !charBeforeCursor.equals(" ") - && (charBeforeCursor.length() > 0)) { - newText = " " + newText; - } - - connection.setComposingText(newText, 1); - } - - private static int getCursorPosition(InputConnection connection) { - ExtractedText extracted = connection.getExtractedText( - new ExtractedTextRequest(), 0); - if (extracted == null) { - return -1; - } - return extracted.startOffset + extracted.selectionStart; - } - - /** - * @param connection connection to the current text field. - * @param sep characters which may separate words - * @param range the range object to store the result into - * @return the word that surrounds the cursor, including up to one trailing - * separator. For example, if the field contains "he|llo world", where | - * represents the cursor, then "hello " will be returned. - */ - public static String getWordAtCursor( - InputConnection connection, String separators, Range range) { - Range r = getWordRangeAtCursor(connection, separators, range); - return (r == null) ? null : r.word; - } - - /** - * Removes the word surrounding the cursor. Parameters are identical to - * getWordAtCursor. - */ - public static void deleteWordAtCursor( - InputConnection connection, String separators) { - - Range range = getWordRangeAtCursor(connection, separators, null); - if (range == null) return; - - connection.finishComposingText(); - // Move cursor to beginning of word, to avoid crash when cursor is outside - // of valid range after deleting text. - int newCursor = getCursorPosition(connection) - range.charsBefore; - connection.setSelection(newCursor, newCursor); - connection.deleteSurroundingText(0, range.charsBefore + range.charsAfter); - } - - /** - * Represents a range of text, relative to the current cursor position. - */ - public static class Range { - /** Characters before selection start */ - public int charsBefore; - - /** - * Characters after selection start, including one trailing word - * separator. - */ - public int charsAfter; - - /** The actual characters that make up a word */ - public String word; - - public Range() {} - - public Range(int charsBefore, int charsAfter, String word) { - if (charsBefore < 0 || charsAfter < 0) { - throw new IndexOutOfBoundsException(); - } - this.charsBefore = charsBefore; - this.charsAfter = charsAfter; - this.word = word; - } - } - - private static Range getWordRangeAtCursor( - InputConnection connection, String sep, Range range) { - if (connection == null || sep == null) { - return null; - } - CharSequence before = connection.getTextBeforeCursor(1000, 0); - CharSequence after = connection.getTextAfterCursor(1000, 0); - if (before == null || after == null) { - return null; - } - - // Find first word separator before the cursor - int start = before.length(); - while (start > 0 && !isWhitespace(before.charAt(start - 1), sep)) start--; - - // Find last word separator after the cursor - int end = -1; - while (++end < after.length() && !isWhitespace(after.charAt(end), sep)); - - int cursor = getCursorPosition(connection); - if (start >= 0 && cursor + end <= after.length() + before.length()) { - String word = before.toString().substring(start, before.length()) - + after.toString().substring(0, end); - - Range returnRange = range != null? range : new Range(); - returnRange.charsBefore = before.length() - start; - returnRange.charsAfter = end; - returnRange.word = word; - return returnRange; - } - - return null; - } - - private static boolean isWhitespace(int code, String whitespace) { - return whitespace.contains(String.valueOf((char) code)); - } - - private static final Pattern spaceRegex = Pattern.compile("\\s+"); - - public static CharSequence getPreviousWord(InputConnection connection, - String sentenceSeperators) { - //TODO: Should fix this. This could be slow! - CharSequence prev = connection.getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0); - if (prev == null) { - return null; - } - String[] w = spaceRegex.split(prev); - if (w.length >= 2 && w[w.length-2].length() > 0) { - char lastChar = w[w.length-2].charAt(w[w.length-2].length() -1); - if (sentenceSeperators.contains(String.valueOf(lastChar))) { - return null; - } - return w[w.length-2]; - } else { - return null; - } - } - - public static class SelectedWord { - public int start; - public int end; - public CharSequence word; - } - - /** - * Takes a character sequence with a single character and checks if the character occurs - * in a list of word separators or is empty. - * @param singleChar A CharSequence with null, zero or one character - * @param wordSeparators A String containing the word separators - * @return true if the character is at a word boundary, false otherwise - */ - private static boolean isWordBoundary(CharSequence singleChar, String wordSeparators) { - return TextUtils.isEmpty(singleChar) || wordSeparators.contains(singleChar); - } - - /** - * Checks if the cursor is inside a word or the current selection is a whole word. - * @param ic the InputConnection for accessing the text field - * @param selStart the start position of the selection within the text field - * @param selEnd the end position of the selection within the text field. This could be - * the same as selStart, if there's no selection. - * @param wordSeparators the word separator characters for the current language - * @return an object containing the text and coordinates of the selected/touching word, - * null if the selection/cursor is not marking a whole word. - */ - public static SelectedWord getWordAtCursorOrSelection(final InputConnection ic, - int selStart, int selEnd, String wordSeparators) { - if (selStart == selEnd) { - // There is just a cursor, so get the word at the cursor - EditingUtil.Range range = new EditingUtil.Range(); - CharSequence touching = getWordAtCursor(ic, wordSeparators, range); - if (!TextUtils.isEmpty(touching)) { - SelectedWord selWord = new SelectedWord(); - selWord.word = touching; - selWord.start = selStart - range.charsBefore; - selWord.end = selEnd + range.charsAfter; - return selWord; - } - } else { - // Is the previous character empty or a word separator? If not, return null. - CharSequence charsBefore = ic.getTextBeforeCursor(1, 0); - if (!isWordBoundary(charsBefore, wordSeparators)) { - return null; - } - - // Is the next character empty or a word separator? If not, return null. - CharSequence charsAfter = ic.getTextAfterCursor(1, 0); - if (!isWordBoundary(charsAfter, wordSeparators)) { - return null; - } - - // Extract the selection alone - CharSequence touching = getSelectedText(ic, selStart, selEnd); - if (TextUtils.isEmpty(touching)) return null; - // Is any part of the selection a separator? If so, return null. - final int length = touching.length(); - for (int i = 0; i < length; i++) { - if (wordSeparators.contains(touching.subSequence(i, i + 1))) { - return null; - } - } - // Prepare the selected word - SelectedWord selWord = new SelectedWord(); - selWord.start = selStart; - selWord.end = selEnd; - selWord.word = touching; - return selWord; - } - return null; - } - - /** - * Cache method pointers for performance - */ - private static void initializeMethodsForReflection() { - try { - // These will either both exist or not, so no need for separate try/catch blocks. - // If other methods are added later, use separate try/catch blocks. - sMethodGetSelectedText = InputConnection.class.getMethod("getSelectedText", int.class); - sMethodSetComposingRegion = InputConnection.class.getMethod("setComposingRegion", - int.class, int.class); - } catch (NoSuchMethodException exc) { - // Ignore - } - sMethodsInitialized = true; - } - - /** - * Returns the selected text between the selStart and selEnd positions. - */ - private static CharSequence getSelectedText(InputConnection ic, int selStart, int selEnd) { - // Use reflection, for backward compatibility - CharSequence result = null; - if (!sMethodsInitialized) { - initializeMethodsForReflection(); - } - if (sMethodGetSelectedText != null) { - try { - result = (CharSequence) sMethodGetSelectedText.invoke(ic, 0); - return result; - } catch (InvocationTargetException exc) { - // Ignore - } catch (IllegalArgumentException e) { - // Ignore - } catch (IllegalAccessException e) { - // Ignore - } - } - // Reflection didn't work, try it the poor way, by moving the cursor to the start, - // getting the text after the cursor and moving the text back to selected mode. - // TODO: Verify that this works properly in conjunction with - // LatinIME#onUpdateSelection - ic.setSelection(selStart, selEnd); - result = ic.getTextAfterCursor(selEnd - selStart, 0); - ic.setSelection(selStart, selEnd); - return result; - } - - /** - * Tries to set the text into composition mode if there is support for it in the framework. - */ - public static void underlineWord(InputConnection ic, SelectedWord word) { - // Use reflection, for backward compatibility - // If method not found, there's nothing we can do. It still works but just wont underline - // the word. - if (!sMethodsInitialized) { - initializeMethodsForReflection(); - } - if (sMethodSetComposingRegion != null) { - try { - sMethodSetComposingRegion.invoke(ic, word.start, word.end); - } catch (InvocationTargetException exc) { - // Ignore - } catch (IllegalArgumentException e) { - // Ignore - } catch (IllegalAccessException e) { - // Ignore - } - } - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ExpandableDictionary.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ExpandableDictionary.java deleted file mode 100644 index 95737626..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/ExpandableDictionary.java +++ /dev/null @@ -1,691 +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. - */ - -package keepass2android.softkeyboard; - -import java.util.LinkedList; - -import android.content.Context; -import android.os.AsyncTask; - -/** - * Base class for an in-memory dictionary that can grow dynamically and can - * be searched for suggestions and valid words. - */ -public class ExpandableDictionary extends Dictionary { - /** - * There is difference between what java and native code can handle. - * It uses 32 because Java stack overflows when greater value is used. - */ - protected static final int MAX_WORD_LENGTH = 32; - - private Context mContext; - private char[] mWordBuilder = new char[MAX_WORD_LENGTH]; - private int mDicTypeId; - private int mMaxDepth; - private int mInputLength; - private int[] mNextLettersFrequencies; - private StringBuilder sb = new StringBuilder(MAX_WORD_LENGTH); - - private static final char QUOTE = '\''; - - private boolean mRequiresReload; - - private boolean mUpdatingDictionary; - - // Use this lock before touching mUpdatingDictionary & mRequiresDownload - private Object mUpdatingLock = new Object(); - - static class Node { - char code; - int frequency; - boolean terminal; - Node parent; - NodeArray children; - LinkedList ngrams; // Supports ngram - } - - static class NodeArray { - Node[] data; - int length = 0; - private static final int INCREMENT = 2; - - NodeArray() { - data = new Node[INCREMENT]; - } - - void add(Node n) { - if (length + 1 > data.length) { - Node[] tempData = new Node[length + INCREMENT]; - if (length > 0) { - System.arraycopy(data, 0, tempData, 0, length); - } - data = tempData; - } - data[length++] = n; - } - } - - static class NextWord { - Node word; - NextWord nextWord; - int frequency; - - NextWord(Node word, int frequency) { - this.word = word; - this.frequency = frequency; - } - } - - - private NodeArray mRoots; - - private int[][] mCodes; - - ExpandableDictionary(Context context, int dicTypeId) { - mContext = context; - clearDictionary(); - mCodes = new int[MAX_WORD_LENGTH][]; - mDicTypeId = dicTypeId; - } - - public void loadDictionary() { - synchronized (mUpdatingLock) { - startDictionaryLoadingTaskLocked(); - } - } - - public void startDictionaryLoadingTaskLocked() { - if (!mUpdatingDictionary) { - mUpdatingDictionary = true; - mRequiresReload = false; - new LoadDictionaryTask().execute(); - } - } - - public void setRequiresReload(boolean reload) { - synchronized (mUpdatingLock) { - mRequiresReload = reload; - } - } - - public boolean getRequiresReload() { - return mRequiresReload; - } - - /** Override to load your dictionary here, on a background thread. */ - public void loadDictionaryAsync() { - } - - Context getContext() { - return mContext; - } - - int getMaxWordLength() { - return MAX_WORD_LENGTH; - } - - public void addWord(String word, int frequency) { - addWordRec(mRoots, word, 0, frequency, null); - } - - private void addWordRec(NodeArray children, final String word, final int depth, - final int frequency, Node parentNode) { - final int wordLength = word.length(); - final char c = word.charAt(depth); - // Does children have the current character? - final int childrenLength = children.length; - Node childNode = null; - boolean found = false; - for (int i = 0; i < childrenLength; i++) { - childNode = children.data[i]; - if (childNode.code == c) { - found = true; - break; - } - } - if (!found) { - childNode = new Node(); - childNode.code = c; - childNode.parent = parentNode; - children.add(childNode); - } - if (wordLength == depth + 1) { - // Terminate this word - childNode.terminal = true; - childNode.frequency = Math.max(frequency, childNode.frequency); - if (childNode.frequency > 255) childNode.frequency = 255; - return; - } - if (childNode.children == null) { - childNode.children = new NodeArray(); - } - addWordRec(childNode.children, word, depth + 1, frequency, childNode); - } - - @Override - public void getWords(final WordComposer codes, final WordCallback callback, - int[] nextLettersFrequencies) { - synchronized (mUpdatingLock) { - // If we need to update, start off a background task - if (mRequiresReload) startDictionaryLoadingTaskLocked(); - // Currently updating contacts, don't return any results. - if (mUpdatingDictionary) return; - } - - mInputLength = codes.size(); - mNextLettersFrequencies = nextLettersFrequencies; - if (mCodes.length < mInputLength) mCodes = new int[mInputLength][]; - // Cache the codes so that we don't have to lookup an array list - for (int i = 0; i < mInputLength; i++) { - mCodes[i] = codes.getCodesAt(i); - } - mMaxDepth = mInputLength * 3; - getWordsRec(mRoots, codes, mWordBuilder, 0, false, 1, 0, -1, callback); - for (int i = 0; i < mInputLength; i++) { - getWordsRec(mRoots, codes, mWordBuilder, 0, false, 1, 0, i, callback); - } - } - - @Override - public synchronized boolean isValidWord(CharSequence word) { - synchronized (mUpdatingLock) { - // If we need to update, start off a background task - if (mRequiresReload) startDictionaryLoadingTaskLocked(); - if (mUpdatingDictionary) return false; - } - final int freq = getWordFrequency(word); - return freq > -1; - } - - /** - * Returns the word's frequency or -1 if not found - */ - public int getWordFrequency(CharSequence word) { - Node node = searchNode(mRoots, word, 0, word.length()); - return (node == null) ? -1 : node.frequency; - } - - /** - * Recursively traverse the tree for words that match the input. Input consists of - * a list of arrays. Each item in the list is one input character position. An input - * character is actually an array of multiple possible candidates. This function is not - * optimized for speed, assuming that the user dictionary will only be a few hundred words in - * size. - * @param roots node whose children have to be search for matches - * @param codes the input character codes - * @param word the word being composed as a possible match - * @param depth the depth of traversal - the length of the word being composed thus far - * @param completion whether the traversal is now in completion mode - meaning that we've - * exhausted the input and we're looking for all possible suffixes. - * @param snr current weight of the word being formed - * @param inputIndex position in the input characters. This can be off from the depth in - * case we skip over some punctuations such as apostrophe in the traversal. That is, if you type - * "wouldve", it could be matching "would've", so the depth will be one more than the - * inputIndex - * @param callback the callback class for adding a word - */ - protected void getWordsRec(NodeArray roots, final WordComposer codes, final char[] word, - final int depth, boolean completion, int snr, int inputIndex, int skipPos, - WordCallback callback) { - final int count = roots.length; - final int codeSize = mInputLength; - // Optimization: Prune out words that are too long compared to how much was typed. - if (depth > mMaxDepth) { - return; - } - int[] currentChars = null; - if (codeSize <= inputIndex) { - completion = true; - } else { - currentChars = mCodes[inputIndex]; - } - - for (int i = 0; i < count; i++) { - final Node node = roots.data[i]; - final char c = node.code; - final char lowerC = toLowerCase(c); - final boolean terminal = node.terminal; - final NodeArray children = node.children; - final int freq = node.frequency; - if (completion) { - word[depth] = c; - if (terminal) { - if (!callback.addWord(word, 0, depth + 1, freq * snr, mDicTypeId, - DataType.UNIGRAM)) { - return; - } - // Add to frequency of next letters for predictive correction - if (mNextLettersFrequencies != null && depth >= inputIndex && skipPos < 0 - && mNextLettersFrequencies.length > word[inputIndex]) { - mNextLettersFrequencies[word[inputIndex]]++; - } - } - if (children != null) { - getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex, - skipPos, callback); - } - } else if ((c == QUOTE && currentChars[0] != QUOTE) || depth == skipPos) { - // Skip the ' and continue deeper - word[depth] = c; - if (children != null) { - getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex, - skipPos, callback); - } - } else { - // Don't use alternatives if we're looking for missing characters - final int alternativesSize = skipPos >= 0? 1 : currentChars.length; - for (int j = 0; j < alternativesSize; j++) { - final int addedAttenuation = (j > 0 ? 1 : 2); - final int currentChar = currentChars[j]; - if (currentChar == -1) { - break; - } - if (currentChar == lowerC || currentChar == c) { - word[depth] = c; - - if (codeSize == inputIndex + 1) { - if (terminal) { - if (INCLUDE_TYPED_WORD_IF_VALID - || !same(word, depth + 1, codes.getTypedWord())) { - int finalFreq = freq * snr * addedAttenuation; - if (skipPos < 0) finalFreq *= FULL_WORD_FREQ_MULTIPLIER; - callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId, - DataType.UNIGRAM); - } - } - if (children != null) { - getWordsRec(children, codes, word, depth + 1, - true, snr * addedAttenuation, inputIndex + 1, - skipPos, callback); - } - } else if (children != null) { - getWordsRec(children, codes, word, depth + 1, - false, snr * addedAttenuation, inputIndex + 1, - skipPos, callback); - } - } - } - } - } - } - - protected int setBigram(String word1, String word2, int frequency) { - return addOrSetBigram(word1, word2, frequency, false); - } - - protected int addBigram(String word1, String word2, int frequency) { - return addOrSetBigram(word1, word2, frequency, true); - } - - /** - * Adds bigrams to the in-memory trie structure that is being used to retrieve any word - * @param frequency frequency for this bigrams - * @param addFrequency if true, it adds to current frequency - * @return returns the final frequency - */ - private int addOrSetBigram(String word1, String word2, int frequency, boolean addFrequency) { - Node firstWord = searchWord(mRoots, word1, 0, null); - Node secondWord = searchWord(mRoots, word2, 0, null); - LinkedList bigram = firstWord.ngrams; - if (bigram == null || bigram.size() == 0) { - firstWord.ngrams = new LinkedList(); - bigram = firstWord.ngrams; - } else { - for (NextWord nw : bigram) { - if (nw.word == secondWord) { - if (addFrequency) { - nw.frequency += frequency; - } else { - nw.frequency = frequency; - } - return nw.frequency; - } - } - } - NextWord nw = new NextWord(secondWord, frequency); - firstWord.ngrams.add(nw); - return frequency; - } - - /** - * Searches for the word and add the word if it does not exist. - * @return Returns the terminal node of the word we are searching for. - */ - private Node searchWord(NodeArray children, String word, int depth, Node parentNode) { - final int wordLength = word.length(); - final char c = word.charAt(depth); - // Does children have the current character? - final int childrenLength = children.length; - Node childNode = null; - boolean found = false; - for (int i = 0; i < childrenLength; i++) { - childNode = children.data[i]; - if (childNode.code == c) { - found = true; - break; - } - } - if (!found) { - childNode = new Node(); - childNode.code = c; - childNode.parent = parentNode; - children.add(childNode); - } - if (wordLength == depth + 1) { - // Terminate this word - childNode.terminal = true; - return childNode; - } - if (childNode.children == null) { - childNode.children = new NodeArray(); - } - return searchWord(childNode.children, word, depth + 1, childNode); - } - - // @VisibleForTesting - boolean reloadDictionaryIfRequired() { - synchronized (mUpdatingLock) { - // If we need to update, start off a background task - if (mRequiresReload) startDictionaryLoadingTaskLocked(); - // Currently updating contacts, don't return any results. - return mUpdatingDictionary; - } - } - - private void runReverseLookUp(final CharSequence previousWord, final WordCallback callback) { - Node prevWord = searchNode(mRoots, previousWord, 0, previousWord.length()); - if (prevWord != null && prevWord.ngrams != null) { - reverseLookUp(prevWord.ngrams, callback); - } - } - - @Override - public void getBigrams(final WordComposer codes, final CharSequence previousWord, - final WordCallback callback, int[] nextLettersFrequencies) { - if (!reloadDictionaryIfRequired()) { - runReverseLookUp(previousWord, callback); - } - } - - /** - * Used only for testing purposes - * This function will wait for loading from database to be done - */ - void waitForDictionaryLoading() { - while (mUpdatingDictionary) { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - } - } - } - - /** - * reverseLookUp retrieves the full word given a list of terminal nodes and adds those words - * through callback. - * @param terminalNodes list of terminal nodes we want to add - */ - private void reverseLookUp(LinkedList terminalNodes, - final WordCallback callback) { - Node node; - int freq; - for (NextWord nextWord : terminalNodes) { - node = nextWord.word; - freq = nextWord.frequency; - // TODO Not the best way to limit suggestion threshold - if (freq >= UserBigramDictionary.SUGGEST_THRESHOLD) { - sb.setLength(0); - do { - sb.insert(0, node.code); - node = node.parent; - } while(node != null); - - // TODO better way to feed char array? - callback.addWord(sb.toString().toCharArray(), 0, sb.length(), freq, mDicTypeId, - DataType.BIGRAM); - } - } - } - - /** - * Search for the terminal node of the word - * @return Returns the terminal node of the word if the word exists - */ - private Node searchNode(final NodeArray children, final CharSequence word, final int offset, - final int length) { - // TODO Consider combining with addWordRec - final int count = children.length; - char currentChar = word.charAt(offset); - for (int j = 0; j < count; j++) { - final Node node = children.data[j]; - if (node.code == currentChar) { - if (offset == length - 1) { - if (node.terminal) { - return node; - } - } else { - if (node.children != null) { - Node returnNode = searchNode(node.children, word, offset + 1, length); - if (returnNode != null) return returnNode; - } - } - } - } - return null; - } - - protected void clearDictionary() { - mRoots = new NodeArray(); - } - - private class LoadDictionaryTask extends AsyncTask { - @Override - protected Void doInBackground(Void... v) { - loadDictionaryAsync(); - synchronized (mUpdatingLock) { - mUpdatingDictionary = false; - } - return null; - } - } - - static char toLowerCase(char c) { - if (c < BASE_CHARS.length) { - c = BASE_CHARS[c]; - } - if (c >= 'A' && c <= 'Z') { - c = (char) (c | 32); - } else if (c > 127) { - c = Character.toLowerCase(c); - } - return c; - } - - /** - * 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 final char 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/java/src/keepass2android/softkeyboard/Hints.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Hints.java deleted file mode 100644 index 58c15cd8..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/Hints.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2009 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.content.ContentResolver; -import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.view.inputmethod.InputConnection; - -import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; - -/** - * Logic to determine when to display hints on usage to the user. - */ -public class Hints { - public interface Display { - public void showHint(int viewResource); - } - - private static final String PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN = - "voice_hint_num_unique_days_shown"; - private static final String PREF_VOICE_HINT_LAST_TIME_SHOWN = - "voice_hint_last_time_shown"; - private static final String PREF_VOICE_INPUT_LAST_TIME_USED = - "voice_input_last_time_used"; - private static final String PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT = - "voice_punctuation_hint_view_count"; - private static final int DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW = 7; - private static final int DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS = 7; - - private Context mContext; - private Display mDisplay; - private boolean mVoiceResultContainedPunctuation; - private int mSwipeHintMaxDaysToShow; - private int mPunctuationHintMaxDisplays; - - // Only show punctuation hint if voice result did not contain punctuation. - static final Map SPEAKABLE_PUNCTUATION - = new HashMap(); - static { - SPEAKABLE_PUNCTUATION.put(",", "comma"); - SPEAKABLE_PUNCTUATION.put(".", "period"); - SPEAKABLE_PUNCTUATION.put("?", "question mark"); - } - - public Hints(Context context, Display display) { - mContext = context; - mDisplay = display; - - ContentResolver cr = mContext.getContentResolver(); - - } - - public boolean showSwipeHintIfNecessary(boolean fieldRecommended) { - if (fieldRecommended && shouldShowSwipeHint()) { - showHint(R.layout.voice_swipe_hint); - return true; - } - - return false; - } - - public boolean showPunctuationHintIfNecessary(InputConnection ic) { - if (!mVoiceResultContainedPunctuation - && ic != null - && getAndIncrementPref(PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT) - < mPunctuationHintMaxDisplays) { - CharSequence charBeforeCursor = ic.getTextBeforeCursor(1, 0); - if (SPEAKABLE_PUNCTUATION.containsKey(charBeforeCursor)) { - showHint(R.layout.voice_punctuation_hint); - return true; - } - } - - return false; - } - - public void registerVoiceResult(String text) { - // Update the current time as the last time voice input was used. - SharedPreferences.Editor editor = - PreferenceManager.getDefaultSharedPreferences(mContext).edit(); - editor.putLong(PREF_VOICE_INPUT_LAST_TIME_USED, System.currentTimeMillis()); - SharedPreferencesCompat.apply(editor); - - mVoiceResultContainedPunctuation = false; - for (CharSequence s : SPEAKABLE_PUNCTUATION.keySet()) { - if (text.indexOf(s.toString()) >= 0) { - mVoiceResultContainedPunctuation = true; - break; - } - } - } - - private boolean shouldShowSwipeHint() { - - - return false; - } - - /** - * Determines whether the provided time is from some time today (i.e., this day, month, - * and year). - */ - private boolean isFromToday(long timeInMillis) { - if (timeInMillis == 0) return false; - - Calendar today = Calendar.getInstance(); - today.setTimeInMillis(System.currentTimeMillis()); - - Calendar timestamp = Calendar.getInstance(); - timestamp.setTimeInMillis(timeInMillis); - - return (today.get(Calendar.YEAR) == timestamp.get(Calendar.YEAR) && - today.get(Calendar.DAY_OF_MONTH) == timestamp.get(Calendar.DAY_OF_MONTH) && - today.get(Calendar.MONTH) == timestamp.get(Calendar.MONTH)); - } - - private void showHint(int hintViewResource) { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); - - int numUniqueDaysShown = sp.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0); - long lastTimeHintWasShown = sp.getLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, 0); - - // If this is the first time the hint is being shown today, increase the saved values - // to represent that. We don't need to increase the last time the hint was shown unless - // it is a different day from the current value. - if (!isFromToday(lastTimeHintWasShown)) { - SharedPreferences.Editor editor = sp.edit(); - editor.putInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, numUniqueDaysShown + 1); - editor.putLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, System.currentTimeMillis()); - SharedPreferencesCompat.apply(editor); - } - - if (mDisplay != null) { - mDisplay.showHint(hintViewResource); - } - } - - private int getAndIncrementPref(String pref) { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); - int value = sp.getInt(pref, 0); - SharedPreferences.Editor editor = sp.edit(); - editor.putInt(pref, value + 1); - SharedPreferencesCompat.apply(editor); - return value; - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/InputLanguageSelection.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/InputLanguageSelection.java deleted file mode 100644 index 66cb46f0..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/InputLanguageSelection.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) 2008-2009 Google Inc. - * Copyright (C) 2014 Philipp Crocoll - * Copyright (C) 2014 Wiktor Lawski - * - * 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.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.PreferenceActivity; -import android.preference.PreferenceGroup; -import android.preference.PreferenceManager; -import android.text.TextUtils; - -import java.text.Collator; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Locale; - -public class InputLanguageSelection extends PreferenceActivity { - - private String mSelectedLanguages; - private ArrayList mAvailableLanguages = new ArrayList(); - - private static final String[] WHITELIST_LANGUAGES = { - "cs", "da", "de", "en_GB", "en_US", "es", "es_US", "fr", "it", "nb", "nl", "pl", "pt", - "ru", "tr" - }; - - private static final String[] WEAK_WHITELIST_LANGUAGES = { - "cs", "da", "de", "en_GB", "en_US", "es", "es_US", "fr", "it", "nb", "nl", "pl", "pt", - "ru", "tr", "en" - }; - - private static boolean isWhitelisted(String lang, boolean strict) { - for (String s : (strict? WHITELIST_LANGUAGES : WEAK_WHITELIST_LANGUAGES)) { - if (s.equalsIgnoreCase(lang)) { - return true; - } - if ((!strict) && (s.length()==2) && lang.toLowerCase(Locale.US).startsWith(s)) - { - return true; - } - } - return false; - } - - private static class Loc implements Comparable { - static Collator sCollator = Collator.getInstance(); - - String label; - Locale locale; - - public Loc(String label, Locale locale) { - this.label = label; - this.locale = locale; - } - - @Override - public String toString() { - return this.label; - } - - public int compareTo(Object o) { - return sCollator.compare(this.label, ((Loc) o).label); - } - } - - @Override - protected void onCreate(Bundle icicle) { - // Get the settings preferences - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); - - Design.updateTheme(this, sp); - - super.onCreate(icicle); - addPreferencesFromResource(R.xml.language_prefs); - mSelectedLanguages = sp.getString(KP2AKeyboard.PREF_SELECTED_LANGUAGES, ""); - String[] languageList = mSelectedLanguages.split(","); - - //first try to get the unique locales in a strict mode (filtering most redundant layouts like English (Jamaica) etc.) - mAvailableLanguages = getUniqueLocales(true); - //sometimes the strict check returns only EN_US, EN_GB and ES_US. Accept more in these cases: - if (mAvailableLanguages.size() < 5) - { - mAvailableLanguages = getUniqueLocales(false); - } - PreferenceGroup parent = getPreferenceScreen(); - for (int i = 0; i < mAvailableLanguages.size(); i++) { - CheckBoxPreference pref = new CheckBoxPreference(this); - Locale locale = mAvailableLanguages.get(i).locale; - pref.setTitle(LanguageSwitcher.toTitleCase(locale.getDisplayName(locale), locale)); - boolean checked = isLocaleIn(locale, languageList); - pref.setChecked(checked); - if (hasDictionary(locale, this)) { - pref.setSummary(R.string.has_dictionary); - } - parent.addPreference(pref); - } - } - - private boolean isLocaleIn(Locale locale, String[] list) { - String lang = get5Code(locale); - for (int i = 0; i < list.length; i++) { - if (lang.equalsIgnoreCase(list[i])) return true; - } - return false; - } - - private boolean hasDictionary(Locale locale, Context ctx) { - Resources res = getResources(); - Configuration conf = res.getConfiguration(); - Locale saveLocale = conf.locale; - boolean haveDictionary = false; - conf.locale = locale; - res.updateConfiguration(conf, res.getDisplayMetrics()); - - //somewhat a hack. But simply querying the dictionary will always return an English - //dictionary in KP2A so if we get a dict, we wouldn't know if it's language specific - if (locale.getLanguage().equals("en")) - { - haveDictionary = true; - } - else - { - BinaryDictionary plug = PluginManager.getDictionary(getApplicationContext(), locale.getLanguage()); - if (plug != null) { - plug.close(); - haveDictionary = true; - } - } - conf.locale = saveLocale; - res.updateConfiguration(conf, res.getDisplayMetrics()); - return haveDictionary; - } - - private String get5Code(Locale locale) { - String country = locale.getCountry(); - return locale.getLanguage() - + (TextUtils.isEmpty(country) ? "" : "_" + country); - } - - @Override - protected void onResume() { - super.onResume(); - } - - @Override - protected void onPause() { - super.onPause(); - // Save the selected languages - String checkedLanguages = ""; - PreferenceGroup parent = getPreferenceScreen(); - int count = parent.getPreferenceCount(); - for (int i = 0; i < count; i++) { - CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i); - if (pref.isChecked()) { - Locale locale = mAvailableLanguages.get(i).locale; - checkedLanguages += get5Code(locale) + ","; - } - } - if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); - Editor editor = sp.edit(); - editor.putString(KP2AKeyboard.PREF_SELECTED_LANGUAGES, checkedLanguages); - SharedPreferencesCompat.apply(editor); - } - - ArrayList getUniqueLocales(boolean strict) { - String[] locales = getAssets().getLocales(); - Arrays.sort(locales); - ArrayList uniqueLocales = new ArrayList(); - - final int origSize = locales.length; - Loc[] preprocess = new Loc[origSize]; - int finalSize = 0; - for (int i = 0 ; i < origSize; i++ ) { - String s = locales[i]; - - int len = s.length(); - final Locale l; - final String language; - if (len == 5) { - language = s.substring(0, 2); - String country = s.substring(3, 5); - l = new Locale(language, country); - } else if (len == 2) { - language = s; - l = new Locale(language); - } else { - android.util.Log.d("KP2AK", "locale "+s+" has unexpected length."); - continue; - } - // Exclude languages that are not relevant to LatinIME - if (!isWhitelisted(s, strict)) - { - android.util.Log.d("KP2AK", "locale "+s+" is not white-listed"); - continue; - } - - android.util.Log.d("KP2AK", "adding locale "+s); - if (finalSize == 0) { - preprocess[finalSize++] = - new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName(l), l), l); - } else { - // check previous entry: - // same lang and a country -> upgrade to full name and - // insert ours with full name - // diff lang -> insert ours with lang-only name - if (preprocess[finalSize-1].locale.getLanguage().equals( - language)) { - preprocess[finalSize-1].label = LanguageSwitcher.toTitleCase( - preprocess[finalSize-1].locale.getDisplayName(), - preprocess[finalSize-1].locale); - preprocess[finalSize++] = - new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName(), l), l); - } else { - String displayName; - if (s.equals("zz_ZZ")) { - } else { - displayName = LanguageSwitcher.toTitleCase(l.getDisplayName(l), l); - preprocess[finalSize++] = new Loc(displayName, l); - } - } - } - } - for (int i = 0; i < finalSize ; i++) { - uniqueLocales.add(preprocess[i]); - } - return uniqueLocales; - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/KP2AKeyboard.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/KP2AKeyboard.java deleted file mode 100644 index a0a5dfde..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/KP2AKeyboard.java +++ /dev/null @@ -1,2598 +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.app.AlertDialog; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.XmlResourceParser; -import android.inputmethodservice.InputMethodService; -import android.inputmethodservice.Keyboard; -import android.media.AudioManager; -import android.os.Debug; -import android.os.Handler; -import android.os.Message; -import android.os.SystemClock; -import android.preference.PreferenceActivity; -import android.preference.PreferenceManager; -import android.text.ClipboardManager; -import android.text.TextUtils; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.PrintWriterPrinter; -import android.util.Printer; -import android.view.HapticFeedbackConstants; -import android.view.KeyEvent; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.view.inputmethod.CompletionInfo; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.ExtractedText; -import android.view.inputmethod.ExtractedTextRequest; -import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; -import android.widget.LinearLayout; - -import keepass2android.kbbridge.StringForTyping; -import keepass2android.softkeyboard.LatinIMEUtil.RingCharBuffer; - -import org.xmlpull.v1.XmlPullParserException; - -import java.io.FileDescriptor; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -/** - * Input method implementation for Qwerty'ish keyboard. - */ -public class KP2AKeyboard extends InputMethodService - implements LatinKeyboardBaseView.OnKeyboardActionListener, - SharedPreferences.OnSharedPreferenceChangeListener { - private static String get_KEEPASS2ANDROID_KEYBOARD_CLEARED(Context ctx) - { - return ctx.getPackageName()+".keyboard_cleared"; - } - private static final String KP2A_SAVED_FIELD_HINTS = "savedFieldHints"; - private static final String PREF_KP2A_REMEMBER_AUTO_FILL = "kp2a_remember_auto_fill"; - private static final String TAG = "LatinIME"; - private static final boolean PERF_DEBUG = false; - static final boolean DEBUG = false; - static final boolean TRACE = false; - - private static final String PREF_VIBRATE_ON = "vibrate_on"; - private static final String PREF_SOUND_ON = "sound_on"; - private static final String PREF_POPUP_ON = "popup_on"; - private static final String PREF_AUTO_CAP = "auto_cap"; - private static final String PREF_QUICK_FIXES = "quick_fixes"; - private static final String PREF_SHOW_SUGGESTIONS = "show_suggestions"; - private static final String PREF_AUTO_COMPLETE = "auto_complete"; - //private static final String PREF_BIGRAM_SUGGESTIONS = "bigram_suggestion"; - - - public static final String PREF_SELECTED_LANGUAGES = "selected_languages"; - public static final String PREF_INPUT_LANGUAGE = "input_language"; - private static final String PREF_RECORRECTION_ENABLED = "recorrection_enabled"; - - private static final int MSG_UPDATE_SUGGESTIONS = 0; - private static final int MSG_UPDATE_SHIFT_STATE = 2; - - private static final int MSG_UPDATE_OLD_SUGGESTIONS = 4; - - // How many continuous deletes at which to start deleting at a higher speed. - private static final int DELETE_ACCELERATE_AT = 20; - // Key events coming any faster than this are long-presses. - private static final int QUICK_PRESS = 200; - - static final int KEYCODE_ENTER = '\n'; - static final int KEYCODE_SPACE = ' '; - static final int KEYCODE_PERIOD = '.'; - - // Contextual menu positions - private static final int POS_METHOD = 0; - private static final int POS_SETTINGS = 1; - - //private LatinKeyboardView mInputView; - private LinearLayout mCandidateViewContainer; - private CandidateView mCandidateView; - private Suggest mSuggest; - private CompletionInfo[] mCompletions; - - private AlertDialog mOptionsDialog; - - /* package */ KeyboardSwitcher mKeyboardSwitcher; - - //dictionaries disabled for KP2A to reduce permissions - //private UserDictionary mUserDictionary; - //private UserBigramDictionary mUserBigramDictionary; - //private ContactsDictionary mContactsDictionary; - //private AutoDictionary mAutoDictionary; - - private Resources mResources; - - private String mInputLocale; - private String mSystemLocale; - private LanguageSwitcher mLanguageSwitcher; - - private StringBuilder mComposing = new StringBuilder(); - private WordComposer mWord = new WordComposer(); - private int mCommittedLength; - private boolean mPredicting; - private boolean mRecognizing; - private CharSequence mBestWord; - private boolean mPredictionOn; - private boolean mCompletionOn; - private boolean mHasDictionary; - private boolean mAutoSpace; - private boolean mJustAddedAutoSpace; - private boolean mAutoCorrectEnabled; - private boolean mReCorrectionEnabled; - // Bigram Suggestion is disabled in this version. - private final boolean mBigramSuggestionEnabled = false; - private boolean mAutoCorrectOn; - // TODO move this state variable outside LatinIME - private boolean mCapsLock; - private boolean mVibrateOn; - private boolean mSoundOn; - private boolean mPopupOn; - private boolean mAutoCap; - private boolean mQuickFixes; - private boolean mKp2aAutoFillOn; - private boolean mKp2aRememberAutoFill; - private boolean mKp2aEnableSimpleKeyboard; - private boolean mKp2aSwitchKeyboardOnSendGoDone; - private boolean mKp2aLockOnSendGoDone; - - private boolean mIsSendGoDone; - - - private boolean mShowSuggestions; - private boolean mIsShowingHint; - private int mCorrectionMode; - private int mOrientation; - private List mSuggestPuncList; - // Keep track of the last selection range to decide if we need to show word alternatives - private int mLastSelectionStart; - private int mLastSelectionEnd; - - // Input type is such that we should not auto-correct - private boolean mInputTypeNoAutoCorrect; - - // Indicates whether the suggestion strip is to be on in landscape - private boolean mJustAccepted; - private CharSequence mJustRevertedSeparator; - private int mDeleteCount; - private long mLastKeyTime; - - // Modifier keys state - private ModifierKeyState mShiftKeyState = new ModifierKeyState(); - private ModifierKeyState mSymbolKeyState = new ModifierKeyState(); - - - private AudioManager mAudioManager; - // Align sound effect volume on music volume - private final float FX_VOLUME = -1.0f; - private boolean mSilentMode; - - /* package */ String mWordSeparators; - private String mSentenceSeparators; - private String mSuggestPuncs; - private boolean mConfigurationChanging; - - // Keeps track of most recently inserted text (multi-character key) for reverting - private CharSequence mEnteredText; - private boolean mRefreshKeyboardRequired; - - //KP2A - private boolean mShowKp2aKeyboard; //true if the user wants to see/should see the Kp2a keyboard - private boolean mHadKp2aData; //true if we already had data available in the last session - - // For each word, a list of potential replacements, usually from voice. - private Map> mWordToSuggestions = - new HashMap>(); - - private ArrayList mWordHistory = new ArrayList(); - - - public abstract static class WordAlternatives { - protected CharSequence mChosenWord; - - public WordAlternatives() { - // Nothing - } - - public WordAlternatives(CharSequence chosenWord) { - mChosenWord = chosenWord; - } - - @Override - public int hashCode() { - return mChosenWord.hashCode(); - } - - public abstract CharSequence getOriginalWord(); - - public CharSequence getChosenWord() { - return mChosenWord; - } - - public abstract List getAlternatives(); - } - - public class TypedWordAlternatives extends WordAlternatives { - private WordComposer word; - - public TypedWordAlternatives() { - // Nothing - } - - public TypedWordAlternatives(CharSequence chosenWord, WordComposer wordComposer) { - super(chosenWord); - word = wordComposer; - } - - @Override - public CharSequence getOriginalWord() { - return word.getTypedWord(); - } - - @Override - public List getAlternatives() { - return getTypedSuggestions(word); - } - } - - /* package */ Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_UPDATE_SUGGESTIONS: - updateSuggestions(); - break; - case MSG_UPDATE_OLD_SUGGESTIONS: - setOldSuggestions(); - break; - case MSG_UPDATE_SHIFT_STATE: - updateShiftKeyState(getCurrentInputEditorInfo()); - break; - - } - } - }; - private ClearKeyboardBroadcastReceiver mClearKeyboardReceiver; - private PluginManager mPluginManager; - - public class ClearKeyboardBroadcastReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - android.util.Log.d("KP2AK", "received clear keyboard broadcast"); - mShowKp2aKeyboard = false; - updateKeyboardMode(getCurrentInputEditorInfo()); - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); - boolean switchback = sp.getBoolean("AutoSwitchBackKeyboard_key", true); - if (switchback) - { - //switch back, but only "silently" (i.e. if automatic switching is enabled and available) - keepass2android.kbbridge.ImeSwitcher.switchToPreviousKeyboard(KP2AKeyboard.this, true); - } - } - - } - - - - - @Override - public void onCreate() { - LatinImeLogger.init(this); - KeyboardSwitcher.init(this); - super.onCreate(); - //setStatusIcon(R.drawable.ime_qwerty); - mResources = getResources(); - final Configuration conf = mResources.getConfiguration(); - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - mLanguageSwitcher = new LanguageSwitcher(this); - mLanguageSwitcher.loadLocales(prefs); - mKeyboardSwitcher = KeyboardSwitcher.getInstance(); - mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher); - mSystemLocale = conf.locale.toString(); - mLanguageSwitcher.setSystemLocale(conf.locale); - String inputLanguage = mLanguageSwitcher.getInputLanguage(); - if (inputLanguage == null) { - inputLanguage = conf.locale.toString(); - } - mReCorrectionEnabled = prefs.getBoolean(PREF_RECORRECTION_ENABLED, - getResources().getBoolean(R.bool.default_recorrection_enabled)); - - Log.d("KP2AK","finding plugin dicts..."); - PluginManager.getPluginDictionaries(getApplicationContext()); - mPluginManager = new PluginManager(this); - final IntentFilter pFilter = new IntentFilter(); - pFilter.addDataScheme("package"); - pFilter.addAction("android.intent.action.PACKAGE_ADDED"); - pFilter.addAction("android.intent.action.PACKAGE_REPLACED"); - pFilter.addAction("android.intent.action.PACKAGE_REMOVED"); - registerReceiver(mPluginManager, pFilter); - - - LatinIMEUtil.GCUtils.getInstance().reset(); - boolean tryGC = true; - for (int i = 0; i < LatinIMEUtil.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { - try { - initSuggest(inputLanguage); - tryGC = false; - } catch (OutOfMemoryError e) { - tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait(inputLanguage, e); - } - } - - mOrientation = conf.orientation; - initSuggestPuncList(); - - // register to receive ringer mode changes for silent mode - IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION); - registerReceiver(mReceiver, filter); - - prefs.registerOnSharedPreferenceChangeListener(this); - - //check if we have KP2A data available: - mHadKp2aData = mShowKp2aKeyboard = keepass2android.kbbridge.KeyboardData.hasData(); - - mClearKeyboardReceiver = new ClearKeyboardBroadcastReceiver(); - registerReceiver(mClearKeyboardReceiver, new IntentFilter(get_KEEPASS2ANDROID_KEYBOARD_CLEARED(this))); - android.util.Log.d("KP2AK", "registered receiver for clear keyboard broadcast: "+get_KEEPASS2ANDROID_KEYBOARD_CLEARED(this)); - - } - - /** - * Loads a dictionary or multiple separated dictionary - * @param ctx - * @return returns array of dictionary resource ids - */ - /* package */ static int[] getDictionary(Resources res, Context ctx) { - String packageName = KP2AKeyboard.class.getPackage().getName(); - Log.d("KP2AK", "package of keyboard " + packageName); - XmlResourceParser xrp = res.getXml(R.xml.dictionary); - ArrayList dictionaries = new ArrayList(); - - 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("part")) { - String dictFileName = xrp.getAttributeValue(null, "name"); - int dictId = res.getIdentifier(dictFileName, "raw", ctx.getPackageName()); - Log.d("KP2AK", "Adding " + packageName+"/"+dictFileName+"/"+dictId); - dictionaries.add(dictId); - } - } - } - xrp.next(); - current = xrp.getEventType(); - } - } catch (XmlPullParserException e) { - Log.e(TAG, "Dictionary XML parsing failure"); - } catch (IOException e) { - Log.e(TAG, "Dictionary XML IOException"); - } - - int count = dictionaries.size(); - int[] dict = new int[count]; - for (int i = 0; i < count; i++) { - dict[i] = dictionaries.get(i); - } - - Log.d("KP2AK", "num dicts: " + count); - - return dict; - } - - private void initSuggest(String locale) { - mInputLocale = locale; - - Resources orig = getResources(); - Configuration conf = orig.getConfiguration(); - Locale saveLocale = conf.locale; - conf.locale = new Locale(locale); - orig.updateConfiguration(conf, orig.getDisplayMetrics()); - if (mSuggest != null) { - mSuggest.close(); - } - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); - mQuickFixes = sp.getBoolean(PREF_QUICK_FIXES, true); - - int[] dictionaries = getDictionary(orig, this); - mSuggest = new Suggest(this, dictionaries); - updateAutoTextEnabled(saveLocale); - //if (mUserDictionary != null) mUserDictionary.close(); - //mUserDictionary = new UserDictionary(this, mInputLocale); - /*if (mContactsDictionary == null) { - mContactsDictionary = new ContactsDictionary(this, Suggest.DIC_CONTACTS); - } - if (mAutoDictionary != null) { - mAutoDictionary.close(); - } - mAutoDictionary = new AutoDictionary(this, this, mInputLocale, Suggest.DIC_AUTO);*/ - //if (mUserBigramDictionary != null) { - // mUserBigramDictionary.close(); - //} - //mUserBigramDictionary = new UserBigramDictionary(this, this, mInputLocale, - // Suggest.DIC_USER); - /*mSuggest.setUserBigramDictionary(mUserBigramDictionary); - mSuggest.setUserDictionary(mUserDictionary); - mSuggest.setContactsDictionary(mContactsDictionary); - mSuggest.setAutoDictionary(mAutoDictionary);*/ - updateCorrectionMode(); - mWordSeparators = mResources.getString(R.string.word_separators); - mSentenceSeparators = mResources.getString(R.string.sentence_separators); - - conf.locale = saveLocale; - orig.updateConfiguration(conf, orig.getDisplayMetrics()); - } - - @Override - public void onDestroy() { - /*if (mUserDictionary != null) { - mUserDictionary.close(); - } - if (mContactsDictionary != null) { - mContactsDictionary.close(); - }*/ - unregisterReceiver(mReceiver); - unregisterReceiver(mPluginManager); - unregisterReceiver(mClearKeyboardReceiver); - - LatinImeLogger.commit(); - LatinImeLogger.onDestroy(); - super.onDestroy(); - } - - @Override - public void onConfigurationChanged(Configuration conf) { - // If the system locale changes and is different from the saved - // locale (mSystemLocale), then reload the input locale list from the - // latin ime settings (shared prefs) and reset the input locale - // to the first one. - final String systemLocale = conf.locale.toString(); - if (!TextUtils.equals(systemLocale, mSystemLocale)) { - mSystemLocale = systemLocale; - if (mLanguageSwitcher != null) { - mLanguageSwitcher.loadLocales( - PreferenceManager.getDefaultSharedPreferences(this)); - mLanguageSwitcher.setSystemLocale(conf.locale); - toggleLanguage(true, true); - } else { - reloadKeyboards(); - } - } - // If orientation changed while predicting, commit the change - if (conf.orientation != mOrientation) { - InputConnection ic = getCurrentInputConnection(); - commitTyped(ic); - if (ic != null) ic.finishComposingText(); // For voice input - mOrientation = conf.orientation; - reloadKeyboards(); - } - mConfigurationChanging = true; - super.onConfigurationChanged(conf); - mConfigurationChanging = false; - } - - @Override - public View onCreateInputView() { - mKeyboardSwitcher.recreateInputView(); - mKeyboardSwitcher.makeKeyboards(true); - - loadSettings(); - - updateShowKp2aMode(); - Log.d("KP2AK", "onCreateInputView -> setKM"); - if ((mShowKp2aKeyboard) && (mKp2aEnableSimpleKeyboard)) - { - mKeyboardSwitcher.setKeyboardMode( - KeyboardSwitcher.MODE_KP2A, 0); - } - else - { - mKeyboardSwitcher.setKeyboardMode( - KeyboardSwitcher.MODE_TEXT, 0); - } - - return mKeyboardSwitcher.getInputView(); - } - - @Override - public View onCreateCandidatesView() { - mKeyboardSwitcher.makeKeyboards(true); - mCandidateViewContainer = (LinearLayout) getLayoutInflater().inflate( - R.layout.candidates, null); - mCandidateView = (CandidateView) mCandidateViewContainer.findViewById(R.id.candidates); - mCandidateView.setService(this); - setCandidatesViewShown(true); - return mCandidateViewContainer; - } - - @Override - public void onStartInputView(EditorInfo attribute, boolean restarting) { - LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); - // In landscape mode, this method gets called without the input view being created. - if (inputView == null) { - return; - } - - loadSettings(); - - if (mRefreshKeyboardRequired) { - mRefreshKeyboardRequired = false; - toggleLanguage(true, true); - } - - mKeyboardSwitcher.makeKeyboards(false); - - TextEntryState.newSession(this); - - updateKeyboardMode(attribute); - inputView.closing(); - mComposing.setLength(0); - mPredicting = false; - mDeleteCount = 0; - mJustAddedAutoSpace = false; - mIsSendGoDone = ((attribute.imeOptions&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) == EditorInfo.IME_ACTION_GO) - || ((attribute.imeOptions&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) == EditorInfo.IME_ACTION_DONE) - || ((attribute.imeOptions&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) == EditorInfo.IME_ACTION_SEND); - - updateShiftKeyState(attribute); - - setCandidatesViewShownInternal(isCandidateStripVisible() || mCompletionOn, - false /* needsInputViewShown */ ); - updateSuggestions(); - - // If the dictionary is not big enough, don't auto correct - mHasDictionary = mSuggest.hasMainDictionary(); - Log.d("KP2AK", "has main dict: " + mHasDictionary); - - updateCorrectionMode(); - - inputView.setPreviewEnabled(mPopupOn); - inputView.setProximityCorrectionEnabled(true); - mPredictionOn = mPredictionOn && (mCorrectionMode > 0 || mShowSuggestions); - // If we just entered a text field, maybe it has some old text that requires correction - checkReCorrectionOnStart(); - - tryKp2aAutoFill(attribute); - - if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); - } - - private void updateKeyboardMode(EditorInfo attribute) { - - mInputTypeNoAutoCorrect = false; - mPredictionOn = false; - mCompletionOn = false; - mCompletions = null; - mCapsLock = false; - mEnteredText = null; - - int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION; - - updateShowKp2aMode(); - Log.d("KP2AK", "updateKeyboardMode -> setKM"); - if ((mShowKp2aKeyboard) && (mKp2aEnableSimpleKeyboard)) - { - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_KP2A, attribute.imeOptions); - mPredictionOn = false; - mPredicting = false; - mCompletionOn = false; - mInputTypeNoAutoCorrect = true; - } - else - { - - switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) { - case EditorInfo.TYPE_CLASS_NUMBER: - case EditorInfo.TYPE_CLASS_DATETIME: - // fall through - // NOTE: For now, we use the phone keyboard for NUMBER and DATETIME until we get - // a dedicated number entry keypad. - // TODO: Use a dedicated number entry keypad here when we get one. - case EditorInfo.TYPE_CLASS_PHONE: - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_PHONE, - attribute.imeOptions); - break; - case EditorInfo.TYPE_CLASS_TEXT: - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, - attribute.imeOptions); - //startPrediction(); - mPredictionOn = true; - // Make sure that passwords are not displayed in candidate view - if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD || - variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ) { - mPredictionOn = false; - } - if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS - || variation == EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME) { - mAutoSpace = false; - } else { - mAutoSpace = true; - } - if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) { - mPredictionOn = false; - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_EMAIL, - attribute.imeOptions); - } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) { - mPredictionOn = false; - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_URL, - attribute.imeOptions); - } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_IM, - attribute.imeOptions); - } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) { - mPredictionOn = false; - } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) { - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_WEB, - attribute.imeOptions); - // If it's a browser edit field and auto correct is not ON explicitly, then - // disable auto correction, but keep suggestions on. - if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) { - mInputTypeNoAutoCorrect = true; - } - } - - // If NO_SUGGESTIONS is set, don't do prediction. - if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) { - mPredictionOn = false; - mInputTypeNoAutoCorrect = true; - } - // If it's not multiline and the autoCorrect flag is not set, then don't correct - if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 && - (attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0) { - mInputTypeNoAutoCorrect = true; - } - if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { - mPredictionOn = false; - mCompletionOn = isFullscreenMode(); - } - break; - default: - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, - attribute.imeOptions); - } - } - } - - private void updateShowKp2aMode() { - if (!keepass2android.kbbridge.KeyboardData.hasData()) - { - //data no longer available. hide kp2a keyboard: - mShowKp2aKeyboard = false; - mHadKp2aData = false; - } - else - { - - if (!mHadKp2aData) - { - if (keepass2android.kbbridge.KeyboardData.hasData()) - { - //new data available -> show kp2a keyboard: - mShowKp2aKeyboard = true; - } - } - - mHadKp2aData = keepass2android.kbbridge.KeyboardData.hasData(); - } - - Log.d("KP2AK", "show: " + mShowKp2aKeyboard); - } - - private boolean tryKp2aAutoFill(final EditorInfo editorInfo) { - - if (!mKp2aAutoFillOn) - return false; - - //auto fill in? - InputConnection ic = getCurrentInputConnection(); - if (ic == null) return false; - ExtractedTextRequest etr = new ExtractedTextRequest(); - etr.token = 0; // anything is fine here - ExtractedText et = ic.getExtractedText(etr, 0); - - boolean hasTextInField = (et != null) && (!TextUtils.isEmpty(et.text)); - if (!hasTextInField) //only auto-fill if target field is empty - { - //try to look up saved field hint: - if (!TextUtils.isEmpty(editorInfo.hintText)) - { - SharedPreferences prefs = getApplicationContext().getSharedPreferences(KP2A_SAVED_FIELD_HINTS, MODE_PRIVATE); - - String key = editorInfo.packageName+"/"+keepass2android.kbbridge.KeyboardData.entryId+"/"+editorInfo.hintText; - Log.d("KP2AK", "looking up saved field hint for "+key); - - String savedKey = prefs.getString(key, ""); - - if ("".equals(savedKey) == false) - { - Log.d("KP2AK","Found field "+savedKey); - if (commitTextForKey(editorInfo, savedKey)) - return true; - } - } - - //try to look up by hint - if ((editorInfo.hintText != null) && (editorInfo.hintText.length() > 0)) - { - if (commitTextForKey(editorInfo, editorInfo.hintText.toString())) - return true; - } - - } - return false; - } - - private boolean commitTextForKey(final EditorInfo attribute, String key) { - List availableFields = keepass2android.kbbridge.KeyboardData.availableFields; - for (StringForTyping str: availableFields) - { - if (str.key.equals(key)) - { - Log.d("KP2AK", "Typing!"); - commitKp2aString(str.value, attribute); - return true; - } - } - return false; - } - - private void commitKp2aString(String value, EditorInfo editorInfo) { - //getCurrentInputConnection().commitText(value, 0); - onText(value); - - if ((editorInfo.imeOptions&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) == EditorInfo.IME_ACTION_NEXT) - { - Log.d("KP2AK", "action is NEXT"); - getCurrentInputConnection().performEditorAction(editorInfo.actionId); - } - } - - - private void checkReCorrectionOnStart() { - if (mReCorrectionEnabled && isPredictionOn()) { - // First get the cursor position. This is required by setOldSuggestions(), so that - // it can pass the correct range to setComposingRegion(). At this point, we don't - // have valid values for mLastSelectionStart/Stop because onUpdateSelection() has - // not been called yet. - InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - ExtractedTextRequest etr = new ExtractedTextRequest(); - etr.token = 0; // anything is fine here - ExtractedText et = ic.getExtractedText(etr, 0); - if (et == null) return; - - mLastSelectionStart = et.startOffset + et.selectionStart; - mLastSelectionEnd = et.startOffset + et.selectionEnd; - - // Then look for possible corrections in a delayed fashion - if (!TextUtils.isEmpty(et.text) && isCursorTouchingWord()) { - postUpdateOldSuggestions(); - } - } - } - - @Override - public void onFinishInput() { - super.onFinishInput(); - - LatinImeLogger.commit(); - onAutoCompletionStateChanged(false); - - - if (mKeyboardSwitcher.getInputView() != null) { - mKeyboardSwitcher.getInputView().closing(); - } - //if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites(); - //if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites(); - } - - @Override - public void onFinishInputView(boolean finishingInput) { - super.onFinishInputView(finishingInput); - // Remove penging messages related to update suggestions - mHandler.removeMessages(MSG_UPDATE_SUGGESTIONS); - mHandler.removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); - } - - @Override - public void onUpdateSelection(int oldSelStart, int oldSelEnd, - int newSelStart, int newSelEnd, - int candidatesStart, int candidatesEnd) { - super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, - candidatesStart, candidatesEnd); - - if (DEBUG) { - Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart - + ", ose=" + oldSelEnd - + ", nss=" + newSelStart - + ", nse=" + newSelEnd - + ", cs=" + candidatesStart - + ", ce=" + candidatesEnd); - } - - // If the current selection in the text view changes, we should - // clear whatever candidate text we have. - if ((((mComposing.length() > 0 && mPredicting)) - && (newSelStart != candidatesEnd - || newSelEnd != candidatesEnd) - && mLastSelectionStart != newSelStart)) { - mComposing.setLength(0); - mPredicting = false; - postUpdateSuggestions(); - TextEntryState.reset(); - InputConnection ic = getCurrentInputConnection(); - if (ic != null) { - ic.finishComposingText(); - } - } else if (!mPredicting && !mJustAccepted) { - switch (TextEntryState.getState()) { - case ACCEPTED_DEFAULT: - TextEntryState.reset(); - // fall through - case SPACE_AFTER_PICKED: - mJustAddedAutoSpace = false; // The user moved the cursor. - break; - } - } - mJustAccepted = false; - postUpdateShiftKeyState(); - - // Make a note of the cursor position - mLastSelectionStart = newSelStart; - mLastSelectionEnd = newSelEnd; - - if (mReCorrectionEnabled) { - // Don't look for corrections if the keyboard is not visible - if (mKeyboardSwitcher != null && mKeyboardSwitcher.getInputView() != null - && mKeyboardSwitcher.getInputView().isShown()) { - // Check if we should go in or out of correction mode. - if (isPredictionOn() - && mJustRevertedSeparator == null - && (candidatesStart == candidatesEnd || newSelStart != oldSelStart - || TextEntryState.isCorrecting()) - && (newSelStart < newSelEnd - 1 || (!mPredicting)) - ) { - if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) { - postUpdateOldSuggestions(); - } else { - abortCorrection(false); - // Show the punctuation suggestions list if the current one is not - // and if not showing "Touch again to save". - if (mCandidateView != null - && !mSuggestPuncList.equals(mCandidateView.getSuggestions()) - && !mCandidateView.isShowingAddToDictionaryHint()) { - setNextSuggestions(); - } - } - } - } - } - } - - /** - * This is called when the user has clicked on the extracted text view, - * when running in fullscreen mode. The default implementation hides - * the candidates view when this happens, but only if the extracted text - * editor has a vertical scroll bar because its text doesn't fit. - * Here we override the behavior due to the possibility that a re-correction could - * cause the candidate strip to disappear and re-appear. - */ - @Override - public void onExtractedTextClicked() { - if (mReCorrectionEnabled && isPredictionOn()) return; - - super.onExtractedTextClicked(); - } - - /** - * This is called when the user has performed a cursor movement in the - * extracted text view, when it is running in fullscreen mode. The default - * implementation hides the candidates view when a vertical movement - * happens, but only if the extracted text editor has a vertical scroll bar - * because its text doesn't fit. - * Here we override the behavior due to the possibility that a re-correction could - * cause the candidate strip to disappear and re-appear. - */ - @Override - public void onExtractedCursorMovement(int dx, int dy) { - if (mReCorrectionEnabled && isPredictionOn()) return; - - super.onExtractedCursorMovement(dx, dy); - } - - @Override - public void hideWindow() { - LatinImeLogger.commit(); - onAutoCompletionStateChanged(false); - - if (TRACE) Debug.stopMethodTracing(); - if (mOptionsDialog != null && mOptionsDialog.isShowing()) { - mOptionsDialog.dismiss(); - mOptionsDialog = null; - } - mWordToSuggestions.clear(); - mWordHistory.clear(); - super.hideWindow(); - TextEntryState.endSession(); - } - - @Override - public void onDisplayCompletions(CompletionInfo[] completions) { - if (DEBUG) { - Log.i("foo", "Received completions:"); - for (int i=0; i<(completions != null ? completions.length : 0); i++) { - Log.i("foo", " #" + i + ": " + completions[i]); - } - } - if (mCompletionOn) { - mCompletions = completions; - if (completions == null) { - clearSuggestions(); - return; - } - - List stringList = new ArrayList(); - for (int i=0; i<(completions != null ? completions.length : 0); i++) { - CompletionInfo ci = completions[i]; - if (ci != null) stringList.add(ci.getText()); - } - // When in fullscreen mode, show completions generated by the application - setSuggestions(stringList, true, true, true); - mBestWord = null; - setCandidatesViewShown(true); - } - } - - private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) { - // TODO: Remove this if we support candidates with hard keyboard - if (onEvaluateInputViewShown()) { - super.setCandidatesViewShown(shown && mKeyboardSwitcher.getInputView() != null - && (needsInputViewShown ? mKeyboardSwitcher.getInputView().isShown() : true)); - } - } - - @Override - public void setCandidatesViewShown(boolean shown) { - setCandidatesViewShownInternal(shown, true /* needsInputViewShown */ ); - } - - @Override - public void onComputeInsets(InputMethodService.Insets outInsets) { - super.onComputeInsets(outInsets); - if (!isFullscreenMode()) { - outInsets.contentTopInsets = outInsets.visibleTopInsets; - } - } - - @Override - public boolean onEvaluateFullscreenMode() { - - //no full screen mode if only simple Kp2aKeyboard is shown - if (mShowKp2aKeyboard) - return false; - - DisplayMetrics dm = getResources().getDisplayMetrics(); - float displayHeight = dm.heightPixels; - // If the display is more than X inches high, don't go to fullscreen mode - float dimen = getResources().getDimension(R.dimen.max_height_for_fullscreen); - if (displayHeight > dimen) { - return false; - } else { - return super.onEvaluateFullscreenMode(); - } - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_BACK: - if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) { - if (mKeyboardSwitcher.getInputView().handleBack()) { - return true; - } - } - break; - case KeyEvent.KEYCODE_DPAD_DOWN: - case KeyEvent.KEYCODE_DPAD_UP: - case KeyEvent.KEYCODE_DPAD_LEFT: - case KeyEvent.KEYCODE_DPAD_RIGHT: - break; - } - return super.onKeyDown(keyCode, event); - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_DPAD_DOWN: - case KeyEvent.KEYCODE_DPAD_UP: - case KeyEvent.KEYCODE_DPAD_LEFT: - case KeyEvent.KEYCODE_DPAD_RIGHT: - LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); - // Enable shift key and DPAD to do selections - if (inputView != null && inputView.isShown() - && inputView.isShifted()) { - event = new KeyEvent(event.getDownTime(), event.getEventTime(), - event.getAction(), event.getKeyCode(), event.getRepeatCount(), - event.getDeviceId(), event.getScanCode(), - KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON); - InputConnection ic = getCurrentInputConnection(); - if (ic != null) ic.sendKeyEvent(event); - return true; - } - break; - } - return super.onKeyUp(keyCode, event); - } - - - private void reloadKeyboards() { - mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher); - mKeyboardSwitcher.makeKeyboards(true); - } - - private void commitTyped(InputConnection inputConnection) { - if (mPredicting) { - mPredicting = false; - if (mComposing.length() > 0) { - if (inputConnection != null) { - inputConnection.commitText(mComposing, 1); - } - mCommittedLength = mComposing.length(); - TextEntryState.acceptedTyped(mComposing); - addToDictionaries(mComposing, AutoDictionary.FREQUENCY_FOR_TYPED); - } - updateSuggestions(); - } - } - - private void postUpdateShiftKeyState() { - mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE); - // TODO: Should remove this 300ms delay? - mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SHIFT_STATE), 300); - } - - public void updateShiftKeyState(EditorInfo attr) { - InputConnection ic = getCurrentInputConnection(); - if (ic != null && attr != null && mKeyboardSwitcher.isAlphabetMode()) { - mKeyboardSwitcher.setShifted(mShiftKeyState.isMomentary() || mCapsLock - || getCursorCapsMode(ic, attr) != 0); - } - } - - private int getCursorCapsMode(InputConnection ic, EditorInfo attr) { - int caps = 0; - EditorInfo ei = getCurrentInputEditorInfo(); - if (mAutoCap && ei != null && ei.inputType != EditorInfo.TYPE_NULL) { - caps = ic.getCursorCapsMode(attr.inputType); - } - return caps; - } - - private void swapPunctuationAndSpace() { - final InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - CharSequence lastTwo = ic.getTextBeforeCursor(2, 0); - if (lastTwo != null && lastTwo.length() == 2 - && lastTwo.charAt(0) == KEYCODE_SPACE && isSentenceSeparator(lastTwo.charAt(1))) { - ic.beginBatchEdit(); - ic.deleteSurroundingText(2, 0); - ic.commitText(lastTwo.charAt(1) + " ", 1); - ic.endBatchEdit(); - updateShiftKeyState(getCurrentInputEditorInfo()); - mJustAddedAutoSpace = true; - } - } - - private void reswapPeriodAndSpace() { - final InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - CharSequence lastThree = ic.getTextBeforeCursor(3, 0); - if (lastThree != null && lastThree.length() == 3 - && lastThree.charAt(0) == KEYCODE_PERIOD - && lastThree.charAt(1) == KEYCODE_SPACE - && lastThree.charAt(2) == KEYCODE_PERIOD) { - ic.beginBatchEdit(); - ic.deleteSurroundingText(3, 0); - ic.commitText(" ..", 1); - ic.endBatchEdit(); - updateShiftKeyState(getCurrentInputEditorInfo()); - } - } - - private void doubleSpace() { - //if (!mAutoPunctuate) return; - if (mCorrectionMode == Suggest.CORRECTION_NONE) return; - final InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - CharSequence lastThree = ic.getTextBeforeCursor(3, 0); - if (lastThree != null && lastThree.length() == 3 - && Character.isLetterOrDigit(lastThree.charAt(0)) - && lastThree.charAt(1) == KEYCODE_SPACE && lastThree.charAt(2) == KEYCODE_SPACE) { - ic.beginBatchEdit(); - ic.deleteSurroundingText(2, 0); - ic.commitText(". ", 1); - ic.endBatchEdit(); - updateShiftKeyState(getCurrentInputEditorInfo()); - mJustAddedAutoSpace = true; - } - } - - private void maybeRemovePreviousPeriod(CharSequence text) { - final InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - - // When the text's first character is '.', remove the previous period - // if there is one. - CharSequence lastOne = ic.getTextBeforeCursor(1, 0); - if (lastOne != null && lastOne.length() == 1 - && lastOne.charAt(0) == KEYCODE_PERIOD - && text.charAt(0) == KEYCODE_PERIOD) { - ic.deleteSurroundingText(1, 0); - } - } - - private void removeTrailingSpace() { - final InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - - CharSequence lastOne = ic.getTextBeforeCursor(1, 0); - if (lastOne != null && lastOne.length() == 1 - && lastOne.charAt(0) == KEYCODE_SPACE) { - ic.deleteSurroundingText(1, 0); - } - } - - public boolean addWordToDictionary(String word) { - //mUserDictionary.addWord(word, 128); - // Suggestion strip should be updated after the operation of adding word to the - // user dictionary - postUpdateSuggestions(); - return true; - } - - private boolean isAlphabet(int code) { - if (Character.isLetter(code)) { - return true; - } else { - return false; - } - } - - private void showInputMethodPicker() { - ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)) - .showInputMethodPicker(); - } - - private void onOptionKeyPressed() { - if (!isShowingOptionDialog()) { - launchSettings(); - } - } - - private void onOptionKeyLongPressed() { - if (!isShowingOptionDialog()) { - if (LatinIMEUtil.hasMultipleEnabledIMEs(this)) { - showInputMethodPicker(); - } else { - launchSettings(); - } - } - } - - private boolean isShowingOptionDialog() { - return mOptionsDialog != null && mOptionsDialog.isShowing(); - } - - // Implementation of KeyboardViewListener - - public void onKey(int primaryCode, int[] keyCodes, int x, int y) { - long when = SystemClock.uptimeMillis(); - if (primaryCode != Keyboard.KEYCODE_DELETE || - when > mLastKeyTime + QUICK_PRESS) { - mDeleteCount = 0; - } - mLastKeyTime = when; - final boolean distinctMultiTouch = mKeyboardSwitcher.hasDistinctMultitouch(); - switch (primaryCode) { - case Keyboard.KEYCODE_DELETE: - handleBackspace(); - mDeleteCount++; - LatinImeLogger.logOnDelete(); - break; - case Keyboard.KEYCODE_SHIFT: - // Shift key is handled in onPress() when device has distinct multi-touch panel. - if (!distinctMultiTouch) - handleShift(); - break; - case Keyboard.KEYCODE_MODE_CHANGE: - // Symbol key is handled in onPress() when device has distinct multi-touch panel. - if (!distinctMultiTouch) - changeKeyboardMode(); - break; - case Keyboard.KEYCODE_CANCEL: - if (!isShowingOptionDialog()) { - handleClose(); - } - break; - case LatinKeyboardView.KEYCODE_OPTIONS: - onOptionKeyPressed(); - break; - case LatinKeyboardView.KEYCODE_KP2A: - onKp2aKeyPressed(); - break; - case LatinKeyboardView.KEYCODE_KP2A_USER: - onKp2aUserKeyPressed(); - break; - case LatinKeyboardView.KEYCODE_KP2A_PASSWORD: - onKp2aPasswordKeyPressed(); - break; - case LatinKeyboardView.KEYCODE_KP2A_ALPHA: - onKp2aAlphaKeyPressed(); - break; - case LatinKeyboardView.KEYCODE_KP2A_SWITCH: - onKp2aSwitchKeyboardPressed(); - break; - case LatinKeyboardView.KEYCODE_KP2A_LOCK: - onKp2aLockKeyPressed(); - break; - case LatinKeyboardView.KEYCODE_OPTIONS_LONGPRESS: - onOptionKeyLongPressed(); - break; - case LatinKeyboardView.KEYCODE_NEXT_LANGUAGE: - toggleLanguage(false, true); - break; - case LatinKeyboardView.KEYCODE_PREV_LANGUAGE: - toggleLanguage(false, false); - break; - case 9 /*Tab*/: - sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB); - break; - case KEYCODE_ENTER: - onEnterKey(); - //fall through - default: - if (primaryCode != KEYCODE_ENTER) { - mJustAddedAutoSpace = false; - } - RingCharBuffer.getInstance().push((char)primaryCode, x, y); - LatinImeLogger.logOnInputChar(); - if (isWordSeparator(primaryCode)) { - handleSeparator(primaryCode); - } else { - handleCharacter(primaryCode, keyCodes); - } - // Cancel the just reverted state - mJustRevertedSeparator = null; - } - mKeyboardSwitcher.onKey(primaryCode); - // Reset after any single keystroke - mEnteredText = null; - } - - private void onEnterKey() { - if ((mIsSendGoDone) && (mKeyboardSwitcher.getKeyboardMode() == KeyboardSwitcher.MODE_KP2A)) - { - if (mKp2aSwitchKeyboardOnSendGoDone) - { - keepass2android.kbbridge.ImeSwitcher.switchToPreviousKeyboard(this, false); - } - if (mKp2aLockOnSendGoDone) - { - onKp2aLockKeyPressed(); - } - } - - } - - private void onKp2aLockKeyPressed() { - - String action = getPackageName()+".lock_database"; - android.util.Log.i("KP2A", "sending broadcast with action "+action); - sendBroadcast(new Intent(action)); - - } - - private void onKp2aSwitchKeyboardPressed() { - showInputMethodPicker(); - - } - - private void onKp2aAlphaKeyPressed() { - mShowKp2aKeyboard = false; - updateKeyboardMode(getCurrentInputEditorInfo()); - } - - private void onKp2aPasswordKeyPressed() { - commitStringForTyping(findStringForTyping("Password")); - } - - private StringForTyping findStringForTyping(String key) { - - for (StringForTyping s: keepass2android.kbbridge.KeyboardData.availableFields) - { - if (key.equals(s.key)) - { - return s; - } - } - //found nothing: return empty struct: - return new StringForTyping(); - } - - private void onKp2aUserKeyPressed() { - commitStringForTyping(findStringForTyping("UserName")); - - } - - private void onKp2aKeyPressed() { - if ((mKeyboardSwitcher.getKeyboardMode() == KeyboardSwitcher.MODE_KP2A) - || (!mKp2aEnableSimpleKeyboard) - || (!keepass2android.kbbridge.KeyboardData.hasData())) - { - showKp2aDialog(); - return; - } - mShowKp2aKeyboard = true; - updateKeyboardMode(getCurrentInputEditorInfo()); - setCandidatesViewShown(false); - } - - private void showKp2aDialog() { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - String title = "Keepass2Android"; - List availableFields = keepass2android.kbbridge.KeyboardData.availableFields; - - final EditorInfo attribute = getCurrentInputEditorInfo(); - Log.d("KP2AK", "hint: "+attribute.hintText); - Log.d("KP2AK", "field name: "+attribute.fieldName); - Log.d("KP2AK", "label: "+attribute.label); - attribute.dump(new Printer() { - - @Override - public void println(String x) { - Log.d("KP2AK", x); - - } - },""); - final ArrayList items = new ArrayList(); - for (StringForTyping entry : availableFields) - { - Log.d("KP2AK", entry.displayName); - items.add(entry.clone()); - } - - - - StringForTyping openOrChangeEntry = new StringForTyping(); - if (keepass2android.kbbridge.KeyboardData.entryName == null) - { - openOrChangeEntry.displayName = openOrChangeEntry.key = getString(R.string.open_entry); - } - else - { - openOrChangeEntry.displayName = openOrChangeEntry.key = getString(R.string.change_entry); - } - openOrChangeEntry.value = "KP2ASPECIAL_SelectEntryTask"; - items.add(openOrChangeEntry); - - - final String clientPackageName = attribute.packageName; - - if ((clientPackageName != null) && (clientPackageName != "")) - { - StringForTyping searchEntry = new StringForTyping(); - try - { - searchEntry.key = searchEntry.displayName - = getString(R.string.open_entry_for_app, clientPackageName); - } - catch (java.util.FormatFlagsConversionMismatchException e) //buggy crowdin support for Arabic? - { - android.util.Log.e("KP2A", "Please report this error to crocoapps@gmail.com"); - android.util.Log.e("KP2A", e.toString()); - - searchEntry.key = searchEntry.displayName - = "Search entry for app"; - } - - searchEntry.value = "KP2ASPECIAL_SearchUrlTask"; - items.add(searchEntry); - } - - - builder.setTitle(title); - - CharSequence[] itemNames = new CharSequence[items.size()]; - int i=0; - for (StringForTyping sft: items) - itemNames[i++] = sft.displayName; - - builder.setItems(itemNames, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int item) { - - Log.d("KP2AK", "clicked item: " + items.get(item).key); - - if (items.get(item).value.startsWith("KP2ASPECIAL")) { - //change entry - Log.d("KP2AK", "clicked item: " + items.get(item).value); - - String packageName = getApplicationContext().getPackageName(); - Intent startKp2aIntent = getPackageManager().getLaunchIntentForPackage(packageName); - if (startKp2aIntent != null) - { - startKp2aIntent.addCategory(Intent.CATEGORY_LAUNCHER); - startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - String value = items.get(item).value; - String taskName = value.substring("KP2ASPECIAL_".length()); - startKp2aIntent.putExtra("KP2A_APPTASK", taskName); - if (taskName.equals("SearchUrlTask")) - { - startKp2aIntent.putExtra("UrlToSearch", "androidapp://"+clientPackageName); - } - startActivity(startKp2aIntent); - } else Log.w("KP2AK", "didn't find intent for "+packageName); - } else { - - StringForTyping theItem = items.get(item); - - commitStringForTyping(theItem); - - } - } - - }); - - builder.setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // User cancelled the dialog - } - }); - - // Create the AlertDialog - AlertDialog dialog = builder.create(); - Window window = dialog.getWindow(); - WindowManager.LayoutParams lp = window.getAttributes(); - LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); - lp.token = inputView.getWindowToken(); - lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; - window.setAttributes(lp); - window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - - dialog.show(); - } - private void commitStringForTyping(StringForTyping theItem) { - - if ((mKp2aRememberAutoFill) && (!TextUtils.isEmpty(getCurrentInputEditorInfo().hintText))) - { - EditorInfo editorInfo = getCurrentInputEditorInfo(); - String key = editorInfo.packageName+"/"+keepass2android.kbbridge.KeyboardData.entryId+"/"+editorInfo.hintText; - SharedPreferences prefs = getApplicationContext().getSharedPreferences(KP2A_SAVED_FIELD_HINTS, MODE_PRIVATE); - - Editor edit = prefs.edit(); - - edit.putString(key, theItem.key); - edit.commit(); - } - - - - Log.d("KP2AK", "committing text for " + theItem.key); - commitKp2aString(theItem.value, getCurrentInputEditorInfo()); - } - - - public void onText(CharSequence text) { - InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - if (text == null) - { - Log.e("KP2AK", "text = null!"); - return; - } - abortCorrection(false); - ic.beginBatchEdit(); - if (mPredicting) { - commitTyped(ic); - } - maybeRemovePreviousPeriod(text); - ic.commitText(text, 1); - ic.endBatchEdit(); - updateShiftKeyState(getCurrentInputEditorInfo()); - mKeyboardSwitcher.onKey(0); // dummy key code. - mJustRevertedSeparator = null; - mJustAddedAutoSpace = false; - mEnteredText = text; - } - - public void onCancel() { - // User released a finger outside any key - mKeyboardSwitcher.onCancelInput(); - } - - private void handleBackspace() { - boolean deleteChar = false; - InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - - ic.beginBatchEdit(); - - if (mPredicting) { - final int length = mComposing.length(); - if (length > 0) { - mComposing.delete(length - 1, length); - mWord.deleteLast(); - ic.setComposingText(mComposing, 1); - if (mComposing.length() == 0) { - mPredicting = false; - } - postUpdateSuggestions(); - } else { - ic.deleteSurroundingText(1, 0); - } - } else { - deleteChar = true; - } - postUpdateShiftKeyState(); - TextEntryState.backspace(); - if (TextEntryState.getState() == TextEntryState.State.UNDO_COMMIT) { - revertLastWord(deleteChar); - ic.endBatchEdit(); - return; - } else if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) { - ic.deleteSurroundingText(mEnteredText.length(), 0); - } else if (deleteChar) { - if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { - // Go back to the suggestion mode if the user canceled the - // "Touch again to save". - // NOTE: In gerenal, we don't revert the word when backspacing - // from a manual suggestion pick. We deliberately chose a - // different behavior only in the case of picking the first - // suggestion (typed word). It's intentional to have made this - // inconsistent with backspacing after selecting other suggestions. - revertLastWord(deleteChar); - } else { - sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); - if (mDeleteCount > DELETE_ACCELERATE_AT) { - sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); - } - } - } - mJustRevertedSeparator = null; - ic.endBatchEdit(); - } - - private void resetShift() { - handleShiftInternal(true); - } - - private void handleShift() { - handleShiftInternal(false); - } - - private void handleShiftInternal(boolean forceNormal) { - mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE); - KeyboardSwitcher switcher = mKeyboardSwitcher; - LatinKeyboardView inputView = switcher.getInputView(); - if (switcher.isAlphabetMode()) { - if (mCapsLock || forceNormal) { - mCapsLock = false; - switcher.setShifted(false); - } else if (inputView != null) { - if (inputView.isShifted()) { - mCapsLock = true; - switcher.setShiftLocked(true); - } else { - switcher.setShifted(true); - } - } - } else { - switcher.toggleShift(); - } - } - - private void abortCorrection(boolean force) { - if (force || TextEntryState.isCorrecting()) { - getCurrentInputConnection().finishComposingText(); - clearSuggestions(); - } - } - - private void handleCharacter(int primaryCode, int[] keyCodes) { - - if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isCorrecting()) { - abortCorrection(false); - } - - if (isAlphabet(primaryCode) && isPredictionOn() && !isCursorTouchingWord()) { - if (!mPredicting) { - mPredicting = true; - mComposing.setLength(0); - saveWordInHistory(mBestWord); - mWord.reset(); - } - } - if (mKeyboardSwitcher.getInputView().isShifted()) { - if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT - || keyCodes[0] > Character.MAX_CODE_POINT) { - return; - } - primaryCode = keyCodes[0]; - if (mKeyboardSwitcher.isAlphabetMode() && Character.isLowerCase(primaryCode)) { - // In some locales, such as Turkish, Character.toUpperCase() may return a wrong - // character because it doesn't take care of locale. - final String upperCaseString = new String(new int[] {primaryCode}, 0, 1) - .toUpperCase(mLanguageSwitcher.getInputLocale()); - if (upperCaseString.codePointCount(0, upperCaseString.length()) == 1) { - primaryCode = upperCaseString.codePointAt(0); - } else { - // Some keys, such as [eszett], have upper case as multi-characters. - onText(upperCaseString); - return; - } - } - } - if (mPredicting) { - if (mKeyboardSwitcher.getInputView().isShifted() - && mKeyboardSwitcher.isAlphabetMode() - && mComposing.length() == 0) { - mWord.setFirstCharCapitalized(true); - } - mComposing.append((char) primaryCode); - mWord.add(primaryCode, keyCodes); - InputConnection ic = getCurrentInputConnection(); - if (ic != null) { - // If it's the first letter, make note of auto-caps state - if (mWord.size() == 1) { - mWord.setAutoCapitalized( - getCursorCapsMode(ic, getCurrentInputEditorInfo()) != 0); - } - ic.setComposingText(mComposing, 1); - } - postUpdateSuggestions(); - } else { - sendKeyChar((char)primaryCode); - } - updateShiftKeyState(getCurrentInputEditorInfo()); - if (KP2AKeyboard.PERF_DEBUG) measureCps(); - TextEntryState.typedCharacter((char) primaryCode, isWordSeparator(primaryCode)); - } - - private void handleSeparator(int primaryCode) { - // Should dismiss the "Touch again to save" message when handling separator - if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { - postUpdateSuggestions(); - } - - boolean pickedDefault = false; - // Handle separator - InputConnection ic = getCurrentInputConnection(); - if (ic != null) { - ic.beginBatchEdit(); - abortCorrection(false); - } - if (mPredicting) { - // In certain languages where single quote is a separator, it's better - // not to auto correct, but accept the typed word. For instance, - // in Italian dov' should not be expanded to dove' because the elision - // requires the last vowel to be removed. - if (mAutoCorrectOn && primaryCode != '\'' && - (mJustRevertedSeparator == null - || mJustRevertedSeparator.length() == 0 - || mJustRevertedSeparator.charAt(0) != primaryCode)) { - pickedDefault = pickDefaultSuggestion(); - // Picked the suggestion by the space key. We consider this - // as "added an auto space". - if (primaryCode == KEYCODE_SPACE) { - mJustAddedAutoSpace = true; - } - } else { - commitTyped(ic); - } - } - if (mJustAddedAutoSpace && primaryCode == KEYCODE_ENTER) { - removeTrailingSpace(); - mJustAddedAutoSpace = false; - } - sendKeyChar((char)primaryCode); - - // Handle the case of ". ." -> " .." with auto-space if necessary - // before changing the TextEntryState. - if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED - && primaryCode == KEYCODE_PERIOD) { - reswapPeriodAndSpace(); - } - - TextEntryState.typedCharacter((char) primaryCode, true); - if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED - && primaryCode != KEYCODE_ENTER) { - swapPunctuationAndSpace(); - } else if (isPredictionOn() && primaryCode == KEYCODE_SPACE) { - doubleSpace(); - } - if (pickedDefault) { - TextEntryState.backToAcceptedDefault(mWord.getTypedWord()); - } - updateShiftKeyState(getCurrentInputEditorInfo()); - if (ic != null) { - ic.endBatchEdit(); - } - } - - private void handleClose() { - commitTyped(getCurrentInputConnection()); - requestHideSelf(0); - if (mKeyboardSwitcher != null) { - LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); - if (inputView != null) { - inputView.closing(); - } - } - TextEntryState.endSession(); - } - - private void saveWordInHistory(CharSequence result) { - if (mWord.size() <= 1) { - mWord.reset(); - return; - } - // Skip if result is null. It happens in some edge case. - if (TextUtils.isEmpty(result)) { - return; - } - - // Make a copy of the CharSequence, since it is/could be a mutable CharSequence - final String resultCopy = result.toString(); - TypedWordAlternatives entry = new TypedWordAlternatives(resultCopy, - new WordComposer(mWord)); - mWordHistory.add(entry); - } - - private void postUpdateSuggestions() { - mHandler.removeMessages(MSG_UPDATE_SUGGESTIONS); - mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SUGGESTIONS), 100); - } - - private void postUpdateOldSuggestions() { - mHandler.removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); - mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_OLD_SUGGESTIONS), 300); - } - - private boolean isPredictionOn() { - return mPredictionOn; - } - - private boolean isCandidateStripVisible() { - return isPredictionOn() && mShowSuggestions; - } - - public void onCancelVoice() { - if (mRecognizing) { - switchToKeyboardView(); - } - } - - private void switchToKeyboardView() { - mHandler.post(new Runnable() { - public void run() { - mRecognizing = false; - if (mKeyboardSwitcher.getInputView() != null) { - setInputView(mKeyboardSwitcher.getInputView()); - } - setCandidatesViewShown(true); - updateInputViewShown(); - postUpdateSuggestions(); - }}); - } - - private void clearSuggestions() { - setSuggestions(null, false, false, false); - } - - private void setSuggestions( - List suggestions, - boolean completions, - boolean typedWordValid, - boolean haveMinimalSuggestion) { - - if (mIsShowingHint) { - setCandidatesView(mCandidateViewContainer); - mIsShowingHint = false; - } - - if (mCandidateView != null) { - mCandidateView.setSuggestions( - suggestions, completions, typedWordValid, haveMinimalSuggestion); - } - } - - private void updateSuggestions() { - LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); - ((LatinKeyboard) inputView.getKeyboard()).setPreferredLetters(null); - - // Check if we have a suggestion engine attached. - if ((mSuggest == null || !isPredictionOn())) { - return; - } - - if (!mPredicting) { - setNextSuggestions(); - return; - } - showSuggestions(mWord); - } - - private List getTypedSuggestions(WordComposer word) { - List stringList = mSuggest.getSuggestions( - mKeyboardSwitcher.getInputView(), word, false, null); - return stringList; - } - - private void showCorrections(WordAlternatives alternatives) { - List stringList = alternatives.getAlternatives(); - ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).setPreferredLetters(null); - showSuggestions(stringList, alternatives.getOriginalWord(), false, false); - } - - private void showSuggestions(WordComposer word) { - // long startTime = System.currentTimeMillis(); // TIME MEASUREMENT! - // TODO Maybe need better way of retrieving previous word - CharSequence prevWord = EditingUtil.getPreviousWord(getCurrentInputConnection(), - mWordSeparators); - List stringList = mSuggest.getSuggestions( - mKeyboardSwitcher.getInputView(), word, false, prevWord); - // long stopTime = System.currentTimeMillis(); // TIME MEASUREMENT! - // Log.d("LatinIME","Suggest Total Time - " + (stopTime - startTime)); - - int[] nextLettersFrequencies = mSuggest.getNextLettersFrequencies(); - - ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).setPreferredLetters( - nextLettersFrequencies); - - boolean correctionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasMinimalCorrection(); - //|| mCorrectionMode == mSuggest.CORRECTION_FULL; - CharSequence typedWord = word.getTypedWord(); - // If we're in basic correct - boolean typedWordValid = mSuggest.isValidWord(typedWord) || - (preferCapitalization() - && mSuggest.isValidWord(typedWord.toString().toLowerCase())); - if (mCorrectionMode == Suggest.CORRECTION_FULL - || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) { - correctionAvailable |= typedWordValid; - } - // Don't auto-correct words with multiple capital letter - correctionAvailable &= !word.isMostlyCaps(); - correctionAvailable &= !TextEntryState.isCorrecting(); - - showSuggestions(stringList, typedWord, typedWordValid, correctionAvailable); - } - - private void showSuggestions(List stringList, CharSequence typedWord, - boolean typedWordValid, boolean correctionAvailable) { - setSuggestions(stringList, false, typedWordValid, correctionAvailable); - if (stringList.size() > 0) { - if (correctionAvailable && !typedWordValid && stringList.size() > 1) { - mBestWord = stringList.get(1); - } else { - mBestWord = typedWord; - } - } else { - mBestWord = null; - } - setCandidatesViewShown(isCandidateStripVisible() || mCompletionOn); - } - - private boolean pickDefaultSuggestion() { - // Complete any pending candidate query first - if (mHandler.hasMessages(MSG_UPDATE_SUGGESTIONS)) { - mHandler.removeMessages(MSG_UPDATE_SUGGESTIONS); - updateSuggestions(); - } - if (mBestWord != null && mBestWord.length() > 0) { - TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord); - mJustAccepted = true; - pickSuggestion(mBestWord, false); - // Add the word to the auto dictionary if it's not a known word - addToDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED); - return true; - - } - return false; - } - - public void pickSuggestionManually(int index, CharSequence suggestion) { - List suggestions = mCandidateView.getSuggestions(); - - - - final boolean correcting = TextEntryState.isCorrecting(); - InputConnection ic = getCurrentInputConnection(); - if (ic != null) { - ic.beginBatchEdit(); - } - if (mCompletionOn && mCompletions != null && index >= 0 - && index < mCompletions.length) { - CompletionInfo ci = mCompletions[index]; - if (ic != null) { - ic.commitCompletion(ci); - } - mCommittedLength = suggestion.length(); - if (mCandidateView != null) { - mCandidateView.clear(); - } - updateShiftKeyState(getCurrentInputEditorInfo()); - if (ic != null) { - ic.endBatchEdit(); - } - return; - } - - // If this is a punctuation, apply it through the normal key press - if (suggestion.length() == 1 && (isWordSeparator(suggestion.charAt(0)) - || isSuggestedPunctuation(suggestion.charAt(0)))) { - // Word separators are suggested before the user inputs something. - // So, LatinImeLogger logs "" as a user's input. - LatinImeLogger.logOnManualSuggestion( - "", suggestion.toString(), index, suggestions); - final char primaryCode = suggestion.charAt(0); - onKey(primaryCode, new int[]{primaryCode}, LatinKeyboardBaseView.NOT_A_TOUCH_COORDINATE, - LatinKeyboardBaseView.NOT_A_TOUCH_COORDINATE); - if (ic != null) { - ic.endBatchEdit(); - } - return; - } - mJustAccepted = true; - pickSuggestion(suggestion, correcting); - // Add the word to the auto dictionary if it's not a known word - if (index == 0) { - addToDictionaries(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED); - } else { - addToBigramDictionary(suggestion, 1); - } - LatinImeLogger.logOnManualSuggestion(mComposing.toString(), suggestion.toString(), - index, suggestions); - TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion); - // Follow it with a space - if (mAutoSpace && !correcting) { - sendSpace(); - mJustAddedAutoSpace = true; - } - - final boolean showingAddToDictionaryHint = index == 0 && mCorrectionMode > 0 - && !mSuggest.isValidWord(suggestion) - && !mSuggest.isValidWord(suggestion.toString().toLowerCase()); - - if (!correcting) { - // Fool the state watcher so that a subsequent backspace will not do a revert, unless - // we just did a correction, in which case we need to stay in - // TextEntryState.State.PICKED_SUGGESTION state. - TextEntryState.typedCharacter((char) KEYCODE_SPACE, true); - setNextSuggestions(); - } else if (!showingAddToDictionaryHint) { - // If we're not showing the "Touch again to save", then show corrections again. - // In case the cursor position doesn't change, make sure we show the suggestions again. - clearSuggestions(); - postUpdateOldSuggestions(); - } - if (showingAddToDictionaryHint) { - mCandidateView.showAddToDictionaryHint(suggestion); - } - if (ic != null) { - ic.endBatchEdit(); - } - } - - private void rememberReplacedWord(CharSequence suggestion) { - - } - - /** - * Commits the chosen word to the text field and saves it for later - * retrieval. - * @param suggestion the suggestion picked by the user to be committed to - * the text field - * @param correcting whether this is due to a correction of an existing - * word. - */ - private void pickSuggestion(CharSequence suggestion, boolean correcting) { - final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); - final Locale inputLocale = mLanguageSwitcher.getInputLocale(); - if (mCapsLock) { - suggestion = suggestion.toString().toUpperCase(inputLocale); - } else if (preferCapitalization() - || (mKeyboardSwitcher.isAlphabetMode() - && inputView.isShifted())) { - suggestion = suggestion.toString().toUpperCase(inputLocale).charAt(0) - + suggestion.subSequence(1, suggestion.length()).toString(); - } - InputConnection ic = getCurrentInputConnection(); - if (ic != null) { - rememberReplacedWord(suggestion); - ic.commitText(suggestion, 1); - } - saveWordInHistory(suggestion); - mPredicting = false; - mCommittedLength = suggestion.length(); - ((LatinKeyboard) inputView.getKeyboard()).setPreferredLetters(null); - // If we just corrected a word, then don't show punctuations - if (!correcting) { - setNextSuggestions(); - } - updateShiftKeyState(getCurrentInputEditorInfo()); - } - - /** - * Tries to apply any typed alternatives for the word if we have any cached alternatives, - * otherwise tries to find new corrections and completions for the word. - * @param touching The word that the cursor is touching, with position information - * @return true if an alternative was found, false otherwise. - */ - private boolean applyTypedAlternatives(EditingUtil.SelectedWord touching) { - // If we didn't find a match, search for result in typed word history - WordComposer foundWord = null; - WordAlternatives alternatives = null; - for (WordAlternatives entry : mWordHistory) { - if (TextUtils.equals(entry.getChosenWord(), touching.word)) { - if (entry instanceof TypedWordAlternatives) { - foundWord = ((TypedWordAlternatives) entry).word; - } - alternatives = entry; - break; - } - } - // If we didn't find a match, at least suggest completions - if (foundWord == null - && (mSuggest.isValidWord(touching.word) - || mSuggest.isValidWord(touching.word.toString().toLowerCase()))) { - foundWord = new WordComposer(); - for (int i = 0; i < touching.word.length(); i++) { - foundWord.add(touching.word.charAt(i), new int[] { - touching.word.charAt(i) - }); - } - foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.word.charAt(0))); - } - // Found a match, show suggestions - if (foundWord != null || alternatives != null) { - if (alternatives == null) { - alternatives = new TypedWordAlternatives(touching.word, foundWord); - } - showCorrections(alternatives); - if (foundWord != null) { - mWord = new WordComposer(foundWord); - } else { - mWord.reset(); - } - return true; - } - return false; - } - - private void setOldSuggestions() { - - if (mCandidateView != null && mCandidateView.isShowingAddToDictionaryHint()) { - return; - } - InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - if (!mPredicting) { - // Extract the selected or touching text - EditingUtil.SelectedWord touching = EditingUtil.getWordAtCursorOrSelection(ic, - mLastSelectionStart, mLastSelectionEnd, mWordSeparators); - - if (touching != null && touching.word.length() > 1) { - ic.beginBatchEdit(); - - if (!applyTypedAlternatives(touching)) { - abortCorrection(true); - } else { - TextEntryState.selectedForCorrection(); - EditingUtil.underlineWord(ic, touching); - } - - ic.endBatchEdit(); - } else { - abortCorrection(true); - setNextSuggestions(); // Show the punctuation suggestions list - } - } else { - abortCorrection(true); - } - } - - private void setNextSuggestions() { - setSuggestions(mSuggestPuncList, false, false, false); - } - - private void addToDictionaries(CharSequence suggestion, int frequencyDelta) { - checkAddToDictionary(suggestion, frequencyDelta, false); - } - - private void addToBigramDictionary(CharSequence suggestion, int frequencyDelta) { - checkAddToDictionary(suggestion, frequencyDelta, true); - } - - /** - * Adds to the UserBigramDictionary and/or AutoDictionary - * @param addToBigramDictionary true if it should be added to bigram dictionary if possible - */ - private void checkAddToDictionary(CharSequence suggestion, int frequencyDelta, - boolean addToBigramDictionary) { - if (suggestion == null || suggestion.length() < 1) return; - // Only auto-add to dictionary if auto-correct is ON. Otherwise we'll be - // adding words in situations where the user or application really didn't - // want corrections enabled or learned. - if (!(mCorrectionMode == Suggest.CORRECTION_FULL - || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM)) { - return; - } - if (suggestion != null) { - /*if (!addToBigramDictionary && mAutoDictionary.isValidWord(suggestion) - || (!mSuggest.isValidWord(suggestion.toString()) - && !mSuggest.isValidWord(suggestion.toString().toLowerCase()))) { - mAutoDictionary.addWord(suggestion.toString(), frequencyDelta); - } - - if (mUserBigramDictionary != null) { - CharSequence prevWord = EditingUtil.getPreviousWord(getCurrentInputConnection(), - mSentenceSeparators); - if (!TextUtils.isEmpty(prevWord)) { - mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString()); - } - }*/ - } - } - - private boolean isCursorTouchingWord() { - InputConnection ic = getCurrentInputConnection(); - if (ic == null) return false; - CharSequence toLeft = ic.getTextBeforeCursor(1, 0); - CharSequence toRight = ic.getTextAfterCursor(1, 0); - if (!TextUtils.isEmpty(toLeft) - && !isWordSeparator(toLeft.charAt(0)) - && !isSuggestedPunctuation(toLeft.charAt(0))) { - return true; - } - if (!TextUtils.isEmpty(toRight) - && !isWordSeparator(toRight.charAt(0)) - && !isSuggestedPunctuation(toRight.charAt(0))) { - return true; - } - return false; - } - - private boolean sameAsTextBeforeCursor(InputConnection ic, CharSequence text) { - CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0); - return TextUtils.equals(text, beforeText); - } - - public void revertLastWord(boolean deleteChar) { - final int length = mComposing.length(); - if (!mPredicting && length > 0) { - final InputConnection ic = getCurrentInputConnection(); - mPredicting = true; - mJustRevertedSeparator = ic.getTextBeforeCursor(1, 0); - if (deleteChar) ic.deleteSurroundingText(1, 0); - int toDelete = mCommittedLength; - CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0); - if (toTheLeft != null && toTheLeft.length() > 0 - && isWordSeparator(toTheLeft.charAt(0))) { - toDelete--; - } - ic.deleteSurroundingText(toDelete, 0); - ic.setComposingText(mComposing, 1); - TextEntryState.backspace(); - postUpdateSuggestions(); - } else { - sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); - mJustRevertedSeparator = null; - } - } - - protected String getWordSeparators() { - return mWordSeparators; - } - - public boolean isWordSeparator(int code) { - String separators = getWordSeparators(); - return separators.contains(String.valueOf((char)code)); - } - - private boolean isSentenceSeparator(int code) { - return mSentenceSeparators.contains(String.valueOf((char)code)); - } - - private void sendSpace() { - sendKeyChar((char)KEYCODE_SPACE); - updateShiftKeyState(getCurrentInputEditorInfo()); - //onKey(KEY_SPACE[0], KEY_SPACE); - } - - public boolean preferCapitalization() { - return mWord.isFirstCharCapitalized(); - } - - void toggleLanguage(boolean reset, boolean next) { - if (reset) { - mLanguageSwitcher.reset(); - } else { - if (next) { - mLanguageSwitcher.next(); - } else { - mLanguageSwitcher.prev(); - } - } - int currentKeyboardMode = mKeyboardSwitcher.getKeyboardMode(); - reloadKeyboards(); - mKeyboardSwitcher.makeKeyboards(true); - Log.d("KP2AK", "toggleLanguage -> setKM"); - mKeyboardSwitcher.setKeyboardMode(currentKeyboardMode, 0); - initSuggest(mLanguageSwitcher.getInputLanguage()); - mLanguageSwitcher.persist(); - updateShiftKeyState(getCurrentInputEditorInfo()); - } - - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, - String key) { - if (PREF_SELECTED_LANGUAGES.equals(key)) { - mLanguageSwitcher.loadLocales(sharedPreferences); - mRefreshKeyboardRequired = true; - } else if (PREF_RECORRECTION_ENABLED.equals(key)) { - mReCorrectionEnabled = sharedPreferences.getBoolean(PREF_RECORRECTION_ENABLED, - getResources().getBoolean(R.bool.default_recorrection_enabled)); - } - if (PREF_KP2A_REMEMBER_AUTO_FILL.equals(key)) - { - if (sharedPreferences.getBoolean(key, true) == false) - { - Log.d("KP2AK", "clearing saved field hints"); - SharedPreferences savedHints = getApplicationContext().getSharedPreferences(KP2A_SAVED_FIELD_HINTS, MODE_PRIVATE); - Editor edit = savedHints.edit(); - edit.clear(); - edit.commit(); - - } - } - } - - public void swipeRight() { - if (LatinKeyboardView.DEBUG_AUTO_PLAY) { - ClipboardManager cm = ((ClipboardManager)getSystemService(CLIPBOARD_SERVICE)); - CharSequence text = cm.getText(); - if (!TextUtils.isEmpty(text)) { - mKeyboardSwitcher.getInputView().startPlaying(text.toString()); - } - } - } - - public void swipeLeft() { - } - - public void swipeDown() { - handleClose(); - } - - public void swipeUp() { - //launchSettings(); - } - - public void onPress(int primaryCode) { - if (mKeyboardSwitcher.isVibrateAndSoundFeedbackRequired()) { - vibrate(); - playKeyClick(primaryCode); - } - final boolean distinctMultiTouch = mKeyboardSwitcher.hasDistinctMultitouch(); - if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) { - mShiftKeyState.onPress(); - handleShift(); - } else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) { - changeKeyboardMode(); - mSymbolKeyState.onPress(); - mKeyboardSwitcher.setAutoModeSwitchStateMomentary(); - } else { - mShiftKeyState.onOtherKeyPressed(); - mSymbolKeyState.onOtherKeyPressed(); - } - } - - public void onRelease(int primaryCode) { - // Reset any drag flags in the keyboard - ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).keyReleased(); - //vibrate(); - final boolean distinctMultiTouch = mKeyboardSwitcher.hasDistinctMultitouch(); - if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) { - if (mShiftKeyState.isMomentary()) - resetShift(); - mShiftKeyState.onRelease(); - } else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) { - // Snap back to the previous keyboard mode if the user chords the mode change key and - // other key, then released the mode change key. - if (mKeyboardSwitcher.isInChordingAutoModeSwitchState()) - changeKeyboardMode(); - mSymbolKeyState.onRelease(); - } - } - - - - // receive ringer mode changes to detect silent mode - private BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - updateRingerMode(); - } - }; - - // update flags for silent mode - private void updateRingerMode() { - if (mAudioManager == null) { - mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); - } - if (mAudioManager != null) { - mSilentMode = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL); - } - } - - private void playKeyClick(int primaryCode) { - // if mAudioManager is null, we don't have the ringer state yet - // mAudioManager will be set by updateRingerMode - if (mAudioManager == null) { - if (mKeyboardSwitcher.getInputView() != null) { - updateRingerMode(); - } - } - if (mSoundOn && !mSilentMode) { - // FIXME: Volume and enable should come from UI settings - // FIXME: These should be triggered after auto-repeat logic - int sound = AudioManager.FX_KEYPRESS_STANDARD; - switch (primaryCode) { - case Keyboard.KEYCODE_DELETE: - sound = AudioManager.FX_KEYPRESS_DELETE; - break; - case KEYCODE_ENTER: - sound = AudioManager.FX_KEYPRESS_RETURN; - break; - case KEYCODE_SPACE: - sound = AudioManager.FX_KEYPRESS_SPACEBAR; - break; - } - mAudioManager.playSoundEffect(sound, FX_VOLUME); - } - } - - private void vibrate() { - if (!mVibrateOn) { - return; - } - if (mKeyboardSwitcher.getInputView() != null) { - mKeyboardSwitcher.getInputView().performHapticFeedback( - HapticFeedbackConstants.KEYBOARD_TAP, - HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); - } - } - - /* package */ void promoteToUserDictionary(String word, int frequency) { - //if (mUserDictionary.isValidWord(word)) return; - //mUserDictionary.addWord(word, frequency); - } - - /* package */ WordComposer getCurrentWord() { - return mWord; - } - - /* package */ boolean getPopupOn() { - return mPopupOn; - } - - private void updateCorrectionMode() { - mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false; - mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes) - && !mInputTypeNoAutoCorrect && mHasDictionary; - mCorrectionMode = (mAutoCorrectOn && mAutoCorrectEnabled) - ? Suggest.CORRECTION_FULL - : (mAutoCorrectOn ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE); - mCorrectionMode = (mBigramSuggestionEnabled && mAutoCorrectOn && mAutoCorrectEnabled) - ? Suggest.CORRECTION_FULL_BIGRAM : mCorrectionMode; - if (mSuggest != null) { - mSuggest.setCorrectionMode(mCorrectionMode); - } - } - - private void updateAutoTextEnabled(Locale systemLocale) { - if (mSuggest == null) return; - boolean different = - !systemLocale.getLanguage().equalsIgnoreCase(mInputLocale.substring(0, 2)); - mSuggest.setAutoTextEnabled(!different && mQuickFixes); - } - - protected void launchSettings() { - launchSettings(LatinIMESettings.class); - } - - public void launchDebugSettings() { - launchSettings(LatinIMEDebugSettings.class); - } - - protected void launchSettings (Class settingsClass) { - handleClose(); - Intent intent = new Intent(); - intent.setClass(KP2AKeyboard.this, settingsClass); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - } - - private void loadSettings() { - // Get the settings preferences - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); - mVibrateOn = sp.getBoolean(PREF_VIBRATE_ON, false); - mSoundOn = sp.getBoolean(PREF_SOUND_ON, false); - mPopupOn = sp.getBoolean(PREF_POPUP_ON, - mResources.getBoolean(R.bool.default_popup_preview)); - mAutoCap = sp.getBoolean(PREF_AUTO_CAP, true); - mQuickFixes = sp.getBoolean(PREF_QUICK_FIXES, true); - - mKp2aAutoFillOn = sp.getBoolean("kp2a_auto_fill", true); - mKp2aRememberAutoFill = sp.getBoolean(PREF_KP2A_REMEMBER_AUTO_FILL, true); - mKp2aEnableSimpleKeyboard = sp.getBoolean("kp2a_simple_keyboard", true); - mKp2aSwitchKeyboardOnSendGoDone = sp.getBoolean("kp2a_switch_on_sendgodone", false); - mKp2aLockOnSendGoDone = sp.getBoolean("kp2a_lock_on_sendgodone", false); - - - mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, true); - - mAutoCorrectEnabled = sp.getBoolean(PREF_AUTO_COMPLETE, - mResources.getBoolean(R.bool.enable_autocorrect)) & mShowSuggestions; - //mBigramSuggestionEnabled = sp.getBoolean( - // PREF_BIGRAM_SUGGESTIONS, true) & mShowSuggestions; - updateCorrectionMode(); - updateAutoTextEnabled(mResources.getConfiguration().locale); - mLanguageSwitcher.loadLocales(sp); - } - - private void initSuggestPuncList() { - mSuggestPuncList = new ArrayList(); - mSuggestPuncs = mResources.getString(R.string.suggested_punctuations); - if (mSuggestPuncs != null) { - for (int i = 0; i < mSuggestPuncs.length(); i++) { - mSuggestPuncList.add(mSuggestPuncs.subSequence(i, i + 1)); - } - } - } - - private boolean isSuggestedPunctuation(int code) { - return mSuggestPuncs.contains(String.valueOf((char)code)); - } - - private void showOptionsMenu() { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setCancelable(true); - builder.setIcon(R.drawable.ic_dialog_keyboard); - builder.setNegativeButton(android.R.string.cancel, null); - CharSequence itemSettings = getString(R.string.english_ime_settings); - CharSequence itemInputMethod = getString(R.string.selectInputMethod); - builder.setItems(new CharSequence[] { - itemInputMethod, itemSettings}, - new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface di, int position) { - di.dismiss(); - switch (position) { - case POS_SETTINGS: - launchSettings(); - break; - case POS_METHOD: - ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)) - .showInputMethodPicker(); - break; - } - } - }); - builder.setTitle(mResources.getString(R.string.english_ime_input_options)); - mOptionsDialog = builder.create(); - Window window = mOptionsDialog.getWindow(); - WindowManager.LayoutParams lp = window.getAttributes(); - lp.token = mKeyboardSwitcher.getInputView().getWindowToken(); - lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; - window.setAttributes(lp); - window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - mOptionsDialog.show(); - } - - public void changeKeyboardMode() { - mKeyboardSwitcher.toggleSymbols(); - if (mCapsLock && mKeyboardSwitcher.isAlphabetMode()) { - mKeyboardSwitcher.setShiftLocked(mCapsLock); - } - - updateShiftKeyState(getCurrentInputEditorInfo()); - } - - public static ArrayList newArrayList(E... elements) { - int capacity = (elements.length * 110) / 100 + 5; - ArrayList list = new ArrayList(capacity); - Collections.addAll(list, elements); - return list; - } - - @Override - protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { - super.dump(fd, fout, args); - - final Printer p = new PrintWriterPrinter(fout); - p.println("LatinIME state :"); - p.println(" Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode()); - p.println(" mCapsLock=" + mCapsLock); - p.println(" mComposing=" + mComposing.toString()); - p.println(" mPredictionOn=" + mPredictionOn); - p.println(" mCorrectionMode=" + mCorrectionMode); - p.println(" mPredicting=" + mPredicting); - p.println(" mAutoCorrectOn=" + mAutoCorrectOn); - p.println(" mAutoSpace=" + mAutoSpace); - p.println(" mCompletionOn=" + mCompletionOn); - p.println(" TextEntryState.state=" + TextEntryState.getState()); - p.println(" mSoundOn=" + mSoundOn); - p.println(" mVibrateOn=" + mVibrateOn); - p.println(" mPopupOn=" + mPopupOn); - } - - // Characters per second measurement - - private long mLastCpsTime; - private static final int CPS_BUFFER_SIZE = 16; - private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE]; - private int mCpsIndex; - - private void measureCps() { - long now = System.currentTimeMillis(); - if (mLastCpsTime == 0) mLastCpsTime = now - 100; // Initial - mCpsIntervals[mCpsIndex] = now - mLastCpsTime; - mLastCpsTime = now; - mCpsIndex = (mCpsIndex + 1) % CPS_BUFFER_SIZE; - long total = 0; - for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i]; - System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total)); - } - - public void onAutoCompletionStateChanged(boolean isAutoCompletion) { - mKeyboardSwitcher.onAutoCompletionStateChanged(isAutoCompletion); - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/KeyDetector.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/KeyDetector.java deleted file mode 100644 index d43e685b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/KeyDetector.java +++ /dev/null @@ -1,113 +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; -import android.inputmethodservice.Keyboard.Key; - -import java.util.Arrays; -import java.util.List; - -abstract class KeyDetector { - protected Keyboard mKeyboard; - - private Key[] mKeys; - - protected int mCorrectionX; - - protected int mCorrectionY; - - protected boolean mProximityCorrectOn; - - protected int mProximityThresholdSquare; - - public Key[] setKeyboard(Keyboard keyboard, float correctionX, float correctionY) { - if (keyboard == null) - throw new NullPointerException(); - mCorrectionX = (int)correctionX; - mCorrectionY = (int)correctionY; - mKeyboard = keyboard; - List keys = mKeyboard.getKeys(); - Key[] array = keys.toArray(new Key[keys.size()]); - mKeys = array; - return array; - } - - protected int getTouchX(int x) { - return x + mCorrectionX; - } - - protected int getTouchY(int y) { - return y + mCorrectionY; - } - - protected Key[] getKeys() { - if (mKeys == null) - throw new IllegalStateException("keyboard isn't set"); - // mKeyboard is guaranteed not to be null at setKeybaord() method if mKeys is not null - return mKeys; - } - - public void setProximityCorrectionEnabled(boolean enabled) { - mProximityCorrectOn = enabled; - } - - public boolean isProximityCorrectionEnabled() { - return mProximityCorrectOn; - } - - public void setProximityThreshold(int threshold) { - mProximityThresholdSquare = threshold * threshold; - } - - /** - * Allocates array that can hold all key indices returned by {@link #getKeyIndexAndNearbyCodes} - * method. The maximum size of the array should be computed by {@link #getMaxNearbyKeys}. - * - * @return Allocates and returns an array that can hold all key indices returned by - * {@link #getKeyIndexAndNearbyCodes} method. All elements in the returned array are - * initialized by {@link keepass2android.softkeyboard.LatinKeyboardView.NOT_A_KEY} - * value. - */ - public int[] newCodeArray() { - int[] codes = new int[getMaxNearbyKeys()]; - Arrays.fill(codes, LatinKeyboardBaseView.NOT_A_KEY); - return codes; - } - - /** - * Computes maximum size of the array that can contain all nearby key indices returned by - * {@link #getKeyIndexAndNearbyCodes}. - * - * @return Returns maximum size of the array that can contain all nearby key indices returned - * by {@link #getKeyIndexAndNearbyCodes}. - */ - abstract protected int getMaxNearbyKeys(); - - /** - * Finds all possible nearby key indices around a touch event point and returns the nearest key - * index. The algorithm to determine the nearby keys depends on the threshold set by - * {@link #setProximityThreshold(int)} and the mode set by - * {@link #setProximityCorrectionEnabled(boolean)}. - * - * @param x The x-coordinate of a touch point - * @param y The y-coordinate of a touch point - * @param allKeys All nearby key indices are returned in this array - * @return The nearest key index - */ - abstract public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys); -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/KeyboardSwitcher.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/KeyboardSwitcher.java deleted file mode 100644 index afed1204..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/KeyboardSwitcher.java +++ /dev/null @@ -1,591 +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.SharedPreferences; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.preference.PreferenceManager; -import android.util.Log; -import android.view.InflateException; - -import java.lang.ref.SoftReference; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Locale; - -public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener { - - public static final int MODE_NONE = 0; - public static final int MODE_TEXT = 1; - public static final int MODE_SYMBOLS = 2; - public static final int MODE_PHONE = 3; - public static final int MODE_URL = 4; - public static final int MODE_EMAIL = 5; - public static final int MODE_IM = 6; - public static final int MODE_WEB = 7; - public static final int MODE_KP2A = 8; - - // Main keyboard layouts without the settings key - public static final int KEYBOARDMODE_NORMAL = R.id.mode_normal; - public static final int KEYBOARDMODE_URL = R.id.mode_url; - public static final int KEYBOARDMODE_EMAIL = R.id.mode_email; - public static final int KEYBOARDMODE_IM = R.id.mode_im; - public static final int KEYBOARDMODE_WEB = R.id.mode_webentry; - // Main keyboard layouts with the settings key - public static final int KEYBOARDMODE_NORMAL_WITH_SETTINGS_KEY = - R.id.mode_normal_with_settings_key; - public static final int KEYBOARDMODE_URL_WITH_SETTINGS_KEY = - R.id.mode_url_with_settings_key; - public static final int KEYBOARDMODE_EMAIL_WITH_SETTINGS_KEY = - R.id.mode_email_with_settings_key; - public static final int KEYBOARDMODE_IM_WITH_SETTINGS_KEY = - R.id.mode_im_with_settings_key; - public static final int KEYBOARDMODE_WEB_WITH_SETTINGS_KEY = - R.id.mode_webentry_with_settings_key; - - // Symbols keyboard layout without the settings key - public static final int KEYBOARDMODE_SYMBOLS = R.id.mode_symbols; - // Symbols keyboard layout with the settings key - public static final int KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY = - R.id.mode_symbols_with_settings_key; - - public static final String DEFAULT_LAYOUT_ID = "4"; - public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20100902"; - private static final int[] THEMES = new int [] { - R.layout.input_basic, R.layout.input_basic_highcontrast, R.layout.input_stone_normal, - R.layout.input_stone_bold, R.layout.input_gingerbread}; - - // Ids for each characters' color in the keyboard - private static final int CHAR_THEME_COLOR_WHITE = 0; - private static final int CHAR_THEME_COLOR_BLACK = 1; - - // Tables which contains resource ids for each character theme color - private static final int[] KBD_PHONE = new int[] {R.xml.kbd_phone, R.xml.kbd_phone_black}; - private static final int[] KBD_PHONE_SYMBOLS = new int[] { - R.xml.kbd_phone_symbols, R.xml.kbd_phone_symbols_black}; - private static final int[] KBD_SYMBOLS = new int[] { - R.xml.kbd_symbols, R.xml.kbd_symbols_black}; - private static final int[] KBD_SYMBOLS_SHIFT = new int[] { - R.xml.kbd_symbols_shift, R.xml.kbd_symbols_shift_black}; - private static final int[] KBD_QWERTY = new int[] {R.xml.kbd_qwerty, R.xml.kbd_qwerty_black}; - - private static final int[] KBD_KP2A = new int[] {R.xml.kbd_kp2a, R.xml.kbd_kp2a_black}; - - private LatinKeyboardView mInputView; - private static final int[] ALPHABET_MODES = { - KEYBOARDMODE_NORMAL, - KEYBOARDMODE_URL, - KEYBOARDMODE_EMAIL, - KEYBOARDMODE_IM, - KEYBOARDMODE_WEB, - KEYBOARDMODE_NORMAL_WITH_SETTINGS_KEY, - KEYBOARDMODE_URL_WITH_SETTINGS_KEY, - KEYBOARDMODE_EMAIL_WITH_SETTINGS_KEY, - KEYBOARDMODE_IM_WITH_SETTINGS_KEY, - KEYBOARDMODE_WEB_WITH_SETTINGS_KEY }; - - private KP2AKeyboard mInputMethodService; - - private KeyboardId mSymbolsId; - private KeyboardId mSymbolsShiftedId; - - private KeyboardId mCurrentId; - private final HashMap> mKeyboards = - new HashMap>(); - - private int mMode = MODE_NONE; /** One of the MODE_XXX values */ - private int mImeOptions; - private boolean mIsSymbols; - /** mIsAutoCompletionActive indicates that auto completed word will be input instead of - * what user actually typed. */ - private boolean mIsAutoCompletionActive; - private boolean mPreferSymbols; - - private static final int AUTO_MODE_SWITCH_STATE_ALPHA = 0; - private static final int AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN = 1; - private static final int AUTO_MODE_SWITCH_STATE_SYMBOL = 2; - // The following states are used only on the distinct multi-touch panel devices. - private static final int AUTO_MODE_SWITCH_STATE_MOMENTARY = 3; - private static final int AUTO_MODE_SWITCH_STATE_CHORDING = 4; - private int mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA; - - // Indicates whether or not we have the settings key - private boolean mHasSettingsKey; - private static final int SETTINGS_KEY_MODE_AUTO = R.string.settings_key_mode_auto; - private static final int SETTINGS_KEY_MODE_ALWAYS_SHOW = R.string.settings_key_mode_always_show; - // NOTE: No need to have SETTINGS_KEY_MODE_ALWAYS_HIDE here because it's not being referred to - // in the source code now. - // Default is SETTINGS_KEY_MODE_AUTO. - private static final int DEFAULT_SETTINGS_KEY_MODE = SETTINGS_KEY_MODE_AUTO; - - private int mLastDisplayWidth; - private LanguageSwitcher mLanguageSwitcher; - private Locale mInputLocale; - - private int mLayoutId; - - private static final KeyboardSwitcher sInstance = new KeyboardSwitcher(); - - public static KeyboardSwitcher getInstance() { - return sInstance; - } - - private KeyboardSwitcher() { - // Intentional empty constructor for singleton. - } - - public static void init(KP2AKeyboard ims) { - sInstance.mInputMethodService = ims; - - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ims); - sInstance.mLayoutId = Integer.valueOf( - prefs.getString(PREF_KEYBOARD_LAYOUT, DEFAULT_LAYOUT_ID)); - sInstance.updateSettingsKeyState(prefs); - prefs.registerOnSharedPreferenceChangeListener(sInstance); - - sInstance.mSymbolsId = sInstance.makeSymbolsId(); - sInstance.mSymbolsShiftedId = sInstance.makeSymbolsShiftedId(); - } - - /** - * Sets the input locale, when there are multiple locales for input. - * If no locale switching is required, then the locale should be set to null. - * @param locale the current input locale, or null for default locale with no locale - * button. - */ - public void setLanguageSwitcher(LanguageSwitcher languageSwitcher) { - mLanguageSwitcher = languageSwitcher; - mInputLocale = mLanguageSwitcher.getInputLocale(); - } - - private KeyboardId makeSymbolsId() { - return new KeyboardId(KBD_SYMBOLS[getCharColorId()], mHasSettingsKey ? - KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY : KEYBOARDMODE_SYMBOLS, - false); - } - - private KeyboardId makeSymbolsShiftedId() { - return new KeyboardId(KBD_SYMBOLS_SHIFT[getCharColorId()], mHasSettingsKey ? - KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY : KEYBOARDMODE_SYMBOLS, - false); - } - - public void makeKeyboards(boolean forceCreate) { - mSymbolsId = makeSymbolsId(); - mSymbolsShiftedId = makeSymbolsShiftedId(); - - if (forceCreate) mKeyboards.clear(); - // Configuration change is coming after the keyboard gets recreated. So don't rely on that. - // If keyboards have already been made, check if we have a screen width change and - // create the keyboard layouts again at the correct orientation - int displayWidth = mInputMethodService.getMaxWidth(); - if (displayWidth == mLastDisplayWidth) return; - mLastDisplayWidth = displayWidth; - if (!forceCreate) mKeyboards.clear(); - } - - /** - * Represents the parameters necessary to construct a new LatinKeyboard, - * which also serve as a unique identifier for each keyboard type. - */ - private static class KeyboardId { - // TODO: should have locale and portrait/landscape orientation? - public final int mXml; - public final int mKeyboardMode; /** A KEYBOARDMODE_XXX value */ - public final boolean mEnableShiftLock; - - private final int mHashCode; - - public KeyboardId(int xml, int mode, boolean enableShiftLock) { - this.mXml = xml; - this.mKeyboardMode = mode; - this.mEnableShiftLock = enableShiftLock; - - this.mHashCode = Arrays.hashCode(new Object[] { - xml, mode, enableShiftLock - }); - } - - public KeyboardId(int xml) { - this(xml, 0, false); - } - - @Override - public boolean equals(Object other) { - return other instanceof KeyboardId && equals((KeyboardId) other); - } - - private boolean equals(KeyboardId other) { - return other.mXml == this.mXml - && other.mKeyboardMode == this.mKeyboardMode - && other.mEnableShiftLock == this.mEnableShiftLock - ; - } - - @Override - public int hashCode() { - return mHashCode; - } - } - - - public void setKeyboardMode(int mode, int imeOptions) { - Log.d("KP2AK", "Switcher.SetKeyboardMode: " + mode); - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA; - mPreferSymbols = mode == MODE_SYMBOLS; - if (mode == MODE_SYMBOLS) { - mode = MODE_TEXT; - } - try { - setKeyboardMode(mode, imeOptions, mPreferSymbols); - } catch (RuntimeException e) { - LatinImeLogger.logOnException(mode + "," + imeOptions + "," + mPreferSymbols, e); - } - } - - private void setKeyboardMode(int mode, int imeOptions, boolean isSymbols) { - if (mInputView == null) return; - mMode = mode; - mImeOptions = imeOptions; - mIsSymbols = isSymbols; - - mInputView.setPreviewEnabled(mInputMethodService.getPopupOn()); - KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); - LatinKeyboard keyboard = null; - keyboard = getKeyboard(id); - - if (mode == MODE_PHONE) { - mInputView.setPhoneKeyboard(keyboard); - } - - mCurrentId = id; - mInputView.setKeyboard(keyboard); - keyboard.setShifted(false); - keyboard.setShiftLocked(keyboard.isShiftLocked()); - keyboard.setImeOptions(mInputMethodService.getResources(), mMode, imeOptions); - keyboard.setColorOfSymbolIcons(mIsAutoCompletionActive, isBlackSym()); - // Update the settings key state because number of enabled IMEs could have been changed - updateSettingsKeyState(PreferenceManager.getDefaultSharedPreferences(mInputMethodService)); - } - - private LatinKeyboard getKeyboard(KeyboardId id) { - SoftReference ref = mKeyboards.get(id); - LatinKeyboard keyboard = (ref == null) ? null : ref.get(); - if (keyboard == null) { - Resources orig = mInputMethodService.getResources(); - Configuration conf = orig.getConfiguration(); - Locale saveLocale = conf.locale; - conf.locale = mInputLocale; - orig.updateConfiguration(conf, null); - keyboard = new LatinKeyboard(mInputMethodService, id.mXml, id.mKeyboardMode); - keyboard.setLanguageSwitcher(mLanguageSwitcher, mIsAutoCompletionActive, isBlackSym()); - - if (id.mEnableShiftLock) { - keyboard.enableShiftLock(); - } - mKeyboards.put(id, new SoftReference(keyboard)); - - conf.locale = saveLocale; - orig.updateConfiguration(conf, null); - } - return keyboard; - } - - private KeyboardId getKeyboardId(int mode, int imeOptions, boolean isSymbols) { - int charColorId = getCharColorId(); - if (isSymbols) { - if (mode == MODE_PHONE) { - return new KeyboardId(KBD_PHONE_SYMBOLS[charColorId]); - } else { - return new KeyboardId(KBD_SYMBOLS[charColorId], mHasSettingsKey ? - KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY : KEYBOARDMODE_SYMBOLS, - false); - } - } - // TODO: generalize for any KeyboardId - int keyboardRowsResId = KBD_QWERTY[charColorId]; - - switch (mode) { - case MODE_KP2A: - return new KeyboardId(KBD_KP2A[charColorId]); - case MODE_NONE: - LatinImeLogger.logOnWarning( - "getKeyboardId:" + mode + "," + imeOptions + "," + isSymbols); - /* fall through */ - case MODE_TEXT: - return new KeyboardId(keyboardRowsResId, mHasSettingsKey ? - KEYBOARDMODE_NORMAL_WITH_SETTINGS_KEY : KEYBOARDMODE_NORMAL, - true); - case MODE_SYMBOLS: - return new KeyboardId(KBD_SYMBOLS[charColorId], mHasSettingsKey ? - KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY : KEYBOARDMODE_SYMBOLS, - false); - case MODE_PHONE: - return new KeyboardId(KBD_PHONE[charColorId]); - case MODE_URL: - return new KeyboardId(keyboardRowsResId, mHasSettingsKey ? - KEYBOARDMODE_URL_WITH_SETTINGS_KEY : KEYBOARDMODE_URL, true); - case MODE_EMAIL: - return new KeyboardId(keyboardRowsResId, mHasSettingsKey ? - KEYBOARDMODE_EMAIL_WITH_SETTINGS_KEY : KEYBOARDMODE_EMAIL, true); - case MODE_IM: - return new KeyboardId(keyboardRowsResId, mHasSettingsKey ? - KEYBOARDMODE_IM_WITH_SETTINGS_KEY : KEYBOARDMODE_IM, true); - case MODE_WEB: - return new KeyboardId(keyboardRowsResId, mHasSettingsKey ? - KEYBOARDMODE_WEB_WITH_SETTINGS_KEY : KEYBOARDMODE_WEB, true); - } - return null; - } - - public int getKeyboardMode() { - return mMode; - } - - public boolean isAlphabetMode() { - if (mCurrentId == null) { - return false; - } - int currentMode = mCurrentId.mKeyboardMode; - for (Integer mode : ALPHABET_MODES) { - if (currentMode == mode) { - return true; - } - } - return false; - } - - public void setShifted(boolean shifted) { - if (mInputView != null) { - mInputView.setShifted(shifted); - } - } - - public void setShiftLocked(boolean shiftLocked) { - if (mInputView != null) { - mInputView.setShiftLocked(shiftLocked); - } - } - - public void toggleShift() { - if (isAlphabetMode()) - return; - if (mCurrentId.equals(mSymbolsId) || !mCurrentId.equals(mSymbolsShiftedId)) { - LatinKeyboard symbolsShiftedKeyboard = getKeyboard(mSymbolsShiftedId); - mCurrentId = mSymbolsShiftedId; - mInputView.setKeyboard(symbolsShiftedKeyboard); - // Symbol shifted keyboard has an ALT key that has a caps lock style indicator. To - // enable the indicator, we need to call enableShiftLock() and setShiftLocked(true). - // Thus we can keep the ALT key's Key.on value true while LatinKey.onRelease() is - // called. - symbolsShiftedKeyboard.enableShiftLock(); - symbolsShiftedKeyboard.setShiftLocked(true); - symbolsShiftedKeyboard.setImeOptions(mInputMethodService.getResources(), - mMode, mImeOptions); - } else { - LatinKeyboard symbolsKeyboard = getKeyboard(mSymbolsId); - mCurrentId = mSymbolsId; - mInputView.setKeyboard(symbolsKeyboard); - // Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the - // indicator, we need to call enableShiftLock() and setShiftLocked(false). - symbolsKeyboard.enableShiftLock(); - symbolsKeyboard.setShifted(false); - symbolsKeyboard.setImeOptions(mInputMethodService.getResources(), mMode, mImeOptions); - } - } - - public void onCancelInput() { - // Snap back to the previous keyboard mode if the user cancels sliding input. - if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY && getPointerCount() == 1) - mInputMethodService.changeKeyboardMode(); - } - - public void toggleSymbols() { - setKeyboardMode(mMode, mImeOptions, !mIsSymbols); - if (mIsSymbols && !mPreferSymbols) { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN; - } else { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA; - } - } - - public boolean hasDistinctMultitouch() { - return mInputView != null && mInputView.hasDistinctMultitouch(); - } - - public void setAutoModeSwitchStateMomentary() { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_MOMENTARY; - } - - public boolean isInMomentaryAutoModeSwitchState() { - return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY; - } - - public boolean isInChordingAutoModeSwitchState() { - return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_CHORDING; - } - - public boolean isVibrateAndSoundFeedbackRequired() { - return mInputView != null && !mInputView.isInSlidingKeyInput(); - } - - private int getPointerCount() { - return mInputView == null ? 0 : mInputView.getPointerCount(); - } - - /** - * Updates state machine to figure out when to automatically snap back to the previous mode. - */ - public void onKey(int key) { - // Switch back to alpha mode if user types one or more non-space/enter characters - // followed by a space/enter - switch (mAutoModeSwitchState) { - case AUTO_MODE_SWITCH_STATE_MOMENTARY: - // Only distinct multi touch devices can be in this state. - // On non-distinct multi touch devices, mode change key is handled by {@link onKey}, - // not by {@link onPress} and {@link onRelease}. So, on such devices, - // {@link mAutoModeSwitchState} starts from {@link AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN}, - // or {@link AUTO_MODE_SWITCH_STATE_ALPHA}, not from - // {@link AUTO_MODE_SWITCH_STATE_MOMENTARY}. - if (key == LatinKeyboard.KEYCODE_MODE_CHANGE) { - // Detected only the mode change key has been pressed, and then released. - if (mIsSymbols) { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN; - } else { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA; - } - } else if (getPointerCount() == 1) { - // Snap back to the previous keyboard mode if the user pressed the mode change key - // and slid to other key, then released the finger. - // If the user cancels the sliding input, snapping back to the previous keyboard - // mode is handled by {@link #onCancelInput}. - mInputMethodService.changeKeyboardMode(); - } else { - // Chording input is being started. The keyboard mode will be snapped back to the - // previous mode in {@link onReleaseSymbol} when the mode change key is released. - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_CHORDING; - } - break; - case AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN: - if (key != KP2AKeyboard.KEYCODE_SPACE && key != KP2AKeyboard.KEYCODE_ENTER && key >= 0) { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL; - } - break; - case AUTO_MODE_SWITCH_STATE_SYMBOL: - // Snap back to alpha keyboard mode if user types one or more non-space/enter - // characters followed by a space/enter. - if (key == KP2AKeyboard.KEYCODE_ENTER || key == KP2AKeyboard.KEYCODE_SPACE) { - mInputMethodService.changeKeyboardMode(); - } - break; - } - } - - public LatinKeyboardView getInputView() { - return mInputView; - } - - public void recreateInputView() { - changeLatinKeyboardView(mLayoutId, true); - } - - private void changeLatinKeyboardView(int newLayout, boolean forceReset) { - if (mLayoutId != newLayout || mInputView == null || forceReset) { - if (mInputView != null) { - mInputView.closing(); - } - if (THEMES.length <= newLayout) { - newLayout = Integer.valueOf(DEFAULT_LAYOUT_ID); - } - - LatinIMEUtil.GCUtils.getInstance().reset(); - boolean tryGC = true; - for (int i = 0; i < LatinIMEUtil.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { - try { - mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater( - ).inflate(THEMES[newLayout], null); - tryGC = false; - } catch (OutOfMemoryError e) { - tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait( - mLayoutId + "," + newLayout, e); - } catch (InflateException e) { - tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait( - mLayoutId + "," + newLayout, e); - } - } - mInputView.setOnKeyboardActionListener(mInputMethodService); - mLayoutId = newLayout; - } - mInputMethodService.mHandler.post(new Runnable() { - public void run() { - if (mInputView != null) { - mInputMethodService.setInputView(mInputView); - } - mInputMethodService.updateInputViewShown(); - }}); - } - - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (PREF_KEYBOARD_LAYOUT.equals(key)) { - changeLatinKeyboardView( - Integer.valueOf(sharedPreferences.getString(key, DEFAULT_LAYOUT_ID)), false); - } else if (LatinIMESettings.PREF_SETTINGS_KEY.equals(key)) { - updateSettingsKeyState(sharedPreferences); - recreateInputView(); - } - } - - public boolean isBlackSym () { - if (mInputView != null && mInputView.getSymbolColorScheme() == 1) { - return true; - } - return false; - } - - private int getCharColorId () { - if (isBlackSym()) { - return CHAR_THEME_COLOR_BLACK; - } else { - return CHAR_THEME_COLOR_WHITE; - } - } - - public void onAutoCompletionStateChanged(boolean isAutoCompletion) { - if (isAutoCompletion != mIsAutoCompletionActive) { - LatinKeyboardView keyboardView = getInputView(); - mIsAutoCompletionActive = isAutoCompletion; - keyboardView.invalidateKey(((LatinKeyboard) keyboardView.getKeyboard()) - .onAutoCompletionStateChanged(isAutoCompletion)); - } - } - - private void updateSettingsKeyState(SharedPreferences prefs) { - Resources resources = mInputMethodService.getResources(); - final String settingsKeyMode = prefs.getString(LatinIMESettings.PREF_SETTINGS_KEY, - resources.getString(DEFAULT_SETTINGS_KEY_MODE)); - // We show the settings key when 1) SETTINGS_KEY_MODE_ALWAYS_SHOW or - // 2) SETTINGS_KEY_MODE_AUTO and there are two or more enabled IMEs on the system - if (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW)) - || (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_AUTO)) - && LatinIMEUtil.hasMultipleEnabledIMEs(mInputMethodService))) { - mHasSettingsKey = true; - } else { - mHasSettingsKey = false; - } - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LanguageSwitcher.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LanguageSwitcher.java deleted file mode 100644 index 844b7c4c..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LanguageSwitcher.java +++ /dev/null @@ -1,201 +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.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.preference.PreferenceManager; -import android.text.TextUtils; - -import java.util.Locale; - -/** - * Keeps track of list of selected input languages and the current - * input language that the user has selected. - */ -public class LanguageSwitcher { - - private Locale[] mLocales; - private KP2AKeyboard mIme; - private String[] mSelectedLanguageArray; - private String mSelectedLanguages; - private int mCurrentIndex = 0; - private String mDefaultInputLanguage; - private Locale mDefaultInputLocale; - private Locale mSystemLocale; - - public LanguageSwitcher(KP2AKeyboard ime) { - mIme = ime; - mLocales = new Locale[0]; - } - - public Locale[] getLocales() { - return mLocales; - } - - public int getLocaleCount() { - return mLocales.length; - } - - /** - * Loads the currently selected input languages from shared preferences. - * @param sp - * @return whether there was any change - */ - public boolean loadLocales(SharedPreferences sp) { - String selectedLanguages = sp.getString(KP2AKeyboard.PREF_SELECTED_LANGUAGES, null); - String currentLanguage = sp.getString(KP2AKeyboard.PREF_INPUT_LANGUAGE, null); - if (selectedLanguages == null || selectedLanguages.length() < 1) { - loadDefaults(); - if (mLocales.length == 0) { - return false; - } - mLocales = new Locale[0]; - return true; - } - if (selectedLanguages.equals(mSelectedLanguages)) { - return false; - } - mSelectedLanguageArray = selectedLanguages.split(","); - mSelectedLanguages = selectedLanguages; // Cache it for comparison later - constructLocales(); - mCurrentIndex = 0; - if (currentLanguage != null) { - // Find the index - mCurrentIndex = 0; - for (int i = 0; i < mLocales.length; i++) { - if (mSelectedLanguageArray[i].equals(currentLanguage)) { - mCurrentIndex = i; - break; - } - } - // If we didn't find the index, use the first one - } - return true; - } - - private void loadDefaults() { - mDefaultInputLocale = mIme.getResources().getConfiguration().locale; - String country = mDefaultInputLocale.getCountry(); - mDefaultInputLanguage = mDefaultInputLocale.getLanguage() + - (TextUtils.isEmpty(country) ? "" : "_" + country); - } - - private void constructLocales() { - mLocales = new Locale[mSelectedLanguageArray.length]; - for (int i = 0; i < mLocales.length; i++) { - final String lang = mSelectedLanguageArray[i]; - mLocales[i] = new Locale(lang.substring(0, 2), - lang.length() > 4 ? lang.substring(3, 5) : ""); - } - } - - /** - * Returns the currently selected input language code, or the display language code if - * no specific locale was selected for input. - */ - public String getInputLanguage() { - if (getLocaleCount() == 0) return mDefaultInputLanguage; - - return mSelectedLanguageArray[mCurrentIndex]; - } - - /** - * Returns the list of enabled language codes. - */ - public String[] getEnabledLanguages() { - return mSelectedLanguageArray; - } - - /** - * Returns the currently selected input locale, or the display locale if no specific - * locale was selected for input. - * @return - */ - public Locale getInputLocale() { - if (getLocaleCount() == 0) return mDefaultInputLocale; - - return mLocales[mCurrentIndex]; - } - - /** - * Returns the next input locale in the list. Wraps around to the beginning of the - * list if we're at the end of the list. - * @return - */ - public Locale getNextInputLocale() { - if (getLocaleCount() == 0) return mDefaultInputLocale; - - return mLocales[(mCurrentIndex + 1) % mLocales.length]; - } - - /** - * Sets the system locale (display UI) used for comparing with the input language. - * @param locale the locale of the system - */ - public void setSystemLocale(Locale locale) { - mSystemLocale = locale; - } - - /** - * Returns the system locale. - * @return the system locale - */ - public Locale getSystemLocale() { - return mSystemLocale; - } - - /** - * Returns the previous input locale in the list. Wraps around to the end of the - * list if we're at the beginning of the list. - * @return - */ - public Locale getPrevInputLocale() { - if (getLocaleCount() == 0) return mDefaultInputLocale; - - return mLocales[(mCurrentIndex - 1 + mLocales.length) % mLocales.length]; - } - - public void reset() { - mCurrentIndex = 0; - } - - public void next() { - mCurrentIndex++; - if (mCurrentIndex >= mLocales.length) mCurrentIndex = 0; // Wrap around - } - - public void prev() { - mCurrentIndex--; - if (mCurrentIndex < 0) mCurrentIndex = mLocales.length - 1; // Wrap around - } - - public void persist() { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mIme); - Editor editor = sp.edit(); - editor.putString(KP2AKeyboard.PREF_INPUT_LANGUAGE, getInputLanguage()); - SharedPreferencesCompat.apply(editor); - } - - static String toTitleCase(String s, Locale locale) { - if (s.length() == 0) { - return s; - } - - return s.toUpperCase(locale).charAt(0) + s.substring(1); - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMEBackupAgent.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMEBackupAgent.java deleted file mode 100644 index 58618cef..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMEBackupAgent.java +++ /dev/null @@ -1,32 +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.app.backup.BackupAgentHelper; -import android.app.backup.SharedPreferencesBackupHelper; - -/** - * Backs up the Latin IME shared preferences. - */ -public class LatinIMEBackupAgent extends BackupAgentHelper { - - @Override - public void onCreate() { - addHelper("shared_pref", new SharedPreferencesBackupHelper(this, - getPackageName() + "_preferences")); - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMEDebugSettings.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMEDebugSettings.java deleted file mode 100644 index 789030e7..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMEDebugSettings.java +++ /dev/null @@ -1,75 +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 android.content.pm.PackageInfo; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.PreferenceActivity; -import android.util.Log; - -public class LatinIMEDebugSettings extends PreferenceActivity - implements SharedPreferences.OnSharedPreferenceChangeListener { - - private static final String TAG = "LatinIMEDebugSettings"; - private static final String DEBUG_MODE_KEY = "debug_mode"; - - private CheckBoxPreference mDebugMode; - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - addPreferencesFromResource(R.xml.prefs_for_debug); - SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); - prefs.registerOnSharedPreferenceChangeListener(this); - - mDebugMode = (CheckBoxPreference) findPreference(DEBUG_MODE_KEY); - updateDebugMode(); - } - - public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { - if (key.equals(DEBUG_MODE_KEY)) { - if (mDebugMode != null) { - mDebugMode.setChecked(prefs.getBoolean(DEBUG_MODE_KEY, false)); - updateDebugMode(); - } - } - } - - private void updateDebugMode() { - if (mDebugMode == null) { - return; - } - boolean isDebugMode = mDebugMode.isChecked(); - String version = ""; - try { - PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0); - version = "Version " + info.versionName; - } catch (NameNotFoundException e) { - Log.e(TAG, "Could not find version info."); - } - if (!isDebugMode) { - mDebugMode.setTitle(version); - mDebugMode.setSummary(""); - } else { - mDebugMode.setTitle(getResources().getString(R.string.prefs_debug_mode)); - mDebugMode.setSummary(version); - } - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMESettings.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMESettings.java deleted file mode 100644 index bc94b9de..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMESettings.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * Copyright (C) 2014 Philipp Crocoll - * Copyright (C) 2014 Wiktor Lawski - * - * 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; -import java.util.Locale; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.backup.BackupManager; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.ListPreference; -import android.preference.PreferenceActivity; -import android.preference.PreferenceGroup; -import android.preference.PreferenceManager; -import android.speech.SpeechRecognizer; -import android.text.AutoText; -import android.util.Log; - -public class LatinIMESettings extends PreferenceActivity - implements SharedPreferences.OnSharedPreferenceChangeListener, - DialogInterface.OnDismissListener { - - private static final String QUICK_FIXES_KEY = "quick_fixes"; - private static final String PREDICTION_SETTINGS_KEY = "prediction_settings"; - - /* package */ static final String PREF_SETTINGS_KEY = "settings_key"; - - private static final String TAG = "LatinIMESettings"; - - - private CheckBoxPreference mQuickFixes; - private ListPreference mSettingsKeyPreference; - - private boolean mOkClicked = false; - - @Override - protected void onCreate(Bundle icicle) { - SharedPreferences prefs = - PreferenceManager.getDefaultSharedPreferences(this); - Design.updateTheme(this, prefs); - - super.onCreate(icicle); - addPreferencesFromResource(R.xml.prefs); - mQuickFixes = (CheckBoxPreference) findPreference(QUICK_FIXES_KEY); - mSettingsKeyPreference = (ListPreference) findPreference(PREF_SETTINGS_KEY); - prefs.registerOnSharedPreferenceChangeListener(this); - - - } - - @Override - protected void onResume() { - super.onResume(); - int autoTextSize = AutoText.getSize(getListView()); - if (autoTextSize < 1) { - ((PreferenceGroup) findPreference(PREDICTION_SETTINGS_KEY)) - .removePreference(mQuickFixes); - } - - - } - - @Override - protected void onDestroy() { - getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener( - this); - super.onDestroy(); - } - - public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { - (new BackupManager(this)).dataChanged(); - - } - - - - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - - default: - Log.e(TAG, "unknown dialog " + id); - return null; - } - } - - public void onDismiss(DialogInterface dialog) { - - } - -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMEUtil.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMEUtil.java deleted file mode 100644 index 070ff43b..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinIMEUtil.java +++ /dev/null @@ -1,171 +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.view.inputmethod.InputMethodManager; - -import android.content.Context; -import android.os.AsyncTask; -import android.text.format.DateUtils; -import android.util.Log; - -public class LatinIMEUtil { - - /** - * Cancel an {@link AsyncTask}. - * - * @param mayInterruptIfRunning true if the thread executing this - * task should be interrupted; otherwise, in-progress tasks are allowed - * to complete. - */ - public static void cancelTask(AsyncTask task, boolean mayInterruptIfRunning) { - if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) { - task.cancel(mayInterruptIfRunning); - } - } - - public static class GCUtils { - private static final String TAG = "GCUtils"; - public static final int GC_TRY_COUNT = 2; - // GC_TRY_LOOP_MAX is used for the hard limit of GC wait, - // GC_TRY_LOOP_MAX should be greater than GC_TRY_COUNT. - public static final int GC_TRY_LOOP_MAX = 5; - private static final long GC_INTERVAL = DateUtils.SECOND_IN_MILLIS; - private static GCUtils sInstance = new GCUtils(); - private int mGCTryCount = 0; - - public static GCUtils getInstance() { - return sInstance; - } - - public void reset() { - mGCTryCount = 0; - } - - public boolean tryGCOrWait(String metaData, Throwable t) { - if (mGCTryCount == 0) { - System.gc(); - } - if (++mGCTryCount > GC_TRY_COUNT) { - LatinImeLogger.logOnException(metaData, t); - return false; - } else { - try { - Thread.sleep(GC_INTERVAL); - return true; - } catch (InterruptedException e) { - Log.e(TAG, "Sleep was interrupted."); - LatinImeLogger.logOnException(metaData, t); - return false; - } - } - } - } - - public static boolean hasMultipleEnabledIMEs(Context context) { - return ((InputMethodManager) context.getSystemService( - Context.INPUT_METHOD_SERVICE)).getEnabledInputMethodList().size() > 1; - } - - /* package */ static class RingCharBuffer { - private static RingCharBuffer sRingCharBuffer = new RingCharBuffer(); - private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC'; - private static final int INVALID_COORDINATE = -2; - /* package */ static final int BUFSIZE = 20; - private Context mContext; - private boolean mEnabled = false; - private int mEnd = 0; - /* package */ int mLength = 0; - private char[] mCharBuf = new char[BUFSIZE]; - private int[] mXBuf = new int[BUFSIZE]; - private int[] mYBuf = new int[BUFSIZE]; - - private RingCharBuffer() { - } - public static RingCharBuffer getInstance() { - return sRingCharBuffer; - } - public static RingCharBuffer init(Context context, boolean enabled) { - sRingCharBuffer.mContext = context; - sRingCharBuffer.mEnabled = enabled; - return sRingCharBuffer; - } - private int normalize(int in) { - int ret = in % BUFSIZE; - return ret < 0 ? ret + BUFSIZE : ret; - } - public void push(char c, int x, int y) { - if (!mEnabled) return; - mCharBuf[mEnd] = c; - mXBuf[mEnd] = x; - mYBuf[mEnd] = y; - mEnd = normalize(mEnd + 1); - if (mLength < BUFSIZE) { - ++mLength; - } - } - public char pop() { - if (mLength < 1) { - return PLACEHOLDER_DELIMITER_CHAR; - } else { - mEnd = normalize(mEnd - 1); - --mLength; - return mCharBuf[mEnd]; - } - } - public char getLastChar() { - if (mLength < 1) { - return PLACEHOLDER_DELIMITER_CHAR; - } else { - return mCharBuf[normalize(mEnd - 1)]; - } - } - public int getPreviousX(char c, int back) { - int index = normalize(mEnd - 2 - back); - if (mLength <= back - || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) { - return INVALID_COORDINATE; - } else { - return mXBuf[index]; - } - } - public int getPreviousY(char c, int back) { - int index = normalize(mEnd - 2 - back); - if (mLength <= back - || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) { - return INVALID_COORDINATE; - } else { - return mYBuf[index]; - } - } - public String getLastString() { - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < mLength; ++i) { - char c = mCharBuf[normalize(mEnd - 1 - i)]; - if (!((KP2AKeyboard)mContext).isWordSeparator(c)) { - sb.append(c); - } else { - break; - } - } - return sb.reverse().toString(); - } - public void reset() { - mLength = 0; - } - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinImeLogger.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinImeLogger.java deleted file mode 100644 index 1e347369..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinImeLogger.java +++ /dev/null @@ -1,71 +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 keepass2android.softkeyboard.Dictionary.DataType; - -import android.content.Context; -import android.content.SharedPreferences; -import android.inputmethodservice.Keyboard; -import java.util.List; - -public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChangeListener { - - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - } - - public static void init(Context context) { - } - - public static void commit() { - } - - public static void onDestroy() { - } - - public static void logOnManualSuggestion( - String before, String after, int position, List suggestions) { - } - - public static void logOnAutoSuggestion(String before, String after) { - } - - public static void logOnAutoSuggestionCanceled() { - } - - public static void logOnDelete() { - } - - public static void logOnInputChar() { - } - - public static void logOnException(String metaData, Throwable e) { - } - - public static void logOnWarning(String warning) { - } - - public static void onStartSuggestion(CharSequence previousWords) { - } - - public static void onAddSuggestedWord(String word, int typeId, DataType dataType) { - } - - public static void onSetKeyboard(Keyboard kb) { - } - -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinKeyboard.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinKeyboard.java deleted file mode 100644 index 45bc65d9..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinKeyboard.java +++ /dev/null @@ -1,1013 +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.annotation.SuppressLint; -import android.content.Context; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.Paint.Align; -import android.graphics.PixelFormat; -import android.graphics.PorterDuff; -import android.graphics.Rect; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.inputmethodservice.Keyboard; -import android.text.TextPaint; -import android.util.Log; -import android.view.ViewConfiguration; -import android.view.inputmethod.EditorInfo; - -import java.util.List; -import java.util.Locale; - -public class LatinKeyboard extends Keyboard { - - private static final boolean DEBUG_PREFERRED_LETTER = false; - private static final String TAG = "LatinKeyboard"; - private static final int OPACITY_FULLY_OPAQUE = 255; - private static final int SPACE_LED_LENGTH_PERCENT = 80; - - private Drawable mShiftLockIcon; - private Drawable mShiftLockPreviewIcon; - private Drawable mOldShiftIcon; - private Drawable mSpaceIcon; - private Drawable mSpaceAutoCompletionIndicator; - private Drawable mSpacePreviewIcon; - private Drawable mMicIcon; - private Drawable mMicPreviewIcon; - private Drawable m123MicIcon; - private Drawable m123MicPreviewIcon; - private final Drawable mButtonArrowLeftIcon; - private final Drawable mButtonArrowRightIcon; - private Key mShiftKey; - private Key mEnterKey; - private Key mF1Key; - private final Drawable mHintIcon; - private Key mSpaceKey; - private Key m123Key; - private final int NUMBER_HINT_COUNT = 10; - private Key[] mNumberHintKeys; - private Drawable[] mNumberHintIcons = new Drawable[NUMBER_HINT_COUNT]; - private final int[] mSpaceKeyIndexArray; - private int mSpaceDragStartX; - private int mSpaceDragLastDiff; - private Locale mLocale; - private LanguageSwitcher mLanguageSwitcher; - private final Resources mRes; - private final Context mContext; - private int mMode; - // Whether this keyboard has voice icon on it - private boolean mHasVoiceButton; - // Whether voice icon is enabled at all - - private final boolean mIsAlphaKeyboard; - private CharSequence m123Label; - private boolean mCurrentlyInSpace; - private SlidingLocaleDrawable mSlidingLocaleIcon; - private int[] mPrefLetterFrequencies; - private int mPrefLetter; - private int mPrefLetterX; - private int mPrefLetterY; - private int mPrefDistance; - - // TODO: generalize for any keyboardId - private boolean mIsBlackSym; - - // TODO: remove this attribute when either Keyboard.mDefaultVerticalGap or Key.parent becomes - // non-private. - private final int mVerticalGap; - - private static final int SHIFT_OFF = 0; - private static final int SHIFT_ON = 1; - private static final int SHIFT_LOCKED = 2; - - private int mShiftState = SHIFT_OFF; - - private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f; - private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f; - private static final float OVERLAP_PERCENTAGE_HIGH_PROB = 0.85f; - // Minimum width of space key preview (proportional to keyboard width) - private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f; - // Height in space key the language name will be drawn. (proportional to space key height) - private static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f; - // If the full language name needs to be smaller than this value to be drawn on space key, - // its short language name will be used instead. - private static final float MINIMUM_SCALE_OF_LANGUAGE_NAME = 0.8f; - - private static int sSpacebarVerticalCorrection; - - public LatinKeyboard(Context context, int xmlLayoutResId) { - this(context, xmlLayoutResId, 0); - } - - public LatinKeyboard(Context context, int xmlLayoutResId, int mode) { - super(context, xmlLayoutResId, mode); - final Resources res = context.getResources(); - mContext = context; - mMode = mode; - mRes = res; - mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked); - mShiftLockPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_shift_locked); - setDefaultBounds(mShiftLockPreviewIcon); - mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space); - mSpaceAutoCompletionIndicator = res.getDrawable(R.drawable.sym_keyboard_space_led); - mSpacePreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_space); - mMicIcon = res.getDrawable(R.drawable.sym_keyboard_mic); - mMicPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_mic); - setDefaultBounds(mMicPreviewIcon); - mButtonArrowLeftIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_left); - mButtonArrowRightIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_right); - m123MicIcon = res.getDrawable(R.drawable.sym_keyboard_123_mic); - m123MicPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_123_mic); - mHintIcon = res.getDrawable(R.drawable.hint_popup); - setDefaultBounds(m123MicPreviewIcon); - sSpacebarVerticalCorrection = res.getDimensionPixelOffset( - R.dimen.spacebar_vertical_correction); - mIsAlphaKeyboard = xmlLayoutResId == R.xml.kbd_qwerty - || xmlLayoutResId == R.xml.kbd_qwerty_black; - // The index of space key is available only after Keyboard constructor has finished. - mSpaceKeyIndexArray = new int[] { indexOf(KP2AKeyboard.KEYCODE_SPACE) }; - initializeNumberHintResources(context); - // TODO remove this initialization after cleanup - mVerticalGap = super.getVerticalGap(); - } - - private void initializeNumberHintResources(Context context) { - final Resources res = context.getResources(); - mNumberHintIcons[0] = res.getDrawable(R.drawable.keyboard_hint_0); - mNumberHintIcons[1] = res.getDrawable(R.drawable.keyboard_hint_1); - mNumberHintIcons[2] = res.getDrawable(R.drawable.keyboard_hint_2); - mNumberHintIcons[3] = res.getDrawable(R.drawable.keyboard_hint_3); - mNumberHintIcons[4] = res.getDrawable(R.drawable.keyboard_hint_4); - mNumberHintIcons[5] = res.getDrawable(R.drawable.keyboard_hint_5); - mNumberHintIcons[6] = res.getDrawable(R.drawable.keyboard_hint_6); - mNumberHintIcons[7] = res.getDrawable(R.drawable.keyboard_hint_7); - mNumberHintIcons[8] = res.getDrawable(R.drawable.keyboard_hint_8); - mNumberHintIcons[9] = res.getDrawable(R.drawable.keyboard_hint_9); - } - - @Override - protected Key createKeyFromXml(Resources res, Row parent, int x, int y, - XmlResourceParser parser) { - Key key = new LatinKey(res, parent, x, y, parser); - switch (key.codes[0]) { - case KP2AKeyboard.KEYCODE_ENTER: - mEnterKey = key; - break; - case LatinKeyboardView.KEYCODE_F1: - mF1Key = key; - break; - case KP2AKeyboard.KEYCODE_SPACE: - mSpaceKey = key; - break; - case KEYCODE_MODE_CHANGE: - m123Key = key; - m123Label = key.label; - break; - } - - // For number hints on the upper-right corner of key - if (mNumberHintKeys == null) { - // NOTE: This protected method is being called from the base class constructor before - // mNumberHintKeys gets initialized. - mNumberHintKeys = new Key[NUMBER_HINT_COUNT]; - } - int hintNumber = -1; - if (LatinKeyboardBaseView.isNumberAtLeftmostPopupChar(key)) { - hintNumber = key.popupCharacters.charAt(0) - '0'; - } else if (LatinKeyboardBaseView.isNumberAtRightmostPopupChar(key)) { - hintNumber = key.popupCharacters.charAt(key.popupCharacters.length() - 1) - '0'; - } - if (hintNumber >= 0 && hintNumber <= 9) { - mNumberHintKeys[hintNumber] = key; - } - - return key; - } - - void setImeOptions(Resources res, int mode, int options) { - mMode = mode; - // TODO should clean up this method - if (mEnterKey != null) { - // Reset some of the rarely used attributes. - mEnterKey.popupCharacters = null; - mEnterKey.popupResId = 0; - mEnterKey.text = null; - switch (options&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) { - case EditorInfo.IME_ACTION_GO: - mEnterKey.iconPreview = null; - mEnterKey.icon = null; - mEnterKey.label = res.getText(R.string.label_go_key); - break; - case EditorInfo.IME_ACTION_NEXT: - mEnterKey.iconPreview = null; - mEnterKey.icon = null; - mEnterKey.label = res.getText(R.string.label_next_key); - break; - case EditorInfo.IME_ACTION_DONE: - mEnterKey.iconPreview = null; - mEnterKey.icon = null; - mEnterKey.label = res.getText(R.string.label_done_key); - break; - case EditorInfo.IME_ACTION_SEARCH: - mEnterKey.iconPreview = res.getDrawable( - R.drawable.sym_keyboard_feedback_search); - mEnterKey.icon = res.getDrawable(mIsBlackSym ? - R.drawable.sym_bkeyboard_search : R.drawable.sym_keyboard_search); - mEnterKey.label = null; - break; - case EditorInfo.IME_ACTION_SEND: - mEnterKey.iconPreview = null; - mEnterKey.icon = null; - mEnterKey.label = res.getText(R.string.label_send_key); - break; - default: - if (mode == KeyboardSwitcher.MODE_IM) { - mEnterKey.icon = mHintIcon; - mEnterKey.iconPreview = null; - mEnterKey.label = ":-)"; - mEnterKey.text = ":-) "; - mEnterKey.popupResId = R.xml.popup_smileys; - } else { - mEnterKey.iconPreview = res.getDrawable( - R.drawable.sym_keyboard_feedback_return); - mEnterKey.icon = res.getDrawable(mIsBlackSym ? - R.drawable.sym_bkeyboard_return : R.drawable.sym_keyboard_return); - mEnterKey.label = null; - } - break; - } - // Set the initial size of the preview icon - if (mEnterKey.iconPreview != null) { - setDefaultBounds(mEnterKey.iconPreview); - } - } - } - - void enableShiftLock() { - int index = getShiftKeyIndex(); - if (index >= 0) { - mShiftKey = getKeys().get(index); - if (mShiftKey instanceof LatinKey) { - ((LatinKey)mShiftKey).enableShiftLock(); - } - mOldShiftIcon = mShiftKey.icon; - } - } - - void setShiftLocked(boolean shiftLocked) { - if (mShiftKey != null) { - if (shiftLocked) { - mShiftKey.on = true; - mShiftKey.icon = mShiftLockIcon; - mShiftState = SHIFT_LOCKED; - } else { - mShiftKey.on = false; - mShiftKey.icon = mShiftLockIcon; - mShiftState = SHIFT_ON; - } - } - } - - boolean isShiftLocked() { - return mShiftState == SHIFT_LOCKED; - } - - @Override - public boolean setShifted(boolean shiftState) { - boolean shiftChanged = false; - if (mShiftKey != null) { - if (shiftState == false) { - shiftChanged = mShiftState != SHIFT_OFF; - mShiftState = SHIFT_OFF; - mShiftKey.on = false; - mShiftKey.icon = mOldShiftIcon; - } else { - if (mShiftState == SHIFT_OFF) { - shiftChanged = mShiftState == SHIFT_OFF; - mShiftState = SHIFT_ON; - mShiftKey.icon = mShiftLockIcon; - } - } - } else { - return super.setShifted(shiftState); - } - return shiftChanged; - } - - @Override - public boolean isShifted() { - if (mShiftKey != null) { - return mShiftState != SHIFT_OFF; - } else { - return super.isShifted(); - } - } - - /* package */ boolean isAlphaKeyboard() { - return mIsAlphaKeyboard; - } - - public void setColorOfSymbolIcons(boolean isAutoCompletion, boolean isBlack) { - mIsBlackSym = isBlack; - if (isBlack) { - mShiftLockIcon = mRes.getDrawable(R.drawable.sym_bkeyboard_shift_locked); - mSpaceIcon = mRes.getDrawable(R.drawable.sym_bkeyboard_space); - mMicIcon = mRes.getDrawable(R.drawable.sym_bkeyboard_mic); - m123MicIcon = mRes.getDrawable(R.drawable.sym_bkeyboard_123_mic); - } else { - mShiftLockIcon = mRes.getDrawable(R.drawable.sym_keyboard_shift_locked); - mSpaceIcon = mRes.getDrawable(R.drawable.sym_keyboard_space); - mMicIcon = mRes.getDrawable(R.drawable.sym_keyboard_mic); - m123MicIcon = mRes.getDrawable(R.drawable.sym_keyboard_123_mic); - } - updateDynamicKeys(); - if (mSpaceKey != null) { - updateSpaceBarForLocale(isAutoCompletion, isBlack); - } - updateNumberHintKeys(); - } - - private void setDefaultBounds(Drawable drawable) { - drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); - } - - - private void updateDynamicKeys() { - update123Key(); - updateF1Key(); - } - - private void update123Key() { - // Update KEYCODE_MODE_CHANGE key only on alphabet mode, not on symbol mode. - if (m123Key != null && mIsAlphaKeyboard) { - - m123Key.icon = null; - m123Key.iconPreview = null; - m123Key.label = m123Label; - - } - } - - private void updateF1Key() { - // Update KEYCODE_F1 key. Please note that some keyboard layouts have no F1 key. - if (mF1Key == null) - return; - - if (mIsAlphaKeyboard) { - if (mMode == KeyboardSwitcher.MODE_URL) { - setNonMicF1Key(mF1Key, "/", R.xml.popup_slash); - } else if (mMode == KeyboardSwitcher.MODE_EMAIL) { - setNonMicF1Key(mF1Key, "@", R.xml.popup_at); - } else { - setNonMicF1Key(mF1Key, ",", R.xml.popup_comma); - - } - } else { // Symbols keyboard - setNonMicF1Key(mF1Key, ",", R.xml.popup_comma); - } - } - private void setNonMicF1Key(Key key, String label, int popupResId) { - key.label = label; - key.codes = new int[] { label.charAt(0) }; - key.popupResId = popupResId; - key.icon = mHintIcon; - key.iconPreview = null; - } - - public boolean isF1Key(Key key) { - return key == mF1Key; - } - - public static boolean hasPuncOrSmileysPopup(Key key) { - return key.popupResId == R.xml.popup_punctuation || key.popupResId == R.xml.popup_smileys; - } - - /** - * @return a key which should be invalidated. - */ - public Key onAutoCompletionStateChanged(boolean isAutoCompletion) { - updateSpaceBarForLocale(isAutoCompletion, mIsBlackSym); - return mSpaceKey; - } - - private void updateNumberHintKeys() { - for (int i = 0; i < mNumberHintKeys.length; ++i) { - if (mNumberHintKeys[i] != null) { - mNumberHintKeys[i].icon = mNumberHintIcons[i]; - } - } - } - - public boolean isLanguageSwitchEnabled() { - return mLocale != null; - } - - private void updateSpaceBarForLocale(boolean isAutoCompletion, boolean isBlack) { - // If application locales are explicitly selected. - try - { - if (mLocale != null) { - mSpaceKey.icon = new BitmapDrawable(mRes, - drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion, isBlack)); - } else { - // sym_keyboard_space_led can be shared with Black and White symbol themes. - if (isAutoCompletion) { - mSpaceKey.icon = new BitmapDrawable(mRes, - drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion, isBlack)); - } else { - mSpaceKey.icon = isBlack ? mRes.getDrawable(R.drawable.sym_bkeyboard_space) - : mRes.getDrawable(R.drawable.sym_keyboard_space); - } - } - } - catch (NullPointerException e) - { - //this exception was reported through Google Play. I need further info to resolve. - android.util.Log.e("KP2A", "Please report this error to crocoapps@gmail.com"); - android.util.Log.e("KP2A", e.toString()); - android.util.Log.e("KP2A", ((mSpaceKey==null) ? "1" : "0") - + ((mRes==null) ? "1" : "0")); - } - - } - - // Compute width of text with specified text size using paint. - private static int getTextWidth(Paint paint, String text, float textSize, Rect bounds) { - paint.setTextSize(textSize); - paint.getTextBounds(text, 0, text.length(), bounds); - return bounds.width(); - } - - // Overlay two images: mainIcon and hintIcon. - private Bitmap drawSynthesizedSettingsHintImage( - int width, int height, Drawable mainIcon, Drawable hintIcon) { - if (mainIcon == null || hintIcon == null) - return null; - Rect hintIconPadding = new Rect(0, 0, 0, 0); - hintIcon.getPadding(hintIconPadding); - final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(buffer); - canvas.drawColor(mRes.getColor(R.color.latinkeyboard_transparent), PorterDuff.Mode.CLEAR); - - // Draw main icon at the center of the key visual - // Assuming the hintIcon shares the same padding with the key's background drawable - final int drawableX = (width + hintIconPadding.left - hintIconPadding.right - - mainIcon.getIntrinsicWidth()) / 2; - final int drawableY = (height + hintIconPadding.top - hintIconPadding.bottom - - mainIcon.getIntrinsicHeight()) / 2; - setDefaultBounds(mainIcon); - canvas.translate(drawableX, drawableY); - mainIcon.draw(canvas); - canvas.translate(-drawableX, -drawableY); - - // Draw hint icon fully in the key - hintIcon.setBounds(0, 0, width, height); - hintIcon.draw(canvas); - return buffer; - } - - // Layout local language name and left and right arrow on space bar. - private static String layoutSpaceBar(Paint paint, Locale locale, Drawable lArrow, - Drawable rArrow, int width, int height, float origTextSize, - boolean allowVariableTextSize) { - final float arrowWidth = lArrow.getIntrinsicWidth(); - final float arrowHeight = lArrow.getIntrinsicHeight(); - final float maxTextWidth = width - (arrowWidth + arrowWidth); - final Rect bounds = new Rect(); - - // Estimate appropriate language name text size to fit in maxTextWidth. - String language = LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale), locale); - int textWidth = getTextWidth(paint, language, origTextSize, bounds); - // Assuming text width and text size are proportional to each other. - float textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f); - - final boolean useShortName; - if (allowVariableTextSize) { - textWidth = getTextWidth(paint, language, textSize, bounds); - // If text size goes too small or text does not fit, use short name - useShortName = textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME - || textWidth > maxTextWidth; - } else { - useShortName = textWidth > maxTextWidth; - textSize = origTextSize; - } - if (useShortName) { - language = LanguageSwitcher.toTitleCase(locale.getLanguage(), locale); - textWidth = getTextWidth(paint, language, origTextSize, bounds); - textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f); - } - paint.setTextSize(textSize); - - // Place left and right arrow just before and after language text. - final float baseline = height * SPACEBAR_LANGUAGE_BASELINE; - final int top = (int)(baseline - arrowHeight); - final float remains = (width - textWidth) / 2; - lArrow.setBounds((int)(remains - arrowWidth), top, (int)remains, (int)baseline); - rArrow.setBounds((int)(remains + textWidth), top, (int)(remains + textWidth + arrowWidth), - (int)baseline); - - return language; - } - - private Bitmap drawSpaceBar(int opacity, boolean isAutoCompletion, boolean isBlack) { - final int width = mSpaceKey.width; - final int height = mSpaceIcon.getIntrinsicHeight(); - final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(buffer); - canvas.drawColor(mRes.getColor(R.color.latinkeyboard_transparent), PorterDuff.Mode.CLEAR); - - // If application locales are explicitly selected. - if (mLocale != null) { - final Paint paint = new Paint(); - paint.setAlpha(opacity); - paint.setAntiAlias(true); - paint.setTextAlign(Align.CENTER); - - final boolean allowVariableTextSize = true; - final String language = layoutSpaceBar(paint, mLanguageSwitcher.getInputLocale(), - mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height, - getTextSizeFromTheme(android.R.style.TextAppearance_Small, 14), - allowVariableTextSize); - - // Draw language text with shadow - final int shadowColor = mRes.getColor(isBlack - ? R.color.latinkeyboard_bar_language_shadow_black - : R.color.latinkeyboard_bar_language_shadow_white); - final float baseline = height * SPACEBAR_LANGUAGE_BASELINE; - final float descent = paint.descent(); - paint.setColor(shadowColor); - canvas.drawText(language, width / 2, baseline - descent - 1, paint); - paint.setColor(mRes.getColor(R.color.latinkeyboard_bar_language_text)); - canvas.drawText(language, width / 2, baseline - descent, paint); - - // Put arrows that are already layed out on either side of the text - if (mLanguageSwitcher.getLocaleCount() > 1) { - mButtonArrowLeftIcon.draw(canvas); - mButtonArrowRightIcon.draw(canvas); - } - } - - // Draw the spacebar icon at the bottom - if (isAutoCompletion) { - final int iconWidth = width * SPACE_LED_LENGTH_PERCENT / 100; - final int iconHeight = mSpaceAutoCompletionIndicator.getIntrinsicHeight(); - int x = (width - iconWidth) / 2; - int y = height - iconHeight; - mSpaceAutoCompletionIndicator.setBounds(x, y, x + iconWidth, y + iconHeight); - mSpaceAutoCompletionIndicator.draw(canvas); - } else { - final int iconWidth = mSpaceIcon.getIntrinsicWidth(); - final int iconHeight = mSpaceIcon.getIntrinsicHeight(); - int x = (width - iconWidth) / 2; - int y = height - iconHeight; - mSpaceIcon.setBounds(x, y, x + iconWidth, y + iconHeight); - mSpaceIcon.draw(canvas); - } - return buffer; - } - - private void updateLocaleDrag(int diff) { - if (mSlidingLocaleIcon == null) { - final int width = Math.max(mSpaceKey.width, - (int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO)); - final int height = mSpacePreviewIcon.getIntrinsicHeight(); - mSlidingLocaleIcon = new SlidingLocaleDrawable(mSpacePreviewIcon, width, height); - mSlidingLocaleIcon.setBounds(0, 0, width, height); - mSpaceKey.iconPreview = mSlidingLocaleIcon; - } - mSlidingLocaleIcon.setDiff(diff); - if (Math.abs(diff) == Integer.MAX_VALUE) { - mSpaceKey.iconPreview = mSpacePreviewIcon; - } else { - mSpaceKey.iconPreview = mSlidingLocaleIcon; - } - mSpaceKey.iconPreview.invalidateSelf(); - } - - public int getLanguageChangeDirection() { - if (mSpaceKey == null || mLanguageSwitcher.getLocaleCount() < 2 - || Math.abs(mSpaceDragLastDiff) < mSpaceKey.width * SPACEBAR_DRAG_THRESHOLD ) { - return 0; // No change - } - return mSpaceDragLastDiff > 0 ? 1 : -1; - } - - public void setLanguageSwitcher(LanguageSwitcher switcher, boolean isAutoCompletion, - boolean isBlackSym) { - mLanguageSwitcher = switcher; - Locale locale = mLanguageSwitcher.getLocaleCount() > 0 - ? mLanguageSwitcher.getInputLocale() - : null; - // If the language count is 1 and is the same as the system language, don't show it. - if (locale != null - && mLanguageSwitcher.getLocaleCount() == 1 - && mLanguageSwitcher.getSystemLocale().getLanguage() - .equalsIgnoreCase(locale.getLanguage())) { - locale = null; - } - mLocale = locale; - setColorOfSymbolIcons(isAutoCompletion, isBlackSym); - } - - public Locale getInputLocale() { - return (mLocale != null) ? mLocale : mLanguageSwitcher.getSystemLocale(); - } - - boolean isCurrentlyInSpace() { - return mCurrentlyInSpace; - } - - void setPreferredLetters(int[] frequencies) { - mPrefLetterFrequencies = frequencies; - mPrefLetter = 0; - } - - void keyReleased() { - mCurrentlyInSpace = false; - mSpaceDragLastDiff = 0; - mPrefLetter = 0; - mPrefLetterX = 0; - mPrefLetterY = 0; - mPrefDistance = Integer.MAX_VALUE; - if (mSpaceKey != null) { - updateLocaleDrag(Integer.MAX_VALUE); - } - } - - /** - * Does the magic of locking the touch gesture into the spacebar when - * switching input languages. - */ - boolean isInside(LatinKey key, int x, int y) { - final int code = key.codes[0]; - if (code == KEYCODE_SHIFT || - code == KEYCODE_DELETE) { - y -= key.height / 10; - if (code == KEYCODE_SHIFT) x += key.width / 6; - if (code == KEYCODE_DELETE) x -= key.width / 6; - } else if (code == KP2AKeyboard.KEYCODE_SPACE) { - y += LatinKeyboard.sSpacebarVerticalCorrection; - if (mLanguageSwitcher.getLocaleCount() > 1) { - if (mCurrentlyInSpace) { - int diff = x - mSpaceDragStartX; - if (Math.abs(diff - mSpaceDragLastDiff) > 0) { - updateLocaleDrag(diff); - } - mSpaceDragLastDiff = diff; - return true; - } else { - boolean insideSpace = key.isInsideSuper(x, y); - if (insideSpace) { - mCurrentlyInSpace = true; - mSpaceDragStartX = x; - updateLocaleDrag(0); - } - return insideSpace; - } - } - } else if (mPrefLetterFrequencies != null) { - // New coordinate? Reset - if (mPrefLetterX != x || mPrefLetterY != y) { - mPrefLetter = 0; - mPrefDistance = Integer.MAX_VALUE; - } - // Handle preferred next letter - final int[] pref = mPrefLetterFrequencies; - if (mPrefLetter > 0) { - if (DEBUG_PREFERRED_LETTER) { - if (mPrefLetter == code && !key.isInsideSuper(x, y)) { - Log.d(TAG, "CORRECTED !!!!!!"); - } - } - return mPrefLetter == code; - } else { - final boolean inside = key.isInsideSuper(x, y); - int[] nearby = getNearestKeys(x, y); - List nearbyKeys = getKeys(); - if (inside) { - // If it's a preferred letter - if (inPrefList(code, pref)) { - // Check if its frequency is much lower than a nearby key - mPrefLetter = code; - mPrefLetterX = x; - mPrefLetterY = y; - for (int i = 0; i < nearby.length; i++) { - Key k = nearbyKeys.get(nearby[i]); - if (k != key && inPrefList(k.codes[0], pref)) { - final int dist = distanceFrom(k, x, y); - if (dist < (int) (k.width * OVERLAP_PERCENTAGE_LOW_PROB) && - (pref[k.codes[0]] > pref[mPrefLetter] * 3)) { - mPrefLetter = k.codes[0]; - mPrefDistance = dist; - if (DEBUG_PREFERRED_LETTER) { - Log.d(TAG, "CORRECTED ALTHOUGH PREFERRED !!!!!!"); - } - break; - } - } - } - - return mPrefLetter == code; - } - } - - // Get the surrounding keys and intersect with the preferred list - // For all in the intersection - // if distance from touch point is within a reasonable distance - // make this the pref letter - // If no pref letter - // return inside; - // else return thiskey == prefletter; - - for (int i = 0; i < nearby.length; i++) { - Key k = nearbyKeys.get(nearby[i]); - if (inPrefList(k.codes[0], pref)) { - final int dist = distanceFrom(k, x, y); - if (dist < (int) (k.width * OVERLAP_PERCENTAGE_HIGH_PROB) - && dist < mPrefDistance) { - mPrefLetter = k.codes[0]; - mPrefLetterX = x; - mPrefLetterY = y; - mPrefDistance = dist; - } - } - } - // Didn't find any - if (mPrefLetter == 0) { - return inside; - } else { - return mPrefLetter == code; - } - } - } - - // Lock into the spacebar - if (mCurrentlyInSpace) return false; - - return key.isInsideSuper(x, y); - } - - private boolean inPrefList(int code, int[] pref) { - if (code < pref.length && code >= 0) return pref[code] > 0; - return false; - } - - private int distanceFrom(Key k, int x, int y) { - if (y > k.y && y < k.y + k.height) { - return Math.abs(k.x + k.width / 2 - x); - } else { - return Integer.MAX_VALUE; - } - } - - @Override - public int[] getNearestKeys(int x, int y) { - if (mCurrentlyInSpace) { - return mSpaceKeyIndexArray; - } else { - // Avoid dead pixels at edges of the keyboard - return super.getNearestKeys(Math.max(0, Math.min(x, getMinWidth() - 1)), - Math.max(0, Math.min(y, getHeight() - 1))); - } - } - - private int indexOf(int code) { - List keys = getKeys(); - int count = keys.size(); - for (int i = 0; i < count; i++) { - if (keys.get(i).codes[0] == code) return i; - } - return -1; - } - - private int getTextSizeFromTheme(int style, int defValue) { - TypedArray array = mContext.getTheme().obtainStyledAttributes( - style, new int[] { android.R.attr.textSize }); - int textSize = array.getDimensionPixelSize(array.getResourceId(0, 0), defValue); - return textSize; - } - - // TODO LatinKey could be static class - class LatinKey extends Keyboard.Key { - - // functional normal state (with properties) - private final int[] KEY_STATE_FUNCTIONAL_NORMAL = { - android.R.attr.state_single - }; - - // functional pressed state (with properties) - private final int[] KEY_STATE_FUNCTIONAL_PRESSED = { - android.R.attr.state_single, - android.R.attr.state_pressed - }; - - private boolean mShiftLockEnabled; - - public LatinKey(Resources res, Keyboard.Row parent, int x, int y, - XmlResourceParser parser) { - super(res, parent, x, y, parser); - if (popupCharacters != null && popupCharacters.length() == 0) { - // If there is a keyboard with no keys specified in popupCharacters - popupResId = 0; - } - } - - private void enableShiftLock() { - mShiftLockEnabled = true; - } - - // sticky is used for shift key. If a key is not sticky and is modifier, - // the key will be treated as functional. - private boolean isFunctionalKey() { - return !sticky && modifier; - } - - @Override - public void onReleased(boolean inside) { - if (!mShiftLockEnabled) { - super.onReleased(inside); - } else { - pressed = !pressed; - } - } - - /** - * Overriding this method so that we can reduce the target area for certain keys. - */ - @Override - public boolean isInside(int x, int y) { - // TODO This should be done by parent.isInside(this, x, y) - // if Key.parent were protected. - boolean result = LatinKeyboard.this.isInside(this, x, y); - return result; - } - - boolean isInsideSuper(int x, int y) { - return super.isInside(x, y); - } - - @Override - public int[] getCurrentDrawableState() { - if (isFunctionalKey()) { - if (pressed) { - return KEY_STATE_FUNCTIONAL_PRESSED; - } else { - return KEY_STATE_FUNCTIONAL_NORMAL; - } - } - return super.getCurrentDrawableState(); - } - - @Override - public int squaredDistanceFrom(int x, int y) { - // We should count vertical gap between rows to calculate the center of this Key. - final int verticalGap = LatinKeyboard.this.mVerticalGap; - final int xDist = this.x + width / 2 - x; - final int yDist = this.y + (height + verticalGap) / 2 - y; - return xDist * xDist + yDist * yDist; - } - } - - /** - * Animation to be displayed on the spacebar preview popup when switching - * languages by swiping the spacebar. It draws the current, previous and - * next languages and moves them by the delta of touch movement on the spacebar. - */ - class SlidingLocaleDrawable extends Drawable { - - private final int mWidth; - private final int mHeight; - private final Drawable mBackground; - private final TextPaint mTextPaint; - private final int mMiddleX; - private final Drawable mLeftDrawable; - private final Drawable mRightDrawable; - private final int mThreshold; - private int mDiff; - private boolean mHitThreshold; - private String mCurrentLanguage; - private String mNextLanguage; - private String mPrevLanguage; - - @SuppressLint("ResourceAsColor") - public SlidingLocaleDrawable(Drawable background, int width, int height) { - mBackground = background; - setDefaultBounds(mBackground); - mWidth = width; - mHeight = height; - mTextPaint = new TextPaint(); - mTextPaint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18)); - - mTextPaint.setColor(R.color.latinkeyboard_transparent); - mTextPaint.setTextAlign(Align.CENTER); - mTextPaint.setAlpha(OPACITY_FULLY_OPAQUE); - mTextPaint.setAntiAlias(true); - mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2; - mLeftDrawable = - mRes.getDrawable(R.drawable.sym_keyboard_feedback_language_arrows_left); - mRightDrawable = - mRes.getDrawable(R.drawable.sym_keyboard_feedback_language_arrows_right); - mThreshold = ViewConfiguration.get(mContext).getScaledTouchSlop(); - } - - private void setDiff(int diff) { - if (diff == Integer.MAX_VALUE) { - mHitThreshold = false; - mCurrentLanguage = null; - return; - } - mDiff = diff; - if (mDiff > mWidth) mDiff = mWidth; - if (mDiff < -mWidth) mDiff = -mWidth; - if (Math.abs(mDiff) > mThreshold) mHitThreshold = true; - invalidateSelf(); - } - - private String getLanguageName(Locale locale) { - return LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale), locale); - } - - @Override - public void draw(Canvas canvas) { - canvas.save(); - if (mHitThreshold) { - Paint paint = mTextPaint; - final int width = mWidth; - final int height = mHeight; - final int diff = mDiff; - final Drawable lArrow = mLeftDrawable; - final Drawable rArrow = mRightDrawable; - canvas.clipRect(0, 0, width, height); - if (mCurrentLanguage == null) { - final LanguageSwitcher languageSwitcher = mLanguageSwitcher; - mCurrentLanguage = getLanguageName(languageSwitcher.getInputLocale()); - mNextLanguage = getLanguageName(languageSwitcher.getNextInputLocale()); - mPrevLanguage = getLanguageName(languageSwitcher.getPrevInputLocale()); - } - // Draw language text with shadow - final float baseline = mHeight * SPACEBAR_LANGUAGE_BASELINE - paint.descent(); - paint.setColor(mRes.getColor(R.color.latinkeyboard_feedback_language_text)); - canvas.drawText(mCurrentLanguage, width / 2 + diff, baseline, paint); - canvas.drawText(mNextLanguage, diff - width / 2, baseline, paint); - canvas.drawText(mPrevLanguage, diff + width + width / 2, baseline, paint); - - setDefaultBounds(lArrow); - rArrow.setBounds(width - rArrow.getIntrinsicWidth(), 0, width, - rArrow.getIntrinsicHeight()); - lArrow.draw(canvas); - rArrow.draw(canvas); - } - if (mBackground != null) { - canvas.translate(mMiddleX, 0); - mBackground.draw(canvas); - } - canvas.restore(); - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - - @Override - public void setAlpha(int alpha) { - // Ignore - } - - @Override - public void setColorFilter(ColorFilter cf) { - // Ignore - } - - @Override - public int getIntrinsicWidth() { - return mWidth; - } - - @Override - public int getIntrinsicHeight() { - return mHeight; - } - } -} diff --git a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinKeyboardBaseView.java b/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinKeyboardBaseView.java deleted file mode 100644 index 0761aae2..00000000 --- a/src/java/KP2ASoftKeyboard2/java/src/keepass2android/softkeyboard/LatinKeyboardBaseView.java +++ /dev/null @@ -1,1517 +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.Context; -import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Align; -import android.graphics.PorterDuff; -import android.graphics.Rect; -import android.graphics.Region.Op; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.inputmethodservice.Keyboard; -import android.inputmethodservice.Keyboard.Key; -import android.os.Handler; -import android.os.Message; -import android.os.SystemClock; -import android.util.AttributeSet; -import android.util.Log; -import android.util.TypedValue; -import android.view.GestureDetector; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.widget.PopupWindow; -import android.widget.TextView; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.WeakHashMap; - -/** - * A view that renders a virtual {@link LatinKeyboard}. It handles rendering of keys and - * detecting key presses and touch movements. - * - * TODO: References to LatinKeyboard in this class should be replaced with ones to its base class. - * - * @attr ref R.styleable#LatinKeyboardBaseView_keyBackground - * @attr ref R.styleable#LatinKeyboardBaseView_keyPreviewLayout - * @attr ref R.styleable#LatinKeyboardBaseView_keyPreviewOffset - * @attr ref R.styleable#LatinKeyboardBaseView_labelTextSize - * @attr ref R.styleable#LatinKeyboardBaseView_keyTextSize - * @attr ref R.styleable#LatinKeyboardBaseView_keyTextColor - * @attr ref R.styleable#LatinKeyboardBaseView_verticalCorrection - * @attr ref R.styleable#LatinKeyboardBaseView_popupLayout - */ -public class LatinKeyboardBaseView extends View implements PointerTracker.UIProxy { - private static final String TAG = "LatinKeyboardBaseView"; - private static final boolean DEBUG = false; - - public static final int NOT_A_TOUCH_COORDINATE = -1; - - public interface OnKeyboardActionListener { - - /** - * Called when the user presses a key. This is sent before the - * {@link #onKey} is called. For keys that repeat, this is only - * called once. - * - * @param primaryCode - * the unicode of the key being pressed. If the touch is - * not on a valid key, the value will be zero. - */ - void onPress(int primaryCode); - - /** - * Called when the user releases a key. This is sent after the - * {@link #onKey} is called. For keys that repeat, this is only - * called once. - * - * @param primaryCode - * the code of the key that was released - */ - void onRelease(int primaryCode); - - /** - * Send a key press to the listener. - * - * @param primaryCode - * this is the key that was pressed - * @param keyCodes - * the codes for all the possible alternative keys with - * the primary code being the first. If the primary key - * code is a single character such as an alphabet or - * number or symbol, the alternatives will include other - * characters that may be on the same key or adjacent - * keys. These codes are useful to correct for - * accidental presses of a key adjacent to the intended - * key. - * @param x - * x-coordinate pixel of touched event. If onKey is not called by onTouchEvent, - * the value should be NOT_A_TOUCH_COORDINATE. - * @param y - * y-coordinate pixel of touched event. If onKey is not called by onTouchEvent, - * the value should be NOT_A_TOUCH_COORDINATE. - */ - void onKey(int primaryCode, int[] keyCodes, int x, int y); - - /** - * Sends a sequence of characters to the listener. - * - * @param text - * the sequence of characters to be displayed. - */ - void onText(CharSequence text); - - /** - * Called when user released a finger outside any key. - */ - void onCancel(); - - /** - * Called when the user quickly moves the finger from right to - * left. - */ - void swipeLeft(); - - /** - * Called when the user quickly moves the finger from left to - * right. - */ - void swipeRight(); - - /** - * Called when the user quickly moves the finger from up to down. - */ - void swipeDown(); - - /** - * Called when the user quickly moves the finger from down to up. - */ - void swipeUp(); - } - - // Timing constants - private final int mKeyRepeatInterval; - - // Miscellaneous constants - /* package */ static final int NOT_A_KEY = -1; - private static final int[] LONG_PRESSABLE_STATE_SET = { android.R.attr.state_long_pressable }; - private static final int NUMBER_HINT_VERTICAL_ADJUSTMENT_PIXEL = -1; - - // XML attribute - private int mKeyTextSize; - private int mKeyTextColor; - private Typeface mKeyTextStyle = Typeface.DEFAULT; - private int mLabelTextSize; - private int mSymbolColorScheme = 0; - private int mShadowColor; - private float mShadowRadius; - private Drawable mKeyBackground; - private float mBackgroundDimAmount; - private float mKeyHysteresisDistance; - private float mVerticalCorrection; - private int mPreviewOffset; - private int mPreviewHeight; - private int mPopupLayout; - - // Main keyboard - private Keyboard mKeyboard; - private Key[] mKeys; - // TODO this attribute should be gotten from Keyboard. - private int mKeyboardVerticalGap; - - // Key preview popup - private TextView mPreviewText; - private PopupWindow mPreviewPopup; - private int mPreviewTextSizeLarge; - private int[] mOffsetInWindow; - private int mOldPreviewKeyIndex = NOT_A_KEY; - private boolean mShowPreview = true; - private boolean mShowTouchPoints = true; - private int mPopupPreviewOffsetX; - private int mPopupPreviewOffsetY; - private int mWindowY; - private int mPopupPreviewDisplayedY; - private final int mDelayBeforePreview; - private final int mDelayAfterPreview; - - // Popup mini keyboard - private PopupWindow mMiniKeyboardPopup; - private LatinKeyboardBaseView mMiniKeyboard; - private View mMiniKeyboardParent; - private final WeakHashMap mMiniKeyboardCache = new WeakHashMap(); - private int mMiniKeyboardOriginX; - private int mMiniKeyboardOriginY; - private long mMiniKeyboardPopupTime; - private int[] mWindowOffset; - private final float mMiniKeyboardSlideAllowance; - private int mMiniKeyboardTrackerId; - - /** Listener for {@link OnKeyboardActionListener}. */ - private OnKeyboardActionListener mKeyboardActionListener; - - private final ArrayList mPointerTrackers = new ArrayList(); - - // TODO: Let the PointerTracker class manage this pointer queue - private final PointerQueue mPointerQueue = new PointerQueue(); - - private final boolean mHasDistinctMultitouch; - private int mOldPointerCount = 1; - - protected KeyDetector mKeyDetector = new ProximityKeyDetector(); - - // Swipe gesture detector - private GestureDetector mGestureDetector; - private final SwipeTracker mSwipeTracker = new SwipeTracker(); - private final int mSwipeThreshold; - private final boolean mDisambiguateSwipe; - - // Drawing - /** Whether the keyboard bitmap needs to be redrawn before it's blitted. **/ - private boolean mDrawPending; - /** The dirty region in the keyboard bitmap */ - private final Rect mDirtyRect = new Rect(); - /** The keyboard bitmap for faster updates */ - private Bitmap mBuffer; - /** Notes if the keyboard just changed, so that we could possibly reallocate the mBuffer. */ - private boolean mKeyboardChanged; - private Key mInvalidatedKey; - /** The canvas for the above mutable keyboard bitmap */ - private Canvas mCanvas; - private final Paint mPaint; - private final Rect mPadding; - private final Rect mClipRegion = new Rect(0, 0, 0, 0); - // This map caches key label text height in pixel as value and key label text size as map key. - private final HashMap mTextHeightCache = new HashMap(); - // Distance from horizontal center of the key, proportional to key label text height. - private final float KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR = 0.55f; - private final String KEY_LABEL_HEIGHT_REFERENCE_CHAR = "H"; - - private final UIHandler mHandler = new UIHandler(); - - class UIHandler extends Handler { - private static final int MSG_POPUP_PREVIEW = 1; - private static final int MSG_DISMISS_PREVIEW = 2; - private static final int MSG_REPEAT_KEY = 3; - private static final int MSG_LONGPRESS_KEY = 4; - - private boolean mInKeyRepeat; - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_POPUP_PREVIEW: - showKey(msg.arg1, (PointerTracker)msg.obj); - break; - case MSG_DISMISS_PREVIEW: - mPreviewPopup.dismiss(); - break; - case MSG_REPEAT_KEY: { - final PointerTracker tracker = (PointerTracker)msg.obj; - tracker.repeatKey(msg.arg1); - startKeyRepeatTimer(mKeyRepeatInterval, msg.arg1, tracker); - break; - } - case MSG_LONGPRESS_KEY: { - final PointerTracker tracker = (PointerTracker)msg.obj; - openPopupIfRequired(msg.arg1, tracker); - break; - } - } - } - - public void popupPreview(long delay, int keyIndex, PointerTracker tracker) { - removeMessages(MSG_POPUP_PREVIEW); - if (mPreviewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) { - // Show right away, if it's already visible and finger is moving around - showKey(keyIndex, tracker); - } else { - sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker), - delay); - } - } - - public void cancelPopupPreview() { - removeMessages(MSG_POPUP_PREVIEW); - } - - public void dismissPreview(long delay) { - if (mPreviewPopup.isShowing()) { - sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay); - } - } - - public void cancelDismissPreview() { - removeMessages(MSG_DISMISS_PREVIEW); - } - - public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) { - mInKeyRepeat = true; - sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, keyIndex, 0, tracker), delay); - } - - public void cancelKeyRepeatTimer() { - mInKeyRepeat = false; - removeMessages(MSG_REPEAT_KEY); - } - - public boolean isInKeyRepeat() { - return mInKeyRepeat; - } - - public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) { - removeMessages(MSG_LONGPRESS_KEY); - sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, keyIndex, 0, tracker), delay); - } - - public void cancelLongPressTimer() { - removeMessages(MSG_LONGPRESS_KEY); - } - - public void cancelKeyTimers() { - cancelKeyRepeatTimer(); - cancelLongPressTimer(); - } - - public void cancelAllMessages() { - cancelKeyTimers(); - cancelPopupPreview(); - cancelDismissPreview(); - } - } - - static class PointerQueue { - private LinkedList mQueue = new LinkedList(); - - public void add(PointerTracker tracker) { - mQueue.add(tracker); - } - - public int lastIndexOf(PointerTracker tracker) { - LinkedList queue = mQueue; - for (int index = queue.size() - 1; index >= 0; index--) { - PointerTracker t = queue.get(index); - if (t == tracker) - return index; - } - return -1; - } - - public void releaseAllPointersOlderThan(PointerTracker tracker, long eventTime) { - LinkedList queue = mQueue; - int oldestPos = 0; - for (PointerTracker t = queue.get(oldestPos); t != tracker; t = queue.get(oldestPos)) { - if (t.isModifier()) { - oldestPos++; - } else { - t.onUpEvent(t.getLastX(), t.getLastY(), eventTime); - t.setAlreadyProcessed(); - queue.remove(oldestPos); - } - } - } - - public void releaseAllPointersExcept(PointerTracker tracker, long eventTime) { - for (PointerTracker t : mQueue) { - if (t == tracker) - continue; - t.onUpEvent(t.getLastX(), t.getLastY(), eventTime); - t.setAlreadyProcessed(); - } - mQueue.clear(); - if (tracker != null) - mQueue.add(tracker); - } - - public void remove(PointerTracker tracker) { - mQueue.remove(tracker); - } - - public boolean isInSlidingKeyInput() { - for (final PointerTracker tracker : mQueue) { - if (tracker.isInSlidingKeyInput()) - return true; - } - return false; - } - } - - public LatinKeyboardBaseView(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.keyboardViewStyle); - } - - public LatinKeyboardBaseView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - TypedArray a = context.obtainStyledAttributes( - attrs, R.styleable.LatinKeyboardBaseView, defStyle, R.style.LatinKeyboardBaseView); - LayoutInflater inflate = - (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - int previewLayout = 0; - int keyTextSize = 0; - - int n = a.getIndexCount(); - - for (int i = 0; i < n; i++) { - int attr = a.getIndex(i); - - switch (attr) { - case R.styleable.LatinKeyboardBaseView_keyBackground: - mKeyBackground = a.getDrawable(attr); - break; - case R.styleable.LatinKeyboardBaseView_keyHysteresisDistance: - mKeyHysteresisDistance = a.getDimensionPixelOffset(attr, 0); - break; - case R.styleable.LatinKeyboardBaseView_verticalCorrection: - mVerticalCorrection = a.getDimensionPixelOffset(attr, 0); - break; - case R.styleable.LatinKeyboardBaseView_keyPreviewLayout: - previewLayout = a.getResourceId(attr, 0); - break; - case R.styleable.LatinKeyboardBaseView_keyPreviewOffset: - mPreviewOffset = a.getDimensionPixelOffset(attr, 0); - break; - case R.styleable.LatinKeyboardBaseView_keyPreviewHeight: - mPreviewHeight = a.getDimensionPixelSize(attr, 80); - break; - case R.styleable.LatinKeyboardBaseView_keyTextSize: - mKeyTextSize = a.getDimensionPixelSize(attr, 18); - break; - case R.styleable.LatinKeyboardBaseView_keyTextColor: - mKeyTextColor = a.getColor(attr, 0xFF000000); - break; - case R.styleable.LatinKeyboardBaseView_labelTextSize: - mLabelTextSize = a.getDimensionPixelSize(attr, 14); - break; - case R.styleable.LatinKeyboardBaseView_popupLayout: - mPopupLayout = a.getResourceId(attr, 0); - break; - case R.styleable.LatinKeyboardBaseView_shadowColor: - mShadowColor = a.getColor(attr, 0); - break; - case R.styleable.LatinKeyboardBaseView_shadowRadius: - mShadowRadius = a.getFloat(attr, 0f); - break; - // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount) - case R.styleable.LatinKeyboardBaseView_backgroundDimAmount: - mBackgroundDimAmount = a.getFloat(attr, 0.5f); - break; - //case android.R.styleable. - case R.styleable.LatinKeyboardBaseView_keyTextStyle: - int textStyle = a.getInt(attr, 0); - switch (textStyle) { - case 0: - mKeyTextStyle = Typeface.DEFAULT; - break; - case 1: - mKeyTextStyle = Typeface.DEFAULT_BOLD; - break; - default: - mKeyTextStyle = Typeface.defaultFromStyle(textStyle); - break; - } - break; - case R.styleable.LatinKeyboardBaseView_symbolColorScheme: - mSymbolColorScheme = a.getInt(attr, 0); - break; - } - } - - final Resources res = getResources(); - - mPreviewPopup = new PopupWindow(context); - if (previewLayout != 0) { - mPreviewText = (TextView) inflate.inflate(previewLayout, null); - mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large); - mPreviewPopup.setContentView(mPreviewText); - mPreviewPopup.setBackgroundDrawable(null); - } else { - mShowPreview = false; - } - mPreviewPopup.setTouchable(false); - mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation); - mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview); - mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview); - - mMiniKeyboardParent = this; - mMiniKeyboardPopup = new PopupWindow(context); - mMiniKeyboardPopup.setBackgroundDrawable(null); - mMiniKeyboardPopup.setAnimationStyle(R.style.MiniKeyboardAnimation); - - mPaint = new Paint(); - mPaint.setAntiAlias(true); - mPaint.setTextSize(keyTextSize); - mPaint.setTextAlign(Align.CENTER); - mPaint.setAlpha(255); - - mPadding = new Rect(0, 0, 0, 0); - mKeyBackground.getPadding(mPadding); - - mSwipeThreshold = (int) (500 * res.getDisplayMetrics().density); - // TODO: Refer frameworks/base/core/res/res/values/config.xml - mDisambiguateSwipe = res.getBoolean(R.bool.config_swipeDisambiguation); - mMiniKeyboardSlideAllowance = res.getDimension(R.dimen.mini_keyboard_slide_allowance); - - GestureDetector.SimpleOnGestureListener listener = - new GestureDetector.SimpleOnGestureListener() { - @Override - public boolean onFling(MotionEvent me1, MotionEvent me2, float velocityX, - float velocityY) { - final float absX = Math.abs(velocityX); - final float absY = Math.abs(velocityY); - float deltaX = me2.getX() - me1.getX(); - float deltaY = me2.getY() - me1.getY(); - int travelX = getWidth() / 2; // Half the keyboard width - int travelY = getHeight() / 2; // Half the keyboard height - mSwipeTracker.computeCurrentVelocity(1000); - final float endingVelocityX = mSwipeTracker.getXVelocity(); - final float endingVelocityY = mSwipeTracker.getYVelocity(); - if (velocityX > mSwipeThreshold && absY < absX && deltaX > travelX) { - if (mDisambiguateSwipe && endingVelocityX >= velocityX / 4) { - swipeRight(); - return true; - } - } else if (velocityX < -mSwipeThreshold && absY < absX && deltaX < -travelX) { - if (mDisambiguateSwipe && endingVelocityX <= velocityX / 4) { - swipeLeft(); - return true; - } - } else if (velocityY < -mSwipeThreshold && absX < absY && deltaY < -travelY) { - if (mDisambiguateSwipe && endingVelocityY <= velocityY / 4) { - swipeUp(); - return true; - } - } else if (velocityY > mSwipeThreshold && absX < absY / 2 && deltaY > travelY) { - if (mDisambiguateSwipe && endingVelocityY >= velocityY / 4) { - swipeDown(); - return true; - } - } - return false; - } - }; - - final boolean ignoreMultitouch = true; - mGestureDetector = new GestureDetector(getContext(), listener, null, ignoreMultitouch); - mGestureDetector.setIsLongpressEnabled(false); - - mHasDistinctMultitouch = context.getPackageManager() - .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT); - mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval); - } - - public void setOnKeyboardActionListener(OnKeyboardActionListener listener) { - mKeyboardActionListener = listener; - for (PointerTracker tracker : mPointerTrackers) { - tracker.setOnKeyboardActionListener(listener); - } - } - - /** - * Returns the {@link OnKeyboardActionListener} object. - * @return the listener attached to this keyboard - */ - protected OnKeyboardActionListener getOnKeyboardActionListener() { - return mKeyboardActionListener; - } - - /** - * Attaches a keyboard to this view. The keyboard can be switched at any time and the - * view will re-layout itself to accommodate the keyboard. - * @see Keyboard - * @see #getKeyboard() - * @param keyboard the keyboard to display in this view - */ - public void setKeyboard(Keyboard keyboard) { - if (mKeyboard != null) { - dismissKeyPreview(); - } - // Remove any pending messages, except dismissing preview - mHandler.cancelKeyTimers(); - mHandler.cancelPopupPreview(); - mKeyboard = keyboard; - LatinImeLogger.onSetKeyboard(keyboard); - mKeys = mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), - -getPaddingTop() + mVerticalCorrection); - mKeyboardVerticalGap = (int)getResources().getDimension(R.dimen.key_bottom_gap); - for (PointerTracker tracker : mPointerTrackers) { - tracker.setKeyboard(mKeys, mKeyHysteresisDistance); - } - requestLayout(); - // Hint to reallocate the buffer if the size changed - mKeyboardChanged = true; - invalidateAllKeys(); - computeProximityThreshold(keyboard); - mMiniKeyboardCache.clear(); - } - - /** - * Returns the current keyboard being displayed by this view. - * @return the currently attached keyboard - * @see #setKeyboard(Keyboard) - */ - public Keyboard getKeyboard() { - return mKeyboard; - } - - /** - * Return whether the device has distinct multi-touch panel. - * @return true if the device has distinct multi-touch panel. - */ - public boolean hasDistinctMultitouch() { - return mHasDistinctMultitouch; - } - - /** - * Sets the state of the shift key of the keyboard, if any. - * @param shifted whether or not to enable the state of the shift key - * @return true if the shift key state changed, false if there was no change - */ - public boolean setShifted(boolean shifted) { - if (mKeyboard != null) { - if (mKeyboard.setShifted(shifted)) { - // The whole keyboard probably needs to be redrawn - invalidateAllKeys(); - return true; - } - } - return false; - } - - /** - * Returns the state of the shift key of the keyboard, if any. - * @return true if the shift is in a pressed state, false otherwise. If there is - * no shift key on the keyboard or there is no keyboard attached, it returns false. - */ - public boolean isShifted() { - if (mKeyboard != null) { - return mKeyboard.isShifted(); - } - return false; - } - - /** - * Enables or disables the key feedback popup. This is a popup that shows a magnified - * version of the depressed key. By default the preview is enabled. - * @param previewEnabled whether or not to enable the key feedback popup - * @see #isPreviewEnabled() - */ - public void setPreviewEnabled(boolean previewEnabled) { - mShowPreview = previewEnabled; - } - - /** - * Returns the enabled state of the key feedback popup. - * @return whether or not the key feedback popup is enabled - * @see #setPreviewEnabled(boolean) - */ - public boolean isPreviewEnabled() { - return mShowPreview; - } - - public int getSymbolColorScheme() { - return mSymbolColorScheme; - } - - public void setPopupParent(View v) { - mMiniKeyboardParent = v; - } - - public void setPopupOffset(int x, int y) { - mPopupPreviewOffsetX = x; - mPopupPreviewOffsetY = y; - mPreviewPopup.dismiss(); - } - - /** - * When enabled, calls to {@link OnKeyboardActionListener#onKey} will include key - * codes for adjacent keys. When disabled, only the primary key code will be - * reported. - * @param enabled whether or not the proximity correction is enabled - */ - public void setProximityCorrectionEnabled(boolean enabled) { - mKeyDetector.setProximityCorrectionEnabled(enabled); - } - - /** - * Returns true if proximity correction is enabled. - */ - public boolean isProximityCorrectionEnabled() { - return mKeyDetector.isProximityCorrectionEnabled(); - } - - protected Locale getKeyboardLocale() { - if (mKeyboard instanceof LatinKeyboard) { - return ((LatinKeyboard)mKeyboard).getInputLocale(); - } else { - return getContext().getResources().getConfiguration().locale; - } - } - - protected CharSequence adjustCase(CharSequence label) { - if (mKeyboard.isShifted() && label != null && label.length() < 3 - && Character.isLowerCase(label.charAt(0))) { - return label.toString().toUpperCase(getKeyboardLocale()); - } - return label; - } - - @Override - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // Round up a little - if (mKeyboard == null) { - setMeasuredDimension( - getPaddingLeft() + getPaddingRight(), getPaddingTop() + getPaddingBottom()); - } else { - int width = mKeyboard.getMinWidth() + getPaddingLeft() + getPaddingRight(); - if (MeasureSpec.getSize(widthMeasureSpec) < width + 10) { - width = MeasureSpec.getSize(widthMeasureSpec); - } - setMeasuredDimension( - width, mKeyboard.getHeight() + getPaddingTop() + getPaddingBottom()); - } - } - - /** - * Compute the average distance between adjacent keys (horizontally and vertically) - * and square it to get the proximity threshold. We use a square here and in computing - * the touch distance from a key's center to avoid taking a square root. - * @param keyboard - */ - private void computeProximityThreshold(Keyboard keyboard) { - if (keyboard == null) return; - final Key[] keys = mKeys; - if (keys == null) return; - int length = keys.length; - int dimensionSum = 0; - for (int i = 0; i < length; i++) { - Key key = keys[i]; - dimensionSum += Math.min(key.width, key.height + mKeyboardVerticalGap) + key.gap; - } - if (dimensionSum < 0 || length == 0) return; - mKeyDetector.setProximityThreshold((int) (dimensionSum * 1.4f / length)); - } - - @Override - public void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - // Release the buffer, if any and it will be reallocated on the next draw - mBuffer = null; - } - - @Override - public void onDraw(Canvas canvas) { - super.onDraw(canvas); - if (mDrawPending || mBuffer == null || mKeyboardChanged) { - onBufferDraw(); - } - canvas.drawBitmap(mBuffer, 0, 0, null); - } - - private void onBufferDraw() { - if (mBuffer == null || mKeyboardChanged) { - if (mBuffer == null || mKeyboardChanged && - (mBuffer.getWidth() != getWidth() || mBuffer.getHeight() != getHeight())) { - // Make sure our bitmap is at least 1x1 - final int width = Math.max(1, getWidth()); - final int height = Math.max(1, getHeight()); - mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - mCanvas = new Canvas(mBuffer); - } - invalidateAllKeys(); - mKeyboardChanged = false; - } - final Canvas canvas = mCanvas; - canvas.clipRect(mDirtyRect, Op.REPLACE); - - if (mKeyboard == null) return; - - final Paint paint = mPaint; - final Drawable keyBackground = mKeyBackground; - final Rect clipRegion = mClipRegion; - final Rect padding = mPadding; - final int kbdPaddingLeft = getPaddingLeft(); - final int kbdPaddingTop = getPaddingTop(); - final Key[] keys = mKeys; - final Key invalidKey = mInvalidatedKey; - - paint.setColor(mKeyTextColor); - boolean drawSingleKey = false; - if (invalidKey != null && canvas.getClipBounds(clipRegion)) { - // TODO we should use Rect.inset and Rect.contains here. - // Is clipRegion completely contained within the invalidated key? - if (invalidKey.x + kbdPaddingLeft - 1 <= clipRegion.left && - invalidKey.y + kbdPaddingTop - 1 <= clipRegion.top && - invalidKey.x + invalidKey.width + kbdPaddingLeft + 1 >= clipRegion.right && - invalidKey.y + invalidKey.height + kbdPaddingTop + 1 >= clipRegion.bottom) { - drawSingleKey = true; - } - } - canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR); - final int keyCount = keys.length; - for (int i = 0; i < keyCount; i++) { - final Key key = keys[i]; - if (drawSingleKey && invalidKey != key) { - continue; - } - int[] drawableState = key.getCurrentDrawableState(); - keyBackground.setState(drawableState); - - // Switch the character to uppercase if shift is pressed - String label = key.label == null? null : adjustCase(key.label).toString(); - - final Rect bounds = keyBackground.getBounds(); - if (key.width != bounds.right || key.height != bounds.bottom) { - keyBackground.setBounds(0, 0, key.width, key.height); - } - canvas.translate(key.x + kbdPaddingLeft, key.y + kbdPaddingTop); - keyBackground.draw(canvas); - - boolean shouldDrawIcon = true; - if (label != null) { - // For characters, use large font. For labels like "Done", use small font. - final int labelSize; - if (label.length() > 1 && key.codes.length < 2) { - labelSize = mLabelTextSize; - paint.setTypeface(Typeface.DEFAULT_BOLD); - } else { - labelSize = mKeyTextSize; - paint.setTypeface(mKeyTextStyle); - } - paint.setTextSize(labelSize); - - Integer labelHeightValue = mTextHeightCache.get(labelSize); - final int labelHeight; - if (labelHeightValue != null) { - labelHeight = labelHeightValue; - } else { - Rect textBounds = new Rect(); - paint.getTextBounds(KEY_LABEL_HEIGHT_REFERENCE_CHAR, 0, 1, textBounds); - labelHeight = textBounds.height(); - mTextHeightCache.put(labelSize, labelHeight); - } - - // Draw a drop shadow for the text - paint.setShadowLayer(mShadowRadius, 0, 0, mShadowColor); - final int centerX = (key.width + padding.left - padding.right) / 2; - final int centerY = (key.height + padding.top - padding.bottom) / 2; - final float baseline = centerY - + labelHeight * KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR; - canvas.drawText(label, centerX, baseline, paint); - // Turn off drop shadow - paint.setShadowLayer(0, 0, 0, 0); - - // Usually don't draw icon if label is not null, but we draw icon for the number - // hint and popup hint. - shouldDrawIcon = shouldDrawLabelAndIcon(key); - } - if (key.icon != null && shouldDrawIcon) { - // Special handing for the upper-right number hint icons - final int drawableWidth; - final int drawableHeight; - final int drawableX; - final int drawableY; - if (shouldDrawIconFully(key)) { - drawableWidth = key.width; - drawableHeight = key.height; - drawableX = 0; - drawableY = NUMBER_HINT_VERTICAL_ADJUSTMENT_PIXEL; - } else { - drawableWidth = key.icon.getIntrinsicWidth(); - drawableHeight = key.icon.getIntrinsicHeight(); - drawableX = (key.width + padding.left - padding.right - drawableWidth) / 2; - drawableY = (key.height + padding.top - padding.bottom - drawableHeight) / 2; - } - canvas.translate(drawableX, drawableY); - key.icon.setBounds(0, 0, drawableWidth, drawableHeight); - key.icon.draw(canvas); - canvas.translate(-drawableX, -drawableY); - } - canvas.translate(-key.x - kbdPaddingLeft, -key.y - kbdPaddingTop); - } - mInvalidatedKey = null; - // Overlay a dark rectangle to dim the keyboard - if (mMiniKeyboard != null) { - paint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24); - canvas.drawRect(0, 0, getWidth(), getHeight(), paint); - } - - if (DEBUG) { - if (mShowTouchPoints) { - for (PointerTracker tracker : mPointerTrackers) { - int startX = tracker.getStartX(); - int startY = tracker.getStartY(); - int lastX = tracker.getLastX(); - int lastY = tracker.getLastY(); - paint.setAlpha(128); - paint.setColor(0xFFFF0000); - canvas.drawCircle(startX, startY, 3, paint); - canvas.drawLine(startX, startY, lastX, lastY, paint); - paint.setColor(0xFF0000FF); - canvas.drawCircle(lastX, lastY, 3, paint); - paint.setColor(0xFF00FF00); - canvas.drawCircle((startX + lastX) / 2, (startY + lastY) / 2, 2, paint); - } - } - } - - mDrawPending = false; - mDirtyRect.setEmpty(); - } - - // TODO: clean up this method. - private void dismissKeyPreview() { - for (PointerTracker tracker : mPointerTrackers) - tracker.updateKey(NOT_A_KEY); - showPreview(NOT_A_KEY, null); - } - - public void showPreview(int keyIndex, PointerTracker tracker) { - int oldKeyIndex = mOldPreviewKeyIndex; - mOldPreviewKeyIndex = keyIndex; - final boolean isLanguageSwitchEnabled = (mKeyboard instanceof LatinKeyboard) - && ((LatinKeyboard)mKeyboard).isLanguageSwitchEnabled(); - // We should re-draw popup preview when 1) we need to hide the preview, 2) we will show - // the space key preview and 3) pointer moves off the space key to other letter key, we - // should hide the preview of the previous key. - final boolean hidePreviewOrShowSpaceKeyPreview = (tracker == null) - || tracker.isSpaceKey(keyIndex) || tracker.isSpaceKey(oldKeyIndex); - // If key changed and preview is on or the key is space (language switch is enabled) - if (oldKeyIndex != keyIndex - && (mShowPreview - || (hidePreviewOrShowSpaceKeyPreview && isLanguageSwitchEnabled))) { - if (keyIndex == NOT_A_KEY) { - mHandler.cancelPopupPreview(); - mHandler.dismissPreview(mDelayAfterPreview); - } else if (tracker != null) { - mHandler.popupPreview(mDelayBeforePreview, keyIndex, tracker); - } - } - } - - private void showKey(final int keyIndex, PointerTracker tracker) { - Key key = tracker.getKey(keyIndex); - if (key == null) - return; - // Should not draw hint icon in key preview - if (key.icon != null && !shouldDrawLabelAndIcon(key)) { - mPreviewText.setCompoundDrawables(null, null, null, - key.iconPreview != null ? key.iconPreview : key.icon); - mPreviewText.setText(null); - } else { - mPreviewText.setCompoundDrawables(null, null, null, null); - mPreviewText.setText(adjustCase(tracker.getPreviewText(key))); - if (key.label.length() > 1 && key.codes.length < 2) { - mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyTextSize); - mPreviewText.setTypeface(Typeface.DEFAULT_BOLD); - } else { - mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSizeLarge); - mPreviewText.setTypeface(mKeyTextStyle); - } - } - mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.width - + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight()); - final int popupHeight = mPreviewHeight; - LayoutParams lp = mPreviewText.getLayoutParams(); - if (lp != null) { - lp.width = popupWidth; - lp.height = popupHeight; - } - - int popupPreviewX = key.x - (popupWidth - key.width) / 2; - int popupPreviewY = key.y - popupHeight + mPreviewOffset; - - mHandler.cancelDismissPreview(); - if (mOffsetInWindow == null) { - mOffsetInWindow = new int[2]; - getLocationInWindow(mOffsetInWindow); - mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero - mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero - int[] windowLocation = new int[2]; - getLocationOnScreen(windowLocation); - mWindowY = windowLocation[1]; - } - // Set the preview background state - mPreviewText.getBackground().setState( - key.popupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET); - popupPreviewX += mOffsetInWindow[0]; - popupPreviewY += mOffsetInWindow[1]; - - // If the popup cannot be shown above the key, put it on the side - if (popupPreviewY + mWindowY < 0) { - // If the key you're pressing is on the left side of the keyboard, show the popup on - // the right, offset by enough to see at least one key to the left/right. - if (key.x + key.width <= getWidth() / 2) { - popupPreviewX += (int) (key.width * 2.5); - } else { - popupPreviewX -= (int) (key.width * 2.5); - } - popupPreviewY += popupHeight; - } - - if (mPreviewPopup.isShowing()) { - mPreviewPopup.update(popupPreviewX, popupPreviewY, popupWidth, popupHeight); - } else { - mPreviewPopup.setWidth(popupWidth); - mPreviewPopup.setHeight(popupHeight); - mPreviewPopup.showAtLocation(mMiniKeyboardParent, Gravity.NO_GRAVITY, - popupPreviewX, popupPreviewY); - } - // Record popup preview position to display mini-keyboard later at the same positon - mPopupPreviewDisplayedY = popupPreviewY; - mPreviewText.setVisibility(VISIBLE); - } - - /** - * Requests a redraw of the entire keyboard. Calling {@link #invalidate} is not sufficient - * because the keyboard renders the keys to an off-screen buffer and an invalidate() only - * draws the cached buffer. - * @see #invalidateKey(Key) - */ - public void invalidateAllKeys() { - mDirtyRect.union(0, 0, getWidth(), getHeight()); - mDrawPending = true; - invalidate(); - } - - /** - * Invalidates a key so that it will be redrawn on the next repaint. Use this method if only - * one key is changing it's content. Any changes that affect the position or size of the key - * may not be honored. - * @param key key in the attached {@link Keyboard}. - * @see #invalidateAllKeys - */ - public void invalidateKey(Key key) { - if (key == null) - return; - mInvalidatedKey = key; - // TODO we should clean up this and record key's region to use in onBufferDraw. - mDirtyRect.union(key.x + getPaddingLeft(), key.y + getPaddingTop(), - key.x + key.width + getPaddingLeft(), key.y + key.height + getPaddingTop()); - onBufferDraw(); - invalidate(key.x + getPaddingLeft(), key.y + getPaddingTop(), - key.x + key.width + getPaddingLeft(), key.y + key.height + getPaddingTop()); - } - - private boolean openPopupIfRequired(int keyIndex, PointerTracker tracker) { - // Check if we have a popup layout specified first. - if (mPopupLayout == 0) { - return false; - } - - Key popupKey = tracker.getKey(keyIndex); - if (popupKey == null) - return false; - boolean result = onLongPress(popupKey); - if (result) { - dismissKeyPreview(); - mMiniKeyboardTrackerId = tracker.mPointerId; - // Mark this tracker "already processed" and remove it from the pointer queue - tracker.setAlreadyProcessed(); - mPointerQueue.remove(tracker); - } - return result; - } - - private View inflateMiniKeyboardContainer(Key popupKey) { - int popupKeyboardId = popupKey.popupResId; - LayoutInflater inflater = (LayoutInflater)getContext().getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - View container = inflater.inflate(mPopupLayout, null); - if (container == null) - throw new NullPointerException(); - - LatinKeyboardBaseView miniKeyboard = - (LatinKeyboardBaseView)container.findViewById(R.id.LatinKeyboardBaseView); - miniKeyboard.setOnKeyboardActionListener(new OnKeyboardActionListener() { - public void onKey(int primaryCode, int[] keyCodes, int x, int y) { - mKeyboardActionListener.onKey(primaryCode, keyCodes, x, y); - dismissPopupKeyboard(); - } - - public void onText(CharSequence text) { - mKeyboardActionListener.onText(text); - dismissPopupKeyboard(); - } - - public void onCancel() { - mKeyboardActionListener.onCancel(); - dismissPopupKeyboard(); - } - - public void swipeLeft() { - } - public void swipeRight() { - } - public void swipeUp() { - } - public void swipeDown() { - } - public void onPress(int primaryCode) { - mKeyboardActionListener.onPress(primaryCode); - } - public void onRelease(int primaryCode) { - mKeyboardActionListener.onRelease(primaryCode); - } - }); - // Override default ProximityKeyDetector. - miniKeyboard.mKeyDetector = new MiniKeyboardKeyDetector(mMiniKeyboardSlideAllowance); - // Remove gesture detector on mini-keyboard - miniKeyboard.mGestureDetector = null; - - Keyboard keyboard; - if (popupKey.popupCharacters != null) { - keyboard = new Keyboard(getContext(), popupKeyboardId, popupKey.popupCharacters, - -1, getPaddingLeft() + getPaddingRight()); - } else { - keyboard = new Keyboard(getContext(), popupKeyboardId); - } - miniKeyboard.setKeyboard(keyboard); - miniKeyboard.setPopupParent(this); - - container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST)); - - return container; - } - - private static boolean isOneRowKeys(List keys) { - if (keys.size() == 0) return false; - final int edgeFlags = keys.get(0).edgeFlags; - // HACK: The first key of mini keyboard which was inflated from xml and has multiple rows, - // does not have both top and bottom edge flags on at the same time. On the other hand, - // the first key of mini keyboard that was created with popupCharacters must have both top - // and bottom edge flags on. - // When you want to use one row mini-keyboard from xml file, make sure that the row has - // both top and bottom edge flags set. - return (edgeFlags & Keyboard.EDGE_TOP) != 0 && (edgeFlags & Keyboard.EDGE_BOTTOM) != 0; - } - - /** - * Called when a key is long pressed. By default this will open any popup keyboard associated - * with this key through the attributes popupLayout and popupCharacters. - * @param popupKey the key that was long pressed - * @return true if the long press is handled, false otherwise. Subclasses should call the - * method on the base class if the subclass doesn't wish to handle the call. - */ - protected boolean onLongPress(Key popupKey) { - // TODO if popupKey.popupCharacters has only one letter, send it as key without opening - // mini keyboard. - - if (popupKey.popupResId == 0) - return false; - - View container = mMiniKeyboardCache.get(popupKey); - if (container == null) { - container = inflateMiniKeyboardContainer(popupKey); - mMiniKeyboardCache.put(popupKey, container); - } - mMiniKeyboard = (LatinKeyboardBaseView)container.findViewById(R.id.LatinKeyboardBaseView); - if (mWindowOffset == null) { - mWindowOffset = new int[2]; - getLocationInWindow(mWindowOffset); - } - - // Get width of a key in the mini popup keyboard = "miniKeyWidth". - // On the other hand, "popupKey.width" is width of the pressed key on the main keyboard. - // We adjust the position of mini popup keyboard with the edge key in it: - // a) When we have the leftmost key in popup keyboard directly above the pressed key - // Right edges of both keys should be aligned for consistent default selection - // b) When we have the rightmost key in popup keyboard directly above the pressed key - // Left edges of both keys should be aligned for consistent default selection - final List miniKeys = mMiniKeyboard.getKeyboard().getKeys(); - final int miniKeyWidth = miniKeys.size() > 0 ? miniKeys.get(0).width : 0; - - // HACK: Have the leftmost number in the popup characters right above the key - boolean isNumberAtLeftmost = - hasMultiplePopupChars(popupKey) && isNumberAtLeftmostPopupChar(popupKey); - int popupX = popupKey.x + mWindowOffset[0]; - popupX += getPaddingLeft(); - if (isNumberAtLeftmost) { - popupX += popupKey.width - miniKeyWidth; // adjustment for a) described above - popupX -= container.getPaddingLeft(); - } else { - popupX += miniKeyWidth; // adjustment for b) described above - popupX -= container.getMeasuredWidth(); - popupX += container.getPaddingRight(); - } - int popupY = popupKey.y + mWindowOffset[1]; - popupY += getPaddingTop(); - popupY -= container.getMeasuredHeight(); - popupY += container.getPaddingBottom(); - final int x = popupX; - final int y = mShowPreview && isOneRowKeys(miniKeys) ? mPopupPreviewDisplayedY : popupY; - - int adjustedX = x; - if (x < 0) { - adjustedX = 0; - } else if (x > (getMeasuredWidth() - container.getMeasuredWidth())) { - adjustedX = getMeasuredWidth() - container.getMeasuredWidth(); - } - mMiniKeyboardOriginX = adjustedX + container.getPaddingLeft() - mWindowOffset[0]; - mMiniKeyboardOriginY = y + container.getPaddingTop() - mWindowOffset[1]; - mMiniKeyboard.setPopupOffset(adjustedX, y); - mMiniKeyboard.setShifted(isShifted()); - // Mini keyboard needs no pop-up key preview displayed. - mMiniKeyboard.setPreviewEnabled(false); - mMiniKeyboardPopup.setContentView(container); - mMiniKeyboardPopup.setWidth(container.getMeasuredWidth()); - mMiniKeyboardPopup.setHeight(container.getMeasuredHeight()); - mMiniKeyboardPopup.showAtLocation(this, Gravity.NO_GRAVITY, x, y); - - // Inject down event on the key to mini keyboard. - long eventTime = SystemClock.uptimeMillis(); - mMiniKeyboardPopupTime = eventTime; - MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN, popupKey.x - + popupKey.width / 2, popupKey.y + popupKey.height / 2, eventTime); - mMiniKeyboard.onTouchEvent(downEvent); - downEvent.recycle(); - - invalidateAllKeys(); - return true; - } - - private static boolean hasMultiplePopupChars(Key key) { - if (key.popupCharacters != null && key.popupCharacters.length() > 1) { - return true; - } - return false; - } - - private boolean shouldDrawIconFully(Key key) { - return isNumberAtEdgeOfPopupChars(key) || isLatinF1Key(key) - || LatinKeyboard.hasPuncOrSmileysPopup(key); - } - - private boolean shouldDrawLabelAndIcon(Key key) { - return isNumberAtEdgeOfPopupChars(key) || isNonMicLatinF1Key(key) - || LatinKeyboard.hasPuncOrSmileysPopup(key); - } - - private boolean isLatinF1Key(Key key) { - return (mKeyboard instanceof LatinKeyboard) && ((LatinKeyboard)mKeyboard).isF1Key(key); - } - - private boolean isNonMicLatinF1Key(Key key) { - return isLatinF1Key(key) && key.label != null; - } - - private static boolean isNumberAtEdgeOfPopupChars(Key key) { - return isNumberAtLeftmostPopupChar(key) || isNumberAtRightmostPopupChar(key); - } - - /* package */ static boolean isNumberAtLeftmostPopupChar(Key key) { - if (key.popupCharacters != null && key.popupCharacters.length() > 0 - && isAsciiDigit(key.popupCharacters.charAt(0))) { - return true; - } - return false; - } - - /* package */ static boolean isNumberAtRightmostPopupChar(Key key) { - if (key.popupCharacters != null && key.popupCharacters.length() > 0 - && isAsciiDigit(key.popupCharacters.charAt(key.popupCharacters.length() - 1))) { - return true; - } - return false; - } - - private static boolean isAsciiDigit(char c) { - return (c < 0x80) && Character.isDigit(c); - } - - private MotionEvent generateMiniKeyboardMotionEvent(int action, int x, int y, long eventTime) { - return MotionEvent.obtain(mMiniKeyboardPopupTime, eventTime, action, - x - mMiniKeyboardOriginX, y - mMiniKeyboardOriginY, 0); - } - - private PointerTracker getPointerTracker(final int id) { - final ArrayList 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() { - - @Override - protected Object doInBackground(Object... params) { - try { - Thread.sleep(1000, 0); - } catch (InterruptedException e) { - e.printStackTrace(); - } - typeQueue(); - return null; - } - - }; - typeQueue(); - break; - case ConnectionManager.STATE_DISCONNECTED: - Log.d(_TAG, "stopping service. State = "+state); - stopSelf(); - break; - case ConnectionManager.STATE_FAILURE: - Log.d(_TAG, "stopping service. State = "+state); - stopSelf(); - AlertDialog ad = InputStickHID.getDownloadDialog(this); - if (ad != null) { - //Utility application not installed - ad.show(); - } else { - Toast.makeText(this, "Failure connecting to InputStick!", Toast.LENGTH_LONG).show(); - } - break; - default: - break; - } - - } - -} diff --git a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/PluginUtils.java b/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/PluginUtils.java deleted file mode 100644 index 801260b9..00000000 --- a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/PluginUtils.java +++ /dev/null @@ -1,28 +0,0 @@ -package keepass2android.plugin.inputstick; - -import com.inputstick.api.ConnectionManager; -import com.inputstick.api.basic.InputStickHID; -import com.inputstick.api.layout.KeyboardLayout; - -import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; - -public class PluginUtils { - - public static void type(Context ctx, String toType) { - if (InputStickHID.getState() == ConnectionManager.STATE_READY) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); - String layoutKey; - if ("PRIMARY".equals(prefs.getString("active_layout", "PRIMARY"))) { - layoutKey = "kbd_layout"; - } else { - layoutKey = "secondary_kbd_layout"; - } - - KeyboardLayout layout = KeyboardLayout.getLayout(prefs.getString(layoutKey, "en-US")); - layout.type(toType); - } - } - -} diff --git a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/QuickSettingsActivity.java b/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/QuickSettingsActivity.java deleted file mode 100644 index 7c9d1471..00000000 --- a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/QuickSettingsActivity.java +++ /dev/null @@ -1,61 +0,0 @@ -package keepass2android.plugin.inputstick; - -import android.app.Activity; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.widget.CheckBox; -import android.widget.RadioButton; - -public class QuickSettingsActivity extends Activity { - - private CheckBox checkBoxAutoConnect; - private RadioButton radioButtonPrimary; - private RadioButton radioButtonSecondary; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB){ - super.setTheme( android.R.style.Theme_Holo_Dialog); - } - setContentView(R.layout.activity_quick_settings); - - checkBoxAutoConnect = (CheckBox)findViewById(R.id.checkBoxAutoConnect); - radioButtonPrimary = (RadioButton)findViewById(R.id.radioButtonPrimary); - radioButtonSecondary = (RadioButton)findViewById(R.id.radioButtonSecondary); - } - - @Override - protected void onResume() { - super.onResume(); - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - radioButtonPrimary.setText("Primary layout: " + prefs.getString("kbd_layout", "en-US")); - radioButtonSecondary.setText("Secondary layout: " + prefs.getString("secondary_kbd_layout", "en-US")); - if ("PRIMARY".equals(prefs.getString("active_layout", "PRIMARY"))) { - radioButtonPrimary.setChecked(true); - } else { - radioButtonSecondary.setChecked(true); - } - - checkBoxAutoConnect.setChecked(prefs.getBoolean("autoconnect", true)); - } - - @Override - protected void onPause() { - // TODO if modified - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - SharedPreferences.Editor editor = prefs.edit(); - - if (radioButtonPrimary.isChecked()) { - editor.putString("active_layout", "PRIMARY"); - } else { - editor.putString("active_layout", "SECONDARY"); - } - editor.putBoolean("autoconnect", checkBoxAutoConnect.isChecked()); - editor.apply(); - super.onPause(); - } - -} diff --git a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/SettingsActivity.java b/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/SettingsActivity.java deleted file mode 100644 index 054a5d8f..00000000 --- a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/SettingsActivity.java +++ /dev/null @@ -1,394 +0,0 @@ -package keepass2android.plugin.inputstick; - -import keepass2android.pluginsdk.AccessManager; -import keepass2android.pluginsdk.Strings; -import sheetrock.panda.changelog.ChangeLog; -import android.annotation.TargetApi; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceChangeListener; -import android.preference.Preference.OnPreferenceClickListener; -import android.preference.PreferenceActivity; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.widget.CheckBox; - -/** - * A {@link PreferenceActivity} that presents a set of application settings. On - * handset devices, settings are presented as a single list. On tablets, - * settings are split by category, with category headers shown to the left of - * the list of settings. - *

- * See - * Android Design: Settings for design guidelines and the Settings - * API Guide for more information on developing a Settings UI. - */ - -@SuppressWarnings("deprecation") -public class SettingsActivity extends PreferenceActivity { - /** - * Determines whether to always show the simplified settings UI, where - * settings are presented in a single list. When false, settings are shown - * as a master/detail two-pane view on tablets. When true, a single pane is - * shown on tablets. - */ - private static final boolean ALWAYS_SIMPLE_PREFS = false; - - private Preference prefShowSecondary; - private Preference prefSecondaryKbdLayout; - - private Preference prefAutoconnectTimeout; - - private Preference prefSettings; - private Preference prefMacSetup; - private Preference prefTabEnter; - - private Preference prefUserPass; - private Preference prefUserPassEnter; - private Preference prefMasked; - private Preference prefType; - private Preference prefTypeSlow; - - private Preference prefSecondaryUserPass; - private Preference prefSecondaryUserPassEnter; - private Preference prefSecondaryMasked; - private Preference prefSecondaryType; - private Preference prefSecondaryTypeSlow; - - private boolean displayReloadInfo; - private OnPreferenceClickListener reloadInfoListener = new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - displayReloadInfo = true; - return false; - } - }; - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - - setupSimplePreferencesScreen(); - - if (getIntent().getBooleanExtra(Const.EXTRA_CHANGELOG, false)) { - ChangeLog cl = new ChangeLog(this); - cl.getLogDialog().show(); - } else { - //first run ever? - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - if (prefs.getBoolean("display_configuration_message", true)) { - AlertDialog.Builder alert = new AlertDialog.Builder(this); - - alert.setTitle(R.string.configuration_title); - alert.setMessage(R.string.configuration_message); - alert.setPositiveButton("OK", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - //disable cfg message ONLY after clicking OK button - prefs.edit().putBoolean("display_configuration_message", false).apply(); - } - }); - alert.show(); - } - } - } - - /** - * Shows the simplified settings UI if the device configuration if the - * device configuration dictates that a simplified, single-pane UI should be - * shown. - */ - - private void setupSimplePreferencesScreen() { - if (!isSimplePreferences(this)) { - return; - } - - // In the simplified UI, fragments are not used at all and we instead - // use the older PreferenceActivity APIs. - - // Add 'general' preferences. - addPreferencesFromResource(R.xml.pref_general); - - bindPreferenceSummaryToValue(findPreference("kbd_layout")); - bindPreferenceSummaryToValue(findPreference("secondary_kbd_layout")); - bindPreferenceSummaryToValue(findPreference("typing_speed")); - bindPreferenceSummaryToValue(findPreference("autoconnect_timeout")); - - - - Preference pref; - - pref = findPreference("enable_plugin_pref"); - pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - try { - Intent i = new Intent( Strings.ACTION_EDIT_PLUGIN_SETTINGS); - i.putExtra(Strings.EXTRA_PLUGIN_PACKAGE, SettingsActivity.this.getPackageName()); - startActivityForResult(i, 123); - } catch (Exception e) { - e.printStackTrace(); - } - return true; - } - }); - - pref = (Preference)findPreference("show_changelog_preference_key"); - pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - ChangeLog cl = new ChangeLog(SettingsActivity.this); - cl.getFullLogDialog().show(); - return true; - } - }); - - pref = (Preference)findPreference("show_help_webpage_key"); - pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.inputstick.com/help")); - startActivity(browserIntent); - return true; - } - }); - - - pref = (Preference) findPreference("show_secondary"); - pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - setSecondaryLayoutEnabled((Boolean)newValue); - return true; - } - }); - - pref = (Preference) findPreference("autoconnect"); - pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - setAutoconnectTimeoutEnabled((Boolean)newValue); - return true; - } - }); - - prefAutoconnectTimeout = (Preference) findPreference("autoconnect_timeout"); - prefShowSecondary = (Preference) findPreference("show_secondary"); - - prefSettings = (Preference) findPreference("show_settings"); - prefMacSetup = (Preference) findPreference("show_mac_setup"); - prefTabEnter = (Preference) findPreference("show_tab_enter"); - - prefUserPass = (Preference) findPreference("show_user_pass"); - prefUserPassEnter = (Preference) findPreference("show_user_pass_enter"); - prefMasked = (Preference) findPreference("show_masked"); - prefType = (Preference) findPreference("show_field_type"); - prefTypeSlow = (Preference) findPreference("show_field_type_slow"); - - prefSecondaryKbdLayout = findPreference("secondary_kbd_layout"); - prefSecondaryUserPass = findPreference("show_user_pass_secondary"); - prefSecondaryUserPassEnter = findPreference("show_user_pass_enter_secondary"); - prefSecondaryMasked = findPreference("show_masked_secondary"); - prefSecondaryType = findPreference("show_field_type_secondary"); - prefSecondaryTypeSlow = findPreference("show_field_type_slow_secondary"); - - - - prefShowSecondary.setOnPreferenceClickListener(reloadInfoListener); - - prefSettings.setOnPreferenceClickListener(reloadInfoListener); - prefMacSetup.setOnPreferenceClickListener(reloadInfoListener); - prefTabEnter.setOnPreferenceClickListener(reloadInfoListener); - - prefUserPass.setOnPreferenceClickListener(reloadInfoListener); - prefUserPassEnter.setOnPreferenceClickListener(reloadInfoListener); - prefMasked.setOnPreferenceClickListener(reloadInfoListener); - prefType.setOnPreferenceClickListener(reloadInfoListener); - prefTypeSlow.setOnPreferenceClickListener(reloadInfoListener); - - prefSecondaryUserPass.setOnPreferenceClickListener(reloadInfoListener); - prefSecondaryUserPassEnter.setOnPreferenceClickListener(reloadInfoListener); - prefSecondaryMasked.setOnPreferenceClickListener(reloadInfoListener); - prefSecondaryType.setOnPreferenceClickListener(reloadInfoListener); - prefSecondaryTypeSlow.setOnPreferenceClickListener(reloadInfoListener); - - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - setSecondaryLayoutEnabled(prefs.getBoolean("show_secondary", false)); - setAutoconnectTimeoutEnabled(prefs.getBoolean("autoconnect", true)); - } - - @Override - protected void onResume() { - displayReloadInfo = false; - Preference enablePref = findPreference("enable_plugin_pref"); - if (AccessManager.getAllHostPackages(SettingsActivity.this).isEmpty()) { - enablePref.setSummary(""); - } else { - enablePref.setSummary(R.string.enabled); - } - - super.onResume(); - } - - @Override - public void onBackPressed() { - if (displayReloadInfo) { - final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - if (sharedPref.getBoolean("show_reload_warning", true)) { - displayReloadInfo = false; - AlertDialog.Builder alert = new AlertDialog.Builder(this); - alert.setTitle(R.string.important_title); - alert.setMessage(R.string.entry_reload_message); - - final CheckBox cb = new CheckBox(this); - cb.setText(R.string.do_not_remind); - cb.setChecked(false); - alert.setView(cb); - - alert.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - SettingsActivity.this.onBackPressed(); - if (cb.isChecked()) { - SharedPreferences.Editor editor = sharedPref.edit(); - editor.putBoolean("show_reload_warning", false); - editor.apply(); - } - } - }); - alert.show(); - } else { - super.onBackPressed(); - } - } else { - super.onBackPressed(); - } - } - - - private void setAutoconnectTimeoutEnabled(boolean enabled) { - prefAutoconnectTimeout.setEnabled( !enabled); // <<<<<<<<<<< show this pref only if autoconnect is DISABLED - } - - private void setSecondaryLayoutEnabled(boolean enabled) { - prefSecondaryKbdLayout.setEnabled(enabled); - prefSecondaryUserPass.setEnabled(enabled); - prefSecondaryUserPassEnter.setEnabled(enabled); - prefSecondaryMasked.setEnabled(enabled); - prefSecondaryType.setEnabled(enabled); - prefSecondaryTypeSlow.setEnabled(enabled); - } - - /** {@inheritDoc} */ - @Override - public boolean onIsMultiPane() { - return isXLargeTablet(this) && !isSimplePreferences(this); - } - - /** - * Helper method to determine if the device has an extra-large screen. For - * example, 10" tablets are extra-large. - */ - private static boolean isXLargeTablet(Context context) { - return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE; - } - - /** - * Determines whether the simplified settings UI should be shown. This is - * true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device - * doesn't have newer APIs like {@link PreferenceFragment}, or the device - * doesn't have an extra-large screen. In these cases, a single-pane - * "simplified" settings UI should be shown. - */ - private static boolean isSimplePreferences(Context context) { - return ALWAYS_SIMPLE_PREFS - || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB - || !isXLargeTablet(context); - } - - - - /** - * A preference value change listener that updates the preference's summary - * to reflect its new value. - */ - private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - String stringValue = value.toString(); - - if (preference instanceof ListPreference) { - // For list preferences, look up the correct display value in - // the preference's 'entries' list. - ListPreference listPreference = (ListPreference) preference; - int index = listPreference.findIndexOfValue(stringValue); - - // Set the summary to reflect the new value. - preference - .setSummary(index >= 0 ? listPreference.getEntries()[index] - : null); - - - } else { - // For all other preferences, set the summary to the value's - // simple string representation. - preference.setSummary(stringValue); - } - return true; - } - }; - - /** - * Binds a preference's summary to its value. More specifically, when the - * preference's value is changed, its summary (line of text below the - * preference title) is updated to reflect the value. The summary is also - * immediately updated upon calling this method. The exact display format is - * dependent on the type of preference. - * - * @see #sBindPreferenceSummaryToValueListener - */ - private static void bindPreferenceSummaryToValue(Preference preference) { - // Set the listener to watch for value changes. - preference - .setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener); - - // Trigger the listener immediately with the preference's - // current value. - sBindPreferenceSummaryToValueListener.onPreferenceChange( - preference, - PreferenceManager.getDefaultSharedPreferences( - preference.getContext()).getString(preference.getKey(), - "")); - } - - /** - * This fragment shows general preferences only. It is used when the - * activity is showing a two-pane settings UI. - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public static class GeneralPreferenceFragment extends PreferenceFragment { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.pref_general); - - // Bind the summaries of EditText/List/Dialog/Ringtone preferences - // to their values. When their values change, their summaries are - // updated to reflect the new value, per the Android Design - // guidelines. - //bindPreferenceSummaryToValue(findPreference("example_text")); - //bindPreferenceSummaryToValue(findPreference("example_list")); - } - } - -} diff --git a/src/java/PluginInputStick3/.idea/.name b/src/java/PluginInputStick3/.idea/.name new file mode 100644 index 00000000..7d5e9b7a --- /dev/null +++ b/src/java/PluginInputStick3/.idea/.name @@ -0,0 +1 @@ +PluginInputStick \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/compiler.xml b/src/java/PluginInputStick3/.idea/compiler.xml new file mode 100644 index 00000000..96cc43ef --- /dev/null +++ b/src/java/PluginInputStick3/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/copyright/profiles_settings.xml b/src/java/PluginInputStick3/.idea/copyright/profiles_settings.xml new file mode 100644 index 00000000..e7bedf33 --- /dev/null +++ b/src/java/PluginInputStick3/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/encodings.xml b/src/java/PluginInputStick3/.idea/encodings.xml new file mode 100644 index 00000000..97626ba4 --- /dev/null +++ b/src/java/PluginInputStick3/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/gradle.xml b/src/java/PluginInputStick3/.idea/gradle.xml new file mode 100644 index 00000000..28abdf2f --- /dev/null +++ b/src/java/PluginInputStick3/.idea/gradle.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/inspectionProfiles/Project_Default.xml b/src/java/PluginInputStick3/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..cda74312 --- /dev/null +++ b/src/java/PluginInputStick3/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/inspectionProfiles/profiles_settings.xml b/src/java/PluginInputStick3/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 00000000..3b312839 --- /dev/null +++ b/src/java/PluginInputStick3/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/libraries/appcompat_v7_19_1_0.xml b/src/java/PluginInputStick3/.idea/libraries/appcompat_v7_19_1_0.xml new file mode 100644 index 00000000..8b3f2728 --- /dev/null +++ b/src/java/PluginInputStick3/.idea/libraries/appcompat_v7_19_1_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/libraries/support_v4_19_1_0.xml b/src/java/PluginInputStick3/.idea/libraries/support_v4_19_1_0.xml new file mode 100644 index 00000000..e08a400c --- /dev/null +++ b/src/java/PluginInputStick3/.idea/libraries/support_v4_19_1_0.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/misc.xml b/src/java/PluginInputStick3/.idea/misc.xml new file mode 100644 index 00000000..f49fb40b --- /dev/null +++ b/src/java/PluginInputStick3/.idea/misc.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 1.7 + + + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/modules.xml b/src/java/PluginInputStick3/.idea/modules.xml new file mode 100644 index 00000000..c14e1f0e --- /dev/null +++ b/src/java/PluginInputStick3/.idea/modules.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/vcs.xml b/src/java/PluginInputStick3/.idea/vcs.xml new file mode 100644 index 00000000..6564d52d --- /dev/null +++ b/src/java/PluginInputStick3/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/.idea/workspace.xml b/src/java/PluginInputStick3/.idea/workspace.xml new file mode 100644 index 00000000..5338a06a --- /dev/null +++ b/src/java/PluginInputStick3/.idea/workspace.xml @@ -0,0 +1,3460 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Android Lint + + + + + AndroidLintMissingTranslation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1453869721121 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/PluginInputStick3.iml b/src/java/PluginInputStick3/PluginInputStick3.iml new file mode 100644 index 00000000..20eca2fb --- /dev/null +++ b/src/java/PluginInputStick3/PluginInputStick3.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/build.gradle b/src/java/PluginInputStick3/build.gradle new file mode 100644 index 00000000..88d246d4 --- /dev/null +++ b/src/java/PluginInputStick3/build.gradle @@ -0,0 +1,15 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.2.3' + } +} + +allprojects { + repositories { + jcenter() + } +} diff --git a/src/java/PluginInputStick3/gradle/wrapper/gradle-wrapper.jar b/src/java/PluginInputStick3/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..8c0fb64a Binary files /dev/null and b/src/java/PluginInputStick3/gradle/wrapper/gradle-wrapper.jar differ diff --git a/src/java/PluginInputStick3/gradle/wrapper/gradle-wrapper.properties b/src/java/PluginInputStick3/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..0c71e760 --- /dev/null +++ b/src/java/PluginInputStick3/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Apr 10 15:27:10 PDT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/src/java/PluginInputStick3/gradlew b/src/java/PluginInputStick3/gradlew new file mode 100644 index 00000000..91a7e269 --- /dev/null +++ b/src/java/PluginInputStick3/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/src/java/PluginInputStick3/gradlew.bat b/src/java/PluginInputStick3/gradlew.bat new file mode 100644 index 00000000..8a0b282a --- /dev/null +++ b/src/java/PluginInputStick3/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/java/PluginInputStick3/import-summary.txt b/src/java/PluginInputStick3/import-summary.txt new file mode 100644 index 00000000..6a1c097d --- /dev/null +++ b/src/java/PluginInputStick3/import-summary.txt @@ -0,0 +1,1926 @@ +ECLIPSE ANDROID PROJECT IMPORT SUMMARY +====================================== + +Manifest Merging: +----------------- +Your project uses libraries that provide manifests, and your Eclipse +project did not explicitly turn on manifest merging. In Android Gradle +projects, manifests are always merged (meaning that contents from your +libraries' manifests will be merged into the app manifest. If you had +manually copied contents from library manifests into your app manifest +you may need to remove these for the app to build correctly. + +Ignored Files: +-------------- +The following files were *not* copied into the new Gradle project; you +should evaluate whether these are still needed in your project and if +so manually move them: + +From InputStickAPI: +* .gitignore +* .gradle\ +* .gradle\2.2.1\ +* .gradle\2.2.1\taskArtifacts\ +* .gradle\2.2.1\taskArtifacts\cache.properties +* .gradle\2.2.1\taskArtifacts\cache.properties.lock +* .gradle\2.2.1\taskArtifacts\fileHashes.bin +* .gradle\2.2.1\taskArtifacts\fileSnapshots.bin +* .gradle\2.2.1\taskArtifacts\outputFileStates.bin +* .gradle\2.2.1\taskArtifacts\taskArtifacts.bin +* .idea\ +* .idea\.name +* .idea\compiler.xml +* .idea\copyright\ +* .idea\copyright\profiles_settings.xml +* .idea\gradle.xml +* .idea\libraries\ +* .idea\libraries\appcompat_v7_19_1_0.xml +* .idea\libraries\support_v4_19_1_0.xml +* .idea\misc.xml +* .idea\modules.xml +* .idea\vcs.xml +* .idea\workspace.xml +* InputStickAPI.iml +* LICENSE +* README.md +* app\ +* app\app.iml +* app\build.gradle +* app\build\ +* app\build\generated\ +* app\build\generated\source\ +* app\build\generated\source\buildConfig\ +* app\build\generated\source\buildConfig\androidTest\ +* app\build\generated\source\buildConfig\androidTest\debug\ +* app\build\generated\source\buildConfig\androidTest\debug\com\ +* app\build\generated\source\buildConfig\androidTest\debug\com\inputstick\ +* app\build\generated\source\buildConfig\androidTest\debug\com\inputstick\api\ +* app\build\generated\source\buildConfig\androidTest\debug\com\inputstick\api\test\ +* app\build\generated\source\buildConfig\androidTest\debug\com\inputstick\api\test\BuildConfig.java +* app\build\generated\source\buildConfig\debug\ +* app\build\generated\source\buildConfig\debug\com\ +* app\build\generated\source\buildConfig\debug\com\inputstick\ +* app\build\generated\source\buildConfig\debug\com\inputstick\api\ +* app\build\generated\source\buildConfig\debug\com\inputstick\api\BuildConfig.java +* app\build\generated\source\r\ +* app\build\generated\source\r\androidTest\ +* app\build\generated\source\r\androidTest\debug\ +* app\build\generated\source\r\androidTest\debug\android\ +* app\build\generated\source\r\androidTest\debug\android\support\ +* app\build\generated\source\r\androidTest\debug\android\support\v7\ +* app\build\generated\source\r\androidTest\debug\android\support\v7\appcompat\ +* app\build\generated\source\r\androidTest\debug\android\support\v7\appcompat\R.java +* app\build\generated\source\r\androidTest\debug\com\ +* app\build\generated\source\r\androidTest\debug\com\inputstick\ +* app\build\generated\source\r\androidTest\debug\com\inputstick\api\ +* app\build\generated\source\r\androidTest\debug\com\inputstick\api\R.java +* app\build\generated\source\r\androidTest\debug\com\inputstick\api\test\ +* app\build\generated\source\r\androidTest\debug\com\inputstick\api\test\R.java +* app\build\generated\source\r\debug\ +* app\build\generated\source\r\debug\com\ +* app\build\generated\source\r\debug\com\inputstick\ +* app\build\generated\source\r\debug\com\inputstick\api\ +* app\build\generated\source\r\debug\com\inputstick\api\R.java +* app\build\intermediates\ +* app\build\intermediates\bundles\ +* app\build\intermediates\bundles\debug\ +* app\build\intermediates\bundles\debug\AndroidManifest.xml +* app\build\intermediates\bundles\debug\R.txt +* app\build\intermediates\bundles\debug\aapt\ +* app\build\intermediates\bundles\debug\aapt\AndroidManifest.xml +* app\build\intermediates\bundles\debug\classes.jar +* app\build\intermediates\bundles\debug\res\ +* app\build\intermediates\bundles\debug\res\drawable-hdpi\ +* app\build\intermediates\bundles\debug\res\drawable-hdpi\ic_launcher.png +* app\build\intermediates\bundles\debug\res\drawable-mdpi\ +* app\build\intermediates\bundles\debug\res\drawable-mdpi\ic_launcher.png +* app\build\intermediates\bundles\debug\res\drawable-xhdpi\ +* app\build\intermediates\bundles\debug\res\drawable-xhdpi\ic_launcher.png +* app\build\intermediates\bundles\debug\res\menu\ +* app\build\intermediates\bundles\debug\res\menu\install_utility.xml +* app\build\intermediates\bundles\debug\res\values-sw720dp-land\ +* app\build\intermediates\bundles\debug\res\values-sw720dp-land\values-sw720dp-land.xml +* app\build\intermediates\bundles\debug\res\values-v11\ +* app\build\intermediates\bundles\debug\res\values-v11\values-v11.xml +* app\build\intermediates\bundles\debug\res\values-v14\ +* app\build\intermediates\bundles\debug\res\values-v14\values-v14.xml +* app\build\intermediates\bundles\debug\res\values\ +* app\build\intermediates\bundles\debug\res\values\values.xml +* app\build\intermediates\classes\ +* app\build\intermediates\classes\androidTest\ +* app\build\intermediates\classes\androidTest\debug\ +* app\build\intermediates\classes\androidTest\debug\android\ +* app\build\intermediates\classes\androidTest\debug\android\support\ +* app\build\intermediates\classes\androidTest\debug\android\support\v7\ +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\ +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$anim.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$attr.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$bool.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$color.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$dimen.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$drawable.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$id.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$integer.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$layout.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$string.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$style.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R$styleable.class +* app\build\intermediates\classes\androidTest\debug\android\support\v7\appcompat\R.class +* app\build\intermediates\classes\androidTest\debug\com\ +* app\build\intermediates\classes\androidTest\debug\com\inputstick\ +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\ +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$anim.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$attr.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$bool.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$color.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$dimen.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$drawable.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$id.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$integer.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$layout.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$menu.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$string.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$style.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R$styleable.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\R.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\ +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\BuildConfig.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$anim.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$attr.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$bool.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$color.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$dimen.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$drawable.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$id.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$integer.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$layout.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$menu.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$string.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$style.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R$styleable.class +* app\build\intermediates\classes\androidTest\debug\com\inputstick\api\test\R.class +* app\build\intermediates\classes\debug\ +* app\build\intermediates\classes\debug\com\ +* app\build\intermediates\classes\debug\com\inputstick\ +* app\build\intermediates\classes\debug\com\inputstick\api\ +* app\build\intermediates\classes\debug\com\inputstick\api\AES.class +* app\build\intermediates\classes\debug\com\inputstick\api\BTConnectionManager$BTHandler.class +* app\build\intermediates\classes\debug\com\inputstick\api\BTConnectionManager.class +* app\build\intermediates\classes\debug\com\inputstick\api\BuildConfig.class +* app\build\intermediates\classes\debug\com\inputstick\api\ConnectionManager.class +* app\build\intermediates\classes\debug\com\inputstick\api\DownloadDialog$1.class +* app\build\intermediates\classes\debug\com\inputstick\api\DownloadDialog$2.class +* app\build\intermediates\classes\debug\com\inputstick\api\DownloadDialog.class +* app\build\intermediates\classes\debug\com\inputstick\api\HIDInfo.class +* app\build\intermediates\classes\debug\com\inputstick\api\IPCConnectionManager$1.class +* app\build\intermediates\classes\debug\com\inputstick\api\IPCConnectionManager$IncomingHandler.class +* app\build\intermediates\classes\debug\com\inputstick\api\IPCConnectionManager.class +* app\build\intermediates\classes\debug\com\inputstick\api\InputStickDataListener.class +* app\build\intermediates\classes\debug\com\inputstick\api\InputStickError.class +* app\build\intermediates\classes\debug\com\inputstick\api\InputStickKeyboardListener.class +* app\build\intermediates\classes\debug\com\inputstick\api\InputStickStateListener.class +* app\build\intermediates\classes\debug\com\inputstick\api\OnEmptyBufferListener.class +* app\build\intermediates\classes\debug\com\inputstick\api\Packet.class +* app\build\intermediates\classes\debug\com\inputstick\api\PacketManager.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$anim.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$attr.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$bool.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$color.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$dimen.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$drawable.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$id.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$integer.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$layout.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$menu.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$string.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$style.class +* app\build\intermediates\classes\debug\com\inputstick\api\R$styleable.class +* app\build\intermediates\classes\debug\com\inputstick\api\R.class +* app\build\intermediates\classes\debug\com\inputstick\api\Util.class +* app\build\intermediates\classes\debug\com\inputstick\api\basic\ +* app\build\intermediates\classes\debug\com\inputstick\api\basic\InputStickConsumer.class +* app\build\intermediates\classes\debug\com\inputstick\api\basic\InputStickGamepad.class +* app\build\intermediates\classes\debug\com\inputstick\api\basic\InputStickHID$1.class +* app\build\intermediates\classes\debug\com\inputstick\api\basic\InputStickHID.class +* app\build\intermediates\classes\debug\com\inputstick\api\basic\InputStickKeyboard.class +* app\build\intermediates\classes\debug\com\inputstick\api\basic\InputStickMouse.class +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\ +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\BT20Connection$ConnectThread.class +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\BT20Connection$ConnectedThread.class +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\BT20Connection.class +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\BT40Connection$1.class +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\BT40Connection$2.class +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\BT40Connection.class +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\BTConnection.class +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\BTService$1.class +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\BTService.class +* app\build\intermediates\classes\debug\com\inputstick\api\bluetooth\PacketReader.class +* app\build\intermediates\classes\debug\com\inputstick\api\broadcast\ +* app\build\intermediates\classes\debug\com\inputstick\api\broadcast\InputStickBroadcast.class +* app\build\intermediates\classes\debug\com\inputstick\api\hid\ +* app\build\intermediates\classes\debug\com\inputstick\api\hid\ConsumerReport.class +* app\build\intermediates\classes\debug\com\inputstick\api\hid\GamepadReport.class +* app\build\intermediates\classes\debug\com\inputstick\api\hid\HIDKeycodes.class +* app\build\intermediates\classes\debug\com\inputstick\api\hid\HIDReport.class +* app\build\intermediates\classes\debug\com\inputstick\api\hid\HIDTransaction.class +* app\build\intermediates\classes\debug\com\inputstick\api\hid\HIDTransactionQueue$1.class +* app\build\intermediates\classes\debug\com\inputstick\api\hid\HIDTransactionQueue.class +* app\build\intermediates\classes\debug\com\inputstick\api\hid\KeyboardReport.class +* app\build\intermediates\classes\debug\com\inputstick\api\hid\MouseReport.class +* app\build\intermediates\classes\debug\com\inputstick\api\init\ +* app\build\intermediates\classes\debug\com\inputstick\api\init\BasicInitManager$1.class +* app\build\intermediates\classes\debug\com\inputstick\api\init\BasicInitManager$2.class +* app\build\intermediates\classes\debug\com\inputstick\api\init\BasicInitManager.class +* app\build\intermediates\classes\debug\com\inputstick\api\init\DeviceInfo.class +* app\build\intermediates\classes\debug\com\inputstick\api\init\InitManager.class +* app\build\intermediates\classes\debug\com\inputstick\api\init\InitManagerListener.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\ +* app\build\intermediates\classes\debug\com\inputstick\api\layout\DanishLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\DvorakLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\FinnishLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\FrenchLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\GermanLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\GermanMacLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\HebrewLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\ItalianLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\KeyboardLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\NorwegianLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\PolishLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\PortugueseBrazilianLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\RussianLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\SlovakLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\SpanishLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\SwedishLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\SwissFrenchLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\SwissGermanLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\UnitedKingdomLayout.class +* app\build\intermediates\classes\debug\com\inputstick\api\layout\UnitedStatesLayout.class +* app\build\intermediates\classes\debug\com\inputstick\init\ +* app\build\intermediates\classes\debug\com\inputstick\init\BasicInitManager.class +* app\build\intermediates\classes\debug\com\inputstick\init\BootloaderInitManager.class +* app\build\intermediates\classes\debug\com\inputstick\init\DeviceInfo.class +* app\build\intermediates\classes\debug\com\inputstick\init\InitManager.class +* app\build\intermediates\classes\debug\com\inputstick\init\InitManagerListener.class +* app\build\intermediates\exploded-aar\ +* app\build\intermediates\exploded-aar\com.android.support\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\AndroidManifest.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\R.txt +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\jars\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\jars\classes.jar +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\anim\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\anim\abc_fade_in.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\anim\abc_fade_out.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\anim\abc_slide_in_bottom.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\anim\abc_slide_in_top.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\anim\abc_slide_out_bottom.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\anim\abc_slide_out_top.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\color\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\color\abc_search_url_text_holo.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_clear_disabled.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_clear_normal.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_go.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_search.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_voice_search.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_list_focused_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-hdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_clear_disabled.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_clear_normal.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_go.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_search.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_voice_search.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_list_focused_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-mdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_clear_disabled.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_clear_normal.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_go.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_search.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_voice_search.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_list_focused_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xhdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_clear_disabled.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_clear_normal.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_go.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_search.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_voice_search.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_list_focused_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable-xxhdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_ic_clear.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_ic_clear_holo_light.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_item_background_holo_dark.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_item_background_holo_light.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_list_selector_background_transition_holo_dark.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_list_selector_background_transition_holo_light.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_list_selector_holo_dark.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_list_selector_holo_light.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_search_dropdown_dark.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_search_dropdown_light.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_spinner_ab_holo_dark.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_spinner_ab_holo_light.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_tab_indicator_ab_holo.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_textfield_searchview_holo_dark.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_textfield_searchview_holo_light.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_textfield_searchview_right_holo_dark.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\drawable\abc_textfield_searchview_right_holo_light.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout-v11\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout-v11\abc_action_bar_decor.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout-v11\abc_simple_decor.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout-v14\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout-v14\abc_activity_chooser_view.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_bar_decor.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_bar_decor_include.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_bar_decor_overlay.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_bar_home.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_bar_tab.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_bar_tabbar.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_bar_title_item.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_bar_view_list_nav_layout.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_menu_item_layout.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_menu_layout.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_mode_bar.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_action_mode_close_item.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_activity_chooser_view.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_activity_chooser_view_include.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_activity_chooser_view_list_item.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_expanded_menu_layout.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_list_menu_item_checkbox.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_list_menu_item_icon.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_list_menu_item_layout.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_list_menu_item_radio.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_popup_menu_item_layout.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_search_dropdown_item_icons_2line.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_search_view.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\abc_simple_decor.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\layout\support_simple_spinner_dropdown_item.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-af\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-af\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-am\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-am\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ar\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ar\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-bg\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-bg\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ca\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ca\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-cs\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-cs\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-da\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-da\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-de\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-de\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-el\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-el\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-en-rGB\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-en-rGB\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-en-rIN\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-en-rIN\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-es-rUS\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-es-rUS\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-es\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-es\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-et-rEE\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-et-rEE\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-fa\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-fa\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-fi\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-fi\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-fr-rCA\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-fr-rCA\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-fr\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-fr\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-hi\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-hi\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-hr\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-hr\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-hu\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-hu\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-hy-rAM\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-hy-rAM\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-in\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-in\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-it\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-it\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-iw\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-iw\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ja\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ja\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ka-rGE\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ka-rGE\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-km-rKH\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-km-rKH\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ko\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ko\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-land\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-land\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-large-v14\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-large-v14\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-large\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-large\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-lo-rLA\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-lo-rLA\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-lt\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-lt\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-lv\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-lv\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-mn-rMN\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-mn-rMN\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ms-rMY\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ms-rMY\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-nb\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-nb\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-nl\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-nl\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-pl\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-pl\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-pt-rPT\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-pt-rPT\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-pt\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-pt\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ro\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ro\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ru\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-ru\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sk\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sk\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sl\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sl\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sr\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sr\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sv\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sv\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sw600dp\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sw600dp\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sw\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-sw\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-th\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-th\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-tl\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-tl\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-tr\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-tr\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-uk\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-uk\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-v11\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-v11\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-v14\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-v14\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-vi\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-vi\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-w360dp\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-w360dp\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-w480dp\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-w480dp\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-w500dp\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-w500dp\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-w600dp\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-w600dp\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-w720dp\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-w720dp\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-xlarge\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-xlarge\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-zh-rCN\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-zh-rCN\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-zh-rHK\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-zh-rHK\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-zh-rTW\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-zh-rTW\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-zu\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values-zu\values.xml +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values\ +* app\build\intermediates\exploded-aar\com.android.support\appcompat-v7\19.1.0\res\values\values.xml +* app\build\intermediates\incremental\ +* app\build\intermediates\incremental\aidl\ +* app\build\intermediates\incremental\aidl\androidTest\ +* app\build\intermediates\incremental\aidl\androidTest\debug\ +* app\build\intermediates\incremental\aidl\androidTest\debug\dependency.store +* app\build\intermediates\incremental\aidl\debug\ +* app\build\intermediates\incremental\aidl\debug\dependency.store +* app\build\intermediates\incremental\mergeAssets\ +* app\build\intermediates\incremental\mergeAssets\androidTest\ +* app\build\intermediates\incremental\mergeAssets\androidTest\debug\ +* app\build\intermediates\incremental\mergeAssets\androidTest\debug\merger.xml +* app\build\intermediates\incremental\mergeAssets\debug\ +* app\build\intermediates\incremental\mergeAssets\debug\merger.xml +* app\build\intermediates\incremental\mergeResources\ +* app\build\intermediates\incremental\mergeResources\androidTest\ +* app\build\intermediates\incremental\mergeResources\androidTest\debug\ +* app\build\intermediates\incremental\mergeResources\androidTest\debug\merger.xml +* app\build\intermediates\incremental\mergeResources\debug\ +* app\build\intermediates\incremental\mergeResources\debug\merger.xml +* app\build\intermediates\incremental\packageResources\ +* app\build\intermediates\incremental\packageResources\debug\ +* app\build\intermediates\incremental\packageResources\debug\merger.xml +* app\build\intermediates\manifests\ +* app\build\intermediates\manifests\androidTest\ +* app\build\intermediates\manifests\androidTest\debug\ +* app\build\intermediates\manifests\androidTest\debug\AndroidManifest.xml +* app\build\intermediates\manifests\tmp\ +* app\build\intermediates\manifests\tmp\manifestMerger2383964013971591643.xml +* app\build\intermediates\res\ +* app\build\intermediates\res\androidTest\ +* app\build\intermediates\res\androidTest\debug\ +* app\build\intermediates\res\androidTest\debug\anim\ +* app\build\intermediates\res\androidTest\debug\anim\abc_fade_in.xml +* app\build\intermediates\res\androidTest\debug\anim\abc_fade_out.xml +* app\build\intermediates\res\androidTest\debug\anim\abc_slide_in_bottom.xml +* app\build\intermediates\res\androidTest\debug\anim\abc_slide_in_top.xml +* app\build\intermediates\res\androidTest\debug\anim\abc_slide_out_bottom.xml +* app\build\intermediates\res\androidTest\debug\anim\abc_slide_out_top.xml +* app\build\intermediates\res\androidTest\debug\color\ +* app\build\intermediates\res\androidTest\debug\color\abc_search_url_text_holo.xml +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\ +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_clear_disabled.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_clear_normal.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_go.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_search.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_voice_search.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_list_focused_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-hdpi\ic_launcher.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\ +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_clear_disabled.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_clear_normal.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_go.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_search.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_voice_search.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_list_focused_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-mdpi\ic_launcher.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\ +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_clear_disabled.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_clear_normal.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_go.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_search.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_voice_search.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_list_focused_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xhdpi\ic_launcher.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\ +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_clear_disabled.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_clear_normal.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_go.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_search.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_voice_search.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_list_focused_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\res\androidTest\debug\drawable-xxhdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\res\androidTest\debug\drawable\ +* app\build\intermediates\res\androidTest\debug\drawable\abc_ic_clear.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_ic_clear_holo_light.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_item_background_holo_dark.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_item_background_holo_light.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_list_selector_background_transition_holo_dark.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_list_selector_background_transition_holo_light.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_list_selector_holo_dark.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_list_selector_holo_light.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_search_dropdown_dark.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_search_dropdown_light.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_spinner_ab_holo_dark.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_spinner_ab_holo_light.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_tab_indicator_ab_holo.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_textfield_searchview_holo_dark.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_textfield_searchview_holo_light.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_textfield_searchview_right_holo_dark.xml +* app\build\intermediates\res\androidTest\debug\drawable\abc_textfield_searchview_right_holo_light.xml +* app\build\intermediates\res\androidTest\debug\layout-v11\ +* app\build\intermediates\res\androidTest\debug\layout-v11\abc_action_bar_decor.xml +* app\build\intermediates\res\androidTest\debug\layout-v11\abc_simple_decor.xml +* app\build\intermediates\res\androidTest\debug\layout-v14\ +* app\build\intermediates\res\androidTest\debug\layout-v14\abc_activity_chooser_view.xml +* app\build\intermediates\res\androidTest\debug\layout\ +* app\build\intermediates\res\androidTest\debug\layout\abc_action_bar_decor.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_bar_decor_include.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_bar_decor_overlay.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_bar_home.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_bar_tab.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_bar_tabbar.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_bar_title_item.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_bar_view_list_nav_layout.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_menu_item_layout.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_menu_layout.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_mode_bar.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_action_mode_close_item.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_activity_chooser_view.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_activity_chooser_view_include.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_activity_chooser_view_list_item.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_expanded_menu_layout.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_list_menu_item_checkbox.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_list_menu_item_icon.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_list_menu_item_layout.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_list_menu_item_radio.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_popup_menu_item_layout.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_search_dropdown_item_icons_2line.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_search_view.xml +* app\build\intermediates\res\androidTest\debug\layout\abc_simple_decor.xml +* app\build\intermediates\res\androidTest\debug\layout\support_simple_spinner_dropdown_item.xml +* app\build\intermediates\res\androidTest\debug\menu\ +* app\build\intermediates\res\androidTest\debug\menu\install_utility.xml +* app\build\intermediates\res\androidTest\debug\values-af\ +* app\build\intermediates\res\androidTest\debug\values-af\values-af.xml +* app\build\intermediates\res\androidTest\debug\values-am\ +* app\build\intermediates\res\androidTest\debug\values-am\values-am.xml +* app\build\intermediates\res\androidTest\debug\values-ar\ +* app\build\intermediates\res\androidTest\debug\values-ar\values-ar.xml +* app\build\intermediates\res\androidTest\debug\values-bg\ +* app\build\intermediates\res\androidTest\debug\values-bg\values-bg.xml +* app\build\intermediates\res\androidTest\debug\values-ca\ +* app\build\intermediates\res\androidTest\debug\values-ca\values-ca.xml +* app\build\intermediates\res\androidTest\debug\values-cs\ +* app\build\intermediates\res\androidTest\debug\values-cs\values-cs.xml +* app\build\intermediates\res\androidTest\debug\values-da\ +* app\build\intermediates\res\androidTest\debug\values-da\values-da.xml +* app\build\intermediates\res\androidTest\debug\values-de\ +* app\build\intermediates\res\androidTest\debug\values-de\values-de.xml +* app\build\intermediates\res\androidTest\debug\values-el\ +* app\build\intermediates\res\androidTest\debug\values-el\values-el.xml +* app\build\intermediates\res\androidTest\debug\values-en-rGB\ +* app\build\intermediates\res\androidTest\debug\values-en-rGB\values-en-rGB.xml +* app\build\intermediates\res\androidTest\debug\values-en-rIN\ +* app\build\intermediates\res\androidTest\debug\values-en-rIN\values-en-rIN.xml +* app\build\intermediates\res\androidTest\debug\values-es-rUS\ +* app\build\intermediates\res\androidTest\debug\values-es-rUS\values-es-rUS.xml +* app\build\intermediates\res\androidTest\debug\values-es\ +* app\build\intermediates\res\androidTest\debug\values-es\values-es.xml +* app\build\intermediates\res\androidTest\debug\values-et-rEE\ +* app\build\intermediates\res\androidTest\debug\values-et-rEE\values-et-rEE.xml +* app\build\intermediates\res\androidTest\debug\values-fa\ +* app\build\intermediates\res\androidTest\debug\values-fa\values-fa.xml +* app\build\intermediates\res\androidTest\debug\values-fi\ +* app\build\intermediates\res\androidTest\debug\values-fi\values-fi.xml +* app\build\intermediates\res\androidTest\debug\values-fr-rCA\ +* app\build\intermediates\res\androidTest\debug\values-fr-rCA\values-fr-rCA.xml +* app\build\intermediates\res\androidTest\debug\values-fr\ +* app\build\intermediates\res\androidTest\debug\values-fr\values-fr.xml +* app\build\intermediates\res\androidTest\debug\values-hi\ +* app\build\intermediates\res\androidTest\debug\values-hi\values-hi.xml +* app\build\intermediates\res\androidTest\debug\values-hr\ +* app\build\intermediates\res\androidTest\debug\values-hr\values-hr.xml +* app\build\intermediates\res\androidTest\debug\values-hu\ +* app\build\intermediates\res\androidTest\debug\values-hu\values-hu.xml +* app\build\intermediates\res\androidTest\debug\values-hy-rAM\ +* app\build\intermediates\res\androidTest\debug\values-hy-rAM\values-hy-rAM.xml +* app\build\intermediates\res\androidTest\debug\values-in\ +* app\build\intermediates\res\androidTest\debug\values-in\values-in.xml +* app\build\intermediates\res\androidTest\debug\values-it\ +* app\build\intermediates\res\androidTest\debug\values-it\values-it.xml +* app\build\intermediates\res\androidTest\debug\values-iw\ +* app\build\intermediates\res\androidTest\debug\values-iw\values-iw.xml +* app\build\intermediates\res\androidTest\debug\values-ja\ +* app\build\intermediates\res\androidTest\debug\values-ja\values-ja.xml +* app\build\intermediates\res\androidTest\debug\values-ka-rGE\ +* app\build\intermediates\res\androidTest\debug\values-ka-rGE\values-ka-rGE.xml +* app\build\intermediates\res\androidTest\debug\values-km-rKH\ +* app\build\intermediates\res\androidTest\debug\values-km-rKH\values-km-rKH.xml +* app\build\intermediates\res\androidTest\debug\values-ko\ +* app\build\intermediates\res\androidTest\debug\values-ko\values-ko.xml +* app\build\intermediates\res\androidTest\debug\values-land\ +* app\build\intermediates\res\androidTest\debug\values-land\values-land.xml +* app\build\intermediates\res\androidTest\debug\values-large-v14\ +* app\build\intermediates\res\androidTest\debug\values-large-v14\values-large-v14.xml +* app\build\intermediates\res\androidTest\debug\values-large\ +* app\build\intermediates\res\androidTest\debug\values-large\values-large.xml +* app\build\intermediates\res\androidTest\debug\values-lo-rLA\ +* app\build\intermediates\res\androidTest\debug\values-lo-rLA\values-lo-rLA.xml +* app\build\intermediates\res\androidTest\debug\values-lt\ +* app\build\intermediates\res\androidTest\debug\values-lt\values-lt.xml +* app\build\intermediates\res\androidTest\debug\values-lv\ +* app\build\intermediates\res\androidTest\debug\values-lv\values-lv.xml +* app\build\intermediates\res\androidTest\debug\values-mn-rMN\ +* app\build\intermediates\res\androidTest\debug\values-mn-rMN\values-mn-rMN.xml +* app\build\intermediates\res\androidTest\debug\values-ms-rMY\ +* app\build\intermediates\res\androidTest\debug\values-ms-rMY\values-ms-rMY.xml +* app\build\intermediates\res\androidTest\debug\values-nb\ +* app\build\intermediates\res\androidTest\debug\values-nb\values-nb.xml +* app\build\intermediates\res\androidTest\debug\values-nl\ +* app\build\intermediates\res\androidTest\debug\values-nl\values-nl.xml +* app\build\intermediates\res\androidTest\debug\values-pl\ +* app\build\intermediates\res\androidTest\debug\values-pl\values-pl.xml +* app\build\intermediates\res\androidTest\debug\values-pt-rPT\ +* app\build\intermediates\res\androidTest\debug\values-pt-rPT\values-pt-rPT.xml +* app\build\intermediates\res\androidTest\debug\values-pt\ +* app\build\intermediates\res\androidTest\debug\values-pt\values-pt.xml +* app\build\intermediates\res\androidTest\debug\values-ro\ +* app\build\intermediates\res\androidTest\debug\values-ro\values-ro.xml +* app\build\intermediates\res\androidTest\debug\values-ru\ +* app\build\intermediates\res\androidTest\debug\values-ru\values-ru.xml +* app\build\intermediates\res\androidTest\debug\values-sk\ +* app\build\intermediates\res\androidTest\debug\values-sk\values-sk.xml +* app\build\intermediates\res\androidTest\debug\values-sl\ +* app\build\intermediates\res\androidTest\debug\values-sl\values-sl.xml +* app\build\intermediates\res\androidTest\debug\values-sr\ +* app\build\intermediates\res\androidTest\debug\values-sr\values-sr.xml +* app\build\intermediates\res\androidTest\debug\values-sv\ +* app\build\intermediates\res\androidTest\debug\values-sv\values-sv.xml +* app\build\intermediates\res\androidTest\debug\values-sw600dp\ +* app\build\intermediates\res\androidTest\debug\values-sw600dp\values-sw600dp.xml +* app\build\intermediates\res\androidTest\debug\values-sw720dp-land\ +* app\build\intermediates\res\androidTest\debug\values-sw720dp-land\values-sw720dp-land.xml +* app\build\intermediates\res\androidTest\debug\values-sw\ +* app\build\intermediates\res\androidTest\debug\values-sw\values-sw.xml +* app\build\intermediates\res\androidTest\debug\values-th\ +* app\build\intermediates\res\androidTest\debug\values-th\values-th.xml +* app\build\intermediates\res\androidTest\debug\values-tl\ +* app\build\intermediates\res\androidTest\debug\values-tl\values-tl.xml +* app\build\intermediates\res\androidTest\debug\values-tr\ +* app\build\intermediates\res\androidTest\debug\values-tr\values-tr.xml +* app\build\intermediates\res\androidTest\debug\values-uk\ +* app\build\intermediates\res\androidTest\debug\values-uk\values-uk.xml +* app\build\intermediates\res\androidTest\debug\values-v11\ +* app\build\intermediates\res\androidTest\debug\values-v11\values-v11.xml +* app\build\intermediates\res\androidTest\debug\values-v14\ +* app\build\intermediates\res\androidTest\debug\values-v14\values-v14.xml +* app\build\intermediates\res\androidTest\debug\values-vi\ +* app\build\intermediates\res\androidTest\debug\values-vi\values-vi.xml +* app\build\intermediates\res\androidTest\debug\values-w360dp\ +* app\build\intermediates\res\androidTest\debug\values-w360dp\values-w360dp.xml +* app\build\intermediates\res\androidTest\debug\values-w480dp\ +* app\build\intermediates\res\androidTest\debug\values-w480dp\values-w480dp.xml +* app\build\intermediates\res\androidTest\debug\values-w500dp\ +* app\build\intermediates\res\androidTest\debug\values-w500dp\values-w500dp.xml +* app\build\intermediates\res\androidTest\debug\values-w600dp\ +* app\build\intermediates\res\androidTest\debug\values-w600dp\values-w600dp.xml +* app\build\intermediates\res\androidTest\debug\values-w720dp\ +* app\build\intermediates\res\androidTest\debug\values-w720dp\values-w720dp.xml +* app\build\intermediates\res\androidTest\debug\values-xlarge\ +* app\build\intermediates\res\androidTest\debug\values-xlarge\values-xlarge.xml +* app\build\intermediates\res\androidTest\debug\values-zh-rCN\ +* app\build\intermediates\res\androidTest\debug\values-zh-rCN\values-zh-rCN.xml +* app\build\intermediates\res\androidTest\debug\values-zh-rHK\ +* app\build\intermediates\res\androidTest\debug\values-zh-rHK\values-zh-rHK.xml +* app\build\intermediates\res\androidTest\debug\values-zh-rTW\ +* app\build\intermediates\res\androidTest\debug\values-zh-rTW\values-zh-rTW.xml +* app\build\intermediates\res\androidTest\debug\values-zu\ +* app\build\intermediates\res\androidTest\debug\values-zu\values-zu.xml +* app\build\intermediates\res\androidTest\debug\values\ +* app\build\intermediates\res\androidTest\debug\values\values.xml +* app\build\intermediates\res\debug\ +* app\build\intermediates\res\debug\anim\ +* app\build\intermediates\res\debug\anim\abc_fade_in.xml +* app\build\intermediates\res\debug\anim\abc_fade_out.xml +* app\build\intermediates\res\debug\anim\abc_slide_in_bottom.xml +* app\build\intermediates\res\debug\anim\abc_slide_in_top.xml +* app\build\intermediates\res\debug\anim\abc_slide_out_bottom.xml +* app\build\intermediates\res\debug\anim\abc_slide_out_top.xml +* app\build\intermediates\res\debug\color\ +* app\build\intermediates\res\debug\color\abc_search_url_text_holo.xml +* app\build\intermediates\res\debug\drawable-hdpi\ +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_clear_disabled.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_clear_normal.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_go.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_search.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_voice_search.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_list_focused_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-hdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\res\debug\drawable-hdpi\ic_launcher.png +* app\build\intermediates\res\debug\drawable-mdpi\ +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_clear_disabled.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_clear_normal.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_go.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_search.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_voice_search.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_list_focused_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-mdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\res\debug\drawable-mdpi\ic_launcher.png +* app\build\intermediates\res\debug\drawable-xhdpi\ +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_clear_disabled.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_clear_normal.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_go.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_search.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_voice_search.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_list_focused_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xhdpi\ic_launcher.png +* app\build\intermediates\res\debug\drawable-xxhdpi\ +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_bottom_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_bottom_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_bottom_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_bottom_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_share_pack_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_share_pack_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_stacked_solid_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_stacked_solid_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_stacked_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_stacked_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_transparent_dark_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ab_transparent_light_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_cab_background_bottom_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_cab_background_bottom_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_cab_background_top_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_cab_background_top_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_ab_back_holo_dark.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_ab_back_holo_light.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_cab_done_holo_dark.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_cab_done_holo_light.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_clear_disabled.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_clear_normal.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_clear_search_api_disabled_holo_light.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_clear_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_commit_search_api_holo_dark.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_commit_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_go.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_go_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_menu_moreoverflow_normal_holo_dark.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_menu_moreoverflow_normal_holo_light.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_menu_share_holo_dark.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_menu_share_holo_light.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_search.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_voice_search.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_ic_voice_search_api_holo_light.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_list_divider_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_list_divider_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_list_focused_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_list_longpressed_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_list_pressed_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_list_pressed_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_list_selector_disabled_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_list_selector_disabled_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_menu_dropdown_panel_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_menu_dropdown_panel_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_menu_hardkey_panel_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_menu_hardkey_panel_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_spinner_ab_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_spinner_ab_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_spinner_ab_disabled_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_spinner_ab_disabled_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_spinner_ab_focused_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_spinner_ab_focused_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_spinner_ab_pressed_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_spinner_ab_pressed_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_tab_selected_focused_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_tab_selected_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_tab_selected_pressed_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_tab_unselected_pressed_holo.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_textfield_search_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_textfield_search_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_textfield_search_right_default_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_textfield_search_right_default_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_textfield_search_right_selected_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_textfield_search_right_selected_holo_light.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_textfield_search_selected_holo_dark.9.png +* app\build\intermediates\res\debug\drawable-xxhdpi\abc_textfield_search_selected_holo_light.9.png +* app\build\intermediates\res\debug\drawable\ +* app\build\intermediates\res\debug\drawable\abc_ic_clear.xml +* app\build\intermediates\res\debug\drawable\abc_ic_clear_holo_light.xml +* app\build\intermediates\res\debug\drawable\abc_item_background_holo_dark.xml +* app\build\intermediates\res\debug\drawable\abc_item_background_holo_light.xml +* app\build\intermediates\res\debug\drawable\abc_list_selector_background_transition_holo_dark.xml +* app\build\intermediates\res\debug\drawable\abc_list_selector_background_transition_holo_light.xml +* app\build\intermediates\res\debug\drawable\abc_list_selector_holo_dark.xml +* app\build\intermediates\res\debug\drawable\abc_list_selector_holo_light.xml +* app\build\intermediates\res\debug\drawable\abc_search_dropdown_dark.xml +* app\build\intermediates\res\debug\drawable\abc_search_dropdown_light.xml +* app\build\intermediates\res\debug\drawable\abc_spinner_ab_holo_dark.xml +* app\build\intermediates\res\debug\drawable\abc_spinner_ab_holo_light.xml +* app\build\intermediates\res\debug\drawable\abc_tab_indicator_ab_holo.xml +* app\build\intermediates\res\debug\drawable\abc_textfield_searchview_holo_dark.xml +* app\build\intermediates\res\debug\drawable\abc_textfield_searchview_holo_light.xml +* app\build\intermediates\res\debug\drawable\abc_textfield_searchview_right_holo_dark.xml +* app\build\intermediates\res\debug\drawable\abc_textfield_searchview_right_holo_light.xml +* app\build\intermediates\res\debug\layout-v11\ +* app\build\intermediates\res\debug\layout-v11\abc_action_bar_decor.xml +* app\build\intermediates\res\debug\layout-v11\abc_simple_decor.xml +* app\build\intermediates\res\debug\layout-v14\ +* app\build\intermediates\res\debug\layout-v14\abc_activity_chooser_view.xml +* app\build\intermediates\res\debug\layout\ +* app\build\intermediates\res\debug\layout\abc_action_bar_decor.xml +* app\build\intermediates\res\debug\layout\abc_action_bar_decor_include.xml +* app\build\intermediates\res\debug\layout\abc_action_bar_decor_overlay.xml +* app\build\intermediates\res\debug\layout\abc_action_bar_home.xml +* app\build\intermediates\res\debug\layout\abc_action_bar_tab.xml +* app\build\intermediates\res\debug\layout\abc_action_bar_tabbar.xml +* app\build\intermediates\res\debug\layout\abc_action_bar_title_item.xml +* app\build\intermediates\res\debug\layout\abc_action_bar_view_list_nav_layout.xml +* app\build\intermediates\res\debug\layout\abc_action_menu_item_layout.xml +* app\build\intermediates\res\debug\layout\abc_action_menu_layout.xml +* app\build\intermediates\res\debug\layout\abc_action_mode_bar.xml +* app\build\intermediates\res\debug\layout\abc_action_mode_close_item.xml +* app\build\intermediates\res\debug\layout\abc_activity_chooser_view.xml +* app\build\intermediates\res\debug\layout\abc_activity_chooser_view_include.xml +* app\build\intermediates\res\debug\layout\abc_activity_chooser_view_list_item.xml +* app\build\intermediates\res\debug\layout\abc_expanded_menu_layout.xml +* app\build\intermediates\res\debug\layout\abc_list_menu_item_checkbox.xml +* app\build\intermediates\res\debug\layout\abc_list_menu_item_icon.xml +* app\build\intermediates\res\debug\layout\abc_list_menu_item_layout.xml +* app\build\intermediates\res\debug\layout\abc_list_menu_item_radio.xml +* app\build\intermediates\res\debug\layout\abc_popup_menu_item_layout.xml +* app\build\intermediates\res\debug\layout\abc_search_dropdown_item_icons_2line.xml +* app\build\intermediates\res\debug\layout\abc_search_view.xml +* app\build\intermediates\res\debug\layout\abc_simple_decor.xml +* app\build\intermediates\res\debug\layout\support_simple_spinner_dropdown_item.xml +* app\build\intermediates\res\debug\menu\ +* app\build\intermediates\res\debug\menu\install_utility.xml +* app\build\intermediates\res\debug\values-af\ +* app\build\intermediates\res\debug\values-af\values-af.xml +* app\build\intermediates\res\debug\values-am\ +* app\build\intermediates\res\debug\values-am\values-am.xml +* app\build\intermediates\res\debug\values-ar\ +* app\build\intermediates\res\debug\values-ar\values-ar.xml +* app\build\intermediates\res\debug\values-bg\ +* app\build\intermediates\res\debug\values-bg\values-bg.xml +* app\build\intermediates\res\debug\values-ca\ +* app\build\intermediates\res\debug\values-ca\values-ca.xml +* app\build\intermediates\res\debug\values-cs\ +* app\build\intermediates\res\debug\values-cs\values-cs.xml +* app\build\intermediates\res\debug\values-da\ +* app\build\intermediates\res\debug\values-da\values-da.xml +* app\build\intermediates\res\debug\values-de\ +* app\build\intermediates\res\debug\values-de\values-de.xml +* app\build\intermediates\res\debug\values-el\ +* app\build\intermediates\res\debug\values-el\values-el.xml +* app\build\intermediates\res\debug\values-en-rGB\ +* app\build\intermediates\res\debug\values-en-rGB\values-en-rGB.xml +* app\build\intermediates\res\debug\values-en-rIN\ +* app\build\intermediates\res\debug\values-en-rIN\values-en-rIN.xml +* app\build\intermediates\res\debug\values-es-rUS\ +* app\build\intermediates\res\debug\values-es-rUS\values-es-rUS.xml +* app\build\intermediates\res\debug\values-es\ +* app\build\intermediates\res\debug\values-es\values-es.xml +* app\build\intermediates\res\debug\values-et-rEE\ +* app\build\intermediates\res\debug\values-et-rEE\values-et-rEE.xml +* app\build\intermediates\res\debug\values-fa\ +* app\build\intermediates\res\debug\values-fa\values-fa.xml +* app\build\intermediates\res\debug\values-fi\ +* app\build\intermediates\res\debug\values-fi\values-fi.xml +* app\build\intermediates\res\debug\values-fr-rCA\ +* app\build\intermediates\res\debug\values-fr-rCA\values-fr-rCA.xml +* app\build\intermediates\res\debug\values-fr\ +* app\build\intermediates\res\debug\values-fr\values-fr.xml +* app\build\intermediates\res\debug\values-hi\ +* app\build\intermediates\res\debug\values-hi\values-hi.xml +* app\build\intermediates\res\debug\values-hr\ +* app\build\intermediates\res\debug\values-hr\values-hr.xml +* app\build\intermediates\res\debug\values-hu\ +* app\build\intermediates\res\debug\values-hu\values-hu.xml +* app\build\intermediates\res\debug\values-hy-rAM\ +* app\build\intermediates\res\debug\values-hy-rAM\values-hy-rAM.xml +* app\build\intermediates\res\debug\values-in\ +* app\build\intermediates\res\debug\values-in\values-in.xml +* app\build\intermediates\res\debug\values-it\ +* app\build\intermediates\res\debug\values-it\values-it.xml +* app\build\intermediates\res\debug\values-iw\ +* app\build\intermediates\res\debug\values-iw\values-iw.xml +* app\build\intermediates\res\debug\values-ja\ +* app\build\intermediates\res\debug\values-ja\values-ja.xml +* app\build\intermediates\res\debug\values-ka-rGE\ +* app\build\intermediates\res\debug\values-ka-rGE\values-ka-rGE.xml +* app\build\intermediates\res\debug\values-km-rKH\ +* app\build\intermediates\res\debug\values-km-rKH\values-km-rKH.xml +* app\build\intermediates\res\debug\values-ko\ +* app\build\intermediates\res\debug\values-ko\values-ko.xml +* app\build\intermediates\res\debug\values-land\ +* app\build\intermediates\res\debug\values-land\values-land.xml +* app\build\intermediates\res\debug\values-large-v14\ +* app\build\intermediates\res\debug\values-large-v14\values-large-v14.xml +* app\build\intermediates\res\debug\values-large\ +* app\build\intermediates\res\debug\values-large\values-large.xml +* app\build\intermediates\res\debug\values-lo-rLA\ +* app\build\intermediates\res\debug\values-lo-rLA\values-lo-rLA.xml +* app\build\intermediates\res\debug\values-lt\ +* app\build\intermediates\res\debug\values-lt\values-lt.xml +* app\build\intermediates\res\debug\values-lv\ +* app\build\intermediates\res\debug\values-lv\values-lv.xml +* app\build\intermediates\res\debug\values-mn-rMN\ +* app\build\intermediates\res\debug\values-mn-rMN\values-mn-rMN.xml +* app\build\intermediates\res\debug\values-ms-rMY\ +* app\build\intermediates\res\debug\values-ms-rMY\values-ms-rMY.xml +* app\build\intermediates\res\debug\values-nb\ +* app\build\intermediates\res\debug\values-nb\values-nb.xml +* app\build\intermediates\res\debug\values-nl\ +* app\build\intermediates\res\debug\values-nl\values-nl.xml +* app\build\intermediates\res\debug\values-pl\ +* app\build\intermediates\res\debug\values-pl\values-pl.xml +* app\build\intermediates\res\debug\values-pt-rPT\ +* app\build\intermediates\res\debug\values-pt-rPT\values-pt-rPT.xml +* app\build\intermediates\res\debug\values-pt\ +* app\build\intermediates\res\debug\values-pt\values-pt.xml +* app\build\intermediates\res\debug\values-ro\ +* app\build\intermediates\res\debug\values-ro\values-ro.xml +* app\build\intermediates\res\debug\values-ru\ +* app\build\intermediates\res\debug\values-ru\values-ru.xml +* app\build\intermediates\res\debug\values-sk\ +* app\build\intermediates\res\debug\values-sk\values-sk.xml +* app\build\intermediates\res\debug\values-sl\ +* app\build\intermediates\res\debug\values-sl\values-sl.xml +* app\build\intermediates\res\debug\values-sr\ +* app\build\intermediates\res\debug\values-sr\values-sr.xml +* app\build\intermediates\res\debug\values-sv\ +* app\build\intermediates\res\debug\values-sv\values-sv.xml +* app\build\intermediates\res\debug\values-sw600dp\ +* app\build\intermediates\res\debug\values-sw600dp\values-sw600dp.xml +* app\build\intermediates\res\debug\values-sw720dp-land\ +* app\build\intermediates\res\debug\values-sw720dp-land\values-sw720dp-land.xml +* app\build\intermediates\res\debug\values-sw\ +* app\build\intermediates\res\debug\values-sw\values-sw.xml +* app\build\intermediates\res\debug\values-th\ +* app\build\intermediates\res\debug\values-th\values-th.xml +* app\build\intermediates\res\debug\values-tl\ +* app\build\intermediates\res\debug\values-tl\values-tl.xml +* app\build\intermediates\res\debug\values-tr\ +* app\build\intermediates\res\debug\values-tr\values-tr.xml +* app\build\intermediates\res\debug\values-uk\ +* app\build\intermediates\res\debug\values-uk\values-uk.xml +* app\build\intermediates\res\debug\values-v11\ +* app\build\intermediates\res\debug\values-v11\values-v11.xml +* app\build\intermediates\res\debug\values-v14\ +* app\build\intermediates\res\debug\values-v14\values-v14.xml +* app\build\intermediates\res\debug\values-vi\ +* app\build\intermediates\res\debug\values-vi\values-vi.xml +* app\build\intermediates\res\debug\values-w360dp\ +* app\build\intermediates\res\debug\values-w360dp\values-w360dp.xml +* app\build\intermediates\res\debug\values-w480dp\ +* app\build\intermediates\res\debug\values-w480dp\values-w480dp.xml +* app\build\intermediates\res\debug\values-w500dp\ +* app\build\intermediates\res\debug\values-w500dp\values-w500dp.xml +* app\build\intermediates\res\debug\values-w600dp\ +* app\build\intermediates\res\debug\values-w600dp\values-w600dp.xml +* app\build\intermediates\res\debug\values-w720dp\ +* app\build\intermediates\res\debug\values-w720dp\values-w720dp.xml +* app\build\intermediates\res\debug\values-xlarge\ +* app\build\intermediates\res\debug\values-xlarge\values-xlarge.xml +* app\build\intermediates\res\debug\values-zh-rCN\ +* app\build\intermediates\res\debug\values-zh-rCN\values-zh-rCN.xml +* app\build\intermediates\res\debug\values-zh-rHK\ +* app\build\intermediates\res\debug\values-zh-rHK\values-zh-rHK.xml +* app\build\intermediates\res\debug\values-zh-rTW\ +* app\build\intermediates\res\debug\values-zh-rTW\values-zh-rTW.xml +* app\build\intermediates\res\debug\values-zu\ +* app\build\intermediates\res\debug\values-zu\values-zu.xml +* app\build\intermediates\res\debug\values\ +* app\build\intermediates\res\debug\values\values.xml +* app\build\intermediates\resources\ +* app\build\intermediates\resources\resources-debug-androidTest.ap_ +* app\build\intermediates\symbols\ +* app\build\intermediates\symbols\androidTest\ +* app\build\intermediates\symbols\androidTest\debug\ +* app\build\intermediates\symbols\androidTest\debug\R.txt +* app\build\outputs\ +* app\build\outputs\aar\ +* app\build\outputs\aar\app-debug.aar +* app\build\tmp\ +* app\build\tmp\packageDebugJar\ +* app\build\tmp\packageDebugJar\MANIFEST.MF +* app\src\ +* app\src\main\ +* app\src\main\AndroidManifest.xml +* app\src\main\java\ +* app\src\main\java\com\ +* app\src\main\java\com\inputstick\ +* app\src\main\java\com\inputstick\api\ +* app\src\main\java\com\inputstick\api\AES.java +* app\src\main\java\com\inputstick\api\BTConnectionManager.java +* app\src\main\java\com\inputstick\api\ConnectionManager.java +* app\src\main\java\com\inputstick\api\DownloadDialog.java +* app\src\main\java\com\inputstick\api\HIDInfo.java +* app\src\main\java\com\inputstick\api\IPCConnectionManager.java +* app\src\main\java\com\inputstick\api\InputStickDataListener.java +* app\src\main\java\com\inputstick\api\InputStickError.java +* app\src\main\java\com\inputstick\api\InputStickKeyboardListener.java +* app\src\main\java\com\inputstick\api\InputStickStateListener.java +* app\src\main\java\com\inputstick\api\OnEmptyBufferListener.java +* app\src\main\java\com\inputstick\api\Packet.java +* app\src\main\java\com\inputstick\api\PacketManager.java +* app\src\main\java\com\inputstick\api\Util.java +* app\src\main\java\com\inputstick\api\basic\ +* app\src\main\java\com\inputstick\api\basic\InputStickConsumer.java +* app\src\main\java\com\inputstick\api\basic\InputStickGamepad.java +* app\src\main\java\com\inputstick\api\basic\InputStickHID.java +* app\src\main\java\com\inputstick\api\basic\InputStickKeyboard.java +* app\src\main\java\com\inputstick\api\basic\InputStickMouse.java +* app\src\main\java\com\inputstick\api\bluetooth\ +* app\src\main\java\com\inputstick\api\bluetooth\BT20Connection.java +* app\src\main\java\com\inputstick\api\bluetooth\BT40Connection.java +* app\src\main\java\com\inputstick\api\bluetooth\BTConnection.java +* app\src\main\java\com\inputstick\api\bluetooth\BTService.java +* app\src\main\java\com\inputstick\api\bluetooth\PacketReader.java +* app\src\main\java\com\inputstick\api\broadcast\ +* app\src\main\java\com\inputstick\api\broadcast\InputStickBroadcast.java +* app\src\main\java\com\inputstick\api\hid\ +* app\src\main\java\com\inputstick\api\hid\ConsumerReport.java +* app\src\main\java\com\inputstick\api\hid\GamepadReport.java +* app\src\main\java\com\inputstick\api\hid\HIDKeycodes.java +* app\src\main\java\com\inputstick\api\hid\HIDReport.java +* app\src\main\java\com\inputstick\api\hid\HIDTransaction.java +* app\src\main\java\com\inputstick\api\hid\HIDTransactionQueue.java +* app\src\main\java\com\inputstick\api\hid\KeyboardReport.java +* app\src\main\java\com\inputstick\api\hid\MouseReport.java +* app\src\main\java\com\inputstick\api\init\ +* app\src\main\java\com\inputstick\api\init\BasicInitManager.java +* app\src\main\java\com\inputstick\api\init\DeviceInfo.java +* app\src\main\java\com\inputstick\api\init\InitManager.java +* app\src\main\java\com\inputstick\api\init\InitManagerListener.java +* app\src\main\java\com\inputstick\api\layout\ +* app\src\main\java\com\inputstick\api\layout\DanishLayout.java +* app\src\main\java\com\inputstick\api\layout\DvorakLayout.java +* app\src\main\java\com\inputstick\api\layout\FinnishLayout.java +* app\src\main\java\com\inputstick\api\layout\FrenchLayout.java +* app\src\main\java\com\inputstick\api\layout\GermanLayout.java +* app\src\main\java\com\inputstick\api\layout\GermanMacLayout.java +* app\src\main\java\com\inputstick\api\layout\HebrewLayout.java +* app\src\main\java\com\inputstick\api\layout\ItalianLayout.java +* app\src\main\java\com\inputstick\api\layout\KeyboardLayout.java +* app\src\main\java\com\inputstick\api\layout\NorwegianLayout.java +* app\src\main\java\com\inputstick\api\layout\PolishLayout.java +* app\src\main\java\com\inputstick\api\layout\PortugueseBrazilianLayout.java +* app\src\main\java\com\inputstick\api\layout\RussianLayout.java +* app\src\main\java\com\inputstick\api\layout\SlovakLayout.java +* app\src\main\java\com\inputstick\api\layout\SpanishLayout.java +* app\src\main\java\com\inputstick\api\layout\SwedishLayout.java +* app\src\main\java\com\inputstick\api\layout\SwissFrenchLayout.java +* app\src\main\java\com\inputstick\api\layout\SwissGermanLayout.java +* app\src\main\java\com\inputstick\api\layout\UnitedKingdomLayout.java +* app\src\main\java\com\inputstick\api\layout\UnitedStatesLayout.java +* app\src\main\java\com\inputstick\init\ +* app\src\main\java\com\inputstick\init\BasicInitManager.java +* app\src\main\java\com\inputstick\init\BootloaderInitManager.java +* app\src\main\java\com\inputstick\init\DeviceInfo.java +* app\src\main\java\com\inputstick\init\InitManager.java +* app\src\main\java\com\inputstick\init\InitManagerListener.java +* app\src\main\res\ +* app\src\main\res\drawable-hdpi\ +* app\src\main\res\drawable-hdpi\ic_launcher.png +* app\src\main\res\drawable-mdpi\ +* app\src\main\res\drawable-mdpi\ic_launcher.png +* app\src\main\res\drawable-xhdpi\ +* app\src\main\res\drawable-xhdpi\ic_launcher.png +* app\src\main\res\menu\ +* app\src\main\res\menu\install_utility.xml +* app\src\main\res\values-sw600dp\ +* app\src\main\res\values-sw600dp\dimens.xml +* app\src\main\res\values-sw720dp-land\ +* app\src\main\res\values-sw720dp-land\dimens.xml +* app\src\main\res\values-v11\ +* app\src\main\res\values-v11\styles.xml +* app\src\main\res\values-v14\ +* app\src\main\res\values-v14\styles.xml +* app\src\main\res\values\ +* app\src\main\res\values\dimens.xml +* app\src\main\res\values\strings.xml +* app\src\main\res\values\styles.xml +* build.gradle +* build\ +* build\intermediates\ +* build\intermediates\gradle_project_sync_data.bin +* gradle\ +* gradle\wrapper\ +* gradle\wrapper\gradle-wrapper.jar +* gradle\wrapper\gradle-wrapper.properties +* gradlew +* gradlew.bat +* import-summary.txt +* proguard-project.txt +* settings.gradle +From Keepass2AndroidPluginSDK: +* proguard-project.txt +From PluginInputStick: +* ic_launcher-web.png +* proguard-project.txt + +Replaced Jars with Dependencies: +-------------------------------- +The importer recognized the following .jar files as third party +libraries and replaced them with Gradle dependencies instead. This has +the advantage that more explicit version information is known, and the +libraries can be updated automatically. However, it is possible that +the .jar file in your project was of an older version than the +dependency we picked, which could render the project not compileable. +You can disable the jar replacement in the import wizard and try again: + +android-support-v4.jar => com.android.support:support-v4:19.1.0 +android-support-v7-appcompat.jar => com.android.support:appcompat-v7:19.1.0 + +Moved Files: +------------ +Android Gradle projects use a different directory structure than ADT +Eclipse projects. Here's how the projects were restructured: + +In InputStickAPI: +* AndroidManifest.xml => inputStickAPI\src\main\AndroidManifest.xml +* res\ => inputStickAPI\src\main\res\ +* src\ => inputStickAPI\src\main\java\ +In Keepass2AndroidPluginSDK: +* AndroidManifest.xml => keepass2AndroidPluginSDK\src\main\AndroidManifest.xml +* lint.xml => keepass2AndroidPluginSDK\lint.xml +* res\ => keepass2AndroidPluginSDK\src\main\res\ +* src\ => keepass2AndroidPluginSDK\src\main\java\ +In PluginInputStick: +* AndroidManifest.xml => pluginInputStick\src\main\AndroidManifest.xml +* res\ => pluginInputStick\src\main\res\ +* src\ => pluginInputStick\src\main\java\ + +Next Steps: +----------- +You can now build the project. The Gradle project needs network +connectivity to download dependencies. + +Bugs: +----- +If for some reason your project does not build, and you determine that +it is due to a bug or limitation of the Eclipse to Gradle importer, +please file a bug at http://b.android.com with category +Component-Tools. + +(This import summary is for your information only, and can be deleted +after import once you are satisfied with the results.) diff --git a/src/java/PluginInputStick3/inputStickAPI/build.gradle b/src/java/PluginInputStick3/inputStickAPI/build.gradle new file mode 100644 index 00000000..d8f9011c --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/build.gradle @@ -0,0 +1,23 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 19 + buildToolsVersion "23.0.0" + + defaultConfig { + minSdkVersion 9 + targetSdkVersion 19 + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } +} + +dependencies { + compile 'com.android.support:support-v4:19.1.0' + compile 'com.android.support:appcompat-v7:19.1.0' +} diff --git a/src/java/PluginInputStick3/inputStickAPI/inputStickAPI.iml b/src/java/PluginInputStick3/inputStickAPI/inputStickAPI.iml new file mode 100644 index 00000000..5ae401b3 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/inputStickAPI.iml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/AndroidManifest.xml b/src/java/PluginInputStick3/inputStickAPI/src/main/AndroidManifest.xml new file mode 100644 index 00000000..1f241d8d --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/AES.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/AES.java new file mode 100644 index 00000000..e07cadb2 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/AES.java @@ -0,0 +1,57 @@ +package com.inputstick.api; + +import java.security.MessageDigest; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public class AES { + + private Cipher mCipherEncr; + private Cipher mCipherDecr; + private SecretKeySpec mKey; + private boolean ready; + + public AES() { + ready = false; + } + + public static byte[] getMD5(String s) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + return md.digest(s.getBytes("UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public byte[] init(byte[] key) { + byte[] iv = null; + try { + mKey = new SecretKeySpec(key, "AES"); + mCipherEncr = Cipher.getInstance("AES/CBC/NoPadding"); + mCipherEncr.init(Cipher.ENCRYPT_MODE, mKey); + iv = mCipherEncr.getIV(); + Util.printHex(iv, "AES IV: "); + mCipherDecr = Cipher.getInstance("AES/CBC/NoPadding"); + mCipherDecr.init(Cipher.DECRYPT_MODE, mKey, new IvParameterSpec(iv)); + ready = true; + } catch (Exception e) { + e.printStackTrace(); + } + return iv; + } + + public byte[] encrypt(byte[] data) { + return mCipherEncr.update(data); + } + + public byte[] decrypt(byte[] data) { + return mCipherDecr.update(data); + } + + public boolean isReady() { + return ready; + } +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/BTConnectionManager.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/BTConnectionManager.java new file mode 100644 index 00000000..9c818ec8 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/BTConnectionManager.java @@ -0,0 +1,159 @@ +package com.inputstick.api; + +import java.lang.ref.WeakReference; + +import android.app.Application; +import android.os.Handler; +import android.os.Message; + +import com.inputstick.api.bluetooth.BTService; +import com.inputstick.api.init.InitManager; +import com.inputstick.api.init.InitManagerListener; + +public class BTConnectionManager extends ConnectionManager implements InitManagerListener { + + //private static final String mTag = "BTConnectionManager"; + + private String mMac; + private byte[] mKey; + private boolean mIsBT40; + + private InitManager mInitManager; + private Application mApp; + protected BTService mBTService; + private PacketManager mPacketManager; + private final BTHandler mBTHandler = new BTHandler(this); + + + + private static class BTHandler extends Handler { + private final WeakReference ref; + + BTHandler(BTConnectionManager manager) { + ref = new WeakReference(manager); + } + + @Override + public void handleMessage(Message msg) { + BTConnectionManager manager = ref.get(); + switch (msg.what) { + case BTService.EVENT_DATA: + manager.onData((byte[])msg.obj); + break; + case BTService.EVENT_CONNECTED: + manager.onConnected(); + break; + case BTService.EVENT_CANCELLED: + manager.onDisconnected(); + break; + case BTService.EVENT_ERROR: + manager.onFailure(msg.arg1); + break; + default: + manager.onFailure(InputStickError.ERROR_BLUETOOTH); + } + } + } + + private void onConnecting() { + stateNotify(ConnectionManager.STATE_CONNECTING); + } + + private void onConnected() { + stateNotify(ConnectionManager.STATE_CONNECTED); + //mInitManager.startTimeoutCountdown(InitManager.DEFAULT_INIT_TIMEOUT); + mInitManager.onConnected(); + } + + private void onDisconnected() { + stateNotify(ConnectionManager.STATE_DISCONNECTED); + mInitManager.onDisconnected(); + } + + private void onFailure(int code) { + mErrorCode = code; + stateNotify(ConnectionManager.STATE_FAILURE); + disconnect(); + } + + @Override + protected void onData(byte[] rawData) { + byte[] data; + data = mPacketManager.bytesToPacket(rawData); + if (data == null) { + //TODO failure? + return; + } + + mInitManager.onData(data); + super.onData(data); + } + + public BTConnectionManager(InitManager initManager, Application app, String mac, byte[] key, boolean isBT40) { + mInitManager = initManager; + mMac = mac; + mKey = key; + mApp = app; + mIsBT40 = isBT40; + } + + public BTConnectionManager(InitManager initManager, Application app, String mac, byte[] key) { + this(initManager, app, mac, key, false); + } + + @Override + public void connect() { + connect(false, BTService.DEFAULT_CONNECT_TIMEOUT); + } + + public void connect(boolean reflection, int timeout, boolean doNotAsk) { + mErrorCode = InputStickError.ERROR_NONE; + if (mBTService == null) { + mBTService = new BTService(mApp, mBTHandler); + mPacketManager = new PacketManager(mBTService, mKey); + mInitManager.init(this, mPacketManager); + } + mBTService.setConnectTimeout(timeout); + mBTService.enableReflection(reflection); + mBTService.connect(mMac, doNotAsk, mIsBT40); + onConnecting(); + } + + public void connect(boolean reflection, int timeout) { + connect(reflection, timeout, false); + } + + @Override + public void disconnect() { + if (mBTService != null) { + mBTService.disconnect(); + } + } + + public void disconnect(int failureCode) { + onFailure(failureCode); + } + + + @Override + public void sendPacket(Packet p) { + mPacketManager.sendPacket(p); + } + + + @Override + public void onInitReady() { + stateNotify(ConnectionManager.STATE_READY); + } + + @Override + public void onInitNotReady() { + stateNotify(ConnectionManager.STATE_CONNECTED); + } + + @Override + public void onInitFailure(int code) { + onFailure(code); + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/ConnectionManager.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/ConnectionManager.java new file mode 100644 index 00000000..82f7cc67 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/ConnectionManager.java @@ -0,0 +1,99 @@ +package com.inputstick.api; + +import java.util.Vector; + +public abstract class ConnectionManager { + + public static final int STATE_DISCONNECTED = 0; + public static final int STATE_FAILURE = 1; + public static final int STATE_CONNECTING = 2; + public static final int STATE_CONNECTED = 3; + public static final int STATE_READY = 4; + + + protected Vector mStateListeners = new Vector(); + protected Vector mDataListeners = new Vector(); + + protected int mState; + protected int mErrorCode; + + public abstract void connect(); + public abstract void disconnect(); + public abstract void sendPacket(Packet p); + + protected void stateNotify(int state) { + stateNotify(state, false); + } + + protected void stateNotify(int state, boolean forceNotification) { + if (( !forceNotification) && (mState == state )) { + //do nothing + } else { + //notify all listeners + mState = state; + for (InputStickStateListener listener : mStateListeners) { + listener.onStateChanged(state); + } + } + } + + public int getState() { + return mState; + } + + public boolean isReady() { + if (mState == STATE_READY) { + return true; + } else { + return false; + } + } + + public boolean isConnected() { + if ((mState == STATE_READY) || (mState == STATE_CONNECTED)) { + return true; + } else { + return false; + } + } + + public int getErrorCode() { + return mErrorCode; + } + + + protected void onData(byte[] data) { + for (InputStickDataListener listener : mDataListeners) { + listener.onInputStickData(data); + } + } + + public void addStateListener(InputStickStateListener listener) { + if (listener != null) { + if ( !mStateListeners.contains(listener)) { + mStateListeners.add(listener); + } + } + } + + public void removeStateListener(InputStickStateListener listener) { + if (listener != null) { + mStateListeners.remove(listener); + } + } + + public void addDataListener(InputStickDataListener listener) { + if (listener != null) { + if ( !mDataListeners.contains(listener)) { + mDataListeners.add(listener); + } + } + } + + public void removeDataListener(InputStickDataListener listener) { + if (listener != null) { + mDataListeners.remove(listener); + } + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/DownloadDialog.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/DownloadDialog.java new file mode 100644 index 00000000..423d205b --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/DownloadDialog.java @@ -0,0 +1,53 @@ +package com.inputstick.api; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; + +public class DownloadDialog { + + public static final int NOT_INSTALLED = 0; + public static final int NOT_UPDATED = 1; + + + public static AlertDialog getDialog(final Context ctx, final int messageCode) { + AlertDialog.Builder downloadDialog = new AlertDialog.Builder(ctx); + + if (messageCode == NOT_UPDATED) { + downloadDialog.setTitle("InputStickUtility app must be updated"); + downloadDialog.setMessage("It appears that you are using older version of InputStickUtility application. Update now (GoolePlay)?"); + } else { + downloadDialog.setTitle("InputStickUtility app NOT installed"); + downloadDialog.setMessage("InputStickUtility is required to complete this action. Download now (GoolePlay)?\nNote: InputStick USB receiver (HARDWARE!) is also required."); + } + downloadDialog.setPositiveButton("Yes", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + final String appPackageName = "com.inputstick.apps.inputstickutility"; + try { + ctx.startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("market://details?id=" + + appPackageName))); + } catch (android.content.ActivityNotFoundException anfe) { + ctx.startActivity(new Intent( + Intent.ACTION_VIEW, + Uri.parse("http://play.google.com/store/apps/details?id=" + + appPackageName))); + } + } + }); + downloadDialog.setNegativeButton("No", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + } + }); + return downloadDialog.show(); + } + + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/HIDInfo.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/HIDInfo.java new file mode 100644 index 00000000..908e4e11 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/HIDInfo.java @@ -0,0 +1,149 @@ +package com.inputstick.api; + +public class HIDInfo { + + private int state; + + private boolean numLock; + private boolean capsLock; + private boolean scrollLock; + + private boolean keyboardReportProtocol; + private boolean mouseReportProtocol; + + private boolean keyboardReady; + private boolean mouseReady; + private boolean consumerReady; + + // >= 0.93 + private boolean sentToHostInfo; + private int keyboardReportsSentToHost; + private int mouseReportsSentToHost; + private int consumerReportsSentToHost; + + public HIDInfo() { + keyboardReportProtocol = true; + mouseReportProtocol = true; + sentToHostInfo = false; + } + + public void update(byte[] data) { + state = data[1]; + + int leds = data[2]; + if ((leds & 0x01) != 0) { + numLock = true; + } else { + numLock = false; + } + if ((leds & 0x02) != 0) { + capsLock = true; + } else { + capsLock = false; + } + if ((leds & 0x04) != 0) { + scrollLock = true; + } else { + scrollLock = false; + } + + if (data[3] == 0) { + keyboardReportProtocol = true; + } else { + keyboardReportProtocol = false; + } + + if (data[4] == 0) { + keyboardReady = false; + } else { + keyboardReady = true; + } + + if (data[5] == 0) { + mouseReportProtocol = true; + } else { + mouseReportProtocol = false; + } + + if (data[6] == 0) { + mouseReady = false; + } else { + mouseReady = true; + } + + if (data[7] == 0) { + consumerReady = false; + } else { + consumerReady = true; + } + if (data.length >= 12) { + if (data[11] == (byte)0xFF) { + sentToHostInfo = true; + keyboardReportsSentToHost = data[8] & 0xFF; + mouseReportsSentToHost = data[9] & 0xFF; + consumerReportsSentToHost = data[10] & 0xFF; + } + } + } + + public void setKeyboardBusy() { + keyboardReady = false; + } + + public int getState() { + return state; + } + + public boolean getNumLock() { + return numLock; + } + + public boolean getCapsLock() { + return capsLock; + } + + public boolean getScrollLock() { + return scrollLock; + } + + public boolean isKeyboardReportProtocol() { + return keyboardReportProtocol; + } + + public boolean isMouseReportProtocol() { + return mouseReportProtocol; + } + + public boolean isKeyboardReady() { + return keyboardReady; + } + + public boolean isMouseReady() { + return mouseReady; + } + + public boolean isConsumerReady() { + return consumerReady; + } + + + + // > v0.93 firmware only + + public boolean isSentToHostInfoAvailable() { + return sentToHostInfo; + } + + public int getKeyboardReportsSentToHost() { + return keyboardReportsSentToHost; + } + + public int getMouseReportsSentToHost() { + return mouseReportsSentToHost; + } + + public int getConsumerReportsSentToHost() { + return consumerReportsSentToHost; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/IPCConnectionManager.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/IPCConnectionManager.java new file mode 100644 index 00000000..1d459727 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/IPCConnectionManager.java @@ -0,0 +1,180 @@ +package com.inputstick.api; + +import java.lang.ref.WeakReference; + +import android.app.Application; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; + +public class IPCConnectionManager extends ConnectionManager { + + //private static final String mTag = "IPCConnectionManager"; + + public static final int SERVICE_CMD_CONNECT = 1; + public static final int SERVICE_CMD_DISCONNECT = 2; + public static final int SERVICE_CMD_DATA = 3; + public static final int SERVICE_CMD_STATE = 4; + + Context mCtx; + Messenger mService = null; + boolean mBound; + boolean initSent; + final Messenger mMessenger = new Messenger(new IncomingHandler(this)); + + private static class IncomingHandler extends Handler { + private final WeakReference ref; + + IncomingHandler(IPCConnectionManager manager) { + ref = new WeakReference(manager); + } + + @Override + public void handleMessage(Message msg) { + if (ref == null) return; + IPCConnectionManager manager = ref.get(); + if (manager != null) { + switch (msg.what) { + case SERVICE_CMD_DATA: + byte[] data = null; + Bundle b = msg.getData(); + if (b != null) { + data = b.getByteArray("data"); + manager.onData(data); + } + break; + case SERVICE_CMD_STATE: + manager.stateNotify(msg.arg1); + break; + } + } + } + } + + private ServiceConnection mConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, IBinder service) { + mService = new Messenger(service); + mBound = true; + sendConnectMessage(); + } + + public void onServiceDisconnected(ComponentName className) { + // unexpectedly disconnected from service + mService = null; + mBound = false; + mErrorCode = InputStickError.ERROR_ANDROID_SERVICE_DISCONNECTED; + stateNotify(STATE_FAILURE); + stateNotify(STATE_DISCONNECTED); + } + }; + //SERVICE========================================================= + + + + + + private void sendConnectMessage() { + Bundle b = new Bundle(); + b.putLong("TIME", System.currentTimeMillis()); + sendMessage(SERVICE_CMD_CONNECT, 0, 0, b); + } + + + private void sendMessage(int what, int arg1, int arg2, Bundle b) { + Message msg; + try { + msg = Message.obtain(null, what, arg1, 0, null); + msg.replyTo = mMessenger; + msg.setData(b); + mService.send(msg); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void sendMessage(int what, int arg1, int arg2, byte[] data) { + Bundle b; + b = new Bundle(); + b.putByteArray("data", data); + sendMessage(what, arg1, arg2, b); + } + + private void sendMessage(int what, int arg1, int arg2) { + sendMessage(what, arg1, arg2, (Bundle)null); + } + + @Override + protected void onData(byte[] data) { + super.onData(data); + } + + + public IPCConnectionManager(Application app) { + mCtx = app.getApplicationContext(); + } + + @Override + public void connect() { + PackageManager pm = mCtx.getPackageManager(); + boolean exists = true; + try { + pm.getPackageInfo("com.inputstick.apps.inputstickutility", PackageManager.GET_META_DATA); + } catch (NameNotFoundException e) { + exists = false; + } + + if (exists) { + mErrorCode = InputStickError.ERROR_NONE; + Intent intent = new Intent(); + intent.setComponent(new ComponentName("com.inputstick.apps.inputstickutility","com.inputstick.apps.inputstickutility.service.InputStickService")); + intent.putExtra("TIME", System.currentTimeMillis()); + mCtx.startService(intent); + mCtx.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + if (mBound) { + //already bound + sendConnectMessage(); + } + } else { + mErrorCode = InputStickError.ERROR_ANDROID_NO_UTILITY_APP; + stateNotify(STATE_FAILURE); + stateNotify(STATE_DISCONNECTED); + } + } + + @Override + public void disconnect() { + if (mBound) { + sendMessage(SERVICE_CMD_DISCONNECT, 0, 0); + Intent intent = new Intent(); + intent.setComponent(new ComponentName("com.inputstick.apps.inputstickutility","com.inputstick.apps.inputstickutility.service.InputStickService")); + mCtx.unbindService(mConnection); + mCtx.stopService(intent); + mBound = false; + //service will pass notification message (disconnected) + } else { + //just set state, there is nothing else to do + stateNotify(STATE_DISCONNECTED); + } + } + + @Override + public void sendPacket(Packet p) { + if ((mState == ConnectionManager.STATE_READY) || (mState == ConnectionManager.STATE_CONNECTED)) { + if (p.getRespond()) { + sendMessage(IPCConnectionManager.SERVICE_CMD_DATA, 1, 0, p.getBytes()); + } else { + sendMessage(IPCConnectionManager.SERVICE_CMD_DATA, 0, 0, p.getBytes()); + } + } + } + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickDataListener.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickDataListener.java new file mode 100644 index 00000000..1496db85 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickDataListener.java @@ -0,0 +1,7 @@ +package com.inputstick.api; + +public interface InputStickDataListener { + + public void onInputStickData(byte[] data); + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickError.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickError.java new file mode 100644 index 00000000..d9bbbc6f --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickError.java @@ -0,0 +1,144 @@ +package com.inputstick.api; + +import android.util.SparseArray; + +public class InputStickError { + + public static String ERROR_UNKNOWN_MSG = "Unknown"; + + public static final int ERROR_NONE = 0; + public static final int ERROR_UNKNOWN = 1; + + //Bluetooth comm errors: + public static final int ERROR_BLUETOOTH = 0x0100; + public static final int ERROR_BLUETOOTH_CONNECTION_FAILED = ERROR_BLUETOOTH | 0x01; + public static final int ERROR_BLUETOOTH_CONNECTION_LOST = ERROR_BLUETOOTH | 0x02; + public static final int ERROR_BLUETOOTH_NOT_SUPPORTED = ERROR_BLUETOOTH | 0x03; + public static final int ERROR_BLUETOOTH_INVALID_MAC = ERROR_BLUETOOTH | 0x04; + public static final int ERROR_BLUETOOTH_ECHO_TIMEDOUT = ERROR_BLUETOOTH | 0x05; + public static final int ERROR_BLUETOOTH_NO_REMOTE_DEVICE = ERROR_BLUETOOTH | 0x06; + public static final int ERROR_BLUETOOTH_BT40_NOT_SUPPRTED = ERROR_BLUETOOTH | 0x07; + public static final int ERROR_BLUETOOTH_BT40_NO_SPP_SERVICE = ERROR_BLUETOOTH | 0x08; + + //Hardware-related errors: + public static final int ERROR_HARDWARE = 0x0200; + public static final int ERROR_HARDWARE_WDG_RESET = ERROR_HARDWARE | 0x01; + + //Packet + public static final int ERROR_PACKET = 0x0300; + public static final int ERROR_PACKET_INVALID_CRC = ERROR_PACKET | 0x01; + public static final int ERROR_PACKET_INVALID_LENGTH = ERROR_PACKET | 0x02; + public static final int ERROR_PACKET_INVALID_HEADER = ERROR_PACKET | 0x03; + + //Init + public static final int ERROR_INIT = 0x0400; + public static final int ERROR_INIT_UNSUPPORTED_CMD = ERROR_INIT | 0x01; + public static final int ERROR_INIT_TIMEDOUT = ERROR_INIT | 0x02; + public static final int ERROR_INIT_FW_TYPE_NOT_SUPPORTED = ERROR_INIT | 0x03; + public static final int ERROR_INIT_FW_VERSION_NOT_SUPPORTED = ERROR_INIT | 0x04; + + //Security + public static final int ERROR_SECURITY = 0x0500; + public static final int ERROR_SECURITY_NOT_SUPPORTED = ERROR_SECURITY | 0x01; + public static final int ERROR_SECURITY_NO_KEY = ERROR_SECURITY | 0x02; + public static final int ERROR_SECURITY_INVALID_KEY = ERROR_SECURITY | 0x03; + public static final int ERROR_SECURITY_CHALLENGE = ERROR_SECURITY | 0x04; + public static final int ERROR_SECURITY_NOT_PROTECTED = ERROR_SECURITY | 0x05; + + //Android + public static final int ERROR_ANDROID = 0x1000; + public static final int ERROR_ANDROID_NO_UTILITY_APP = ERROR_ANDROID | 0x01; + public static final int ERROR_ANDROID_SERVICE_DISCONNECTED = ERROR_ANDROID | 0x02; + public static final int ERROR_ANDROID_UTIL_FORCE_DISC = ERROR_ANDROID | 0x03; + public static final int ERROR_ANDROID_UTIL_IDLE_DISC = ERROR_ANDROID | 0x04; + + // 0000 - ERROR_NONE + // xx00 - Category / Unknown + // xxyy - Category / Details + + private static final SparseArray errorCodeMap; + static + { + errorCodeMap = new SparseArray(); + errorCodeMap.put(ERROR_NONE, "None"); + errorCodeMap.put(ERROR_UNKNOWN, "Unknown"); + //Bluetooth + errorCodeMap.put(ERROR_BLUETOOTH, "Bluetooth"); + errorCodeMap.put(ERROR_BLUETOOTH_CONNECTION_FAILED, "Failed to connect"); + errorCodeMap.put(ERROR_BLUETOOTH_CONNECTION_LOST, "Connection lost"); + errorCodeMap.put(ERROR_BLUETOOTH_NOT_SUPPORTED, "Not supported"); + errorCodeMap.put(ERROR_BLUETOOTH_INVALID_MAC, "Invalid MAC"); + errorCodeMap.put(ERROR_BLUETOOTH_ECHO_TIMEDOUT, "Echo timedout"); + errorCodeMap.put(ERROR_BLUETOOTH_NO_REMOTE_DEVICE, "Can't find remote device"); + errorCodeMap.put(ERROR_BLUETOOTH_BT40_NOT_SUPPRTED, "BT 4.0 is not supported"); + errorCodeMap.put(ERROR_BLUETOOTH_BT40_NO_SPP_SERVICE, "BT 4.0 RXTX not found"); + + //Hardware + errorCodeMap.put(ERROR_HARDWARE, "Hardware"); + errorCodeMap.put(ERROR_HARDWARE_WDG_RESET, "WDG reset"); + + //Packet + errorCodeMap.put(ERROR_PACKET, "Invalid packet"); + errorCodeMap.put(ERROR_PACKET_INVALID_CRC, "Invalid CRC"); + errorCodeMap.put(ERROR_PACKET_INVALID_LENGTH, "Invalid length"); + errorCodeMap.put(ERROR_PACKET_INVALID_HEADER, "Invalid header"); + + //Init + errorCodeMap.put(ERROR_INIT, "Init"); + errorCodeMap.put(ERROR_INIT_UNSUPPORTED_CMD, "Command not supported"); + errorCodeMap.put(ERROR_INIT_TIMEDOUT, "Timedout"); + errorCodeMap.put(ERROR_INIT_FW_TYPE_NOT_SUPPORTED, "FW type not supported"); + errorCodeMap.put(ERROR_INIT_FW_VERSION_NOT_SUPPORTED, "FW version not supported"); + + //Security + errorCodeMap.put(ERROR_SECURITY, "Security"); + errorCodeMap.put(ERROR_SECURITY_NOT_SUPPORTED, "Not supported"); + errorCodeMap.put(ERROR_SECURITY_NO_KEY, "No key provided"); + errorCodeMap.put(ERROR_SECURITY_INVALID_KEY, "Invalid key"); + errorCodeMap.put(ERROR_SECURITY_CHALLENGE, "Challenge failed"); + errorCodeMap.put(ERROR_SECURITY_NOT_PROTECTED, "Key was provided, but device is not password protected"); + + //Android + errorCodeMap.put(ERROR_ANDROID, "Android"); + errorCodeMap.put(ERROR_ANDROID_NO_UTILITY_APP, "InputStickUtility app not installed"); + errorCodeMap.put(ERROR_ANDROID_SERVICE_DISCONNECTED, "Service connection lost"); + errorCodeMap.put(ERROR_ANDROID_UTIL_FORCE_DISC, "Connection closed by InputStickUtility"); + errorCodeMap.put(ERROR_ANDROID_UTIL_IDLE_DISC, "Connection closed due to inactivity"); + + } + + public static String getErrorType(int errorCode) { + String result; + errorCode &= 0xFF00; + result = errorCodeMap.get(errorCode); + if (result != null) { + return result; + } else { + return ERROR_UNKNOWN_MSG; + } + } + + public static String getErrorMessage(int errorCode) { + String result; + if (errorCode == ERROR_NONE) { + return errorCodeMap.get(ERROR_NONE); + } + + //handle case: "Bluetooth: Unknown" etc + if ((errorCode & 0x00FF) == 0) { + return ERROR_UNKNOWN_MSG; + } + + result = errorCodeMap.get(errorCode); + if (result != null) { + return result; + } else { + return ERROR_UNKNOWN_MSG; + } + } + + public static String getFullErrorMessage(int errorCode) { + return getErrorType(errorCode) + " - " + getErrorMessage(errorCode); + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickKeyboardListener.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickKeyboardListener.java new file mode 100644 index 00000000..c0508417 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickKeyboardListener.java @@ -0,0 +1,7 @@ +package com.inputstick.api; + +public interface InputStickKeyboardListener { + + public void onLEDsChanged(boolean numLock, boolean capsLock, boolean scrollLock); + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickStateListener.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickStateListener.java new file mode 100644 index 00000000..16a7df8e --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/InputStickStateListener.java @@ -0,0 +1,7 @@ +package com.inputstick.api; + +public interface InputStickStateListener { + + public void onStateChanged(int state); + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/OnEmptyBufferListener.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/OnEmptyBufferListener.java new file mode 100644 index 00000000..9b84b954 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/OnEmptyBufferListener.java @@ -0,0 +1,8 @@ +package com.inputstick.api; + +public interface OnEmptyBufferListener { + + public void onLocalBufferEmpty(int interfaceId); + public void onRemoteBufferEmpty(int interfaceId); + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/Packet.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/Packet.java new file mode 100644 index 00000000..7b4c2fff --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/Packet.java @@ -0,0 +1,144 @@ +package com.inputstick.api; + +public class Packet { + + public static final byte NONE = 0x00; + + public static final byte START_TAG = 0x55; + public static final byte FLAG_RESPOND = (byte)0x80; + public static final byte FLAG_ENCRYPTED = 0x40; + + public static final int MAX_SUBPACKETS = 17; + public static final int MAX_LENGTH = MAX_SUBPACKETS * 16; + + public static final byte CMD_IDENTIFY = 0x01; + public static final byte CMD_LED = 0x02; + public static final byte CMD_RUN_BL = 0x03; + public static final byte CMD_RUN_FW = 0x04; + public static final byte CMD_GET_INFO = 0x05; + public static final byte CMD_BL_ERASE = 0x06; + public static final byte CMD_ADD_DATA = 0x07; + public static final byte CMD_BL_WRITE = 0x08; + + public static final byte CMD_FW_INFO = 0x10; + public static final byte CMD_INIT = 0x11; + public static final byte CMD_INIT_AUTH = 0x12; + public static final byte CMD_INIT_CON = 0x13; + public static final byte CMD_SET_VALUE = 0x14; + public static final byte CMD_RESTORE_DEFAULTS = 0x15; + public static final byte CMD_RESTORE_STATUS = 0x16; + public static final byte CMD_GET_VALUE = 0x17; + public static final byte CMD_SET_PIN = 0x18; + public static final byte CMD_USB_RESUME = 0x19; + public static final byte CMD_USB_POWER = 0x1A; + + public static final byte CMD_SYSTEM_NOTIFICATION = 0x1F; + + + + public static final byte CMD_HID_STATUS_REPORT = 0x20; + public static final byte CMD_HID_DATA_KEYB = 0x21; + public static final byte CMD_HID_DATA_CONSUMER = 0x22; + public static final byte CMD_HID_DATA_MOUSE = 0x23; + public static final byte CMD_HID_DATA_GAMEPAD = 0x24; + + public static final byte CMD_HID_DATA_ENDP = 0x2B; + public static final byte CMD_HID_DATA_KEYB_FAST = 0x2C; + public static final byte CMD_HID_DATA_KEYB_FASTEST = 0x2D; + //out + public static final byte CMD_HID_STATUS = 0x2F; + + + + public static final byte CMD_DUMMY = (byte)0xFF; + + + public static final byte RESP_OK = 0x01; + public static final byte RESP_UNKNOWN_CMD = (byte)0xFF; + + + public static final byte[] RAW_OLD_BOOTLOADER = new byte[] {START_TAG, (byte)0x00, (byte)0x02, (byte)0x83, (byte)0x00, (byte)0xDA}; + public static final byte[] RAW_DELAY_1_MS = new byte[] {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; + + private byte[] mData; + private int mPos; + private boolean mRespond; + + //do not modify + public Packet(boolean respond, byte[] data) { + mRespond = respond; + mData = data; + mPos = data.length; + } + + public Packet(boolean respond, byte cmd, byte param, byte[] data) { + mRespond = respond; + mData = new byte[MAX_LENGTH]; + mData[0] = cmd; + mData[1] = param; + mPos = 2; + if (data != null) { + addBytes(data); + } + } + + public Packet(boolean respond, byte cmd, byte param) { + this(respond, cmd, param, null); + } + + public Packet(boolean respond, byte cmd) { + mRespond = respond; + mData = new byte[MAX_LENGTH]; + mData[0] = cmd; + mPos = 1; + } + + public void modifyByte(int pos, byte b) { + mData[pos] = b; + } + + public void addBytes(byte[] data) { + //TODO check null pointer / available size (MAX_PAYLOAD - mPos) + System.arraycopy(data, 0, mData, mPos, data.length); + mPos += data.length; + } + + public void addByte(byte b) { + mData[mPos++] = b; + } + + public void addInt16(int val) { + mData[mPos + 0] = Util.getMSB(val); + mData[mPos + 1] = Util.getLSB(val); + mPos += 2; + } + + public void addInt32(long val) { + mData[mPos + 3] = (byte)val; + val >>= 8; + mData[mPos + 2] = (byte)val; + val >>= 8; + mData[mPos + 1] = (byte)val; + val >>= 8; + mData[mPos + 0] = (byte)val; + val >>= 8; + mPos += 4; + } + + + public byte[] getBytes() { + byte[] result; + result = new byte[mPos]; + System.arraycopy(mData, 0, result, 0, mPos); + return result; + } + + public boolean getRespond() { + return mRespond; + } + + public void print() { + Util.printHex(mData, "PACKET DATA:"); + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/PacketManager.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/PacketManager.java new file mode 100644 index 00000000..eea81f04 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/PacketManager.java @@ -0,0 +1,185 @@ +package com.inputstick.api; + +import java.util.Arrays; +import java.util.Random; +import java.util.zip.CRC32; + +import com.inputstick.api.bluetooth.BTService; + +public class PacketManager { + + public static final int MAX_PAYLAOD = 64; + public static final int HEADER_OFFSET = 2; + public static final int CRC_OFFSET = 4; + public static final int PACKET_SIZE = 16; + + private final BTService mBTService; + private final AES mAes; + private final byte[] mKey; + private byte[] cmpData; + private final CRC32 mCrc; + private boolean mEncryption; + + public PacketManager(BTService btService, byte[] key) { + mBTService = btService; + mCrc = new CRC32(); + mAes = new AES(); + mKey = key; + mEncryption = false; + } + + public boolean setEncryption(byte[] cmp, boolean encryptOut) { + byte[] cmpDec = mAes.decrypt(cmp); + if (Arrays.equals(cmpDec, cmpData)) { + mEncryption = encryptOut; + return true; + } else { + mEncryption = false; + return false; + } + } + + public boolean isEncrypted() { + return mEncryption; + } + + public Packet encPacket(boolean enable) { + Random r = new Random(); + Packet p = new Packet(true, Packet.CMD_INIT_AUTH); + if (enable) { + p.addByte((byte)1); + } else { + p.addByte((byte)0); + } + + byte[] iv = mAes.init(mKey); + p.addBytes(iv); + + //Util.printHex(mKey, "key: "); // TODO prnt + + //Util.printHex(iv, "IV: "); + + byte[] initData = new byte[16]; + r.nextBytes(initData); + mCrc.reset(); + mCrc.update(initData, 4, 12); //only 12 bytes! + long crcValue = mCrc.getValue(); + initData[3] = (byte)crcValue; + crcValue >>= 8; + initData[2] = (byte)crcValue; + crcValue >>= 8; + initData[1] = (byte)crcValue; + crcValue >>= 8; + initData[0] = (byte)crcValue; + initData = mAes.encrypt(initData); + p.addBytes(initData); + + //Util.printHex(initData, "InitData: "); + + cmpData = new byte[16]; + r.nextBytes(cmpData); + p.addBytes(cmpData); + + //Util.printHex(cmpData, "CmpData: "); + return p; + } + + + + public byte[] bytesToPacket(byte[] data) { + byte[] payload; + //boolean decrypt = false; + long crcValue, crcCompare; + + //Util.printHex(data, "RX DATA: "); // TODO prnt + + payload = Arrays.copyOfRange(data, 2, data.length); //remove TAG, info + if ((data[1] & Packet.FLAG_ENCRYPTED) != 0) { + //Util.log("DECRYPT"); + if (mAes.isReady()) { + payload = mAes.decrypt(payload); + //Util.printHex(payload, "RX DECR: "); // TODO prnt + } else { + return null; + } + } + + //Util.printHex(payload, "DATA IN: "); + + //check CRC + crcCompare = Util.getLong(payload[0], payload[1], payload[2], payload[3]); + mCrc.reset(); + mCrc.update(payload, CRC_OFFSET, payload.length - CRC_OFFSET); + crcValue = mCrc.getValue(); + //System.out.println("CMP: " + crcCompare + " VAL: " + crcValue); + + if (crcValue == crcCompare) { + payload = Arrays.copyOfRange(payload, 4, payload.length); //remove CRC + //Util.printHex(payload, "RX PAYLOAD FINAL: "); // TODO prnt + return payload; + } else { + return null; //TODO + } + + } + + public void sendRAW(byte[] data) { + mBTService.write(data); + } + + public void sendPacket(Packet p) { + if (p != null) { + sendPacket(p, mEncryption); + } + } + + public void sendPacket(Packet p, boolean encrypt) { + byte[] result, header, data; + int length; + int packets; + long crcValue; + + //if data > MAX_PAYLAOD -> error + + data = p.getBytes(); + + length = data.length + CRC_OFFSET; //include 4bytes for CRC32 + packets = ((length - 1) >> 4) + 1; //how many 16 bytes data sub-packets are necessary + + result = new byte[packets * PACKET_SIZE]; + System.arraycopy(data, 0, result, CRC_OFFSET, data.length); + + //add CRC32 + mCrc.reset(); + mCrc.update(result, CRC_OFFSET, result.length - CRC_OFFSET); + crcValue = mCrc.getValue(); + //Util.log("CRC: "+crcValue); + result[3] = (byte)crcValue; + crcValue >>= 8; + result[2] = (byte)crcValue; + crcValue >>= 8; + result[1] = (byte)crcValue; + crcValue >>= 8; + result[0] = (byte)crcValue; + + //Util.printHex(result, "TX DATA: "); // TODO prnt + if (encrypt) { + result = mAes.encrypt(result); + //Util.printHex(result, "ENC DATA: "); // TODO prnt + } + + header = new byte[2]; + header[0] = Packet.START_TAG; + header[1] = (byte)packets; + if (encrypt) { + header[1] |= Packet.FLAG_ENCRYPTED; + } + if (p.getRespond()) { + header[1] |= Packet.FLAG_RESPOND; + } + //Util.printHex(header, "TX HEADER: "); // TODO prnt + mBTService.write(header); + mBTService.write(result); + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/Util.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/Util.java new file mode 100644 index 00000000..155448bb --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/Util.java @@ -0,0 +1,121 @@ +package com.inputstick.api; + +import android.annotation.SuppressLint; +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + + +public abstract class Util { + + public static boolean debug = false; + public static boolean flashingToolMode = false; + + public static void log(String msg) { + log(msg, false); + } + + public static void log(String msg, boolean displayTime) { + if (debug) { + System.out.print("LOG: " + msg); + if (displayTime) { + System.out.print(" @ " + System.currentTimeMillis()); + } + System.out.println(); + } + } + + public static void printHex(byte[] toPrint, String info) { + if (debug) { + System.out.println(info); + printHex(toPrint); + } + } + + @SuppressLint("DefaultLocale") + public static String byteToHexString(byte b) { + String s; + //0x0..0xF = 0x00..0x0F + if ((b < 0x10) && (b >= 0)) { + s = Integer.toHexString((int)b); + s = "0" + s; + } else { + s = Integer.toHexString((int)b); + if (s.length() > 2) { + s = s.substring(s.length() - 2); + } + } + s = s.toUpperCase(); + return s; + } + + public static void printHex(byte[] toPrint) { + if (debug) { + if (toPrint != null) { + int cnt = 0; + byte b; + for (int i = 0; i < toPrint.length; i++) { + b = toPrint[i]; + + System.out.print("0x" + byteToHexString(b) + " "); + cnt++; + if (cnt == 8) { + System.out.println(""); + cnt = 0; + } + } + + } else { + System.out.println("null"); + } + System.out.println("\n#####"); + } + } + + + public static byte getLSB(int n) { + return (byte)(n & 0x00FF); + } + + public static byte getMSB(int n) { + return (byte)((n & 0xFF00) >> 8); + } + + public static int getInt(byte b) { + int bInt = b & 0xFF; + return bInt; + } + + public static int getInt(byte msb, byte lsb) { + int msbInt = msb & 0xFF; + int lsbInt = lsb & 0xFF; + return (msbInt << 8) + lsbInt; + } + + public static long getLong(byte b0, byte b1, byte b2, byte b3) { + long result; + result = (b0) & 0xFF; + result <<= 8; + result += (b1) & 0xFF; + result <<= 8; + result += (b2) & 0xFF; + result <<= 8; + result += (b3) & 0xFF; + return result; + } + + + public static byte[] getPasswordBytes(String plainText) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + return md.digest(plainText.getBytes("UTF-8")); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return null; + } + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickConsumer.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickConsumer.java new file mode 100644 index 00000000..5274592c --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickConsumer.java @@ -0,0 +1,89 @@ +package com.inputstick.api.basic; + +import com.inputstick.api.hid.ConsumerReport; +import com.inputstick.api.hid.HIDTransaction; + +public class InputStickConsumer { + + //CONSUMER PAGE (consumerAction) + public static final int VOL_UP = 0x00E9; + public static final int VOL_DOWN = 0x00EA; + public static final int VOL_MUTE = 0x00E2; + public static final int TRACK_NEXT = 0x00B5; + public static final int TRACK_PREV = 0x00B6; + public static final int STOP = 0x00B7; + public static final int PLAY_PAUSE = 0x00CD; + + public static final int LAUNCH_BROWSER = 0x0196; + public static final int LAUNCH_EMAIL = 0x018A; + public static final int LAUNCH_CALC = 0x0192; + + //Android OS (consumer): + public static final int HOME = 0x0223; + public static final int BACK = 0x0224; + public static final int SEARCH = 0x0221; + + + //SYSTEM PAGE (systemAction) + public static final byte SYSTEM_POWER_DOWN = 0x01; + public static final byte SYSTEM_SLEEP = 0x02; + public static final byte SYSTEM_WAKEUP = 0x03; + + private InputStickConsumer() { + + } + + + /* + * Use only for system actions SYSTEM_POWER_DOWN, SYSTEM_SLEEP and SYSTEM_WAKEUP + * + * @param action code of system action + */ + public static void systemAction(byte action) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new ConsumerReport(ConsumerReport.SYSTEM_REPORT_ID, action, (byte)0)); + t.addReport(new ConsumerReport(ConsumerReport.SYSTEM_REPORT_ID, (byte)0, (byte)0)); + InputStickHID.addConsumerTransaction(t); + } + + + /* + * Requests USB host to power down. Must be supported and enabled by USB host. + */ + public static void systemPowerDown() { + systemAction(SYSTEM_POWER_DOWN); + } + + + /* + * Requests USB host to go into sleep/standby mode. Must be supported and enabled by USB host. + */ + public static void systemSleep() { + systemAction(SYSTEM_SLEEP); + } + + + /* + * Requests USB host to resume from sleep/standby mode. Must be supported and enabled by USB host. + * Note: USB host must supply USB power when suspended. Otherwise InputStick will not work. + */ + public static void systemWakeUp() { + systemAction(SYSTEM_WAKEUP); + } + + + /* + * Consumer control action: media playback, volume etc. + * See http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (consumer page). + * USB host may not support certain action codes + * + * @param action code of consumer control action + */ + public static void consumerAction(int action) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new ConsumerReport(action)); + t.addReport(new ConsumerReport()); + InputStickHID.addConsumerTransaction(t); + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickGamepad.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickGamepad.java new file mode 100644 index 00000000..c042a610 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickGamepad.java @@ -0,0 +1,38 @@ +package com.inputstick.api.basic; + +import com.inputstick.api.Packet; + + +public class InputStickGamepad { + + private InputStickGamepad() { + + } + + + /* + * Sends custom HID gamepad report + * + * @param buttons1 state (on/off) of buttons0..7 + * @param buttons2 state (on/off) of buttons8..15 + * @param x value of X axis + * @param y value of Y axis + * @param z value of Z axis + * @param rx value of rX axis + */ + public static void customReport(byte buttons1, byte buttons2, byte x, byte y, byte z, byte rX) { + if (InputStickHID.isReady()) { + Packet p = new Packet(false, (byte)0x2B, (byte)0x03); //write directly to endp3in, no buffering + p.addByte((byte)0x07); //report bytes cnt + p.addByte((byte)0x03); //report ID + p.addByte(buttons1); + p.addByte(buttons2); + p.addByte(x); + p.addByte(y); + p.addByte(z); + p.addByte(rX); + InputStickHID.sendPacket(p); + } + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickHID.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickHID.java new file mode 100644 index 00000000..659debd0 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickHID.java @@ -0,0 +1,602 @@ +package com.inputstick.api.basic; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.Vector; + +import android.app.AlertDialog; +import android.app.Application; +import android.content.Context; + +import com.inputstick.api.BTConnectionManager; +import com.inputstick.api.ConnectionManager; +import com.inputstick.api.DownloadDialog; +import com.inputstick.api.HIDInfo; +import com.inputstick.api.IPCConnectionManager; +import com.inputstick.api.InputStickDataListener; +import com.inputstick.api.InputStickError; +import com.inputstick.api.InputStickStateListener; +import com.inputstick.api.OnEmptyBufferListener; +import com.inputstick.api.Packet; +import com.inputstick.api.hid.HIDReport; +import com.inputstick.api.hid.HIDTransaction; +import com.inputstick.api.hid.HIDTransactionQueue; +import com.inputstick.api.init.BasicInitManager; +import com.inputstick.api.init.DeviceInfo; +import com.inputstick.api.init.InitManager; + +public class InputStickHID implements InputStickStateListener, InputStickDataListener { + + public static final int INTERFACE_KEYBOARD = 0; + public static final int INTERFACE_CONSUMER = 1; + public static final int INTERFACE_MOUSE = 2; + + private static ConnectionManager mConnectionManager; + + private static Vector mStateListeners = new Vector(); + protected static Vector mBufferEmptyListeners = new Vector(); + + private static InputStickHID instance = new InputStickHID(); + private static HIDInfo mHIDInfo; + private static DeviceInfo mDeviceInfo; + + private static HIDTransactionQueue keyboardQueue; + private static HIDTransactionQueue mouseQueue; + private static HIDTransactionQueue consumerQueue; + + + //FW 0.93 - 0.95 + private static Timer updateQueueTimer; + + + private static int mKeyboardReportMultiplier; //enables "slow" typing by multiplying HID reports + + private InputStickHID() { + } + + public static InputStickHID getInstance() { + return instance; + } + + private static void init() { + mHIDInfo = new HIDInfo(); + keyboardQueue = new HIDTransactionQueue(INTERFACE_KEYBOARD, mConnectionManager); + mouseQueue = new HIDTransactionQueue(INTERFACE_MOUSE, mConnectionManager); + consumerQueue = new HIDTransactionQueue(INTERFACE_CONSUMER, mConnectionManager); + + mConnectionManager.addStateListener(instance); + mConnectionManager.addDataListener(instance); + mConnectionManager.connect(); + } + + /* + * Returns download InputStickUtility AlertDialog if InputStickUtility is not installed. Returns null is InputStickUtility application is installed. + * Should be called when your application is started or before InputStick functionality is about to be used. + * + * @return download InputStickUtility AlertDialog or null + */ + public static AlertDialog getDownloadDialog(final Context ctx) { + if (mConnectionManager.getErrorCode() == InputStickError.ERROR_ANDROID_NO_UTILITY_APP) { + return DownloadDialog.getDialog(ctx, DownloadDialog.NOT_INSTALLED); + } else { + return null; + } + } + + + /* + * Connect using InputStickUtility application. + * IN MOST CASES THIS METHOD SHOULD BE USED TO INITIATE CONNECTION! + * + * @param app Application + */ + public static void connect(Application app) { + mConnectionManager = new IPCConnectionManager(app); + init(); + } + + + /* + * Close connection + */ + public static void disconnect() { + if (mConnectionManager != null) { + mConnectionManager.disconnect(); + } + } + + + /* + * Direct connection to InputStick (BT2.1 only!). InputStickUtility application is not required in this case. + * TIP: use Util.getPasswordBytes(plainText) to get key. + * + * @param app Application + * @param mac Bluetooth MAC address + * @param key MD5(password) - must be provided if InputStick is password protected. Use null otherwise + * @param initManager custom init manager + */ + public static void connect(Application app, String mac, byte[] key, InitManager initManager) { + connect(app, mac, key, initManager, false); + } + + + /* + * Direct connection to InputStick. InputStickUtility application is not required in this case. + * TIP: use Util.getPasswordBytes(plainText) to get key. + * + * @param app Application + * @param mac Bluetooth MAC address + * @param key MD5(password) - must be provided if InputStick is password protected. Use null otherwise + * @param initManager custom init manager + * @param isBT40 specify Bluetooth version. Must match your hardware (InputStick BT2.1 or BT4.0)! + */ + public static void connect(Application app, String mac, byte[] key, InitManager initManager, boolean isBT40) { + mConnectionManager = new BTConnectionManager(initManager, app, mac, key, isBT40); + init(); + } + + + /* + * Direct connection to InputStick. InputStickUtility application is not required in this case. + * TIP: use Util.getPasswordBytes(plainText) to get key. + * + * @param app Application + * @param mac Bluetooth MAC address + * @param key MD5(password) - must be provided if InputStick is password protected. Use null otherwise + * @param initManager custom init manager + * @param isBT40 specify Bluetooth version. Must match your hardware (InputStick BT2.1 or BT4.0)! + */ + public static void connect(Application app, String mac, byte[] key, boolean isBT40) { + mConnectionManager = new BTConnectionManager(new BasicInitManager(key), app, mac, key, isBT40); + init(); + } + + + /* + * Direct connection to InputStick (BT2.1 only!). InputStickUtility application is not required in this case. + * TIP: use Util.getPasswordBytes(plainText) to get key. + * + * @param app Application + * @param mac Bluetooth MAC address + * @param key MD5(password) - must be provided if InputStick is password protected. Use null otherwise + */ + public static void connect(Application app, String mac, byte[] key) { + connect(app, mac, key, false); + } + + + /* + * When keyboard transactions are queued, each individual HID keyboard report is duplicated by reportMultiplier. + * Allows to control typing speed. Can help with missing characters (for example in BIOS). + * Important! Value of multiplier should be manually restored back to 1, when slow typing is no longer needed! + * + * Example: press and release "a" key: + * 1) Multiplier = 1 + * "a" key presses, all keys released + * 2 HID reports, fastest typing speed + * 2) Multiplier = 2 + * "a" key presses, "a" key presses, all keys released, all keys released + * 4 HID reports, 50% slower typing speed + * + * + * @param reportMultiplier number by which each HID report will be duplicated + */ + public static void setKeyboardReportMultiplier(int reportMultiplier) { + mKeyboardReportMultiplier = reportMultiplier; + } + + + /* + * Returns value of keyboard report multiplier + * + * @return keyboard report multiplier + */ + public static int getKeyboardReportMultiplier(int reportMultiplier) { + return mKeyboardReportMultiplier; + } + + + /* + * Requests USB host to resume from sleep / suspended state. Feature must be supported and enabled by USB host. + * Note 1: when USB host is suspended, device state will be STATE_CONNECTED. + * Note 2: some USB hosts may cut off USB power when suspended. + */ + public static void wakeUpUSBHost() { + if (isConnected()) { + Packet p = new Packet(false, Packet.CMD_USB_RESUME); + InputStickHID.sendPacket(p); + mConnectionManager.sendPacket(p); + } + } + + + /* + * Get device info of connected device + * + * @return Device info of connected device. Null if info is not available + */ + public static DeviceInfo getDeviceInfo() { + if ((isReady()) && (mDeviceInfo != null)) { + return mDeviceInfo; + } else { + return null; + } + } + + + /* + * Get latest status update received from InputStick. + * + * @return latest status update + */ + public static HIDInfo getHIDInfo() { + return mHIDInfo; + } + + + /* + * Returns current state of the connection. + * + * @return state of the connection + */ + public static int getState() { + if (mConnectionManager != null) { + return mConnectionManager.getState(); + } else { + return ConnectionManager.STATE_DISCONNECTED; + } + } + + + /* + * Returns last error code. See class InputStickError. + * + * @return last error code + */ + public static int getErrorCode() { + if (mConnectionManager != null) { + return mConnectionManager.getErrorCode(); + } else { + return InputStickError.ERROR_UNKNOWN; + } + } + + + /* + * Checks if Bluetooth connection between Android device and InputStick is established. + * Note - InputStick may be not ready yet to accept keyboard/mouse data. + * + * @return true if Bluetooth connection is established + */ + public static boolean isConnected() { + if ((getState() == ConnectionManager.STATE_READY) || (getState() == ConnectionManager.STATE_CONNECTED)) { + return true; + } else { + return false; + } + } + + + /* + * Checks if InputStick is ready to accept keyboard/mouse/etc. data. + * + * @return true if InputStick is ready to accept data + */ + public static boolean isReady() { + if (getState() == ConnectionManager.STATE_READY) { + return true; + } else { + return false; + } + } + + + /* + * Adds InputStickStateListener. Listener will be notified when connection state changes. + * + * @param listener listener to add + */ + public static void addStateListener(InputStickStateListener listener) { + if (listener != null) { + if ( !mStateListeners.contains(listener)) { + mStateListeners.add(listener); + } + } + } + + + /* + * Removes InputStickStateListener. Listener will no longer be notified when connection state changes. + * + * @param listener listener to remove + */ + public static void removeStateListener(InputStickStateListener listener) { + if (listener != null) { + mStateListeners.remove(listener); + } + } + + + /* + * Adds OnEmptyBufferListener. Listeners will be notified when local (application) or remote (InputStick) HID report buffer is empty. + * + * @param listener listener to add + */ + public static void addBufferEmptyListener(OnEmptyBufferListener listener) { + if (listener != null) { + if ( !mBufferEmptyListeners.contains(listener)) { + mBufferEmptyListeners.add(listener); + } + } + } + + + /* + * Removes OnEmptyBufferListener. + * + * @param listener listener to remove + */ + public static void removeBufferEmptyListener(OnEmptyBufferListener listener) { + if (listener != null) { + mBufferEmptyListeners.remove(listener); + } + } + + + /* + * Returns vector with registered OnEmptyBuffer listeners. + * + * @return vector with OnEmptyBuffer listeners + */ + public static Vector getBufferEmptyListeners() { + return mBufferEmptyListeners; + } + + + /* + * Adds transaction to keyboard queue. + * If possible, all reports form a single transactions will be sent in a single packet. + * This should prevent from key being stuck in pressed position when connection is suddenly lost. + * + * @param transaction transaction to be queued + */ + public static void addKeyboardTransaction(HIDTransaction transaction) { + if ((transaction != null) && (keyboardQueue != null)) { + //keyboardQueue.addTransaction(transaction); + + if (mKeyboardReportMultiplier > 1) { + HIDTransaction multipliedTransaction = new HIDTransaction(); + HIDReport r; + for (int i = 0; i < transaction.getReportsCount(); i++) { + r = transaction.getHIDReportAt(i); + for (int j = 0; j < mKeyboardReportMultiplier; j++) { + multipliedTransaction.addReport(r); + } + } + keyboardQueue.addTransaction(multipliedTransaction); + } else { + keyboardQueue.addTransaction(transaction); + } + } + } + + + /* + * Adds transaction to mouse queue. + * If possible, all reports form a single transactions will be sent in a single packet. + * + * @param transaction transaction to be queued + */ + public static void addMouseTransaction(HIDTransaction transaction) { + if ((transaction != null) && (mouseQueue != null)) { + mouseQueue.addTransaction(transaction); + } + } + + + /* + * Adds transaction to consumer control queue. + * If possible, all reports form a single transactions will be sent in a single packet. + * + * @param transaction transaction to be queued + */ + public static void addConsumerTransaction(HIDTransaction transaction) { + if ((transaction != null) && (consumerQueue != null)) { + consumerQueue.addTransaction(transaction); + } + } + + + /* + * Removes all reports from keyboard buffer. + */ + public static void clearKeyboardBuffer() { + if (keyboardQueue != null) { + keyboardQueue.clearBuffer(); + } + } + + + /* + * Removes all reports from mouse buffer. + */ + public static void clearMouseBuffer() { + if (mouseQueue != null) { + mouseQueue.clearBuffer(); + } + } + + + /* + * Removes all reports from consumer control buffer. + */ + public static void clearConsumerBuffer() { + if (consumerQueue != null) { + consumerQueue.clearBuffer(); + } + } + + + /* + * Sends custom packet to InputStick. + * + * @param p packet to send. + */ + public static boolean sendPacket(Packet p) { + if (mConnectionManager != null) { + mConnectionManager.sendPacket(p); + return true; + } else { + return false; + } + } + + + /* + * Checks if local (Android device) keyboard report buffer is empty. It is possible that there are reports queued in InputStick's buffer. + * + * @return true if local keyboard buffer is empty, false otherwise + */ + public static boolean isKeyboardLocalBufferEmpty() { + if (keyboardQueue != null) { + return keyboardQueue.isLocalBufferEmpty(); + } else { + return true; + } + } + + + /* + * Checks if local (Android device) mouse report buffer is empty. It is possible that there are reports queued in InputStick's buffer. + * + * @return true if local mouse buffer is empty, false otherwise + */ + public static boolean isMouseLocalBufferEmpty() { + if (mouseQueue != null) { + return mouseQueue.isLocalBufferEmpty(); + } else { + return true; + } + } + + + /* + * Checks if local (Android device) consumer control report buffer is empty. It is possible that there are reports queued in InputStick's buffer. + * + * @return true if local consumer control buffer is empty, false otherwise + */ + public static boolean isConsumerLocalBufferEmpty() { + if (consumerQueue != null) { + return consumerQueue.isLocalBufferEmpty(); + } else { + return true; + } + } + + + /* + * Checks if local (Android device) AND remote (InputStick) keyboard report buffers are empty. + * + * @return true if local and remote keyboard buffers are empty, false otherwise + */ + public static boolean isKeyboardRemoteBufferEmpty() { + if (keyboardQueue != null) { + return keyboardQueue.isRemoteBufferEmpty(); + } else { + return true; + } + } + + + /* + * Checks if local (Android device) AND remote (InputStick) mouse report buffers are empty. + * + * @return true if local and remote mouse buffers are empty, false otherwise + */ + public static boolean isMouseRemoteBufferEmpty() { + if (mouseQueue != null) { + return mouseQueue.isRemoteBufferEmpty(); + } else { + return true; + } + } + + + /* + * Checks if local (Android device) AND remote (InputStick) consumer control report buffers are empty. + * + * @return true if local and remote consumer control buffers are empty, false otherwise + */ + public static boolean isConsumerRemoteBufferEmpty() { + if (consumerQueue != null) { + return consumerQueue.isRemoteBufferEmpty(); + } else { + return true; + } + } + + + + + + + @Override + public void onStateChanged(int state) { + if ((state == ConnectionManager.STATE_DISCONNECTED) && (updateQueueTimer != null)) { + updateQueueTimer.cancel(); + updateQueueTimer = null; + } + for (InputStickStateListener listener : mStateListeners) { + listener.onStateChanged(state); + } + } + + @Override + public void onInputStickData(byte[] data) { + byte cmd = data[0]; + if (cmd == Packet.CMD_FW_INFO) { + mDeviceInfo = new DeviceInfo(data); + } + + if (cmd == Packet.CMD_HID_STATUS) { + mHIDInfo.update(data); + + if (mHIDInfo.isSentToHostInfoAvailable()) { + // >= FW 0.93 + keyboardQueue.deviceReady(mHIDInfo, mHIDInfo.getKeyboardReportsSentToHost()); + mouseQueue.deviceReady(mHIDInfo, mHIDInfo.getMouseReportsSentToHost()); + consumerQueue.deviceReady(mHIDInfo, mHIDInfo.getConsumerReportsSentToHost()); + + if (mDeviceInfo != null) { + if ((updateQueueTimer == null) && (mDeviceInfo.getFirmwareVersion() < 97)) { + updateQueueTimer = new Timer(); + updateQueueTimer.schedule(new TimerTask() { + @Override + public void run() { + keyboardQueue.sendToBuffer(false); + mouseQueue.sendToBuffer(false); + consumerQueue.sendToBuffer(false); + } + }, 5, 5); + } + } + } else { + //previous FW versions + if (mHIDInfo.isKeyboardReady()) { + keyboardQueue.deviceReady(null, 0); + } + if (mHIDInfo.isMouseReady()) { + mouseQueue.deviceReady(null, 0); + } + if (mHIDInfo.isConsumerReady()) { + consumerQueue.deviceReady(null, 0); + } + } + + InputStickKeyboard.setLEDs(mHIDInfo.getNumLock(), mHIDInfo.getCapsLock(), mHIDInfo.getScrollLock()); + } + } + + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickKeyboard.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickKeyboard.java new file mode 100644 index 00000000..b310bebf --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickKeyboard.java @@ -0,0 +1,263 @@ +package com.inputstick.api.basic; + +import java.util.Vector; + +import android.util.SparseArray; + +import com.inputstick.api.InputStickKeyboardListener; +import com.inputstick.api.hid.HIDKeycodes; +import com.inputstick.api.hid.HIDTransaction; +import com.inputstick.api.hid.KeyboardReport; +import com.inputstick.api.layout.KeyboardLayout; + +public class InputStickKeyboard { + + private static final byte NONE = (byte)0; + + private static final byte LED_NUM_LOCK = 1; + private static final byte LED_CAPS_LOCK = 2; + private static final byte LED_SCROLL_LOCK = 4; + + private static boolean mReportProtocol; + private static boolean mNumLock; + private static boolean mCapsLock; + private static boolean mScrollLock; + + private static Vector mKeyboardListeners = new Vector(); + + private static final SparseArray ledsMap; + static + { + ledsMap = new SparseArray(); + ledsMap.put(LED_NUM_LOCK, "NumLock"); + ledsMap.put(LED_CAPS_LOCK, "CapsLock"); + ledsMap.put(LED_SCROLL_LOCK, "ScrollLock"); + } + + private InputStickKeyboard() { + } + + + /* + * Uses InputStick to press and then immediately release key combination specified by parameters. + * + * @param modifier state of modifier keys (CTRL_LEFT .. GUI_RIGHT, see HIDKeycodes) + * @param key non-modifier key (see HIDKeycodes) + */ + public static void pressAndRelease(byte modifier, byte key) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new KeyboardReport(modifier, NONE)); + t.addReport(new KeyboardReport(modifier, key)); + t.addReport(new KeyboardReport(NONE, NONE)); + InputStickHID.addKeyboardTransaction(t); + } + + + /* + * Type text via InputStick, using selected keyboard layout. USB host must use matching keyboard layout. + * For available keyboard layouts see: com.inputstick.api.layout. + * If layout is null or not found, en-US will be used. + * + * @param toType text to type + * @param layoutCode code of keyboard layout ("en-US", "de-DE", etc.) + */ + public static void type(String toType, String layoutCode) { + KeyboardLayout layout = KeyboardLayout.getLayout(layoutCode); + layout.type(toType); + } + + + /* + * Type text via InputStick. ASCII characters only! It is assumed that USB host uses en-US keyboard layout. + * + * @param toType text to type + */ + public static void typeASCII(String toType) { + int keyCode; + int index; + + for (int i = 0; i < toType.length(); i++) { + index = toType.charAt(i); + if (index == '\n') { + pressAndRelease(NONE, HIDKeycodes.KEY_ENTER); + } else if (index == '\t') { + pressAndRelease(NONE, HIDKeycodes.KEY_TAB); + } else { + if (index > 127) { + index = 127; + } + keyCode = HIDKeycodes.getKeyCode(index); + if (keyCode > 128) { + keyCode -= 128; + pressAndRelease(HIDKeycodes.SHIFT_LEFT, (byte)keyCode); + } else { + pressAndRelease(NONE, (byte)keyCode); + } + } + } + } + + + /* + * Sends custom keyboard HID report. + * Note: keys must be "manually" released by sending next custom HID report (with 0x00s as key0..key5). + * + * @param modifier state of modifier keys (CTRL_LEFT .. GUI_RIGHT, see HIDKeycodes) + * @param key0 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + * @param key1 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + * @param key2 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + * @param key3 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + * @param key4 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + * @param key5 non modifier keyboard key (see HIDKeycodes). Use 0x00 when no key is pressed. + */ + public static void customReport(byte modifier, byte key0, byte key1, byte key2, byte key3, byte key4, byte key5) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new KeyboardReport(modifier, key0, key1, key2, key3, key4, key5)); + InputStickHID.addKeyboardTransaction(t); + } + + + /* + * Checks is report protocol is used. + * Report protocol is in most cases used by OS + * Boot protocol is used by BIOS, or when OS is booting + * + * @return true if USB host uses report protocol, false if USB host uses boot protocol + */ + public boolean isReportProtocol() { + return mReportProtocol; + } + + + /* + * Checks states of NumLock keyboard LED + * + * @return true if NumLock LED is on, false if off. + */ + public static boolean isNumLock() { + return mNumLock; + } + + + /* + * Checks states of CapsLock keyboard LED + * + * @return true if CapsLock LED is on, false if off. + */ + public static boolean isCapsLock() { + return mCapsLock; + } + + + /* + * Checks states of ScrollLock keyboard LED + * + * @return true if ScrollLock LED is on, false if off. + */ + public static boolean isScrollLock() { + return mScrollLock; + } + + + /* + * Toggle state of NumLock by press and release NumLock key. + */ + public static void toggleNumLock() { + pressAndRelease(NONE, HIDKeycodes.KEY_NUM_LOCK); + } + + + /* + * Toggle state of CapsLock by press and release CapsLock key. + */ + public static void toggleCapsLock() { + pressAndRelease(NONE, HIDKeycodes.KEY_CAPS_LOCK); + } + + + /* + * Toggle state of ScrollLock by press and release ScrollLock key. + */ + public static void toggleScrollLock() { + pressAndRelease(NONE, HIDKeycodes.KEY_SCROLL_LOCK); + } + + + + + + + /* + * Converts state of keyboard LEDs to String. Example: "CapsLock, ScrollLock". + * + * @return String description of keyboard LEDs. + */ + public static String ledsToString(byte leds) { + String result = "None"; + boolean first = true; + byte mod; + for (int i = 0; i < 8; i++) { + mod = (byte)(LED_NUM_LOCK << i); + if ((leds & mod) != 0) { + if ( !first) { + result += ", "; + } else { + result = ""; + } + first = false; + result += ledsMap.get(mod); + } + } + + return result; + } + + + /* + * Adds InputStickKeyboardListener. Listener will be notified when state of keyboard LEDs changes (NumLock, CapsLock, ScrollLock). + * + * @param listener listener to add + */ + public static void addKeyboardListener(InputStickKeyboardListener listener) { + if (listener != null) { + if ( !mKeyboardListeners.contains(listener)) { + mKeyboardListeners.add(listener); + } + } + } + + + /* + * Removes InputStickKeyboardListener. + * + * @param listener listener to remove + */ + public static void removeKeyboardListener(InputStickKeyboardListener listener) { + if (listener != null) { + mKeyboardListeners.remove(listener); + } + } + + + + protected void setReportProtocol(boolean reportProtocol) { + mReportProtocol = reportProtocol; + } + + protected static void setLEDs(boolean numLock, boolean capsLock, boolean scrollLock) { + boolean mustUpdate = false; + if ((numLock != mNumLock) || (capsLock != mCapsLock) || (scrollLock != mScrollLock)) { + mustUpdate = true; + } + mNumLock = numLock; + mCapsLock = capsLock; + mScrollLock = scrollLock; + + if (mustUpdate) { + for (InputStickKeyboardListener listener : mKeyboardListeners) { + listener.onLEDsChanged(mNumLock, mCapsLock, mScrollLock); + } + } + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickMouse.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickMouse.java new file mode 100644 index 00000000..412d67a4 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/basic/InputStickMouse.java @@ -0,0 +1,131 @@ +package com.inputstick.api.basic; + +import android.util.SparseArray; + +import com.inputstick.api.hid.HIDTransaction; +import com.inputstick.api.hid.MouseReport; + +public class InputStickMouse { + + private static final byte NONE = 0x00; + + public static final byte BUTTON_NONE = 0x00; + public static final byte BUTTON_LEFT = 0x01; + public static final byte BUTTON_RIGHT = 0x02; + public static final byte BUTTON_MIDDLE = 0x04; + + private static final SparseArray buttonsMap; + static + { + buttonsMap = new SparseArray(); + buttonsMap.put(BUTTON_LEFT, "Left"); + buttonsMap.put(BUTTON_RIGHT, "Right"); + buttonsMap.put(BUTTON_MIDDLE, "Middle"); + } + + private static boolean mReportProtocol; + + private InputStickMouse() { + + } + + + /* + * Clicks selected mouse button (BUTTON_LEFT etc) N times + * + * @param button code of mouse button + * @param n number of button clicks (press and release events) + */ + public static void click(byte button, int n) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new MouseReport()); //release + for (int i = 0; i < n; i++) { + t.addReport(new MouseReport(button, NONE, NONE, NONE)); //press + t.addReport(new MouseReport()); //release + } + InputStickHID.addMouseTransaction(t); + } + + /* + * Move mouse pointer + * + * @param x x displacement + * @param y y dispalcement + */ + public static void move(byte x, byte y) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new MouseReport(NONE, x, y, NONE)); + InputStickHID.addMouseTransaction(t); + } + + /* + * Moves mouse scroll wheel + * + * @param wheel scroll wheel displacement + */ + public static void scroll(byte wheel) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new MouseReport(NONE, NONE, NONE, wheel)); + InputStickHID.addMouseTransaction(t); + } + + //sends custom mouse report (buttons will remain in pressed state until released by next report) + + /* + * Sends custom HID mouse report. Mouse buttons will remain in selected state until new report is received. + * + * @param buttons state of mouse buttons + * @param x x displacement + * @param y y dispalcement + * @param wheel scroll wheel displacement + */ + public static void customReport(byte buttons, byte x, byte y, byte wheel) { + HIDTransaction t = new HIDTransaction(); + t.addReport(new MouseReport(buttons, x, y, wheel)); + InputStickHID.addMouseTransaction(t); + } + + + /* + * Returns names of buttons in "pressed" state + * + * @param buttons state of mouse buttons + */ + public static String buttonsToString(byte buttons) { + String result = "None"; + boolean first = true; + byte mod; + for (int i = 0; i < 8; i++) { + mod = (byte)(BUTTON_LEFT << i); + if ((buttons & mod) != 0) { + if ( !first) { + result += ", "; + } else { + result = ""; + } + first = false; + result += buttonsMap.get(mod); + } + } + + return result; + } + + + /* + * When report protocol is used, scroll wheel is enabled. Otherwise, simplified boot protocol is selected by USB host. + * Report protocol is in most cases used by OS. + * Boot protocol is used by BIOS, or when OS is booting. + * + * @return true if USB host uses report protocol, false if USB host uses boot protocol + */ + public boolean isReportProtocol() { + return mReportProtocol; + } + + + protected void setReportProtocol(boolean reportProtocol) { + mReportProtocol = reportProtocol; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BT20Connection.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BT20Connection.java new file mode 100644 index 00000000..8f982035 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BT20Connection.java @@ -0,0 +1,198 @@ +package com.inputstick.api.bluetooth; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Method; +import java.util.UUID; + +import android.app.Application; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Util; + +public class BT20Connection extends BTConnection { + + private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //SPP + + private final BluetoothAdapter mAdapter; + + private ConnectThread mConnectThread; + private ConnectedThread mConnectedThread; + + + public BT20Connection(Application app, BTService btService, String mac, boolean reflections) { + super(app, btService, mac, reflections); + mAdapter = BluetoothAdapter.getDefaultAdapter(); + } + + @Override + public void connect() { + if (mConnectThread != null) { + mConnectThread.cancel(); + mConnectThread = null; + } + if (mConnectedThread != null) { + mConnectedThread.cancel(); + mConnectedThread = null; + } + final BluetoothDevice device = mAdapter.getRemoteDevice(mMac); + if (device != null) { + mConnectThread = new ConnectThread(device, mReflections); + mConnectThread.start(); + } else { + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_NO_REMOTE_DEVICE); + } + } + + @Override + public void disconnect() { + cancelThreads(); + } + + @Override + public void write(byte[] out) { + mConnectedThread.write(out); + } + + + + + + //################################ + + private synchronized void cancelThreads() { + if (mConnectThread != null) { + mConnectThread.cancel(); + mConnectThread = null; + } + if (mConnectedThread != null) { + mConnectedThread.cancel(); + mConnectedThread = null; + } + } + + + private class ConnectThread extends Thread { + + private final BluetoothSocket mmSocket; + //private final BluetoothDevice mmDevice; + + public ConnectThread(BluetoothDevice device, boolean useReflection) { + //mmDevice = device; + BluetoothSocket tmp = null; + + try { + if (useReflection) { + Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}); + tmp = (BluetoothSocket) m.invoke(device, 1); + } else { + tmp = device.createRfcommSocketToServiceRecord(MY_UUID); + } + + } catch (IOException e) { + Util.log("Socket create() failed"); + } catch (Exception e) { + Util.log("Socket create() REFLECTION failed"); + e.printStackTrace(); + } + mmSocket = tmp; + } + + public void run() { + Util.log("BEGIN mConnectThread"); + + mAdapter.cancelDiscovery(); //else it will slow down connection + + try { + mmSocket.connect(); + } catch (IOException e) { + try { + mmSocket.close(); + } catch (IOException e2) { + Util.log("unable to close() socket during connection failure"); + } + mBTservice.connectionFailed(true, 0); + return; + } + + mConnectThread = null; + cancelThreads(); + + //now connected: + mConnectedThread = new ConnectedThread(mmSocket); + mConnectedThread.start(); + mBTservice.connectedEstablished(); + } + + public void cancel() { + try { + mmSocket.close(); + } catch (IOException e) { + Util.log("close() of connect socket failed"); + } + } + } + + + + private class ConnectedThread extends Thread { + + private final BluetoothSocket mmSocket; + private final InputStream mmInStream; + private final OutputStream mmOutStream; + + public ConnectedThread(BluetoothSocket socket) { + Util.log("create ConnectedThread"); + mmSocket = socket; + InputStream tmpIn = null; + OutputStream tmpOut = null; + + try { + tmpIn = socket.getInputStream(); + tmpOut = socket.getOutputStream(); + } catch (IOException e) { + Util.log("temp sockets not created"); + } + + mmInStream = tmpIn; + mmOutStream = tmpOut; + } + + + public void run() { + Util.log("BEGIN mConnectedThread"); + int rxTmp; + while (true) { + try { + rxTmp = mmInStream.read(); + mBTservice.onByteRx(rxTmp); + } catch (IOException e) { + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_CONNECTION_LOST); + break; + } + } + } + + public void write(byte[] buffer) { + try { + mmOutStream.write(buffer); + mmOutStream.flush(); + } catch (IOException e) { + Util.log("write() exception"); + } + } + + public void cancel() { + try { + mmSocket.close(); + } catch (IOException e) { + Util.log("socket close() exception"); + } + } + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BT40Connection.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BT40Connection.java new file mode 100644 index 00000000..eb0b1baf --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BT40Connection.java @@ -0,0 +1,286 @@ +package com.inputstick.api.bluetooth; + +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import android.annotation.SuppressLint; +import android.app.Application; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Handler; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Util; + +@SuppressLint("NewApi") +public class BT40Connection extends BTConnection { + + private static final int CONNECTION_TIMEOUT = 10000; + + private static final String MOD_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; + private static final String MOD_CONF = "0000ffe0-0000-1000-8000-00805f9b34fb"; + private static final String MOD_RX_TX = "0000ffe1-0000-1000-8000-00805f9b34fb"; + private static final UUID UUID_HM_RX_TX = UUID.fromString(MOD_RX_TX); + + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothGatt mBluetoothGatt; + private BluetoothGattCharacteristic characteristicTX; + private BluetoothGattCharacteristic characteristicRX; + + private LinkedList txBuffer; + private boolean canSend; + + private boolean isConnecting; + private Handler handler; + + public BT40Connection(Application app, BTService btService, String mac, boolean reflections) { + super(app, btService, mac, reflections); + mBluetoothManager = (BluetoothManager) (mCtx.getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + + } + + @Override + public void connect() { + final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mMac); + if (device != null) { + mBluetoothGatt = device.connectGatt(mCtx, false, mGattCallback); + + isConnecting = true; + handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + if (isConnecting) { + disconnect(); + mBTservice.connectionFailed(true, 0); + } + } + }, CONNECTION_TIMEOUT); + } else { + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_NO_REMOTE_DEVICE); + } + } + + @Override + public void disconnect() { + txBuffer = null; + try { + if (mBluetoothGatt != null) { + mBluetoothGatt.close(); + mBluetoothGatt.disconnect(); + mBluetoothGatt = null; + } + } catch (Exception e) { + + } + } + + + + @Override + public void write(byte[] out) { + byte[] tmp; + int offset = 0; + + //SPECIAL CASES for flashing utility + if (Util.flashingToolMode) { + //txBuffer.add(out); + //return; + if (out.length == 1) { + txBuffer.add(out); + return; + } + if (out.length == 1026) { + tmp = new byte[2]; + tmp[0] = out[0]; + tmp[1] = out[1]; + txBuffer.add(tmp); + offset = 2; + for (int i = 0; i < 64; i++) { + tmp = new byte[16]; + System.arraycopy(out, offset, tmp, 0, 16); + offset += 16; + txBuffer.add(tmp); + } + return; + } + } + + if (out.length == 2) { + addHeader(out); + } else { + Util.log("ADDING: " + out.length); + int loops = out.length / 16; + offset = 0; + for (int i = 0; i < loops; i++) { + tmp = new byte[16]; + System.arraycopy(out, offset, tmp, 0, 16); + offset += 16; + addData16(tmp); + } + sendNext(); + } + } + + + private byte h0; + private byte h1; + private boolean header; + + private synchronized void addHeader(byte[] data) { + h0 = data[0]; + h1 = data[1]; + header = true; + } + + private synchronized void addData16(byte[] data) { + byte[] tmp; + int offset = 0; + if (txBuffer != null) { + if (header) { + header = false; + + tmp = new byte[18]; + offset = 2; + + tmp[0] = h0; + tmp[1] = h1; + } else { + tmp = new byte[16]; + offset = 0; + } + System.arraycopy(data, 0, tmp, offset, 16); + txBuffer.add(tmp); + } + } + + private synchronized byte[] getData() { + if (txBuffer != null) { + if (!txBuffer.isEmpty()) { + byte[] data = txBuffer.poll(); + return data; + } + } + return null; + } + + private synchronized void sendNext() { + if (canSend) { + byte[] data = getData(); + if (data != null) { + canSend = false; + characteristicTX.setValue(data); + characteristicTX.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); //TODO + //characteristicTX.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); //TODO + mBluetoothGatt.writeCharacteristic(characteristicTX); + } + } + } + + + + private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + isConnecting = false; + Util.log("Connected to GATT server."); + Util.log("Attempting to start service discovery:" + mBluetoothGatt.discoverServices()); + } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { + isConnecting = false; + Util.log("Disconnected from GATT server."); + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_CONNECTION_LOST); + } + } + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + Util.log("GATT onServicesDiscovered"); + List gattServices = null; + boolean serviceDiscovered = false; + if (mBluetoothGatt != null) { + gattServices = mBluetoothGatt.getServices(); + } + if (gattServices != null) { + String uuid = null; + characteristicRX = null; + for (BluetoothGattService gattService : gattServices) { + uuid = gattService.getUuid().toString(); + if (MOD_CONF.equals(uuid)) { + Util.log("BT LE - Serial Service Discovered"); + + characteristicTX = gattService.getCharacteristic(UUID_HM_RX_TX); + characteristicRX = gattService.getCharacteristic(UUID_HM_RX_TX); + if (characteristicRX == null) { + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_BT40_NO_SPP_SERVICE); + } else { + serviceDiscovered = true; + } + } + } + } + if (serviceDiscovered) { + //enable notifications + mBluetoothGatt.setCharacteristicNotification(characteristicRX, true); + if (UUID_HM_RX_TX.equals(characteristicRX.getUuid())) { + Util.log("RXTX SERVICE DISCOVERED!"); + BluetoothGattDescriptor descriptor = characteristicRX.getDescriptor(UUID.fromString(MOD_CHARACTERISTIC_CONFIG)); + descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + mBluetoothGatt.writeDescriptor(descriptor); + + txBuffer = new LinkedList(); + canSend = true; + sendNext(); + + mBTservice.connectedEstablished(); + } else { + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_BT40_NO_SPP_SERVICE); + } + } else { + Util.log("BT LE - Serial Service NOT FOUND"); + mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_BT40_NO_SPP_SERVICE); + } + } else { + Util.log("onServicesDiscovered received: " + status); + } + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + } + } + + @Override + public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + byte b[] = characteristic.getValue(); + if (b != null) { + mBTservice.onByteRx(b); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + Util.log("GATT onCharacteristicWrite"); + if (status == BluetoothGatt.GATT_SUCCESS) { + canSend = true; + sendNext(); + } //TODO error code? + } + + }; + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BTConnection.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BTConnection.java new file mode 100644 index 00000000..a23e1e38 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BTConnection.java @@ -0,0 +1,26 @@ +package com.inputstick.api.bluetooth; + +import android.app.Application; +import android.content.Context; + + +public abstract class BTConnection { + + protected final Application mApp; + protected final Context mCtx; + protected final String mMac; + protected boolean mReflections; + protected final BTService mBTservice; + + public BTConnection(Application app, BTService btService, String mac, boolean reflections) { + mApp = app; + mCtx = app.getApplicationContext(); + mMac = mac; + mReflections = reflections; + mBTservice = btService; + } + + public abstract void connect(); + public abstract void disconnect(); + public abstract void write(byte[] out); +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BTService.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BTService.java new file mode 100644 index 00000000..2faddf35 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/BTService.java @@ -0,0 +1,231 @@ +package com.inputstick.api.bluetooth; + +import android.app.Application; +import android.bluetooth.BluetoothAdapter; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Handler; +import android.os.Message; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Util; + +public class BTService { + + public static final int DEFAULT_CONNECT_TIMEOUT = 30000; + + public static final int EVENT_NONE = 0; + public static final int EVENT_DATA = 1; + public static final int EVENT_CONNECTED = 2; + public static final int EVENT_CANCELLED = 3; + public static final int EVENT_ERROR = 4; + + + private final Handler mHandler; + private int mLastEvent; + + private String mMac; + private final Application mApp; + private final Context mCtx; + + private boolean mUseReflection; + private int mConnectTimeout; + + private long timeout; + private int retryCnt; + + private boolean disconnecting; + private boolean connected; + + private PacketReader mPacketReader; + private BTConnection mBTConnection; + + private boolean turnBluetoothOn; + private boolean receiverRegistered; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { + final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); + if ((state == BluetoothAdapter.STATE_ON) && (turnBluetoothOn)) { + turnBluetoothOn = false; + connect(false); + } + } + } + }; + + + + public BTService(Application app, Handler handler) { + mLastEvent = EVENT_NONE; + mHandler = handler; + mApp = app; + mCtx = app.getApplicationContext(); + mConnectTimeout = DEFAULT_CONNECT_TIMEOUT; + } + + public void setConnectTimeout(int timeout) { + mConnectTimeout = timeout; + } + + public void enableReflection(boolean enabled) { + mUseReflection = enabled; + } + + + protected synchronized void event(int event, int arg1) { + Util.log("event() " + mLastEvent + " -> " + event); + mLastEvent = event; + Message msg = Message.obtain(null, mLastEvent, arg1, 0); + mHandler.sendMessage(msg); + } + + public synchronized int getLastEvent() { + return mLastEvent; + } + + private void connect(boolean reconnecting) { + if (reconnecting) { + retryCnt++; + } else { + retryCnt = 0; + timeout = System.currentTimeMillis() + mConnectTimeout; + } + + mBTConnection.connect(); + } + + + public synchronized void connect(String mac) { + connect(mac, false); + } + + public synchronized void connect(String mac, boolean doNotAsk) { + connect(mac, doNotAsk, false); + } + + public synchronized void connect(String mac, boolean doNotAsk, boolean bt40) { + try { + Util.log("connect to: " + mac + " REFLECTION: " + mUseReflection); + disconnecting = false; + connected = false; + mMac = mac; + if (BluetoothAdapter.checkBluetoothAddress(mac)) { + BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (mBluetoothAdapter == null) { + event(BTService.EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_NOT_SUPPORTED); + } else { + if (bt40) { + mBTConnection = new BT40Connection(mApp, this, mMac, mUseReflection); + } else { + mBTConnection = new BT20Connection(mApp, this, mMac, mUseReflection); + } + + if (mBluetoothAdapter.isEnabled()) { + connect(false); + } else { + //enableBluetooth(doNotAsk); : + if (mApp != null) { + turnBluetoothOn = true; + + if ( !receiverRegistered) { + IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); + mCtx.registerReceiver(mReceiver, filter); + receiverRegistered = true; + } + + if (doNotAsk) { + BluetoothAdapter.getDefaultAdapter().enable(); + } else { + Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); + enableBtIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mApp.startActivity(enableBtIntent); + } + } + } + } + } else { + event(BTService.EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_INVALID_MAC); + } + } catch (NoClassDefFoundError e) { + event(BTService.EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_BT40_NOT_SUPPRTED); + } + } + + public synchronized void disconnect() { + Util.log("disconnect"); + disconnecting = true; + if (mBTConnection != null) { + mBTConnection.disconnect(); + } + event(EVENT_CANCELLED, 0); + } + + + public synchronized void write(byte[] out) { + if (connected) { + mBTConnection.write(out); + } + } + + + + + protected synchronized void connectedEstablished() { + removeReceiver(); //TODO + mPacketReader = new PacketReader(this, mHandler); + timeout = 0; + connected = true; + event(EVENT_CONNECTED, 0); + } + + + protected void connectionFailed(boolean canRetry, int errorCode) { + removeReceiver(); //TODO + connected = false; + if (disconnecting) { + disconnecting = false; + } else { + if (canRetry) { + if ((timeout > 0) && (System.currentTimeMillis() < timeout)) { + Util.log("RETRY: "+retryCnt + " time left: " + (timeout - System.currentTimeMillis())); + connect(true); + } else { + event(EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_CONNECTION_FAILED); + } + } else { + event(EVENT_ERROR, errorCode); + } + } + } + + + protected synchronized void onByteRx(int rxByte) { + mPacketReader.rxByte((byte)rxByte); + } + + protected synchronized void onByteRx(byte[] rxBytes) { + for (int i = 0; i < rxBytes.length; i++) { + mPacketReader.rxByte(rxBytes[i]); + } + } + + + private void removeReceiver() { + if (receiverRegistered) { + mCtx.unregisterReceiver(mReceiver); + receiverRegistered = false; + } + } + + + + public static boolean isBT40Supported() { + return (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR2); + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/PacketReader.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/PacketReader.java new file mode 100644 index 00000000..f8f66727 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/bluetooth/PacketReader.java @@ -0,0 +1,88 @@ +package com.inputstick.api.bluetooth; + +import android.os.Handler; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Packet; +import com.inputstick.api.Util; + +public class PacketReader { + + private static final int RX_TIMEOUT = 3000; + + private static final int RX_TAG = 0; + private static final int RX_LENGTH = 1; + private static final int RX_DATA = 2; + + private long lastRxTime; + private int rxState; + private int rxPos; + private int rxLength; + private byte[] rxData; + private int rxWdgCnt; + + private final BTService mBTService; + private final Handler mHandler; + + public PacketReader(BTService btService, Handler handler) { + mBTService = btService; + mHandler = handler; + } + + + public void rxByte(byte b) { + //byte b = (byte)rxByte; + long time = System.currentTimeMillis(); + if (time > lastRxTime + RX_TIMEOUT) { + rxState = RX_TAG; + } + + + switch (rxState) { + case RX_TAG: + if (b == Packet.START_TAG) { + rxState = RX_LENGTH; + } else { + Util.log("Unexpected RX byte" + b); + if (b == 0xAF) { + rxWdgCnt++; + } + if (rxWdgCnt > 1024) { + rxWdgCnt = 0; + mBTService.event(BTService.EVENT_ERROR, InputStickError.ERROR_HARDWARE_WDG_RESET); + } + } + break; + case RX_LENGTH: + rxLength = b; + rxLength &= 0x3F; + rxLength *= 16; + rxLength += 2; + rxPos = 2; + + rxData = new byte[rxLength]; + rxData[0] = Packet.START_TAG; + rxData[1] = (byte)b; + + rxState = RX_DATA; + break; + case RX_DATA: + if (rxPos < rxLength) { + rxData[rxPos] = b; + rxPos++; + if (rxPos == rxLength) { + //done! + mHandler.obtainMessage(BTService.EVENT_DATA, 0, 0, rxData).sendToTarget(); + rxState = RX_TAG; + } + } else { + //buffer overrun! + rxState = RX_TAG; + } + break; + } + + lastRxTime = time; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/broadcast/InputStickBroadcast.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/broadcast/InputStickBroadcast.java new file mode 100644 index 00000000..f8736bdc --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/broadcast/InputStickBroadcast.java @@ -0,0 +1,430 @@ +package com.inputstick.api.broadcast; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager.NameNotFoundException; + +import com.inputstick.api.DownloadDialog; + + +/* + * IMPORTANT: + * + * Using InputStickBroadcast is the easiest and fastest way to use InputStick with your application. + * InputStickUility takes care of almost everything: + * -enabling Bluetooth if necessary, + * -selecting InputStick device (if more than one is available), + * -establishing connection, + * -deals with potential connection problems (connection failed, lost), + * -user preferences (keyboard layout, typing speed). + * + * as a result of that, your application has little to no control over: + * -connection, + * -buffers + * -timing, + * + * + * Using InputStickBroadcast is recommended only for simple use cases: typing strings. + * Example: barcode scanner app, assuming that user will use InputStick to type only some of scanned codes. + * + * Using InputStickBroadcast is NOT recommended if + * -timing is critical, + * -low latency is necessary, + * -many actions can be executed in a short period of time + * + * Example: remote control app. + * + * In such case use classes from com.inputstick.api.hid package and implement all necessary callbacks. + * + */ + + +public class InputStickBroadcast { + + private static boolean AUTO_SUPPORT_CHECK; + + public static final String PARAM_REQUEST = "REQUEST"; + public static final String PARAM_RELEASE = "RELEASE"; + public static final String PARAM_CLEAR = "CLEAR"; + + public static final String PARAM_TEXT = "TEXT"; + public static final String PARAM_LAYOUT = "LAYOUT"; + public static final String PARAM_MULTIPLIER = "MULTIPLIER"; + public static final String PARAM_KEY = "KEY"; + public static final String PARAM_MODIFIER = "MODIFIER"; + public static final String PARAM_REPORT_KEYB = "REPORT_KEYB"; + public static final String PARAM_REPORT_EMPTY = "REPORT_EMPTY"; + + public static final String PARAM_REPORT_MOUSE = "REPORT_MOUSE"; + public static final String PARAM_MOUSE_BUTTONS ="MOUSE_BUTTONS"; + public static final String PARAM_MOUSE_CLICKS = "MOUSE_CLICKS"; + + public static final String PARAM_CONSUMER = "CONSUMER"; + + + + + /* + * Checks whether InputStickUtility is installed and supports intents (version code >= 11). + * Optionally download dialog can be displayed if InputStickUtility is not installed. + * + * @param ctx context + * @param allowMessages when true, download dialog will be displayed if necessary + * + */ + public static boolean isSupported(Context ctx, boolean allowMessages) { + PackageInfo pInfo; + try { + pInfo = ctx.getPackageManager().getPackageInfo("com.inputstick.apps.inputstickutility", 0); + //System.out.println("ver: " + pInfo.versionName + " code: " + pInfo.versionCode); + if (pInfo.versionCode < 11) { + if (allowMessages) { + DownloadDialog.getDialog(ctx, DownloadDialog.NOT_UPDATED).show(); + } + return false; + } else { + return true; + } + } catch (NameNotFoundException e) { + //e.printStackTrace(); + //InputStickUtility not installed + if (allowMessages) { + DownloadDialog.getDialog(ctx, DownloadDialog.NOT_INSTALLED).show(); + } + return false; + } + } + + + /* + * When Auto Support Check is enabled, isSupported(ctx, true) will be called each time before sending broadcast. + * You do not have to check support manually. Download dialog will be displayed if InputStickUtility is not installed. + * + * WARNING: checking support each time after sending broadcast can be very time consuming!!! + * + * @param enabled true to enable Auto Support Check, false to disable + */ + public static void setAutoSupportCheck(boolean enabled) { + AUTO_SUPPORT_CHECK = enabled; + } + + + /* + * Indicates that it is very likely that this application will want to use InputStick within next few seconds. + * Depending on user preferences this action may be ignored! In such case InputStickUtility will wait until some data arrives (text etc.). + * In many cases this will allow to reduce delay between requesting some action and executing it (typing text etc). + * + * @param ctx context used to send broadcast. + */ + public static void requestConnection(Context ctx) { + Intent intent = new Intent(); + intent.putExtra(PARAM_REQUEST, true); + send(ctx, intent); + } + + + /* + * Indicates that application will no longer need InputStick in nearest future. + * Allows to save power. + * Depending on user preferences this action may be ignored! + * Ignored if not connected. + * + * @param ctx context used to send broadcast. + */ + public static void releaseConnection(Context ctx) { + Intent intent = new Intent(); + intent.putExtra(PARAM_RELEASE, true); + send(ctx, intent); + } + + + /* + * Removes all actions from queue. Clears all interface buffers. + * Use to immediately stop all actions + * Depending on user preferences this action may be ignored! + * + * @param ctx context used to send broadcast. + */ + public static void clearQueue(Context ctx) { + Intent intent = new Intent(); + intent.putExtra(PARAM_CLEAR, true); + send(ctx, intent); + } + + + + + //####################################################################################################### + //##### KEYBOARD INTERFACE ############################################################################## + //####################################################################################################### + + + /* + * Puts "type text" action into queue. Fastest typing speed, use en-US layout. + * + * @param ctx context used to send broadcast. + * @param text text to be typed. \n and \t characters are allowed. + */ + public static void type(Context ctx, String text) { + type(ctx, text, null, 1); + } + + + /* + * Puts "type text" action into queue. Fastest typing speed. + * + * Keyboard layout must match layout used by USB host. en-US is used by default. + * Depending on user preferences value of layoutCode may be ignored! + * + * @param ctx context used to send broadcast + * @param text text to be typed. \n and \t characters are allowed. + * @param layoutCode keyboard layout to be used: en-US, de-DE, pl-PL etc. + */ + public static void type(Context ctx, String text, String layoutCode) { + type(ctx, text, layoutCode, 1); + } + + + /* + * Puts "type text" action into queue. + * + * Keyboard layout must match layout used by USB host. en-US is used by default. + * Depending on user preferences value of layoutCode may be ignored! + * + * When multiplier is set to 1, keys will be "pressed" at fastest possible speed. Increase value of this parameter to obtain slower typing speed, by multiplying number of HID keyboard reports. + * Depending on user preferences value of multiplier may be ignored! + * + * @param ctx context used to send broadcast + * @param text text to be typed. \n and \t characters are allowed. + * @param layoutCode keyboard layout to be used: en-US, de-DE, pl-PL etc. + * @param multiplier controls typing speed. + */ + public static void type(Context ctx, String text, String layoutCode, int multiplier) { + Intent intent = new Intent(); + + intent.putExtra(PARAM_TEXT, text); + if (layoutCode != null) { + intent.putExtra(PARAM_LAYOUT, layoutCode); + } + if (multiplier > 1) { + intent.putExtra(PARAM_MULTIPLIER, multiplier); + } + send(ctx, intent); + } + + + /* + * Puts "press and release key" action into queue. + * + * @param ctx context used to send broadcast. + * @param modifiers modifier keys: Shift, Alt, Ctrl, Gui/Win/Command keys, (see HIDKeycodes class. + * @param key any non-modifier key, see HIDKeycodes class. + */ + public static void pressAndRelease(Context ctx, byte modifiers, byte key) { + pressAndRelease(ctx, modifiers, key, 1); + } + + + /* + * Puts "press and release key" action into queue. + * When multiplier is set to 1, keys will be "pressed" at fastest possible speed. Increase value of this parameter to obtain slower typing speed, by multiplying number of HID reports. + * + * @param ctx context used to send broadcast. + * @param modifiers modifier keys: Shift, Alt, Ctrl, Gui/Win/Command keys, (see HIDKeycodes class). + * @param key any non-modifier key, see HIDKeycodes class. + * @param multiplier controls typing speed. + */ + public static void pressAndRelease(Context ctx, byte modifiers, byte key, int multiplier) { + Intent intent = new Intent(); + + intent.putExtra(PARAM_MODIFIER, modifiers); + intent.putExtra(PARAM_KEY, key); + if (multiplier > 1) { + intent.putExtra(PARAM_MULTIPLIER, multiplier); + } + send(ctx, intent); + } + + + /* + * Puts single HID keyboard report into queue. + * HID keyboard report represents state of keyboard (which keys are pressed) at a given moment. + * Must be 8 bytes long: + * report[0] = modifier keys + * report[1] = 0x00 + * report[2] = key1 + * report[3] = key2 + * report[4] = key3 + * report[5] = key4 + * report[6] = key5 + * report[7] = key6 + * To avoid keys getting "stuck" they should be released (by adding empty report). + * + * @param ctx context used to send broadcast. + * @param report HID keyboard report. + * @param addEmptyReport empty keyboard report (all keys released) will be added if true. + */ + public static void keyboardReport(Context ctx, byte[] report, boolean addEmptyReport) { + Intent intent = new Intent(); + intent.putExtra(PARAM_REPORT_KEYB, report); + if (addEmptyReport) { + intent.putExtra(PARAM_REPORT_EMPTY, true); + } + send(ctx, intent); + } + + + /* + * Puts single HID keyboard report into queue. + * HID keyboard report represents state of keyboard (which keys are pressed) at a given moment. + * To avoid keys getting "stuck" they should be released (by adding empty report). + * + * @param ctx context used to send broadcast. + * @param modifiers modifier keys: Shift, Alt, Ctrl, Gui/Win/Command keys, (see HIDKeycodes class). + * @param key1 any non-modifier key, see HIDKeycodes class. + * @param key2 any non-modifier key, see HIDKeycodes class. + * @param key3 any non-modifier key, see HIDKeycodes class. + * @param key4 any non-modifier key, see HIDKeycodes class. + * @param key5 any non-modifier key, see HIDKeycodes class. + * @param key6 any non-modifier key, see HIDKeycodes class. + * @param addEmptyReport empty keyboard report (all keys released) will be added if true. + */ + public static void keyboardReport(Context ctx, byte modifiers, byte key1, byte key2, byte key3, byte key4, byte key5, byte key6, boolean addEmptyReport) { + byte[] report = new byte[8]; + report[0] = modifiers; + report[2] = key1; + report[3] = key2; + report[4] = key3; + report[5] = key4; + report[6] = key5; + report[7] = key6; + keyboardReport(ctx, report, addEmptyReport); + } + + + + + //####################################################################################################### + //##### MOUSE INTERFACE ################################################################################# + //####################################################################################################### + + + /* + * Puts single HID mouse report into queue. + * HID mouse report represents change in state of a mouse. + * Must be 4 bytes long: + * report[0] = buttons + * report[1] = x axis displacement + * report[2] = y axis displacement + * report[3] = scroll wheel displacement + * + * @param ctx context used to send broadcast. + * @param report HID mouse report. + */ + public static void mouseReport(Context ctx, byte[] report) { + Intent intent = new Intent(); + intent.putExtra(PARAM_REPORT_MOUSE, report); + send(ctx, intent); + } + + + /* + * Puts single HID mouse report into queue. + * Left mouse button = 0x01 + * Right mouse button = 0x02 + * Middle mouse button = 0x04 + * + * @param ctx context used to send broadcast. + * @param buttons mouse buttons to click. + * @param dx x axis displacement. + * @param dy y axis displacement. + * @param scroll scroll wheel displacement. + */ + public static void mouseReport(Context ctx, byte buttons, byte dx, byte dy, byte scroll) { + byte[] report = new byte[4]; + report[0] = buttons; + report[1] = dx; + report[2] = dy; + report[3] = scroll; + mouseReport(ctx, report); + } + + + /* + * Puts mouse click (button(s) press-release) action into queue. + * Left mouse button = 0x01 + * Right mouse button = 0x02 + * Middle mouse button = 0x04 + * + * @param ctx context used to send broadcast. + * @param buttons mouse buttons to click. + * @param n number of clicks. + */ + public static void mouseClick(Context ctx, byte buttons, int n) { + Intent intent = new Intent(); + intent.putExtra(PARAM_MOUSE_BUTTONS, buttons); + intent.putExtra(PARAM_MOUSE_CLICKS, n); + send(ctx, intent); + } + + + /* + * Puts mouse move action into queue. + * + * @param ctx context used to send broadcast. + * @param dx x axis displacement. + * @param dy y axis displacement. + */ + public static void mouseMove(Context ctx, byte dx, byte dy) { + mouseReport(ctx, (byte)0x00, dx, dy, (byte)0x00); + } + + + /* + * Puts mouse scroll action into queue. + * Positive values: scroll up; negative values: scroll down + * + * @param ctx context used to send broadcast. + * @param scroll scroll wheel displacement. + */ + public static void mouseScroll(Context ctx, byte scroll) { + mouseReport(ctx, (byte)0x00, (byte)0x00, (byte)0x00, scroll); + } + + + + + //####################################################################################################### + //##### CONSUMER CONTROL INTERFACE ###################################################################### + //####################################################################################################### + + /* + * Puts "consumer" action into queue. See InputStickConsumer class for list available actions. + * + * @param ctx context used to send broadcast. + * @param action code of consumer action. + */ + public static void consumerControlAction(Context ctx, int action) { + Intent intent = new Intent(); + intent.putExtra(PARAM_CONSUMER, action); + send(ctx, intent); + } + + + private static void send(Context ctx, Intent intent) { + intent.setAction("com.inputstick.apps.inputstickutility.HID"); + intent.setClassName("com.inputstick.apps.inputstickutility", "com.inputstick.apps.inputstickutility.service.HIDReceiver"); + + //if necessary, show download dialog message + if (AUTO_SUPPORT_CHECK) { + if (isSupported(ctx, true)) { + ctx.sendBroadcast(intent); + } + } else { + ctx.sendBroadcast(intent); + } + } + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/ConsumerReport.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/ConsumerReport.java new file mode 100644 index 00000000..b13ae68b --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/ConsumerReport.java @@ -0,0 +1,43 @@ +package com.inputstick.api.hid; + +import com.inputstick.api.Util; + +public class ConsumerReport extends HIDReport { + + public static final byte CONSUMER_REPORT_ID = 1; + public static final byte SYSTEM_REPORT_ID = 2; + public static final byte GAMEPAD_REPORT_ID = 3; + + public static final int SIZE = 3; + + private byte[] data; + + public ConsumerReport(byte id, byte b1, byte b2) { + data = new byte[SIZE]; + data[0] = id; + data[1] = b1; + data[2] = b2; + } + + public ConsumerReport(int usage) { + data = new byte[SIZE]; + data[0] = CONSUMER_REPORT_ID; + data[1] = Util.getLSB(usage); + data[2] = Util.getMSB(usage); + } + + public ConsumerReport() { + this(0); + } + + public byte[] getBytes() { + return data; + } + + public int getBytesCount() { + return SIZE; + } + + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/GamepadReport.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/GamepadReport.java new file mode 100644 index 00000000..242d4d9d --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/GamepadReport.java @@ -0,0 +1,32 @@ +package com.inputstick.api.hid; + +public class GamepadReport extends HIDReport { + + public static final int SIZE = 7; + + private byte[] data; + + public GamepadReport(byte b1, byte b2, byte x, byte y, byte z, byte rx) { + data = new byte[SIZE]; + data[0] = 3; + data[1] = b1; + data[2] = b2; + data[3] = x; + data[4] = y; + data[5] = z; + data[6] = rx; + } + + public GamepadReport() { + this((byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0); + } + + public byte[] getBytes() { + return data; + } + + public int getBytesCount() { + return SIZE; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDKeycodes.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDKeycodes.java new file mode 100644 index 00000000..3decb11e --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDKeycodes.java @@ -0,0 +1,436 @@ +package com.inputstick.api.hid; + +import android.util.SparseArray; + +public class HIDKeycodes { + + public static final byte NONE = 0x00; + + public static final byte CTRL_LEFT = 0x01; + public static final byte SHIFT_LEFT = 0x02; + public static final byte ALT_LEFT = 0x04; + public static final byte GUI_LEFT = 0x08; + public static final byte CTRL_RIGHT = 0x10; + public static final byte SHIFT_RIGHT = 0x20; + public static final byte ALT_RIGHT = 0x40; + public static final byte GUI_RIGHT = (byte)0x80; + + + public static final byte KEY_ENTER = 0x28; + public static final byte KEY_ESCAPE = 0x29; + public static final byte KEY_BACKSPACE = 0x2A; + public static final byte KEY_TAB = 0x2B; + public static final byte KEY_SPACEBAR = 0x2C; + + public static final byte KEY_CAPS_LOCK = 0x39; + + + public static final byte KEY_1 = 0x1E; + public static final byte KEY_2 = 0x1F; + public static final byte KEY_3 = 0x20; + public static final byte KEY_4 = 0x21; + public static final byte KEY_5 = 0x22; + public static final byte KEY_6 = 0x23; + public static final byte KEY_7 = 0x24; + public static final byte KEY_8 = 0x25; + public static final byte KEY_9 = 0x26; + public static final byte KEY_0 = 0x27; + + public static final byte KEY_F1 = 0x3A; + public static final byte KEY_F2 = 0x3B; + public static final byte KEY_F3 = 0x3C; + public static final byte KEY_F4 = 0x3D; + public static final byte KEY_F5 = 0x3E; + public static final byte KEY_F6 = 0x3F; + public static final byte KEY_F7 = 0x40; + public static final byte KEY_F8 = 0x41; + public static final byte KEY_F9 = 0x42; + public static final byte KEY_F10 = 0x43; + public static final byte KEY_F11 = 0x44; + public static final byte KEY_F12 = 0x45; + + public static final byte KEY_PRINT_SCREEN = 0x46; + public static final byte KEY_SCROLL_LOCK = 0x47; + public static final byte KEY_PASUE = 0x48; + public static final byte KEY_INSERT = 0x49; + public static final byte KEY_HOME = 0x4A; + public static final byte KEY_PAGE_UP = 0x4B; + public static final byte KEY_DELETE = 0x4C; + public static final byte KEY_END = 0x4D; + public static final byte KEY_PAGE_DOWN = 0x4E; + + public static final byte KEY_ARROW_RIGHT = 0x4F; + public static final byte KEY_ARROW_LEFT = 0x50; + public static final byte KEY_ARROW_DOWN = 0x51; + public static final byte KEY_ARROW_UP = 0x52; + + public static final byte KEY_NUM_LOCK = 0x53; + public static final byte KEY_NUM_SLASH = 0x54; + public static final byte KEY_NUM_STAR = 0x55; + public static final byte KEY_NUM_MINUS = 0x56; + public static final byte KEY_NUM_PLUS = 0x57; + public static final byte KEY_NUM_ENTER = 0x58; + public static final byte KEY_NUM_1 = 0x59; + public static final byte KEY_NUM_2 = 0x5A; + public static final byte KEY_NUM_3 = 0x5B; + public static final byte KEY_NUM_4 = 0x5C; + public static final byte KEY_NUM_5 = 0x5D; + public static final byte KEY_NUM_6 = 0x5E; + public static final byte KEY_NUM_7 = 0x5F; + public static final byte KEY_NUM_8 = 0x60; + public static final byte KEY_NUM_9 = 0x61; + public static final byte KEY_NUM_0 = 0x62; + public static final byte KEY_NUM_DOT = 0x63; + + public static final byte KEY_BACKSLASH_NON_US = 0x64; + + public static final byte KEY_A = 0x04; + public static final byte KEY_B = 0x05; + public static final byte KEY_C = 0x06; + public static final byte KEY_D = 0x07; + public static final byte KEY_E = 0x08; + public static final byte KEY_F = 0x09; + public static final byte KEY_G = 0x0A; + public static final byte KEY_H = 0x0B; + public static final byte KEY_I = 0x0C; + public static final byte KEY_J = 0x0D; + public static final byte KEY_K = 0x0E; + public static final byte KEY_L = 0x0F; + public static final byte KEY_M = 0x10; + public static final byte KEY_N = 0x11; + public static final byte KEY_O = 0x12; + public static final byte KEY_P = 0x13; + public static final byte KEY_Q = 0x14; + public static final byte KEY_R = 0x15; + public static final byte KEY_S = 0x16; + public static final byte KEY_T = 0x17; + public static final byte KEY_U = 0x18; + public static final byte KEY_V = 0x19; + public static final byte KEY_W = 0x1A; + public static final byte KEY_X = 0x1B; + public static final byte KEY_Y = 0x1C; + public static final byte KEY_Z = 0x1D; + + + + public static final byte KEY_MINUS = 0x2D; + public static final byte KEY_EQUALS = 0x2E; + public static final byte KEY_LEFT_BRACKET = 0x2F; + public static final byte KEY_RIGHT_BRACKET = 0x30; + public static final byte KEY_BACKSLASH = 0x31; + //public static final byte KEY_GRAVE = 0x32; + public static final byte KEY_SEMICOLON = 0x33; + public static final byte KEY_APOSTROPHE = 0x34; + public static final byte KEY_GRAVE = 0x35; + public static final byte KEY_COMA = 0x36; + public static final byte KEY_DOT = 0x37; + public static final byte KEY_SLASH = 0x38; + + + public static final byte KEY_APPLICATION = 0x65; + + + + public static final SparseArray modifiersMap; + static + { + modifiersMap = new SparseArray(); + modifiersMap.put(CTRL_LEFT, "Left Ctrl"); + modifiersMap.put(SHIFT_LEFT, "Left Shift"); + modifiersMap.put(ALT_LEFT, "Left Alt"); + modifiersMap.put(GUI_LEFT, "Left GUI"); + modifiersMap.put(CTRL_RIGHT, "Right Ctrl"); + modifiersMap.put(SHIFT_RIGHT, "Right Shift"); + modifiersMap.put(ALT_RIGHT, "Right Alt"); + modifiersMap.put(GUI_RIGHT, "Right GUI"); + } + + public static final SparseArray keyMap; + static + { + keyMap = new SparseArray(); + keyMap.put(0, "None"); + keyMap.put(KEY_ENTER, "Enter"); + keyMap.put(KEY_ESCAPE , "Esc"); + keyMap.put(KEY_BACKSPACE , "Backspace"); + keyMap.put(KEY_TAB , "Tab"); + keyMap.put(KEY_SPACEBAR , "Space"); + + keyMap.put(KEY_CAPS_LOCK , "CapsLock"); + + keyMap.put(KEY_1 , "1"); + keyMap.put(KEY_2 , "2"); + keyMap.put(KEY_3 , "3"); + keyMap.put(KEY_4 , "4"); + keyMap.put(KEY_5 , "5"); + keyMap.put(KEY_6 , "6"); + keyMap.put(KEY_7 , "7"); + keyMap.put(KEY_8 , "8"); + keyMap.put(KEY_9 , "9"); + keyMap.put(KEY_0 , "0"); + + keyMap.put(KEY_F1 , "F1"); + keyMap.put(KEY_F2 , "F2"); + keyMap.put(KEY_F3 , "F3"); + keyMap.put(KEY_F4 , "F4"); + keyMap.put(KEY_F5 , "F5"); + keyMap.put(KEY_F6 , "F6"); + keyMap.put(KEY_F7 , "F7"); + keyMap.put(KEY_F8 , "F8"); + keyMap.put(KEY_F9 , "F9"); + keyMap.put(KEY_F10 , "F10"); + keyMap.put(KEY_F11 , "F11"); + keyMap.put(KEY_F12 , "F12"); + + keyMap.put(KEY_PRINT_SCREEN , "Print Scrn"); + keyMap.put(KEY_SCROLL_LOCK , "ScrollLock"); + keyMap.put(KEY_PASUE , "Pause Break"); + keyMap.put(KEY_INSERT , "Insert"); + keyMap.put(KEY_HOME , "Home"); + keyMap.put(KEY_PAGE_UP , "PageUp"); + keyMap.put(KEY_DELETE , "Delete"); + keyMap.put(KEY_END , "End"); + keyMap.put(KEY_PAGE_DOWN , "PageDown"); + + keyMap.put(KEY_ARROW_RIGHT , "Right Arrow"); + keyMap.put(KEY_ARROW_LEFT , "Left Arrow"); + keyMap.put(KEY_ARROW_DOWN , "Down Arrow"); + keyMap.put(KEY_ARROW_UP , "Up Arrow"); + + keyMap.put(KEY_NUM_LOCK , "NumLock"); + keyMap.put(KEY_NUM_SLASH , "Num /"); + keyMap.put(KEY_NUM_STAR , "Num *"); + keyMap.put(KEY_NUM_MINUS , "Num -"); + keyMap.put(KEY_NUM_PLUS , "Num +"); + keyMap.put(KEY_NUM_ENTER , "Num Enter"); + keyMap.put(KEY_NUM_1 , "Num 1"); + keyMap.put(KEY_NUM_2 , "Num 2"); + keyMap.put(KEY_NUM_3 , "Num 3"); + keyMap.put(KEY_NUM_4 , "Num 4"); + keyMap.put(KEY_NUM_5 , "Num 5"); + keyMap.put(KEY_NUM_6 , "Num 6"); + keyMap.put(KEY_NUM_7 , "Num 7"); + keyMap.put(KEY_NUM_8 , "Num 8"); + keyMap.put(KEY_NUM_9 , "Num 9"); + keyMap.put(KEY_NUM_0 , "Num 0"); + keyMap.put(KEY_NUM_DOT , "Num ."); + + keyMap.put(KEY_A , "A"); + keyMap.put(KEY_B , "B"); + keyMap.put(KEY_C , "C"); + keyMap.put(KEY_D , "D"); + keyMap.put(KEY_E , "E"); + keyMap.put(KEY_F , "F"); + keyMap.put(KEY_G , "G"); + keyMap.put(KEY_H , "H"); + keyMap.put(KEY_I , "I"); + keyMap.put(KEY_J , "J"); + keyMap.put(KEY_K , "K"); + keyMap.put(KEY_L , "L"); + keyMap.put(KEY_M , "M"); + keyMap.put(KEY_N , "N"); + keyMap.put(KEY_O , "O"); + keyMap.put(KEY_P , "P"); + keyMap.put(KEY_Q , "Q"); + keyMap.put(KEY_R , "R"); + keyMap.put(KEY_S , "S"); + keyMap.put(KEY_T , "T"); + keyMap.put(KEY_U , "U"); + keyMap.put(KEY_V , "V"); + keyMap.put(KEY_W , "W"); + keyMap.put(KEY_X , "X"); + keyMap.put(KEY_Y , "Y"); + keyMap.put(KEY_Z , "Z"); + + keyMap.put(KEY_MINUS , "-"); + keyMap.put(KEY_EQUALS , "="); + keyMap.put(KEY_LEFT_BRACKET , "["); + keyMap.put(KEY_RIGHT_BRACKET , "]"); + keyMap.put(KEY_BACKSLASH , "\\"); + //keyMap.put(KEY_GRAVE , "`"); + keyMap.put(KEY_SEMICOLON , ";"); + keyMap.put(KEY_APOSTROPHE , "'"); + keyMap.put(KEY_GRAVE , "`"); + keyMap.put(KEY_COMA , ","); + keyMap.put(KEY_DOT , "."); + keyMap.put(KEY_SLASH , "/"); + + keyMap.put(KEY_APPLICATION , "Application"); + } + + public static final int[] ASCIItoHID = { + 0, //000 + 0, //001 + 0, //002 + 0, //003 + 0, //004 + 0, //005 + 0, //006 + 0, //007 + 0, //008 + 0, //009 + 0, //010 + 0, //011 + 0, //012 + 0, //013 + 0, //014 + 0, //015 + 0, //016 + 0, //017 + 0, //018 + 0, //019 + 0, //020 + 0, //021 + 0, //022 + 0, //023 + 0, //024 + 0, //025 + 0, //026 + 0, //027 + 0, //028 + 0, //029 + 0, //030 + 0, //031 + 44, //032 space + 128 + 30, //033 ! [SHIFT] + 128 + 52, //034 " [SHIFT] + 128 + 32, //035 # [SHIFT] + 128 + 33, //036 $ [SHIFT] + 128 + 34, //037 % [SHIFT] + 128 + 36, //038 & [SHIFT] + 52, //039 ' + 128 + 38, //040 ( [SHIFT] + 128 + 39, //041 ) [SHIFT] + 128 + 37, //042 * [SHIFT] + 128 + 46, //043 + [SHIFT] + 54, //044 , + 45, //045 - (-) + 55, //046 . (.) + 56, //047 / + 39, //048 0 + 30, //049 1 + 31, //050 2 + 32, //051 3 + 33, //052 4 + 34, //053 5 + 35, //054 6 + 36, //055 7 + 37, //056 8 + 38, //057 9 + 128 + 51, //058 : [SHIFT] + 51, //059 ; + 128 + 54, //060 < [SHIFT] + 46, //061 = + 128 + 55, //062 > [SHIFT] + 128 + 56, //063 ? [SHIFT] + 128 + 31, //064 @ [SHIFT] + 128 + 4, //065 A [SHIFT] + 128 + 5, //066 B [SHIFT] + 128 + 6, //067 C [SHIFT] + 128 + 7, //068 D [SHIFT] + 128 + 8, //069 E [SHIFT] + 128 + 9, //070 F [SHIFT] + 128 + 10, //071 G [SHIFT] + 128 + 11, //072 H [SHIFT] + 128 + 12, //073 I [SHIFT] + 128 + 13, //074 J [SHIFT] + 128 + 14, //075 K [SHIFT] + 128 + 15, //076 L [SHIFT] + 128 + 16, //077 M [SHIFT] + 128 + 17, //078 N [SHIFT] + 128 + 18, //079 O [SHIFT] + 128 + 19, //080 P [SHIFT] + 128 + 20, //081 Q [SHIFT] + 128 + 21, //082 R [SHIFT] + 128 + 22, //083 S [SHIFT] + 128 + 23, //084 T [SHIFT] + 128 + 24, //085 U [SHIFT] + 128 + 25, //086 V [SHIFT] + 128 + 26, //087 W [SHIFT] + 128 + 27, //088 X [SHIFT] + 128 + 28, //089 Y [SHIFT] + 128 + 29, //090 Z [SHIFT] + 47, //091 [ + 49, /*092 \ */ + 48, //093 ] + 128 + 35, //094 ^ [SHIFT] + 128 + 45, //095 _ [SHIFT] (underscore) + 128 + 53, //096 ` [SHIFT] (grave accent) + 4, //097 a + 5, //098 b + 6, //099 c + 7, //100 d + 8, //101 e + 9, //102 f + 10, //103 g + 11, //104 h + 12, //105 i + 13, //106 j + 14, //107 k + 15, //108 l + 16, //109 m + 17, //110 n + 18, //111 o + 19, //112 p + 20, //113 q + 21, //114 r + 22, //115 s + 23, //116 t + 24, //117 u + 25, //118 v + 26, //119 w + 27, //120 x + 28, //121 y + 29, //122 z + 128 + 47, //123 { [SHIFT] + 128 + 49, //124 | [SHIFT] + 128 + 48, //125 } [SHIFT] + 128 + 53, //126 ~ [SHIFT] + 0 //127 just in case... + }; + + public static char getChar(byte keyCode) { + for (int i = 0; i < ASCIItoHID.length; i++) { + if (ASCIItoHID[i] == keyCode) { + return (char)i; + } + } + return 0; + } + + public static byte getKeyCode(char c) { + return (byte)ASCIItoHID[c]; //TODO range + } + + public static int getKeyCode(int c) { + return ASCIItoHID[c]; //TODO range + } + + public static String modifiersToString(byte modifiers) { + String result = "None"; + boolean first = true; + byte mod; + for (int i = 0; i < 8; i++) { + mod = (byte)(CTRL_LEFT << i); + if ((modifiers & mod) != 0) { + if ( !first) { + result += ", "; + } else { + result = ""; + } + first = false; + result += modifiersMap.get(mod); + } + } + + return result; + } + + public static String keyToString(byte key) { + String result = keyMap.get(key); + if (result == null) { + result = "Unknown"; + } + return result; + } +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDReport.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDReport.java new file mode 100644 index 00000000..28cce791 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDReport.java @@ -0,0 +1,8 @@ +package com.inputstick.api.hid; + +public abstract class HIDReport { + + public abstract byte[] getBytes(); + public abstract int getBytesCount(); + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDTransaction.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDTransaction.java new file mode 100644 index 00000000..39de4683 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDTransaction.java @@ -0,0 +1,56 @@ +package com.inputstick.api.hid; + +import java.util.LinkedList; + +public class HIDTransaction { + + private int mID; + private LinkedList reports; + + public HIDTransaction() { + reports = new LinkedList(); + } + + public void addReport(HIDReport report) { + reports.add(report); + } + + public int getReportsCount() { + return reports.size(); + } + + public void setID(int id) { + mID = id; + } + + public int getID() { + return mID; + } + + public boolean hasNext() { + return !reports.isEmpty(); + } + + public byte[] getNextReport() { + return reports.poll().getBytes(); + } + + public HIDReport getHIDReportAt(int pos) { + return reports.get(pos); + } + + public HIDTransaction split(int n) { + HIDTransaction result = new HIDTransaction(); + HIDReport report; + if (n <= reports.size()) { + while(n > 0) { + report = reports.poll(); + result.addReport(report); + n--; + } + } + + return result; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDTransactionQueue.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDTransactionQueue.java new file mode 100644 index 00000000..f0cecdbd --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/HIDTransactionQueue.java @@ -0,0 +1,324 @@ +package com.inputstick.api.hid; + +import java.util.LinkedList; +import java.util.Timer; +import java.util.TimerTask; +import java.util.Vector; + +import com.inputstick.api.ConnectionManager; +import com.inputstick.api.HIDInfo; +import com.inputstick.api.OnEmptyBufferListener; +import com.inputstick.api.Packet; +import com.inputstick.api.basic.InputStickHID; + +public class HIDTransactionQueue { + + private static final int BUFFER_SIZE = 32; + private static final int BT_DELAY = 50; //additional delay for BT overhead + + private static final int MAX_PACKETS_PER_UPDATE = 10; + private static final int MAX_IMMEDIATE_PACKETS = 3; + + private final LinkedList queue; + private final ConnectionManager mConnectionManager; + private final byte cmd; + private boolean ready; + + private int mInterfaceType; + private boolean mustNotify; + + private Timer t; + private boolean timerCancelled; + private boolean sentAhead; + private long lastTime; + private long minNextTime; + private int lastReports; + + + // >= FW 0.93 + private boolean bufferInitDone; + private boolean constantUpdateMode; + private int bufferFreeSpace; + private int immediatePacketsLeft; + private int packetsSentSinceLastUpdate; + + private int interfaceReadyCnt; //fix BT4.0 lost packet problem + + public HIDTransactionQueue(int interfaceType, ConnectionManager connectionManager) { + constantUpdateMode = false; + bufferFreeSpace = BUFFER_SIZE; + interfaceReadyCnt = 0; + + queue = new LinkedList(); + mConnectionManager = connectionManager; + ready = false; + sentAhead = false; + minNextTime = 0; + + mustNotify = false; + + mInterfaceType = interfaceType; + switch (interfaceType) { + case InputStickHID.INTERFACE_KEYBOARD: + cmd = Packet.CMD_HID_DATA_KEYB; + //TODO mod + //cmd = Packet.CMD_HID_DATA_KEYB_FAST; + break; + case InputStickHID.INTERFACE_MOUSE: + cmd = Packet.CMD_HID_DATA_MOUSE; + break; + case InputStickHID.INTERFACE_CONSUMER: + cmd = Packet.CMD_HID_DATA_CONSUMER; + break; + default: + cmd = Packet.CMD_DUMMY; + } + } + + private int sendNext(int maxReports) { + HIDTransaction transaction; + + //assume there is at least 1 element in queue + transaction = queue.peek(); + if (transaction.getReportsCount() > maxReports) { + // v0.92 + if (maxReports < BUFFER_SIZE) { + //don't split transactions until there is no other way left! + return 0; + } + + //transaction too big to fit single packet! split + transaction = transaction.split(BUFFER_SIZE); + } else { + queue.removeFirst(); + } + + byte reports = 0; + ready = false; + Packet p = new Packet(false, cmd, reports); + + while (transaction.hasNext()) { + p.addBytes(transaction.getNextReport()); + //TODO mod + //byte[] r = transaction.getNextReport(); + //p.addByte(r[0]); + //p.addByte(r[2]); + + reports++; + } + + while(true) { + if (queue.isEmpty()) { + break; + } + + transaction = queue.peek(); + if (reports + transaction.getReportsCount() < maxReports) { + queue.removeFirst(); + while (transaction.hasNext()) { + p.addBytes(transaction.getNextReport()); + //TODO mod + //byte[] r = transaction.getNextReport(); + //p.addByte(r[0]); + //p.addByte(r[2]); + + reports++; + } + } else { + break; + } + } + + //!! total number of reports must be < 32 ! (max packet limitation) + p.modifyByte(1, reports); //set reports count + mConnectionManager.sendPacket(p); + + interfaceReadyCnt = 0; + lastReports = reports; + lastTime = System.currentTimeMillis(); + minNextTime = lastTime + (lastReports * 4) + BT_DELAY; + + if (queue.isEmpty()) { + notifyOnLocalBufferEmpty(); + } + + return reports; + } + + private void notifyOnRemoteBufferEmpty() { + Vector listeners = InputStickHID.getBufferEmptyListeners(); + for (OnEmptyBufferListener listener : listeners) { + listener.onRemoteBufferEmpty(mInterfaceType); + } + } + + private void notifyOnLocalBufferEmpty() { + Vector listeners = InputStickHID.getBufferEmptyListeners(); + for (OnEmptyBufferListener listener : listeners) { + listener.onLocalBufferEmpty(mInterfaceType); + } + } + + public synchronized boolean isLocalBufferEmpty() { + return queue.isEmpty(); + } + + public synchronized boolean isRemoteBufferEmpty() { + if ((queue.isEmpty()) && (bufferFreeSpace == BUFFER_SIZE)) { + return true; + } + + if (queue.isEmpty() && ( !mustNotify)) { + return true; + } else { + return false; + } + } + + public synchronized void clearBuffer() { + queue.clear(); + } + + public synchronized void addTransaction(HIDTransaction transaction) { + if ( !bufferInitDone) { + queue.add(transaction); + return; + } + + + if (constantUpdateMode) { + queue.add(transaction); + sendToBuffer(true); + return; + } + + + mustNotify = true; + //using sentAhead will slow down mouse. FW0.92 will solve the problems + if ((queue.isEmpty()) && (System.currentTimeMillis() > minNextTime) /*&& ( !sentAhead)*/) { + sentAhead = true; + ready = true; + } + + queue.add(transaction); + if (ready) { + sendNext(BUFFER_SIZE); + } + } + + private synchronized void timerAction() { + if ( !timerCancelled) { + if (sentAhead) { + deviceReady(null, 0); //will set sentAhead to false; + sentAhead = true; //restore value + } else { + deviceReady(null, 0); + } + } + } + + public synchronized void deviceReady(HIDInfo hidInfo, int reportsSentToHost) { + //it is possible that in the meantime some packets has been sent to IS!!! + + bufferInitDone = true; + + if (hidInfo != null) { + if (hidInfo.isSentToHostInfoAvailable()) { + + //BT4.0 lost packets fix: + if (bufferFreeSpace < BUFFER_SIZE) { + boolean interfaceReady = false; + if (mInterfaceType == InputStickHID.INTERFACE_KEYBOARD) { + interfaceReady = hidInfo.isKeyboardReady(); + } + if (mInterfaceType == InputStickHID.INTERFACE_MOUSE) { + interfaceReady = hidInfo.isMouseReady(); + } + if (mInterfaceType == InputStickHID.INTERFACE_CONSUMER) { + interfaceReady = hidInfo.isConsumerReady(); + } + if (interfaceReady) { + interfaceReadyCnt++; + if (interfaceReadyCnt == 10) { + bufferFreeSpace = BUFFER_SIZE; + } + } else { + interfaceReadyCnt = 0; + } + } + + + constantUpdateMode = true; + // >= FW 0.93 + bufferFreeSpace += reportsSentToHost; + if ((bufferFreeSpace == BUFFER_SIZE) && (queue.isEmpty())) { + notifyOnRemoteBufferEmpty(); + } + immediatePacketsLeft = MAX_IMMEDIATE_PACKETS; + //reportsSentSinceLastUpdate = 0; + packetsSentSinceLastUpdate = 0; + sendToBuffer(false); + return; + } + } + + + + long now = System.currentTimeMillis(); + //System.out.println("v90 HID update"); + if (now < minNextTime) { + //set timer, just in case if deviceReady won't be called again + timerCancelled = false; + t = new Timer(); + t.schedule(new TimerTask() { + @Override + public void run() { + timerAction(); + } + }, (minNextTime - now + 1)); + } else { + timerCancelled = true; + sentAhead = false; + if (!queue.isEmpty()) { + sendNext(BUFFER_SIZE); + } else { + ready = true; + //queue is empty, InputStick reported that buffer is empty, data was added since last notification + if (mustNotify) { + notifyOnRemoteBufferEmpty(); + mustNotify = false; + } + } + } + } + + public synchronized void sendToBuffer(boolean justAdded) { + if ((justAdded) && (immediatePacketsLeft <= 0)) { + return; + } + + if ( !InputStickHID.isReady()) { + return; + } + + if (queue.isEmpty()) { + return; + } + if (bufferFreeSpace <= 0) { + return; + } + if (packetsSentSinceLastUpdate >= MAX_PACKETS_PER_UPDATE) { + return; + } + + int reportsSent = sendNext(bufferFreeSpace); + if (reportsSent > 0) { + if (justAdded) { + immediatePacketsLeft --; + } + bufferFreeSpace -= reportsSent; + packetsSentSinceLastUpdate ++; + } + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/KeyboardReport.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/KeyboardReport.java new file mode 100644 index 00000000..7ece9b62 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/KeyboardReport.java @@ -0,0 +1,36 @@ +package com.inputstick.api.hid; + +public class KeyboardReport extends HIDReport { + + public static final int SIZE = 8; + + private byte[] data; + + public KeyboardReport(byte modifier, byte key0, byte key1, byte key2, byte key3, byte key4, byte key5) { + data = new byte[SIZE]; + data[0] = modifier; + data[2] = key0; + data[3] = key1; + data[4] = key2; + data[5] = key3; + data[6] = key4; + data[7] = key5; + } + + public KeyboardReport() { + this((byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0); + } + + public KeyboardReport(byte modifier, byte key) { + this(modifier, key, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0); + } + + public byte[] getBytes() { + return data; + } + + public int getBytesCount() { + return SIZE; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/MouseReport.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/MouseReport.java new file mode 100644 index 00000000..8454513e --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/hid/MouseReport.java @@ -0,0 +1,29 @@ +package com.inputstick.api.hid; + +public class MouseReport extends HIDReport { + + public static final int SIZE = 4; + + private byte[] data; + + public MouseReport(byte buttons, byte x, byte y, byte wheel) { + data = new byte[SIZE]; + data[0] = buttons; + data[1] = x; + data[2] = y; + data[3] = wheel; + } + + public MouseReport() { + this((byte)0, (byte)0, (byte)0, (byte)0); + } + + public byte[] getBytes() { + return data; + } + + public int getBytesCount() { + return SIZE; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/BasicInitManager.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/BasicInitManager.java new file mode 100644 index 00000000..a2082406 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/BasicInitManager.java @@ -0,0 +1,97 @@ +package com.inputstick.api.init; + +import android.os.Handler; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Packet; + + +public class BasicInitManager extends InitManager { + + private int lastStatusParam; + private Handler handler; + private boolean cancelled; + + public BasicInitManager(byte[] key) { + super(key); + lastStatusParam = 0; + } + + + @Override + public void onConnected() { + lastStatusParam = 0; + cancelled = false; + initDone = false; + sendPacket(new Packet(true, Packet.CMD_RUN_FW)); + + handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + if ((!cancelled) && ( !initDone)) { + sendPacket(new Packet(true, Packet.CMD_RUN_FW)); + } + } + }, 1000); + + handler.postDelayed(new Runnable() { + @Override + public void run() { + if ((!cancelled) && ( !initDone)) { + mListener.onInitFailure(InputStickError.ERROR_INIT_TIMEDOUT); + } + } + }, 2000); + } + + @Override + public void onDisconnected() { + cancelled = true; + } + + @Override + public void onData(byte[] data) { + byte cmd = data[0]; + byte respCode = data[1]; + byte param = data[1]; + + switch (cmd) { + case Packet.CMD_RUN_FW: + sendPacket(new Packet(true, Packet.CMD_FW_INFO)); + break; + case Packet.CMD_FW_INFO: + onFWInfo(data, true, true, new Packet(true, Packet.CMD_INIT)); //TODO next FW: params! + break; + case Packet.CMD_INIT: + if (respCode == Packet.RESP_OK) { + initDone = true; + sendPacket(new Packet(true, Packet.CMD_HID_STATUS_REPORT)); + } else { + mListener.onInitFailure(respCode); + } + break; + case Packet.CMD_INIT_AUTH: + initDone = onAuth(data, true, new Packet(true, Packet.CMD_INIT)); //TODO next FW: params! + break; + case Packet.CMD_HID_STATUS: + if (mKey == null) { + initDone = true; + } + + if (initDone) { + if (param != lastStatusParam) { + lastStatusParam = param; + if (param == 0x05) { + mListener.onInitReady(); + } else { + mListener.onInitNotReady(); + } + } + } + break; + } + } + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/DeviceInfo.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/DeviceInfo.java new file mode 100644 index 00000000..9e1dc49e --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/DeviceInfo.java @@ -0,0 +1,93 @@ +package com.inputstick.api.init; + +public class DeviceInfo { + + private int firmwareType; + private int versionMajor; + private int versionMinor; + private int versionHardware; + private int securityStatus; + + private boolean passwordProtected; + + public DeviceInfo(byte[] data) { + //cmd, param + firmwareType = data[2]; + versionMajor = data[3]; + versionMinor = data[4]; + versionHardware = data[5]; + + + //6,7,8,9 + //10,11,12,13 + //14,15,16,17 + + //18,19 + securityStatus = data[19]; + if (data[20] == 0) { + passwordProtected = false; + } else { + passwordProtected = true; + } + } + + public int getSecurityStatus() { + return securityStatus; + } + + public boolean isAuthenticated() { + return ((securityStatus & 0x10) != 0); + } + + public boolean isUnlocked() { + if (getFirmwareVersion() < 96) { + return true; + } else { + return ((securityStatus & 0x08) != 0); + } + } + + public int getFirmwareType() { + return firmwareType; + } + + public boolean isPasswordProtected() { + return passwordProtected; + } + + public int getVersionMinor() { + return versionMinor; + } + + public int getVersionMajor() { + return versionMajor; + } + + public int getHardwareVersion() { + return versionHardware; + } + + public int getFirmwareVersion() { + return (versionMajor) * 100 + versionMinor; + } + + + + public boolean supportsEncryption() { + return (getFirmwareVersion() >= 91); + } + + public boolean supportsPinChange() { + return (getFirmwareVersion() >= 97); + } + + public boolean supportsGamepad() { + return (getFirmwareVersion() >= 97); + } + + public boolean supportsRestoreOptions() { + return (getFirmwareVersion() >= 98); + } + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/InitManager.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/InitManager.java new file mode 100644 index 00000000..d4f8e445 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/InitManager.java @@ -0,0 +1,112 @@ +package com.inputstick.api.init; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Packet; +import com.inputstick.api.PacketManager; + +public class InitManager { + + public static final int DEFAULT_INIT_TIMEOUT = 60000; //60s init timeout + + protected PacketManager mPacketManager; + protected InitManagerListener mListener; + protected byte[] mKey; + protected DeviceInfo mInfo; + protected boolean initDone; + + public InitManager(byte[] key) { + mKey = key; + } + + + public DeviceInfo getDeviceInfo() { + return mInfo; + } + + public boolean isEncrypted() { + return mPacketManager.isEncrypted(); + } + + + public void init(InitManagerListener listener, PacketManager packetManager) { + mListener = listener; + mPacketManager = packetManager; + + initDone = false; + } + + public void onConnected() { + mListener.onInitReady(); + } + + public void onDisconnected() { + } + + public void onData(byte[] data) { + //byte cmd = data[0]; + //byte param = data[1]; + } + + public void sendPacket(Packet p) { + mPacketManager.sendPacket(p); + } + + public void onFWInfo(byte[] data, boolean authenticate, boolean enableEncryption, Packet sendNext) { + mInfo = new DeviceInfo(data); + + if (authenticate) { + if (mInfo.isPasswordProtected()) { + if (mKey != null) { + //authenticate + sendPacket(mPacketManager.encPacket(enableEncryption)); + } else { + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NO_KEY); + } + } else { + if (mKey != null) { + //possible scenarios: FW upgrade / password removed using other device/app / tampering! + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_PROTECTED); + } + sendPacket(sendNext); + } + } else { + sendPacket(sendNext); + } + } + + public boolean onAuth(byte[] data, boolean enableOutEncryption, Packet sendNext) { + byte respCode = data[1]; + + switch (respCode) { + case Packet.RESP_OK: + byte[] cmp = new byte[16]; + //TODO check length! + System.arraycopy(data, 2, cmp, 0, 16); + if (mPacketManager.setEncryption(cmp, enableOutEncryption)) { + sendPacket(sendNext); + return true; + } else { + mListener.onInitFailure(InputStickError.ERROR_SECURITY_CHALLENGE); + } + break; + + case 0x20: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_INVALID_KEY); + break; + + case 0x21: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_PROTECTED); + break; + + case Packet.RESP_UNKNOWN_CMD: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_SUPPORTED); + break; + + default: + mListener.onInitFailure(InputStickError.ERROR_SECURITY); + } + return false; + + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/InitManagerListener.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/InitManagerListener.java new file mode 100644 index 00000000..10cff787 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/init/InitManagerListener.java @@ -0,0 +1,9 @@ +package com.inputstick.api.init; + +public interface InitManagerListener { + + public void onInitReady(); + public void onInitNotReady(); + public void onInitFailure(int code); + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/DanishLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/DanishLayout.java new file mode 100644 index 00000000..ad0ee880 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/DanishLayout.java @@ -0,0 +1,390 @@ +package com.inputstick.api.layout; + +public class DanishLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "da-DK"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 53, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 31, 0, 0 }, + { 35, 2, 32, 0, 0 }, + { 36, 64, 33, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 35, 0, 0 }, + { 39, 0, 49, 0, 0 }, + { 40, 2, 37, 0, 0 }, + { 41, 2, 38, 0, 0 }, + { 42, 2, 49, 0, 0 }, + { 43, 0, 45, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 56, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 2, 36, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 55, 0, 0 }, + { 59, 2, 54, 0, 0 }, + { 60, 0, 100, 0, 0 }, + { 61, 2, 39, 0, 0 }, + { 62, 2, 100, 0, 0 }, + { 63, 2, 45, 0, 0 }, + { 64, 64, 31, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 29, 0, 0 }, + { 91, 64, 37, 0, 0 }, + { 92, 64, 100, 0, 0 }, + { 93, 64, 38, 0, 0 }, + { 94, 0, 44, 2, 48 }, + { 95, 2, 56, 0, 0 }, + { 96, 0, 44, 2, 46 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 28, 0, 0 }, + { 122, 0, 29, 0, 0 }, + { 123, 64, 36, 0, 0 }, + { 124, 64, 46, 0, 0 }, + { 125, 64, 39, 0, 0 }, + { 126, 0, 44, 64, 48 }, + { 163, 64, 32, 0, 0 }, + { 164, 2, 33, 0, 0 }, + { 167, 2, 53, 0, 0 }, + { 168, 0, 44, 0, 48 }, + { 180, 0, 44, 0, 46 }, + { 181, 64, 16, 0, 0 }, + { 189, 0, 53, 0, 0 }, + { 192, 2, 4, 2, 46 }, + { 193, 2, 4, 0, 46 }, + { 194, 2, 4, 2, 48 }, + { 195, 2, 4, 64, 48 }, + { 196, 2, 4, 0, 48 }, + { 197, 2, 47, 0, 0 }, + { 198, 2, 51, 0, 0 }, + { 200, 2, 8, 2, 46 }, + { 201, 2, 8, 0, 46 }, + { 202, 2, 8, 2, 48 }, + { 203, 2, 8, 0, 48 }, + { 204, 2, 12, 2, 46 }, + { 205, 2, 12, 0, 46 }, + { 206, 2, 12, 2, 48 }, + { 207, 2, 12, 0, 48 }, + { 209, 2, 17, 64, 48 }, + { 210, 2, 18, 2, 46 }, + { 211, 2, 18, 0, 46 }, + { 212, 2, 18, 2, 48 }, + { 213, 2, 18, 64, 48 }, + { 214, 2, 18, 0, 48 }, + { 216, 2, 52, 0, 0 }, + { 217, 2, 24, 2, 46 }, + { 218, 2, 24, 0, 46 }, + { 219, 2, 24, 2, 48 }, + { 220, 2, 24, 0, 48 }, + { 221, 2, 28, 0, 46 }, + { 224, 0, 4, 2, 46 }, + { 225, 0, 4, 0, 46 }, + { 226, 0, 4, 2, 48 }, + { 227, 0, 4, 64, 48 }, + { 228, 0, 4, 0, 48 }, + { 229, 0, 47, 0, 0 }, + { 230, 0, 51, 0, 0 }, + { 232, 0, 8, 2, 46 }, + { 233, 0, 8, 0, 46 }, + { 234, 0, 8, 2, 48 }, + { 235, 0, 8, 0, 48 }, + { 236, 0, 12, 2, 46 }, + { 237, 0, 12, 0, 46 }, + { 238, 0, 12, 2, 48 }, + { 239, 0, 12, 0, 48 }, + { 241, 0, 17, 64, 48 }, + { 242, 0, 18, 2, 46 }, + { 243, 0, 18, 0, 46 }, + { 244, 0, 18, 2, 48 }, + { 245, 0, 18, 64, 48 }, + { 246, 0, 18, 0, 48 }, + { 248, 0, 52, 0, 0 }, + { 249, 0, 24, 2, 46 }, + { 250, 0, 24, 0, 46 }, + { 251, 0, 24, 2, 48 }, + { 252, 0, 24, 0, 48 }, + { 253, 0, 28, 0, 46 }, + { 255, 0, 28, 0, 48 }, + { 8364, 64, 34, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x0021 , -1 , -1 , -1 } , + { 0 , (int)'2' , 0x0022 , -1 , 0x0040 , -1 } , + { 0 , (int)'3' , 0x0023 , -1 , 0x00a3 , -1 } , + { 0 , (int)'4' , 0x00a4 , -1 , 0x0024 , -1 } , + { 0 , (int)'5' , 0x0025 , -1 , 0x20ac , -1 } , + { 0 , (int)'6' , 0x0026 , -1 , -1 , -1 } , + { 0 , (int)'7' , 0x002f , -1 , 0x007b , -1 } , + { 0 , (int)'8' , 0x0028 , -1 , 0x005b , -1 } , + { 0 , (int)'9' , 0x0029 , -1 , 0x005d , -1 } , + { 0 , (int)'0' , 0x003d , -1 , 0x007d , -1 } , + { 0 , 0x002b , 0x003f , -1 , -1 , -1 } , + { 0 , 0x00b4 , 0x0060 , -1 , 0x007c , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 1 , 0x00e5 , 0x00c5 , 0x001b , -1 , -1 } , + { 0 , 0x00a8 , 0x005e , 0x001d , 0x007e , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 1 , 0x00e6 , 0x00c6 , -1 , -1 , -1 } , + { 1 , 0x00f8 , 0x00d8 , -1 , -1 , -1 } , + { 0 , 0x00bd , 0x00a7 , 0x001c , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x0027 , 0x002a , -1 , -1 , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , -1 } , + { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x003c , 0x003e , 0x001c , 0x005c , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x00b4, 0x0060, 0x00a8, 0x005e, 0x007e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0061 , 0x00e1 }, + { 0x00b4 , 0x0065 , 0x00e9 }, + { 0x00b4 , 0x0075 , 0x00fa }, + { 0x00b4 , 0x0069 , 0x00ed }, + { 0x00b4 , 0x0079 , 0x00fd }, + { 0x00b4 , 0x006f , 0x00f3 }, + { 0x00b4 , 0x0041 , 0x00c1 }, + { 0x00b4 , 0x0045 , 0x00c9 }, + { 0x00b4 , 0x0055 , 0x00da }, + { 0x00b4 , 0x0049 , 0x00cd }, + { 0x00b4 , 0x0059 , 0x00dd }, + { 0x00b4 , 0x004f , 0x00d3 }, + { 0x00b4 , 0x0020 , 0x00b4 }, + { 0x0060 , 0x0061 , 0x00e0 }, + { 0x0060 , 0x0065 , 0x00e8 }, + { 0x0060 , 0x0075 , 0x00f9 }, + { 0x0060 , 0x0069 , 0x00ec }, + { 0x0060 , 0x006f , 0x00f2 }, + { 0x0060 , 0x0041 , 0x00c0 }, + { 0x0060 , 0x0045 , 0x00c8 }, + { 0x0060 , 0x0055 , 0x00d9 }, + { 0x0060 , 0x0049 , 0x00cc }, + { 0x0060 , 0x004f , 0x00d2 }, + { 0x0060 , 0x0020 , 0x0060 }, + { 0x00a8 , 0x0061 , 0x00e4 }, + { 0x00a8 , 0x0065 , 0x00eb }, + { 0x00a8 , 0x0075 , 0x00fc }, + { 0x00a8 , 0x0069 , 0x00ef }, + { 0x00a8 , 0x0079 , 0x00ff }, + { 0x00a8 , 0x006f , 0x00f6 }, + { 0x00a8 , 0x0041 , 0x00c4 }, + { 0x00a8 , 0x0045 , 0x00cb }, + { 0x00a8 , 0x0055 , 0x00dc }, + { 0x00a8 , 0x0049 , 0x00cf }, + { 0x00a8 , 0x004f , 0x00d6 }, + { 0x00a8 , 0x0020 , 0x00a8 }, + { 0x005e , 0x0061 , 0x00e2 }, + { 0x005e , 0x0065 , 0x00ea }, + { 0x005e , 0x0075 , 0x00fb }, + { 0x005e , 0x0069 , 0x00ee }, + { 0x005e , 0x006f , 0x00f4 }, + { 0x005e , 0x0041 , 0x00c2 }, + { 0x005e , 0x0045 , 0x00ca }, + { 0x005e , 0x0055 , 0x00db }, + { 0x005e , 0x0049 , 0x00ce }, + { 0x005e , 0x004f , 0x00d4 }, + { 0x005e , 0x0020 , 0x005e }, + { 0x007e , 0x006e , 0x00f1 }, + { 0x007e , 0x0061 , 0x00e3 }, + { 0x007e , 0x006f , 0x00f5 }, + { 0x007e , 0x004e , 0x00d1 }, + { 0x007e , 0x0041 , 0x00c3 }, + { 0x007e , 0x004f , 0x00d5 }, + { 0x007e , 0x0020 , 0x007e }, + + }; + + private static DanishLayout instance = new DanishLayout(); + + private DanishLayout() { + } + + public static DanishLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} \ No newline at end of file diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/DvorakLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/DvorakLayout.java new file mode 100644 index 00000000..a5cd6306 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/DvorakLayout.java @@ -0,0 +1,269 @@ +package com.inputstick.api.layout; + +public class DvorakLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "en-DV"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //en-DV + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 45, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 46, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 20, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 36, 0, 0 }, // & + { 39, 0, 20, 0, 0 }, // ' + { 40, 2, 38, 0, 0 }, // ( + { 41, 2, 39, 0, 0 }, // ) + { 42, 2, 37, 0, 0 }, // * + { 43, 2, 48, 0, 0 }, // + + { 44, 0, 26, 0, 0 }, // , + { 45, 0, 52, 0, 0 }, // - + { 46, 0, 8, 0, 0 }, // . + { 47, 0, 47, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 29, 0, 0 }, // : + { 59, 0, 29, 0, 0 }, // ; + { 60, 2, 26, 0, 0 }, // < + { 61, 0, 48, 0, 0 }, // = + { 62, 2, 8, 0, 0 }, // > + { 63, 2, 47, 0, 0 }, // ? + { 64, 2, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 17, 0, 0 }, // B + { 67, 2, 12, 0, 0 }, // C + { 68, 2, 11, 0, 0 }, // D + { 69, 2, 7, 0, 0 }, // E + { 70, 2, 28, 0, 0 }, // F + { 71, 2, 24, 0, 0 }, // G + { 72, 2, 13, 0, 0 }, // H + { 73, 2, 10, 0, 0 }, // I + { 74, 2, 6, 0, 0 }, // J + { 75, 2, 25, 0, 0 }, // K + { 76, 2, 19, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 15, 0, 0 }, // N + { 79, 2, 22, 0, 0 }, // O + { 80, 2, 21, 0, 0 }, // P + { 81, 2, 27, 0, 0 }, // Q + { 82, 2, 18, 0, 0 }, // R + { 83, 2, 51, 0, 0 }, // S + { 84, 2, 14, 0, 0 }, // T + { 85, 2, 9, 0, 0 }, // U + { 86, 2, 55, 0, 0 }, // V + { 87, 2, 54, 0, 0 }, // W + { 88, 2, 5, 0, 0 }, // X + { 89, 2, 23, 0, 0 }, // Y + { 90, 2, 56, 0, 0 }, // Z + { 91, 0, 45, 0, 0 }, // [ + { 92, 0, 49, 0, 0 }, // \ + { 93, 0, 46, 0, 0 }, // ] + { 94, 2, 35, 0, 0 }, // ^ + { 95, 2, 52, 0, 0 }, // _ + { 96, 0, 53, 0, 0 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 17, 0, 0 }, // b + { 99, 0, 12, 0, 0 }, // c + { 100, 0, 11, 0, 0 }, // d + { 101, 0, 7, 0, 0 }, // e + { 102, 0, 28, 0, 0 }, // f + { 103, 0, 24, 0, 0 }, // g + { 104, 0, 13, 0, 0 }, // h + { 105, 0, 10, 0, 0 }, // i + { 106, 0, 6, 0, 0 }, // j + { 107, 0, 25, 0, 0 }, // k + { 108, 0, 19, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 15, 0, 0 }, // n + { 111, 0, 22, 0, 0 }, // o + { 112, 0, 21, 0, 0 }, // p + { 113, 0, 27, 0, 0 }, // q + { 114, 0, 18, 0, 0 }, // r + { 115, 0, 51, 0, 0 }, // s + { 116, 0, 14, 0, 0 }, // t + { 117, 0, 9, 0, 0 }, // u + { 118, 0, 55, 0, 0 }, // v + { 119, 0, 54, 0, 0 }, // w + { 120, 0, 5, 0, 0 }, // x + { 121, 0, 23, 0, 0 }, // y + { 122, 0, 56, 0, 0 }, // z + { 123, 2, 45, 0, 0 }, // { + { 124, 2, 49, 0, 0 }, // | + { 125, 2, 46, 0, 0 }, // } + { 126, 2, 53, 0, 0 }, // ~ + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x021 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x040 , -1 , -1 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x023 , -1 , -1 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x024 , -1 , -1 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x025 , -1 , -1 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x05e , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x026 , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x02a , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x028 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x029 , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x05b , 0x07b , 0x01b , -1 , -1 } , + /* 0d */ { 0 , 0x05d , 0x07d , 0x01d , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 0 , 0x027 , 0x022 , -1 , -1 , -1 } , + /* 11 */ { 0 , 0x02c , 0x03c , -1 , -1 , -1 } , + /* 12 */ { 0 , 0x02e , 0x03e , -1 , -1 , -1 } , + /* 13 */ { 1 , 'p' , 'P' , -1 , -1 , -1 } , + /* 14 */ { 1 , 'y' , 'Y' , -1 , -1 , -1 } , + /* 15 */ { 1 , 'f' , 'F' , -1 , -1 , -1 } , + /* 16 */ { 1 , 'g' , 'G' , -1 , -1 , -1 } , + /* 17 */ { 1 , 'c' , 'C' , -1 , -1 , -1 } , + /* 18 */ { 1 , 'r' , 'R' , -1 , -1 , -1 } , + /* 19 */ { 1 , 'l' , 'L' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x02f , 0x03f , -1 , -1 , -1 } , + /* 1b */ { 0 , 0x03d , 0x02b , -1 , -1 , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , 'a' , 'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , 'o' , 'O' , -1 , -1 , -1 } , + + /* 20 */ { 1 , 'e' , 'E' , -1 , -1 , -1 } , + /* 21 */ { 1 , 'u' , 'U' , -1 , -1 , -1 } , + /* 22 */ { 1 , 'i' , 'I' , -1 , -1 , -1 } , + /* 23 */ { 1 , 'd' , 'D' , -1 , -1 , -1 } , + /* 24 */ { 1 , 'h' , 'H' , -1 , -1 , -1 } , + /* 25 */ { 1 , 't' , 'T' , -1 , -1 , -1 } , + /* 26 */ { 1 , 'n' , 'N' , -1 , -1 , -1 } , + /* 27 */ { 1 , 's' , 'S' , -1 , -1 , -1 } , + /* 28 */ { 0 , 0x02d , 0x05f , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x060 , 0x07e , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x005c , 0x07c , 0x01c , -1 , -1 } , + /* 2c */ { 0 , 0x003b , 0x03a , -1 , -1 , -1 } , + /* 2d */ { 1 , 'q' , 'Q' , -1 , -1 , -1 } , + /* 2e */ { 1 , 'j' , 'J' , -1 , -1 , -1 } , + /* 2f */ { 1 , 'k' , 'K' , -1 , -1 , -1 } , + + /* 30 */ { 1 , 'x' , 'X' , -1 , -1 , -1 } , + /* 31 */ { 1 , 'b' , 'B' , -1 , -1 , -1 } , + /* 32 */ { 1 , 'm' , 'M' , -1 , -1 , -1 } , + /* 33 */ { 1 , 'w' , 'W' , -1 , -1 , -1 } , + /* 34 */ { 1 , 'v' , 'V' , -1 , -1 , -1 } , + /* 35 */ { 1 , 'z' , 'Z' , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x020 , 0x020 , 0x020 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x02e , 0x02e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x05c , 0x07c , 0x01c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static DvorakLayout instance = new DvorakLayout(); + + private DvorakLayout() { + } + + public static DvorakLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} \ No newline at end of file diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/FinnishLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/FinnishLayout.java new file mode 100644 index 00000000..9135ed48 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/FinnishLayout.java @@ -0,0 +1,388 @@ +package com.inputstick.api.layout; + +public class FinnishLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "fi-FI"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 24, 64, 33, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 53, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 31, 0, 0 }, + { 35, 2, 32, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 35, 0, 0 }, + { 39, 0, 49, 0, 0 }, + { 40, 2, 37, 0, 0 }, + { 41, 2, 38, 0, 0 }, + { 42, 2, 49, 0, 0 }, + { 43, 0, 45, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 56, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 2, 36, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 55, 0, 0 }, + { 59, 2, 54, 0, 0 }, + { 60, 0, 100, 0, 0 }, + { 61, 2, 39, 0, 0 }, + { 62, 2, 100, 0, 0 }, + { 63, 2, 45, 0, 0 }, + { 64, 64, 31, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 29, 0, 0 }, + { 91, 64, 37, 0, 0 }, + { 92, 64, 45, 0, 0 }, + { 93, 64, 38, 0, 0 }, + { 94, 0, 44, 2, 48 }, + { 95, 2, 56, 0, 0 }, + { 96, 0, 44, 2, 46 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 28, 0, 0 }, + { 122, 0, 29, 0, 0 }, + { 123, 64, 36, 0, 0 }, + { 124, 64, 100, 0, 0 }, + { 125, 64, 39, 0, 0 }, + { 126, 0, 44, 64, 48 }, + { 163, 64, 32, 0, 0 }, + { 164, 2, 33, 0, 0 }, + { 167, 0, 53, 0, 0 }, + { 168, 0, 44, 0, 48 }, + { 180, 0, 44, 0, 46 }, + { 181, 64, 16, 0, 0 }, + { 189, 2, 53, 0, 0 }, + { 192, 2, 4, 2, 46 }, + { 193, 2, 4, 0, 46 }, + { 194, 2, 4, 2, 48 }, + { 195, 2, 4, 64, 48 }, + { 196, 2, 52, 0, 0 }, + { 197, 2, 47, 0, 0 }, + { 200, 2, 8, 2, 46 }, + { 201, 2, 8, 0, 46 }, + { 202, 2, 8, 2, 48 }, + { 203, 2, 8, 0, 48 }, + { 204, 2, 12, 2, 46 }, + { 205, 2, 12, 0, 46 }, + { 206, 2, 12, 2, 48 }, + { 207, 2, 12, 0, 48 }, + { 209, 2, 17, 64, 48 }, + { 210, 2, 18, 2, 46 }, + { 211, 2, 18, 0, 46 }, + { 212, 2, 18, 2, 48 }, + { 213, 2, 18, 64, 48 }, + { 214, 2, 51, 0, 0 }, + { 217, 2, 24, 2, 46 }, + { 218, 2, 24, 0, 46 }, + { 219, 2, 24, 2, 48 }, + { 220, 2, 24, 0, 48 }, + { 221, 2, 28, 0, 46 }, + { 224, 0, 4, 2, 46 }, + { 225, 0, 4, 0, 46 }, + { 226, 0, 4, 2, 48 }, + { 227, 0, 4, 64, 48 }, + { 228, 0, 52, 0, 0 }, + { 229, 0, 47, 0, 0 }, + { 232, 0, 8, 2, 46 }, + { 233, 0, 8, 0, 46 }, + { 234, 0, 8, 2, 48 }, + { 235, 0, 8, 0, 48 }, + { 236, 0, 12, 2, 46 }, + { 237, 0, 12, 0, 46 }, + { 238, 0, 12, 2, 48 }, + { 239, 0, 12, 0, 48 }, + { 241, 0, 17, 64, 48 }, + { 242, 0, 18, 2, 46 }, + { 243, 0, 18, 0, 46 }, + { 244, 0, 18, 2, 48 }, + { 245, 0, 18, 64, 48 }, + { 246, 0, 51, 0, 0 }, + { 249, 0, 24, 2, 46 }, + { 250, 0, 24, 0, 46 }, + { 251, 0, 24, 2, 48 }, + { 252, 0, 24, 0, 48 }, + { 253, 0, 28, 0, 46 }, + { 255, 0, 28, 0, 48 }, + { 8364, 64, 34, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x0021 , -1 , -1 , -1 } , + { 0 , (int)'2' , 0x0022 , -1 , 0x0040 , -1 } , + { 0 , (int)'3' , 0x0023 , -1 , 0x00a3 , -1 } , + { 0 , (int)'4' , 0x00a4 , -1 , 24 , -1 } , + { 0 , (int)'5' , 0x0025 , -1 , 0x20ac , -1 } , + { 0 , (int)'6' , 0x0026 , -1 , -1 , -1 } , + { 0 , (int)'7' , 0x002f , -1 , 0x007b , -1 } , + { 0 , (int)'8' , 0x0028 , -1 , 0x005b , -1 } , + { 0 , (int)'9' , 0x0029 , -1 , 0x005d , -1 } , + { 0 , (int)'0' , 0x003d , -1 , 0x007d , -1 } , + { 0 , 0x002b , 0x003f , -1 , 0x005c , -1 } , + { 0 , 0x00b4 , 0x0060 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x020ac , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 1 , 0x00e5 , 0x00c5 , 0x001b , -1 , -1 } , + { 0 , 0x00a8 , 0x005e , 0x001d , 0x007e , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 1 , 0x00f6 , 0x00d6 , -1 , -1 , -1 } , + { 1 , 0x00e4 , 0x00c4 , -1 , -1 , -1 } , + { 0 , 0x00a7 , 0x00bd , 0x001c , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x0027 , 0x002a , -1 , -1 , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , -1 } , + { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x003c , 0x003e , 0x001c , 0x007c , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x00b4, 0x0060, 0x00a8, 0x005e, 0x007e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + + + }; + + private static FinnishLayout instance = new FinnishLayout(); + + private FinnishLayout() { + } + + public static FinnishLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/FrenchLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/FrenchLayout.java new file mode 100644 index 00000000..a869b1c2 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/FrenchLayout.java @@ -0,0 +1,362 @@ +package com.inputstick.api.layout; + +public class FrenchLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "fr-FR"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 0, 56, 0, 0 }, + { 34, 0, 32, 0, 0 }, + { 35, 64, 32, 0, 0 }, + { 36, 0, 48, 0, 0 }, + { 37, 2, 52, 0, 0 }, + { 38, 0, 30, 0, 0 }, + { 39, 0, 33, 0, 0 }, + { 40, 0, 34, 0, 0 }, + { 41, 0, 45, 0, 0 }, + { 42, 0, 49, 0, 0 }, + { 43, 2, 46, 0, 0 }, + { 44, 0, 16, 0, 0 }, + { 45, 0, 35, 0, 0 }, + { 46, 2, 54, 0, 0 }, + { 47, 2, 55, 0, 0 }, + { 48, 2, 39, 0, 0 }, + { 49, 2, 30, 0, 0 }, + { 50, 2, 31, 0, 0 }, + { 51, 2, 32, 0, 0 }, + { 52, 2, 33, 0, 0 }, + { 53, 2, 34, 0, 0 }, + { 54, 2, 35, 0, 0 }, + { 55, 2, 36, 0, 0 }, + { 56, 2, 37, 0, 0 }, + { 57, 2, 38, 0, 0 }, + { 58, 0, 55, 0, 0 }, + { 59, 0, 54, 0, 0 }, + { 60, 0, 100, 0, 0 }, + { 61, 0, 46, 0, 0 }, + { 62, 2, 100, 0, 0 }, + { 63, 2, 16, 0, 0 }, + { 64, 64, 39, 0, 0 }, + { 65, 2, 20, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 51, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 4, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 29, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 26, 0, 0 }, + { 91, 64, 34, 0, 0 }, + { 92, 64, 37, 0, 0 }, + { 93, 64, 45, 0, 0 }, + { 94, 0, 44, 64, 38 }, + { 95, 0, 37, 0, 0 }, + { 96, 0, 44, 64, 36 }, + { 97, 0, 20, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 51, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 4, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 29, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 28, 0, 0 }, + { 122, 0, 26, 0, 0 }, + { 123, 64, 33, 0, 0 }, + { 124, 64, 35, 0, 0 }, + { 125, 64, 46, 0, 0 }, + { 126, 0, 44, 64, 31 }, + { 163, 2, 48, 0, 0 }, + { 164, 64, 48, 0, 0 }, + { 167, 2, 56, 0, 0 }, + { 168, 0, 44, 2, 47 }, + { 176, 2, 45, 0, 0 }, + { 178, 0, 53, 0, 0 }, + { 181, 2, 49, 0, 0 }, + { 192, 2, 20, 64, 36 }, + { 194, 2, 20, 64, 38 }, + { 195, 2, 20, 64, 31 }, + { 196, 2, 20, 2, 47 }, + { 200, 2, 8, 64, 36 }, + { 202, 2, 8, 64, 38 }, + { 203, 2, 8, 2, 47 }, + { 204, 2, 12, 64, 36 }, + { 206, 2, 12, 64, 38 }, + { 207, 2, 12, 2, 47 }, + { 209, 2, 17, 64, 31 }, + { 210, 2, 18, 64, 36 }, + { 212, 2, 18, 64, 38 }, + { 213, 2, 18, 64, 31 }, + { 214, 2, 18, 2, 47 }, + { 217, 2, 24, 64, 36 }, + { 219, 2, 24, 64, 38 }, + { 220, 2, 24, 2, 47 }, + { 224, 0, 39, 0, 0 }, + { 226, 0, 20, 64, 38 }, + { 227, 0, 20, 64, 31 }, + { 228, 0, 20, 2, 47 }, + { 231, 0, 38, 0, 0 }, + { 232, 0, 36, 0, 0 }, + { 233, 0, 31, 0, 0 }, + { 234, 0, 8, 64, 38 }, + { 235, 0, 8, 2, 47 }, + { 236, 0, 12, 64, 36 }, + { 238, 0, 12, 64, 38 }, + { 239, 0, 12, 2, 47 }, + { 241, 0, 17, 64, 31 }, + { 242, 0, 18, 64, 36 }, + { 244, 0, 18, 64, 38 }, + { 245, 0, 18, 64, 31 }, + { 246, 0, 18, 2, 47 }, + { 249, 0, 52, 0, 0 }, + { 251, 0, 24, 64, 38 }, + { 252, 0, 24, 2, 47 }, + { 255, 0, 28, 2, 47 }, + { 8364, 64, 8, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , 0x26 , (int)'1' , -1 , -1 , -1 } , + { 1 , 0x00e9 , (int)'2' , -1 , 0x007e , -1 } , + { 1 , 0x22 , (int)'3' , -1 , 0x23 , -1 } , + { 1 , 0x27 , (int)'4' , -1 , 0x007b , -1 } , + { 1 , 0x28 , (int)'5' , -1 , 0x005b , -1 } , + { 1 , 0x002d , (int)'6' , -1 , 0x007c , -1 } , + { 1 , 0x00e8 , (int)'7' , -1 , 0x0060 , -1 } , + { 1 , 0x005f , (int)'8' , -1 , 0x005c , -1 } , + { 1 , 0x00e7 , (int)'9' , -1 , 0x005e , -1 } , + { 1 , 0x00e0 , (int)'0' , -1 , 0x40 , -1 } , + { 1 , 0x29 , 0x00b0 , -1 , 0x005d , -1 } , + { 1 , 0x003d , 0x002b , -1 , 0x007d , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 1 , 0x005e , 0x00a8 , 0x001b , -1 , -1 } , + { 1 , 0x24 , 0x00a3 , 0x001d , 0x00a4 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + { 1 , 0x00f9 , 0x25 , -1 , -1 , -1 } , + { 0 , 0x00b2 , -1 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , 0x002a , 0x00b5 , 0x001c , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , 0x002c , 0x003f , -1 , -1 , -1 } , + { 1 , 0x003b , 0x002e , -1 , -1 , -1 } , + { 1 , 0x003a , 0x002f , -1 , -1 , -1 } , + { 1 , 0x21 , 0x00a7 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x003c , 0x003e , 0x001c , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x007e, 0x0060, 0x005e, 0x00a8, 0x007e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x0020 , 0x007e } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + }; + + private static FrenchLayout instance = new FrenchLayout(); + + private FrenchLayout() { + } + + public static FrenchLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/GermanLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/GermanLayout.java new file mode 100644 index 00000000..f405d82d --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/GermanLayout.java @@ -0,0 +1,355 @@ +package com.inputstick.api.layout; + +public class GermanLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "de-DE"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 31, 0, 0 }, + { 35, 0, 49, 0, 0 }, + { 36, 2, 33, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 35, 0, 0 }, + { 39, 2, 49, 0, 0 }, + { 40, 2, 37, 0, 0 }, + { 41, 2, 38, 0, 0 }, + { 42, 2, 48, 0, 0 }, + { 43, 0, 48, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 56, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 2, 36, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 55, 0, 0 }, + { 59, 2, 54, 0, 0 }, + { 60, 0, 100, 0, 0 }, + { 61, 2, 39, 0, 0 }, + { 62, 2, 100, 0, 0 }, + { 63, 2, 45, 0, 0 }, + { 64, 64, 20, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 29, 0, 0 }, + { 90, 2, 28, 0, 0 }, + { 91, 64, 37, 0, 0 }, + { 92, 64, 45, 0, 0 }, + { 93, 64, 38, 0, 0 }, + { 94, 0, 44, 0, 53 }, + { 95, 2, 56, 0, 0 }, + { 96, 0, 44, 2, 46 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 29, 0, 0 }, + { 122, 0, 28, 0, 0 }, + { 123, 64, 36, 0, 0 }, + { 124, 64, 100, 0, 0 }, + { 125, 64, 39, 0, 0 }, + { 126, 64, 48, 0, 0 }, + { 167, 2, 32, 0, 0 }, + { 176, 2, 53, 0, 0 }, + { 178, 64, 31, 0, 0 }, + { 179, 64, 32, 0, 0 }, + { 180, 0, 44, 0, 46 }, + { 181, 64, 16, 0, 0 }, + { 192, 2, 4, 2, 46 }, + { 193, 2, 4, 0, 46 }, + { 194, 2, 4, 0, 53 }, + { 196, 2, 52, 0, 0 }, + { 200, 2, 8, 2, 46 }, + { 201, 2, 8, 0, 46 }, + { 202, 2, 8, 0, 53 }, + { 204, 2, 12, 2, 46 }, + { 205, 2, 12, 0, 46 }, + { 206, 2, 12, 0, 53 }, + { 210, 2, 18, 2, 46 }, + { 211, 2, 18, 0, 46 }, + { 212, 2, 18, 0, 53 }, + { 214, 2, 51, 0, 0 }, + { 217, 2, 24, 2, 46 }, + { 218, 2, 24, 0, 46 }, + { 219, 2, 24, 0, 53 }, + { 220, 2, 47, 0, 0 }, + { 221, 2, 29, 0, 46 }, + { 223, 0, 45, 0, 0 }, + { 224, 0, 4, 2, 46 }, + { 225, 0, 4, 0, 46 }, + { 226, 0, 4, 0, 53 }, + { 228, 0, 52, 0, 0 }, + { 232, 0, 8, 2, 46 }, + { 233, 0, 8, 0, 46 }, + { 234, 0, 8, 0, 53 }, + { 236, 0, 12, 2, 46 }, + { 237, 0, 12, 0, 46 }, + { 238, 0, 12, 0, 53 }, + { 242, 0, 18, 2, 46 }, + { 243, 0, 18, 0, 46 }, + { 244, 0, 18, 0, 53 }, + { 246, 0, 51, 0, 0 }, + { 249, 0, 24, 2, 46 }, + { 250, 0, 24, 0, 46 }, + { 251, 0, 24, 0, 53 }, + { 252, 0, 47, 0, 0 }, + { 253, 0, 29, 0, 46 }, + { 8364, 64, 8, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + { 0 , (int)'2' , 0x22 , -1 , 0x00b2 , 0x00b2 } , + { 0 , (int)'3' , 0x00a7 , -1 , 0x00b3 , 0x00b3 } , + { 0 , (int)'4' , 0x24 , -1 , -1 , -1 } , + { 0 , (int)'5' , 0x25 , -1 , -1 , -1 } , + { 0 , (int)'6' , 0x26 , -1 , -1 , -1 } , + { 0 , (int)'7' , 0x002f , -1 , 0x007b , 0x007b } , + { 0 , (int)'8' , 0x28 , -1 , 0x005b , 0x005b } , + { 0 , (int)'9' , 0x29 , -1 , 0x005d , 0x005d } , + { 0 , (int)'0' , 0x003d , -1 , 0x007d , 0x007d } , + { 0 , 0x00df , 0x003f , -1 , 0x005c , 0x005c } , + { 0 , 0x00b4 , 0x0060 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + + { 1 , (int)'q' , (int)'Q' , -1 , 0x40 , 0x40 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 1 , 0x00fc , 0x00dc , 0x001b , -1 , -1 } , + { 0 , 0x002b , 0x002a , 0x001d , 0x007e , 0x007e } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 1 , 0x00f6 , 0x00d6 , -1 , -1 , -1 } , + { 1 , 0x00e4 , 0x00c4 , -1 , -1 , -1 } , + { 0 , 0x005e , 0x00b0 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x23 , 0x27 , 0x001c , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , 0x00b5 } , + { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x003c , 0x003e , -1 , 0x007c , 0x007c } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x0060, 0x00b4, 0x005e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + + }; + + private static GermanLayout instance = new GermanLayout(); + + private GermanLayout() { + } + + public static GermanLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/GermanMacLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/GermanMacLayout.java new file mode 100644 index 00000000..b902b75a --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/GermanMacLayout.java @@ -0,0 +1,353 @@ +package com.inputstick.api.layout; + +public class GermanMacLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "de-DE-mac"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 31, 0, 0 }, + { 35, 0, 49, 0, 0 }, + { 36, 2, 33, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 35, 0, 0 }, + { 39, 2, 49, 0, 0 }, + { 40, 2, 37, 0, 0 }, + { 41, 2, 38, 0, 0 }, + { 42, 2, 48, 0, 0 }, + { 43, 0, 48, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 56, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 2, 36, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 55, 0, 0 }, + { 59, 2, 54, 0, 0 }, + { 60, 0, 100, 0, 0 }, + { 61, 2, 39, 0, 0 }, + { 62, 2, 100, 0, 0 }, + { 63, 2, 45, 0, 0 }, + { 64, 64, 15, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 29, 0, 0 }, + { 90, 2, 28, 0, 0 }, + { 91, 64, 34, 0, 0 }, + { 93, 64, 35, 0, 0 }, + { 94, 0, 44, 0, 53 }, + { 95, 2, 56, 0, 0 }, + { 96, 0, 44, 2, 46 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 29, 0, 0 }, + { 122, 0, 28, 0, 0 }, + { 123, 64, 37, 0, 0 }, + { 124, 64, 36, 0, 0 }, + { 125, 64, 38, 0, 0 }, + { 126, 64, 17, 0, 0 }, + { 167, 2, 32, 0, 0 }, + { 176, 2, 53, 0, 0 }, + { 180, 0, 44, 0, 46 }, + { 181, 64, 16, 0, 0 }, + { 192, 2, 4, 2, 46 }, + { 193, 2, 4, 0, 46 }, + { 194, 2, 4, 0, 53 }, + { 196, 2, 52, 0, 0 }, + { 200, 2, 8, 2, 46 }, + { 201, 2, 8, 0, 46 }, + { 202, 2, 8, 0, 53 }, + { 204, 2, 12, 2, 46 }, + { 205, 2, 12, 0, 46 }, + { 206, 2, 12, 0, 53 }, + { 210, 2, 18, 2, 46 }, + { 211, 2, 18, 0, 46 }, + { 212, 2, 18, 0, 53 }, + { 214, 2, 51, 0, 0 }, + { 217, 2, 24, 2, 46 }, + { 218, 2, 24, 0, 46 }, + { 219, 2, 24, 0, 53 }, + { 220, 2, 47, 0, 0 }, + { 221, 2, 29, 0, 46 }, + { 223, 0, 45, 0, 0 }, + { 224, 0, 4, 2, 46 }, + { 225, 0, 4, 0, 46 }, + { 226, 0, 4, 0, 53 }, + { 228, 0, 52, 0, 0 }, + { 232, 0, 8, 2, 46 }, + { 233, 0, 8, 0, 46 }, + { 234, 0, 8, 0, 53 }, + { 236, 0, 12, 2, 46 }, + { 237, 0, 12, 0, 46 }, + { 238, 0, 12, 0, 53 }, + { 242, 0, 18, 2, 46 }, + { 243, 0, 18, 0, 46 }, + { 244, 0, 18, 0, 53 }, + { 246, 0, 51, 0, 0 }, + { 249, 0, 24, 2, 46 }, + { 250, 0, 24, 0, 46 }, + { 251, 0, 24, 0, 53 }, + { 252, 0, 47, 0, 0 }, + { 253, 0, 29, 0, 46 }, + { 8364, 64, 8, 0, 0 }, + }; + + public static final int LUT[][] = { + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + { 0 , (int)'2' , 0x22 , -1 , -1 , -1 } , + { 0 , (int)'3' , 0x00a7 , -1 , -1 , -1 } , + { 0 , (int)'4' , 0x24 , -1 , -1 , -1 } , + { 0 , (int)'5' , 0x25 , -1 , 0x005b , 0x005b } , + { 0 , (int)'6' , 0x26 , -1 , 0x005d , 0x005d } , + { 0 , (int)'7' , 0x002f , -1 , 0x007c , 0x007c } , + { 0 , (int)'8' , 0x28 , -1 , 0x007b , 0x007b } , + { 0 , (int)'9' , 0x29 , -1 , 0x007d , 0x007d } , + { 0 , (int)'0' , 0x003d , -1 , -1 , -1 } , + { 0 , 0x00df , 0x003f , -1 , -1 , -1 } , + { 0 , 0x00b4 , 0x0060 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 1 , 0x00fc , 0x00dc , 0x001b , -1 , -1 } , + { 0 , 0x002b , 0x002a , 0x001d , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , 0x0040 , -1 } , + { 1 , 0x00f6 , 0x00d6 , -1 , -1 , -1 } , + { 1 , 0x00e4 , 0x00c4 , -1 , -1 , -1 } , + { 0 , 0x005e , 0x00b0 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x23 , 0x27 , 0x001c , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , 0x007e , 0x007e } , + { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , 0x00b5 } , + { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x003c , 0x003e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x0060, 0x00b4, 0x005e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + + }; + + private static GermanMacLayout instance = new GermanMacLayout(); + + private GermanMacLayout() { + } + + public static GermanMacLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/HebrewLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/HebrewLayout.java new file mode 100644 index 00000000..350b290c --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/HebrewLayout.java @@ -0,0 +1,275 @@ +package com.inputstick.api.layout; + +public class HebrewLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "he-IL"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 52, 0, 0 }, + { 35, 2, 32, 0, 0 }, + { 36, 2, 33, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 36, 0, 0 }, + { 39, 0, 26, 0, 0 }, + { 40, 2, 39, 0, 0 }, + { 41, 2, 38, 0, 0 }, + { 42, 2, 37, 0, 0 }, + { 43, 2, 46, 0, 0 }, + { 44, 0, 52, 0, 0 }, + { 45, 0, 45, 0, 0 }, + { 46, 0, 56, 0, 0 }, + { 47, 0, 20, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 51, 0, 0 }, + { 59, 0, 53, 0, 0 }, + { 60, 2, 55, 0, 0 }, + { 61, 0, 46, 0, 0 }, + { 62, 2, 54, 0, 0 }, + { 63, 2, 56, 0, 0 }, + { 64, 2, 31, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 29, 0, 0 }, + { 91, 0, 48, 0, 0 }, + { 92, 0, 49, 0, 0 }, + { 93, 0, 47, 0, 0 }, + { 94, 2, 35, 0, 0 }, + { 95, 2, 45, 0, 0 }, + { 123, 2, 48, 0, 0 }, + { 124, 2, 49, 0, 0 }, + { 125, 2, 47, 0, 0 }, + { 126, 2, 53, 0, 0 }, + { 1471, 66, 45, 0, 0 }, + { 1488, 0, 23, 0, 0 }, + { 1489, 0, 6, 0, 0 }, + { 1490, 0, 7, 0, 0 }, + { 1491, 0, 22, 0, 0 }, + { 1492, 0, 25, 0, 0 }, + { 1493, 0, 24, 0, 0 }, + { 1494, 0, 29, 0, 0 }, + { 1495, 0, 13, 0, 0 }, + { 1496, 0, 28, 0, 0 }, + { 1497, 0, 11, 0, 0 }, + { 1498, 0, 15, 0, 0 }, + { 1499, 0, 9, 0, 0 }, + { 1500, 0, 14, 0, 0 }, + { 1501, 0, 18, 0, 0 }, + { 1502, 0, 17, 0, 0 }, + { 1503, 0, 12, 0, 0 }, + { 1504, 0, 5, 0, 0 }, + { 1505, 0, 27, 0, 0 }, + { 1506, 0, 10, 0, 0 }, + { 1507, 0, 51, 0, 0 }, + { 1508, 0, 19, 0, 0 }, + { 1509, 0, 55, 0, 0 }, + { 1510, 0, 16, 0, 0 }, + { 1511, 0, 8, 0, 0 }, + { 1512, 0, 21, 0, 0 }, + { 1513, 0, 4, 0, 0 }, + { 1514, 0, 54, 0, 0 }, + { 1520, 66, 24, 0, 0 }, + { 1521, 66, 13, 0, 0 }, + { 1522, 66, 11, 0, 0 }, + { 8206, 64, 32, 0, 0 }, + { 8207, 64, 33, 0, 0 }, + { 8362, 66, 33, 0, 0 }, + { 8364, 66, 8, 0, 0 }, + }; + + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x0021 , -1 , -1 , -1 } , + { 0 , (int)'2' , 0x0040 , -1 , -1 , -1 } , + { 0 , (int)'3' , 0x0023 , -1 , 0x200e , -1 } , + { 0 , (int)'4' , 0x0024 , -1 , 0x200f , 0x20aa } , + { 0 , (int)'5' , 0x0025 , -1 , -1 , -1 } , + { 0 , (int)'6' , 0x005e , -1 , -1 , -1 } , + { 0 , (int)'7' , 0x0026 , -1 , -1 , -1 } , + { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + { 0 , (int)'9' , 0x0029 , -1 , -1 , -1 } , + { 0 , (int)'0' , 0x0028 , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , 0x05bf } , + { 0 , 0x003d , 0x002b , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , 0x002f , (int)'Q' , -1 , -1 , -1 } , + { 1 , 0x0027 , (int)'W' , -1 , -1 , -1 } , + { 1 , 0x05e7 , (int)'E' , -1 , -1 , 0x20ac } , + { 1 , 0x05e8 , (int)'R' , -1 , -1 , -1 } , + { 1 , 0x05d0 , (int)'T' , -1 , -1 , -1 } , + { 1 , 0x05d8 , (int)'Y' , -1 , -1 , -1 } , + { 1 , 0x05d5 , (int)'U' , -1 , -1 , 0x05f0 } , + { 1 , 0x05df , (int)'I' , -1 , -1 , -1 } , + { 1 , 0x05dd , (int)'O' , -1 , -1 , -1 } , + { 1 , 0x05e4 , (int)'P' , -1 , -1 , -1 } , + { 0 , 0x005d , 0x007d , 0x200e , -1 , -1 } , + { 0 , 0x005b , 0x007b , 0x200f , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , 0x05e9 , (int)'A' , -1 , -1 , -1 } , + { 1 , 0x05d3 , (int)'S' , -1 , -1 , -1 } , + + { 1 , 0x05d2 , (int)'D' , -1 , -1 , -1 } , + { 1 , 0x05db , (int)'F' , -1 , -1 , -1 } , + { 1 , 0x05e2 , (int)'G' , -1 , -1 , -1 } , + { 1 , 0x05d9 , (int)'H' , -1 , -1 , 0x05f2 } , + { 1 , 0x05d7 , (int)'J' , -1 , -1 , 0x05f1 } , + { 1 , 0x05dc , (int)'K' , -1 , -1 , -1 } , + { 1 , 0x05da , (int)'L' , -1 , -1 , -1 } , + { 0 , 0x05e3 , 0x003a , -1 , -1 , -1 } , + { 0 , 0x002c , 0x0022 , -1 , -1 , -1 } , + { 0 , 0x003b , 0x007e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + { 1 , 0x05d6 , (int)'Z' , -1 , -1 , -1 } , + { 1 , 0x05e1 , (int)'X' , -1 , -1 , -1 } , + { 1 , 0x05d1 , (int)'C' , -1 , -1 , -1 } , + { 1 , 0x05d4 , (int)'V' , -1 , -1 , -1 } , + + { 1 , 0x05e0 , (int)'B' , -1 , -1 , -1 } , + { 1 , 0x05de , (int)'N' , -1 , -1 , -1 } , + { 1 , 0x05e6 , (int)'M' , -1 , -1 , -1 } , + { 0 , 0x05ea , 0x003e , -1 , -1 , -1 } , + { 0 , 0x05e5 , 0x003c , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static HebrewLayout instance = new HebrewLayout(); + + private HebrewLayout() { + } + + public static HebrewLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/ItalianLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/ItalianLayout.java new file mode 100644 index 00000000..4ebeb55b --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/ItalianLayout.java @@ -0,0 +1,279 @@ +package com.inputstick.api.layout; + +public class ItalianLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "it-IT"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 31, 0, 0 }, + { 35, 64, 52, 0, 0 }, + { 36, 2, 33, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 35, 0, 0 }, + { 39, 0, 45, 0, 0 }, + { 40, 2, 37, 0, 0 }, + { 41, 2, 38, 0, 0 }, + { 42, 2, 48, 0, 0 }, + { 43, 0, 48, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 56, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 2, 36, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 55, 0, 0 }, + { 59, 2, 54, 0, 0 }, + { 60, 0, 100, 0, 0 }, + { 61, 2, 39, 0, 0 }, + { 62, 2, 100, 0, 0 }, + { 63, 2, 45, 0, 0 }, + { 64, 64, 51, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 29, 0, 0 }, + { 91, 64, 47, 0, 0 }, + { 92, 0, 53, 0, 0 }, + { 93, 64, 48, 0, 0 }, + { 94, 2, 46, 0, 0 }, + { 95, 2, 56, 0, 0 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 28, 0, 0 }, + { 122, 0, 29, 0, 0 }, + { 123, 66, 47, 0, 0 }, + { 124, 2, 53, 0, 0 }, + { 125, 66, 48, 0, 0 }, + { 163, 2, 32, 0, 0 }, + { 167, 2, 49, 0, 0 }, + { 176, 2, 52, 0, 0 }, + { 224, 0, 52, 0, 0 }, + { 231, 2, 51, 0, 0 }, + { 232, 0, 47, 0, 0 }, + { 233, 2, 47, 0, 0 }, + { 236, 0, 46, 0, 0 }, + { 242, 0, 51, 0, 0 }, + { 249, 0, 49, 0, 0 }, + { 8364, 64, 34, 0, 0 }, + }; + + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x0021 , -1 , -1 , -1 } , + { 0 , (int)'2' , 0x0022 , -1 , -1 , -1 } , + { 0 , (int)'3' , 0x00a3 , -1 , -1 , -1 } , + { 0 , (int)'4' , 0x0024 , -1 , -1 , -1 } , + { 0 , (int)'5' , 0x0025 , -1 , 0x20ac , -1 } , + { 0 , (int)'6' , 0x0026 , -1 , -1 , -1 } , + { 0 , (int)'7' , 0x002f , -1 , -1 , -1 } , + { 0 , (int)'8' , 0x0028 , -1 , -1 , -1 } , + { 0 , (int)'9' , 0x0029 , -1 , -1 , -1 } , + { 0 , (int)'0' , 0x003d , -1 , -1 , -1 } , + { 0 , 0x0027 , 0x003f , -1 , -1 , -1 } , + { 0 , 0x00ec , 0x005e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 0 , 0x00e8 , 0x00e9 , 0x001b , 0x005b , 0x007b } , + { 0 , 0x002b , 0x002a , 0x001d , 0x005d , 0x007d } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 0 , 0x00f2 , 0x00e7 , -1 , 0x0040 , -1 } , + { 0 , 0x00e0 , 0x00b0 , -1 , 0x0023 , -1 } , + { 0 , 0x005c , 0x007c , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x00f9 , 0x00a7 , 0x001c , -1 , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x003c , 0x003e , 0x001c , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static ItalianLayout instance = new ItalianLayout(); + + private ItalianLayout() { + } + + public static ItalianLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/KeyboardLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/KeyboardLayout.java new file mode 100644 index 00000000..e418cf9e --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/KeyboardLayout.java @@ -0,0 +1,432 @@ +package com.inputstick.api.layout; + +import com.inputstick.api.ConnectionManager; +import com.inputstick.api.basic.InputStickHID; +import com.inputstick.api.basic.InputStickKeyboard; +import com.inputstick.api.hid.HIDKeycodes; +import com.inputstick.api.hid.HIDTransaction; +import com.inputstick.api.hid.KeyboardReport; + +public abstract class KeyboardLayout { + + public static final int MAX_SCANCODE = 0x60; + + public static final byte[] scanCodeToHID = { + /* 0x00 */ 0, + /* 0x01 */ HIDKeycodes.KEY_ESCAPE, + /* 0x02 */ HIDKeycodes.KEY_1, + /* 0x03 */ HIDKeycodes.KEY_2, + /* 0x04 */ HIDKeycodes.KEY_3, + /* 0x05 */ HIDKeycodes.KEY_4, + /* 0x06 */ HIDKeycodes.KEY_5, + /* 0x07 */ HIDKeycodes.KEY_6, + /* 0x08 */ HIDKeycodes.KEY_7, + /* 0x09 */ HIDKeycodes.KEY_8, + /* 0x0a */ HIDKeycodes.KEY_9, + /* 0x0b */ HIDKeycodes.KEY_0, + /* 0x0c */ HIDKeycodes.KEY_MINUS, + /* 0x0d */ HIDKeycodes.KEY_EQUALS, + /* 0x0e */ HIDKeycodes.KEY_BACKSPACE, + /* 0x0f */ HIDKeycodes.KEY_TAB, + + + /* 0x10 */ HIDKeycodes.KEY_Q, + /* 0x11 */ HIDKeycodes.KEY_W, + /* 0x12 */ HIDKeycodes.KEY_E, + /* 0x13 */ HIDKeycodes.KEY_R, + /* 0x14 */ HIDKeycodes.KEY_T, + /* 0x15 */ HIDKeycodes.KEY_Y, + /* 0x16 */ HIDKeycodes.KEY_U, + /* 0x17 */ HIDKeycodes.KEY_I, + /* 0x18 */ HIDKeycodes.KEY_O, + /* 0x19 */ HIDKeycodes.KEY_P, + /* 0x1a */ HIDKeycodes.KEY_LEFT_BRACKET, + /* 0x1b */ HIDKeycodes.KEY_RIGHT_BRACKET, + /* 0x1c */ HIDKeycodes.KEY_ENTER, + /* 0x1d */ 0, //RL CTRL + /* 0x1e */ HIDKeycodes.KEY_A, + /* 0x1f */ HIDKeycodes.KEY_S, + + /* 0x20 */ HIDKeycodes.KEY_D, + /* 0x21 */ HIDKeycodes.KEY_F, + /* 0x22 */ HIDKeycodes.KEY_G, + /* 0x23 */ HIDKeycodes.KEY_H, + /* 0x24 */ HIDKeycodes.KEY_J, + /* 0x25 */ HIDKeycodes.KEY_K, + /* 0x26 */ HIDKeycodes.KEY_L, + /* 0x27 */ HIDKeycodes.KEY_SEMICOLON, + /* 0x28 */ HIDKeycodes.KEY_APOSTROPHE, + /* 0x29 */ HIDKeycodes.KEY_GRAVE, + /* 0x2a */ 0, //L SHIFT + /* 0x2b */ HIDKeycodes.KEY_BACKSLASH, + /* 0x2c */ HIDKeycodes.KEY_Z, + /* 0x2d */ HIDKeycodes.KEY_X, + /* 0x2e */ HIDKeycodes.KEY_C, + /* 0x2f */ HIDKeycodes.KEY_V, + + /* 0x30 */ HIDKeycodes.KEY_B, + /* 0x31 */ HIDKeycodes.KEY_N, + /* 0x32 */ HIDKeycodes.KEY_M, + /* 0x33 */ HIDKeycodes.KEY_COMA, + /* 0x34 */ HIDKeycodes.KEY_DOT, + /* 0x35 */ HIDKeycodes.KEY_SLASH, + /* 0x36 */ 0, //R SHIFT + /* 0x37 */ HIDKeycodes.KEY_PRINT_SCREEN, + /* 0x38 */ 0, //RL ALT + /* 0x39 */ HIDKeycodes.KEY_SPACEBAR, + /* 0x3a */ HIDKeycodes.KEY_CAPS_LOCK, + /* 0x3b */ HIDKeycodes.KEY_F1, + /* 0x3c */ HIDKeycodes.KEY_F2, + /* 0x3d */ HIDKeycodes.KEY_F3, + /* 0x3e */ HIDKeycodes.KEY_F4, + /* 0x3f */ HIDKeycodes.KEY_F5, + + /* 0x40 */ HIDKeycodes.KEY_F6, + /* 0x41 */ HIDKeycodes.KEY_F7, + /* 0x42 */ HIDKeycodes.KEY_F8, + /* 0x43 */ HIDKeycodes.KEY_F9, + /* 0x44 */ HIDKeycodes.KEY_F10, + /* 0x45 */ HIDKeycodes.KEY_NUM_LOCK, + /* 0x46 */ HIDKeycodes.KEY_SCROLL_LOCK, + /* 0x47 */ HIDKeycodes.KEY_HOME, + /* 0x48 */ HIDKeycodes.KEY_ARROW_UP, + /* 0x49 */ HIDKeycodes.KEY_PAGE_UP, + /* 0x4a */ 0, //- + /* 0x4b */ HIDKeycodes.KEY_ARROW_LEFT, + /* 0x4c */ 0, //CENTER + /* 0x4d */ HIDKeycodes.KEY_ARROW_RIGHT, + /* 0x4e */ 0, //+ + /* 0x4f */ HIDKeycodes.KEY_END, + + /* 0x50 */ HIDKeycodes.KEY_ARROW_DOWN, + /* 0x51 */ HIDKeycodes.KEY_PAGE_DOWN, + /* 0x52 */ HIDKeycodes.KEY_INSERT, + /* 0x53 */ HIDKeycodes.KEY_DELETE, + /* 0x54 */ 0, + /* 0x55 */ 0, + /* 0x56 */ HIDKeycodes.KEY_BACKSLASH_NON_US, //GERMAN LAYOUT! + /* 0x57 */ HIDKeycodes.KEY_F11, + /* 0x58 */ HIDKeycodes.KEY_F12, + /* 0x59 */ 0, + /* 0x5a */ 0, + /* 0x5b */ 0, + /* 0x5c */ 0, + /* 0x5d */ 0, + /* 0x5e */ 0, + /* 0x5f */ 0, + + }; + + public static final int LAYOUT_CODE = 0; + + public abstract int[][] getLUT(); + public abstract int[][] getFastLUT(); + public abstract int[][] getDeadkeyLUT(); + public abstract int[] getDeadkeys(); + public abstract String getLocaleName(); + + /* + * Type text using InputStick. Assumes that USB host uses matching keyboard layout. + * + * @param text text to type + */ + public abstract void type(String text); + + + /* + * Type text using InputStick. Assumes that USB host uses matching keyboard layout. + * Note: use only if you are certain that specified modifier keys will not cause any side effects during typing. + * + * @param text text to type + * @param modifiers state of keyboard modifier keys (CTRL_LEFT .. GUI_RIGHT, see HIDKeycodes) + */ + public abstract void type(String text, byte modifiers); + + public abstract char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr); + + public void type(int[][] fastLUT, String text, byte modifiers) { + if (InputStickHID.getState() == ConnectionManager.STATE_READY) { + char[] chars = text.toCharArray(); + HIDTransaction t; + for (char c : chars) { + if (c == '\n') { + InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER); + } else if (c == '\t') { + InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_TAB); + } else { + t = getHIDTransaction(fastLUT, c, modifiers); + if (t != null) { + InputStickHID.addKeyboardTransaction(t); + } + } + } + } + } + + /*public void type(int[][] lut, int[][] deadkeyLUT, int[] deadkeys, String text, byte modifiers) { + if (InputStickHID.getState() == ConnectionManager.STATE_READY) { + char[] chars = text.toCharArray(); + HIDTransaction t; + for (char c : chars) { + if (c == '\n') { + InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER); + } else if (c == '\t') { + InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_TAB); + } else { + t = getHIDTransaction(lut, deadkeyLUT, deadkeys, c, modifiers); + if (t != null) { + InputStickHID.addKeyboardTransaction(t); + } + } + } + } + } */ + + public static int hidToScanCode(byte key) { + for (int scanCode = 0; scanCode < MAX_SCANCODE; scanCode++) { + if (scanCodeToHID[scanCode] == key) { + return scanCode; + } + } + return -1; + } + + public static char getChar(int[][] lut, int scanCode, boolean capsLock, boolean shift, boolean altGr) { + if ((scanCode >= MAX_SCANCODE) || (scanCode < 0)) { + return (char)0; + } + + int index = 1; + + if ((capsLock) && (lut[scanCode][0] > 0)) { + //capslock is on and it affects current key + if (lut[scanCode][0] == 1) { + if (shift) { + index = 1; //caps + shift = default + } else { + index = 2; //shift + } + } else { + // >1 + if (shift) { + if (altGr) { + index = 4; //caps + shift + alt = alt + } else { + index = 1; //caps + shift = default + } + } else { + if (altGr) { + index = 5; //caps + alt = shift + alt + } else { + index = 2; //caps = shift + } + } + } + } else { + if (shift) { + index = 2; + } + if (altGr) { + if (shift) { + index = 5; + } else { + index = 4; + } + } + } + + if (lut[scanCode][index] == -1) { + index = 1; + } + return (char)lut[scanCode][index]; + } + + public static int getScanCode(int[][] lut, char c) { + for (int scanCode = 0; scanCode < MAX_SCANCODE; scanCode++) { + if (lut[scanCode][0] == -1) { + continue; + } else { + for (int i = 1; i < 6; i++) { + if (lut[scanCode][i] == (int)c) { + return scanCode; + } + } + } + } + return -1; + } + + public static byte getKey(int scanCode) { + return scanCodeToHID[scanCode]; + } + + public static byte getModifiers(int[][] lut, int scanCode, char c) { + if (lut[scanCode][1] == (int)c) { + return 0; + } + if (lut[scanCode][2] == (int)c) { + return HIDKeycodes.SHIFT_LEFT; + } + if (lut[scanCode][3] == (int)c) { + return HIDKeycodes.CTRL_LEFT; + } + if (lut[scanCode][4] == (int)c) { + return HIDKeycodes.ALT_RIGHT; + } + if (lut[scanCode][5] == (int)c) { + return HIDKeycodes.SHIFT_LEFT | HIDKeycodes.ALT_RIGHT; + } + + return 0; + } + + + public static boolean isDeadkey(int[] deadkeys, char c) { + if (deadkeys != null) { + for (int key : deadkeys) { + if (key == (int)c) { + return true; + } + } + } + return false; + } + + public static int searchLUT(int[][] deadkeyLUT, char c, int returnIndex) { + if (deadkeyLUT != null) { + for (int i = 0; i < deadkeyLUT.length; i++) { + if (deadkeyLUT[i][2] == (int)c) { + return deadkeyLUT[i][returnIndex]; + } + } + } + return -1; + } + + public static int findDeadKey(int[][] deadkeyLUT, char c) { + return searchLUT(deadkeyLUT, c, 0); + } + + public static int findFollowingKey(int[][] deadkeyLUT, char c) { + return searchLUT(deadkeyLUT, c, 1); + } + + public static HIDTransaction getHIDTransaction(int[][] fastLUT, char c, byte additionalModifierKeys) { + byte modifiers, key, deadKey, deadKeyModifiers; + HIDTransaction t = new HIDTransaction(); + + for (int i = 0; i < fastLUT.length; i++) { + if (fastLUT[i][0] == c) { + modifiers = (byte)fastLUT[i][1]; + key = (byte)fastLUT[i][2]; + deadKeyModifiers = (byte)fastLUT[i][3]; + deadKey = (byte)fastLUT[i][4]; + + if (deadKey > 0) { + t.addReport(new KeyboardReport(deadKeyModifiers, (byte)0)); + t.addReport(new KeyboardReport(deadKeyModifiers, deadKey)); + t.addReport(new KeyboardReport()); + } + t.addReport(new KeyboardReport(modifiers, (byte)0)); + t.addReport(new KeyboardReport(modifiers, key)); + t.addReport(new KeyboardReport()); + } + } + return t; + } + + public static HIDTransaction getHIDTransaction(int[][] lut, int[][] deadkeyLUT, int[] deadkeys, char c, byte additionalModifierKeys) { + byte modifiers, key; + int scanCode; + + HIDTransaction t = new HIDTransaction(); + scanCode = getScanCode(lut, c); + if (scanCode > 0) { + key = getKey(scanCode); + modifiers = getModifiers(lut, scanCode, c); + modifiers |= additionalModifierKeys; + + t.addReport(new KeyboardReport(modifiers, (byte)0)); + t.addReport(new KeyboardReport(modifiers, key)); + t.addReport(new KeyboardReport()); + + //add space after deadkey! + if (isDeadkey(deadkeys, c)) { + t.addReport(new KeyboardReport((byte)0, HIDKeycodes.KEY_SPACEBAR)); //this won't work if modifiers are present! + t.addReport(new KeyboardReport()); + } + + } else { + //check if character can be obtained using deadkey: + int deadkey = findDeadKey(deadkeyLUT, c); + if (deadkey > 0) { + //yes it can + int following = findFollowingKey(deadkeyLUT, c); + + scanCode = getScanCode(lut, (char)deadkey); + key = getKey(scanCode); + modifiers = getModifiers(lut, scanCode, (char)deadkey); + t.addReport(new KeyboardReport(modifiers, (byte)0)); + t.addReport(new KeyboardReport(modifiers, key)); + t.addReport(new KeyboardReport()); + + scanCode = getScanCode(lut, (char)following); + key = getKey(scanCode); + modifiers = getModifiers(lut, scanCode, (char)following); + t.addReport(new KeyboardReport(modifiers, (byte)0)); + t.addReport(new KeyboardReport(modifiers, key)); + t.addReport(new KeyboardReport()); + } + + } + return t; + } + + //returns layout sepcified by locale (example: "de-DE"). If specified layout is not available, en=US will be returned. + public static KeyboardLayout getLayout(String locale) { + if (locale != null) { + if (locale.equalsIgnoreCase(UnitedStatesLayout.LOCALE_NAME)) { + return UnitedStatesLayout.getInstance(); + } else if (locale.equalsIgnoreCase(PolishLayout.LOCALE_NAME)) { + return PolishLayout.getInstance(); + } else if (locale.equalsIgnoreCase(RussianLayout.LOCALE_NAME)) { + return RussianLayout.getInstance(); + } else if (locale.equalsIgnoreCase(GermanLayout.LOCALE_NAME)) { + return GermanLayout.getInstance(); + } else if (locale.equalsIgnoreCase(SlovakLayout.LOCALE_NAME)) { + return SlovakLayout.getInstance(); + } else if (locale.equalsIgnoreCase(PortugueseBrazilianLayout.LOCALE_NAME)) { + return PortugueseBrazilianLayout.getInstance(); + } else if (locale.equalsIgnoreCase(DvorakLayout.LOCALE_NAME)) { + return DvorakLayout.getInstance(); + } else if (locale.equalsIgnoreCase(NorwegianLayout.LOCALE_NAME)) { + return NorwegianLayout.getInstance(); + } else if (locale.equalsIgnoreCase(SwedishLayout.LOCALE_NAME)) { + return SwedishLayout.getInstance(); + } else if (locale.equalsIgnoreCase(FrenchLayout.LOCALE_NAME)) { + return FrenchLayout.getInstance(); + } else if (locale.equalsIgnoreCase(SpanishLayout.LOCALE_NAME)) { + return SpanishLayout.getInstance(); + } else if (locale.equalsIgnoreCase(UnitedKingdomLayout.LOCALE_NAME)) { + return UnitedKingdomLayout.getInstance(); + } else if (locale.equalsIgnoreCase(GermanMacLayout.LOCALE_NAME)) { + return GermanMacLayout.getInstance(); // TODO + } else if (locale.equalsIgnoreCase(ItalianLayout.LOCALE_NAME)) { + return ItalianLayout.getInstance(); + } else if (locale.equalsIgnoreCase(FinnishLayout.LOCALE_NAME)) { + return FinnishLayout.getInstance(); + } else if (locale.equalsIgnoreCase(SwissFrenchLayout.LOCALE_NAME)) { + return SwissFrenchLayout.getInstance(); + } else if (locale.equalsIgnoreCase(SwissGermanLayout.LOCALE_NAME)) { + return SwissGermanLayout.getInstance(); + } else if (locale.equalsIgnoreCase(HebrewLayout.LOCALE_NAME)) { + return HebrewLayout.getInstance(); + } else if (locale.equalsIgnoreCase(DanishLayout.LOCALE_NAME)) { + return DanishLayout.getInstance(); + } + } + + return UnitedStatesLayout.getInstance(); + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/NorwegianLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/NorwegianLayout.java new file mode 100644 index 00000000..109ddfe0 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/NorwegianLayout.java @@ -0,0 +1,392 @@ +package com.inputstick.api.layout; + +public class NorwegianLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "nb-NO"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //nb-NO + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 53, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 64, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 35, 0, 0 }, // & + { 39, 0, 49, 0, 0 }, // ' + { 40, 2, 37, 0, 0 }, // ( + { 41, 2, 38, 0, 0 }, // ) + { 42, 2, 49, 0, 0 }, // * + { 43, 0, 45, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 56, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 2, 36, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 55, 0, 0 }, // : + { 59, 2, 54, 0, 0 }, // ; + { 60, 0, 100, 0, 0 }, // < + { 61, 2, 39, 0, 0 }, // = + { 62, 2, 100, 0, 0 }, // > + { 63, 2, 45, 0, 0 }, // ? + { 64, 64, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 64, 37, 0, 0 }, // [ + { 92, 0, 46, 0, 0 }, // \ + { 93, 64, 38, 0, 0 }, // ] + { 94, 0, 44, 2, 48 }, // ^ + { 95, 2, 56, 0, 0 }, // _ + { 96, 0, 44, 2, 46 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 64, 36, 0, 0 }, // { + { 124, 0, 53, 0, 0 }, // | + { 125, 64, 39, 0, 0 }, // } + { 126, 0, 44, 64, 48 }, // ~ + { 163, 64, 32, 0, 0 }, // ? + { 164, 2, 33, 0, 0 }, // ¤ + { 167, 2, 53, 0, 0 }, // § + { 168, 0, 44, 0, 48 }, // ¨ + { 180, 0, 44, 64, 46 }, // ´ + { 181, 64, 16, 0, 0 }, // µ + { 192, 2, 4, 2, 46 }, // ? + { 193, 2, 4, 64, 46 }, // Á + { 194, 2, 4, 2, 48 }, // Â + { 195, 2, 4, 64, 48 }, // ? + { 196, 2, 4, 0, 48 }, // Ä + { 197, 2, 47, 0, 0 }, // ? + { 198, 2, 52, 0, 0 }, // ? + { 200, 2, 8, 2, 46 }, // ? + { 201, 2, 8, 64, 46 }, // É + { 202, 2, 8, 2, 48 }, // ? + { 203, 2, 8, 0, 48 }, // Ë + { 204, 2, 12, 2, 46 }, // ? + { 205, 2, 12, 64, 46 }, // Í + { 206, 2, 12, 2, 48 }, // Î + { 207, 2, 12, 0, 48 }, // ? + { 209, 2, 17, 64, 48 }, // ? + { 210, 2, 18, 2, 46 }, // ? + { 211, 2, 18, 64, 46 }, // Ó + { 212, 2, 18, 2, 48 }, // Ô + { 213, 2, 18, 64, 48 }, // ? + { 214, 2, 18, 0, 48 }, // Ö + { 216, 2, 51, 0, 0 }, // ? + { 217, 2, 24, 2, 46 }, // ? + { 218, 2, 24, 64, 46 }, // Ú + { 219, 2, 24, 2, 48 }, // ? + { 220, 2, 24, 0, 48 }, // Ü + { 221, 2, 28, 64, 46 }, // Ý + { 224, 0, 4, 2, 46 }, // ? + { 225, 0, 4, 64, 46 }, // á + { 226, 0, 4, 2, 48 }, // â + { 227, 0, 4, 64, 48 }, // ? + { 228, 0, 4, 0, 48 }, // ä + { 229, 0, 47, 0, 0 }, // ? + { 230, 0, 52, 0, 0 }, // ? + { 232, 0, 8, 2, 46 }, // ? + { 233, 0, 8, 64, 46 }, // é + { 234, 0, 8, 2, 48 }, // ? + { 235, 0, 8, 0, 48 }, // ë + { 236, 0, 12, 2, 46 }, // ? + { 237, 0, 12, 64, 46 }, // í + { 238, 0, 12, 2, 48 }, // î + { 239, 0, 12, 0, 48 }, // ? + { 241, 0, 17, 64, 48 }, // ? + { 242, 0, 18, 2, 46 }, // ? + { 243, 0, 18, 64, 46 }, // ó + { 244, 0, 18, 2, 48 }, // ô + { 245, 0, 18, 64, 48 }, // ? + { 246, 0, 18, 0, 48 }, // ö + { 248, 0, 51, 0, 0 }, // ? + { 249, 0, 24, 2, 46 }, // ? + { 250, 0, 24, 64, 46 }, // ú + { 251, 0, 24, 2, 48 }, // ? + { 252, 0, 24, 0, 48 }, // ü + { 253, 0, 28, 64, 46 }, // ý + { 255, 0, 28, 0, 48 }, // ? + { 8364, 64, 34, 0, 0 }, // € + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x22 , -1 , 0x40 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x23 , -1 , 0x00a3 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x00a4 , -1 , 0x24 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , 0x20ac , -1 } , + /* 7 */ { 0 , (int)'6' , 0x26 , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x002f , -1 , 0x007b , -1 } , + /* 9 */ { 0 , (int)'8' , 0x28 , -1 , 0x005b , -1 } , + /* 0a */ { 0 , (int)'9' , 0x29 , -1 , 0x005d , -1 } , + /* 0b */ { 0 , (int)'0' , 0x003d , -1 , 0x007d , -1 } , + /* 0c */ { 0 , 0x002b , 0x003f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x005c , 0x0060 , -1 , 0x00b4 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 1 , 0x00e5 , 0x00c5 , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x00a8 , 0x005e , 0x001d , 0x007e , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 1 , 0x00f8 , 0x00d8 , -1 , -1 , -1 } , + /* 28 */ { 1 , 0x00e6 , 0x00c6 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x007c , 0x00a7 , 0x001c , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x27 , 0x002a , -1 , -1 , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x003c , 0x003e , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x0060, 0x00b4, 0x00a8, 0x005e, 0x007e + }; + + //0x0060 => 0061 00e0 // a -> à + public static final int DEADKEY_LUT[][] = { + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + }; + + + + private static NorwegianLayout instance = new NorwegianLayout(); + + private NorwegianLayout() { + } + + public static NorwegianLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/PolishLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/PolishLayout.java new file mode 100644 index 00000000..ef3ec4e9 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/PolishLayout.java @@ -0,0 +1,312 @@ +package com.inputstick.api.layout; + + +public class PolishLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "pl-PL"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 52, 0, 0 }, + { 35, 2, 32, 0, 0 }, + { 36, 2, 33, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 36, 0, 0 }, + { 39, 0, 52, 0, 0 }, + { 40, 2, 38, 0, 0 }, + { 41, 2, 39, 0, 0 }, + { 42, 2, 37, 0, 0 }, + { 43, 2, 46, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 45, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 0, 56, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 51, 0, 0 }, + { 59, 0, 51, 0, 0 }, + { 60, 2, 54, 0, 0 }, + { 61, 0, 46, 0, 0 }, + { 62, 2, 55, 0, 0 }, + { 63, 2, 56, 0, 0 }, + { 64, 2, 31, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 29, 0, 0 }, + { 91, 0, 47, 0, 0 }, + { 92, 0, 49, 0, 0 }, + { 93, 0, 48, 0, 0 }, + { 94, 2, 35, 0, 0 }, + { 95, 2, 45, 0, 0 }, + { 96, 0, 53, 0, 0 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 28, 0, 0 }, + { 122, 0, 29, 0, 0 }, + { 123, 2, 47, 0, 0 }, + { 124, 2, 49, 0, 0 }, + { 125, 2, 48, 0, 0 }, + { 126, 0, 44, 2, 53 }, + { 211, 66, 18, 0, 0 }, + { 243, 64, 18, 0, 0 }, + { 260, 66, 4, 0, 0 }, + { 261, 64, 4, 0, 0 }, + { 262, 66, 6, 0, 0 }, + { 263, 64, 6, 0, 0 }, + { 280, 66, 8, 0, 0 }, + { 281, 64, 8, 0, 0 }, + { 321, 66, 15, 0, 0 }, + { 322, 64, 15, 0, 0 }, + { 323, 66, 17, 0, 0 }, + { 324, 64, 17, 0, 0 }, + { 346, 66, 22, 0, 0 }, + { 347, 64, 22, 0, 0 }, + { 377, 66, 27, 0, 0 }, + { 378, 64, 27, 0, 0 }, + { 379, 66, 29, 0, 0 }, + { 380, 64, 29, 0, 0 }, + { 8364, 64, 24, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + { 0 , (int)'2' , 0x40 , -1 , -1 , -1 } , + { 0 , (int)'3' , 0x23 , -1 , -1 , -1 } , + { 0 , (int)'4' , 0x24 , -1 , -1 , -1 } , + { 0 , (int)'5' , 0x25 , -1 , -1 , -1 } , + { 0 , (int)'6' , 0x005e , -1 , -1 , -1 } , + { 0 , (int)'7' , 0x26 , -1 , -1 , -1 } , + { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + { 0 , (int)'9' , 0x28 , -1 , -1 , -1 } , + { 0 , (int)'0' , 0x29 , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { 0 , 0x003d , 0x002b , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 5 , (int)'e' , (int)'E' , -1 , 0x119 , 0x118 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , 0x20ac , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 5 , (int)'o' , (int)'O' , -1 , 0x00f3 , 0x00d3 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 0 , 0x005b , 0x007b , 0x001b , -1 , -1 } , + { 0 , 0x005d , 0x007d , 0x001d , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 5 , (int)'a' , (int)'A' , -1 , 0x105 , 0x104 } , + { 5 , (int)'s' , (int)'S' , -1 , 0x015b , 0x015a } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 5 , (int)'l' , (int)'L' , -1 , 0x142 , 0x141 } , + { 0 , 0x003b , 0x003a , 0x001d , -1 , -1 } , + { 0 , 0x27 , 0x22 , -1 , -1 , -1 } , + { 0 , 0x60 , 0x007e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + { 5 , (int)'z' , (int)'Z' , -1 , 0x017c , 0x017b } , + { 5 , (int)'x' , (int)'X' , -1 , 0x017a , 0x179 } , + { 5 , (int)'c' , (int)'C' , -1 , 0x107 , 0x106 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 5 , (int)'n' , (int)'N' , -1 , 0x144 , 0x143 } , + { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + { 0 , 0x002c , 0x003c , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003e , -1 , -1 , -1 } , + { 0 , 0x002f , 0x003f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + + }; + + public static final int DEADKEYS[] = { + 0x007e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x007e , 0x006e , 0x0144 } , + { 0x007e , 0x0063 , 0x0107 } , + { 0x007e , 0x0078 , 0x017a } , + { 0x007e , 0x007a , 0x017c } , + { 0x007e , 0x0061 , 0x0105 } , + { 0x007e , 0x0073 , 0x015b } , + { 0x007e , 0x006c , 0x0142 } , + { 0x007e , 0x0065 , 0x0119 } , + { 0x007e , 0x006f , 0x00f3 } , + { 0x007e , 0x004e , 0x0143 } , + { 0x007e , 0x0043 , 0x0106 } , + { 0x007e , 0x0058 , 0x0179 } , + { 0x007e , 0x005a , 0x017b } , + { 0x007e , 0x0041 , 0x0104 } , + { 0x007e , 0x0053 , 0x015a } , + { 0x007e , 0x004c , 0x0141 } , + { 0x007e , 0x0045 , 0x0118 } , + { 0x007e , 0x004f , 0x00d3 } , + { 0x007e , 0x0020 , 0x007e } , + }; + + private static PolishLayout instance = new PolishLayout(); + + private PolishLayout() { + } + + public static PolishLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/PortugueseBrazilianLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/PortugueseBrazilianLayout.java new file mode 100644 index 00000000..29da9d92 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/PortugueseBrazilianLayout.java @@ -0,0 +1,399 @@ +package com.inputstick.api.layout; + +public class PortugueseBrazilianLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "pt-BR"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 27, 1, 48, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 51, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 53, 0, 0 }, + { 35, 2, 32, 0, 0 }, + { 36, 2, 33, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 36, 0, 0 }, + { 39, 0, 53, 0, 0 }, + { 40, 2, 38, 0, 0 }, + { 41, 2, 39, 0, 0 }, + { 42, 2, 37, 0, 0 }, + { 43, 2, 46, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 45, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 64, 20, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 56, 0, 0 }, + { 59, 0, 56, 0, 0 }, + { 60, 2, 54, 0, 0 }, + { 61, 0, 46, 0, 0 }, + { 62, 2, 55, 0, 0 }, + { 63, 64, 26, 0, 0 }, + { 64, 2, 31, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 29, 0, 0 }, + { 91, 0, 48, 0, 0 }, + { 92, 0, 100, 0, 0 }, + { 93, 0, 49, 0, 0 }, + { 94, 0, 44, 2, 52 }, + { 95, 2, 45, 0, 0 }, + { 96, 0, 44, 2, 47 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 28, 0, 0 }, + { 122, 0, 29, 0, 0 }, + { 123, 2, 48, 0, 0 }, + { 124, 2, 100, 0, 0 }, + { 125, 2, 49, 0, 0 }, + { 126, 0, 44, 0, 52 }, + { 162, 64, 34, 0, 0 }, + { 163, 64, 33, 0, 0 }, + { 167, 64, 46, 0, 0 }, + { 168, 0, 44, 2, 35 }, + { 170, 64, 48, 0, 0 }, + { 172, 64, 35, 0, 0 }, + { 176, 64, 8, 0, 0 }, + { 178, 64, 31, 0, 0 }, + { 179, 64, 32, 0, 0 }, + { 180, 0, 44, 0, 47 }, + { 185, 64, 30, 0, 0 }, + { 186, 64, 49, 0, 0 }, + { 192, 2, 4, 2, 47 }, + { 193, 2, 4, 0, 47 }, + { 194, 2, 4, 2, 52 }, + { 195, 2, 4, 0, 52 }, + { 196, 2, 4, 2, 35 }, + { 199, 2, 51, 0, 0 }, + { 200, 2, 8, 2, 47 }, + { 201, 2, 8, 0, 47 }, + { 202, 2, 8, 2, 52 }, + { 203, 2, 8, 2, 35 }, + { 204, 2, 12, 2, 47 }, + { 205, 2, 12, 0, 47 }, + { 206, 2, 12, 2, 52 }, + { 207, 2, 12, 2, 35 }, + { 209, 2, 17, 0, 52 }, + { 210, 2, 18, 2, 47 }, + { 211, 2, 18, 0, 47 }, + { 212, 2, 18, 2, 52 }, + { 213, 2, 18, 0, 52 }, + { 214, 2, 18, 2, 35 }, + { 217, 2, 24, 2, 47 }, + { 218, 2, 24, 0, 47 }, + { 219, 2, 24, 2, 52 }, + { 220, 2, 24, 2, 35 }, + { 221, 2, 28, 0, 47 }, + { 224, 0, 4, 2, 47 }, + { 225, 0, 4, 0, 47 }, + { 226, 0, 4, 2, 52 }, + { 227, 0, 4, 0, 52 }, + { 228, 0, 4, 2, 35 }, + { 231, 0, 51, 0, 0 }, + { 232, 0, 8, 2, 47 }, + { 233, 0, 8, 0, 47 }, + { 234, 0, 8, 2, 52 }, + { 235, 0, 8, 2, 35 }, + { 236, 0, 12, 2, 47 }, + { 237, 0, 12, 0, 47 }, + { 238, 0, 12, 2, 52 }, + { 239, 0, 12, 2, 35 }, + { 241, 0, 17, 0, 52 }, + { 242, 0, 18, 2, 47 }, + { 243, 0, 18, 0, 47 }, + { 244, 0, 18, 2, 52 }, + { 245, 0, 18, 0, 52 }, + { 246, 0, 18, 2, 35 }, + { 249, 0, 24, 2, 47 }, + { 250, 0, 24, 0, 47 }, + { 251, 0, 24, 2, 52 }, + { 252, 0, 24, 2, 35 }, + { 253, 0, 28, 0, 47 }, + { 255, 0, 28, 2, 35 }, + { 8354, 64, 6, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x21 , -1 , 0x00b9 , -1 } , + { 0 , (int)'2' , 0x40 , -1 , 0x00b2 , -1 } , + { 0 , (int)'3' , 0x23 , -1 , 0x00b3 , -1 } , + { 0 , (int)'4' , 0x24 , -1 , 0x00a3 , -1 } , + { 0 , (int)'5' , 0x25 , -1 , 0x00a2 , -1 } , + { 0 , (int)'6' , 0x00a8 , -1 , 0x00ac , -1 } , + { 0 , (int)'7' , 0x26 , -1 , -1 , -1 } , + { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + { 0 , (int)'9' , 0x28 , -1 , -1 , -1 } , + { 0 , (int)'0' , 0x29 , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { 0 , 0x003d , 0x002b , -1 , 0x00a7 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'q' , (int)'Q' , -1 , 0x002f , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , 0x003f , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x00b0 , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 0 , 0x00b4 , 0x0060 , -1 , -1 , -1 } , + { 0 , 0x005b , 0x007b , 0x001b , 0x00aa , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 1 , 0x00e7 , 0x00c7 , 0x001d , -1 , -1 } , + { 0 , 0x007e , 0x005e , -1 , -1 , -1 } , + { 0 , 0x27 , 0x22 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x005d , 0x007d , 0x001c , 0x00ba , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , 0x20a2 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + { 0 , 0x002c , 0x003c , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003e , -1 , -1 , -1 } , + { 0 , 0x003b , 0x003a , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + + + + + + + + }; + + public static final int DEADKEYS[] = { + 0x00a8, 0x00b4, 0x0060, 0x007e, 0x005e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + + }; + + private static PortugueseBrazilianLayout instance = new PortugueseBrazilianLayout(); + + private PortugueseBrazilianLayout() { + } + + public static PortugueseBrazilianLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/RussianLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/RussianLayout.java new file mode 100644 index 00000000..0c2c7d0c --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/RussianLayout.java @@ -0,0 +1,269 @@ +package com.inputstick.api.layout; + +public class RussianLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "ru-RU"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //ru-RU + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 28, 1, 49, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 31, 0, 0 }, // " + { 37, 2, 34, 0, 0 }, // % + { 40, 2, 38, 0, 0 }, // ( + { 41, 2, 39, 0, 0 }, // ) + { 42, 2, 37, 0, 0 }, // * + { 43, 2, 46, 0, 0 }, // + + { 44, 2, 56, 0, 0 }, // , + { 45, 0, 45, 0, 0 }, // - + { 46, 0, 56, 0, 0 }, // . + { 47, 2, 49, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 35, 0, 0 }, // : + { 59, 2, 33, 0, 0 }, // ; + { 61, 0, 46, 0, 0 }, // = + { 63, 2, 36, 0, 0 }, // ? + { 92, 0, 49, 0, 0 }, // \ + { 95, 2, 45, 0, 0 }, // _ + { 1025, 2, 53, 0, 0 }, // ? + { 1040, 2, 9, 0, 0 }, // ? + { 1041, 2, 54, 0, 0 }, // ? + { 1042, 2, 7, 0, 0 }, // ? + { 1043, 2, 24, 0, 0 }, // ? + { 1044, 2, 15, 0, 0 }, // ? + { 1045, 2, 23, 0, 0 }, // ? + { 1046, 2, 51, 0, 0 }, // ? + { 1047, 2, 19, 0, 0 }, // ? + { 1048, 2, 5, 0, 0 }, // ? + { 1049, 2, 20, 0, 0 }, // ? + { 1050, 2, 21, 0, 0 }, // ? + { 1051, 2, 14, 0, 0 }, // ? + { 1052, 2, 25, 0, 0 }, // ? + { 1053, 2, 28, 0, 0 }, // ? + { 1054, 2, 13, 0, 0 }, // ? + { 1055, 2, 10, 0, 0 }, // ? + { 1056, 2, 11, 0, 0 }, // ? + { 1057, 2, 6, 0, 0 }, // ? + { 1058, 2, 17, 0, 0 }, // ? + { 1059, 2, 8, 0, 0 }, // ? + { 1060, 2, 4, 0, 0 }, // ? + { 1061, 2, 47, 0, 0 }, // ? + { 1062, 2, 26, 0, 0 }, // ? + { 1063, 2, 27, 0, 0 }, // ? + { 1064, 2, 12, 0, 0 }, // ? + { 1065, 2, 18, 0, 0 }, // ? + { 1066, 2, 48, 0, 0 }, // ? + { 1067, 2, 22, 0, 0 }, // ? + { 1068, 2, 16, 0, 0 }, // ? + { 1069, 2, 52, 0, 0 }, // ? + { 1070, 2, 55, 0, 0 }, // ? + { 1071, 2, 29, 0, 0 }, // ? + { 1072, 0, 9, 0, 0 }, // ? + { 1073, 0, 54, 0, 0 }, // ? + { 1074, 0, 7, 0, 0 }, // ? + { 1075, 0, 24, 0, 0 }, // ? + { 1076, 0, 15, 0, 0 }, // ? + { 1077, 0, 23, 0, 0 }, // ? + { 1078, 0, 51, 0, 0 }, // ? + { 1079, 0, 19, 0, 0 }, // ? + { 1080, 0, 5, 0, 0 }, // ? + { 1081, 0, 20, 0, 0 }, // ? + { 1082, 0, 21, 0, 0 }, // ? + { 1083, 0, 14, 0, 0 }, // ? + { 1084, 0, 25, 0, 0 }, // ? + { 1085, 0, 28, 0, 0 }, // ? + { 1086, 0, 13, 0, 0 }, // ? + { 1087, 0, 10, 0, 0 }, // ? + { 1088, 0, 11, 0, 0 }, // ? + { 1089, 0, 6, 0, 0 }, // ? + { 1090, 0, 17, 0, 0 }, // ? + { 1091, 0, 8, 0, 0 }, // ? + { 1092, 0, 4, 0, 0 }, // ? + { 1093, 0, 47, 0, 0 }, // ? + { 1094, 0, 26, 0, 0 }, // ? + { 1095, 0, 27, 0, 0 }, // ? + { 1096, 0, 12, 0, 0 }, // ? + { 1097, 0, 18, 0, 0 }, // ? + { 1098, 0, 48, 0, 0 }, // ? + { 1099, 0, 22, 0, 0 }, // ? + { 1100, 0, 16, 0, 0 }, // ? + { 1101, 0, 52, 0, 0 }, // ? + { 1102, 0, 55, 0, 0 }, // ? + { 1103, 0, 29, 0, 0 }, // ? + { 1105, 0, 53, 0, 0 }, // ? + { 8470, 2, 32, 0, 0 }, // ? + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x22 , -1 , -1 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x2116 , -1 , -1 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x003b , -1 , -1 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , -1 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x003a , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x003f , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x28 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x29 , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x003d , 0x002b , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , 0x439 , 0x419 , -1 , -1 , -1 } , + /* 11 */ { 1 , 0x446 , 0x426 , -1 , -1 , -1 } , + /* 12 */ { 1 , 0x443 , 0x423 , -1 , -1 , -1 } , + /* 13 */ { 1 , 0x043a , 0x041a , -1 , -1 , -1 } , + /* 14 */ { 1 , 0x435 , 0x415 , -1 , -1 , -1 } , + /* 15 */ { 1 , 0x043d , 0x041d , -1 , -1 , -1 } , + /* 16 */ { 1 , 0x433 , 0x413 , -1 , -1 , -1 } , + /* 17 */ { 1 , 0x448 , 0x428 , -1 , -1 , -1 } , + /* 18 */ { 1 , 0x449 , 0x429 , -1 , -1 , -1 } , + /* 19 */ { 1 , 0x437 , 0x417 , -1 , -1 , -1 } , + /* 1a */ { 1 , 0x445 , 0x425 , -1 , -1 , -1 } , + /* 1b */ { 1 , 0x044a , 0x042a , -1 , -1 , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , 0x444 , 0x424 , -1 , -1 , -1 } , + /* 1f */ { 1 , 0x044b , 0x042b , -1 , -1 , -1 } , + + + /* 20 */ { 1 , 0x432 , 0x412 , -1 , -1 , -1 } , + /* 21 */ { 1 , 0x430 , 0x410 , -1 , -1 , -1 } , + /* 22 */ { 1 , 0x043f , 0x041f , -1 , -1 , -1 } , + /* 23 */ { 1 , 0x440 , 0x420 , -1 , -1 , -1 } , + /* 24 */ { 1 , 0x043e , 0x041e , -1 , -1 , -1 } , + /* 25 */ { 1 , 0x043b , 0x041b , -1 , -1 , -1 } , + /* 26 */ { 1 , 0x434 , 0x414 , -1 , -1 , -1 } , + /* 27 */ { 1 , 0x436 , 0x416 , -1 , -1 , -1 } , + /* 28 */ { 1 , 0x044d , 0x042d , -1 , -1 , -1 } , + /* 29 */ { 1 , 0x451 , 0x401 , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x005c , 0x002f , 0x001c , -1 , -1 } , + /* 2c */ { 1 , 0x044f , 0x042f , -1 , -1 , -1 } , + /* 2d */ { 1 , 0x447 , 0x427 , -1 , -1 , -1 } , + /* 2e */ { 1 , 0x441 , 0x421 , -1 , -1 , -1 } , + /* 2f */ { 1 , 0x043c , 0x041c , -1 , -1 , -1 } , + + + /* 30 */ { 1 , 0x438 , 0x418 , -1 , -1 , -1 } , + /* 31 */ { 1 , 0x442 , 0x422 , -1 , -1 , -1 } , + /* 32 */ { 1 , 0x044c , 0x042c , -1 , -1 , -1 } , + /* 33 */ { 1 , 0x431 , 0x411 , -1 , -1 , -1 } , + /* 34 */ { 1 , 0x044e , 0x042e , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002e , 0x002c , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x005c , 0x002f , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static RussianLayout instance = new RussianLayout(); + + private RussianLayout() { + } + + public static RussianLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SlovakLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SlovakLayout.java new file mode 100644 index 00000000..1d093790 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SlovakLayout.java @@ -0,0 +1,505 @@ +package com.inputstick.api.layout; + +public class SlovakLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "sk-SK"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 0, 66, 30, 0, 0 }, + { 7, 64, 30, 0, 0 }, + { 27, 1, 48, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 51, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 52, 0, 0 }, + { 34, 2, 51, 0, 0 }, + { 35, 64, 27, 0, 0 }, + { 36, 64, 51, 0, 0 }, + { 37, 2, 45, 0, 0 }, + { 38, 64, 6, 0, 0 }, + { 39, 64, 19, 0, 0 }, + { 40, 2, 48, 0, 0 }, + { 41, 2, 49, 0, 0 }, + { 42, 64, 56, 0, 0 }, + { 43, 0, 30, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 56, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 2, 47, 0, 0 }, + { 48, 2, 39, 0, 0 }, + { 49, 2, 30, 0, 0 }, + { 50, 2, 31, 0, 0 }, + { 51, 2, 32, 0, 0 }, + { 52, 2, 33, 0, 0 }, + { 53, 2, 34, 0, 0 }, + { 54, 2, 35, 0, 0 }, + { 55, 2, 36, 0, 0 }, + { 56, 2, 37, 0, 0 }, + { 57, 2, 38, 0, 0 }, + { 58, 2, 55, 0, 0 }, + { 59, 0, 53, 0, 0 }, + { 60, 64, 54, 0, 0 }, + { 61, 0, 45, 0, 0 }, + { 62, 64, 29, 0, 0 }, + { 63, 2, 54, 0, 0 }, + { 64, 64, 25, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 29, 0, 0 }, + { 91, 64, 9, 0, 0 }, + { 92, 64, 20, 0, 0 }, + { 93, 64, 10, 0, 0 }, + { 94, 0, 44, 64, 32 }, + { 95, 2, 56, 0, 0 }, + { 96, 64, 36, 0, 0 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 28, 0, 0 }, + { 122, 0, 29, 0, 0 }, + { 123, 64, 5, 0, 0 }, + { 124, 64, 26, 0, 0 }, + { 125, 64, 17, 0, 0 }, + { 164, 64, 49, 0, 0 }, + { 167, 0, 52, 0, 0 }, + { 168, 0, 44, 64, 45 }, + { 176, 0, 44, 64, 34 }, + { 180, 0, 44, 64, 38 }, + { 184, 0, 44, 64, 46 }, + { 193, 2, 4, 64, 38 }, + { 194, 2, 4, 64, 32 }, + { 196, 2, 4, 64, 45 }, + { 199, 2, 6, 64, 46 }, + { 201, 2, 8, 64, 38 }, + { 203, 2, 8, 64, 45 }, + { 205, 2, 12, 64, 38 }, + { 206, 2, 12, 64, 32 }, + { 211, 2, 18, 64, 38 }, + { 212, 2, 18, 64, 32 }, + { 214, 2, 18, 64, 45 }, + { 215, 64, 48, 0, 0 }, + { 218, 2, 24, 64, 38 }, + { 220, 2, 24, 64, 45 }, + { 221, 2, 28, 64, 38 }, + { 223, 64, 52, 0, 0 }, + { 225, 0, 37, 0, 0 }, + { 226, 0, 4, 64, 32 }, + { 228, 0, 48, 0, 0 }, + { 231, 0, 6, 64, 46 }, + { 233, 0, 39, 0, 0 }, + { 235, 0, 8, 64, 45 }, + { 237, 0, 38, 0, 0 }, + { 238, 0, 12, 64, 32 }, + { 243, 0, 18, 64, 38 }, + { 244, 0, 51, 0, 0 }, + { 246, 0, 18, 64, 45 }, + { 247, 64, 47, 0, 0 }, + { 250, 0, 47, 0, 0 }, + { 252, 0, 24, 64, 45 }, + { 253, 0, 36, 0, 0 }, + { 258, 2, 4, 64, 32 }, + { 259, 0, 4, 64, 32 }, + { 260, 2, 4, 64, 35 }, + { 261, 0, 4, 64, 35 }, + { 262, 2, 6, 64, 38 }, + { 263, 0, 6, 64, 38 }, + { 268, 2, 6, 64, 31 }, + { 269, 0, 33, 0, 0 }, + { 270, 2, 7, 64, 31 }, + { 271, 0, 7, 64, 31 }, + { 272, 64, 7, 0, 0 }, + { 273, 64, 22, 0, 0 }, + { 280, 2, 8, 64, 35 }, + { 281, 0, 8, 64, 35 }, + { 282, 2, 8, 64, 31 }, + { 283, 0, 8, 64, 31 }, + { 313, 2, 15, 64, 38 }, + { 314, 0, 15, 64, 38 }, + { 317, 2, 15, 64, 31 }, + { 318, 0, 31, 0, 0 }, + { 321, 64, 15, 0, 0 }, + { 322, 64, 14, 0, 0 }, + { 323, 2, 17, 64, 38 }, + { 324, 0, 17, 64, 38 }, + { 327, 2, 17, 64, 31 }, + { 328, 0, 49, 0, 0 }, + { 336, 2, 18, 64, 39 }, + { 337, 0, 18, 64, 39 }, + { 340, 2, 21, 64, 38 }, + { 341, 0, 21, 64, 38 }, + { 344, 2, 21, 64, 31 }, + { 345, 0, 21, 64, 31 }, + { 346, 2, 22, 64, 38 }, + { 347, 0, 22, 64, 38 }, + { 350, 2, 22, 64, 46 }, + { 351, 0, 22, 64, 46 }, + { 352, 2, 22, 64, 31 }, + { 353, 0, 32, 0, 0 }, + { 354, 2, 23, 64, 46 }, + { 355, 0, 23, 64, 46 }, + { 356, 2, 23, 64, 31 }, + { 357, 0, 34, 0, 0 }, + { 366, 2, 24, 64, 34 }, + { 367, 0, 24, 64, 34 }, + { 368, 2, 24, 64, 39 }, + { 369, 0, 24, 64, 39 }, + { 377, 2, 29, 64, 38 }, + { 378, 0, 29, 64, 38 }, + { 379, 2, 29, 64, 37 }, + { 380, 0, 29, 64, 37 }, + { 381, 2, 29, 64, 31 }, + { 382, 0, 35, 0, 0 }, + { 711, 0, 44, 64, 31 }, + { 728, 0, 44, 64, 33 }, + { 729, 0, 44, 64, 37 }, + { 731, 0, 44, 64, 35 }, + { 733, 0, 44, 64, 39 }, + { 8364, 64, 8, 0, 0 }, + }; + + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x02b , (int)'1' , -1 , 0x007 , 0 } , + { 0 , 0x13e , (int)'2' , -1 , 0x2c7 , 0 } , + { 0 , 0x161 , (int)'3' , -1 , 0x05e , 0 } , + { 0 , 0x10d , (int)'4' , -1 , 0x2d8 , 0 } , + { 0 , 0x165 , (int)'5' , -1 , 0x0b0 , 0 } , + { 0 , 0x17e , (int)'6' , -1 , 0x2db , 0 } , + { 0 , 0x0fd , (int)'7' , -1 , 0x060 , 0 } , + { 0 , 0x0e1 , (int)'8' , -1 , 0x2d9 , 0 } , + { 0 , 0x0ed , (int)'9' , -1 , 0x0b4 , 0 } , + { 0 , 0x0e9 , (int)'0' , -1 , 0x2dd , 0 } , + { 0 , 0x03d , 0x025 , -1 , 0x0a8 , 0 } , + { 0 , 0x0b4 , 0x2c7 , -1 , 0x0b8 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , 'q' , 'Q' , -1 , 0x05c , 0 } , + { 1 , 'w' , 'W' , -1 , 0x07c , 0 } , + { 1 , 'e' , 'E' , -1 , 0x20ac , 0 } , + { 1 , 'r' , 'R' , -1 , -1 , 0 } , + { 1 , 't' , 'T' , -1 , -1 , 0 } , + { 1 , 'y' , 'Y' , -1 , -1 , 0 } , + { 1 , 'u' , 'U' , -1 , -1 , 0 } , + { 1 , 'i' , 'I' , -1 , -1 , 0 } , + { 1 , 'o' , 'O' , -1 , -1 , 0 } , + { 1 , 'p' , 'P' , -1 , 0x027 , 0 } , + { 0 , 0x0fa , 0x02f , -1 , 0x0f7 , 0 } , + { 0 , 0x0e4 , 0x028 , 0x01b , 0x0d7 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , 'a' , 'A' , -1 , -1 , 0 } , + { 1 , 's' , 'S' , -1 , 0x111 , 0 } , + + { 1 , 'd' , 'D' , -1 , 0x110 , 0 } , + { 1 , 'f' , 'F' , -1 , 0x05b , 0 } , + { 1 , 'g' , 'G' , -1 , 0x05d , 0 } , + { 1 , 'h' , 'H' , -1 , -1 , 0 } , + { 1 , 'j' , 'J' , -1 , -1 , 0 } , + { 1 , 'k' , 'K' , -1 , 0x142 , 0 } , + { 1 , 'l' , 'L' , -1 , 0x141 , 0 } , + { 0 , 0x0f4 , 0x022 , 0x01d , 0x024 , 0 } , + { 0 , 0x0a7 , 0x021 , -1 , 0x0df , 0 } , + { 0 , 0x03b , 0x0b0 , -1 , -1 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x148 , 0x029 , 0x01c , 0x0a4 , 0 } , + { 1 , 'z' , 'Z' , -1 , 0x03e , 0 } , + { 1 , 'x' , 'X' , -1 , 0x023 , 0 } , + { 1 , 'c' , 'C' , -1 , 0x026 , 0 } , + { 1 , 'v' , 'V' , -1 , 0x040 , 0 } , + + { 1 , 'b' , 'B' , -1 , 0x07b , 0 } , + { 1 , 'n' , 'N' , -1 , 0x07d , 0 } , + { 1 , 'm' , 'M' , -1 , -1 , 0 } , + { 0 , 0x02c , 0x03f , -1 , 0x03c , 0 } , + { 0 , 0x02e , 0x03a , -1 , 0x03e , 0 } , + { 0 , 0x02d , 0x05f , -1 , 0x02a , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x020 , 0x020 , 0x020 , -1 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x02c , 0x02c , -1 , -1 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x026 , 0x02a , 0x01c , 0x03c , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + + + }; + + public static final int DEADKEYS[] = { + 0x02c7, 0x005e, 0x02d8, 0x00b0, 0x02db, 0x02d9, 0x00b4, 0x02dd, 0x00a8, 0x00b4, 0x02c7, 0x00b8, 0x00b0 + }; + + public static final int DEADKEY_LUT[][] = { + { 0x02c7 , 0x006e , 0x0148 } , + { 0x02c7 , 0x0063 , 0x010d } , + { 0x02c7 , 0x007a , 0x017e } , + { 0x02c7 , 0x0064 , 0x010f } , + { 0x02c7 , 0x0073 , 0x0161 } , + { 0x02c7 , 0x006c , 0x013e } , + { 0x02c7 , 0x0065 , 0x011b } , + { 0x02c7 , 0x0072 , 0x0159 } , + { 0x02c7 , 0x0074 , 0x0165 } , + { 0x02c7 , 0x004e , 0x0147 } , + { 0x02c7 , 0x0043 , 0x010c } , + { 0x02c7 , 0x005a , 0x017d } , + { 0x02c7 , 0x0044 , 0x010e } , + { 0x02c7 , 0x0053 , 0x0160 } , + { 0x02c7 , 0x004c , 0x013d } , + { 0x02c7 , 0x0045 , 0x011a } , + { 0x02c7 , 0x0052 , 0x0158 } , + { 0x02c7 , 0x0054 , 0x0164 } , + { 0x02c7 , 0x0020 , 0x02c7 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x005e , 0x0061 , 0x0103 } , + { 0x005e , 0x0041 , 0x0102 } , + { 0x005e , 0x0020 , 0x02d8 } , + { 0x00b0 , 0x0075 , 0x016f } , + { 0x00b0 , 0x0055 , 0x016e } , + { 0x00b0 , 0x0020 , 0x00b0 } , + { 0x02db , 0x0061 , 0x0105 } , + { 0x02db , 0x0065 , 0x0119 } , + { 0x02db , 0x0041 , 0x0104 } , + { 0x02db , 0x0045 , 0x0118 } , + { 0x02db , 0x0020 , 0x02db } , + { 0x02d9 , 0x007a , 0x017c } , + { 0x02d9 , 0x005a , 0x017b } , + { 0x02d9 , 0x0020 , 0x02d9 } , + { 0x00b4 , 0x006e , 0x0144 } , + { 0x00b4 , 0x0063 , 0x0107 } , + { 0x00b4 , 0x007a , 0x017a } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0073 , 0x015b } , + { 0x00b4 , 0x006c , 0x013a } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0072 , 0x0155 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x004e , 0x0143 } , + { 0x00b4 , 0x0043 , 0x0106 } , + { 0x00b4 , 0x005a , 0x0179 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0053 , 0x015a } , + { 0x00b4 , 0x004c , 0x0139 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0052 , 0x0154 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x02dd , 0x0075 , 0x0171 } , + { 0x02dd , 0x006f , 0x0151 } , + { 0x02dd , 0x0055 , 0x0170 } , + { 0x02dd , 0x004f , 0x0150 } , + { 0x02dd , 0x0020 , 0x02dd } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + { 0x00b4 , 0x006e , 0x0144 } , + { 0x00b4 , 0x0063 , 0x0107 } , + { 0x00b4 , 0x007a , 0x017a } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0073 , 0x015b } , + { 0x00b4 , 0x006c , 0x013a } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0072 , 0x0155 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x004e , 0x0143 } , + { 0x00b4 , 0x0043 , 0x0106 } , + { 0x00b4 , 0x005a , 0x0179 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0053 , 0x015a } , + { 0x00b4 , 0x004c , 0x0139 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0052 , 0x0154 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x02c7 , 0x006e , 0x0148 } , + { 0x02c7 , 0x0063 , 0x010d } , + { 0x02c7 , 0x007a , 0x017e } , + { 0x02c7 , 0x0064 , 0x010f } , + { 0x02c7 , 0x0073 , 0x0161 } , + { 0x02c7 , 0x006c , 0x013e } , + { 0x02c7 , 0x0065 , 0x011b } , + { 0x02c7 , 0x0072 , 0x0159 } , + { 0x02c7 , 0x0074 , 0x0165 } , + { 0x02c7 , 0x004e , 0x0147 } , + { 0x02c7 , 0x0043 , 0x010c } , + { 0x02c7 , 0x005a , 0x017d } , + { 0x02c7 , 0x0044 , 0x010e } , + { 0x02c7 , 0x0053 , 0x0160 } , + { 0x02c7 , 0x004c , 0x013d } , + { 0x02c7 , 0x0045 , 0x011a } , + { 0x02c7 , 0x0052 , 0x0158 } , + { 0x02c7 , 0x0054 , 0x0164 } , + { 0x02c7 , 0x0020 , 0x02c7 } , + { 0x00b8 , 0x0063 , 0x00e7 } , + { 0x00b8 , 0x0073 , 0x015f } , + { 0x00b8 , 0x0074 , 0x0163 } , + { 0x00b8 , 0x0043 , 0x00c7 } , + { 0x00b8 , 0x0053 , 0x015e } , + { 0x00b8 , 0x0054 , 0x0162 } , + { 0x00b8 , 0x0020 , 0x00b8 } , + { 0x00b0 , 0x0075 , 0x016f } , + { 0x00b0 , 0x0055 , 0x016e } , + { 0x00b0 , 0x0020 , 0x00b0 } , + + }; + + private static SlovakLayout instance = new SlovakLayout(); + + private SlovakLayout() { + } + + public static SlovakLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SpanishLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SpanishLayout.java new file mode 100644 index 00000000..212e3d76 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SpanishLayout.java @@ -0,0 +1,392 @@ +package com.inputstick.api.layout; + +public class SpanishLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "es-ES"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 20, 1, 44, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 31, 0, 0 }, + { 35, 64, 32, 0, 0 }, + { 36, 2, 33, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 35, 0, 0 }, + { 39, 0, 45, 0, 0 }, + { 40, 2, 37, 0, 0 }, + { 41, 2, 38, 0, 0 }, + { 42, 2, 48, 0, 0 }, + { 43, 0, 48, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 56, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 2, 36, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 55, 0, 0 }, + { 59, 2, 54, 0, 0 }, + { 60, 0, 100, 0, 0 }, + { 61, 2, 39, 0, 0 }, + { 62, 2, 100, 0, 0 }, + { 63, 2, 45, 0, 0 }, + { 64, 64, 31, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 29, 0, 0 }, + { 91, 64, 47, 0, 0 }, + { 92, 64, 53, 0, 0 }, + { 93, 64, 48, 0, 0 }, + { 94, 0, 44, 2, 47 }, + { 95, 2, 56, 0, 0 }, + { 96, 0, 44, 0, 47 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 28, 0, 0 }, + { 122, 0, 29, 0, 0 }, + { 123, 64, 52, 0, 0 }, + { 124, 64, 30, 0, 0 }, + { 125, 64, 49, 0, 0 }, + { 126, 0, 44, 64, 33 }, + { 161, 0, 46, 0, 0 }, + { 168, 0, 44, 2, 52 }, + { 170, 2, 53, 0, 0 }, + { 172, 64, 35, 0, 0 }, + { 180, 0, 44, 0, 52 }, + { 183, 2, 32, 0, 0 }, + { 186, 0, 53, 0, 0 }, + { 191, 2, 46, 0, 0 }, + { 192, 2, 4, 0, 47 }, + { 193, 2, 4, 0, 52 }, + { 194, 2, 4, 2, 47 }, + { 195, 2, 4, 64, 33 }, + { 196, 2, 4, 2, 52 }, + { 199, 2, 49, 0, 0 }, + { 200, 2, 8, 0, 47 }, + { 201, 2, 8, 0, 52 }, + { 202, 2, 8, 2, 47 }, + { 203, 2, 8, 2, 52 }, + { 204, 2, 12, 0, 47 }, + { 205, 2, 12, 0, 52 }, + { 206, 2, 12, 2, 47 }, + { 207, 2, 12, 2, 52 }, + { 209, 2, 51, 0, 0 }, + { 210, 2, 18, 0, 47 }, + { 211, 2, 18, 0, 52 }, + { 212, 2, 18, 2, 47 }, + { 213, 2, 18, 64, 33 }, + { 214, 2, 18, 2, 52 }, + { 217, 2, 24, 0, 47 }, + { 218, 2, 24, 0, 52 }, + { 219, 2, 24, 2, 47 }, + { 220, 2, 24, 2, 52 }, + { 221, 2, 28, 0, 52 }, + { 224, 0, 4, 0, 47 }, + { 225, 0, 4, 0, 52 }, + { 226, 0, 4, 2, 47 }, + { 227, 0, 4, 64, 33 }, + { 228, 0, 4, 2, 52 }, + { 231, 0, 49, 0, 0 }, + { 232, 0, 8, 0, 47 }, + { 233, 0, 8, 0, 52 }, + { 234, 0, 8, 2, 47 }, + { 235, 0, 8, 2, 52 }, + { 236, 0, 12, 0, 47 }, + { 237, 0, 12, 0, 52 }, + { 238, 0, 12, 2, 47 }, + { 239, 0, 12, 2, 52 }, + { 241, 0, 51, 0, 0 }, + { 242, 0, 18, 0, 47 }, + { 243, 0, 18, 0, 52 }, + { 244, 0, 18, 2, 47 }, + { 245, 0, 18, 64, 33 }, + { 246, 0, 18, 2, 52 }, + { 249, 0, 24, 0, 47 }, + { 250, 0, 24, 0, 52 }, + { 251, 0, 24, 2, 47 }, + { 252, 0, 24, 2, 52 }, + { 253, 0, 28, 0, 52 }, + { 255, 0, 28, 2, 52 }, + { 8364, 64, 34, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x21 , -1 , 0x007c , -1 } , + { 0 , (int)'2' , 0x22 , -1 , 0x40 , -1 } , + { 0 , (int)'3' , 0x00b7 , -1 , 0x23 , -1 } , + { 0 , (int)'4' , 0x24 , -1 , 0x007e , -1 } , + { 0 , (int)'5' , 0x25 , -1 , 0x20ac , -1 } , + { 0 , (int)'6' , 0x26 , -1 , 0x00ac , -1 } , + { 0 , (int)'7' , 0x002f , -1 , -1 , -1 } , + { 0 , (int)'8' , 0x28 , -1 , -1 , -1 } , + { 0 , (int)'9' , 0x29 , -1 , -1 , -1 } , + { 0 , (int)'0' , 0x003d , -1 , -1 , -1 } , + { 0 , 0x27 , 0x003f , -1 , -1 , -1 } , + { 0 , 0x00a1 , 0x00bf , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 0 , 0x0060 , 0x005e , 0x001b , 0x005b , -1 } , + { 0 , 0x002b , 0x002a , 0x001d , 0x005d , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 1 , 0x00f1 , 0x00d1 , -1 , -1 , -1 } , + { 0 , 0x00b4 , 0x00a8 , -1 , 0x007b , -1 } , + { 0 , 0x00ba , 0x00aa , -1 , 0x005c , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , 0x00e7 , 0x00c7 , 0x001c , 0x007d , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x20 , 0x20 , 20 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x003c , 0x003e , 0x001c , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x007e, 0x0060, 0x005e, 0x00b4,0x00a8 + }; + + public static final int DEADKEY_LUT[][] = { + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + }; + + private static SpanishLayout instance = new SpanishLayout(); + + private SpanishLayout() { + } + + public static SpanishLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SwedishLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SwedishLayout.java new file mode 100644 index 00000000..d0c2228b --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SwedishLayout.java @@ -0,0 +1,386 @@ +package com.inputstick.api.layout; + +public class SwedishLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "sv-SE"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 53, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 31, 0, 0 }, + { 35, 2, 32, 0, 0 }, + { 36, 64, 33, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 35, 0, 0 }, + { 39, 0, 49, 0, 0 }, + { 40, 2, 37, 0, 0 }, + { 41, 2, 38, 0, 0 }, + { 42, 2, 49, 0, 0 }, + { 43, 0, 45, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 56, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 2, 36, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 55, 0, 0 }, + { 59, 2, 54, 0, 0 }, + { 60, 0, 100, 0, 0 }, + { 61, 2, 39, 0, 0 }, + { 62, 2, 100, 0, 0 }, + { 63, 2, 45, 0, 0 }, + { 64, 64, 31, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 29, 0, 0 }, + { 91, 64, 37, 0, 0 }, + { 92, 64, 45, 0, 0 }, + { 93, 64, 38, 0, 0 }, + { 94, 0, 44, 2, 48 }, + { 95, 2, 56, 0, 0 }, + { 96, 0, 44, 2, 46 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 28, 0, 0 }, + { 122, 0, 29, 0, 0 }, + { 123, 64, 36, 0, 0 }, + { 124, 64, 100, 0, 0 }, + { 125, 64, 39, 0, 0 }, + { 126, 0, 44, 64, 48 }, + { 163, 64, 32, 0, 0 }, + { 164, 2, 33, 0, 0 }, + { 167, 0, 53, 0, 0 }, + { 168, 0, 44, 0, 48 }, + { 180, 0, 44, 0, 46 }, + { 181, 64, 16, 0, 0 }, + { 189, 2, 53, 0, 0 }, + { 192, 2, 4, 2, 46 }, + { 193, 2, 4, 0, 46 }, + { 194, 2, 4, 2, 48 }, + { 195, 2, 4, 64, 48 }, + { 196, 2, 52, 0, 0 }, + { 197, 2, 47, 0, 0 }, + { 200, 2, 8, 2, 46 }, + { 201, 2, 8, 0, 46 }, + { 202, 2, 8, 2, 48 }, + { 203, 2, 8, 0, 48 }, + { 204, 2, 12, 2, 46 }, + { 205, 2, 12, 0, 46 }, + { 206, 2, 12, 2, 48 }, + { 207, 2, 12, 0, 48 }, + { 209, 2, 17, 64, 48 }, + { 210, 2, 18, 2, 46 }, + { 211, 2, 18, 0, 46 }, + { 212, 2, 18, 2, 48 }, + { 213, 2, 18, 64, 48 }, + { 214, 2, 51, 0, 0 }, + { 217, 2, 24, 2, 46 }, + { 218, 2, 24, 0, 46 }, + { 219, 2, 24, 2, 48 }, + { 220, 2, 24, 0, 48 }, + { 221, 2, 28, 0, 46 }, + { 224, 0, 4, 2, 46 }, + { 225, 0, 4, 0, 46 }, + { 226, 0, 4, 2, 48 }, + { 227, 0, 4, 64, 48 }, + { 228, 0, 52, 0, 0 }, + { 229, 0, 47, 0, 0 }, + { 232, 0, 8, 2, 46 }, + { 233, 0, 8, 0, 46 }, + { 234, 0, 8, 2, 48 }, + { 235, 0, 8, 0, 48 }, + { 236, 0, 12, 2, 46 }, + { 237, 0, 12, 0, 46 }, + { 238, 0, 12, 2, 48 }, + { 239, 0, 12, 0, 48 }, + { 241, 0, 17, 64, 48 }, + { 242, 0, 18, 2, 46 }, + { 243, 0, 18, 0, 46 }, + { 244, 0, 18, 2, 48 }, + { 245, 0, 18, 64, 48 }, + { 246, 0, 51, 0, 0 }, + { 249, 0, 24, 2, 46 }, + { 250, 0, 24, 0, 46 }, + { 251, 0, 24, 2, 48 }, + { 252, 0, 24, 0, 48 }, + { 253, 0, 28, 0, 46 }, + { 255, 0, 28, 0, 48 }, + { 8364, 64, 34, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + { 0 , (int)'2' , 0x22 , -1 , 0x40 , -1 } , + { 0 , (int)'3' , 0x23 , -1 , 0x00a3 , -1 } , + { 0 , (int)'4' , 0x00a4 , -1 , 0x24 , -1 } , + { 0 , (int)'5' , 0x25 , -1 , 0x20ac , -1 } , + { 0 , (int)'6' , 0x26 , -1 , -1 , -1 } , + { 0 , (int)'7' , 0x002f , -1 , 0x007b , -1 } , + { 0 , (int)'8' , 0x28 , -1 , 0x005b , -1 } , + { 0 , (int)'9' , 0x29 , -1 , 0x005d , -1 } , + { 0 , (int)'0' , 0x003d , -1 , 0x007d , -1 } , + { 0 , 0x002b , 0x003f , -1 , 0x005c , -1 } , + { 0 , 0x00b4 , 0x0060 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 1 , 0x00e5 , 0x00c5 , 0x001b , -1 , -1 } , + { 0 , 0x00a8 , 0x005e , 0x001d , 0x007e , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 1 , 0x00f6 , 0x00d6 , -1 , -1 , -1 } , + { 1 , 0x00e4 , 0x00c4 , -1 , -1 , -1 } , + { 0 , 0x00a7 , 0x00bd , 0x001c , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x27 , 0x002a , -1 , -1 , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , 0x00b5 , -1 } , + { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002c , 0x002c , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x003c , 0x003e , 0x001c , 0x007c , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x0060, 0x00b4, 0x005e, 0x00a8, 0x007e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + }; + + private static SwedishLayout instance = new SwedishLayout(); + + private SwedishLayout() { + } + + public static SwedishLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SwissFrenchLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SwissFrenchLayout.java new file mode 100644 index 00000000..250e1407 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SwissFrenchLayout.java @@ -0,0 +1,353 @@ +package com.inputstick.api.layout; + +public class SwissFrenchLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "fr-CH"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 8, 2, 37, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 48, 0, 0 }, + { 34, 2, 31, 0, 0 }, + { 35, 64, 32, 0, 0 }, + { 36, 0, 49, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 35, 0, 0 }, + { 39, 0, 45, 0, 0 }, + { 41, 2, 38, 0, 0 }, + { 42, 2, 32, 0, 0 }, + { 43, 2, 30, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 56, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 2, 36, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 55, 0, 0 }, + { 59, 2, 54, 0, 0 }, + { 60, 0, 100, 0, 0 }, + { 61, 2, 39, 0, 0 }, + { 62, 2, 100, 0, 0 }, + { 63, 2, 45, 0, 0 }, + { 64, 64, 31, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 29, 0, 0 }, + { 90, 2, 28, 0, 0 }, + { 91, 64, 47, 0, 0 }, + { 92, 64, 100, 0, 0 }, + { 93, 64, 48, 0, 0 }, + { 94, 0, 44, 0, 46 }, + { 95, 2, 56, 0, 0 }, + { 96, 0, 44, 2, 46 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 29, 0, 0 }, + { 122, 0, 28, 0, 0 }, + { 123, 64, 52, 0, 0 }, + { 124, 64, 36, 0, 0 }, + { 125, 64, 49, 0, 0 }, + { 126, 64, 46, 0, 0 }, + { 162, 64, 37, 0, 0 }, + { 163, 2, 49, 0, 0 }, + { 166, 64, 30, 0, 0 }, + { 167, 64, 34, 0, 0 }, + { 168, 0, 48, 0, 0 }, + { 172, 64, 35, 0, 0 }, + { 176, 64, 33, 0, 0 }, + { 180, 0, 44, 64, 45 }, + { 192, 2, 4, 2, 46 }, + { 193, 2, 4, 64, 45 }, + { 194, 2, 4, 0, 46 }, + { 200, 2, 8, 2, 46 }, + { 201, 2, 8, 64, 45 }, + { 202, 2, 8, 0, 46 }, + { 204, 2, 12, 2, 46 }, + { 205, 2, 12, 64, 45 }, + { 206, 2, 12, 0, 46 }, + { 210, 2, 18, 2, 46 }, + { 211, 2, 18, 64, 45 }, + { 212, 2, 18, 0, 46 }, + { 217, 2, 24, 2, 46 }, + { 218, 2, 24, 64, 45 }, + { 219, 2, 24, 0, 46 }, + { 221, 2, 29, 64, 45 }, + { 224, 0, 52, 0, 0 }, + { 225, 0, 4, 64, 45 }, + { 226, 0, 4, 0, 46 }, + { 228, 2, 52, 0, 0 }, + { 231, 2, 33, 0, 0 }, + { 232, 0, 47, 0, 0 }, + { 233, 0, 51, 0, 0 }, + { 234, 0, 8, 0, 46 }, + { 236, 0, 12, 2, 46 }, + { 237, 0, 12, 64, 45 }, + { 238, 0, 12, 0, 46 }, + { 242, 0, 18, 2, 46 }, + { 243, 0, 18, 64, 45 }, + { 244, 0, 18, 0, 46 }, + { 246, 2, 51, 0, 0 }, + { 249, 0, 24, 2, 46 }, + { 250, 0, 24, 64, 45 }, + { 251, 0, 24, 0, 46 }, + { 252, 2, 47, 0, 0 }, + { 253, 0, 29, 64, 45 }, + { 8364, 64, 8, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x002b , -1 , 0x00a6 , -1 } , + { 0 , (int)'2' , 0x0022 , -1 , 0x0040 , -1 } , + { 0 , (int)'3' , 0x002a , -1 , 0x0023 , -1 } , + { 0 , (int)'4' , 0x00e7 , -1 , 0x00b0 , -1 } , + { 0 , (int)'5' , 0x0025 , -1 , 0x00a7 , -1 } , + { 0 , (int)'6' , 0x0026 , -1 , 0x00ac , -1 } , + { 0 , (int)'7' , 0x002f , -1 , 0x007c , -1 } , + { 0 , (int)'8' , 0x008 , -1 , 0x00a2 , -1 } , + { 0 , (int)'9' , 0x0029 , -1 , -1 , -1 } , + { 0 , (int)'0' , 0x003d , -1 , -1 , -1 } , + { 0 , 0x0027 , 0x003f , -1 , 0x00b4 , -1 } , + { 0 , 0x005e , 0x0060 , -1 , 0x007e , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 0 , 0x00e8 , 0x00fc , 0x001b , 0x005b , -1 } , + { 0 , 0x00a8 , 0x0021 , 0x001d , 0x005d , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 0 , 0x00e9 , 0x00f6 , -1 , -1 , -1 } , + { 0 , 0x00e0 , 0x00e4 , -1 , 0x007b , -1 } , + { 0 , 0x00a7 , 0x00b0 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x0024 , 0x00a3 , 0x001c , 0x007d , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x003c , 0x003e , 0x001c , 0x005c , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x0060, 0x00b4, 0x005e + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + + }; + + private static SwissFrenchLayout instance = new SwissFrenchLayout(); + + private SwissFrenchLayout() { + } + + public static SwissFrenchLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SwissGermanLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SwissGermanLayout.java new file mode 100644 index 00000000..83d4db00 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/SwissGermanLayout.java @@ -0,0 +1,388 @@ +package com.inputstick.api.layout; + +public class SwissGermanLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "de-CH"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 48, 0, 0 }, + { 34, 2, 31, 0, 0 }, + { 35, 64, 32, 0, 0 }, + { 36, 0, 49, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 35, 0, 0 }, + { 39, 0, 45, 0, 0 }, + { 40, 2, 37, 0, 0 }, + { 41, 2, 38, 0, 0 }, + { 42, 2, 32, 0, 0 }, + { 43, 2, 30, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 56, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 2, 36, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 55, 0, 0 }, + { 59, 2, 54, 0, 0 }, + { 60, 0, 100, 0, 0 }, + { 61, 2, 39, 0, 0 }, + { 62, 2, 100, 0, 0 }, + { 63, 2, 45, 0, 0 }, + { 64, 64, 31, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 29, 0, 0 }, + { 90, 2, 28, 0, 0 }, + { 91, 64, 47, 0, 0 }, + { 92, 64, 100, 0, 0 }, + { 93, 64, 48, 0, 0 }, + { 94, 0, 44, 0, 46 }, + { 95, 2, 56, 0, 0 }, + { 96, 0, 44, 2, 46 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 29, 0, 0 }, + { 122, 0, 28, 0, 0 }, + { 123, 64, 52, 0, 0 }, + { 124, 64, 36, 0, 0 }, + { 125, 64, 49, 0, 0 }, + { 126, 0, 44, 64, 46 }, + { 162, 64, 37, 0, 0 }, + { 163, 2, 49, 0, 0 }, + { 166, 64, 30, 0, 0 }, + { 167, 64, 34, 0, 0 }, + { 168, 0, 44, 0, 48 }, + { 172, 64, 35, 0, 0 }, + { 176, 64, 33, 0, 0 }, + { 180, 0, 44, 64, 45 }, + { 192, 2, 4, 2, 46 }, + { 193, 2, 4, 64, 45 }, + { 194, 2, 4, 0, 46 }, + { 195, 2, 4, 64, 46 }, + { 196, 2, 4, 0, 48 }, + { 200, 2, 8, 2, 46 }, + { 201, 2, 8, 64, 45 }, + { 202, 2, 8, 0, 46 }, + { 203, 2, 8, 0, 48 }, + { 204, 2, 12, 2, 46 }, + { 205, 2, 12, 64, 45 }, + { 206, 2, 12, 0, 46 }, + { 207, 2, 12, 0, 48 }, + { 209, 2, 17, 64, 46 }, + { 210, 2, 18, 2, 46 }, + { 211, 2, 18, 64, 45 }, + { 212, 2, 18, 0, 46 }, + { 213, 2, 18, 64, 46 }, + { 214, 2, 18, 0, 48 }, + { 217, 2, 24, 2, 46 }, + { 218, 2, 24, 64, 45 }, + { 219, 2, 24, 0, 46 }, + { 220, 2, 24, 0, 48 }, + { 221, 2, 29, 64, 45 }, + { 224, 2, 52, 0, 0 }, + { 225, 0, 4, 64, 45 }, + { 226, 0, 4, 0, 46 }, + { 227, 0, 4, 64, 46 }, + { 228, 0, 52, 0, 0 }, + { 231, 2, 33, 0, 0 }, + { 232, 2, 47, 0, 0 }, + { 233, 2, 51, 0, 0 }, + { 234, 0, 8, 0, 46 }, + { 235, 0, 8, 0, 48 }, + { 236, 0, 12, 2, 46 }, + { 237, 0, 12, 64, 45 }, + { 238, 0, 12, 0, 46 }, + { 239, 0, 12, 0, 48 }, + { 241, 0, 17, 64, 46 }, + { 242, 0, 18, 2, 46 }, + { 243, 0, 18, 64, 45 }, + { 244, 0, 18, 0, 46 }, + { 245, 0, 18, 64, 46 }, + { 246, 0, 51, 0, 0 }, + { 249, 0, 24, 2, 46 }, + { 250, 0, 24, 64, 45 }, + { 251, 0, 24, 0, 46 }, + { 252, 0, 47, 0, 0 }, + { 253, 0, 29, 64, 45 }, + { 255, 0, 29, 0, 48 }, + { 8364, 64, 8, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x002b , -1 , 0x00a6 , -1 } , + { 0 , (int)'2' , 0x0022 , -1 , 0x0040 , -1 } , + { 0 , (int)'3' , 0x002a , -1 , 0x0023 , -1 } , + { 0 , (int)'4' , 0x00e7 , -1 , 0x00b0 , -1 } , + { 0 , (int)'5' , 0x0025 , -1 , 0x00a7 , -1 } , + { 0 , (int)'6' , 0x0026 , -1 , 0x00ac , -1 } , + { 0 , (int)'7' , 0x002f , -1 , 0x007c , -1 } , + { 0 , (int)'8' , 0x0028 , -1 , 0x00a2 , -1 } , + { 0 , (int)'9' , 0x0029 , -1 , -1 , -1 } , + { 0 , (int)'0' , 0x003d , -1 , -1 , -1 } , + { 0 , 0x0027 , 0x003f , -1 , 0x00b4 , -1 } , + { 0 , 0x005e , 0x0060 , -1 , 0x007e , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 1 , (int)'e' , (int)'E' , -1 , 0x20ac , -1 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 0 , 0x00fc , 0x00e8 , 0x001b , 0x005b , -1 } , + { 0 , 0x00a8 , 0x0021 , 0x001d , 0x005d , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 0 , 0x00f6 , 0x00e9 , -1 , -1 , -1 } , + { 0 , 0x00e4 , 0x00e0 , -1 , 0x007b , -1 } , + { 0 , 0x00a7 , 0x00b0 , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x0024 , 0x00a3 , 0x001c , 0x007d , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + { 0 , 0x002c , 0x003b , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003a , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x0020 , 0x0020 , 0x0020 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x003c , 0x003e , 0x001c , 0x005c , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = { + 0x00b4, 0x005e, 0x0060, 0x007e, 0x00a8 + }; + + public static final int DEADKEY_LUT[][] = { + { 0x00b4 , 0x0079 , 0x00fd } , + { 0x00b4 , 0x0061 , 0x00e1 } , + { 0x00b4 , 0x0065 , 0x00e9 } , + { 0x00b4 , 0x0075 , 0x00fa } , + { 0x00b4 , 0x0069 , 0x00ed } , + { 0x00b4 , 0x006f , 0x00f3 } , + { 0x00b4 , 0x0059 , 0x00dd } , + { 0x00b4 , 0x0041 , 0x00c1 } , + { 0x00b4 , 0x0045 , 0x00c9 } , + { 0x00b4 , 0x0055 , 0x00da } , + { 0x00b4 , 0x0049 , 0x00cd } , + { 0x00b4 , 0x004f , 0x00d3 } , + { 0x00b4 , 0x0020 , 0x00b4 } , + { 0x005e , 0x0061 , 0x00e2 } , + { 0x005e , 0x0065 , 0x00ea } , + { 0x005e , 0x0075 , 0x00fb } , + { 0x005e , 0x0069 , 0x00ee } , + { 0x005e , 0x006f , 0x00f4 } , + { 0x005e , 0x0041 , 0x00c2 } , + { 0x005e , 0x0045 , 0x00ca } , + { 0x005e , 0x0055 , 0x00db } , + { 0x005e , 0x0049 , 0x00ce } , + { 0x005e , 0x004f , 0x00d4 } , + { 0x005e , 0x0020 , 0x005e } , + { 0x0060 , 0x0061 , 0x00e0 } , + { 0x0060 , 0x0065 , 0x00e8 } , + { 0x0060 , 0x0075 , 0x00f9 } , + { 0x0060 , 0x0069 , 0x00ec } , + { 0x0060 , 0x006f , 0x00f2 } , + { 0x0060 , 0x0041 , 0x00c0 } , + { 0x0060 , 0x0045 , 0x00c8 } , + { 0x0060 , 0x0055 , 0x00d9 } , + { 0x0060 , 0x0049 , 0x00cc } , + { 0x0060 , 0x004f , 0x00d2 } , + { 0x0060 , 0x0020 , 0x0060 } , + { 0x007e , 0x006e , 0x00f1 } , + { 0x007e , 0x0061 , 0x00e3 } , + { 0x007e , 0x006f , 0x00f5 } , + { 0x007e , 0x004e , 0x00d1 } , + { 0x007e , 0x0041 , 0x00c3 } , + { 0x007e , 0x004f , 0x00d5 } , + { 0x007e , 0x0020 , 0x007e } , + { 0x00a8 , 0x0079 , 0x00ff } , + { 0x00a8 , 0x0061 , 0x00e4 } , + { 0x00a8 , 0x0065 , 0x00eb } , + { 0x00a8 , 0x0075 , 0x00fc } , + { 0x00a8 , 0x0069 , 0x00ef } , + { 0x00a8 , 0x006f , 0x00f6 } , + { 0x00a8 , 0x0041 , 0x00c4 } , + { 0x00a8 , 0x0045 , 0x00cb } , + { 0x00a8 , 0x0055 , 0x00dc } , + { 0x00a8 , 0x0049 , 0x00cf } , + { 0x00a8 , 0x004f , 0x00d6 } , + { 0x00a8 , 0x0020 , 0x00a8 } , + }; + + + + private static SwissGermanLayout instance = new SwissGermanLayout(); + + private SwissGermanLayout() { + } + + public static SwissGermanLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/UnitedKingdomLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/UnitedKingdomLayout.java new file mode 100644 index 00000000..95e842f0 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/UnitedKingdomLayout.java @@ -0,0 +1,283 @@ +package com.inputstick.api.layout; + +public class UnitedKingdomLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "en-GB"; + + + + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, + { 27, 1, 47, 0, 0 }, + { 28, 1, 49, 0, 0 }, + { 29, 1, 48, 0, 0 }, + { 32, 0, 44, 0, 0 }, + { 33, 2, 30, 0, 0 }, + { 34, 2, 31, 0, 0 }, + { 35, 0, 49, 0, 0 }, + { 36, 2, 33, 0, 0 }, + { 37, 2, 34, 0, 0 }, + { 38, 2, 36, 0, 0 }, + { 39, 0, 52, 0, 0 }, + { 40, 2, 38, 0, 0 }, + { 41, 2, 39, 0, 0 }, + { 42, 2, 37, 0, 0 }, + { 43, 2, 46, 0, 0 }, + { 44, 0, 54, 0, 0 }, + { 45, 0, 45, 0, 0 }, + { 46, 0, 55, 0, 0 }, + { 47, 0, 56, 0, 0 }, + { 48, 0, 39, 0, 0 }, + { 49, 0, 30, 0, 0 }, + { 50, 0, 31, 0, 0 }, + { 51, 0, 32, 0, 0 }, + { 52, 0, 33, 0, 0 }, + { 53, 0, 34, 0, 0 }, + { 54, 0, 35, 0, 0 }, + { 55, 0, 36, 0, 0 }, + { 56, 0, 37, 0, 0 }, + { 57, 0, 38, 0, 0 }, + { 58, 2, 51, 0, 0 }, + { 59, 0, 51, 0, 0 }, + { 60, 2, 54, 0, 0 }, + { 61, 0, 46, 0, 0 }, + { 62, 2, 55, 0, 0 }, + { 63, 2, 56, 0, 0 }, + { 64, 2, 52, 0, 0 }, + { 65, 2, 4, 0, 0 }, + { 66, 2, 5, 0, 0 }, + { 67, 2, 6, 0, 0 }, + { 68, 2, 7, 0, 0 }, + { 69, 2, 8, 0, 0 }, + { 70, 2, 9, 0, 0 }, + { 71, 2, 10, 0, 0 }, + { 72, 2, 11, 0, 0 }, + { 73, 2, 12, 0, 0 }, + { 74, 2, 13, 0, 0 }, + { 75, 2, 14, 0, 0 }, + { 76, 2, 15, 0, 0 }, + { 77, 2, 16, 0, 0 }, + { 78, 2, 17, 0, 0 }, + { 79, 2, 18, 0, 0 }, + { 80, 2, 19, 0, 0 }, + { 81, 2, 20, 0, 0 }, + { 82, 2, 21, 0, 0 }, + { 83, 2, 22, 0, 0 }, + { 84, 2, 23, 0, 0 }, + { 85, 2, 24, 0, 0 }, + { 86, 2, 25, 0, 0 }, + { 87, 2, 26, 0, 0 }, + { 88, 2, 27, 0, 0 }, + { 89, 2, 28, 0, 0 }, + { 90, 2, 29, 0, 0 }, + { 91, 0, 47, 0, 0 }, + { 92, 0, 100, 0, 0 }, + { 93, 0, 48, 0, 0 }, + { 94, 2, 35, 0, 0 }, + { 95, 2, 45, 0, 0 }, + { 96, 0, 53, 0, 0 }, + { 97, 0, 4, 0, 0 }, + { 98, 0, 5, 0, 0 }, + { 99, 0, 6, 0, 0 }, + { 100, 0, 7, 0, 0 }, + { 101, 0, 8, 0, 0 }, + { 102, 0, 9, 0, 0 }, + { 103, 0, 10, 0, 0 }, + { 104, 0, 11, 0, 0 }, + { 105, 0, 12, 0, 0 }, + { 106, 0, 13, 0, 0 }, + { 107, 0, 14, 0, 0 }, + { 108, 0, 15, 0, 0 }, + { 109, 0, 16, 0, 0 }, + { 110, 0, 17, 0, 0 }, + { 111, 0, 18, 0, 0 }, + { 112, 0, 19, 0, 0 }, + { 113, 0, 20, 0, 0 }, + { 114, 0, 21, 0, 0 }, + { 115, 0, 22, 0, 0 }, + { 116, 0, 23, 0, 0 }, + { 117, 0, 24, 0, 0 }, + { 118, 0, 25, 0, 0 }, + { 119, 0, 26, 0, 0 }, + { 120, 0, 27, 0, 0 }, + { 121, 0, 28, 0, 0 }, + { 122, 0, 29, 0, 0 }, + { 123, 2, 47, 0, 0 }, + { 124, 2, 100, 0, 0 }, + { 125, 2, 48, 0, 0 }, + { 126, 2, 49, 0, 0 }, + { 163, 2, 32, 0, 0 }, + { 166, 64, 53, 0, 0 }, + { 172, 2, 53, 0, 0 }, + { 193, 66, 4, 0, 0 }, + { 201, 66, 8, 0, 0 }, + { 205, 66, 12, 0, 0 }, + { 211, 66, 18, 0, 0 }, + { 218, 66, 24, 0, 0 }, + { 225, 64, 4, 0, 0 }, + { 233, 64, 8, 0, 0 }, + { 237, 64, 12, 0, 0 }, + { 243, 64, 18, 0, 0 }, + { 250, 64, 24, 0, 0 }, + { 8364, 64, 33, 0, 0 }, + }; + + public static final int LUT[][] = { + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + { 0 , (int)'2' , 0x22 , -1 , -1 , -1 } , + { 0 , (int)'3' , 0x00a3 , -1 , -1 , -1 } , + { 0 , (int)'4' , 0x24 , -1 , 0x20ac , -1 } , + { 0 , (int)'5' , 0x25 , -1 , -1 , -1 } , + { 0 , (int)'6' , 0x005e , -1 , -1 , -1 } , + { 0 , (int)'7' , 0x26 , -1 , -1 , -1 } , + { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + { 0 , (int)'9' , 0x28 , -1 , -1 , -1 } , + { 0 , (int)'0' , 0x29 , -1 , -1 , -1 } , + { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + { 0 , 0x003d , 0x002b , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + { 5 , (int)'e' , (int)'E' , -1 , 0x00e9 , 0x00c9 } , + { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + { 5 , (int)'u' , (int)'U' , -1 , 0x00fa , 0x00da } , + { 5 , (int)'i' , (int)'I' , -1 , 0x00ed , 0x00cd } , + { 5 , (int)'o' , (int)'O' , -1 , 0x00f3 , 0x00d3 } , + { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + { 0 , 0x005b , 0x007b , 0x001b , -1 , -1 } , + { 0 , 0x005d , 0x007d , 0x001d , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 5 , (int)'a' , (int)'A' , -1 , 0x00e1 , 0x00c1 } , + { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + { 0 , 0x003b , 0x003a , -1 , -1 , -1 } , + { 0 , 0x27 , 0x40 , -1 , -1 , -1 } , + { 0 , 0x60 , 0x00ac , -1 , 0x00a6 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x23 , 0x007e , 0x001c , -1 , -1 } , + { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + { 0 , 0x002c , 0x003c , -1 , -1 , -1 } , + { 0 , 0x002e , 0x003e , -1 , -1 , -1 } , + { 0 , 0x002f , 0x003f , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + { -1 , 0 , 0 , 0 , 0 , 0 } , + + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static UnitedKingdomLayout instance = new UnitedKingdomLayout(); + + private UnitedKingdomLayout() { + } + + public static UnitedKingdomLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/UnitedStatesLayout.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/UnitedStatesLayout.java new file mode 100644 index 00000000..62097466 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/api/layout/UnitedStatesLayout.java @@ -0,0 +1,268 @@ +package com.inputstick.api.layout; + +public class UnitedStatesLayout extends KeyboardLayout { + + public static final String LOCALE_NAME = "en-US"; + + //{char (16b unicode), modifier, key, deadkey_modifier, deadkey} + //en-US + private static final int[][] FAST_LUT = { + { 0, 0, 0, 0, 0 }, // empty + { 27, 1, 47, 0, 0 }, //  + { 28, 1, 49, 0, 0 }, //  + { 29, 1, 48, 0, 0 }, //  + { 32, 0, 44, 0, 0 }, // + { 33, 2, 30, 0, 0 }, // ! + { 34, 2, 52, 0, 0 }, // " + { 35, 2, 32, 0, 0 }, // # + { 36, 2, 33, 0, 0 }, // $ + { 37, 2, 34, 0, 0 }, // % + { 38, 2, 36, 0, 0 }, // & + { 39, 0, 52, 0, 0 }, // ' + { 40, 2, 38, 0, 0 }, // ( + { 41, 2, 39, 0, 0 }, // ) + { 42, 2, 37, 0, 0 }, // * + { 43, 2, 46, 0, 0 }, // + + { 44, 0, 54, 0, 0 }, // , + { 45, 0, 45, 0, 0 }, // - + { 46, 0, 55, 0, 0 }, // . + { 47, 0, 56, 0, 0 }, // / + { 48, 0, 39, 0, 0 }, // 0 + { 49, 0, 30, 0, 0 }, // 1 + { 50, 0, 31, 0, 0 }, // 2 + { 51, 0, 32, 0, 0 }, // 3 + { 52, 0, 33, 0, 0 }, // 4 + { 53, 0, 34, 0, 0 }, // 5 + { 54, 0, 35, 0, 0 }, // 6 + { 55, 0, 36, 0, 0 }, // 7 + { 56, 0, 37, 0, 0 }, // 8 + { 57, 0, 38, 0, 0 }, // 9 + { 58, 2, 51, 0, 0 }, // : + { 59, 0, 51, 0, 0 }, // ; + { 60, 2, 54, 0, 0 }, // < + { 61, 0, 46, 0, 0 }, // = + { 62, 2, 55, 0, 0 }, // > + { 63, 2, 56, 0, 0 }, // ? + { 64, 2, 31, 0, 0 }, // @ + { 65, 2, 4, 0, 0 }, // A + { 66, 2, 5, 0, 0 }, // B + { 67, 2, 6, 0, 0 }, // C + { 68, 2, 7, 0, 0 }, // D + { 69, 2, 8, 0, 0 }, // E + { 70, 2, 9, 0, 0 }, // F + { 71, 2, 10, 0, 0 }, // G + { 72, 2, 11, 0, 0 }, // H + { 73, 2, 12, 0, 0 }, // I + { 74, 2, 13, 0, 0 }, // J + { 75, 2, 14, 0, 0 }, // K + { 76, 2, 15, 0, 0 }, // L + { 77, 2, 16, 0, 0 }, // M + { 78, 2, 17, 0, 0 }, // N + { 79, 2, 18, 0, 0 }, // O + { 80, 2, 19, 0, 0 }, // P + { 81, 2, 20, 0, 0 }, // Q + { 82, 2, 21, 0, 0 }, // R + { 83, 2, 22, 0, 0 }, // S + { 84, 2, 23, 0, 0 }, // T + { 85, 2, 24, 0, 0 }, // U + { 86, 2, 25, 0, 0 }, // V + { 87, 2, 26, 0, 0 }, // W + { 88, 2, 27, 0, 0 }, // X + { 89, 2, 28, 0, 0 }, // Y + { 90, 2, 29, 0, 0 }, // Z + { 91, 0, 47, 0, 0 }, // [ + { 92, 0, 49, 0, 0 }, // \ + { 93, 0, 48, 0, 0 }, // ] + { 94, 2, 35, 0, 0 }, // ^ + { 95, 2, 45, 0, 0 }, // _ + { 96, 0, 53, 0, 0 }, // ` + { 97, 0, 4, 0, 0 }, // a + { 98, 0, 5, 0, 0 }, // b + { 99, 0, 6, 0, 0 }, // c + { 100, 0, 7, 0, 0 }, // d + { 101, 0, 8, 0, 0 }, // e + { 102, 0, 9, 0, 0 }, // f + { 103, 0, 10, 0, 0 }, // g + { 104, 0, 11, 0, 0 }, // h + { 105, 0, 12, 0, 0 }, // i + { 106, 0, 13, 0, 0 }, // j + { 107, 0, 14, 0, 0 }, // k + { 108, 0, 15, 0, 0 }, // l + { 109, 0, 16, 0, 0 }, // m + { 110, 0, 17, 0, 0 }, // n + { 111, 0, 18, 0, 0 }, // o + { 112, 0, 19, 0, 0 }, // p + { 113, 0, 20, 0, 0 }, // q + { 114, 0, 21, 0, 0 }, // r + { 115, 0, 22, 0, 0 }, // s + { 116, 0, 23, 0, 0 }, // t + { 117, 0, 24, 0, 0 }, // u + { 118, 0, 25, 0, 0 }, // v + { 119, 0, 26, 0, 0 }, // w + { 120, 0, 27, 0, 0 }, // x + { 121, 0, 28, 0, 0 }, // y + { 122, 0, 29, 0, 0 }, // z + { 123, 2, 47, 0, 0 }, // { + { 124, 2, 49, 0, 0 }, // | + { 125, 2, 48, 0, 0 }, // } + { 126, 2, 53, 0, 0 }, // ~ + }; + + public static final int LUT[][] = { + /* 0 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2 */ { 0 , (int)'1' , 0x21 , -1 , -1 , -1 } , + /* 3 */ { 0 , (int)'2' , 0x40 , -1 , -1 , -1 } , + /* 4 */ { 0 , (int)'3' , 0x23 , -1 , -1 , -1 } , + /* 5 */ { 0 , (int)'4' , 0x24 , -1 , -1 , -1 } , + /* 6 */ { 0 , (int)'5' , 0x25 , -1 , -1 , -1 } , + /* 7 */ { 0 , (int)'6' , 0x005e , -1 , -1 , -1 } , + /* 8 */ { 0 , (int)'7' , 0x26 , -1 , -1 , -1 } , + /* 9 */ { 0 , (int)'8' , 0x002a , -1 , -1 , -1 } , + /* 0a */ { 0 , (int)'9' , 0x28 , -1 , -1 , -1 } , + /* 0b */ { 0 , (int)'0' , 0x29 , -1 , -1 , -1 } , + /* 0c */ { 0 , 0x002d , 0x005f , -1 , -1 , -1 } , + /* 0d */ { 0 , 0x003d , 0x002b , -1 , -1 , -1 } , + /* 0e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 0f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 10 */ { 1 , (int)'q' , (int)'Q' , -1 , -1 , -1 } , + /* 11 */ { 1 , (int)'w' , (int)'W' , -1 , -1 , -1 } , + /* 12 */ { 1 , (int)'e' , (int)'E' , -1 , -1 , -1 } , + /* 13 */ { 1 , (int)'r' , (int)'R' , -1 , -1 , -1 } , + /* 14 */ { 1 , (int)'t' , (int)'T' , -1 , -1 , -1 } , + /* 15 */ { 1 , (int)'y' , (int)'Y' , -1 , -1 , -1 } , + /* 16 */ { 1 , (int)'u' , (int)'U' , -1 , -1 , -1 } , + /* 17 */ { 1 , (int)'i' , (int)'I' , -1 , -1 , -1 } , + /* 18 */ { 1 , (int)'o' , (int)'O' , -1 , -1 , -1 } , + /* 19 */ { 1 , (int)'p' , (int)'P' , -1 , -1 , -1 } , + /* 1a */ { 0 , 0x005b , 0x007b , 0x001b , -1 , -1 } , + /* 1b */ { 0 , 0x005d , 0x007d , 0x001d , -1 , -1 } , + /* 1c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 1e */ { 1 , (int)'a' , (int)'A' , -1 , -1 , -1 } , + /* 1f */ { 1 , (int)'s' , (int)'S' , -1 , -1 , -1 } , + + /* 20 */ { 1 , (int)'d' , (int)'D' , -1 , -1 , -1 } , + /* 21 */ { 1 , (int)'f' , (int)'F' , -1 , -1 , -1 } , + /* 22 */ { 1 , (int)'g' , (int)'G' , -1 , -1 , -1 } , + /* 23 */ { 1 , (int)'h' , (int)'H' , -1 , -1 , -1 } , + /* 24 */ { 1 , (int)'j' , (int)'J' , -1 , -1 , -1 } , + /* 25 */ { 1 , (int)'k' , (int)'K' , -1 , -1 , -1 } , + /* 26 */ { 1 , (int)'l' , (int)'L' , -1 , -1 , -1 } , + /* 27 */ { 0 , 0x003b , 0x003a , -1 , -1 , -1 } , + /* 28 */ { 0 , 0x27 , 0x22 , -1 , -1 , -1 } , + /* 29 */ { 0 , 0x60 , 0x007e , -1 , -1 , -1 } , + /* 2a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 2b */ { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + /* 2c */ { 1 , (int)'z' , (int)'Z' , -1 , -1 , -1 } , + /* 2d */ { 1 , (int)'x' , (int)'X' , -1 , -1 , -1 } , + /* 2e */ { 1 , (int)'c' , (int)'C' , -1 , -1 , -1 } , + /* 2f */ { 1 , (int)'v' , (int)'V' , -1 , -1 , -1 } , + + /* 30 */ { 1 , (int)'b' , (int)'B' , -1 , -1 , -1 } , + /* 31 */ { 1 , (int)'n' , (int)'N' , -1 , -1 , -1 } , + /* 32 */ { 1 , (int)'m' , (int)'M' , -1 , -1 , -1 } , + /* 33 */ { 0 , 0x002c , 0x003c , -1 , -1 , -1 } , + /* 34 */ { 0 , 0x002e , 0x003e , -1 , -1 , -1 } , + /* 35 */ { 0 , 0x002f , 0x003f , -1 , -1 , -1 } , + /* 36 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 37 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 38 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 39 */ { 0 , 0x20 , 0x20 , 0x20 , -1 , -1 } , + /* 3a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 3f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 40 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 41 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 42 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 43 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 44 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 45 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 46 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 47 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 48 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 49 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 4f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + /* 50 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 51 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 52 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 53 */ { 0 , 0x002e , 0x002e , -1 , -1 , -1 } , + /* 54 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 55 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 56 */ { 0 , 0x005c , 0x007c , 0x001c , -1 , -1 } , + /* 57 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 58 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 59 */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5a */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5b */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5c */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5d */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5e */ { -1 , 0 , 0 , 0 , 0 , 0 } , + /* 5f */ { -1 , 0 , 0 , 0 , 0 , 0 } , + + }; + + public static final int DEADKEYS[] = null; + public static final int DEADKEY_LUT[][] = null; + + private static UnitedStatesLayout instance = new UnitedStatesLayout(); + + private UnitedStatesLayout() { + } + + public static UnitedStatesLayout getInstance() { + return instance; + } + + @Override + public int[][] getLUT() { + return LUT; + } + + @Override + public int[][] getFastLUT() { + return FAST_LUT; + } + + @Override + public void type(String text) { + super.type(FAST_LUT, text, (byte)0); + } + + @Override + public void type(String text, byte modifiers) { + super.type(FAST_LUT, text, modifiers); + } + + @Override + public char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr) { + return super.getChar(LUT, scanCode, capsLock, shift, altGr); + } + + @Override + public String getLocaleName() { + return LOCALE_NAME; + } + + @Override + public int[][] getDeadkeyLUT() { + return DEADKEY_LUT; + } + + @Override + public int[] getDeadkeys() { + return DEADKEYS; + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/BasicInitManager.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/BasicInitManager.java new file mode 100644 index 00000000..9af6e902 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/BasicInitManager.java @@ -0,0 +1,78 @@ +package com.inputstick.init; + +import com.inputstick.api.Packet; + + +public class BasicInitManager extends InitManager { + + private static final int UPDATES_LIMIT = 50; + private static final int RETRY_LIMIT = 3; + + + private int lastStatusParam; + private int noInitUpdatesCnt; + private int noInitRetryCnt; + + public BasicInitManager(byte[] key) { + super(key); + lastStatusParam = 0; + } + + + @Override + public void onConnected() { + sendPacket(new Packet(true, Packet.CMD_RUN_FW)); + } + + @Override + public void onData(byte[] data) { + byte cmd = data[0]; + byte respCode = data[1]; + byte param = data[1]; + + switch (cmd) { + case Packet.CMD_RUN_FW: + sendPacket(new Packet(true, Packet.CMD_FW_INFO)); + break; + case Packet.CMD_FW_INFO: + onFWInfo(data, true, true, new Packet(true, Packet.CMD_INIT)); //TODO next FW: params! + break; + case Packet.CMD_INIT: + if (respCode == Packet.RESP_OK) { + initDone = true; + noInitUpdatesCnt = 0; + noInitRetryCnt = 0; + sendPacket(new Packet(true, Packet.CMD_HID_STATUS_REPORT)); + } else { + mListener.onInitFailure(respCode); + } + break; + case Packet.CMD_INIT_AUTH: + onAuth(data, true, new Packet(true, Packet.CMD_INIT)); //TODO next FW: params! + break; + case Packet.CMD_HID_STATUS: + if (initDone) { + if (param != lastStatusParam) { + lastStatusParam = param; + if (param == 0x05) { + mListener.onInitReady(); + } else { + mListener.onInitNotReady(); + } + } + } else { + noInitUpdatesCnt++; + if (noInitUpdatesCnt == UPDATES_LIMIT) { + noInitUpdatesCnt = 0; + if (noInitRetryCnt < RETRY_LIMIT) { + sendPacket(new Packet(true, Packet.CMD_RUN_FW)); + noInitRetryCnt++; + } + } + } + break; + } + } + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/BootloaderInitManager.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/BootloaderInitManager.java new file mode 100644 index 00000000..ea49b56d --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/BootloaderInitManager.java @@ -0,0 +1,28 @@ +package com.inputstick.init; + +import com.inputstick.api.Packet; + +public class BootloaderInitManager extends InitManager { + + public BootloaderInitManager(byte[] key) { + super(key); + } + + @Override + public void onConnected() { + //TODO key + sendPacket(new Packet(true, Packet.CMD_RUN_BL)); + } + + @Override + public void onData(byte[] data) { + byte cmd = data[0]; + //byte respCode = data[1]; + //byte param = data[1]; + + if (cmd == Packet.CMD_RUN_BL) { + mListener.onInitReady(); + } + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/DeviceInfo.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/DeviceInfo.java new file mode 100644 index 00000000..286bed75 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/DeviceInfo.java @@ -0,0 +1,89 @@ +package com.inputstick.init; + +public class DeviceInfo { + + private int firmwareType; + private int versionMajor; + private int versionMinor; + private int versionHardware; + private int securityStatus; + + private boolean passwordProtected; + + public DeviceInfo(byte[] data) { + //cmd, param + firmwareType = data[2]; + versionMajor = data[3]; + versionMinor = data[4]; + versionHardware = data[5]; + + + //6,7,8,9 + //10,11,12,13 + //14,15,16,17 + + //18,19 + securityStatus = data[19]; + if (data[20] == 0) { + passwordProtected = false; + } else { + passwordProtected = true; + } + } + + public int getSecurityStatus() { + return securityStatus; + } + + public boolean isAuthenticated() { + return ((securityStatus & 0x10) != 0); + } + + public boolean isUnlocked() { + if (getFirmwareVersion() < 96) { + return true; + } else { + return ((securityStatus & 0x08) != 0); + } + } + + public int getFirmwareType() { + return firmwareType; + } + + public boolean isPasswordProtected() { + return passwordProtected; + } + + public int getVersionMinor() { + return versionMinor; + } + + public int getVersionMajor() { + return versionMajor; + } + + public int getHardwareVersion() { + return versionHardware; + } + + public int getFirmwareVersion() { + return (versionMajor) * 100 + versionMinor; + } + + + + public boolean supportsEncryption() { + return (getFirmwareVersion() >= 91); + } + + public boolean supportsPinChange() { + return (getFirmwareVersion() >= 97); + } + + public boolean supportsGamepad() { + return (getFirmwareVersion() >= 97); + } + + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/InitManager.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/InitManager.java new file mode 100644 index 00000000..c3c62256 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/InitManager.java @@ -0,0 +1,107 @@ +package com.inputstick.init; + +import com.inputstick.api.InputStickError; +import com.inputstick.api.Packet; +import com.inputstick.api.PacketManager; + +public class InitManager { + + public static final int DEFAULT_INIT_TIMEOUT = 60000; //60s init timeout + + protected PacketManager mPacketManager; + protected InitManagerListener mListener; + protected byte[] mKey; + protected DeviceInfo mInfo; + protected boolean initDone; + + public InitManager(byte[] key) { + mKey = key; + } + + + public DeviceInfo getDeviceInfo() { + return mInfo; + } + + public boolean isEncrypted() { + return mPacketManager.isEncrypted(); + } + + + public void init(InitManagerListener listener, PacketManager packetManager) { + mListener = listener; + mPacketManager = packetManager; + + initDone = false; + } + + public void onConnected() { + mListener.onInitReady(); + } + + public void onData(byte[] data) { + //byte cmd = data[0]; + //byte param = data[1]; + } + + public void sendPacket(Packet p) { + mPacketManager.sendPacket(p); + } + + public void onFWInfo(byte[] data, boolean authenticate, boolean enableEncryption, Packet sendNext) { + mInfo = new DeviceInfo(data); + + if (authenticate) { + if (mInfo.isPasswordProtected()) { + if (mKey != null) { + //authenticate + sendPacket(mPacketManager.encPacket(enableEncryption)); + } else { + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NO_KEY); + } + } else { + if (mKey != null) { + //possible scenarios: FW upgrade / password removed using other device/app / tampering! + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_PROTECTED); + } + sendPacket(sendNext); + } + } else { + sendPacket(sendNext); + } + } + + public void onAuth(byte[] data, boolean enableOutEncryption, Packet sendNext) { + byte respCode = data[1]; + + switch (respCode) { + case Packet.RESP_OK: + byte[] cmp = new byte[16]; + //TODO check length! + System.arraycopy(data, 2, cmp, 0, 16); + if (mPacketManager.setEncryption(cmp, enableOutEncryption)) { + sendPacket(sendNext); + } else { + mListener.onInitFailure(InputStickError.ERROR_SECURITY_CHALLENGE); + } + break; + + case 0x20: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_INVALID_KEY); + break; + + case 0x21: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_PROTECTED); + break; + + case Packet.RESP_UNKNOWN_CMD: + mListener.onInitFailure(InputStickError.ERROR_SECURITY_NOT_SUPPORTED); + break; + + default: + mListener.onInitFailure(InputStickError.ERROR_SECURITY); + } + + } + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/InitManagerListener.java b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/InitManagerListener.java new file mode 100644 index 00000000..fee3c21a --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/java/com/inputstick/init/InitManagerListener.java @@ -0,0 +1,9 @@ +package com.inputstick.init; + +public interface InitManagerListener { + + public void onInitReady(); + public void onInitNotReady(); + public void onInitFailure(int code); + +} diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/drawable-hdpi/ic_launcher.png b/src/java/PluginInputStick3/inputStickAPI/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 00000000..96a442e5 Binary files /dev/null and b/src/java/PluginInputStick3/inputStickAPI/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/drawable-mdpi/ic_launcher.png b/src/java/PluginInputStick3/inputStickAPI/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 00000000..359047df Binary files /dev/null and b/src/java/PluginInputStick3/inputStickAPI/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/drawable-xhdpi/ic_launcher.png b/src/java/PluginInputStick3/inputStickAPI/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 00000000..71c6d760 Binary files /dev/null and b/src/java/PluginInputStick3/inputStickAPI/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/menu/install_utility.xml b/src/java/PluginInputStick3/inputStickAPI/src/main/res/menu/install_utility.xml new file mode 100644 index 00000000..c0020282 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/res/menu/install_utility.xml @@ -0,0 +1,9 @@ +

+ + + + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-sw600dp/dimens.xml b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-sw600dp/dimens.xml new file mode 100644 index 00000000..44f01db7 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-sw600dp/dimens.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-sw720dp-land/dimens.xml b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-sw720dp-land/dimens.xml new file mode 100644 index 00000000..61e3fa8f --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-sw720dp-land/dimens.xml @@ -0,0 +1,9 @@ + + + + 128dp + + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-v11/styles.xml b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-v11/styles.xml new file mode 100644 index 00000000..3c02242a --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-v11/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-v14/styles.xml b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-v14/styles.xml new file mode 100644 index 00000000..a91fd037 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values-v14/styles.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/values/dimens.xml b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values/dimens.xml new file mode 100644 index 00000000..55c1e590 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values/dimens.xml @@ -0,0 +1,7 @@ + + + + 16dp + 16dp + + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/values/strings.xml b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values/strings.xml new file mode 100644 index 00000000..fbe60928 --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values/strings.xml @@ -0,0 +1,9 @@ + + + + InputStickAPI + Download InputStickUtility + Settings + Hello world! + + diff --git a/src/java/PluginInputStick3/inputStickAPI/src/main/res/values/styles.xml b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values/styles.xml new file mode 100644 index 00000000..6ce89c7b --- /dev/null +++ b/src/java/PluginInputStick3/inputStickAPI/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/build.gradle b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/build.gradle new file mode 100644 index 00000000..87b86b32 --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/build.gradle @@ -0,0 +1,18 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 19 + buildToolsVersion "23.0.0" + + defaultConfig { + minSdkVersion 8 + targetSdkVersion 19 + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } +} diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/keepass2AndroidPluginSDK.iml b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/keepass2AndroidPluginSDK.iml new file mode 100644 index 00000000..53edcdbc --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/keepass2AndroidPluginSDK.iml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/lint.xml b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/lint.xml new file mode 100644 index 00000000..8423c0ef --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/lint.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/AndroidManifest.xml b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/AndroidManifest.xml new file mode 100644 index 00000000..91aef12e --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/AccessManager.java b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/AccessManager.java new file mode 100644 index 00000000..c8fe8d56 --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/AccessManager.java @@ -0,0 +1,201 @@ +package keepass2android.pluginsdk; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +import org.json.JSONArray; +import org.json.JSONException; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.preference.PreferenceManager; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.PopupMenu; + + +public class AccessManager +{ + + private static final String _tag = "Kp2aPluginSDK"; + private static final String PREF_KEY_SCOPE = "scope"; + private static final String PREF_KEY_TOKEN = "token"; + + public static String stringArrayToString(ArrayList values) { + JSONArray a = new JSONArray(); + for (int i = 0; i < values.size(); i++) { + a.put(values.get(i)); + } + if (!values.isEmpty()) { + return a.toString(); + } else { + return null; + } + + } + + public static ArrayList stringToStringArray(String s) { + ArrayList strings = new ArrayList(); + if (TextUtils.isEmpty(s) == false) { + try { + JSONArray a = new JSONArray(s); + for (int i = 0; i < a.length(); i++) { + String url = a.optString(i); + strings.add(url); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + return strings; + } + + public static void storeAccessToken(Context ctx, String hostPackage, String accessToken, ArrayList scopes) + { + SharedPreferences prefs = getPrefsForHost(ctx, hostPackage); + + Editor edit = prefs.edit(); + edit.putString(PREF_KEY_TOKEN, accessToken); + String scopesString = stringArrayToString(scopes); + edit.putString(PREF_KEY_SCOPE, scopesString); + edit.commit(); + Log.d(_tag, "stored access token " + accessToken.substring(0, 4)+"... for "+scopes.size()+" scopes ("+scopesString+")."); + + SharedPreferences hostPrefs = ctx.getSharedPreferences("KP2A.PluginAccess.hosts", Context.MODE_PRIVATE); + if (!hostPrefs.contains(hostPackage)) + { + hostPrefs.edit().putString(hostPackage, "").commit(); + } + + + } + + public static void preparePopup(Object popupMenu) + { + try + { + Field[] fields = popupMenu.getClass().getDeclaredFields(); + for (Field field : fields) { + if ("mPopup".equals(field.getName())) { + field.setAccessible(true); + Object menuPopupHelper = field.get(popupMenu); + Class classPopupHelper = Class.forName(menuPopupHelper + .getClass().getName()); + Method setForceIcons = classPopupHelper.getMethod( + "setForceShowIcon", boolean.class); + setForceIcons.invoke(menuPopupHelper, true); + break; + } + } + + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + private static SharedPreferences getPrefsForHost(Context ctx, + String hostPackage) { + SharedPreferences prefs = ctx.getSharedPreferences("KP2A.PluginAccess."+hostPackage, Context.MODE_PRIVATE); + return prefs; + } + + public static String tryGetAccessToken(Context ctx, String hostPackage, ArrayList scopes) { + + if (TextUtils.isEmpty(hostPackage)) + { + Log.d(_tag, "hostPackage is empty!"); + return null; + } + Log.d(_tag, "trying to find prefs for "+hostPackage); + SharedPreferences prefs = getPrefsForHost(ctx, hostPackage); + String scopesString = prefs.getString(PREF_KEY_SCOPE, ""); + Log.d(_tag, "available scopes: "+ scopesString); + ArrayList currentScope = stringToStringArray(scopesString); + if (isSubset(scopes, currentScope)) + { + return prefs.getString(PREF_KEY_TOKEN, null); + } + else + { + Log.d(_tag, "looks like scope changed. Access token invalid."); + return null; + } + } + + public static boolean isSubset(ArrayList requiredScopes, + ArrayList availableScopes) { + for (String r: requiredScopes){ + if (availableScopes.indexOf(r)<0) + { + Log.d(_tag, "Scope "+r+" not available. "+availableScopes.size()); + return false; + } + } + return true; + } + + public static void removeAccessToken(Context ctx, String hostPackage, + String accessToken) { + SharedPreferences prefs = getPrefsForHost(ctx, hostPackage); + + Log.d(_tag, "removing AccessToken."); + if (prefs.getString(PREF_KEY_TOKEN, "").equals(accessToken)) + { + Editor edit = prefs.edit(); + edit.clear(); + edit.commit(); + + } + + SharedPreferences hostPrefs = ctx.getSharedPreferences("KP2A.PluginAccess.hosts", Context.MODE_PRIVATE); + if (hostPrefs.contains(hostPackage)) + { + hostPrefs.edit().remove(hostPackage).commit(); + } + + } + + public static Set getAllHostPackages(Context ctx) + { + SharedPreferences prefs = ctx.getSharedPreferences("KP2A.PluginAccess.hosts", Context.MODE_PRIVATE); + Set result = new HashSet(); + for (String host: prefs.getAll().keySet()) + { + try + { + PackageInfo info = ctx.getPackageManager().getPackageInfo(host, PackageManager.GET_META_DATA); + //if we get here, the package is still there + result.add(host); + } + catch (PackageManager.NameNotFoundException e) + { + //host gone. ignore. + } + } + return result; + + } + + + + /** + * Returns a valid access token or throws PluginAccessException + */ + public static String getAccessToken(Context context, String hostPackage, + ArrayList scopes) throws PluginAccessException { + String accessToken = tryGetAccessToken(context, hostPackage, scopes); + if (accessToken == null) + throw new PluginAccessException(hostPackage, scopes); + return accessToken; + } +} diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/KeepassDefs.java b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/KeepassDefs.java new file mode 100644 index 00000000..7dd2e706 --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/KeepassDefs.java @@ -0,0 +1,48 @@ +package keepass2android.pluginsdk; + +public class KeepassDefs { + + /// + /// Default identifier string for the title field. Should not contain + /// spaces, tabs or other whitespace. + /// + public static String TitleField = "Title"; + + /// + /// Default identifier string for the user name field. Should not contain + /// spaces, tabs or other whitespace. + /// + public static String UserNameField = "UserName"; + + /// + /// Default identifier string for the password field. Should not contain + /// spaces, tabs or other whitespace. + /// + public static String PasswordField = "Password"; + + /// + /// Default identifier string for the URL field. Should not contain + /// spaces, tabs or other whitespace. + /// + public static String UrlField = "URL"; + + /// + /// Default identifier string for the notes field. Should not contain + /// spaces, tabs or other whitespace. + /// + public static String NotesField = "Notes"; + + + public static boolean IsStandardField(String strFieldName) + { + if(strFieldName == null) + return false; + if(strFieldName.equals(TitleField)) return true; + if(strFieldName.equals(UserNameField)) return true; + if(strFieldName.equals(PasswordField)) return true; + if(strFieldName.equals(UrlField)) return true; + if(strFieldName.equals(NotesField)) return true; + + return false; + } +} diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/Kp2aControl.java b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/Kp2aControl.java new file mode 100644 index 00000000..84bfc4e4 --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/Kp2aControl.java @@ -0,0 +1,111 @@ +package keepass2android.pluginsdk; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.content.Intent; +import android.text.TextUtils; + +public class Kp2aControl { + + /** + * Creates and returns an intent to launch Keepass2Android for adding an entry with the given fields. + * @param fields Key/Value pairs of the field values. See KeepassDefs for standard keys. + * @param protectedFields List of keys of the protected fields. + * @return Intent to start Keepass2Android. + * @throws JSONException + */ + public static Intent getAddEntryIntent(HashMap fields, ArrayList protectedFields) + { + return getAddEntryIntent(new JSONObject(fields).toString(), protectedFields); + } + + public static Intent getAddEntryIntent(String outputData, ArrayList protectedFields) + { + Intent startKp2aIntent = new Intent(Strings.ACTION_START_WITH_TASK); + startKp2aIntent.addCategory(Intent.CATEGORY_DEFAULT); + startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startKp2aIntent.putExtra("KP2A_APPTASK", "CreateEntryThenCloseTask"); + startKp2aIntent.putExtra("ShowUserNotifications", "false"); //KP2A expects a StringExtra + startKp2aIntent.putExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA, outputData); + if (protectedFields != null) + startKp2aIntent.putStringArrayListExtra(Strings.EXTRA_PROTECTED_FIELDS_LIST, protectedFields); + + + return startKp2aIntent; + } + + + /** + * Creates an intent to open a Password Entry matching searchText + * @param searchText queryString + * @param showUserNotifications if true, the notifications (copy to clipboard, keyboard) are displayed + * @param closeAfterOpen if true, the entry is opened and KP2A is immediately closed + * @return Intent to start KP2A with + */ + public static Intent getOpenEntryIntent(String searchText, boolean showUserNotifications, boolean closeAfterOpen) + { + Intent startKp2aIntent = new Intent(Strings.ACTION_START_WITH_TASK); + startKp2aIntent.addCategory(Intent.CATEGORY_DEFAULT); + startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startKp2aIntent.putExtra("KP2A_APPTASK", "SearchUrlTask"); + startKp2aIntent.putExtra("ShowUserNotifications", String.valueOf(showUserNotifications)); + startKp2aIntent.putExtra("CloseAfterCreate", String.valueOf(closeAfterOpen)); + startKp2aIntent.putExtra("UrlToSearch", searchText); + return startKp2aIntent; + } + + /** + * Creates an intent to query a password entry from KP2A. The credentials are returned as Activity result. + * @param searchText Text to search for. Should be a URL or "androidapp://com.my.package." + * @return an Intent to start KP2A with + */ + public static Intent getQueryEntryIntent(String searchText) + { + Intent i = new Intent(Strings.ACTION_QUERY_CREDENTIALS); + if (!TextUtils.isEmpty(searchText)) + i.putExtra(Strings.EXTRA_QUERY_STRING, searchText); + return i; + } + + /** + * Creates an intent to query a password entry from KP2A, matching to the current app's package . + * The credentials are returned as Activity result. + * This requires SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE. + * @return an Intent to start KP2A with + */ + public static Intent getQueryEntryIntentForOwnPackage() + { + return new Intent(Strings.ACTION_QUERY_CREDENTIALS_FOR_OWN_PACKAGE); + } + + /** + * Converts the entry fields returned in an intent from a query to a hashmap. + * @param intent data received in onActivityResult after getQueryEntryIntent(ForOwnPackage) + * @return HashMap with keys = field names (see KeepassDefs for standard keys) and values = values + */ + public static HashMap getEntryFieldsFromIntent(Intent intent) + { + HashMap res = new HashMap(); + try { + JSONObject json = new JSONObject(intent.getStringExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA)); + for(Iterator iter = json.keys();iter.hasNext();) { + String key = iter.next(); + String value = json.get(key).toString(); + res.put(key, value); + } + + } catch (JSONException e) { + e.printStackTrace(); + } catch (NullPointerException e) { + e.printStackTrace(); + } + return res; + } + +} diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/PluginAccessBroadcastReceiver.java b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/PluginAccessBroadcastReceiver.java new file mode 100644 index 00000000..3f3d6f13 --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/PluginAccessBroadcastReceiver.java @@ -0,0 +1,101 @@ +package keepass2android.pluginsdk; + +import java.util.ArrayList; + +import android.R.anim; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +/** + * Broadcast flow between Host and Plugin + * ====================================== + * + * The host is responsible for deciding when to initiate the session. It + * should initiate the session as soon as plugins are required or when a plugin + * has been updated through the OS. + * It will then send a broadcast to request the currently required scope. + * The plugin then sends a broadcast to the app which scope is required. If an + * access token is already available, it's sent along with the requset. + * + * If a previous permission has been revoked (or the app settings cleared or the + * permissions have been extended or the token is invalid for any other reason) + * the host will answer with a Revoked-Permission broadcast (i.e. the plugin is + * unconnected.) + * + * Unconnected plugins must be permitted by the user (requiring user action). + * When the user grants access, the plugin will receive an access token for + * the host. This access token is valid for the requested scope. If the scope + * changes (e.g after an update of the plugin), the access token becomes invalid. + * + */ +public abstract class PluginAccessBroadcastReceiver extends BroadcastReceiver { + + private static final String _tag = "Kp2aPluginSDK"; + + @Override + public void onReceive(Context ctx, Intent intent) { + String action = intent.getAction(); + android.util.Log.d(_tag, "received broadcast with action="+action); + if (action == null) + return; + if (action.equals(Strings.ACTION_TRIGGER_REQUEST_ACCESS)) + { + requestAccess(ctx, intent); + } else if (action.equals(Strings.ACTION_RECEIVE_ACCESS)) + { + receiveAccess(ctx, intent); + } else if (action.equals(Strings.ACTION_REVOKE_ACCESS)) + { + revokeAccess(ctx, intent); + } else + { + //TODO handle unexpected action + } + } + + + + private void revokeAccess(Context ctx, Intent intent) { + String senderPackage = intent.getStringExtra(Strings.EXTRA_SENDER); + String accessToken = intent.getStringExtra(Strings.EXTRA_ACCESS_TOKEN); + //this intent must send the invalid(ated) token to prevent malicious apps + //from revoking access of all plugins. + AccessManager.removeAccessToken(ctx, senderPackage, accessToken); + } + + + + private void receiveAccess(Context ctx, Intent intent) { + String senderPackage = intent.getStringExtra(Strings.EXTRA_SENDER); + String accessToken = intent.getStringExtra(Strings.EXTRA_ACCESS_TOKEN); + AccessManager.storeAccessToken(ctx, senderPackage, accessToken, getScopes()); + } + + public void requestAccess(Context ctx, Intent intent) { + String senderPackage = intent.getStringExtra(Strings.EXTRA_SENDER); + String requestToken = intent.getStringExtra(Strings.EXTRA_REQUEST_TOKEN); + Intent rpi = new Intent(Strings.ACTION_REQUEST_ACCESS); + rpi.setPackage(senderPackage); + rpi.putExtra(Strings.EXTRA_SENDER, ctx.getPackageName()); + rpi.putExtra(Strings.EXTRA_REQUEST_TOKEN, requestToken); + + String token = AccessManager.tryGetAccessToken(ctx, senderPackage, getScopes()); + if (token != null) + { + rpi.putExtra(Strings.EXTRA_ACCESS_TOKEN, token); + } + + rpi.putStringArrayListExtra(Strings.EXTRA_SCOPES, getScopes()); + Log.d(_tag, "requesting access for "+getScopes().size()+" tokens."); + ctx.sendBroadcast(rpi); + } + + /** + * + * @return the list of required scopes for this plugin. + */ + abstract public ArrayList getScopes(); + +} diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/PluginAccessException.java b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/PluginAccessException.java new file mode 100644 index 00000000..5f2a73ad --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/PluginAccessException.java @@ -0,0 +1,21 @@ +package keepass2android.pluginsdk; + +import java.util.ArrayList; + +public class PluginAccessException extends Exception { + + public PluginAccessException(String what) + { + super(what); + } + + public PluginAccessException(String hostPackage, ArrayList scopes) { + + } + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/PluginActionBroadcastReceiver.java b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/PluginActionBroadcastReceiver.java new file mode 100644 index 00000000..3d924ad8 --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/PluginActionBroadcastReceiver.java @@ -0,0 +1,303 @@ +package keepass2android.pluginsdk; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import org.json.JSONException; +import org.json.JSONObject; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +public abstract class PluginActionBroadcastReceiver extends BroadcastReceiver { + + protected abstract class PluginActionBase + { + protected Context _context; + protected Intent _intent; + + + public PluginActionBase(Context context, Intent intent) + { + _context = context; + _intent = intent; + } + + public String getHostPackage() { + return _intent.getStringExtra(Strings.EXTRA_SENDER); + } + + public Context getContext() + { + return _context; + } + + } + + protected abstract class PluginEntryActionBase extends PluginActionBase + { + + public PluginEntryActionBase(Context context, Intent intent) + { + super(context, intent); + } + + protected HashMap getEntryFieldsFromIntent() + { + HashMap res = new HashMap(); + try { + JSONObject json = new JSONObject(_intent.getStringExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA)); + for(Iterator iter = json.keys();iter.hasNext();) { + String key = iter.next(); + String value = json.get(key).toString(); + Log.d("KP2APluginSDK", "received " + key+"/"+value); + res.put(key, value); + } + + } catch (JSONException e) { + e.printStackTrace(); + } + return res; + } + + protected String[] getProtectedFieldsListFromIntent() + { + return _intent.getStringArrayExtra(Strings.EXTRA_PROTECTED_FIELDS_LIST); + } + + + public String getEntryId() + { + return _intent.getStringExtra(Strings.EXTRA_ENTRY_ID); + } + + + public void setEntryField(String fieldId, String fieldValue, boolean isProtected) throws PluginAccessException + { + Intent i = new Intent(Strings.ACTION_SET_ENTRY_FIELD); + ArrayList scope = new ArrayList(); + scope.add(Strings.SCOPE_CURRENT_ENTRY); + i.putExtra(Strings.EXTRA_ACCESS_TOKEN, AccessManager.getAccessToken(_context, getHostPackage(), scope)); + i.setPackage(getHostPackage()); + i.putExtra(Strings.EXTRA_SENDER, _context.getPackageName()); + i.putExtra(Strings.EXTRA_FIELD_VALUE, fieldValue); + i.putExtra(Strings.EXTRA_ENTRY_ID, getEntryId()); + i.putExtra(Strings.EXTRA_FIELD_ID, fieldId); + i.putExtra(Strings.EXTRA_FIELD_PROTECTED, isProtected); + + _context.sendBroadcast(i); + } + + } + + protected class ActionSelectedAction extends PluginEntryActionBase + { + public ActionSelectedAction(Context ctx, Intent intent) { + super(ctx, intent); + + } + + + + + /** + * + * @return the Bundle associated with the action. This bundle can be set in OpenEntry.add(Entry)FieldAction + */ + public Bundle getActionData() + { + return _intent.getBundleExtra(Strings.EXTRA_ACTION_DATA); + } + + /** + * + * @return the field id which was selected. null if an entry action (in the options menu) was selected. + */ + public String getFieldId() + { + return _intent.getStringExtra(Strings.EXTRA_FIELD_ID); + } + + /** + * + * @return true if an entry action, i.e. an option from the options menu, was selected. False if an option + * in a popup menu for a certain field was selected. + */ + public boolean isEntryAction() + { + return getFieldId() == null; + } + + /** + * + * @return a hashmap containing the entry fields in key/value form + */ + public HashMap getEntryFields() + { + return getEntryFieldsFromIntent(); + } + + /** + * + * @return an array with the keys of all protected fields in the entry + */ + public String[] getProtectedFieldsList() + { + return getProtectedFieldsListFromIntent(); + } + } + + protected class CloseEntryViewAction extends PluginEntryActionBase + { + public CloseEntryViewAction(Context context, Intent intent) { + super(context, intent); + } + + public String getEntryId() + { + return _intent.getStringExtra(Strings.EXTRA_ENTRY_ID); + } + } + + protected class OpenEntryAction extends PluginEntryActionBase + { + + public OpenEntryAction(Context context, Intent intent) + { + super(context, intent); + } + + + public HashMap getEntryFields() + { + return getEntryFieldsFromIntent(); + } + + /** + * + * @return an array with the keys of all protected fields in the entry + */ + public String[] getProtectedFieldsList() + { + return getProtectedFieldsListFromIntent(); + } + + public void addEntryAction(String actionDisplayText, int actionIconResourceId, Bundle actionData) throws PluginAccessException + { + addEntryFieldAction(null, null, actionDisplayText, actionIconResourceId, actionData); + } + + public void addEntryFieldAction(String actionId, String fieldId, String actionDisplayText, int actionIconResourceId, Bundle actionData) throws PluginAccessException + { + Intent i = new Intent(Strings.ACTION_ADD_ENTRY_ACTION); + ArrayList scope = new ArrayList(); + scope.add(Strings.SCOPE_CURRENT_ENTRY); + i.putExtra(Strings.EXTRA_ACCESS_TOKEN, AccessManager.getAccessToken(_context, getHostPackage(), scope)); + i.setPackage(getHostPackage()); + i.putExtra(Strings.EXTRA_SENDER, _context.getPackageName()); + i.putExtra(Strings.EXTRA_ACTION_DATA, actionData); + i.putExtra(Strings.EXTRA_ACTION_DISPLAY_TEXT, actionDisplayText); + i.putExtra(Strings.EXTRA_ACTION_ICON_RES_ID, actionIconResourceId); + i.putExtra(Strings.EXTRA_ENTRY_ID, getEntryId()); + i.putExtra(Strings.EXTRA_FIELD_ID, fieldId); + i.putExtra(Strings.EXTRA_ACTION_ID, actionId); + + _context.sendBroadcast(i); + } + + + + + } + + protected class DatabaseAction extends PluginActionBase + { + + public DatabaseAction(Context context, Intent intent) { + super(context, intent); + } + + public String getFileDisplayName() + { + return _intent.getStringExtra(Strings.EXTRA_DATABASE_FILE_DISPLAYNAME); + } + + public String getFilePath() + { + return _intent.getStringExtra(Strings.EXTRA_DATABASE_FILEPATH); + } + + public String getAction() + { + return _intent.getAction(); + } + + } + //EntryOutputModified is very similar to OpenEntry because it receives the same + //data (+ the field id which was modified) + protected class EntryOutputModifiedAction extends OpenEntryAction + { + + public EntryOutputModifiedAction(Context context, Intent intent) + { + super(context, intent); + } + + public String getModifiedFieldId() + { + return _intent.getStringExtra(Strings.EXTRA_FIELD_ID); + } + } + + @Override + public void onReceive(Context ctx, Intent intent) { + String action = intent.getAction(); + android.util.Log.d("KP2A.pluginsdk", "received broadcast in PluginActionBroadcastReceiver with action="+action); + if (action == null) + return; + if (action.equals(Strings.ACTION_OPEN_ENTRY)) + { + openEntry(new OpenEntryAction(ctx, intent)); + } + else if (action.equals(Strings.ACTION_CLOSE_ENTRY_VIEW)) + { + closeEntryView(new CloseEntryViewAction(ctx, intent)); + } + else if (action.equals(Strings.ACTION_ENTRY_ACTION_SELECTED)) + { + actionSelected(new ActionSelectedAction(ctx, intent)); + } + else if (action.equals(Strings.ACTION_ENTRY_OUTPUT_MODIFIED)) + { + entryOutputModified(new EntryOutputModifiedAction(ctx, intent)); + } + else if (action.equals(Strings.ACTION_LOCK_DATABASE) + || action.equals(Strings.ACTION_UNLOCK_DATABASE) + || action.equals(Strings.ACTION_OPEN_DATABASE) + || action.equals(Strings.ACTION_CLOSE_DATABASE)) + { + dbAction(new DatabaseAction(ctx, intent)); + } + else + { + //TODO handle unexpected action + } + + + } + + protected void closeEntryView(CloseEntryViewAction closeEntryView) {} + + protected void actionSelected(ActionSelectedAction actionSelected) {} + + protected void openEntry(OpenEntryAction oe) {} + + protected void entryOutputModified(EntryOutputModifiedAction eom) {} + + protected void dbAction(DatabaseAction db) {} + +} diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/Strings.java b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/Strings.java new file mode 100644 index 00000000..779eb01b --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/java/keepass2android/pluginsdk/Strings.java @@ -0,0 +1,190 @@ +package keepass2android.pluginsdk; + +public class Strings { + /** + * Plugin is notified about actions like open/close/update a database. + */ + public static final String SCOPE_DATABASE_ACTIONS = "keepass2android.SCOPE_DATABASE_ACTIONS"; + /** + * Plugin is notified when an entry is opened. + */ + public static final String SCOPE_CURRENT_ENTRY = "keepass2android.SCOPE_CURRENT_ENTRY"; + + /** + * Plugin may query credentials for its own package + */ + public static final String SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE = "keepass2android.SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE"; + + /** + * Plugin may query credentials for a deliberate package + */ + public static final String SCOPE_QUERY_CREDENTIALS = "keepass2android.SCOPE_QUERY_CREDENTIALS"; + + /** + * Extra key to transfer a (json serialized) list of scopes + */ + public static final String EXTRA_SCOPES = "keepass2android.EXTRA_SCOPES"; + + + public static final String EXTRA_PLUGIN_PACKAGE = "keepass2android.EXTRA_PLUGIN_PACKAGE"; + + /** + * Extra key for sending the package name of the sender of a broadcast. + * Should be set in every broadcast. + */ + public static final String EXTRA_SENDER = "keepass2android.EXTRA_SENDER"; + + /** + * Extra key for sending a request token. The request token is passed from + * KP2A to the plugin. It's used in the authorization process. + */ + public static final String EXTRA_REQUEST_TOKEN = "keepass2android.EXTRA_REQUEST_TOKEN"; + + /** + * Action to start KP2A with an AppTask + */ + public static final String ACTION_START_WITH_TASK = "keepass2android.ACTION_START_WITH_TASK"; + + /** + * Action sent from KP2A to the plugin to indicate that the plugin should request + * access (sending it's scopes) + */ + public static final String ACTION_TRIGGER_REQUEST_ACCESS = "keepass2android.ACTION_TRIGGER_REQUEST_ACCESS"; + /** + * Action sent from the plugin to KP2A including the scopes. + */ + public static final String ACTION_REQUEST_ACCESS = "keepass2android.ACTION_REQUEST_ACCESS"; + /** + * Action sent from the KP2A to the plugin when the user grants access. + * Will contain an access token. + */ + public static final String ACTION_RECEIVE_ACCESS = "keepass2android.ACTION_RECEIVE_ACCESS"; + /** + * Action sent from KP2A to the plugin to indicate that access is not or no longer valid. + */ + public static final String ACTION_REVOKE_ACCESS = "keepass2android.ACTION_REVOKE_ACCESS"; + + + /** + * Action for startActivity(). Opens an activity in the Plugin Host to edit the plugin settings (i.e. enable it) + */ + public static final String ACTION_EDIT_PLUGIN_SETTINGS = "keepass2android.ACTION_EDIT_PLUGIN_SETTINGS"; + + /** + * Action sent from KP2A to the plugin to indicate that an entry was opened. + * The Intent contains the full entry data. + */ + public static final String ACTION_OPEN_ENTRY= "keepass2android.ACTION_OPEN_ENTRY"; + + /** + * Action sent from KP2A to the plugin to indicate that an entry output field was modified/added. + * The Intent contains the full new entry data. + */ + public static final String ACTION_ENTRY_OUTPUT_MODIFIED= "keepass2android.ACTION_ENTRY_OUTPUT_MODIFIED"; + + /** + * Action sent from KP2A to the plugin to indicate that an entry activity was closed. + */ + public static final String ACTION_CLOSE_ENTRY_VIEW= "keepass2android.ACTION_CLOSE_ENTRY_VIEW"; + + /** + * Extra key for a string containing the GUID of the entry. + */ + public static final String EXTRA_ENTRY_ID= "keepass2android.EXTRA_ENTRY_DATA"; + + /** + * Json serialized data of the PwEntry (C# class) representing the opened entry. + * currently not implemented. + */ + //public static final String EXTRA_ENTRY_DATA = "keepass2android.EXTRA_ENTRY_DATA"; + + /** + * Json serialized list of fields, transformed using the database context (i.e. placeholders are replaced already) + */ + public static final String EXTRA_ENTRY_OUTPUT_DATA = "keepass2android.EXTRA_ENTRY_OUTPUT_DATA"; + + /** + * Json serialized lisf of field keys, specifying which field of the EXTRA_ENTRY_OUTPUT_DATA is protected. + */ + public static final String EXTRA_PROTECTED_FIELDS_LIST = "keepass2android.EXTRA_PROTECTED_FIELDS_LIST"; + + + /** + * Extra key for passing the access token (both ways) + */ + public static final String EXTRA_ACCESS_TOKEN = "keepass2android.EXTRA_ACCESS_TOKEN"; + + /** + * Action for an intent from the plugin to KP2A to add menu options regarding the currently open entry. + * Requires SCOPE_CURRENT_ENTRY. + */ + public static final String ACTION_ADD_ENTRY_ACTION = "keepass2android.ACTION_ADD_ENTRY_ACTION"; + + public static final String EXTRA_ACTION_DISPLAY_TEXT = "keepass2android.EXTRA_ACTION_DISPLAY_TEXT"; + public static final String EXTRA_ACTION_ICON_RES_ID = "keepass2android.EXTRA_ACTION_ICON_RES_ID"; + + public static final String EXTRA_FIELD_ID = "keepass2android.EXTRA_FIELD_ID"; + + /** + * Used to pass an id for the action. Each actionId may occur only once per field, otherwise the previous + * action with same id is replaced by the new action. + */ + public static final String EXTRA_ACTION_ID = "keepass2android.EXTRA_ACTION_ID"; + + /** Extra for ACTION_ADD_ENTRY_ACTION and ACTION_ENTRY_ACTION_SELECTED to pass data specifying the action parameters.*/ + public static final String EXTRA_ACTION_DATA = "keepass2android.EXTRA_ACTION_DATA"; + + /** + * Action for an intent from KP2A to the plugin when an action added with ACTION_ADD_ENTRY_ACTION was selected by the user. + * + */ + public static final String ACTION_ENTRY_ACTION_SELECTED = "keepass2android.ACTION_ENTRY_ACTION_SELECTED"; + + /** + * Extra key for the string which is used to query the credentials. This should be either a URL for + * a web login (google.com or a full URI) or something in the form "androidapp://com.my.package" + */ + public static final String EXTRA_QUERY_STRING = "keepass2android.EXTRA_QUERY_STRING"; + + /** + * Action when plugin wants to query credentials for its own package + */ + public static final String ACTION_QUERY_CREDENTIALS_FOR_OWN_PACKAGE = "keepass2android.ACTION_QUERY_CREDENTIALS_FOR_OWN_PACKAGE"; + + + /** + * Action when plugin wants to query credentials for a deliberate package + * The query string is passed as intent data + */ + public static final String ACTION_QUERY_CREDENTIALS = "keepass2android.ACTION_QUERY_CREDENTIALS"; + + /** + * Action for an intent from the plugin to KP2A to set (i.e. add or update) a field in the entry. + * May be used to update existing or add new fields at any time while the entry is opened. + */ + public static final String ACTION_SET_ENTRY_FIELD = "keepass2android.ACTION_SET_ENTRY_FIELD"; + + /** Actions for an intent from KP2A to the plugin to inform that a database was opened, closed, quicklocked or quickunlocked.*/ + public static final String ACTION_OPEN_DATABASE = "keepass2android.ACTION_OPEN_DATABASE"; + public static final String ACTION_CLOSE_DATABASE = "keepass2android.ACTION_CLOSE_DATABASE"; + public static final String ACTION_LOCK_DATABASE = "keepass2android.ACTION_LOCK_DATABASE"; + public static final String ACTION_UNLOCK_DATABASE = "keepass2android.ACTION_UNLOCK_DATABASE"; + + /** Extra for ACTION_OPEN_DATABASE and ACTION_CLOSE_DATABASE containing a filepath which is used + * by KP2A internally to identify the file. Use only where necessary, might contain credentials + * for accessing the file (on remote storage).*/ + public static final String EXTRA_DATABASE_FILEPATH = "keepass2android.EXTRA_DATABASE_FILEPATH"; + /** Extra for ACTION_OPEN_DATABASE and ACTION_CLOSE_DATABASE containing a filepath which can be + * displayed to the user.*/ + public static final String EXTRA_DATABASE_FILE_DISPLAYNAME = "keepass2android.EXTRA_DATABASE_FILE_DISPLAYNAME"; + + + public static final String EXTRA_FIELD_VALUE = "keepass2android.EXTRA_FIELD_VALUE"; + public static final String EXTRA_FIELD_PROTECTED = "keepass2android.EXTRA_FIELD_PROTECTED"; + + public static final String PREFIX_STRING = "STRING_"; + public static final String PREFIX_BINARY = "BINARY_"; + + + +} diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/drawable-hdpi/ic_launcher.png b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 00000000..96a442e5 Binary files /dev/null and b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/drawable-mdpi/ic_launcher.png b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 00000000..359047df Binary files /dev/null and b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/drawable-xhdpi/ic_launcher.png b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 00000000..71c6d760 Binary files /dev/null and b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values-v11/styles.xml b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values-v11/styles.xml new file mode 100644 index 00000000..3c02242a --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values-v11/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values-v14/styles.xml b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values-v14/styles.xml new file mode 100644 index 00000000..a91fd037 --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values-v14/styles.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/src/java/PluginInputStick/res/values-w820dp/dimens.xml b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values-w820dp/dimens.xml similarity index 100% rename from src/java/PluginInputStick/res/values-w820dp/dimens.xml rename to src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values-w820dp/dimens.xml diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values/dimens.xml b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values/dimens.xml new file mode 100644 index 00000000..55c1e590 --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values/dimens.xml @@ -0,0 +1,7 @@ + + + + 16dp + 16dp + + diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values/strings.xml b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values/strings.xml new file mode 100644 index 00000000..5f5b7531 --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + Keepass2Android Plugin SDK + + diff --git a/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values/styles.xml b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values/styles.xml new file mode 100644 index 00000000..6ce89c7b --- /dev/null +++ b/src/java/PluginInputStick3/keepass2AndroidPluginSDK/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/src/java/PluginInputStick3/local.properties b/src/java/PluginInputStick3/local.properties new file mode 100644 index 00000000..e4151bf6 --- /dev/null +++ b/src/java/PluginInputStick3/local.properties @@ -0,0 +1,7 @@ +## This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# Location of the SDK. This is only used by Gradle. +# +#Wed Jan 27 05:42:01 CET 2016 +sdk.dir=C\:\\Users\\Philipp\\AppData\\Local\\Android\\android-sdk diff --git a/src/java/PluginInputStick3/pluginInputStick/build.gradle b/src/java/PluginInputStick3/pluginInputStick/build.gradle new file mode 100644 index 00000000..b8929bfd --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/build.gradle @@ -0,0 +1,29 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 19 + buildToolsVersion "23.0.0" + + defaultConfig { + applicationId "keepass2android.plugin.inputstick" + minSdkVersion 14 + targetSdkVersion 19 + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + lintOptions { + disable 'MissingTranslation' + } + } + } + + +} + +dependencies { + compile project(':keepass2AndroidPluginSDK') + compile project(':inputStickAPI') +} diff --git a/src/java/PluginInputStick3/pluginInputStick/pluginInputStick.iml b/src/java/PluginInputStick3/pluginInputStick/pluginInputStick.iml new file mode 100644 index 00000000..28ef96d5 --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/pluginInputStick.iml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/java/PluginInputStick/AndroidManifest.xml b/src/java/PluginInputStick3/pluginInputStick/src/main/AndroidManifest.xml similarity index 67% rename from src/java/PluginInputStick/AndroidManifest.xml rename to src/java/PluginInputStick3/pluginInputStick/src/main/AndroidManifest.xml index e0a5df5c..37a89e11 100644 --- a/src/java/PluginInputStick/AndroidManifest.xml +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="7" + android:versionName="1.40" > + + + + + @@ -42,6 +47,10 @@ android:name=".InputStickService" android:enabled="true" > + + + + + + + + + + diff --git a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/AccessReceiver.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/AccessReceiver.java similarity index 100% rename from src/java/PluginInputStick/src/keepass2android/plugin/inputstick/AccessReceiver.java rename to src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/AccessReceiver.java diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/ActionManager.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/ActionManager.java new file mode 100644 index 00000000..b98d43fa --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/ActionManager.java @@ -0,0 +1,265 @@ +package keepass2android.plugin.inputstick; + +import java.util.HashMap; + +import keepass2android.pluginsdk.KeepassDefs; +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.widget.Toast; + +import com.inputstick.api.hid.HIDKeycodes; + +public class ActionManager { + + + private static UserPreferences userPrefs; + private static SharedPreferences prefs; + private static Context ctx; + + private static HashMap entryFields; + private static long lastActivityTime; + + public static void init(Context ctx, String entryId, HashMap entryFields) { + ActionManager.ctx = ctx; + ActionManager.entryFields = entryFields; + prefs = PreferenceManager.getDefaultSharedPreferences(ctx); + userPrefs = new UserPreferences(prefs, entryId); + lastActivityTime = 0; + } + + public static void reloadPreferences() { + if (userPrefs != null) { + userPrefs.reload(); + } + } + + public static UserPreferences getUserPrefs() { + return userPrefs; + } + + + public static String getActionStringForPrimaryLayout(int id, boolean allowInputStickText) { + return getActionString(id, userPrefs.getLayoutPrimaryDisplayCode(), allowInputStickText); + } + public static String getActionStringForSecondaryLayout(int id, boolean allowInputStickText) { + return getActionString(id, userPrefs.getLayoutSecondaryDisplayCode(), allowInputStickText); + } + public static String getActionString(int id, boolean allowInputStickText) { + return getActionString(id, null, allowInputStickText); + } + + private static String getActionString(int id, String layoutCode, boolean allowInputStickText) { + String s = ctx.getString(id); + if (layoutCode != null) { + s += " (" + layoutCode + ")"; + } + if ((allowInputStickText) && (userPrefs.isDisplayInputStickText())) { + s += " (IS)"; + } + return s; + } + + public static long getLastActivityTime() { + return lastActivityTime; + } + + + + public static void startSettingsActivity() { + Intent i = new Intent(ctx.getApplicationContext(), SettingsActivity.class); + i.putExtra(Const.EXTRA_LAUNCHED_FROM_KP2A, true); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + ctx.getApplicationContext().startActivity(i); + } + public static void startShowAllActivity() { + Intent i = new Intent(ctx.getApplicationContext(), AllActionsActivity.class); + i.putExtra(Const.EXTRA_MAX_TIME, System.currentTimeMillis() + Const.ACTIVITY_LOCK_TIMEOUT_MS); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + ctx.getApplicationContext().startActivity(i); + } + public static void startMacSetupActivity() { + connect(); + 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); + } + + + + + + + public static void connect() { + Intent serviceIntent = new Intent(ctx, InputStickService.class); + serviceIntent.setAction(Const.SERVICE_CONNECT); + ctx.startService(serviceIntent); + } + + public static void disconnect() { + Intent serviceIntent = new Intent(ctx, InputStickService.class); + serviceIntent.setAction(Const.SERVICE_DISCONNECT); + ctx.startService(serviceIntent); + } + + + public static void queueText(String text, String layout, int reportMultiplier) { + Bundle b = new Bundle(); + b.putString(Const.EXTRA_ACTION, Const.ACTION_TYPE); + b.putString(Const.EXTRA_TEXT, text); + b.putString(Const.EXTRA_LAYOUT, layout); + b.putInt(Const.EXTRA_REPORT_MULTIPLIER, reportMultiplier); + sendToService(b); + } + + public static void queueText(String text, String layout) { + queueText(text, layout, userPrefs.getReportMultiplier()); + } + + public static void queueDelay(int value) { + Bundle b = new Bundle(); + b.putString(Const.EXTRA_ACTION, Const.ACTION_DELAY); + b.putInt(Const.EXTRA_DELAY, value); + sendToService(b); + } + + public static void queueKey(byte modifier, byte key) { + Bundle b = new Bundle(); + b.putString(Const.EXTRA_ACTION, Const.ACTION_KEY_PRESS); + b.putByte(Const.EXTRA_MODIFIER, modifier); + b.putByte(Const.EXTRA_KEY, key); + b.putInt(Const.EXTRA_REPORT_MULTIPLIER, userPrefs.getReportMultiplier()); + sendToService(b); + } + + public static void sendToService(Bundle b) { + lastActivityTime = System.currentTimeMillis(); + Intent serviceIntent = new Intent(ctx, InputStickService.class); + serviceIntent.setAction(Const.SERVICE_EXEC); + serviceIntent.putExtras(b); + ctx.startService(serviceIntent); + } + + + + + + public static void typeUsernameAndPassword(String layoutName, boolean addEnter) { + queueText(entryFields.get(KeepassDefs.UserNameField), layoutName); + queueDelay(5); + queueKey(HIDKeycodes.NONE, HIDKeycodes.KEY_TAB); + queueDelay(5); + queueText(entryFields.get(KeepassDefs.PasswordField), layoutName); + if (addEnter) { + queueDelay(5); + queueKey(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER); + } + } + + + + public static void runMacro(String layoutName) { + String macro = userPrefs.getMacro(); + if ((macro != null) && (macro.length() > 0)) { + boolean runInBackground = macro.startsWith(MacroHelper.MACRO_BACKGROUND_EXEC_STRING); + String actions[] = macro.split("%"); + connect(); + if (runInBackground) { + for (String s : actions) { + runMacroAction(layoutName, s); + } + } else { + Intent i = new Intent(ctx.getApplicationContext(), MacroExecuteActivity.class); + i.putExtra(Const.EXTRA_MAX_TIME, System.currentTimeMillis() + Const.ACTIVITY_LOCK_TIMEOUT_MS); + i.putExtra(Const.EXTRA_MACRO_ACTIONS, actions); + 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 { + addEditMacro(true); + } + } + + + @SuppressLint("DefaultLocale") + public static void runMacroAction(String layoutName, String s) { + String tmp, param; + if ((s != null) && (s.length() > 0)) { + tmp = s.toLowerCase(); + //no parameter + if (tmp.startsWith(MacroHelper.MACRO_ACTION_PASSWORD)) { + queueText(entryFields.get(KeepassDefs.PasswordField), layoutName); + } else if (tmp.startsWith(MacroHelper.MACRO_ACTION_USER_NAME)) { + queueText(entryFields.get(KeepassDefs.UserNameField), layoutName); + } else if (tmp.startsWith(MacroHelper.MACRO_ACTION_URL)) { + queueText(entryFields.get(KeepassDefs.UrlField), layoutName); + } else if (tmp.startsWith(MacroHelper.MACRO_ACTION_PASSWORD_MASKED)) { + openMaskedPassword(layoutName, false); + } else if (tmp.startsWith(MacroHelper.MACRO_ACTION_CLIPBOARD)) { + clipboardTyping(layoutName); + } else { + //get parameter + param = MacroHelper.getParam(s); + if ((param != null) && (param.length() > 0)) { + if (tmp.startsWith(MacroHelper.MACRO_ACTION_TYPE)) { + queueText(param, layoutName); + } + if (tmp.startsWith(MacroHelper.MACRO_ACTION_DELAY)) { + queueDelay(MacroHelper.getDelay(param)); + } + if (tmp.startsWith(MacroHelper.MACRO_ACTION_KEY)) { + queueKey(MacroHelper.getModifiers(param), MacroHelper.getKey(param)); + } + } + } + } + } + + + + public static void clipboardTyping(String layoutName) { + connect(); //in case not connected already + if (userPrefs.isClipboardLaunchAuthenticator()) { + Intent launchIntent = ctx.getPackageManager().getLaunchIntentForPackage("com.google.android.apps.authenticator2"); + if (launchIntent != null) { + ctx.getApplicationContext().startActivity(launchIntent); + } else { + Toast.makeText(ctx, R.string.text_authenticator_app_not_found, Toast.LENGTH_LONG).show(); + } + } + + Intent i = new Intent(ctx, ClipboardService.class); + i.putExtra(Const.EXTRA_LAYOUT, layoutName); + ctx.startService(i); + } + + + public static void addEditMacro(boolean showEmptyMacroError) { + Intent i = new Intent(ctx.getApplicationContext(), MacroActivity.class); + i.putExtra(Const.EXTRA_MACRO, userPrefs.getMacro()); + i.putExtra(Const.EXTRA_ENTRY_ID, userPrefs.getEntryId()); + if (showEmptyMacroError) { + i.putExtra(Const.EXTRA_MACRO_RUN_BUT_EMPTY, showEmptyMacroError); + } + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + ctx.getApplicationContext().startActivity(i); + } + + public static void openMaskedPassword(String layoutName, boolean addClearFlags) { + connect(); //in case not connected already + Intent i = new Intent(ctx.getApplicationContext(), MaskedPasswordActivity.class); + i.putExtra(Const.EXTRA_TEXT, entryFields.get(KeepassDefs.PasswordField)); + i.putExtra(Const.EXTRA_LAYOUT, layoutName); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + if (addClearFlags) { + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + } + ctx.getApplicationContext().startActivity(i); + } + + +} diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/ActionReceiver.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/ActionReceiver.java new file mode 100644 index 00000000..f996cdf3 --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/ActionReceiver.java @@ -0,0 +1,288 @@ +package keepass2android.plugin.inputstick; + +import keepass2android.pluginsdk.PluginAccessException; +import keepass2android.pluginsdk.Strings; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; + +import com.inputstick.api.hid.HIDKeycodes; + +public class ActionReceiver extends keepass2android.pluginsdk.PluginActionBroadcastReceiver { + + private static final int LAYOUT_NONE = 0; + private static final int LAYOUT_PRIMARY = 1; + private static final int LAYOUT_SECONDARY = 2; + + private static final String ACTION_SHOW_ALL = "keepass2android.plugin.inputstick.show_all"; + private static final String ACTION_MASKED_PASSWORD = "keepass2android.plugin.inputstick.masked_password"; + private static final String ACTION_SETTINGS = "keepass2android.plugin.inputstick.settings"; + private static final String ACTION_CONNECT = "keepass2android.plugin.inputstick.connect"; + private static final String ACTION_DISCONNECT = "keepass2android.plugin.inputstick.disconnect"; + private static final String ACTION_USER_PASS = "keepass2android.plugin.inputstick.user_pass"; + private static final String ACTION_USER_PASS_ENTER = "keepass2android.plugin.inputstick.user_pass_enter"; + private static final String ACTION_MAC_SETUP = "keepass2android.plugin.inputstick.mac_setup"; + private static final String ACTION_TAB = "keepass2android.plugin.inputstick.tab"; + private static final String ACTION_ENTER = "keepass2android.plugin.inputstick.enter"; + + private static final String ACTION_MACRO_ADDEDIT = "keepass2android.plugin.inputstick.macro_addedit"; + private static final String ACTION_CLIPBOARD = "keepass2android.plugin.inputstick.clipboard"; + private static final String ACTION_MACRO_RUN = "keepass2android.plugin.inputstick.macro_run"; + + private static final String ACTION_FIELD_TYPE_PRIMARY = "keepass2android.plugin.inputstick.type"; + private static final String ACTION_FIELD_TYPE_SLOW_PRIMARY = "keepass2android.plugin.inputstick.type_slow"; + private static final String ACTION_FIELD_TYPE_SECONDARY = "keepass2android.plugin.inputstick.types_econdary"; + private static final String ACTION_FIELD_TYPE_SLOW_SECONDARY = "keepass2android.plugin.inputstick.type_slow_secondary"; + + private static final int IC = R.drawable.ic_launcher; + + private static Context ctx; + private static SharedPreferences sharedPref; + private static UserPreferences userPrefs; + + + @Override + protected void openEntry(OpenEntryAction oe) { + try { + ctx = oe.getContext(); + sharedPref = PreferenceManager.getDefaultSharedPreferences(ctx); + + SettingsActivity.convertOldUiPreferences(sharedPref, ctx); + + + MigrationMessageActivity.displayNotification(ctx); + + ActionManager.init(ctx, oe.getEntryId(), oe.getEntryFields()); + userPrefs = ActionManager.getUserPrefs(); + + for (String field: oe.getEntryFields().keySet()) { + //primary layout + if (userPrefs.isShowType(true)) { + addEntryFieldTypeAction(oe, ACTION_FIELD_TYPE_PRIMARY, Strings.PREFIX_STRING + field, false, LAYOUT_PRIMARY); + } + if (userPrefs.isShowTypeSlow(true)) { + addEntryFieldTypeAction(oe, ACTION_FIELD_TYPE_SLOW_PRIMARY, Strings.PREFIX_STRING + field, true, LAYOUT_PRIMARY); + } + //secondary layout + if (userPrefs.isShowType(false)) { + addEntryFieldTypeAction(oe, ACTION_FIELD_TYPE_SECONDARY, Strings.PREFIX_STRING + field, false, LAYOUT_SECONDARY); + } + if (userPrefs.isShowTypeSlow(false)) { + addEntryFieldTypeAction(oe, ACTION_FIELD_TYPE_SLOW_SECONDARY, Strings.PREFIX_STRING + field, true, LAYOUT_SECONDARY); + } + } + + //always add "all actions" + addEntryAction(oe, R.string.action_show_all, ACTION_SHOW_ALL, LAYOUT_NONE); + + //general items + if (userPrefs.isShowSettings()) { + addEntryAction(oe, R.string.action_open_settings, ACTION_SETTINGS, LAYOUT_NONE); + } + if (userPrefs.isShowConnectionOptions()) { + addEntryAction(oe, R.string.action_connect, ACTION_CONNECT, LAYOUT_NONE); + addEntryAction(oe, R.string.action_disconnect, ACTION_DISCONNECT, LAYOUT_NONE); + } + + if (userPrefs.isShowMacSetup()) { + addEntryAction(oe, R.string.action_open_mac_setup, ACTION_MAC_SETUP, LAYOUT_NONE); + } + if (userPrefs.isShowTabEnter()) { + addEntryAction(oe, R.string.action_type_tab, ACTION_TAB, LAYOUT_NONE); + addEntryAction(oe, R.string.action_type_enter, ACTION_ENTER, LAYOUT_NONE); + } + if (userPrefs.isShowMacroAddEdit()) { + addEntryAction(oe, R.string.action_macro_add_edit, ACTION_MACRO_ADDEDIT, LAYOUT_NONE); + } + + //entry items, primary layout + if (userPrefs.isShowUserPass(true)) { + addEntryAction(oe, R.string.action_type_user_tab_pass, ACTION_USER_PASS, LAYOUT_PRIMARY); + } + if (userPrefs.isShowUserPassEnter(true)) { + addEntryAction(oe, R.string.action_type_user_tab_pass_enter, ACTION_USER_PASS_ENTER, LAYOUT_PRIMARY); + } + if (userPrefs.isShowMasked(true)) { + addEntryAction(oe, R.string.action_masked_password, ACTION_MASKED_PASSWORD, LAYOUT_PRIMARY); + } + if (userPrefs.isShowMacro(true)) { + addEntryAction(oe, R.string.action_macro_run, ACTION_MACRO_RUN, LAYOUT_PRIMARY); + } + if (userPrefs.isShowClipboard(true)) { + addEntryAction(oe, R.string.action_clipboard, ACTION_CLIPBOARD, LAYOUT_PRIMARY); + } + + //entry items, secondary layout + if (userPrefs.isShowUserPass(false)) { + addEntryAction(oe, R.string.action_type_user_tab_pass, ACTION_USER_PASS, LAYOUT_SECONDARY); + } + if (userPrefs.isShowUserPassEnter(false)) { + addEntryAction(oe, R.string.action_type_user_tab_pass_enter, ACTION_USER_PASS_ENTER, LAYOUT_SECONDARY); + } + if (userPrefs.isShowMasked(false)) { + addEntryAction(oe, R.string.action_masked_password, ACTION_MASKED_PASSWORD, LAYOUT_SECONDARY); + } + if (userPrefs.isShowMacro(false)) { + addEntryAction(oe, R.string.action_macro_run, ACTION_MACRO_RUN, LAYOUT_SECONDARY); + } + if (userPrefs.isShowClipboard(false)) { + addEntryAction(oe, R.string.action_clipboard, ACTION_CLIPBOARD, LAYOUT_SECONDARY); + } + } catch (PluginAccessException e) { + e.printStackTrace(); + } + + if (userPrefs.isAutoConnect()) { + ActionManager.connect(); + } else { + if ((ActionManager.getLastActivityTime() != 0) && ((System.currentTimeMillis() - userPrefs.getAutoConnectTimeout()) < ActionManager.getLastActivityTime())) { + ActionManager.connect(); + } + } + + + if (MigrationMessageActivity.shouldShowActivity(sharedPref)) { + 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); + } + + //removed; upadate notification will be displayed anyway + /*ChangeLog cl = new ChangeLog(ctx.getApplicationContext()); + if (cl.firstRun()) { + Intent i = new Intent(ctx.getApplicationContext(), SettingsActivity.class); + i.putExtra(Const.EXTRA_SHOW_CHANGELOG, true); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + ctx.getApplicationContext().startActivity(i); + }*/ + } + + + + private void addEntryAction(OpenEntryAction oe, int nameResId, String action, int layoutType) throws PluginAccessException { + Bundle b = new Bundle(); + b.putString(Const.SELECTED_UI_ACTION, action); + String displayText; + if (layoutType == LAYOUT_PRIMARY) { + b.putString(Const.EXTRA_LAYOUT, userPrefs.getLayoutPrimary()); + displayText = ActionManager.getActionStringForPrimaryLayout(nameResId, true); + } else if (layoutType == LAYOUT_SECONDARY) { + b.putString(Const.EXTRA_LAYOUT, userPrefs.getLayoutSecondary()); + displayText = ActionManager.getActionStringForSecondaryLayout(nameResId, true); + } else { + displayText = ActionManager.getActionString(nameResId, true); + } + oe.addEntryAction(displayText, IC, b); + } + + private void addEntryFieldTypeAction(OpenEntryAction oe, String actionId, String fieldId, boolean slowTyping, int layoutType) throws PluginAccessException { + int nameResId; + Bundle b = new Bundle(); + if (slowTyping) { + b.putBoolean(Const.EXTRA_TYPE_SLOW, true); + nameResId = R.string.action_type_slow; + } else { + nameResId = R.string.action_type; + } + String displayText; + if (layoutType == LAYOUT_SECONDARY) { + b.putString(Const.EXTRA_LAYOUT, userPrefs.getLayoutSecondary()); + displayText = ActionManager.getActionStringForSecondaryLayout(nameResId, true); + } else { + b.putString(Const.EXTRA_LAYOUT, userPrefs.getLayoutPrimary()); + displayText = ActionManager.getActionStringForPrimaryLayout(nameResId, true); + } + oe.addEntryFieldAction(actionId, fieldId, displayText, IC, b); + } + + + + @Override + protected void closeEntryView(CloseEntryViewAction closeEntryView) { + try { + if ((userPrefs != null) && (userPrefs.isDisconnectOnClose())) { + ActionManager.disconnect(); + } + MigrationMessageActivity.hideNotification(ctx); + } catch (Exception e) { + } + }; + + @Override + protected void actionSelected(ActionSelectedAction actionSelected) { + String layoutName = actionSelected.getActionData().getString(Const.EXTRA_LAYOUT, "en-US"); + if (actionSelected.isEntryAction()) { + String text = actionSelected.getActionData().getString(Const.SELECTED_UI_ACTION); + + if (ACTION_MASKED_PASSWORD.equals(text)) { + ActionManager.openMaskedPassword(layoutName, true); + } else if (ACTION_SETTINGS.equals(text)) { + ActionManager.startSettingsActivity(); + } else if (ACTION_SHOW_ALL.equals(text)) { + ActionManager.startShowAllActivity(); + } else if (ACTION_USER_PASS.equals(text)) { + ActionManager.typeUsernameAndPassword(layoutName, false); + } else if (ACTION_USER_PASS_ENTER.equals(text)) { + ActionManager.typeUsernameAndPassword(layoutName, true); + } else if (ACTION_MAC_SETUP.equals(text)) { + ActionManager.startMacSetupActivity(); + } else if (ACTION_MACRO_ADDEDIT.equals(text)) { + ActionManager.addEditMacro(false); + } else if (ACTION_CLIPBOARD.equals(text)) { + ActionManager.clipboardTyping(layoutName); + } else if (ACTION_MACRO_RUN.equals(text)) { + ActionManager.runMacro(layoutName); + } else if (ACTION_TAB.equals(text)) { + ActionManager.queueKey(HIDKeycodes.NONE, HIDKeycodes.KEY_TAB); + } else if (ACTION_ENTER.equals(text)) { + ActionManager.queueKey(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER); + } else if (ACTION_CONNECT.equals(text)) { + ActionManager.connect(); + } else if (ACTION_DISCONNECT.equals(text)) { + ActionManager.disconnect(); + } + } else { + //field actions: type/type slow + boolean typeSlow = actionSelected.getActionData().getBoolean(Const.EXTRA_TYPE_SLOW, false); + String fieldKey = actionSelected.getFieldId().substring(Strings.PREFIX_STRING.length()); + String text = actionSelected.getEntryFields().get(fieldKey); + if (typeSlow) { + ActionManager.queueText(text, layoutName, Const.SLOW_TYPING_MULTIPLIER); + } else { + ActionManager.queueText(text, layoutName); + } + + if ((userPrefs.isEnterAfterURL()) && ("URL".equals(fieldKey))) { + ActionManager.queueKey(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER); + } + } + } + + + + @Override + protected void entryOutputModified(EntryOutputModifiedAction eom) { + try { + //primary layout: + if (userPrefs.isShowType(true)) { + addEntryFieldTypeAction(eom, ACTION_FIELD_TYPE_PRIMARY, eom.getModifiedFieldId(), false, LAYOUT_PRIMARY); + } + if (userPrefs.isShowTypeSlow(true)) { + addEntryFieldTypeAction(eom, ACTION_FIELD_TYPE_SLOW_PRIMARY, eom.getModifiedFieldId(), true, LAYOUT_PRIMARY); + } + //secondary layout: + if (userPrefs.isShowType(false)) { + addEntryFieldTypeAction(eom, ACTION_FIELD_TYPE_SECONDARY, eom.getModifiedFieldId(), false, LAYOUT_SECONDARY); + } + if (userPrefs.isShowTypeSlow(false)) { + addEntryFieldTypeAction(eom, ACTION_FIELD_TYPE_SLOW_SECONDARY, eom.getModifiedFieldId(), true, LAYOUT_SECONDARY); + } + } catch (PluginAccessException e) { + e.printStackTrace(); + } + } + + +} diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/AllActionsActivity.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/AllActionsActivity.java new file mode 100644 index 00000000..aa910fda --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/AllActionsActivity.java @@ -0,0 +1,130 @@ +package keepass2android.plugin.inputstick; + +import java.util.ArrayList; + +import android.app.Activity; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.Toast; + +import com.inputstick.api.hid.HIDKeycodes; + +public class AllActionsActivity extends Activity { + + private long lastActionTime; + private long maxTime; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.setTheme( android.R.style.Theme_Holo_Dialog); + setContentView(R.layout.activity_all_actions); + + final UserPreferences userPrefs = ActionManager.getUserPrefs(); + maxTime = getIntent().getLongExtra(Const.EXTRA_MAX_TIME, 0); + lastActionTime = System.currentTimeMillis(); + + ListView listViewActions = (ListView) findViewById(R.id.listViewActions); + ArrayList list = new ArrayList(); + ArrayAdapter listAdapter = new ArrayAdapter(this, R.layout.row, list); + + listAdapter.add(ActionManager.getActionString(R.string.action_open_settings, false)); + listAdapter.add(ActionManager.getActionString(R.string.action_connect, false)); + listAdapter.add(ActionManager.getActionString(R.string.action_disconnect, false)); + listAdapter.add(ActionManager.getActionString(R.string.action_open_mac_setup, false)); + listAdapter.add(ActionManager.getActionString(R.string.action_type_tab, false)); + listAdapter.add(ActionManager.getActionString(R.string.action_type_enter, false)); + listAdapter.add(ActionManager.getActionString(R.string.action_macro_add_edit, false)); + + listAdapter.add(ActionManager.getActionStringForPrimaryLayout(R.string.action_type_user_tab_pass, false)); + listAdapter.add(ActionManager.getActionStringForPrimaryLayout(R.string.action_type_user_tab_pass_enter, false)); + listAdapter.add(ActionManager.getActionStringForPrimaryLayout(R.string.action_masked_password, false)); + listAdapter.add(ActionManager.getActionStringForPrimaryLayout(R.string.action_macro_run, false)); + listAdapter.add(ActionManager.getActionStringForPrimaryLayout(R.string.action_clipboard, false)); + + if (userPrefs.isShowSecondary()) { + listAdapter.add(ActionManager.getActionStringForSecondaryLayout(R.string.action_type_user_tab_pass, false)); + listAdapter.add(ActionManager.getActionStringForSecondaryLayout(R.string.action_type_user_tab_pass_enter, false)); + listAdapter.add(ActionManager.getActionStringForSecondaryLayout(R.string.action_masked_password, false)); + listAdapter.add(ActionManager.getActionStringForSecondaryLayout(R.string.action_macro_run, false)); + listAdapter.add(ActionManager.getActionStringForSecondaryLayout(R.string.action_clipboard, false)); + } + + listViewActions.setAdapter(listAdapter); + listViewActions.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView arg0, View view, int pos, long arg3) { + long now = System.currentTimeMillis(); + if (now > maxTime) { + Toast.makeText(AllActionsActivity.this, R.string.text_locked, Toast.LENGTH_LONG).show(); + } else { + maxTime += (now - lastActionTime); + lastActionTime = now; + + switch (pos) { + //general: + case 0: + ActionManager.startSettingsActivity(); + break; + case 1: + ActionManager.connect(); + break; + case 2: + ActionManager.disconnect(); + break; + case 3: + ActionManager.startMacSetupActivity(); + break; + case 4: + ActionManager.queueKey(HIDKeycodes.NONE, HIDKeycodes.KEY_TAB); + break; + case 5: + ActionManager.queueKey(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER); + break; + case 6: + ActionManager.addEditMacro(false); + break; + //entry, primary layout + case 7: + ActionManager.typeUsernameAndPassword(userPrefs.getLayoutPrimary(), false); + break; + case 8: + ActionManager.typeUsernameAndPassword(userPrefs.getLayoutPrimary(), true); + break; + case 9: + ActionManager.openMaskedPassword(userPrefs.getLayoutPrimary(), true); + break; + case 10: + ActionManager.runMacro(userPrefs.getLayoutPrimary()); + break; + case 11: + ActionManager.clipboardTyping(userPrefs.getLayoutPrimary()); + break; + //entry, secondary layout + case 12: + ActionManager.typeUsernameAndPassword(userPrefs.getLayoutSecondary(), false); + break; + case 13: + ActionManager.typeUsernameAndPassword(userPrefs.getLayoutSecondary(), true); + break; + case 14: + ActionManager.openMaskedPassword(userPrefs.getLayoutSecondary(), true); + break; + case 15: + ActionManager.runMacro(userPrefs.getLayoutSecondary()); + break; + case 16: + ActionManager.clipboardTyping(userPrefs.getLayoutSecondary()); + break; + } + } + } + }); + } + + +} diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/ClipboardService.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/ClipboardService.java new file mode 100644 index 00000000..b09e3f33 --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/ClipboardService.java @@ -0,0 +1,77 @@ +package keepass2android.plugin.inputstick; + +import com.inputstick.api.hid.HIDKeycodes; + +import android.app.Service; +import android.content.ClipData; +import android.content.ClipDescription; +import android.content.ClipboardManager; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder; +import android.widget.Toast; + +public class ClipboardService extends Service { + + private String layout; + + Handler delayhandler = new Handler(); + private Runnable mUpdateTimeTask = new Runnable() { + public void run() { + stopSelf(); + } + }; + + @Override + public IBinder onBind(Intent arg0) { + return null; + } + + @Override + public void onDestroy() { + Toast.makeText(this, R.string.text_clipboard_disabled, Toast.LENGTH_SHORT).show(); + delayhandler.removeCallbacksAndMessages(null); + if (myClipBoard != null) { + myClipBoard.removePrimaryClipChangedListener(mPrimaryClipChangedListener); + myClipBoard = null; + } + super.onDestroy(); + + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + layout = intent.getStringExtra(Const.EXTRA_LAYOUT); + if (myClipBoard == null) { + myClipBoard = (ClipboardManager)getSystemService(android.content.Context.CLIPBOARD_SERVICE); + myClipBoard.addPrimaryClipChangedListener(mPrimaryClipChangedListener); + } + delayhandler.removeCallbacksAndMessages(null); + delayhandler.postDelayed(mUpdateTimeTask, Const.CLIPBOARD_TIMEOUT_MS); + Toast.makeText(this, R.string.text_clipboard_copy_now, Toast.LENGTH_LONG).show(); + return START_NOT_STICKY; + } + + + ClipboardManager myClipBoard ; + ClipboardManager.OnPrimaryClipChangedListener mPrimaryClipChangedListener = new ClipboardManager.OnPrimaryClipChangedListener() { + public void onPrimaryClipChanged() { + ClipData clipData = myClipBoard.getPrimaryClip(); + if (clipData.getDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) { + String text = clipData.getItemAt(0).getText().toString(); + if (text != null) { + UserPreferences userPrefs = ActionManager.getUserPrefs(); + ActionManager.queueText(text, layout); + if (userPrefs.isClipboardAutoEnter()) { + ActionManager.queueKey(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER); + } + if (userPrefs.isClipboardAutoDisable()) { + delayhandler.removeCallbacksAndMessages(null); + stopSelf(); + } + } + } + } + }; + +} diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/Const.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/Const.java new file mode 100644 index 00000000..ac4a2a99 --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/Const.java @@ -0,0 +1,49 @@ +package keepass2android.plugin.inputstick; + + +public class Const { + + public static final int MASKED_PASSWORD_TIMEOUT_MS = 120000; //2min + public static final int CLIPBOARD_TIMEOUT_MS = 30000; //30s + public static final int DEFAULT_AUTOCONNECT_TIMEOUT_MS = 600000; //10min + public static final int ACTIVITY_LOCK_TIMEOUT_MS = 180000; //3min, + + public static final String SERVICE_CONNECT = "connect"; + public static final String SERVICE_DISCONNECT = "disconnect"; + public static final String SERVICE_EXEC = "exec"; + + + public static final String EXTRA_ACTION = "action"; + + public static final String SELECTED_UI_ACTION = "action"; + public static final String EXTRA_TEXT = "text"; + public static final String EXTRA_LAYOUT = "layout"; + public static final String EXTRA_REPORT_MULTIPLIER = "multiplier"; + public static final String EXTRA_DELAY = "delay"; + public static final String EXTRA_MODIFIER = "mod"; + public static final String EXTRA_KEY = "key"; + public static final String EXTRA_MACRO = "macro"; + public static final String EXTRA_ENTRY_ID = "entry_id"; + public static final String EXTRA_LAUNCHED_FROM_KP2A = "kp2a_launch"; + public static final String EXTRA_MACRO_RUN_BUT_EMPTY = "macro_run_empty"; + public static final String EXTRA_MACRO_ACTIONS = "macro_actions"; + + public static final String EXTRA_MAX_TIME = "max_time"; + + + public static final String EXTRA_TYPE_SLOW = "params"; + public static final String EXTRA_SHOW_CHANGELOG = "changelog"; + + public static final String ACTION_TYPE = "type"; + public static final String ACTION_DELAY = "delay"; + public static final String ACTION_KEY_PRESS = "key"; + + public static final int SLOW_TYPING_MULTIPLIER= 10; + + public static final String MACRO_PREF_PREFIX = "m_"; + public static final String TEMPLATE_PREF_PREFIX = "t_"; + public static final String TEMPLATE_NAME_PREF_PREFIX = "tn_"; + + public static final String TEMPLATE_DEFAULT_NAME_PREF_PREFIX = "TEMPLATE: "; + +} diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/InputStickService.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/InputStickService.java new file mode 100644 index 00000000..edc623df --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/InputStickService.java @@ -0,0 +1,188 @@ +package keepass2android.plugin.inputstick; + +import java.util.ArrayList; + +import android.app.AlertDialog; +import android.app.Service; +import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; +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.HIDTransaction; +import com.inputstick.api.hid.KeyboardReport; + +public class InputStickService extends Service implements InputStickStateListener { + + private static final String _TAG = "KP2AINPUTSTICK"; + + private ArrayList items = new ArrayList(); + + + @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 (Const.SERVICE_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; + } else if (Const.SERVICE_CONNECT.equals(intent.getAction())) { + if ( !InputStickHID.isConnected()) { + InputStickHID.connect(getApplication()); + } + } else if (Const.SERVICE_EXEC.equals(intent.getAction())) { + int state = InputStickHID.getState(); + Bundle b = intent.getExtras(); + //Log.d(_TAG, "type params: "+params); + switch (state) { + case ConnectionManager.STATE_CONNECTED: + case ConnectionManager.STATE_CONNECTING: + synchronized (items) { + items.add(new ItemToExecute(b)); + } + break; + case ConnectionManager.STATE_READY: + new ItemToExecute(b).execute(); + break; + case ConnectionManager.STATE_DISCONNECTED: + case ConnectionManager.STATE_FAILURE: + synchronized (items) { + items.add(new ItemToExecute(b)); + } + Log.d(_TAG, "trigger connect"); + InputStickHID.connect(getApplication()); + break; + } + } else { + //unknown action + } + return Service.START_NOT_STICKY; + + } + + @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: + executeQueue(); + break; + case ConnectionManager.STATE_DISCONNECTED: + Log.d(_TAG, "stopping service. State = "+state); + stopSelf(); + break; + case ConnectionManager.STATE_FAILURE: + Log.d(_TAG, "stopping service. State = "+state); + AlertDialog ad = InputStickHID.getDownloadDialog(this); + if (ad != null) { + //InputStickUtility application not installed + ad.show(); + } else { + Toast.makeText(this, R.string.text_connection_failed, Toast.LENGTH_LONG).show(); + } + stopSelf(); + break; + default: + break; + } + + } + + private void executeQueue() { + dummyKeyPresses(15); + synchronized (items) { + for (ItemToExecute itt : items) { + Log.d(_TAG, "executing (after callback) "); + itt.execute(); + } + items.clear(); + } + } + + //short delay achieved by sending empty keyboard reports + private void dummyKeyPresses(int keys) { + HIDTransaction t = new HIDTransaction(); + for (int i = 0; i < keys * 3; i++) { // 1 keypress = 3 HID reports (modifier, modifier+key, all released) + t.addReport(new KeyboardReport((byte)0x00, (byte)0x00)); + } + InputStickHID.addKeyboardTransaction(t); + } + + + + private class ItemToExecute { + public Bundle mBundle; + ItemToExecute(Bundle b) { + mBundle = b; + } + + public void execute() { + if ((InputStickHID.getState() == ConnectionManager.STATE_READY) && (mBundle != null)) { + String action = mBundle.getString(Const.EXTRA_ACTION); + InputStickHID.setKeyboardReportMultiplier(mBundle.getInt(Const.EXTRA_REPORT_MULTIPLIER, 1)); + + if (Const.ACTION_TYPE.equals(action)) { + String text = mBundle.getString(Const.EXTRA_TEXT); + String layout = mBundle.getString(Const.EXTRA_LAYOUT); + InputStickKeyboard.type(text, layout); + } else if (Const.ACTION_KEY_PRESS.equals(action)) { + byte modifier = mBundle.getByte(Const.EXTRA_MODIFIER); + byte key = mBundle.getByte(Const.EXTRA_KEY); + InputStickKeyboard.pressAndRelease(modifier, key); + } else if (Const.ACTION_DELAY.equals(action)) { + int reports = mBundle.getInt(Const.EXTRA_DELAY, 0) / 4; //1 report / 4ms + dummyKeyPresses(reports); + } else { + //unknown action type! + } + InputStickHID.setKeyboardReportMultiplier(1); + } + } + } + +} diff --git a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/MacSetupActivity.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacSetupActivity.java similarity index 68% rename from src/java/PluginInputStick/src/keepass2android/plugin/inputstick/MacSetupActivity.java rename to src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacSetupActivity.java index e344b0bf..37705957 100644 --- a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/MacSetupActivity.java +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacSetupActivity.java @@ -1,9 +1,7 @@ package keepass2android.plugin.inputstick; import android.app.Activity; -import android.content.SharedPreferences; import android.os.Bundle; -import android.preference.PreferenceManager; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; @@ -17,32 +15,22 @@ import com.inputstick.api.hid.HIDKeycodes; import com.inputstick.api.layout.KeyboardLayout; public class MacSetupActivity extends Activity { - - private KeyboardLayout layout; - private TextView textViewLayoutInfo; - private Button buttonNextToShift; private boolean nonUS; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB){ - super.setTheme( android.R.style.Theme_Holo_Dialog); - } + super.setTheme( android.R.style.Theme_Holo_Dialog); setContentView(R.layout.activity_mac_setup); + + String layoutName = ActionManager.getUserPrefs().getLayoutPrimary(); + KeyboardLayout layout = KeyboardLayout.getLayout(layoutName); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - String layoutName = prefs.getString("kbd_layout", "en-US"); - - layout = KeyboardLayout.getLayout(layoutName); - - textViewLayoutInfo = (TextView)findViewById(R.id.textViewLayoutInfo); - textViewLayoutInfo.append(layoutName); - - buttonNextToShift = (Button)findViewById(R.id.buttonNextToShift); + TextView textViewLayoutInfo = (TextView)findViewById(R.id.textViewLayoutInfo); + textViewLayoutInfo.append(" " + layoutName); + Button buttonNextToShift = (Button)findViewById(R.id.buttonNextToShift); buttonNextToShift.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (InputStickHID.getState() == ConnectionManager.STATE_READY) { @@ -58,7 +46,7 @@ public class MacSetupActivity extends Activity { }); - //check non-us backslash key is used by this layout: + //check if non-us backslash key is used by this layout: int[][] lut = layout.getLUT(); int tmp = lut[0x56][1]; nonUS = true; @@ -77,7 +65,6 @@ public class MacSetupActivity extends Activity { //US ANSI buttonNextToShift.setText(String.valueOf(layout.getChar(KeyboardLayout.hidToScanCode(HIDKeycodes.KEY_Z), false, false, false))); } - //System.out.println("NonUS: "+nonUS); } diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacroActivity.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacroActivity.java new file mode 100644 index 00000000..ecf348e8 --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacroActivity.java @@ -0,0 +1,452 @@ +package keepass2android.plugin.inputstick; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.RadioButton; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.Toast; + +public class MacroActivity extends Activity { + + private SharedPreferences prefs; + + private String macro; + private String id; + + private EditText editTextMacro; + private EditText editTextString; + private Spinner spinnerDelay; + private Button buttonDelete; + private Button buttonSave; + private RadioButton radioButtonBackground; + private RadioButton radioButtonShowControls; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_macro); + + prefs = PreferenceManager.getDefaultSharedPreferences(this); + + editTextMacro = (EditText)findViewById(R.id.editTextMacro); + editTextString = (EditText)findViewById(R.id.editTextString); + spinnerDelay = (Spinner)findViewById(R.id.spinnerDelay); + + + radioButtonBackground = (RadioButton)findViewById(R.id.radioButtonBackground); + radioButtonBackground.setOnCheckedChangeListener(new OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton arg0, boolean isChecked) { + if (isChecked) { + setExecutionMode(true); + } + } + }); + radioButtonShowControls = (RadioButton)findViewById(R.id.radioButtonShowControls); + radioButtonShowControls.setOnCheckedChangeListener(new OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton arg0, boolean isChecked) { + if (isChecked) { + setExecutionMode(false); + } + } + }); + + editTextMacro.addTextChangedListener(new TextWatcher() { + @Override + public void afterTextChanged(Editable s) { + if (s.length() > 0) { + buttonSave.setEnabled(true); + } else { + buttonSave.setEnabled(false); + } + } + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + }); + + + buttonDelete = (Button)findViewById(R.id.buttonDelete); + buttonDelete.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + AlertDialog.Builder alert = new AlertDialog.Builder(MacroActivity.this); + alert.setTitle(R.string.delete_title); + alert.setMessage(R.string.delete_message); + alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + deleteMacro(); + } + }); + alert.setNegativeButton(R.string.cancel, null); + alert.show(); + } + }); + + + buttonSave = (Button)findViewById(R.id.buttonSave); + buttonSave.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + saveMacro(); + } + }); + + Button button; + button = (Button)findViewById(R.id.buttonHelp); + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + AlertDialog.Builder alert = new AlertDialog.Builder(MacroActivity.this); + alert.setTitle(R.string.help); + alert.setMessage(R.string.macro_help); + alert.setNeutralButton(R.string.ok, null); + alert.show(); + } + }); + + button = (Button)findViewById(R.id.buttonAddFromField); + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + CharSequence options[] = new CharSequence[] {MacroActivity.this.getString(R.string.user_name), + MacroActivity.this.getString(R.string.password), + MacroActivity.this.getString(R.string.url), + MacroActivity.this.getString(R.string.password_masked), + MacroActivity.this.getString(R.string.clipboard_authenticator)}; + + + AlertDialog.Builder builder = new AlertDialog.Builder(MacroActivity.this); + builder.setTitle(R.string.add_from_field); + builder.setItems(options, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case 0: + addAction(MacroHelper.MACRO_ACTION_USER_NAME, null); + break; + case 1: + addAction(MacroHelper.MACRO_ACTION_PASSWORD, null); + break; + case 2: + addAction(MacroHelper.MACRO_ACTION_URL, null); + break; + case 3: + addAction(MacroHelper.MACRO_ACTION_PASSWORD_MASKED, null); + break; + case 4: + addAction(MacroHelper.MACRO_ACTION_CLIPBOARD, null); + break; + } + } + }); + builder.show(); + } + }); + + button = (Button)findViewById(R.id.buttonAddEnter); + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + addAction(MacroHelper.MACRO_ACTION_KEY, "enter"); + } + }); + button = (Button)findViewById(R.id.buttonAddTab); + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + addAction(MacroHelper.MACRO_ACTION_KEY, "tab"); + } + }); + button = (Button)findViewById(R.id.buttonAddCustom); + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + AlertDialog.Builder alert = new AlertDialog.Builder(MacroActivity.this); + alert.setTitle(R.string.custom_key_title); + + final LinearLayout lin= new LinearLayout(MacroActivity.this); + lin.setOrientation(LinearLayout.VERTICAL); + + final TextView tvInfo = new TextView(MacroActivity.this); + tvInfo.setText(R.string.custom_key_message); + + final Spinner spinner = new Spinner(MacroActivity.this); + ArrayAdapter adapter = new ArrayAdapter(MacroActivity.this, android.R.layout.simple_spinner_item, MacroHelper.getKeyList()); + spinner.setAdapter(adapter); + + final CheckBox cbCtrlLeft = new CheckBox(MacroActivity.this); + cbCtrlLeft.setText("Ctrl"); + final CheckBox cbShiftLeft = new CheckBox(MacroActivity.this); + cbShiftLeft.setText("Shift"); + final CheckBox cbAltLeft = new CheckBox(MacroActivity.this); + cbAltLeft.setText("Alt"); + final CheckBox cbGuiLeft = new CheckBox(MacroActivity.this); + cbGuiLeft.setText("GUI (Win key)"); + final CheckBox cbAltRight = new CheckBox(MacroActivity.this); + cbAltRight.setText("AltGr (right)"); + + //cbKeyword = new CheckBox(SettingsTextActivity.this); + //cbKeyword.setChecked(false); + + lin.addView(tvInfo); + lin.addView(spinner); + lin.addView(cbCtrlLeft); + lin.addView(cbShiftLeft); + lin.addView(cbAltLeft); + lin.addView(cbGuiLeft); + lin.addView(cbAltRight); + alert.setView(lin); + + alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + private String param; + + private void add(String toAdd) { + if (param.length() > 0) { + param += "+"; + } + param += toAdd; + } + + public void onClick(DialogInterface dialog, int whichButton) { + param = ""; + if (cbCtrlLeft.isChecked()) add("Ctrl"); + if (cbShiftLeft.isChecked()) add("Shift"); + if (cbAltLeft.isChecked()) add("Alt"); + if (cbGuiLeft.isChecked()) add("Gui"); + if (cbAltRight.isChecked()) add("AltGr"); + add((String)spinner.getSelectedItem()); + addAction(MacroHelper.MACRO_ACTION_KEY, param); + } + }); + alert.setNegativeButton(R.string.cancel, null); + alert.show(); + } + }); + button = (Button)findViewById(R.id.buttonAddString); + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + String s = editTextString.getText().toString(); + if ((s != null) && (s.length() > 0)) { + if (s.contains("%")) { + Toast.makeText(MacroActivity.this, R.string.illegal_character_toast, Toast.LENGTH_LONG).show(); + } else { + addAction(MacroHelper.MACRO_ACTION_TYPE, s); + } + } + } + }); + button = (Button)findViewById(R.id.buttonAddDelay); + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + addAction(MacroHelper.MACRO_ACTION_DELAY, String.valueOf(spinnerDelay.getSelectedItem())); + } + }); + + button = (Button) findViewById(R.id.buttonTemplateSave); + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + AlertDialog.Builder builder = new AlertDialog.Builder(MacroActivity.this); + builder.setTitle(R.string.save_as); + builder.setItems(getTemplateNames(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + getSaveTemplateDialog(which).show(); + } + }); + builder.show(); + } + }); + button = (Button)findViewById(R.id.buttonTemplateLoad); + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + AlertDialog.Builder builder = new AlertDialog.Builder(MacroActivity.this); + builder.setTitle(R.string.load_from); + builder.setItems(getTemplateNames(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String tmp = prefs.getString(Const.TEMPLATE_PREF_PREFIX + which, ""); + if ((tmp != null) && ( !tmp.equals(""))) { + editTextMacro.setText(tmp); + macro = tmp; + manageUI(); + saveMacro(); + } else { + Toast.makeText(MacroActivity.this, R.string.empty, Toast.LENGTH_SHORT).show(); + } + } + }); + builder.show(); + } + }); + + + Bundle b = getIntent().getExtras(); + macro = b.getString(Const.EXTRA_MACRO, null); + id = b.getString(Const.EXTRA_ENTRY_ID, null); + + if (b.getBoolean(Const.EXTRA_MACRO_RUN_BUT_EMPTY, false)) { + Toast.makeText(MacroActivity.this, R.string.no_macro_create_new, Toast.LENGTH_LONG).show(); + } + + if (macro == null) { + macro = ""; + setTitle(R.string.add_macro_title); + buttonDelete.setEnabled(false); + buttonSave.setEnabled(false); + } else { + setTitle(R.string.edit_macro_title); + editTextMacro.setText(macro); + } + manageUI(); + } + + private void manageUI() { + if (macro != null) { + if (macro.startsWith(MacroHelper.MACRO_BACKGROUND_EXEC_STRING)) { + radioButtonBackground.setChecked(true); + } + } + } + + private void setExecutionMode(boolean isBackground) { + String tmp = editTextMacro.getText().toString(); + if (isBackground) { + if ((tmp != null) && ( !tmp.startsWith(MacroHelper.MACRO_BACKGROUND_EXEC_STRING))) { + editTextMacro.setText(MacroHelper.MACRO_BACKGROUND_EXEC_STRING + tmp); + } + } else { + if ((tmp != null) && (tmp.startsWith(MacroHelper.MACRO_BACKGROUND_EXEC_STRING))) { + editTextMacro.setText(tmp.substring(MacroHelper.MACRO_BACKGROUND_EXEC_STRING.length())); + } + } + } + + private void addAction(String action, String param) { + String tmp = "%" + action; + if (param != null) { + tmp += "=" + param; + } + + String m = editTextMacro.getText().toString(); + m += tmp; + Toast.makeText(this, getString(R.string.added) + " " + tmp, Toast.LENGTH_SHORT).show(); + if (radioButtonBackground.isChecked()) { + if ( !m.startsWith(MacroHelper.MACRO_BACKGROUND_EXEC_STRING)) { + m = MacroHelper.MACRO_BACKGROUND_EXEC_STRING + m; + } + } + + editTextMacro.setText(m); + } + + private void saveMacro() { + macro = editTextMacro.getText().toString(); + SharedPreferences.Editor editor = prefs.edit(); + if ("".equals(macro)) { + editor.putString(Const.MACRO_PREF_PREFIX + id, null); //do not save empty macro + } else { + editor.putString(Const.MACRO_PREF_PREFIX + id, macro); + } + editor.apply(); + buttonDelete.setEnabled(true); + Toast.makeText(MacroActivity.this, R.string.saved_toast, Toast.LENGTH_SHORT).show(); + } + + private void deleteMacro() { + macro = ""; + SharedPreferences.Editor editor = prefs.edit(); + editor.remove(Const.MACRO_PREF_PREFIX + id); + editor.apply(); + editTextMacro.setText(""); + buttonDelete.setEnabled(false); + Toast.makeText(MacroActivity.this, R.string.deleted_toast, Toast.LENGTH_SHORT).show(); + } + + @Override + public void onBackPressed() { + if ( !editTextMacro.getText().toString().equals(macro)) { + AlertDialog.Builder alert = new AlertDialog.Builder(MacroActivity.this); + alert.setTitle(R.string.save_title); + alert.setMessage(R.string.save_message); + alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + saveMacro(); + finish(); + } + }); + alert.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + finish(); + } + }); + alert.setNeutralButton(R.string.cancel, null); + alert.show(); + } else { + super.onBackPressed(); + } + } + + + + + public CharSequence[] getTemplateNames() { + return new CharSequence[] {getTemplateName(0), getTemplateName(1), getTemplateName(2), getTemplateName(3), getTemplateName(4)}; + } + + public String getTemplateName(int id) { + return prefs.getString(Const.TEMPLATE_NAME_PREF_PREFIX + id, getTemplateDefaultName(id)); + } + + public String getTemplateDefaultName(int id) { + return Const.TEMPLATE_DEFAULT_NAME_PREF_PREFIX + id; + } + + public AlertDialog getSaveTemplateDialog(final int id) { + AlertDialog.Builder alert = new AlertDialog.Builder(this); + alert.setTitle(R.string.template_name); + + final EditText editTextName = new EditText(this); + //display current name if exists, if not, leave empty + if (prefs.contains(Const.TEMPLATE_NAME_PREF_PREFIX + id)) { + editTextName.setText(getTemplateName(id)); + } + final LinearLayout lin= new LinearLayout(this); + lin.setOrientation(LinearLayout.VERTICAL); + lin.addView(editTextName); + alert.setView(lin); + + alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + String name = editTextName.getText().toString(); + //use default name if no name was provided + if ("".equals(name)) { + name = getTemplateDefaultName(id); + } + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(Const.TEMPLATE_NAME_PREF_PREFIX + id, name); + editor.putString(Const.TEMPLATE_PREF_PREFIX + id, editTextMacro.getText().toString()); + editor.apply(); + Toast.makeText(MacroActivity.this, R.string.saved_toast, Toast.LENGTH_SHORT).show(); + } + }); + alert.setNegativeButton(R.string.cancel, null); + return alert.show(); + } + +} diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacroExecuteActivity.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacroExecuteActivity.java new file mode 100644 index 00000000..2baade17 --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacroExecuteActivity.java @@ -0,0 +1,131 @@ +package keepass2android.plugin.inputstick; + +import java.util.ArrayList; +import java.util.List; + +import android.app.Activity; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +public class MacroExecuteActivity extends Activity { + + private long lastActionTime; + private long maxTime; + + private String layoutName; + private List actions; + private int index; + + private Button buttonActionExecute; + private Button buttonActionPrev; + private Button buttonActionNext; + private TextView textViewActionPreview; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.setTheme( android.R.style.Theme_Holo_Dialog); + setContentView(R.layout.activity_macro_execute); + + maxTime = getIntent().getLongExtra(Const.EXTRA_MAX_TIME, 0); + lastActionTime = System.currentTimeMillis(); + + textViewActionPreview = (TextView)findViewById(R.id.textViewActionPreview); + + buttonActionExecute = (Button) findViewById(R.id.buttonActionExecute); + buttonActionExecute.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + if (index >= actions.size()) { + finish(); + } else { + if (checkTime()) { + ActionManager.runMacroAction(layoutName, actions.get(index)); + goToNext(); + } + } + } + }); + + buttonActionPrev = (Button)findViewById(R.id.buttonActionPrev); + buttonActionPrev.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + if (checkTime()) { + goToPrev(); + } + } + }); + + buttonActionNext = (Button)findViewById(R.id.buttonActionNext); + buttonActionNext.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + if (checkTime()) { + goToNext(); + } + } + }); + + layoutName = getIntent().getStringExtra(Const.EXTRA_LAYOUT); + String tmp[] = getIntent().getStringArrayExtra(Const.EXTRA_MACRO_ACTIONS); + if (tmp == null) finish(); + + actions = new ArrayList(); + for (String s : tmp) { + if ((s != null) && (s.length() > 0)) { + if (( !s.startsWith(MacroHelper.MACRO_ACTION_DELAY)) && ( !s.startsWith(MacroHelper.MACRO_BACKGROUND_EXEC_STRING))) { + actions.add(s); + } + } + } + index = 0; + manageUI(); + } + + private void goToPrev() { + if (index > 0) { + index--; + manageUI(); + } + } + + private void goToNext() { + if (index < actions.size()) { + index++; + manageUI(); + } + } + + private void manageUI() { + if (index >= actions.size()) { + textViewActionPreview.setText(R.string.end); + buttonActionExecute.setText(R.string.done); + buttonActionNext.setEnabled(false); + } else { + textViewActionPreview.setText(getString(R.string.current_position) + " " + (index + 1) + "/" + actions.size()); + textViewActionPreview.append("\n" + getString(R.string.preview) + "\n" + actions.get(index)); + buttonActionExecute.setText(R.string.execute); + buttonActionNext.setEnabled(true); + } + if (index == 0) { + buttonActionPrev.setEnabled(false); + } else { + buttonActionPrev.setEnabled(true); + } + } + + private boolean checkTime() { + long now = System.currentTimeMillis(); + if (now > maxTime) { + Toast.makeText(this, R.string.text_locked, Toast.LENGTH_LONG).show(); + return false; + } else { + maxTime += (now - lastActionTime); + lastActionTime = now; + return true; + } + } + +} diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacroHelper.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacroHelper.java new file mode 100644 index 00000000..0b3faa5e --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MacroHelper.java @@ -0,0 +1,243 @@ +package keepass2android.plugin.inputstick; + +import android.annotation.SuppressLint; +import com.inputstick.api.hid.HIDKeycodes; + +public class MacroHelper { + + public static final String MACRO_ACTION_URL = "url"; + public static final String MACRO_ACTION_USER_NAME = "user"; + public static final String MACRO_ACTION_PASSWORD = "pass"; + public static final String MACRO_ACTION_PASSWORD_MASKED = "masked_pass"; + public static final String MACRO_ACTION_CLIPBOARD = "clipboard"; + public static final String MACRO_ACTION_TYPE = "type"; + public static final String MACRO_ACTION_KEY = "key"; + public static final String MACRO_ACTION_DELAY = "delay"; + public static final String MACRO_ACTION_BACKGROUND = "background"; + + public static final String MACRO_BACKGROUND_EXEC_STRING = "%" + MACRO_ACTION_BACKGROUND; + + private static class KeyLabel { + byte keyCode; + String primary; + String secondary; + + public KeyLabel(byte keyCode, String primary, String secondary) { + this.keyCode = keyCode; + this.primary = primary; + this.secondary = secondary; + } + + } + + private static final KeyLabel[] modLUT = { + + new KeyLabel(HIDKeycodes.ALT_LEFT, "alt", "lalt"), + new KeyLabel(HIDKeycodes.CTRL_LEFT, "ctrl", "lctrl"), + new KeyLabel(HIDKeycodes.SHIFT_LEFT, "shift", "lshift"), + new KeyLabel(HIDKeycodes.GUI_LEFT, "gui", "win"), + + new KeyLabel(HIDKeycodes.ALT_RIGHT, "ralt", "altgr"), + new KeyLabel(HIDKeycodes.CTRL_RIGHT, "rctrl", null), + new KeyLabel(HIDKeycodes.SHIFT_RIGHT, "rshift", null), + new KeyLabel(HIDKeycodes.GUI_RIGHT, "rgui", "rwin"), + }; + + private static final KeyLabel[] keyLUT = { + + new KeyLabel(HIDKeycodes.KEY_Q, "q", null), + new KeyLabel(HIDKeycodes.KEY_W, "w", null), + new KeyLabel(HIDKeycodes.KEY_E, "e", null), + new KeyLabel(HIDKeycodes.KEY_R, "r", null), + new KeyLabel(HIDKeycodes.KEY_T, "t", null), + new KeyLabel(HIDKeycodes.KEY_Y, "y", null), + new KeyLabel(HIDKeycodes.KEY_U, "u", null), + new KeyLabel(HIDKeycodes.KEY_I, "i", null), + new KeyLabel(HIDKeycodes.KEY_O, "o", null), + new KeyLabel(HIDKeycodes.KEY_P, "p", null), + new KeyLabel(HIDKeycodes.KEY_LEFT_BRACKET, "[", "{"), + new KeyLabel(HIDKeycodes.KEY_RIGHT_BRACKET, "]", "}"), + + new KeyLabel(HIDKeycodes.KEY_A, "a", null), + new KeyLabel(HIDKeycodes.KEY_S, "s", null), + new KeyLabel(HIDKeycodes.KEY_D, "d", null), + new KeyLabel(HIDKeycodes.KEY_F, "f", null), + new KeyLabel(HIDKeycodes.KEY_G, "g", null), + new KeyLabel(HIDKeycodes.KEY_H, "h", null), + new KeyLabel(HIDKeycodes.KEY_J, "j", null), + new KeyLabel(HIDKeycodes.KEY_K, "k", null), + new KeyLabel(HIDKeycodes.KEY_L, "l", null), + new KeyLabel(HIDKeycodes.KEY_SEMICOLON, ";", ":"), + new KeyLabel(HIDKeycodes.KEY_APOSTROPHE,"'", "\""), + + new KeyLabel(HIDKeycodes.KEY_Z, "z", null), + new KeyLabel(HIDKeycodes.KEY_X, "x", null), + new KeyLabel(HIDKeycodes.KEY_C, "c", null), + new KeyLabel(HIDKeycodes.KEY_V, "v", null), + new KeyLabel(HIDKeycodes.KEY_B, "b", null), + new KeyLabel(HIDKeycodes.KEY_N, "n", null), + new KeyLabel(HIDKeycodes.KEY_M, "m", null), + new KeyLabel(HIDKeycodes.KEY_COMA, ",", "<"), + new KeyLabel(HIDKeycodes.KEY_DOT, ".", ">"), + new KeyLabel(HIDKeycodes.KEY_SLASH, "/", "?"), + new KeyLabel(HIDKeycodes.KEY_BACKSLASH, "\\", "|"), + + new KeyLabel(HIDKeycodes.KEY_GRAVE, "`", "~"), + new KeyLabel(HIDKeycodes.KEY_1, "1", "!"), + new KeyLabel(HIDKeycodes.KEY_2, "2", "@"), + new KeyLabel(HIDKeycodes.KEY_3, "3", "#"), + new KeyLabel(HIDKeycodes.KEY_4, "4", "$"), + new KeyLabel(HIDKeycodes.KEY_5, "5", "%"), + new KeyLabel(HIDKeycodes.KEY_6, "6", "^"), + new KeyLabel(HIDKeycodes.KEY_7, "7", "&"), + new KeyLabel(HIDKeycodes.KEY_8, "8", "*"), + new KeyLabel(HIDKeycodes.KEY_9, "9", "("), + new KeyLabel(HIDKeycodes.KEY_0, "0", ")"), + new KeyLabel(HIDKeycodes.KEY_MINUS, "-", "_"), + new KeyLabel(HIDKeycodes.KEY_EQUALS, "=", "+"), + + new KeyLabel(HIDKeycodes.KEY_BACKSPACE, "backspace", null), + new KeyLabel(HIDKeycodes.KEY_ENTER, "enter", null), + new KeyLabel(HIDKeycodes.KEY_TAB, "tab", null), + new KeyLabel(HIDKeycodes.KEY_SPACEBAR, "space", null), + new KeyLabel(HIDKeycodes.KEY_CAPS_LOCK, "capslock", "caps"), + new KeyLabel(HIDKeycodes.KEY_ESCAPE, "esc", "escape"), + new KeyLabel(HIDKeycodes.KEY_APPLICATION, "application", "app"), + + new KeyLabel(HIDKeycodes.KEY_F1, "f1", null), + new KeyLabel(HIDKeycodes.KEY_F2, "f2", null), + new KeyLabel(HIDKeycodes.KEY_F3, "f3", null), + new KeyLabel(HIDKeycodes.KEY_F4, "f4", null), + new KeyLabel(HIDKeycodes.KEY_F5, "f5", null), + new KeyLabel(HIDKeycodes.KEY_F6, "f6", null), + new KeyLabel(HIDKeycodes.KEY_F7, "f7", null), + new KeyLabel(HIDKeycodes.KEY_F8, "f8", null), + new KeyLabel(HIDKeycodes.KEY_F9, "f9", null), + new KeyLabel(HIDKeycodes.KEY_F10, "f10", null), + new KeyLabel(HIDKeycodes.KEY_F11, "f11", null), + new KeyLabel(HIDKeycodes.KEY_F12, "f12", null), + + new KeyLabel(HIDKeycodes.KEY_PRINT_SCREEN, "printscrn", "printscreen"), + new KeyLabel(HIDKeycodes.KEY_SCROLL_LOCK, "scrolllock", "scroll"), + new KeyLabel(HIDKeycodes.KEY_PASUE, "pause", "break"), + + new KeyLabel(HIDKeycodes.KEY_INSERT, "insert", "ins"), + new KeyLabel(HIDKeycodes.KEY_HOME, "home", null), + new KeyLabel(HIDKeycodes.KEY_PAGE_UP, "pageup", "pgup"), + new KeyLabel(HIDKeycodes.KEY_DELETE, "delete", "del"), + new KeyLabel(HIDKeycodes.KEY_END, "end", null), + new KeyLabel(HIDKeycodes.KEY_PAGE_DOWN, "pagedown", "pgdn"), + + new KeyLabel(HIDKeycodes.KEY_ARROW_LEFT, "left", null), + new KeyLabel(HIDKeycodes.KEY_ARROW_RIGHT, "right", null), + new KeyLabel(HIDKeycodes.KEY_ARROW_UP, "up", null), + new KeyLabel(HIDKeycodes.KEY_ARROW_DOWN, "down", null), + + new KeyLabel(HIDKeycodes.KEY_NUM_1, "num_1", "num_end"), + new KeyLabel(HIDKeycodes.KEY_NUM_2, "num_2", "num_down"), + new KeyLabel(HIDKeycodes.KEY_NUM_3, "num_3", "num_pagedown"), + new KeyLabel(HIDKeycodes.KEY_NUM_4, "num_4", "num_left"), + new KeyLabel(HIDKeycodes.KEY_NUM_5, "num_5", "num_center"), + new KeyLabel(HIDKeycodes.KEY_NUM_6, "num_6", "num_right"), + new KeyLabel(HIDKeycodes.KEY_NUM_7, "num_7", "num_home"), + new KeyLabel(HIDKeycodes.KEY_NUM_8, "num_8", "num_up"), + new KeyLabel(HIDKeycodes.KEY_NUM_9, "num_9", "num_pageup"), + new KeyLabel(HIDKeycodes.KEY_NUM_0, "num_0", "num_insert"), + new KeyLabel(HIDKeycodes.KEY_NUM_ENTER, "num_enter", null), + new KeyLabel(HIDKeycodes.KEY_NUM_DOT, "num_dot", "num_delete"), + new KeyLabel(HIDKeycodes.KEY_NUM_PLUS, "num_3", null), + new KeyLabel(HIDKeycodes.KEY_NUM_MINUS, "num_4", null), + new KeyLabel(HIDKeycodes.KEY_NUM_STAR, "num_5", null), + new KeyLabel(HIDKeycodes.KEY_NUM_SLASH, "num_6", null), + }; + + + public static String[] getKeyList() { + String[] result = new String[keyLUT.length]; + for (int i = 0; i < keyLUT.length; i++) { + result[i] = keyLUT[i].primary; + } + return result; + } + + public static String getParam(String s) { + if ((s != null) && (s.length() > 0)) { + int index = s.indexOf("="); + if (index > 0) { + return s.substring(index + 1); + } + } + return null; + } + + //returns first found non-modifier key only! + public static byte getKey(String param) { + byte key = 0x00; + String[] keys = prepareSearchArray(param); + for (String s : keys) { + if ((s != null) && (s.length() > 0)) { + key = findKey(s); + if (key != 0) { + return key; + } + } + } + return key; + } + + public static byte getModifiers(String param) { + byte modifiers = 0x00; + String[] keys = prepareSearchArray(param); + for (String s : keys) { + if ((s != null) && (s.length() > 0)) { + modifiers |= findMod(s); + } + } + return modifiers; + } + + public static int getDelay(String s) { + int delay = 0; + try { + delay = Integer.parseInt(s); + } catch (Exception e) { + delay = 0; + } + return delay; + } + + @SuppressLint("DefaultLocale") + private static String[] prepareSearchArray(String param) { + param = param.toLowerCase(); + param = param.replace(" ", ""); //remove spaces! + param = param.replace("++", "+="); //handle special case! + return param.split("\\+"); + } + + private static byte findMod(String str) { + return searchLUT(str, modLUT); + } + + private static byte findKey(String str) { + return searchLUT(str, keyLUT); + } + + private static byte searchLUT(String str, KeyLabel[] lut) { + if (str != null) { + for (KeyLabel l : lut) { + if (l.primary != null) { + if (str.equals(l.primary)) { + return l.keyCode; + } + } + if (l.secondary != null) { + if (str.equals(l.secondary)) { + return l.keyCode; + } + } + } + } + return 0; + } + +} diff --git a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/MainActivity.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MainActivity.java similarity index 59% rename from src/java/PluginInputStick/src/keepass2android/plugin/inputstick/MainActivity.java rename to src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MainActivity.java index 8885cdb3..6f799b73 100644 --- a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/MainActivity.java +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MainActivity.java @@ -2,7 +2,6 @@ package keepass2android.plugin.inputstick; import android.app.Activity; import android.app.Fragment; -import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; @@ -18,14 +17,12 @@ public class MainActivity extends Activity { setContentView(R.layout.activity_main); if (savedInstanceState == null) { - getFragmentManager().beginTransaction() - .add(R.id.container, new PlaceholderFragment()).commit(); + getFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; @@ -52,40 +49,10 @@ public class MainActivity extends Activity { } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_main, container, - false); - View btn1 = rootView.findViewById(R.id.button1); - btn1.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - - String textToType = "some text to transfer"; - triggerTypeService(textToType); - } - - }); - - rootView.findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - triggerTypeService(""); - - } - }); - + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_main, container, false); return rootView; } - private void triggerTypeService(String textToType) { - Intent serviceIntent = new Intent(getActivity(), InputStickService.class); - serviceIntent.setAction(InputStickService.TYPE); - - serviceIntent.putExtra(Intent.EXTRA_TEXT, textToType); - getActivity().startService(serviceIntent); - } } } diff --git a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/MaskedPasswordActivity.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MaskedPasswordActivity.java similarity index 71% rename from src/java/PluginInputStick/src/keepass2android/plugin/inputstick/MaskedPasswordActivity.java rename to src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MaskedPasswordActivity.java index ea36c6dd..a5c7e2be 100644 --- a/src/java/PluginInputStick/src/keepass2android/plugin/inputstick/MaskedPasswordActivity.java +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MaskedPasswordActivity.java @@ -1,14 +1,10 @@ package keepass2android.plugin.inputstick; -import java.util.Timer; -import java.util.TimerTask; - import android.app.Activity; import android.graphics.Color; import android.graphics.PorterDuff; import android.os.Bundle; import android.os.Handler; -import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; @@ -18,21 +14,18 @@ import android.widget.Toast; import com.inputstick.api.basic.InputStickHID; import com.inputstick.api.layout.KeyboardLayout; -public class MaskedPasswordActivity extends Activity /*implements InputStickStateListener*/ { - - private static final int TIME = 120; //activity will be available for max TIME [s] +public class MaskedPasswordActivity extends Activity { + private static final int BUTTONS_CNT = 16; private boolean[] wasClicked; + private int offset; private MyButtonOnClickListener listener = new MyButtonOnClickListener(); - private static String password; - private static KeyboardLayout layout; - private static int offset; - - - + private String password; + private KeyboardLayout layout; + private Button buttonPrev; private Button buttonNext; @@ -57,52 +50,31 @@ public class MaskedPasswordActivity extends Activity /*implements InputStickStat R.id.buttonChar16, }; + private String timeLeftMessage; private static int remainingTime; - private static MaskedPasswordActivity me; - private static Timer timer; - protected static void startTimer() { - remainingTime = TIME; - if (timer == null) { - timer = new Timer(); - timer.scheduleAtFixedRate(new TimerTask() { - public void run() { - if (remainingTime > 0) { - remainingTime--; - mHandler.obtainMessage(1).sendToTarget(); - } else { - if (timer != null) { - timer.cancel(); - timer.purge(); - timer = null; - } - } - } - }, 1000, 1000); - } - }; - - private static final Handler mHandler = new Handler() { - public void handleMessage(Message msg) { - if (me != null) { - me.setTitle("Time left: " + remainingTime); - if (remainingTime == 0) { - password = " "; - me.finish(); - } - } + private final Handler mHandler = new Handler(); + private final Runnable tick = new Runnable(){ + public void run(){ + setTitle(timeLeftMessage + " " + (remainingTime/1000)); + if (remainingTime <= 0) { + password = " "; + finish(); + } else { + remainingTime -= 1000; + mHandler.postDelayed(this, 1000); + } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB){ - super.setTheme( android.R.style.Theme_Holo_Dialog); - } + super.setTheme( android.R.style.Theme_Holo_Dialog); setContentView(R.layout.activity_masked_password); + timeLeftMessage = getString(R.string.time_left); + checkBoxShowPassword = (CheckBox)findViewById(R.id.checkBoxShowPassword); buttonPrev = (Button)findViewById(R.id.buttonPrev); buttonNext = (Button)findViewById(R.id.buttonNext); @@ -134,8 +106,6 @@ public class MaskedPasswordActivity extends Activity /*implements InputStickStat buttons[i] = (Button)findViewById(buttonIds[i]); buttons[i].setOnClickListener(listener); } - - me = this; Bundle b = getIntent().getExtras(); if (b != null) { @@ -145,11 +115,12 @@ public class MaskedPasswordActivity extends Activity /*implements InputStickStat } if (savedInstanceState == null) { - setTitle("Time left: " + TIME); - startTimer(); + remainingTime = Const.MASKED_PASSWORD_TIMEOUT_MS; + mHandler.post(tick); } else { offset = savedInstanceState.getInt("offset"); wasClicked = savedInstanceState.getBooleanArray("clicked"); + mHandler.post(tick); } @@ -166,14 +137,13 @@ public class MaskedPasswordActivity extends Activity /*implements InputStickStat @Override protected void onResume() { super.onResume(); - //InputStickHID.addStateListener(this); refreshButtons(); } @Override - protected void onPause() { - //InputStickHID.removeStateListener(this); - super.onPause(); + protected void onDestroy() { + super.onDestroy(); + mHandler.removeCallbacks(tick); } private void drawButton(int i) { @@ -189,7 +159,7 @@ public class MaskedPasswordActivity extends Activity /*implements InputStickStat if (checkBoxShowPassword.isChecked()) { b.setText(String.valueOf(password.charAt(index))); } else { - b.setText(String.valueOf(index)); + b.setText(String.valueOf(index + 1)); } if (wasClicked[index]) { @@ -225,7 +195,6 @@ public class MaskedPasswordActivity extends Activity /*implements InputStickStat if (index < 0) return; char c = password.charAt(index); String toType = String.valueOf(c); - //System.out.println("TYPE: "+toType); if ((InputStickHID.isReady()) && (layout != null)) { layout.type(toType); } else { @@ -248,8 +217,4 @@ public class MaskedPasswordActivity extends Activity /*implements InputStickStat } } - /*@Override - public void onStateChanged(int state) { - refreshButtons(); - }*/ } diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MigrationMessageActivity.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MigrationMessageActivity.java new file mode 100644 index 00000000..1ec9c821 --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MigrationMessageActivity.java @@ -0,0 +1,78 @@ +package keepass2android.plugin.inputstick; + +import android.app.Activity; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.NotificationCompat; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.Toast; + +public class MigrationMessageActivity extends Activity { + + public static long lastToast; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_migration_message); + + Button button = (Button)findViewById(R.id.buttonMigrationAction); + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + try { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.inputstick.apps.kp2aplugin"))); + } catch (android.content.ActivityNotFoundException anfe) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=com.inputstick.apps.kp2aplugin"))); + } + } + }); + } + + @Override + protected void onPause() { + SharedPreferences.Editor edit = PreferenceManager.getDefaultSharedPreferences(MigrationMessageActivity.this).edit(); + edit.putBoolean("show_migration_message_activity", false); + edit.apply(); + super.onPause(); + } + + public static void displayNotification(Context ctx) { + NotificationManager mNotificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE); + NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctx); + + Intent intent = new Intent(ctx, MigrationMessageActivity.class); + PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0, intent, 0); + + mBuilder.setContentTitle(ctx.getString(R.string.app_name)); + mBuilder.setContentText(ctx.getString(R.string.update_required)); + mBuilder.setSmallIcon(R.drawable.ic_notification); + mBuilder.setAutoCancel(true); + mBuilder.setOngoing(true); + mBuilder.setContentIntent(pendingIntent); + mNotificationManager.notify(0, mBuilder.build()); + + long now = System.currentTimeMillis(); + if (now > lastToast + 86400000) { + lastToast = now; + Toast.makeText(ctx, ctx.getString(R.string.app_name) + ": " + ctx.getString(R.string.update_required), Toast.LENGTH_SHORT).show(); + } + } + + public static void hideNotification(Context ctx) { + NotificationManager mNotificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE); + mNotificationManager.cancel(0); + } + + public static boolean shouldShowActivity(SharedPreferences sharedPref) { + return sharedPref.getBoolean("show_migration_message_activity", true); + } + +} diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MultiSelectListPreference.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MultiSelectListPreference.java new file mode 100644 index 00000000..b0d19ffe --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/MultiSelectListPreference.java @@ -0,0 +1,133 @@ +package keepass2android.plugin.inputstick; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; + +import android.app.AlertDialog.Builder; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnMultiChoiceClickListener; +import android.preference.ListPreference; +import android.util.AttributeSet; + +public class MultiSelectListPreference extends ListPreference { + + public static final String SEPARATOR = "|"; + + private boolean[] checkedEntryIndexes; + + + public static boolean isEmpty(CharSequence str) { + return str == null || str.length() == 0; + } + + public static String[] fromPersistedPreferenceValue(String val) { + if (isEmpty(val)) { + return new String[0]; + } else { + return val.split("\\" + SEPARATOR); + } + } + + public static String toPersistedPreferenceValue(CharSequence... entryKeys) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < entryKeys.length; i++) { + sb.append(entryKeys[i]); + if (i < entryKeys.length - 1) { + sb.append(SEPARATOR); + } + } + return sb.toString(); + } + + public CharSequence[] getCheckedEntries() { + CharSequence[] entries = getEntries(); + ArrayList checkedEntries = new ArrayList(); + for (int i = 0; i < entries.length; i++) { + if (checkedEntryIndexes[i]) { + checkedEntries.add(entries[i]); + } + } + return checkedEntries.toArray(new String[checkedEntries.size()]); + } + + public String getSummary() { + String tmp = ""; + CharSequence[] entries = getEntries(); + for (int i = 0; i < entries.length; i++) { + if (checkedEntryIndexes[i]) { + if (tmp.length() > 0) { + tmp += ", "; + } + tmp += entries[i]; + } + } + if (tmp.length() == 0) { + tmp = "None"; + } + return tmp; + } + + + public MultiSelectListPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public MultiSelectListPreference(Context context) { + super(context); + } + + @Override + public void setEntries(CharSequence[] entries) { + super.setEntries(entries); + updateCheckedEntryIndexes(); + } + + @Override + public void setValue(String value) { + super.setValue(value); + updateCheckedEntryIndexes(); + } + + @Override + protected void onPrepareDialogBuilder(Builder builder) { + updateCheckedEntryIndexes(); + builder.setMultiChoiceItems(getEntries(), checkedEntryIndexes, new OnMultiChoiceClickListener() { + @Override + public void onClick(DialogInterface dialog, int which, boolean isChecked) { + checkedEntryIndexes[which] = isChecked; + } + }); + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + if (positiveResult) { + CharSequence[] entryVals = getEntryValues(); + ArrayList checkedVals = new ArrayList(); + for (int i = 0; i < entryVals.length; i++) { + if (checkedEntryIndexes[i]) { + checkedVals.add(entryVals[i]); + } + } + String val = toPersistedPreferenceValue(checkedVals.toArray(new CharSequence[checkedVals.size()])); + if (callChangeListener(val)) { + setValue(val); + } + } + } + + private void updateCheckedEntryIndexes() { + CharSequence[] entryVals = getEntryValues(); + checkedEntryIndexes = new boolean[entryVals.length]; + String val = getValue(); + if (val != null) { + HashSet checkedEntryVals = new HashSet(Arrays.asList(fromPersistedPreferenceValue(val))); + for (int i = 0; i < entryVals.length; i++) { + checkedEntryIndexes[i] = checkedEntryVals.contains(entryVals[i]); + } + } + } + +} \ No newline at end of file diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/OnUpgradeBroadcastReceiver.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/OnUpgradeBroadcastReceiver.java new file mode 100644 index 00000000..d865408a --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/OnUpgradeBroadcastReceiver.java @@ -0,0 +1,14 @@ +package keepass2android.plugin.inputstick; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class OnUpgradeBroadcastReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context ctx, Intent arg1) { + MigrationMessageActivity.displayNotification(ctx); + } + +} diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/SettingsActivity.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/SettingsActivity.java new file mode 100644 index 00000000..91c3f3f5 --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/SettingsActivity.java @@ -0,0 +1,362 @@ +package keepass2android.plugin.inputstick; + +import keepass2android.pluginsdk.AccessManager; +import keepass2android.pluginsdk.Strings; +import sheetrock.panda.changelog.ChangeLog; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.net.Uri; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceActivity; +import android.preference.PreferenceManager; +import android.widget.CheckBox; +import android.widget.Toast; + + +@SuppressWarnings("deprecation") +public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener { + + + public static final String ITEMS_GENERAL = "items_general"; + public static final String ITEMS_ENTRY_PRIMARY = "items_entry_primary"; + public static final String ITEMS_FIELD_PRIMARY = "items_field_primary"; + public static final String ITEMS_ENTRY_SECONDARY = "items_entry_secondary"; + public static final String ITEMS_FIELD_SECONDARY = "items_field_secondary"; + + //IMPORTANT: checked using .contains() ! + //username_password_only + //general + public static final String ITEM_SETTINGS = "settings"; + public static final String ITEM_CONNECTION = "con_disc"; + public static final String ITEM_MAC_SETUP = "osx"; + public static final String ITEM_TAB_ENTER = "tab_enter"; + public static final String ITEM_MACRO = "macro"; + //entry + public static final String ITEM_USER_PASSWORD = "username_and_password"; + public static final String ITEM_USER_PASSWORD_ENTER = "username_password_enter"; + public static final String ITEM_MASKED = "masked_password"; + public static final String ITEM_CLIPBOARD = "clipboard"; + + //field + public static final String ITEM_TYPE = "type_normal"; + public static final String ITEM_TYPE_SLOW = "type_slow"; + + private static final String[] PREFS_UI_GENERAL = {"show_settings", "show_mac_setup", "show_tab_enter"}; + private static final String[] PREFS_UI_ENTRY_PRIMARY = {"show_user_pass", "show_user_pass_enter", "show_masked"}; + private static final String[] PREFS_UI_FIELD_PRIMARY = {"show_field_type", "show_field_type_slow"}; + private static final String[] PREFS_UI_ENTRY_SECONDARY = {"show_user_pass_secondary", "show_user_pass_enter_secondary", "show_masked_secondary"}; + private static final String[] PREFS_UI_FIELD_SECONDARY = {"show_field_type_secondary", "show_field_type_slow_secondary"}; + + private static final String[] NAMES_UI_GENERAL = {ITEM_SETTINGS, ITEM_MAC_SETUP, ITEM_TAB_ENTER}; + private static final String[] NAMES_UI_ENTRY = {ITEM_USER_PASSWORD, ITEM_USER_PASSWORD_ENTER, ITEM_MASKED}; + private static final String[] NAMES_UI_FIELD = {ITEM_TYPE, ITEM_TYPE_SLOW}; + + + private SharedPreferences sharedPref; + + private Preference prefShowSecondary; + private Preference prefSecondaryKbdLayout; + + private Preference prefAutoconnectTimeout; + private Preference prefUiEntrySecondary; + private Preference prefUiFieldSecondary; + + private boolean displayReloadInfo; + private OnPreferenceClickListener reloadInfoListener = new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + displayReloadInfo = true; + return false; + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + sharedPref = PreferenceManager.getDefaultSharedPreferences(this); + + convertOldUiPreferences(sharedPref, this); + + addPreferencesFromResource(R.layout.activity_settings); + setupSimplePreferencesScreen(); + + //ask user to download new release of the plugin (force display activity only once, use only notification next time) + if (MigrationMessageActivity.shouldShowActivity(sharedPref)) { + startActivity(new Intent(this, MigrationMessageActivity.class)); + } + } + + + private void setupSimplePreferencesScreen() { + Preference pref; + + setListSummary("kbd_layout"); + setListSummary("secondary_kbd_layout"); + setListSummary("typing_speed"); + setListSummary("autoconnect_timeout"); + + pref = findPreference("enable_plugin_pref"); + pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + try { + Intent i = new Intent( Strings.ACTION_EDIT_PLUGIN_SETTINGS); + i.putExtra(Strings.EXTRA_PLUGIN_PACKAGE, SettingsActivity.this.getPackageName()); + startActivityForResult(i, 123); + } catch (Exception e) { + e.printStackTrace(); + } + return true; + } + }); + + pref = (Preference)findPreference("show_changelog_preference_key"); + pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + new ChangeLog(SettingsActivity.this).getFullLogDialog().show(); + return true; + } + }); + + pref = (Preference)findPreference("show_help_webpage_key"); + pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.inputstick.com/help"))); + return true; + } + }); + + pref = (Preference)findPreference("show_source_key"); + pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/inputstick"))); + return true; + } + }); + + //typing: + findPreference("kbd_layout").setOnPreferenceClickListener(reloadInfoListener); + prefShowSecondary = (Preference) findPreference("show_secondary"); + prefShowSecondary.setOnPreferenceClickListener(reloadInfoListener); + prefShowSecondary.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean enabled = (Boolean)newValue; + setSecondaryLayoutEnabled(enabled); + if (enabled) { + //check if at least one action is enabled + boolean showMessage = true; + String tmp; + tmp = sharedPref.getString(SettingsActivity.ITEMS_FIELD_SECONDARY, null); + if ((tmp != null) && (tmp.length() > 1)) { + showMessage = false; + } + tmp = sharedPref.getString(SettingsActivity.ITEMS_ENTRY_SECONDARY, null); + if ((tmp != null) && (tmp.length() > 1)) { + showMessage = false; + } + if (showMessage) { + AlertDialog.Builder alert = new AlertDialog.Builder(SettingsActivity.this); + + alert.setTitle(R.string.configuration_title); + alert.setMessage(R.string.secondary_layout_action_reminder_message); + alert.setPositiveButton(R.string.ok, null); + alert.show(); + } + } + return true; + } + }); + prefSecondaryKbdLayout = findPreference("secondary_kbd_layout"); + prefSecondaryKbdLayout.setOnPreferenceClickListener(reloadInfoListener); + + //connection: + pref = (Preference) findPreference("autoconnect"); + pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + setAutoconnectTimeoutEnabled((Boolean)newValue); + displayReloadInfo = true; + return true; + } + }); + + prefAutoconnectTimeout = (Preference) findPreference("autoconnect_timeout"); + prefAutoconnectTimeout.setOnPreferenceClickListener(reloadInfoListener); + + + //UI: + findPreference("display_inputstick_text").setOnPreferenceClickListener(reloadInfoListener); + findPreference("items_general").setOnPreferenceClickListener(reloadInfoListener); + findPreference("items_entry_primary").setOnPreferenceClickListener(reloadInfoListener); + findPreference("items_field_primary").setOnPreferenceClickListener(reloadInfoListener); + prefUiEntrySecondary = findPreference("items_entry_secondary"); + prefUiEntrySecondary.setOnPreferenceClickListener(reloadInfoListener); + prefUiFieldSecondary = findPreference("items_field_secondary"); + prefUiFieldSecondary.setOnPreferenceClickListener(reloadInfoListener); + + setSecondaryLayoutEnabled(sharedPref.getBoolean("show_secondary", false)); + setAutoconnectTimeoutEnabled(sharedPref.getBoolean("autoconnect", true)); + } + + @Override + protected void onResume() { + super.onResume(); + getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); + displayReloadInfo = false; + Preference enablePref = findPreference("enable_plugin_pref"); + if (AccessManager.getAllHostPackages(SettingsActivity.this).isEmpty()) { + enablePref.setSummary(R.string.not_configured); + } else { + enablePref.setSummary(R.string.enabled); + } + + MigrationMessageActivity.displayNotification(this); + } + + @Override + protected void onPause() { + getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); + ActionManager.reloadPreferences(); + MigrationMessageActivity.hideNotification(this); + super.onPause(); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + setListSummary(key); + } + + private void setListSummary(String key) { + Preference pref; + ListPreference listPref; + pref = findPreference(key); + if (pref instanceof ListPreference) { + listPref = (ListPreference) pref; + pref.setSummary(listPref.getEntry()); + } + } + + + @Override + public void onBackPressed() { + boolean kp2a = getIntent().getBooleanExtra(Const.EXTRA_LAUNCHED_FROM_KP2A, false); //show warning only if activity was launched from kp2a app, + boolean showWarning = sharedPref.getBoolean("show_reload_warning", true); //show warning only if user did not checked "do not show again" before + //show warning only if it is necessary to reload entry + if (kp2a && displayReloadInfo) { + if (showWarning) { + displayReloadInfo = false; + AlertDialog.Builder alert = new AlertDialog.Builder(this); + alert.setTitle(R.string.important_title); + alert.setMessage(R.string.entry_reload_message); + + final CheckBox cb = new CheckBox(this); + cb.setText(R.string.do_not_remind); + cb.setChecked(false); + alert.setView(cb); + + alert.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + SettingsActivity.this.onBackPressed(); + if (cb.isChecked()) { + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putBoolean("show_reload_warning", false); + editor.apply(); + } + } + }); + alert.show(); + } else { + //just toast, used does not want to see dialog msg + Toast.makeText(this, R.string.entry_reload_message, Toast.LENGTH_LONG).show(); + super.onBackPressed(); + } + } else { + super.onBackPressed(); + } + } + + + private void setAutoconnectTimeoutEnabled(boolean enabled) { + prefAutoconnectTimeout.setEnabled( !enabled); // show this pref only if autoconnect is DISABLED + } + + private void setSecondaryLayoutEnabled(boolean enabled) { + prefUiEntrySecondary.setEnabled(enabled); + prefUiFieldSecondary.setEnabled(enabled); + prefSecondaryKbdLayout.setEnabled(enabled); + } + + + + + //converting old preferences to new ones: + public static void convertOldUiPreferences(SharedPreferences sharedPref, Context ctx) { + //if this is a fresh install, UI display preferences will be set to default values anyway + ChangeLog cl = new ChangeLog(ctx); + if ( !cl.firstRunEver()) { + //if ITEMS_GENERAL exista -> already converted + if ( !sharedPref.contains(ITEMS_GENERAL)) { + final SharedPreferences.Editor editor = sharedPref.edit(); + //editor.putBoolean("convert_old_ui_preferences", false); + editor.putString(ITEMS_GENERAL, getMultiSelectPreferenceString(sharedPref, PREFS_UI_GENERAL, NAMES_UI_GENERAL, true, false)); + editor.putString(ITEMS_ENTRY_PRIMARY, getMultiSelectPreferenceString(sharedPref, PREFS_UI_ENTRY_PRIMARY, NAMES_UI_ENTRY, true, true)); + editor.putString(ITEMS_FIELD_PRIMARY, getMultiSelectPreferenceString(sharedPref, PREFS_UI_FIELD_PRIMARY, NAMES_UI_FIELD, false, false)); + editor.putString(ITEMS_ENTRY_SECONDARY, getMultiSelectPreferenceString(sharedPref, PREFS_UI_ENTRY_SECONDARY, NAMES_UI_ENTRY, true, true)); + editor.putString(ITEMS_FIELD_SECONDARY, getMultiSelectPreferenceString(sharedPref, PREFS_UI_FIELD_SECONDARY, NAMES_UI_FIELD, false, false)); + editor.commit(); + } + } else { + //make sure ITEMS_GENERAL exists + if ( !sharedPref.contains(ITEMS_GENERAL)) { + final SharedPreferences.Editor editor = sharedPref.edit(); + editor.putString(ITEMS_GENERAL, "settings|osx|tab_enter|macro"); + editor.commit(); + } + } + cl.updateVersionInPreferences(); + } + + private static String getMultiSelectPreferenceString(SharedPreferences sharedPref, String[] prefs, String[] names, boolean addMacro, boolean addClipboard) { + String tmp = ""; + boolean addSeparator = false; + if (prefs != null) { + for (int i = 0; i < prefs.length; i++) { + if ((sharedPref.contains(prefs[i])) && (sharedPref.getBoolean(prefs[i], true))) { + if (addSeparator) { + tmp += MultiSelectListPreference.SEPARATOR; // "|" + } + tmp += names[i]; + addSeparator = true; + } + } + if (addMacro) { + if (addSeparator) { + tmp += MultiSelectListPreference.SEPARATOR; + } + tmp += ITEM_MACRO; + addSeparator = true; + } + if (addClipboard) { + if (addSeparator) { + tmp += MultiSelectListPreference.SEPARATOR; + } + tmp += ITEM_CLIPBOARD; + } + } + return tmp; + } + + +} diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/UserPreferences.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/UserPreferences.java new file mode 100644 index 00000000..f4c83fbc --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/keepass2android/plugin/inputstick/UserPreferences.java @@ -0,0 +1,273 @@ +package keepass2android.plugin.inputstick; + +import android.content.SharedPreferences; + +public class UserPreferences { + + private SharedPreferences prefs; + + private String layoutPrimary; + private String layoutSecondary; + private String layoutPrimaryDisplayCode; + private String layoutSecondaryDisplayCode; + + private boolean showSecondary; + private boolean enterAfterURL; + private boolean autoConnect; + private int autoConnectTimeout; + private boolean disconnectOnClose; + private int reportMultiplier; + + private String macro; + private String entryId; + + //clipboard + private boolean clipboardLaunchAuthenticator; + private boolean clipboardAutoDisable; + private boolean clipboardAutoEnter; + + private boolean displayInputstickText; + //general + private boolean showSettings; + private boolean showConnectionOptions; + private boolean showMacSetup; + private boolean showTabEnter; + private boolean showMacroAddEdit; + //entry + private boolean showUserPass; + private boolean showUserPassEnter; + private boolean showMasked; + private boolean showMacro; + private boolean showClipboard; + private boolean showUserPassSec; + private boolean showUserPassEnterSec; + private boolean showMaskedSec; + private boolean showMacroSec; + private boolean showClipboardSec; + //item + private boolean showType; + private boolean showTypeSlow; + private boolean showTypeSec; + private boolean showTypeSlowSec; + + + public UserPreferences(SharedPreferences prefs, String id) { + this.prefs = prefs; + entryId = id; + reload(); + } + + public void reload() { + getMacro(); //is always reloaded + + layoutPrimary = prefs.getString("kbd_layout", "en-US"); + layoutSecondary = prefs.getString("secondary_kbd_layout", "en-US"); + showSecondary = prefs.getBoolean("show_secondary", false); + + if (showSecondary) { + // display layout codes only if secondary layout is enabled + layoutPrimaryDisplayCode = layoutPrimary; + layoutSecondaryDisplayCode = layoutSecondary; + } + enterAfterURL = prefs.getBoolean("enter_after_url", false); + + reportMultiplier = 1; + try { + reportMultiplier = Integer.parseInt(prefs.getString("typing_speed", "1")); + } catch (Exception e) { + reportMultiplier = 1; + } + + disconnectOnClose = !prefs.getBoolean("do_not_disconnect", false); + autoConnectTimeout = Const.DEFAULT_AUTOCONNECT_TIMEOUT_MS; + try { + autoConnectTimeout = Integer.parseInt(prefs.getString("autoconnect_timeout", "600000")); + } catch (Exception e) { + autoConnectTimeout = Const.DEFAULT_AUTOCONNECT_TIMEOUT_MS; + } + + displayInputstickText = prefs.getBoolean("display_inputstick_text", true); + String tmp; + tmp = prefs.getString("items_general", "settings|osx|tab_enter|macro"); + showSettings = tmp.contains(SettingsActivity.ITEM_SETTINGS); + showConnectionOptions = tmp.contains(SettingsActivity.ITEM_CONNECTION); + showMacSetup = tmp.contains(SettingsActivity.ITEM_MAC_SETUP); + showTabEnter = tmp.contains(SettingsActivity.ITEM_TAB_ENTER); + showMacroAddEdit = tmp.contains(SettingsActivity.ITEM_MACRO); + + + + + tmp = prefs.getString(SettingsActivity.ITEMS_ENTRY_PRIMARY, "username_and_password|username_password_enter|masked_password|macro|clipboard"); + showUserPass = tmp.contains(SettingsActivity.ITEM_USER_PASSWORD); + showUserPassEnter = tmp.contains(SettingsActivity.ITEM_USER_PASSWORD_ENTER); + showMasked = tmp.contains(SettingsActivity.ITEM_MASKED); + showMacro = tmp.contains(SettingsActivity.ITEM_MACRO); + showClipboard = tmp.contains(SettingsActivity.ITEM_CLIPBOARD); + + if (showSecondary) { + tmp = prefs.getString(SettingsActivity.ITEMS_ENTRY_SECONDARY, "username_and_password|username_password_enter|masked_password|macro|clipboard"); + showUserPassSec = tmp.contains(SettingsActivity.ITEM_USER_PASSWORD); + showUserPassEnterSec = tmp.contains(SettingsActivity.ITEM_USER_PASSWORD_ENTER); + showMaskedSec = tmp.contains(SettingsActivity.ITEM_MASKED); + showMacroSec = tmp.contains(SettingsActivity.ITEM_MACRO); + showClipboardSec = tmp.contains(SettingsActivity.ITEM_CLIPBOARD); + } + + tmp = prefs.getString(SettingsActivity.ITEMS_FIELD_PRIMARY, "type_normal|type_slow"); + showType = tmp.contains(SettingsActivity.ITEM_TYPE); + showTypeSlow = tmp.contains(SettingsActivity.ITEM_TYPE_SLOW); + + if (showSecondary) { + tmp = prefs.getString(SettingsActivity.ITEMS_FIELD_SECONDARY, "type_normal|type_slow"); + showTypeSec = tmp.contains(SettingsActivity.ITEM_TYPE); + showTypeSlowSec = tmp.contains(SettingsActivity.ITEM_TYPE_SLOW); + } + + clipboardLaunchAuthenticator = prefs.getBoolean("clipboard_launch_authenticator", true); + clipboardAutoDisable = prefs.getBoolean("clipboard_auto_disable", true); + clipboardAutoEnter = prefs.getBoolean("clipboard_auto_enter", false); + + } + + + public String getLayoutPrimary() { + return layoutPrimary; + } + + public String getLayoutSecondary() { + return layoutSecondary; + } + + public String getLayoutPrimaryDisplayCode() { + return layoutPrimaryDisplayCode; + } + + public String getLayoutSecondaryDisplayCode() { + return layoutSecondaryDisplayCode; + } + + public boolean isShowSecondary() { + return showSecondary; + } + + public boolean isEnterAfterURL() { + return enterAfterURL; + } + + public boolean isAutoConnect() { + return autoConnect; + } + + public int getAutoConnectTimeout() { + return autoConnectTimeout; + } + + public boolean isDisconnectOnClose() { + return disconnectOnClose; + } + + public int getReportMultiplier() { + return reportMultiplier; + } + + + + public boolean isDisplayInputStickText() { + return displayInputstickText; + } + + public boolean isShowSettings() { + return showSettings; + } + public boolean isShowConnectionOptions() { + return showConnectionOptions; + } + public boolean isShowMacSetup() { + return showMacSetup; + } + public boolean isShowTabEnter() { + return showTabEnter; + } + public boolean isShowMacroAddEdit() { + return showMacroAddEdit; + } + + public boolean isShowClipboard(boolean isPrimary) { + if (isPrimary) { + return showClipboard; + } else { + return showClipboardSec; + } + } + + public boolean isShowUserPass(boolean isPrimary) { + if (isPrimary) { + return showUserPass; + } else { + return showUserPassSec; + } + } + + public boolean isShowUserPassEnter(boolean isPrimary) { + if (isPrimary) { + return showUserPassEnter; + } else { + return showUserPassEnterSec; + } + } + + public boolean isShowMasked(boolean isPrimary) { + if (isPrimary) { + return showMasked; + } else { + return showMaskedSec; + } + } + + public boolean isShowType(boolean isPrimary) { + if (isPrimary) { + return showType; + } else { + return showTypeSec; + } + } + + public boolean isShowTypeSlow(boolean isPrimary) { + if (isPrimary) { + return showTypeSlow; + } else { + return showTypeSlowSec; + } + } + + public boolean isShowMacro(boolean isPrimary) { + if (isPrimary) { + return showMacro; + } else { + return showMacroSec; + } + } + + public String getMacro() { + macro = prefs.getString(Const.MACRO_PREF_PREFIX + entryId, null); + return macro; + } + + public String getEntryId() { + return entryId; + } + + + public boolean isClipboardLaunchAuthenticator() { + return clipboardLaunchAuthenticator; + } + public boolean isClipboardAutoDisable() { + return clipboardAutoDisable; + } + public boolean isClipboardAutoEnter() { + return clipboardAutoEnter; + } + + +} diff --git a/src/java/PluginInputStick/src/sheetrock/panda/changelog/ChangeLog.java b/src/java/PluginInputStick3/pluginInputStick/src/main/java/sheetrock/panda/changelog/ChangeLog.java similarity index 99% rename from src/java/PluginInputStick/src/sheetrock/panda/changelog/ChangeLog.java rename to src/java/PluginInputStick3/pluginInputStick/src/main/java/sheetrock/panda/changelog/ChangeLog.java index b08e876b..b90714db 100644 --- a/src/java/PluginInputStick/src/sheetrock/panda/changelog/ChangeLog.java +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/java/sheetrock/panda/changelog/ChangeLog.java @@ -164,7 +164,7 @@ public class ChangeLog { // OK button .setPositiveButton( context.getResources().getString( - R.string.changelog_ok_button), + R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { @@ -185,7 +185,7 @@ public class ChangeLog { return builder.create(); } - private void updateVersionInPreferences() { + public void updateVersionInPreferences() { // save new version number to preferences SharedPreferences sp = PreferenceManager .getDefaultSharedPreferences(context); diff --git a/src/java/PluginInputStick/res/drawable-hdpi/ic_launcher.png b/src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-hdpi/ic_launcher.png similarity index 100% rename from src/java/PluginInputStick/res/drawable-hdpi/ic_launcher.png rename to src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-hdpi/ic_launcher.png diff --git a/src/java/PluginInputStick/res/drawable-hdpi/ic_notification.png b/src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-hdpi/ic_notification.png similarity index 100% rename from src/java/PluginInputStick/res/drawable-hdpi/ic_notification.png rename to src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-hdpi/ic_notification.png diff --git a/src/java/PluginInputStick/res/drawable-mdpi/ic_launcher.png b/src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-mdpi/ic_launcher.png similarity index 100% rename from src/java/PluginInputStick/res/drawable-mdpi/ic_launcher.png rename to src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-mdpi/ic_launcher.png diff --git a/src/java/PluginInputStick/res/drawable-mdpi/ic_notification.png b/src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-mdpi/ic_notification.png similarity index 100% rename from src/java/PluginInputStick/res/drawable-mdpi/ic_notification.png rename to src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-mdpi/ic_notification.png diff --git a/src/java/PluginInputStick/res/drawable-xhdpi/ic_launcher.png b/src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-xhdpi/ic_launcher.png similarity index 100% rename from src/java/PluginInputStick/res/drawable-xhdpi/ic_launcher.png rename to src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-xhdpi/ic_launcher.png diff --git a/src/java/PluginInputStick/res/drawable-xhdpi/ic_notification.png b/src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-xhdpi/ic_notification.png similarity index 100% rename from src/java/PluginInputStick/res/drawable-xhdpi/ic_notification.png rename to src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-xhdpi/ic_notification.png diff --git a/src/java/PluginInputStick/res/drawable-xxhdpi/ic_launcher.png b/src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-xxhdpi/ic_launcher.png similarity index 100% rename from src/java/PluginInputStick/res/drawable-xxhdpi/ic_launcher.png rename to src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-xxhdpi/ic_launcher.png diff --git a/src/java/PluginInputStick/res/drawable-xxhdpi/ic_notification.png b/src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-xxhdpi/ic_notification.png similarity index 100% rename from src/java/PluginInputStick/res/drawable-xxhdpi/ic_notification.png rename to src/java/PluginInputStick3/pluginInputStick/src/main/res/drawable-xxhdpi/ic_notification.png diff --git a/src/java/PluginInputStick3/pluginInputStick/src/main/res/layout/activity_all_actions.xml b/src/java/PluginInputStick3/pluginInputStick/src/main/res/layout/activity_all_actions.xml new file mode 100644 index 00000000..13c355b7 --- /dev/null +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/res/layout/activity_all_actions.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/src/java/PluginInputStick/res/layout/activity_mac_setup.xml b/src/java/PluginInputStick3/pluginInputStick/src/main/res/layout/activity_mac_setup.xml similarity index 92% rename from src/java/PluginInputStick/res/layout/activity_mac_setup.xml rename to src/java/PluginInputStick3/pluginInputStick/src/main/res/layout/activity_mac_setup.xml index c040574d..dad6e759 100644 --- a/src/java/PluginInputStick/res/layout/activity_mac_setup.xml +++ b/src/java/PluginInputStick3/pluginInputStick/src/main/res/layout/activity_mac_setup.xml @@ -2,6 +2,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:padding="10dp" tools:context="${relativePackage}.${activityClass}" > + android:text="@string/osx_shift_key" />