From a583a355a1bd64cbae173822f34f19b9ace0a9eb Mon Sep 17 00:00:00 2001 From: Alexey 'Cluster' Avdyukhin Date: Wed, 11 Dec 2019 09:26:10 +0300 Subject: First commit --- .gitignore | 13 + app/.gitignore | 1 + app/build.gradle | 34 ++ app/proguard-rules.pro | 21 + app/src/main/AndroidManifest.xml | 29 ++ .../com/clusterrr/hardwarekeyboard/KeyMapping.kt | 12 + .../com/clusterrr/hardwarekeyboard/Keyboard.kt | 385 +++++++++++++++++ .../com/clusterrr/hardwarekeyboard/RusMapping.kt | 469 +++++++++++++++++++++ .../com/clusterrr/hardwarekeyboard/ScanCodes.kt | 196 +++++++++ .../res/drawable-v24/ic_launcher_foreground.xml | 34 ++ .../main/res/drawable/ic_launcher_background.xml | 170 ++++++++ app/src/main/res/layout/keyboard_layout.xml | 48 +++ app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../res/mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2963 bytes app/src/main/res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 4905 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2060 bytes app/src/main/res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2783 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4490 bytes .../main/res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 6895 bytes app/src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6387 bytes .../main/res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10413 bytes app/src/main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9128 bytes .../main/res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15132 bytes app/src/main/res/values/colors.xml | 9 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/styles.xml | 10 + app/src/main/res/xml/method.xml | 5 + build.gradle | 29 ++ gradle.properties | 15 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 ++++++++ gradlew.bat | 84 ++++ settings.gradle | 1 + 35 files changed, 1756 insertions(+) create mode 100644 .gitignore create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/clusterrr/hardwarekeyboard/KeyMapping.kt create mode 100644 app/src/main/java/com/clusterrr/hardwarekeyboard/Keyboard.kt create mode 100644 app/src/main/java/com/clusterrr/hardwarekeyboard/RusMapping.kt create mode 100644 app/src/main/java/com/clusterrr/hardwarekeyboard/ScanCodes.kt create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/layout/keyboard_layout.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/main/res/xml/method.xml create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e76c77c --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..3543521 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..8f7794b --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,34 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-android' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "com.clusterrr.hardwarekeyboard" + minSdkVersion 28 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} +repositories { + mavenCentral() +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..6e7ffa9 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# 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 *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..22ec5f7 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + \ No newline at end of file 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() + 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, 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 = object : HashMap() { + 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 diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..971add5 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..eed7a42 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/keyboard_layout.xml b/app/src/main/res/layout/keyboard_layout.xml new file mode 100644 index 0000000..8a11266 --- /dev/null +++ b/app/src/main/res/layout/keyboard_layout.xml @@ -0,0 +1,48 @@ + + + + + + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..a26f6fb --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..a26f6fb --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..898f3ed Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..dffca36 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..64ba76f Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..dae5e08 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..e5ed465 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..14ed0af Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..b0907ca Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..d8ae031 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..2c18de9 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..beed3cd Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..0145c7c --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,9 @@ + + + #408040 + #B0B0B0 + #0000FF + #008577 + #00574B + #D81B60 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..c5a811b --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Hardware Keyboard + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..7532894 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/app/src/main/res/xml/method.xml b/app/src/main/res/xml/method.xml new file mode 100644 index 0000000..55e7ab2 --- /dev/null +++ b/app/src/main/res/xml/method.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..036271b --- /dev/null +++ b/build.gradle @@ -0,0 +1,29 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + + } + dependencies { + classpath 'com.android.tools.build:gradle:3.5.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..9f85f38 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,15 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..7ae826d --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Aug 28 14:51:31 MSK 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..d3db109 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':app' -- cgit v1.2.3