592 // Since we handle dead keys ourselves, reset the keyboard dead key status (if any)
593 static BYTE kbState[256];
594 ::GetKeyboardState(kbState);
595 WORD ignored;
596 ::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0),
597 kbState, &ignored, 0, m_kbLayout);
598 }
599
600 void ViewContainer::HandleViewTypedEvent(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
601 {
602 if (!GetGlassView()) {
603 return;
604 }
605
606 int repCount = LOWORD(lParam);
607 jchar wChar;
608
609 if (!m_deadKeyWParam) {
610 wChar = (jchar)wParam;
611 } else {
612 wchar_t deadKey;
613
614 // Some dead keys need additional translation:
615 // http://www.fileformat.info/info/unicode/block/combining_diacritical_marks/images.htm
616 // Also see awt_Component.cpp for the original dead keys table
617 switch (m_deadKeyWParam) {
618 case L'`': deadKey = 0x300; break;
619 case L'\'': deadKey = 0x301; break;
620 case 0x00B4: deadKey = 0x301; break;
621 case L'^': deadKey = 0x302; break;
622 case L'~': deadKey = 0x303; break;
623 case 0x02DC: deadKey = 0x303; break;
624 case 0x00AF: deadKey = 0x304; break;
625 case 0x02D8: deadKey = 0x306; break;
626 case 0x02D9: deadKey = 0x307; break;
627 case L'"': deadKey = 0x308; break;
628 case 0x00A8: deadKey = 0x308; break;
629 case 0x02DA: deadKey = 0x30A; break;
630 case 0x02DD: deadKey = 0x30B; break;
631 case 0x02C7: deadKey = 0x30C; break;
632 case L',': deadKey = 0x327; break;
633 case 0x00B8: deadKey = 0x327; break;
634 case 0x02DB: deadKey = 0x328; break;
635 default: deadKey = static_cast<wchar_t>(m_deadKeyWParam); break;
636 }
637
638 wchar_t in[3] = {(wchar_t)wParam, deadKey, L'\0'};
639 wchar_t out[3];
640 int res = ::FoldString(MAP_PRECOMPOSED, (LPWSTR)in, 3, (LPWSTR)out, 3);
641
642 if (res > 0) {
643 wChar = (jchar)out[0];
644
645 if (res == 3) {
646 // The character cannot be accented, so we send a TYPED event
647 // for the dead key itself first.
648 SendViewTypedEvent(1, (jchar)m_deadKeyWParam);
649 }
650 } else {
651 // Folding failed. Use the untranslated original character then
652 wChar = (jchar)wParam;
653 }
654
655 // Clear the dead key
656 m_deadKeyWParam = 0;
657 }
658
659 SendViewTypedEvent(repCount, wChar);
660 }
|
592 // Since we handle dead keys ourselves, reset the keyboard dead key status (if any)
593 static BYTE kbState[256];
594 ::GetKeyboardState(kbState);
595 WORD ignored;
596 ::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0),
597 kbState, &ignored, 0, m_kbLayout);
598 }
599
600 void ViewContainer::HandleViewTypedEvent(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
601 {
602 if (!GetGlassView()) {
603 return;
604 }
605
606 int repCount = LOWORD(lParam);
607 jchar wChar;
608
609 if (!m_deadKeyWParam) {
610 wChar = (jchar)wParam;
611 } else {
612 // The character is composed together with the dead key, which
613 // may be translated into one or more combining characters.
614 const size_t COMP_SIZE = 5;
615 wchar_t comp[COMP_SIZE] = { (wchar_t)wParam };
616
617 // Some dead keys need additional translation:
618 // http://www.fileformat.info/info/unicode/block/combining_diacritical_marks/images.htm
619 // Also see awt_Component.cpp for the original dead keys table
620 if ((wParam >= 0x0370 && wParam < 0x0400)) {
621 // Greek alphabet
622 switch (m_deadKeyWParam) {
623 case L']': comp[1] = 0x300; break; // varia
624 case L';': comp[1] = 0x301; break; // oxia (wrong? generates tonos, not oxia)
625 case L'-': comp[1] = 0x304; break; // macron
626 case L'_': comp[1] = 0x306; break; // vrachy
627 case L':': comp[1] = 0x308; break; // dialytika
628 case L'"': comp[1] = 0x314; break; // dasia
629 case 0x0384: comp[1] = 0x341; break; // tonos
630 case L'[': comp[1] = 0x342; break; // perispomeni
631 case L'\'': comp[1] = 0x343; break; // psili
632 case L'~': comp[1] = 0x344; break; // dialytika oxia
633 case L'{': comp[1] = 0x345; break; // ypogegrammeni
634
635 case L'`': comp[1] = 0x308; comp[2] = 0x300; break; // dialytika varia
636 case L'\\': comp[1] = 0x313; comp[2] = 0x300; break; // psili varia
637 case L'/': comp[1] = 0x313; comp[2] = 0x301; break; // psili oxia
638 case L'=': comp[1] = 0x313; comp[2] = 0x342; break; // psili perispomeni
639 case L'|': comp[1] = 0x314; comp[2] = 0x300; break; // dasia varia
640 case L'?': comp[1] = 0x314; comp[2] = 0x301; break; // dasia oxia
641 case L'+': comp[1] = 0x314; comp[2] = 0x342; break; // dasia perispomeni
642
643 // AltGr dead chars don't work. Maybe kbd isn't reset properly?
644 // case 0x1fc1: comp[1] = 0x308; comp[2] = 0x342; break; // dialytika perispomeni
645 // case 0x1fde: comp[1] = 0x314; comp[2] = 0x301; comp[3] = 0x345; break; // dasia oxia ypogegrammeni
646
647 default: comp[1] = static_cast<wchar_t>(m_deadKeyWParam); break;
648 }
649 } else {
650 switch (m_deadKeyWParam) {
651 case L'`': comp[1] = 0x300; break;
652 case L'\'': comp[1] = 0x301; break;
653 case 0x00B4: comp[1] = 0x301; break;
654 case L'^': comp[1] = 0x302; break;
655 case L'~': comp[1] = 0x303; break;
656 case 0x02DC: comp[1] = 0x303; break;
657 case 0x00AF: comp[1] = 0x304; break;
658 case 0x02D8: comp[1] = 0x306; break;
659 case 0x02D9: comp[1] = 0x307; break;
660 case L'"': comp[1] = 0x308; break;
661 case 0x00A8: comp[1] = 0x308; break;
662 case 0x02DA: comp[1] = 0x30A; break;
663 case 0x02DD: comp[1] = 0x30B; break;
664 case 0x02C7: comp[1] = 0x30C; break;
665 case L',': comp[1] = 0x327; break;
666 case 0x00B8: comp[1] = 0x327; break;
667 case 0x02DB: comp[1] = 0x328; break;
668 default: comp[1] = static_cast<wchar_t>(m_deadKeyWParam); break;
669 }
670 }
671
672 int compSize = 3;
673 for (int i = 1; i < COMP_SIZE; i++) {
674 if (comp[i] == L'\0') {
675 compSize = i + 1;
676 break;
677 }
678 }
679 wchar_t out[3];
680
681 int res = ::FoldString(MAP_PRECOMPOSED, (LPWSTR)comp, compSize, (LPWSTR)out, 3);
682
683 if (res > 0) {
684 wChar = (jchar)out[0];
685
686 if (res == 3) {
687 // The character cannot be accented, so we send a TYPED event
688 // for the dead key itself first.
689 SendViewTypedEvent(1, (jchar)m_deadKeyWParam);
690 }
691 } else {
692 // Folding failed. Use the untranslated original character then
693 wChar = (jchar)wParam;
694 }
695
696 // Clear the dead key
697 m_deadKeyWParam = 0;
698 }
699
700 SendViewTypedEvent(repCount, wChar);
701 }
|