From b55bb2a8b16be4144055c760b1422800c45fdbb6 Mon Sep 17 00:00:00 2001 From: maron2000 <68574602+maron2000@users.noreply.github.com> Date: Sat, 5 Oct 2024 08:56:07 +0900 Subject: [PATCH 01/10] Add function to check codepage is DBCS --- src/dos/drive_local.cpp | 8 ++++---- src/ints/bios_disk.cpp | 4 ++-- src/misc/messages.cpp | 16 +++++++++++++--- src/output/output_ttf.cpp | 5 +++-- src/shell/shell_cmds.cpp | 5 +++-- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 6308fe7b20..385a147654 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -111,7 +111,7 @@ std::string ldir[256]; static host_cnv_char_t cpcnv_temp[4096]; static host_cnv_char_t cpcnv_ltemp[4096]; host_cnv_char_t *CodePageGuestToHost(const char *s); -extern bool isDBCSCP(), isKanji1(uint8_t chr), shiftjis_lead_byte(int c); +bool isDBCSCP(), isKanji1(uint8_t chr), shiftjis_lead_byte(int c), CheckDBCSCP(int32_t codepage); extern bool rsize, morelen, force_sfn, enable_share_exe, chinasea, uao, halfwidthkana, dbcs_sbcs, inmsg, forceswk; extern int lfn_filefind_handle, freesizecap, file_access_tries; extern unsigned long totalc, freec; @@ -1010,7 +1010,7 @@ bool CodePageGuestToHostUTF8(char *d/*CROSS_LEN*/,const char *s/*CROSS_LEN*/) { host_cnv_char_t *CodePageGuestToHost(const char *s) { #if defined(host_cnv_use_wchar) uint16_t cp = GetACP(), cpbak = dos.loaded_codepage; - if (tryconvertcp && !notrycp && cpbak == 437 && (cp == 932 || cp == 936 || cp == 949 || cp == 950 || cp == 951)) { + if (tryconvertcp && !notrycp && cpbak == 437 && CheckDBCSCP(cp)) { dos.loaded_codepage = cp; if (CodePageGuestToHostUTF16((uint16_t *)cpcnv_temp,s)) { dos.loaded_codepage = cpbak; @@ -1030,7 +1030,7 @@ host_cnv_char_t *CodePageGuestToHost(const char *s) { char *CodePageHostToGuest(const host_cnv_char_t *s) { #if defined(host_cnv_use_wchar) uint16_t cp = GetACP(), cpbak = dos.loaded_codepage; - if (tryconvertcp && !notrycp && cpbak == 437 && (cp == 932 || cp == 936 || cp == 949 || cp == 950 || cp == 951)) { + if (tryconvertcp && !notrycp && cpbak == 437 && CheckDBCSCP(cp)) { dos.loaded_codepage = cp; if (CodePageHostToGuestUTF16((char *)cpcnv_temp,(const uint16_t *)s)) { dos.loaded_codepage = cpbak; @@ -1050,7 +1050,7 @@ char *CodePageHostToGuest(const host_cnv_char_t *s) { char *CodePageHostToGuestL(const host_cnv_char_t *s) { #if defined(host_cnv_use_wchar) uint16_t cp = GetACP(), cpbak = dos.loaded_codepage; - if (tryconvertcp && !notrycp && cpbak == 437 && (cp == 932 || cp == 936 || cp == 949 || cp == 950 || cp == 951)) { + if (tryconvertcp && !notrycp && cpbak == 437 && CheckDBCSCP(cp)) { dos.loaded_codepage = cp; if (CodePageHostToGuestUTF16((char *)cpcnv_ltemp,(const uint16_t *)s)) { dos.loaded_codepage = cpbak; diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 9166dbb6b8..a087e6b921 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -41,7 +41,7 @@ extern const uint8_t freedos_mbr[]; extern int bootdrive, tryconvertcp; extern bool int13_disk_change_detect_enable, skipintprog, rsize; extern bool int13_extensions_enable, bootguest, bootvm, use_quick_reboot; -extern bool isDBCSCP(), isKanji1_gbk(uint8_t chr), shiftjis_lead_byte(int c); +bool isDBCSCP(), isKanji1_gbk(uint8_t chr), shiftjis_lead_byte(int c), CheckDBCSCP(int32_t codepage); extern bool CodePageGuestToHostUTF16(uint16_t *d/*CROSS_LEN*/,const char *s/*CROSS_LEN*/); #define STATIC_ASSERTM(A,B) static_assertion_##A##_##B @@ -514,7 +514,7 @@ struct fatFromDOSDrive uint16_t uname[4]; #if defined(WIN32) uint16_t cp = GetACP(), cpbak = dos.loaded_codepage; - if (tryconvertcp && cpbak == 437 && (cp == 932 || cp == 936 || cp == 949 || cp == 950 || cp == 951)) + if (tryconvertcp && cpbak == 437 && CheckDBCSCP(cp)) dos.loaded_codepage = cp; #endif for (size_t i=0; i < lfnlen; i++) { diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 67f6edbb02..fb87fbc78f 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -52,6 +52,7 @@ extern const char * RunningProgram; Bitu DOS_ChangeKeyboardLayout(const char* layoutname, int32_t codepage); Bitu DOS_ChangeCodepage(int32_t codepage, const char* codepagefile); Bitu DOS_LoadKeyboardLayout(const char* layoutname, int32_t codepage, const char* codepagefile); +bool CheckDBCSCP(int32_t codepage); #define LINE_IN_MAXLEN 2048 @@ -204,12 +205,21 @@ void AddMessages() { MSG_Add("AUTO_CYCLE_OFF","Auto cycles [off]"); } +// True if specified codepage is a DBCS codepage +bool CheckDBCSCP(int32_t codepage) { + if(codepage == 932 || codepage == 936 || codepage == 949 || codepage == 950 || codepage == 951) { + //LOG_MSG("CheckDBCSCP: Codepage %d true", codepage); + return true; + } + else return false; +} + void MSG_Init(void); void SetKEYBCP() { if (IS_PC98_ARCH || IS_JEGA_ARCH || IS_DOSV || dos_kernel_disabled || !strcmp(RunningProgram, "LOADLIN")) return; Bitu return_code; - if(msgcodepage == 932 || msgcodepage == 936 || msgcodepage == 949 || msgcodepage == 950 || msgcodepage == 951) { + if(CheckDBCSCP(msgcodepage)) { MSG_Init(); InitFontHandle(); JFONT_Init(); @@ -389,7 +399,7 @@ void LoadMessageFile(const char * fname) { dos.loaded_codepage=cp; if (loadlangcp && msgcodepage>0 && isSupportedCP(msgcodepage) && msgcodepage != dos.loaded_codepage) { ShutFontHandle(); - if(msgcodepage == 932 || msgcodepage == 936 || msgcodepage == 949 || msgcodepage == 950 || msgcodepage == 951) { + if(CheckDBCSCP(msgcodepage)) { dos.loaded_codepage = msgcodepage; InitFontHandle(); JFONT_Init(); @@ -486,7 +496,7 @@ void MSG_Init() { sprintf(cstr, "%s,%d", countrystr, msgcodepage); SetVal("config", "country", cstr); const char *imestr = section->Get_string("ime"); - if (tonoime && !strcasecmp(imestr, "auto") && (msgcodepage == 932 || msgcodepage == 936 || msgcodepage == 949 || msgcodepage == 950 || msgcodepage == 951)) { + if (tonoime && !strcasecmp(imestr, "auto") && CheckDBCSCP(msgcodepage)) { tonoime = false; enableime = true; SetIME(); diff --git a/src/output/output_ttf.cpp b/src/output/output_ttf.cpp index 110efdcf3e..4216b148e7 100644 --- a/src/output/output_ttf.cpp +++ b/src/output/output_ttf.cpp @@ -125,6 +125,7 @@ bool init_once = false, init_twice = false; int menuwidth_atleast(int width), FileDirExistCP(const char *name), FileDirExistUTF8(std::string &localname, const char *name); void AdjustIMEFontSize(void),refreshExtChar(void), initcodepagefont(void), change_output(int output), drawmenu(Bitu val), KEYBOARD_Clear(void), RENDER_Reset(void), DOSBox_SetSysMenu(void), GetMaxWidthHeight(unsigned int *pmaxWidth, unsigned int *pmaxHeight), SetWindowTransparency(int trans), resetFontSize(void), RENDER_CallBack( GFX_CallBackFunctions_t function ); bool isDBCSCP(void), InitCodePage(void), CodePageGuestToHostUTF16(uint16_t *d/*CROSS_LEN*/,const char *s/*CROSS_LEN*/), systemmessagebox(char const * aTitle, char const * aMessage, char const * aDialogType, char const * aIconType, int aDefaultButton); +bool CheckDBCSCP(int32_t codepage); std::string GetDOSBoxXPath(bool withexe=false); #if defined(C_SDL2) @@ -502,14 +503,14 @@ int setTTFMap(bool changecp) { uname[0]=0; uname[1]=0; if (cp == 932 && (halfwidthkana || IS_JEGA_ARCH)) forceswk=true; - if (cp == 932 || cp == 936 || cp == 949 || cp == 950 || cp == 951) dos.loaded_codepage = 437; + if (CheckDBCSCP(cp)) dos.loaded_codepage = 437; if (CodePageGuestToHostUTF16(uname,text)) { wcTest[i] = uname[1]==0?uname[0]:i; if (cp == 932 && lowboxdrawmap.find(i)!=lowboxdrawmap.end() && TTF_GlyphIsProvided(ttf.SDL_font, wcTest[i])) cpMap[i] = wcTest[i]; } forceswk=false; - if (cp == 932 || cp == 936 || cp == 949 || cp == 950 || cp == 951) dos.loaded_codepage = cp; + if (CheckDBCSCP(cp)) dos.loaded_codepage = cp; } uint16_t unimap; int notMapped = 0; diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 93cde79a97..b7718b8085 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -140,6 +140,7 @@ extern void MAPPER_AutoType(std::vector &sequence, const uint32_t w extern void DOS_SetCountry(uint16_t countryNo), DOSV_FillScreen(void); std::string GetDOSBoxXPath(bool withexe=false); FILE *testLoadLangFile(const char *fname); +bool CheckDBCSCP(int32_t codepage); /* support functions */ static char empty_char = 0; @@ -4599,7 +4600,7 @@ void DOS_Shell::CMD_CHCP(char * args) { int32_t cp = dos.loaded_codepage; Bitu keyb_error; if(n == 1) { - if(newCP == 932 || newCP == 936 || newCP == 949 || newCP == 950 || newCP == 951 + if(CheckDBCSCP(newCP) #if defined(USE_TTF) || (ttf.inUse && (newCP >= 1250 && newCP <= 1258)) #endif @@ -4636,7 +4637,7 @@ void DOS_Shell::CMD_CHCP(char * args) { if(*buff == ':' && strchr(StripArg(args), ':')) { std::string name = buff + 1; if(name.empty() && iter != langcp_map.end()) name = iter->second; - if(newCP == 932 || newCP == 936 || newCP == 949 || newCP == 950 || newCP == 951) { + if(CheckDBCSCP(newCP)) { missing = toSetCodePage(this, newCP, -1); if(missing > -1) SwitchLanguage(cp, newCP, true); if(missing > 0) WriteOut(MSG_Get("SHELL_CMD_CHCP_MISSING"), missing); From f3847d7df9dd435afd5ddb4dd2928ca7ec56baf8 Mon Sep 17 00:00:00 2001 From: maron2000 <68574602+maron2000@users.noreply.github.com> Date: Sat, 5 Oct 2024 10:35:34 +0900 Subject: [PATCH 02/10] toSetCodePage function switches codepages in non-TTF mode and in non-DBCS codepages --- src/shell/shell_cmds.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index b7718b8085..00815b7e55 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -140,7 +140,9 @@ extern void MAPPER_AutoType(std::vector &sequence, const uint32_t w extern void DOS_SetCountry(uint16_t countryNo), DOSV_FillScreen(void); std::string GetDOSBoxXPath(bool withexe=false); FILE *testLoadLangFile(const char *fname); +Bitu DOS_ChangeCodepage(int32_t codepage, const char* codepagefile); bool CheckDBCSCP(int32_t codepage); +static int32_t lastsetcp = 0; /* support functions */ static char empty_char = 0; @@ -4527,14 +4529,16 @@ extern bool jfont_init, isDBCSCP(); extern Bitu DOS_LoadKeyboardLayout(const char * layoutname, int32_t codepage, const char * codepagefile); void runRescan(const char *str), MSG_Init(), JFONT_Init(), InitFontHandle(), ShutFontHandle(), initcodepagefont(), DOSBox_SetSysMenu(); int toSetCodePage(DOS_Shell *shell, int newCP, int opt) { - if (isSupportedCP(newCP)) { - dos.loaded_codepage = newCP; + if((TTF_using() && isSupportedCP(newCP)) || !TTF_using()) { + if(!CheckDBCSCP(newCP)) DOS_ChangeCodepage(newCP, "auto"); + dos.loaded_codepage = newCP; int missing = 0; #if defined(USE_TTF) missing = TTF_using() ? setTTFCodePage() : 0; #endif if (!TTF_using()) initcodepagefont(); - if (dos.loaded_codepage==437) DOS_LoadKeyboardLayout("us", 437, "auto"); + //if (dos.loaded_codepage==437) DOS_LoadKeyboardLayout("us", 437, "auto"); + //LOG_MSG("toSetCodePage opt=%d, loadlangnew=%d", opt, loadlangnew?1:0); if (opt==-1) { MSG_Init(); #if DOSBOXMENU_TYPE == DOSBOXMENU_HMENU @@ -4550,8 +4554,8 @@ int toSetCodePage(DOS_Shell *shell, int newCP, int opt) { ShutFontHandle(); InitFontHandle(); JFONT_Init(); + SetupDBCSTable(); } - SetupDBCSTable(); runRescan("-A -Q"); #if defined(USE_TTF) if ((opt==-1||opt==-2)&&TTF_using()) { @@ -4565,6 +4569,10 @@ int toSetCodePage(DOS_Shell *shell, int newCP, int opt) { } } #endif + if(newCP != lastsetcp) { + LOG_MSG("Codepage set to %d", newCP); + lastsetcp = newCP; + } return missing; } else if (opt<1 && shell) { shell->WriteOut(MSG_Get("SHELL_CMD_CHCP_INVALID"), std::to_string(newCP).c_str()); From 2205c844a14aedc39a1bf36ff127f33252c34ef2 Mon Sep 17 00:00:00 2001 From: maron2000 <68574602+maron2000@users.noreply.github.com> Date: Sat, 5 Oct 2024 11:39:41 +0900 Subject: [PATCH 03/10] Fix initial loading of Chinese & Korean keyboard layouts --- src/dos/dos_keyboard_layout.cpp | 88 +++++++++++++++------------------ 1 file changed, 40 insertions(+), 48 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 2f465d1d0c..234e7bd3bb 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1447,11 +1447,11 @@ class DOS_KeyboardLayout: public Module_base { const Section_prop* section = static_cast(configuration); const char * layoutname=section->Get_string("keyboardlayout"); dos.loaded_codepage = GetDefaultCP(); // default codepage already initialized - int tocp=!strcmp(layoutname, "jp")||IS_JDOSV?932:(!strcmp(layoutname, "ko")||IS_KDOSV?949:(!strcmp(layoutname, "tw")||!strcmp(layoutname, "hk")||!strcmp(layoutname, "zht")||IS_TDOSV?950:(!strcmp(layoutname, "cn")||!strcmp(layoutname, "zh")||!strcmp(layoutname, "zhs")||IS_PDOSV?936:(!strcmp(layoutname, "us")?437:0)))); + int tocp=!stricmp(layoutname, "jp")||IS_JDOSV?932:(!stricmp(layoutname, "ko")||IS_KDOSV?949:(!stricmp(layoutname, "tw")||!stricmp(layoutname, "hk")||!stricmp(layoutname, "zht")||IS_TDOSV?950:(!stricmp(layoutname, "cn")||!stricmp(layoutname, "zh")||!stricmp(layoutname, "zhs")||IS_PDOSV?936:(!stricmp(layoutname, "us")?437:0)))); #if defined(WIN32) if (dos.loaded_codepage == 932 && !IS_PC98_ARCH && GetKeyboardType(0) == 7 && !strcmp(layoutname, "auto")) layoutname = "jp106"; #endif - if (tocp && strcmp(layoutname, "jp106") && strcmp(layoutname, "jp") && strcmp(layoutname, "ko")) layoutname="us"; + if (tocp && stricmp(layoutname, "jp106") && stricmp(layoutname, "jp") && stricmp(layoutname, "ko") && stricmp(layoutname, "cn") && stricmp(layoutname, "hk") && stricmp(layoutname, "tw")) layoutname="us"; #if defined(USE_TTF) if (TTF_using()) setTTFCodePage(); else @@ -1487,11 +1487,9 @@ class DOS_KeyboardLayout: public Module_base { layoutname = "bg241"; break; */ case 1028: // Taiwan, CP 950, Alt CP 951 - if (tryconvertcp == 1) { - layoutname = "us"; - tocp = 950; - } - break; + layoutname = "us"; + tocp = 950; + break; case 1029: // Czech Republic, CP 852, Alt CP 850 layoutname = "cz243"; break; @@ -1533,17 +1531,13 @@ class DOS_KeyboardLayout: public Module_base { wants_dos_codepage = GetDefaultCP(); break; case 1041: // Japan, CP 932 - if (tryconvertcp == 1) { - layoutname = "jp"; - tocp = 932; - } - break; + layoutname = "jp"; + tocp = 932; + break; case 1042: // Korea, CP 949 - if (tryconvertcp == 1) { - layoutname = "ko"; - tocp = 949; - } - break; + layoutname = "us"; + tocp = 949; + break; case 1043: // Netherlands, CP 850, Alt CP 437 layoutname = "nl"; wants_dos_codepage = GetDefaultCP(); @@ -1610,11 +1604,9 @@ class DOS_KeyboardLayout: public Module_base { layoutname = "hy"; break; */ case 2052: // China, CP 936 - if (tryconvertcp == 1) { - layoutname = "us"; - tocp = 936; - } - break; + layoutname = "us"; + tocp = 936; + break; case 2055: // Swiss-German, CP 850, Alt CP 437 layoutname = "sg"; wants_dos_codepage = GetDefaultCP(); @@ -1639,11 +1631,9 @@ class DOS_KeyboardLayout: public Module_base { layoutname = "po"; break; case 3076: // Hong Kong, CP 950, Alt CP 951 - if (tryconvertcp == 1) { - layoutname = "us"; - tocp = 950; - } - break; + layoutname = "us"; + tocp = 950; + break; case 3081: // Australia, CP 850, Alt CP 437 layoutname = "us"; wants_dos_codepage = GetDefaultCP(); @@ -1681,13 +1671,18 @@ class DOS_KeyboardLayout: public Module_base { wants_dos_codepage = GetDefaultCP(); break; default: - break; + layoutname = "us"; + wants_dos_codepage = 437; + break; } - } - else if(!strncmp(layoutname, "none", 4)) { +#else // !WIN32 layoutname = "us"; wants_dos_codepage = 437; #endif + } + else if(!strncmp(layoutname, "none", 4)) { + layoutname = "us"; + wants_dos_codepage = 437; } bool extract_codepage = !tocp; @@ -1706,8 +1701,14 @@ class DOS_KeyboardLayout: public Module_base { /* if (strncmp(layoutname,"auto",4) && strncmp(layoutname,"none",4)) { LOG_MSG("Loading DOS keyboard layout %s ...",layoutname); } */ - if (!tocp && loaded_layout->read_keyboard_file(layoutname, dos.loaded_codepage)) { - if (strncmp(layoutname,"auto",4)) { + if(!stricmp(layoutname, "cn") || !stricmp(layoutname, "hk") || !stricmp(layoutname, "tw") || !stricmp(layoutname, "ko")) { + loaded_layout->read_keyboard_file("us", 437); + if(!stricmp(layoutname, "cn")) dos.loaded_codepage = 936; + if(!stricmp(layoutname, "hk") || !stricmp(layoutname, "tw")) dos.loaded_codepage = 950; + if(!stricmp(layoutname, "ko")) dos.loaded_codepage = 949; + } + if (!tocp && loaded_layout->read_keyboard_file(layoutname, dos.loaded_codepage)) { + if (strncmp(layoutname,"auto",4)) { LOG_MSG("Error loading keyboard layout %s",layoutname); } } else if (!tocp) { @@ -1717,20 +1718,15 @@ class DOS_KeyboardLayout: public Module_base { } } if (tocp && !IS_PC98_ARCH) { - if((dos.loaded_codepage == 932 || tocp == 932) && (!strcmp(layoutname, "jp106") || !strcmp(layoutname, "jp"))) loaded_layout->read_keyboard_file(layoutname, 932); - uint16_t cpbak = dos.loaded_codepage; -#if defined(USE_TTF) - if (ttf.inUse) - toSetCodePage(NULL, tocp, -1); - else -#endif - { + if((dos.loaded_codepage == 932 || tocp == 932) && (!stricmp(layoutname, "jp106") || !stricmp(layoutname, "jp"))) loaded_layout->read_keyboard_file(layoutname, 932); + if(!stricmp(layoutname, "ko") || !stricmp(layoutname, "cn") || !stricmp(layoutname, "tw") || !stricmp(layoutname, "hk")) { + loaded_layout->read_keyboard_file("us", 437); dos.loaded_codepage = tocp; - MSG_Init(); - DOSBox_SetSysMenu(); - if (!jfont_init && isDBCSCP()) JFONT_Init(); - SetupDBCSTable(); + } + + if (!TTF_using() || (TTF_using() && isSupportedCP(tocp))){ + toSetCodePage(NULL, msgcodepage ? msgcodepage : tocp, -2); runRescan("-A -Q"); #if C_OPENGL && DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW if (OpenGL_using() && control->opt_lang.size() && lastcp && lastcp != dos.loaded_codepage) @@ -1738,10 +1734,6 @@ class DOS_KeyboardLayout: public Module_base { #endif } } - if(msgcodepage) { - SwitchLanguage(dos.loaded_codepage, msgcodepage, false); - DOS_ChangeCodepage(msgcodepage, "auto"); - } } ~DOS_KeyboardLayout(){ From 9447b8d2032353d72734a7e4bf8160f506b38d86 Mon Sep 17 00:00:00 2001 From: maron2000 <68574602+maron2000@users.noreply.github.com> Date: Sat, 5 Oct 2024 12:58:08 +0900 Subject: [PATCH 04/10] CHCP: Fix handling of invalid codepage --- src/dos/dos.cpp | 2 +- src/dos/dos_keyboard_layout.cpp | 11 +++---- src/dos/dos_programs.cpp | 8 +++-- src/misc/messages.cpp | 4 +-- src/shell/shell.cpp | 2 +- src/shell/shell_cmds.cpp | 53 +++++++++++++++++---------------- 6 files changed, 43 insertions(+), 37 deletions(-) diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index e95dfea0ff..5a05f827d9 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -90,7 +90,7 @@ bool isDBCSCP(); uint32_t BIOS_get_PC98_INT_STUB(void); uint16_t GetDefaultCP(void); void ResolvePath(std::string& in); -void SwitchLanguage(int oldcp, int newcp, bool confirm); +bool SwitchLanguage(int oldcp, int newcp, bool confirm); void makestdcp950table(), makeseacp951table(); std::string GetDOSBoxXPath(bool withexe=false); extern std::string prefix_local, prefix_overlay; diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 234e7bd3bb..0c88e72dc7 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -48,7 +48,6 @@ int lastcp = 0; void DOSBox_SetSysMenu(void); bool OpenGL_using(void), isDBCSCP(void); void change_output(int output), UpdateSDLDrawTexture(); -void SwitchLanguage(int oldcp, int newcp, bool confirm); Bitu DOS_ChangeCodepage(int32_t codepage, const char* codepagefile); void MSG_Init(), JFONT_Init(), runRescan(const char *str); extern int tryconvertcp, toSetCodePage(DOS_Shell *shell, int newCP, int opt); @@ -1425,8 +1424,10 @@ Bitu DOS_ChangeKeyboardLayout(const char* layoutname, int32_t codepage) { Bitu DOS_ChangeCodepage(int32_t codepage, const char* codepagefile) { // try to read the layout for the specified codepage + int32_t oldcp = dos.loaded_codepage; Bitu kerrcode = loaded_layout->read_codepage_file(codepagefile, codepage); if(kerrcode) { + loaded_layout->read_codepage_file("auto", oldcp); return kerrcode; } // Everything went fine @@ -1487,7 +1488,7 @@ class DOS_KeyboardLayout: public Module_base { layoutname = "bg241"; break; */ case 1028: // Taiwan, CP 950, Alt CP 951 - layoutname = "us"; + layoutname = "tw"; tocp = 950; break; case 1029: // Czech Republic, CP 852, Alt CP 850 @@ -1535,7 +1536,7 @@ class DOS_KeyboardLayout: public Module_base { tocp = 932; break; case 1042: // Korea, CP 949 - layoutname = "us"; + layoutname = "ko"; tocp = 949; break; case 1043: // Netherlands, CP 850, Alt CP 437 @@ -1604,7 +1605,7 @@ class DOS_KeyboardLayout: public Module_base { layoutname = "hy"; break; */ case 2052: // China, CP 936 - layoutname = "us"; + layoutname = "cn"; tocp = 936; break; case 2055: // Swiss-German, CP 850, Alt CP 437 @@ -1631,7 +1632,7 @@ class DOS_KeyboardLayout: public Module_base { layoutname = "po"; break; case 3076: // Hong Kong, CP 950, Alt CP 951 - layoutname = "us"; + layoutname = "hk"; tocp = 950; break; case 3081: // Australia, CP 850, Alt CP 437 diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index e92ffc5ab9..4fad572a35 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -114,6 +114,7 @@ void runBoot(const char *str), runMount(const char *str), runImgmount(const char void getdrivezpath(std::string &path, std::string const& dirname), drivezRegister(std::string const& path, std::string const& dir, bool usecp), UpdateDefaultPrinterFont(void); std::string GetDOSBoxXPath(bool withexe=false); FILE *testLoadLangFile(const char *fname); +bool CheckDBCSCP(int32_t codepage); #if defined(OS2) #define INCL DOSFILEMGR @@ -206,8 +207,7 @@ void DetachFromBios(imageDisk* image) { } } -void SwitchLanguage(int oldcp, int newcp, bool confirm) { - (void)oldcp; //unused +bool SwitchLanguage(int oldcp, int newcp, bool confirm) { auto iterold = langcp_map.find(lastmsgcp), iternew = langcp_map.find(newcp); std::string langold = iterold != langcp_map.end() ? iterold->second : "", langnew = iternew != langcp_map.end() ? iternew->second : ""; if (loadlang && langnew.size() && strcasecmp(langold.c_str(), langnew.c_str())) { @@ -215,13 +215,15 @@ void SwitchLanguage(int oldcp, int newcp, bool confirm) { if (file) { fclose(file); std::string msg = "You have changed the active code page to " + std::to_string(newcp) + ". Do you want to load language file " + langnew + " for this code page?"; - if (!confirm || systemmessagebox("DOSBox-X language file", msg.c_str(), "yesno","question", 2)) { + if (!confirm || (CheckDBCSCP(oldcp) && !CheckDBCSCP(newcp)) || systemmessagebox("DOSBox-X language file", msg.c_str(), "yesno","question", 2)) { SetVal("dosbox", "language", langnew); Load_Language(langnew); lastmsgcp = newcp; + return true; // Will load language file for the active codepage } } } + return false; } extern std::string hidefiles, dosbox_title; diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index fb87fbc78f..f92043d62c 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -46,7 +46,7 @@ bool isSupportedCP(int newCP), CodePageHostToGuestUTF8(char *d/*CROSS_LEN*/,cons void InitFontHandle(void), ShutFontHandle(void), refreshExtChar(void), SetIME(void), runRescan(const char *str), menu_update_dynamic(void), menu_update_autocycle(void), update_bindbutton_text(void), set_eventbutton_text(const char *eventname, const char *buttonname), JFONT_Init(), DOSBox_SetSysMenu(), UpdateSDLDrawTexture(), makestdcp950table(), makeseacp951table(); std::string langname = "", langnote = "", GetDOSBoxXPath(bool withexe=false); extern int lastcp, FileDirExistUTF8(std::string &localname, const char *name), toSetCodePage(DOS_Shell *shell, int newCP, int opt); -extern bool dos_kernel_disabled, force_conversion, showdbcs, dbcs_sbcs, enableime, tonoime, chinasea; +extern bool dos_kernel_disabled, force_conversion, showdbcs, dbcs_sbcs, enableime, tonoime, chinasea, CHCP_changed; extern uint16_t GetDefaultCP(); extern const char * RunningProgram; Bitu DOS_ChangeKeyboardLayout(const char* layoutname, int32_t codepage); @@ -335,7 +335,7 @@ void LoadMessageFile(const char * fname) { } else { std::string msg = "The specified language file uses code page " + std::to_string(c) + ". Do you want to change to this code page accordingly?"; - if(c != dos.loaded_codepage && (control->opt_langcp || uselangcp || !loadlang || (loadlang && systemmessagebox("DOSBox-X language file", msg.c_str(), "yesno", "question", 1)))){ + if(c != dos.loaded_codepage && (control->opt_langcp || uselangcp || !CHCP_changed || !loadlang || (loadlang && systemmessagebox("DOSBox-X language file", msg.c_str(), "yesno", "question", 1)))){ loadlangcp = true; msgcodepage = c; dos.loaded_codepage = c; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 8e30e14219..eb16b07e72 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -77,7 +77,7 @@ void initcodepagefont(void); void runMount(const char *str); void ResolvePath(std::string& in); void DOS_SetCountry(uint16_t countryNo); -void SwitchLanguage(int oldcp, int newcp, bool confirm); +bool SwitchLanguage(int oldcp, int newcp, bool confirm); void CALLBACK_DeAllocate(Bitu in), DOSBox_ConsolePauseWait(); void GFX_SetTitle(int32_t cycles, int frameskip, Bits timing, bool paused); bool isDBCSCP(), InitCodePage(), isKanji1(uint8_t chr), shiftjis_lead_byte(int c), sdl_wait_on_error(); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 00815b7e55..189547bc14 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -135,14 +135,15 @@ extern uint16_t countryNo, altcp_to_unicode[256]; extern bool isDBCSCP(), isKanji1(uint8_t chr), shiftjis_lead_byte(int c), TTF_using(void), Network_IsNetworkResource(const char * filename); extern bool CheckBoxDrawing(uint8_t c1, uint8_t c2, uint8_t c3, uint8_t c4), GFX_GetPreventFullscreen(void), DOS_SetAnsiAttr(uint8_t attr); extern bool systemmessagebox(char const * aTitle, char const * aMessage, char const * aDialogType, char const * aIconType, int aDefaultButton); -extern void Load_Language(std::string name), SwitchLanguage(int oldcp, int newcp, bool confirm), GetExpandedPath(std::string &path); +extern void Load_Language(std::string name), GetExpandedPath(std::string &path); extern void MAPPER_AutoType(std::vector &sequence, const uint32_t wait_ms, const uint32_t pace_ms, bool choice); extern void DOS_SetCountry(uint16_t countryNo), DOSV_FillScreen(void); std::string GetDOSBoxXPath(bool withexe=false); FILE *testLoadLangFile(const char *fname); Bitu DOS_ChangeCodepage(int32_t codepage, const char* codepagefile); -bool CheckDBCSCP(int32_t codepage); +bool CheckDBCSCP(int32_t codepage), SwitchLanguage(int oldcp, int newcp, bool confirm); static int32_t lastsetcp = 0; +bool CHCP_changed = false; /* support functions */ static char empty_char = 0; @@ -4530,8 +4531,18 @@ extern Bitu DOS_LoadKeyboardLayout(const char * layoutname, int32_t codepage, co void runRescan(const char *str), MSG_Init(), JFONT_Init(), InitFontHandle(), ShutFontHandle(), initcodepagefont(), DOSBox_SetSysMenu(); int toSetCodePage(DOS_Shell *shell, int newCP, int opt) { if((TTF_using() && isSupportedCP(newCP)) || !TTF_using()) { - if(!CheckDBCSCP(newCP)) DOS_ChangeCodepage(newCP, "auto"); - dos.loaded_codepage = newCP; + int32_t oldcp = dos.loaded_codepage; + Bitu keyb_error; + if (!CheckDBCSCP(newCP)){ + keyb_error = DOS_ChangeCodepage(newCP, "auto"); + if (keyb_error != KEYB_NOERROR) { + dos.loaded_codepage = oldcp; + return -1; + } + } + else { + dos.loaded_codepage = newCP; + } int missing = 0; #if defined(USE_TTF) missing = TTF_using() ? setTTFCodePage() : 0; @@ -4608,37 +4619,29 @@ void DOS_Shell::CMD_CHCP(char * args) { int32_t cp = dos.loaded_codepage; Bitu keyb_error; if(n == 1) { - if(CheckDBCSCP(newCP) -#if defined(USE_TTF) - || (ttf.inUse && (newCP >= 1250 && newCP <= 1258)) -#endif - ) { - missing = toSetCodePage(this, newCP, -1); - if(missing > -1) SwitchLanguage(cp, newCP, true); + if (!TTF_using() || (TTF_using() && isSupportedCP(newCP))){ + bool load_language = SwitchLanguage(cp, newCP, true); + CHCP_changed = true; + missing = toSetCodePage(this, newCP, load_language ? -1: -2); if(missing > 0) WriteOut(MSG_Get("SHELL_CMD_CHCP_MISSING"), missing); + else if(missing < 0) { + WriteOut(MSG_Get("SHELL_CMD_CHCP_INVALID"), StripArg(args)); + CHCP_changed = false; + return; + } } else { -#if defined(USE_TTF) - if(ttf.inUse && !isSupportedCP(newCP)) { + if(TTF_using() && !isSupportedCP(newCP)) { WriteOut(MSG_Get("SHELL_CMD_CHCP_INVALID"), StripArg(args)); LOG_MSG("CHCP: Codepage %d not supported for TTF output", newCP); - return; - } -#endif - keyb_error = DOS_ChangeCodepage(newCP, "auto"); - if(keyb_error == KEYB_NOERROR) { - SwitchLanguage(cp, newCP, true); -/** - if(layout_name != NULL) { - keyb_error = DOS_ChangeKeyboardLayout(layout_name, cp); - } -*/ } else { WriteOut(MSG_Get("SHELL_CMD_CHCP_INVALID"), StripArg(args)); - return; } + CHCP_changed = false; + return; } + CHCP_changed = false; WriteOut(MSG_Get("SHELL_CMD_CHCP_ACTIVE"), dos.loaded_codepage); } else if(n == 2 && strlen(buff)) { From a205b99ad3549175efd719515c56c7f2d869d88e Mon Sep 17 00:00:00 2001 From: maron2000 <68574602+maron2000@users.noreply.github.com> Date: Sat, 5 Oct 2024 14:18:46 +0900 Subject: [PATCH 05/10] Remove some redundant codes in CHCP command --- src/misc/programs.cpp | 4 +++- src/shell/shell_cmds.cpp | 30 ++++++------------------------ 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index ee27e63ae9..b5e4c986d0 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -726,7 +726,7 @@ void dos_ver_menu(bool start), ReloadMapper(Section_prop *sec, bool init), SetGa bool set_ver(char *s), GFX_IsFullscreen(void); void Load_Language(std::string name) { - if (control->opt_lang != "") control->opt_lang = name; + control->opt_lang = name; MSG_Init(); #if DOSBOXMENU_TYPE == DOSBOXMENU_HMENU || DOSBOXMENU_TYPE == DOSBOXMENU_NSMENU mainMenu.unbuild(); @@ -738,12 +738,14 @@ void Load_Language(std::string name) { #if defined(USE_TTF) if (TTF_using()) resetFontSize(); #endif +#if 0 if (!uselangcp && !incall) { int oldmsgcp = msgcodepage; msgcodepage = dos.loaded_codepage; SetKEYBCP(); msgcodepage = oldmsgcp; } +#endif } void ApplySetting(std::string pvar, std::string inputline, bool quiet) { diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index 189547bc14..adb98b2f75 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -4648,40 +4648,22 @@ void DOS_Shell::CMD_CHCP(char * args) { if(*buff == ':' && strchr(StripArg(args), ':')) { std::string name = buff + 1; if(name.empty() && iter != langcp_map.end()) name = iter->second; - if(CheckDBCSCP(newCP)) { + if(!TTF_using() || (TTF_using() && isSupportedCP(newCP))) { + CHCP_changed = true; missing = toSetCodePage(this, newCP, -1); - if(missing > -1) SwitchLanguage(cp, newCP, true); if(missing > 0) WriteOut(MSG_Get("SHELL_CMD_CHCP_MISSING"), missing); - } -#if defined(USE_TTF) - else if(ttf.inUse) { - if(newCP >= 1250 && newCP <= 1258) { - missing = toSetCodePage(this, newCP, -1); - if(missing > -1) SwitchLanguage(cp, newCP, true); - if(missing > 0) WriteOut(MSG_Get("SHELL_CMD_CHCP_MISSING"), missing); - } - else if(!isSupportedCP(newCP)) { + else if(missing < 0) { WriteOut(MSG_Get("SHELL_CMD_CHCP_INVALID"), StripArg(args)); - LOG_MSG("CHCP: Codepage %d not supported for TTF output", newCP); + CHCP_changed = false; return; } } -#endif - else { - keyb_error = DOS_ChangeCodepage(newCP, "auto"); - if(keyb_error == KEYB_NOERROR) { - if(layout_name != NULL) { - keyb_error = DOS_ChangeKeyboardLayout(layout_name, cp); - } - } - else - WriteOut(MSG_Get("SHELL_CMD_CHCP_INVALID"), StripArg(args)); - } if(name.size() && dos.loaded_codepage == newCP) { SetVal("dosbox", "language", name); Load_Language(name); } WriteOut(MSG_Get("SHELL_CMD_CHCP_ACTIVE"), dos.loaded_codepage); + CHCP_changed = false; return; } #if defined(USE_TTF) @@ -4706,7 +4688,7 @@ void DOS_Shell::CMD_CHCP(char * args) { FILE* file = fopen(cpfile.c_str(), "r"); /* should check the result */ std::string exepath = GetDOSBoxXPath(); if(!file && exepath.size()) file = fopen((exepath + CROSS_FILESPLIT + cpfile).c_str(), "r"); - if(file && newCP > 0 && newCP != 932 && newCP != 936 && newCP != 949 && newCP != 950 && newCP != 951) { + if(file && newCP > 0 && !CheckDBCSCP(newCP)) { altcp = newCP; char line[256], * l = line; while(fgets(line, sizeof(line), file)) { From 0be59ed77a2117e64202abf662da24acfc75994a Mon Sep 17 00:00:00 2001 From: maron2000 <68574602+maron2000@users.noreply.github.com> Date: Sat, 5 Oct 2024 16:09:29 +0900 Subject: [PATCH 06/10] Fix build error --- src/dos/dos_keyboard_layout.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 0c88e72dc7..c9a362e5e2 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1448,11 +1448,11 @@ class DOS_KeyboardLayout: public Module_base { const Section_prop* section = static_cast(configuration); const char * layoutname=section->Get_string("keyboardlayout"); dos.loaded_codepage = GetDefaultCP(); // default codepage already initialized - int tocp=!stricmp(layoutname, "jp")||IS_JDOSV?932:(!stricmp(layoutname, "ko")||IS_KDOSV?949:(!stricmp(layoutname, "tw")||!stricmp(layoutname, "hk")||!stricmp(layoutname, "zht")||IS_TDOSV?950:(!stricmp(layoutname, "cn")||!stricmp(layoutname, "zh")||!stricmp(layoutname, "zhs")||IS_PDOSV?936:(!stricmp(layoutname, "us")?437:0)))); + int tocp=!strcmp(layoutname, "jp")||IS_JDOSV?932:(!strcmp(layoutname, "ko")||IS_KDOSV?949:(!strcmp(layoutname, "tw")||!strcmp(layoutname, "hk")||!strcmp(layoutname, "zht")||IS_TDOSV?950:(!strcmp(layoutname, "cn")||!strcmp(layoutname, "zh")||!strcmp(layoutname, "zhs")||IS_PDOSV?936:(!strcmp(layoutname, "us")?437:0)))); #if defined(WIN32) if (dos.loaded_codepage == 932 && !IS_PC98_ARCH && GetKeyboardType(0) == 7 && !strcmp(layoutname, "auto")) layoutname = "jp106"; #endif - if (tocp && stricmp(layoutname, "jp106") && stricmp(layoutname, "jp") && stricmp(layoutname, "ko") && stricmp(layoutname, "cn") && stricmp(layoutname, "hk") && stricmp(layoutname, "tw")) layoutname="us"; + if (tocp && strcmp(layoutname, "jp106") && strcmp(layoutname, "jp") && strcmp(layoutname, "ko") && strcmp(layoutname, "cn") && strcmp(layoutname, "hk") && strcmp(layoutname, "tw")) layoutname="us"; #if defined(USE_TTF) if (TTF_using()) setTTFCodePage(); else @@ -1702,11 +1702,11 @@ class DOS_KeyboardLayout: public Module_base { /* if (strncmp(layoutname,"auto",4) && strncmp(layoutname,"none",4)) { LOG_MSG("Loading DOS keyboard layout %s ...",layoutname); } */ - if(!stricmp(layoutname, "cn") || !stricmp(layoutname, "hk") || !stricmp(layoutname, "tw") || !stricmp(layoutname, "ko")) { + if(!strcmp(layoutname, "cn") || !strcmp(layoutname, "hk") || !strcmp(layoutname, "tw") || !strcmp(layoutname, "ko")) { loaded_layout->read_keyboard_file("us", 437); - if(!stricmp(layoutname, "cn")) dos.loaded_codepage = 936; - if(!stricmp(layoutname, "hk") || !stricmp(layoutname, "tw")) dos.loaded_codepage = 950; - if(!stricmp(layoutname, "ko")) dos.loaded_codepage = 949; + if(!strcmp(layoutname, "cn")) dos.loaded_codepage = 936; + if(!strcmp(layoutname, "hk") || !strcmp(layoutname, "tw")) dos.loaded_codepage = 950; + if(!strcmp(layoutname, "ko")) dos.loaded_codepage = 949; } if (!tocp && loaded_layout->read_keyboard_file(layoutname, dos.loaded_codepage)) { if (strncmp(layoutname,"auto",4)) { @@ -1720,14 +1720,14 @@ class DOS_KeyboardLayout: public Module_base { } if (tocp && !IS_PC98_ARCH) { uint16_t cpbak = dos.loaded_codepage; - if((dos.loaded_codepage == 932 || tocp == 932) && (!stricmp(layoutname, "jp106") || !stricmp(layoutname, "jp"))) loaded_layout->read_keyboard_file(layoutname, 932); - if(!stricmp(layoutname, "ko") || !stricmp(layoutname, "cn") || !stricmp(layoutname, "tw") || !stricmp(layoutname, "hk")) { + if((dos.loaded_codepage == 932 || tocp == 932) && (!strcmp(layoutname, "jp106") || !strcmp(layoutname, "jp"))) loaded_layout->read_keyboard_file(layoutname, 932); + if(!strcmp(layoutname, "ko") || !strcmp(layoutname, "cn") || !strcmp(layoutname, "tw") || !strcmp(layoutname, "hk")) { loaded_layout->read_keyboard_file("us", 437); dos.loaded_codepage = tocp; } if (!TTF_using() || (TTF_using() && isSupportedCP(tocp))){ - toSetCodePage(NULL, msgcodepage ? msgcodepage : tocp, -2); + toSetCodePage(NULL, msgcodepage ? msgcodepage : tocp, msgcodepage ? -1: -2); runRescan("-A -Q"); #if C_OPENGL && DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW if (OpenGL_using() && control->opt_lang.size() && lastcp && lastcp != dos.loaded_codepage) From cbecf9eba0f91b0d3c4e27d24508c00c4030164a Mon Sep 17 00:00:00 2001 From: maron2000 <68574602+maron2000@users.noreply.github.com> Date: Sat, 5 Oct 2024 16:10:12 +0900 Subject: [PATCH 07/10] Fix switching codepage on launch --- src/misc/messages.cpp | 23 +++-------------------- src/misc/programs.cpp | 2 +- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index f92043d62c..b2799e252a 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -397,26 +397,9 @@ void LoadMessageFile(const char * fname) { menu_update_autocycle(); update_bindbutton_text(); dos.loaded_codepage=cp; - if (loadlangcp && msgcodepage>0 && isSupportedCP(msgcodepage) && msgcodepage != dos.loaded_codepage) { - ShutFontHandle(); - if(CheckDBCSCP(msgcodepage)) { - dos.loaded_codepage = msgcodepage; - InitFontHandle(); - JFONT_Init(); - } - if (!IS_DOSV && !IS_JEGA_ARCH) { -#if defined(USE_TTF) - if (ttf.inUse) toSetCodePage(NULL, msgcodepage, -2); else -#endif - { - dos.loaded_codepage = msgcodepage; - DOSBox_SetSysMenu(); -#if C_OPENGL && DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW - if (OpenGL_using() && control->opt_lang.size() && lastcp && lastcp != dos.loaded_codepage) - UpdateSDLDrawTexture(); -#endif - } - SetKEYBCP(); + if (loadlangcp && msgcodepage>0) { + if(!IS_DOSV && !IS_JEGA_ARCH) { + toSetCodePage(NULL, msgcodepage, -1); } } refreshExtChar(); diff --git a/src/misc/programs.cpp b/src/misc/programs.cpp index b5e4c986d0..df6de1691c 100644 --- a/src/misc/programs.cpp +++ b/src/misc/programs.cpp @@ -726,7 +726,7 @@ void dos_ver_menu(bool start), ReloadMapper(Section_prop *sec, bool init), SetGa bool set_ver(char *s), GFX_IsFullscreen(void); void Load_Language(std::string name) { - control->opt_lang = name; + if(control->opt_lang != "") control->opt_lang = name; MSG_Init(); #if DOSBOXMENU_TYPE == DOSBOXMENU_HMENU || DOSBOXMENU_TYPE == DOSBOXMENU_NSMENU mainMenu.unbuild(); From 860f01b985c60807bbaac98857859f248d5d8d79 Mon Sep 17 00:00:00 2001 From: maron2000 <68574602+maron2000@users.noreply.github.com> Date: Sat, 5 Oct 2024 16:17:12 +0900 Subject: [PATCH 08/10] Always switch codepages for DBCS language files --- src/misc/messages.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index b2799e252a..f1f52d2567 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -335,7 +335,7 @@ void LoadMessageFile(const char * fname) { } else { std::string msg = "The specified language file uses code page " + std::to_string(c) + ". Do you want to change to this code page accordingly?"; - if(c != dos.loaded_codepage && (control->opt_langcp || uselangcp || !CHCP_changed || !loadlang || (loadlang && systemmessagebox("DOSBox-X language file", msg.c_str(), "yesno", "question", 1)))){ + if(c != dos.loaded_codepage && (control->opt_langcp || uselangcp || !CHCP_changed || CheckDBCSCP(c) || !loadlang || (loadlang && systemmessagebox("DOSBox-X language file", msg.c_str(), "yesno", "question", 1)))) { loadlangcp = true; msgcodepage = c; dos.loaded_codepage = c; From c58d4dc1945d2ec45620d0c4d2f7de458709be9f Mon Sep 17 00:00:00 2001 From: maron2000 <68574602+maron2000@users.noreply.github.com> Date: Wed, 9 Oct 2024 23:42:36 +0900 Subject: [PATCH 09/10] Fix loading DBCS language files on launch --- src/dos/dos_keyboard_layout.cpp | 10 ++++---- src/misc/messages.cpp | 6 +++-- src/shell/shell.cpp | 41 +++++++++++---------------------- 3 files changed, 23 insertions(+), 34 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index c9a362e5e2..18ed7baa1d 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1142,7 +1142,7 @@ Bitu keyboard_layout::read_codepage_file(const char* codepage_file_name, int32_t uint16_t seg=0; uint16_t size=0x1500; - if (!DOS_AllocateMemory(&seg,&size)) E_Exit("Not enough free low memory to unpack data"); + if (!DOS_AllocateMemory(&seg, &size)) E_Exit("Not enough free low memory to unpack data"); MEM_BlockWrite(((unsigned int)seg<<4u)+0x100u,cpi_buf,size_of_cpxdata); // setup segments @@ -1704,9 +1704,9 @@ class DOS_KeyboardLayout: public Module_base { } */ if(!strcmp(layoutname, "cn") || !strcmp(layoutname, "hk") || !strcmp(layoutname, "tw") || !strcmp(layoutname, "ko")) { loaded_layout->read_keyboard_file("us", 437); - if(!strcmp(layoutname, "cn")) dos.loaded_codepage = 936; - if(!strcmp(layoutname, "hk") || !strcmp(layoutname, "tw")) dos.loaded_codepage = 950; - if(!strcmp(layoutname, "ko")) dos.loaded_codepage = 949; + if(!strcmp(layoutname, "cn")) tocp = 936; + if(!strcmp(layoutname, "hk") || !strcmp(layoutname, "tw")) tocp = 950; + if(!strcmp(layoutname, "ko")) tocp = 949; } if (!tocp && loaded_layout->read_keyboard_file(layoutname, dos.loaded_codepage)) { if (strncmp(layoutname,"auto",4)) { @@ -1718,7 +1718,7 @@ class DOS_KeyboardLayout: public Module_base { LOG_MSG("DOS keyboard layout loaded with main language code %s for layout %s",lcode,layoutname); } } - if (tocp && !IS_PC98_ARCH) { + if ((tocp || msgcodepage) && !IS_PC98_ARCH) { uint16_t cpbak = dos.loaded_codepage; if((dos.loaded_codepage == 932 || tocp == 932) && (!strcmp(layoutname, "jp106") || !strcmp(layoutname, "jp"))) loaded_layout->read_keyboard_file(layoutname, 932); if(!strcmp(layoutname, "ko") || !strcmp(layoutname, "cn") || !strcmp(layoutname, "tw") || !strcmp(layoutname, "hk")) { diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index f1f52d2567..6f9c1557c1 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -52,7 +52,9 @@ extern const char * RunningProgram; Bitu DOS_ChangeKeyboardLayout(const char* layoutname, int32_t codepage); Bitu DOS_ChangeCodepage(int32_t codepage, const char* codepagefile); Bitu DOS_LoadKeyboardLayout(const char* layoutname, int32_t codepage, const char* codepagefile); +const char* DOS_GetLoadedLayout(void); bool CheckDBCSCP(int32_t codepage); +void MSG_Init(void); #define LINE_IN_MAXLEN 2048 @@ -214,7 +216,6 @@ bool CheckDBCSCP(int32_t codepage) { else return false; } -void MSG_Init(void); void SetKEYBCP() { if (IS_PC98_ARCH || IS_JEGA_ARCH || IS_DOSV || dos_kernel_disabled || !strcmp(RunningProgram, "LOADLIN")) return; Bitu return_code; @@ -398,7 +399,8 @@ void LoadMessageFile(const char * fname) { update_bindbutton_text(); dos.loaded_codepage=cp; if (loadlangcp && msgcodepage>0) { - if(!IS_DOSV && !IS_JEGA_ARCH) { + const char* layoutname = DOS_GetLoadedLayout(); + if(!IS_DOSV && !IS_JEGA_ARCH && layoutname != NULL) { toSetCodePage(NULL, msgcodepage, -1); } } diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index eb16b07e72..b09ea77122 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -55,7 +55,7 @@ extern bool shell_keyboard_flush; extern bool dos_shell_running_program, mountwarning, winautorun; extern bool startcmd, startwait, startquiet, internal_program; extern bool addovl, addipx, addne2k, enableime, showdbcs; -extern bool halfwidthkana, force_conversion, gbk; +extern bool halfwidthkana, force_conversion, gbk, uselangcp; extern const char* RunningProgram; extern int enablelfn, msgcodepage, lastmsgcp; extern uint16_t countryNo; @@ -80,7 +80,7 @@ void DOS_SetCountry(uint16_t countryNo); bool SwitchLanguage(int oldcp, int newcp, bool confirm); void CALLBACK_DeAllocate(Bitu in), DOSBox_ConsolePauseWait(); void GFX_SetTitle(int32_t cycles, int frameskip, Bits timing, bool paused); -bool isDBCSCP(), InitCodePage(), isKanji1(uint8_t chr), shiftjis_lead_byte(int c), sdl_wait_on_error(); +bool isDBCSCP(), InitCodePage(), isKanji1(uint8_t chr), shiftjis_lead_byte(int c), sdl_wait_on_error(), CheckDBCSCP(int32_t codepage), TTF_using(void); Bitu call_shellstop = 0; /* Larger scope so shell_del autoexec can use it to @@ -862,34 +862,21 @@ void DOS_Shell::Prepare(void) { if (r!=NULL) *r=0; country = atoi(trim(countrystr)); int32_t newCP = r==NULL||IS_PC98_ARCH||IS_JEGA_ARCH||IS_DOSV?dos.loaded_codepage:atoi(trim(r+1)); - if (control->opt_langcp && msgcodepage>0 && isSupportedCP(msgcodepage) && msgcodepage != newCP) - newCP = msgcodepage; if (r!=NULL) *r=','; if (!IS_PC98_ARCH&&!IS_JEGA_ARCH) { -#if defined(USE_TTF) - if (ttf.inUse) { - if (newCP) { - int missing = toSetCodePage(this, newCP, control->opt_fastlaunch?1:0); - WriteOut(MSG_Get("SHELL_CMD_CHCP_ACTIVE"), dos.loaded_codepage); - if (missing > 0) WriteOut(MSG_Get("SHELL_CMD_CHCP_MISSING"), missing); - } - else if (r!=NULL) WriteOut(MSG_Get("SHELL_CMD_CHCP_INVALID"), trim(r+1)); - } else -#endif - if (!newCP && IS_DOSV) { - if (IS_JDOSV) newCP=932; - else if (IS_PDOSV) newCP=936; - else if (IS_KDOSV) newCP=949; - else if (IS_TDOSV) newCP=950; + if(!newCP && IS_DOSV) { + if(IS_JDOSV) newCP = 932; + else if(IS_PDOSV) newCP = 936; + else if(IS_KDOSV) newCP = 949; + else if(IS_TDOSV) newCP = 950; + } + if((control->opt_langcp && msgcodepage > 0 ) || CheckDBCSCP(msgcodepage)|| msgcodepage == dos.loaded_codepage) newCP = msgcodepage; + if (newCP != dos.loaded_codepage && (!TTF_using() || (TTF_using() && isSupportedCP(newCP)))) { + int missing = toSetCodePage(this, newCP, control->opt_fastlaunch?1:0); + //WriteOut(MSG_Get("SHELL_CMD_CHCP_ACTIVE"), dos.loaded_codepage); + if (missing > 0) WriteOut(MSG_Get("SHELL_CMD_CHCP_MISSING"), missing); + else if (missing < 0) WriteOut(MSG_Get("SHELL_CMD_CHCP_INVALID"), newCP); } - const char* name = DOS_GetLoadedLayout(); - if (newCP==932||newCP==936||newCP==949||newCP==950||newCP==951) { - dos.loaded_codepage=newCP; - SetupDBCSTable(); - runRescan("-A -Q"); - DOSBox_SetSysMenu(); - } else if (control->opt_langcp && !name && (layout.empty() || layout=="auto")) - SetKEYBCP(); } //if (lastmsgcp && lastmsgcp != dos.loaded_codepage) SwitchLanguage(lastmsgcp, dos.loaded_codepage, true); if (msgcodepage && msgcodepage != dos.loaded_codepage) SwitchLanguage(dos.loaded_codepage, msgcodepage, true); From c766244d45ed4de653ca98a83dc2f88c2b79a8ce Mon Sep 17 00:00:00 2001 From: maron2000 <68574602+maron2000@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:01:29 +0900 Subject: [PATCH 10/10] Fix initial rescan command slow on launch --- src/dos/dos_keyboard_layout.cpp | 1 - src/misc/messages.cpp | 5 +++-- src/shell/shell.cpp | 20 +++++++++++--------- src/shell/shell_cmds.cpp | 4 ++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/dos/dos_keyboard_layout.cpp b/src/dos/dos_keyboard_layout.cpp index 18ed7baa1d..05d37e352d 100644 --- a/src/dos/dos_keyboard_layout.cpp +++ b/src/dos/dos_keyboard_layout.cpp @@ -1728,7 +1728,6 @@ class DOS_KeyboardLayout: public Module_base { if (!TTF_using() || (TTF_using() && isSupportedCP(tocp))){ toSetCodePage(NULL, msgcodepage ? msgcodepage : tocp, msgcodepage ? -1: -2); - runRescan("-A -Q"); #if C_OPENGL && DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW if (OpenGL_using() && control->opt_lang.size() && lastcp && lastcp != dos.loaded_codepage) UpdateSDLDrawTexture(); diff --git a/src/misc/messages.cpp b/src/misc/messages.cpp index 6f9c1557c1..85a1a06d60 100644 --- a/src/misc/messages.cpp +++ b/src/misc/messages.cpp @@ -94,7 +94,7 @@ void MSG_Replace(const char * _name, const char* _val) { bool InitCodePage() { if (!dos.loaded_codepage || dos_kernel_disabled || force_conversion) { - if (((control->opt_langcp && msgcodepage != dos.loaded_codepage) || uselangcp) && msgcodepage>0 && isSupportedCP(msgcodepage)) { + if (((control->opt_langcp && msgcodepage != dos.loaded_codepage) || uselangcp) && msgcodepage>0) { dos.loaded_codepage = msgcodepage; return true; } @@ -103,10 +103,11 @@ bool InitCodePage() { char *countrystr = (char *)section->Get_string("country"), *r=strchr(countrystr, ','); if (r!=NULL && *(r+1)) { int cp = atoi(trim(r+1)); - if (cp>0 && isSupportedCP(cp)) { + if(cp > 0 && isSupportedCP(cp) && !msgcodepage) { dos.loaded_codepage = cp; return true; } + else dos.loaded_codepage = msgcodepage; } } if (msgcodepage>0) { diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index b09ea77122..9de39e4edf 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -685,7 +685,7 @@ const char *ParseMsg(const char *msg) { #if defined(USE_TTF) && halfwidthkana #endif - && InitCodePage() && dos.loaded_codepage==932) uselowbox = true; + && dos.loaded_codepage==932) uselowbox = true; force_conversion = false; dos.loaded_codepage=cp; if (uselowbox || IS_JEGA_ARCH || IS_JDOSV) { @@ -816,6 +816,7 @@ void showWelcome(Program *shell) { } } +bool finish_prepare = false; void DOS_Shell::Prepare(void) { if (this == first_shell) { Section_prop *section = static_cast(control->GetSection("dosbox")); @@ -872,20 +873,19 @@ void DOS_Shell::Prepare(void) { } if((control->opt_langcp && msgcodepage > 0 ) || CheckDBCSCP(msgcodepage)|| msgcodepage == dos.loaded_codepage) newCP = msgcodepage; if (newCP != dos.loaded_codepage && (!TTF_using() || (TTF_using() && isSupportedCP(newCP)))) { - int missing = toSetCodePage(this, newCP, control->opt_fastlaunch?1:0); + int missing = toSetCodePage(this, newCP, msgcodepage?-1:control->opt_fastlaunch?1:-2); //WriteOut(MSG_Get("SHELL_CMD_CHCP_ACTIVE"), dos.loaded_codepage); if (missing > 0) WriteOut(MSG_Get("SHELL_CMD_CHCP_MISSING"), missing); else if (missing < 0) WriteOut(MSG_Get("SHELL_CMD_CHCP_INVALID"), newCP); } } - //if (lastmsgcp && lastmsgcp != dos.loaded_codepage) SwitchLanguage(lastmsgcp, dos.loaded_codepage, true); - if (msgcodepage && msgcodepage != dos.loaded_codepage) SwitchLanguage(dos.loaded_codepage, msgcodepage, true); } if (country>0&&!control->opt_noconfig) { countryNo = country; DOS_SetCountry(countryNo); } - const char * extra = section->data.c_str(); + runRescan("-A -Q"); + const char * extra = section->data.c_str(); if (extra&&!control->opt_securemode&&!control->SecureMode()&&!control->opt_noconfig) { std::string vstr; std::istringstream in(extra); @@ -977,10 +977,12 @@ void DOS_Shell::Prepare(void) { internal_program = true; VFILE_Register("4DOS.INI",(uint8_t *)i4dos_data,(uint32_t)strlen(i4dos_data), "/4DOS/"); internal_program = false; - unsigned int cp=dos.loaded_codepage; - if (!dos.loaded_codepage) InitCodePage(); - initcodepagefont(); - dos.loaded_codepage=cp; + //unsigned int cp=dos.loaded_codepage; + //if (!dos.loaded_codepage) InitCodePage(); + //initcodepagefont(); + //dos.loaded_codepage=cp; + finish_prepare = true; + } #if (defined(WIN32) && !defined(HX_DOS) || defined(LINUX) && C_X11 || defined(MACOSX)) && (defined(C_SDL2) || defined(SDL_DOSBOX_X_SPECIAL)) if (enableime) SetIMPosition(); diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index adb98b2f75..b922940131 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -4526,7 +4526,7 @@ void DOS_Shell::CMD_COUNTRY(char * args) { return; } -extern bool jfont_init, isDBCSCP(); +extern bool jfont_init, finish_prepare, isDBCSCP(); extern Bitu DOS_LoadKeyboardLayout(const char * layoutname, int32_t codepage, const char * codepagefile); void runRescan(const char *str), MSG_Init(), JFONT_Init(), InitFontHandle(), ShutFontHandle(), initcodepagefont(), DOSBox_SetSysMenu(); int toSetCodePage(DOS_Shell *shell, int newCP, int opt) { @@ -4567,7 +4567,7 @@ int toSetCodePage(DOS_Shell *shell, int newCP, int opt) { JFONT_Init(); SetupDBCSTable(); } - runRescan("-A -Q"); + if (finish_prepare) runRescan("-A -Q"); #if defined(USE_TTF) if ((opt==-1||opt==-2)&&TTF_using()) { Section_prop * ttf_section = static_cast(control->GetSection("ttf"));