modules/graphics/src/main/native-glass/win/ViewContainer.cpp

Print this page
rev 8853 : RT-39464: Polytonic displays incorrectly when typed in (via TextField)


 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 }