update InputStick Plugin to 1.31

This commit is contained in:
Philipp Crocoll 2015-06-23 17:25:27 +02:00
parent 137fdd8d28
commit ede97fc726
67 changed files with 6391 additions and 784 deletions

View File

@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@ -0,0 +1,8 @@
<resources>
<!--
Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw600dp devices (e.g. 7" tablets) here.
-->
</resources>

View File

@ -0,0 +1,9 @@
<resources>
<!--
Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
-->
<dimen name="activity_horizontal_margin">128dp</dimen>
</resources>

View File

@ -0,0 +1,7 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

View File

@ -16,6 +16,7 @@ public class BTConnectionManager extends ConnectionManager implements InitManage
private String mMac; private String mMac;
private byte[] mKey; private byte[] mKey;
private boolean mIsBT40;
private InitManager mInitManager; private InitManager mInitManager;
private Application mApp; private Application mApp;
@ -74,28 +75,29 @@ public class BTConnectionManager extends ConnectionManager implements InitManage
disconnect(); disconnect();
} }
private void onData(byte[] rawData) { @Override
protected void onData(byte[] rawData) {
byte[] data; byte[] data;
data = mPacketManager.bytesToPacket(rawData); data = mPacketManager.bytesToPacket(rawData);
if (data == null) { if (data == null) {
//TODO failure? //TODO failure?
return; return;
} }
mInitManager.onData(data); mInitManager.onData(data);
super.onData(data);
for (InputStickDataListener listener : mDataListeners) {
listener.onInputStickData(data);
}
} }
public BTConnectionManager(InitManager initManager, Application app, String mac, byte[] key, boolean isBT40) {
public BTConnectionManager(InitManager initManager, Application app, String mac, byte[] key) {
mInitManager = initManager; mInitManager = initManager;
mMac = mac; mMac = mac;
mKey = key; mKey = key;
mApp = app; mApp = app;
mIsBT40 = isBT40;
}
public BTConnectionManager(InitManager initManager, Application app, String mac, byte[] key) {
this(initManager, app, mac, key, false);
} }
@Override @Override
@ -112,7 +114,7 @@ public class BTConnectionManager extends ConnectionManager implements InitManage
} }
mBTService.setConnectTimeout(timeout); mBTService.setConnectTimeout(timeout);
mBTService.enableReflection(reflection); mBTService.enableReflection(reflection);
mBTService.connect(mMac, doNotAsk); mBTService.connect(mMac, doNotAsk, mIsBT40);
onConnecting(); onConnecting();
} }

View File

@ -15,7 +15,7 @@ public abstract class ConnectionManager {
protected Vector<InputStickDataListener> mDataListeners = new Vector<InputStickDataListener>(); protected Vector<InputStickDataListener> mDataListeners = new Vector<InputStickDataListener>();
protected int mState; protected int mState;
protected int mErrorCode; protected int mErrorCode;
public abstract void connect(); public abstract void connect();
public abstract void disconnect(); public abstract void disconnect();
@ -41,10 +41,33 @@ public abstract class ConnectionManager {
return mState; 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() { public int getErrorCode() {
return mErrorCode; return mErrorCode;
} }
protected void onData(byte[] data) {
for (InputStickDataListener listener : mDataListeners) {
listener.onInputStickData(data);
}
}
public void addStateListener(InputStickStateListener listener) { public void addStateListener(InputStickStateListener listener) {
if (listener != null) { if (listener != null) {
if ( !mStateListeners.contains(listener)) { if ( !mStateListeners.contains(listener)) {

View File

@ -63,7 +63,7 @@ public class HIDInfo {
mouseReportProtocol = true; mouseReportProtocol = true;
} else { } else {
mouseReportProtocol = false; mouseReportProtocol = false;
} }
if (data[6] == 0) { if (data[6] == 0) {
mouseReady = false; mouseReady = false;

View File

@ -14,7 +14,6 @@ import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
import android.os.RemoteException;
public class IPCConnectionManager extends ConnectionManager { public class IPCConnectionManager extends ConnectionManager {
@ -39,22 +38,24 @@ public class IPCConnectionManager extends ConnectionManager {
} }
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
if (ref == null) return;
IPCConnectionManager manager = ref.get(); IPCConnectionManager manager = ref.get();
if (manager != null) {
switch (msg.what) { switch (msg.what) {
case SERVICE_CMD_DATA: case SERVICE_CMD_DATA:
byte[] data = null; byte[] data = null;
Bundle b = msg.getData(); Bundle b = msg.getData();
if (b != null) { if (b != null) {
data = b.getByteArray("data"); data = b.getByteArray("data");
manager.onData(data); manager.onData(data);
} }
break; break;
case SERVICE_CMD_STATE: case SERVICE_CMD_STATE:
manager.stateNotify(msg.arg1); manager.stateNotify(msg.arg1);
break; break;
} }
}
} }
} }
@ -90,7 +91,7 @@ public class IPCConnectionManager extends ConnectionManager {
msg.replyTo = mMessenger; msg.replyTo = mMessenger;
msg.setData(b); msg.setData(b);
mService.send(msg); mService.send(msg);
} catch (RemoteException e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -106,11 +107,9 @@ public class IPCConnectionManager extends ConnectionManager {
sendMessage(what, arg1, arg2, (Bundle)null); sendMessage(what, arg1, arg2, (Bundle)null);
} }
@Override
private void onData(byte[] data) { protected void onData(byte[] data) {
for (InputStickDataListener listener : mDataListeners) { super.onData(data);
listener.onInputStickData(data);
}
} }
@ -163,7 +162,7 @@ public class IPCConnectionManager extends ConnectionManager {
@Override @Override
public void sendPacket(Packet p) { public void sendPacket(Packet p) {
if (mState == ConnectionManager.STATE_READY) { if ((mState == ConnectionManager.STATE_READY) || (mState == ConnectionManager.STATE_CONNECTED)) {
if (p.getRespond()) { if (p.getRespond()) {
sendMessage(IPCConnectionManager.SERVICE_CMD_DATA, 1, 0, p.getBytes()); sendMessage(IPCConnectionManager.SERVICE_CMD_DATA, 1, 0, p.getBytes());
} else { } else {

View File

@ -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<String> errorCodeMap;
static
{
errorCodeMap = new SparseArray<String>();
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);
}
}

View File

@ -0,0 +1,8 @@
package com.inputstick.api;
public interface OnEmptyBufferListener {
public void onLocalBufferEmpty(int interfaceId);
public void onRemoteBufferEmpty(int interfaceId);
}

View File

@ -2,48 +2,59 @@ package com.inputstick.api;
public class Packet { public class Packet {
public static final byte NONE = 0x00; public static final byte NONE = 0x00;
public static final byte START_TAG = 0x55; public static final byte START_TAG = 0x55;
public static final byte FLAG_RESPOND = (byte)0x80; public static final byte FLAG_RESPOND = (byte)0x80;
public static final byte FLAG_ENCRYPTED = 0x40; public static final byte FLAG_ENCRYPTED = 0x40;
public static final int MAX_SUBPACKETS = 17; public static final int MAX_SUBPACKETS = 17;
public static final int MAX_LENGTH = MAX_SUBPACKETS * 16; public static final int MAX_LENGTH = MAX_SUBPACKETS * 16;
public static final byte CMD_IDENTIFY = 0x01; public static final byte CMD_IDENTIFY = 0x01;
public static final byte CMD_LED = 0x02; public static final byte CMD_LED = 0x02;
public static final byte CMD_RUN_BL = 0x03; public static final byte CMD_RUN_BL = 0x03;
public static final byte CMD_RUN_FW = 0x04; public static final byte CMD_RUN_FW = 0x04;
public static final byte CMD_GET_INFO = 0x05; public static final byte CMD_GET_INFO = 0x05;
public static final byte CMD_BL_ERASE = 0x06; public static final byte CMD_BL_ERASE = 0x06;
public static final byte CMD_ADD_DATA = 0x07; public static final byte CMD_ADD_DATA = 0x07;
public static final byte CMD_BL_WRITE = 0x08; public static final byte CMD_BL_WRITE = 0x08;
public static final byte CMD_FW_INFO = 0x10; public static final byte CMD_FW_INFO = 0x10;
public static final byte CMD_INIT = 0x11; public static final byte CMD_INIT = 0x11;
public static final byte CMD_INIT_AUTH = 0x12; public static final byte CMD_INIT_AUTH = 0x12;
public static final byte CMD_INIT_CON = 0x13; public static final byte CMD_INIT_CON = 0x13;
//public static final byte CMD_SET_KEY = 0x14; public static final byte CMD_SET_VALUE = 0x14;
public static final byte CMD_SET_VALUE = 0x14; public static final byte CMD_RESTORE_DEFAULTS = 0x15;
public static final byte CMD_RESTORE_DEFAULTS = 0x15; public static final byte CMD_RESTORE_STATUS = 0x16;
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_STATUS_REPORT = 0x20;
public static final byte CMD_HID_DATA_CONSUMER = 0x22; public static final byte CMD_HID_DATA_KEYB = 0x21;
public static final byte CMD_HID_DATA_MOUSE = 0x23; 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 //out
public static final byte CMD_HID_STATUS = 0x2F; public static final byte CMD_HID_STATUS = 0x2F;
public static final byte CMD_DUMMY = (byte)0xFF; public static final byte CMD_DUMMY = (byte)0xFF;
public static final byte RESP_OK = 0x01; public static final byte RESP_OK = 0x01;
public static final byte RESP_UNKNOWN_CMD = (byte)0xFF; 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_OLD_BOOTLOADER = new byte[] {START_TAG, (byte)0x00, (byte)0x02, (byte)0x83, (byte)0x00, (byte)0xDA};

View File

@ -8,6 +8,7 @@ import java.security.NoSuchAlgorithmException;
public abstract class Util { public abstract class Util {
public static boolean debug = false; public static boolean debug = false;
public static boolean flashingToolMode = false;
public static void log(String msg) { public static void log(String msg) {
log(msg, false); log(msg, false);
@ -30,27 +31,31 @@ public abstract class Util {
} }
} }
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) { public static void printHex(byte[] toPrint) {
if (debug) { if (debug) {
if (toPrint != null) { if (toPrint != null) {
int cnt = 0; int cnt = 0;
String s;
byte b; byte b;
for (int i = 0; i < toPrint.length; i++) { for (int i = 0; i < toPrint.length; i++) {
b = toPrint[i]; b = toPrint[i];
//0x0..0xF = 0x00..0x0F
if ((b < 0x10) && (b >= 0)) { System.out.print("0x" + byteToHexString(b) + " ");
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();
System.out.print("0x" + s + " ");
cnt++; cnt++;
if (cnt == 8) { if (cnt == 8) {
System.out.println(""); System.out.println("");

View File

@ -5,7 +5,9 @@ import com.inputstick.api.hid.HIDTransaction;
public class InputStickConsumer { public class InputStickConsumer {
//CONSUMER PAGE
//CONSUMER PAGE (consumerAction)
public static final int VOL_UP = 0x00E9; public static final int VOL_UP = 0x00E9;
public static final int VOL_DOWN = 0x00EA; public static final int VOL_DOWN = 0x00EA;
public static final int VOL_MUTE = 0x00E2; public static final int VOL_MUTE = 0x00E2;
@ -18,18 +20,42 @@ public class InputStickConsumer {
public static final int LAUNCH_EMAIL = 0x018A; public static final int LAUNCH_EMAIL = 0x018A;
public static final int LAUNCH_CALC = 0x0192; public static final int LAUNCH_CALC = 0x0192;
//SYSTEM CONTROL //Android OS:
public static final int POWER_DOWN = 0x81; public static final int HOME = 0x0223;
public static final int SLEEP = 0x82; public static final int BACK = 0x0224;
public static final int WAKEUP = 0x83; 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() { private InputStickConsumer() {
} }
/*public static void systemAction(int action) { //use only for SYSTEM_POWER_DOWN, SYSTEM_SLEEP and SYSTEM_WAKEUP
}*/ 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);
}
public static void systemPowerDown() {
systemAction(SYSTEM_POWER_DOWN);
}
public static void systemSleep() {
systemAction(SYSTEM_SLEEP);
}
public static void systemWakeUp() {
systemAction(SYSTEM_WAKEUP);
}
//action - see http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (consumer page)
public static void consumerAction(int action) { public static void consumerAction(int action) {
HIDTransaction t = new HIDTransaction(); HIDTransaction t = new HIDTransaction();
t.addReport(new ConsumerReport(action)); t.addReport(new ConsumerReport(action));

View File

@ -0,0 +1,29 @@
package com.inputstick.api.basic;
import com.inputstick.api.Packet;
public class InputStickGamepad {
private InputStickGamepad() {
}
//buttons1 - button0, button1, ..., button7
//buttons2 - button8, button1, ..., button15
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);
}
}
}

View File

@ -21,8 +21,11 @@ import com.inputstick.api.InputStickStateListener;
import com.inputstick.api.OnEmptyBufferListener; import com.inputstick.api.OnEmptyBufferListener;
import com.inputstick.api.Packet; import com.inputstick.api.Packet;
import com.inputstick.api.Util; import com.inputstick.api.Util;
import com.inputstick.api.hid.HIDReport;
import com.inputstick.api.hid.HIDTransaction; import com.inputstick.api.hid.HIDTransaction;
import com.inputstick.api.hid.HIDTransactionQueue; import com.inputstick.api.hid.HIDTransactionQueue;
import com.inputstick.init.BasicInitManager;
import com.inputstick.init.DeviceInfo;
import com.inputstick.init.InitManager; import com.inputstick.init.InitManager;
public class InputStickHID implements InputStickStateListener, InputStickDataListener { public class InputStickHID implements InputStickStateListener, InputStickDataListener {
@ -36,19 +39,25 @@ public class InputStickHID implements InputStickStateListener, InputStickDataLis
private static ConnectionManager mConnectionManager; private static ConnectionManager mConnectionManager;
private static Vector<InputStickStateListener> mStateListeners = new Vector<InputStickStateListener>(); private static Vector<InputStickStateListener> mStateListeners = new Vector<InputStickStateListener>();
protected static Vector<OnEmptyBufferListener> mBufferEmptyListeners = new Vector<OnEmptyBufferListener>();
private static InputStickHID instance = new InputStickHID(); private static InputStickHID instance = new InputStickHID();
private static HIDInfo mHIDInfo; private static HIDInfo mHIDInfo;
private static DeviceInfo mDeviceInfo;
private static HIDTransactionQueue keyboardQueue; private static HIDTransactionQueue keyboardQueue;
private static HIDTransactionQueue mouseQueue; private static HIDTransactionQueue mouseQueue;
private static HIDTransactionQueue consumerQueue; private static HIDTransactionQueue consumerQueue;
// >= FW 0.93 // >= FW 0.93
private static Timer t1; private static Timer t1;
private static boolean constantUpdateMode; private static boolean constantUpdateMode;
private static int mKeyboardReportMultiplier; //enables "slow" typing by multiplying HID reports
private InputStickHID() { private InputStickHID() {
} }
@ -68,29 +77,73 @@ public class InputStickHID implements InputStickStateListener, InputStickDataLis
mConnectionManager.connect(); mConnectionManager.connect();
} }
//direct Bluetooth connection, custom InitManager //direct Bluetooth connection, custom InitManager (use BT2.0)
//mac - Bluetooth MAC address
//key - use null if InputStick is not password protected, otherwise provide 16byte key: MD5(password)
public static void connect(Application app, String mac, byte[] key, InitManager initManager) { public static void connect(Application app, String mac, byte[] key, InitManager initManager) {
mConnectionManager = new BTConnectionManager(initManager, app, mac, key); connect(app, mac, key, initManager, false);
init();
} }
//direct Bluetooth connection //direct Bluetooth connection, custom InitManager
public static void connect(Application app, String mac, byte[] key) { //is40 - use true if target device is BluetoothLowEnergy (4.0) type
mConnectionManager = new BTConnectionManager(new InitManager(key), app, mac, key); //mac - Bluetooth MAC address
//key - use null if InputStick is not password protected, otherwise provide 16byte key: MD5(password)
//is40 - use true if target device is BluetoothLowEnergy (4.0) type
public static void connect(Application app, String mac, byte[] key, InitManager initManager, boolean isBT40) {
mConnectionManager = new BTConnectionManager(initManager, app, mac, key, isBT40);
init(); init();
} }
//use background service & DeviceManager //direct Bluetooth connection
//key - use null if InputStick is not password protected, otherwise provide 16byte key: MD5(password)
//is40 - use true if target device is BluetoothLowEnergy (4.0) type
public static void connect(Application app, String mac, byte[] key, boolean isBT40) {
mConnectionManager = new BTConnectionManager(new BasicInitManager(key), app, mac, key, isBT40);
init();
}
//direct Bluetooth connection (use BT2.0)
//key - use null if InputStick is not password protected, otherwise provide 16byte key: MD5(password)
public static void connect(Application app, String mac, byte[] key) {
connect(app, mac, key, false);
}
//use InputStickUtility to connect with InputStick
public static void connect(Application app) { public static void connect(Application app) {
mConnectionManager = new IPCConnectionManager(app); mConnectionManager = new IPCConnectionManager(app);
init(); init();
} }
//closes Bluetooth connection
public static void disconnect() { public static void disconnect() {
//TODO check state? if (mConnectionManager != null) {
mConnectionManager.disconnect(); mConnectionManager.disconnect();
}
} }
//requests USB host to resume from sleep mode (must be supported by USB host)
//note: InputStick will most likely be in STATE_CONNECTED state instead of STATE_READY
public static void wakeUpUSBHost() {
if (isConnected()) {
Packet p = new Packet(false, Packet.CMD_USB_RESUME);
InputStickHID.sendPacket(p);
mConnectionManager.sendPacket(p);
}
}
public static DeviceInfo getDeviceInfo() {
if ((isReady()) && (mDeviceInfo != null)) {
return mDeviceInfo;
} else {
return null;
}
}
public static HIDInfo getHIDInfo() {
return mHIDInfo;
}
//returns current connection state
public static int getState() { public static int getState() {
if (mConnectionManager != null) { if (mConnectionManager != null) {
return mConnectionManager.getState(); return mConnectionManager.getState();
@ -99,6 +152,7 @@ public class InputStickHID implements InputStickStateListener, InputStickDataLis
} }
} }
//returns last error code
public static int getErrorCode() { public static int getErrorCode() {
if (mConnectionManager != null) { if (mConnectionManager != null) {
return mConnectionManager.getErrorCode(); return mConnectionManager.getErrorCode();
@ -107,8 +161,17 @@ public class InputStickHID implements InputStickStateListener, InputStickDataLis
} }
} }
//returns true if Bluetooth connection is established between the device and InputStick.
//note - InputStick may be not ready yet to accept keyboard/mouse data
public static boolean isConnected() {
if ((getState() == ConnectionManager.STATE_READY) || (getState() == ConnectionManager.STATE_CONNECTED)) {
return true;
} else {
return false;
}
}
//returns true if InputStick is ready for keyboard/mouse data
public static boolean isReady() { public static boolean isReady() {
if (getState() == ConnectionManager.STATE_READY) { if (getState() == ConnectionManager.STATE_READY) {
return true; return true;
@ -117,6 +180,7 @@ public class InputStickHID implements InputStickStateListener, InputStickDataLis
} }
} }
//adds state listener. Listeners will be notified about change of connection state
public static void addStateListener(InputStickStateListener listener) { public static void addStateListener(InputStickStateListener listener) {
if (listener != null) { if (listener != null) {
if ( !mStateListeners.contains(listener)) { if ( !mStateListeners.contains(listener)) {
@ -125,52 +189,97 @@ public class InputStickHID implements InputStickStateListener, InputStickDataLis
} }
} }
public static void removeStateListener(InputStickStateListener listener) { public static void removeStateListener(InputStickStateListener listener) {
if (listener != null) { if (listener != null) {
mStateListeners.remove(listener); mStateListeners.remove(listener);
} }
} }
//adds buffer listener. Listeners will be notified when local (application) or remote (InputStick) HID report buffer is empty
public static void addBufferEmptyListener(OnEmptyBufferListener listener) { public static void addBufferEmptyListener(OnEmptyBufferListener listener) {
if (listener != null) { if (listener != null) {
keyboardQueue.addBufferEmptyListener(listener); if ( !mBufferEmptyListeners.contains(listener)) {
mouseQueue.addBufferEmptyListener(listener); mBufferEmptyListeners.add(listener);
consumerQueue.addBufferEmptyListener(listener); }
} }
} }
public static void removeBufferEmptyListener(OnEmptyBufferListener listener) { public static void removeBufferEmptyListener(OnEmptyBufferListener listener) {
if (listener != null) { if (listener != null) {
keyboardQueue.removeBufferEmptyListener(listener); mBufferEmptyListeners.remove(listener);
mouseQueue.removeBufferEmptyListener(listener); }
consumerQueue.removeBufferEmptyListener(listener); }
}
public static Vector<OnEmptyBufferListener> getBufferEmptyListeners() {
return mBufferEmptyListeners;
}
//reports added to keyboard queue will be multiplied by reportMultiplier times. This allows to type text slower.
//NOTE: using high multiplier values can make transactions larger than available buffer and as a result they will be splitted!
//this can cause problem if connection is lost (stuck keys)
//TIP: remember to manually set multiplier value back to 1 when slow typing mode is no longer needed!!!
public static void setKeyboardReportMultiplier(int reportMultiplier) {
mKeyboardReportMultiplier = reportMultiplier;
} }
//adds transaction to keyboard queue. If possible, all reports form a signel transactions will be sent in a single packet
public static void addKeyboardTransaction(HIDTransaction transaction) { public static void addKeyboardTransaction(HIDTransaction transaction) {
keyboardQueue.addTransaction(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 signel transactions will be sent in a single packet
public static void addMouseTransaction(HIDTransaction transaction) { public static void addMouseTransaction(HIDTransaction transaction) {
mouseQueue.addTransaction(transaction); if ((transaction != null) && (mouseQueue != null)) {
mouseQueue.addTransaction(transaction);
}
} }
//adds transaction to consumer queue. If possible, all reports form a signel transactions will be sent in a single packet
public static void addConsumerTransaction(HIDTransaction transaction) { public static void addConsumerTransaction(HIDTransaction transaction) {
consumerQueue.addTransaction(transaction); if ((transaction != null) && (consumerQueue != null)) {
consumerQueue.addTransaction(transaction);
}
} }
//removes all reports from keyboard buffer
public static void clearKeyboardBuffer() { public static void clearKeyboardBuffer() {
keyboardQueue.clearBuffer(); if (keyboardQueue != null) {
keyboardQueue.clearBuffer();
}
} }
//removes all reports from mouse buffer
public static void clearMouseBuffer() { public static void clearMouseBuffer() {
mouseQueue.clearBuffer(); if (mouseQueue != null) {
mouseQueue.clearBuffer();
}
} }
//removes all reports from consumer buffer
public static void clearConsumerBuffer() { public static void clearConsumerBuffer() {
consumerQueue.clearBuffer(); if (consumerQueue != null) {
consumerQueue.clearBuffer();
}
} }
//sends packet to InputStick
public static boolean sendPacket(Packet p) { public static boolean sendPacket(Packet p) {
if (mConnectionManager != null) { if (mConnectionManager != null) {
mConnectionManager.sendPacket(p); mConnectionManager.sendPacket(p);
@ -191,29 +300,68 @@ public class InputStickHID implements InputStickStateListener, InputStickDataLis
} }
} }
//returns true if local (application) keyboard report buffer is empty. It is still possible that there are reports queued in InputStick's buffer.
public static boolean isKeyboardLocalBufferEmpty() { public static boolean isKeyboardLocalBufferEmpty() {
return keyboardQueue.isLocalBufferEmpty(); if (keyboardQueue != null) {
} return keyboardQueue.isLocalBufferEmpty();
public static boolean isMouseLocalBufferEmpty() { } else {
return mouseQueue.isLocalBufferEmpty(); return true;
} }
public static boolean isConsumerLocalBufferEmpty() {
return consumerQueue.isLocalBufferEmpty();
} }
//returns true if local (application) mouse report buffer is empty. It is still possible that there are reports queued in InputStick's buffer.
public static boolean isMouseLocalBufferEmpty() {
if (mouseQueue != null) {
return mouseQueue.isLocalBufferEmpty();
} else {
return true;
}
}
//returns true if local (application) consumer report buffer is empty. It is still possible that there are reports queued in InputStick's buffer.
public static boolean isConsumerLocalBufferEmpty() {
if (consumerQueue != null) {
return consumerQueue.isLocalBufferEmpty();
} else {
return true;
}
}
//returns true if remote (InputStick) keyboard report buffer is empty. No more keyboard reports will be send to USB host
public static boolean isKeyboardRemoteBufferEmpty() { public static boolean isKeyboardRemoteBufferEmpty() {
return keyboardQueue.isRemoteBufferEmpty(); if (keyboardQueue != null) {
return keyboardQueue.isRemoteBufferEmpty();
} else {
return true;
}
} }
//returns true if remote (InputStick) mouse report buffer is empty. No more mouse reports will be send to USB host
public static boolean isMouseRemoteBufferEmpty() { public static boolean isMouseRemoteBufferEmpty() {
return mouseQueue.isRemoteBufferEmpty(); if (mouseQueue != null) {
return mouseQueue.isRemoteBufferEmpty();
} else {
return true;
}
} }
//returns true if remote (InputStick) consumer report buffer is empty. No more consumer reports will be send to USB host
public static boolean isConsumerRemoteBufferEmpty() { public static boolean isConsumerRemoteBufferEmpty() {
return consumerQueue.isRemoteBufferEmpty(); if (consumerQueue != null) {
return consumerQueue.isRemoteBufferEmpty();
} else {
return true;
}
} }
@Override @Override
public void onInputStickData(byte[] data) { public void onInputStickData(byte[] data) {
if (data[0] == Packet.CMD_HID_STATUS) { byte cmd = data[0];
if (cmd == Packet.CMD_FW_INFO) {
mDeviceInfo = new DeviceInfo(data);
}
if (cmd == Packet.CMD_HID_STATUS) {
mHIDInfo.update(data); mHIDInfo.update(data);
if (mHIDInfo.isSentToHostInfoAvailable()) { if (mHIDInfo.isSentToHostInfoAvailable()) {
@ -252,12 +400,13 @@ public class InputStickHID implements InputStickStateListener, InputStickDataLis
} }
} }
//returns "Download InputStickUtility" dialog, if connection attepmt resulted in error caused by InputStickUtility not being installed on the device.
//otherwise returns null
public static AlertDialog getDownloadDialog(final Context ctx) { public static AlertDialog getDownloadDialog(final Context ctx) {
if (mConnectionManager.getErrorCode() == InputStickError.ERROR_ANDROID_NO_UTILITY_APP) { if (mConnectionManager.getErrorCode() == InputStickError.ERROR_ANDROID_NO_UTILITY_APP) {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(ctx); AlertDialog.Builder downloadDialog = new AlertDialog.Builder(ctx);
downloadDialog.setTitle("No InputStickUtility app installed"); downloadDialog.setTitle("No InputStickUtility app installed");
downloadDialog.setMessage("InputStickUtility is required to run this application. Download now?"); downloadDialog.setMessage("InputStickUtility is required to run this application. Download now?\nNote: InputStick USB receiver hardware is also required.");
downloadDialog.setPositiveButton("Yes", downloadDialog.setPositiveButton("Yes",
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
@ -286,7 +435,7 @@ public class InputStickHID implements InputStickStateListener, InputStickDataLis
} else { } else {
return null; return null;
} }
} }
} }

View File

@ -38,6 +38,7 @@ public class InputStickKeyboard {
private InputStickKeyboard() { private InputStickKeyboard() {
} }
//listener will be notified when status of keyboard LEDs changes (NumLock, CapsLock, ScrollLock)
public static void addKeyboardListener(InputStickKeyboardListener listener) { public static void addKeyboardListener(InputStickKeyboardListener listener) {
if (listener != null) { if (listener != null) {
if ( !mKeyboardListeners.contains(listener)) { if ( !mKeyboardListeners.contains(listener)) {
@ -76,30 +77,39 @@ public class InputStickKeyboard {
} }
} }
//returns true if NumLock LED is set to ON by USB host, otherwise false is returned.
public static boolean isNumLock() { public static boolean isNumLock() {
return mNumLock; return mNumLock;
} }
//returns true if CapsLock LED is set to ON by USB host, otherwise false is returned.
public static boolean isCapsLock() { public static boolean isCapsLock() {
return mCapsLock; return mCapsLock;
} }
//returns true if ScrollLock LED is set to ON by USB host, otherwise false is returned.
public static boolean isScrollLock() { public static boolean isScrollLock() {
return mScrollLock; return mScrollLock;
} }
//same as pressing NumLock key
public static void toggleNumLock() { public static void toggleNumLock() {
pressAndRelease(NONE, HIDKeycodes.KEY_NUM_LOCK); pressAndRelease(NONE, HIDKeycodes.KEY_NUM_LOCK);
} }
//same as pressing CapsLock key
public static void toggleCapsLock() { public static void toggleCapsLock() {
pressAndRelease(NONE, HIDKeycodes.KEY_CAPS_LOCK); pressAndRelease(NONE, HIDKeycodes.KEY_CAPS_LOCK);
} }
//same as pressing ScrollLock key
public static void toggleScrollLock() { public static void toggleScrollLock() {
pressAndRelease(NONE, HIDKeycodes.KEY_SCROLL_LOCK); pressAndRelease(NONE, HIDKeycodes.KEY_SCROLL_LOCK);
} }
//following key combination will be pressed and immediately released
//modifier - see HIDKeycodes (CTRL_LEFT .. GUI_RIGHT)
//key - see HIDKeycodes
public static void pressAndRelease(byte modifier, byte key) { public static void pressAndRelease(byte modifier, byte key) {
HIDTransaction t = new HIDTransaction(); HIDTransaction t = new HIDTransaction();
t.addReport(new KeyboardReport(modifier, NONE)); t.addReport(new KeyboardReport(modifier, NONE));
@ -108,36 +118,41 @@ public class InputStickKeyboard {
InputStickHID.addKeyboardTransaction(t); InputStickHID.addKeyboardTransaction(t);
} }
//types text assuming that USB host uses en-US keyboard layout.
public static void typeASCII(String toType) { public static void typeASCII(String toType) {
int keyCode; int keyCode;
int index; int index;
for (int i = 0; i < toType.length(); i++) {
for (int i = 0; i < toType.length(); i++) {
index = toType.charAt(i); index = toType.charAt(i);
if (index > 127) { if (index == '\n') {
index = 127; pressAndRelease(NONE, HIDKeycodes.KEY_ENTER);
} } else if (index == '\t') {
keyCode = HIDKeycodes.getKeyCode(index); pressAndRelease(NONE, HIDKeycodes.KEY_TAB);
if (keyCode > 128) { } else {
keyCode -= 128; if (index > 127) {
pressAndRelease(HIDKeycodes.SHIFT_LEFT, (byte)keyCode); index = 127;
} else { }
pressAndRelease(NONE, (byte)keyCode); keyCode = HIDKeycodes.getKeyCode(index);
if (keyCode > 128) {
keyCode -= 128;
pressAndRelease(HIDKeycodes.SHIFT_LEFT, (byte)keyCode);
} else {
pressAndRelease(NONE, (byte)keyCode);
}
} }
} }
} }
//modifier - see HIDKeycodes (CTRL_LEFT .. GUI_RIGHT)
//key0..key5 - see HIDKeycodes
//note: keys will not be released until next report is sent!
public static void customReport(byte modifier, byte key0, byte key1, byte key2, byte key3, byte key4, byte key5) { public static void customReport(byte modifier, byte key0, byte key1, byte key2, byte key3, byte key4, byte key5) {
HIDTransaction t = new HIDTransaction(); HIDTransaction t = new HIDTransaction();
t.addReport(new KeyboardReport(modifier, key0, key1, key2, key3, key4, key5)); t.addReport(new KeyboardReport(modifier, key0, key1, key2, key3, key4, key5));
InputStickHID.addKeyboardTransaction(t); InputStickHID.addKeyboardTransaction(t);
} }
/*public static void customReport(byte[] report) {
HIDTransaction t = new HIDTransaction();
t.addReport(report);
InputStickHID.addKeyboardTransaction(t);
}*/
public static String ledsToString(byte leds) { public static String ledsToString(byte leds) {
String result = "None"; String result = "None";
boolean first = true; boolean first = true;

View File

@ -37,6 +37,7 @@ public class InputStickMouse {
return mReportProtocol; return mReportProtocol;
} }
//clicks button (BUTTON_LEFT..BUTTON_MIDDLE) n times.
public static void click(byte button, int n) { public static void click(byte button, int n) {
HIDTransaction t = new HIDTransaction(); HIDTransaction t = new HIDTransaction();
t.addReport(new MouseReport()); //release t.addReport(new MouseReport()); //release
@ -47,18 +48,21 @@ public class InputStickMouse {
InputStickHID.addMouseTransaction(t); InputStickHID.addMouseTransaction(t);
} }
//moves mouse pointer by x,y
public static void move(byte x, byte y) { public static void move(byte x, byte y) {
HIDTransaction t = new HIDTransaction(); HIDTransaction t = new HIDTransaction();
t.addReport(new MouseReport(NONE, x, y, NONE)); t.addReport(new MouseReport(NONE, x, y, NONE));
InputStickHID.addMouseTransaction(t); InputStickHID.addMouseTransaction(t);
} }
//moves scroll wheel by "wheel"
public static void scroll(byte wheel) { public static void scroll(byte wheel) {
HIDTransaction t = new HIDTransaction(); HIDTransaction t = new HIDTransaction();
t.addReport(new MouseReport(NONE, NONE, NONE, wheel)); t.addReport(new MouseReport(NONE, NONE, NONE, wheel));
InputStickHID.addMouseTransaction(t); InputStickHID.addMouseTransaction(t);
} }
//sends custom mouse report (buttons will remain in pressed state until released by next report)
public static void customReport(byte buttons, byte x, byte y, byte wheel) { public static void customReport(byte buttons, byte x, byte y, byte wheel) {
HIDTransaction t = new HIDTransaction(); HIDTransaction t = new HIDTransaction();
t.addReport(new MouseReport(buttons, x, y, wheel)); t.addReport(new MouseReport(buttons, x, y, wheel));

View File

@ -0,0 +1,204 @@
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;
}
//synchronized (BTService.this) {
mConnectThread = null; //TODO
//}
//connected(mmSocket, mmDevice); :
cancelThreads();
//receiver
// Start the thread to manage the connection and perform transmissions
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");
}
}
}
}

View File

@ -0,0 +1,286 @@
package com.inputstick.api.bluetooth;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.Vector;
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 com.inputstick.api.InputStickError;
import com.inputstick.api.Util;
@SuppressLint("NewApi")
public class BT40Connection extends BTConnection {
private static String MOD_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";
private static String MOD_CONF = "0000ffe0-0000-1000-8000-00805f9b34fb";
private static String MOD_RX_TX = "0000ffe1-0000-1000-8000-00805f9b34fb";
private final static 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 static final int REFRESH_INTERVAL = 10;
private Timer t1;
private Vector<byte[]> txBuffer;
private boolean canSend;
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);
} else {
mBTservice.connectionFailed(false, InputStickError.ERROR_BLUETOOTH_NO_REMOTE_DEVICE);
}
}
@Override
public void disconnect() {
txBuffer = null;
try {
if (t1 != null) {
t1.cancel();
t1 = null;
}
} catch (Exception e) {
}
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) {
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);
}
}
}
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.firstElement();
txBuffer.removeElementAt(0);
return data;
}
}
return null;
}
private synchronized void sendNext() {
if (canSend) {
byte[] data = getData();
if (data != null) {
canSend = false;
characteristicTX.setValue(data);
mBluetoothGatt.writeCharacteristic(characteristicTX);
}
}
}
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
Util.log("Connected to GATT server.");
Util.log("Attempting to start service discovery:" + mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
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<BluetoothGattService> 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 Vector<byte[]>();
t1 = new Timer();
t1.schedule(new TimerTask() {
@Override
public void run() {
sendNext();
}
}, REFRESH_INTERVAL, REFRESH_INTERVAL);
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) {
for (int i = 0; i < b.length; i++) {
mBTservice.onByteRx(b[i]);
}
} //TODO error code?
}
@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?
}
};
}

View File

@ -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);
}

View File

@ -1,15 +1,7 @@
package com.inputstick.api.bluetooth; 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.app.Application;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -17,9 +9,8 @@ import android.content.IntentFilter;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import com.inputstick.api.Packet;
import com.inputstick.api.Util;
import com.inputstick.api.InputStickError; import com.inputstick.api.InputStickError;
import com.inputstick.api.Util;
public class BTService { public class BTService {
@ -30,50 +21,29 @@ public class BTService {
public static final int EVENT_CONNECTED = 2; public static final int EVENT_CONNECTED = 2;
public static final int EVENT_CANCELLED = 3; public static final int EVENT_CANCELLED = 3;
public static final int EVENT_ERROR = 4; public static final int EVENT_ERROR = 4;
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //SPP
//private final String dTag = "BTService";
private final BluetoothAdapter mAdapter;
private final Handler mHandler; private final Handler mHandler;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mLastEvent; private int mLastEvent;
private String mMac; private String mMac;
private boolean mReflection;
private final Application mApp; private final Application mApp;
private final Context mCtx; private final Context mCtx;
private boolean mUseReflection; private boolean mUseReflection;
private int mConnectTimeout; private int mConnectTimeout;
private boolean turnBluetoothOn;
private boolean receiverRegistered;
private long timeout; private long timeout;
private int retryCnt; private int retryCnt;
private boolean disconnecting; private boolean disconnecting;
private boolean connected; private boolean connected;
//================================================================ private PacketReader mPacketReader;
private static final int RX_TIMEOUT = 3000; private BTConnection mBTConnection;
private long lastRxTime;
private int rxState;
private int rxPos;
private int rxLength;
private byte[] rxData;
private int rxWdgCnt;
private static final int RX_TAG = 0;
private static final int RX_LENGTH = 1;
private static final int RX_DATA = 2;
private boolean turnBluetoothOn;
private boolean receiverRegistered;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() { private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
@ -82,22 +52,20 @@ public class BTService {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if ((state == BluetoothAdapter.STATE_ON) && (turnBluetoothOn)) { if ((state == BluetoothAdapter.STATE_ON) && (turnBluetoothOn)) {
turnBluetoothOn = false; turnBluetoothOn = false;
doConnect(false); connect(false);
} }
} }
} }
}; };
public BTService(Application app, Handler handler) {
public BTService(Application app, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mLastEvent = EVENT_NONE; mLastEvent = EVENT_NONE;
mHandler = handler; mHandler = handler;
mApp = app; mApp = app;
mCtx = app.getApplicationContext(); mCtx = app.getApplicationContext();
mConnectTimeout = DEFAULT_CONNECT_TIMEOUT; //30s - default value mConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
} }
public void setConnectTimeout(int timeout) { public void setConnectTimeout(int timeout) {
@ -109,7 +77,7 @@ public class BTService {
} }
private synchronized void event(int event, int arg1) { protected synchronized void event(int event, int arg1) {
Util.log("event() " + mLastEvent + " -> " + event); Util.log("event() " + mLastEvent + " -> " + event);
mLastEvent = event; mLastEvent = event;
Message msg = Message.obtain(null, mLastEvent, arg1, 0); Message msg = Message.obtain(null, mLastEvent, arg1, 0);
@ -120,29 +88,7 @@ public class BTService {
return mLastEvent; return mLastEvent;
} }
private void connect(boolean reconnecting) {
private void enableBluetooth(boolean 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);
}
}
}
private void doConnect(boolean reconnecting) {
if (reconnecting) { if (reconnecting) {
retryCnt++; retryCnt++;
} else { } else {
@ -150,306 +96,130 @@ public class BTService {
timeout = System.currentTimeMillis() + mConnectTimeout; timeout = System.currentTimeMillis() + mConnectTimeout;
} }
if (mConnectThread != null) { mBTConnection.connect();
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectThread = new ConnectThread(mAdapter.getRemoteDevice(mMac), mReflection);
mConnectThread.start();
} }
public synchronized void connect(String mac) { public synchronized void connect(String mac) {
connect(mac, false); connect(mac, false);
} }
public synchronized void connect(String mac, boolean doNotAsk) { public synchronized void connect(String mac, boolean doNotAsk) {
Util.log("connect to: " + mac + " REFLECTION: " + mUseReflection); connect(mac, doNotAsk, false);
disconnecting = false; }
connected = false;
mMac = mac; public synchronized void connect(String mac, boolean doNotAsk, boolean bt40) {
try {
if (BluetoothAdapter.checkBluetoothAddress(mac)) { Util.log("connect to: " + mac + " REFLECTION: " + mUseReflection);
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); disconnecting = false;
if (mBluetoothAdapter == null) { connected = false;
event(EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_NOT_SUPPORTED); mMac = mac;
} else { if (BluetoothAdapter.checkBluetoothAddress(mac)) {
if (mBluetoothAdapter.isEnabled()) { BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
doConnect(false); if (mBluetoothAdapter == null) {
} else { event(BTService.EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_NOT_SUPPORTED);
enableBluetooth(doNotAsk); } 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 {
} else { event(BTService.EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_INVALID_MAC);
event(EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_INVALID_MAC); }
} catch (NoClassDefFoundError e) {
event(BTService.EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_BT40_NOT_SUPPRTED);
} }
} }
public synchronized void disconnect() { public synchronized void disconnect() {
Util.log("disconnect"); Util.log("disconnect");
disconnecting = true; disconnecting = true;
cancelThreads(); if (mBTConnection != null) {
mBTConnection.disconnect();
}
event(EVENT_CANCELLED, 0); event(EVENT_CANCELLED, 0);
} }
public synchronized void write(byte[] out) { public synchronized void write(byte[] out) {
// Create temporary object
/*
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
r = mConnectedThread;
}
// Perform the write unsynchronized
if (connected) { if (connected) {
r.write(out); mBTConnection.write(out);
}*/
if (connected) {
mConnectedThread.write(out);
} }
} }
private synchronized void cancelThreads() {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
}
private synchronized void connected(BluetoothSocket socket, BluetoothDevice device) { protected synchronized void connectedEstablished() {
removeReceiver(); //TODO
mPacketReader = new PacketReader(this, mHandler);
timeout = 0; timeout = 0;
cancelThreads(); connected = true;
if (receiverRegistered) { event(EVENT_CONNECTED, 0);
mCtx.unregisterReceiver(mReceiver);
receiverRegistered = false;
}
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
connected = true;
event(EVENT_CONNECTED, 0);
} }
private void connectionFailed() { protected void connectionFailed(boolean canRetry, int errorCode) {
removeReceiver(); //TODO
connected = false; connected = false;
if (disconnecting) { if (disconnecting) {
disconnecting = false; disconnecting = false;
} else { } else {
if ((timeout > 0) && (System.currentTimeMillis() < timeout)) { if (canRetry) {
Util.log("RETRY: "+retryCnt + " time left: " + (timeout - System.currentTimeMillis())); if ((timeout > 0) && (System.currentTimeMillis() < timeout)) {
doConnect(true); Util.log("RETRY: "+retryCnt + " time left: " + (timeout - System.currentTimeMillis()));
} else { connect(true);
event(EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_CONNECTION_FAILED); } else {
} event(EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_CONNECTION_FAILED);
}
} else {
event(EVENT_ERROR, errorCode);
}
} }
} }
private void connectionLost() {
connected = false;
if (disconnecting) {
disconnecting = false;
} else {
event(EVENT_ERROR, InputStickError.ERROR_BLUETOOTH_CONNECTION_LOST);
}
}
protected void onByteRx(int rxByte) {
mPacketReader.rxByte(rxByte);
}
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);
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");
}
connectionFailed();
return;
}
// Reset the ConnectThread
synchronized (BTService.this) {
mConnectThread = null;
}
connected(mmSocket, mmDevice);
}
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;
}
private void rxByte(byte b) {
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;
event(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(EVENT_DATA, 0, 0, rxData).sendToTarget();
rxState = RX_TAG;
}
} else {
//buffer overrun!
rxState = RX_TAG;
}
break;
}
lastRxTime = time;
}
public void run() {
Util.log("BEGIN mConnectedThread");
int rxTmp;
while (true) {
try {
rxTmp = mmInStream.read();
rxByte((byte)rxTmp);
} catch (IOException e) {
connectionLost();
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");
}
}
}
} }

View File

@ -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(int rxByte) {
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;
}
}

View File

@ -4,13 +4,24 @@ import com.inputstick.api.Util;
public class ConsumerReport extends HIDReport { 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; public static final int SIZE = 3;
private byte[] data; 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) { public ConsumerReport(int usage) {
data = new byte[SIZE]; data = new byte[SIZE];
data[0] = 1; data[0] = CONSUMER_REPORT_ID;
data[1] = Util.getLSB(usage); data[1] = Util.getLSB(usage);
data[2] = Util.getMSB(usage); data[2] = Util.getMSB(usage);
} }
@ -26,5 +37,7 @@ public class ConsumerReport extends HIDReport {
public int getBytesCount() { public int getBytesCount() {
return SIZE; return SIZE;
} }
} }

View File

@ -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;
}
}

View File

@ -4,68 +4,68 @@ import android.util.SparseArray;
public class HIDKeycodes { public class HIDKeycodes {
public static final byte NONE = 0x00; public static final byte NONE = 0x00;
public static final byte CTRL_LEFT = 0x01; public static final byte CTRL_LEFT = 0x01;
public static final byte SHIFT_LEFT = 0x02; public static final byte SHIFT_LEFT = 0x02;
public static final byte ALT_LEFT = 0x04; public static final byte ALT_LEFT = 0x04;
public static final byte GUI_LEFT = 0x08; public static final byte GUI_LEFT = 0x08;
public static final byte CTRL_RIGHT = 0x10; public static final byte CTRL_RIGHT = 0x10;
public static final byte SHIFT_RIGHT = 0x20; public static final byte SHIFT_RIGHT = 0x20;
public static final byte ALT_RIGHT = 0x40; public static final byte ALT_RIGHT = 0x40;
public static final byte GUI_RIGHT = (byte)0x80; public static final byte GUI_RIGHT = (byte)0x80;
public static final byte KEY_ENTER = 0x28; public static final byte KEY_ENTER = 0x28;
public static final byte KEY_ESCAPE = 0x29; public static final byte KEY_ESCAPE = 0x29;
public static final byte KEY_BACKSPACE = 0x2A; public static final byte KEY_BACKSPACE = 0x2A;
public static final byte KEY_TAB = 0x2B; public static final byte KEY_TAB = 0x2B;
public static final byte KEY_SPACEBAR = 0x2C; public static final byte KEY_SPACEBAR = 0x2C;
public static final byte KEY_CAPS_LOCK = 0x39; public static final byte KEY_CAPS_LOCK = 0x39;
public static final byte KEY_1 = 0x1E; public static final byte KEY_1 = 0x1E;
public static final byte KEY_2 = 0x1F; public static final byte KEY_2 = 0x1F;
public static final byte KEY_3 = 0x20; public static final byte KEY_3 = 0x20;
public static final byte KEY_4 = 0x21; public static final byte KEY_4 = 0x21;
public static final byte KEY_5 = 0x22; public static final byte KEY_5 = 0x22;
public static final byte KEY_6 = 0x23; public static final byte KEY_6 = 0x23;
public static final byte KEY_7 = 0x24; public static final byte KEY_7 = 0x24;
public static final byte KEY_8 = 0x25; public static final byte KEY_8 = 0x25;
public static final byte KEY_9 = 0x26; public static final byte KEY_9 = 0x26;
public static final byte KEY_0 = 0x27; public static final byte KEY_0 = 0x27;
public static final byte KEY_F1 = 0x3A; public static final byte KEY_F1 = 0x3A;
public static final byte KEY_F2 = 0x3B; public static final byte KEY_F2 = 0x3B;
public static final byte KEY_F3 = 0x3C; public static final byte KEY_F3 = 0x3C;
public static final byte KEY_F4 = 0x3D; public static final byte KEY_F4 = 0x3D;
public static final byte KEY_F5 = 0x3E; public static final byte KEY_F5 = 0x3E;
public static final byte KEY_F6 = 0x3F; public static final byte KEY_F6 = 0x3F;
public static final byte KEY_F7 = 0x40; public static final byte KEY_F7 = 0x40;
public static final byte KEY_F8 = 0x41; public static final byte KEY_F8 = 0x41;
public static final byte KEY_F9 = 0x42; public static final byte KEY_F9 = 0x42;
public static final byte KEY_F10 = 0x43; public static final byte KEY_F10 = 0x43;
public static final byte KEY_F11 = 0x44; public static final byte KEY_F11 = 0x44;
public static final byte KEY_F12 = 0x45; public static final byte KEY_F12 = 0x45;
public static final byte KEY_PRINT_SCREEN = 0x46; public static final byte KEY_PRINT_SCREEN = 0x46;
public static final byte KEY_SCROLL_LOCK = 0x47; public static final byte KEY_SCROLL_LOCK = 0x47;
public static final byte KEY_PASUE = 0x48; public static final byte KEY_PASUE = 0x48;
public static final byte KEY_INSERT = 0x49; public static final byte KEY_INSERT = 0x49;
public static final byte KEY_HOME = 0x4A; public static final byte KEY_HOME = 0x4A;
public static final byte KEY_PAGE_UP = 0x4B; public static final byte KEY_PAGE_UP = 0x4B;
public static final byte KEY_DELETE = 0x4C; public static final byte KEY_DELETE = 0x4C;
public static final byte KEY_END = 0x4D; public static final byte KEY_END = 0x4D;
public static final byte KEY_PAGE_DOWN = 0x4E; public static final byte KEY_PAGE_DOWN = 0x4E;
public static final byte KEY_ARROW_RIGHT = 0x4F; public static final byte KEY_ARROW_RIGHT = 0x4F;
public static final byte KEY_ARROW_LEFT = 0x50; public static final byte KEY_ARROW_LEFT = 0x50;
public static final byte KEY_ARROW_DOWN = 0x51; public static final byte KEY_ARROW_DOWN = 0x51;
public static final byte KEY_ARROW_UP = 0x52; public static final byte KEY_ARROW_UP = 0x52;
public static final byte KEY_NUM_LOCK = 0x53; public static final byte KEY_NUM_LOCK = 0x53;
public static final byte KEY_NUM_BACKSLASH = 0x54; public static final byte KEY_NUM_SLASH = 0x54;
public static final byte KEY_NUM_STAR = 0x55; public static final byte KEY_NUM_STAR = 0x55;
public static final byte KEY_NUM_MINUS = 0x56; public static final byte KEY_NUM_MINUS = 0x56;
public static final byte KEY_NUM_PLUS = 0x57; public static final byte KEY_NUM_PLUS = 0x57;
@ -198,7 +198,7 @@ public class HIDKeycodes {
keyMap.put(KEY_ARROW_UP , "Up Arrow"); keyMap.put(KEY_ARROW_UP , "Up Arrow");
keyMap.put(KEY_NUM_LOCK , "NumLock"); keyMap.put(KEY_NUM_LOCK , "NumLock");
keyMap.put(KEY_NUM_BACKSLASH , "Num /"); keyMap.put(KEY_NUM_SLASH , "Num /");
keyMap.put(KEY_NUM_STAR , "Num *"); keyMap.put(KEY_NUM_STAR , "Num *");
keyMap.put(KEY_NUM_MINUS , "Num -"); keyMap.put(KEY_NUM_MINUS , "Num -");
keyMap.put(KEY_NUM_PLUS , "Num +"); keyMap.put(KEY_NUM_PLUS , "Num +");

View File

@ -38,6 +38,10 @@ public class HIDTransaction {
return report; return report;
} }
public HIDReport getHIDReportAt(int pos) {
return reports.elementAt(pos);
}
public HIDTransaction split(int n) { public HIDTransaction split(int n) {
HIDTransaction result = new HIDTransaction(); HIDTransaction result = new HIDTransaction();
HIDReport report; HIDReport report;

View File

@ -25,7 +25,6 @@ public class HIDTransactionQueue {
private int mInterfaceType; private int mInterfaceType;
private boolean mustNotify; private boolean mustNotify;
private Vector<OnEmptyBufferListener> mBufferEmptyListeners = new Vector<OnEmptyBufferListener>();
private Timer t; private Timer t;
private boolean timerCancelled; private boolean timerCancelled;
@ -132,29 +131,17 @@ public class HIDTransactionQueue {
return reports; return reports;
} }
public void addBufferEmptyListener(OnEmptyBufferListener listener) {
if (listener != null) {
if ( !mBufferEmptyListeners.contains(listener)) {
mBufferEmptyListeners.add(listener);
}
}
}
public void removeBufferEmptyListener(OnEmptyBufferListener listener) {
if (listener != null) {
mBufferEmptyListeners.remove(listener);
}
}
private void notifyOnRemoteBufferEmpty() { private void notifyOnRemoteBufferEmpty() {
for (OnEmptyBufferListener listener : mBufferEmptyListeners) { Vector<OnEmptyBufferListener> listeners = InputStickHID.getBufferEmptyListeners();
for (OnEmptyBufferListener listener : listeners) {
listener.onRemoteBufferEmpty(mInterfaceType); listener.onRemoteBufferEmpty(mInterfaceType);
} }
} }
private void notifyOnLocalBufferEmpty() { private void notifyOnLocalBufferEmpty() {
for (OnEmptyBufferListener listener : mBufferEmptyListeners) { Vector<OnEmptyBufferListener> listeners = InputStickHID.getBufferEmptyListeners();
listener.onRemoteBufferEmpty(mInterfaceType); for (OnEmptyBufferListener listener : listeners) {
listener.onLocalBufferEmpty(mInterfaceType);
} }
} }

View File

@ -0,0 +1,218 @@
package com.inputstick.api.layout;
public class DanishLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "da-DK";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,160 @@
package com.inputstick.api.layout;
public class DvorakLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "en-DV";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,220 @@
package com.inputstick.api.layout;
public class FinnishLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "fi-FI";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,206 @@
package com.inputstick.api.layout;
public class FrenchLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "fr-FR";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -153,49 +153,6 @@ public class GermanLayout extends KeyboardLayout {
}; };
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 static GermanLayout instance = new GermanLayout();
private GermanLayout() { private GermanLayout() {

View File

@ -0,0 +1,201 @@
package com.inputstick.api.layout;
public class GermanMacLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "de-DE-mac";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,159 @@
package com.inputstick.api.layout;
public class HebrewLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "he-IL";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,160 @@
package com.inputstick.api.layout;
public class ItalianLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "it-IT";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -2,6 +2,7 @@ package com.inputstick.api.layout;
import com.inputstick.api.ConnectionManager; import com.inputstick.api.ConnectionManager;
import com.inputstick.api.basic.InputStickHID; import com.inputstick.api.basic.InputStickHID;
import com.inputstick.api.basic.InputStickKeyboard;
import com.inputstick.api.hid.HIDKeycodes; import com.inputstick.api.hid.HIDKeycodes;
import com.inputstick.api.hid.HIDTransaction; import com.inputstick.api.hid.HIDTransaction;
import com.inputstick.api.hid.KeyboardReport; import com.inputstick.api.hid.KeyboardReport;
@ -122,6 +123,8 @@ public abstract class KeyboardLayout {
public abstract int[][] getDeadkeyLUT(); public abstract int[][] getDeadkeyLUT();
public abstract int[] getDeadkeys(); public abstract int[] getDeadkeys();
public abstract String getLocaleName(); public abstract String getLocaleName();
//types text assuming that USB host uses the same keyboard layout
public abstract void type(String text); public abstract void type(String text);
public abstract void type(String text, byte modifiers); public abstract void type(String text, byte modifiers);
public abstract char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr); public abstract char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr);
@ -131,9 +134,15 @@ public abstract class KeyboardLayout {
char[] chars = text.toCharArray(); char[] chars = text.toCharArray();
HIDTransaction t; HIDTransaction t;
for (char c : chars) { for (char c : chars) {
t = getHIDTransaction(lut, deadkeyLUT, deadkeys, c, modifiers); if (c == '\n') {
if (t != null) { InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER);
InputStickHID.addKeyboardTransaction(t); } 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);
}
} }
} }
} }
@ -315,6 +324,7 @@ public abstract class KeyboardLayout {
return t; 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) { public static KeyboardLayout getLayout(String locale) {
if (locale != null) { if (locale != null) {
if (locale.equals(UnitedStatesLayout.getInstance().getLocaleName())) { if (locale.equals(UnitedStatesLayout.getInstance().getLocaleName())) {

View File

@ -0,0 +1,221 @@
package com.inputstick.api.layout;
public class NorwegianLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "nb-NO";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,226 @@
package com.inputstick.api.layout;
public class PortugueseBrazilianLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "pt-BR";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,299 @@
package com.inputstick.api.layout;
public class SlovakLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "sk-SK";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,222 @@
package com.inputstick.api.layout;
public class SpanishLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "es-ES";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,218 @@
package com.inputstick.api.layout;
public class SwedishLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "sv-SE";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,199 @@
package com.inputstick.api.layout;
public class SwissFrenchLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "fr-CH";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,220 @@
package com.inputstick.api.layout;
public class SwissGermanLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "de-CH";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -0,0 +1,160 @@
package com.inputstick.api.layout;
public class UnitedKingdomLayout extends KeyboardLayout {
public static final String LOCALE_NAME = "en-GB";
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 void type(String text) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, text, (byte)0);
}
@Override
public void type(String text, byte modifiers) {
super.type(LUT, DEADKEY_LUT, DEADKEYS, 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;
}
}

View File

@ -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);
}
}

View File

@ -32,29 +32,16 @@ public class InitManager {
mListener = listener; mListener = listener;
mPacketManager = packetManager; mPacketManager = packetManager;
initDone = false; initDone = false;
} }
//WRONG THREAD!
/*public void startTimeoutCountdown(int timeout) {
t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
if ( !initDone) {
mListener.onInitFailure(InputStickError.ERROR_INIT_TIMEDOUT);
}
}
}, timeout);
}*/
public void onConnected() { public void onConnected() {
mListener.onInitReady(); mListener.onInitReady();
} }
public void onData(byte[] data) { public void onData(byte[] data) {
//byte cmd = data[0]; //byte cmd = data[0];
//byte param = data[1]; //byte param = data[1];
} }
public void sendPacket(Packet p) { public void sendPacket(Packet p) {

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="keepass2android.plugin.inputstick" package="keepass2android.plugin.inputstick"
android:versionCode="4" android:versionCode="5"
android:versionName="1.3" > android:versionName="1.31" >
<uses-sdk <uses-sdk
android:minSdkVersion="14" android:minSdkVersion="14"

View File

@ -0,0 +1,42 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<TextView
android:id="@+id/textViewLayoutInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/selected_keyboard_layout" />
<Button
android:id="@+id/buttonShiftDummy"
android:enabled="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textViewLayoutInfo"
android:layout_marginTop="10dp"
android:text="Shift" />
<Button
android:id="@+id/buttonNextToShift"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/buttonShiftDummy"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/buttonShiftDummy"
android:text="Z" />
<TextView
android:id="@+id/textViewMacSetupInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/buttonShiftDummy"
android:layout_marginTop="15dp"
android:text="@string/osx_setup_note" />
</RelativeLayout>

View File

@ -0,0 +1,177 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >
<Button
android:id="@+id/buttonPrev"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/linearLayout1"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="&lt;" />
<Button
android:id="@+id/buttonNext"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/linearLayout1"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text=">" />
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/buttonNext"
android:layout_toRightOf="@+id/buttonPrev"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/buttonChar1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/buttonChar5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar7"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar8"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/buttonChar9"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar10"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar11"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar12"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/buttonChar13"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar14"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar15"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
<Button
android:id="@+id/buttonChar16"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="00" />
</LinearLayout>
</LinearLayout>
<CheckBox
android:id="@+id/checkBoxShowPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/linearLayout1"
android:text="@string/show_password" />
</RelativeLayout>

View File

@ -0,0 +1,34 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >
<CheckBox
android:id="@+id/checkBoxAutoConnect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Auto-connect" />
<RadioGroup
android:id="@+id/radioGroup1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/radioButtonPrimary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="Primary layout" />
<RadioButton
android:id="@+id/radioButtonSecondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Secondary layout" />
</RadioGroup>
</LinearLayout>

View File

@ -0,0 +1,44 @@
<html>
<head>
<style type='text/css'>
a { color:#000000 }
div.title {
color:287AA9;
font-size:1.2em;
font-weight:bold;
margin-top:1em;
margin-bottom:0.5em;
text-align:center }
div.subtitle {
color:287AA9;
font-size:0.8em;
margin-bottom:1em;
text-align:center }
div.freetext { color:#000000 }
div.list { color:#000000 }
</style>
</head>
<body>
$ 1.31
% Version 1.31
* Typing speed can be decreased (Settings)
* Added "Type (slow)" action
* Added option to keep connection after entry is closed (Settings)
* Added "Help" webpage button (Settings)
* Autoconnect timeout can be configured in Settings
* Action names changed to: "%name (%layout) (InputStick)"
* More UI configuration options
* Added reminder about reloading entry if UI-related settings were modified
* Polish translation
$ 1.30
% Version 1.30
* More keyboard layouts
* Introduced secondary layout option
* Autoconnect can now be disabled
* Support for typing masked passwords
* UI customization
* Mac OSX setup screen (for Keyboard Setup Assistant)
* Changelog
$ END_OF_CHANGE_LOG
</body>
</html>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">InputStick Plugin dla KP2A</string>
<string name="action_settings">Ustawienia</string>
<string name="kp2aplugin_title">InputStick Plugin</string>
<string name="kp2aplugin_shortdesc">Pozwól na przesyłanie tekstu z KP2A do Twojego PC poprzez InputStick.</string>
<string name="kp2aplugin_author">Philipp Crocoll</string>
<string name="enabled">Włączony</string>
<string name="action_type">Wpisz</string>
<string name="action_type_slow">Wpisz (powoli)</string>
<string name="action_type_tab">Tab</string>
<string name="action_type_enter">Enter</string>
<string name="action_type_user_tab_pass">Login/hasło</string>
<string name="action_type_user_tab_pass_enter">Login/hasło/Enter</string>
<string name="action_open_settings">Ustawienia</string>
<string name="action_open_mac_setup">OSX konfiguracja</string>
<string name="action_masked_password">Maskowane hasło</string>
<string name="title_activity_masked_password">Wpisz maskowane hasło</string>
<string name="title_activity_init">Plugin Init</string>
<string name="configuration_title">Plugin Configuration</string>
<string name="configuration_message">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.</string>
<string name="changelog_full_title">Historia zmian</string>
<string name="changelog_title">Ostatnie zmiany</string>
<string name="changelog_ok_button">OK</string>
<string name="changelog_show_full">więcej&#8230;</string>
<string name="title_activity_mac_setup">Konfiguracja Mac OSX</string>
<string name="hello_world">Hello world!</string>
<string name="not_ready">InputStick NIE jest gotowy!</string>
<string name="show_password">Pokaż hasło</string>
<string name="selected_keyboard_layout">Wybrany układ klawiatury: </string>
<string name="osx_setup_note">Ważne: skorzystaj z tego ekranu, gdy OSX poprosi o naciśnięcie klawisza na prawo od lewego Shifta</string>
</resources>

View File

@ -0,0 +1,105 @@
<resources>
<string name="title_activity_settings">KP2A InputStick Ustawienia</string>
<!-- Strings related to Settings -->
<string name="configure_plugin">Ustaw jako plugin</string>
<string name="show_changelog_title">Pokaż zmiany</string>
<string name="show_help_webpage_title">Otwórz stronę z pomocą</string>
<string name="typing_settings_title">Układ klawiatury hosta USB</string>
<string name="connection_settings_title">Połączenie z InputStick</string>
<string name="layout_title">Układ klawiatury (główny)</string>
<string name="secondary_layout_title">Układ klawiatury (dodatkowy)</string>
<string name="show_secondary_title">Dodatkowy układ klawiatury</string>
<string name="show_secondary_summary_on">Dodatkowy układ klawiatury jest włączony. Możesz wybrać jakie akcje będą dostępne dla tego układu (zobacz niżej)</string>
<string name="show_secondary_summary_off">Dodatkowy układ klawiatury jest wyłączony</string>
<string name="enter_after_url_title">Enter po URL</string>
<string name="enter_after_url_summary_on">Zawsze dodaj Enter po wpisaniu pola URL</string>
<string name="enter_after_url_summary_off">Nic nie rób po wpisaniu pola URL</string>
<string name="autoconnect_title">Łącz automatycznie</string>
<string name="autoconnect_summary_on">Łącz z InputStick za każdym razem gdy otwierany jest wpis. Użyj tego trybu gdy korzystasz z InputStick przez większość czasu.</string>
<string name="autoconnect_summary_off">Łą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.</string>
<string name="autoconnect_timeout_title">Timeout</string>
<string name="ui_general_title">Widoczne elementy interfejsu (Ogólne, zakres dla wpisu)</string>
<string name="show_settings_title">Skrót: ustawienia</string>
<string name="show_mac_setup_title">Skrót: konfiguracja OSX</string>
<string name="mac_setup_summary">Pozwala poprawnie zidentyfikować układ klawiatury na OSX</string>
<string name="show_tab_enter_title">Akcje: Tab i Enter</string>
<string name="ui_entry_primary_title">Widoczne elementy interfejsu (Główny układ klawiatury, zakres dla wpisu)</string>
<string name="ui_entry_secondary_title">Widoczne elementy interfejsu (Dodatkowy układ klawiatury, zakres dla wpisu)</string>
<string name="show_user_pass_title">Login/hasło</string>
<string name="show_user_pass_enter_title">Login/hasło/enter</string>
<string name="show_masked_title">"Maskowane" hasło</string>
<string name="ui_filed_primary_title">Widoczne elementy interfejsu (Główny układ klawiatury, zakres dla pola)</string>
<string name="ui_filed_secondary_title">Widoczne elementy interfejsu (Dodatkowy układ klawiatury, zakres dla pola)</string>
<string name="show_field_type">Wpisz</string>
<string name="show_field_type_slow">Wpisz (powoli)</string>
<string name="field_type_slow_summary">Wpisywanie ze zredukowaną szybkością: 0.1x standardowej. Użyj gdy host USB nie akceptuje szybko wprowadzanego tekstu (np: BIOS)</string>
<string name="typing_speed_title">Szybkość wpisywania</string>
<string name="do_not_disconnect_title">Utrzymuj połączenie</string>
<string name="do_not_disconnect_summary_on">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</string>
<string name="do_not_disconnect_summary_off">Połaczenie zostanie zakończone gdy wpis jest zamykany.</string>
<string name="ok">OK</string>
<string name="important_title">Ważne!</string>
<string name="entry_reload_message">Ustawienia elementów interfejsu będą widoczne dopiero po załadowaniu nowego wpisu</string>
<string name="do_not_remind">Nie przypominaj</string>
<string-array name="autoconnect_timeout_names">
<item>Brak</item>
<item>1 min</item>
<item>3 min</item>
<item>10 min</item>
<item>30 min</item>
<item>60 min</item>
</string-array>
<string-array name="typing_speed_names">
<item>Standardowa (1.0)</item>
<item>Wolno (0.5)</item>
<item>Wolniej (0.2)</item>
<item>Najwolniej (0.1)</item>
</string-array>
<string-array name="layout_names">
<item>Duński</item>
<item>Angielski (US)</item>
<item>Angielski (UK)</item>
<item>Fiński</item>
<item>Francuski</item>
<item>Francuski (Swiss)</item>
<item>Niemiecki</item>
<item>Niemiecki (Mac)</item>
<item>Niemiecki (Swiss)</item>
<item>Hebrajski</item>
<item>Włoski</item>
<item>Norweski</item>
<item>Polski</item>
<item>Portugalski (BR)</item>
<item>Rosyjski</item>
<item>Słowacki</item>
<item>Hiszpański</item>
<item>Szwedzki</item>
<item>Angielski (Dvorak)</item>
</string-array>
</resources>

View File

@ -6,24 +6,34 @@
<string name="kp2aplugin_title">InputStick Plugin</string> <string name="kp2aplugin_title">InputStick Plugin</string>
<string name="kp2aplugin_shortdesc">Allows to send text from KP2A via InputStick to your PC.</string> <string name="kp2aplugin_shortdesc">Allows to send text from KP2A via InputStick to your PC.</string>
<string name="kp2aplugin_author">Philipp Crocoll</string> <string name="kp2aplugin_author">Philipp Crocoll</string>
<string name="action_input_stick">Type with InputStick</string>
<string name="action_type_tab">Type Tab with InputStick</string> <string name="enabled">Enabled</string>
<string name="action_type_enter">Type Enter with InputStick</string>
<string name="action_type_user_tab_pass">Type username/password with InputStick</string> <string name="action_type">Type</string>
<string name="action_type_user_tab_pass_enter">Type username/password/enter with InputStick</string> <string name="action_type_slow">Type (slow)</string>
<string name="action_quick_settings">(InputStick) Quick settings</string> <string name="action_type_tab">Tab</string>
<string name="action_open_settings">(InputStick) Settings</string> <string name="action_type_enter">Enter</string>
<string name="action_open_mac_setup">(InputStick) Mac OSX setup</string> <string name="action_type_user_tab_pass">Username/password</string>
<string name="action_masked_password">(InputStick) Masked Password</string> <string name="action_type_user_tab_pass_enter">Username/password/Enter</string>
<string name="action_open_settings">Settings</string>
<string name="action_open_mac_setup">OSX setup</string>
<string name="action_masked_password">Masked Password</string>
<string name="title_activity_masked_password">Type Masked Password</string> <string name="title_activity_masked_password">Type Masked Password</string>
<string name="title_activity_init">Plugin Init</string> <string name="title_activity_init">Plugin Init</string>
<string name="configuration_title">Plugin Configuration</string> <string name="configuration_title">Plugin Configuration</string>
<string name="configuration_message">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 everytime 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.</string> <string name="configuration_message">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.</string>
<string name="changelog_full_title">Change Log</string> <string name="changelog_full_title">Change Log</string>
<string name="changelog_title">What\'s New</string> <string name="changelog_title">What\'s New</string>
<string name="changelog_ok_button">OK</string> <string name="changelog_ok_button">OK</string>
<string name="changelog_show_full">more...</string> <string name="changelog_show_full">more&#8230;</string>
<string name="title_activity_mac_setup">Mac OSX Setup</string> <string name="title_activity_mac_setup">Mac OSX Setup</string>
<string name="hello_world">Hello world!</string> <string name="hello_world">Hello world!</string>
<string name="not_ready">InputStick is NOT ready!</string>
<string name="show_password">Show password</string>
<string name="selected_keyboard_layout">Selected keyboard layout: </string>
<string name="osx_setup_note">Note: use this screen when OSX &quot;Keyboard Setup Assistant&quot; asks you to: &quot;Press the key immediatelly to the right of the Shift key on the left side of the keyboard that can't be identified&quot;</string>
</resources> </resources>

View File

@ -6,34 +6,78 @@
<string name="configure_plugin">Configure as plugin</string> <string name="configure_plugin">Configure as plugin</string>
<string name="show_changelog_title">Show changelog</string> <string name="show_changelog_title">Show changelog</string>
<string name="show_help_webpage_title">Open help webpage</string>
<string name="typing_settings_title">USB host keyboard layout settings</string> <string name="typing_settings_title">USB host keyboard layout settings</string>
<string name="connection_settings_title">InputStick connection settings</string> <string name="connection_settings_title">InputStick connection settings</string>
<string name="ui_settings_title">UI settings</string>
<string name="layout_title">Host keyboard layout (primary)</string> <string name="layout_title">Host keyboard layout (primary)</string>
<string name="secondary_layout_title">Host keyboard layout (secondary)</string> <string name="secondary_layout_title">Host keyboard layout (secondary)</string>
<string name="enable_secondary_layout_title">Enable secondary layout</string>
<string name="show_secondary_title">Enable secondary layout</string> <string name="show_secondary_title">Secondary layout</string>
<string name="show_secondary_summary">When enabled, both layouts options will be shown for each entry and field.\nNOTE: will take effect after entry is reloaded!</string> <string name="show_secondary_summary_on">Secondary keyboard layout is enabled. You can choose which actions will be available for this layout (see below)</string>
<string name="show_secondary_summary_off">Secondary keyboard layout is disabled</string>
<string name="enter_after_url_title">Always add Enter after typing URL</string> <string name="enter_after_url_title">Enter after URL</string>
<string name="enter_after_url_summary_on">Press Enter key after typing URL field</string>
<string name="enter_after_url_summary_off">Do nothing after typing URL field</string>
<string name="autoconnect_title">InputStick autoconnect</string> <string name="autoconnect_title">Autoconnect</string>
<string name="autoconnect_summary">Connect to InputStick every time entry is opened. If not checked, connection will be established before typing OR after entry is opened, but only if typing action was used within last 10min.\nENABLE - when InputStick is used most of the time.\nDISABLE - when InputStick is used occasionally</string> <string name="autoconnect_summary_on">Connect to InputStick each time entry is being opened. Use this mode when InputStick is used most of the time.</string>
<string name="autoconnect_summary_off">Connect to InputStick before typing text OR when entry is being opened within \"Timeout\" (see below) since last typing action. Use this mode when InputStick is used occasionally</string>
<string name="show_tab_enter_title">Show Tab and Enter actions</string> <string name="autoconnect_timeout_title">Timeout</string>
<string name="show_user_pass_title">Show username/password shortcut</string>
<string name="show_user_pass_enter_title">Show username/password/enter shortcut</string>
<string name="show_masked_title">Show Masked Password shortcut</string>
<string name="show_settings_title">Show Settings shortcut</string>
<string name="show_mac_setup_title">Show Mac OSX Setup shortcut</string>
<string name="mac_setup_summary">Allows to properly identify InputStick as a keyboard on OSX PCs.</string>
<string name="ui_general_title">Visible UI elements (General, Entry Scope)</string>
<string name="show_settings_title">Settings shortcut</string>
<string name="show_mac_setup_title">OSX Setup shortcut</string>
<string name="mac_setup_summary">Helps to properly identify InputStick as a keyboard on OSX PCs.</string>
<string name="show_tab_enter_title">Tab and Enter actions</string>
<string name="ui_entry_primary_title">Visible UI elements (Primary keyboard layout, Entry Scope)</string>
<string name="ui_entry_secondary_title">Visible UI elements (Secondary keyboard layout, Entry Scope)</string>
<string name="show_user_pass_title">Username/password</string>
<string name="show_user_pass_enter_title">Username/password/enter</string>
<string name="show_masked_title">Masked Password shortcut</string>
<string name="ui_filed_primary_title">Visible UI elements (Primary keyboard layout, Field Scope)</string>
<string name="ui_filed_secondary_title">Visible UI elements (Secondary keyboard layout, Field Scope)</string>
<string name="show_field_type">Type</string>
<string name="show_field_type_slow">Type (slow)</string>
<string name="field_type_slow_summary">Type with reduced speed: 0.1x normal. Use when USB host does not accept fast keyboard input (example: BIOS)</string>
<string name="typing_speed_title">Typing speed</string>
<string name="do_not_disconnect_title">Stay connected</string>
<string name="do_not_disconnect_summary_on">Connection will NOT be closed after closing entry. You must disconnect manually or set timeout in InputStickUtility application</string>
<string name="do_not_disconnect_summary_off">Connection will be closed after closing entry.</string>
<string name="ok">OK</string>
<string name="important_title">Important!</string>
<string name="entry_reload_message">UI elements changes will be visible after new entry is opened</string>
<string name="do_not_remind">Do not remind</string>
<string-array name="autoconnect_timeout_names">
<item>Disabled</item>
<item>1 min</item>
<item>3 min</item>
<item>10 min</item>
<item>30 min</item>
<item>60 min</item>
</string-array>
<string-array name="typing_speed_names">
<item>Normal (1.0)</item>
<item>Slow (0.5)</item>
<item>Slower (0.2)</item>
<item>Slowest (0.1)</item>
</string-array>
<string-array name="layout_names"> <string-array name="layout_names">
<item>Danish</item> <item>Danish</item>
@ -57,6 +101,23 @@
<item>English (Dvorak)</item> <item>English (Dvorak)</item>
</string-array> </string-array>
<string-array name="autoconnect_timeout_values">
<item>0</item>
<item>60000</item>
<item>180000</item>
<item>600000</item>
<item>1800000</item>
<item>3600000</item>
</string-array>
<string-array name="typing_speed_values">
<item>1</item>
<item>2</item>
<item>5</item>
<item>10</item>
</string-array>
<string-array name="layout_values"> <string-array name="layout_values">
<item>da-DK</item> <item>da-DK</item>
<item>en-US</item> <item>en-US</item>

View File

@ -9,6 +9,13 @@
android:key="show_changelog_preference_key" android:key="show_changelog_preference_key"
android:title="@string/show_changelog_title" > android:title="@string/show_changelog_title" >
</Preference> </Preference>
<Preference
android:key="show_help_webpage_key"
android:title="@string/show_help_webpage_title" >
</Preference>
<!-- <!--
NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to
@ -32,7 +39,8 @@
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="false" android:defaultValue="false"
android:key="show_secondary" android:key="show_secondary"
android:summary="@string/show_secondary_summary" android:summaryOn="@string/show_secondary_summary_on"
android:summaryOff="@string/show_secondary_summary_off"
android:title="@string/show_secondary_title" /> android:title="@string/show_secondary_title" />
<ListPreference <ListPreference
@ -47,7 +55,18 @@
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="false" android:defaultValue="false"
android:key="enter_after_url" android:key="enter_after_url"
android:title="@string/enter_after_url_title" /> android:summaryOn="@string/enter_after_url_summary_on"
android:summaryOff="@string/enter_after_url_summary_off"
android:title="@string/enter_after_url_title" />
<ListPreference
android:defaultValue="1"
android:entries="@array/typing_speed_names"
android:entryValues="@array/typing_speed_values"
android:key="typing_speed"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="@string/typing_speed_title" />
</PreferenceCategory> </PreferenceCategory>
@ -56,18 +75,48 @@
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="true" android:defaultValue="true"
android:key="autoconnect" android:key="autoconnect"
android:summary="@string/autoconnect_summary" android:summaryOn="@string/autoconnect_summary_on"
android:summaryOff="@string/autoconnect_summary_off"
android:title="@string/autoconnect_title" /> android:title="@string/autoconnect_title" />
<ListPreference
android:defaultValue="600000"
android:entries="@array/autoconnect_timeout_names"
android:entryValues="@array/autoconnect_timeout_values"
android:key="autoconnect_timeout"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="@string/autoconnect_timeout_title" />
<CheckBoxPreference
android:defaultValue="false"
android:key="do_not_disconnect"
android:summaryOn="@string/do_not_disconnect_summary_on"
android:summaryOff="@string/do_not_disconnect_summary_off"
android:title="@string/do_not_disconnect_title" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/ui_settings_title" > <PreferenceCategory android:title="@string/ui_general_title" >
<CheckBoxPreference
android:defaultValue="true"
android:key="show_settings"
android:title="@string/show_settings_title" />
<CheckBoxPreference
android:defaultValue="true"
android:key="show_mac_setup"
android:summary="@string/mac_setup_summary"
android:title="@string/show_mac_setup_title" />
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="true" android:defaultValue="true"
android:key="show_tab_enter" android:key="show_tab_enter"
android:title="@string/show_tab_enter_title" /> android:title="@string/show_tab_enter_title" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/ui_entry_primary_title" >
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="true" android:defaultValue="true"
android:key="show_user_pass" android:key="show_user_pass"
@ -81,19 +130,52 @@
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="true" android:defaultValue="true"
android:key="show_masked" android:key="show_masked"
android:title="@string/show_masked_title" /> android:title="@string/show_masked_title" />
<CheckBoxPreference
android:defaultValue="true"
android:key="show_settings"
android:title="@string/show_settings_title" />
<CheckBoxPreference
android:defaultValue="true"
android:key="show_mac_setup"
android:summary="@string/mac_setup_summary"
android:title="@string/show_mac_setup_title" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/ui_filed_primary_title" >
<CheckBoxPreference
android:defaultValue="true"
android:key="show_field_type"
android:title="@string/show_field_type" />
<CheckBoxPreference
android:defaultValue="false"
android:key="show_field_type_slow"
android:summary="@string/field_type_slow_summary"
android:title="@string/show_field_type_slow" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/ui_entry_secondary_title" >
<CheckBoxPreference
android:defaultValue="false"
android:key="show_user_pass_secondary"
android:title="@string/show_user_pass_title" />
<CheckBoxPreference
android:defaultValue="false"
android:key="show_user_pass_enter_secondary"
android:title="@string/show_user_pass_enter_title" />
<CheckBoxPreference
android:defaultValue="false"
android:key="show_masked_secondary"
android:title="@string/show_masked_title" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/ui_filed_secondary_title" >
<CheckBoxPreference
android:defaultValue="false"
android:key="show_field_type_secondary"
android:title="@string/show_field_type" />
<CheckBoxPreference
android:defaultValue="false"
android:key="show_field_type_slow_secondary"
android:summary="@string/field_type_slow_summary"
android:title="@string/show_field_type_slow" />
</PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@ -16,7 +16,7 @@ public class ActionReceiver extends keepass2android.pluginsdk.PluginActionBroadc
private static final String ACTION_SETTINGS = "settings"; private static final String ACTION_SETTINGS = "settings";
private static final String ACTION_USER_PASS = "user_pass"; 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_USER_PASS_ENTER = "user_pass_enter";
private static final String ACTION_MAC_SETUP = "mac_setup"; private static final String ACTION_MAC_SETUP = "mac_setup";
private static final int IC = R.drawable.ic_launcher; private static final int IC = R.drawable.ic_launcher;
@ -32,114 +32,140 @@ public class ActionReceiver extends keepass2android.pluginsdk.PluginActionBroadc
try { try {
enterAfterURL = prefs.getBoolean("enter_after_url", true); enterAfterURL = prefs.getBoolean("enter_after_url", true);
boolean showSecondary = prefs.getBoolean("show_secondary", false); boolean showSecondary = prefs.getBoolean("show_secondary", false);
String layoutPrimary = prefs.getString("kbd_layout", "en-US"); String layoutPrimary = prefs.getString("kbd_layout", "en-US"); //layout code used when typing
String layoutSecondary = prefs.getString("secondary_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; Bundle b;
String displayText; String displayText;
for (String field: oe.getEntryFields().keySet()) {
boolean showType = prefs.getBoolean("show_field_type", true);
displayText = ctx.getString(R.string.action_input_stick); boolean showTypeSlow = prefs.getBoolean("show_field_type_slow", false);
if (showSecondary) { boolean showTypeSec = prefs.getBoolean("show_field_type_secondary", false);
displayText += " (" + layoutPrimary + ")"; boolean showTypeSlowSec = prefs.getBoolean("show_field_type_slow_secondary", false);
} for (String field: oe.getEntryFields().keySet()) {
b = new Bundle(); if (showType) {
b.putString(Const.EXTRA_LAYOUT, layoutPrimary); displayText = getActionString(ctx, R.string.action_type, layoutPrimaryDisplayCode, true);
oe.addEntryFieldAction("keepass2android.plugin.inputstick.type", Strings.PREFIX_STRING + field, displayText, IC, b);
if (showSecondary) {
displayText = oe.getContext().getString(R.string.action_input_stick) + " (" + layoutSecondary + ")";
b = new Bundle(); b = new Bundle();
b.putString(Const.EXTRA_LAYOUT, layoutSecondary); b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
oe.addEntryFieldAction("keepass2android.plugin.inputstick.typesecondary", Strings.PREFIX_STRING + field, displayText, IC, b); 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);
}
} }
} }
if (prefs.getBoolean("show_tab_enter", true)) {
b = new Bundle();
b.putString(Const.EXTRA_TEXT, "\t");
oe.addEntryAction(ctx.getString(R.string.action_type_tab), IC, b);
b = new Bundle();
b.putString(Const.EXTRA_TEXT, "\n");
oe.addEntryAction(ctx.getString(R.string.action_type_enter), IC, b);
}
if (prefs.getBoolean("show_user_pass", true)) {
displayText = ctx.getString(R.string.action_type_user_tab_pass);
if (showSecondary) {
displayText += " (" + layoutPrimary + ")";
}
b = new Bundle();
b.putString(Const.EXTRA_TEXT, ACTION_USER_PASS);
b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
oe.addEntryAction(displayText, IC, b);
if (showSecondary) {
displayText = oe.getContext().getString(R.string.action_type_user_tab_pass) + " (" + layoutSecondary + ")";
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", false)) {
displayText = ctx.getString(R.string.action_type_user_tab_pass_enter);
if (showSecondary) {
displayText += " (" + layoutPrimary + ")";
}
b = new Bundle();
b.putString(Const.EXTRA_TEXT, ACTION_USER_PASS_ENTER);
b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
oe.addEntryAction(displayText, IC, b);
if (showSecondary) {
displayText = oe.getContext().getString(R.string.action_type_user_tab_pass_enter) + " (" + layoutSecondary + ")";
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", true)) {
displayText = ctx.getString(R.string.action_masked_password);
if (showSecondary) {
displayText += " (" + layoutPrimary + ")";
}
b = new Bundle();
b.putString(Const.EXTRA_TEXT, ACTION_MASKED_PASSWORD);
b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
oe.addEntryAction(displayText, IC, b);
if (showSecondary) {
displayText = oe.getContext().getString(R.string.action_masked_password) + " (" + layoutSecondary + ")";
b = new Bundle();
b.putString(Const.EXTRA_TEXT, ACTION_MASKED_PASSWORD);
b.putString(Const.EXTRA_LAYOUT, layoutSecondary);
oe.addEntryAction(displayText, IC, b);
}
}
//GENERAL
if (prefs.getBoolean("show_settings", true)) { if (prefs.getBoolean("show_settings", true)) {
b = new Bundle(); b = new Bundle();
b.putString(Const.EXTRA_TEXT, ACTION_SETTINGS); b.putString(Const.EXTRA_TEXT, ACTION_SETTINGS);
oe.addEntryAction(ctx.getString(R.string.action_open_settings), IC, b); oe.addEntryAction(getActionString(ctx, R.string.action_open_settings, null, true), IC, b);
} }
if (prefs.getBoolean("show_mac_setup", true)) { if (prefs.getBoolean("show_mac_setup", true)) {
b = new Bundle(); b = new Bundle();
b.putString(Const.EXTRA_TEXT, ACTION_MAC_SETUP); b.putString(Const.EXTRA_TEXT, ACTION_MAC_SETUP);
oe.addEntryAction(ctx.getString(R.string.action_open_mac_setup), IC, b); 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) { } catch (PluginAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
//typeText(oe.getContext(), "en-US");
if (prefs.getBoolean("autoconnect", true)) { if (prefs.getBoolean("autoconnect", true)) {
typeText(ctx, "", "en-US"); typeText(ctx, "", "en-US");
} else { } else {
if ((lastTypingTime != 0) && ((System.currentTimeMillis() - AUTOCONNECT_TIMEOUT) < lastTypingTime)) { 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)"); //System.out.println("AUTOCONNECT (NO TIMEOUT)");
typeText(ctx, "", "en-US"); typeText(ctx, "", "en-US");
} }
@ -154,18 +180,33 @@ public class ActionReceiver extends keepass2android.pluginsdk.PluginActionBroadc
} }
} }
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 @Override
protected void closeEntryView(CloseEntryViewAction closeEntryView) { protected void closeEntryView(CloseEntryViewAction closeEntryView) {
Intent serviceIntent = new Intent(closeEntryView.getContext(), InputStickService.class); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(closeEntryView.getContext());
serviceIntent.setAction(InputStickService.DISCONNECT); boolean doNotDisconnect = prefs.getBoolean("do_not_disconnect", false);
closeEntryView.getContext().startService(serviceIntent); if ( !doNotDisconnect) {
//System.out.println("CLOSE ENTRY"); Intent serviceIntent = new Intent(closeEntryView.getContext(), InputStickService.class);
serviceIntent.setAction(InputStickService.DISCONNECT);
closeEntryView.getContext().startService(serviceIntent);
}
}; };
@Override @Override
protected void actionSelected(ActionSelectedAction actionSelected) { protected void actionSelected(ActionSelectedAction actionSelected) {
Context ctx = actionSelected.getContext(); Context ctx = actionSelected.getContext();
String layoutName = actionSelected.getActionData().getString(Const.EXTRA_LAYOUT, "en-US"); String layoutName = actionSelected.getActionData().getString(Const.EXTRA_LAYOUT, "en-US");
String params = actionSelected.getActionData().getString(Const.EXTRA_PARAMS, null);
if (actionSelected.isEntryAction()) { if (actionSelected.isEntryAction()) {
String text = actionSelected.getActionData().getString(Const.EXTRA_TEXT); String text = actionSelected.getActionData().getString(Const.EXTRA_TEXT);
@ -197,57 +238,87 @@ public class ActionReceiver extends keepass2android.pluginsdk.PluginActionBroadc
ctx.getApplicationContext().startActivity(i); ctx.getApplicationContext().startActivity(i);
} else { } else {
typeText(ctx, text, layoutName); typeText(ctx, text, layoutName);
} }
} else { } else {
String fieldKey = actionSelected.getFieldId().substring(Strings.PREFIX_STRING.length()); String fieldKey = actionSelected.getFieldId().substring(Strings.PREFIX_STRING.length());
String text = actionSelected.getEntryFields().get(fieldKey); String text = actionSelected.getEntryFields().get(fieldKey);
typeText(ctx, text, layoutName); typeText(ctx, text, layoutName, params);
if ((enterAfterURL) && ("URL".equals(fieldKey))) { if ((enterAfterURL) && ("URL".equals(fieldKey))) {
typeText(ctx, "\n", layoutName); typeText(ctx, "\n", layoutName, params);
} }
} }
} }
private void typeText(Context ctx, String text, String layout) { private void typeText(Context ctx, String text, String layout) {
lastTypingTime = System.currentTimeMillis(); 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); Intent serviceIntent = new Intent(ctx, InputStickService.class);
serviceIntent.setAction(InputStickService.TYPE); serviceIntent.setAction(InputStickService.TYPE);
Bundle b = new Bundle(); Bundle b = new Bundle();
b.putString(Const.EXTRA_TEXT, text); b.putString(Const.EXTRA_TEXT, text);
b.putString(Const.EXTRA_LAYOUT, layout); b.putString(Const.EXTRA_LAYOUT, layout);
b.putString(Const.EXTRA_PARAMS, params);
serviceIntent.putExtras(b); serviceIntent.putExtras(b);
ctx.startService(serviceIntent); ctx.startService(serviceIntent);
} }
@Override @Override
protected void entryOutputModified(EntryOutputModifiedAction eom) { protected void entryOutputModified(EntryOutputModifiedAction eom) {
Context ctx = eom.getContext(); Context ctx = eom.getContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
try { try {
boolean showSecondary = prefs.getBoolean("show_secondary", false); boolean showSecondary = prefs.getBoolean("show_secondary", false);
String layoutPrimary = prefs.getString("kbd_layout", "en-US"); String layoutPrimary = prefs.getString("kbd_layout", "en-US");
String layoutSecondary = prefs.getString("secondary_kbd_layout", "en-US"); String layoutSecondary = prefs.getString("secondary_kbd_layout", "en-US");
Bundle b;
String displayText;
displayText = ctx.getString(R.string.action_input_stick); String layoutPrimaryDisplayCode = null; //only for displaying layout code
String layoutSecondaryDisplayCode = null;
if (showSecondary) { if (showSecondary) {
displayText += " (" + layoutPrimary + ")"; //display layout code only if secondary layout is enabled
} layoutPrimaryDisplayCode = layoutPrimary;
b = new Bundle(); layoutSecondaryDisplayCode = layoutSecondary;
b.putString(Const.EXTRA_LAYOUT, layoutPrimary); }
eom.addEntryFieldAction("keepass2android.plugin.inputstick.type", eom.getModifiedFieldId(), displayText, IC, null);
Bundle b;
if (showSecondary) { String displayText;
displayText = ctx.getString(R.string.action_input_stick) + " (" + layoutSecondary + ")";
if (prefs.getBoolean("show_field_type", true)) {
displayText = getActionString(ctx, R.string.action_type, layoutPrimaryDisplayCode, true);
b = new Bundle(); b = new Bundle();
b.putString(Const.EXTRA_LAYOUT, layoutSecondary); b.putString(Const.EXTRA_LAYOUT, layoutPrimary);
eom.addEntryFieldAction("keepass2android.plugin.inputstick.typesecondary", eom.getModifiedFieldId(), displayText, IC, null); 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) { } catch (PluginAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -0,0 +1,13 @@
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";
}

View File

@ -5,8 +5,10 @@ import java.util.ArrayList;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
@ -22,14 +24,16 @@ public class InputStickService extends Service implements InputStickStateListene
private class ItemToType { private class ItemToType {
public String mText; public String mText;
public String mLayout; public String mLayout;
public String mParams;
ItemToType(String text, String layout) { ItemToType(String text, String layout, String params) {
mText = text; mText = text;
mLayout = layout; mLayout = layout;
mParams = params;
} }
public void type() { public void type() {
typeString(mText, mLayout); typeString(mText, mLayout, mParams);
} }
} }
@ -81,21 +85,24 @@ public class InputStickService extends Service implements InputStickStateListene
int state = InputStickHID.getState(); int state = InputStickHID.getState();
String stringToType = intent.getStringExtra(Const.EXTRA_TEXT); String stringToType = intent.getStringExtra(Const.EXTRA_TEXT);
String layoutToUse = intent.getStringExtra(Const.EXTRA_LAYOUT); 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) { switch (state) {
case ConnectionManager.STATE_CONNECTED: case ConnectionManager.STATE_CONNECTED:
case ConnectionManager.STATE_CONNECTING: case ConnectionManager.STATE_CONNECTING:
synchronized (items) { synchronized (items) {
items.add(new ItemToType(stringToType, layoutToUse)); items.add(new ItemToType(stringToType, layoutToUse, params));
} }
break; break;
case ConnectionManager.STATE_READY: case ConnectionManager.STATE_READY:
typeString(stringToType, layoutToUse); typeString(stringToType, layoutToUse, params);
break; break;
case ConnectionManager.STATE_DISCONNECTED: case ConnectionManager.STATE_DISCONNECTED:
case ConnectionManager.STATE_FAILURE: case ConnectionManager.STATE_FAILURE:
synchronized (items) { synchronized (items) {
items.add(new ItemToType(stringToType, layoutToUse)); items.add(new ItemToType(stringToType, layoutToUse, params));
} }
Log.d(_TAG, "trigger connect"); Log.d(_TAG, "trigger connect");
InputStickHID.connect(getApplication()); InputStickHID.connect(getApplication());
@ -107,9 +114,26 @@ public class InputStickService extends Service implements InputStickStateListene
} }
private void typeString(String stringToType, String layoutToUse) { 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) { if (InputStickHID.getState() == ConnectionManager.STATE_READY) {
Log.d(_TAG, "typing "+stringToType + " @ " + layoutToUse); //Log.d(_TAG, "typing "+stringToType + " @ " + layoutToUse + " @mul: " + reportMultiplier);
if (stringToType.equals("\n")) { if (stringToType.equals("\n")) {
InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER); InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_ENTER);
return; return;
@ -123,6 +147,7 @@ public class InputStickService extends Service implements InputStickStateListene
} else { } else {
Log.d(_TAG, "typing NOT READY"); Log.d(_TAG, "typing NOT READY");
} }
InputStickHID.setKeyboardReportMultiplier(1);
} }
private void typeQueue() { private void typeQueue() {

View File

@ -0,0 +1,84 @@
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;
import android.widget.TextView;
import android.widget.Toast;
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.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);
}
setContentView(R.layout.activity_mac_setup);
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);
buttonNextToShift.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (InputStickHID.getState() == ConnectionManager.STATE_READY) {
if (nonUS) {
InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_BACKSLASH_NON_US);
} else {
InputStickKeyboard.pressAndRelease(HIDKeycodes.NONE, HIDKeycodes.KEY_Z);
}
} else {
Toast.makeText(MacSetupActivity.this, R.string.not_ready, Toast.LENGTH_SHORT).show();
}
}
});
//check non-us backslash key is used by this layout:
int[][] lut = layout.getLUT();
int tmp = lut[0x56][1];
nonUS = true;
for (int i = 0; i < 0x40; i++) {
for (int j = 1; j < 6; j++) {
if (lut[i][j] == tmp) {
nonUS = false;
break;
}
}
}
if (nonUS) {
//non-US ISO
buttonNextToShift.setText(String.valueOf(layout.getChar(KeyboardLayout.hidToScanCode(HIDKeycodes.KEY_BACKSLASH_NON_US), false, false, false)));
} else {
//US ANSI
buttonNextToShift.setText(String.valueOf(layout.getChar(KeyboardLayout.hidToScanCode(HIDKeycodes.KEY_Z), false, false, false)));
}
//System.out.println("NonUS: "+nonUS);
}
}

View File

@ -1,11 +1,6 @@
package keepass2android.plugin.inputstick; package keepass2android.plugin.inputstick;
import com.inputstick.api.ConnectionManager;
import com.inputstick.api.basic.InputStickHID;
import com.inputstick.api.basic.InputStickKeyboard;
import android.app.Activity; import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment; import android.app.Fragment;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@ -14,7 +9,6 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.os.Build;
public class MainActivity extends Activity { public class MainActivity extends Activity {
@ -69,11 +63,8 @@ public class MainActivity extends Activity {
public void onClick(View v) { public void onClick(View v) {
String textToType = "some text to transfer"; String textToType = "some text to transfer";
triggerTypeService(textToType); triggerTypeService(textToType);
} }
}); });

View File

@ -0,0 +1,255 @@
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;
import android.widget.CheckBox;
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]
private static final int BUTTONS_CNT = 16;
private boolean[] wasClicked;
private MyButtonOnClickListener listener = new MyButtonOnClickListener();
private static String password;
private static KeyboardLayout layout;
private static int offset;
private Button buttonPrev;
private Button buttonNext;
private CheckBox checkBoxShowPassword;
private Button[] buttons;
private int[] buttonIds = {
R.id.buttonChar1,
R.id.buttonChar2,
R.id.buttonChar3,
R.id.buttonChar4,
R.id.buttonChar5,
R.id.buttonChar6,
R.id.buttonChar7,
R.id.buttonChar8,
R.id.buttonChar9,
R.id.buttonChar10,
R.id.buttonChar11,
R.id.buttonChar12,
R.id.buttonChar13,
R.id.buttonChar14,
R.id.buttonChar15,
R.id.buttonChar16,
};
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();
}
}
}
};
@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_masked_password);
checkBoxShowPassword = (CheckBox)findViewById(R.id.checkBoxShowPassword);
buttonPrev = (Button)findViewById(R.id.buttonPrev);
buttonNext = (Button)findViewById(R.id.buttonNext);
checkBoxShowPassword.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
refreshButtons();
}
});
buttonPrev.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (offset >= BUTTONS_CNT) {
offset -= BUTTONS_CNT;
refreshButtons();
}
}
});
buttonNext.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
offset += BUTTONS_CNT;
refreshButtons();
}
});
buttons = new Button[16];
for (int i = 0; i < 16; i++) {
buttons[i] = (Button)findViewById(buttonIds[i]);
buttons[i].setOnClickListener(listener);
}
me = this;
Bundle b = getIntent().getExtras();
if (b != null) {
password = b.getString(Const.EXTRA_TEXT, " ");
layout = KeyboardLayout.getLayout(b.getString(Const.EXTRA_LAYOUT, "en-US"));
wasClicked = new boolean[password.length()];
}
if (savedInstanceState == null) {
setTitle("Time left: " + TIME);
startTimer();
} else {
offset = savedInstanceState.getInt("offset");
wasClicked = savedInstanceState.getBooleanArray("clicked");
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("offset", offset);
savedInstanceState.putBooleanArray("clicked", wasClicked);
super.onSaveInstanceState(savedInstanceState);
}
@Override
protected void onResume() {
super.onResume();
//InputStickHID.addStateListener(this);
refreshButtons();
}
@Override
protected void onPause() {
//InputStickHID.removeStateListener(this);
super.onPause();
}
private void drawButton(int i) {
Button b = buttons[i];
int index = i + offset;
boolean enabled = true;
int color = Color.WHITE;
if (index >= password.length()) {
b.setText("");
enabled = false;
} else {
if (checkBoxShowPassword.isChecked()) {
b.setText(String.valueOf(password.charAt(index)));
} else {
b.setText(String.valueOf(index));
}
if (wasClicked[index]) {
color = Color.GREEN;
}
}
b.getBackground().setColorFilter(color, PorterDuff.Mode.MULTIPLY );
b.setEnabled(enabled);
}
private void refreshButtons() {
if ((offset + BUTTONS_CNT) >= password.length()) {
buttonNext.setEnabled(false);
} else {
buttonNext.setEnabled(true);
}
if (offset == 0) {
buttonPrev.setEnabled(false);
} else {
buttonPrev.setEnabled(true);
}
for (int i = 0; i < BUTTONS_CNT; i++) {
drawButton(i);
}
}
private void type(int n) {
if (password != null) {
if (password.length() >= n) {
int index = n;
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 {
Toast.makeText(this, R.string.not_ready, Toast.LENGTH_SHORT).show();
}
}
}
}
private class MyButtonOnClickListener implements OnClickListener {
@Override
public void onClick(View v) {
for (int i = 0; i < 16; i++) {
if (buttons[i].equals(v)) {
type(i + offset);
wasClicked[i + offset] = true;
v.getBackground().setColorFilter(Color.GREEN, PorterDuff.Mode.MULTIPLY );
}
}
}
}
/*@Override
public void onStateChanged(int state) {
refreshButtons();
}*/
}

View File

@ -0,0 +1,28 @@
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);
}
}
}

View File

@ -0,0 +1,61 @@
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();
}
}

View File

@ -10,14 +10,17 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener; import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.widget.CheckBox;
/** /**
* A {@link PreferenceActivity} that presents a set of application settings. On * A {@link PreferenceActivity} that presents a set of application settings. On
@ -30,6 +33,8 @@ import android.preference.PreferenceManager;
* href="http://developer.android.com/guide/topics/ui/settings.html">Settings * href="http://developer.android.com/guide/topics/ui/settings.html">Settings
* API Guide</a> for more information on developing a Settings UI. * API Guide</a> for more information on developing a Settings UI.
*/ */
@SuppressWarnings("deprecation")
public class SettingsActivity extends PreferenceActivity { public class SettingsActivity extends PreferenceActivity {
/** /**
* Determines whether to always show the simplified settings UI, where * Determines whether to always show the simplified settings UI, where
@ -38,6 +43,36 @@ public class SettingsActivity extends PreferenceActivity {
* shown on tablets. * shown on tablets.
*/ */
private static final boolean ALWAYS_SIMPLE_PREFS = false; 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 @Override
protected void onPostCreate(Bundle savedInstanceState) { protected void onPostCreate(Bundle savedInstanceState) {
@ -54,8 +89,8 @@ public class SettingsActivity extends PreferenceActivity {
if (prefs.getBoolean("display_configuration_message", true)) { if (prefs.getBoolean("display_configuration_message", true)) {
AlertDialog.Builder alert = new AlertDialog.Builder(this); AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle(getString(R.string.configuration_title)); alert.setTitle(R.string.configuration_title);
alert.setMessage(getString(R.string.configuration_message)); alert.setMessage(R.string.configuration_message);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() { alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) { public void onClick(DialogInterface dialog, int whichButton) {
//disable cfg message ONLY after clicking OK button //disable cfg message ONLY after clicking OK button
@ -72,6 +107,7 @@ public class SettingsActivity extends PreferenceActivity {
* device configuration dictates that a simplified, single-pane UI should be * device configuration dictates that a simplified, single-pane UI should be
* shown. * shown.
*/ */
private void setupSimplePreferencesScreen() { private void setupSimplePreferencesScreen() {
if (!isSimplePreferences(this)) { if (!isSimplePreferences(this)) {
return; return;
@ -85,9 +121,15 @@ public class SettingsActivity extends PreferenceActivity {
bindPreferenceSummaryToValue(findPreference("kbd_layout")); bindPreferenceSummaryToValue(findPreference("kbd_layout"));
bindPreferenceSummaryToValue(findPreference("secondary_kbd_layout")); bindPreferenceSummaryToValue(findPreference("secondary_kbd_layout"));
bindPreferenceSummaryToValue(findPreference("typing_speed"));
bindPreferenceSummaryToValue(findPreference("autoconnect_timeout"));
Preference enablePref = findPreference("enable_plugin_pref");
enablePref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
Preference pref;
pref = findPreference("enable_plugin_pref");
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
try { try {
@ -101,8 +143,8 @@ public class SettingsActivity extends PreferenceActivity {
} }
}); });
Preference showChangelogPref = (Preference)findPreference("show_changelog_preference_key"); pref = (Preference)findPreference("show_changelog_preference_key");
showChangelogPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
ChangeLog cl = new ChangeLog(SettingsActivity.this); ChangeLog cl = new ChangeLog(SettingsActivity.this);
@ -111,18 +153,141 @@ public class SettingsActivity extends PreferenceActivity {
} }
}); });
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 @Override
protected void onResume() { protected void onResume() {
displayReloadInfo = false;
Preference enablePref = findPreference("enable_plugin_pref"); Preference enablePref = findPreference("enable_plugin_pref");
if (AccessManager.getAllHostPackages(SettingsActivity.this).isEmpty()) { if (AccessManager.getAllHostPackages(SettingsActivity.this).isEmpty()) {
enablePref.setSummary(""); enablePref.setSummary("");
} else { } else {
enablePref.setSummary("enabled."); enablePref.setSummary(R.string.enabled);
} }
super.onResume(); 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} */ /** {@inheritDoc} */
@Override @Override

View File

@ -0,0 +1,330 @@
/**
* Copyright (C) 2011-2013, Karsten Priegnitz
*
* Permission to use, copy, modify, and distribute this piece of software
* for any purpose with or without fee is hereby granted, provided that
* the above copyright notice and this permission notice appear in the
* source code of all copies.
*
* It would be appreciated if you mention the author in your change log,
* contributors list or the like.
*
* @author: Karsten Priegnitz
* @see: http://code.google.com/p/android-change-log/
*/
package sheetrock.panda.changelog;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import keepass2android.plugin.inputstick.R;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Color;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.webkit.WebView;
public class ChangeLog {
private final Context context;
private String lastVersion, thisVersion;
// this is the key for storing the version name in SharedPreferences
private static final String VERSION_KEY = "PREFS_VERSION_KEY";
private static final String NO_VERSION = "";
/**
* Constructor
*
* Retrieves the version names and stores the new version name in
* SharedPreferences
*
* @param context
*/
public ChangeLog(Context context) {
this(context, PreferenceManager.getDefaultSharedPreferences(context));
}
/**
* Constructor
*
* Retrieves the version names and stores the new version name in
* SharedPreferences
*
* @param context
* @param sp
* the shared preferences to store the last version name into
*/
public ChangeLog(Context context, SharedPreferences sp) {
this.context = context;
// get version numbers
this.lastVersion = sp.getString(VERSION_KEY, NO_VERSION);
Log.d(TAG, "lastVersion: " + lastVersion);
try {
this.thisVersion = context.getPackageManager().getPackageInfo(
context.getPackageName(), 0).versionName;
} catch (NameNotFoundException e) {
this.thisVersion = NO_VERSION;
Log.e(TAG, "could not get version name from manifest!");
e.printStackTrace();
}
Log.d(TAG, "appVersion: " + this.thisVersion);
}
/**
* @return The version name of the last installation of this app (as
* described in the former manifest). This will be the same as
* returned by <code>getThisVersion()</code> the second time this
* version of the app is launched (more precisely: the second time
* ChangeLog is instantiated).
* @see AndroidManifest.xml#android:versionName
*/
public String getLastVersion() {
return this.lastVersion;
}
/**
* @return The version name of this app as described in the manifest.
* @see AndroidManifest.xml#android:versionName
*/
public String getThisVersion() {
return this.thisVersion;
}
/**
* @return <code>true</code> if this version of your app is started the
* first time
*/
public boolean firstRun() {
return !this.lastVersion.equals(this.thisVersion);
}
/**
* @return <code>true</code> if your app including ChangeLog is started the
* first time ever. Also <code>true</code> if your app was
* deinstalled and installed again.
*/
public boolean firstRunEver() {
return NO_VERSION.equals(this.lastVersion);
}
/**
* @return An AlertDialog displaying the changes since the previous
* installed version of your app (what's new). But when this is the
* first run of your app including ChangeLog then the full log
* dialog is show.
*/
public AlertDialog getLogDialog() {
return this.getDialog(this.firstRunEver());
}
/**
* @return an AlertDialog with a full change log displayed
*/
public AlertDialog getFullLogDialog() {
return this.getDialog(true);
}
private AlertDialog getDialog(boolean full) {
WebView wv = new WebView(this.context);
//wv.setBackgroundColor(Color.BLACK);
wv.setBackgroundColor(Color.WHITE);
wv.loadDataWithBaseURL(null, this.getLog(full), "text/html", "UTF-8",
null);
AlertDialog.Builder builder;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB){
builder = new AlertDialog.Builder(
new ContextThemeWrapper(
this.context, android.R.style.Theme_Holo_Dialog));
} else{
builder = new AlertDialog.Builder(
new ContextThemeWrapper(
this.context, android.R.style.Theme_Dialog));
}
builder.setTitle(
context.getResources().getString(
full ? R.string.changelog_full_title
: R.string.changelog_title))
.setView(wv)
.setCancelable(false)
// OK button
.setPositiveButton(
context.getResources().getString(
R.string.changelog_ok_button),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
updateVersionInPreferences();
}
});
if (!full) {
// "more ..." button
builder.setNegativeButton(R.string.changelog_show_full,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
getFullLogDialog().show();
}
});
}
return builder.create();
}
private void updateVersionInPreferences() {
// save new version number to preferences
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sp.edit();
editor.putString(VERSION_KEY, thisVersion);
// // on SDK-Versions > 9 you should use this:
// if(Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
// editor.commit();
// } else {
// editor.apply();
// }
editor.commit();
}
/**
* @return HTML displaying the changes since the previous installed version
* of your app (what's new)
*/
public String getLog() {
return this.getLog(false);
}
/**
* @return HTML which displays full change log
*/
public String getFullLog() {
return this.getLog(true);
}
/** modes for HTML-Lists (bullet, numbered) */
private enum Listmode {
NONE, ORDERED, UNORDERED,
};
private Listmode listMode = Listmode.NONE;
private StringBuffer sb = null;
private static final String EOCL = "END_OF_CHANGE_LOG";
private String getLog(boolean full) {
// read changelog.txt file
sb = new StringBuffer();
try {
InputStream ins = context.getResources().openRawResource(
R.raw.changelog);
BufferedReader br = new BufferedReader(new InputStreamReader(ins));
String line = null;
boolean advanceToEOVS = false; // if true: ignore further version
// sections
while ((line = br.readLine()) != null) {
line = line.trim();
char marker = line.length() > 0 ? line.charAt(0) : 0;
if (marker == '$') {
// begin of a version section
this.closeList();
String version = line.substring(1).trim();
// stop output?
if (!full) {
if (this.lastVersion.equals(version)) {
advanceToEOVS = true;
} else if (version.equals(EOCL)) {
advanceToEOVS = false;
}
}
} else if (!advanceToEOVS) {
switch (marker) {
case '%':
// line contains version title
this.closeList();
sb.append("<div class='title'>"
+ line.substring(1).trim() + "</div>\n");
break;
case '_':
// line contains version title
this.closeList();
sb.append("<div class='subtitle'>"
+ line.substring(1).trim() + "</div>\n");
break;
case '!':
// line contains free text
this.closeList();
sb.append("<div class='freetext'>"
+ line.substring(1).trim() + "</div>\n");
break;
case '#':
// line contains numbered list item
this.openList(Listmode.ORDERED);
sb.append("<li>" + line.substring(1).trim() + "</li>\n");
break;
case '*':
// line contains bullet list item
this.openList(Listmode.UNORDERED);
sb.append("<li>" + line.substring(1).trim() + "</li>\n");
break;
default:
// no special character: just use line as is
this.closeList();
sb.append(line + "\n");
}
}
}
this.closeList();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
private void openList(Listmode listMode) {
if (this.listMode != listMode) {
closeList();
if (listMode == Listmode.ORDERED) {
sb.append("<div class='list'><ol>\n");
} else if (listMode == Listmode.UNORDERED) {
sb.append("<div class='list'><ul>\n");
}
this.listMode = listMode;
}
}
private void closeList() {
if (this.listMode == Listmode.ORDERED) {
sb.append("</ol></div>\n");
} else if (this.listMode == Listmode.UNORDERED) {
sb.append("</ul></div>\n");
}
this.listMode = Listmode.NONE;
}
private static final String TAG = "ChangeLog";
/**
* manually set the last version name - for testing purposes only
*
* @param lastVersion
*/
public void dontuseSetLastVersion(String lastVersion) {
this.lastVersion = lastVersion;
}
}