• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
11using blink::WebInputEvent;
12using blink::WebKeyboardEvent;
13using blink::WebMouseEvent;
14using blink::WebMouseWheelEvent;
15
16namespace content {
17
18namespace {
19
20// Returns true if the given key is a modifier key.
21bool 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.
39bool 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
53PluginWebEventConverter::PluginWebEventConverter() {
54}
55
56PluginWebEventConverter::~PluginWebEventConverter() {
57}
58
59bool 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
74bool 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
113bool 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
161bool 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
172NSUInteger 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