diff options
Diffstat (limited to 'src/android/app/src/main/jni')
-rw-r--r-- | src/android/app/src/main/jni/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/android/app/src/main/jni/android_common/android_common.cpp | 35 | ||||
-rw-r--r-- | src/android/app/src/main/jni/android_common/android_common.h | 12 | ||||
-rw-r--r-- | src/android/app/src/main/jni/applets/software_keyboard.cpp | 277 | ||||
-rw-r--r-- | src/android/app/src/main/jni/applets/software_keyboard.h | 78 | ||||
-rw-r--r-- | src/android/app/src/main/jni/id_cache.cpp | 7 | ||||
-rw-r--r-- | src/android/app/src/main/jni/native.cpp | 62 | ||||
-rw-r--r-- | src/android/app/src/main/jni/native.h | 6 |
8 files changed, 462 insertions, 19 deletions
diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt index 21c27d4ee..3cf36b7d1 100644 --- a/src/android/app/src/main/jni/CMakeLists.txt +++ b/src/android/app/src/main/jni/CMakeLists.txt @@ -1,4 +1,8 @@ add_library(yuzu-android SHARED + android_common/android_common.cpp + android_common/android_common.h + applets/software_keyboard.cpp + applets/software_keyboard.h config.cpp config.h default_ini.h diff --git a/src/android/app/src/main/jni/android_common/android_common.cpp b/src/android/app/src/main/jni/android_common/android_common.cpp new file mode 100644 index 000000000..52d8ecfeb --- /dev/null +++ b/src/android/app/src/main/jni/android_common/android_common.cpp @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "jni/android_common/android_common.h" + +#include <string> +#include <string_view> + +#include <jni.h> + +#include "common/string_util.h" + +std::string GetJString(JNIEnv* env, jstring jstr) { + if (!jstr) { + return {}; + } + + const jchar* jchars = env->GetStringChars(jstr, nullptr); + const jsize length = env->GetStringLength(jstr); + const std::u16string_view string_view(reinterpret_cast<const char16_t*>(jchars), length); + const std::string converted_string = Common::UTF16ToUTF8(string_view); + env->ReleaseStringChars(jstr, jchars); + + return converted_string; +} + +jstring ToJString(JNIEnv* env, std::string_view str) { + const std::u16string converted_string = Common::UTF8ToUTF16(str); + return env->NewString(reinterpret_cast<const jchar*>(converted_string.data()), + static_cast<jint>(converted_string.size())); +} + +jstring ToJString(JNIEnv* env, std::u16string_view str) { + return ToJString(env, Common::UTF16ToUTF8(str)); +} diff --git a/src/android/app/src/main/jni/android_common/android_common.h b/src/android/app/src/main/jni/android_common/android_common.h new file mode 100644 index 000000000..ccb0c06f7 --- /dev/null +++ b/src/android/app/src/main/jni/android_common/android_common.h @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <string> + +#include <jni.h> + +std::string GetJString(JNIEnv* env, jstring jstr); +jstring ToJString(JNIEnv* env, std::string_view str); +jstring ToJString(JNIEnv* env, std::u16string_view str); diff --git a/src/android/app/src/main/jni/applets/software_keyboard.cpp b/src/android/app/src/main/jni/applets/software_keyboard.cpp new file mode 100644 index 000000000..278137b4c --- /dev/null +++ b/src/android/app/src/main/jni/applets/software_keyboard.cpp @@ -0,0 +1,277 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <map> +#include <thread> + +#include <jni.h> + +#include "common/logging/log.h" +#include "common/string_util.h" +#include "core/core.h" +#include "jni/android_common/android_common.h" +#include "jni/applets/software_keyboard.h" +#include "jni/id_cache.h" + +static jclass s_software_keyboard_class; +static jclass s_keyboard_config_class; +static jclass s_keyboard_data_class; +static jmethodID s_swkbd_execute_normal; +static jmethodID s_swkbd_execute_inline; + +namespace SoftwareKeyboard { + +static jobject ToJKeyboardParams(const Core::Frontend::KeyboardInitializeParameters& config) { + JNIEnv* env = IDCache::GetEnvForThread(); + jobject object = env->AllocObject(s_keyboard_config_class); + + env->SetObjectField(object, + env->GetFieldID(s_keyboard_config_class, "ok_text", "Ljava/lang/String;"), + ToJString(env, config.ok_text)); + env->SetObjectField( + object, env->GetFieldID(s_keyboard_config_class, "header_text", "Ljava/lang/String;"), + ToJString(env, config.header_text)); + env->SetObjectField(object, + env->GetFieldID(s_keyboard_config_class, "sub_text", "Ljava/lang/String;"), + ToJString(env, config.sub_text)); + env->SetObjectField( + object, env->GetFieldID(s_keyboard_config_class, "guide_text", "Ljava/lang/String;"), + ToJString(env, config.guide_text)); + env->SetObjectField( + object, env->GetFieldID(s_keyboard_config_class, "initial_text", "Ljava/lang/String;"), + ToJString(env, config.initial_text)); + env->SetShortField(object, + env->GetFieldID(s_keyboard_config_class, "left_optional_symbol_key", "S"), + static_cast<jshort>(config.left_optional_symbol_key)); + env->SetShortField(object, + env->GetFieldID(s_keyboard_config_class, "right_optional_symbol_key", "S"), + static_cast<jshort>(config.right_optional_symbol_key)); + env->SetIntField(object, env->GetFieldID(s_keyboard_config_class, "max_text_length", "I"), + static_cast<jint>(config.max_text_length)); + env->SetIntField(object, env->GetFieldID(s_keyboard_config_class, "min_text_length", "I"), + static_cast<jint>(config.min_text_length)); + env->SetIntField(object, + env->GetFieldID(s_keyboard_config_class, "initial_cursor_position", "I"), + static_cast<jint>(config.initial_cursor_position)); + env->SetIntField(object, env->GetFieldID(s_keyboard_config_class, "type", "I"), + static_cast<jint>(config.type)); + env->SetIntField(object, env->GetFieldID(s_keyboard_config_class, "password_mode", "I"), + static_cast<jint>(config.password_mode)); + env->SetIntField(object, env->GetFieldID(s_keyboard_config_class, "text_draw_type", "I"), + static_cast<jint>(config.text_draw_type)); + env->SetIntField(object, env->GetFieldID(s_keyboard_config_class, "key_disable_flags", "I"), + static_cast<jint>(config.key_disable_flags.raw)); + env->SetBooleanField(object, + env->GetFieldID(s_keyboard_config_class, "use_blur_background", "Z"), + static_cast<jboolean>(config.use_blur_background)); + env->SetBooleanField(object, + env->GetFieldID(s_keyboard_config_class, "enable_backspace_button", "Z"), + static_cast<jboolean>(config.enable_backspace_button)); + env->SetBooleanField(object, + env->GetFieldID(s_keyboard_config_class, "enable_return_button", "Z"), + static_cast<jboolean>(config.enable_return_button)); + env->SetBooleanField(object, + env->GetFieldID(s_keyboard_config_class, "disable_cancel_button", "Z"), + static_cast<jboolean>(config.disable_cancel_button)); + + return object; +} + +AndroidKeyboard::ResultData AndroidKeyboard::ResultData::CreateFromFrontend(jobject object) { + JNIEnv* env = IDCache::GetEnvForThread(); + const jstring string = reinterpret_cast<jstring>(env->GetObjectField( + object, env->GetFieldID(s_keyboard_data_class, "text", "Ljava/lang/String;"))); + return ResultData{GetJString(env, string), + static_cast<Service::AM::Applets::SwkbdResult>(env->GetIntField( + object, env->GetFieldID(s_keyboard_data_class, "result", "I")))}; +} + +AndroidKeyboard::~AndroidKeyboard() = default; + +void AndroidKeyboard::InitializeKeyboard( + bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters, + SubmitNormalCallback submit_normal_callback_, SubmitInlineCallback submit_inline_callback_) { + if (is_inline) { + LOG_WARNING( + Frontend, + "(STUBBED) called, backend requested to initialize the inline software keyboard."); + + submit_inline_callback = std::move(submit_inline_callback_); + } else { + LOG_WARNING( + Frontend, + "(STUBBED) called, backend requested to initialize the normal software keyboard."); + + submit_normal_callback = std::move(submit_normal_callback_); + } + + parameters = std::move(initialize_parameters); + + LOG_INFO(Frontend, + "\nKeyboardInitializeParameters:" + "\nok_text={}" + "\nheader_text={}" + "\nsub_text={}" + "\nguide_text={}" + "\ninitial_text={}" + "\nmax_text_length={}" + "\nmin_text_length={}" + "\ninitial_cursor_position={}" + "\ntype={}" + "\npassword_mode={}" + "\ntext_draw_type={}" + "\nkey_disable_flags={}" + "\nuse_blur_background={}" + "\nenable_backspace_button={}" + "\nenable_return_button={}" + "\ndisable_cancel_button={}", + Common::UTF16ToUTF8(parameters.ok_text), Common::UTF16ToUTF8(parameters.header_text), + Common::UTF16ToUTF8(parameters.sub_text), Common::UTF16ToUTF8(parameters.guide_text), + Common::UTF16ToUTF8(parameters.initial_text), parameters.max_text_length, + parameters.min_text_length, parameters.initial_cursor_position, parameters.type, + parameters.password_mode, parameters.text_draw_type, parameters.key_disable_flags.raw, + parameters.use_blur_background, parameters.enable_backspace_button, + parameters.enable_return_button, parameters.disable_cancel_button); +} + +void AndroidKeyboard::ShowNormalKeyboard() const { + LOG_DEBUG(Frontend, "called, backend requested to show the normal software keyboard."); + + ResultData data{}; + + // Pivot to a new thread, as we cannot call GetEnvForThread() from a Fiber. + std::thread([&] { + data = ResultData::CreateFromFrontend(IDCache::GetEnvForThread()->CallStaticObjectMethod( + s_software_keyboard_class, s_swkbd_execute_normal, ToJKeyboardParams(parameters))); + }).join(); + + SubmitNormalText(data); +} + +void AndroidKeyboard::ShowTextCheckDialog( + Service::AM::Applets::SwkbdTextCheckResult text_check_result, + std::u16string text_check_message) const { + LOG_WARNING(Frontend, "(STUBBED) called, backend requested to show the text check dialog."); +} + +void AndroidKeyboard::ShowInlineKeyboard( + Core::Frontend::InlineAppearParameters appear_parameters) const { + LOG_WARNING(Frontend, + "(STUBBED) called, backend requested to show the inline software keyboard."); + + LOG_INFO(Frontend, + "\nInlineAppearParameters:" + "\nmax_text_length={}" + "\nmin_text_length={}" + "\nkey_top_scale_x={}" + "\nkey_top_scale_y={}" + "\nkey_top_translate_x={}" + "\nkey_top_translate_y={}" + "\ntype={}" + "\nkey_disable_flags={}" + "\nkey_top_as_floating={}" + "\nenable_backspace_button={}" + "\nenable_return_button={}" + "\ndisable_cancel_button={}", + appear_parameters.max_text_length, appear_parameters.min_text_length, + appear_parameters.key_top_scale_x, appear_parameters.key_top_scale_y, + appear_parameters.key_top_translate_x, appear_parameters.key_top_translate_y, + appear_parameters.type, appear_parameters.key_disable_flags.raw, + appear_parameters.key_top_as_floating, appear_parameters.enable_backspace_button, + appear_parameters.enable_return_button, appear_parameters.disable_cancel_button); + + // Pivot to a new thread, as we cannot call GetEnvForThread() from a Fiber. + m_is_inline_active = true; + std::thread([&] { + IDCache::GetEnvForThread()->CallStaticVoidMethod( + s_software_keyboard_class, s_swkbd_execute_inline, ToJKeyboardParams(parameters)); + }).join(); +} + +void AndroidKeyboard::HideInlineKeyboard() const { + LOG_WARNING(Frontend, + "(STUBBED) called, backend requested to hide the inline software keyboard."); +} + +void AndroidKeyboard::InlineTextChanged( + Core::Frontend::InlineTextParameters text_parameters) const { + LOG_WARNING(Frontend, + "(STUBBED) called, backend requested to change the inline keyboard text."); + + LOG_INFO(Frontend, + "\nInlineTextParameters:" + "\ninput_text={}" + "\ncursor_position={}", + Common::UTF16ToUTF8(text_parameters.input_text), text_parameters.cursor_position); + + submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString, + text_parameters.input_text, text_parameters.cursor_position); +} + +void AndroidKeyboard::ExitKeyboard() const { + LOG_WARNING(Frontend, "(STUBBED) called, backend requested to exit the software keyboard."); +} + +void AndroidKeyboard::SubmitInlineKeyboardText(std::u16string submitted_text) { + if (!m_is_inline_active) { + return; + } + + m_current_text += submitted_text; + + submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString, m_current_text, + m_current_text.size()); +} + +void AndroidKeyboard::SubmitInlineKeyboardInput(int key_code) { + static constexpr int KEYCODE_BACK = 4; + static constexpr int KEYCODE_ENTER = 66; + static constexpr int KEYCODE_DEL = 67; + + if (!m_is_inline_active) { + return; + } + + switch (key_code) { + case KEYCODE_BACK: + case KEYCODE_ENTER: + m_is_inline_active = false; + submit_inline_callback(Service::AM::Applets::SwkbdReplyType::DecidedEnter, m_current_text, + static_cast<s32>(m_current_text.size())); + break; + case KEYCODE_DEL: + m_current_text.pop_back(); + submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString, m_current_text, + m_current_text.size()); + break; + } +} + +void AndroidKeyboard::SubmitNormalText(const ResultData& data) const { + submit_normal_callback(data.result, Common::UTF8ToUTF16(data.text), true); +} + +void InitJNI(JNIEnv* env) { + s_software_keyboard_class = reinterpret_cast<jclass>( + env->NewGlobalRef(env->FindClass("org/yuzu/yuzu_emu/applets/SoftwareKeyboard"))); + s_keyboard_config_class = reinterpret_cast<jclass>(env->NewGlobalRef( + env->FindClass("org/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardConfig"))); + s_keyboard_data_class = reinterpret_cast<jclass>(env->NewGlobalRef( + env->FindClass("org/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardData"))); + + s_swkbd_execute_normal = env->GetStaticMethodID( + s_software_keyboard_class, "ExecuteNormal", + "(Lorg/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardConfig;)Lorg/yuzu/yuzu_emu/" + "applets/SoftwareKeyboard$KeyboardData;"); + s_swkbd_execute_inline = + env->GetStaticMethodID(s_software_keyboard_class, "ExecuteInline", + "(Lorg/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardConfig;)V"); +} + +void CleanupJNI(JNIEnv* env) { + env->DeleteGlobalRef(s_software_keyboard_class); + env->DeleteGlobalRef(s_keyboard_config_class); + env->DeleteGlobalRef(s_keyboard_data_class); +} + +} // namespace SoftwareKeyboard diff --git a/src/android/app/src/main/jni/applets/software_keyboard.h b/src/android/app/src/main/jni/applets/software_keyboard.h new file mode 100644 index 000000000..b2fb59b68 --- /dev/null +++ b/src/android/app/src/main/jni/applets/software_keyboard.h @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <jni.h> + +#include "core/frontend/applets/software_keyboard.h" + +namespace SoftwareKeyboard { + +class AndroidKeyboard final : public Core::Frontend::SoftwareKeyboardApplet { +public: + ~AndroidKeyboard() override; + + void Close() const override { + ExitKeyboard(); + } + + void InitializeKeyboard(bool is_inline, + Core::Frontend::KeyboardInitializeParameters initialize_parameters, + SubmitNormalCallback submit_normal_callback_, + SubmitInlineCallback submit_inline_callback_) override; + + void ShowNormalKeyboard() const override; + + void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result, + std::u16string text_check_message) const override; + + void ShowInlineKeyboard( + Core::Frontend::InlineAppearParameters appear_parameters) const override; + + void HideInlineKeyboard() const override; + + void InlineTextChanged(Core::Frontend::InlineTextParameters text_parameters) const override; + + void ExitKeyboard() const override; + + void SubmitInlineKeyboardText(std::u16string submitted_text); + + void SubmitInlineKeyboardInput(int key_code); + +private: + struct ResultData { + static ResultData CreateFromFrontend(jobject object); + + std::string text; + Service::AM::Applets::SwkbdResult result{}; + }; + + void SubmitNormalText(const ResultData& result) const; + + Core::Frontend::KeyboardInitializeParameters parameters{}; + + mutable SubmitNormalCallback submit_normal_callback; + mutable SubmitInlineCallback submit_inline_callback; + +private: + mutable bool m_is_inline_active{}; + std::u16string m_current_text; +}; + +// Should be called in JNI_Load +void InitJNI(JNIEnv* env); + +// Should be called in JNI_Unload +void CleanupJNI(JNIEnv* env); + +} // namespace SoftwareKeyboard + +// Native function calls +extern "C" { +JNIEXPORT jobject JNICALL Java_org_citra_citra_1emu_applets_SoftwareKeyboard_ValidateFilters( + JNIEnv* env, jclass clazz, jstring text); + +JNIEXPORT jobject JNICALL Java_org_citra_citra_1emu_applets_SoftwareKeyboard_ValidateInput( + JNIEnv* env, jclass clazz, jstring text); +} diff --git a/src/android/app/src/main/jni/id_cache.cpp b/src/android/app/src/main/jni/id_cache.cpp index 8f085798d..6291c8652 100644 --- a/src/android/app/src/main/jni/id_cache.cpp +++ b/src/android/app/src/main/jni/id_cache.cpp @@ -4,6 +4,7 @@ #include <jni.h> #include "common/fs/fs_android.h" +#include "jni/applets/software_keyboard.h" #include "jni/id_cache.h" static JavaVM* s_java_vm; @@ -63,6 +64,9 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { // Initialize Android Storage Common::FS::Android::RegisterCallbacks(env, s_native_library_class); + // Initialize applets + SoftwareKeyboard::InitJNI(env); + return JNI_VERSION; } @@ -75,6 +79,9 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) { // UnInitialize Android Storage Common::FS::Android::UnRegisterCallbacks(); env->DeleteGlobalRef(s_native_library_class); + + // UnInitialze applets + SoftwareKeyboard::CleanupJNI(env); } #ifdef __cplusplus diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 6e670e899..10603c8fa 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -23,15 +23,29 @@ #include "common/scm_rev.h" #include "common/scope_exit.h" #include "common/settings.h" +#include "common/string_util.h" #include "core/core.h" #include "core/cpu_manager.h" #include "core/crypto/key_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/vfs_real.h" +#include "core/frontend/applets/cabinet.h" +#include "core/frontend/applets/controller.h" +#include "core/frontend/applets/error.h" +#include "core/frontend/applets/general_frontend.h" +#include "core/frontend/applets/mii_edit.h" +#include "core/frontend/applets/profile_select.h" +#include "core/frontend/applets/software_keyboard.h" +#include "core/frontend/applets/web_browser.h" #include "core/hid/hid_core.h" +#include "core/hle/service/am/applet_ae.h" +#include "core/hle/service/am/applet_oe.h" +#include "core/hle/service/am/applets/applets.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/loader.h" #include "core/perf_stats.h" +#include "jni/android_common/android_common.h" +#include "jni/applets/software_keyboard.h" #include "jni/config.h" #include "jni/emu_window/emu_window.h" #include "jni/id_cache.h" @@ -135,11 +149,24 @@ public: m_vulkan_library); // Initialize system. + auto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>(); + m_software_keyboard = android_keyboard.get(); m_system.SetShuttingDown(false); m_system.ApplySettings(); m_system.HIDCore().ReloadInputDevices(); m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>()); m_system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>()); + m_system.SetAppletFrontendSet({ + nullptr, // Amiibo Settings + nullptr, // Controller Selector + nullptr, // Error Display + nullptr, // Mii Editor + nullptr, // Parental Controls + nullptr, // Photo Viewer + nullptr, // Profile Selector + std::move(android_keyboard), // Software Keyboard + nullptr, // Web Browser + }); m_system.GetFileSystemController().CreateFactories(*m_system.GetFilesystem()); // Load the ROM. @@ -233,6 +260,10 @@ public: m_rom_metadata_cache.clear(); } + SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard() { + return m_software_keyboard; + } + private: struct RomMetadata { std::string title; @@ -278,6 +309,7 @@ private: std::shared_ptr<FileSys::RealVfsFilesystem> m_vfs; Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized}; bool m_is_running{}; + SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{}; // GPU driver parameters std::shared_ptr<Common::DynamicLibrary> m_vulkan_library; @@ -290,25 +322,6 @@ private: /*static*/ EmulationSession EmulationSession::s_instance; -std::string UTF16ToUTF8(std::u16string_view input) { - std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; - return convert.to_bytes(input.data(), input.data() + input.size()); -} - -std::string GetJString(JNIEnv* env, jstring jstr) { - if (!jstr) { - return {}; - } - - const jchar* jchars = env->GetStringChars(jstr, nullptr); - const jsize length = env->GetStringLength(jstr); - const std::u16string_view string_view(reinterpret_cast<const char16_t*>(jchars), length); - const std::string converted_string = UTF16ToUTF8(string_view); - env->ReleaseStringChars(jstr, jchars); - - return converted_string; -} - } // Anonymous namespace static Core::SystemResultStatus RunEmulation(const std::string& filepath) { @@ -605,4 +618,15 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_LogDeviceInfo([[maybe_unused]] JNIEnv LOG_INFO(Frontend, "Host OS: Android API level {}", android_get_device_api_level()); } +void Java_org_yuzu_yuzu_1emu_NativeLibrary_SubmitInlineKeyboardText(JNIEnv* env, jclass clazz, + jstring j_text) { + const std::u16string input = Common::UTF8ToUTF16(GetJString(env, j_text)); + EmulationSession::GetInstance().SoftwareKeyboard()->SubmitInlineKeyboardText(input); +} + +void Java_org_yuzu_yuzu_1emu_NativeLibrary_SubmitInlineKeyboardInput(JNIEnv* env, jclass clazz, + jint j_key_code) { + EmulationSession::GetInstance().SoftwareKeyboard()->SubmitInlineKeyboardInput(j_key_code); +} + } // extern "C" diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h index 192c9261d..d30351c16 100644 --- a/src/android/app/src/main/jni/native.h +++ b/src/android/app/src/main/jni/native.h @@ -133,6 +133,12 @@ JNIEXPORT jdoubleArray JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_GetPerfStat JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_LogDeviceInfo(JNIEnv* env, jclass clazz); +JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SubmitInlineKeyboardText( + JNIEnv* env, jclass clazz, jstring j_text); + +JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SubmitInlineKeyboardInput( + JNIEnv* env, jclass clazz, jint j_key_code); + #ifdef __cplusplus } #endif |