VitaShell/ime_dialog.c

151 lines
4.5 KiB
C

/*
VitaShell
Copyright (C) 2015-2018, TheFloW
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "ime_dialog.h"
#include "utils.h"
static int ime_dialog_running = 0;
static int ime_dialog_option = 0;
static const char *ime_initial_text = NULL;
static uint16_t ime_title_utf16[SCE_IME_DIALOG_MAX_TITLE_LENGTH];
static uint16_t ime_initial_text_utf16[SCE_IME_DIALOG_MAX_TEXT_LENGTH];
static uint16_t ime_input_text_utf16[SCE_IME_DIALOG_MAX_TEXT_LENGTH + 1];
static uint8_t ime_input_text_utf8[SCE_IME_DIALOG_MAX_TEXT_LENGTH + 1];
static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) {
int i;
for (i = 0; src[i]; i++) {
if ((src[i] & 0xFF80) == 0) {
*(dst++) = src[i] & 0xFF;
} else if((src[i] & 0xF800) == 0) {
*(dst++) = ((src[i] >> 6) & 0xFF) | 0xC0;
*(dst++) = (src[i] & 0x3F) | 0x80;
} else if((src[i] & 0xFC00) == 0xD800 && (src[i + 1] & 0xFC00) == 0xDC00) {
*(dst++) = (((src[i] + 64) >> 8) & 0x3) | 0xF0;
*(dst++) = (((src[i] >> 2) + 16) & 0x3F) | 0x80;
*(dst++) = ((src[i] >> 4) & 0x30) | 0x80 | ((src[i + 1] << 2) & 0xF);
*(dst++) = (src[i + 1] & 0x3F) | 0x80;
i += 1;
} else {
*(dst++) = ((src[i] >> 12) & 0xF) | 0xE0;
*(dst++) = ((src[i] >> 6) & 0x3F) | 0x80;
*(dst++) = (src[i] & 0x3F) | 0x80;
}
}
*dst = '\0';
}
static void utf8_to_utf16(const uint8_t *src, uint16_t *dst) {
int i;
for (i = 0; src[i];) {
if ((src[i] & 0xE0) == 0xE0) {
*(dst++) = ((src[i] & 0x0F) << 12) | ((src[i + 1] & 0x3F) << 6) | (src[i + 2] & 0x3F);
i += 3;
} else if ((src[i] & 0xC0) == 0xC0) {
*(dst++) = ((src[i] & 0x1F) << 6) | (src[i + 1] & 0x3F);
i += 2;
} else {
*(dst++) = src[i];
i += 1;
}
}
*dst = '\0';
}
int initImeDialog(const char *title, const char *initial_text, int max_text_length, int type, int option, int password) {
if (ime_dialog_running)
return VITASHELL_ERROR_ALREADY_RUNNING;
ime_initial_text = initial_text;
// Convert UTF8 to UTF16
memset(ime_title_utf16, 0, sizeof(ime_title_utf16));
memset(ime_initial_text_utf16, 0, sizeof(ime_initial_text_utf16));
utf8_to_utf16((uint8_t *)title, ime_title_utf16);
utf8_to_utf16((uint8_t *)initial_text, ime_initial_text_utf16);
SceImeDialogParam param;
sceImeDialogParamInit(&param);
param.supportedLanguages = 0x0001FFFF;
param.languagesForced = SCE_TRUE;
param.type = type;
param.option = option;
if (option == SCE_IME_OPTION_MULTILINE)
param.dialogMode = SCE_IME_DIALOG_DIALOG_MODE_WITH_CANCEL;
param.textBoxMode = password ? SCE_IME_DIALOG_TEXTBOX_MODE_PASSWORD : SCE_IME_DIALOG_TEXTBOX_MODE_DEFAULT;
param.title = ime_title_utf16;
param.maxTextLength = max_text_length;
param.initialText = ime_initial_text_utf16;
param.inputTextBuffer = ime_input_text_utf16;
int res = sceImeDialogInit(&param);
if (res >= 0) {
ime_dialog_running = 1;
ime_dialog_option = option;
}
return res;
}
int isImeDialogRunning() {
return ime_dialog_running;
}
uint16_t *getImeDialogInputTextUTF16() {
return ime_input_text_utf16;
}
uint8_t *getImeDialogInputTextUTF8() {
return ime_input_text_utf8;
}
const char *getImeDialogInitialText() {
return ime_initial_text;
}
int updateImeDialog() {
if (!ime_dialog_running)
return IME_DIALOG_RESULT_NONE;
SceCommonDialogStatus status = sceImeDialogGetStatus();
if (status == IME_DIALOG_RESULT_FINISHED) {
SceImeDialogResult result;
memset(&result, 0, sizeof(SceImeDialogResult));
sceImeDialogGetResult(&result);
if ((ime_dialog_option == SCE_IME_OPTION_MULTILINE && result.button == SCE_IME_DIALOG_BUTTON_CLOSE) ||
(ime_dialog_option != SCE_IME_OPTION_MULTILINE && result.button == SCE_IME_DIALOG_BUTTON_ENTER)) {
// Convert UTF16 to UTF8
utf16_to_utf8(ime_input_text_utf16, ime_input_text_utf8);
} else {
status = IME_DIALOG_RESULT_CANCELED;
}
sceImeDialogTerm();
ime_dialog_running = 0;
}
return status;
}