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