diff --git a/nx/include/switch/applets/swkbd.h b/nx/include/switch/applets/swkbd.h index bd54e6f0..11d21957 100644 --- a/nx/include/switch/applets/swkbd.h +++ b/nx/include/switch/applets/swkbd.h @@ -127,10 +127,10 @@ typedef struct { u8 returnButtonFlag; ///< Controls whether the Return button is enabled, for newlines input. 0 = disabled, non-zero = enabled. u16 unk_x29; u8 unk_x2b; - u32 unk_x2c; + u32 flags; u8 unk_x30; u8 unk_x31[0x17]; -} SwkbdAppearArg; +} PACKED SwkbdAppearArg; typedef struct { u32 unk_x0; @@ -142,30 +142,31 @@ typedef struct { float volume; ///< Flags bitmask 0x2. s32 cursorPos; ///< Flags bitmask 0x10. SwkbdAppearArg appearArg; - u8 unk_x68[0x3d4]; + u16 inputText[0x3f4/2]; ///< Flags bitmask 0x8. u8 utf8Mode; ///< Flags bitmask 0x20. - u8 unk_x43d; - u8 enableBackspace; ///< Flags bitmask 0x8000. Added with 5.x. - u8 unk_x43f[3]; + u8 unk_x45d; + u8 enableBackspace; ///< Flags bitmask 0x8000. Only available with 5.0.0+. + u8 unk_x45f[3]; u8 keytopAsFloating; ///< Flags bitmask 0x200. u8 footerScalable; ///< Flags bitmask 0x100. u8 alphaEnabledInInputMode; ///< Flags bitmask 0x200. u8 inputModeFadeType; ///< Flags bitmask 0x100. u8 disableTouch; ///< Flags bitmask 0x200. u8 disableUSBKeyboard; ///< Flags bitmask 0x800. - u8 unk_x448[5]; - u16 unk_x44d; - u8 unk_x44f; + u8 unk_x468[5]; + u16 unk_x46d; + u8 unk_x46f; float keytopScale0; ///< Flags bitmask 0x200. float keytopScale1; ///< Flags bitmask 0x200. float keytopTranslate0; ///< Flags bitmask 0x200. float keytopTranslate1; ///< Flags bitmask 0x200. float keytopBgAlpha; ///< Flags bitmask 0x100. - float unk_x464; + float unk_x484; float balloonScale; ///< Flags bitmask 0x200. - float unk_x46c; - u64 unk_x470[4]; - u8 unk_x490[0x10]; + float unk_x48c; + u8 unk_x490[0xc]; + u8 seGroup; ////< Flags bitmask: enable=0x2000, disable=0x4000. Only available with 5.0.0+. + u8 pad_x49d[3]; } PACKED SwkbdInlineCalcArg; /// InlineKeyboard @@ -173,6 +174,7 @@ typedef struct { u32 version; AppletHolder holder; SwkbdInlineCalcArg calcArg; + bool directionalButtonAssignFlag; } SwkbdInline; /** @@ -347,3 +349,77 @@ void swkbdInlineDisappear(SwkbdInline* s); */ void swkbdInlineMakeAppearArg(SwkbdAppearArg* arg, u32 type, bool flag, const char* str); +/** + * @brief Sets the audio volume. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param volume Volume + */ +void swkbdInlineSetVolume(SwkbdInline* s, float volume); + +/** + * @brief Sets the current input text string. Overrides the entire user input string if the user previously entered any text. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @note This will not affect the cursor position, see \ref swkbdInlineSetCursorPos for that. + * @param s SwkbdInline object. + * @param str UTF-8 input string. + */ +void swkbdInlineSetInputText(SwkbdInline* s, const char* str); + +/** + * @brief Sets the cursor character position in the string. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param pos Position + */ +void swkbdInlineSetCursorPos(SwkbdInline* s, s32 pos); + +/** + * @brief Sets the utf8Mode. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetUtf8Mode(SwkbdInline* s, bool flag); + +/** + * @brief Sets whether touch is enabled. The default is enabled. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetTouchFlag(SwkbdInline* s, bool flag); + +/** + * @brief Sets whether USB-keyboard is enabled. The default is enabled. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetUSBKeyboardFlag(SwkbdInline* s, bool flag); + +/** + * @brief Sets whether DirectionalButtonAssign is enabled. The default is disabled. Only available on 4.0.0+. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetDirectionalButtonAssignFlag(SwkbdInline* s, bool flag); + +/** + * @brief Sets whether the specified SeGroup (sound effect) is enabled. The default is enabled. Only available on 5.0.0+. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. If called again with a different seGroup, \ref swkbdInlineUpdate must be called prior to calling this again. + * @param s SwkbdInline object. + * @param seGroup SeGroup + * @param flag Flag + */ +void swkbdInlineSetSeGroup(SwkbdInline* s, u8 seGroup, bool flag); + +/** + * @brief Sets whether the backspace button is enabled. The default is enabled. Only available on 5.0.0+. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetBackspaceFlag(SwkbdInline* s, bool flag); + diff --git a/nx/source/applets/swkbd.c b/nx/source/applets/swkbd.c index 656af497..e0bd55d8 100644 --- a/nx/source/applets/swkbd.c +++ b/nx/source/applets/swkbd.c @@ -350,16 +350,16 @@ Result swkbdInlineCreate(SwkbdInline* s) { s->calcArg.appearArg.unk_x30 = 1; s->calcArg.enableBackspace = 1; - s->calcArg.unk_x43f[0] = 1; + s->calcArg.unk_x45f[0] = 1; s->calcArg.footerScalable = 1; s->calcArg.inputModeFadeType = 1; s->calcArg.keytopScale0 = 1.0f; s->calcArg.keytopScale1 = 1.0f; s->calcArg.keytopBgAlpha = 1.0f; - s->calcArg.unk_x464 = 1.0f; + s->calcArg.unk_x484 = 1.0f; s->calcArg.balloonScale = 1.0f; - s->calcArg.unk_x46c = 1.0f; + s->calcArg.unk_x48c = 1.0f; return 0; } @@ -408,6 +408,8 @@ Result swkbdInlineLaunch(SwkbdInline* s) { Result swkbdInlineUpdate(SwkbdInline* s) { Result rc=0; AppletStorage storage; + u32 tmp0=0, tmp1=0; + u8 tmp2[0x10] = {0}; //TODO: 'Normalize' floats. @@ -425,14 +427,33 @@ Result swkbdInlineUpdate(SwkbdInline* s) { while(R_SUCCEEDED(appletHolderPopInteractiveOutData(&s->holder, &storage))) { //TODO: Process storage content. + + s64 tmpsize=0; + rc = appletStorageGetSize(&storage, &tmpsize); + + if (R_SUCCEEDED(rc)) rc = appletStorageRead(&storage, 0x0, &tmp0, sizeof(u32)); + if (R_SUCCEEDED(rc)) rc = appletStorageRead(&storage, 0x4, &tmp1, sizeof(u32)); + if (R_SUCCEEDED(rc)) rc = appletStorageRead(&storage, 0x8, tmp2, tmpsize-8 > sizeof(tmp2) ? sizeof(tmp2) : tmpsize-8);//TODO + appletStorageClose(&storage); + + if (R_FAILED(rc)) break; } return rc; } +static void _swkbdInlineUpdateAppearFlags(SwkbdInline* s) { + u32 mask = 0x10000000; + u32 tmp = s->calcArg.appearArg.flags; + if (!s->directionalButtonAssignFlag) tmp &= ~mask; + if (s->directionalButtonAssignFlag) tmp |= mask; + s->calcArg.appearArg.flags = tmp; +} + void swkbdInlineAppear(SwkbdInline* s, SwkbdAppearArg* arg) { memcpy(&s->calcArg.appearArg, arg, sizeof(SwkbdAppearArg)); + _swkbdInlineUpdateAppearFlags(s); s->calcArg.flags = (s->calcArg.flags & ~0x80) | 0x4; } @@ -486,8 +507,61 @@ void swkbdInlineMakeAppearArg(SwkbdAppearArg* arg, u32 type, bool flag, const ch arg->type = tmpval; arg->dicFlag = tmpval2[0]; arg->returnButtonFlag = tmpval2[1]; - if (flag) arg->unk_x2c = 0x4; + if (flag) arg->flags = 0x4; _swkbdConvertToUTF16ByteSize(arg->okButtonText, str, sizeof(arg->okButtonText)); } +void swkbdInlineSetVolume(SwkbdInline* s, float volume) { + if (s->calcArg.volume == volume) return; + s->calcArg.volume = volume; + s->calcArg.flags |= 0x2; +} + +void swkbdInlineSetInputText(SwkbdInline* s, const char* str) { + _swkbdConvertToUTF16ByteSize(s->calcArg.inputText, str, sizeof(s->calcArg.inputText)); + s->calcArg.flags |= 0x8; +} + +void swkbdInlineSetCursorPos(SwkbdInline* s, s32 pos) { + s->calcArg.cursorPos = pos; + s->calcArg.flags |= 0x10; +} + +void swkbdInlineSetUtf8Mode(SwkbdInline* s, bool flag) { + u8 tmp = flag!=0; + if (s->calcArg.utf8Mode == tmp) return; + s->calcArg.utf8Mode = tmp; + s->calcArg.flags |= 0x20; +} + +void swkbdInlineSetTouchFlag(SwkbdInline* s, bool flag) { + u8 tmp = flag==0; + if (s->calcArg.disableTouch == tmp) return; + s->calcArg.disableTouch = tmp; + s->calcArg.flags |= 0x200; +} + +void swkbdInlineSetUSBKeyboardFlag(SwkbdInline* s, bool flag) { + u8 tmp = flag==0; + if (s->calcArg.disableUSBKeyboard == tmp) return; + s->calcArg.disableUSBKeyboard = tmp; + s->calcArg.flags |= 0x800; +} + +void swkbdInlineSetDirectionalButtonAssignFlag(SwkbdInline* s, bool flag) { + s->directionalButtonAssignFlag = flag; + _swkbdInlineUpdateAppearFlags(s); + s->calcArg.flags |= 0x1000; +} + +void swkbdInlineSetSeGroup(SwkbdInline* s, u8 seGroup, bool flag) { + s->calcArg.seGroup = seGroup; + s->calcArg.flags |= flag ? 0x2000 : 0x4000; +} + +void swkbdInlineSetBackspaceFlag(SwkbdInline* s, bool flag) { + s->calcArg.enableBackspace = flag!=0; + s->calcArg.flags |= 0x8000; +} +