Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / doc / devguide / coding / view-focus-input-events.rst
1 .. _view_focus_input_events:
2
3 ####################################
4 View Change, Focus, and Input Events
5 ####################################
6
7 .. contents::
8   :local:
9   :backlinks: none
10   :depth: 2
11
12 This chapter describes view change, focus, and input event handling for a
13 Native Client module. The chapter assumes you are familiar with the
14 material presented in the :doc:`Technical Overview <../../overview>`.
15
16 There are two examples used in this chapter to illustrate basic
17 programming techniques. The ``input_events`` example is used to
18 illustrate how your module can react to keyboard and mouse input
19 event.  The ``mouse_lock`` example is used to illustrate how your module
20 can react to view change events. You can find these examples in the
21 ``/examples/api/input_events`` and ``/examples/api/mouse_lock``
22 directories in the Native Client SDK.  There is also the
23 ppapi_simple library that can be used to to implement most of the
24 boiler plate.  The ``pi_generator`` example in
25 ``/examples/demo/pi_generator`` uses ppapi_simple to manage view
26 change events and 2D graphics.
27
28
29 Overview
30 ========
31
32 When a user interacts with the web page using a keyboard, mouse or some other
33 input device, the browser generates input events.  In a traditional web
34 application, these input events are passed to and handled in JavaScript,
35 typically through event listeners and event handlers. In a Native Client
36 application, user interaction with an instance of a module (e.g., clicking
37 inside the rectangle managed by a module) also generates input events, which
38 are passed to the module. The browser also passes view change and focus events
39 that affect a module's instance to the module. Native Client modules can
40 override certain functions in the `pp::Instance
41 </native-client/pepper_stable/cpp/classpp_1_1_instance>`_ class to handle input
42 and browser events. These functions are listed in the table below:
43
44
45 ======================  ===============================  ====================
46 Function                  Event                            Use
47 ======================  ===============================  ====================
48 ``DidChangeView``       Called when the position,        An implementation
49                         size, or clip rectangle          of this function
50                         of the module's instance in      might check the size
51                         the browser has changed.         of the module
52                         This event also occurs           instance's rectangle
53                         when browser window is           has changed and
54                         resized or mouse wheel           reallocate the
55                         is scrolled.                     graphics context
56                                                          when a different
57                                                          size is received.
58
59 ``DidChangeFocus``      Called when the module's         An implementation
60                         instance in the browser          of this function
61                         has gone in or out of            might start or stop
62                         focus (usually by                an animation or a
63                         clicking inside or               blinking cursor.
64                         outside the module
65                         instance). Having focus
66                         means that keyboard
67                         events will be sent to
68                         the module instance.
69                         An instance's default
70                         condition is that it
71                         does not have focus.
72
73 ``HandleDocumentLoad``  Called after                     This API is only
74                         ``pp::Instance::Init()``         applicable when you
75                         for a full-frame module          are writing an
76                         instance that was                extension to enhance
77                         instantiated based on            the abilities of
78                         the MIME type of a               the Chrome web
79                         DOMWindow navigation.            browser. For
80                         This situation only              example, a PDF
81                         applies to modules that          viewer might
82                         are pre-registered to            implement this
83                         handle certain MIME              function to download
84                         types. If you haven't            and display a PDF
85                         specifically registered          file.
86                         to handle a MIME type or
87                         aren't positive this
88                         applies to you, your
89                         implementation of this
90                         function can just return
91                         false.
92
93 ``HandleInputEvent``    Called when a user               An implementation of
94                         interacts with the               this function
95                         module's instance in the         examines the input
96                         browser using an input           event type and
97                         device such as a mouse           branches accordingly.
98                         or keyboard. You must
99                         register your module to
100                         accept input events
101                         using
102                         ``RequestInputEvents()``
103                         for mouse events and
104                         ``RequestFilteringInputEvents``
105                         for keyboard events
106                         prior to overriding this
107                         function.
108 ======================  ===============================  ====================
109
110
111 These interfaces are found in the `pp::Instance class
112 </native-client/pepper_stable/cpp/classpp_1_1_instance>`_.  The sections below
113 provide examples of how to handle these events.
114
115
116 Handling browser events
117 =======================
118
119 DidChangeView()
120 ---------------
121
122 In the ``mouse_lock`` example, ``DidChangeView()`` checks the previous size
123 of instance's rectangle versus the new size.  It also compares
124 other state such as whether or not the app is running in full screen mode.
125 If none of the state has actually changed, no action is needed.
126 However, if the size of the view or other state has changed, it frees the
127 old graphics context and allocates a new one.
128
129 .. naclcode::
130
131   void MouseLockInstance::DidChangeView(const pp::View& view) {
132     // DidChangeView can get called for many reasons, so we only want to
133     // rebuild the device context if we really need to.
134     if ((size_ == view.GetRect().size()) &&
135         (was_fullscreen_ == view.IsFullscreen()) && is_context_bound_) {
136       return;
137     }
138
139     // ...
140
141     // Reallocate the graphics context.
142     size_ = view.GetRect().size();
143     device_context_ = pp::Graphics2D(this, size_, false);
144     waiting_for_flush_completion_ = false;
145
146     is_context_bound_ = BindGraphics(device_context_);
147     // ...
148
149     // Remember if we are fullscreen or not
150     was_fullscreen_ = view.IsFullscreen();
151     // ...
152   }
153
154
155 For more information about graphics contexts and how to manipulate images, see:
156
157 * `pp::ImageData class
158   </native-client/pepper_stable/cpp/classpp_1_1_image_data>`_
159 * `pp::Graphics2D class
160   </native-client/pepper_stable/cpp/classpp_1_1_graphics2_d>`_
161
162
163 DidChangeFocus()
164 ----------------
165
166 ``DidChangeFocus()`` is called when you click inside or outside of a
167 module's instance in the web page. When the instance goes out
168 of focus (click outside of the instance), you might do something
169 like stop an animation. When the instance regains focus, you can
170 restart the animation.
171
172 .. naclcode::
173
174   void DidChangeFocus(bool focus) {
175     // Do something like stopping animation or a blinking cursor in
176     // the instance.
177   }
178
179
180 Handling input events
181 =====================
182
183 Input events are events that occur when the user interacts with a
184 module instance using the mouse, keyboard, or other input device
185 (e.g., touch screen). This section describes how the ``input_events``
186 example handles input events.
187
188
189 Registering a module to accept input events
190 -------------------------------------------
191
192 Before your module can handle these events, you must register your
193 module to accept input events using ``RequestInputEvents()`` for mouse
194 events and ``RequestFilteringInputEvents()`` for keyboard events. For the
195 ``input_events`` example, this is done in the constructor of the
196 ``InputEventInstance`` class:
197
198 .. naclcode::
199
200   class InputEventInstance : public pp::Instance {
201    public:
202     explicit InputEventInstance(PP_Instance instance)
203         : pp::Instance(instance), event_thread_(NULL), callback_factory_(this) {
204       RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL |
205                          PP_INPUTEVENT_CLASS_TOUCH);
206       RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
207     }
208     // ...
209   };
210
211
212 ``RequestInputEvents()`` and ``RequestFilteringInputEvents()`` accept a
213 combination of flags that identify the class of events that the instance is
214 requesting to receive. Input event classes are defined in the
215 `PP_InputEvent_Class
216 </native-client/pepper_stable/c/group___enums.html#gafe68e3c1031daa4a6496845ff47649cd>`_
217 enumeration in `ppb_input_event.h
218 </native-client/pepper_stable/c/ppb__input__event_8h>`_.
219
220
221 Determining and branching on event types
222 ----------------------------------------
223
224 In a typical implementation, the ``HandleInputEvent()`` function determines the
225 type of each event using the ``GetType()`` function found in the ``InputEvent``
226 class. The ``HandleInputEvent()`` function then uses a switch statement to
227 branch on the type of input event. Input events are defined in the
228 `PP_InputEvent_Type
229 </native-client/pepper_stable/c/group___enums.html#gaca7296cfec99fcb6646b7144d1d6a0c5>`_
230 enumeration in `ppb_input_event.h
231 </native-client/pepper_stable/c/ppb__input__event_8h>`_.
232
233 .. naclcode::
234
235   virtual bool HandleInputEvent(const pp::InputEvent& event) {
236     Event* event_ptr = NULL;
237     switch (event.GetType()) {
238       case PP_INPUTEVENT_TYPE_UNDEFINED:
239         break;
240       case PP_INPUTEVENT_TYPE_MOUSEDOWN:
241       case PP_INPUTEVENT_TYPE_MOUSEUP:
242       case PP_INPUTEVENT_TYPE_MOUSEMOVE:
243       case PP_INPUTEVENT_TYPE_MOUSEENTER:
244       case PP_INPUTEVENT_TYPE_MOUSELEAVE:
245       case PP_INPUTEVENT_TYPE_CONTEXTMENU: {
246         pp::MouseInputEvent mouse_event(event);
247         PP_InputEvent_MouseButton pp_button = mouse_event.GetButton();
248         MouseEvent::MouseButton mouse_button = MouseEvent::kNone;
249         switch (pp_button) {
250           case PP_INPUTEVENT_MOUSEBUTTON_NONE:
251             mouse_button = MouseEvent::kNone;
252             break;
253           case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
254             mouse_button = MouseEvent::kLeft;
255             break;
256           case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
257             mouse_button = MouseEvent::kMiddle;
258             break;
259           case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
260             mouse_button = MouseEvent::kRight;
261             break;
262         }
263         event_ptr =
264             new MouseEvent(ConvertEventModifier(mouse_event.GetModifiers()),
265                            mouse_button,
266                            mouse_event.GetPosition().x(),
267                            mouse_event.GetPosition().y(),
268                            mouse_event.GetClickCount(),
269                            mouse_event.GetTimeStamp(),
270                            event.GetType() == PP_INPUTEVENT_TYPE_CONTEXTMENU);
271       } break;
272       case PP_INPUTEVENT_TYPE_WHEEL: {
273         pp::WheelInputEvent wheel_event(event);
274         event_ptr =
275             new WheelEvent(ConvertEventModifier(wheel_event.GetModifiers()),
276                            wheel_event.GetDelta().x(),
277                            wheel_event.GetDelta().y(),
278                            wheel_event.GetTicks().x(),
279                            wheel_event.GetTicks().y(),
280                            wheel_event.GetScrollByPage(),
281                            wheel_event.GetTimeStamp());
282       } break;
283       case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
284       case PP_INPUTEVENT_TYPE_KEYDOWN:
285       case PP_INPUTEVENT_TYPE_KEYUP:
286       case PP_INPUTEVENT_TYPE_CHAR: {
287         pp::KeyboardInputEvent key_event(event);
288         event_ptr = new KeyEvent(ConvertEventModifier(key_event.GetModifiers()),
289                                  key_event.GetKeyCode(),
290                                  key_event.GetTimeStamp(),
291                                  key_event.GetCharacterText().DebugString());
292       } break;
293       default: {
294         // For any unhandled events, send a message to the browser
295         // so that the user is aware of these and can investigate.
296         std::stringstream oss;
297         oss << "Default (unhandled) event, type=" << event.GetType();
298         PostMessage(oss.str());
299       } break;
300     }
301     event_queue_.Push(event_ptr);
302     return true;
303   }
304
305
306 Notice that the generic ``InputEvent`` received by ``HandleInputEvent()`` is
307 converted into a specific type after the event type is
308 determined.  The event types handled in the example code are
309 ``MouseInputEvent``, ``WheelInputEvent``, and ``KeyboardInputEvent``.
310 There are also ``TouchInputEvents``.  For the latest list of event types,
311 see the `InputEvent documentation
312 </native-client/pepper_stable/c/classpp_1_1_input_event>`_.
313 For reference information related to the these event classes, see the
314 following documentation:
315
316 * `pp::MouseInputEvent class
317   </native-client/pepper_stable/c/classpp_1_1_mouse_input_event>`_
318 * `pp::WheelInputEvent class
319   </native-client/pepper_stable/c/classpp_1_1_wheel_input_event>`_
320 * `pp::KeyboardInputEvent class
321   </native-client/pepper_stable/c/classpp_1_1_keyboard_input_event>`_
322
323
324 Threading and blocking
325 ----------------------
326
327 ``HandleInputEvent()`` in this example runs on the main module thread.
328 However, the bulk of the work happens on a separate worker thread (see
329 ``ProcessEventOnWorkerThread``). ``HandleInputEvent()`` puts events in
330 the ``event_queue_`` and the worker thread takes events from the
331 ``event_queue_``. This processing happens independently of the main
332 thread, so as not to slow down the browser.