/* VitaShell Copyright (C) 2015-2017, 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 . */ #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) { if (ime_dialog_running) return -1; ime_initial_text = initial_text; // Convert UTF8 to UTF16 utf8_to_utf16((uint8_t *)title, ime_title_utf16); utf8_to_utf16((uint8_t *)initial_text, ime_initial_text_utf16); SceImeDialogParam param; sceImeDialogParamInit(¶m); 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.title = ime_title_utf16; param.maxTextLength = max_text_length; param.initialText = ime_initial_text_utf16; param.inputTextBuffer = ime_input_text_utf16; int res = sceImeDialogInit(¶m); 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; }