<commit_before>#include <iostream>
#include <sstream>

#include "globals.hh"
#include "normalise.hh"
#include "archive.hh"
#include "shared.hh"

typedef void (* Operation) (Strings opFlags, Strings opArgs);

static bool pathArgs = false;

static void printHelp()
{
    cout <<
#include "nix-help.txt.hh"
        ;
    exit(0);
}

static FSId argToId(const string & arg)
{
    if (!pathArgs)
        return parseHash(arg);
    else {
        FSId id;
        if (!queryPathId(arg, id))
            throw Error(format("don't know id of `%1%'") % arg);
        return id;
    }
}

/* Realise (or install) paths from the given Nix fstate
   expressions. */
static void opInstall(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");

    for (Strings::iterator it = opArgs.begin();
         it != opArgs.end(); it++)
    {
        FSId id = normaliseFState(argToId(*it));
        realiseSlice(id);
        cout << format("%1%\n") % (string) id;
    }
}

/* Delete a path in the Nix store directory. */
static void opDelete(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");

    for (Strings::iterator it = opArgs.begin();
         it != opArgs.end(); it++)
        deleteFromStore(absPath(*it));
}

/* Add paths to the Nix values directory and print the hashes of those
   paths. */
static void opAdd(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");

    for (Strings::iterator it = opArgs.begin();
         it != opArgs.end(); it++)
    {
        string path;
        FSId id;
        addToStore(*it, path, id);
        cout << format("%1% %2%\n") % (string) id % path;
    }
}

static string dotQuote(const string & s)
{
    return "\"" + s + "\"";
}

FSId maybeNormalise(const FSId & id, bool normalise)
{
    return normalise ? normaliseFState(id) : id;
}

/* Perform various sorts of queries. */
static void opQuery(Strings opFlags, Strings opArgs)
{
    enum { qList, qRefs, qGenerators, qExpansion, qGraph
    } query = qList;
    bool normalise = false;

    for (Strings::iterator i = opFlags.begin();
         i != opFlags.end(); i++)
        if (*i == "--list" || *i == "-l") query = qList;
        else if (*i == "--refs" || *i == "-r") query = qRefs;
        else if (*i == "--generators" || *i == "-g") query = qGenerators;
        else if (*i == "--expansion" || *i == "-e") query = qExpansion;
        else if (*i == "--graph") query = qGraph;
        else if (*i == "--normalise" || *i == "-n") normalise = true;
        else throw UsageError(format("unknown flag `%1%'") % *i);

    switch (query) {

        case qList: {
            StringSet paths;
            for (Strings::iterator i = opArgs.begin();
                 i != opArgs.end(); i++)
            {
                Strings paths2 = fstatePaths(
                    maybeNormalise(argToId(*i), normalise));
                paths.insert(paths2.begin(), paths2.end());
            }
            for (StringSet::iterator i = paths.begin();
                 i != paths.end(); i++)
                cout << format("%s\n") % *i;
            break;
        }

        case qRefs: {
            StringSet paths;
            for (Strings::iterator i = opArgs.begin();
                 i != opArgs.end(); i++)
            {
                Strings paths2 = fstateRefs(
                    maybeNormalise(argToId(*i), normalise));
                paths.insert(paths2.begin(), paths2.end());
            }
            for (StringSet::iterator i = paths.begin();
                 i != paths.end(); i++)
                cout << format("%s\n") % *i;
            break;
        }

        case qGenerators: {
            FSIds outIds;
            for (Strings::iterator i = opArgs.begin();
                 i != opArgs.end(); i++)
                outIds.push_back(argToId(*i));

            FSIds genIds = findGenerators(outIds);

            for (FSIds::iterator i = genIds.begin();
                 i != genIds.end(); i++)
                cout << format("%s\n") % expandId(*i);
            break;
        }

        case qExpansion: {
            for (Strings::iterator i = opArgs.begin();
                 i != opArgs.end(); i++)
                /* !!! should not use substitutes; this is a query,
                   it should not have side-effects */
                cout << format("%s\n") % expandId(parseHash(*i));
            break;
        }

        case qGraph: {

            FSIds workList;

            for (Strings::iterator i = opArgs.begin();
                 i != opArgs.end(); i++)
                workList.push_back(argToId(*i));

            FSIdSet doneSet;

            cout << "digraph G {\n";

            while (!workList.empty()) {
                FSId id = workList.front();
                workList.pop_front();

                if (doneSet.find(id) == doneSet.end()) {
                    doneSet.insert(id);

                    FState fs = parseFState(termFromId(id));

                    string label;

                    if (fs.type == FState::fsDerive) {
                        for (FSIds::iterator i = fs.derive.inputs.begin();
                             i != fs.derive.inputs.end(); i++)
                        {
                            workList.push_back(*i);
                            cout << dotQuote(*i) << " -> "
                                 << dotQuote(id) << ";\n";
                        }

                        label = "derive";
                        for (StringPairs::iterator i = fs.derive.env.begin();
                             i != fs.derive.env.end(); i++)
                            if (i->first == "name") label = i->second;
                    }

                    else if (fs.type == FState::fsSlice) {
                        label = baseNameOf((*fs.slice.elems.begin()).path);
                    }

                    else abort();

                    cout << dotQuote(id) << "[label = "
                         << dotQuote(label)
                         << "];\n";
                }
            }

            cout << "}\n";
            break;
        }

        default:
            abort();
    }
}

static void opSuccessor(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");
    if (opArgs.size() % 2) throw UsageError("expecting even number of arguments");

    for (Strings::iterator i = opArgs.begin();
         i != opArgs.end(); )
    {
        FSId id1 = parseHash(*i++);
        FSId id2 = parseHash(*i++);
        registerSuccessor(id1, id2);
    }
}

static void opSubstitute(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");
    if (opArgs.size() % 2) throw UsageError("expecting even number of arguments");

    for (Strings::iterator i = opArgs.begin();
         i != opArgs.end(); )
    {
        FSId src = parseHash(*i++);
        FSId sub = parseHash(*i++);
        registerSubstitute(src, sub);
    }
}

/* A sink that writes dump output to stdout. */
struct StdoutSink : DumpSink
{
    virtual void operator ()
        (const unsigned char * data, unsigned int len)
    {
        writeFull(STDOUT_FILENO, data, len);
    }
};

/* Dump a path as a Nix archive.  The archive is written to standard
   output. */
static void opDump(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");
    if (opArgs.size() != 1) throw UsageError("only one argument allowed");

    StdoutSink sink;
    string arg = *opArgs.begin();
    string path = pathArgs ? arg : expandId(parseHash(arg));

    dumpPath(path, sink);
}

/* A source that read restore intput to stdin. */
struct StdinSource : RestoreSource
{
    virtual void operator () (unsigned char * data, unsigned int len)
    {
        readFull(STDIN_FILENO, data, len);
    }
};

/* Restore a value from a Nix archive.  The archive is written to
   standard input. */
static void opRestore(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");
    if (opArgs.size() != 1) throw UsageError("only one argument allowed");

    StdinSource source;
    restorePath(*opArgs.begin(), source);
}

/* Initialise the Nix databases. */
static void opInit(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");
    if (!opArgs.empty())
        throw UsageError("--init does not have arguments");
    initDB();
}

/* Verify the consistency of the Nix environment. */
static void opVerify(Strings opFlags, Strings opArgs)
{
    verifyStore();
}

/* Scan the arguments; find the operation, set global flags, put all
   other flags in a list, and put all other arguments in another
   list. */
void run(Strings args)
{
    Strings opFlags, opArgs;
    Operation op = 0;

    for (Strings::iterator it = args.begin(); it != args.end(); )
    {
        string arg = *it++;

        Operation oldOp = op;

        if (arg == "--install" || arg == "-i")
            op = opInstall;
        else if (arg == "--delete" || arg == "-d")
            op = opDelete;
        else if (arg == "--add" || arg == "-A")
            op = opAdd;
        else if (arg == "--query" || arg == "-q")
            op = opQuery;
        else if (arg == "--successor")
            op = opSuccessor;
        else if (arg == "--substitute")
            op = opSubstitute;
        else if (arg == "--dump")
            op = opDump;
        else if (arg == "--restore")
            op = opRestore;
        else if (arg == "--init")
            op = opInit;
        else if (arg == "--verify")
            op = opVerify;
        else if (arg == "--path" || arg == "-p")
            pathArgs = true;
        else if (arg == "--verbose" || arg == "-v")
            verbosity = (Verbosity) ((int) verbosity + 1);
        else if (arg == "--help")
            printHelp();
        else if (arg[0] == '-')
            opFlags.push_back(arg);
        else
            opArgs.push_back(arg);

        if (oldOp && oldOp != op)
            throw UsageError("only one operation may be specified");
    }

    if (!op) throw UsageError("no operation specified");

    op(opFlags, opArgs);
}

string programId = "nix";
<commit_msg>* Nicer dot graphs.<commit_after>#include <iostream>
#include <sstream>

#include "globals.hh"
#include "normalise.hh"
#include "archive.hh"
#include "shared.hh"

typedef void (* Operation) (Strings opFlags, Strings opArgs);

static bool pathArgs = false;

static void printHelp()
{
    cout <<
#include "nix-help.txt.hh"
        ;
    exit(0);
}

static FSId argToId(const string & arg)
{
    if (!pathArgs)
        return parseHash(arg);
    else {
        FSId id;
        if (!queryPathId(arg, id))
            throw Error(format("don't know id of `%1%'") % arg);
        return id;
    }
}

/* Realise (or install) paths from the given Nix fstate
   expressions. */
static void opInstall(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");

    for (Strings::iterator it = opArgs.begin();
         it != opArgs.end(); it++)
    {
        FSId id = normaliseFState(argToId(*it));
        realiseSlice(id);
        cout << format("%1%\n") % (string) id;
    }
}

/* Delete a path in the Nix store directory. */
static void opDelete(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");

    for (Strings::iterator it = opArgs.begin();
         it != opArgs.end(); it++)
        deleteFromStore(absPath(*it));
}

/* Add paths to the Nix values directory and print the hashes of those
   paths. */
static void opAdd(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");

    for (Strings::iterator it = opArgs.begin();
         it != opArgs.end(); it++)
    {
        string path;
        FSId id;
        addToStore(*it, path, id);
        cout << format("%1% %2%\n") % (string) id % path;
    }
}

static string dotQuote(const string & s)
{
    return "\"" + s + "\"";
}

FSId maybeNormalise(const FSId & id, bool normalise)
{
    return normalise ? normaliseFState(id) : id;
}

/* Perform various sorts of queries. */
static void opQuery(Strings opFlags, Strings opArgs)
{
    enum { qList, qRefs, qGenerators, qExpansion, qGraph
    } query = qList;
    bool normalise = false;

    for (Strings::iterator i = opFlags.begin();
         i != opFlags.end(); i++)
        if (*i == "--list" || *i == "-l") query = qList;
        else if (*i == "--refs" || *i == "-r") query = qRefs;
        else if (*i == "--generators" || *i == "-g") query = qGenerators;
        else if (*i == "--expansion" || *i == "-e") query = qExpansion;
        else if (*i == "--graph") query = qGraph;
        else if (*i == "--normalise" || *i == "-n") normalise = true;
        else throw UsageError(format("unknown flag `%1%'") % *i);

    switch (query) {

        case qList: {
            StringSet paths;
            for (Strings::iterator i = opArgs.begin();
                 i != opArgs.end(); i++)
            {
                Strings paths2 = fstatePaths(
                    maybeNormalise(argToId(*i), normalise));
                paths.insert(paths2.begin(), paths2.end());
            }
            for (StringSet::iterator i = paths.begin();
                 i != paths.end(); i++)
                cout << format("%s\n") % *i;
            break;
        }

        case qRefs: {
            StringSet paths;
            for (Strings::iterator i = opArgs.begin();
                 i != opArgs.end(); i++)
            {
                Strings paths2 = fstateRefs(
                    maybeNormalise(argToId(*i), normalise));
                paths.insert(paths2.begin(), paths2.end());
            }
            for (StringSet::iterator i = paths.begin();
                 i != paths.end(); i++)
                cout << format("%s\n") % *i;
            break;
        }

        case qGenerators: {
            FSIds outIds;
            for (Strings::iterator i = opArgs.begin();
                 i != opArgs.end(); i++)
                outIds.push_back(argToId(*i));

            FSIds genIds = findGenerators(outIds);

            for (FSIds::iterator i = genIds.begin();
                 i != genIds.end(); i++)
                cout << format("%s\n") % expandId(*i);
            break;
        }

        case qExpansion: {
            for (Strings::iterator i = opArgs.begin();
                 i != opArgs.end(); i++)
                /* !!! should not use substitutes; this is a query,
                   it should not have side-effects */
                cout << format("%s\n") % expandId(parseHash(*i));
            break;
        }

        case qGraph: {

            FSIds workList;

            for (Strings::iterator i = opArgs.begin();
                 i != opArgs.end(); i++)
                workList.push_back(argToId(*i));

            FSIdSet doneSet;

            cout << "digraph G {\n";

            while (!workList.empty()) {
                FSId id = workList.front();
                workList.pop_front();

                if (doneSet.find(id) == doneSet.end()) {
                    doneSet.insert(id);

                    FState fs = parseFState(termFromId(id));

                    string label, shape;

                    if (fs.type == FState::fsDerive) {
                        for (FSIds::iterator i = fs.derive.inputs.begin();
                             i != fs.derive.inputs.end(); i++)
                        {
                            workList.push_back(*i);
                            cout << dotQuote(*i) << " -> "
                                 << dotQuote(id) << ";\n";
                        }

                        label = "derive";
                        shape = "box";
                        for (StringPairs::iterator i = fs.derive.env.begin();
                             i != fs.derive.env.end(); i++)
                            if (i->first == "name") label = i->second;
                    }

                    else if (fs.type == FState::fsSlice) {
                        label = baseNameOf((*fs.slice.elems.begin()).path);
                        shape = "ellipse";
                        if (isHash(string(label, 0, Hash::hashSize * 2)) &&
                            label[Hash::hashSize * 2] == '-')
                            label = string(label, Hash::hashSize * 2 + 1);
                    }

                    else abort();

                    cout << dotQuote(id) << "[label = "
                         << dotQuote(label)
                         << ", shape = " << shape
                         << "];\n";
                }
            }

            cout << "}\n";
            break;
        }

        default:
            abort();
    }
}

static void opSuccessor(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");
    if (opArgs.size() % 2) throw UsageError("expecting even number of arguments");

    for (Strings::iterator i = opArgs.begin();
         i != opArgs.end(); )
    {
        FSId id1 = parseHash(*i++);
        FSId id2 = parseHash(*i++);
        registerSuccessor(id1, id2);
    }
}

static void opSubstitute(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");
    if (opArgs.size() % 2) throw UsageError("expecting even number of arguments");

    for (Strings::iterator i = opArgs.begin();
         i != opArgs.end(); )
    {
        FSId src = parseHash(*i++);
        FSId sub = parseHash(*i++);
        registerSubstitute(src, sub);
    }
}

/* A sink that writes dump output to stdout. */
struct StdoutSink : DumpSink
{
    virtual void operator ()
        (const unsigned char * data, unsigned int len)
    {
        writeFull(STDOUT_FILENO, data, len);
    }
};

/* Dump a path as a Nix archive.  The archive is written to standard
   output. */
static void opDump(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");
    if (opArgs.size() != 1) throw UsageError("only one argument allowed");

    StdoutSink sink;
    string arg = *opArgs.begin();
    string path = pathArgs ? arg : expandId(parseHash(arg));

    dumpPath(path, sink);
}

/* A source that read restore intput to stdin. */
struct StdinSource : RestoreSource
{
    virtual void operator () (unsigned char * data, unsigned int len)
    {
        readFull(STDIN_FILENO, data, len);
    }
};

/* Restore a value from a Nix archive.  The archive is written to
   standard input. */
static void opRestore(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");
    if (opArgs.size() != 1) throw UsageError("only one argument allowed");

    StdinSource source;
    restorePath(*opArgs.begin(), source);
}

/* Initialise the Nix databases. */
static void opInit(Strings opFlags, Strings opArgs)
{
    if (!opFlags.empty()) throw UsageError("unknown flag");
    if (!opArgs.empty())
        throw UsageError("--init does not have arguments");
    initDB();
}

/* Verify the consistency of the Nix environment. */
static void opVerify(Strings opFlags, Strings opArgs)
{
    verifyStore();
}

/* Scan the arguments; find the operation, set global flags, put all
   other flags in a list, and put all other arguments in another
   list. */
void run(Strings args)
{
    Strings opFlags, opArgs;
    Operation op = 0;

    for (Strings::iterator it = args.begin(); it != args.end(); )
    {
        string arg = *it++;

        Operation oldOp = op;

        if (arg == "--install" || arg == "-i")
            op = opInstall;
        else if (arg == "--delete" || arg == "-d")
            op = opDelete;
        else if (arg == "--add" || arg == "-A")
            op = opAdd;
        else if (arg == "--query" || arg == "-q")
            op = opQuery;
        else if (arg == "--successor")
            op = opSuccessor;
        else if (arg == "--substitute")
            op = opSubstitute;
        else if (arg == "--dump")
            op = opDump;
        else if (arg == "--restore")
            op = opRestore;
        else if (arg == "--init")
            op = opInit;
        else if (arg == "--verify")
            op = opVerify;
        else if (arg == "--path" || arg == "-p")
            pathArgs = true;
        else if (arg == "--verbose" || arg == "-v")
            verbosity = (Verbosity) ((int) verbosity + 1);
        else if (arg == "--help")
            printHelp();
        else if (arg[0] == '-')
            opFlags.push_back(arg);
        else
            opArgs.push_back(arg);

        if (oldOp && oldOp != op)
            throw UsageError("only one operation may be specified");
    }

    if (!op) throw UsageError("no operation specified");

    op(opFlags, opArgs);
}

string programId = "nix";
<|endoftext|>


<commit_before>//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Surface.cpp: Implements the egl::Surface class, representing a drawing surface
// such as the client area of a window, including any back buffers.
// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.

#include "Surface.h"

#include "main.h"
#include "debug.h"

namespace egl
{
Surface::Surface(IDirect3DDevice9 *device, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9 *depthStencil, EGLint configID)
    : mSwapChain(swapChain), mConfigID(configID), mDepthStencil(depthStencil)
{
    mBackBuffer = NULL;
    mRenderTarget = NULL;

    mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
    mRenderBuffer = EGL_BACK_BUFFER;
    mSwapBehavior = EGL_BUFFER_PRESERVED;

    if (mSwapChain)
    {
        mSwapChain->AddRef();
        mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);

        D3DSURFACE_DESC description;
        mBackBuffer->GetDesc(&description);

        mWidth = description.Width;
        mHeight = description.Height;

        HRESULT result = device->CreateRenderTarget(mWidth, mHeight, description.Format, description.MultiSampleType, description.MultiSampleQuality, FALSE, &mRenderTarget, NULL);

        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
        {
            error(EGL_BAD_ALLOC);

            return;
        }

        ASSERT(SUCCEEDED(result));
    }
}

Surface::~Surface()
{
    if (mSwapChain)
    {
        mSwapChain->Release();
    }

    if (mBackBuffer)
    {
        mBackBuffer->Release();
    }

    if (mRenderTarget)
    {
        mRenderTarget->Release();
    }

    if (mDepthStencil)
    {
        mDepthStencil->Release();
    }
}

HWND Surface::getWindowHandle()
{
    if (mSwapChain)
    {
        D3DPRESENT_PARAMETERS presentParameters;
        mSwapChain->GetPresentParameters(&presentParameters);

        return presentParameters.hDeviceWindow;
    }

    return NULL;
}

void Surface::swap()
{
    if (mSwapChain)
    {
        IDirect3DDevice9 *device;
        mSwapChain->GetDevice(&device);

        D3DSURFACE_DESC description;
        mBackBuffer->GetDesc(&description);

        // Copy the render target into a texture
        IDirect3DTexture9 *texture;
        HRESULT result = device->CreateTexture(mWidth, mHeight, 1, D3DUSAGE_RENDERTARGET, description.Format, D3DPOOL_DEFAULT, &texture, NULL);

        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
        {
            return error(EGL_BAD_ALLOC);
        }

        ASSERT(SUCCEEDED(result));

        IDirect3DSurface9 *textureSurface;
        texture->GetSurfaceLevel(0, &textureSurface);

        device->StretchRect(mRenderTarget, NULL, textureSurface, NULL, D3DTEXF_POINT);

        // Disable all pipeline operations
        device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
        device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
        device->SetRenderState(D3DRS_ALPHATESTENABLE , FALSE);
        device->SetRenderState(D3DRS_ALPHABLENDENABLE , FALSE);
        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
        device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
        device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
        device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
        device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
        device->SetPixelShader(NULL);
        device->SetVertexShader(NULL);

        // Just sample the texture
        device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
        device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
        device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
        device->SetTexture(0, texture);
        device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
        device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
        device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
        device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
        device->SetRenderTarget(0, mBackBuffer);

        // Render the texture upside down into the back buffer
        float quad[4][6] = {{     0 - 0.5f,       0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f},
                            {mWidth - 0.5f,       0 - 0.5f, 0.0f, 1.0f, 1.0f, 1.0f},
                            {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 1.0f, 0.0f},
                            {     0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f}};   // x, y, z, rhw, u, v

        device->BeginScene();
        device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
        device->EndScene();

        result = mSwapChain->Present(NULL, NULL, NULL, NULL, D3DPRESENT_INTERVAL_DEFAULT);   // FIXME: Get the swap interval from the associated Display

        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
        {
            return error(EGL_BAD_ALLOC);
        }

        textureSurface->Release();
        texture->Release();
        device->Release();
    }
}

EGLint Surface::getWidth() const
{
    return mWidth;
}

EGLint Surface::getHeight() const
{
    return mHeight;
}

IDirect3DSurface9 *Surface::getRenderTarget()
{
    if (mRenderTarget)
    {
        mRenderTarget->AddRef();
    }

    return mRenderTarget;
}

IDirect3DSurface9 *Surface::getDepthStencil()
{
    if (mDepthStencil)
    {
        mDepthStencil->AddRef();
    }

    return mDepthStencil;
}
}
<commit_msg>ANGLE | Don't perform any filtering when swapping<commit_after>//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Surface.cpp: Implements the egl::Surface class, representing a drawing surface
// such as the client area of a window, including any back buffers.
// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.

#include "Surface.h"

#include "main.h"
#include "debug.h"

namespace egl
{
Surface::Surface(IDirect3DDevice9 *device, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9 *depthStencil, EGLint configID)
    : mSwapChain(swapChain), mConfigID(configID), mDepthStencil(depthStencil)
{
    mBackBuffer = NULL;
    mRenderTarget = NULL;

    mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
    mRenderBuffer = EGL_BACK_BUFFER;
    mSwapBehavior = EGL_BUFFER_PRESERVED;

    if (mSwapChain)
    {
        mSwapChain->AddRef();
        mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);

        D3DSURFACE_DESC description;
        mBackBuffer->GetDesc(&description);

        mWidth = description.Width;
        mHeight = description.Height;

        HRESULT result = device->CreateRenderTarget(mWidth, mHeight, description.Format, description.MultiSampleType, description.MultiSampleQuality, FALSE, &mRenderTarget, NULL);

        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
        {
            error(EGL_BAD_ALLOC);

            return;
        }

        ASSERT(SUCCEEDED(result));
    }
}

Surface::~Surface()
{
    if (mSwapChain)
    {
        mSwapChain->Release();
    }

    if (mBackBuffer)
    {
        mBackBuffer->Release();
    }

    if (mRenderTarget)
    {
        mRenderTarget->Release();
    }

    if (mDepthStencil)
    {
        mDepthStencil->Release();
    }
}

HWND Surface::getWindowHandle()
{
    if (mSwapChain)
    {
        D3DPRESENT_PARAMETERS presentParameters;
        mSwapChain->GetPresentParameters(&presentParameters);

        return presentParameters.hDeviceWindow;
    }

    return NULL;
}

void Surface::swap()
{
    if (mSwapChain)
    {
        IDirect3DDevice9 *device;
        mSwapChain->GetDevice(&device);

        D3DSURFACE_DESC description;
        mBackBuffer->GetDesc(&description);

        // Copy the render target into a texture
        IDirect3DTexture9 *texture;
        HRESULT result = device->CreateTexture(mWidth, mHeight, 1, D3DUSAGE_RENDERTARGET, description.Format, D3DPOOL_DEFAULT, &texture, NULL);

        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
        {
            return error(EGL_BAD_ALLOC);
        }

        ASSERT(SUCCEEDED(result));

        IDirect3DSurface9 *textureSurface;
        texture->GetSurfaceLevel(0, &textureSurface);

        device->StretchRect(mRenderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE);

        // Disable all pipeline operations
        device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
        device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
        device->SetRenderState(D3DRS_ALPHATESTENABLE , FALSE);
        device->SetRenderState(D3DRS_ALPHABLENDENABLE , FALSE);
        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
        device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
        device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
        device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
        device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
        device->SetPixelShader(NULL);
        device->SetVertexShader(NULL);

        // Just sample the texture
        device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
        device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
        device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
        device->SetTexture(0, texture);
        device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
        device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
        device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
        device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
        device->SetRenderTarget(0, mBackBuffer);

        // Render the texture upside down into the back buffer
        float quad[4][6] = {{     0 - 0.5f,       0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f},
                            {mWidth - 0.5f,       0 - 0.5f, 0.0f, 1.0f, 1.0f, 1.0f},
                            {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 1.0f, 0.0f},
                            {     0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f}};   // x, y, z, rhw, u, v

        device->BeginScene();
        device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
        device->EndScene();

        result = mSwapChain->Present(NULL, NULL, NULL, NULL, D3DPRESENT_INTERVAL_DEFAULT);   // FIXME: Get the swap interval from the associated Display

        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
        {
            return error(EGL_BAD_ALLOC);
        }

        textureSurface->Release();
        texture->Release();
        device->Release();
    }
}

EGLint Surface::getWidth() const
{
    return mWidth;
}

EGLint Surface::getHeight() const
{
    return mHeight;
}

IDirect3DSurface9 *Surface::getRenderTarget()
{
    if (mRenderTarget)
    {
        mRenderTarget->AddRef();
    }

    return mRenderTarget;
}

IDirect3DSurface9 *Surface::getDepthStencil()
{
    if (mDepthStencil)
    {
        mDepthStencil->AddRef();
    }

    return mDepthStencil;
}
}
<|endoftext|>


<commit_before>//   Copyright 2014 Tom Regan
//
//   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 "encodings.h"

namespace encodings {

namespace binary {

void print_byte(uint8_t byte) {
  for (auto i = 0x80; i; i >>= 1) {
    std::cout << (((byte & i) == i) ? "1" : "0");
  }
  std::cout << '\n';
}

void print_double(uint32_t bits) {
  for (auto i = 0x80000000; i; i >>= 1) {
    if (i == 0x80 || i == 0x8000 || i == 0x800000) {
      std::cout << ' ';
    }
    std::cout << (((bits & i) == i) ? "1" : "0");
  }
  std::cout << '\n';
}

}  // binary

namespace base64 {

uint8_t to_byte(uint8_t byte) {
  if (byte == '+') {
    return 62;
  } else if (byte == '/') {
    return 63;
  } else if (byte < 58) {
    return byte + 4;
  } else if (byte < 91) {
    return byte - 65;
  }
  return byte - 71;
}

uint8_t from_byte(uint8_t byte) {
  byte &= 0x3f;
  if (byte < 26) {
    return byte + 65;  // ascii A
  } else if (byte < 52) {
    return byte + 71;  // ascii a
  } else if (byte < 62) {
    return byte - 4;   // ascii 0
  } else if (byte == 62) {
    return '+';
 }
  return '/';
}

std::string from_hex(std::string hex_string) {
  std::stringstream buffer;
  while (!hex_string.empty()) {
    uint32_t bitset = std::stoul(hex_string.substr(0, 6), 0, 16);
    hex_string.erase(0, 6);
    while (!(bitset & 0x00ff0000)) {
      bitset <<= 8;
    }
    buffer << from_byte(bitset >> 18);
    buffer << from_byte(bitset >> 12);
    if (bitset & 0x00000fc0) {
      buffer << from_byte(bitset >> 6);
      if (bitset & 0x0000003f) {
	buffer << from_byte(bitset);
      }
    }
  }
  while (buffer.str().size() % 4) {
    buffer << '=';
  }
  return buffer.str();
}

}  // base64

namespace hex {

std::string from_base64(std::string base64_string) {
  std::stringstream buffer;
  while (!base64_string.empty()) {
    std::string dword = base64_string.substr(0, 4);
    base64_string.erase(0, 4);
    uint32_t bitset = base64::to_byte(dword[0]);
    bitset <<=6;
    bitset |= base64::to_byte(dword[1]);
    bitset <<= 6;
    bitset |= base64::to_byte(dword[2]);
    bitset <<=6;
    bitset |= base64::to_byte(dword[3]);
    if (dword[2] == '=' && dword[3] == '=') {
      bitset >>= 16;
    }
    else if (dword[3]  == '=') {
      bitset >>= 8;
    }
    buffer << std::hex << bitset;
  }
  return buffer.str();
}

}  // hex

}  // encodings
<commit_msg>simplify hex::from_base64<commit_after>//   Copyright 2014 Tom Regan
//
//   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 "encodings.h"

namespace encodings {

namespace binary {

void print_byte(uint8_t byte) {
  for (auto i = 0x80; i; i >>= 1) {
    std::cout << (((byte & i) == i) ? "1" : "0");
  }
  std::cout << '\n';
}

void print_double(uint32_t bits) {
  for (auto i = 0x80000000; i; i >>= 1) {
    if (i == 0x80 || i == 0x8000 || i == 0x800000) {
      std::cout << ' ';
    }
    std::cout << (((bits & i) == i) ? "1" : "0");
  }
  std::cout << '\n';
}

}  // binary

namespace base64 {

uint8_t to_byte(uint8_t byte) {
  if (byte == '+') {
    return 62;
  } else if (byte == '/') {
    return 63;
  } else if (byte < 58) {
    return byte + 4;
  } else if (byte < 91) {
    return byte - 65;
  }
  return byte - 71;
}

uint8_t from_byte(uint8_t byte) {
  byte &= 0x3f;
  if (byte < 26) {
    return byte + 65;  // ascii A
  } else if (byte < 52) {
    return byte + 71;  // ascii a
  } else if (byte < 62) {
    return byte - 4;   // ascii 0
  } else if (byte == 62) {
    return '+';
 }
  return '/';
}

std::string from_hex(std::string hex_string) {
  std::stringstream buffer;
  while (!hex_string.empty()) {
    uint32_t bitset = std::stoul(hex_string.substr(0, 6), 0, 16);
    hex_string.erase(0, 6);
    while (!(bitset & 0x00ff0000)) {
      bitset <<= 8;
    }
    buffer << from_byte(bitset >> 18);
    buffer << from_byte(bitset >> 12);
    if (bitset & 0x00000fc0) {
      buffer << from_byte(bitset >> 6);
      if (bitset & 0x0000003f) {
	buffer << from_byte(bitset);
      }
    }
  }
  while (buffer.str().size() % 4) {
    buffer << '=';
  }
  return buffer.str();
}

}  // base64

namespace hex {

std::string from_base64(std::string base64_string) {
  std::stringstream buffer;
  while (!base64_string.empty()) {
    std::string dword = base64_string.substr(0, 4);
    base64_string.erase(0, 4);
    uint32_t bitset = base64::to_byte(dword[0]) << 18;
    bitset |= base64::to_byte(dword[1]) << 12;
    bitset |= base64::to_byte(dword[2]) << 6;
    bitset |= base64::to_byte(dword[3]);
    if (dword[3] == '=') {
      bitset >>= 8;
      if (dword[2] == '=') {
	bitset >>=8;
      }
    }
    buffer << std::hex << bitset;
  }
  return buffer.str();
}

}  // hex

}  // encodings
<|endoftext|>


<commit_before>#include "EjectOSD.h"

#include <Dbt.h>

#include "..\HotkeyInfo.h"
#include "..\Monitor.h"
#include "..\Skin\Skin.h"
#include "..\Skin\SkinManager.h"

EjectOSD::EjectOSD() :
OSD(L"3RVX-EjectDispatcher"),
_mWnd(L"3RVX-EjectOSD", L"3RVX-EjectOSD") {

    Skin *skin = SkinManager::Instance()->CurrentSkin();
    _mWnd.BackgroundImage(skin->ejectBackground);
    _mWnd.EnableGlass(skin->ejectMask);
    _mWnd.Update();

    OSD::InitMeterWnd(_mWnd);
}

void EjectOSD::EjectDrive(std::wstring driveLetter) {
    std::wstring name = L"\\\\.\\" + driveLetter + L":";
    CLOG(L"Ejecting %s", name.c_str());

    HANDLE dev = CreateFile(name.c_str(),
        GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
    if (dev == INVALID_HANDLE_VALUE) {
        CLOG(L"Failed to get device handle");
        return;
    }

    DWORD bytesReturned = 0;
    bool success = DeviceIoControl(dev, FSCTL_LOCK_VOLUME,
        NULL, NULL, NULL, NULL, &bytesReturned, NULL)
    && DeviceIoControl(dev, FSCTL_DISMOUNT_VOLUME,
        NULL, NULL, NULL, NULL, &bytesReturned, NULL)
    && DeviceIoControl(dev, IOCTL_STORAGE_EJECT_MEDIA,
        NULL, NULL, NULL, NULL, &bytesReturned, NULL);

    if (success) {
        std::wstring rootPath = driveLetter + L":\\";
        if (GetDriveType(rootPath.c_str()) != DRIVE_CDROM) {
            int driveBit = (int) pow(2, (driveLetter.at(0) - 65));
            _ignoreDrives |= driveBit;
            CLOG(L"Added drive bit %d to ignore list", driveBit);
        }
        HideOthers(Eject);
        _mWnd.Show();
    }

    CloseHandle(dev);
}

void EjectOSD::Hide() {
    _mWnd.Hide(false);
}

void EjectOSD::ProcessHotkeys(HotkeyInfo &hki) {
    switch (hki.action) {
    case HotkeyInfo::EjectDrive:
        if (hki.args.size() > 0) {
            EjectDrive(hki.args[0]);
        }
        break;

    case HotkeyInfo::EjectLastDisk:
        if (_latestDrive != 0) {
            wchar_t letter = MaskToDriveLetter(_latestDrive);
            std::wstring lStr(1, letter);
            EjectDrive(lStr);
            _latestDrive = 0;
        }

        break;
    }
}

LRESULT
EjectOSD::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    if (message == WM_DEVICECHANGE && wParam == DBT_DEVICEREMOVECOMPLETE) {
        PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lParam;
        if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) {
            PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME) lpdb;

            DWORD driveMask = lpdbv->dbcv_unitmask;
            CLOG(L"Eject notification received for drive %c:",
                MaskToDriveLetter(driveMask));

            if (driveMask & _ignoreDrives) {
                CLOG(L"Drive already ejected by a hotkey; not displaying OSD.");
                _ignoreDrives ^= driveMask;
            } else {
                HideOthers(Eject);
                _mWnd.Show();
            }

            if (_latestDrive == driveMask) {
                _latestDrive = 0;
            }
        }
    }

    if (message == WM_DEVICECHANGE && wParam == DBT_DEVICEARRIVAL) {
        PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lParam;
        if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) {
            PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME) lpdb;

            if (lpdbv->dbcv_flags != DBTF_NET) {
                _latestDrive = lpdbv->dbcv_unitmask;

                CLOG(L"Media inserted in drive %c:",
                    MaskToDriveLetter(_latestDrive));
            }
        }
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}

DWORD EjectOSD::DriveLetterToMask(wchar_t letter) {
    if (letter < 65 || letter > 90) {
        return 0;
    }

    return (DWORD) pow(2, (letter - 65));
}

wchar_t EjectOSD::MaskToDriveLetter(DWORD mask) {
    return (wchar_t) (log2(mask) + 65);
}
<commit_msg>Update eject OSD for skin interface changes<commit_after>#include "EjectOSD.h"

#include <Dbt.h>

#include "../HotkeyInfo.h"
#include "../Monitor.h"
#include "../Skin/OSDComponent.h"
#include "../Skin/Skin.h"
#include "../Skin/SkinManager.h"

EjectOSD::EjectOSD() :
OSD(L"3RVX-EjectDispatcher"),
_mWnd(L"3RVX-EjectOSD", L"3RVX-EjectOSD") {

    Skin *skin = SkinManager::Instance()->CurrentSkin();
    _mWnd.BackgroundImage(skin->EjectOSD()->background);
    _mWnd.EnableGlass(skin->EjectOSD()->mask);
    _mWnd.Update();

    OSD::InitMeterWnd(_mWnd);
}

void EjectOSD::EjectDrive(std::wstring driveLetter) {
    std::wstring name = L"\\\\.\\" + driveLetter + L":";
    CLOG(L"Ejecting %s", name.c_str());

    HANDLE dev = CreateFile(name.c_str(),
        GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
    if (dev == INVALID_HANDLE_VALUE) {
        CLOG(L"Failed to get device handle");
        return;
    }

    DWORD bytesReturned = 0;
    bool success = DeviceIoControl(dev, FSCTL_LOCK_VOLUME,
        NULL, NULL, NULL, NULL, &bytesReturned, NULL)
    && DeviceIoControl(dev, FSCTL_DISMOUNT_VOLUME,
        NULL, NULL, NULL, NULL, &bytesReturned, NULL)
    && DeviceIoControl(dev, IOCTL_STORAGE_EJECT_MEDIA,
        NULL, NULL, NULL, NULL, &bytesReturned, NULL);

    if (success) {
        std::wstring rootPath = driveLetter + L":\\";
        if (GetDriveType(rootPath.c_str()) != DRIVE_CDROM) {
            int driveBit = (int) pow(2, (driveLetter.at(0) - 65));
            _ignoreDrives |= driveBit;
            CLOG(L"Added drive bit %d to ignore list", driveBit);
        }
        HideOthers(Eject);
        _mWnd.Show();
    }

    CloseHandle(dev);
}

void EjectOSD::Hide() {
    _mWnd.Hide(false);
}

void EjectOSD::ProcessHotkeys(HotkeyInfo &hki) {
    switch (hki.action) {
    case HotkeyInfo::EjectDrive:
        if (hki.args.size() > 0) {
            EjectDrive(hki.args[0]);
        }
        break;

    case HotkeyInfo::EjectLastDisk:
        if (_latestDrive != 0) {
            wchar_t letter = MaskToDriveLetter(_latestDrive);
            std::wstring lStr(1, letter);
            EjectDrive(lStr);
            _latestDrive = 0;
        }

        break;
    }
}

LRESULT
EjectOSD::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    if (message == WM_DEVICECHANGE && wParam == DBT_DEVICEREMOVECOMPLETE) {
        PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lParam;
        if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) {
            PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME) lpdb;

            DWORD driveMask = lpdbv->dbcv_unitmask;
            CLOG(L"Eject notification received for drive %c:",
                MaskToDriveLetter(driveMask));

            if (driveMask & _ignoreDrives) {
                CLOG(L"Drive already ejected by a hotkey; not displaying OSD.");
                _ignoreDrives ^= driveMask;
            } else {
                HideOthers(Eject);
                _mWnd.Show();
            }

            if (_latestDrive == driveMask) {
                _latestDrive = 0;
            }
        }
    }

    if (message == WM_DEVICECHANGE && wParam == DBT_DEVICEARRIVAL) {
        PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lParam;
        if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) {
            PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME) lpdb;

            if (lpdbv->dbcv_flags != DBTF_NET) {
                _latestDrive = lpdbv->dbcv_unitmask;

                CLOG(L"Media inserted in drive %c:",
                    MaskToDriveLetter(_latestDrive));
            }
        }
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}

DWORD EjectOSD::DriveLetterToMask(wchar_t letter) {
    if (letter < 65 || letter > 90) {
        return 0;
    }

    return (DWORD) pow(2, (letter - 65));
}

wchar_t EjectOSD::MaskToDriveLetter(DWORD mask) {
    return (wchar_t) (log2(mask) + 65);
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

// mapnik
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <mapnik/util/spirit_transform_attribute.hpp>

// boost
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/fusion/include/at.hpp>

namespace mapnik { namespace json {

namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;

template <typename OutputIterator, typename Geometry>
geometry_generator_grammar<OutputIterator, Geometry>::geometry_generator_grammar()
    : geometry_generator_grammar::base_type(geometry)
{
    boost::spirit::karma::_val_type _val;
    boost::spirit::karma::_1_type _1;
    boost::spirit::karma::_a_type _a;
    boost::spirit::karma::lit_type lit;
    boost::spirit::karma::uint_type uint_;
    boost::spirit::karma::eps_type eps;

    geometry = geometry_dispatch.alias()
        ;

    geometry_dispatch = eps[_a = geometry_type(_val)] <<
        (&uint_(new_geometry::geometry_types::Point)[_1 = _a]
         << point)
        |
        (&uint_(new_geometry::geometry_types::LineString)[_1 = _a]
         << linestring )
        |
        (&uint_(new_geometry::geometry_types::Polygon)[_1 = _a]
         << polygon )
        |
        (&uint_(new_geometry::geometry_types::MultiPoint)[_1 = _a]
         << multi_point)
        |
        (&uint_(new_geometry::geometry_types::MultiLineString)[_1 = _a]
         << multi_linestring)
        |
        (&uint_(new_geometry::geometry_types::MultiPolygon)[_1 = _a]
         << multi_polygon)
        |
        (&uint_(new_geometry::geometry_types::GeometryCollection)[_1 = _a]
         << geometry_collection)
        ;

    point = lit("{\"type\":\"Point\",\"coordinates\":") << point_coord << lit("}")
        ;
    linestring = lit("{\"type\":\"LineString\",\"coordinates\":[") << linestring_coord << lit("]}")
        ;
    polygon = lit("{\"type\":\"Polygon\",\"coordinates\":[") << polygon_coord << lit("]}")
        ;
    multi_point = lit("{\"type\":\"MultiPoint\",\"coordinates\":[") << multi_point_coord << lit("]}")
        ;
    multi_linestring = lit("{\"type\":\"MultiLineString\",\"coordinates\":[") << multi_linestring_coord << lit("]}")
        ;
    multi_polygon = lit("{\"type\":\"MultiPolygon\",\"coordinates\":[") << multi_polygon_coord << lit("]}")
        ;
    geometry_collection = lit("{\"type\":\"GeometryCollection\",\"geometries\":[") << geometries  << lit("]}")
        ;
    point_coord = lit('[') << coordinate << lit(',') << coordinate  << lit(']')
        ;
    linestring_coord = point_coord % lit(',')
        ;
    polygon_coord = lit('[') << exterior_ring_coord << lit(']') << interior_ring_coord
        ;
    exterior_ring_coord = linestring_coord.alias()
        ;
    interior_ring_coord =  *(lit(",[") << exterior_ring_coord << lit(']'))
        ;
    multi_point_coord = linestring_coord.alias()
        ;
    multi_linestring_coord = linestring_coord % lit(',')
        ;
    multi_polygon_coord = polygon_coord % lit(',')
        ;
    geometries =  geometry % lit(',')
        ;
}

}}
<commit_msg>geojson - fix brackets blues<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

// mapnik
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <mapnik/util/spirit_transform_attribute.hpp>

// boost
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/fusion/include/at.hpp>

namespace mapnik { namespace json {

namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;

template <typename OutputIterator, typename Geometry>
geometry_generator_grammar<OutputIterator, Geometry>::geometry_generator_grammar()
    : geometry_generator_grammar::base_type(geometry)
{
    boost::spirit::karma::_val_type _val;
    boost::spirit::karma::_1_type _1;
    boost::spirit::karma::_a_type _a;
    boost::spirit::karma::lit_type lit;
    boost::spirit::karma::uint_type uint_;
    boost::spirit::karma::eps_type eps;

    geometry = geometry_dispatch.alias()
        ;

    geometry_dispatch = eps[_a = geometry_type(_val)] <<
        (&uint_(new_geometry::geometry_types::Point)[_1 = _a]
         << point)
        |
        (&uint_(new_geometry::geometry_types::LineString)[_1 = _a]
         << linestring )
        |
        (&uint_(new_geometry::geometry_types::Polygon)[_1 = _a]
         << polygon )
        |
        (&uint_(new_geometry::geometry_types::MultiPoint)[_1 = _a]
         << multi_point)
        |
        (&uint_(new_geometry::geometry_types::MultiLineString)[_1 = _a]
         << multi_linestring)
        |
        (&uint_(new_geometry::geometry_types::MultiPolygon)[_1 = _a]
         << multi_polygon)
        |
        (&uint_(new_geometry::geometry_types::GeometryCollection)[_1 = _a]
         << geometry_collection)
        ;

    point = lit("{\"type\":\"Point\",\"coordinates\":") << point_coord << lit("}")
        ;
    linestring = lit("{\"type\":\"LineString\",\"coordinates\":[") << linestring_coord << lit("]}")
        ;
    polygon = lit("{\"type\":\"Polygon\",\"coordinates\":[") << polygon_coord << lit("]}")
        ;
    multi_point = lit("{\"type\":\"MultiPoint\",\"coordinates\":[") << multi_point_coord << lit("]}")
        ;
    multi_linestring = lit("{\"type\":\"MultiLineString\",\"coordinates\":[") << multi_linestring_coord << lit("]}")
        ;
    multi_polygon = lit("{\"type\":\"MultiPolygon\",\"coordinates\":[") << multi_polygon_coord << lit("]}")
        ;
    geometry_collection = lit("{\"type\":\"GeometryCollection\",\"geometries\":[") << geometries  << lit("]}")
        ;
    point_coord = lit('[') << coordinate << lit(',') << coordinate  << lit(']')
        ;
    linestring_coord = point_coord % lit(',')
        ;
    polygon_coord = lit('[') << exterior_ring_coord << lit(']') << interior_ring_coord
        ;
    exterior_ring_coord = linestring_coord.alias()
        ;
    interior_ring_coord =  *(lit(",[") << exterior_ring_coord << lit(']'))
        ;
    multi_point_coord = linestring_coord.alias()
        ;
    multi_linestring_coord = (lit('[') << linestring_coord << lit(']')) % lit(',')
        ;
    multi_polygon_coord = (lit('[') << polygon_coord << lit(']')) % lit(',')
        ;
    geometries =  geometry % lit(',')
        ;
}

}}
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * 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 <votca/csg/topology.h>
#include <votca/csg/interaction.h>
#include <votca/tools/rangeparser.h>
#include <stdexcept>

namespace votca { namespace csg {

Topology::~Topology()
{
    Cleanup();
    if(_bc)
        delete (_bc);
    _bc = NULL;
}

void Topology::Cleanup()
{
    // cleanup beads
    {
        BeadContainer::iterator i;
        for(i=_beads.begin();i<_beads.end();++i)
            delete *i;
        _beads.clear();
    }
    // cleanup molecules
    {
        MoleculeContainer::iterator i;
        for(i=_molecules.begin();i<_molecules.end();++i)
            delete *i;
        _molecules.clear();
    }
    // cleanup residues
    {
        ResidueContainer::iterator i;
        for(i=_residues.begin();i<_residues.end();++i)
            delete (*i);
        _residues.clear();
    }
    // cleanup interactions
    {
        InteractionContainer::iterator i;
        for(i=_interactions.begin();i<_interactions.end();++i)
            delete (*i);
        _interactions.clear();
    }
    // cleanup _bc object
    if(_bc)
        delete (_bc);
    _bc = new OpenBox();
}

/// \todo implement checking!!
void Topology::CreateMoleculesByRange(string name, int first, int nbeads, int nmolecules)
{
    Molecule *mol = CreateMolecule(name);
    int beadcount=0;

    BeadContainer::iterator bead;
    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
        if(first-- > 0) continue;
        string bname = //lexical_cast<string>(mol->getId()) + ":"
                      //lexical_cast<string>(bead->Residue()) + ":"
                      //+
                      (*bead)->getName();
        mol->AddBead((*bead), bname);
        if(++beadcount == nbeads) {
            if(--nmolecules <= 0) break;
            mol = CreateMolecule(name);
            beadcount = 0;
        }
    }
}

/// \todo clean up CreateMoleculesByResidue!
void Topology::CreateMoleculesByResidue()
{
    // first create a molecule for each residue
    ResidueContainer::iterator res;
    for(res=_residues.begin(); res!=_residues.end(); ++res) {
        CreateMolecule((*res)->getName());
    }

    // add the beads to the corresponding molecules based on their resid
    BeadContainer::iterator bead;
    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
        //MoleculeByIndex((*bead)->getResnr())->AddBead((*bead)->getId(), (*bead)->getName());

        MoleculeByIndex((*bead)->getResnr())->AddBead((*bead), string("1:TRI:") + (*bead)->getName());
    }

    /// \todo sort beads in molecules that all beads are stored in the same order. This is needed for the mapping!
}

void Topology::CreateOneBigMolecule(string name)
{
    Molecule *mi = CreateMolecule(name);

    BeadContainer::iterator bead;

    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
        stringstream n("");
        n << (*bead)->getResnr() +1 << ":" <<  _residues[(*bead)->getResnr()]->getName() << ":" << (*bead)->getName();
        //cout << n.str() << endl;
        mi->AddBead((*bead), n.str());
    }
}

void Topology::Add(Topology *top)
{
    BeadContainer::iterator bead;
    ResidueContainer::iterator res;
    MoleculeContainer::iterator mol;

    int res0=ResidueCount();

    for(bead=top->_beads.begin(); bead!=top->_beads.end(); ++bead) {
        Bead *bi = *bead;
        BeadType *type =  GetOrCreateBeadType(bi->getType()->getName());
        CreateBead(bi->getSymmetry(), bi->getName(), type, bi->getResnr()+res0, bi->getM(), bi->getQ());
    }

    for(res=top->_residues.begin();res!=top->_residues.end(); ++res) {
        CreateResidue((*res)->getName());
    }

    // \todo beadnames in molecules!!
    for(mol=top->_molecules.begin();mol!=top->_molecules.end(); ++mol) {
        Molecule *mi = CreateMolecule((*mol)->getName());
        for(int i=0; i<mi->BeadCount(); i++) {
            mi->AddBead(mi->getBead(i), "invalid");
        }
    }
}

void Topology::CopyTopologyData(Topology *top)
{
    BeadContainer::iterator it_bead;
    ResidueContainer::iterator it_res;
    MoleculeContainer::iterator it_mol;
    InteractionContainer::iterator it_ia;

    _bc->setBox(top->getBox());
    _time = top->_time;
    _step = top->_step;

    // cleanup old data
    Cleanup();

    // copy all residues
    for(it_res=top->_residues.begin();it_res!=top->_residues.end(); ++it_res) {
        CreateResidue((*it_res)->getName());
    }

    // create all beads
    for(it_bead=top->_beads.begin(); it_bead!=top->_beads.end(); ++it_bead) {
        Bead *bi = *it_bead;
        BeadType *type =  GetOrCreateBeadType(bi->getType()->getName());
        Bead *bn = CreateBead(bi->getSymmetry(), bi->getName(), type, bi->getResnr(), bi->getM(), bi->getQ());
        bn->setOptions(bi->Options());
    }

    // copy all molecules
    for(it_mol=top->_molecules.begin();it_mol!=top->_molecules.end(); ++it_mol) {
        Molecule *mi = CreateMolecule((*it_mol)->getName());
        for(int i=0; i<(*it_mol)->BeadCount(); i++) {
            int beadid = (*it_mol)->getBead(i)->getId();
            mi->AddBead(_beads[beadid], (*it_mol)->getBeadName(i));
        }
    }
    // TODO: copy interactions
    //for(it_ia=top->_interaction.begin();it_ia=top->_interactions.end();++it_ia) {

    //}
}

void Topology::RenameMolecules(string range, string name)
{
    RangeParser rp;
    RangeParser::iterator i;

    rp.Parse(range);
    for(i=rp.begin();i!=rp.end();++i) {
        if((unsigned int)*i > _molecules.size())
            throw runtime_error(string("RenameMolecules: num molecules smaller than"));
        getMolecule(*i-1)->setName(name);
    }
}

void Topology::CheckMoleculeNaming(void)
{
    map<string,int> nbeads;

    for(MoleculeContainer::iterator iter = _molecules.begin(); iter!=_molecules.end(); ++iter) {
        map<string,int>::iterator entry = nbeads.find((*iter)->getName());
        if(entry != nbeads.end()) {
            if(entry->second != (*iter)->BeadCount())
                throw runtime_error("There are molecules which have the same name but different number of bead "
                        "please check the section manual topology handling in the votca manual");
            continue;
        }
        nbeads[(*iter)->getName()] = (*iter)->BeadCount();
    }
}

void Topology::AddBondedInteraction(Interaction *ic)
{
    map<string,int>::iterator iter;
    iter = _interaction_groups.find(ic->getGroup());
    if(iter!=_interaction_groups.end())
        ic->setGroupId((*iter).second);
    else {
        int i= _interaction_groups.size();
        _interaction_groups[ic->getGroup()] = i;
        ic->setGroupId(i);
    }
    _interactions.push_back(ic);
    _interactions_by_group[ic->getGroup()].push_back(ic);
}

std::list<Interaction *> Topology::InteractionsInGroup(const string &group)
{
    map<string, list<Interaction*> >::iterator iter;
    iter = _interactions_by_group.find(group);
    if(iter == _interactions_by_group.end())
        return list<Interaction *>();
    return iter->second;
}

BeadType *Topology::GetOrCreateBeadType(string name)
{
    map<string, int>::iterator iter;

    iter = _beadtype_map.find(name);
    if(iter == _beadtype_map.end()) {
        BeadType *bt = new BeadType(this, _beadtypes.size(), name);
        _beadtypes.push_back(bt);
        _beadtype_map[name] = bt->getId();
        return bt;
    }
    else {
        return _beadtypes[(*iter).second];
    }
    return NULL;
}

vec Topology::BCShortestConnection(const vec &r_i, const vec &r_j) const
{
    return _bc->BCShortestConnection(r_i, r_j);
}

vec Topology::getDist(int bead1, int bead2) const
{
    return BCShortestConnection(
            getBead(bead1)->getPos(),
            getBead(bead2)->getPos());
}

double Topology::BoxVolume()
{
    return _bc->BoxVolume();
}

void Topology::RebuildExclusions()
{
    _exclusions.CreateExclusions(this);
}

BoundaryCondition::eBoxtype Topology::autoDetectBoxType(const matrix &box) {
    // set the box type to OpenBox in case "box" is the zero matrix,
    // to OrthorhombicBox in case "box" is a diagonal matrix,
    // or to TriclinicBox otherwise
    if(box.get(0,0)==0 && box.get(0,1)==0 && box.get(0,2)==0 &&
       box.get(1,0)==0 && box.get(1,1)==0 && box.get(1,2)==0 &&
       box.get(2,0)==0 && box.get(2,1)==0 && box.get(2,2)==0) {
        //cout << "box open\n";
        return BoundaryCondition::typeOpen;
    }
    else
    if(box.get(0,1)==0 && box.get(0,2)==0 &&
       box.get(1,0)==0 && box.get(1,2)==0 &&
       box.get(2,0)==0 && box.get(2,1)==0) {
        //cout << "box orth\n";
        return BoundaryCondition::typeOrthorhombic;
    }
    else {
        //cout << "box tric\n";
        return BoundaryCondition::typeTriclinic;
    }
    return BoundaryCondition::typeOpen;
}

double Topology::ShortestBoxSize()
{
    vec _box_a = getBox().getCol(0);
    vec _box_b = getBox().getCol(1);
    vec _box_c = getBox().getCol(2);

    // create plane normals
    vec _norm_a = _box_b ^ _box_c;
    vec _norm_b = _box_c ^ _box_a;
    vec _norm_c = _box_a ^ _box_b;

    _norm_a.normalize();
    _norm_b.normalize();
    _norm_c.normalize();

    double la = _box_a * _norm_a;
    double lb = _box_b * _norm_b;
    double lc = _box_c * _norm_c;

    return min(la, min(lb, lc));
}

}}
<commit_msg>CreateMoleculesByRange: first should >=1<commit_after>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * 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 <votca/csg/topology.h>
#include <votca/csg/interaction.h>
#include <votca/tools/rangeparser.h>
#include <stdexcept>

namespace votca { namespace csg {

Topology::~Topology()
{
    Cleanup();
    if(_bc)
        delete (_bc);
    _bc = NULL;
}

void Topology::Cleanup()
{
    // cleanup beads
    {
        BeadContainer::iterator i;
        for(i=_beads.begin();i<_beads.end();++i)
            delete *i;
        _beads.clear();
    }
    // cleanup molecules
    {
        MoleculeContainer::iterator i;
        for(i=_molecules.begin();i<_molecules.end();++i)
            delete *i;
        _molecules.clear();
    }
    // cleanup residues
    {
        ResidueContainer::iterator i;
        for(i=_residues.begin();i<_residues.end();++i)
            delete (*i);
        _residues.clear();
    }
    // cleanup interactions
    {
        InteractionContainer::iterator i;
        for(i=_interactions.begin();i<_interactions.end();++i)
            delete (*i);
        _interactions.clear();
    }
    // cleanup _bc object
    if(_bc)
        delete (_bc);
    _bc = new OpenBox();
}

/// \todo implement checking!!
void Topology::CreateMoleculesByRange(string name, int first, int nbeads, int nmolecules)
{
    Molecule *mol = CreateMolecule(name);
    int beadcount=0;

    BeadContainer::iterator bead;
    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
	//xml numbering starts with 1
        if(--first > 0) continue;
        string bname = //lexical_cast<string>(mol->getId()) + ":"
                      //lexical_cast<string>(bead->Residue()) + ":"
                      //+
                      (*bead)->getName();
        mol->AddBead((*bead), bname);
        if(++beadcount == nbeads) {
            if(--nmolecules <= 0) break;
            mol = CreateMolecule(name);
            beadcount = 0;
        }
    }
}

/// \todo clean up CreateMoleculesByResidue!
void Topology::CreateMoleculesByResidue()
{
    // first create a molecule for each residue
    ResidueContainer::iterator res;
    for(res=_residues.begin(); res!=_residues.end(); ++res) {
        CreateMolecule((*res)->getName());
    }

    // add the beads to the corresponding molecules based on their resid
    BeadContainer::iterator bead;
    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
        //MoleculeByIndex((*bead)->getResnr())->AddBead((*bead)->getId(), (*bead)->getName());

        MoleculeByIndex((*bead)->getResnr())->AddBead((*bead), string("1:TRI:") + (*bead)->getName());
    }

    /// \todo sort beads in molecules that all beads are stored in the same order. This is needed for the mapping!
}

void Topology::CreateOneBigMolecule(string name)
{
    Molecule *mi = CreateMolecule(name);

    BeadContainer::iterator bead;

    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
        stringstream n("");
        n << (*bead)->getResnr() +1 << ":" <<  _residues[(*bead)->getResnr()]->getName() << ":" << (*bead)->getName();
        //cout << n.str() << endl;
        mi->AddBead((*bead), n.str());
    }
}

void Topology::Add(Topology *top)
{
    BeadContainer::iterator bead;
    ResidueContainer::iterator res;
    MoleculeContainer::iterator mol;

    int res0=ResidueCount();

    for(bead=top->_beads.begin(); bead!=top->_beads.end(); ++bead) {
        Bead *bi = *bead;
        BeadType *type =  GetOrCreateBeadType(bi->getType()->getName());
        CreateBead(bi->getSymmetry(), bi->getName(), type, bi->getResnr()+res0, bi->getM(), bi->getQ());
    }

    for(res=top->_residues.begin();res!=top->_residues.end(); ++res) {
        CreateResidue((*res)->getName());
    }

    // \todo beadnames in molecules!!
    for(mol=top->_molecules.begin();mol!=top->_molecules.end(); ++mol) {
        Molecule *mi = CreateMolecule((*mol)->getName());
        for(int i=0; i<mi->BeadCount(); i++) {
            mi->AddBead(mi->getBead(i), "invalid");
        }
    }
}

void Topology::CopyTopologyData(Topology *top)
{
    BeadContainer::iterator it_bead;
    ResidueContainer::iterator it_res;
    MoleculeContainer::iterator it_mol;
    InteractionContainer::iterator it_ia;

    _bc->setBox(top->getBox());
    _time = top->_time;
    _step = top->_step;

    // cleanup old data
    Cleanup();

    // copy all residues
    for(it_res=top->_residues.begin();it_res!=top->_residues.end(); ++it_res) {
        CreateResidue((*it_res)->getName());
    }

    // create all beads
    for(it_bead=top->_beads.begin(); it_bead!=top->_beads.end(); ++it_bead) {
        Bead *bi = *it_bead;
        BeadType *type =  GetOrCreateBeadType(bi->getType()->getName());
        Bead *bn = CreateBead(bi->getSymmetry(), bi->getName(), type, bi->getResnr(), bi->getM(), bi->getQ());
        bn->setOptions(bi->Options());
    }

    // copy all molecules
    for(it_mol=top->_molecules.begin();it_mol!=top->_molecules.end(); ++it_mol) {
        Molecule *mi = CreateMolecule((*it_mol)->getName());
        for(int i=0; i<(*it_mol)->BeadCount(); i++) {
            int beadid = (*it_mol)->getBead(i)->getId();
            mi->AddBead(_beads[beadid], (*it_mol)->getBeadName(i));
        }
    }
    // TODO: copy interactions
    //for(it_ia=top->_interaction.begin();it_ia=top->_interactions.end();++it_ia) {

    //}
}

void Topology::RenameMolecules(string range, string name)
{
    RangeParser rp;
    RangeParser::iterator i;

    rp.Parse(range);
    for(i=rp.begin();i!=rp.end();++i) {
        if((unsigned int)*i > _molecules.size())
            throw runtime_error(string("RenameMolecules: num molecules smaller than"));
        getMolecule(*i-1)->setName(name);
    }
}

void Topology::CheckMoleculeNaming(void)
{
    map<string,int> nbeads;

    for(MoleculeContainer::iterator iter = _molecules.begin(); iter!=_molecules.end(); ++iter) {
        map<string,int>::iterator entry = nbeads.find((*iter)->getName());
        if(entry != nbeads.end()) {
            if(entry->second != (*iter)->BeadCount())
                throw runtime_error("There are molecules which have the same name but different number of bead "
                        "please check the section manual topology handling in the votca manual");
            continue;
        }
        nbeads[(*iter)->getName()] = (*iter)->BeadCount();
    }
}

void Topology::AddBondedInteraction(Interaction *ic)
{
    map<string,int>::iterator iter;
    iter = _interaction_groups.find(ic->getGroup());
    if(iter!=_interaction_groups.end())
        ic->setGroupId((*iter).second);
    else {
        int i= _interaction_groups.size();
        _interaction_groups[ic->getGroup()] = i;
        ic->setGroupId(i);
    }
    _interactions.push_back(ic);
    _interactions_by_group[ic->getGroup()].push_back(ic);
}

std::list<Interaction *> Topology::InteractionsInGroup(const string &group)
{
    map<string, list<Interaction*> >::iterator iter;
    iter = _interactions_by_group.find(group);
    if(iter == _interactions_by_group.end())
        return list<Interaction *>();
    return iter->second;
}

BeadType *Topology::GetOrCreateBeadType(string name)
{
    map<string, int>::iterator iter;

    iter = _beadtype_map.find(name);
    if(iter == _beadtype_map.end()) {
        BeadType *bt = new BeadType(this, _beadtypes.size(), name);
        _beadtypes.push_back(bt);
        _beadtype_map[name] = bt->getId();
        return bt;
    }
    else {
        return _beadtypes[(*iter).second];
    }
    return NULL;
}

vec Topology::BCShortestConnection(const vec &r_i, const vec &r_j) const
{
    return _bc->BCShortestConnection(r_i, r_j);
}

vec Topology::getDist(int bead1, int bead2) const
{
    return BCShortestConnection(
            getBead(bead1)->getPos(),
            getBead(bead2)->getPos());
}

double Topology::BoxVolume()
{
    return _bc->BoxVolume();
}

void Topology::RebuildExclusions()
{
    _exclusions.CreateExclusions(this);
}

BoundaryCondition::eBoxtype Topology::autoDetectBoxType(const matrix &box) {
    // set the box type to OpenBox in case "box" is the zero matrix,
    // to OrthorhombicBox in case "box" is a diagonal matrix,
    // or to TriclinicBox otherwise
    if(box.get(0,0)==0 && box.get(0,1)==0 && box.get(0,2)==0 &&
       box.get(1,0)==0 && box.get(1,1)==0 && box.get(1,2)==0 &&
       box.get(2,0)==0 && box.get(2,1)==0 && box.get(2,2)==0) {
        //cout << "box open\n";
        return BoundaryCondition::typeOpen;
    }
    else
    if(box.get(0,1)==0 && box.get(0,2)==0 &&
       box.get(1,0)==0 && box.get(1,2)==0 &&
       box.get(2,0)==0 && box.get(2,1)==0) {
        //cout << "box orth\n";
        return BoundaryCondition::typeOrthorhombic;
    }
    else {
        //cout << "box tric\n";
        return BoundaryCondition::typeTriclinic;
    }
    return BoundaryCondition::typeOpen;
}

double Topology::ShortestBoxSize()
{
    vec _box_a = getBox().getCol(0);
    vec _box_b = getBox().getCol(1);
    vec _box_c = getBox().getCol(2);

    // create plane normals
    vec _norm_a = _box_b ^ _box_c;
    vec _norm_b = _box_c ^ _box_a;
    vec _norm_c = _box_a ^ _box_b;

    _norm_a.normalize();
    _norm_b.normalize();
    _norm_c.normalize();

    double la = _box_a * _norm_a;
    double lb = _box_b * _norm_b;
    double lc = _box_c * _norm_c;

    return min(la, min(lb, lc));
}

}}
<|endoftext|>


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

 The MIT License (MIT)

 Copyright (c) 2015 Dmitry Sovetov

 https://github.com/dmsovetov

 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 "WindowsWindow.h"

DC_BEGIN_DREEMCHEST

namespace platform {

// ** createWindow
IWindow* createWindow( u32 width, u32 height )
{
    WindowsWindow* window = DC_NEW WindowsWindow;

    if( window->create( width, height ) ) {
        return window;
    }

    delete window;
    return NULL;
}

WindowsWindow::Windows WindowsWindow::s_windows;

u32 WindowsWindow::s_windowCount = 0;

// ** WindowsWindow::WindowsWindow
WindowsWindow::WindowsWindow( void ) : m_owner( NULL ), m_window( NULL )
{

}

// ** WindowsWindow::~WindowsWindow
WindowsWindow::~WindowsWindow( void )
{

}

// ** WindowsWindow::close
void WindowsWindow::close( void )
{
	DC_BREAK_IF( m_window == NULL );

	// ** Destroy window
	if( !DestroyWindow( m_window ) ) {
		return;
	}

	// ** Free the window class
	if( !UnregisterClass( m_className.c_str(), m_applicationInstance ) ) {
		return;
	}

	// ** Remove window from registry
	int removed = s_windows.erase( m_window );
	DC_BREAK_IF( removed != 1 );

	m_window				= NULL;
	m_applicationInstance	= NULL;
}

// ** WindowsWindow::setOwner
void WindowsWindow::setOwner( Window* value )
{
    m_owner = value;
}

// ** WindowsWindow::owner
Window* WindowsWindow::owner( void ) const
{
    return m_owner;
}

// ** WindowsWindow::width
u32 WindowsWindow::width( void ) const
{
    RECT rect;
	GetWindowRect( m_window, &rect );
	return rect.right - rect.left;
}

// ** WindowsWindow::height
u32 WindowsWindow::height( void ) const
{
	RECT rect;
	GetWindowRect( m_window, &rect );
	return rect.bottom - rect.top;
}

// ** WindowsWindow::setCaption
void WindowsWindow::setCaption( const String& value )
{
    log::warn( "WindowsWindow::setCaption : window caption is not supported on Windows\n" );
}

// ** WindowsWindow::caption
String WindowsWindow::caption( void ) const
{
    return "";
}

// ** WindowsWindow::handle
void* WindowsWindow::handle( void ) const
{
    return reinterpret_cast<void*>( m_window );
}

// ** WindowsWindow::create
bool WindowsWindow::create( u32 width, u32 height )
{
	m_applicationInstance = GetModuleHandle( 0 );

	memset( &m_windowClass, 0, sizeof( m_windowClass ) );

	m_className = "dreemchest" + format::number( s_windowCount++ );

	m_windowClass.hCursor		= LoadCursor( NULL, IDC_ARROW );
	m_windowClass.hInstance		= m_applicationInstance;
	m_windowClass.lpfnWndProc	= ( WNDPROC )windowProc;
	m_windowClass.lpszClassName	= m_className.c_str();
	m_windowClass.style			= CS_HREDRAW | CS_VREDRAW;
	m_windowClass.hbrBackground	= ( HBRUSH )COLOR_GRAYTEXT;

	if( !RegisterClass( &m_windowClass ) ) {
		log::error( "WindowsWindow::create : failed to register window class" );
		return false;
	}

	u32 style	= WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
	u32 x		= ( GetSystemMetrics( SM_CXSCREEN ) / 2 ) - ( width  / 2 );
	u32 y		= ( GetSystemMetrics( SM_CYSCREEN ) / 2 ) - ( height / 2 );

	m_window = CreateWindowEx( 0,
		m_windowClass.lpszClassName, "",
		style,
		x, y,
		width, height,
		NULL, NULL, m_applicationInstance, NULL );

	if( !m_window ) {
		log::error( "WindowsWindow::create : failed to create window" );
		return false;
	}

	s_windows[m_window] = this;

	ShowWindow( m_window, SW_SHOW );
	SetFocus( m_window );

    return true;
}

// ** WindowsWindow::windowProc
LRESULT WindowsWindow::windowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
	WindowsWindow* window = s_windows[hWnd];

	switch( message ) {
	case WM_CLOSE:			window->owner()->release();
							if( s_windows.size() == 0 ) {
								PostQuitMessage( 0 );
							}
							break;

	case WM_KEYDOWN:		window->owner()->notifyKeyDown( translateKey( ( u32 )wParam ) );
							break;

	case WM_KEYUP:			window->owner()->notifyKeyUp( translateKey( ( u32 )wParam ) );
							break;

	case WM_LBUTTONDOWN:	window->owner()->notifyMouseDown( LOWORD( lParam ), HIWORD( lParam ) );
							break;

	case WM_LBUTTONUP:		window->owner()->notifyMouseUp( LOWORD( lParam ), HIWORD( lParam ) );
							break;

	case WM_RBUTTONDOWN:	break;

	case WM_RBUTTONUP:		break;

	case WM_CHAR:			break;

	}

	return DefWindowProc( hWnd, message, wParam, lParam );
}

// ** WindowsWindow::translateKey
Key WindowsWindow::translateKey( u32 vkey )
{
	switch( vkey ) {
		// ** Numbers
	case 0x30: return Key::_0; break;	// 0
	case 0x31: return Key::_1; break;	// 1
	case 0x32: return Key::_2; break;	// 2
	case 0x33: return Key::_3; break;	// 3
	case 0x34: return Key::_4; break;	// 4
	case 0x35: return Key::_5; break;	// 5
	case 0x36: return Key::_6; break;	// 6
	case 0x37: return Key::_7; break;	// 7
	case 0x38: return Key::_8; break;	// 8
	case 0x39: return Key::_9; break;	// 9

	case VK_NUMPAD0: return Key::Num0; break;
	case VK_NUMPAD1: return Key::Num1; break;
	case VK_NUMPAD2: return Key::Num2; break;
	case VK_NUMPAD3: return Key::Num3; break;
	case VK_NUMPAD4: return Key::Num4; break;
	case VK_NUMPAD5: return Key::Num5; break;
	case VK_NUMPAD6: return Key::Num6; break;
	case VK_NUMPAD7: return Key::Num7; break;
	case VK_NUMPAD8: return Key::Num8; break;
	case VK_NUMPAD9: return Key::Num9; break;

		// ** Characters
	case 0x41: return Key::A; break;	// A
	case 0x42: return Key::B; break;	// B
	case 0x43: return Key::C; break;	// C
	case 0x44: return Key::D; break;	// D
	case 0x45: return Key::E; break;	// E
	case 0x46: return Key::F; break;	// F
	case 0x47: return Key::G; break;	// G
	case 0x48: return Key::H; break;	// H
	case 0x49: return Key::I; break;	// I
	case 0x4A: return Key::J; break;	// J
	case 0x4B: return Key::K; break;	// K
	case 0x4C: return Key::L; break;	// L
	case 0x4D: return Key::M; break;	// M
	case 0x4E: return Key::N; break;	// N
	case 0x4F: return Key::O; break;	// O
	case 0x50: return Key::P; break;	// P
	case 0x51: return Key::Q; break;	// Q
	case 0x52: return Key::R; break;	// R
	case 0x53: return Key::S; break;	// S
	case 0x54: return Key::T; break;	// T
	case 0x55: return Key::U; break;	// U
	case 0x56: return Key::V; break;	// V
	case 0x57: return Key::W; break;	// W
	case 0x58: return Key::X; break;	// X
	case 0x59: return Key::Y; break;	// Y
	case 0x5A: return Key::Z; break;	// Z

		// ** Functional
	case VK_F1: return Key::F1; break;
	case VK_F2: return Key::F2; break;
	case VK_F3: return Key::F3; break;
	case VK_F4: return Key::F4; break;
	case VK_F5: return Key::F5; break;
	case VK_F6: return Key::F6; break;
	case VK_F7: return Key::F7; break;
	case VK_F8: return Key::F8; break;
	case VK_F9: return Key::F9; break;
	case VK_F10: return Key::F10; break;
	case VK_F11: return Key::F11; break;
	case VK_F12: return Key::F12; break;

	case VK_ESCAPE: return Key::Escape; break;
	case VK_TAB: return Key::Tab; break;
	case VK_CAPITAL: return Key::Capital; break;
	case VK_SHIFT: return Key::Shift; break;
	case VK_CONTROL: return Key::Control; break;
	case VK_LWIN: return Key::Win; break;
	case VK_MENU: return Key::Alt; break;
	case VK_SPACE: return Key::Space; break;

	case VK_RETURN: return Key::Return; break;
	case VK_BACK: return Key::Back; break;

	case VK_PAUSE: return Key::Pause; break;
	case VK_SNAPSHOT: return Key::Snapshot; break;
	case VK_SCROLL: return Key::Scroll; break;

	case VK_NEXT: return Key::PgDown; break;
	case VK_PRIOR: return Key::PgUp; break;
	case VK_HOME: return Key::Home; break;
	case VK_END: return Key::End; break;
	case VK_INSERT: return Key::Insert; break;
	case VK_DELETE: return Key::Delete; break;

	case VK_UP: return Key::Up; break;
	case VK_DOWN: return Key::Down; break;
	case VK_LEFT: return Key::Left; break;
	case VK_RIGHT: return Key::Right; break;

		// ** Numpad
	case VK_NUMLOCK: return Key::Numlock; break;
	case VK_DIVIDE: return Key::Divide; break;
	case VK_MULTIPLY: return Key::Multiply; break;
	case VK_SUBTRACT: return Key::Subtract; break;
	case VK_ADD: return Key::Add; break;
	case VK_DECIMAL: return Key::Decimal; break;

		// ** Mouse
	case VK_RBUTTON: return Key::RButton; break;
	case VK_LBUTTON: return Key::LButton; break;
	case VK_MBUTTON: return Key::MButton; break;
	};

	return Key::Total;
}

} // namespace platform

DC_END_DREEMCHEST<commit_msg>Fixed Windows window caption<commit_after>/**************************************************************************

 The MIT License (MIT)

 Copyright (c) 2015 Dmitry Sovetov

 https://github.com/dmsovetov

 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 "WindowsWindow.h"

DC_BEGIN_DREEMCHEST

namespace platform {

// ** createWindow
IWindow* createWindow( u32 width, u32 height )
{
    WindowsWindow* window = DC_NEW WindowsWindow;

    if( window->create( width, height ) ) {
        return window;
    }

    delete window;
    return NULL;
}

WindowsWindow::Windows WindowsWindow::s_windows;

u32 WindowsWindow::s_windowCount = 0;

// ** WindowsWindow::WindowsWindow
WindowsWindow::WindowsWindow( void ) : m_owner( NULL ), m_window( NULL )
{

}

// ** WindowsWindow::~WindowsWindow
WindowsWindow::~WindowsWindow( void )
{

}

// ** WindowsWindow::close
void WindowsWindow::close( void )
{
	DC_BREAK_IF( m_window == NULL );

	// ** Destroy window
	if( !DestroyWindow( m_window ) ) {
		return;
	}

	// ** Free the window class
	if( !UnregisterClass( m_className.c_str(), m_applicationInstance ) ) {
		return;
	}

	// ** Remove window from registry
	int removed = s_windows.erase( m_window );
	DC_BREAK_IF( removed != 1 );

	m_window				= NULL;
	m_applicationInstance	= NULL;
}

// ** WindowsWindow::setOwner
void WindowsWindow::setOwner( Window* value )
{
    m_owner = value;
}

// ** WindowsWindow::owner
Window* WindowsWindow::owner( void ) const
{
    return m_owner;
}

// ** WindowsWindow::width
u32 WindowsWindow::width( void ) const
{
    RECT rect;
	GetWindowRect( m_window, &rect );
	return rect.right - rect.left;
}

// ** WindowsWindow::height
u32 WindowsWindow::height( void ) const
{
	RECT rect;
	GetWindowRect( m_window, &rect );
	return rect.bottom - rect.top;
}

// ** WindowsWindow::setCaption
void WindowsWindow::setCaption( const String& value )
{
	SetWindowText( m_window, value.c_str() );
}

// ** WindowsWindow::caption
String WindowsWindow::caption( void ) const
{
	s8 text[128];
    GetWindowText( m_window, text, 128 );
	return text;
}

// ** WindowsWindow::handle
void* WindowsWindow::handle( void ) const
{
    return reinterpret_cast<void*>( m_window );
}

// ** WindowsWindow::create
bool WindowsWindow::create( u32 width, u32 height )
{
	m_applicationInstance = GetModuleHandle( 0 );

	memset( &m_windowClass, 0, sizeof( m_windowClass ) );

	m_className = "dreemchest" + format::number( s_windowCount++ );

	m_windowClass.hCursor		= LoadCursor( NULL, IDC_ARROW );
	m_windowClass.hInstance		= m_applicationInstance;
	m_windowClass.lpfnWndProc	= ( WNDPROC )windowProc;
	m_windowClass.lpszClassName	= m_className.c_str();
	m_windowClass.style			= CS_HREDRAW | CS_VREDRAW;
	m_windowClass.hbrBackground	= ( HBRUSH )COLOR_GRAYTEXT;

	if( !RegisterClass( &m_windowClass ) ) {
		log::error( "WindowsWindow::create : failed to register window class" );
		return false;
	}

	u32 style	= WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
	u32 x		= ( GetSystemMetrics( SM_CXSCREEN ) / 2 ) - ( width  / 2 );
	u32 y		= ( GetSystemMetrics( SM_CYSCREEN ) / 2 ) - ( height / 2 );

	m_window = CreateWindowEx( 0,
		m_windowClass.lpszClassName, "",
		style,
		x, y,
		width, height,
		NULL, NULL, m_applicationInstance, NULL );

	if( !m_window ) {
		log::error( "WindowsWindow::create : failed to create window" );
		return false;
	}

	s_windows[m_window] = this;

	ShowWindow( m_window, SW_SHOW );
	SetFocus( m_window );

    return true;
}

// ** WindowsWindow::windowProc
LRESULT WindowsWindow::windowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
	WindowsWindow* window = s_windows[hWnd];

	switch( message ) {
	case WM_CLOSE:			window->owner()->release();
							if( s_windows.size() == 0 ) {
								PostQuitMessage( 0 );
							}
							break;

	case WM_KEYDOWN:		window->owner()->notifyKeyDown( translateKey( ( u32 )wParam ) );
							break;

	case WM_KEYUP:			window->owner()->notifyKeyUp( translateKey( ( u32 )wParam ) );
							break;

	case WM_LBUTTONDOWN:	window->owner()->notifyMouseDown( LOWORD( lParam ), HIWORD( lParam ) );
							break;

	case WM_LBUTTONUP:		window->owner()->notifyMouseUp( LOWORD( lParam ), HIWORD( lParam ) );
							break;

	case WM_RBUTTONDOWN:	break;

	case WM_RBUTTONUP:		break;

	case WM_CHAR:			break;

	}

	return DefWindowProc( hWnd, message, wParam, lParam );
}

// ** WindowsWindow::translateKey
Key WindowsWindow::translateKey( u32 vkey )
{
	switch( vkey ) {
		// ** Numbers
	case 0x30: return Key::_0; break;	// 0
	case 0x31: return Key::_1; break;	// 1
	case 0x32: return Key::_2; break;	// 2
	case 0x33: return Key::_3; break;	// 3
	case 0x34: return Key::_4; break;	// 4
	case 0x35: return Key::_5; break;	// 5
	case 0x36: return Key::_6; break;	// 6
	case 0x37: return Key::_7; break;	// 7
	case 0x38: return Key::_8; break;	// 8
	case 0x39: return Key::_9; break;	// 9

	case VK_NUMPAD0: return Key::Num0; break;
	case VK_NUMPAD1: return Key::Num1; break;
	case VK_NUMPAD2: return Key::Num2; break;
	case VK_NUMPAD3: return Key::Num3; break;
	case VK_NUMPAD4: return Key::Num4; break;
	case VK_NUMPAD5: return Key::Num5; break;
	case VK_NUMPAD6: return Key::Num6; break;
	case VK_NUMPAD7: return Key::Num7; break;
	case VK_NUMPAD8: return Key::Num8; break;
	case VK_NUMPAD9: return Key::Num9; break;

		// ** Characters
	case 0x41: return Key::A; break;	// A
	case 0x42: return Key::B; break;	// B
	case 0x43: return Key::C; break;	// C
	case 0x44: return Key::D; break;	// D
	case 0x45: return Key::E; break;	// E
	case 0x46: return Key::F; break;	// F
	case 0x47: return Key::G; break;	// G
	case 0x48: return Key::H; break;	// H
	case 0x49: return Key::I; break;	// I
	case 0x4A: return Key::J; break;	// J
	case 0x4B: return Key::K; break;	// K
	case 0x4C: return Key::L; break;	// L
	case 0x4D: return Key::M; break;	// M
	case 0x4E: return Key::N; break;	// N
	case 0x4F: return Key::O; break;	// O
	case 0x50: return Key::P; break;	// P
	case 0x51: return Key::Q; break;	// Q
	case 0x52: return Key::R; break;	// R
	case 0x53: return Key::S; break;	// S
	case 0x54: return Key::T; break;	// T
	case 0x55: return Key::U; break;	// U
	case 0x56: return Key::V; break;	// V
	case 0x57: return Key::W; break;	// W
	case 0x58: return Key::X; break;	// X
	case 0x59: return Key::Y; break;	// Y
	case 0x5A: return Key::Z; break;	// Z

		// ** Functional
	case VK_F1: return Key::F1; break;
	case VK_F2: return Key::F2; break;
	case VK_F3: return Key::F3; break;
	case VK_F4: return Key::F4; break;
	case VK_F5: return Key::F5; break;
	case VK_F6: return Key::F6; break;
	case VK_F7: return Key::F7; break;
	case VK_F8: return Key::F8; break;
	case VK_F9: return Key::F9; break;
	case VK_F10: return Key::F10; break;
	case VK_F11: return Key::F11; break;
	case VK_F12: return Key::F12; break;

	case VK_ESCAPE: return Key::Escape; break;
	case VK_TAB: return Key::Tab; break;
	case VK_CAPITAL: return Key::Capital; break;
	case VK_SHIFT: return Key::Shift; break;
	case VK_CONTROL: return Key::Control; break;
	case VK_LWIN: return Key::Win; break;
	case VK_MENU: return Key::Alt; break;
	case VK_SPACE: return Key::Space; break;

	case VK_RETURN: return Key::Return; break;
	case VK_BACK: return Key::Back; break;

	case VK_PAUSE: return Key::Pause; break;
	case VK_SNAPSHOT: return Key::Snapshot; break;
	case VK_SCROLL: return Key::Scroll; break;

	case VK_NEXT: return Key::PgDown; break;
	case VK_PRIOR: return Key::PgUp; break;
	case VK_HOME: return Key::Home; break;
	case VK_END: return Key::End; break;
	case VK_INSERT: return Key::Insert; break;
	case VK_DELETE: return Key::Delete; break;

	case VK_UP: return Key::Up; break;
	case VK_DOWN: return Key::Down; break;
	case VK_LEFT: return Key::Left; break;
	case VK_RIGHT: return Key::Right; break;

		// ** Numpad
	case VK_NUMLOCK: return Key::Numlock; break;
	case VK_DIVIDE: return Key::Divide; break;
	case VK_MULTIPLY: return Key::Multiply; break;
	case VK_SUBTRACT: return Key::Subtract; break;
	case VK_ADD: return Key::Add; break;
	case VK_DECIMAL: return Key::Decimal; break;

		// ** Mouse
	case VK_RBUTTON: return Key::RButton; break;
	case VK_LBUTTON: return Key::LButton; break;
	case VK_MBUTTON: return Key::MButton; break;
	};

	return Key::Total;
}

} // namespace platform

DC_END_DREEMCHEST<|endoftext|>