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 
#pragma alloc_text(FE_TEXT, CheckBisectStringA)
00023 
#pragma alloc_text(FE_TEXT, BisectWrite)
00024 
#pragma alloc_text(FE_TEXT, BisectClipbrd)
00025 
#pragma alloc_text(FE_TEXT, BisectWriteAttr)
00026 
#pragma alloc_text(FE_TEXT, IsDBCSLeadByteConsole)
00027 
#pragma alloc_text(FE_TEXT, TextOutEverything)
00028 
#pragma alloc_text(FE_TEXT, TextOutCommonLVB)
00029 
#ifdef i386
00030 
#pragma alloc_text(FE_TEXT, RealUnicodeToNEC_OS2_Unicode)
00031 
#pragma alloc_text(FE_TEXT, InitializeNEC_OS2_CP)
00032 
#endif
00033 
#pragma alloc_text(FE_TEXT, ProcessCreateConsoleIME)
00034 
#pragma alloc_text(FE_TEXT, InitConsoleIMEStuff)
00035 
#pragma alloc_text(FE_TEXT, WaitConsoleIMEStuff)
00036 
#pragma alloc_text(FE_TEXT, ConSrvRegisterConsoleIME)
00037 
#pragma alloc_text(FE_TEXT, RemoveConsoleIME)
00038 
#pragma alloc_text(FE_TEXT, ConsoleImeMessagePump)
00039 
#pragma alloc_text(FE_TEXT, RegisterKeisenOfTTFont)
00040 
#pragma alloc_text(FE_TEXT, ImmConversionToConsole)
00041 
#pragma alloc_text(FE_TEXT, ImmConversionFromConsole)
00042 
#pragma alloc_text(FE_TEXT, TranslateUnicodeToOem)
00043 
00044 
00045 
#if defined(FE_SB)
00046 
00047 SINGLE_LIST_ENTRY gTTFontList;    
00048 
00049 
#if defined(i386)
00050 
ULONG  gdwMachineId;
00051 
#endif
00052 
00053 LPTHREAD_START_ROUTINE 
ConsoleIMERoutine;  
00054 CRITICAL_SECTION ConIMEInitWindowsLock;
00055 
00056 
#if defined(i386)
00057 
00058 
00059 
00060 
00061 PCPTABLEINFO pGlyph_NEC_OS2_CP;
00062 
PUSHORT pGlyph_NEC_OS2_Table;
00063 
#endif // i386
00064 
00065 
00066 
00067 
#if defined(FE_IME)
00068 
00069 
00070 
#if defined(i386)
00071 
NTSTATUS
00072 ImeWmFullScreen(
00073     IN BOOL Foreground,
00074     IN 
PCONSOLE_INFORMATION Console,
00075     IN 
PSCREEN_INFORMATION ScreenInfo
00076     )
00077 {
00078     
NTSTATUS Status = STATUS_SUCCESS;
00079 
00080     
if(Foreground) {
00081         ULONG ModeIndex;
00082         PCONVERSIONAREA_INFORMATION ConvAreaInfo;
00083 
00084         
if (!
NT_SUCCESS(ConsoleImeMessagePump(Console,
00085                               CONIME_SETFOCUS,
00086                               (WPARAM)Console->ConsoleHandle,
00087                               (LPARAM)Console->hklActive
00088                              ))) {
00089             
return STATUS_INVALID_HANDLE;
00090         }
00091 
00092         
if (ConvAreaInfo = Console->ConsoleIme.ConvAreaRoot) {
00093             
if (!(ScreenInfo->Flags & 
CONSOLE_GRAPHICS_BUFFER))
00094                 ModeIndex = ScreenInfo->BufferInfo.TextInfo.ModeIndex;
00095             
else if (!(Console->CurrentScreenBuffer->Flags & 
CONSOLE_GRAPHICS_BUFFER))
00096                 ModeIndex = Console->CurrentScreenBuffer->BufferInfo.TextInfo.ModeIndex;
00097             
else
00098                 ModeIndex = 0;
00099             
do {
00100 
#ifdef FE_SB
00101 
                
00102                 
if (! (ConvAreaInfo->ScreenBuffer->Flags & 
CONSOLE_GRAPHICS_BUFFER))
00103                     ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.ModeIndex = ModeIndex;
00104                 
else
00105                     
ASSERT(FALSE);
00106 
#else
00107 
                ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.ModeIndex = ModeIndex;
00108 
#endif
00109 
            } 
while (ConvAreaInfo = ConvAreaInfo->ConvAreaNext);
00110         }
00111     }
00112     
else
00113     {
00114         
if (!
NT_SUCCESS(ConsoleImeMessagePump(Console,
00115                               CONIME_KILLFOCUS,
00116                               (WPARAM)Console->ConsoleHandle,
00117                               (LPARAM)Console->hklActive
00118                              ))) {
00119             
return STATUS_INVALID_HANDLE;
00120         }
00121     }
00122 
00123     
return Status;
00124 }
00125 
#endif // i386
00126 
00127 
00128 
00129 
00130 
NTSTATUS
00131 GetImeKeyState(
00132     IN 
PCONSOLE_INFORMATION Console,
00133     IN PDWORD pdwConversion
00134     )
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 {
00151     
DWORD dwDummy;
00152 
00153     
00154 
00155 
00156 
00157 
00158 
00159     
if (pdwConversion == 
NULL) {
00160         pdwConversion = &dwDummy;
00161     }
00162 
00163     
if (Console->InputBuffer.ImeMode.Disable)
00164     {
00165         *pdwConversion = 0;
00166     }
00167     
else
00168     {
00169         
PINPUT_THREAD_INFO InputThreadInfo;     
00170 
00171         InputThreadInfo = TlsGetValue(InputThreadTlsIndex);
00172 
00173         
if (InputThreadInfo != 
NULL)
00174         {
00175             LRESULT lResult;
00176 
00177             
00178 
00179 
00180 
00181 
00182             
if (!
NT_SUCCESS(ConsoleImeMessagePumpWorker(Console,
00183                     CONIME_GET_NLSMODE,
00184                     (WPARAM)Console->ConsoleHandle,
00185                     (LPARAM)0,
00186                     &lResult))) {
00187 
00188                 *pdwConversion = 
IME_CMODE_DISABLE;
00189                 
return STATUS_INVALID_HANDLE;
00190             }
00191 
00192 
00193             *pdwConversion = (
DWORD)lResult;
00194 
00195             
if (Console->InputBuffer.ImeMode.ReadyConversion == 
FALSE)
00196                 Console->InputBuffer.ImeMode.ReadyConversion = 
TRUE;
00197         }
00198         
else
00199         {
00200             
00201 
00202 
00203 
00204             
if (Console->InputBuffer.ImeMode.ReadyConversion == 
FALSE) {
00205                 *pdwConversion = 0;
00206                 
return STATUS_SUCCESS;
00207             }
00208 
00209             *pdwConversion = Console->InputBuffer.ImeMode.Conversion;
00210         }
00211 
00212 
00213         
if (*pdwConversion & 
IME_CMODE_OPEN)
00214             Console->InputBuffer.ImeMode.Open = 
TRUE;
00215         
else
00216             Console->InputBuffer.ImeMode.Open = 
FALSE;
00217         
if (*pdwConversion & 
IME_CMODE_DISABLE)
00218             Console->InputBuffer.ImeMode.Disable = 
TRUE;
00219         
else
00220             Console->InputBuffer.ImeMode.Disable = 
FALSE;
00221 
00222         Console->InputBuffer.ImeMode.Conversion = *pdwConversion;
00223 
00224     }
00225 
00226     
return STATUS_SUCCESS;
00227 }
00228 
00229 
00230 
00231 
00232 
NTSTATUS
00233 SetImeKeyState(
00234     IN 
PCONSOLE_INFORMATION Console,
00235     IN DWORD fdwConversion
00236     )
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 {
00255     PCONVERSIONAREA_INFORMATION ConvAreaInfo;
00256 
00257     
if ( (fdwConversion & 
IME_CMODE_DISABLE) && (! Console->InputBuffer.ImeMode.Disable) ) {
00258         Console->InputBuffer.ImeMode.Disable = 
TRUE;
00259         
if ( Console->InputBuffer.ImeMode.Open ) {
00260             ConvAreaInfo = Console->ConsoleIme.ConvAreaMode;
00261             
if (ConvAreaInfo)
00262                 ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
00263             ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
00264             
if (ConvAreaInfo)
00265                 ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
00266             
if (Console->InputBuffer.ImeMode.Open && CONSOLE_IS_DBCS_OUTPUTCP(Console))
00267                 ConsoleImePaint(Console, Console->ConsoleIme.ConvAreaRoot);
00268         }
00269     }
00270     
else if ( (! (fdwConversion & 
IME_CMODE_DISABLE)) && Console->InputBuffer.ImeMode.Disable) {
00271         Console->InputBuffer.ImeMode.Disable = 
FALSE;
00272         
if ( fdwConversion & 
IME_CMODE_OPEN ) {
00273             ConvAreaInfo = Console->ConsoleIme.ConvAreaMode;
00274             
if (ConvAreaInfo)
00275                 ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
00276             ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
00277             
if (ConvAreaInfo)
00278                 ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
00279             
if (Console->InputBuffer.ImeMode.Open && CONSOLE_IS_DBCS_OUTPUTCP(Console))
00280                 ConsoleImePaint(Console, Console->ConsoleIme.ConvAreaRoot);
00281         }
00282     }
00283     
else if ( (fdwConversion & 
IME_CMODE_DISABLE) && (Console->InputBuffer.ImeMode.Disable) ) {
00284         
return STATUS_SUCCESS;
00285     }
00286 
00287     
if ( (fdwConversion & 
IME_CMODE_OPEN) && (! Console->InputBuffer.ImeMode.Open)) {
00288         Console->InputBuffer.ImeMode.Open = 
TRUE;
00289     }
00290     
else if ( (! (fdwConversion & 
IME_CMODE_OPEN)) && Console->InputBuffer.ImeMode.Open) {
00291         Console->InputBuffer.ImeMode.Open = 
FALSE;
00292     }
00293 
00294     Console->InputBuffer.ImeMode.Conversion = fdwConversion;
00295 
00296     
if (Console->InputBuffer.ImeMode.ReadyConversion == 
FALSE)
00297         Console->InputBuffer.ImeMode.ReadyConversion = 
TRUE;
00298 
00299     
if (!
NT_SUCCESS(ConsoleImeMessagePump(Console,
00300                           CONIME_SET_NLSMODE,
00301                           (WPARAM)Console->ConsoleHandle,
00302                           (LPARAM)fdwConversion
00303                          ))) {
00304         
return STATUS_INVALID_HANDLE;
00305     }
00306 
00307     
return STATUS_SUCCESS;
00308 }
00309 
00310 
NTSTATUS
00311 SetImeCodePage(
00312     IN 
PCONSOLE_INFORMATION Console
00313     )
00314 {
00315     
DWORD CodePage = Console->OutputCP;
00316     
DWORD fdwConversion;
00317 
00318     
if (!CONSOLE_IS_DBCS_CP(Console))
00319     {
00320         
if (!
NT_SUCCESS(GetImeKeyState(Console, &fdwConversion))) {
00321             
return STATUS_INVALID_HANDLE;
00322         }
00323 
00324         fdwConversion |= 
IME_CMODE_DISABLE;
00325 
00326     }
00327     
else {
00328         fdwConversion = Console->InputBuffer.ImeMode.Conversion & ~
IME_CMODE_DISABLE;
00329     }
00330 
00331     
if (!
NT_SUCCESS(SetImeKeyState(Console, fdwConversion))) {
00332         
return STATUS_INVALID_HANDLE;
00333     }
00334 
00335     
if (
CONSOLE_IS_IME_ENABLED()) {
00336         
if (!
NT_SUCCESS(ConsoleImeMessagePump(Console,
00337                               CONIME_NOTIFY_CODEPAGE,
00338                               (WPARAM)Console->ConsoleHandle,
00339                               (LPARAM)MAKELPARAM(FALSE, CodePage)
00340                              ))) {
00341             
return STATUS_INVALID_HANDLE;
00342         }
00343     }
00344 
00345     
return STATUS_SUCCESS;
00346 }
00347 
00348 
NTSTATUS
00349 SetImeOutputCodePage(
00350     IN 
PCONSOLE_INFORMATION Console,
00351     IN 
PSCREEN_INFORMATION ScreenInfo,
00352     IN DWORD PrevCodePage
00353     )
00354 {
00355     
DWORD CodePage = Console->OutputCP;
00356 
00357     
00358     
if ((ScreenInfo->Flags & 
CONSOLE_TEXTMODE_BUFFER) &&
00359         (
IsAvailableFarEastCodePage(CodePage) || 
IsAvailableFarEastCodePage(PrevCodePage)))
00360     {
00361         
ConvertToCodePage(Console, PrevCodePage);
00362         
AdjustFont(Console, CodePage);
00363     }
00364     
00365 
#ifdef i386
00366 
    if ( (Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) &&
00367          !(ScreenInfo->Flags & 
CONSOLE_GRAPHICS_BUFFER))
00368     {
00369         SetROMFontCodePage(CodePage,
00370                            ScreenInfo->BufferInfo.TextInfo.ModeIndex);
00371         SetCursorInformationHW(ScreenInfo,
00372                         ScreenInfo->BufferInfo.TextInfo.CursorSize,
00373                         ScreenInfo->BufferInfo.TextInfo.CursorVisible);
00374         WriteRegionToScreenHW(ScreenInfo,
00375                 &ScreenInfo->Window);
00376     }
00377 
#endif
00378 
00379     
if (
CONSOLE_IS_IME_ENABLED()) {
00380         
if (!
NT_SUCCESS(ConsoleImeMessagePump(Console,
00381                               CONIME_NOTIFY_CODEPAGE,
00382                               (WPARAM)Console->ConsoleHandle,
00383                               (LPARAM)MAKELPARAM(TRUE, CodePage)
00384                              ))) {
00385             
return STATUS_INVALID_HANDLE;
00386         }
00387     }
00388 
00389     
return STATUS_SUCCESS;
00390 }
00391 
#endif // FE_IME
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
VOID
00410 
SetLineChar(
00411     IN 
PSCREEN_INFORMATION ScreenInfo
00412     )
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430 {
00431     
if (CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console))
00432     {
00433         
if (
OEMCP == 
JAPAN_CP || 
OEMCP == 
KOREAN_CP)
00434         {
00435             
00436 
00437 
00438 
00439 
00440             ScreenInfo->LineChar[UPPER_LEFT_CORNER]   = 0x0001;
00441             ScreenInfo->LineChar[UPPER_RIGHT_CORNER]  = 0x0002;
00442             ScreenInfo->LineChar[HORIZONTAL_LINE]     = 0x0006;
00443             ScreenInfo->LineChar[VERTICAL_LINE]       = 0x0005;
00444             ScreenInfo->LineChar[BOTTOM_LEFT_CORNER]  = 0x0003;
00445             ScreenInfo->LineChar[BOTTOM_RIGHT_CORNER] = 0x0004;
00446         }
00447         
else
00448         {
00449             
00450 
00451 
00452 
00453 
00454             ScreenInfo->LineChar[UPPER_LEFT_CORNER]   = 
L'+';
00455             ScreenInfo->LineChar[UPPER_RIGHT_CORNER]  = 
L'+';
00456             ScreenInfo->LineChar[HORIZONTAL_LINE]     = 
L'-';
00457             ScreenInfo->LineChar[VERTICAL_LINE]       = 
L'|';
00458             ScreenInfo->LineChar[BOTTOM_LEFT_CORNER]  = 
L'+';
00459             ScreenInfo->LineChar[BOTTOM_RIGHT_CORNER] = 
L'+';
00460         }
00461     }
00462     
else {
00463         ScreenInfo->LineChar[UPPER_LEFT_CORNER]   = 0x250c;
00464         ScreenInfo->LineChar[UPPER_RIGHT_CORNER]  = 0x2510;
00465         ScreenInfo->LineChar[HORIZONTAL_LINE]     = 0x2500;
00466         ScreenInfo->LineChar[VERTICAL_LINE]       = 0x2502;
00467         ScreenInfo->LineChar[BOTTOM_LEFT_CORNER]  = 0x2514;
00468         ScreenInfo->LineChar[BOTTOM_RIGHT_CORNER] = 0x2518;
00469     }
00470 }
00471 
00472 
BOOL
00473 
CheckBisectStringA(
00474     IN DWORD CodePage,
00475     IN PCHAR Buffer,
00476     IN DWORD NumBytes,
00477     IN LPCPINFO lpCPInfo
00478     )
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 {
00503     UNREFERENCED_PARAMETER(CodePage);
00504 
00505     
while(NumBytes) {
00506         
if (
IsDBCSLeadByteConsole(*Buffer,lpCPInfo)) {
00507             
if (NumBytes <= 1)
00508                 
return TRUE;
00509             
else {
00510                 
Buffer += 2;
00511                 NumBytes -= 2;
00512             }
00513         }
00514         
else {
00515             
Buffer++;
00516             NumBytes--;
00517         }
00518     }
00519     
return FALSE;
00520 }
00521 
00522 
00523 
00524 
VOID
00525 
BisectWrite(
00526     IN SHORT StringLength,
00527     IN COORD TargetPoint,
00528     IN 
PSCREEN_INFORMATION ScreenInfo
00529     )
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 {
00544     
SHORT RowIndex;
00545     
PROW Row;
00546     
PROW RowPrev;
00547     
PROW RowNext;
00548 
00549 
#if defined(DBG) && defined(DBG_KATTR)
00550 
    BeginKAttrCheck(ScreenInfo);
00551 
#endif
00552 
00553 
#ifdef FE_SB
00554 
    
00555     
ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER));
00556 
#endif
00557 
00558     RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->ScreenBufferSize.Y;
00559     Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
00560 
00561     
if (RowIndex > 0) {
00562         RowPrev = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex-1];
00563     } 
else {
00564         RowPrev = &ScreenInfo->BufferInfo.TextInfo.Rows[ScreenInfo->ScreenBufferSize.Y-1];
00565     }
00566 
00567     
if (RowIndex+1 < ScreenInfo->ScreenBufferSize.Y) {
00568         RowNext = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex+1];
00569     } 
else {
00570         RowNext = &ScreenInfo->BufferInfo.TextInfo.Rows[0];
00571     }
00572 
00573     
00574     
00575     
00576     
if (Row->
CharRow.KAttrs[TargetPoint.X] & ATTR_TRAILING_BYTE)
00577     {
00578         
if (TargetPoint.X == 0) {
00579             RowPrev->
CharRow.
Chars[ScreenInfo->ScreenBufferSize.X-1] = 
UNICODE_SPACE;
00580             RowPrev->
CharRow.KAttrs[ScreenInfo->ScreenBufferSize.X-1] = 0;
00581             ScreenInfo->BisectFlag |= BISECT_TOP;
00582         }
00583         
else {
00584             Row->
CharRow.
Chars[TargetPoint.X-1] = 
UNICODE_SPACE;
00585             Row->
CharRow.KAttrs[TargetPoint.X-1] = 0;
00586             ScreenInfo->BisectFlag |= BISECT_LEFT;
00587         }
00588     }
00589 
00590     
00591     
00592     
00593     
if (TargetPoint.X+
StringLength < ScreenInfo->ScreenBufferSize.X) {
00594         
if (Row->
CharRow.KAttrs[TargetPoint.X+
StringLength] & ATTR_TRAILING_BYTE)
00595           {
00596             Row->
CharRow.
Chars[TargetPoint.X+
StringLength] = 
UNICODE_SPACE;
00597             Row->
CharRow.KAttrs[TargetPoint.X+
StringLength] = 0;
00598             ScreenInfo->BisectFlag |= BISECT_RIGHT;
00599         }
00600     }
00601     
else if (TargetPoint.Y+1 < ScreenInfo->ScreenBufferSize.Y) {
00602         
if (RowNext->
CharRow.KAttrs[0] & ATTR_TRAILING_BYTE)
00603         {
00604             RowNext->
CharRow.
Chars[0] = 
UNICODE_SPACE;
00605             RowNext->
CharRow.KAttrs[0] = 0;
00606             ScreenInfo->BisectFlag |= BISECT_BOTTOM;
00607         }
00608     }
00609 }
00610 
00611 
VOID
00612 
BisectClipbrd(
00613     IN SHORT StringLength,
00614     IN COORD TargetPoint,
00615     IN 
PSCREEN_INFORMATION ScreenInfo,
00616     OUT PSMALL_RECT SmallRect
00617     )
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 
00631 {
00632     
SHORT RowIndex;
00633     
PROW Row;
00634     
PROW RowNext;
00635 
00636 
#if defined(DBG) && defined(DBG_KATTR)
00637 
00638 
#endif
00639 
00640 
#ifdef FE_SB
00641 
    
00642     
ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER));
00643 
#endif
00644 
00645     RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->ScreenBufferSize.Y;
00646     Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
00647 
00648     
if (RowIndex+1 < ScreenInfo->ScreenBufferSize.Y) {
00649         RowNext = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex+1];
00650     } 
else {
00651         RowNext = &ScreenInfo->BufferInfo.TextInfo.Rows[0];
00652     }
00653 
00654     
00655     
00656     
00657     
ASSERT(CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console));
00658     
if (Row->
CharRow.KAttrs[TargetPoint.X] & ATTR_TRAILING_BYTE)
00659     {
00660         
if (TargetPoint.X == 0) {
00661             SmallRect->Left++;
00662         }
00663         
else {
00664             SmallRect->Left--;
00665         }
00666     }
00667     
00668     
00669     
00670     
if (TargetPoint.X+
StringLength < ScreenInfo->ScreenBufferSize.X) {
00671         
if (Row->
CharRow.KAttrs[TargetPoint.X+
StringLength] & ATTR_TRAILING_BYTE)
00672         {
00673             SmallRect->Right++;
00674         }
00675     }
00676     
else if (TargetPoint.Y+1 < ScreenInfo->ScreenBufferSize.Y) {
00677         
if (RowNext->
CharRow.KAttrs[0] & ATTR_TRAILING_BYTE)
00678         {
00679             SmallRect->Right--;
00680         }
00681     }
00682 }
00683 
00684 
00685 
VOID
00686 
BisectWriteAttr(
00687     IN SHORT StringLength,
00688     IN COORD TargetPoint,
00689     IN 
PSCREEN_INFORMATION ScreenInfo
00690     )
00691 
00692 
00693 
00694 
00695 
00696 
00697 
00698 
00699 
00700 
00701 
00702 
00703 
00704 {
00705     
SHORT RowIndex;
00706     
PROW Row;
00707     
PROW RowNext;
00708 
00709 
#if defined(DBG) && defined(DBG_KATTR)
00710 
    BeginKAttrCheck(ScreenInfo);
00711 
#endif
00712 
00713 
#ifdef FE_SB
00714 
    
00715     
ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER));
00716 
#endif
00717 
00718     RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->ScreenBufferSize.Y;
00719     Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
00720 
00721     
if (RowIndex+1 < ScreenInfo->ScreenBufferSize.Y) {
00722         RowNext = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex+1];
00723     } 
else {
00724         RowNext = &ScreenInfo->BufferInfo.TextInfo.Rows[0];
00725     }
00726 
00727     
00728     
00729     
00730     
if (Row->
CharRow.KAttrs[TargetPoint.X] & ATTR_TRAILING_BYTE){
00731         
if (TargetPoint.X == 0) {
00732             ScreenInfo->BisectFlag |= BISECT_TOP;
00733         }
00734         
else {
00735             ScreenInfo->BisectFlag |= BISECT_LEFT;
00736         }
00737     }
00738 
00739     
00740     
00741     
00742     
if (TargetPoint.X+
StringLength < ScreenInfo->ScreenBufferSize.X) {
00743         
if (Row->
CharRow.KAttrs[TargetPoint.X+
StringLength] & ATTR_TRAILING_BYTE){
00744             ScreenInfo->BisectFlag |= BISECT_RIGHT;
00745         }
00746     }
00747     
else if (TargetPoint.Y+1 < ScreenInfo->ScreenBufferSize.Y) {
00748         
if (RowNext->
CharRow.KAttrs[0] & ATTR_TRAILING_BYTE){
00749             ScreenInfo->BisectFlag |= BISECT_BOTTOM;
00750         }
00751     }
00752 }
00753 
00754 
00755 
00756 
00757 
00758 
00759 
00760 
00761 
00762 
00763 
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771 
00772 
00773 
00774 
00775 
BOOL IsConsoleFullWidth(
00776     IN HDC hDC,
00777     IN DWORD CodePage,
00778     IN WCHAR wch
00779     )
00780 {
00781     
INT Width;
00782     TEXTMETRIC tmi;
00783 
00784     
if (! 
IsAvailableFarEastCodePage(CodePage))
00785         
return FALSE;
00786 
00787     
if (0x20 <= wch && wch <= 0x7e)
00788         
00789         
return FALSE;
00790     
else if (0x3041 <= wch && wch <= 0x3094)
00791         
00792         
return TRUE;
00793     
else if (0x30a1 <= wch && wch <= 0x30f6)
00794         
00795         
return TRUE;
00796     
else if (0x3105 <= wch && wch <= 0x312c)
00797         
00798         
return TRUE;
00799     
else if (0x3131 <= wch && wch <= 0x318e)
00800         
00801         
return TRUE;
00802     
else if (0xac00 <= wch && wch <= 0xd7a3)
00803         
00804         
return TRUE;
00805     
else if (0xff01 <= wch && wch <= 0xff5e)
00806         
00807         
return TRUE;
00808     
else if (0xff61 <= wch && wch <= 0xff9f)
00809         
00810         
return FALSE;
00811     
else if ( (0xffa0 <= wch && wch <= 0xffbe) ||
00812               (0xffc2 <= wch && wch <= 0xffc7) ||
00813               (0xffca <= wch && wch <= 0xffcf) ||
00814               (0xffd2 <= wch && wch <= 0xffd7) ||
00815               (0xffda <= wch && wch <= 0xffdc)   )
00816         
00817         
return FALSE;
00818     
else if (0xffe0 <= wch && wch <= 0xffe6)
00819         
00820         
return TRUE;
00821     
else if (0x4e00 <= wch && wch <= 0x9fa5)
00822         
00823         
return TRUE;
00824     
else if (0xf900 <= wch && wch <= 0xfa2d)
00825         
00826         
return TRUE;
00827     
else
00828     {
00829         
BOOL ret;
00830 
00831         
00832 
00833         ret = GetTextMetricsW(hDC, &tmi);
00834         
if (! ret) {
00835             KdPrint((
"CONSRV: IsConsoleFullWidth: GetTextMetricsW failed 0x%x\n",GetLastError()));
00836             
return FALSE;
00837         }
00838         
if (IS_ANY_DBCS_CHARSET(tmi.tmCharSet))
00839             tmi.tmMaxCharWidth /= 2;
00840 
00841         ret = GetCharWidth32(hDC, wch, wch, &Width);
00842         
if (! ret) {
00843             KdPrint((
"CONSRV: IsConsoleFullWidth: GetCharWidth32 failed 0x%x\n",GetLastError()));
00844             
return FALSE;
00845         }
00846         
if (Width == tmi.tmMaxCharWidth)
00847             
return FALSE;
00848         
else if (Width == tmi.tmMaxCharWidth*2)
00849             
return TRUE;
00850     }
00851     
ASSERT(FALSE);
00852     
return FALSE;
00853 }
00854 
00855 
00856 
00857 
00858 
00859 
00860 
00861 
00862 
00863 
00864 
00865 
00866 
00867 
00868 
00869 
00870 
00871 
00872 
00873 
00874 
00875 
00876 
DWORD
00877 
RemoveDbcsMark(
00878     IN PWCHAR Dst,
00879     IN PWCHAR Src,
00880     IN DWORD NumBytes,
00881     IN PCHAR SrcA,
00882     IN BOOL OS2OemFormat
00883     )
00884 {
00885     PWCHAR Tmp = Dst;
00886 
00887     
if (NumBytes == 0 || NumBytes >= 0xffffffff)
00888         
return( 0 );
00889 
00890 
#if defined(i386)
00891 
    if (OS2OemFormat) {
00892         RealUnicodeToNEC_OS2_Unicode(Src, NumBytes);
00893     }
00894 
#endif
00895 
00896     
if (SrcA) {
00897         
while (NumBytes--)
00898         {
00899             
if (!(*SrcA++ & ATTR_TRAILING_BYTE))
00900                 *Dst++ = *Src;
00901             Src++;
00902         }
00903         
return (ULONG)(Dst - Tmp);
00904     }
00905     
else {
00906         RtlCopyMemory(Dst,Src,NumBytes * 
sizeof(WCHAR)) ;
00907         
return(NumBytes) ;
00908     }
00909 
#if !defined(i386)
00910 
    UNREFERENCED_PARAMETER(OS2OemFormat);
00911 
#endif
00912 
}
00913 
00914 
00915 
00916 
00917 
00918 
00919 
00920 
00921 
00922 
00923 
00924 
00925 
00926 
00927 
00928 
00929 
00930 
00931 
00932 
DWORD
00933 
RemoveDbcsMarkCell(
00934     IN PCHAR_INFO Dst,
00935     IN PCHAR_INFO Src,
00936     IN DWORD NumBytes
00937     )
00938 {
00939     PCHAR_INFO Tmp = Dst;
00940     
DWORD TmpByte;
00941 
00942     TmpByte = NumBytes;
00943     
while (NumBytes--) {
00944         
if (!(Src->Attributes & COMMON_LVB_TRAILING_BYTE)){
00945             *Dst = *Src;
00946             Dst->Attributes &= ~COMMON_LVB_SBCSDBCS;
00947             Dst++;
00948         }
00949         Src++;
00950     }
00951     NumBytes = (ULONG)(TmpByte - (Dst - Tmp));
00952     RtlZeroMemory(Dst, NumBytes * 
sizeof(CHAR_INFO));
00953     Dst += NumBytes;
00954 
00955     
return (ULONG)(Dst - Tmp);
00956 }
00957 
00958 
DWORD
00959 
RemoveDbcsMarkAll(
00960     IN 
PSCREEN_INFORMATION ScreenInfo,
00961     IN 
PROW Row,
00962     IN PSHORT LeftChar,
00963     IN PRECT TextRect,
00964     IN 
int *TextLeft,
00965     IN PWCHAR Buffer,
00966     IN SHORT NumberOfChars
00967     )
00968 {
00969     
BOOL OS2OemFormat = 
FALSE;
00970 
00971 
#if defined(i386)
00972 
    if ((ScreenInfo->Console->Flags & CONSOLE_OS2_REGISTERED) &&
00973         (ScreenInfo->Console->Flags & CONSOLE_OS2_OEM_FORMAT) &&
00974         (ScreenInfo->Console->OutputCP == 
OEMCP)) {
00975         OS2OemFormat = 
TRUE;
00976     }
00977 
#endif // i386
00978 
00979     
if (NumberOfChars <= 0)
00980         
return NumberOfChars;
00981 
00982     
if ( !CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console))
00983     {
00984         
return RemoveDbcsMark(Buffer,
00985                               &Row->CharRow.Chars[*LeftChar],
00986                               NumberOfChars,
00987                               NULL,
00988                               OS2OemFormat
00989                              );
00990     }
00991     
else if ( *LeftChar > ScreenInfo->Window.Left &&  Row->CharRow.KAttrs[*LeftChar] & ATTR_TRAILING_BYTE)
00992     {
00993         TextRect->left -= 
SCR_FONTSIZE(ScreenInfo).X;
00994         --*LeftChar;
00995         
if (TextLeft)
00996             *TextLeft = TextRect->left;
00997         
return RemoveDbcsMark(Buffer,
00998                               &Row->CharRow.Chars[*LeftChar],
00999                               NumberOfChars+1,
01000                               &Row->CharRow.KAttrs[*LeftChar],
01001                               OS2OemFormat
01002                              );
01003     }
01004     
else if (*LeftChar == ScreenInfo->Window.Left && Row->CharRow.KAttrs[*LeftChar] & ATTR_TRAILING_BYTE)
01005     {
01006         *
Buffer = 
UNICODE_SPACE;
01007         
return RemoveDbcsMark(Buffer+1,
01008                               &Row->CharRow.Chars[*LeftChar+1],
01009                               NumberOfChars-1,
01010                               &Row->CharRow.KAttrs[*LeftChar+1],
01011                               OS2OemFormat
01012                              ) + 1;
01013     }
01014     
else
01015     {
01016         
return RemoveDbcsMark(Buffer,
01017                               &Row->CharRow.Chars[*LeftChar],
01018                               NumberOfChars,
01019                               &Row->CharRow.KAttrs[*LeftChar],
01020                               OS2OemFormat
01021                              );
01022     }
01023 }
01024 
01025 
01026 
BOOL
01027 
IsDBCSLeadByteConsole(
01028     IN BYTE AsciiChar,
01029     IN LPCPINFO lpCPInfo
01030     )
01031 {
01032     
int i;
01033 
01034     i = 0;
01035     
while (lpCPInfo->LeadByte[i]) {
01036         
if (lpCPInfo->LeadByte[i] <= AsciiChar && AsciiChar <= lpCPInfo->LeadByte[i+1])
01037             
return TRUE;
01038         i += 2;
01039     }
01040     
return FALSE;
01041 }
01042 
01043 
01044 
NTSTATUS
01045 
AdjustFont(
01046     IN 
PCONSOLE_INFORMATION Console,
01047     IN UINT CodePage
01048     )
01049 {
01050     
PSCREEN_INFORMATION ScreenInfo = Console->CurrentScreenBuffer;
01051     ULONG FontIndex;
01052     
static const COORD NullCoord = {0, 0};
01053     
TEXT_BUFFER_FONT_INFO TextFontInfo;
01054     
NTSTATUS Status;
01055 
01056     
Status = 
FindTextBufferFontInfo(ScreenInfo,
01057                                     CodePage,
01058                                     &TextFontInfo);
01059     
if (
NT_SUCCESS(Status)) {
01060         FontIndex = 
FindCreateFont(TextFontInfo.
Family,
01061                                    TextFontInfo.
FaceName,
01062                                    TextFontInfo.
FontSize,
01063                                    TextFontInfo.
Weight,
01064                                    CodePage);
01065     }
01066     
else {
01067         FontIndex = 
FindCreateFont(0,
01068                                    
SCR_FACENAME(ScreenInfo),
01069                                    NullCoord,                  
01070                                    0,
01071                                    CodePage);
01072     }
01073 
#ifdef i386
01074 
    if (! (Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
01075         
SetScreenBufferFont(Console->CurrentScreenBuffer,FontIndex, CodePage);
01076     }
01077     
else {
01078         
BOOL fChange = 
FALSE;
01079 
01080         
if ((Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) &&
01081             (GetForegroundWindow() == Console->hWnd)                    )
01082         {
01083             
ChangeDispSettings(Console, Console->hWnd, 0);
01084             fChange = 
TRUE;
01085         }
01086         
SetScreenBufferFont(Console->CurrentScreenBuffer,FontIndex, CodePage);
01087         
ConvertToFullScreen(Console);
01088         
if (fChange &&
01089             (GetForegroundWindow() == Console->hWnd))
01090             
ChangeDispSettings(Console, Console->hWnd, CDS_FULLSCREEN);
01091     }
01092 
#else
01093 
    SetScreenBufferFont(Console->CurrentScreenBuffer,FontIndex, CodePage);
01094 
#endif
01095 
    return STATUS_SUCCESS;
01096 }
01097 
01098 
01099 
NTSTATUS
01100 
ConvertToCodePage(
01101     IN 
PCONSOLE_INFORMATION Console,
01102     IN UINT PrevCodePage
01103     )
01104 {
01105     
PSCREEN_INFORMATION Cur;
01106 
01107     
if (Console->OutputCP != 
OEMCP && PrevCodePage == 
OEMCP)
01108     {
01109 
01110         
for (Cur=Console->ScreenBuffers;Cur!=
NULL;Cur=Cur->
Next) {
01111 
01112             
if (Cur->
Flags & 
CONSOLE_GRAPHICS_BUFFER) {
01113                 
continue;
01114             }
01115 
01116             
ConvertOutputOemToNonOemUnicode(
01117                 Cur->
BufferInfo.TextInfo.TextRows,
01118                 Cur->
BufferInfo.TextInfo.DbcsScreenBuffer.KAttrRows,
01119                 Cur->
ScreenBufferSize.X * Cur->
ScreenBufferSize.Y,
01120                 Console->OutputCP);
01121 
01122             
if ((Cur->
Flags & 
CONSOLE_OEMFONT_DISPLAY) &&
01123                 ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) == 0)) {
01124                 
RealUnicodeToFalseUnicode(
01125                     Cur->
BufferInfo.TextInfo.TextRows,
01126                     Cur->
ScreenBufferSize.X * Cur->
ScreenBufferSize.Y,
01127                     Console->OutputCP);
01128             }
01129         }
01130 
01131         
if (Console->CurrentScreenBuffer->Flags & 
CONSOLE_TEXTMODE_BUFFER) {
01132             PCONVERSIONAREA_INFORMATION ConvAreaInfo;
01133             ConvAreaInfo = Console->ConsoleIme.ConvAreaRoot;
01134             
while (ConvAreaInfo) {
01135                 Cur = ConvAreaInfo->ScreenBuffer;
01136 
01137                 
if (!(Cur->
Flags & 
CONSOLE_GRAPHICS_BUFFER)) {
01138 
01139                     
ConvertOutputOemToNonOemUnicode(
01140                         Cur->
BufferInfo.TextInfo.TextRows,
01141                         Cur->
BufferInfo.TextInfo.DbcsScreenBuffer.KAttrRows,
01142                         Cur->
ScreenBufferSize.X * Cur->
ScreenBufferSize.Y,
01143                         Console->OutputCP);
01144 
01145                     
if ((Cur->
Flags & 
CONSOLE_OEMFONT_DISPLAY) &&
01146                         ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) == 0)) {
01147                         
RealUnicodeToFalseUnicode(
01148                             Cur->
BufferInfo.TextInfo.TextRows,
01149                             Cur->
ScreenBufferSize.X * Cur->
ScreenBufferSize.Y,
01150                             Console->OutputCP);
01151                     }
01152                 }
01153 
01154                 ConvAreaInfo = ConvAreaInfo->ConvAreaNext;
01155             }
01156 
01157             Console->CurrentScreenBuffer->BufferInfo.TextInfo.Flags &= ~
TEXT_VALID_HINT;
01158         }
01159 
01160 
#ifdef FE_SB
01161 
        else
01162         {
01163             
01164             
ASSERT(FALSE);
01165         }
01166 
#endif
01167 
01168         
SetWindowSize(Console->CurrentScreenBuffer);
01169         
WriteToScreen(Console->CurrentScreenBuffer,&Console->CurrentScreenBuffer->Window);
01170     }
01171 
01172     
return STATUS_SUCCESS;
01173 }
01174 
01175 
NTSTATUS
01176 
ConvertOutputOemToNonOemUnicode(
01177     IN OUT LPWSTR Source,
01178     IN OUT PBYTE KAttrRows,
01179     IN 
int SourceLength, 
01180     IN UINT Codepage
01181     )
01182 {
01183     
NTSTATUS Status;
01184     LPSTR  pTemp;
01185     LPWSTR pwTemp;
01186     ULONG TempLength;
01187     ULONG Length;
01188     
BOOL NormalChars;
01189     
int i;
01190 
01191     
if (SourceLength == 0 )
01192         
return STATUS_SUCCESS;
01193 
01194     NormalChars = 
TRUE;
01195     
for (i=0;i<SourceLength;i++) {
01196         
if (Source[i] > 0x7f) {
01197             NormalChars = 
FALSE;
01198             
break;
01199         }
01200     }
01201     
if (NormalChars) {
01202         
return STATUS_SUCCESS;
01203     }
01204 
01205     pTemp = (LPSTR)
ConsoleHeapAlloc(
MAKE_TAG( TMP_TAG ),SourceLength);
01206     
if (pTemp == 
NULL) {
01207         
return STATUS_NO_MEMORY;
01208     }
01209 
01210     pwTemp = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG( TMP_TAG ),SourceLength * 
sizeof(WCHAR));
01211     
if (pwTemp == 
NULL) {
01212         
ConsoleHeapFree(pTemp);
01213         
return STATUS_NO_MEMORY;
01214     }
01215 
01216     TempLength = 
RemoveDbcsMark(pwTemp,
01217                                 Source,
01218                                 SourceLength,
01219                                 KAttrRows,
01220                                 FALSE);
01221 
01222     
Status = 
RtlUnicodeToOemN(pTemp,
01223                               (ULONG)
ConsoleHeapSize(pTemp),
01224                               &Length,
01225                               pwTemp,
01226                               TempLength * 
sizeof(WCHAR)
01227                              );
01228     
if (!
NT_SUCCESS(Status)) {
01229         
ConsoleHeapFree(pTemp);
01230         
ConsoleHeapFree(pwTemp);
01231         
return Status;
01232     }
01233 
01234     MultiByteToWideChar(Codepage,
01235                         0,
01236                         pTemp,
01237                         Length,
01238                         Source,
01239                         SourceLength
01240                        );
01241     
ConsoleHeapFree(pTemp);
01242     
ConsoleHeapFree(pwTemp);
01243 
01244     
if (!
NT_SUCCESS(Status)) {
01245         
return Status;
01246     } 
else {
01247         
if (KAttrRows) {
01248             RtlZeroMemory(KAttrRows, SourceLength);
01249         }
01250         
return STATUS_SUCCESS;
01251     }
01252 }
01253 
01254 
01255 
01256 
01257 
01258 
01259 
VOID
01260 
TextOutEverything(
01261     IN 
PCONSOLE_INFORMATION Console,
01262     IN 
PSCREEN_INFORMATION ScreenInfo,
01263     IN SHORT LeftWindowPos,
01264     IN OUT PSHORT RightWindowPos,
01265     IN OUT PSHORT CountOfAttr,
01266     IN SHORT CountOfAttrOriginal,
01267     IN OUT PBOOL DoubleColorDBCS,
01268     IN BOOL LocalEUDCFlag,
01269     IN 
PROW Row,
01270     IN 
PATTR_PAIR Attr,
01271     IN SHORT LeftTextPos,
01272     IN SHORT RightTextPos,
01273     IN 
int WindowRectLeft,
01274     IN RECT WindowRect,
01275     IN SHORT NumberOfChars
01276     )
01277 
01278 
01279 
01280 
01281 
01282 
01283 
01284 
01285 
01286 
01287 
01288 
01289 
01290 {
01291     
int   j = LeftWindowPos;
01292     
int   TextLeft = WindowRectLeft;
01293     RECT TextRect = WindowRect;
01294     
SHORT LeftChar = LeftTextPos;
01295     
SHORT RightChar = RightTextPos;
01296     
BOOL  DoubleColorDBCSBefore;
01297     
BOOL  LocalEUDCFlagBefore;
01298     
PEUDC_INFORMATION EudcInfo;
01299 
01300     
int   RightPos  = j + *CountOfAttr - 1;
01301     
int   RightText = LeftChar + *CountOfAttr - 1;
01302     
BOOL  OS2OemFormat = 
FALSE;
01303 
01304 
#ifdef FE_SB
01305 
    
01306     
ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER));
01307 
#endif
01308 
01309 
#if defined(i386)
01310 
    if ((ScreenInfo->Console->Flags & CONSOLE_OS2_REGISTERED) &&
01311         (ScreenInfo->Console->Flags & CONSOLE_OS2_OEM_FORMAT) &&
01312         (ScreenInfo->Console->OutputCP == 
OEMCP)) {
01313         OS2OemFormat = 
TRUE;
01314     }
01315 
#endif // i386
01316 
01317 
#if defined(DBG) && defined(DBG_KATTR)
01318 
    BeginKAttrCheck(ScreenInfo);
01319 
#endif
01320 
01321     RightText = 
min(RightText,(ScreenInfo->ScreenBufferSize.X-1));
01322 
01323     LocalEUDCFlagBefore = LocalEUDCFlag ;
01324     EudcInfo = (
PEUDC_INFORMATION)Console->EudcInformation;
01325 
01326     DoubleColorDBCSBefore = *DoubleColorDBCS ;
01327     
if (DoubleColorDBCSBefore){
01328         RECT TmpRect;
01329 
01330         
if (Console->FonthDC == 
NULL) {
01331             Console->FonthDC = CreateCompatibleDC(Console->hDC);
01332             Console->hBitmap = CreateBitmap(DEFAULT_FONTSIZE, DEFAULT_FONTSIZE, BITMAP_PLANES, BITMAP_BITS_PIXEL, NULL);
01333             SelectObject(Console->FonthDC, Console->hBitmap);
01334         }
01335 
01336         
if (LocalEUDCFlagBefore){
01337             
if (EudcInfo->
hDCLocalEudc == 
NULL) {
01338                 EudcInfo->
hDCLocalEudc = CreateCompatibleDC(Console->hDC);
01339                 EudcInfo->
hBmpLocalEudc = CreateBitmap(EudcInfo->
LocalEudcSize.X,
01340                                                        EudcInfo->
LocalEudcSize.Y,
01341                                                        BITMAP_PLANES, BITMAP_BITS_PIXEL, NULL);
01342                 SelectObject(EudcInfo->
hDCLocalEudc, EudcInfo->
hBmpLocalEudc);
01343             }
01344             
GetFitLocalEUDCFont(Console,
01345                                 Row->CharRow.Chars[LeftChar-1]);
01346             BitBlt(Console->hDC,
01347                    TextRect.left,
01348                    TextRect.top,
01349                    
SCR_FONTSIZE(ScreenInfo).X,
01350                    
SCR_FONTSIZE(ScreenInfo).Y,
01351                    EudcInfo->
hDCLocalEudc,
01352                    
SCR_FONTSIZE(ScreenInfo).X,
01353                    0,
01354                    SRCCOPY
01355                   );
01356             TextRect.left += 
SCR_FONTSIZE(ScreenInfo).X;
01357             TextLeft +=  
SCR_FONTSIZE(ScreenInfo).X;
01358             TextRect.right += 
SCR_FONTSIZE(ScreenInfo).X;
01359             (*CountOfAttr)++;
01360             NumberOfChars = 0;
01361         }
01362         
else{
01363             TmpRect.left = 0;
01364             TmpRect.top = 0;
01365             TmpRect.right = 
SCR_FONTSIZE(ScreenInfo).X;
01366             TmpRect.bottom = 
SCR_FONTSIZE(ScreenInfo).Y;
01367 
01368             SelectObject(Console->FonthDC,
01369                          FontInfo[
SCR_FONTNUMBER(ScreenInfo)].hFont
01370                         );
01371 
01372             ExtTextOutW(Console->FonthDC,
01373                         0,
01374                         0,
01375                         ETO_OPAQUE,
01376                         &TmpRect,
01377                         &Row->CharRow.Chars[LeftChar-1],
01378                         1,
01379                         NULL
01380                        );
01381             BitBlt(Console->hDC,
01382                    TextRect.left,
01383                    TextRect.top,
01384                    
SCR_FONTSIZE(ScreenInfo).X,
01385                    
SCR_FONTSIZE(ScreenInfo).Y,
01386                    Console->FonthDC,
01387                    
SCR_FONTSIZE(ScreenInfo).X,
01388                    0,
01389                    SRCCOPY
01390                   );
01391             TextRect.left += 
SCR_FONTSIZE(ScreenInfo).X;
01392             TextLeft += 
SCR_FONTSIZE(ScreenInfo).X;
01393             NumberOfChars = (
SHORT)
RemoveDbcsMark(ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferCharacter,
01394                                                   &Row->CharRow.Chars[LeftChar+1],
01395                                                   NumberOfChars-1,
01396                                                   &Row->CharRow.KAttrs[LeftChar+1],
01397                                                   OS2OemFormat);
01398         }
01399 
01400     }
01401     
else {
01402         NumberOfChars = (
SHORT)
RemoveDbcsMarkAll(ScreenInfo,
01403                                                  Row,
01404                                                  &LeftChar,
01405                                                  &TextRect,
01406                                                  &TextLeft,
01407                                                  ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferCharacter,
01408                                                  NumberOfChars);
01409     }
01410 
01411 
01412     *DoubleColorDBCS = 
FALSE ;
01413     
if ((NumberOfChars != 0) && (Row->CharRow.KAttrs[RightText] & ATTR_LEADING_BYTE)){
01414         
if (RightPos >= ScreenInfo->Window.Right)
01415             *(ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferCharacter+NumberOfChars-1) = 
UNICODE_SPACE;
01416         
else if(TextRect.right <= ScreenInfo->Window.Right * 
SCR_FONTSIZE(ScreenInfo).X) {
01417             *DoubleColorDBCS = 
TRUE;
01418             TextRect.right += 
SCR_FONTSIZE(ScreenInfo).X;
01419             
if((j == *RightWindowPos)&&
01420                (*RightWindowPos < ScreenInfo->Window.Right))
01421             *RightWindowPos++;
01422         }
01423     }
01424 
01425     
if( TextRect.left < TextRect.right){
01426         ExtTextOutW(Console->hDC,
01427                     TextLeft,
01428                     TextRect.top,
01429                     ETO_OPAQUE,
01430                     &TextRect,
01431                     ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferCharacter,
01432                     NumberOfChars,
01433                     NULL
01434                    );
01435     }
01436     
if (LocalEUDCFlagBefore){
01437         
DWORD dwFullWidth = (IsConsoleFullWidth(Console->hDC,
01438                                                 Console->OutputCP,
01439                                                 Row->CharRow.Chars[RightText+1]) ? 2 : 1);
01440 
01441         
if (EudcInfo->
hDCLocalEudc == 
NULL) {
01442             EudcInfo->
hDCLocalEudc = CreateCompatibleDC(Console->hDC);
01443             EudcInfo->
hBmpLocalEudc = CreateBitmap(EudcInfo->
LocalEudcSize.X,
01444                                                    EudcInfo->
LocalEudcSize.Y,
01445                                                    BITMAP_PLANES, BITMAP_BITS_PIXEL, NULL);
01446             SelectObject(EudcInfo->
hDCLocalEudc, EudcInfo->
hBmpLocalEudc);
01447         }
01448         
GetFitLocalEUDCFont(Console,
01449                             Row->CharRow.Chars[RightText+1]);
01450         BitBlt(Console->hDC,                      
01451                TextRect.right,                    
01452                TextRect.top,                      
01453                
SCR_FONTSIZE(ScreenInfo).X * dwFullWidth, 
01454                
SCR_FONTSIZE(ScreenInfo).Y,    
01455                EudcInfo->
hDCLocalEudc,            
01456                0,                                 
01457                0,                                 
01458                SRCCOPY
01459               );
01460 
01461         TextRect.right += (
SCR_FONTSIZE(ScreenInfo).X * dwFullWidth);
01462         (*CountOfAttr) += (
SHORT)dwFullWidth;
01463         
if (CountOfAttrOriginal < *CountOfAttr ){
01464             *DoubleColorDBCS = 
TRUE ;
01465             (*CountOfAttr)--;
01466             TextRect.right -= 
SCR_FONTSIZE(ScreenInfo).X;
01467         }
01468     }
01469     
if (DoubleColorDBCSBefore){
01470         TextRect.left -= 
SCR_FONTSIZE(ScreenInfo).X;
01471     }
01472 
01473     
TextOutCommonLVB(Console, Attr->Attr, TextRect);
01474 
01475 }
01476 
01477 
VOID
01478 
TextOutCommonLVB(
01479     IN 
PCONSOLE_INFORMATION Console,
01480     IN WORD Attributes,
01481     IN RECT CommonLVBRect
01482     )
01483 {
01484     HBRUSH hbrSave;
01485     HGDIOBJ hbr;
01486     
int GridX;
01487 
01488     
if (Attributes & (COMMON_LVB_GRID_HORIZONTAL |
01489                       COMMON_LVB_GRID_LVERTICAL  |
01490                       COMMON_LVB_GRID_RVERTICAL  |
01491                       COMMON_LVB_UNDERSCORE       )
01492        )
01493     {
01494         
if(Attributes & COMMON_LVB_UNDERSCORE){
01495             
if(Attributes & COMMON_LVB_REVERSE_VIDEO)
01496                 hbr = CreateSolidBrush(
ConvertAttrToRGB(Console, 
LOBYTE(Attributes >> 4)));
01497             
else
01498                 hbr = CreateSolidBrush(
ConvertAttrToRGB(Console, 
LOBYTE(Attributes)));
01499             hbrSave = SelectObject(Console->hDC, hbr);
01500             PatBlt(Console->hDC,
01501                    CommonLVBRect.left,
01502                    CommonLVBRect.bottom-1,
01503                    CommonLVBRect.right-CommonLVBRect.left,
01504                    1,
01505                    PATCOPY
01506                   );
01507             SelectObject(Console->hDC, hbrSave);
01508             DeleteObject(hbr);
01509         }
01510 
01511         
if(Attributes & (COMMON_LVB_GRID_HORIZONTAL | COMMON_LVB_GRID_LVERTICAL | COMMON_LVB_GRID_RVERTICAL)){
01512             hbr = CreateSolidBrush(
ConvertAttrToRGB(Console, 0x0007));
01513             hbrSave = SelectObject(Console->hDC, hbr);
01514 
01515             
if(Attributes & COMMON_LVB_GRID_HORIZONTAL){
01516                 PatBlt(Console->hDC,
01517                        CommonLVBRect.left,
01518                        CommonLVBRect.top,
01519                        CommonLVBRect.right-CommonLVBRect.left,
01520                        1,
01521                        PATCOPY
01522                       );
01523             }
01524             
if(Attributes & COMMON_LVB_GRID_LVERTICAL){
01525                 
for ( GridX = CommonLVBRect.left ;
01526                       GridX < CommonLVBRect.right ;
01527                       GridX += 
CON_FONTSIZE(Console).X){
01528                     PatBlt(Console->hDC,
01529                            GridX,
01530                            CommonLVBRect.top,
01531                            1,
01532                            
CON_FONTSIZE(Console).Y,
01533                            PATCOPY
01534                           );
01535                 }
01536             }
01537             
if(Attributes & COMMON_LVB_GRID_RVERTICAL){
01538                 
for ( GridX = CommonLVBRect.left + 
CON_FONTSIZE(Console).X-1 ;
01539                       GridX < CommonLVBRect.right ;
01540                       GridX += 
CON_FONTSIZE(Console).X){
01541                     PatBlt(Console->hDC,
01542                            GridX,
01543                            CommonLVBRect.top,
01544                            1,
01545                            
CON_FONTSIZE(Console).Y,
01546                            PATCOPY
01547                           );
01548                 }
01549             }
01550             SelectObject(Console->hDC, hbrSave);
01551             DeleteObject(hbr);
01552         }
01553     }
01554 }
01555 
01556 
NTSTATUS
01557 
MakeAltRasterFont(
01558     UINT CodePage,
01559     COORD DefaultFontSize,
01560     COORD *AltFontSize,
01561     BYTE  *AltFontFamily,
01562     ULONG *AltFontIndex,
01563     LPWSTR AltFaceName
01564     )
01565 {
01566     
DWORD i;
01567     
DWORD Find;
01568     ULONG FontIndex;
01569     COORD FontSize = 
DefaultFontSize;
01570     COORD FontDelta;
01571     
BOOL  fDbcsCharSet = 
IsAvailableFarEastCodePage(CodePage);
01572 
01573     FontIndex = 0;
01574     Find = (
DWORD)-1;
01575     
for (i=0; i < 
NumberOfFonts; i++)
01576     {
01577         
if (!
TM_IS_TT_FONT(FontInfo[i].Family) &&
01578             IS_ANY_DBCS_CHARSET(FontInfo[i].tmCharSet) == fDbcsCharSet
01579            )
01580         {
01581             FontDelta.X = 
abs(FontSize.X - FontInfo[i].Size.X);
01582             FontDelta.Y = 
abs(FontSize.Y - FontInfo[i].Size.Y);
01583             
if (Find > (
DWORD)(FontDelta.X + FontDelta.Y))
01584             {
01585                 Find = (
DWORD)(FontDelta.X + FontDelta.Y);
01586                 FontIndex = i;
01587             }
01588         }
01589     }
01590 
01591     *AltFontIndex = FontIndex;
01592     wcscpy(AltFaceName, FontInfo[*AltFontIndex].FaceName);
01593     *AltFontSize = 
FontInfo[*AltFontIndex].
Size;
01594     *AltFontFamily = 
FontInfo[*AltFontIndex].
Family;
01595 
01596     
DBGFONTS((
"MakeAltRasterFont : AltFontIndex = %ld\n", *AltFontIndex));
01597 
01598     
return STATUS_SUCCESS;
01599 }
01600 
01601 
01602 
NTSTATUS
01603 
InitializeDbcsMisc(
01604     VOID
01605     )
01606 {
01607     HANDLE hkRegistry = 
NULL;
01608     
NTSTATUS Status;
01609     WCHAR awchValue[ 512 ];
01610     WCHAR awchData[ 512 ];
01611     
BYTE  Buffer[ 512 ];
01612     
DWORD Length;
01613     
DWORD dwIndex;
01614     LPWSTR pwsz;
01615 
01616     
ASSERT(gTTFontList.Next==NULL);
01617     
ASSERT(
gRegFullScreenCodePage.Next==NULL);
01618 
01619     gTTFontList.Next = 
NULL;
01620     
gRegFullScreenCodePage.Next = 
NULL;
01621 
01622     
01623 
01624 
01625     
Status = 
MyRegOpenKey(NULL,
01626                           MACHINE_REGISTRY_CONSOLE_TTFONT,
01627                           &hkRegistry);
01628     
if (!
NT_SUCCESS( Status )) {
01629         
DBGPRINT((
"CONSRV: NtOpenKey failed %ws\n", MACHINE_REGISTRY_CONSOLE_TTFONT));
01630     }
01631     
else {
01632         LPTTFONTLIST pTTFontList;
01633 
01634         
for( dwIndex = 0; ; dwIndex++) {
01635             
Status = MyRegEnumValue(hkRegistry,
01636                                     dwIndex,
01637                                     
sizeof(awchValue), (LPWSTR)&awchValue,
01638                                     
sizeof(awchData),  (PBYTE)&awchData);
01639             
if (!
NT_SUCCESS( Status )) {
01640                 
break;
01641             }
01642 
01643             pTTFontList = 
ConsoleHeapAlloc(
01644                                     
MAKE_TAG( SCREEN_DBCS_TAG ),
01645                                     
sizeof(TTFONTLIST));
01646             
if (pTTFontList == 
NULL) {
01647                 
break;
01648             }
01649 
01650             pTTFontList->List.Next = 
NULL;
01651             pTTFontList->CodePage = 
ConvertStringToDec(awchValue, NULL);
01652             pwsz = awchData;
01653             
if (*pwsz == BOLD_MARK) {
01654                 pTTFontList->fDisableBold = 
TRUE;
01655                 pwsz++;
01656             }
01657             
else
01658                 pTTFontList->fDisableBold = 
FALSE;
01659             wcscpy(pTTFontList->FaceName1, pwsz);
01660 
01661             pwsz += wcslen(pwsz) + 1;
01662             
if (*pwsz == BOLD_MARK) {
01663                 pTTFontList->fDisableBold = 
TRUE;
01664                 pwsz++;
01665             }
01666             wcscpy(pTTFontList->FaceName2, pwsz);
01667 
01668             PushEntryList(&gTTFontList, &(pTTFontList->List));
01669         }
01670 
01671         
NtClose(hkRegistry);
01672     }
01673 
01674     
01675 
01676 
01677     
Status = 
MyRegOpenKey(NULL,
01678                           MACHINE_REGISTRY_CONSOLE_FULLSCREEN,
01679                           &hkRegistry);
01680     
if (!
NT_SUCCESS( Status )) {
01681         
DBGPRINT((
"CONSRV: NtOpenKey failed %ws\n", MACHINE_REGISTRY_CONSOLE_FULLSCREEN));
01682     }
01683     
else {
01684         
01685 
01686 
01687         
Status = MyRegQueryValueEx(hkRegistry,
01688                                    MACHINE_REGISTRY_INITIAL_PALETTE,
01689                                    
sizeof( Buffer ), Buffer, &Length);
01690         
if (
NT_SUCCESS( Status ) && Length > 
sizeof(
DWORD)) {
01691             
DWORD PaletteLength = ((LPDWORD)
Buffer)[0];
01692             
PUSHORT Palette;
01693 
01694             
if (PaletteLength * 
sizeof(
USHORT) >= (Length - 
sizeof(
DWORD)))
01695             {
01696                 Palette = 
ConsoleHeapAlloc(
01697                                     
MAKE_TAG( BUFFER_TAG ),
01698                                     Length);
01699                 
if (Palette != 
NULL)
01700                 {
01701                     RtlCopyMemory(Palette, Buffer, Length);
01702                     
RegInitialPalette = Palette;
01703                 }
01704             }
01705         }
01706 
01707         
01708 
01709 
01710         
Status = MyRegQueryValueEx(hkRegistry,
01711                                    MACHINE_REGISTRY_COLOR_BUFFER,
01712                                    
sizeof( Buffer ), Buffer, &Length);
01713         
if (
NT_SUCCESS( Status ) && Length > 
sizeof(
DWORD)) {
01714             
DWORD ColorBufferLength = ((LPDWORD)
Buffer)[0];
01715             PUCHAR Color;
01716 
01717             
if (ColorBufferLength * 
sizeof(
DWORD) >= (Length - 
sizeof(
DWORD)))
01718             {
01719                 Color = 
ConsoleHeapAlloc(
01720                                   
MAKE_TAG( BUFFER_TAG ),
01721                                   Length);
01722                 
if (Color != 
NULL)
01723                 {
01724                     RtlCopyMemory(Color, Buffer, Length);
01725                     
RegColorBuffer = Color;
01726                 }
01727             }
01728         }
01729 
01730         
01731 
01732 
01733         
Status = MyRegQueryValueEx(hkRegistry,
01734                                    MACHINE_REGISTRY_COLOR_BUFFER_NO_TRANSLATE,
01735                                    
sizeof( Buffer ), Buffer, &Length);
01736         
if (
NT_SUCCESS( Status ) && Length > 
sizeof(
DWORD)) {
01737             
DWORD ColorBufferLength = ((LPDWORD)
Buffer)[0];
01738             PUCHAR Color;
01739 
01740             
if (ColorBufferLength * 
sizeof(
DWORD) >= (Length - 
sizeof(
DWORD)))
01741             {
01742                 Color = 
ConsoleHeapAlloc(
01743                                   
MAKE_TAG( BUFFER_TAG ),
01744                                   Length);
01745                 
if (Color != 
NULL)
01746                 {
01747                     RtlCopyMemory(Color, Buffer, Length);
01748                     
RegColorBufferNoTranslate = Color;
01749                 }
01750             }
01751         }
01752 
01753         
01754 
01755 
01756         
Status = MyRegQueryValueEx(hkRegistry,
01757                                    MACHINE_REGISTRY_MODE_FONT_PAIRS,
01758                                    
sizeof( Buffer ), Buffer, &Length);
01759         
if (
NT_SUCCESS( Status ) && Length > 
sizeof(
DWORD)) {
01760             
DWORD NumOfEntries = ((LPDWORD)
Buffer)[0];
01761             
PMODE_FONT_PAIR ModeFont;
01762 
01763             
if (NumOfEntries * 
sizeof(
MODE_FONT_PAIR) >= (Length - 
sizeof(
DWORD)))
01764             {
01765                 ModeFont = 
ConsoleHeapAlloc(
01766                                      
MAKE_TAG( BUFFER_TAG ),
01767                                      Length);
01768                 
if (ModeFont != 
NULL)
01769                 {
01770                     Length -= 
sizeof(
DWORD);
01771                     RtlCopyMemory(ModeFont, &Buffer[
sizeof(DWORD)], Length);
01772                     
RegModeFontPairs = ModeFont;
01773                     
NUMBER_OF_MODE_FONT_PAIRS = NumOfEntries;
01774                 }
01775             }
01776         }
01777 
01778         
01779 
01780 
01781         {
01782             HANDLE hkRegCP = 
NULL;
01783 
01784             
Status = 
MyRegOpenKey(hkRegistry,
01785                                   MACHINE_REGISTRY_FS_CODEPAGE,
01786                                   &hkRegCP);
01787             
if (!
NT_SUCCESS( Status )) {
01788                 
DBGPRINT((
"CONSRV: NtOpenKey failed %ws\n", MACHINE_REGISTRY_FS_CODEPAGE));
01789             }
01790             
else {
01791                 
PFS_CODEPAGE pFsCodePage;
01792 
01793                 
for( dwIndex = 0; ; dwIndex++) {
01794                     
Status = MyRegEnumValue(hkRegCP,
01795                                             dwIndex,
01796                                             
sizeof(awchValue), (LPWSTR)&awchValue,
01797                                             
sizeof(awchData),  (PBYTE)&awchData);
01798                     
if (!
NT_SUCCESS( Status )) {
01799                         
break;
01800                     }
01801 
01802                     pFsCodePage = 
ConsoleHeapAlloc(
01803                                             
MAKE_TAG( BUFFER_TAG ),
01804                                             
sizeof(
FS_CODEPAGE));
01805                     
if (pFsCodePage == 
NULL) {
01806                         
break;
01807                     }
01808 
01809                     pFsCodePage->
List.Next = 
NULL;
01810                     pFsCodePage->
CodePage = 
ConvertStringToDec(awchValue, NULL);
01811 
01812                     PushEntryList(&gRegFullScreenCodePage, &(pFsCodePage->
List));
01813                 }
01814 
01815                 
NtClose(hkRegCP);
01816             }
01817         }
01818 
01819 
01820         
NtClose(hkRegistry);
01821     }
01822 
01823 
01824 
#if defined(i386)
01825 
    Status = NtGetMachineIdentifierValue(&gdwMachineId);
01826     
if (!
NT_SUCCESS(Status)) {
01827         gdwMachineId = MACHINEID_MS_PCAT;
01828     }
01829 
#endif
01830 
01831     
Status = 
RtlInitializeCriticalSectionAndSpinCount(&ConIMEInitWindowsLock,
01832                                                       0x80000000);
01833 
01834     
return Status;
01835 }
01836 
01837 
#if defined(i386)
01838 
NTSTATUS
01839 RealUnicodeToNEC_OS2_Unicode(
01840     IN OUT LPWSTR Source,
01841     IN 
int SourceLength      
01842     )
01843 
01844 
01845 
01846 
01847 
01848 
01849 
01850 
01851 {
01852     
NTSTATUS Status;
01853     LPSTR Temp;
01854     ULONG TempLength;
01855     ULONG Length;
01856     
CHAR StackBuffer[
STACK_BUFFER_SIZE];
01857     
BOOL NormalChars;
01858     
int i;
01859 
01860     
DBGCHARS((
"RealUnicodeToNEC_OS2_Unicode U->ACP:???->U %.*ls\n",
01861             SourceLength > 10 ? 10 : SourceLength, Source));
01862     NormalChars = 
TRUE;
01863 
01864     
if (pGlyph_NEC_OS2_CP == 
NULL || pGlyph_NEC_OS2_CP->MultiByteTable == 
NULL) {
01865         
DBGCHARS((
"RealUnicodeToNEC_OS2_Unicode  xfer buffer null\n"));
01866         
return STATUS_SUCCESS;  
01867     }
01868 
01869     
01870 
01871 
01872 
01873     
for (i=0;i<SourceLength;i++) {
01874         
if ((
USHORT)(Source[i]) < 0x20) {
01875             NormalChars = 
FALSE;
01876             
break;
01877         }
01878     }
01879     
if (NormalChars) {
01880         
return STATUS_SUCCESS;
01881     }
01882 
01883     TempLength = SourceLength;
01884     
if (TempLength > 
STACK_BUFFER_SIZE) {
01885         Temp = (LPSTR)
ConsoleHeapAlloc(
MAKE_TAG( TMP_TAG ),TempLength);
01886         
if (Temp == 
NULL) {
01887             
return STATUS_NO_MEMORY;
01888         }
01889     } 
else {
01890         Temp = StackBuffer;
01891     }
01892     
Status = 
RtlUnicodeToMultiByteN(Temp,
01893                                     TempLength,
01894                                     &Length,
01895                                     Source,
01896                                     SourceLength * 
sizeof(WCHAR)
01897                                    );
01898     
if (!
NT_SUCCESS(Status)) {
01899         
if (TempLength > 
STACK_BUFFER_SIZE) {
01900             
ConsoleHeapFree(Temp);
01901         }
01902         
return Status;
01903     }
01904     
ASSERT(pGlyph_NEC_OS2_CP != NULL && pGlyph_NEC_OS2_CP->MultiByteTable != NULL);
01905     
Status = 
RtlCustomCPToUnicodeN(pGlyph_NEC_OS2_CP,
01906                                    Source,
01907                                    SourceLength * 
sizeof(WCHAR),
01908                                    &Length,
01909                                    Temp,
01910                                    TempLength
01911                                   );
01912     
if (TempLength > 
STACK_BUFFER_SIZE) {
01913         
ConsoleHeapFree(Temp);
01914     }
01915     
if (!
NT_SUCCESS(Status)) {
01916         
return Status;
01917     } 
else {
01918         
return STATUS_SUCCESS;
01919     }
01920 }
01921 
01922 
BOOL
01923 InitializeNEC_OS2_CP(
01924     VOID
01925     )
01926 {
01927     PPEB pPeb;
01928 
01929     pPeb = NtCurrentPeb();
01930     
if ((pPeb == 
NULL) || (pPeb->OemCodePageData == 
NULL)) {
01931         
return FALSE;
01932     }
01933 
01934     
01935 
01936 
01937     
if (pGlyph_NEC_OS2_CP == 
NULL) {
01938         pGlyph_NEC_OS2_CP = (PCPTABLEINFO)
ConsoleHeapAlloc( 
MAKE_TAG(SCREEN_DBCS_TAG), 
sizeof(CPTABLEINFO));
01939         
if (pGlyph_NEC_OS2_CP == 
NULL) {
01940             
return FALSE;
01941         }
01942     }
01943     
RtlInitCodePageTable(pPeb->OemCodePageData, pGlyph_NEC_OS2_CP);
01944 
01945     
01946 
01947 
01948     
if (pGlyph_NEC_OS2_Table == 
NULL) {
01949         pGlyph_NEC_OS2_Table = (
PUSHORT)
ConsoleHeapAlloc( 
MAKE_TAG(SCREEN_DBCS_TAG), 256 * 
sizeof(USHORT));
01950         
if (pGlyph_NEC_OS2_Table == 
NULL) {
01951             
return FALSE;
01952         }
01953     }
01954     RtlCopyMemory(pGlyph_NEC_OS2_Table, pGlyph_NEC_OS2_CP->MultiByteTable, 256 * 
sizeof(USHORT));
01955 
01956     
01957 
01958 
01959     MultiByteToWideChar(CP_OEMCP, MB_USEGLYPHCHARS,
01960             
"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
01961             
"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1E\x1F\x1C\x07",
01962             0x20, pGlyph_NEC_OS2_Table, 0x20);
01963 
01964 
01965     
01966 
01967 
01968     pGlyph_NEC_OS2_CP->MultiByteTable = pGlyph_NEC_OS2_Table;
01969 
01970     
return TRUE;
01971 }
01972 
#endif // i386
01973 
01974 
BYTE
01975 
CodePageToCharSet(
01976     UINT CodePage
01977     )
01978 {
01979     CHARSETINFO csi;
01980 
01981     
if (!TranslateCharsetInfo((DWORD *)CodePage, &csi, TCI_SRCCODEPAGE))
01982         csi.ciCharset = OEM_CHARSET;
01983 
01984     
return (
BYTE)csi.ciCharset;
01985 }
01986 
01987 
BOOL
01988 
IsAvailableFarEastCodePage(
01989     UINT CodePage
01990     )
01991 {
01992     
BYTE CharSet = 
CodePageToCharSet(CodePage);
01993 
01994     
return IS_ANY_DBCS_CHARSET(CharSet);
01995 }
01996 
01997 LPTTFONTLIST
01998 
SearchTTFont(
01999     LPWSTR pwszFace,
02000     BOOL   fCodePage,
02001     UINT   CodePage
02002     )
02003 {
02004     PSINGLE_LIST_ENTRY pTemp = gTTFontList.Next;
02005 
02006     
if (pwszFace) {
02007         
while (pTemp != 
NULL) {
02008             LPTTFONTLIST pTTFontList = (LPTTFONTLIST)pTemp;
02009 
02010             
if (wcscmp(pwszFace, pTTFontList->FaceName1) == 0 ||
02011                 wcscmp(pwszFace, pTTFontList->FaceName2) == 0    ) {
02012                 
if (fCodePage)
02013                     
if (pTTFontList->CodePage == CodePage )
02014                         
return pTTFontList;
02015                     
else
02016                         
return NULL;
02017                 
else
02018                     
return pTTFontList;
02019             }
02020 
02021             pTemp = pTemp->Next;
02022         }
02023     }
02024 
02025     
return NULL;
02026 }
02027 
02028 
BOOL
02029 
IsAvailableTTFont(
02030     LPWSTR pwszFace
02031     )
02032 {
02033     
if (
SearchTTFont(pwszFace, FALSE, 0))
02034         
return TRUE;
02035     
else
02036         
return FALSE;
02037 }
02038 
02039 
BOOL
02040 
IsAvailableTTFontCP(
02041     LPWSTR pwszFace,
02042     UINT CodePage
02043     )
02044 {
02045     
if (
SearchTTFont(pwszFace, TRUE, CodePage))
02046         
return TRUE;
02047     
else
02048         
return FALSE;
02049 }
02050 
02051 LPWSTR
02052 
GetAltFaceName(
02053     LPWSTR pwszFace
02054     )
02055 {
02056     LPTTFONTLIST pTTFontList;
02057 
02058     pTTFontList = 
SearchTTFont(pwszFace, FALSE, 0);
02059     
if (pTTFontList != 
NULL) {
02060         
if (wcscmp(pwszFace, pTTFontList->FaceName1) == 0) {
02061             
return pTTFontList->FaceName2;
02062         }
02063         
if (wcscmp(pwszFace, pTTFontList->FaceName2) == 0) {
02064             
return pTTFontList->FaceName1;
02065         }
02066         
return NULL;
02067     }
02068     
else
02069         
return NULL;
02070 }
02071 
02072 
BOOL
02073 
IsAvailableFsCodePage(
02074     UINT CodePage
02075     )
02076 {
02077     PSINGLE_LIST_ENTRY pTemp = 
gRegFullScreenCodePage.Next;
02078 
02079     
while (pTemp != 
NULL) {
02080         
PFS_CODEPAGE pFsCodePage = (
PFS_CODEPAGE)pTemp;
02081 
02082         
if (pFsCodePage->
CodePage == CodePage) {
02083             
return TRUE;
02084         }
02085 
02086         pTemp = pTemp->Next;
02087     }
02088 
02089     
return FALSE;
02090 }
02091 
02092 
02093 
#if defined(FE_IME)
02094 
02095 
02096 
02097 
02098 
02099 
02100 
02101 
02102 
02103 
02104 
02105 
02106 
02107 
02108 
02109 
02110 
02111 
02112 
02113 
02114 
02115 
02116 
02117 
02118 
02119 
02120 
02121 
02122 
02123 
02124 
02125 
02126 
02127 
02128 
02129 
02130 
02131 
02132 
02133 
02134 
02135 
02136 
02137 
02138 
02139 
02140 
02141 
02142 
02143 
02144 
02145 
02146 
02147 
02148 
02149 
02150 
02151 
02152 
02153 
02154 
02155 
02156 
02157 
02158 
02159 
02160 
02161 
02162 
02163 
02164 
02165 
02166 
02167 
02168 
02169 
02170 
02171 
02172 
02173 
02174 
02175 
02176 
02177 
02178 
02179 
02180 
02181 
02182 
02183 
02184 
02185 
02186 
02187 
02188 
02189 
02190 
02191 
02192 
02193 
02194 
02195 
02196 
02197 
02198 
02199 
02200 
02201 
02202 
02203 
02204 
02205 
02206 
02207 
02208 
02209 
VOID
02210 ProcessCreateConsoleIME(
02211     IN LPMSG lpMsg,
02212     DWORD dwConsoleThreadId
02213     )
02214 {
02215     
NTSTATUS Status;
02216     HANDLE ConsoleHandle = (HANDLE)lpMsg->wParam;
02217     
PCONSOLE_INFORMATION pConsole;
02218     HWND hwndConIme;
02219 
02220     
Status = 
RevalidateConsole(ConsoleHandle, &pConsole);
02221     
if (!
NT_SUCCESS(Status)) {
02222         
return;  
02223     }
02224 
02225     hwndConIme = pConsole->
InputThreadInfo->hWndConsoleIME;
02226 
02227     
if (pConsole->
InputThreadInfo->hWndConsoleIME != 
NULL) {
02228         LRESULT lResult;
02229 
02230         
if (!
NT_SUCCESS(ConsoleImeMessagePumpWorker(pConsole,
02231                                   CONIME_CREATE,
02232                                   (WPARAM)pConsole->
ConsoleHandle,
02233                                   (LPARAM)pConsole->
hWnd,
02234                                   &lResult
02235                                  ))) {
02236             
goto TerminateConsoleIme;
02237         }
02238 
02239         
if (lResult)
02240         {
02241             
DBGPRINT((
"ConsoleIME connected(Create)\n")) ;
02242 
02243             
if (!CONSOLE_IS_DBCS_CP(pConsole))
02244                 pConsole->
InputBuffer.ImeMode.Disable = 
TRUE;
02245 
02246             CreateConvAreaModeSystem(pConsole);
02247 
02248             
if ((pConsole->
Flags & 
CONSOLE_HAS_FOCUS) ||
02249                 (pConsole->
FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE))
02250             {
02251                 
if (!
NT_SUCCESS(ConsoleImeMessagePump(pConsole,
02252                                       CONIME_SETFOCUS,
02253                                       (WPARAM)pConsole->
ConsoleHandle,
02254                                       (LPARAM)pConsole->
hklActive
02255                                      ))) {
02256                     
goto TerminateConsoleIme;
02257                 }
02258             }
02259 
02260             
if (pConsole->
CurrentScreenBuffer->
Flags & 
CONSOLE_TEXTMODE_BUFFER)
02261             {
02262                 
if (!
NT_SUCCESS(ConsoleImeMessagePump(pConsole,
02263                                       CONIME_NOTIFY_SCREENBUFFERSIZE,
02264                                       (WPARAM)pConsole->
ConsoleHandle,
02265                                       (LPARAM)MAKELPARAM(pConsole->
CurrentScreenBuffer->
ScreenBufferSize.X,
02266                                                          pConsole->
CurrentScreenBuffer->
ScreenBufferSize.Y)
02267                                      ))) {
02268                     
goto TerminateConsoleIme;
02269                 }
02270             }
02271             
if (!
NT_SUCCESS(ConsoleImeMessagePump(pConsole,
02272                                   CONIME_NOTIFY_CODEPAGE,
02273                                   (WPARAM)pConsole->
ConsoleHandle,
02274                                   (LPARAM)MAKELPARAM(FALSE, pConsole->
CP)
02275                                  ))) {
02276                 
goto TerminateConsoleIme;
02277             }
02278             
if (!
NT_SUCCESS(ConsoleImeMessagePump(pConsole,
02279                                   CONIME_NOTIFY_CODEPAGE,
02280                                   (WPARAM)pConsole->
ConsoleHandle,
02281                                   (LPARAM)MAKELPARAM(TRUE, pConsole->
OutputCP)
02282                                  ))) {
02283                 
goto TerminateConsoleIme;
02284             }
02285 
02286             
if (!
NT_SUCCESS(GetImeKeyState(pConsole, NULL))) {
02287                 
goto TerminateConsoleIme;
02288             }
02289         }
02290     }
02291     
else if (lpMsg->lParam) {
02292         
02293 
02294 
02295 
02296 
02297 
02298         
Status = 
QueueThreadMessage(dwConsoleThreadId,
02299                                     CM_CONIME_CREATE,
02300                                     (WPARAM)ConsoleHandle,
02301                                     (LPARAM)FALSE
02302                                     );
02303 
02304         
if (!
NT_SUCCESS(Status)) {
02305                 RIPMSG1(RIP_WARNING, 
"QueueThreadMessage(CM_CONIME_CREATE) failed (%08x)\n", Status);
02306         }
02307     }
02308     
UnlockConsole(pConsole);
02309 
02310     
return;
02311 
02312 TerminateConsoleIme:
02313     
if (
IsWindow(hwndConIme)) {
02314         
PostMessage(hwndConIme, CONIME_DESTROY, (WPARAM)ConsoleHandle, (LPARAM)NULL);
02315     }
02316 }
02317 
02318 
NTSTATUS
02319 InitConsoleIMEStuff(
02320     HDESK hDesktop,
02321     DWORD dwConsoleThreadId,
02322     
PCONSOLE_INFORMATION Console
02323     )
02324 {
02325     
NTSTATUS Status = STATUS_SUCCESS;
02326     CONSOLE_REGISTER_CONSOLEIME RegConIMEInfo;
02327     HANDLE hThread = 
NULL;
02328     
BOOL First = 
FALSE;
02329 
02330     
if (!
gfLoadConIme) {
02331         KdPrint((
"CONSRV: InitConsoleIMEStuff is skipping conime loading\n"));
02332         
return STATUS_UNSUCCESSFUL; 
02333     }
02334 
02335     RtlEnterCriticalSection(&ConIMEInitWindowsLock);
02336 
02337     RegConIMEInfo.hdesk      = hDesktop;
02338     RegConIMEInfo.dwThreadId = 0;
02339     RegConIMEInfo.dwAction   = REGCONIME_QUERY;
02340     
NtUserConsoleControl(ConsoleRegisterConsoleIME, &RegConIMEInfo, 
sizeof(RegConIMEInfo));
02341     
if (RegConIMEInfo.dwThreadId == 0)
02342     {
02343         
02344 
02345 
02346 
02347         hThread = 
InternalCreateCallbackThread(
CONSOLE_CLIENTPROCESSHANDLE(),
02348                                                (ULONG_PTR)ConsoleIMERoutine,
02349                                                (ULONG_PTR)0);
02350         
if (hThread == 
NULL) {
02351             KdPrint((
"CONSRV: CreateRemoteThread failed %x\n",GetLastError()));
02352         }
02353         
else
02354         {
02355             
02356 
02357 
02358 
02359             
Status = 
QueueThreadMessage(dwConsoleThreadId,
02360                                         CM_WAIT_CONIME_PROCESS,
02361                                         (WPARAM)hDesktop,
02362                                         (LPARAM)hThread
02363                                         );
02364             
if (!
NT_SUCCESS(Status)) {
02365                 RIPMSG1(RIP_WARNING, 
"QueueThreadMessage(CM_WAIT_CONIME_PROCESS) failed (%08x)\n", Status);
02366             } 
else {
02367                 First = 
TRUE;
02368             }
02369         }
02370     }
02371 
02372     
Status = 
QueueThreadMessage(dwConsoleThreadId,
02373                                 CM_CONIME_CREATE,
02374                                 (WPARAM)Console->
ConsoleHandle,
02375                                 (LPARAM)First
02376                                 );
02377     
if (!
NT_SUCCESS(Status)) {
02378         RIPMSG1(RIP_WARNING, 
"InitConsoleIMEStuff: QueueThreadMessage(CM_CONIME_CREATE) failed (%08x)\n", Status);
02379     }
02380 
02381     RtlLeaveCriticalSection(&ConIMEInitWindowsLock);
02382 
02383     
return Status;
02384 }
02385 
02386 
NTSTATUS
02387 WaitConsoleIMEStuff(
02388     HDESK hDesktop,
02389     HANDLE hThread
02390     )
02391 {
02392     
NTSTATUS Status = STATUS_SUCCESS;
02393     CONSOLE_REGISTER_CONSOLEIME RegConIMEInfo;
02394 
02395     RtlEnterCriticalSection(&ConIMEInitWindowsLock);
02396 
02397     RegConIMEInfo.hdesk      = hDesktop;
02398     RegConIMEInfo.dwThreadId = 0;
02399     RegConIMEInfo.dwAction   = REGCONIME_QUERY;
02400     
NtUserConsoleControl(ConsoleRegisterConsoleIME, &RegConIMEInfo, 
sizeof(RegConIMEInfo));
02401 
02402     RtlLeaveCriticalSection(&ConIMEInitWindowsLock);
02403 
02404     
if (RegConIMEInfo.dwThreadId == 0)
02405     {
02406         
int cLoops;
02407         LARGE_INTEGER li;
02408 
02409         
02410 
02411 
02412 
02413 
02414 
02415 
02416         cLoops = 80;
02417         li.QuadPart = (LONGLONG)-10000 * 250;
02418         
while (cLoops--)
02419         {
02420             
02421 
02422 
02423             
Status = 
NtWaitForSingleObject(hThread, FALSE, &li);
02424             
if (
Status != STATUS_TIMEOUT) {
02425                 
break;
02426             }
02427 
02428             RtlEnterCriticalSection(&ConIMEInitWindowsLock);
02429             RegConIMEInfo.hdesk      = hDesktop;
02430             RegConIMEInfo.dwThreadId = 0;
02431             RegConIMEInfo.dwAction   = REGCONIME_QUERY;
02432             
NtUserConsoleControl(ConsoleRegisterConsoleIME, &RegConIMEInfo, 
sizeof(RegConIMEInfo));
02433             RtlLeaveCriticalSection(&ConIMEInitWindowsLock);
02434             
if (RegConIMEInfo.dwThreadId != 0) {
02435                 
break;
02436             }
02437         }
02438     }
02439 
02440     
NtClose(hThread);
02441 
02442     
return Status;
02443 }
02444 
02445 
NTSTATUS
02446 ConSrvRegisterConsoleIME(
02447     PCSR_PROCESS Process,
02448     HDESK hDesktop,
02449     HWINSTA hWinSta,
02450     HWND  hWndConsoleIME,
02451     DWORD dwConsoleIMEThreadId,
02452     DWORD dwAction,
02453     DWORD *dwConsoleThreadId
02454     )
02455 {
02456     
NTSTATUS Status;
02457     CONSOLE_REGISTER_CONSOLEIME RegConIMEInfo;
02458     
PCONSOLE_PER_PROCESS_DATA ProcessData;
02459 
02460     RtlEnterCriticalSection(&ConIMEInitWindowsLock);
02461 
02462     ProcessData = 
CONSOLE_FROMPROCESSPERPROCESSDATA(Process);
02463 
02464     RegConIMEInfo.hdesk      = hDesktop;
02465     RegConIMEInfo.dwThreadId = 0;
02466     RegConIMEInfo.dwAction   = REGCONIME_QUERY;
02467     
NtUserConsoleControl(ConsoleRegisterConsoleIME, &RegConIMEInfo, 
sizeof(RegConIMEInfo));
02468     
if (RegConIMEInfo.dwConsoleInputThreadId == 0)
02469     {
02470         
Status = STATUS_UNSUCCESSFUL;
02471         
goto ErrorExit;
02472     }
02473 
02474     
if (RegConIMEInfo.dwThreadId == 0)
02475     {
02476         
02477 
02478 
02479         
if (dwAction == REGCONIME_REGISTER)
02480         {
02481             
02482 
02483 
02484             RegConIMEInfo.hdesk      = hDesktop;
02485             RegConIMEInfo.dwThreadId = dwConsoleIMEThreadId;
02486             RegConIMEInfo.dwAction   = dwAction;
02487             
Status = 
NtUserConsoleControl(ConsoleRegisterConsoleIME, &RegConIMEInfo, 
sizeof(RegConIMEInfo));
02488             
if (
NT_SUCCESS(Status)) {
02489                 
Status = 
QueueThreadMessage(RegConIMEInfo.dwConsoleInputThreadId,
02490                                             CM_SET_CONSOLEIME_WINDOW,
02491                                             (WPARAM)hWndConsoleIME,
02492                                             0
02493                                             );
02494                 
if (!
NT_SUCCESS(Status)) {
02495                     RIPMSG1(RIP_WARNING, 
"ConSrvRegisterConsoleIME: QueueThreadMessage failed (%08x)\n", Status);
02496                     
Status = STATUS_UNSUCCESSFUL;
02497                     
goto ErrorExit;
02498                 }
02499 
02500                 ProcessData->hDesk = hDesktop;
02501                 ProcessData->hWinSta = hWinSta;
02502 
02503                 
if (
dwConsoleThreadId)
02504                     *
dwConsoleThreadId = RegConIMEInfo.dwConsoleInputThreadId;
02505             }
02506         }
02507         
else
02508         {
02509             
Status = STATUS_UNSUCCESSFUL;
02510             
goto ErrorExit;
02511         }
02512     }
02513     
else
02514     {
02515         
02516 
02517 
02518         
if ( (dwAction == REGCONIME_UNREGISTER) ||
02519              (dwAction == REGCONIME_TERMINATE)     )
02520         {
02521             
02522 
02523 
02524             RegConIMEInfo.hdesk      = hDesktop;
02525             RegConIMEInfo.dwThreadId = dwConsoleIMEThreadId;
02526             RegConIMEInfo.dwAction   = dwAction;
02527             
Status = 
NtUserConsoleControl(ConsoleRegisterConsoleIME, &RegConIMEInfo, 
sizeof(RegConIMEInfo));
02528             
if (
NT_SUCCESS(Status)) {
02529                 
Status = 
QueueThreadMessage(RegConIMEInfo.dwConsoleInputThreadId,
02530                                             CM_SET_CONSOLEIME_WINDOW,
02531                                             (WPARAM)NULL,
02532                                             0
02533                                             );
02534                 
if (!
NT_SUCCESS(Status)) {
02535                     RIPMSG1(RIP_WARNING, 
"ConSrvRegisterConsoleIME: QueueThreadMessage failed (%08x)\n", Status);
02536                     
Status = STATUS_UNSUCCESSFUL;
02537                     
goto ErrorExit;
02538                 }
02539 
02540                 CloseDesktop(ProcessData->hDesk);
02541                 
CloseWindowStation(ProcessData->hWinSta);
02542 
02543                 ProcessData->hDesk = 
NULL;
02544                 ProcessData->hWinSta = 
NULL;
02545 
02546                 
if (
dwConsoleThreadId)
02547                     *
dwConsoleThreadId = RegConIMEInfo.dwConsoleInputThreadId;
02548             }
02549         }
02550         
else
02551         {
02552             
Status = STATUS_UNSUCCESSFUL;
02553             
goto ErrorExit;
02554         }
02555     }
02556 
02557 
ErrorExit:
02558     
if (! 
NT_SUCCESS(Status))
02559     {
02560         CloseDesktop(hDesktop);
02561         
CloseWindowStation(hWinSta);
02562     }
02563 
02564     RtlLeaveCriticalSection(&ConIMEInitWindowsLock);
02565 
02566     
return Status;
02567 }
02568 
02569 
02570 
VOID
02571 RemoveConsoleIME(
02572     PCSR_PROCESS Process,
02573     DWORD dwConsoleIMEThreadId
02574     )
02575 {
02576     
NTSTATUS Status;
02577     CONSOLE_REGISTER_CONSOLEIME RegConIMEInfo;
02578     
PCONSOLE_PER_PROCESS_DATA ProcessData;
02579 
02580     ProcessData = 
CONSOLE_FROMPROCESSPERPROCESSDATA(Process);
02581 
02582     
02583     
02584     
02585     RtlEnterCriticalSection(&ConIMEInitWindowsLock);
02586 
02587     RegConIMEInfo.hdesk      = ProcessData->hDesk;
02588     RegConIMEInfo.dwThreadId = 0;
02589     RegConIMEInfo.dwAction   = REGCONIME_QUERY;
02590     
NtUserConsoleControl(ConsoleRegisterConsoleIME, &RegConIMEInfo, 
sizeof(RegConIMEInfo));
02591     
if (RegConIMEInfo.dwConsoleInputThreadId == 0)
02592     {
02593         
Status = STATUS_UNSUCCESSFUL;
02594     }
02595     
else
02596     
if (dwConsoleIMEThreadId == RegConIMEInfo.dwThreadId)
02597     {
02598         
02599 
02600 
02601         
Status = ConSrvRegisterConsoleIME(Process,
02602                                           ProcessData->hDesk,
02603                                           ProcessData->hWinSta,
02604                                           NULL,
02605                                           dwConsoleIMEThreadId,
02606                                           REGCONIME_TERMINATE,
02607                                           NULL
02608                                          );
02609     }
02610     RtlLeaveCriticalSection(&ConIMEInitWindowsLock);
02611 
02612     
return;
02613 }
02614 
02615 
02616 
02617 
02618 
02619 
02620 
02621 
02622 
02623 
02624 
02625 
02626 
02627 
NTSTATUS
02628 ConsoleImeMessagePumpWorker(
02629     
PCONSOLE_INFORMATION Console,
02630     UINT    Message,
02631     WPARAM  wParam,
02632     LPARAM  lParam,
02633     LRESULT* lplResult)
02634 {
02635     HWND    hWndConsoleIME = Console->
InputThreadInfo->hWndConsoleIME;
02636     LRESULT fNoTimeout;
02637     
PINPUT_THREAD_INFO InputThreadInfo;     
02638 
02639     *lplResult = 0;
02640 
02641     
if (hWndConsoleIME == 
NULL)
02642     {
02643         
return STATUS_SUCCESS;
02644     }
02645 
02646     InputThreadInfo = TlsGetValue(InputThreadTlsIndex);
02647 
02648     
if (InputThreadInfo != 
NULL)
02649     {
02650         HWND 
hWnd = Console->
hWnd;
02651 
02652         
02653 
02654 
02655 
02656 
02657         fNoTimeout = 
SendMessageTimeout(hWndConsoleIME,
02658                                         Message,
02659                                         wParam,
02660                                         lParam,
02661                                         SMTO_ABORTIFHUNG | SMTO_NORMAL,
02662                                         CONIME_SENDMSG_TIMEOUT,
02663                                         lplResult);
02664         
if (fNoTimeout)
02665         {
02666             
return STATUS_SUCCESS;
02667         }
02668 
02669         
if ((Console = 
GetWindowConsole(hWnd)) == 
NULL ||
02670                 (Console->
Flags & 
CONSOLE_TERMINATING)) {
02671 
02672             
02673             
02674 
02675             
return STATUS_INVALID_HANDLE;
02676         }
02677 
02678         
02679 
02680 
02681 
02682     }
02683 
02684     
02685 
02686 
02687 
02688 
02689     
DBGPRINT((
"ConsoleImeMessagePumpWorker::PostMessage(0x%x)\n",Message));
02690     
PostMessage(hWndConsoleIME,
02691                 Message,
02692                 wParam,
02693                 lParam);
02694 
02695     
return STATUS_SUCCESS;
02696 }
02697 
02698 
NTSTATUS
02699 ConsoleImeMessagePump(
02700     
PCONSOLE_INFORMATION Console,
02701     UINT   Message,
02702     WPARAM wParam,
02703     LPARAM lParam
02704     )
02705 {
02706     LRESULT lResultDummy;
02707 
02708     
return ConsoleImeMessagePumpWorker(Console, Message, wParam, lParam, &lResultDummy);
02709 }
02710 
02711 
#endif // FE_IME
02712 
02713 
02714 
02715 
02716 
BOOL
02717 
RegisterKeisenOfTTFont(
02718     IN 
PSCREEN_INFORMATION ScreenInfo
02719     )
02720 {
02721     
NTSTATUS Status;
02722     COORD FontSize;
02723     
DWORD BuffSize;
02724     
LPSTRINGBITMAP StringBitmap;
02725     WCHAR wChar;
02726     WCHAR wCharBuf[2];
02727     ULONG ulNumFonts;
02728     
DWORD dwFonts;
02729     
PCONSOLE_INFORMATION Console = ScreenInfo->Console;
02730 
02731     
GetNumFonts(&ulNumFonts);
02732     
for (dwFonts=0; dwFonts < ulNumFonts; dwFonts++) {
02733         
if (!
TM_IS_TT_FONT(FontInfo[dwFonts].Family) &&
02734             IS_ANY_DBCS_CHARSET(FontInfo[dwFonts].tmCharSet)
02735            ) {
02736             
GetFontSize(dwFonts, &FontSize);
02737             BuffSize = 
CalcBitmapBufferSize(FontSize,BYTE_ALIGN);
02738             StringBitmap = 
ConsoleHeapAlloc( 
MAKE_TAG( TMP_DBCS_TAG ), 
sizeof(
STRINGBITMAP) + BuffSize);
02739             
if (StringBitmap == 
NULL) {
02740                 RIPMSG1(RIP_WARNING, 
"RegisterKeisenOfTTFont: cannot allocate memory (%d bytes)",
02741                           
sizeof(
STRINGBITMAP) + BuffSize);
02742                 
return FALSE;
02743             }
02744 
02745             
if (SelectObject(Console->
hDC,FontInfo[dwFonts].hFont)==0) {
02746                 
goto error_return;
02747             }
02748 
02749             
for (wChar=0; wChar < 
UNICODE_SPACE; wChar++) {
02750                 wCharBuf[0] = wChar;
02751                 wCharBuf[1] = TEXT(
'\0');;
02752                 
if (
GetStringBitmapW(Console->
hDC,
02753                                      wCharBuf,
02754                                      1,
02755                                      
sizeof(
STRINGBITMAP) + BuffSize,
02756                                      (BYTE*)StringBitmap
02757                                     ) == 0) {
02758                     
goto error_return;
02759                 }
02760                 FontSize.X = (WORD)StringBitmap->
uiWidth;
02761                 FontSize.Y = (WORD)StringBitmap->
uiHeight;
02762                 
Status = 
RegisterLocalEUDC(Console,wChar,FontSize,StringBitmap->
ajBits);
02763                 
if (! 
NT_SUCCESS(Status)) {
02764 error_return:
02765                     
ConsoleHeapFree(StringBitmap);
02766                     
return FALSE;
02767                 }
02768             }
02769 
02770             
ConsoleHeapFree(StringBitmap);
02771         }
02772         ((
PEUDC_INFORMATION)(Console->EudcInformation))->LocalKeisenEudcMode = 
TRUE ;
02773     }
02774     
return TRUE;
02775 }
02776 
02777 ULONG
02778 
TranslateUnicodeToOem(
02779     IN 
PCONSOLE_INFORMATION Console,
02780     IN PWCHAR UnicodeBuffer,
02781     IN ULONG UnicodeCharCount,
02782     OUT PCHAR AnsiBuffer,
02783     IN ULONG AnsiByteCount,
02784     OUT PINPUT_RECORD DbcsLeadInpRec
02785     )
02786 {
02787     ULONG i,j;
02788     PWCHAR TmpUni;
02789     
BYTE AsciiDbcs[2];
02790     ULONG NumBytes;
02791 
02792     TmpUni = 
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),UnicodeCharCount*
sizeof(WCHAR));
02793     
if (TmpUni == 
NULL)
02794         
return 0;
02795 
02796     memcpy(TmpUni,UnicodeBuffer,UnicodeCharCount*
sizeof(WCHAR));
02797     AsciiDbcs[1] = 0;
02798     
for (i=0,j=0; i<UnicodeCharCount; i++,j++) {
02799         
if (IsConsoleFullWidth(Console->hDC,Console->CP,TmpUni[i])) {
02800             NumBytes = 
sizeof(AsciiDbcs);
02801             
ConvertToOem(Console->CP,
02802                    &TmpUni[i],
02803                    1,
02804                    &AsciiDbcs[0],
02805                    NumBytes
02806                    );
02807             
if (
IsDBCSLeadByteConsole(AsciiDbcs[0],&Console->CPInfo)) {
02808                 
if (j < AnsiByteCount-1) {  
02809                     AnsiBuffer[j] = AsciiDbcs[0];
02810                     j++;
02811                     AnsiBuffer[j] = AsciiDbcs[1];
02812                     AsciiDbcs[1] = 0;
02813                 }
02814                 
else if (j == AnsiByteCount-1) {
02815                     AnsiBuffer[j] = AsciiDbcs[0];
02816                     j++;
02817                     
break;
02818                 }
02819                 
else {
02820                     AsciiDbcs[1] = 0;
02821                     
break;
02822                 }
02823             }
02824             
else {
02825                 AnsiBuffer[j] = AsciiDbcs[0];
02826                 AsciiDbcs[1] = 0;
02827             }
02828         }
02829         
else {
02830             
ConvertToOem(Console->CP,
02831                    &TmpUni[i],
02832                    1,
02833                    &AnsiBuffer[j],
02834                    1
02835                    );
02836         }
02837     }
02838     
if (DbcsLeadInpRec) {
02839         
if (AsciiDbcs[1]) {
02840             DbcsLeadInpRec->EventType = KEY_EVENT;
02841             DbcsLeadInpRec->Event.KeyEvent.uChar.AsciiChar = AsciiDbcs[1];
02842         }
02843         
else {
02844             RtlZeroMemory(DbcsLeadInpRec,
sizeof(INPUT_RECORD));
02845         }
02846     }
02847     
ConsoleHeapFree(TmpUni);
02848     
return j;
02849 }
02850 
02851 
02852 
DWORD
02853 
ImmConversionToConsole(
02854     DWORD fdwConversion
02855     )
02856 {
02857     
DWORD dwNlsMode;
02858 
02859     
if (
GetKeyState(VK_KANA) & 
KEY_TOGGLED) {
02860         fdwConversion = (fdwConversion & ~IME_CMODE_LANGUAGE) | (IME_CMODE_NATIVE | IME_CMODE_KATAKANA);
02861     }
02862 
02863     dwNlsMode = 0;
02864     
if (fdwConversion & IME_CMODE_NATIVE) {
02865         
if (fdwConversion & IME_CMODE_KATAKANA)
02866             dwNlsMode |= NLS_KATAKANA;
02867         
else
02868             dwNlsMode |= NLS_HIRAGANA;
02869     }
02870     
else {
02871         dwNlsMode |= NLS_ALPHANUMERIC;
02872     }
02873 
02874     
if (fdwConversion & IME_CMODE_FULLSHAPE)
02875         dwNlsMode |= NLS_DBCSCHAR;
02876 
02877     
if (fdwConversion & IME_CMODE_ROMAN)
02878         dwNlsMode |= NLS_ROMAN;
02879 
02880     
if (fdwConversion & 
IME_CMODE_OPEN)
02881         dwNlsMode |= NLS_IME_CONVERSION;
02882 
02883     
if (fdwConversion & 
IME_CMODE_DISABLE)
02884         dwNlsMode |= NLS_IME_DISABLE;
02885 
02886     
return dwNlsMode;
02887 }
02888 
02889 
DWORD
02890 
ImmConversionFromConsole(
02891     DWORD dwNlsMode
02892     )
02893 {
02894     
DWORD fdwConversion;
02895 
02896     fdwConversion = 0;
02897     
if (dwNlsMode & (NLS_KATAKANA | NLS_HIRAGANA)) {
02898         fdwConversion |= IME_CMODE_NATIVE;
02899         
if (dwNlsMode & NLS_KATAKANA)
02900             fdwConversion |= IME_CMODE_KATAKANA;
02901     }
02902 
02903     
if (dwNlsMode & NLS_DBCSCHAR)
02904         fdwConversion |= IME_CMODE_FULLSHAPE;
02905 
02906     
if (dwNlsMode & NLS_ROMAN)
02907         fdwConversion |= IME_CMODE_ROMAN;
02908 
02909     
if (dwNlsMode & NLS_IME_CONVERSION)
02910         fdwConversion |= 
IME_CMODE_OPEN;
02911 
02912     
if (dwNlsMode & NLS_IME_DISABLE)
02913         fdwConversion |= 
IME_CMODE_DISABLE;
02914 
02915     
return fdwConversion;
02916 }
02917 
02918 
02919 
02920 
02921 
02922 
02923 
02924 
02925 
02926 
02927 
02928 
02929 
#if defined(DBG) && defined(DBG_KATTR)
02930 
VOID
02931 BeginKAttrCheck(
02932     IN 
PSCREEN_INFORMATION ScreenInfo
02933     )
02934 {
02935     
SHORT RowIndex;
02936     
PROW Row;
02937     
SHORT i;
02938 
02939     RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow) % ScreenInfo->ScreenBufferSize.Y;
02940     Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
02941 
02942     
for (i=0;i<ScreenInfo->ScreenBufferSize.Y;i++) {
02943         
ASSERT (Row->
CharRow.KAttrs);
02944         
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
02945             RowIndex = 0;
02946         }
02947     }
02948 }
02949 
#endif // DBG && DBG_KATTR
02950 
02951 
#endif