summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/mac/KeyEventMac.mm
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/mac/KeyEventMac.mm')
-rw-r--r--Source/WebCore/platform/mac/KeyEventMac.mm266
1 files changed, 266 insertions, 0 deletions
diff --git a/Source/WebCore/platform/mac/KeyEventMac.mm b/Source/WebCore/platform/mac/KeyEventMac.mm
new file mode 100644
index 0000000..30f1689
--- /dev/null
+++ b/Source/WebCore/platform/mac/KeyEventMac.mm
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2004, 2006, 2007, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "PlatformKeyboardEvent.h"
+
+#if PLATFORM(MAC)
+
+#import "KeyEventCocoa.h"
+#import "Logging.h"
+#import "WindowsKeyboardCodes.h"
+#import <Carbon/Carbon.h>
+
+using namespace WTF;
+
+namespace WebCore {
+
+static bool isKeypadEvent(NSEvent* event)
+{
+ // Check that this is the type of event that has a keyCode.
+ switch ([event type]) {
+ case NSKeyDown:
+ case NSKeyUp:
+ case NSFlagsChanged:
+ break;
+ default:
+ return false;
+ }
+
+ if ([event modifierFlags] & NSNumericPadKeyMask)
+ return true;
+
+ switch ([event keyCode]) {
+ case 71: // Clear
+ case 81: // =
+ case 75: // /
+ case 67: // *
+ case 78: // -
+ case 69: // +
+ case 76: // Enter
+ case 65: // .
+ case 82: // 0
+ case 83: // 1
+ case 84: // 2
+ case 85: // 3
+ case 86: // 4
+ case 87: // 5
+ case 88: // 6
+ case 89: // 7
+ case 91: // 8
+ case 92: // 9
+ return true;
+ }
+
+ return false;
+}
+
+static inline bool isKeyUpEvent(NSEvent *event)
+{
+ if ([event type] != NSFlagsChanged)
+ return [event type] == NSKeyUp;
+ // FIXME: This logic fails if the user presses both Shift keys at once, for example:
+ // we treat releasing one of them as keyDown.
+ switch ([event keyCode]) {
+ case 54: // Right Command
+ case 55: // Left Command
+ return ([event modifierFlags] & NSCommandKeyMask) == 0;
+
+ case 57: // Capslock
+ return ([event modifierFlags] & NSAlphaShiftKeyMask) == 0;
+
+ case 56: // Left Shift
+ case 60: // Right Shift
+ return ([event modifierFlags] & NSShiftKeyMask) == 0;
+
+ case 58: // Left Alt
+ case 61: // Right Alt
+ return ([event modifierFlags] & NSAlternateKeyMask) == 0;
+
+ case 59: // Left Ctrl
+ case 62: // Right Ctrl
+ return ([event modifierFlags] & NSControlKeyMask) == 0;
+
+ case 63: // Function
+ return ([event modifierFlags] & NSFunctionKeyMask) == 0;
+ }
+ return false;
+}
+
+static inline String textFromEvent(NSEvent* event)
+{
+ if ([event type] == NSFlagsChanged)
+ return "";
+ return [event characters];
+}
+
+
+static inline String unmodifiedTextFromEvent(NSEvent* event)
+{
+ if ([event type] == NSFlagsChanged)
+ return "";
+ return [event charactersIgnoringModifiers];
+}
+
+static String keyIdentifierForKeyEvent(NSEvent* event)
+{
+ if ([event type] == NSFlagsChanged)
+ switch ([event keyCode]) {
+ case 54: // Right Command
+ case 55: // Left Command
+ return "Meta";
+
+ case 57: // Capslock
+ return "CapsLock";
+
+ case 56: // Left Shift
+ case 60: // Right Shift
+ return "Shift";
+
+ case 58: // Left Alt
+ case 61: // Right Alt
+ return "Alt";
+
+ case 59: // Left Ctrl
+ case 62: // Right Ctrl
+ return "Control";
+
+ default:
+ ASSERT_NOT_REACHED();
+ return "";
+ }
+
+ NSString *s = [event charactersIgnoringModifiers];
+ if ([s length] != 1) {
+ LOG(Events, "received an unexpected number of characters in key event: %u", [s length]);
+ return "Unidentified";
+ }
+ return keyIdentifierForCharCode([s characterAtIndex:0]);
+}
+
+static int windowsKeyCodeForKeyEvent(NSEvent *event)
+{
+ int code = 0;
+ // There are several kinds of characters for which we produce key code from char code:
+ // 1. Roman letters. Windows keyboard layouts affect both virtual key codes and character codes for these,
+ // so e.g. 'A' gets the same keyCode on QWERTY, AZERTY or Dvorak layouts.
+ // 2. Keys for which there is no known Mac virtual key codes, like PrintScreen.
+ // 3. Certain punctuation keys. On Windows, these are also remapped depending on current keyboard layout,
+ // but see comment in windowsKeyCodeForCharCode().
+ if ([event type] == NSKeyDown || [event type] == NSKeyUp) {
+ // Cmd switches Roman letters for Dvorak-QWERTY layout, so try modified characters first.
+ NSString* s = [event characters];
+ code = [s length] > 0 ? windowsKeyCodeForCharCode([s characterAtIndex:0]) : 0;
+ if (code)
+ return code;
+
+ // Ctrl+A on an AZERTY keyboard would get VK_Q keyCode if we relied on -[NSEvent keyCode] below.
+ s = [event charactersIgnoringModifiers];
+ code = [s length] > 0 ? windowsKeyCodeForCharCode([s characterAtIndex:0]) : 0;
+ if (code)
+ return code;
+ }
+
+ // Map Mac virtual key code directly to Windows one for any keys not handled above.
+ // E.g. the key next to Caps Lock has the same Event.keyCode on U.S. keyboard ('A') and on Russian keyboard (CYRILLIC LETTER EF).
+ return windowsKeyCodeForKeyCode([event keyCode]);
+}
+
+PlatformKeyboardEvent::PlatformKeyboardEvent(NSEvent *event)
+ : m_type(isKeyUpEvent(event) ? PlatformKeyboardEvent::KeyUp : PlatformKeyboardEvent::KeyDown)
+ , m_text(textFromEvent(event))
+ , m_unmodifiedText(unmodifiedTextFromEvent(event))
+ , m_keyIdentifier(keyIdentifierForKeyEvent(event))
+ , m_autoRepeat(([event type] != NSFlagsChanged) && [event isARepeat])
+ , m_windowsVirtualKeyCode(windowsKeyCodeForKeyEvent(event))
+ , m_nativeVirtualKeyCode([event keyCode])
+ , m_isKeypad(isKeypadEvent(event))
+ , m_shiftKey([event modifierFlags] & NSShiftKeyMask)
+ , m_ctrlKey([event modifierFlags] & NSControlKeyMask)
+ , m_altKey([event modifierFlags] & NSAlternateKeyMask)
+ , m_metaKey([event modifierFlags] & NSCommandKeyMask)
+ , m_macEvent(event)
+{
+ // Always use 13 for Enter/Return -- we don't want to use AppKit's different character for Enter.
+ if (m_windowsVirtualKeyCode == VK_RETURN) {
+ m_text = "\r";
+ m_unmodifiedText = "\r";
+ }
+
+ // AppKit sets text to "\x7F" for backspace, but the correct KeyboardEvent character code is 8.
+ if (m_windowsVirtualKeyCode == VK_BACK) {
+ m_text = "\x8";
+ m_unmodifiedText = "\x8";
+ }
+
+ // Always use 9 for Tab -- we don't want to use AppKit's different character for shift-tab.
+ if (m_windowsVirtualKeyCode == VK_TAB) {
+ m_text = "\x9";
+ m_unmodifiedText = "\x9";
+ }
+}
+
+void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCompatibilityMode)
+{
+ // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions.
+ ASSERT(m_type == KeyDown);
+ ASSERT(type == RawKeyDown || type == Char);
+ m_type = type;
+ if (backwardCompatibilityMode)
+ return;
+
+ if (type == RawKeyDown) {
+ m_text = String();
+ m_unmodifiedText = String();
+ } else {
+ m_keyIdentifier = String();
+ m_windowsVirtualKeyCode = 0;
+ if (m_text.length() == 1 && (m_text[0U] >= 0xF700 && m_text[0U] <= 0xF7FF)) {
+ // According to NSEvents.h, OpenStep reserves the range 0xF700-0xF8FF for function keys. However, some actual private use characters
+ // happen to be in this range, e.g. the Apple logo (Option+Shift+K).
+ // 0xF7FF is an arbitrary cut-off.
+ m_text = String();
+ m_unmodifiedText = String();
+ }
+ }
+}
+
+bool PlatformKeyboardEvent::currentCapsLockState()
+{
+ return GetCurrentKeyModifiers() & alphaLock;
+}
+
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+ UInt32 currentModifiers = GetCurrentKeyModifiers();
+ shiftKey = currentModifiers & ::shiftKey;
+ ctrlKey = currentModifiers & ::controlKey;
+ altKey = currentModifiers & ::optionKey;
+ metaKey = currentModifiers & ::cmdKey;
+}
+
+}
+
+#endif // PLATFORM(MAC)