diff --git a/nx/include/switch/applets/swkbd.h b/nx/include/switch/applets/swkbd.h index c2b912b2..ebc1feaa 100644 --- a/nx/include/switch/applets/swkbd.h +++ b/nx/include/switch/applets/swkbd.h @@ -18,14 +18,14 @@ typedef struct { u16 rightButtonText; u16 unk_x1a; u32 keySetDisableBitmask; - u32 initialCursorPos; + u32 initialCursorPos; ///< Initial cursor position in the string: 0 = start, 1 = end. u16 headerText[130/2]; u16 subText[258/2]; u16 guideText[514/2]; u16 pad_x3aa; u32 stringLenMax; u32 unk_x3b0; - u32 passwordFlag; + u32 passwordFlag; ///< Use password: 0 = disable, 1 = enable. u32 unk_x3b8; u16 returnButtonFlag; ///< Controls whether the Return button is enabled, for newlines input. 0 = disabled, non-zero = enabled. u8 blurBackground; ///< When enabled with value 1, the background is blurred. @@ -42,7 +42,7 @@ typedef struct { /// Arg struct for version 0x30007+. typedef struct { SwkbdArgV0 arg; - u64 unk_x3e0[4]; + u32 unk_x3e0[8]; } SwkbdArgV7; typedef struct { @@ -51,6 +51,8 @@ typedef struct { u8* workbuf; size_t workbuf_size; s32 max_dictwords; + + u32 version; } SwkbdConfig; /// User dictionary word. @@ -71,6 +73,34 @@ Result swkbdCreate(SwkbdConfig* c, s32 max_dictwords); */ void swkbdClose(SwkbdConfig* c); +/** + * @brief Clears the args in the SwkbdConfig struct and initializes it with the Default Preset. + * @note Do not use this before \ref swkbdCreate. + * @param c SwkbdConfig struct. + */ +void swkbdConfigMakePresetDefault(SwkbdConfig* c); + +/** + * @brief Clears the args in the SwkbdConfig struct and initializes it with the Password Preset. + * @note Do not use this before \ref swkbdCreate. + * @param c SwkbdConfig struct. + */ +void swkbdConfigMakePresetPassword(SwkbdConfig* c); + +/** + * @brief Clears the args in the SwkbdConfig struct and initializes it with the UserName Preset. + * @note Do not use this before \ref swkbdCreate. + * @param c SwkbdConfig struct. + */ +void swkbdConfigMakePresetUserName(SwkbdConfig* c); + +/** + * @brief Clears the args in the SwkbdConfig struct and initializes it with the DownloadCode Preset. + * @note Do not use this before \ref swkbdCreate. + * @param c SwkbdConfig struct. + */ +void swkbdConfigMakePresetDownloadCode(SwkbdConfig* c); + /** * @brief Sets the Ok button text. The default is "". * @param c SwkbdConfig struct. diff --git a/nx/source/applets/swkbd.c b/nx/source/applets/swkbd.c index 8aba473e..f07566ce 100644 --- a/nx/source/applets/swkbd.c +++ b/nx/source/applets/swkbd.c @@ -34,11 +34,31 @@ static ssize_t _swkbdConvertToUTF16ByteSize(u16* out, const char* in, size_t max return _swkbdConvertToUTF16(out, in, (max/sizeof(u16)) - 1); } +static void _swkbdConfigClear(SwkbdConfig* c) { + memset(&c->arg.arg, 0, sizeof(c->arg.arg)); + memset(c->arg.unk_x3e0, 0xff, sizeof(c->arg.unk_x3e0)); +} + Result swkbdCreate(SwkbdConfig* c, s32 max_dictwords) { Result rc=0; memset(c, 0, sizeof(SwkbdConfig)); - memset(c->arg.unk_x3e0, 0xff, sizeof(c->arg.unk_x3e0)); + _swkbdConfigClear(c); + + c->version=0x5;//1.0.0+ version + if (kernelAbove500()) { + c->version = 0x50009; + } + else if (kernelAbove400()) { + c->version = 0x40008; + } + else if (kernelAbove300()) { + c->version = 0x30007; + } + else if (kernelAbove200()) { + c->version = 0x10006; + } + c->workbuf_size = 0x1000; if (max_dictwords > 0 && max_dictwords <= 0x3e8) c->max_dictwords = max_dictwords; @@ -59,6 +79,54 @@ void swkbdClose(SwkbdConfig* c) { memset(c, 0, sizeof(SwkbdConfig)); } +void swkbdConfigMakePresetDefault(SwkbdConfig* c) { + _swkbdConfigClear(c); + + c->arg.arg.unk_x0 = 2; + c->arg.arg.initialCursorPos = 1; + if (c->version < 0x50009) c->arg.arg.unk_x3b8 = 1;//removed with 5.x + c->arg.arg.returnButtonFlag = 1; + c->arg.arg.blurBackground = 1; +} + +void swkbdConfigMakePresetPassword(SwkbdConfig* c) { + _swkbdConfigClear(c); + + c->arg.arg.unk_x0 = 2; + c->arg.arg.initialCursorPos = 1; + c->arg.arg.passwordFlag = 1; + c->arg.arg.blurBackground = 1; +} + +void swkbdConfigMakePresetUserName(SwkbdConfig* c) { + _swkbdConfigClear(c); + + c->arg.arg.keySetDisableBitmask = 0x100; + c->arg.arg.initialCursorPos = 1; + c->arg.arg.blurBackground = 1; +} + +void swkbdConfigMakePresetDownloadCode(SwkbdConfig* c) { + _swkbdConfigClear(c); + + c->arg.arg.keySetDisableBitmask = 0x80; + c->arg.arg.initialCursorPos = 1; + + if (c->version >= 0x50009) {//5.x + c->arg.arg.stringLenMax = 16; + c->arg.arg.unk_x3b0 = 1; + c->arg.arg.unk_x3b8 = 2; + } + + c->arg.arg.blurBackground = 1; + + if (c->version >= 0x50009) {//5.x + c->arg.unk_x3e0[0] = 0x3; + c->arg.unk_x3e0[1] = 0x7; + c->arg.unk_x3e0[2] = 0xb; + } +} + void swkbdConfigSetOkButtonText(SwkbdConfig* c, const char* str) { _swkbdConvertToUTF16ByteSize(c->arg.arg.okButtonText, str, sizeof(c->arg.arg.okButtonText)); } @@ -145,28 +213,20 @@ Result swkbdShow(SwkbdConfig* c, char* out_string, size_t out_string_size) { Result rc=0; AppletHolder holder; AppletStorage storage; - u32 version=0x5;//1.0.0+ version memset(&storage, 0, sizeof(AppletStorage)); - //TODO: >3.0.0 versions. - if (kernelAbove300()) { - version = 0x30007; - } - else if (kernelAbove200()) { - version = 0x10006; - } - rc = appletCreateLibraryApplet(&holder, AppletId_swkbd, LibAppletMode_AllForeground); if (R_FAILED(rc)) return rc; LibAppletArgs commonargs; - libappletArgsCreate(&commonargs, version); + libappletArgsCreate(&commonargs, c->version); rc = libappletArgsPush(&commonargs, &holder); if (R_SUCCEEDED(rc)) { - if (version < 0x30007) rc = libappletPushInData(&holder, &c->arg.arg, sizeof(c->arg.arg)); - if (version >= 0x30007) rc = libappletPushInData(&holder, &c->arg, sizeof(c->arg)); + //3.0.0+ has a larger struct. + if (c->version < 0x30007) rc = libappletPushInData(&holder, &c->arg.arg, sizeof(c->arg.arg)); + if (c->version >= 0x30007) rc = libappletPushInData(&holder, &c->arg, sizeof(c->arg)); } if (R_SUCCEEDED(rc)) {