summaryrefslogtreecommitdiffstats
path: root/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt
new file mode 100644
index 000000000..82a6712b6
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt
@@ -0,0 +1,121 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.yuzu.yuzu_emu.applets.keyboard
+
+import android.content.Context
+import android.os.Handler
+import android.os.Looper
+import android.view.KeyEvent
+import android.view.View
+import android.view.WindowInsets
+import android.view.inputmethod.InputMethodManager
+import androidx.annotation.Keep
+import androidx.core.view.ViewCompat
+import org.yuzu.yuzu_emu.NativeLibrary
+import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.applets.keyboard.ui.KeyboardDialogFragment
+import java.io.Serializable
+
+@Keep
+object SoftwareKeyboard {
+ lateinit var data: KeyboardData
+ val dataLock = Object()
+
+ private fun executeNormalImpl(config: KeyboardConfig) {
+ val emulationActivity = NativeLibrary.sEmulationActivity.get()
+ data = KeyboardData(SwkbdResult.Cancel.ordinal, "")
+ val fragment = KeyboardDialogFragment.newInstance(config)
+ fragment.show(emulationActivity!!.supportFragmentManager, KeyboardDialogFragment.TAG)
+ }
+
+ private fun executeInlineImpl(config: KeyboardConfig) {
+ val emulationActivity = NativeLibrary.sEmulationActivity.get()
+
+ val overlayView = emulationActivity!!.findViewById<View>(R.id.surface_input_overlay)
+ val im =
+ overlayView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ im.showSoftInput(overlayView, InputMethodManager.SHOW_FORCED)
+
+ // There isn't a good way to know that the IMM is dismissed, so poll every 500ms to submit inline keyboard result.
+ val handler = Handler(Looper.myLooper()!!)
+ val delayMs = 500
+ handler.postDelayed(object : Runnable {
+ override fun run() {
+ val insets = ViewCompat.getRootWindowInsets(overlayView)
+ val isKeyboardVisible = insets!!.isVisible(WindowInsets.Type.ime())
+ if (isKeyboardVisible) {
+ handler.postDelayed(this, delayMs.toLong())
+ return
+ }
+
+ // No longer visible, submit the result.
+ NativeLibrary.submitInlineKeyboardInput(KeyEvent.KEYCODE_ENTER)
+ }
+ }, delayMs.toLong())
+ }
+
+ @JvmStatic
+ fun executeNormal(config: KeyboardConfig): KeyboardData {
+ NativeLibrary.sEmulationActivity.get()!!.runOnUiThread { executeNormalImpl(config) }
+ synchronized(dataLock) {
+ dataLock.wait()
+ }
+ return data
+ }
+
+ @JvmStatic
+ fun executeInline(config: KeyboardConfig) {
+ NativeLibrary.sEmulationActivity.get()!!.runOnUiThread { executeInlineImpl(config) }
+ }
+
+ // Corresponds to Service::AM::Applets::SwkbdType
+ enum class SwkbdType {
+ Normal,
+ NumberPad,
+ Qwerty,
+ Unknown3,
+ Latin,
+ SimplifiedChinese,
+ TraditionalChinese,
+ Korean
+ }
+
+ // Corresponds to Service::AM::Applets::SwkbdPasswordMode
+ enum class SwkbdPasswordMode {
+ Disabled,
+ Enabled
+ }
+
+ // Corresponds to Service::AM::Applets::SwkbdResult
+ enum class SwkbdResult {
+ Ok,
+ Cancel
+ }
+
+ @Keep
+ data class KeyboardConfig(
+ var ok_text: String? = null,
+ var header_text: String? = null,
+ var sub_text: String? = null,
+ var guide_text: String? = null,
+ var initial_text: String? = null,
+ var left_optional_symbol_key: Short = 0,
+ var right_optional_symbol_key: Short = 0,
+ var max_text_length: Int = 0,
+ var min_text_length: Int = 0,
+ var initial_cursor_position: Int = 0,
+ var type: Int = 0,
+ var password_mode: Int = 0,
+ var text_draw_type: Int = 0,
+ var key_disable_flags: Int = 0,
+ var use_blur_background: Boolean = false,
+ var enable_backspace_button: Boolean = false,
+ var enable_return_button: Boolean = false,
+ var disable_cancel_button: Boolean = false
+ ) : Serializable
+
+ // Corresponds to Frontend::KeyboardData
+ @Keep
+ data class KeyboardData(var result: Int, var text: String)
+}