Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: ppapi/examples/mouse_lock/mouse_lock.cc

Issue 7863003: Mouse lock implementation, including the renderer side and the Windows version of the browser side. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/renderer/render_widget.cc ('k') | ppapi/examples/mouse_lock/mouse_lock.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 #include <stdarg.h>
7 #include <stdio.h>
8
9 #include "ppapi/c/dev/ppb_console_dev.h"
10 #include "ppapi/c/ppb_input_event.h"
11 #include "ppapi/cpp/completion_callback.h"
12 #include "ppapi/cpp/dev/mouse_lock_dev.h"
13 #include "ppapi/cpp/graphics_2d.h"
14 #include "ppapi/cpp/image_data.h"
15 #include "ppapi/cpp/input_event.h"
16 #include "ppapi/cpp/instance.h"
17 #include "ppapi/cpp/logging.h"
18 #include "ppapi/cpp/module.h"
19 #include "ppapi/cpp/rect.h"
20 #include "ppapi/cpp/var.h"
21
22 class MyInstance : public pp::Instance, public pp::MouseLock_Dev {
23 public:
24 explicit MyInstance(PP_Instance instance)
25 : pp::Instance(instance),
26 pp::MouseLock_Dev(this),
27 width_(0),
28 height_(0),
29 mouse_locked_(false),
30 pending_paint_(false),
31 waiting_for_flush_completion_(false),
32 callback_factory_(this),
33 console_(NULL) {
34 }
35 virtual ~MyInstance() {}
36
37 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
38 console_ = reinterpret_cast<const PPB_Console_Dev*>(
39 pp::Module::Get()->GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE));
40 if (!console_)
41 return false;
42
43 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE |
44 PP_INPUTEVENT_CLASS_KEYBOARD);
45 return true;
46 }
47
48 virtual bool HandleInputEvent(const pp::InputEvent& event) {
49 switch (event.GetType()) {
50 case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
51 pp::MouseInputEvent mouse_event(event);
52 if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT &&
53 !mouse_locked_) {
54 LockMouse(
55 callback_factory_.NewRequiredCallback(&MyInstance::DidLockMouse));
56 } else if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_RIGHT &&
57 mouse_locked_) {
58 UnlockMouse();
59 }
60 return true;
61 }
62 case PP_INPUTEVENT_TYPE_MOUSEMOVE: {
63 pp::MouseInputEvent mouse_event(event);
64 mouse_movement_ = mouse_event.GetMovement();
65 static unsigned int i = 0;
66 Log(PP_LOGLEVEL_LOG, "[%d] movementX: %d; movementY: %d\n", i++,
67 mouse_movement_.x(), mouse_movement_.y());
68 Paint();
69 return true;
70 }
71 case PP_INPUTEVENT_TYPE_KEYDOWN: {
72 pp::KeyboardInputEvent key_event(event);
73 // Lock the mouse when the Enter key is pressed.
74 if (!mouse_locked_ && key_event.GetKeyCode() == 13) {
75 LockMouse(
76 callback_factory_.NewRequiredCallback(&MyInstance::DidLockMouse));
77 }
78 return true;
79 }
80 default:
81 return false;
82 }
83 }
84
85 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
86 if (position.size().width() == width_ &&
87 position.size().height() == height_)
88 return; // We don't care about the position, only the size.
89
90 width_ = position.size().width();
91 height_ = position.size().height();
92
93 device_context_ = pp::Graphics2D(this, pp::Size(width_, height_), false);
94 if (!BindGraphics(device_context_))
95 return;
96
97 Paint();
98 }
99
100 virtual void MouseLockLost() {
101 if (mouse_locked_) {
102 mouse_locked_ = false;
103 Paint();
104 } else {
105 PP_NOTREACHED();
106 }
107 }
108
109 private:
110 void DidLockMouse(int32_t result) {
111 mouse_locked_ = result == PP_OK;
112 mouse_movement_.set_x(0);
113 mouse_movement_.set_y(0);
114 Paint();
115 }
116
117 void DidFlush(int32_t result) {
118 waiting_for_flush_completion_ = false;
119 if (pending_paint_) {
120 pending_paint_ = false;
121 Paint();
122 }
123 }
124
125 void Paint() {
126 if (waiting_for_flush_completion_) {
127 pending_paint_ = true;
128 return;
129 }
130
131 pp::ImageData image = PaintImage(width_, height_);
132 if (!image.is_null()) {
133 device_context_.ReplaceContents(&image);
134 waiting_for_flush_completion_ = true;
135 device_context_.Flush(
136 callback_factory_.NewRequiredCallback(&MyInstance::DidFlush));
137 }
138 }
139
140 pp::ImageData PaintImage(int width, int height) {
141 pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
142 pp::Size(width, height), false);
143 if (image.is_null())
144 return image;
145
146 const static int kCenteralSpotRadius = 5;
147 const static uint32_t kBackgroundColor = 0xfff0f0f0;
148 const static uint32_t kLockedForegroundColor = 0xfff08080;
149 const static uint32_t kUnlockedForegroundColor = 0xff80f080;
150
151 int center_x = width / 2;
152 int center_y = height / 2;
153 pp::Point vertex(mouse_movement_.x() + center_x,
154 mouse_movement_.y() + center_y);
155 pp::Point anchor_1;
156 pp::Point anchor_2;
157 enum {
158 LEFT = 0,
159 RIGHT = 1,
160 UP = 2,
161 DOWN = 3
162 } direction;
163 bool draw_needle = GetDistance(mouse_movement_.x(), mouse_movement_.y(),
164 0, 0) > kCenteralSpotRadius;
165 if (draw_needle) {
166 if (abs(mouse_movement_.x()) >= abs(mouse_movement_.y())) {
167 anchor_1.set_x(center_x);
168 anchor_1.set_y(center_y - kCenteralSpotRadius);
169 anchor_2.set_x(center_x);
170 anchor_2.set_y(center_y + kCenteralSpotRadius);
171 direction = (mouse_movement_.x() < 0) ? LEFT : RIGHT;
172 if (direction == LEFT)
173 anchor_1.swap(anchor_2);
174 } else {
175 anchor_1.set_x(center_x + kCenteralSpotRadius);
176 anchor_1.set_y(center_y);
177 anchor_2.set_x(center_x - kCenteralSpotRadius);
178 anchor_2.set_y(center_y);
179 direction = (mouse_movement_.y() < 0) ? UP : DOWN;
180 if (direction == UP)
181 anchor_1.swap(anchor_2);
182 }
183 }
184 uint32_t foreground_color = mouse_locked_ ? kLockedForegroundColor :
185 kUnlockedForegroundColor;
186 for (int y = 0; y < image.size().height(); ++y) {
187 for (int x = 0; x < image.size().width(); ++x) {
188 if (GetDistance(x, y, center_x, center_y) < kCenteralSpotRadius) {
189 *image.GetAddr32(pp::Point(x, y)) = foreground_color;
190 continue;
191 }
192 if (draw_needle) {
193 bool within_bound_1 =
194 ((y - anchor_1.y()) * (vertex.x() - anchor_1.x())) >
195 ((vertex.y() - anchor_1.y()) * (x - anchor_1.x()));
196 bool within_bound_2 =
197 ((y - anchor_2.y()) * (vertex.x() - anchor_2.x())) <
198 ((vertex.y() - anchor_2.y()) * (x - anchor_2.x()));
199 bool within_bound_3 =
200 (direction == UP && y < center_y) ||
201 (direction == DOWN && y > center_y) ||
202 (direction == LEFT && x < center_x) ||
203 (direction == RIGHT && x > center_y);
204
205 if (within_bound_1 && within_bound_2 && within_bound_3) {
206 *image.GetAddr32(pp::Point(x, y)) = foreground_color;
207 continue;
208 }
209 }
210 *image.GetAddr32(pp::Point(x, y)) = kBackgroundColor;
211 }
212 }
213
214 return image;
215 }
216
217 double GetDistance(int point_1_x, int point_1_y,
218 int point_2_x, int point_2_y) {
219 return sqrt(pow(static_cast<double>(point_1_x - point_2_x), 2) +
220 pow(static_cast<double>(point_1_y - point_2_y), 2));
221 }
222
223 void Log(PP_LogLevel_Dev level, const char* format, ...) {
224 va_list args;
225 va_start(args, format);
226 char buf[512];
227 vsnprintf(buf, sizeof(buf) - 1, format, args);
228 buf[sizeof(buf) - 1] = '\0';
229 va_end(args);
230
231 pp::Var value(buf);
232 console_->Log(pp_instance(), level, value.pp_var());
233 }
234
235 int width_;
236 int height_;
237
238 bool mouse_locked_;
239 pp::Point mouse_movement_;
240
241 bool pending_paint_;
242 bool waiting_for_flush_completion_;
243
244 pp::CompletionCallbackFactory<MyInstance> callback_factory_;
245
246 const PPB_Console_Dev* console_;
247
248 pp::Graphics2D device_context_;
249 };
250
251 // This object is the global object representing this plugin library as long
252 // as it is loaded.
253 class MyModule : public pp::Module {
254 public:
255 MyModule() : pp::Module() {}
256 virtual ~MyModule() {}
257
258 // Override CreateInstance to create your customized Instance object.
259 virtual pp::Instance* CreateInstance(PP_Instance instance) {
260 return new MyInstance(instance);
261 }
262 };
263
264 namespace pp {
265
266 // Factory function for your specialization of the Module object.
267 Module* CreateModule() {
268 return new MyModule();
269 }
270
271 } // namespace pp
272
OLDNEW
« no previous file with comments | « content/renderer/render_widget.cc ('k') | ppapi/examples/mouse_lock/mouse_lock.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698