<commit_before>//----------------------------  full_matrix.double.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  full_matrix.double.cc  ---------------------------

#include <lac/full_matrix.templates.h>
#include <base/logstream.h>

#define TYPEMAT double

template class FullMatrix<TYPEMAT>;

#define TYPEMAT2 double

//template FullMatrix<TYPEMAT>& FullMatrix<TYPEMAT>::operator =(const FullMatrix<TYPEMAT2>&);
template void FullMatrix<TYPEMAT>::fill (const FullMatrix<TYPEMAT2>&, const unsigned, const unsigned);
template void FullMatrix<TYPEMAT>::add (const TYPEMAT, const FullMatrix<TYPEMAT2>&);
template void FullMatrix<TYPEMAT>::Tadd (const TYPEMAT, const FullMatrix<TYPEMAT2>&);
template void FullMatrix<TYPEMAT>::mmult (FullMatrix<TYPEMAT2>&, const FullMatrix<TYPEMAT2>&, const bool) const;
template void FullMatrix<TYPEMAT>::Tmmult (FullMatrix<TYPEMAT2>&, const FullMatrix<TYPEMAT2>&, const bool) const;
template void FullMatrix<TYPEMAT>::add_diag (const TYPEMAT, const FullMatrix<TYPEMAT2>&);

#define TYPEVEC double
#define TYPERES double

template void FullMatrix<TYPEMAT>::fill_permutation (const FullMatrix<TYPEVEC>&,
						     const std::vector<unsigned int>&,
						     const std::vector<unsigned int>&);
template void FullMatrix<TYPEMAT>::vmult(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const bool) const;
template void FullMatrix<TYPEMAT>::Tvmult(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const bool) const;
template double FullMatrix<TYPEMAT>::residual(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const Vector<TYPERES>&) const;
template TYPEVEC FullMatrix<TYPEMAT>::matrix_norm_square (const Vector<TYPEVEC> &) const;
template TYPEVEC FullMatrix<TYPEMAT>::matrix_scalar_product(const Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::forward(Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::backward(Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::householder(Vector<TYPEVEC>&);
template double FullMatrix<TYPEMAT>::least_squares(Vector<TYPEVEC>&, Vector<TYPEVEC>&);

#undef TYPEVEC
#define TYPEVEC float

template void FullMatrix<TYPEMAT>::fill_permutation (const FullMatrix<TYPEVEC>&,
						     const std::vector<unsigned int>&,
						     const std::vector<unsigned int>&);
template void FullMatrix<TYPEMAT>::vmult(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const bool) const;
template void FullMatrix<TYPEMAT>::Tvmult(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const bool) const;
template double FullMatrix<TYPEMAT>::residual(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const Vector<TYPERES>&) const;
template TYPEVEC FullMatrix<TYPEMAT>::matrix_norm_square (const Vector<TYPEVEC> &) const;
template TYPEVEC FullMatrix<TYPEMAT>::matrix_scalar_product(const Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::forward(Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::backward(Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::householder(Vector<TYPEVEC>&);
template double FullMatrix<TYPEMAT>::least_squares(Vector<TYPEVEC>&, Vector<TYPEVEC>&);

#undef TYPERES
#define TYPERES float

template double FullMatrix<TYPEMAT>::residual(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const Vector<TYPERES>&) const;

// Experimental code

#ifdef HAVE_LIBLAPACK
extern "C" int dgels_ (const char* trans,
		       const unsigned int* M, const unsigned int* N,
		       const unsigned int* NRHS,
		       double* A, const unsigned int* LDA,
		       double* B, const unsigned int* LDB,
		       double* WORK, const unsigned int* LWORK,
		       int* INFO);
extern "C" int dgelss_ (const unsigned int* M, const unsigned int* N,
			const unsigned int* NRHS,
			double* A, const unsigned int* LDA,
			double* B, const unsigned int* LDB,
			double* S, const double* RCOND,
			int* RANK,
			double* WORK, const unsigned int* LWORK,
			int* INFO);

template<>
void
FullMatrix<double>::invert (const FullMatrix<double> &M)
{
  Assert (val != 0, ExcEmptyMatrix());

  Assert (dim_range == dim_image, ExcNotQuadratic());
  Assert (dim_range == M.dim_range,
          ExcDimensionMismatch(dim_range,M.dim_range));
  Assert (dim_image == M.dim_image,
	  ExcDimensionMismatch(dim_image,M.dim_image));

  clear();
  diagadd(1.);

  const unsigned int lwork = 10*dim_range*dim_range;
  double* work = new double[lwork];
  int info;

//  const char* trans = "N";
  int rank;
  const double rcond=-1.;
  double* s = new double[dim_range];

  double* matrix = new double[dim_range*dim_range];
  std::copy (&M.val[0], &M.val[dim_image*dim_range], matrix);

  int erg = dgelss_ (&dim_range, &dim_range, &dim_range,
		     matrix, &dim_range,
		     val, &dim_range,
		     s, &rcond, &rank,
		     work, &lwork,
		     &info);
//    int erg = dgels_ (trans, &dim_range, &dim_range, &dim_range,
//  		    M.val, &dim_range,
//  		    val, &dim_range,
//  		    work, &lwork,
//  		    &info);

//  double condition = s[0]/s[dim_range-1];

  if (info!=0)
    deallog << "inverting error " << info << ' ' << erg << std::endl;
  if (rank<(int)dim_range)
    deallog << "rank deficiency " << rank << std::endl;
  delete[] work;
  delete[] s;
  delete[] matrix;
}

#endif
<commit_msg>vector2d for LAPACK enhancement<commit_after>//----------------------------  full_matrix.double.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  full_matrix.double.cc  ---------------------------

#include <lac/full_matrix.templates.h>
#include <base/logstream.h>

#define TYPEMAT double

template class FullMatrix<TYPEMAT>;

#define TYPEMAT2 double

//template FullMatrix<TYPEMAT>& FullMatrix<TYPEMAT>::operator =(const FullMatrix<TYPEMAT2>&);
template void FullMatrix<TYPEMAT>::fill (const FullMatrix<TYPEMAT2>&, const unsigned, const unsigned);
template void FullMatrix<TYPEMAT>::add (const TYPEMAT, const FullMatrix<TYPEMAT2>&);
template void FullMatrix<TYPEMAT>::Tadd (const TYPEMAT, const FullMatrix<TYPEMAT2>&);
template void FullMatrix<TYPEMAT>::mmult (FullMatrix<TYPEMAT2>&, const FullMatrix<TYPEMAT2>&, const bool) const;
template void FullMatrix<TYPEMAT>::Tmmult (FullMatrix<TYPEMAT2>&, const FullMatrix<TYPEMAT2>&, const bool) const;
template void FullMatrix<TYPEMAT>::add_diag (const TYPEMAT, const FullMatrix<TYPEMAT2>&);

#define TYPEVEC double
#define TYPERES double

template void FullMatrix<TYPEMAT>::fill_permutation (const FullMatrix<TYPEVEC>&,
						     const std::vector<unsigned int>&,
						     const std::vector<unsigned int>&);
template void FullMatrix<TYPEMAT>::vmult(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const bool) const;
template void FullMatrix<TYPEMAT>::Tvmult(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const bool) const;
template double FullMatrix<TYPEMAT>::residual(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const Vector<TYPERES>&) const;
template TYPEVEC FullMatrix<TYPEMAT>::matrix_norm_square (const Vector<TYPEVEC> &) const;
template TYPEVEC FullMatrix<TYPEMAT>::matrix_scalar_product(const Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::forward(Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::backward(Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::householder(Vector<TYPEVEC>&);
template double FullMatrix<TYPEMAT>::least_squares(Vector<TYPEVEC>&, Vector<TYPEVEC>&);

#undef TYPEVEC
#define TYPEVEC float

template void FullMatrix<TYPEMAT>::fill_permutation (const FullMatrix<TYPEVEC>&,
						     const std::vector<unsigned int>&,
						     const std::vector<unsigned int>&);
template void FullMatrix<TYPEMAT>::vmult(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const bool) const;
template void FullMatrix<TYPEMAT>::Tvmult(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const bool) const;
template double FullMatrix<TYPEMAT>::residual(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const Vector<TYPERES>&) const;
template TYPEVEC FullMatrix<TYPEMAT>::matrix_norm_square (const Vector<TYPEVEC> &) const;
template TYPEVEC FullMatrix<TYPEMAT>::matrix_scalar_product(const Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::forward(Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::backward(Vector<TYPEVEC>&, const Vector<TYPEVEC>&) const;
template void FullMatrix<TYPEMAT>::householder(Vector<TYPEVEC>&);
template double FullMatrix<TYPEMAT>::least_squares(Vector<TYPEVEC>&, Vector<TYPEVEC>&);

#undef TYPERES
#define TYPERES float

template double FullMatrix<TYPEMAT>::residual(Vector<TYPEVEC>&, const Vector<TYPEVEC>&, const Vector<TYPERES>&) const;

// Experimental code

#ifdef HAVE_LIBLAPACK
extern "C" int dgels_ (const char* trans,
		       const unsigned int* M, const unsigned int* N,
		       const unsigned int* NRHS,
		       double* A, const unsigned int* LDA,
		       double* B, const unsigned int* LDB,
		       double* WORK, const unsigned int* LWORK,
		       int* INFO);
extern "C" int dgelss_ (const unsigned int* M, const unsigned int* N,
			const unsigned int* NRHS,
			double* A, const unsigned int* LDA,
			double* B, const unsigned int* LDB,
			double* S, const double* RCOND,
			int* RANK,
			double* WORK, const unsigned int* LWORK,
			int* INFO);

template<>
void
FullMatrix<double>::invert (const FullMatrix<double> &M)
{
  double* val = const_cast<double*> (data());

  Assert (val != 0, ExcEmptyMatrix());

  unsigned int dim_range = n_cols ();
  unsigned int dim_image = n_rows ();

  Assert (dim_range == dim_image, ExcNotQuadratic());
  Assert (dim_range == M.n_cols(),
          ExcDimensionMismatch(dim_range,M.n_cols()));
  Assert (dim_image == M.n_rows(),
	  ExcDimensionMismatch(dim_image,M.n_rows()));

  clear();
  diagadd(1.);

  const unsigned int lwork = 10*dim_range*dim_range;
  double* work = new double[lwork];
  int info;

//  const char* trans = "N";
  int rank;
  const double rcond=-1.;
  double* s = new double[dim_range];

  double* matrix = new double[dim_range*dim_range];
  std::copy (M.data(), M.data()+dim_image*dim_range, matrix);

  int erg = dgelss_ (&dim_range, &dim_range, &dim_range,
		     matrix, &dim_range,
		     val, &dim_range,
		     s, &rcond, &rank,
		     work, &lwork,
		     &info);
//    int erg = dgels_ (trans, &dim_range, &dim_range, &dim_range,
//  		    M.val, &dim_range,
//  		    val, &dim_range,
//  		    work, &lwork,
//  		    &info);

//  double condition = s[0]/s[dim_range-1];

  if (info!=0)
    deallog << "inverting error " << info << ' ' << erg << std::endl;
  if (rank<(int)dim_range)
    deallog << "rank deficiency " << rank << std::endl;
  delete[] work;
  delete[] s;
  delete[] matrix;
}

#endif
<|endoftext|>


<commit_before>#include <osgFX/Cartoon>
#include <osgFX/Registry>

#include <osg/PolygonOffset>
#include <osg/Texture1D>
#include <osg/VertexProgram>
#include <osg/PolygonMode>
#include <osg/CullFace>
#include <osg/Image>
#include <osg/TexEnv>
#include <osg/LineWidth>
#include <osg/Material>
#include <osg/Program>
#include <osg/Shader>

#include <sstream>

using namespace osgFX;

namespace
{

    osg::Image* create_sharp_lighting_map(int levels = 4, int texture_size = 16)
    {
        osg::ref_ptr<osg::Image> image = new osg::Image;
        image->setImage(texture_size, 1, 1, 4, GL_RGBA, GL_UNSIGNED_BYTE, new unsigned char[4*texture_size], osg::Image::USE_NEW_DELETE);
        for (int i=0; i<texture_size; ++i) {
            float c = i/static_cast<float>(texture_size);
            c = (1+static_cast<int>(sqrtf(c) * (levels))) / static_cast<float>(levels+1);
            *(image->data(i, 0)+0) = static_cast<unsigned char>(c*255);
            *(image->data(i, 0)+1) = static_cast<unsigned char>(c*255);
            *(image->data(i, 0)+2) = static_cast<unsigned char>(c*255);
            *(image->data(i, 0)+3) = 255;
        }
        return image.take();
    }

}

namespace
{

    // register a prototype for this effect
    Registry::Proxy proxy(new Cartoon);

    // default technique class
    class DefaultTechnique: public Technique {
    public:
        DefaultTechnique(osg::Material* wf_mat, osg::LineWidth *wf_lw, int lightnum)
            : Technique(), _wf_mat(wf_mat), _wf_lw(wf_lw), _lightnum(lightnum) {}

        void getRequiredExtensions(std::vector<std::string>& extensions) const
        {
            extensions.push_back("GL_ARB_vertex_program");
        }

    protected:

        void define_passes()
        {
            // implement pass #1 (solid surfaces)
            {
                std::ostringstream vp_oss;
                vp_oss <<
                    "!!ARBvp1.0\n"
                    "OPTION ARB_position_invariant;"
                    "PARAM c0 = { 0, 0, 0, 0 };"
                    "TEMP R0, R1;"
                    "ATTRIB v18 = vertex.normal;"
                    "PARAM s18 = state.light[" << _lightnum << "].position;"
                    "PARAM s16 = state.light[" << _lightnum << "].diffuse;"
                    "PARAM s1 = state.material.diffuse;"
                    "PARAM s631[4] = { state.matrix.modelview.invtrans };"
                    "MOV R0, s1;"
                    "MUL result.color.front.primary, R0, s16;"
                    "DP4 R0.x, s18, s18;"
                    "RSQ R0.x, R0.x;"
                    "MUL R1, R0.x, s18;"
                    "DP4 R0.x, s631[0], v18;"
                    "DP4 R0.y, s631[1], v18;"
                    "DP4 R0.z, s631[2], v18;"
                    "DP4 R0.w, s631[3], v18;"
                    "DP4 R0.x, R1, R0;"
                    "MAX result.texcoord[0].x, c0.x, R0.x;"
                    "END";

                osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;

                osg::ref_ptr<osg::PolygonOffset> polyoffset = new osg::PolygonOffset;
                polyoffset->setFactor(1.0f);
                polyoffset->setUnits(1.0f);
                ss->setAttributeAndModes(polyoffset.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                osg::ref_ptr<osg::VertexProgram> vp = new osg::VertexProgram;
                vp->setVertexProgram(vp_oss.str());
                ss->setAttributeAndModes(vp.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                ss->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);

                osg::ref_ptr<osg::Texture1D> texture = new osg::Texture1D;
                texture->setImage(create_sharp_lighting_map());
                texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
                texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
                ss->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
                texenv->setMode(osg::TexEnv::MODULATE);
                ss->setTextureAttributeAndModes(0, texenv.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                addPass(ss.get());
            }

            // implement pass #2 (outlines)
            {
                osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
                osg::ref_ptr<osg::PolygonMode> polymode = new osg::PolygonMode;
                polymode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
                ss->setAttributeAndModes(polymode.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                osg::ref_ptr<osg::CullFace> cf = new osg::CullFace;
                cf->setMode(osg::CullFace::FRONT);
                ss->setAttributeAndModes(cf.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                _wf_lw->setWidth(2);
                ss->setAttributeAndModes(_wf_lw.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                _wf_mat->setColorMode(osg::Material::OFF);
                _wf_mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                _wf_mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                _wf_mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                _wf_mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                ss->setAttributeAndModes(_wf_mat.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                ss->setMode(GL_LIGHTING, osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
                ss->setTextureMode(0, GL_TEXTURE_1D, osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
                ss->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);

                   addPass(ss.get());

            }
        }

    private:
        osg::ref_ptr<osg::Material> _wf_mat;
        osg::ref_ptr<osg::LineWidth> _wf_lw;
        int _lightnum;
    };

}

///////////////////////////////////////////////////////////////////////////
// A port of Marco Jez's "cartoon.cg" to the OpenGL Shading Language
// by Mike Weiblen 2003-10-03,
//
// This shader is simplified due to limitations in the OGLSL implementation
// in the current 3Dlabs driver.  As the OGLSL implementation improves,
// need to revisit and enhance this shader.
namespace
{
    class OGLSL_Technique : public Technique {
    public:
        OGLSL_Technique(osg::Material* wf_mat, osg::LineWidth *wf_lw, int lightnum)
            : Technique(), _wf_mat(wf_mat), _wf_lw(wf_lw), _lightnum(lightnum) {}

        void getRequiredExtensions(std::vector<std::string>& extensions) const
        {
            extensions.push_back( "GL_ARB_shader_objects" );
            extensions.push_back( "GL_ARB_vertex_shader" );
            extensions.push_back( "GL_ARB_fragment_shader" );
        }

    protected:

        void define_passes()
        {
            // implement pass #1 (solid surfaces)
            {
                const char * vert_source =
                "const vec3 LightPosition = vec3( 0.0, 2.0, 4.0 );"
                "varying float CartoonTexCoord;"
                "void main( void )"
                "{"
                    "vec3 eye_space_normal = normalize(gl_NormalMatrix * gl_Normal);"
                    "CartoonTexCoord = max(0.0, dot(normalize(LightPosition), eye_space_normal));"
                    "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
                "}";

                const char * frag_source =
                "uniform sampler1D CartoonTexUnit;"
                "varying float CartoonTexCoord;"
                "void main( void )"
                "{"
                    "gl_FragColor = texture1D( CartoonTexUnit, CartoonTexCoord );"
                "}";

                osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;

                osg::ref_ptr<osg::PolygonOffset> polyoffset = new osg::PolygonOffset;
                polyoffset->setFactor(1.0f);
                polyoffset->setUnits(1.0f);
                ss->setAttributeAndModes(polyoffset.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                osg::ref_ptr<osg::Program> program = new osg::Program;
                program->addShader( new osg::Shader( osg::Shader::VERTEX, vert_source ) );
                program->addShader( new osg::Shader( osg::Shader::FRAGMENT, frag_source ) );

                ss->addUniform( new osg::Uniform("CartoonTexUnit", 0));
                ss->setAttributeAndModes( program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                ss->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);

                osg::ref_ptr<osg::Texture1D> texture = new osg::Texture1D;
                texture->setImage(create_sharp_lighting_map());
                texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
                texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
                ss->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
                texenv->setMode(osg::TexEnv::MODULATE);
                ss->setTextureAttributeAndModes(0, texenv.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                addPass(ss.get());
            }

            // implement pass #2 (outlines)
            {
                osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
                osg::ref_ptr<osg::PolygonMode> polymode = new osg::PolygonMode;
                polymode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
                ss->setAttributeAndModes(polymode.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                osg::ref_ptr<osg::CullFace> cf = new osg::CullFace;
                cf->setMode(osg::CullFace::FRONT);
                ss->setAttributeAndModes(cf.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                _wf_lw->setWidth(2);
                ss->setAttributeAndModes(_wf_lw.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                _wf_mat->setColorMode(osg::Material::OFF);
                _wf_mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                _wf_mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                _wf_mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                _wf_mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                ss->setAttributeAndModes(_wf_mat.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                ss->setMode(GL_LIGHTING, osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
                ss->setTextureMode(0, GL_TEXTURE_1D, osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
                ss->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);

                   addPass(ss.get());

            }
        }

    private:
        osg::ref_ptr<osg::Material> _wf_mat;
        osg::ref_ptr<osg::LineWidth> _wf_lw;
        int _lightnum;
    };

}

///////////////////////////////////////////////////////////////////////////

Cartoon::Cartoon()
:    Effect(),
    _wf_mat(new osg::Material),
    _wf_lw(new osg::LineWidth),
    _lightnum(0)
{
}

Cartoon::Cartoon(const Cartoon& copy, const osg::CopyOp& copyop)
:    Effect(copy, copyop),
    _wf_mat(static_cast<osg::Material* >(copyop(copy._wf_mat.get()))),
    _wf_lw(static_cast<osg::LineWidth *>(copyop(copy._wf_lw.get()))),
    _lightnum(copy._lightnum)
{
}

bool Cartoon::define_techniques()
{
    addTechnique(new DefaultTechnique(_wf_mat.get(), _wf_lw.get(), _lightnum));
    addTechnique(new OGLSL_Technique(_wf_mat.get(), _wf_lw.get(), _lightnum));
    return true;
}
<commit_msg>From Thom Carlo, with tweak from Robert Osfield, removed the setting of the outline colour (the emission part of material) during setup of the Carton effects for the second pass.<commit_after>#include <osgFX/Cartoon>
#include <osgFX/Registry>

#include <osg/PolygonOffset>
#include <osg/Texture1D>
#include <osg/VertexProgram>
#include <osg/PolygonMode>
#include <osg/CullFace>
#include <osg/Image>
#include <osg/TexEnv>
#include <osg/LineWidth>
#include <osg/Material>
#include <osg/Program>
#include <osg/Shader>

#include <sstream>

using namespace osgFX;

namespace
{

    osg::Image* create_sharp_lighting_map(int levels = 4, int texture_size = 16)
    {
        osg::ref_ptr<osg::Image> image = new osg::Image;
        image->setImage(texture_size, 1, 1, 4, GL_RGBA, GL_UNSIGNED_BYTE, new unsigned char[4*texture_size], osg::Image::USE_NEW_DELETE);
        for (int i=0; i<texture_size; ++i) {
            float c = i/static_cast<float>(texture_size);
            c = (1+static_cast<int>(sqrtf(c) * (levels))) / static_cast<float>(levels+1);
            *(image->data(i, 0)+0) = static_cast<unsigned char>(c*255);
            *(image->data(i, 0)+1) = static_cast<unsigned char>(c*255);
            *(image->data(i, 0)+2) = static_cast<unsigned char>(c*255);
            *(image->data(i, 0)+3) = 255;
        }
        return image.take();
    }

}

namespace
{

    // register a prototype for this effect
    Registry::Proxy proxy(new Cartoon);

    // default technique class
    class DefaultTechnique: public Technique {
    public:
        DefaultTechnique(osg::Material* wf_mat, osg::LineWidth *wf_lw, int lightnum)
            : Technique(), _wf_mat(wf_mat), _wf_lw(wf_lw), _lightnum(lightnum) {}

        void getRequiredExtensions(std::vector<std::string>& extensions) const
        {
            extensions.push_back("GL_ARB_vertex_program");
        }

    protected:

        void define_passes()
        {
            // implement pass #1 (solid surfaces)
            {
                std::ostringstream vp_oss;
                vp_oss <<
                    "!!ARBvp1.0\n"
                    "OPTION ARB_position_invariant;"
                    "PARAM c0 = { 0, 0, 0, 0 };"
                    "TEMP R0, R1;"
                    "ATTRIB v18 = vertex.normal;"
                    "PARAM s18 = state.light[" << _lightnum << "].position;"
                    "PARAM s16 = state.light[" << _lightnum << "].diffuse;"
                    "PARAM s1 = state.material.diffuse;"
                    "PARAM s631[4] = { state.matrix.modelview.invtrans };"
                    "MOV R0, s1;"
                    "MUL result.color.front.primary, R0, s16;"
                    "DP4 R0.x, s18, s18;"
                    "RSQ R0.x, R0.x;"
                    "MUL R1, R0.x, s18;"
                    "DP4 R0.x, s631[0], v18;"
                    "DP4 R0.y, s631[1], v18;"
                    "DP4 R0.z, s631[2], v18;"
                    "DP4 R0.w, s631[3], v18;"
                    "DP4 R0.x, R1, R0;"
                    "MAX result.texcoord[0].x, c0.x, R0.x;"
                    "END";

                osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;

                osg::ref_ptr<osg::PolygonOffset> polyoffset = new osg::PolygonOffset;
                polyoffset->setFactor(1.0f);
                polyoffset->setUnits(1.0f);
                ss->setAttributeAndModes(polyoffset.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                osg::ref_ptr<osg::VertexProgram> vp = new osg::VertexProgram;
                vp->setVertexProgram(vp_oss.str());
                ss->setAttributeAndModes(vp.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                ss->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);

                osg::ref_ptr<osg::Texture1D> texture = new osg::Texture1D;
                texture->setImage(create_sharp_lighting_map());
                texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
                texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
                ss->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
                texenv->setMode(osg::TexEnv::MODULATE);
                ss->setTextureAttributeAndModes(0, texenv.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                addPass(ss.get());
            }

            // implement pass #2 (outlines)
            {
                osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
                osg::ref_ptr<osg::PolygonMode> polymode = new osg::PolygonMode;
                polymode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
                ss->setAttributeAndModes(polymode.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                osg::ref_ptr<osg::CullFace> cf = new osg::CullFace;
                cf->setMode(osg::CullFace::FRONT);
                ss->setAttributeAndModes(cf.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                _wf_lw->setWidth(2);
                ss->setAttributeAndModes(_wf_lw.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                _wf_mat->setColorMode(osg::Material::OFF);
                _wf_mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                _wf_mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                _wf_mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));

                // set by outline colour so no need to set here.
                //_wf_mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));

                ss->setAttributeAndModes(_wf_mat.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                ss->setMode(GL_LIGHTING, osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
                ss->setTextureMode(0, GL_TEXTURE_1D, osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
                ss->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);

                addPass(ss.get());

            }
        }

    private:
        osg::ref_ptr<osg::Material> _wf_mat;
        osg::ref_ptr<osg::LineWidth> _wf_lw;
        int _lightnum;
    };

}

///////////////////////////////////////////////////////////////////////////
// A port of Marco Jez's "cartoon.cg" to the OpenGL Shading Language
// by Mike Weiblen 2003-10-03,
//
// This shader is simplified due to limitations in the OGLSL implementation
// in the current 3Dlabs driver.  As the OGLSL implementation improves,
// need to revisit and enhance this shader.
namespace
{
    class OGLSL_Technique : public Technique {
    public:
        OGLSL_Technique(osg::Material* wf_mat, osg::LineWidth *wf_lw, int lightnum)
            : Technique(), _wf_mat(wf_mat), _wf_lw(wf_lw), _lightnum(lightnum) {}

        void getRequiredExtensions(std::vector<std::string>& extensions) const
        {
            extensions.push_back( "GL_ARB_shader_objects" );
            extensions.push_back( "GL_ARB_vertex_shader" );
            extensions.push_back( "GL_ARB_fragment_shader" );
        }

    protected:

        void define_passes()
        {
            // implement pass #1 (solid surfaces)
            {
                const char * vert_source =
                "const vec3 LightPosition = vec3( 0.0, 2.0, 4.0 );"
                "varying float CartoonTexCoord;"
                "void main( void )"
                "{"
                    "vec3 eye_space_normal = normalize(gl_NormalMatrix * gl_Normal);"
                    "CartoonTexCoord = max(0.0, dot(normalize(LightPosition), eye_space_normal));"
                    "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
                "}";

                const char * frag_source =
                "uniform sampler1D CartoonTexUnit;"
                "varying float CartoonTexCoord;"
                "void main( void )"
                "{"
                    "gl_FragColor = texture1D( CartoonTexUnit, CartoonTexCoord );"
                "}";

                osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;

                osg::ref_ptr<osg::PolygonOffset> polyoffset = new osg::PolygonOffset;
                polyoffset->setFactor(1.0f);
                polyoffset->setUnits(1.0f);
                ss->setAttributeAndModes(polyoffset.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                osg::ref_ptr<osg::Program> program = new osg::Program;
                program->addShader( new osg::Shader( osg::Shader::VERTEX, vert_source ) );
                program->addShader( new osg::Shader( osg::Shader::FRAGMENT, frag_source ) );

                ss->addUniform( new osg::Uniform("CartoonTexUnit", 0));
                ss->setAttributeAndModes( program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                ss->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);

                osg::ref_ptr<osg::Texture1D> texture = new osg::Texture1D;
                texture->setImage(create_sharp_lighting_map());
                texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
                texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
                ss->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
                texenv->setMode(osg::TexEnv::MODULATE);
                ss->setTextureAttributeAndModes(0, texenv.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                addPass(ss.get());
            }

            // implement pass #2 (outlines)
            {
                osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
                osg::ref_ptr<osg::PolygonMode> polymode = new osg::PolygonMode;
                polymode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
                ss->setAttributeAndModes(polymode.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                osg::ref_ptr<osg::CullFace> cf = new osg::CullFace;
                cf->setMode(osg::CullFace::FRONT);
                ss->setAttributeAndModes(cf.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                _wf_lw->setWidth(2);
                ss->setAttributeAndModes(_wf_lw.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                _wf_mat->setColorMode(osg::Material::OFF);
                _wf_mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                _wf_mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
                _wf_mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));

                // set by outline colour so no need to set here.
                //_wf_mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));

                ss->setAttributeAndModes(_wf_mat.get(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

                ss->setMode(GL_LIGHTING, osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
                ss->setTextureMode(0, GL_TEXTURE_1D, osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
                ss->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);

                addPass(ss.get());

            }
        }

    private:
        osg::ref_ptr<osg::Material> _wf_mat;
        osg::ref_ptr<osg::LineWidth> _wf_lw;
        int _lightnum;
    };

}

///////////////////////////////////////////////////////////////////////////

Cartoon::Cartoon()
:    Effect(),
    _wf_mat(new osg::Material),
    _wf_lw(new osg::LineWidth),
    _lightnum(0)
{
    setOutlineColor(osg::Vec4(0, 0, 0, 1));
}

Cartoon::Cartoon(const Cartoon& copy, const osg::CopyOp& copyop)
:    Effect(copy, copyop),
    _wf_mat(static_cast<osg::Material* >(copyop(copy._wf_mat.get()))),
    _wf_lw(static_cast<osg::LineWidth *>(copyop(copy._wf_lw.get()))),
    _lightnum(copy._lightnum)
{
}

bool Cartoon::define_techniques()
{
    addTechnique(new DefaultTechnique(_wf_mat.get(), _wf_lw.get(), _lightnum));
    addTechnique(new OGLSL_Technique(_wf_mat.get(), _wf_lw.get(), _lightnum));
    return true;
}
<|endoftext|>


<commit_before>/**
 * A set of network utility functions.
 *
 * @date                    December 13, 2014
 * @author                  Joeri HERMANS
 * @version                 0.1
 *
 * Copyright 2014 Joeri HERMANS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// BEGIN Includes. ///////////////////////////////////////////////////

// System dependencies.
#include <cassert>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <iostream>
#include <poll.h>
#include <netdb.h>
#include <errno.h>

// System dependencies.
#include <ias/network/util.h>
#include <ias/network/proxy/socks.h>

// END Includes. /////////////////////////////////////////////////////

int connect( const std::string & address, const std::size_t port ) {
    struct addrinfo hints;
    struct addrinfo * results;
    std::string portString;
    int result;
    int fd;

    // Checking the precondition.
    assert( !address.empty() && port > 0 );

    result = -1;
    memset(&hints,0,sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    portString = std::to_string(port);
    getaddrinfo(address.c_str(),portString.c_str(),&hints,&results);
    if( results != nullptr ) {
        fd = socket(results->ai_family,results->ai_socktype,results->ai_protocol);
        if( fd >= 0 ) {
            if( connect(fd,results->ai_addr,results->ai_addrlen) == 0 )
                result = fd;
            else
                close(fd);
        }
        freeaddrinfo(results);
    }

    return ( result );
}

bool enableKeepAlive( const int fd ) {
    static const int optval = 1;
    bool s;

    // Checking the precondition.
    assert( fd >= 0 );

    s = (setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,&optval,sizeof optval) >= 0);

    return ( s );
}

bool disableNagle( const int fd ) {
    static const int optval = 1;
    bool s;

    // Checking the precondition.
    assert( fd >= 0 );

    s = (setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,&optval,sizeof optval) >= 0);

    return (s);
}

int connectToSocks( const std::string & proxyAddress,
                    const std::size_t proxyPort,
                    const std::string & address,
                    const std::size_t port ) {
    int fd;

    // Checking the precondition.
    assert( !proxyAddress.empty() && proxyPort > 0 &&
            !address.empty() && port > 0 );

    fd = -1;
    if( !proxyAddress.empty() && proxyPort > 0 ) {
        fd = connect(proxyAddress,proxyPort);
        if( fd >= 0 && !socksConnect(address,port,fd) ) {
            close(fd);
            fd = -1;
        }
    }

    return ( fd );
}
<commit_msg>Fix segmentation fault because of freeaddrinfo when no internet connection is available.<commit_after>/**
 * A set of network utility functions.
 *
 * @date                    December 13, 2014
 * @author                  Joeri HERMANS
 * @version                 0.1
 *
 * Copyright 2014 Joeri HERMANS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// BEGIN Includes. ///////////////////////////////////////////////////

// System dependencies.
#include <cassert>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <iostream>
#include <poll.h>
#include <netdb.h>
#include <errno.h>
#include <iostream>

// System dependencies.
#include <ias/network/util.h>
#include <ias/network/proxy/socks.h>

// END Includes. /////////////////////////////////////////////////////

int connect( const std::string & address, const std::size_t port ) {
    struct addrinfo hints;
    struct addrinfo * results;
    std::string portString;
    int result;
    int fd;

    // Checking the precondition.
    assert( !address.empty() && port > 0 );

    result = -1;
    memset(&hints,0,sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    portString = std::to_string(port);
    int rc = getaddrinfo(address.c_str(),portString.c_str(),&hints,&results);
    if( results != nullptr && rc >= 0 ) {
        fd = socket(results->ai_family,results->ai_socktype,results->ai_protocol);
        if( fd >= 0 ) {
            if( connect(fd,results->ai_addr,results->ai_addrlen) == 0 )
                result = fd;
            else
                close(fd);
        }
        freeaddrinfo(results);
    }

    return ( result );
}

bool enableKeepAlive( const int fd ) {
    static const int optval = 1;
    bool s;

    // Checking the precondition.
    assert( fd >= 0 );

    s = (setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,&optval,sizeof optval) >= 0);

    return ( s );
}

bool disableNagle( const int fd ) {
    static const int optval = 1;
    bool s;

    // Checking the precondition.
    assert( fd >= 0 );

    s = (setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,&optval,sizeof optval) >= 0);

    return (s);
}

int connectToSocks( const std::string & proxyAddress,
                    const std::size_t proxyPort,
                    const std::string & address,
                    const std::size_t port ) {
    int fd;

    // Checking the precondition.
    assert( !proxyAddress.empty() && proxyPort > 0 &&
            !address.empty() && port > 0 );

    fd = -1;
    if( !proxyAddress.empty() && proxyPort > 0 ) {
        fd = connect(proxyAddress,proxyPort);
        if( fd >= 0 && !socksConnect(address,port,fd) ) {
            close(fd);
            fd = -1;
        }
    }

    return ( fd );
}
<|endoftext|>


<commit_before>RowVector5i v = RowVector5i::Random();
cout << "Here is the vector v:" << endl << v << endl;
cout << "Here is v.block<2>(1):" << endl << v.start<2>() << endl;
v.block<2>(2).setZero();
cout << "Now the vector v is:" << endl << v << endl;
<commit_msg>fix doc compilation<commit_after>RowVector4i v = RowVector4i::Random();
cout << "Here is the vector v:" << endl << v << endl;
cout << "Here is v.block<2>(1):" << endl << v.block<2>(1) << endl;
v.block<2>(2).setZero();
cout << "Now the vector v is:" << endl << v << endl;
<|endoftext|>


<commit_before>#include "output-impl.hpp"
#include "wayfire/view.hpp"
#include "../core/core-impl.hpp"
#include "wayfire/signal-definitions.hpp"
#include "wayfire/render-manager.hpp"
#include "wayfire/output-layout.hpp"
#include "wayfire/workspace-manager.hpp"
#include "wayfire/compositor-view.hpp"
#include "wayfire-shell.hpp"
#include "../core/seat/input-manager.hpp"
#include "../view/xdg-shell.hpp"
#include <wayfire/util/log.hpp>
#include <wayfire/nonstd/wlroots-full.hpp>

#include <algorithm>
#include <assert.h>

wf::output_t::output_t() = default;

wf::output_impl_t::output_impl_t(wlr_output *handle,
    const wf::dimensions_t& effective_size)
{
    this->set_effective_size(effective_size);
    this->handle = handle;
    workspace    = std::make_unique<workspace_manager>(this);
    render = std::make_unique<render_manager>(this);

    view_disappeared_cb = [=] (wf::signal_data_t *data)
    {
        output_t::refocus(get_signaled_view(data));
    };

    connect_signal("view-disappeared", &view_disappeared_cb);
}

void wf::output_impl_t::start_plugins()
{
    plugin = std::make_unique<plugin_manager>(this);
}

std::string wf::output_t::to_string() const
{
    return handle->name;
}

void wf::output_impl_t::refocus(wayfire_view skip_view, uint32_t layers)
{
    wayfire_view next_focus = nullptr;
    auto views = workspace->get_views_on_workspace(
        workspace->get_current_workspace(), layers);

    for (auto v : views)
    {
        if ((v != skip_view) && v->is_mapped() &&
            v->get_keyboard_focus_surface() &&
            !v->minimized)
        {
            next_focus = v;
            break;
        }
    }

    focus_view(next_focus, 0u);
}

void wf::output_t::refocus(wayfire_view skip_view)
{
    uint32_t focused_layer = wf::get_core().get_focused_layer();
    uint32_t layers = focused_layer <=
        LAYER_WORKSPACE ? MIDDLE_LAYERS : focused_layer;

    auto views = workspace->get_views_on_workspace(
        workspace->get_current_workspace(), layers);

    if (views.empty())
    {
        if (wf::get_core().get_active_output() == this)
        {
            LOGD("warning: no focused views in the focused layer, probably a bug");
        }

        /* Usually, we focus a layer so that a particular view has focus, i.e
         * we expect that there is a view in the focused layer. However we
         * should try to find reasonable focus in any focuseable layers if
         * that is not the case, for ex. if there is a focused layer by a
         * layer surface on another output */
        layers = all_layers_not_below(focused_layer);
    }

    refocus(skip_view, layers);
}

wf::output_t::~output_t()
{
    wf::get_core_impl().input->free_output_bindings(this);
}

wf::output_impl_t::~output_impl_t()
{}

void wf::output_impl_t::set_effective_size(const wf::dimensions_t& size)
{
    this->effective_size = size;
}

wf::dimensions_t wf::output_impl_t::get_screen_size() const
{
    return this->effective_size;
}

wf::geometry_t wf::output_t::get_relative_geometry() const
{
    auto size = get_screen_size();

    return {
        0, 0, size.width, size.height
    };
}

wf::geometry_t wf::output_t::get_layout_geometry() const
{
    auto box = wlr_output_layout_get_box(
        wf::get_core().output_layout->get_handle(), handle);
    if (box)
    {
        return *box;
    } else
    {
        LOGE("Get layout geometry for an invalid output!");

        return {0, 0, 1, 1};
    }
}

void wf::output_t::ensure_pointer(bool center) const
{
    auto ptr = wf::get_core().get_cursor_position();
    if (!center &&
        (get_layout_geometry() & wf::point_t{(int)ptr.x, (int)ptr.y}))
    {
        return;
    }

    auto lg = get_layout_geometry();
    wf::pointf_t target = {
        lg.x + lg.width / 2.0,
        lg.y + lg.height / 2.0,
    };
    wf::get_core().warp_cursor(target);
    wf::get_core().set_cursor("default");
}

wf::pointf_t wf::output_t::get_cursor_position() const
{
    auto og = get_layout_geometry();
    auto gc = wf::get_core().get_cursor_position();

    return {gc.x - og.x, gc.y - og.y};
}

bool wf::output_t::ensure_visible(wayfire_view v)
{
    auto bbox = v->get_bounding_box();
    auto g    = this->get_relative_geometry();

    /* Compute the percentage of the view which is visible */
    auto intersection = wf::geometry_intersection(bbox, g);
    double area = 1.0 * intersection.width * intersection.height;
    area /= 1.0 * bbox.width * bbox.height;

    if (area >= 0.1) /* View is somewhat visible, no need for anything special */
    {
        return false;
    }

    /* Otherwise, switch the workspace so the view gets maximum exposure */
    int dx = bbox.x + bbox.width / 2;
    int dy = bbox.y + bbox.height / 2;

    int dvx  = std::floor(1.0 * dx / g.width);
    int dvy  = std::floor(1.0 * dy / g.height);
    auto cws = workspace->get_current_workspace();
    workspace->request_workspace(cws + wf::point_t{dvx, dvy});

    return true;
}

void wf::output_impl_t::close_popups()
{
    for (auto& v : workspace->get_views_in_layer(wf::ALL_LAYERS))
    {
        auto popup = dynamic_cast<wayfire_xdg_popup*>(v.get());
        if (!popup || (popup->popup_parent == active_view.get()))
        {
            continue;
        }

        /* Ignore popups which have a popup as their parent. In those cases, we'll
         * close the topmost popup and this will recursively destroy the others.
         *
         * Otherwise we get a race condition with wlroots. */
        if (dynamic_cast<wayfire_xdg_popup*>(popup->popup_parent))
        {
            continue;
        }

        popup->close();
    }
}

void wf::output_impl_t::update_active_view(wayfire_view v, uint32_t flags)
{
    this->active_view = v;
    if (this == wf::get_core().get_active_output())
    {
        wf::get_core().set_active_view(v);
    }

    if (flags & FOCUS_VIEW_CLOSE_POPUPS)
    {
        close_popups();
    }
}

void wf::output_impl_t::focus_view(wayfire_view v, uint32_t flags)
{
    const auto& make_view_visible = [this, flags] (wayfire_view view)
    {
        if (view->minimized)
        {
            view->minimize_request(false);
        }

        if (flags & FOCUS_VIEW_RAISE)
        {
            workspace->bring_to_front(view);
        }
    };

    if (v && (workspace->get_view_layer(v) < wf::get_core().get_focused_layer()))
    {
        auto active_view = get_active_view();
        if (active_view && (active_view->get_app_id().find("$unfocus") == 0))
        {
            /* This is the case where for ex. a panel has grabbed input focus,
             * but user has clicked on another view so we want to dismiss the
             * grab. We can't do that straight away because the client still
             * holds the focus layer request.
             *
             * Instead, we want to deactive the $unfocus view, so that it can
             * release the grab. At the same time, we bring the to-be-focused
             * view on top, so that it gets the focus next. */
            update_active_view(nullptr, flags);
            make_view_visible(v);
        } else
        {
            LOGD("Denying focus request for a view from a lower layer than the"
                 " focused layer");
        }

        return;
    }

    if (!v || !v->is_mapped())
    {
        update_active_view(nullptr, flags);

        return;
    }

    while (v->parent && v->parent->is_mapped())
    {
        v = v->parent;
    }

    /* If no keyboard focus surface is set, then we don't want to focus the view */
    if (v->get_keyboard_focus_surface() || interactive_view_from_view(v.get()))
    {
        make_view_visible(v);
        update_active_view(v, flags);

        focus_view_signal data;
        data.view = v;
        emit_signal("view-focused", &data);
    }
}

void wf::output_impl_t::focus_view(wayfire_view v, bool raise)
{
    uint32_t flags = FOCUS_VIEW_CLOSE_POPUPS;
    if (raise)
    {
        flags |= FOCUS_VIEW_RAISE;
    }

    focus_view(v, flags);
}

wayfire_view wf::output_t::get_top_view() const
{
    auto views = workspace->get_views_on_workspace(
        workspace->get_current_workspace(),
        LAYER_WORKSPACE);

    return views.empty() ? nullptr : views[0];
}

wayfire_view wf::output_impl_t::get_active_view() const
{
    return active_view;
}

bool wf::output_impl_t::can_activate_plugin(uint32_t caps,
    uint32_t flags)
{
    if (this->inhibited && !(flags & wf::PLUGIN_ACTIVATION_IGNORE_INHIBIT))
    {
        return false;
    }

    for (auto act_owner : active_plugins)
    {
        bool compatible = ((act_owner->capabilities & caps) == 0);
        if (!compatible)
        {
            return false;
        }
    }

    return true;
}

bool wf::output_impl_t::can_activate_plugin(const plugin_grab_interface_uptr& owner,
    uint32_t flags)
{
    if (!owner)
    {
        return false;
    }

    if (active_plugins.find(owner.get()) != active_plugins.end())
    {
        return flags & wf::PLUGIN_ACTIVATE_ALLOW_MULTIPLE;
    }

    return can_activate_plugin(owner->capabilities, flags);
}

bool wf::output_impl_t::activate_plugin(const plugin_grab_interface_uptr& owner,
    uint32_t flags)
{
    if (!can_activate_plugin(owner, flags))
    {
        return false;
    }

    if (active_plugins.find(owner.get()) != active_plugins.end())
    {
        LOGD("output ", handle->name,
            ": activate plugin ", owner->name, " again");
    } else
    {
        LOGD("output ", handle->name, ": activate plugin ", owner->name);
    }

    active_plugins.insert(owner.get());

    return true;
}

bool wf::output_impl_t::deactivate_plugin(
    const plugin_grab_interface_uptr& owner)
{
    auto it = active_plugins.find(owner.get());
    if (it == active_plugins.end())
    {
        return true;
    }

    active_plugins.erase(it);
    LOGD("output ", handle->name, ": deactivate plugin ", owner->name);

    if (active_plugins.count(owner.get()) == 0)
    {
        owner->ungrab();
        active_plugins.erase(owner.get());

        return true;
    }

    return false;
}

void wf::output_impl_t::cancel_active_plugins()
{
    std::vector<wf::plugin_grab_interface_t*> ifaces;
    for (auto p : active_plugins)
    {
        if (p->callbacks.cancel)
        {
            ifaces.push_back(p);
        }
    }

    for (auto p : ifaces)
    {
        p->callbacks.cancel();
    }
}

bool wf::output_impl_t::is_plugin_active(std::string name) const
{
    for (auto act : active_plugins)
    {
        if (act && (act->name == name))
        {
            return true;
        }
    }

    return false;
}

wf::plugin_grab_interface_t*wf::output_impl_t::get_input_grab_interface()
{
    for (auto p : active_plugins)
    {
        if (p && p->is_grabbed())
        {
            return p;
        }
    }

    return nullptr;
}

void wf::output_impl_t::inhibit_plugins()
{
    this->inhibited = true;
    cancel_active_plugins();
}

void wf::output_impl_t::uninhibit_plugins()
{
    this->inhibited = false;
}

bool wf::output_impl_t::is_inhibited() const
{
    return this->inhibited;
}

/* simple wrappers for wf::get_core_impl().input, as it isn't exposed to plugins */
wf::binding_t*wf::output_t::add_key(option_sptr_t<keybinding_t> key,
    wf::key_callback *callback)
{
    return wf::get_core_impl().input->new_binding(WF_BINDING_KEY, key, this,
        callback);
}

wf::binding_t*wf::output_t::add_axis(option_sptr_t<keybinding_t> axis,
    wf::axis_callback *callback)
{
    return wf::get_core_impl().input->new_binding(WF_BINDING_AXIS, axis, this,
        callback);
}

wf::binding_t*wf::output_t::add_button(option_sptr_t<buttonbinding_t> button,
    wf::button_callback *callback)
{
    return wf::get_core_impl().input->new_binding(WF_BINDING_BUTTON, button,
        this, callback);
}

wf::binding_t*wf::output_t::add_gesture(option_sptr_t<touchgesture_t> gesture,
    wf::gesture_callback *callback)
{
    return wf::get_core_impl().input->new_binding(WF_BINDING_GESTURE, gesture,
        this, callback);
}

wf::binding_t*wf::output_t::add_activator(
    option_sptr_t<activatorbinding_t> activator, wf::activator_callback *callback)
{
    return wf::get_core_impl().input->new_binding(WF_BINDING_ACTIVATOR, activator,
        this, callback);
}

void wf::output_t::rem_binding(wf::binding_t *binding)
{
    wf::get_core_impl().input->rem_binding(binding);
}

void wf::output_t::rem_binding(void *callback)
{
    wf::get_core_impl().input->rem_binding(callback);
}

namespace wf
{
uint32_t all_layers_not_below(uint32_t layer)
{
    uint32_t mask = 0;
    for (int i = 0; i < wf::TOTAL_LAYERS; i++)
    {
        if ((1u << i) >= layer)
        {
            mask |= (1 << i);
        }
    }

    return mask;
}
}
<commit_msg>Emit focus-view signal when focus is lost<commit_after>#include "output-impl.hpp"
#include "wayfire/view.hpp"
#include "../core/core-impl.hpp"
#include "wayfire/signal-definitions.hpp"
#include "wayfire/render-manager.hpp"
#include "wayfire/output-layout.hpp"
#include "wayfire/workspace-manager.hpp"
#include "wayfire/compositor-view.hpp"
#include "wayfire-shell.hpp"
#include "../core/seat/input-manager.hpp"
#include "../view/xdg-shell.hpp"
#include <wayfire/util/log.hpp>
#include <wayfire/nonstd/wlroots-full.hpp>

#include <algorithm>
#include <assert.h>

wf::output_t::output_t() = default;

wf::output_impl_t::output_impl_t(wlr_output *handle,
    const wf::dimensions_t& effective_size)
{
    this->set_effective_size(effective_size);
    this->handle = handle;
    workspace    = std::make_unique<workspace_manager>(this);
    render = std::make_unique<render_manager>(this);

    view_disappeared_cb = [=] (wf::signal_data_t *data)
    {
        output_t::refocus(get_signaled_view(data));
    };

    connect_signal("view-disappeared", &view_disappeared_cb);
}

void wf::output_impl_t::start_plugins()
{
    plugin = std::make_unique<plugin_manager>(this);
}

std::string wf::output_t::to_string() const
{
    return handle->name;
}

void wf::output_impl_t::refocus(wayfire_view skip_view, uint32_t layers)
{
    wayfire_view next_focus = nullptr;
    auto views = workspace->get_views_on_workspace(
        workspace->get_current_workspace(), layers);

    for (auto v : views)
    {
        if ((v != skip_view) && v->is_mapped() &&
            v->get_keyboard_focus_surface() &&
            !v->minimized)
        {
            next_focus = v;
            break;
        }
    }

    focus_view(next_focus, 0u);
}

void wf::output_t::refocus(wayfire_view skip_view)
{
    uint32_t focused_layer = wf::get_core().get_focused_layer();
    uint32_t layers = focused_layer <=
        LAYER_WORKSPACE ? MIDDLE_LAYERS : focused_layer;

    auto views = workspace->get_views_on_workspace(
        workspace->get_current_workspace(), layers);

    if (views.empty())
    {
        if (wf::get_core().get_active_output() == this)
        {
            LOGD("warning: no focused views in the focused layer, probably a bug");
        }

        /* Usually, we focus a layer so that a particular view has focus, i.e
         * we expect that there is a view in the focused layer. However we
         * should try to find reasonable focus in any focuseable layers if
         * that is not the case, for ex. if there is a focused layer by a
         * layer surface on another output */
        layers = all_layers_not_below(focused_layer);
    }

    refocus(skip_view, layers);
}

wf::output_t::~output_t()
{
    wf::get_core_impl().input->free_output_bindings(this);
}

wf::output_impl_t::~output_impl_t()
{}

void wf::output_impl_t::set_effective_size(const wf::dimensions_t& size)
{
    this->effective_size = size;
}

wf::dimensions_t wf::output_impl_t::get_screen_size() const
{
    return this->effective_size;
}

wf::geometry_t wf::output_t::get_relative_geometry() const
{
    auto size = get_screen_size();

    return {
        0, 0, size.width, size.height
    };
}

wf::geometry_t wf::output_t::get_layout_geometry() const
{
    auto box = wlr_output_layout_get_box(
        wf::get_core().output_layout->get_handle(), handle);
    if (box)
    {
        return *box;
    } else
    {
        LOGE("Get layout geometry for an invalid output!");

        return {0, 0, 1, 1};
    }
}

void wf::output_t::ensure_pointer(bool center) const
{
    auto ptr = wf::get_core().get_cursor_position();
    if (!center &&
        (get_layout_geometry() & wf::point_t{(int)ptr.x, (int)ptr.y}))
    {
        return;
    }

    auto lg = get_layout_geometry();
    wf::pointf_t target = {
        lg.x + lg.width / 2.0,
        lg.y + lg.height / 2.0,
    };
    wf::get_core().warp_cursor(target);
    wf::get_core().set_cursor("default");
}

wf::pointf_t wf::output_t::get_cursor_position() const
{
    auto og = get_layout_geometry();
    auto gc = wf::get_core().get_cursor_position();

    return {gc.x - og.x, gc.y - og.y};
}

bool wf::output_t::ensure_visible(wayfire_view v)
{
    auto bbox = v->get_bounding_box();
    auto g    = this->get_relative_geometry();

    /* Compute the percentage of the view which is visible */
    auto intersection = wf::geometry_intersection(bbox, g);
    double area = 1.0 * intersection.width * intersection.height;
    area /= 1.0 * bbox.width * bbox.height;

    if (area >= 0.1) /* View is somewhat visible, no need for anything special */
    {
        return false;
    }

    /* Otherwise, switch the workspace so the view gets maximum exposure */
    int dx = bbox.x + bbox.width / 2;
    int dy = bbox.y + bbox.height / 2;

    int dvx  = std::floor(1.0 * dx / g.width);
    int dvy  = std::floor(1.0 * dy / g.height);
    auto cws = workspace->get_current_workspace();
    workspace->request_workspace(cws + wf::point_t{dvx, dvy});

    return true;
}

void wf::output_impl_t::close_popups()
{
    for (auto& v : workspace->get_views_in_layer(wf::ALL_LAYERS))
    {
        auto popup = dynamic_cast<wayfire_xdg_popup*>(v.get());
        if (!popup || (popup->popup_parent == active_view.get()))
        {
            continue;
        }

        /* Ignore popups which have a popup as their parent. In those cases, we'll
         * close the topmost popup and this will recursively destroy the others.
         *
         * Otherwise we get a race condition with wlroots. */
        if (dynamic_cast<wayfire_xdg_popup*>(popup->popup_parent))
        {
            continue;
        }

        popup->close();
    }
}

void wf::output_impl_t::update_active_view(wayfire_view v, uint32_t flags)
{
    this->active_view = v;
    if (this == wf::get_core().get_active_output())
    {
        wf::get_core().set_active_view(v);
    }

    if (flags & FOCUS_VIEW_CLOSE_POPUPS)
    {
        close_popups();
    }
}

void wf::output_impl_t::focus_view(wayfire_view v, uint32_t flags)
{
    const auto& make_view_visible = [this, flags] (wayfire_view view)
    {
        if (view->minimized)
        {
            view->minimize_request(false);
        }

        if (flags & FOCUS_VIEW_RAISE)
        {
            workspace->bring_to_front(view);
        }
    };

    if (v && (workspace->get_view_layer(v) < wf::get_core().get_focused_layer()))
    {
        auto active_view = get_active_view();
        if (active_view && (active_view->get_app_id().find("$unfocus") == 0))
        {
            /* This is the case where for ex. a panel has grabbed input focus,
             * but user has clicked on another view so we want to dismiss the
             * grab. We can't do that straight away because the client still
             * holds the focus layer request.
             *
             * Instead, we want to deactive the $unfocus view, so that it can
             * release the grab. At the same time, we bring the to-be-focused
             * view on top, so that it gets the focus next. */
            update_active_view(nullptr, flags);
            make_view_visible(v);
        } else
        {
            LOGD("Denying focus request for a view from a lower layer than the"
                 " focused layer");
        }

        return;
    }

    focus_view_signal data;

    if (!v || !v->is_mapped())
    {
        update_active_view(nullptr, flags);
        data.view = nullptr;
        emit_signal("focus-view", &data);
        return;
    }

    while (v->parent && v->parent->is_mapped())
    {
        v = v->parent;
    }

    /* If no keyboard focus surface is set, then we don't want to focus the view */
    if (v->get_keyboard_focus_surface() || interactive_view_from_view(v.get()))
    {
        make_view_visible(v);
        update_active_view(v, flags);
        data.view = v;
        emit_signal("view-focused", &data);
    }
}

void wf::output_impl_t::focus_view(wayfire_view v, bool raise)
{
    uint32_t flags = FOCUS_VIEW_CLOSE_POPUPS;
    if (raise)
    {
        flags |= FOCUS_VIEW_RAISE;
    }

    focus_view(v, flags);
}

wayfire_view wf::output_t::get_top_view() const
{
    auto views = workspace->get_views_on_workspace(
        workspace->get_current_workspace(),
        LAYER_WORKSPACE);

    return views.empty() ? nullptr : views[0];
}

wayfire_view wf::output_impl_t::get_active_view() const
{
    return active_view;
}

bool wf::output_impl_t::can_activate_plugin(uint32_t caps,
    uint32_t flags)
{
    if (this->inhibited && !(flags & wf::PLUGIN_ACTIVATION_IGNORE_INHIBIT))
    {
        return false;
    }

    for (auto act_owner : active_plugins)
    {
        bool compatible = ((act_owner->capabilities & caps) == 0);
        if (!compatible)
        {
            return false;
        }
    }

    return true;
}

bool wf::output_impl_t::can_activate_plugin(const plugin_grab_interface_uptr& owner,
    uint32_t flags)
{
    if (!owner)
    {
        return false;
    }

    if (active_plugins.find(owner.get()) != active_plugins.end())
    {
        return flags & wf::PLUGIN_ACTIVATE_ALLOW_MULTIPLE;
    }

    return can_activate_plugin(owner->capabilities, flags);
}

bool wf::output_impl_t::activate_plugin(const plugin_grab_interface_uptr& owner,
    uint32_t flags)
{
    if (!can_activate_plugin(owner, flags))
    {
        return false;
    }

    if (active_plugins.find(owner.get()) != active_plugins.end())
    {
        LOGD("output ", handle->name,
            ": activate plugin ", owner->name, " again");
    } else
    {
        LOGD("output ", handle->name, ": activate plugin ", owner->name);
    }

    active_plugins.insert(owner.get());

    return true;
}

bool wf::output_impl_t::deactivate_plugin(
    const plugin_grab_interface_uptr& owner)
{
    auto it = active_plugins.find(owner.get());
    if (it == active_plugins.end())
    {
        return true;
    }

    active_plugins.erase(it);
    LOGD("output ", handle->name, ": deactivate plugin ", owner->name);

    if (active_plugins.count(owner.get()) == 0)
    {
        owner->ungrab();
        active_plugins.erase(owner.get());

        return true;
    }

    return false;
}

void wf::output_impl_t::cancel_active_plugins()
{
    std::vector<wf::plugin_grab_interface_t*> ifaces;
    for (auto p : active_plugins)
    {
        if (p->callbacks.cancel)
        {
            ifaces.push_back(p);
        }
    }

    for (auto p : ifaces)
    {
        p->callbacks.cancel();
    }
}

bool wf::output_impl_t::is_plugin_active(std::string name) const
{
    for (auto act : active_plugins)
    {
        if (act && (act->name == name))
        {
            return true;
        }
    }

    return false;
}

wf::plugin_grab_interface_t*wf::output_impl_t::get_input_grab_interface()
{
    for (auto p : active_plugins)
    {
        if (p && p->is_grabbed())
        {
            return p;
        }
    }

    return nullptr;
}

void wf::output_impl_t::inhibit_plugins()
{
    this->inhibited = true;
    cancel_active_plugins();
}

void wf::output_impl_t::uninhibit_plugins()
{
    this->inhibited = false;
}

bool wf::output_impl_t::is_inhibited() const
{
    return this->inhibited;
}

/* simple wrappers for wf::get_core_impl().input, as it isn't exposed to plugins */
wf::binding_t*wf::output_t::add_key(option_sptr_t<keybinding_t> key,
    wf::key_callback *callback)
{
    return wf::get_core_impl().input->new_binding(WF_BINDING_KEY, key, this,
        callback);
}

wf::binding_t*wf::output_t::add_axis(option_sptr_t<keybinding_t> axis,
    wf::axis_callback *callback)
{
    return wf::get_core_impl().input->new_binding(WF_BINDING_AXIS, axis, this,
        callback);
}

wf::binding_t*wf::output_t::add_button(option_sptr_t<buttonbinding_t> button,
    wf::button_callback *callback)
{
    return wf::get_core_impl().input->new_binding(WF_BINDING_BUTTON, button,
        this, callback);
}

wf::binding_t*wf::output_t::add_gesture(option_sptr_t<touchgesture_t> gesture,
    wf::gesture_callback *callback)
{
    return wf::get_core_impl().input->new_binding(WF_BINDING_GESTURE, gesture,
        this, callback);
}

wf::binding_t*wf::output_t::add_activator(
    option_sptr_t<activatorbinding_t> activator, wf::activator_callback *callback)
{
    return wf::get_core_impl().input->new_binding(WF_BINDING_ACTIVATOR, activator,
        this, callback);
}

void wf::output_t::rem_binding(wf::binding_t *binding)
{
    wf::get_core_impl().input->rem_binding(binding);
}

void wf::output_t::rem_binding(void *callback)
{
    wf::get_core_impl().input->rem_binding(callback);
}

namespace wf
{
uint32_t all_layers_not_below(uint32_t layer)
{
    uint32_t mask = 0;
    for (int i = 0; i < wf::TOTAL_LAYERS; i++)
    {
        if ((1u << i) >= layer)
        {
            mask |= (1 << i);
        }
    }

    return mask;
}
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium 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 "ui/views/controls/menu/menu_host_root_view.h"

#include "ui/views/controls/menu/menu_controller.h"
#include "ui/views/controls/menu/submenu_view.h"

namespace views {

MenuHostRootView::MenuHostRootView(Widget* widget,
                                   SubmenuView* submenu)
    : internal::RootView(widget),
      submenu_(submenu),
      forward_drag_to_menu_controller_(true) {
}

bool MenuHostRootView::OnMousePressed(const ui::MouseEvent& event) {
  forward_drag_to_menu_controller_ =
      !GetLocalBounds().Contains(event.location()) ||
      !RootView::OnMousePressed(event);
  if (forward_drag_to_menu_controller_ && GetMenuController())
    GetMenuController()->OnMousePressed(submenu_, event);
  return true;
}

bool MenuHostRootView::OnMouseDragged(const ui::MouseEvent& event) {
  if (forward_drag_to_menu_controller_ && GetMenuController()) {
    GetMenuController()->OnMouseDragged(submenu_, event);
    return true;
  }
  return RootView::OnMouseDragged(event);
}

void MenuHostRootView::OnMouseReleased(const ui::MouseEvent& event) {
  RootView::OnMouseReleased(event);
  if (forward_drag_to_menu_controller_ && GetMenuController()) {
    forward_drag_to_menu_controller_ = false;
    GetMenuController()->OnMouseReleased(submenu_, event);
  }
}

void MenuHostRootView::OnMouseMoved(const ui::MouseEvent& event) {
  RootView::OnMouseMoved(event);
  if (GetMenuController())
    GetMenuController()->OnMouseMoved(submenu_, event);
}

bool MenuHostRootView::OnMouseWheel(const ui::MouseWheelEvent& event) {
#if defined(OS_LINUX)
  // ChromeOS uses MenuController to forward events like other
  // mouse events.
  return GetMenuController() &&
      GetMenuController()->OnMouseWheel(submenu_, event);
#else
  // Windows uses focus_util_win::RerouteMouseWheel to forward events to
  // the right menu.
  // RootView::OnMouseWheel forwards to the focused view. We don't have a
  // focused view, so we need to override this then forward to the menu.
  return submenu_->OnMouseWheel(event);
#endif
}

ui::EventResult MenuHostRootView::OnGestureEvent(
    const ui::GestureEvent& event) {
  RootView::OnGestureEvent(event);
  // ChromeOS uses MenuController to forward events like other
  // mouse events.
  if (!GetMenuController())
    return ui::ER_UNHANDLED;
  return GetMenuController()->OnGestureEvent(submenu_, event);
}

MenuController* MenuHostRootView::GetMenuController() {
  return submenu_ ? submenu_->GetMenuItem()->GetMenuController() : NULL;
}

}  // namespace views
<commit_msg>views: Make sure a gesture event is not processed more than once.<commit_after>// Copyright (c) 2012 The Chromium 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 "ui/views/controls/menu/menu_host_root_view.h"

#include "ui/views/controls/menu/menu_controller.h"
#include "ui/views/controls/menu/submenu_view.h"

namespace views {

MenuHostRootView::MenuHostRootView(Widget* widget,
                                   SubmenuView* submenu)
    : internal::RootView(widget),
      submenu_(submenu),
      forward_drag_to_menu_controller_(true) {
}

bool MenuHostRootView::OnMousePressed(const ui::MouseEvent& event) {
  forward_drag_to_menu_controller_ =
      !GetLocalBounds().Contains(event.location()) ||
      !RootView::OnMousePressed(event);
  if (forward_drag_to_menu_controller_ && GetMenuController())
    GetMenuController()->OnMousePressed(submenu_, event);
  return true;
}

bool MenuHostRootView::OnMouseDragged(const ui::MouseEvent& event) {
  if (forward_drag_to_menu_controller_ && GetMenuController()) {
    GetMenuController()->OnMouseDragged(submenu_, event);
    return true;
  }
  return RootView::OnMouseDragged(event);
}

void MenuHostRootView::OnMouseReleased(const ui::MouseEvent& event) {
  RootView::OnMouseReleased(event);
  if (forward_drag_to_menu_controller_ && GetMenuController()) {
    forward_drag_to_menu_controller_ = false;
    GetMenuController()->OnMouseReleased(submenu_, event);
  }
}

void MenuHostRootView::OnMouseMoved(const ui::MouseEvent& event) {
  RootView::OnMouseMoved(event);
  if (GetMenuController())
    GetMenuController()->OnMouseMoved(submenu_, event);
}

bool MenuHostRootView::OnMouseWheel(const ui::MouseWheelEvent& event) {
#if defined(OS_LINUX)
  // ChromeOS uses MenuController to forward events like other
  // mouse events.
  return GetMenuController() &&
      GetMenuController()->OnMouseWheel(submenu_, event);
#else
  // Windows uses focus_util_win::RerouteMouseWheel to forward events to
  // the right menu.
  // RootView::OnMouseWheel forwards to the focused view. We don't have a
  // focused view, so we need to override this then forward to the menu.
  return submenu_->OnMouseWheel(event);
#endif
}

ui::EventResult MenuHostRootView::OnGestureEvent(
    const ui::GestureEvent& event) {
  ui::EventResult result = RootView::OnGestureEvent(event);
  if (result != ui::ER_UNHANDLED)
    return result;
  // ChromeOS uses MenuController to forward events like other
  // mouse events.
  if (!GetMenuController())
    return ui::ER_UNHANDLED;
  return GetMenuController()->OnGestureEvent(submenu_, event);
}

MenuController* MenuHostRootView::GetMenuController() {
  return submenu_ ? submenu_->GetMenuItem()->GetMenuController() : NULL;
}

}  // namespace views
<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS formcelllinkage (1.5.92); FILE MERGED 2003/10/01 09:18:31 fs 1.5.92.1: #i18994# merging the changes from the CWS fs002<commit_after><|endoftext|>


<commit_before>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbOGRDataSourceToLabelImageFilter.h"
#include "itkImageRegionConstIterator.h"
#include "otbOGRDataSourceWrapper.h"

#include "itkImageRegionSplitter.h"
#include "otbStreamingTraits.h"

namespace otb
{
namespace Wrapper
{

class ComputeConfusionMatrix : public Application
{
public:
  /** Standard class typedefs. */
  typedef ComputeConfusionMatrix Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ComputeConfusionMatrix, otb::Application);

  typedef itk::ImageRegionConstIterator<Int32ImageType> ImageIteratorType;

  typedef otb::OGRDataSourceToLabelImageFilter
    <Int32ImageType>                                    RasterizeFilterType;

  typedef otb::StreamingTraits<Int32ImageType>        StreamingTraitsType;

  typedef itk::ImageRegionSplitter<2>                 SplitterType;

  typedef Int32ImageType::RegionType                  RegionType;

private:
  void DoInit()
  {
  SetName("ComputeConfusionMatrix");
  SetDescription("Computes the confusion matrix of a classification");

  // Documentation
  SetDocName("Compute Confusion Matrix Application");
  SetDocLongDescription("This application computes the confusion matrix of a classification  relatively to a ground truth. This ground truth can be given as a raster or a vector data.");
  SetDocLimitations("None");
  SetDocAuthors("OTB-Team");
  SetDocSeeAlso(" ");

  //AddDocTag(Tags::Classification);

  AddParameter(ParameterType_InputImage, "in", "Input Image");
  SetParameterDescription( "in", "The input classification image." );

  AddParameter(ParameterType_OutputFilename, "out", "Matrix output");
  SetParameterDescription("out", "Filename to store the output matrix (csv format)");

  AddParameter(ParameterType_Choice,"ref","Ground truth");
  SetParameterDescription("ref","Choice of ground truth format");

  AddChoice("ref.raster","Ground truth as a raster image");

  AddChoice("ref.vector","Ground truth as a vector data file");

  AddParameter(ParameterType_InputImage,"ref.raster.in","Input reference image");
  SetParameterDescription("ref.raster.in","Input image containing the ground truth labels");

  AddParameter(ParameterType_InputFilename,"ref.vector.in","Input reference vector data");
  SetParameterDescription("ref.vector.in", "Input vector data of the ground truth");

  AddParameter(ParameterType_String,"ref.vector.field","Field name");
  SetParameterDescription("ref.vector.field","Field name containing the label values");
  SetParameterString("ref.vector.field","dn");
  MandatoryOff("ref.vector.field");
  DisableParameter("ref.vector.field");

  AddParameter(ParameterType_Int,"labels","Number of labels");
  SetParameterDescription("labels","Number of labels in the classification. The label values shall be contiguous and start from 1.");
  SetDefaultParameterInt("labels",2);
  MandatoryOff("labels");
  DisableParameter("labels");

  AddParameter(ParameterType_Int,"nodata","Value for nodata pixels");
  SetParameterDescription("nodata","This value will be used to discard pixels from the ground truth");
  SetDefaultParameterInt("nodata",0);
  MandatoryOff("nodata");
  DisableParameter("nodata");

  AddRAMParameter();

  // Doc example parameter settings
  SetDocExampleParameterValue("in", "clLabeledImageQB1.tif");
  SetDocExampleParameterValue("out", "confusion.txt");
  SetDocExampleParameterValue("ref", "vector");
  SetDocExampleParameterValue("ref.vector.in","VectorData_QB1_bis.shp");
  SetDocExampleParameterValue("ref.vector.field","Class");
  SetDocExampleParameterValue("labels","4");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    Int32ImageType* input = this->GetParameterImage<Int32ImageType>("in");

    std::string field;
    int nodata = this->GetParameterInt("nodata");

    //Init Conf Matrix
    unsigned int nbClasses = this->GetParameterInt("labels");
    m_Matrix.resize(nbClasses);
    for(unsigned int i=0; i<nbClasses; i++ )
      {
      m_Matrix[i].assign(nbClasses,0);
      }

    Int32ImageType::Pointer reference;
    otb::ogr::DataSource::Pointer ogrRef;
    RasterizeFilterType::Pointer rasterizeReference = RasterizeFilterType::New();

    if (GetParameterString("ref") == "raster")
      {
      reference = this->GetParameterImage<Int32ImageType>("ref.raster.in");
      }
    else
      {
      ogrRef = otb::ogr::DataSource::New(GetParameterString("ref.vector.in"), otb::ogr::DataSource::Modes::Read);
      field = this->GetParameterString("ref.vector.field");

      rasterizeReference->AddOGRDataSource(ogrRef);
      rasterizeReference->SetOutputParametersFromImage(input);
      rasterizeReference->SetBackgroundValue(nodata);
      rasterizeReference->SetBurnAttribute(field.c_str());

      reference = rasterizeReference->GetOutput();
      reference->UpdateOutputInformation();
      }

    // Prepare local streaming
    SplitterType::Pointer splitter = SplitterType::New();
    unsigned int numberOfStreamDivisions = StreamingTraitsType::CalculateNumberOfStreamDivisions(
      input,
      input->GetLargestPossibleRegion(),
      splitter,
      otb::SET_BUFFER_MEMORY_SIZE,
      0, 1048576*GetParameterInt("ram"), 0);
    RegionType streamRegion;

    otbAppLogINFO("Number of stream divisions : "<<numberOfStreamDivisions);

    for (unsigned int index=0 ; index<numberOfStreamDivisions ; index++)
      {
      streamRegion = splitter->GetSplit(index, numberOfStreamDivisions, input->GetLargestPossibleRegion());

      input->SetRequestedRegion(streamRegion);
      input->PropagateRequestedRegion();
      input->UpdateOutputData();

      reference->SetRequestedRegion(streamRegion);
      reference->PropagateRequestedRegion();
      reference->UpdateOutputData();

      ImageIteratorType itInput(input, streamRegion);
      itInput.GoToBegin();

      ImageIteratorType itRef(reference, streamRegion);
      itRef.GoToBegin();

      while (!itInput.IsAtEnd())
        {
        if (itRef.Get() != nodata)
          {
          if (itRef.Get()>0 && itRef.Get()<=nbClasses && itInput.Get()>0 && itInput.Get()<=nbClasses)
            {
            m_Matrix[itInput.Get()-1][itRef.Get()-1] ++;
            }
          }
        ++ itInput;
        ++ itRef;
        }
      }

    std::ofstream outFile;
    outFile.open(this->GetParameterString("out").c_str());
    outFile<<std::fixed;
    outFile.precision(10);
    for(unsigned int j=0; j<nbClasses; j++ )
      {
      for(unsigned int i=0; i<nbClasses; i++ )
        {
        outFile << m_Matrix[i][j];
        if (i<(nbClasses-1))
          {
          outFile<<"\t";
          }
        else
          {
          outFile<<std::endl;
          }
        }
      }
    outFile.close();

  }

  std::vector<std::vector<unsigned long> > m_Matrix;

};

}
}
OTB_APPLICATION_EXPORT(otb::Wrapper::ComputeConfusionMatrix)
<commit_msg>STYLE<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbOGRDataSourceToLabelImageFilter.h"
#include "itkImageRegionConstIterator.h"
#include "otbOGRDataSourceWrapper.h"

#include "itkImageRegionSplitter.h"
#include "otbStreamingTraits.h"

namespace otb
{
namespace Wrapper
{

class ComputeConfusionMatrix : public Application
{
public:
  /** Standard class typedefs. */
  typedef ComputeConfusionMatrix Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ComputeConfusionMatrix, otb::Application);

  typedef itk::ImageRegionConstIterator<Int32ImageType> ImageIteratorType;

  typedef otb::OGRDataSourceToLabelImageFilter
    <Int32ImageType>                                    RasterizeFilterType;

  typedef otb::StreamingTraits<Int32ImageType>        StreamingTraitsType;

  typedef itk::ImageRegionSplitter<2>                 SplitterType;

  typedef Int32ImageType::RegionType                  RegionType;

private:
  void DoInit()
  {
  SetName("ComputeConfusionMatrix");
  SetDescription("Computes the confusion matrix of a classification");

  // Documentation
  SetDocName("Compute Confusion Matrix Application");
  SetDocLongDescription("This application computes the confusion matrix of a classification  relatively to a ground truth. This ground truth can be given as a raster or a vector data.");
  SetDocLimitations("None");
  SetDocAuthors("OTB-Team");
  SetDocSeeAlso(" ");

  //AddDocTag(Tags::Classification);

  AddParameter(ParameterType_InputImage, "in", "Input Image");
  SetParameterDescription( "in", "The input classification image." );

  AddParameter(ParameterType_OutputFilename, "out", "Matrix output");
  SetParameterDescription("out", "Filename to store the output matrix (csv format)");

  AddParameter(ParameterType_Choice,"ref","Ground truth");
  SetParameterDescription("ref","Choice of ground truth format");

  AddChoice("ref.raster","Ground truth as a raster image");

  AddChoice("ref.vector","Ground truth as a vector data file");

  AddParameter(ParameterType_InputImage,"ref.raster.in","Input reference image");
  SetParameterDescription("ref.raster.in","Input image containing the ground truth labels");

  AddParameter(ParameterType_InputFilename,"ref.vector.in","Input reference vector data");
  SetParameterDescription("ref.vector.in", "Input vector data of the ground truth");

  AddParameter(ParameterType_String,"ref.vector.field","Field name");
  SetParameterDescription("ref.vector.field","Field name containing the label values");
  SetParameterString("ref.vector.field","dn");
  MandatoryOff("ref.vector.field");
  DisableParameter("ref.vector.field");

  AddParameter(ParameterType_Int,"labels","Number of labels");
  SetParameterDescription("labels","Number of labels in the classification. The label values shall be contiguous and start from 1.");
  SetDefaultParameterInt("labels",2);
  MandatoryOff("labels");
  DisableParameter("labels");

  AddParameter(ParameterType_Int,"nodata","Value for nodata pixels");
  SetParameterDescription("nodata","This value will be used to discard pixels from the ground truth");
  SetDefaultParameterInt("nodata",0);
  MandatoryOff("nodata");
  DisableParameter("nodata");

  AddRAMParameter();

  // Doc example parameter settings
  SetDocExampleParameterValue("in", "clLabeledImageQB1.tif");
  SetDocExampleParameterValue("out", "confusion.txt");
  SetDocExampleParameterValue("ref", "vector");
  SetDocExampleParameterValue("ref.vector.in","VectorData_QB1_bis.shp");
  SetDocExampleParameterValue("ref.vector.field","Class");
  SetDocExampleParameterValue("labels","4");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    Int32ImageType* input = this->GetParameterImage<Int32ImageType>("in");

    std::string field;
    int nodata = this->GetParameterInt("nodata");

    //Init Conf Matrix
    unsigned int nbClasses = this->GetParameterInt("labels");
    m_Matrix.resize(nbClasses);
    for(unsigned int i=0; i<nbClasses; i++ )
      {
      m_Matrix[i].assign(nbClasses,0);
      }

    Int32ImageType::Pointer reference;
    otb::ogr::DataSource::Pointer ogrRef;
    RasterizeFilterType::Pointer rasterizeReference = RasterizeFilterType::New();

    if (GetParameterString("ref") == "raster")
      {
      reference = this->GetParameterImage<Int32ImageType>("ref.raster.in");
      }
    else
      {
      ogrRef = otb::ogr::DataSource::New(GetParameterString("ref.vector.in"), otb::ogr::DataSource::Modes::Read);
      field = this->GetParameterString("ref.vector.field");

      rasterizeReference->AddOGRDataSource(ogrRef);
      rasterizeReference->SetOutputParametersFromImage(input);
      rasterizeReference->SetBackgroundValue(nodata);
      rasterizeReference->SetBurnAttribute(field.c_str());

      reference = rasterizeReference->GetOutput();
      reference->UpdateOutputInformation();
      }

    // Prepare local streaming
    SplitterType::Pointer splitter = SplitterType::New();
    unsigned int numberOfStreamDivisions = StreamingTraitsType::CalculateNumberOfStreamDivisions(
      input,
      input->GetLargestPossibleRegion(),
      splitter,
      otb::SET_BUFFER_MEMORY_SIZE,
      0, 1048576*GetParameterInt("ram"), 0);
    RegionType streamRegion;

    otbAppLogINFO("Number of stream divisions : "<<numberOfStreamDivisions);

    for (unsigned int index=0; index<numberOfStreamDivisions; index++)
      {
      streamRegion = splitter->GetSplit(index, numberOfStreamDivisions, input->GetLargestPossibleRegion());

      input->SetRequestedRegion(streamRegion);
      input->PropagateRequestedRegion();
      input->UpdateOutputData();

      reference->SetRequestedRegion(streamRegion);
      reference->PropagateRequestedRegion();
      reference->UpdateOutputData();

      ImageIteratorType itInput(input, streamRegion);
      itInput.GoToBegin();

      ImageIteratorType itRef(reference, streamRegion);
      itRef.GoToBegin();

      while (!itInput.IsAtEnd())
        {
        if (itRef.Get() != nodata)
          {
          if (itRef.Get()>0 && itRef.Get()<=nbClasses && itInput.Get()>0 && itInput.Get()<=nbClasses)
            {
            m_Matrix[itInput.Get()-1][itRef.Get()-1] ++;
            }
          }
        ++ itInput;
        ++ itRef;
        }
      }

    std::ofstream outFile;
    outFile.open(this->GetParameterString("out").c_str());
    outFile<<std::fixed;
    outFile.precision(10);
    for(unsigned int j=0; j<nbClasses; j++ )
      {
      for(unsigned int i=0; i<nbClasses; i++ )
        {
        outFile << m_Matrix[i][j];
        if (i<(nbClasses-1))
          {
          outFile<<"\t";
          }
        else
          {
          outFile<<std::endl;
          }
        }
      }
    outFile.close();

  }

  std::vector<std::vector<unsigned long> > m_Matrix;

};

}
}
OTB_APPLICATION_EXPORT(otb::Wrapper::ComputeConfusionMatrix)
<|endoftext|>