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

Side by Side Diff: ppapi/example/example.cc

Issue 10697022: Delete the PPAPI example plugin. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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 | « ppapi/example/Info.plist ('k') | ppapi/example/example.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) 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 <math.h>
6 #include <stdio.h> // FIXME(brettw) erase me.
7 #ifndef _WIN32
8 #include <sys/time.h>
9 #else
10 #include <windows.h>
11 #endif
12 #include <time.h>
13
14 #include <algorithm>
15
16 #include "ppapi/c/dev/ppb_console_dev.h"
17 #include "ppapi/c/dev/ppb_cursor_control_dev.h"
18 #include "ppapi/c/dev/ppp_printing_dev.h"
19 #include "ppapi/c/pp_errors.h"
20 #include "ppapi/c/pp_rect.h"
21 #include "ppapi/cpp/completion_callback.h"
22 #include "ppapi/cpp/dev/memory_dev.h"
23 #include "ppapi/cpp/dev/scriptable_object_deprecated.h"
24 #include "ppapi/cpp/graphics_2d.h"
25 #include "ppapi/cpp/image_data.h"
26 #include "ppapi/cpp/input_event.h"
27 #include "ppapi/cpp/private/instance_private.h"
28 #include "ppapi/cpp/module.h"
29 #include "ppapi/cpp/private/var_private.h"
30 #include "ppapi/cpp/rect.h"
31 #include "ppapi/cpp/url_loader.h"
32 #include "ppapi/cpp/url_request_info.h"
33 #include "ppapi/cpp/var.h"
34 #include "ppapi/utility/completion_callback_factory.h"
35
36 static const int kStepsPerCircle = 800;
37
38 void FlushCallback(void* data, int32_t result);
39
40 void FillRect(pp::ImageData* image, int left, int top, int width, int height,
41 uint32_t color) {
42 for (int y = std::max(0, top);
43 y < std::min(image->size().height() - 1, top + height);
44 y++) {
45 for (int x = std::max(0, left);
46 x < std::min(image->size().width() - 1, left + width);
47 x++)
48 *image->GetAddr32(pp::Point(x, y)) = color;
49 }
50 }
51
52 class MyScriptableObject : public pp::deprecated::ScriptableObject {
53 public:
54 explicit MyScriptableObject(pp::InstancePrivate* instance)
55 : instance_(instance) {}
56
57 virtual bool HasMethod(const pp::Var& method, pp::Var* exception) {
58 return method.AsString() == "toString";
59 }
60
61 virtual bool HasProperty(const pp::Var& name, pp::Var* exception) {
62 if (name.is_string()) {
63 if (name.AsString() == "blah") {
64 return true;
65 } else if (name.AsString() == "removePluginWhenHasPropertyCalled") {
66 pp::Var script("var plugin = document.getElementById('plugin');"
67 "plugin.parentElement.removeChild(plugin);");
68 instance_->ExecuteScript(script);
69 }
70 }
71 return false;
72 }
73
74 virtual pp::Var GetProperty(const pp::Var& name, pp::Var* exception) {
75 if (name.is_string() && name.AsString() == "blah")
76 return pp::VarPrivate(instance_, new MyScriptableObject(instance_));
77 return pp::Var();
78 }
79
80 virtual void GetAllPropertyNames(std::vector<pp::Var>* names,
81 pp::Var* exception) {
82 names->push_back("blah");
83 }
84
85 virtual pp::Var Call(const pp::Var& method,
86 const std::vector<pp::Var>& args,
87 pp::Var* exception) {
88 if (method.AsString() == "toString")
89 return pp::Var("hello world");
90 return pp::Var();
91 }
92
93 private:
94 pp::InstancePrivate* instance_;
95 };
96
97 class MyFetcherClient {
98 public:
99 virtual void DidFetch(bool success, const std::string& data) = 0;
100 };
101
102 class MyFetcher {
103 public:
104 MyFetcher() : client_(NULL) {
105 callback_factory_.Initialize(this);
106 }
107
108 void Start(pp::Instance* instance,
109 const pp::Var& url,
110 MyFetcherClient* client) {
111 pp::URLRequestInfo request;
112 request.SetURL(url);
113 request.SetMethod("GET");
114
115 loader_ = pp::URLLoader(pp::InstanceHandle(instance));
116 client_ = client;
117
118 pp::CompletionCallback callback =
119 callback_factory_.NewOptionalCallback(&MyFetcher::DidOpen);
120 int rv = loader_.Open(request, callback);
121 if (rv != PP_OK_COMPLETIONPENDING)
122 callback.Run(rv);
123 }
124
125 void StartWithOpenedLoader(const pp::URLLoader& loader,
126 MyFetcherClient* client) {
127 loader_ = loader;
128 client_ = client;
129
130 ReadMore();
131 }
132
133 private:
134 void ReadMore() {
135 pp::CompletionCallback callback =
136 callback_factory_.NewOptionalCallback(&MyFetcher::DidRead);
137 int rv = loader_.ReadResponseBody(buf_, sizeof(buf_), callback);
138 if (rv != PP_OK_COMPLETIONPENDING)
139 callback.Run(rv);
140 }
141
142 void DidOpen(int32_t result) {
143 if (result == PP_OK) {
144 ReadMore();
145 } else {
146 DidFinish(result);
147 }
148 }
149
150 void DidRead(int32_t result) {
151 if (result > 0) {
152 data_.append(buf_, result);
153 ReadMore();
154 } else {
155 DidFinish(result);
156 }
157 }
158
159 void DidFinish(int32_t result) {
160 if (client_)
161 client_->DidFetch(result == PP_OK, data_);
162 }
163
164 pp::CompletionCallbackFactory<MyFetcher> callback_factory_;
165 pp::URLLoader loader_;
166 MyFetcherClient* client_;
167 char buf_[4096];
168 std::string data_;
169 };
170
171 class MyInstance : public pp::InstancePrivate, public MyFetcherClient {
172 public:
173 MyInstance(PP_Instance instance)
174 : pp::InstancePrivate(instance),
175 time_at_last_check_(0.0),
176 fetcher_(NULL),
177 width_(0),
178 height_(0),
179 animation_counter_(0),
180 print_settings_valid_(false),
181 showing_custom_cursor_(false) {
182 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
183 }
184
185 virtual ~MyInstance() {
186 if (fetcher_) {
187 delete fetcher_;
188 fetcher_ = NULL;
189 }
190 }
191
192 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
193 return true;
194 }
195
196 void Log(PP_LogLevel_Dev level, const pp::Var& value) {
197 const PPB_Console_Dev* console = reinterpret_cast<const PPB_Console_Dev*>(
198 pp::Module::Get()->GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE));
199 if (!console)
200 return;
201 console->Log(pp_instance(), level, value.pp_var());
202 }
203
204 virtual bool HandleDocumentLoad(const pp::URLLoader& loader) {
205 fetcher_ = new MyFetcher();
206 fetcher_->StartWithOpenedLoader(loader, this);
207 return true;
208 }
209
210 virtual bool HandleInputEvent(const pp::InputEvent& event) {
211 switch (event.GetType()) {
212 case PP_INPUTEVENT_TYPE_MOUSEDOWN:
213 SayHello();
214 ToggleCursor();
215 return true;
216 case PP_INPUTEVENT_TYPE_MOUSEMOVE:
217 return true;
218 case PP_INPUTEVENT_TYPE_KEYDOWN:
219 return true;
220 default:
221 return false;
222 }
223 }
224
225 virtual pp::Var GetInstanceObject() {
226 return pp::VarPrivate(this, new MyScriptableObject(this));
227 }
228
229 pp::ImageData PaintImage(int width, int height) {
230 pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
231 pp::Size(width, height), false);
232 if (image.is_null()) {
233 printf("Couldn't allocate the image data: %d, %d\n", width, height);
234 return image;
235 }
236
237 // Fill with semitransparent gradient.
238 for (int y = 0; y < image.size().height(); y++) {
239 char* row = &static_cast<char*>(image.data())[y * image.stride()];
240 for (int x = 0; x < image.size().width(); x++) {
241 row[x * 4 + 0] = y;
242 row[x * 4 + 1] = y;
243 row[x * 4 + 2] = 0;
244 row[x * 4 + 3] = y;
245 }
246 }
247
248 // Draw the orbiting box.
249 float radians = static_cast<float>(animation_counter_) / kStepsPerCircle *
250 2 * 3.14159265358979F;
251
252 float radius = static_cast<float>(std::min(width, height)) / 2.0f - 3.0f;
253 int x = static_cast<int>(cos(radians) * radius + radius + 2);
254 int y = static_cast<int>(sin(radians) * radius + radius + 2);
255
256 const uint32_t box_bgra = 0x80000000; // Alpha 50%.
257 FillRect(&image, x - 3, y - 3, 7, 7, box_bgra);
258 return image;
259 }
260
261 void Paint() {
262 pp::ImageData image = PaintImage(width_, height_);
263 if (!image.is_null()) {
264 device_context_.ReplaceContents(&image);
265 device_context_.Flush(pp::CompletionCallback(&FlushCallback, this));
266 } else {
267 printf("NullImage: %d, %d\n", width_, height_);
268 }
269 }
270
271 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
272 Log(PP_LOGLEVEL_LOG, "DidChangeView");
273 if (position.size().width() == width_ &&
274 position.size().height() == height_)
275 return; // We don't care about the position, only the size.
276
277 width_ = position.size().width();
278 height_ = position.size().height();
279 printf("DidChangeView relevant change: width=%d height:%d\n",
280 width_, height_);
281
282 device_context_ = pp::Graphics2D(this, pp::Size(width_, height_), false);
283 if (!BindGraphics(device_context_)) {
284 printf("Couldn't bind the device context\n");
285 return;
286 }
287
288 Paint();
289 }
290
291 #if defined(_WIN32)
292 struct timeval {
293 long tv_sec;
294 long tv_usec;
295 };
296
297 struct timezone {
298 long x;
299 long y;
300 };
301
302 #define EPOCHFILETIME (116444736000000000i64)
303
304 int gettimeofday(struct timeval *tv, struct timezone*) {
305 FILETIME ft;
306 ::GetSystemTimeAsFileTime(&ft);
307 LARGE_INTEGER li = {ft.dwLowDateTime, ft.dwHighDateTime};
308 __int64 t = li.QuadPart - EPOCHFILETIME;
309 tv->tv_sec = static_cast<long>(t / 10000000);
310 tv->tv_usec = static_cast<long>(t % 10000000);
311 return 0;
312 }
313 #endif // if defined(_WIN32)
314
315 void UpdateFps() {
316 pp::VarPrivate window = GetWindowObject();
317 if (window.is_undefined())
318 return;
319 pp::VarPrivate doc = window.GetProperty("document");
320 pp::VarPrivate fps = doc.Call("getElementById", "fps");
321
322 struct timeval tv;
323 struct timezone tz = {0, 0};
324 gettimeofday(&tv, &tz);
325
326 double time_now = tv.tv_sec + tv.tv_usec / 1000000.0;
327
328 if (animation_counter_ > 0) {
329 char fps_text[64];
330 sprintf(fps_text, "%g fps",
331 kStepsPerCircle / (time_now - time_at_last_check_));
332 fps.SetProperty("innerHTML", fps_text);
333 }
334
335 time_at_last_check_ = time_now;
336 }
337
338 // Print interfaces.
339 // TODO(mball,dmichael) Replace this with the PPP_PRINTING_DEV_USE_0_4 version
340 virtual PP_PrintOutputFormat_Dev* QuerySupportedPrintOutputFormats(
341 uint32_t* format_count) {
342 pp::Memory_Dev memory;
343 PP_PrintOutputFormat_Dev* format =
344 static_cast<PP_PrintOutputFormat_Dev*>(
345 memory.MemAlloc(sizeof(PP_PrintOutputFormat_Dev)));
346 *format = PP_PRINTOUTPUTFORMAT_RASTER;
347 *format_count = 1;
348 return format;
349 }
350
351 virtual int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) {
352 if (print_settings_.format != PP_PRINTOUTPUTFORMAT_RASTER)
353 return 0;
354
355 print_settings_ = print_settings;
356 print_settings_valid_ = true;
357 return 1;
358 }
359
360 virtual pp::Resource PrintPages(
361 const PP_PrintPageNumberRange_Dev* page_ranges,
362 uint32_t page_range_count) {
363 if (!print_settings_valid_)
364 return pp::Resource();
365
366 if (page_range_count != 1)
367 return pp::Resource();
368
369 // Check if the page numbers are valid. We returned 1 in PrintBegin so we
370 // only have 1 page to print.
371 if (page_ranges[0].first_page_number || page_ranges[0].last_page_number) {
372 return pp::Resource();
373 }
374
375 int width = static_cast<int>(
376 (print_settings_.printable_area.size.width / 72.0) *
377 print_settings_.dpi);
378 int height = static_cast<int>(
379 (print_settings_.printable_area.size.height / 72.0) *
380 print_settings_.dpi);
381
382 return PaintImage(width, height);
383 }
384
385 virtual void PrintEnd() {
386 print_settings_valid_ = false;
387 }
388
389 void OnFlush() {
390 if (animation_counter_ % kStepsPerCircle == 0)
391 UpdateFps();
392 animation_counter_++;
393 Paint();
394 }
395
396 private:
397 void SayHello() {
398 pp::VarPrivate window = GetWindowObject();
399 pp::VarPrivate doc = window.GetProperty("document");
400 pp::VarPrivate body = doc.GetProperty("body");
401
402 pp::VarPrivate obj(this, new MyScriptableObject(this));
403
404 // Our object should have its toString method called.
405 Log(PP_LOGLEVEL_LOG, "Testing MyScriptableObject::toString():");
406 Log(PP_LOGLEVEL_LOG, obj);
407
408 // body.appendChild(body) should throw an exception
409 Log(PP_LOGLEVEL_LOG, "Calling body.appendChild(body):");
410 pp::Var exception;
411 body.Call("appendChild", body, &exception);
412 Log(PP_LOGLEVEL_LOG, exception);
413
414 Log(PP_LOGLEVEL_LOG, "Enumeration of window properties:");
415 std::vector<pp::Var> props;
416 window.GetAllPropertyNames(&props);
417 for (size_t i = 0; i < props.size(); ++i)
418 Log(PP_LOGLEVEL_LOG, props[i]);
419
420 pp::VarPrivate location = window.GetProperty("location");
421 pp::VarPrivate href = location.GetProperty("href");
422
423 if (!fetcher_) {
424 fetcher_ = new MyFetcher();
425 fetcher_->Start(this, href, this);
426 }
427 }
428
429 void DidFetch(bool success, const std::string& data) {
430 Log(PP_LOGLEVEL_LOG, "Downloaded location.href:");
431 if (success) {
432 Log(PP_LOGLEVEL_LOG, data);
433 } else {
434 Log(PP_LOGLEVEL_ERROR, "Failed to download.");
435 }
436 delete fetcher_;
437 fetcher_ = NULL;
438 }
439
440 void ToggleCursor() {
441 const PPB_CursorControl_Dev* cursor_control =
442 reinterpret_cast<const PPB_CursorControl_Dev*>(
443 pp::Module::Get()->GetBrowserInterface(
444 PPB_CURSOR_CONTROL_DEV_INTERFACE));
445 if (!cursor_control)
446 return;
447
448 if (showing_custom_cursor_) {
449 cursor_control->SetCursor(pp_instance(), PP_CURSORTYPE_POINTER, 0, NULL);
450 } else {
451 pp::ImageData image_data(this, pp::ImageData::GetNativeImageDataFormat(),
452 pp::Size(50, 50), false);
453 FillRect(&image_data, 0, 0, 50, 50,
454 image_data.format() == PP_IMAGEDATAFORMAT_BGRA_PREMUL ?
455 0x80800000 : 0x80000080);
456 pp::Point hot_spot(0, 0);
457 cursor_control->SetCursor(pp_instance(), PP_CURSORTYPE_CUSTOM,
458 image_data.pp_resource(), &hot_spot.pp_point());
459 }
460
461 showing_custom_cursor_ = !showing_custom_cursor_;
462 }
463
464 pp::Var console_;
465 pp::Graphics2D device_context_;
466
467 double time_at_last_check_;
468
469 MyFetcher* fetcher_;
470
471 int width_;
472 int height_;
473
474 // Incremented for each flush we get.
475 int animation_counter_;
476 bool print_settings_valid_;
477 PP_PrintSettings_Dev print_settings_;
478
479 bool showing_custom_cursor_;
480 };
481
482 void FlushCallback(void* data, int32_t result) {
483 if (result == PP_OK)
484 static_cast<MyInstance*>(data)->OnFlush();
485 }
486
487 class MyModule : public pp::Module {
488 public:
489 MyModule() : pp::Module() {}
490 virtual ~MyModule() {}
491
492 virtual pp::Instance* CreateInstance(PP_Instance instance) {
493 return new MyInstance(instance);
494 }
495 };
496
497 namespace pp {
498
499 // Factory function for your specialization of the Module object.
500 Module* CreateModule() {
501 return new MyModule();
502 }
503
504 } // namespace pp
OLDNEW
« no previous file with comments | « ppapi/example/Info.plist ('k') | ppapi/example/example.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698