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

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

Issue 6543028: Implement the filesystem proxy. This allows the FileRef tests to pass in the... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <math.h> 5 #include "ppapi/c/dev/ppb_file_chooser_dev.h"
6 #include <stdio.h> // FIXME(brettw) erase me.
7 #ifndef _WIN32
8 #include <sys/time.h>
9 #endif
10 #include <time.h>
11
12 #include <algorithm>
13
14 #include "ppapi/c/dev/ppp_printing_dev.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/c/pp_input_event.h" 6 #include "ppapi/c/pp_input_event.h"
17 #include "ppapi/c/pp_rect.h"
18 #include "ppapi/cpp/completion_callback.h" 7 #include "ppapi/cpp/completion_callback.h"
19 #include "ppapi/cpp/dev/scriptable_object_deprecated.h" 8 #include "ppapi/cpp/dev/file_chooser_dev.h"
20 #include "ppapi/cpp/graphics_2d.h" 9 #include "ppapi/cpp/dev/file_ref_dev.h"
21 #include "ppapi/cpp/image_data.h"
22 #include "ppapi/cpp/instance.h" 10 #include "ppapi/cpp/instance.h"
23 #include "ppapi/cpp/module.h" 11 #include "ppapi/cpp/module.h"
24 #include "ppapi/cpp/rect.h"
25 #include "ppapi/cpp/url_loader.h"
26 #include "ppapi/cpp/url_request_info.h"
27 #include "ppapi/cpp/var.h" 12 #include "ppapi/cpp/var.h"
28 13
29 static const int kStepsPerCircle = 800; 14 class MyInstance : public pp::Instance {
30
31 void FlushCallback(void* data, int32_t result);
32
33 void FillRect(pp::ImageData* image, int left, int top, int width, int height,
34 uint32_t color) {
35 for (int y = std::max(0, top);
36 y < std::min(image->size().height() - 1, top + height);
37 y++) {
38 for (int x = std::max(0, left);
39 x < std::min(image->size().width() - 1, left + width);
40 x++)
41 *image->GetAddr32(pp::Point(x, y)) = color;
42 }
43 }
44
45 class MyScriptableObject : public pp::deprecated::ScriptableObject {
46 public:
47 explicit MyScriptableObject(pp::Instance* instance) : instance_(instance) {}
48
49 virtual bool HasMethod(const pp::Var& method, pp::Var* exception) {
50 return method.AsString() == "toString";
51 }
52
53 virtual bool HasProperty(const pp::Var& name, pp::Var* exception) {
54 if (name.is_string() && name.AsString() == "blah")
55 return true;
56 return false;
57 }
58
59 virtual pp::Var GetProperty(const pp::Var& name, pp::Var* exception) {
60 if (name.is_string() && name.AsString() == "blah")
61 return pp::Var(instance_, new MyScriptableObject(instance_));
62 return pp::Var();
63 }
64
65 virtual void GetAllPropertyNames(std::vector<pp::Var>* names,
66 pp::Var* exception) {
67 names->push_back("blah");
68 }
69
70 virtual pp::Var Call(const pp::Var& method,
71 const std::vector<pp::Var>& args,
72 pp::Var* exception) {
73 if (method.AsString() == "toString")
74 return pp::Var("hello world");
75 return pp::Var();
76 }
77
78 private:
79 pp::Instance* instance_;
80 };
81
82 class MyFetcherClient {
83 public:
84 virtual void DidFetch(bool success, const std::string& data) = 0;
85 };
86
87 class MyFetcher {
88 public:
89 MyFetcher() : client_(NULL) {
90 callback_factory_.Initialize(this);
91 }
92
93 void Start(const pp::Instance& instance,
94 const pp::Var& url,
95 MyFetcherClient* client) {
96 pp::URLRequestInfo request;
97 request.SetURL(url);
98 request.SetMethod("GET");
99
100 loader_ = pp::URLLoader(instance);
101 client_ = client;
102
103 pp::CompletionCallback callback =
104 callback_factory_.NewCallback(&MyFetcher::DidOpen);
105 int rv = loader_.Open(request, callback);
106 if (rv != PP_ERROR_WOULDBLOCK)
107 callback.Run(rv);
108 }
109
110 void StartWithOpenedLoader(const pp::URLLoader& loader,
111 MyFetcherClient* client) {
112 loader_ = loader;
113 client_ = client;
114
115 ReadMore();
116 }
117
118 private:
119 void ReadMore() {
120 pp::CompletionCallback callback =
121 callback_factory_.NewCallback(&MyFetcher::DidRead);
122 int rv = loader_.ReadResponseBody(buf_, sizeof(buf_), callback);
123 if (rv != PP_ERROR_WOULDBLOCK)
124 callback.Run(rv);
125 }
126
127 void DidOpen(int32_t result) {
128 if (result == PP_OK) {
129 ReadMore();
130 } else {
131 DidFinish(result);
132 }
133 }
134
135 void DidRead(int32_t result) {
136 if (result > 0) {
137 data_.append(buf_, result);
138 ReadMore();
139 } else {
140 DidFinish(result);
141 }
142 }
143
144 void DidFinish(int32_t result) {
145 if (client_)
146 client_->DidFetch(result == PP_OK, data_);
147 }
148
149 pp::CompletionCallbackFactory<MyFetcher> callback_factory_;
150 pp::URLLoader loader_;
151 MyFetcherClient* client_;
152 char buf_[4096];
153 std::string data_;
154 };
155
156 class MyInstance : public pp::Instance, public MyFetcherClient {
157 public: 15 public:
158 MyInstance(PP_Instance instance) 16 MyInstance(PP_Instance instance)
159 : pp::Instance(instance), 17 : pp::Instance(instance) {
160 time_at_last_check_(0.0), 18 callback_factory_.Initialize(this);
161 fetcher_(NULL),
162 width_(0),
163 height_(0),
164 animation_counter_(0),
165 print_settings_valid_(false) {}
166
167 virtual ~MyInstance() {
168 if (fetcher_) {
169 delete fetcher_;
170 fetcher_ = NULL;
171 }
172 }
173
174 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
175 return true;
176 }
177
178 virtual bool HandleDocumentLoad(const pp::URLLoader& loader) {
179 fetcher_ = new MyFetcher();
180 fetcher_->StartWithOpenedLoader(loader, this);
181 return true;
182 } 19 }
183 20
184 virtual bool HandleInputEvent(const PP_InputEvent& event) { 21 virtual bool HandleInputEvent(const PP_InputEvent& event) {
185 switch (event.type) { 22 switch (event.type) {
186 case PP_INPUTEVENT_TYPE_MOUSEDOWN: 23 case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
187 //SayHello(); 24 const PP_InputEvent_Mouse& mouse_event = event.u.mouse;
25 if (mouse_event.button == PP_INPUTEVENT_MOUSEBUTTON_LEFT)
26 ShowFileChooser(false);
27 else if (mouse_event.button == PP_INPUTEVENT_MOUSEBUTTON_RIGHT)
28 ShowFileChooser(true);
29 else
30 return false;
31
188 return true; 32 return true;
189 case PP_INPUTEVENT_TYPE_MOUSEMOVE: 33 }
190 return true;
191 case PP_INPUTEVENT_TYPE_KEYDOWN:
192 return true;
193 default: 34 default:
194 return false; 35 return false;
195 } 36 }
196 } 37 }
197 38
198 virtual pp::Var GetInstanceObject() { 39 private:
199 return pp::Var(this, new MyScriptableObject(this)); 40 void ShowFileChooser(bool multi_select) {
41 RecreateConsole();
42
43 PP_FileChooserOptions_Dev options;
44 options.mode = (multi_select ? PP_FILECHOOSERMODE_OPENMULTIPLE :
45 PP_FILECHOOSERMODE_OPEN);
46 options.accept_mime_types = (multi_select ? "" : "plain/text");
47
48 // Deleted in ShowSelectedFileNames().
49 pp::FileChooser_Dev* file_chooser = new pp::FileChooser_Dev(
50 *this, options);
51 file_chooser->Show(callback_factory_.NewCallback(
52 &MyInstance::ShowSelectedFileNames, file_chooser));
200 } 53 }
201 54
202 pp::ImageData PaintImage(int width, int height) { 55 void ShowSelectedFileNames(int32_t, pp::FileChooser_Dev* file_chooser) {
203 pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 56 if (!file_chooser)
204 pp::Size(width, height), false); 57 return;
205 if (image.is_null()) { 58
206 printf("Couldn't allocate the image data: %d, %d\n", width, height); 59 pp::FileRef_Dev file_ref = file_chooser->GetNextChosenFile();
207 return image; 60 while (!file_ref.is_null()) {
61 Log(file_ref.GetName());
62 file_ref = file_chooser->GetNextChosenFile();
208 } 63 }
209 64
210 // Fill with semitransparent gradient. 65 delete file_chooser;
211 for (int y = 0; y < image.size().height(); y++) {
212 char* row = &static_cast<char*>(image.data())[y * image.stride()];
213 for (int x = 0; x < image.size().width(); x++) {
214 row[x * 4 + 0] = y;
215 row[x * 4 + 1] = y;
216 row[x * 4 + 2] = 0;
217 row[x * 4 + 3] = y;
218 }
219 }
220
221 // Draw the orbiting box.
222 float radians = static_cast<float>(animation_counter_) / kStepsPerCircle *
223 2 * 3.14159265358979F;
224
225 float radius = static_cast<float>(std::min(width, height)) / 2.0f - 3.0f;
226 int x = static_cast<int>(cos(radians) * radius + radius + 2);
227 int y = static_cast<int>(sin(radians) * radius + radius + 2);
228
229 const uint32_t box_bgra = 0x80000000; // Alpha 50%.
230 FillRect(&image, x - 3, y - 3, 7, 7, box_bgra);
231 return image;
232 } 66 }
233 67
234 void Paint() { 68 void RecreateConsole() {
235 pp::ImageData image = PaintImage(width_, height_); 69 pp::Var doc = GetWindowObject().GetProperty("document");
236 if (!image.is_null()) { 70 pp::Var body = doc.GetProperty("body");
237 device_context_.ReplaceContents(&image); 71 if (!console_.is_undefined())
238 device_context_.Flush(pp::CompletionCallback(&FlushCallback, this)); 72 body.Call("removeChild", console_);
239 } else { 73
240 printf("NullImage: %d, %d\n", width_, height_); 74 console_ = doc.Call("createElement", "pre");
241 } 75 console_.SetProperty("id", "console");
76 console_.GetProperty("style").SetProperty("backgroundColor", "lightgray");
77 body.Call("appendChild", console_);
242 } 78 }
243 79
244 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
245 if (position.size().width() == width_ &&
246 position.size().height() == height_)
247 return; // We don't care about the position, only the size.
248
249 width_ = position.size().width();
250 height_ = position.size().height();
251 printf("DidChangeView relevant change: width=%d height:%d\n",
252 width_, height_);
253
254 device_context_ = pp::Graphics2D(this, pp::Size(width_, height_), false);
255 if (!BindGraphics(device_context_)) {
256 printf("Couldn't bind the device context\n");
257 return;
258 }
259
260 Paint();
261 }
262
263 void UpdateFps() {
264 // Time code doesn't currently compile on Windows, just skip FPS for now.
265 #ifndef _WIN32
266 pp::Var window = GetWindowObject();
267 pp::Var doc = window.GetProperty("document");
268 pp::Var fps = doc.Call("getElementById", "fps");
269
270 struct timeval tv;
271 struct timezone tz = {0, 0};
272 gettimeofday(&tv, &tz);
273
274 double time_now = tv.tv_sec + tv.tv_usec / 1000000.0;
275
276 if (animation_counter_ > 0) {
277 char fps_text[64];
278 sprintf(fps_text, "%g fps",
279 kStepsPerCircle / (time_now - time_at_last_check_));
280 fps.SetProperty("innerHTML", fps_text);
281 }
282
283 time_at_last_check_ = time_now;
284 #endif
285 }
286
287 // Print interfaces.
288 virtual PP_PrintOutputFormat_Dev* QuerySupportedPrintOutputFormats(
289 uint32_t* format_count) {
290 PP_PrintOutputFormat_Dev* format =
291 reinterpret_cast<PP_PrintOutputFormat_Dev*>(
292 pp::Module::Get()->core()->MemAlloc(
293 sizeof(PP_PrintOutputFormat_Dev)));
294 *format = PP_PRINTOUTPUTFORMAT_RASTER;
295 *format_count = 1;
296 return format;
297 }
298
299 virtual int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) {
300 if (print_settings_.format != PP_PRINTOUTPUTFORMAT_RASTER)
301 return 0;
302
303 print_settings_ = print_settings;
304 print_settings_valid_ = true;
305 return 1;
306 }
307
308 virtual pp::Resource PrintPages(
309 const PP_PrintPageNumberRange_Dev* page_ranges,
310 uint32_t page_range_count) {
311 if (!print_settings_valid_)
312 return pp::Resource();
313
314 if (page_range_count != 1)
315 return pp::Resource();
316
317 // Check if the page numbers are valid. We returned 1 in PrintBegin so we
318 // only have 1 page to print.
319 if (page_ranges[0].first_page_number || page_ranges[0].last_page_number) {
320 return pp::Resource();
321 }
322
323 int width = static_cast<int>(
324 (print_settings_.printable_area.size.width / 72.0) *
325 print_settings_.dpi);
326 int height = static_cast<int>(
327 (print_settings_.printable_area.size.height / 72.0) *
328 print_settings_.dpi);
329
330 return PaintImage(width, height);
331 }
332
333 virtual void PrintEnd() {
334 print_settings_valid_ = false;
335 }
336
337 void OnFlush() {
338 if (animation_counter_ % kStepsPerCircle == 0)
339 UpdateFps();
340 animation_counter_++;
341 Paint();
342 }
343
344 private:
345 void Log(const pp::Var& var) { 80 void Log(const pp::Var& var) {
346 pp::Var doc = GetWindowObject().GetProperty("document"); 81 pp::Var doc = GetWindowObject().GetProperty("document");
347 if (console_.is_undefined()) {
348 pp::Var body = doc.GetProperty("body");
349 console_ = doc.Call("createElement", "pre");
350 console_.GetProperty("style").SetProperty("backgroundColor", "lightgray");
351 body.Call("appendChild", console_);
352 }
353 console_.Call("appendChild", doc.Call("createTextNode", var)); 82 console_.Call("appendChild", doc.Call("createTextNode", var));
354 console_.Call("appendChild", doc.Call("createTextNode", "\n")); 83 console_.Call("appendChild", doc.Call("createTextNode", "\n"));
355 } 84 }
356 85
357 void SayHello() { 86 pp::CompletionCallbackFactory<MyInstance> callback_factory_;
358 pp::Var window = GetWindowObject();
359 pp::Var doc = window.GetProperty("document");
360 pp::Var body = doc.GetProperty("body");
361
362 pp::Var obj(this, new MyScriptableObject(this));
363
364 // Our object should have its toString method called.
365 Log("Testing MyScriptableObject::toString():");
366 Log(obj);
367
368 // body.appendChild(body) should throw an exception
369 Log("\nCalling body.appendChild(body):");
370 pp::Var exception;
371 body.Call("appendChild", body, &exception);
372 Log(exception);
373
374 Log("\nEnumeration of window properties:");
375 std::vector<pp::Var> props;
376 window.GetAllPropertyNames(&props);
377 for (size_t i = 0; i < props.size(); ++i)
378 Log(props[i]);
379
380 pp::Var location = window.GetProperty("location");
381 pp::Var href = location.GetProperty("href");
382
383 if (!fetcher_) {
384 fetcher_ = new MyFetcher();
385 fetcher_->Start(*this, href, this);
386 }
387 }
388
389 void DidFetch(bool success, const std::string& data) {
390 Log("\nDownloaded location.href:");
391 if (success) {
392 Log(data);
393 } else {
394 Log("Failed to download.");
395 }
396 delete fetcher_;
397 fetcher_ = NULL;
398 }
399
400 pp::Var console_; 87 pp::Var console_;
401 pp::Graphics2D device_context_;
402
403 double time_at_last_check_;
404
405 MyFetcher* fetcher_;
406
407 int width_;
408 int height_;
409
410 // Incremented for each flush we get.
411 int animation_counter_;
412 bool print_settings_valid_;
413 PP_PrintSettings_Dev print_settings_;
414 }; 88 };
415 89
416 void FlushCallback(void* data, int32_t result) {
417 static_cast<MyInstance*>(data)->OnFlush();
418 }
419
420 class MyModule : public pp::Module { 90 class MyModule : public pp::Module {
421 public: 91 public:
422 MyModule() : pp::Module() {} 92 MyModule() : pp::Module() {}
423 virtual ~MyModule() {} 93 virtual ~MyModule() {}
424 94
425 virtual pp::Instance* CreateInstance(PP_Instance instance) { 95 virtual pp::Instance* CreateInstance(PP_Instance instance) {
426 return new MyInstance(instance); 96 return new MyInstance(instance);
427 } 97 }
428 }; 98 };
429 99
430 namespace pp { 100 namespace pp {
431 101
432 // Factory function for your specialization of the Module object. 102 // Factory function for your specialization of the Module object.
433 Module* CreateModule() { 103 Module* CreateModule() {
434 return new MyModule(); 104 return new MyModule();
435 } 105 }
436 106
437 } // namespace pp 107 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698