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/c/pp_errors.h"
6#include "ppapi/thunk/enter.h"
7#include "ppapi/thunk/ppb_input_event_api.h"
8#include "ppapi/thunk/ppb_instance_api.h"
9#include "ppapi/thunk/resource_creation_api.h"
10#include "ppapi/thunk/thunk.h"
11
12namespace ppapi {
13namespace thunk {
14
15namespace {
16
17typedef EnterResource<PPB_InputEvent_API> EnterInputEvent;
18
19// InputEvent ------------------------------------------------------------------
20
21int32_t RequestInputEvents(PP_Instance instance, uint32_t event_classes) {
22  VLOG(4) << "PPB_InputEvent::RequestInputEvents()";
23  EnterInstance enter(instance);
24  if (enter.failed())
25    return enter.retval();
26  return enter.functions()->RequestInputEvents(instance, event_classes);
27}
28
29int32_t RequestFilteringInputEvents(PP_Instance instance,
30                                    uint32_t event_classes) {
31  VLOG(4) << "PPB_InputEvent::RequestFilteringInputEvents()";
32  EnterInstance enter(instance);
33  if (enter.failed())
34    return enter.retval();
35  return enter.functions()->RequestFilteringInputEvents(instance,
36                                                        event_classes);
37}
38
39void ClearInputEventRequest(PP_Instance instance,
40                            uint32_t event_classes) {
41  VLOG(4) << "PPB_InputEvent::ClearInputEventRequest()";
42  EnterInstance enter(instance);
43  if (enter.succeeded())
44    enter.functions()->ClearInputEventRequest(instance, event_classes);
45}
46
47PP_Bool IsInputEvent(PP_Resource resource) {
48  VLOG(4) << "PPB_InputEvent::IsInputEvent()";
49  EnterInputEvent enter(resource, false);
50  return enter.succeeded() ? PP_TRUE : PP_FALSE;
51}
52
53PP_InputEvent_Type GetType(PP_Resource event) {
54  VLOG(4) << "PPB_InputEvent::GetType()";
55  EnterInputEvent enter(event, true);
56  if (enter.failed())
57    return PP_INPUTEVENT_TYPE_UNDEFINED;
58  return enter.object()->GetType();
59}
60
61PP_TimeTicks GetTimeStamp(PP_Resource event) {
62  VLOG(4) << "PPB_InputEvent::GetTimeStamp()";
63  EnterInputEvent enter(event, true);
64  if (enter.failed())
65    return 0.0;
66  return enter.object()->GetTimeStamp();
67}
68
69uint32_t GetModifiers(PP_Resource event) {
70  VLOG(4) << "PPB_InputEvent::GetModifiers()";
71  EnterInputEvent enter(event, true);
72  if (enter.failed())
73    return 0;
74  return enter.object()->GetModifiers();
75}
76
77const PPB_InputEvent g_ppb_input_event_thunk = {
78  &RequestInputEvents,
79  &RequestFilteringInputEvents,
80  &ClearInputEventRequest,
81  &IsInputEvent,
82  &GetType,
83  &GetTimeStamp,
84  &GetModifiers
85};
86
87// Mouse -----------------------------------------------------------------------
88
89PP_Resource CreateMouseInputEvent1_0(PP_Instance instance,
90                                     PP_InputEvent_Type type,
91                                     PP_TimeTicks time_stamp,
92                                     uint32_t modifiers,
93                                     PP_InputEvent_MouseButton mouse_button,
94                                     const PP_Point* mouse_position,
95                                     int32_t click_count) {
96  VLOG(4) << "PPB_MouseInputEvent::Create()";
97  EnterResourceCreation enter(instance);
98  if (enter.failed())
99    return 0;
100
101  PP_Point mouse_movement = PP_MakePoint(0, 0);
102  return enter.functions()->CreateMouseInputEvent(instance, type, time_stamp,
103                                                  modifiers, mouse_button,
104                                                  mouse_position, click_count,
105                                                  &mouse_movement);
106}
107
108PP_Resource CreateMouseInputEvent1_1(PP_Instance instance,
109                                     PP_InputEvent_Type type,
110                                     PP_TimeTicks time_stamp,
111                                     uint32_t modifiers,
112                                     PP_InputEvent_MouseButton mouse_button,
113                                     const PP_Point* mouse_position,
114                                     int32_t click_count,
115                                     const PP_Point* mouse_movement) {
116  VLOG(4) << "PPB_MouseInputEvent::Create()";
117  EnterResourceCreation enter(instance);
118  if (enter.failed())
119    return 0;
120  return enter.functions()->CreateMouseInputEvent(instance, type, time_stamp,
121                                                  modifiers, mouse_button,
122                                                  mouse_position, click_count,
123                                                  mouse_movement);
124}
125
126PP_Bool IsMouseInputEvent(PP_Resource resource) {
127  VLOG(4) << "PPB_MouseInputEvent::IsMouseInputEvent()";
128  if (!IsInputEvent(resource))
129    return PP_FALSE;  // Prevent warning log in GetType.
130  PP_InputEvent_Type type = GetType(resource);
131  return PP_FromBool(type == PP_INPUTEVENT_TYPE_MOUSEDOWN ||
132                     type == PP_INPUTEVENT_TYPE_MOUSEUP ||
133                     type == PP_INPUTEVENT_TYPE_MOUSEMOVE ||
134                     type == PP_INPUTEVENT_TYPE_MOUSEENTER ||
135                     type == PP_INPUTEVENT_TYPE_MOUSELEAVE ||
136                     type == PP_INPUTEVENT_TYPE_CONTEXTMENU);
137}
138
139PP_InputEvent_MouseButton GetMouseButton(PP_Resource mouse_event) {
140  VLOG(4) << "PPB_MouseInputEvent::GetButton()";
141  EnterInputEvent enter(mouse_event, true);
142  if (enter.failed())
143    return PP_INPUTEVENT_MOUSEBUTTON_NONE;
144  return enter.object()->GetMouseButton();
145}
146
147PP_Point GetMousePosition(PP_Resource mouse_event) {
148  VLOG(4) << "PPB_MouseInputEvent::GetPosition()";
149  EnterInputEvent enter(mouse_event, true);
150  if (enter.failed())
151    return PP_MakePoint(0, 0);
152  return enter.object()->GetMousePosition();
153}
154
155int32_t GetMouseClickCount(PP_Resource mouse_event) {
156  VLOG(4) << "PPB_MouseInputEvent::GetClickCount()";
157  EnterInputEvent enter(mouse_event, true);
158  if (enter.failed())
159    return 0;
160  return enter.object()->GetMouseClickCount();
161}
162
163PP_Point GetMouseMovement(PP_Resource mouse_event) {
164  VLOG(4) << "PPB_MouseInputEvent::GetMovement()";
165  EnterInputEvent enter(mouse_event, true);
166  if (enter.failed())
167    return PP_MakePoint(0, 0);
168  return enter.object()->GetMouseMovement();
169}
170
171const PPB_MouseInputEvent_1_0 g_ppb_mouse_input_event_1_0_thunk = {
172  &CreateMouseInputEvent1_0,
173  &IsMouseInputEvent,
174  &GetMouseButton,
175  &GetMousePosition,
176  &GetMouseClickCount
177};
178
179const PPB_MouseInputEvent g_ppb_mouse_input_event_1_1_thunk = {
180  &CreateMouseInputEvent1_1,
181  &IsMouseInputEvent,
182  &GetMouseButton,
183  &GetMousePosition,
184  &GetMouseClickCount,
185  &GetMouseMovement
186};
187
188// Wheel -----------------------------------------------------------------------
189
190PP_Resource CreateWheelInputEvent(PP_Instance instance,
191                                  PP_TimeTicks time_stamp,
192                                  uint32_t modifiers,
193                                  const PP_FloatPoint* wheel_delta,
194                                  const PP_FloatPoint* wheel_ticks,
195                                  PP_Bool scroll_by_page) {
196  VLOG(4) << "PPB_WheelInputEvent::Create()";
197  EnterResourceCreation enter(instance);
198  if (enter.failed())
199    return 0;
200  return enter.functions()->CreateWheelInputEvent(instance, time_stamp,
201                                                  modifiers, wheel_delta,
202                                                  wheel_ticks, scroll_by_page);
203}
204
205PP_Bool IsWheelInputEvent(PP_Resource resource) {
206  VLOG(4) << "PPB_WheelInputEvent::IsWheelInputEvent()";
207  if (!IsInputEvent(resource))
208    return PP_FALSE;  // Prevent warning log in GetType.
209  PP_InputEvent_Type type = GetType(resource);
210  return PP_FromBool(type == PP_INPUTEVENT_TYPE_WHEEL);
211}
212
213PP_FloatPoint GetWheelDelta(PP_Resource wheel_event) {
214  VLOG(4) << "PPB_WheelInputEvent::GetDelta()";
215  EnterInputEvent enter(wheel_event, true);
216  if (enter.failed())
217    return PP_MakeFloatPoint(0.0f, 0.0f);
218  return enter.object()->GetWheelDelta();
219}
220
221PP_FloatPoint GetWheelTicks(PP_Resource wheel_event) {
222  VLOG(4) << "PPB_WheelInputEvent::GetTicks()";
223  EnterInputEvent enter(wheel_event, true);
224  if (enter.failed())
225    return PP_MakeFloatPoint(0.0f, 0.0f);
226  return enter.object()->GetWheelTicks();
227}
228
229PP_Bool GetWheelScrollByPage(PP_Resource wheel_event) {
230  VLOG(4) << "PPB_WheelInputEvent::GetScrollByPage()";
231  EnterInputEvent enter(wheel_event, true);
232  if (enter.failed())
233    return PP_FALSE;
234  return enter.object()->GetWheelScrollByPage();
235}
236
237const PPB_WheelInputEvent g_ppb_wheel_input_event_thunk = {
238  &CreateWheelInputEvent,
239  &IsWheelInputEvent,
240  &GetWheelDelta,
241  &GetWheelTicks,
242  &GetWheelScrollByPage
243};
244
245// Keyboard --------------------------------------------------------------------
246
247PP_Resource CreateKeyboardInputEvent(PP_Instance instance,
248                                     PP_InputEvent_Type type,
249                                     PP_TimeTicks time_stamp,
250                                     uint32_t modifiers,
251                                     uint32_t key_code,
252                                     struct PP_Var character_text) {
253  VLOG(4) << "PPB_KeyboardInputEvent::Create()";
254  EnterResourceCreation enter(instance);
255  if (enter.failed())
256    return 0;
257  return enter.functions()->CreateKeyboardInputEvent(instance, type, time_stamp,
258                                                     modifiers, key_code,
259                                                     character_text);
260}
261
262PP_Bool IsKeyboardInputEvent(PP_Resource resource) {
263  VLOG(4) << "PPB_KeyboardInputEvent::IsKeyboardInputEvent()";
264  if (!IsInputEvent(resource))
265    return PP_FALSE;  // Prevent warning log in GetType.
266  PP_InputEvent_Type type = GetType(resource);
267  return PP_FromBool(type == PP_INPUTEVENT_TYPE_KEYDOWN ||
268                     type == PP_INPUTEVENT_TYPE_KEYUP ||
269                     type == PP_INPUTEVENT_TYPE_RAWKEYDOWN ||
270                     type == PP_INPUTEVENT_TYPE_CHAR);
271}
272
273uint32_t GetKeyCode(PP_Resource key_event) {
274  VLOG(4) << "PPB_KeyboardInputEvent::GetKeyCode()";
275  EnterInputEvent enter(key_event, true);
276  if (enter.failed())
277    return 0;
278  return enter.object()->GetKeyCode();
279}
280
281PP_Var GetCharacterText(PP_Resource character_event) {
282  VLOG(4) << "PPB_KeyboardInputEvent::GetCharacterText()";
283  EnterInputEvent enter(character_event, true);
284  if (enter.failed())
285    return PP_MakeUndefined();
286  return enter.object()->GetCharacterText();
287}
288
289const PPB_KeyboardInputEvent g_ppb_keyboard_input_event_thunk = {
290  &CreateKeyboardInputEvent,
291  &IsKeyboardInputEvent,
292  &GetKeyCode,
293  &GetCharacterText
294};
295
296// _Dev interface.
297
298PP_Bool SetUsbKeyCode(PP_Resource key_event, uint32_t usb_key_code) {
299  VLOG(4) << "PPB_KeyboardInputEvent_Dev::SetUsbKeyCode()";
300  EnterInputEvent enter(key_event, true);
301  if (enter.failed())
302    return PP_FALSE;
303  return enter.object()->SetUsbKeyCode(usb_key_code);
304}
305
306uint32_t GetUsbKeyCode(PP_Resource key_event) {
307  VLOG(4) << "PPB_KeyboardInputEvent_Dev::GetUsbKeyCode()";
308  EnterInputEvent enter(key_event, true);
309  if (enter.failed())
310    return 0;
311  return enter.object()->GetUsbKeyCode();
312}
313
314PP_Var GetCode(PP_Resource key_event) {
315  VLOG(4) << "PPB_KeyboardInputEvent_Dev::GetCode()";
316  EnterInputEvent enter(key_event, true);
317  if (enter.failed())
318    return PP_MakeUndefined();
319  return enter.object()->GetCode();
320}
321
322const PPB_KeyboardInputEvent_Dev_0_2
323    g_ppb_keyboard_input_event_dev_0_2_thunk = {
324  &SetUsbKeyCode,
325  &GetUsbKeyCode,
326  &GetCode,
327};
328
329// Composition -----------------------------------------------------------------
330
331PP_Resource CreateIMEInputEvent(PP_Instance instance,
332                                PP_InputEvent_Type type,
333                                PP_TimeTicks time_stamp,
334                                PP_Var text,
335                                uint32_t segment_number,
336                                const uint32_t segment_offsets[],
337                                int32_t target_segment,
338                                uint32_t selection_start,
339                                uint32_t selection_end) {
340  VLOG(4) << "PPB_IMEInputEvent_Dev::Create()";
341  EnterResourceCreation enter(instance);
342  if (enter.failed())
343    return 0;
344  return enter.functions()->CreateIMEInputEvent(instance, type, time_stamp,
345                                                text, segment_number,
346                                                segment_offsets,
347                                                target_segment,
348                                                selection_start,
349                                                selection_end);
350}
351
352PP_Bool IsIMEInputEvent(PP_Resource resource) {
353  VLOG(4) << "PPB_IMEInputEvent_Dev::IsIMEInputEvent()";
354  if (!IsInputEvent(resource))
355    return PP_FALSE;  // Prevent warning log in GetType.
356  PP_InputEvent_Type type = GetType(resource);
357  return PP_FromBool(type == PP_INPUTEVENT_TYPE_IME_COMPOSITION_START ||
358                     type == PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE ||
359                     type == PP_INPUTEVENT_TYPE_IME_COMPOSITION_END ||
360                     type == PP_INPUTEVENT_TYPE_IME_TEXT);
361}
362
363PP_Var GetIMEText(PP_Resource ime_event) {
364  VLOG(4) << "PPB_IMEInputEvent_Dev::GetText()";
365  return GetCharacterText(ime_event);
366}
367
368uint32_t GetIMESegmentNumber(PP_Resource ime_event) {
369  VLOG(4) << "PPB_IMEInputEvent_Dev::GetSegmentNumber()";
370  EnterInputEvent enter(ime_event, true);
371  if (enter.failed())
372    return 0;
373  return enter.object()->GetIMESegmentNumber();
374}
375
376uint32_t GetIMESegmentOffset(PP_Resource ime_event, uint32_t index) {
377  VLOG(4) << "PPB_IMEInputEvent_Dev::GetSegmentOffset()";
378  EnterInputEvent enter(ime_event, true);
379  if (enter.failed())
380    return 0;
381  return enter.object()->GetIMESegmentOffset(index);
382}
383
384int32_t GetIMETargetSegment(PP_Resource ime_event) {
385  VLOG(4) << "PPB_IMEInputEvent_Dev::GetTargetSegment()";
386  EnterInputEvent enter(ime_event, true);
387  if (enter.failed())
388    return -1;
389  return enter.object()->GetIMETargetSegment();
390}
391
392void GetIMESelection(PP_Resource ime_event, uint32_t* start, uint32_t* end) {
393  VLOG(4) << "PPB_IMEInputEvent_Dev::GetSelection()";
394  EnterInputEvent enter(ime_event, true);
395  if (enter.failed()) {
396    if (start)
397      *start = 0;
398    if (end)
399      *end = 0;
400    return;
401  }
402  enter.object()->GetIMESelection(start, end);
403}
404
405const PPB_IMEInputEvent_Dev_0_1 g_ppb_ime_input_event_0_1_thunk = {
406  &IsIMEInputEvent,
407  &GetIMEText,
408  &GetIMESegmentNumber,
409  &GetIMESegmentOffset,
410  &GetIMETargetSegment,
411  &GetIMESelection
412};
413
414const PPB_IMEInputEvent_Dev_0_2 g_ppb_ime_input_event_0_2_thunk = {
415  &CreateIMEInputEvent,
416  &IsIMEInputEvent,
417  &GetIMEText,
418  &GetIMESegmentNumber,
419  &GetIMESegmentOffset,
420  &GetIMETargetSegment,
421  &GetIMESelection
422};
423
424const PPB_IMEInputEvent_1_0 g_ppb_ime_input_event_1_0_thunk = {
425  &CreateIMEInputEvent,
426  &IsIMEInputEvent,
427  &GetIMEText,
428  &GetIMESegmentNumber,
429  &GetIMESegmentOffset,
430  &GetIMETargetSegment,
431  &GetIMESelection
432};
433
434// Touch -----------------------------------------------------------------------
435
436PP_Resource CreateTouchInputEvent(PP_Instance instance,
437                                  PP_InputEvent_Type type,
438                                  PP_TimeTicks time_stamp,
439                                  uint32_t modifiers) {
440  VLOG(4) << "PPB_TouchInputEvent::Create()";
441  EnterResourceCreation enter(instance);
442  if (enter.failed())
443    return 0;
444  return enter.functions()->CreateTouchInputEvent(instance, type, time_stamp,
445                                                  modifiers);
446}
447
448void AddTouchPoint(PP_Resource touch_event,
449                   PP_TouchListType list,
450                   const PP_TouchPoint* point) {
451  VLOG(4) << "PPB_TouchInputEvent::AddTouchPoint()";
452  EnterInputEvent enter(touch_event, true);
453  if (enter.failed())
454    return;
455  return enter.object()->AddTouchPoint(list, *point);
456}
457
458PP_Bool IsTouchInputEvent(PP_Resource resource) {
459  VLOG(4) << "PPB_TouchInputEvent::IsTouchInputEvent()";
460  if (!IsInputEvent(resource))
461    return PP_FALSE;  // Prevent warning log in GetType.
462  PP_InputEvent_Type type = GetType(resource);
463  return PP_FromBool(type == PP_INPUTEVENT_TYPE_TOUCHSTART ||
464                     type == PP_INPUTEVENT_TYPE_TOUCHMOVE ||
465                     type == PP_INPUTEVENT_TYPE_TOUCHEND ||
466                     type == PP_INPUTEVENT_TYPE_TOUCHCANCEL);
467}
468
469uint32_t GetTouchCount(PP_Resource touch_event, PP_TouchListType list) {
470  VLOG(4) << "PPB_TouchInputEvent::GetTouchCount()";
471  EnterInputEvent enter(touch_event, true);
472  if (enter.failed())
473    return 0;
474  return enter.object()->GetTouchCount(list);
475}
476
477struct PP_TouchPoint GetTouchByIndex(PP_Resource touch_event,
478                                     PP_TouchListType list,
479                                     uint32_t index) {
480  VLOG(4) << "PPB_TouchInputEvent::GetTouchByIndex()";
481  EnterInputEvent enter(touch_event, true);
482  if (enter.failed())
483    return PP_MakeTouchPoint();
484  return enter.object()->GetTouchByIndex(list, index);
485}
486
487struct PP_TouchPoint GetTouchById(PP_Resource touch_event,
488                                  PP_TouchListType list,
489                                  uint32_t id) {
490  VLOG(4) << "PPB_TouchInputEvent::GetTouchById()";
491  EnterInputEvent enter(touch_event, true);
492  if (enter.failed())
493    return PP_MakeTouchPoint();
494  return enter.object()->GetTouchById(list, id);
495}
496
497const PPB_TouchInputEvent_1_0 g_ppb_touch_input_event_thunk = {
498  &CreateTouchInputEvent,
499  &AddTouchPoint,
500  &IsTouchInputEvent,
501  &GetTouchCount,
502  &GetTouchByIndex,
503  &GetTouchById
504};
505
506}  // namespace
507
508const PPB_InputEvent_1_0* GetPPB_InputEvent_1_0_Thunk() {
509  return &g_ppb_input_event_thunk;
510}
511
512const PPB_MouseInputEvent_1_0* GetPPB_MouseInputEvent_1_0_Thunk() {
513  return &g_ppb_mouse_input_event_1_0_thunk;
514}
515
516const PPB_MouseInputEvent_1_1* GetPPB_MouseInputEvent_1_1_Thunk() {
517  return &g_ppb_mouse_input_event_1_1_thunk;
518}
519
520const PPB_KeyboardInputEvent_1_0* GetPPB_KeyboardInputEvent_1_0_Thunk() {
521  return &g_ppb_keyboard_input_event_thunk;
522}
523
524const PPB_KeyboardInputEvent_Dev_0_2*
525    GetPPB_KeyboardInputEvent_Dev_0_2_Thunk() {
526  return &g_ppb_keyboard_input_event_dev_0_2_thunk;
527}
528
529const PPB_WheelInputEvent_1_0* GetPPB_WheelInputEvent_1_0_Thunk() {
530  return &g_ppb_wheel_input_event_thunk;
531}
532
533const PPB_IMEInputEvent_Dev_0_1* GetPPB_IMEInputEvent_Dev_0_1_Thunk() {
534  return &g_ppb_ime_input_event_0_1_thunk;
535}
536
537const PPB_IMEInputEvent_Dev_0_2* GetPPB_IMEInputEvent_Dev_0_2_Thunk() {
538  return &g_ppb_ime_input_event_0_2_thunk;
539}
540
541const PPB_IMEInputEvent_1_0* GetPPB_IMEInputEvent_1_0_Thunk() {
542  return &g_ppb_ime_input_event_1_0_thunk;
543}
544
545const PPB_TouchInputEvent_1_0* GetPPB_TouchInputEvent_1_0_Thunk() {
546  return &g_ppb_touch_input_event_thunk;
547}
548
549}  // namespace thunk
550}  // namespace ppapi
551