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_1_0(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_1_0(instance, type,
258                                                         time_stamp,
259                                                         modifiers, key_code,
260                                                         character_text);
261}
262
263PP_Resource CreateKeyboardInputEvent_1_2(PP_Instance instance,
264                                         PP_InputEvent_Type type,
265                                         PP_TimeTicks time_stamp,
266                                         uint32_t modifiers,
267                                         uint32_t key_code,
268                                         struct PP_Var character_text,
269                                         struct PP_Var code) {
270  VLOG(4) << "PPB_KeyboardInputEvent::Create()";
271  EnterResourceCreation enter(instance);
272  if (enter.failed())
273    return 0;
274  return enter.functions()->CreateKeyboardInputEvent_1_2(instance, type,
275                                                         time_stamp,
276                                                         modifiers, key_code,
277                                                         character_text, code);
278}
279
280PP_Bool IsKeyboardInputEvent(PP_Resource resource) {
281  VLOG(4) << "PPB_KeyboardInputEvent::IsKeyboardInputEvent()";
282  if (!IsInputEvent(resource))
283    return PP_FALSE;  // Prevent warning log in GetType.
284  PP_InputEvent_Type type = GetType(resource);
285  return PP_FromBool(type == PP_INPUTEVENT_TYPE_KEYDOWN ||
286                     type == PP_INPUTEVENT_TYPE_KEYUP ||
287                     type == PP_INPUTEVENT_TYPE_RAWKEYDOWN ||
288                     type == PP_INPUTEVENT_TYPE_CHAR);
289}
290
291uint32_t GetKeyCode(PP_Resource key_event) {
292  VLOG(4) << "PPB_KeyboardInputEvent::GetKeyCode()";
293  EnterInputEvent enter(key_event, true);
294  if (enter.failed())
295    return 0;
296  return enter.object()->GetKeyCode();
297}
298
299PP_Var GetCharacterText(PP_Resource character_event) {
300  VLOG(4) << "PPB_KeyboardInputEvent::GetCharacterText()";
301  EnterInputEvent enter(character_event, true);
302  if (enter.failed())
303    return PP_MakeUndefined();
304  return enter.object()->GetCharacterText();
305}
306
307PP_Var GetCode(PP_Resource key_event) {
308  VLOG(4) << "PPB_KeyboardInputEvent::GetCode()";
309  EnterInputEvent enter(key_event, true);
310  if (enter.failed())
311    return PP_MakeUndefined();
312  return enter.object()->GetCode();
313}
314
315const PPB_KeyboardInputEvent_1_0 g_ppb_keyboard_input_event_1_0_thunk = {
316  &CreateKeyboardInputEvent_1_0,
317  &IsKeyboardInputEvent,
318  &GetKeyCode,
319  &GetCharacterText
320};
321
322const PPB_KeyboardInputEvent g_ppb_keyboard_input_event_thunk = {
323  &CreateKeyboardInputEvent_1_2,
324  &IsKeyboardInputEvent,
325  &GetKeyCode,
326  &GetCharacterText,
327  &GetCode
328};
329
330// Composition -----------------------------------------------------------------
331
332PP_Resource CreateIMEInputEvent(PP_Instance instance,
333                                PP_InputEvent_Type type,
334                                PP_TimeTicks time_stamp,
335                                PP_Var text,
336                                uint32_t segment_number,
337                                const uint32_t segment_offsets[],
338                                int32_t target_segment,
339                                uint32_t selection_start,
340                                uint32_t selection_end) {
341  VLOG(4) << "PPB_IMEInputEvent_Dev::Create()";
342  EnterResourceCreation enter(instance);
343  if (enter.failed())
344    return 0;
345  return enter.functions()->CreateIMEInputEvent(instance, type, time_stamp,
346                                                text, segment_number,
347                                                segment_offsets,
348                                                target_segment,
349                                                selection_start,
350                                                selection_end);
351}
352
353PP_Bool IsIMEInputEvent(PP_Resource resource) {
354  VLOG(4) << "PPB_IMEInputEvent_Dev::IsIMEInputEvent()";
355  if (!IsInputEvent(resource))
356    return PP_FALSE;  // Prevent warning log in GetType.
357  PP_InputEvent_Type type = GetType(resource);
358  return PP_FromBool(type == PP_INPUTEVENT_TYPE_IME_COMPOSITION_START ||
359                     type == PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE ||
360                     type == PP_INPUTEVENT_TYPE_IME_COMPOSITION_END ||
361                     type == PP_INPUTEVENT_TYPE_IME_TEXT);
362}
363
364PP_Var GetIMEText(PP_Resource ime_event) {
365  VLOG(4) << "PPB_IMEInputEvent_Dev::GetText()";
366  return GetCharacterText(ime_event);
367}
368
369uint32_t GetIMESegmentNumber(PP_Resource ime_event) {
370  VLOG(4) << "PPB_IMEInputEvent_Dev::GetSegmentNumber()";
371  EnterInputEvent enter(ime_event, true);
372  if (enter.failed())
373    return 0;
374  return enter.object()->GetIMESegmentNumber();
375}
376
377uint32_t GetIMESegmentOffset(PP_Resource ime_event, uint32_t index) {
378  VLOG(4) << "PPB_IMEInputEvent_Dev::GetSegmentOffset()";
379  EnterInputEvent enter(ime_event, true);
380  if (enter.failed())
381    return 0;
382  return enter.object()->GetIMESegmentOffset(index);
383}
384
385int32_t GetIMETargetSegment(PP_Resource ime_event) {
386  VLOG(4) << "PPB_IMEInputEvent_Dev::GetTargetSegment()";
387  EnterInputEvent enter(ime_event, true);
388  if (enter.failed())
389    return -1;
390  return enter.object()->GetIMETargetSegment();
391}
392
393void GetIMESelection(PP_Resource ime_event, uint32_t* start, uint32_t* end) {
394  VLOG(4) << "PPB_IMEInputEvent_Dev::GetSelection()";
395  EnterInputEvent enter(ime_event, true);
396  if (enter.failed()) {
397    if (start)
398      *start = 0;
399    if (end)
400      *end = 0;
401    return;
402  }
403  enter.object()->GetIMESelection(start, end);
404}
405
406const PPB_IMEInputEvent_Dev_0_1 g_ppb_ime_input_event_0_1_thunk = {
407  &IsIMEInputEvent,
408  &GetIMEText,
409  &GetIMESegmentNumber,
410  &GetIMESegmentOffset,
411  &GetIMETargetSegment,
412  &GetIMESelection
413};
414
415const PPB_IMEInputEvent_Dev_0_2 g_ppb_ime_input_event_0_2_thunk = {
416  &CreateIMEInputEvent,
417  &IsIMEInputEvent,
418  &GetIMEText,
419  &GetIMESegmentNumber,
420  &GetIMESegmentOffset,
421  &GetIMETargetSegment,
422  &GetIMESelection
423};
424
425const PPB_IMEInputEvent_1_0 g_ppb_ime_input_event_1_0_thunk = {
426  &CreateIMEInputEvent,
427  &IsIMEInputEvent,
428  &GetIMEText,
429  &GetIMESegmentNumber,
430  &GetIMESegmentOffset,
431  &GetIMETargetSegment,
432  &GetIMESelection
433};
434
435// Touch -----------------------------------------------------------------------
436
437PP_Resource CreateTouchInputEvent(PP_Instance instance,
438                                  PP_InputEvent_Type type,
439                                  PP_TimeTicks time_stamp,
440                                  uint32_t modifiers) {
441  VLOG(4) << "PPB_TouchInputEvent::Create()";
442  EnterResourceCreation enter(instance);
443  if (enter.failed())
444    return 0;
445  return enter.functions()->CreateTouchInputEvent(instance, type, time_stamp,
446                                                  modifiers);
447}
448
449void AddTouchPoint(PP_Resource touch_event,
450                   PP_TouchListType list,
451                   const PP_TouchPoint* point) {
452  VLOG(4) << "PPB_TouchInputEvent::AddTouchPoint()";
453  EnterInputEvent enter(touch_event, true);
454  if (enter.failed())
455    return;
456  return enter.object()->AddTouchPoint(list, *point);
457}
458
459PP_Bool IsTouchInputEvent(PP_Resource resource) {
460  VLOG(4) << "PPB_TouchInputEvent::IsTouchInputEvent()";
461  if (!IsInputEvent(resource))
462    return PP_FALSE;  // Prevent warning log in GetType.
463  PP_InputEvent_Type type = GetType(resource);
464  return PP_FromBool(type == PP_INPUTEVENT_TYPE_TOUCHSTART ||
465                     type == PP_INPUTEVENT_TYPE_TOUCHMOVE ||
466                     type == PP_INPUTEVENT_TYPE_TOUCHEND ||
467                     type == PP_INPUTEVENT_TYPE_TOUCHCANCEL);
468}
469
470uint32_t GetTouchCount(PP_Resource touch_event, PP_TouchListType list) {
471  VLOG(4) << "PPB_TouchInputEvent::GetTouchCount()";
472  EnterInputEvent enter(touch_event, true);
473  if (enter.failed())
474    return 0;
475  return enter.object()->GetTouchCount(list);
476}
477
478struct PP_TouchPoint GetTouchByIndex(PP_Resource touch_event,
479                                     PP_TouchListType list,
480                                     uint32_t index) {
481  VLOG(4) << "PPB_TouchInputEvent::GetTouchByIndex()";
482  EnterInputEvent enter(touch_event, true);
483  if (enter.failed())
484    return PP_MakeTouchPoint();
485  return enter.object()->GetTouchByIndex(list, index);
486}
487
488struct PP_TouchPoint GetTouchById(PP_Resource touch_event,
489                                  PP_TouchListType list,
490                                  uint32_t id) {
491  VLOG(4) << "PPB_TouchInputEvent::GetTouchById()";
492  EnterInputEvent enter(touch_event, true);
493  if (enter.failed())
494    return PP_MakeTouchPoint();
495  return enter.object()->GetTouchById(list, id);
496}
497
498const PPB_TouchInputEvent_1_0 g_ppb_touch_input_event_thunk = {
499  &CreateTouchInputEvent,
500  &AddTouchPoint,
501  &IsTouchInputEvent,
502  &GetTouchCount,
503  &GetTouchByIndex,
504  &GetTouchById
505};
506
507}  // namespace
508
509const PPB_InputEvent_1_0* GetPPB_InputEvent_1_0_Thunk() {
510  return &g_ppb_input_event_thunk;
511}
512
513const PPB_MouseInputEvent_1_0* GetPPB_MouseInputEvent_1_0_Thunk() {
514  return &g_ppb_mouse_input_event_1_0_thunk;
515}
516
517const PPB_MouseInputEvent_1_1* GetPPB_MouseInputEvent_1_1_Thunk() {
518  return &g_ppb_mouse_input_event_1_1_thunk;
519}
520
521const PPB_KeyboardInputEvent_1_0* GetPPB_KeyboardInputEvent_1_0_Thunk() {
522  return &g_ppb_keyboard_input_event_1_0_thunk;
523}
524
525const PPB_KeyboardInputEvent_1_2* GetPPB_KeyboardInputEvent_1_2_Thunk() {
526  return &g_ppb_keyboard_input_event_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