Home | History | Annotate | Download | only in win
      1 /*
      2  * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "PlatformKeyboardEvent.h"
     28 
     29 #include <windows.h>
     30 #include <wtf/ASCIICType.h>
     31 
     32 using namespace WTF;
     33 
     34 namespace WebCore {
     35 
     36 static const unsigned short HIGH_BIT_MASK_SHORT = 0x8000;
     37 
     38 // FIXME: This is incomplete. We could change this to mirror
     39 // more like what Firefox does, and generate these switch statements
     40 // at build time.
     41 static String keyIdentifierForWindowsKeyCode(unsigned short keyCode)
     42 {
     43     switch (keyCode) {
     44         case VK_MENU:
     45             return "Alt";
     46         case VK_CONTROL:
     47             return "Control";
     48         case VK_SHIFT:
     49             return "Shift";
     50         case VK_CAPITAL:
     51             return "CapsLock";
     52         case VK_LWIN:
     53         case VK_RWIN:
     54             return "Win";
     55         case VK_CLEAR:
     56             return "Clear";
     57         case VK_DOWN:
     58             return "Down";
     59         // "End"
     60         case VK_END:
     61             return "End";
     62         // "Enter"
     63         case VK_RETURN:
     64             return "Enter";
     65         case VK_EXECUTE:
     66             return "Execute";
     67         case VK_F1:
     68             return "F1";
     69         case VK_F2:
     70             return "F2";
     71         case VK_F3:
     72             return "F3";
     73         case VK_F4:
     74             return "F4";
     75         case VK_F5:
     76             return "F5";
     77         case VK_F6:
     78             return "F6";
     79         case VK_F7:
     80             return "F7";
     81         case VK_F8:
     82             return "F8";
     83         case VK_F9:
     84             return "F9";
     85         case VK_F10:
     86             return "F11";
     87         case VK_F12:
     88             return "F12";
     89         case VK_F13:
     90             return "F13";
     91         case VK_F14:
     92             return "F14";
     93         case VK_F15:
     94             return "F15";
     95         case VK_F16:
     96             return "F16";
     97         case VK_F17:
     98             return "F17";
     99         case VK_F18:
    100             return "F18";
    101         case VK_F19:
    102             return "F19";
    103         case VK_F20:
    104             return "F20";
    105         case VK_F21:
    106             return "F21";
    107         case VK_F22:
    108             return "F22";
    109         case VK_F23:
    110             return "F23";
    111         case VK_F24:
    112             return "F24";
    113         case VK_HELP:
    114             return "Help";
    115         case VK_HOME:
    116             return "Home";
    117         case VK_INSERT:
    118             return "Insert";
    119         case VK_LEFT:
    120             return "Left";
    121         case VK_NEXT:
    122             return "PageDown";
    123         case VK_PRIOR:
    124             return "PageUp";
    125         case VK_PAUSE:
    126             return "Pause";
    127         case VK_SNAPSHOT:
    128             return "PrintScreen";
    129         case VK_RIGHT:
    130             return "Right";
    131         case VK_SCROLL:
    132             return "Scroll";
    133         case VK_SELECT:
    134             return "Select";
    135         case VK_UP:
    136             return "Up";
    137         // Standard says that DEL becomes U+007F.
    138         case VK_DELETE:
    139             return "U+007F";
    140         default:
    141             return String::format("U+%04X", toASCIIUpper(keyCode));
    142     }
    143 }
    144 
    145 static bool isKeypadEvent(WPARAM code, LPARAM keyData, PlatformKeyboardEvent::Type type)
    146 {
    147     if (type != PlatformKeyboardEvent::RawKeyDown && type != PlatformKeyboardEvent::KeyUp)
    148         return false;
    149 
    150     switch (code) {
    151         case VK_NUMLOCK:
    152         case VK_NUMPAD0:
    153         case VK_NUMPAD1:
    154         case VK_NUMPAD2:
    155         case VK_NUMPAD3:
    156         case VK_NUMPAD4:
    157         case VK_NUMPAD5:
    158         case VK_NUMPAD6:
    159         case VK_NUMPAD7:
    160         case VK_NUMPAD8:
    161         case VK_NUMPAD9:
    162         case VK_MULTIPLY:
    163         case VK_ADD:
    164         case VK_SEPARATOR:
    165         case VK_SUBTRACT:
    166         case VK_DECIMAL:
    167         case VK_DIVIDE:
    168             return true;
    169         case VK_RETURN:
    170             return HIWORD(keyData) & KF_EXTENDED;
    171         case VK_INSERT:
    172         case VK_DELETE:
    173         case VK_PRIOR:
    174         case VK_NEXT:
    175         case VK_END:
    176         case VK_HOME:
    177         case VK_LEFT:
    178         case VK_UP:
    179         case VK_RIGHT:
    180         case VK_DOWN:
    181             return !(HIWORD(keyData) & KF_EXTENDED);
    182         default:
    183             return false;
    184     }
    185 }
    186 
    187 static inline String singleCharacterString(UChar c) { return String(&c, 1); }
    188 
    189 PlatformKeyboardEvent::PlatformKeyboardEvent(HWND, WPARAM code, LPARAM keyData, Type type, bool systemKey)
    190     : m_type(type)
    191     , m_text((type == Char) ? singleCharacterString(code) : String())
    192     , m_unmodifiedText((type == Char) ? singleCharacterString(code) : String())
    193     , m_keyIdentifier((type == Char) ? String() : keyIdentifierForWindowsKeyCode(code))
    194     , m_autoRepeat(HIWORD(keyData) & KF_REPEAT)
    195     , m_windowsVirtualKeyCode((type == RawKeyDown || type == KeyUp) ? code : 0)
    196     , m_nativeVirtualKeyCode(m_windowsVirtualKeyCode)
    197     , m_isKeypad(isKeypadEvent(code, keyData, type))
    198     , m_shiftKey(GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT)
    199     , m_ctrlKey(GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT)
    200     , m_altKey(GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT)
    201     , m_metaKey(false)
    202     , m_isSystemKey(systemKey)
    203 {
    204 }
    205 
    206 void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type, bool)
    207 {
    208     // No KeyDown events on Windows to disambiguate.
    209     ASSERT_NOT_REACHED();
    210 }
    211 
    212 bool PlatformKeyboardEvent::currentCapsLockState()
    213 {
    214      return GetKeyState(VK_CAPITAL) & 1;
    215 }
    216 
    217 void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
    218 {
    219     shiftKey = GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT;
    220     ctrlKey = GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT;
    221     altKey = GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT;
    222     metaKey = false;
    223 }
    224 
    225 }
    226