/*++ Copyright (c) 1992 Microsoft Corporation Module Name: dbcs.c Abstract: This module contains the code for console DBCS font dialog Author: kazum Feb-27-1995 Revision History: --*/ #include "precomp.h" #pragma hdrstop #if defined(FE_SB) SINGLE_LIST_ENTRY gTTFontList; // This list contain TTFONTLIST data. UINT OEMCP; BOOL gfFESystem; WORD ConvertStringToDec( LPTSTR lpch, LPTSTR *endptr ) { TCHAR ch; WORD val = 0; while ( (ch=*lpch) != TEXT('\0')) { if (TEXT('0') <= ch && ch <= TEXT('9')) val = (val * 10) + (ch - TEXT('0')); else break; lpch++; } if (endptr) *endptr = lpch; return val; } WORD ConvertStringToHex( LPTSTR lpch, LPTSTR *endptr ) { TCHAR ch; WORD val = 0; while ( (ch=*lpch) != TEXT('\0')) { if (TEXT('0') <= ch && ch <= TEXT('9')) val = (val << 4) + (ch - TEXT('0')); else if (TEXT('A') <= ch && ch <= TEXT('F')) val = (val << 4) + (ch - TEXT('A') + 10); else if (TEXT('a') <= ch && ch <= TEXT('f')) val = (val << 4) + (ch - TEXT('a') + 10); else break; lpch++; } if (endptr) *endptr = lpch; return val; } NTSTATUS MakeAltRasterFont( UINT CodePage, COORD *AltFontSize, BYTE *AltFontFamily, ULONG *AltFontIndex, LPTSTR AltFaceName ) { DWORD i; DWORD Find; ULONG FontIndex; COORD FontSize = FontInfo[DefaultFontIndex].Size; COORD FontDelta; BOOL fDbcsCharSet = IS_ANY_DBCS_CHARSET( CodePageToCharSet( CodePage ) ); FontIndex = 0; Find = (DWORD)-1; for (i=0; i < NumberOfFonts; i++) { if (!TM_IS_TT_FONT(FontInfo[i].Family) && IS_ANY_DBCS_CHARSET(FontInfo[i].tmCharSet) == fDbcsCharSet ) { FontDelta.X = (SHORT)abs(FontSize.X - FontInfo[i].Size.X); FontDelta.Y = (SHORT)abs(FontSize.Y - FontInfo[i].Size.Y); if (Find > (DWORD)(FontDelta.X + FontDelta.Y)) { Find = (DWORD)(FontDelta.X + FontDelta.Y); FontIndex = i; } } } *AltFontIndex = FontIndex; _tcscpy(AltFaceName, FontInfo[*AltFontIndex].FaceName); *AltFontSize = FontInfo[*AltFontIndex].Size; *AltFontFamily = FontInfo[*AltFontIndex].Family; DBGFONTS(("MakeAltRasterFont : AltFontIndex = %ld\n", *AltFontIndex)); return STATUS_SUCCESS; } NTSTATUS InitializeDbcsMisc( VOID ) { HANDLE hkRegistry = NULL; NTSTATUS Status; WCHAR awchValue[ 512 ]; WCHAR awchData[ 512 ]; DWORD dwIndex; LPWSTR pwsz; gTTFontList.Next = NULL; Status = MyRegOpenKey(NULL, MACHINE_REGISTRY_CONSOLE_TTFONT, &hkRegistry); if (!NT_SUCCESS( Status )) { DBGPRINT(("CONSRV: NtOpenKey failed %ws\n", MACHINE_REGISTRY_CONSOLE)); } else { LPTTFONTLIST pTTFontList; for( dwIndex = 0; ; dwIndex++) { Status = MyRegEnumValue(hkRegistry, dwIndex, sizeof(awchValue), (LPWSTR)&awchValue, sizeof(awchData), (PBYTE)&awchData); if (!NT_SUCCESS( Status )) { break; } pTTFontList = LocalAlloc(LPTR, sizeof(TTFONTLIST)); if (pTTFontList == NULL) { break; } pTTFontList->List.Next = NULL; pTTFontList->CodePage = ConvertStringToDec(awchValue, NULL); pwsz = awchData; if (*pwsz == BOLD_MARK) { pTTFontList->fDisableBold = TRUE; pwsz++; } else pTTFontList->fDisableBold = FALSE; _tcscpy(pTTFontList->FaceName1, pwsz); pwsz += _tcslen(pwsz) + 1; if (*pwsz == BOLD_MARK) { pTTFontList->fDisableBold = TRUE; pwsz++; } _tcscpy(pTTFontList->FaceName2, pwsz); PushEntryList(&gTTFontList, &(pTTFontList->List)); } NtClose(hkRegistry); } ASSERT(OEMCP != 0); // OEMCP must be initialized so far by CPL_INIT ASSERT(IsFarEastCP(OEMCP) == gfFESystem); return STATUS_SUCCESS; } BYTE CodePageToCharSet( UINT CodePage ) { CHARSETINFO csi; if (!TranslateCharsetInfo((DWORD *)IntToPtr(CodePage), &csi, TCI_SRCCODEPAGE)) csi.ciCharset = OEM_CHARSET; return (BYTE)csi.ciCharset; } LPTTFONTLIST SearchTTFont( LPTSTR ptszFace, BOOL fCodePage, UINT CodePage ) { PSINGLE_LIST_ENTRY pTemp = gTTFontList.Next; if (ptszFace) { while (pTemp != NULL) { LPTTFONTLIST pTTFontList = (LPTTFONTLIST)pTemp; if (wcscmp(ptszFace, pTTFontList->FaceName1) == 0 || wcscmp(ptszFace, pTTFontList->FaceName2) == 0 ) { if (fCodePage) if (pTTFontList->CodePage == CodePage ) return pTTFontList; else return NULL; else return pTTFontList; } pTemp = pTemp->Next; } } return NULL; } BOOL IsAvailableTTFont( LPTSTR ptszFace ) { if (SearchTTFont(ptszFace, FALSE, 0)) return TRUE; else return FALSE; } BOOL IsAvailableTTFontCP( LPTSTR ptszFace, UINT CodePage ) { if (SearchTTFont(ptszFace, TRUE, CodePage)) return TRUE; else return FALSE; } BOOL IsDisableBoldTTFont( LPTSTR ptszFace ) { LPTTFONTLIST pTTFontList; pTTFontList = SearchTTFont(ptszFace, FALSE, 0); if (pTTFontList != NULL) return pTTFontList->fDisableBold; else return FALSE; } LPTSTR GetAltFaceName( LPTSTR ptszFace ) { LPTTFONTLIST pTTFontList; pTTFontList = SearchTTFont(ptszFace, FALSE, 0); if (pTTFontList != NULL) { if (wcscmp(ptszFace, pTTFontList->FaceName1) == 0) { return pTTFontList->FaceName2; } if (wcscmp(ptszFace, pTTFontList->FaceName2) == 0) { return pTTFontList->FaceName1; } return NULL; } else return NULL; } NTSTATUS DestroyDbcsMisc( VOID ) { while (gTTFontList.Next != NULL) { LPTTFONTLIST pTTFontList = (LPTTFONTLIST)PopEntryList(&gTTFontList); if (pTTFontList != NULL) LocalFree(pTTFontList); } return STATUS_SUCCESS; } typedef struct _LC_List { struct _LC_List* Next; BOOL FindFlag; TCHAR LC_String[9]; } LC_List, *PLC_List; static PLC_List LocaleList = NULL; BOOL CALLBACK EnumProc( LPTSTR LC_String ) { PLC_List TmpList; if (_tcslen(LC_String) <= (sizeof(LocaleList->LC_String)/sizeof(TCHAR))-1) { TmpList = (PLC_List)&LocaleList; while(TmpList->Next != NULL) TmpList = TmpList->Next; TmpList->Next = LocalAlloc(LPTR, sizeof(LC_List)); if (TmpList->Next != NULL) { TmpList = TmpList->Next; _tcscpy(TmpList->LC_String, LC_String); } } return TRUE; } int LanguageListCreate( HWND hDlg, UINT CodePage ) /*++ Initializes the Language list by enumerating all Locale Information. Returns --*/ { HWND hWndLanguageCombo; HANDLE hkRegistry = NULL; NTSTATUS Status; WCHAR awchValue[ 512 ]; WCHAR awchData[ 512 ]; DWORD dwIndex; PLC_List TmpList; WORD LangID; LCID Locale; int cchData; LONG lListIndex; UINT cp; BOOL fRet; CPINFOEX cpinfo; /* * Enumrate system locale information */ EnumSystemLocales( EnumProc, CP_INSTALLED ); /* * Enumrate registory key */ Status = MyRegOpenKey(NULL, MACHINE_REGISTRY_CONSOLE_NLS, &hkRegistry); if (!NT_SUCCESS( Status )) { DBGPRINT(("CONSRV: NtOpenKey failed %ws\n", MACHINE_REGISTRY_CONSOLE)); } else { for( dwIndex = 0; ; dwIndex++) { Status = MyRegEnumValue(hkRegistry, dwIndex, sizeof(awchValue), (LPWSTR)&awchValue, sizeof(awchData), (PBYTE)&awchData); if (!NT_SUCCESS( Status )) { break; } TmpList = (PLC_List)&LocaleList; while(TmpList->Next != NULL) { TmpList = TmpList->Next; if (_tcscmp(awchValue, TmpList->LC_String) == 0) { TmpList->FindFlag = TRUE; break; } } } NtClose(hkRegistry); } /* * Create ComboBox items */ hWndLanguageCombo = GetDlgItem(hDlg, IDD_LANGUAGELIST); SendMessage(hWndLanguageCombo, CB_RESETCONTENT, 0, 0L); TmpList = (PLC_List)&LocaleList; while(TmpList->Next != NULL) { TmpList = TmpList->Next; if (TmpList->FindFlag) { LangID = ConvertStringToHex(TmpList->LC_String, NULL); Locale = MAKELCID( LangID, SORT_DEFAULT ); cchData = GetLocaleInfo(Locale, LOCALE_IDEFAULTCODEPAGE, awchData, sizeof(awchData)/sizeof(TCHAR)); if (cchData) { awchData[cchData] = TEXT('\0'); cp = ConvertStringToDec(awchData, NULL); if ( (IS_ANY_DBCS_CHARSET(CodePageToCharSet(cp)) && GetOEMCP() == cp) || (!IS_ANY_DBCS_CHARSET(CodePageToCharSet(cp))) ) { fRet = GetCPInfoEx(cp, 0, &cpinfo); if (fRet) { lListIndex = (LONG)SendMessage(hWndLanguageCombo, CB_ADDSTRING, 0, (LPARAM)cpinfo.CodePageName); SendMessage(hWndLanguageCombo, CB_SETITEMDATA, (DWORD)lListIndex, cp); if (CodePage == cp) { SendMessage(hWndLanguageCombo, CB_SETCURSEL, lListIndex, 0L); } } } } } } { PLC_List Tmp; TmpList = (PLC_List)&LocaleList; while(TmpList->Next != NULL) { Tmp = TmpList; TmpList = TmpList->Next; if (Tmp != (PLC_List)&LocaleList) LocalFree(Tmp); } LocaleList = NULL; } /* * Get the LocaleIndex from the currently selected item. * (i will be LB_ERR if no currently selected item). */ lListIndex = (LONG)SendMessage(hWndLanguageCombo, CB_GETCURSEL, 0, 0L); return (LONG)SendMessage(hWndLanguageCombo, CB_GETITEMDATA, lListIndex, 0L); } // v-HirShi Nov.20.1996 int LanguageDisplay( HWND hDlg, UINT CodePage ) /*++ Display the Language . Returns --*/ { HWND hWndLanguageDisp; HANDLE hkRegistry = NULL; NTSTATUS Status; WCHAR awchValue[ 512 ]; WCHAR awchData[ 512 ]; DWORD dwIndex; PLC_List TmpList; WORD LangID; LCID Locale; int cchData; LONG lListIndex; UINT cp; BOOL fRet; CPINFOEX cpinfo; /* * Enumrate system locale information */ EnumSystemLocales( EnumProc, CP_INSTALLED ); /* * Enumrate registory key */ Status = MyRegOpenKey(NULL, MACHINE_REGISTRY_CONSOLE_NLS, &hkRegistry); if (!NT_SUCCESS( Status )) { DBGPRINT(("CONSRV: NtOpenKey failed %ws\n", MACHINE_REGISTRY_CONSOLE)); } else { for( dwIndex = 0; ; dwIndex++) { Status = MyRegEnumValue(hkRegistry, dwIndex, sizeof(awchValue), (LPWSTR)&awchValue, sizeof(awchData), (PBYTE)&awchData); if (!NT_SUCCESS( Status )) { break; } TmpList = (PLC_List)&LocaleList; while(TmpList->Next != NULL) { TmpList = TmpList->Next; if (_tcscmp(awchValue, TmpList->LC_String) == 0) { TmpList->FindFlag = TRUE; break; } } } NtClose(hkRegistry); } /* * Display Language */ TmpList = (PLC_List)&LocaleList; while(TmpList->Next != NULL) { TmpList = TmpList->Next; if (TmpList->FindFlag) { LangID = ConvertStringToHex(TmpList->LC_String, NULL); Locale = MAKELCID( LangID, SORT_DEFAULT ); cchData = GetLocaleInfo(Locale, LOCALE_IDEFAULTCODEPAGE, awchData, sizeof(awchData)/sizeof(TCHAR)); if (cchData) { awchData[cchData] = TEXT('\0'); cp = ConvertStringToDec(awchData, NULL); fRet = GetCPInfoEx(cp, 0, &cpinfo); if (fRet) { if (CodePage == cp) { hWndLanguageDisp = GetDlgItem(hDlg, IDD_LANGUAGE); SetWindowText(hWndLanguageDisp, cpinfo.CodePageName); } } } } } { PLC_List Tmp; TmpList = (PLC_List)&LocaleList; while(TmpList->Next != NULL) { Tmp = TmpList; TmpList = TmpList->Next; if (Tmp != (PLC_List)&LocaleList) LocalFree(Tmp); } LocaleList = NULL; } return TRUE; } #endif // FE_SB