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