From 32f93bef5d1117ae1ae90525108747f5c786b5be Mon Sep 17 00:00:00 2001 From: yellows8 Date: Thu, 20 Dec 2018 13:06:20 -0500 Subject: [PATCH] Added initial swkbd impl. --- nx/include/switch.h | 1 + nx/include/switch/applets/swkbd.h | 30 ++++++++++++++ nx/source/applets/swkbd.c | 65 +++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 nx/include/switch/applets/swkbd.h create mode 100644 nx/source/applets/swkbd.c diff --git a/nx/include/switch.h b/nx/include/switch.h index 99599e53..71b9c01c 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -101,6 +101,7 @@ extern "C" { #include "switch/audio/driver.h" #include "switch/applets/libapplet.h" +#include "switch/applets/swkbd.h" #include "switch/runtime/env.h" #include "switch/runtime/nxlink.h" diff --git a/nx/include/switch/applets/swkbd.h b/nx/include/switch/applets/swkbd.h new file mode 100644 index 00000000..adddccb4 --- /dev/null +++ b/nx/include/switch/applets/swkbd.h @@ -0,0 +1,30 @@ +/** + * @file swkbd.h + * @brief Wrapper for using the swkbd LibraryApplet. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/applet.h" + +typedef struct { + u8 data[0x3E0];//TODO: Fill this in. +} SwkbdArg; + +typedef struct { + SwkbdArg arg; +} SwkbdConfig; + +/** + * @brief Creates a SwkbdConfig struct. + * @param c SwkbdConfig struct. + */ +void swkbdCreate(SwkbdConfig* c); + +/** + * @brief Launch swkbd with the specified config. This will return once swkbd is finished running. + * @param c SwkbdConfig struct. + */ +Result swkbdShow(SwkbdConfig* c); + diff --git a/nx/source/applets/swkbd.c b/nx/source/applets/swkbd.c new file mode 100644 index 00000000..055f5b5f --- /dev/null +++ b/nx/source/applets/swkbd.c @@ -0,0 +1,65 @@ +#include +#include "types.h" +#include "result.h" +#include "services/applet.h" +#include "applets/libapplet.h" +#include "applets/swkbd.h" + +void swkbdCreate(SwkbdConfig* c) { + memset(c, 0, sizeof(SwkbdConfig)); +} + +Result swkbdShow(SwkbdConfig* c) { + Result rc=0; + AppletHolder holder; + AppletStorage storage; + u8 *workbuf = NULL;//TODO + size_t workbuf_size = 0x1000;//TODO + + memset(&storage, 0, sizeof(AppletStorage)); + + rc = appletCreateLibraryApplet(&holder, AppletId_swkbd, LibAppletMode_AllForeground); + if (R_FAILED(rc)) return rc; + + LibAppletArgs commonargs; + libappletArgsCreate(&commonargs, 0x5);//1.0.0+ version + rc = libappletArgsPush(&commonargs, &holder); + + if (R_SUCCEEDED(rc)) rc = libappletPushInData(&holder, &c->arg, sizeof(c->arg)); + + if (R_SUCCEEDED(rc)) { + if (R_SUCCEEDED(rc)) rc = appletCreateTransferMemoryStorage(&storage, workbuf, workbuf_size, true); + appletHolderPushInData(&holder, &storage); + } + + if (R_SUCCEEDED(rc)) rc = appletHolderStart(&holder); + + if (R_SUCCEEDED(rc)) { + while(appletHolderWaitInteractiveOut(&holder)) { + //TODO: Handle Interactive data here. + } + } + + if (R_SUCCEEDED(rc)) { + appletHolderJoin(&holder); + + LibAppletExitReason reason = appletHolderGetExitReason(&holder); + + if (reason == LibAppletExitReason_Canceled) { + rc = 0x29f;//TODO: Official sw returns this, replace it with something else. + } + else if (reason == LibAppletExitReason_Abnormal || reason == LibAppletExitReason_Unexpected) { + //TODO: Official sw asserts here - return a proper error here. + return -1; + } + else { //success + //TODO: Process the output storage here. When the output CloseResult indicates failure, official sw returns same error as above. + } + } + + appletHolderClose(&holder); + appletStorageCloseTmem(&storage); + + return rc; +} +