Home | History | Annotate | Download | only in input_event
      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.
      4 
      5 // C headers
      6 #include <stdio.h>
      7 
      8 // C++ headers
      9 #include <sstream>
     10 #include <string>
     11 
     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"
     20 
     21 #ifdef PostMessage
     22 #undef PostMessage
     23 #endif
     24 
     25 namespace {
     26 
     27 std::string ModifierToString(uint32_t modifier) {
     28   std::string s;
     29   if (modifier & PP_INPUTEVENT_MODIFIER_SHIFTKEY) {
     30     s += "shift ";
     31   }
     32   if (modifier & PP_INPUTEVENT_MODIFIER_CONTROLKEY) {
     33     s += "ctrl ";
     34   }
     35   if (modifier & PP_INPUTEVENT_MODIFIER_ALTKEY) {
     36     s += "alt ";
     37   }
     38   if (modifier & PP_INPUTEVENT_MODIFIER_METAKEY) {
     39     s += "meta ";
     40   }
     41   if (modifier & PP_INPUTEVENT_MODIFIER_ISKEYPAD) {
     42     s += "keypad ";
     43   }
     44   if (modifier & PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) {
     45     s += "autorepeat ";
     46   }
     47   if (modifier & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
     48     s += "left-button-down ";
     49   }
     50   if (modifier & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) {
     51     s += "middle-button-down ";
     52   }
     53   if (modifier & PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) {
     54     s += "right-button-down ";
     55   }
     56   if (modifier & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) {
     57     s += "caps-lock ";
     58   }
     59   if (modifier & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) {
     60     s += "num-lock ";
     61   }
     62   return s;
     63 }
     64 
     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();
     79   }
     80 }
     81 
     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();
     96   }
     97 }
     98 
     99 }  // namespace
    100 
    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);
    108   }
    109 
    110   bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
    111     return true;
    112   }
    113 
    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());
    124   }
    125 
    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());
    141   }
    142 
    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;
    171       }
    172 
    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;
    186       }
    187 
    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;
    201       }
    202 
    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());
    211 
    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();
    223         }
    224         stream << " time:" << touch_event.GetTimeStamp();
    225         PostMessage(stream.str());
    226         break;
    227       }
    228 
    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;
    236     }
    237 
    238     return true;
    239   }
    240 };
    241 
    242 class InputEventModule : public pp::Module {
    243  public:
    244   InputEventModule() : pp::Module() {}
    245   virtual ~InputEventModule() {}
    246 
    247   virtual pp::Instance* CreateInstance(PP_Instance instance) {
    248     return new InputEventInstance(instance);
    249   }
    250 };
    251 
    252 namespace pp {
    253 Module* CreateModule() { return new InputEventModule(); }
    254 }
    255