+InputStick plugin
+ "PluginA" (sample plugin) + icons and updated text for PluginQR
							
								
								
									
										9
									
								
								src/java/InputStickAPI/.classpath
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,9 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<classpath>
 | 
			
		||||
	<classpathentry kind="src" path="src"/>
 | 
			
		||||
	<classpathentry kind="src" path="gen"/>
 | 
			
		||||
	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
 | 
			
		||||
	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
 | 
			
		||||
	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
 | 
			
		||||
	<classpathentry kind="output" path="bin/classes"/>
 | 
			
		||||
</classpath>
 | 
			
		||||
							
								
								
									
										33
									
								
								src/java/InputStickAPI/.project
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,33 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<projectDescription>
 | 
			
		||||
	<name>InputStickAPI</name>
 | 
			
		||||
	<comment></comment>
 | 
			
		||||
	<projects>
 | 
			
		||||
	</projects>
 | 
			
		||||
	<buildSpec>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>org.eclipse.jdt.core.javabuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
	</buildSpec>
 | 
			
		||||
	<natures>
 | 
			
		||||
		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
 | 
			
		||||
		<nature>org.eclipse.jdt.core.javanature</nature>
 | 
			
		||||
	</natures>
 | 
			
		||||
</projectDescription>
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
eclipse.preferences.version=1
 | 
			
		||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
 | 
			
		||||
org.eclipse.jdt.core.compiler.compliance=1.6
 | 
			
		||||
org.eclipse.jdt.core.compiler.source=1.6
 | 
			
		||||
							
								
								
									
										17
									
								
								src/java/InputStickAPI/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,17 @@
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    package="com.inputstick.api"
 | 
			
		||||
    android:versionCode="1"
 | 
			
		||||
    android:versionName="1.0" >
 | 
			
		||||
 | 
			
		||||
    <uses-sdk
 | 
			
		||||
        android:minSdkVersion="9"
 | 
			
		||||
        android:targetSdkVersion="17" />
 | 
			
		||||
 | 
			
		||||
    <application
 | 
			
		||||
        android:allowBackup="true"
 | 
			
		||||
        android:icon="@drawable/ic_launcher"
 | 
			
		||||
        android:label="@string/app_name"
 | 
			
		||||
        android:theme="@style/AppTheme" >
 | 
			
		||||
    </application>
 | 
			
		||||
 | 
			
		||||
</manifest>
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
/** Automatically generated file. DO NOT MODIFY */
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
public final class BuildConfig {
 | 
			
		||||
    public final static boolean DEBUG = true;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								src/java/InputStickAPI/gen/com/inputstick/api/R.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,47 @@
 | 
			
		||||
/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 | 
			
		||||
 *
 | 
			
		||||
 * This class was automatically generated by the
 | 
			
		||||
 * aapt tool from the resource data it found.  It
 | 
			
		||||
 * should not be modified by hand.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
public final class R {
 | 
			
		||||
    public static final class attr {
 | 
			
		||||
    }
 | 
			
		||||
    public static final class drawable {
 | 
			
		||||
        public static int ic_launcher=0x7f020000;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class string {
 | 
			
		||||
        public static int app_name=0x7f030000;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class style {
 | 
			
		||||
        /** 
 | 
			
		||||
        Base application theme, dependent on API level. This theme is replaced
 | 
			
		||||
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
            Theme customizations available in newer API levels can go in
 | 
			
		||||
            res/values-vXX/styles.xml, while customizations related to
 | 
			
		||||
            backward-compatibility can go here.
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        Base application theme for API 11+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from res/values/styles.xml on API 11+ devices.
 | 
			
		||||
    
 | 
			
		||||
 API 11 theme customizations can go here. 
 | 
			
		||||
 | 
			
		||||
        Base application theme for API 14+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from BOTH res/values/styles.xml and
 | 
			
		||||
        res/values-v11/styles.xml on API 14+ devices.
 | 
			
		||||
    
 | 
			
		||||
 API 14 theme customizations can go here. 
 | 
			
		||||
         */
 | 
			
		||||
        public static int AppBaseTheme=0x7f040000;
 | 
			
		||||
        /**  Application theme. 
 | 
			
		||||
 All customizations that are NOT specific to a particular API-level can go here. 
 | 
			
		||||
         */
 | 
			
		||||
        public static int AppTheme=0x7f040001;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/java/InputStickAPI/libs/android-support-v4.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										20
									
								
								src/java/InputStickAPI/proguard-project.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,20 @@
 | 
			
		||||
# To enable ProGuard in your project, edit project.properties
 | 
			
		||||
# to define the proguard.config property as described in that file.
 | 
			
		||||
#
 | 
			
		||||
# Add project specific ProGuard rules here.
 | 
			
		||||
# By default, the flags in this file are appended to flags specified
 | 
			
		||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
 | 
			
		||||
# You can edit the include path and order by changing the ProGuard
 | 
			
		||||
# include property in project.properties.
 | 
			
		||||
#
 | 
			
		||||
# For more details, see
 | 
			
		||||
#   http://developer.android.com/guide/developing/tools/proguard.html
 | 
			
		||||
 | 
			
		||||
# Add any project specific keep options here:
 | 
			
		||||
 | 
			
		||||
# If your project uses WebView with JS, uncomment the following
 | 
			
		||||
# and specify the fully qualified class name to the JavaScript interface
 | 
			
		||||
# class:
 | 
			
		||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
 | 
			
		||||
#   public *;
 | 
			
		||||
#}
 | 
			
		||||
							
								
								
									
										15
									
								
								src/java/InputStickAPI/project.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,15 @@
 | 
			
		||||
# This file is automatically generated by Android Tools.
 | 
			
		||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
 | 
			
		||||
#
 | 
			
		||||
# This file must be checked in Version Control Systems.
 | 
			
		||||
#
 | 
			
		||||
# To customize properties used by the Ant build system edit
 | 
			
		||||
# "ant.properties", and override values to adapt the script to your
 | 
			
		||||
# project structure.
 | 
			
		||||
#
 | 
			
		||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
 | 
			
		||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
 | 
			
		||||
 | 
			
		||||
# Project target.
 | 
			
		||||
target=android-19
 | 
			
		||||
android.library=true
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/java/InputStickAPI/res/drawable-hdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 9.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/java/InputStickAPI/res/drawable-mdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/java/InputStickAPI/res/drawable-xhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 14 KiB  | 
							
								
								
									
										11
									
								
								src/java/InputStickAPI/res/values-v11/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,11 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
        Base application theme for API 11+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from res/values/styles.xml on API 11+ devices.
 | 
			
		||||
    -->
 | 
			
		||||
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
 | 
			
		||||
        <!-- API 11 theme customizations can go here. -->
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										12
									
								
								src/java/InputStickAPI/res/values-v14/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,12 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
        Base application theme for API 14+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from BOTH res/values/styles.xml and
 | 
			
		||||
        res/values-v11/styles.xml on API 14+ devices.
 | 
			
		||||
    -->
 | 
			
		||||
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
 | 
			
		||||
        <!-- API 14 theme customizations can go here. -->
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										5
									
								
								src/java/InputStickAPI/res/values/strings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,5 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <string name="app_name">InputStickAPI</string>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										20
									
								
								src/java/InputStickAPI/res/values/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,20 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
        Base application theme, dependent on API level. This theme is replaced
 | 
			
		||||
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 | 
			
		||||
    -->
 | 
			
		||||
    <style name="AppBaseTheme" parent="android:Theme.Light">
 | 
			
		||||
        <!--
 | 
			
		||||
            Theme customizations available in newer API levels can go in
 | 
			
		||||
            res/values-vXX/styles.xml, while customizations related to
 | 
			
		||||
            backward-compatibility can go here.
 | 
			
		||||
        -->
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
    <!-- Application theme. -->
 | 
			
		||||
    <style name="AppTheme" parent="AppBaseTheme">
 | 
			
		||||
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										52
									
								
								src/java/InputStickAPI/src/com/inputstick/api/AES.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,52 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
import java.security.MessageDigest;
 | 
			
		||||
import javax.crypto.Cipher;
 | 
			
		||||
import javax.crypto.spec.IvParameterSpec;
 | 
			
		||||
import javax.crypto.spec.SecretKeySpec;
 | 
			
		||||
 | 
			
		||||
public class AES {
 | 
			
		||||
	
 | 
			
		||||
	private Cipher mCipherEncr;
 | 
			
		||||
	private Cipher mCipherDecr;
 | 
			
		||||
	private SecretKeySpec mKey;	
 | 
			
		||||
	
 | 
			
		||||
	public AES() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static byte[] getMD5(String s) {
 | 
			
		||||
		try {
 | 
			
		||||
			MessageDigest md = MessageDigest.getInstance("MD5");
 | 
			
		||||
			return md.digest(s.getBytes("UTF-8"));
 | 
			
		||||
		} catch (Exception e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		} 		
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public byte[] init(byte[] key) {
 | 
			
		||||
		byte[] iv = null;
 | 
			
		||||
		try {
 | 
			
		||||
			mKey = new SecretKeySpec(key, "AES");		
 | 
			
		||||
			mCipherEncr = Cipher.getInstance("AES/CBC/NoPadding");					
 | 
			
		||||
			mCipherEncr.init(Cipher.ENCRYPT_MODE, mKey);
 | 
			
		||||
			iv = mCipherEncr.getIV();
 | 
			
		||||
			//System.out.println("AES IV: ");
 | 
			
		||||
			Util.printHex(iv);
 | 
			
		||||
			mCipherDecr = Cipher.getInstance("AES/CBC/NoPadding");
 | 
			
		||||
			mCipherDecr.init(Cipher.DECRYPT_MODE, mKey, new IvParameterSpec(iv));
 | 
			
		||||
		} catch (Exception e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		}
 | 
			
		||||
		return iv;
 | 
			
		||||
	}		
 | 
			
		||||
	
 | 
			
		||||
	public byte[] encrypt(byte[] data) {
 | 
			
		||||
		return mCipherEncr.update(data);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public byte[] decrypt(byte[] data) {
 | 
			
		||||
		return mCipherDecr.update(data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,168 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
import java.lang.ref.WeakReference;
 | 
			
		||||
 | 
			
		||||
import android.app.Application;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.os.Message;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.bluetooth.BTService;
 | 
			
		||||
import com.inputstick.init.InitManager;
 | 
			
		||||
import com.inputstick.init.InitManagerListener;
 | 
			
		||||
 | 
			
		||||
public class BTConnectionManager extends ConnectionManager implements InitManagerListener {
 | 
			
		||||
	
 | 
			
		||||
	//private static final String mTag = "BTConnectionManager";
 | 
			
		||||
	
 | 
			
		||||
	private String mMac;
 | 
			
		||||
	private byte[] mKey;		
 | 
			
		||||
	
 | 
			
		||||
	private InitManager mInitManager;
 | 
			
		||||
	private Application mApp;
 | 
			
		||||
	private BTService mBTService;
 | 
			
		||||
	private PacketManager mPacketManager;
 | 
			
		||||
	//private PacketQueue mPacketQueue;
 | 
			
		||||
	private final BTHandler mBTHandler = new BTHandler(this);				
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
    private static class BTHandler extends Handler {    	
 | 
			
		||||
    	private final WeakReference<BTConnectionManager> ref; 
 | 
			
		||||
 | 
			
		||||
    	BTHandler(BTConnectionManager manager) { 
 | 
			
		||||
    		ref = new WeakReference<BTConnectionManager>(manager); 
 | 
			
		||||
        }    	
 | 
			
		||||
    	
 | 
			
		||||
		@Override
 | 
			
		||||
		public void handleMessage(Message msg) {
 | 
			
		||||
			BTConnectionManager manager = ref.get();
 | 
			
		||||
			switch (msg.what) {
 | 
			
		||||
				case BTService.EVENT_DATA:
 | 
			
		||||
					manager.onData((byte[])msg.obj);
 | 
			
		||||
					break;			
 | 
			
		||||
				case BTService.EVENT_CONNECTED:
 | 
			
		||||
					manager.onConnected();
 | 
			
		||||
					break;
 | 
			
		||||
				case BTService.EVENT_CANCELLED:
 | 
			
		||||
					manager.onDisconnected();
 | 
			
		||||
					break;					
 | 
			
		||||
				case BTService.EVENT_CONNECTION_FAILED:
 | 
			
		||||
					manager.onFailure(1); 
 | 
			
		||||
					break;
 | 
			
		||||
				case BTService.EVENT_CONNECTION_LOST:
 | 
			
		||||
					manager.onFailure(1); 
 | 
			
		||||
					break;					
 | 
			
		||||
				case BTService.EVENT_NO_BT_HW:
 | 
			
		||||
					manager.onFailure(1); 
 | 
			
		||||
					break;
 | 
			
		||||
				case BTService.EVENT_INVALID_MAC:
 | 
			
		||||
					manager.onFailure(1); 
 | 
			
		||||
					break;
 | 
			
		||||
				case BTService.EVENT_CMD_TIMEOUT:
 | 
			
		||||
					manager.onFailure(1); 
 | 
			
		||||
					break;
 | 
			
		||||
				case BTService.EVENT_INTERVAL_TIMEOUT:
 | 
			
		||||
					manager.onFailure(1); 
 | 
			
		||||
					break;
 | 
			
		||||
				case BTService.EVENT_TURN_ON_TIMEOUT:
 | 
			
		||||
					manager.onFailure(1); 
 | 
			
		||||
					break;					
 | 
			
		||||
				case BTService.EVENT_OTHER_ERROR:
 | 
			
		||||
					manager.onFailure(1); 
 | 
			
		||||
					break;									
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
    } 		
 | 
			
		||||
    
 | 
			
		||||
    private void onConnecting() {
 | 
			
		||||
    	stateNotify(ConnectionManager.STATE_CONNECTING);
 | 
			
		||||
    }
 | 
			
		||||
	
 | 
			
		||||
	private void onConnected() {		
 | 
			
		||||
		stateNotify(ConnectionManager.STATE_CONNECTED);
 | 
			
		||||
		mInitManager.onConnected();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void onDisconnected() {
 | 
			
		||||
		stateNotify(ConnectionManager.STATE_DISCONNECTED);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void onFailure(int code) {
 | 
			
		||||
		mErrorCode = code;
 | 
			
		||||
		stateNotify(ConnectionManager.STATE_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void onData(byte[] rawData) {
 | 
			
		||||
		byte[] data;
 | 
			
		||||
		data = mPacketManager.bytesToPacket(rawData);
 | 
			
		||||
		
 | 
			
		||||
		if (data == null) {
 | 
			
		||||
			//TODO
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		mInitManager.onData(data);
 | 
			
		||||
		
 | 
			
		||||
		//sendNext(); TODO
 | 
			
		||||
		for (InputStickDataListener listener : mDataListeners) {
 | 
			
		||||
			listener.onInputStickData(data);
 | 
			
		||||
		}		
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public BTConnectionManager(InitManager initManager, Application app, String mac, byte[] key) {		
 | 
			
		||||
		mInitManager = initManager;		
 | 
			
		||||
		mMac = mac;		
 | 
			
		||||
		mKey = key;
 | 
			
		||||
		mApp = app;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public void connect() {
 | 
			
		||||
		connect(false, BTService.DEFAULT_CONNECT_TIMEOUT);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	public void connect(boolean reflection, int timeout) {
 | 
			
		||||
		mErrorCode = ConnectionManager.ERROR_NONE;
 | 
			
		||||
		if (mBTService == null) {
 | 
			
		||||
			mBTService = new BTService(mApp, mBTHandler);
 | 
			
		||||
			mPacketManager = new PacketManager(mBTService, mKey);
 | 
			
		||||
			mInitManager.init(this, mPacketManager);
 | 
			
		||||
		}
 | 
			
		||||
		mBTService.setConnectTimeout(timeout);
 | 
			
		||||
		mBTService.enableReflection(reflection);
 | 
			
		||||
		mBTService.connect(mMac);
 | 
			
		||||
		onConnecting();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void disconnect() {
 | 
			
		||||
		if (mBTService != null) {
 | 
			
		||||
			mBTService.disconnect();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void sendPacket(Packet p) {
 | 
			
		||||
		mPacketManager.sendPacket(p); //TODO tmp; zalozmy z beda same NO_RESP ???
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onInitReady() {
 | 
			
		||||
		stateNotify(ConnectionManager.STATE_READY);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onInitNotReady() {
 | 
			
		||||
		stateNotify(ConnectionManager.STATE_CONNECTED);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onInitFailure(int code) {
 | 
			
		||||
		onFailure(code);
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,72 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
public abstract class ConnectionManager {
 | 
			
		||||
	
 | 
			
		||||
	public static final int STATE_DISCONNECTED = 0;
 | 
			
		||||
	public static final int STATE_FAILURE = 1;
 | 
			
		||||
	public static final int STATE_CONNECTING = 2;
 | 
			
		||||
	public static final int STATE_CONNECTED = 3;
 | 
			
		||||
	public static final int STATE_READY = 4;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public static final int ERROR_NONE = 0;
 | 
			
		||||
	
 | 
			
		||||
	public static final int ERROR_UNSUPPORTED_FIRMWARE = 10;
 | 
			
		||||
	public static final int ERROR_PASSWORD_PROTECTED = 11;
 | 
			
		||||
	public static final int ERROR_INVALID_KEY = 12;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	protected Vector<InputStickStateListener> mStateListeners = new Vector<InputStickStateListener>();
 | 
			
		||||
	protected Vector<InputStickDataListener> mDataListeners = new Vector<InputStickDataListener>();
 | 
			
		||||
	
 | 
			
		||||
	protected int mState;
 | 
			
		||||
	protected int mErrorCode;
 | 
			
		||||
	
 | 
			
		||||
	public abstract void connect();
 | 
			
		||||
	public abstract void disconnect();
 | 
			
		||||
	public abstract void sendPacket(Packet p);
 | 
			
		||||
	
 | 
			
		||||
	protected void stateNotify(int state) {
 | 
			
		||||
		if (mState != state) {							
 | 
			
		||||
			mState = state;
 | 
			
		||||
			for (InputStickStateListener listener : mStateListeners) {
 | 
			
		||||
				listener.onStateChanged(state);
 | 
			
		||||
			}	
 | 
			
		||||
		}
 | 
			
		||||
	}    
 | 
			
		||||
	
 | 
			
		||||
	public int getState() {
 | 
			
		||||
		return mState;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int getErrorCode() {
 | 
			
		||||
		return mErrorCode;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addStateListener(InputStickStateListener listener) {
 | 
			
		||||
		if (listener != null) {
 | 
			
		||||
			mStateListeners.add(listener);
 | 
			
		||||
		}	
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void removeStateListener(InputStickStateListener listener) {
 | 
			
		||||
		if (listener != null) {
 | 
			
		||||
			mStateListeners.remove(listener);
 | 
			
		||||
		}	
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addDataListener(InputStickDataListener listener) {
 | 
			
		||||
		if (listener != null) {
 | 
			
		||||
			mDataListeners.add(listener);
 | 
			
		||||
		}				
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void removeDataListener(InputStickDataListener listener) {
 | 
			
		||||
		if (listener != null) {
 | 
			
		||||
			mDataListeners.remove(listener);
 | 
			
		||||
		}			
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										115
									
								
								src/java/InputStickAPI/src/com/inputstick/api/HIDInfo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,115 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
public class HIDInfo {
 | 
			
		||||
	
 | 
			
		||||
	private int state;
 | 
			
		||||
	
 | 
			
		||||
	private boolean numLock;
 | 
			
		||||
	private boolean capsLock;
 | 
			
		||||
	private boolean scrollLock;
 | 
			
		||||
	
 | 
			
		||||
	private boolean keyboardReportProtocol;
 | 
			
		||||
	private boolean mouseReportProtocol;
 | 
			
		||||
	
 | 
			
		||||
	private boolean keyboardReady;
 | 
			
		||||
	private boolean mouseReady;
 | 
			
		||||
	private boolean consumerReady;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	public HIDInfo() {
 | 
			
		||||
		keyboardReportProtocol = true;
 | 
			
		||||
		mouseReportProtocol = true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void update(byte[] data) {
 | 
			
		||||
		state = data[1];
 | 
			
		||||
		
 | 
			
		||||
		int leds = data[2];
 | 
			
		||||
		if ((leds & 0x01) != 0) {
 | 
			
		||||
			numLock = true;
 | 
			
		||||
		} else {
 | 
			
		||||
			numLock = false;
 | 
			
		||||
		}
 | 
			
		||||
		if ((leds & 0x02) != 0) {
 | 
			
		||||
			capsLock = true;
 | 
			
		||||
		} else {
 | 
			
		||||
			capsLock = false;
 | 
			
		||||
		}
 | 
			
		||||
		if ((leds & 0x04) != 0) {
 | 
			
		||||
			scrollLock = true;
 | 
			
		||||
		} else {
 | 
			
		||||
			scrollLock = false;
 | 
			
		||||
		}	
 | 
			
		||||
		
 | 
			
		||||
		if (data[3] == 0) {
 | 
			
		||||
			keyboardReportProtocol = true;
 | 
			
		||||
		} else {
 | 
			
		||||
			keyboardReportProtocol = false;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (data[4] == 0) {
 | 
			
		||||
			keyboardReady = false;
 | 
			
		||||
		} else {
 | 
			
		||||
			keyboardReady = true;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (data[5] == 0) {
 | 
			
		||||
			mouseReportProtocol = true;
 | 
			
		||||
		} else {
 | 
			
		||||
			mouseReportProtocol = false;
 | 
			
		||||
		}	
 | 
			
		||||
		
 | 
			
		||||
		if (data[6] == 0) {
 | 
			
		||||
			mouseReady = false;
 | 
			
		||||
		} else {
 | 
			
		||||
			mouseReady = true;
 | 
			
		||||
		}		
 | 
			
		||||
		
 | 
			
		||||
		if (data[7] == 0) {
 | 
			
		||||
			consumerReady = false;
 | 
			
		||||
		} else {
 | 
			
		||||
			consumerReady = true;
 | 
			
		||||
		}			
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void setKeyboardBusy() {
 | 
			
		||||
		keyboardReady = false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int getState() {
 | 
			
		||||
		return state;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean getNumLock() {
 | 
			
		||||
		return numLock;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean getCapsLock() {
 | 
			
		||||
		return capsLock;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean getScrollLock() {
 | 
			
		||||
		return scrollLock;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	public boolean isKeyboardReportProtocol() {
 | 
			
		||||
		return keyboardReportProtocol;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isMouseReportProtocol() {
 | 
			
		||||
		return mouseReportProtocol;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	public boolean isKeyboardReady() {
 | 
			
		||||
		return keyboardReady;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isMouseReady() {
 | 
			
		||||
		return mouseReady;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isConsumerReady() {
 | 
			
		||||
		return consumerReady;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,180 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
import java.lang.ref.WeakReference;
 | 
			
		||||
 | 
			
		||||
import android.app.Application;
 | 
			
		||||
import android.content.ComponentName;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.content.ServiceConnection;
 | 
			
		||||
import android.content.pm.PackageManager;
 | 
			
		||||
import android.content.pm.PackageManager.NameNotFoundException;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.os.IBinder;
 | 
			
		||||
import android.os.Message;
 | 
			
		||||
import android.os.Messenger;
 | 
			
		||||
import android.os.RemoteException;
 | 
			
		||||
 | 
			
		||||
public class IPCConnectionManager extends ConnectionManager {
 | 
			
		||||
	
 | 
			
		||||
	//private static final String mTag = "IPCConnectionManager";
 | 
			
		||||
	
 | 
			
		||||
	public static final int SERVICE_CMD_CONNECT = 1;
 | 
			
		||||
	public static final int SERVICE_CMD_DISCONNECT = 2;
 | 
			
		||||
	public static final int SERVICE_CMD_DATA = 3;
 | 
			
		||||
	public static final int SERVICE_CMD_STATE = 4;
 | 
			
		||||
	
 | 
			
		||||
    Context mCtx;
 | 
			
		||||
	Messenger mService = null;    
 | 
			
		||||
	boolean mBound;
 | 
			
		||||
	boolean initSent;
 | 
			
		||||
    final Messenger mMessenger = new Messenger(new IncomingHandler(this)); 
 | 
			
		||||
    
 | 
			
		||||
    private static class IncomingHandler extends Handler {    	
 | 
			
		||||
    	private final WeakReference<IPCConnectionManager> ref; 
 | 
			
		||||
 | 
			
		||||
    	IncomingHandler(IPCConnectionManager manager) { 
 | 
			
		||||
    		ref = new WeakReference<IPCConnectionManager>(manager); 
 | 
			
		||||
        }    	
 | 
			
		||||
    	
 | 
			
		||||
        @Override
 | 
			
		||||
        public void handleMessage(Message msg) {      	
 | 
			
		||||
        	IPCConnectionManager manager = ref.get();
 | 
			
		||||
        	
 | 
			
		||||
        	switch (msg.what) {     	
 | 
			
		||||
    		case SERVICE_CMD_DATA:
 | 
			
		||||
            	byte[] data = null;        	
 | 
			
		||||
            	Bundle b = msg.getData();
 | 
			
		||||
            	if (b != null) {
 | 
			
		||||
            		data = b.getByteArray("data");
 | 
			
		||||
            		manager.onData(data);
 | 
			
		||||
            	}             	
 | 
			
		||||
    			break;
 | 
			
		||||
    		case SERVICE_CMD_STATE:
 | 
			
		||||
    			//System.out.println("CMD STATE: "+msg.arg1);
 | 
			
		||||
    			manager.stateNotify(msg.arg1);
 | 
			
		||||
    			break;             	
 | 
			
		||||
        	}         	
 | 
			
		||||
        }
 | 
			
		||||
    }     
 | 
			
		||||
    
 | 
			
		||||
    private ServiceConnection mConnection = new ServiceConnection() {
 | 
			
		||||
        public void onServiceConnected(ComponentName className, IBinder service) {
 | 
			
		||||
        	//System.out.println("onServiceConnected!");
 | 
			
		||||
            mService = new Messenger(service);
 | 
			
		||||
            mBound = true;                  
 | 
			
		||||
            sendMessage(SERVICE_CMD_CONNECT, 0, 0); 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void onServiceDisconnected(ComponentName className) {
 | 
			
		||||
            // unexpectedly disconnected from service
 | 
			
		||||
        	//System.out.println("onService DISCONNECTED!");
 | 
			
		||||
            mService = null;
 | 
			
		||||
            mBound = false;
 | 
			
		||||
            stateNotify(STATE_DISCONNECTED);
 | 
			
		||||
        }
 | 
			
		||||
    };  
 | 
			
		||||
    //SERVICE=========================================================            
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    private void sendMessage(int what, int arg1, int arg2, Bundle b) {
 | 
			
		||||
		Message msg;
 | 
			
		||||
		try {
 | 
			
		||||
			msg = Message.obtain(null, what, arg1, 0, null);
 | 
			
		||||
			msg.replyTo = mMessenger;
 | 
			
		||||
			msg.setData(b);				
 | 
			
		||||
			mService.send(msg);
 | 
			
		||||
		} catch (RemoteException e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		}    	
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private void sendMessage(int what, int arg1, int arg2, byte[] data) {
 | 
			
		||||
    	Bundle b;
 | 
			
		||||
		b = new Bundle();
 | 
			
		||||
		b.putByteArray("data", data);
 | 
			
		||||
		sendMessage(what, arg1, arg2, b);
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    private void sendMessage(int what, int arg1, int arg2) {
 | 
			
		||||
    	sendMessage(what, arg1, arg2, (Bundle)null);	
 | 
			
		||||
    }  	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	private void onData(byte[] data) {
 | 
			
		||||
		for (InputStickDataListener listener : mDataListeners) {
 | 
			
		||||
			listener.onInputStickData(data);
 | 
			
		||||
		} 		
 | 
			
		||||
	}    		
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public IPCConnectionManager(Application app) {
 | 
			
		||||
		mCtx = app.getApplicationContext();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void connect() {
 | 
			
		||||
		PackageManager pm = mCtx.getPackageManager();
 | 
			
		||||
		boolean exists = true;
 | 
			
		||||
		try {
 | 
			
		||||
			pm.getPackageInfo("com.inputstick.apps.inputstickutility", PackageManager.GET_META_DATA);
 | 
			
		||||
		} catch (NameNotFoundException e) {
 | 
			
		||||
			exists = false;
 | 
			
		||||
		}		
 | 
			
		||||
		
 | 
			
		||||
		if (exists) {
 | 
			
		||||
			mErrorCode = ConnectionManager.ERROR_NONE;
 | 
			
		||||
			Intent intent = new Intent();									
 | 
			
		||||
			intent.setComponent(new ComponentName("com.inputstick.apps.inputstickutility","com.inputstick.apps.inputstickutility.service.InputStickService"));
 | 
			
		||||
			mCtx.startService(intent);
 | 
			
		||||
			mCtx.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
 | 
			
		||||
	        if (mBound) {
 | 
			
		||||
	        	//already bound?
 | 
			
		||||
	        	//System.out.println("Service already Connected");
 | 
			
		||||
	        	sendMessage(SERVICE_CMD_CONNECT, 0, 0); 
 | 
			
		||||
	        } 
 | 
			
		||||
		} else {
 | 
			
		||||
			mErrorCode = 1; //TODO
 | 
			
		||||
			stateNotify(STATE_FAILURE);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void disconnect() {
 | 
			
		||||
		if (mBound) {
 | 
			
		||||
			//System.out.println("UNBIND");
 | 
			
		||||
			sendMessage(SERVICE_CMD_DISCONNECT, 0, 0); 
 | 
			
		||||
			Intent intent = new Intent();		   
 | 
			
		||||
			intent.setComponent(new ComponentName("com.inputstick.apps.inputstickutility","com.inputstick.apps.inputstickutility.service.InputStickService"));	
 | 
			
		||||
			mCtx.unbindService(mConnection);
 | 
			
		||||
			mCtx.stopService(intent);
 | 
			
		||||
			mBound = false;
 | 
			
		||||
			//TODO stateNotify 
 | 
			
		||||
			//service will pass notification message
 | 
			
		||||
		} else {
 | 
			
		||||
			//just set state, there is nothing else to do
 | 
			
		||||
			stateNotify(STATE_DISCONNECTED);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public void sendPacket(Packet p) {
 | 
			
		||||
		if (mState == ConnectionManager.STATE_READY) {			
 | 
			
		||||
			if (p.getRespond()) {
 | 
			
		||||
				sendMessage(IPCConnectionManager.SERVICE_CMD_DATA, 1, 0, p.getBytes());
 | 
			
		||||
			} else {
 | 
			
		||||
				sendMessage(IPCConnectionManager.SERVICE_CMD_DATA, 0, 0, p.getBytes());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
public interface InputStickDataListener {
 | 
			
		||||
 | 
			
		||||
	public void onInputStickData(byte[] data);
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
public interface InputStickKeyboardListener {
 | 
			
		||||
	
 | 
			
		||||
	public void onLEDsChanged(boolean numLock, boolean capsLock, boolean scrollLock);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
public interface InputStickStateListener {
 | 
			
		||||
	
 | 
			
		||||
	public void onStateChanged(int state); 
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										122
									
								
								src/java/InputStickAPI/src/com/inputstick/api/Packet.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,122 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
public class Packet {
 | 
			
		||||
	
 | 
			
		||||
	public static final byte NONE =						0x00;
 | 
			
		||||
	
 | 
			
		||||
	public static final byte START_TAG = 				0x55;
 | 
			
		||||
	public static final byte FLAG_RESPOND = 			(byte)0x80;
 | 
			
		||||
	public static final byte FLAG_ENCRYPTED = 			0x40;
 | 
			
		||||
	
 | 
			
		||||
	public static final int MAX_SUBPACKETS = 			17;	
 | 
			
		||||
	public static final int MAX_LENGTH = 				MAX_SUBPACKETS * 16;
 | 
			
		||||
	
 | 
			
		||||
	public static final byte CMD_IDENTIFY =		 		0x01;
 | 
			
		||||
	public static final byte CMD_LED =				 	0x02;
 | 
			
		||||
	public static final byte CMD_RUN_BL =		 		0x03;
 | 
			
		||||
	public static final byte CMD_RUN_FW =		 		0x04;
 | 
			
		||||
	public static final byte CMD_GET_INFO =		 		0x05;
 | 
			
		||||
	public static final byte CMD_BL_ERASE =		 		0x06;
 | 
			
		||||
	public static final byte CMD_ADD_DATA =		 		0x07;
 | 
			
		||||
	public static final byte CMD_BL_WRITE =		 		0x08;
 | 
			
		||||
	
 | 
			
		||||
	public static final byte CMD_FW_INFO =		 		0x10;
 | 
			
		||||
	public static final byte CMD_INIT =			 		0x11;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public static final byte CMD_HID_STATUS_REPORT = 	0x20;
 | 
			
		||||
	public static final byte CMD_HID_DATA_KEYB = 		0x21;
 | 
			
		||||
	public static final byte CMD_HID_DATA_CONSUMER =	0x22;
 | 
			
		||||
	public static final byte CMD_HID_DATA_MOUSE = 		0x23;
 | 
			
		||||
	//out	
 | 
			
		||||
	public static final byte CMD_HID_STATUS =			0x2F;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public static final byte CMD_DUMMY =	 			(byte)0xFF;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public static final byte RESP_OK =					0x01;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public static final byte[] RAW_OLD_BOOTLOADER = new byte[] {START_TAG, (byte)0x00, (byte)0x02, (byte)0x83, (byte)0x00, (byte)0xDA};			
 | 
			
		||||
	public static final byte[] RAW_DELAY_1_MS = new byte[] {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; 
 | 
			
		||||
	
 | 
			
		||||
	private byte[] mData;
 | 
			
		||||
	private int mPos;
 | 
			
		||||
	private boolean mRespond;
 | 
			
		||||
	
 | 
			
		||||
	//do not modify
 | 
			
		||||
	public Packet(boolean respond, byte[] data) {
 | 
			
		||||
		mRespond = respond;
 | 
			
		||||
		mData = data;
 | 
			
		||||
		mPos = data.length;		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Packet(boolean respond, byte cmd, byte param, byte[] data) {
 | 
			
		||||
		mRespond = respond;
 | 
			
		||||
		mData = new byte[MAX_LENGTH];
 | 
			
		||||
		mData[0] = cmd;
 | 
			
		||||
		mData[1] = param;
 | 
			
		||||
		mPos = 2;		
 | 
			
		||||
		if (data != null) {
 | 
			
		||||
			addBytes(data);
 | 
			
		||||
		}		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Packet(boolean respond, byte cmd, byte param) {
 | 
			
		||||
		this(respond, cmd, param, null);
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	public Packet(boolean respond, byte cmd) {
 | 
			
		||||
		mRespond = respond;
 | 
			
		||||
		mData = new byte[MAX_LENGTH];
 | 
			
		||||
		mData[0] = cmd;
 | 
			
		||||
		mPos = 1;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	public void modifyByte(int pos, byte b) {
 | 
			
		||||
		mData[pos] = b;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addBytes(byte[] data) {
 | 
			
		||||
		//TODO check null pointer / available size (MAX_PAYLOAD - mPos) 
 | 
			
		||||
		System.arraycopy(data, 0, mData, mPos, data.length);
 | 
			
		||||
		mPos += data.length;		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addByte(byte b) {
 | 
			
		||||
		mData[mPos++] = b;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addInt16(int val) {
 | 
			
		||||
		mData[mPos + 0] = Util.getMSB(val);
 | 
			
		||||
		mData[mPos + 1] = Util.getLSB(val);
 | 
			
		||||
		mPos += 2;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addInt32(long val) {
 | 
			
		||||
		mData[mPos + 3] = (byte)val;
 | 
			
		||||
		val >>= 8;
 | 
			
		||||
		mData[mPos + 2] = (byte)val;
 | 
			
		||||
		val >>= 8;
 | 
			
		||||
		mData[mPos + 1] = (byte)val;
 | 
			
		||||
		val >>= 8;
 | 
			
		||||
		mData[mPos + 0] = (byte)val;
 | 
			
		||||
		val >>= 8;	
 | 
			
		||||
		mPos += 4;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public byte[] getBytes() {
 | 
			
		||||
		byte[] result;		
 | 
			
		||||
		result = new byte[mPos];
 | 
			
		||||
		System.arraycopy(mData, 0, result, 0, mPos);
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean getRespond() {
 | 
			
		||||
		return mRespond;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										169
									
								
								src/java/InputStickAPI/src/com/inputstick/api/PacketManager.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,169 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.zip.CRC32;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.bluetooth.BTService;
 | 
			
		||||
 | 
			
		||||
public class PacketManager {
 | 
			
		||||
	
 | 
			
		||||
	public static final int MAX_PAYLAOD = 64;
 | 
			
		||||
	public static final int HEADER_OFFSET = 2;
 | 
			
		||||
	public static final int CRC_OFFSET = 4;
 | 
			
		||||
	public static final int PACKET_SIZE = 16;
 | 
			
		||||
	
 | 
			
		||||
	private final BTService mBTService;
 | 
			
		||||
	private final AES mAes;
 | 
			
		||||
	private final byte[] mKey;
 | 
			
		||||
	private byte[] cmpData;
 | 
			
		||||
	private final CRC32 mCrc;	
 | 
			
		||||
	private boolean mEncryption;
 | 
			
		||||
	
 | 
			
		||||
	public PacketManager(BTService btService, byte[] key) {
 | 
			
		||||
		mBTService = btService;
 | 
			
		||||
		mCrc = new CRC32();
 | 
			
		||||
		mAes = new AES();
 | 
			
		||||
		mKey = key;
 | 
			
		||||
		mEncryption = false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean setEncryption(byte[] cmp, boolean encryptOut) {
 | 
			
		||||
		byte[] cmpDec = mAes.decrypt(cmp);					
 | 
			
		||||
		if (Arrays.equals(cmpDec, cmpData)) {
 | 
			
		||||
			mEncryption = encryptOut;
 | 
			
		||||
			return true;
 | 
			
		||||
		} else {
 | 
			
		||||
			mEncryption = false;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Packet encPacket(boolean enable) {
 | 
			
		||||
		Random r = new Random();         
 | 
			
		||||
		Packet p = new Packet(true, Packet.CMD_INIT);
 | 
			
		||||
		if (enable) {
 | 
			
		||||
			p.addByte((byte)1);
 | 
			
		||||
		} else {
 | 
			
		||||
			p.addByte((byte)0);
 | 
			
		||||
		}	
 | 
			
		||||
		
 | 
			
		||||
		byte[] iv = mAes.init(mKey);		
 | 
			
		||||
		p.addBytes(iv);
 | 
			
		||||
		
 | 
			
		||||
		Util.printHex(iv, "IV: ");
 | 
			
		||||
		
 | 
			
		||||
		byte[] initData = new byte[16];
 | 
			
		||||
		r.nextBytes(initData);		
 | 
			
		||||
		mCrc.reset();
 | 
			
		||||
		mCrc.update(initData, 4, 12); //only 12 bytes!
 | 
			
		||||
		long crcValue = mCrc.getValue();
 | 
			
		||||
		initData[3] = (byte)crcValue;
 | 
			
		||||
		crcValue >>= 8;
 | 
			
		||||
		initData[2] = (byte)crcValue;
 | 
			
		||||
		crcValue >>= 8;
 | 
			
		||||
		initData[1] = (byte)crcValue;
 | 
			
		||||
		crcValue >>= 8;
 | 
			
		||||
		initData[0] = (byte)crcValue;		
 | 
			
		||||
		initData = mAes.encrypt(initData);
 | 
			
		||||
		p.addBytes(initData);				
 | 
			
		||||
		
 | 
			
		||||
		//Util.printHex(initData, "InitData: ");
 | 
			
		||||
		
 | 
			
		||||
		cmpData = new byte[16];
 | 
			
		||||
		r.nextBytes(cmpData);
 | 
			
		||||
		p.addBytes(cmpData);
 | 
			
		||||
		
 | 
			
		||||
		//Util.printHex(cmpData, "CmpData: ");		
 | 
			
		||||
		return p;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public byte[] bytesToPacket(byte[] data) {
 | 
			
		||||
		byte[] payload;		
 | 
			
		||||
		//boolean decrypt = false;
 | 
			
		||||
		long crcValue, crcCompare;
 | 
			
		||||
		
 | 
			
		||||
		payload = Arrays.copyOfRange(data, 2, data.length); //remove TAG, info
 | 
			
		||||
		if ((data[1] & Packet.FLAG_ENCRYPTED) != 0) {
 | 
			
		||||
			Util.log("DECRYPT");
 | 
			
		||||
			payload = mAes.decrypt(payload);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		Util.printHex(payload, "DATA IN: ");
 | 
			
		||||
	
 | 
			
		||||
		//check CRC		
 | 
			
		||||
		crcCompare = Util.getLong(payload[0], payload[1], payload[2], payload[3]);
 | 
			
		||||
		mCrc.reset();
 | 
			
		||||
		mCrc.update(payload, CRC_OFFSET, payload.length - CRC_OFFSET);
 | 
			
		||||
		crcValue = mCrc.getValue();
 | 
			
		||||
		//System.out.println("CMP: " + crcCompare + " VAL: " + crcValue); 				
 | 
			
		||||
		
 | 
			
		||||
		if (crcValue == crcCompare) {
 | 
			
		||||
			payload = Arrays.copyOfRange(payload, 4, payload.length); //remove CRC
 | 
			
		||||
			return payload;
 | 
			
		||||
		} else {
 | 
			
		||||
			return null; //TODO
 | 
			
		||||
		}		
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void sendRAW(byte[] data) {
 | 
			
		||||
		mBTService.write(data);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void sendPacket(Packet p) {
 | 
			
		||||
		sendPacket(p, mEncryption);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void sendPacket(Packet p, boolean encrypt) {
 | 
			
		||||
		byte[] result, header, data;
 | 
			
		||||
		int length;
 | 
			
		||||
		int packets;
 | 
			
		||||
		long crcValue;		
 | 
			
		||||
		
 | 
			
		||||
		//if data > MAX_PAYLAOD -> error
 | 
			
		||||
		
 | 
			
		||||
		data = p.getBytes();
 | 
			
		||||
		
 | 
			
		||||
		length = data.length + CRC_OFFSET; //include 4bytes for CRC32		
 | 
			
		||||
		packets = ((length - 1) >> 4) + 1; //how many 16 bytes data sub-packets are necessary		
 | 
			
		||||
 | 
			
		||||
		result = new byte[packets * PACKET_SIZE];
 | 
			
		||||
		System.arraycopy(data, 0, result, CRC_OFFSET, data.length);
 | 
			
		||||
				
 | 
			
		||||
		//add CRC32
 | 
			
		||||
		mCrc.reset();
 | 
			
		||||
		mCrc.update(result, CRC_OFFSET, result.length - CRC_OFFSET);		
 | 
			
		||||
		crcValue = mCrc.getValue();
 | 
			
		||||
		Util.log("CRC: "+crcValue);
 | 
			
		||||
		result[3] = (byte)crcValue;
 | 
			
		||||
	    crcValue >>= 8;
 | 
			
		||||
	    result[2] = (byte)crcValue;
 | 
			
		||||
		crcValue >>= 8;
 | 
			
		||||
		result[1] = (byte)crcValue;
 | 
			
		||||
		crcValue >>= 8;
 | 
			
		||||
		result[0] = (byte)crcValue;			
 | 
			
		||||
		
 | 
			
		||||
		//Util.printHex(result);
 | 
			
		||||
		
 | 
			
		||||
		if (encrypt) {
 | 
			
		||||
			result = mAes.encrypt(result);
 | 
			
		||||
			//Util.printHex(result);			
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		header = new byte[2];
 | 
			
		||||
		header[0] = Packet.START_TAG;
 | 
			
		||||
		header[1] = (byte)packets;
 | 
			
		||||
		if (encrypt) {
 | 
			
		||||
			header[1] |= Packet.FLAG_ENCRYPTED;
 | 
			
		||||
		}
 | 
			
		||||
		if (p.getRespond()) {
 | 
			
		||||
			header[1] |= Packet.FLAG_RESPOND;
 | 
			
		||||
		}
 | 
			
		||||
		mBTService.write(header);
 | 
			
		||||
		mBTService.write(result);	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								src/java/InputStickAPI/src/com/inputstick/api/Util.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,83 @@
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public abstract class Util {
 | 
			
		||||
	
 | 
			
		||||
	private static final boolean debug = false;
 | 
			
		||||
	
 | 
			
		||||
	public static void log(String msg) {
 | 
			
		||||
		if (debug) {
 | 
			
		||||
			System.out.println("LOG: " + msg);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void printHex(byte[] toPrint, String info) {
 | 
			
		||||
		if (debug) {
 | 
			
		||||
			System.out.println(info);
 | 
			
		||||
			printHex(toPrint);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public static void printHex(byte[] toPrint) {
 | 
			
		||||
		if (debug) {
 | 
			
		||||
			int cnt = 0;
 | 
			
		||||
			String s;
 | 
			
		||||
			byte b;
 | 
			
		||||
	        for (int i = 0; i < toPrint.length; i++) {
 | 
			
		||||
	        	b = toPrint[i];    	
 | 
			
		||||
	        	if ((b < 10) && (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();
 | 
			
		||||
	        	System.out.print("0x" + s + " ");
 | 
			
		||||
	        	cnt++;
 | 
			
		||||
	        	if (cnt == 8) {
 | 
			
		||||
	        		System.out.println("");
 | 
			
		||||
	        		cnt = 0;
 | 
			
		||||
	        	}
 | 
			
		||||
	        }
 | 
			
		||||
	        System.out.println("\n#####");	
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
    public static byte getLSB(int n) {
 | 
			
		||||
        return (byte)(n & 0x00FF);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static byte getMSB(int n) {
 | 
			
		||||
        return (byte)((n & 0xFF00) >> 8);
 | 
			
		||||
    }   
 | 
			
		||||
    
 | 
			
		||||
    public static int getInt(byte b) {
 | 
			
		||||
    	int bInt = b & 0xFF;
 | 
			
		||||
    	return bInt;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static int getInt(byte msb, byte lsb) {
 | 
			
		||||
    	int msbInt = msb & 0xFF;
 | 
			
		||||
    	int lsbInt = lsb & 0xFF;
 | 
			
		||||
    	return (msbInt << 8) + lsbInt;    	
 | 
			
		||||
    } 	
 | 
			
		||||
	
 | 
			
		||||
	public static long getLong(byte b0, byte b1, byte b2, byte b3) {
 | 
			
		||||
		long result;		
 | 
			
		||||
		result = (b0) & 0xFF;
 | 
			
		||||
		result <<= 8;
 | 
			
		||||
		result += (b1) & 0xFF;
 | 
			
		||||
		result <<= 8;
 | 
			
		||||
		result += (b2) & 0xFF;
 | 
			
		||||
		result <<= 8;
 | 
			
		||||
		result += (b3) & 0xFF;				
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,40 @@
 | 
			
		||||
package com.inputstick.api.basic;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.hid.ConsumerReport;
 | 
			
		||||
import com.inputstick.api.hid.HIDTransaction;
 | 
			
		||||
 | 
			
		||||
public class InputStickConsumer {
 | 
			
		||||
	
 | 
			
		||||
	//CONSUMER PAGE
 | 
			
		||||
	public static final int VOL_UP = 0x00E9;
 | 
			
		||||
	public static final int VOL_DOWN = 0x00EA;
 | 
			
		||||
	public static final int VOL_MUTE = 0x00E2;
 | 
			
		||||
	public static final int TRACK_NEXT = 0x00B5;
 | 
			
		||||
	public static final int TRACK_PREV = 0x00B6;
 | 
			
		||||
	public static final int STOP = 0x00B7;
 | 
			
		||||
	public static final int PLAY_PAUSE = 0x00CD;
 | 
			
		||||
	
 | 
			
		||||
	public static final int LAUNCH_BROWSER = 0x0196;
 | 
			
		||||
	public static final int LAUNCH_EMAIL = 0x018A;
 | 
			
		||||
	public static final int LAUNCH_CALC = 0x0192;
 | 
			
		||||
	
 | 
			
		||||
	//SYSTEM CONTROL
 | 
			
		||||
	public static final int POWER_DOWN = 0x81;
 | 
			
		||||
	public static final int SLEEP = 0x82;
 | 
			
		||||
	public static final int WAKEUP = 0x83;		
 | 
			
		||||
	
 | 
			
		||||
	private InputStickConsumer() {
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/*public static void systemAction(int action) {
 | 
			
		||||
	}*/	
 | 
			
		||||
	
 | 
			
		||||
	public static void consumerAction(int action) {
 | 
			
		||||
		HIDTransaction t = new HIDTransaction();
 | 
			
		||||
		t.addReport(new ConsumerReport(action));
 | 
			
		||||
		t.addReport(new ConsumerReport());
 | 
			
		||||
		InputStickHID.addConsumerTransaction(t);		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,152 @@
 | 
			
		||||
package com.inputstick.api.basic;
 | 
			
		||||
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
import android.app.Application;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.BTConnectionManager;
 | 
			
		||||
import com.inputstick.api.ConnectionManager;
 | 
			
		||||
import com.inputstick.api.HIDInfo;
 | 
			
		||||
import com.inputstick.api.IPCConnectionManager;
 | 
			
		||||
import com.inputstick.api.InputStickDataListener;
 | 
			
		||||
import com.inputstick.api.InputStickStateListener;
 | 
			
		||||
import com.inputstick.api.Packet;
 | 
			
		||||
import com.inputstick.api.hid.HIDTransaction;
 | 
			
		||||
import com.inputstick.api.hid.HIDTransactionQueue;
 | 
			
		||||
import com.inputstick.init.InitManager;
 | 
			
		||||
 | 
			
		||||
public class InputStickHID implements InputStickStateListener, InputStickDataListener  {
 | 
			
		||||
	
 | 
			
		||||
	//private static final String mTag = "InputStickBasic";		
 | 
			
		||||
	
 | 
			
		||||
	private static ConnectionManager mConnectionManager;
 | 
			
		||||
	
 | 
			
		||||
	private static Vector<InputStickStateListener> mStateListeners = new Vector<InputStickStateListener>();
 | 
			
		||||
	
 | 
			
		||||
	private static InputStickHID instance = new InputStickHID();
 | 
			
		||||
	private static HIDInfo mHIDInfo = new HIDInfo();
 | 
			
		||||
	
 | 
			
		||||
	private static HIDTransactionQueue keyboardQueue;
 | 
			
		||||
	private static HIDTransactionQueue mouseQueue;
 | 
			
		||||
	private static HIDTransactionQueue consumerQueue;
 | 
			
		||||
	
 | 
			
		||||
	private InputStickHID() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static InputStickHID getInstance() {
 | 
			
		||||
		return instance;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static void init() {
 | 
			
		||||
		keyboardQueue = new HIDTransactionQueue(HIDTransactionQueue.KEYBOARD, mConnectionManager);
 | 
			
		||||
		mouseQueue = new HIDTransactionQueue(HIDTransactionQueue.MOUSE, mConnectionManager);
 | 
			
		||||
		consumerQueue = new HIDTransactionQueue(HIDTransactionQueue.CONSUMER, mConnectionManager);		
 | 
			
		||||
		
 | 
			
		||||
		mConnectionManager.addStateListener(instance);
 | 
			
		||||
		mConnectionManager.addDataListener(instance);
 | 
			
		||||
		mConnectionManager.connect();		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	//direct Bluetooth connection, custom InitManager
 | 
			
		||||
	public static void connect(Application app, String mac, byte[] key, InitManager initManager) {
 | 
			
		||||
		mConnectionManager = new BTConnectionManager(initManager, app, mac, key);		
 | 
			
		||||
		init();
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	//direct Bluetooth connection
 | 
			
		||||
	public static void connect(Application app, String mac, byte[] key) {
 | 
			
		||||
		//mConnectionManager = new BTConnectionManager(new BasicInitManager(key), app, mac, reflections, key);
 | 
			
		||||
		//mConnectionManager = new BTConnectionManager(new BasicInitManager(key), app, mac, key);
 | 
			
		||||
		mConnectionManager = new BTConnectionManager(new InitManager(key), app, mac, key);
 | 
			
		||||
		init();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	//use background service & DeviceManager
 | 
			
		||||
	public static void connect(Application app) {
 | 
			
		||||
		mConnectionManager = new IPCConnectionManager(app);
 | 
			
		||||
		init();
 | 
			
		||||
	}			
 | 
			
		||||
	
 | 
			
		||||
	public static void disconnect() { 
 | 
			
		||||
		//TODO check state?
 | 
			
		||||
		mConnectionManager.disconnect();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static int getState() {
 | 
			
		||||
		if (mConnectionManager != null) {
 | 
			
		||||
			return mConnectionManager.getState();
 | 
			
		||||
		} else {
 | 
			
		||||
			return ConnectionManager.STATE_DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static boolean isReady() {
 | 
			
		||||
		if (getState() == ConnectionManager.STATE_READY) {
 | 
			
		||||
			return true;
 | 
			
		||||
		} else {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void addStateListener(InputStickStateListener listener) {
 | 
			
		||||
		if (listener != null) {
 | 
			
		||||
			mStateListeners.add(listener);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void removeStateListener(InputStickStateListener listener) {
 | 
			
		||||
		if (listener != null) {
 | 
			
		||||
			mStateListeners.remove(listener);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static void addKeyboardTransaction(HIDTransaction transaction) {
 | 
			
		||||
		keyboardQueue.addTransaction(transaction);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void addMouseTransaction(HIDTransaction transaction) {
 | 
			
		||||
		mouseQueue.addTransaction(transaction);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void addConsumerTransaction(HIDTransaction transaction) {
 | 
			
		||||
		consumerQueue.addTransaction(transaction);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static boolean sendPacket(Packet p) {
 | 
			
		||||
		if (mConnectionManager != null) {
 | 
			
		||||
			mConnectionManager.sendPacket(p);
 | 
			
		||||
			return true;
 | 
			
		||||
		} else {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}				
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onStateChanged(int state) {
 | 
			
		||||
		for (InputStickStateListener listener : mStateListeners) {
 | 
			
		||||
			listener.onStateChanged(state);
 | 
			
		||||
		}		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onInputStickData(byte[] data) {
 | 
			
		||||
		if (data[0] == Packet.CMD_HID_STATUS) {
 | 
			
		||||
			mHIDInfo.update(data);
 | 
			
		||||
 | 
			
		||||
			if (mHIDInfo.isKeyboardReady()) {
 | 
			
		||||
				keyboardQueue.deviceReady();
 | 
			
		||||
			}
 | 
			
		||||
			if (mHIDInfo.isMouseReady()) {
 | 
			
		||||
				mouseQueue.deviceReady();
 | 
			
		||||
			}
 | 
			
		||||
			if (mHIDInfo.isConsumerReady()) {
 | 
			
		||||
				consumerQueue.deviceReady();
 | 
			
		||||
			}			
 | 
			
		||||
			
 | 
			
		||||
			InputStickKeyboard.setLEDs(mHIDInfo.getNumLock(), mHIDInfo.getCapsLock(), mHIDInfo.getScrollLock());			
 | 
			
		||||
		}
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,118 @@
 | 
			
		||||
package com.inputstick.api.basic;
 | 
			
		||||
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.InputStickKeyboardListener;
 | 
			
		||||
import com.inputstick.api.hid.HIDKeycodes;
 | 
			
		||||
import com.inputstick.api.hid.HIDTransaction;
 | 
			
		||||
import com.inputstick.api.hid.KeyboardReport;
 | 
			
		||||
 | 
			
		||||
public class InputStickKeyboard {
 | 
			
		||||
	
 | 
			
		||||
	//private static final String mTag = "InputStickKeyboard";
 | 
			
		||||
	
 | 
			
		||||
	private static final byte NONE = (byte)0;
 | 
			
		||||
	
 | 
			
		||||
	private static boolean mReportProtocol;		
 | 
			
		||||
	private static boolean mNumLock;
 | 
			
		||||
	private static boolean mCapsLock;
 | 
			
		||||
	private static boolean mScrollLock;
 | 
			
		||||
	
 | 
			
		||||
	private static Vector<InputStickKeyboardListener> mKeyboardListeners = new Vector<InputStickKeyboardListener>();
 | 
			
		||||
	
 | 
			
		||||
	private InputStickKeyboard() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void addKeyboardListener(InputStickKeyboardListener listener) {
 | 
			
		||||
		if (listener != null) {
 | 
			
		||||
			mKeyboardListeners.add(listener);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void removeKeyboardListener(InputStickKeyboardListener listener) {
 | 
			
		||||
		if (listener != null) {
 | 
			
		||||
			mKeyboardListeners.remove(listener);
 | 
			
		||||
		}
 | 
			
		||||
	}		
 | 
			
		||||
	
 | 
			
		||||
	protected void setReportProtocol(boolean reportProtocol) {
 | 
			
		||||
		mReportProtocol = reportProtocol;				
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isReportProtocol() {
 | 
			
		||||
		return mReportProtocol;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected static void setLEDs(boolean numLock, boolean capsLock, boolean scrollLock) {
 | 
			
		||||
		mNumLock = numLock;
 | 
			
		||||
		mCapsLock = capsLock;
 | 
			
		||||
		mScrollLock = scrollLock;
 | 
			
		||||
		
 | 
			
		||||
		for (InputStickKeyboardListener listener : mKeyboardListeners) {
 | 
			
		||||
			listener.onLEDsChanged(mNumLock, mCapsLock, mScrollLock);
 | 
			
		||||
		}			
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static boolean isNumLock() {
 | 
			
		||||
		return mNumLock;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static boolean isCapsLock() {
 | 
			
		||||
		return mCapsLock;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static boolean isScrollLock() {
 | 
			
		||||
		return mScrollLock;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void toggleNumLock() {
 | 
			
		||||
		pressAndRelease(NONE, HIDKeycodes.KEY_NUM_LOCK);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void toggleCapsLock() {
 | 
			
		||||
		pressAndRelease(NONE, HIDKeycodes.KEY_CAPS_LOCK);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void toggleScrollLock() {
 | 
			
		||||
		pressAndRelease(NONE, HIDKeycodes.KEY_SCROLL_LOCK);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void pressAndRelease(byte modifier, byte key) {
 | 
			
		||||
		HIDTransaction t = new HIDTransaction();
 | 
			
		||||
		t.addReport(new KeyboardReport(modifier, NONE));
 | 
			
		||||
		t.addReport(new KeyboardReport(modifier, key));
 | 
			
		||||
		t.addReport(new KeyboardReport(NONE, NONE));
 | 
			
		||||
		InputStickHID.addKeyboardTransaction(t);
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	public static void typeASCII(String toType) {
 | 
			
		||||
		int keyCode;
 | 
			
		||||
		int index;
 | 
			
		||||
		for (int i = 0; i < toType.length(); i++) {
 | 
			
		||||
			index = toType.charAt(i);
 | 
			
		||||
			if (index > 127) {
 | 
			
		||||
				index = 127;
 | 
			
		||||
			}
 | 
			
		||||
			keyCode = HIDKeycodes.getKeyCode(index);
 | 
			
		||||
			if (keyCode > 128) {
 | 
			
		||||
				keyCode -= 128;
 | 
			
		||||
				pressAndRelease(HIDKeycodes.SHIFT_LEFT, (byte)keyCode);
 | 
			
		||||
			} else {
 | 
			
		||||
				pressAndRelease(NONE, (byte)keyCode);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}		
 | 
			
		||||
	
 | 
			
		||||
	public static void customReport(byte modifier, byte key0, byte key1, byte key2, byte key3, byte key4, byte key5) {
 | 
			
		||||
		HIDTransaction t = new HIDTransaction();
 | 
			
		||||
		t.addReport(new KeyboardReport(modifier, key0, key1, key2, key3, key4, key5));
 | 
			
		||||
		InputStickHID.addKeyboardTransaction(t);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/*public static void customReport(byte[] report) {
 | 
			
		||||
		HIDTransaction t = new HIDTransaction();
 | 
			
		||||
		t.addReport(report);
 | 
			
		||||
		InputStickHID.addKeyboardTransaction(t);	
 | 
			
		||||
	}*/
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,57 @@
 | 
			
		||||
package com.inputstick.api.basic;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.hid.HIDTransaction;
 | 
			
		||||
import com.inputstick.api.hid.MouseReport;
 | 
			
		||||
 | 
			
		||||
public class InputStickMouse {
 | 
			
		||||
	
 | 
			
		||||
	private static final byte NONE = 0x00;
 | 
			
		||||
 | 
			
		||||
	public static final byte BUTTON_NONE = 0x00;
 | 
			
		||||
	public static final byte BUTTON_LEFT = 0x01;
 | 
			
		||||
	public static final byte BUTTON_RIGHT = 0x02;
 | 
			
		||||
	public static final byte BUTTON_MIDDLE = 0x04;
 | 
			
		||||
	
 | 
			
		||||
	private static boolean mReportProtocol;
 | 
			
		||||
	
 | 
			
		||||
	private InputStickMouse() {
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected void setReportProtocol(boolean reportProtocol) {
 | 
			
		||||
		mReportProtocol = reportProtocol;				
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isReportProtocol() {
 | 
			
		||||
		return mReportProtocol;
 | 
			
		||||
	}		
 | 
			
		||||
	
 | 
			
		||||
	public static void click(byte button, int n) {
 | 
			
		||||
		HIDTransaction t = new HIDTransaction();
 | 
			
		||||
		t.addReport(new MouseReport()); //release
 | 
			
		||||
		for (int i = 0; i < n; i++) {								
 | 
			
		||||
			t.addReport(new MouseReport(button, NONE, NONE, NONE)); //press
 | 
			
		||||
			t.addReport(new MouseReport()); //release			
 | 
			
		||||
		}
 | 
			
		||||
		InputStickHID.addMouseTransaction(t);	
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void move(byte x, byte y) {
 | 
			
		||||
		HIDTransaction t = new HIDTransaction();
 | 
			
		||||
		t.addReport(new MouseReport(NONE, x, y, NONE));
 | 
			
		||||
		InputStickHID.addMouseTransaction(t);	
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void scroll(byte wheel) {
 | 
			
		||||
		HIDTransaction t = new HIDTransaction();
 | 
			
		||||
		t.addReport(new MouseReport(NONE, NONE, NONE, wheel));
 | 
			
		||||
		InputStickHID.addMouseTransaction(t);		
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	public static void customReport(byte buttons, byte x, byte y, byte wheel) {
 | 
			
		||||
		HIDTransaction t = new HIDTransaction();
 | 
			
		||||
		t.addReport(new MouseReport(buttons, x, y, wheel));
 | 
			
		||||
		InputStickHID.addMouseTransaction(t);		
 | 
			
		||||
	}		
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,404 @@
 | 
			
		||||
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 android.content.BroadcastReceiver;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.content.IntentFilter;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.os.Message;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.Packet;
 | 
			
		||||
import com.inputstick.api.Util;
 | 
			
		||||
 | 
			
		||||
public class BTService {
 | 
			
		||||
	
 | 
			
		||||
	public static final int DEFAULT_CONNECT_TIMEOUT = 30000;
 | 
			
		||||
	
 | 
			
		||||
	public static final int EVENT_NONE = 0;
 | 
			
		||||
	public static final int EVENT_DATA = 1;
 | 
			
		||||
	public static final int EVENT_CONNECTED = 2;
 | 
			
		||||
	public static final int EVENT_CANCELLED = 3;
 | 
			
		||||
	public static final int EVENT_CONNECTION_FAILED = 4;
 | 
			
		||||
	public static final int EVENT_CONNECTION_LOST = 5;
 | 
			
		||||
	public static final int EVENT_NO_BT_HW = 6;
 | 
			
		||||
	public static final int EVENT_INVALID_MAC = 7;
 | 
			
		||||
	//TODO:
 | 
			
		||||
	public static final int EVENT_CMD_TIMEOUT = 8;
 | 
			
		||||
	public static final int EVENT_INTERVAL_TIMEOUT = 9;
 | 
			
		||||
	public static final int EVENT_TURN_ON_TIMEOUT = 10;
 | 
			
		||||
	public static final int EVENT_OTHER_ERROR = 11;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
       
 | 
			
		||||
    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 ConnectThread mConnectThread;
 | 
			
		||||
    private ConnectedThread mConnectedThread;
 | 
			
		||||
    private int mLastEvent;
 | 
			
		||||
    
 | 
			
		||||
    private String mMac;
 | 
			
		||||
    private boolean mReflection;
 | 
			
		||||
    private final Application mApp;
 | 
			
		||||
    private final Context mCtx;    
 | 
			
		||||
    
 | 
			
		||||
    private boolean mUseReflection;
 | 
			
		||||
    private int mConnectTimeout;    
 | 
			
		||||
    
 | 
			
		||||
    private boolean turnBluetoothOn;
 | 
			
		||||
    private boolean receiverRegistered;
 | 
			
		||||
    private long timeout;
 | 
			
		||||
    private int retryCnt;    
 | 
			
		||||
    
 | 
			
		||||
    private boolean disconnecting;
 | 
			
		||||
    private boolean connected;
 | 
			
		||||
  
 | 
			
		||||
    
 | 
			
		||||
	private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
 | 
			
		||||
		@Override
 | 
			
		||||
		public void onReceive(Context context, Intent intent) {
 | 
			
		||||
			final String action = intent.getAction();
 | 
			
		||||
			System.out.println("ACTION: "+action);
 | 
			
		||||
			if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
 | 
			
		||||
				final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
 | 
			
		||||
				if ((state == BluetoothAdapter.STATE_ON)  && (turnBluetoothOn)) {					
 | 
			
		||||
					turnBluetoothOn = false;					
 | 
			
		||||
					doConnect(false);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	};    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    public BTService(Application app, Handler handler) {
 | 
			
		||||
        mAdapter = BluetoothAdapter.getDefaultAdapter();
 | 
			
		||||
        mLastEvent = EVENT_NONE;
 | 
			
		||||
        mHandler = handler;
 | 
			
		||||
        mApp = app;
 | 
			
		||||
        mCtx = app.getApplicationContext();
 | 
			
		||||
        mConnectTimeout = DEFAULT_CONNECT_TIMEOUT; //30s - default value
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    public void setConnectTimeout(int timeout) {
 | 
			
		||||
    	mConnectTimeout = timeout;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public void enableReflection(boolean enabled) {
 | 
			
		||||
    	mUseReflection = enabled;
 | 
			
		||||
    }
 | 
			
		||||
	
 | 
			
		||||
    private synchronized void event(int event) {
 | 
			
		||||
    	Util.log("event() " + mLastEvent + " -> " + event);
 | 
			
		||||
        mLastEvent = event;
 | 
			
		||||
        
 | 
			
		||||
        Message msg = Message.obtain(null, mLastEvent, 0, 0);
 | 
			
		||||
        mHandler.sendMessage(msg);        
 | 
			
		||||
    }        
 | 
			
		||||
    
 | 
			
		||||
    public synchronized int getLastEvent() {
 | 
			
		||||
        return mLastEvent;
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    private void enableBluetooth() {
 | 
			
		||||
    	if (mApp != null) {
 | 
			
		||||
	    	turnBluetoothOn = true;
 | 
			
		||||
	    	if ( !receiverRegistered) {
 | 
			
		||||
	    		IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
 | 
			
		||||
	    		mCtx.registerReceiver(mReceiver, filter);
 | 
			
		||||
	    		receiverRegistered = true;
 | 
			
		||||
	    	}
 | 
			
		||||
	        
 | 
			
		||||
	    	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) {
 | 
			
		||||
    		retryCnt++;
 | 
			
		||||
    	} else {	
 | 
			
		||||
    		retryCnt = 0;
 | 
			
		||||
			timeout = System.currentTimeMillis() + mConnectTimeout;
 | 
			
		||||
    	}
 | 
			
		||||
        
 | 
			
		||||
        if (mConnectThread != null) {
 | 
			
		||||
        	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) {
 | 
			
		||||
    	Util.log("connect to: " + mac + " REFLECTION: " + mUseReflection);
 | 
			
		||||
		disconnecting = false;
 | 
			
		||||
		connected = false;
 | 
			
		||||
		mMac = mac;
 | 
			
		||||
		
 | 
			
		||||
		if (BluetoothAdapter.checkBluetoothAddress(mac)) {
 | 
			
		||||
			BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 | 
			
		||||
			if (mBluetoothAdapter == null) {
 | 
			
		||||
				event(EVENT_NO_BT_HW);
 | 
			
		||||
			} else {
 | 
			
		||||
				if (mBluetoothAdapter.isEnabled()) {					
 | 
			
		||||
					doConnect(false);
 | 
			
		||||
				} else {					
 | 
			
		||||
					enableBluetooth();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			event(EVENT_INVALID_MAC);
 | 
			
		||||
		}
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    public synchronized void disconnect() {
 | 
			
		||||
    	Util.log("disconnect");
 | 
			
		||||
        disconnecting = true;
 | 
			
		||||
        cancelThreads();            
 | 
			
		||||
        event(EVENT_CANCELLED);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    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) {
 | 
			
		||||
        	r.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) {
 | 
			
		||||
        timeout = 0;
 | 
			
		||||
        cancelThreads();        
 | 
			
		||||
        if (receiverRegistered) {
 | 
			
		||||
        	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);
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    private void connectionFailed() {    	
 | 
			
		||||
    	connected = false;
 | 
			
		||||
    	if (disconnecting) {
 | 
			
		||||
    		disconnecting = false;
 | 
			
		||||
    	} else {	
 | 
			
		||||
	    	if ((timeout > 0) && (System.currentTimeMillis() < timeout)) {
 | 
			
		||||
	    		Util.log("RETRY: "+retryCnt + " time left: " + (timeout - System.currentTimeMillis()));    		
 | 
			
		||||
	    		doConnect(true);
 | 
			
		||||
	    	} else {    	
 | 
			
		||||
	    		event(EVENT_CONNECTION_FAILED);
 | 
			
		||||
	    	}     
 | 
			
		||||
    	}
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    private void connectionLost() { 
 | 
			
		||||
    	connected = false;
 | 
			
		||||
    	if (disconnecting) {
 | 
			
		||||
    		disconnecting = false;
 | 
			
		||||
    	} else {
 | 
			
		||||
    		event(EVENT_CONNECTION_LOST);
 | 
			
		||||
    	}
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void run() {
 | 
			
		||||
        	Util.log("BEGIN mConnectedThread");           
 | 
			
		||||
            byte[] buffer = null;    
 | 
			
		||||
            int rxTmp;
 | 
			
		||||
            int lengthByte;
 | 
			
		||||
            int length;            
 | 
			
		||||
            while (true) {
 | 
			
		||||
                try {
 | 
			
		||||
                	rxTmp = mmInStream.read();
 | 
			
		||||
                	if (rxTmp == Packet.START_TAG) {
 | 
			
		||||
	                	lengthByte = mmInStream.read();
 | 
			
		||||
	                	length = lengthByte;
 | 
			
		||||
						length &= 0x3F;
 | 
			
		||||
						length *= 16;					
 | 
			
		||||
						buffer = new byte[length + 2];
 | 
			
		||||
						buffer[0] = Packet.START_TAG;
 | 
			
		||||
						buffer[1] = (byte)lengthByte;
 | 
			
		||||
						for (int i = 2; i < length + 2; i++) {
 | 
			
		||||
							buffer[i] = (byte)mmInStream.read();
 | 
			
		||||
						}				
 | 
			
		||||
						mHandler.obtainMessage(EVENT_DATA, 0, 0, buffer).sendToTarget();             
 | 
			
		||||
                	} else {
 | 
			
		||||
                		System.out.println("RX: " + rxTmp);
 | 
			
		||||
                		//possible WDG reset															     
 | 
			
		||||
                	}
 | 
			
		||||
                } catch (IOException e) {
 | 
			
		||||
                    connectionLost();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void write(byte[] buffer) {      	
 | 
			
		||||
            try {
 | 
			
		||||
                mmOutStream.write(buffer);
 | 
			
		||||
                mmOutStream.flush();
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
            	Util.log("Exception during write");
 | 
			
		||||
            }
 | 
			
		||||
        }          
 | 
			
		||||
 | 
			
		||||
        public void cancel() {
 | 
			
		||||
            try {
 | 
			
		||||
                mmSocket.close();
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
            	Util.log("close() of connect socket failed");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }            
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
package com.inputstick.api.hid;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.Util;
 | 
			
		||||
 | 
			
		||||
public class ConsumerReport extends HIDReport {
 | 
			
		||||
	
 | 
			
		||||
	public static final int SIZE = 3;
 | 
			
		||||
	
 | 
			
		||||
	private byte[] data;
 | 
			
		||||
	
 | 
			
		||||
	public ConsumerReport(int usage) {
 | 
			
		||||
		data = new byte[SIZE];
 | 
			
		||||
		data[0] = 1;
 | 
			
		||||
		data[1] = Util.getLSB(usage);
 | 
			
		||||
		data[2] = Util.getMSB(usage);		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public ConsumerReport() {
 | 
			
		||||
		this(0);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public byte[] getBytes() {
 | 
			
		||||
		return data;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int getBytesCount() {
 | 
			
		||||
		return SIZE;
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,272 @@
 | 
			
		||||
package com.inputstick.api.hid;
 | 
			
		||||
 | 
			
		||||
public class HIDKeycodes {
 | 
			
		||||
	
 | 
			
		||||
	public static final byte NONE = 0x00;
 | 
			
		||||
	
 | 
			
		||||
	public static final byte CTRL_LEFT = 0x01;
 | 
			
		||||
	public static final byte SHIFT_LEFT = 0x02;
 | 
			
		||||
	public static final byte ALT_LEFT = 0x04;
 | 
			
		||||
	public static final byte GUI_LEFT = 0x08;
 | 
			
		||||
	public static final byte CTRL_RIGHT = 0x10;
 | 
			
		||||
	public static final byte SHIFT_RIGHT = 0x20;
 | 
			
		||||
	public static final byte ALT_RIGHT = 0x40;
 | 
			
		||||
	public static final byte GUI_RIGHT = (byte)0x80;	
 | 
			
		||||
	
 | 
			
		||||
	public static final byte KEY_ENTER = 0x28;
 | 
			
		||||
	public static final byte KEY_ESCAPE = 0x29;
 | 
			
		||||
	public static final byte KEY_BACKSPACE = 0x2A;
 | 
			
		||||
	public static final byte KEY_TAB = 0x2B;
 | 
			
		||||
	public static final byte KEY_SPACEBAR = 0x2C;
 | 
			
		||||
		
 | 
			
		||||
	public static final byte KEY_CAPS_LOCK = 0x39;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public static final byte KEY_1 = 0x1E;
 | 
			
		||||
	public static final byte KEY_2 = 0x1F;
 | 
			
		||||
	public static final byte KEY_3 = 0x20;
 | 
			
		||||
	public static final byte KEY_4 = 0x21;
 | 
			
		||||
	public static final byte KEY_5 = 0x22;
 | 
			
		||||
	public static final byte KEY_6 = 0x23;
 | 
			
		||||
	public static final byte KEY_7 = 0x24;
 | 
			
		||||
	public static final byte KEY_8 = 0x25;
 | 
			
		||||
	public static final byte KEY_9 = 0x26;
 | 
			
		||||
	public static final byte KEY_0 = 0x27;
 | 
			
		||||
	
 | 
			
		||||
	public static final byte KEY_F1 = 0x3A;
 | 
			
		||||
	public static final byte KEY_F2 = 0x3B;
 | 
			
		||||
	public static final byte KEY_F3 = 0x3C;
 | 
			
		||||
	public static final byte KEY_F4 = 0x3D;
 | 
			
		||||
	public static final byte KEY_F5 = 0x3E;
 | 
			
		||||
	public static final byte KEY_F6 = 0x3F;
 | 
			
		||||
	public static final byte KEY_F7 = 0x40;
 | 
			
		||||
	public static final byte KEY_F8 = 0x41;
 | 
			
		||||
	public static final byte KEY_F9 = 0x42;
 | 
			
		||||
	public static final byte KEY_F10 = 0x43;
 | 
			
		||||
	public static final byte KEY_F11 = 0x44;
 | 
			
		||||
	public static final byte KEY_F12 = 0x45;		
 | 
			
		||||
	
 | 
			
		||||
	public static final byte KEY_PRINT_SCREEN = 0x46;
 | 
			
		||||
	public static final byte KEY_SCROLL_LOCK = 0x47;
 | 
			
		||||
	public static final byte KEY_PASUE = 0x48;
 | 
			
		||||
	public static final byte KEY_INSERT = 0x49;
 | 
			
		||||
	public static final byte KEY_HOME = 0x4A;
 | 
			
		||||
	public static final byte KEY_PAGE_UP = 0x4B;
 | 
			
		||||
	public static final byte KEY_DELETE = 0x4C;
 | 
			
		||||
	public static final byte KEY_END = 0x4D;
 | 
			
		||||
	public static final byte KEY_PAGE_DOWN = 0x4E;
 | 
			
		||||
	
 | 
			
		||||
	public static final byte KEY_ARROW_RIGHT = 0x4F;
 | 
			
		||||
	public static final byte KEY_ARROW_LEFT = 0x50;
 | 
			
		||||
	public static final byte KEY_ARROW_DOWN = 0x51;
 | 
			
		||||
	public static final byte KEY_ARROW_UP = 0x52;		
 | 
			
		||||
	
 | 
			
		||||
	public static final byte KEY_NUM_LOCK = 0x53;	
 | 
			
		||||
	public static final byte KEY_NUM_BACKSLASH = 	0x54;
 | 
			
		||||
	public static final byte KEY_NUM_STAR = 		0x55;
 | 
			
		||||
	public static final byte KEY_NUM_MINUS = 		0x56;
 | 
			
		||||
	public static final byte KEY_NUM_PLUS = 		0x57;	
 | 
			
		||||
	public static final byte KEY_NUM_ENTER = 		0x58;	
 | 
			
		||||
	public static final byte KEY_NUM_1 = 			0x59;
 | 
			
		||||
	public static final byte KEY_NUM_2 = 			0x5A;
 | 
			
		||||
	public static final byte KEY_NUM_3 = 			0x5B;
 | 
			
		||||
	public static final byte KEY_NUM_4 = 			0x5C;
 | 
			
		||||
	public static final byte KEY_NUM_5 = 			0x5D;
 | 
			
		||||
	public static final byte KEY_NUM_6 = 			0x5E;
 | 
			
		||||
	public static final byte KEY_NUM_7 = 			0x5F;
 | 
			
		||||
	public static final byte KEY_NUM_8 = 			0x60;
 | 
			
		||||
	public static final byte KEY_NUM_9 = 			0x61;
 | 
			
		||||
	public static final byte KEY_NUM_0 = 			0x62;		
 | 
			
		||||
	public static final byte KEY_NUM_DOT = 			0x63;
 | 
			
		||||
	
 | 
			
		||||
	public static final byte KEY_A = 				0x04;
 | 
			
		||||
	public static final byte KEY_B = 				0x05;
 | 
			
		||||
	public static final byte KEY_C = 				0x06;
 | 
			
		||||
	public static final byte KEY_D = 				0x07;
 | 
			
		||||
	public static final byte KEY_E = 				0x08;
 | 
			
		||||
	public static final byte KEY_F = 				0x09;
 | 
			
		||||
	public static final byte KEY_G = 				0x0A;
 | 
			
		||||
	public static final byte KEY_H = 				0x0B;
 | 
			
		||||
	public static final byte KEY_I = 				0x0C;
 | 
			
		||||
	public static final byte KEY_J = 				0x0D;
 | 
			
		||||
	public static final byte KEY_K = 				0x0E;
 | 
			
		||||
	public static final byte KEY_L = 				0x0F;
 | 
			
		||||
	public static final byte KEY_M = 				0x10;
 | 
			
		||||
	public static final byte KEY_N = 				0x11;
 | 
			
		||||
	public static final byte KEY_O = 				0x12;
 | 
			
		||||
	public static final byte KEY_P = 				0x13;
 | 
			
		||||
	public static final byte KEY_Q = 				0x14;
 | 
			
		||||
	public static final byte KEY_R = 				0x15;
 | 
			
		||||
	public static final byte KEY_S = 				0x16;
 | 
			
		||||
	public static final byte KEY_T = 				0x17;
 | 
			
		||||
	public static final byte KEY_U = 				0x18;	
 | 
			
		||||
	public static final byte KEY_V = 				0x19;
 | 
			
		||||
	public static final byte KEY_W = 				0x1A;
 | 
			
		||||
	public static final byte KEY_X = 				0x1B;
 | 
			
		||||
	public static final byte KEY_Y = 				0x1C;
 | 
			
		||||
	public static final byte KEY_Z = 				0x1D;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	public static final byte KEY_MINUS = 			0x2D;
 | 
			
		||||
	public static final byte KEY_EQUALS = 			0x2E;	
 | 
			
		||||
	public static final byte KEY_LEFT_BRACKET = 	0x2F;
 | 
			
		||||
	public static final byte KEY_RIGHT_BRACKET = 	0x30;
 | 
			
		||||
	public static final byte KEY_BACKSLASH =		0x31;
 | 
			
		||||
	//public static final byte KEY_GRAVE = 			0x32;
 | 
			
		||||
	public static final byte KEY_SEMICOLON = 		0x33;
 | 
			
		||||
	public static final byte KEY_APOSTROPHE = 		0x34;
 | 
			
		||||
	public static final byte KEY_GRAVE = 			0x35;
 | 
			
		||||
	public static final byte KEY_COMA = 			0x36;
 | 
			
		||||
	public static final byte KEY_DOT = 				0x37;	
 | 
			
		||||
	public static final byte KEY_SLASH = 			0x38;
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	public static final byte KEY_APPLICATION = 		0x65;	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
    public static final int[] ASCIItoHID = {
 | 
			
		||||
        0, //000
 | 
			
		||||
        0, //001
 | 
			
		||||
        0, //002
 | 
			
		||||
        0, //003
 | 
			
		||||
        0, //004
 | 
			
		||||
        0, //005
 | 
			
		||||
        0, //006
 | 
			
		||||
        0, //007
 | 
			
		||||
        0, //008
 | 
			
		||||
        0, //009
 | 
			
		||||
        0, //010
 | 
			
		||||
        0, //011
 | 
			
		||||
        0, //012
 | 
			
		||||
        0, //013
 | 
			
		||||
        0, //014
 | 
			
		||||
        0, //015
 | 
			
		||||
        0, //016
 | 
			
		||||
        0, //017
 | 
			
		||||
        0, //018
 | 
			
		||||
        0, //019
 | 
			
		||||
        0, //020
 | 
			
		||||
        0, //021
 | 
			
		||||
        0, //022
 | 
			
		||||
        0, //023
 | 
			
		||||
        0, //024
 | 
			
		||||
        0, //025
 | 
			
		||||
        0, //026
 | 
			
		||||
        0, //027
 | 
			
		||||
        0, //028
 | 
			
		||||
        0, //029
 | 
			
		||||
        0, //030
 | 
			
		||||
        0, //031
 | 
			
		||||
        44, //032 space
 | 
			
		||||
        128 + 30, //033 ! [SHIFT]
 | 
			
		||||
        128 + 52, //034 " [SHIFT]
 | 
			
		||||
        128 + 32, //035 # [SHIFT]
 | 
			
		||||
        128 + 33, //036 $ [SHIFT]
 | 
			
		||||
        128 + 34, //037 % [SHIFT]
 | 
			
		||||
        128 + 36, //038 & [SHIFT]
 | 
			
		||||
        52, //039 '
 | 
			
		||||
        128 + 38, //040 ( [SHIFT]
 | 
			
		||||
        128 + 39, //041 ) [SHIFT]
 | 
			
		||||
        128 + 37, //042 * [SHIFT]
 | 
			
		||||
        128 + 46, //043 + [SHIFT]
 | 
			
		||||
        54, //044 ,
 | 
			
		||||
        45, //045 - (-)
 | 
			
		||||
        55, //046 . (.)
 | 
			
		||||
        56, //047 /
 | 
			
		||||
        39, //048 0
 | 
			
		||||
        30, //049 1
 | 
			
		||||
        31, //050 2
 | 
			
		||||
        32, //051 3
 | 
			
		||||
        33, //052 4
 | 
			
		||||
        34, //053 5
 | 
			
		||||
        35, //054 6
 | 
			
		||||
        36, //055 7
 | 
			
		||||
        37, //056 8
 | 
			
		||||
        38, //057 9
 | 
			
		||||
        128 + 51, //058 : [SHIFT]
 | 
			
		||||
        51, //059 ;
 | 
			
		||||
        128 + 54, //060 < [SHIFT]
 | 
			
		||||
        46, //061 =
 | 
			
		||||
        128 + 55, //062 > [SHIFT]
 | 
			
		||||
        128 + 56, //063 ? [SHIFT]
 | 
			
		||||
        128 + 31, //064 @ [SHIFT]
 | 
			
		||||
        128 + 4, //065 A [SHIFT]
 | 
			
		||||
        128 + 5, //066 B [SHIFT]
 | 
			
		||||
        128 + 6, //067 C [SHIFT]
 | 
			
		||||
        128 + 7, //068 D [SHIFT]
 | 
			
		||||
        128 + 8, //069 E [SHIFT]
 | 
			
		||||
        128 + 9, //070 F [SHIFT]
 | 
			
		||||
        128 + 10, //071 G [SHIFT]
 | 
			
		||||
        128 + 11, //072 H [SHIFT]
 | 
			
		||||
        128 + 12, //073 I [SHIFT]
 | 
			
		||||
        128 + 13, //074 J [SHIFT]
 | 
			
		||||
        128 + 14, //075 K [SHIFT]
 | 
			
		||||
        128 + 15, //076 L [SHIFT]
 | 
			
		||||
        128 + 16, //077 M [SHIFT]
 | 
			
		||||
        128 + 17, //078 N [SHIFT]
 | 
			
		||||
        128 + 18, //079 O [SHIFT]
 | 
			
		||||
        128 + 19, //080 P [SHIFT]
 | 
			
		||||
        128 + 20, //081 Q [SHIFT]
 | 
			
		||||
        128 + 21, //082 R [SHIFT]
 | 
			
		||||
        128 + 22, //083 S [SHIFT]
 | 
			
		||||
        128 + 23, //084 T [SHIFT]
 | 
			
		||||
        128 + 24, //085 U [SHIFT]
 | 
			
		||||
        128 + 25, //086 V [SHIFT]
 | 
			
		||||
        128 + 26, //087 W [SHIFT]
 | 
			
		||||
        128 + 27, //088 X [SHIFT]
 | 
			
		||||
        128 + 28, //089 Y [SHIFT]
 | 
			
		||||
        128 + 29, //090 Z [SHIFT]
 | 
			
		||||
        47, //091 [
 | 
			
		||||
        49, /*092 \   */
 | 
			
		||||
        48, //093 ]
 | 
			
		||||
        128 + 35, //094 ^ [SHIFT]
 | 
			
		||||
        128 + 45, //095 _ [SHIFT] (underscore)
 | 
			
		||||
        128 + 53, //096 ` [SHIFT] (grave accent)
 | 
			
		||||
        4, //097 a
 | 
			
		||||
        5, //098 b
 | 
			
		||||
        6, //099 c
 | 
			
		||||
        7, //100 d
 | 
			
		||||
        8, //101 e
 | 
			
		||||
        9, //102 f
 | 
			
		||||
        10, //103 g
 | 
			
		||||
        11, //104 h
 | 
			
		||||
        12, //105 i
 | 
			
		||||
        13, //106 j
 | 
			
		||||
        14, //107 k
 | 
			
		||||
        15, //108 l
 | 
			
		||||
        16, //109 m
 | 
			
		||||
        17, //110 n
 | 
			
		||||
        18, //111 o
 | 
			
		||||
        19, //112 p
 | 
			
		||||
        20, //113 q
 | 
			
		||||
        21, //114 r
 | 
			
		||||
        22, //115 s
 | 
			
		||||
        23, //116 t
 | 
			
		||||
        24, //117 u
 | 
			
		||||
        25, //118 v
 | 
			
		||||
        26, //119 w
 | 
			
		||||
        27, //120 x
 | 
			
		||||
        28, //121 y
 | 
			
		||||
        29, //122 z
 | 
			
		||||
        128 + 47, //123 { [SHIFT]
 | 
			
		||||
        128 + 49, //124 | [SHIFT]
 | 
			
		||||
        128 + 48, //125 } [SHIFT]
 | 
			
		||||
        128 + 53, //126 ~ [SHIFT]
 | 
			
		||||
        0       //127 just in case...
 | 
			
		||||
    };	
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
	public static byte getKeyCode(char c) {
 | 
			
		||||
		return (byte)ASCIItoHID[c]; //TODO range
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static int getKeyCode(int c) {
 | 
			
		||||
		return ASCIItoHID[c]; //TODO range
 | 
			
		||||
	}    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,8 @@
 | 
			
		||||
package com.inputstick.api.hid;
 | 
			
		||||
 | 
			
		||||
public abstract class HIDReport {
 | 
			
		||||
 | 
			
		||||
	public abstract byte[] getBytes();
 | 
			
		||||
	public abstract int getBytesCount();
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,56 @@
 | 
			
		||||
package com.inputstick.api.hid;
 | 
			
		||||
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
public class HIDTransaction {
 | 
			
		||||
 | 
			
		||||
	private int mID;
 | 
			
		||||
	private Vector<HIDReport> reports;
 | 
			
		||||
	
 | 
			
		||||
	public HIDTransaction() {
 | 
			
		||||
		reports = new Vector<HIDReport>();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addReport(HIDReport report) {
 | 
			
		||||
		reports.add(report);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int getReportsCount() {
 | 
			
		||||
		return reports.size();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void setID(int id) {
 | 
			
		||||
		mID = id;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int getID() {
 | 
			
		||||
		return mID;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean hasNext() {
 | 
			
		||||
		return !reports.isEmpty();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public byte[] getNextReport() {
 | 
			
		||||
		byte[] report;
 | 
			
		||||
		report = reports.elementAt(0).getBytes();
 | 
			
		||||
		reports.removeElementAt(0);
 | 
			
		||||
		return report;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public HIDTransaction split(int n) {
 | 
			
		||||
		HIDTransaction result = new HIDTransaction();
 | 
			
		||||
		HIDReport report;
 | 
			
		||||
		if (n <= reports.size()) {
 | 
			
		||||
			while(n > 0) {
 | 
			
		||||
				report = reports.firstElement();
 | 
			
		||||
				reports.remove(0);
 | 
			
		||||
				result.addReport(report);
 | 
			
		||||
				n--;
 | 
			
		||||
			}		
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,111 @@
 | 
			
		||||
package com.inputstick.api.hid;
 | 
			
		||||
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
import com.inputstick.api.ConnectionManager;
 | 
			
		||||
import com.inputstick.api.Packet;
 | 
			
		||||
 | 
			
		||||
public class HIDTransactionQueue {
 | 
			
		||||
	
 | 
			
		||||
	public static final int KEYBOARD = 1;
 | 
			
		||||
	public static final int MOUSE = 2;
 | 
			
		||||
	public static final int CONSUMER = 3;
 | 
			
		||||
	
 | 
			
		||||
	private static final int BUFFER_SIZE = 32;
 | 
			
		||||
 | 
			
		||||
	private final Vector<HIDTransaction> queue;
 | 
			
		||||
	private final ConnectionManager mConnectionManager;
 | 
			
		||||
	private final byte cmd;
 | 
			
		||||
	private boolean ready;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	private long lastTime;
 | 
			
		||||
	private int lastReports;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public HIDTransactionQueue(int type, ConnectionManager connectionManager) {
 | 
			
		||||
		queue = new Vector<HIDTransaction>();
 | 
			
		||||
		mConnectionManager = connectionManager;
 | 
			
		||||
		ready = false;
 | 
			
		||||
		switch (type) {
 | 
			
		||||
			case KEYBOARD:
 | 
			
		||||
				cmd = Packet.CMD_HID_DATA_KEYB;
 | 
			
		||||
				break;
 | 
			
		||||
			case MOUSE:
 | 
			
		||||
				cmd = Packet.CMD_HID_DATA_MOUSE;
 | 
			
		||||
				break;
 | 
			
		||||
			case CONSUMER:
 | 
			
		||||
				cmd = Packet.CMD_HID_DATA_CONSUMER;
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				cmd = Packet.CMD_DUMMY;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void sendNext() {
 | 
			
		||||
		HIDTransaction transaction;
 | 
			
		||||
		byte reports = 0;
 | 
			
		||||
		ready = false;
 | 
			
		||||
		Packet p = new Packet(false, cmd, reports);
 | 
			
		||||
		
 | 
			
		||||
		//assume there is at least 1 element in queue		
 | 
			
		||||
		transaction = queue.firstElement();
 | 
			
		||||
		if (transaction.getReportsCount() > BUFFER_SIZE) {
 | 
			
		||||
			//transaction too big! split
 | 
			
		||||
			transaction = transaction.split(BUFFER_SIZE);			
 | 
			
		||||
		} else {
 | 
			
		||||
			queue.removeElementAt(0);						
 | 
			
		||||
		}
 | 
			
		||||
				
 | 
			
		||||
		while (transaction.hasNext()) {
 | 
			
		||||
			p.addBytes(transaction.getNextReport());
 | 
			
		||||
			reports++;
 | 
			
		||||
		}		
 | 
			
		||||
		//TODO add next transactions if possible
 | 
			
		||||
		
 | 
			
		||||
		while(true) {
 | 
			
		||||
			if (queue.isEmpty()) {
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			transaction = queue.firstElement();			
 | 
			
		||||
			if (reports + transaction.getReportsCount() < BUFFER_SIZE) {
 | 
			
		||||
				queue.removeElementAt(0);	
 | 
			
		||||
				while (transaction.hasNext()) {
 | 
			
		||||
					p.addBytes(transaction.getNextReport());
 | 
			
		||||
					reports++;
 | 
			
		||||
				}				
 | 
			
		||||
			} else {
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		p.modifyByte(1, reports); //set reports count
 | 
			
		||||
		mConnectionManager.sendPacket(p);	
 | 
			
		||||
		
 | 
			
		||||
		lastReports = reports;
 | 
			
		||||
		lastTime = System.currentTimeMillis();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addTransaction(HIDTransaction transaction) {
 | 
			
		||||
		if (queue.isEmpty()) {
 | 
			
		||||
			if (System.currentTimeMillis() > lastTime + (lastReports * 8 * 2/*just to be safe*/)) {
 | 
			
		||||
				ready = true;
 | 
			
		||||
			}
 | 
			
		||||
		}		
 | 
			
		||||
		
 | 
			
		||||
		queue.add(transaction);						
 | 
			
		||||
		if (ready) {
 | 
			
		||||
			sendNext();
 | 
			
		||||
		} 		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void deviceReady() {
 | 
			
		||||
		if (!queue.isEmpty()) {
 | 
			
		||||
			sendNext();
 | 
			
		||||
		} else {
 | 
			
		||||
			ready = true;
 | 
			
		||||
		}
 | 
			
		||||
	}			
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
package com.inputstick.api.hid;
 | 
			
		||||
 | 
			
		||||
public class KeyboardReport extends HIDReport {
 | 
			
		||||
	
 | 
			
		||||
	public static final int SIZE = 8;
 | 
			
		||||
	
 | 
			
		||||
	private byte[] data;
 | 
			
		||||
 | 
			
		||||
	public KeyboardReport(byte modifier, byte key0, byte key1, byte key2, byte key3, byte key4, byte key5) {
 | 
			
		||||
		data = new byte[SIZE];
 | 
			
		||||
		data[0] = modifier;
 | 
			
		||||
		data[2] = key0;
 | 
			
		||||
		data[3] = key1;
 | 
			
		||||
		data[4] = key2;
 | 
			
		||||
		data[5] = key3;
 | 
			
		||||
		data[6] = key4;
 | 
			
		||||
		data[7] = key5;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public KeyboardReport() {
 | 
			
		||||
		this((byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public KeyboardReport(byte modifier, byte key) {
 | 
			
		||||
		this(modifier, key, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public byte[] getBytes() {
 | 
			
		||||
		return data;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int getBytesCount() {
 | 
			
		||||
		return SIZE;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,29 @@
 | 
			
		||||
package com.inputstick.api.hid;
 | 
			
		||||
 | 
			
		||||
public class MouseReport extends HIDReport {
 | 
			
		||||
	
 | 
			
		||||
	public static final int SIZE = 4;
 | 
			
		||||
	
 | 
			
		||||
	private byte[] data;
 | 
			
		||||
 | 
			
		||||
	public MouseReport(byte buttons, byte x, byte y, byte wheel) {
 | 
			
		||||
		data = new byte[SIZE];
 | 
			
		||||
		data[0] = buttons;
 | 
			
		||||
		data[1] = x;
 | 
			
		||||
		data[2] = y;
 | 
			
		||||
		data[3] = wheel;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public MouseReport() {
 | 
			
		||||
		this((byte)0, (byte)0, (byte)0, (byte)0);
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	public byte[] getBytes() {
 | 
			
		||||
		return data;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int getBytesCount() {
 | 
			
		||||
		return SIZE;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,142 @@
 | 
			
		||||
package com.inputstick.api.layout;
 | 
			
		||||
 | 
			
		||||
public class GermanLayout extends KeyboardLayout {
 | 
			
		||||
	
 | 
			
		||||
	public static final String LOCALE_NAME = "de-DE";
 | 
			
		||||
	
 | 
			
		||||
	public static final int LUT[][] = {
 | 
			
		||||
		/*	0	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	1	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	2	*/	{	0	,	(int)'1'	,	0x21	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	3	*/	{	0	,	(int)'2'	,	0x22	,	-1	,	0x00b2	,	0x00b2	}	,
 | 
			
		||||
		/*	4	*/	{	0	,	(int)'3'	,	0x00a7	,	-1	,	0x00b3	,	0x00b3	}	,
 | 
			
		||||
		/*	5	*/	{	0	,	(int)'4'	,	0x24	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	6	*/	{	0	,	(int)'5'	,	0x25	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	7	*/	{	0	,	(int)'6'	,	0x26	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	8	*/	{	0	,	(int)'7'	,	0x002f	,	-1	,	0x007b	,	0x007b	}	,
 | 
			
		||||
		/*	9	*/	{	0	,	(int)'8'	,	0x28	,	-1	,	0x005b	,	0x005b	}	,
 | 
			
		||||
		/*	0a	*/	{	0	,	(int)'9'	,	0x29	,	-1	,	0x005d	,	0x005d	}	,
 | 
			
		||||
		/*	0b	*/	{	0	,	(int)'0'	,	0x003d	,	-1	,	0x007d	,	0x007d	}	,
 | 
			
		||||
		/*	0c	*/	{	0	,	0x00df	,	0x003f	,	-1	,	0x005c	,	0x005c	}	,
 | 
			
		||||
		/*	0d	*/	{	0	,	0x00b4	,	0x0060	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	0e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	0f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		/*	10	*/	{	1	,	(int)'q'	,	(int)'Q'	,	-1	,	0x40	,	0x40	}	,
 | 
			
		||||
		/*	11	*/	{	1	,	(int)'w'	,	(int)'W'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	12	*/	{	1	,	(int)'e'	,	(int)'E'	,	-1	,	0x20ac	,	-1	}	,
 | 
			
		||||
		/*	13	*/	{	1	,	(int)'r'	,	(int)'R'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	14	*/	{	1	,	(int)'t'	,	(int)'T'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	15	*/	{	1	,	(int)'z'	,	(int)'Z'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	16	*/	{	1	,	(int)'u'	,	(int)'U'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	17	*/	{	1	,	(int)'i'	,	(int)'I'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	18	*/	{	1	,	(int)'o'	,	(int)'O'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	19	*/	{	1	,	(int)'p'	,	(int)'P'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	1a	*/	{	1	,	0x00fc	,	0x00dc	,	0x001b	,	-1	,	-1	}	,
 | 
			
		||||
		/*	1b	*/	{	0	,	0x002b	,	0x002a	,	0x001d	,	0x007e	,	0x007e	}	,
 | 
			
		||||
		/*	1c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	1d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	1e	*/	{	1	,	(int)'a'	,	(int)'A'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	1f	*/	{	1	,	(int)'s'	,	(int)'S'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		
 | 
			
		||||
		/*	20	*/	{	1	,	(int)'d'	,	(int)'D'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	21	*/	{	1	,	(int)'f'	,	(int)'F'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	22	*/	{	1	,	(int)'g'	,	(int)'G'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	23	*/	{	1	,	(int)'h'	,	(int)'H'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	24	*/	{	1	,	(int)'j'	,	(int)'J'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	25	*/	{	1	,	(int)'k'	,	(int)'K'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	26	*/	{	1	,	(int)'l'	,	(int)'L'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	27	*/	{	1	,	0x00f6	,	0x00d6	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	28	*/	{	1	,	0x00e4	,	0x00c4	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	29	*/	{	0	,	0x005e	,	0x00b0	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	2a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	2b	*/	{	0	,	0x23	,	0x27	,	0x001c	,	-1	,	-1	}	,
 | 
			
		||||
		/*	2c	*/	{	1	,	(int)'y'	,	(int)'Y'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	2d	*/	{	1	,	(int)'x'	,	(int)'X'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	2e	*/	{	1	,	(int)'c'	,	(int)'C'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	2f	*/	{	1	,	(int)'v'	,	(int)'V'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		
 | 
			
		||||
		/*	30	*/	{	1	,	(int)'b'	,	(int)'B'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	31	*/	{	1	,	(int)'n'	,	(int)'N'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	32	*/	{	1	,	(int)'m'	,	(int)'M'	,	-1	,	0x00b5	,	0x00b5	}	,
 | 
			
		||||
		/*	33	*/	{	0	,	0x002c	,	0x003b	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	34	*/	{	0	,	0x002e	,	0x003a	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	35	*/	{	0	,	0x002d	,	0x005f	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	36	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	37	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	38	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	39	*/	{	0	,	0x20	,	0x20	,	0x20	,	-1	,	-1	}	,
 | 
			
		||||
		/*	3a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	3b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	3c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	3d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	3e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	3f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		
 | 
			
		||||
		/*	40	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	41	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	42	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	43	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	44	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	45	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	46	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	47	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
		/*	48	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	49	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		
 | 
			
		||||
		/*	50	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	51	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
		/*	52	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	53	*/	{	0	,	0x002c	,	0x002c	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	54	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	55	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	56	*/	{	0	,	0x003c	,	0x003e	,	-1	,	0x007c	,	0x007c	}	,
 | 
			
		||||
		/*	57	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
		/*	58	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	59	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,		
 | 
			
		||||
		
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	private static GermanLayout instance = new GermanLayout();
 | 
			
		||||
	
 | 
			
		||||
	private GermanLayout() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static GermanLayout getInstance() {
 | 
			
		||||
		return instance;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public int[][] getLUT() {
 | 
			
		||||
		return LUT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void type(String text) {
 | 
			
		||||
		super.type(LUT, text);
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	@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;
 | 
			
		||||
	}			
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,269 @@
 | 
			
		||||
package com.inputstick.api.layout;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.ConnectionManager;
 | 
			
		||||
import com.inputstick.api.basic.InputStickHID;
 | 
			
		||||
import com.inputstick.api.hid.HIDKeycodes;
 | 
			
		||||
import com.inputstick.api.hid.HIDTransaction;
 | 
			
		||||
import com.inputstick.api.hid.KeyboardReport;
 | 
			
		||||
 | 
			
		||||
public abstract class KeyboardLayout {
 | 
			
		||||
	
 | 
			
		||||
	public static final byte[] scanCodeToHID = {
 | 
			
		||||
		/* 0x00 */ 0,
 | 
			
		||||
		/* 0x01 */ HIDKeycodes.KEY_ESCAPE,
 | 
			
		||||
		/* 0x02 */ HIDKeycodes.KEY_1,
 | 
			
		||||
		/* 0x03 */ HIDKeycodes.KEY_2,
 | 
			
		||||
		/* 0x04 */ HIDKeycodes.KEY_3,
 | 
			
		||||
		/* 0x05 */ HIDKeycodes.KEY_4,
 | 
			
		||||
		/* 0x06 */ HIDKeycodes.KEY_5,
 | 
			
		||||
		/* 0x07 */ HIDKeycodes.KEY_6,
 | 
			
		||||
		/* 0x08 */ HIDKeycodes.KEY_7,
 | 
			
		||||
		/* 0x09 */ HIDKeycodes.KEY_8,
 | 
			
		||||
		/* 0x0a */ HIDKeycodes.KEY_9,
 | 
			
		||||
		/* 0x0b */ HIDKeycodes.KEY_0,
 | 
			
		||||
		/* 0x0c */ HIDKeycodes.KEY_MINUS,
 | 
			
		||||
		/* 0x0d */ HIDKeycodes.KEY_EQUALS,
 | 
			
		||||
		/* 0x0e */ HIDKeycodes.KEY_BACKSPACE,
 | 
			
		||||
		/* 0x0f */ HIDKeycodes.KEY_TAB,
 | 
			
		||||
			
 | 
			
		||||
		
 | 
			
		||||
		/* 0x10 */ HIDKeycodes.KEY_Q,
 | 
			
		||||
		/* 0x11 */ HIDKeycodes.KEY_W,
 | 
			
		||||
		/* 0x12 */ HIDKeycodes.KEY_E,
 | 
			
		||||
		/* 0x13 */ HIDKeycodes.KEY_R,
 | 
			
		||||
		/* 0x14 */ HIDKeycodes.KEY_T,
 | 
			
		||||
		/* 0x15 */ HIDKeycodes.KEY_Y,
 | 
			
		||||
		/* 0x16 */ HIDKeycodes.KEY_U,
 | 
			
		||||
		/* 0x17 */ HIDKeycodes.KEY_I,
 | 
			
		||||
		/* 0x18 */ HIDKeycodes.KEY_O,
 | 
			
		||||
		/* 0x19 */ HIDKeycodes.KEY_P,
 | 
			
		||||
		/* 0x1a */ HIDKeycodes.KEY_LEFT_BRACKET,
 | 
			
		||||
		/* 0x1b */ HIDKeycodes.KEY_RIGHT_BRACKET,
 | 
			
		||||
		/* 0x1c */ HIDKeycodes.KEY_ENTER,
 | 
			
		||||
		/* 0x1d */ 0, //RL CTRL
 | 
			
		||||
		/* 0x1e */ HIDKeycodes.KEY_A,
 | 
			
		||||
		/* 0x1f */ HIDKeycodes.KEY_S,	
 | 
			
		||||
		
 | 
			
		||||
		/* 0x20 */ HIDKeycodes.KEY_D,
 | 
			
		||||
		/* 0x21 */ HIDKeycodes.KEY_F,
 | 
			
		||||
		/* 0x22 */ HIDKeycodes.KEY_G,
 | 
			
		||||
		/* 0x23 */ HIDKeycodes.KEY_H,
 | 
			
		||||
		/* 0x24 */ HIDKeycodes.KEY_J,
 | 
			
		||||
		/* 0x25 */ HIDKeycodes.KEY_K,
 | 
			
		||||
		/* 0x26 */ HIDKeycodes.KEY_L,
 | 
			
		||||
		/* 0x27 */ HIDKeycodes.KEY_SEMICOLON,
 | 
			
		||||
		/* 0x28 */ HIDKeycodes.KEY_APOSTROPHE,
 | 
			
		||||
		/* 0x29 */ HIDKeycodes.KEY_GRAVE,
 | 
			
		||||
		/* 0x2a */ 0, //L SHIFT
 | 
			
		||||
		/* 0x2b */ HIDKeycodes.KEY_BACKSLASH,
 | 
			
		||||
		/* 0x2c */ HIDKeycodes.KEY_Z,
 | 
			
		||||
		/* 0x2d */ HIDKeycodes.KEY_X,
 | 
			
		||||
		/* 0x2e */ HIDKeycodes.KEY_C,
 | 
			
		||||
		/* 0x2f */ HIDKeycodes.KEY_V,		
 | 
			
		||||
		
 | 
			
		||||
		/* 0x30 */ HIDKeycodes.KEY_B,
 | 
			
		||||
		/* 0x31 */ HIDKeycodes.KEY_N,
 | 
			
		||||
		/* 0x32 */ HIDKeycodes.KEY_M,
 | 
			
		||||
		/* 0x33 */ HIDKeycodes.KEY_COMA,
 | 
			
		||||
		/* 0x34 */ HIDKeycodes.KEY_DOT,
 | 
			
		||||
		/* 0x35 */ HIDKeycodes.KEY_SLASH,
 | 
			
		||||
		/* 0x36 */ 0, //R SHIFT
 | 
			
		||||
		/* 0x37 */ HIDKeycodes.KEY_PRINT_SCREEN,
 | 
			
		||||
		/* 0x38 */ 0, //RL ALT
 | 
			
		||||
		/* 0x39 */ HIDKeycodes.KEY_SPACEBAR,
 | 
			
		||||
		/* 0x3a */ HIDKeycodes.KEY_CAPS_LOCK,
 | 
			
		||||
		/* 0x3b */ HIDKeycodes.KEY_F1,
 | 
			
		||||
		/* 0x3c */ HIDKeycodes.KEY_F2,
 | 
			
		||||
		/* 0x3d */ HIDKeycodes.KEY_F3,
 | 
			
		||||
		/* 0x3e */ HIDKeycodes.KEY_F4,
 | 
			
		||||
		/* 0x3f */ HIDKeycodes.KEY_F5,
 | 
			
		||||
		
 | 
			
		||||
		/* 0x40 */ HIDKeycodes.KEY_F6,
 | 
			
		||||
		/* 0x41 */ HIDKeycodes.KEY_F7,
 | 
			
		||||
		/* 0x42 */ HIDKeycodes.KEY_F8,
 | 
			
		||||
		/* 0x43 */ HIDKeycodes.KEY_F9,
 | 
			
		||||
		/* 0x44 */ HIDKeycodes.KEY_F10,
 | 
			
		||||
		/* 0x45 */ HIDKeycodes.KEY_NUM_LOCK,
 | 
			
		||||
		/* 0x46 */ HIDKeycodes.KEY_SCROLL_LOCK,
 | 
			
		||||
		/* 0x47 */ HIDKeycodes.KEY_HOME,
 | 
			
		||||
		/* 0x48 */ HIDKeycodes.KEY_ARROW_UP,
 | 
			
		||||
		/* 0x49 */ HIDKeycodes.KEY_PAGE_UP,
 | 
			
		||||
		/* 0x4a */ 0, //-
 | 
			
		||||
		/* 0x4b */ HIDKeycodes.KEY_ARROW_LEFT,
 | 
			
		||||
		/* 0x4c */ 0, //CENTER
 | 
			
		||||
		/* 0x4d */ HIDKeycodes.KEY_ARROW_RIGHT,
 | 
			
		||||
		/* 0x4e */ 0, //+
 | 
			
		||||
		/* 0x4f */ HIDKeycodes.KEY_END,
 | 
			
		||||
		
 | 
			
		||||
		/* 0x50 */ HIDKeycodes.KEY_ARROW_DOWN,
 | 
			
		||||
		/* 0x51 */ HIDKeycodes.KEY_PAGE_DOWN,
 | 
			
		||||
		/* 0x52 */ HIDKeycodes.KEY_INSERT,
 | 
			
		||||
		/* 0x53 */ HIDKeycodes.KEY_DELETE,
 | 
			
		||||
		/* 0x54 */ 0,
 | 
			
		||||
		/* 0x55 */ 0,
 | 
			
		||||
		/* 0x56 */ 0,
 | 
			
		||||
		/* 0x57 */ HIDKeycodes.KEY_F11,
 | 
			
		||||
		/* 0x58 */ HIDKeycodes.KEY_F12,
 | 
			
		||||
		/* 0x59 */ 0,
 | 
			
		||||
		/* 0x5a */ 0,
 | 
			
		||||
		/* 0x5b */ 0,
 | 
			
		||||
		/* 0x5c */ 0,
 | 
			
		||||
		/* 0x5d */ 0,
 | 
			
		||||
		/* 0x5e */ 0,
 | 
			
		||||
		/* 0x5f */ 0,		
 | 
			
		||||
		
 | 
			
		||||
	};	
 | 
			
		||||
	
 | 
			
		||||
	public static final int LAYOUT_CODE = 0;
 | 
			
		||||
	
 | 
			
		||||
	public abstract int[][] getLUT();
 | 
			
		||||
	public abstract String getLocaleName();
 | 
			
		||||
	public abstract void type(String text);
 | 
			
		||||
	public abstract char getChar(int scanCode, boolean capsLock, boolean shift, boolean altGr);
 | 
			
		||||
	
 | 
			
		||||
	public void type(int[][] lut, String text) {
 | 
			
		||||
		if (InputStickHID.getState() == ConnectionManager.STATE_READY) {			
 | 
			
		||||
			char[] chars = text.toCharArray();
 | 
			
		||||
			HIDTransaction t;
 | 
			
		||||
			for (char c : chars) {
 | 
			
		||||
				t = getHIDTransaction(lut, c);
 | 
			
		||||
				if (t != null) {
 | 
			
		||||
					InputStickHID.addKeyboardTransaction(t);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	public static int hidToScanCode(byte key) {
 | 
			
		||||
		for (int scanCode = 0; scanCode < 80; scanCode++) {
 | 
			
		||||
			if (scanCodeToHID[scanCode] == key) {
 | 
			
		||||
				return scanCode;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static char getChar(int[][] lut, int scanCode, boolean capsLock, boolean shift, boolean altGr) {
 | 
			
		||||
		if ((scanCode > 80) || (scanCode < 0)) {
 | 
			
		||||
			return (char)0;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		int index = 1;
 | 
			
		||||
		
 | 
			
		||||
		if ((capsLock) && (lut[scanCode][0] > 0)) {
 | 
			
		||||
			//capslock is on and it affects current key						
 | 
			
		||||
			if (lut[scanCode][0] == 1) {
 | 
			
		||||
				if (shift) {
 | 
			
		||||
					index = 1; //caps + shift = default
 | 
			
		||||
				} else {
 | 
			
		||||
					index = 2; //shift
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				// >1
 | 
			
		||||
				if (shift) {
 | 
			
		||||
					if (altGr) {
 | 
			
		||||
						index = 4; //caps + shift + alt = alt
 | 
			
		||||
					} else {					
 | 
			
		||||
						index = 1; //caps + shift = default
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					if (altGr) {
 | 
			
		||||
						index = 5; //caps + alt = shift + alt
 | 
			
		||||
					} else {
 | 
			
		||||
						index = 2; //caps = shift
 | 
			
		||||
					}
 | 
			
		||||
				}					
 | 
			
		||||
			}
 | 
			
		||||
		} else {				
 | 
			
		||||
			if (shift) {
 | 
			
		||||
				index = 2;
 | 
			
		||||
			}		
 | 
			
		||||
			if (altGr) {
 | 
			
		||||
				if (shift) {
 | 
			
		||||
					index = 5;
 | 
			
		||||
				} else {
 | 
			
		||||
					index = 4;
 | 
			
		||||
				}
 | 
			
		||||
			} 
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (lut[scanCode][index] == -1) {
 | 
			
		||||
			index = 1;
 | 
			
		||||
		} 
 | 
			
		||||
		return (char)lut[scanCode][index];		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static int getScanCode(int[][] lut, char c) {		
 | 
			
		||||
		for (int scanCode = 0; scanCode < 80; scanCode++) {
 | 
			
		||||
			if (lut[scanCode][0] == -1) {
 | 
			
		||||
				continue;
 | 
			
		||||
			} else {
 | 
			
		||||
				for (int i = 1; i < 6; i++) {
 | 
			
		||||
					if (lut[scanCode][i] == (int)c) {
 | 
			
		||||
						return scanCode;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static byte getKey(int scanCode) {	
 | 
			
		||||
		return scanCodeToHID[scanCode];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static byte getModifiers(int[][] lut, int scanCode, char c) {
 | 
			
		||||
		if (lut[scanCode][1] == (int)c) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (lut[scanCode][2] == (int)c) {
 | 
			
		||||
			return HIDKeycodes.SHIFT_LEFT;
 | 
			
		||||
		}
 | 
			
		||||
		if (lut[scanCode][3] == (int)c) {
 | 
			
		||||
			return HIDKeycodes.CTRL_LEFT;
 | 
			
		||||
		}
 | 
			
		||||
		if (lut[scanCode][4] == (int)c) {
 | 
			
		||||
			return HIDKeycodes.ALT_RIGHT;
 | 
			
		||||
		}
 | 
			
		||||
		if (lut[scanCode][5] == (int)c) {
 | 
			
		||||
			return HIDKeycodes.SHIFT_LEFT | HIDKeycodes.ALT_RIGHT;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public static HIDTransaction getHIDTransaction(int[][] lut, char c) {
 | 
			
		||||
		byte modifiers, key;
 | 
			
		||||
		int scanCode;
 | 
			
		||||
		
 | 
			
		||||
		HIDTransaction t = new HIDTransaction();		
 | 
			
		||||
		scanCode = getScanCode(lut, c);
 | 
			
		||||
		if (scanCode > 0) {
 | 
			
		||||
			key = getKey(scanCode);
 | 
			
		||||
			modifiers = getModifiers(lut, scanCode, c);
 | 
			
		||||
			
 | 
			
		||||
			t.addReport(new KeyboardReport(modifiers, (byte)0));
 | 
			
		||||
			t.addReport(new KeyboardReport(modifiers, key));
 | 
			
		||||
			t.addReport(new KeyboardReport());
 | 
			
		||||
		}
 | 
			
		||||
		return t;
 | 
			
		||||
	}		
 | 
			
		||||
	
 | 
			
		||||
	public static KeyboardLayout getLayout(String locale) {
 | 
			
		||||
		if (locale != null) {
 | 
			
		||||
			if (locale.equals(UnitedStatesLayout.getInstance().getLocaleName())) {
 | 
			
		||||
				return UnitedStatesLayout.getInstance();
 | 
			
		||||
			} else if (locale.equals(PolishLayout.getInstance().getLocaleName())) {
 | 
			
		||||
				return PolishLayout.getInstance();
 | 
			
		||||
			} else if (locale.equals(RussianLayout.getInstance().getLocaleName())) {
 | 
			
		||||
				return RussianLayout.getInstance();
 | 
			
		||||
			} else if (locale.equals(GermanLayout.getInstance().getLocaleName())) {
 | 
			
		||||
				return GermanLayout.getInstance();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return UnitedStatesLayout.getInstance();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,144 @@
 | 
			
		||||
package com.inputstick.api.layout;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class PolishLayout extends KeyboardLayout {
 | 
			
		||||
	
 | 
			
		||||
	public static final String LOCALE_NAME = "pl-PL";
 | 
			
		||||
	
 | 
			
		||||
	public static final int LUT[][] = {
 | 
			
		||||
	/*	0	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	1	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	2	*/	{	0	,	(int)'1'	,	0x21	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	3	*/	{	0	,	(int)'2'	,	0x40	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	4	*/	{	0	,	(int)'3'	,	0x23	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	5	*/	{	0	,	(int)'4'	,	0x24	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	6	*/	{	0	,	(int)'5'	,	0x25	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	7	*/	{	0	,	(int)'6'	,	0x005e	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	8	*/	{	0	,	(int)'7'	,	0x26	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	9	*/	{	0	,	(int)'8'	,	0x002a	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	0a	*/	{	0	,	(int)'9'	,	0x28	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	0b	*/	{	0	,	(int)'0'	,	0x29	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	0c	*/	{	0	,	0x002d		,	0x005f	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	0d	*/	{	0	,	0x003d		,	0x002b	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	0e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	0f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	
 | 
			
		||||
	/*	10	*/	{	1	,	(int)'q'	,	(int)'Q'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	11	*/	{	1	,	(int)'w'	,	(int)'W'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	12	*/	{	5	,	(int)'e'	,	(int)'E'	,	-1	,	0x119	,	0x118	}	,
 | 
			
		||||
	/*	13	*/	{	1	,	(int)'r'	,	(int)'R'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	14	*/	{	1	,	(int)'t'	,	(int)'T'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	15	*/	{	1	,	(int)'y'	,	(int)'Y'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	16	*/	{	1	,	(int)'u'	,	(int)'U'	,	-1	,	0x20ac	,	-1	}	,
 | 
			
		||||
	/*	17	*/	{	1	,	(int)'i'	,	(int)'I'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	18	*/	{	5	,	(int)'o'	,	(int)'O'	,	-1	,	0x00f3	,	0x00d3	}	,
 | 
			
		||||
	/*	19	*/	{	1	,	(int)'p'	,	(int)'P'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	1a	*/	{	0	,	0x005b	,	0x007b	,	0x001b	,	-1	,	-1	}	,
 | 
			
		||||
	/*	1b	*/	{	0	,	0x005d	,	0x007d	,	0x001d	,	-1	,	-1	}	,
 | 
			
		||||
	/*	1c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	1d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	1e	*/	{	5	,	(int)'a'	,	(int)'A'	,	-1	,	0x105	,	0x104	}	,
 | 
			
		||||
	/*	1f	*/	{	5	,	(int)'s'	,	(int)'S'	,	-1	,	0x015b	,	0x015a	}	,
 | 
			
		||||
	
 | 
			
		||||
	/*	20	*/	{	1	,	(int)'d'	,	(int)'D'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	21	*/	{	1	,	(int)'f'	,	(int)'F'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	22	*/	{	1	,	(int)'g'	,	(int)'G'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	23	*/	{	1	,	(int)'h'	,	(int)'H'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	24	*/	{	1	,	(int)'j'	,	(int)'J'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	25	*/	{	1	,	(int)'k'	,	(int)'K'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	26	*/	{	5	,	(int)'l'	,	(int)'L'	,	-1	,	0x142	,	0x141	}	,
 | 
			
		||||
	/*	27	*/	{	0	,	0x003b	,	0x003a	,	0x001d	,	-1	,	-1	}	,
 | 
			
		||||
	/*	28	*/	{	0	,	0x27	,	0x22	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	29	*/	{	0	,	0x60	,	0x007e	,	-1	,	-1	,	-1	}	, //@
 | 
			
		||||
	/*	2a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	2b	*/	{	0	,	0x005c	,	0x007c	,	0x001c	,	-1	,	-1	}	,
 | 
			
		||||
	/*	2c	*/	{	5	,	(int)'z'	,	(int)'Z'	,	-1	,	0x017c	,	0x017b	}	,
 | 
			
		||||
	/*	2d	*/	{	5	,	(int)'x'	,	(int)'X'	,	-1	,	0x017a	,	0x179	}	,
 | 
			
		||||
	/*	2e	*/	{	5	,	(int)'c'	,	(int)'C'	,	-1	,	0x107	,	0x106	}	,
 | 
			
		||||
	/*	2f	*/	{	1	,	(int)'v'	,	(int)'V'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	
 | 
			
		||||
	/*	30	*/	{	1	,	(int)'b'	,	(int)'B'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	31	*/	{	5	,	(int)'n'	,	(int)'N'	,	-1	,	0x144	,	0x143	}	,
 | 
			
		||||
	/*	32	*/	{	1	,	(int)'m'	,	(int)'M'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	33	*/	{	0	,	0x002c	,	0x003c	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	34	*/	{	0	,	0x002e	,	0x003e	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	35	*/	{	0	,	0x002f	,	0x003f	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	36	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	37	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	38	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	39	*/	{	0	,	0x20	,	0x20	,	0x20	,	-1	,	-1	}	,
 | 
			
		||||
	/*	3a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	3b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	3c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	3d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	3e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	3f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	
 | 
			
		||||
	/*	40	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	41	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	42	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	43	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	44	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	45	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	46	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	47	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
	/*	48	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	49	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
	
 | 
			
		||||
	/*	50	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	51	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	52	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
	/*	53	*/	{	0	,	0x002c	,	0x002c		,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	54	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	55	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
	/*	56	*/	{	0	,	0x005c	,	0x007c		,	0x001c	,	-1	,	-1	}	,
 | 
			
		||||
	/*	57	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
	/*	58	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	59	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,		
 | 
			
		||||
	
 | 
			
		||||
		
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	private static PolishLayout instance = new PolishLayout();
 | 
			
		||||
	
 | 
			
		||||
	private PolishLayout() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static PolishLayout getInstance() {
 | 
			
		||||
		return instance;
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public int[][] getLUT() {
 | 
			
		||||
		return LUT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void type(String text) {
 | 
			
		||||
		super.type(LUT, text);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@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;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,144 @@
 | 
			
		||||
package com.inputstick.api.layout;
 | 
			
		||||
 | 
			
		||||
public class RussianLayout extends KeyboardLayout {
 | 
			
		||||
	
 | 
			
		||||
	public static final String LOCALE_NAME = "ru-RU";
 | 
			
		||||
	
 | 
			
		||||
	public static final int LUT[][] = {
 | 
			
		||||
	/*	0	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	1	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	2	*/	{	0	,	(int)'1'	,	0x21	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	3	*/	{	0	,	(int)'2'	,	0x22	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	4	*/	{	0	,	(int)'3'	,	0x2116	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	5	*/	{	0	,	(int)'4'	,	0x003b	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	6	*/	{	0	,	(int)'5'	,	0x25	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	7	*/	{	0	,	(int)'6'	,	0x003a	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	8	*/	{	0	,	(int)'7'	,	0x003f	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	9	*/	{	0	,	(int)'8'	,	0x002a	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	0a	*/	{	0	,	(int)'9'	,	0x28	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	0b	*/	{	0	,	(int)'0'	,	0x29	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	0c	*/	{	0	,	0x002d	,	0x005f	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	0d	*/	{	0	,	0x003d	,	0x002b	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	0e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	0f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	
 | 
			
		||||
	/*	10	*/	{	1	,	0x439	,	0x419	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	11	*/	{	1	,	0x446	,	0x426	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	12	*/	{	1	,	0x443	,	0x423	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	13	*/	{	1	,	0x043a	,	0x041a	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	14	*/	{	1	,	0x435	,	0x415	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	15	*/	{	1	,	0x043d	,	0x041d	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	16	*/	{	1	,	0x433	,	0x413	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	17	*/	{	1	,	0x448	,	0x428	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	18	*/	{	1	,	0x449	,	0x429	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	19	*/	{	1	,	0x437	,	0x417	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	1a	*/	{	1	,	0x445	,	0x425	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	1b	*/	{	1	,	0x044a	,	0x042a	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	1c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	1d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	1e	*/	{	1	,	0x444	,	0x424	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	1f	*/	{	1	,	0x044b	,	0x042b	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	/*	20	*/	{	1	,	0x432	,	0x412	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	21	*/	{	1	,	0x430	,	0x410	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	22	*/	{	1	,	0x043f	,	0x041f	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	23	*/	{	1	,	0x440	,	0x420	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	24	*/	{	1	,	0x043e	,	0x041e	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	25	*/	{	1	,	0x043b	,	0x041b	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	26	*/	{	1	,	0x434	,	0x414	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	27	*/	{	1	,	0x436	,	0x416	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	28	*/	{	1	,	0x044d	,	0x042d	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	29	*/	{	1	,	0x451	,	0x401	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	2a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	2b	*/	{	0	,	0x005c	,	0x002f	,	0x001c	,	-1	,	-1	}	,
 | 
			
		||||
	/*	2c	*/	{	1	,	0x044f	,	0x042f	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	2d	*/	{	1	,	0x447	,	0x427	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	2e	*/	{	1	,	0x441	,	0x421	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	2f	*/	{	1	,	0x043c	,	0x041c	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	/*	30	*/	{	1	,	0x438	,	0x418	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	31	*/	{	1	,	0x442	,	0x422	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	32	*/	{	1	,	0x044c	,	0x042c	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	33	*/	{	1	,	0x431	,	0x411	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	34	*/	{	1	,	0x044e	,	0x042e	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	35	*/	{	0	,	0x002e	,	0x002c	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	36	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	37	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	38	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	39	*/	{	0	,	0x20	,	0x20	,	0x20	,	-1	,	-1	}	,
 | 
			
		||||
	/*	3a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	3b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	3c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	3d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	3e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	3f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	
 | 
			
		||||
	/*	40	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	41	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	42	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	43	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	44	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	45	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	46	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	47	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
	/*	48	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	49	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	4f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	/*	50	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	51	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
	/*	52	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	53	*/	{	0	,	0x002c	,	0x002c	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
	/*	54	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	55	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	56	*/	{	0	,	0x005c	,	0x002f	,	0x001c	,	-1	,	-1	}	,
 | 
			
		||||
	/*	57	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
	/*	58	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	59	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
	/*	5f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,				
 | 
			
		||||
		
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	private static RussianLayout instance = new RussianLayout();
 | 
			
		||||
	
 | 
			
		||||
	private RussianLayout() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static RussianLayout getInstance() {
 | 
			
		||||
		return instance;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public int[][] getLUT() {
 | 
			
		||||
		return LUT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void type(String text) {
 | 
			
		||||
		super.type(LUT, text);
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	@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;
 | 
			
		||||
	}		
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,146 @@
 | 
			
		||||
package com.inputstick.api.layout;
 | 
			
		||||
 | 
			
		||||
public class UnitedStatesLayout extends KeyboardLayout {
 | 
			
		||||
	
 | 
			
		||||
	public static final String LOCALE_NAME = "en-US";
 | 
			
		||||
	
 | 
			
		||||
	public static final int LUT[][] = {
 | 
			
		||||
		/*	0	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	1	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	2	*/	{	0	,	(int)'1'	,	0x21	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	3	*/	{	0	,	(int)'2'	,	0x40	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	4	*/	{	0	,	(int)'3'	,	0x23	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	5	*/	{	0	,	(int)'4'	,	0x24	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	6	*/	{	0	,	(int)'5'	,	0x25	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	7	*/	{	0	,	(int)'6'	,	0x005e	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	8	*/	{	0	,	(int)'7'	,	0x26	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	9	*/	{	0	,	(int)'8'	,	0x002a	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	0a	*/	{	0	,	(int)'9'	,	0x28	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	0b	*/	{	0	,	(int)'0'	,	0x29	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	0c	*/	{	0	,	0x002d	,	0x005f	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	0d	*/	{	0	,	0x003d	,	0x002b	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	0e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	0f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		/*	10	*/	{	1	,	(int)'q'	,	(int)'Q'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	11	*/	{	1	,	(int)'w'	,	(int)'W'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	12	*/	{	1	,	(int)'e'	,	(int)'E'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	13	*/	{	1	,	(int)'r'	,	(int)'R'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	14	*/	{	1	,	(int)'t'	,	(int)'T'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	15	*/	{	1	,	(int)'y'	,	(int)'Y'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	16	*/	{	1	,	(int)'u'	,	(int)'U'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	17	*/	{	1	,	(int)'i'	,	(int)'I'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	18	*/	{	1	,	(int)'o'	,	(int)'O'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	19	*/	{	1	,	(int)'p'	,	(int)'P'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	1a	*/	{	0	,	0x005b	,	0x007b	,	0x001b	,	-1	,	-1	}	,
 | 
			
		||||
		/*	1b	*/	{	0	,	0x005d	,	0x007d	,	0x001d	,	-1	,	-1	}	,
 | 
			
		||||
		/*	1c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	1d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	1e	*/	{	1	,	(int)'a'	,	(int)'A'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	1f	*/	{	1	,	(int)'s'	,	(int)'S' ,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		/*	20	*/	{	1	,	(int)'d'	,	(int)'D'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	21	*/	{	1	,	(int)'f'	,	(int)'F'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	22	*/	{	1	,	(int)'g'	,	(int)'G'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	23	*/	{	1	,	(int)'h'	,	(int)'H'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	24	*/	{	1	,	(int)'j'	,	(int)'J'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	25	*/	{	1	,	(int)'k'	,	(int)'K'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	26	*/	{	1	,	(int)'l'	,	(int)'L'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	27	*/	{	0	,	0x003b	,	0x003a	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	28	*/	{	0	,	0x27	,	0x22	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	29	*/	{	0	,	0x60	,	0x007e	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	2a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	2b	*/	{	0	,	0x005c	,	0x007c	,	0x001c	,	-1	,	-1	}	,
 | 
			
		||||
		/*	2c	*/	{	1	,	(int)'z'	,	(int)'Z'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	2d	*/	{	1	,	(int)'x'	,	(int)'X'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	2e	*/	{	1	,	(int)'c'	,	(int)'C'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	2f	*/	{	1	,	(int)'v'	,	(int)'V'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		/*	30	*/	{	1	,	(int)'b'	,	(int)'B'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	31	*/	{	1	,	(int)'n'	,	(int)'N'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	32	*/	{	1	,	(int)'m'	,	(int)'M'	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	33	*/	{	0	,	0x002c	,	0x003c	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	34	*/	{	0	,	0x002e	,	0x003e	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	35	*/	{	0	,	0x002f	,	0x003f	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	36	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	37	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	38	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,		
 | 
			
		||||
		/*	39	*/	{	0	,	0x20	,	0x20	,	0x20	,	-1	,	-1	}	,
 | 
			
		||||
		/*	3a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	3b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	3c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	3d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	3e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	3f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		/*	40	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	41	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	42	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	43	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	44	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	45	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	46	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	47	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
		/*	48	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	49	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	4f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,		
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		/*	50	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	51	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
		/*	52	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,		
 | 
			
		||||
		/*	53	*/	{	0	,	0x002e	,	0x002e	,	-1	,	-1	,	-1	}	,
 | 
			
		||||
		/*	54	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	55	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,		
 | 
			
		||||
		/*	56	*/	{	0	,	0x005c	,	0x007c	,	0x001c	,	-1	,	-1	}	,
 | 
			
		||||
		/*	57	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,	
 | 
			
		||||
		/*	58	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	59	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5a	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5b	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5c	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5d	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5e	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,
 | 
			
		||||
		/*	5f	*/	{	-1	,	0			,	0		,	0	,	0	,	0	}	,			
 | 
			
		||||
		
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	private static UnitedStatesLayout instance = new UnitedStatesLayout();
 | 
			
		||||
	
 | 
			
		||||
	private UnitedStatesLayout() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static UnitedStatesLayout getInstance() {
 | 
			
		||||
		return instance;
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public int[][] getLUT() {
 | 
			
		||||
		return LUT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void type(String text) {
 | 
			
		||||
		super.type(LUT, text);
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	@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;
 | 
			
		||||
	}		
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,61 @@
 | 
			
		||||
package com.inputstick.init;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.Packet;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class BasicInitManager extends InitManager {
 | 
			
		||||
	
 | 
			
		||||
	private boolean initDone = false;	
 | 
			
		||||
	
 | 
			
		||||
	public BasicInitManager(byte[] key) {
 | 
			
		||||
		super(key);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onConnected() {		
 | 
			
		||||
		/*Packet p = new Packet(false, Packet.RAW_OLD_BOOTLOADER); //compatibility
 | 
			
		||||
		sendPacket(p);*/
 | 
			
		||||
		
 | 
			
		||||
		sendPacket(new Packet(true, Packet.CMD_RUN_FW));			
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onData(byte[] data) {
 | 
			
		||||
		byte cmd = data[0];
 | 
			
		||||
		byte respCode = data[1];
 | 
			
		||||
		byte param = data[1];
 | 
			
		||||
		
 | 
			
		||||
		if (cmd == Packet.CMD_RUN_FW) {
 | 
			
		||||
			sendPacket(new Packet(true, Packet.CMD_GET_INFO));
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (cmd == Packet.CMD_GET_INFO) {
 | 
			
		||||
			//store info
 | 
			
		||||
			sendPacket(new Packet(true, Packet.CMD_INIT)); //TODO params!	
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (cmd == Packet.CMD_INIT) {
 | 
			
		||||
			if (respCode == Packet.RESP_OK) {						
 | 
			
		||||
				initDone = true;
 | 
			
		||||
				sendPacket(new Packet(false, Packet.CMD_HID_STATUS_REPORT));
 | 
			
		||||
			} else {
 | 
			
		||||
				mListener.onInitFailure(respCode);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (cmd == Packet.CMD_HID_STATUS) {
 | 
			
		||||
			if (initDone) {
 | 
			
		||||
				if (param == 0x05) {
 | 
			
		||||
					mListener.onInitReady();
 | 
			
		||||
				} else {
 | 
			
		||||
					mListener.onInitNotReady();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
package com.inputstick.init;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.Packet;
 | 
			
		||||
 | 
			
		||||
public class BootloaderInitManager extends InitManager {
 | 
			
		||||
 | 
			
		||||
	public BootloaderInitManager(byte[] key) {
 | 
			
		||||
		super(key);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onConnected() {
 | 
			
		||||
		//TODO key
 | 
			
		||||
		sendPacket(new Packet(true, Packet.CMD_RUN_BL));			
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onData(byte[] data) {
 | 
			
		||||
		byte cmd = data[0];
 | 
			
		||||
		//byte respCode = data[1];
 | 
			
		||||
		//byte param = data[1];
 | 
			
		||||
		
 | 
			
		||||
		if (cmd == Packet.CMD_RUN_BL) {
 | 
			
		||||
			mListener.onInitReady();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
package com.inputstick.init;
 | 
			
		||||
 | 
			
		||||
import com.inputstick.api.Packet;
 | 
			
		||||
import com.inputstick.api.PacketManager;
 | 
			
		||||
 | 
			
		||||
public class InitManager {
 | 
			
		||||
	
 | 
			
		||||
	protected PacketManager mPacketManager;
 | 
			
		||||
	protected InitManagerListener mListener;	
 | 
			
		||||
	protected byte[] mKey;
 | 
			
		||||
	
 | 
			
		||||
	public InitManager(byte[] key) {
 | 
			
		||||
		mKey = key;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void init(InitManagerListener listener, PacketManager packetManager) {
 | 
			
		||||
		mListener = listener;
 | 
			
		||||
		mPacketManager = packetManager;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	public void onConnected() {
 | 
			
		||||
		mListener.onInitReady();
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	public void onData(byte[] data) {
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void sendPacket(Packet p) {
 | 
			
		||||
		mPacketManager.sendPacket(p);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
package com.inputstick.init;
 | 
			
		||||
 | 
			
		||||
public interface InitManagerListener {
 | 
			
		||||
	
 | 
			
		||||
	public void onInitReady();
 | 
			
		||||
	public void onInitNotReady();
 | 
			
		||||
	public void onInitFailure(int code);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								src/java/PluginA/.classpath
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,9 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<classpath>
 | 
			
		||||
	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
 | 
			
		||||
	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
 | 
			
		||||
	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
 | 
			
		||||
	<classpathentry kind="src" path="src"/>
 | 
			
		||||
	<classpathentry kind="src" path="gen"/>
 | 
			
		||||
	<classpathentry kind="output" path="bin/classes"/>
 | 
			
		||||
</classpath>
 | 
			
		||||
							
								
								
									
										33
									
								
								src/java/PluginA/.project
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,33 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<projectDescription>
 | 
			
		||||
	<name>PluginA</name>
 | 
			
		||||
	<comment></comment>
 | 
			
		||||
	<projects>
 | 
			
		||||
	</projects>
 | 
			
		||||
	<buildSpec>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>org.eclipse.jdt.core.javabuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
	</buildSpec>
 | 
			
		||||
	<natures>
 | 
			
		||||
		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
 | 
			
		||||
		<nature>org.eclipse.jdt.core.javanature</nature>
 | 
			
		||||
	</natures>
 | 
			
		||||
</projectDescription>
 | 
			
		||||
							
								
								
									
										4
									
								
								src/java/PluginA/.settings/org.eclipse.jdt.core.prefs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,4 @@
 | 
			
		||||
eclipse.preferences.version=1
 | 
			
		||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
 | 
			
		||||
org.eclipse.jdt.core.compiler.compliance=1.6
 | 
			
		||||
org.eclipse.jdt.core.compiler.source=1.6
 | 
			
		||||
							
								
								
									
										50
									
								
								src/java/PluginA/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,50 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    package="keepass2android.plugina"
 | 
			
		||||
    android:versionCode="1"
 | 
			
		||||
    android:versionName="1.0" >
 | 
			
		||||
 | 
			
		||||
    <uses-sdk
 | 
			
		||||
        android:minSdkVersion="14"
 | 
			
		||||
        android:targetSdkVersion="19" />
 | 
			
		||||
 | 
			
		||||
    <application
 | 
			
		||||
        android:allowBackup="true"
 | 
			
		||||
        android:icon="@drawable/ic_launcher"
 | 
			
		||||
        android:label="@string/app_name"
 | 
			
		||||
        android:theme="@style/AppTheme" >
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name="keepass2android.plugina.PlugInA"
 | 
			
		||||
            android:label="@string/app_name" >
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="android.intent.action.MAIN" />
 | 
			
		||||
 | 
			
		||||
                <category android:name="android.intent.category.LAUNCHER" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </activity>
 | 
			
		||||
        
 | 
			
		||||
        <receiver android:name="PluginAAccessReceiver" android:exported="true">
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="keepass2android.ACTION_TRIGGER_REQUEST_ACCESS" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_RECEIVE_ACCESS" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_REVOKE_ACCESS" />
 | 
			
		||||
                
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </receiver>
 | 
			
		||||
        
 | 
			
		||||
        <receiver android:name="PluginAActionReceiver" android:exported="true">
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="keepass2android.ACTION_OPEN_ENTRY" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_CLOSE_ENTRY_VIEW" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_ENTRY_ACTION_SELECTED" />
 | 
			
		||||
                
 | 
			
		||||
                <action android:name="keepass2android.ACTION_LOCK_DATABASE" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_UNLOCK_DATABASE" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_CLOSE_DATABASE" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_OPEN_DATABASE" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </receiver>
 | 
			
		||||
        
 | 
			
		||||
            </application>
 | 
			
		||||
 | 
			
		||||
</manifest>
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
/** Automatically generated file. DO NOT MODIFY */
 | 
			
		||||
package keepass2android.plugina;
 | 
			
		||||
 | 
			
		||||
public final class BuildConfig {
 | 
			
		||||
    public final static boolean DEBUG = true;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										91
									
								
								src/java/PluginA/gen/keepass2android/plugina/R.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,91 @@
 | 
			
		||||
/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 | 
			
		||||
 *
 | 
			
		||||
 * This class was automatically generated by the
 | 
			
		||||
 * aapt tool from the resource data it found.  It
 | 
			
		||||
 * should not be modified by hand.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package keepass2android.plugina;
 | 
			
		||||
 | 
			
		||||
public final class R {
 | 
			
		||||
    public static final class attr {
 | 
			
		||||
    }
 | 
			
		||||
    public static final class dimen {
 | 
			
		||||
        /**  Default screen margins, per the Android Design guidelines. 
 | 
			
		||||
 | 
			
		||||
         Example customization of dimensions originally defined in res/values/dimens.xml
 | 
			
		||||
         (such as screen margins) for screens with more than 820dp of available width. This
 | 
			
		||||
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
 | 
			
		||||
    
 | 
			
		||||
 Default screen margins, per the Android Design guidelines. 
 | 
			
		||||
 | 
			
		||||
         Example customization of dimensions originally defined in res/values/dimens.xml
 | 
			
		||||
         (such as screen margins) for screens with more than 820dp of available width. This
 | 
			
		||||
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
 | 
			
		||||
    
 | 
			
		||||
         */
 | 
			
		||||
        public static final int activity_horizontal_margin=0x7f040000;
 | 
			
		||||
        public static final int activity_vertical_margin=0x7f040001;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class drawable {
 | 
			
		||||
        public static final int ic_launcher=0x7f020000;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class id {
 | 
			
		||||
        public static final int action_settings=0x7f080001;
 | 
			
		||||
        public static final int container=0x7f080000;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class layout {
 | 
			
		||||
        public static final int activity_plug_in=0x7f030000;
 | 
			
		||||
        public static final int fragment_plug_in=0x7f030001;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class menu {
 | 
			
		||||
        public static final int plug_in=0x7f070000;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class string {
 | 
			
		||||
        public static final int action_settings=0x7f050002;
 | 
			
		||||
        public static final int app_name=0x7f050000;
 | 
			
		||||
        public static final int hello_world=0x7f050001;
 | 
			
		||||
        public static final int kp2aplugin_author=0x7f050005;
 | 
			
		||||
        public static final int kp2aplugin_shortdesc=0x7f050004;
 | 
			
		||||
        public static final int kp2aplugin_title=0x7f050003;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class style {
 | 
			
		||||
        /** 
 | 
			
		||||
        Base application theme, dependent on API level. This theme is replaced
 | 
			
		||||
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
            Theme customizations available in newer API levels can go in
 | 
			
		||||
            res/values-vXX/styles.xml, while customizations related to
 | 
			
		||||
            backward-compatibility can go here.
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        Base application theme for API 11+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from res/values/styles.xml on API 11+ devices.
 | 
			
		||||
    
 | 
			
		||||
 API 11 theme customizations can go here. 
 | 
			
		||||
 | 
			
		||||
        Base application theme for API 14+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from BOTH res/values/styles.xml and
 | 
			
		||||
        res/values-v11/styles.xml on API 14+ devices.
 | 
			
		||||
    
 | 
			
		||||
 API 14 theme customizations can go here. 
 | 
			
		||||
 | 
			
		||||
        Base application theme, dependent on API level. This theme is replaced
 | 
			
		||||
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
            Theme customizations available in newer API levels can go in
 | 
			
		||||
            res/values-vXX/styles.xml, while customizations related to
 | 
			
		||||
            backward-compatibility can go here.
 | 
			
		||||
        
 | 
			
		||||
         */
 | 
			
		||||
        public static final int AppBaseTheme=0x7f060000;
 | 
			
		||||
        /**  Application theme. 
 | 
			
		||||
 All customizations that are NOT specific to a particular API-level can go here. 
 | 
			
		||||
 Application theme. 
 | 
			
		||||
 All customizations that are NOT specific to a particular API-level can go here. 
 | 
			
		||||
         */
 | 
			
		||||
        public static final int AppTheme=0x7f060001;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/java/PluginA/gen/keepass2android/pluginsdk/R.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,24 @@
 | 
			
		||||
/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 | 
			
		||||
 *
 | 
			
		||||
 * This class was automatically generated by the
 | 
			
		||||
 * aapt tool from the resource data it found.  It
 | 
			
		||||
 * should not be modified by hand.
 | 
			
		||||
 */
 | 
			
		||||
package keepass2android.pluginsdk;
 | 
			
		||||
 | 
			
		||||
public final class R {
 | 
			
		||||
	public static final class dimen {
 | 
			
		||||
		public static final int activity_horizontal_margin = 0x7f040000;
 | 
			
		||||
		public static final int activity_vertical_margin = 0x7f040001;
 | 
			
		||||
	}
 | 
			
		||||
	public static final class drawable {
 | 
			
		||||
		public static final int ic_launcher = 0x7f020000;
 | 
			
		||||
	}
 | 
			
		||||
	public static final class string {
 | 
			
		||||
		public static final int app_name = 0x7f050000;
 | 
			
		||||
	}
 | 
			
		||||
	public static final class style {
 | 
			
		||||
		public static final int AppBaseTheme = 0x7f060000;
 | 
			
		||||
		public static final int AppTheme = 0x7f060001;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/java/PluginA/libs/android-support-v4.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										20
									
								
								src/java/PluginA/proguard-project.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,20 @@
 | 
			
		||||
# To enable ProGuard in your project, edit project.properties
 | 
			
		||||
# to define the proguard.config property as described in that file.
 | 
			
		||||
#
 | 
			
		||||
# Add project specific ProGuard rules here.
 | 
			
		||||
# By default, the flags in this file are appended to flags specified
 | 
			
		||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
 | 
			
		||||
# You can edit the include path and order by changing the ProGuard
 | 
			
		||||
# include property in project.properties.
 | 
			
		||||
#
 | 
			
		||||
# For more details, see
 | 
			
		||||
#   http://developer.android.com/guide/developing/tools/proguard.html
 | 
			
		||||
 | 
			
		||||
# Add any project specific keep options here:
 | 
			
		||||
 | 
			
		||||
# If your project uses WebView with JS, uncomment the following
 | 
			
		||||
# and specify the fully qualified class name to the JavaScript interface
 | 
			
		||||
# class:
 | 
			
		||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
 | 
			
		||||
#   public *;
 | 
			
		||||
#}
 | 
			
		||||
							
								
								
									
										15
									
								
								src/java/PluginA/project.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,15 @@
 | 
			
		||||
# This file is automatically generated by Android Tools.
 | 
			
		||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
 | 
			
		||||
#
 | 
			
		||||
# This file must be checked in Version Control Systems.
 | 
			
		||||
#
 | 
			
		||||
# To customize properties used by the Ant build system edit
 | 
			
		||||
# "ant.properties", and override values to adapt the script to your
 | 
			
		||||
# project structure.
 | 
			
		||||
#
 | 
			
		||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
 | 
			
		||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
 | 
			
		||||
 | 
			
		||||
# Project target.
 | 
			
		||||
target=android-19
 | 
			
		||||
android.library.reference.1=../Keepass2AndroidPluginSDK
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/java/PluginA/res/drawable-xhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 14 KiB  | 
							
								
								
									
										8
									
								
								src/java/PluginA/res/layout/activity_plug_in.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,8 @@
 | 
			
		||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:id="@+id/container"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context="keepass2android.plugina.PlugInA"
 | 
			
		||||
    tools:ignore="MergeRootFrame" />
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								src/java/PluginA/res/layout/fragment_plug_in.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,16 @@
 | 
			
		||||
<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"
 | 
			
		||||
    android:paddingBottom="@dimen/activity_vertical_margin"
 | 
			
		||||
    android:paddingLeft="@dimen/activity_horizontal_margin"
 | 
			
		||||
    android:paddingRight="@dimen/activity_horizontal_margin"
 | 
			
		||||
    android:paddingTop="@dimen/activity_vertical_margin"
 | 
			
		||||
    tools:context="keepass2android.plugina.PlugInA$PlaceholderFragment" >
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:text="@string/hello_world" />
 | 
			
		||||
 | 
			
		||||
</RelativeLayout>
 | 
			
		||||
							
								
								
									
										12
									
								
								src/java/PluginA/res/menu/plug_in.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,12 @@
 | 
			
		||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    tools:context="keepass2android.plugina.PlugInA" >
 | 
			
		||||
 | 
			
		||||
    <item
 | 
			
		||||
        android:id="@+id/action_settings"
 | 
			
		||||
        android:orderInCategory="100"
 | 
			
		||||
        android:title="@string/action_settings"
 | 
			
		||||
        android:showAsAction="never"/>
 | 
			
		||||
 | 
			
		||||
</menu>
 | 
			
		||||
							
								
								
									
										10
									
								
								src/java/PluginA/res/values-w820dp/dimens.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,10 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
         Example customization of dimensions originally defined in res/values/dimens.xml
 | 
			
		||||
         (such as screen margins) for screens with more than 820dp of available width. This
 | 
			
		||||
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
 | 
			
		||||
    -->
 | 
			
		||||
    <dimen name="activity_horizontal_margin">64dp</dimen>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										7
									
								
								src/java/PluginA/res/values/dimens.xml
									
									
									
									
									
										Normal 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>
 | 
			
		||||
							
								
								
									
										11
									
								
								src/java/PluginA/res/values/strings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,11 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <string name="app_name">PluginA</string>
 | 
			
		||||
    <string name="hello_world">Hello world!</string>
 | 
			
		||||
    <string name="action_settings">Settings</string>
 | 
			
		||||
    <string name="kp2aplugin_title">The Great PluginA</string>
 | 
			
		||||
    <string name="kp2aplugin_shortdesc">Test plugin to demonstrate how plugins work</string>
 | 
			
		||||
    <string name="kp2aplugin_author">Philipp Crocoll</string>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										20
									
								
								src/java/PluginA/res/values/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,20 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
        Base application theme, dependent on API level. This theme is replaced
 | 
			
		||||
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 | 
			
		||||
    -->
 | 
			
		||||
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
 | 
			
		||||
        <!--
 | 
			
		||||
            Theme customizations available in newer API levels can go in
 | 
			
		||||
            res/values-vXX/styles.xml, while customizations related to
 | 
			
		||||
            backward-compatibility can go here.
 | 
			
		||||
        -->
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
    <!-- Application theme. -->
 | 
			
		||||
    <style name="AppTheme" parent="AppBaseTheme">
 | 
			
		||||
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
@@ -0,0 +1,20 @@
 | 
			
		||||
package keepass2android.plugina;
 | 
			
		||||
 | 
			
		||||
import android.content.BroadcastReceiver;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class EntryOpenedReceiver extends BroadcastReceiver {
 | 
			
		||||
	@Override
 | 
			
		||||
	  public void onReceive(Context context, Intent intent) {
 | 
			
		||||
	    Bundle extras = intent.getExtras();
 | 
			
		||||
	    if (extras != null) {
 | 
			
		||||
	      Log.w("PluginA", "received broadcast!");
 | 
			
		||||
	      
 | 
			
		||||
	    }
 | 
			
		||||
	  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								src/java/PluginA/src/keepass2android/plugina/PlugInA.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,62 @@
 | 
			
		||||
package keepass2android.plugina;
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.app.Fragment;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
 | 
			
		||||
public class PlugInA extends Activity {
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
		super.onCreate(savedInstanceState);
 | 
			
		||||
		setContentView(R.layout.activity_plug_in);
 | 
			
		||||
 | 
			
		||||
		if (savedInstanceState == null) {
 | 
			
		||||
			getFragmentManager().beginTransaction()
 | 
			
		||||
					.add(R.id.container, new PlaceholderFragment()).commit();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean onCreateOptionsMenu(Menu menu) {
 | 
			
		||||
 | 
			
		||||
		// Inflate the menu; this adds items to the action bar if it is present.
 | 
			
		||||
		getMenuInflater().inflate(R.menu.plug_in, menu);
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean onOptionsItemSelected(MenuItem item) {
 | 
			
		||||
		// Handle action bar item clicks here. The action bar will
 | 
			
		||||
		// automatically handle clicks on the Home/Up button, so long
 | 
			
		||||
		// as you specify a parent activity in AndroidManifest.xml.
 | 
			
		||||
		int id = item.getItemId();
 | 
			
		||||
		if (id == R.id.action_settings) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		return super.onOptionsItemSelected(item);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * A placeholder fragment containing a simple view.
 | 
			
		||||
	 */
 | 
			
		||||
	public static class PlaceholderFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
		public PlaceholderFragment() {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
				Bundle savedInstanceState) {
 | 
			
		||||
			View rootView = inflater.inflate(R.layout.fragment_plug_in,
 | 
			
		||||
					container, false);
 | 
			
		||||
			return rootView;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,20 @@
 | 
			
		||||
package keepass2android.plugina;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import keepass2android.pluginsdk.Strings;
 | 
			
		||||
 | 
			
		||||
public class PluginAAccessReceiver
 | 
			
		||||
 extends keepass2android.pluginsdk.PluginAccessBroadcastReceiver
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public ArrayList<String> getScopes() {
 | 
			
		||||
		ArrayList<String> scopes = new ArrayList<String>();
 | 
			
		||||
		scopes.add(Strings.SCOPE_DATABASE_ACTIONS);
 | 
			
		||||
		scopes.add(Strings.SCOPE_CURRENT_ENTRY);
 | 
			
		||||
		return scopes;
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								src/java/PluginInputStick/.classpath
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,9 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<classpath>
 | 
			
		||||
	<classpathentry kind="src" path="src"/>
 | 
			
		||||
	<classpathentry kind="src" path="gen"/>
 | 
			
		||||
	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
 | 
			
		||||
	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
 | 
			
		||||
	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
 | 
			
		||||
	<classpathentry kind="output" path="bin/classes"/>
 | 
			
		||||
</classpath>
 | 
			
		||||
							
								
								
									
										33
									
								
								src/java/PluginInputStick/.project
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,33 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<projectDescription>
 | 
			
		||||
	<name>PluginInputStick</name>
 | 
			
		||||
	<comment></comment>
 | 
			
		||||
	<projects>
 | 
			
		||||
	</projects>
 | 
			
		||||
	<buildSpec>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>org.eclipse.jdt.core.javabuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
	</buildSpec>
 | 
			
		||||
	<natures>
 | 
			
		||||
		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
 | 
			
		||||
		<nature>org.eclipse.jdt.core.javanature</nature>
 | 
			
		||||
	</natures>
 | 
			
		||||
</projectDescription>
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
eclipse.preferences.version=1
 | 
			
		||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
 | 
			
		||||
org.eclipse.jdt.core.compiler.compliance=1.6
 | 
			
		||||
org.eclipse.jdt.core.compiler.source=1.6
 | 
			
		||||
							
								
								
									
										57
									
								
								src/java/PluginInputStick/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,57 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    package="keepass2android.plugin.inputstick"
 | 
			
		||||
    android:versionCode="1"
 | 
			
		||||
    android:versionName="1.0" >
 | 
			
		||||
 | 
			
		||||
    <uses-sdk
 | 
			
		||||
        android:minSdkVersion="14"
 | 
			
		||||
        android:targetSdkVersion="19" />
 | 
			
		||||
 | 
			
		||||
    <application
 | 
			
		||||
        android:allowBackup="true"
 | 
			
		||||
        android:icon="@drawable/ic_launcher"
 | 
			
		||||
        android:label="@string/app_name"
 | 
			
		||||
        android:theme="@style/AppTheme" >
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name="keepass2android.plugin.inputstick.MainActivity"
 | 
			
		||||
            android:label="@string/app_name" >
 | 
			
		||||
            
 | 
			
		||||
        </activity>
 | 
			
		||||
 | 
			
		||||
        <receiver
 | 
			
		||||
            android:name="keepass2android.plugin.inputstick.AccessReceiver"
 | 
			
		||||
            android:exported="true" >
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="keepass2android.ACTION_TRIGGER_REQUEST_ACCESS" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_RECEIVE_ACCESS" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_REVOKE_ACCESS" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </receiver>
 | 
			
		||||
        <receiver
 | 
			
		||||
            android:name="keepass2android.plugin.inputstick.ActionReceiver"
 | 
			
		||||
            android:exported="true" >
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="keepass2android.ACTION_OPEN_ENTRY" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_ENTRY_OUTPUT_MODIFIED" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_ENTRY_ACTION_SELECTED" />
 | 
			
		||||
                <action android:name="keepass2android.ACTION_CLOSE_ENTRY_VIEW" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </receiver>
 | 
			
		||||
 | 
			
		||||
        <service
 | 
			
		||||
            android:name="keepass2android.plugin.inputstick.InputStickService"
 | 
			
		||||
            android:enabled="true" >
 | 
			
		||||
        </service>
 | 
			
		||||
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name="keepass2android.plugin.inputstick.SettingsActivity"
 | 
			
		||||
            android:label="@string/title_activity_settings" >
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="android.intent.action.MAIN" />
 | 
			
		||||
                <category android:name="android.intent.category.LAUNCHER" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </activity>
 | 
			
		||||
    </application>
 | 
			
		||||
 | 
			
		||||
</manifest>
 | 
			
		||||
							
								
								
									
										20
									
								
								src/java/PluginInputStick/gen/com/inputstick/api/R.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,20 @@
 | 
			
		||||
/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 | 
			
		||||
 *
 | 
			
		||||
 * This class was automatically generated by the
 | 
			
		||||
 * aapt tool from the resource data it found.  It
 | 
			
		||||
 * should not be modified by hand.
 | 
			
		||||
 */
 | 
			
		||||
package com.inputstick.api;
 | 
			
		||||
 | 
			
		||||
public final class R {
 | 
			
		||||
	public static final class drawable {
 | 
			
		||||
		public static final int ic_launcher = 0x7f020000;
 | 
			
		||||
	}
 | 
			
		||||
	public static final class string {
 | 
			
		||||
		public static final int app_name = 0x7f060000;
 | 
			
		||||
	}
 | 
			
		||||
	public static final class style {
 | 
			
		||||
		public static final int AppBaseTheme = 0x7f070000;
 | 
			
		||||
		public static final int AppTheme = 0x7f070001;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
/** Automatically generated file. DO NOT MODIFY */
 | 
			
		||||
package keepass2android.plugin.inputstick;
 | 
			
		||||
 | 
			
		||||
public final class BuildConfig {
 | 
			
		||||
    public final static boolean DEBUG = true;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,141 @@
 | 
			
		||||
/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 | 
			
		||||
 *
 | 
			
		||||
 * This class was automatically generated by the
 | 
			
		||||
 * aapt tool from the resource data it found.  It
 | 
			
		||||
 * should not be modified by hand.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package keepass2android.plugin.inputstick;
 | 
			
		||||
 | 
			
		||||
public final class R {
 | 
			
		||||
    public static final class array {
 | 
			
		||||
        public static final int layout_names=0x7f080000;
 | 
			
		||||
        public static final int layout_values=0x7f080001;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class attr {
 | 
			
		||||
    }
 | 
			
		||||
    public static final class dimen {
 | 
			
		||||
        /**  Default screen margins, per the Android Design guidelines. 
 | 
			
		||||
 | 
			
		||||
         Example customization of dimensions originally defined in res/values/dimens.xml
 | 
			
		||||
         (such as screen margins) for screens with more than 820dp of available width. This
 | 
			
		||||
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
 | 
			
		||||
    
 | 
			
		||||
 Default screen margins, per the Android Design guidelines. 
 | 
			
		||||
 | 
			
		||||
         Example customization of dimensions originally defined in res/values/dimens.xml
 | 
			
		||||
         (such as screen margins) for screens with more than 820dp of available width. This
 | 
			
		||||
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
 | 
			
		||||
    
 | 
			
		||||
         */
 | 
			
		||||
        public static final int activity_horizontal_margin=0x7f050000;
 | 
			
		||||
        public static final int activity_vertical_margin=0x7f050001;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class drawable {
 | 
			
		||||
        public static final int ic_launcher=0x7f020000;
 | 
			
		||||
        public static final int ic_notification=0x7f020001;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class id {
 | 
			
		||||
        public static final int action_settings=0x7f0a0003;
 | 
			
		||||
        public static final int button1=0x7f0a0001;
 | 
			
		||||
        public static final int button2=0x7f0a0002;
 | 
			
		||||
        public static final int container=0x7f0a0000;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class layout {
 | 
			
		||||
        public static final int activity_main=0x7f030000;
 | 
			
		||||
        public static final int fragment_main=0x7f030001;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class menu {
 | 
			
		||||
        public static final int main=0x7f090000;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class string {
 | 
			
		||||
        public static final int action_input_stick=0x7f060005;
 | 
			
		||||
        public static final int action_settings=0x7f060001;
 | 
			
		||||
        public static final int action_type_enter=0x7f060007;
 | 
			
		||||
        public static final int action_type_tab=0x7f060006;
 | 
			
		||||
        public static final int app_name=0x7f060000;
 | 
			
		||||
        /**  Strings related to Settings 
 | 
			
		||||
         */
 | 
			
		||||
        public static final int configure_plugin=0x7f060009;
 | 
			
		||||
        public static final int kp2aplugin_author=0x7f060004;
 | 
			
		||||
        public static final int kp2aplugin_shortdesc=0x7f060003;
 | 
			
		||||
        public static final int kp2aplugin_title=0x7f060002;
 | 
			
		||||
        public static final int layout_title=0x7f06000a;
 | 
			
		||||
        public static final int title_activity_settings=0x7f060008;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class style {
 | 
			
		||||
        /** 
 | 
			
		||||
        Base application theme, dependent on API level. This theme is replaced
 | 
			
		||||
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
            Theme customizations available in newer API levels can go in
 | 
			
		||||
            res/values-vXX/styles.xml, while customizations related to
 | 
			
		||||
            backward-compatibility can go here.
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        Base application theme for API 11+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from res/values/styles.xml on API 11+ devices.
 | 
			
		||||
    
 | 
			
		||||
 API 11 theme customizations can go here. 
 | 
			
		||||
 | 
			
		||||
        Base application theme for API 14+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from BOTH res/values/styles.xml and
 | 
			
		||||
        res/values-v11/styles.xml on API 14+ devices.
 | 
			
		||||
    
 | 
			
		||||
 API 14 theme customizations can go here. 
 | 
			
		||||
 | 
			
		||||
        Base application theme, dependent on API level. This theme is replaced
 | 
			
		||||
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
            Theme customizations available in newer API levels can go in
 | 
			
		||||
            res/values-vXX/styles.xml, while customizations related to
 | 
			
		||||
            backward-compatibility can go here.
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        Base application theme for API 11+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from res/values/styles.xml on API 11+ devices.
 | 
			
		||||
    
 | 
			
		||||
 API 11 theme customizations can go here. 
 | 
			
		||||
 | 
			
		||||
        Base application theme for API 14+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from BOTH res/values/styles.xml and
 | 
			
		||||
        res/values-v11/styles.xml on API 14+ devices.
 | 
			
		||||
    
 | 
			
		||||
 API 14 theme customizations can go here. 
 | 
			
		||||
 | 
			
		||||
        Base application theme, dependent on API level. This theme is replaced
 | 
			
		||||
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
            Theme customizations available in newer API levels can go in
 | 
			
		||||
            res/values-vXX/styles.xml, while customizations related to
 | 
			
		||||
            backward-compatibility can go here.
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        Base application theme for API 11+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from res/values/styles.xml on API 11+ devices.
 | 
			
		||||
    
 | 
			
		||||
 API 11 theme customizations can go here. 
 | 
			
		||||
 | 
			
		||||
        Base application theme for API 14+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from BOTH res/values/styles.xml and
 | 
			
		||||
        res/values-v11/styles.xml on API 14+ devices.
 | 
			
		||||
    
 | 
			
		||||
 API 14 theme customizations can go here. 
 | 
			
		||||
         */
 | 
			
		||||
        public static final int AppBaseTheme=0x7f070000;
 | 
			
		||||
        /**  Application theme. 
 | 
			
		||||
 All customizations that are NOT specific to a particular API-level can go here. 
 | 
			
		||||
 Application theme. 
 | 
			
		||||
 All customizations that are NOT specific to a particular API-level can go here. 
 | 
			
		||||
 Application theme. 
 | 
			
		||||
 All customizations that are NOT specific to a particular API-level can go here. 
 | 
			
		||||
         */
 | 
			
		||||
        public static final int AppTheme=0x7f070001;
 | 
			
		||||
    }
 | 
			
		||||
    public static final class xml {
 | 
			
		||||
        public static final int pref_general=0x7f040000;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 | 
			
		||||
 *
 | 
			
		||||
 * This class was automatically generated by the
 | 
			
		||||
 * aapt tool from the resource data it found.  It
 | 
			
		||||
 * should not be modified by hand.
 | 
			
		||||
 */
 | 
			
		||||
package keepass2android.pluginsdk;
 | 
			
		||||
 | 
			
		||||
public final class R {
 | 
			
		||||
	public static final class dimen {
 | 
			
		||||
		public static final int activity_horizontal_margin = 0x7f050000;
 | 
			
		||||
		public static final int activity_vertical_margin = 0x7f050001;
 | 
			
		||||
	}
 | 
			
		||||
	public static final class drawable {
 | 
			
		||||
		public static final int ic_launcher = 0x7f020000;
 | 
			
		||||
	}
 | 
			
		||||
	public static final class string {
 | 
			
		||||
		public static final int app_name = 0x7f060000;
 | 
			
		||||
	}
 | 
			
		||||
	public static final class style {
 | 
			
		||||
		public static final int AppBaseTheme = 0x7f070000;
 | 
			
		||||
		public static final int AppTheme = 0x7f070001;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/java/PluginInputStick/ic_launcher-web.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 17 KiB  | 
							
								
								
									
										20
									
								
								src/java/PluginInputStick/proguard-project.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,20 @@
 | 
			
		||||
# To enable ProGuard in your project, edit project.properties
 | 
			
		||||
# to define the proguard.config property as described in that file.
 | 
			
		||||
#
 | 
			
		||||
# Add project specific ProGuard rules here.
 | 
			
		||||
# By default, the flags in this file are appended to flags specified
 | 
			
		||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
 | 
			
		||||
# You can edit the include path and order by changing the ProGuard
 | 
			
		||||
# include property in project.properties.
 | 
			
		||||
#
 | 
			
		||||
# For more details, see
 | 
			
		||||
#   http://developer.android.com/guide/developing/tools/proguard.html
 | 
			
		||||
 | 
			
		||||
# Add any project specific keep options here:
 | 
			
		||||
 | 
			
		||||
# If your project uses WebView with JS, uncomment the following
 | 
			
		||||
# and specify the fully qualified class name to the JavaScript interface
 | 
			
		||||
# class:
 | 
			
		||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
 | 
			
		||||
#   public *;
 | 
			
		||||
#}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/java/PluginInputStick/project.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,16 @@
 | 
			
		||||
# This file is automatically generated by Android Tools.
 | 
			
		||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
 | 
			
		||||
#
 | 
			
		||||
# This file must be checked in Version Control Systems.
 | 
			
		||||
#
 | 
			
		||||
# To customize properties used by the Ant build system edit
 | 
			
		||||
# "ant.properties", and override values to adapt the script to your
 | 
			
		||||
# project structure.
 | 
			
		||||
#
 | 
			
		||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
 | 
			
		||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
 | 
			
		||||
 | 
			
		||||
# Project target.
 | 
			
		||||
target=android-19
 | 
			
		||||
android.library.reference.1=../InputStickAPI
 | 
			
		||||
android.library.reference.2=../Keepass2AndroidPluginSDK
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/java/PluginInputStick/res/drawable-hdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/java/PluginInputStick/res/drawable-hdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 839 B  | 
							
								
								
									
										
											BIN
										
									
								
								src/java/PluginInputStick/res/drawable-mdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/java/PluginInputStick/res/drawable-mdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 548 B  | 
							
								
								
									
										
											BIN
										
									
								
								src/java/PluginInputStick/res/drawable-xhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/java/PluginInputStick/res/drawable-xhdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1016 B  | 
							
								
								
									
										
											BIN
										
									
								
								src/java/PluginInputStick/res/drawable-xxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.8 KiB  | 
| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										12
									
								
								src/java/PluginInputStick/res/layout/activity_main.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,12 @@
 | 
			
		||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:id="@+id/container"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context="keepass2android.plugin.inputstick.MainActivity"
 | 
			
		||||
    tools:ignore="MergeRootFrame" >
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
</FrameLayout>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										29
									
								
								src/java/PluginInputStick/res/layout/fragment_main.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,29 @@
 | 
			
		||||
<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"
 | 
			
		||||
    android:paddingBottom="@dimen/activity_vertical_margin"
 | 
			
		||||
    android:paddingLeft="@dimen/activity_horizontal_margin"
 | 
			
		||||
    android:paddingRight="@dimen/activity_horizontal_margin"
 | 
			
		||||
    android:paddingTop="@dimen/activity_vertical_margin"
 | 
			
		||||
    tools:context="keepass2android.plugin.inputstick.MainActivity$PlaceholderFragment" >
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:orientation="vertical" >
 | 
			
		||||
        <Button
 | 
			
		||||
        android:id="@+id/button1"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:text="Button 1" />
 | 
			
		||||
 | 
			
		||||
    <Button
 | 
			
		||||
        android:id="@+id/button2"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:text="Button 2" />
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
</RelativeLayout>
 | 
			
		||||
							
								
								
									
										11
									
								
								src/java/PluginInputStick/res/menu/main.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,11 @@
 | 
			
		||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    tools:context="keepass2android.plugin.inputstick.MainActivity" >
 | 
			
		||||
 | 
			
		||||
    <item
 | 
			
		||||
        android:id="@+id/action_settings"
 | 
			
		||||
        android:orderInCategory="100"
 | 
			
		||||
        android:showAsAction="never"
 | 
			
		||||
        android:title="@string/action_settings"/>
 | 
			
		||||
 | 
			
		||||
</menu>
 | 
			
		||||
							
								
								
									
										11
									
								
								src/java/PluginInputStick/res/values-v11/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,11 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
        Base application theme for API 11+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from res/values/styles.xml on API 11+ devices.
 | 
			
		||||
    -->
 | 
			
		||||
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
 | 
			
		||||
        <!-- API 11 theme customizations can go here. -->
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										12
									
								
								src/java/PluginInputStick/res/values-v14/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,12 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
        Base application theme for API 14+. This theme completely replaces
 | 
			
		||||
        AppBaseTheme from BOTH res/values/styles.xml and
 | 
			
		||||
        res/values-v11/styles.xml on API 14+ devices.
 | 
			
		||||
    -->
 | 
			
		||||
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
 | 
			
		||||
        <!-- API 14 theme customizations can go here. -->
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										10
									
								
								src/java/PluginInputStick/res/values-w820dp/dimens.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,10 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
         Example customization of dimensions originally defined in res/values/dimens.xml
 | 
			
		||||
         (such as screen margins) for screens with more than 820dp of available width. This
 | 
			
		||||
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
 | 
			
		||||
    -->
 | 
			
		||||
    <dimen name="activity_horizontal_margin">64dp</dimen>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										7
									
								
								src/java/PluginInputStick/res/values/dimens.xml
									
									
									
									
									
										Normal 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>
 | 
			
		||||
							
								
								
									
										16
									
								
								src/java/PluginInputStick/res/values/strings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,16 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <string name="app_name">InputStick Plugin for KP2A</string>
 | 
			
		||||
    
 | 
			
		||||
    <string name="action_settings">Settings</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_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="action_type_enter">Type Enter with InputStick</string>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <string name="title_activity_settings">KP2A InputStick Settings</string>
 | 
			
		||||
 | 
			
		||||
    <!-- Strings related to Settings -->
 | 
			
		||||
    <string name="configure_plugin">Configure as plugin</string>
 | 
			
		||||
 | 
			
		||||
    <string name="layout_title">Host keyboard layout</string>
 | 
			
		||||
    
 | 
			
		||||
    <string-array name="layout_names">
 | 
			
		||||
        <item>English (United States) - en-US</item>
 | 
			
		||||
        <item>German - de-DE</item>
 | 
			
		||||
        <item>Polish - pl-PL</item>
 | 
			
		||||
        <item>Russian - ru-RU</item>
 | 
			
		||||
    </string-array>
 | 
			
		||||
    
 | 
			
		||||
    <string-array name="layout_values">
 | 
			
		||||
        <item>en-US</item>
 | 
			
		||||
        <item>de-DE</item>
 | 
			
		||||
        <item>pl-PL</item>
 | 
			
		||||
        <item>ru-RU</item>
 | 
			
		||||
    </string-array>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										20
									
								
								src/java/PluginInputStick/res/values/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,20 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
        Base application theme, dependent on API level. This theme is replaced
 | 
			
		||||
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 | 
			
		||||
    -->
 | 
			
		||||
    <style name="AppBaseTheme" parent="android:Theme.Light">
 | 
			
		||||
        <!--
 | 
			
		||||
            Theme customizations available in newer API levels can go in
 | 
			
		||||
            res/values-vXX/styles.xml, while customizations related to
 | 
			
		||||
            backward-compatibility can go here.
 | 
			
		||||
        -->
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
    <!-- Application theme. -->
 | 
			
		||||
    <style name="AppTheme" parent="AppBaseTheme">
 | 
			
		||||
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										24
									
								
								src/java/PluginInputStick/res/xml/pref_general.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,24 @@
 | 
			
		||||
<PreferenceScreen
 | 
			
		||||
    android:key="general_pref"
 | 
			
		||||
     xmlns:android="http://schemas.android.com/apk/res/android" >
 | 
			
		||||
 | 
			
		||||
    <Preference
 | 
			
		||||
        android:key="enable_plugin_pref"
 | 
			
		||||
        android:title="@string/configure_plugin" />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
         NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to
 | 
			
		||||
         dismiss it.
 | 
			
		||||
    -->
 | 
			
		||||
    <!-- NOTE: ListPreference's summary should be set to its value by the activity code. -->
 | 
			
		||||
    <ListPreference
 | 
			
		||||
        android:defaultValue="en-US"
 | 
			
		||||
        android:entries="@array/layout_names"
 | 
			
		||||
        android:entryValues="@array/layout_values"
 | 
			
		||||
        android:key="kbd_layout"
 | 
			
		||||
        android:negativeButtonText="@null"
 | 
			
		||||
        android:positiveButtonText="@null"
 | 
			
		||||
        android:title="@string/layout_title" />
 | 
			
		||||
 | 
			
		||||
</PreferenceScreen>
 | 
			
		||||