Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / native_client_sdk / src / examples / api / input_event / input_event.cc
blob583c230091755670a95f058b38acbc067fa2271f
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.
5 // C headers
6 #include <stdio.h>
8 // C++ headers
9 #include <sstream>
10 #include <string>
12 // PPAPI headers
13 #include "ppapi/cpp/completion_callback.h"
14 #include "ppapi/cpp/input_event.h"
15 #include "ppapi/cpp/instance.h"
16 #include "ppapi/cpp/module.h"
17 #include "ppapi/cpp/point.h"
18 #include "ppapi/cpp/var.h"
19 #include "ppapi/utility/completion_callback_factory.h"
21 #ifdef PostMessage
22 #undef PostMessage
23 #endif
25 namespace {
27 std::string ModifierToString(uint32_t modifier) {
28 std::string s;
29 if (modifier & PP_INPUTEVENT_MODIFIER_SHIFTKEY) {
30 s += "shift ";
32 if (modifier & PP_INPUTEVENT_MODIFIER_CONTROLKEY) {
33 s += "ctrl ";
35 if (modifier & PP_INPUTEVENT_MODIFIER_ALTKEY) {
36 s += "alt ";
38 if (modifier & PP_INPUTEVENT_MODIFIER_METAKEY) {
39 s += "meta ";
41 if (modifier & PP_INPUTEVENT_MODIFIER_ISKEYPAD) {
42 s += "keypad ";
44 if (modifier & PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) {
45 s += "autorepeat ";
47 if (modifier & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
48 s += "left-button-down ";
50 if (modifier & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) {
51 s += "middle-button-down ";
53 if (modifier & PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) {
54 s += "right-button-down ";
56 if (modifier & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) {
57 s += "caps-lock ";
59 if (modifier & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) {
60 s += "num-lock ";
62 return s;
65 std::string MouseButtonToString(PP_InputEvent_MouseButton button) {
66 switch (button) {
67 case PP_INPUTEVENT_MOUSEBUTTON_NONE:
68 return "None";
69 case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
70 return "Left";
71 case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
72 return "Middle";
73 case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
74 return "Right";
75 default:
76 std::ostringstream stream;
77 stream << "Unrecognized (" << static_cast<int32_t>(button) << ")";
78 return stream.str();
82 std::string TouchKindToString(PP_InputEvent_Type kind) {
83 switch (kind) {
84 case PP_INPUTEVENT_TYPE_TOUCHSTART:
85 return "Start";
86 case PP_INPUTEVENT_TYPE_TOUCHMOVE:
87 return "Move";
88 case PP_INPUTEVENT_TYPE_TOUCHEND:
89 return "End";
90 case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
91 return "Cancel";
92 default:
93 std::ostringstream stream;
94 stream << "Unrecognized (" << static_cast<int32_t>(kind) << ")";
95 return stream.str();
99 } // namespace
101 class InputEventInstance : public pp::Instance {
102 public:
103 explicit InputEventInstance(PP_Instance instance)
104 : pp::Instance(instance) {
105 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL |
106 PP_INPUTEVENT_CLASS_TOUCH);
107 RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
110 bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
111 return true;
114 /// Clicking outside of the instance's bounding box
115 /// will create a DidChangeFocus event (the NaCl instance is
116 /// out of focus). Clicking back inside the instance's
117 /// bounding box will create another DidChangeFocus event
118 /// (the NaCl instance is back in focus). The default is
119 /// that the instance is out of focus.
120 void DidChangeFocus(bool focus) {
121 std::ostringstream stream;
122 stream << "DidChangeFocus:" << " focus:" << focus;
123 PostMessage(stream.str());
126 /// Scrolling the mouse wheel causes a DidChangeView event.
127 void DidChangeView(const pp::View& view) {
128 std::ostringstream stream;
129 stream << "DidChangeView:"
130 << " x:" << view.GetRect().x()
131 << " y:" << view.GetRect().y()
132 << " width:" << view.GetRect().width()
133 << " height:" << view.GetRect().height()
134 << "\n"
135 << " IsFullscreen:" << view.IsFullscreen()
136 << " IsVisible:" << view.IsVisible()
137 << " IsPageVisible:" << view.IsPageVisible()
138 << " GetDeviceScale:" << view.GetDeviceScale()
139 << " GetCSSScale:" << view.GetCSSScale();
140 PostMessage(stream.str());
143 virtual bool HandleInputEvent(const pp::InputEvent& event) {
144 switch (event.GetType()) {
145 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
146 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
147 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
148 case PP_INPUTEVENT_TYPE_IME_TEXT:
149 case PP_INPUTEVENT_TYPE_UNDEFINED:
150 // these cases are not handled.
151 break;
152 case PP_INPUTEVENT_TYPE_MOUSEDOWN:
153 case PP_INPUTEVENT_TYPE_MOUSEUP:
154 case PP_INPUTEVENT_TYPE_MOUSEMOVE:
155 case PP_INPUTEVENT_TYPE_MOUSEENTER:
156 case PP_INPUTEVENT_TYPE_MOUSELEAVE:
157 case PP_INPUTEVENT_TYPE_CONTEXTMENU: {
158 pp::MouseInputEvent mouse_event(event);
159 std::ostringstream stream;
160 stream << "Mouse event:"
161 << " modifier:" << ModifierToString(mouse_event.GetModifiers())
162 << " button:" << MouseButtonToString(mouse_event.GetButton())
163 << " x:" << mouse_event.GetPosition().x()
164 << " y:" << mouse_event.GetPosition().y()
165 << " click_count:" << mouse_event.GetClickCount()
166 << " time:" << mouse_event.GetTimeStamp()
167 << " is_context_menu: "
168 << (event.GetType() == PP_INPUTEVENT_TYPE_CONTEXTMENU);
169 PostMessage(stream.str());
170 break;
173 case PP_INPUTEVENT_TYPE_WHEEL: {
174 pp::WheelInputEvent wheel_event(event);
175 std::ostringstream stream;
176 stream << "Wheel event:"
177 << " modifier:" << ModifierToString(wheel_event.GetModifiers())
178 << " deltax:" << wheel_event.GetDelta().x()
179 << " deltay:" << wheel_event.GetDelta().y()
180 << " wheel_ticks_x:" << wheel_event.GetTicks().x()
181 << " wheel_ticks_y:" << wheel_event.GetTicks().y()
182 << " scroll_by_page: " << wheel_event.GetScrollByPage()
183 << " time:" << wheel_event.GetTimeStamp();
184 PostMessage(stream.str());
185 break;
188 case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
189 case PP_INPUTEVENT_TYPE_KEYDOWN:
190 case PP_INPUTEVENT_TYPE_KEYUP:
191 case PP_INPUTEVENT_TYPE_CHAR: {
192 pp::KeyboardInputEvent key_event(event);
193 std::ostringstream stream;
194 stream << "Key event:"
195 << " modifier:" << ModifierToString(key_event.GetModifiers())
196 << " key_code:" << key_event.GetKeyCode()
197 << " time:" << key_event.GetTimeStamp()
198 << " text:" << key_event.GetCharacterText().DebugString();
199 PostMessage(stream.str());
200 break;
203 case PP_INPUTEVENT_TYPE_TOUCHSTART:
204 case PP_INPUTEVENT_TYPE_TOUCHMOVE:
205 case PP_INPUTEVENT_TYPE_TOUCHEND:
206 case PP_INPUTEVENT_TYPE_TOUCHCANCEL: {
207 pp::TouchInputEvent touch_event(event);
208 std::ostringstream stream;
209 stream << "Touch event:" << TouchKindToString(event.GetType())
210 << " modifier:" << ModifierToString(touch_event.GetModifiers());
212 uint32_t touch_count =
213 touch_event.GetTouchCount(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES);
214 for (uint32_t i = 0; i < touch_count; ++i) {
215 pp::TouchPoint point =
216 touch_event.GetTouchByIndex(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES, i);
217 stream << " x[" << point.id() << "]:" << point.position().x()
218 << " y[" << point.id() << "]:" << point.position().y()
219 << " radii_x[" << point.id() << "]:" << point.radii().x()
220 << " radii_y[" << point.id() << "]:" << point.radii().y()
221 << " angle[" << point.id() << "]:" << point.rotation_angle()
222 << " pressure[" << point.id() << "]:" << point.pressure();
224 stream << " time:" << touch_event.GetTimeStamp();
225 PostMessage(stream.str());
226 break;
229 default: {
230 // For any unhandled events, send a message to the browser
231 // so that the user is aware of these and can investigate.
232 std::stringstream oss;
233 oss << "Default (unhandled) event, type=" << event.GetType();
234 PostMessage(oss.str());
235 } break;
238 return true;
242 class InputEventModule : public pp::Module {
243 public:
244 InputEventModule() : pp::Module() {}
245 virtual ~InputEventModule() {}
247 virtual pp::Instance* CreateInstance(PP_Instance instance) {
248 return new InputEventInstance(instance);
252 namespace pp {
253 Module* CreateModule() { return new InputEventModule(); }