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 32using namespace WTF; 33 34namespace WebCore { 35 36static 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. 41static 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 145static 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 187static inline String singleCharacterString(UChar c) { return String(&c, 1); } 188 189PlatformKeyboardEvent::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 206void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type, bool) 207{ 208 // No KeyDown events on Windows to disambiguate. 209 ASSERT_NOT_REACHED(); 210} 211 212bool PlatformKeyboardEvent::currentCapsLockState() 213{ 214 return GetKeyState(VK_CAPITAL) & 1; 215} 216 217void 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