diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-01 16:16:50 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-01 16:16:50 +0000 |
commit | 1758e88fd909ea0ffd49621e8066ffad5627ffdf (patch) | |
tree | c304a5eed047cae5665f5af1739d84655fb5815d | |
parent | e7d8b51953b7d3b2b8a0aba46132305b32f3efce (diff) | |
download | chromium_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
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&q=http%3A%2F%2Fcreativecommons.org/licenses/by/2.5/">Creative Commons + Attribution 2.5 license</a>. + </p> + + <address> + ©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 + — 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_ |