Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/clukeyboard.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/com/clusterrr/hardwarekeyboard')
-rw-r--r--app/src/main/java/com/clusterrr/hardwarekeyboard/KeyMapping.kt12
-rw-r--r--app/src/main/java/com/clusterrr/hardwarekeyboard/Keyboard.kt385
-rw-r--r--app/src/main/java/com/clusterrr/hardwarekeyboard/RusMapping.kt469
-rw-r--r--app/src/main/java/com/clusterrr/hardwarekeyboard/ScanCodes.kt196
4 files changed, 1062 insertions, 0 deletions
diff --git a/app/src/main/java/com/clusterrr/hardwarekeyboard/KeyMapping.kt b/app/src/main/java/com/clusterrr/hardwarekeyboard/KeyMapping.kt
new file mode 100644
index 0000000..2007d84
--- /dev/null
+++ b/app/src/main/java/com/clusterrr/hardwarekeyboard/KeyMapping.kt
@@ -0,0 +1,12 @@
+package com.clusterrr.hardwarekeyboard
+
+open class KeyMapping {
+ var ReplaceKeyCode: Int = 0
+ var ReplaceScanCode: Int = 0
+ var AlternateKeyCode: Int = 0
+ var AlternateScanCode: Int = 0
+ var AlternateFix: Boolean = false
+ var Char: String? = null
+ var ShiftChar: String? = null
+ var IgnoreCapsLock: Boolean = false
+}
diff --git a/app/src/main/java/com/clusterrr/hardwarekeyboard/Keyboard.kt b/app/src/main/java/com/clusterrr/hardwarekeyboard/Keyboard.kt
new file mode 100644
index 0000000..2314440
--- /dev/null
+++ b/app/src/main/java/com/clusterrr/hardwarekeyboard/Keyboard.kt
@@ -0,0 +1,385 @@
+package com.clusterrr.hardwarekeyboard
+
+import android.inputmethodservice.InputMethodService
+import android.util.Log
+import android.view.KeyEvent
+import android.view.View
+import android.widget.CompoundButton
+import android.widget.Switch
+import android.widget.TextView
+import android.widget.Toast
+import java.util.ArrayList
+import android.provider.Settings
+import java.lang.Exception
+
+class Keyboard : InputMethodService(), View.OnClickListener, CompoundButton.OnCheckedChangeListener {
+ private val FN_KEY = ScanCodes.SCANCODE_SHOW_KEYBOARD
+ private val LANGUAGE_KEYS = arrayOf(
+ intArrayOf(ScanCodes.SCANCODE_LANGUAGE),
+ intArrayOf(ScanCodes.SCANCODE_SHIFT_LEFT, ScanCodes.SCANCODE_CTRL_LEFT)
+ )
+ private val FN_FIX_KEYS = arrayOf(
+ intArrayOf(ScanCodes.SCANCODE_SHOW_KEYBOARD, ScanCodes.SCANCODE_SPACE)
+ )
+ private val SHOW_HIDE_KEYS = arrayOf(intArrayOf(ScanCodes.SCANCODE_SHOW_KEYBOARD, ScanCodes.SCANCODE_TAB))
+ private val BRIGHTNESS_DOWN_KEYS = arrayOf(intArrayOf(ScanCodes.SCANCODE_SHOW_KEYBOARD, ScanCodes.SCANCODE_J))
+ private val BRIGHTNESS_UP_KEYS = arrayOf(intArrayOf(ScanCodes.SCANCODE_SHOW_KEYBOARD, ScanCodes.SCANCODE_K))
+ private val SCANCODE_ONLY_APPS = arrayOf("com.microsoft.rdc.android")
+
+ private var altLanguage = false
+ private var fnLock = false
+ private val keysPressed = ArrayList<Int>()
+ private var capsLock = false
+
+ internal var textViewLanguage: TextView? = null
+ internal var switchCapsLock: Switch? = null
+ internal var switchFnLock: Switch? = null
+
+ override fun onEvaluateFullscreenMode(): Boolean {
+ return false
+ }
+
+ override fun onCreateInputView(): View {
+ val inputView = layoutInflater.inflate(R.layout.keyboard_layout, null)
+ textViewLanguage = inputView.findViewById(R.id.textViewLanguage)
+ switchCapsLock = inputView.findViewById(R.id.switchCapsLock)
+ switchFnLock = inputView.findViewById(R.id.switchFnLock)
+ textViewLanguage!!.setOnClickListener(this)
+ switchCapsLock!!.setOnCheckedChangeListener(this)
+ switchFnLock!!.setOnCheckedChangeListener(this)
+ updateLangage()
+ updateFnFixSwitch()
+ updateCapsLockSwitch()
+ return inputView
+ }
+
+ private fun updateLangage(): String {
+ var languageName: String? = null
+ if (!altLanguage)
+ languageName = "EN"
+ else
+ languageName = "RU"
+ if (textViewLanguage != null)
+ textViewLanguage!!.text = languageName
+ return languageName
+ }
+
+ fun toggleLanguage() {
+ altLanguage = !altLanguage
+ val languageName = updateLangage()
+ Toast.makeText(this, languageName, Toast.LENGTH_SHORT).show()
+ }
+
+ private fun updateFnFixSwitch() {
+ if (switchFnLock == null)
+ return
+ if (switchFnLock!!.isChecked != fnLock) {
+ switchFnLock!!.setOnCheckedChangeListener(null)
+ switchFnLock!!.isChecked = fnLock
+ switchFnLock!!.setOnCheckedChangeListener(this)
+ }
+ }
+
+ fun toggleFnLock() {
+ if (!fnLock) {
+ fnLock = true
+ Toast.makeText(this, "FN lock: on", Toast.LENGTH_SHORT).show()
+ } else {
+ fnLock = false
+ Toast.makeText(this, "FN lock: off", Toast.LENGTH_SHORT).show()
+ }
+ updateFnFixSwitch()
+ }
+
+ private fun updateCapsLockSwitch() {
+ if (switchCapsLock == null)
+ return
+ if (switchCapsLock!!.isChecked != capsLock)
+ switchCapsLock!!.isChecked = capsLock
+ }
+
+ private fun shouldUseScanCodes(): Boolean {
+ val packageName = currentInputEditorInfo.packageName
+ return packageName in SCANCODE_ONLY_APPS
+ }
+
+ override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
+ Log.d("keyboard", " down key_code=" + event.keyCode
+ + ", scan_code=" + event.scanCode
+ + ", device_code=" + event.deviceId
+ + ", repeat=" + event.repeatCount
+ + ", shift=" + event.isShiftPressed
+ + ", ctrl=" + event.isCtrlPressed
+ + ", alt=" + event.isAltPressed
+ )
+
+ val scanCode = event.scanCode
+
+ // Hide keyboard on back
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ updateInputViewShown()
+ val current = isInputViewShown
+ if (current) {
+ requestHideSelf(0)
+ return true
+ }
+ }
+
+ if (scanCode <= 0 || event.deviceId <= 0)
+ return false
+
+ // Handle caps lock to show current status
+ if (scanCode == ScanCodes.SCANCODE_CAPS_LOCK) {
+ if (!keysPressed.contains(ScanCodes.SCANCODE_CAPS_LOCK)) {
+ capsLock = !event.isCapsLockOn
+ if (capsLock)
+ Toast.makeText(this, "Сaps Lock: ON", Toast.LENGTH_SHORT).show()
+ else
+ Toast.makeText(this, "Caps Lock: off", Toast.LENGTH_SHORT).show()
+ }
+ } else {
+ capsLock = event.isCapsLockOn
+ }
+ updateCapsLockSwitch()
+
+ // Toggle language
+ if (!shouldUseScanCodes() && checkCombinations(LANGUAGE_KEYS, scanCode)) {
+ keysPressed.add(scanCode) // do not repeat
+ toggleLanguage()
+ return true
+ }
+
+ // Toggle FN fix
+ if (checkCombinations(FN_FIX_KEYS, scanCode)) {
+ keysPressed.add(scanCode) // do not repeat
+ toggleFnLock()
+ return true
+ }
+
+ // Toggle GUI
+ if (checkCombinations(SHOW_HIDE_KEYS, scanCode)) {
+ keysPressed.add(scanCode) // do not repeat
+ toggleVisibility()
+ return true
+ }
+
+ if (checkCombinations(BRIGHTNESS_DOWN_KEYS, scanCode)) {
+ adjustBrightness(-5)
+ return true
+ }
+
+ if (checkCombinations(BRIGHTNESS_UP_KEYS, scanCode)) {
+ adjustBrightness(5)
+ return true
+ }
+
+ if (!keysPressed.contains(scanCode)) {
+ keysPressed.add(scanCode)
+ }
+
+ if (scanCode == FN_KEY) {
+ return true
+ }
+
+ // Get mapping for key
+ val key = mapping.getMapping(scanCode)
+ if (key != null) {
+
+ // Is the FN key hold?
+ if (keysPressed.contains(FN_KEY) xor (fnLock && key.AlternateFix)) {
+ // Does key has some FN-function?
+ if (key.AlternateScanCode != 0 || key.AlternateKeyCode != 0) {
+ sendKeyCode(event, key.AlternateKeyCode, key.AlternateScanCode)
+ return true
+ }
+ }
+
+ // Does the key have an alternative function?
+ if (key.ReplaceKeyCode != 0 || key.ReplaceScanCode != 0) {
+ sendKeyCode(event, key.ReplaceKeyCode, key.ReplaceScanCode)
+ return true
+ }
+
+ // Is it alternative language?
+ if (!shouldUseScanCodes() // Workaround for some apps: send scancode only
+ && altLanguage && !event.isAltPressed && !event.isCtrlPressed) {
+ val shift = event.isShiftPressed xor (event.isCapsLockOn && !key.IgnoreCapsLock)
+ var text: String? = null
+ if (!shift)
+ text = key.Char
+ else
+ text = key.ShiftChar
+ // Send keypresses as text
+ if (text != null) {
+ sendText(text)
+ return true
+ }
+ }
+
+ // Do not alter key function
+ }
+
+ // Workaround for some apps: send scancode only
+ if (shouldUseScanCodes()) {
+ sendScanCode(event)
+ return true
+ }
+
+ // Passthru this key without overrides
+ return false
+ }
+
+ override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
+ Log.d("keyboard", " up key_code=" + event.keyCode
+ + ", scan_code=" + event.scanCode
+ + ", device_code=" + event.deviceId
+ + ", repeat=" + event.repeatCount
+ + ", shift=" + event.isShiftPressed
+ + ", ctrl=" + event.isCtrlPressed
+ + ", alt=" + event.isAltPressed
+ )
+
+ val scanCode = event.scanCode
+
+ if (scanCode <= 0 || event.deviceId <= 0)
+ return false
+
+ if (keysPressed.contains(scanCode))
+ keysPressed.remove(scanCode)
+
+ if (scanCode == FN_KEY) {
+ return true
+ }
+
+ val key = mapping.getMapping(scanCode)
+ if (key != null) {
+
+ if (keysPressed.contains(FN_KEY) || fnLock && key.AlternateFix) {
+ if (key.AlternateScanCode != 0 || key.AlternateKeyCode != 0) {
+ sendKeyCode(event, key.AlternateKeyCode, key.AlternateScanCode)
+ return true
+ }
+ }
+
+ if (key.ReplaceKeyCode != 0 || key.ReplaceScanCode != 0) {
+ sendKeyCode(event, key.ReplaceKeyCode, key.ReplaceScanCode)
+ return true
+ }
+
+ if (shouldUseScanCodes()) {
+ sendScanCode(event)
+ return true
+ }
+
+ if (altLanguage && !event.isAltPressed && !event.isCtrlPressed) {
+ val shift = event.isShiftPressed xor (event.isCapsLockOn && !key.IgnoreCapsLock)
+ var text: String? = null
+ if (!shift)
+ text = key.Char
+ else
+ text = key.ShiftChar
+ if (text != null) {
+ //sendText(text);
+ return true
+ }
+ }
+
+ }
+
+ if (shouldUseScanCodes()) {
+ sendScanCode(event)
+ return true
+ }
+
+ return false
+ }
+
+ private fun checkCombinations(combinations: Array<IntArray>, scanCode: Int): Boolean {
+ for (c in combinations.indices) {
+ val combination = combinations[c]
+ if (combination.size - 1 != keysPressed.size)
+ continue
+ var matched = true
+ for (k in combination.indices) {
+ if (!(scanCode != combination[k] && keysPressed.contains(combination[k]) || scanCode == combination[k] && !keysPressed.contains(combination[k]))) {
+ matched = false
+ break
+ }
+ }
+ if (matched) {
+ if (keysPressed.contains(scanCode))
+ keysPressed.add(scanCode)
+ return true
+ }
+ }
+ return false
+ }
+
+ private fun sendKeyCode(sourceEvent: KeyEvent, keyCode: Int, scanCode: Int) {
+ var keyCode = keyCode
+ val ic = currentInputConnection
+
+ if (shouldUseScanCodes() && scanCode != 0)
+ keyCode = 0
+ val event = KeyEvent(sourceEvent.downTime, sourceEvent.eventTime, sourceEvent.action,
+ keyCode, sourceEvent.repeatCount, sourceEvent.metaState,
+ sourceEvent.deviceId, scanCode,
+ 0,
+ sourceEvent.source)
+ ic.sendKeyEvent(event)
+ }
+
+ private fun sendScanCode(sourceEvent: KeyEvent) {
+ val ic = currentInputConnection
+ val event = KeyEvent(sourceEvent.downTime, sourceEvent.eventTime, sourceEvent.action,
+ 0, sourceEvent.repeatCount, sourceEvent.metaState,
+ sourceEvent.deviceId, sourceEvent.scanCode,
+ 0,
+ sourceEvent.source)
+ ic.sendKeyEvent(event)
+ }
+
+ private fun sendText(text: String) {
+ val ic = currentInputConnection
+ ic.commitText(text, 1)
+ }
+
+ override fun onClick(v: View) {
+ when (v.id) {
+ R.id.textViewLanguage -> toggleLanguage()
+ }
+ }
+
+ override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
+ when (buttonView.id) {
+ R.id.switchCapsLock -> updateCapsLockSwitch()
+ R.id.switchFnLock -> toggleFnLock()
+ }
+ }
+
+ fun toggleVisibility() {
+ updateInputViewShown()
+ val current = isInputViewShown
+ if (!current)
+ requestShowSelf(0)
+ else
+ requestHideSelf(0)
+ }
+
+ private fun adjustBrightness(delta: Int) {
+ try {
+ var brightness = Settings.System.getInt(getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS, 0)
+ brightness += delta
+ Settings.System.putInt(getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS, brightness);
+ }
+ catch (ex: Exception) {
+ ex.printStackTrace()
+ }
+ }
+
+ companion object {
+ private val mapping = RusMapping()
+ }
+}
diff --git a/app/src/main/java/com/clusterrr/hardwarekeyboard/RusMapping.kt b/app/src/main/java/com/clusterrr/hardwarekeyboard/RusMapping.kt
new file mode 100644
index 0000000..7038bbc
--- /dev/null
+++ b/app/src/main/java/com/clusterrr/hardwarekeyboard/RusMapping.kt
@@ -0,0 +1,469 @@
+package com.clusterrr.hardwarekeyboard
+
+import android.view.KeyEvent
+
+import java.util.HashMap
+
+class RusMapping {
+ internal var mapping: HashMap<Int, KeyMapping> = object : HashMap<Int, KeyMapping>() {
+ init {
+ put(ScanCodes.SCANCODE_GRAVE,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_ESCAPE
+ AlternateScanCode = ScanCodes.SCANCODE_ESCAPE
+ AlternateFix = true
+ Char = "ё"
+ ShiftChar = "Ё"
+ }
+ })
+ put(ScanCodes.SCANCODE_1,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F1
+ AlternateScanCode = ScanCodes.SCANCODE_F1
+ AlternateFix = true
+ }
+ })
+ put(ScanCodes.SCANCODE_2,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F2
+ AlternateScanCode = ScanCodes.SCANCODE_F2
+ AlternateFix = true
+ ShiftChar = "\""
+ IgnoreCapsLock = true
+ }
+ })
+ put(ScanCodes.SCANCODE_3,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F3
+ AlternateScanCode = ScanCodes.SCANCODE_F3
+ AlternateFix = true
+ ShiftChar = "№"
+ IgnoreCapsLock = true
+ }
+ })
+ put(ScanCodes.SCANCODE_4,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F4
+ AlternateScanCode = ScanCodes.SCANCODE_F4
+ AlternateFix = true
+ ShiftChar = ";"
+ IgnoreCapsLock = true
+ }
+ })
+ put(ScanCodes.SCANCODE_5,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F5
+ AlternateScanCode = ScanCodes.SCANCODE_F5
+ AlternateFix = true
+ }
+ })
+ put(ScanCodes.SCANCODE_6,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F6
+ AlternateScanCode = ScanCodes.SCANCODE_F6
+ AlternateFix = true
+ ShiftChar = ":"
+ IgnoreCapsLock = true
+ }
+ })
+ put(ScanCodes.SCANCODE_7,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F7
+ AlternateScanCode = ScanCodes.SCANCODE_F7
+ AlternateFix = true
+ ShiftChar = "?"
+ IgnoreCapsLock = true
+ }
+ })
+ put(ScanCodes.SCANCODE_8,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F8
+ AlternateScanCode = ScanCodes.SCANCODE_F8
+ AlternateFix = true
+ }
+ })
+ put(ScanCodes.SCANCODE_9,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F9
+ AlternateScanCode = ScanCodes.SCANCODE_F9
+ AlternateFix = true
+ }
+ })
+ put(ScanCodes.SCANCODE_0,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F10
+ AlternateScanCode = ScanCodes.SCANCODE_F10
+ AlternateFix = true
+ }
+ })
+ put(ScanCodes.SCANCODE_MINUS,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F11
+ AlternateScanCode = ScanCodes.SCANCODE_F11
+ AlternateFix = true
+ }
+ })
+ put(ScanCodes.SCANCODE_EQUALS,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_F12
+ AlternateScanCode = ScanCodes.SCANCODE_F12
+ AlternateFix = true
+ }
+ })
+ put(ScanCodes.SCANCODE_Q,
+ object : KeyMapping() {
+ init {
+ Char = "й"
+ ShiftChar = "Й"
+ AlternateKeyCode = KeyEvent.KEYCODE_BACK
+ }
+ })
+ put(ScanCodes.SCANCODE_W,
+ object : KeyMapping() {
+ init {
+ Char = "ц"
+ ShiftChar = "Ц"
+ }
+ })
+ put(ScanCodes.SCANCODE_E,
+ object : KeyMapping() {
+ init {
+ Char = "у"
+ ShiftChar = "У"
+ }
+ })
+ put(ScanCodes.SCANCODE_R,
+ object : KeyMapping() {
+ init {
+ Char = "к"
+ ShiftChar = "К"
+ }
+ })
+ put(ScanCodes.SCANCODE_T,
+ object : KeyMapping() {
+ init {
+ Char = "е"
+ ShiftChar = "Е"
+ }
+ })
+ put(ScanCodes.SCANCODE_Y,
+ object : KeyMapping() {
+ init {
+ Char = "н"
+ ShiftChar = "Н"
+ }
+ })
+ put(ScanCodes.SCANCODE_U,
+ object : KeyMapping() {
+ init {
+ Char = "г"
+ ShiftChar = "Г"
+ }
+ })
+ put(ScanCodes.SCANCODE_I,
+ object : KeyMapping() {
+ init {
+ Char = "ш"
+ ShiftChar = "Ш"
+ }
+ })
+ put(ScanCodes.SCANCODE_O,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_NUMPAD_SUBTRACT
+ AlternateScanCode = ScanCodes.SCANCODE_NUMPAD_SUBTRACT
+ AlternateFix = false
+ Char = "щ"
+ ShiftChar = "Щ"
+ }
+ })
+ put(ScanCodes.SCANCODE_P,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_NUMPAD_ADD
+ AlternateScanCode = ScanCodes.SCANCODE_NUMPAD_ADD
+ AlternateFix = false
+ Char = "з"
+ ShiftChar = "З"
+ }
+ })
+ put(ScanCodes.SCANCODE_LEFT_BRACKET,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_NUMPAD_DIVIDE
+ AlternateScanCode = ScanCodes.SCANCODE_NUMPAD_DIVIDE
+ AlternateFix = false
+ Char = "х"
+ ShiftChar = "Х"
+ }
+ })
+ put(ScanCodes.SCANCODE_RIGHT_BRACKET,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_NUMPAD_MULTIPLY
+ AlternateScanCode = ScanCodes.SCANCODE_NUMPAD_MULTIPLY
+ AlternateFix = false
+ Char = "ъ"
+ ShiftChar = "Ъ"
+ }
+ })
+ put(ScanCodes.SCANCODE_A,
+ object : KeyMapping() {
+ init {
+ Char = "ф"
+ ShiftChar = "Ф"
+ }
+ })
+ put(ScanCodes.SCANCODE_S,
+ object : KeyMapping() {
+ init {
+ Char = "ы"
+ ShiftChar = "Ы"
+ }
+ })
+ put(ScanCodes.SCANCODE_D,
+ object : KeyMapping() {
+ init {
+ Char = "в"
+ ShiftChar = "В"
+ }
+ })
+ put(ScanCodes.SCANCODE_F,
+ object : KeyMapping() {
+ init {
+ Char = "а"
+ ShiftChar = "А"
+ }
+ })
+ put(ScanCodes.SCANCODE_G,
+ object : KeyMapping() {
+ init {
+ Char = "п"
+ ShiftChar = "П"
+ }
+ })
+ put(ScanCodes.SCANCODE_H,
+ object : KeyMapping() {
+ init {
+ Char = "р"
+ ShiftChar = "Р"
+ }
+ })
+ put(ScanCodes.SCANCODE_J,
+ object : KeyMapping() {
+ init {
+ Char = "о"
+ ShiftChar = "О"
+ }
+ })
+ put(ScanCodes.SCANCODE_K,
+ object : KeyMapping() {
+ init {
+ Char = "л"
+ ShiftChar = "Л"
+ }
+ })
+ put(ScanCodes.SCANCODE_L,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_VOLUME_MUTE
+ //AlternateScanCode = ScanCodes.SCANCODE_VOLUME_MUTE;
+ AlternateFix = false
+ Char = "д"
+ ShiftChar = "Д"
+ }
+ })
+ put(ScanCodes.SCANCODE_SEMICOLON,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_VOLUME_DOWN
+ //AlternateScanCode = ScanCodes.SCANCODE_VOLUME_DOWN;
+ AlternateFix = false
+ Char = "ж"
+ ShiftChar = "Ж"
+ }
+ })
+ put(ScanCodes.SCANCODE_APOSTROPHE,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_VOLUME_UP
+ //AlternateScanCode = ScanCodes.SCANCODE_VOLUME_UP;
+ AlternateFix = false
+ Char = "э"
+ ShiftChar = "Э"
+ }
+ })
+ put(ScanCodes.SCANCODE_Z,
+ object : KeyMapping() {
+ init {
+ Char = "я"
+ ShiftChar = "Я"
+ }
+ })
+ put(ScanCodes.SCANCODE_X,
+ object : KeyMapping() {
+ init {
+ Char = "ч"
+ ShiftChar = "Ч"
+ }
+ })
+ put(ScanCodes.SCANCODE_C,
+ object : KeyMapping() {
+ init {
+ Char = "с"
+ ShiftChar = "С"
+ }
+ })
+ put(ScanCodes.SCANCODE_V,
+ object : KeyMapping() {
+ init {
+ Char = "м"
+ ShiftChar = "М"
+ }
+ })
+ put(ScanCodes.SCANCODE_B,
+ object : KeyMapping() {
+ init {
+ Char = "и"
+ ShiftChar = "И"
+ }
+ })
+ put(ScanCodes.SCANCODE_N,
+ object : KeyMapping() {
+ init {
+ Char = "т"
+ ShiftChar = "Т"
+ }
+ })
+ put(ScanCodes.SCANCODE_M,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_MEDIA_REWIND
+ //AlternateScanCode = ScanCodes.SCANCODE_MEDIA_REWIND;
+ AlternateFix = false
+ Char = "ь"
+ ShiftChar = "Ь"
+ }
+ })
+ put(ScanCodes.SCANCODE_COMMA,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_MEDIA_FAST_FORWARD
+ //AlternateScanCode = ScanCodes.SCANCODE_MEDIA_FAST_FORWARD;
+ AlternateFix = false
+ Char = "б"
+ ShiftChar = "Б"
+ }
+ })
+ put(ScanCodes.SCANCODE_PERIOD,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS
+ //AlternateScanCode = ScanCodes.SCANCODE_MEDIA_PREVIOUS;
+ AlternateFix = false
+ Char = "ю"
+ ShiftChar = "Ю"
+ }
+ })
+ put(ScanCodes.SCANCODE_BACKSLASH,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_INSERT
+ ShiftChar = "/"
+ IgnoreCapsLock = true
+ }
+ })
+ put(ScanCodes.SCANCODE_BACKSLASH_LEFT,
+ object : KeyMapping() {
+ init {
+ ShiftChar = "/"
+ IgnoreCapsLock = true
+ }
+ })
+ put(ScanCodes.SCANCODE_SLASH,
+ object : KeyMapping() {
+ init {
+ Char = "."
+ ShiftChar = ","
+ IgnoreCapsLock = true
+ AlternateKeyCode = KeyEvent.KEYCODE_MEDIA_NEXT
+ //AlternateScanCode = ScanCodes.SCANCODE_MEDIA_NEXT;
+ AlternateFix = false
+ }
+ })
+ put(ScanCodes.SCANCODE_SHIFT_RIGHT,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
+ //AlternateScanCode = ScanCodes.SCANCODE_MEDIA_PLAY_PAUSE;
+ AlternateFix = false
+ }
+ })
+ put(ScanCodes.SCANCODE_DPAD_LEFT,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_MOVE_HOME
+ AlternateScanCode = ScanCodes.SCANCODE_MOVE_HOME
+ AlternateFix = false
+ }
+ })
+ put(ScanCodes.SCANCODE_DPAD_RIGHT,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_MOVE_END
+ AlternateScanCode = ScanCodes.SCANCODE_MOVE_END
+ AlternateFix = false
+ }
+ })
+ put(ScanCodes.SCANCODE_DPAD_UP,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_PAGE_UP
+ AlternateScanCode = ScanCodes.SCANCODE_PAGE_UP
+ AlternateFix = false
+ }
+ })
+ put(ScanCodes.SCANCODE_DPAD_DOWN,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_PAGE_DOWN
+ AlternateScanCode = ScanCodes.SCANCODE_PAGE_DOWN
+ AlternateFix = false
+ }
+ })
+ put(ScanCodes.SCANCODE_DEL,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_FORWARD_DEL
+ AlternateScanCode = ScanCodes.SCANCODE_FORWARD_DEL
+ AlternateFix = false
+ }
+ })
+ put(ScanCodes.SCANCODE_ALT_RIGHT,
+ object : KeyMapping() {
+ init {
+ AlternateKeyCode = KeyEvent.KEYCODE_MENU
+ AlternateScanCode = ScanCodes.SCANCODE_MENU
+ AlternateFix = false
+ }
+ })
+ }
+ }
+
+ fun getMapping(scanCode: Int): KeyMapping? {
+ return if (mapping.containsKey(scanCode)) mapping[scanCode] else null
+ }
+}
diff --git a/app/src/main/java/com/clusterrr/hardwarekeyboard/ScanCodes.kt b/app/src/main/java/com/clusterrr/hardwarekeyboard/ScanCodes.kt
new file mode 100644
index 0000000..f6f8e65
--- /dev/null
+++ b/app/src/main/java/com/clusterrr/hardwarekeyboard/ScanCodes.kt
@@ -0,0 +1,196 @@
+package com.clusterrr.hardwarekeyboard
+
+object ScanCodes {
+ val SCANCODE_VOLUME_MUTE = 113
+ val SCANCODE_VOLUME_DOWN = 114
+ val SCANCODE_VOLUME_UP = 115
+ val SCANCODE_MEDIA_NEXT = 163
+ val SCANCODE_MEDIA_PLAY_PAUSE = 164
+ val SCANCODE_MEDIA_PREVIOUS = 165
+ val SCANCODE_SEARCH = 217
+ val SCANCODE_DPAD_LEFT = 105
+ val SCANCODE_DPAD_RIGHT = 106
+ val SCANCODE_DPAD_UP = 103
+ val SCANCODE_DPAD_DOWN = 108
+
+ val SCANCODE_ESCAPE = 1
+ val SCANCODE_F1 = 59
+ val SCANCODE_F2 = 60
+ val SCANCODE_F3 = 61
+ val SCANCODE_F4 = 62
+ val SCANCODE_F5 = 63
+ val SCANCODE_F6 = 64
+ val SCANCODE_F7 = 65
+ val SCANCODE_F8 = 66
+ val SCANCODE_F9 = 67
+ val SCANCODE_F10 = 68
+ val SCANCODE_F11 = 87
+ val SCANCODE_F12 = 88
+ val SCANCODE_FORWARD_DEL = 111
+
+ val SCANCODE_GRAVE = 41
+ val SCANCODE_1 = 2
+ val SCANCODE_2 = 3
+ val SCANCODE_3 = 4
+ val SCANCODE_4 = 5
+ val SCANCODE_5 = 6
+ val SCANCODE_6 = 7
+ val SCANCODE_7 = 8
+ val SCANCODE_8 = 9
+ val SCANCODE_9 = 10
+ val SCANCODE_0 = 11
+ val SCANCODE_DEL = 14
+
+ val SCANCODE_TAB = 15
+ val SCANCODE_Q = 16
+ val SCANCODE_W = 17
+ val SCANCODE_E = 18
+ val SCANCODE_R = 19
+ val SCANCODE_T = 20
+ val SCANCODE_Y = 21
+ val SCANCODE_U = 22
+ val SCANCODE_I = 23
+ val SCANCODE_O = 24
+ val SCANCODE_P = 25
+ val SCANCODE_BACKSLASH = 43
+ val SCANCODE_BACKSLASH_LEFT = 86
+
+ val SCANCODE_CAPS_LOCK = 58
+ val SCANCODE_A = 30
+ val SCANCODE_S = 31
+ val SCANCODE_D = 32
+ val SCANCODE_F = 33
+ val SCANCODE_G = 34
+ val SCANCODE_H = 35
+ val SCANCODE_J = 36
+ val SCANCODE_K = 37
+ val SCANCODE_L = 38
+ val SCANCODE_ENTER = 28
+
+ val SCANCODE_SHIFT_LEFT = 42
+ val SCANCODE_Z = 44
+ val SCANCODE_X = 45
+ val SCANCODE_C = 46
+ val SCANCODE_V = 47
+ val SCANCODE_B = 48
+ val SCANCODE_N = 49
+ val SCANCODE_M = 50
+ val SCANCODE_COMMA = 51
+ val SCANCODE_PERIOD = 52
+ val SCANCODE_SEMICOLON = 39
+ val SCANCODE_APOSTROPHE = 40
+ val SCANCODE_SHIFT_RIGHT = 54
+
+ val SCANCODE_CTRL_LEFT = 29
+ val SCANCODE_SHOW_KEYBOARD = 706
+ val SCANCODE_ALT_LEFT = 56
+ val SCANCODE_SPACE = 57
+ val SCANCODE_LANGUAGE = 122
+ val SCANCODE_ALT_RIGHT = 100
+ val SCANCODE_MINUS = 12
+ val SCANCODE_EQUALS = 13
+ val SCANCODE_LEFT_BRACKET = 26
+ val SCANCODE_RIGHT_BRACKET = 27
+ val SCANCODE_SLASH = 53
+
+ val SCANCODE_PAGE_UP = 104
+ val SCANCODE_PAGE_DOWN = 109
+ val SCANCODE_MOVE_HOME = 102
+ val SCANCODE_MOVE_END = 107
+
+ /**
+ * Key code constant: System Request / Print Screen key.
+ */
+ val SCANCODE_SYSRQ = 84
+ /**
+ * Scan code constant: Scroll Lock key.
+ */
+ val SCANCODE_SCROLL_LOCK = 70
+ /**
+ * Key code constant: Break / Pause key.
+ */
+ val SCANCODE_BREAK = 119
+ /**
+ * Scan code constant: Num Lock key.
+ * This key alters the behavior of other keys on the numeric keypad.
+ */
+ val SCANCODE_NUM_LOCK = 69
+ /**
+ * Scan code constant: Numeric keypad '0' key.
+ */
+ val SCANCODE_NUMPAD_0 = 82
+ /**
+ * Scan code constant: Numeric keypad '1' key.
+ */
+ val SCANCODE_NUMPAD_1 = 79
+ /**
+ * Scan code constant: Numeric keypad '2' key.
+ */
+ val SCANCODE_NUMPAD_2 = 80
+ /**
+ * Scan code constant: Numeric keypad '3' key.
+ */
+ val SCANCODE_NUMPAD_3 = 81
+ /**
+ * Scan code constant: Numeric keypad '4' key.
+ */
+ val SCANCODE_NUMPAD_4 = 75
+ /**
+ * Scan code constant: Numeric keypad '5' key.
+ */
+ val SCANCODE_NUMPAD_5 = 76
+ /**
+ * Scan code constant: Numeric keypad '6' key.
+ */
+ val SCANCODE_NUMPAD_6 = 77
+ /**
+ * Scan code constant: Numeric keypad '7' key.
+ */
+ val SCANCODE_NUMPAD_7 = 71
+ /**
+ * Scan code constant: Numeric keypad '8' key.
+ */
+ val SCANCODE_NUMPAD_8 = 72
+ /**
+ * Scan code constant: Numeric keypad '9' key.
+ */
+ val SCANCODE_NUMPAD_9 = 73
+ /**
+ * Scan code constant: Numeric keypad '/' key (for division).
+ */
+ val SCANCODE_NUMPAD_DIVIDE = 98
+ /**
+ * Scan code constant: Numeric keypad '*' key (for multiplication).
+ */
+ val SCANCODE_NUMPAD_MULTIPLY = 55
+ /**
+ * Scan code constant: Numeric keypad '-' key (for subtraction).
+ */
+ val SCANCODE_NUMPAD_SUBTRACT = 74
+ /**
+ * Scan code constant: Numeric keypad '+' key (for addition).
+ */
+ val SCANCODE_NUMPAD_ADD = 78
+ /**
+ * Scan code constant: Numeric keypad '.' key (for decimals or digit grouping).
+ */
+ val SCANCODE_NUMPAD_DOT = 83
+ /**
+ * Scan code constant: Numeric keypad ',' key (for decimals or digit grouping).
+ */
+ val SCANCODE_NUMPAD_COMMA = 159
+ /**
+ * Scan code constant: Numeric keypad Enter key.
+ */
+ val SCANCODE_NUMPAD_ENTER = 96
+
+ /**
+ * Scan code constant: Menu key.
+ */
+ val SCANCODE_MENU = 127
+ /**
+ * Scan code constant: Calculator special function key.
+ * Used to launch a calculator application.
+ */
+ val SCANCODE_CALCULATOR = 140
+} \ No newline at end of file