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 <cmath>
6
7#include "ppapi/c/ppb_fullscreen.h"
8#include "ppapi/c/ppb_input_event.h"
9#include "ppapi/cpp/completion_callback.h"
10#include "ppapi/cpp/fullscreen.h"
11#include "ppapi/cpp/graphics_2d.h"
12#include "ppapi/cpp/image_data.h"
13#include "ppapi/cpp/input_event.h"
14#include "ppapi/cpp/instance.h"
15#include "ppapi/cpp/module.h"
16#include "ppapi/cpp/mouse_lock.h"
17#include "ppapi/cpp/rect.h"
18#include "ppapi/cpp/size.h"
19#include "ppapi/cpp/var.h"
20#include "ppapi/utility/completion_callback_factory.h"
21
22#ifdef _MSC_VER
23// Allow 'this' in initializer list
24#pragma warning(disable : 4355)
25#endif
26
27class MouseLockInstance : public pp::Instance, public pp::MouseLock {
28 public:
29  explicit MouseLockInstance(PP_Instance instance)
30      : pp::Instance(instance),
31        pp::MouseLock(this),
32        mouse_locked_(false),
33        waiting_for_flush_completion_(false),
34        callback_factory_(this),
35        fullscreen_(this),
36        is_context_bound_(false),
37        was_fullscreen_(false),
38        background_scanline_(NULL) {}
39  virtual ~MouseLockInstance();
40
41  // Called by the browser when the NaCl module is loaded and all ready to go.
42  virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
43
44  // Called by the browser to handle incoming input events.
45  virtual bool HandleInputEvent(const pp::InputEvent& event);
46
47  // Called whenever the in-browser window changes size.
48  virtual void DidChangeView(const pp::View& view);
49
50  // Called by the browser when mouselock is lost.  This happens when the NaCl
51  // module exits fullscreen mode.
52  virtual void MouseLockLost();
53
54 private:
55  // Return the Cartesian distance between two points.
56  double GetDistance(int point_1_x,
57                     int point_1_y,
58                     int point_2_x,
59                     int point_2_y) {
60    return sqrt(pow(static_cast<double>(point_1_x - point_2_x), 2) +
61                pow(static_cast<double>(point_1_y - point_2_y), 2));
62  }
63
64  // Called when mouse lock has been acquired.  Used as a callback to
65  // pp::MouseLock.LockMouse().
66  void DidLockMouse(int32_t result);
67
68  // Called when the 2D context has been flushed to the browser window.  Used
69  // as a callback to pp::Graphics2D.Flush().
70  void DidFlush(int32_t result);
71
72  // Creates a new paint buffer, paints it then flush it to the 2D context.  If
73  // a flush is pending, this does nothing.
74  void Paint();
75
76  // Create a new pp::ImageData and paint the graphics that represent the mouse
77  // movement in it.  Return the new pp::ImageData.
78  pp::ImageData PaintImage(const pp::Size& size);
79
80  // Fill the image with the background color.
81  void ClearToBackground(pp::ImageData* image);
82
83  void DrawCenterSpot(pp::ImageData* image, uint32_t spot_color);
84
85  void DrawNeedle(pp::ImageData* image, uint32_t needle_color);
86
87  // Print the printf-style format to the "console" via PostMessage.
88  void Log(const char* format, ...);
89
90  pp::Size size_;
91
92  bool mouse_locked_;
93  pp::Point mouse_movement_;
94  bool waiting_for_flush_completion_;
95  pp::CompletionCallbackFactory<MouseLockInstance> callback_factory_;
96
97  pp::Fullscreen fullscreen_;
98  pp::Graphics2D device_context_;
99  bool is_context_bound_;
100  bool was_fullscreen_;
101  uint32_t* background_scanline_;
102};
103