OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 #include <sstream> |
| 6 #include <utility> |
| 7 |
| 8 #include "ppapi/cpp/completion_callback.h" |
| 9 #include "ppapi/cpp/graphics_2d.h" |
| 10 #include "ppapi/cpp/image_data.h" |
| 11 #include "ppapi/cpp/input_event.h" |
| 12 #include "ppapi/cpp/instance.h" |
| 13 #include "ppapi/cpp/module.h" |
| 14 |
| 15 namespace { |
| 16 |
| 17 void DummyCompletionCallback(void*, int32_t) {} |
| 18 |
| 19 // This is a simple C++ Pepper plugin for Blink layout tests. |
| 20 // |
| 21 // Layout tests can instantiate this plugin by requesting the mime type |
| 22 // application/x-blink-test-plugin. When possible, tests should use the |
| 23 // startAfterLoadAndFinish() helper in resources/plugin.js to perform work |
| 24 // after the plugin has loaded. |
| 25 // |
| 26 // The plugin also exposes several other features for testing convenience: |
| 27 // - On first paint, the plugin posts a 'loaded' message to its owner element. |
| 28 // - On subsequent paints, the plugin posts a 'painted' message instead. |
| 29 // - Keyboard and mouse input events are logged to the console. |
| 30 class BlinkTestInstance : public pp::Instance { |
| 31 public: |
| 32 explicit BlinkTestInstance(PP_Instance instance) |
| 33 : pp::Instance(instance), first_paint_(true) {} |
| 34 ~BlinkTestInstance() override {} |
| 35 |
| 36 bool Init(uint32_t argc, const char* argn[], const char* argv[]) { |
| 37 return RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_MOUSE | |
| 38 PP_INPUTEVENT_CLASS_KEYBOARD) == PP_OK; |
| 39 } |
| 40 |
| 41 void DidChangeView(const pp::View& view) override { |
| 42 view_ = view; |
| 43 device_context_ = pp::Graphics2D(this, view_.GetRect().size(), true); |
| 44 if (!BindGraphics(device_context_)) |
| 45 return; |
| 46 |
| 47 // Since we draw a static image, we only need to make a new frame when |
| 48 // the device is initialized or the view size changes. |
| 49 Paint(); |
| 50 } |
| 51 |
| 52 void DidChangeFocus(bool has_focus) override { |
| 53 LogMessage("DidChangeFocus(", has_focus, ")"); |
| 54 } |
| 55 |
| 56 bool HandleInputEvent(const pp::InputEvent& event) override { |
| 57 switch (event.GetType()) { |
| 58 case PP_INPUTEVENT_TYPE_MOUSEDOWN: |
| 59 LogMouseEvent("Down", event); |
| 60 break; |
| 61 case PP_INPUTEVENT_TYPE_MOUSEUP: |
| 62 LogMouseEvent("Up", event); |
| 63 break; |
| 64 case PP_INPUTEVENT_TYPE_KEYDOWN: |
| 65 LogKeyboardEvent("Down", event); |
| 66 break; |
| 67 case PP_INPUTEVENT_TYPE_KEYUP: |
| 68 LogKeyboardEvent("Up", event); |
| 69 break; |
| 70 case PP_INPUTEVENT_TYPE_MOUSEMOVE: |
| 71 case PP_INPUTEVENT_TYPE_MOUSEENTER: |
| 72 case PP_INPUTEVENT_TYPE_MOUSELEAVE: |
| 73 case PP_INPUTEVENT_TYPE_RAWKEYDOWN: |
| 74 case PP_INPUTEVENT_TYPE_CHAR: |
| 75 // Just swallow these events without any logging. |
| 76 return true; |
| 77 default: |
| 78 LogMessage("Unexpected input event with type = ", event.GetType()); |
| 79 return false; |
| 80 } |
| 81 return true; |
| 82 } |
| 83 |
| 84 private: |
| 85 void Paint() { |
| 86 pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 87 view_.GetRect().size(), true); |
| 88 if (image.is_null()) |
| 89 return; |
| 90 |
| 91 // Draw blue and green checkerboard pattern to show "interesting" keyframe. |
| 92 const int kSquareSizePixels = 8; |
| 93 for (int y = 0; y < view_.GetRect().size().height(); ++y) { |
| 94 for (int x = 0; x < view_.GetRect().size().width(); ++x) { |
| 95 int x_square = x / kSquareSizePixels; |
| 96 int y_square = y / kSquareSizePixels; |
| 97 uint32_t color = ((x_square + y_square) % 2) ? 0xFF0000FF : 0xFF00FF00; |
| 98 *image.GetAddr32(pp::Point(x, y)) = color; |
| 99 } |
| 100 } |
| 101 |
| 102 device_context_.ReplaceContents(&image); |
| 103 device_context_.Flush( |
| 104 pp::CompletionCallback(&DummyCompletionCallback, nullptr)); |
| 105 |
| 106 // TODO(dcheng): In theory, this should wait for the flush to complete |
| 107 // before claiming that it's painted. In practice, this is difficult: when |
| 108 // running layout tests, a frame is typically only generated at the end of |
| 109 // the layout test. Sending the completion message in the callback results |
| 110 // in a deadlock: the test wants to wait for the plugin to paint, but the |
| 111 // plugin won't paint until the test completes. This seems to be Good |
| 112 // Enoughâ„¢ for now. |
| 113 if (first_paint_) { |
| 114 first_paint_ = false; |
| 115 PostMessage(pp::Var("loaded")); |
| 116 } else { |
| 117 PostMessage(pp::Var("painted")); |
| 118 } |
| 119 } |
| 120 |
| 121 void LogMouseEvent(const std::string& type, const pp::InputEvent& event) { |
| 122 pp::MouseInputEvent mouse_event(event); |
| 123 pp::Point mouse_position = mouse_event.GetPosition(); |
| 124 LogMessage("Mouse", type, " at (", mouse_position.x(), ",", |
| 125 mouse_position.y(), ")"); |
| 126 } |
| 127 |
| 128 void LogKeyboardEvent(const std::string& type, const pp::InputEvent& event) { |
| 129 pp::KeyboardInputEvent keyboard_event(event); |
| 130 LogMessage("Key", type, " '", keyboard_event.GetCode().AsString(), "'"); |
| 131 } |
| 132 |
| 133 // Template magic to cover the lack of base::StringPrintf. |
| 134 template <typename... Args> |
| 135 void LogMessage(const Args&... args) { |
| 136 std::ostringstream ss; |
| 137 ss << std::boolalpha; |
| 138 LogMessageHelper(&ss, args...); |
| 139 } |
| 140 |
| 141 template <typename Arg, typename... Args> |
| 142 void LogMessageHelper(std::ostringstream* os, |
| 143 const Arg& arg, |
| 144 const Args&... args) { |
| 145 *os << arg; |
| 146 LogMessageHelper(os, args...); |
| 147 } |
| 148 |
| 149 template <typename Arg> |
| 150 void LogMessageHelper(std::ostringstream* os, const Arg& arg) { |
| 151 *os << arg; |
| 152 LogToConsoleWithSource(PP_LOGLEVEL_LOG, pp::Var("Blink Test Plugin"), |
| 153 pp::Var(os->str())); |
| 154 } |
| 155 |
| 156 bool first_paint_; |
| 157 pp::View view_; |
| 158 pp::Graphics2D device_context_; |
| 159 }; |
| 160 |
| 161 class BlinkTestModule : public pp::Module { |
| 162 public: |
| 163 BlinkTestModule() {} |
| 164 virtual ~BlinkTestModule() {} |
| 165 |
| 166 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
| 167 return new BlinkTestInstance(instance); |
| 168 } |
| 169 }; |
| 170 |
| 171 } // namespace |
| 172 |
| 173 namespace pp { |
| 174 |
| 175 Module* CreateModule() { |
| 176 return new BlinkTestModule(); |
| 177 } |
| 178 |
| 179 } // namespace pp |
OLD | NEW |