<commit_before>/***********************************************************************
    filename:   CEGUIDirectFBRenderer.cpp
    created:    Tue Mar 10 2009
    author:     Paul D Turner (parts based on code by Keith Mok)
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is 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 Software.
 *
 *   THE SOFTWARE IS 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 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 SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/RendererModules/DirectFB/Renderer.h"
#include "CEGUI/RendererModules/DirectFB/Texture.h"
#include "CEGUI/RendererModules/DirectFB/GeometryBuffer.h"
#include "CEGUI/RendererModules/DirectFB/RenderTarget.h"
#include "CEGUI/TextureTarget.h"
#include "CEGUI/Exceptions.h"
#include "CEGUI/Logger.h"

#include <algorithm>

// Start of CEGUI namespace section
namespace CEGUI
{
//----------------------------------------------------------------------------//
String DirectFBRenderer::d_rendererID(
"CEGUI::DirectFBRenderer - Official DirectFB based 2nd generation renderer "
"module.");

//----------------------------------------------------------------------------//
DirectFBRenderer& DirectFBRenderer::create(IDirectFB& directfb,
                                           IDirectFBSurface& surface)
{
    return *new DirectFBRenderer(directfb, surface);
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroy(DirectFBRenderer& renderer)
{
    delete &renderer;
}

//----------------------------------------------------------------------------//
IDirectFBSurface& DirectFBRenderer::getTargetSurface() const
{
    return *d_targetSurface;
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::setTargetSurface(IDirectFBSurface& surface)
{
    d_targetSurface = &surface;
}

//----------------------------------------------------------------------------//
RenderTarget& DirectFBRenderer::getDefaultRenderTarget()
{
    return *d_defaultTarget;
}

//----------------------------------------------------------------------------//
GeometryBuffer& DirectFBRenderer::createGeometryBuffer()
{
    DirectFBGeometryBuffer* b = new DirectFBGeometryBuffer(*this);
    d_geometryBuffers.push_back(b);
    return *b;
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyGeometryBuffer(const GeometryBuffer& buffer)
{
    GeometryBufferList::iterator i = std::find(d_geometryBuffers.begin(),
                                               d_geometryBuffers.end(),
                                               &buffer);

    if (d_geometryBuffers.end() != i)
    {
        d_geometryBuffers.erase(i);
        delete &buffer;
    }
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyAllGeometryBuffers()
{
    while (!d_geometryBuffers.empty())
        destroyGeometryBuffer(**d_geometryBuffers.begin());
}

//----------------------------------------------------------------------------//
TextureTarget* DirectFBRenderer::createTextureTarget()
{
    // TODO:
    return 0;
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyTextureTarget(TextureTarget* target)
{
    TextureTargetList::iterator i = std::find(d_textureTargets.begin(),
                                              d_textureTargets.end(),
                                              target);

    if (d_textureTargets.end() != i)
    {
        d_textureTargets.erase(i);
        delete target;
    }
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyAllTextureTargets()
{
    while (!d_textureTargets.empty())
        destroyTextureTarget(*d_textureTargets.begin());
}

//----------------------------------------------------------------------------//
Texture& DirectFBRenderer::createTexture(const CEGUI::String& name)
{
    if (d_textures.find(name) != d_textures.end())
        CEGUI_THROW(AlreadyExistsException("DirectFBRenderer::createTexture: "
            "A texture named '" + name + "' already exists."));

    DirectFBTexture* tex = new DirectFBTexture(d_directfb, name);
    d_textures[name] = tex;

    logTextureCreation(name);

    return *tex;
}

//----------------------------------------------------------------------------//
Texture& DirectFBRenderer::createTexture(const CEGUI::String& name,
                                         const String& filename,
                                         const String& resourceGroup)
{
    if (d_textures.find(name) != d_textures.end())
        CEGUI_THROW(AlreadyExistsException("DirectFBRenderer::createTexture: "
            "A texture named '" + name + "' already exists."));

    DirectFBTexture* tex = new DirectFBTexture(d_directfb, name,
                                               filename, resourceGroup);
    d_textures[name] = tex;

    logTextureDestruction(name);

    return *tex;
}

//----------------------------------------------------------------------------//
Texture& DirectFBRenderer::createTexture(const CEGUI::String& name,
                                         const Sizef& size)
{
    if (d_textures.find(name) != d_textures.end())
        CEGUI_THROW(AlreadyExistsException("DirectFBRenderer::createTexture: "
            "A texture named '" + name + "' already exists."));

    DirectFBTexture* tex = new DirectFBTexture(d_directfb, name, size);
    d_textures[name] = tex;

    logTextureCreation(name);

    return *tex;
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::logTextureCreation(const String& name)
{
    if (Logger* logger = Logger::getSingletonPtr())
        logger->logEvent("[DirectFBRenderer] Created texture: " + name);
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyTexture(Texture& texture)
{
    destroyTexture(texture.getName());
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyTexture(const CEGUI::String& name)
{
    TextureMap::iterator i = d_textures.find(name);

    if (d_textures.end() != i)
    {
        logTextureDestruction(name);
        delete i->second;
        d_textures.erase(i);
    }
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::logTextureDestruction(const String& name)
{
    if (Logger* logger = Logger::getSingletonPtr())
        logger->logEvent("[DirectFBRenderer] Destroyed texture: " + name);
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyAllTextures()
{
    while (!d_textures.empty())
        destroyTexture(d_textures.begin()->first);
}

//----------------------------------------------------------------------------//
Texture& DirectFBRenderer::getTexture(const String&) const
{
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::beginRendering()
{
    // TODO:
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::endRendering()
{
    // TODO:
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::setDisplaySize(const Sizef& sz)
{
    if (sz != d_displaySize)
    {
        d_displaySize = sz;

        // update the default target's area
        Rectf area(d_defaultTarget->getArea());
        area.setSize(sz);
        d_defaultTarget->setArea(area);
    }
}

//----------------------------------------------------------------------------//
const Sizef& DirectFBRenderer::getDisplaySize() const
{
    return d_displaySize;
}

//----------------------------------------------------------------------------//
const Vector2f& DirectFBRenderer::getDisplayDPI() const
{
    return d_displayDPI;
}

//----------------------------------------------------------------------------//
uint DirectFBRenderer::getMaxTextureSize() const
{
    return 2048;
}

//----------------------------------------------------------------------------//
const String& DirectFBRenderer::getIdentifierString() const
{
    return d_rendererID;
}

//----------------------------------------------------------------------------//
DirectFBRenderer::DirectFBRenderer(IDirectFB& directfb,
                                   IDirectFBSurface& surface) :
    d_directfb(directfb),
    d_rootSurface(surface),
    d_targetSurface(&d_rootSurface),
    d_displayDPI(96, 96),
    d_defaultTarget(new DirectFBRenderTarget(*this, d_rootSurface))
{
    int w, h;
    d_rootSurface.GetSize(&d_rootSurface, &w, &h);
    d_displaySize.d_width = static_cast<float>(w);
    d_displaySize.d_height = static_cast<float>(h);
}

//----------------------------------------------------------------------------//
DirectFBRenderer::~DirectFBRenderer()
{
    destroyAllTextureTargets();
    destroyAllTextures();
    destroyAllGeometryBuffers();

    delete d_defaultTarget;
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section
<commit_msg>Logging for DirectFB texture creation from image file was backwards.<commit_after>/***********************************************************************
    filename:   CEGUIDirectFBRenderer.cpp
    created:    Tue Mar 10 2009
    author:     Paul D Turner (parts based on code by Keith Mok)
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is 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 Software.
 *
 *   THE SOFTWARE IS 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 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 SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/RendererModules/DirectFB/Renderer.h"
#include "CEGUI/RendererModules/DirectFB/Texture.h"
#include "CEGUI/RendererModules/DirectFB/GeometryBuffer.h"
#include "CEGUI/RendererModules/DirectFB/RenderTarget.h"
#include "CEGUI/TextureTarget.h"
#include "CEGUI/Exceptions.h"
#include "CEGUI/Logger.h"

#include <algorithm>

// Start of CEGUI namespace section
namespace CEGUI
{
//----------------------------------------------------------------------------//
String DirectFBRenderer::d_rendererID(
"CEGUI::DirectFBRenderer - Official DirectFB based 2nd generation renderer "
"module.");

//----------------------------------------------------------------------------//
DirectFBRenderer& DirectFBRenderer::create(IDirectFB& directfb,
                                           IDirectFBSurface& surface)
{
    return *new DirectFBRenderer(directfb, surface);
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroy(DirectFBRenderer& renderer)
{
    delete &renderer;
}

//----------------------------------------------------------------------------//
IDirectFBSurface& DirectFBRenderer::getTargetSurface() const
{
    return *d_targetSurface;
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::setTargetSurface(IDirectFBSurface& surface)
{
    d_targetSurface = &surface;
}

//----------------------------------------------------------------------------//
RenderTarget& DirectFBRenderer::getDefaultRenderTarget()
{
    return *d_defaultTarget;
}

//----------------------------------------------------------------------------//
GeometryBuffer& DirectFBRenderer::createGeometryBuffer()
{
    DirectFBGeometryBuffer* b = new DirectFBGeometryBuffer(*this);
    d_geometryBuffers.push_back(b);
    return *b;
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyGeometryBuffer(const GeometryBuffer& buffer)
{
    GeometryBufferList::iterator i = std::find(d_geometryBuffers.begin(),
                                               d_geometryBuffers.end(),
                                               &buffer);

    if (d_geometryBuffers.end() != i)
    {
        d_geometryBuffers.erase(i);
        delete &buffer;
    }
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyAllGeometryBuffers()
{
    while (!d_geometryBuffers.empty())
        destroyGeometryBuffer(**d_geometryBuffers.begin());
}

//----------------------------------------------------------------------------//
TextureTarget* DirectFBRenderer::createTextureTarget()
{
    // TODO:
    return 0;
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyTextureTarget(TextureTarget* target)
{
    TextureTargetList::iterator i = std::find(d_textureTargets.begin(),
                                              d_textureTargets.end(),
                                              target);

    if (d_textureTargets.end() != i)
    {
        d_textureTargets.erase(i);
        delete target;
    }
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyAllTextureTargets()
{
    while (!d_textureTargets.empty())
        destroyTextureTarget(*d_textureTargets.begin());
}

//----------------------------------------------------------------------------//
Texture& DirectFBRenderer::createTexture(const CEGUI::String& name)
{
    if (d_textures.find(name) != d_textures.end())
        CEGUI_THROW(AlreadyExistsException("DirectFBRenderer::createTexture: "
            "A texture named '" + name + "' already exists."));

    DirectFBTexture* tex = new DirectFBTexture(d_directfb, name);
    d_textures[name] = tex;

    logTextureCreation(name);

    return *tex;
}

//----------------------------------------------------------------------------//
Texture& DirectFBRenderer::createTexture(const CEGUI::String& name,
                                         const String& filename,
                                         const String& resourceGroup)
{
    if (d_textures.find(name) != d_textures.end())
        CEGUI_THROW(AlreadyExistsException("DirectFBRenderer::createTexture: "
            "A texture named '" + name + "' already exists."));

    DirectFBTexture* tex = new DirectFBTexture(d_directfb, name,
                                               filename, resourceGroup);
    d_textures[name] = tex;

    logTextureCreation(name);

    return *tex;
}

//----------------------------------------------------------------------------//
Texture& DirectFBRenderer::createTexture(const CEGUI::String& name,
                                         const Sizef& size)
{
    if (d_textures.find(name) != d_textures.end())
        CEGUI_THROW(AlreadyExistsException("DirectFBRenderer::createTexture: "
            "A texture named '" + name + "' already exists."));

    DirectFBTexture* tex = new DirectFBTexture(d_directfb, name, size);
    d_textures[name] = tex;

    logTextureCreation(name);

    return *tex;
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::logTextureCreation(const String& name)
{
    if (Logger* logger = Logger::getSingletonPtr())
        logger->logEvent("[DirectFBRenderer] Created texture: " + name);
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyTexture(Texture& texture)
{
    destroyTexture(texture.getName());
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyTexture(const CEGUI::String& name)
{
    TextureMap::iterator i = d_textures.find(name);

    if (d_textures.end() != i)
    {
        logTextureDestruction(name);
        delete i->second;
        d_textures.erase(i);
    }
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::logTextureDestruction(const String& name)
{
    if (Logger* logger = Logger::getSingletonPtr())
        logger->logEvent("[DirectFBRenderer] Destroyed texture: " + name);
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::destroyAllTextures()
{
    while (!d_textures.empty())
        destroyTexture(d_textures.begin()->first);
}

//----------------------------------------------------------------------------//
Texture& DirectFBRenderer::getTexture(const String&) const
{
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::beginRendering()
{
    // TODO:
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::endRendering()
{
    // TODO:
}

//----------------------------------------------------------------------------//
void DirectFBRenderer::setDisplaySize(const Sizef& sz)
{
    if (sz != d_displaySize)
    {
        d_displaySize = sz;

        // update the default target's area
        Rectf area(d_defaultTarget->getArea());
        area.setSize(sz);
        d_defaultTarget->setArea(area);
    }
}

//----------------------------------------------------------------------------//
const Sizef& DirectFBRenderer::getDisplaySize() const
{
    return d_displaySize;
}

//----------------------------------------------------------------------------//
const Vector2f& DirectFBRenderer::getDisplayDPI() const
{
    return d_displayDPI;
}

//----------------------------------------------------------------------------//
uint DirectFBRenderer::getMaxTextureSize() const
{
    return 2048;
}

//----------------------------------------------------------------------------//
const String& DirectFBRenderer::getIdentifierString() const
{
    return d_rendererID;
}

//----------------------------------------------------------------------------//
DirectFBRenderer::DirectFBRenderer(IDirectFB& directfb,
                                   IDirectFBSurface& surface) :
    d_directfb(directfb),
    d_rootSurface(surface),
    d_targetSurface(&d_rootSurface),
    d_displayDPI(96, 96),
    d_defaultTarget(new DirectFBRenderTarget(*this, d_rootSurface))
{
    int w, h;
    d_rootSurface.GetSize(&d_rootSurface, &w, &h);
    d_displaySize.d_width = static_cast<float>(w);
    d_displaySize.d_height = static_cast<float>(h);
}

//----------------------------------------------------------------------------//
DirectFBRenderer::~DirectFBRenderer()
{
    destroyAllTextureTargets();
    destroyAllTextures();
    destroyAllGeometryBuffers();

    delete d_defaultTarget;
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section
<|endoftext|>


<commit_before>#include "chainerx/python/cuda/memory_pool.h"

#include <cstddef>
#include <cstdint>
#include <functional>
#include <utility>

#include <pybind11/functional.h>

#include "chainerx/cuda/cuda_device.h"
#include "chainerx/cuda/memory_pool.h"
#include "chainerx/device.h"

#include "chainerx/python/common.h"
#include "chainerx/python/device.h"

namespace chainerx {
namespace python {
namespace cuda {
namespace cuda_internal {

namespace py = pybind11;  // standard convention

void InitChainerxMemoryPool(py::module& m) {
    m.def("get_memory_pool_malloc",
          [](py::handle device) -> std::function<intptr_t(size_t)> {
              Device& actual_device = chainerx::python::python_internal::GetDevice(device);

              std::function<void*(size_t)> malloc = std::bind(
                      &chainerx::cuda::MemoryPool::Malloc,
                      dynamic_cast<chainerx::cuda::CudaDevice*>(&actual_device)->device_memory_pool().get(),
                      std::placeholders::_1);

              return [malloc = std::move(malloc)](size_t bytesize) {
                  return reinterpret_cast<intptr_t>(malloc(bytesize));  // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
              };
          },
          py::arg("device"));
    m.def("get_memory_pool_free",
          [](py::handle device) -> std::function<void(void*)> {
              Device& actual_device = chainerx::python::python_internal::GetDevice(device);

              return std::bind(
                      &chainerx::cuda::MemoryPool::Free,
                      dynamic_cast<chainerx::cuda::CudaDevice*>(&actual_device)->device_memory_pool().get(),
                      std::placeholders::_1);
          },
          py::arg("device"));
}

}  // namespace cuda_internal
}  // namespace cuda
}  // namespace python
}  // namespace chainerx
<commit_msg>Fix pointer cast for MemoryPool::Free exposure to Python<commit_after>#include "chainerx/python/cuda/memory_pool.h"

#include <cstddef>
#include <cstdint>
#include <functional>
#include <utility>

#include <pybind11/functional.h>

#include "chainerx/cuda/cuda_device.h"
#include "chainerx/cuda/memory_pool.h"
#include "chainerx/device.h"

#include "chainerx/python/common.h"
#include "chainerx/python/device.h"

namespace chainerx {
namespace python {
namespace cuda {
namespace cuda_internal {

namespace py = pybind11;  // standard convention

void InitChainerxMemoryPool(py::module& m) {
    m.def("get_memory_pool_malloc",
          [](py::handle device) -> std::function<intptr_t(size_t)> {
              Device& actual_device = chainerx::python::python_internal::GetDevice(device);

              std::function<void*(size_t)> malloc = std::bind(
                      &chainerx::cuda::MemoryPool::Malloc,
                      dynamic_cast<chainerx::cuda::CudaDevice*>(&actual_device)->device_memory_pool().get(),
                      std::placeholders::_1);

              return [malloc = std::move(malloc)](size_t bytesize) {
                  return reinterpret_cast<intptr_t>(malloc(bytesize));  // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
              };
          },
          py::arg("device"));
    m.def("get_memory_pool_free",
          [](py::handle device) -> std::function<void(intptr_t)> {
              Device& actual_device = chainerx::python::python_internal::GetDevice(device);

              std::function<void(void*)> free = std::bind(
                      &chainerx::cuda::MemoryPool::Free,
                      dynamic_cast<chainerx::cuda::CudaDevice*>(&actual_device)->device_memory_pool().get(),
                      std::placeholders::_1);

              return [free = std::move(free)](intptr_t bytesize) {
                  free(reinterpret_cast<void*>(bytesize));  // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
              };
          },
          py::arg("device"));
}

}  // namespace cuda_internal
}  // namespace cuda
}  // namespace python
}  // namespace chainerx
<|endoftext|>


<commit_before>/**
 *  cppclassinphp.cpp
 *  @author Jasper van Eck<jasper.vaneck@copernica.com>
 *
 *  An example file to show the working of using a C++ class in PHP.
 */

#include "includeMyCustomClass.h"
/**
 *  Namespace to use
 */
using namespace std;

class MyCustomClass : public Php::Base // , public Php::Countable
{
private:
    int _x = 3;

public:
    MyCustomClass()
    {
        std::cout << "MyCustomClass::MyCustomClass()" << std::endl;
    }

    MyCustomClass(int value) : _x(value)
    {
        std::cout << "MyCustomClass::MyCustomClass(" << value << ")" << std::endl;
    }

    MyCustomClass(const MyCustomClass &that)
    {
        std::cout << "MyCustomClass::MyCustomClass copy constructor" << std::endl;
    }

    virtual ~MyCustomClass()
    {
        std::cout << "MyCustomClass::~MyCustomClass" << std::endl;
    }

    virtual void __construct()
    {
        std::cout << "MyCustomClass::__construct" << std::endl;
    }

    virtual void __destruct()
    {
        std::cout << "MyCustomClass::__destruct" << std::endl;
    }

    virtual Php::Value count() //override
    {
        return 33;
    }

    Php::Value myMethod(Php::Parameters &params)
    {
        // check number of parameters
        if (params.size() != 1) throw Php::Exception("Invalid number of parameters supplied");

        std::cout << "myMethod is called for object " << _x << std::endl;

        return Php::Object("MyClass", new MyCustomClass(100));

        return false;

        // create a new PHP DateTime object representing the current time
        Php::Object now("DateTime", "now");

        // show it
        std::cout << "current time: " << now.call("format", "Y-m-d H:i:s") << std::endl;

        std::cout << "construct " << params[0] << std::endl;

        // construct a new class
        Php::Object obj(params[0]);

        std::cout << "return " << params[0] << std::endl;

        // return it
        return obj;

   //     std::cout << "get property1 " << value()["property1"] << std::endl;
   //
   //     // set it to something else
   //     value().set("property1", "new value");
   //
   //     std::cout << "get property1 " << value()["property1"] << std::endl;
    }
};

// Symbols are exported according to the "C" language
extern "C"
{
    // export the "get_module" function that will be called by the Zend engine
    PHPCPP_EXPORT void *get_module()
    {
        // create extension
        static Php::Extension extension("Cpp_classes_in_php","1.0");

        // build an interface
        Php::Interface interface("MyInterface");

        // add methods to the interface
        interface.method("method1");
        interface.method("method2");

        // add the interface to the extension
        extension.add(interface);

        // we are going to define a class
        Php::Class<MyCustomClass> customClass("MyClass");

        // add methods to it
        customClass.method("myMethod", &MyCustomClass::myMethod, Php::Final, {});
        customClass.method("myMethod2", &MyCustomClass::myMethod);
        customClass.property("property1", "prop1");
        customClass.property("property2", "prop2", Php::Protected);

        // add the class to the extension
        extension.add(customClass);

        // return the extension module
        return extension.module();
    }
}
<commit_msg>modified example to test accessing properties directly from the base<commit_after>/**
 *  cppclassinphp.cpp
 *  @author Jasper van Eck<jasper.vaneck@copernica.com>
 *
 *  An example file to show the working of using a C++ class in PHP.
 */

#include "includeMyCustomClass.h"
/**
 *  Namespace to use
 */
using namespace std;

class MyCustomClass : public Php::Base // , public Php::Countable
{
private:
    int _x = 3;

public:
    MyCustomClass()
    {
        std::cout << "MyCustomClass::MyCustomClass()" << std::endl;
    }

    MyCustomClass(int value) : _x(value)
    {
        std::cout << "MyCustomClass::MyCustomClass(" << value << ")" << std::endl;
    }

    MyCustomClass(const MyCustomClass &that)
    {
        std::cout << "MyCustomClass::MyCustomClass copy constructor" << std::endl;
    }

    virtual ~MyCustomClass()
    {
        std::cout << "MyCustomClass::~MyCustomClass" << std::endl;
    }

    virtual void __construct()
    {
        std::cout << "MyCustomClass::__construct" << std::endl;
    }

    virtual void __destruct()
    {
        std::cout << "MyCustomClass::__destruct" << std::endl;
    }

    virtual Php::Value count() //override
    {
        return 33;
    }

    Php::Value myMethod(Php::Parameters &params)
    {
        // check number of parameters
        if (params.size() != 1) throw Php::Exception("Invalid number of parameters supplied");

        std::cout << "myMethod is called for object " << _x << std::endl;

        std::cout << "property1: " << property("property1") << std::endl;

        return Php::Object("MyClass", new MyCustomClass(100));

        return false;

        // create a new PHP DateTime object representing the current time
        Php::Object now("DateTime", "now");

        // show it
        std::cout << "current time: " << now.call("format", "Y-m-d H:i:s") << std::endl;

        std::cout << "construct " << params[0] << std::endl;

        // construct a new class
        Php::Object obj(params[0]);

        std::cout << "return " << params[0] << std::endl;

        // return it
        return obj;

   //     std::cout << "get property1 " << value()["property1"] << std::endl;
   //
   //     // set it to something else
   //     value().set("property1", "new value");
   //
   //     std::cout << "get property1 " << value()["property1"] << std::endl;
    }
};

// Symbols are exported according to the "C" language
extern "C"
{
    // export the "get_module" function that will be called by the Zend engine
    PHPCPP_EXPORT void *get_module()
    {
        // create extension
        static Php::Extension extension("Cpp_classes_in_php","1.0");

        // build an interface
        Php::Interface interface("MyInterface");

        // add methods to the interface
        interface.method("method1");
        interface.method("method2");

        // add the interface to the extension
        extension.add(interface);

        // we are going to define a class
        Php::Class<MyCustomClass> customClass("MyClass");

        // add methods to it
        customClass.method("myMethod", &MyCustomClass::myMethod, Php::Final, {});
        customClass.method("myMethod2", &MyCustomClass::myMethod);
        customClass.property("property1", "prop1");
        customClass.property("property2", "prop2", Php::Protected);

        // add the class to the extension
        extension.add(customClass);

        // return the extension module
        return extension.module();
    }
}
<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
  Copyright 2009 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/

#include "ui_EasyView.h"
#include "EasyView.h"

#include <vtkAnnotationLink.h>
#include <vtkDataObjectToTable.h>
#include <vtkDataRepresentation.h>
#include <vtkGraphLayoutView.h>
#include <vtkQtTableView.h>
#include <vtkQtTreeView.h>
#include <vtkRenderer.h>
#include <vtkSelection.h>
#include <vtkSelectionNode.h>
#include <vtkTable.h>
#include <vtkTableToGraph.h>
#include <vtkTreeLayoutStrategy.h>
#include <vtkViewTheme.h>
#include <vtkViewUpdater.h>
#include <vtkXMLTreeReader.h>

#include <QDir>
#include <QFileDialog>
#include <QTreeView>

#include "vtkSmartPointer.h"
#define VTK_CREATE(type, name) \
  vtkSmartPointer<type> name = vtkSmartPointer<type>::New()

// Constructor
EasyView::EasyView()
{
  this->ui = new Ui_EasyView;
  this->ui->setupUi(this);

  this->XMLReader    = vtkSmartPointer<vtkXMLTreeReader>::New();
  this->GraphView    = vtkSmartPointer<vtkGraphLayoutView>::New();
  this->TreeView     = vtkSmartPointer<vtkQtTreeView>::New();
  this->TableView    = vtkSmartPointer<vtkQtTableView>::New();
  this->ColumnView   = vtkSmartPointer<vtkQtTreeView>::New();
  this->ColumnView->SetUseColumnView(1);

  // Tell the table view to sort selections that it receives (but does
  // not initiate) to the top
  this->TableView->SetSortSelectionToTop(true);

  // Set widgets for the tree and table views
  this->ui->treeFrame->layout()->addWidget(this->TreeView->GetWidget());
  this->ui->tableFrame->layout()->addWidget(this->TableView->GetWidget());
  this->ui->columnFrame->layout()->addWidget(this->ColumnView->GetWidget());

  // Graph View needs to get my render window
  this->ui->vtkGraphViewWidget->SetRenderWindow(this->GraphView->GetRenderWindow());

  // Set up the theme on the graph view :)
  vtkViewTheme* theme = vtkViewTheme::CreateNeonTheme();
  this->GraphView->ApplyViewTheme(theme);
  theme->Delete();

  // Set up action signals and slots
  connect(this->ui->actionOpenXMLFile, SIGNAL(triggered()), this, SLOT(slotOpenXMLFile()));
  connect(this->ui->actionExit, SIGNAL(triggered()), this, SLOT(slotExit()));

  // Apply application stylesheet
  QString css = "* { font: bold italic 18px \"Calibri\"; color: midnightblue }";
  css += "QTreeView { font: bold italic 16px \"Calibri\"; color: midnightblue }";
  //qApp->setStyleSheet(css); // Seems to cause a bug on some systems
                              // But at least it's here as an example

  this->GraphView->Render();
};

// Set up the annotation between the vtk and qt views
void EasyView::SetupAnnotationLink()
{
  // Create a selection link and have all the views use it
  VTK_CREATE(vtkAnnotationLink,annLink);
  this->TreeView->GetRepresentation()->SetAnnotationLink(annLink);
  this->TreeView->GetRepresentation()->SetSelectionType(vtkSelectionNode::PEDIGREEIDS);
  this->TableView->GetRepresentation()->SetAnnotationLink(annLink);
  this->TableView->GetRepresentation()->SetSelectionType(vtkSelectionNode::PEDIGREEIDS);
  this->ColumnView->GetRepresentation()->SetAnnotationLink(annLink);
  this->ColumnView->GetRepresentation()->SetSelectionType(vtkSelectionNode::PEDIGREEIDS);
  this->GraphView->GetRepresentation()->SetAnnotationLink(annLink);
  this->GraphView->GetRepresentation()->SetSelectionType(vtkSelectionNode::PEDIGREEIDS);

  // Set up the theme on the graph view :)
  vtkViewTheme* theme = vtkViewTheme::CreateNeonTheme();
  this->GraphView->ApplyViewTheme(theme);
  this->GraphView->Update();
  theme->Delete();

  VTK_CREATE(vtkViewUpdater,updater);
  updater->AddView(this->TreeView);
  updater->AddView(this->TableView);
  updater->AddView(this->ColumnView);
  updater->AddView(this->GraphView);
}

EasyView::~EasyView()
{

}

// Action to be taken upon graph file open
void EasyView::slotOpenXMLFile()
{
  // Browse for and open the file
  QDir dir;

  // Open the text data file
  QString fileName = QFileDialog::getOpenFileName(
    this,
    "Select the text data file",
    QDir::homePath(),
    "XML Files (*.xml);;All Files (*.*)");

  if (fileName.isNull())
    {
    cerr << "Could not open file" << endl;
    return;
    }

  // Create XML reader
  this->XMLReader->SetFileName( fileName.toAscii() );
  this->XMLReader->ReadTagNameOff();
  this->XMLReader->Update();

  // Set up some hard coded parameters for the graph view
  this->GraphView->SetVertexLabelArrayName("id");
  this->GraphView->VertexLabelVisibilityOn();
  this->GraphView->SetVertexColorArrayName("VertexDegree");
  this->GraphView->ColorVerticesOn();
  this->GraphView->SetEdgeColorArrayName("edge id");
  this->GraphView->ColorEdgesOn();

  // Create a tree layout strategy
  VTK_CREATE(vtkTreeLayoutStrategy, treeStrat);
  treeStrat->RadialOn();
  treeStrat->SetAngle(360);
  treeStrat->SetLogSpacingValue(1);
  this->GraphView->SetLayoutStrategy(treeStrat);

  // Set the input to the graph view
  this->GraphView->SetRepresentationFromInputConnection(this->XMLReader->GetOutputPort());

  // Okay now do an explicit reset camera so that
  // the user doesn't have to move the mouse
  // in the window to see the resulting graph
  this->GraphView->ResetCamera();

  // Now hand off tree to the tree view
  this->TreeView->SetRepresentationFromInputConnection(this->XMLReader->GetOutputPort());
  this->ColumnView->SetRepresentationFromInputConnection(this->XMLReader->GetOutputPort());

  // Extract a table and give to table view
  VTK_CREATE(vtkDataObjectToTable, toTable);
  toTable->SetInputConnection(this->XMLReader->GetOutputPort());
  toTable->SetFieldType(vtkDataObjectToTable::VERTEX_DATA);
  this->TableView->SetRepresentationFromInputConnection(toTable->GetOutputPort());

  this->SetupAnnotationLink();

  // Update all the views
  this->TreeView->Update();
  this->TableView->Update();
  this->ColumnView->Update();

  // Force a render on the graph view
  this->GraphView->Render();
}

void EasyView::slotExit() {
  qApp->exit();
}
<commit_msg>ENH: EasyView example demonstrates hiding a tree column.<commit_after>/*-------------------------------------------------------------------------
  Copyright 2009 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/

#include "ui_EasyView.h"
#include "EasyView.h"

#include <vtkAnnotationLink.h>
#include <vtkDataObjectToTable.h>
#include <vtkDataRepresentation.h>
#include <vtkGraphLayoutView.h>
#include <vtkQtTableView.h>
#include <vtkQtTreeView.h>
#include <vtkRenderer.h>
#include <vtkSelection.h>
#include <vtkSelectionNode.h>
#include <vtkTable.h>
#include <vtkTableToGraph.h>
#include <vtkTreeLayoutStrategy.h>
#include <vtkViewTheme.h>
#include <vtkViewUpdater.h>
#include <vtkXMLTreeReader.h>

#include <QDir>
#include <QFileDialog>
#include <QTreeView>

#include "vtkSmartPointer.h"
#define VTK_CREATE(type, name) \
  vtkSmartPointer<type> name = vtkSmartPointer<type>::New()

// Constructor
EasyView::EasyView()
{
  this->ui = new Ui_EasyView;
  this->ui->setupUi(this);

  this->XMLReader    = vtkSmartPointer<vtkXMLTreeReader>::New();
  this->GraphView    = vtkSmartPointer<vtkGraphLayoutView>::New();
  this->TreeView     = vtkSmartPointer<vtkQtTreeView>::New();
  this->TableView    = vtkSmartPointer<vtkQtTableView>::New();
  this->ColumnView   = vtkSmartPointer<vtkQtTreeView>::New();
  this->ColumnView->SetUseColumnView(1);

  // Tell the table view to sort selections that it receives (but does
  // not initiate) to the top
  this->TableView->SetSortSelectionToTop(true);

  // Set widgets for the tree and table views
  this->ui->treeFrame->layout()->addWidget(this->TreeView->GetWidget());
  this->ui->tableFrame->layout()->addWidget(this->TableView->GetWidget());
  this->ui->columnFrame->layout()->addWidget(this->ColumnView->GetWidget());

  // Graph View needs to get my render window
  this->ui->vtkGraphViewWidget->SetRenderWindow(this->GraphView->GetRenderWindow());

  // Set up the theme on the graph view :)
  vtkViewTheme* theme = vtkViewTheme::CreateNeonTheme();
  this->GraphView->ApplyViewTheme(theme);
  theme->Delete();

  // Set up action signals and slots
  connect(this->ui->actionOpenXMLFile, SIGNAL(triggered()), this, SLOT(slotOpenXMLFile()));
  connect(this->ui->actionExit, SIGNAL(triggered()), this, SLOT(slotExit()));

  // Apply application stylesheet
  QString css = "* { font: bold italic 18px \"Calibri\"; color: midnightblue }";
  css += "QTreeView { font: bold italic 16px \"Calibri\"; color: midnightblue }";
  //qApp->setStyleSheet(css); // Seems to cause a bug on some systems
                              // But at least it's here as an example

  this->GraphView->Render();
};

// Set up the annotation between the vtk and qt views
void EasyView::SetupAnnotationLink()
{
  // Create a selection link and have all the views use it
  VTK_CREATE(vtkAnnotationLink,annLink);
  this->TreeView->GetRepresentation()->SetAnnotationLink(annLink);
  this->TreeView->GetRepresentation()->SetSelectionType(vtkSelectionNode::PEDIGREEIDS);
  this->TableView->GetRepresentation()->SetAnnotationLink(annLink);
  this->TableView->GetRepresentation()->SetSelectionType(vtkSelectionNode::PEDIGREEIDS);
  this->ColumnView->GetRepresentation()->SetAnnotationLink(annLink);
  this->ColumnView->GetRepresentation()->SetSelectionType(vtkSelectionNode::PEDIGREEIDS);
  this->GraphView->GetRepresentation()->SetAnnotationLink(annLink);
  this->GraphView->GetRepresentation()->SetSelectionType(vtkSelectionNode::PEDIGREEIDS);

  // Set up the theme on the graph view :)
  vtkViewTheme* theme = vtkViewTheme::CreateNeonTheme();
  this->GraphView->ApplyViewTheme(theme);
  this->GraphView->Update();
  theme->Delete();

  VTK_CREATE(vtkViewUpdater,updater);
  updater->AddView(this->TreeView);
  updater->AddView(this->TableView);
  updater->AddView(this->ColumnView);
  updater->AddView(this->GraphView);
}

EasyView::~EasyView()
{

}

// Action to be taken upon graph file open
void EasyView::slotOpenXMLFile()
{
  // Browse for and open the file
  QDir dir;

  // Open the text data file
  QString fileName = QFileDialog::getOpenFileName(
    this,
    "Select the text data file",
    QDir::homePath(),
    "XML Files (*.xml);;All Files (*.*)");

  if (fileName.isNull())
    {
    cerr << "Could not open file" << endl;
    return;
    }

  // Create XML reader
  this->XMLReader->SetFileName( fileName.toAscii() );
  this->XMLReader->ReadTagNameOff();
  this->XMLReader->Update();

  // Set up some hard coded parameters for the graph view
  this->GraphView->SetVertexLabelArrayName("id");
  this->GraphView->VertexLabelVisibilityOn();
  this->GraphView->SetVertexColorArrayName("VertexDegree");
  this->GraphView->ColorVerticesOn();
  this->GraphView->SetEdgeColorArrayName("edge id");
  this->GraphView->ColorEdgesOn();

  // Create a tree layout strategy
  VTK_CREATE(vtkTreeLayoutStrategy, treeStrat);
  treeStrat->RadialOn();
  treeStrat->SetAngle(360);
  treeStrat->SetLogSpacingValue(1);
  this->GraphView->SetLayoutStrategy(treeStrat);

  // Set the input to the graph view
  this->GraphView->SetRepresentationFromInputConnection(this->XMLReader->GetOutputPort());

  // Okay now do an explicit reset camera so that
  // the user doesn't have to move the mouse
  // in the window to see the resulting graph
  this->GraphView->ResetCamera();

  // Now hand off tree to the tree view
  this->TreeView->SetRepresentationFromInputConnection(this->XMLReader->GetOutputPort());
  this->ColumnView->SetRepresentationFromInputConnection(this->XMLReader->GetOutputPort());

  // Extract a table and give to table view
  VTK_CREATE(vtkDataObjectToTable, toTable);
  toTable->SetInputConnection(this->XMLReader->GetOutputPort());
  toTable->SetFieldType(vtkDataObjectToTable::VERTEX_DATA);
  this->TableView->SetRepresentationFromInputConnection(toTable->GetOutputPort());

  this->SetupAnnotationLink();

  // Update all the views
  this->TreeView->Update();
  this->TableView->Update();
  this->ColumnView->Update();

  // Hide an unwanted column in the tree view.  Note that this code *only* workes here,
  // after a call to this->TreeView->Update() ... that's because the Qt tree view widget
  // has to have data before it can be hidden.
  this->TreeView->HideColumn(2);

  // Force a render on the graph view
  this->GraphView->Render();
}

void EasyView::slotExit() {
  qApp->exit();
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium 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 <atlbase.h>
#include <vector>

#include "base/file_path.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

class AccessibilityWinBrowserTest : public InProcessBrowserTest {
 public:
  AccessibilityWinBrowserTest() : screenreader_running_(FALSE) {}

  // InProcessBrowserTest
  void SetUpInProcessBrowserTestFixture();
  void TearDownInProcessBrowserTestFixture();

 protected:
  IAccessible* GetRenderWidgetHostViewClientAccessible();

 private:
  BOOL screenreader_running_;
};

void AccessibilityWinBrowserTest::SetUpInProcessBrowserTestFixture() {
  // This test assumes the windows system-wide SPI_SETSCREENREADER flag is
  // cleared.
  if (SystemParametersInfo(SPI_GETSCREENREADER, 0, &screenreader_running_, 0) &&
      screenreader_running_) {
    // Clear the SPI_SETSCREENREADER flag and notify active applications about
    // the setting change.
    ::SystemParametersInfo(SPI_SETSCREENREADER, FALSE, NULL, 0);
    ::SendNotifyMessage(
        HWND_BROADCAST, WM_SETTINGCHANGE, SPI_GETSCREENREADER, 0);
  }
}

void AccessibilityWinBrowserTest::TearDownInProcessBrowserTestFixture() {
  if (screenreader_running_) {
    // Restore the SPI_SETSCREENREADER flag and notify active applications about
    // the setting change.
    ::SystemParametersInfo(SPI_SETSCREENREADER, TRUE, NULL, 0);
    ::SendNotifyMessage(
        HWND_BROADCAST, WM_SETTINGCHANGE, SPI_GETSCREENREADER, 0);
  }
}

class AccessibleChecker {
 public:
  AccessibleChecker(std::wstring expected_name, int32 expected_role);
  AccessibleChecker(std::wstring expected_name, std::wstring expected_role);

  // Append an AccessibleChecker that verifies accessibility information for
  // a child IAccessible. Order is important.
  void AppendExpectedChild(AccessibleChecker* expected_child);

  // Check that the name and role of the given IAccessible instance and its
  // descendants match the expected names and roles that this object was
  // initialized with.
  void CheckAccessible(IAccessible* accessible);

  typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;

 private:
  void CheckAccessibleName(IAccessible* accessible);
  void CheckAccessibleRole(IAccessible* accessible);
  void CheckAccessibleChildren(IAccessible* accessible);

 private:
  // Expected accessible name. Checked against IAccessible::get_accName.
  std::wstring name_;

  // Expected accessible role. Checked against IAccessible::get_accRole.
  CComVariant role_;

  // Expected accessible children. Checked using IAccessible::get_accChildCount
  // and ::AccessibleChildren.
  AccessibleCheckerVector children_;
};

VARIANT CreateI4Variant(LONG value) {
  VARIANT variant = {0};

  V_VT(&variant) = VT_I4;
  V_I4(&variant) = value;

  return variant;
}

IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
  switch (V_VT(var)) {
    case VT_DISPATCH:
      return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
      break;

    case VT_I4: {
      CComPtr<IDispatch> dispatch;
      HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
      EXPECT_EQ(hr, S_OK);
      return CComQIPtr<IAccessible>(dispatch).Detach();
      break;
    }
  }

  return NULL;
}

// Retrieve the MSAA client accessibility object for the Render Widget Host View
// of the selected tab.
IAccessible*
AccessibilityWinBrowserTest::GetRenderWidgetHostViewClientAccessible() {
  HWND hwnd_render_widget_host_view =
      browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
          GetNativeView();

  IAccessible* accessible;
  HRESULT hr = AccessibleObjectFromWindow(
      hwnd_render_widget_host_view, OBJID_CLIENT,
      IID_IAccessible, reinterpret_cast<void**>(&accessible));
  EXPECT_EQ(S_OK, hr);
  EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));

  return accessible;
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, int32 expected_role) :
    name_(expected_name),
    role_(expected_role) {
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, std::wstring expected_role) :
    name_(expected_name),
    role_(expected_role.c_str()) {
}

void AccessibleChecker::AppendExpectedChild(
    AccessibleChecker* expected_child) {
  children_.push_back(expected_child);
}

void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
  CheckAccessibleName(accessible);
  CheckAccessibleRole(accessible);
  CheckAccessibleChildren(accessible);
}

void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
  CComBSTR name;
  HRESULT hr =
      accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);

  if (name_.empty()) {
    // If the object doesn't have name S_FALSE should be returned.
    EXPECT_EQ(hr, S_FALSE);
  } else {
    // Test that the correct string was returned.
    EXPECT_EQ(hr, S_OK);
    EXPECT_EQ(CompareString(LOCALE_NEUTRAL, 0, name, SysStringLen(name),
                  name_.c_str(), name_.length()),
              CSTR_EQUAL);
  }
}

void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
  VARIANT var_role = {0};
  HRESULT hr =
      accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
  EXPECT_EQ(hr, S_OK);
  ASSERT_TRUE(role_ == var_role);
}

void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
  LONG child_count = 0;
  HRESULT hr = parent->get_accChildCount(&child_count);
  EXPECT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, children_.size());

  std::auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
  LONG obtained_count = 0;
  hr = AccessibleChildren(parent, 0, child_count,
                          child_array.get(), &obtained_count);
  ASSERT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, obtained_count);

  VARIANT* child = child_array.get();
  for (AccessibleCheckerVector::iterator child_checker = children_.begin();
       child_checker != children_.end();
       ++child_checker, ++child) {
    ScopedComPtr<IAccessible> child_accessible;
    child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
    (*child_checker)->CheckAccessible(child_accessible);
  }
}

// http://crbug.com/48079 started failing after WebKit roll  62240:62258
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       DISABLED_TestRendererAccessibilityTree) {
  // By requesting an accessible chrome will believe a screen reader has been
  // detected.
  ScopedComPtr<IAccessible> document_accessible(
      GetRenderWidgetHostViewClientAccessible());

  // The initial accessible returned should have state STATE_SYSTEM_BUSY while
  // the accessibility tree is being requested from the renderer.
  VARIANT var_state;
  HRESULT hr = document_accessible->
      get_accState(CreateI4Variant(CHILDID_SELF), &var_state);
  EXPECT_EQ(hr, S_OK);
  EXPECT_EQ(V_VT(&var_state), VT_I4);
  EXPECT_EQ(V_I4(&var_state), STATE_SYSTEM_BUSY);

  GURL tree_url(
      "data:text/html,<title>Accessibility Win Test</title>"
      "<input type='button' value='push' /><input type='checkbox' />"
      "");
  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);

  document_accessible = GetRenderWidgetHostViewClientAccessible();
  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));

  AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON);
  AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON);

  AccessibleChecker grouping_checker(L"", L"div");
  grouping_checker.AppendExpectedChild(&button_checker);
  grouping_checker.AppendExpectedChild(&checkbox_checker);

  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT);
  document_checker.AppendExpectedChild(&grouping_checker);

  // Check the accessible tree of the renderer.
  document_checker.CheckAccessible(document_accessible);

  // Check that document accessible has a parent accessible.
  ScopedComPtr<IDispatch> parent_dispatch;
  hr = document_accessible->get_accParent(parent_dispatch.Receive());
  EXPECT_EQ(hr, S_OK);
  EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));

  // Navigate to another page.
  GURL about_url("about:");
  ui_test_utils::NavigateToURL(browser(), about_url);

  // Verify that the IAccessible reference still points to a valid object and
  // that it calls to its methods fail since the tree is no longer valid after
  // the page navagation.
  // Todo(ctguil): Currently this is giving a false positive because E_FAIL is
  // returned when BrowserAccessibilityManager::RequestAccessibilityInfo fails
  // since the previous render view host connection is lost. Verify that
  // instances are actually marked as invalid once the browse side cache is
  // checked in.
  CComBSTR name;
  hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
  ASSERT_EQ(E_FAIL, hr);
}
}  // namespace.
<commit_msg>Roll out 51377 since WebKit roll was reverted<commit_after>// Copyright (c) 2010 The Chromium 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 <atlbase.h>
#include <vector>

#include "base/file_path.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

class AccessibilityWinBrowserTest : public InProcessBrowserTest {
 public:
  AccessibilityWinBrowserTest() : screenreader_running_(FALSE) {}

  // InProcessBrowserTest
  void SetUpInProcessBrowserTestFixture();
  void TearDownInProcessBrowserTestFixture();

 protected:
  IAccessible* GetRenderWidgetHostViewClientAccessible();

 private:
  BOOL screenreader_running_;
};

void AccessibilityWinBrowserTest::SetUpInProcessBrowserTestFixture() {
  // This test assumes the windows system-wide SPI_SETSCREENREADER flag is
  // cleared.
  if (SystemParametersInfo(SPI_GETSCREENREADER, 0, &screenreader_running_, 0) &&
      screenreader_running_) {
    // Clear the SPI_SETSCREENREADER flag and notify active applications about
    // the setting change.
    ::SystemParametersInfo(SPI_SETSCREENREADER, FALSE, NULL, 0);
    ::SendNotifyMessage(
        HWND_BROADCAST, WM_SETTINGCHANGE, SPI_GETSCREENREADER, 0);
  }
}

void AccessibilityWinBrowserTest::TearDownInProcessBrowserTestFixture() {
  if (screenreader_running_) {
    // Restore the SPI_SETSCREENREADER flag and notify active applications about
    // the setting change.
    ::SystemParametersInfo(SPI_SETSCREENREADER, TRUE, NULL, 0);
    ::SendNotifyMessage(
        HWND_BROADCAST, WM_SETTINGCHANGE, SPI_GETSCREENREADER, 0);
  }
}

class AccessibleChecker {
 public:
  AccessibleChecker(std::wstring expected_name, int32 expected_role);
  AccessibleChecker(std::wstring expected_name, std::wstring expected_role);

  // Append an AccessibleChecker that verifies accessibility information for
  // a child IAccessible. Order is important.
  void AppendExpectedChild(AccessibleChecker* expected_child);

  // Check that the name and role of the given IAccessible instance and its
  // descendants match the expected names and roles that this object was
  // initialized with.
  void CheckAccessible(IAccessible* accessible);

  typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;

 private:
  void CheckAccessibleName(IAccessible* accessible);
  void CheckAccessibleRole(IAccessible* accessible);
  void CheckAccessibleChildren(IAccessible* accessible);

 private:
  // Expected accessible name. Checked against IAccessible::get_accName.
  std::wstring name_;

  // Expected accessible role. Checked against IAccessible::get_accRole.
  CComVariant role_;

  // Expected accessible children. Checked using IAccessible::get_accChildCount
  // and ::AccessibleChildren.
  AccessibleCheckerVector children_;
};

VARIANT CreateI4Variant(LONG value) {
  VARIANT variant = {0};

  V_VT(&variant) = VT_I4;
  V_I4(&variant) = value;

  return variant;
}

IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
  switch (V_VT(var)) {
    case VT_DISPATCH:
      return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
      break;

    case VT_I4: {
      CComPtr<IDispatch> dispatch;
      HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
      EXPECT_EQ(hr, S_OK);
      return CComQIPtr<IAccessible>(dispatch).Detach();
      break;
    }
  }

  return NULL;
}

// Retrieve the MSAA client accessibility object for the Render Widget Host View
// of the selected tab.
IAccessible*
AccessibilityWinBrowserTest::GetRenderWidgetHostViewClientAccessible() {
  HWND hwnd_render_widget_host_view =
      browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
          GetNativeView();

  IAccessible* accessible;
  HRESULT hr = AccessibleObjectFromWindow(
      hwnd_render_widget_host_view, OBJID_CLIENT,
      IID_IAccessible, reinterpret_cast<void**>(&accessible));
  EXPECT_EQ(S_OK, hr);
  EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));

  return accessible;
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, int32 expected_role) :
    name_(expected_name),
    role_(expected_role) {
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, std::wstring expected_role) :
    name_(expected_name),
    role_(expected_role.c_str()) {
}

void AccessibleChecker::AppendExpectedChild(
    AccessibleChecker* expected_child) {
  children_.push_back(expected_child);
}

void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
  CheckAccessibleName(accessible);
  CheckAccessibleRole(accessible);
  CheckAccessibleChildren(accessible);
}

void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
  CComBSTR name;
  HRESULT hr =
      accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);

  if (name_.empty()) {
    // If the object doesn't have name S_FALSE should be returned.
    EXPECT_EQ(hr, S_FALSE);
  } else {
    // Test that the correct string was returned.
    EXPECT_EQ(hr, S_OK);
    EXPECT_EQ(CompareString(LOCALE_NEUTRAL, 0, name, SysStringLen(name),
                  name_.c_str(), name_.length()),
              CSTR_EQUAL);
  }
}

void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
  VARIANT var_role = {0};
  HRESULT hr =
      accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
  EXPECT_EQ(hr, S_OK);
  ASSERT_TRUE(role_ == var_role);
}

void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
  LONG child_count = 0;
  HRESULT hr = parent->get_accChildCount(&child_count);
  EXPECT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, children_.size());

  std::auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
  LONG obtained_count = 0;
  hr = AccessibleChildren(parent, 0, child_count,
                          child_array.get(), &obtained_count);
  ASSERT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, obtained_count);

  VARIANT* child = child_array.get();
  for (AccessibleCheckerVector::iterator child_checker = children_.begin();
       child_checker != children_.end();
       ++child_checker, ++child) {
    ScopedComPtr<IAccessible> child_accessible;
    child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
    (*child_checker)->CheckAccessible(child_accessible);
  }
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestRendererAccessibilityTree) {
  // By requesting an accessible chrome will believe a screen reader has been
  // detected.
  ScopedComPtr<IAccessible> document_accessible(
      GetRenderWidgetHostViewClientAccessible());

  // The initial accessible returned should have state STATE_SYSTEM_BUSY while
  // the accessibility tree is being requested from the renderer.
  VARIANT var_state;
  HRESULT hr = document_accessible->
      get_accState(CreateI4Variant(CHILDID_SELF), &var_state);
  EXPECT_EQ(hr, S_OK);
  EXPECT_EQ(V_VT(&var_state), VT_I4);
  EXPECT_EQ(V_I4(&var_state), STATE_SYSTEM_BUSY);

  GURL tree_url(
      "data:text/html,<title>Accessibility Win Test</title>"
      "<input type='button' value='push' /><input type='checkbox' />"
      "");
  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);

  document_accessible = GetRenderWidgetHostViewClientAccessible();
  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));

  AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON);
  AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON);

  AccessibleChecker grouping_checker(L"", L"div");
  grouping_checker.AppendExpectedChild(&button_checker);
  grouping_checker.AppendExpectedChild(&checkbox_checker);

  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT);
  document_checker.AppendExpectedChild(&grouping_checker);

  // Check the accessible tree of the renderer.
  document_checker.CheckAccessible(document_accessible);

  // Check that document accessible has a parent accessible.
  ScopedComPtr<IDispatch> parent_dispatch;
  hr = document_accessible->get_accParent(parent_dispatch.Receive());
  EXPECT_EQ(hr, S_OK);
  EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));

  // Navigate to another page.
  GURL about_url("about:");
  ui_test_utils::NavigateToURL(browser(), about_url);

  // Verify that the IAccessible reference still points to a valid object and
  // that it calls to its methods fail since the tree is no longer valid after
  // the page navagation.
  // Todo(ctguil): Currently this is giving a false positive because E_FAIL is
  // returned when BrowserAccessibilityManager::RequestAccessibilityInfo fails
  // since the previous render view host connection is lost. Verify that
  // instances are actually marked as invalid once the browse side cache is
  // checked in.
  CComBSTR name;
  hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
  ASSERT_EQ(E_FAIL, hr);
}
}  // namespace.
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium 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 <atlbase.h>
#include <vector>

#include "base/file_path.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

#if defined(OS_WIN)
// http://crbug.com/48655
#define SKIP_WIN(test) DISABLED_##test
#else
#define SKIP_WIN(test) test
#endif

namespace {

class AccessibilityWinBrowserTest : public InProcessBrowserTest {
 public:
  AccessibilityWinBrowserTest() : screenreader_running_(FALSE) {}

  // InProcessBrowserTest
  void SetUpInProcessBrowserTestFixture();
  void TearDownInProcessBrowserTestFixture();

 protected:
  IAccessible* GetRenderWidgetHostViewClientAccessible();

 private:
  BOOL screenreader_running_;
};

void AccessibilityWinBrowserTest::SetUpInProcessBrowserTestFixture() {
  // This test assumes the windows system-wide SPI_SETSCREENREADER flag is
  // cleared.
  if (SystemParametersInfo(SPI_GETSCREENREADER, 0, &screenreader_running_, 0) &&
      screenreader_running_) {
    // Clear the SPI_SETSCREENREADER flag and notify active applications about
    // the setting change.
    ::SystemParametersInfo(SPI_SETSCREENREADER, FALSE, NULL, 0);
    ::SendNotifyMessage(
        HWND_BROADCAST, WM_SETTINGCHANGE, SPI_GETSCREENREADER, 0);
  }
}

void AccessibilityWinBrowserTest::TearDownInProcessBrowserTestFixture() {
  if (screenreader_running_) {
    // Restore the SPI_SETSCREENREADER flag and notify active applications about
    // the setting change.
    ::SystemParametersInfo(SPI_SETSCREENREADER, TRUE, NULL, 0);
    ::SendNotifyMessage(
        HWND_BROADCAST, WM_SETTINGCHANGE, SPI_GETSCREENREADER, 0);
  }
}

class AccessibleChecker {
 public:
  AccessibleChecker(std::wstring expected_name, int32 expected_role);
  AccessibleChecker(std::wstring expected_name, std::wstring expected_role);

  // Append an AccessibleChecker that verifies accessibility information for
  // a child IAccessible. Order is important.
  void AppendExpectedChild(AccessibleChecker* expected_child);

  // Check that the name and role of the given IAccessible instance and its
  // descendants match the expected names and roles that this object was
  // initialized with.
  void CheckAccessible(IAccessible* accessible);

  typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;

 private:
  void CheckAccessibleName(IAccessible* accessible);
  void CheckAccessibleRole(IAccessible* accessible);
  void CheckAccessibleChildren(IAccessible* accessible);

 private:
  // Expected accessible name. Checked against IAccessible::get_accName.
  std::wstring name_;

  // Expected accessible role. Checked against IAccessible::get_accRole.
  CComVariant role_;

  // Expected accessible children. Checked using IAccessible::get_accChildCount
  // and ::AccessibleChildren.
  AccessibleCheckerVector children_;
};

VARIANT CreateI4Variant(LONG value) {
  VARIANT variant = {0};

  V_VT(&variant) = VT_I4;
  V_I4(&variant) = value;

  return variant;
}

IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
  switch (V_VT(var)) {
    case VT_DISPATCH:
      return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
      break;

    case VT_I4: {
      CComPtr<IDispatch> dispatch;
      HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
      EXPECT_EQ(hr, S_OK);
      return CComQIPtr<IAccessible>(dispatch).Detach();
      break;
    }
  }

  return NULL;
}

// Retrieve the MSAA client accessibility object for the Render Widget Host View
// of the selected tab.
IAccessible*
AccessibilityWinBrowserTest::GetRenderWidgetHostViewClientAccessible() {
  HWND hwnd_render_widget_host_view =
      browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
          GetNativeView();

  IAccessible* accessible;
  HRESULT hr = AccessibleObjectFromWindow(
      hwnd_render_widget_host_view, OBJID_CLIENT,
      IID_IAccessible, reinterpret_cast<void**>(&accessible));
  EXPECT_EQ(S_OK, hr);
  EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));

  return accessible;
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, int32 expected_role) :
    name_(expected_name),
    role_(expected_role) {
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, std::wstring expected_role) :
    name_(expected_name),
    role_(expected_role.c_str()) {
}

void AccessibleChecker::AppendExpectedChild(
    AccessibleChecker* expected_child) {
  children_.push_back(expected_child);
}

void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
  CheckAccessibleName(accessible);
  CheckAccessibleRole(accessible);
  CheckAccessibleChildren(accessible);
}

void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
  CComBSTR name;
  HRESULT hr =
      accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);

  if (name_.empty()) {
    // If the object doesn't have name S_FALSE should be returned.
    EXPECT_EQ(hr, S_FALSE);
  } else {
    // Test that the correct string was returned.
    EXPECT_EQ(hr, S_OK);
    EXPECT_EQ(CompareString(LOCALE_NEUTRAL, 0, name, SysStringLen(name),
                  name_.c_str(), name_.length()),
              CSTR_EQUAL);
  }
}

void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
  VARIANT var_role = {0};
  HRESULT hr =
      accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
  EXPECT_EQ(hr, S_OK);
  ASSERT_TRUE(role_ == var_role);
}

void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
  LONG child_count = 0;
  HRESULT hr = parent->get_accChildCount(&child_count);
  EXPECT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, children_.size());

  std::auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
  LONG obtained_count = 0;
  hr = AccessibleChildren(parent, 0, child_count,
                          child_array.get(), &obtained_count);
  ASSERT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, obtained_count);

  VARIANT* child = child_array.get();
  for (AccessibleCheckerVector::iterator child_checker = children_.begin();
       child_checker != children_.end();
       ++child_checker, ++child) {
    ScopedComPtr<IAccessible> child_accessible;
    child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
    (*child_checker)->CheckAccessible(child_accessible);
  }
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       SKIP_WIN(TestRendererAccessibilityTree)) {
  // By requesting an accessible chrome will believe a screen reader has been
  // detected.
  ScopedComPtr<IAccessible> document_accessible(
      GetRenderWidgetHostViewClientAccessible());

  // The initial accessible returned should have state STATE_SYSTEM_BUSY while
  // the accessibility tree is being requested from the renderer.
  VARIANT var_state;
  HRESULT hr = document_accessible->
      get_accState(CreateI4Variant(CHILDID_SELF), &var_state);
  EXPECT_EQ(hr, S_OK);
  EXPECT_EQ(V_VT(&var_state), VT_I4);
  EXPECT_EQ(V_I4(&var_state), STATE_SYSTEM_BUSY);

  GURL tree_url(
      "data:text/html,<title>Accessibility Win Test</title>"
      "<input type='button' value='push' /><input type='checkbox' />"
      "");
  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);

  document_accessible = GetRenderWidgetHostViewClientAccessible();
  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));

  AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON);
  AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON);

  AccessibleChecker grouping_checker(L"", L"div");
  grouping_checker.AppendExpectedChild(&button_checker);
  grouping_checker.AppendExpectedChild(&checkbox_checker);

  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT);
  document_checker.AppendExpectedChild(&grouping_checker);

  // Check the accessible tree of the renderer.
  document_checker.CheckAccessible(document_accessible);

  // Check that document accessible has a parent accessible.
  ScopedComPtr<IDispatch> parent_dispatch;
  hr = document_accessible->get_accParent(parent_dispatch.Receive());
  EXPECT_EQ(hr, S_OK);
  EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));

  // Navigate to another page.
  GURL about_url("about:");
  ui_test_utils::NavigateToURL(browser(), about_url);

  // Verify that the IAccessible reference still points to a valid object and
  // that it calls to its methods fail since the tree is no longer valid after
  // the page navagation.
  // Todo(ctguil): Currently this is giving a false positive because E_FAIL is
  // returned when BrowserAccessibilityManager::RequestAccessibilityInfo fails
  // since the previous render view host connection is lost. Verify that
  // instances are actually marked as invalid once the browse side cache is
  // checked in.
  CComBSTR name;
  hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
  ASSERT_EQ(E_FAIL, hr);
}
}  // namespace.
<commit_msg>Wait for the initial accessibility tree to load from the renderer.<commit_after>// Copyright (c) 2010 The Chromium 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 <atlbase.h>
#include <vector>

#include "base/file_path.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

class AccessibilityWinBrowserTest : public InProcessBrowserTest {
 public:
  AccessibilityWinBrowserTest() : screenreader_running_(FALSE) {}

  // InProcessBrowserTest
  void SetUpInProcessBrowserTestFixture();
  void TearDownInProcessBrowserTestFixture();

 protected:
  IAccessible* GetRenderWidgetHostViewClientAccessible();

 private:
  BOOL screenreader_running_;
};

void AccessibilityWinBrowserTest::SetUpInProcessBrowserTestFixture() {
  // This test assumes the windows system-wide SPI_SETSCREENREADER flag is
  // cleared.
  if (SystemParametersInfo(SPI_GETSCREENREADER, 0, &screenreader_running_, 0) &&
      screenreader_running_) {
    // Clear the SPI_SETSCREENREADER flag and notify active applications about
    // the setting change.
    ::SystemParametersInfo(SPI_SETSCREENREADER, FALSE, NULL, 0);
    ::SendNotifyMessage(
        HWND_BROADCAST, WM_SETTINGCHANGE, SPI_GETSCREENREADER, 0);
  }
}

void AccessibilityWinBrowserTest::TearDownInProcessBrowserTestFixture() {
  if (screenreader_running_) {
    // Restore the SPI_SETSCREENREADER flag and notify active applications about
    // the setting change.
    ::SystemParametersInfo(SPI_SETSCREENREADER, TRUE, NULL, 0);
    ::SendNotifyMessage(
        HWND_BROADCAST, WM_SETTINGCHANGE, SPI_GETSCREENREADER, 0);
  }
}

class AccessibleChecker {
 public:
  AccessibleChecker(std::wstring expected_name, int32 expected_role);
  AccessibleChecker(std::wstring expected_name, std::wstring expected_role);

  // Append an AccessibleChecker that verifies accessibility information for
  // a child IAccessible. Order is important.
  void AppendExpectedChild(AccessibleChecker* expected_child);

  // Check that the name and role of the given IAccessible instance and its
  // descendants match the expected names and roles that this object was
  // initialized with.
  void CheckAccessible(IAccessible* accessible);

  typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;

 private:
  void CheckAccessibleName(IAccessible* accessible);
  void CheckAccessibleRole(IAccessible* accessible);
  void CheckAccessibleChildren(IAccessible* accessible);

 private:
  // Expected accessible name. Checked against IAccessible::get_accName.
  std::wstring name_;

  // Expected accessible role. Checked against IAccessible::get_accRole.
  CComVariant role_;

  // Expected accessible children. Checked using IAccessible::get_accChildCount
  // and ::AccessibleChildren.
  AccessibleCheckerVector children_;
};

VARIANT CreateI4Variant(LONG value) {
  VARIANT variant = {0};

  V_VT(&variant) = VT_I4;
  V_I4(&variant) = value;

  return variant;
}

IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
  switch (V_VT(var)) {
    case VT_DISPATCH:
      return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
      break;

    case VT_I4: {
      CComPtr<IDispatch> dispatch;
      HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
      EXPECT_EQ(hr, S_OK);
      return CComQIPtr<IAccessible>(dispatch).Detach();
      break;
    }
  }

  return NULL;
}

// Retrieve the MSAA client accessibility object for the Render Widget Host View
// of the selected tab.
IAccessible*
AccessibilityWinBrowserTest::GetRenderWidgetHostViewClientAccessible() {
  HWND hwnd_render_widget_host_view =
      browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
          GetNativeView();

  IAccessible* accessible;
  HRESULT hr = AccessibleObjectFromWindow(
      hwnd_render_widget_host_view, OBJID_CLIENT,
      IID_IAccessible, reinterpret_cast<void**>(&accessible));
  EXPECT_EQ(S_OK, hr);
  EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));

  return accessible;
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, int32 expected_role) :
    name_(expected_name),
    role_(expected_role) {
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, std::wstring expected_role) :
    name_(expected_name),
    role_(expected_role.c_str()) {
}

void AccessibleChecker::AppendExpectedChild(
    AccessibleChecker* expected_child) {
  children_.push_back(expected_child);
}

void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
  CheckAccessibleName(accessible);
  CheckAccessibleRole(accessible);
  CheckAccessibleChildren(accessible);
}

void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
  CComBSTR name;
  HRESULT hr =
      accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);

  if (name_.empty()) {
    // If the object doesn't have name S_FALSE should be returned.
    EXPECT_EQ(hr, S_FALSE);
  } else {
    // Test that the correct string was returned.
    EXPECT_EQ(hr, S_OK);
    EXPECT_EQ(CompareString(LOCALE_NEUTRAL, 0, name, SysStringLen(name),
                  name_.c_str(), name_.length()),
              CSTR_EQUAL);
  }
}

void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
  VARIANT var_role = {0};
  HRESULT hr =
      accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
  EXPECT_EQ(hr, S_OK);
  ASSERT_TRUE(role_ == var_role);
}

void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
  LONG child_count = 0;
  HRESULT hr = parent->get_accChildCount(&child_count);
  EXPECT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, children_.size());

  std::auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
  LONG obtained_count = 0;
  hr = AccessibleChildren(parent, 0, child_count,
                          child_array.get(), &obtained_count);
  ASSERT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, obtained_count);

  VARIANT* child = child_array.get();
  for (AccessibleCheckerVector::iterator child_checker = children_.begin();
       child_checker != children_.end();
       ++child_checker, ++child) {
    ScopedComPtr<IAccessible> child_accessible;
    child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
    (*child_checker)->CheckAccessible(child_accessible);
  }
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestRendererAccessibilityTree) {
  // By requesting an accessible chrome will believe a screen reader has been
  // detected.
  ScopedComPtr<IAccessible> document_accessible(
      GetRenderWidgetHostViewClientAccessible());

  // The initial accessible returned should have state STATE_SYSTEM_BUSY while
  // the accessibility tree is being requested from the renderer.
  VARIANT var_state;
  HRESULT hr = document_accessible->
      get_accState(CreateI4Variant(CHILDID_SELF), &var_state);
  EXPECT_EQ(hr, S_OK);
  EXPECT_EQ(V_VT(&var_state), VT_I4);
  EXPECT_EQ(V_I4(&var_state), STATE_SYSTEM_BUSY);

  // Wait for the initial accessibility tree to load.
  ui_test_utils::WaitForNotification(
      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);

  GURL tree_url(
      "data:text/html,<title>Accessibility Win Test</title>"
      "<input type='button' value='push' /><input type='checkbox' />"
      "");
  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);

  document_accessible = GetRenderWidgetHostViewClientAccessible();
  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));

  AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON);
  AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON);

  AccessibleChecker grouping_checker(L"", L"div");
  grouping_checker.AppendExpectedChild(&button_checker);
  grouping_checker.AppendExpectedChild(&checkbox_checker);

  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT);
  document_checker.AppendExpectedChild(&grouping_checker);

  // Check the accessible tree of the renderer.
  document_checker.CheckAccessible(document_accessible);

  // Check that document accessible has a parent accessible.
  ScopedComPtr<IDispatch> parent_dispatch;
  hr = document_accessible->get_accParent(parent_dispatch.Receive());
  EXPECT_EQ(hr, S_OK);
  EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));

  // Navigate to another page.
  GURL about_url("about:");
  ui_test_utils::NavigateToURL(browser(), about_url);

  // Verify that the IAccessible reference still points to a valid object and
  // that calls to its methods fail since the tree is no longer valid after
  // the page navagation.
  // Todo(ctguil): Currently this is giving a false positive because E_FAIL is
  // returned when BrowserAccessibilityManager::RequestAccessibilityInfo fails
  // since the previous render view host connection is lost. Verify that
  // instances are actually marked as invalid once the browse side cache is
  // checked in.
  CComBSTR name;
  hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
  ASSERT_EQ(E_FAIL, hr);
}
}  // namespace.
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium 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 "chrome/browser/extensions/extensions_service.h"

#include "base/file_util.h"
#include "base/values.h"
#include "base/string_util.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/json_value_serializer.h"

// ExtensionsService

const FilePath::CharType* ExtensionsService::kInstallDirectoryName =
    FILE_PATH_LITERAL("Extensions");

ExtensionsService::ExtensionsService(const FilePath& profile_directory)
    : message_loop_(MessageLoop::current()),
      backend_(new ExtensionsServiceBackend),
      install_directory_(profile_directory.Append(kInstallDirectoryName)) {
}

ExtensionsService::~ExtensionsService() {
  for (ExtensionList::iterator iter = extensions_.begin();
       iter != extensions_.end(); ++iter) {
    delete *iter;
  }
}

bool ExtensionsService::Init() {
  // TODO(aa): This message loop should probably come from a backend
  // interface, similar to how the message loop for the frontend comes
  // from the frontend interface.
  g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
      NewRunnableMethod(backend_.get(),
          &ExtensionsServiceBackend::LoadExtensionsFromDirectory,
          install_directory_,
          scoped_refptr<ExtensionsServiceFrontendInterface>(this)));
  // TODO(aa): Load extensions from other registered directories.

  return true;
}

MessageLoop* ExtensionsService::GetMessageLoop() {
  return message_loop_;
}

void ExtensionsService::OnExtensionsLoadedFromDirectory(
    ExtensionList* new_extensions) {
  extensions_.insert(extensions_.end(), new_extensions->begin(),
                     new_extensions->end());
  delete new_extensions;

  // TODO(aa): Notify extensions are loaded.
}

void ExtensionsService::OnExtensionLoadError(const std::string& error) {
  // TODO(aa): Print the error message out somewhere better. I think we are
  // going to need some sort of 'extension inspector'.
  LOG(WARNING) << error;
}

// ExtensionsServicesBackend

bool ExtensionsServiceBackend::LoadExtensionsFromDirectory(
    const FilePath& path,
    scoped_refptr<ExtensionsServiceFrontendInterface> frontend) {
  // Find all child directories in the install directory and load their
  // manifests. Post errors and results to the frontend.
  scoped_ptr<ExtensionList> extensions(new ExtensionList);
  file_util::FileEnumerator enumerator(path.ToWStringHack(),
                                       false, // not recursive
                                       file_util::FileEnumerator::DIRECTORIES);
  for (std::wstring child_path = enumerator.Next(); !child_path.empty();
       child_path = enumerator.Next()) {
     FilePath manifest_path = FilePath::FromWStringHack(child_path).Append(
         Extension::kManifestFilename);
    if (!file_util::PathExists(manifest_path)) {
      ReportExtensionLoadError(frontend.get(), child_path,
                               Extension::kInvalidManifestError);
      continue;
    }

    JSONFileValueSerializer serializer(manifest_path.ToWStringHack());
    Value* root = NULL;
    std::string error;
    if (!serializer.Deserialize(&root, &error)) {
      ReportExtensionLoadError(frontend.get(), child_path, error);
      continue;
    }

    scoped_ptr<Value> scoped_root(root);
    if (!root->IsType(Value::TYPE_DICTIONARY)) {
      ReportExtensionLoadError(frontend.get(), child_path,
                               Extension::kInvalidManifestError);
      continue;
    }

    scoped_ptr<Extension> extension(new Extension());
    if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root),
                                  &error)) {
      ReportExtensionLoadError(frontend.get(), child_path, error);
      continue;
    }

    extensions->push_back(extension.release());
    delete root;
  }

  ReportExtensionsLoaded(frontend.get(), extensions.release());
  return true;
}

void ExtensionsServiceBackend::ReportExtensionLoadError(
    ExtensionsServiceFrontendInterface *frontend, const std::wstring& path,
    const std::string &error) {
  std::string message = StringPrintf("Could not load extension from '%s'. %s",
                                     WideToASCII(path).c_str(), error.c_str());
  frontend->GetMessageLoop()->PostTask(FROM_HERE, NewRunnableMethod(
      frontend, &ExtensionsServiceFrontendInterface::OnExtensionLoadError,
      message));
}

void ExtensionsServiceBackend::ReportExtensionsLoaded(
    ExtensionsServiceFrontendInterface *frontend, ExtensionList* extensions) {
  frontend->GetMessageLoop()->PostTask(FROM_HERE, NewRunnableMethod(
      frontend,
      &ExtensionsServiceFrontendInterface::OnExtensionsLoadedFromDirectory,
      extensions));
}
<commit_msg>bad merge, no need to delete a scoped_ptr<commit_after>// Copyright (c) 2006-2008 The Chromium 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 "chrome/browser/extensions/extensions_service.h"

#include "base/file_util.h"
#include "base/values.h"
#include "base/string_util.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/json_value_serializer.h"

// ExtensionsService

const FilePath::CharType* ExtensionsService::kInstallDirectoryName =
    FILE_PATH_LITERAL("Extensions");

ExtensionsService::ExtensionsService(const FilePath& profile_directory)
    : message_loop_(MessageLoop::current()),
      backend_(new ExtensionsServiceBackend),
      install_directory_(profile_directory.Append(kInstallDirectoryName)) {
}

ExtensionsService::~ExtensionsService() {
  for (ExtensionList::iterator iter = extensions_.begin();
       iter != extensions_.end(); ++iter) {
    delete *iter;
  }
}

bool ExtensionsService::Init() {
  // TODO(aa): This message loop should probably come from a backend
  // interface, similar to how the message loop for the frontend comes
  // from the frontend interface.
  g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
      NewRunnableMethod(backend_.get(),
          &ExtensionsServiceBackend::LoadExtensionsFromDirectory,
          install_directory_,
          scoped_refptr<ExtensionsServiceFrontendInterface>(this)));
  // TODO(aa): Load extensions from other registered directories.

  return true;
}

MessageLoop* ExtensionsService::GetMessageLoop() {
  return message_loop_;
}

void ExtensionsService::OnExtensionsLoadedFromDirectory(
    ExtensionList* new_extensions) {
  extensions_.insert(extensions_.end(), new_extensions->begin(),
                     new_extensions->end());
  delete new_extensions;

  // TODO(aa): Notify extensions are loaded.
}

void ExtensionsService::OnExtensionLoadError(const std::string& error) {
  // TODO(aa): Print the error message out somewhere better. I think we are
  // going to need some sort of 'extension inspector'.
  LOG(WARNING) << error;
}

// ExtensionsServicesBackend

bool ExtensionsServiceBackend::LoadExtensionsFromDirectory(
    const FilePath& path,
    scoped_refptr<ExtensionsServiceFrontendInterface> frontend) {
  // Find all child directories in the install directory and load their
  // manifests. Post errors and results to the frontend.
  scoped_ptr<ExtensionList> extensions(new ExtensionList);
  file_util::FileEnumerator enumerator(path.ToWStringHack(),
                                       false, // not recursive
                                       file_util::FileEnumerator::DIRECTORIES);
  for (std::wstring child_path = enumerator.Next(); !child_path.empty();
       child_path = enumerator.Next()) {
     FilePath manifest_path = FilePath::FromWStringHack(child_path).Append(
         Extension::kManifestFilename);
    if (!file_util::PathExists(manifest_path)) {
      ReportExtensionLoadError(frontend.get(), child_path,
                               Extension::kInvalidManifestError);
      continue;
    }

    JSONFileValueSerializer serializer(manifest_path.ToWStringHack());
    Value* root = NULL;
    std::string error;
    if (!serializer.Deserialize(&root, &error)) {
      ReportExtensionLoadError(frontend.get(), child_path, error);
      continue;
    }

    scoped_ptr<Value> scoped_root(root);
    if (!root->IsType(Value::TYPE_DICTIONARY)) {
      ReportExtensionLoadError(frontend.get(), child_path,
                               Extension::kInvalidManifestError);
      continue;
    }

    scoped_ptr<Extension> extension(new Extension());
    if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root),
                                  &error)) {
      ReportExtensionLoadError(frontend.get(), child_path, error);
      continue;
    }

    extensions->push_back(extension.release());
  }

  ReportExtensionsLoaded(frontend.get(), extensions.release());
  return true;
}

void ExtensionsServiceBackend::ReportExtensionLoadError(
    ExtensionsServiceFrontendInterface *frontend, const std::wstring& path,
    const std::string &error) {
  std::string message = StringPrintf("Could not load extension from '%s'. %s",
                                     WideToASCII(path).c_str(), error.c_str());
  frontend->GetMessageLoop()->PostTask(FROM_HERE, NewRunnableMethod(
      frontend, &ExtensionsServiceFrontendInterface::OnExtensionLoadError,
      message));
}

void ExtensionsServiceBackend::ReportExtensionsLoaded(
    ExtensionsServiceFrontendInterface *frontend, ExtensionList* extensions) {
  frontend->GetMessageLoop()->PostTask(FROM_HERE, NewRunnableMethod(
      frontend,
      &ExtensionsServiceFrontendInterface::OnExtensionsLoadedFromDirectory,
      extensions));
}
<|endoftext|>