windows-nt/Source/XPSP1/NT/shell/osshell/control/console/dbcs.c
2020-09-26 16:20:57 +08:00

610 lines
14 KiB
C

/*++
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