Input Events in C++
This topic describes the "Input Events in C++" sample application implementation.
Related Info
Samples
Due to NaCl deprecation by the Chromium project, Tizen TV will continue its support for NaCl only until 2021-year products. Meanwhile, Tizen TV will start focusing on high-performance, cross-browser WebAssembly from 2020-year products.
This tutorial describes how to implement a simple input-handling Native Client (NaCl) application in C++. The NaCl module waits for input events in the space inside the blue rectangle. When it receives mouse or keyboard events, they are interpreted and logged in the "NaCl messages:" field.
To allow the NaCl plugin to capture keyboard input events, the user must focus the plugin area by clicking it. Therefore, the NaCl embed
object must have non-zero dimensions and be visible to the user.
Mouse and mouse wheel events can be handled whenever the mouse pointer hovers over the NaCl plugin object, even when the plugin does not have focus.
For information on how to access the sample application cheat sheet and run the application, see Sample-based Tutorials.
To implement input event handling:
-
In the main instance constructor, enable the events you want to capture:
- The
RequestInputEvents()
function enables the mouse and mouse wheel input events. - The
RequestFilteringInputEvents()
function enables keyboard input events.
- The
-
To add a prefix to the logged messages, initialize the static
Logger
class, which is a wrapper for thePostMessage()
function. TheLogger
class is implemented in the "logger.cc" file.explicit InputEventsInstance(PP_Instance instance) : pp::Instance(instance) { RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL); RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); Logger::InitializeInstance(this); }
-
To react to specific input events, overload the
HandleInputEvent()
function.
TheHandleInputEvent()
function takes a const reference topp::InputEvent
as a parameter. To extract the event type, use theGetType()
function on it. This returns an enumeration value that can be used as a parameter for the switch expression. You can handle as many input event types as you want.
In each case statement, thepp::InputEvent
object is casted to the class that corresponds to its type. For example, for thePP_INPUTEVENT_TYPE_KEYDOWN
event, thepp::InputEvent
object is casted topp::KeyboardInputEvent
. This allows you to call event-specific functions that can provide additional information, such as the mouse position or the clicked key code.
For each event, interpret the input data, create a reply message describing the event, and send the message to the browser using theLogger
class:virtual bool HandleInputEvent(const pp::InputEvent& event) { switch (event.GetType()) { case PP_INPUTEVENT_TYPE_UNDEFINED: break; // Mouse button pressed while hovering over the embed element case PP_INPUTEVENT_TYPE_MOUSEDOWN: { pp::MouseInputEvent mouse_event(event); switch (mouse_event.GetButton()) { case PP_INPUTEVENT_MOUSEBUTTON_LEFT: Logger::Log("Left mouse button down"); break; case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE: Logger::Log("Middle mouse button down"); break; case PP_INPUTEVENT_MOUSEBUTTON_RIGHT: Logger::Log("Right mouse button down"); break; default: break; } } break; // Mouse button released while embed element has focus case PP_INPUTEVENT_TYPE_MOUSEUP: { pp::MouseInputEvent mouse_event(event); switch (mouse_event.GetButton()) { case PP_INPUTEVENT_MOUSEBUTTON_LEFT: Logger::Log("Left mouse button up"); break; case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE: Logger::Log("Middle mouse button up"); break; case PP_INPUTEVENT_MOUSEBUTTON_RIGHT: Logger::Log("Right mouse button up"); break; default: break; } } break; // Left mouse button is pressed while hovering over the embed element, or while the embed element has focus case PP_INPUTEVENT_TYPE_MOUSEMOVE: { pp::MouseInputEvent mouse_event(event); pp::Point pos = mouse_event.GetPosition(); Logger::Log("Mouse moved to position: (%d, %d)", pos.x(), pos.y()); } break; case PP_INPUTEVENT_TYPE_MOUSEENTER: break; case PP_INPUTEVENT_TYPE_MOUSELEAVE: break; case PP_INPUTEVENT_TYPE_CONTEXTMENU: break; // Mouse wheel rotated while hovering over the embed element case PP_INPUTEVENT_TYPE_WHEEL: { pp::WheelInputEvent wheel_event(event); pp::FloatPoint delta = wheel_event.GetDelta(); Logger::Log("Wheel move delta: (%f, %f)", delta.x(), delta.y()); } break; case PP_INPUTEVENT_TYPE_RAWKEYDOWN: break; // Keyboard key is pressed while embed element has focus case PP_INPUTEVENT_TYPE_KEYDOWN: { pp::KeyboardInputEvent key_event(event); Logger::Log("Keyboard stroke code: %u", key_event.GetKeyCode()); } break; case PP_INPUTEVENT_TYPE_KEYUP: break; // Keyboard key representing a printable character is pressed while embed element has focus case PP_INPUTEVENT_TYPE_CHAR: { pp::KeyboardInputEvent key_event(event); pp::Var key_name = key_event.GetCharacterText(); Logger::Log("Keyboard stroke char: \"%s\"", key_name.AsString().c_str()); } break; default: break; } return true; }
-
To show the log messages on the Web page, in the JavaScript application component, receive the NaCl messages:
function handleNaclMessage(message_event) { var message = message_event.data; if (printIfLog(message)) { return; // This was a log or error message; finish handling } }
-
Check whether the message starts with any of the predefined prefixes. If it does, append it to the "NaCl messages" HTML object on the Web page:
function printIfLog(message) { if ((typeof message == "string") && (uses_logging == true) && (startsWith(message, kLogPrefix) || startsWith(message, kErrorPrefix) || startsWith(message, kDebugPrefix))) { logs.value += message; logs.scrollTop = logs.scrollHeight; return true; } return false; }