summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-01 16:16:50 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-01 16:16:50 +0000
commit1758e88fd909ea0ffd49621e8066ffad5627ffdf (patch)
treec304a5eed047cae5665f5af1739d84655fb5815d
parente7d8b51953b7d3b2b8a0aba46132305b32f3efce (diff)
downloadchromium_src-1758e88fd909ea0ffd49621e8066ffad5627ffdf.zip
chromium_src-1758e88fd909ea0ffd49621e8066ffad5627ffdf.tar.gz
chromium_src-1758e88fd909ea0ffd49621e8066ffad5627ffdf.tar.bz2
Move PPAPI into the Chrome repo. The old repo was
http://ppapi.googlecode.com/ TEST=none BUG=none git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64613 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ppapi/GLES2/gl2.h607
-rw-r--r--ppapi/GLES2/khrplatform.h269
-rw-r--r--ppapi/LICENSE27
-rw-r--r--ppapi/c/dev/pp_cursor_type_dev.h53
-rw-r--r--ppapi/c/dev/pp_file_info_dev.h32
-rw-r--r--ppapi/c/dev/pp_video_dev.h290
-rw-r--r--ppapi/c/dev/ppb_audio_config_dev.h94
-rw-r--r--ppapi/c/dev/ppb_audio_dev.h71
-rw-r--r--ppapi/c/dev/ppb_audio_trusted_dev.h27
-rw-r--r--ppapi/c/dev/ppb_buffer_dev.h36
-rw-r--r--ppapi/c/dev/ppb_char_set_dev.h78
-rw-r--r--ppapi/c/dev/ppb_cursor_control_dev.h56
-rw-r--r--ppapi/c/dev/ppb_directory_reader_dev.h52
-rw-r--r--ppapi/c/dev/ppb_file_chooser_dev.h57
-rw-r--r--ppapi/c/dev/ppb_file_io_dev.h115
-rw-r--r--ppapi/c/dev/ppb_file_io_trusted_dev.h45
-rw-r--r--ppapi/c/dev/ppb_file_ref_dev.h88
-rw-r--r--ppapi/c/dev/ppb_file_system_dev.h29
-rw-r--r--ppapi/c/dev/ppb_find_dev.h28
-rw-r--r--ppapi/c/dev/ppb_font_dev.h161
-rw-r--r--ppapi/c/dev/ppb_fullscreen_dev.h27
-rw-r--r--ppapi/c/dev/ppb_graphics_3d_dev.h103
-rw-r--r--ppapi/c/dev/ppb_opengles_dev.h248
-rw-r--r--ppapi/c/dev/ppb_scrollbar_dev.h62
-rw-r--r--ppapi/c/dev/ppb_testing_dev.h70
-rw-r--r--ppapi/c/dev/ppb_transport_dev.h70
-rw-r--r--ppapi/c/dev/ppb_url_loader_dev.h101
-rw-r--r--ppapi/c/dev/ppb_url_loader_trusted_dev.h19
-rw-r--r--ppapi/c/dev/ppb_url_request_info_dev.h71
-rw-r--r--ppapi/c/dev/ppb_url_response_info_dev.h41
-rw-r--r--ppapi/c/dev/ppb_url_util_dev.h111
-rw-r--r--ppapi/c/dev/ppb_var_deprecated.h243
-rw-r--r--ppapi/c/dev/ppb_video_decoder_dev.h86
-rw-r--r--ppapi/c/dev/ppb_widget_dev.h39
-rw-r--r--ppapi/c/dev/ppb_zoom_dev.h28
-rw-r--r--ppapi/c/dev/ppp_class_deprecated.h134
-rw-r--r--ppapi/c/dev/ppp_cursor_control_dev.h19
-rw-r--r--ppapi/c/dev/ppp_find_dev.h33
-rw-r--r--ppapi/c/dev/ppp_graphics_3d_dev.h18
-rw-r--r--ppapi/c/dev/ppp_printing_dev.h74
-rw-r--r--ppapi/c/dev/ppp_scrollbar_dev.h22
-rw-r--r--ppapi/c/dev/ppp_selection_dev.h23
-rw-r--r--ppapi/c/dev/ppp_widget_dev.h22
-rw-r--r--ppapi/c/dev/ppp_zoom_dev.h22
-rw-r--r--ppapi/c/pp_completion_callback.h64
-rw-r--r--ppapi/c/pp_errors.h82
-rw-r--r--ppapi/c/pp_input_event.h181
-rw-r--r--ppapi/c/pp_instance.h33
-rw-r--r--ppapi/c/pp_module.h30
-rw-r--r--ppapi/c/pp_point.h35
-rw-r--r--ppapi/c/pp_rect.h39
-rw-r--r--ppapi/c/pp_resource.h39
-rw-r--r--ppapi/c/pp_size.h34
-rw-r--r--ppapi/c/pp_stdint.h36
-rw-r--r--ppapi/c/pp_time.h38
-rw-r--r--ppapi/c/pp_var.h88
-rw-r--r--ppapi/c/ppb.h26
-rw-r--r--ppapi/c/ppb_class.h121
-rw-r--r--ppapi/c/ppb_core.h92
-rw-r--r--ppapi/c/ppb_graphics_2d.h223
-rw-r--r--ppapi/c/ppb_image_data.h99
-rw-r--r--ppapi/c/ppb_instance.h89
-rw-r--r--ppapi/c/ppb_var.h295
-rw-r--r--ppapi/c/ppp.h60
-rw-r--r--ppapi/c/ppp_instance.h133
-rw-r--r--ppapi/c/trusted/ppb_image_data_trusted.h21
-rw-r--r--ppapi/codereview.settings5
-rw-r--r--ppapi/cpp/completion_callback.h313
-rw-r--r--ppapi/cpp/core.cc25
-rw-r--r--ppapi/cpp/core.h67
-rw-r--r--ppapi/cpp/dev/audio_config_dev.cc39
-rw-r--r--ppapi/cpp/dev/audio_config_dev.h57
-rw-r--r--ppapi/cpp/dev/audio_dev.cc38
-rw-r--r--ppapi/cpp/dev/audio_dev.h38
-rw-r--r--ppapi/cpp/dev/buffer_dev.cc55
-rw-r--r--ppapi/cpp/dev/buffer_dev.h39
-rw-r--r--ppapi/cpp/dev/directory_entry_dev.cc41
-rw-r--r--ppapi/cpp/dev/directory_entry_dev.h38
-rw-r--r--ppapi/cpp/dev/directory_reader_dev.cc53
-rw-r--r--ppapi/cpp/dev/directory_reader_dev.h36
-rw-r--r--ppapi/cpp/dev/file_chooser_dev.cc58
-rw-r--r--ppapi/cpp/dev/file_chooser_dev.h38
-rw-r--r--ppapi/cpp/dev/file_io_dev.cc135
-rw-r--r--ppapi/cpp/dev/file_io_dev.h61
-rw-r--r--ppapi/cpp/dev/file_ref_dev.cc124
-rw-r--r--ppapi/cpp/dev/file_ref_dev.h71
-rw-r--r--ppapi/cpp/dev/file_system_dev.cc37
-rw-r--r--ppapi/cpp/dev/file_system_dev.h32
-rw-r--r--ppapi/cpp/dev/find_dev.cc75
-rw-r--r--ppapi/cpp/dev/find_dev.h61
-rw-r--r--ppapi/cpp/dev/font_dev.cc210
-rw-r--r--ppapi/cpp/dev/font_dev.h139
-rw-r--r--ppapi/cpp/dev/fullscreen_dev.cc39
-rw-r--r--ppapi/cpp/dev/fullscreen_dev.h31
-rw-r--r--ppapi/cpp/dev/graphics_3d_client_dev.cc43
-rw-r--r--ppapi/cpp/dev/graphics_3d_client_dev.h36
-rw-r--r--ppapi/cpp/dev/graphics_3d_dev.cc117
-rw-r--r--ppapi/cpp/dev/graphics_3d_dev.h54
-rw-r--r--ppapi/cpp/dev/printing_dev.cc74
-rw-r--r--ppapi/cpp/dev/printing_dev.h38
-rw-r--r--ppapi/cpp/dev/scriptable_object_deprecated.cc188
-rw-r--r--ppapi/cpp/dev/scriptable_object_deprecated.h92
-rw-r--r--ppapi/cpp/dev/scrollbar_dev.cc84
-rw-r--r--ppapi/cpp/dev/scrollbar_dev.h39
-rw-r--r--ppapi/cpp/dev/selection_dev.cc41
-rw-r--r--ppapi/cpp/dev/selection_dev.h52
-rw-r--r--ppapi/cpp/dev/transport_dev.cc28
-rw-r--r--ppapi/cpp/dev/transport_dev.h23
-rw-r--r--ppapi/cpp/dev/url_loader_dev.cc115
-rw-r--r--ppapi/cpp/dev/url_loader_dev.h108
-rw-r--r--ppapi/cpp/dev/url_request_info_dev.cc81
-rw-r--r--ppapi/cpp/dev/url_request_info_dev.h57
-rw-r--r--ppapi/cpp/dev/url_response_info_dev.cc54
-rw-r--r--ppapi/cpp/dev/url_response_info_dev.h58
-rw-r--r--ppapi/cpp/dev/url_util_dev.cc70
-rw-r--r--ppapi/cpp/dev/url_util_dev.h54
-rw-r--r--ppapi/cpp/dev/video_decoder_dev.cc84
-rw-r--r--ppapi/cpp/dev/video_decoder_dev.h47
-rw-r--r--ppapi/cpp/dev/widget_client_dev.cc74
-rw-r--r--ppapi/cpp/dev/widget_client_dev.h44
-rw-r--r--ppapi/cpp/dev/widget_dev.cc62
-rw-r--r--ppapi/cpp/dev/widget_dev.h41
-rw-r--r--ppapi/cpp/dev/zoom_dev.cc58
-rw-r--r--ppapi/cpp/dev/zoom_dev.h58
-rw-r--r--ppapi/cpp/graphics_2d.cc98
-rw-r--r--ppapi/cpp/graphics_2d.h75
-rw-r--r--ppapi/cpp/image_data.cc98
-rw-r--r--ppapi/cpp/image_data.h65
-rw-r--r--ppapi/cpp/instance.cc143
-rw-r--r--ppapi/cpp/instance.h157
-rw-r--r--ppapi/cpp/logging.h14
-rw-r--r--ppapi/cpp/module.cc198
-rw-r--r--ppapi/cpp/module.h123
-rw-r--r--ppapi/cpp/module_embedder.h20
-rw-r--r--ppapi/cpp/module_impl.h41
-rw-r--r--ppapi/cpp/non_thread_safe_ref_count.h48
-rw-r--r--ppapi/cpp/paint_aggregator.cc274
-rw-r--r--ppapi/cpp/paint_aggregator.h130
-rw-r--r--ppapi/cpp/paint_manager.cc174
-rw-r--r--ppapi/cpp/paint_manager.h207
-rw-r--r--ppapi/cpp/point.h93
-rw-r--r--ppapi/cpp/ppp_entrypoints.cc52
-rw-r--r--ppapi/cpp/rect.cc137
-rw-r--r--ppapi/cpp/rect.h213
-rw-r--r--ppapi/cpp/resource.cc53
-rw-r--r--ppapi/cpp/resource.h58
-rw-r--r--ppapi/cpp/size.h108
-rw-r--r--ppapi/cpp/var.cc365
-rw-r--r--ppapi/cpp/var.h205
-rwxr-xr-xppapi/documentation/Doxyfile1274
-rwxr-xr-xppapi/documentation/check.sh26
-rw-r--r--ppapi/documentation/footer.dox19
-rw-r--r--ppapi/documentation/header.dox13
-rw-r--r--ppapi/documentation/images-dox/README.txt9
-rw-r--r--ppapi/documentation/index.dox105
-rw-r--r--ppapi/documentation/modules.dox24
-rw-r--r--ppapi/documentation/stylesheet-dox.css478
-rw-r--r--ppapi/documentation/stylesheet.css101
-rw-r--r--ppapi/example/Info.plist46
-rw-r--r--ppapi/example/example.cc426
-rw-r--r--ppapi/example/example.html17
-rw-r--r--ppapi/example/example.rc30
-rw-r--r--ppapi/example/example_framed.html2
-rw-r--r--ppapi/examples/2d/graphics_2d_example.c225
-rw-r--r--ppapi/examples/2d/paint_manager_example.cc157
-rw-r--r--ppapi/examples/2d/scroll.cc119
-rw-r--r--ppapi/examples/audio/audio.cc80
-rw-r--r--ppapi/examples/file_chooser/file_chooser.cc107
-rw-r--r--ppapi/examples/font/simple_font.cc67
-rw-r--r--ppapi/examples/stub/stub.c35
-rw-r--r--ppapi/examples/stub/stub.cc41
-rw-r--r--ppapi/ppapi.gyp465
-rw-r--r--ppapi/tests/test_buffer.cc77
-rw-r--r--ppapi/tests/test_buffer.h31
-rw-r--r--ppapi/tests/test_case.cc37
-rw-r--r--ppapi/tests/test_case.h114
-rw-r--r--ppapi/tests/test_case.html74
-rw-r--r--ppapi/tests/test_char_set.cc167
-rw-r--r--ppapi/tests/test_char_set.h35
-rw-r--r--ppapi/tests/test_file_io.cc341
-rw-r--r--ppapi/tests/test_file_io.h26
-rw-r--r--ppapi/tests/test_file_ref.cc502
-rw-r--r--ppapi/tests/test_file_ref.h31
-rw-r--r--ppapi/tests/test_graphics_2d.cc542
-rw-r--r--ppapi/tests/test_graphics_2d.h88
-rw-r--r--ppapi/tests/test_image_data.cc140
-rw-r--r--ppapi/tests/test_image_data.h31
-rw-r--r--ppapi/tests/test_image_data/test_image_data.cc151
-rw-r--r--ppapi/tests/test_image_data/test_image_data.html11
-rw-r--r--ppapi/tests/test_instance_deprecated.cc122
-rw-r--r--ppapi/tests/test_instance_deprecated.h35
-rw-r--r--ppapi/tests/test_page.css67
-rw-r--r--ppapi/tests/test_paint_aggregator.cc426
-rw-r--r--ppapi/tests/test_paint_aggregator.h41
-rw-r--r--ppapi/tests/test_scrollbar.cc50
-rw-r--r--ppapi/tests/test_scrollbar.h33
-rw-r--r--ppapi/tests/test_transport.cc50
-rw-r--r--ppapi/tests/test_transport.h39
-rw-r--r--ppapi/tests/test_url_loader.cc315
-rw-r--r--ppapi/tests/test_url_loader.h44
-rw-r--r--ppapi/tests/test_url_loader_data/hello.txt1
-rw-r--r--ppapi/tests/test_url_util.cc118
-rw-r--r--ppapi/tests/test_url_util.h29
-rw-r--r--ppapi/tests/test_var.cc178
-rw-r--r--ppapi/tests/test_var.h32
-rw-r--r--ppapi/tests/test_var_deprecated.cc329
-rw-r--r--ppapi/tests/test_var_deprecated.h39
-rw-r--r--ppapi/tests/testing_instance.cc182
-rw-r--r--ppapi/tests/testing_instance.h75
209 files changed, 21306 insertions, 0 deletions
diff --git a/ppapi/GLES2/gl2.h b/ppapi/GLES2/gl2.h
new file mode 100644
index 0000000..ca30cb5
--- /dev/null
+++ b/ppapi/GLES2/gl2.h
@@ -0,0 +1,607 @@
+// Copyright (c 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef __gl2_h_
+#define __gl2_h_
+
+#include "../c/dev/ppb_opengles_dev.h"
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+/* OpenGL ES core versions */
+#define GL_ES_VERSION_2_0 1
+
+/* ClearBufferMask */
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_COLOR_BUFFER_BIT 0x00004000
+
+/* Boolean */
+#define GL_FALSE 0
+#define GL_TRUE 1
+
+/* BeginMode */
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_STRIP 0x0003
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+
+/* AlphaFunction (not supported in ES20 */
+/* GL_NEVER */
+/* GL_LESS */
+/* GL_EQUAL */
+/* GL_LEQUAL */
+/* GL_GREATER */
+/* GL_NOTEQUAL */
+/* GL_GEQUAL */
+/* GL_ALWAYS */
+
+/* BlendingFactorDest */
+#define GL_ZERO 0
+#define GL_ONE 1
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+
+/* BlendingFactorSrc */
+/* GL_ZERO */
+/* GL_ONE */
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+/* GL_SRC_ALPHA */
+/* GL_ONE_MINUS_SRC_ALPHA */
+/* GL_DST_ALPHA */
+/* GL_ONE_MINUS_DST_ALPHA */
+
+/* BlendEquationSeparate */
+#define GL_FUNC_ADD 0x8006
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+
+/* BlendSubtract */
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+
+/* Separate Blend Functions */
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+
+/* Buffer Objects */
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STATIC_DRAW 0x88E4
+#define GL_DYNAMIC_DRAW 0x88E8
+
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+
+/* CullFaceMode */
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_FRONT_AND_BACK 0x0408
+
+/* DepthFunction */
+/* GL_NEVER */
+/* GL_LESS */
+/* GL_EQUAL */
+/* GL_LEQUAL */
+/* GL_GREATER */
+/* GL_NOTEQUAL */
+/* GL_GEQUAL */
+/* GL_ALWAYS */
+
+/* EnableCap */
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_CULL_FACE 0x0B44
+#define GL_BLEND 0x0BE2
+#define GL_DITHER 0x0BD0
+#define GL_STENCIL_TEST 0x0B90
+#define GL_DEPTH_TEST 0x0B71
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_COVERAGE 0x80A0
+
+/* ErrorCode */
+#define GL_NO_ERROR 0
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_CONTEXT_LOST 0x300E // TODO(gman: What value?
+
+/* FrontFaceDirection */
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+
+/* GetPName */
+#define GL_LINE_WIDTH 0x0B21
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#define GL_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+/* GL_SCISSOR_TEST */
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+/* GL_POLYGON_OFFSET_FILL */
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+
+/* GetTextureParameter */
+/* GL_TEXTURE_MAG_FILTER */
+/* GL_TEXTURE_MIN_FILTER */
+/* GL_TEXTURE_WRAP_S */
+/* GL_TEXTURE_WRAP_T */
+
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+
+/* HintMode */
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+
+/* HintTarget */
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+
+/* DataType */
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_FIXED 0x140C
+
+/* PixelFormat */
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+
+/* PixelType */
+/* GL_UNSIGNED_BYTE */
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+
+/* Shaders */
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_DELETE_STATUS 0x8B80
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+
+/* StencilFunction */
+#define GL_NEVER 0x0200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+
+/* StencilOp */
+/* GL_ZERO */
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_INVERT 0x150A
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+
+/* StringName */
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+
+/* TextureMagFilter */
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+
+/* TextureMinFilter */
+/* GL_NEAREST */
+/* GL_LINEAR */
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+
+/* TextureParameterName */
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+
+/* TextureTarget */
+/* GL_TEXTURE_2D */
+#define GL_TEXTURE 0x1702
+
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+
+/* TextureUnit */
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+
+/* TextureWrapMode */
+#define GL_REPEAT 0x2901
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MIRRORED_REPEAT 0x8370
+
+/* Uniform Types */
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_CUBE 0x8B60
+
+/* Vertex Arrays */
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+
+/* Read Format */
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+
+/* Shader Source */
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_COMPILER 0x8DFA
+
+/* Shader Binary */
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+
+/* Shader Precision-Specified Types */
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+
+/* Framebuffer Object. */
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGB565 0x8D62
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_STENCIL_INDEX 0x1901
+#define GL_STENCIL_INDEX8 0x8D48
+
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+
+#define GL_NONE 0
+
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+
+
+/*-------------------------------------------------------------------------
+ * GL core functions.
+ *-----------------------------------------------------------------------*/
+#undef GL_APICALL
+#define GL_APICALL
+#undef GL_APIENTRY
+#define GL_APIENTRY
+
+// The client must set this to point to the Pepper OpenGLES interface once it
+// is obtained. PPAPI C++ wrappers will do this for you.
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern const struct PPB_OpenGLES_Dev* pepper_opengl_interface;
+#ifdef __cplusplus
+}
+#endif
+
+#define glActiveTexture pepper_opengl_interface->ActiveTexture
+#define glAttachShader pepper_opengl_interface->AttachShader
+#define glBindAttribLocation pepper_opengl_interface->BindAttribLocation
+#define glBindBuffer pepper_opengl_interface->BindBuffer
+#define glBindFramebuffer pepper_opengl_interface->BindFramebuffer
+#define glBindRenderbuffer pepper_opengl_interface->BindRenderbuffer
+#define glBindTexture pepper_opengl_interface->BindTexture
+#define glBlendColor pepper_opengl_interface->BlendColor
+#define glBlendEquation pepper_opengl_interface->BlendEquation
+#define glBlendEquationSeparate pepper_opengl_interface->BlendEquationSeparate
+#define glBlendFunc pepper_opengl_interface->BlendFunc
+#define glBlendFuncSeparate pepper_opengl_interface->BlendFuncSeparate
+#define glBufferData pepper_opengl_interface->BufferData
+#define glBufferSubData pepper_opengl_interface->BufferSubData
+#define glCheckFramebufferStatus pepper_opengl_interface->CheckFramebufferStatus
+#define glClear pepper_opengl_interface->Clear
+#define glClearColor pepper_opengl_interface->ClearColor
+#define glClearDepthf pepper_opengl_interface->ClearDepthf
+#define glClearStencil pepper_opengl_interface->ClearStencil
+#define glColorMask pepper_opengl_interface->ColorMask
+#define glCompileShader pepper_opengl_interface->CompileShader
+#define glCompressedTexImage2D pepper_opengl_interface->CompressedTexImage2D
+#define glCompressedTexSubImage2D pepper_opengl_interface->CompressedTexSubImage2D
+#define glCopyTexImage2D pepper_opengl_interface->CopyTexImage2D
+#define glCopyTexSubImage2D pepper_opengl_interface->CopyTexSubImage2D
+#define glCreateProgram pepper_opengl_interface->CreateProgram
+#define glCreateShader pepper_opengl_interface->CreateShader
+#define glCullFace pepper_opengl_interface->CullFace
+#define glDeleteBuffers pepper_opengl_interface->DeleteBuffers
+#define glDeleteFramebuffers pepper_opengl_interface->DeleteFramebuffers
+#define glDeleteProgram pepper_opengl_interface->DeleteProgram
+#define glDeleteRenderbuffers pepper_opengl_interface->DeleteRenderbuffers
+#define glDeleteShader pepper_opengl_interface->DeleteShader
+#define glDeleteTextures pepper_opengl_interface->DeleteTextures
+#define glDepthFunc pepper_opengl_interface->DepthFunc
+#define glDepthMask pepper_opengl_interface->DepthMask
+#define glDepthRangef pepper_opengl_interface->DepthRangef
+#define glDetachShader pepper_opengl_interface->DetachShader
+#define glDisable pepper_opengl_interface->Disable
+#define glDisableVertexAttribArray pepper_opengl_interface->DisableVertexAttribArray
+#define glDrawArrays pepper_opengl_interface->DrawArrays
+#define glDrawElements pepper_opengl_interface->DrawElements
+#define glEnable pepper_opengl_interface->Enable
+#define glEnableVertexAttribArray pepper_opengl_interface->EnableVertexAttribArray
+#define glFinish pepper_opengl_interface->Finish
+#define glFlush pepper_opengl_interface->Flush
+#define glFramebufferRenderbuffer pepper_opengl_interface->FramebufferRenderbuffer
+#define glFramebufferTexture2D pepper_opengl_interface->FramebufferTexture2D
+#define glFrontFace pepper_opengl_interface->FrontFace
+#define glGenBuffers pepper_opengl_interface->GenBuffers
+#define glGenerateMipmap pepper_opengl_interface->GenerateMipmap
+#define glGenFramebuffers pepper_opengl_interface->GenFramebuffers
+#define glGenRenderbuffers pepper_opengl_interface->GenRenderbuffers
+#define glGenTextures pepper_opengl_interface->GenTextures
+#define glGetActiveAttrib pepper_opengl_interface->GetActiveAttrib
+#define glGetActiveUniform pepper_opengl_interface->GetActiveUniform
+#define glGetAttachedShaders pepper_opengl_interface->GetAttachedShaders
+#define glGetAttribLocation pepper_opengl_interface->GetAttribLocation
+#define glGetBooleanv pepper_opengl_interface->GetBooleanv
+#define glGetBufferParameteriv pepper_opengl_interface->GetBufferParameteriv
+#define glGetError pepper_opengl_interface->GetError
+#define glGetFloatv pepper_opengl_interface->GetFloatv
+#define glGetFramebufferAttachmentParameteriv pepper_opengl_interface->GetFramebufferAttachmentParameteriv
+#define glGetIntegerv pepper_opengl_interface->GetIntegerv
+#define glGetProgramiv pepper_opengl_interface->GetProgramiv
+#define glGetProgramInfoLog pepper_opengl_interface->GetProgramInfoLog
+#define glGetRenderbufferParameteriv pepper_opengl_interface->GetRenderbufferParameteriv
+#define glGetShaderiv pepper_opengl_interface->GetShaderiv
+#define glGetShaderInfoLog pepper_opengl_interface->GetShaderInfoLog
+#define glGetShaderPrecisionFormat pepper_opengl_interface->GetShaderPrecisionFormat
+#define glGetShaderSource pepper_opengl_interface->GetShaderSource
+#define glGetString pepper_opengl_interface->GetString
+#define glGetTexParameterfv pepper_opengl_interface->GetTexParameterfv
+#define glGetTexParameteriv pepper_opengl_interface->GetTexParameteriv
+#define glGetUniformfv pepper_opengl_interface->GetUniformfv
+#define glGetUniformiv pepper_opengl_interface->GetUniformiv
+#define glGetUniformLocation pepper_opengl_interface->GetUniformLocation
+#define glGetVertexAttribfv pepper_opengl_interface->GetVertexAttribfv
+#define glGetVertexAttribiv pepper_opengl_interface->GetVertexAttribiv
+#define glGetVertexAttribPointerv pepper_opengl_interface->GetVertexAttribPointerv
+#define glHint pepper_opengl_interface->Hint
+#define glIsBuffer pepper_opengl_interface->IsBuffer
+#define glIsEnabled pepper_opengl_interface->IsEnabled
+#define glIsFramebuffer pepper_opengl_interface->IsFramebuffer
+#define glIsProgram pepper_opengl_interface->IsProgram
+#define glIsRenderbuffer pepper_opengl_interface->IsRenderbuffer
+#define glIsShader pepper_opengl_interface->IsShader
+#define glIsTexture pepper_opengl_interface->IsTexture
+#define glLineWidth pepper_opengl_interface->LineWidth
+#define glLinkProgram pepper_opengl_interface->LinkProgram
+#define glPixelStorei pepper_opengl_interface->PixelStorei
+#define glPolygonOffset pepper_opengl_interface->PolygonOffset
+#define glReadPixels pepper_opengl_interface->ReadPixels
+#define glReleaseShaderCompiler pepper_opengl_interface->ReleaseShaderCompiler
+#define glRenderbufferStorage pepper_opengl_interface->RenderbufferStorage
+#define glSampleCoverage pepper_opengl_interface->SampleCoverage
+#define glScissor pepper_opengl_interface->Scissor
+#define glShaderBinary pepper_opengl_interface->ShaderBinary
+#define glShaderSource pepper_opengl_interface->ShaderSource
+#define glStencilFunc pepper_opengl_interface->StencilFunc
+#define glStencilFuncSeparate pepper_opengl_interface->StencilFuncSeparate
+#define glStencilMask pepper_opengl_interface->StencilMask
+#define glStencilMaskSeparate pepper_opengl_interface->StencilMaskSeparate
+#define glStencilOp pepper_opengl_interface->StencilOp
+#define glStencilOpSeparate pepper_opengl_interface->StencilOpSeparate
+#define glTexImage2D pepper_opengl_interface->TexImage2D
+#define glTexParameterf pepper_opengl_interface->TexParameterf
+#define glTexParameterfv pepper_opengl_interface->TexParameterfv
+#define glTexParameteri pepper_opengl_interface->TexParameteri
+#define glTexParameteriv pepper_opengl_interface->TexParameteriv
+#define glTexSubImage2D pepper_opengl_interface->TexSubImage2D
+#define glUniform1f pepper_opengl_interface->Uniform1f
+#define glUniform1fv pepper_opengl_interface->Uniform1fv
+#define glUniform1i pepper_opengl_interface->Uniform1i
+#define glUniform1iv pepper_opengl_interface->Uniform1iv
+#define glUniform2f pepper_opengl_interface->Uniform2f
+#define glUniform2fv pepper_opengl_interface->Uniform2fv
+#define glUniform2i pepper_opengl_interface->Uniform2i
+#define glUniform2iv pepper_opengl_interface->Uniform2iv
+#define glUniform3f pepper_opengl_interface->Uniform3f
+#define glUniform3fv pepper_opengl_interface->Uniform3fv
+#define glUniform3i pepper_opengl_interface->Uniform3i
+#define glUniform3iv pepper_opengl_interface->Uniform3iv
+#define glUniform4f pepper_opengl_interface->Uniform4f
+#define glUniform4fv pepper_opengl_interface->Uniform4fv
+#define glUniform4i pepper_opengl_interface->Uniform4i
+#define glUniform4iv pepper_opengl_interface->Uniform4iv
+#define glUniformMatrix2fv pepper_opengl_interface->UniformMatrix2fv
+#define glUniformMatrix3fv pepper_opengl_interface->UniformMatrix3fv
+#define glUniformMatrix4fv pepper_opengl_interface->UniformMatrix4fv
+#define glUseProgram pepper_opengl_interface->UseProgram
+#define glValidateProgram pepper_opengl_interface->ValidateProgram
+#define glVertexAttrib1f pepper_opengl_interface->VertexAttrib1f
+#define glVertexAttrib1fv pepper_opengl_interface->VertexAttrib1fv
+#define glVertexAttrib2f pepper_opengl_interface->VertexAttrib2f
+#define glVertexAttrib2fv pepper_opengl_interface->VertexAttrib2fv
+#define glVertexAttrib3f pepper_opengl_interface->VertexAttrib3f
+#define glVertexAttrib3fv pepper_opengl_interface->VertexAttrib3fv
+#define glVertexAttrib4f pepper_opengl_interface->VertexAttrib4f
+#define glVertexAttrib4fv pepper_opengl_interface->VertexAttrib4fv
+#define glVertexAttribPointer pepper_opengl_interface->VertexAttribPointer
+#define glViewport pepper_opengl_interface->Viewport
+
+#endif /* __gl2_h_ */
+
diff --git a/ppapi/GLES2/khrplatform.h b/ppapi/GLES2/khrplatform.h
new file mode 100644
index 0000000..8341f71b
--- /dev/null
+++ b/ppapi/GLES2/khrplatform.h
@@ -0,0 +1,269 @@
+#ifndef __khrplatform_h_
+#define __khrplatform_h_
+
+/*
+** Copyright (c) 2008-2009 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Khronos platform-specific types and definitions.
+ *
+ * $Revision: 7820 $ on $Date: 2009-04-03 13:46:26 -0700 (Fri, 03 Apr 2009) $
+ *
+ * Adopters may modify this file to suit their platform. Adopters are
+ * encouraged to submit platform specific modifications to the Khronos
+ * group so that they can be included in future versions of this file.
+ * Please submit changes by sending them to the public Khronos Bugzilla
+ * (http://khronos.org/bugzilla) by filing a bug against product
+ * "Khronos (general)" component "Registry".
+ *
+ * A predefined template which fills in some of the bug fields can be
+ * reached using http://tinyurl.com/khrplatform-h-bugreport, but you
+ * must create a Bugzilla login first.
+ *
+ *
+ * See the Implementer's Guidelines for information about where this file
+ * should be located on your system and for more details of its use:
+ * http://www.khronos.org/registry/implementers_guide.pdf
+ *
+ * This file should be included as
+ * #include <KHR/khrplatform.h>
+ * by Khronos client API header files that use its types and defines.
+ *
+ * The types in khrplatform.h should only be used to define API-specific types.
+ *
+ * Types defined in khrplatform.h:
+ * khronos_int8_t signed 8 bit
+ * khronos_uint8_t unsigned 8 bit
+ * khronos_int16_t signed 16 bit
+ * khronos_uint16_t unsigned 16 bit
+ * khronos_int32_t signed 32 bit
+ * khronos_uint32_t unsigned 32 bit
+ * khronos_int64_t signed 64 bit
+ * khronos_uint64_t unsigned 64 bit
+ * khronos_intptr_t signed same number of bits as a pointer
+ * khronos_uintptr_t unsigned same number of bits as a pointer
+ * khronos_ssize_t signed size
+ * khronos_usize_t unsigned size
+ * khronos_float_t signed 32 bit floating point
+ * khronos_time_ns_t unsigned 64 bit time in nanoseconds
+ * khronos_utime_nanoseconds_t unsigned time interval or absolute time in
+ * nanoseconds
+ * khronos_stime_nanoseconds_t signed time interval in nanoseconds
+ * khronos_boolean_enum_t enumerated boolean type. This should
+ * only be used as a base type when a client API's boolean type is
+ * an enum. Client APIs which use an integer or other type for
+ * booleans cannot use this as the base type for their boolean.
+ *
+ * Tokens defined in khrplatform.h:
+ *
+ * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
+ *
+ * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
+ * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
+ *
+ * Calling convention macros defined in this file:
+ * KHRONOS_APICALL
+ * KHRONOS_APIENTRY
+ * KHRONOS_APIATTRIBUTES
+ *
+ * These may be used in function prototypes as:
+ *
+ * KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
+ * int arg1,
+ * int arg2) KHRONOS_APIATTRIBUTES;
+ */
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APICALL
+ *-------------------------------------------------------------------------
+ * This precedes the return type of the function in the function prototype.
+ */
+#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
+# define KHRONOS_APICALL __declspec(dllimport)
+#elif defined (__SYMBIAN32__)
+# define KHRONOS_APICALL IMPORT_C
+#else
+# define KHRONOS_APICALL
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIENTRY
+ *-------------------------------------------------------------------------
+ * This follows the return type of the function and precedes the function
+ * name in the function prototype.
+ */
+#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
+ /* Win32 but not WinCE */
+# define KHRONOS_APIENTRY __stdcall
+#else
+# define KHRONOS_APIENTRY
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIATTRIBUTES
+ *-------------------------------------------------------------------------
+ * This follows the closing parenthesis of the function prototype arguments.
+ */
+#if defined (__ARMCC_2__)
+#define KHRONOS_APIATTRIBUTES __softfp
+#else
+#define KHRONOS_APIATTRIBUTES
+#endif
+
+/*-------------------------------------------------------------------------
+ * basic type definitions
+ *-----------------------------------------------------------------------*/
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
+
+
+/*
+ * Using <stdint.h>
+ */
+#include <stdint.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__VMS ) || defined(__sgi)
+
+/*
+ * Using <inttypes.h>
+ */
+#include <inttypes.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
+
+/*
+ * Win32
+ */
+typedef __int32 khronos_int32_t;
+typedef unsigned __int32 khronos_uint32_t;
+typedef __int64 khronos_int64_t;
+typedef unsigned __int64 khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__sun__) || defined(__digital__)
+
+/*
+ * Sun or Digital
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#if defined(__arch64__) || defined(_LP64)
+typedef long int khronos_int64_t;
+typedef unsigned long int khronos_uint64_t;
+#else
+typedef long long int khronos_int64_t;
+typedef unsigned long long int khronos_uint64_t;
+#endif /* __arch64__ */
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif 0
+
+/*
+ * Hypothetical platform with no float or int64 support
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#define KHRONOS_SUPPORT_INT64 0
+#define KHRONOS_SUPPORT_FLOAT 0
+
+#else
+
+/*
+ * Generic fallback
+ */
+#include <stdint.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#endif
+
+
+/*
+ * Types that are (so far) the same on all platforms
+ */
+typedef signed char khronos_int8_t;
+typedef unsigned char khronos_uint8_t;
+typedef signed short int khronos_int16_t;
+typedef unsigned short int khronos_uint16_t;
+typedef signed long int khronos_intptr_t;
+typedef unsigned long int khronos_uintptr_t;
+typedef signed long int khronos_ssize_t;
+typedef unsigned long int khronos_usize_t;
+
+#if KHRONOS_SUPPORT_FLOAT
+/*
+ * Float type
+ */
+typedef float khronos_float_t;
+#endif
+
+#if KHRONOS_SUPPORT_INT64
+/* Time types
+ *
+ * These types can be used to represent a time interval in nanoseconds or
+ * an absolute Unadjusted System Time. Unadjusted System Time is the number
+ * of nanoseconds since some arbitrary system event (e.g. since the last
+ * time the system booted). The Unadjusted System Time is an unsigned
+ * 64 bit value that wraps back to 0 every 584 years. Time intervals
+ * may be either signed or unsigned.
+ */
+typedef khronos_uint64_t khronos_utime_nanoseconds_t;
+typedef khronos_int64_t khronos_stime_nanoseconds_t;
+#endif
+
+/*
+ * Dummy value used to pad enum types to 32 bits.
+ */
+#ifndef KHRONOS_MAX_ENUM
+#define KHRONOS_MAX_ENUM 0x7FFFFFFF
+#endif
+
+/*
+ * Enumerated boolean type
+ *
+ * Values other than zero should be considered to be true. Therefore
+ * comparisons should not be made against KHRONOS_TRUE.
+ */
+typedef enum {
+ KHRONOS_FALSE = 0,
+ KHRONOS_TRUE = 1,
+ KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
+} khronos_boolean_enum_t;
+
+#endif /* __khrplatform_h_ */
diff --git a/ppapi/LICENSE b/ppapi/LICENSE
new file mode 100644
index 0000000..8dc3504
--- /dev/null
+++ b/ppapi/LICENSE
@@ -0,0 +1,27 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/ppapi/c/dev/pp_cursor_type_dev.h b/ppapi/c/dev/pp_cursor_type_dev.h
new file mode 100644
index 0000000..b7a113a
--- /dev/null
+++ b/ppapi/c/dev/pp_cursor_type_dev.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PP_CURSORTYPE_DEV_H_
+#define PPAPI_C_DEV_PP_CURSORTYPE_DEV_H_
+
+enum PP_CursorType_Dev {
+ PP_CURSORTYPE_POINTER = 0,
+ PP_CURSORTYPE_CROSS = 1,
+ PP_CURSORTYPE_HAND = 2,
+ PP_CURSORTYPE_IBEAM = 3,
+ PP_CURSORTYPE_WAIT = 4,
+ PP_CURSORTYPE_HELP = 5,
+ PP_CURSORTYPE_EASTRESIZE = 6,
+ PP_CURSORTYPE_NORTHRESIZE = 7,
+ PP_CURSORTYPE_NORTHEASTRESIZE = 8,
+ PP_CURSORTYPE_NORTHWESTRESIZE = 9,
+ PP_CURSORTYPE_SOUTHRESIZE = 10,
+ PP_CURSORTYPE_SOUTHEASTRESIZE = 11,
+ PP_CURSORTYPE_SOUTHWESTRESIZE = 12,
+ PP_CURSORTYPE_WESTRESIZE = 13,
+ PP_CURSORTYPE_NORTHSOUTHRESIZE = 14,
+ PP_CURSORTYPE_EASTWESTRESIZE = 15,
+ PP_CURSORTYPE_NORTHEASTSOUTHWESTRESIZE = 16,
+ PP_CURSORTYPE_NORTHWESTSOUTHEASTRESIZE = 17,
+ PP_CURSORTYPE_COLUMNRESIZE = 18,
+ PP_CURSORTYPE_ROWRESIZE = 19,
+ PP_CURSORTYPE_MIDDLEPANNING = 20,
+ PP_CURSORTYPE_EASTPANNING = 21,
+ PP_CURSORTYPE_NORTHPANNING = 22,
+ PP_CURSORTYPE_NORTHEASTPANNING = 23,
+ PP_CURSORTYPE_NORTHWESTPANNING = 24,
+ PP_CURSORTYPE_SOUTHPANNING = 25,
+ PP_CURSORTYPE_SOUTHEASTPANNING = 26,
+ PP_CURSORTYPE_SOUTHWESTPANNING = 27,
+ PP_CURSORTYPE_WESTPANNING = 28,
+ PP_CURSORTYPE_MOVE = 29,
+ PP_CURSORTYPE_VERTICALTEXT = 30,
+ PP_CURSORTYPE_CELL = 31,
+ PP_CURSORTYPE_CONTEXTMENU = 32,
+ PP_CURSORTYPE_ALIAS = 33,
+ PP_CURSORTYPE_PROGRESS = 34,
+ PP_CURSORTYPE_NODROP = 35,
+ PP_CURSORTYPE_COPY = 36,
+ PP_CURSORTYPE_NONE = 37,
+ PP_CURSORTYPE_NOTALLOWED = 38,
+ PP_CURSORTYPE_ZOOMIN = 39,
+ PP_CURSORTYPE_ZOOMOUT = 40,
+ PP_CURSORTYPE_CUSTOM = 41
+};
+
+#endif // PPAPI_C_DEV_PP_CURSORTYPE_DEV_H_
diff --git a/ppapi/c/dev/pp_file_info_dev.h b/ppapi/c/dev/pp_file_info_dev.h
new file mode 100644
index 0000000..c1e1a07
--- /dev/null
+++ b/ppapi/c/dev/pp_file_info_dev.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PP_FILE_INFO_DEV_H_
+#define PPAPI_C_DEV_PP_FILE_INFO_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_time.h"
+
+typedef enum {
+ PP_FILETYPE_REGULAR,
+ PP_FILETYPE_DIRECTORY,
+ PP_FILETYPE_OTHER // A catch-all for unidentified types.
+} PP_FileType_Dev;
+
+typedef enum {
+ PP_FILESYSTEMTYPE_EXTERNAL,
+ PP_FILESYSTEMTYPE_LOCALPERSISTENT,
+ PP_FILESYSTEMTYPE_LOCALTEMPORARY
+} PP_FileSystemType_Dev;
+
+struct PP_FileInfo_Dev {
+ int64_t size; // Measured in bytes
+ PP_FileType_Dev type;
+ PP_FileSystemType_Dev system_type;
+ PP_Time creation_time;
+ PP_Time last_access_time;
+ PP_Time last_modified_time;
+};
+
+#endif // PPAPI_C_DEV_PP_FILE_INFO_DEV_H_
diff --git a/ppapi/c/dev/pp_video_dev.h b/ppapi/c/dev/pp_video_dev.h
new file mode 100644
index 0000000..92b9f37
--- /dev/null
+++ b/ppapi/c/dev/pp_video_dev.h
@@ -0,0 +1,290 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PP_VIDEO_DEV_H_
+#define PPAPI_C_DEV_PP_VIDEO_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+enum PP_VideoKey_Dev {
+ PP_VIDEOKEY_NONE = 0,
+ // Value is type of PP_VideoCodecId.
+ PP_VIDEOKEY_CODECID,
+ // Value is type of PP_VideoOperation.
+ PP_VIDEOKEY_OPERATION,
+ // Value is type of PP_VideoCodecProfile.
+ PP_VIDEOKEY_CODECPROFILE,
+ // Value is type of PP_VideoCodecLevel.
+ PP_VIDEOKEY_CODECLEVEL,
+ // Value is 0 or 1.
+ PP_VIDEOKEY_ACCELERATION,
+ // Value is type of PP_VideoPayloadFormat.
+ PP_VIDEOKEY_PAYLOADFORMAT,
+ // Value is type of PP_VideoFrameColorType.
+ PP_VIDEOKEY_COLORTYPE,
+ // Value is type of PP_VideoFrameSurfaceType.
+ PP_VIDEOKEY_SURFACETYPE,
+ // Value is type of PP_VideoFrameInfoFlag.
+ PP_VIDEOKEY_FRAMEINFOFLAG,
+
+ // Subset for H.264 features, value of 1 means supported. This is needed in
+ // case decoder has partial support for certain profile.
+ PP_VIDEOKEY_H264FEATURE_FMO = 0x100,
+ PP_VIDEOKEY_H264FEATURE_ASO,
+ PP_VIDEOKEY_H264FEATURE_INTERLACE,
+ PP_VIDEOKEY_H264FEATURE_CABAC,
+ PP_VIDEOKEY_H264FEATURE_WEIGHTEDPREDICTION
+};
+
+enum PP_VideoDecoderEvent_Dev {
+ PP_VIDEODECODEREVENT_NONE = 0,
+ // Signaling that an error has been hit.
+ PP_VIDEODECODEREVENT_ERROR,
+ // Signaling new width/height of video frame
+ PP_VIDEODECODEREVENT_NEWDIMENSION,
+ // Signaling new cropping rectangle
+ PP_VIDEODECODEREVENT_NEWCROP
+};
+
+enum PP_VideoDecodeError_Dev {
+ PP_VIDEODECODEERROR_NONE = 0,
+ PP_VIDEODECODEERROR_NOTSUPPORTED,
+ PP_VIDEODECODEERROR_INSUFFICIENTRESOURCES,
+ PP_VIDEODECODEERROR_UNDEFINED,
+ PP_VIDEODECODEERROR_BADINPUT,
+ PP_VIDEODECODEERROR_HARDWARE
+};
+
+enum PP_VideoCodecId_Dev {
+ PP_VIDEODECODECID_NONE = 0,
+ PP_VIDEODECODECID_H264,
+ PP_VIDEODECODECID_VC1,
+ PP_VIDEODECODECID_MPEG2,
+ PP_VIDEODECODECID_VP8
+};
+
+enum PP_VideoOperation_Dev {
+ PP_VIDEOOPERATION_NONE = 0,
+ PP_VIDEOOPERATION_DECODE,
+ PP_VIDEOOPERATION_ENCODE
+};
+
+enum PP_VideoCodecProfile_Dev {
+ PP_VIDEOCODECPROFILE_NONE = 0,
+ PP_VIDEOCODECPROFILE_H264_BASELINE,
+ PP_VIDEOCODECPROFILE_H264_MAIN,
+ PP_VIDEOCODECPROFILE_H264_EXTENDED,
+ PP_VIDEOCODECPROFILE_H264_HIGH,
+ PP_VIDEOCODECPROFILE_H264_SCALABLEBASELINE,
+ PP_VIDEOCODECPROFILE_H264_SCALABLEHIGH,
+ PP_VIDEOCODECPROFILE_H264_STEREOHIGH,
+ PP_VIDEOCODECPROFILE_H264_MULTIVIEWHIGH,
+
+ PP_VIDEOCODECPROFILE_VC1_SIMPLE = 0x40,
+ PP_VIDEOCODECPROFILE_VC1_MAIN,
+ PP_VIDEOCODECPROFILE_VC1_ADVANCED,
+
+ PP_VIDEOCODECPROFILE_MPEG2_SIMPLE = 0x80,
+ PP_VIDEOCODECPROFILE_MPEG2_MAIN,
+ PP_VIDEOCODECPROFILE_MPEG2_SNR,
+ PP_VIDEOCODECPROFILE_MPEG2_SPATIAL,
+ PP_VIDEOCODECPROFILE_MPEG2_HIGH
+};
+
+enum PP_VideoCodecLevel_Dev {
+ PP_VIDEOCODECLEVEL_NONE = 0,
+ PP_VIDEOCODECLEVEL_H264_10,
+ PP_VIDEOCODECLEVEL_H264_1B,
+ PP_VIDEOCODECLEVEL_H264_11,
+ PP_VIDEOCODECLEVEL_H264_12,
+ PP_VIDEOCODECLEVEL_H264_13,
+ PP_VIDEOCODECLEVEL_H264_20,
+ PP_VIDEOCODECLEVEL_H264_21,
+ PP_VIDEOCODECLEVEL_H264_22,
+ PP_VIDEOCODECLEVEL_H264_30,
+ PP_VIDEOCODECLEVEL_H264_31,
+ PP_VIDEOCODECLEVEL_H264_32,
+ PP_VIDEOCODECLEVEL_H264_40,
+ PP_VIDEOCODECLEVEL_H264_41,
+ PP_VIDEOCODECLEVEL_H264_42,
+ PP_VIDEOCODECLEVEL_H264_50,
+ PP_VIDEOCODECLEVEL_H264_51,
+
+ PP_VIDEOCODECLEVEL_VC1_LOW = 0x40,
+ PP_VIDEOCODECLEVEL_VC1_MEDIUM,
+ PP_VIDEOCODECLEVEL_VC1_HIGH,
+ PP_VIDEOCODECLEVEL_VC1_L0,
+ PP_VIDEOCODECLEVEL_VC1_L1,
+ PP_VIDEOCODECLEVEL_VC1_L2,
+ PP_VIDEOCODECLEVEL_VC1_L3,
+ PP_VIDEOCODECLEVEL_VC1_L4,
+
+ PP_VIDEOCODECLEVEL_MPEG2_LOW = 0x80,
+ PP_VIDEOCODECLEVEL_MPEG2_MAIN,
+ PP_VIDEOCODECLEVEL_MPEG2_HIGH1440,
+ PP_VIDEOCODECLEVEL_MPEG2_HIGH
+};
+
+enum PP_VideoPayloadFormat_Dev {
+ PP_VIDEOPAYLOADFORMAT_NONE = 0,
+ PP_VIDEOPAYLOADFORMAT_BYTESTREAM,
+ PP_VIDEOPAYLOADFORMAT_RTPPAYLOAD
+};
+
+enum PP_VideoFrameColorType_Dev {
+ PP_VIDEOFRAMECOLORTYPE_NONE = 0,
+ PP_VIDEOFRAMECOLORTYPE_RGB565,
+ PP_VIDEOFRAMECOLORTYPE_ARGB8888,
+ PP_VIDEOFRAMECOLORTYPE_YUV,
+ PP_VIDEOFRAMECOLORTYPE_Monochrome,
+ PP_VIDEOFRAMECOLORTYPE_YUV420PLANAR,
+ PP_VIDEOFRAMECOLORTYPE_YUV422PLANAR,
+ PP_VIDEOFRAMECOLORTYPE_YUV444PLANAR
+};
+
+enum PP_VideoFrameSurfaceType_Dev {
+ PP_VIDEOFRAMESURFACETYPE_NONE = 0,
+ PP_VIDEOFRAMESURFACETYPE_SYSTEMMEMORY,
+ PP_VIDEOFRAMESURFACETYPE_GLTEXTURE,
+ PP_VIDEOFRAMESURFACETYPE_PIXMAP
+};
+
+enum PP_VideoFrameInfoFlag_Dev {
+ PP_VIDEOFRAMEINFOFLAG_NONE = 0,
+ // Indicate this is the end of stream. Used by both plugin and browser.
+ PP_VIDEOFRAMEINFOFLAG_EOS = 1 << 0,
+ // Decode the frame only, don't return decoded frame. Used by plugin.
+ PP_VIDEOFRAMEINFOFLAG_NOEMIT = 1 << 1,
+ // Indicate this is an anchor frame. Used by plugin.
+ PP_VIDEOFRAMEINFOFLAG_SYNCFRAME = 1 << 2,
+ // Indicate the decoded frame has data corruption. Used by browser.
+ PP_VIDEOFRAMEINFOFLAG_DATACORRUPT = 1 << 3
+};
+
+enum PP_VideoFrameBufferConst_Dev {
+ // YUV formats
+ PP_VIDEOFRAMEBUFFER_YPLANE = 0,
+ PP_VIDEOFRAMEBUFFER_UPLANE = 1,
+ PP_VIDEOFRAMEBUFFER_VPLANE = 2,
+ PP_VIDEOFRAMEBUFFER_NUMBERYUVPLANES = 3,
+
+ // RGBA formats
+ PP_VIDEOFRAMEBUFFER_RGBAPLANE = 0,
+ PP_VIDEOFRAMEBUFFER_NUMBERRGBAPLANES = 1,
+
+ PP_VIDEOFRAMEBUFFER_MAXNUMBERPLANES = 4
+};
+
+typedef int64_t PP_VideoDecodeData_Dev;
+
+// Array of key/value pairs describing video configuration.
+// It could include any keys from PP_VideoKey. Its last element shall be
+// PP_VIDEOKEY_NONE with no corresponding value.
+// An example:
+// {
+// PP_VIDEOKEY_CODECID, PP_VIDEODECODECID_H264,
+// PP_VIDEOKEY_OPERATION, PP_VIDEOOPERATION_DECODE,
+// PP_VIDEOKEY_CODECPROFILE, PP_VIDEOCODECPROFILE_H264_HIGH,
+// PP_VIDEOKEY_CODECLEVEL, PP_VIDEOCODECLEVEL_H264_41,
+// PP_VIDEOKEY_ACCELERATION, 1
+// PP_VIDEOKEY_NONE,
+// };
+typedef int32_t* PP_VideoConfig_Dev;
+typedef int32_t PP_VideoConfigElement_Dev;
+
+// The data structure for compressed data buffer.
+struct PP_VideoCompressedDataBuffer_Dev {
+ // The buffer is created through PPB_Buffer API.
+ // TODO(wjia): would uint8_t* be good, too?
+ PP_Resource buffer;
+ // number of bytes with real data in the buffer.
+ int32_t filled_size;
+
+ // Time stamp of the frame in microsecond.
+ uint64_t time_stamp_us;
+
+ // Bit mask of PP_VideoFrameInfoFlag.
+ uint32_t flags;
+};
+
+struct PP_VideoFrameBuffer_Dev {
+ union {
+ struct {
+ int32_t planes;
+ struct {
+ int32_t width;
+ int32_t height;
+ int32_t stride;
+
+ // TODO(wjia): uint8* would be better for some cases.
+ PP_Resource buffer;
+ } data_plane[PP_VIDEOFRAMEBUFFER_MAXNUMBERPLANES];
+ } sys_mem;
+
+ // Handle for pixmap, gl texture, etc.
+ void* handle;
+ } buffer;
+
+ // Storage for decoder to save some private data. It could be useful when
+ // plugin returns frame buffer to decoder.
+ void* private_handle;
+};
+
+struct PP_VideoUncompressedDataBuffer_Dev {
+ PP_VideoConfig_Dev format;
+ struct PP_VideoFrameBuffer_Dev buffer;
+
+ // Time stamp of the frame in microsecond.
+ uint64_t time_stamp_us;
+
+ // Bit mask of PP_VideoFrameInfoFlag.
+ uint32_t flags;
+
+ // Output from decoder, indicating the decoded frame has error pixels. This
+ // could be resulted from corrupted input bit stream and error concealment
+ // in decoding.
+ // TODO(wjia): add more info about error pixels, such as error MB map, etc.
+ bool has_error;
+};
+
+// Plugin callback for decoder to deliver decoded frame buffers.
+// |format| in |buffer| specifies the format of decoded frame, with
+// PP_VIDEOKEY_COLORTYPE and PP_VIDEOKEY_SURFACETYPE required.
+typedef void (*PP_VideoDecodeOutputCallback_Func_Dev)(
+ PP_Instance instance,
+ struct PP_VideoUncompressedDataBuffer_Dev* buffer);
+
+// Plugin callback for decoder to return input data buffers.
+// Plugin can optionally provide this callback only when it wants to recycle
+// input data buffers.
+typedef void (*PP_VideoDecodeInputCallback_Func_Dev)(
+ PP_Instance instance,
+ struct PP_VideoCompressedDataBuffer_Dev* buffer);
+
+// Event handling Function for decoder to deliver events to plugin.
+// The correspondence between event and data1, data2:
+// When event == PP_VIDEODECODEREVENT_ERROR,
+// data1 is type of PP_VideoDecodeError id and data2 is ignored;
+// When event == PP_VIDEODECODEREVENT_NEWDIMENSION,
+// data1 is type of PP_Size*, data2 is ignored;
+// When event == PP_VIDEODECODEREVENT_NEWCROP,
+// data1 is type of PP_Rect*, data2 is ignored;
+typedef void (*PP_VideoDecodeEventHandler_Func_Dev)(
+ PP_Instance instance,
+ PP_VideoDecoderEvent_Dev event,
+ PP_VideoDecodeData_Dev data1,
+ PP_VideoDecodeData_Dev data2);
+
+// Requested decoder configuration and callback from plugin.
+struct PP_VideoDecoderConfig_Dev {
+ PP_VideoConfig_Dev input_format;
+ PP_VideoConfig_Dev output_format;
+ PP_VideoDecodeOutputCallback_Func_Dev output_callback;
+ PP_VideoDecodeInputCallback_Func_Dev input_callback;
+ PP_VideoDecodeEventHandler_Func_Dev event_handler;
+};
+
+#endif // PPAPI_C_DEV_PP_VIDEO_DEV_H_
diff --git a/ppapi/c/dev/ppb_audio_config_dev.h b/ppapi/c/dev/ppb_audio_config_dev.h
new file mode 100644
index 0000000..01079a9
--- /dev/null
+++ b/ppapi/c/dev/ppb_audio_config_dev.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_AUDIO_CONFIG_DEV_H_
+#define PPAPI_C_DEV_PPB_AUDIO_CONFIG_DEV_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+#define PPB_AUDIO_CONFIG_DEV_INTERFACE "PPB_AudioConfig(Dev);0.2"
+
+enum {
+ PP_AUDIOMINSAMPLEFRAMECOUNT = 64,
+ PP_AUDIOMAXSAMPLEFRAMECOUNT = 32768
+};
+
+typedef enum {
+ PP_AUDIOSAMPLERATE_NONE = 0,
+ PP_AUDIOSAMPLERATE_44100 = 44100,
+ PP_AUDIOSAMPLERATE_48000 = 48000
+} PP_AudioSampleRate_Dev;
+
+/**
+ * Audio configuration. This base configuration interface supports only stereo
+ * 16bit output. This class is not mutable, therefore it is okay to access
+ * instances from different threads.
+ */
+struct PPB_AudioConfig_Dev {
+ /**
+ * Create a 16 bit stereo config with the given sample rate. We guarantee
+ * that PP_AUDIOSAMPLERATE_44100 and PP_AUDIOSAMPLERATE_48000 sample rates
+ * are supported. The |sample_frame_count| should be the result of calling
+ * RecommendSampleFrameCount. If the sample frame count or bit rate aren't
+ * supported, this function will fail and return a null resource.
+ *
+ * A single sample frame on a stereo device means one value for the left
+ * channel and one value for the right channel.
+ *
+ * Buffer layout for a stereo int16 configuration:
+ * int16_t *buffer16;
+ * buffer16[0] is the first left channel sample
+ * buffer16[1] is the first right channel sample
+ * buffer16[2] is the second left channel sample
+ * buffer16[3] is the second right channel sample
+ * ...
+ * buffer16[2 * (sample_frame_count - 1)] is the last left channel sample
+ * buffer16[2 * (sample_frame_count - 1) + 1] is the last right channel sample
+ * Data will always be in the native endian format of the platform.
+ */
+ PP_Resource (*CreateStereo16Bit)(PP_Module module,
+ PP_AudioSampleRate_Dev sample_rate,
+ uint32_t sample_frame_count);
+
+ /*
+ * Returns a supported sample frame count closest to the given requested
+ * count. The sample frame count determines the overall latency of audio.
+ * Since one "frame" is always buffered in advance, smaller frame counts
+ * will yield lower latency, but higher CPU utilization.
+ *
+ * Supported sample frame counts will vary by hardware and system (consider
+ * that the local system might be anywhere from a cell phone or a high-end
+ * audio workstation). Sample counts less than PP_AUDIOMINSAMPLEFRAMECOUNT
+ * and greater than PP_AUDIOMAXSAMPLEFRAMECOUNT are never supported on any
+ * system, but values in between aren't necessarily valid. This function
+ * will return a supported count closest to the requested value.
+ *
+ * If you pass 0 as the requested sample count, the recommended sample for
+ * the local system is returned.
+ */
+ uint32_t (*RecommendSampleFrameCount)(uint32_t requested_sample_frame_count);
+
+ /**
+ * Returns true if the given resource is an AudioConfig object.
+ */
+ bool (*IsAudioConfig)(PP_Resource resource);
+
+ /**
+ * Returns the sample rate for the given AudioConfig resource. If the
+ * resource is invalid, this will return PP_AUDIOSAMPLERATE_NONE.
+ */
+ PP_AudioSampleRate_Dev (*GetSampleRate)(PP_Resource config);
+
+ /**
+ * Returns the sample frame count for the given AudioConfig resource. If the
+ * resource is invalid, this will return 0. See RecommendSampleFrameCount for
+ * more on sample frame counts.
+ */
+ uint32_t (*GetSampleFrameCount)(PP_Resource config);
+};
+
+#endif // PPAPI_C_DEV_PPB_AUDIO_CONFIG_DEV_H_
+
diff --git a/ppapi/c/dev/ppb_audio_dev.h b/ppapi/c/dev/ppb_audio_dev.h
new file mode 100644
index 0000000..cc567414
--- /dev/null
+++ b/ppapi/c/dev/ppb_audio_dev.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_AUDIO_DEV_H_
+#define PPAPI_C_DEV_PPB_AUDIO_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+#define PPB_AUDIO_DEV_INTERFACE "PPB_Audio(Dev);0.2"
+
+// Callback function type for SetCallback.
+typedef void (*PPB_Audio_Callback)(void* sample_buffer,
+ size_t buffer_size_in_bytes,
+ void* user_data);
+
+// Callback-based audio interface. User of audio must set the callback that will
+// be called each time that the buffer needs to be filled.
+//
+// A C++ example:
+//
+// void audio_callback(void* sample_buffer,
+// size_t buffer_size_in_bytes,
+// void* user_data) {
+// ... fill in the buffer with samples ...
+// }
+//
+// uint32_t obtained;
+// AudioConfig config(PP_AUDIOSAMPLERATE_44100, 4096, &obtained);
+// Audio audio(config, audio_callback, NULL);
+// audio.StartPlayback();
+//
+struct PPB_Audio_Dev {
+ // Creates a paused audio interface. No sound will be heard until
+ // StartPlayback() is called. The callback is called with the buffer address
+ // and given user data whenever the buffer needs to be filled. From within the
+ // callback, you should not call PPB_Audio functions. The callback will be
+ // called on a different thread than the one which created the interface. For
+ // performance-critical applications (i.e. low-latency audio), the callback
+ // should avoid blocking or calling functions that can obtain locks, such as
+ // malloc. The layout and the size of the buffer passed to the audio callback
+ // will be determined by the device configuration and is specified in the
+ // AudioConfig documentation. If the configuration cannot be honored, or the
+ // callback is null, the function returns 0.
+ PP_Resource (*Create)(PP_Instance instance, PP_Resource config,
+ PPB_Audio_Callback audio_callback, void* user_data);
+
+ /**
+ * Returns true if the given resource is an Audio resource.
+ */
+ bool (*IsAudio)(PP_Resource resource);
+
+ // Get the current configuration.
+ PP_Resource (*GetCurrentConfig)(PP_Resource audio);
+
+ // Start the playback. Begin periodically calling the callback. If called
+ // while playback is already in progress, will return true and be a no-op.
+ // On error, return false.
+ bool (*StartPlayback)(PP_Resource audio);
+
+ // Stop the playback. If playback is already stopped, this is a no-op and
+ // returns true. On error, returns false. If a callback is in progress,
+ // StopPlayback will block until callback completes.
+ bool (*StopPlayback)(PP_Resource audio);
+};
+
+#endif // PPAPI_C_DEV_PPB_DEVICE_CONTEXT_AUDIO_DEV_H_
+
diff --git a/ppapi/c/dev/ppb_audio_trusted_dev.h b/ppapi/c/dev/ppb_audio_trusted_dev.h
new file mode 100644
index 0000000..acb883f
--- /dev/null
+++ b/ppapi/c/dev/ppb_audio_trusted_dev.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_AUDIO_TRUSTED_DEV_H_
+#define PPAPI_C_DEV_PPB_AUDIO_TRUSTED_DEV_H_
+
+#include "ppapi/c/pp_resource.h"
+
+#define PPB_AUDIO_TRUSTED_DEV_INTERFACE "PPB_AudioTrusted(Dev);0.1"
+
+// This interface is used to get access to the audio buffer and a socket on
+// which the client can block until the audio is ready to accept more data.
+// This interface should be used by NaCl to implement the Audio interface.
+struct PPB_AudioTrusted_Dev {
+ // Returns a Buffer object that has the audio buffer.
+ PP_Resource (*GetBuffer)(PP_Resource audio);
+
+ // Returns a select()-able/Wait()-able OS-specific descriptor. The browser
+ // will put a byte on the socket each time the buffer is ready to be filled.
+ // The plugin can then implement its own audio thread using select()/poll() to
+ // block until the browser is ready to receive data.
+ int (*GetOSDescriptor)(PP_Resource audio);
+};
+
+#endif // PPAPI_C_DEV_PPB_AUDIO_TRUSTED_DEV_H_
+
diff --git a/ppapi/c/dev/ppb_buffer_dev.h b/ppapi/c/dev/ppb_buffer_dev.h
new file mode 100644
index 0000000..416ab0b
--- /dev/null
+++ b/ppapi/c/dev/ppb_buffer_dev.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_BUFFER_DEV_H_
+#define PPAPI_C_DEV_PPB_BUFFER_DEV_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+#define PPB_BUFFER_DEV_INTERFACE "PPB_Buffer(Dev);0.1"
+
+struct PPB_Buffer_Dev {
+ // Allocates a buffer of the given size in bytes. The return value will have
+ // a non-zero ID on success, or zero on failure. Failure means the module
+ // handle was invalid. The buffer will be initialized to contain zeroes.
+ PP_Resource (*Create)(PP_Module module, int32_t size_in_bytes);
+
+ // Returns true if the given resource is a Buffer. Returns false if the
+ // resource is invalid or some type other than a Buffer.
+ bool (*IsBuffer)(PP_Resource resource);
+
+ // Gets the size of the buffer. Returns true on success, false
+ // if the resource is not a buffer. On failure, |*size_in_bytes| is not set.
+ bool (*Describe)(PP_Resource resource, int32_t* size_in_bytes);
+
+ // Maps this buffer into the plugin address space and returns a pointer to the
+ // beginning of the data.
+ void* (*Map)(PP_Resource resource);
+
+ void (*Unmap)(PP_Resource resource);
+};
+
+#endif // PPAPI_C_DEV_PPB_BUFFER_DEV_H_
+
diff --git a/ppapi/c/dev/ppb_char_set_dev.h b/ppapi/c/dev/ppb_char_set_dev.h
new file mode 100644
index 0000000..382e1a8
--- /dev/null
+++ b/ppapi/c/dev/ppb_char_set_dev.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_CHAR_SET_DEV_H_
+#define PPAPI_C_DEV_PPB_CHAR_SET_DEV_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_CHAR_SET_DEV_INTERFACE "PPB_CharSet(Dev);0.1"
+
+// Specifies the error behavior for the character set conversion functions.
+// This will affect two cases: where the input is not encoded correctly, and
+// when the requested character can not be converted to the destination
+// character set.
+enum PP_CharSet_ConversionError {
+ // Causes the entire conversion to fail if an error is encountered. The
+ // conversion function will return NULL.
+ PP_CHARSET_CONVERSIONERROR_FAIL,
+
+ // Silently skips over errors. Unrepresentable characters and input encoding
+ // errors will be removed from the output.
+ PP_CHARSET_CONVERSIONERROR_SKIP,
+
+ // Replaces the error or unrepresentable character with a substitution
+ // character. When converting to a Unicode character set (UTF-8 or UTF-16)
+ // it will use the unicode "substitution character" U+FFFD. When converting
+ // to another character set, the character will be charset-specific. For
+ // many languages this will be the representation of the '?' character.
+ PP_CHARSET_CONVERSIONERROR_SUBSTITUTE,
+};
+
+struct PPB_CharSet_Dev {
+ // Converts the UTF-16 string pointed to in |*utf16| to an 8-bit string in the
+ // specified code page. |utf16_len| is measured in UTF-16 units, not bytes.
+ // This value may not be NULL.
+ //
+ // The return value is a NULL-terminated 8-bit string corresponding to the
+ // new character set, or NULL on failure. THIS STRING MUST BE FREED USING
+ // PPB_Core::MemFree(). The length of the returned string, not including the
+ // terminating NULL, will be placed into *output_length. When there is no
+ // error, the result will always be non-NULL, even if the output is 0-length.
+ // In this case, it will only contain the terminator. You must still call
+ // MemFree any time the return value is non-NULL.
+ //
+ // This function will return NULL if there was an error converting the string
+ // and you requested PP_CHARSET_CONVERSIONERROR_FAIL, or the output character
+ // set was unknown.
+ char* (*UTF16ToCharSet)(const uint16_t* utf16, uint32_t utf16_len,
+ const char* output_char_set,
+ PP_CharSet_ConversionError on_error,
+ uint32_t* output_length);
+
+ // Same as UTF16ToCharSet except converts in the other direction. The input
+ // is in the given charset, and the |input_len| is the number of bytes in
+ // the |input| string. |*output_length| is the number of 16-bit values in
+ // the output not counting the terminating NULL.
+ //
+ // Since UTF16 can represent every Unicode character, the only time the
+ // replacement character will be used is if the encoding in the input string
+ // is incorrect.
+ uint16_t* (*CharSetToUTF16)(const char* input, uint32_t input_len,
+ const char* input_char_set,
+ PP_CharSet_ConversionError on_error,
+ uint32_t* output_length);
+
+ // Returns a string var representing the current multi-byte character set of
+ // the current system.
+ //
+ // WARNING: You really shouldn't be using this function unless you're dealing
+ // with legacy data. You should be using UTF-8 or UTF-16 and you don't have
+ // to worry about the character sets.
+ PP_Var (*GetDefaultCharSet)(PP_Module module);
+};
+
+#endif // PPAPI_C_DEV_PPB_CHAR_SET_DEV_H_
diff --git a/ppapi/c/dev/ppb_cursor_control_dev.h b/ppapi/c/dev/ppb_cursor_control_dev.h
new file mode 100644
index 0000000..7a38767
--- /dev/null
+++ b/ppapi/c/dev/ppb_cursor_control_dev.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_CURSOR_CONTROL_DEV_H_
+#define PPAPI_C_DEV_PPB_CURSOR_CONTROL_DEV_H_
+
+#include "ppapi/c/dev/pp_cursor_type_dev.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_point.h"
+#include "ppapi/c/pp_resource.h"
+
+#define PPB_CURSOR_CONTROL_DEV_INTERFACE "PPB_CursorControl(Dev);0.1"
+
+struct PPB_CursorControl_Dev {
+ // Set a cursor. If "type" is PP_CURSOR_TYPE_CUSTOM, then "custom_image"
+ // must be an ImageData resource containing the cursor and "hot_spot" must
+ // contain the offset within that image that refers to the cursor's position.
+ bool (*SetCursor)(PP_Instance instance,
+ enum PP_CursorType_Dev type,
+ PP_Resource custom_image,
+ const struct PP_Point* hot_spot);
+
+ // This method causes the cursor to be moved to the center of the
+ // instance and be locked, preventing the user from moving it.
+ // The cursor is implicitly hidden from the user while locked.
+ // Cursor lock may only be requested in response to a
+ // PP_InputEvent_MouseDown, and then only if the event was generated via
+ // user gesture.
+ //
+ // While the cursor is locked, any movement of the mouse will
+ // generate a PP_InputEvent_Type_MouseMove, whose x and y values
+ // indicate the position the cursor would have been moved to had
+ // the cursor not been locked, and had the screen been infinite in size.
+ //
+ // The browser may revoke cursor lock for reasons including but not
+ // limited to the user pressing the ESC key, the user activating
+ // another program via a reserved keystroke (e.g., ALT+TAB), or
+ // some other system event.
+ //
+ // Returns true if the cursor could be locked.
+ bool (*LockCursor)(PP_Instance);
+
+ // Causes the cursor to be unlocked, allowing it to track user
+ // movement again.
+ bool (*UnlockCursor)(PP_Instance);
+
+ // Returns true if the cursor is locked.
+ bool (*HasCursorLock)(PP_Instance);
+
+ // Returns true if the cursor can be locked.
+ bool (*CanLockCursor)(PP_Instance);
+};
+
+#endif // PPAPI_C_DEV_PPB_CURSOR_CONTROL_DEV_H_
+
diff --git a/ppapi/c/dev/ppb_directory_reader_dev.h b/ppapi/c/dev/ppb_directory_reader_dev.h
new file mode 100644
index 0000000..84983f5
--- /dev/null
+++ b/ppapi/c/dev/ppb_directory_reader_dev.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_DIRECTORY_READER_DEV_H_
+#define PPAPI_C_DEV_PPB_DIRECTORY_READER_DEV_H_
+
+#include "ppapi/c/dev/pp_file_info_dev.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+
+struct PP_CompletionCallback;
+
+struct PP_DirectoryEntry_Dev {
+ PP_Resource file_ref;
+ PP_FileType_Dev file_type;
+};
+
+#define PPB_DIRECTORYREADER_DEV_INTERFACE "PPB_DirectoryReader(Dev);0.1"
+
+struct PPB_DirectoryReader_Dev {
+ // Creates a DirectoryReader for the given directory. Upon success, the
+ // corresponding directory is classified as "in use" by the resulting
+ // DirectoryReader object until such time as the DirectoryReader object is
+ // destroyed.
+ PP_Resource (*Create)(PP_Resource directory_ref);
+
+ // Returns true if the given resource is a DirectoryReader. Returns false if
+ // the resource is invalid or some type other than a DirectoryReader.
+ bool (*IsDirectoryReader)(PP_Resource resource);
+
+ // Reads the next entry in the directory. Return PP_OK and sets
+ // entry->file_ref to 0 to indicate reaching the end of the directory. If
+ // entry->file_ref is non-zero when passed to GetNextEntry, it will be
+ // released before the next file_ref is stored.
+ //
+ // EXAMPLE USAGE:
+ //
+ // PP_Resource reader = reader_funcs->Create(dir_ref);
+ // PP_DirectoryEntry entry = {0};
+ // while (reader_funcs->GetNextEntry(reader, &entry,
+ // PP_BlockUntilComplete()) == PP_OK) {
+ // ProcessDirectoryEntry(entry);
+ // }
+ // core_funcs->ReleaseResource(reader);
+ //
+ int32_t (*GetNextEntry)(PP_Resource directory_reader,
+ struct PP_DirectoryEntry_Dev* entry,
+ struct PP_CompletionCallback callback);
+};
+
+#endif // PPAPI_C_DEV_PPB_DIRECTORY_READER_DEV_H_
diff --git a/ppapi/c/dev/ppb_file_chooser_dev.h b/ppapi/c/dev/ppb_file_chooser_dev.h
new file mode 100644
index 0000000..d5b06faa
--- /dev/null
+++ b/ppapi/c/dev/ppb_file_chooser_dev.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_FILE_CHOOSER_DEV_H_
+#define PPAPI_C_DEV_PPB_FILE_CHOOSER_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+
+struct PP_CompletionCallback;
+
+typedef enum {
+ PP_FILECHOOSERMODE_OPEN,
+ PP_FILECHOOSERMODE_OPENMULTIPLE
+ // TODO(darin): Should there be a way to choose a directory?
+} PP_FileChooserMode_Dev;
+
+struct PP_FileChooserOptions_Dev {
+ PP_FileChooserMode_Dev mode;
+
+ // A comma-separated list of MIME types such as audio/*,text/plain. The
+ // dialog may restrict selectable files to the specified MIME types.
+ // TODO(darin): What if the mime type is unknown to the system? The plugin
+ // may wish to describe the mime type and provide a matching file extension.
+ // It is more webby to use mime types here instead of file extensions.
+ const char* accept_mime_types;
+};
+
+#define PPB_FILECHOOSER_DEV_INTERFACE "PPB_FileChooser(Dev);0.1"
+
+struct PPB_FileChooser_Dev {
+ // Creates a file chooser dialog with the specified options. The chooser is
+ // associated with a particular instance, so that it may be positioned on the
+ // screen relative to the tab containing the instance. Returns 0 if passed
+ // an invalid instance.
+ PP_Resource (*Create)(PP_Instance instance,
+ const struct PP_FileChooserOptions_Dev* options);
+
+ // Returns true if the given resource is a FileChooser. Returns false if the
+ // resource is invalid or some type other than a FileChooser.
+ bool (*IsFileChooser)(PP_Resource resource);
+
+ // Prompts the user to choose a file or files.
+ int32_t (*Show)(PP_Resource chooser, struct PP_CompletionCallback callback);
+
+ // After a successful call to Show, this method may be used to query the
+ // chosen files. It should be called in a loop until it returns 0.
+ // Depending on the PP_ChooseFileMode requested when the FileChooser was
+ // created, the file refs will either be readable or writable. Their file
+ // system type will be PP_FileSystemType_External. If the user chose no
+ // files or cancelled the dialog, then this method will simply return 0
+ // the first time it is called.
+ PP_Resource (*GetNextChosenFile)(PP_Resource chooser);
+};
+
+#endif // PPAPI_C_DEV_PPB_FILE_CHOOSER_DEV_H_
diff --git a/ppapi/c/dev/ppb_file_io_dev.h b/ppapi/c/dev/ppb_file_io_dev.h
new file mode 100644
index 0000000..1dfefd1
--- /dev/null
+++ b/ppapi/c/dev/ppb_file_io_dev.h
@@ -0,0 +1,115 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_FILE_IO_DEV_H_
+#define PPAPI_C_DEV_PPB_FILE_IO_DEV_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_time.h"
+
+struct PP_CompletionCallback;
+struct PP_FileInfo_Dev;
+
+typedef enum {
+ // Requests read access to a file.
+ PP_FILEOPENFLAG_READ = 1 << 0,
+
+ // Requests write access to a file. May be combined with
+ // PP_FILEOPENFLAG_READ to request read and write access.
+ PP_FILEOPENFLAG_WRITE = 1 << 1,
+
+ // Requests that the file be created if it does not exist. If the file
+ // already exists, then this flag is ignored unless PP_FILEOPENFLAG_EXCLUSIVE
+ // was also specified, in which case FileIO::Open will fail.
+ PP_FILEOPENFLAG_CREATE = 1 << 2,
+
+ // Requests that the file be truncated to length 0 if it exists and is a
+ // regular file. PP_FILEOPENFLAG_WRITE must also be specified.
+ PP_FILEOPENFLAG_TRUNCATE = 1 << 3,
+
+ // Requests that the file is created when this flag is combined with
+ // PP_FILEOPENFLAG_CREATE. If this flag is specified, and the file already
+ // exists, then the FileIO::Open call will fail.
+ PP_FILEOPENFLAG_EXCLUSIVE = 1 << 4
+} PP_FileOpenFlags_Dev;
+
+#define PPB_FILEIO_DEV_INTERFACE "PPB_FileIO(Dev);0.1"
+
+// Use this interface to operate on a regular file (PP_FileType_Regular).
+struct PPB_FileIO_Dev {
+ // Creates a new FileIO object. Returns 0 if the module is invalid.
+ PP_Resource (*Create)(PP_Module module);
+
+ // Returns true if the given resource is a FileIO. Returns false if the
+ // resource is invalid or some type other than a FileIO.
+ bool (*IsFileIO)(PP_Resource resource);
+
+ // Open the specified regular file for I/O according to the given open flags,
+ // which is a bit-mask of the PP_FileOpenFlags values. Upon success, the
+ // corresponding file is classified as "in use" by this FileIO object until
+ // such time as the FileIO object is closed or destroyed.
+ int32_t (*Open)(PP_Resource file_io,
+ PP_Resource file_ref,
+ int32_t open_flags,
+ struct PP_CompletionCallback callback);
+
+ // Queries info about the file opened by this FileIO object. Fails if the
+ // FileIO object has not been opened.
+ int32_t (*Query)(PP_Resource file_io,
+ PP_FileInfo_Dev* info,
+ struct PP_CompletionCallback callback);
+
+ // Updates timestamps for the file opened by this FileIO object. Fails if
+ // the FileIO object has not been opened.
+ int32_t (*Touch)(PP_Resource file_io,
+ PP_Time last_access_time,
+ PP_Time last_modified_time,
+ struct PP_CompletionCallback callback);
+
+ // Read from an offset in the file. The size of the buffer must be large
+ // enough to hold the specified number of bytes to read. May perform a
+ // partial read. Returns the number of bytes read or an error code. If the
+ // return value is 0, then it indicates that end-of-file was reached. It is
+ // valid to call Read multiple times with a completion callback to queue up
+ // parallel reads from the file at different offsets.
+ int32_t (*Read)(PP_Resource file_io,
+ int64_t offset,
+ char* buffer,
+ int32_t bytes_to_read,
+ struct PP_CompletionCallback callback);
+
+ // Write to an offset in the file. May perform a partial write. Returns the
+ // number of bytes written or an error code. It is valid to call Write
+ // multiple times with a completion callback to queue up parallel writes to
+ // the file at different offsets. The FileIO object must have been opened
+ // with write access.
+ int32_t (*Write)(PP_Resource file_io,
+ int64_t offset,
+ const char* buffer,
+ int32_t bytes_to_write,
+ struct PP_CompletionCallback callback);
+
+ // Sets the length of the file. If the file size is extended, then the
+ // extended area of the file is zero-filled. The FileIO object must have
+ // been opened with write access.
+ int32_t (*SetLength)(PP_Resource file_io,
+ int64_t length,
+ struct PP_CompletionCallback callback);
+
+ // Flush changes to disk. This call can be very expensive!
+ int32_t (*Flush)(PP_Resource file_io,
+ struct PP_CompletionCallback callback);
+
+ // Cancels any IO that may be pending, and closes the FileIO object. Any
+ // pending callbacks will still run, reporting PP_Error_Aborted if pending IO
+ // was interrupted. It is NOT valid to call Open again after a call to this
+ // method. Note: If the FileIO object is destroyed, and it is still open,
+ // then it will be implicitly closed, so you are not required to call the
+ // Close method.
+ void (*Close)(PP_Resource file_io);
+};
+
+#endif // PPAPI_C_DEV_PPB_FILE_IO_DEV_H_
diff --git a/ppapi/c/dev/ppb_file_io_trusted_dev.h b/ppapi/c/dev/ppb_file_io_trusted_dev.h
new file mode 100644
index 0000000..f4915fa
--- /dev/null
+++ b/ppapi/c/dev/ppb_file_io_trusted_dev.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_FILE_IO_TRUSTED_DEV_H_
+#define PPAPI_C_DEV_PPB_FILE_IO_TRUSTED_DEV_H_
+
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+struct PP_CompletionCallback;
+
+#define PPB_FILEIOTRUSTED_DEV_INTERFACE "PPB_FileIOTrusted(Dev);0.1"
+
+// Available only to trusted implementations.
+struct PPB_FileIOTrusted_Dev {
+ // Returns a POSIX file descriptor corresponding to the given FileIO object.
+ // The FileIO object must have been opened with a successful call to
+ // FileIO::Open. The file descriptor will be closed automatically when the
+ // FileIO object is closed or destroyed.
+ int32_t (*GetOSFileDescriptor)(PP_Resource file_io);
+
+ // Notifies the browser that underlying file will be modified. This gives
+ // the browser the opportunity to apply quota restrictions and possibly
+ // return an error to indicate that the write is not allowed.
+ int32_t (*WillWrite)(PP_Resource file_io,
+ int64_t offset,
+ int32_t bytes_to_write,
+ struct PP_CompletionCallback callback);
+
+ // Notifies the browser that underlying file will be modified. This gives
+ // the browser the opportunity to apply quota restrictions and possibly
+ // return an error to indicate that the write is not allowed.
+ int32_t (*WillSetLength)(PP_Resource file_io,
+ int64_t length,
+ struct PP_CompletionCallback callback);
+
+ // TODO(darin): Maybe unify the above into a single WillChangeFileSize
+ // method? The above methods have the advantage of mapping to PPB_FileIO
+ // Write and SetLength calls. WillChangeFileSize would require the caller to
+ // compute the file size resulting from a Write call, which may be
+ // undesirable.
+};
+
+#endif // PPAPI_C_DEV_PPB_FILE_IO_TRUSTED_DEV_H_
diff --git a/ppapi/c/dev/ppb_file_ref_dev.h b/ppapi/c/dev/ppb_file_ref_dev.h
new file mode 100644
index 0000000..fd3a602
--- /dev/null
+++ b/ppapi/c/dev/ppb_file_ref_dev.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_FILE_REF_DEV_H_
+#define PPAPI_C_DEV_PPB_FILE_REF_DEV_H_
+
+#include "ppapi/c/dev/pp_file_info_dev.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_FILEREF_DEV_INTERFACE "PPB_FileRef(Dev);0.2"
+
+// A FileRef is a "weak pointer" to a file in a file system. It contains a
+// PP_FileSystemType identifier and a file path string.
+struct PPB_FileRef_Dev {
+ // Creates a weak pointer to a file in the given filesystem. File paths are
+ // POSIX style. Returns 0 if the path is malformed.
+ PP_Resource (*Create)(PP_Resource file_system, const char* path);
+
+ // Returns true if the given resource is a FileRef. Returns false if the
+ // resource is invalid or some type other than a FileRef.
+ bool (*IsFileRef)(PP_Resource resource);
+
+ // Returns the file system identifier of this file.
+ PP_FileSystemType_Dev (*GetFileSystemType)(PP_Resource file_ref);
+
+ // Returns the name of the file.
+ struct PP_Var (*GetName)(PP_Resource file_ref);
+
+ // Returns the absolute path of the file. This method fails if the file
+ // system type is PP_FileSystemType_External.
+ struct PP_Var (*GetPath)(PP_Resource file_ref);
+
+ // Returns the parent directory of this file. If file_ref points to the root
+ // of the filesystem, then the root is returned. This method fails if the
+ // file system type is PP_FileSystemType_External.
+ PP_Resource (*GetParent)(PP_Resource file_ref);
+
+ // Makes a new directory in the filesystem as well as any parent directories
+ // if the make_ancestors parameter is true. It is not valid to make a
+ // directory in the external filesystem. Fails if the directory already
+ // exists or if ancestor directories do not exist and make_ancestors was not
+ // passed as true.
+ int32_t (*MakeDirectory)(PP_Resource directory_ref,
+ bool make_ancestors,
+ struct PP_CompletionCallback callback);
+
+ // Queries info about the file. You must have read access to this file if it
+ // exists in the external filesystem.
+ int32_t (*Query)(PP_Resource file_ref,
+ struct PP_FileInfo_Dev* info,
+ struct PP_CompletionCallback callback);
+
+ // Updates timestamps for a file. You must have write access to the file if
+ // it exists in the external filesystem.
+ int32_t (*Touch)(PP_Resource file_ref,
+ PP_Time last_access_time,
+ PP_Time last_modified_time,
+ struct PP_CompletionCallback callback);
+
+ // Delete a file or directory. If file_ref refers to a directory, then the
+ // directory must be empty. It is an error to delete a file or directory
+ // that is in use. It is not valid to delete a file in the external
+ // filesystem.
+ int32_t (*Delete)(PP_Resource file_ref,
+ struct PP_CompletionCallback callback);
+
+ // Rename a file or directory. file_ref and new_file_ref must both refer to
+ // files in the same filesystem. It is an error to rename a file or
+ // directory that is in use. It is not valid to rename a file in the
+ // external filesystem.
+ int32_t (*Rename)(PP_Resource file_ref,
+ PP_Resource new_file_ref,
+ struct PP_CompletionCallback callback);
+
+ // TODO(darin): Add these conversion routines.
+#if 0
+ // Convert a DOM File object to a FileRef object.
+ PP_Resource (*FromFileObject)(PP_Var file_object);
+
+ // Convert a FileRef object to a DOM File object.
+ PP_Var (*ToFileObject)(PP_Resource file_ref);
+#endif
+};
+
+#endif // PPAPI_C_DEV_PPB_FILE_REF_DEV_H_
diff --git a/ppapi/c/dev/ppb_file_system_dev.h b/ppapi/c/dev/ppb_file_system_dev.h
new file mode 100644
index 0000000..9f93a1a
--- /dev/null
+++ b/ppapi/c/dev/ppb_file_system_dev.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_FILE_SYSTEM_DEV_H_
+#define PPAPI_C_DEV_PPB_FILE_SYSTEM_DEV_H_
+
+#include "ppapi/c/dev/pp_file_info_dev.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_time.h"
+
+struct PP_CompletionCallback;
+
+#define PPB_FILESYSTEM_DEV_INTERFACE "PPB_FileSystem(Dev);0.2"
+
+struct PPB_FileSystem_Dev {
+ // Creates a weak pointer to the filesystem of the given type.
+ PP_Resource (*Create)(PP_Instance instance, PP_FileSystemType_Dev type);
+
+ // Opens the file system. A file system must be opened before running any
+ // other operation on it.
+ int32_t (*Open)(PP_Resource file_system,
+ int64_t expected_size,
+ struct PP_CompletionCallback callback);
+};
+
+#endif // PPAPI_C_DEV_PPB_FILE_SYSTEM_DEV_H_
diff --git a/ppapi/c/dev/ppb_find_dev.h b/ppapi/c/dev/ppb_find_dev.h
new file mode 100644
index 0000000..ffd7ca8
--- /dev/null
+++ b/ppapi/c/dev/ppb_find_dev.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_FIND_DEV_H_
+#define PPAPI_C_DEV_PPB_FIND_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_stdint.h"
+
+#define PPB_FIND_DEV_INTERFACE "PPB_Find(Dev);0.1"
+
+struct PPB_Find_Dev {
+ // Updates the number of find results for the current search term. If
+ // there are no matches 0 should be passed in. Only when the plugin has
+ // finished searching should it pass in the final count with finalResult set
+ // to true.
+ void (*NumberOfFindResultsChanged)(PP_Instance instance,
+ int32_t total,
+ bool final_result);
+
+ // Updates the index of the currently selected search item.
+ void (*SelectedFindResultChanged)(PP_Instance instance,
+ int32_t index);
+
+};
+
+#endif // PPAPI_C_DEV_PPB_FIND_DEV_H_
diff --git a/ppapi/c/dev/ppb_font_dev.h b/ppapi/c/dev/ppb_font_dev.h
new file mode 100644
index 0000000..48dc91f
--- /dev/null
+++ b/ppapi/c/dev/ppb_font_dev.h
@@ -0,0 +1,161 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_FONT_DEV_H_
+#define PPAPI_C_DEV_PPB_FONT_DEV_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_FONT_DEV_INTERFACE "PPB_Font(Dev);0.1"
+
+struct PP_Point;
+struct PP_Rect;
+
+typedef enum {
+ // Uses the user's default web page font (normally either the default serif
+ // or sans serif font).
+ PP_FONTFAMILY_DEFAULT = 0,
+
+ // These families will use the default web page font corresponding to the
+ // given family.
+ PP_FONTFAMILY_SERIF = 1,
+ PP_FONTFAMILY_SANSSERIF = 2,
+ PP_FONTFAMILY_MONOSPACE = 3
+} PP_FontFamily_Dev;
+
+typedef enum {
+ PP_FONTWEIGHT_100 = 0,
+ PP_FONTWEIGHT_200,
+ PP_FONTWEIGHT_300,
+ PP_FONTWEIGHT_400,
+ PP_FONTWEIGHT_500,
+ PP_FONTWEIGHT_600,
+ PP_FONTWEIGHT_700,
+ PP_FONTWEIGHT_800,
+ PP_FONTWEIGHT_900,
+ PP_FONTWEIGHT_NORMAL = PP_FONTWEIGHT_400,
+ PP_FONTWEIGHT_BOLD = PP_FONTWEIGHT_700
+} PP_FontWeight_Dev;
+
+struct PP_FontDescription_Dev {
+ // Font face name as a string. This can also be a Null var, in which case the
+ // generic family will be obeyed.
+ struct PP_Var face;
+
+ // When face is a Null string, this specifies the generic font family type
+ // to use. If the face is specified, this will be ignored.
+ PP_FontFamily_Dev family;
+
+ uint32_t size;
+
+ // Normally you will use either PP_FONTWEIGHT_NORMAL or PP_FONTWEIGHT_BOLD.
+ PP_FontWeight_Dev weight;
+
+ bool italic;
+ bool small_caps;
+
+ // Adjustment to apply to letter and word spacing, respectively. Initialize
+ // to 0 to get normal spacing. Negative values bring letters/words closer
+ // together, positive values separate them.
+ int letter_spacing;
+ int word_spacing;
+};
+
+struct PP_FontMetrics_Dev {
+ int32_t height;
+ int32_t ascent;
+ int32_t descent;
+ int32_t line_spacing;
+ int32_t x_height;
+};
+
+struct PP_TextRun_Dev {
+ // This var must either be a string or a null var (which will be treated as
+ // a 0-length string).
+ struct PP_Var text;
+
+ // Set to true if the text is right-to-left.
+ bool rtl;
+
+ // Set to true to force the directionality of the text regardless of content
+ bool override_direction;
+};
+
+struct PPB_Font_Dev {
+ // Returns a font which best matches the given description. The return value
+ // will have a non-zero ID on success, or zero on failure.
+ PP_Resource (*Create)(PP_Module module,
+ const struct PP_FontDescription_Dev* description);
+
+ // Returns true if the given resource is a Font. Returns false if the
+ // resource is invalid or some type other than a Font.
+ bool (*IsFont)(PP_Resource resource);
+
+ // Loads the description and metrics of the font into the given structures.
+ // The description will be different than the description the font was
+ // created with since it will be filled with the real values from the font
+ // that was actually selected.
+ //
+ // The PP_Var in the description should be of type Void on input. On output,
+ // this will contain the string and will have a reference count of 1. The
+ // plugin is responsible for calling Release on this var.
+ //
+ // Returns true on success, false if the font is invalid or if the Var in
+ // the description isn't Null (to prevent leaks).
+ bool (*Describe)(PP_Resource font,
+ struct PP_FontDescription_Dev* description,
+ struct PP_FontMetrics_Dev* metrics);
+
+ // Draws the text to the image buffer.
+ //
+ // The given point represents the baseline of the left edge of the font,
+ // regardless of whether it is left-to-right or right-to-left (in the case of
+ // RTL text, this will actually represent the logical end of the text).
+ //
+ // The clip is optional and may be NULL. In this case, the text will be
+ // clipped to the image.
+ //
+ // The image_data_is_opaque flag indicates whether subpixel antialiasing can
+ // be performend, if it is supported. When the image below the text is
+ // opaque, subpixel antialiasing is supported and you should set this to true
+ // to pick up the user's default preferences. If your plugin is partially
+ // transparent, then subpixel antialiasing is not possible and grayscale
+ // antialiasing will be used instead (assuming the user has antialiasing
+ // enabled at all).
+ bool (*DrawTextAt)(PP_Resource font,
+ PP_Resource image_data,
+ const struct PP_TextRun_Dev* text,
+ const struct PP_Point* position,
+ uint32_t color,
+ const struct PP_Rect* clip,
+ bool image_data_is_opaque);
+
+ // Returns the width of the given string. If the font is invalid or the var
+ // isn't a valid string, this will return -1.
+ //
+ // Note that this function handles complex scripts such as Arabic, combining
+ // accents, etc. so that adding the width of substrings won't necessarily
+ // produce the correct width of the entire string.
+ int32_t (*MeasureText)(PP_Resource font,
+ const struct PP_TextRun_Dev* text);
+
+ // Returns the character at the given pixel X position from the beginning of
+ // the string. This handles complex scripts such as Arabic, where characters
+ // may be combined or replaced depending on the context.
+ uint32_t (*CharacterOffsetForPixel)(PP_Resource font,
+ const struct PP_TextRun_Dev* text,
+ int32_t pixel_position);
+
+ // Returns the horizontal advance to the given character if the string was
+ // placed at the given position. This handles complex scripts such as Arabic,
+ // where characters may be combined or replaced depending on context.
+ int32_t (*PixelOffsetForCharacter)(PP_Resource font,
+ const struct PP_TextRun_Dev* text,
+ uint32_t char_offset);
+};
+
+#endif // PPAPI_C_DEV_PPB_FONT_DEV_H_
diff --git a/ppapi/c/dev/ppb_fullscreen_dev.h b/ppapi/c/dev/ppb_fullscreen_dev.h
new file mode 100644
index 0000000..9730b3e
--- /dev/null
+++ b/ppapi/c/dev/ppb_fullscreen_dev.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_FULLSCREEN_DEV_H_
+#define PPAPI_C_DEV_PPB_FULLSCREEN_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_stdint.h"
+
+#define PPB_FULLSCREEN_DEV_INTERFACE "PPB_Fullscreen(Dev);0.1"
+
+// Use this interface to change a plugin instance to fullscreen mode.
+struct PPB_Fullscreen_Dev {
+ // Checks whether the plugin instance is currently in fullscreen mode.
+ bool (*IsFullscreen)(PP_Instance instance);
+
+ // Switches the plugin instance to/from fullscreen mode. Returns true on
+ // success, false on failure.
+ // When in fullscreen mode, the plugin will be transparently scaled to the
+ // size of the screen. It will not receive a ViewChanged event, and doesn't
+ // need to rebind the graphics context. The pending flushes will execute
+ // normally, to the new fullscreen window.
+ bool (*SetFullscreen)(PP_Instance instance, bool fullscreen);
+};
+
+#endif // PPAPI_C_DEV_PPB_FULLSCREEN_DEV_H_
diff --git a/ppapi/c/dev/ppb_graphics_3d_dev.h b/ppapi/c/dev/ppb_graphics_3d_dev.h
new file mode 100644
index 0000000..142c2f2
--- /dev/null
+++ b/ppapi/c/dev/ppb_graphics_3d_dev.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_GRAPHICS_3D_DEV_H_
+#define PPAPI_C_DEV_PPB_GRAPHICS_3D_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+// Example usage from plugin code:
+//
+// PP_Resource context = device->Create(module, config, contextAttribList);
+// CHECK(context);
+//
+// // Present one frame.
+// CHECK(device->MakeCurrent(context));
+// glClear(GL_COLOR_BUFFER);
+// CHECK(device->MakeCurrent(NULL));
+// CHECK(device->SwapBuffers(context));
+//
+// // Shutdown.
+// core->ReleaseResource(context);
+
+#define PPB_GRAPHICS_3D_DEV_INTERFACE "PPB_Graphics3D(Dev);0.1"
+
+// These are the same error codes as used by EGL.
+enum {
+ PP_GRAPHICS_3D_ERROR_SUCCESS = 0x3000,
+ PP_GRAPHICS_3D_ERROR_NOT_INITIALIZED = 0x3001,
+ PP_GRAOHICS_3D_ERROR_BAD_CONTEXT = 0x3006,
+ PP_GRAPHICS_3D_ERROR_BAD_PARAMETER = 0x300C,
+ PP_GRAPHICS_3D_ERROR_CONTEXT_LOST = 0x300E
+};
+
+// QueryString targets, matching EGL ones.
+enum {
+ EGL_VENDOR = 0x3053,
+ EGL_VERSION = 0x3054,
+ EGL_EXTENSIONS = 0x3055,
+ EGL_CLIENT_APIS = 0x308D
+};
+
+struct PPB_Graphics3D_Dev {
+ bool (*IsGraphics3D)(PP_Resource resource);
+
+ // EGL-like configuration ----------------------------------------------------
+ bool (*GetConfigs)(int32_t* configs,
+ int32_t config_size,
+ int32_t* num_config);
+
+ bool (*ChooseConfig)(const int32_t* attrib_list,
+ int32_t* configs,
+ int32_t config_size,
+ int32_t* num_config);
+
+ // TODO(apatrick): What to do if the browser window is moved to
+ // another display? Do the configs potentially change?
+ bool (*GetConfigAttrib)(int32_t config, int32_t attribute, int32_t* value);
+
+ const char* (*QueryString)(int32_t name);
+ // ---------------------------------------------------------------------------
+
+
+ // Create a reference counted 3D context. Releasing a context while it is
+ // current automatically sets the current context to NULL. This is only true
+ // for the releasing thread. Releasing a context while it is current on
+ // another thread leads to undefined behavior.
+ PP_Resource (*CreateContext)(PP_Instance instance,
+ int32_t config,
+ int32_t share_context,
+ const int32_t* attrib_list);
+
+ // Get the address of any GL functions, whether core or part of an extension.
+ // Any thread.
+ void* (*GetProcAddress)(const char* name);
+
+ // Make a particular context current of the calling thread.
+ bool (*MakeCurent)(PP_Resource context);
+
+ // Returns the calling thread's current context or NULL if no context is
+ // current.
+ PP_Resource (*GetCurrentContext)();
+
+ // Snapshots the rendered frame and makes it available for composition with
+ // the rest of the page. The alpha channel is used for translucency effects.
+ // One means fully opaque. Zero means fully transparent. Any thread.
+ // TODO(apatrick): premultiplied alpha or linear alpha? Premultiplied alpha is
+ // better for correct alpha blending effect. Most existing OpenGL code assumes
+ // linear. I could convert from linear to premultiplied during the copy from
+ // back-buffer to offscreen "front-buffer".
+ bool (*SwapBuffers)(PP_Resource context);
+
+ // Returns the current error for this thread. This is not associated with a
+ // particular context. It is distinct from the GL error returned by
+ // glGetError.
+ uint32_t (*GetError)();
+};
+
+#endif // PPAPI_C_DEV_PPB_GRAPHICS_3D_DEV_H_
+
diff --git a/ppapi/c/dev/ppb_opengles_dev.h b/ppapi/c/dev/ppb_opengles_dev.h
new file mode 100644
index 0000000..c397beb
--- /dev/null
+++ b/ppapi/c/dev/ppb_opengles_dev.h
@@ -0,0 +1,248 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is auto-generated. DO NOT EDIT!
+
+// This interface is used to access common and lite profile OpenGL ES 2.0
+// functions.
+#ifndef PPAPI_C_DEV_PPB_OPENGLES_DEV_H_
+#define PPAPI_C_DEV_PPB_OPENGLES_DEV_H_
+
+#include "../../GLES2/khrplatform.h"
+
+#define PPB_OPENGLES_DEV_INTERFACE "PPB_OpenGLES(Dev);2.0"
+
+typedef unsigned int GLenum;
+typedef void GLvoid;
+typedef khronos_intptr_t GLintptr;
+typedef int GLsizei;
+typedef khronos_ssize_t GLsizeiptr;
+typedef int GLint;
+typedef unsigned char GLboolean;
+typedef unsigned int GLuint;
+typedef unsigned int GLbitfield;
+typedef short GLshort;
+typedef float GLfloat;
+typedef float GLclampf;
+typedef signed char GLbyte;
+typedef unsigned char GLubyte;
+typedef int GLfixed;
+typedef unsigned short GLushort;
+typedef int GLclampx;
+
+struct PPB_OpenGLES_Dev {
+ void (*ActiveTexture)(GLenum texture);
+ void (*AttachShader)(GLuint program, GLuint shader);
+ void (*BindAttribLocation)(GLuint program, GLuint index, const char* name);
+ void (*BindBuffer)(GLenum target, GLuint buffer);
+ void (*BindFramebuffer)(GLenum target, GLuint framebuffer);
+ void (*BindRenderbuffer)(GLenum target, GLuint renderbuffer);
+ void (*BindTexture)(GLenum target, GLuint texture);
+ void (*BlendColor)(
+ GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void (*BlendEquation)(GLenum mode);
+ void (*BlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha);
+ void (*BlendFunc)(GLenum sfactor, GLenum dfactor);
+ void (*BlendFuncSeparate)(
+ GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ void (*BufferData)(
+ GLenum target, GLsizeiptr size, const void* data, GLenum usage);
+ void (*BufferSubData)(
+ GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
+ GLenum (*CheckFramebufferStatus)(GLenum target);
+ void (*Clear)(GLbitfield mask);
+ void (*ClearColor)(
+ GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void (*ClearDepthf)(GLclampf depth);
+ void (*ClearStencil)(GLint s);
+ void (*ColorMask)(
+ GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void (*CompileShader)(GLuint shader);
+ void (*CompressedTexImage2D)(
+ GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLsizei height, GLint border, GLsizei imageSize, const void* data);
+ void (*CompressedTexSubImage2D)(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+ GLsizei height, GLenum format, GLsizei imageSize, const void* data);
+ void (*CopyTexImage2D)(
+ GLenum target, GLint level, GLenum internalformat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border);
+ void (*CopyTexSubImage2D)(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x,
+ GLint y, GLsizei width, GLsizei height);
+ GLuint (*CreateProgram)();
+ GLuint (*CreateShader)(GLenum type);
+ void (*CullFace)(GLenum mode);
+ void (*DeleteBuffers)(GLsizei n, const GLuint* buffers);
+ void (*DeleteFramebuffers)(GLsizei n, const GLuint* framebuffers);
+ void (*DeleteProgram)(GLuint program);
+ void (*DeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers);
+ void (*DeleteShader)(GLuint shader);
+ void (*DeleteTextures)(GLsizei n, const GLuint* textures);
+ void (*DepthFunc)(GLenum func);
+ void (*DepthMask)(GLboolean flag);
+ void (*DepthRangef)(GLclampf zNear, GLclampf zFar);
+ void (*DetachShader)(GLuint program, GLuint shader);
+ void (*Disable)(GLenum cap);
+ void (*DisableVertexAttribArray)(GLuint index);
+ void (*DrawArrays)(GLenum mode, GLint first, GLsizei count);
+ void (*DrawElements)(
+ GLenum mode, GLsizei count, GLenum type, const void* indices);
+ void (*Enable)(GLenum cap);
+ void (*EnableVertexAttribArray)(GLuint index);
+ void (*Finish)();
+ void (*Flush)();
+ void (*FramebufferRenderbuffer)(
+ GLenum target, GLenum attachment, GLenum renderbuffertarget,
+ GLuint renderbuffer);
+ void (*FramebufferTexture2D)(
+ GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
+ GLint level);
+ void (*FrontFace)(GLenum mode);
+ void (*GenBuffers)(GLsizei n, GLuint* buffers);
+ void (*GenerateMipmap)(GLenum target);
+ void (*GenFramebuffers)(GLsizei n, GLuint* framebuffers);
+ void (*GenRenderbuffers)(GLsizei n, GLuint* renderbuffers);
+ void (*GenTextures)(GLsizei n, GLuint* textures);
+ void (*GetActiveAttrib)(
+ GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
+ GLint* size, GLenum* type, char* name);
+ void (*GetActiveUniform)(
+ GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
+ GLint* size, GLenum* type, char* name);
+ void (*GetAttachedShaders)(
+ GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+ GLint (*GetAttribLocation)(GLuint program, const char* name);
+ void (*GetBooleanv)(GLenum pname, GLboolean* params);
+ void (*GetBufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ GLenum (*GetError)();
+ void (*GetFloatv)(GLenum pname, GLfloat* params);
+ void (*GetFramebufferAttachmentParameteriv)(
+ GLenum target, GLenum attachment, GLenum pname, GLint* params);
+ void (*GetIntegerv)(GLenum pname, GLint* params);
+ void (*GetProgramiv)(GLuint program, GLenum pname, GLint* params);
+ void (*GetProgramInfoLog)(
+ GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
+ void (*GetRenderbufferParameteriv)(
+ GLenum target, GLenum pname, GLint* params);
+ void (*GetShaderiv)(GLuint shader, GLenum pname, GLint* params);
+ void (*GetShaderInfoLog)(
+ GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
+ void (*GetShaderPrecisionFormat)(
+ GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+ void (*GetShaderSource)(
+ GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
+ const GLubyte* (*GetString)(GLenum name);
+ void (*GetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params);
+ void (*GetTexParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (*GetUniformfv)(GLuint program, GLint location, GLfloat* params);
+ void (*GetUniformiv)(GLuint program, GLint location, GLint* params);
+ GLint (*GetUniformLocation)(GLuint program, const char* name);
+ void (*GetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params);
+ void (*GetVertexAttribiv)(GLuint index, GLenum pname, GLint* params);
+ void (*GetVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer);
+ void (*Hint)(GLenum target, GLenum mode);
+ GLboolean (*IsBuffer)(GLuint buffer);
+ GLboolean (*IsEnabled)(GLenum cap);
+ GLboolean (*IsFramebuffer)(GLuint framebuffer);
+ GLboolean (*IsProgram)(GLuint program);
+ GLboolean (*IsRenderbuffer)(GLuint renderbuffer);
+ GLboolean (*IsShader)(GLuint shader);
+ GLboolean (*IsTexture)(GLuint texture);
+ void (*LineWidth)(GLfloat width);
+ void (*LinkProgram)(GLuint program);
+ void (*PixelStorei)(GLenum pname, GLint param);
+ void (*PolygonOffset)(GLfloat factor, GLfloat units);
+ void (*ReadPixels)(
+ GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ GLenum type, void* pixels);
+ void (*ReleaseShaderCompiler)();
+ void (*RenderbufferStorage)(
+ GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void (*SampleCoverage)(GLclampf value, GLboolean invert);
+ void (*Scissor)(GLint x, GLint y, GLsizei width, GLsizei height);
+ void (*ShaderBinary)(
+ GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary,
+ GLsizei length);
+ void (*ShaderSource)(
+ GLuint shader, GLsizei count, const char** str, const GLint* length);
+ void (*StencilFunc)(GLenum func, GLint ref, GLuint mask);
+ void (*StencilFuncSeparate)(
+ GLenum face, GLenum func, GLint ref, GLuint mask);
+ void (*StencilMask)(GLuint mask);
+ void (*StencilMaskSeparate)(GLenum face, GLuint mask);
+ void (*StencilOp)(GLenum fail, GLenum zfail, GLenum zpass);
+ void (*StencilOpSeparate)(
+ GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+ void (*TexImage2D)(
+ GLenum target, GLint level, GLint internalformat, GLsizei width,
+ GLsizei height, GLint border, GLenum format, GLenum type,
+ const void* pixels);
+ void (*TexParameterf)(GLenum target, GLenum pname, GLfloat param);
+ void (*TexParameterfv)(GLenum target, GLenum pname, const GLfloat* params);
+ void (*TexParameteri)(GLenum target, GLenum pname, GLint param);
+ void (*TexParameteriv)(GLenum target, GLenum pname, const GLint* params);
+ void (*TexSubImage2D)(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+ GLsizei height, GLenum format, GLenum type, const void* pixels);
+ void (*Uniform1f)(GLint location, GLfloat x);
+ void (*Uniform1fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (*Uniform1i)(GLint location, GLint x);
+ void (*Uniform1iv)(GLint location, GLsizei count, const GLint* v);
+ void (*Uniform2f)(GLint location, GLfloat x, GLfloat y);
+ void (*Uniform2fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (*Uniform2i)(GLint location, GLint x, GLint y);
+ void (*Uniform2iv)(GLint location, GLsizei count, const GLint* v);
+ void (*Uniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z);
+ void (*Uniform3fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (*Uniform3i)(GLint location, GLint x, GLint y, GLint z);
+ void (*Uniform3iv)(GLint location, GLsizei count, const GLint* v);
+ void (*Uniform4f)(
+ GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (*Uniform4fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (*Uniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w);
+ void (*Uniform4iv)(GLint location, GLsizei count, const GLint* v);
+ void (*UniformMatrix2fv)(
+ GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat* value);
+ void (*UniformMatrix3fv)(
+ GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat* value);
+ void (*UniformMatrix4fv)(
+ GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat* value);
+ void (*UseProgram)(GLuint program);
+ void (*ValidateProgram)(GLuint program);
+ void (*VertexAttrib1f)(GLuint indx, GLfloat x);
+ void (*VertexAttrib1fv)(GLuint indx, const GLfloat* values);
+ void (*VertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y);
+ void (*VertexAttrib2fv)(GLuint indx, const GLfloat* values);
+ void (*VertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ void (*VertexAttrib3fv)(GLuint indx, const GLfloat* values);
+ void (*VertexAttrib4f)(
+ GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (*VertexAttrib4fv)(GLuint indx, const GLfloat* values);
+ void (*VertexAttribPointer)(
+ GLuint indx, GLint size, GLenum type, GLboolean normalized,
+ GLsizei stride, const void* ptr);
+ void (*Viewport)(GLint x, GLint y, GLsizei width, GLsizei height);
+ void (*SwapBuffers)();
+ GLuint (*GetMaxValueInBuffer)(
+ GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
+ void (*GenSharedIds)(
+ GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
+ void (*DeleteSharedIds)(GLuint namespace_id, GLsizei n, const GLuint* ids);
+ void (*RegisterSharedIds)(GLuint namespace_id, GLsizei n, const GLuint* ids);
+ GLboolean (*CommandBufferEnable)(const char* feature);
+ void* (*MapBufferSubData)(
+ GLuint target, GLintptr offset, GLsizeiptr size, GLenum access);
+ void (*UnmapBufferSubData)(const void* mem);
+ void* (*MapTexSubImage2D)(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+ GLsizei height, GLenum format, GLenum type, GLenum access);
+ void (*UnmapTexSubImage2D)(const void* mem);
+};
+
+#endif // PPAPI_C_DEV_PPB_OPENGLES_DEV_H_
+
diff --git a/ppapi/c/dev/ppb_scrollbar_dev.h b/ppapi/c/dev/ppb_scrollbar_dev.h
new file mode 100644
index 0000000..4b365bb
--- /dev/null
+++ b/ppapi/c/dev/ppb_scrollbar_dev.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_SCROLLBAR_DEV_H_
+#define PPAPI_C_DEV_PPB_SCROLLBAR_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+struct PP_Rect;
+
+typedef enum {
+ PP_SCROLLBY_PIXEL = 0,
+ PP_SCROLLBY_LINE = 1,
+ PP_SCROLLBY_PAGE = 2,
+ PP_SCROLLBY_DOCUMENT = 3
+} PP_ScrollBy_Dev;
+
+#define PPB_SCROLLBAR_DEV_INTERFACE "PPB_Scrollbar(Dev);0.1"
+
+// The interface for a scrollbar. A scrollbar is a widget, so the functions
+// in PPB_Widget can also be used with scrollbar objects.
+struct PPB_Scrollbar_Dev {
+ // Create a new scrollbar. Returns 0 if the instance is invalid.
+ PP_Resource (*Create)(PP_Instance instance,
+ bool vertical);
+
+ // Returns true if the given resource is a Scrollbar. Returns false if the
+ // resource is invalid or some type other than a scrollbar.
+ bool (*IsScrollbar)(PP_Resource resource);
+
+ // Gets the thickness of a scrollbar.
+ uint32_t (*GetThickness)();
+
+ // Get/set the value of the scrollbar.
+ uint32_t (*GetValue)(PP_Resource scrollbar);
+
+ void (*SetValue)(PP_Resource scrollbar,
+ uint32_t value);
+
+ // Set the document size (i.e. total length of the region that's being
+ // scrolled).
+ void (*SetDocumentSize)(PP_Resource scrollbar,
+ uint32_t size);
+
+ // Updates the tickmarks. Only valid for vertical scrollbars. "tick_marks"
+ // contains "count" PP_Rect objects.
+ void (*SetTickMarks)(PP_Resource scrollbar,
+ const struct PP_Rect* tick_marks,
+ uint32_t count);
+
+ // Scroll by "multiplier" pixels/lines/pages units. Positive values are
+ // forward and negative are backward. If "unit" is document then any positive
+ // value goes to the end while any negative value goes to the beginning.
+ void (*ScrollBy)(PP_Resource scrollbar,
+ PP_ScrollBy_Dev unit,
+ int32_t multiplier);
+};
+
+#endif // PPAPI_C_DEV_PPB_SCROLLBAR_DEV_H_
diff --git a/ppapi/c/dev/ppb_testing_dev.h b/ppapi/c/dev/ppb_testing_dev.h
new file mode 100644
index 0000000..16c2bd4
--- /dev/null
+++ b/ppapi/c/dev/ppb_testing_dev.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_TESTING_DEV_H_
+#define PPAPI_C_DEV_PPB_TESTING_DEV_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+struct PP_Point;
+
+#define PPB_TESTING_DEV_INTERFACE "PPB_Testing(Dev);0.2"
+
+// This interface contains functions used for unit testing. Do not use in
+// production code. They are not guaranteed to be available in normal plugin
+// environments so you should not depend on them.
+struct PPB_Testing_Dev {
+ // Reads the bitmap data out of the backing store for the given
+ // DeviceContext2D and into the given image. If the data was successfully
+ // read, it will return true.
+ //
+ // This function should not generally be necessary for normal plugin
+ // operation. If you want to update portions of a device, the expectation is
+ // that you will either regenerate the data, or maintain a backing store
+ // pushing updates to the device from your backing store via PaintImageData.
+ // Using this function will introduce an extra copy which will make your
+ // plugin slower. In some cases, this may be a very expensive operation (it
+ // may require slow cross-process transitions or graphics card readbacks).
+ //
+ // Data will be read into the image starting at |top_left| in the device
+ // context, and proceeding down and to the right for as many pixels as the
+ // image is large. If any part of the image bound would fall outside of the
+ // backing store of the device if positioned at |top_left|, this function
+ // will fail and return false.
+ //
+ // The image format must be of the format
+ // PPB_ImageData.GetNativeImageDataFormat() or this function will fail and
+ // return false.
+ //
+ // The returned image data will represent the current status of the backing
+ // store. This will not include any paint, scroll, or replace operations
+ // that have not yet been flushed; these operations are only reflected in
+ // the backing store (and hence ReadImageData) until after a Flush()
+ // operation has completed.
+ bool (*ReadImageData)(PP_Resource device_context_2d,
+ PP_Resource image,
+ const struct PP_Point* top_left);
+
+ // Runs a nested message loop. The plugin will be reentered from this call.
+ // This function is used for unit testing the API. The normal pattern is to
+ // issue some asynchronous call that has a callback. Then you call
+ // RunMessageLoop which will suspend the plugin and go back to processing
+ // messages, giving the asynchronous operation time to complete. In your
+ // callback, you save the data and call QuitMessageLoop, which will then
+ // pop back up and continue with the test. This avoids having to write a
+ // complicated state machine for simple tests for asynchronous APIs.
+ void (*RunMessageLoop)();
+
+ // Posts a quit message for the outermost nested message loop. Use this to
+ // exit and return back to the caller after you call RunMessageLoop.
+ void (*QuitMessageLoop)();
+
+ // Returns the number of live objects (resources + strings + objects)
+ // associated with this plugin module. Used for detecting leaks.
+ uint32_t (*GetLiveObjectCount)(PP_Module module);
+};
+
+#endif // PPAPI_C_DEV_PPB_TESTING_DEV_H_
diff --git a/ppapi/c/dev/ppb_transport_dev.h b/ppapi/c/dev/ppb_transport_dev.h
new file mode 100644
index 0000000..821557d
--- /dev/null
+++ b/ppapi/c/dev/ppb_transport_dev.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPB_TRANSPORT_DEV_H_
+#define PPAPI_C_PPB_TRANSPORT_DEV_H_
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_TRANSPORT_DEV_INTERFACE "PPB_Transport;0.1"
+
+struct PPB_Transport_Dev {
+ // Creates a new transport object with the specified name
+ // using the specified protocol.
+ PP_Resource (*CreateTransport)(PP_Module module,
+ const char* name,
+ const char* proto);
+
+ // Returns whether or not resource is a Transport
+ bool (*IsTransport)(PP_Resource resource);
+
+ // Returns whether the transport is currently writable
+ // (i.e. can send data to the remote peer)
+ bool (*IsWritable)(PP_Resource transport);
+ // TODO(juberti): other getters/setters
+ // connect state
+ // connect type, protocol
+ // RTT
+
+ // Establishes a connection to the remote peer.
+ // Returns PP_ERROR_WOULDBLOCK and notifies on |cb|
+ // when connectivity is established (or timeout occurs).
+ int32_t (*Connect)(PP_Resource transport,
+ PP_CompletionCallback cb);
+
+ // Obtains another ICE candidate address to be provided
+ // to the remote peer. Returns PP_ERROR_WOULDBLOCK
+ // if there are no more addresses to be sent.
+ int32_t (*GetNextAddress)(PP_Resource transport,
+ PP_Var* address,
+ PP_CompletionCallback cb);
+ // Provides an ICE candidate address that was received
+ // from the remote peer.
+ int32_t (*ReceiveRemoteAddress)(PP_Resource transport,
+ PP_Var address);
+
+ // Like recv(), receives data. Returns PP_ERROR_WOULDBLOCK
+ // if there is currently no data to receive.
+ int32_t (*Recv)(PP_Resource transport,
+ void* data,
+ uint32_t len,
+ PP_CompletionCallback cb);
+ // Like send(), sends data. Returns PP_ERROR_WOULDBLOCK
+ // if the socket is currently flow-controlled.
+ int32_t (*Send)(PP_Resource transport,
+ const void* data,
+ uint32_t len,
+ PP_CompletionCallback cb);
+
+ // Disconnects from the remote peer.
+ int32_t (*Close)(PP_Resource transport);
+};
+
+#endif // PPAPI_C_PPB_TRANSPORT_DEV_H_
+
diff --git a/ppapi/c/dev/ppb_url_loader_dev.h b/ppapi/c/dev/ppb_url_loader_dev.h
new file mode 100644
index 0000000..44f4dc90
--- /dev/null
+++ b/ppapi/c/dev/ppb_url_loader_dev.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_URL_LOADER_DEV_H_
+#define PPAPI_C_DEV_PPB_URL_LOADER_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+struct PP_CompletionCallback;
+
+#define PPB_URLLOADER_DEV_INTERFACE "PPB_URLLoader(Dev);0.1"
+
+// The interface for loading URLs.
+//
+// Typical steps for loading an URL:
+// 1- Create an URLLoader object.
+// 2- Create an URLRequestInfo object and set properties on it.
+// 3- Call URLLoader's Open method passing the URLRequestInfo.
+// 4- When Open completes, call GetResponseInfo to examine the response headers.
+// 5- Then call ReadResponseBody to stream the data for the response.
+//
+// Alternatively, if PP_URLREQUESTPROPERTY_STREAMTOFILE was set on the
+// URLRequestInfo, then call FinishStreamingToFile at step #5 to wait for the
+// downloaded file to be complete. The downloaded file may be accessed via the
+// GetBody method of the URLResponseInfo returned in step #4.
+//
+struct PPB_URLLoader_Dev {
+ // Create a new URLLoader object. Returns 0 if the instance is invalid. The
+ // URLLoader is associated with a particular instance, so that any UI dialogs
+ // that need to be shown to the user can be positioned relative to the window
+ // containing the instance. It is also important for security reasons to
+ // know the origin of the URL request.
+ PP_Resource (*Create)(PP_Instance instance);
+
+ // Returns true if the given resource is an URLLoader. Returns false if the
+ // resource is invalid or some type other than an URLLoader.
+ bool (*IsURLLoader)(PP_Resource resource);
+
+ // Begins loading the URLRequestInfo. Completes when response headers are
+ // received or when an error occurs. Use the GetResponseInfo method to
+ // access the response headers.
+ int32_t (*Open)(PP_Resource loader,
+ PP_Resource request_info,
+ struct PP_CompletionCallback callback);
+
+ // If the current URLResponseInfo object corresponds to a redirect, then call
+ // this method to follow the redirect.
+ int32_t (*FollowRedirect)(PP_Resource loader,
+ struct PP_CompletionCallback callback);
+
+ // Returns the current upload progress, which is meaningful after Open has
+ // been called, and the request given to Open must have been configured with
+ // PP_URLREQUESTPROPERTY_REPORTUPLOADPROGRESS set to true. Progress only
+ // refers to the request body. This data is only available if the
+ // PP_URLREQUESTPROPERTY_REPORTUPLOADPROGRESS was set to true on the
+ // URLRequestInfo. This method returns false if upload progress is not
+ // available.
+ bool (*GetUploadProgress)(PP_Resource loader,
+ int64_t* bytes_sent,
+ int64_t* total_bytes_to_be_sent);
+
+ // Returns the current download progress, which is meaningful after Open has
+ // been called. Progress only refers to the response body. The total bytes
+ // to be received may be unknown, in which case -1 is returned. This method
+ // returns false if download progress is not available.
+ bool (*GetDownloadProgress)(PP_Resource loader,
+ int64_t* bytes_received,
+ int64_t* total_bytes_to_be_received);
+
+ // Returns the current URLResponseInfo object.
+ PP_Resource (*GetResponseInfo)(PP_Resource loader);
+
+ // Call this method to read the response body. The size of the buffer must
+ // be large enough to hold the specified number of bytes to read. May
+ // perform a partial read. Returns the number of bytes read or an error
+ // code.
+ int32_t (*ReadResponseBody)(PP_Resource loader,
+ char* buffer,
+ int32_t bytes_to_read,
+ struct PP_CompletionCallback callback);
+
+ // If PP_URLREQUESTPROPERTY_STREAMTOFILE was set on the URLRequestInfo passed
+ // to the Open method, then this method may be used to wait for the response
+ // body to be completely downloaded to the file provided by URLResponseInfo's
+ // GetBody method.
+ int32_t (*FinishStreamingToFile)(PP_Resource loader,
+ struct PP_CompletionCallback callback);
+
+ // Cancels any IO that may be pending, and closes the URLLoader object. Any
+ // pending callbacks will still run, reporting PP_ERROR_ABORTED if pending IO
+ // was interrupted. It is NOT valid to call Open again after a call to this
+ // method. Note: If the URLLoader object is destroyed, and it is still open,
+ // then it will be implicitly closed, so you are not required to call the
+ // Close method.
+ void (*Close)(PP_Resource loader);
+};
+
+#endif // PPAPI_C_DEV_PPB_URL_LOADER_DEV_H_
diff --git a/ppapi/c/dev/ppb_url_loader_trusted_dev.h b/ppapi/c/dev/ppb_url_loader_trusted_dev.h
new file mode 100644
index 0000000..4eabe14
--- /dev/null
+++ b/ppapi/c/dev/ppb_url_loader_trusted_dev.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_URL_LOADER_TRUSTED_DEV_H_
+#define PPAPI_C_DEV_PPB_URL_LOADER_TRUSTED_DEV_H_
+
+#include "ppapi/c/pp_resource.h"
+
+#define PPB_URLLOADERTRUSTED_DEV_INTERFACE "PPB_URLLoaderTrusted(Dev);0.1"
+
+// Available only to trusted implementations.
+struct PPB_URLLoaderTrusted_Dev {
+ // Grant this URLLoader the capability to make unrestricted cross-origin
+ // requests.
+ void (*GrantUniversalAccess)(PP_Resource loader);
+};
+
+#endif // PPAPI_C_DEV_PPB_URL_LOADER_DEV_H_
diff --git a/ppapi/c/dev/ppb_url_request_info_dev.h b/ppapi/c/dev/ppb_url_request_info_dev.h
new file mode 100644
index 0000000..2503a0c
--- /dev/null
+++ b/ppapi/c/dev/ppb_url_request_info_dev.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_URL_REQUEST_INFO_DEV_H_
+#define PPAPI_C_DEV_PPB_URL_REQUEST_INFO_DEV_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_time.h"
+
+struct PP_Var;
+
+typedef enum {
+ PP_URLREQUESTPROPERTY_URL, // string
+ PP_URLREQUESTPROPERTY_METHOD, // string
+ PP_URLREQUESTPROPERTY_HEADERS, // string, \n-delim
+ PP_URLREQUESTPROPERTY_STREAMTOFILE, // bool (default=false)
+ PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS, // bool (default=true)
+ PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS // bool (default=false)
+ // TODO(darin): Add security/privacy options?
+} PP_URLRequestProperty_Dev;
+
+#define PPB_URLREQUESTINFO_DEV_INTERFACE "PPB_URLRequestInfo(Dev);0.1"
+
+struct PPB_URLRequestInfo_Dev {
+ // Create a new URLRequestInfo object. Returns 0 if the module is invalid.
+ PP_Resource (*Create)(PP_Module module);
+
+ // Returns true if the given resource is an URLRequestInfo. Returns false if
+ // the resource is invalid or some type other than an URLRequestInfo.
+ bool (*IsURLRequestInfo)(PP_Resource resource);
+
+ // Sets a request property. Returns false if any of the parameters are
+ // invalid. The value property must be the correct type according to the
+ // property being set.
+ bool (*SetProperty)(PP_Resource request,
+ PP_URLRequestProperty_Dev property,
+ struct PP_Var value);
+
+ // Append data to the request body.
+ //
+ // A Content-Length request header will be automatically generated.
+ //
+ // Returns false if any of the parameters are invalid.
+ bool (*AppendDataToBody)(PP_Resource request, const char* data, uint32_t len);
+
+ // Append a file reference to be uploaded.
+ //
+ // A sub-range of the file starting from start_offset may be specified. If
+ // number_of_bytes is -1, then the sub-range to upload extends to the end of
+ // the file.
+ //
+ // An optional (non-zero) last modified time stamp may be provided, which
+ // will be used to validate that the file was not modified since the given
+ // time before it is uploaded. The upload will fail with an error code of
+ // PP_Error_FileChanged if the file has been modified since the given time.
+ // If expected_last_modified_time is 0, then no validation is performed.
+ //
+ // A Content-Length request header will be automatically generated.
+ //
+ // Returns false if any of the parameters are invalid.
+ bool (*AppendFileToBody)(PP_Resource request,
+ PP_Resource file_ref,
+ int64_t start_offset,
+ int64_t number_of_bytes,
+ PP_Time expected_last_modified_time);
+};
+
+#endif // PPAPI_C_DEV_PPB_URL_REQUEST_INFO_DEV_H_
diff --git a/ppapi/c/dev/ppb_url_response_info_dev.h b/ppapi/c/dev/ppb_url_response_info_dev.h
new file mode 100644
index 0000000..8e3a9e4
--- /dev/null
+++ b/ppapi/c/dev/ppb_url_response_info_dev.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_URL_RESPONSE_INFO_DEV_H_
+#define PPAPI_C_DEV_PPB_URL_RESPONSE_INFO_DEV_H_
+
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_var.h"
+
+typedef enum {
+ PP_URLRESPONSEPROPERTY_URL, // string
+ PP_URLRESPONSEPROPERTY_REDIRECTURL, // string
+ PP_URLRESPONSEPROPERTY_REDIRECTMETHOD, // string
+ PP_URLRESPONSEPROPERTY_STATUSCODE, // int32
+ PP_URLRESPONSEPROPERTY_STATUSLINE, // string
+ PP_URLRESPONSEPROPERTY_HEADERS // string, \n-delim
+} PP_URLResponseProperty_Dev;
+
+#define PPB_URLRESPONSEINFO_DEV_INTERFACE "PPB_URLResponseInfo(Dev);0.1"
+
+struct PPB_URLResponseInfo_Dev {
+ // Returns true if the given resource is an URLResponseInfo. Returns false if
+ // the resource is invalid or some type other than an URLResponseInfo.
+ bool (*IsURLResponseInfo)(PP_Resource resource);
+
+ // Gets a response property. Return PP_VarType_Void if an input parameter is
+ // invalid.
+ PP_Var (*GetProperty)(PP_Resource response,
+ PP_URLResponseProperty_Dev property);
+
+ // Returns a FileRef pointing to the file containing the response body. This
+ // is only valid if PP_URLREQUESTPROPERTY_STREAMTOFILE was set on the
+ // URLRequestInfo used to produce this response. This file remains valid
+ // until the URLLoader associated with this URLResponseInfo is closed or
+ // destroyed. Returns 0 if PP_URLREQUESTPROPERTY_STREAMTOFILE was not
+ // requested or if the URLLoader has not been opened yet.
+ PP_Resource (*GetBody)(PP_Resource response);
+};
+
+#endif // PPAPI_C_DEV_PPB_URL_RESPONSE_INFO_DEV_H_
diff --git a/ppapi/c/dev/ppb_url_util_dev.h b/ppapi/c/dev/ppb_url_util_dev.h
new file mode 100644
index 0000000..c16e59d
--- /dev/null
+++ b/ppapi/c/dev/ppb_url_util_dev.h
@@ -0,0 +1,111 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_URL_UTIL_DEV_H_
+#define PPAPI_C_DEV_PPB_URL_UTIL_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_URLUTIL_DEV_INTERFACE "PPB_UrlUtil(Dev);0.1"
+
+// A component specifies the range of the part of the URL. The begin specifies
+// the index into the string of the first character of that component. The len
+// specifies the length of that component.
+//
+// This range does not include any special delimiter for that component, so
+// the scheme doesn't include the trailing colon, the username and password
+// don't include the @ and :, the port doesn't include the colon, the query
+// doesn't include the ?, and the ref doesn't include the #.
+//
+// The exception is that the path *does* include the first /, since that's an
+// integral part of the path.
+//
+// If the component is not present at all, begin will be 0 and len will be -1.
+// If the component is present but empty, the length will be 0 instead. Example:
+// http://foo/search -> query = (0, -1)
+// http://foo/search? -> query = (18, 0)
+struct PP_UrlComponent_Dev {
+ int32_t begin;
+ int32_t len;
+};
+
+struct PP_UrlComponents_Dev {
+ PP_UrlComponent_Dev scheme;
+ PP_UrlComponent_Dev username;
+ PP_UrlComponent_Dev password;
+ PP_UrlComponent_Dev host;
+ PP_UrlComponent_Dev port;
+ PP_UrlComponent_Dev path;
+ PP_UrlComponent_Dev query;
+ PP_UrlComponent_Dev ref;
+};
+
+// URL encoding: URLs are supplied to this interface as NULL-terminated 8-bit
+// strings. You can pass non-ASCII characters which will be interpreted as
+// UTF-8. Canonicalized URL strings returned by these functions will be ASCII
+// except for the reference fragment (stuff after the '#') which will be
+// encoded as UTF-8.
+struct PPB_UrlUtil_Dev {
+ // Canonicalizes the given URL string according to the rules of the host
+ // browser. If the URL is invalid or the var is not a string, this will
+ // return a Null var and the components structure will be unchanged.
+ //
+ // The components pointer, if non-NULL and the canonicalized URL is valid,
+ // will identify the components of the resulting URL. Components may be NULL
+ // to specify that no component information is necessary.
+ struct PP_Var (*Canonicalize)(struct PP_Var url,
+ struct PP_UrlComponents_Dev* components);
+
+ // Resolves the given URL relative to the given base URL. The resulting URL
+ // is returned as a string. If the resolution is invalid or either of the
+ // inputs are not strings, a Null var will be returned. The resulting URL
+ // will also be canonicalized according to the rules of the browser.
+ //
+ // Note that the "relative" URL bay in fact be absolute, in which case it
+ // will be returned. This function is identical to resolving the full URL
+ // for an <a href="..."> on a web page. Attempting to resolve a relative URL
+ // on a base URL that doesn't support this (e.g. "data") will fail and will
+ // return a Null var, unless the relative URL is itself absolute.
+ //
+ // The components pointer, if non-NULL and the canonicalized URL is valid,
+ // will identify the components of the resulting URL. Components may be NULL
+ // to specify that no component information is necessary.
+ struct PP_Var (*ResolveRelativeToUrl)(
+ struct PP_Var base_url,
+ struct PP_Var relative_string,
+ struct PP_UrlComponents_Dev* components);
+
+ // Identical to ResolveRelativeToUrl except that the base URL is the base
+ // URL of the document containing the given plugin instance.
+ //
+ // Danger: This will be identical to resolving a relative URL on the page,
+ // and might be overridden by the page to something different than its actual
+ // URL via the <base> tag. Therefore, resolving a relative URL of "" won't
+ // necessarily give you the URL of the page!
+ struct PP_Var (*ResolveRelativeToDocument)(
+ PP_Instance instance,
+ struct PP_Var relative_string,
+ struct PP_UrlComponents_Dev* components);
+
+ // Checks whether the given two URLs are in the same security origin. Returns
+ // false if either of the URLs are invalid.
+ bool (*IsSameSecurityOrigin)(struct PP_Var url_a, struct PP_Var url_b);
+
+ // Checks whether the document hosting the given plugin instance can access
+ // the given URL according to the same origin policy of the browser. Returns
+ // false if the instance or the URL is invalid.
+ bool (*DocumentCanRequest)(PP_Instance instance, struct PP_Var url);
+
+ // Checks whether the document containing the |active| plugin instance can
+ // access the document containing the |target| plugin instance according to
+ // the security policy of the browser. This includes the same origin policy
+ // and any cross-origin capabilities enabled by the document. If either of
+ // the plugin instances are invalid, returns false.
+ bool (*DocumentCanAccessDocument)(PP_Instance active, PP_Instance target);
+};
+
+#endif // PPAPI_C_DEV_PPB_URL_UTIL_DEV_H_
+
diff --git a/ppapi/c/dev/ppb_var_deprecated.h b/ppapi/c/dev/ppb_var_deprecated.h
new file mode 100644
index 0000000..51194b2
--- /dev/null
+++ b/ppapi/c/dev/ppb_var_deprecated.h
@@ -0,0 +1,243 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPB_VAR_DEPRECATED_H_
+#define PPAPI_C_PPB_VAR_DEPRECATED_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+struct PPP_Class_Deprecated;
+
+#define PPB_VAR_DEPRECATED_INTERFACE "PPB_Var(Deprecated);0.1"
+
+/**
+ * @file
+ * Defines the PPB_Var_Deprecated struct.
+ * See http://code.google.com/p/ppapi/wiki/InterfacingWithJavaScript
+ * for general information on using this interface.
+ * {PENDING: Should the generated doc really be pointing to methods?}
+ *
+ * @addtogroup PPB
+ * @{
+ */
+
+struct PPB_Var_Deprecated {
+ /**
+ * Adds a reference to the given var. If this is not a refcounted object,
+ * this function will do nothing so you can always call it no matter what the
+ * type.
+ */
+ void (*AddRef)(struct PP_Var var);
+
+ /**
+ * Removes a reference to given var, deleting it if the internal refcount
+ * becomes 0. If the given var is not a refcounted object, this function will
+ * do nothing so you can always call it no matter what the type.
+ */
+ void (*Release)(struct PP_Var var);
+
+ /**
+ * Creates a string var from a string. The string must be encoded in valid
+ * UTF-8 and is NOT NULL-terminated, the length must be specified in |len|.
+ * It is an error if the string is not valid UTF-8.
+ *
+ * If the length is 0, the |data| pointer will not be dereferenced and may
+ * be NULL. Note, however, that if you do this, the "NULL-ness" will not be
+ * preserved, as VarToUtf8 will never return NULL on success, even for empty
+ * strings.
+ *
+ * The resulting object will be a refcounted string object. It will be
+ * AddRef()ed for the caller. When the caller is done with it, it should be
+ * Release()d.
+ *
+ * On error (basically out of memory to allocate the string, or input that
+ * is not valid UTF-8), this function will return a Null var.
+ */
+ struct PP_Var (*VarFromUtf8)(PP_Module module,
+ const char* data, uint32_t len);
+
+ /**
+ * Converts a string-type var to a char* encoded in UTF-8. This string is NOT
+ * NULL-terminated. The length will be placed in |*len|. If the string is
+ * valid but empty the return value will be non-NULL, but |*len| will still
+ * be 0.
+ *
+ * If the var is not a string, this function will return NULL and |*len| will
+ * be 0.
+ *
+ * The returned buffer will be valid as long as the underlying var is alive.
+ * If the plugin frees its reference, the string will be freed and the pointer
+ * will be to random memory.
+ */
+ const char* (*VarToUtf8)(struct PP_Var var, uint32_t* len);
+
+ /**
+ * Returns true if the property with the given name exists on the given
+ * object, false if it does not. Methods are also counted as properties.
+ *
+ * The name can either be a string or an integer var. It is an error to pass
+ * another type of var as the name.
+ *
+ * If you pass an invalid name or object, the exception will be set (if it is
+ * non-NULL, and the return value will be false).
+ */
+ bool (*HasProperty)(struct PP_Var object,
+ struct PP_Var name,
+ struct PP_Var* exception);
+
+ /**
+ * Identical to HasProperty, except that HasMethod additionally checks if the
+ * property is a function.
+ */
+ bool (*HasMethod)(struct PP_Var object,
+ struct PP_Var name,
+ struct PP_Var* exception);
+
+ /**
+ * Returns the value of the given property. If the property doesn't exist, the
+ * exception (if non-NULL) will be set and a "Void" var will be returned.
+ */
+ struct PP_Var (*GetProperty)(struct PP_Var object,
+ struct PP_Var name,
+ struct PP_Var* exception);
+
+ /**
+ * Retrieves all property names on the given object. Property names include
+ * methods.
+ *
+ * If there is a failure, the given exception will be set (if it is non-NULL).
+ * On failure, |*properties| will be set to NULL and |*property_count| will be
+ * set to 0.
+ *
+ * A pointer to the array of property names will be placesd in |*properties|.
+ * The caller is responsible for calling Release() on each of these properties
+ * (as per normal refcounted memory management) as well as freeing the array
+ * pointer with PPB_Core.MemFree().
+ *
+ * This function returns all "enumerable" properties. Some JavaScript
+ * properties are "hidden" and these properties won't be retrieved by this
+ * function, yet you can still set and get them.
+ *
+ * Example:
+ * <pre> uint32_t count;
+ * PP_Var* properties;
+ * ppb_var.GetAllPropertyNames(object, &count, &properties);
+ *
+ * ...use the properties here...
+ *
+ * for (uint32_t i = 0; i < count; i++)
+ * ppb_var.Release(properties[i]);
+ * ppb_core.MemFree(properties); </pre>
+ */
+ void (*GetAllPropertyNames)(struct PP_Var object,
+ uint32_t* property_count,
+ struct PP_Var** properties,
+ struct PP_Var* exception);
+
+ /**
+ * Sets the property with the given name on the given object. The exception
+ * will be set, if it is non-NULL, on failure.
+ */
+ void (*SetProperty)(struct PP_Var object,
+ struct PP_Var name,
+ struct PP_Var value,
+ struct PP_Var* exception);
+
+ /**
+ * Removes the given property from the given object. The property name must
+ * be an string or integer var, using other types will throw an exception
+ * (assuming the exception pointer is non-NULL).
+ */
+ void (*RemoveProperty)(struct PP_Var object,
+ struct PP_Var name,
+ struct PP_Var* exception);
+
+ // TODO(brettw) need native array access here.
+
+ /**
+ * Invoke the function |method_name| on the given object. If |method_name|
+ * is a Null var, the default method will be invoked, which is how you can
+ * invoke function objects.
+ *
+ * Unless it is type Null, |method_name| must be a string. Unlike other
+ * Var functions, integer lookup is not supported since you can't call
+ * functions on integers in JavaScript.
+ *
+ * Pass the arguments to the function in order in the |argv| array, and the
+ * number of arguments in the |argc| parameter. |argv| can be NULL if |argc|
+ * is zero.
+ *
+ * Example:
+ * Call(obj, VarFromUtf8("DoIt"), 0, NULL, NULL) = obj.DoIt() in JavaScript.
+ * Call(obj, PP_MakeNull(), 0, NULL, NULL) = obj() in JavaScript.
+ */
+ struct PP_Var (*Call)(struct PP_Var object,
+ struct PP_Var method_name,
+ uint32_t argc,
+ struct PP_Var* argv,
+ struct PP_Var* exception);
+
+ /**
+ * Invoke the object as a constructor.
+ *
+ * For example, if |object| is |String|, this is like saying |new String| in
+ * JavaScript.
+ */
+ struct PP_Var (*Construct)(struct PP_Var object,
+ uint32_t argc,
+ struct PP_Var* argv,
+ struct PP_Var* exception);
+
+ /**
+ * If the object is an instance of the given class, then this method returns
+ * true and sets *object_data to the value passed to CreateObject provided
+ * object_data is non-NULL. Otherwise, this method returns false.
+ */
+ bool (*IsInstanceOf)(struct PP_Var var,
+ const struct PPP_Class_Deprecated* object_class,
+ void** object_data);
+
+ /**
+ * Creates an object that the plugin implements. The plugin supplies a
+ * pointer to the class interface it implements for that object, and its
+ * associated internal data that represents that object.
+ *
+ * The returned object will have a reference count of 1. When the reference
+ * count reached 0, the class' Destruct function wlil be called.
+ *
+ * On failure, this will return a null var. This probably means the module
+ * was invalid.
+ *
+ * Example: Say we're implementing a "Point" object.
+ * <pre> void PointDestruct(void* object) {
+ * delete (Point*)object;
+ * }
+ *
+ * const PPP_Class_Deprecated point_class = {
+ * ... all the other class functions go here ...
+ * &PointDestruct
+ * };
+ *
+ * * The plugin's internal object associated with the point.
+ * class Point {
+ * ...
+ * };
+ *
+ * PP_Var MakePoint(int x, int y) {
+ * return CreateObject(&point_class, new Point(x, y));
+ * }</pre>
+ */
+ struct PP_Var (*CreateObject)(PP_Module module,
+ const struct PPP_Class_Deprecated* object_class,
+ void* object_data);
+};
+
+/**
+ * @}
+ * End addtogroup PPB
+ */
+#endif // PPAPI_C_PPB_VAR_DEPRECATED_H_
+
diff --git a/ppapi/c/dev/ppb_video_decoder_dev.h b/ppapi/c/dev/ppb_video_decoder_dev.h
new file mode 100644
index 0000000..33274de
--- /dev/null
+++ b/ppapi/c/dev/ppb_video_decoder_dev.h
@@ -0,0 +1,86 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_VIDEO_DECODER_DEV_H_
+#define PPAPI_C_DEV_PPB_VIDEO_DECODER_DEV_H_
+
+#include "ppapi/c/dev/pp_video_dev.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_completion_callback.h"
+
+#define PPB_VIDEODECODER_DEV_INTERFACE "PPB_VideoDecoder(Dev);0.1"
+
+struct PPB_VideoDecoder_Dev {
+ // Queries capability of the decoder for |codec|.
+ // |codec| is the requested codec id.
+ // |configs| is a pointer to a buffer containing |config_size| elements.
+ // The number of configurations is returned in |num_config|. Element 0 through
+ // |num_config| - 1 of |configs| are filled in with valid PP_VideoConfig's.
+ // No more than |config_size| PP_VideoConfig's will be returned even if more
+ // are available on the device.
+ // When this function is called with |configs| = NULL, then no configurations
+ // are returned, but the total number of configurations available will be
+ // returned in |num_config|.
+ //
+ // Returns true on success, false otherwise.
+ // NOTE: browser owns the memory of all PP_VideoConfig's.
+ bool (*GetConfig)(PP_Instance instance,
+ PP_VideoCodecId_Dev codec,
+ PP_VideoConfig_Dev* configs,
+ int32_t config_size,
+ int32_t* num_config);
+
+ // Creates a video decoder with requested |decoder_config|.
+ // |input_format| in |decoder_config| specifies the format of input access
+ // unit, with PP_VIDEOKEY_CODECID and PP_VIDEOKEY_PAYLOADFORMAT required.
+ // Plugin has the option to specify codec profile/level and other
+ // information such as PP_VIDEOKEY_ACCELERATION, to let browser choose
+ // the most appropriate decoder.
+ //
+ // |output_format| in |decoder_config| specifies desired decoded frame buffer
+ // format, with PP_VIDEOKEY_COLORTYPE and PP_VIDEOKEY_SURFACETYPE required.
+ //
+ // |output_callback| in |decoder_config| specifies the callback function
+ // for decoder to deliver decoded frame buffers. Decoder shall retain it.
+ //
+ // |input_callback| in |decoder_config| specifies the callback function
+ // for decoder to return compressed data buffers to plugin. Decoder shall
+ // retain it. When plugin doesn't expect buffer recycling, it shall set
+ // |input_callback| to NULL. In this case, plugin shall allocate buffer via
+ // |MemAlloc| in PPB_Core interface, and decoder will free buffer via
+ // |MemFree| in the same API.
+ //
+ // |event_handler| in |decoder_config| specifies the function for decoder
+ // to deliver events to plugin. Decoder shall retain it.
+ //
+ // The created decoder is returned as PP_Resource. NULL means failure.
+ PP_Resource (*Create)(PP_Instance instance,
+ const struct PP_VideoDecoderConfig_Dev* decoder_config);
+
+ // Sends bit stream in |input_buffer| to the decoder.
+ // This is a non-blocking call.
+ // The decoded frame will be returned by decoder calling |output_callback|
+ // provided by plugin during creation of decoder.
+ // The input data buffer is returned to plugin by decoder only when plugin
+ // provides |input_callback|.
+ // Returns true on decoder successfully accepting buffer, false otherwise.
+ //
+ bool (*Decode)(PP_Resource decoder,
+ struct PP_VideoCompressedDataBuffer_Dev* input_buffer);
+
+ // Requests the decoder to flush its input and output buffers. Once done with
+ // flushing, the decode will call the |callback|.
+ int32_t (*Flush)(PP_Resource decoder,
+ PP_CompletionCallback callback);
+
+ // Plugin sends uncompressed data buffers to the decoder.
+ // Returns true on decoder successfully accepting the buffer, false otherwise.
+ bool (*ReturnUncompressedDataBuffer)(
+ PP_Resource decoder,
+ struct PP_VideoUncompressedDataBuffer_Dev* buffer);
+};
+
+#endif // PPAPI_C_DEV_PPB_VIDEO_DECODER_DEV_H_
diff --git a/ppapi/c/dev/ppb_widget_dev.h b/ppapi/c/dev/ppb_widget_dev.h
new file mode 100644
index 0000000..0319b22
--- /dev/null
+++ b/ppapi/c/dev/ppb_widget_dev.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_WIDGET_DEV_H_
+#define PPAPI_C_DEV_PPB_WIDGET_DEV_H_
+
+#include "ppapi/c/pp_resource.h"
+
+struct PP_Rect;
+struct PP_InputEvent;
+
+#define PPB_WIDGET_DEV_INTERFACE "PPB_Widget(Dev);0.1"
+
+// The interface for reusing browser widgets.
+struct PPB_Widget_Dev {
+ // Returns true if the given resource is a Widget. Returns false if the
+ // resource is invalid or some type other than an Widget.
+ bool (*IsWidget)(PP_Resource resource);
+
+ // Paint the given rectangle of the widget into the given image.
+ // Returns true on success, false on failure
+ bool (*Paint)(PP_Resource widget,
+ const struct PP_Rect* rect,
+ PP_Resource image);
+
+ // Pass in an event to a widget. It'll return true if the event was consumed.
+ bool (*HandleEvent)(PP_Resource widget,
+ const struct PP_InputEvent* event);
+
+ // Get/set the location of the widget.
+ bool (*GetLocation)(PP_Resource widget,
+ struct PP_Rect* location);
+
+ void (*SetLocation)(PP_Resource widget,
+ const struct PP_Rect* location);
+};
+
+#endif // PPAPI_C_DEV_PPB_WIDGET_DEV_H_
diff --git a/ppapi/c/dev/ppb_zoom_dev.h b/ppapi/c/dev/ppb_zoom_dev.h
new file mode 100644
index 0000000..e6046e1
--- /dev/null
+++ b/ppapi/c/dev/ppb_zoom_dev.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPB_ZOOM_DEV_H_
+#define PPAPI_C_DEV_PPB_ZOOM_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+
+// Zoom interface should only apply to those full-page "plugin-document".
+#define PPB_ZOOM_DEV_INTERFACE "PPB_Zoom(Dev);0.1"
+
+struct PPB_Zoom_Dev {
+ // Informs the browser about the new zoom factor for the plugin (see
+ // ppp_zoom_dev.h for a description of zoom factor). The plugin should only
+ // call this function if the zoom change was triggered by the browser, it's
+ // only needed in case a plugin can update its own zoom, say because of its
+ // own UI.
+ void (*ZoomChanged)(PP_Instance instance,
+ double factor);
+
+ // Sets the mininum and maximium zoom factors.
+ void (*ZoomLimitsChanged)(PP_Instance instance,
+ double minimum_factor,
+ double maximium_factor);
+};
+
+#endif // PPAPI_C_DEV_PPB_ZOOM_DEV_H_
diff --git a/ppapi/c/dev/ppp_class_deprecated.h b/ppapi/c/dev/ppp_class_deprecated.h
new file mode 100644
index 0000000..d8a1349
--- /dev/null
+++ b/ppapi/c/dev/ppp_class_deprecated.h
@@ -0,0 +1,134 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPP_CLASS_DEPRECATED_H_
+#define PPAPI_C_PPP_CLASS_DEPRECATED_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+/**
+ * @file
+ * Defines the PPP_Class_Deprecated struct.
+ *
+ * @addtogroup PPP
+ * @{
+ */
+
+struct PP_Var;
+
+/**
+ * Interface for the plugin to implement JavaScript-accessible objects.
+ *
+ * This interface has no interface name. Instead, the plugin passes a pointer
+ * to this interface to PPB_Var_Deprecated.CreateObject that corresponds to the
+ * object being implemented.
+ *
+ * See the PPB_Var_Deprecated interface for more information on these functions.
+ * This interface just allows you to implement the "back end" of those
+ * functions, so most of the contract is specified in that interface.
+ *
+ * See
+ * http://code.google.com/p/ppapi/wiki/InterfacingWithJavaScript
+ * for general information on using and implementing vars.
+ */
+struct PPP_Class_Deprecated {
+ /**
+ * |name| is guaranteed to be an integer or string type var. Exception is
+ * guaranteed non-NULL. An integer is used for |name| when implementing
+ * array access into the object. This test should only return true for
+ * properties that are not methods. Use HasMethod() to handle methods.
+ */
+ bool (*HasProperty)(void* object,
+ struct PP_Var name,
+ struct PP_Var* exception);
+
+ /**
+ * |name| is guaranteed to be a string-type. Exception is guaranteed non-NULL.
+ * If the method does not exist, return false and don't set the exception.
+ * Errors in this function will probably not occur in general usage, but
+ * if you need to throw an exception, still return false.
+ */
+ bool (*HasMethod)(void* object,
+ struct PP_Var name,
+ struct PP_Var* exception);
+
+ /**
+ * |name| is guaranteed to be a string-type or an integer-type var. Exception
+ * is guaranteed non-NULL. An integer is used for |name| when implementing
+ * array access into the object. If the property does not exist, set the
+ * exception and return a var of type Void. A property does not exist if
+ * a call HasProperty() for the same |name| would return false.
+ */
+ struct PP_Var (*GetProperty)(void* object,
+ struct PP_Var name,
+ struct PP_Var* exception);
+
+ /**
+ * Exception is guaranteed non-NULL.
+ *
+ * This should include all enumerable properties, including methods. Be sure
+ * to set |*property_count| to 0 and |properties| to NULL in all failure
+ * cases, these should never be unset when calling this function. The
+ * pointers passed in are guaranteed not to be NULL, so you don't have to
+ * NULL check them.
+ *
+ * If you have any properties, allocate the property array with
+ * PPB_Core.MemAlloc(sizeof(PP_Var) * property_count) and add a reference
+ * to each property on behalf of the caller. The caller is responsible for
+ * Release()ing each var and calling PPB_Core.MemFree on the property pointer.
+ */
+ void (*GetAllPropertyNames)(void* object,
+ uint32_t* property_count,
+ struct PP_Var** properties,
+ struct PP_Var* exception);
+
+ /**
+ * |name| is guaranteed to be an integer or string type var. Exception is
+ * guaranteed non-NULL.
+ */
+ void (*SetProperty)(void* object,
+ struct PP_Var name,
+ struct PP_Var value,
+ struct PP_Var* exception);
+
+ /**
+ * |name| is guaranteed to be an integer or string type var. Exception is
+ * guaranteed non-NULL.
+ */
+ void (*RemoveProperty)(void* object,
+ struct PP_Var name,
+ struct PP_Var* exception);
+
+ // TODO(brettw) need native array access here.
+
+ /**
+ * |name| is guaranteed to be a string type var. Exception is guaranteed
+ * non-NULL
+ */
+ struct PP_Var (*Call)(void* object,
+ struct PP_Var method_name,
+ uint32_t argc,
+ struct PP_Var* argv,
+ struct PP_Var* exception);
+
+ /** Exception is guaranteed non-NULL. */
+ struct PP_Var (*Construct)(void* object,
+ uint32_t argc,
+ struct PP_Var* argv,
+ struct PP_Var* exception);
+
+ /**
+ * Called when the reference count of the object reaches 0. Normally, plugins
+ * would free their internal data pointed to by the |object| pointer.
+ */
+ void (*Deallocate)(void* object);
+};
+
+/**
+ * @}
+ * End addtogroup PPP
+ */
+#endif // PPAPI_C_PPP_CLASS_DEPRECATED_H_
+
diff --git a/ppapi/c/dev/ppp_cursor_control_dev.h b/ppapi/c/dev/ppp_cursor_control_dev.h
new file mode 100644
index 0000000..b9403f4
--- /dev/null
+++ b/ppapi/c/dev/ppp_cursor_control_dev.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPP_CURSOR_CONTROL_DEV_H_
+#define PPAPI_C_DEV_PPP_CURSOR_CONTROL_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+
+#define PPP_CURSOR_CONTROL_DEV_INTERFACE "PPP_CursorControl(Dev);0.1"
+
+struct PPP_CursorControl_Dev {
+ // Called when the instance looses the cursor lock, e.g. because the user
+ // pressed the ESC key.
+ void (*CursorLockLost)(PP_Instance instance);
+};
+
+#endif // PPAPI_C_DEV_PPP_CURSOR_CONTROL_DEV_H_
+
diff --git a/ppapi/c/dev/ppp_find_dev.h b/ppapi/c/dev/ppp_find_dev.h
new file mode 100644
index 0000000..98586a3
--- /dev/null
+++ b/ppapi/c/dev/ppp_find_dev.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPP_FIND_DEV_H_
+#define PPAPI_C_DEV_PPP_FIND_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+
+#define PPP_FIND_DEV_INTERFACE "PPP_Find(Dev);0.1"
+
+struct PPP_Find_Dev {
+ // Finds the given UTF-8 text starting at the current selection. The number of
+ // results will be updated asynchronously via NumberOfFindResultsChanged in
+ // PPB_Find. Note that multiple StartFind calls can happen before StopFind is
+ // called in the case of the search term changing.
+ //
+ // Return false if plugin doesn't support find in page. Consequently, it won't
+ // call any callbacks.
+ bool (*StartFind)(PP_Instance instance,
+ const char* text,
+ bool case_sensitive);
+
+ // Go to the next/previous result.
+ void (*SelectFindResult)(PP_Instance instance,
+ bool forward);
+
+ // Tells the plugin that the find operation has stopped, so it should clear
+ // any highlighting.
+ void (*StopFind)(PP_Instance instance);
+};
+
+#endif // PPAPI_C_DEV_PPP_FIND_DEV_H_
diff --git a/ppapi/c/dev/ppp_graphics_3d_dev.h b/ppapi/c/dev/ppp_graphics_3d_dev.h
new file mode 100644
index 0000000..2dc4402
--- /dev/null
+++ b/ppapi/c/dev/ppp_graphics_3d_dev.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPP_GRAPHICS_3D_DEV_H_
+#define PPAPI_C_DEV_PPP_GRAPHICS_3D_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+
+#define PPP_GRAPHICS_3D_DEV_INTERFACE "PPP_Graphics_3D(Dev);0.1"
+
+struct PPP_Graphics3D_Dev {
+ // Called when the OpenGL ES window is invalidated and needs to be repainted.
+ void (*Graphics3DContextLost)(PP_Instance instance);
+};
+
+#endif // PPAPI_C_DEV_PPP_GRAPHICS_3D_DEV_H_
+
diff --git a/ppapi/c/dev/ppp_printing_dev.h b/ppapi/c/dev/ppp_printing_dev.h
new file mode 100644
index 0000000..0a4316e
--- /dev/null
+++ b/ppapi/c/dev/ppp_printing_dev.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPP_PRINTING_DEV_H_
+#define PPAPI_C_DEV_PPP_PRINTING_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_rect.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+typedef enum {
+ PP_PRINTORIENTATION_NORMAL = 0,
+ PP_PRINTORIENTATION_ROTATED_90_CW = 1,
+ PP_PRINTORIENTATION_ROTATED_180 = 2,
+ PP_PRINTORIENTATION_ROTATED_90_CCW = 3
+} PP_PrintOrientation_Dev;
+
+typedef enum {
+ PP_PRINTOUTPUTFORMAT_RASTER = 0,
+ PP_PRINTOUTPUTFORMAT_PDF = 1,
+ PP_PRINTOUTPUTFORMAT_POSTSCRIPT = 2
+} PP_PrintOutputFormat_Dev;
+
+struct PP_PrintSettings_Dev {
+ // This is the size of the printable area in points (1/72 of an inch)
+ struct PP_Rect printable_area;
+ int32_t dpi;
+ PP_PrintOrientation_Dev orientation;
+ bool grayscale;
+ PP_PrintOutputFormat_Dev format;
+};
+
+// Specifies a contiguous range of page numbers to be printed.
+// The page numbers use a zero-based index.
+struct PP_PrintPageNumberRange_Dev {
+ uint32_t first_page_number;
+ uint32_t last_page_number;
+};
+
+// Interface for the plugin to implement printing.
+#define PPP_PRINTING_DEV_INTERFACE "PPP_Printing(Dev);0.1"
+
+struct PPP_Printing_Dev {
+ // Returns array of supported print output formats. The array is allocated
+ // using PPB_Core.MemAlloc. The caller is responsible for freeing the array
+ // using PPB_Core.MemFree.
+ // Sets |*format_count| to 0 returns NULL if printing is not supported at all.
+ PP_PrintOutputFormat_Dev* (*QuerySupportedFormats)(PP_Instance instance,
+ uint32_t* format_count);
+
+ // Begins a print session with the given print settings. Calls to PrintPage
+ // can only be made after a successful call to Begin. Returns the number of
+ // pages required for the print output at the given page size (0 indicates
+ // a failure).
+ int32_t (*Begin)(PP_Instance instance,
+ const struct PP_PrintSettings_Dev* print_settings);
+
+ // Prints the specified pages using the format specified in Begin.
+ // Returns a resource that represents the printed output.
+ // This is a PPB_ImageData resource if the output format is
+ // PP_PrintOutputFormat_Raster and a PPB_Blob otherwise. Returns 0 on failure.
+ PP_Resource (*PrintPages)(
+ PP_Instance instance,
+ const struct PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count);
+
+ // Ends the print session. Further calls to PrintPage will fail.
+ void (*End)(PP_Instance instance);
+};
+
+#endif // PPAPI_C_DEV_PPP_PRINTING_DEV_H_
+
diff --git a/ppapi/c/dev/ppp_scrollbar_dev.h b/ppapi/c/dev/ppp_scrollbar_dev.h
new file mode 100644
index 0000000..73688f42
--- /dev/null
+++ b/ppapi/c/dev/ppp_scrollbar_dev.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPP_SCROLLBAR_DEV_H_
+#define PPAPI_C_DEv_PPP_SCROLLBAR_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+// Interface for the plugin to implement when using a scrollbar widget.
+#define PPP_SCROLLBAR_DEV_INTERFACE "PPP_Scrollbar(Dev);0.1"
+
+struct PPP_Scrollbar_Dev {
+ // Informs the instance that the scrollbar's value has changed.
+ void (*ValueChanged)(PP_Instance instance,
+ PP_Resource scrollbar,
+ uint32_t value);
+};
+
+#endif // PPAPI_C_DEV_PPP_SCROLLBAR_DEV_H_
diff --git a/ppapi/c/dev/ppp_selection_dev.h b/ppapi/c/dev/ppp_selection_dev.h
new file mode 100644
index 0000000..bcdc97d
--- /dev/null
+++ b/ppapi/c/dev/ppp_selection_dev.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPP_SELECTION_DEV_H_
+#define PPAPI_C_DEV_PPP_SELECTION_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPP_SELECTION_DEV_INTERFACE "PPP_Selection(Dev);0.1"
+
+struct PPP_Selection_Dev {
+ /**
+ * Returns the selection, either as plain text or as html depending on "html".
+ * If nothing is selected, or if the given format is unavailable, return a
+ * void string.
+ */
+ struct PP_Var (*GetSelectedText)(PP_Instance instance,
+ bool html);
+};
+
+#endif // PPAPI_C_DEV_PPP_SELECTION_DEV_H_
diff --git a/ppapi/c/dev/ppp_widget_dev.h b/ppapi/c/dev/ppp_widget_dev.h
new file mode 100644
index 0000000..26a4847
--- /dev/null
+++ b/ppapi/c/dev/ppp_widget_dev.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPP_WIDGET_DEV_H_
+#define PPAPI_C_DEV_PPP_WIDGET_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_rect.h"
+
+// Interface for the plugin to implement when using a widget.
+#define PPP_WIDGET_DEV_INTERFACE "PPP_Widget(Dev);0.1"
+
+struct PPP_Widget_Dev {
+ // Informs the instance that the given rectangle needs to be repainted.
+ void (*Invalidate)(PP_Instance instance,
+ PP_Resource widget,
+ const struct PP_Rect* dirty_rect);
+};
+
+#endif // PPAPI_C_DEV_PPP_WIDGET_DEV_H_
diff --git a/ppapi/c/dev/ppp_zoom_dev.h b/ppapi/c/dev/ppp_zoom_dev.h
new file mode 100644
index 0000000..725ff69
--- /dev/null
+++ b/ppapi/c/dev/ppp_zoom_dev.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_DEV_PPP_ZOOM_DEV_H_
+#define PPAPI_C_DEV_PPP_ZOOM_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+
+// Zoom interface should only apply to those full-page "plugin-document".
+#define PPP_ZOOM_DEV_INTERFACE "PPP_Zoom(Dev);0.1"
+
+struct PPP_Zoom_Dev {
+ // Instruct plug-in to zoom according to the given factor and whether the zoom
+ // only applies to text only. The scale factor is the percentage divided by
+ // 100, i.e. 150% zoom is 1.5.
+ void (*Zoom)(PP_Instance instance,
+ double factor,
+ bool text_only);
+};
+
+#endif // PPAPI_C_DEV_PPP_ZOOM_DEV_H_
diff --git a/ppapi/c/pp_completion_callback.h b/ppapi/c/pp_completion_callback.h
new file mode 100644
index 0000000..3944a815
--- /dev/null
+++ b/ppapi/c/pp_completion_callback.h
@@ -0,0 +1,64 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_COMPLETION_CALLBACK_H_
+#define PPAPI_C_PP_COMPLETION_CALLBACK_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+#include <stdlib.h>
+
+#include "ppapi/c/pp_stdint.h"
+
+typedef void (*PP_CompletionCallback_Func)(void* user_data, int32_t result);
+
+/**
+ * Any method that takes a PP_CompletionCallback has the option of completing
+ * asynchronously if the operation would block. Such a method should return
+ * PP_Error_WouldBlock to indicate when the method will complete
+ * asynchronously. If the completion callback is NULL, then the operation will
+ * block if necessary to complete its work. PP_BlockUntilComplete() provides a
+ * convenient way to specify blocking behavior.
+ *
+ * The result parameter passes an int32_t that if negative indicates an error
+ * code. Otherwise the result value indicates success. If it is a positive
+ * value then it may carry additional information.
+ */
+struct PP_CompletionCallback {
+ PP_CompletionCallback_Func func;
+ void* user_data;
+};
+
+inline struct PP_CompletionCallback PP_MakeCompletionCallback(
+ PP_CompletionCallback_Func func,
+ void* user_data) {
+ struct PP_CompletionCallback cc = { func, user_data };
+ return cc;
+}
+
+inline void PP_RunCompletionCallback(struct PP_CompletionCallback* cc,
+ int32_t res) {
+ cc->func(cc->user_data, res);
+}
+
+/**
+ * Use this in place of an actual completion callback to request blocking
+ * behavior. If specified, the calling thread will block until a method
+ * completes. This is only usable from background threads.
+ */
+inline struct PP_CompletionCallback PP_BlockUntilComplete() {
+ return PP_MakeCompletionCallback(NULL, NULL);
+}
+
+/**
+ * @}
+ * End of addtogroup PP
+ */
+#endif // PPAPI_C_PP_COMPLETION_CALLBACK_H_
diff --git a/ppapi/c/pp_errors.h b/ppapi/c/pp_errors.h
new file mode 100644
index 0000000..a5ab5d1
--- /dev/null
+++ b/ppapi/c/pp_errors.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_ERRORS_H_
+#define PPAPI_C_PP_ERRORS_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+/** Errors are negative valued. */
+enum {
+ PP_OK = 0,
+
+ /**
+ * Returned by a function, taking a PP_CompletionCallback, that cannot
+ * complete synchronously. This return value indicates that the given
+ * callback will be asynchronously notified of the final result once it is
+ * available.
+ */
+ PP_ERROR_WOULDBLOCK = -1,
+
+ /** Indicates failure for unspecified reasons. */
+ PP_ERROR_FAILED = -2,
+
+ /**
+ * Indicates failure due to an asynchronous operation being interrupted,
+ * typically as a result of user action.
+ */
+ PP_ERROR_ABORTED = -3,
+
+ /** Indicates failure due to an invalid argument. */
+ PP_ERROR_BADARGUMENT = -4,
+
+ /** Indicates failure due to an invalid PP_Resource. */
+ PP_ERROR_BADRESOURCE = -5,
+
+ /** Indicates failure due to an unavailable PPAPI interface. */
+ PP_ERROR_NOINTERFACE = -6,
+
+ /** Indicates failure due to insufficient privileges. */
+ PP_ERROR_NOACCESS = -7,
+
+ /** Indicates failure due to insufficient memory. */
+ PP_ERROR_NOMEMORY = -8,
+
+ /** Indicates failure due to insufficient storage space. */
+ PP_ERROR_NOSPACE = -9,
+
+ /** Indicates failure due to insufficient storage quota. */
+ PP_ERROR_NOQUOTA = -10,
+
+ /** Indicates failure due to an action already being in progress. */
+ PP_ERROR_INPROGRESS = -11,
+
+ /** Indicates failure due to a file that does not exist. */
+ PP_ERROR_FILENOTFOUND = -20,
+
+ /** Indicates failure due to a file that already exists. */
+ PP_ERROR_FILEEXISTS = -21,
+
+ /** Indicates failure due to a file that is too big. */
+ PP_ERROR_FILETOOBIG = -22,
+
+ /** Indicates failure due to a file having been modified unexpectedly. */
+ PP_ERROR_FILECHANGED = -23,
+
+ /** Indicates failure due to a time limit being exceeded. */
+ PP_ERROR_TIMEDOUT = -30
+};
+
+/**
+ * @}
+ * End of addtogroup PP
+ */
+
+#endif // PPAPI_C_PP_ERRORS_H_
diff --git a/ppapi/c/pp_input_event.h b/ppapi/c/pp_input_event.h
new file mode 100644
index 0000000..eddfb2d
--- /dev/null
+++ b/ppapi/c/pp_input_event.h
@@ -0,0 +1,181 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_INPUT_EVENT_H_
+#define PPAPI_C_PP_INPUT_EVENT_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_time.h"
+
+typedef enum {
+ PP_INPUTEVENT_MOUSEBUTTON_NONE = -1,
+ PP_INPUTEVENT_MOUSEBUTTON_LEFT = 0,
+ PP_INPUTEVENT_MOUSEBUTTON_MIDDLE = 1,
+ PP_INPUTEVENT_MOUSEBUTTON_RIGHT = 2
+} PP_InputEvent_MouseButton;
+
+typedef enum {
+ PP_INPUTEVENT_TYPE_UNDEFINED = -1,
+ PP_INPUTEVENT_TYPE_MOUSEDOWN = 0,
+ PP_INPUTEVENT_TYPE_MOUSEUP = 1,
+ PP_INPUTEVENT_TYPE_MOUSEMOVE = 2,
+ PP_INPUTEVENT_TYPE_MOUSEENTER = 3,
+ PP_INPUTEVENT_TYPE_MOUSELEAVE = 4,
+ PP_INPUTEVENT_TYPE_MOUSEWHEEL = 5,
+ PP_INPUTEVENT_TYPE_RAWKEYDOWN = 6,
+ PP_INPUTEVENT_TYPE_KEYDOWN = 7,
+ PP_INPUTEVENT_TYPE_KEYUP = 8,
+ PP_INPUTEVENT_TYPE_CHAR = 9
+} PP_InputEvent_Type;
+
+typedef enum {
+ PP_INPUTEVENT_MODIFIER_SHIFTKEY = 1 << 0,
+ PP_INPUTEVENT_MODIFIER_CONTROLKEY = 1 << 1,
+ PP_INPUTEVENT_MODIFIER_ALTKEY = 1 << 2,
+ PP_INPUTEVENT_MODIFIER_METAKEY = 1 << 3,
+ PP_INPUTEVENT_MODIFIER_ISKEYPAD = 1 << 4,
+ PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT = 1 << 5,
+ PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN = 1 << 6,
+ PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN = 1 << 7,
+ PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN = 1 << 8,
+ PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY = 1 << 9,
+ PP_INPUTEVENT_MODIFIER_NUMLOCKKEY = 1 << 10
+} PP_InputEvent_Modifier;
+
+/**
+ * An event representing a key up or down event.
+ *
+ * Key up and down events correspond to physical keys on the keyboard. The
+ * actual character that the user typed (if any) will be delivered in a
+ * "character" event.
+ *
+ * If the user kills focus on the plugin while a key is down, you may not get
+ * a key up event. For example, if the plugin has focus and the user presses
+ * and holds shift, the plugin will see a "shift down" message. Then if they
+ * click elsewhere on the web page, the plugin focus will be lost and no more
+ * input events will be delivered. If you depend on getting key up events, you
+ * will also want to handle "lost focus" as the equivalent of "all keys up."
+ */
+struct PP_InputEvent_Key {
+ /** A combination of the EVENT_MODIFIER flags. */
+ uint32_t modifier;
+
+ /**
+ * The key code.
+ *
+ * TODO(brettw) define what these actually are.
+ */
+ uint32_t key_code;
+};
+
+/**
+ * An event representing a typed character.
+ *
+ * Normally, the program will receive a key down event, followed by a character
+ * event, followed by a key up event. The character event will have any
+ * modifier keys applied. Obvious examples are symbols, where Shift-5 gives you
+ * a '%'. The key down and up events will give you the scan code for the "5"
+ * key, and the character event will give you the '%' character.
+ *
+ * You may not get a character event for all key down if the key doesn't
+ * generate a character. Likewise, you may actually get multiple character
+ * events in a row. For example, some locales have an accent key that modifies
+ * the next character typed. You might get this stream of events: accent down,
+ * accent up (it didn't generate a character), letter key down, letter with
+ * accent character event (it was modified by the previous accent key), letter
+ * key up. If the letter can't be combined with the accent, like an umlaut and
+ * an 'R', the system might send unlaut down, umlaut up, 'R' key down, umlaut
+ * character ("whoops, I can't combine it with 'R', I better just send the raw
+ * unlaut so it isn't lost"), 'R' character event, 'R' key up.
+ */
+struct PP_InputEvent_Character {
+ /** A combination of the EVENT_MODIFIER flags. */
+ uint32_t modifier;
+
+ /**
+ * The character the user typed, as a single null-terminated UTF-8 character.
+ * Any unused bytes will be filled with null bytes. Since the maximum UTF-8
+ * character is 4 bytes, there will always be at least one null at the end
+ * so you can treat this as a null-termianted UTF-8 string.
+ */
+ char text[5];
+};
+
+/** Represents a mouse event for everything other than the mouse wheel. */
+struct PP_InputEvent_Mouse {
+ /** A combination of the EVENT_MODIFIER flags. */
+ uint32_t modifier;
+
+ /**
+ * Which button changed in the case of mouse down or up events. For mouse
+ * move, enter, and leave events, this will be PP_EVENT_MOUSEBUTTON_NONE.
+ */
+ PP_InputEvent_MouseButton button;
+
+ /**
+ * The coordinates of the mouse when the event occurred.
+ *
+ * In most cases these coordinates will just be integers, but they may not
+ * be in some cases. For example, the plugin element might be arbitrarily
+ * scaled or transformed in the DOM, and translating a mouse event into the
+ * coordinate space of the plugin will give non-integer values.
+ */
+ float x;
+ float y;
+
+ /** TODO(brettw) figure out exactly what this means. */
+ int32_t click_count;
+};
+
+struct PP_InputEvent_Wheel {
+ /** A combination of the EVENT_MODIFIER flags. */
+ uint32_t modifier;
+
+ float delta_x;
+ float delta_y;
+ float wheel_ticks_x;
+ float wheel_ticks_y;
+
+ bool scroll_by_page;
+};
+
+struct PP_InputEvent {
+ /** Identifies the type of the event. */
+ PP_InputEvent_Type type;
+
+ /**
+ * When this event was generated. This is not relative to any particular
+ * epoch, the most you can do is compare time stamps.
+ */
+ PP_TimeTicks time_stamp;
+
+ /** Event-specific data. */
+ union {
+ struct PP_InputEvent_Key key;
+ struct PP_InputEvent_Character character;
+ struct PP_InputEvent_Mouse mouse;
+ struct PP_InputEvent_Wheel wheel;
+
+ /**
+ * Allows new events to be added without changing the size of this
+ * struct.
+ */
+ char padding[64];
+ } u;
+};
+
+/**
+ * @}
+ * End of addtogroup PP
+ */
+
+#endif // PPAPI_C_PP_INPUT_EVENT_H_
diff --git a/ppapi/c/pp_instance.h b/ppapi/c/pp_instance.h
new file mode 100644
index 0000000..6f78f11
--- /dev/null
+++ b/ppapi/c/pp_instance.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_INSTANCE_H_
+#define PPAPI_C_PP_INSTANCE_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+#include "ppapi/c/pp_stdint.h"
+
+/** A PP_Instance uniquely identifies one plugin instance, which is one time
+ * that a page says \<embed>. There can be multiple instances of the same plugin
+ * type on a page that will all be in the same module.
+ *
+ * The identifier is an opaque handle assigned by the browser to the plugin. It
+ * is guaranteed never to be 0, so a plugin can initialize it to 0 to
+ * indicate a "NULL handle."
+ */
+typedef int64_t PP_Instance;
+
+/**
+ * @}
+ * End addtogroup PP
+ */
+
+#endif // PPAPI_C_PP_INSTANCE_H_
diff --git a/ppapi/c/pp_module.h b/ppapi/c/pp_module.h
new file mode 100644
index 0000000..5376207
--- /dev/null
+++ b/ppapi/c/pp_module.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_MODULE_H_
+#define PPAPI_C_PP_MODULE_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+#include "ppapi/c/pp_stdint.h"
+
+/**
+ * A module uniquely identifies one plugin library. The identifier is an opaque
+ * handle assigned by the browser to the plugin. It is guaranteed never to be
+ * 0, so a plugin can initialize it to 0 to indicate a "NULL handle."
+ */
+typedef int64_t PP_Module;
+
+/**
+ * @}
+ * End addtogroup PP
+ */
+
+#endif // PPAPI_C_PP_MODULE_H_
diff --git a/ppapi/c/pp_point.h b/ppapi/c/pp_point.h
new file mode 100644
index 0000000..24bb775
--- /dev/null
+++ b/ppapi/c/pp_point.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_POINT_H_
+#define PPAPI_C_PP_POINT_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+#include "ppapi/c/pp_stdint.h"
+
+struct PP_Point {
+ int32_t x;
+ int32_t y;
+};
+
+inline struct PP_Point PP_MakePoint(int32_t x, int32_t y) {
+ struct PP_Point ret;
+ ret.x = x;
+ ret.y = y;
+ return ret;
+}
+
+/**
+ * @}
+ * End addtogroup PP
+ */
+
+#endif // PPAPI_C_PP_POINT_H_
diff --git a/ppapi/c/pp_rect.h b/ppapi/c/pp_rect.h
new file mode 100644
index 0000000..8b76ebd
--- /dev/null
+++ b/ppapi/c/pp_rect.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_RECT_H_
+#define PPAPI_C_PP_RECT_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+#include "ppapi/c/pp_point.h"
+#include "ppapi/c/pp_size.h"
+#include "ppapi/c/pp_stdint.h"
+
+struct PP_Rect {
+ struct PP_Point point;
+ struct PP_Size size;
+};
+
+inline struct PP_Rect PP_MakeRectFromXYWH(int32_t x, int32_t y,
+ int32_t w, int32_t h) {
+ struct PP_Rect ret;
+ ret.point.x = x;
+ ret.point.y = y;
+ ret.size.width = w;
+ ret.size.height = h;
+ return ret;
+}
+
+/**
+ * @}
+ * End addtogroup PP
+ */
+#endif // PPAPI_C_PP_RECT_H_
diff --git a/ppapi/c/pp_resource.h b/ppapi/c/pp_resource.h
new file mode 100644
index 0000000..755995a
--- /dev/null
+++ b/ppapi/c/pp_resource.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_RESOURCE_H_
+#define PPAPI_C_PP_RESOURCE_H_
+
+#include "ppapi/c/pp_stdint.h"
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+/**
+ * A resource is data associated with the Pepper plugin interface. While a
+ * Var represents something callable to JS or from the plugin to the DOM, a
+ * resource has no meaning or visibility outside of the plugin interface.
+ *
+ * Resources are reference counted. Use AddRefResource and ReleaseResource to
+ * manage your reference count of a resource. The data will be automatically
+ * destroyed when the internal reference count reaches 0.
+ *
+ * Value is an opaque handle assigned by the browser to the resource. It is
+ * guaranteed never to be 0 for a valid resource, so a plugin can initialize
+ * it to 0 to indicate a "NULL handle." Some interfaces may return a NULL
+ * resource to indicate failure.
+ */
+typedef int64_t PP_Resource;
+
+/**
+ * @}
+ * End addtogroup PP
+ */
+
+#endif // PPAPI_C_PP_RESOURCE_H_
diff --git a/ppapi/c/pp_size.h b/ppapi/c/pp_size.h
new file mode 100644
index 0000000..3ad2084
--- /dev/null
+++ b/ppapi/c/pp_size.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_SIZE_H_
+#define PPAPI_C_PP_SIZE_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+#include "ppapi/c/pp_stdint.h"
+
+struct PP_Size {
+ int32_t width;
+ int32_t height;
+};
+
+inline struct PP_Size PP_MakeSize(int32_t w, int32_t h) {
+ struct PP_Size ret;
+ ret.width = w;
+ ret.height = h;
+ return ret;
+}
+
+/**
+ * @}
+ * End addtogroup PP
+ */
+#endif // PPAPI_C_PP_SIZE_H_
diff --git a/ppapi/c/pp_stdint.h b/ppapi/c/pp_stdint.h
new file mode 100644
index 0000000..3bb11b9
--- /dev/null
+++ b/ppapi/c/pp_stdint.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_STDINT_H_
+#define PPAPI_C_PP_STDINT_H_
+
+/**
+ * @file
+ * Provides a definition of C99 sized types
+ * across different compilers.
+ *
+ * @addtogroup PP
+ * @{
+ */
+#if defined(_MSC_VER)
+
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+typedef unsigned short uint16_t;
+typedef short int16_t;
+typedef unsigned int uint32_t;
+typedef int int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#else
+#include <stdint.h>
+#include <stddef.h> // Needed for size_t.
+#endif
+
+/**
+ * @}
+ * End addtogroup PP
+ */
+#endif // PPAPI_C_PP_STDINT_H_
diff --git a/ppapi/c/pp_time.h b/ppapi/c/pp_time.h
new file mode 100644
index 0000000..7dec91a
--- /dev/null
+++ b/ppapi/c/pp_time.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_TIME_H_
+#define PPAPI_C_PP_TIME_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+/**
+ * PP_Time represents the "wall clock time" according to the browser and is
+ * defined as the number of seconds since the Epoch (00:00:00 UTC, January 1,
+ * 1970).
+ */
+typedef double PP_Time;
+
+/**
+ * Represents time ticks which is measured in seconds and is used for indicating
+ * the time that certain messages were received. In contrast to PP_Time, it
+ * does not correspond to any actual wall clock time and will not change
+ * discontinuously if the user changes their computer clock.
+ *
+ * The units are in seconds, but are not measured relative to any particular
+ * epoch, so the most you can do is compare two values.
+ */
+typedef double PP_TimeTicks;
+
+/**
+ * @}
+ * End addtogroup PP
+ */
+#endif // PPAPI_C_PP_TIME_H_
diff --git a/ppapi/c/pp_var.h b/ppapi/c/pp_var.h
new file mode 100644
index 0000000..75a9492
--- /dev/null
+++ b/ppapi/c/pp_var.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PP_VAR_H_
+#define PPAPI_C_PP_VAR_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PP
+ * @{
+ */
+
+#include "ppapi/c/pp_stdint.h"
+
+typedef enum {
+ PP_VARTYPE_UNDEFINED,
+ PP_VARTYPE_NULL,
+ PP_VARTYPE_BOOL,
+ PP_VARTYPE_INT32,
+ PP_VARTYPE_DOUBLE,
+ PP_VARTYPE_STRING,
+ PP_VARTYPE_OBJECT
+} PP_VarType;
+
+/**
+ * Do not rely on having a predictable and reproducible
+ * int/double differentiation.
+ * JavaScript has a "number" type for holding a number, and
+ * does not differentiate between floating point and integer numbers. The
+ * JavaScript library will try to optimize operations by using integers
+ * when possible, but could end up with doubles depending on how the number
+ * was arrived at.
+ *
+ * Your best bet is to have a wrapper for variables
+ * that always gets out the type you expect, converting as necessary.
+ */
+struct PP_Var {
+ PP_VarType type;
+ union {
+ bool as_bool;
+ int32_t as_int;
+ double as_double;
+
+ /**
+ * Internal ID for strings and objects. The identifier is an opaque handle
+ * assigned by the browser to the plugin. It is guaranteed never to be 0,
+ * so a plugin can initialize this ID to 0 to indicate a "NULL handle."
+ */
+ int64_t as_id;
+ } value;
+};
+
+inline struct PP_Var PP_MakeUndefined() {
+ struct PP_Var result = { PP_VARTYPE_UNDEFINED, {0} };
+ return result;
+}
+
+inline struct PP_Var PP_MakeNull() {
+ struct PP_Var result = { PP_VARTYPE_NULL, {0} };
+ return result;
+}
+
+inline struct PP_Var PP_MakeBool(bool value) {
+ struct PP_Var result = { PP_VARTYPE_BOOL, {0} };
+ result.value.as_bool = value;
+ return result;
+}
+
+inline struct PP_Var PP_MakeInt32(int32_t value) {
+ PP_Var result = { PP_VARTYPE_INT32, {0} };
+ result.value.as_int = value;
+ return result;
+}
+
+inline struct PP_Var PP_MakeDouble(double value) {
+ PP_Var result = { PP_VARTYPE_DOUBLE, {0} };
+ result.value.as_double = value;
+ return result;
+}
+
+/**
+ * @}
+ * End addtogroup PP
+ */
+#endif // PPAPI_C_PP_VAR_H_
diff --git a/ppapi/c/ppb.h b/ppapi/c/ppb.h
new file mode 100644
index 0000000..1f525cd
--- /dev/null
+++ b/ppapi/c/ppb.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPB_H_
+#define PPAPI_C_PPB_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PPB
+ * @{
+ */
+
+/**
+ * Returns an interface pointer for the interface of the given name, or NULL
+ * if the interface is not supported. Interface names should be ASCII.
+ */
+typedef const void* (*PPB_GetInterface)(const char* interface_name);
+
+/**
+ * @}
+ * End addtogroup PPB
+ */
+#endif // PPAPI_C_PPB_H_
diff --git a/ppapi/c/ppb_class.h b/ppapi/c/ppb_class.h
new file mode 100644
index 0000000..c4718dd
--- /dev/null
+++ b/ppapi/c/ppb_class.h
@@ -0,0 +1,121 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPB_CLASS_H_
+#define PPAPI_C_PPB_CLASS_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/ppb_var.h"
+
+#define PPB_CLASS_INTERFACE "PPB_Class;0.1"
+
+/**
+ * @file
+ * Defines the PPB_Class struct.
+ *
+ * @addtogroup PPB
+ * @{
+ */
+
+/**
+ * Function callback.
+ *
+ * native_ptr will always be the native_ptr used to create this_object. If
+ * this object was not created in this module, native_ptr will be NULL. There
+ * is no other type protection - if your module contains two objects with
+ * different native_ptr information, make sure you can handle the case of
+ * JS calling one object's function with another object set as this.
+ */
+typedef PP_Var (*PP_ClassFunction)(void* native_ptr, PP_Var this_object,
+ PP_Var* args, uint32_t argc,
+ PP_Var* exception);
+
+typedef void (*PP_ClassDestructor)(void* native_ptr);
+
+/**
+ * One property of a class.
+ *
+ * It can be either a value property, in which case it need to have getter
+ * and/or setter fields set, and method NULL, or a function, in which case it
+ * needs to have method set, and getter/setter set to NULL. It is an error to
+ * have method and either getter or setter set, as it is an error to not provide
+ * any of them.
+ *
+ * Not providing a getter will be equivalent to having a getter which returns
+ * undefined. Not providing a setter will be equivalent to providing a setter
+ * which doesn't do anything.
+ */
+struct PP_ClassProperty {
+ const char* name;
+ PP_ClassFunction method;
+ PP_ClassFunction getter;
+ PP_ClassFunction setter;
+ uint32_t modifiers;
+};
+
+/** Interface for implementing JavaScript-accessible objects.
+ *
+ *
+ * Example usage:
+ *
+ * struct PP_ClassProperty properties[] = {
+ * { "method", methodFunc },
+ * { "hiddenMethod", hiddenMethodFunc, NULL, NULL,
+ * PP_OBJECTPROPERTY_MODIFIER_DONTENUM },
+ * { "property", NULL, propertyGetter, propertySetter },
+ * { "readonlyProperty", NULL, propertyGetter, NULL,
+ * PP_OBJECTPROPERTY_MODIFIER_READONLY },
+ * { NULL }
+ * };
+ *
+ * PP_Resource object_template =
+ * Create(module, &operator delete, NULL, properties);
+ *
+ * ...
+ *
+ * struct NativeData { int blah; ... }; // Can be anything.
+ * NativeData* native_data = new NativeData;
+ * native_data->blah = 123; // Initialize native data.
+ *
+ * PP_Var object = Instantiate(object_template, native_data);
+ *
+ * Please also see:
+ * http://code.google.com/p/ppapi/wiki/InterfacingWithJavaScript
+ * for general information on using and implementing vars.
+ */
+struct PPB_Class {
+ /**
+ * Creates a class containing given methods and properties.
+ *
+ * Properties list is terminated with a NULL-named property. New instances are
+ * created using Instantiate(). Each instance carries one void* of native
+ * state, which is passed to Instantiate(). When the instance is finalized,
+ * the destructor function is called to destruct the native state.
+ *
+ * If invoke handler is specified, then the instances can be used as
+ * functions.
+ */
+ PP_Resource (*Create)(PP_Module module,
+ PP_ClassDestructor destruct,
+ PP_ClassFunction invoke,
+ PP_ClassProperty* properties);
+
+ /**
+ * Creates an instance of the given class, and attaches given native pointer
+ * to it.
+ *
+ * If the class_object is invalid, throws an exception.
+ */
+ PP_Var (*Instantiate)(PP_Resource class_object,
+ void* native_ptr, PP_Var* exception);
+};
+
+/**
+ * @}
+ * End addtogroup PPP
+ */
+#endif // PPAPI_C_PPP_CLASS_H_
+
diff --git a/ppapi/c/ppb_core.h b/ppapi/c/ppb_core.h
new file mode 100644
index 0000000..2e1b30c
--- /dev/null
+++ b/ppapi/c/ppb_core.h
@@ -0,0 +1,92 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPB_CORE_H_
+#define PPAPI_C_PPB_CORE_H_
+
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_time.h"
+#include "ppapi/c/pp_var.h"
+
+struct PP_CompletionCallback;
+
+#define PPB_CORE_INTERFACE "PPB_Core;0.1"
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PPB
+ * @{
+ */
+
+/** {PENDING: describe PPB_CORE} */
+struct PPB_Core {
+ /** Same as AddRefVar for Resources. */
+ void (*AddRefResource)(PP_Resource resource);
+
+ /** Same as ReleaseVar for Resources. */
+ void (*ReleaseResource)(PP_Resource resource);
+
+ /**
+ * Allocate memory.
+ *
+ * @return NULL If the allocation fails.
+ */
+ void* (*MemAlloc)(size_t num_bytes);
+
+ /** Free memory; it's safe to pass NULL. */
+ void (*MemFree)(void* ptr);
+
+ /**
+ * Returns the "wall clock time" according to the browser.
+ *
+ * See the definition of PP_Time.
+ */
+ PP_Time (*GetTime)();
+
+ /**
+ * Returns the "tick time" according to the browser. This clock is used by
+ * the browser when passing some event times to the plugin (e.g., via the
+ * PP_InputEvent::time_stamp_seconds field). It is not correlated to any
+ * actual wall clock time (like GetTime()). Because of this, it will not run
+ * change if the user changes their computer clock.
+ *
+ * TODO(brettw) http://code.google.com/p/chromium/issues/detail?id=57448
+ * This currently does change with wall clock time, but will be fixed in
+ * a future release.
+ */
+ PP_TimeTicks (*GetTimeTicks)();
+
+ /**
+ * Schedules work to be executed on the main plugin thread after the
+ * specified delay. The delay may be 0 to specify a call back as soon as
+ * possible.
+ *
+ * The |result| parameter will just be passed as the second argument as the
+ * callback. Many applications won't need this, but it allows a plugin to
+ * emulate calls of some callbacks which do use this value.
+ *
+ * NOTE: If the browser is shutting down or if the plugin has no instances,
+ * then the callback function may not be called.
+ */
+ void (*CallOnMainThread)(int32_t delay_in_milliseconds,
+ struct PP_CompletionCallback callback,
+ int32_t result);
+
+ /**
+ * Returns true if the current thread is the main pepper thread.
+ *
+ * This is useful for implementing sanity checks, and deciding if dispatching
+ * via CallOnMainThread() is required.
+ */
+ bool (*IsMainThread)();
+};
+
+/**
+ * @}
+ * End addtogroup PPB
+ */
+#endif // PPAPI_C_DEV_PPB_CORE_DEV_H_
diff --git a/ppapi/c/ppb_graphics_2d.h b/ppapi/c/ppb_graphics_2d.h
new file mode 100644
index 0000000..6a15b14
--- /dev/null
+++ b/ppapi/c/ppb_graphics_2d.h
@@ -0,0 +1,223 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPB_GRAPHICS_2D_H_
+#define PPAPI_C_PPB_GRAPHICS_2D_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+struct PP_CompletionCallback;
+struct PP_Point;
+struct PP_Rect;
+struct PP_Size;
+
+#define PPB_GRAPHICS_2D_INTERFACE "PPB_Graphics2D;0.1"
+
+/**
+ * @file
+ * Defines the PPB_Graphics2D struct.
+ *
+ * @addtogroup PPB
+ * @{
+ */
+
+/** {PENDING: describe PPB_Graphics2D. */
+struct PPB_Graphics2D {
+ /**
+ * The returned graphics context will not be bound to any plugin instance on
+ * creation (call BindGraphics on the plugin instance to do that. The
+ * graphics context has a lifetime that can exceed that of the given plugin
+ * instance.
+ *
+ * Set the is_always_opaque flag if you know that you will be painting only
+ * opaque data to this context. This will disable blending when compositing
+ * the plugin with the web page, which will give slightly higher performance.
+ *
+ * If you set is_always_opaque, your alpha channel should always be set to
+ * 0xFF or there may be painting artifacts. Being opaque will allow the
+ * browser to do a memcpy rather than a blend to paint the plugin, and this
+ * means your alpha values will get set on the page backing store. If these
+ * values are incorrect, it could mess up future blending.
+ *
+ * If you aren't sure, it is always correct to specify that it it not opaque.
+ */
+ PP_Resource (*Create)(PP_Module module,
+ const struct PP_Size* size,
+ bool is_always_opaque);
+
+ /**
+ * Returns true if the given resource is a valid Graphics2D, false if it
+ * is an invalid resource or is a resource of another type.
+ */
+ bool (*IsGraphics2D)(PP_Resource resource);
+
+ /**
+ * Retrieves the configuration for the given graphics context, filling the
+ * given values (which must not be NULL). On success, returns true. If the
+ * resource is invalid, the output parameters will be set to 0 and it will
+ * return false.
+ */
+ bool (*Describe)(PP_Resource graphics_2d,
+ struct PP_Size* size,
+ bool* is_always_opqaue);
+
+ /**
+ * Enqueues a paint of the given image into the context. THIS HAS NO EFFECT
+ * UNTIL YOU CALL Flush(). As a result, what counts is the contents of the
+ * bitmap when you call Flush, not when you call this function.
+ *
+ * The given image will be placed at |top_left| from the top left of the
+ * context's internal backing store. Then the src_rect will be copied into the
+ * backing store. This parameter may not be NULL.
+ *
+ * The src_rect is specified in the coordinate system of the image being
+ * painted, not the context. For the common case of copying the entire image,
+ * you may specify a NULL |src_rect| pointer. If you are frequently updating
+ * the entire image, consider using SwapImageData which will give slightly
+ * higher performance.
+ *
+ * The painted area of the source bitmap must fall entirely within the
+ * context. Attempting to paint outside of the context will result in an
+ * error. However, the source bitmap may fall outside the context, as long
+ * as the src_rect subset of it falls entirely within the context.
+ */
+ void (*PaintImageData)(PP_Resource graphics_2d,
+ PP_Resource image_data,
+ const struct PP_Point* top_left,
+ const struct PP_Rect* src_rect);
+
+ /**
+ * Enqueues a scroll of the context's backing store. THIS HAS NO EFFECT UNTIL
+ * YOU CALL Flush(). The data within the given clip rect (you may specify
+ * NULL to scroll the entire region) will be shifted by (dx, dy) pixels.
+ *
+ * This will result in some exposed region which will have undefined
+ * contents. The plugin should call PaintImageData on these exposed regions
+ * to give the correct contents.
+ *
+ * The scroll can be larger than the area of the clip rect, which means the
+ * current image will be scrolled out of the rect. This is not an error but
+ * will be a no-op.
+ */
+ void (*Scroll)(PP_Resource graphics_2d,
+ const struct PP_Rect* clip_rect,
+ const struct PP_Point* amount);
+
+ /**
+ * This function provides a slightly more efficient way to paint the entire
+ * plugin's image. Normally, calling PaintImageData requires that the browser
+ * copy the pixels out of the image and into the graphics context's backing
+ * store. This function replaces the graphics context's backing store with the
+ * given image, avoiding the copy.
+ *
+ * The new image must be the exact same size as this graphics context. If the
+ * new image uses a different image format than the browser's native bitmap
+ * format (use PPB_ImageData.GetNativeImageDataFormat to retrieve this), then
+ * a conversion will be done inside the browser which may slow the performance
+ * a little bit.
+ *
+ * THE NEW IMAGE WILL NOT BE PAINTED UNTIL YOU CALL FLUSH.
+ *
+ * After this call, you should take care to release your references to the
+ * image. If you paint to the image after a Swap, there is the possibility of
+ * significant painting artifacts because the page might use partially-
+ * rendered data when copying out of the backing store.
+ *
+ * In the case of an animation, you will want to allocate a new image for the
+ * next frame. It is best if you wait until the flush callback has executed
+ * before allocating this bitmap. This gives the browser the option of
+ * caching the previous backing store and handing it back to you (assuming
+ * the sizes match). In the optimal case, this means no bitmaps are allocated
+ * during the animation, and the backing store and "front buffer" (which the
+ * plugin is painting into) are just being swapped back and forth.
+ */
+ void (*ReplaceContents)(PP_Resource graphics_2d, PP_Resource image_data);
+
+ /**
+ * Flushes any enqueued paint, scroll, and swap commands for the backing
+ * store. This actually executes the updates, and causes a repaint of the
+ * webpage, assuming this graphics context is bound to a plugin instance. This
+ * can run in two modes:
+ *
+ * - In synchronous mode, you specify NULL for the callback and the callback
+ * data. This function will block the calling thread until the image has
+ * been painted to the screen. It is not legal to block the main thread of
+ * the plugin, you can use synchronous mode only from background threads.
+ *
+ * - In asynchronous mode, you specify a callback function and the argument
+ * for that callback function. The callback function will be executed on
+ * the calling thread when the image has been painted to the screen. While
+ * you are waiting for a Flush callback, additional calls to Flush will
+ * fail.
+ *
+ * Because the callback is executed (or thread unblocked) only when the
+ * plugin's current state is actually on the screen, this function provides a
+ * way to rate limit animations. By waiting until the image is on the screen
+ * before painting the next frame, you can ensure you're not generating
+ * updates faster than the screen can be updated.
+ *
+ * <dl>
+ * <dt>Unbound contexts</dt>
+ * <dd>
+ * If the context is not bound to a plugin instance, you will
+ * still get a callback. It will execute after the Flush function returns
+ * to avoid reentrancy. Of course, it will not wait until anything is
+ * painted to the screen because there will be nothing on the screen. The
+ * timing of this callback is not guaranteed and may be deprioritized by
+ * the browser because it is not affecting the user experience.
+ * </dd>
+ *
+ * <dt>Off-screen instances</dt>
+ * <dd>
+ * If the context is bound to an instance that is
+ * currently not visible (for example, scrolled out of view) it will behave
+ * like the "unbound context" case.
+ * </dd>
+ *
+ * <dt>Detaching a context</dt>
+ * <dd>
+ * If you detach a context from a plugin instance, any
+ * pending flush callbacks will be converted into the "unbound context"
+ * case.
+ * </dd>
+ *
+ * <dt>Released contexts</dt>
+ * <dd>
+ * A callback may or may not still get called even if you have released all
+ * of your references to the context. This can occur if there are internal
+ * references to the context that means it has not been internally
+ * destroyed (for example, if it is still bound to an instance) or due to
+ * other implementation details. As a result, you should be careful to
+ * check that flush callbacks are for the context you expect and that
+ * you're capable of handling callbacks for context that you may have
+ * released your reference to.
+ * </dd>
+ *
+ * <dt>Shutdown</dt>
+ * <dd>
+ * If a plugin instance is removed when a Flush is pending, the
+ * callback will not be executed.
+ * </dd>
+ * </dl>
+ *
+ * Returns PP_OK on success, PP_Error_BadResource if the graphics context is
+ * invalid, PP_Error_BadArgument if the callback is null and Flush is being
+ * called from the main thread of the plugin, or PP_Error_InProgress if a
+ * Flush is already pending that has not issued its callback yet. In the
+ * failure case, nothing will be updated and no callback will be scheduled.
+ */
+ // TODO(darin): We should ensure that the completion callback always runs, so
+ // that it is easier for consumers to manage memory referenced by a callback.
+ int32_t (*Flush)(PP_Resource graphics_2d,
+ struct PP_CompletionCallback callback);
+
+};
+
+/**
+ * @}
+ * End addtogroup PPB
+ */
+#endif // PPAPI_C_PPB_GRAPHICS_2D_H_
diff --git a/ppapi/c/ppb_image_data.h b/ppapi/c/ppb_image_data.h
new file mode 100644
index 0000000..905e694
--- /dev/null
+++ b/ppapi/c/ppb_image_data.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPB_IMAGE_DATA_H_
+#define PPAPI_C_PPB_IMAGE_DATA_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_size.h"
+#include "ppapi/c/pp_stdint.h"
+
+typedef enum {
+ PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ PP_IMAGEDATAFORMAT_RGBA_PREMUL
+} PP_ImageDataFormat;
+
+struct PP_ImageDataDesc {
+ PP_ImageDataFormat format;
+
+ // Size of the bitmap in pixels.
+ PP_Size size;
+
+ // The row width in bytes. This may be different than width * 4 since there
+ // may be padding at the end of the lines.
+ int32_t stride;
+};
+
+#define PPB_IMAGEDATA_INTERFACE "PPB_ImageData;0.1"
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PPB
+ * @{
+ */
+
+struct PPB_ImageData {
+ /**
+ * Returns the browser's preferred format for image data. This format will be
+ * the format is uses internally for painting. Other formats may require
+ * internal conversions to paint or may have additional restrictions depending
+ * on the function.
+ */
+ PP_ImageDataFormat (*GetNativeImageDataFormat)();
+
+ /**
+ * Returns true if the given image data format is supported by the browser.
+ */
+ bool (*IsImageDataFormatSupported)(PP_ImageDataFormat format);
+
+ /**
+ * Allocates an image data resource with the given format and size. The
+ * return value will have a nonzero ID on success, or zero on failure.
+ * Failure means the module handle, image size, or format was invalid.
+ *
+ * Set the init_to_zero flag if you want the bitmap initialized to
+ * transparent during the creation process. If this flag is not set, the
+ * current contents of the bitmap will be undefined, and the plugin should
+ * be sure to set all the pixels.
+ *
+ * For security reasons, if uninitialized, the bitmap will not contain random
+ * memory, but may contain data from a previous image produced by the same
+ * plugin if the bitmap was cached and re-used.
+ */
+ PP_Resource (*Create)(PP_Module module,
+ PP_ImageDataFormat format,
+ const struct PP_Size* size,
+ bool init_to_zero);
+
+ /**
+ * Returns true if the given resource is an image data. Returns false if the
+ * resource is invalid or some type other than an image data.
+ */
+ bool (*IsImageData)(PP_Resource image_data);
+
+ /**
+ * Computes the description of the image data. Returns true on success, false
+ * if the resource is not an image data. On false, the |desc| structure will
+ * be filled with 0.
+ */
+ bool (*Describe)(PP_Resource image_data,
+ struct PP_ImageDataDesc* desc);
+
+ /**
+ * Maps this bitmap into the plugin address space and returns a pointer to the
+ * beginning of the data.
+ */
+ void* (*Map)(PP_Resource image_data);
+
+ void (*Unmap)(PP_Resource image_data);
+};
+
+/**
+ * @}
+ * End addtogroup PPB
+ */
+#endif // PPAPI_C_PPB_IMAGE_DATA_H_
diff --git a/ppapi/c/ppb_instance.h b/ppapi/c/ppb_instance.h
new file mode 100644
index 0000000..3815650
--- /dev/null
+++ b/ppapi/c/ppb_instance.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPB_INSTANCE_H_
+#define PPAPI_C_PPB_INSTANCE_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_INSTANCE_INTERFACE "PPB_Instance;0.1"
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PPB
+ * @{
+ */
+
+struct PPB_Instance {
+ /** Returns a reference to the DOM window containing this instance. */
+ struct PP_Var (*GetWindowObject)(PP_Instance instance);
+
+ /** Returns a reference to the DOM element containing this instance. */
+ struct PP_Var (*GetOwnerElementObject)(PP_Instance instance);
+
+ /**
+ * Binds the given graphics device as the current drawing surface. The
+ * contents of this device is what will be displayed in the plugin's area
+ * on the web page. The device must be a 2D or a 3D device.
+ *
+ * You can pass a NULL resource as the device parameter to unbind all
+ * devices from the given instance. The instance will then appear
+ * transparent. Re-binding the same device will return true and will do
+ * nothing. Unbinding a device will drop any pending flush callbacks.
+ *
+ * Any previously-bound device will be Release()d. It is an error to bind
+ * a device when it is already bound to another plugin instance. If you want
+ * to move a device between instances, first unbind it from the old one, and
+ * then rebind it to the new one.
+ *
+ * Returns true if the bind was successful. False means the device was not
+ * the correct type. On success, a reference to the device will be held by
+ * the plugin instance, so the caller can release its reference if it
+ * chooses.
+ *
+ * Binding a device will invalidate that portion of the web page to flush the
+ * contents of the new device to the screen.
+ */
+ bool (*BindGraphics)(PP_Instance instance, PP_Resource device);
+
+ /**
+ * Returns true if the instance is full-frame. Such a plugin represents the
+ * entire document in a frame rather than an embedded resource. This can
+ * happen if the user does a top level navigation or the page specifies an
+ * iframe to a resource with a MIME type registered by the plugin.
+ */
+ bool (*IsFullFrame)(PP_Instance instance);
+
+ /**
+ * Executes the given script in the context of the frame containing the
+ * plugin.
+ *
+ * The exception, if any, will be returned in *exception. As
+ * with the PPB_Var interface, the exception parameter,
+ * if non-NULL, must be initialized
+ * to a void exception or the function will immediately return. On success,
+ * the exception parameter will be set to a "void" var. On failure, the return
+ * value will be a "void" var.
+ *
+ * @param script A string containing the JavaScript to execute.
+ * @param exception Initialize this to NULL if you don't want exception info;
+ * initialize this to a void exception if you do.
+ * See the function description for details.
+ *
+ * @return The result of the script execution,
+ * or a "void" var if execution failed.
+ */
+ PP_Var (*ExecuteScript)(PP_Instance instance, PP_Var script,
+ PP_Var* exception);
+};
+
+/**
+ * @}
+ * End addtogroup PPB
+ */
+#endif // PPAPI_C_PPB_INSTANCE_H_
diff --git a/ppapi/c/ppb_var.h b/ppapi/c/ppb_var.h
new file mode 100644
index 0000000..9de1121
--- /dev/null
+++ b/ppapi/c/ppb_var.h
@@ -0,0 +1,295 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPB_VAR_H_
+#define PPAPI_C_PPB_VAR_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_VAR_INTERFACE "PPB_Var;0.1"
+
+/**
+ * @file
+ * Defines the PPB_Var struct.
+ * See http://code.google.com/p/ppapi/wiki/InterfacingWithJavaScript
+ * for general information on using this interface.
+ * {PENDING: Should the generated doc really be pointing to methods?}
+ *
+ * @addtogroup PPB
+ * @{
+ */
+
+enum PP_ObjectProperty_Modifier {
+ PP_OBJECTPROPERTY_MODIFIER_NONE = 0,
+ PP_OBJECTPROPERTY_MODIFIER_READONLY = 1 << 0,
+ PP_OBJECTPROPERTY_MODIFIER_DONTENUM = 1 << 1,
+ PP_OBJECTPROPERTY_MODIFIER_DONTDELETE = 1 << 2,
+ PP_OBJECTPROPERTY_MODIFIER_HASVALUE = 1 << 3
+};
+
+struct PP_ObjectProperty {
+ PP_Var name;
+ PP_Var value;
+ PP_Var getter;
+ PP_Var setter;
+ uint32_t modifiers;
+};
+
+/**
+ * PPB_Var API
+ *
+ * JavaScript specification:
+ *
+ * When referencing JS specification, we will refer to ECMAScript, 5th edition,
+ * and we will put section numbers in square brackets.
+ *
+ * Exception handling:
+ *
+ * If an exception parameter is NULL, then any exceptions that happen during the
+ * execution of the function will be ignored. If it is non-NULL, and has a type
+ * of PP_VARTYPE_UNDEFINED, then if an exception is thrown it will be stored in
+ * the exception variable. It it is non-NULL and not PP_VARTYPE_UNDEFINED, then
+ * the function is a no-op, and, if it returns a value, it will return
+ * PP_VARTYPE_UNDEFINED. This can be used to chain together multiple calls and
+ * only check the exception at the end.
+ *
+ * Make sure not to intermix non-JS with JS calls when relying on this behavior
+ * to catch JS exceptions, as non-JS functions will still execute!
+
+ * JS engine's exceptions will always be of type PP_VARTYPE_OBJECT. However,
+ * PP_Var interface can also throw PP_VARTYPE_STRING exceptions, in situations
+ * where there's no JS execution context defined. These are usually invalid
+ * parameter errors - passing an invalid PP_Var value, for example, will always
+ * result in an PP_VARTYPE_STRING exception. Exceptions will not be of any other
+ * type.
+ * TODO(neb): Specify the exception for ill-formed PP_Vars, invalid module,
+ * instance, resource, string and object ids.
+ */
+struct PPB_Var {
+ /**
+ * Adds a reference to the given var. If this is not a refcounted object,
+ * this function will do nothing so you can always call it no matter what the
+ * type.
+ */
+ void (*AddRef)(struct PP_Var var);
+
+ /**
+ * Removes a reference to given var, deleting it if the internal refcount
+ * becomes 0. If the given var is not a refcounted object, this function will
+ * do nothing so you can always call it no matter what the type.
+ */
+ void (*Release)(struct PP_Var var);
+
+ /**
+ * Creates a string var from a string. The string must be encoded in valid
+ * UTF-8 and is NOT NULL-terminated, the length must be specified in |len|.
+ * It is an error if the string is not valid UTF-8.
+ *
+ * If the length is 0, the |data| pointer will not be dereferenced and may
+ * be NULL. Note, however, that if you do this, the "NULL-ness" will not be
+ * preserved, as VarToUtf8 will never return NULL on success, even for empty
+ * strings.
+ *
+ * The resulting object will be a refcounted string object. It will be
+ * AddRef()ed for the caller. When the caller is done with it, it should be
+ * Release()d.
+ *
+ * On error (basically out of memory to allocate the string, or input that
+ * is not valid UTF-8), this function will return a Null var.
+ */
+ struct PP_Var (*VarFromUtf8)(PP_Module module,
+ const char* data, uint32_t len);
+
+ /**
+ * Converts a string-type var to a char* encoded in UTF-8. This string is NOT
+ * NULL-terminated. The length will be placed in |*len|. If the string is
+ * valid but empty the return value will be non-NULL, but |*len| will still
+ * be 0.
+ *
+ * If the var is not a string, this function will return NULL and |*len| will
+ * be 0.
+ *
+ * The returned buffer will be valid as long as the underlying var is alive.
+ * If the plugin frees its reference, the string will be freed and the pointer
+ * will be to random memory.
+ */
+ const char* (*VarToUtf8)(struct PP_Var var, uint32_t* len);
+
+ /**
+ * Convert a variable to a different type using rules from ECMAScript
+ * specification, section [9].
+ *
+ * For conversions from/to PP_VARTYPE_OBJECT, the instance must be specified,
+ * or an exception of type PP_VARTYPE_STRING will be thrown.
+ */
+ PP_Var (*ConvertType)(PP_Instance instance,
+ struct PP_Var var,
+ PP_VarType new_type,
+ PP_Var* exception);
+
+ /**
+ * Sets a property on the object, similar to Object.prototype.defineProperty.
+ *
+ * First, if object is not PP_VARTYPE_OBJECT, throw an exception.
+ * TODO(neb): Specify the exception. Ideally, it would be a TypeError, but
+ * don't have the JS context to create new objects, we might throw a string.
+ * Then, the property's 'name' field is converted to string using
+ * ConvertType (ToString [9.8]).
+ * After that, defineOwnProperty [8.12.9, 15.4.5.1] is called with the
+ * property.
+ * To set a simple property, set the value and set modifiers to default
+ * (Writable|Enumerable|Configurable|HasValue), see [8.12.15] and
+ * function PPB_MakeSimpleProperty.
+ */
+ void (*DefineProperty)(struct PP_Var object,
+ struct PP_ObjectProperty property,
+ PP_Var* exception);
+
+ /**
+ * Tests whether an object has a property with a given name.
+ *
+ * First, if object is not PP_VARTYPE_OBJECT, throw an exception.
+ * TODO(neb): Specify the exception. Ideally, it would be a TypeError, but
+ * don't have the JS context to create new objects, we might throw a string.
+ * Then, convert 'property' to string using ConvertType (ToString [9.8]).
+ * Then return true if the given property exists on the object [8.12.6].
+ */
+ bool (*HasProperty)(struct PP_Var object,
+ struct PP_Var property,
+ struct PP_Var* exception);
+
+ /**
+ * Returns a given property of the object.
+ *
+ * First, if object is not PP_VARTYPE_OBJECT, throw an exception.
+ * TODO(neb): Specify the exception. Ideally, it would be a TypeError, but
+ * don't have the JS context to create new objects, we might throw a string.
+ * Then, convert 'property' to string using ConvertType (ToString [9.8]).
+ * Then return the given property of the object [8.12.2].
+ */
+ PP_Var (*GetProperty)(struct PP_Var object,
+ struct PP_Var property,
+ struct PP_Var* exception);
+
+ /**
+ * Delete a property from the object, return true if succeeded.
+ *
+ * True is returned if the property didn't exist in the first place.
+ *
+ * First, if object is not PP_VARTYPE_OBJECT, throw an exception.
+ * TODO(neb): Specify the exception. Ideally, it would be a TypeError, but
+ * don't have the JS context to create new objects, we might throw a string.
+ * Then, convert 'property' to string using ConvertType (ToString [9.8]).
+ * Then delete the given property of the object [8.12.7].
+ */
+ bool (*DeleteProperty)(struct PP_Var object,
+ struct PP_Var property,
+ struct PP_Var* exception);
+
+ /**
+ * Retrieves all property names on the given object. Property names include
+ * methods.
+ *
+ * If object is not PP_VARTYPE_OBJECT, throw an exception.
+ * TODO(neb): Specify the exception. Ideally, it would be a TypeError, but
+ * don't have the JS context to create new objects, we might throw a string.
+ *
+ * If there is a failure, the given exception will be set (if it is non-NULL).
+ * On failure, |*properties| will be set to NULL and |*property_count| will be
+ * set to 0.
+ *
+ * A pointer to the array of property names will be placed in |*properties|.
+ * The caller is responsible for calling Release() on each of these properties
+ * (as per normal refcounted memory management) as well as freeing the array
+ * pointer with PPB_Core.MemFree().
+ *
+ * This function returns all "enumerable" properties. Some JavaScript
+ * properties are "hidden" and these properties won't be retrieved by this
+ * function, yet you can still set and get them. You can use JS
+ * Object.getOwnPropertyNames() to access these properties.
+ *
+ * Example:
+ * <pre> uint32_t count;
+ * PP_Var* properties;
+ * ppb_var.EnumerateProperties(object, &count, &properties);
+ *
+ * ...use the properties here...
+ *
+ * for (uint32_t i = 0; i < count; i++)
+ * ppb_var.Release(properties[i]);
+ * ppb_core.MemFree(properties); </pre>
+ */
+ void (*EnumerateProperties)(struct PP_Var object,
+ uint32_t* property_count,
+ struct PP_Var** properties,
+ struct PP_Var* exception);
+
+ /**
+ * Check if an object is a JS Function [9.11].
+ */
+ bool (*IsCallable)(struct PP_Var object);
+
+ /**
+ * Call the functions.
+ *
+ * Similar to Function.prototype.call [15.3.4.4]. It will throw a TypeError
+ * and return undefined if object is not PP_VARTYPE_OBJECT, or is not
+ * callable.
+ *
+ * Pass the arguments to the function in order in the |argv| array, and the
+ * number of arguments in the |argc| parameter. |argv| can be NULL if |argc|
+ * is zero.
+ *
+ * Example:
+ * Call(obj.GetProperty("DoIt"), obj, 0, NULL, NULL)
+ * Equivalent to obj.DoIt() in JavaScript.
+ *
+ * Call(obj, PP_MakeUndefined(), 0, NULL, NULL)
+ * Equivalent to obj() in JavaScript.
+ */
+ struct PP_Var (*Call)(struct PP_Var object,
+ struct PP_Var this_object,
+ uint32_t argc,
+ struct PP_Var* argv,
+ struct PP_Var* exception);
+
+ /**
+ * Invoke the object as a constructor. It will throw a |TypeError| and return
+ * |undefined| if |object| is not PP_VARTYPE_OBJECT, or cannot be used as a
+ * constructor.
+ *
+ * Pass the arguments to the function in order in the |argv| array, and the
+ * number of arguments in the |argc| parameter. |argv| can be NULL if |argc|
+ * is zero.
+ *
+ * For example, if |object| is |String|, this is like saying |new String| in
+ * JavaScript. Similar to the [[Construct]] internal method [13.2.2].
+ *
+ * For examples, to construct an empty object, do:
+ * GetWindow().GetProperty("Object").Construct(0, NULL);
+ */
+ struct PP_Var (*Construct)(struct PP_Var object,
+ uint32_t argc,
+ struct PP_Var* argv,
+ struct PP_Var* exception);
+};
+
+inline struct PP_ObjectProperty PP_MakeSimpleProperty(PP_Var name,
+ PP_Var value) {
+ struct PP_ObjectProperty result = {
+ name, value, PP_MakeUndefined(), PP_MakeUndefined(),
+ PP_OBJECTPROPERTY_MODIFIER_HASVALUE };
+ return result;
+}
+
+/**
+ * @}
+ * End addtogroup PPB
+ */
+#endif // PPAPI_C_PPB_VAR_H_
+
diff --git a/ppapi/c/ppp.h b/ppapi/c/ppp.h
new file mode 100644
index 0000000..67d66c3
--- /dev/null
+++ b/ppapi/c/ppp.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPP_H_
+#define PPAPI_C_PPP_H_
+
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/ppb.h"
+
+#if __GNUC__ >= 4
+#define PP_EXPORT __attribute__ ((visibility("default")))
+#elif defined(_MSC_VER)
+#define PP_EXPORT __declspec(dllexport)
+#endif
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * {PENDING: undefine PP_EXPORT?}
+ * @addtogroup PPP
+ * @{
+ */
+
+// We don't want name mangling for these external functions. We only need
+// 'extern "C"' if we're compiling with a C++ compiler.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Entrypoint for the module.
+ *
+ * Returns PP_OK on success, any other value on failure. Failure indicates to
+ * the browser that this plugin can not be used. In this case, the plugin will
+ * be unloaded and ShutdownModule will NOT be called.
+ */
+PP_EXPORT int32_t PPP_InitializeModule(PP_Module module,
+ PPB_GetInterface get_browser_interface);
+
+/** Called before the plugin module is unloaded. */
+PP_EXPORT void PPP_ShutdownModule();
+
+/**
+ * Returns an interface pointer for the interface of the given name, or NULL
+ * if the interface is not supported. Interface names should be ASCII.
+ */
+PP_EXPORT const void* PPP_GetInterface(const char* interface_name);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+/**
+ * @}
+ * End addtogroup PPP
+ */
+#endif // PPAPI_C_PPP_H_
diff --git a/ppapi/c/ppp_instance.h b/ppapi/c/ppp_instance.h
new file mode 100644
index 0000000..a7b72e7
--- /dev/null
+++ b/ppapi/c/ppp_instance.h
@@ -0,0 +1,133 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_PPP_INSTANCE_H_
+#define PPAPI_C_PPP_INSTANCE_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_rect.h"
+#include "ppapi/c/pp_resource.h"
+
+struct PP_InputEvent;
+struct PP_Var;
+
+#define PPP_INSTANCE_INTERFACE "PPP_Instance;0.1"
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup PPP
+ * @{
+ */
+
+struct PPP_Instance {
+ /**
+ * Called when a new plugin is instantiated on the web page. The identifier
+ * of the new instance will be passed in as the first argument (this value is
+ * generated by the browser and is an opaque handle).
+ *
+ * It's possible for more than one plugin instance to be created within the
+ * same module (i.e. you may get more than one OnCreate without an OnDestroy
+ * in between).
+ *
+ * If the plugin reports failure from this function, the plugin will be
+ * deleted and OnDestroy will be called.
+ */
+ bool (*DidCreate)(PP_Instance instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]);
+
+ /**
+ * Called when the plugin instance is destroyed. This will always be called,
+ * even if Create returned failure. The plugin should deallocate any data
+ * associated with the instance.
+ */
+ void (*DidDestroy)(PP_Instance instance);
+
+ /**
+ * Called when the position, the size, or the clip rect has changed.
+ *
+ * The |position| is the location on the page of this plugin instance. This is
+ * relative to the top left corner of the viewport, which changes as the page
+ * is scrolled.
+ *
+ * The |clip| indicates the visible region of the plugin instance. This is
+ * relative to the top left of the plugin's coordinate system (not the page).
+ * If the plugin is invisible, the clip rect will be (0, 0, 0, 0).
+ */
+ void (*DidChangeView)(PP_Instance instance,
+ const struct PP_Rect* position,
+ const struct PP_Rect* clip);
+
+ /**
+ * Notification that the given plugin instance has gained or lost focus.
+ * Having focus means that keyboard events will be sent to your plugin
+ * instance. A plugin's default condition is that it will not have focus.
+ *
+ * Note: clicks on your plugins will give focus only if you handle the
+ * click event. You signal if you handled it by returning true from
+ * HandleInputEvent. Otherwise the browser will bubble the event and give
+ * focus to the element on the page that actually did end up consuming it.
+ * If you're not getting focus, check to make sure you're returning true from
+ * the mouse click in HandleInputEvent.
+ */
+ void (*DidChangeFocus)(PP_Instance instance, bool has_focus);
+
+ /**
+ * General handler for input events. Returns true if the event was handled or
+ * false if it was not.
+ *
+ * If the event was handled, it will not be forwarded to the web page or
+ * browser. If it was not handled, it will bubble according to the normal
+ * rules. So it is important that a plugin respond accurately with whether
+ * event propogation should continue.
+ *
+ * Event propogation also controls focus. If you handle an event like a mouse
+ * event, typically your plugin will be given focus. Returning false means
+ * that the click will be given to a lower part of the page and the plugin
+ * will not receive focus. This allows a plugin to be partially transparent,
+ * where clicks on the transparent areas will behave like clicks to the
+ * underlying page.
+ */
+ bool (*HandleInputEvent)(PP_Instance instance,
+ const struct PP_InputEvent* event);
+
+ /**
+ * Called after Initialize for a full-frame plugin that was instantiated
+ * based on the MIME type of a DOMWindow navigation. This only applies to
+ * plugins that are registered to handle certain MIME types (not current
+ * Native Client plugins).
+ *
+ * The given url_loader corresponds to a PPB_URLLoader instance that is
+ * already opened. Its response headers may be queried using
+ * PPB_URLLoader::GetResponseInfo. The url loader is not addrefed on behalf
+ * of the plugin, if you're going to keep a reference to it, you need to
+ * addref it yourself.
+ *
+ * This method returns false if the plugin cannot handle the data. In
+ * response to this method, the plugin should call ReadResponseBody to read
+ * the incoming data.
+ */
+ bool (*HandleDocumentLoad)(PP_Instance instance, PP_Resource url_loader);
+
+ /**
+ * Returns a Var representing the instance object to the web page. Normally
+ * this will be a PPP_Class object that exposes certain methods the page
+ * may want to call.
+ *
+ * On Failure, the returned var should be a "void" var.
+ *
+ * The returned PP_Var should have a reference added for the caller, which
+ * will be responsible for Release()ing that reference.
+ */
+ struct PP_Var (*GetInstanceObject)(PP_Instance instance);
+};
+
+/**
+ * @}
+ * End addtogroup PPP
+ */
+#endif // PPAPI_C_PPP_INSTANCE_H_
diff --git a/ppapi/c/trusted/ppb_image_data_trusted.h b/ppapi/c/trusted/ppb_image_data_trusted.h
new file mode 100644
index 0000000..b72dcc2
--- /dev/null
+++ b/ppapi/c/trusted/ppb_image_data_trusted.h
@@ -0,0 +1,21 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_C_TRUSTED_PPB_IMAGE_DATA_TRUSTED_H_
+#define PPAPI_C_TRUSTED_PPB_IMAGE_DATA_TRUSTED_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_resource.h"
+
+#define PPB_IMAGEDATA_TRUSTED_INTERFACE "PPB_ImageDataTrusted;0.1"
+
+struct PPB_ImageDataTrusted {
+ /**
+ * Returns the internal shared memory pointer associated with the given
+ * ImageData resource. Used for proxying. Returns the handle or 0 on failure.
+ */
+ uint64_t (*GetNativeMemoryHandle)(PP_Resource image_data);
+};
+
+#endif // PPAPI_C_TRUSTED_PPB_IMAGE_DATA_TRUSTED_H_
diff --git a/ppapi/codereview.settings b/ppapi/codereview.settings
new file mode 100644
index 0000000..427abb4
--- /dev/null
+++ b/ppapi/codereview.settings
@@ -0,0 +1,5 @@
+# This file is used by gcl to get repository specific information.
+CODE_REVIEW_SERVER: codereview.chromium.org
+CC_LIST: chromium-reviews@chromium.org
+VIEW_VC: http://code.google.com/p/ppapi/source/detail?r=
+
diff --git a/ppapi/cpp/completion_callback.h b/ppapi/cpp/completion_callback.h
new file mode 100644
index 0000000..394271a
--- /dev/null
+++ b/ppapi/cpp/completion_callback.h
@@ -0,0 +1,313 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_COMPLETION_CALLBACK_H_
+#define PPAPI_CPP_COMPLETION_CALLBACK_H_
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/non_thread_safe_ref_count.h"
+
+namespace pp {
+
+// A CompletionCallback provides a wrapper around PP_CompletionCallback.
+class CompletionCallback {
+ public:
+ // Use this special constructor to create a 'blocking' CompletionCallback
+ // that may be passed to a method to indicate that the calling thread should
+ // be blocked until the asynchronous operation corresponding to the method
+ // completes.
+ struct Block {};
+ CompletionCallback(Block) {
+ cc_ = PP_BlockUntilComplete();
+ }
+
+ CompletionCallback(PP_CompletionCallback_Func func, void* user_data) {
+ cc_ = PP_MakeCompletionCallback(func, user_data);
+ }
+
+ // Call this method to explicitly run the CompletionCallback. Normally, the
+ // system runs a CompletionCallback after an asynchronous operation
+ // completes, but programs may wish to run the CompletionCallback manually
+ // in order to reuse the same code paths.
+ void Run(int32_t result) {
+ PP_DCHECK(cc_.func);
+ PP_RunCompletionCallback(&cc_, result);
+ }
+
+ const PP_CompletionCallback& pp_completion_callback() const { return cc_; }
+
+ protected:
+ PP_CompletionCallback cc_;
+};
+
+// CompletionCallbackFactory<T> may be used to create CompletionCallback
+// objects that are bound to member functions.
+//
+// If a factory is destroyed, then any pending callbacks will be cancelled
+// preventing any bound member functions from being called. The CancelAll
+// method allows pending callbacks to be cancelled without destroying the
+// factory.
+//
+// NOTE: by default, CompletionCallbackFactory<T> isn't thread safe, but you can
+// make it more thread-friendly by passing a thread-safe refcounting class as
+// the second template element. However, it only guarantees safety for
+// *creating* a callback from another thread, the callback itself needs to
+// execute on the same thread as the thread that creates/destroys the factory.
+// With this restriction, it is safe to create the CompletionCallbackFactory on
+// the main thread, create callbacks from any thread and pass them to
+// CallOnMainThread.
+//
+// EXAMPLE USAGE:
+//
+// class MyHandler {
+// public:
+// MyHandler() : factory_(this), offset_(0) {
+// }
+//
+// void ProcessFile(const FileRef& file) {
+// CompletionCallback cc = factory_.NewCallback(&MyHandler::DidOpen);
+// int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc);
+// if (rv != PP_ERROR_WOULDBLOCK)
+// cc.Run(rv);
+// }
+//
+// private:
+// CompletionCallback NewCallback() {
+// return factory_.NewCallback(&MyHandler::DidCompleteIO);
+// }
+//
+// void DidOpen(int32_t result) {
+// if (result == PP_OK) {
+// // The file is open, and we can begin reading.
+// offset_ = 0;
+// ReadMore();
+// } else {
+// // Failed to open the file with error given by 'result'.
+// }
+// }
+//
+// void DidRead(int32_t result) {
+// if (result > 0) {
+// // buf_ now contains 'result' number of bytes from the file.
+// ProcessBytes(buf_, result);
+// offset_ += result;
+// ReadMore();
+// } else {
+// // Done reading (possibly with an error given by 'result').
+// }
+// }
+//
+// void ReadMore() {
+// CompletionCallback cc = factory_.NewCallback(&MyHandler::DidRead);
+// int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), cc);
+// if (rv != PP_ERROR_WOULDBLOCK)
+// cc.Run(rv);
+// }
+//
+// void ProcessBytes(const char* bytes, int32_t length) {
+// // Do work ...
+// }
+//
+// pp::CompletionCallbackFactory<MyHandler> factory_;
+// pp::FileIO fio_;
+// char buf_[4096];
+// int64_t offset_;
+// };
+//
+template <typename T, typename RefCount = NonThreadSafeRefCount>
+class CompletionCallbackFactory {
+ public:
+ explicit CompletionCallbackFactory(T* object = NULL)
+ : object_(object) {
+ InitBackPointer();
+ }
+
+ ~CompletionCallbackFactory() {
+ ResetBackPointer();
+ }
+
+ // Cancels all CompletionCallbacks allocated from this factory.
+ void CancelAll() {
+ ResetBackPointer();
+ InitBackPointer();
+ }
+
+ void Initialize(T* object) {
+ PP_DCHECK(object);
+ PP_DCHECK(!object_); // May only initialize once!
+ object_ = object;
+ }
+
+ T* GetObject() {
+ return object_;
+ }
+
+ // Allocates a new, single-use CompletionCallback. The CompletionCallback
+ // must be run in order for the memory allocated by NewCallback to be freed.
+ // If after passing the CompletionCallback to a PPAPI method, the method does
+ // not return PP_ERROR_WOULDBLOCK, then you should manually call the
+ // CompletionCallback's Run method otherwise memory will be leaked.
+
+ template <typename Method>
+ CompletionCallback NewCallback(Method method) {
+ PP_DCHECK(object_);
+ return NewCallbackHelper(Dispatcher0<Method>(method));
+ }
+
+ // A copy of "a" will be passed to "method" when the completion callback
+ // runs.
+ //
+ // Method should be of type:
+ // void (T::*)(int32_t result, const A& a)
+ //
+ template <typename Method, typename A>
+ CompletionCallback NewCallback(Method method, const A& a) {
+ PP_DCHECK(object_);
+ return NewCallbackHelper(Dispatcher1<Method, A>(method, a));
+ }
+
+ // A copy of "a" and "b" will be passed to "method" when the completion
+ // callback runs.
+ //
+ // Method should be of type:
+ // void (T::*)(int32_t result, const A& a, const B& b)
+ //
+ template <typename Method, typename A, typename B>
+ CompletionCallback NewCallback(Method method, const A& a, const B& b) {
+ PP_DCHECK(object_);
+ return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b));
+ }
+
+ private:
+ class BackPointer {
+ public:
+ typedef CompletionCallbackFactory<T, RefCount> FactoryType;
+
+ BackPointer(FactoryType* factory)
+ : factory_(factory) {
+ }
+
+ void AddRef() {
+ ref_.AddRef();
+ }
+
+ void Release() {
+ if (ref_.Release() == 0)
+ delete this;
+ }
+
+ void DropFactory() {
+ factory_ = NULL;
+ }
+
+ T* GetObject() {
+ return factory_ ? factory_->GetObject() : NULL;
+ }
+
+ private:
+ RefCount ref_;
+ FactoryType* factory_;
+ };
+
+ template <typename Dispatcher>
+ class CallbackData {
+ public:
+ CallbackData(BackPointer* back_pointer, const Dispatcher& dispatcher)
+ : back_pointer_(back_pointer),
+ dispatcher_(dispatcher) {
+ back_pointer_->AddRef();
+ }
+
+ ~CallbackData() {
+ back_pointer_->Release();
+ }
+
+ static void Thunk(void* user_data, int32_t result) {
+ Self* self = static_cast<Self*>(user_data);
+ T* object = self->back_pointer_->GetObject();
+ if (object)
+ self->dispatcher_(object, result);
+ delete self;
+ }
+
+ private:
+ typedef CallbackData<Dispatcher> Self;
+ BackPointer* back_pointer_;
+ Dispatcher dispatcher_;
+ };
+
+ template <typename Method>
+ class Dispatcher0 {
+ public:
+ Dispatcher0(Method method) : method_(method) {
+ }
+ void operator()(T* object, int32_t result) {
+ (object->*method_)(result);
+ }
+ private:
+ Method method_;
+ };
+
+ template <typename Method, typename A>
+ class Dispatcher1 {
+ public:
+ Dispatcher1(Method method, const A& a)
+ : method_(method),
+ a_(a) {
+ }
+ void operator()(T* object, int32_t result) {
+ (object->*method_)(result, a_);
+ }
+ private:
+ Method method_;
+ A a_;
+ };
+
+ template <typename Method, typename A, typename B>
+ class Dispatcher2 {
+ public:
+ Dispatcher2(Method method, const A& a, const B& b)
+ : method_(method),
+ a_(a),
+ b_(b) {
+ }
+ void operator()(T* object, int32_t result) {
+ (object->*method_)(result, a_, b_);
+ }
+ private:
+ Method method_;
+ A a_;
+ B b_;
+ };
+
+ void InitBackPointer() {
+ back_pointer_ = new BackPointer(this);
+ back_pointer_->AddRef();
+ }
+
+ void ResetBackPointer() {
+ back_pointer_->DropFactory();
+ back_pointer_->Release();
+ }
+
+ template <typename Dispatcher>
+ CompletionCallback NewCallbackHelper(const Dispatcher& dispatcher) {
+ PP_DCHECK(object_); // Expects a non-null object!
+ return CompletionCallback(
+ &CallbackData<Dispatcher>::Thunk,
+ new CallbackData<Dispatcher>(back_pointer_, dispatcher));
+ }
+
+ // Disallowed:
+ CompletionCallbackFactory(const CompletionCallbackFactory&);
+ CompletionCallbackFactory& operator=(const CompletionCallbackFactory&);
+
+ T* object_;
+ BackPointer* back_pointer_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_COMPLETION_CALLBACK_H_
diff --git a/ppapi/cpp/core.cc b/ppapi/cpp/core.cc
new file mode 100644
index 0000000..5a24ecb
--- /dev/null
+++ b/ppapi/cpp/core.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/core.h"
+
+#include "ppapi/cpp/completion_callback.h"
+
+namespace pp {
+
+// This function is implemented in the .cc file to avoid including completion
+// callback all over the project.
+void Core::CallOnMainThread(int32_t delay_in_milliseconds,
+ const CompletionCallback& callback,
+ int32_t result) {
+ return interface_->CallOnMainThread(delay_in_milliseconds,
+ callback.pp_completion_callback(),
+ result);
+}
+
+bool Core::IsMainThread() {
+ return interface_->IsMainThread();
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/core.h b/ppapi/cpp/core.h
new file mode 100644
index 0000000..50c89d5
--- /dev/null
+++ b/ppapi/cpp/core.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_CORE_H_
+#define PPAPI_CPP_CORE_H_
+
+#include "ppapi/c/ppb_core.h"
+
+namespace pp {
+
+class CompletionCallback;
+class Module;
+
+// Simple wrapper around the PPB_Core interface. Some of these wrappers add
+// nothing over the C interface, but some allow the use of C++ arguments.
+class Core {
+ public:
+ // Note that we explicitly don't expose Resource& versions of this function
+ // since Resource will normally manage the refcount properly. These should
+ // be called only when doing manual management on raw PP_Resource handles,
+ // which should be fairly rare.
+ void AddRefResource(PP_Resource resource) {
+ interface_->AddRefResource(resource);
+ }
+ void ReleaseResource(PP_Resource resource) {
+ interface_->ReleaseResource(resource);
+ }
+
+ void* MemAlloc(size_t num_bytes) {
+ return interface_->MemAlloc(num_bytes);
+ }
+ void MemFree(void* ptr) {
+ interface_->MemFree(ptr);
+ }
+
+ PP_Time GetTime() {
+ return interface_->GetTime();
+ }
+
+ PP_TimeTicks GetTimeTicks() {
+ return interface_->GetTimeTicks();
+ }
+
+ void CallOnMainThread(int32_t delay_in_milliseconds,
+ const CompletionCallback& callback,
+ int32_t result = 0);
+
+ bool IsMainThread();
+
+ private:
+ // Allow Module to construct.
+ friend class Module;
+
+ // Only module should make this class so this constructor is private.
+ Core(const PPB_Core* inter) : interface_(inter) {}
+
+ // Copy and assignment are disallowed.
+ Core(const Core& other);
+ Core& operator=(const Core& other);
+
+ const PPB_Core* interface_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_CORE_H_
diff --git a/ppapi/cpp/dev/audio_config_dev.cc b/ppapi/cpp/dev/audio_config_dev.cc
new file mode 100644
index 0000000..c68dd84
--- /dev/null
+++ b/ppapi/cpp/dev/audio_config_dev.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/audio_config_dev.h"
+
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+DeviceFuncs<PPB_AudioConfig_Dev> audio_cfg_f(PPB_AUDIO_CONFIG_DEV_INTERFACE);
+
+namespace pp {
+
+AudioConfig_Dev::AudioConfig_Dev()
+ : sample_rate_(PP_AUDIOSAMPLERATE_NONE),
+ sample_frame_count_(0) {
+}
+
+AudioConfig_Dev::AudioConfig_Dev(PP_AudioSampleRate_Dev sample_rate,
+ uint32_t sample_frame_count)
+ : sample_rate_(sample_rate),
+ sample_frame_count_(sample_frame_count) {
+ if (audio_cfg_f) {
+ PassRefFromConstructor(audio_cfg_f->CreateStereo16Bit(
+ Module::Get()->pp_module(), sample_rate,
+ sample_frame_count));
+ }
+}
+
+// static
+uint32_t AudioConfig_Dev::RecommendSampleFrameCount(
+ uint32_t requested_sample_frame_count) {
+ if (!audio_cfg_f)
+ return 0;
+ return audio_cfg_f->RecommendSampleFrameCount(requested_sample_frame_count);
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/audio_config_dev.h b/ppapi/cpp/dev/audio_config_dev.h
new file mode 100644
index 0000000..1229156
--- /dev/null
+++ b/ppapi/cpp/dev/audio_config_dev.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_AUDIO_CONFIG_DEV_H_
+#define PPAPI_CPP_DEV_AUDIO_CONFIG_DEV_H_
+
+#include "ppapi/c/dev/ppb_audio_config_dev.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+// Typical usage:
+//
+// // Create an audio config with a supported frame count.
+// uint32_t sample_frame_count =
+// AudioConfig_Dev::RecommendSampleFrameCount(4096);
+// AudioConfig_Dev config(PP_AUDIOSAMPLERATE_44100, sample_frame_count);
+// if (config.is_null())
+// return false; // Couldn't configure audio.
+//
+// // Then use the config to create your audio resource.
+// Audio_dev audio(..., config, ...);
+// if (audio.is_null())
+// return false; // Couldn't create audio.
+class AudioConfig_Dev : public Resource {
+ public:
+ AudioConfig_Dev();
+
+ // Creates an audio config based on the given sample rate and frame count.
+ // If the rate and frame count aren't supported, the resulting resource
+ // will be is_null(). Pass the result of RecommendSampleFrameCount as the
+ // semple frame count.
+ //
+ // See PPB_AudioConfigDev.CreateStereo16Bit for more.
+ AudioConfig_Dev(PP_AudioSampleRate_Dev sample_rate,
+ uint32_t sample_frame_count);
+
+ // Returns a supported frame count for use in the constructor.
+ //
+ // See PPB_AudioConfigDev.RecommendSampleFrameCount.
+ static uint32_t RecommendSampleFrameCount(
+ uint32_t requested_sample_frame_count);
+
+ PP_AudioSampleRate_Dev sample_rate() const { return sample_rate_; }
+ uint32_t sample_frame_count() { return sample_frame_count_; }
+
+ private:
+ PP_AudioSampleRate_Dev sample_rate_;
+ uint32_t sample_frame_count_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_AUDIO_CONFIG_DEV_H_
+
diff --git a/ppapi/cpp/dev/audio_dev.cc b/ppapi/cpp/dev/audio_dev.cc
new file mode 100644
index 0000000..c747c78
--- /dev/null
+++ b/ppapi/cpp/dev/audio_dev.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/audio_dev.h"
+
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_Audio_Dev> audio_f(PPB_AUDIO_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Audio_Dev::Audio_Dev(const Instance& instance,
+ const AudioConfig_Dev& config,
+ PPB_Audio_Callback callback,
+ void* user_data)
+ : config_(config) {
+ if (audio_f) {
+ PassRefFromConstructor(audio_f->Create(instance.pp_instance(),
+ config.pp_resource(),
+ callback, user_data));
+ }
+}
+
+bool Audio_Dev::StartPlayback() {
+ return audio_f && audio_f->StartPlayback(pp_resource());
+}
+
+bool Audio_Dev::StopPlayback() {
+ return audio_f && audio_f->StopPlayback(pp_resource());
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/audio_dev.h b/ppapi/cpp/dev/audio_dev.h
new file mode 100644
index 0000000..983e53c
--- /dev/null
+++ b/ppapi/cpp/dev/audio_dev.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_AUDIO_DEV_H_
+#define PPAPI_CPP_DEV_AUDIO_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/dev/ppb_audio_dev.h"
+#include "ppapi/cpp/dev/audio_config_dev.h"
+#include "ppapi/cpp/dev/buffer_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Audio_Dev : public Resource {
+ public:
+ Audio_Dev() {}
+ Audio_Dev(const Instance& instance,
+ const AudioConfig_Dev& config,
+ PPB_Audio_Callback callback,
+ void* user_data);
+
+ AudioConfig_Dev& config() { return config_; }
+ const AudioConfig_Dev& config() const { return config_; }
+
+ bool StartPlayback();
+ bool StopPlayback();
+
+ private:
+ AudioConfig_Dev config_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_AUDIO_DEV_H_
+
diff --git a/ppapi/cpp/dev/buffer_dev.cc b/ppapi/cpp/dev/buffer_dev.cc
new file mode 100644
index 0000000..57ebed7
--- /dev/null
+++ b/ppapi/cpp/dev/buffer_dev.cc
@@ -0,0 +1,55 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/buffer_dev.h"
+
+#include "ppapi/c/dev/ppb_buffer_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_Buffer_Dev> buffer_f(PPB_BUFFER_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Buffer_Dev::Buffer_Dev() : data_(NULL), size_(0) {
+}
+
+Buffer_Dev::Buffer_Dev(const Buffer_Dev& other)
+ : Resource(other),
+ data_(other.data_),
+ size_(other.size_) {
+}
+
+Buffer_Dev::Buffer_Dev(int32_t size) : data_(NULL), size_(0) {
+ if (!buffer_f)
+ return;
+
+ PassRefFromConstructor(buffer_f->Create(Module::Get()->pp_module(), size));
+ if (!buffer_f->Describe(pp_resource(), &size_) ||
+ !(data_ = buffer_f->Map(pp_resource())))
+ *this = Buffer_Dev();
+}
+
+Buffer_Dev::~Buffer_Dev() {
+}
+
+Buffer_Dev& Buffer_Dev::operator=(const Buffer_Dev& other) {
+ Buffer_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Buffer_Dev::swap(Buffer_Dev& other) {
+ Resource::swap(other);
+ std::swap(size_, other.size_);
+ std::swap(data_, other.data_);
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/buffer_dev.h b/ppapi/cpp/dev/buffer_dev.h
new file mode 100644
index 0000000..7497a6f
--- /dev/null
+++ b/ppapi/cpp/dev/buffer_dev.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_BUFFER_DEV_H_
+#define PPAPI_CPP_DEV_BUFFER_DEV_H_
+
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Buffer_Dev : public Resource {
+ public:
+ // Creates an is_null() Buffer object.
+ Buffer_Dev();
+
+ Buffer_Dev(const Buffer_Dev& other);
+
+ // Allocates a new Buffer in the browser with the given size. The
+ // resulting object will be is_null() if the allocation failed.
+ explicit Buffer_Dev(int32_t size);
+
+ ~Buffer_Dev();
+
+ Buffer_Dev& operator=(const Buffer_Dev& other);
+ void swap(Buffer_Dev& other);
+
+ int32_t size() const { return size_; }
+ void* data() const { return data_; }
+
+ private:
+ void* data_;
+ int32_t size_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_BUFFER_DEV_H_
+
diff --git a/ppapi/cpp/dev/directory_entry_dev.cc b/ppapi/cpp/dev/directory_entry_dev.cc
new file mode 100644
index 0000000..a5f8179
--- /dev/null
+++ b/ppapi/cpp/dev/directory_entry_dev.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/directory_entry_dev.h"
+
+#include <string.h>
+
+#include "ppapi/cpp/module.h"
+
+namespace pp {
+
+DirectoryEntry_Dev::DirectoryEntry_Dev() {
+ memset(&data_, 0, sizeof(data_));
+}
+
+DirectoryEntry_Dev::DirectoryEntry_Dev(const DirectoryEntry_Dev& other) {
+ data_.file_ref = other.data_.file_ref;
+ data_.file_type = other.data_.file_type;
+ if (data_.file_ref)
+ Module::Get()->core()->AddRefResource(data_.file_ref);
+}
+
+DirectoryEntry_Dev::~DirectoryEntry_Dev() {
+ if (data_.file_ref)
+ Module::Get()->core()->ReleaseResource(data_.file_ref);
+}
+
+DirectoryEntry_Dev& DirectoryEntry_Dev::operator=(
+ const DirectoryEntry_Dev& other) {
+ DirectoryEntry_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void DirectoryEntry_Dev::swap(DirectoryEntry_Dev& other) {
+ std::swap(data_.file_ref, other.data_.file_ref);
+ std::swap(data_.file_type, other.data_.file_type);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/directory_entry_dev.h b/ppapi/cpp/dev/directory_entry_dev.h
new file mode 100644
index 0000000..84ef623
--- /dev/null
+++ b/ppapi/cpp/dev/directory_entry_dev.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_DIRECTORY_ENTRY_DEV_H_
+#define PPAPI_CPP_DEV_DIRECTORY_ENTRY_DEV_H_
+
+#include "ppapi/c/dev/ppb_directory_reader_dev.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+
+namespace pp {
+
+class DirectoryEntry_Dev {
+ public:
+ DirectoryEntry_Dev();
+ DirectoryEntry_Dev(const DirectoryEntry_Dev& other);
+ ~DirectoryEntry_Dev();
+
+ DirectoryEntry_Dev& operator=(const DirectoryEntry_Dev& other);
+ void swap(DirectoryEntry_Dev& other);
+
+ // Returns true if the DirectoryEntry is invalid or uninitialized.
+ bool is_null() const { return !data_.file_ref; }
+
+ // Returns the FileRef held by this DirectoryEntry.
+ FileRef_Dev file_ref() const { return FileRef_Dev(data_.file_ref); }
+
+ // Returns the type of the file referenced by this DirectoryEntry.
+ PP_FileType_Dev file_type() const { return data_.file_type; }
+
+ private:
+ friend class DirectoryReader_Dev;
+ PP_DirectoryEntry_Dev data_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_DIRECTORY_ENTRY_DEV_H_
diff --git a/ppapi/cpp/dev/directory_reader_dev.cc b/ppapi/cpp/dev/directory_reader_dev.cc
new file mode 100644
index 0000000..bcf5e11
--- /dev/null
+++ b/ppapi/cpp/dev/directory_reader_dev.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/directory_reader_dev.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/directory_entry_dev.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_DirectoryReader_Dev> directory_reader_f(
+ PPB_DIRECTORYREADER_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+DirectoryReader_Dev::DirectoryReader_Dev(const FileRef_Dev& directory_ref) {
+ if (!directory_reader_f)
+ return;
+ PassRefFromConstructor(
+ directory_reader_f->Create(directory_ref.pp_resource()));
+}
+
+DirectoryReader_Dev::DirectoryReader_Dev(const DirectoryReader_Dev& other)
+ : Resource(other) {
+}
+
+DirectoryReader_Dev& DirectoryReader_Dev::operator=(
+ const DirectoryReader_Dev& other) {
+ DirectoryReader_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void DirectoryReader_Dev::swap(DirectoryReader_Dev& other) {
+ Resource::swap(other);
+}
+
+int32_t DirectoryReader_Dev::GetNextEntry(DirectoryEntry_Dev* entry,
+ const CompletionCallback& cc) {
+ if (!directory_reader_f)
+ return PP_ERROR_NOINTERFACE;
+ return directory_reader_f->GetNextEntry(pp_resource(), &entry->data_,
+ cc.pp_completion_callback());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/directory_reader_dev.h b/ppapi/cpp/dev/directory_reader_dev.h
new file mode 100644
index 0000000..e90fbc0
--- /dev/null
+++ b/ppapi/cpp/dev/directory_reader_dev.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_DIRECTORY_READER_DEV_H_
+#define PPAPI_CPP_DEV_DIRECTORY_READER_DEV_H_
+
+#include <stdlib.h>
+
+#include "ppapi/c/dev/ppb_directory_reader_dev.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class CompletionCallback;
+class DirectoryEntry_Dev;
+class FileRef_Dev;
+
+class DirectoryReader_Dev : public Resource {
+ public:
+ // Creates a DirectoryReader for the given directory.
+ DirectoryReader_Dev(const FileRef_Dev& directory_ref);
+
+ DirectoryReader_Dev(const DirectoryReader_Dev& other);
+
+ DirectoryReader_Dev& operator=(const DirectoryReader_Dev& other);
+ void swap(DirectoryReader_Dev& other);
+
+ // See PPB_DirectoryReader::GetNextEntry.
+ int32_t GetNextEntry(DirectoryEntry_Dev* entry,
+ const CompletionCallback& cc);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DIRECTORY_READER_H_
diff --git a/ppapi/cpp/dev/file_chooser_dev.cc b/ppapi/cpp/dev/file_chooser_dev.cc
new file mode 100644
index 0000000..051ab38
--- /dev/null
+++ b/ppapi/cpp/dev/file_chooser_dev.cc
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/file_chooser_dev.h"
+
+#include "ppapi/c/dev/ppb_file_chooser_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_FileChooser_Dev> file_chooser_f(PPB_FILECHOOSER_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+FileChooser_Dev::FileChooser_Dev(const Instance& instance,
+ const PP_FileChooserOptions_Dev& options) {
+ if (!file_chooser_f)
+ return;
+ PassRefFromConstructor(file_chooser_f->Create(instance.pp_instance(),
+ &options));
+}
+
+FileChooser_Dev::FileChooser_Dev(const FileChooser_Dev& other)
+ : Resource(other) {
+}
+
+FileChooser_Dev& FileChooser_Dev::operator=(const FileChooser_Dev& other) {
+ FileChooser_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void FileChooser_Dev::swap(FileChooser_Dev& other) {
+ Resource::swap(other);
+}
+
+int32_t FileChooser_Dev::Show(const CompletionCallback& cc) {
+ if (!file_chooser_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_chooser_f->Show(pp_resource(), cc.pp_completion_callback());
+}
+
+FileRef_Dev FileChooser_Dev::GetNextChosenFile() const {
+ if (!file_chooser_f)
+ return FileRef_Dev();
+ return FileRef_Dev(FileRef_Dev::PassRef(),
+ file_chooser_f->GetNextChosenFile(pp_resource()));
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/file_chooser_dev.h b/ppapi/cpp/dev/file_chooser_dev.h
new file mode 100644
index 0000000..f611b1e
--- /dev/null
+++ b/ppapi/cpp/dev/file_chooser_dev.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_FILE_CHOOSER_DEV_H_
+#define PPAPI_CPP_DEV_FILE_CHOOSER_DEV_H_
+
+#include "ppapi/cpp/resource.h"
+
+struct PP_FileChooserOptions_Dev;
+
+namespace pp {
+
+class CompletionCallback;
+class FileRef_Dev;
+class Instance;
+
+class FileChooser_Dev : public Resource {
+ public:
+ // Creates an is_null() FileChooser object.
+ FileChooser_Dev() {}
+
+ FileChooser_Dev(const Instance& instance,
+ const PP_FileChooserOptions_Dev& options);
+
+ FileChooser_Dev(const FileChooser_Dev& other);
+
+ FileChooser_Dev& operator=(const FileChooser_Dev& other);
+ void swap(FileChooser_Dev& other);
+
+ // PPB_FileChooser methods:
+ int32_t Show(const CompletionCallback& cc);
+ FileRef_Dev GetNextChosenFile() const;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FILE_CHOOSER_DEV_H_
diff --git a/ppapi/cpp/dev/file_io_dev.cc b/ppapi/cpp/dev/file_io_dev.cc
new file mode 100644
index 0000000..54731ed
--- /dev/null
+++ b/ppapi/cpp/dev/file_io_dev.cc
@@ -0,0 +1,135 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/file_io_dev.h"
+
+#include "ppapi/c/dev/ppb_file_io_dev.h"
+#include "ppapi/c/dev/ppb_file_io_trusted_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_FileIO_Dev> file_io_f(
+ PPB_FILEIO_DEV_INTERFACE);
+DeviceFuncs<PPB_FileIOTrusted_Dev> file_io_trusted_f(
+ PPB_FILEIOTRUSTED_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+FileIO_Dev::FileIO_Dev() {
+ if (!file_io_f)
+ return;
+ PassRefFromConstructor(file_io_f->Create(Module::Get()->pp_module()));
+}
+
+FileIO_Dev::FileIO_Dev(const FileIO_Dev& other)
+ : Resource(other) {
+}
+
+FileIO_Dev& FileIO_Dev::operator=(const FileIO_Dev& other) {
+ FileIO_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void FileIO_Dev::swap(FileIO_Dev& other) {
+ Resource::swap(other);
+}
+
+int32_t FileIO_Dev::Open(const FileRef_Dev& file_ref,
+ int32_t open_flags,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Open(pp_resource(), file_ref.pp_resource(), open_flags,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::Query(PP_FileInfo_Dev* result_buf,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Query(pp_resource(), result_buf,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Touch(pp_resource(), last_access_time, last_modified_time,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::Read(int64_t offset,
+ char* buffer,
+ int32_t bytes_to_read,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Read(pp_resource(), offset, buffer, bytes_to_read,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::Write(int64_t offset,
+ const char* buffer,
+ int32_t bytes_to_write,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Write(pp_resource(), offset, buffer, bytes_to_write,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::SetLength(int64_t length,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->SetLength(pp_resource(), length,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::Flush(const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Flush(pp_resource(), cc.pp_completion_callback());
+}
+
+void FileIO_Dev::Close() {
+ if (!file_io_f)
+ return;
+ file_io_f->Close(pp_resource());
+}
+
+int32_t FileIO_Dev::GetOSFileDescriptor() {
+ if (!file_io_trusted_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_trusted_f->GetOSFileDescriptor(pp_resource());
+}
+
+int32_t FileIO_Dev::WillWrite(int64_t offset,
+ int32_t bytes_to_write,
+ const CompletionCallback& cc) {
+ if (!file_io_trusted_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_trusted_f->WillWrite(pp_resource(), offset, bytes_to_write,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::WillSetLength(int64_t length,
+ const CompletionCallback& cc) {
+ if (!file_io_trusted_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_trusted_f->WillSetLength(pp_resource(), length,
+ cc.pp_completion_callback());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/file_io_dev.h b/ppapi/cpp/dev/file_io_dev.h
new file mode 100644
index 0000000..e38c2e1
--- /dev/null
+++ b/ppapi/cpp/dev/file_io_dev.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_FILE_IO_DEV_H_
+#define PPAPI_CPP_DEV_FILE_IO_DEV_H_
+
+#include "ppapi/c/pp_time.h"
+#include "ppapi/cpp/resource.h"
+
+struct PP_FileInfo_Dev;
+
+namespace pp {
+
+class CompletionCallback;
+class FileRef_Dev;
+
+class FileIO_Dev : public Resource {
+ public:
+ FileIO_Dev();
+ FileIO_Dev(const FileIO_Dev& other);
+
+ FileIO_Dev& operator=(const FileIO_Dev& other);
+ void swap(FileIO_Dev& other);
+
+ // PPB_FileIO methods:
+ int32_t Open(const FileRef_Dev& file_ref,
+ int32_t open_flags,
+ const CompletionCallback& cc);
+ int32_t Query(PP_FileInfo_Dev* result_buf,
+ const CompletionCallback& cc);
+ int32_t Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ const CompletionCallback& cc);
+ int32_t Read(int64_t offset,
+ char* buffer,
+ int32_t bytes_to_read,
+ const CompletionCallback& cc);
+ int32_t Write(int64_t offset,
+ const char* buffer,
+ int32_t bytes_to_write,
+ const CompletionCallback& cc);
+ int32_t SetLength(int64_t length,
+ const CompletionCallback& cc);
+ int32_t Flush(const CompletionCallback& cc);
+ void Close();
+
+ // PPB_FileIOTrusted methods:
+ // NOTE: These are only available to trusted plugins and will return
+ // PP_ERROR_NOINTERFACE if called from an untrusted plugin.
+ int32_t GetOSFileDescriptor();
+ int32_t WillWrite(int64_t offset,
+ int32_t bytes_to_write,
+ const CompletionCallback& cc);
+ int32_t WillSetLength(int64_t length,
+ const CompletionCallback& cc);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FILE_IO_DEV_H_
diff --git a/ppapi/cpp/dev/file_ref_dev.cc b/ppapi/cpp/dev/file_ref_dev.cc
new file mode 100644
index 0000000..c65c07f
--- /dev/null
+++ b/ppapi/cpp/dev/file_ref_dev.cc
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/file_ref_dev.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_system_dev.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_FileRef_Dev> file_ref_f(PPB_FILEREF_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+FileRef_Dev::FileRef_Dev(PP_Resource resource) : Resource(resource) {
+}
+
+FileRef_Dev::FileRef_Dev(PassRef, PP_Resource resource) {
+ PassRefFromConstructor(resource);
+}
+
+FileRef_Dev::FileRef_Dev(const FileSystem_Dev& file_system,
+ const char* path) {
+ if (!file_ref_f)
+ return;
+ PassRefFromConstructor(file_ref_f->Create(file_system.pp_resource(), path));
+}
+
+FileRef_Dev::FileRef_Dev(const FileRef_Dev& other)
+ : Resource(other) {
+}
+
+FileRef_Dev& FileRef_Dev::operator=(const FileRef_Dev& other) {
+ FileRef_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void FileRef_Dev::swap(FileRef_Dev& other) {
+ Resource::swap(other);
+}
+
+PP_FileSystemType_Dev FileRef_Dev::GetFileSystemType() const {
+ if (!file_ref_f)
+ return PP_FILESYSTEMTYPE_EXTERNAL;
+ return file_ref_f->GetFileSystemType(pp_resource());
+}
+
+Var FileRef_Dev::GetName() const {
+ if (!file_ref_f)
+ return Var();
+ return Var(Var::PassRef(), file_ref_f->GetName(pp_resource()));
+}
+
+Var FileRef_Dev::GetPath() const {
+ if (!file_ref_f)
+ return Var();
+ return Var(Var::PassRef(), file_ref_f->GetPath(pp_resource()));
+}
+
+FileRef_Dev FileRef_Dev::GetParent() const {
+ if (!file_ref_f)
+ return FileRef_Dev();
+ return FileRef_Dev(PassRef(), file_ref_f->GetParent(pp_resource()));
+}
+
+int32_t FileRef_Dev::MakeDirectory(const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->MakeDirectory(pp_resource(),
+ false, // make_ancestors
+ cc.pp_completion_callback());
+}
+
+int32_t FileRef_Dev::MakeDirectoryIncludingAncestors(
+ const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->MakeDirectory(pp_resource(),
+ true, // make_ancestors
+ cc.pp_completion_callback());
+}
+
+int32_t FileRef_Dev::Query(PP_FileInfo_Dev* result_buf,
+ const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->Query(pp_resource(),
+ result_buf,
+ cc.pp_completion_callback());
+}
+
+int32_t FileRef_Dev::Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->Touch(pp_resource(),
+ last_access_time,
+ last_modified_time,
+ cc.pp_completion_callback());
+}
+
+int32_t FileRef_Dev::Delete(const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->Delete(pp_resource(), cc.pp_completion_callback());
+}
+
+int32_t FileRef_Dev::Rename(const FileRef_Dev& new_file_ref,
+ const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->Rename(pp_resource(),
+ new_file_ref.pp_resource(),
+ cc.pp_completion_callback());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/file_ref_dev.h b/ppapi/cpp/dev/file_ref_dev.h
new file mode 100644
index 0000000..b2d10a6
--- /dev/null
+++ b/ppapi/cpp/dev/file_ref_dev.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_FILE_REF_DEV_H_
+#define PPAPI_CPP_DEV_FILE_REF_DEV_H_
+
+#include "ppapi/c/dev/ppb_file_ref_dev.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+class CompletionCallback;
+class FileSystem_Dev;
+
+class FileRef_Dev : public Resource {
+ public:
+ // Creates an is_null() FileRef object.
+ FileRef_Dev() {}
+
+ // This constructor is used when we've gotten a PP_Resource as a return value
+ // that we need to addref.
+ explicit FileRef_Dev(PP_Resource resource);
+
+ // This constructor is used when we've gotten a PP_Resource as a return value
+ // that has already been addref'ed for us.
+ struct PassRef {};
+ FileRef_Dev(PassRef, PP_Resource resource);
+
+ // Creates a FileRef pointing to a path in the given filesystem.
+ FileRef_Dev(const FileSystem_Dev& file_system, const char* path);
+
+ FileRef_Dev(const FileRef_Dev& other);
+
+ FileRef_Dev& operator=(const FileRef_Dev& other);
+ void swap(FileRef_Dev& other);
+
+ // Returns the file system type.
+ PP_FileSystemType_Dev GetFileSystemType() const;
+
+ // Returns the name of the file.
+ Var GetName() const;
+
+ // Returns the absolute path of the file. See PPB_FileRef::GetPath for more
+ // details.
+ Var GetPath() const;
+
+ // Returns the parent directory of this file. See PPB_FileRef::GetParent for
+ // more details.
+ FileRef_Dev GetParent() const;
+
+ int32_t MakeDirectory(const CompletionCallback& cc);
+
+ int32_t MakeDirectoryIncludingAncestors(const CompletionCallback& cc);
+
+ int32_t Query(PP_FileInfo_Dev* result_buf, const CompletionCallback& cc);
+
+ int32_t Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ const CompletionCallback& cc);
+
+ int32_t Delete(const CompletionCallback& cc);
+
+ int32_t Rename(const FileRef_Dev& new_file_ref, const CompletionCallback& cc);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_FILE_REF_H_
diff --git a/ppapi/cpp/dev/file_system_dev.cc b/ppapi/cpp/dev/file_system_dev.cc
new file mode 100644
index 0000000..e6dfaff
--- /dev/null
+++ b/ppapi/cpp/dev/file_system_dev.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/file_system_dev.h"
+
+#include "ppapi/c/dev/ppb_file_system_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_FileSystem_Dev> file_sys_f(PPB_FILESYSTEM_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+FileSystem_Dev::FileSystem_Dev(Instance* instance,
+ PP_FileSystemType_Dev type) {
+ if (!file_sys_f)
+ return;
+ PassRefFromConstructor(file_sys_f->Create(instance->pp_instance(), type));
+}
+
+int32_t FileSystem_Dev::Open(int64_t expected_size,
+ const CompletionCallback& cc) {
+ if (!file_sys_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_sys_f->Open(pp_resource(), expected_size,
+ cc.pp_completion_callback());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/file_system_dev.h b/ppapi/cpp/dev/file_system_dev.h
new file mode 100644
index 0000000..497740a
--- /dev/null
+++ b/ppapi/cpp/dev/file_system_dev.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_FILE_SYSTEM_DEV_H_
+#define PPAPI_CPP_DEV_FILE_SYSTEM_DEV_H_
+
+#include "ppapi/c/dev/pp_file_info_dev.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_time.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+
+struct PP_FileInfo_Dev;
+
+namespace pp {
+
+class CompletionCallback;
+class FileRef_Dev;
+
+// Wraps methods from ppb_file_system.h
+class FileSystem_Dev : public Resource {
+ public:
+ FileSystem_Dev(Instance* instance, PP_FileSystemType_Dev type);
+
+ int32_t Open(int64_t expected_size, const CompletionCallback& cc);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FILE_SYSTEM_DEV_H_
diff --git a/ppapi/cpp/dev/find_dev.cc b/ppapi/cpp/dev/find_dev.cc
new file mode 100644
index 0000000..8cbde54
--- /dev/null
+++ b/ppapi/cpp/dev/find_dev.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/find_dev.h"
+
+#include "ppapi/c/dev/ppb_find_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+static const char kPPPFindInterface[] = PPP_FIND_DEV_INTERFACE;
+
+bool StartFind(PP_Instance instance,
+ const char* text,
+ bool case_sensitive) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPFindInterface);
+ if (!object)
+ return false;
+ return static_cast<Find_Dev*>(object)->StartFind(text, case_sensitive);
+}
+
+void SelectFindResult(PP_Instance instance, bool forward) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPFindInterface);
+ if (object)
+ static_cast<Find_Dev*>(object)->SelectFindResult(forward);
+}
+
+void StopFind(PP_Instance instance) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPFindInterface);
+ if (object)
+ static_cast<Find_Dev*>(object)->StopFind();
+}
+
+const PPP_Find_Dev ppp_find = {
+ &StartFind,
+ &SelectFindResult,
+ &StopFind
+};
+
+DeviceFuncs<PPB_Find_Dev> ppb_find_f(PPB_FIND_DEV_INTERFACE);
+
+} // namespace
+
+Find_Dev::Find_Dev(Instance* instance) : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPFindInterface, &ppp_find);
+ associated_instance_->AddPerInstanceObject(kPPPFindInterface, this);
+}
+
+Find_Dev::~Find_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPFindInterface, this);
+}
+
+void Find_Dev::NumberOfFindResultsChanged(int32_t total, bool final_result) {
+ if (ppb_find_f) {
+ ppb_find_f->NumberOfFindResultsChanged(associated_instance_->pp_instance(),
+ total, final_result);
+ }
+}
+
+void Find_Dev::SelectedFindResultChanged(int32_t index) {
+ if (ppb_find_f) {
+ ppb_find_f->SelectedFindResultChanged(associated_instance_->pp_instance(),
+ index);
+ }
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/find_dev.h b/ppapi/cpp/dev/find_dev.h
new file mode 100644
index 0000000..b89160f
--- /dev/null
+++ b/ppapi/cpp/dev/find_dev.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_FIND_DEV_H_
+#define PPAPI_CPP_DEV_FIND_DEV_H_
+
+#include <string>
+
+#include "ppapi/c/dev/ppp_find_dev.h"
+
+namespace pp {
+
+class Instance;
+
+// This class allows you to associate the PPP_Find and PPB_Find C-based
+// interfaces with an object. It associates itself with the given instance, and
+// registers as the global handler for handling the PPP_Find interface that the
+// browser calls.
+//
+// You would typically use this either via inheritance on your instance:
+// class MyInstance : public pp::Instance, public pp::Find_Dev {
+// class MyInstance() : pp::Find_Dev(this) {
+// }
+// ...
+// };
+//
+// or by composition:
+// class MyFinder : public pp::Find {
+// ...
+// };
+//
+// class MyInstance : public pp::Instance {
+// MyInstance() : finder_(this) {
+// }
+//
+// MyFinder finder_;
+// };
+class Find_Dev {
+ public:
+ // The instance parameter must outlive this class.
+ Find_Dev(Instance* instance);
+ virtual ~Find_Dev();
+
+ // PPP_Find_Dev functions exposed as virtual functions for you to
+ // override.
+ virtual bool StartFind(const std::string& text, bool case_sensitive) = 0;
+ virtual void SelectFindResult(bool forward) = 0;
+ virtual void StopFind() = 0;
+
+ // PPB_Find_Def functions for you to call to report find results.
+ void NumberOfFindResultsChanged(int32_t total, bool final_result);
+ void SelectedFindResultChanged(int32_t index);
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FIND_DEV_H_
diff --git a/ppapi/cpp/dev/font_dev.cc b/ppapi/cpp/dev/font_dev.cc
new file mode 100644
index 0000000..9e294fb
--- /dev/null
+++ b/ppapi/cpp/dev/font_dev.cc
@@ -0,0 +1,210 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/font_dev.h"
+
+#include <algorithm>
+
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_Font_Dev> font_f(PPB_FONT_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+// FontDescription_Dev ---------------------------------------------------------
+
+FontDescription_Dev::FontDescription_Dev() {
+ pp_font_description_.face = face_.pp_var();
+ set_family(PP_FONTFAMILY_DEFAULT);
+ set_size(0);
+ set_weight(PP_FONTWEIGHT_NORMAL);
+ set_italic(false);
+ set_small_caps(false);
+ set_letter_spacing(0);
+ set_word_spacing(0);
+}
+
+FontDescription_Dev::FontDescription_Dev(const FontDescription_Dev& other) {
+ set_face(other.face());
+ set_family(other.family());
+ set_size(other.size());
+ set_weight(other.weight());
+ set_italic(other.italic());
+ set_small_caps(other.small_caps());
+ set_letter_spacing(other.letter_spacing());
+ set_word_spacing(other.word_spacing());
+}
+
+FontDescription_Dev::~FontDescription_Dev() {
+}
+
+FontDescription_Dev& FontDescription_Dev::operator=(
+ const FontDescription_Dev& other) {
+ FontDescription_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void FontDescription_Dev::swap(FontDescription_Dev& other) {
+ // Need to fix up both the face and the pp_font_description_.face which the
+ // setter does for us.
+ Var temp = face();
+ set_face(other.face());
+ other.set_face(temp);
+
+ std::swap(pp_font_description_.family, other.pp_font_description_.family);
+ std::swap(pp_font_description_.size, other.pp_font_description_.size);
+ std::swap(pp_font_description_.weight, other.pp_font_description_.weight);
+ std::swap(pp_font_description_.italic, other.pp_font_description_.italic);
+ std::swap(pp_font_description_.small_caps,
+ other.pp_font_description_.small_caps);
+ std::swap(pp_font_description_.letter_spacing,
+ other.pp_font_description_.letter_spacing);
+ std::swap(pp_font_description_.word_spacing,
+ other.pp_font_description_.word_spacing);
+}
+
+// TextRun_Dev -----------------------------------------------------------------
+
+TextRun_Dev::TextRun_Dev() {
+ pp_text_run_.text = text_.pp_var();
+ pp_text_run_.rtl = false;
+ pp_text_run_.override_direction = false;
+}
+
+TextRun_Dev::TextRun_Dev(const std::string& text,
+ bool rtl,
+ bool override_direction)
+ : text_(text) {
+ pp_text_run_.text = text_.pp_var();
+ pp_text_run_.rtl = rtl;
+ pp_text_run_.override_direction = override_direction;
+}
+
+TextRun_Dev::TextRun_Dev(const TextRun_Dev& other) : text_(other.text_) {
+ pp_text_run_.text = text_.pp_var();
+ pp_text_run_.rtl = other.pp_text_run_.rtl;
+ pp_text_run_.override_direction = other.pp_text_run_.override_direction;
+}
+
+TextRun_Dev::~TextRun_Dev() {
+}
+
+TextRun_Dev& TextRun_Dev::operator=(const TextRun_Dev& other) {
+ TextRun_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void TextRun_Dev::swap(TextRun_Dev& other) {
+ std::swap(text_, other.text_);
+
+ // Fix up both object's pp_text_run.text to point to their text_ member.
+ pp_text_run_.text = text_.pp_var();
+ other.pp_text_run_.text = other.text_.pp_var();
+
+ std::swap(pp_text_run_.rtl, other.pp_text_run_.rtl);
+ std::swap(pp_text_run_.override_direction,
+ other.pp_text_run_.override_direction);
+}
+
+// Font ------------------------------------------------------------------------
+
+Font_Dev::Font_Dev(PP_Resource resource) : Resource(resource) {
+}
+
+Font_Dev::Font_Dev(const FontDescription_Dev& description) {
+ if (!font_f)
+ return;
+ PassRefFromConstructor(font_f->Create(
+ Module::Get()->pp_module(), &description.pp_font_description()));
+}
+
+Font_Dev::Font_Dev(const Font_Dev& other) : Resource(other) {
+}
+
+Font_Dev& Font_Dev::operator=(const Font_Dev& other) {
+ Font_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Font_Dev::swap(Font_Dev& other) {
+ Resource::swap(other);
+}
+
+bool Font_Dev::Describe(FontDescription_Dev* description,
+ PP_FontMetrics_Dev* metrics) const {
+ if (!font_f)
+ return false;
+
+ // Be careful with ownership of the |face| string. It will come back with
+ // a ref of 1, which we want to assign to the |face_| member of the C++ class.
+ if (!font_f->Describe(pp_resource(), &description->pp_font_description_,
+ metrics))
+ return false;
+ description->face_ = Var(Var::PassRef(),
+ description->pp_font_description_.face);
+
+ return true;
+}
+
+bool Font_Dev::DrawTextAt(ImageData* dest,
+ const TextRun_Dev& text,
+ const Point& position,
+ uint32_t color,
+ const Rect& clip,
+ bool image_data_is_opaque) const {
+ if (!font_f)
+ return false;
+ return font_f->DrawTextAt(pp_resource(), dest->pp_resource(),
+ &text.pp_text_run(), &position.pp_point(),
+ color, &clip.pp_rect(), image_data_is_opaque);
+}
+
+int32_t Font_Dev::MeasureText(const TextRun_Dev& text) const {
+ if (!font_f)
+ return -1;
+ return font_f->MeasureText(pp_resource(), &text.pp_text_run());
+}
+
+uint32_t Font_Dev::CharacterOffsetForPixel(const TextRun_Dev& text,
+ int32_t pixel_position) const {
+ if (!font_f)
+ return 0;
+ return font_f->CharacterOffsetForPixel(pp_resource(), &text.pp_text_run(),
+ pixel_position);
+
+}
+
+int32_t Font_Dev::PixelOffsetForCharacter(const TextRun_Dev& text,
+ uint32_t char_offset) const {
+ if (!font_f)
+ return 0;
+ return font_f->PixelOffsetForCharacter(pp_resource(), &text.pp_text_run(),
+ char_offset);
+}
+
+bool Font_Dev::DrawSimpleText(ImageData* dest,
+ const std::string& text,
+ const Point& position,
+ uint32_t color,
+ bool image_data_is_opaque) const {
+ return DrawTextAt(dest, TextRun_Dev(text), position, color,
+ Rect(dest->size()), image_data_is_opaque);
+}
+
+int32_t Font_Dev::MeasureSimpleText(const std::string& text) const {
+ return MeasureText(TextRun_Dev(text));
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/font_dev.h b/ppapi/cpp/dev/font_dev.h
new file mode 100644
index 0000000..bac8bb9
--- /dev/null
+++ b/ppapi/cpp/dev/font_dev.h
@@ -0,0 +1,139 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_FONT_DEV_H_
+#define PPAPI_CPP_DEV_FONT_DEV_H_
+
+#include <string>
+
+#include "ppapi/c/dev/ppb_font_dev.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+struct PP_FontDescription_Dev;
+
+namespace pp {
+
+class Font_dev;
+class ImageData;
+class Instance;
+class Point;
+class Rect;
+
+// FontDescription_Dev ---------------------------------------------------------
+
+class FontDescription_Dev {
+ public:
+ FontDescription_Dev();
+ FontDescription_Dev(const FontDescription_Dev& other);
+ ~FontDescription_Dev();
+
+ const PP_FontDescription_Dev& pp_font_description() const {
+ return pp_font_description_;
+ }
+
+ FontDescription_Dev& operator=(const FontDescription_Dev& other);
+ void swap(FontDescription_Dev& other);
+
+ Var face() const { return face_; }
+ void set_face(const Var& face) {
+ face_ = face;
+ pp_font_description_.face = face_.pp_var();
+ }
+
+ PP_FontFamily_Dev family() const { return pp_font_description_.family; }
+ void set_family(PP_FontFamily_Dev f) { pp_font_description_.family = f; }
+
+ uint32_t size() const { return pp_font_description_.size; }
+ void set_size(uint32_t s) { pp_font_description_.size = s; }
+
+ PP_FontWeight_Dev weight() const { return pp_font_description_.weight; }
+ void set_weight(PP_FontWeight_Dev w) { pp_font_description_.weight = w; }
+
+ bool italic() const { return pp_font_description_.italic; }
+ void set_italic(bool i) { pp_font_description_.italic = i; }
+
+ bool small_caps() const { return pp_font_description_.small_caps; }
+ void set_small_caps(bool s) { pp_font_description_.small_caps = s; }
+
+ int letter_spacing() const { return pp_font_description_.letter_spacing; }
+ void set_letter_spacing(int s) { pp_font_description_.letter_spacing = s; }
+
+ int word_spacing() const { return pp_font_description_.word_spacing; }
+ void set_word_spacing(int w) { pp_font_description_.word_spacing = w; }
+
+ private:
+ friend class Font_Dev;
+
+ Var face_; // Manages memory for pp_font_description_.face
+ PP_FontDescription_Dev pp_font_description_;
+};
+
+// TextRun_Dev ---------------------------------------------------------------------
+
+class TextRun_Dev {
+ public:
+ TextRun_Dev();
+ TextRun_Dev(const std::string& text,
+ bool rtl = false,
+ bool override_direction = false);
+ TextRun_Dev(const TextRun_Dev& other);
+ ~TextRun_Dev();
+
+ TextRun_Dev& operator=(const TextRun_Dev& other);
+ void swap(TextRun_Dev& other);
+
+ const PP_TextRun_Dev& pp_text_run() const {
+ return pp_text_run_;
+ }
+
+ private:
+ Var text_; // Manages memory for the reference in pp_text_run_.
+ PP_TextRun_Dev pp_text_run_;
+};
+
+// Font ------------------------------------------------------------------------
+
+// Provides access to system fonts.
+class Font_Dev : public Resource {
+ public:
+ // Creates an is_null() Font object.
+ Font_Dev() {}
+
+ explicit Font_Dev(PP_Resource resource);
+ explicit Font_Dev(const FontDescription_Dev& description);
+ Font_Dev(const Font_Dev& other);
+
+ Font_Dev& operator=(const Font_Dev& other);
+ void swap(Font_Dev& other);
+
+ // PPB_Font methods:
+ bool Describe(FontDescription_Dev* description,
+ PP_FontMetrics_Dev* metrics) const;
+ bool DrawTextAt(ImageData* dest,
+ const TextRun_Dev& text,
+ const Point& position,
+ uint32_t color,
+ const Rect& clip,
+ bool image_data_is_opaque) const;
+ int32_t MeasureText(const TextRun_Dev& text) const;
+ uint32_t CharacterOffsetForPixel(const TextRun_Dev& text,
+ int32_t pixel_position) const;
+ int32_t PixelOffsetForCharacter(const TextRun_Dev& text,
+ uint32_t char_offset) const;
+
+ // Convenience function that assumes a left-to-right string with no clipping.
+ bool DrawSimpleText(ImageData* dest,
+ const std::string& text,
+ const Point& position,
+ uint32_t color,
+ bool image_data_is_opaque = false) const;
+
+ // Convenience function that assumes a left-to-right string.
+ int32_t MeasureSimpleText(const std::string& text) const;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FONT_DEV_H_
diff --git a/ppapi/cpp/dev/fullscreen_dev.cc b/ppapi/cpp/dev/fullscreen_dev.cc
new file mode 100644
index 0000000..fd04ec9
--- /dev/null
+++ b/ppapi/cpp/dev/fullscreen_dev.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/fullscreen_dev.h"
+
+#include "ppapi/c/dev/ppb_fullscreen_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+DeviceFuncs<PPB_Fullscreen_Dev> ppb_fullscreen_f(PPB_FULLSCREEN_DEV_INTERFACE);
+
+} // anonymous namespace
+
+Fullscreen_Dev::Fullscreen_Dev(Instance* instance)
+ : associated_instance_(instance) {
+}
+
+Fullscreen_Dev::~Fullscreen_Dev() {
+}
+
+bool Fullscreen_Dev::IsFullscreen() {
+ return ppb_fullscreen_f && ppb_fullscreen_f->IsFullscreen(
+ associated_instance_->pp_instance());
+}
+
+bool Fullscreen_Dev::SetFullscreen(bool fullscreen) {
+ if (!ppb_fullscreen_f)
+ return false;
+ return ppb_fullscreen_f->SetFullscreen(associated_instance_->pp_instance(),
+ fullscreen);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/fullscreen_dev.h b/ppapi/cpp/dev/fullscreen_dev.h
new file mode 100644
index 0000000..1050faf
--- /dev/null
+++ b/ppapi/cpp/dev/fullscreen_dev.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_FULLSCREEN_DEV_H_
+#define PPAPI_CPP_DEV_FULLSCREEN_DEV_H_
+
+#include <string>
+
+#include "ppapi/c/dev/ppb_fullscreen_dev.h"
+
+namespace pp {
+
+class Instance;
+
+class Fullscreen_Dev {
+ public:
+ Fullscreen_Dev(Instance* instance);
+ virtual ~Fullscreen_Dev();
+
+ // PPB_Fullscreen_Dev methods.
+ bool IsFullscreen();
+ bool SetFullscreen(bool fullscreen);
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FULLSCREEN_DEV_H_
diff --git a/ppapi/cpp/dev/graphics_3d_client_dev.cc b/ppapi/cpp/dev/graphics_3d_client_dev.cc
new file mode 100644
index 0000000..bdd2e7e
--- /dev/null
+++ b/ppapi/cpp/dev/graphics_3d_client_dev.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/graphics_3d_client_dev.h"
+
+#include "ppapi/c/dev/ppp_graphics_3d_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+const char kPPPGraphics3DInterface[] = PPP_GRAPHICS_3D_DEV_INTERFACE;
+
+void Graphics3D_ContextLost(PP_Instance instance) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPGraphics3DInterface);
+ if (!object)
+ return;
+ return static_cast<Graphics3DClient_Dev*>(object)->Graphics3DContextLost();
+}
+
+static PPP_Graphics3D_Dev graphics3d_interface = {
+ &Graphics3D_ContextLost,
+};
+
+} // namespace
+
+Graphics3DClient_Dev::Graphics3DClient_Dev(Instance* instance)
+ : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPGraphics3DInterface,
+ &graphics3d_interface);
+ associated_instance_->AddPerInstanceObject(kPPPGraphics3DInterface, this);
+}
+
+Graphics3DClient_Dev::~Graphics3DClient_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPGraphics3DInterface, this);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/graphics_3d_client_dev.h b/ppapi/cpp/dev/graphics_3d_client_dev.h
new file mode 100644
index 0000000..5f68fb2
--- /dev/null
+++ b/ppapi/cpp/dev/graphics_3d_client_dev.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_GRAPHICS_3D_CLIENT_DEV_H_
+#define PPAPI_CPP_DEV_GRAPHICS_3D_CLIENT_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+
+namespace pp {
+
+class Instance;
+class Rect;
+class Scrollbar_Dev;
+class Widget_Dev;
+
+// This class provides a C++ interface for callbacks related to 3D. You
+// would normally use multiple inheritance to derive from this class in your
+// instance.
+class Graphics3DClient_Dev {
+ public:
+ Graphics3DClient_Dev(Instance* instance);
+ virtual ~Graphics3DClient_Dev();
+
+ /**
+ * Notification that the context was lost for the 3D devices.
+ */
+ virtual void Graphics3DContextLost() = 0;
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_GRAPHICS_3D_CLIENT_DEV_H_
diff --git a/ppapi/cpp/dev/graphics_3d_dev.cc b/ppapi/cpp/dev/graphics_3d_dev.cc
new file mode 100644
index 0000000..766b70c
--- /dev/null
+++ b/ppapi/cpp/dev/graphics_3d_dev.cc
@@ -0,0 +1,117 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/graphics_3d_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+extern "C" {
+const PPB_OpenGLES_Dev* pepper_opengl_interface = NULL;
+}
+
+namespace {
+
+DeviceFuncs<PPB_Graphics3D_Dev> graphics_3d_f(PPB_GRAPHICS_3D_DEV_INTERFACE);
+DeviceFuncs<PPB_OpenGLES_Dev> opengles_f(PPB_OPENGLES_DEV_INTERFACE);
+
+inline void InitializeOpenGLCInterface() {
+ if (!pepper_opengl_interface)
+ pepper_opengl_interface = &(*opengles_f);
+}
+
+} // namespace
+
+namespace pp {
+
+// static
+bool Graphics3D_Dev::GetConfigs(int32_t *configs, int32_t config_size,
+ int32_t *num_config) {
+ if (graphics_3d_f)
+ return graphics_3d_f->GetConfigs(configs, config_size, num_config);
+ return false;
+}
+
+// static
+bool Graphics3D_Dev::ChooseConfig(const int32_t *attrib_list, int32_t *configs,
+ int32_t config_size, int32_t *num_config) {
+ if (graphics_3d_f)
+ return graphics_3d_f->ChooseConfig(attrib_list, configs, config_size,
+ num_config);
+ return false;
+}
+
+// static
+bool Graphics3D_Dev::GetConfigAttrib(int32_t config, int32_t attribute,
+ int32_t *value) {
+ if (graphics_3d_f)
+ return graphics_3d_f->GetConfigAttrib(config, attribute, value);
+ return false;
+}
+
+// static
+const char* Graphics3D_Dev::QueryString(int32_t name) {
+ if (graphics_3d_f)
+ return graphics_3d_f->QueryString(name);
+ return NULL;
+}
+
+// static
+void* Graphics3D_Dev::GetProcAddress(const char* name) {
+ if (graphics_3d_f)
+ return graphics_3d_f->GetProcAddress(name);
+ return NULL;
+}
+
+Graphics3D_Dev Graphics3D_Dev::FromResource(PP_Resource resource_id) {
+ if (graphics_3d_f && graphics_3d_f->IsGraphics3D(resource_id))
+ return Graphics3D_Dev(resource_id);
+ return Graphics3D_Dev();
+}
+
+bool Graphics3D_Dev::ResetCurrent() {
+ return graphics_3d_f && graphics_3d_f->MakeCurent(0);
+}
+
+Graphics3D_Dev Graphics3D_Dev::GetCurrentContext() {
+ if (graphics_3d_f)
+ return FromResource(graphics_3d_f->GetCurrentContext());
+ return Graphics3D_Dev();
+}
+
+uint32_t Graphics3D_Dev::GetError() {
+ if (graphics_3d_f)
+ return graphics_3d_f->GetError();
+ return PP_GRAPHICS_3D_ERROR_NOT_INITIALIZED;
+}
+
+const PPB_OpenGLES_Dev* Graphics3D_Dev::GetImplementation() {
+ return &(*opengles_f);
+}
+
+Graphics3D_Dev::Graphics3D_Dev(const Instance& instance,
+ int32_t config,
+ int32_t share_context,
+ const int32_t* attrib_list) {
+ if (graphics_3d_f && opengles_f) {
+ InitializeOpenGLCInterface();
+ PassRefFromConstructor(graphics_3d_f->CreateContext(instance.pp_instance(),
+ config, share_context,
+ attrib_list));
+ }
+}
+
+bool Graphics3D_Dev::MakeCurrent() const {
+ InitializeOpenGLCInterface();
+ return graphics_3d_f && graphics_3d_f->MakeCurent(pp_resource());
+}
+
+bool Graphics3D_Dev::SwapBuffers() const {
+ return graphics_3d_f && graphics_3d_f->SwapBuffers(pp_resource());
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/graphics_3d_dev.h b/ppapi/cpp/dev/graphics_3d_dev.h
new file mode 100644
index 0000000..88fe47d
--- /dev/null
+++ b/ppapi/cpp/dev/graphics_3d_dev.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_GRAPHICS_3D_DEV_H_
+#define PPAPI_CPP_DEV_GRAPHICS_3D_DEV_H_
+
+#include "ppapi/c/dev/ppb_graphics_3d_dev.h"
+#include "ppapi/c/dev/ppb_opengles_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Graphics3D_Dev : public Resource {
+ public:
+ static bool GetConfigs(int32_t* configs, int32_t config_size,
+ int32_t* num_config);
+
+ static bool ChooseConfig(const int32_t* attrib_list, int32_t* configs,
+ int32_t config_size, int32_t* num_config);
+
+ static bool GetConfigAttrib(int32_t config, int32_t attribute,
+ int32_t* value);
+
+ static const char* QueryString(int32_t name);
+
+ static void* GetProcAddress(const char* name);
+
+ static bool ResetCurrent();
+ static Graphics3D_Dev GetCurrentContext();
+ static uint32_t GetError();
+ static const PPB_OpenGLES_Dev* GetImplementation();
+
+ // Creates an is_null() Graphics3D object.
+ Graphics3D_Dev() {}
+
+ Graphics3D_Dev(const Instance& instance,
+ int32_t config,
+ int32_t share_context,
+ const int32_t* attrib_list);
+
+ bool MakeCurrent() const;
+ bool SwapBuffers() const;
+
+ protected:
+ explicit Graphics3D_Dev(PP_Resource resource_id) : Resource(resource_id) {}
+ static Graphics3D_Dev FromResource(PP_Resource resource_id);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_GRAPHICS_3D_DEV_H_
+
diff --git a/ppapi/cpp/dev/printing_dev.cc b/ppapi/cpp/dev/printing_dev.cc
new file mode 100644
index 0000000..a5aa361
--- /dev/null
+++ b/ppapi/cpp/dev/printing_dev.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/printing_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+static const char kPPPPrintingInterface[] = PPP_PRINTING_DEV_INTERFACE;
+
+PP_PrintOutputFormat_Dev* QuerySupportedFormats(PP_Instance instance,
+ uint32_t* format_count) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPrintingInterface);
+ if (!object)
+ return NULL;
+ return static_cast<Printing_Dev*>(object)->QuerySupportedPrintOutputFormats(
+ format_count);
+}
+
+int32_t Begin(PP_Instance instance,
+ const struct PP_PrintSettings_Dev* print_settings) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPrintingInterface);
+ if (!object)
+ return 0;
+ return static_cast<Printing_Dev*>(object)->PrintBegin(*print_settings);
+}
+
+PP_Resource PrintPages(PP_Instance instance,
+ const struct PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPrintingInterface);
+ if (!object)
+ return 0;
+ return static_cast<Printing_Dev*>(object)->PrintPages(
+ page_ranges, page_range_count).detach();
+}
+
+void End(PP_Instance instance) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPrintingInterface);
+ if (object)
+ static_cast<Printing_Dev*>(object)->PrintEnd();
+}
+
+const PPP_Printing_Dev ppp_printing = {
+ &QuerySupportedFormats,
+ &Begin,
+ &PrintPages,
+ &End
+};
+
+} // namespace
+
+Printing_Dev::Printing_Dev(Instance* instance)
+ : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPPrintingInterface, &ppp_printing);
+ associated_instance_->AddPerInstanceObject(kPPPPrintingInterface, this);
+}
+
+Printing_Dev::~Printing_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPPrintingInterface, this);
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/printing_dev.h b/ppapi/cpp/dev/printing_dev.h
new file mode 100644
index 0000000..ca34ba3
--- /dev/null
+++ b/ppapi/cpp/dev/printing_dev.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_PRINTING_DEV_H_
+#define PPAPI_CPP_DEV_PRINTING_DEV_H_
+
+#include "ppapi/c/dev/ppp_printing_dev.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Instance;
+
+// You would typically use this either via inheritance on your instance or
+// by composition: see find_dev.h for an example.
+class Printing_Dev {
+ public:
+ // The instance parameter must outlive this class.
+ explicit Printing_Dev(Instance* instance);
+ virtual ~Printing_Dev();
+
+ // PPP_Printing_Dev functions exposed as virtual functions for you to
+ // override.
+ virtual PP_PrintOutputFormat_Dev* QuerySupportedPrintOutputFormats(
+ uint32_t* format_count) = 0;
+ virtual int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) = 0;
+ virtual Resource PrintPages(const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count) = 0;
+ virtual void PrintEnd() = 0;
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_PRINTING_DEV_H_
diff --git a/ppapi/cpp/dev/scriptable_object_deprecated.cc b/ppapi/cpp/dev/scriptable_object_deprecated.cc
new file mode 100644
index 0000000..59f44d1
--- /dev/null
+++ b/ppapi/cpp/dev/scriptable_object_deprecated.cc
@@ -0,0 +1,188 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
+
+#include "ppapi/c/dev/ppp_class_deprecated.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+namespace deprecated {
+
+namespace {
+
+// Allows converting an output param of a Var to an output param of a PP_Var
+// for exceptions. The object is only copied if it is not void, which we
+// take to mean an exception occurred.
+class ExceptionConverter {
+ public:
+ ExceptionConverter(PP_Var* out) : out_(out) {
+ }
+ ~ExceptionConverter() {
+ if (!exception_.is_undefined())
+ *out_ = exception_.Detach();
+ }
+
+ Var* Get() { return &exception_; }
+
+ private:
+ PP_Var* out_;
+ Var exception_;
+};
+
+// Used internally to convert a C-style array of PP_Var to a vector of Var.
+void ArgListToVector(uint32_t argc, PP_Var* argv, std::vector<Var>* output) {
+ output->reserve(argc);
+ for (size_t i = 0; i < argc; i++)
+ output->push_back(Var(Var::DontManage(), argv[i]));
+}
+
+bool HasProperty(void* object, PP_Var name, PP_Var* exception) {
+ ExceptionConverter e(exception);
+ return static_cast<ScriptableObject*>(object)->HasProperty(
+ Var(Var::DontManage(), name), e.Get());
+}
+
+bool HasMethod(void* object, PP_Var name, PP_Var* exception) {
+ ExceptionConverter e(exception);
+ return static_cast<ScriptableObject*>(object)->HasMethod(
+ Var(Var::DontManage(), name), e.Get());
+}
+
+PP_Var GetProperty(void* object,
+ PP_Var name,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+ return static_cast<ScriptableObject*>(object)->GetProperty(
+ Var(Var::DontManage(), name), e.Get()).Detach();
+}
+
+void GetAllPropertyNames(void* object,
+ uint32_t* property_count,
+ PP_Var** properties,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+ std::vector<Var> props;
+ static_cast<ScriptableObject*>(object)->GetAllPropertyNames(&props, e.Get());
+ if (props.empty())
+ return;
+ *property_count = static_cast<uint32_t>(props.size());
+ *properties = static_cast<PP_Var*>(
+ Module::Get()->core()->MemAlloc(sizeof(PP_Var) * props.size()));
+ for (size_t i = 0; i < props.size(); ++i)
+ (*properties)[i] = props[i].Detach();
+}
+
+void SetProperty(void* object,
+ PP_Var name,
+ PP_Var value,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+ static_cast<ScriptableObject*>(object)->SetProperty(
+ Var(Var::DontManage(), name), Var(Var::DontManage(), value), e.Get());
+}
+
+void RemoveProperty(void* object,
+ PP_Var name,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+ static_cast<ScriptableObject*>(object)->RemoveProperty(
+ Var(Var::DontManage(), name), e.Get());
+}
+
+PP_Var Call(void* object,
+ PP_Var method_name,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+
+ std::vector<Var> args;
+ ArgListToVector(argc, argv, &args);
+ return static_cast<ScriptableObject*>(object)->Call(
+ Var(Var::DontManage(), method_name), args, e.Get()).Detach();
+}
+
+PP_Var Construct(void* object,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+
+ std::vector<Var> args;
+ ArgListToVector(argc, argv, &args);
+ return static_cast<ScriptableObject*>(object)->Construct(
+ args, e.Get()).Detach();
+}
+
+void Deallocate(void* object) {
+ delete static_cast<ScriptableObject*>(object);
+}
+
+PPP_Class_Deprecated plugin_class = {
+ &HasProperty,
+ &HasMethod,
+ &GetProperty,
+ &GetAllPropertyNames,
+ &SetProperty,
+ &RemoveProperty,
+ &Call,
+ &Construct,
+ &Deallocate
+};
+
+} // namespace
+
+bool ScriptableObject::HasProperty(const Var& /*name*/, Var* /*exception*/) {
+ return false;
+}
+
+bool ScriptableObject::HasMethod(const Var& /*name*/, Var* /*exception*/) {
+ return false;
+}
+
+Var ScriptableObject::GetProperty(const Var& /*name*/, Var* exception) {
+ *exception = Var("Property does not exist on ScriptableObject");
+ return Var();
+}
+
+void ScriptableObject::GetAllPropertyNames(std::vector<Var>* /*properties*/,
+ Var* /*exception*/) {
+}
+
+void ScriptableObject::SetProperty(const Var& /*name*/,
+ const Var& /*value*/,
+ Var* exception) {
+ *exception = Var("Property can not be set on ScriptableObject");
+}
+
+void ScriptableObject::RemoveProperty(const Var& /*name*/,
+ Var* exception) {
+ *exception = Var(
+ "Property does does not exist to be removed in ScriptableObject");
+}
+
+Var ScriptableObject::Call(const Var& /*method_name*/,
+ const std::vector<Var>& /*args*/,
+ Var* exception) {
+ *exception = Var("Method does not exist to call in ScriptableObject");
+ return Var();
+}
+
+Var ScriptableObject::Construct(const std::vector<Var>& /*args*/,
+ Var* exception) {
+ *exception = Var("Constuct method does not exist in ScriptableObject");
+ return Var();
+}
+
+// static
+const PPP_Class_Deprecated* ScriptableObject::GetClass() {
+ return &plugin_class;
+}
+
+} // namespace deprecated
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/scriptable_object_deprecated.h b/ppapi/cpp/dev/scriptable_object_deprecated.h
new file mode 100644
index 0000000..42ab466
--- /dev/null
+++ b/ppapi/cpp/dev/scriptable_object_deprecated.h
@@ -0,0 +1,92 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_SCRIPTABLE_OBJECT_DEPRECATED_H_
+#define PPAPI_CPP_SCRIPTABLE_OBJECT_DEPRECATED_H_
+
+#include <vector>
+
+struct PPP_Class_Deprecated;
+
+namespace pp {
+class Var;
+}
+using pp::Var;
+
+namespace pp {
+
+namespace deprecated {
+
+// This class allows you to implement objects accessible by JavaScript. Derive
+// from this class and override the virtual functions you support. pp::Var has
+// a constructor that takes a pointer to a ScriptableObject for when you want
+// to convert your custom object to a var.
+//
+// Please see the PPB_Core C interface for more information on how to implement
+// these functions. These functions are the backend implementation for the
+// functions in PPB_Var, which contains further information.
+//
+// Please see:
+// http://code.google.com/p/ppapi/wiki/InterfacingWithJavaScript
+// for a general overview of interfacing with JavaScript.
+class ScriptableObject {
+ public:
+ ScriptableObject() {}
+ virtual ~ScriptableObject() {}
+
+ // The default implementation returns false.
+ virtual bool HasProperty(const Var& name, Var* exception);
+
+ // The default implementation returns false.
+ virtual bool HasMethod(const Var& name, Var* exception);
+
+ // The default implementation sets an exception that the property doesn't
+ // exist.
+ virtual Var GetProperty(const Var& name, Var* exception);
+
+ // The default implementation returns no properties.
+ virtual void GetAllPropertyNames(std::vector<Var>* properties,
+ Var* exception);
+
+ // The default implementation sets an exception that the property can not be
+ // set.
+ virtual void SetProperty(const Var& name,
+ const Var& value,
+ Var* exception);
+
+ // The default implementation sets an exception that the method does not
+ // exist.
+ virtual void RemoveProperty(const Var& name,
+ Var* exception);
+
+ // TODO(brettw) need native array access here.
+
+ // method_name is guaranteed to be either a string or an integer.
+ //
+ // The default implementation sets an exception that the method does not
+ // exist.
+ virtual Var Call(const Var& method_name,
+ const std::vector<Var>& args,
+ Var* exception);
+
+ // The default implementation sets an exception that the method does not
+ // exist.
+ virtual Var Construct(const std::vector<Var>& args,
+ Var* exception);
+
+ private:
+ friend class ::pp::Var;
+ static const PPP_Class_Deprecated* GetClass();
+
+ // Unimplemented, copy and assigmnent is not allowed.
+ ScriptableObject(const ScriptableObject& other);
+ ScriptableObject& operator=(const ScriptableObject& other);
+};
+
+} // namespace deprecated
+
+} // namespace pp
+
+#endif // PPAPI_CPP_SCRIPTABLE_OBJECT_DEPRECATED_H_
+
diff --git a/ppapi/cpp/dev/scrollbar_dev.cc b/ppapi/cpp/dev/scrollbar_dev.cc
new file mode 100644
index 0000000..23395ef
--- /dev/null
+++ b/ppapi/cpp/dev/scrollbar_dev.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "ppapi/cpp/dev/scrollbar_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/rect.h"
+
+namespace {
+
+DeviceFuncs<PPB_Scrollbar_Dev> scrollbar_f(PPB_SCROLLBAR_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Scrollbar_Dev::Scrollbar_Dev(PP_Resource resource) : Widget_Dev(resource) {
+}
+
+Scrollbar_Dev::Scrollbar_Dev(const Instance& instance, bool vertical) {
+ if (!scrollbar_f)
+ return;
+ PassRefFromConstructor(scrollbar_f->Create(instance.pp_instance(), vertical));
+}
+
+Scrollbar_Dev::Scrollbar_Dev(const Scrollbar_Dev& other)
+ : Widget_Dev(other) {
+}
+
+Scrollbar_Dev& Scrollbar_Dev::operator=(const Scrollbar_Dev& other) {
+ Scrollbar_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Scrollbar_Dev::swap(Scrollbar_Dev& other) {
+ Resource::swap(other);
+}
+
+uint32_t Scrollbar_Dev::GetThickness() {
+ if (!scrollbar_f)
+ return 0;
+ return scrollbar_f->GetThickness();
+}
+
+uint32_t Scrollbar_Dev::GetValue() {
+ if (!scrollbar_f)
+ return 0;
+ return scrollbar_f->GetValue(pp_resource());
+}
+
+void Scrollbar_Dev::SetValue(uint32_t value) {
+ if (scrollbar_f)
+ scrollbar_f->SetValue(pp_resource(), value);
+}
+
+void Scrollbar_Dev::SetDocumentSize(uint32_t size) {
+ if (scrollbar_f)
+ scrollbar_f->SetDocumentSize(pp_resource(), size);
+}
+
+void Scrollbar_Dev::SetTickMarks(const Rect* tick_marks, uint32_t count) {
+ if (!scrollbar_f)
+ return;
+
+ std::vector<PP_Rect> temp;
+ temp.resize(count);
+ for (uint32_t i = 0; i < count; ++i)
+ temp[i] = tick_marks[i];
+
+ scrollbar_f->SetTickMarks(pp_resource(), count ? &temp[0] : NULL, count);
+}
+
+void Scrollbar_Dev::ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier) {
+ if (scrollbar_f)
+ scrollbar_f->ScrollBy(pp_resource(), unit, multiplier);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/scrollbar_dev.h b/ppapi/cpp/dev/scrollbar_dev.h
new file mode 100644
index 0000000..0605641
--- /dev/null
+++ b/ppapi/cpp/dev/scrollbar_dev.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_SCROLLBAR_DEV_H_
+#define PPAPI_CPP_DEV_SCROLLBAR_DEV_H_
+
+#include "ppapi/c/dev/ppb_scrollbar_dev.h"
+#include "ppapi/cpp/dev/widget_dev.h"
+
+namespace pp {
+
+class Instance;
+
+// This class allows a plugin to use the browser's scrollbar widget.
+class Scrollbar_Dev : public Widget_Dev {
+ public:
+ // Creates an is_null() Scrollbar object.
+ Scrollbar_Dev() {}
+
+ explicit Scrollbar_Dev(PP_Resource resource);
+ Scrollbar_Dev(const Instance& instance, bool vertical);
+ Scrollbar_Dev(const Scrollbar_Dev& other);
+
+ Scrollbar_Dev& operator=(const Scrollbar_Dev& other);
+ void swap(Scrollbar_Dev& other);
+
+ // PPB_Scrollbar methods:
+ static uint32_t GetThickness();
+ uint32_t GetValue();
+ void SetValue(uint32_t value);
+ void SetDocumentSize(uint32_t size);
+ void SetTickMarks(const Rect* tick_marks, uint32_t count);
+ void ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_SCROLLBAR_DEV_H_
diff --git a/ppapi/cpp/dev/selection_dev.cc b/ppapi/cpp/dev/selection_dev.cc
new file mode 100644
index 0000000..6f1fcb7
--- /dev/null
+++ b/ppapi/cpp/dev/selection_dev.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/selection_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+namespace {
+
+static const char kPPPSelectionInterface[] = PPP_SELECTION_DEV_INTERFACE;
+
+PP_Var GetSelectedText(PP_Instance instance, bool html) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPSelectionInterface);
+ if (!object)
+ return Var().Detach();
+ return static_cast<Selection_Dev*>(object)->GetSelectedText(html).Detach();
+}
+
+const PPP_Selection_Dev ppp_selection = {
+ &GetSelectedText
+};
+
+} // namespace
+
+Selection_Dev::Selection_Dev(Instance* instance)
+ : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPSelectionInterface, &ppp_selection);
+ associated_instance_->AddPerInstanceObject(kPPPSelectionInterface, this);
+}
+
+Selection_Dev::~Selection_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPSelectionInterface, this);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/selection_dev.h b/ppapi/cpp/dev/selection_dev.h
new file mode 100644
index 0000000..282bdb4
--- /dev/null
+++ b/ppapi/cpp/dev/selection_dev.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_SELECTION_DEV_H_
+#define PPAPI_CPP_DEV_SELECTION_DEV_H_
+
+#include "ppapi/c/dev/ppp_selection_dev.h"
+
+namespace pp {
+
+class Instance;
+class Var;
+
+// This class allows you to associate the PPP_Selection_Dev C-based interface
+// with an object. It registers as the global handler for handling the
+// PPP_Selection_Dev interface that the browser calls.
+//
+// You would typically use this either via inheritance on your instance:
+// class MyInstance : public pp::Instance, public pp::Selection_Dev {
+// class MyInstance() : pp::Selection_Dev(this) {
+// }
+// ...
+// };
+//
+// or by composition:
+// class MySelection : public pp::Selection_Dev {
+// ...
+// };
+//
+// class MyInstance : public pp::Instance {
+// MyInstance() : selection_(this) {
+// }
+//
+// MySelection selection_;
+// };
+class Selection_Dev {
+ public:
+ Selection_Dev(Instance* instance);
+ virtual ~Selection_Dev();
+
+ // PPP_Selection_Dev functions exposed as virtual functions for you to
+ // override.
+ virtual Var GetSelectedText(bool html) = 0;
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_SELECTION_DEV_H_
diff --git a/ppapi/cpp/dev/transport_dev.cc b/ppapi/cpp/dev/transport_dev.cc
new file mode 100644
index 0000000..f7eae6b
--- /dev/null
+++ b/ppapi/cpp/dev/transport_dev.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/transport_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_Transport_Dev> transport_f(PPB_TRANSPORT_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Transport_Dev::Transport_Dev(const char* name,
+ const char* proto) {
+ if (transport_f)
+ PassRefFromConstructor(
+ transport_f->CreateTransport(Module::Get()->pp_module(), name, proto));
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/transport_dev.h b/ppapi/cpp/dev/transport_dev.h
new file mode 100644
index 0000000..a9b73c2
--- /dev/null
+++ b/ppapi/cpp/dev/transport_dev.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_TRANSPORT_DEV_H_
+#define PPAPI_CPP_DEV_TRANSPORT_DEV_H_
+
+#include "ppapi/c/dev/ppb_transport_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Transport_Dev : public Resource {
+ public:
+ Transport_Dev() {}
+ Transport_Dev(const char* name, const char* proto);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_TRANSPORT_DEV_H_
+
diff --git a/ppapi/cpp/dev/url_loader_dev.cc b/ppapi/cpp/dev/url_loader_dev.cc
new file mode 100644
index 0000000..5c63f3d
--- /dev/null
+++ b/ppapi/cpp/dev/url_loader_dev.cc
@@ -0,0 +1,115 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/url_loader_dev.h"
+
+#include "ppapi/c/dev/ppb_url_loader_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/dev/url_request_info_dev.h"
+#include "ppapi/cpp/dev/url_response_info_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_URLLoader_Dev> url_loader_f(PPB_URLLOADER_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+URLLoader_Dev::URLLoader_Dev(PP_Resource resource) : Resource(resource) {
+}
+
+URLLoader_Dev::URLLoader_Dev(const Instance& instance) {
+ if (!url_loader_f)
+ return;
+ PassRefFromConstructor(url_loader_f->Create(instance.pp_instance()));
+}
+
+URLLoader_Dev::URLLoader_Dev(const URLLoader_Dev& other)
+ : Resource(other) {
+}
+
+URLLoader_Dev& URLLoader_Dev::operator=(const URLLoader_Dev& other) {
+ URLLoader_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void URLLoader_Dev::swap(URLLoader_Dev& other) {
+ Resource::swap(other);
+}
+
+int32_t URLLoader_Dev::Open(const URLRequestInfo_Dev& request_info,
+ const CompletionCallback& cc) {
+ if (!url_loader_f)
+ return PP_ERROR_NOINTERFACE;
+ return url_loader_f->Open(pp_resource(), request_info.pp_resource(),
+ cc.pp_completion_callback());
+}
+
+int32_t URLLoader_Dev::FollowRedirect(const CompletionCallback& cc) {
+ if (!url_loader_f)
+ return PP_ERROR_NOINTERFACE;
+ return url_loader_f->FollowRedirect(pp_resource(),
+ cc.pp_completion_callback());
+}
+
+bool URLLoader_Dev::GetUploadProgress(int64_t* bytes_sent,
+ int64_t* total_bytes_to_be_sent) const {
+ if (!url_loader_f)
+ return false;
+ return url_loader_f->GetUploadProgress(
+ pp_resource(),
+ bytes_sent,
+ total_bytes_to_be_sent);
+}
+
+bool URLLoader_Dev::GetDownloadProgress(
+ int64_t* bytes_received,
+ int64_t* total_bytes_to_be_received) const {
+ if (!url_loader_f)
+ return false;
+ return url_loader_f->GetDownloadProgress(
+ pp_resource(),
+ bytes_received,
+ total_bytes_to_be_received);
+}
+
+URLResponseInfo_Dev URLLoader_Dev::GetResponseInfo() const {
+ if (!url_loader_f)
+ return URLResponseInfo_Dev();
+ return URLResponseInfo_Dev(URLResponseInfo_Dev::PassRef(),
+ url_loader_f->GetResponseInfo(pp_resource()));
+}
+
+int32_t URLLoader_Dev::ReadResponseBody(char* buffer,
+ int32_t bytes_to_read,
+ const CompletionCallback& cc) {
+ if (!url_loader_f)
+ return PP_ERROR_NOINTERFACE;
+ return url_loader_f->ReadResponseBody(pp_resource(),
+ buffer,
+ bytes_to_read,
+ cc.pp_completion_callback());
+}
+
+int32_t URLLoader_Dev::FinishStreamingToFile(const CompletionCallback& cc) {
+ if (!url_loader_f)
+ return PP_ERROR_NOINTERFACE;
+ return url_loader_f->FinishStreamingToFile(pp_resource(),
+ cc.pp_completion_callback());
+}
+
+void URLLoader_Dev::Close() {
+ if (!url_loader_f)
+ return;
+ url_loader_f->Close(pp_resource());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/url_loader_dev.h b/ppapi/cpp/dev/url_loader_dev.h
new file mode 100644
index 0000000..4256c32
--- /dev/null
+++ b/ppapi/cpp/dev/url_loader_dev.h
@@ -0,0 +1,108 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_URL_LOADER_DEV_H_
+#define PPAPI_CPP_DEV_URL_LOADER_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class CompletionCallback;
+class Instance;
+class URLRequestInfo_Dev;
+class URLResponseInfo_Dev;
+
+// URLLoader provides an API to download URLs.
+//
+// EXAMPLE USAGE:
+//
+// class MyHandler {
+// public:
+// MyHandler(const Instance& instance)
+// : factory_(this),
+// loader_(instance),
+// did_open_(false) {
+// }
+// void ProcessURL(const char* url) {
+// CompletionCallback* cc = NewCallback();
+// int32_t rv = loader_.Open(MakeRequest(url), cc);
+// if (rv != PP_Error_WouldBlock)
+// cc->Run(rv);
+// }
+// private:
+// CompletionCallback* NewCallback() {
+// return factory_.NewCallback(&MyHandler::DidCompleteIO);
+// }
+// URLRequestInfo MakeRequest(const char* url) {
+// URLRequestInfo request;
+// request.SetURL(url);
+// request.SetMethod("GET");
+// request.SetFollowRedirects(true);
+// return request;
+// }
+// void DidCompleteIO(int32_t result) {
+// if (result > 0) {
+// // buf_ now contains 'result' number of bytes from the URL.
+// ProcessBytes(buf_, result);
+// ReadMore();
+// } else if (result == PP_OK && !did_open_) {
+// // Headers are available, and we can start reading the body.
+// did_open_ = true;
+// ProcessResponseInfo(loader_.GetResponseInfo());
+// ReadMore();
+// } else {
+// // Done reading (possibly with an error given by 'result').
+// }
+// }
+// void ReadMore() {
+// CompletionCallback* cc = NewCallback();
+// int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), cc);
+// if (rv != PP_Error_WouldBlock)
+// cc->Run(rv);
+// }
+// void ProcessResponseInfo(const URLResponseInfo& response_info) {
+// // Read response headers, etc.
+// }
+// void ProcessBytes(const char* bytes, int32_t length) {
+// // Do work ...
+// }
+// pp::CompletionCallbackFactory<MyHandler> factory_;
+// pp::URLLoader loader_;
+// char buf_[4096];
+// bool did_open_;
+// };
+//
+class URLLoader_Dev : public Resource {
+ public:
+ // Creates an is_null() URLLoader object.
+ URLLoader_Dev() {}
+
+ explicit URLLoader_Dev(PP_Resource resource);
+ explicit URLLoader_Dev(const Instance& instance);
+ URLLoader_Dev(const URLLoader_Dev& other);
+
+ URLLoader_Dev& operator=(const URLLoader_Dev& other);
+ void swap(URLLoader_Dev& other);
+
+ // PPB_URLLoader methods:
+ int32_t Open(const URLRequestInfo_Dev& request_info,
+ const CompletionCallback& cc);
+ int32_t FollowRedirect(const CompletionCallback& cc);
+ bool GetUploadProgress(int64_t* bytes_sent,
+ int64_t* total_bytes_to_be_sent) const;
+ bool GetDownloadProgress(int64_t* bytes_received,
+ int64_t* total_bytes_to_be_received) const;
+ URLResponseInfo_Dev GetResponseInfo() const;
+ int32_t ReadResponseBody(char* buffer,
+ int32_t bytes_to_read,
+ const CompletionCallback& cc);
+ int32_t FinishStreamingToFile(const CompletionCallback& cc);
+ void Close();
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_URL_LOADER_DEV_H_
diff --git a/ppapi/cpp/dev/url_request_info_dev.cc b/ppapi/cpp/dev/url_request_info_dev.cc
new file mode 100644
index 0000000..faf975c5
--- /dev/null
+++ b/ppapi/cpp/dev/url_request_info_dev.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/url_request_info_dev.h"
+
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_URLRequestInfo_Dev> url_request_info_f(
+ PPB_URLREQUESTINFO_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+URLRequestInfo_Dev::URLRequestInfo_Dev() {
+ if (!url_request_info_f)
+ return;
+ PassRefFromConstructor(
+ url_request_info_f->Create(Module::Get()->pp_module()));
+}
+
+URLRequestInfo_Dev::URLRequestInfo_Dev(const URLRequestInfo_Dev& other)
+ : Resource(other) {
+}
+
+URLRequestInfo_Dev& URLRequestInfo_Dev::operator=(
+ const URLRequestInfo_Dev& other) {
+ URLRequestInfo_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void URLRequestInfo_Dev::swap(URLRequestInfo_Dev& other) {
+ Resource::swap(other);
+}
+
+bool URLRequestInfo_Dev::SetProperty(PP_URLRequestProperty_Dev property,
+ const Var& value) {
+ if (!url_request_info_f)
+ return false;
+ return url_request_info_f->SetProperty(pp_resource(),
+ property,
+ value.pp_var());
+}
+
+bool URLRequestInfo_Dev::AppendDataToBody(const char* data, uint32_t len) {
+ if (!url_request_info_f)
+ return false;
+ return url_request_info_f->AppendDataToBody(pp_resource(), data, len);
+}
+
+bool URLRequestInfo_Dev::AppendFileToBody(
+ const FileRef_Dev& file_ref,
+ PP_Time expected_last_modified_time) {
+ if (!url_request_info_f)
+ return false;
+ return url_request_info_f->AppendFileToBody(pp_resource(),
+ file_ref.pp_resource(),
+ 0,
+ -1,
+ expected_last_modified_time);
+}
+
+bool URLRequestInfo_Dev::AppendFileRangeToBody(
+ const FileRef_Dev& file_ref,
+ int64_t start_offset,
+ int64_t length,
+ PP_Time expected_last_modified_time) {
+ return url_request_info_f->AppendFileToBody(pp_resource(),
+ file_ref.pp_resource(),
+ start_offset,
+ length,
+ expected_last_modified_time);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/url_request_info_dev.h b/ppapi/cpp/dev/url_request_info_dev.h
new file mode 100644
index 0000000..1d56543
--- /dev/null
+++ b/ppapi/cpp/dev/url_request_info_dev.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_URL_REQUEST_INFO_DEV_H_
+#define PPAPI_CPP_DEV_URL_REQUEST_INFO_DEV_H_
+
+#include "ppapi/c/dev/ppb_url_request_info_dev.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+class FileRef_Dev;
+
+class URLRequestInfo_Dev : public Resource {
+ public:
+ URLRequestInfo_Dev();
+ URLRequestInfo_Dev(const URLRequestInfo_Dev& other);
+
+ URLRequestInfo_Dev& operator=(const URLRequestInfo_Dev& other);
+ void swap(URLRequestInfo_Dev& other);
+
+ // PPB_URLRequestInfo_Dev methods:
+ bool SetProperty(PP_URLRequestProperty_Dev property, const Var& value);
+ bool AppendDataToBody(const char* data, uint32_t len);
+ bool AppendFileToBody(const FileRef_Dev& file_ref,
+ PP_Time expected_last_modified_time = 0);
+ bool AppendFileRangeToBody(const FileRef_Dev& file_ref,
+ int64_t start_offset,
+ int64_t length,
+ PP_Time expected_last_modified_time = 0);
+
+ // Convenient helpers for setting properties:
+ bool SetURL(const Var& url_string) {
+ return SetProperty(PP_URLREQUESTPROPERTY_URL, url_string);
+ }
+ bool SetMethod(const Var& method_string) {
+ return SetProperty(PP_URLREQUESTPROPERTY_METHOD, method_string);
+ }
+ bool SetHeaders(const Var& headers_string) {
+ return SetProperty(PP_URLREQUESTPROPERTY_HEADERS, headers_string);
+ }
+ bool SetStreamToFile(bool enable) {
+ return SetProperty(PP_URLREQUESTPROPERTY_STREAMTOFILE, enable);
+ }
+ bool SetFollowRedirects(bool enable) {
+ return SetProperty(PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS, enable);
+ }
+ bool SetRecordUploadProgress(bool enable) {
+ return SetProperty(PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS, enable);
+ }
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_URL_REQUEST_INFO_DEV_H_
diff --git a/ppapi/cpp/dev/url_response_info_dev.cc b/ppapi/cpp/dev/url_response_info_dev.cc
new file mode 100644
index 0000000..abeca7f
--- /dev/null
+++ b/ppapi/cpp/dev/url_response_info_dev.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/url_response_info_dev.h"
+
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_URLResponseInfo_Dev> url_response_info_f(
+ PPB_URLRESPONSEINFO_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+URLResponseInfo_Dev::URLResponseInfo_Dev(const URLResponseInfo_Dev& other)
+ : Resource(other) {
+}
+
+URLResponseInfo_Dev::URLResponseInfo_Dev(PassRef, PP_Resource resource) {
+ PassRefFromConstructor(resource);
+}
+
+URLResponseInfo_Dev& URLResponseInfo_Dev::operator=(
+ const URLResponseInfo_Dev& other) {
+ URLResponseInfo_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void URLResponseInfo_Dev::swap(URLResponseInfo_Dev& other) {
+ Resource::swap(other);
+}
+
+Var URLResponseInfo_Dev::GetProperty(
+ PP_URLResponseProperty_Dev property) const {
+ if (!url_response_info_f)
+ return Var();
+ return Var(Var::PassRef(),
+ url_response_info_f->GetProperty(pp_resource(), property));
+}
+
+FileRef_Dev URLResponseInfo_Dev::GetBody() const {
+ if (!url_response_info_f)
+ return FileRef_Dev();
+ return FileRef_Dev(FileRef_Dev::PassRef(),
+ url_response_info_f->GetBody(pp_resource()));
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/url_response_info_dev.h b/ppapi/cpp/dev/url_response_info_dev.h
new file mode 100644
index 0000000..6596c8b
--- /dev/null
+++ b/ppapi/cpp/dev/url_response_info_dev.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_URL_RESPONSE_INFO_DEV_H_
+#define PPAPI_CPP_DEV_URL_RESPONSE_INFO_DEV_H_
+
+#include "ppapi/c/dev/ppb_url_response_info_dev.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+class FileRef_Dev;
+
+class URLResponseInfo_Dev : public Resource {
+ public:
+ // Creates an is_null() URLResponseInfo object.
+ URLResponseInfo_Dev() {}
+
+ // This constructor is used when we've gotten a PP_Resource as a return value
+ // that has already been addref'ed for us.
+ struct PassRef {};
+ URLResponseInfo_Dev(PassRef, PP_Resource resource);
+
+ URLResponseInfo_Dev(const URLResponseInfo_Dev& other);
+
+ URLResponseInfo_Dev& operator=(const URLResponseInfo_Dev& other);
+ void swap(URLResponseInfo_Dev& other);
+
+ // PPB_URLResponseInfo methods:
+ Var GetProperty(PP_URLResponseProperty_Dev property) const;
+ FileRef_Dev GetBody() const;
+
+ // Convenient helpers for getting properties:
+ Var GetURL() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_URL);
+ }
+ Var GetRedirectURL() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_REDIRECTURL);
+ }
+ Var GetRedirectMethod() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_REDIRECTMETHOD);
+ }
+ int32_t GetStatusCode() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_STATUSCODE).AsInt();
+ }
+ Var GetStatusLine() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_STATUSLINE);
+ }
+ Var GetHeaders() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_HEADERS);
+ }
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_URL_RESPONSE_INFO_DEV_H_
diff --git a/ppapi/cpp/dev/url_util_dev.cc b/ppapi/cpp/dev/url_util_dev.cc
new file mode 100644
index 0000000..82e1974
--- /dev/null
+++ b/ppapi/cpp/dev/url_util_dev.cc
@@ -0,0 +1,70 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/url_util_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+
+namespace pp {
+
+// static
+const UrlUtil_Dev* UrlUtil_Dev::Get() {
+ static bool tried_to_init = false;
+ static UrlUtil_Dev util;
+
+ if (!tried_to_init) {
+ tried_to_init = true;
+ util.interface_ = static_cast<const PPB_UrlUtil_Dev*>(
+ Module::Get()->GetBrowserInterface(PPB_URLUTIL_DEV_INTERFACE));
+ }
+
+ if (!util.interface_)
+ return NULL;
+ return &util;
+}
+
+Var UrlUtil_Dev::Canonicalize(const Var& url,
+ PP_UrlComponents_Dev* components) const {
+ return Var(Var::PassRef(),
+ interface_->Canonicalize(url.pp_var(), components));
+}
+
+Var UrlUtil_Dev::ResolveRelativeToUrl(const Var& base_url,
+ const Var& relative_string,
+ PP_UrlComponents_Dev* components) const {
+ return Var(Var::PassRef(),
+ interface_->ResolveRelativeToUrl(base_url.pp_var(),
+ relative_string.pp_var(),
+ components));
+}
+
+Var UrlUtil_Dev::ResoveRelativeToDocument(
+ const Instance& instance,
+ const Var& relative_string,
+ PP_UrlComponents_Dev* components) const {
+ return Var(Var::PassRef(),
+ interface_->ResolveRelativeToDocument(instance.pp_instance(),
+ relative_string.pp_var(),
+ components));
+}
+
+bool UrlUtil_Dev::IsSameSecurityOrigin(const Var& url_a,
+ const Var& url_b) const {
+ return interface_->IsSameSecurityOrigin(url_a.pp_var(), url_b.pp_var());
+}
+
+bool UrlUtil_Dev::DocumentCanRequest(const Instance& instance,
+ const Var& url) const {
+ return interface_->DocumentCanRequest(instance.pp_instance(), url.pp_var());
+}
+
+bool UrlUtil_Dev::DocumentCanAccessDocument(const Instance& active,
+ const Instance& target) const {
+ return interface_->DocumentCanAccessDocument(active.pp_instance(),
+ target.pp_instance());
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/url_util_dev.h b/ppapi/cpp/dev/url_util_dev.h
new file mode 100644
index 0000000..3be217e
--- /dev/null
+++ b/ppapi/cpp/dev/url_util_dev.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_URL_UTIL_DEV_H_
+#define PPAPI_CPP_DEV_URL_UTIL_DEV_H_
+
+#include "ppapi/c/dev/ppb_url_util_dev.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+class Instance;
+class Module;
+
+// Simple wrapper around the PPB_UrlUtil interface.
+class UrlUtil_Dev {
+ public:
+ // This class is just a collection of random functions that aren't
+ // particularly attached to anything. So this getter returns a cached
+ // instance of this interface. This may return NULL if the browser doesn't
+ // support the UrlUtil inteface. Since this is a singleton, don't delete the
+ // pointer.
+ static const UrlUtil_Dev* Get();
+
+ Var Canonicalize(const Var& url,
+ PP_UrlComponents_Dev* components = NULL) const;
+
+ Var ResolveRelativeToUrl(const Var& base_url,
+ const Var& relative_string,
+ PP_UrlComponents_Dev* components = NULL) const;
+ Var ResoveRelativeToDocument(const Instance& instance,
+ const Var& relative_string,
+ PP_UrlComponents_Dev* components = NULL) const;
+
+ bool IsSameSecurityOrigin(const Var& url_a, const Var& url_b) const;
+ bool DocumentCanRequest(const Instance& instance, const Var& url) const;
+ bool DocumentCanAccessDocument(const Instance& active,
+ const Instance& target) const;
+
+ private:
+ UrlUtil_Dev() : interface_(NULL) {}
+
+ // Copy and assignment are disallowed.
+ UrlUtil_Dev(const UrlUtil_Dev& other);
+ UrlUtil_Dev& operator=(const UrlUtil_Dev& other);
+
+ const PPB_UrlUtil_Dev* interface_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_URL_UTIL_DEV_H_
+
diff --git a/ppapi/cpp/dev/video_decoder_dev.cc b/ppapi/cpp/dev/video_decoder_dev.cc
new file mode 100644
index 0000000..298bad4
--- /dev/null
+++ b/ppapi/cpp/dev/video_decoder_dev.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/video_decoder_dev.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_VideoDecoder_Dev> video_decoder_f(
+ PPB_VIDEODECODER_DEV_INTERFACE);
+
+} // namespace
+
+
+namespace pp {
+
+VideoDecoder_Dev::VideoDecoder_Dev(PP_Resource resource) : Resource(resource) {
+}
+
+VideoDecoder_Dev::VideoDecoder_Dev(
+ const Instance& instance,
+ const PP_VideoDecoderConfig_Dev& decoder_config) {
+ if (!video_decoder_f)
+ return;
+ PassRefFromConstructor(video_decoder_f->Create(instance.pp_instance(),
+ &decoder_config));
+}
+
+VideoDecoder_Dev::VideoDecoder_Dev(const VideoDecoder_Dev& other)
+ : Resource(other) {
+}
+
+VideoDecoder_Dev& VideoDecoder_Dev::operator=(const VideoDecoder_Dev& other) {
+ VideoDecoder_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void VideoDecoder_Dev::swap(VideoDecoder_Dev& other) {
+ Resource::swap(other);
+}
+
+// static
+bool VideoDecoder_Dev::GetConfig(const Instance& instance,
+ PP_VideoCodecId_Dev codec,
+ PP_VideoConfig_Dev* configs,
+ int32_t config_size,
+ int32_t* num_config) {
+ if (!video_decoder_f)
+ return false;
+ return video_decoder_f->GetConfig(instance.pp_instance(),
+ codec,
+ configs,
+ config_size,
+ num_config);
+}
+
+bool VideoDecoder_Dev::Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer) {
+ if (!video_decoder_f || !pp_resource())
+ return false;
+ return video_decoder_f->Decode(pp_resource(),
+ &input_buffer);
+}
+
+int32_t VideoDecoder_Dev::Flush(PP_CompletionCallback callback) {
+ if (!video_decoder_f)
+ return PP_ERROR_NOINTERFACE;
+ return video_decoder_f->Flush(pp_resource(), callback);
+}
+
+bool VideoDecoder_Dev::ReturnUncompressedDataBuffer(
+ PP_VideoUncompressedDataBuffer_Dev& buffer) {
+ if (!video_decoder_f || !pp_resource())
+ return false;
+ return video_decoder_f->ReturnUncompressedDataBuffer(pp_resource(),
+ &buffer);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/video_decoder_dev.h b/ppapi/cpp/dev/video_decoder_dev.h
new file mode 100644
index 0000000..0ee6fc96
--- /dev/null
+++ b/ppapi/cpp/dev/video_decoder_dev.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_VIDEO_DECODER_DEV_H_
+#define PPAPI_CPP_DEV_VIDEO_DECODER_DEV_H_
+
+#include "ppapi/c/dev/pp_video_dev.h"
+#include "ppapi/c/dev/ppb_video_decoder_dev.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Instance;
+
+// Provides access to video decoders.
+class VideoDecoder_Dev : public Resource {
+ public:
+ // Creates an is_null() VideoDecoder object.
+ VideoDecoder_Dev() {}
+
+ explicit VideoDecoder_Dev(PP_Resource resource);
+
+ VideoDecoder_Dev(const Instance& instance,
+ const PP_VideoDecoderConfig_Dev& decoder_config);
+ VideoDecoder_Dev(const VideoDecoder_Dev& other);
+
+ VideoDecoder_Dev& operator=(const VideoDecoder_Dev& other);
+ void swap(VideoDecoder_Dev& other);
+
+ // PPB_VideoDecoder methods:
+ static bool GetConfig(const Instance& instance,
+ PP_VideoCodecId_Dev codec,
+ PP_VideoConfig_Dev* configs,
+ int32_t config_size,
+ int32_t* num_config);
+
+ bool Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer);
+
+ int32_t Flush(PP_CompletionCallback callback);
+
+ bool ReturnUncompressedDataBuffer(PP_VideoUncompressedDataBuffer_Dev& buffer);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_VIDEO_DECODER_DEV_H_
diff --git a/ppapi/cpp/dev/widget_client_dev.cc b/ppapi/cpp/dev/widget_client_dev.cc
new file mode 100644
index 0000000..8407810
--- /dev/null
+++ b/ppapi/cpp/dev/widget_client_dev.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/widget_client_dev.h"
+
+#include "ppapi/c/dev/ppp_scrollbar_dev.h"
+#include "ppapi/c/dev/ppp_widget_dev.h"
+#include "ppapi/cpp/dev/scrollbar_dev.h"
+#include "ppapi/cpp/dev/widget_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/rect.h"
+
+namespace pp {
+
+namespace {
+
+// PPP_Widget_Dev --------------------------------------------------------------
+
+const char kPPPWidgetInterface[] = PPP_WIDGET_DEV_INTERFACE;
+
+void Widget_Invalidate(PP_Instance instance,
+ PP_Resource widget_id,
+ const PP_Rect* dirty_rect) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPWidgetInterface);
+ if (!object)
+ return;
+ return static_cast<WidgetClient_Dev*>(object)->InvalidateWidget(
+ Widget_Dev(widget_id), *dirty_rect);
+}
+
+static PPP_Widget_Dev widget_interface = {
+ &Widget_Invalidate,
+};
+
+// PPP_Scrollbar_Dev -----------------------------------------------------------
+
+const char kPPPScrollbarInterface[] = PPP_SCROLLBAR_DEV_INTERFACE;
+
+void Scrollbar_ValueChanged(PP_Instance instance,
+ PP_Resource scrollbar_id,
+ uint32_t value) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPScrollbarInterface);
+ if (!object)
+ return;
+ return static_cast<WidgetClient_Dev*>(object)->ScrollbarValueChanged(
+ Scrollbar_Dev(scrollbar_id), value);
+}
+
+static PPP_Scrollbar_Dev scrollbar_interface = {
+ &Scrollbar_ValueChanged,
+};
+
+} // namespace
+
+WidgetClient_Dev::WidgetClient_Dev(Instance* instance)
+ : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPWidgetInterface, &widget_interface);
+ associated_instance_->AddPerInstanceObject(kPPPWidgetInterface, this);
+ pp::Module::Get()->AddPluginInterface(kPPPScrollbarInterface,
+ &scrollbar_interface);
+ associated_instance_->AddPerInstanceObject(kPPPScrollbarInterface, this);
+}
+
+WidgetClient_Dev::~WidgetClient_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPScrollbarInterface, this);
+ associated_instance_->RemovePerInstanceObject(kPPPWidgetInterface, this);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/widget_client_dev.h b/ppapi/cpp/dev/widget_client_dev.h
new file mode 100644
index 0000000..a8910e8
--- /dev/null
+++ b/ppapi/cpp/dev/widget_client_dev.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_WIDGET_CLIENT_DEV_H_
+#define PPAPI_CPP_DEV_WIDGET_CLIENT_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+
+namespace pp {
+
+class Instance;
+class Rect;
+class Scrollbar_Dev;
+class Widget_Dev;
+
+// This class provides a C++ interface for callbacks related to widgets. You
+// would normally use multiple inheritance to derive from this class in your
+// instance.
+class WidgetClient_Dev {
+ public:
+ WidgetClient_Dev(Instance* instance);
+ virtual ~WidgetClient_Dev();
+
+ /**
+ * Notification that the given widget should be repainted. This is the
+ * implementation for PPP_Widget_Dev.
+ */
+ virtual void InvalidateWidget(Widget_Dev widget, const Rect& dirty_rect) = 0;
+
+ /**
+ * Notification that the given scrollbar should change value. This is the
+ * implementation for PPP_Scrollbar_Dev.
+ */
+ virtual void ScrollbarValueChanged(Scrollbar_Dev scrollbar,
+ uint32_t value) = 0;
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_WIDGET_CLIENT_DEV_H_
diff --git a/ppapi/cpp/dev/widget_dev.cc b/ppapi/cpp/dev/widget_dev.cc
new file mode 100644
index 0000000..e3c94ee
--- /dev/null
+++ b/ppapi/cpp/dev/widget_dev.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/widget_dev.h"
+
+#include "ppapi/c/dev/ppb_widget_dev.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_Widget_Dev> widget_f(PPB_WIDGET_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Widget_Dev::Widget_Dev(PP_Resource resource) : Resource(resource) {
+}
+
+Widget_Dev::Widget_Dev(const Widget_Dev& other) : Resource(other) {
+}
+
+Widget_Dev& Widget_Dev::operator=(const Widget_Dev& other) {
+ Widget_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Widget_Dev::swap(Widget_Dev& other) {
+ Resource::swap(other);
+}
+
+bool Widget_Dev::Paint(const Rect& rect, ImageData* image) {
+ if (!widget_f)
+ return false;
+ return widget_f->Paint(
+ pp_resource(), &rect.pp_rect(), image->pp_resource());
+}
+
+bool Widget_Dev::HandleEvent(const PP_InputEvent& event) {
+ if (!widget_f)
+ return false;
+ return widget_f->HandleEvent(pp_resource(), &event);
+}
+
+bool Widget_Dev::GetLocation(Rect* location) {
+ if (!widget_f)
+ return false;
+ return widget_f->GetLocation(pp_resource(), &location->pp_rect());
+}
+
+void Widget_Dev::SetLocation(const Rect& location) {
+ if (widget_f)
+ widget_f->SetLocation(pp_resource(), &location.pp_rect());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/widget_dev.h b/ppapi/cpp/dev/widget_dev.h
new file mode 100644
index 0000000..59ca60d
--- /dev/null
+++ b/ppapi/cpp/dev/widget_dev.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_WIDGET_DEV_H_
+#define PPAPI_CPP_DEV_WIDGET_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+
+struct PP_InputEvent;
+
+namespace pp {
+
+class ImageData;
+class Instance;
+class Rect;
+
+// This is the base class for widget elements. As such, it can't be created
+// directly.
+class Widget_Dev : public Resource {
+ public:
+ // Creates an is_null() Widget object.
+ Widget_Dev() {}
+
+ explicit Widget_Dev(PP_Resource resource);
+ Widget_Dev(const Widget_Dev& other);
+
+ Widget_Dev& operator=(const Widget_Dev& other);
+ void swap(Widget_Dev& other);
+
+ // PPB_Widget methods:
+ bool Paint(const Rect& rect, ImageData* image);
+ bool HandleEvent(const PP_InputEvent& event);
+ bool GetLocation(Rect* location);
+ void SetLocation(const Rect& location);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_WIDGET_DEV_H_
diff --git a/ppapi/cpp/dev/zoom_dev.cc b/ppapi/cpp/dev/zoom_dev.cc
new file mode 100644
index 0000000..43966b3
--- /dev/null
+++ b/ppapi/cpp/dev/zoom_dev.cc
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/zoom_dev.h"
+
+#include "ppapi/c/dev/ppb_zoom_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+static const char kPPPZoomInterface[] = PPP_ZOOM_DEV_INTERFACE;
+
+void Zoom(PP_Instance instance,
+ double factor,
+ bool text_only) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPZoomInterface);
+ if (!object)
+ return;
+ static_cast<Zoom_Dev*>(object)->Zoom(factor, text_only);
+}
+
+const PPP_Zoom_Dev ppp_zoom = {
+ &Zoom
+};
+
+DeviceFuncs<PPB_Zoom_Dev> ppb_zoom_f(PPB_ZOOM_DEV_INTERFACE);
+
+} // namespace
+
+Zoom_Dev::Zoom_Dev(Instance* instance) : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPZoomInterface, &ppp_zoom);
+ associated_instance_->AddPerInstanceObject(kPPPZoomInterface, this);
+}
+
+Zoom_Dev::~Zoom_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPZoomInterface, this);
+}
+
+void Zoom_Dev::ZoomChanged(double factor) {
+ if (ppb_zoom_f)
+ ppb_zoom_f->ZoomChanged(associated_instance_->pp_instance(), factor);
+}
+
+void Zoom_Dev::ZoomLimitsChanged(double minimum_factor,
+ double maximium_factor) {
+ if (!ppb_zoom_f)
+ return;
+ ppb_zoom_f->ZoomLimitsChanged(
+ associated_instance_->pp_instance(), minimum_factor, maximium_factor);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/zoom_dev.h b/ppapi/cpp/dev/zoom_dev.h
new file mode 100644
index 0000000..0a079f0
--- /dev/null
+++ b/ppapi/cpp/dev/zoom_dev.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_ZOOM_DEV_H_
+#define PPAPI_CPP_DEV_ZOOM_DEV_H_
+
+#include <string>
+
+#include "ppapi/c/dev/ppp_zoom_dev.h"
+
+namespace pp {
+
+class Instance;
+
+// This class allows you to associate the PPP_Zoom_Dev and PPB_Zoom_Dev C-based
+// interfaces with an object. It associates itself with the given instance, and
+// registers as the global handler for handling the PPP_Zoom_Dev interface that
+// the browser calls.
+//
+// You would typically use this either via inheritance on your instance:
+// class MyInstance : public pp::Instance, public pp::Zoom_Dev {
+// class MyInstance() : pp::Zoom_Dev(this) {
+// }
+// ...
+// };
+//
+// or by composition:
+// class MyZoom : public pp::Zoom_Dev {
+// ...
+// };
+//
+// class MyInstance : public pp::Instance {
+// MyInstance() : zoom_(this) {
+// }
+//
+// MyZoom zoom_;
+// };
+class Zoom_Dev {
+ public:
+ Zoom_Dev(Instance* instance);
+ virtual ~Zoom_Dev();
+
+ // PPP_Zoom_Dev functions exposed as virtual functions for you to
+ // override.
+ virtual void Zoom(double factor, bool text_only) = 0;
+
+ // PPB_Zoom_Def functions for you to call to report new zoom factor.
+ void ZoomChanged(double factor);
+ void ZoomLimitsChanged(double minimum_factor, double maximium_factor);
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_ZOOM_DEV_H_
diff --git a/ppapi/cpp/graphics_2d.cc b/ppapi/cpp/graphics_2d.cc
new file mode 100644
index 0000000..aaccff7
--- /dev/null
+++ b/ppapi/cpp/graphics_2d.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/graphics_2d.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_graphics_2d.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/rect.h"
+
+namespace {
+
+DeviceFuncs<PPB_Graphics2D> graphics_2d_f(PPB_GRAPHICS_2D_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Graphics2D::Graphics2D() : Resource() {
+}
+
+Graphics2D::Graphics2D(const Graphics2D& other)
+ : Resource(other),
+ size_(other.size_) {
+}
+
+Graphics2D::Graphics2D(const Size& size, bool is_always_opaque)
+ : Resource() {
+ if (!graphics_2d_f)
+ return;
+ PassRefFromConstructor(graphics_2d_f->Create(Module::Get()->pp_module(),
+ &size.pp_size(),
+ is_always_opaque));
+ if (!is_null()) {
+ // Only save the size if allocation succeeded.
+ size_ = size;
+ }
+}
+
+Graphics2D::~Graphics2D() {
+}
+
+Graphics2D& Graphics2D::operator=(const Graphics2D& other) {
+ Graphics2D copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Graphics2D::swap(Graphics2D& other) {
+ Resource::swap(other);
+ size_.swap(other.size_);
+}
+
+void Graphics2D::PaintImageData(const ImageData& image,
+ const Point& top_left) {
+ if (!graphics_2d_f)
+ return;
+ graphics_2d_f->PaintImageData(pp_resource(), image.pp_resource(),
+ &top_left.pp_point(), NULL);
+}
+
+void Graphics2D::PaintImageData(const ImageData& image,
+ const Point& top_left,
+ const Rect& src_rect) {
+ if (!graphics_2d_f)
+ return;
+ graphics_2d_f->PaintImageData(pp_resource(), image.pp_resource(),
+ &top_left.pp_point(), &src_rect.pp_rect());
+}
+
+void Graphics2D::Scroll(const Rect& clip, const Point& amount) {
+ if (!graphics_2d_f)
+ return;
+ graphics_2d_f->Scroll(pp_resource(), &clip.pp_rect(), &amount.pp_point());
+}
+
+void Graphics2D::ReplaceContents(ImageData* image) {
+ if (!graphics_2d_f)
+ return;
+ graphics_2d_f->ReplaceContents(pp_resource(), image->pp_resource());
+
+ // On success, reset the image data. This is to help prevent people
+ // from continuing to use the resource which will result in artifacts.
+ *image = ImageData();
+}
+
+int32_t Graphics2D::Flush(const CompletionCallback& cc) {
+ if (!graphics_2d_f)
+ return PP_ERROR_NOINTERFACE;
+ return graphics_2d_f->Flush(pp_resource(), cc.pp_completion_callback());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/graphics_2d.h b/ppapi/cpp/graphics_2d.h
new file mode 100644
index 0000000..8f4622f
--- /dev/null
+++ b/ppapi/cpp/graphics_2d.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_GRAPHICS_2D_H_
+#define PPAPI_CPP_GRAPHICS_2D_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/size.h"
+
+namespace pp {
+
+class CompletionCallback;
+class ImageData;
+class Point;
+class Rect;
+
+class Graphics2D : public Resource {
+ public:
+ // Creates an is_null() ImageData object.
+ Graphics2D();
+
+ // The copied context will refer to the original (since this is just a wrapper
+ // around a refcounted resource).
+ Graphics2D(const Graphics2D& other);
+
+ // Allocates a new 2D graphics context with the given size in the browser,
+ // resulting object will be is_null() if the allocation failed.
+ Graphics2D(const Size& size, bool is_always_opaque);
+
+ virtual ~Graphics2D();
+
+ Graphics2D& operator=(const Graphics2D& other);
+ void swap(Graphics2D& other);
+
+ const Size& size() const { return size_; }
+
+ // Enqueues paint or scroll commands. THIS COMMAND HAS NO EFFECT UNTIL YOU
+ // CALL Flush().
+ //
+ // If you call the version with no source rect, the entire image will be
+ // painted.
+ //
+ // Please see PPB_Graphics2D.PaintImageData / .Scroll for more details.
+ void PaintImageData(const ImageData& image,
+ const Point& top_left);
+ void PaintImageData(const ImageData& image,
+ const Point& top_left,
+ const Rect& src_rect);
+ void Scroll(const Rect& clip, const Point& amount);
+
+ // The browser will take ownership of the given image data. The object
+ // pointed to by the parameter will be cleared. To avoid horrible artifacts,
+ // you should also not use any other ImageData objects referring to the same
+ // resource will no longer be usable. THIS COMMAND HAS NO EFFECT UNTIL YOU
+ // CALL Flush().
+ //
+ // Please see PPB_Graphics2D.ReplaceContents for more details.
+ void ReplaceContents(ImageData* image);
+
+ // Flushes all the currently enqueued Paint, Scroll, and Replace commands.
+ // Can be used in synchronous mode (NULL callback pointer) from background
+ // threads.
+ //
+ // Please see PPB_Graphics2D.Flush for more details.
+ int32_t Flush(const CompletionCallback& cc);
+
+ private:
+ Size size_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_GRAPHICS_2D_H_
diff --git a/ppapi/cpp/image_data.cc b/ppapi/cpp/image_data.cc
new file mode 100644
index 0000000..6f4bf69
--- /dev/null
+++ b/ppapi/cpp/image_data.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/image_data.h"
+
+#include <string.h> // Needed for memset.
+
+#include <algorithm>
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_ImageData> image_data_f(PPB_IMAGEDATA_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+ImageData::ImageData() : data_(NULL) {
+ memset(&desc_, 0, sizeof(PP_ImageDataDesc));
+}
+
+ImageData::ImageData(const ImageData& other)
+ : Resource(other),
+ desc_(other.desc_),
+ data_(other.data_) {
+}
+
+ImageData::ImageData(PassRef, PP_Resource resource)
+ : data_(NULL) {
+ memset(&desc_, 0, sizeof(PP_ImageDataDesc));
+
+ if (!image_data_f)
+ return;
+
+ PassRefAndInitData(resource);
+}
+
+ImageData::ImageData(PP_ImageDataFormat format,
+ const Size& size,
+ bool init_to_zero)
+ : data_(NULL) {
+ memset(&desc_, 0, sizeof(PP_ImageDataDesc));
+
+ if (!image_data_f)
+ return;
+
+ PassRefAndInitData(image_data_f->Create(Module::Get()->pp_module(),
+ format, &size.pp_size(),
+ init_to_zero));
+}
+
+ImageData::~ImageData() {
+}
+
+ImageData& ImageData::operator=(const ImageData& other) {
+ ImageData copy(other);
+ swap(copy);
+ return *this;
+}
+
+void ImageData::swap(ImageData& other) {
+ Resource::swap(other);
+ std::swap(desc_, other.desc_);
+ std::swap(data_, other.data_);
+}
+
+const uint32_t* ImageData::GetAddr32(const Point& coord) const {
+ // Prefer evil const casts rather than evil code duplication.
+ return const_cast<ImageData*>(this)->GetAddr32(coord);
+}
+
+uint32_t* ImageData::GetAddr32(const Point& coord) {
+ // If we add more image format types that aren't 32-bit, we'd want to check
+ // here and fail.
+ return reinterpret_cast<uint32_t*>(
+ &static_cast<char*>(data())[coord.y() * stride() + coord.x() * 4]);
+}
+
+// static
+PP_ImageDataFormat ImageData::GetNativeImageDataFormat() {
+ if (!image_data_f)
+ return PP_IMAGEDATAFORMAT_BGRA_PREMUL; // Default to something on failure.
+ return image_data_f->GetNativeImageDataFormat();
+}
+
+void ImageData::PassRefAndInitData(PP_Resource resource) {
+ PassRefFromConstructor(resource);
+ if (!image_data_f->Describe(pp_resource(), &desc_) ||
+ !(data_ = image_data_f->Map(pp_resource())))
+ *this = ImageData();
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/image_data.h b/ppapi/cpp/image_data.h
new file mode 100644
index 0000000..07b77e3
--- /dev/null
+++ b/ppapi/cpp/image_data.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_IMAGE_DATA_H_
+#define PPAPI_CPP_IMAGE_DATA_H_
+
+#include "ppapi/c/ppb_image_data.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/size.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Plugin;
+
+class ImageData : public Resource {
+ public:
+ // Creates an is_null() ImageData object.
+ ImageData();
+
+ // This magic constructor is used when we've gotten a PP_Resource as a return
+ // value that has already been addref'ed for us.
+ struct PassRef {};
+ ImageData(PassRef, PP_Resource resource);
+
+ ImageData(const ImageData& other);
+
+ // Allocates a new ImageData in the browser with the given parameters. The
+ // resulting object will be is_null() if the allocation failed.
+ ImageData(PP_ImageDataFormat format,
+ const Size& size,
+ bool init_to_zero);
+
+ virtual ~ImageData();
+
+ ImageData& operator=(const ImageData& other);
+ void swap(ImageData& other);
+
+ // Returns the browser's preferred format for images. Using this format
+ // guarantees no extra conversions will occur when painting.
+ static PP_ImageDataFormat GetNativeImageDataFormat();
+
+ PP_ImageDataFormat format() const { return desc_.format; }
+
+ pp::Size size() const { return desc_.size; }
+ int32_t stride() const { return desc_.stride; }
+
+ void* data() const { return data_; }
+
+ // Helper function to retrieve the address of the given pixel for 32-bit
+ // pixel formats.
+ const uint32_t* GetAddr32(const Point& coord) const;
+ uint32_t* GetAddr32(const Point& coord);
+
+ private:
+ void PassRefAndInitData(PP_Resource resource);
+
+ PP_ImageDataDesc desc_;
+ void* data_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_IMAGE_DATA_H_
diff --git a/ppapi/cpp/instance.cc b/ppapi/cpp/instance.cc
new file mode 100644
index 0000000..16d7f76
--- /dev/null
+++ b/ppapi/cpp/instance.cc
@@ -0,0 +1,143 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/instance.h"
+
+#include "ppapi/c/dev/ppp_printing_dev.h"
+#include "ppapi/c/ppb_instance.h"
+#include "ppapi/cpp/dev/scrollbar_dev.h"
+#include "ppapi/cpp/dev/widget_dev.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+namespace {
+
+DeviceFuncs<PPB_Instance> ppb_instance_f(PPB_INSTANCE_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Instance::Instance(PP_Instance instance) : pp_instance_(instance) {
+}
+
+Instance::~Instance() {
+ // Ensure that all per-instance objects have been removed. Generally, these
+ // objects should have their lifetime scoped to the instance, such as being
+ // instance members or even implemented by your instance sub-class directly.
+ //
+ // If they're not unregistered at this point, they will usually have a
+ // dangling reference to the instance, which can cause a crash later.
+ PP_DCHECK(interface_name_to_objects_.empty());
+}
+
+bool Instance::Init(uint32_t /*argc*/, const char* /*argn*/[],
+ const char* /*argv*/[]) {
+ return true;
+}
+
+void Instance::DidChangeView(const pp::Rect& /*position*/,
+ const pp::Rect& /*clip*/) {
+}
+
+void Instance::DidChangeFocus(bool /*has_focus*/) {
+}
+
+
+bool Instance::HandleDocumentLoad(const URLLoader_Dev& /*url_loader*/) {
+ return false;
+}
+
+bool Instance::HandleInputEvent(const PP_InputEvent& /*event*/) {
+ return false;
+}
+
+Var Instance::GetInstanceObject() {
+ return Var();
+}
+
+Var Instance::GetSelectedText(bool /* html */) {
+ return Var();
+}
+
+Var Instance::GetWindowObject() {
+ if (!ppb_instance_f)
+ return Var();
+ return Var(Var::PassRef(), ppb_instance_f->GetWindowObject(pp_instance()));
+}
+
+Var Instance::GetOwnerElementObject() {
+ if (!ppb_instance_f)
+ return Var();
+ return Var(Var::PassRef(),
+ ppb_instance_f->GetOwnerElementObject(pp_instance()));
+}
+
+bool Instance::BindGraphics(const Graphics2D& graphics) {
+ if (!ppb_instance_f)
+ return false;
+ return ppb_instance_f->BindGraphics(pp_instance(), graphics.pp_resource());
+}
+
+bool Instance::IsFullFrame() {
+ if (!ppb_instance_f)
+ return false;
+ return ppb_instance_f->IsFullFrame(pp_instance());
+}
+
+Var Instance::ExecuteScript(const Var& script, Var* exception) {
+ if (!ppb_instance_f)
+ return Var();
+ return Var(Var::PassRef(),
+ ppb_instance_f->ExecuteScript(pp_instance(), script.pp_var(),
+ Var::OutException(exception).get()));
+}
+
+void Instance::AddPerInstanceObject(const std::string& interface_name,
+ void* object) {
+ // Ensure we're not trying to register more than one object per interface
+ // type. Otherwise, we'll get confused in GetPerInstanceObject.
+ PP_DCHECK(interface_name_to_objects_.find(interface_name) ==
+ interface_name_to_objects_.end());
+ interface_name_to_objects_[interface_name] = object;
+}
+
+void Instance::RemovePerInstanceObject(const std::string& interface_name,
+ void* object) {
+ InterfaceNameToObjectMap::iterator found = interface_name_to_objects_.find(
+ interface_name);
+ if (found == interface_name_to_objects_.end()) {
+ // Attempting to unregister an object that doesn't exist or was already
+ // unregistered.
+ PP_DCHECK(false);
+ return;
+ }
+
+ // Validate that we're removing the object we thing we are.
+ PP_DCHECK(found->second == object);
+ (void)object; // Prevent warning in release mode.
+
+ interface_name_to_objects_.erase(found);
+}
+
+// static
+void* Instance::GetPerInstanceObject(PP_Instance instance,
+ const std::string& interface_name) {
+ Instance* that = Module::Get()->InstanceForPPInstance(instance);
+ if (!that)
+ return NULL;
+ InterfaceNameToObjectMap::iterator found =
+ that->interface_name_to_objects_.find(interface_name);
+ if (found == that->interface_name_to_objects_.end())
+ return NULL;
+ return found->second;
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/instance.h b/ppapi/cpp/instance.h
new file mode 100644
index 0000000..df09bb9
--- /dev/null
+++ b/ppapi/cpp/instance.h
@@ -0,0 +1,157 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_INSTANCE_H_
+#define PPAPI_CPP_INSTANCE_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup CPP
+ * @{
+ */
+
+#include <map>
+#include <string>
+
+#include "ppapi/c/dev/ppp_printing_dev.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+struct PP_InputEvent;
+
+/** The C++ interface to the Pepper API. */
+namespace pp {
+
+class Graphics2D;
+class ImageData;
+class Point;
+class Rect;
+class Rect;
+class Resource;
+class Scrollbar_Dev;
+class URLLoader_Dev;
+class Var;
+class Widget_Dev;
+
+class Instance {
+ public:
+ explicit Instance(PP_Instance instance);
+ virtual ~Instance();
+
+ PP_Instance pp_instance() const { return pp_instance_; }
+
+ /**
+ * Initializes this plugin with the given arguments.
+ * @param argc The argument count
+ * @param argn The argument names
+ * @param argv The argument values
+ * @return True on success. Returning false causes the plugin
+ * instance to be deleted and no other functions to be called.
+ */
+ virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
+
+
+ // @{
+ /** @name PPP_Instance methods for the plugin to override: */
+
+ /** See PPP_Instance.DidChangeView. */
+ virtual void DidChangeView(const Rect& position, const Rect& clip);
+
+ /** See PPP_Instance.DidChangeFocus. */
+ virtual void DidChangeFocus(bool has_focus);
+
+ /** See PPP_Instance.HandleInputEvent. */
+ virtual bool HandleInputEvent(const PP_InputEvent& event);
+
+ /** See PPP_Instance.HandleDocumentLoad. */
+ virtual bool HandleDocumentLoad(const URLLoader_Dev& url_loader);
+
+ /** See PPP_Instance.GetInstanceObject. */
+ virtual Var GetInstanceObject();
+
+ /** See PPP_Instance.GetSelectedText. */
+ virtual Var GetSelectedText(bool html);
+ // @}
+
+ // @{
+ /** @name PPB_Instance methods for querying the browser: */
+
+ /** See PPB_Instance.GetWindowObject. */
+ Var GetWindowObject();
+
+ /** See PPB_Instance.GetOwnerElementObject. */
+ Var GetOwnerElementObject();
+
+ /** See PPB_Instance.BindGraphics. */
+ bool BindGraphics(const Graphics2D& graphics);
+
+ /** See PPB_Instance.IsFullFrame. */
+ bool IsFullFrame();
+
+ /** See PPB_Instance.ExecuteScript. */
+ Var ExecuteScript(const Var& script, Var* exception = NULL);
+ // @}
+
+ /**
+ * Associates a plugin instance with an interface,
+ * creating an object... {PENDING: clarify!}
+ *
+ * Many optional interfaces are associated with a plugin instance. For
+ * example, the find in PPP_Find interface receives updates on a per-instance
+ * basis. This "per-instance" tracking allows such objects to associate
+ * themselves with an instance as "the" handler for that interface name.
+ *
+ * In the case of the find example, the find object registers with its
+ * associated instance in its constructor and unregisters in its destructor.
+ * Then whenever it gets updates with a PP_Instance parameter, it can
+ * map back to the find object corresponding to that given PP_Instance by
+ * calling GetPerInstanceObject.
+ *
+ * This lookup is done on a per-interface-name basis. This means you can
+ * only have one object of a given interface name associated with an
+ * instance.
+ *
+ * If you are adding a handler for an additional interface, be sure to
+ * register with the module (AddPluginInterface) for your interface name to
+ * get the C calls in the first place.
+ *
+ * @see RemovePerInstanceObject
+ * @see GetPerInstanceObject
+ */
+ void AddPerInstanceObject(const std::string& interface_name, void* object);
+
+ /**
+ * {PENDING: summarize Remove method here}
+ *
+ * @see AddPerInstanceObject
+ */
+ void RemovePerInstanceObject(const std::string& interface_name, void* object);
+
+ /**
+ * Look up an object previously associated with an instance. Returns NULL
+ * if the instance is invalid or there is no object for the given interface
+ * name on the instance.
+ *
+ * @see AddPerInstanceObject
+ */
+ static void* GetPerInstanceObject(PP_Instance instance,
+ const std::string& interface_name);
+
+ private:
+ PP_Instance pp_instance_;
+
+ typedef std::map<std::string, void*> InterfaceNameToObjectMap;
+ InterfaceNameToObjectMap interface_name_to_objects_;
+};
+
+} // namespace pp
+
+/**
+ * @}
+ * End addtogroup CPP
+ */
+#endif // PPAPI_CPP_INSTANCE_H_
diff --git a/ppapi/cpp/logging.h b/ppapi/cpp/logging.h
new file mode 100644
index 0000000..42061c7
--- /dev/null
+++ b/ppapi/cpp/logging.h
@@ -0,0 +1,14 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_LOGGING_H_
+#define PPAPI_CPP_LOGGING_H_
+
+#include <cassert>
+
+#define PP_DCHECK(a) assert(a)
+
+#define PP_NOTREACHED() assert(false)
+
+#endif // PPAPI_CPP_LOGGING_H_
diff --git a/ppapi/cpp/module.cc b/ppapi/cpp/module.cc
new file mode 100644
index 0000000..fe32569
--- /dev/null
+++ b/ppapi/cpp/module.cc
@@ -0,0 +1,198 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Note that the single accessor, Module::Get(), is not actually implemented
+// in this file. This is an intentional hook that allows users of ppapi's
+// C++ wrapper objects to provide difference semantics for how the singleton
+// object is accessed.
+//
+// In general, users of ppapi will also link in ppp_entrypoints.cc, which
+// provides a simple default implementation of Module::Get().
+//
+// A notable exception where the default ppp_entrypoints will not work is
+// when implementing "internal plugins" that are statically linked into the
+// browser. In this case, the process may actually have multiple Modules
+// loaded at once making a traditional "singleton" unworkable. To get around
+// this, the users of ppapi need to get creative about how to properly
+// implement the Module::Get() so that ppapi's C++ wrappers can find the
+// right Module object. One example solution is to use thread local storage
+// to change the Module* returned based on which thread is invoking the
+// function. Leaving Module::Get() unimplemented provides a hook for
+// implementing such behavior.
+
+#include "ppapi/cpp/module.h"
+
+#include <string.h>
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/ppp_instance.h"
+#include "ppapi/cpp/dev/url_loader_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+// PPP_Instance implementation -------------------------------------------------
+
+bool Instance_DidCreate(PP_Instance pp_instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return false;
+
+ Instance* instance = module_singleton->CreateInstance(pp_instance);
+ if (!instance)
+ return false;
+ module_singleton->current_instances_[pp_instance] = instance;
+ return instance->Init(argc, argn, argv);
+}
+
+void Instance_DidDestroy(PP_Instance instance) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return;
+ Module::InstanceMap::iterator found =
+ module_singleton->current_instances_.find(instance);
+ if (found == module_singleton->current_instances_.end())
+ return;
+
+ // Remove it from the map before deleting to try to catch reentrancy.
+ Instance* obj = found->second;
+ module_singleton->current_instances_.erase(found);
+ delete obj;
+}
+
+void Instance_DidChangeView(PP_Instance pp_instance,
+ const PP_Rect* position,
+ const PP_Rect* clip) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return;
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return;
+ instance->DidChangeView(*position, *clip);
+}
+
+void Instance_DidChangeFocus(PP_Instance pp_instance, bool has_focus) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return;
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return;
+ instance->DidChangeFocus(has_focus);
+}
+
+bool Instance_HandleInputEvent(PP_Instance pp_instance,
+ const PP_InputEvent* event) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return false;
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return false;
+ return instance->HandleInputEvent(*event);
+}
+
+bool Instance_HandleDocumentLoad(PP_Instance pp_instance,
+ PP_Resource pp_url_loader) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return false;
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return false;
+ return instance->HandleDocumentLoad(URLLoader_Dev(pp_url_loader));
+}
+
+PP_Var Instance_GetInstanceObject(PP_Instance pp_instance) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return Var().Detach();
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return Var().Detach();
+ return instance->GetInstanceObject().Detach();
+}
+
+static PPP_Instance instance_interface = {
+ &Instance_DidCreate,
+ &Instance_DidDestroy,
+ &Instance_DidChangeView,
+ &Instance_DidChangeFocus,
+ &Instance_HandleInputEvent,
+ &Instance_HandleDocumentLoad,
+ &Instance_GetInstanceObject
+};
+
+// Module ----------------------------------------------------------------------
+
+Module::Module() : pp_module_(0), get_browser_interface_(NULL), core_(NULL) {
+}
+
+Module::~Module() {
+ delete core_;
+ core_ = NULL;
+}
+
+const void* Module::GetPluginInterface(const char* interface_name) {
+ if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
+ return &instance_interface;
+
+ // Now see if anything was dynamically registered.
+ InterfaceMap::const_iterator found = additional_interfaces_.find(
+ std::string(interface_name));
+ if (found != additional_interfaces_.end())
+ return found->second;
+
+ return NULL;
+}
+
+const void* Module::GetBrowserInterface(const char* interface_name) {
+ return get_browser_interface_(interface_name);
+}
+
+Instance* Module::InstanceForPPInstance(PP_Instance instance) {
+ InstanceMap::iterator found = current_instances_.find(instance);
+ if (found == current_instances_.end())
+ return NULL;
+ return found->second;
+}
+
+void Module::AddPluginInterface(const std::string& interface_name,
+ const void* vtable) {
+ // Verify that we're not trying to register an interface that's already
+ // handled, and if it is, that we're re-registering with the same vtable.
+ // Calling GetPluginInterface rather than looking it up in the map allows
+ // us to also catch "internal" ones in addition to just previously added ones.
+ const void* existing_interface = GetPluginInterface(interface_name.c_str());
+ if (existing_interface) {
+ PP_DCHECK(vtable == existing_interface);
+ return;
+ }
+ additional_interfaces_[interface_name] = vtable;
+}
+
+bool Module::InternalInit(PP_Module mod,
+ PPB_GetInterface get_browser_interface) {
+ pp_module_ = mod;
+ get_browser_interface_ = get_browser_interface;
+
+ // Get the core interface which we require to run.
+ const PPB_Core* core = reinterpret_cast<const PPB_Core*>(GetBrowserInterface(
+ PPB_CORE_INTERFACE));
+ if (!core)
+ return false;
+ core_ = new Core(core);
+
+ return Init();
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/module.h b/ppapi/cpp/module.h
new file mode 100644
index 0000000..362eedf
--- /dev/null
+++ b/ppapi/cpp/module.h
@@ -0,0 +1,123 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_MODULE_H_
+#define PPAPI_CPP_MODULE_H_
+
+#include <map>
+#include <string>
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/ppb.h"
+#include "ppapi/c/ppb_core.h"
+#include "ppapi/cpp/core.h"
+
+namespace pp {
+
+class Instance;
+
+class Module {
+ public:
+ // You may not call any other PP functions from the constructor, put them
+ // in Init instead. Various things will not be set up until the constructor
+ // completes.
+ Module();
+ virtual ~Module();
+
+ // Returns the global instance of this module object, or NULL if the module
+ // is not initialized yet.
+ static Module* Get();
+
+ // This function will be automatically called after the object is created.
+ // This is where you can put functions that rely on other parts of the API,
+ // now that the module has been created.
+ virtual bool Init() { return true; }
+
+ // Returns the internal module handle.
+ PP_Module pp_module() const { return pp_module_; }
+
+ // Returns the internal get_browser_interface pointer.
+ // TODO(sehr): This should be removed once the NaCl browser plugin no longer
+ // needs it.
+ PPB_GetInterface get_browser_interface() const {
+ return get_browser_interface_;
+ }
+
+ // Returns the core interface for doing basic global operations. This is
+ // guaranteed to be non-NULL once the module has successfully initialized
+ // and during the Init() call.
+ //
+ // It will be NULL before Init() has been called.
+ Core* core() { return core_; }
+
+ // Implements GetInterface for the browser to get plugin interfaces. If you
+ // need to provide your own implementations of new interfaces, you can use
+ // AddPluginInterface which this function will use.
+ const void* GetPluginInterface(const char* interface_name);
+
+ // Returns an interface in the browser.
+ const void* GetBrowserInterface(const char* interface_name);
+
+ // Returns the object associated with this PP_Instance, or NULL if one is
+ // not found.
+ Instance* InstanceForPPInstance(PP_Instance instance);
+
+ // Adds a handler for a given interface name. When the browser requests
+ // that interface name, the given |vtable| will be returned.
+ //
+ // In general, plugins will not need to call this directly. Instead, the
+ // C++ wrappers for each interface will register themselves with this
+ // function.
+ //
+ // This function may be called more than once with the same interface name
+ // and vtable with no effect. However, it may not be used to register a
+ // different vtable for an already-registered interface. It will assert for
+ // a different registration for an already-registered interface in debug
+ // mode, and just ignore the registration in release mode.
+ void AddPluginInterface(const std::string& interface_name,
+ const void* vtable);
+
+ // Sets the browser interface and calls the regular init function that
+ // can be overridden by the base classes.
+ //
+ // TODO(brettw) make this private when I can figure out how to make the
+ // initialize function a friend.
+ bool InternalInit(PP_Module mod,
+ PPB_GetInterface get_browser_interface);
+
+ protected:
+ // Override to create your own plugin type.
+ virtual Instance* CreateInstance(PP_Instance instance) = 0;
+
+ private:
+ friend bool Instance_DidCreate(PP_Instance pp_instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]);
+ friend void Instance_DidDestroy(PP_Instance instance);
+
+ // Unimplemented (disallow copy and assign).
+ Module(const Module&);
+ Module& operator=(const Module&);
+
+ // Instance tracking.
+ typedef std::map<PP_Instance, Instance*> InstanceMap;
+ InstanceMap current_instances_;
+
+ PP_Module pp_module_;
+ PPB_GetInterface get_browser_interface_;
+
+ Core* core_;
+
+ // All additional interfaces this plugin can handle as registered by
+ // AddPluginInterface.
+ typedef std::map<std::string, const void*> InterfaceMap;
+ InterfaceMap additional_interfaces_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_MODULE_H_
diff --git a/ppapi/cpp/module_embedder.h b/ppapi/cpp/module_embedder.h
new file mode 100644
index 0000000..c384364
--- /dev/null
+++ b/ppapi/cpp/module_embedder.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_MODULE_EMBEDDER_H_
+#define PPAPI_CPP_MODULE_EMBEDDER_H_
+
+namespace pp {
+
+class Module;
+// Implemented by the embedder.
+//
+// Creates the pp::Module object associated with this plugin. Returns the
+// module if it was successfully created, or NULL on failure. Upon failure,
+// the plugin will be unloaded.
+pp::Module* CreateModule();
+
+} // namespace pp
+
+#endif // PPAPI_CPP_MODULE_EMBEDDER_H_
diff --git a/ppapi/cpp/module_impl.h b/ppapi/cpp/module_impl.h
new file mode 100644
index 0000000..9cde170
--- /dev/null
+++ b/ppapi/cpp/module_impl.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_MODULE_IMPL_H_
+#define PPAPI_CPP_MODULE_IMPL_H_
+
+#include "ppapi/cpp/module.h"
+
+namespace {
+
+template <typename T> class DeviceFuncs {
+ public:
+ explicit DeviceFuncs(const char* ifname) : ifname_(ifname), funcs_(NULL) {}
+
+ operator T const*() {
+ if (!funcs_) {
+ funcs_ = reinterpret_cast<T const*>(
+ pp::Module::Get()->GetBrowserInterface(ifname_));
+ }
+ return funcs_;
+ }
+
+ // This version doesn't check for existence of the function object. It is
+ // used so that, for DeviceFuncs f, the expression:
+ // if (f) f->doSomething();
+ // checks the existence only once.
+ T const* operator->() const { return funcs_; }
+
+ private:
+ DeviceFuncs(const DeviceFuncs&other);
+ DeviceFuncs &operator=(const DeviceFuncs &other);
+
+ const char* ifname_;
+ T const* funcs_;
+};
+
+} // namespace
+
+#endif // PPAPI_CPP_MODULE_IMPL_H_
+
diff --git a/ppapi/cpp/non_thread_safe_ref_count.h b/ppapi/cpp/non_thread_safe_ref_count.h
new file mode 100644
index 0000000..d827209
--- /dev/null
+++ b/ppapi/cpp/non_thread_safe_ref_count.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_NON_THREAD_SAFE_REF_COUNT_H_
+#define PPAPI_CPP_NON_THREAD_SAFE_REF_COUNT_H_
+
+#include "ppapi/cpp/core.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module.h"
+
+namespace pp {
+
+// Simple ref-count that isn't thread safe. Note: in Debug mode, it checks that
+// it is either called on the main thread, or always called on another thread.
+class NonThreadSafeRefCount {
+ public:
+ NonThreadSafeRefCount()
+ : ref_(0) {
+#ifndef NDEBUG
+ is_main_thread_ = Module::Get()->core()->IsMainThread();
+#endif
+ }
+
+ ~NonThreadSafeRefCount() {
+ PP_DCHECK(is_main_thread_ == Module::Get()->core()->IsMainThread());
+ }
+
+ int32_t AddRef() {
+ PP_DCHECK(is_main_thread_ == Module::Get()->core()->IsMainThread());
+ return ++ref_;
+ }
+
+ int32_t Release() {
+ PP_DCHECK(is_main_thread_ == Module::Get()->core()->IsMainThread());
+ return --ref_;
+ }
+
+ private:
+ int32_t ref_;
+#ifndef NDEBUG
+ bool is_main_thread_;
+#endif
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_NON_THREAD_SAFE_REF_COUNT_H_
diff --git a/ppapi/cpp/paint_aggregator.cc b/ppapi/cpp/paint_aggregator.cc
new file mode 100644
index 0000000..7f54331
--- /dev/null
+++ b/ppapi/cpp/paint_aggregator.cc
@@ -0,0 +1,274 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/paint_aggregator.h"
+
+#include <algorithm>
+
+#include "ppapi/cpp/logging.h"
+
+// ----------------------------------------------------------------------------
+// ALGORITHM NOTES
+//
+// We attempt to maintain a scroll rect in the presence of invalidations that
+// are contained within the scroll rect. If an invalidation crosses a scroll
+// rect, then we just treat the scroll rect as an invalidation rect.
+//
+// For invalidations performed prior to scrolling and contained within the
+// scroll rect, we offset the invalidation rects to account for the fact that
+// the consumer will perform scrolling before painting.
+//
+// We only support scrolling along one axis at a time. A diagonal scroll will
+// therefore be treated as an invalidation.
+// ----------------------------------------------------------------------------
+
+namespace pp {
+
+PaintAggregator::InternalPaintUpdate::InternalPaintUpdate() {
+}
+
+Rect PaintAggregator::InternalPaintUpdate::GetScrollDamage() const {
+ // Should only be scrolling in one direction at a time.
+ PP_DCHECK(!(scroll_delta.x() && scroll_delta.y()));
+
+ Rect damaged_rect;
+
+ // Compute the region we will expose by scrolling, and paint that into a
+ // shared memory section.
+ if (scroll_delta.x()) {
+ int32_t dx = scroll_delta.x();
+ damaged_rect.set_y(scroll_rect.y());
+ damaged_rect.set_height(scroll_rect.height());
+ if (dx > 0) {
+ damaged_rect.set_x(scroll_rect.x());
+ damaged_rect.set_width(dx);
+ } else {
+ damaged_rect.set_x(scroll_rect.right() + dx);
+ damaged_rect.set_width(-dx);
+ }
+ } else {
+ int32_t dy = scroll_delta.y();
+ damaged_rect.set_x(scroll_rect.x());
+ damaged_rect.set_width(scroll_rect.width());
+ if (dy > 0) {
+ damaged_rect.set_y(scroll_rect.y());
+ damaged_rect.set_height(dy);
+ } else {
+ damaged_rect.set_y(scroll_rect.bottom() + dy);
+ damaged_rect.set_height(-dy);
+ }
+ }
+
+ // In case the scroll offset exceeds the width/height of the scroll rect
+ return scroll_rect.Intersect(damaged_rect);
+}
+
+Rect PaintAggregator::InternalPaintUpdate::GetPaintBounds() const {
+ Rect bounds;
+ for (size_t i = 0; i < paint_rects.size(); ++i)
+ bounds = bounds.Union(paint_rects[i]);
+ return bounds;
+}
+
+PaintAggregator::PaintAggregator()
+ : max_redundant_paint_to_scroll_area_(0.8f),
+ max_paint_rects_(10) {
+}
+
+bool PaintAggregator::HasPendingUpdate() const {
+ return !update_.scroll_rect.IsEmpty() || !update_.paint_rects.empty();
+}
+
+void PaintAggregator::ClearPendingUpdate() {
+ update_ = InternalPaintUpdate();
+}
+
+PaintAggregator::PaintUpdate PaintAggregator::GetPendingUpdate() const {
+ // Convert the internal paint update to the external one, which includes a
+ // bit more precomputed info for the caller.
+ PaintUpdate ret;
+ ret.scroll_delta = update_.scroll_delta;
+ ret.scroll_rect = update_.scroll_rect;
+ ret.has_scroll = ret.scroll_delta.x() != 0 || ret.scroll_delta.y() != 0;
+
+ ret.paint_rects.reserve(update_.paint_rects.size() + 1);
+ for (size_t i = 0; i < update_.paint_rects.size(); i++)
+ ret.paint_rects.push_back(update_.paint_rects[i]);
+
+ ret.paint_bounds = update_.GetPaintBounds();
+
+ // Also include the scroll damage (if any) in the paint rects.
+ if (ret.has_scroll) {
+ PP_Rect scroll_damage = update_.GetScrollDamage();
+ ret.paint_rects.push_back(scroll_damage);
+ ret.paint_bounds = ret.paint_bounds.Union(scroll_damage);
+ }
+
+ return ret;
+}
+
+void PaintAggregator::InvalidateRect(const Rect& rect) {
+ // Combine overlapping paints using smallest bounding box.
+ for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
+ const Rect& existing_rect = update_.paint_rects[i];
+ if (existing_rect.Contains(rect)) // Optimize out redundancy.
+ return;
+ if (rect.Intersects(existing_rect) || rect.SharesEdgeWith(existing_rect)) {
+ // Re-invalidate in case the union intersects other paint rects.
+ Rect combined_rect = existing_rect.Union(rect);
+ update_.paint_rects.erase(update_.paint_rects.begin() + i);
+ InvalidateRect(combined_rect);
+ return;
+ }
+ }
+
+ // Add a non-overlapping paint.
+ update_.paint_rects.push_back(rect);
+
+ // If the new paint overlaps with a scroll, then it forces an invalidation of
+ // the scroll. If the new paint is contained by a scroll, then trim off the
+ // scroll damage to avoid redundant painting.
+ if (!update_.scroll_rect.IsEmpty()) {
+ if (ShouldInvalidateScrollRect(rect)) {
+ InvalidateScrollRect();
+ } else if (update_.scroll_rect.Contains(rect)) {
+ update_.paint_rects[update_.paint_rects.size() - 1] =
+ rect.Subtract(update_.GetScrollDamage());
+ if (update_.paint_rects[update_.paint_rects.size() - 1].IsEmpty())
+ update_.paint_rects.erase(update_.paint_rects.end() - 1);
+ }
+ }
+
+ if (update_.paint_rects.size() > max_paint_rects_)
+ CombinePaintRects();
+}
+
+void PaintAggregator::ScrollRect(const Rect& clip_rect, const Point& amount) {
+ // We only support scrolling along one axis at a time.
+ if (amount.x() != 0 && amount.y() != 0) {
+ InvalidateRect(clip_rect);
+ return;
+ }
+
+ // We can only scroll one rect at a time.
+ if (!update_.scroll_rect.IsEmpty() && update_.scroll_rect != clip_rect) {
+ InvalidateRect(clip_rect);
+ return;
+ }
+
+ // Again, we only support scrolling along one axis at a time. Make sure this
+ // update doesn't scroll on a different axis than any existing one.
+ if ((amount.x() && update_.scroll_delta.y()) ||
+ (amount.y() && update_.scroll_delta.x())) {
+ InvalidateRect(clip_rect);
+ return;
+ }
+
+ // The scroll rect is new or isn't changing (though the scroll amount may
+ // be changing).
+ update_.scroll_rect = clip_rect;
+ update_.scroll_delta += amount;
+
+ // We might have just wiped out a pre-existing scroll.
+ if (update_.scroll_delta == Point()) {
+ update_.scroll_rect = Rect();
+ return;
+ }
+
+ // Adjust any contained paint rects and check for any overlapping paints.
+ for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
+ if (update_.scroll_rect.Contains(update_.paint_rects[i])) {
+ update_.paint_rects[i] = ScrollPaintRect(update_.paint_rects[i], amount);
+ // The rect may have been scrolled out of view.
+ if (update_.paint_rects[i].IsEmpty()) {
+ update_.paint_rects.erase(update_.paint_rects.begin() + i);
+ i--;
+ }
+ } else if (update_.scroll_rect.Intersects(update_.paint_rects[i])) {
+ InvalidateScrollRect();
+ return;
+ }
+ }
+
+ // If the new scroll overlaps too much with contained paint rects, then force
+ // an invalidation of the scroll.
+ if (ShouldInvalidateScrollRect(Rect()))
+ InvalidateScrollRect();
+}
+
+Rect PaintAggregator::ScrollPaintRect(const Rect& paint_rect,
+ const Point& amount) const {
+ Rect result = paint_rect;
+
+ result.Offset(amount);
+ result = update_.scroll_rect.Intersect(result);
+
+ // Subtract out the scroll damage rect to avoid redundant painting.
+ return result.Subtract(update_.GetScrollDamage());
+}
+
+bool PaintAggregator::ShouldInvalidateScrollRect(const Rect& rect) const {
+ if (!rect.IsEmpty()) {
+ if (!update_.scroll_rect.Intersects(rect))
+ return false;
+
+ if (!update_.scroll_rect.Contains(rect))
+ return true;
+ }
+
+ // Check if the combined area of all contained paint rects plus this new
+ // rect comes too close to the area of the scroll_rect. If so, then we
+ // might as well invalidate the scroll rect.
+
+ int paint_area = rect.size().GetArea();
+ for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
+ const Rect& existing_rect = update_.paint_rects[i];
+ if (update_.scroll_rect.Contains(existing_rect))
+ paint_area += existing_rect.size().GetArea();
+ }
+ int scroll_area = update_.scroll_rect.size().GetArea();
+ if (float(paint_area) / float(scroll_area) > max_redundant_paint_to_scroll_area_)
+ return true;
+
+ return false;
+}
+
+void PaintAggregator::InvalidateScrollRect() {
+ Rect scroll_rect = update_.scroll_rect;
+ update_.scroll_rect = Rect();
+ update_.scroll_delta = Point();
+ InvalidateRect(scroll_rect);
+}
+
+void PaintAggregator::CombinePaintRects() {
+ // Combine paint rects down to at most two rects: one inside the scroll_rect
+ // and one outside the scroll_rect. If there is no scroll_rect, then just
+ // use the smallest bounding box for all paint rects.
+ //
+ // NOTE: This is a fairly simple algorithm. We could get fancier by only
+ // combining two rects to get us under the max_paint_rects limit, but if we
+ // reach this method then it means we're hitting a rare case, so there's no
+ // need to over-optimize it.
+ //
+ if (update_.scroll_rect.IsEmpty()) {
+ Rect bounds = update_.GetPaintBounds();
+ update_.paint_rects.clear();
+ update_.paint_rects.push_back(bounds);
+ } else {
+ Rect inner, outer;
+ for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
+ const Rect& existing_rect = update_.paint_rects[i];
+ if (update_.scroll_rect.Contains(existing_rect)) {
+ inner = inner.Union(existing_rect);
+ } else {
+ outer = outer.Union(existing_rect);
+ }
+ }
+ update_.paint_rects.clear();
+ update_.paint_rects.push_back(inner);
+ update_.paint_rects.push_back(outer);
+ }
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/paint_aggregator.h b/ppapi/cpp/paint_aggregator.h
new file mode 100644
index 0000000..a73a998
--- /dev/null
+++ b/ppapi/cpp/paint_aggregator.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_PAINT_AGGREGATOR_H_
+#define PPAPI_CPP_PAINT_AGGREGATOR_H_
+
+#include <vector>
+
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/rect.h"
+
+namespace pp {
+
+// This class is responsible for aggregating multiple invalidation and scroll
+// commands to produce a scroll and repaint sequence. You can use this manually
+// to track your updates, but most applications will use the PaintManager to
+// additionally handle the necessary callbacks on top of the PaintAggregator
+// functionality.
+//
+// See http://code.google.com/p/ppapi/wiki/2DPaintingModel
+class PaintAggregator {
+ public:
+ struct PaintUpdate {
+ // True if there is a scroll applied. This indicates that the scroll delta
+ // and scroll_rect are nonzero (just as a convenience).
+ bool has_scroll;
+
+ // The amount to scroll by. Either the X or Y may be nonzero to indicate a
+ // scroll in that direction, but there will never be a scroll in both
+ // directions at the same time (this will be converted to a paint of the
+ // region instead).
+ //
+ // If there is no scroll, this will be (0, 0).
+ Point scroll_delta;
+
+ // The rectangle that should be scrolled by the scroll_delta. If there is no
+ // scroll, this will be (0, 0, 0, 0). We only track one scroll command at
+ // once. If there are multiple ones, they will be converted to invalidates.
+ Rect scroll_rect;
+
+ // A list of all the individual dirty rectangles. This is an aggregated list
+ // of all invalidate calls. Different rectangles may be unified to produce a
+ // minimal list with no overlap that is more efficient to paint. This list
+ // also contains the region exposed by any scroll command.
+ std::vector<Rect> paint_rects;
+
+ // The union of all paint_rects.
+ Rect paint_bounds;
+ };
+
+ PaintAggregator();
+
+ // Setters for the configuration settings. See the corresponding variables
+ // below for what these mean.
+ void set_max_redundant_paint_to_scroll_area(float area) {
+ max_redundant_paint_to_scroll_area_ = area;
+ }
+ void set_max_paint_rects(size_t max_rects) {
+ max_paint_rects_ = max_rects;
+ }
+
+ // There is a PendingUpdate if InvalidateRect or ScrollRect were called and
+ // ClearPendingUpdate was not called.
+ bool HasPendingUpdate() const;
+ void ClearPendingUpdate();
+
+ PaintUpdate GetPendingUpdate() const;
+
+ // The given rect should be repainted.
+ void InvalidateRect(const Rect& rect);
+
+ // The given rect should be scrolled by the given amounts.
+ void ScrollRect(const Rect& clip_rect, const Point& amount);
+
+ private:
+ // This structure is an internal version of PaintUpdate. It's different in
+ // two respects:
+ //
+ // - The scroll damange (area exposed by the scroll operation, if any) is
+ // maintained separately from the dirty rects generated by calling
+ // InvalidateRect. We need to know this distinction for some operations.
+ //
+ // - The paint bounds union is computed on the fly so we don't have to keep
+ // a rectangle up-to-date as we do different operations.
+ class InternalPaintUpdate {
+ public:
+ InternalPaintUpdate();
+
+ // Computes the rect damaged by scrolling within |scroll_rect| by
+ // |scroll_delta|. This rect must be repainted. It is not included in
+ // paint_rects or in the rect returned by GetPaintBounds.
+ Rect GetScrollDamage() const;
+
+ // Returns the smallest rect containing all paint rects, not including the
+ // scroll damage rect.
+ Rect GetPaintBounds() const;
+
+ Point scroll_delta;
+ Rect scroll_rect;
+
+ // Does not include the scroll damage rect.
+ std::vector<Rect> paint_rects;
+ };
+
+ Rect ScrollPaintRect(const Rect& paint_rect, const Point& amount) const;
+ bool ShouldInvalidateScrollRect(const Rect& rect) const;
+ void InvalidateScrollRect();
+ void CombinePaintRects();
+
+ InternalPaintUpdate update_;
+
+ // If the combined area of paint rects contained within the scroll rect grows
+ // too large, then we might as well just treat the scroll rect as a paint
+ // rect. This constant sets the max ratio of paint rect area to scroll rect
+ // area that we will tolerate before downgrading the scroll into a repaint.
+ float max_redundant_paint_to_scroll_area_;
+
+ // The maximum number of paint rects. If we exceed this limit, then we'll
+ // start combining paint rects (see CombinePaintRects). This limiting can be
+ // important since there is typically some overhead in deciding what to
+ // paint. If your plugin is fast at doing these computations, raise this
+ // threshold, if your plugin is slow, lower it (probably requires some
+ // tuning to find the right value).
+ size_t max_paint_rects_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_PAINT_AGGREGATOR_H_
diff --git a/ppapi/cpp/paint_manager.cc b/ppapi/cpp/paint_manager.cc
new file mode 100644
index 0000000..87c0750
--- /dev/null
+++ b/ppapi/cpp/paint_manager.cc
@@ -0,0 +1,174 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/paint_manager.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module.h"
+
+namespace pp {
+
+PaintManager::PaintManager()
+ : instance_(NULL),
+ client_(NULL),
+ is_always_opaque_(false),
+ callback_factory_(NULL) {
+ // Set the callback object outside of the initializer list to avoid a
+ // compiler warning about using "this" in an initializer list.
+ callback_factory_.Initialize(this);
+}
+
+PaintManager::PaintManager(Instance* instance,
+ Client* client,
+ bool is_always_opaque)
+ : instance_(instance),
+ client_(client),
+ is_always_opaque_(is_always_opaque),
+ callback_factory_(NULL) {
+ // Set the callback object outside of the initializer list to avoid a
+ // compiler warning about using "this" in an initializer list.
+ callback_factory_.Initialize(this);
+
+ // You can not use a NULL client pointer.
+ PP_DCHECK(client);
+}
+
+PaintManager::~PaintManager() {
+}
+
+void PaintManager::Initialize(Instance* instance,
+ Client* client,
+ bool is_always_opaque) {
+ PP_DCHECK(!instance_ && !client_); // Can't initialize twice.
+ instance_ = instance;
+ client_ = client;
+ is_always_opaque_ = is_always_opaque;
+}
+
+void PaintManager::SetSize(const Size& new_size) {
+ if (new_size == graphics_.size())
+ return;
+
+ graphics_ = Graphics2D(new_size, is_always_opaque_);
+ if (graphics_.is_null())
+ return;
+ instance_->BindGraphics(graphics_);
+
+ manual_callback_pending_ = false;
+ flush_pending_ = false;
+ callback_factory_.CancelAll();
+
+ Invalidate();
+}
+
+void PaintManager::Invalidate() {
+ // You must call SetDevice before using.
+ PP_DCHECK(!graphics_.is_null());
+
+ EnsureCallbackPending();
+ aggregator_.InvalidateRect(Rect(graphics_.size()));
+}
+
+void PaintManager::InvalidateRect(const Rect& rect) {
+ // You must call SetDevice before using.
+ PP_DCHECK(!graphics_.is_null());
+
+ // Clip the rect to the device area.
+ Rect clipped_rect = rect.Intersect(Rect(graphics_.size()));
+ if (clipped_rect.IsEmpty())
+ return; // Nothing to do.
+
+ EnsureCallbackPending();
+ aggregator_.InvalidateRect(clipped_rect);
+}
+
+void PaintManager::ScrollRect(const Rect& clip_rect, const Point& amount) {
+ // You must call SetDevice before using.
+ PP_DCHECK(!graphics_.is_null());
+
+ EnsureCallbackPending();
+ aggregator_.ScrollRect(clip_rect, amount);
+}
+
+void PaintManager::EnsureCallbackPending() {
+ // The best way for us to do the next update is to get a notification that
+ // a previous one has completed. So if we're already waiting for one, we
+ // don't have to do anything differently now.
+ if (flush_pending_)
+ return;
+
+ // If no flush is pending, we need to do a manual call to get back to the
+ // main thread. We may have one already pending, or we may need to schedule.
+ if (manual_callback_pending_)
+ return;
+
+ Module::Get()->core()->CallOnMainThread(
+ 0,
+ callback_factory_.NewCallback(&PaintManager::OnManualCallbackComplete),
+ 0);
+ manual_callback_pending_ = true;
+}
+
+void PaintManager::DoPaint() {
+ PP_DCHECK(aggregator_.HasPendingUpdate());
+
+ // Make a copy of the pending update and clear the pending update flag before
+ // actually painting. A plugin might cause invalidates in its Paint code, and
+ // we want those to go to the *next* paint.
+ PaintAggregator::PaintUpdate update = aggregator_.GetPendingUpdate();
+ aggregator_.ClearPendingUpdate();
+
+ // Apply any scroll before asking the client to paint.
+ if (update.has_scroll)
+ graphics_.Scroll(update.scroll_rect, update.scroll_delta);
+
+ if (!client_->OnPaint(graphics_, update.paint_rects, update.paint_bounds))
+ return; // Nothing was painted, don't schedule a flush.
+
+ int32_t result = graphics_.Flush(
+ callback_factory_.NewCallback(&PaintManager::OnFlushComplete));
+
+ // If you trigger this assertion, then your plugin has called Flush()
+ // manually. When using the PaintManager, you should not call Flush, it will
+ // handle that for you because it needs to know when it can do the next paint
+ // by implementing the flush callback.
+ //
+ // Another possible cause of this assertion is re-using devices. If you
+ // use one device, swap it with another, then swap it back, we won't know
+ // that we've already scheduled a Flush on the first device. It's best to not
+ // re-use devices in this way.
+ PP_DCHECK(result != PP_ERROR_INPROGRESS);
+
+ if (result == PP_ERROR_WOULDBLOCK) {
+ flush_pending_ = true;
+ } else {
+ PP_DCHECK(result == PP_OK); // Catch all other errors in debug mode.
+ }
+}
+
+void PaintManager::OnFlushComplete(int32_t) {
+ PP_DCHECK(flush_pending_);
+ flush_pending_ = false;
+
+ // If more paints were enqueued while we were waiting for the flush to
+ // complete, execute them now.
+ if (aggregator_.HasPendingUpdate())
+ DoPaint();
+}
+
+void PaintManager::OnManualCallbackComplete(int32_t) {
+ PP_DCHECK(manual_callback_pending_);
+ manual_callback_pending_ = false;
+
+ // Just because we have a manual callback doesn't mean there are actually any
+ // invalid regions. Even though we only schedule this callback when something
+ // is pending, a Flush callback could have come in before this callback was
+ // executed and that could have cleared the queue.
+ if (aggregator_.HasPendingUpdate())
+ DoPaint();
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/paint_manager.h b/ppapi/cpp/paint_manager.h
new file mode 100644
index 0000000..d8cba66
--- /dev/null
+++ b/ppapi/cpp/paint_manager.h
@@ -0,0 +1,207 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_PAINT_MANAGER_H_
+#define PPAPI_CPP_PAINT_MANAGER_H_
+
+#include <vector>
+
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/paint_aggregator.h"
+
+namespace pp {
+
+class Graphics2D;
+class Instance;
+class Point;
+class Rect;
+
+// This class converts the "plugin push" model of painting in PPAPI to a paint
+// request at a later time. Usage is that you call Invalidate and Scroll, and
+// implement the Client interface. Your OnPaint handler will then get called
+// with coalesced paint events.
+//
+// This class is basically a PaintAggregator that groups updates, plus
+// management of callbacks for scheduling paints.
+//
+// Typical usage:
+//
+// class MyClass : public pp::Instance, public PaintManager::Client {
+// public:
+// MyClass() {
+// paint_manager_.Initialize(this, this, false);
+// }
+//
+// void ViewChanged(const pp::Rect& position, const pp::Rect& clip) {
+// paint_manager_.SetSize(position.size());
+// }
+//
+// void DoSomething() {
+// // This function does something like respond to an event that causes
+// // the screen to need updating.
+// paint_manager_.InvalidateRect(some_rect);
+// }
+//
+// // Implementation of PaintManager::Client
+// virtual bool OnPaint(pp::Graphics2D& device,
+// const pp::PaintUpdate& update) {
+// // If our app needed scrolling, we would apply that first here.
+//
+// // Then we would either repaint the area returned by GetPaintBounds or
+// // iterate through all the paint_rects.
+//
+// // The caller will call Flush() for us, so don't do that here.
+// return true;
+// }
+//
+// private:
+// pp::PaintManager paint_manager_;
+// };
+class PaintManager {
+ public:
+ class Client {
+ public:
+ // Paints the given invalid area of the plugin to the given graphics
+ // device. Returns true if anything was painted.
+ //
+ // You are given the list of rects to paint in |paint_rects|, and the
+ // union of all of these rects in |paint_bounds|. You only have to paint
+ // the area inside each of the |paint_rects|, but can paint more if you
+ // want (some apps may just want to paint the union).
+ //
+ // Do not call Flush() on the graphics device, this will be done
+ // automatically if you return true from this function since the
+ // PaintManager needs to handle the callback.
+ //
+ // It is legal for you to cause invalidates inside of Paint which will
+ // then get executed as soon as the Flush for this update has completed.
+ // However, this is not very nice to the host system since it will spin the
+ // CPU, possibly updating much faster than necessary. It is best to have a
+ // 1/60 second timer to do an invalidate instead. This will limit your
+ // animation to the slower of 60Hz or "however fast Flush can complete."
+ virtual bool OnPaint(Graphics2D& graphics,
+ const std::vector<Rect>& paint_rects,
+ const Rect& paint_bounds) = 0;
+
+ protected:
+ // You shouldn't be doing deleting through this interface.
+ virtual ~Client() {}
+ };
+
+ // If you use this version of the constructor, you must call Initialize()
+ // below.
+ PaintManager();
+
+ // The instance is the plugin instance using this paint manager to do its
+ // painting. Painting will automatically go to this instance and you don't
+ // have to manually bind any device context (this is all handled by the
+ // paint manager).
+ //
+ // The Client is a non-owning pointer and must remain valid (normally the
+ // object implementing the Client interface will own the paint manager).
+ //
+ // The is_always_opaque flag will be passed to the device contexts that this
+ // class creates. Set this to true if your plugin always draws an opaque
+ // image to the device. This is used as a hint to the browser that it does
+ // not need to do alpha blending, which speeds up painting. If you generate
+ // non-opqaue pixels or aren't sure, set this to false for more general
+ // blending.
+ //
+ // If you set is_always_opaque, your alpha channel should always be set to
+ // 0xFF or there may be painting artifacts. Being opaque will allow the
+ // browser to do a memcpy rather than a blend to paint the plugin, and this
+ // means your alpha values will get set on the page backing store. If these
+ // values are incorrect, it could mess up future blending. If you aren't
+ // sure, it is always correct to specify that it it not opaque.
+ //
+ // You will need to call SetSize before this class will do anything. Normally
+ // you do this from the ViewChanged method of your plugin instance.
+ PaintManager(Instance* instance, Client* client, bool is_always_opaque);
+
+ ~PaintManager();
+
+ // You must call this function before using if you use the 0-arg constructor.
+ // See the constructor for what these arguments mean.
+ void Initialize(Instance* instance, Client* client, bool is_always_opaque);
+
+ // Setters for the configuration settings in the paint aggregator.
+ // See paint_aggregator.h for what these mean.
+ void set_max_redundant_paint_to_scroll_area(float area) {
+ aggregator_.set_max_redundant_paint_to_scroll_area(area);
+ }
+ void set_max_paint_rects(size_t max_rects) {
+ aggregator_.set_max_paint_rects(max_rects);
+ }
+
+ // Sets the size of the plugin. If the size is the same as the previous call,
+ // this will be a NOP. If the size has changed, a new device will be
+ // allocated to the given size and a paint to that device will be scheduled.
+ //
+ // This is intended to be called from ViewChanged with the size of the
+ // plugin. Since it tracks the old size and only allocates when the size
+ // changes, you can always call this function without worrying about whether
+ // the size changed or ViewChanged is called for another reason (like the
+ // position changed).
+ void SetSize(const Size& new_size);
+
+ // Provides access to the underlying device in case you need it. Note: if
+ // you call Flush on this device the paint manager will get very confused,
+ // don't do this!
+ const Graphics2D& graphics() const { return graphics_; }
+ Graphics2D& graphics() { return graphics_; }
+
+ // Invalidate the entire plugin.
+ void Invalidate();
+
+ // Invalidate the given rect.
+ void InvalidateRect(const Rect& rect);
+
+ // The given rect should be scrolled by the given amounts.
+ void ScrollRect(const Rect& clip_rect, const Point& amount);
+
+ private:
+ // Disallow copy and assign (these are unimplemented).
+ PaintManager(const PaintManager&);
+ PaintManager& operator=(const PaintManager&);
+
+ // Makes sure there is a callback that will trigger a paint at a later time.
+ // This will be either a Flush callback telling us we're allowed to generate
+ // more data, or, if there's no flush callback pending, a manual call back
+ // to the message loop via ExecuteOnMainThread.
+ void EnsureCallbackPending();
+
+ // Does the client paint and executes a Flush if necessary.
+ void DoPaint();
+
+ // Callback for asynchronous completion of Flush.
+ void OnFlushComplete(int32_t);
+
+ // Callback for manual scheduling of paints when there is no flush callback
+ // pending.
+ void OnManualCallbackComplete(int32_t);
+
+ Instance* instance_;
+
+ // Non-owning pointer. See the constructor.
+ Client* client_;
+
+ bool is_always_opaque_;
+
+ CompletionCallbackFactory<PaintManager> callback_factory_;
+
+ // This graphics device will be is_null() if no graphics has been manually
+ // set yet.
+ Graphics2D graphics_;
+
+ PaintAggregator aggregator_;
+
+ // See comment for EnsureCallbackPending for more on how these work.
+ bool manual_callback_pending_;
+ bool flush_pending_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_PAINT_MANAGER_H_
diff --git a/ppapi/cpp/point.h b/ppapi/cpp/point.h
new file mode 100644
index 0000000..ce1c5a4
--- /dev/null
+++ b/ppapi/cpp/point.h
@@ -0,0 +1,93 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_POINT_H_
+#define PPAPI_CPP_POINT_H_
+
+#include "ppapi/c/pp_point.h"
+
+namespace pp {
+
+// A point has an x and y coordinate.
+class Point {
+ public:
+ Point() {
+ point_.x = 0;
+ point_.y = 0;
+ }
+ Point(int32_t in_x, int32_t in_y) {
+ point_.x = in_x;
+ point_.y = in_y;
+ }
+ Point(const PP_Point& point) { // Implicit.
+ point_.x = point.x;
+ point_.y = point.y;
+ }
+
+ ~Point() {
+ }
+
+ operator PP_Point() const {
+ return point_;
+ }
+ const PP_Point& pp_point() const {
+ return point_;
+ }
+ PP_Point& pp_point() {
+ return point_;
+ }
+
+ int32_t x() const { return point_.x; }
+ void set_x(int32_t in_x) {
+ point_.x = in_x;
+ }
+
+ int32_t y() const { return point_.y; }
+ void set_y(int32_t in_y) {
+ point_.y = in_y;
+ }
+
+ Point operator+(const Point& other) const {
+ return Point(x() + other.x(), y() + other.y());
+ }
+ Point operator-(const Point& other) const {
+ return Point(x() - other.x(), y() - other.y());
+ }
+
+ Point& operator+=(const Point& other) {
+ point_.x += other.x();
+ point_.y += other.y();
+ return *this;
+ }
+ Point& operator-=(const Point& other) {
+ point_.x -= other.x();
+ point_.y -= other.y();
+ return *this;
+ }
+
+ void swap(Point& other) {
+ int32_t x = point_.x;
+ int32_t y = point_.y;
+ point_.x = other.point_.x;
+ point_.y = other.point_.y;
+ other.point_.x = x;
+ other.point_.y = y;
+ }
+
+ private:
+ PP_Point point_;
+};
+
+} // namespace pp
+
+inline bool operator==(const pp::Point& lhs, const pp::Point& rhs) {
+ return lhs.x() == rhs.x() && lhs.y() == rhs.y();
+}
+
+inline bool operator!=(const pp::Point& lhs, const pp::Point& rhs) {
+ return !(lhs == rhs);
+}
+
+#endif // PPAPI_CPP_POINT_H_
+
diff --git a/ppapi/cpp/ppp_entrypoints.cc b/ppapi/cpp/ppp_entrypoints.cc
new file mode 100644
index 0000000..c3e7568
--- /dev/null
+++ b/ppapi/cpp/ppp_entrypoints.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// When used in conjunction with module_embedder.h, this gives a default
+// implementation of ppp.h for clients of the ppapi C++ interface. Most
+// plugin implementors can export their derivation of Module by just
+// linking to this implementation.
+
+#include "ppapi/c/ppb.h"
+#include "ppapi/c/ppp.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_embedder.h"
+
+static pp::Module* g_module_singleton = NULL;
+
+namespace pp {
+
+// Give a default implementation of Module::Get(). See module.cc for details.
+pp::Module* Module::Get() {
+ return g_module_singleton;
+}
+
+} // namespace pp
+
+// Global PPP functions --------------------------------------------------------
+
+PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id,
+ PPB_GetInterface get_browser_interface) {
+ pp::Module* module = pp::CreateModule();
+ if (!module)
+ return PP_ERROR_FAILED;
+
+ if (!module->InternalInit(module_id, get_browser_interface)) {
+ delete module;
+ return PP_ERROR_FAILED;
+ }
+ g_module_singleton = module;
+ return PP_OK;
+}
+
+PP_EXPORT void PPP_ShutdownModule() {
+ delete g_module_singleton;
+ g_module_singleton = NULL;
+}
+
+PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
+ if (!g_module_singleton)
+ return NULL;
+ return g_module_singleton->GetPluginInterface(interface_name);
+}
diff --git a/ppapi/cpp/rect.cc b/ppapi/cpp/rect.cc
new file mode 100644
index 0000000..b57be2d
--- /dev/null
+++ b/ppapi/cpp/rect.cc
@@ -0,0 +1,137 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/rect.h"
+
+#include <algorithm>
+
+namespace {
+
+void AdjustAlongAxis(int32_t dst_origin, int32_t dst_size,
+ int32_t* origin, int32_t* size) {
+ if (*origin < dst_origin) {
+ *origin = dst_origin;
+ *size = std::min(dst_size, *size);
+ } else {
+ *size = std::min(dst_size, *size);
+ *origin = std::min(dst_origin + dst_size, *origin + *size) - *size;
+ }
+}
+
+} // namespace
+
+namespace pp {
+
+void Rect::Inset(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+ Offset(left, top);
+ set_width(std::max<int32_t>(width() - left - right, 0));
+ set_height(std::max<int32_t>(height() - top - bottom, 0));
+}
+
+void Rect::Offset(int32_t horizontal, int32_t vertical) {
+ rect_.point.x += horizontal;
+ rect_.point.y += vertical;
+}
+
+void Rect::swap(Rect& other) {
+ std::swap(rect_.point.x, other.rect_.point.x);
+ std::swap(rect_.point.y, other.rect_.point.y);
+ std::swap(rect_.size.width, other.rect_.size.width);
+ std::swap(rect_.size.height, other.rect_.size.height);
+}
+
+bool Rect::Contains(int32_t point_x, int32_t point_y) const {
+ return (point_x >= x()) && (point_x < right()) &&
+ (point_y >= y()) && (point_y < bottom());
+}
+
+bool Rect::Contains(const Rect& rect) const {
+ return (rect.x() >= x() && rect.right() <= right() &&
+ rect.y() >= y() && rect.bottom() <= bottom());
+}
+
+bool Rect::Intersects(const Rect& rect) const {
+ return !(rect.x() >= right() || rect.right() <= x() ||
+ rect.y() >= bottom() || rect.bottom() <= y());
+}
+
+Rect Rect::Intersect(const Rect& rect) const {
+ int32_t rx = std::max(x(), rect.x());
+ int32_t ry = std::max(y(), rect.y());
+ int32_t rr = std::min(right(), rect.right());
+ int32_t rb = std::min(bottom(), rect.bottom());
+
+ if (rx >= rr || ry >= rb)
+ rx = ry = rr = rb = 0; // non-intersecting
+
+ return Rect(rx, ry, rr - rx, rb - ry);
+}
+
+Rect Rect::Union(const Rect& rect) const {
+ // special case empty rects...
+ if (IsEmpty())
+ return rect;
+ if (rect.IsEmpty())
+ return *this;
+
+ int32_t rx = std::min(x(), rect.x());
+ int32_t ry = std::min(y(), rect.y());
+ int32_t rr = std::max(right(), rect.right());
+ int32_t rb = std::max(bottom(), rect.bottom());
+
+ return Rect(rx, ry, rr - rx, rb - ry);
+}
+
+Rect Rect::Subtract(const Rect& rect) const {
+ // boundary cases:
+ if (!Intersects(rect))
+ return *this;
+ if (rect.Contains(*this))
+ return Rect();
+
+ int32_t rx = x();
+ int32_t ry = y();
+ int32_t rr = right();
+ int32_t rb = bottom();
+
+ if (rect.y() <= y() && rect.bottom() >= bottom()) {
+ // complete int32_tersection in the y-direction
+ if (rect.x() <= x()) {
+ rx = rect.right();
+ } else {
+ rr = rect.x();
+ }
+ } else if (rect.x() <= x() && rect.right() >= right()) {
+ // complete int32_tersection in the x-direction
+ if (rect.y() <= y()) {
+ ry = rect.bottom();
+ } else {
+ rb = rect.y();
+ }
+ }
+ return Rect(rx, ry, rr - rx, rb - ry);
+}
+
+Rect Rect::AdjustToFit(const Rect& rect) const {
+ int32_t new_x = x();
+ int32_t new_y = y();
+ int32_t new_width = width();
+ int32_t new_height = height();
+ AdjustAlongAxis(rect.x(), rect.width(), &new_x, &new_width);
+ AdjustAlongAxis(rect.y(), rect.height(), &new_y, &new_height);
+ return Rect(new_x, new_y, new_width, new_height);
+}
+
+Point Rect::CenterPoint() const {
+ return Point(x() + (width() + 1) / 2, y() + (height() + 1) / 2);
+}
+
+bool Rect::SharesEdgeWith(const Rect& rect) const {
+ return (y() == rect.y() && height() == rect.height() &&
+ (x() == rect.right() || right() == rect.x())) ||
+ (x() == rect.x() && width() == rect.width() &&
+ (y() == rect.bottom() || bottom() == rect.y()));
+}
+
+} // namespace gfx
diff --git a/ppapi/cpp/rect.h b/ppapi/cpp/rect.h
new file mode 100644
index 0000000..7b133d2
--- /dev/null
+++ b/ppapi/cpp/rect.h
@@ -0,0 +1,213 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_RECT_H_
+#define PPAPI_CPP_RECT_H_
+
+#include "ppapi/c/pp_rect.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/size.h"
+
+namespace pp {
+
+class Rect {
+ public:
+ Rect() {
+ rect_.point.x = 0;
+ rect_.point.y = 0;
+ rect_.size.width = 0;
+ rect_.size.height = 0;
+ }
+ Rect(const PP_Rect& rect) { // Implicit.
+ set_x(rect.point.x);
+ set_y(rect.point.y);
+ set_width(rect.size.width);
+ set_height(rect.size.height);
+ }
+ Rect(int32_t w, int32_t h) {
+ set_x(0);
+ set_y(0);
+ set_width(w);
+ set_height(h);
+ }
+ Rect(int32_t x, int32_t y, int32_t w, int32_t h) {
+ set_x(x);
+ set_y(y);
+ set_width(w);
+ set_height(h);
+ }
+ explicit Rect(const Size& s) {
+ set_x(0);
+ set_y(0);
+ set_size(s);
+ }
+ Rect(const Point& origin, const Size& size) {
+ set_point(origin);
+ set_size(size);
+ }
+
+ ~Rect() {
+ }
+
+ operator PP_Rect() const {
+ return rect_;
+ }
+ const PP_Rect& pp_rect() const {
+ return rect_;
+ }
+ PP_Rect& pp_rect() {
+ return rect_;
+ }
+
+ int32_t x() const {
+ return rect_.point.x;
+ }
+ void set_x(int32_t in_x) {
+ rect_.point.x = in_x;
+ }
+
+ int32_t y() const {
+ return rect_.point.y;
+ }
+ void set_y(int32_t in_y) {
+ rect_.point.y = in_y;
+ }
+
+ int32_t width() const {
+ return rect_.size.width;
+ }
+ void set_width(int32_t w) {
+ if (w < 0) {
+ PP_DCHECK(w >= 0);
+ w = 0;
+ }
+ rect_.size.width = w;
+ }
+
+ int32_t height() const {
+ return rect_.size.height;
+ }
+ void set_height(int32_t h) {
+ if (h < 0) {
+ PP_DCHECK(h >= 0);
+ h = 0;
+ }
+ rect_.size.height = h;
+ }
+
+ Point point() const {
+ return Point(rect_.point);
+ }
+ void set_point(const Point& origin) {
+ rect_.point = origin;
+ }
+
+ Size size() const {
+ return Size(rect_.size);
+ }
+ void set_size(const Size& s) {
+ rect_.size.width = s.width();
+ rect_.size.height = s.height();
+ }
+
+ int32_t right() const {
+ return x() + width();
+ }
+ int32_t bottom() const {
+ return y() + height();
+ }
+
+ void SetRect(int32_t x, int32_t y, int32_t w, int32_t h) {
+ set_x(x);
+ set_y(y);
+ set_width(w);
+ set_height(h);
+ }
+ void SetRect(const PP_Rect& rect) {
+ rect_ = rect;
+ }
+
+ // Shrink the rectangle by a horizontal and vertical distance on all sides.
+ void Inset(int32_t horizontal, int32_t vertical) {
+ Inset(horizontal, vertical, horizontal, vertical);
+ }
+
+ // Shrink the rectangle by the specified amount on each side.
+ void Inset(int32_t left, int32_t top, int32_t right, int32_t bottom);
+
+ // Move the rectangle by a horizontal and vertical distance.
+ void Offset(int32_t horizontal, int32_t vertical);
+ void Offset(const Point& point) {
+ Offset(point.x(), point.y());
+ }
+
+ // Returns true if the area of the rectangle is zero.
+ bool IsEmpty() const {
+ return rect_.size.width == 0 && rect_.size.height == 0;
+ }
+
+ void swap(Rect& other);
+
+ // Returns true if the point identified by point_x and point_y falls inside
+ // this rectangle. The point (x, y) is inside the rectangle, but the
+ // point (x + width, y + height) is not.
+ bool Contains(int32_t point_x, int32_t point_y) const;
+
+ // Returns true if the specified point is contained by this rectangle.
+ bool Contains(const Point& point) const {
+ return Contains(point.x(), point.y());
+ }
+
+ // Returns true if this rectangle contains the specified rectangle.
+ bool Contains(const Rect& rect) const;
+
+ // Returns true if this rectangle int32_tersects the specified rectangle.
+ bool Intersects(const Rect& rect) const;
+
+ // Computes the int32_tersection of this rectangle with the given rectangle.
+ Rect Intersect(const Rect& rect) const;
+
+ // Computes the union of this rectangle with the given rectangle. The union
+ // is the smallest rectangle containing both rectangles.
+ Rect Union(const Rect& rect) const;
+
+ // Computes the rectangle resulting from subtracting |rect| from |this|. If
+ // |rect| does not intersect completely in either the x- or y-direction, then
+ // |*this| is returned. If |rect| contains |this|, then an empty Rect is
+ // returned.
+ Rect Subtract(const Rect& rect) const;
+
+ // Fits as much of the receiving rectangle int32_to the supplied rectangle as
+ // possible, returning the result. For example, if the receiver had
+ // a x-location of 2 and a width of 4, and the supplied rectangle had
+ // an x-location of 0 with a width of 5, the returned rectangle would have
+ // an x-location of 1 with a width of 4.
+ Rect AdjustToFit(const Rect& rect) const;
+
+ // Returns the center of this rectangle.
+ Point CenterPoint() const;
+
+ // Returns true if this rectangle shares an entire edge (i.e., same width or
+ // same height) with the given rectangle, and the rectangles do not overlap.
+ bool SharesEdgeWith(const Rect& rect) const;
+
+ private:
+ PP_Rect rect_;
+};
+
+} // namespace pp
+
+inline bool operator==(const pp::Rect& lhs, const pp::Rect& rhs) {
+ return lhs.x() == rhs.x() &&
+ lhs.y() == rhs.y() &&
+ lhs.width() == rhs.width() &&
+ lhs.height() == rhs.height();
+}
+
+inline bool operator!=(const pp::Rect& lhs, const pp::Rect& rhs) {
+ return !(lhs == rhs);
+}
+
+#endif
+
diff --git a/ppapi/cpp/resource.cc b/ppapi/cpp/resource.cc
new file mode 100644
index 0000000..e4a0d96
--- /dev/null
+++ b/ppapi/cpp/resource.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/resource.h"
+
+#include <algorithm>
+
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module.h"
+
+namespace pp {
+
+Resource::Resource() : pp_resource_(0) {
+}
+
+Resource::Resource(const Resource& other) : pp_resource_(other.pp_resource_) {
+ if (!is_null())
+ Module::Get()->core()->AddRefResource(pp_resource_);
+}
+
+Resource::~Resource() {
+ if (!is_null())
+ Module::Get()->core()->ReleaseResource(pp_resource_);
+}
+
+Resource& Resource::operator=(const Resource& other) {
+ Resource copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Resource::swap(Resource& other) {
+ std::swap(pp_resource_, other.pp_resource_);
+}
+
+PP_Resource Resource::detach() {
+ PP_Resource ret = pp_resource_;
+ pp_resource_ = 0;
+ return ret;
+}
+
+Resource::Resource(PP_Resource resource) : pp_resource_(resource) {
+ if (!is_null())
+ Module::Get()->core()->AddRefResource(pp_resource_);
+}
+
+void Resource::PassRefFromConstructor(PP_Resource resource) {
+ PP_DCHECK(!pp_resource_);
+ pp_resource_ = resource;
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/resource.h b/ppapi/cpp/resource.h
new file mode 100644
index 0000000..33e9982
--- /dev/null
+++ b/ppapi/cpp/resource.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_RESOURCE_H_
+#define PPAPI_CPP_RESOURCE_H_
+
+#include "ppapi/c/pp_resource.h"
+
+namespace pp {
+
+// Base class for refcounted plugin resources.
+class Resource {
+ public:
+ Resource();
+ Resource(const Resource& other);
+
+ virtual ~Resource();
+
+ Resource& operator=(const Resource& other);
+ void swap(Resource& other);
+
+ // Returns true if the given resource is invalid or uninitialized.
+ bool is_null() const { return !pp_resource_; }
+
+ PP_Resource pp_resource() const { return pp_resource_; }
+
+ // Releases ownership of the PP_Resource and returns it to the caller.
+ // Note the the reference count on the resource is unchanged and the caller
+ // needs to release the resource.
+ PP_Resource detach();
+
+ protected:
+ // This constructor is used when we've gotten a PP_Resource as a return value
+ // that we need to addref.
+ explicit Resource(PP_Resource resource);
+
+ // Called by derived class' constructors to initialize this Resource with
+ // a PP_Resource that has already been AddRef'ed. It also assumes this object
+ // has no current resource.
+ //
+ // The intended usage is that the derived class constructor will call the
+ // default Resource constructor, then make a call to create a resource. It
+ // then wants to assign the new resource (which, since it was returned by the
+ // browser, is already AddRef'ed).
+ void PassRefFromConstructor(PP_Resource resource);
+
+ private:
+ PP_Resource pp_resource_;
+};
+
+} // namespace pp
+
+inline bool operator==(const pp::Resource& lhs, const pp::Resource& rhs) {
+ return lhs.pp_resource() == rhs.pp_resource();
+}
+
+#endif // PPAPI_CPP_RESOURCE_H_
diff --git a/ppapi/cpp/size.h b/ppapi/cpp/size.h
new file mode 100644
index 0000000..adcaf78
--- /dev/null
+++ b/ppapi/cpp/size.h
@@ -0,0 +1,108 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_SIZE_H_
+#define PPAPI_CPP_SIZE_H_
+
+#include "ppapi/c/pp_size.h"
+#include "ppapi/cpp/logging.h"
+
+namespace pp {
+
+class Size {
+ public:
+ Size() {
+ size_.width = 0;
+ size_.height = 0;
+ }
+ Size(const PP_Size& s) { // Implicit.
+ // Want the >= 0 checking of the setter.
+ set_width(s.width);
+ set_height(s.height);
+ }
+ Size(int w, int h) {
+ // Want the >= 0 checking of the setter.
+ set_width(w);
+ set_height(h);
+ }
+
+ ~Size() {
+ }
+
+ operator PP_Size() {
+ return size_;
+ }
+ const PP_Size& pp_size() const {
+ return size_;
+ }
+ PP_Size& pp_size() {
+ return size_;
+ }
+
+ int width() const {
+ return size_.width;
+ }
+ void set_width(int w) {
+ if (w < 0) {
+ PP_DCHECK(w >= 0);
+ w = 0;
+ }
+ size_.width = w;
+ }
+
+ int height() const {
+ return size_.height;
+ }
+ void set_height(int h) {
+ if (h < 0) {
+ PP_DCHECK(h >= 0);
+ h = 0;
+ }
+ size_.height = h;
+ }
+
+ int GetArea() const {
+ return width() * height();
+ }
+
+ void SetSize(int w, int h) {
+ set_width(w);
+ set_height(h);
+ }
+
+ void Enlarge(int w, int h) {
+ set_width(width() + w);
+ set_height(height() + h);
+ }
+
+ void swap(Size& other) {
+ int32_t w = size_.width;
+ int32_t h = size_.height;
+ size_.width = other.size_.width;
+ size_.height = other.size_.height;
+ other.size_.width = w;
+ other.size_.height = h;
+ }
+
+ bool IsEmpty() const {
+ // Size doesn't allow negative dimensions, so testing for 0 is enough.
+ return (width() == 0) || (height() == 0);
+ }
+
+ private:
+ PP_Size size_;
+};
+
+} // namespace pp
+
+inline bool operator==(const pp::Size& lhs, const pp::Size& rhs) {
+ return lhs.width() == rhs.width() && lhs.height() == rhs.height();
+}
+
+inline bool operator!=(const pp::Size& lhs, const pp::Size& rhs) {
+ return !(lhs == rhs);
+}
+
+#endif // PPAPI_CPP_SIZE_H_
+
diff --git a/ppapi/cpp/var.cc b/ppapi/cpp/var.cc
new file mode 100644
index 0000000..d48253a
--- /dev/null
+++ b/ppapi/cpp/var.cc
@@ -0,0 +1,365 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/var.h"
+
+#include <string.h>
+
+#include <algorithm>
+
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
+
+// Defining snprintf
+#include <stdio.h>
+#if defined(_MSC_VER)
+# define snprintf _snprintf_s
+#endif
+
+namespace {
+
+DeviceFuncs<PPB_Var_Deprecated> ppb_var_f(PPB_VAR_DEPRECATED_INTERFACE);
+
+// Technically you can call AddRef and Release on any Var, but it may involve
+// cross-process calls depending on the plugin. This is an optimization so we
+// only do refcounting on the necessary objects.
+inline bool NeedsRefcounting(const PP_Var& var) {
+ return var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT;
+}
+
+} // namespace
+
+namespace pp {
+
+using namespace deprecated;
+
+Var::Var() {
+ var_.type = PP_VARTYPE_UNDEFINED;
+ needs_release_ = false;
+}
+
+Var::Var(Null) {
+ var_.type = PP_VARTYPE_NULL;
+ needs_release_ = false;
+}
+
+Var::Var(bool b) {
+ var_.type = PP_VARTYPE_BOOL;
+ var_.value.as_bool = b;
+ needs_release_ = false;
+}
+
+Var::Var(int32_t i) {
+ var_.type = PP_VARTYPE_INT32;
+ var_.value.as_int = i;
+ needs_release_ = false;
+}
+
+Var::Var(double d) {
+ var_.type = PP_VARTYPE_DOUBLE;
+ var_.value.as_double = d;
+ needs_release_ = false;
+}
+
+Var::Var(const char* utf8_str) {
+ if (ppb_var_f) {
+ uint32_t len = utf8_str ? static_cast<uint32_t>(strlen(utf8_str)) : 0;
+ var_ = ppb_var_f->VarFromUtf8(Module::Get()->pp_module(), utf8_str, len);
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ }
+ needs_release_ = (var_.type == PP_VARTYPE_STRING);
+}
+
+Var::Var(const std::string& utf8_str) {
+ if (ppb_var_f) {
+ var_ = ppb_var_f->VarFromUtf8(Module::Get()->pp_module(),
+ utf8_str.c_str(),
+ static_cast<uint32_t>(utf8_str.size()));
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ }
+ needs_release_ = (var_.type == PP_VARTYPE_STRING);
+}
+
+Var::Var(ScriptableObject* object) {
+ if (ppb_var_f) {
+ var_ = ppb_var_f->CreateObject(Module::Get()->pp_module(),
+ object->GetClass(), object);
+ needs_release_ = true;
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ needs_release_ = false;
+ }
+}
+
+Var::Var(const Var& other) {
+ var_ = other.var_;
+ if (NeedsRefcounting(var_)) {
+ if (ppb_var_f) {
+ needs_release_ = true;
+ ppb_var_f->AddRef(var_);
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ needs_release_ = false;
+ }
+ } else {
+ needs_release_ = false;
+ }
+}
+
+Var::~Var() {
+ if (needs_release_ && ppb_var_f)
+ ppb_var_f->Release(var_);
+}
+
+Var& Var::operator=(const Var& other) {
+ if (needs_release_ && ppb_var_f)
+ ppb_var_f->Release(var_);
+ var_ = other.var_;
+ if (NeedsRefcounting(var_)) {
+ if (ppb_var_f) {
+ needs_release_ = true;
+ ppb_var_f->AddRef(var_);
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ needs_release_ = false;
+ }
+ } else {
+ needs_release_ = false;
+ }
+ return *this;
+}
+
+bool Var::operator==(const Var& other) const {
+ if (var_.type != other.var_.type)
+ return false;
+ switch (var_.type) {
+ case PP_VARTYPE_UNDEFINED:
+ case PP_VARTYPE_NULL:
+ return true;
+ case PP_VARTYPE_BOOL:
+ return AsBool() == other.AsBool();
+ case PP_VARTYPE_INT32:
+ return AsInt() == other.AsInt();
+ case PP_VARTYPE_DOUBLE:
+ return AsDouble() == other.AsDouble();
+ case PP_VARTYPE_STRING:
+ if (var_.value.as_id == other.var_.value.as_id)
+ return true;
+ return AsString() == other.AsString();
+ // TODO(neb): Document that this is === and not ==, unlike strings.
+ case PP_VARTYPE_OBJECT:
+ return var_.value.as_id == other.var_.value.as_id;
+ default:
+ return false;
+ }
+}
+
+bool Var::AsBool() const {
+ if (!is_bool()) {
+ PP_NOTREACHED();
+ return false;
+ }
+ return var_.value.as_bool;
+}
+
+int32_t Var::AsInt() const {
+ if (is_int())
+ return var_.value.as_int;
+ if (is_double())
+ return static_cast<int>(var_.value.as_double);
+ PP_NOTREACHED();
+ return 0;
+}
+
+double Var::AsDouble() const {
+ if (is_double())
+ return var_.value.as_double;
+ if (is_int())
+ return static_cast<double>(var_.value.as_int);
+ PP_NOTREACHED();
+ return 0.0;
+}
+
+std::string Var::AsString() const {
+ if (!is_string()) {
+ PP_NOTREACHED();
+ return std::string();
+ }
+
+ if (!ppb_var_f)
+ return std::string();
+ uint32_t len;
+ const char* str = ppb_var_f->VarToUtf8(var_, &len);
+ return std::string(str, len);
+}
+
+ScriptableObject* Var::AsScriptableObject() const {
+ if (!is_object()) {
+ PP_NOTREACHED();
+ } else if (ppb_var_f) {
+ void* object = NULL;
+ if (ppb_var_f->IsInstanceOf(var_, ScriptableObject::GetClass(), &object)) {
+ return reinterpret_cast<ScriptableObject*>(object);
+ }
+ }
+ return NULL;
+}
+
+bool Var::HasProperty(const Var& name, Var* exception) const {
+ if (!ppb_var_f)
+ return false;
+ return ppb_var_f->HasProperty(var_, name.var_, OutException(exception).get());
+}
+
+bool Var::HasMethod(const Var& name, Var* exception) const {
+ if (!ppb_var_f)
+ return false;
+ return ppb_var_f->HasMethod(var_, name.var_, OutException(exception).get());
+}
+
+Var Var::GetProperty(const Var& name, Var* exception) const {
+ if (!ppb_var_f)
+ return Var();
+ return Var(PassRef(), ppb_var_f->GetProperty(var_, name.var_,
+ OutException(exception).get()));
+}
+
+void Var::GetAllPropertyNames(std::vector<Var>* properties,
+ Var* exception) const {
+ if (!ppb_var_f)
+ return;
+ PP_Var* props = NULL;
+ uint32_t prop_count = 0;
+ ppb_var_f->GetAllPropertyNames(var_, &prop_count, &props,
+ OutException(exception).get());
+ if (!prop_count)
+ return;
+ properties->resize(prop_count);
+ for (uint32_t i = 0; i < prop_count; ++i) {
+ Var temp(PassRef(), props[i]);
+ (*properties)[i] = temp;
+ }
+ Module::Get()->core()->MemFree(props);
+}
+
+void Var::SetProperty(const Var& name, const Var& value, Var* exception) {
+ if (!ppb_var_f)
+ return;
+ ppb_var_f->SetProperty(var_, name.var_, value.var_,
+ OutException(exception).get());
+}
+
+void Var::RemoveProperty(const Var& name, Var* exception) {
+ if (!ppb_var_f)
+ return;
+ ppb_var_f->RemoveProperty(var_, name.var_, OutException(exception).get());
+}
+
+Var Var::Call(const Var& method_name, uint32_t argc, Var* argv,
+ Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ if (argc > 0) {
+ std::vector<PP_Var> args;
+ args.reserve(argc);
+ for (size_t i = 0; i < argc; i++)
+ args.push_back(argv[i].var_);
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_,
+ argc, &args[0],
+ OutException(exception).get()));
+ } else {
+ // Don't try to get the address of a vector if it's empty.
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 0, NULL,
+ OutException(exception).get()));
+ }
+}
+
+Var Var::Construct(uint32_t argc, Var* argv, Var* exception) const {
+ if (!ppb_var_f)
+ return Var();
+ if (argc > 0) {
+ std::vector<PP_Var> args;
+ args.reserve(argc);
+ for (size_t i = 0; i < argc; i++)
+ args.push_back(argv[i].var_);
+ return Var(PassRef(), ppb_var_f->Construct(var_, argc, &args[0],
+ OutException(exception).get()));
+ } else {
+ // Don't try to get the address of a vector if it's empty.
+ return Var(PassRef(), ppb_var_f->Construct(var_, 0, NULL,
+ OutException(exception).get()));
+ }
+}
+
+Var Var::Call(const Var& method_name, Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 0, NULL,
+ OutException(exception).get()));
+}
+
+Var Var::Call(const Var& method_name, const Var& arg1, Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ PP_Var args[1] = {arg1.var_};
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 1, args,
+ OutException(exception).get()));
+}
+
+Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ PP_Var args[2] = {arg1.var_, arg2.var_};
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 2, args,
+ OutException(exception).get()));
+}
+
+Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ const Var& arg3, Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ PP_Var args[3] = {arg1.var_, arg2.var_, arg3.var_};
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 3, args,
+ OutException(exception).get()));
+}
+
+Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ const Var& arg3, const Var& arg4, Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ PP_Var args[4] = {arg1.var_, arg2.var_, arg3.var_, arg4.var_};
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 4, args,
+ OutException(exception).get()));
+}
+
+std::string Var::DebugString() const {
+ char buf[256];
+ if (is_undefined())
+ snprintf(buf, sizeof(buf), "Var<UNDEFINED>");
+ else if (is_null())
+ snprintf(buf, sizeof(buf), "Var<NULL>");
+ else if (is_bool())
+ snprintf(buf, sizeof(buf), AsBool() ? "Var<true>" : "Var<false>");
+ else if (is_int())
+ // Note that the following static_cast is necessary because
+ // NativeClient's int32_t is actually "long".
+ // TODO(sehr,polina): remove this after newlib is changed.
+ snprintf(buf, sizeof(buf), "Var<%d>", static_cast<int>(AsInt()));
+ else if (is_double())
+ snprintf(buf, sizeof(buf), "Var<%f>", AsDouble());
+ else if (is_string())
+ snprintf(buf, sizeof(buf), "Var<'%s'>", AsString().c_str());
+ else if (is_object())
+ snprintf(buf, sizeof(buf), "Var<OBJECT>");
+ return buf;
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/var.h b/ppapi/cpp/var.h
new file mode 100644
index 0000000..9109fef
--- /dev/null
+++ b/ppapi/cpp/var.h
@@ -0,0 +1,205 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_VAR_H_
+#define PPAPI_CPP_VAR_H_
+
+#include <string>
+#include <vector>
+
+#include "ppapi/c/pp_var.h"
+
+namespace pp {
+
+namespace deprecated {
+class ScriptableObject;
+}
+
+class Var {
+ public:
+ struct Null {}; // Special value passed to constructor to make NULL.
+
+ Var(); // PP_Var of type Undefined.
+ Var(Null); // PP_Var of type Null.
+ Var(bool b);
+ Var(int32_t i);
+ Var(double d);
+ Var(const char* utf8_str); // Must be encoded in UTF-8.
+ Var(const std::string& utf8_str); // Must be encoded in UTF-8.
+
+ // This magic constructor is used when we've gotten a PP_Var as a return
+ // value that has already been addref'ed for us.
+ struct PassRef {};
+ Var(PassRef, PP_Var var) {
+ var_ = var;
+ needs_release_ = true;
+ }
+
+ // TODO(brettw): remove DontManage when this bug is fixed
+ // http://code.google.com/p/chromium/issues/detail?id=52105
+ // This magic constructor is used when we've given a PP_Var as an input
+ // argument from somewhere and that reference is managing the reference
+ // count for us. The object will not be AddRef'ed or Release'd by this
+ // class instance..
+ struct DontManage {};
+ Var(DontManage, PP_Var var) {
+ var_ = var;
+ needs_release_ = false;
+ }
+
+ // Takes ownership of the given pointer.
+ Var(deprecated::ScriptableObject* object);
+
+ Var(const Var& other);
+
+ virtual ~Var();
+
+ Var& operator=(const Var& other);
+
+ bool operator==(const Var& other) const;
+
+ bool is_undefined() const { return var_.type == PP_VARTYPE_UNDEFINED; }
+ bool is_null() const { return var_.type == PP_VARTYPE_NULL; }
+ bool is_bool() const { return var_.type == PP_VARTYPE_BOOL; }
+ bool is_string() const { return var_.type == PP_VARTYPE_STRING; }
+ bool is_object() const { return var_.type == PP_VARTYPE_OBJECT; }
+
+ // IsInt and IsDouble return the internal representation. The JavaScript
+ // runtime may convert between the two as needed, so the distinction may
+ // not be relevant in all cases (int is really an optimization inside the
+ // runtime). So most of the time, you will want to check IsNumber.
+ bool is_int() const { return var_.type == PP_VARTYPE_INT32; }
+ bool is_double() const { return var_.type == PP_VARTYPE_DOUBLE; }
+ bool is_number() const {
+ return var_.type == PP_VARTYPE_INT32 ||
+ var_.type == PP_VARTYPE_DOUBLE;
+ }
+
+ // Assumes the internal representation IsBool. If it's not, it will assert
+ // in debug mode, and return false.
+ bool AsBool() const;
+
+ // AsInt and AsDouble implicitly convert between ints and doubles. This is
+ // because JavaScript doesn't have a concept of ints and doubles, only
+ // numbers. The distinction between the two is an optimization inside the
+ // compiler. Since converting from a double to an int may be lossy, if you
+ // care about the distinction, either always work in doubles, or check
+ // !IsDouble() before calling AsInt().
+ //
+ // These functions will assert in debug mode and return 0 if the internal
+ // representation is not IsNumber().
+ int32_t AsInt() const;
+ double AsDouble() const;
+
+ // This assumes the object is of type string. If it's not, it will assert
+ // in debug mode, and return an empty string.
+ std::string AsString() const;
+
+ // This assumes the object is of type object. If it's not, it will assert in
+ // debug mode. If it is not an object or not a ScriptableObject type, returns
+ // NULL.
+ deprecated::ScriptableObject* AsScriptableObject() const;
+
+ bool HasProperty(const Var& name, Var* exception = NULL) const;
+ bool HasMethod(const Var& name, Var* exception = NULL) const;
+ Var GetProperty(const Var& name, Var* exception = NULL) const;
+ void GetAllPropertyNames(std::vector<Var>* properties,
+ Var* exception = NULL) const;
+ void SetProperty(const Var& name, const Var& value, Var* exception = NULL);
+ void RemoveProperty(const Var& name, Var* exception = NULL);
+ Var Call(const Var& method_name, uint32_t argc, Var* argv,
+ Var* exception = NULL);
+ Var Construct(uint32_t argc, Var* argv, Var* exception = NULL) const;
+
+ // Convenience functions for calling functions with small # of args.
+ Var Call(const Var& method_name, Var* exception = NULL);
+ Var Call(const Var& method_name, const Var& arg1, Var* exception = NULL);
+ Var Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ Var* exception = NULL);
+ Var Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ const Var& arg3, Var* exception = NULL);
+ Var Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ const Var& arg3, const Var& arg4, Var* exception = NULL);
+
+ // Returns a const reference to the PP_Var managed by this Var object.
+ const PP_Var& pp_var() const {
+ return var_;
+ }
+
+ // Detaches from the internal PP_Var of this object, keeping the reference
+ // count the same. This is used when returning a PP_Var from an API function
+ // where the caller expects the return value to be AddRef'ed for it.
+ PP_Var Detach() {
+ PP_Var ret = var_;
+ var_ = PP_MakeUndefined();
+ needs_release_ = false;
+ return ret;
+ }
+
+ // Prints a short description "Var<X>" that can be used for logging, where
+ // "X" is the underlying scalar or "UNDEFINED" or "OBJ" as it does not call
+ // into the browser to get the object description.
+ std::string DebugString() const;
+
+ // For use when calling the raw C PPAPI when using the C++ Var as a possibly
+ // NULL exception. This will handle getting the address of the internal value
+ // out if it's non-NULL and fixing up the reference count.
+ //
+ // Danger: this will only work for things with exception semantics, i.e. that
+ // the value will not be changed if it's a non-undefined exception. Otherwise,
+ // this class will mess up the refcounting.
+ //
+ // This is a bit subtle:
+ // - If NULL is passed, we return NULL from get() and do nothing.
+ //
+ // - If a undefined value is passed, we return the address of a undefined var
+ // from get and have the output value take ownership of that var.
+ //
+ // - If a non-undefined value is passed, we return the address of that var
+ // from get, and nothing else should change.
+ //
+ // Example:
+ // void FooBar(a, b, Var* exception = NULL) {
+ // foo_interface->Bar(a, b, Var::OutException(exception).get());
+ // }
+ class OutException {
+ public:
+ OutException(Var* v)
+ : output_(v),
+ originally_had_exception_(v && v->is_null()) {
+ if (output_)
+ temp_ = output_->var_;
+ else
+ temp_.type = PP_VARTYPE_UNDEFINED;
+ }
+ ~OutException() {
+ if (output_ && !originally_had_exception_)
+ *output_ = Var(PassRef(), temp_);
+ }
+
+ PP_Var* get() {
+ if (output_)
+ return &temp_;
+ return NULL;
+ }
+
+ private:
+ Var* output_;
+ bool originally_had_exception_;
+ PP_Var temp_;
+ };
+
+ private:
+ // Prevent an arbitrary pointer argument from being implicitly converted to
+ // a bool at Var construction. If somebody makes such a mistake, (s)he will
+ // get a compilation error.
+ Var(void* non_scriptable_object_pointer);
+
+ PP_Var var_;
+ bool needs_release_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_VAR_H_
diff --git a/ppapi/documentation/Doxyfile b/ppapi/documentation/Doxyfile
new file mode 100755
index 0000000..686d202
--- /dev/null
+++ b/ppapi/documentation/Doxyfile
@@ -0,0 +1,1274 @@
+# Doxyfile 1.4.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for the Pepper (PPAPI) project.
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+#MODIFIED
+
+PROJECT_NAME = "Pepper (PPAPI)"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+#MODIFIED
+
+OUTPUT_DIRECTORY = doc-out-linux
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# obsolete tag
+#
+# USE_WINDOWS_ENCODING = YES
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+#MODIFIED
+##Would like YES, but takes too much space with default styles.
+
+BRIEF_MEMBER_DESC = NO
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+#MODIFIED?
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+#MODIFIED
+
+INLINE_INHERITED_MEMB = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+#MODIFIED
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+#STRIP_FROM_PATH = \
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# obsolete tag
+#
+# DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+#MODIFIED
+
+#ALIASES = \
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+#MODIFIED
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
+# include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+#MODIFIED
+
+SHOW_INCLUDE_FILES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+#MODIFIED
+
+INPUT = \
+ ./c \
+ ./cpp \
+ ./documentation
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS = *.h \
+ *.dox
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+#MODIFIED
+
+EXCLUDE_PATTERNS = _*.h
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+#MODIFIED
+
+IMAGE_PATH = ./documentation/images-dox
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+#MODIFIED (comment, at least)
+##Setting this to YES adds Packages, Classes, and Files tabs.
+##Setting VERBATIM_HEADERS to YES (when this is NO) just adds the Files tab.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+#MODIFIED
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+#MODIFIED
+
+REFERENCES_RELATION = NO
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+#MODIFIED
+##YES includes the Files tab (with link to source files); NO means no Files Tab
+##unless SOURCE_BROWSER is YES (in which case this seems to have no effect).
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+#MODIFIED?
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+#MODIFIED
+
+HTML_HEADER = documentation/header.dox
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+#MODIFIED
+
+HTML_FOOTER = documentation/footer.dox
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+#MODIFIED
+
+HTML_STYLESHEET = documentation/stylesheet-dox.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+#MODIFIED
+
+HTML_ALIGN_MEMBERS = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 251
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+#MODIFIED
+
+PREDEFINED = __native_client__ \
+ DOXYGEN_SHOULD_SKIP_THIS \
+ __attribute__(x)= \
+ EXTERN_C_BEGIN= \
+ EXTERN_C_END=
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = NO
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = NO
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = NO
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = NO
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# obsolete
+#
+# MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+# obsolete
+#
+# MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that a graph may be further truncated if the graph's
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 1000
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/ppapi/documentation/check.sh b/ppapi/documentation/check.sh
new file mode 100755
index 0000000..ce3b49f
--- /dev/null
+++ b/ppapi/documentation/check.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# simple script to check html via tidy. Either specify html files on
+# command line or rely on default which checks all html files in
+# current directory
+set -o nounset
+set -o errexit
+
+
+CheckFile () {
+ echo "========================================"
+ echo "checking $1"
+ echo "========================================"
+ tidy -e -q $1
+}
+
+
+if [ $# -eq 0 ] ; then
+ for file in *.html ; do
+ CheckFile ${file}
+ done
+else
+ for file in $* ; do
+ CheckFile ${file}
+ done
+fi
diff --git a/ppapi/documentation/footer.dox b/ppapi/documentation/footer.dox
new file mode 100644
index 0000000..ce4589a
--- /dev/null
+++ b/ppapi/documentation/footer.dox
@@ -0,0 +1,19 @@
+ <p id="license">
+ Except as otherwise
+ <a href="http://code.google.com/policies.html#restrictions">noted</a>,
+ the content of this page is licensed under a
+ <a href="http://www.google.com/url?sa=D&amp;q=http%3A%2F%2Fcreativecommons.org/licenses/by/2.5/">Creative Commons
+ Attribution 2.5 license</a>.
+ </p>
+
+ <address>
+ &copy;2010 Google
+ </address>
+
+ <address>
+ Generated $date by
+ <a href="http://www.doxygen.org/index.html">doxygen</a> $doxygenversion
+ </address>
+
+ </body>
+</html>
diff --git a/ppapi/documentation/header.dox b/ppapi/documentation/header.dox
new file mode 100644
index 0000000..b9d96c9
--- /dev/null
+++ b/ppapi/documentation/header.dox
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+ <title>$title</title>
+ <link href="./tabs.css" rel="stylesheet" type="text/css">
+ <link href="./stylesheet-dox.css" rel="stylesheet" type="text/css">
+ <link href="./stylesheet-dox-all.css" rel="stylesheet" type="text/css">
+ </head>
+ <body>
+ <div id="toplinks">
+ <a href="http://code.google.com/p/ppapi">PPAPI homepage</a>
+ </div>
diff --git a/ppapi/documentation/images-dox/README.txt b/ppapi/documentation/images-dox/README.txt
new file mode 100644
index 0000000..9a9e18c
--- /dev/null
+++ b/ppapi/documentation/images-dox/README.txt
@@ -0,0 +1,9 @@
+This directory holds all images that go into the doxygen-generated
+API reference doc. To include an image, use code like the following:
+
+@image html figure.jpg
+
+If you want a caption, specify it like this:
+
+@image html figure.jpg "Test image"
+
diff --git a/ppapi/documentation/index.dox b/ppapi/documentation/index.dox
new file mode 100644
index 0000000..21b9351
--- /dev/null
+++ b/ppapi/documentation/index.dox
@@ -0,0 +1,105 @@
+/** \mainpage Pepper API (PPAPI) Reference Documentation
+
+ <p>
+ This reference documentation describes the Pepper plugin API (PPAPI),
+ a cross-platform, open-source API for browser plugins.
+ You can use the Pepper API
+ in <a href="http://code.google.com/p/nativeclient-sdk">Native Client</a>
+ modules to communicate with the Google Chrome browser.
+ This page has the following contents:
+ </p>
+
+ <ul>
+ <li> @ref reading </li>
+ <li> @ref modules </li>
+ <li> @ref about </li>
+ <li> @ref todo </li>
+ </ul>
+
+
+ \section reading Before you start
+
+ This documentation assumes that you have read and understood
+ the following pages in the PPAPI project:
+
+ - <a href="http://code.google.com/p/ppapi/wiki/GettingStarted">Getting started</a>
+ - <a href="http://code.google.com/p/ppapi/wiki/Concepts">Important concepts</a>
+
+ For additional documentation and information
+ about Pepper, see the PPAPI project
+ <a href="http://code.google.com/p/ppapi/">homepage</a> and
+ <a href="http://code.google.com/p/ppapi/w/list">wiki</a>.
+
+
+ \section modules API categories
+
+The Pepper API consists of C API,
+plus C++ classes
+(in the pp namespace)
+that we recommend you use if you're writing a C++ plugin.
+You'll see three prefixes in the C API:
+
+ <dl>
+ <dt> PP_ </dt>
+ <dd> Data types,
+ such as ::PP_Instance and ::PP_Event.
+ </dd>
+ <dt> PPB_ </dt>
+ <dd> API that you can use to call into the browser,
+ such as ::PPB_Instance and ::PPB_GetInterface.
+ </dd>
+ <dt> PPP_ </dt>
+ <dd> API that you implement
+ so that the browser can call into your module.
+ Examples include ::PPP_Instance and ::PPP_InitializeModule.
+ </dd>
+ </dl>
+
+ The C++ API provides a layer over the C API.
+ For example, when you call the constructor
+ for the pp::Instance class,
+ you specify a ::PP_Instance variable.
+ For your convenience, pp::Instance defines methods such as
+ HandleEvent(), which implements ::PPP_Instance.HandleEvent, and
+ GetWindowObject(), which implements ::PPB_Instance.GetWindowObject.
+
+
+ \section about About this doc
+
+ <p>
+ The tabs at the top of each page
+ take you to the following sections.
+ </p>
+
+ <ul>
+ <li> <b>Main Page</b>: This page </li>
+ <li> <a href="modules.html"><b>Modules</b></a>:
+ Lets you find API by functional area
+ &mdash; for example,
+ <a href="group___c_p_p.html">C++ API</a> or
+ <a href="group___p_p.html">Data Types (PP)</a>.
+ Don't confuse this Doxygen term
+ with the Pepper concept of modules,
+ which are represented by pp::Module objects.
+ </li>
+ <li> <a href="annotated.html"><b>Data Structures</b></a>:
+ List of classes and data structures in PPAPI.
+ </li>
+ <li> <a href="files.html"><b>Files</b></a>:
+ The header files used to generate this documentation,
+ with file descriptions and links to generated doc.
+ Don't miss the <a href="globals.html">File member index</a>.
+ </li>
+ </ul>
+
+ \section todo TO DO {PENDING: remove/comment this out before publishing}
+
+ - add include filenames to doc {NOTE: they're now at the end of each page. ok?}
+ - check whether private fields should be documented
+ - make sure naming is consistent and as understandable as possible
+ (modules? plugins? ...)
+ <!-- - make sure access levels (public/protected/private are in the doc)
+ {PENDING: they appear to be. e.g. see file:///home/kathyw/SVN/ppapi/doc-out-linux/html/classpp_1_1_resource.html} -->
+ <!-- - Modules -> API Groups? I couldn't figure out how to do this. -->
+
+ */
diff --git a/ppapi/documentation/modules.dox b/ppapi/documentation/modules.dox
new file mode 100644
index 0000000..90a8884
--- /dev/null
+++ b/ppapi/documentation/modules.dox
@@ -0,0 +1,24 @@
+/**
+ * @defgroup CPP C++ API (Use This)
+ * Description of C++ API goes here.
+ * Mention the pp::Instance and pp::Resource classes.
+ *
+ * @defgroup CAPI C API (Refer to This)
+ * These APIs define the implementation of PPAPI;
+ * they are the contract.
+ * However, you should use the @ref CPP "C++ API" whenever possible.
+ *
+ * @defgroup PP PP: Data Types
+ * @ingroup CAPI
+ * Pepper data types begin with the prefix PP_.
+ *
+ * @defgroup PPB PPB: How the Nexe Calls the Browser
+ * @ingroup CAPI
+ * Browser functions that a nexe can call
+ * begin with the prefix PPB_.
+ *
+ * @defgroup PPP PPP: How the Browser Calls the Nexe
+ * @ingroup CAPI
+ * Nexe functions that the browser can call
+ * begin with the prefix PPP_.
+ */
diff --git a/ppapi/documentation/stylesheet-dox.css b/ppapi/documentation/stylesheet-dox.css
new file mode 100644
index 0000000..81d1a42
--- /dev/null
+++ b/ppapi/documentation/stylesheet-dox.css
@@ -0,0 +1,478 @@
+body, table, div, p, dl {
+ font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
+ font-size: 12px;
+}
+
+/* @group Heading Levels */
+
+h1 {
+ text-align: center;
+ font-size: 150%;
+}
+
+h1 a, h2 a, h3 a, h4 a {
+ font-weight:bold;
+}
+
+h2 {
+ font-size: 120%;
+ margin-top: 2.0em;
+ margin-bottom: 0.5em;
+}
+
+h3 {
+ font-size: 100%;
+}
+
+div.contents {
+ margin-top: 2.0em;
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+ font-size: 9px;
+}
+
+div.qindex, div.navpath, div.navtab{
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ padding: 2px;
+}
+
+div.qindex, div.navpath {
+ width: 100%;
+ line-height: 140%;
+}
+
+div.navtab {
+ margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+ color: #153788;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+.contents a:visited {
+ color: #1b77c5;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a.qindex {
+ font-weight: bold;
+}
+
+a.qindexHL {
+ font-weight: bold;
+ background-color: #6666cc;
+ color: #ffffff;
+ border: 1px double #9295C2;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code {
+}
+
+a.codeRef {
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
+.fragment {
+ font-family: monospace, fixed;
+ font-size: 105%;
+}
+
+pre.fragment {
+ border: 1px solid #CCCCCC;
+ background-color: #f5f5f5;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+}
+
+div.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ margin-bottom: 6px;
+ font-weight: bold;
+}
+
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
+}
+
+body {
+ background: white;
+ color: black;
+ margin-right: 20px;
+ margin-left: 20px;
+}
+
+td.indexkey {
+ background-color: #e8eef2;
+ font-weight: bold;
+ border: 1px solid #CCCCCC;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
+}
+
+td.indexvalue {
+ background-color: #e8eef2;
+ border: 1px solid #CCCCCC;
+ padding: 2px 10px;
+ margin: 2px 0px;
+}
+
+tr.memlist {
+ background-color: #f0f0f0;
+}
+
+p.formulaDsp {
+ text-align: center;
+}
+
+img.formulaDsp {
+}
+
+img.formulaInl {
+ vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
+}
+
+span.keywordtype {
+ color: #604020
+}
+
+span.keywordflow {
+ color: #e08000
+}
+
+span.comment {
+ color: #800000
+}
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+/* @end */
+
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #84b0c7;
+}
+
+th.dirtab {
+ background: #e8eef2;
+ font-weight: bold;
+}
+
+hr {
+ height: 0;
+ border: none;
+ border-top: 1px solid #666;
+}
+
+/* @group Member Descriptions */
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: #FAFAFA;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
+}
+
+.memItemLeft, .memItemRight, .memTemplParams {
+ border-top: 1px solid #ccc;
+}
+
+.memTemplParams {
+ color: #606060;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+ font-size: 80%;
+ color: #606060;
+ font-weight: normal;
+ margin-left: 3px;
+}
+
+.memnav {
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
+.memitem {
+ padding: 0;
+}
+
+.memname {
+ white-space: nowrap;
+ font-weight: bold;
+}
+
+.memproto, .memdoc {
+ border: 1px solid #84b0c7;
+}
+
+.memproto {
+ padding: 0;
+ background-color: #d5e1e8;
+ font-weight: bold;
+ -webkit-border-top-left-radius: 8px;
+ -webkit-border-top-right-radius: 8px;
+ -moz-border-radius-topleft: 8px;
+ -moz-border-radius-topright: 8px;
+}
+
+.memdoc {
+ padding: 2px 5px;
+ background-color: #eef3f5;
+ border-top-width: 0;
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+}
+
+.memdoc p, .memdoc dl, .memdoc ul {
+ margin: 6px 0;
+}
+
+.paramkey {
+ text-align: right;
+}
+
+.paramtype {
+ white-space: nowrap;
+}
+
+.paramname {
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
+}
+
+/* @end */
+
+/* @group Directory (tree) */
+
+/* for the tree view */
+
+.ftvtree {
+ font-family: sans-serif;
+ margin: 0.5em;
+}
+
+/* these are for tree view when used as main index */
+
+.directory {
+ font-size: 9pt;
+ font-weight: bold;
+}
+
+.directory h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice. Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+/*
+.directory h3.swap {
+ height: 61px;
+ background-repeat: no-repeat;
+ background-image: url("yourimage.gif");
+}
+.directory h3.swap span {
+ display: none;
+}
+*/
+
+.directory > h3 {
+ margin-top: 0;
+}
+
+.directory p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory div {
+ display: none;
+ margin: 0px;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+/* these are for tree view when not used as main index */
+
+.directory-alt {
+ font-size: 100%;
+ font-weight: bold;
+}
+
+.directory-alt h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+.directory-alt > h3 {
+ margin-top: 0;
+}
+
+.directory-alt p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory-alt div {
+ display: none;
+ margin: 0px;
+}
+
+.directory-alt img {
+ vertical-align: -30%;
+}
+
+/* @end */
+
+address {
+ font-style: normal;
+ text-align: center;
+ font-size: 90%;
+ color: gray;
+}
+
+DIV.tabs A, #toplinks
+{
+ font-size : 9px;
+}
+
+#toplinks {
+ text-align: right;
+ margin-bottom: -1.9em;
+}
+
+.pending {
+ /* display:none; */
+ color:red; font-weight:bold;
+}
+
+#license {
+ color:gray;
+ font-size:90%;
+ border-top:1px solid;
+ border-color:gray;
+ padding-top:1em;
+ margin-top:3em;
+ text-align:center;
+}
diff --git a/ppapi/documentation/stylesheet.css b/ppapi/documentation/stylesheet.css
new file mode 100644
index 0000000..3d17af0
--- /dev/null
+++ b/ppapi/documentation/stylesheet.css
@@ -0,0 +1,101 @@
+@charset "utf-8";
+a:link { color: #0000cc; }
+body {
+ background: #fff; margin: 3px 8px;
+ font-family: arial, sans-serif;
+}
+
+body { font-size: 83%;}
+pre, code, p kbd { font-size: 120%;}
+
+h1 { font-size: x-large; }
+h2 { font-size: large; }
+h3 { font-size: medium; }
+h4 { font-size: small; }
+
+img { border: 1px solid #ccc; }
+
+pre {
+ margin-left: 2em;
+ padding: 0.5em;
+ border-left: 3px solid #ccc;
+}
+
+pre.no-bar {
+ padding: 0;
+ border-left: 0;
+}
+
+table {
+ border: 1px solid #999999;
+ border-collapse: collapse;
+}
+
+th {
+ border: 1px solid #999999;
+ padding: 0.25em 0.5em;
+ background: #ccc;
+}
+
+td {
+ border-bottom: 1px dotted #999999;
+ border-left: 1px dotted #999999;
+ text-align: left;
+ padding: 0.25em 0.5em;
+}
+
+td pre.listing {
+ margin: 0.25em 0.25em 0.25em 0;
+}
+
+pre.listing {
+ padding: 0;
+ background-color: #fff;
+ border: none;
+}
+
+div#toplink {
+ font-size: small;
+ text-align: right;
+ margin-bottom: -2em;
+}
+
+.caption {
+ font-weight:bold
+}
+
+#license {
+ color:gray;
+ font-size:small;
+ border-top:1px solid;
+ border-color:gray;
+ padding:1em;
+ margin-top:3em;
+ text-align:center;
+}
+
+.technote {
+ border:1px solid #999;
+ background:#ccc;
+ margin:0em 5em;
+ padding: 0.25em 0.5em;
+}
+
+.notapplicable {
+ color:lightgray;
+ font-style:italic;
+}
+
+pre kbd {
+ background:rgb(221, 248, 204);
+}
+
+table caption {
+ font-style:italic;
+ text-align:left;
+}
+
+.comment {
+ display:none; /* comment this line out if you want to see comments */
+ color:red; font-weight:bold;
+}
diff --git a/ppapi/example/Info.plist b/ppapi/example/Info.plist
new file mode 100644
index 0000000..7925b7f
--- /dev/null
+++ b/ppapi/example/Info.plist
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Copyright 2010 Google, Inc.</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.google.exampleplugin</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>BRPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CFPlugInDynamicRegisterFunction</key>
+ <string></string>
+ <key>CFPlugInDynamicRegistration</key>
+ <string>NO</string>
+ <key>WebPluginDescription</key>
+ <string>Simple Pepper plug-in that handles tests</string>
+ <key>WebPluginMIMETypes</key>
+ <dict>
+ <key>pepper-application/x-pepper-example-plugin</key>
+ <dict>
+ <key>WebPluginExtensions</key>
+ <array>
+ <string>testpepper</string>
+ </array>
+ <key>WebPluginTypeDescription</key>
+ <string>Test Pepper API</string>
+ </dict>
+ </dict>
+ <key>WebPluginName</key>
+ <string>Pepper Test PlugIn</string>
+</dict>
+</plist>
diff --git a/ppapi/example/example.cc b/ppapi/example/example.cc
new file mode 100644
index 0000000..bb3825f
--- /dev/null
+++ b/ppapi/example/example.cc
@@ -0,0 +1,426 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <math.h>
+#include <stdio.h> // FIXME(brettw) erase me.
+#ifndef _WIN32
+#include <sys/time.h>
+#endif
+#include <time.h>
+
+#include <algorithm>
+
+#include "ppapi/c/dev/ppp_printing_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/pp_input_event.h"
+#include "ppapi/c/pp_rect.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
+#include "ppapi/cpp/dev/url_loader_dev.h"
+#include "ppapi/cpp/dev/url_request_info_dev.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/var.h"
+
+static const int kStepsPerCircle = 800;
+
+void FlushCallback(void* data, int32_t result);
+
+void FillRect(pp::ImageData* image, int left, int top, int width, int height,
+ uint32_t color) {
+ for (int y = std::max(0, top);
+ y < std::min(image->size().height() - 1, top + height);
+ y++) {
+ for (int x = std::max(0, left);
+ x < std::min(image->size().width() - 1, left + width);
+ x++)
+ *image->GetAddr32(pp::Point(x, y)) = color;
+ }
+}
+
+class MyScriptableObject : public pp::deprecated::ScriptableObject {
+ public:
+ virtual bool HasMethod(const pp::Var& method, pp::Var* exception) {
+ return method.AsString() == "toString";
+ }
+
+ virtual bool HasProperty(const pp::Var& name, pp::Var* exception) {
+ if (name.is_string() && name.AsString() == "blah")
+ return true;
+ return false;
+ }
+
+ virtual pp::Var GetProperty(const pp::Var& name, pp::Var* exception) {
+ if (name.is_string() && name.AsString() == "blah")
+ return new MyScriptableObject();
+ return pp::Var();
+ }
+
+ virtual void GetAllPropertyNames(std::vector<pp::Var>* names,
+ pp::Var* exception) {
+ names->push_back("blah");
+ }
+
+ virtual pp::Var Call(const pp::Var& method,
+ const std::vector<pp::Var>& args,
+ pp::Var* exception) {
+ if (method.AsString() == "toString")
+ return pp::Var("hello world");
+ return pp::Var();
+ }
+};
+
+class MyFetcherClient {
+ public:
+ virtual void DidFetch(bool success, const std::string& data) = 0;
+};
+
+class MyFetcher {
+ public:
+ MyFetcher() : client_(NULL) {
+ callback_factory_.Initialize(this);
+ }
+
+ void Start(const pp::Instance& instance,
+ const pp::Var& url,
+ MyFetcherClient* client) {
+ pp::URLRequestInfo_Dev request;
+ request.SetURL(url);
+ request.SetMethod("GET");
+
+ loader_ = pp::URLLoader_Dev(instance);
+ client_ = client;
+
+ pp::CompletionCallback callback =
+ callback_factory_.NewCallback(&MyFetcher::DidOpen);
+ int rv = loader_.Open(request, callback);
+ if (rv != PP_ERROR_WOULDBLOCK)
+ callback.Run(rv);
+ }
+
+ void StartWithOpenedLoader(const pp::URLLoader_Dev& loader,
+ MyFetcherClient* client) {
+ loader_ = loader;
+ client_ = client;
+
+ ReadMore();
+ }
+
+ private:
+ void ReadMore() {
+ pp::CompletionCallback callback =
+ callback_factory_.NewCallback(&MyFetcher::DidRead);
+ int rv = loader_.ReadResponseBody(buf_, sizeof(buf_), callback);
+ if (rv != PP_ERROR_WOULDBLOCK)
+ callback.Run(rv);
+ }
+
+ void DidOpen(int32_t result) {
+ if (result == PP_OK) {
+ ReadMore();
+ } else {
+ DidFinish(result);
+ }
+ }
+
+ void DidRead(int32_t result) {
+ if (result > 0) {
+ data_.append(buf_, result);
+ ReadMore();
+ } else {
+ DidFinish(result);
+ }
+ }
+
+ void DidFinish(int32_t result) {
+ if (client_)
+ client_->DidFetch(result == PP_OK, data_);
+ }
+
+ pp::CompletionCallbackFactory<MyFetcher> callback_factory_;
+ pp::URLLoader_Dev loader_;
+ MyFetcherClient* client_;
+ char buf_[4096];
+ std::string data_;
+};
+
+class MyInstance : public pp::Instance, public MyFetcherClient {
+ public:
+ MyInstance(PP_Instance instance)
+ : pp::Instance(instance),
+ time_at_last_check_(0.0),
+ fetcher_(NULL),
+ width_(0),
+ height_(0),
+ animation_counter_(0),
+ print_settings_valid_(false) {}
+
+ virtual ~MyInstance() {
+ if (fetcher_) {
+ delete fetcher_;
+ fetcher_ = NULL;
+ }
+ }
+
+ virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
+ return true;
+ }
+
+ virtual bool HandleDocumentLoad(const pp::URLLoader_Dev& loader) {
+ fetcher_ = new MyFetcher();
+ fetcher_->StartWithOpenedLoader(loader, this);
+ return true;
+ }
+
+ virtual bool HandleInputEvent(const PP_InputEvent& event) {
+ switch (event.type) {
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ //SayHello();
+ return true;
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ return true;
+ case PP_INPUTEVENT_TYPE_KEYDOWN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ virtual pp::Var GetInstanceObject() {
+ return new MyScriptableObject();
+ }
+
+ pp::ImageData PaintImage(int width, int height) {
+ pp::ImageData image(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ pp::Size(width, height), false);
+ if (image.is_null()) {
+ printf("Couldn't allocate the image data\n");
+ return image;
+ }
+
+ // Fill with semitransparent gradient.
+ for (int y = 0; y < image.size().height(); y++) {
+ char* row = &static_cast<char*>(image.data())[y * image.stride()];
+ for (int x = 0; x < image.size().width(); x++) {
+ row[x * 4 + 0] = y;
+ row[x * 4 + 1] = y;
+ row[x * 4 + 2] = 0;
+ row[x * 4 + 3] = y;
+ }
+ }
+
+ float radians = static_cast<float>(animation_counter_) / kStepsPerCircle *
+ 2 * 3.14159265358979F;
+
+ float radius = static_cast<float>(std::min(width, height)) / 2.0f - 3.0f;
+ int x = static_cast<int>(cos(radians) * radius + radius + 2);
+ int y = static_cast<int>(sin(radians) * radius + radius + 2);
+
+ FillRect(&image, x - 3, y - 3, 7, 7, 0x80000000);
+ return image;
+ }
+
+ void Paint() {
+ pp::ImageData image = PaintImage(width_, height_);
+ if (!image.is_null()) {
+ device_context_.ReplaceContents(&image);
+ device_context_.Flush(pp::CompletionCallback(&FlushCallback, this));
+ }
+ }
+
+ virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
+ if (position.size().width() == width_ &&
+ position.size().height() == height_)
+ return; // We don't care about the position, only the size.
+
+ width_ = position.size().width();
+ height_ = position.size().height();
+
+ device_context_ = pp::Graphics2D(pp::Size(width_, height_), false);
+ if (!BindGraphics(device_context_)) {
+ printf("Couldn't bind the device context\n");
+ return;
+ }
+
+ Paint();
+ }
+
+ void UpdateFps() {
+// Time code doesn't currently compile on Windows, just skip FPS for now.
+#ifndef _WIN32
+ pp::Var window = GetWindowObject();
+ pp::Var doc = window.GetProperty("document");
+ pp::Var fps = doc.Call("getElementById", "fps");
+
+ struct timeval tv;
+ struct timezone tz = {0, 0};
+ gettimeofday(&tv, &tz);
+
+ double time_now = tv.tv_sec + tv.tv_usec / 1000000.0;
+
+ if (animation_counter_ > 0) {
+ char fps_text[64];
+ sprintf(fps_text, "%g fps",
+ kStepsPerCircle / (time_now - time_at_last_check_));
+ fps.SetProperty("innerHTML", fps_text);
+ }
+
+ time_at_last_check_ = time_now;
+#endif
+ }
+
+ // Print interfaces.
+ virtual PP_PrintOutputFormat_Dev* QuerySupportedPrintOutputFormats(
+ uint32_t* format_count) {
+ PP_PrintOutputFormat_Dev* format =
+ reinterpret_cast<PP_PrintOutputFormat_Dev*>(
+ pp::Module::Get()->core()->MemAlloc(
+ sizeof(PP_PrintOutputFormat_Dev)));
+ *format = PP_PRINTOUTPUTFORMAT_RASTER;
+ *format_count = 1;
+ return format;
+ }
+
+ virtual int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) {
+ if (print_settings_.format != PP_PRINTOUTPUTFORMAT_RASTER)
+ return 0;
+
+ print_settings_ = print_settings;
+ print_settings_valid_ = true;
+ return 1;
+ }
+
+ virtual pp::Resource PrintPages(
+ const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count) {
+ if (!print_settings_valid_)
+ return pp::Resource();
+
+ if (page_range_count != 1)
+ return pp::Resource();
+
+ // Check if the page numbers are valid. We returned 1 in PrintBegin so we
+ // only have 1 page to print.
+ if (page_ranges[0].first_page_number || page_ranges[0].last_page_number) {
+ return pp::Resource();
+ }
+
+ int width = static_cast<int>(
+ (print_settings_.printable_area.size.width / 72.0) *
+ print_settings_.dpi);
+ int height = static_cast<int>(
+ (print_settings_.printable_area.size.height / 72.0) *
+ print_settings_.dpi);
+
+ return PaintImage(width, height);
+ }
+
+ virtual void PrintEnd() {
+ print_settings_valid_ = false;
+ }
+
+ void OnFlush() {
+ if (animation_counter_ % kStepsPerCircle == 0)
+ UpdateFps();
+ animation_counter_++;
+ Paint();
+ }
+
+ private:
+ void Log(const pp::Var& var) {
+ pp::Var doc = GetWindowObject().GetProperty("document");
+ if (console_.is_undefined()) {
+ pp::Var body = doc.GetProperty("body");
+ console_ = doc.Call("createElement", "pre");
+ console_.GetProperty("style").SetProperty("backgroundColor", "lightgray");
+ body.Call("appendChild", console_);
+ }
+ console_.Call("appendChild", doc.Call("createTextNode", var));
+ console_.Call("appendChild", doc.Call("createTextNode", "\n"));
+ }
+
+ void SayHello() {
+ pp::Var window = GetWindowObject();
+ pp::Var doc = window.GetProperty("document");
+ pp::Var body = doc.GetProperty("body");
+
+ pp::Var obj(new MyScriptableObject());
+
+ // Our object should have its toString method called.
+ Log("Testing MyScriptableObject::toString():");
+ Log(obj);
+
+ // body.appendChild(body) should throw an exception
+ Log("\nCalling body.appendChild(body):");
+ pp::Var exception;
+ body.Call("appendChild", body, &exception);
+ Log(exception);
+
+ Log("\nEnumeration of window properties:");
+ std::vector<pp::Var> props;
+ window.GetAllPropertyNames(&props);
+ for (size_t i = 0; i < props.size(); ++i)
+ Log(props[i]);
+
+ pp::Var location = window.GetProperty("location");
+ pp::Var href = location.GetProperty("href");
+
+ if (!fetcher_) {
+ fetcher_ = new MyFetcher();
+ fetcher_->Start(*this, href, this);
+ }
+ }
+
+ void DidFetch(bool success, const std::string& data) {
+ Log("\nDownloaded location.href:");
+ if (success) {
+ Log(data);
+ } else {
+ Log("Failed to download.");
+ }
+ delete fetcher_;
+ fetcher_ = NULL;
+ }
+
+ pp::Var console_;
+ pp::Graphics2D device_context_;
+
+ double time_at_last_check_;
+
+ MyFetcher* fetcher_;
+
+ int width_;
+ int height_;
+
+ // Incremented for each flush we get.
+ int animation_counter_;
+ bool print_settings_valid_;
+ PP_PrintSettings_Dev print_settings_;
+};
+
+void FlushCallback(void* data, int32_t result) {
+ static_cast<MyInstance*>(data)->OnFlush();
+}
+
+class MyModule : public pp::Module {
+ public:
+ MyModule() : pp::Module() {}
+ virtual ~MyModule() {}
+
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new MyInstance(instance);
+ }
+};
+
+namespace pp {
+
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+ return new MyModule();
+}
+
+} // namespace pp
diff --git a/ppapi/example/example.html b/ppapi/example/example.html
new file mode 100644
index 0000000..f6fdc52
--- /dev/null
+++ b/ppapi/example/example.html
@@ -0,0 +1,17 @@
+<body style="background-image:url(http://www.google.com/intl/en_ALL/images/logo.gif);
+ background-repeat:repeat">
+
+<script type="text/javascript">
+function Test() {
+ plugin = document.getElementById('plugin');
+ // Confirm that this no longer segfaults.
+ alert(plugin.toString(new Array(10)));
+}
+
+</script>
+
+ <button onclick='Test()'>Test</button>
+ <div id="fps" style="background-color:white; font-weight:bold; padding:4px;">FPS GOES HERE</div>
+ <object id="plugin" type="application/x-ppapi-example" width="400" height="400" />
+ <hr>
+</body>
diff --git a/ppapi/example/example.rc b/ppapi/example/example.rc
new file mode 100644
index 0000000..9e06702
--- /dev/null
+++ b/ppapi/example/example.rc
@@ -0,0 +1,30 @@
+1 VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x17L
+ FILEFLAGS 0x0L
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Google"
+ VALUE "FileDescription", "Pepper Test Plugin"
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "InternalName", "ppapi_example"
+ VALUE "LegalCopyright", "Copyright (C) 2010"
+ VALUE "OriginalFilename", "ppapi_example.dll"
+ VALUE "ProductName", "Pepper Test Plugin"
+ VALUE "ProductVersion", "1, 0, 0, 1"
+ VALUE "MIMEType", "pepper-application/x-pepper-test-plugin"
+ VALUE "FileExtents", "ptp"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/ppapi/example/example_framed.html b/ppapi/example/example_framed.html
new file mode 100644
index 0000000..5247106
--- /dev/null
+++ b/ppapi/example/example_framed.html
@@ -0,0 +1,2 @@
+<!-- In this invocation of the example plugin, Instance::HandleDocumentLoad is called. -->
+<iframe style="width: 90%; height: 90%" src="data:application/x-ppapi-example,hello%20world"></iframe>
diff --git a/ppapi/examples/2d/graphics_2d_example.c b/ppapi/examples/2d/graphics_2d_example.c
new file mode 100644
index 0000000..eadfb31
--- /dev/null
+++ b/ppapi/examples/2d/graphics_2d_example.c
@@ -0,0 +1,225 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_size.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/ppb.h"
+#include "ppapi/c/ppb_core.h"
+#include "ppapi/c/ppb_graphics_2d.h"
+#include "ppapi/c/ppb_image_data.h"
+#include "ppapi/c/ppb_instance.h"
+#include "ppapi/c/ppp.h"
+#include "ppapi/c/ppp_instance.h"
+
+PP_Module g_module_id;
+PPB_GetInterface g_get_browser_interface = NULL;
+
+const struct PPB_Core* g_core_interface;
+const struct PPB_Graphics2D* g_graphics_2d_interface;
+const struct PPB_ImageData* g_image_data_interface;
+const struct PPB_Instance* g_instance_interface;
+
+// PPP_Instance implementation -------------------------------------------------
+
+struct InstanceInfo {
+ PP_Instance pp_instance;
+ PP_Size last_size;
+
+ InstanceInfo* next;
+};
+
+// Linked list of all live instances.
+InstanceInfo* all_instances = NULL;
+
+// Returns a refed resource corresponding to the created device context.
+PP_Resource MakeAndBindDeviceContext(PP_Instance instance,
+ const struct PP_Size* size) {
+ PP_Resource device_context;
+
+ device_context = g_graphics_2d_interface->Create(g_module_id, size, false);
+ if (!device_context)
+ return 0;
+
+ if (!g_instance_interface->BindGraphics(instance, device_context)) {
+ g_core_interface->ReleaseResource(device_context);
+ return 0;
+ }
+ return device_context;
+}
+
+void FlushCompletionCallback(void* user_data, int32_t result) {
+ // Don't need to do anything here.
+}
+
+void Repaint(InstanceInfo* instance, const struct PP_Size* size) {
+ PP_Resource image, device_context;
+ PP_ImageDataDesc image_desc;
+ uint32_t* image_data;
+ int num_words, i;
+
+ // Create image data to paint into.
+ image = g_image_data_interface->Create(
+ g_module_id, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, true);
+ if (!image)
+ return;
+ g_image_data_interface->Describe(image, &image_desc);
+
+ // Fill the image with blue.
+ image_data = (uint32_t*)g_image_data_interface->Map(image);
+ if (!image_data) {
+ g_core_interface->ReleaseResource(image);
+ return;
+ }
+ num_words = image_desc.stride * size->height / 4;
+ for (i = 0; i < num_words; i++)
+ image_data[i] = 0xFF0000FF;
+
+ // Create the device context and paint the image to it.
+ device_context = MakeAndBindDeviceContext(instance->pp_instance, size);
+ if (!device_context) {
+ g_core_interface->ReleaseResource(image);
+ return;
+ }
+
+ g_graphics_2d_interface->ReplaceContents(device_context, image);
+ g_graphics_2d_interface->Flush(device_context,
+ PP_MakeCompletionCallback(&FlushCompletionCallback, NULL));
+
+ g_core_interface->ReleaseResource(device_context);
+ g_core_interface->ReleaseResource(image);
+}
+
+// Returns the info for the given instance, or NULL if it's not found.
+InstanceInfo* FindInstance(PP_Instance instance) {
+ InstanceInfo* cur = all_instances;
+ while (cur) {
+ if (cur->pp_instance == instance)
+ return cur;
+ }
+ return NULL;
+}
+
+bool Instance_New(PP_Instance instance) {
+ InstanceInfo* info = (InstanceInfo*)malloc(sizeof(InstanceInfo));
+ info->pp_instance = instance;
+ info->last_size.width = 0;
+ info->last_size.height = 0;
+
+ // Insert into linked list of live instances.
+ info->next = all_instances;
+ all_instances = info;
+ return true;
+}
+
+void Instance_Delete(PP_Instance instance) {
+ // Find the matching item in the linked list, delete it, and patch the links.
+ InstanceInfo** prev_ptr = &all_instances;
+ InstanceInfo* cur = all_instances;
+ while (cur) {
+ if (instance == cur->pp_instance) {
+ *prev_ptr = cur->next;
+ free(cur);
+ return;
+ }
+ prev_ptr = &cur->next;
+ }
+}
+
+bool Instance_Initialize(PP_Instance pp_instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]) {
+ return true;
+}
+
+bool Instance_HandleDocumentLoad(PP_Instance pp_instance,
+ PP_Resource pp_url_loader) {
+ return false;
+}
+
+bool Instance_HandleInputEvent(PP_Instance pp_instance,
+ const struct PP_InputEvent* event) {
+ // We don't handle any events.
+ return false;
+}
+
+void Instance_HandleFocusChanged(bool /*has_focus*/) {
+}
+
+PP_Var Instance_GetInstanceObject(PP_Instance pp_instance) {
+ return PP_MakeNull();
+}
+
+void Instance_ViewChanged(PP_Instance pp_instance,
+ const struct PP_Rect* position,
+ const struct PP_Rect* clip) {
+ InstanceInfo* info = FindInstance(pp_instance);
+ if (!info)
+ return;
+
+ if (info->last_size.width != position->size.width ||
+ info->last_size.height != position->size.height) {
+ // Got a resize, repaint the plugin.
+ Repaint(info, &position->size);
+ info->last_size.width = position->size.width;
+ info->last_size.height = position->size.height;
+ }
+}
+
+PP_Var Instance_GetSelectedText(PP_Instance pp_instance,
+ bool html) {
+ return PP_MakeNull();
+}
+
+static PPP_Instance instance_interface = {
+ &Instance_New,
+ &Instance_Delete,
+ &Instance_Initialize,
+ &Instance_HandleDocumentLoad,
+ &Instance_HandleInputEvent,
+ &Instance_HandleFocusChanged,
+ &Instance_GetInstanceObject,
+ &Instance_ViewChanged,
+ &Instance_GetSelectedText,
+};
+
+
+// Global entrypoints ----------------------------------------------------------
+
+PP_EXPORT int32_t PPP_InitializeModule(PP_Module module,
+ PPB_GetInterface get_browser_interface) {
+ // Save the global module information for later.
+ g_module_id = module;
+ g_get_browser_interface = get_browser_interface;
+
+ g_core_interface = (const struct PPB_Core*)
+ get_browser_interface(PPB_CORE_INTERFACE);
+ g_instance_interface = (const struct PPB_Instance*)
+ get_browser_interface(PPB_INSTANCE_INTERFACE);
+ g_image_data_interface = (const struct PPB_ImageData*)
+ get_browser_interface(PPB_IMAGEDATA_INTERFACE);
+ g_graphics_2d_interface = (const struct PPB_Graphics2D*)
+ get_browser_interface(PPB_GRAPHICS_2D_INTERFACE);
+ if (!g_core_interface || !g_instance_interface || !g_image_data_interface ||
+ !g_graphics_2d_interface)
+ return -1;
+
+ return PP_OK;
+}
+
+PP_EXPORT void PPP_ShutdownModule() {
+}
+
+PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
+ if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
+ return &instance_interface;
+ return NULL;
+}
diff --git a/ppapi/examples/2d/paint_manager_example.cc b/ppapi/examples/2d/paint_manager_example.cc
new file mode 100644
index 0000000..5d2bb22
--- /dev/null
+++ b/ppapi/examples/2d/paint_manager_example.cc
@@ -0,0 +1,157 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/c/pp_input_event.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/paint_manager.h"
+#include "ppapi/cpp/size.h"
+
+// Number of pixels to each side of the center of the square that we draw.
+static const int kSquareRadius = 2;
+
+// We identify our square by the center point. This computes the rect for the
+// square given that point.
+pp::Rect SquareForPoint(int x, int y) {
+ return PP_MakeRectFromXYWH(x - kSquareRadius, y - kSquareRadius,
+ kSquareRadius * 2 + 1, kSquareRadius * 2 + 1);
+}
+
+static void FillRect(pp::ImageData* image,
+ int left, int top, int width, int height,
+ uint32_t color) {
+ for (int y = std::max(0, top);
+ y < std::min(image->size().height() - 1, top + height);
+ y++) {
+ for (int x = std::max(0, left);
+ x < std::min(image->size().width() - 1, left + width);
+ x++)
+ *image->GetAddr32(pp::Point(x, y)) = color;
+ }
+}
+
+class MyInstance : public pp::Instance, public pp::PaintManager::Client {
+ public:
+ MyInstance(PP_Instance instance)
+ : pp::Instance(instance),
+ paint_manager_(),
+ last_x_(0),
+ last_y_(0) {
+ paint_manager_.Initialize(this, this, false);
+ }
+
+ virtual bool HandleEvent(const PP_InputEvent& event) {
+ switch (event.type) {
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
+ const PP_InputEvent_Mouse& mouse_event = event.u.mouse;
+ // Update the square on a mouse down.
+ if (mouse_event.button == PP_INPUTEVENT_MOUSEBUTTON_LEFT) {
+ UpdateSquare(static_cast<int>(mouse_event.x),
+ static_cast<int>(mouse_event.y));
+ }
+ return true;
+ }
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE: {
+ const PP_InputEvent_Mouse& mouse_event = event.u.mouse;
+ // Update the square on a drag.
+ if (mouse_event.button == PP_INPUTEVENT_MOUSEBUTTON_LEFT) {
+ UpdateSquare(static_cast<int>(mouse_event.x),
+ static_cast<int>(mouse_event.y));
+ }
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ virtual void ViewChanged(const pp::Rect& position, const pp::Rect& clip) {
+ paint_manager_.SetSize(position.size());
+ }
+
+ // PaintManager::Client implementation.
+ virtual bool OnPaint(pp::Graphics2D& device,
+ const std::vector<pp::Rect>& paint_rects,
+ const pp::Rect& paint_bounds) {
+ // Make an image just large enough to hold all dirty rects. We won't
+ // actually paint all of these pixels below, but rather just the dirty
+ // ones. Since image allocation can be somewhat heavyweight, we wouldn't
+ // want to allocate separate images in the case of multiple dirty rects.
+ pp::ImageData updated_image(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ paint_bounds.size(), false);
+
+ // We could repaint everything inside the image we made above. For this
+ // example, that would probably be the easiest thing since updates are
+ // small and typically close to each other. However, for the purposes of
+ // demonstration, here we only actually paint the pixels that changed,
+ // which may be the entire update region, or could be multiple discontigous
+ // regions inside the update region.
+ //
+ // Note that the aggregator used by the paint manager won't give us
+ // multiple regions that overlap, so we don't have to worry about double
+ // painting in this code.
+ for (size_t i = 0; i < paint_rects.size(); i++) {
+ // Since our image is just the invalid region, we need to offset the
+ // areas we paint by that much. This is just a light blue background.
+ FillRect(&updated_image,
+ paint_rects[i].x() - paint_bounds.x(),
+ paint_rects[i].y() - paint_bounds.y(),
+ paint_rects[i].width(),
+ paint_rects[i].height(),
+ 0xFFAAAAFF);
+ }
+
+ // Paint the square black. Because we're lazy, we do this outside of the
+ // loop above.
+ pp::Rect square = SquareForPoint(last_x_, last_y_);
+ FillRect(&updated_image,
+ square.x() - paint_bounds.x(),
+ square.y() - paint_bounds.y(),
+ square.width(),
+ square.height(),
+ 0xFF000000);
+
+ return true;
+ }
+
+ private:
+ void UpdateSquare(int x, int y) {
+ if (x == last_x_ && y == last_y_)
+ return; // Nothing changed.
+
+ // Invalidate the region around the old square which needs to be repainted
+ // because it's no longer there.
+ paint_manager_.InvalidateRect(SquareForPoint(last_x_, last_y_));
+
+ // Update the current position.
+ last_x_ = x;
+ last_y_ = y;
+
+ // Also invalidate the region around the new square.
+ paint_manager_.InvalidateRect(SquareForPoint(last_x_, last_y_));
+ }
+
+ pp::PaintManager paint_manager_;
+
+ int last_x_;
+ int last_y_;
+};
+
+class MyModule : public pp::Module {
+ public:
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new MyInstance(instance);
+ }
+};
+
+namespace pp {
+
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+ return new MyModule();
+}
+
+} // namespace pp
diff --git a/ppapi/examples/2d/scroll.cc b/ppapi/examples/2d/scroll.cc
new file mode 100644
index 0000000..b570ae1
--- /dev/null
+++ b/ppapi/examples/2d/scroll.cc
@@ -0,0 +1,119 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <math.h>
+
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/paint_manager.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/var.h"
+
+static const int kSquareSpacing = 98;
+static const int kSquareSize = 5;
+
+static const int kAdvanceXPerFrame = 0;
+static const int kAdvanceYPerFrame = -3;
+
+void FillRect(pp::ImageData* image, const pp::Rect& rect, uint32_t color) {
+ for (int y = std::max(0, rect.y());
+ y < std::min(image->size().height(), rect.bottom());
+ y++) {
+ for (int x = std::max(0, rect.x());
+ x < std::min(image->size().width(), rect.right());
+ x++)
+ *image->GetAddr32(pp::Point(x, y)) = color;
+ }
+}
+
+class MyInstance : public pp::Instance, public pp::PaintManager::Client {
+ public:
+ MyInstance(PP_Instance instance)
+ : pp::Instance(instance),
+ current_step_(0),
+ kicked_off_(false) {
+ factory_.Initialize(this);
+ paint_manager_.Initialize(this, this, false);
+ }
+
+ virtual void ViewChanged(const pp::Rect& position, const pp::Rect& clip) {
+ paint_manager_.SetSize(position.size());
+ }
+
+ void OnTimer(int32_t) {
+ pp::Module::Get()->core()->CallOnMainThread(
+ 16, factory_.NewCallback(&MyInstance::OnTimer), 0);
+ // The scroll and the invalidate will do the same thing in this example,
+ // but the invalidate will cause a large repaint, whereas the scroll will
+ // be faster and cause a smaller repaint.
+#if 1
+ paint_manager_.ScrollRect(pp::Rect(paint_manager_.graphics().size()),
+ pp::Point(kAdvanceXPerFrame, kAdvanceYPerFrame));
+#else
+ paint_manager_.Invalidate();
+#endif
+ current_step_++;
+ }
+
+ private:
+ // PaintManager::Client implementation.
+ virtual bool OnPaint(pp::Graphics2D& device,
+ const std::vector<pp::Rect>& paint_rects,
+ const pp::Rect& paint_bounds) {
+ if (!kicked_off_) {
+ pp::Module::Get()->core()->CallOnMainThread(
+ 16, factory_.NewCallback(&MyInstance::OnTimer), 0);
+ kicked_off_ = true;
+ }
+
+ // Paint the background.
+ pp::ImageData updated_image(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ paint_bounds.size(), false);
+ FillRect(&updated_image, pp::Rect(updated_image.size()), 0xFF8888FF);
+
+ int x_origin = current_step_ * kAdvanceXPerFrame;
+ int y_origin = current_step_ * kAdvanceYPerFrame;
+
+ int x_offset = x_origin % kSquareSpacing;
+ int y_offset = y_origin % kSquareSpacing;
+
+ for (int ys = 0; ys < device.size().height() / kSquareSpacing + 2; ys++) {
+ for (int xs = 0; xs < device.size().width() / kSquareSpacing + 2; xs++) {
+ int x = xs * kSquareSpacing + x_offset - paint_bounds.x();
+ int y = ys * kSquareSpacing + y_offset - paint_bounds.y();
+ FillRect(&updated_image, pp::Rect(x, y, kSquareSize, kSquareSize),
+ 0xFF000000);
+ }
+ }
+ device.PaintImageData(updated_image, paint_bounds.point());
+ return true;
+ }
+
+ pp::CompletionCallbackFactory<MyInstance> factory_;
+
+ pp::PaintManager paint_manager_;
+
+ int current_step_;
+
+ bool kicked_off_;
+};
+
+class MyModule : public pp::Module {
+ public:
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new MyInstance(instance);
+ }
+};
+
+namespace pp {
+
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+ return new MyModule();
+}
+
+} // namespace pp
diff --git a/ppapi/examples/audio/audio.cc b/ppapi/examples/audio/audio.cc
new file mode 100644
index 0000000..8f80ba4
--- /dev/null
+++ b/ppapi/examples/audio/audio.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cmath>
+#include <limits>
+
+#include "ppapi/cpp/dev/audio_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+
+// Separate left and right frequency to make sure we didn't swap L & R.
+// Sounds pretty horrible, though...
+const double frequency_l = 200;
+const double frequency_r = 1000;
+
+// This sample frequency is guaranteed to work.
+const PP_AudioSampleRate_Dev sample_frequency = PP_AUDIOSAMPLERATE_44100;
+const uint32_t sample_count = 4096;
+
+class MyInstance : public pp::Instance {
+ public:
+ explicit MyInstance(PP_Instance instance)
+ : pp::Instance(instance),
+ audio_time_(0) {
+ }
+
+ virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
+ audio_ = pp::Audio_Dev(
+ *this, pp::AudioConfig_Dev(sample_frequency, sample_count),
+ SineWaveCallback, this);
+ return audio_.StartPlayback();
+ }
+
+ private:
+ static void SineWaveCallback(void* samples,
+ size_t buffer_size_in_bytes,
+ void* thiz) {
+ const double th_l = 2 * 3.141592653589 * frequency_l / sample_frequency;
+ const double th_r = 2 * 3.141592653589 * frequency_r / sample_frequency;
+
+ // Store time value to avoid clicks on buffer boundries.
+ size_t t = reinterpret_cast<MyInstance*>(thiz)->audio_time_;
+
+ uint16_t* buf = reinterpret_cast<uint16_t*>(samples);
+ for (size_t buffer_index = 0u;
+ buffer_index < buffer_size_in_bytes;
+ buffer_index += 2) {
+ *buf++ = static_cast<uint16_t>(std::sin(th_l * t)
+ * std::numeric_limits<uint16_t>::max());
+ *buf++ = static_cast<uint16_t>(std::sin(th_r * t++)
+ * std::numeric_limits<uint16_t>::max());
+ }
+ reinterpret_cast<MyInstance*>(thiz)->audio_time_ = t;
+ }
+
+ // Audio resource. Allocated in Init(), freed on destruction.
+ pp::Audio_Dev audio_;
+
+ // Audio buffer time. Used to make prevent sine wave skips on buffer
+ // boundaries.
+ size_t audio_time_;
+};
+
+class MyModule : public pp::Module {
+ public:
+ // Override CreateInstance to create your customized Instance object.
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new MyInstance(instance);
+ }
+};
+
+namespace pp {
+
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+ return new MyModule();
+}
+
+} // namespace pp
diff --git a/ppapi/examples/file_chooser/file_chooser.cc b/ppapi/examples/file_chooser/file_chooser.cc
new file mode 100644
index 0000000..22af29f
--- /dev/null
+++ b/ppapi/examples/file_chooser/file_chooser.cc
@@ -0,0 +1,107 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/c/dev/ppb_file_chooser_dev.h"
+#include "ppapi/c/pp_input_event.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_chooser_dev.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+
+class MyInstance : public pp::Instance {
+ public:
+ MyInstance(PP_Instance instance)
+ : pp::Instance(instance) {
+ callback_factory_.Initialize(this);
+ }
+
+ virtual bool HandleEvent(const PP_InputEvent& event) {
+ switch (event.type) {
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
+ const PP_InputEvent_Mouse& mouse_event = event.u.mouse;
+ if (mouse_event.button == PP_INPUTEVENT_MOUSEBUTTON_LEFT)
+ ShowFileChooser(false);
+ else if (mouse_event.button == PP_INPUTEVENT_MOUSEBUTTON_RIGHT)
+ ShowFileChooser(true);
+ else
+ return false;
+
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ private:
+ void ShowFileChooser(bool multi_select) {
+ RecreateConsole();
+
+ PP_FileChooserOptions_Dev options;
+ options.mode = (multi_select ? PP_FILECHOOSERMODE_OPENMULTIPLE :
+ PP_FILECHOOSERMODE_OPEN);
+ options.accept_mime_types = (multi_select ? "" : "plain/text");
+
+ // Deleted in ShowSelectedFileNames().
+ pp::FileChooser_Dev* file_chooser = new pp::FileChooser_Dev(
+ *this, options);
+ file_chooser->Show(callback_factory_.NewCallback(
+ &MyInstance::ShowSelectedFileNames, file_chooser));
+ }
+
+ void ShowSelectedFileNames(int32_t, pp::FileChooser_Dev* file_chooser) {
+ if (!file_chooser)
+ return;
+
+ pp::FileRef_Dev file_ref = file_chooser->GetNextChosenFile();
+ while (!file_ref.is_null()) {
+ Log(file_ref.GetPath());
+ file_ref = file_chooser->GetNextChosenFile();
+ }
+
+ delete file_chooser;
+ }
+
+ void RecreateConsole() {
+ pp::Var doc = GetWindowObject().GetProperty("document");
+ pp::Var body = doc.GetProperty("body");
+ if (!console_.is_undefined())
+ body.Call("removeChild", console_);
+
+ console_ = doc.Call("createElement", "pre");
+ console_.SetProperty("id", "console");
+ console_.GetProperty("style").SetProperty("backgroundColor", "lightgray");
+ body.Call("appendChild", console_);
+ }
+
+ void Log(const pp::Var& var) {
+ pp::Var doc = GetWindowObject().GetProperty("document");
+ console_.Call("appendChild", doc.Call("createTextNode", var));
+ console_.Call("appendChild", doc.Call("createTextNode", "\n"));
+ }
+
+ pp::CompletionCallbackFactory<MyInstance> callback_factory_;
+ pp::Var console_;
+};
+
+class MyModule : public pp::Module {
+ public:
+ MyModule() : pp::Module() {}
+ virtual ~MyModule() {}
+
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new MyInstance(instance);
+ }
+};
+
+namespace pp {
+
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+ return new MyModule();
+}
+
+} // namespace pp
diff --git a/ppapi/examples/font/simple_font.cc b/ppapi/examples/font/simple_font.cc
new file mode 100644
index 0000000..26c8c2d
--- /dev/null
+++ b/ppapi/examples/font/simple_font.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/font_dev.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/size.h"
+
+static void DummyCompletionCallback(void* /*user_data*/, int32_t /*result*/) {
+}
+
+class MyInstance : public pp::Instance {
+ public:
+ MyInstance(PP_Instance instance)
+ : pp::Instance(instance) {
+ }
+
+ virtual void ViewChanged(const pp::Rect& position, const pp::Rect& clip) {
+ if (position.size() == last_size_)
+ return;
+ last_size_ = position.size();
+
+ pp::ImageData image(PP_IMAGEDATAFORMAT_BGRA_PREMUL, last_size_, true);
+ pp::Graphics2D device(last_size_, false);
+ BindGraphics(device);
+
+ pp::FontDescription_Dev desc;
+ desc.set_family(PP_FONTFAMILY_SANSSERIF);
+ desc.set_size(30);
+ pp::Font_Dev font(desc);
+
+ pp::Rect text_clip(position.size()); // Use entire bounds for clip.
+ font.DrawTextAt(&image,
+ pp::TextRun_Dev("\xD9\x85\xD8\xB1\xD8\xAD\xD8\xA8\xD8\xA7\xE2\x80\x8E",
+ true, true),
+ pp::Point(10, 40), 0xFF008000, clip, false);
+ font.DrawTextAt(&image, pp::TextRun_Dev("Hello"),
+ pp::Point(10, 80), 0xFF000080, text_clip, false);
+
+ device.PaintImageData(image, pp::Point(0, 0));
+ device.Flush(pp::CompletionCallback(&DummyCompletionCallback, NULL));
+ }
+
+ private:
+ pp::Size last_size_;
+};
+
+class MyModule : public pp::Module {
+ public:
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new MyInstance(instance);
+ }
+};
+
+namespace pp {
+
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+ return new MyModule();
+}
+
+} // namespace pp
diff --git a/ppapi/examples/stub/stub.c b/ppapi/examples/stub/stub.c
new file mode 100644
index 0000000..8786669
--- /dev/null
+++ b/ppapi/examples/stub/stub.c
@@ -0,0 +1,35 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is the simplest possible C Pepper plugin that does nothing. If you're
+// using C++, you will want to look at stub.cc which uses the more convenient
+// C++ wrappers.
+
+#include <stddef.h>
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/ppb.h"
+#include "ppapi/c/ppp.h"
+
+PP_Module g_module_id;
+PPB_GetInterface g_get_browser_interface = NULL;
+
+PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id,
+ PPB_GetInterface get_browser_interface) {
+ // Save the global module information for later.
+ g_module_id = module_id;
+ g_get_browser_interface = get_browser_interface;
+
+ return PP_OK;
+}
+
+PP_EXPORT void PPP_ShutdownModule() {
+}
+
+PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
+ // You will normally implement a getter for at least PPP_INSTANCE_INTERFACE
+ // here.
+ return NULL;
+}
diff --git a/ppapi/examples/stub/stub.cc b/ppapi/examples/stub/stub.cc
new file mode 100644
index 0000000..41628a3
--- /dev/null
+++ b/ppapi/examples/stub/stub.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+
+// This is the simplest possible C++ Pepper plugin that does nothing.
+
+// This object represents one time the page says <embed>.
+class MyInstance : public pp::Instance {
+ public:
+ explicit MyInstance(PP_Instance instance) : pp::Instance(instance) {}
+ virtual ~MyInstance() {}
+
+ virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
+ return true;
+ }
+};
+
+// This object is the global object representing this plugin library as long
+// as it is loaded.
+class MyModule : public pp::Module {
+ public:
+ MyModule() : pp::Module() {}
+ virtual ~MyModule() {}
+
+ // Override CreateInstance to create your customized Instance object.
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new MyInstance(instance);
+ }
+};
+
+namespace pp {
+
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+ return new MyModule();
+}
+
+} // namespace pp
diff --git a/ppapi/ppapi.gyp b/ppapi/ppapi.gyp
new file mode 100644
index 0000000..13b1dd6
--- /dev/null
+++ b/ppapi/ppapi.gyp
@@ -0,0 +1,465 @@
+# Copyright (c) 2010 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+
+{
+ 'variables': {
+ 'chromium_code': 1, # Use higher warning level.
+ },
+ 'target_defaults': {
+ 'conditions': [
+ # Linux shared libraries should always be built -fPIC.
+ #
+ # TODO(ajwong): For internal pepper plugins, which are statically linked
+ # into chrome, do we want to build w/o -fPIC? If so, how can we express
+ # that in the build system?
+ ['OS=="linux" or OS=="openbsd" or OS=="freebsd" or OS=="solaris"', {
+ 'cflags': ['-fPIC', '-fvisibility=hidden'],
+
+ # This is needed to make the Linux shlib build happy. Without this,
+ # -fvisibility=hidden gets stripped by the exclusion in common.gypi
+ # that is triggered when a shared library build is specified.
+ 'cflags/': [['include', '^-fvisibility=hidden$']],
+ }],
+ ],
+ },
+ 'targets': [
+ {
+ 'target_name': 'ppapi_c',
+ 'type': 'none',
+ 'all_dependent_settings': {
+ 'include_dirs': [
+ '..',
+ ],
+ },
+ 'sources': [
+ 'c/pp_completion_callback.h',
+ 'c/pp_errors.h',
+ 'c/pp_input_event.h',
+ 'c/pp_instance.h',
+ 'c/pp_module.h',
+ 'c/pp_point.h',
+ 'c/pp_rect.h',
+ 'c/pp_resource.h',
+ 'c/pp_size.h',
+ 'c/pp_stdint.h',
+ 'c/pp_time.h',
+ 'c/pp_var.h',
+ 'c/ppb.h',
+ 'c/ppb_core.h',
+ 'c/ppb_class.h',
+ 'c/ppb_graphics_2d.h',
+ 'c/ppb_image_data.h',
+ 'c/ppb_instance.h',
+ 'c/ppb_var.h',
+ 'c/ppp.h',
+ 'c/ppp_instance.h',
+
+ # Dev interfaces.
+ 'c/dev/pp_cursor_type_dev.h',
+ 'c/dev/pp_file_info_dev.h',
+ 'c/dev/pp_video_dev.h',
+ 'c/dev/ppb_audio_config_dev.h',
+ 'c/dev/ppb_audio_dev.h',
+ 'c/dev/ppb_audio_trusted_dev.h',
+ 'c/dev/ppb_buffer_dev.h',
+ 'c/dev/ppb_char_set_dev.h',
+ 'c/dev/ppb_cursor_control_dev.h',
+ 'c/dev/ppb_directory_reader_dev.h',
+ 'c/dev/ppb_file_chooser_dev.h',
+ 'c/dev/ppb_file_io_dev.h',
+ 'c/dev/ppb_file_io_trusted_dev.h',
+ 'c/dev/ppb_file_ref_dev.h',
+ 'c/dev/ppb_file_system_dev.h',
+ 'c/dev/ppb_find_dev.h',
+ 'c/dev/ppb_font_dev.h',
+ 'c/dev/ppb_fullscreen_dev.h',
+ 'c/dev/ppb_graphics_3d_dev.h',
+ 'c/dev/ppb_opengles_dev.h',
+ 'c/dev/ppb_scrollbar_dev.h',
+ 'c/dev/ppb_testing_dev.h',
+ 'c/dev/ppb_transport_dev.h',
+ 'c/dev/ppb_url_loader_dev.h',
+ 'c/dev/ppb_url_loader_trusted_dev.h',
+ 'c/dev/ppb_url_request_info_dev.h',
+ 'c/dev/ppb_url_response_info_dev.h',
+ 'c/dev/ppb_url_util_dev.h',
+ 'c/dev/ppb_video_decoder_dev.h',
+ 'c/dev/ppb_zoom_dev.h',
+ 'c/dev/ppp_cursor_control_dev.h',
+ 'c/dev/ppp_find_dev.h',
+ 'c/dev/ppp_graphics_3d_dev.h',
+ 'c/dev/ppp_scrollbar_dev.h',
+ 'c/dev/ppp_selection_dev.h',
+ 'c/dev/ppp_printing_dev.h',
+ 'c/dev/ppp_widget_dev.h',
+ 'c/dev/ppp_zoom_dev.h',
+
+ # Deprecated interfaces.
+ 'c/dev/ppb_var_deprecated.h',
+ 'c/dev/ppp_class_deprecated.h',
+ ],
+ },
+ {
+ 'target_name': 'ppapi_cpp_objects',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'ppapi_c'
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'cpp/completion_callback.h',
+ 'cpp/core.cc',
+ 'cpp/core.h',
+ 'cpp/graphics_2d.cc',
+ 'cpp/graphics_2d.h',
+ 'cpp/image_data.cc',
+ 'cpp/image_data.h',
+ 'cpp/instance.cc',
+ 'cpp/instance.h',
+ 'cpp/logging.h',
+ 'cpp/module.cc',
+ 'cpp/module.h',
+ 'cpp/module_impl.h',
+ 'cpp/paint_aggregator.cc',
+ 'cpp/paint_aggregator.h',
+ 'cpp/paint_manager.cc',
+ 'cpp/paint_manager.h',
+ 'cpp/point.h',
+ 'cpp/rect.cc',
+ 'cpp/rect.h',
+ 'cpp/resource.cc',
+ 'cpp/resource.h',
+ 'cpp/size.h',
+ 'cpp/var.cc',
+ 'cpp/var.h',
+
+ # Dev interfaces.
+ 'cpp/dev/audio_config_dev.cc',
+ 'cpp/dev/audio_config_dev.h',
+ 'cpp/dev/audio_dev.cc',
+ 'cpp/dev/audio_dev.h',
+ 'cpp/dev/buffer_dev.cc',
+ 'cpp/dev/buffer_dev.h',
+ 'cpp/dev/directory_entry_dev.cc',
+ 'cpp/dev/directory_entry_dev.h',
+ 'cpp/dev/directory_reader_dev.cc',
+ 'cpp/dev/directory_reader_dev.h',
+ 'cpp/dev/file_chooser_dev.cc',
+ 'cpp/dev/file_chooser_dev.h',
+ 'cpp/dev/file_io_dev.cc',
+ 'cpp/dev/file_io_dev.h',
+ 'cpp/dev/file_ref_dev.cc',
+ 'cpp/dev/file_ref_dev.h',
+ 'cpp/dev/file_system_dev.cc',
+ 'cpp/dev/file_system_dev.h',
+ 'cpp/dev/find_dev.cc',
+ 'cpp/dev/find_dev.h',
+ 'cpp/dev/font_dev.cc',
+ 'cpp/dev/font_dev.h',
+ 'cpp/dev/fullscreen_dev.cc',
+ 'cpp/dev/fullscreen_dev.h',
+ 'cpp/dev/graphics_3d_client_dev.cc',
+ 'cpp/dev/graphics_3d_client_dev.h',
+ 'cpp/dev/graphics_3d_dev.cc',
+ 'cpp/dev/graphics_3d_dev.h',
+ 'cpp/dev/printing_dev.cc',
+ 'cpp/dev/printing_dev.h',
+ 'cpp/dev/scrollbar_dev.cc',
+ 'cpp/dev/scrollbar_dev.h',
+ 'cpp/dev/selection_dev.cc',
+ 'cpp/dev/selection_dev.h',
+ 'cpp/dev/transport_dev.cc',
+ 'cpp/dev/transport_dev.h',
+ 'cpp/dev/url_loader_dev.cc',
+ 'cpp/dev/url_loader_dev.h',
+ 'cpp/dev/url_request_info_dev.cc',
+ 'cpp/dev/url_request_info_dev.h',
+ 'cpp/dev/url_response_info_dev.cc',
+ 'cpp/dev/url_response_info_dev.h',
+ 'cpp/dev/url_util_dev.cc',
+ 'cpp/dev/url_util_dev.h',
+ 'cpp/dev/video_decoder_dev.cc',
+ 'cpp/dev/video_decoder_dev.h',
+ 'cpp/dev/widget_client_dev.cc',
+ 'cpp/dev/widget_client_dev.h',
+ 'cpp/dev/widget_dev.cc',
+ 'cpp/dev/widget_dev.h',
+ 'cpp/dev/zoom_dev.cc',
+ 'cpp/dev/zoom_dev.h',
+
+ # Deprecated interfaces.
+ 'cpp/dev/scriptable_object_deprecated.h',
+ 'cpp/dev/scriptable_object_deprecated.cc',
+ ],
+ 'conditions': [
+ ['OS=="win"', {
+ 'msvs_guid': 'AD371A1D-3459-4E2D-8E8A-881F4B83B908',
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'AdditionalOptions': ['/we4244'], # implicit conversion, possible loss of data
+ },
+ },
+ }],
+ ['OS=="linux"', {
+ 'cflags': ['-Wextra', '-pedantic'],
+ }],
+ ['OS=="mac"', {
+ 'xcode_settings': {
+ 'WARNING_CFLAGS': ['-Wextra', '-pedantic'],
+ },
+ }]
+ ],
+ },
+ {
+ 'target_name': 'ppapi_cpp',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'ppapi_c',
+ 'ppapi_cpp_objects',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'cpp/module_embedder.h',
+ 'cpp/ppp_entrypoints.cc',
+ ],
+ 'conditions': [
+ ['OS=="win"', {
+ 'msvs_guid': '057E7FA0-83C0-11DF-8395-0800200C9A66',
+ }],
+ ['OS=="linux"', {
+ 'cflags': ['-Wextra', '-pedantic'],
+ }],
+ ['OS=="mac"', {
+ 'xcode_settings': {
+ 'WARNING_CFLAGS': ['-Wextra', '-pedantic'],
+ },
+ }]
+ ],
+ },
+ {
+ 'target_name': 'ppapi_example',
+ 'dependencies': [
+ 'ppapi_cpp'
+ ],
+ 'xcode_settings': {
+ 'INFOPLIST_FILE': 'example/Info.plist',
+ },
+ 'sources': [
+ 'example/example.cc',
+ ],
+ 'conditions': [
+ ['OS=="win"', {
+ 'product_name': 'ppapi_example',
+ 'type': 'shared_library',
+ 'msvs_guid': 'EE00E36E-9E8C-4DFB-925E-FBE32CEDB91B',
+ 'sources': [
+ 'example/example.rc',
+ ],
+ 'run_as': {
+ 'action': [
+ '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)chrome<(EXECUTABLE_SUFFIX)',
+ '--register-pepper-plugins=$(TargetPath);application/x-ppapi-example',
+ 'file://$(ProjectDir)/example/example.html',
+ ],
+ },
+ }],
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
+ 'product_name': 'ppapi_example',
+ 'type': 'shared_library',
+ 'cflags': ['-fvisibility=hidden'],
+ # -gstabs, used in the official builds, causes an ICE. Simply remove
+ # it.
+ 'cflags!': ['-gstabs'],
+ }],
+ ['OS=="mac"', {
+ 'type': 'loadable_module',
+ 'mac_bundle': 1,
+ 'product_name': 'PPAPIExample',
+ 'product_extension': 'plugin',
+ 'sources+': [
+ 'example/Info.plist'
+ ],
+ }],
+ ],
+ # See README for instructions on how to run and debug on the Mac.
+ #'conditions' : [
+ # ['OS=="mac"', {
+ # 'target_name' : 'Chromium',
+ # 'type' : 'executable',
+ # 'xcode_settings' : {
+ # 'ARGUMENTS' : '--renderer-startup-dialog --internal-pepper --no-sandbox file://${SRCROOT}/test_page.html'
+ # },
+ # }],
+ #],
+ },
+ {
+ 'target_name': 'ppapi_example_skeleton',
+ 'type': 'none',
+ 'dependencies': [
+ 'ppapi_cpp',
+ ],
+ 'export_dependent_setting': ['ppapi_cpp'],
+ 'direct_dependent_settings': {
+ 'product_name': '>(_target_name)',
+ 'conditions': [
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
+ 'type': 'shared_library',
+ 'cflags': ['-fvisibility=hidden'],
+ # -gstabs, used in the official builds, causes an ICE. Simply remove
+ # it.
+ 'cflags!': ['-gstabs'],
+ }],
+ # TODO(ppapi authors): Make the examples build on Windows & Mac
+ ['OS=="win"', {
+ 'suppress_wildcard': 1,
+ 'type': 'shared_library',
+ }],
+ ['OS=="mac"', {
+ 'suppress_wildcard': 1,
+ 'type': 'loadable_module',
+ }],
+ ],
+ },
+ },
+ {
+ 'target_name': 'ppapi_example_c_stub',
+ 'dependencies': [
+ 'ppapi_example_skeleton',
+ ],
+ 'sources': [
+ 'examples/stub/stub.c',
+ ],
+ },
+ {
+ 'target_name': 'ppapi_example_cc_stub',
+ 'dependencies': [
+ 'ppapi_example_skeleton',
+ ],
+ 'sources': [
+ 'examples/stub/stub.cc',
+ ],
+ },
+ {
+ 'target_name': 'ppapi_example_audio',
+ 'dependencies': [
+ 'ppapi_example_skeleton',
+ ],
+ 'sources': [
+ 'examples/audio/audio.cc',
+ ],
+ },
+ {
+ 'target_name': 'ppapi_example_file_chooser',
+ 'dependencies': [
+ 'ppapi_example_skeleton',
+ ],
+ 'sources': [
+ 'examples/file_chooser/file_chooser.cc',
+ ],
+ },
+#TODO(ppapi authors): Fix the C headers so that they are C compatible.
+# {
+# 'target_name': 'ppapi_example_graphics_2d',
+# 'dependencies': [
+# 'ppapi_example_skeleton',
+# ],
+# 'sources': [
+# 'examples/2d/graphics_2d_example.c',
+# ],
+# },
+ {
+ 'target_name': 'ppapi_example_paint_manager',
+ 'dependencies': [
+ 'ppapi_example_skeleton',
+ ],
+ 'sources': [
+ 'examples/2d/paint_manager_example.cc',
+ ],
+ },
+ {
+ 'target_name': 'ppapi_example_scroll',
+ 'dependencies': [
+ 'ppapi_example_skeleton',
+ ],
+ 'sources': [
+ 'examples/2d/scroll.cc',
+ ],
+ },
+ {
+ 'target_name': 'ppapi_example_simple_font',
+ 'dependencies': [
+ 'ppapi_example_skeleton',
+ ],
+ 'sources': [
+ 'examples/font/simple_font.cc',
+ ],
+ },
+ {
+ 'target_name': 'ppapi_tests',
+ 'type': 'loadable_module',
+ 'sources': [
+ # Common test files.
+ 'tests/test_case.cc',
+ 'tests/test_case.h',
+ 'tests/testing_instance.cc',
+ 'tests/testing_instance.h',
+
+ # Test cases.
+ 'tests/test_buffer.cc',
+ 'tests/test_buffer.h',
+ 'tests/test_char_set.cc',
+ 'tests/test_char_set.h',
+ 'tests/test_file_io.cc',
+ 'tests/test_file_io.h',
+ 'tests/test_file_ref.cc',
+ 'tests/test_file_ref.h',
+ 'tests/test_graphics_2d.cc',
+ 'tests/test_graphics_2d.h',
+ 'tests/test_image_data.cc',
+ 'tests/test_image_data.h',
+ 'tests/test_paint_aggregator.cc',
+ 'tests/test_paint_aggregator.h',
+ 'tests/test_scrollbar.cc',
+ 'tests/test_scrollbar.h',
+ 'tests/test_transport.cc',
+ 'tests/test_transport.h',
+ 'tests/test_url_loader.cc',
+ 'tests/test_url_loader.h',
+ 'tests/test_url_util.cc',
+ 'tests/test_url_util.h',
+ 'tests/test_var.cc',
+ 'tests/test_var.h',
+
+ # Deprecated test cases.
+ 'tests/test_instance_deprecated.cc',
+ 'tests/test_instance_deprecated.h',
+ 'tests/test_var_deprecated.cc',
+ 'tests/test_var_deprecated.h',
+ ],
+ 'dependencies': [
+ 'ppapi_cpp'
+ ],
+ 'conditions': [
+ ['OS=="win"', {
+ 'defines': [
+ '_CRT_SECURE_NO_DEPRECATE',
+ '_CRT_NONSTDC_NO_WARNINGS',
+ '_CRT_NONSTDC_NO_DEPRECATE',
+ '_SCL_SECURE_NO_DEPRECATE',
+ ],
+ }],
+ ['OS=="mac"', {
+ 'mac_bundle': 1,
+ 'product_name': 'ppapi_tests',
+ 'product_extension': 'plugin',
+ }],
+ ],
+ },
+ ],
+}
diff --git a/ppapi/tests/test_buffer.cc b/ppapi/tests/test_buffer.cc
new file mode 100644
index 0000000..c920271
--- /dev/null
+++ b/ppapi/tests/test_buffer.cc
@@ -0,0 +1,77 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_buffer.h"
+
+#include "ppapi/c/dev/ppb_buffer_dev.h"
+#include "ppapi/cpp/dev/buffer_dev.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(Buffer);
+
+bool TestBuffer::Init() {
+ buffer_interface_ = reinterpret_cast<PPB_Buffer_Dev const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_BUFFER_DEV_INTERFACE));
+ return !!buffer_interface_;
+}
+
+void TestBuffer::RunTest() {
+ instance_->LogTest("InvalidSize", TestInvalidSize());
+ instance_->LogTest("InitToZero", TestInitToZero());
+ instance_->LogTest("IsBuffer", TestIsBuffer());
+}
+
+std::string TestBuffer::TestInvalidSize() {
+ pp::Buffer_Dev zero_size(0);
+ if (!zero_size.is_null())
+ return "Zero size accepted";
+
+ return "";
+}
+
+std::string TestBuffer::TestInitToZero() {
+ pp::Buffer_Dev buffer(100);
+ if (buffer.is_null())
+ return "Could not create buffer";
+
+ if (buffer.size() != 100)
+ return "Buffer size not as expected";
+
+ // Now check that everything is 0.
+ unsigned char* bytes = static_cast<unsigned char *>(buffer.data());
+ for (int index = 0; index < buffer.size(); index++) {
+ if (bytes[index] != 0)
+ return "Buffer isn't entirely zero";
+ }
+
+ return "";
+}
+
+std::string TestBuffer::TestIsBuffer() {
+ // Test that a NULL resource isn't a buffer.
+ pp::Resource null_resource;
+ if (buffer_interface_->IsBuffer(null_resource.pp_resource()))
+ return "Null resource was reported as a valid buffer";
+
+ // Make another resource type and test it.
+ const int w = 16, h = 16;
+ pp::Graphics2D device(pp::Size(w, h), true);
+ if (device.is_null())
+ return "Couldn't create device context";
+ if (buffer_interface_->IsBuffer(device.pp_resource()))
+ return "Device context was reported as a buffer";
+
+ // Make a valid buffer.
+ pp::Buffer_Dev buffer(100);
+ if (buffer.is_null())
+ return "Couldn't create buffer";
+ if (!buffer_interface_->IsBuffer(buffer.pp_resource()))
+ return "Buffer should be identified as a buffer";
+
+ return "";
+}
+
diff --git a/ppapi/tests/test_buffer.h b/ppapi/tests/test_buffer.h
new file mode 100644
index 0000000..4c78d9d
--- /dev/null
+++ b/ppapi/tests/test_buffer.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PAPPI_TESTS_TEST_BUFFER_H_
+#define PAPPI_TESTS_TEST_BUFFER_H_
+
+#include <string>
+
+#include "ppapi/tests/test_case.h"
+
+struct PPB_Buffer_Dev;
+
+class TestBuffer : public TestCase {
+ public:
+ explicit TestBuffer(TestingInstance* instance) : TestCase(instance) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ private:
+ std::string TestInvalidSize();
+ std::string TestInitToZero();
+ std::string TestIsBuffer();
+
+ // Used by the tests that access the C API directly.
+ const PPB_Buffer_Dev* buffer_interface_;
+};
+
+#endif // PAPPI_TESTS_TEST_BUFFER_H_
diff --git a/ppapi/tests/test_case.cc b/ppapi/tests/test_case.cc
new file mode 100644
index 0000000..a37bfc3
--- /dev/null
+++ b/ppapi/tests/test_case.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_case.h"
+
+#include <sstream>
+
+std::string TestCase::MakeFailureMessage(const char* file,
+ int line,
+ const char* cmd) {
+ // The mere presence of this local variable works around a gcc-4.2.4
+ // compiler bug in official Chrome Linux builds. If you remove it,
+ // confirm this compile command still works:
+ // GYP_DEFINES='branding=Chrome buildtype=Official target_arch=x64'
+ // gclient runhooks
+ // make -k -j4 BUILDTYPE=Release ppapi_tests
+ std::string s;
+
+ std::ostringstream output;
+ output << "Failure in " << file << "(" << line << "): " << cmd;
+ return output.str();
+}
+
+pp::Var TestCase::GetTestObject() {
+ if (test_object_.is_undefined()) {
+ pp::deprecated::ScriptableObject* so = CreateTestObject();
+ if (so)
+ test_object_ = pp::Var(so); // Takes ownership.
+ }
+ return test_object_;
+}
+
+pp::deprecated::ScriptableObject* TestCase::CreateTestObject() {
+ return NULL;
+}
+
diff --git a/ppapi/tests/test_case.h b/ppapi/tests/test_case.h
new file mode 100644
index 0000000..0ca6d8e
--- /dev/null
+++ b/ppapi/tests/test_case.h
@@ -0,0 +1,114 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_TEST_TEST_CASE_H_
+#define PPAPI_TEST_TEST_CASE_H_
+
+#include <string>
+
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/cpp/dev/scrollbar_dev.h"
+#include "ppapi/cpp/var.h"
+
+class TestingInstance;
+
+namespace pp {
+namespace deprecated {
+class ScriptableObject;
+}
+}
+
+// Individual classes of tests derive from this generic test case.
+class TestCase {
+ public:
+ TestCase(TestingInstance* instance) : instance_(instance) {}
+ virtual ~TestCase() {}
+
+ // Optionally override to do testcase specific initialization.
+ virtual bool Init() { return true; }
+
+ // Override to implement the test. It will be called after the plugin is
+ // first displayed.
+ virtual void RunTest() = 0;
+
+ std::string MakeFailureMessage(const char* file, int line, const char* cmd);
+
+ // Returns the scriptable test object for the current test, if any.
+ // Internally, this uses CreateTestObject which each test overrides.
+ pp::Var GetTestObject();
+
+ protected:
+ // Overridden by each test to supply a ScriptableObject corresponding to the
+ // test. There can only be one object created for all test in a given class
+ // so be sure your object is designed to be re-used.
+ //
+ // This object should be created on the heap. Ownership will be passed to the
+ // caller. Return NULL if there is no supported test object (the default).
+ virtual pp::deprecated::ScriptableObject* CreateTestObject();
+
+ // Pointer to the instance that owns us.
+ TestingInstance* instance_;
+
+ private:
+ // Holds the test object, if any was retrieved from CreateTestObject.
+ pp::Var test_object_;
+};
+
+// This class is an implementation detail.
+class TestCaseFactory {
+ public:
+ typedef TestCase* (*Method)(TestingInstance* instance);
+
+ TestCaseFactory(const char* name, Method method)
+ : next_(head_),
+ name_(name),
+ method_(method) {
+ head_ = this;
+ }
+
+ private:
+ friend class TestingInstance;
+
+ TestCaseFactory* next_;
+ const char* name_;
+ Method method_;
+
+ static TestCaseFactory* head_;
+};
+
+// Use the REGISTER_TEST_CASE macro in your TestCase implementation file to
+// register your TestCase. If your test is named TestFoo, then add the
+// following to test_foo.cc:
+//
+// REGISTER_TEST_CASE(Foo);
+//
+// This will cause your test to be included in the set of known tests.
+//
+#define REGISTER_TEST_CASE(name) \
+ static TestCase* Test##name##_FactoryMethod(TestingInstance* instance) { \
+ return new Test##name(instance); \
+ } \
+ static TestCaseFactory g_Test##name_factory( \
+ #name, &Test##name##_FactoryMethod \
+ )
+
+// Helper macro for calling functions implementing specific tests in the
+// RunTest function. This assumes the function name is TestFoo where Foo is the
+// test name,
+#define RUN_TEST(name) \
+ instance_->LogTest(#name, Test##name());
+
+// Helper macros for checking values in tests, and returning a location
+// description of the test fails.
+#define ASSERT_TRUE(cmd) \
+ if (!(cmd)) { \
+ return MakeFailureMessage(__FILE__, __LINE__, #cmd); \
+ }
+#define ASSERT_FALSE(cmd) ASSERT_TRUE(!(cmd))
+#define ASSERT_EQ(a, b) ASSERT_TRUE((a) == (b))
+#define ASSERT_NE(a, b) ASSERT_TRUE((a) != (b))
+
+#define PASS() return std::string()
+
+#endif // PPAPI_TEST_TEST_CASE_H_
diff --git a/ppapi/tests/test_case.html b/ppapi/tests/test_case.html
new file mode 100644
index 0000000..71c305a
--- /dev/null
+++ b/ppapi/tests/test_case.html
@@ -0,0 +1,74 @@
+<html><head>
+<link rel="stylesheet" href="test_page.css">
+<script>
+function AdjustHeight(frameWin) {
+ var div = frameWin.document.getElementsByTagName("div")[0];
+ var height = frameWin.getComputedStyle(div).height;
+ frameWin.frameElement.style.height = height;
+}
+
+function DidExecuteTests() {
+ if (window == top)
+ return;
+
+ // Otherwise, we are in a subframe, so we can use this opportunity to resize
+ // ourselves.
+ AdjustHeight(window);
+}
+
+function AppendFrame(testcase, i) {
+ var p = document.createElement("P");
+ p.setAttribute("class", "frame-container");
+
+ var title = document.createElement("H2");
+ title.appendChild(document.createTextNode(testcase));
+ p.appendChild(title);
+
+ var frame = document.createElement("IFRAME");
+ frame.setAttribute("src", "?" + testcase);
+ frame.setAttribute("onload", "LoadNext(" + (i + 1) + ")");
+ p.appendChild(frame);
+
+ document.body.appendChild(p);
+}
+
+function LoadNext(i) {
+ var links = document.links;
+ if (links.length > i)
+ AppendFrame(links[i].firstChild.nodeValue, i);
+}
+
+function RunAll() {
+ // Remove any existing frames.
+ var existing = document.getElementsByClassName("frame-container");
+ while (existing.length)
+ existing[0].parentNode.removeChild(existing[0]);
+
+ // Add new frames for each test, but do so one frame at a time.
+ LoadNext(0);
+}
+
+onload = function() {
+ var mimeType = "application/x-ppapi-tests";
+ if (mimeType in navigator.mimeTypes) {
+ var testcase = location.search.substring(1);
+ document.title = 'Test ' + testcase;
+
+ var obj = document.createElement("OBJECT");
+ obj.setAttribute("id", "plugin");
+ obj.setAttribute("type", mimeType);
+ obj.setAttribute("testcase", testcase);
+ document.getElementById("container").appendChild(obj);
+ } else {
+ document.getElementById("console").innerHTML =
+ '<span class="fail">FAIL</span>: ' +
+ '<span class="err_msg">Test plug-in is not registered.</span>';
+ }
+}
+</script>
+</head><body>
+<div>
+ <div id="container"></div>
+ <div id="console" /><span class="load_msg">loading...</span></div>
+</div>
+</body></html>
diff --git a/ppapi/tests/test_char_set.cc b/ppapi/tests/test_char_set.cc
new file mode 100644
index 0000000..e97804a
--- /dev/null
+++ b/ppapi/tests/test_char_set.cc
@@ -0,0 +1,167 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_char_set.h"
+
+#include "ppapi/c/dev/ppb_char_set_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(CharSet);
+
+TestCharSet::TestCharSet(TestingInstance* instance)
+ : TestCase(instance),
+ char_set_interface_(NULL) {
+}
+
+bool TestCharSet::Init() {
+ char_set_interface_ = reinterpret_cast<struct PPB_CharSet_Dev const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_CHAR_SET_DEV_INTERFACE));
+ return !!char_set_interface_;
+}
+
+void TestCharSet::RunTest() {
+ RUN_TEST(UTF16ToCharSet);
+ RUN_TEST(CharSetToUTF16);
+}
+
+std::string TestCharSet::TestUTF16ToCharSet() {
+ // Empty string.
+ std::vector<uint16_t> utf16;
+ utf16.push_back(0);
+ uint32_t utf8result_len = 0;
+ char* utf8result = char_set_interface_->UTF16ToCharSet(
+ &utf16[0], 0, "latin1",
+ PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
+ ASSERT_TRUE(utf8result);
+ ASSERT_TRUE(utf8result[0] == 0);
+ ASSERT_TRUE(utf8result_len == 0);
+ pp::Module::Get()->core()->MemFree(utf8result);
+
+ // Try round-tripping some English & Chinese from UTF-8 through UTF-16
+ std::string utf8source("Hello, world. \xe4\xbd\xa0\xe5\xa5\xbd");
+ utf16 = UTF8ToUTF16(utf8source);
+ utf8result = char_set_interface_->UTF16ToCharSet(
+ &utf16[0], static_cast<uint32_t>(utf16.size()), "Utf-8",
+ PP_CHARSET_CONVERSIONERROR_FAIL, &utf8result_len);
+ ASSERT_TRUE(utf8source == std::string(utf8result, utf8result_len));
+ pp::Module::Get()->core()->MemFree(utf8result);
+
+ // Test an un-encodable character with various modes.
+ utf16 = UTF8ToUTF16("h\xe4\xbd\xa0i");
+
+ // Fail mode.
+ utf8result_len = 1234; // Test that this gets 0'ed on failure.
+ utf8result = char_set_interface_->UTF16ToCharSet(
+ &utf16[0], static_cast<uint32_t>(utf16.size()), "latin1",
+ PP_CHARSET_CONVERSIONERROR_FAIL, &utf8result_len);
+ ASSERT_TRUE(utf8result_len == 0);
+ ASSERT_TRUE(utf8result == NULL);
+
+ // Skip mode.
+ utf8result = char_set_interface_->UTF16ToCharSet(
+ &utf16[0], static_cast<uint32_t>(utf16.size()), "latin1",
+ PP_CHARSET_CONVERSIONERROR_SKIP, &utf8result_len);
+ ASSERT_TRUE(utf8result_len == 2);
+ ASSERT_TRUE(utf8result[0] == 'h' && utf8result[1] == 'i' &&
+ utf8result[2] == 0);
+ pp::Module::Get()->core()->MemFree(utf8result);
+
+ // Substitute mode.
+ utf8result = char_set_interface_->UTF16ToCharSet(
+ &utf16[0], static_cast<uint32_t>(utf16.size()), "latin1",
+ PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
+ ASSERT_TRUE(utf8result_len == 3);
+ ASSERT_TRUE(utf8result[0] == 'h' && utf8result[1] == '?' &&
+ utf8result[2] == 'i' && utf8result[3] == 0);
+ pp::Module::Get()->core()->MemFree(utf8result);
+
+ // Try some invalid input encoding.
+ utf16.clear();
+ utf16.push_back(0xD800); // High surrogate.
+ utf16.push_back('A'); // Not a low surrogate.
+ utf8result = char_set_interface_->UTF16ToCharSet(
+ &utf16[0], static_cast<uint32_t>(utf16.size()), "latin1",
+ PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
+ ASSERT_TRUE(utf8result_len == 2);
+ ASSERT_TRUE(utf8result[0] == '?' && utf8result[1] == 'A' &&
+ utf8result[2] == 0);
+ pp::Module::Get()->core()->MemFree(utf8result);
+
+ // Invalid encoding name.
+ utf8result = char_set_interface_->UTF16ToCharSet(
+ &utf16[0], static_cast<uint32_t>(utf16.size()), "poopiepants",
+ PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
+ ASSERT_TRUE(!utf8result);
+ ASSERT_TRUE(utf8result_len == 0);
+
+ return std::string();
+}
+
+std::string TestCharSet::TestCharSetToUTF16() {
+ // Empty string.
+ uint32_t utf16result_len;
+ uint16_t* utf16result = char_set_interface_->CharSetToUTF16(
+ "", 0, "latin1", PP_CHARSET_CONVERSIONERROR_FAIL, &utf16result_len);
+ ASSERT_TRUE(utf16result);
+ ASSERT_TRUE(utf16result_len == 0);
+ ASSERT_TRUE(utf16result[0] == 0);
+
+ // Basic Latin1.
+ char latin1[] = "H\xef";
+ utf16result = char_set_interface_->CharSetToUTF16(
+ latin1, 2, "latin1", PP_CHARSET_CONVERSIONERROR_FAIL, &utf16result_len);
+ ASSERT_TRUE(utf16result);
+ ASSERT_TRUE(utf16result_len == 2);
+ ASSERT_TRUE(utf16result[0] == 'H' && utf16result[1] == 0xef &&
+ utf16result[2] == 0);
+
+ // Invalid input encoding with FAIL.
+ char badutf8[] = "A\xe4Z";
+ utf16result = char_set_interface_->CharSetToUTF16(
+ badutf8, 3, "utf8", PP_CHARSET_CONVERSIONERROR_FAIL, &utf16result_len);
+ ASSERT_TRUE(!utf16result);
+ ASSERT_TRUE(utf16result_len == 0);
+
+ // Invalid input with SKIP.
+ utf16result = char_set_interface_->CharSetToUTF16(
+ badutf8, 3, "utf8", PP_CHARSET_CONVERSIONERROR_SKIP, &utf16result_len);
+ ASSERT_TRUE(utf16result);
+ ASSERT_TRUE(utf16result_len == 2);
+ ASSERT_TRUE(utf16result[0] == 'A' && utf16result[1] == 'Z' &&
+ utf16result[2] == 0);
+
+ // Invalid input with SUBSTITUTE.
+ utf16result = char_set_interface_->CharSetToUTF16(
+ badutf8, 3, "utf8", PP_CHARSET_CONVERSIONERROR_SUBSTITUTE,
+ &utf16result_len);
+ ASSERT_TRUE(utf16result);
+ ASSERT_TRUE(utf16result_len == 3);
+ ASSERT_TRUE(utf16result[0] == 'A' && utf16result[1] == 0xFFFD &&
+ utf16result[2] == 'Z' && utf16result[3] == 0);
+
+ // Invalid encoding name.
+ utf16result = char_set_interface_->CharSetToUTF16(
+ badutf8, 3, "poopiepants",
+ PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf16result_len);
+ ASSERT_TRUE(!utf16result);
+ ASSERT_TRUE(utf16result_len == 0);
+
+ return std::string();
+}
+
+std::vector<uint16_t> TestCharSet::UTF8ToUTF16(const std::string& utf8) {
+ uint32_t result_len = 0;
+ uint16_t* result = char_set_interface_->CharSetToUTF16(
+ utf8.c_str(), static_cast<uint32_t>(utf8.size()),
+ "utf-8", PP_CHARSET_CONVERSIONERROR_FAIL, &result_len);
+
+ std::vector<uint16_t> result_vector;
+ if (!result)
+ return result_vector;
+
+ result_vector.assign(result, &result[result_len]);
+ pp::Module::Get()->core()->MemFree(result);
+ return result_vector;
+}
diff --git a/ppapi/tests/test_char_set.h b/ppapi/tests/test_char_set.h
new file mode 100644
index 0000000..980b29c
--- /dev/null
+++ b/ppapi/tests/test_char_set.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_TESTS_TEST_CHAR_SET_H_
+#define PPAPI_TESTS_TEST_CHAR_SET_H_
+
+#include <string>
+#include <vector>
+
+#include "ppapi/tests/test_case.h"
+
+struct PPB_CharSet_Dev;
+
+class TestCharSet : public TestCase {
+ public:
+ TestCharSet(TestingInstance* instance);
+
+ // TestCase implementation.
+
+ virtual bool Init();
+ virtual void RunTest();
+
+ private:
+ std::string TestUTF16ToCharSet();
+ std::string TestCharSetToUTF16();
+
+ // Converts the given UTF-8 string to a NON-NULL TERMINATED UTF-16 string
+ // stored in the given vector.
+ std::vector<uint16_t> UTF8ToUTF16(const std::string& utf8);
+
+ const struct PPB_CharSet_Dev* char_set_interface_;
+};
+
+#endif // PPAPI_TESTS_TEST_CHAR_SET_H_
diff --git a/ppapi/tests/test_file_io.cc b/ppapi/tests/test_file_io.cc
new file mode 100644
index 0000000..300052d
--- /dev/null
+++ b/ppapi/tests/test_file_io.cc
@@ -0,0 +1,341 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_file_io.h"
+
+#include <stdio.h>
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/dev/ppb_file_io_dev.h"
+#include "ppapi/c/dev/ppb_testing_dev.h"
+#include "ppapi/cpp/dev/file_io_dev.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/dev/file_system_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(FileIO);
+
+namespace {
+
+const PPB_Testing_Dev* g_testing_interface;
+
+class TestCompletionCallback {
+ public:
+ TestCompletionCallback() : result_(PP_ERROR_WOULDBLOCK) {
+ }
+
+ operator pp::CompletionCallback() const {
+ return pp::CompletionCallback(&TestCompletionCallback::Handler,
+ const_cast<TestCompletionCallback*>(this));
+ }
+
+ int32_t WaitForResult() {
+ result_ = PP_ERROR_WOULDBLOCK; // Reset
+ g_testing_interface->RunMessageLoop();
+ return result_;
+ }
+
+ private:
+ static void Handler(void* user_data, int32_t result) {
+ static_cast<TestCompletionCallback*>(user_data)->result_ = result;
+ g_testing_interface->QuitMessageLoop();
+ }
+
+ int32_t result_;
+};
+
+std::string ReportError(const char* method, int32_t error) {
+ char error_as_string[12];
+ sprintf(error_as_string, "%d", error);
+ std::string result = method + std::string(" failed with error: ") +
+ error_as_string;
+ if (error == PP_ERROR_NOSPACE)
+ result += ". Did you run the test with --unlimited-quota-for-files?";
+ return result;
+}
+
+std::string ReportMismatch(const std::string& method_name,
+ const std::string& returned_result,
+ const std::string& expected_result) {
+ return method_name + " returned '" + returned_result + "'; '" +
+ expected_result + "' expected.";
+}
+
+int32_t ReadEntireFile(pp::FileIO_Dev* file_io,
+ int32_t offset,
+ std::string* data) {
+ TestCompletionCallback callback;
+ char buf[256];
+ int32_t read_offset = offset;
+
+ for (;;) {
+ int32_t rv = file_io->Read(read_offset, buf, sizeof(buf), callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv < 0)
+ return rv;
+ if (rv == 0)
+ break;
+ read_offset += rv;
+ data->append(buf, rv);
+ }
+
+ return PP_OK;
+}
+
+int32_t WriteEntireBuffer(pp::FileIO_Dev* file_io,
+ int32_t offset,
+ const std::string& data) {
+ TestCompletionCallback callback;
+ int32_t write_offset = offset;
+ const char* buf = data.c_str();
+ int32_t size = data.size();
+
+ while (write_offset < offset + size) {
+ int32_t rv = file_io->Write(write_offset, &buf[write_offset - offset],
+ size - write_offset + offset, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv < 0)
+ return rv;
+ if (rv == 0)
+ return PP_ERROR_FAILED;
+ write_offset += rv;
+ }
+
+ return PP_OK;
+}
+
+} // namespace
+
+bool TestFileIO::Init() {
+ g_testing_interface = reinterpret_cast<PPB_Testing_Dev const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE));
+ if (!g_testing_interface) {
+ // Give a more helpful error message for the testing interface being gone
+ // since that needs special enabling in Chrome.
+ instance_->AppendError("This test needs the testing interface, which is "
+ "not currently available. In Chrome, use --enable-pepper-testing when "
+ "launching.");
+ return false;
+ }
+
+ // Make sure we're running over HTTP.
+ pp::Var window = instance_->GetWindowObject();
+ pp::Var location = window.GetProperty("location");
+ pp::Var protocol = location.GetProperty("protocol");
+ if (!protocol.is_string() || protocol.AsString() != "http:") {
+ instance_->AppendError("This test needs to be run over HTTP.");
+ return false;
+ }
+
+ return true;
+}
+
+void TestFileIO::RunTest() {
+ RUN_TEST(Open);
+ RUN_TEST(ReadWriteSetLength);
+ RUN_TEST(TouchQuery);
+}
+
+std::string TestFileIO::TestOpen() {
+ TestCompletionCallback callback;
+
+ pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+ pp::FileRef_Dev file_ref(file_system, "/file_open");
+ int32_t rv = file_system.Open(1024, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Open", rv);
+
+ pp::FileIO_Dev file_io;
+ rv = file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileIO::Open", rv);
+
+ // Try opening a file that doesn't exist.
+ pp::FileRef_Dev nonexistent_file_ref(file_system, "/nonexistent_file");
+ pp::FileIO_Dev nonexistent_file_io;
+ rv = nonexistent_file_io.Open(
+ nonexistent_file_ref, PP_FILEOPENFLAG_READ, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_ERROR_FILENOTFOUND)
+ return ReportError("FileIO::Open", rv);
+
+ return "";
+}
+
+std::string TestFileIO::TestReadWriteSetLength() {
+ TestCompletionCallback callback;
+
+ pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+ pp::FileRef_Dev file_ref(file_system, "/file_read_write_setlength");
+ int32_t rv = file_system.Open(1024, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Open", rv);
+
+ pp::FileIO_Dev file_io;
+ rv = file_io.Open(file_ref,
+ PP_FILEOPENFLAG_CREATE |
+ PP_FILEOPENFLAG_READ |
+ PP_FILEOPENFLAG_WRITE,
+ callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileIO::Open", rv);
+
+ // Write something to the file.
+ rv = WriteEntireBuffer(&file_io, 0, "test_test");
+ if (rv != PP_OK)
+ return ReportError("FileIO::Write", rv);
+
+ // Read the entire file.
+ std::string read_buffer;
+ rv = ReadEntireFile(&file_io, 0, &read_buffer);
+ if (rv != PP_OK)
+ return ReportError("FileIO::Read", rv);
+ if (read_buffer != "test_test")
+ return ReportMismatch("FileIO::Read", read_buffer, "test_test");
+
+ // Truncate the file.
+ rv = file_io.SetLength(4, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileIO::SetLength", rv);
+
+ // Check the file contents.
+ read_buffer.clear();
+ rv = ReadEntireFile(&file_io, 0, &read_buffer);
+ if (rv != PP_OK)
+ return ReportError("FileIO::Read", rv);
+ if (read_buffer != "test")
+ return ReportMismatch("FileIO::Read", read_buffer, "test");
+
+ // Try to read past the end of the file.
+ read_buffer.clear();
+ rv = ReadEntireFile(&file_io, 100, &read_buffer);
+ if (rv != PP_OK)
+ return ReportError("FileIO::Read", rv);
+ if (!read_buffer.empty())
+ return ReportMismatch("FileIO::Read", read_buffer, "<empty string>");
+
+ // Write past the end of the file. The file should be zero-padded.
+ rv = WriteEntireBuffer(&file_io, 8, "test");
+ if (rv != PP_OK)
+ return ReportError("FileIO::Write", rv);
+
+ // Check the contents of the file.
+ read_buffer.clear();
+ rv = ReadEntireFile(&file_io, 0, &read_buffer);
+ if (rv != PP_OK)
+ return ReportError("FileIO::Read", rv);
+ if (read_buffer != std::string("test\0\0\0\0test", 12))
+ return ReportMismatch("FileIO::Read", read_buffer,
+ std::string("test\0\0\0\0test", 12));
+
+ // Extend the file.
+ rv = file_io.SetLength(16, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileIO::SetLength", rv);
+
+ // Check the contents of the file.
+ read_buffer.clear();
+ rv = ReadEntireFile(&file_io, 0, &read_buffer);
+ if (rv != PP_OK)
+ return ReportError("FileIO::Read", rv);
+ if (read_buffer != std::string("test\0\0\0\0test\0\0\0\0", 16))
+ return ReportMismatch("FileIO::Read", read_buffer,
+ std::string("test\0\0\0\0test\0\0\0\0", 16));
+
+ // Write in the middle of the file.
+ rv = WriteEntireBuffer(&file_io, 4, "test");
+ if (rv != PP_OK)
+ return ReportError("FileIO::Write", rv);
+
+ // Check the contents of the file.
+ read_buffer.clear();
+ rv = ReadEntireFile(&file_io, 0, &read_buffer);
+ if (rv != PP_OK)
+ return ReportError("FileIO::Read", rv);
+ if (read_buffer != std::string("testtesttest\0\0\0\0", 16))
+ return ReportMismatch("FileIO::Read", read_buffer,
+ std::string("testtesttest\0\0\0\0", 16));
+
+ // Read from the middle of the file.
+ read_buffer.clear();
+ rv = ReadEntireFile(&file_io, 4, &read_buffer);
+ if (rv != PP_OK)
+ return ReportError("FileIO::Read", rv);
+ if (read_buffer != std::string("testtest\0\0\0\0", 12))
+ return ReportMismatch("FileIO::Read", read_buffer,
+ std::string("testtest\0\0\0\0", 12));
+
+ return "";
+}
+
+std::string TestFileIO::TestTouchQuery() {
+ TestCompletionCallback callback;
+
+ pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+ int32_t rv = file_system.Open(1024, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Open", rv);
+
+ pp::FileRef_Dev file_ref(file_system, "/file_touch");
+ pp::FileIO_Dev file_io;
+ rv = file_io.Open(file_ref,
+ PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE,
+ callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileIO::Open", rv);
+
+ // Write some data to have a non-zero file size.
+ rv = file_io.Write(0, "test", 4, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != 4)
+ return ReportError("FileIO::Write", rv);
+
+ // last_access_time's granularity is 1 day
+ // last_modified_time's granularity is 2 seconds
+ const PP_Time last_access_time = 123 * 24 * 3600.0;
+ const PP_Time last_modified_time = 246.0;
+ rv = file_io.Touch(last_access_time, last_modified_time, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Touch", rv);
+
+ PP_FileInfo_Dev info;
+ rv = file_io.Query(&info, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Query", rv);
+
+ if ((info.size != 4) ||
+ (info.type != PP_FILETYPE_REGULAR) ||
+ (info.system_type != PP_FILESYSTEMTYPE_LOCALTEMPORARY) ||
+ (info.last_access_time != last_access_time) ||
+ (info.last_modified_time != last_modified_time))
+ return "FileSystem::Query() has returned bad data.";
+
+ return "";
+}
diff --git a/ppapi/tests/test_file_io.h b/ppapi/tests/test_file_io.h
new file mode 100644
index 0000000..c641c14
--- /dev/null
+++ b/ppapi/tests/test_file_io.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PAPPI_TESTS_TEST_FILE_IO_H_
+#define PAPPI_TESTS_TEST_FILE_IO_H_
+
+#include <string>
+
+#include "ppapi/tests/test_case.h"
+
+class TestFileIO : public TestCase {
+ public:
+ explicit TestFileIO(TestingInstance* instance) : TestCase(instance) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ private:
+ std::string TestOpen();
+ std::string TestReadWriteSetLength();
+ std::string TestTouchQuery();
+};
+
+#endif // PAPPI_TESTS_TEST_FILE_IO_H_
diff --git a/ppapi/tests/test_file_ref.cc b/ppapi/tests/test_file_ref.cc
new file mode 100644
index 0000000..b83a2f4
--- /dev/null
+++ b/ppapi/tests/test_file_ref.cc
@@ -0,0 +1,502 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_file_ref.h"
+
+#include <stdio.h>
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/dev/ppb_file_io_dev.h"
+#include "ppapi/c/dev/ppb_testing_dev.h"
+#include "ppapi/cpp/dev/file_io_dev.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/dev/file_system_dev.h"
+#include "ppapi/cpp/dev/url_loader_dev.h"
+#include "ppapi/cpp/dev/url_request_info_dev.h"
+#include "ppapi/cpp/dev/url_response_info_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(FileRef);
+
+namespace {
+
+const char* kPersFileName = "persistent";
+const char* kTempFileName = "temporary";
+const char* kParentPath = "/foo/bar";
+const char* kPersFilePath = "/foo/bar/persistent";
+const char* kTempFilePath = "/foo/bar/temporary";
+
+const PPB_Testing_Dev* g_testing_interface;
+
+class TestCompletionCallback {
+ public:
+ TestCompletionCallback() : result_(PP_ERROR_WOULDBLOCK) {
+ }
+
+ operator pp::CompletionCallback() const {
+ return pp::CompletionCallback(&TestCompletionCallback::Handler,
+ const_cast<TestCompletionCallback*>(this));
+ }
+
+ int32_t WaitForResult() {
+ result_ = PP_ERROR_WOULDBLOCK; // Reset
+ g_testing_interface->RunMessageLoop();
+ return result_;
+ }
+
+ private:
+ static void Handler(void* user_data, int32_t result) {
+ static_cast<TestCompletionCallback*>(user_data)->result_ = result;
+ g_testing_interface->QuitMessageLoop();
+ }
+
+ int32_t result_;
+};
+
+std::string ReportMismatch(const std::string& method_name,
+ const std::string& returned_result,
+ const std::string& expected_result) {
+ return method_name + " returned '" + returned_result + "'; '" +
+ expected_result + "' expected.";
+}
+
+std::string ReportError(const char* method, int32_t error) {
+ char error_as_string[12];
+ sprintf(error_as_string, "%d", error);
+ std::string result = method + std::string(" failed with error: ") +
+ error_as_string;
+ if (error == PP_ERROR_NOSPACE)
+ result += ". Did you run the test with --unlimited-quota-for-files?";
+ return result;
+}
+
+} // namespace
+
+bool TestFileRef::Init() {
+ g_testing_interface = reinterpret_cast<PPB_Testing_Dev const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE));
+ if (!g_testing_interface) {
+ // Give a more helpful error message for the testing interface being gone
+ // since that needs special enabling in Chrome.
+ instance_->AppendError("This test needs the testing interface, which is "
+ "not currently available. In Chrome, use --enable-pepper-testing when "
+ "launching.");
+ return false;
+ }
+
+ // Make sure we're running over HTTP.
+ pp::Var window = instance_->GetWindowObject();
+ pp::Var location = window.GetProperty("location");
+ pp::Var protocol = location.GetProperty("protocol");
+ if (!protocol.is_string() || protocol.AsString() != "http:") {
+ instance_->AppendError("This test needs to be run over HTTP.");
+ return false;
+ }
+
+ return true;
+}
+
+void TestFileRef::RunTest() {
+ RUN_TEST(GetFileSystemType);
+ RUN_TEST(GetName);
+ RUN_TEST(GetPath);
+ RUN_TEST(GetParent);
+ RUN_TEST(MakeDirectory);
+ RUN_TEST(QueryAndTouchFile);
+ RUN_TEST(DeleteFileAndDirectory);
+ RUN_TEST(RenameFileAndDirectory);
+}
+
+std::string TestFileRef::TestGetFileSystemType() {
+ pp::FileSystem_Dev file_system_pers(
+ instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
+ pp::FileSystem_Dev file_system_temp(
+ instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+
+ pp::FileRef_Dev file_ref_pers(file_system_pers, kPersFilePath);
+ if (file_ref_pers.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALPERSISTENT)
+ return "file_ref_pers expected to be persistent.";
+
+ pp::FileRef_Dev file_ref_temp(file_system_temp, kTempFilePath);
+ if (file_ref_temp.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALTEMPORARY)
+ return "file_ref_temp expected to be temporary.";
+
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("test_url_loader_data/hello.txt");
+ request.SetStreamToFile(true);
+
+ TestCompletionCallback callback;
+
+ pp::URLLoader_Dev loader(*instance_);
+ int32_t rv = loader.Open(request, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return "URLLoader::Open() failed.";
+
+ pp::URLResponseInfo_Dev response_info(loader.GetResponseInfo());
+ if (response_info.is_null())
+ return "URLLoader::GetResponseInfo returned null";
+ int32_t status_code = response_info.GetStatusCode();
+ if (status_code != 200)
+ return "Unexpected HTTP status code";
+
+ pp::FileRef_Dev file_ref_ext(response_info.GetBody());
+ if (file_ref_ext.GetFileSystemType() != PP_FILESYSTEMTYPE_EXTERNAL)
+ return "file_ref_ext expected to be external.";
+
+ return "";
+}
+
+std::string TestFileRef::TestGetName() {
+ pp::FileSystem_Dev file_system_pers(
+ instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
+ pp::FileSystem_Dev file_system_temp(
+ instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+
+ pp::FileRef_Dev file_ref_pers(file_system_pers, kPersFilePath);
+ std::string name = file_ref_pers.GetName().AsString();
+ if (name != kPersFileName)
+ return ReportMismatch("FileRef::GetName", name, kPersFileName);
+
+ pp::FileRef_Dev file_ref_temp(file_system_temp, kTempFilePath);
+ name = file_ref_temp.GetName().AsString();
+ if (name != kTempFileName)
+ return ReportMismatch("FileRef::GetName", name, kTempFileName);
+
+ // Test the "/" case.
+ pp::FileRef_Dev file_ref_slash(file_system_temp, "/");
+ name = file_ref_slash.GetName().AsString();
+ if (name != "/")
+ return ReportMismatch("FileRef::GetName", name, "/");
+
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("test_url_loader_data/hello.txt");
+ request.SetStreamToFile(true);
+
+ TestCompletionCallback callback;
+
+ pp::URLLoader_Dev loader(*instance_);
+ int32_t rv = loader.Open(request, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return "URLLoader::Open() failed.";
+
+ pp::URLResponseInfo_Dev response_info(loader.GetResponseInfo());
+ if (response_info.is_null())
+ return "URLLoader::GetResponseInfo returned null";
+ int32_t status_code = response_info.GetStatusCode();
+ if (status_code != 200)
+ return "Unexpected HTTP status code";
+
+ pp::FileRef_Dev file_ref_ext(response_info.GetBody());
+ name = file_ref_ext.GetName().AsString();
+ if (name != "")
+ return ReportMismatch("FileRef::GetName", name, "<empty string>");
+
+ return "";
+}
+
+std::string TestFileRef::TestGetPath() {
+ pp::FileSystem_Dev file_system_pers(
+ instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
+ pp::FileSystem_Dev file_system_temp(
+ instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+
+ pp::FileRef_Dev file_ref_pers(file_system_pers, kPersFilePath);
+ std::string path = file_ref_pers.GetPath().AsString();
+ if (path != kPersFilePath)
+ return ReportMismatch("FileRef::GetPath", path, kPersFilePath);
+
+ pp::FileRef_Dev file_ref_temp(file_system_temp, kTempFilePath);
+ path = file_ref_temp.GetPath().AsString();
+ if (path != kTempFilePath)
+ return ReportMismatch("FileRef::GetPath", path, kTempFilePath);
+
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("test_url_loader_data/hello.txt");
+ request.SetStreamToFile(true);
+
+ TestCompletionCallback callback;
+
+ pp::URLLoader_Dev loader(*instance_);
+ int32_t rv = loader.Open(request, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return "URLLoader::Open() failed.";
+
+ pp::URLResponseInfo_Dev response_info(loader.GetResponseInfo());
+ if (response_info.is_null())
+ return "URLLoader::GetResponseInfo returned null";
+ int32_t status_code = response_info.GetStatusCode();
+ if (status_code != 200)
+ return "Unexpected HTTP status code";
+
+ pp::FileRef_Dev file_ref_ext(response_info.GetBody());
+ if (!file_ref_ext.GetPath().is_undefined())
+ return "The path of an external FileRef should be void.";
+
+ return "";
+}
+
+std::string TestFileRef::TestGetParent() {
+ pp::FileSystem_Dev file_system_pers(
+ instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
+ pp::FileSystem_Dev file_system_temp(
+ instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+
+ pp::FileRef_Dev file_ref_pers(file_system_pers, kPersFilePath);
+ std::string parent_path = file_ref_pers.GetParent().GetPath().AsString();
+ if (parent_path != kParentPath)
+ return ReportMismatch("FileRef::GetParent", parent_path, kParentPath);
+
+ pp::FileRef_Dev file_ref_temp(file_system_temp, kTempFilePath);
+ parent_path = file_ref_temp.GetParent().GetPath().AsString();
+ if (parent_path != kParentPath)
+ return ReportMismatch("FileRef::GetParent", parent_path, kParentPath);
+
+ // Test the "/" case.
+ pp::FileRef_Dev file_ref_slash(file_system_temp, "/");
+ parent_path = file_ref_slash.GetParent().GetPath().AsString();
+ if (parent_path != "/")
+ return ReportMismatch("FileRef::GetParent", parent_path, "/");
+
+ // Test the "/foo" case (the parent is "/").
+ pp::FileRef_Dev file_ref_with_root_parent(file_system_temp, "/foo");
+ parent_path = file_ref_with_root_parent.GetParent().GetPath().AsString();
+ if (parent_path != "/")
+ return ReportMismatch("FileRef::GetParent", parent_path, "/");
+
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("test_url_loader_data/hello.txt");
+ request.SetStreamToFile(true);
+
+ TestCompletionCallback callback;
+
+ pp::URLLoader_Dev loader(*instance_);
+ int32_t rv = loader.Open(request, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return "URLLoader::Open() failed.";
+
+ pp::URLResponseInfo_Dev response_info(loader.GetResponseInfo());
+ if (response_info.is_null())
+ return "URLLoader::GetResponseInfo returned null";
+ int32_t status_code = response_info.GetStatusCode();
+ if (status_code != 200)
+ return "Unexpected HTTP status code";
+
+ pp::FileRef_Dev file_ref_ext(response_info.GetBody());
+ if (!file_ref_ext.GetParent().is_null())
+ return "The parent of an external FileRef should be null.";
+
+ return "";
+}
+
+std::string TestFileRef::TestMakeDirectory() {
+ TestCompletionCallback callback;
+
+ pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+ int32_t rv = file_system.Open(1024, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Open", rv);
+
+ pp::FileRef_Dev dir_ref(file_system, "/test_dir_make_directory");
+ rv = dir_ref.MakeDirectory(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::MakeDirectory", rv);
+
+ dir_ref = pp::FileRef_Dev(file_system, "/dir_make_dir_1/dir_make_dir_2");
+ rv = dir_ref.MakeDirectoryIncludingAncestors(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::MakeDirectoryIncludingAncestors", rv);
+
+ dir_ref = pp::FileRef_Dev(file_system, "/dir_make_dir_3/dir_make_dir_4");
+ rv = dir_ref.MakeDirectory(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv == PP_OK)
+ return "Calling FileSystem::MakeDirectory() with a nested directory path " \
+ "should have failed.";
+
+ return "";
+}
+
+std::string TestFileRef::TestQueryAndTouchFile() {
+ TestCompletionCallback callback;
+ pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+ int32_t rv = file_system.Open(1024, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Open", rv);
+
+ pp::FileRef_Dev file_ref(file_system, "/file_touch");
+ pp::FileIO_Dev file_io;
+ rv = file_io.Open(file_ref,
+ PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE,
+ callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileIO::Open", rv);
+
+ // Write some data to have a non-zero file size.
+ rv = file_io.Write(0, "test", 4, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != 4)
+ return ReportError("FileIO::Write", rv);
+
+ // last_access_time's granularity is 1 day
+ // last_modified_time's granularity is 2 seconds
+ const PP_Time last_access_time = 123 * 24 * 3600.0;
+ const PP_Time last_modified_time = 246.0;
+ rv = file_ref.Touch(last_access_time, last_modified_time, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Touch", rv);
+
+ PP_FileInfo_Dev info;
+ rv = file_ref.Query(&info, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Query", rv);
+
+ if ((info.size != 4) ||
+ (info.type != PP_FILETYPE_REGULAR) ||
+ (info.system_type != PP_FILESYSTEMTYPE_LOCALTEMPORARY) ||
+ (info.last_access_time != last_access_time) ||
+ (info.last_modified_time != last_modified_time))
+ return "FileSystem::Query() has returned bad data.";
+
+ return "";
+}
+
+std::string TestFileRef::TestDeleteFileAndDirectory() {
+ TestCompletionCallback callback;
+ pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+ int32_t rv = file_system.Open(1024, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Open", rv);
+
+ pp::FileRef_Dev file_ref(file_system, "/file_delete");
+ pp::FileIO_Dev file_io;
+ rv = file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileIO::Open", rv);
+
+ rv = file_ref.Delete(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Delete", rv);
+
+ pp::FileRef_Dev dir_ref(file_system, "/dir_delete");
+ rv = dir_ref.MakeDirectory(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::MakeDirectory", rv);
+
+ rv = dir_ref.Delete(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Delete", rv);
+
+ pp::FileRef_Dev nested_dir_ref(file_system, "/dir_delete_1/dir_delete_2");
+ rv = nested_dir_ref.MakeDirectoryIncludingAncestors(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::MakeDirectoryIncludingAncestors", rv);
+
+ rv = nested_dir_ref.GetParent().Delete(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_ERROR_FAILED)
+ return ReportError("FileSystem::Delete", rv);
+
+ pp::FileRef_Dev nonexistent_file_ref(file_system, "/nonexistent_file_delete");
+ rv = nonexistent_file_ref.Delete(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_ERROR_FILENOTFOUND)
+ return ReportError("FileSystem::Delete", rv);
+
+ return "";
+}
+
+std::string TestFileRef::TestRenameFileAndDirectory() {
+ TestCompletionCallback callback;
+ pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
+ int32_t rv = file_system.Open(1024, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Open", rv);
+
+ pp::FileRef_Dev file_ref(file_system, "/file_rename");
+ pp::FileIO_Dev file_io;
+ rv = file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileIO::Open", rv);
+
+ pp::FileRef_Dev target_file_ref(file_system, "/target_file_rename");
+ rv = file_ref.Rename(target_file_ref, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Rename", rv);
+
+ pp::FileRef_Dev dir_ref(file_system, "/dir_rename");
+ rv = dir_ref.MakeDirectory(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::MakeDirectory", rv);
+
+ pp::FileRef_Dev target_dir_ref(file_system, "/target_dir_rename");
+ rv = dir_ref.Rename(target_dir_ref, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::Rename", rv);
+
+ pp::FileRef_Dev nested_dir_ref(file_system, "/dir_rename_1/dir_rename_2");
+ rv = nested_dir_ref.MakeDirectoryIncludingAncestors(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileSystem::MakeDirectoryIncludingAncestors", rv);
+
+ pp::FileRef_Dev target_nested_dir_ref(file_system, "/dir_rename_1");
+ rv = nested_dir_ref.Rename(target_nested_dir_ref, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_ERROR_FAILED)
+ return ReportError("FileSystem::Rename", rv);
+
+ return "";
+}
diff --git a/ppapi/tests/test_file_ref.h b/ppapi/tests/test_file_ref.h
new file mode 100644
index 0000000..ba9e39a
--- /dev/null
+++ b/ppapi/tests/test_file_ref.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PAPPI_TESTS_TEST_FILE_REF_H_
+#define PAPPI_TESTS_TEST_FILE_REF_H_
+
+#include <string>
+
+#include "ppapi/tests/test_case.h"
+
+class TestFileRef : public TestCase {
+ public:
+ explicit TestFileRef(TestingInstance* instance) : TestCase(instance) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ private:
+ std::string TestGetFileSystemType();
+ std::string TestGetName();
+ std::string TestGetPath();
+ std::string TestGetParent();
+ std::string TestMakeDirectory();
+ std::string TestQueryAndTouchFile();
+ std::string TestDeleteFileAndDirectory();
+ std::string TestRenameFileAndDirectory();
+};
+
+#endif // PAPPI_TESTS_TEST_FILE_REF_H_
diff --git a/ppapi/tests/test_graphics_2d.cc b/ppapi/tests/test_graphics_2d.cc
new file mode 100644
index 0000000..34b9945
--- /dev/null
+++ b/ppapi/tests/test_graphics_2d.cc
@@ -0,0 +1,542 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_graphics_2d.h"
+
+#include <string.h>
+
+#include "ppapi/c/dev/ppb_testing_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_graphics_2d.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(Graphics2D);
+
+namespace {
+
+// A NOP flush callback for use in various tests.
+void FlushCallbackNOP(void* data, int32_t result) {
+}
+
+void FlushCallbackQuitMessageLoop(void* data, int32_t result) {
+ reinterpret_cast<TestGraphics2D*>(data)->QuitMessageLoop();
+}
+
+} // namespace
+
+bool TestGraphics2D::Init() {
+ graphics_2d_interface_ = reinterpret_cast<PPB_Graphics2D const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_GRAPHICS_2D_INTERFACE));
+ image_data_interface_ = reinterpret_cast<PPB_ImageData const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_IMAGEDATA_INTERFACE));
+ testing_interface_ = reinterpret_cast<PPB_Testing_Dev const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE));
+ if (!testing_interface_) {
+ // Give a more helpful error message for the testing interface being gone
+ // since that needs special enabling in Chrome.
+ instance_->AppendError("This test needs the testing interface, which is "
+ "not currently available. In Chrome, use --enable-pepper-testing when "
+ "launching.");
+ }
+ return graphics_2d_interface_ && image_data_interface_ &&
+ testing_interface_;
+}
+
+void TestGraphics2D::RunTest() {
+ instance_->LogTest("InvalidResource", TestInvalidResource());
+ instance_->LogTest("InvalidSize", TestInvalidSize());
+ instance_->LogTest("Humongous", TestHumongous());
+ instance_->LogTest("InitToZero", TestInitToZero());
+ instance_->LogTest("Describe", TestDescribe());
+ instance_->LogTest("Paint", TestPaint());
+ //instance_->LogTest("Scroll", TestScroll()); // TODO(brettw) implement.
+ instance_->LogTest("Replace", TestReplace());
+ instance_->LogTest("Flush", TestFlush());
+}
+
+void TestGraphics2D::QuitMessageLoop() {
+ testing_interface_->QuitMessageLoop();
+}
+
+bool TestGraphics2D::ReadImageData(const pp::Graphics2D& dc,
+ pp::ImageData* image,
+ const pp::Point& top_left) const {
+ return testing_interface_->ReadImageData(dc.pp_resource(),
+ image->pp_resource(),
+ &top_left.pp_point());
+}
+
+bool TestGraphics2D::IsDCUniformColor(const pp::Graphics2D& dc,
+ uint32_t color) const {
+ pp::ImageData readback(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ dc.size(), false);
+ if (readback.is_null())
+ return false;
+ if (!ReadImageData(dc, &readback, pp::Point(0, 0)))
+ return false;
+ return IsSquareInImage(readback, 0, pp::Rect(dc.size()), color);
+}
+
+bool TestGraphics2D::FlushAndWaitForDone(pp::Graphics2D* context) {
+ pp::CompletionCallback cc(&FlushCallbackQuitMessageLoop, this);
+ int32_t rv = context->Flush(cc);
+ if (rv == PP_OK)
+ return true;
+ if (rv != PP_ERROR_WOULDBLOCK)
+ return false;
+ testing_interface_->RunMessageLoop();
+ return true;
+}
+
+void TestGraphics2D::FillRectInImage(pp::ImageData* image,
+ const pp::Rect& rect,
+ uint32_t color) const {
+ for (int y = rect.y(); y < rect.bottom(); y++) {
+ uint32_t* row = image->GetAddr32(pp::Point(rect.x(), y));
+ for (int pixel = 0; pixel < rect.width(); pixel++)
+ row[pixel] = color;
+ }
+}
+
+void TestGraphics2D::FillImageWithGradient(pp::ImageData* image) const {
+ for (int y = 0; y < image->size().height(); y++) {
+ uint32_t red = ((y * 256) / image->size().height()) & 0xFF;
+ for (int x = 0; x < image->size().width(); x++) {
+ uint32_t green = ((x * 256) / image->size().width()) & 0xFF;
+ uint32_t blue = ((red + green) / 2) & 0xFF;
+ uint32_t* pixel = image->GetAddr32(pp::Point(x, y));
+ *pixel = (blue << 24) | (green << 16) | (red << 8);
+ }
+ }
+}
+
+bool TestGraphics2D::CompareImages(const pp::ImageData& image1,
+ const pp::ImageData& image2) {
+ return CompareImageRect(
+ image1, pp::Rect(0, 0, image1.size().width(), image1.size().height()),
+ image2, pp::Rect(0, 0, image2.size().width(), image2.size().height()));
+}
+
+bool TestGraphics2D::CompareImageRect(const pp::ImageData& image1,
+ const pp::Rect& rc1,
+ const pp::ImageData& image2,
+ const pp::Rect& rc2) const {
+ if (rc1.width() != rc2.width() || rc1.height() != rc2.height())
+ return false;
+
+ for (int y = 0; y < rc1.height(); y++) {
+ for (int x = 0; x < rc1.width(); x++) {
+ if (*(image1.GetAddr32(pp::Point(rc1.x() + x, rc1.y() + y))) !=
+ *(image2.GetAddr32(pp::Point(rc2.x() + x, rc2.y() + y))))
+ return false;
+ }
+ }
+ return true;
+}
+
+bool TestGraphics2D::IsSquareInImage(const pp::ImageData& image_data,
+ uint32_t background_color,
+ const pp::Rect& square,
+ uint32_t square_color) const {
+ for (int y = 0; y < image_data.size().height(); y++) {
+ for (int x = 0; x < image_data.size().width(); x++) {
+ uint32_t pixel = *image_data.GetAddr32(pp::Point(x, y));
+ uint32_t desired_color;
+ if (square.Contains(x, y))
+ desired_color = square_color;
+ else
+ desired_color = background_color;
+ if (pixel != desired_color)
+ return false;
+ }
+ }
+ return true;
+}
+
+bool TestGraphics2D::IsSquareInDC(const pp::Graphics2D& dc,
+ uint32_t background_color,
+ const pp::Rect& square,
+ uint32_t square_color) const {
+ pp::ImageData readback(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ dc.size(), false);
+ if (readback.is_null())
+ return false;
+ if (!ReadImageData(dc, &readback, pp::Point(0, 0)))
+ return false;
+ return IsSquareInImage(readback, background_color, square, square_color);
+}
+
+// Test all the functions with an invalid handle. Most of these just check for
+// a crash since the browser don't return a value.
+std::string TestGraphics2D::TestInvalidResource() {
+ pp::Graphics2D null_context;
+ pp::ImageData image(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(16, 16), true);
+
+ // Describe.
+ PP_Size size;
+ bool opaque;
+ graphics_2d_interface_->Describe(image.pp_resource(), &size, &opaque);
+ graphics_2d_interface_->Describe(null_context.pp_resource(),
+ &size, &opaque);
+
+ // PaintImageData.
+ PP_Point zero_zero;
+ zero_zero.x = 0;
+ zero_zero.y = 0;
+ graphics_2d_interface_->PaintImageData(image.pp_resource(),
+ image.pp_resource(),
+ &zero_zero, NULL);
+ graphics_2d_interface_->PaintImageData(null_context.pp_resource(),
+ image.pp_resource(),
+ &zero_zero, NULL);
+
+ // Scroll.
+ PP_Point zero_ten;
+ zero_ten.x = 0;
+ zero_ten.y = 10;
+ graphics_2d_interface_->Scroll(image.pp_resource(), NULL, &zero_ten);
+ graphics_2d_interface_->Scroll(null_context.pp_resource(),
+ NULL, &zero_ten);
+
+ // ReplaceContents.
+ graphics_2d_interface_->ReplaceContents(image.pp_resource(),
+ image.pp_resource());
+ graphics_2d_interface_->ReplaceContents(null_context.pp_resource(),
+ image.pp_resource());
+
+ // Flush.
+ if (graphics_2d_interface_->Flush(
+ image.pp_resource(),
+ PP_MakeCompletionCallback(&FlushCallbackNOP, NULL)) == PP_OK)
+ return "Flush succeeded with a different resource";
+ if (graphics_2d_interface_->Flush(
+ null_context.pp_resource(),
+ PP_MakeCompletionCallback(&FlushCallbackNOP, NULL)) == PP_OK)
+ return "Flush succeeded with a NULL resource";
+
+ // ReadImageData.
+ if (testing_interface_->ReadImageData(image.pp_resource(),
+ image.pp_resource(),
+ &zero_zero))
+ return "ReadImageData succeeded with a different resource";
+ if (testing_interface_->ReadImageData(null_context.pp_resource(),
+ image.pp_resource(),
+ &zero_zero))
+ return "ReadImageData succeeded with a NULL resource";
+
+ return "";
+}
+
+std::string TestGraphics2D::TestInvalidSize() {
+ pp::Graphics2D a(pp::Size(16, 0), false);
+ if (!a.is_null())
+ return "0 height accepted";
+
+ pp::Graphics2D b(pp::Size(0, 16), false);
+ if (!b.is_null())
+ return "0 width accepted";
+
+ // Need to use the C API since pp::Size prevents negative sizes.
+ PP_Size size;
+ size.width = 16;
+ size.height = -16;
+ ASSERT_FALSE(!!graphics_2d_interface_->Create(
+ pp::Module::Get()->pp_module(), &size, false));
+
+ size.width = -16;
+ size.height = 16;
+ ASSERT_FALSE(!!graphics_2d_interface_->Create(
+ pp::Module::Get()->pp_module(), &size, false));
+
+ return "";
+}
+
+std::string TestGraphics2D::TestHumongous() {
+ pp::Graphics2D a(pp::Size(100000, 100000), false);
+ if (!a.is_null())
+ return "Humongous device created";
+ return "";
+}
+
+std::string TestGraphics2D::TestInitToZero() {
+ const int w = 15, h = 17;
+ pp::Graphics2D dc(pp::Size(w, h), false);
+ if (dc.is_null())
+ return "Failure creating a boring device";
+
+ // Make an image with nonzero data in it (so we can test that zeros were
+ // actually read versus ReadImageData being a NOP).
+ pp::ImageData image(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(w, h), true);
+ if (image.is_null())
+ return "Failure to allocate an image";
+ memset(image.data(), 0xFF, image.stride() * image.size().height() * 4);
+
+ // Read out the initial data from the device & check.
+ if (!ReadImageData(dc, &image, pp::Point(0, 0)))
+ return "Couldn't read image data";
+ if (!IsSquareInImage(image, 0, pp::Rect(0, 0, w, h), 0))
+ return "Got a nonzero pixel";
+
+ return "";
+}
+
+std::string TestGraphics2D::TestDescribe() {
+ const int w = 15, h = 17;
+ pp::Graphics2D dc(pp::Size(w, h), false);
+ if (dc.is_null())
+ return "Failure creating a boring device";
+
+ PP_Size size;
+ size.width = -1;
+ size.height = -1;
+ bool is_always_opaque = true;
+ if (!graphics_2d_interface_->Describe(dc.pp_resource(), &size,
+ &is_always_opaque))
+ return "Describe failed";
+ if (size.width != w || size.height != h || is_always_opaque != false)
+ return "Mismatch of data.";
+
+ return "";
+}
+
+std::string TestGraphics2D::TestPaint() {
+ const int w = 15, h = 17;
+ pp::Graphics2D dc(pp::Size(w, h), false);
+ if (dc.is_null())
+ return "Failure creating a boring device";
+
+ // Make sure the device background is 0.
+ if (!IsDCUniformColor(dc, 0))
+ return "Bad initial color";
+
+ // Fill the backing store with white.
+ const uint32_t background_color = 0xFFFFFFFF;
+ pp::ImageData background(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(w, h),
+ false);
+ FillRectInImage(&background, pp::Rect(0, 0, w, h), background_color);
+ dc.PaintImageData(background, pp::Point(0, 0));
+ if (!FlushAndWaitForDone(&dc))
+ return "Couldn't flush to fill backing store";
+
+ // Make an image to paint with that's opaque white and enqueue a paint.
+ const int fill_w = 2, fill_h = 3;
+ pp::ImageData fill(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(fill_w, fill_h),
+ true);
+ if (fill.is_null())
+ return "Failure to allocate fill image";
+ FillRectInImage(&fill, pp::Rect(fill.size()), background_color);
+ const int paint_x = 4, paint_y = 5;
+ dc.PaintImageData(fill, pp::Point(paint_x, paint_y));
+
+ // Validate that nothing has been actually painted.
+ if (!IsDCUniformColor(dc, background_color))
+ return "Image updated before flush (or failure in readback).";
+
+ // The paint hasn't been flushed so we can still change the bitmap. Fill with
+ // 50% blue. This will also verify that the backing store is replaced
+ // with the contents rather than blended.
+ const uint32_t fill_color = 0x80000080;
+ FillRectInImage(&fill, pp::Rect(fill.size()), fill_color);
+ if (!FlushAndWaitForDone(&dc))
+ return "Couldn't flush 50% blue paint";
+
+ if (!IsSquareInDC(dc, background_color,
+ pp::Rect(paint_x, paint_y, fill_w, fill_h),
+ fill_color))
+ return "Image not painted properly.";
+
+ // Reset the DC to blank white & paint our image slightly off the buffer.
+ // This should succeed. We also try painting the same thing where the
+ // dirty rect falls outeside of the device, which should fail.
+ dc.PaintImageData(background, pp::Point(0, 0));
+ const int second_paint_x = -1, second_paint_y = -2;
+ dc.PaintImageData(fill, pp::Point(second_paint_x, second_paint_y));
+ dc.PaintImageData(fill, pp::Point(second_paint_x, second_paint_y),
+ pp::Rect(-second_paint_x, -second_paint_y, 1, 1));
+ if (!FlushAndWaitForDone(&dc))
+ return "Couldn't flush second paint";
+
+ // Now we should have a little bit of the image peeking out the top left.
+ if (!IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1),
+ fill_color))
+ return "Partially offscreen paint failed.";
+
+ // Now repaint that top left pixel by doing a subset of the source image.
+ pp::ImageData subset(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(w, h), false);
+ uint32_t subset_color = 0x80808080;
+ const int subset_x = 2, subset_y = 1;
+ *subset.GetAddr32(pp::Point(subset_x, subset_y)) = subset_color;
+ dc.PaintImageData(subset, pp::Point(-subset_x, -subset_y),
+ pp::Rect(subset_x, subset_y, 1, 1));
+ if (!FlushAndWaitForDone(&dc))
+ return "Couldn't flush repaint";
+ if (!IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1),
+ subset_color))
+ return "Subset paint failed.";
+
+ return "";
+}
+
+std::string TestGraphics2D::TestScroll() {
+ const int w = 115, h = 117;
+ pp::Graphics2D dc(pp::Size(w, h), false);
+ if (dc.is_null())
+ return "Failure creating a boring device.";
+
+ // Make sure the device background is 0.
+ if (!IsDCUniformColor(dc, 0))
+ return "Bad initial color.";
+
+ const int image_w = 15, image_h = 23;
+ pp::ImageData test_image(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ pp::Size(image_w, image_h), false);
+ FillImageWithGradient(&test_image);
+
+ int image_x = 51, image_y = 72;
+ dc.PaintImageData(test_image, pp::Point(image_x, image_y));
+ if (!FlushAndWaitForDone(&dc))
+ return "Couldn't flush to fill backing store.";
+
+ // TC1, Scroll image to a free space.
+ int dx = -40, dy = -48;
+ pp::Rect clip = pp::Rect(image_x, image_y, test_image.size().width(),
+ test_image.size().height());
+ dc.Scroll(clip, pp::Point(dx, dy));
+
+ if (!FlushAndWaitForDone(&dc))
+ return "TC1, Couldn't flush to scroll.";
+
+ image_x += dx;
+ image_y += dy;
+
+ pp::ImageData readback(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ pp::Size(image_w, image_h), false);
+ if (!ReadImageData(dc, &readback, pp::Point(image_x, image_y)))
+ return "TC1, Couldn't read back image data.";
+
+ if (!CompareImages(test_image, readback))
+ return "TC1, Read back image is not the same as test image.";
+
+ // TC2, Scroll image to an overlapping space.
+ dx = 6;
+ dy = 9;
+ clip = pp::Rect(image_x, image_y, test_image.size().width(),
+ test_image.size().height());
+ dc.Scroll(clip, pp::Point(dx, dy));
+
+ if (!FlushAndWaitForDone(&dc))
+ return "TC2, Couldn't flush to scroll.";
+
+ image_x += dx;
+ image_y += dy;
+
+ if (!ReadImageData(dc, &readback, pp::Point(image_x, image_y)))
+ return "TC2, Couldn't read back image data.";
+
+ if (!CompareImages(test_image, readback))
+ return "TC2, Read back image is not the same as test image.";
+
+ return "";
+}
+
+std::string TestGraphics2D::TestReplace() {
+ const int w = 15, h = 17;
+ pp::Graphics2D dc(pp::Size(w, h), false);
+ if (dc.is_null())
+ return "Failure creating a boring device";
+
+ // Replacing with a different size image should fail.
+ pp::ImageData weird_size(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ pp::Size(w - 1, h), true);
+ if (weird_size.is_null())
+ return "Failure allocating the weird sized image";
+ dc.ReplaceContents(&weird_size);
+
+ // Fill the background with blue but don't flush yet.
+ const int32_t background_color = 0xFF0000FF;
+ pp::ImageData background(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(w, h),
+ true);
+ if (background.is_null())
+ return "Failure to allocate background image";
+ FillRectInImage(&background, pp::Rect(0, 0, w, h), background_color);
+ dc.PaintImageData(background, pp::Point(0, 0));
+
+ // Replace with a green background but don't flush yet.
+ const int32_t swapped_color = 0xFF0000FF;
+ pp::ImageData swapped(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(w, h), true);
+ if (swapped.is_null())
+ return "Failure to allocate swapped image";
+ FillRectInImage(&swapped, pp::Rect(0, 0, w, h), swapped_color);
+ dc.ReplaceContents(&swapped);
+
+ // The background should be unchanged since we didn't flush yet.
+ if (!IsDCUniformColor(dc, 0))
+ return "Image updated before flush (or failure in readback).";
+
+ // Test the C++ wrapper. The size of the swapped image should be reset.
+ if (swapped.pp_resource() || swapped.size().width() ||
+ swapped.size().height() || swapped.data())
+ return "Size of the swapped image should be reset.";
+
+ // Painting with the swapped image should fail.
+ dc.PaintImageData(swapped, pp::Point(0, 0));
+
+ // Flush and make sure the result is correct.
+ if (!FlushAndWaitForDone(&dc))
+ return "Couldn't flush";
+
+ // The background should be green from the swapped image.
+ if (!IsDCUniformColor(dc, swapped_color))
+ return "Flushed color incorrect (or failure in readback).";
+
+ return "";
+}
+
+std::string TestGraphics2D::TestFlush() {
+ // Tests that synchronous flushes (NULL callback) fail on the main thread
+ // (which is the current one).
+ const int w = 15, h = 17;
+ pp::Graphics2D dc(pp::Size(w, h), false);
+ if (dc.is_null())
+ return "Failure creating a boring device";
+
+ // Fill the background with blue but don't flush yet.
+ pp::ImageData background(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(w, h),
+ true);
+ if (background.is_null())
+ return "Failure to allocate background image";
+ dc.PaintImageData(background, pp::Point(0, 0));
+
+ int32_t rv = dc.Flush(pp::CompletionCallback::Block());
+ if (rv == PP_OK || rv == PP_ERROR_WOULDBLOCK)
+ return "Flush succeeded from the main thread with no callback.";
+
+ // Test flushing with no operations still issues a callback.
+ // (This may also hang if the browser never issues the callback).
+ pp::Graphics2D dc_nopaints(pp::Size(w, h), false);
+ if (dc.is_null())
+ return "Failure creating the nopaint device";
+ if (!FlushAndWaitForDone(&dc_nopaints))
+ return "Couldn't flush the nopaint device";
+
+ // Test that multiple flushes fail if we don't get a callback in between.
+ rv = dc_nopaints.Flush(pp::CompletionCallback(&FlushCallbackNOP, NULL));
+ if (rv != PP_OK && rv != PP_ERROR_WOULDBLOCK)
+ return "Couldn't flush first time for multiple flush test.";
+
+ if (rv != PP_OK) {
+ // If the first flush would block, then a second should fail.
+ rv = dc_nopaints.Flush(pp::CompletionCallback(&FlushCallbackNOP, NULL));
+ if (rv == PP_OK || rv == PP_ERROR_WOULDBLOCK)
+ return "Second flush succeeded before callback ran.";
+ }
+
+ return "";
+}
diff --git a/ppapi/tests/test_graphics_2d.h b/ppapi/tests/test_graphics_2d.h
new file mode 100644
index 0000000..a82207f
--- /dev/null
+++ b/ppapi/tests/test_graphics_2d.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PAPPI_TESTS_TEST_GRAPHICS_2D_H_
+#define PAPPI_TESTS_TEST_GRAPHICS_2D_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/tests/test_case.h"
+
+struct PPB_Graphics2D;
+struct PPB_ImageData;
+struct PPB_Testing_Dev;
+
+namespace pp {
+class Graphics2D;
+class ImageData;
+class Point;
+class Rect;
+}
+
+class TestGraphics2D : public TestCase {
+ public:
+ TestGraphics2D(TestingInstance* instance) : TestCase(instance) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ void QuitMessageLoop();
+
+ private:
+ bool ReadImageData(const pp::Graphics2D& dc,
+ pp::ImageData* image,
+ const pp::Point& top_left) const;
+
+ void FillRectInImage(pp::ImageData* image,
+ const pp::Rect& rect,
+ uint32_t color) const;
+
+ // Fill image with gradient colors.
+ void FillImageWithGradient(pp::ImageData* image) const;
+
+ // Return true if images are the same.
+ bool CompareImages(const pp::ImageData& image1,
+ const pp::ImageData& image2);
+
+ // Return true if images within specified rectangles are the same.
+ bool CompareImageRect(const pp::ImageData& image1,
+ const pp::Rect& rc1,
+ const pp::ImageData& image2,
+ const pp::Rect& rc2) const;
+
+ // Validates that the given image is a single color with a square of another
+ // color inside it.
+ bool IsSquareInImage(const pp::ImageData& image_data,
+ uint32_t background_color,
+ const pp::Rect& square, uint32_t square_color) const;
+
+ // Validates that the given device context is a single color with a square of
+ // another color inside it.
+ bool IsSquareInDC(const pp::Graphics2D& dc, uint32_t background_color,
+ const pp::Rect& square, uint32_t square_color) const;
+
+ // Validates that the given device context is filled with the given color.
+ bool IsDCUniformColor(const pp::Graphics2D& dc, uint32_t color) const;
+
+ // Issues a flush on the given device context and blocks until the flush
+ // has issued its callback. Returns true on success.
+ bool FlushAndWaitForDone(pp::Graphics2D* context);
+
+ std::string TestInvalidResource();
+ std::string TestInvalidSize();
+ std::string TestHumongous();
+ std::string TestInitToZero();
+ std::string TestDescribe();
+ std::string TestPaint();
+ std::string TestScroll();
+ std::string TestReplace();
+ std::string TestFlush();
+
+ // Used by the tests that access the C API directly.
+ const PPB_Graphics2D* graphics_2d_interface_;
+ const PPB_ImageData* image_data_interface_;
+ const PPB_Testing_Dev* testing_interface_;
+};
+
+#endif // PAPPI_TESTS_TEST_GRAPHICS_2D_H_
diff --git a/ppapi/tests/test_image_data.cc b/ppapi/tests/test_image_data.cc
new file mode 100644
index 0000000..6b918f4
--- /dev/null
+++ b/ppapi/tests/test_image_data.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_image_data.h"
+
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(ImageData);
+
+bool TestImageData::Init() {
+ image_data_interface_ = reinterpret_cast<PPB_ImageData const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_IMAGEDATA_INTERFACE));
+ return !!image_data_interface_;
+}
+
+void TestImageData::RunTest() {
+ instance_->LogTest("InvalidFormat", TestInvalidFormat());
+ instance_->LogTest("InvalidSize", TestInvalidSize());
+ instance_->LogTest("HugeSize", TestHugeSize());
+ instance_->LogTest("InitToZero", TestInitToZero());
+ instance_->LogTest("IsImageData", TestIsImageData());
+}
+
+std::string TestImageData::TestInvalidFormat() {
+ pp::ImageData a(static_cast<PP_ImageDataFormat>(1337), pp::Size(16, 16),
+ true);
+ if (!a.is_null())
+ return "Crazy image data format accepted";
+
+ pp::ImageData b(static_cast<PP_ImageDataFormat>(-1), pp::Size(16, 16),
+ true);
+ if (!b.is_null())
+ return "Negative image data format accepted";
+
+ return "";
+}
+
+std::string TestImageData::TestInvalidSize() {
+ pp::ImageData zero_size(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(0, 0), true);
+ if (!zero_size.is_null())
+ return "Zero width and height accepted";
+
+ pp::ImageData zero_height(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ pp::Size(16, 0), true);
+ if (!zero_height.is_null())
+ return "Zero height accepted";
+
+ pp::ImageData zero_width(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ pp::Size(0, 16), true);
+ if (!zero_width.is_null())
+ return "Zero width accepted";
+
+ PP_Size negative_height;
+ negative_height.width = 16;
+ negative_height.height = -2;
+ PP_Resource rsrc = image_data_interface_->Create(
+ pp::Module::Get()->pp_module(),
+ PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ &negative_height, true);
+ if (rsrc)
+ return "Negative height accepted";
+
+ PP_Size negative_width;
+ negative_width.width = -2;
+ negative_width.height = 16;
+ rsrc = image_data_interface_->Create(
+ pp::Module::Get()->pp_module(),
+ PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ &negative_width, true);
+ if (rsrc)
+ return "Negative width accepted";
+
+ return "";
+}
+
+std::string TestImageData::TestHugeSize() {
+ pp::ImageData huge_size(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ pp::Size(100000000, 100000000), true);
+ if (!huge_size.is_null())
+ return "31-bit overflow size accepted";
+ return "";
+}
+
+std::string TestImageData::TestInitToZero() {
+ const int w = 5;
+ const int h = 6;
+ pp::ImageData img(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(w, h), true);
+ if (img.is_null())
+ return "Could not create bitmap";
+
+ // Basic validity checking of the bitmap. This also tests "describe" since
+ // that's where the image data object got its imfo from.
+ if (img.size().width() != w || img.size().height() != h)
+ return "Wrong size";
+ if (img.format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL)
+ return "Wrong format";
+ if (img.stride() < w * 4)
+ return "Stride too small";
+
+ // Now check that everything is 0.
+ for (int y = 0; y < h; y++) {
+ uint32_t* row = img.GetAddr32(pp::Point(0, y));
+ for (int x = 0; x < w; x++) {
+ if (row[x] != 0)
+ return "Image data isn't entirely zero";
+ }
+ }
+
+ return "";
+}
+
+std::string TestImageData::TestIsImageData() {
+ // Test that a NULL resource isn't an image data.
+ pp::Resource null_resource;
+ if (image_data_interface_->IsImageData(null_resource.pp_resource()))
+ return "Null resource was reported as a valid image";
+
+ // Make another resource type and test it.
+ const int w = 16, h = 16;
+ pp::Graphics2D device(pp::Size(w, h), true);
+ if (device.is_null())
+ return "Couldn't create device context";
+ if (image_data_interface_->IsImageData(device.pp_resource()))
+ return "Device context was reported as an image";
+
+ // Make a valid image resource.
+ pp::ImageData img(PP_IMAGEDATAFORMAT_BGRA_PREMUL, pp::Size(w, h), true);
+ if (img.is_null())
+ return "Couldn't create image data";
+ if (!image_data_interface_->IsImageData(img.pp_resource()))
+ return "Image data should be identified as an image";
+
+ return "";
+}
+
diff --git a/ppapi/tests/test_image_data.h b/ppapi/tests/test_image_data.h
new file mode 100644
index 0000000..c3f7dcd
--- /dev/null
+++ b/ppapi/tests/test_image_data.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_TESTS_TEST_IMAGE_DATA_H_
+#define PPAPI_TESTS_TEST_IMAGE_DATA_H_
+
+#include "ppapi/tests/test_case.h"
+
+struct PPB_ImageData;
+
+class TestImageData : public TestCase {
+ public:
+ TestImageData(TestingInstance* instance) : TestCase(instance) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ private:
+ std::string TestInvalidFormat();
+ std::string TestInvalidSize();
+ std::string TestHugeSize();
+ std::string TestInitToZero();
+ std::string TestIsImageData();
+
+ // Used by the tests that access the C API directly.
+ const PPB_ImageData* image_data_interface_;
+};
+
+#endif // PPAPI_TESTS_TEST_IMAGE_DATA_H_
diff --git a/ppapi/tests/test_image_data/test_image_data.cc b/ppapi/tests/test_image_data/test_image_data.cc
new file mode 100644
index 0000000..0f04472
--- /dev/null
+++ b/ppapi/tests/test_image_data/test_image_data.cc
@@ -0,0 +1,151 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_instance.h"
+
+#include "ppapi/cpp/device_context_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+
+class Instance : public TestInstance {
+ public:
+ Instance(PP_Instance instance) : TestInstance(instance) {}
+
+ virtual bool Init(size_t argc, const char* argn[], const char* argv[]) {
+ image_data_interface_ = reinterpret_cast<PPB_ImageData const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_IMAGEDATA_INTERFACE));
+ return !!image_data_interface_;
+ }
+
+ virtual std::string GetTestCaseName() const {
+ return std::string("ImageData");
+ }
+
+ virtual void RunTest() {
+ LogTest("InvalidFormat", TestInvalidFormat());
+ LogTest("InvalidSize", TestInvalidSize());
+ LogTest("HugeSize", TestHugeSize());
+ LogTest("InitToZero", TestInitToZero());
+ LogTest("IsImageData", TestIsImageData());
+ }
+
+ private:
+ std::string TestInvalidFormat() {
+ pp::ImageData a(static_cast<PP_ImageDataFormat>(1337), 16, 16, true);
+ if (!a.is_null())
+ return "Crazy image data format accepted";
+
+ pp::ImageData b(static_cast<PP_ImageDataFormat>(-1), 16, 16, true);
+ if (!b.is_null())
+ return "Negative image data format accepted";
+
+ return "";
+ }
+
+ std::string TestInvalidSize() {
+ pp::ImageData zero_size(PP_IMAGEDATAFORMAT_BGRA_PREMUL, 0, 0, true);
+ if (!zero_size.is_null())
+ return "Zero width and height accepted";
+
+ pp::ImageData zero_height(PP_IMAGEDATAFORMAT_BGRA_PREMUL, 16, 0, true);
+ if (!zero_height.is_null())
+ return "Zero height accepted";
+
+ pp::ImageData zero_width(PP_IMAGEDATAFORMAT_BGRA_PREMUL, 0, 16, true);
+ if (!zero_width.is_null())
+ return "Zero width accepted";
+
+ pp::ImageData negative_height(PP_IMAGEDATAFORMAT_BGRA_PREMUL, 16, -2, true);
+ if (!negative_height.is_null())
+ return "Negative height accepted";
+
+ pp::ImageData negative_width(PP_IMAGEDATAFORMAT_BGRA_PREMUL, -2, 16, true);
+ if (!negative_width.is_null())
+ return "Negative width accepted";
+
+ return "";
+ }
+
+ std::string TestHugeSize() {
+ pp::ImageData huge_size(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ 100000000, 100000000, true);
+ if (!huge_size.is_null())
+ return "31-bit overflow size accepted";
+ return "";
+ }
+
+ std::string TestInitToZero() {
+ const int w = 5;
+ const int h = 6;
+ pp::ImageData img(PP_IMAGEDATAFORMAT_BGRA_PREMUL, w, h, true);
+ if (img.is_null())
+ return "Could not create bitmap";
+
+ // Basic validity checking of the bitmap. This also tests "describe" since
+ // that's where the image data object got its imfo from.
+ if (img.width() != w || img.height() != h)
+ return "Wrong size";
+ if (img.format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL)
+ return "Wrong format";
+ if (img.stride() < w * 4)
+ return "Stride too small";
+
+ // Now check that everything is 0.
+ for (int y = 0; y < h; y++) {
+ uint32_t* row = img.GetAddr32(0, y);
+ for (int x = 0; x < w; x++) {
+ if (row[x] != 0)
+ return "Image data isn't entirely zero";
+ }
+ }
+
+ return "";
+ }
+
+ std::string TestIsImageData() {
+ // Test that a NULL resource isn't an image data.
+ pp::Resource null_resource;
+ if (image_data_interface_->IsImageData(null_resource.pp_resource()))
+ return "Null resource was reported as a valid image";
+
+ // Make another resource type and test it.
+ const int w = 16, h = 16;
+ pp::DeviceContext2D device(w, h, true);
+ if (device.is_null())
+ return "Couldn't create device context";
+ if (image_data_interface_->IsImageData(device.pp_resource()))
+ return "Device context was reported as an image";
+
+ // Make a valid image resource.
+ pp::ImageData img(PP_IMAGEDATAFORMAT_BGRA_PREMUL, w, h, true);
+ if (img.is_null())
+ return "Couldn't create image data";
+ if (!image_data_interface_->IsImageData(img.pp_resource()))
+ return "Image data should be identified as an image";
+
+ return "";
+ }
+
+ // Used by the tests that access the C API directly.
+ const PPB_ImageData* image_data_interface_;
+};
+
+class Module : public pp::Module {
+ public:
+ Module() : pp::Module() {}
+ virtual ~Module() {}
+
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new Instance(instance);
+ }
+};
+
+namespace pp {
+
+Module* CreateModule() {
+ return new ::Module();
+}
+
+} // namespace pp
diff --git a/ppapi/tests/test_image_data/test_image_data.html b/ppapi/tests/test_image_data/test_image_data.html
new file mode 100644
index 0000000..0dc06e5
--- /dev/null
+++ b/ppapi/tests/test_image_data/test_image_data.html
@@ -0,0 +1,11 @@
+<html><head>
+<title>Test PPAPI ImageData</title>
+<link rel="stylesheet" href="../test_page.css">
+</head><body>
+<h1>Test PPAPI ImageData</h1>
+
+<object id="plugin" type="application/x-ppapi-test-image-data" width="16" height="16"></object>
+
+<div id="console" /><span class="load_msg">loading...</span></div>
+
+</body></html>
diff --git a/ppapi/tests/test_instance_deprecated.cc b/ppapi/tests/test_instance_deprecated.cc
new file mode 100644
index 0000000..74e929a
--- /dev/null
+++ b/ppapi/tests/test_instance_deprecated.cc
@@ -0,0 +1,122 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_instance_deprecated.h"
+
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
+#include "ppapi/tests/testing_instance.h"
+
+namespace {
+
+static const char kSetValueFunction[] = "SetValue";
+static const char kSetExceptionFunction[] = "SetException";
+static const char kReturnValueFunction[] = "ReturnValue";
+
+// ScriptableObject used by instance.
+class InstanceSO : public pp::deprecated::ScriptableObject {
+ public:
+ InstanceSO(TestInstance* i) : test_instance_(i) {}
+
+ // pp::deprecated::ScriptableObject overrides.
+ bool HasMethod(const pp::Var& name, pp::Var* exception);
+ pp::Var Call(const pp::Var& name,
+ const std::vector<pp::Var>& args,
+ pp::Var* exception);
+
+ private:
+ TestInstance* test_instance_;
+};
+
+bool InstanceSO::HasMethod(const pp::Var& name, pp::Var* exception) {
+ if (!name.is_string())
+ return false;
+ return name.AsString() == kSetValueFunction ||
+ name.AsString() == kSetExceptionFunction ||
+ name.AsString() == kReturnValueFunction;
+}
+
+pp::Var InstanceSO::Call(const pp::Var& method_name,
+ const std::vector<pp::Var>& args,
+ pp::Var* exception) {
+ if (!method_name.is_string())
+ return false;
+ std::string name = method_name.AsString();
+
+ if (name == kSetValueFunction) {
+ if (args.size() != 1 || !args[0].is_string())
+ *exception = pp::Var("Bad argument to SetValue(<string>)");
+ else
+ test_instance_->set_string(args[0].AsString());
+ } else if (name == kSetExceptionFunction) {
+ if (args.size() != 1 || !args[0].is_string())
+ *exception = pp::Var("Bad argument to SetException(<string>)");
+ else
+ *exception = args[0];
+ } else if (name == kReturnValueFunction) {
+ if (args.size() != 1)
+ *exception = pp::Var("Need single arg to call ReturnValue");
+ else
+ return args[0];
+ } else {
+ *exception = pp::Var("Bad function call");
+ }
+
+ return pp::Var();
+}
+
+} // namespace
+
+REGISTER_TEST_CASE(Instance);
+
+TestInstance::TestInstance(TestingInstance* instance) : TestCase(instance) {
+}
+
+bool TestInstance::Init() {
+ return true;
+}
+
+void TestInstance::RunTest() {
+ RUN_TEST(ExecuteScript);
+}
+
+pp::deprecated::ScriptableObject* TestInstance::CreateTestObject() {
+ return new InstanceSO(this);
+}
+
+std::string TestInstance::TestExecuteScript() {
+ // Simple call back into the plugin.
+ pp::Var exception;
+ pp::Var ret = instance_->ExecuteScript(
+ "document.getElementById('plugin').SetValue('hello, world');",
+ &exception);
+ ASSERT_TRUE(ret.is_undefined());
+ ASSERT_TRUE(exception.is_undefined());
+ ASSERT_TRUE(string_ == "hello, world");
+
+ // Return values from the plugin should be returned.
+ ret = instance_->ExecuteScript(
+ "document.getElementById('plugin').ReturnValue('return value');",
+ &exception);
+ ASSERT_TRUE(ret.is_string() && ret.AsString() == "return value");
+ ASSERT_TRUE(exception.is_undefined());
+
+ // Exception thrown by the plugin should be caught.
+ ret = instance_->ExecuteScript(
+ "document.getElementById('plugin').SetException('plugin exception');",
+ &exception);
+ ASSERT_TRUE(ret.is_undefined());
+ ASSERT_TRUE(exception.is_string());
+ // TODO(brettw) bug 54011: The TryCatch isn't working properly and
+ // doesn't actually pass the exception text up.
+ //ASSERT_TRUE(exception.AsString() == "plugin exception");
+
+ // Exception caused by string evaluation should be caught.
+ exception = pp::Var();
+ ret = instance_->ExecuteScript("document.doesntExist()", &exception);
+ ASSERT_TRUE(ret.is_undefined());
+ ASSERT_TRUE(exception.is_string()); // Don't know exactly what it will say.
+
+ return std::string();
+}
diff --git a/ppapi/tests/test_instance_deprecated.h b/ppapi/tests/test_instance_deprecated.h
new file mode 100644
index 0000000..fdd7174
--- /dev/null
+++ b/ppapi/tests/test_instance_deprecated.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_TESTS_TEST_INSTANCE_H_
+#define PPAPI_TESTS_TEST_INSTANCE_H_
+
+#include <string>
+#include <vector>
+
+#include "ppapi/tests/test_case.h"
+
+class TestInstance : public TestCase {
+ public:
+ TestInstance(TestingInstance* instance);
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ void set_string(const std::string& s) { string_ = s; }
+
+ protected:
+ // Test case protected overrides.
+ virtual pp::deprecated::ScriptableObject* CreateTestObject();
+
+ private:
+ std::string TestExecuteScript();
+
+ // Value written by set_string which is called by the ScriptableObject. This
+ // allows us to keep track of what was called.
+ std::string string_;
+};
+
+#endif // PPAPI_TESTS_TEST_INSTANCE_H_
diff --git a/ppapi/tests/test_page.css b/ppapi/tests/test_page.css
new file mode 100644
index 0000000..7cce1ff
--- /dev/null
+++ b/ppapi/tests/test_page.css
@@ -0,0 +1,67 @@
+body {
+ font-family:Verdana,Arial,sans-serif;
+ padding: 0;
+ margin: 0;
+}
+
+p.frame-container {
+ margin: 0;
+ margin-top: 1em ! important;
+ margin-bottom: 1em ! important;
+ padding: 0;
+}
+
+p.frame-container > h2 {
+ font-size: 1.1em;
+ margin: 0;
+ margin-left: 10% ! important;
+ padding: 0;
+}
+
+p.frame-container > iframe {
+ margin: 0;
+ padding: 0;
+ border: none;
+ width: 100%;
+ height: 30%;
+}
+
+#console {
+ border:1px solid black;
+ padding:4px;
+ background-color:#EEE;
+ margin-left:10%;
+ margin-right:10%;
+}
+
+#container {
+ height: 16px;
+}
+
+#container > object {
+ width: 100%;
+ height: 100%;
+}
+
+.test_line {
+}
+
+.test_name {
+}
+
+.pass {
+ font-weight:bold;
+ color:#080;
+}
+
+.fail {
+ font-weight:bold;
+ color:#800;
+}
+
+.err_msg {
+}
+
+.load_msg {
+ font-style:italic;
+}
diff --git a/ppapi/tests/test_paint_aggregator.cc b/ppapi/tests/test_paint_aggregator.cc
new file mode 100644
index 0000000..7859a70
--- /dev/null
+++ b/ppapi/tests/test_paint_aggregator.cc
@@ -0,0 +1,426 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_paint_aggregator.h"
+
+#include "ppapi/cpp/paint_aggregator.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(PaintAggregator);
+
+bool TestPaintAggregator::Init() {
+ return true;
+}
+
+void TestPaintAggregator::RunTest() {
+ RUN_TEST(InitialState);
+ RUN_TEST(SingleInvalidation);
+ RUN_TEST(DoubleDisjointInvalidation);
+ RUN_TEST(SingleScroll);
+ RUN_TEST(DoubleOverlappingScroll);
+ RUN_TEST(NegatingScroll);
+ RUN_TEST(DiagonalScroll);
+ RUN_TEST(ContainedPaintAfterScroll);
+ RUN_TEST(ContainedPaintBeforeScroll);
+ RUN_TEST(ContainedPaintsBeforeAndAfterScroll);
+ RUN_TEST(LargeContainedPaintAfterScroll);
+ RUN_TEST(LargeContainedPaintBeforeScroll);
+ RUN_TEST(OverlappingPaintBeforeScroll);
+ RUN_TEST(OverlappingPaintAfterScroll);
+ RUN_TEST(DisjointPaintBeforeScroll);
+ RUN_TEST(DisjointPaintAfterScroll);
+ RUN_TEST(ContainedPaintTrimmedByScroll);
+ RUN_TEST(ContainedPaintEliminatedByScroll);
+ RUN_TEST(ContainedPaintAfterScrollTrimmedByScrollDamage);
+ RUN_TEST(ContainedPaintAfterScrollEliminatedByScrollDamage);
+}
+
+std::string TestPaintAggregator::TestInitialState() {
+ pp::PaintAggregator greg;
+ if (greg.HasPendingUpdate())
+ return "Pending update invalid";
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestSingleInvalidation() {
+ pp::PaintAggregator greg;
+
+ pp::Rect rect(2, 4, 10, 16);
+ greg.InvalidateRect(rect);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+ ASSERT_TRUE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(1U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(rect == greg.GetPendingUpdate().paint_rects[0]);
+
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestDoubleDisjointInvalidation() {
+ pp::PaintAggregator greg;
+
+ pp::Rect r1(2, 4, 2, 4);
+ pp::Rect r2(4, 2, 4, 2);
+
+ greg.InvalidateRect(r1);
+ greg.InvalidateRect(r2);
+
+ pp::Rect expected_bounds = r1.Union(r2);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+ ASSERT_TRUE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(2U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(expected_bounds == greg.GetPendingUpdate().paint_bounds);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestSingleScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect r1(2, 4, 2, 4);
+ pp::Rect r2(4, 2, 4, 2);
+
+ greg.InvalidateRect(r1);
+ greg.InvalidateRect(r2);
+
+ pp::Rect expected_bounds = r1.Union(r2);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+ ASSERT_TRUE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(2U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(expected_bounds == greg.GetPendingUpdate().paint_bounds);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestDoubleOverlappingScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect rect(1, 2, 3, 4);
+ pp::Point delta1(1, 0);
+ pp::Point delta2(1, 0);
+ greg.ScrollRect(rect, delta1);
+ greg.ScrollRect(rect, delta2);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+ ASSERT_TRUE(1U == greg.GetPendingUpdate().paint_rects.size());
+ ASSERT_FALSE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+
+ ASSERT_TRUE(rect == greg.GetPendingUpdate().scroll_rect);
+
+ pp::Point expected_delta(delta1.x() + delta2.x(),
+ delta1.y() + delta2.y());
+ ASSERT_TRUE(expected_delta.x() == greg.GetPendingUpdate().scroll_delta.x());
+ ASSERT_TRUE(expected_delta.y() == greg.GetPendingUpdate().scroll_delta.y());
+
+ pp::Rect resulting_damage = greg.GetPendingUpdate().paint_rects[0];
+ pp::Rect expected_damage(1, 2, 2, 4);
+ ASSERT_TRUE(expected_damage == resulting_damage);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestNegatingScroll() {
+ pp::PaintAggregator greg;
+
+ // Scroll twice in opposite directions by equal amounts. The result
+ // should be no scrolling.
+
+ pp::Rect rect(1, 2, 3, 4);
+ pp::Point delta1(1, 0);
+ pp::Point delta2(-1, 0);
+ greg.ScrollRect(rect, delta1);
+ greg.ScrollRect(rect, delta2);
+
+ ASSERT_FALSE(greg.HasPendingUpdate());
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestDiagonalScroll() {
+ pp::PaintAggregator greg;
+
+ // We don't support optimized diagonal scrolling, so this should result in
+ // repainting.
+
+ pp::Rect rect(1, 2, 3, 4);
+ pp::Point delta(1, 1);
+ greg.ScrollRect(rect, delta);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+ ASSERT_TRUE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(1U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(rect == greg.GetPendingUpdate().paint_rects[0]);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestContainedPaintAfterScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(2, 0));
+
+ pp::Rect paint_rect(4, 4, 2, 2);
+ greg.InvalidateRect(paint_rect);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ // Expecting a paint rect inside the scroll rect. The last paint rect is the
+ // scroll dirty rect.
+ ASSERT_FALSE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(2U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().scroll_rect);
+ ASSERT_TRUE(paint_rect == greg.GetPendingUpdate().paint_rects[0]);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestContainedPaintBeforeScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect paint_rect(4, 4, 2, 2);
+ greg.InvalidateRect(paint_rect);
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(2, 0));
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ // Expecting a paint rect inside the scroll rect. The last paint rect is the
+ // scroll dirty rect.
+ ASSERT_FALSE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(2U == greg.GetPendingUpdate().paint_rects.size());
+
+ paint_rect.Offset(2, 0);
+
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().scroll_rect);
+ ASSERT_TRUE(paint_rect == greg.GetPendingUpdate().paint_rects[0]);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestContainedPaintsBeforeAndAfterScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect paint_rect1(4, 4, 2, 2);
+ greg.InvalidateRect(paint_rect1);
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(2, 0));
+
+ pp::Rect paint_rect2(6, 4, 2, 2);
+ greg.InvalidateRect(paint_rect2);
+
+ pp::Rect expected_paint_rect = paint_rect2;
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ // Expecting a paint rect inside the scroll rect
+ ASSERT_FALSE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(2U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().scroll_rect);
+ ASSERT_TRUE(expected_paint_rect == greg.GetPendingUpdate().paint_rects[0]);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestLargeContainedPaintAfterScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(0, 1));
+
+ pp::Rect paint_rect(0, 0, 10, 9); // Repaint 90%
+ greg.InvalidateRect(paint_rect);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ ASSERT_TRUE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(1U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().paint_rects[0]);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestLargeContainedPaintBeforeScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect paint_rect(0, 0, 10, 9); // Repaint 90%
+ greg.InvalidateRect(paint_rect);
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(0, 1));
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ ASSERT_TRUE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(1U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().paint_rects[0]);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestOverlappingPaintBeforeScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect paint_rect(4, 4, 10, 2);
+ greg.InvalidateRect(paint_rect);
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(2, 0));
+
+ pp::Rect expected_paint_rect = scroll_rect.Union(paint_rect);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ ASSERT_TRUE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(1U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(expected_paint_rect == greg.GetPendingUpdate().paint_rects[0]);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestOverlappingPaintAfterScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(2, 0));
+
+ pp::Rect paint_rect(4, 4, 10, 2);
+ greg.InvalidateRect(paint_rect);
+
+ pp::Rect expected_paint_rect = scroll_rect.Union(paint_rect);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ ASSERT_TRUE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(1U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(expected_paint_rect == greg.GetPendingUpdate().paint_rects[0]);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestDisjointPaintBeforeScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect paint_rect(4, 4, 10, 2);
+ greg.InvalidateRect(paint_rect);
+
+ pp::Rect scroll_rect(0, 0, 2, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(2, 0));
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ ASSERT_FALSE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(2U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(paint_rect == greg.GetPendingUpdate().paint_rects[0]);
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().scroll_rect);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestDisjointPaintAfterScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect scroll_rect(0, 0, 2, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(2, 0));
+
+ pp::Rect paint_rect(4, 4, 10, 2);
+ greg.InvalidateRect(paint_rect);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ ASSERT_FALSE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(2U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(paint_rect == greg.GetPendingUpdate().paint_rects[0]);
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().scroll_rect);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestContainedPaintTrimmedByScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect paint_rect(4, 4, 6, 6);
+ greg.InvalidateRect(paint_rect);
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(2, 0));
+
+ // The paint rect should have become narrower.
+ pp::Rect expected_paint_rect(6, 4, 4, 6);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ ASSERT_FALSE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(2U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(expected_paint_rect == greg.GetPendingUpdate().paint_rects[0]);
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().scroll_rect);
+ return std::string();
+}
+
+std::string TestPaintAggregator::TestContainedPaintEliminatedByScroll() {
+ pp::PaintAggregator greg;
+
+ pp::Rect paint_rect(4, 4, 6, 6);
+ greg.InvalidateRect(paint_rect);
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(6, 0));
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ ASSERT_FALSE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(1U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().scroll_rect);
+ return std::string();
+}
+
+std::string
+TestPaintAggregator::TestContainedPaintAfterScrollTrimmedByScrollDamage() {
+ pp::PaintAggregator greg;
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(4, 0));
+
+ pp::Rect paint_rect(2, 0, 4, 10);
+ greg.InvalidateRect(paint_rect);
+
+ pp::Rect expected_scroll_damage(0, 0, 4, 10);
+ pp::Rect expected_paint_rect(4, 0, 2, 10);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ ASSERT_FALSE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(2U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().scroll_rect);
+ ASSERT_TRUE(expected_scroll_damage == greg.GetPendingUpdate().paint_rects[1]);
+ ASSERT_TRUE(expected_paint_rect == greg.GetPendingUpdate().paint_rects[0]);
+ return std::string();
+}
+
+std::string
+TestPaintAggregator::TestContainedPaintAfterScrollEliminatedByScrollDamage() {
+ pp::PaintAggregator greg;
+
+ pp::Rect scroll_rect(0, 0, 10, 10);
+ greg.ScrollRect(scroll_rect, pp::Point(4, 0));
+
+ pp::Rect paint_rect(2, 0, 2, 10);
+ greg.InvalidateRect(paint_rect);
+
+ pp::Rect expected_scroll_damage(0, 0, 4, 10);
+
+ ASSERT_TRUE(greg.HasPendingUpdate());
+
+ ASSERT_FALSE(greg.GetPendingUpdate().scroll_rect.IsEmpty());
+ ASSERT_TRUE(1U == greg.GetPendingUpdate().paint_rects.size());
+
+ ASSERT_TRUE(scroll_rect == greg.GetPendingUpdate().scroll_rect);
+ ASSERT_TRUE(expected_scroll_damage == greg.GetPendingUpdate().paint_rects[0]);
+ return std::string();
+}
diff --git a/ppapi/tests/test_paint_aggregator.h b/ppapi/tests/test_paint_aggregator.h
new file mode 100644
index 0000000..8649ee2
--- /dev/null
+++ b/ppapi/tests/test_paint_aggregator.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_TESTS_TEST_PAINT_AGGREGATOR_H_
+#define PPAPI_TESTS_TEST_PAINT_AGGREGATOR_H_
+
+#include "ppapi/tests/test_case.h"
+
+class TestPaintAggregator : public TestCase {
+ public:
+ TestPaintAggregator(TestingInstance* instance) : TestCase(instance) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ private:
+ std::string TestInitialState();
+ std::string TestSingleInvalidation();
+ std::string TestDoubleDisjointInvalidation();
+ std::string TestSingleScroll();
+ std::string TestDoubleOverlappingScroll();
+ std::string TestNegatingScroll();
+ std::string TestDiagonalScroll();
+ std::string TestContainedPaintAfterScroll();
+ std::string TestContainedPaintBeforeScroll();
+ std::string TestContainedPaintsBeforeAndAfterScroll();
+ std::string TestLargeContainedPaintAfterScroll();
+ std::string TestLargeContainedPaintBeforeScroll();
+ std::string TestOverlappingPaintBeforeScroll();
+ std::string TestOverlappingPaintAfterScroll();
+ std::string TestDisjointPaintBeforeScroll();
+ std::string TestDisjointPaintAfterScroll();
+ std::string TestContainedPaintTrimmedByScroll();
+ std::string TestContainedPaintEliminatedByScroll();
+ std::string TestContainedPaintAfterScrollTrimmedByScrollDamage();
+ std::string TestContainedPaintAfterScrollEliminatedByScrollDamage();
+};
+
+#endif // PPAPI_TESTS_TEST_PAINT_AGGREGATOR_H_
diff --git a/ppapi/tests/test_scrollbar.cc b/ppapi/tests/test_scrollbar.cc
new file mode 100644
index 0000000..fc5bd9d
--- /dev/null
+++ b/ppapi/tests/test_scrollbar.cc
@@ -0,0 +1,50 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_scrollbar.h"
+
+#include "ppapi/c/pp_input_event.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(Scrollbar);
+
+TestScrollbar::TestScrollbar(TestingInstance* instance)
+ : TestCase(instance),
+ WidgetClient_Dev(instance),
+ scrollbar_(*instance, true),
+ scrollbar_value_changed_(false) {
+}
+
+void TestScrollbar::RunTest() {
+ instance_->LogTest("HandleEvent", TestHandleEvent());
+}
+
+std::string TestScrollbar::TestHandleEvent() {
+ pp::Rect location;
+ location.set_width(1000);
+ location.set_height(1000);
+ scrollbar_.SetLocation(location);
+
+ scrollbar_.SetDocumentSize(10000);
+
+ PP_InputEvent event;
+ event.type = PP_INPUTEVENT_TYPE_KEYDOWN;
+ event.u.key.key_code = 0x28; // VKEY_DOWN
+ scrollbar_.HandleEvent(event);
+
+ return scrollbar_value_changed_ ?
+ "" : "Didn't get callback for scrollbar value change";
+}
+
+void TestScrollbar::InvalidateWidget(pp::Widget_Dev widget,
+ const pp::Rect& dirty_rect) {
+}
+
+void TestScrollbar::ScrollbarValueChanged(pp::Scrollbar_Dev scrollbar,
+ uint32_t value) {
+ if (scrollbar == scrollbar_)
+ scrollbar_value_changed_ = true;
+}
diff --git a/ppapi/tests/test_scrollbar.h b/ppapi/tests/test_scrollbar.h
new file mode 100644
index 0000000..9a9bb1d
--- /dev/null
+++ b/ppapi/tests/test_scrollbar.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PAPPI_TESTS_TEST_SCROLLBAR_H_
+#define PAPPI_TESTS_TEST_SCROLLBAR_H_
+
+#include "ppapi/cpp/dev/scrollbar_dev.h"
+#include "ppapi/cpp/dev/widget_client_dev.h"
+#include "ppapi/cpp/dev/widget_dev.h"
+#include "ppapi/tests/test_case.h"
+
+class TestScrollbar : public TestCase,
+ public pp::WidgetClient_Dev {
+ public:
+ TestScrollbar(TestingInstance* instance);
+
+ // TestCase implementation.
+ virtual void RunTest();
+
+ private:
+ std::string TestHandleEvent();
+
+ virtual void InvalidateWidget(pp::Widget_Dev widget,
+ const pp::Rect& dirty_rect);
+ virtual void ScrollbarValueChanged(pp::Scrollbar_Dev scrollbar,
+ uint32_t value);
+
+ pp::Scrollbar_Dev scrollbar_;
+ bool scrollbar_value_changed_;
+};
+
+#endif // PAPPI_TESTS_TEST_SCROLLBAR_H_
diff --git a/ppapi/tests/test_transport.cc b/ppapi/tests/test_transport.cc
new file mode 100644
index 0000000..9f506f6
--- /dev/null
+++ b/ppapi/tests/test_transport.cc
@@ -0,0 +1,50 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_transport.h"
+
+#include <string.h>
+
+#include <string>
+
+#include "ppapi/c/dev/ppb_testing_dev.h"
+#include "ppapi/c/dev/ppb_transport_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(Transport);
+
+bool TestTransport::Init() {
+ transport_interface_ = reinterpret_cast<PPB_Transport_Dev const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_TRANSPORT_DEV_INTERFACE));
+ testing_interface_ = reinterpret_cast<PPB_Testing_Dev const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE));
+ if (!testing_interface_) {
+ // Give a more helpful error message for the testing interface being gone
+ // since that needs special enabling in Chrome.
+ instance_->AppendError("This test needs the testing interface, which is "
+ "not currently available. In Chrome, use --enable-pepper-testing when "
+ "launching.");
+ }
+
+ return transport_interface_ && testing_interface_;
+}
+
+void TestTransport::RunTest() {
+ RUN_TEST(FirstTransport);
+ // TODO(juberti): more Transport tests here...
+}
+
+void TestTransport::QuitMessageLoop() {
+ testing_interface_->QuitMessageLoop();
+}
+
+std::string TestTransport::TestFirstTransport() {
+ // TODO(juberti): actual test
+ return "";
+}
+
diff --git a/ppapi/tests/test_transport.h b/ppapi/tests/test_transport.h
new file mode 100644
index 0000000..f7b57be
--- /dev/null
+++ b/ppapi/tests/test_transport.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PAPPI_TESTS_TEST_TRANSPORT_H_
+#define PAPPI_TESTS_TEST_TRANSPORT_H_
+
+#include <string>
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/tests/test_case.h"
+
+struct PPB_Testing_Dev;
+struct PPB_Transport_Dev;
+
+namespace pp {
+class Transport;
+}
+
+class TestTransport : public TestCase {
+ public:
+ explicit TestTransport(TestingInstance* instance) : TestCase(instance) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ void QuitMessageLoop();
+
+ private:
+ std::string TestFirstTransport();
+
+ // Used by the tests that access the C API directly.
+ const PPB_Testing_Dev* testing_interface_;
+ const PPB_Transport_Dev* transport_interface_;
+};
+
+#endif // PAPPI_TESTS_TEST_TRANSPORT_H_
+
diff --git a/ppapi/tests/test_url_loader.cc b/ppapi/tests/test_url_loader.cc
new file mode 100644
index 0000000..9fb64f2
--- /dev/null
+++ b/ppapi/tests/test_url_loader.cc
@@ -0,0 +1,315 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_url_loader.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "ppapi/c/dev/ppb_file_io_dev.h"
+#include "ppapi/c/dev/ppb_testing_dev.h"
+#include "ppapi/c/dev/ppb_url_loader_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_io_dev.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/dev/file_system_dev.h"
+#include "ppapi/cpp/dev/url_loader_dev.h"
+#include "ppapi/cpp/dev/url_request_info_dev.h"
+#include "ppapi/cpp/dev/url_response_info_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(URLLoader);
+
+namespace {
+
+const PPB_Testing_Dev* g_testing_interface;
+
+class TestCompletionCallback {
+ public:
+ TestCompletionCallback() : result_(PP_ERROR_WOULDBLOCK) {
+ }
+
+ operator pp::CompletionCallback() const {
+ return pp::CompletionCallback(&TestCompletionCallback::Handler,
+ const_cast<TestCompletionCallback*>(this));
+ }
+
+ int32_t WaitForResult() {
+ result_ = PP_ERROR_WOULDBLOCK; // Reset
+ g_testing_interface->RunMessageLoop();
+ return result_;
+ }
+
+ private:
+ static void Handler(void* user_data, int32_t result) {
+ static_cast<TestCompletionCallback*>(user_data)->result_ = result;
+ g_testing_interface->QuitMessageLoop();
+ }
+
+ int32_t result_;
+};
+
+std::string ReportError(const char* method, int32_t error) {
+ char error_as_string[12];
+ sprintf(error_as_string, "%d", error);
+ return method + std::string(" failed with error: ") + error_as_string;
+}
+
+} // namespace
+
+bool TestURLLoader::Init() {
+ g_testing_interface = reinterpret_cast<PPB_Testing_Dev const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE));
+ if (!g_testing_interface) {
+ // Give a more helpful error message for the testing interface being gone
+ // since that needs special enabling in Chrome.
+ instance_->AppendError("This test needs the testing interface, which is "
+ "not currently available. In Chrome, use --enable-pepper-testing when "
+ "launching.");
+ return false;
+ }
+
+ // Make sure we're running over HTTP.
+ pp::Var window = instance_->GetWindowObject();
+ pp::Var location = window.GetProperty("location");
+ pp::Var protocol = location.GetProperty("protocol");
+ if (!protocol.is_string() || protocol.AsString() != "http:") {
+ instance_->AppendError("This test needs to be run over HTTP.");
+ return false;
+ }
+
+ return true;
+}
+
+void TestURLLoader::RunTest() {
+ RUN_TEST(BasicGET);
+ RUN_TEST(BasicPOST);
+ RUN_TEST(CompoundBodyPOST);
+ RUN_TEST(EmptyDataPOST);
+ RUN_TEST(BinaryDataPOST);
+ RUN_TEST(CustomRequestHeader);
+ RUN_TEST(IgnoresBogusContentLength);
+ RUN_TEST(SameOriginRestriction);
+ RUN_TEST(StreamToFile);
+}
+
+std::string TestURLLoader::ReadEntireFile(pp::FileIO_Dev* file_io,
+ std::string* data) {
+ TestCompletionCallback callback;
+ char buf[256];
+ int64_t offset = 0;
+
+ for (;;) {
+ int32_t rv = file_io->Read(offset, buf, sizeof(buf), callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv < 0)
+ return ReportError("FileIO::Read", rv);
+ if (rv == 0)
+ break;
+ offset += rv;
+ data->append(buf, rv);
+ }
+
+ return "";
+}
+
+std::string TestURLLoader::ReadEntireResponseBody(pp::URLLoader_Dev* loader,
+ std::string* body) {
+ TestCompletionCallback callback;
+ char buf[256];
+
+ for (;;) {
+ int32_t rv = loader->ReadResponseBody(buf, sizeof(buf), callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv < 0)
+ return ReportError("URLLoader::ReadResponseBody", rv);
+ if (rv == 0)
+ break;
+ body->append(buf, rv);
+ }
+
+ return "";
+}
+
+std::string TestURLLoader::LoadAndCompareBody(
+ const pp::URLRequestInfo_Dev& request,
+ const std::string& expected_body) {
+ TestCompletionCallback callback;
+
+ pp::URLLoader_Dev loader(*instance_);
+ int32_t rv = loader.Open(request, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("URLLoader::Open", rv);
+
+ pp::URLResponseInfo_Dev response_info(loader.GetResponseInfo());
+ if (response_info.is_null())
+ return "URLLoader::GetResponseInfo returned null";
+ int32_t status_code = response_info.GetStatusCode();
+ if (status_code != 200)
+ return "Unexpected HTTP status code";
+
+ std::string body;
+ std::string error = ReadEntireResponseBody(&loader, &body);
+ if (!error.empty())
+ return error;
+
+ if (body.size() != expected_body.size())
+ return "URLLoader::ReadResponseBody returned unexpected content length";
+ if (body != expected_body)
+ return "URLLoader::ReadResponseBody returned unexpected content";
+
+ return "";
+}
+
+std::string TestURLLoader::TestBasicGET() {
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("test_url_loader_data/hello.txt");
+ return LoadAndCompareBody(request, "hello\n");
+}
+
+std::string TestURLLoader::TestBasicPOST() {
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("/echo");
+ request.SetMethod("POST");
+ std::string postdata("postdata");
+ request.AppendDataToBody(postdata.data(), postdata.length());
+ return LoadAndCompareBody(request, postdata);
+}
+
+std::string TestURLLoader::TestCompoundBodyPOST() {
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("/echo");
+ request.SetMethod("POST");
+ std::string postdata1("post");
+ request.AppendDataToBody(postdata1.data(), postdata1.length());
+ std::string postdata2("data");
+ request.AppendDataToBody(postdata2.data(), postdata2.length());
+ return LoadAndCompareBody(request, postdata1 + postdata2);
+}
+
+std::string TestURLLoader::TestEmptyDataPOST() {
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("/echo");
+ request.SetMethod("POST");
+ request.AppendDataToBody("", 0);
+ return LoadAndCompareBody(request, "");
+}
+
+std::string TestURLLoader::TestBinaryDataPOST() {
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("/echo");
+ request.SetMethod("POST");
+ const char postdata_chars[] =
+ "\x00\x01\x02\x03\x04\x05postdata\xfa\xfb\xfc\xfd\xfe\xff";
+ std::string postdata(postdata_chars,
+ sizeof(postdata_chars) / sizeof(postdata_chars[0]));
+ request.AppendDataToBody(postdata.data(), postdata.length());
+ return LoadAndCompareBody(request, postdata);
+}
+
+std::string TestURLLoader::TestCustomRequestHeader() {
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("/echoheader?Foo");
+ request.SetHeaders("Foo: 1");
+ return LoadAndCompareBody(request, "1");
+}
+
+std::string TestURLLoader::TestIgnoresBogusContentLength() {
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("/echo");
+ request.SetMethod("POST");
+ request.SetHeaders("Content-Length: 400");
+ std::string postdata("postdata");
+ request.AppendDataToBody(postdata.data(), postdata.length());
+ return LoadAndCompareBody(request, postdata);
+}
+
+std::string TestURLLoader::TestStreamToFile() {
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("test_url_loader_data/hello.txt");
+ request.SetStreamToFile(true);
+
+ TestCompletionCallback callback;
+
+ pp::URLLoader_Dev loader(*instance_);
+ int32_t rv = loader.Open(request, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("URLLoader::Open", rv);
+
+ pp::URLResponseInfo_Dev response_info(loader.GetResponseInfo());
+ if (response_info.is_null())
+ return "URLLoader::GetResponseInfo returned null";
+ int32_t status_code = response_info.GetStatusCode();
+ if (status_code != 200)
+ return "Unexpected HTTP status code";
+
+ pp::FileRef_Dev body(response_info.GetBody());
+ if (body.is_null())
+ return "URLResponseInfo::GetBody returned null";
+
+ rv = loader.FinishStreamingToFile(callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("URLLoader::FinishStreamingToFile", rv);
+
+
+ pp::FileIO_Dev reader;
+ rv = reader.Open(body, PP_FILEOPENFLAG_READ, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("FileIO::Open", rv);
+
+ std::string data;
+ std::string error = ReadEntireFile(&reader, &data);
+ if (!error.empty())
+ return error;
+
+ std::string expected_body = "hello\n";
+ if (data.size() != expected_body.size())
+ return "ReadEntireFile returned unexpected content length";
+ if (data != expected_body)
+ return "ReadEntireFile returned unexpected content";
+
+ int32_t file_descriptor = reader.GetOSFileDescriptor();
+ if (file_descriptor < 0)
+ return "FileIO::GetOSFileDescriptor() returned a bad file descriptor.";
+
+ return "";
+}
+
+std::string TestURLLoader::TestSameOriginRestriction() {
+ pp::URLRequestInfo_Dev request;
+ request.SetURL("http://www.google.com/");
+
+ TestCompletionCallback callback;
+
+ pp::URLLoader_Dev loader(*instance_);
+ int32_t rv = loader.Open(request, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+
+ // We expect a failure.
+ if (rv != PP_ERROR_NOACCESS) {
+ if (rv == PP_OK) {
+ return "URLLoader::Open() failed to block a cross-origin request.";
+ } else {
+ return ReportError("URLLoader::Open()", rv);
+ }
+ }
+
+ return "";
+}
+
+// TODO(darin): Add a test for GrantUniversalAccess.
diff --git a/ppapi/tests/test_url_loader.h b/ppapi/tests/test_url_loader.h
new file mode 100644
index 0000000..9664508
--- /dev/null
+++ b/ppapi/tests/test_url_loader.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PAPPI_TESTS_TEST_URL_LOADER_H_
+#define PAPPI_TESTS_TEST_URL_LOADER_H_
+
+#include <string>
+
+#include "ppapi/tests/test_case.h"
+
+namespace pp {
+class FileIO_Dev;
+class URLLoader_Dev;
+class URLRequestInfo_Dev;
+}
+
+class TestURLLoader : public TestCase {
+ public:
+ explicit TestURLLoader(TestingInstance* instance) : TestCase(instance) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ private:
+ std::string ReadEntireFile(pp::FileIO_Dev* file_io, std::string* data);
+ std::string ReadEntireResponseBody(pp::URLLoader_Dev* loader,
+ std::string* body);
+ std::string LoadAndCompareBody(const pp::URLRequestInfo_Dev& request,
+ const std::string& expected_body);
+
+ std::string TestBasicGET();
+ std::string TestBasicPOST();
+ std::string TestCompoundBodyPOST();
+ std::string TestEmptyDataPOST();
+ std::string TestBinaryDataPOST();
+ std::string TestCustomRequestHeader();
+ std::string TestIgnoresBogusContentLength();
+ std::string TestStreamToFile();
+ std::string TestSameOriginRestriction();
+};
+
+#endif // PAPPI_TESTS_TEST_URL_LOADER_H_
diff --git a/ppapi/tests/test_url_loader_data/hello.txt b/ppapi/tests/test_url_loader_data/hello.txt
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/ppapi/tests/test_url_loader_data/hello.txt
@@ -0,0 +1 @@
+hello
diff --git a/ppapi/tests/test_url_util.cc b/ppapi/tests/test_url_util.cc
new file mode 100644
index 0000000..a5749d7
--- /dev/null
+++ b/ppapi/tests/test_url_util.cc
@@ -0,0 +1,118 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_url_util.h"
+
+#include "ppapi/c/dev/ppb_url_util_dev.h"
+#include "ppapi/cpp/dev/url_util_dev.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(UrlUtil);
+
+static bool ComponentEquals(const PP_UrlComponent_Dev& component,
+ int begin, int len) {
+ return component.begin == begin && component.len == len;
+}
+
+bool TestUrlUtil::Init() {
+ util_ = pp::UrlUtil_Dev::Get();
+ return !!util_;
+}
+
+void TestUrlUtil::RunTest() {
+ RUN_TEST(Canonicalize);
+ RUN_TEST(ResolveRelative);
+ RUN_TEST(IsSameSecurityOrigin);
+ RUN_TEST(DocumentCanRequest);
+ RUN_TEST(DocumentCanAccessDocument);
+}
+
+std::string TestUrlUtil::TestCanonicalize() {
+ // Test no canonicalize output.
+ pp::Var result = util_->Canonicalize("http://Google.com");
+ ASSERT_TRUE(result.AsString() == "http://google.com/");
+
+ // Test all the components
+ PP_UrlComponents_Dev c;
+ result = util_->Canonicalize(
+ "http://me:pw@Google.com:1234/path?query#ref ",
+ &c);
+ ASSERT_TRUE(result.AsString() ==
+ // 0 1 2 3 4
+ // 0123456789012345678901234567890123456789012
+ "http://me:pw@google.com:1234/path?query#ref");
+ ASSERT_TRUE(ComponentEquals(c.scheme, 0, 4));
+ ASSERT_TRUE(ComponentEquals(c.username, 7, 2));
+ ASSERT_TRUE(ComponentEquals(c.password, 10, 2));
+ ASSERT_TRUE(ComponentEquals(c.host, 13, 10));
+ ASSERT_TRUE(ComponentEquals(c.port, 24, 4));
+ ASSERT_TRUE(ComponentEquals(c.path, 28, 5));
+ ASSERT_TRUE(ComponentEquals(c.query, 34, 5));
+ ASSERT_TRUE(ComponentEquals(c.ref, 40, 3));
+
+ // Test minimal components.
+ result = util_->Canonicalize("http://google.com/", &c);
+ // 0 1
+ // 0123456789012345678
+ ASSERT_TRUE(result.AsString() == "http://google.com/");
+ ASSERT_TRUE(ComponentEquals(c.scheme, 0, 4));
+ ASSERT_TRUE(ComponentEquals(c.username, 0, -1));
+ ASSERT_TRUE(ComponentEquals(c.password, 0, -1));
+ ASSERT_TRUE(ComponentEquals(c.host, 7, 10));
+ ASSERT_TRUE(ComponentEquals(c.port, 0, -1));
+ ASSERT_TRUE(ComponentEquals(c.path, 17, 1));
+ ASSERT_TRUE(ComponentEquals(c.query, 0, -1));
+ ASSERT_TRUE(ComponentEquals(c.ref, 0, -1));
+
+ return std::string();
+}
+
+std::string TestUrlUtil::TestResolveRelative() {
+ const int kTestCount = 6;
+ struct TestCase {
+ const char* base;
+ const char* relative;
+ const char* expected; // NULL if
+ } test_cases[kTestCount] = {
+ {"http://google.com/", "foo", "http://google.com/foo"},
+ {"http://google.com/foo", "/bar", "http://google.com/bar"},
+ {"http://foo/", "http://bar", "http://bar/"},
+ {"data:foo", "/bar", NULL},
+ {"data:foo", "http://foo/", "http://foo/"},
+ {"http://foo/", "", "http://foo/"},
+ };
+
+ for (int i = 0; i < kTestCount; i++) {
+ pp::Var result = util_->ResolveRelativeToUrl(test_cases[i].base,
+ test_cases[i].relative);
+ if (test_cases[i].expected == NULL) {
+ ASSERT_TRUE(result.is_null());
+ } else {
+ ASSERT_TRUE(result.AsString() == test_cases[i].expected);
+ }
+ }
+ return std::string();
+}
+
+std::string TestUrlUtil::TestIsSameSecurityOrigin() {
+ ASSERT_FALSE(util_->IsSameSecurityOrigin("http://google.com/",
+ "http://example.com/"));
+ ASSERT_TRUE(util_->IsSameSecurityOrigin("http://google.com/foo",
+ "http://google.com/bar"));
+ return std::string();
+}
+
+std::string TestUrlUtil::TestDocumentCanRequest() {
+ // This is hard to test, but we can at least verify we can't request
+ // some random domain.
+ ASSERT_FALSE(util_->DocumentCanRequest(*instance_, "http://evil.com/"));
+ return std::string();
+}
+
+std::string TestUrlUtil::TestDocumentCanAccessDocument() {
+ // This is hard to test, but we can at least verify we can access ourselves.
+ ASSERT_TRUE(util_->DocumentCanAccessDocument(*instance_, *instance_));
+ return std::string();
+}
+
diff --git a/ppapi/tests/test_url_util.h b/ppapi/tests/test_url_util.h
new file mode 100644
index 0000000..2d3b2ff
--- /dev/null
+++ b/ppapi/tests/test_url_util.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_TESTS_TEST_URL_UTIL_H_
+#define PPAPI_TESTS_TEST_URL_UTIL_H_
+
+#include "ppapi/cpp/dev/url_util_dev.h"
+#include "ppapi/tests/test_case.h"
+
+class TestUrlUtil : public TestCase {
+ public:
+ TestUrlUtil(TestingInstance* instance) : TestCase(instance), util_(NULL) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ private:
+ std::string TestCanonicalize();
+ std::string TestResolveRelative();
+ std::string TestIsSameSecurityOrigin();
+ std::string TestDocumentCanRequest();
+ std::string TestDocumentCanAccessDocument();
+
+ const pp::UrlUtil_Dev* util_;
+};
+
+#endif // PPAPI_TESTS_TEST_URL_UTIL_H_
diff --git a/ppapi/tests/test_var.cc b/ppapi/tests/test_var.cc
new file mode 100644
index 0000000..efd0dd1
--- /dev/null
+++ b/ppapi/tests/test_var.cc
@@ -0,0 +1,178 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_var.h"
+
+#include <limits>
+
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/dev/ppb_testing_dev.h"
+#include "ppapi/c/ppb_var.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(Var);
+
+namespace {
+pp::Var adoptVar(PP_Var var) {
+ return pp::Var(pp::Var::PassRef(), var);
+}
+} // namespace
+
+bool TestVar::Init() {
+ var_interface_ = reinterpret_cast<PPB_Var const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
+ testing_interface_ = reinterpret_cast<PPB_Testing_Dev const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE));
+ if (!testing_interface_) {
+ // Give a more helpful error message for the testing interface being gone
+ // since that needs special enabling in Chrome.
+ instance_->AppendError("This test needs the testing interface, which is "
+ "not currently available. In Chrome, use --enable-pepper-testing when "
+ "launching.");
+ }
+ return var_interface_ && testing_interface_;
+}
+
+void TestVar::RunTest() {
+ RUN_TEST(ConvertType);
+ RUN_TEST(DefineProperty);
+}
+
+std::string TestVar::TestConvertType() {
+ pp::Var result;
+ PP_Var exception = PP_MakeUndefined();
+ double NaN = std::numeric_limits<double>::quiet_NaN();
+
+ // Int to string
+ result = adoptVar(var_interface_->ConvertType(instance_->pp_instance(),
+ pp::Var(100).pp_var(),
+ PP_VARTYPE_STRING,
+ &exception));
+ ASSERT_EQ(pp::Var("100"), result);
+ ASSERT_TRUE(adoptVar(exception).is_undefined());
+
+ // Int to double
+ result = adoptVar(var_interface_->ConvertType(instance_->pp_instance(),
+ pp::Var(100).pp_var(),
+ PP_VARTYPE_DOUBLE,
+ &exception));
+ ASSERT_EQ(pp::Var(100.0), result);
+ ASSERT_TRUE(adoptVar(exception).is_undefined());
+
+ // Double to int
+ result = adoptVar(var_interface_->ConvertType(instance_->pp_instance(),
+ pp::Var(100.0).pp_var(),
+ PP_VARTYPE_INT32,
+ &exception));
+ ASSERT_EQ(pp::Var(100), result);
+ ASSERT_TRUE(adoptVar(exception).is_undefined());
+
+ // Double(NaN) to int
+ result = adoptVar(var_interface_->ConvertType(instance_->pp_instance(),
+ pp::Var(NaN).pp_var(),
+ PP_VARTYPE_INT32,
+ &exception));
+ ASSERT_EQ(pp::Var(0), result);
+ ASSERT_TRUE(adoptVar(exception).is_undefined());
+
+ // Double to string
+ result = adoptVar(var_interface_->ConvertType(instance_->pp_instance(),
+ pp::Var(100.0).pp_var(),
+ PP_VARTYPE_STRING,
+ &exception));
+ ASSERT_EQ(pp::Var("100"), result);
+ ASSERT_TRUE(adoptVar(exception).is_undefined());
+
+ // Double(NaN) to string
+ result = adoptVar(var_interface_->ConvertType(instance_->pp_instance(),
+ pp::Var(NaN).pp_var(),
+ PP_VARTYPE_STRING,
+ &exception));
+ ASSERT_EQ(pp::Var("NaN"), result);
+ ASSERT_TRUE(adoptVar(exception).is_undefined());
+
+ // String to int, valid string
+ result = adoptVar(var_interface_->ConvertType(instance_->pp_instance(),
+ pp::Var("100").pp_var(),
+ PP_VARTYPE_INT32,
+ &exception));
+ ASSERT_EQ(pp::Var(100), result);
+ ASSERT_TRUE(adoptVar(exception).is_undefined());
+
+ // String to int, invalid string
+ result = adoptVar(var_interface_->ConvertType(instance_->pp_instance(),
+ pp::Var("jockey").pp_var(),
+ PP_VARTYPE_INT32,
+ &exception));
+ ASSERT_EQ(pp::Var(0), result);
+ ASSERT_TRUE(adoptVar(exception).is_undefined());
+
+ PASS();
+}
+
+std::string TestVar::TestDefineProperty() {
+ pp::Var exception;
+ pp::Var property;
+ pp::Var value;
+ PP_Var unmanaged_exception = PP_MakeUndefined();
+
+ // Create an empty object.
+ pp::Var test_obj = instance_->ExecuteScript("({})", &exception);
+ ASSERT_TRUE(exception.is_undefined());
+ ASSERT_TRUE(test_obj.is_object());
+
+ // Define a simple property.
+ property = "x";
+ value = 1001;
+ var_interface_->DefineProperty(test_obj.pp_var(),
+ PP_MakeSimpleProperty(property.pp_var(),
+ value.pp_var()),
+ &unmanaged_exception);
+ ASSERT_TRUE(adoptVar(unmanaged_exception).is_undefined());
+
+ ASSERT_EQ(value, test_obj.GetProperty(property, &exception));
+ ASSERT_TRUE(exception.is_undefined());
+
+ // Define a property with a getter that always returns 123 and setter that
+ // sets another property to the given value.
+ property = "y";
+ pp::Var getter = instance_->ExecuteScript(
+ "(function(){return 'okey';})", &exception);
+ ASSERT_TRUE(getter.is_object());
+ ASSERT_TRUE(exception.is_undefined());
+ pp::Var setter = instance_->ExecuteScript(
+ "(function(x){this['another']=x;})", &exception);
+ ASSERT_TRUE(setter.is_object());
+ ASSERT_TRUE(exception.is_undefined());
+
+ struct PP_ObjectProperty property_attributes = {
+ property.pp_var(),
+ PP_MakeUndefined(),
+ getter.pp_var(),
+ setter.pp_var(),
+ PP_OBJECTPROPERTY_MODIFIER_NONE
+ };
+ var_interface_->DefineProperty(test_obj.pp_var(), property_attributes,
+ &unmanaged_exception);
+ ASSERT_TRUE(adoptVar(unmanaged_exception).is_undefined());
+
+ value = test_obj.GetProperty(property, &exception);
+ ASSERT_EQ(pp::Var("okey"), value);
+ ASSERT_TRUE(exception.is_undefined());
+
+ value = test_obj.GetProperty("another", &exception);
+ ASSERT_TRUE(value.is_undefined());
+ ASSERT_TRUE(exception.is_undefined());
+
+ test_obj.SetProperty("another", "dokey", &exception);
+ ASSERT_TRUE(exception.is_undefined());
+
+ ASSERT_EQ(pp::Var("dokey"), test_obj.GetProperty("another", &exception));
+ ASSERT_TRUE(exception.is_undefined());
+
+ PASS();
+}
+
diff --git a/ppapi/tests/test_var.h b/ppapi/tests/test_var.h
new file mode 100644
index 0000000..8499003
--- /dev/null
+++ b/ppapi/tests/test_var.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_TEST_TEST_VAR_H_
+#define PPAPI_TEST_TEST_VAR_H_
+
+#include <string>
+
+#include "ppapi/tests/test_case.h"
+
+struct PPB_Testing_Dev;
+struct PPB_Var;
+
+class TestVar : public TestCase {
+ public:
+ explicit TestVar(TestingInstance* instance) : TestCase(instance) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ private:
+ std::string TestConvertType();
+ std::string TestDefineProperty();
+
+ // Used by the tests that access the C API directly.
+ const PPB_Var* var_interface_;
+ const PPB_Testing_Dev* testing_interface_;
+};
+
+#endif // PPAPI_TEST_TEST_VAR_H_
diff --git a/ppapi/tests/test_var_deprecated.cc b/ppapi/tests/test_var_deprecated.cc
new file mode 100644
index 0000000..084afaf
--- /dev/null
+++ b/ppapi/tests/test_var_deprecated.cc
@@ -0,0 +1,329 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_var_deprecated.h"
+
+#include <string.h>
+
+#include <limits>
+
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/dev/ppb_testing_dev.h"
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+#include "ppapi/tests/testing_instance.h"
+
+static uint32_t kInvalidLength = static_cast<uint32_t>(-1);
+
+REGISTER_TEST_CASE(VarDeprecated);
+
+bool TestVarDeprecated::Init() {
+ var_interface_ = reinterpret_cast<PPB_Var_Deprecated const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_VAR_DEPRECATED_INTERFACE));
+ testing_interface_ = reinterpret_cast<PPB_Testing_Dev const*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE));
+ if (!testing_interface_) {
+ // Give a more helpful error message for the testing interface being gone
+ // since that needs special enabling in Chrome.
+ instance_->AppendError("This test needs the testing interface, which is "
+ "not currently available. In Chrome, use --enable-pepper-testing when "
+ "launching.");
+ }
+ return var_interface_ && testing_interface_;
+}
+
+void TestVarDeprecated::RunTest() {
+ RUN_TEST(BasicString);
+ RUN_TEST(InvalidAndEmpty);
+ RUN_TEST(InvalidUtf8);
+ RUN_TEST(NullInputInUtf8Conversion);
+ RUN_TEST(ValidUtf8);
+ RUN_TEST(Utf8WithEmbeddedNulls);
+ RUN_TEST(VarToUtf8ForWrongType);
+ RUN_TEST(HasPropertyAndMethod);
+}
+
+std::string TestVarDeprecated::TestBasicString() {
+ uint32_t before_object = testing_interface_->GetLiveObjectCount(
+ pp::Module::Get()->pp_module());
+ {
+ const uint32_t kStrLen = 5;
+ const char kStr[kStrLen + 1] = "Hello";
+ PP_Var str = var_interface_->VarFromUtf8(pp::Module::Get()->pp_module(),
+ kStr, sizeof(kStr) - 1);
+ ASSERT_EQ(PP_VARTYPE_STRING, str.type);
+
+ // Reading back the string should work.
+ uint32_t len = 0;
+ const char* result = var_interface_->VarToUtf8(str, &len);
+ ASSERT_EQ(kStrLen, len);
+ ASSERT_EQ(0, strncmp(kStr, result, kStrLen));
+
+ // Destroy the string, readback should now fail.
+ var_interface_->Release(str);
+ result = var_interface_->VarToUtf8(str, &len);
+ ASSERT_EQ(0, len);
+ ASSERT_EQ(NULL, result);
+ }
+
+ // Make sure nothing leaked.
+ ASSERT_TRUE(testing_interface_->GetLiveObjectCount(
+ pp::Module::Get()->pp_module()) == before_object);
+
+ return std::string();
+}
+
+std::string TestVarDeprecated::TestInvalidAndEmpty() {
+ PP_Var invalid_string;
+ invalid_string.type = PP_VARTYPE_STRING;
+ invalid_string.value.as_id = 31415926;
+
+ // Invalid strings should give NULL as the return value.
+ uint32_t len = std::numeric_limits<uint32_t>::max();
+ const char* result = var_interface_->VarToUtf8(invalid_string, &len);
+ ASSERT_EQ(0, len);
+ ASSERT_EQ(NULL, result);
+
+ // Same with vars that are not strings.
+ len = std::numeric_limits<uint32_t>::max();
+ pp::Var int_var(42);
+ result = var_interface_->VarToUtf8(int_var.pp_var(), &len);
+ ASSERT_EQ(0, len);
+ ASSERT_EQ(NULL, result);
+
+ // Empty strings should return non-NULL.
+ pp::Var empty_string("");
+ len = std::numeric_limits<uint32_t>::max();
+ result = var_interface_->VarToUtf8(empty_string.pp_var(), &len);
+ ASSERT_EQ(0, len);
+ ASSERT_NE(NULL, result);
+
+ return std::string();
+}
+
+std::string TestVarDeprecated::TestInvalidUtf8() {
+ // utf8じゃăȘい (japanese for "is not utf8") in shift-jis encoding.
+ static const char kSjisString[] = "utf8\x82\xb6\x82\xe1\x82\xc8\x82\xa2";
+ pp::Var sjis(kSjisString);
+ if (!sjis.is_null())
+ return "Non-UTF8 string permitted.";
+
+ return "";
+}
+
+std::string TestVarDeprecated::TestNullInputInUtf8Conversion() {
+ // This test talks directly to the C interface to access edge cases that
+ // cannot be exercised via the C++ interface.
+ PP_Var converted_string;
+
+ // 0-length string should not dereference input string, and should produce
+ // an empty string.
+ converted_string = var_interface_->VarFromUtf8(
+ pp::Module::Get()->pp_module(), NULL, 0);
+ if (converted_string.type != PP_VARTYPE_STRING) {
+ return "Expected 0 length to return empty string.";
+ }
+
+ // Now convert it back.
+ uint32_t length = kInvalidLength;
+ const char* result = NULL;
+ result = var_interface_->VarToUtf8(converted_string, &length);
+ if (length != 0) {
+ return "Expected 0 length string on conversion.";
+ }
+ if (result == NULL) {
+ return "Expected a non-null result for 0-lengthed string from VarToUtf8.";
+ }
+
+ // Should not crash, and make an empty string.
+ const char* null_string = NULL;
+ pp::Var null_var(null_string);
+ if (!null_var.is_string() || null_var.AsString() != "") {
+ return "Expected NULL input to make an empty string Var.";
+ }
+
+ return "";
+}
+
+std::string TestVarDeprecated::TestValidUtf8() {
+ // From UTF8 string -> PP_Var.
+ // Chinese for "I am utf8."
+ static const char kValidUtf8[] = "\xe6\x88\x91\xe6\x98\xafutf8.";
+ pp::Var converted_string(kValidUtf8);
+
+ if (converted_string.is_null())
+ return "Unable to convert valid utf8 to var.";
+
+ // Since we're already here, test PP_Var back to UTF8 string.
+ std::string returned_string = converted_string.AsString();
+
+ // We need to check against 1 less than sizeof because the resulting string
+ // is technically not NULL terminated by API design.
+ if (returned_string.size() != sizeof(kValidUtf8) - 1) {
+ return "Unable to convert utf8 string back from var.";
+ }
+ if (returned_string != kValidUtf8) {
+ return "String mismatches on conversion back from PP_Var.";
+ }
+
+ return "";
+}
+
+std::string TestVarDeprecated::TestUtf8WithEmbeddedNulls() {
+ // From UTF8 string with embedded nulls -> PP_Var.
+ // Chinese for "also utf8."
+ static const char kUtf8WithEmbededNull[] = "\xe6\xb9\x9f\xe6\x98\xaf\0utf8.";
+ std::string orig_string(kUtf8WithEmbededNull,
+ sizeof(kUtf8WithEmbededNull) -1);
+ pp::Var converted_string(orig_string);
+
+ if (converted_string.is_null())
+ return "Unable to convert utf8 with embedded nulls to var.";
+
+ // Since we're already here, test PP_Var back to UTF8 string.
+ std::string returned_string = converted_string.AsString();
+
+ if (returned_string.size() != orig_string.size()) {
+ return "Unable to convert utf8 with embedded nulls back from var.";
+ }
+ if (returned_string != orig_string) {
+ return "String mismatches on conversion back from PP_Var.";
+ }
+
+ return "";
+}
+
+std::string TestVarDeprecated::TestVarToUtf8ForWrongType() {
+ uint32_t length = kInvalidLength;
+ const char* result = NULL;
+ result = var_interface_->VarToUtf8(PP_MakeUndefined(), &length);
+ if (length != 0) {
+ return "Expected 0 on string conversion from Void var.";
+ }
+ if (result != NULL) {
+ return "Expected NULL on string conversion from Void var.";
+ }
+
+ length = kInvalidLength;
+ result = NULL;
+ result = var_interface_->VarToUtf8(PP_MakeNull(), &length);
+ if (length != 0) {
+ return "Expected 0 on string conversion from Null var.";
+ }
+ if (result != NULL) {
+ return "Expected NULL on string conversion from Null var.";
+ }
+
+ length = kInvalidLength;
+ result = NULL;
+ result = var_interface_->VarToUtf8(PP_MakeBool(true), &length);
+ if (length != 0) {
+ return "Expected 0 on string conversion from Bool var.";
+ }
+ if (result != NULL) {
+ return "Expected NULL on string conversion from Bool var.";
+ }
+
+ length = kInvalidLength;
+ result = NULL;
+ result = var_interface_->VarToUtf8(PP_MakeInt32(1), &length);
+ if (length != 0) {
+ return "Expected 0 on string conversion from Int32 var.";
+ }
+ if (result != NULL) {
+ return "Expected NULL on string conversion from Int32 var.";
+ }
+
+ length = kInvalidLength;
+ result = NULL;
+ result = var_interface_->VarToUtf8(PP_MakeDouble(1.0), &length);
+ if (length != 0) {
+ return "Expected 0 on string conversion from Double var.";
+ }
+ if (result != NULL) {
+ return "Expected NULL on string conversion from Double var.";
+ }
+
+ return "";
+}
+
+std::string TestVarDeprecated::TestHasPropertyAndMethod() {
+ uint32_t before_objects = testing_interface_->GetLiveObjectCount(
+ pp::Module::Get()->pp_module());
+ {
+ pp::Var window = instance_->GetWindowObject();
+ ASSERT_TRUE(window.is_object());
+
+ // Regular property.
+ pp::Var exception;
+ ASSERT_TRUE(window.HasProperty("scrollX", &exception));
+ ASSERT_TRUE(exception.is_undefined());
+ ASSERT_FALSE(window.HasMethod("scrollX", &exception));
+ ASSERT_TRUE(exception.is_undefined());
+
+ // Regular method (also counts as HasProperty).
+ ASSERT_TRUE(window.HasProperty("find", &exception));
+ ASSERT_TRUE(exception.is_undefined());
+ ASSERT_TRUE(window.HasMethod("find", &exception));
+ ASSERT_TRUE(exception.is_undefined());
+
+ // Nonexistant ones should return false and not set the exception.
+ ASSERT_FALSE(window.HasProperty("superEvilBit", &exception));
+ ASSERT_TRUE(exception.is_undefined());
+ ASSERT_FALSE(window.HasMethod("superEvilBit", &exception));
+ ASSERT_TRUE(exception.is_undefined());
+
+ // Check exception and return false on invalid property name.
+ ASSERT_FALSE(window.HasProperty(3.14159, &exception));
+ ASSERT_FALSE(exception.is_undefined());
+ exception = pp::Var();
+
+ exception = pp::Var();
+ ASSERT_FALSE(window.HasMethod(3.14159, &exception));
+ ASSERT_FALSE(exception.is_undefined());
+
+ // Try to use something not an object.
+ exception = pp::Var();
+ pp::Var string_object("asdf");
+ ASSERT_FALSE(string_object.HasProperty("find", &exception));
+ ASSERT_FALSE(exception.is_undefined());
+ exception = pp::Var();
+ ASSERT_FALSE(string_object.HasMethod("find", &exception));
+ ASSERT_FALSE(exception.is_undefined());
+
+ // Try to use an invalid object (need to use the C API).
+ PP_Var invalid_object;
+ invalid_object.type = PP_VARTYPE_OBJECT;
+ invalid_object.value.as_id = static_cast<int64_t>(-1234567);
+ PP_Var exception2 = PP_MakeUndefined();
+ ASSERT_FALSE(var_interface_->HasProperty(invalid_object,
+ pp::Var("find").pp_var(),
+ &exception2));
+ ASSERT_NE(PP_VARTYPE_UNDEFINED, exception2.type);
+ var_interface_->Release(exception2);
+
+ exception2 = PP_MakeUndefined();
+ ASSERT_FALSE(var_interface_->HasMethod(invalid_object,
+ pp::Var("find").pp_var(),
+ &exception2));
+ ASSERT_NE(PP_VARTYPE_UNDEFINED, exception2.type);
+ var_interface_->Release(exception2);
+
+ // Get a valid property/method when the exception is set returns false.
+ exception = pp::Var("Bad something-or-other exception");
+ ASSERT_FALSE(window.HasProperty("find", &exception));
+ ASSERT_FALSE(exception.is_undefined());
+ ASSERT_FALSE(window.HasMethod("find", &exception));
+ ASSERT_FALSE(exception.is_undefined());
+ }
+
+ // Make sure nothing leaked.
+ ASSERT_TRUE(testing_interface_->GetLiveObjectCount(
+ pp::Module::Get()->pp_module()) == before_objects);
+
+ return std::string();
+}
+
diff --git a/ppapi/tests/test_var_deprecated.h b/ppapi/tests/test_var_deprecated.h
new file mode 100644
index 0000000..6b7902a9
--- /dev/null
+++ b/ppapi/tests/test_var_deprecated.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_TEST_TEST_VAR_DEPRECATED_H_
+#define PPAPI_TEST_TEST_VAR_DEPRECATED_H_
+
+#include <string>
+
+#include "ppapi/tests/test_case.h"
+
+struct PPB_Testing_Dev;
+struct PPB_Var_Deprecated;
+
+class TestVarDeprecated : public TestCase {
+ public:
+ explicit TestVarDeprecated(TestingInstance* instance) : TestCase(instance) {}
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTest();
+
+ private:
+ std::string TestBasicString();
+ std::string TestInvalidAndEmpty();
+ std::string TestInvalidUtf8();
+ std::string TestNullInputInUtf8Conversion();
+ std::string TestValidUtf8();
+ std::string TestUtf8WithEmbeddedNulls();
+ std::string TestVarToUtf8ForWrongType();
+ std::string TestHasPropertyAndMethod();
+
+ // Used by the tests that access the C API directly.
+ const PPB_Var_Deprecated* var_interface_;
+ const PPB_Testing_Dev* testing_interface_;
+};
+
+#endif // PPAPI_TEST_TEST_VAR_DEPRECATED_H_
+
diff --git a/ppapi/tests/testing_instance.cc b/ppapi/tests/testing_instance.cc
new file mode 100644
index 0000000..9cdd942
--- /dev/null
+++ b/ppapi/tests/testing_instance.cc
@@ -0,0 +1,182 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/testing_instance.h"
+
+#include <algorithm>
+#include <string.h>
+
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+#include "ppapi/tests/test_case.h"
+
+TestCaseFactory* TestCaseFactory::head_ = NULL;
+
+// Returns a new heap-allocated test case for the given test, or NULL on
+// failure.
+TestingInstance::TestingInstance(PP_Instance instance)
+ : pp::Instance(instance),
+ current_case_(NULL),
+ executed_tests_(false) {
+ callback_factory_.Initialize(this);
+}
+
+bool TestingInstance::Init(uint32_t argc, const char* argn[], const char* argv[]) {
+ // Create the proper test case from the argument.
+ for (uint32_t i = 0; i < argc; i++) {
+ if (strcmp(argn[i], "testcase") == 0) {
+ if (argv[i][0] == '\0')
+ break;
+ current_case_ = CaseForTestName(argv[i]);
+ if (!current_case_)
+ errors_.append(std::string("Unknown test case ") + argv[i]);
+ else if (!current_case_->Init())
+ errors_.append(" Test case could not initialize.");
+ return true;
+ }
+ }
+
+ // In DidChangeView, we'll dump out a list of all available tests.
+ return true;
+}
+
+pp::Var TestingInstance::GetInstanceObject() {
+ return current_case_->GetTestObject();
+}
+
+void TestingInstance::DidChangeView(const pp::Rect& position,
+ const pp::Rect& clip) {
+ if (!executed_tests_) {
+ executed_tests_ = true;
+ pp::Module::Get()->core()->CallOnMainThread(
+ 0,
+ callback_factory_.NewCallback(&TestingInstance::ExecuteTests));
+ }
+}
+
+void TestingInstance::LogTest(const std::string& test_name,
+ const std::string& error_message) {
+ std::string html;
+ html.append("<div class=\"test_line\"><span class=\"test_name\">");
+ html.append(test_name);
+ html.append("</span> ");
+ if (error_message.empty()) {
+ html.append("<span class=\"pass\">PASS</span>");
+ } else {
+ html.append("<span class=\"fail\">FAIL</span>: <span class=\"err_msg\">");
+ html.append(error_message);
+ html.append("</span>");
+
+ if (!errors_.empty())
+ errors_.append(", "); // Separator for different error messages.
+ errors_.append(test_name + " FAIL: " + error_message);
+ }
+ html.append("</div>");
+ LogHTML(html);
+}
+
+void TestingInstance::AppendError(const std::string& message) {
+ if (!errors_.empty())
+ errors_.append(", ");
+ errors_.append(message);
+}
+
+void TestingInstance::ExecuteTests(int32_t unused) {
+ // Clear the console.
+ // This does: window.document.getElementById("console").innerHTML = "";
+ pp::Var window = GetWindowObject();
+ window.GetProperty("document").
+ Call("getElementById", "console").SetProperty("innerHTML", "");
+
+ if (!errors_.empty()) {
+ // Catch initialization errors and output the current error string to
+ // the console.
+ LogError("Plugin initialization failed: " + errors_);
+ } else if (!current_case_) {
+ LogAvailableTests();
+ } else {
+ current_case_->RunTest();
+ }
+
+ // Declare we're done by setting a cookie to either "PASS" or the errors.
+ SetCookie("COMPLETION_COOKIE", errors_.empty() ? "PASS" : errors_);
+
+ window.Call("DidExecuteTests");
+}
+
+TestCase* TestingInstance::CaseForTestName(const char* name) {
+ TestCaseFactory* iter = TestCaseFactory::head_;
+ while (iter != NULL) {
+ if (strcmp(name, iter->name_) == 0)
+ return iter->method_(this);
+ iter = iter->next_;
+ }
+ return NULL;
+}
+
+void TestingInstance::LogAvailableTests() {
+ // Print out a listing of all tests.
+ std::vector<std::string> test_cases;
+ TestCaseFactory* iter = TestCaseFactory::head_;
+ while (iter != NULL) {
+ test_cases.push_back(iter->name_);
+ iter = iter->next_;
+ }
+ std::sort(test_cases.begin(), test_cases.end());
+
+ std::string html;
+ html.append("Available test cases: <dl>");
+ for (size_t i = 0; i < test_cases.size(); ++i) {
+ html.append("<dd><a href='?");
+ html.append(test_cases[i]);
+ html.append("'>");
+ html.append(test_cases[i]);
+ html.append("</a></dd>");
+ }
+ html.append("</dl>");
+ html.append("<button onclick='RunAll()'>Run All Tests</button>");
+ LogHTML(html);
+}
+
+void TestingInstance::LogError(const std::string& text) {
+ std::string html;
+ html.append("<span class=\"fail\">FAIL</span>: <span class=\"err_msg\">");
+ html.append(text);
+ html.append("</span>");
+ LogHTML(html);
+}
+
+void TestingInstance::LogHTML(const std::string& html) {
+ // This does: window.document.getElementById("console").innerHTML += html
+ pp::Var console = GetWindowObject().GetProperty("document").
+ Call("getElementById", "console");
+ pp::Var inner_html = console.GetProperty("innerHTML");
+ console.SetProperty("innerHTML", inner_html.AsString() + html);
+}
+
+void TestingInstance::SetCookie(const std::string& name,
+ const std::string& value) {
+ // window.document.cookie = "<name>=<value>; path=/"
+ std::string cookie_string = name + "=" + value + "; path=/";
+ pp::Var document = GetWindowObject().GetProperty("document");
+ document.SetProperty("cookie", cookie_string);
+}
+
+class Module : public pp::Module {
+ public:
+ Module() : pp::Module() {}
+ virtual ~Module() {}
+
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new TestingInstance(instance);
+ }
+};
+
+namespace pp {
+
+Module* CreateModule() {
+ return new ::Module();
+}
+
+} // namespace pp
diff --git a/ppapi/tests/testing_instance.h b/ppapi/tests/testing_instance.h
new file mode 100644
index 0000000..1f9257e
--- /dev/null
+++ b/ppapi/tests/testing_instance.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_TEST_TESTING_INSTANCE_H_
+#define PPAPI_TEST_TESTING_INSTANCE_H_
+
+#include <string>
+
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/instance.h"
+
+class TestCase;
+
+class TestingInstance : public pp::Instance {
+ public:
+ TestingInstance(PP_Instance instance);
+
+ // pp::Instance override.
+ virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
+ virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip);
+ virtual pp::Var GetInstanceObject();
+
+ // Outputs the information from one test run, using the format
+ // <test_name> [PASS|FAIL <error_message>]
+ // If error_message is empty, we say the test passed and emit PASS. If
+ // error_message is nonempty, the test failed with that message as the error
+ // string.
+ //
+ // Intended usage:
+ // LogTest("Foo", FooTest());
+ //
+ // Where FooTest is defined as:
+ // std::string FooTest() {
+ // if (something_horrible_happened)
+ // return "Something horrible happened";
+ // return "";
+ // }
+ void LogTest(const std::string& test_name, const std::string& error_message);
+
+ // Appends an error message to the log.
+ void AppendError(const std::string& message);
+
+ private:
+ void ExecuteTests(int32_t unused);
+
+ // Creates a new TestCase for the give test name, or NULL if there is no such
+ // test. Ownership is passed to the caller.
+ TestCase* CaseForTestName(const char* name);
+
+ // Appends a list of available tests to the console in the document.
+ void LogAvailableTests();
+
+ // Appends the given error test to the console in the document.
+ void LogError(const std::string& text);
+
+ // Appends the given HTML string to the console in the document.
+ void LogHTML(const std::string& html);
+
+ // Sets the given cookie in the current document.
+ void SetCookie(const std::string& name, const std::string& value);
+
+ pp::CompletionCallbackFactory<TestingInstance> callback_factory_;
+
+ // Owning pointer to the current test case. Valid after Init has been called.
+ TestCase* current_case_;
+
+ // Set once the tests are run so we know not to re-run when the view is sized.
+ bool executed_tests_;
+
+ // Collects all errors to send the the browser. Empty indicates no error yet.
+ std::string errors_;
+};
+
+#endif // PPAPI_TEST_TESTING_INSTANCE_H_