Software Keyboard

The software keyboard (swkbd) expects to be passed three IStorages. See also AM_services#Library_Applets.

The below is for normal swkbd usage, see the #InlineKeyboard section for InlineKeyboard.

Library Applet Versions

System Version Value
0x0..0x1
0x2
0x3..4
[1.0.0+] 0x5
[2.0.0+] 0x10006
[3.0.0+] 0x30007
[4.0.0+] 0x40008
[5.0.0+] 0x50009

KeyboardConfig

The second IStorage passed to this applet should contain the configuration for the keyboard.

Offset Size Typical Value Notes
0x0 4 Type
0x4 18 0 UTF-16 text displayed in the submit button
0x16 2 0 UTF-16 "left optional symbol key"
0x18 2 0 UTF-16 "right optional symbol key"
0x1A 1 0 Enables dictionary usage when non-zero (including the system dictionary).
0x1C 4 0 #Key Set Disable Bitmask
0x20 4 1 Initial cursor position (0 = start of string, 1 = end of string)
0x24 130 u"" UTF-16 header text
0xA6 258 u"" UTF-16 sub text
0x1A8 514 u"" UTF-16 guide text
0x3AC 4 0 stringLenMax
0x3B0 4 0 stringLenMaxExt. When non-zero, specifies the max string length. When the input is too long, swkbd will display an icon and disable the ok-button.
0x3B4 4 0 Password flag (0 = not password, 1 = password)
0x3B8 4 1 textDrawType
0x3BC 2 1 Return button flag (0 = disable, non-zero = enable)
0x3BE 1 1 Blur background (0 = no, 1 = yes)
0x3C0 4 20 Offset of initial string in work buffer (or 0)
0x3C4 4 0 Size of initial string in work buffer (bytes)
0x3C8 4 2024 Offset of user dictionary in work buffer (or 0)
0x3CC 4 0 Length of user dictionary (number of entries)
0x3D0 1 0 #Text check enable
0x3D8 8 0 #Text check callback function address. Not sure why this is included here
0x3E0 0x20 -1 When set and enabled via textDrawType, controls displayed text grouping (inserts spaces, without affecting output string). Used for DownloadCodes.

This struct is 0x3E0-bytes with version 0x5. Starting with version 0x30007 this struct is 0x400-bytes.

The 0x20-bytes at offset 0x3E0 is -1 normally, except for DownloadCodes.

Each entry in the user dictionary is 100 bytes long.

stringLenMax: When the input is too long, swkbd will stop accepting more input until text is deleted via the B button (Backspace).

Type

  • 0: Normal keyboard.
  • 1: Number pad. The buttons at the bottom left/right are only available when the characters at offset 0x16/0x18 are set.
  • 2: QWERTY (and variants) keyboard only.

textDrawType

If the length limit (stringLenMax) is 1..32, the type specified by textDrawType will be used. Otherwise, type1 will be used.

  • 0: The text will be displayed on a line. Also enables displaying the Header and Sub text.
  • 1: The text will be displayed in a box.
  • 2: Used for DownloadCodes on 5.0.0+. Enables using the data starting at offset 0x3E0.

Key Set Disable Bitmask

Various bits in this u32 field disable certain keys on the keyboard.

0x02: disable ' '
0x04: disable '@'
0x08: disable '%'
0x10: disable '/'
0x20: disable '\'
0x40: disable numbers
0x80: Used for DownloadCodes.
0x100: Used for UserNames. Disables '@', '%', and '\'.

Work Buffer

This is the third IStorage passed to this applet. It is a transfer memory storage. The transfer memory should have size 0x1000 (0xd000 in certain cases) and permissions 0.

The layout of the work buffer doesn't seem to matter as long as the offsets in the #KeyboardConfig are adjusted, but official code lays it out like this.

Prior to version 0x5, offset 0x0 size 0x14(20) is a header (size 0x10 for version <=0x2).

Offset Size Notes
20 (decimal) Unknown UTF-16 initial string
2024 (decimal) Unknown User dictionary

Text Check

If text checking is enabled in #KeyboardConfig, text will be checked when the submit button is pressed. First, swkbd sends the text via PushInteractiveOutData. Normally size 0x7D4 is allocated for the string.

Offset Size Notes
0x0 0x8 Buffer size
0x8 Variable UTF-16 text

The application then has an opportunity to validate or reject the text. It creates a new IStorage, writes the response to it, and sends it via PushInteractiveInData. This storage is 0x7D8-bytes.

Offset Size Notes
0x0 0x4 TextCheckResult
0x4 Variable UTF-16 error message (shown in a dialog box)

TextCheckResult:

  • 0: Success, valid string.
  • 1: Failure, invalid string. Error message is displayed in a message-box, pressing OK will return to swkbd again.
  • 2: Failure, invalid string. Error message is displayed in a message-box, pressing Cancel will return to swkbd again, while pressing OK will continue as if the text was valid.
  • 3: Failure, invalid string. With value 3 and above, swkbd will silently not accept the string, without displaying any error.

Output

When either the submit button is pressed and input has been validated, or the user cancels the text entry, swkbd will push its response and exit. The response IStorage has the following format. This storage is 0x7D8-bytes.

Offset Size Notes
0x0 0x4 Result code (0 = OK, 1 = Cancel)
0x4 Variable UTF-16 text

InlineKeyboard

This doesn't run in the foreground and has completely different input/output IStorages. This is essentially an asynchronous version of the regular swkbd. Whether it displays on the screen is controlled by the user-process. The user-process can also get the gfx data via Display_services. InlineKeyboard was added with 2.0.0, however it wasn't added to sdk-nso until the version corresponding to sysver 3.x (even though 2.0.0 system titles use it).

InitializeArg

Offset Size Notes
0x0 0x4 Unknown, normally 0.
0x4 0x1 Controls the LibraryAppletMode when launching the applet. Non-zero indicates LibraryAppletMode=0x1, otherwise LibraryAppletMode=0x3.
0x5 0x1 Set to 0x1 with [5.0.0+] in a separate init func by official sw, originally set to value 0.
0x6 0x2 Padding

AppearArg

Offset Size Notes
0x0 0x4 Initialized to value 0x2.
0x4 0x12 UTF-16 string okButtonText
0x16 0x4
0x1A 0x1 Enables dictionary usage when non-zero (including the system dictionary).
0x1B 0x1
0x1C 0x4 #Key Set Disable Bitmask
0x20 0x4 s32, Unknown. Initialized to value -1.
0x24 0x4 s32, Unknown. Initialized to value -1.
0x28 0x1 Return button flag (0 = disable, non-zero = enable)
0x29 0x2
0x2B 0x1
0x2C 0x4
0x30 0x1 Initialized to value 1.
0x31 0x17

The above struct is cleared to 0 during initialization, besides the fields specified otherwise.

CalcArg

Offset Size Flags bitmask Notes
0x0 0x4 Set to 0x30000.
0x4 0x2 Size of this struct.
0x6 0x1 Unknown, set to value 0x1.
0x7 0x1 Unknown, set to value 0x1.
0x8 0x8 Flags
0x10 0x8 0x1 #InitializeArg
0x18 0x4 0x2 float volume
0x1C 0x4 0x10 s32 cursorPos
0x20 0x48 #AppearArg
0x68 0x3D4 Not known to be set by official sw?
0x43C 0x1 0x20 utf8Mode
0x43D 0x1 Unknown
0x43E 0x1 0x8000 enableBackspace. Added with 5.x in the user-process sdk-nso.
0x43F 0x3 Unknown
0x442 0x1 0x200 keytopAsFloating
0x443 0x1 0x100 footerScalable
0x444 0x1 0x200 alphaEnabledInInputMode
0x445 0x1 0x100 inputModeFadeType
0x446 0x1 0x200 disableTouch
0x447 0x1 0x800 disableUSBKeyboard
0x448 0x5 Unknown
0x44D 0x2
0x44F 0x1
0x450 0x4 0x200 float keytopScale0
0x454 0x4 0x200 float keytopScale1
0x458 0x4 0x200 float keytopTranslate0
0x45C 0x4 0x200 float keytopTranslate1
0x460 0x4 0x100 float keytopBgAlpha
0x464 0x4 float, unknown
0x468 0x4 0x200 float balloonScale
0x46C 0x4 float, unknown
0x470 0x20
0x490 0x10

This is 0x4A0-bytes.

All floats except for keytopTranslate0/keytopTranslate1 are initialized to value 1.0f.

The applet-specific IStorage for data input is the #InitializeArg within this struct.

Runtime

Once the applet is running, official sw can call a func which does the following:

  • Checks whether the applet exited via an event, then handles exit if so and returns.
  • Otherwise:
    • If the Flags field in the #CalcArg state is non-zero, sends a Calc #Request then clears the Flags field.
    • Enters a loop which pops each applet Interactive output IStorage, reads 2 u32s from the #Reply storage and processes the reply.
    • The u32 from offset 0x0 from the last processed storage is then returned as the retval.

Request

RequestCommand Data Size Name Notes
0x4 0x0 Finalize
0x7 0x70 SetCustomizeDic
0xA 0x4A0 Calc Data is #CalcArg.

Requests are sent via an applet Interactive input IStorage: the u32 at offset 0x0 is the RequestCommand, and the rest of the storage is the request-specific data. While swkbd supports other requests, official sw only uses requests 0x4, 0x7, and 0xA.

Reply

ReplyType Data Size Name Notes

See #Runtime. In the storage, the first u32 is the retval, while the second u32 is the ReplyType. The rest is the reply-specific data.