00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include "precomp.h"
00020
#pragma hdrstop
00021
00022
00023
#if defined(FE_SB)
00024
00025
00026
NTSTATUS
00027
CreateEUDC(
00028
PCONSOLE_INFORMATION Console
00029 )
00030 {
00031
PEUDC_INFORMATION EudcInfo;
00032
00033 EudcInfo =
ConsoleHeapAlloc(
MAKE_TAG( EUDC_TAG ),
sizeof(
EUDC_INFORMATION));
00034
if (EudcInfo ==
NULL) {
00035
return STATUS_NO_MEMORY;
00036 }
00037 EudcInfo->
LocalVDMEudcMode =
FALSE;
00038 EudcInfo->
LocalKeisenEudcMode =
FALSE;
00039 EudcInfo->
hDCLocalEudc =
NULL;
00040 EudcInfo->
hBmpLocalEudc =
NULL;
00041 EudcInfo->
EudcFontCacheInformation =
NULL;
00042 EudcInfo->
LocalEudcSize.X =
DEFAULT_EUDCSIZE;
00043 EudcInfo->
LocalEudcSize.Y =
DEFAULT_EUDCSIZE;
00044
00045 RtlZeroMemory(&EudcInfo->
EudcRange,
sizeof(EudcInfo->
EudcRange));
00046 EudcInfo->
EudcRangeSize =
GetSystemEUDCRangeW(EudcInfo->
EudcRange, EUDC_RANGE_SIZE);
00047
if (EudcInfo->
EudcRangeSize)
00048 EudcInfo->
EudcRangeSize--;
00049
00050 Console->EudcInformation = (PVOID)EudcInfo;
00051
00052
return STATUS_SUCCESS;
00053 }
00054
00055
VOID
00056
DeleteEUDC(
00057
PCONSOLE_INFORMATION Console
00058 )
00059 {
00060
PEUDC_INFORMATION EudcInfo = Console->EudcInformation;
00061
00062
if (EudcInfo->
hDCLocalEudc) {
00063
ReleaseDC(NULL, EudcInfo->
hDCLocalEudc);
00064 DeleteObject(EudcInfo->
hBmpLocalEudc);
00065 }
00066 }
00067
00068
NTSTATUS
00069
RegisterLocalEUDC(
00070 IN
PCONSOLE_INFORMATION Console,
00071 IN WCHAR wChar,
00072 IN COORD FontSize,
00073 IN PCHAR FontFace
00074 )
00075 {
00076
NTSTATUS Status;
00077 PCHAR TmpBuff;
00078
DWORD BuffSize;
00079
PEUDC_INFORMATION EudcInfo = Console->EudcInformation;
00080
00081
if (EudcInfo->
EudcFontCacheInformation ==
NULL) {
00082
Status = (
NTSTATUS)
CreateFontCache(&(
PFONT_CACHE_INFORMATION)EudcInfo->
EudcFontCacheInformation);
00083
if (!
NT_SUCCESS(Status)) {
00084 RIPMSG1(RIP_WARNING,
"RegisterLocalEUDC: failed in CreateFontCache, Status is %08x", Status);
00085
return Status;
00086 }
00087 }
00088
00089 BuffSize =
CalcBitmapBufferSize(FontSize, BYTE_ALIGN);
00090 TmpBuff = FontFace;
00091
while(BuffSize--)
00092 *TmpBuff++ = ~(*TmpBuff);
00093
00094
return (
NTSTATUS)
SetFontImage(EudcInfo->
EudcFontCacheInformation,
00095 wChar,
00096 FontSize,
00097 BYTE_ALIGN,
00098 FontFace
00099 );
00100 }
00101
00102
VOID
00103
FreeLocalEUDC(
00104 IN
PCONSOLE_INFORMATION Console
00105 )
00106 {
00107
PEUDC_INFORMATION EudcInfo = Console->EudcInformation;
00108
00109
if (EudcInfo->
EudcFontCacheInformation !=
NULL) {
00110
DestroyFontCache((
PFONT_CACHE_INFORMATION)EudcInfo->
EudcFontCacheInformation);
00111 }
00112
00113
ConsoleHeapFree(Console->EudcInformation);
00114 }
00115
00116
VOID
00117
GetFitLocalEUDCFont(
00118 IN
PCONSOLE_INFORMATION Console,
00119 IN WCHAR wChar
00120 )
00121 {
00122
NTSTATUS Status;
00123 COORD FontSize;
00124
VOID *FontFace;
00125
DWORD BuffSize;
00126
PEUDC_INFORMATION EudcInfo;
00127
PFONT_CACHE_INFORMATION FontCacheInfo;
00128
00129 EudcInfo = (
PEUDC_INFORMATION)Console->EudcInformation;
00130 FontCacheInfo = (
PFONT_CACHE_INFORMATION)EudcInfo->
EudcFontCacheInformation;
00131
00132 FontSize =
CON_FONTSIZE(Console);
00133
if (IsConsoleFullWidth(Console->hDC,Console->OutputCP,wChar)) {
00134 FontSize.X *= 2;
00135 }
00136
00137
if ((EudcInfo->
LocalEudcSize.X != FontSize.X) ||
00138 (EudcInfo->
LocalEudcSize.Y != FontSize.Y) ) {
00139
ReleaseDC(NULL, EudcInfo->
hDCLocalEudc);
00140 DeleteObject(EudcInfo->
hBmpLocalEudc);
00141 EudcInfo->
hDCLocalEudc = CreateCompatibleDC(Console->hDC);
00142 EudcInfo->
hBmpLocalEudc = CreateBitmap(FontSize.X, FontSize.Y, BITMAP_PLANES, BITMAP_BITS_PIXEL, NULL);
00143 SelectObject(EudcInfo->
hDCLocalEudc, EudcInfo->
hBmpLocalEudc);
00144 EudcInfo->
LocalEudcSize.X = FontSize.X;
00145 EudcInfo->
LocalEudcSize.Y = FontSize.Y;
00146 }
00147
00148 BuffSize =
CalcBitmapBufferSize(FontSize,WORD_ALIGN);
00149 FontFace =
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ), BuffSize);
00150
if (FontFace ==
NULL) {
00151 RIPMSG0(RIP_WARNING,
"GetFitLocalEUDCFont: failed to allocate FontFace.");
00152
return;
00153 }
00154
00155
Status = (
NTSTATUS)
GetFontImage(FontCacheInfo,
00156 wChar,
00157 FontSize,
00158 WORD_ALIGN,
00159 FontFace
00160 );
00161
if (!
NT_SUCCESS(Status)) {
00162
00163
if ((Console->Flags &
CONSOLE_VDM_REGISTERED) &&
00164 FontSize.X ==
DefaultFontSize.X * 2 &&
00165 FontSize.Y ==
DefaultFontSize.Y &&
00166 FontSize.X ==
VDM_EUDC_FONT_SIZE_X &&
00167 FontSize.Y - 2 ==
VDM_EUDC_FONT_SIZE_Y ) {
00168
00169 COORD TmpFontSize = FontSize;
00170
00171 TmpFontSize.Y -= 2;
00172 RtlFillMemory((PVOID)FontFace,BuffSize,0xff);
00173
Status = (
NTSTATUS)
GetFontImage(FontCacheInfo,
00174 wChar,
00175 TmpFontSize,
00176 WORD_ALIGN,
00177 FontFace
00178 );
00179
if (!
NT_SUCCESS(Status)) {
00180
Status = (
NTSTATUS)
GetStretchedFontImage(FontCacheInfo,
00181 wChar,
00182 FontSize,
00183 WORD_ALIGN,
00184 FontFace
00185 );
00186
if (!
NT_SUCCESS(Status)) {
00187
ASSERT(FALSE);
00188
ConsoleHeapFree(FontFace);
00189
return;
00190 }
00191 }
00192 }
00193
else {
00194
Status = (
NTSTATUS)
GetStretchedFontImage(FontCacheInfo,
00195 wChar,
00196 FontSize,
00197 WORD_ALIGN,
00198 FontFace
00199 );
00200
if (!
NT_SUCCESS(Status)) {
00201
ASSERT(FALSE);
00202
ConsoleHeapFree(FontFace);
00203
return;
00204 }
00205 }
00206
00207
Status = (
NTSTATUS)
SetFontImage(FontCacheInfo,
00208 wChar,
00209 FontSize,
00210 WORD_ALIGN,
00211 FontFace
00212 );
00213
if (!
NT_SUCCESS(Status)) {
00214
ASSERT(FALSE);
00215
ConsoleHeapFree(FontFace);
00216
return;
00217 }
00218 }
00219
00220 SetBitmapBits(EudcInfo->
hBmpLocalEudc, BuffSize, (PBYTE)FontFace);
00221
00222
ConsoleHeapFree(FontFace);
00223 }
00224
00225
BOOL
00226
IsEudcRange(
00227 IN
PCONSOLE_INFORMATION Console,
00228 IN WCHAR ch
00229 )
00230 {
00231
PEUDC_INFORMATION EudcInfo;
00232
int i;
00233
00234 EudcInfo = (
PEUDC_INFORMATION)Console->EudcInformation;
00235
00236
for (i=0; i < EudcInfo->
EudcRangeSize; i+=2)
00237 {
00238
if (EudcInfo->
EudcRange[i] <= ch && ch <= EudcInfo->
EudcRange[i+1])
00239
return TRUE;
00240 }
00241
return FALSE;
00242 }
00243
00244
BOOL
00245
CheckEudcRangeInString(
00246 IN
PCONSOLE_INFORMATION Console,
00247 IN PWCHAR string,
00248 IN SHORT len,
00249 OUT SHORT *find_pos
00250 )
00251 {
00252
SHORT i;
00253
00254
for (i = 0; i < len; i++,string++)
00255 {
00256
if (
IsEudcRange(Console, *string))
00257 {
00258 *find_pos = i;
00259
return TRUE;
00260 }
00261 }
00262
return FALSE;
00263 }
00264
00265 LPWSTR
00266 SkipWhite(
00267 LPWSTR lpch
00268 )
00269 {
00270
if( lpch ==
NULL )
00271
return(
NULL );
00272
00273
for ( ; ; lpch++ )
00274 {
00275
switch (*lpch)
00276 {
00277
case L' ':
00278
case L'\t':
00279
case L'\r':
00280
case L'\n':
00281
break;
00282
00283
default:
00284
return(lpch);
00285 }
00286 }
00287 }
00288
00289 WORD
00290
ConvertStringToHex(
00291 LPWSTR lpch,
00292 LPWSTR *endptr
00293 )
00294 {
00295 WCHAR ch;
00296 WORD val = 0;
00297
00298
while ( (ch=*lpch) !=
L'\0')
00299 {
00300
if (
L'0' <= ch && ch <=
L'9')
00301 val = (val << 4) + (ch -
L'0');
00302
else if (
L'A' <= ch && ch <=
L'F')
00303 val = (val << 4) + (ch -
L'A' + 10);
00304
else if (
L'a' <= ch && ch <=
L'f')
00305 val = (val << 4) + (ch -
L'a' + 10);
00306
else
00307
break;
00308
00309 lpch++;
00310 }
00311
00312
if (endptr)
00313 *endptr = lpch;
00314
return val;
00315 }
00316
00317 WORD
00318
ConvertStringToDec(
00319 LPWSTR lpch,
00320 LPWSTR *endptr
00321 )
00322 {
00323 WCHAR ch;
00324 WORD val = 0;
00325
00326
while ( (ch=*lpch) !=
L'\0')
00327 {
00328
if (
L'0' <= ch && ch <=
L'9')
00329 val = (val * 10) + (ch -
L'0');
00330
else
00331
break;
00332
00333 lpch++;
00334 }
00335
00336
if (endptr)
00337 *endptr = lpch;
00338
return val;
00339 }
00340
00341
INT
00342
GetSystemEUDCRangeW(
00343 WORD *pwEUDCCharTable,
00344 UINT cjSize
00345 )
00346 {
00347
NTSTATUS Status;
00348 HKEY hkRegistry;
00349 UNICODE_STRING SystemACPString;
00350 WCHAR awcACP[10];
00351 WCHAR awchBuffer[ 512 ];
00352
INT iEntry = 0;
00353
00354
00355
00356
00357
00358
00359
00360
if( ( pwEUDCCharTable ==
NULL && cjSize != 0 ) ||
00361 ( pwEUDCCharTable !=
NULL && cjSize == 0 )
00362 )
00363 {
00364
return 0;
00365 }
00366
00367
00368
00369
00370
Status =
MyRegOpenKey(NULL,
00371 MACHINE_REGISTRY_EUDC,
00372 &hkRegistry);
00373
if (!
NT_SUCCESS( Status )) {
00374
DBGPRINT((
"CONSRV:GetSystemEUDCRangeW() RegOpenKeyExW( %ws ) fail\n", MACHINE_REGISTRY_EUDC));
00375
return 0;
00376 }
00377
00378
00379
00380
00381 SystemACPString.Length = 0;
00382 SystemACPString.MaximumLength =
sizeof(awcACP)/
sizeof(WCHAR);
00383 SystemACPString.Buffer = awcACP;
00384
RtlIntegerToUnicodeString( WINDOWSCP, 10, &SystemACPString );
00385
00386
00387
00388
00389
Status =
MyRegQueryValue(hkRegistry,
00390 awcACP,
00391
sizeof(awchBuffer), (PBYTE)&awchBuffer);
00392
if (!
NT_SUCCESS( Status )) {
00393
DBGPRINT((
"CONSRV:GetSystemEUDCRangeW NtQueryValueKey failed %ws\n", awcACP));
00394 }
00395
else {
00396 LPWSTR pwszBuf = awchBuffer;
00397
00398
00399
00400
00401
while( pwszBuf !=
NULL && *pwszBuf !=
L'\0' )
00402 {
00403 WORD ch1,ch2;
00404
00405
00406
00407 pwszBuf = SkipWhite( pwszBuf );
00408 ch1 =
ConvertStringToHex( pwszBuf, &pwszBuf );
00409
00410 pwszBuf = SkipWhite( pwszBuf );
00411
if (*pwszBuf !=
L'-')
00412 {
00413
DBGPRINT((
"CONSRV:GetSystemEUDCRangeW() Invalid format\n"));
00414
return( 0 );
00415 }
00416
00417
00418
00419 pwszBuf = SkipWhite( pwszBuf+1 );
00420 ch2 =
ConvertStringToHex( pwszBuf, &pwszBuf );
00421
00422
00423
00424
if( ch1 > ch2 )
00425 {
00426
DBGPRINT((
"CONSRV:GetSystemEUDCRangeW() Sort order is incorrect\n"));
00427
return( 0 );
00428 }
00429
00430
00431
00432 pwszBuf = SkipWhite( pwszBuf );
00433
if( *pwszBuf ==
L',' )
00434 pwszBuf = SkipWhite( pwszBuf+1 );
00435
00436
00437
00438 iEntry ++;
00439
00440
00441
00442
00443
00444
00445
if( cjSize >= 3 )
00446 {
00447 *pwEUDCCharTable++ = ch1;
00448 *pwEUDCCharTable++ = ch2;
00449 cjSize -= 2;
00450 }
00451 }
00452
00453 *pwEUDCCharTable =
L'\0';
00454
00455
00456 iEntry = iEntry * 2 + 1;
00457
00458 }
00459
00460
00461
00462
00463
NtClose( hkRegistry );
00464
00465
return (iEntry);
00466 }
00467
#endif