Home | History | Annotate | Download | only in npapi
      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