improve IME support on SDL2

This commit is contained in:
Wengier 2021-12-08 22:02:30 -05:00
parent b23f5c724f
commit 05434a0589
7 changed files with 43 additions and 14 deletions

View File

@ -1,6 +1,8 @@
0.83.21
- Pausing the emulation will automatically release the
mouse and prevent mouse capture. (Wengier)
- Improved IME support for CJK languages on the
Windows SDL2 builds. (Wengier)
- The selected text will be highlighted when you try
to select text for copying in J-3100 mode. (Wengier)
- Config option "pixelshader" now allows a shader file
@ -9,7 +11,9 @@
- Added config options (in "ethernet, slirp" section)
"tcp_port_forwards" and "tcp_port_forwards" for port
forwarding when using the Slirp backend. (kcgen)
- Added hidden code page 951 for Big5-HKSCS. (Wengier)
- Added hidden code page 951 for Big5-HKSCS encoding.
If ChinaSea is enabled, ChinaSea characters will be
used instead of the original characters. (Wengier)
- Mac OS X builds from now on will use an in-tree tool
to replace dylib references in all executable files.
XCode install_name_tool is no longer used, it became

View File

@ -1102,6 +1102,9 @@ void DOSBOX_RealInit() {
}
#elif (defined(WIN32) && !defined(HX_DOS) || defined(LINUX) && C_X11) && defined(C_SDL2)
if (enableime && !control->opt_silent) {
#if !defined(SDL_DOSBOX_X_IME)
LOG_MSG("Note: The linked SDL 2.x library is not compiled with enhanced IME functions.")
#endif
dos.im_enable_flag = true;
SDL_StartTextInput();
#if defined(LINUX)

View File

@ -7488,7 +7488,11 @@ static bool CheckEnableImmOnKey(SDL_KeyboardEvent key)
#elif defined(WIN32) && !defined(HX_DOS) && defined(C_SDL2)
static bool CheckEnableImmOnKey(SDL_KeyboardEvent key)
{
if(key.keysym.scancode == 0x29 || (key.keysym.scancode >= 0x49 && key.keysym.scancode <= 0x52) || (key.keysym.scancode >= 0xe0 && key.keysym.scancode <= 0xe6) || (strPasteBuffer.length() && key.keysym.sym >= 0x20)) {
if(key.keysym.scancode == 0x29 ||
#if defined(SDL_DOSBOX_X_IME)
(!SDL_IM_Composition() && (key.keysym.sym == 0x08 || key.keysym.sym == 0x09 || key.keysym.sym >= 0x20 && key.keysym.sym <= 0x7F || key.keysym.sym >= 0x111 && key.keysym.sym <= 0x119)) ||
#endif
(key.keysym.scancode >= 0x49 && key.keysym.scancode <= 0x52) || (key.keysym.scancode >= 0xe0 && key.keysym.scancode <= 0xe6) || (strPasteBuffer.length() && key.keysym.sym >= 0x20)) {
// ESC, shift, control, alt, PgUp, PgDn, etc.
return true;
} else if((key.keysym.mod & 0x03) != 0 && key.keysym.scancode == 0x2c) {

View File

@ -50,9 +50,8 @@
bool clearline=false, inshell=false;
int autofixwarn=3;
extern int lfn_filefind_handle;
extern bool ctrlbrk, gbk, rtl;
extern bool DOS_BreakFlag;
extern bool DOS_BreakConioFlag;
extern bool ctrlbrk, gbk, rtl, dbcs_sbcs;
extern bool DOS_BreakFlag, DOS_BreakConioFlag;
extern uint16_t cmd_line_seg;
#if defined(USE_TTF)
extern bool ttf_dosv;
@ -558,7 +557,7 @@ void DOS_Shell::InputCommand(char * line) {
break;
case 0x4B00: /* LEFT */
if(IS_PC98_ARCH || (isDBCSCP() && IS_DOS_JAPANESE)) {
if(IS_PC98_ARCH || (isDBCSCP() && dbcs_sbcs && IS_DOS_JAPANESE)) {
if (str_index) {
uint16_t count = GetWideCount(line, str_index);
uint8_t ch = line[str_index - 1];
@ -572,7 +571,7 @@ void DOS_Shell::InputCommand(char * line) {
}
}
} else {
if (isDBCSCP()&&str_index>1&&(line[str_index-1]<0||((dos.loaded_codepage==932||(dos.loaded_codepage==936&&gbk)||dos.loaded_codepage==950||dos.loaded_codepage==951)&&line[str_index-1]>=0x40))&&line[str_index-2]<0) {
if (isDBCSCP()&&dbcs_sbcs&&str_index>1&&(line[str_index-1]<0||((dos.loaded_codepage==932||(dos.loaded_codepage==936&&gbk)||dos.loaded_codepage==950||dos.loaded_codepage==951)&&line[str_index-1]>=0x40))&&line[str_index-2]<0) {
backone();
str_index --;
MoveCaretBackwards();
@ -631,7 +630,7 @@ void DOS_Shell::InputCommand(char * line) {
}
break;
case 0x4D00: /* RIGHT */
if(IS_PC98_ARCH || (isDBCSCP() && IS_DOS_JAPANESE)) {
if(IS_PC98_ARCH || (isDBCSCP() && dbcs_sbcs && IS_DOS_JAPANESE)) {
if (str_index < str_len) {
uint16_t count = 1;
if(str_index < str_len - 1) {
@ -643,7 +642,7 @@ void DOS_Shell::InputCommand(char * line) {
}
}
} else {
if (isDBCSCP()&&str_index<str_len-1&&line[str_index]<0&&(line[str_index+1]<0||((dos.loaded_codepage==932||(dos.loaded_codepage==936&&gbk)||dos.loaded_codepage==950||dos.loaded_codepage==951)&&line[str_index+1]>=0x40))) {
if (isDBCSCP()&&dbcs_sbcs&&str_index<str_len-1&&line[str_index]<0&&(line[str_index+1]<0||((dos.loaded_codepage==932||(dos.loaded_codepage==936&&gbk)||dos.loaded_codepage==950||dos.loaded_codepage==951)&&line[str_index+1]>=0x40))) {
outc((uint8_t)line[str_index++]);
}
if (str_index < str_len) {
@ -735,14 +734,14 @@ void DOS_Shell::InputCommand(char * line) {
break;
case 0x5300:/* DELETE */
if(IS_PC98_ARCH || (isDBCSCP() && IS_DOS_JAPANESE)) {
if(IS_PC98_ARCH || (isDBCSCP() && dbcs_sbcs && IS_DOS_JAPANESE)) {
if(str_len) {
size += DeleteBackspace(true, line, str_index, str_len);
}
} else {
if(str_index>=str_len) break;
int k=1;
if (isDBCSCP()&&str_index<str_len-1&&line[str_index]<0&&(line[str_index+1]<0||((dos.loaded_codepage==932||(dos.loaded_codepage==936&&gbk)||dos.loaded_codepage==950||dos.loaded_codepage==951)&&line[str_index+1]>=0x40)))
if (isDBCSCP()&&dbcs_sbcs&&str_index<str_len-1&&line[str_index]<0&&(line[str_index+1]<0||((dos.loaded_codepage==932||(dos.loaded_codepage==936&&gbk)||dos.loaded_codepage==950||dos.loaded_codepage==951)&&line[str_index+1]>=0x40)))
k=2;
for (int i=0; i<k; i++) {
uint16_t a=str_len-str_index-1;
@ -784,13 +783,13 @@ void DOS_Shell::InputCommand(char * line) {
}
break;
case 0x08: /* BackSpace */
if(IS_PC98_ARCH || (isDBCSCP() && IS_DOS_JAPANESE)) {
if(IS_PC98_ARCH || (isDBCSCP() && dbcs_sbcs && IS_DOS_JAPANESE)) {
if(str_index) {
size += DeleteBackspace(false, line, str_index, str_len);
}
} else {
int k=1;
if (isDBCSCP()&&str_index>1&&(line[str_index-1]<0||((dos.loaded_codepage==932||(dos.loaded_codepage==936&&gbk)||dos.loaded_codepage==950||dos.loaded_codepage==951)&&line[str_index-1]>=0x40))&&line[str_index-2]<0)
if (isDBCSCP()&&dbcs_sbcs&&str_index>1&&(line[str_index-1]<0||((dos.loaded_codepage==932||(dos.loaded_codepage==936&&gbk)||dos.loaded_codepage==950||dos.loaded_codepage==951)&&line[str_index-1]>=0x40))&&line[str_index-2]<0)
k=2;
for (int i=0; i<k; i++)
if (str_index) {
@ -950,7 +949,7 @@ void DOS_Shell::InputCommand(char * line) {
str_len = 0;
break;
default:
if(IS_PC98_ARCH || (isDBCSCP() && IS_DOS_JAPANESE)) {
if(IS_PC98_ARCH || (isDBCSCP() && dbcs_sbcs && IS_DOS_JAPANESE)) {
bool kanji_flag = false;
uint16_t pos = str_index;
while(1) {

View File

@ -149,6 +149,8 @@ extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDL_Keycode key);
*/
extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name);
extern DECLSPEC SDL_bool SDLCALL SDL_IM_Composition(void);
/**
* \brief Start accepting Unicode text input events.
* This function will show the on-screen keyboard if supported.

View File

@ -36,6 +36,9 @@
extern "C" {
#endif
/* This is the DOSBox-X's modified SDL 2.x with IME support, not the general library */
#define SDL_DOSBOX_X_IME 1
/**
* \brief Information the version of SDL in use.
*

View File

@ -31,6 +31,8 @@
#include <oleauto.h>
#ifndef SDL_DISABLE_WINDOWS_IME
static Uint32 end_ticks = 0;
static SDL_bool ime_incompos;
static void IME_Init(SDL_VideoData *videodata, HWND hwnd);
static void IME_Enable(SDL_VideoData *videodata, HWND hwnd);
static void IME_Disable(SDL_VideoData *videodata, HWND hwnd);
@ -157,6 +159,15 @@ WIN_QuitKeyboard(_THIS)
#endif
}
SDL_bool SDL_IM_Composition() {
#ifndef SDL_DISABLE_WINDOWS_IME
#define IME_END_CR_WAIT 50
return ime_incompos||end_ticks&&(GetTickCount()-end_ticks<IME_END_CR_WAIT) ? SDL_TRUE : SDL_FALSE;
#else
return SDL_FALSE;
#endif
}
void
WIN_ResetDeadKeys()
{
@ -887,6 +898,7 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD
//*lParam = 0;
break;
case WM_IME_STARTCOMPOSITION:
ime_incompos = 1;
//trap = SDL_TRUE;
break;
case WM_IME_COMPOSITION:
@ -906,6 +918,8 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD
ImmReleaseContext(hwnd, himc);
break;
case WM_IME_ENDCOMPOSITION:
end_ticks = GetTickCount();
ime_incompos = 0;
videodata->ime_composition[0] = 0;
videodata->ime_readingstring[0] = 0;
videodata->ime_cursor = 0;