00288 {
00289 WORD wModBits;
00290 WORD nShift;
00291 WCHAR *pUniChar;
00292 PVK_TO_WCHARS1 pVK;
00293 PVK_TO_WCHAR_TABLE pVKT;
00294
static WORD NumpadChar;
00295
static WORD VKLastDown;
00296
static BYTE ConvMode;
00297
PTHREADINFO ptiCurrent =
PtiCurrentShared();
00298
PKL pkl;
00299 PKBDTABLES pKbdTbl;
00300 PLIGATURE1 pLigature;
00301
00302 *pdwKeyFlags = (uScanCode & KBDBREAK);
00303
00304
if ((hkl ==
NULL) && ptiCurrent->
spklActive) {
00305 pkl = ptiCurrent->
spklActive;
00306 pKbdTbl = pkl->
spkf->
pKbdTbl;
00307 }
else {
00308 pkl =
HKLtoPKL(ptiCurrent, hkl);
00309
if (!pkl) {
00310
return 0;
00311 }
00312 pKbdTbl = pkl->
spkf->
pKbdTbl;
00313 }
00314 UserAssert(pkl != NULL);
00315 UserAssert(pKbdTbl != NULL);
00316
00317 pUniChar = awchChars;
00318
00319 uScanCode &= (0xFF | KBDEXT);
00320
00321
if (*pdwKeyFlags & KBDBREAK) {
00322
00323
00324
00325
00326
if (uVirtKey == VK_MENU) {
00327
if (NumpadChar) {
00328
if (ConvMode ==
NUMPADCONV_HEX_UNICODE) {
00329 *pUniChar = NumpadChar;
00330 }
else if (ConvMode ==
NUMPADCONV_OEMCP &&
00331 (ptiCurrent->
TIF_flags &
TIF_CSRSSTHREAD)) {
00332
00333
00334
00335
00336
00337 *pdwKeyFlags |= ALTNUMPAD_BIT;
00338 *pUniChar = NumpadChar;
00339 }
else {
00340
00341
00342
00343 WORD wCodePage;
00344
00345
if (ConvMode ==
NUMPADCONV_OEMCP) {
00346
00347
extern __declspec(dllimport) USHORT NlsOemCodePage;
00348
00349 wCodePage = (WORD)NlsOemCodePage;
00350 } else {
00351 wCodePage = pkl->
CodePage;
00352 }
00353
if (
IS_DBCS_CODEPAGE(wCodePage)) {
00354
if (NumpadChar & (WORD)~0xff) {
00355
00356
00357
00358
00359
00360 NumpadChar = MAKEWORD(
HIBYTE(NumpadChar),
LOBYTE(NumpadChar));
00361 }
else if (
IsDbcsExemptionForHighAnsi(wCodePage, NumpadChar)) {
00362
00363
00364
00365
00366
00367 wCodePage = 1252;
00368 }
00369 }
else {
00370
00371
00372
00373
00374 NumpadChar &= 0xff;
00375 }
00376
00377 *pUniChar =
xxxClientCharToWchar(wCodePage, NumpadChar);
00378 }
00379
00380
00381
00382
00383 VKLastDown = 0;
00384 ConvMode =
NUMPADCONV_OEMCP;
00385 NumpadChar = 0;
00386
gfInNumpadHexInput &= ~
NUMPAD_HEXMODE_HL;
00387
00388
return 1;
00389 }
else if (ConvMode !=
NUMPADCONV_OEMCP) {
00390 ConvMode =
NUMPADCONV_OEMCP;
00391 }
00392 }
else if (uVirtKey == VKLastDown) {
00393
00394
00395
00396
00397 VKLastDown = 0;
00398 }
00399 }
00400
00401
if (!(*pdwKeyFlags & KBDBREAK) || (uiTMFlags & TM_POSTCHARBREAKS)) {
00402
00403
00404
00405
00406
00407
00408 wModBits =
GetModifierBits(pKbdTbl->pCharModifiers, pfvk);
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
if (!(*pdwKeyFlags & KBDBREAK) &&
MODIFIER_FOR_ALT_NUMPAD(wModBits)) {
00430
00431
00432
00433
if ((uiTMFlags & TM_INMENUMODE) == 0) {
00434
if (
gfEnableHexNumpad && uScanCode ==
SCANCODE_NUMPAD_DOT) {
00435
if ((
gfInNumpadHexInput &
NUMPAD_HEXMODE_HL) == 0) {
00436
00437
00438
00439
00440 ConvMode =
NUMPADCONV_HEX_HKLCP;
00441
00442
00443
00444
00445
gfInNumpadHexInput |=
NUMPAD_HEXMODE_HL;
00446 TAGMSG0(DBGTAG_ToUnicode,
"NUMPADCONV_HEX_HKLCP");
00447 }
else {
00448
goto ExitNumpadMode;
00449 }
00450 }
else if (
gfEnableHexNumpad && uScanCode ==
SCANCODE_NUMPAD_PLUS) {
00451
if ((
gfInNumpadHexInput &
NUMPAD_HEXMODE_HL) == 0) {
00452
00453
00454
00455
00456 ConvMode =
NUMPADCONV_HEX_UNICODE;
00457
00458
00459
00460
00461
gfInNumpadHexInput |=
NUMPAD_HEXMODE_HL;
00462 TAGMSG0(DBGTAG_ToUnicode,
"NUMPADCONV_HEX_UNICODE");
00463 }
else {
00464
goto ExitNumpadMode;
00465 }
00466 }
else {
00467
int digit =
NumPadScanCodeToHex(uScanCode, uVirtKey);
00468
00469
if (digit < 0) {
00470
goto ExitNumpadMode;
00471 }
00472
00473
00474
00475
00476
if (VKLastDown == uVirtKey) {
00477
return 0;
00478 }
00479
00480
switch (ConvMode) {
00481
case NUMPADCONV_HEX_HKLCP:
00482
case NUMPADCONV_HEX_UNICODE:
00483
00484
00485
00486 TAGMSG1(DBGTAG_ToUnicode,
"->NUMPADCONV_HEX_*: old NumpadChar=%02x\n", NumpadChar);
00487 NumpadChar = NumpadChar * 0x10 + digit;
00488 TAGMSG1(DBGTAG_ToUnicode,
"<-NUMPADCONV_HEX_*: new NumpadChar=%02x\n", NumpadChar);
00489
break;
00490
default:
00491
00492
00493
00494 NumpadChar = NumpadChar * 10 + digit;
00495
00496
00497
00498
00499
if (NumpadChar == 0 && digit == 0) {
00500 ConvMode =
NUMPADCONV_HKLCP;
00501 }
00502
break;
00503 }
00504 }
00505 VKLastDown = (WORD)uVirtKey;
00506 }
else {
00507 ExitNumpadMode:
00508
00509
00510
00511 VKLastDown = 0;
00512 ConvMode =
NUMPADCONV_OEMCP;
00513 NumpadChar = 0;
00514 wModBits &= ~KBDALT;
00515
gfInNumpadHexInput &= ~
NUMPAD_HEXMODE_HL;
00516 }
00517 }
00518
00519
00520
00521
00522
if ((uVirtKey == VK_BACK) && (pKbdTbl->fLocaleFlags & KLLF_LRM_RLM)) {
00523
if (
TestKeyDownBit(pfvk, VK_LSHIFT)) {
00524 *pUniChar = 0x200E;
00525
return 1;
00526 }
else if (
TestKeyDownBit(pfvk, VK_RSHIFT)) {
00527 *pUniChar = 0x200F;
00528
return 1;
00529 }
00530 }
else if (((WORD)uVirtKey == VK_PACKET) && (
LOBYTE(uScanCode) == 0)) {
00531
return TranslateInjectedVKey(uScanCode, awchChars, uiTMFlags);
00532 }
00533
00534
00535
00536
00537
00538
for (pVKT = pKbdTbl->pVkToWcharTable; pVKT->pVkToWchars !=
NULL; pVKT++) {
00539 pVK = pVKT->pVkToWchars;
00540
while (pVK->VirtualKey != 0) {
00541
if (pVK->VirtualKey == (
BYTE)uVirtKey) {
00542
goto VK_Found;
00543 }
00544 pVK = (PVK_TO_WCHARS1)((
PBYTE)pVK + pVKT->cbSize);
00545 }
00546 }
00547
00548
00549
00550
00551
goto ReturnBadCharacter;
00552
00553 VK_Found:
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
if ((pVK->Attributes & KANALOK) && (
ISKANALOCKON(pfvk))) {
00565 wModBits |= KBDKANA;
00566 }
else
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
if ((pVK->Attributes & CAPLOK) && ((wModBits & ~KBDSHIFT) == 0) &&
00577
ISCAPSLOCKON(pfvk)) {
00578 wModBits ^= KBDSHIFT;
00579 }
else if ((pVK->Attributes & CAPLOKALTGR) &&
00580 ((wModBits & (KBDALT | KBDCTRL)) == (KBDALT | KBDCTRL)) &&
00581
ISCAPSLOCKON(pfvk)) {
00582 wModBits ^= KBDSHIFT;
00583 }
00584
00585
00586
00587
00588
00589
00590
if ((pVK->Attributes & SGCAPS) && ((wModBits & ~KBDSHIFT) == 0) &&
00591
ISCAPSLOCKON(pfvk)) {
00592 pVK = (PVK_TO_WCHARS1)((
PBYTE)pVK + pVKT->cbSize);
00593 }
00594
00595
00596
00597
00598
00599 nShift =
GetModificationNumber(pKbdTbl->pCharModifiers, wModBits);
00600
00601
if (nShift == SHFT_INVALID) {
00602
00603
00604
00605
goto ReturnBadCharacter;
00606
00607 }
else if ((nShift < pVKT->nModifications) &&
00608 (pVK->wch[nShift] != WCH_NONE)) {
00609
00610
00611
00612
00613
if (pVK->wch[nShift] == WCH_DEAD) {
00614
00615
00616
00617
00618 pVK = (PVK_TO_WCHARS1)((
PBYTE)pVK + pVKT->cbSize);
00619
00620
00621
00622
00623
if (pkl->
wchDiacritic == 0) {
00624 TAGMSG2(DBGTAG_ToUnicode,
00625
"xxxInternalToUnicode: new dead char '%C'(%x), goto ReturnDeadCharacter",
00626 pVK->wch[nShift], pVK->wch[nShift]);
00627
goto ReturnDeadCharacter;
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 TAGMSG4(DBGTAG_ToUnicode,
00639
"xxxInternalToUnicode: 2 dead chars '%C'(%x)+'%C'(%x)",
00640 pkl->
wchDiacritic, pkl->
wchDiacritic,
00641 pVK->wch[nShift], pVK->wch[nShift]);
00642
if (
GetAppCompatFlags2(VER40) & GACF2_NOCHAR_DEADKEY) {
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
goto ReturnDeadCharacter;
00657 }
00658
00659
goto ReturnGoodCharacter;
00660
00661 }
else if (pVK->wch[nShift] == WCH_LGTR) {
00662
00663
00664
00665
if ((GET_KBD_VERSION(pKbdTbl) == 0) || ((pLigature = pKbdTbl->pLigature) ==
NULL)) {
00666
00667
00668
00669
xxxMessageBeep(0);
00670
goto ReturnBadCharacter;
00671 }
00672
00673
while (pLigature->VirtualKey != 0) {
00674
int iLig = 0;
00675
int cwchT = 0;
00676
00677
if ((pLigature->VirtualKey == pVK->VirtualKey) &&
00678 (pLigature->ModificationNumber == nShift)) {
00679
00680
00681
00682
while ((iLig < pKbdTbl->nLgMax) && (cwchT < cChar)) {
00683
if (pLigature->wch[iLig] == WCH_NONE) {
00684
00685
00686
00687
return cwchT;
00688 }
00689
if (pkl->
wchDiacritic != 0) {
00690
int cComposed;
00691
00692
00693
00694
00695
00696
00697 cComposed =
ComposeDeadKeys(
00698 pkl,
00699 pKbdTbl->pDeadKey,
00700 pLigature->wch[iLig],
00701 pUniChar + cwchT,
00702 cChar - cwchT,
00703 *pdwKeyFlags & KBDBREAK
00704 );
00705
if (cComposed > 0) {
00706 cwchT += cComposed;
00707 }
else {
00708 RIPMSG2(RIP_ERROR,
00709
"InternalToUnicode: dead+lig(%x)->dead(%x)",
00710 pLigature->wch[0], pkl->
wchDiacritic);
00711 }
00712 }
else {
00713 pUniChar[cwchT++] = pLigature->wch[iLig];
00714 }
00715 iLig++;
00716 }
00717
return cwchT;
00718 }
00719
00720
00721
00722 pLigature = (PLIGATURE1)((
PBYTE)pLigature + pKbdTbl->cbLgEntry);
00723 }
00724
00725
00726
00727
xxxMessageBeep(0);
00728
goto ReturnBadCharacter;
00729 }
00730
00731
00732
00733
00734 TAGMSG2(DBGTAG_ToUnicode,
00735
"xxxInternalToUnicode: Match found '%C'(%x), goto ReturnGoodChar",
00736 pVK->wch[nShift], pVK->wch[nShift]);
00737
goto ReturnGoodCharacter;
00738
00739 }
else if ((wModBits == KBDCTRL) || (wModBits == (KBDCTRL|KBDSHIFT)) ||
00740 (wModBits == (KBDKANA|KBDCTRL)) || (wModBits == (KBDKANA|KBDCTRL|KBDSHIFT))) {
00741
00742
00743
00744
00745
00746
if ((uVirtKey >=
'A') && (uVirtKey <=
'Z')) {
00747
00748
00749
00750
00751
00752
00753 *pUniChar = (WORD)(uVirtKey & 0x1f);
00754
return 1;
00755 }
else if ((uVirtKey >= 0xFF61) && (uVirtKey <= 0xFF91)) {
00756
00757
00758
00759
00760
00761 *pUniChar = (WORD)(
InternalVkKeyScanEx((WCHAR)uVirtKey,pKbdTbl) & 0x1f);
00762
return 1;
00763 }
00764 }
00765 }
00766
00767 ReturnBadCharacter:
00768
00769
return 0;
00770
00771 ReturnDeadCharacter:
00772 *pUniChar = pVK->wch[nShift];
00773
00774
00775
00776
00777
if (!(*pdwKeyFlags & KBDBREAK)) {
00778 pkl->
wchDiacritic = *pUniChar;
00779 }
00780
00781 UserAssert(pKbdTbl->pDeadKey);
00782
00783
00784
00785
00786
return -1;
00787
00788 ReturnGoodCharacter:
00789
if ((pKbdTbl->pDeadKey !=
NULL) && (pkl->
wchDiacritic != 0)) {
00790
return ComposeDeadKeys(
00791 pkl,
00792 pKbdTbl->pDeadKey,
00793 pVK->wch[nShift],
00794 pUniChar,
00795 cChar,
00796 *pdwKeyFlags & KBDBREAK
00797 );
00798 }
00799 *pUniChar = (WORD)pVK->wch[nShift];
00800
return 1;
00801 }