Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

dbcs.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1985 - 1999, Microsoft Corporation 00004 00005 Module Name: 00006 00007 dbcs.c 00008 00009 Abstract: 00010 00011 Author: 00012 00013 KazuM Mar.05.1992 00014 00015 Revision History: 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; // This list contain TTFONTLIST data. 00048 00049 #if defined(i386) 00050 ULONG gdwMachineId; 00051 #endif 00052 00053 LPTHREAD_START_ROUTINE ConsoleIMERoutine; // client side console IME routine 00054 CRITICAL_SECTION ConIMEInitWindowsLock; 00055 00056 #if defined(i386) 00057 /* 00058 * NEC PC-98 OS/2 OEM character set 00059 * When FormatID is 0 or 80, Convert SBCS (00h-1Fh) font. 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 // Check code for must CONSOLE_TEXTMODE_BUFFER !! 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 Routine Description: 00139 00140 This routine get IME mode for KEY_EVENT_RECORD. 00141 00142 Arguments: 00143 00144 ConsoleInfo - Pointer to console information structure. 00145 00146 Return Value: 00147 00148 --*/ 00149 00150 { 00151 DWORD dwDummy; 00152 00153 /* 00154 * If pdwConversion is NULL, the caller doensn't want 00155 * the result --- but for code efficiency, let it 00156 * point to the dummy dword variable, so that 00157 * we don't have to care from here. 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; // console thread info 00170 00171 InputThreadInfo = TlsGetValue(InputThreadTlsIndex); 00172 00173 if (InputThreadInfo != NULL) 00174 { 00175 LRESULT lResult; 00176 00177 /* 00178 * This thread is in InputThread() 00179 * We can try message pump. 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 * This thread is in CsrApiRequestThread() 00202 * We can not try message pump. 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 Routine Description: 00241 00242 This routine get IME mode for KEY_EVENT_RECORD. 00243 00244 Arguments: 00245 00246 Console - Pointer to console information structure. 00247 00248 fdwConversion - IME conversion status. 00249 00250 Return Value: 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 // Output code page 00358 if ((ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) && 00359 (IsAvailableFarEastCodePage(CodePage) || IsAvailableFarEastCodePage(PrevCodePage))) 00360 { 00361 ConvertToCodePage(Console, PrevCodePage); 00362 AdjustFont(Console, CodePage); 00363 } 00364 // load special ROM font, if necessary 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 Routine Description: 00417 00418 This routine setup of line character code. 00419 00420 Arguments: 00421 00422 ScreenInfo - Pointer to screen information structure. 00423 00424 Return Value: 00425 00426 none. 00427 00428 --*/ 00429 00430 { 00431 if (CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console)) 00432 { 00433 if (OEMCP == JAPAN_CP || OEMCP == KOREAN_CP) 00434 { 00435 /* 00436 * This is Japanese/Korean case, 00437 * These characters maps grid of half width. 00438 * so, same as U+2500. 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 * This is FE case, 00451 * FE don't uses U+2500 because these grid characters 00452 * maps to full width. 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 Routine Description: 00483 00484 This routine check bisected on Ascii string end. 00485 00486 Arguments: 00487 00488 CodePage - Value of code page. 00489 00490 Buffer - Pointer to Ascii string buffer. 00491 00492 NumBytes - Number of Ascii string. 00493 00494 Return Value: 00495 00496 TRUE - Bisected character. 00497 00498 FALSE - Correctly. 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 Routine Description: 00534 00535 This routine write buffer with bisect. 00536 00537 Arguments: 00538 00539 Return Value: 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 // Check code for must CONSOLE_TEXTMODE_BUFFER !! 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 // Check start position of strings 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 // Check end position of strings 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 Routine Description: 00622 00623 This routine check bisect for clipboard process. 00624 00625 Arguments: 00626 00627 Return Value: 00628 00629 --*/ 00630 00631 { 00632 SHORT RowIndex; 00633 PROW Row; 00634 PROW RowNext; 00635 00636 #if defined(DBG) && defined(DBG_KATTR) 00637 // BeginKAttrCheck(ScreenInfo); 00638 #endif 00639 00640 #ifdef FE_SB 00641 // Check code for must CONSOLE_TEXTMODE_BUFFER !! 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 // Check start position of strings 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 // Check end position of strings 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 Routine Description: 00695 00696 This routine write buffer with bisect. 00697 00698 Arguments: 00699 00700 Return Value: 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 // Check code for must CONSOLE_TEXTMODE_BUFFER !! 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 // Check start position of strings 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 // Check end position of strings 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 * BOOL IsConsoleFullWidth(HDC hDC,DWORD CodePage,WCHAR wch) 00758 * 00759 * Determine if the given Unicode char is fullwidth or not. 00760 * 00761 * Return: 00762 * FASLE : half width. Uses 1 column per one character 00763 * TRUE : full width. Uses 2 columns per one character 00764 * 00765 * History: 00766 * 04-08-92 ShunK Created. 00767 * Jul-27-1992 KazuM Added Screen Information and Code Page Information. 00768 * Jan-29-1992 V-Hirots Substruct Screen Information. 00769 * Oct-06-1996 KazuM Not use RtlUnicodeToMultiByteSize and WideCharToMultiByte 00770 * Because 950 only defined 13500 chars, 00771 * and unicode defined almost 18000 chars. 00772 * So there are almost 4000 chars can not be mapped to big5 code. 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 /* ASCII */ 00789 return FALSE; 00790 else if (0x3041 <= wch && wch <= 0x3094) 00791 /* Hiragana */ 00792 return TRUE; 00793 else if (0x30a1 <= wch && wch <= 0x30f6) 00794 /* Katakana */ 00795 return TRUE; 00796 else if (0x3105 <= wch && wch <= 0x312c) 00797 /* Bopomofo */ 00798 return TRUE; 00799 else if (0x3131 <= wch && wch <= 0x318e) 00800 /* Hangul Elements */ 00801 return TRUE; 00802 else if (0xac00 <= wch && wch <= 0xd7a3) 00803 /* Korean Hangul Syllables */ 00804 return TRUE; 00805 else if (0xff01 <= wch && wch <= 0xff5e) 00806 /* Fullwidth ASCII variants */ 00807 return TRUE; 00808 else if (0xff61 <= wch && wch <= 0xff9f) 00809 /* Halfwidth Katakana variants */ 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 /* Halfwidth Hangule variants */ 00817 return FALSE; 00818 else if (0xffe0 <= wch && wch <= 0xffe6) 00819 /* Fullwidth symbol variants */ 00820 return TRUE; 00821 else if (0x4e00 <= wch && wch <= 0x9fa5) 00822 /* Han Ideographic */ 00823 return TRUE; 00824 else if (0xf900 <= wch && wch <= 0xfa2d) 00825 /* Han Compatibility Ideographs */ 00826 return TRUE; 00827 else 00828 { 00829 BOOL ret; 00830 00831 /* Unknown character */ 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 Routine Description: 00859 00860 This routine remove DBCS padding code. 00861 00862 Arguments: 00863 00864 Dst - Pointer to destination. 00865 00866 Src - Pointer to source. 00867 00868 NumBytes - Number of string. 00869 00870 OS2OemFormat - 00871 00872 Return Value: 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 Routine Description: 00917 00918 This routine remove DBCS padding code for cell format. 00919 00920 Arguments: 00921 00922 Dst - Pointer to destination. 00923 00924 Src - Pointer to source. 00925 00926 NumBytes - Number of string. 00927 00928 Return Value: 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, // sets new font by FontSize=0 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 // Check code for must CONSOLE_TEXTMODE_BUFFER !! 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, // in chars 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 Routine Description: 01281 01282 This routine text out everything. 01283 01284 Arguments: 01285 01286 Return Value: 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 // Check code for must CONSOLE_TEXTMODE_BUFFER !! 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, // hdcDest 01451 TextRect.right, // nXDest 01452 TextRect.top, // nYDest 01453 SCR_FONTSIZE(ScreenInfo).X * dwFullWidth, // nWidth 01454 SCR_FONTSIZE(ScreenInfo).Y, // nHeight 01455 EudcInfo->hDCLocalEudc, // hdcSrc 01456 0, // nXSrc 01457 0, // nYSrc 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 * Get TrueType Font Face name from registry. 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 * Get Full Screen from registry. 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 * InitialPalette 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 * ColorBuffer 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 * ColorBufferNoTranslate 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 * ModeFontPairs 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 * FullScreen\CodePage 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 // in chars 01842 ) 01843 01844 /* 01845 01846 this routine converts a unicode string from the real unicode characters 01847 to the NEC OS/2 unicode characters. 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; // there's nothing we can do 01867 } 01868 01869 /* 01870 * Test for characters < 0x20. If none are found, we don't have 01871 * any conversion to do! 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 * Fill in the CPTABLEINFO struct 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 * Make a copy of the MultiByteToWideChar table 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 * Modify the first 0x20 bytes so that they are glyphs. 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 * Point the Custom CP at the glyph table 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 * Console IME executing logic. 02096 * 02097 * KERNEL32:ConDllInitialize 02098 * If Reason is DLL_PROCESS_ATTACH 02099 * | 02100 * V 02101 * WINSRV:ConsoleClientConnectRoutine 02102 * | 02103 * V 02104 * SetUpConsole 02105 * | 02106 * V 02107 * AllocateConsole 02108 * PostThreadMessage(CM_CREATE_CONSOLE_WINDOW) 02109 * | 02110 * V 02111 * UnlockConsoleHandleTable 02112 * InitConsoleIMEStuff 02113 * | 02114 * V 02115 * If never register console IME 02116 * hThread = InternalCreateCallbackThread(ConsoleIMERoutine) 02117 * QueueThreadMessage(CM_WAIT_CONIME_PROCESS) 02118 * | 02119 * V 02120 * QueueThreadMessage(CM_CONIME_CREATE) 02121 * | 02122 * V 02123 * KERNEL32:NtWaitForMultipleObjects(InitEvents) 02124 * 02125 * 02126 * WINSRV:InputThread 02127 * | 02128 * V 02129 * GetMessage 02130 * Receive CM_CREATE_CONSOLE_WINDOW 02131 * | 02132 * V 02133 * ProcessCreateConsoleWindow 02134 * | 02135 * V 02136 * CreateWindowsWindow 02137 * | 02138 * V 02139 * CreateWindowEx 02140 * NtSetEvent(InitEvents) 02141 * | 02142 * V 02143 * GetMessage 02144 * Receive CM_WAIT_CONIME_PROCESS (this case is never register console IME) 02145 * | 02146 * V 02147 * WaitConsoleIMEStuff 02148 * If never register console IME 02149 * NtWaitForSingleObject(hThread, 20 sec) 02150 * 02151 * 02152 * KERNEL32:ConsoleIMERoutine 02153 * | 02154 * V 02155 * hEvent = CreateEvent(CONSOLEIME_EVENT) 02156 * If not exist named event 02157 * CreateProcess(conime.exe) 02158 * WaitForSingleObject(hEvent, 10 sec) 02159 * If WAIT_TIMEOUT 02160 * TerminateProcess 02161 * | 02162 * V 02163 * TerminateThread(hThread) 02164 * 02165 * 02166 * CONIME:WinMain 02167 * | 02168 * V 02169 * CreateWindow 02170 * RegisterConsoleIME 02171 * | 02172 * V 02173 * WINSRV:ConSrvRegisterConsoleIME 02174 * | 02175 * V 02176 * QueueThreadMessage(CM_SET_CONSOLEIME_WINDOW) 02177 * | 02178 * V 02179 * AttachThreadInput 02180 * SetEvent(CONSOLEIME_EVENT) 02181 * 02182 * 02183 * WINSRV:InputThread 02184 * | 02185 * V 02186 * GetMessage 02187 * Receive CM_CONIME_CREATE 02188 * | 02189 * V 02190 * ProcessCreateConsoleIME 02191 * If available hWndConsoleIME 02192 * hIMC = SendMessage(console IME, CONIME_CREATE) 02193 * Else 02194 * PostMessage(CM_CONIME_CREATE) 02195 * | 02196 * V 02197 * GetMessage 02198 * Receive CM_SET_CONSOLEIME_WINDOW 02199 * TlsGetValue()->hWndConsoleIME = wParam 02200 * 02201 * 02202 * TerminateProcess of Console IME 02203 * WINSRV:ConsoleClientDisconnectRoutine 02204 * | 02205 * V 02206 * RemoveConsoleIME 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; // STATUS_PROCESS_IS_TERMINATING 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 * This case, First = TRUE 02294 * Again post message of CM_CONIME_CREATE. 02295 * Becase hWndConsoleIME available when CM_SET_CONSOLEIME_WINDOW message 02296 * and it message will be run after this. 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; // the return value does not really matter... 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 * Create a Remote Thread on client side. 02345 * This remote thread do create a console IME process. 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 * CM_WAIT_CONIME_PROCESS 02357 * This message wait for ready to go console IME process. 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 * Do wait for ready to go console IME process. 02411 * 02412 * This wait code should after the CreateWindowsWindow 02413 * because doesn't finish DLL attach on client side 02414 * for wait a Console->InitEvents. 02415 */ 02416 cLoops = 80; 02417 li.QuadPart = (LONGLONG)-10000 * 250; 02418 while (cLoops--) 02419 { 02420 /* 02421 * Sleep for a second. 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 * never registered console ime thread. 02478 */ 02479 if (dwAction == REGCONIME_REGISTER) 02480 { 02481 /* 02482 * register 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 * do registered console ime thread. 02517 */ 02518 if ( (dwAction == REGCONIME_UNREGISTER) || 02519 (dwAction == REGCONIME_TERMINATE) ) 02520 { 02521 /* 02522 * unregister 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 // This is console IME process 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 * Unregister console IME 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 * Console IME message pump. 02618 * 02619 * Note for NT5 --- this function is build on bogus assumptions 02620 * (also has some nasty workaround for sloppy conime). 02621 * There's a chance that pConsole goes away while sendmessage 02622 * is processed by conime. 02623 * Keep in mind, anybody who calls this function should validate 02624 * the return status as appropriate. 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; // console thread info 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 * This thread is in InputThread() 02654 * We can try message pump. 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 // This console is terminated. 02673 // ConsoleImeMessagePump gives up SendMessage to conime. 02674 02675 return STATUS_INVALID_HANDLE; 02676 } 02677 02678 /* 02679 * Timeout return from SendMessageTimeout 02680 * Or, Hung hWndConsoleIME. 02681 */ 02682 } 02683 02684 /* 02685 * This thread is in CsrApiRequestThread() 02686 * We can not try message pump. 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) { // -1 is safe DBCS in buffer 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

Generated on Sat May 15 19:39:38 2004 for test by doxygen 1.3.7