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#ifndef REMOTING_CLIENT_PLUGIN_PEPPER_INPUT_HANDLER_H_
6#define REMOTING_CLIENT_PLUGIN_PEPPER_INPUT_HANDLER_H_
7
8#include "base/compiler_specific.h"
9#include "base/memory/scoped_ptr.h"
10#include "ppapi/cpp/mouse_lock.h"
11#include "ppapi/cpp/point.h"
12#include "ppapi/utility/completion_callback_factory.h"
13#include "remoting/protocol/input_stub.h"
14
15namespace pp {
16class ImageData;
17class InputEvent;
18class Instance;
19}  // namespace pp
20
21namespace remoting {
22
23namespace protocol {
24class InputStub;
25} // namespace protocol
26
27class PepperInputHandler : public pp::MouseLock {
28 public:
29  // |instance| must outlive |this|.
30  explicit PepperInputHandler(pp::Instance* instance);
31  virtual ~PepperInputHandler();
32
33  void set_input_stub(protocol::InputStub* input_stub) {
34    input_stub_ = input_stub;
35  }
36
37  bool HandleInputEvent(const pp::InputEvent& event);
38
39  // Enables locking the mouse when the host sets a completely transparent mouse
40  // cursor.
41  void AllowMouseLock();
42
43  // Called when the plugin receives or loses focus.
44  void DidChangeFocus(bool has_focus);
45
46  // Sets the mouse cursor image. Passing NULL image will lock the mouse if
47  // mouse lock is enabled.
48  void SetMouseCursor(scoped_ptr<pp::ImageData> image,
49                      const pp::Point& hotspot);
50
51  // Enable or disable sending mouse input when the plugin does not have input
52  // focus.
53  void set_send_mouse_input_when_unfocused(bool send) {
54    send_mouse_input_when_unfocused_ = send;
55  }
56
57 private:
58  enum MouseLockState {
59    MouseLockDisallowed,
60    MouseLockOff,
61    MouseLockRequestPending,
62    MouseLockOn,
63    MouseLockCancelling
64  };
65
66  // pp::MouseLock interface.
67  virtual void MouseLockLost() OVERRIDE;
68
69  // Requests the browser to lock the mouse and hides the cursor.
70  void RequestMouseLock();
71
72  // Requests the browser to cancel mouse lock and restores the cursor once
73  // the lock is gone.
74  void CancelMouseLock();
75
76  // Applies |cursor_image_| as the custom pointer or uses the standard arrow
77  // pointer if |cursor_image_| is not available.
78  void UpdateMouseCursor();
79
80  // Handles completion of the mouse lock request issued by RequestMouseLock().
81  void OnMouseLocked(int error);
82
83  pp::Instance* instance_;
84  protocol::InputStub* input_stub_;
85
86  pp::CompletionCallbackFactory<PepperInputHandler> callback_factory_;
87
88  // Custom cursor image sent by the host. |cursor_image_| is set to NULL when
89  // the cursor image is completely transparent. This can be interpreted as
90  // a mouse lock request if enabled by the webapp.
91  scoped_ptr<pp::ImageData> cursor_image_;
92
93  // Hot spot for |cursor_image_|.
94  pp::Point cursor_hotspot_;
95
96  // True if the plugin has focus.
97  bool has_focus_;
98
99  // True if the plugin should respond to mouse input even if it does not have
100  // keyboard focus.
101  bool send_mouse_input_when_unfocused_;
102
103  MouseLockState mouse_lock_state_;
104
105  // Accumulated sub-pixel and sub-tick deltas from wheel events.
106  float wheel_delta_x_;
107  float wheel_delta_y_;
108  float wheel_ticks_x_;
109  float wheel_ticks_y_;
110
111  DISALLOW_COPY_AND_ASSIGN(PepperInputHandler);
112};
113
114}  // namespace remoting
115
116#endif  // REMOTING_CLIENT_PLUGIN_PEPPER_INPUT_HANDLER_H_
117