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#include <algorithm>
6
7#include "ppapi/cpp/graphics_2d.h"
8#include "ppapi/cpp/image_data.h"
9#include "ppapi/cpp/input_event.h"
10#include "ppapi/cpp/instance.h"
11#include "ppapi/cpp/module.h"
12#include "ppapi/cpp/mouse_cursor.h"
13#include "ppapi/cpp/view.h"
14
15void FillRect(pp::ImageData* image, int left, int top, int width, int height,
16              uint32_t color) {
17  for (int y = std::max(0, top);
18       y < std::min(image->size().height() - 1, top + height);
19       y++) {
20    for (int x = std::max(0, left);
21         x < std::min(image->size().width() - 1, left + width);
22         x++)
23      *image->GetAddr32(pp::Point(x, y)) = color;
24  }
25}
26
27class MyInstance : public pp::Instance {
28 public:
29  MyInstance(PP_Instance instance)
30      : pp::Instance(instance), width_(0), height_(0) {
31    RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
32  }
33
34  virtual ~MyInstance() {
35  }
36
37  virtual void DidChangeView(const pp::View& view) {
38    width_ = view.GetRect().width();
39    height_ = view.GetRect().height();
40  }
41
42  virtual bool HandleInputEvent(const pp::InputEvent& event) {
43    switch (event.GetType()) {
44      case PP_INPUTEVENT_TYPE_MOUSEDOWN:
45        return true;
46      case PP_INPUTEVENT_TYPE_MOUSEMOVE:
47        HandleMove(pp::MouseInputEvent(event));
48        return true;
49      case PP_INPUTEVENT_TYPE_KEYDOWN:
50        return true;
51      default:
52        return false;
53    }
54  }
55
56  void HandleMove(const pp::MouseInputEvent& event) {
57    pp::Point point = event.GetPosition();
58    int segments = 3;
59    if (point.y() < height_ / segments) {
60      // Top part gets custom cursor of wait.
61      pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_WAIT);
62    } else if (point.y() < (height_ / segments) * 2) {
63      // Next part gets custom image cursor.
64      pp::ImageData cursor(this, pp::ImageData::GetNativeImageDataFormat(),
65                           pp::Size(32, 32), true);
66      // Note that in real life you will need to handle the case where the
67      // native format is different.
68      FillRect(&cursor, 0, 0, 32, 32, 0x80000080);
69      pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_CUSTOM, cursor,
70                                 pp::Point(16, 16));
71    } else {
72      // Next part gets no cursor.
73      pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_NONE);
74    }
75  }
76
77
78 private:
79  int width_;
80  int height_;
81};
82
83class MyModule : public pp::Module {
84 public:
85  MyModule() : pp::Module() {}
86  virtual ~MyModule() {}
87
88  virtual pp::Instance* CreateInstance(PP_Instance instance) {
89    return new MyInstance(instance);
90  }
91};
92
93namespace pp {
94
95// Factory function for your specialization of the Module object.
96Module* CreateModule() {
97  return new MyModule();
98}
99
100}  // namespace pp
101