<commit_before>#include "Database.h"

#include <QDebug>

/** Database constructor
 * Constructs the local database.
 * Currently no interface to handle remote databases, just creates one in the
 * current working directory.
 */
Database::Database()
    : db(QSqlDatabase::addDatabase("QSQLITE"))
{
    db.setHostName("localhost");
    db.setDatabaseName("horizon.db");
}

Database::Database(QString path)
    : db(QSqlDatabase::addDatabase("QSQLITE"))
{
    db.setHostName("localhost");
    db.setDatabaseName(path);
}

/** Initialize the actual database, if it hasn't been done already.
 * \return Success/failure of the operation.
*/
bool Database::init()
{
    bool status = db.open();
    if (!status)
    {
        qDebug("Couldn't connect to the database!");
        return false;
    }

    QSqlQuery createQuery(db);
    return createQuery.exec("CREATE TABLE IF NOT EXISTS games(ID INTEGER PRIMARY KEY ASC, GAMENAME TEXT NOT NULL, GAMEDIRECTORY TEXT NOT NULL, GAMEEXECUTABLE TEXT NOT NULL, ARGUMENTS TEXT NOT NULL, DRM INT DEFAULT 0);");
}

/** Remove every table in the database.
 * \return Success/failure of the operation.
*/
bool Database::reset()
{
    QSqlQuery query(db);
    return query.exec("DROP TABLE IF EXISTS games");
}

/** Add a game to the database and repopulate the games list.
 * \param gameName The name of the game.
 * \param gameDirectory Working directory of the game.
 * \param executablePath The location of the executable on the filesystem.
 * \param arguments List of arguments to launch with.
 * \param drm The DRM the game came from, where 0 = None, 1 = Steam, 2 = Origin, 3 = uPlay
 * \return Success/failure of the operation.
*/
bool Database::addGame(QString gameName, QString gameDirectory, QString executablePath, QString arguments, int drm)
{
    QSqlQuery query(db);
    query.prepare("INSERT OR IGNORE INTO GAMES(GAMENAME, GAMEDIRECTORY, GAMEEXECUTABLE, ARGUMENTS, DRM) VALUES (:gameName, :gameDirectory, :executablePath, :arguments, :drm);");
    query.bindValue(":gameName", gameName);
    query.bindValue(":gameDirectory", gameDirectory);
    query.bindValue(":executablePath", executablePath);
    query.bindValue(":arguments", arguments);
    query.bindValue(":drm", drm);
    query.exec();
}

/** Add games to the database and repopulate the games list.
 * \param games GameList of games to add.
 * \return Success/failure of the operation.
*/
void Database::addGames(GameList games)
{
    for (auto& game : games)
    {
        addGame(game.gameName, game.gameDirectory, game.executablePath, game.arguments, game.drm);
    }
}

/** Remove a game from the database by their ID.
 * \param id ID of the game to remove.
 * \return Success/failure of the operation.
*/
bool Database::removeGameById(unsigned int id)
{
    if (std::get<0>(isExistant(id)))
    {
        QSqlQuery query(db);
        query.prepare("DELETE FROM games WHERE ID = :id;");
        query.bindValue(":id", id);
        return query.exec();
    }
    else
    {
        return false;
    }
}

/** Remove a game from the database by their name.
 * \param name Name of the game to remove.
*/
bool Database::removeGameByName(QString name)
{
    if (std::get<0>(isExistant(name)))
    {
        QSqlQuery query(db);
        query.prepare("DELETE FROM GAMES WHERE GAMENAME = :name;");
        query.bindValue(":name", name);
        return query.exec();
    }
    else
    {
        return false;
    }
}

/** Wrapper to access the Game object from the ID.
 * \param id ID to find.
 * \return A Game object, empty upon failure.
*/
Game Database::getGameById(unsigned int id)
{
    return std::get<1>(isExistant(id));
}

/** Wrapper to access the Game object from the name.
 * \param id ID to find.
 * \return A Game object, empty upon failure.
*/
Game Database::getGameByName(QString name)
{
    return std::get<1>(isExistant(name));
}

/** Perform a query to find a specific game in the database by their ID. Unsafe at the
 * moment.
 * \param id ID of the game to find.
 * \return A Game object upon success, 0 upon failure.
*/
std::pair<bool, Game> Database::isExistant(unsigned int id)
{
    QSqlQuery query(db);
    query.prepare("SELECT ID, GAMENAME, GAMEDIRECTORY, GAMEEXECUTABLE, ARGUMENTS, DRM FROM GAMES WHERE ID = :id;");
    query.bindValue(":id", id);
    query.exec();

    if (query.next())
    {
        QString name = query.value(1).toString();
        QString path = query.value(2).toString();
        QString exe = query.value(3).toString();
        QString args = query.value(4).toString();
        int drm = query.value(5).toInt();

        return std::make_pair(true, Game {id, name, path, exe, args, drm});
    }
    else
    {
        return std::make_pair(false, Game{});
    }
}

/** Perform a query to find a specific game by their name (soon to be
 * deprecated).
 *
 * \param name Name of the game to find.
 * \return A Game object upon success, 0 upon failure.
*/
std::pair<bool, Game> Database::isExistant(QString name)
{
    QSqlQuery query(db);
    query.prepare("SELECT ID, GAMEDIRECTORY, GAMEEXECUTABLE, ARGUMENTS, DRM FROM GAMES WHERE GAMENAME = :name;");
    query.bindValue(":name", name);
    query.exec();
    if (query.next())
    {
        unsigned int id = query.value(0).toUInt();
        QString path = query.value(1).toString();
        QString exe = query.value(2).toString();
        QString args = query.value(3).toString();
        int drm = query.value(4).toInt();

        return std::make_pair(true, Game {id, name, path, exe, args, drm});
    }
    else
    {
        return std::make_pair(false, Game{});
    }
}

/** Perform a query to find every game in the database.
 * \return A QList of Game objects containing everything in the database.
*/
QList<Game> Database::getGames()
{
    QList<Game> games;
    QSqlQuery query;
    query.exec("SELECT ID, GAMENAME, GAMEDIRECTORY, GAMEEXECUTABLE, ARGUMENTS, DRM FROM GAMES;");
    while (query.next())
    {
        unsigned int id = query.value(0).toUInt();
        QString name = query.value(1).toString();
        QString path = query.value(2).toString();
        QString exe = query.value(3).toString();
        QString args = query.value(4).toString();
        int drm = query.value(5).toInt();

        games.append({id, name, path, exe, args, drm});
    }
    return games;
}

/** Queries the database to find the number of games.
 * \return Total number of games stored so far.
*/
unsigned int Database::getGameCount() const
{
    QSqlQuery query(db);
    query.exec("SELECT count() FROM GAMES;");
    if (!query.next())
    {
        return 0;
    }

    return query.value(0).toUInt();
}
<commit_msg>Fix typo<commit_after>#include "Database.h"

#include <QDebug>

/** Database constructor
 * Constructs the local database.
 * Currently no interface to handle remote databases, just creates one in the
 * current working directory.
 */
Database::Database()
    : db(QSqlDatabase::addDatabase("QSQLITE"))
{
    db.setHostName("localhost");
    db.setDatabaseName("horizon.db");
}

Database::Database(QString path)
    : db(QSqlDatabase::addDatabase("QSQLITE"))
{
    db.setHostName("localhost");
    db.setDatabaseName(path);
}

/** Initialize the actual database, if it hasn't been done already.
 * \return Success/failure of the operation.
*/
bool Database::init()
{
    bool status = db.open();
    if (!status)
    {
        qDebug("Couldn't connect to the database!");
        return false;
    }

    QSqlQuery createQuery(db);
    return createQuery.exec("CREATE TABLE IF NOT EXISTS games(ID INTEGER PRIMARY KEY ASC, GAMENAME TEXT NOT NULL, GAMEDIRECTORY TEXT NOT NULL, GAMEEXECUTABLE TEXT NOT NULL, ARGUMENTS TEXT NOT NULL, DRM INT DEFAULT 0);");
}

/** Remove every table in the database.
 * \return Success/failure of the operation.
*/
bool Database::reset()
{
    QSqlQuery query(db);
    return query.exec("DROP TABLE IF EXISTS games");
}

/** Add a game to the database and repopulate the games list.
 * \param gameName The name of the game.
 * \param gameDirectory Working directory of the game.
 * \param executablePath The location of the executable on the filesystem.
 * \param arguments List of arguments to launch with.
 * \param drm The DRM the game came from, where 0 = None, 1 = Steam, 2 = Origin, 3 = uPlay
 * \return Success/failure of the operation.
*/
bool Database::addGame(QString gameName, QString gameDirectory, QString executablePath, QString arguments, int drm)
{
    QSqlQuery query(db);
    query.prepare("INSERT OR IGNORE INTO GAMES(GAMENAME, GAMEDIRECTORY, GAMEEXECUTABLE, ARGUMENTS, DRM) VALUES (:gameName, :gameDirectory, :executablePath, :arguments, :drm);");
    query.bindValue(":gameName", gameName);
    query.bindValue(":gameDirectory", gameDirectory);
    query.bindValue(":executablePath", executablePath);
    query.bindValue(":arguments", arguments);
    query.bindValue(":drm", drm);
    return query.exec();
}

/** Add games to the database and repopulate the games list.
 * \param games GameList of games to add.
 * \return Success/failure of the operation.
*/
void Database::addGames(GameList games)
{
    for (auto& game : games)
    {
        addGame(game.gameName, game.gameDirectory, game.executablePath, game.arguments, game.drm);
    }
}

/** Remove a game from the database by their ID.
 * \param id ID of the game to remove.
 * \return Success/failure of the operation.
*/
bool Database::removeGameById(unsigned int id)
{
    if (std::get<0>(isExistant(id)))
    {
        QSqlQuery query(db);
        query.prepare("DELETE FROM games WHERE ID = :id;");
        query.bindValue(":id", id);
        return query.exec();
    }
    else
    {
        return false;
    }
}

/** Remove a game from the database by their name.
 * \param name Name of the game to remove.
*/
bool Database::removeGameByName(QString name)
{
    if (std::get<0>(isExistant(name)))
    {
        QSqlQuery query(db);
        query.prepare("DELETE FROM GAMES WHERE GAMENAME = :name;");
        query.bindValue(":name", name);
        return query.exec();
    }
    else
    {
        return false;
    }
}

/** Wrapper to access the Game object from the ID.
 * \param id ID to find.
 * \return A Game object, empty upon failure.
*/
Game Database::getGameById(unsigned int id)
{
    return std::get<1>(isExistant(id));
}

/** Wrapper to access the Game object from the name.
 * \param id ID to find.
 * \return A Game object, empty upon failure.
*/
Game Database::getGameByName(QString name)
{
    return std::get<1>(isExistant(name));
}

/** Perform a query to find a specific game in the database by their ID. Unsafe at the
 * moment.
 * \param id ID of the game to find.
 * \return A Game object upon success, 0 upon failure.
*/
std::pair<bool, Game> Database::isExistant(unsigned int id)
{
    QSqlQuery query(db);
    query.prepare("SELECT ID, GAMENAME, GAMEDIRECTORY, GAMEEXECUTABLE, ARGUMENTS, DRM FROM GAMES WHERE ID = :id;");
    query.bindValue(":id", id);
    query.exec();

    if (query.next())
    {
        QString name = query.value(1).toString();
        QString path = query.value(2).toString();
        QString exe = query.value(3).toString();
        QString args = query.value(4).toString();
        int drm = query.value(5).toInt();

        return std::make_pair(true, Game {id, name, path, exe, args, drm});
    }
    else
    {
        return std::make_pair(false, Game{});
    }
}

/** Perform a query to find a specific game by their name (soon to be
 * deprecated).
 *
 * \param name Name of the game to find.
 * \return A Game object upon success, 0 upon failure.
*/
std::pair<bool, Game> Database::isExistant(QString name)
{
    QSqlQuery query(db);
    query.prepare("SELECT ID, GAMEDIRECTORY, GAMEEXECUTABLE, ARGUMENTS, DRM FROM GAMES WHERE GAMENAME = :name;");
    query.bindValue(":name", name);
    query.exec();
    if (query.next())
    {
        unsigned int id = query.value(0).toUInt();
        QString path = query.value(1).toString();
        QString exe = query.value(2).toString();
        QString args = query.value(3).toString();
        int drm = query.value(4).toInt();

        return std::make_pair(true, Game {id, name, path, exe, args, drm});
    }
    else
    {
        return std::make_pair(false, Game{});
    }
}

/** Perform a query to find every game in the database.
 * \return A QList of Game objects containing everything in the database.
*/
QList<Game> Database::getGames()
{
    QList<Game> games;
    QSqlQuery query;
    query.exec("SELECT ID, GAMENAME, GAMEDIRECTORY, GAMEEXECUTABLE, ARGUMENTS, DRM FROM GAMES;");
    while (query.next())
    {
        unsigned int id = query.value(0).toUInt();
        QString name = query.value(1).toString();
        QString path = query.value(2).toString();
        QString exe = query.value(3).toString();
        QString args = query.value(4).toString();
        int drm = query.value(5).toInt();

        games.append({id, name, path, exe, args, drm});
    }
    return games;
}

/** Queries the database to find the number of games.
 * \return Total number of games stored so far.
*/
unsigned int Database::getGameCount() const
{
    QSqlQuery query(db);
    query.exec("SELECT count() FROM GAMES;");
    if (!query.next())
    {
        return 0;
    }

    return query.value(0).toUInt();
}
<|endoftext|>


<commit_before>#ifndef ELEKTRA_KDBVALUE_HPP
#define ELEKTRA_KDBVALUE_HPP

#include <kdbconfig.h>

#include <set>
#include <map>
#include <string>
#include <vector>
#include <memory>
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <algorithm>
#include <functional>
#include <unordered_map>

#include <kdbproposal.h>
#include <keyset.hpp>

// #include <kdbprivate.h> // for debugging (to see values of internal structures)

namespace kdb
{

// some widely used interfaces

class none_t
{};

template <>
inline void Key::set(none_t)
{}

template <>
inline none_t Key::get() const
{
	none_t ret;
	return ret;
}

class Layer
{
public:
	virtual std::string id() const = 0;
	virtual std::string operator()() const = 0;
};

class ValueObserver
{
public:
	virtual ~ValueObserver() = 0;
	virtual void updateContext() const = 0;

	typedef std::reference_wrapper<ValueObserver> reference;
};

bool operator <(ValueObserver const & lhs, ValueObserver const & rhs)
{
	return &lhs < &rhs;
}

inline ValueObserver::~ValueObserver()
{}

typedef std::function<Key()> Post;

class ValueSubject
{
public:
	virtual void notifyInThread() = 0;
};

// Default Policies for Value

class NoContext
{
public:
	void attachByName(ELEKTRA_UNUSED std::string const & key_name,ELEKTRA_UNUSED  ValueObserver & ValueObserver)
	{}

	std::string evaluate(std::string const & key_name) const
	{
		return key_name;
	}

	Key post(ELEKTRA_UNUSED Post post_)
	{
		return Key();
	}

	void attachToThread(ELEKTRA_UNUSED ValueSubject &v, Post postFkt)
	{
		postFkt();
	}
};

/**
 * @brief Implements lookup with spec.
 */
class DefaultGetPolicy
{
public:
	static Key get(KeySet &ks, Key const& spec)
	{
		return ks.lookup(spec, ckdb::KDB_O_SPEC);
	}
};

/**
 * @brief Implements creating user/ key when key is not found.
 */
class DefaultSetPolicy
{
public:
	static Key set(KeySet &ks, Key const& spec)
	{
		kdb::Key found = ks.lookup(spec.getName(), 0);

		if(!found)
		{
			kdb::Key k("user/"+spec.getName(), KEY_END);
			ks.append(k);
			found = k;
		}

		return found;
	}
};

class DefaultWritePolicy
{
public:
	static const bool allowed = true;
};

class ReadOnlyPolicy
{
public:
	static const bool allowed = false;
};

class DefaultObserverPolicy
{
public:
	typedef double type;
};

class NoLockPolicy
{
public:
	void lock() {}
	void unlock() {}
};

/**
 * This technique with the PolicySelector and Discriminator is taken
 * from the book  "C++ Templates - The Complete Guide"
 * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002
 * in Chapter 16 Templates and Inheritance: Named Template Arguments
 *
 * The technique allows users of the class Value to use any number
 * and order of policies as desired.
 */
template <typename Base, int D>
class Discriminator : public Base
{
};

template < typename Setter1,
	   typename Setter2,
	   typename Setter3,
	   typename Setter4,
	   typename Setter5,
	   typename Setter6
	 >
class PolicySelector : public Discriminator<Setter1,1>,
		       public Discriminator<Setter2,2>,
		       public Discriminator<Setter3,3>,
		       public Discriminator<Setter4,4>,
		       public Discriminator<Setter5,5>,
		       public Discriminator<Setter6,6>
{
};

class DefaultPolicies
{
public:
	typedef DefaultGetPolicy GetPolicy;
	typedef DefaultSetPolicy SetPolicy;
	typedef NoContext ContextPolicy;
	typedef DefaultWritePolicy WritePolicy;
	typedef DefaultObserverPolicy ObserverPolicy;
	typedef NoLockPolicy LockPolicy;
};

class DefaultPolicyArgs : virtual public DefaultPolicies
{
};

// class templates to override the default policy values

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class GetPolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy GetPolicy;
};

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class SetPolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy SetPolicy;
};

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class ContextPolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy ContextPolicy;
};

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class WritePolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy WritePolicy;
};

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class ObserverPolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy ObserverPolicy;
};

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class LockPolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy LockPolicy;
};

// standard types

template<typename T,
	typename PolicySetter1 = DefaultPolicyArgs,
	typename PolicySetter2 = DefaultPolicyArgs,
	typename PolicySetter3 = DefaultPolicyArgs,
	typename PolicySetter4 = DefaultPolicyArgs,
	typename PolicySetter5 = DefaultPolicyArgs,
	typename PolicySetter6 = DefaultPolicyArgs
	>
class Value :
	public ValueObserver,
	public ValueSubject
{
public:
	typedef T type;

	typedef PolicySelector<
		PolicySetter1,
		PolicySetter2,
		PolicySetter3,
		PolicySetter4,
		PolicySetter5,
		PolicySetter6
		>
		Policies;

	// not to be constructed yourself
	Value<T, PolicySetter1, PolicySetter2, PolicySetter3,
		PolicySetter4, PolicySetter5, PolicySetter6>
		(KeySet & ks, typename Policies::ContextPolicy & context_, kdb::Key spec) :
		m_cache(),
		m_ks(ks),
		m_context(context_),
		m_spec(spec)
	{
		assert(m_spec.getName()[0] == '/');
		m_spec.setMeta("name", m_spec.getName());
		ckdb::elektraKeySetName(*m_spec,
				m_context.evaluate(m_spec.getName()).c_str(),
				KEY_CASCADING_NAME);
		m_context.attachByName(m_spec.getMeta<std::string>("name"), *this);
		attachMeToThread();
	}

	void attachMeToThread()
	{
		Post fun = [this]
		{
			this->syncCache();
			assert(m_key);
			return m_key;
		};
		m_context.attachToThread(*this, fun);
	}

	typedef Value<T, PolicySetter1, PolicySetter2, PolicySetter3,
		PolicySetter4, PolicySetter5, PolicySetter6> V;

	V const & operator= (type n)
	{
		static_assert(Policies::WritePolicy::allowed, "read only contextual value");
		m_cache = n;
		post();

		return *this;
	}

	void post()
	{
		m_context.post([this]()
		{
			m_key.set<T>(m_cache);
			return m_key;
		});
	}

	void activate()
	{
		// TODO: use correct switching
		m_spec.setName("user/activate");
		attachMeToThread(); // reattach
	}

	void notifyInThread()
	{
		assert(m_key);
		syncCache();
		// TODO:
		m_cache = m_key.get<T>();
	}

	type operator ++()
	{
		static_assert(Policies::WritePolicy::allowed, "read only contextual value");
		return ++m_cache;
	}

	type operator ++(int)
	{
		static_assert(Policies::WritePolicy::allowed, "read only contextual value");
		return m_cache++;
	}

	// template < typename = typename std::enable_if< true >::type >
	operator type() const
	{
			return m_cache;
	}

	bool operator == (V const & other) const
	{
		return m_cache == other.m_cache ;
	}

	type getDefault() const
	{
		return m_spec.getMeta<type>("default");
	}

	/// We allow manipulation of context for const
	/// objects
	typename Policies::ContextPolicy & context() const
	{
		return const_cast<typename Policies::ContextPolicy&>(m_context);
	}

	typename Policies::ContextPolicy & c() const
	{
		return context();
	}

	Key const& getSpec() const
	{
		return m_spec;
	}

	// keyset to cache
	void syncCache() const
	{
		m_key = Policies::GetPolicy::get(m_ks, m_spec);

		if (m_key)
		{
			m_cache = m_key.get<type>();
		}

#if DEBUG && VERBOSE
		std::cout << "got name: " << m_key.getName() << " value: " << m_cache << std::endl;
#endif
	}

	// cache to keyset
	void syncKeySet() const
	{
		kdb::Key found = Policies::SetPolicy::set(m_ks, m_spec);

#if DEBUG && VERBOSE
		std::cout << "set name: " << found.getName() << " value: " << m_cache << std::endl;
#endif

		if (found)
		{
			found.set<type>(m_cache);
		}
	}

private:
	virtual void updateContext() const
	{
		// Policies::UpdatePolicy::update(this);
		typename Policies::LockPolicy lock;
		lock.lock();

		std::string evaluated_name = m_context.evaluate(m_spec.getMeta<std::string>("name"));
#if DEBUG && VERBOSE
		std::cout << "update context " << evaluated_name << " from " << m_spec.getName() << std::endl;
#endif
		if (evaluated_name != m_spec.getName())
		{
			syncKeySet(); // flush out what currently is in cache
			ckdb::elektraKeySetName(*m_spec,
					evaluated_name.c_str(),
					KEY_CASCADING_NAME);
			syncCache();  // read what we have under new context
		}
		lock.unlock();
	}

private:
	mutable type m_cache;
	KeySet & m_ks;
	typename Policies::ContextPolicy & m_context;
	Key m_spec;
	mutable Key m_key;
};

}

#endif
<commit_msg>add some doku<commit_after>#ifndef ELEKTRA_KDBVALUE_HPP
#define ELEKTRA_KDBVALUE_HPP

#include <kdbconfig.h>

#include <set>
#include <map>
#include <string>
#include <vector>
#include <memory>
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <algorithm>
#include <functional>
#include <unordered_map>

#include <kdbproposal.h>
#include <keyset.hpp>

// #include <kdbprivate.h> // for debugging (to see values of internal structures)

namespace kdb
{

// some widely used interfaces

/**
 * @brief This type is being used as bottom type that always fails.
 */
class none_t
{};

template <>
inline void Key::set(none_t)
{}

template <>
inline none_t Key::get() const
{
	none_t ret;
	return ret;
}

/**
 * @brief Base class for all layers.
 */
class Layer
{
public:
	virtual std::string id() const = 0;
	virtual std::string operator()() const = 0;
};

/**
 * @brief Base class for values to be observed.
 *
 * updateContext() is called whenever a context tells a value that it
 * should reevaluate its name and update its cache.
 */
class ValueObserver
{
public:
	virtual ~ValueObserver() = 0;
	virtual void updateContext() const = 0;

	typedef std::reference_wrapper<ValueObserver> reference;
};

/**
 * @brief Needed to put a ValueObserver in a map
 *
 * @return Comparision result
 */
bool operator <(ValueObserver const & lhs, ValueObserver const & rhs)
{
	return &lhs < &rhs;
}

inline ValueObserver::~ValueObserver()
{}

/**
 * @brief Used by contexts for callbacks (to run code using a mutex).
 */
typedef std::function<Key()> Post;

class ValueSubject
{
public:
	virtual void notifyInThread() = 0;
};

// Default Policies for Value

class NoContext
{
public:
	/**
	 * @brief attach a new value
	 *
	 * NoContext will never update anything
	 */
	void attachByName(ELEKTRA_UNUSED std::string const & key_name,ELEKTRA_UNUSED  ValueObserver & ValueObserver)
	{}

	/**
	 * @brief The evaluated equals the non-evaluated name!
	 *
	 * @return NoContext always returns the same string
	 */
	std::string evaluate(std::string const & key_name) const
	{
		return key_name;
	}

	Key post(ELEKTRA_UNUSED Post postFkt)
	{
		return postFkt();
	}

	void attachToThread(ELEKTRA_UNUSED ValueSubject &v, Post postFkt)
	{
		postFkt();
	}
};

/**
 * @brief Implements lookup with spec.
 */
class DefaultGetPolicy
{
public:
	static Key get(KeySet &ks, Key const& spec)
	{
		return ks.lookup(spec, ckdb::KDB_O_SPEC);
	}
};

/**
 * @brief Implements creating user/ key when key is not found.
 */
class DefaultSetPolicy
{
public:
	static Key set(KeySet &ks, Key const& spec)
	{
		kdb::Key found = ks.lookup(spec.getName(), 0);

		if(!found)
		{
			kdb::Key k("user/"+spec.getName(), KEY_END);
			ks.append(k);
			found = k;
		}

		return found;
	}
};

class DefaultWritePolicy
{
public:
	static const bool allowed = true;
};

class ReadOnlyPolicy
{
public:
	static const bool allowed = false;
};

class DefaultObserverPolicy
{
public:
	typedef double type;
};

class NoLockPolicy
{
public:
	void lock() {}
	void unlock() {}
};

/**
 * This technique with the PolicySelector and Discriminator is taken
 * from the book  "C++ Templates - The Complete Guide"
 * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002
 * in Chapter 16 Templates and Inheritance: Named Template Arguments
 *
 * The technique allows users of the class Value to use any number
 * and order of policies as desired.
 */
template <typename Base, int D>
class Discriminator : public Base
{
};

template < typename Setter1,
	   typename Setter2,
	   typename Setter3,
	   typename Setter4,
	   typename Setter5,
	   typename Setter6
	 >
class PolicySelector : public Discriminator<Setter1,1>,
		       public Discriminator<Setter2,2>,
		       public Discriminator<Setter3,3>,
		       public Discriminator<Setter4,4>,
		       public Discriminator<Setter5,5>,
		       public Discriminator<Setter6,6>
{
};

class DefaultPolicies
{
public:
	typedef DefaultGetPolicy GetPolicy;
	typedef DefaultSetPolicy SetPolicy;
	typedef NoContext ContextPolicy;
	typedef DefaultWritePolicy WritePolicy;
	typedef DefaultObserverPolicy ObserverPolicy;
	typedef NoLockPolicy LockPolicy;
};

class DefaultPolicyArgs : virtual public DefaultPolicies
{
};

// class templates to override the default policy values

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class GetPolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy GetPolicy;
};

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class SetPolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy SetPolicy;
};

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class ContextPolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy ContextPolicy;
};

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class WritePolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy WritePolicy;
};

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class ObserverPolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy ObserverPolicy;
};

/// Needed by the user to set one of the policies
///
/// @tparam Policy
template <typename Policy>
class LockPolicyIs : virtual public DefaultPolicies
{
public:
	typedef Policy LockPolicy;
};

// standard types

template<typename T,
	typename PolicySetter1 = DefaultPolicyArgs,
	typename PolicySetter2 = DefaultPolicyArgs,
	typename PolicySetter3 = DefaultPolicyArgs,
	typename PolicySetter4 = DefaultPolicyArgs,
	typename PolicySetter5 = DefaultPolicyArgs,
	typename PolicySetter6 = DefaultPolicyArgs
	>
class Value :
	public ValueObserver,
	public ValueSubject
{
public:
	typedef T type;

	typedef PolicySelector<
		PolicySetter1,
		PolicySetter2,
		PolicySetter3,
		PolicySetter4,
		PolicySetter5,
		PolicySetter6
		>
		Policies;

	// not to be constructed yourself
	Value<T, PolicySetter1, PolicySetter2, PolicySetter3,
		PolicySetter4, PolicySetter5, PolicySetter6>
		(KeySet & ks, typename Policies::ContextPolicy & context_, kdb::Key spec) :
		m_cache(),
		m_ks(ks),
		m_context(context_),
		m_spec(spec)
	{
		assert(m_spec.getName()[0] == '/');
		m_spec.setMeta("name", m_spec.getName());
		ckdb::elektraKeySetName(*m_spec,
				m_context.evaluate(m_spec.getName()).c_str(),
				KEY_CASCADING_NAME);
		m_context.attachByName(m_spec.getMeta<std::string>("name"), *this);
		attachMeToThread();
	}

	void attachMeToThread()
	{
		Post fun = [this]
		{
			this->syncCache();
			assert(m_key);
			return m_key;
		};
		m_context.attachToThread(*this, fun);
	}

	typedef Value<T, PolicySetter1, PolicySetter2, PolicySetter3,
		PolicySetter4, PolicySetter5, PolicySetter6> V;

	V const & operator= (type n)
	{
		static_assert(Policies::WritePolicy::allowed, "read only contextual value");
		m_cache = n;
		post();

		return *this;
	}

	void post()
	{
		m_context.post([this]()
		{
			m_key.set<T>(m_cache);
			return m_key;
		});
	}

	void activate()
	{
		// TODO: use correct switching
		m_spec.setName("user/activate");
		attachMeToThread(); // reattach
	}

	void notifyInThread()
	{
		assert(m_key);
		syncCache();
		// TODO:
		m_cache = m_key.get<T>();
	}

	type operator ++()
	{
		static_assert(Policies::WritePolicy::allowed, "read only contextual value");
		return ++m_cache;
	}

	type operator ++(int)
	{
		static_assert(Policies::WritePolicy::allowed, "read only contextual value");
		return m_cache++;
	}

	// template < typename = typename std::enable_if< true >::type >
	operator type() const
	{
			return m_cache;
	}

	bool operator == (V const & other) const
	{
		return m_cache == other.m_cache ;
	}

	type getDefault() const
	{
		return m_spec.getMeta<type>("default");
	}

	/// We allow manipulation of context for const
	/// objects
	typename Policies::ContextPolicy & context() const
	{
		return const_cast<typename Policies::ContextPolicy&>(m_context);
	}

	typename Policies::ContextPolicy & c() const
	{
		return context();
	}

	Key const& getSpec() const
	{
		return m_spec;
	}

	// keyset to cache
	void syncCache() const
	{
		m_key = Policies::GetPolicy::get(m_ks, m_spec);

		if (m_key)
		{
			m_cache = m_key.get<type>();
		}

#if DEBUG && VERBOSE
		std::cout << "got name: " << m_key.getName() << " value: " << m_cache << std::endl;
#endif
	}

	// cache to keyset
	void syncKeySet() const
	{
		kdb::Key found = Policies::SetPolicy::set(m_ks, m_spec);

#if DEBUG && VERBOSE
		std::cout << "set name: " << found.getName() << " value: " << m_cache << std::endl;
#endif

		if (found)
		{
			found.set<type>(m_cache);
		}
	}

private:
	virtual void updateContext() const
	{
		// Policies::UpdatePolicy::update(this);
		typename Policies::LockPolicy lock;
		lock.lock();

		std::string evaluated_name = m_context.evaluate(m_spec.getMeta<std::string>("name"));
#if DEBUG && VERBOSE
		std::cout << "update context " << evaluated_name << " from " << m_spec.getName() << std::endl;
#endif
		if (evaluated_name != m_spec.getName())
		{
			syncKeySet(); // flush out what currently is in cache
			ckdb::elektraKeySetName(*m_spec,
					evaluated_name.c_str(),
					KEY_CASCADING_NAME);
			syncCache();  // read what we have under new context
		}
		lock.unlock();
	}

private:
	mutable type m_cache;
	KeySet & m_ks;
	typename Policies::ContextPolicy & m_context;
	Key m_spec;
	mutable Key m_key;
};

}

#endif
<|endoftext|>


<commit_before>// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
//
// 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 <nvcore/StrLib.h>
#include <nvcore/StdStream.h>

#include <nvmath/Color.h>

#include <nvimage/Image.h>
#include <nvimage/ImageIO.h>
#include <nvimage/DirectDrawSurface.h>

#include "cmdline.h"

// @@ Add decent error messages.
// @@ Add option to resize images.
// @@ Add support for reading DDS files with 2D images and possibly mipmaps.

int main(int argc, char *argv[])
{
	MyAssertHandler assertHandler;
	MyMessageHandler messageHandler;

	bool assembleCubeMap = true;
	bool assembleVolume = false;
	bool assembleTextureArray = false;

	nv::Array<nv::Path> files;
	nv::Path output = "output.dds";

	// Parse arguments.
	for (int i = 1; i < argc; i++)
	{
		// Input options.
		if (strcmp("-cube", argv[i]) == 0)
		{
			assembleCubeMap = true;
			assembleVolume = false;
			assembleTextureArray = false;
		}
		/*if (strcmp("-volume", argv[i]) == 0)
		{
			assembleCubeMap = false;
			assembleVolume = true;
			assembleTextureArray = false;
		}
		if (strcmp("-array", argv[i]) == 0)
		{
			assembleCubeMap = false;
			assembleVolume = false;
			assembleTextureArray = true;
		}*/
		else if (strcmp("-o", argv[i]) == 0)
		{
			i++;
			if (i < argc && argv[i][0] != '-')
			{
				output = argv[i];
			}
		}
		else if (argv[i][0] != '-')
		{
			files.append(argv[i]);
		}
	}

	if (files.count() == 0)
	{
		printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n");
		printf("usage: nvassemble [-cube|-volume|-array] 'file0' 'file1' ...\n\n");
		return 1;
	}

	if (nv::strCaseCmp(output.extension(), ".dds") != 0)
	{
		//output.stripExtension();
		output.append(".dds");
	}

	if (assembleCubeMap && files.count() != 6)
	{
		printf("*** error, 6 files expected, but got %d\n", files.count());
		return 1;
	}

	// Load all files.
	nv::Array<nv::Image> images;

	uint w, h;
	bool hasAlpha = false;

	const uint imageCount = files.count();
	images.resize(imageCount);

	for (uint i = 0; i < imageCount; i++)
	{
		if (!images[i].load(files[i]))
		{
			printf("*** error loading file\n");
			return 1;
		}

		if (i == 0)
		{
			w = images[i].width();
			h = images[i].height();
		}
		else if (images[i].width() != w || images[i].height() != h)
		{
			printf("*** error, size of image '%s' does not match\n", files[i].str());
			return 1;
		}

		if (images[i].format() == nv::Image::Format_ARGB)
		{
			hasAlpha = true;
		}
	}

	nv::StdOutputStream stream(output);
	if (stream.isError()) {
		printf("Error opening '%s' for writting\n", output.str());
		return 1;
	}

	// Output DDS header.
	nv::DDSHeader header;
	header.setWidth(w);
	header.setHeight(h);

	if (assembleCubeMap)
	{
		header.setTextureCube();
	}
	else if (assembleVolume)
	{
		header.setTexture3D();
		header.setDepth(imageCount);
	}
	else if (assembleTextureArray)
	{
		//header.setTextureArray(imageCount);
	}

	// @@ It always outputs 32 bpp.
	header.setPitch(4 * w);
	header.setPixelFormat(32, 0xFF0000, 0xFF00, 0xFF, hasAlpha ? 0xFF000000 : 0);

	stream << header;

	// Output images.
	for (uint i = 0; i < imageCount; i++)
	{
		const uint pixelCount = w * h;
		for (uint p = 0; p < pixelCount; p++)
		{
			nv::Color32 c = images[i].pixel(p);
			uint8 r = c.r;
			uint8 g = c.g;
			uint8 b = c.b;
			uint8 a = c.a;
			stream << b << g << r << a;
		}
	}

	return 0;
}

<commit_msg>Remove warnings.<commit_after>// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
//
// 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 <nvcore/StrLib.h>
#include <nvcore/StdStream.h>

#include <nvmath/Color.h>

#include <nvimage/Image.h>
#include <nvimage/ImageIO.h>
#include <nvimage/DirectDrawSurface.h>

#include "cmdline.h"

// @@ Add decent error messages.
// @@ Add option to resize images.
// @@ Add support for reading DDS files with 2D images and possibly mipmaps.

int main(int argc, char *argv[])
{
	MyAssertHandler assertHandler;
	MyMessageHandler messageHandler;

	bool assembleCubeMap = true;
	bool assembleVolume = false;
	bool assembleTextureArray = false;

	nv::Array<nv::Path> files;
	nv::Path output = "output.dds";

	// Parse arguments.
	for (int i = 1; i < argc; i++)
	{
		// Input options.
		if (strcmp("-cube", argv[i]) == 0)
		{
			assembleCubeMap = true;
			assembleVolume = false;
			assembleTextureArray = false;
		}
		/*if (strcmp("-volume", argv[i]) == 0)
		{
			assembleCubeMap = false;
			assembleVolume = true;
			assembleTextureArray = false;
		}
		if (strcmp("-array", argv[i]) == 0)
		{
			assembleCubeMap = false;
			assembleVolume = false;
			assembleTextureArray = true;
		}*/
		else if (strcmp("-o", argv[i]) == 0)
		{
			i++;
			if (i < argc && argv[i][0] != '-')
			{
				output = argv[i];
			}
		}
		else if (argv[i][0] != '-')
		{
			files.append(argv[i]);
		}
	}

	if (files.count() == 0)
	{
		printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n");
		printf("usage: nvassemble [-cube|-volume|-array] 'file0' 'file1' ...\n\n");
		return 1;
	}

	if (nv::strCaseCmp(output.extension(), ".dds") != 0)
	{
		//output.stripExtension();
		output.append(".dds");
	}

	if (assembleCubeMap && files.count() != 6)
	{
		printf("*** error, 6 files expected, but got %d\n", files.count());
		return 1;
	}

	// Load all files.
	nv::Array<nv::Image> images;

	uint w = 0, h = 0;
	bool hasAlpha = false;

	const uint imageCount = files.count();
	images.resize(imageCount);

	for (uint i = 0; i < imageCount; i++)
	{
		if (!images[i].load(files[i]))
		{
			printf("*** error loading file\n");
			return 1;
		}

		if (i == 0)
		{
			w = images[i].width();
			h = images[i].height();
		}
		else if (images[i].width() != w || images[i].height() != h)
		{
			printf("*** error, size of image '%s' does not match\n", files[i].str());
			return 1;
		}

		if (images[i].format() == nv::Image::Format_ARGB)
		{
			hasAlpha = true;
		}
	}

	nv::StdOutputStream stream(output);
	if (stream.isError()) {
		printf("Error opening '%s' for writting\n", output.str());
		return 1;
	}

	// Output DDS header.
	nv::DDSHeader header;
	header.setWidth(w);
	header.setHeight(h);

	if (assembleCubeMap)
	{
		header.setTextureCube();
	}
	else if (assembleVolume)
	{
		header.setTexture3D();
		header.setDepth(imageCount);
	}
	else if (assembleTextureArray)
	{
		//header.setTextureArray(imageCount);
	}

	// @@ It always outputs 32 bpp.
	header.setPitch(4 * w);
	header.setPixelFormat(32, 0xFF0000, 0xFF00, 0xFF, hasAlpha ? 0xFF000000 : 0);

	stream << header;

	// Output images.
	for (uint i = 0; i < imageCount; i++)
	{
		const uint pixelCount = w * h;
		for (uint p = 0; p < pixelCount; p++)
		{
			nv::Color32 c = images[i].pixel(p);
			uint8 r = c.r;
			uint8 g = c.g;
			uint8 b = c.b;
			uint8 a = c.a;
			stream << b << g << r << a;
		}
	}

	return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright 2008, 2009 Google Inc.
 * Copyright 2007 Nintendo Co., Ltd.
 *
 * 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.
 */

#include <sys/stat.h>
#include <sys/types.h>
#include <set>
#include "java.h"

namespace
{

FILE* createFile(const std::string package, const Node* node)
{
    std::string filename = package;

    size_t pos = 0;
    for (;;)
    {
        pos = filename.find('.', pos);
        if (pos == std::string::npos)
        {
            break;
        }
        filename[pos] = '/';
    }

    filename += "/" + node->getName() + ".java";

    std::string dir;
    std::string path(filename);
    for (;;)
    {
        size_t slash = path.find("/");
        if (slash == std::string::npos)
        {
            break;
        }
        dir += path.substr(0, slash);
        path.erase(0, slash + 1);
        mkdir(dir.c_str(), 0777);
        dir += '/';
    }

    printf("# %s in %s\n", node->getName().c_str(), filename.c_str());
    return fopen(filename.c_str(), "w");
}

}  // namespace

class JavaInterface : public Java
{
    // TODO: Move to Java
    void visitInterfaceElement(const Interface* interface, Node* element)
    {
        if (dynamic_cast<Interface*>(element))
        {
            // Do not process Constructor.
            return;
        }

        optionalStage = 0;
        do
        {
            optionalCount = 0;
            element->accept(this);
            ++optionalStage;
        } while (optionalStage <= optionalCount);
    }

public:
    JavaInterface(const char* source, FILE* file, const char* indent = "es") :
        Java(source, file, indent)
    {
    }

    virtual void at(const ExceptDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        write("public class %s extends RuntimeException {\n", node->getName().c_str());
            // TODO(Shiki): Need a constructor.
            printChildren(node);
        writeln("}");
    }

    virtual void at(const Interface* node)
    {
        assert(!(node->getAttr() & Interface::Supplemental) && !node->isLeaf());
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }

        std::string name = node->getQualifiedName();
        name = getInterfaceName(name);
        write("public interface %s", name.substr(name.rfind(':') + 1).c_str());
        if (node->getExtends())
        {
            const char* separator = " extends ";
            for (NodeList::iterator i = node->getExtends()->begin();
                 i != node->getExtends()->end();
                 ++i)
            {
                if ((*i)->getName() == Node::getBaseObjectName())
                {
                    // Do not extend from 'Object'.
                    continue;
                }
                write(separator);
                separator = ", ";
                (*i)->accept(this);
            }
        }
        write(" {\n");

        for (NodeList::iterator i = node->begin(); i != node->end(); ++i)
        {
            visitInterfaceElement(node, *i);
        }

        // Expand mixins
        std::list<const Interface*> interfaceList;
        node->collectMixins(&interfaceList, node);
        for (std::list<const Interface*>::const_iterator i = interfaceList.begin();
                i != interfaceList.end();
                ++i)
        {
            if (*i == node)
            {
                continue;
            }
            writeln("// %s", (*i)->getName().c_str());
            for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j)
            {
                visitInterfaceElement(*i, *j);
            }
        }

        writeln("}");
    }

    virtual void at(const BinaryExpr* node)
    {
        node->getLeft()->accept(this);
        write(" %s ", node->getName().c_str());
        node->getRight()->accept(this);
    }

    virtual void at(const UnaryExpr* node)
    {
        write("%s", node->getName().c_str());
        NodeList::iterator elem = node->begin();
        (*elem)->accept(this);
    }

    virtual void at(const GroupingExpression* node)
    {
        write("(");
        NodeList::iterator elem = node->begin();
        (*elem)->accept(this);
        write(")");
    }

    virtual void at(const Literal* node)
    {
        write("%s", node->getName().c_str());
    }

    virtual void at(const Member* node)
    {
        if (node->isTypedef(node->getParent()))
        {
            return;
        }

        writetab();
        write("public ");
        node->getSpec()->accept(this);
        write(" %s;\n", node->getName().c_str());
    }

    virtual void at(const ArrayDcl* node)
    {
        assert(!node->isLeaf());
        if (node->isTypedef(node->getParent()))
        {
            return;
        }

        writetab();
        node->getSpec()->accept(this);
        write(" %s", node->getName().c_str());
        for (NodeList::iterator i = node->begin(); i != node->end(); ++i)
        {
            write("[");
            (*i)->accept(this);
            write("]");
        }
        if (node->isTypedef(node->getParent()))
        {
            write(";\n");
        }
    }

    virtual void at(const ConstDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        write("public static final ");
        node->getSpec()->accept(this);
        write(" %s = ", node->getName().c_str());
        node->getExp()->accept(this);
        write(";\n");
    }

    virtual void at(const Attribute* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }

        // getter
        Java::getter(node);
        write(";\n");

        if (!node->isReadonly() || node->isPutForwards() || node->isReplaceable())
        {
            // setter
            writetab();
            Java::setter(node);
            write(";\n");
        }
    }

    virtual void at(const OpDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        Java::at(node);
        write(";\n");
    }
};

class JavaImport : public Visitor, public Formatter
{
    std::string package;
    const Interface* current;
    bool printed;
    std::string prefixedName;
    std::set<std::string> importSet;

public:
    JavaImport(std::string package, FILE* file, const char* indent) :
        Formatter(file, indent),
        package(package),
        current(0)
    {
    }

    virtual void at(const Node* node)
    {
        visitChildren(node);
    }

    virtual void at(const ScopedName* node)
    {
        assert(current);

        if (node->isBaseObject())
        {
            return;
        }
        std::string name = node->getName();
        Node* resolved = resolve(current, name);
        if (resolved)
        {
            if (Module* module = dynamic_cast<Module*>(resolved->getParent()))
            {
                if (prefixedName != module->getPrefixedName())
                {
                    importSet.insert(Java::getPackageName(module->getPrefixedName()) + "." + node->getIdentifier());
                }
            }
        }
    }

    virtual void at(const Interface* node)
    {
        if (current)
        {
            return;
        }
        current = node;
        if (Module* module = dynamic_cast<Module*>(node->getParent()))
        {
            prefixedName = module->getPrefixedName();
        }
        visitChildren(node->getExtends());
        visitChildren(node);
        // Expand mixins
        std::list<const Interface*> interfaceList;
        node->collectMixins(&interfaceList, node);
        for (std::list<const Interface*>::const_iterator i = interfaceList.begin();
             i != interfaceList.end();
             ++i)
        {
            if (*i == node)
            {
                continue;
            }
            visitChildren(*i);
        }
    }

    virtual void at(const Attribute* node)
    {
        node->getSpec()->accept(this);
        visitChildren(node->getGetRaises());
        if (!node->isReadonly() || node->isPutForwards() || node->isReplaceable())
        {
            visitChildren(node->getSetRaises());
        }
    }

    virtual void at(const OpDcl* node)
    {
        node->getSpec()->accept(this);
        visitChildren(node);
        visitChildren(node->getRaises());
    }

    virtual void at(const ParamDcl* node)
    {
        node->getSpec()->accept(this);
    }

    void print()
    {
        if (importSet.empty())
        {
            return;
        }
        for (std::set<std::string>::iterator i = importSet.begin();
             i != importSet.end();
             ++i)
        {
            write("import %s;\n", (*i).c_str());
        }
        write("\n");
    }
};

class JavaVisitor : public Visitor
{
    const char* source;
    const char* indent;

    std::string prefixedName;

public:
    JavaVisitor(const char* source, const char* indent = "es") :
        source(source),
        indent(indent)
    {
    }

    virtual void at(const Node* node)
    {
        if (1 < node->getRank())
        {
            return;
        }
        visitChildren(node);
    }

    virtual void at(const Module* node)
    {
        std::string enclosed = prefixedName;
        prefixedName = node->getPrefixedName();
        at(static_cast<const Node*>(node));
        prefixedName = enclosed;
    }

    virtual void at(const ExceptDcl* node)
    {
        if (1 < node->getRank() || node->isLeaf() || !node->isDefinedIn(source))
        {
            return;
        }

        FILE* file = createFile(Java::getPackageName(prefixedName), node);
        if (!file)
        {
            return;
        }

        fprintf(file, "// Generated by esidl %s.\n\n", VERSION);
        fprintf(file, "package %s;\n\n", Java::getPackageName(prefixedName).c_str());

        JavaInterface javaInterface(source, file, indent);
        javaInterface.at(node);

        fclose(file);
    }

    virtual void at(const Interface* node)
    {
        if (1 < node->getRank() || node->isLeaf() || !node->isDefinedIn(source) ||
            (node->getAttr() & Interface::Supplemental))
        {
            return;
        }

        FILE* file = createFile(Java::getPackageName(prefixedName), node);
        if (!file)
        {
            return;
        }

        fprintf(file, "// Generated by esidl %s.\n\n", VERSION);
        fprintf(file, "package %s;\n\n", Java::getPackageName(prefixedName).c_str());

        JavaImport import(Java::getPackageName(prefixedName), file, indent);
        import.at(node);
        import.print();

        JavaInterface javaInterface(source, file, indent);
        javaInterface.at(node);

        fclose(file);
    }
};

void printJava(const char* source, const char* indent)
{
    JavaVisitor visitor(source, indent);
    getSpecification()->accept(&visitor);
}
<commit_msg>(at(const ScopedName* node)) : Fix to follow typedef name.<commit_after>/*
 * Copyright 2008, 2009 Google Inc.
 * Copyright 2007 Nintendo Co., Ltd.
 *
 * 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.
 */

#include <sys/stat.h>
#include <sys/types.h>
#include <set>
#include "java.h"

namespace
{

FILE* createFile(const std::string package, const Node* node)
{
    std::string filename = package;

    size_t pos = 0;
    for (;;)
    {
        pos = filename.find('.', pos);
        if (pos == std::string::npos)
        {
            break;
        }
        filename[pos] = '/';
    }

    filename += "/" + node->getName() + ".java";

    std::string dir;
    std::string path(filename);
    for (;;)
    {
        size_t slash = path.find("/");
        if (slash == std::string::npos)
        {
            break;
        }
        dir += path.substr(0, slash);
        path.erase(0, slash + 1);
        mkdir(dir.c_str(), 0777);
        dir += '/';
    }

    printf("# %s in %s\n", node->getName().c_str(), filename.c_str());
    return fopen(filename.c_str(), "w");
}

}  // namespace

class JavaInterface : public Java
{
    // TODO: Move to Java
    void visitInterfaceElement(const Interface* interface, Node* element)
    {
        if (dynamic_cast<Interface*>(element))
        {
            // Do not process Constructor.
            return;
        }

        optionalStage = 0;
        do
        {
            optionalCount = 0;
            element->accept(this);
            ++optionalStage;
        } while (optionalStage <= optionalCount);
    }

public:
    JavaInterface(const char* source, FILE* file, const char* indent = "es") :
        Java(source, file, indent)
    {
    }

    virtual void at(const ExceptDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        write("public class %s extends RuntimeException {\n", node->getName().c_str());
            // TODO(Shiki): Need a constructor.
            printChildren(node);
        writeln("}");
    }

    virtual void at(const Interface* node)
    {
        assert(!(node->getAttr() & Interface::Supplemental) && !node->isLeaf());
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }

        std::string name = node->getQualifiedName();
        name = getInterfaceName(name);
        write("public interface %s", name.substr(name.rfind(':') + 1).c_str());
        if (node->getExtends())
        {
            const char* separator = " extends ";
            for (NodeList::iterator i = node->getExtends()->begin();
                 i != node->getExtends()->end();
                 ++i)
            {
                if ((*i)->getName() == Node::getBaseObjectName())
                {
                    // Do not extend from 'Object'.
                    continue;
                }
                write(separator);
                separator = ", ";
                (*i)->accept(this);
            }
        }
        write(" {\n");

        for (NodeList::iterator i = node->begin(); i != node->end(); ++i)
        {
            visitInterfaceElement(node, *i);
        }

        // Expand mixins
        std::list<const Interface*> interfaceList;
        node->collectMixins(&interfaceList, node);
        for (std::list<const Interface*>::const_iterator i = interfaceList.begin();
                i != interfaceList.end();
                ++i)
        {
            if (*i == node)
            {
                continue;
            }
            writeln("// %s", (*i)->getName().c_str());
            for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j)
            {
                visitInterfaceElement(*i, *j);
            }
        }

        writeln("}");
    }

    virtual void at(const BinaryExpr* node)
    {
        node->getLeft()->accept(this);
        write(" %s ", node->getName().c_str());
        node->getRight()->accept(this);
    }

    virtual void at(const UnaryExpr* node)
    {
        write("%s", node->getName().c_str());
        NodeList::iterator elem = node->begin();
        (*elem)->accept(this);
    }

    virtual void at(const GroupingExpression* node)
    {
        write("(");
        NodeList::iterator elem = node->begin();
        (*elem)->accept(this);
        write(")");
    }

    virtual void at(const Literal* node)
    {
        write("%s", node->getName().c_str());
    }

    virtual void at(const Member* node)
    {
        if (node->isTypedef(node->getParent()))
        {
            return;
        }

        writetab();
        write("public ");
        node->getSpec()->accept(this);
        write(" %s;\n", node->getName().c_str());
    }

    virtual void at(const ArrayDcl* node)
    {
        assert(!node->isLeaf());
        if (node->isTypedef(node->getParent()))
        {
            return;
        }

        writetab();
        node->getSpec()->accept(this);
        write(" %s", node->getName().c_str());
        for (NodeList::iterator i = node->begin(); i != node->end(); ++i)
        {
            write("[");
            (*i)->accept(this);
            write("]");
        }
        if (node->isTypedef(node->getParent()))
        {
            write(";\n");
        }
    }

    virtual void at(const ConstDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        write("public static final ");
        node->getSpec()->accept(this);
        write(" %s = ", node->getName().c_str());
        node->getExp()->accept(this);
        write(";\n");
    }

    virtual void at(const Attribute* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }

        // getter
        Java::getter(node);
        write(";\n");

        if (!node->isReadonly() || node->isPutForwards() || node->isReplaceable())
        {
            // setter
            writetab();
            Java::setter(node);
            write(";\n");
        }
    }

    virtual void at(const OpDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        Java::at(node);
        write(";\n");
    }
};

class JavaImport : public Visitor, public Formatter
{
    std::string package;
    const Interface* current;
    bool printed;
    std::string prefixedName;
    std::set<std::string> importSet;

public:
    JavaImport(std::string package, FILE* file, const char* indent) :
        Formatter(file, indent),
        package(package),
        current(0)
    {
    }

    virtual void at(const Node* node)
    {
        visitChildren(node);
    }

    virtual void at(const ScopedName* node)
    {
        assert(current);

        if (node->isBaseObject())
        {
            return;
        }
        std::string name = node->getName();
        Node* resolved = node->search(current);
        if (resolved)
        {
            if (Module* module = dynamic_cast<Module*>(resolved->getParent()))
            {
                if (prefixedName != module->getPrefixedName())
                {
                    importSet.insert(Java::getPackageName(module->getPrefixedName()) + "." + node->getIdentifier());
                }
            }
        }
    }

    virtual void at(const Interface* node)
    {
        if (current)
        {
            return;
        }
        current = node;
        if (Module* module = dynamic_cast<Module*>(node->getParent()))
        {
            prefixedName = module->getPrefixedName();
        }
        visitChildren(node->getExtends());
        visitChildren(node);
        // Expand mixins
        std::list<const Interface*> interfaceList;
        node->collectMixins(&interfaceList, node);
        for (std::list<const Interface*>::const_iterator i = interfaceList.begin();
             i != interfaceList.end();
             ++i)
        {
            if (*i == node)
            {
                continue;
            }
            visitChildren(*i);
        }
    }

    virtual void at(const Attribute* node)
    {
        node->getSpec()->accept(this);
        visitChildren(node->getGetRaises());
        if (!node->isReadonly() || node->isPutForwards() || node->isReplaceable())
        {
            visitChildren(node->getSetRaises());
        }
    }

    virtual void at(const OpDcl* node)
    {
        node->getSpec()->accept(this);
        visitChildren(node);
        visitChildren(node->getRaises());
    }

    virtual void at(const ParamDcl* node)
    {
        node->getSpec()->accept(this);
    }

    void print()
    {
        if (importSet.empty())
        {
            return;
        }
        for (std::set<std::string>::iterator i = importSet.begin();
             i != importSet.end();
             ++i)
        {
            write("import %s;\n", (*i).c_str());
        }
        write("\n");
    }
};

class JavaVisitor : public Visitor
{
    const char* source;
    const char* indent;

    std::string prefixedName;

public:
    JavaVisitor(const char* source, const char* indent = "es") :
        source(source),
        indent(indent)
    {
    }

    virtual void at(const Node* node)
    {
        if (1 < node->getRank())
        {
            return;
        }
        visitChildren(node);
    }

    virtual void at(const Module* node)
    {
        std::string enclosed = prefixedName;
        prefixedName = node->getPrefixedName();
        at(static_cast<const Node*>(node));
        prefixedName = enclosed;
    }

    virtual void at(const ExceptDcl* node)
    {
        if (1 < node->getRank() || node->isLeaf() || !node->isDefinedIn(source))
        {
            return;
        }

        FILE* file = createFile(Java::getPackageName(prefixedName), node);
        if (!file)
        {
            return;
        }

        fprintf(file, "// Generated by esidl %s.\n\n", VERSION);
        fprintf(file, "package %s;\n\n", Java::getPackageName(prefixedName).c_str());

        JavaInterface javaInterface(source, file, indent);
        javaInterface.at(node);

        fclose(file);
    }

    virtual void at(const Interface* node)
    {
        if (1 < node->getRank() || node->isLeaf() || !node->isDefinedIn(source) ||
            (node->getAttr() & Interface::Supplemental))
        {
            return;
        }

        FILE* file = createFile(Java::getPackageName(prefixedName), node);
        if (!file)
        {
            return;
        }

        fprintf(file, "// Generated by esidl %s.\n\n", VERSION);
        fprintf(file, "package %s;\n\n", Java::getPackageName(prefixedName).c_str());

        JavaImport import(Java::getPackageName(prefixedName), file, indent);
        import.at(node);
        import.print();

        JavaInterface javaInterface(source, file, indent);
        javaInterface.at(node);

        fclose(file);
    }
};

void printJava(const char* source, const char* indent)
{
    JavaVisitor visitor(source, indent);
    getSpecification()->accept(&visitor);
}
<|endoftext|>


<commit_before>/**
 * @file
 * @brief Implementation of object with set of particles at pixel
 * @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
 * This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
 * In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
 * Intergovernmental Organization or submit itself to any jurisdiction.
 */

#include "PixelCharge.hpp"

#include "exceptions.h"

using namespace allpix;

PixelCharge::PixelCharge(Pixel pixel, unsigned int charge, std::vector<const PropagatedCharge*> propagated_charges)
    : pixel_(std::move(pixel)), charge_(charge) {
    for(auto& propagated_charge : propagated_charges) {
        propagated_charges_.Add(const_cast<PropagatedCharge*>(propagated_charge)); // NOLINT
        bool matched = false;
        for(auto mc_particle : mc_particles_) {
            if(dynamic_cast<MCParticle*>(mc_particle) == propagated_charge->getMCParticle())
                matched = true;
        }
        if(!matched)
            mc_particles_.Add(const_cast<MCParticle*>(propagated_charge->getMCParticle())); // NOLINT
    }
}

const Pixel& PixelCharge::getPixel() const {
    return pixel_;
}

Pixel::Index PixelCharge::getIndex() const {
    return getPixel().getIndex();
}

unsigned int PixelCharge::getCharge() const {
    return charge_;
}

/**
 * @throws MissingReferenceException If the pointed object is not in scope
 *
 * Objects are stored as TRefArray and can only be accessed if pointed objects are in scope
 */
std::vector<const PropagatedCharge*> PixelCharge::getPropagatedCharges() const {
    // FIXME: This is not very efficient unfortunately
    std::vector<const PropagatedCharge*> propagated_charges;
    for(int i = 0; i < propagated_charges_.GetEntries(); ++i) {
        propagated_charges.emplace_back(dynamic_cast<PropagatedCharge*>(propagated_charges_[i]));
        if(propagated_charges.back() == nullptr) {
            throw MissingReferenceException(typeid(*this), typeid(PropagatedCharge));
        }
    }
    return propagated_charges;
}

/**
 * @throws MissingReferenceException If the pointed object is not in scope
 *
 * MCParticles can only be fetched if the full history of objects are in scope and stored
 */
std::vector<const MCParticle*> PixelCharge::getMCParticles() const {

    std::vector<const MCParticle*> mc_particles;
    for(auto mc_particle : mc_particles_) {
        if(mc_particle == nullptr) {
            throw MissingReferenceException(typeid(*this), typeid(MCParticle));
        }
        mc_particles.emplace_back(dynamic_cast<MCParticle*>(mc_particle));
    }

    // Return as a vector of mc particles
    return mc_particles;
}

ClassImp(PixelCharge)
<commit_msg>Added braces<commit_after>/**
 * @file
 * @brief Implementation of object with set of particles at pixel
 * @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
 * This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
 * In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
 * Intergovernmental Organization or submit itself to any jurisdiction.
 */

#include "PixelCharge.hpp"

#include "exceptions.h"

using namespace allpix;

PixelCharge::PixelCharge(Pixel pixel, unsigned int charge, std::vector<const PropagatedCharge*> propagated_charges)
    : pixel_(std::move(pixel)), charge_(charge) {
    for(auto& propagated_charge : propagated_charges) {
        propagated_charges_.Add(const_cast<PropagatedCharge*>(propagated_charge)); // NOLINT
        bool matched = false;
        for(auto mc_particle : mc_particles_) {
            if(dynamic_cast<MCParticle*>(mc_particle) == propagated_charge->getMCParticle()) {
                matched = true;
            }
        }
        if(!matched) {
            mc_particles_.Add(const_cast<MCParticle*>(propagated_charge->getMCParticle())); // NOLINT
        }
    }
}

const Pixel& PixelCharge::getPixel() const {
    return pixel_;
}

Pixel::Index PixelCharge::getIndex() const {
    return getPixel().getIndex();
}

unsigned int PixelCharge::getCharge() const {
    return charge_;
}

/**
 * @throws MissingReferenceException If the pointed object is not in scope
 *
 * Objects are stored as TRefArray and can only be accessed if pointed objects are in scope
 */
std::vector<const PropagatedCharge*> PixelCharge::getPropagatedCharges() const {
    // FIXME: This is not very efficient unfortunately
    std::vector<const PropagatedCharge*> propagated_charges;
    for(int i = 0; i < propagated_charges_.GetEntries(); ++i) {
        propagated_charges.emplace_back(dynamic_cast<PropagatedCharge*>(propagated_charges_[i]));
        if(propagated_charges.back() == nullptr) {
            throw MissingReferenceException(typeid(*this), typeid(PropagatedCharge));
        }
    }
    return propagated_charges;
}

/**
 * @throws MissingReferenceException If the pointed object is not in scope
 *
 * MCParticles can only be fetched if the full history of objects are in scope and stored
 */
std::vector<const MCParticle*> PixelCharge::getMCParticles() const {

    std::vector<const MCParticle*> mc_particles;
    for(auto mc_particle : mc_particles_) {
        if(mc_particle == nullptr) {
            throw MissingReferenceException(typeid(*this), typeid(MCParticle));
        }
        mc_particles.emplace_back(dynamic_cast<MCParticle*>(mc_particle));
    }

    // Return as a vector of mc particles
    return mc_particles;
}

ClassImp(PixelCharge)
<|endoftext|>


<commit_before>/*
    Copyright (C) 1998 by Jorrit Tyberghein

    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 Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include <windows.h>
#include <gl/gl.h>

#include "csutil/scf.h"
#include "oglg2d.h"
#include "isys/system.h"

#ifndef CDS_UPDATEREGISTRY
#  define CDS_UPDATEREGISTRY  0x00000001
#endif
#ifndef CDS_TEST
#define CDS_TEST            0x00000002
#endif
#ifndef CDS_FULLSCREEN
#  define CDS_FULLSCREEN      0x00000004
#endif
#ifndef CDS_GLOBAL
#define CDS_GLOBAL          0x00000008
#endif
#ifndef CDS_SET_PRIMARY
#define CDS_SET_PRIMARY     0x00000010
#endif
#ifndef CDS_RESET
#define CDS_RESET           0x40000000
#endif
#ifndef CDS_SETRECT
#define CDS_SETRECT         0x20000000
#endif
#ifndef CDS_NORESET
#define CDS_NORESET         0x10000000
#endif

/* Return values for ChangeDisplaySettings */
#ifndef DISP_CHANGE_SUCCESSFUL
#define DISP_CHANGE_SUCCESSFUL       0
#endif
#ifndef DISP_CHANGE_RESTART
#define DISP_CHANGE_RESTART          1
#endif
#ifndef DISP_CHANGE_FAILED
#define DISP_CHANGE_FAILED          -1
#endif
#ifndef DISP_CHANGE_BADMODE
#define DISP_CHANGE_BADMODE         -2
#endif
#ifndef DISP_CHANGE_NOTUPDATED
#define DISP_CHANGE_NOTUPDATED      -3
#endif
#ifndef DISP_CHANGE_BADFLAGS
#define DISP_CHANGE_BADFLAGS        -4
#endif
#ifndef DISP_CHANGE_BADPARAM
#define DISP_CHANGE_BADPARAM        -5
#endif

void sys_fatalerror(char *str, HRESULT hRes = S_OK)
{
  LPVOID lpMsgBuf;
  char* szMsg;
  char szStdMessage[] = "Last Error: ";
  if (FAILED(hRes))
  {
    DWORD dwResult;
    dwResult = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
                 hRes,  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                   (LPTSTR) &lpMsgBuf, 0, NULL );

    if (dwResult != 0)
    {
      szMsg = new char[strlen((const char*)lpMsgBuf) + strlen(str) + strlen(szStdMessage) + 1];
      strcpy( szMsg, str );
      strcat( szMsg, szStdMessage );
      strcat( szMsg, (const char*)lpMsgBuf );

      LocalFree( lpMsgBuf );

      MessageBox (NULL, szMsg, "Fatal Error in OpenGL2D.dll", MB_OK);
      delete szMsg;

      exit(1);
    }
  }

  MessageBox(NULL, str, "Fatal Error in OpenGL2D.dll", MB_OK);

  exit(1);
}

/////The 2D Graphics Driver//////////////

IMPLEMENT_FACTORY (csGraphics2DOpenGL)

EXPORT_CLASS_TABLE (glwin32)
  EXPORT_CLASS_DEP (csGraphics2DOpenGL, "crystalspace.graphics2d.glwin32",
    "Win32 OpenGL 2D graphics driver for Crystal Space", "crystalspace.font.server.")
EXPORT_CLASS_TABLE_END

///// Windowed-mode palette stuff //////

struct {
  WORD Version;
  WORD NumberOfEntries;
  PALETTEENTRY aEntries[256];
} SysPalette =
{
  0x300,
    256
};

HPALETTE hWndPalette=NULL;

void ClearSystemPalette()
{
  struct
  {
    WORD Version;
    WORD nEntries;
    PALETTEENTRY aEntries[256];
  } Palette =
  {
    0x300,
      256
  };

  HPALETTE BlackPal, OldPal;
  HDC hdc;

  int c;

  for(c=0; c<256; c++)
  {
    Palette.aEntries[c].peRed = 0;
    Palette.aEntries[c].peGreen = 0;
    Palette.aEntries[c].peBlue = 0;
    Palette.aEntries[c].peFlags = PC_NOCOLLAPSE;
  }

  hdc = GetDC(NULL);

  BlackPal = CreatePalette((LOGPALETTE *)&Palette);

  OldPal = SelectPalette(hdc,BlackPal,FALSE);
  RealizePalette(hdc);
  SelectPalette(hdc, OldPal, FALSE);
  DeleteObject(BlackPal);

  ReleaseDC(NULL, hdc);
}

void CreateIdentityPalette(csRGBpixel *p)
{
  int i;
  struct {
    WORD Version;
    WORD nEntries;
    PALETTEENTRY aEntries[256];
  } Palette =
  {
    0x300,
      256
  };

  if(hWndPalette)
    DeleteObject(hWndPalette);

  Palette.aEntries[0].peFlags = 0;
  Palette.aEntries[0].peFlags = 0;

  for(i=1; i<255; i++)
  {
    Palette.aEntries[i].peRed = p[i].red;
    Palette.aEntries[i].peGreen = p[i].green;
    Palette.aEntries[i].peBlue = p[i].blue;
    Palette.aEntries[i].peFlags = PC_RESERVED;
  }

  hWndPalette = CreatePalette((LOGPALETTE *)&Palette);

  if(!hWndPalette)
    sys_fatalerror("Error creating identity palette.");
}

csGraphics2DOpenGL::csGraphics2DOpenGL(iBase *iParent) :
                   csGraphics2DGLCommon (iParent),
                   m_nGraphicsReady(true),
                   m_hWnd(NULL),
                   m_piWin32System(NULL),
                   m_bPalettized(false),
                   m_bPaletteChanged(false)
{
}

csGraphics2DOpenGL::~csGraphics2DOpenGL(void)
{
  m_piWin32System->DecRef ();
  m_nGraphicsReady=0;
}

bool csGraphics2DOpenGL::Initialize (iSystem *pSystem)
{
  if (!csGraphics2DGLCommon::Initialize (pSystem))
    return false;

  // QI for iWin32SystemDriver //
  m_piWin32System = QUERY_INTERFACE (System, iWin32SystemDriver);
  if (!m_piWin32System)
      sys_fatalerror("csGraphics2DDDraw3::Open(QI) -- iSystem passed does not support iWin32SystemDriver.");

  // Get the creation parameters //
  m_hInstance = m_piWin32System->GetInstance();
  m_nCmdShow  = m_piWin32System->GetCmdShow();

  System->GetSettings(Width, Height, Depth, FullScreen);

  if (Depth == 8)
  {
    pfmt.PalEntries = 256;
    pfmt.PixelBytes = 1;
  }

  CsPrintf (MSG_INITIALIZATION, "Using %d bits per pixel (%d color mode).\n", Depth, 1 << Depth);
  return true;
}

void csGraphics2DOpenGL::CalcPixelFormat ()
{
  PIXELFORMATDESCRIPTOR pfd = {
      sizeof(PIXELFORMATDESCRIPTOR),  /* size */
      1,                              /* version */
      PFD_SUPPORT_OPENGL |
      PFD_DOUBLEBUFFER |              /* support double-buffering */
      PFD_DRAW_TO_WINDOW,
      PFD_TYPE_RGBA,                  /* color type */
      Depth,                          /* prefered color depth */
      0, 0, 0, 0, 0, 0,               /* color bits (ignored) */
      0,                              /* no alpha buffer */
      0,                              /* alpha bits (ignored) */
      0,                              /* no accumulation buffer */
      0, 0, 0, 0,                     /* accum bits (ignored) */
      16,                             /* depth buffer */
      1,                              /* no stencil buffer */
      0,                              /* no auxiliary buffers */
      PFD_MAIN_PLANE,                 /* main layer */
      0,                              /* reserved */
      0, 0, 0                         /* no layer, visible, damage masks */
  };

  int pixelFormat;
  pixelFormat = ChoosePixelFormat(hDC, &pfd);

  if (pixelFormat == 0)
    sys_fatalerror("ChoosePixelFormat failed.");
  if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE)
    sys_fatalerror("SetPixelFormat failed.");

  if (DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd) == 0)
    sys_fatalerror("DescribePixelFormat failed.");
}

bool csGraphics2DOpenGL::Open(const char *Title)
{
  DEVMODE dmode;
  LONG ti;

  // create the window.
  DWORD exStyle = 0;
  DWORD style = WS_POPUP;// | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  if (!FullScreen)
    style |= WS_CAPTION;
  if (FullScreen)
  {
    ChangeDisplaySettings(NULL,0);

    EnumDisplaySettings(NULL, 0, &dmode);

    dmode.dmPelsWidth = Width;
    dmode.dmPelsHeight = Height;
    dmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;

    if((ti = ChangeDisplaySettings(&dmode, CDS_FULLSCREEN)) != DISP_CHANGE_SUCCESSFUL)
    {
      //The cases below need error handling, as they are errors.
      switch(ti)
      {
        case DISP_CHANGE_RESTART:
        //computer must restart for mode to work.
        CsPrintf (MSG_INITIALIZATION, "gl2d error: must restart for display change.\n");
        break;
        case DISP_CHANGE_BADFLAGS:
        //Bad Flag settings
        CsPrintf (MSG_INITIALIZATION, "gl2d error: display change bad flags.\n");
        break;
        case DISP_CHANGE_FAILED:
        //Failure to display
        CsPrintf (MSG_INITIALIZATION, "gl2d error: display change failed.\n");
        break;
        case DISP_CHANGE_NOTUPDATED:
        //No Reg Write Error
        CsPrintf (MSG_INITIALIZATION, "gl2d error: display change could not write registry.\n");
        break;
        default:
        //Unknown Error
        CsPrintf (MSG_INITIALIZATION, "gl2d error: display change gave unknown error.\n");
        break;
      }
    }
  }

  int wwidth,wheight;
  wwidth=Width+2*GetSystemMetrics(SM_CXSIZEFRAME);
  wheight=Height+2*GetSystemMetrics(SM_CYSIZEFRAME)+GetSystemMetrics(SM_CYCAPTION);

  m_hWnd = CreateWindowEx(exStyle, WINDOWCLASSNAME, Title, style,
		(GetSystemMetrics(SM_CXSCREEN)-wwidth)/2,
		(GetSystemMetrics(SM_CYSCREEN)-wheight)/2,
		wwidth, wheight, NULL, NULL, m_hInstance, NULL );
  if( !m_hWnd )
    sys_fatalerror("Cannot create Crystal Space window", GetLastError());

  ShowWindow( m_hWnd, m_nCmdShow );
  UpdateWindow( m_hWnd );
  SetFocus( m_hWnd );

  hDC = GetDC(m_hWnd);
  CalcPixelFormat ();

  hGLRC = wglCreateContext(hDC);
  wglMakeCurrent(hDC, hGLRC);

  if (!csGraphics2DGLCommon::Open(Title))
    return false;

  if (Depth == 8)
    m_bPalettized = true;
  else
    m_bPalettized = false;
  m_bPaletteChanged = false;

  return true;
}

void csGraphics2DOpenGL::Close(void)
{
  if (hGLRC)
  {
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hGLRC);
  }
  ReleaseDC(m_hWnd, hDC);

  if (FullScreen) ChangeDisplaySettings(NULL,0);

  if(!FullScreen)
  {
/*
    // restore the original system palette.
    HDC dc = GetDC(NULL);
    SetSystemPaletteUse(dc, SYSPAL_STATIC);
    PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
    ReleaseDC(NULL, dc);
*/
  }

  csGraphics2D::Close ();
}

void csGraphics2DOpenGL::Print (csRect* /*area*/)
{
  SwapBuffers(hDC);
  glFlush();
}

HRESULT csGraphics2DOpenGL::SetColorPalette()
{
  HRESULT ret = S_OK;

  if ((Depth==8) && m_bPaletteChanged)
  {
    m_bPaletteChanged = false;

   if(!FullScreen)
    {
      HPALETTE oldPal;
      HDC dc = GetDC(NULL);

      SetSystemPaletteUse(dc, SYSPAL_NOSTATIC);
      PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);

      CreateIdentityPalette(Palette);
      ClearSystemPalette();

      oldPal = SelectPalette(dc, hWndPalette, FALSE);

      RealizePalette(dc);
      SelectPalette(dc, oldPal, FALSE);
      ReleaseDC(NULL, dc);
    }

    return ret;
  }

  return S_OK;
}

void csGraphics2DOpenGL::SetRGB(int i, int r, int g, int b)
{
  csGraphics2D::SetRGB (i, r, g, b);
  m_bPaletteChanged = true;
}

bool csGraphics2DOpenGL::SetMouseCursor (csMouseCursorID iShape)
{
  HCURSOR hCursor;

  switch(iShape)
  {
    case csmcNone:     hCursor = NULL; break;
    case csmcArrow:    hCursor = LoadCursor (NULL, IDC_ARROW);    break;
    case csmcMove:     hCursor = LoadCursor (NULL, IDC_SIZEALL);  break;
    case csmcSizeNWSE: hCursor = LoadCursor (NULL, IDC_SIZENWSE); break;
    case csmcSizeNESW: hCursor = LoadCursor (NULL, IDC_SIZENESW); break;
    case csmcSizeNS:   hCursor = LoadCursor (NULL, IDC_SIZENS);   break;
    case csmcSizeEW:   hCursor = LoadCursor (NULL, IDC_SIZEWE);   break;
    case csmcStop:     hCursor = LoadCursor (NULL, IDC_NO);       break;
    case csmcWait:     hCursor = LoadCursor (NULL, IDC_WAIT);     break;
    default: hCursor = NULL;		//return false;
  }

	if (hCursor)
	{
		SetCursor(hCursor);
		return true;
	}
	else
	{
		SetCursor(NULL);
		return false;
	}
}

bool csGraphics2DOpenGL::SetMousePosition (int x, int y)
{
  POINT p;

  p.x = x;
  p.y = y;

  ClientToScreen(m_hWnd, &p);

  ::SetCursorPos(p.x, p.y);

  return true;
}

<commit_msg>Changed Win32 OpenGL2D driver from using a standard popup window. to using a complete and correct caption window with full system menu support.<commit_after>/*
    Copyright (C) 1998 by Jorrit Tyberghein

    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 Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include <windows.h>
#include <gl/gl.h>

#include "csutil/scf.h"
#include "oglg2d.h"
#include "isys/system.h"

#ifndef CDS_UPDATEREGISTRY
#  define CDS_UPDATEREGISTRY  0x00000001
#endif
#ifndef CDS_TEST
#define CDS_TEST            0x00000002
#endif
#ifndef CDS_FULLSCREEN
#  define CDS_FULLSCREEN      0x00000004
#endif
#ifndef CDS_GLOBAL
#define CDS_GLOBAL          0x00000008
#endif
#ifndef CDS_SET_PRIMARY
#define CDS_SET_PRIMARY     0x00000010
#endif
#ifndef CDS_RESET
#define CDS_RESET           0x40000000
#endif
#ifndef CDS_SETRECT
#define CDS_SETRECT         0x20000000
#endif
#ifndef CDS_NORESET
#define CDS_NORESET         0x10000000
#endif

/* Return values for ChangeDisplaySettings */
#ifndef DISP_CHANGE_SUCCESSFUL
#define DISP_CHANGE_SUCCESSFUL       0
#endif
#ifndef DISP_CHANGE_RESTART
#define DISP_CHANGE_RESTART          1
#endif
#ifndef DISP_CHANGE_FAILED
#define DISP_CHANGE_FAILED          -1
#endif
#ifndef DISP_CHANGE_BADMODE
#define DISP_CHANGE_BADMODE         -2
#endif
#ifndef DISP_CHANGE_NOTUPDATED
#define DISP_CHANGE_NOTUPDATED      -3
#endif
#ifndef DISP_CHANGE_BADFLAGS
#define DISP_CHANGE_BADFLAGS        -4
#endif
#ifndef DISP_CHANGE_BADPARAM
#define DISP_CHANGE_BADPARAM        -5
#endif

#define WINDOW_STYLE (WS_CAPTION | WS_MINIMIZEBOX | WS_POPUP | WS_SYSMENU)

void sys_fatalerror(char *str, HRESULT hRes = S_OK)
{
  LPVOID lpMsgBuf;
  char* szMsg;
  char szStdMessage[] = "Last Error: ";
  if (FAILED(hRes))
  {
    DWORD dwResult;
    dwResult = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
                 hRes,  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                   (LPTSTR) &lpMsgBuf, 0, NULL );

    if (dwResult != 0)
    {
      szMsg = new char[strlen((const char*)lpMsgBuf) + strlen(str) + strlen(szStdMessage) + 1];
      strcpy( szMsg, str );
      strcat( szMsg, szStdMessage );
      strcat( szMsg, (const char*)lpMsgBuf );

      LocalFree( lpMsgBuf );

      MessageBox (NULL, szMsg, "Fatal Error in OpenGL2D.dll", MB_OK);
      delete szMsg;

      exit(1);
    }
  }

  MessageBox(NULL, str, "Fatal Error in OpenGL2D.dll", MB_OK);

  exit(1);
}

/////The 2D Graphics Driver//////////////

IMPLEMENT_FACTORY (csGraphics2DOpenGL)

EXPORT_CLASS_TABLE (glwin32)
  EXPORT_CLASS_DEP (csGraphics2DOpenGL, "crystalspace.graphics2d.glwin32",
    "Win32 OpenGL 2D graphics driver for Crystal Space", "crystalspace.font.server.")
EXPORT_CLASS_TABLE_END

///// Windowed-mode palette stuff //////

struct {
  WORD Version;
  WORD NumberOfEntries;
  PALETTEENTRY aEntries[256];
} SysPalette =
{
  0x300,
    256
};

HPALETTE hWndPalette=NULL;

void ClearSystemPalette()
{
  struct
  {
    WORD Version;
    WORD nEntries;
    PALETTEENTRY aEntries[256];
  } Palette =
  {
    0x300,
      256
  };

  HPALETTE BlackPal, OldPal;
  HDC hdc;

  int c;

  for(c=0; c<256; c++)
  {
    Palette.aEntries[c].peRed = 0;
    Palette.aEntries[c].peGreen = 0;
    Palette.aEntries[c].peBlue = 0;
    Palette.aEntries[c].peFlags = PC_NOCOLLAPSE;
  }

  hdc = GetDC(NULL);

  BlackPal = CreatePalette((LOGPALETTE *)&Palette);

  OldPal = SelectPalette(hdc,BlackPal,FALSE);
  RealizePalette(hdc);
  SelectPalette(hdc, OldPal, FALSE);
  DeleteObject(BlackPal);

  ReleaseDC(NULL, hdc);
}

void CreateIdentityPalette(csRGBpixel *p)
{
  int i;
  struct {
    WORD Version;
    WORD nEntries;
    PALETTEENTRY aEntries[256];
  } Palette =
  {
    0x300,
      256
  };

  if(hWndPalette)
    DeleteObject(hWndPalette);

  Palette.aEntries[0].peFlags = 0;
  Palette.aEntries[0].peFlags = 0;

  for(i=1; i<255; i++)
  {
    Palette.aEntries[i].peRed = p[i].red;
    Palette.aEntries[i].peGreen = p[i].green;
    Palette.aEntries[i].peBlue = p[i].blue;
    Palette.aEntries[i].peFlags = PC_RESERVED;
  }

  hWndPalette = CreatePalette((LOGPALETTE *)&Palette);

  if(!hWndPalette)
    sys_fatalerror("Error creating identity palette.");
}

csGraphics2DOpenGL::csGraphics2DOpenGL(iBase *iParent) :
                   csGraphics2DGLCommon (iParent),
                   m_nGraphicsReady(true),
                   m_hWnd(NULL),
                   m_piWin32System(NULL),
                   m_bPalettized(false),
                   m_bPaletteChanged(false)
{
}

csGraphics2DOpenGL::~csGraphics2DOpenGL(void)
{
  m_piWin32System->DecRef ();
  m_nGraphicsReady=0;
}

bool csGraphics2DOpenGL::Initialize (iSystem *pSystem)
{
  if (!csGraphics2DGLCommon::Initialize (pSystem))
    return false;

  // QI for iWin32SystemDriver //
  m_piWin32System = QUERY_INTERFACE (System, iWin32SystemDriver);
  if (!m_piWin32System)
      sys_fatalerror("csGraphics2DDDraw3::Open(QI) -- iSystem passed does not support iWin32SystemDriver.");

  // Get the creation parameters //
  m_hInstance = m_piWin32System->GetInstance();
  m_nCmdShow  = m_piWin32System->GetCmdShow();

  System->GetSettings(Width, Height, Depth, FullScreen);

  if (Depth == 8)
  {
    pfmt.PalEntries = 256;
    pfmt.PixelBytes = 1;
  }

  CsPrintf (MSG_INITIALIZATION, "Using %d bits per pixel (%d color mode).\n", Depth, 1 << Depth);
  return true;
}

void csGraphics2DOpenGL::CalcPixelFormat ()
{
  PIXELFORMATDESCRIPTOR pfd = {
      sizeof(PIXELFORMATDESCRIPTOR),  /* size */
      1,                              /* version */
      PFD_SUPPORT_OPENGL |
      PFD_DOUBLEBUFFER |              /* support double-buffering */
      PFD_DRAW_TO_WINDOW,
      PFD_TYPE_RGBA,                  /* color type */
      Depth,                          /* prefered color depth */
      0, 0, 0, 0, 0, 0,               /* color bits (ignored) */
      0,                              /* no alpha buffer */
      0,                              /* alpha bits (ignored) */
      0,                              /* no accumulation buffer */
      0, 0, 0, 0,                     /* accum bits (ignored) */
      16,                             /* depth buffer */
      1,                              /* no stencil buffer */
      0,                              /* no auxiliary buffers */
      PFD_MAIN_PLANE,                 /* main layer */
      0,                              /* reserved */
      0, 0, 0                         /* no layer, visible, damage masks */
  };

  int pixelFormat;
  pixelFormat = ChoosePixelFormat(hDC, &pfd);

  if (pixelFormat == 0)
    sys_fatalerror("ChoosePixelFormat failed.");
  if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE)
    sys_fatalerror("SetPixelFormat failed.");

  if (DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd) == 0)
    sys_fatalerror("DescribePixelFormat failed.");
}

bool csGraphics2DOpenGL::Open(const char *Title)
{
  DEVMODE dmode;
  LONG ti;

  // create the window.
  DWORD exStyle = 0;
  DWORD style =  WINDOW_STYLE;
  if (!FullScreen)
    style |= WS_CAPTION;
  if (FullScreen)
  {
    ChangeDisplaySettings(NULL,0);

    EnumDisplaySettings(NULL, 0, &dmode);

    dmode.dmPelsWidth = Width;
    dmode.dmPelsHeight = Height;
    dmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;

    if((ti = ChangeDisplaySettings(&dmode, CDS_FULLSCREEN)) != DISP_CHANGE_SUCCESSFUL)
    {
      //The cases below need error handling, as they are errors.
      switch(ti)
      {
        case DISP_CHANGE_RESTART:
        //computer must restart for mode to work.
        CsPrintf (MSG_INITIALIZATION, "gl2d error: must restart for display change.\n");
        break;
        case DISP_CHANGE_BADFLAGS:
        //Bad Flag settings
        CsPrintf (MSG_INITIALIZATION, "gl2d error: display change bad flags.\n");
        break;
        case DISP_CHANGE_FAILED:
        //Failure to display
        CsPrintf (MSG_INITIALIZATION, "gl2d error: display change failed.\n");
        break;
        case DISP_CHANGE_NOTUPDATED:
        //No Reg Write Error
        CsPrintf (MSG_INITIALIZATION, "gl2d error: display change could not write registry.\n");
        break;
        default:
        //Unknown Error
        CsPrintf (MSG_INITIALIZATION, "gl2d error: display change gave unknown error.\n");
        break;
      }
    }
  }

  int wwidth,wheight;
  wwidth=Width+2*GetSystemMetrics(SM_CXSIZEFRAME);
  wheight=Height+2*GetSystemMetrics(SM_CYSIZEFRAME)+GetSystemMetrics(SM_CYCAPTION);

  m_hWnd = CreateWindowEx(exStyle, WINDOWCLASSNAME, Title, style,
		(GetSystemMetrics(SM_CXSCREEN)-wwidth)/2,
		(GetSystemMetrics(SM_CYSCREEN)-wheight)/2,
		wwidth, wheight, NULL, NULL, m_hInstance, NULL );
  if( !m_hWnd )
    sys_fatalerror("Cannot create Crystal Space window", GetLastError());

  ShowWindow( m_hWnd, m_nCmdShow );
  UpdateWindow( m_hWnd );
  SetFocus( m_hWnd );

  hDC = GetDC(m_hWnd);
  CalcPixelFormat ();

  hGLRC = wglCreateContext(hDC);
  wglMakeCurrent(hDC, hGLRC);

  if (!csGraphics2DGLCommon::Open(Title))
    return false;

  if (Depth == 8)
    m_bPalettized = true;
  else
    m_bPalettized = false;
  m_bPaletteChanged = false;

  return true;
}

void csGraphics2DOpenGL::Close(void)
{
  if (hGLRC)
  {
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hGLRC);
  }
  ReleaseDC(m_hWnd, hDC);

  if (FullScreen) ChangeDisplaySettings(NULL,0);

  if(!FullScreen)
  {
/*
    // restore the original system palette.
    HDC dc = GetDC(NULL);
    SetSystemPaletteUse(dc, SYSPAL_STATIC);
    PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
    ReleaseDC(NULL, dc);
*/
  }

  csGraphics2D::Close ();
}

void csGraphics2DOpenGL::Print (csRect* /*area*/)
{
  SwapBuffers(hDC);
  glFlush();
}

HRESULT csGraphics2DOpenGL::SetColorPalette()
{
  HRESULT ret = S_OK;

  if ((Depth==8) && m_bPaletteChanged)
  {
    m_bPaletteChanged = false;

   if(!FullScreen)
    {
      HPALETTE oldPal;
      HDC dc = GetDC(NULL);

      SetSystemPaletteUse(dc, SYSPAL_NOSTATIC);
      PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);

      CreateIdentityPalette(Palette);
      ClearSystemPalette();

      oldPal = SelectPalette(dc, hWndPalette, FALSE);

      RealizePalette(dc);
      SelectPalette(dc, oldPal, FALSE);
      ReleaseDC(NULL, dc);
    }

    return ret;
  }

  return S_OK;
}

void csGraphics2DOpenGL::SetRGB(int i, int r, int g, int b)
{
  csGraphics2D::SetRGB (i, r, g, b);
  m_bPaletteChanged = true;
}

bool csGraphics2DOpenGL::SetMouseCursor (csMouseCursorID iShape)
{
  HCURSOR hCursor;

  switch(iShape)
  {
    case csmcNone:     hCursor = NULL; break;
    case csmcArrow:    hCursor = LoadCursor (NULL, IDC_ARROW);    break;
    case csmcMove:     hCursor = LoadCursor (NULL, IDC_SIZEALL);  break;
    case csmcSizeNWSE: hCursor = LoadCursor (NULL, IDC_SIZENWSE); break;
    case csmcSizeNESW: hCursor = LoadCursor (NULL, IDC_SIZENESW); break;
    case csmcSizeNS:   hCursor = LoadCursor (NULL, IDC_SIZENS);   break;
    case csmcSizeEW:   hCursor = LoadCursor (NULL, IDC_SIZEWE);   break;
    case csmcStop:     hCursor = LoadCursor (NULL, IDC_NO);       break;
    case csmcWait:     hCursor = LoadCursor (NULL, IDC_WAIT);     break;
    default: hCursor = NULL;		//return false;
  }

	if (hCursor)
	{
		SetCursor(hCursor);
		return true;
	}
	else
	{
		SetCursor(NULL);
		return false;
	}
}

bool csGraphics2DOpenGL::SetMousePosition (int x, int y)
{
  POINT p;

  p.x = x;
  p.y = y;

  ClientToScreen(m_hWnd, &p);

  ::SetCursorPos(p.x, p.y);

  return true;
}

<|endoftext|>