VitaShell/ime_dialog.c

150 lines
4.5 KiB
C
Raw Normal View History

2016-08-06 06:59:41 +00:00
/*
2017-10-13 10:42:36 +00:00
VitaShell
2017-12-30 10:43:37 +00:00
Copyright (C) 2015-2018, TheFloW
2016-08-06 06:59:41 +00:00
2017-10-13 10:42:36 +00:00
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.
2016-08-06 06:59:41 +00:00
2017-10-13 10:42:36 +00:00
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.
2016-08-06 06:59:41 +00:00
2017-10-13 10:42:36 +00:00
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
2016-08-06 06:59:41 +00:00
*/
#include "main.h"
#include "ime_dialog.h"
#include "utils.h"
static int ime_dialog_running = 0;
2016-09-07 18:18:43 +00:00
static int ime_dialog_option = 0;
2016-08-06 06:59:41 +00:00
2017-02-12 15:27:43 +00:00
static const char *ime_initial_text = NULL;
2016-08-06 06:59:41 +00:00
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];
2017-10-13 10:42:36 +00:00
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];
2016-08-06 06:59:41 +00:00
2017-02-12 15:27:43 +00:00
static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) {
2017-10-13 10:42:36 +00:00
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';
2016-08-06 06:59:41 +00:00
}
2017-02-12 15:27:43 +00:00
static void utf8_to_utf16(const uint8_t *src, uint16_t *dst) {
2017-10-13 10:42:36 +00:00
int i;
for (i = 0; src[i];) {
if ((src[i] & 0xE0) == 0xE0) {
2017-12-30 10:43:37 +00:00
*(dst++) = ((src[i] & 0x0F) << 12) | ((src[i + 1] & 0x3F) << 6) | (src[i + 2] & 0x3F);
2017-10-13 10:42:36 +00:00
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';
2016-08-06 06:59:41 +00:00
}
int initImeDialog(const char *title, const char *initial_text, int max_text_length, int type, int option, int password) {
2017-10-13 10:42:36 +00:00
if (ime_dialog_running)
return -1;
ime_initial_text = initial_text;
// Convert UTF8 to UTF16
2017-12-30 12:01:48 +00:00
memset(ime_title_utf16, 0, sizeof(ime_title_utf16));
memset(ime_initial_text_utf16, 0, sizeof(ime_initial_text_utf16));
2017-10-13 10:42:36 +00:00
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;
2017-10-13 10:42:36 +00:00
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;
2016-08-06 06:59:41 +00:00
}
int isImeDialogRunning() {
2017-10-13 10:42:36 +00:00
return ime_dialog_running;
2016-08-06 06:59:41 +00:00
}
uint16_t *getImeDialogInputTextUTF16() {
2017-10-13 10:42:36 +00:00
return ime_input_text_utf16;
2016-08-06 06:59:41 +00:00
}
uint8_t *getImeDialogInputTextUTF8() {
2017-10-13 10:42:36 +00:00
return ime_input_text_utf8;
2016-08-06 06:59:41 +00:00
}
2017-02-12 15:27:43 +00:00
const char *getImeDialogInitialText() {
2017-10-13 10:42:36 +00:00
return ime_initial_text;
2016-10-31 18:35:25 +00:00
}
2016-08-06 06:59:41 +00:00
int updateImeDialog() {
2017-10-13 10:42:36 +00:00
if (!ime_dialog_running)
return IME_DIALOG_RESULT_NONE;
2016-08-06 06:59:41 +00:00
2017-10-13 10:42:36 +00:00
SceCommonDialogStatus status = sceImeDialogGetStatus();
if (status == IME_DIALOG_RESULT_FINISHED) {
SceImeDialogResult result;
memset(&result, 0, sizeof(SceImeDialogResult));
sceImeDialogGetResult(&result);
2016-08-06 06:59:41 +00:00
2017-10-13 10:42:36 +00:00
if ((ime_dialog_option == SCE_IME_OPTION_MULTILINE && result.button == SCE_IME_DIALOG_BUTTON_CLOSE) ||
2017-12-30 12:01:48 +00:00
(ime_dialog_option != SCE_IME_OPTION_MULTILINE && result.button == SCE_IME_DIALOG_BUTTON_ENTER)) {
2017-10-13 10:42:36 +00:00
// Convert UTF16 to UTF8
utf16_to_utf8(ime_input_text_utf16, ime_input_text_utf8);
} else {
status = IME_DIALOG_RESULT_CANCELED;
}
2016-08-06 06:59:41 +00:00
2017-10-13 10:42:36 +00:00
sceImeDialogTerm();
2016-08-06 06:59:41 +00:00
2017-10-13 10:42:36 +00:00
ime_dialog_running = 0;
}
2016-08-06 06:59:41 +00:00
2017-10-13 10:42:36 +00:00
return status;
2016-08-06 06:59:41 +00:00
}