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.
5 #include "mojo/services/html_viewer/blink_input_events_type_converters.h"
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"
15 // Used for scrolling. This matches Firefox behavior.
16 const int kPixelsPerTick
= 53;
18 int EventFlagsToWebEventModifiers(int flags
) {
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
;
39 int EventFlagsToWebInputEventModifiers(int flags
) {
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);
51 int GetClickCount(int flags
) {
52 if (flags
& mojo::MOUSE_EVENT_FLAGS_IS_TRIPLE_CLICK
)
54 else if (flags
& mojo::MOUSE_EVENT_FLAGS_IS_DOUBLE_CLICK
)
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
;
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
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
;
75 web_event
->modifiers
= EventFlagsToWebEventModifiers(event
->flags
);
76 web_event
->timeStampSeconds
=
77 base::TimeDelta::FromInternalValue(event
->time_stamp
).InSecondsF();
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
;
87 switch (event
->action
) {
88 case EVENT_TYPE_MOUSE_PRESSED
:
89 web_event
->type
= blink::WebInputEvent::MouseDown
;
91 case EVENT_TYPE_MOUSE_RELEASED
:
92 web_event
->type
= blink::WebInputEvent::MouseUp
;
94 case EVENT_TYPE_MOUSE_ENTERED
:
95 web_event
->type
= blink::WebInputEvent::MouseLeave
;
96 web_event
->button
= blink::WebMouseEvent::ButtonNone
;
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
;
104 NOTIMPLEMENTED() << "Received unexpected event: " << event
->action
;
108 web_event
->clickCount
= GetClickCount(event
->flags
);
110 return web_event
.Pass();
113 scoped_ptr
<blink::WebInputEvent
> BuildWebKeyboardEvent(
114 const EventPtr
& event
) {
115 scoped_ptr
<blink::WebKeyboardEvent
> web_event(new blink::WebKeyboardEvent
);
117 web_event
->modifiers
= EventFlagsToWebInputEventModifiers(event
->flags
);
118 web_event
->timeStampSeconds
=
119 base::TimeDelta::FromInternalValue(event
->time_stamp
).InSecondsF();
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
;
126 case EVENT_TYPE_KEY_RELEASED
:
127 web_event
->type
= blink::WebInputEvent::KeyUp
;
133 if (web_event
->modifiers
& blink::WebInputEvent::AltKey
)
134 web_event
->isSystemKey
= true;
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
;
141 web_event
->setKeyIdentifierFromWindowsKeyCode();
142 return web_event
.Pass();
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();
155 web_event
->x
= event
->location_data
->in_view_location
->x
;
156 web_event
->y
= event
->location_data
->in_view_location
->y
;
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
;
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;
169 web_event
->deltaX
= event
->wheel_data
->x_offset
;
170 web_event
->deltaY
= event
->wheel_data
->y_offset
;
173 web_event
->wheelTicksX
= web_event
->deltaX
/ kPixelsPerTick
;
174 web_event
->wheelTicksY
= web_event
->deltaY
/ kPixelsPerTick
;
176 return web_event
.Pass();
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
) &&
195 return BuildWebKeyboardEvent(event
);
196 } else if (event
->action
== EVENT_TYPE_MOUSEWHEEL
) {
197 return BuildWebMouseWheelEventFrom(event
);
200 return scoped_ptr
<blink::WebInputEvent
>();