mirror of
https://github.com/libretro/devilutionX.git
synced 2026-11-11 02:41:35 -10:00
Was this meant to reset the output? It should never be changed unless the user confirms input. In practice this was calling memcpy with the same src and dest pointers, which is undefined behaviour.
61 lines
1.7 KiB
C++
61 lines
1.7 KiB
C++
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
#include "platform/ctr/keyboard.h"
|
|
#include "utils/utf8.hpp"
|
|
|
|
constexpr size_t MAX_TEXT_LENGTH = 255;
|
|
|
|
struct vkbdEvent {
|
|
devilution::string_view hintText;
|
|
devilution::string_view inText;
|
|
char *outText;
|
|
size_t maxLength;
|
|
};
|
|
|
|
static vkbdEvent events[16];
|
|
static int eventCount = 0;
|
|
|
|
void ctr_vkbdInput(devilution::string_view hintText, devilution::string_view inText, char *outText, size_t maxLength)
|
|
{
|
|
if (eventCount >= sizeof(events))
|
|
return;
|
|
|
|
vkbdEvent &event = events[eventCount];
|
|
event.hintText = hintText;
|
|
event.inText = inText;
|
|
event.outText = outText;
|
|
event.maxLength = maxLength;
|
|
eventCount++;
|
|
}
|
|
|
|
void ctr_vkbdFlush()
|
|
{
|
|
for (int i = 0; i < eventCount; i++) {
|
|
vkbdEvent &event = events[i];
|
|
SwkbdState swkbd;
|
|
|
|
swkbdInit(&swkbd, SWKBD_TYPE_WESTERN, 2, MAX_TEXT_LENGTH);
|
|
swkbdSetValidation(&swkbd, SWKBD_NOTEMPTY_NOTBLANK, 0, 0);
|
|
|
|
// swkbdSetInitialText stores the pointer to the c-string, only copying it when swkbdInputText is called. Need to
|
|
// ensure it has a valid null-terminated string until that point.
|
|
std::string initialText { event.inText };
|
|
swkbdSetInitialText(&swkbd, initialText.c_str());
|
|
|
|
// swkbdSetHintText copies from the c-string immediately so we can use the output buffer to save a malloc
|
|
char mybuf[MAX_TEXT_LENGTH + 1];
|
|
devilution::CopyUtf8(mybuf, event.hintText, sizeof(mybuf));
|
|
swkbdSetHintText(&swkbd, mybuf);
|
|
|
|
memset(mybuf, 0, sizeof(mybuf));
|
|
SwkbdButton button = swkbdInputText(&swkbd, mybuf, sizeof(mybuf));
|
|
|
|
if (button == SWKBD_BUTTON_CONFIRM) {
|
|
devilution::CopyUtf8(event.outText, mybuf, event.maxLength);
|
|
}
|
|
}
|
|
|
|
eventCount = 0;
|
|
}
|