< prev index next >

src/java.desktop/windows/native/libawt/windows/awt_Component.cpp

Print this page


   1 /*
   2  * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 240     m_PendingLeadByte = 0;
 241     m_bitsCandType = 0;
 242 
 243     windowMoveLockPosX = 0;
 244     windowMoveLockPosY = 0;
 245     windowMoveLockPosCX = 0;
 246     windowMoveLockPosCY = 0;
 247 
 248     m_hCursorCache = NULL;
 249 
 250     m_bSubclassed = FALSE;
 251     m_bPauseDestroy = FALSE;
 252 
 253     m_MessagesProcessing = 0;
 254     m_wheelRotationAmount = 0;
 255     if (!sm_PrimaryDynamicTableBuilt) {
 256         // do it once.
 257         AwtComponent::BuildPrimaryDynamicTable();
 258         sm_PrimaryDynamicTableBuilt = TRUE;
 259     }


 260 }
 261 
 262 AwtComponent::~AwtComponent()
 263 {
 264     DASSERT(AwtToolkit::IsMainThread());
 265 
 266     /* Disconnect all links. */
 267     UnlinkObjects();
 268 
 269     /*
 270      * All the messages for this component are processed, native
 271      * resources are freed, and Java object is not connected to
 272      * the native one anymore. So we can safely destroy component's
 273      * handle.
 274      */
 275     DestroyHWnd();
 276 
 277     if (sm_getComponentCache == this) {
 278         sm_getComponentCache = NULL;
 279     }


2935     {L'`',   java_awt_event_KeyEvent_VK_DEAD_GRAVE},
2936     {L'\'',  java_awt_event_KeyEvent_VK_DEAD_ACUTE},
2937     {0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE},
2938     {L'^',   java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX},
2939     {L'~',   java_awt_event_KeyEvent_VK_DEAD_TILDE},
2940     {0x02DC, java_awt_event_KeyEvent_VK_DEAD_TILDE},
2941     {0x00AF, java_awt_event_KeyEvent_VK_DEAD_MACRON},
2942     {0x02D8, java_awt_event_KeyEvent_VK_DEAD_BREVE},
2943     {0x02D9, java_awt_event_KeyEvent_VK_DEAD_ABOVEDOT},
2944     {L'"',   java_awt_event_KeyEvent_VK_DEAD_DIAERESIS},
2945     {0x00A8, java_awt_event_KeyEvent_VK_DEAD_DIAERESIS},
2946     {0x02DA, java_awt_event_KeyEvent_VK_DEAD_ABOVERING},
2947     {0x02DD, java_awt_event_KeyEvent_VK_DEAD_DOUBLEACUTE},
2948     {0x02C7, java_awt_event_KeyEvent_VK_DEAD_CARON},            // aka hacek
2949     {L',',   java_awt_event_KeyEvent_VK_DEAD_CEDILLA},
2950     {0x00B8, java_awt_event_KeyEvent_VK_DEAD_CEDILLA},
2951     {0x02DB, java_awt_event_KeyEvent_VK_DEAD_OGONEK},
2952     {0x037A, java_awt_event_KeyEvent_VK_DEAD_IOTA},             // ASCII ???
2953     {0x309B, java_awt_event_KeyEvent_VK_DEAD_VOICED_SOUND},
2954     {0x309C, java_awt_event_KeyEvent_VK_DEAD_SEMIVOICED_SOUND},

2955     {0,0}
2956 };
2957 
2958 // The full map of the current keyboard state including
2959 // windows virtual key, scancode, java virtual key, and unicode
2960 // for this key sans modifiers.
2961 // All but first element may be 0.
2962 // XXX in the update releases this is an addition to the unchanged existing code
2963 struct DynPrimaryKeymapEntry {
2964     UINT wkey;
2965     UINT scancode;
2966     UINT jkey;
2967     WCHAR unicode;
2968 };
2969 
2970 static DynPrimaryKeymapEntry dynPrimaryKeymap[256];
2971 
2972 void
2973 AwtComponent::InitDynamicKeyMapTable()
2974 {


3427        void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
3428        if (value != NULL) {
3429            isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag));
3430            return static_cast<UINT>(reinterpret_cast<INT_PTR>(value));
3431        }
3432     }
3433 
3434     // If the windows key is a return, wkey will equal 13 ('\r')
3435     // In this case, we want to return 10 ('\n')
3436     // Since ToAscii would convert VK_RETURN to '\r', we need
3437     // to have a special case here.
3438     if (wkey == VK_RETURN)
3439         return '\n';
3440 
3441     // high order bit in keyboardState indicates whether the key is down
3442     static const BYTE KEY_STATE_DOWN = 0x80;
3443     BYTE    keyboardState[AwtToolkit::KB_STATE_SIZE];
3444     AwtToolkit::GetKeyboardState(keyboardState);
3445 
3446     // apply modifiers to keyboard state if necessary

3447     if (modifiers) {
3448         BOOL shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK;
3449         BOOL altIsDown = modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK;
3450         BOOL ctrlIsDown = modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK;
3451 
3452         // Windows treats AltGr as Ctrl+Alt
3453         if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK) {
3454             altIsDown = TRUE;
3455             ctrlIsDown = TRUE;
3456         }
3457 
3458         if (shiftIsDown) {
3459             keyboardState[VK_SHIFT] |= KEY_STATE_DOWN;
3460         }
3461 
3462         // fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715)
3463         // Here we try to resolve a conflict with ::ToAsciiEx's translating
3464         // ALT+number key combinations. kdm@sarc.spb.su
3465         // yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail.
3466         if( IsNavigationKey(wkey) ) {
3467             keyboardState[VK_MENU] &= ~KEY_STATE_DOWN;
3468         }


3500                     TCHAR ch;
3501                     short vk;
3502                     for (ch = _T('\033'); ch < _T('\040'); ch++) {
3503                         vk = ::VkKeyScan(ch);
3504                         if (wkey == LOBYTE(vk)) {
3505                             UINT shiftState = HIBYTE(vk);
3506                             if ((shiftState & _VKS_CTRL_MASK) ||
3507                                 (!(shiftState & _VKS_SHIFT_MASK)
3508                                 == !shiftIsDown))
3509                             {
3510                                 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;
3511                             }
3512                             break;
3513                         }
3514                     }
3515                 }
3516             } // ctrlIsDown && altIsDown
3517         } // ctrlIsDown
3518     } // modifiers
3519 
3520     // instead of creating our own conversion tables, I'll let Win32
3521     // convert the character for me.
3522     WORD wChar[2];










3523     UINT scancode = ::MapVirtualKey(wkey, 0);
3524     int converted = ::ToUnicodeEx(wkey, scancode, keyboardState,
3525                                   wChar, 2, 0, GetKeyboardLayout());

3526 
3527     UINT translation;
3528     BOOL deadKeyFlag = (converted == 2);
3529 
3530     // Dead Key
3531     if (converted < 0) {
3532         translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
3533     } else
3534     // No translation available -- try known conversions or else punt.
3535     if (converted == 0) {
3536         if (wkey == VK_DELETE) {
3537             translation = '\177';
3538         } else
3539         if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) {
3540             translation = '0' + wkey - VK_NUMPAD0;
3541         } else {
3542             translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
3543         }
3544     } else
3545     // the caller expects a Unicode character.
3546     if (converted > 0) {
3547         translation = wChar[0];
3548     }
3549     if (ops == SAVE) {
3550         transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
3551                        reinterpret_cast<void*>(static_cast<INT_PTR>(translation)));


3665 {
3666     // We will simply create Java events here.
3667     WCHAR unicodeChar = character;
3668     MSG msg;
3669     InitMessage(&msg, WM_IME_CHAR, character,
3670                               MAKELPARAM(repCnt, flags));
3671 
3672     jint modifiers = GetJavaModifiers();
3673     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
3674                              ::JVM_CurrentTimeMillis(NULL, 0),
3675                              java_awt_event_KeyEvent_VK_UNDEFINED,
3676                              unicodeChar, modifiers,
3677                              java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
3678                              &msg);
3679     return mrConsume;
3680 }
3681 
3682 MsgRouting AwtComponent::WmChar(UINT character, UINT repCnt, UINT flags,
3683                                 BOOL system)
3684 {


3685     // Will only get WmChar messages with DBCS if we create them for
3686     // an Edit class in the WmForwardChar method. These synthesized
3687     // DBCS chars are ok to pass on directly to the default window
3688     // procedure. They've already been filtered through the Java key
3689     // event queue. We will never get the trail byte since the edit
3690     // class will PeekMessage(&msg, hwnd, WM_CHAR, WM_CHAR,
3691     // PM_REMOVE).  I would like to be able to pass this character off
3692     // via WM_AWT_FORWARD_BYTE, but the Edit classes don't seem to
3693     // like that.
3694 
3695     // We will simply create Java events here.
3696     UINT message = system ? WM_SYSCHAR : WM_CHAR;
3697 
3698     // The Alt modifier is reported in the 29th bit of the lParam,
3699     // i.e., it is the 13th bit of `flags' (which is HIWORD(lParam)).
3700     bool alt_is_down = (flags & (1<<13)) != 0;
3701 
3702     // Fix for bug 4141621, corrected by fix for bug 6223726: Alt+space doesn't invoke system menu
3703     // We should not pass this particular combination to Java.
3704 


   1 /*
   2  * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 240     m_PendingLeadByte = 0;
 241     m_bitsCandType = 0;
 242 
 243     windowMoveLockPosX = 0;
 244     windowMoveLockPosY = 0;
 245     windowMoveLockPosCX = 0;
 246     windowMoveLockPosCY = 0;
 247 
 248     m_hCursorCache = NULL;
 249 
 250     m_bSubclassed = FALSE;
 251     m_bPauseDestroy = FALSE;
 252 
 253     m_MessagesProcessing = 0;
 254     m_wheelRotationAmount = 0;
 255     if (!sm_PrimaryDynamicTableBuilt) {
 256         // do it once.
 257         AwtComponent::BuildPrimaryDynamicTable();
 258         sm_PrimaryDynamicTableBuilt = TRUE;
 259     }
 260 
 261     deadKeyActive = FALSE;
 262 }
 263 
 264 AwtComponent::~AwtComponent()
 265 {
 266     DASSERT(AwtToolkit::IsMainThread());
 267 
 268     /* Disconnect all links. */
 269     UnlinkObjects();
 270 
 271     /*
 272      * All the messages for this component are processed, native
 273      * resources are freed, and Java object is not connected to
 274      * the native one anymore. So we can safely destroy component's
 275      * handle.
 276      */
 277     DestroyHWnd();
 278 
 279     if (sm_getComponentCache == this) {
 280         sm_getComponentCache = NULL;
 281     }


2937     {L'`',   java_awt_event_KeyEvent_VK_DEAD_GRAVE},
2938     {L'\'',  java_awt_event_KeyEvent_VK_DEAD_ACUTE},
2939     {0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE},
2940     {L'^',   java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX},
2941     {L'~',   java_awt_event_KeyEvent_VK_DEAD_TILDE},
2942     {0x02DC, java_awt_event_KeyEvent_VK_DEAD_TILDE},
2943     {0x00AF, java_awt_event_KeyEvent_VK_DEAD_MACRON},
2944     {0x02D8, java_awt_event_KeyEvent_VK_DEAD_BREVE},
2945     {0x02D9, java_awt_event_KeyEvent_VK_DEAD_ABOVEDOT},
2946     {L'"',   java_awt_event_KeyEvent_VK_DEAD_DIAERESIS},
2947     {0x00A8, java_awt_event_KeyEvent_VK_DEAD_DIAERESIS},
2948     {0x02DA, java_awt_event_KeyEvent_VK_DEAD_ABOVERING},
2949     {0x02DD, java_awt_event_KeyEvent_VK_DEAD_DOUBLEACUTE},
2950     {0x02C7, java_awt_event_KeyEvent_VK_DEAD_CARON},            // aka hacek
2951     {L',',   java_awt_event_KeyEvent_VK_DEAD_CEDILLA},
2952     {0x00B8, java_awt_event_KeyEvent_VK_DEAD_CEDILLA},
2953     {0x02DB, java_awt_event_KeyEvent_VK_DEAD_OGONEK},
2954     {0x037A, java_awt_event_KeyEvent_VK_DEAD_IOTA},             // ASCII ???
2955     {0x309B, java_awt_event_KeyEvent_VK_DEAD_VOICED_SOUND},
2956     {0x309C, java_awt_event_KeyEvent_VK_DEAD_SEMIVOICED_SOUND},
2957     {0x0004, java_awt_event_KeyEvent_VK_COMPOSE},
2958     {0,0}
2959 };
2960 
2961 // The full map of the current keyboard state including
2962 // windows virtual key, scancode, java virtual key, and unicode
2963 // for this key sans modifiers.
2964 // All but first element may be 0.
2965 // XXX in the update releases this is an addition to the unchanged existing code
2966 struct DynPrimaryKeymapEntry {
2967     UINT wkey;
2968     UINT scancode;
2969     UINT jkey;
2970     WCHAR unicode;
2971 };
2972 
2973 static DynPrimaryKeymapEntry dynPrimaryKeymap[256];
2974 
2975 void
2976 AwtComponent::InitDynamicKeyMapTable()
2977 {


3430        void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
3431        if (value != NULL) {
3432            isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag));
3433            return static_cast<UINT>(reinterpret_cast<INT_PTR>(value));
3434        }
3435     }
3436 
3437     // If the windows key is a return, wkey will equal 13 ('\r')
3438     // In this case, we want to return 10 ('\n')
3439     // Since ToAscii would convert VK_RETURN to '\r', we need
3440     // to have a special case here.
3441     if (wkey == VK_RETURN)
3442         return '\n';
3443 
3444     // high order bit in keyboardState indicates whether the key is down
3445     static const BYTE KEY_STATE_DOWN = 0x80;
3446     BYTE    keyboardState[AwtToolkit::KB_STATE_SIZE];
3447     AwtToolkit::GetKeyboardState(keyboardState);
3448 
3449     // apply modifiers to keyboard state if necessary
3450     BOOL shiftIsDown = FALSE;
3451     if (modifiers) {
3452         shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK;
3453         BOOL altIsDown = modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK;
3454         BOOL ctrlIsDown = modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK;
3455 
3456         // Windows treats AltGr as Ctrl+Alt
3457         if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK) {
3458             altIsDown = TRUE;
3459             ctrlIsDown = TRUE;
3460         }
3461 
3462         if (shiftIsDown) {
3463             keyboardState[VK_SHIFT] |= KEY_STATE_DOWN;
3464         }
3465 
3466         // fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715)
3467         // Here we try to resolve a conflict with ::ToAsciiEx's translating
3468         // ALT+number key combinations. kdm@sarc.spb.su
3469         // yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail.
3470         if( IsNavigationKey(wkey) ) {
3471             keyboardState[VK_MENU] &= ~KEY_STATE_DOWN;
3472         }


3504                     TCHAR ch;
3505                     short vk;
3506                     for (ch = _T('\033'); ch < _T('\040'); ch++) {
3507                         vk = ::VkKeyScan(ch);
3508                         if (wkey == LOBYTE(vk)) {
3509                             UINT shiftState = HIBYTE(vk);
3510                             if ((shiftState & _VKS_CTRL_MASK) ||
3511                                 (!(shiftState & _VKS_SHIFT_MASK)
3512                                 == !shiftIsDown))
3513                             {
3514                                 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;
3515                             }
3516                             break;
3517                         }
3518                     }
3519                 }
3520             } // ctrlIsDown && altIsDown
3521         } // ctrlIsDown
3522     } // modifiers
3523 


3524     WORD wChar[2];
3525     int converted = 1;
3526     UINT ch = ::MapVirtualKey(wkey, 2);
3527     if (ch & 0x80000000) {
3528         // Dead key which is handled as a normal key
3529         isDeadKey = deadKeyActive = TRUE;
3530     } else if (deadKeyActive) {
3531         // We cannot use ::ToUnicodeEx if dead key is active because this will
3532         // break dead key function
3533         wChar[0] = shiftIsDown ? ch : tolower(ch);
3534     } else {
3535         UINT scancode = ::MapVirtualKey(wkey, 0);
3536         converted = ::ToUnicodeEx(wkey, scancode, keyboardState,
3537                                               wChar, 2, 0, GetKeyboardLayout());
3538     }
3539 
3540     UINT translation;
3541     BOOL deadKeyFlag = (converted == 2);
3542 
3543     // Dead Key
3544     if (converted < 0 || wChar[0] == 0 || isDeadKey) {
3545         translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
3546     } else
3547     // No translation available -- try known conversions or else punt.
3548     if (converted == 0) {
3549         if (wkey == VK_DELETE) {
3550             translation = '\177';
3551         } else
3552         if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) {
3553             translation = '0' + wkey - VK_NUMPAD0;
3554         } else {
3555             translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
3556         }
3557     } else
3558     // the caller expects a Unicode character.
3559     if (converted > 0) {
3560         translation = wChar[0];
3561     }
3562     if (ops == SAVE) {
3563         transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
3564                        reinterpret_cast<void*>(static_cast<INT_PTR>(translation)));


3678 {
3679     // We will simply create Java events here.
3680     WCHAR unicodeChar = character;
3681     MSG msg;
3682     InitMessage(&msg, WM_IME_CHAR, character,
3683                               MAKELPARAM(repCnt, flags));
3684 
3685     jint modifiers = GetJavaModifiers();
3686     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
3687                              ::JVM_CurrentTimeMillis(NULL, 0),
3688                              java_awt_event_KeyEvent_VK_UNDEFINED,
3689                              unicodeChar, modifiers,
3690                              java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
3691                              &msg);
3692     return mrConsume;
3693 }
3694 
3695 MsgRouting AwtComponent::WmChar(UINT character, UINT repCnt, UINT flags,
3696                                 BOOL system)
3697 {
3698     deadKeyActive = FALSE;
3699 
3700     // Will only get WmChar messages with DBCS if we create them for
3701     // an Edit class in the WmForwardChar method. These synthesized
3702     // DBCS chars are ok to pass on directly to the default window
3703     // procedure. They've already been filtered through the Java key
3704     // event queue. We will never get the trail byte since the edit
3705     // class will PeekMessage(&msg, hwnd, WM_CHAR, WM_CHAR,
3706     // PM_REMOVE).  I would like to be able to pass this character off
3707     // via WM_AWT_FORWARD_BYTE, but the Edit classes don't seem to
3708     // like that.
3709 
3710     // We will simply create Java events here.
3711     UINT message = system ? WM_SYSCHAR : WM_CHAR;
3712 
3713     // The Alt modifier is reported in the 29th bit of the lParam,
3714     // i.e., it is the 13th bit of `flags' (which is HIWORD(lParam)).
3715     bool alt_is_down = (flags & (1<<13)) != 0;
3716 
3717     // Fix for bug 4141621, corrected by fix for bug 6223726: Alt+space doesn't invoke system menu
3718     // We should not pass this particular combination to Java.
3719 


< prev index next >