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#include "ppapi/cpp/input_event.h"
6
7#include "ppapi/cpp/instance_handle.h"
8#include "ppapi/cpp/module.h"
9#include "ppapi/cpp/module_impl.h"
10#include "ppapi/cpp/point.h"
11#include "ppapi/cpp/touch_point.h"
12#include "ppapi/cpp/var.h"
13
14namespace pp {
15
16namespace {
17
18template <> const char* interface_name<PPB_InputEvent_1_0>() {
19  return PPB_INPUT_EVENT_INTERFACE_1_0;
20}
21
22template <> const char* interface_name<PPB_KeyboardInputEvent_1_2>() {
23  return PPB_KEYBOARD_INPUT_EVENT_INTERFACE_1_2;
24}
25
26template <> const char* interface_name<PPB_KeyboardInputEvent_1_0>() {
27  return PPB_KEYBOARD_INPUT_EVENT_INTERFACE_1_0;
28}
29
30template <> const char* interface_name<PPB_MouseInputEvent_1_1>() {
31  return PPB_MOUSE_INPUT_EVENT_INTERFACE_1_1;
32}
33
34template <> const char* interface_name<PPB_WheelInputEvent_1_0>() {
35  return PPB_WHEEL_INPUT_EVENT_INTERFACE_1_0;
36}
37
38template <> const char* interface_name<PPB_TouchInputEvent_1_0>() {
39  return PPB_TOUCH_INPUT_EVENT_INTERFACE_1_0;
40}
41
42template <> const char* interface_name<PPB_IMEInputEvent_1_0>() {
43  return PPB_IME_INPUT_EVENT_INTERFACE_1_0;
44}
45
46}  // namespace
47
48// InputEvent ------------------------------------------------------------------
49
50InputEvent::InputEvent() : Resource() {
51}
52
53InputEvent::InputEvent(PP_Resource input_event_resource) : Resource() {
54  // Type check the input event before setting it.
55  if (!has_interface<PPB_InputEvent_1_0>())
56    return;
57  if (get_interface<PPB_InputEvent_1_0>()->IsInputEvent(input_event_resource)) {
58    Module::Get()->core()->AddRefResource(input_event_resource);
59    PassRefFromConstructor(input_event_resource);
60  }
61}
62
63InputEvent::~InputEvent() {
64}
65
66PP_InputEvent_Type InputEvent::GetType() const {
67  if (!has_interface<PPB_InputEvent_1_0>())
68    return PP_INPUTEVENT_TYPE_UNDEFINED;
69  return get_interface<PPB_InputEvent_1_0>()->GetType(pp_resource());
70}
71
72PP_TimeTicks InputEvent::GetTimeStamp() const {
73  if (!has_interface<PPB_InputEvent_1_0>())
74    return 0.0f;
75  return get_interface<PPB_InputEvent_1_0>()->GetTimeStamp(pp_resource());
76}
77
78uint32_t InputEvent::GetModifiers() const {
79  if (!has_interface<PPB_InputEvent_1_0>())
80    return 0;
81  return get_interface<PPB_InputEvent_1_0>()->GetModifiers(pp_resource());
82}
83
84// MouseInputEvent -------------------------------------------------------------
85
86MouseInputEvent::MouseInputEvent() : InputEvent() {
87}
88
89MouseInputEvent::MouseInputEvent(const InputEvent& event) : InputEvent() {
90  // Type check the input event before setting it.
91  if (!has_interface<PPB_MouseInputEvent_1_1>())
92    return;
93  if (get_interface<PPB_MouseInputEvent_1_1>()->IsMouseInputEvent(
94          event.pp_resource())) {
95    Module::Get()->core()->AddRefResource(event.pp_resource());
96    PassRefFromConstructor(event.pp_resource());
97  }
98}
99
100MouseInputEvent::MouseInputEvent(const InstanceHandle& instance,
101                                 PP_InputEvent_Type type,
102                                 PP_TimeTicks time_stamp,
103                                 uint32_t modifiers,
104                                 PP_InputEvent_MouseButton mouse_button,
105                                 const Point& mouse_position,
106                                 int32_t click_count,
107                                 const Point& mouse_movement) {
108  // Type check the input event before setting it.
109  if (!has_interface<PPB_MouseInputEvent_1_1>())
110    return;
111  PassRefFromConstructor(get_interface<PPB_MouseInputEvent_1_1>()->Create(
112      instance.pp_instance(), type, time_stamp, modifiers, mouse_button,
113      &mouse_position.pp_point(), click_count, &mouse_movement.pp_point()));
114}
115
116PP_InputEvent_MouseButton MouseInputEvent::GetButton() const {
117  if (!has_interface<PPB_MouseInputEvent_1_1>())
118    return PP_INPUTEVENT_MOUSEBUTTON_NONE;
119  return get_interface<PPB_MouseInputEvent_1_1>()->GetButton(pp_resource());
120}
121
122Point MouseInputEvent::GetPosition() const {
123  if (!has_interface<PPB_MouseInputEvent_1_1>())
124    return Point();
125  return get_interface<PPB_MouseInputEvent_1_1>()->GetPosition(pp_resource());
126}
127
128int32_t MouseInputEvent::GetClickCount() const {
129  if (!has_interface<PPB_MouseInputEvent_1_1>())
130    return 0;
131  return get_interface<PPB_MouseInputEvent_1_1>()->GetClickCount(pp_resource());
132}
133
134Point MouseInputEvent::GetMovement() const {
135  if (!has_interface<PPB_MouseInputEvent_1_1>())
136    return Point();
137  return get_interface<PPB_MouseInputEvent_1_1>()->GetMovement(pp_resource());
138}
139
140// WheelInputEvent -------------------------------------------------------------
141
142WheelInputEvent::WheelInputEvent() : InputEvent() {
143}
144
145WheelInputEvent::WheelInputEvent(const InputEvent& event) : InputEvent() {
146  // Type check the input event before setting it.
147  if (!has_interface<PPB_WheelInputEvent_1_0>())
148    return;
149  if (get_interface<PPB_WheelInputEvent_1_0>()->IsWheelInputEvent(
150          event.pp_resource())) {
151    Module::Get()->core()->AddRefResource(event.pp_resource());
152    PassRefFromConstructor(event.pp_resource());
153  }
154}
155
156WheelInputEvent::WheelInputEvent(const InstanceHandle& instance,
157                                 PP_TimeTicks time_stamp,
158                                 uint32_t modifiers,
159                                 const FloatPoint& wheel_delta,
160                                 const FloatPoint& wheel_ticks,
161                                 bool scroll_by_page) {
162  // Type check the input event before setting it.
163  if (!has_interface<PPB_WheelInputEvent_1_0>())
164    return;
165  PassRefFromConstructor(get_interface<PPB_WheelInputEvent_1_0>()->Create(
166      instance.pp_instance(), time_stamp, modifiers,
167      &wheel_delta.pp_float_point(), &wheel_ticks.pp_float_point(),
168      PP_FromBool(scroll_by_page)));
169}
170
171FloatPoint WheelInputEvent::GetDelta() const {
172  if (!has_interface<PPB_WheelInputEvent_1_0>())
173    return FloatPoint();
174  return get_interface<PPB_WheelInputEvent_1_0>()->GetDelta(pp_resource());
175}
176
177FloatPoint WheelInputEvent::GetTicks() const {
178  if (!has_interface<PPB_WheelInputEvent_1_0>())
179    return FloatPoint();
180  return get_interface<PPB_WheelInputEvent_1_0>()->GetTicks(pp_resource());
181}
182
183bool WheelInputEvent::GetScrollByPage() const {
184  if (!has_interface<PPB_WheelInputEvent_1_0>())
185    return false;
186  return PP_ToBool(
187      get_interface<PPB_WheelInputEvent_1_0>()->GetScrollByPage(pp_resource()));
188}
189
190// KeyboardInputEvent ----------------------------------------------------------
191
192KeyboardInputEvent::KeyboardInputEvent() : InputEvent() {
193}
194
195KeyboardInputEvent::KeyboardInputEvent(const InputEvent& event) : InputEvent() {
196  PP_Bool is_keyboard_event = PP_FALSE;
197
198  if (has_interface<PPB_KeyboardInputEvent_1_2>()) {
199    is_keyboard_event =
200        get_interface<PPB_KeyboardInputEvent_1_2>()->IsKeyboardInputEvent(
201            event.pp_resource());
202  } else if (has_interface<PPB_KeyboardInputEvent_1_0>()) {
203    is_keyboard_event =
204        get_interface<PPB_KeyboardInputEvent_1_0>()->IsKeyboardInputEvent(
205            event.pp_resource());
206  }
207
208  if (PP_ToBool(is_keyboard_event)) {
209    Module::Get()->core()->AddRefResource(event.pp_resource());
210    PassRefFromConstructor(event.pp_resource());
211  }
212}
213
214KeyboardInputEvent::KeyboardInputEvent(const InstanceHandle& instance,
215                                       PP_InputEvent_Type type,
216                                       PP_TimeTicks time_stamp,
217                                       uint32_t modifiers,
218                                       uint32_t key_code,
219                                       const Var& character_text) {
220  if (has_interface<PPB_KeyboardInputEvent_1_2>()) {
221    PassRefFromConstructor(get_interface<PPB_KeyboardInputEvent_1_2>()->Create(
222        instance.pp_instance(), type, time_stamp, modifiers, key_code,
223        character_text.pp_var(), Var().pp_var()));
224  } else if (has_interface<PPB_KeyboardInputEvent_1_0>()) {
225    PassRefFromConstructor(get_interface<PPB_KeyboardInputEvent_1_0>()->Create(
226        instance.pp_instance(), type, time_stamp, modifiers, key_code,
227        character_text.pp_var()));
228  }
229}
230
231KeyboardInputEvent::KeyboardInputEvent(const InstanceHandle& instance,
232                                       PP_InputEvent_Type type,
233                                       PP_TimeTicks time_stamp,
234                                       uint32_t modifiers,
235                                       uint32_t key_code,
236                                       const Var& character_text,
237                                       const Var& code) {
238  if (has_interface<PPB_KeyboardInputEvent_1_2>()) {
239    PassRefFromConstructor(get_interface<PPB_KeyboardInputEvent_1_2>()->Create(
240        instance.pp_instance(), type, time_stamp, modifiers, key_code,
241        character_text.pp_var(), code.pp_var()));
242  } else if (has_interface<PPB_KeyboardInputEvent_1_0>()) {
243    PassRefFromConstructor(get_interface<PPB_KeyboardInputEvent_1_0>()->Create(
244        instance.pp_instance(), type, time_stamp, modifiers, key_code,
245        character_text.pp_var()));
246  }
247}
248
249uint32_t KeyboardInputEvent::GetKeyCode() const {
250  if (has_interface<PPB_KeyboardInputEvent_1_2>()) {
251    return get_interface<PPB_KeyboardInputEvent_1_2>()->GetKeyCode(
252        pp_resource());
253  } else if (has_interface<PPB_KeyboardInputEvent_1_0>()) {
254    return get_interface<PPB_KeyboardInputEvent_1_0>()->GetKeyCode(
255        pp_resource());
256  }
257  return 0;
258}
259
260Var KeyboardInputEvent::GetCharacterText() const {
261  if (has_interface<PPB_KeyboardInputEvent_1_2>()) {
262    return Var(PASS_REF,
263               get_interface<PPB_KeyboardInputEvent_1_2>()->GetCharacterText(
264                   pp_resource()));
265  } else if (has_interface<PPB_KeyboardInputEvent_1_0>()) {
266    return Var(PASS_REF,
267               get_interface<PPB_KeyboardInputEvent_1_0>()->GetCharacterText(
268                 pp_resource()));
269  }
270  return Var();
271}
272
273Var KeyboardInputEvent::GetCode() const {
274  if (has_interface<PPB_KeyboardInputEvent_1_2>()) {
275    return Var(PASS_REF,
276               get_interface<PPB_KeyboardInputEvent_1_2>()->GetCode(
277                   pp_resource()));
278  }
279  return Var();
280}
281
282// TouchInputEvent ------------------------------------------------------------
283TouchInputEvent::TouchInputEvent() : InputEvent() {
284}
285
286TouchInputEvent::TouchInputEvent(const InputEvent& event) : InputEvent() {
287  if (!has_interface<PPB_TouchInputEvent_1_0>())
288    return;
289  // Type check the input event before setting it.
290  if (get_interface<PPB_TouchInputEvent_1_0>()->IsTouchInputEvent(
291      event.pp_resource())) {
292    Module::Get()->core()->AddRefResource(event.pp_resource());
293    PassRefFromConstructor(event.pp_resource());
294  }
295}
296
297TouchInputEvent::TouchInputEvent(const InstanceHandle& instance,
298                                 PP_InputEvent_Type type,
299                                 PP_TimeTicks time_stamp,
300                                 uint32_t modifiers) {
301  // Type check the input event before setting it.
302  if (!has_interface<PPB_TouchInputEvent_1_0>())
303    return;
304  PassRefFromConstructor(get_interface<PPB_TouchInputEvent_1_0>()->Create(
305      instance.pp_instance(), type, time_stamp, modifiers));
306}
307
308void TouchInputEvent::AddTouchPoint(PP_TouchListType list,
309                                    PP_TouchPoint point) {
310  if (!has_interface<PPB_TouchInputEvent_1_0>())
311    return;
312  get_interface<PPB_TouchInputEvent_1_0>()->AddTouchPoint(pp_resource(), list,
313                                                          &point);
314}
315
316uint32_t TouchInputEvent::GetTouchCount(PP_TouchListType list) const {
317  if (!has_interface<PPB_TouchInputEvent_1_0>())
318    return 0;
319  return get_interface<PPB_TouchInputEvent_1_0>()->GetTouchCount(pp_resource(),
320                                                                 list);
321}
322
323TouchPoint TouchInputEvent::GetTouchById(PP_TouchListType list,
324                                             uint32_t id) const {
325  if (!has_interface<PPB_TouchInputEvent_1_0>())
326    return TouchPoint();
327  return TouchPoint(get_interface<PPB_TouchInputEvent_1_0>()->
328                        GetTouchById(pp_resource(), list, id));
329}
330
331TouchPoint TouchInputEvent::GetTouchByIndex(PP_TouchListType list,
332                                                uint32_t index) const {
333  if (!has_interface<PPB_TouchInputEvent_1_0>())
334    return TouchPoint();
335  return TouchPoint(get_interface<PPB_TouchInputEvent_1_0>()->
336                        GetTouchByIndex(pp_resource(), list, index));
337}
338
339// IMEInputEvent -------------------------------------------------------
340
341IMEInputEvent::IMEInputEvent() : InputEvent() {
342}
343
344IMEInputEvent::IMEInputEvent(const InputEvent& event) : InputEvent() {
345  if (has_interface<PPB_IMEInputEvent_1_0>()) {
346    if (get_interface<PPB_IMEInputEvent_1_0>()->IsIMEInputEvent(
347            event.pp_resource())) {
348      Module::Get()->core()->AddRefResource(event.pp_resource());
349      PassRefFromConstructor(event.pp_resource());
350    }
351  }
352}
353
354IMEInputEvent::IMEInputEvent(
355    const InstanceHandle& instance,
356    PP_InputEvent_Type type,
357    PP_TimeTicks time_stamp,
358    const Var& text,
359    const std::vector<uint32_t>& segment_offsets,
360    int32_t target_segment,
361    const std::pair<uint32_t, uint32_t>& selection) : InputEvent() {
362  if (!has_interface<PPB_IMEInputEvent_1_0>())
363    return;
364  uint32_t dummy = 0;
365  PassRefFromConstructor(get_interface<PPB_IMEInputEvent_1_0>()->Create(
366      instance.pp_instance(), type, time_stamp, text.pp_var(),
367      segment_offsets.empty() ? 0 : segment_offsets.size() - 1,
368      segment_offsets.empty() ? &dummy : &segment_offsets[0],
369      target_segment, selection.first, selection.second));
370}
371
372
373Var IMEInputEvent::GetText() const {
374  if (has_interface<PPB_IMEInputEvent_1_0>()) {
375    return Var(PASS_REF,
376               get_interface<PPB_IMEInputEvent_1_0>()->GetText(
377                   pp_resource()));
378  }
379  return Var();
380}
381
382uint32_t IMEInputEvent::GetSegmentNumber() const {
383  if (has_interface<PPB_IMEInputEvent_1_0>()) {
384    return get_interface<PPB_IMEInputEvent_1_0>()->GetSegmentNumber(
385        pp_resource());
386  }
387  return 0;
388}
389
390uint32_t IMEInputEvent::GetSegmentOffset(uint32_t index) const {
391  if (has_interface<PPB_IMEInputEvent_1_0>()) {
392    return get_interface<PPB_IMEInputEvent_1_0>()->GetSegmentOffset(
393        pp_resource(), index);
394  }
395  return 0;
396}
397
398int32_t IMEInputEvent::GetTargetSegment() const {
399  if (has_interface<PPB_IMEInputEvent_1_0>()) {
400    return get_interface<PPB_IMEInputEvent_1_0>()->GetTargetSegment(
401        pp_resource());
402  }
403  return 0;
404}
405
406void IMEInputEvent::GetSelection(uint32_t* start, uint32_t* end) const {
407  if (has_interface<PPB_IMEInputEvent_1_0>()) {
408    get_interface<PPB_IMEInputEvent_1_0>()->GetSelection(pp_resource(),
409                                                         start,
410                                                         end);
411  }
412}
413
414}  // namespace pp
415