summaryrefslogtreecommitdiffstats
path: root/native_client_sdk
diff options
context:
space:
mode:
authorbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-22 00:21:53 +0000
committerbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-22 00:21:53 +0000
commit5089c49fa38605755a50aa459bbc8d5da797002d (patch)
tree66b744b475ca6b66194eeca8259cb9a863f060b5 /native_client_sdk
parenta60a34dbaf547de7a323f6d487a6bca182f0a40c (diff)
downloadchromium_src-5089c49fa38605755a50aa459bbc8d5da797002d.zip
chromium_src-5089c49fa38605755a50aa459bbc8d5da797002d.tar.gz
chromium_src-5089c49fa38605755a50aa459bbc8d5da797002d.tar.bz2
[NaCl SDK] Make input_event example single-threaded again.
This significantly simplifies the example. Also, it isn't necessary to do anything complex to pass InputEvents to worker threads anymore; the functions can be called off main-thread. BUG=243083 R=sbc@chromium.org, noelallen@chromium.org Review URL: https://codereview.chromium.org/30683002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229968 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'native_client_sdk')
-rw-r--r--native_client_sdk/src/examples/api/input_event/custom_events.cc151
-rw-r--r--native_client_sdk/src/examples/api/input_event/custom_events.h191
-rw-r--r--native_client_sdk/src/examples/api/input_event/example.dsc3
-rw-r--r--native_client_sdk/src/examples/api/input_event/example.js13
-rw-r--r--native_client_sdk/src/examples/api/input_event/index.html25
-rw-r--r--native_client_sdk/src/examples/api/input_event/input_event.cc355
-rw-r--r--native_client_sdk/src/examples/api/input_event/shared_queue.h155
7 files changed, 145 insertions, 748 deletions
diff --git a/native_client_sdk/src/examples/api/input_event/custom_events.cc b/native_client_sdk/src/examples/api/input_event/custom_events.cc
deleted file mode 100644
index e0558a5..0000000
--- a/native_client_sdk/src/examples/api/input_event/custom_events.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <sstream>
-
-#include "custom_events.h"
-
-// Convert a given modifier to a descriptive string. Note that the actual
-// declared type of modifier in each of the event classes is uint32_t, but it is
-// expected to be interpreted as a bitfield of 'or'ed PP_InputEvent_Modifier
-// values.
-std::string ModifierToString(uint32_t modifier) {
- std::string s;
- if (modifier & kShiftKeyModifier) {
- s += "shift ";
- }
- if (modifier & kControlKeyModifier) {
- s += "ctrl ";
- }
- if (modifier & kAltKeyModifier) {
- s += "alt ";
- }
- if (modifier & kMetaKeyModifer) {
- s += "meta ";
- }
- if (modifier & kKeyPadModifier) {
- s += "keypad ";
- }
- if (modifier & kAutoRepeatModifier) {
- s += "autorepeat ";
- }
- if (modifier & kLeftButtonModifier) {
- s += "left-button-down ";
- }
- if (modifier & kMiddleButtonModifier) {
- s += "middle-button-down ";
- }
- if (modifier & kRightButtonModifier) {
- s += "right-button-down ";
- }
- if (modifier & kCapsLockModifier) {
- s += "caps-lock ";
- }
- if (modifier & kNumLockModifier) {
- s += "num-lock ";
- }
- return s;
-}
-
-std::string KeyEvent::ToString() const {
- std::ostringstream stream;
- stream << "Key event:"
- << " modifier:" << string_event_modifiers()
- << " key_code:" << key_code_ << " time:" << timestamp_
- << " text:" << text_ << "\n";
- return stream.str();
-}
-
-std::string MouseEvent::ToString() const {
- std::ostringstream stream;
- stream << "Mouse event:"
- << " modifier:" << string_event_modifiers()
- << " button:" << MouseButtonToString(mouse_button_)
- << " x:" << x_position_ << " y:" << y_position_
- << " click_count:" << click_count_ << " time:" << timestamp_
- << " is_context_menu: " << is_context_menu_ << "\n";
- return stream.str();
-}
-
-std::string WheelEvent::ToString() const {
- std::ostringstream stream;
- stream << "Wheel event:"
- << " modifier:" << string_event_modifiers() << " deltax:" << delta_x_
- << " deltay:" << delta_y_ << " wheel_ticks_x:" << ticks_x_
- << " wheel_ticks_y:" << ticks_y_
- << " scroll_by_page: " << scroll_by_page_ << " time:" << timestamp_
- << "\n";
- return stream.str();
-}
-
-std::string MouseEvent::MouseButtonToString(MouseButton button) const {
- switch (button) {
- case kNone:
- return "None";
- case kLeft:
- return "Left";
- case kMiddle:
- return "Middle";
- case kRight:
- return "Right";
- default:
- std::ostringstream stream;
- stream << "Unrecognized (" << static_cast<int32_t>(button) << ")";
- return stream.str();
- }
-}
-
-std::string TouchEvent::KindToString(Kind kind) const {
- switch (kind) {
- case kNone:
- return "None";
- case kStart:
- return "Start";
- case kMove:
- return "Move";
- case kEnd:
- return "End";
- case kCancel:
- return "Cancel";
- default:
- std::ostringstream stream;
- stream << "Unrecognized (" << static_cast<int32_t>(kind) << ")";
- return stream.str();
- }
-}
-
-void TouchEvent::AddTouch(uint32_t id,
- float x,
- float y,
- float radii_x,
- float radii_y,
- float angle,
- float pressure) {
- Touch touch;
- touch.id = id;
- touch.x = x;
- touch.y = y;
- touch.radii_x = radii_x;
- touch.radii_y = radii_y;
- touch.angle = angle;
- touch.pressure = pressure;
- touches.push_back(touch);
-}
-
-std::string TouchEvent::ToString() const {
- std::ostringstream stream;
- stream << "Touch event:" << KindToString(kind_)
- << " modifier:" << string_event_modifiers();
- for (size_t i = 0; i < touches.size(); ++i) {
- const Touch& touch = touches[i];
- stream << " x[" << touch.id << "]:" << touch.x << " y[" << touch.id
- << "]:" << touch.y << " radii_x[" << touch.id
- << "]:" << touch.radii_x << " radii_y[" << touch.id
- << "]:" << touch.radii_y << " angle[" << touch.id
- << "]:" << touch.angle << " pressure[" << touch.id
- << "]:" << touch.pressure;
- }
- stream << " time:" << timestamp_ << "\n";
- return stream.str();
-}
diff --git a/native_client_sdk/src/examples/api/input_event/custom_events.h b/native_client_sdk/src/examples/api/input_event/custom_events.h
deleted file mode 100644
index fde32d5..0000000
--- a/native_client_sdk/src/examples/api/input_event/custom_events.h
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CUSTOM_EVENTS_H
-#define CUSTOM_EVENTS_H
-
-#include <stdint.h>
-#include <string>
-#include <vector>
-
-// These functions and classes are used to define a non-Pepper set of
-// events. This is typical of what many developers might do, since it
-// would be common to convert a Pepper event into some other more
-// application-specific type of event (SDL, Qt, etc.).
-
-// Constants used for Event::event_modifers_ (which is an int)
-// are given below. Use powers of 2 so we can use bitwise AND/OR operators.
-const uint32_t kShiftKeyModifier = 1 << 0;
-const uint32_t kControlKeyModifier = 1 << 1;
-const uint32_t kAltKeyModifier = 1 << 2;
-const uint32_t kMetaKeyModifer = 1 << 3;
-const uint32_t kKeyPadModifier = 1 << 4;
-const uint32_t kAutoRepeatModifier = 1 << 5;
-const uint32_t kLeftButtonModifier = 1 << 6;
-const uint32_t kMiddleButtonModifier = 1 << 7;
-const uint32_t kRightButtonModifier = 1 << 8;
-const uint32_t kCapsLockModifier = 1 << 9;
-const uint32_t kNumLockModifier = 1 << 10;
-
-std::string ModifierToString(uint32_t modifier);
-
-// Abstract base class for an Event -- ToString() is not defined.
-// With polymorphism, we can have a collection of Event* and call
-// ToString() on each one to be able to display the details of each
-// event.
-class Event {
- public:
- // Constructor for the base class.
- // |modifiers| is an int that uses bit fields to set specific
- // changes, such as the Alt key, specific button, etc. See
- // ModifierToString() and constants defined in custom_events.cc.
- explicit Event(uint32_t modifiers) : event_modifiers_(modifiers) {}
- uint32_t event_modifiers() const { return event_modifiers_; }
- std::string string_event_modifiers() const {
- return ModifierToString(event_modifiers_);
- }
- // Convert the WheelEvent to a string
- virtual std::string ToString() const = 0;
- virtual ~Event() {}
-
- private:
- uint32_t event_modifiers_;
-};
-
-// Class for a keyboard event.
-class KeyEvent : public Event {
- public:
- // KeyEvent Constructor. |modifiers| is passed to Event base class.
- // |keycode| is the ASCII value, |time| is a timestamp,
- // |text| is the value as a string.
- KeyEvent(uint32_t modifiers, uint32_t keycode, double time, std::string text)
- : Event(modifiers), key_code_(keycode), timestamp_(time), text_(text) {}
- // Convert the WheelEvent to a string
- virtual std::string ToString() const;
-
- private:
- uint32_t key_code_;
- double timestamp_;
- std::string text_;
-};
-
-class MouseEvent : public Event {
- public:
- // Specify a mouse button, with kNone available for initialization.
- enum MouseButton {
- kNone,
- kLeft,
- kMiddle,
- kRight
- };
-
- // MouseEvent Constructor. |modifiers| is passed to Event base class.
- // |button| specifies which button
- // |xpos| and |ypos| give the location,
- // |clicks| is how many times this same |xpos|,|ypos|
- // has been clicked in a row. |time| is a timestamp,
- MouseEvent(uint32_t modifiers,
- MouseButton button,
- uint32_t xpos,
- uint32_t ypos,
- uint32_t clicks,
- double time,
- bool is_context_menu)
- : Event(modifiers),
- mouse_button_(button),
- x_position_(xpos),
- y_position_(ypos),
- click_count_(clicks),
- timestamp_(time),
- is_context_menu_(is_context_menu) {}
- // Convert the WheelEvent to a string
- virtual std::string ToString() const;
-
- private:
- MouseButton mouse_button_;
- uint32_t x_position_;
- uint32_t y_position_;
- uint32_t click_count_;
- double timestamp_;
- bool is_context_menu_;
-
- std::string MouseButtonToString(MouseButton button) const;
-};
-
-class WheelEvent : public Event {
- public:
- // WheelEvent Constructor. |modifiers| is passed to Event base class.
- // |xticks| and |yticks| specify number of mouse wheel ticks.
- // |scroll_by_page| indicates if we have scrolled past the current
- // page. |time| is a timestamp,
- WheelEvent(int modifiers,
- uint32_t dx,
- uint32_t dy,
- uint32_t xticks,
- uint32_t yticks,
- bool scroll_by_page,
- float time)
- : Event(modifiers),
- delta_x_(dx),
- delta_y_(dy),
- ticks_x_(xticks),
- ticks_y_(yticks),
- scroll_by_page_(scroll_by_page),
- timestamp_(time) {}
- // Convert the WheelEvent to a string
- virtual std::string ToString() const;
-
- private:
- uint32_t delta_x_;
- uint32_t delta_y_;
- uint32_t ticks_x_;
- uint32_t ticks_y_;
- bool scroll_by_page_;
- double timestamp_;
-};
-
-class TouchEvent : public Event {
- public:
- // The kind of touch event that occurred.
- enum Kind {
- kNone,
- kStart,
- kMove,
- kEnd,
- kCancel
- };
-
- // TouchEvent constructor.
- TouchEvent(int modifiers, Kind kind, float time)
- : Event(modifiers), kind_(kind), timestamp_(time) {}
- // Add a changed touch to this touch event.
- void AddTouch(uint32_t id,
- float x,
- float y,
- float radii_x,
- float radii_y,
- float angle,
- float pressure);
- // Convert the TouchEvent to a string
- virtual std::string ToString() const;
-
- private:
- std::string KindToString(Kind kind) const;
-
- struct Touch {
- uint32_t id;
- float x;
- float y;
- float radii_x;
- float radii_y;
- float angle;
- float pressure;
- };
-
- Kind kind_;
- std::vector<Touch> touches;
- double timestamp_;
-};
-
-#endif // CUSTOM_EVENTS_H
diff --git a/native_client_sdk/src/examples/api/input_event/example.dsc b/native_client_sdk/src/examples/api/input_event/example.dsc
index 5744367..725a83c 100644
--- a/native_client_sdk/src/examples/api/input_event/example.dsc
+++ b/native_client_sdk/src/examples/api/input_event/example.dsc
@@ -5,10 +5,7 @@
'NAME' : 'input_event',
'TYPE' : 'main',
'SOURCES' : [
- 'custom_events.cc',
- 'custom_events.h',
'input_event.cc',
- 'shared_queue.h',
],
'LIBS': ['ppapi_cpp', 'ppapi', 'pthread']
}
diff --git a/native_client_sdk/src/examples/api/input_event/example.js b/native_client_sdk/src/examples/api/input_event/example.js
index 003e843..6375382 100644
--- a/native_client_sdk/src/examples/api/input_event/example.js
+++ b/native_client_sdk/src/examples/api/input_event/example.js
@@ -8,19 +8,6 @@ function moduleDidLoad() {
}
// Called by the common.js module.
-function attachListeners() {
- document.getElementById('killButton').addEventListener('click', cancelQueue);
-}
-
-// Called by the common.js module.
function handleMessage(message) {
common.logMessage(message.data);
}
-
-function cancelQueue() {
- if (common.naclModule == null) {
- console.log('Module is not loaded.');
- return;
- }
- common.naclModule.postMessage('CANCEL');
-}
diff --git a/native_client_sdk/src/examples/api/input_event/index.html b/native_client_sdk/src/examples/api/input_event/index.html
index 0739c7a..da8f178 100644
--- a/native_client_sdk/src/examples/api/input_event/index.html
+++ b/native_client_sdk/src/examples/api/input_event/index.html
@@ -11,28 +11,19 @@ found in the LICENSE file.
<title>{{title}}</title>
<script type="text/javascript" src="common.js"></script>
<script type="text/javascript" src="example.js"></script>
+ <style>
+ #listener { float: left; padding-right: 8px; }
+ </style>
</head>
<body {{attrs}}>
<h1>{{title}}</h1>
<h2>Status: <code id="statusField">NO-STATUS</code></h2>
- <p>The Input Events example shows how to handle input events in a
- multi-threaded application. The main thread converts input events to
- non-pepper events and puts them on a queue. The worker thread pulls them
- off of the queue, converts them to a string, and then uses
- CallOnMainThread so that PostMessage can send the result of the worker
- thread to the browser.</p>
- <p>If you press the 'Kill worker thread and queue' button, then the main
- thread (which puts events on the queue) will call CancelQueue, indicating
- that the main thread will no longer put events on the queue. When the worker
- sees that the shared queue has been cancelled, the worker thread will
- terminate.</p>
-
- <button id="killButton">Kill worker thread and queue</button>
-
- <!-- The NaCl plugin will be embedded inside the element with id "listener".
- See common.js.-->
<div id="listener"></div>
- <h2>Events:</h2>
+ <p>This example shows how to handle input events.</p>
+ <p>Click or touch the box to the left to see the events being sent to the
+ NaCl module. When it has focus, the module will also accept keyboard
+ events.</p>
+ <h2 style="clear: left">Events:</h2>
<pre id="log" style="font-weight: bold"></pre>
</body>
</html>
diff --git a/native_client_sdk/src/examples/api/input_event/input_event.cc b/native_client_sdk/src/examples/api/input_event/input_event.cc
index 1f57fcc..fee260b 100644
--- a/native_client_sdk/src/examples/api/input_event/input_event.cc
+++ b/native_client_sdk/src/examples/api/input_event/input_event.cc
@@ -3,8 +3,7 @@
// found in the LICENSE file.
// C headers
-#include <cassert>
-#include <cstdio>
+#include <stdio.h>
// C++ headers
#include <sstream>
@@ -19,77 +18,100 @@
#include "ppapi/cpp/var.h"
#include "ppapi/utility/completion_callback_factory.h"
-#include "custom_events.h"
-#include "shared_queue.h"
-
#ifdef PostMessage
#undef PostMessage
#endif
-const char* const kDidChangeView = "DidChangeView\n";
-const char* const kHandleInputEvent = "DidHandleInputEvent\n";
-const char* const kDidChangeFocus = "DidChangeFocus\n";
-const char* const kHaveFocus = "HaveFocus\n";
-const char* const kDontHaveFocus = "DontHaveFocus\n";
-const char* const kCancelMessage = "CANCEL";
+namespace {
+
+const char* const kDidChangeFocus = "DidChangeFocus";
+const char* const kHaveFocus = "HaveFocus";
+const char* const kDontHaveFocus = "DontHaveFocus";
-// Convert a pepper inputevent modifier value into a
-// custom event modifier.
-unsigned int ConvertEventModifier(uint32_t pp_modifier) {
- unsigned int custom_modifier = 0;
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_SHIFTKEY) {
- custom_modifier |= kShiftKeyModifier;
+std::string ModifierToString(uint32_t modifier) {
+ std::string s;
+ if (modifier & PP_INPUTEVENT_MODIFIER_SHIFTKEY) {
+ s += "shift ";
+ }
+ if (modifier & PP_INPUTEVENT_MODIFIER_CONTROLKEY) {
+ s += "ctrl ";
}
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_CONTROLKEY) {
- custom_modifier |= kControlKeyModifier;
+ if (modifier & PP_INPUTEVENT_MODIFIER_ALTKEY) {
+ s += "alt ";
}
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_ALTKEY) {
- custom_modifier |= kAltKeyModifier;
+ if (modifier & PP_INPUTEVENT_MODIFIER_METAKEY) {
+ s += "meta ";
}
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_METAKEY) {
- custom_modifier |= kMetaKeyModifer;
+ if (modifier & PP_INPUTEVENT_MODIFIER_ISKEYPAD) {
+ s += "keypad ";
}
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_ISKEYPAD) {
- custom_modifier |= kKeyPadModifier;
+ if (modifier & PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) {
+ s += "autorepeat ";
}
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) {
- custom_modifier |= kAutoRepeatModifier;
+ if (modifier & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
+ s += "left-button-down ";
}
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
- custom_modifier |= kLeftButtonModifier;
+ if (modifier & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) {
+ s += "middle-button-down ";
}
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) {
- custom_modifier |= kMiddleButtonModifier;
+ if (modifier & PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) {
+ s += "right-button-down ";
}
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) {
- custom_modifier |= kRightButtonModifier;
+ if (modifier & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) {
+ s += "caps-lock ";
}
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) {
- custom_modifier |= kCapsLockModifier;
+ if (modifier & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) {
+ s += "num-lock ";
+ }
+ return s;
+}
+
+std::string MouseButtonToString(PP_InputEvent_MouseButton button) {
+ switch (button) {
+ case PP_INPUTEVENT_MOUSEBUTTON_NONE:
+ return "None";
+ case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
+ return "Left";
+ case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
+ return "Middle";
+ case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
+ return "Right";
+ default:
+ std::ostringstream stream;
+ stream << "Unrecognized (" << static_cast<int32_t>(button) << ")";
+ return stream.str();
}
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) {
- custom_modifier |= kNumLockModifier;
+}
+
+std::string TouchKindToString(PP_InputEvent_Type kind) {
+ switch (kind) {
+ case PP_INPUTEVENT_TYPE_TOUCHSTART:
+ return "Start";
+ case PP_INPUTEVENT_TYPE_TOUCHMOVE:
+ return "Move";
+ case PP_INPUTEVENT_TYPE_TOUCHEND:
+ return "End";
+ case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
+ return "Cancel";
+ default:
+ std::ostringstream stream;
+ stream << "Unrecognized (" << static_cast<int32_t>(kind) << ")";
+ return stream.str();
}
- return custom_modifier;
}
+} // namespace
+
class InputEventInstance : public pp::Instance {
public:
explicit InputEventInstance(PP_Instance instance)
- : pp::Instance(instance), event_thread_(NULL), callback_factory_(this) {
+ : pp::Instance(instance) {
RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL |
PP_INPUTEVENT_CLASS_TOUCH);
RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
}
- // Not guaranteed to be called in Pepper, but a good idea to cancel the
- // queue and signal to workers to die if it is called.
- virtual ~InputEventInstance() { CancelQueueAndWaitForWorker(); }
-
- // Create the 'worker thread'.
bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
- event_thread_ = new pthread_t;
- pthread_create(event_thread_, NULL, ProcessEventOnWorkerThread, this);
return true;
}
@@ -100,50 +122,36 @@ class InputEventInstance : public pp::Instance {
/// (the NaCl instance is back in focus). The default is
/// that the instance is out of focus.
void DidChangeFocus(bool focus) {
- PostMessage(pp::Var(kDidChangeFocus));
- if (focus == true) {
- PostMessage(pp::Var(kHaveFocus));
- } else {
- PostMessage(pp::Var(kDontHaveFocus));
- }
+ std::ostringstream stream;
+ stream << "DidChangeFocus:" << " focus:" << focus;
+ PostMessage(stream.str());
}
/// Scrolling the mouse wheel causes a DidChangeView event.
void DidChangeView(const pp::View& view) {
- PostMessage(pp::Var(kDidChangeView));
- }
-
- virtual void HandleMessage(const pp::Var& var_message) {
- std::string message = var_message.AsString();
- if (kCancelMessage == message) {
- std::string reply =
- "Received cancel : only Focus events will be "
- "displayed. Worker thread for mouse/wheel/keyboard will exit.";
- PostMessage(pp::Var(reply));
- printf("Calling cancel queue\n");
- CancelQueueAndWaitForWorker();
- }
+ std::ostringstream stream;
+ stream << "DidChangeView:"
+ << " x:" << view.GetRect().x()
+ << " y:" << view.GetRect().y()
+ << " width:" << view.GetRect().width()
+ << " height:" << view.GetRect().height()
+ << "\n"
+ << " IsFullscreen:" << view.IsFullscreen()
+ << " IsVisible:" << view.IsVisible()
+ << " IsPageVisible:" << view.IsPageVisible()
+ << " GetDeviceScale:" << view.GetDeviceScale()
+ << " GetCSSScale:" << view.GetCSSScale();
+ PostMessage(stream.str());
}
- // HandleInputEvent operates on the main Pepper thread. Here we
- // illustrate copying the Pepper input event to our own custom event type.
- // Since we need to use Pepper API calls to convert it, we must do the
- // conversion on the main thread. Once we have converted it to our own
- // event type, we push that into a thread-safe queue and quickly return.
- // The worker thread can process the custom event and do whatever
- // (possibly slow) things it wants to do without making the browser
- // become unresponsive.
- // We dynamically allocate a sub-class of our custom event (Event)
- // so that the queue can contain an Event*.
virtual bool HandleInputEvent(const pp::InputEvent& event) {
- Event* event_ptr = NULL;
switch (event.GetType()) {
case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
case PP_INPUTEVENT_TYPE_IME_TEXT:
- // these cases are not handled...fall through below...
case PP_INPUTEVENT_TYPE_UNDEFINED:
+ // these cases are not handled.
break;
case PP_INPUTEVENT_TYPE_MOUSEDOWN:
case PP_INPUTEVENT_TYPE_MOUSEUP:
@@ -152,88 +160,76 @@ class InputEventInstance : public pp::Instance {
case PP_INPUTEVENT_TYPE_MOUSELEAVE:
case PP_INPUTEVENT_TYPE_CONTEXTMENU: {
pp::MouseInputEvent mouse_event(event);
- PP_InputEvent_MouseButton pp_button = mouse_event.GetButton();
- MouseEvent::MouseButton mouse_button = MouseEvent::kNone;
- switch (pp_button) {
- case PP_INPUTEVENT_MOUSEBUTTON_NONE:
- mouse_button = MouseEvent::kNone;
- break;
- case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
- mouse_button = MouseEvent::kLeft;
- break;
- case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
- mouse_button = MouseEvent::kMiddle;
- break;
- case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
- mouse_button = MouseEvent::kRight;
- break;
- }
- event_ptr =
- new MouseEvent(ConvertEventModifier(mouse_event.GetModifiers()),
- mouse_button,
- mouse_event.GetPosition().x(),
- mouse_event.GetPosition().y(),
- mouse_event.GetClickCount(),
- mouse_event.GetTimeStamp(),
- event.GetType() == PP_INPUTEVENT_TYPE_CONTEXTMENU);
- } break;
+ std::ostringstream stream;
+ stream << "Mouse event:"
+ << " modifier:" << ModifierToString(mouse_event.GetModifiers())
+ << " button:" << MouseButtonToString(mouse_event.GetButton())
+ << " x:" << mouse_event.GetPosition().x()
+ << " y:" << mouse_event.GetPosition().y()
+ << " click_count:" << mouse_event.GetClickCount()
+ << " time:" << mouse_event.GetTimeStamp()
+ << " is_context_menu: "
+ << (event.GetType() == PP_INPUTEVENT_TYPE_CONTEXTMENU);
+ PostMessage(stream.str());
+ break;
+ }
+
case PP_INPUTEVENT_TYPE_WHEEL: {
pp::WheelInputEvent wheel_event(event);
- event_ptr =
- new WheelEvent(ConvertEventModifier(wheel_event.GetModifiers()),
- wheel_event.GetDelta().x(),
- wheel_event.GetDelta().y(),
- wheel_event.GetTicks().x(),
- wheel_event.GetTicks().y(),
- wheel_event.GetScrollByPage(),
- wheel_event.GetTimeStamp());
- } break;
+ std::ostringstream stream;
+ stream << "Wheel event:"
+ << " modifier:" << ModifierToString(wheel_event.GetModifiers())
+ << " deltax:" << wheel_event.GetDelta().x()
+ << " deltay:" << wheel_event.GetDelta().y()
+ << " wheel_ticks_x:" << wheel_event.GetTicks().x()
+ << " wheel_ticks_y:" << wheel_event.GetTicks().y()
+ << " scroll_by_page: " << wheel_event.GetScrollByPage()
+ << " time:" << wheel_event.GetTimeStamp();
+ PostMessage(stream.str());
+ break;
+ }
+
case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
case PP_INPUTEVENT_TYPE_KEYDOWN:
case PP_INPUTEVENT_TYPE_KEYUP:
case PP_INPUTEVENT_TYPE_CHAR: {
pp::KeyboardInputEvent key_event(event);
- event_ptr = new KeyEvent(ConvertEventModifier(key_event.GetModifiers()),
- key_event.GetKeyCode(),
- key_event.GetTimeStamp(),
- key_event.GetCharacterText().DebugString());
- } break;
+ std::ostringstream stream;
+ stream << "Key event:"
+ << " modifier:" << ModifierToString(key_event.GetModifiers())
+ << " key_code:" << key_event.GetKeyCode()
+ << " time:" << key_event.GetTimeStamp()
+ << " text:" << key_event.GetCharacterText().DebugString();
+ PostMessage(stream.str());
+ break;
+ }
+
case PP_INPUTEVENT_TYPE_TOUCHSTART:
case PP_INPUTEVENT_TYPE_TOUCHMOVE:
case PP_INPUTEVENT_TYPE_TOUCHEND:
case PP_INPUTEVENT_TYPE_TOUCHCANCEL: {
pp::TouchInputEvent touch_event(event);
-
- TouchEvent::Kind touch_kind = TouchEvent::kNone;
- if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHSTART)
- touch_kind = TouchEvent::kStart;
- else if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHMOVE)
- touch_kind = TouchEvent::kMove;
- else if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHEND)
- touch_kind = TouchEvent::kEnd;
- else if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHCANCEL)
- touch_kind = TouchEvent::kCancel;
-
- TouchEvent* touch_event_ptr =
- new TouchEvent(ConvertEventModifier(touch_event.GetModifiers()),
- touch_kind,
- touch_event.GetTimeStamp());
- event_ptr = touch_event_ptr;
+ std::ostringstream stream;
+ stream << "Touch event:" << TouchKindToString(event.GetType())
+ << " modifier:" << ModifierToString(touch_event.GetModifiers());
uint32_t touch_count =
touch_event.GetTouchCount(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES);
for (uint32_t i = 0; i < touch_count; ++i) {
pp::TouchPoint point =
touch_event.GetTouchByIndex(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES, i);
- touch_event_ptr->AddTouch(point.id(),
- point.position().x(),
- point.position().y(),
- point.radii().x(),
- point.radii().y(),
- point.rotation_angle(),
- point.pressure());
+ stream << " x[" << point.id() << "]:" << point.position().x()
+ << " y[" << point.id() << "]:" << point.position().y()
+ << " radii_x[" << point.id() << "]:" << point.radii().x()
+ << " radii_y[" << point.id() << "]:" << point.radii().y()
+ << " angle[" << point.id() << "]:" << point.rotation_angle()
+ << " pressure[" << point.id() << "]:" << point.pressure();
}
- } break;
+ stream << " time:" << touch_event.GetTimeStamp();
+ PostMessage(stream.str());
+ break;
+ }
+
default: {
// For any unhandled events, send a message to the browser
// so that the user is aware of these and can investigate.
@@ -242,86 +238,9 @@ class InputEventInstance : public pp::Instance {
PostMessage(oss.str());
} break;
}
- event_queue_.Push(event_ptr);
- return true;
- }
- // Return an event from the thread-safe queue, waiting for a new event
- // to occur if the queue is empty. Set |was_queue_cancelled| to indicate
- // whether the queue was cancelled. If it was cancelled, then the
- // Event* will be NULL.
- const Event* GetEventFromQueue(bool* was_queue_cancelled) {
- Event* event = NULL;
- QueueGetResult result = event_queue_.GetItem(&event, kWait);
- if (result == kQueueWasCancelled) {
- *was_queue_cancelled = true;
- return NULL;
- }
- *was_queue_cancelled = false;
- return event;
- }
-
- // This method is called from the worker thread using CallOnMainThread.
- // It is not static, and allows PostMessage to be called.
- void* PostStringToBrowser(int32_t result, std::string data_to_send) {
- PostMessage(pp::Var(data_to_send));
- return 0;
- }
-
- // |ProcessEventOnWorkerThread| is a static method that is run
- // by a thread. It pulls events from the queue, converts
- // them to a string, and calls CallOnMainThread so that
- // PostStringToBrowser will be called, which will call PostMessage
- // to send the converted event back to the browser.
- static void* ProcessEventOnWorkerThread(void* param) {
- InputEventInstance* event_instance =
- static_cast<InputEventInstance*>(param);
- while (1) {
- // Grab a generic Event* so that down below we can call
- // event->ToString(), which will use the correct virtual method
- // to convert the event to a string. This 'conversion' is
- // the 'work' being done on the worker thread. In an application
- // the work might involve changing application state based on
- // the event that was processed.
- bool queue_cancelled;
- const Event* event = event_instance->GetEventFromQueue(&queue_cancelled);
- if (queue_cancelled) {
- printf("Queue was cancelled, worker thread exiting\n");
- pthread_exit(NULL);
- }
- std::string event_string = event->ToString();
- delete event;
- // Need to invoke callback on main thread.
- pp::Module::Get()->core()->CallOnMainThread(
- 0,
- event_instance->callback_factory().NewCallback(
- &InputEventInstance::PostStringToBrowser, event_string));
- } // end of while loop.
- return 0;
- }
-
- // Return the callback factory.
- // Allows the static method (ProcessEventOnWorkerThread) to use
- // the |event_instance| pointer to get the factory.
- pp::CompletionCallbackFactory<InputEventInstance>& callback_factory() {
- return callback_factory_;
- }
-
- private:
- // Cancels the queue (which will cause the thread to exit).
- // Wait for the thread. Set |event_thread_| to NULL so we only
- // execute the body once.
- void CancelQueueAndWaitForWorker() {
- if (event_thread_) {
- event_queue_.CancelQueue();
- pthread_join(*event_thread_, NULL);
- delete event_thread_;
- event_thread_ = NULL;
- }
+ return true;
}
- pthread_t* event_thread_;
- LockingQueue<Event*> event_queue_;
- pp::CompletionCallbackFactory<InputEventInstance> callback_factory_;
};
class InputEventModule : public pp::Module {
diff --git a/native_client_sdk/src/examples/api/input_event/shared_queue.h b/native_client_sdk/src/examples/api/input_event/shared_queue.h
deleted file mode 100644
index 22a75bc..0000000
--- a/native_client_sdk/src/examples/api/input_event/shared_queue.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SHARED_QUEUE_H
-#define SHARED_QUEUE_H
-
-#include <pthread.h>
-#include <cassert>
-#include <deque>
-
-// This file provides a queue that uses a mutex and condition variable so that
-// one thread can put pointers into the queue and another thread can pull items
-// out of the queue.
-
-// Specifies whether we want to wait for the queue.
-enum QueueWaitingFlag {
- kWait = 0,
- kDontWait
-};
-
-// Indicates if we got an item, did not wait, or if the queue was cancelled.
-enum QueueGetResult {
- kReturnedItem = 0,
- kDidNotWait = 1,
- kQueueWasCancelled
-};
-
-// A simple scoped mutex lock.
-// For most cases, pp::AutoLock in "ppapi/utility/threading/lock.h" can be
-// used; LockingQueue needs to use the pthread_mutex_t directly in
-// pthread_cond_wait so we reimplement a scoped lock here.
-class ScopedLock {
- public:
- explicit ScopedLock(pthread_mutex_t* mutex) : mutex_(mutex) {
- const int kPthreadMutexSuccess = 0;
- if (pthread_mutex_lock(mutex_) != kPthreadMutexSuccess) {
- mutex_ = NULL;
- }
- }
- ~ScopedLock() {
- if (mutex_ != NULL) {
- pthread_mutex_unlock(mutex_);
- }
- }
-
- private:
- pthread_mutex_t* mutex_; // Weak reference, passed in to constructor.
-
- // Disable copy and assign.
- ScopedLock& operator=(const ScopedLock&);
- ScopedLock(const ScopedLock&);
-};
-
-
-#ifdef __GNUC__
-#define UNUSED __attribute__ ((unused))
-#else
-#define UNUSED
-#endif
-
-// LockingQueue contains a collection of <T>, such as a collection of
-// objects or pointers. The Push() method is used to add items to the
-// queue in a thread-safe manner. The GetItem() is used to retrieve
-// items from the queue in a thread-safe manner.
-template <class T> class LockingQueue {
- public:
- LockingQueue() : quit_(false) {
- int result UNUSED;
- result = pthread_mutex_init(&queue_mutex_, NULL);
- assert(result == 0);
- result = pthread_cond_init(&queue_condition_var_, NULL);
- assert(result == 0);
- }
- ~LockingQueue() { pthread_mutex_destroy(&queue_mutex_); }
-
- // The producer (who instantiates the queue) calls this to tell the
- // consumer that the queue is no longer being used.
- void CancelQueue() {
- ScopedLock scoped_mutex(&queue_mutex_);
- quit_ = true;
- // Signal the condition var so that if a thread is waiting in
- // GetItem the thread will wake up and see that the queue has
- // been cancelled.
- pthread_cond_signal(&queue_condition_var_);
- }
-
- // The consumer calls this to see if the queue has been cancelled by
- // the producer. If so, the thread should not call GetItem and may
- // need to terminate -- i.e. in a case where the producer created
- // the consumer thread.
- bool IsCancelled() {
- ScopedLock scoped_mutex(&queue_mutex_);
- return quit_;
- }
-
- // Grabs the mutex and pushes a new item to the end of the queue if the
- // queue is not full. Signals the condition variable so that a thread
- // that is waiting will wake up and grab the item.
- void Push(const T& item) {
- ScopedLock scoped_mutex(&queue_mutex_);
- the_queue_.push_back(item);
- pthread_cond_signal(&queue_condition_var_);
- }
-
- // Tries to pop the front element from the queue; returns an enum:
- // kReturnedItem if an item is returned in |item_ptr|,
- // kDidNotWait if |wait| was kDontWait and the queue was empty,
- // kQueueWasCancelled if the producer called CancelQueue().
- // If |wait| is kWait, GetItem will wait to return until the queue
- // contains an item (unless the queue is cancelled).
- QueueGetResult GetItem(T* item_ptr, QueueWaitingFlag wait) {
- ScopedLock scoped_mutex(&queue_mutex_);
- // Use a while loop to get an item. If the user does not want to wait,
- // we will exit from the loop anyway, unlocking the mutex.
- // If the user does want to wait, we will wait for pthread_cond_wait,
- // and the while loop will check is_empty_no_locking() one more
- // time so that a spurious wake-up of pthread_cond_wait is handled.
- // If |quit_| has been set, break out of the loop.
- while (!quit_ && is_empty_no_locking()) {
- // If user doesn't want to wait, return...
- if (kDontWait == wait) {
- return kDidNotWait;
- }
- // Wait for signal to occur.
- pthread_cond_wait(&queue_condition_var_, &queue_mutex_);
- }
- // Check to see if quit_ woke us up
- if (quit_) {
- return kQueueWasCancelled;
- }
-
- // At this point, the queue was either not empty or, if it was empty,
- // we called pthread_cond_wait (which released the mutex, waited for the
- // signal to occur, and then atomically reacquired the mutex).
- // Thus, if we are here, the queue cannot be empty because we either
- // had the mutex and verified it was not empty, or we waited for the
- // producer to put an item in and signal a single thread (us).
- T& item = the_queue_.front();
- *item_ptr = item;
- the_queue_.pop_front();
- return kReturnedItem;
- }
-
- private:
- std::deque<T> the_queue_;
- bool quit_;
- pthread_mutex_t queue_mutex_;
- pthread_cond_t queue_condition_var_;
-
- // This is used by methods that already have the lock.
- bool is_empty_no_locking() const { return the_queue_.empty(); }
-};
-
-#endif // SHARED_QUEUE_H