Skip to content

Commit

Permalink
Merge pull request joncampbell123#5235 from maron2000/fix_lang
Browse files Browse the repository at this point in the history
Fixes corrupted display when loading language files at launch.
  • Loading branch information
joncampbell123 authored Oct 14, 2024
2 parents 3c9a960 + c766244 commit e1bfb97
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 179 deletions.
2 changes: 1 addition & 1 deletion src/dos/dos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
94 changes: 43 additions & 51 deletions src/dos/dos_keyboard_layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -1143,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
Expand Down Expand Up @@ -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
Expand All @@ -1451,7 +1452,7 @@ class DOS_KeyboardLayout: public Module_base {
#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 && 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
Expand Down Expand Up @@ -1487,11 +1488,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 = "tw";
tocp = 950;
break;
case 1029: // Czech Republic, CP 852, Alt CP 850
layoutname = "cz243";
break;
Expand Down Expand Up @@ -1533,17 +1532,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 = "ko";
tocp = 949;
break;
case 1043: // Netherlands, CP 850, Alt CP 437
layoutname = "nl";
wants_dos_codepage = GetDefaultCP();
Expand Down Expand Up @@ -1610,11 +1605,9 @@ class DOS_KeyboardLayout: public Module_base {
layoutname = "hy";
break; */
case 2052: // China, CP 936
if (tryconvertcp == 1) {
layoutname = "us";
tocp = 936;
}
break;
layoutname = "cn";
tocp = 936;
break;
case 2055: // Swiss-German, CP 850, Alt CP 437
layoutname = "sg";
wants_dos_codepage = GetDefaultCP();
Expand All @@ -1639,11 +1632,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 = "hk";
tocp = 950;
break;
case 3081: // Australia, CP 850, Alt CP 437
layoutname = "us";
wants_dos_codepage = GetDefaultCP();
Expand Down Expand Up @@ -1681,13 +1672,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;
Expand All @@ -1706,8 +1702,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(!strcmp(layoutname, "cn") || !strcmp(layoutname, "hk") || !strcmp(layoutname, "tw") || !strcmp(layoutname, "ko")) {
loaded_layout->read_keyboard_file("us", 437);
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)) {
LOG_MSG("Error loading keyboard layout %s",layoutname);
}
} else if (!tocp) {
Expand All @@ -1716,32 +1718,22 @@ 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((dos.loaded_codepage == 932 || tocp == 932) && (!strcmp(layoutname, "jp106") || !strcmp(layoutname, "jp"))) loaded_layout->read_keyboard_file(layoutname, 932);

if ((tocp || msgcodepage) && !IS_PC98_ARCH) {
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) && (!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;
MSG_Init();
DOSBox_SetSysMenu();
if (!jfont_init && isDBCSCP()) JFONT_Init();
SetupDBCSTable();
runRescan("-A -Q");
}

if (!TTF_using() || (TTF_using() && isSupportedCP(tocp))){
toSetCodePage(NULL, msgcodepage ? msgcodepage : tocp, msgcodepage ? -1: -2);
#if C_OPENGL && DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
if (OpenGL_using() && control->opt_lang.size() && lastcp && lastcp != dos.loaded_codepage)
UpdateSDLDrawTexture();
#endif
}
}
if(msgcodepage) {
SwitchLanguage(dos.loaded_codepage, msgcodepage, false);
DOS_ChangeCodepage(msgcodepage, "auto");
}
}

~DOS_KeyboardLayout(){
Expand Down
8 changes: 5 additions & 3 deletions src/dos/dos_programs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -206,22 +207,23 @@ 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())) {
FILE *file = testLoadLangFile(langnew.c_str());
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;
Expand Down
8 changes: 4 additions & 4 deletions src/dos/drive_local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/ints/bios_disk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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++) {
Expand Down
50 changes: 23 additions & 27 deletions src/misc/messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,15 @@ 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);
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

Expand Down Expand Up @@ -91,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;
}
Expand All @@ -100,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) {
Expand Down Expand Up @@ -204,12 +208,20 @@ void AddMessages() {
MSG_Add("AUTO_CYCLE_OFF","Auto cycles [off]");
}

void MSG_Init(void);
// 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 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();
Expand Down Expand Up @@ -325,7 +337,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 || CheckDBCSCP(c) || !loadlang || (loadlang && systemmessagebox("DOSBox-X language file", msg.c_str(), "yesno", "question", 1)))) {
loadlangcp = true;
msgcodepage = c;
dos.loaded_codepage = c;
Expand Down Expand Up @@ -387,26 +399,10 @@ 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(msgcodepage == 932 || msgcodepage == 936 || msgcodepage == 949 || msgcodepage == 950 || msgcodepage == 951) {
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) {
const char* layoutname = DOS_GetLoadedLayout();
if(!IS_DOSV && !IS_JEGA_ARCH && layoutname != NULL) {
toSetCodePage(NULL, msgcodepage, -1);
}
}
refreshExtChar();
Expand Down Expand Up @@ -486,7 +482,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();
Expand Down
Loading

0 comments on commit e1bfb97

Please sign in to comment.