1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #import <Cocoa/Cocoa.h> 6 7 #include "base/logging.h" 8 #include "content/child/npapi/plugin_web_event_converter_mac.h" 9 #include "third_party/WebKit/public/web/WebInputEvent.h" 10 11 using WebKit::WebInputEvent; 12 using WebKit::WebKeyboardEvent; 13 using WebKit::WebMouseEvent; 14 using WebKit::WebMouseWheelEvent; 15 16 namespace content { 17 18 namespace { 19 20 // Returns true if the given key is a modifier key. 21 bool KeyIsModifier(int native_key_code) { 22 switch (native_key_code) { 23 case 55: // Left command 24 case 54: // Right command 25 case 58: // Left option 26 case 61: // Right option 27 case 59: // Left control 28 case 62: // Right control 29 case 56: // Left shift 30 case 60: // Right shift 31 case 57: // Caps lock 32 return true; 33 default: 34 return false; 35 } 36 } 37 38 // Returns true if the caps lock flag should be set for the given event. 39 bool CapsLockIsActive(const WebInputEvent& event) { 40 // Only key events have accurate information for the caps lock flag; see 41 // <https://bugs.webkit.org/show_bug.cgi?id=46518>. 42 // For other types, use the live state. 43 if (WebInputEvent::isKeyboardEventType(event.type)) 44 return (event.modifiers & WebInputEvent::CapsLockOn) != 0; 45 else 46 return ([[NSApp currentEvent] modifierFlags] & NSAlphaShiftKeyMask) != 0; 47 } 48 49 } // namespace 50 51 #pragma mark - 52 53 PluginWebEventConverter::PluginWebEventConverter() { 54 } 55 56 PluginWebEventConverter::~PluginWebEventConverter() { 57 } 58 59 bool PluginWebEventConverter::InitWithEvent(const WebInputEvent& web_event) { 60 memset(&cocoa_event_, 0, sizeof(cocoa_event_)); 61 if (web_event.type == WebInputEvent::MouseWheel) { 62 return ConvertMouseWheelEvent( 63 *static_cast<const WebMouseWheelEvent*>(&web_event)); 64 } else if (WebInputEvent::isMouseEventType(web_event.type)) { 65 return ConvertMouseEvent(*static_cast<const WebMouseEvent*>(&web_event)); 66 } else if (WebInputEvent::isKeyboardEventType(web_event.type)) { 67 return ConvertKeyboardEvent( 68 *static_cast<const WebKeyboardEvent*>(&web_event)); 69 } 70 DLOG(WARNING) << "Unknown event type " << web_event.type; 71 return false; 72 } 73 74 bool PluginWebEventConverter::ConvertKeyboardEvent( 75 const WebKeyboardEvent& key_event) { 76 cocoa_event_.data.key.keyCode = key_event.nativeKeyCode; 77 78 cocoa_event_.data.key.modifierFlags |= CocoaModifiers(key_event); 79 80 // Modifier keys have their own event type, and don't get character or 81 // repeat data. 82 if (KeyIsModifier(key_event.nativeKeyCode)) { 83 cocoa_event_.type = NPCocoaEventFlagsChanged; 84 return true; 85 } 86 87 cocoa_event_.data.key.characters = reinterpret_cast<NPNSString*>( 88 [NSString stringWithFormat:@"%S", key_event.text]); 89 cocoa_event_.data.key.charactersIgnoringModifiers = 90 reinterpret_cast<NPNSString*>( 91 [NSString stringWithFormat:@"%S", key_event.unmodifiedText]); 92 93 if (key_event.modifiers & WebInputEvent::IsAutoRepeat) 94 cocoa_event_.data.key.isARepeat = true; 95 96 switch (key_event.type) { 97 case WebInputEvent::KeyDown: 98 cocoa_event_.type = NPCocoaEventKeyDown; 99 return true; 100 case WebInputEvent::KeyUp: 101 cocoa_event_.type = NPCocoaEventKeyUp; 102 return true; 103 case WebInputEvent::RawKeyDown: 104 case WebInputEvent::Char: 105 // May be used eventually for IME, but currently not needed. 106 return false; 107 default: 108 NOTREACHED(); 109 return false; 110 } 111 } 112 113 bool PluginWebEventConverter::ConvertMouseEvent( 114 const WebMouseEvent& mouse_event) { 115 cocoa_event_.data.mouse.pluginX = mouse_event.x; 116 cocoa_event_.data.mouse.pluginY = mouse_event.y; 117 cocoa_event_.data.mouse.modifierFlags |= CocoaModifiers(mouse_event); 118 cocoa_event_.data.mouse.clickCount = mouse_event.clickCount; 119 switch (mouse_event.button) { 120 case WebMouseEvent::ButtonLeft: 121 cocoa_event_.data.mouse.buttonNumber = 0; 122 break; 123 case WebMouseEvent::ButtonMiddle: 124 cocoa_event_.data.mouse.buttonNumber = 2; 125 break; 126 case WebMouseEvent::ButtonRight: 127 cocoa_event_.data.mouse.buttonNumber = 1; 128 break; 129 default: 130 cocoa_event_.data.mouse.buttonNumber = mouse_event.button; 131 break; 132 } 133 switch (mouse_event.type) { 134 case WebInputEvent::MouseDown: 135 cocoa_event_.type = NPCocoaEventMouseDown; 136 return true; 137 case WebInputEvent::MouseUp: 138 cocoa_event_.type = NPCocoaEventMouseUp; 139 return true; 140 case WebInputEvent::MouseMove: { 141 bool mouse_is_down = 142 (mouse_event.modifiers & WebInputEvent::LeftButtonDown) || 143 (mouse_event.modifiers & WebInputEvent::RightButtonDown) || 144 (mouse_event.modifiers & WebInputEvent::MiddleButtonDown); 145 cocoa_event_.type = mouse_is_down ? NPCocoaEventMouseDragged 146 : NPCocoaEventMouseMoved; 147 return true; 148 } 149 case WebInputEvent::MouseEnter: 150 cocoa_event_.type = NPCocoaEventMouseEntered; 151 return true; 152 case WebInputEvent::MouseLeave: 153 cocoa_event_.type = NPCocoaEventMouseExited; 154 return true; 155 default: 156 NOTREACHED(); 157 return false; 158 } 159 } 160 161 bool PluginWebEventConverter::ConvertMouseWheelEvent( 162 const WebMouseWheelEvent& wheel_event) { 163 cocoa_event_.type = NPCocoaEventScrollWheel; 164 cocoa_event_.data.mouse.pluginX = wheel_event.x; 165 cocoa_event_.data.mouse.pluginY = wheel_event.y; 166 cocoa_event_.data.mouse.modifierFlags |= CocoaModifiers(wheel_event); 167 cocoa_event_.data.mouse.deltaX = wheel_event.deltaX; 168 cocoa_event_.data.mouse.deltaY = wheel_event.deltaY; 169 return true; 170 } 171 172 NSUInteger PluginWebEventConverter::CocoaModifiers( 173 const WebInputEvent& web_event) { 174 NSInteger modifiers = 0; 175 if (web_event.modifiers & WebInputEvent::ControlKey) 176 modifiers |= NSControlKeyMask; 177 if (web_event.modifiers & WebInputEvent::ShiftKey) 178 modifiers |= NSShiftKeyMask; 179 if (web_event.modifiers & WebInputEvent::AltKey) 180 modifiers |= NSAlternateKeyMask; 181 if (web_event.modifiers & WebInputEvent::MetaKey) 182 modifiers |= NSCommandKeyMask; 183 if (CapsLockIsActive(web_event)) 184 modifiers |= NSAlphaShiftKeyMask; 185 return modifiers; 186 } 187 188 } // namespace content 189