1 // Copyright 2015 Citra Emulator Project 2 // Licensed under GPLv2 or any later version 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <memory> 8 #include "common/common_funcs.h" 9 #include "common/common_types.h" 10 #include "core/frontend/applets/swkbd.h" 11 #include "core/hle/applets/applet.h" 12 #include "core/hle/kernel/shared_memory.h" 13 #include "core/hle/result.h" 14 #include "core/hle/service/apt/apt.h" 15 16 namespace HLE::Applets { 17 18 /// Maximum number of buttons that can be in the keyboard. 19 constexpr int MAX_BUTTON = 3; 20 /// Maximum button text length, in UTF-16 code units. 21 constexpr int MAX_BUTTON_TEXT_LEN = 16; 22 /// Maximum hint text length, in UTF-16 code units. 23 constexpr int MAX_HINT_TEXT_LEN = 64; 24 /// Maximum filter callback error message length, in UTF-16 code units. 25 constexpr int MAX_CALLBACK_MSG_LEN = 256; 26 27 /// Keyboard types 28 enum class SoftwareKeyboardType : u32 { 29 Normal, ///< Normal keyboard with several pages (QWERTY/accents/symbol/mobile) 30 QWERTY, ///< QWERTY keyboard only. 31 NumPad, ///< Number pad. 32 Western, ///< On JPN systems, a text keyboard without Japanese input capabilities, 33 /// otherwise same as SWKBD_TYPE_NORMAL. 34 }; 35 36 /// Keyboard dialog buttons. 37 enum class SoftwareKeyboardButtonConfig : u32 { 38 SingleButton, ///< Ok button 39 DualButton, ///< Cancel | Ok buttons 40 TripleButton, ///< Cancel | I Forgot | Ok buttons 41 NoButton, ///< No button (returned by swkbdInputText in special cases) 42 }; 43 44 /// Accepted input types. 45 enum class SoftwareKeyboardValidInput : u32 { 46 Anything, ///< All inputs are accepted. 47 NotEmpty, ///< Empty inputs are not accepted. 48 NotEmptyNotBlank, ///< Empty or blank inputs (consisting solely of whitespace) are not 49 /// accepted. 50 NotBlank, ///< Blank inputs (consisting solely of whitespace) are not accepted, but empty 51 /// inputs are. 52 FixedLen, ///< The input must have a fixed length (specified by maxTextLength in 53 /// swkbdInit). 54 }; 55 56 /// Keyboard password modes. 57 enum class SoftwareKeyboardPasswordMode : u32 { 58 None, ///< Characters are not concealed. 59 Hide, ///< Characters are concealed immediately. 60 HideDelay, ///< Characters are concealed a second after they've been typed. 61 }; 62 63 /// Keyboard input filtering flags. Allows the caller to specify what input is explicitly not 64 /// allowed 65 namespace SoftwareKeyboardFilter { 66 enum Filter { 67 Digits = 1, ///< Disallow the use of more than a certain number of digits (0 or more) 68 At = 1 << 1, ///< Disallow the use of the @ sign. 69 Percent = 1 << 2, ///< Disallow the use of the % sign. 70 Backslash = 1 << 3, ///< Disallow the use of the \ sign. 71 Profanity = 1 << 4, ///< Disallow profanity using Nintendo's profanity filter. 72 Callback = 1 << 5, ///< Use a callback in order to check the input. 73 }; 74 } // namespace SoftwareKeyboardFilter 75 76 /// Keyboard features. 77 namespace SoftwareKeyboardFeature { 78 enum Feature { 79 Parental = 1, ///< Parental PIN mode. 80 DarkenTopScreen = 1 << 1, ///< Darken the top screen when the keyboard is shown. 81 PredictiveInput = 82 1 << 2, ///< Enable predictive input (necessary for Kanji input in JPN systems). 83 Multiline = 1 << 3, ///< Enable multiline input. 84 FixedWidth = 1 << 4, ///< Enable fixed-width mode. 85 AllowHome = 1 << 5, ///< Allow the usage of the HOME button. 86 AllowReset = 1 << 6, ///< Allow the usage of a software-reset combination. 87 AllowPower = 1 << 7, ///< Allow the usage of the POWER button. 88 DefaultQWERTY = 1 << 9, ///< Default to the QWERTY page when the keyboard is shown. 89 }; 90 } // namespace SoftwareKeyboardFeature 91 92 /// Keyboard filter callback return values. 93 enum class SoftwareKeyboardCallbackResult : u32 { 94 OK, ///< Specifies that the input is valid. 95 Close, ///< Displays an error message, then closes the keyboard. 96 Continue, ///< Displays an error message and continues displaying the keyboard. 97 }; 98 99 /// Keyboard return values. 100 enum class SoftwareKeyboardResult : s32 { 101 None = -1, ///< Dummy/unused. 102 InvalidInput = -2, ///< Invalid parameters to swkbd. 103 OutOfMem = -3, ///< Out of memory. 104 105 D0Click = 0, ///< The button was clicked in 1-button dialogs. 106 D1Click0, ///< The left button was clicked in 2-button dialogs. 107 D1Click1, ///< The right button was clicked in 2-button dialogs. 108 D2Click0, ///< The left button was clicked in 3-button dialogs. 109 D2Click1, ///< The middle button was clicked in 3-button dialogs. 110 D2Click2, ///< The right button was clicked in 3-button dialogs. 111 112 HomePressed = 10, ///< The HOME button was pressed. 113 ResetPressed, ///< The soft-reset key combination was pressed. 114 PowerPressed, ///< The POWER button was pressed. 115 116 ParentalOK = 20, ///< The parental PIN was verified successfully. 117 ParentalFail, ///< The parental PIN was incorrect. 118 119 BannedInput = 30, ///< The filter callback returned SoftwareKeyboardCallback::CLOSE. 120 }; 121 122 struct SoftwareKeyboardConfig { 123 enum_le<SoftwareKeyboardType> type; 124 enum_le<SoftwareKeyboardButtonConfig> num_buttons_m1; 125 enum_le<SoftwareKeyboardValidInput> valid_input; 126 enum_le<SoftwareKeyboardPasswordMode> password_mode; 127 s32_le is_parental_screen; 128 s32_le darken_top_screen; 129 u32_le filter_flags; 130 u32_le save_state_flags; 131 u16_le max_text_length; 132 u16_le dict_word_count; 133 u16_le max_digits; 134 std::array<std::array<u16_le, MAX_BUTTON_TEXT_LEN + 1>, MAX_BUTTON> button_text; 135 std::array<u16_le, 2> numpad_keys; 136 std::array<u16_le, MAX_HINT_TEXT_LEN + 1> 137 hint_text; ///< Text to display when asking the user for input 138 bool predictive_input; 139 bool multiline; 140 bool fixed_width; 141 bool allow_home; 142 bool allow_reset; 143 bool allow_power; 144 bool unknown; 145 bool default_qwerty; 146 std::array<bool, 4> button_submits_text; 147 u16_le language; 148 149 u32_le initial_text_offset; ///< Offset of the default text in the output SharedMemory 150 u32_le dict_offset; 151 u32_le initial_status_offset; 152 u32_le initial_learning_offset; 153 u32_le shared_memory_size; ///< Size of the SharedMemory 154 u32_le version; 155 156 enum_le<SoftwareKeyboardResult> return_code; 157 158 u32_le status_offset; 159 u32_le learning_offset; 160 161 u32_le text_offset; ///< Offset in the SharedMemory where the output text starts 162 u16_le text_length; ///< Length in characters of the output text 163 164 enum_le<SoftwareKeyboardCallbackResult> callback_result; 165 std::array<u16_le, MAX_CALLBACK_MSG_LEN + 1> callback_msg; 166 bool skip_at_check; 167 INSERT_PADDING_BYTES(0xAB); 168 }; 169 170 /** 171 * The size of this structure (0x400) has been verified via reverse engineering of multiple games 172 * that use the software keyboard. 173 */ 174 static_assert(sizeof(SoftwareKeyboardConfig) == 0x400, "Software Keyboard Config size is wrong"); 175 176 class SoftwareKeyboard final : public Applet { 177 public: SoftwareKeyboard(Service::APT::AppletId id,std::weak_ptr<Service::APT::AppletManager> manager)178 SoftwareKeyboard(Service::APT::AppletId id, std::weak_ptr<Service::APT::AppletManager> manager) 179 : Applet(id, std::move(manager)) {} 180 181 ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; 182 ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; 183 void Update() override; 184 185 /** 186 * Draws a keyboard to the current bottom screen framebuffer. 187 */ 188 void DrawScreenKeyboard(); 189 190 /** 191 * Sends the LibAppletClosing signal to the application, 192 * along with the relevant data buffers. 193 */ 194 void Finalize(); 195 196 private: 197 Frontend::KeyboardConfig ToFrontendConfig(const SoftwareKeyboardConfig& config) const; 198 199 /// This SharedMemory will be created when we receive the LibAppJustStarted message. 200 /// It holds the framebuffer info retrieved by the application with 201 /// GSPGPU::ImportDisplayCaptureInfo 202 std::shared_ptr<Kernel::SharedMemory> framebuffer_memory; 203 204 /// SharedMemory where the output text will be stored 205 std::shared_ptr<Kernel::SharedMemory> text_memory; 206 207 /// Configuration of this instance of the SoftwareKeyboard, as received from the application 208 SoftwareKeyboardConfig config; 209 210 std::shared_ptr<Frontend::SoftwareKeyboard> frontend_applet; 211 }; 212 } // namespace HLE::Applets 213