<commit_before>#include "servercommand.h"
#include <stdio.h>
#include <pthread.h>

#define COMMAND_BUF      256

typedef struct sockaddr SA ;

// client thread
void *clientthread( void *arg )
{
	long int retval = 0 ;
	int clientfd = *(int*)arg ;
	ServerCommand command( clientfd ) ;
	char commandbuf[COMMAND_BUF] ;
	while ( 1 )
	{
		bzero( commandbuf, COMMAND_BUF ) ;
		// take command
		if ( read( clientfd, commandbuf, COMMAND_BUF) <= 0 )
		{
			goto error ;
		}
		std::cout << "command:" << commandbuf << std::endl ;
		if ( !strncmp( COMMAND_LS, commandbuf, strlen(COMMAND_LS) ) )
		{
			if ( -1 == command.LsCommand( ) )
			{
				goto error ;
			}
		}

		if ( !strncmp( COMMAND_GET, commandbuf, strlen(COMMAND_GET) ) )
		{
			if ( -1 == command.GetCommand( commandbuf+strlen(COMMAND_GET) ) )
			{
				goto error ;
			}
		}

		if ( !strncmp( COMMAND_PUT, commandbuf, strlen(COMMAND_PUT) ) )
		{
			if ( -1 == command.PutCommand( commandbuf+strlen(COMMAND_PUT) ) )
			{
				goto error ;
			}
		}

		if ( !strncmp( COMMAND_HELP, commandbuf, strlen(COMMAND_HELP) ) )
		{
			if ( -1 == command.HelpCommand( ) )
			{
				goto error ;
			}
		}

		if ( !strncmp( COMMAND_QUIT, commandbuf, strlen(COMMAND_QUIT) ) )
		{
			if ( -1 == command.QuitCommand( ) )
			{
				goto error ;
			}
		}

		if ( !strncmp( COMMAND_CD, commandbuf, strlen(COMMAND_CD) ) )
		{
			if ( -1 == command.CdCommand( commandbuf+strlen(COMMAND_CD) ) )
			{
				goto error ;
			}
		}
	}
done:
	delete (int*)arg ;
	return (void*)retval ;
error:
	retval = -1 ;
	goto done ;
}

int main( int argc, char **argv )
{
	if ( argc < 2 )
	{
		std::cerr << "用法：" << argv[0] << "<端口号>" << std::endl ;
		return - 1;
	}
	// prepare to listen socket
	int listenfd = socket( AF_INET, SOCK_STREAM, 0 ) ;
	if ( - 1 == listenfd )
	{
		perror( "listen" ) ;
		return -1 ;
	}
	// prepare to bind
	struct sockaddr_in addrserver ;
	bzero( &addrserver, sizeof(addrserver) ) ;
	addrserver.sin_family = AF_INET ;
	addrserver.sin_port = htons( atoi( argv[1] ) );
	// listen
	if ( -1 == bind( listenfd, (SA*)&addrserver, sizeof(addrserver) ) )
	{
		perror( "bind" ) ;
		return -1 ;
	}
	// listen
	if ( -1 == listen( listenfd, 32 ) )
	{
		perror( "listen" ) ;
		return -1 ;
	}

	for( ; ; )
	{
		struct sockaddr_in addrcli ;
		socklen_t len = sizeof(addrcli) ;
		bzero( &addrcli, len ) ;
		// wait for client
		int clientfd = accept( listenfd, (SA*)&addrcli, &len ) ;
		if ( -1 == clientfd )
		{
			perror( "accept" ) ;
			return -1 ;
		}
		// create thread，size 4096 * 10
		pthread_t tid ;
		pthread_attr_t attr ;
		pthread_attr_init( &attr ) ;
		if ( pthread_attr_setstacksize( &attr, 4096 * 10 ) )
		{
			perror( "phread_attr_setstacksize" ) ;
			return -1 ;
		}
		if ( pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED ) )
		{
			perror( "pthread_attr_setdetached" ) ;
			return -1 ;
		}
		if ( pthread_create( &tid, &attr, clientthread, new int( clientfd ) ) )
		{
			perror( "pthread_create" ) ;
			return - 1;
		}
	}
}
<commit_msg>modification<commit_after>#include "servercommand.h"
#include <stdio.h>
#include <pthread.h>

#define COMMAND_BUF      256

typedef struct sockaddr SA ;

// client thread
void *clientthread( void *arg )
{
	long int retval = 0 ;
	int clientfd = *(int*)arg ;
	ServerCommand command( clientfd ) ;
	char commandbuf[COMMAND_BUF] ;
	while ( 1 )
	{
		bzero( commandbuf, COMMAND_BUF ) ;
		// take command
		if ( read( clientfd, commandbuf, COMMAND_BUF) <= 0 )
		{
			goto error ;
		}
		std::cout << "command:" << commandbuf << std::endl ;
		if ( !strncmp( COMMAND_LS, commandbuf, strlen(COMMAND_LS) ) )
		{
			if ( -1 == command.LsCommand( ) )
			{
				goto error ;
			}
		}

		if ( !strncmp( COMMAND_GET, commandbuf, strlen(COMMAND_GET) ) )
		{
			if ( -1 == command.GetCommand( commandbuf+strlen(COMMAND_GET) ) )
			{
				goto error ;
			}
		}

		if ( !strncmp( COMMAND_PUT, commandbuf, strlen(COMMAND_PUT) ) )
		{
			if ( -1 == command.PutCommand( commandbuf+strlen(COMMAND_PUT) ) )
			{
				goto error ;
			}
		}

		if ( !strncmp( COMMAND_HELP, commandbuf, strlen(COMMAND_HELP) ) )
		{
			if ( -1 == command.HelpCommand( ) )
			{
				goto error ;
			}
		}

		if ( !strncmp( COMMAND_QUIT, commandbuf, strlen(COMMAND_QUIT) ) )
		{
			if ( -1 == command.QuitCommand( ) )
			{
				goto error ;
			}
		}

		if ( !strncmp( COMMAND_CD, commandbuf, strlen(COMMAND_CD) ) )
		{
			if ( -1 == command.CdCommand( commandbuf+strlen(COMMAND_CD) ) )
			{
				goto error ;
			}
		}
	}
done:
	delete (int*)arg ;
	return (void*)retval ;
error:
	retval = -1 ;
	goto done ;
}

int main( int argc, char **argv )
{
	if ( argc < 2 )
	{
		std::cerr << "Guide:" << argv[0] << "<Port Number>" << std::endl ;
		return - 1;
	}
	// prepare to listen socket
	int listenfd = socket( AF_INET, SOCK_STREAM, 0 ) ;
	if ( - 1 == listenfd )
	{
		perror( "listen" ) ;
		return -1 ;
	}
	// prepare to bind
	struct sockaddr_in addrserver ;
	bzero( &addrserver, sizeof(addrserver) ) ;
	addrserver.sin_family = AF_INET ;
	addrserver.sin_port = htons( atoi( argv[1] ) );
	// listen
	if ( -1 == bind( listenfd, (SA*)&addrserver, sizeof(addrserver) ) )
	{
		perror( "bind" ) ;
		return -1 ;
	}
	// listen
	if ( -1 == listen( listenfd, 32 ) )
	{
		perror( "listen" ) ;
		return -1 ;
	}

	for( ; ; )
	{
		struct sockaddr_in addrcli ;
		socklen_t len = sizeof(addrcli) ;
		bzero( &addrcli, len ) ;
		// wait for client
		int clientfd = accept( listenfd, (SA*)&addrcli, &len ) ;
		if ( -1 == clientfd )
		{
			perror( "accept" ) ;
			return -1 ;
		}
		// create thread，size 4096 * 10
		pthread_t tid ;
		pthread_attr_t attr ;
		pthread_attr_init( &attr ) ;
		if ( pthread_attr_setstacksize( &attr, 4096 * 10 ) )
		{
			perror( "phread_attr_setstacksize" ) ;
			return -1 ;
		}
		if ( pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED ) )
		{
			perror( "pthread_attr_setdetached" ) ;
			return -1 ;
		}
		if ( pthread_create( &tid, &attr, clientthread, new int( clientfd ) ) )
		{
			perror( "pthread_create" ) ;
			return - 1;
		}
	}
}
<|endoftext|>


<commit_before>// String utilities.
//
// Written by Bernie Bright, started 1998
//
// Copyright (C) 1998  Bernie Bright - bbright@bigpond.net.au
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//
// $Id$

#include <ctype.h>
#include <cstring>

#include "strutils.hxx"

using std::string;
using std::vector;

namespace simgear {
    namespace strutils {

	/**
	 *
	 */
	static vector<string>
	split_whitespace( const string& str, int maxsplit )
	{
	    vector<string> result;
	    string::size_type len = str.length();
	    string::size_type i = 0;
	    string::size_type j;
	    int countsplit = 0;

	    while (i < len)
	    {
		while (i < len && isspace((unsigned char)str[i]))
		{
		    ++i;
		}

		j = i;

		while (i < len && !isspace((unsigned char)str[i]))
		{
		    ++i;
		}

		if (j < i)
		{
		    result.push_back( str.substr(j, i-j) );
		    ++countsplit;
		    while (i < len && isspace((unsigned char)str[i]))
		    {
			++i;
		    }

		    if (maxsplit && (countsplit >= maxsplit) && i < len)
		    {
			result.push_back( str.substr( i, len-i ) );
			i = len;
		    }
		}
	    }

	    return result;
	}

	/**
	 *
	 */
	vector<string>
	split( const string& str, const char* sep, int maxsplit )
	{
	    if (sep == 0)
		return split_whitespace( str, maxsplit );

	    vector<string> result;
	    int n = std::strlen( sep );
	    if (n == 0)
	    {
		// Error: empty separator string
		return result;
	    }
	    const char* s = str.c_str();
	    string::size_type len = str.length();
	    string::size_type i = 0;
	    string::size_type j = 0;
	    int splitcount = 0;

	    while (i+n <= len)
	    {
		if (s[i] == sep[0] && (n == 1 || std::memcmp(s+i, sep, n) == 0))
		{
		    result.push_back( str.substr(j,i-j) );
		    i = j = i + n;
		    ++splitcount;
		    if (maxsplit && (splitcount >= maxsplit))
			break;
		}
		else
		{
		    ++i;
		}
	    }

	    result.push_back( str.substr(j,len-j) );
	    return result;
	}

	/**
	 * The lstrip(), rstrip() and strip() functions are implemented
	 * in do_strip() which uses an additional parameter to indicate what
	 * type of strip should occur.
	 */
	const int LEFTSTRIP = 0;
	const int RIGHTSTRIP = 1;
	const int BOTHSTRIP = 2;

	static string
	do_strip( const string& s, int striptype )
	{
	    //     if (s.empty())
	    //      return s;

	    string::size_type len = s.length();
	    string::size_type i = 0;
	    if (striptype != RIGHTSTRIP)
	    {
		while (i < len && isspace(s[i]))
		{
		    ++i;
		}
	    }

	    string::size_type j = len;
	    if (striptype != LEFTSTRIP)
	    {
		do
		{
		    --j;
		}
		while (j >= 1 && isspace(s[j]));
		++j;
	    }

	    if (i == 0 && j == len)
	    {
		return s;
	    }
	    else
	    {
		return s.substr( i, j - i );
	    }
	}

	string
	lstrip( const string& s )
	{
	    return do_strip( s, LEFTSTRIP );
	}

	string
	rstrip( const string& s )
	{
	    return do_strip( s, RIGHTSTRIP );
	}

	string
	strip( const string& s )
	{
	    return do_strip( s, BOTHSTRIP );
	}

	string
	rpad( const string & s, string::size_type length, char c )
	{
	    string::size_type l = s.length();
	    if( l >= length ) return s;
	    string reply = s;
	    return reply.append( length-l, c );
	}

	string
	lpad( const string & s, size_t length, char c )
	{
	    string::size_type l = s.length();
	    if( l >= length ) return s;
	    string reply = s;
	    return reply.insert( 0, length-l, c );
	}

    } // end namespace strutils
} // end namespace simgear
<commit_msg>Don't crash in strutils::trim() with empty strings<commit_after>// String utilities.
//
// Written by Bernie Bright, started 1998
//
// Copyright (C) 1998  Bernie Bright - bbright@bigpond.net.au
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//
// $Id$

#include <ctype.h>
#include <cstring>

#include "strutils.hxx"

using std::string;
using std::vector;

namespace simgear {
    namespace strutils {

	/**
	 *
	 */
	static vector<string>
	split_whitespace( const string& str, int maxsplit )
	{
	    vector<string> result;
	    string::size_type len = str.length();
	    string::size_type i = 0;
	    string::size_type j;
	    int countsplit = 0;

	    while (i < len)
	    {
		while (i < len && isspace((unsigned char)str[i]))
		{
		    ++i;
		}

		j = i;

		while (i < len && !isspace((unsigned char)str[i]))
		{
		    ++i;
		}

		if (j < i)
		{
		    result.push_back( str.substr(j, i-j) );
		    ++countsplit;
		    while (i < len && isspace((unsigned char)str[i]))
		    {
			++i;
		    }

		    if (maxsplit && (countsplit >= maxsplit) && i < len)
		    {
			result.push_back( str.substr( i, len-i ) );
			i = len;
		    }
		}
	    }

	    return result;
	}

	/**
	 *
	 */
	vector<string>
	split( const string& str, const char* sep, int maxsplit )
	{
	    if (sep == 0)
		return split_whitespace( str, maxsplit );

	    vector<string> result;
	    int n = std::strlen( sep );
	    if (n == 0)
	    {
		// Error: empty separator string
		return result;
	    }
	    const char* s = str.c_str();
	    string::size_type len = str.length();
	    string::size_type i = 0;
	    string::size_type j = 0;
	    int splitcount = 0;

	    while (i+n <= len)
	    {
		if (s[i] == sep[0] && (n == 1 || std::memcmp(s+i, sep, n) == 0))
		{
		    result.push_back( str.substr(j,i-j) );
		    i = j = i + n;
		    ++splitcount;
		    if (maxsplit && (splitcount >= maxsplit))
			break;
		}
		else
		{
		    ++i;
		}
	    }

	    result.push_back( str.substr(j,len-j) );
	    return result;
	}

	/**
	 * The lstrip(), rstrip() and strip() functions are implemented
	 * in do_strip() which uses an additional parameter to indicate what
	 * type of strip should occur.
	 */
	const int LEFTSTRIP = 0;
	const int RIGHTSTRIP = 1;
	const int BOTHSTRIP = 2;

	static string
	do_strip( const string& s, int striptype )
	{
	    string::size_type len = s.length();
	    if( len == 0 ) // empty string is trivial
		return s;
	    string::size_type i = 0;
	    if (striptype != RIGHTSTRIP)
	    {
		while (i < len && isspace(s[i]))
		{
		    ++i;
		}
	    }

	    string::size_type j = len;
	    if (striptype != LEFTSTRIP)
	    {
		do
		{
		    --j;
		}
		while (j >= 1 && isspace(s[j]));
		++j;
	    }

	    if (i == 0 && j == len)
	    {
		return s;
	    }
	    else
	    {
		return s.substr( i, j - i );
	    }
	}

	string
	lstrip( const string& s )
	{
	    return do_strip( s, LEFTSTRIP );
	}

	string
	rstrip( const string& s )
	{
	    return do_strip( s, RIGHTSTRIP );
	}

	string
	strip( const string& s )
	{
	    return do_strip( s, BOTHSTRIP );
	}

	string
	rpad( const string & s, string::size_type length, char c )
	{
	    string::size_type l = s.length();
	    if( l >= length ) return s;
	    string reply = s;
	    return reply.append( length-l, c );
	}

	string
	lpad( const string & s, size_t length, char c )
	{
	    string::size_type l = s.length();
	    if( l >= length ) return s;
	    string reply = s;
	    return reply.insert( 0, length-l, c );
	}

    } // end namespace strutils
} // end namespace simgear
<|endoftext|>


<commit_before>/***********************************************************************
    filename:   CEGUIDirect3D9Texture.cpp
    created:    Mon Feb 9 2009
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   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.
 ***************************************************************************/
#define NOMINMAX
#include <d3dx9.h>
#include "CEGUIDirect3D9Texture.h"
#include "CEGUIExceptions.h"
#include "CEGUISystem.h"
#include "CEGUIImageCodec.h"

// Start of CEGUI namespace section
namespace CEGUI
{
//----------------------------------------------------------------------------//
Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner) :
    d_owner(owner),
    d_texture(0),
    d_size(0, 0),
    d_dataSize(0, 0),
    d_texelScaling(0, 0),
    d_savedSurfaceDescValid(false)
{
}

//----------------------------------------------------------------------------//
Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner,
                                   const String& filename,
                                   const String& resourceGroup) :
    d_owner(owner),
    d_texture(0),
    d_size(0, 0),
    d_dataSize(0, 0),
    d_texelScaling(0, 0),
    d_savedSurfaceDescValid(false)
{
    loadFromFile(filename, resourceGroup);
}

//----------------------------------------------------------------------------//
Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner, const Size& sz) :
    d_owner(owner),
    d_texture(0),
    d_size(0, 0),
    d_dataSize(sz),
    d_texelScaling(0, 0),
    d_savedSurfaceDescValid(false)
{
    Size tex_sz(d_owner.getAdjustedSize(sz));

    HRESULT hr = D3DXCreateTexture(d_owner.getDevice(),
                                   static_cast<UINT>(tex_sz.d_width),
                                   static_cast<UINT>(tex_sz.d_height),
                                   1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
                                   &d_texture);

    if (FAILED(hr))
        CEGUI_THROW(RendererException(
            "Direct3D9Texture - Failed to create texture of specified size: "
            "D3D Texture creation failed."));

    updateTextureSize();
    updateCachedScaleValues();
}

//----------------------------------------------------------------------------//
Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner,
                                   LPDIRECT3DTEXTURE9 tex) :
    d_owner(owner),
    d_texture(0),
    d_size(0, 0),
    d_dataSize(0, 0),
    d_texelScaling(0, 0),
    d_savedSurfaceDescValid(false)
{
    setDirect3D9Texture(tex);
}

//----------------------------------------------------------------------------//
Direct3D9Texture::~Direct3D9Texture()
{
    cleanupDirect3D9Texture();
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::setDirect3D9Texture(LPDIRECT3DTEXTURE9 tex)
{
    if (d_texture != tex)
    {
        cleanupDirect3D9Texture();
        d_dataSize.d_width = d_dataSize.d_height = 0;

        d_texture = tex;
        if (d_texture)
            d_texture->AddRef();
    }

    updateTextureSize();
    d_dataSize = d_size;
    updateCachedScaleValues();
}

//----------------------------------------------------------------------------//
LPDIRECT3DTEXTURE9 Direct3D9Texture::getDirect3D9Texture() const
{
    return d_texture;
}

//----------------------------------------------------------------------------//
const Size& Direct3D9Texture::getSize() const
{
    return d_size;
}

//----------------------------------------------------------------------------//
const Size& Direct3D9Texture::getOriginalDataSize() const
{
    return d_dataSize;
}

//----------------------------------------------------------------------------//
const Vector2& Direct3D9Texture::getTexelScaling() const
{
    return d_texelScaling;
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::loadFromFile(const String& filename,
                                    const String& resourceGroup)
{
    // get and check existence of CEGUI::System object
    System* sys = System::getSingletonPtr();
    if (!sys)
        CEGUI_THROW(RendererException("Direct3D9Texture::loadFromFile - "
            "CEGUI::System object has not been created!"));

    // load file to memory via resource provider
    RawDataContainer texFile;
    sys->getResourceProvider()->loadRawDataContainer(filename, texFile,
            resourceGroup);

    Texture* res = sys->getImageCodec().load(texFile, this);

    // unload file data buffer
    sys->getResourceProvider()->unloadRawDataContainer(texFile);

    if (!res)
        // It's an error
        CEGUI_THROW(RendererException("Direct3D9Texture::loadFromFile - " +
            sys->getImageCodec().getIdentifierString() +
            " failed to load image '" + filename + "'."));
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::loadFromMemory(const void* buffer,
                                      const Size& buffer_size,
                                      PixelFormat pixel_format)
{
    cleanupDirect3D9Texture();

    // create a texture
    // TODO: Check resulting pixel format and react appropriately.
    D3DFORMAT pixfmt;
    switch (pixel_format)
    {
    case PF_RGB:
        pixfmt = D3DFMT_R8G8B8;
        break;
    case PF_RGBA:
        pixfmt = D3DFMT_A8B8G8R8;
        break;
    default:
        CEGUI_THROW(RendererException("Direct3D9Texture::loadFromMemory failed: "
            "Invalid PixelFormat value specified."));
    }

    Size tex_sz(d_owner.getAdjustedSize(buffer_size));

    HRESULT hr = D3DXCreateTexture(d_owner.getDevice(),
                                   static_cast<UINT>(tex_sz.d_width),
                                   static_cast<UINT>(tex_sz.d_height),
                                   1, 0, pixfmt, D3DPOOL_MANAGED, &d_texture);

    if (FAILED(hr))
        CEGUI_THROW(RendererException("Direct3D9Texture::loadFromMemory failed: "
            "Direct3D9 texture creation failed."));

    d_dataSize = buffer_size;
    updateTextureSize();
    updateCachedScaleValues();

    // lock the D3D texture
    D3DLOCKED_RECT rect;
    hr = d_texture->LockRect(0, &rect, 0, 0);

    if (FAILED(hr))
    {
        d_texture->Release();
        d_texture = 0;

        CEGUI_THROW(RendererException("Direct3D9Texture::loadFromMemory failed: "
            "IDirect3DTexture9::LockRect failed."));
    }

    // copy data from buffer into texture
    ulong* dst = static_cast<ulong*>(rect.pBits);
    const ulong* src = static_cast<const ulong*>(buffer);

    // RGBA
    if (pixel_format == PF_RGBA)
    {
        for (uint i = 0; i < buffer_size.d_height; ++i)
        {
            for (uint j = 0; j < buffer_size.d_width; ++j)
            {
                // we dont need endian safety on microsoft
                uchar r = static_cast<uchar>(src[j] & 0xFF);
                uchar g = static_cast<uchar>((src[j] >> 8) & 0xFF);
                uchar b = static_cast<uchar>((src[j] >> 16)  & 0xFF);
                uchar a = static_cast<uchar>((src[j] >> 24) & 0xFF);

                dst[j] = D3DCOLOR_ARGB(a, r, g, b);
            }

            dst += rect.Pitch / sizeof(ulong);
            src += static_cast<ulong>(buffer_size.d_width);
        }
    }
    // RGB
    else
    {
        for (uint i = 0; i < buffer_size.d_height; ++i)
        {
            for (uint j = 0; j < buffer_size.d_width; ++j)
            {
                uchar r = reinterpret_cast<const uchar*>(src)[j * 3];
                uchar g = reinterpret_cast<const uchar*>(src)[j * 3 + 1];
                uchar b = reinterpret_cast<const uchar*>(src)[j * 3 + 2];
                uchar a = 0xFF;

                dst[j] = D3DCOLOR_ARGB(a, r, g, b);
            }

            dst += rect.Pitch / sizeof(ulong);
            src = reinterpret_cast<const ulong*>
                  (reinterpret_cast<const uchar*>(src) +
                   static_cast<int>(buffer_size.d_width) * 3);
        }
    }

    d_texture->UnlockRect(0);
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::saveToMemory(void* buffer)
{
    // TODO:
    CEGUI_THROW(RendererException(
        "Direct3D9Texture::saveToMemory - Unimplemented!"));
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::cleanupDirect3D9Texture()
{
    if (d_texture)
    {
        d_texture->Release();
        d_texture = 0;
    }
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::updateCachedScaleValues()
{
    //
    // calculate what to use for x scale
    //
    const float orgW = d_dataSize.d_width;
    const float texW = d_size.d_width;

    // if texture and original data width are the same, scale is based
    // on the original size.
    // if texture is wider (and source data was not stretched), scale
    // is based on the size of the resulting texture.
    d_texelScaling.d_x = 1.0f / ((orgW == texW) ? orgW : texW);

    //
    // calculate what to use for y scale
    //
    const float orgH = d_dataSize.d_height;
    const float texH = d_size.d_height;

    // if texture and original data height are the same, scale is based
    // on the original size.
    // if texture is taller (and source data was not stretched), scale
    // is based on the size of the resulting texture.
    d_texelScaling.d_y = 1.0f / ((orgH == texH) ? orgH : texH);
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::updateTextureSize()
{
    D3DSURFACE_DESC surfDesc;

    // obtain details of the size of the texture
    if (d_texture && SUCCEEDED(d_texture->GetLevelDesc(0, &surfDesc)))
    {
        d_size.d_width  = static_cast<float>(surfDesc.Width);
        d_size.d_height = static_cast<float>(surfDesc.Height);
    }
    // use the original size if query failed.
    // NB: This should probably be an exception.
    else
        d_size = d_dataSize;
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::setOriginalDataSize(const Size& sz)
{
    d_dataSize = sz;
    updateCachedScaleValues();
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::preD3DReset()
{
    // if already saved surface info, or we have no texture, do nothing
    if (d_savedSurfaceDescValid || !d_texture)
        return;

    // get info about our texture
    d_texture->GetLevelDesc(0, &d_savedSurfaceDesc);

    // if texture is managed, we have nothing more to do
    if (d_savedSurfaceDesc.Pool == D3DPOOL_MANAGED)
        return;

    // otherwise release texture.
    d_texture->Release();
    d_texture = 0;
    d_savedSurfaceDescValid = true;
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::postD3DReset()
{
    // if texture has no saved surface info, we do nothing.
    if (!d_savedSurfaceDescValid)
        return;

    // otherwise, create a new texture using saved details.
    d_owner.getDevice()->
        CreateTexture(d_savedSurfaceDesc.Width,
                      d_savedSurfaceDesc.Height,
                      1, d_savedSurfaceDesc.Usage, d_savedSurfaceDesc.Format,
                      d_savedSurfaceDesc.Pool, &d_texture, 0);

    d_savedSurfaceDescValid = false;
}

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

} // End of  CEGUI namespace section
<commit_msg>ADD: Implement Direct3D9Texture::saveToMemory (backported impl from default)<commit_after>/***********************************************************************
    filename:   CEGUIDirect3D9Texture.cpp
    created:    Mon Feb 9 2009
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   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.
 ***************************************************************************/
#define NOMINMAX
#include <d3dx9.h>
#include "CEGUIDirect3D9Texture.h"
#include "CEGUIExceptions.h"
#include "CEGUISystem.h"
#include "CEGUIImageCodec.h"

// Start of CEGUI namespace section
namespace CEGUI
{
//----------------------------------------------------------------------------//
// Internal helper class to wrap the internal handling needed to copy from a
// D3D9 texture.
class D3DSurfaceBlitter
{
public:
    //------------------------------------------------------------------------//
    D3DSurfaceBlitter(LPDIRECT3DDEVICE9 d3d_device, LPDIRECT3DTEXTURE9 tex) :
        d_device(d3d_device),
        d_texture(tex),
        d_renderTarget(0),
        d_offscreen(0)
    {
        populateTextureSurfaceDescription();
    }

    //------------------------------------------------------------------------//
    ~D3DSurfaceBlitter()
    {
        cleanupSurfaces();
    }

    //------------------------------------------------------------------------//
    void blitToMemory(uint32* dest)
    {
        if (!d_texture)
            return;

        lockRect(0, true);

        blitD3DCOLORSurfaceToRGBA(
            static_cast<uint32*>(d_lockedRect.pBits), dest,
            Size(static_cast<float>(d_surfDesc.Width),
                 static_cast<float>(d_surfDesc.Height)),
            d_lockedRect.Pitch);

        unlockRect();
    }

    //------------------------------------------------------------------------//
    bool isRenderTarget() const
    {
        return d_surfDesc.Usage == D3DUSAGE_RENDERTARGET;
    }

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

private:
    LPDIRECT3DDEVICE9 d_device;
    LPDIRECT3DTEXTURE9 d_texture;
    LPDIRECT3DSURFACE9 d_renderTarget;
    LPDIRECT3DSURFACE9 d_offscreen;
    D3DSURFACE_DESC d_surfDesc;
    D3DLOCKED_RECT d_lockedRect;
    RECT d_fullArea;

    //------------------------------------------------------------------------//
    void initialiseSurfaces()
    {
        if (!d_offscreen)
            createOffscreenSurface();

        if (!d_renderTarget)
            getTextureSurface();
    }

    //------------------------------------------------------------------------//
    void cleanupSurfaces()
    {
        if (d_renderTarget)
        {
            d_renderTarget->Release();
            d_renderTarget = 0;
        }

        if (d_offscreen)
        {
            d_offscreen->Release();
            d_offscreen = 0;
        }
    }

    //------------------------------------------------------------------------//
    void lockRect(RECT* area = 0, bool for_reading = false)
    {
        if (isRenderTarget())
        {
            initialiseSurfaces();

            if (for_reading)
                getRenderTargetData();

            lockSurfaceRect(area);
        }
        else
        {
            lockTextureRect(area);
        }
    }

    //------------------------------------------------------------------------//
    void unlockRect(RECT* area = 0, bool needs_update = false)
    {
        if (isRenderTarget())
        {
            d_offscreen->UnlockRect();

            if (needs_update)
                updateRenderTarget(area);
        }
        else
            d_texture->UnlockRect(0);
    }

    //------------------------------------------------------------------------//
    void populateTextureSurfaceDescription()
    {
        if (FAILED(d_texture->GetLevelDesc(0, &d_surfDesc)))
            CEGUI_THROW(RendererException(
                "IDirect3DTexture9::GetLevelDesc failed."));

        d_fullArea.left = 0;
        d_fullArea.top = 0;
        d_fullArea.right = d_surfDesc.Width;
        d_fullArea.bottom = d_surfDesc.Height;
    }

    //------------------------------------------------------------------------//
    void createOffscreenSurface()
    {
        if (FAILED(d_device->CreateOffscreenPlainSurface(
            d_surfDesc.Width, d_surfDesc.Height, d_surfDesc.Format,
            D3DPOOL_SYSTEMMEM, &d_offscreen, 0)))
        {
            CEGUI_THROW(RendererException(
                "IDirect3DDevice9::CreateOffscreenPlainSurface failed."));
        }
    }

    //------------------------------------------------------------------------//
    void getTextureSurface()
    {
        if (FAILED(d_texture->GetSurfaceLevel(0, &d_renderTarget)))
            CEGUI_THROW(RendererException(
                "IDirect3DTexture9::GetSurfaceLevel failed."));
    }

    //------------------------------------------------------------------------//
    void lockSurfaceRect(RECT* area)
    {
        if (FAILED(d_offscreen->LockRect(&d_lockedRect, area, 0)))
            CEGUI_THROW(RendererException(
                "IDirect3DSurface9::LockRect failed."));
    }

    //------------------------------------------------------------------------//
    void lockTextureRect(RECT* area)
    {
        if (FAILED(d_texture->LockRect(0, &d_lockedRect, area, 0)))
            CEGUI_THROW(RendererException(
                "IDirect3DTexture9::LockRect failed."));
    }

    //------------------------------------------------------------------------//
    void updateRenderTarget(RECT* area)
    {
        POINT pt = {area ? area->left : 0, area ? area->top : 0};
        if (FAILED(d_device->UpdateSurface(d_offscreen,
                                           area ? area : &d_fullArea,
                                           d_renderTarget, &pt)))
        {
            CEGUI_THROW(RendererException(
                "IDirect3DDevice9::UpdateSurface failed."));
        }
    }

    //------------------------------------------------------------------------//
    void getRenderTargetData()
    {
        if (FAILED(d_device->GetRenderTargetData(d_renderTarget, d_offscreen)))
            CEGUI_THROW(RendererException(
                "IDirect3DDevice9::GetRenderTargetData failed."));
    }

    //------------------------------------------------------------------------//
    static void blitD3DCOLORSurfaceToRGBA(const uint32* src, uint32* dst,
                                          const Size& sz, size_t source_pitch)
    {
        for (uint i = 0; i < sz.d_height; ++i)
        {
            for (uint j = 0; j < sz.d_width; ++j)
            {
                const uint32 pixel = src[j];
                const uint32 tmp = pixel & 0x00FF00FF;
                dst[j] = pixel & 0xFF00FF00 | (tmp << 16) | (tmp >> 16);
            }

            src += source_pitch / sizeof(uint32);
            dst += static_cast<uint32>(sz.d_width);
        }
    }
};

//----------------------------------------------------------------------------//
Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner) :
    d_owner(owner),
    d_texture(0),
    d_size(0, 0),
    d_dataSize(0, 0),
    d_texelScaling(0, 0),
    d_savedSurfaceDescValid(false)
{
}

//----------------------------------------------------------------------------//
Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner,
                                   const String& filename,
                                   const String& resourceGroup) :
    d_owner(owner),
    d_texture(0),
    d_size(0, 0),
    d_dataSize(0, 0),
    d_texelScaling(0, 0),
    d_savedSurfaceDescValid(false)
{
    loadFromFile(filename, resourceGroup);
}

//----------------------------------------------------------------------------//
Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner, const Size& sz) :
    d_owner(owner),
    d_texture(0),
    d_size(0, 0),
    d_dataSize(sz),
    d_texelScaling(0, 0),
    d_savedSurfaceDescValid(false)
{
    Size tex_sz(d_owner.getAdjustedSize(sz));

    HRESULT hr = D3DXCreateTexture(d_owner.getDevice(),
                                   static_cast<UINT>(tex_sz.d_width),
                                   static_cast<UINT>(tex_sz.d_height),
                                   1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
                                   &d_texture);

    if (FAILED(hr))
        CEGUI_THROW(RendererException(
            "Direct3D9Texture - Failed to create texture of specified size: "
            "D3D Texture creation failed."));

    updateTextureSize();
    updateCachedScaleValues();
}

//----------------------------------------------------------------------------//
Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner,
                                   LPDIRECT3DTEXTURE9 tex) :
    d_owner(owner),
    d_texture(0),
    d_size(0, 0),
    d_dataSize(0, 0),
    d_texelScaling(0, 0),
    d_savedSurfaceDescValid(false)
{
    setDirect3D9Texture(tex);
}

//----------------------------------------------------------------------------//
Direct3D9Texture::~Direct3D9Texture()
{
    cleanupDirect3D9Texture();
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::setDirect3D9Texture(LPDIRECT3DTEXTURE9 tex)
{
    if (d_texture != tex)
    {
        cleanupDirect3D9Texture();
        d_dataSize.d_width = d_dataSize.d_height = 0;

        d_texture = tex;
        if (d_texture)
            d_texture->AddRef();
    }

    updateTextureSize();
    d_dataSize = d_size;
    updateCachedScaleValues();
}

//----------------------------------------------------------------------------//
LPDIRECT3DTEXTURE9 Direct3D9Texture::getDirect3D9Texture() const
{
    return d_texture;
}

//----------------------------------------------------------------------------//
const Size& Direct3D9Texture::getSize() const
{
    return d_size;
}

//----------------------------------------------------------------------------//
const Size& Direct3D9Texture::getOriginalDataSize() const
{
    return d_dataSize;
}

//----------------------------------------------------------------------------//
const Vector2& Direct3D9Texture::getTexelScaling() const
{
    return d_texelScaling;
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::loadFromFile(const String& filename,
                                    const String& resourceGroup)
{
    // get and check existence of CEGUI::System object
    System* sys = System::getSingletonPtr();
    if (!sys)
        CEGUI_THROW(RendererException("Direct3D9Texture::loadFromFile - "
            "CEGUI::System object has not been created!"));

    // load file to memory via resource provider
    RawDataContainer texFile;
    sys->getResourceProvider()->loadRawDataContainer(filename, texFile,
            resourceGroup);

    Texture* res = sys->getImageCodec().load(texFile, this);

    // unload file data buffer
    sys->getResourceProvider()->unloadRawDataContainer(texFile);

    if (!res)
        // It's an error
        CEGUI_THROW(RendererException("Direct3D9Texture::loadFromFile - " +
            sys->getImageCodec().getIdentifierString() +
            " failed to load image '" + filename + "'."));
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::loadFromMemory(const void* buffer,
                                      const Size& buffer_size,
                                      PixelFormat pixel_format)
{
    cleanupDirect3D9Texture();

    // create a texture
    // TODO: Check resulting pixel format and react appropriately.
    D3DFORMAT pixfmt;
    switch (pixel_format)
    {
    case PF_RGB:
        pixfmt = D3DFMT_R8G8B8;
        break;
    case PF_RGBA:
        pixfmt = D3DFMT_A8B8G8R8;
        break;
    default:
        CEGUI_THROW(RendererException("Direct3D9Texture::loadFromMemory failed: "
            "Invalid PixelFormat value specified."));
    }

    Size tex_sz(d_owner.getAdjustedSize(buffer_size));

    HRESULT hr = D3DXCreateTexture(d_owner.getDevice(),
                                   static_cast<UINT>(tex_sz.d_width),
                                   static_cast<UINT>(tex_sz.d_height),
                                   1, 0, pixfmt, D3DPOOL_MANAGED, &d_texture);

    if (FAILED(hr))
        CEGUI_THROW(RendererException("Direct3D9Texture::loadFromMemory failed: "
            "Direct3D9 texture creation failed."));

    d_dataSize = buffer_size;
    updateTextureSize();
    updateCachedScaleValues();

    // lock the D3D texture
    D3DLOCKED_RECT rect;
    hr = d_texture->LockRect(0, &rect, 0, 0);

    if (FAILED(hr))
    {
        d_texture->Release();
        d_texture = 0;

        CEGUI_THROW(RendererException("Direct3D9Texture::loadFromMemory failed: "
            "IDirect3DTexture9::LockRect failed."));
    }

    // copy data from buffer into texture
    ulong* dst = static_cast<ulong*>(rect.pBits);
    const ulong* src = static_cast<const ulong*>(buffer);

    // RGBA
    if (pixel_format == PF_RGBA)
    {
        for (uint i = 0; i < buffer_size.d_height; ++i)
        {
            for (uint j = 0; j < buffer_size.d_width; ++j)
            {
                // we dont need endian safety on microsoft
                uchar r = static_cast<uchar>(src[j] & 0xFF);
                uchar g = static_cast<uchar>((src[j] >> 8) & 0xFF);
                uchar b = static_cast<uchar>((src[j] >> 16)  & 0xFF);
                uchar a = static_cast<uchar>((src[j] >> 24) & 0xFF);

                dst[j] = D3DCOLOR_ARGB(a, r, g, b);
            }

            dst += rect.Pitch / sizeof(ulong);
            src += static_cast<ulong>(buffer_size.d_width);
        }
    }
    // RGB
    else
    {
        for (uint i = 0; i < buffer_size.d_height; ++i)
        {
            for (uint j = 0; j < buffer_size.d_width; ++j)
            {
                uchar r = reinterpret_cast<const uchar*>(src)[j * 3];
                uchar g = reinterpret_cast<const uchar*>(src)[j * 3 + 1];
                uchar b = reinterpret_cast<const uchar*>(src)[j * 3 + 2];
                uchar a = 0xFF;

                dst[j] = D3DCOLOR_ARGB(a, r, g, b);
            }

            dst += rect.Pitch / sizeof(ulong);
            src = reinterpret_cast<const ulong*>
                  (reinterpret_cast<const uchar*>(src) +
                   static_cast<int>(buffer_size.d_width) * 3);
        }
    }

    d_texture->UnlockRect(0);
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::saveToMemory(void* buffer)
{
    D3DSurfaceBlitter blitter(d_owner.getDevice(), d_texture);
    blitter.blitToMemory(static_cast<uint32*>(buffer));
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::cleanupDirect3D9Texture()
{
    if (d_texture)
    {
        d_texture->Release();
        d_texture = 0;
    }
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::updateCachedScaleValues()
{
    //
    // calculate what to use for x scale
    //
    const float orgW = d_dataSize.d_width;
    const float texW = d_size.d_width;

    // if texture and original data width are the same, scale is based
    // on the original size.
    // if texture is wider (and source data was not stretched), scale
    // is based on the size of the resulting texture.
    d_texelScaling.d_x = 1.0f / ((orgW == texW) ? orgW : texW);

    //
    // calculate what to use for y scale
    //
    const float orgH = d_dataSize.d_height;
    const float texH = d_size.d_height;

    // if texture and original data height are the same, scale is based
    // on the original size.
    // if texture is taller (and source data was not stretched), scale
    // is based on the size of the resulting texture.
    d_texelScaling.d_y = 1.0f / ((orgH == texH) ? orgH : texH);
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::updateTextureSize()
{
    D3DSURFACE_DESC surfDesc;

    // obtain details of the size of the texture
    if (d_texture && SUCCEEDED(d_texture->GetLevelDesc(0, &surfDesc)))
    {
        d_size.d_width  = static_cast<float>(surfDesc.Width);
        d_size.d_height = static_cast<float>(surfDesc.Height);
    }
    // use the original size if query failed.
    // NB: This should probably be an exception.
    else
        d_size = d_dataSize;
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::setOriginalDataSize(const Size& sz)
{
    d_dataSize = sz;
    updateCachedScaleValues();
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::preD3DReset()
{
    // if already saved surface info, or we have no texture, do nothing
    if (d_savedSurfaceDescValid || !d_texture)
        return;

    // get info about our texture
    d_texture->GetLevelDesc(0, &d_savedSurfaceDesc);

    // if texture is managed, we have nothing more to do
    if (d_savedSurfaceDesc.Pool == D3DPOOL_MANAGED)
        return;

    // otherwise release texture.
    d_texture->Release();
    d_texture = 0;
    d_savedSurfaceDescValid = true;
}

//----------------------------------------------------------------------------//
void Direct3D9Texture::postD3DReset()
{
    // if texture has no saved surface info, we do nothing.
    if (!d_savedSurfaceDescValid)
        return;

    // otherwise, create a new texture using saved details.
    d_owner.getDevice()->
        CreateTexture(d_savedSurfaceDesc.Width,
                      d_savedSurfaceDesc.Height,
                      1, d_savedSurfaceDesc.Usage, d_savedSurfaceDesc.Format,
                      d_savedSurfaceDesc.Pool, &d_texture, 0);

    d_savedSurfaceDescValid = false;
}

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

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


<commit_before>// Copyright 2014 The Chromium 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/ozone/platform/dri/dri_cursor.h"

#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/ozone/platform/dri/dri_gpu_platform_support_host.h"
#include "ui/ozone/platform/dri/dri_window.h"
#include "ui/ozone/platform/dri/dri_window_manager.h"

#if defined(OS_CHROMEOS)
#include "ui/events/ozone/chromeos/cursor_controller.h"
#endif

namespace ui {

DriCursor::DriCursor(DriWindowManager* window_manager,
                     DriGpuPlatformSupportHost* sender)
    : window_manager_(window_manager),
      sender_(sender),
      cursor_window_(gfx::kNullAcceleratedWidget) {
}

DriCursor::~DriCursor() {
}

void DriCursor::SetCursor(gfx::AcceleratedWidget widget,
                          PlatformCursor platform_cursor) {
  DCHECK_NE(widget, gfx::kNullAcceleratedWidget);
  scoped_refptr<BitmapCursorOzone> cursor =
      BitmapCursorFactoryOzone::GetBitmapCursor(platform_cursor);
  if (cursor_ == cursor || cursor_window_ != widget)
    return;

  cursor_ = cursor;

  ShowCursor();
}

void DriCursor::ShowCursor() {
  DCHECK_NE(cursor_window_, gfx::kNullAcceleratedWidget);
  if (cursor_.get())
    sender_->SetHardwareCursor(cursor_window_, cursor_->bitmaps(),
                               bitmap_location(), cursor_->frame_delay_ms());
  else
    HideCursor();
}

void DriCursor::HideCursor() {
  DCHECK_NE(cursor_window_, gfx::kNullAcceleratedWidget);
  sender_->SetHardwareCursor(cursor_window_, std::vector<SkBitmap>(),
                             gfx::Point(), 0);
}

void DriCursor::MoveCursorTo(gfx::AcceleratedWidget widget,
                             const gfx::PointF& location) {
  if (widget != cursor_window_ && cursor_window_ != gfx::kNullAcceleratedWidget)
    HideCursor();

  DriWindow* window = window_manager_->GetWindow(widget);

  cursor_window_ = widget;
  cursor_location_ = location;
  cursor_display_bounds_ = window->GetBounds();

  const gfx::Size& size = cursor_display_bounds_.size();
  cursor_location_.SetToMax(gfx::PointF(0, 0));
  // Right and bottom edges are exclusive.
  cursor_location_.SetToMin(gfx::PointF(size.width() - 1, size.height() - 1));

  if (cursor_.get())
    sender_->MoveHardwareCursor(cursor_window_, bitmap_location());
}

void DriCursor::MoveCursorTo(const gfx::PointF& location) {
  DriWindow* window =
      window_manager_->GetWindowAt(gfx::ToFlooredPoint(location));
  if (!window)
    return;

  MoveCursorTo(window->GetAcceleratedWidget(),
               location - window->GetBounds().OffsetFromOrigin());
}

void DriCursor::MoveCursor(const gfx::Vector2dF& delta) {
  if (cursor_window_ == gfx::kNullAcceleratedWidget)
    return;

#if defined(OS_CHROMEOS)
  gfx::Vector2dF transformed_delta = delta;
  ui::CursorController::GetInstance()->ApplyCursorConfigForWindow(
      cursor_window_, &transformed_delta);
  MoveCursorTo(cursor_window_, cursor_location_ + transformed_delta);
#else
  MoveCursorTo(cursor_window_, cursor_location_ + delta);
#endif
}

gfx::Rect DriCursor::GetCursorDisplayBounds() {
  return cursor_display_bounds_;
}

gfx::AcceleratedWidget DriCursor::GetCursorWindow() {
  return cursor_window_;
}

void DriCursor::Reset() {
  cursor_window_ = gfx::kNullAcceleratedWidget;
  cursor_ = nullptr;
}

bool DriCursor::IsCursorVisible() {
  return cursor_.get();
}

gfx::PointF DriCursor::GetLocation() {
  return cursor_location_ + cursor_display_bounds_.OffsetFromOrigin();
}

gfx::Point DriCursor::bitmap_location() {
  return gfx::ToFlooredPoint(cursor_location_) -
         cursor_->hotspot().OffsetFromOrigin();
}

}  // namespace ui
<commit_msg>[Ozone-Dri] Show the cursor when warping to a new display<commit_after>// Copyright 2014 The Chromium 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/ozone/platform/dri/dri_cursor.h"

#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/ozone/platform/dri/dri_gpu_platform_support_host.h"
#include "ui/ozone/platform/dri/dri_window.h"
#include "ui/ozone/platform/dri/dri_window_manager.h"

#if defined(OS_CHROMEOS)
#include "ui/events/ozone/chromeos/cursor_controller.h"
#endif

namespace ui {

DriCursor::DriCursor(DriWindowManager* window_manager,
                     DriGpuPlatformSupportHost* sender)
    : window_manager_(window_manager),
      sender_(sender),
      cursor_window_(gfx::kNullAcceleratedWidget) {
}

DriCursor::~DriCursor() {
}

void DriCursor::SetCursor(gfx::AcceleratedWidget widget,
                          PlatformCursor platform_cursor) {
  DCHECK_NE(widget, gfx::kNullAcceleratedWidget);
  scoped_refptr<BitmapCursorOzone> cursor =
      BitmapCursorFactoryOzone::GetBitmapCursor(platform_cursor);
  if (cursor_ == cursor || cursor_window_ != widget)
    return;

  cursor_ = cursor;

  ShowCursor();
}

void DriCursor::ShowCursor() {
  DCHECK_NE(cursor_window_, gfx::kNullAcceleratedWidget);
  if (cursor_.get())
    sender_->SetHardwareCursor(cursor_window_, cursor_->bitmaps(),
                               bitmap_location(), cursor_->frame_delay_ms());
  else
    HideCursor();
}

void DriCursor::HideCursor() {
  DCHECK_NE(cursor_window_, gfx::kNullAcceleratedWidget);
  sender_->SetHardwareCursor(cursor_window_, std::vector<SkBitmap>(),
                             gfx::Point(), 0);
}

void DriCursor::MoveCursorTo(gfx::AcceleratedWidget widget,
                             const gfx::PointF& location) {
  // When moving between windows hide the cursor on the current window then show
  // it on the new window.
  bool changing_window =
      widget != cursor_window_ && cursor_window_ != gfx::kNullAcceleratedWidget;

  if (changing_window)
    HideCursor();

  DriWindow* window = window_manager_->GetWindow(widget);

  cursor_window_ = widget;
  cursor_location_ = location;
  cursor_display_bounds_ = window->GetBounds();

  const gfx::Size& size = cursor_display_bounds_.size();
  cursor_location_.SetToMax(gfx::PointF(0, 0));
  // Right and bottom edges are exclusive.
  cursor_location_.SetToMin(gfx::PointF(size.width() - 1, size.height() - 1));

  if (cursor_.get()) {
    if (changing_window)
      ShowCursor();
    else
      sender_->MoveHardwareCursor(cursor_window_, bitmap_location());
  }
}

void DriCursor::MoveCursorTo(const gfx::PointF& location) {
  DriWindow* window =
      window_manager_->GetWindowAt(gfx::ToFlooredPoint(location));
  if (!window)
    return;

  MoveCursorTo(window->GetAcceleratedWidget(),
               location - window->GetBounds().OffsetFromOrigin());
}

void DriCursor::MoveCursor(const gfx::Vector2dF& delta) {
  if (cursor_window_ == gfx::kNullAcceleratedWidget)
    return;

#if defined(OS_CHROMEOS)
  gfx::Vector2dF transformed_delta = delta;
  ui::CursorController::GetInstance()->ApplyCursorConfigForWindow(
      cursor_window_, &transformed_delta);
  MoveCursorTo(cursor_window_, cursor_location_ + transformed_delta);
#else
  MoveCursorTo(cursor_window_, cursor_location_ + delta);
#endif
}

gfx::Rect DriCursor::GetCursorDisplayBounds() {
  return cursor_display_bounds_;
}

gfx::AcceleratedWidget DriCursor::GetCursorWindow() {
  return cursor_window_;
}

void DriCursor::Reset() {
  cursor_window_ = gfx::kNullAcceleratedWidget;
  cursor_ = nullptr;
}

bool DriCursor::IsCursorVisible() {
  return cursor_.get();
}

gfx::PointF DriCursor::GetLocation() {
  return cursor_location_ + cursor_display_bounds_.OffsetFromOrigin();
}

gfx::Point DriCursor::bitmap_location() {
  return gfx::ToFlooredPoint(cursor_location_) -
         cursor_->hotspot().OffsetFromOrigin();
}

}  // namespace ui
<|endoftext|>


<commit_before><commit_msg>Use comphelper::SequenceAsHashMap<commit_after><|endoftext|>


<commit_before>#include "data-student.hpp"
using namespace std;

void Student::init(string n, int s, int g, string m) {
	name = n;
	startingYear = s;
	gradutationYear = g;
	parseMajors(m);
}

Student::Student() {
	init("", 2000, 2004, "");
}
Student::Student(string n, string s, string e, string m) {
	int startYear = stringToInt(s), endYear = stringToInt(e);
	init(n, startYear, endYear, m);
}

Student::Student(string fn) {
	string n, yearS, yearE, m, conc, c;
	ifstream infile(fn.c_str());
	string nextLine;
	vector<string> lines;

	// load the entire file
	while (infile.peek() != -1) {
		getline(infile, nextLine);
		lines.push_back(nextLine);
	}

	string previousHeading;
	for (vector<string>::iterator i = lines.begin(); i != lines.end(); ++i) {
		string str = *i;
		if (str[0] == '#') {
			previousHeading = *i;
			continue;
		}

		if (str != "") {
			if (previousHeading == "# NAME")
				n = str;
			else if (previousHeading == "# MAJORS")
				addMajor(Major(str));
			else if (previousHeading == "# CONCENTRATIONS")
				addMajor(Major(str));
			else if (previousHeading == "# COURSES")
				addCourse(Course(str));
		}
	}
}

void Student::addMajor(const Major& m) {
	majors.push_back(m);
}

void Student::addMajors(string str) {
	vector<string> record = split(str, ',');
	for (vector<string>::iterator i = record.begin(); i != record.end(); ++i)
		addMajor(*i);
}

void Student::addCourse(const Course& c) {
	courses.push_back(c);
}

void Student::addCourses(string str) {
	vector<string> record = split(str, ',');
	for (vector<string>::iterator i = record.begin(); i != record.end(); ++i)
		addCourse(Course(*i));
}

bool Student::hasTakenCourse(string str) {
	bool userHasTaken = false;
	Course checkAgainst = getCourse(str);
	for (std::vector<Course>::iterator i = courses.begin(); i != courses.end(); ++i)
		if (*i == checkAgainst)
			userHasTaken = true;
	return userHasTaken;
}

ostream& Student::getData(ostream &os) {
	os << name << ", ";
	os << "you are majoring in ";
	for (vector<Major>::iterator i = majors.begin(); i != majors.end(); ++i){
		if (majors.size() == 2) {
			if (i != majors.end()-1)
				os << *i << " and ";
			else
				os << *i << " ";
		}
		else {
			if (i != majors.end()-1)
				os << *i << ", ";
			else
				os << "and " << *i << ", ";
		}
	}
	os << "while taking:" << endl;
	for (vector<Course>::iterator i = courses.begin(); i != courses.end(); ++i)
		os << *i << endl;
	return os;
}

void Student::display() {
	cout << *this << endl;
};

ostream& operator<<(ostream& os, Student& item) {
	os << item.getData(os);
	return os;
}
<commit_msg>Change a place to addMajors<commit_after>#include "data-student.hpp"
using namespace std;

void Student::init(string n, int s, int g, string m) {
	name = n;
	startingYear = s;
	gradutationYear = g;
	addMajors(m);
}

Student::Student() {
	init("", 2000, 2004, "");
}
Student::Student(string n, string s, string e, string m) {
	int startYear = stringToInt(s), endYear = stringToInt(e);
	init(n, startYear, endYear, m);
}

Student::Student(string fn) {
	string n, yearS, yearE, m, conc, c;
	ifstream infile(fn.c_str());
	string nextLine;
	vector<string> lines;

	// load the entire file
	while (infile.peek() != -1) {
		getline(infile, nextLine);
		lines.push_back(nextLine);
	}

	string previousHeading;
	for (vector<string>::iterator i = lines.begin(); i != lines.end(); ++i) {
		string str = *i;
		if (str[0] == '#') {
			previousHeading = *i;
			continue;
		}

		if (str != "") {
			if (previousHeading == "# NAME")
				n = str;
			else if (previousHeading == "# MAJORS")
				addMajor(Major(str));
			else if (previousHeading == "# CONCENTRATIONS")
				addMajor(Major(str));
			else if (previousHeading == "# COURSES")
				addCourse(Course(str));
		}
	}
}

void Student::addMajor(const Major& m) {
	majors.push_back(m);
}

void Student::addMajors(string str) {
	vector<string> record = split(str, ',');
	for (vector<string>::iterator i = record.begin(); i != record.end(); ++i)
		addMajor(*i);
}

void Student::addCourse(const Course& c) {
	courses.push_back(c);
}

void Student::addCourses(string str) {
	vector<string> record = split(str, ',');
	for (vector<string>::iterator i = record.begin(); i != record.end(); ++i)
		addCourse(Course(*i));
}

bool Student::hasTakenCourse(string str) {
	bool userHasTaken = false;
	Course checkAgainst = getCourse(str);
	for (std::vector<Course>::iterator i = courses.begin(); i != courses.end(); ++i)
		if (*i == checkAgainst)
			userHasTaken = true;
	return userHasTaken;
}

ostream& Student::getData(ostream &os) {
	os << name << ", ";
	os << "you are majoring in ";
	for (vector<Major>::iterator i = majors.begin(); i != majors.end(); ++i){
		if (majors.size() == 2) {
			if (i != majors.end()-1)
				os << *i << " and ";
			else
				os << *i << " ";
		}
		else {
			if (i != majors.end()-1)
				os << *i << ", ";
			else
				os << "and " << *i << ", ";
		}
	}
	os << "while taking:" << endl;
	for (vector<Course>::iterator i = courses.begin(); i != courses.end(); ++i)
		os << *i << endl;
	return os;
}

void Student::display() {
	cout << *this << endl;
};

ostream& operator<<(ostream& os, Student& item) {
	os << item.getData(os);
	return os;
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <cmath>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <thread>
#include "Model/MDLAModel.h"
#include "Color/CIE1931.h"
#include "Color/SRGB.h"
#include "Task/TaskScheduler.h"
#include "Task/TraceTask.h"
#include "ImageUpdater.h"
#include "Ray.h"
#include "SPTracer.h"

namespace SPTracer {

	SPTracer::SPTracer(std::string fileName, size_t numThreads, unsigned int width, unsigned int height)
		: width_(width), height_(height), numThreads_(numThreads)
	{
		// create model from file
		model_ = std::make_unique<MDLAModel>(std::move(fileName));

		// create task scheduler that will spawn threads
		taskScheduler_ = std::make_unique<TaskScheduler>(*this, numThreads);

		// prepare array of pixels
		pixels_.resize((width_ * height_) * 3);

		// wave length parameters
		waveLengthMin_ = 400.0f;
		waveLengthMax_ = 700.0f;
		waveLengthStep_ = 20.0f;

#ifdef _DEBUG
		waveLengthStep_ = 150.0f;
#endif

		waveLengthCount_ = static_cast<size_t>((waveLengthMax_ - waveLengthMin_) / waveLengthStep_) + 1;

		// color converter
		xyzConverter_ = std::make_unique<CIE1931>();

		// color system
		rgbConverter_ = std::make_unique<SRGB>();

	}

	SPTracer::~SPTracer()
	{
	}

	const Model& SPTracer::GetModel() const
	{
		return *model_;
	}

	const XYZConverter& SPTracer::GetXYZConverter() const
	{
		return *xyzConverter_;
	}

	TaskScheduler& SPTracer::GetTaskScheduler() const
	{
		return *taskScheduler_;
	}

	float SPTracer::GetWaveLengthMin() const
	{
		return waveLengthMin_;
	}

	float SPTracer::GetWaveLengthMax() const
	{
		return waveLengthMax_;
	}

	float SPTracer::GetWaveLengthStep() const
	{
		return waveLengthStep_;
	}

	size_t SPTracer::GetWaveLengthCount() const
	{
		return waveLengthCount_;
	}

	size_t SPTracer::GetCompletedSamplesCount() const
	{
		return completedSamplesCount_;
	}

	unsigned int SPTracer::GetWidth() const
	{
		return width_;
	}

	unsigned int SPTracer::GetHeight() const
	{
		return height_;
	}

	void SPTracer::Run()
	{
		// record start time
		start_ = std::chrono::high_resolution_clock::now();

		// add tasks to start sampling
		for (size_t i = 0; i < numThreads_; i++)
		{
			taskScheduler_->AddTask(std::make_unique<TraceTask>(*this));
		}
	}

	void SPTracer::AddSamples(std::vector<Vec3>& color)
	{
		// lock
		std::lock_guard<std::mutex> lock(mutex_);

		// for every pixel
		for (size_t i = 0; i < color.size(); i++)
		{
			pixels_[3 * i] += color[i].x;
			pixels_[3 * i + 1] += color[i].y;
			pixels_[3 * i + 2] += color[i].z;
		}

		// increase count of completed samples
		completedSamplesCount_++;

		// update image when all threads return samples
		static size_t samples = 0;
		samples++;
		if (samples == numThreads_)
		{
			// reset count
			samples = 0;

			// upadte image
			UpdateImage();
		}
	}

	void SPTracer::SetImageUpdater(std::shared_ptr<ImageUpdater> imageUpdater)
	{
		imageUpdater_ = std::move(imageUpdater);
	}

	float SPTracer::FindExposure(const std::vector<Vec3>& xyzColor) const
	{
		float n = static_cast<float>(width_ * height_);

		// Calculate the average intensity. Calculations are based
		// on the CIE Y component, which corresponds to lightness.
		float mean = std::accumulate(xyzColor.begin(), xyzColor.end(), 0.0f,
			[](float a, const Vec3& xyz) { return a + xyz.y; }) / n;

		// Then compute the standard deviation.
		float sqrMean = std::accumulate(xyzColor.begin(), xyzColor.end(), 0.0f,
			[](float a, const Vec3& xyz) { return a + xyz.y * xyz.y; }) / n;

		float variance = sqrMean - mean * mean;

		// The desired 'white' is one standard deviation above average
		return mean + std::sqrt(variance);
	}

	float SPTracer::Clamp(float c) const
	{
		return std::min(1.0f, std::max(0.0f, c));
	}

	std::vector<Vec3> SPTracer::Tonemap(const std::vector<Vec3>& xyzColor) const
	{
		float maxIntensity = FindExposure(xyzColor);
		std::vector<Vec3> rgbColor(xyzColor.size());

		for (size_t i = 0; i < xyzColor.size(); i++)
		{
			Vec3 xyz = xyzColor[i];
			Vec3& rgb = rgbColor[i];

			// Apply exposure correction
			xyz.x = std::log(xyz.x / maxIntensity + 1.0f) / std::log(4.0f);
			xyz.y = std::log(xyz.y / maxIntensity + 1.0f) / std::log(4.0f);
			xyz.z = std::log(xyz.z / maxIntensity + 1.0f) / std::log(4.0f);

			// Convert to sRGB.
			rgb = rgbConverter_->GetRGB(xyz);

			// Clamp colours to saturate.
			rgb.x = Clamp(rgb.x);
			rgb.y = Clamp(rgb.y);
			rgb.z = Clamp(rgb.z);
		}

		return rgbColor;
	}

	void SPTracer::UpdateImage()
	{
		if (imageUpdater_ == nullptr)
		{
			return;
		}

		// divide XYZ color in pixels on the number of samples
		double num = static_cast<double>(completedSamplesCount_ * waveLengthCount_);
		std::vector<Vec3> xyzColor;
		xyzColor.reserve(pixels_.size() / 3);
		for (size_t i = 0; i < xyzColor.size(); i++)
		{
			xyzColor.push_back(Vec3{
				static_cast<float>(pixels_[i * 3] / num),
				static_cast<float>(pixels_[i * 3 + 1] / num),
				static_cast<float>(pixels_[i * 3 + 2] / num)
			});
		}

		// tonemap XYZ to RGB
		std::vector<Vec3> rgbColor = Tonemap(xyzColor);

		// prepare title
		auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
			std::chrono::high_resolution_clock::now() - start_);
		size_t spp = completedSamplesCount_ * waveLengthCount_;
		float sps = (static_cast<float>(spp * width_ * height_) /
			(static_cast<float>(duration.count()) / 1000.0f));

		std::ostringstream oss;
		oss << FormatNumber(static_cast<float>(spp)) << " SPP, " << FormatNumber(sps) << " SPS" ;

		// call image updater
		imageUpdater_->UpdateImage(rgbColor, oss.str());
	}

	std::string SPTracer::FormatNumber(float n) const
	{
		std::ostringstream oss;
		if (n < 1e3f)
		{
			oss << static_cast<size_t>(n);
		}
		else
		{
			oss << std::setprecision(2) << std::fixed;
			if (n < 1e6f)
			{
				oss << n / 1e3f << "K";
			}
			else if (n <= 1e9f)
			{
				oss << n / 1e6f << "M";
			}
			else
			{
				oss << n / 1e9f << "B";
			}
		}

		return oss.str();
	}

}
<commit_msg>Fixed a bug when image array in SPTracer::UpdateImage() would not be filled with color data<commit_after>#include <algorithm>
#include <cmath>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <thread>
#include "Model/MDLAModel.h"
#include "Color/CIE1931.h"
#include "Color/SRGB.h"
#include "Task/TaskScheduler.h"
#include "Task/TraceTask.h"
#include "ImageUpdater.h"
#include "Ray.h"
#include "SPTracer.h"

namespace SPTracer {

	SPTracer::SPTracer(std::string fileName, size_t numThreads, unsigned int width, unsigned int height)
		: width_(width), height_(height), numThreads_(numThreads)
	{
		// create model from file
		model_ = std::make_unique<MDLAModel>(std::move(fileName));

		// create task scheduler that will spawn threads
		taskScheduler_ = std::make_unique<TaskScheduler>(*this, numThreads);

		// prepare array of pixels
		pixels_.resize((width_ * height_) * 3);

		// wave length parameters
		waveLengthMin_ = 400.0f;
		waveLengthMax_ = 700.0f;
		waveLengthStep_ = 20.0f;

#ifdef _DEBUG
		waveLengthStep_ = 150.0f;
#endif

		waveLengthCount_ = static_cast<size_t>((waveLengthMax_ - waveLengthMin_) / waveLengthStep_) + 1;

		// color converter
		xyzConverter_ = std::make_unique<CIE1931>();

		// color system
		rgbConverter_ = std::make_unique<SRGB>();

	}

	SPTracer::~SPTracer()
	{
	}

	const Model& SPTracer::GetModel() const
	{
		return *model_;
	}

	const XYZConverter& SPTracer::GetXYZConverter() const
	{
		return *xyzConverter_;
	}

	TaskScheduler& SPTracer::GetTaskScheduler() const
	{
		return *taskScheduler_;
	}

	float SPTracer::GetWaveLengthMin() const
	{
		return waveLengthMin_;
	}

	float SPTracer::GetWaveLengthMax() const
	{
		return waveLengthMax_;
	}

	float SPTracer::GetWaveLengthStep() const
	{
		return waveLengthStep_;
	}

	size_t SPTracer::GetWaveLengthCount() const
	{
		return waveLengthCount_;
	}

	size_t SPTracer::GetCompletedSamplesCount() const
	{
		return completedSamplesCount_;
	}

	unsigned int SPTracer::GetWidth() const
	{
		return width_;
	}

	unsigned int SPTracer::GetHeight() const
	{
		return height_;
	}

	void SPTracer::Run()
	{
		// record start time
		start_ = std::chrono::high_resolution_clock::now();

		// add tasks to start sampling
		for (size_t i = 0; i < numThreads_; i++)
		{
			taskScheduler_->AddTask(std::make_unique<TraceTask>(*this));
		}
	}

	void SPTracer::AddSamples(std::vector<Vec3>& color)
	{
		// lock
		std::lock_guard<std::mutex> lock(mutex_);

		// for every pixel
		for (size_t i = 0; i < color.size(); i++)
		{
			pixels_[3 * i] += color[i].x;
			pixels_[3 * i + 1] += color[i].y;
			pixels_[3 * i + 2] += color[i].z;
		}

		// increase count of completed samples
		completedSamplesCount_++;

		// update image when all threads return samples
		static size_t samples = 0;
		samples++;
		if (samples == numThreads_)
		{
			// reset count
			samples = 0;

			// upadte image
			UpdateImage();
		}
	}

	void SPTracer::SetImageUpdater(std::shared_ptr<ImageUpdater> imageUpdater)
	{
		imageUpdater_ = std::move(imageUpdater);
	}

	float SPTracer::FindExposure(const std::vector<Vec3>& xyzColor) const
	{
		float n = static_cast<float>(width_ * height_);

		// Calculate the average intensity. Calculations are based
		// on the CIE Y component, which corresponds to lightness.
		float mean = std::accumulate(xyzColor.begin(), xyzColor.end(), 0.0f,
			[](float a, const Vec3& xyz) { return a + xyz.y; }) / n;

		// Then compute the standard deviation.
		float sqrMean = std::accumulate(xyzColor.begin(), xyzColor.end(), 0.0f,
			[](float a, const Vec3& xyz) { return a + xyz.y * xyz.y; }) / n;

		float variance = sqrMean - mean * mean;

		// The desired 'white' is one standard deviation above average
		return mean + std::sqrt(variance);
	}

	float SPTracer::Clamp(float c) const
	{
		return std::min(1.0f, std::max(0.0f, c));
	}

	std::vector<Vec3> SPTracer::Tonemap(const std::vector<Vec3>& xyzColor) const
	{
		float maxIntensity = FindExposure(xyzColor);
		std::vector<Vec3> rgbColor(xyzColor.size());

		for (size_t i = 0; i < xyzColor.size(); i++)
		{
			Vec3 xyz = xyzColor[i];
			Vec3& rgb = rgbColor[i];

			// Apply exposure correction
			xyz.x = std::log(xyz.x / maxIntensity + 1.0f) / std::log(4.0f);
			xyz.y = std::log(xyz.y / maxIntensity + 1.0f) / std::log(4.0f);
			xyz.z = std::log(xyz.z / maxIntensity + 1.0f) / std::log(4.0f);

			// Convert to sRGB.
			rgb = rgbConverter_->GetRGB(xyz);

			// Clamp colours to saturate.
			rgb.x = Clamp(rgb.x);
			rgb.y = Clamp(rgb.y);
			rgb.z = Clamp(rgb.z);
		}

		return rgbColor;
	}

	void SPTracer::UpdateImage()
	{
		if (imageUpdater_ == nullptr)
		{
			return;
		}

		// divide XYZ color in pixels on the number of samples
		double num = static_cast<double>(completedSamplesCount_ * waveLengthCount_);
		std::vector<Vec3> xyzColor;
		xyzColor.reserve(pixels_.size() / 3);
		for (size_t i = 0; i < (pixels_.size() / 3); i++)
		{
			xyzColor.push_back(Vec3{
				static_cast<float>(pixels_[i * 3] / num),
				static_cast<float>(pixels_[i * 3 + 1] / num),
				static_cast<float>(pixels_[i * 3 + 2] / num)
			});
		}

		// tonemap XYZ to RGB
		std::vector<Vec3> rgbColor = Tonemap(xyzColor);

		// prepare title
		auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
			std::chrono::high_resolution_clock::now() - start_);
		size_t spp = completedSamplesCount_ * waveLengthCount_;
		float sps = (static_cast<float>(spp * width_ * height_) /
			(static_cast<float>(duration.count()) / 1000.0f));

		std::ostringstream oss;
		oss << FormatNumber(static_cast<float>(spp)) << " SPP, " << FormatNumber(sps) << " SPS" ;

		// call image updater
		imageUpdater_->UpdateImage(rgbColor, oss.str());
	}

	std::string SPTracer::FormatNumber(float n) const
	{
		std::ostringstream oss;
		if (n < 1e3f)
		{
			oss << static_cast<size_t>(n);
		}
		else
		{
			oss << std::setprecision(2) << std::fixed;
			if (n < 1e6f)
			{
				oss << n / 1e3f << "K";
			}
			else if (n <= 1e9f)
			{
				oss << n / 1e6f << "M";
			}
			else
			{
				oss << n / 1e9f << "B";
			}
		}

		return oss.str();
	}

}
<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Scott Moreau
 *
 * 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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <wayfire/core.hpp>
#include <wayfire/view.hpp>
#include <wayfire/plugin.hpp>
#include <wayfire/output.hpp>
#include "wayfire/view-transform.hpp"
#include "wayfire/workspace-manager.hpp"

class wayfire_alpha : public wf::plugin_interface_t
{
    wf::option_wrapper_t<wf::keybinding_t> modifier{"alpha/modifier"};
    wf::option_wrapper_t<double> min_value{"alpha/min_value"};

  public:
    void init() override
    {
        grab_interface->name = "alpha";
        grab_interface->capabilities = wf::CAPABILITY_MANAGE_DESKTOP;

        min_value.set_callback(min_value_changed);
        output->add_axis(modifier, &axis_cb);
    }

    void update_alpha(wayfire_view view, float delta)
    {
        wf::view_2D *transformer;
        float alpha;

        if (!view->get_transformer("alpha"))
        {
            view->add_transformer(std::make_unique<wf::view_2D>(view), "alpha");
        }

        transformer =
            dynamic_cast<wf::view_2D*>(view->get_transformer("alpha").get());
        alpha = transformer->alpha;

        alpha -= delta * 0.003;

        if (alpha > 1.0)
        {
            alpha = 1.0;
        }

        if (alpha == 1.0)
        {
            return view->pop_transformer("alpha");
        }

        alpha = std::max(alpha, (float)min_value);
        if (transformer->alpha != alpha)
        {
            transformer->alpha = alpha;
            view->damage();
        }
    }

    wf::axis_callback axis_cb = [=] (wlr_event_pointer_axis *ev)
    {
        if (!output->activate_plugin(grab_interface))
        {
            return false;
        }

        output->deactivate_plugin(grab_interface);

        auto view = wf::get_core().get_cursor_focus_view();
        if (!view)
        {
            return false;
        }

        auto layer = output->workspace->get_view_layer(view);

        if (layer == wf::LAYER_BACKGROUND)
        {
            return false;
        }

        if (ev->orientation == WLR_AXIS_ORIENTATION_VERTICAL)
        {
            update_alpha(view, ev->delta);

            return true;
        }

        return false;
    };

    wf::config::option_base_t::updated_callback_t min_value_changed = [=] ()
    {
        for (auto& view : output->workspace->get_views_in_layer(wf::ALL_LAYERS))
        {
            if (!view->get_transformer("alpha"))
            {
                continue;
            }

            wf::view_2D *transformer =
                dynamic_cast<wf::view_2D*>(view->get_transformer("alpha").get());

            if (transformer->alpha < min_value)
            {
                transformer->alpha = min_value;
                view->damage();
            }
        }
    };

    void fini() override
    {
        for (auto& view : output->workspace->get_views_in_layer(wf::ALL_LAYERS))
        {
            if (view->get_transformer("alpha"))
            {
                view->pop_transformer("alpha");
            }
        }

        output->rem_binding(&axis_cb);
    }
};

DECLARE_WAYFIRE_PLUGIN(wayfire_alpha);
<commit_msg>alpha: fix shutdown crashes<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Scott Moreau
 *
 * 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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <wayfire/core.hpp>
#include <wayfire/view.hpp>
#include <wayfire/plugin.hpp>
#include <wayfire/output.hpp>
#include "wayfire/view-transform.hpp"
#include "wayfire/workspace-manager.hpp"

class wayfire_alpha : public wf::plugin_interface_t
{
    wf::option_wrapper_t<wf::keybinding_t> modifier{"alpha/modifier"};
    wf::option_wrapper_t<double> min_value{"alpha/min_value"};

  public:
    void init() override
    {
        grab_interface->name = "alpha";
        grab_interface->capabilities = wf::CAPABILITY_MANAGE_DESKTOP;

        min_value.set_callback(min_value_changed);
        output->add_axis(modifier, &axis_cb);
    }

    void update_alpha(wayfire_view view, float delta)
    {
        wf::view_2D *transformer;
        float alpha;

        if (!view->get_transformer("alpha"))
        {
            view->add_transformer(std::make_unique<wf::view_2D>(view), "alpha");
        }

        transformer =
            dynamic_cast<wf::view_2D*>(view->get_transformer("alpha").get());
        alpha = transformer->alpha;

        alpha -= delta * 0.003;

        if (alpha > 1.0)
        {
            alpha = 1.0;
        }

        if (alpha == 1.0)
        {
            return view->pop_transformer("alpha");
        }

        alpha = std::max(alpha, (float)min_value);
        if (transformer->alpha != alpha)
        {
            transformer->alpha = alpha;
            view->damage();
        }
    }

    wf::axis_callback axis_cb = [=] (wlr_event_pointer_axis *ev)
    {
        if (!output->activate_plugin(grab_interface))
        {
            return false;
        }

        output->deactivate_plugin(grab_interface);

        auto view = wf::get_core().get_cursor_focus_view();
        if (!view)
        {
            return false;
        }

        auto layer = output->workspace->get_view_layer(view);

        if (layer == wf::LAYER_BACKGROUND)
        {
            return false;
        }

        if (ev->orientation == WLR_AXIS_ORIENTATION_VERTICAL)
        {
            update_alpha(view, ev->delta);

            return true;
        }

        return false;
    };

    wf::config::option_base_t::updated_callback_t min_value_changed = [=] ()
    {
        for (auto& view : output->workspace->get_views_in_layer(wf::ALL_LAYERS))
        {
            if (!view->get_transformer("alpha"))
            {
                continue;
            }

            wf::view_2D *transformer =
                dynamic_cast<wf::view_2D*>(view->get_transformer("alpha").get());

            if (transformer->alpha < min_value)
            {
                transformer->alpha = min_value;
                view->damage();
            }
        }
    };

    void fini() override
    {
        for (auto& view : wf::get_core().get_all_views())
        {
            if (!view->get_output() || (view->get_output() == output))
            {
                if (view->get_transformer("alpha"))
                {
                    view->pop_transformer("alpha");
                }
            }
        }

        output->rem_binding(&axis_cb);
    }
};

DECLARE_WAYFIRE_PLUGIN(wayfire_alpha);
<|endoftext|>


<commit_before>//
//  kern_disasm.hpp
//  Lilu
//
//  Copyright © 2016-2017 vit9696. All rights reserved.
//

#ifndef kern_disasm_hpp
#define kern_disasm_hpp

#include <Headers/kern_config.hpp>
#include <Headers/kern_util.hpp>
#include <Headers/capstone/capstone.h>

#include <sys/types.h>
#include <mach/vm_types.h>

class Disassembler {
	/**
	 *  Because captsone handle can be 0
	 */
	bool initialised {false};

	/**
	 *  Internal capstone handle
	 */
	size_t handle;

	/**
	 *  Max instruction size
	 */
	static constexpr size_t MaxInstruction {15};
public:

	/**
	 *  Initialise dissassembling framework
	 *
	 *  @param detailed  debugging output necessity
	 *
	 *  @return true on success
	 */
	EXPORT bool init(bool detailed=false);

	/**
	 *  Deinitialise dissassembling framework, must be called regardless of the init error
	 */
	EXPORT void deinit();

	/**
	 *  Return the real instruction size contained within min bytes
	 *  Unlike instructionSize this uses HDE engine and at the cost of reduced compatibility it is much faster
	 *
	 *  @param ptr instruction pointer
	 *  @param min minimal possible size
	 *
	 *  @return instruction size >= min on success or 0
	 */
	EXPORT static size_t quickInstructionSize(mach_vm_address_t ptr, size_t min);

	/**
	 *  Reads size bytes from addr and disassembles them.
	 *
	 *  @param addr        Address to read from
	 *  @param size        Size of buffer to read
	 *  @param result      Disassembled instructions array. You must free it
	 *
	 *  @return size of result
	 */
	EXPORT size_t disasmBuf(mach_vm_address_t addr, size_t size, cs_insn **result);

	/**
	 *  Return the real instruction size contained within min bytes
	 *
	 *  @param ptr instruction pointer
	 *  @param min minimal possible size
	 *
	 *  @return instruction size >= min on success or 0
	 */
	EXPORT size_t instructionSize(mach_vm_address_t ptr, size_t min);

	/**
	 *  Reads lookup_size bytes from addr and disassembles them.
	 *  After disassembling, tries to find num-th entry with call instruction, which argument is an immediate value (some address).
	 *
	 *  @param addr        Address to read from
	 *  @param num         Number of call instruction to search for
	 *  @param lookup_size Number of bytes to read
	 *
	 *  @note It is assumed that the operand contains a positive relative address.
	 *
	 *  @return direct address of num-th call instruction on success, else 0
	 */
	EXPORT mach_vm_address_t disasmNthSub(mach_vm_address_t addr, size_t num, size_t lookup_size);

	/**
	 *  @brief  Reads lookup_size bytes from addr and disassembles them.
	 *
	 *  After disassembling, tries to find num-th entry with jmp instruction, which argument is an immediate value (some address).
	 *
	 *  @param addr        Address to read from
	 *  @param num         Number of jmp instruction to search for
	 *  @param lookup_size Number of bytes to read
	 *
	 *  @note It is assumed that the operand contains a positive relative address.
	 *
	 *  @return direct address of num-th jmp instruction on success, else 0
	 */
	EXPORT mach_vm_address_t disasmNthJmp(mach_vm_address_t addr, size_t num, size_t lookup_size);

	/**
	 *  Reads lookup_size bytes from addr and disassembles them.
	 *  After disassembling, tries to find num-th entry of inst instruction.
	 *
	 *  @param addr        Addres to read from
	 *  @param ins         Instruction code
	 *  @param num         Number of ins instruction to search for
	 *  @param lookup_size Number of bytes to read
	 *
	 *  @return address of found instruction on success, else 0
	 */
	EXPORT mach_vm_address_t disasmNthIns(mach_vm_address_t addr, x86_insn ins, size_t num, size_t lookup_size);

	/**
	 *  Disassembly matching structure
	 */
	struct DisasmSig {
		x86_insn ins;       // instruction
		bool sub;           // relevant only for X86_INS_CALL, if its arg is X86_OP_IMM
		bool addr;          // if you want to return the address of exact inst in sig
	};

	/**
	 *  Reads lookup_size bytes from addr and disassembles them.
	 *  After disassembling, tries to find num-th entry of sig instruction pattern.
	 *
	 *  @param addr        Address to read from
	 *  @param sig         Instruction pattern
	 *  @param num         Order of pattern to search for
	 *  @param lookup_size Number of bytes to read
	 *
	 *  @return direct address of pattern start on success, else 0
	 */
	EXPORT mach_vm_address_t disasmSig(mach_vm_address_t addr, evector<DisasmSig *> &sig, size_t num, size_t lookup_size);
};

#endif /* kern_disasm_hpp */
<commit_msg>Capstone header compatibility for older plugins<commit_after>//
//  kern_disasm.hpp
//  Lilu
//
//  Copyright © 2016-2017 vit9696. All rights reserved.
//

#ifndef kern_disasm_hpp
#define kern_disasm_hpp

#ifndef CAPSTONE_HAS_OSXKERNEL
#define CAPSTONE_HAS_OSXKERNEL 1
#endif

#include <Headers/kern_config.hpp>
#include <Headers/kern_util.hpp>
#include <Headers/capstone/capstone.h>

#include <sys/types.h>
#include <mach/vm_types.h>

class Disassembler {
	/**
	 *  Because captsone handle can be 0
	 */
	bool initialised {false};

	/**
	 *  Internal capstone handle
	 */
	size_t handle;

	/**
	 *  Max instruction size
	 */
	static constexpr size_t MaxInstruction {15};
public:

	/**
	 *  Initialise dissassembling framework
	 *
	 *  @param detailed  debugging output necessity
	 *
	 *  @return true on success
	 */
	EXPORT bool init(bool detailed=false);

	/**
	 *  Deinitialise dissassembling framework, must be called regardless of the init error
	 */
	EXPORT void deinit();

	/**
	 *  Return the real instruction size contained within min bytes
	 *  Unlike instructionSize this uses HDE engine and at the cost of reduced compatibility it is much faster
	 *
	 *  @param ptr instruction pointer
	 *  @param min minimal possible size
	 *
	 *  @return instruction size >= min on success or 0
	 */
	EXPORT static size_t quickInstructionSize(mach_vm_address_t ptr, size_t min);

	/**
	 *  Reads size bytes from addr and disassembles them.
	 *
	 *  @param addr        Address to read from
	 *  @param size        Size of buffer to read
	 *  @param result      Disassembled instructions array. You must free it
	 *
	 *  @return size of result
	 */
	EXPORT size_t disasmBuf(mach_vm_address_t addr, size_t size, cs_insn **result);

	/**
	 *  Return the real instruction size contained within min bytes
	 *
	 *  @param ptr instruction pointer
	 *  @param min minimal possible size
	 *
	 *  @return instruction size >= min on success or 0
	 */
	EXPORT size_t instructionSize(mach_vm_address_t ptr, size_t min);

	/**
	 *  Reads lookup_size bytes from addr and disassembles them.
	 *  After disassembling, tries to find num-th entry with call instruction, which argument is an immediate value (some address).
	 *
	 *  @param addr        Address to read from
	 *  @param num         Number of call instruction to search for
	 *  @param lookup_size Number of bytes to read
	 *
	 *  @note It is assumed that the operand contains a positive relative address.
	 *
	 *  @return direct address of num-th call instruction on success, else 0
	 */
	EXPORT mach_vm_address_t disasmNthSub(mach_vm_address_t addr, size_t num, size_t lookup_size);

	/**
	 *  @brief  Reads lookup_size bytes from addr and disassembles them.
	 *
	 *  After disassembling, tries to find num-th entry with jmp instruction, which argument is an immediate value (some address).
	 *
	 *  @param addr        Address to read from
	 *  @param num         Number of jmp instruction to search for
	 *  @param lookup_size Number of bytes to read
	 *
	 *  @note It is assumed that the operand contains a positive relative address.
	 *
	 *  @return direct address of num-th jmp instruction on success, else 0
	 */
	EXPORT mach_vm_address_t disasmNthJmp(mach_vm_address_t addr, size_t num, size_t lookup_size);

	/**
	 *  Reads lookup_size bytes from addr and disassembles them.
	 *  After disassembling, tries to find num-th entry of inst instruction.
	 *
	 *  @param addr        Addres to read from
	 *  @param ins         Instruction code
	 *  @param num         Number of ins instruction to search for
	 *  @param lookup_size Number of bytes to read
	 *
	 *  @return address of found instruction on success, else 0
	 */
	EXPORT mach_vm_address_t disasmNthIns(mach_vm_address_t addr, x86_insn ins, size_t num, size_t lookup_size);

	/**
	 *  Disassembly matching structure
	 */
	struct DisasmSig {
		x86_insn ins;       // instruction
		bool sub;           // relevant only for X86_INS_CALL, if its arg is X86_OP_IMM
		bool addr;          // if you want to return the address of exact inst in sig
	};

	/**
	 *  Reads lookup_size bytes from addr and disassembles them.
	 *  After disassembling, tries to find num-th entry of sig instruction pattern.
	 *
	 *  @param addr        Address to read from
	 *  @param sig         Instruction pattern
	 *  @param num         Order of pattern to search for
	 *  @param lookup_size Number of bytes to read
	 *
	 *  @return direct address of pattern start on success, else 0
	 */
	EXPORT mach_vm_address_t disasmSig(mach_vm_address_t addr, evector<DisasmSig *> &sig, size_t num, size_t lookup_size);
};

#endif /* kern_disasm_hpp */
<|endoftext|>