From 58cbacc76f28df89c69bd765cedff4cfa90a6dbd Mon Sep 17 00:00:00 2001
From: yellows8 <yellows8@users.noreply.github.com>
Date: Thu, 20 Dec 2018 20:48:36 -0500
Subject: [PATCH] Handle the output swkbd storage.

---
 nx/include/switch/applets/swkbd.h |  4 ++-
 nx/source/applets/swkbd.c         | 43 +++++++++++++++++++++++++++++--
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/nx/include/switch/applets/swkbd.h b/nx/include/switch/applets/swkbd.h
index adddccb4..d7b30709 100644
--- a/nx/include/switch/applets/swkbd.h
+++ b/nx/include/switch/applets/swkbd.h
@@ -25,6 +25,8 @@ void swkbdCreate(SwkbdConfig* c);
 /**
  * @brief Launch swkbd with the specified config. This will return once swkbd is finished running.
  * @param c SwkbdConfig struct.
+ * @param out_string UTF-8 Output string buffer.
+ * @param out_string_size UTF-8 Output string buffer size, including NUL-terminator.
  */
-Result swkbdShow(SwkbdConfig* c);
+Result swkbdShow(SwkbdConfig* c, char* out_string, size_t out_string_size);
 
diff --git a/nx/source/applets/swkbd.c b/nx/source/applets/swkbd.c
index 055f5b5f..1fd0ea9e 100644
--- a/nx/source/applets/swkbd.c
+++ b/nx/source/applets/swkbd.c
@@ -1,15 +1,54 @@
 #include <string.h>
+#include <malloc.h>
 #include "types.h"
 #include "result.h"
 #include "services/applet.h"
 #include "applets/libapplet.h"
 #include "applets/swkbd.h"
+#include "runtime/util/utf.h"
+
+//TODO: InlineKeyboard currently isn't supported.
 
 void swkbdCreate(SwkbdConfig* c) {
     memset(c, 0, sizeof(SwkbdConfig));
 }
 
-Result swkbdShow(SwkbdConfig* c) {
+static void _swkbdConvertToUTF8(char* out, const u16* in, size_t max) {
+    out[0] = 0;
+    if (out==NULL || in==NULL) return;
+
+    ssize_t units = utf16_to_utf8((uint8_t*)out, in, max);
+    if (units < 0) return;
+    out[units] = 0;
+}
+
+static Result _swkbdProcessOutput(AppletHolder* h, char* out_string, size_t out_string_size) {
+    Result rc=0;
+    AppletStorage outstorage;
+    u32 CloseResult=0;
+    uint16_t* strbuf = NULL;
+    size_t strbuf_size = 0x7D4;
+
+    rc = appletHolderPopOutData(h, &outstorage);
+    if (R_FAILED(rc)) return rc;
+
+    strbuf = (u16*)malloc(strbuf_size+2);
+    if (strbuf==NULL) rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
+    if (strbuf) memset(strbuf, 0, strbuf_size+2);
+
+    if (R_SUCCEEDED(rc)) rc = appletStorageRead(&outstorage, 0, &CloseResult, sizeof(CloseResult));
+    if (R_SUCCEEDED(rc) && CloseResult!=0) rc = 0x29f;//TODO: See below.
+    if (R_SUCCEEDED(rc)) rc = appletStorageRead(&outstorage, sizeof(CloseResult), strbuf, strbuf_size);
+
+    if (R_SUCCEEDED(rc)) _swkbdConvertToUTF8(out_string, strbuf, out_string_size-1);
+
+    free(strbuf);
+    appletStorageClose(&outstorage);
+
+    return rc;
+}
+
+Result swkbdShow(SwkbdConfig* c, char* out_string, size_t out_string_size) {
     Result rc=0;
     AppletHolder holder;
     AppletStorage storage;
@@ -53,7 +92,7 @@ Result swkbdShow(SwkbdConfig* c) {
             return -1;
         }
         else { //success
-            //TODO: Process the output storage here. When the output CloseResult indicates failure, official sw returns same error as above.
+            rc = _swkbdProcessOutput(&holder, out_string, out_string_size);
         }
     }