Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / mojo / services / html_viewer / blink_input_events_type_converters.cc
1 // Copyright 2014 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 #include "mojo/services/html_viewer/blink_input_events_type_converters.h"
6
7 #include "base/logging.h"
8 #include "base/time/time.h"
9 #include "mojo/services/public/interfaces/input_events/input_event_constants.mojom.h"
10 #include "third_party/WebKit/public/web/WebInputEvent.h"
11
12 namespace mojo {
13 namespace {
14
15 // Used for scrolling. This matches Firefox behavior.
16 const int kPixelsPerTick = 53;
17
18 int EventFlagsToWebEventModifiers(int flags) {
19   int modifiers = 0;
20
21   if (flags & mojo::EVENT_FLAGS_SHIFT_DOWN)
22     modifiers |= blink::WebInputEvent::ShiftKey;
23   if (flags & mojo::EVENT_FLAGS_CONTROL_DOWN)
24     modifiers |= blink::WebInputEvent::ControlKey;
25   if (flags & mojo::EVENT_FLAGS_ALT_DOWN)
26     modifiers |= blink::WebInputEvent::AltKey;
27   // TODO(beng): MetaKey/META_MASK
28   if (flags & mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON)
29     modifiers |= blink::WebInputEvent::LeftButtonDown;
30   if (flags & mojo::EVENT_FLAGS_MIDDLE_MOUSE_BUTTON)
31     modifiers |= blink::WebInputEvent::MiddleButtonDown;
32   if (flags & mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON)
33     modifiers |= blink::WebInputEvent::RightButtonDown;
34   if (flags & mojo::EVENT_FLAGS_CAPS_LOCK_DOWN)
35     modifiers |= blink::WebInputEvent::CapsLockOn;
36   return modifiers;
37 }
38
39 int EventFlagsToWebInputEventModifiers(int flags) {
40   return
41       (flags & mojo::EVENT_FLAGS_SHIFT_DOWN ?
42        blink::WebInputEvent::ShiftKey : 0) |
43       (flags & mojo::EVENT_FLAGS_CONTROL_DOWN ?
44        blink::WebInputEvent::ControlKey : 0) |
45       (flags & mojo::EVENT_FLAGS_CAPS_LOCK_DOWN ?
46        blink::WebInputEvent::CapsLockOn : 0) |
47       (flags & mojo::EVENT_FLAGS_ALT_DOWN ?
48        blink::WebInputEvent::AltKey : 0);
49 }
50
51 int GetClickCount(int flags) {
52   if (flags & mojo::MOUSE_EVENT_FLAGS_IS_TRIPLE_CLICK)
53     return 3;
54   else if (flags & mojo::MOUSE_EVENT_FLAGS_IS_DOUBLE_CLICK)
55     return 2;
56
57   return 1;
58 }
59
60 scoped_ptr<blink::WebInputEvent> BuildWebMouseEventFrom(const EventPtr& event) {
61   scoped_ptr<blink::WebMouseEvent> web_event(new blink::WebMouseEvent);
62   web_event->x = event->location_data->in_view_location->x;
63   web_event->y = event->location_data->in_view_location->y;
64
65   // TODO(erg): Remove this if check once we can rely on screen_location
66   // actually being passed to us. As written today, getting the screen
67   // location from ui::Event objects can only be done by querying the
68   // underlying native events, so all synthesized events don't have screen
69   // locations.
70   if (!event->location_data->screen_location.is_null()) {
71     web_event->globalX = event->location_data->screen_location->x;
72     web_event->globalY = event->location_data->screen_location->y;
73   }
74
75   web_event->modifiers = EventFlagsToWebEventModifiers(event->flags);
76   web_event->timeStampSeconds =
77       base::TimeDelta::FromInternalValue(event->time_stamp).InSecondsF();
78
79   web_event->button = blink::WebMouseEvent::ButtonNone;
80   if (event->flags & mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON)
81     web_event->button = blink::WebMouseEvent::ButtonLeft;
82   if (event->flags & mojo::EVENT_FLAGS_MIDDLE_MOUSE_BUTTON)
83     web_event->button = blink::WebMouseEvent::ButtonMiddle;
84   if (event->flags & mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON)
85     web_event->button = blink::WebMouseEvent::ButtonRight;
86
87   switch (event->action) {
88     case EVENT_TYPE_MOUSE_PRESSED:
89       web_event->type = blink::WebInputEvent::MouseDown;
90       break;
91     case EVENT_TYPE_MOUSE_RELEASED:
92       web_event->type = blink::WebInputEvent::MouseUp;
93       break;
94     case EVENT_TYPE_MOUSE_ENTERED:
95       web_event->type = blink::WebInputEvent::MouseLeave;
96       web_event->button = blink::WebMouseEvent::ButtonNone;
97       break;
98     case EVENT_TYPE_MOUSE_EXITED:
99     case EVENT_TYPE_MOUSE_MOVED:
100     case EVENT_TYPE_MOUSE_DRAGGED:
101       web_event->type = blink::WebInputEvent::MouseMove;
102       break;
103     default:
104       NOTIMPLEMENTED() << "Received unexpected event: " << event->action;
105       break;
106   }
107
108   web_event->clickCount = GetClickCount(event->flags);
109
110   return web_event.Pass();
111 }
112
113 scoped_ptr<blink::WebInputEvent> BuildWebKeyboardEvent(
114     const EventPtr& event) {
115   scoped_ptr<blink::WebKeyboardEvent> web_event(new blink::WebKeyboardEvent);
116
117   web_event->modifiers = EventFlagsToWebInputEventModifiers(event->flags);
118   web_event->timeStampSeconds =
119       base::TimeDelta::FromInternalValue(event->time_stamp).InSecondsF();
120
121   switch (event->action) {
122     case EVENT_TYPE_KEY_PRESSED:
123       web_event->type = event->key_data->is_char ? blink::WebInputEvent::Char :
124           blink::WebInputEvent::RawKeyDown;
125       break;
126     case EVENT_TYPE_KEY_RELEASED:
127       web_event->type = blink::WebInputEvent::KeyUp;
128       break;
129     default:
130       NOTREACHED();
131   }
132
133   if (web_event->modifiers & blink::WebInputEvent::AltKey)
134     web_event->isSystemKey = true;
135
136   web_event->windowsKeyCode = event->key_data->windows_key_code;
137   web_event->nativeKeyCode = event->key_data->native_key_code;
138   web_event->text[0] = event->key_data->text;
139   web_event->unmodifiedText[0] = event->key_data->unmodified_text;
140
141   web_event->setKeyIdentifierFromWindowsKeyCode();
142   return web_event.Pass();
143 }
144
145 scoped_ptr<blink::WebInputEvent> BuildWebMouseWheelEventFrom(
146     const EventPtr& event) {
147   scoped_ptr<blink::WebMouseWheelEvent> web_event(
148       new blink::WebMouseWheelEvent);
149   web_event->type = blink::WebInputEvent::MouseWheel;
150   web_event->button = blink::WebMouseEvent::ButtonNone;
151   web_event->modifiers = EventFlagsToWebEventModifiers(event->flags);
152   web_event->timeStampSeconds =
153       base::TimeDelta::FromInternalValue(event->time_stamp).InSecondsF();
154
155   web_event->x = event->location_data->in_view_location->x;
156   web_event->y = event->location_data->in_view_location->y;
157
158   // TODO(erg): Remove this null check as parallel to above.
159   if (!event->location_data->screen_location.is_null()) {
160     web_event->globalX = event->location_data->screen_location->x;
161     web_event->globalY = event->location_data->screen_location->y;
162   }
163
164   if ((event->flags & mojo::EVENT_FLAGS_SHIFT_DOWN) != 0 &&
165       event->wheel_data->x_offset == 0) {
166     web_event->deltaX = event->wheel_data->y_offset;
167     web_event->deltaY = 0;
168   } else {
169     web_event->deltaX = event->wheel_data->x_offset;
170     web_event->deltaY = event->wheel_data->y_offset;
171   }
172
173   web_event->wheelTicksX = web_event->deltaX / kPixelsPerTick;
174   web_event->wheelTicksY = web_event->deltaY / kPixelsPerTick;
175
176   return web_event.Pass();
177 }
178
179 }  // namespace
180
181 // static
182 scoped_ptr<blink::WebInputEvent>
183 TypeConverter<scoped_ptr<blink::WebInputEvent>, EventPtr>::Convert(
184     const EventPtr& event) {
185   if (event->action == EVENT_TYPE_MOUSE_PRESSED ||
186       event->action == EVENT_TYPE_MOUSE_RELEASED ||
187       event->action == EVENT_TYPE_MOUSE_ENTERED ||
188       event->action == EVENT_TYPE_MOUSE_EXITED ||
189       event->action == EVENT_TYPE_MOUSE_MOVED ||
190       event->action == EVENT_TYPE_MOUSE_DRAGGED) {
191     return BuildWebMouseEventFrom(event);
192   } else if ((event->action == EVENT_TYPE_KEY_PRESSED ||
193               event->action == EVENT_TYPE_KEY_RELEASED) &&
194              event->key_data) {
195     return BuildWebKeyboardEvent(event);
196   } else if (event->action == EVENT_TYPE_MOUSEWHEEL) {
197     return BuildWebMouseWheelEventFrom(event);
198   }
199
200   return scoped_ptr<blink::WebInputEvent>();
201 }
202
203 }  // namespace mojo