<commit_before>/****************************************************************************
**
** This file is part of QtCompositor**
**
** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
**
** Contact:  Nokia Corporation qt-info@nokia.com
**
** You may use this file under the terms of the BSD license as follows:
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**
** Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
**
** Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
**
** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
****************************************************************************/

#include "wlcompositor.h"

#include "waylandobject.h"
#include "wldisplay.h"
#include "wlshmbuffer.h"
#include "wlsurface.h"
#include "waylandcompositor.h"

#include <QApplication>
#include <QDesktopWidget>

#include <QSocketNotifier>
#include <QDebug>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <sys/mman.h>
#include <sys/select.h>
#include <sys/time.h>

#include <wayland-server.h>

#include "hardware_integration/graphicshardwareintegration.h"

namespace Wayland {

void input_device_attach(struct wl_client *client,
                         struct wl_input_device *device_base,
                         uint32_t time,
                         struct wl_buffer *buffer, int32_t x, int32_t y)
{
    Q_UNUSED(client);
    Q_UNUSED(device_base);
    Q_UNUSED(time);
    Q_UNUSED(buffer);
    Q_UNUSED(x);
    Q_UNUSED(y);

    qDebug() << "Client %p input device attach" << client;
}

const static struct wl_input_device_interface input_device_interface = {
    input_device_attach,
};

void destroy_surface(struct wl_resource *resource, struct wl_client *client)
{
    Q_UNUSED(client);
    Surface *surface = wayland_cast<Surface *>((wl_surface *)resource);
    delete surface;
}

void compositor_create_surface(struct wl_client *client,
			       struct wl_compositor *compositor, uint32_t id)
{
    wayland_cast<Compositor *>(compositor)->createSurface(client, id);
}

const static struct wl_compositor_interface compositor_interface = {
    compositor_create_surface
};

void shell_move(struct wl_client *client,
                struct wl_shell *shell,
                struct wl_surface *surface,
                struct wl_input_device *input_device,
                uint32_t time)
{
    Q_UNUSED(client);
    Q_UNUSED(shell);
    Q_UNUSED(surface);
    Q_UNUSED(input_device);
    Q_UNUSED(time);
    qDebug() << "shellMove";
}

void shell_resize(struct wl_client *client,
                  struct wl_shell *shell,
                  struct wl_surface *surface,
                  struct wl_input_device *input_device,
                  uint32_t time,
                  uint32_t edges)
{
    Q_UNUSED(client);
    Q_UNUSED(shell);
    Q_UNUSED(surface);
    Q_UNUSED(input_device);
    Q_UNUSED(time);
    Q_UNUSED(edges);
    qDebug() << "shellResize";
}

void shell_drag(struct wl_client *client,
                struct wl_shell *shell,
                uint32_t id)
{
    Q_UNUSED(client);
    Q_UNUSED(shell);
    Q_UNUSED(id);
    qDebug() << "shellDrag";
}

void shell_selection(struct wl_client *client,
                     struct wl_shell *shell,
                     uint32_t id)
{
    Q_UNUSED(client);
    Q_UNUSED(shell);
    Q_UNUSED(id);
    qDebug() << "shellSelection";
}

const static struct wl_shell_interface shell_interface = {
    shell_move,
    shell_resize,
    shell_drag,
    shell_selection
};

Compositor::Compositor(WaylandCompositor *qt_compositor)
    : m_display(new Display)
    , m_shm(this)
    , m_current_frame(0)
    , m_last_queued_buf(-1)
    , m_qt_compositor(qt_compositor)
    , m_pointerFocusSurface(0)
    , m_keyFocusSurface(0)
{
#if defined (QT_COMPOSITOR_WAYLAND_GL)
    m_graphics_hw_integration = GraphicsHardwareIntegration::createGraphicsHardwareIntegration(qt_compositor);
#endif

    if (wl_compositor_init(base(), &compositor_interface, m_display->handle())) {
        fprintf(stderr, "Fatal: Error initializing compositor\n");
        exit(EXIT_FAILURE);
    }

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

    m_display->addGlobalObject(m_output.base(), &wl_output_interface, 0, output_post_geometry);
    m_display->addGlobalObject(&m_shell, &wl_shell_interface, &shell_interface, 0);
    m_display->addGlobalObject(m_shm.base(), &wl_shm_interface, &shm_interface, 0);

    wl_input_device_init(&m_input, base());
    m_display->addGlobalObject(&m_input.object, &wl_input_device_interface, &input_device_interface, 0);

    if (wl_display_add_socket(m_display->handle(), 0)) {
        fprintf(stderr, "Fatal: Failed to open server socket");
        exit(EXIT_FAILURE);
    }

    m_loop = wl_display_get_event_loop(m_display->handle());

    int fd = wl_event_loop_get_fd(m_loop);

    QSocketNotifier *sockNot = new QSocketNotifier(fd, QSocketNotifier::Read, this);
    connect(sockNot, SIGNAL(activated(int)), this, SLOT(processWaylandEvents()));
}

Compositor::~Compositor()
{
    delete m_display;
}

void Compositor::frameFinished()
{
    wl_display_post_frame(m_display->handle(), currentTimeMsecs());
}

void Compositor::createSurface(struct wl_client *client, int id)
{
    Surface *surface = new Surface(client, this);
    printf("Compositor::createSurface: %p %d\n", client, id);

    addClientResource(client, &surface->base()->resource, id, &wl_surface_interface,
            &surface_interface, destroy_surface);

    m_qt_compositor->surfaceCreated(surface->handle());

    m_surfaces << surface;
}

struct wl_client *Compositor::getClientFromWinId(uint winId) const
{
    Surface *surface = getSurfaceFromWinId(winId);
    if (surface)
        return surface->base()->client;

    return 0;
}

Surface *Compositor::getSurfaceFromWinId(uint winId) const
{
    foreach (Surface *surface, m_surfaces) {
        if (surface->id() == winId)
            return surface;
    }

    return 0;
}

QImage Compositor::image(uint winId) const
{
    printf("Compositor::image(%x)\n", winId);
    foreach (Surface *surface, m_surfaces) {
        if (surface->id() == winId) {
            return surface->image();
        }
    }

    return QImage();
}

//XXX: sort this out. Static function?
uint Compositor::currentTimeMsecs() const
{
    //### we throw away the time information
    struct timeval tv;
    int ret = gettimeofday(&tv, 0);
    if (ret == 0)
        return tv.tv_sec*1000 + tv.tv_usec/1000;
    return 0;
}

void Compositor::processWaylandEvents()
{
    int ret = wl_event_loop_dispatch(m_loop, 0);
    if (ret)
        fprintf(stderr, "wl_event_loop_dispatch error: %d\n", ret);
}

void Compositor::surfaceDestroyed(Surface *surface)
{
    m_surfaces.removeOne(surface);
    if (m_keyFocusSurface == surface)
        setKeyFocus(0);
    if (m_pointerFocusSurface == surface)
        setPointerFocus(0);
}

void Compositor::destroyClientForSurface(Surface *surface)
{
    wl_client *client = surface->base()->client;

    if (client)
        wl_client_destroy(client);
}

void Compositor::setInputFocus(Surface *surface)
{
    wl_surface *base = surface ? surface->base() : 0;

    ulong time = currentTimeMsecs();

    m_keyFocusSurface = surface;
    m_pointerFocusSurface = surface;
    wl_input_device_set_keyboard_focus(&m_input, base, time);
    wl_input_device_set_pointer_focus(&m_input, base, time, 0, 0, 0, 0);
}

void Compositor::setKeyFocus(Surface *surface)
{
    m_keyFocusSurface = surface;
    wl_input_device_set_keyboard_focus(&m_input, surface ? surface->base() : 0, currentTimeMsecs());
}

void Compositor::setPointerFocus(Surface *surface, const QPoint &pos)
{
    m_pointerFocusSurface = surface;
    wl_input_device_set_pointer_focus(&m_input, surface ? surface->base() : 0, currentTimeMsecs(), pos.x(), pos.y(), pos.x(), pos.y());
}

QWidget * Compositor::topLevelWidget() const
{
    return m_qt_compositor->topLevelWidget();
}

GraphicsHardwareIntegration * Compositor::graphicsHWIntegration() const
{
#ifdef QT_COMPOSITOR_WAYLAND_GL
    return m_graphics_hw_integration;
#else
    return 0;
#endif
}

void Compositor::initializeHardwareIntegration()
{
#ifdef QT_COMPOSITOR_WAYLAND_GL
    m_graphics_hw_integration->initializeHardware(m_display);
#endif
}

}

wl_input_device * Wayland::Compositor::defaultInputDevice()
{
    return &m_input;
}

<commit_msg>add missing \n in debug output<commit_after>/****************************************************************************
**
** This file is part of QtCompositor**
**
** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
**
** Contact:  Nokia Corporation qt-info@nokia.com
**
** You may use this file under the terms of the BSD license as follows:
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**
** Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
**
** Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
**
** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
****************************************************************************/

#include "wlcompositor.h"

#include "waylandobject.h"
#include "wldisplay.h"
#include "wlshmbuffer.h"
#include "wlsurface.h"
#include "waylandcompositor.h"

#include <QApplication>
#include <QDesktopWidget>

#include <QSocketNotifier>
#include <QDebug>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <sys/mman.h>
#include <sys/select.h>
#include <sys/time.h>

#include <wayland-server.h>

#include "hardware_integration/graphicshardwareintegration.h"

namespace Wayland {

void input_device_attach(struct wl_client *client,
                         struct wl_input_device *device_base,
                         uint32_t time,
                         struct wl_buffer *buffer, int32_t x, int32_t y)
{
    Q_UNUSED(client);
    Q_UNUSED(device_base);
    Q_UNUSED(time);
    Q_UNUSED(buffer);
    Q_UNUSED(x);
    Q_UNUSED(y);

    qDebug() << "Client %p input device attach" << client;
}

const static struct wl_input_device_interface input_device_interface = {
    input_device_attach,
};

void destroy_surface(struct wl_resource *resource, struct wl_client *client)
{
    Q_UNUSED(client);
    Surface *surface = wayland_cast<Surface *>((wl_surface *)resource);
    delete surface;
}

void compositor_create_surface(struct wl_client *client,
			       struct wl_compositor *compositor, uint32_t id)
{
    wayland_cast<Compositor *>(compositor)->createSurface(client, id);
}

const static struct wl_compositor_interface compositor_interface = {
    compositor_create_surface
};

void shell_move(struct wl_client *client,
                struct wl_shell *shell,
                struct wl_surface *surface,
                struct wl_input_device *input_device,
                uint32_t time)
{
    Q_UNUSED(client);
    Q_UNUSED(shell);
    Q_UNUSED(surface);
    Q_UNUSED(input_device);
    Q_UNUSED(time);
    qDebug() << "shellMove";
}

void shell_resize(struct wl_client *client,
                  struct wl_shell *shell,
                  struct wl_surface *surface,
                  struct wl_input_device *input_device,
                  uint32_t time,
                  uint32_t edges)
{
    Q_UNUSED(client);
    Q_UNUSED(shell);
    Q_UNUSED(surface);
    Q_UNUSED(input_device);
    Q_UNUSED(time);
    Q_UNUSED(edges);
    qDebug() << "shellResize";
}

void shell_drag(struct wl_client *client,
                struct wl_shell *shell,
                uint32_t id)
{
    Q_UNUSED(client);
    Q_UNUSED(shell);
    Q_UNUSED(id);
    qDebug() << "shellDrag";
}

void shell_selection(struct wl_client *client,
                     struct wl_shell *shell,
                     uint32_t id)
{
    Q_UNUSED(client);
    Q_UNUSED(shell);
    Q_UNUSED(id);
    qDebug() << "shellSelection";
}

const static struct wl_shell_interface shell_interface = {
    shell_move,
    shell_resize,
    shell_drag,
    shell_selection
};

Compositor::Compositor(WaylandCompositor *qt_compositor)
    : m_display(new Display)
    , m_shm(this)
    , m_current_frame(0)
    , m_last_queued_buf(-1)
    , m_qt_compositor(qt_compositor)
    , m_pointerFocusSurface(0)
    , m_keyFocusSurface(0)
{
#if defined (QT_COMPOSITOR_WAYLAND_GL)
    m_graphics_hw_integration = GraphicsHardwareIntegration::createGraphicsHardwareIntegration(qt_compositor);
#endif

    if (wl_compositor_init(base(), &compositor_interface, m_display->handle())) {
        fprintf(stderr, "Fatal: Error initializing compositor\n");
        exit(EXIT_FAILURE);
    }

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

    m_display->addGlobalObject(m_output.base(), &wl_output_interface, 0, output_post_geometry);
    m_display->addGlobalObject(&m_shell, &wl_shell_interface, &shell_interface, 0);
    m_display->addGlobalObject(m_shm.base(), &wl_shm_interface, &shm_interface, 0);

    wl_input_device_init(&m_input, base());
    m_display->addGlobalObject(&m_input.object, &wl_input_device_interface, &input_device_interface, 0);

    if (wl_display_add_socket(m_display->handle(), 0)) {
        fprintf(stderr, "Fatal: Failed to open server socket\n");
        exit(EXIT_FAILURE);
    }

    m_loop = wl_display_get_event_loop(m_display->handle());

    int fd = wl_event_loop_get_fd(m_loop);

    QSocketNotifier *sockNot = new QSocketNotifier(fd, QSocketNotifier::Read, this);
    connect(sockNot, SIGNAL(activated(int)), this, SLOT(processWaylandEvents()));
}

Compositor::~Compositor()
{
    delete m_display;
}

void Compositor::frameFinished()
{
    wl_display_post_frame(m_display->handle(), currentTimeMsecs());
}

void Compositor::createSurface(struct wl_client *client, int id)
{
    Surface *surface = new Surface(client, this);
    printf("Compositor::createSurface: %p %d\n", client, id);

    addClientResource(client, &surface->base()->resource, id, &wl_surface_interface,
            &surface_interface, destroy_surface);

    m_qt_compositor->surfaceCreated(surface->handle());

    m_surfaces << surface;
}

struct wl_client *Compositor::getClientFromWinId(uint winId) const
{
    Surface *surface = getSurfaceFromWinId(winId);
    if (surface)
        return surface->base()->client;

    return 0;
}

Surface *Compositor::getSurfaceFromWinId(uint winId) const
{
    foreach (Surface *surface, m_surfaces) {
        if (surface->id() == winId)
            return surface;
    }

    return 0;
}

QImage Compositor::image(uint winId) const
{
    printf("Compositor::image(%x)\n", winId);
    foreach (Surface *surface, m_surfaces) {
        if (surface->id() == winId) {
            return surface->image();
        }
    }

    return QImage();
}

//XXX: sort this out. Static function?
uint Compositor::currentTimeMsecs() const
{
    //### we throw away the time information
    struct timeval tv;
    int ret = gettimeofday(&tv, 0);
    if (ret == 0)
        return tv.tv_sec*1000 + tv.tv_usec/1000;
    return 0;
}

void Compositor::processWaylandEvents()
{
    int ret = wl_event_loop_dispatch(m_loop, 0);
    if (ret)
        fprintf(stderr, "wl_event_loop_dispatch error: %d\n", ret);
}

void Compositor::surfaceDestroyed(Surface *surface)
{
    m_surfaces.removeOne(surface);
    if (m_keyFocusSurface == surface)
        setKeyFocus(0);
    if (m_pointerFocusSurface == surface)
        setPointerFocus(0);
}

void Compositor::destroyClientForSurface(Surface *surface)
{
    wl_client *client = surface->base()->client;

    if (client)
        wl_client_destroy(client);
}

void Compositor::setInputFocus(Surface *surface)
{
    wl_surface *base = surface ? surface->base() : 0;

    ulong time = currentTimeMsecs();

    m_keyFocusSurface = surface;
    m_pointerFocusSurface = surface;
    wl_input_device_set_keyboard_focus(&m_input, base, time);
    wl_input_device_set_pointer_focus(&m_input, base, time, 0, 0, 0, 0);
}

void Compositor::setKeyFocus(Surface *surface)
{
    m_keyFocusSurface = surface;
    wl_input_device_set_keyboard_focus(&m_input, surface ? surface->base() : 0, currentTimeMsecs());
}

void Compositor::setPointerFocus(Surface *surface, const QPoint &pos)
{
    m_pointerFocusSurface = surface;
    wl_input_device_set_pointer_focus(&m_input, surface ? surface->base() : 0, currentTimeMsecs(), pos.x(), pos.y(), pos.x(), pos.y());
}

QWidget * Compositor::topLevelWidget() const
{
    return m_qt_compositor->topLevelWidget();
}

GraphicsHardwareIntegration * Compositor::graphicsHWIntegration() const
{
#ifdef QT_COMPOSITOR_WAYLAND_GL
    return m_graphics_hw_integration;
#else
    return 0;
#endif
}

void Compositor::initializeHardwareIntegration()
{
#ifdef QT_COMPOSITOR_WAYLAND_GL
    m_graphics_hw_integration->initializeHardware(m_display);
#endif
}

}

wl_input_device * Wayland::Compositor::defaultInputDevice()
{
    return &m_input;
}

<|endoftext|>


<commit_before>/* Copyright (C) 2010-2011, Snares <snares@users.sourceforge.net>
   Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
   Copyright (C) 2011, Ryan Austin <ryan@gameforcecenters.com>

   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "../mumble_plugin_win32.h"

static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &) {
	for (int i=0;i<3;i++)
		avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f;

	//char ccontext[128];
	char state;
	bool ok;

	ok = peekProc((BYTE *) 0x0237919C, &state, 1); // State value
	if (! ok)
		return false;

	/*
	    Get context string; in this plugin this will be an
	    ip:port (char 256 bytes) string

	ccontext[127] = 0;
	context = std::string(ccontext);
	if ( state == 3 )
		context = std::string("menu");
	if ( state == 2 )
		context = std::string("ingame");
	if ( state == 1 )
		context = std::string("loading");
	*/

	// Current assesment of state values are:
	// 3 = in main menu
	// 2 = in game
	// 1 = loading
	if ( state != 2 )
		return true;	// This results in all vectors being zero which tells Mumble to ignore them.

	ok = peekProc((BYTE *) 0x02379130, avatar_pos, 12) &&
		peekProc((BYTE *)  0x02379160, avatar_front, 12) &&
		peekProc((BYTE *)  0x02379150, avatar_top, 12);

	if (! ok)
		return false;

	// Flip our front vector
	for (int i=0;i<3;i++) {
		avatar_front[i] = -avatar_front[i];
	}

	// Convert from right to left handed
	avatar_pos[0] = -avatar_pos[0];
	avatar_front[0] = -avatar_front[0];
	avatar_top[0] = -avatar_top[0];

	for (int i=0;i<3;i++) {
		camera_pos[i] = avatar_pos[i];
		camera_front[i] = avatar_front[i];
		camera_top[i] = avatar_top[i];
	}

	return ok;
}

static int trylock(const std::multimap<std::wstring, unsigned long long int> &pids) {

	if (! initialize(pids, L"bf3.exe"))
		return false;

	float apos[3], afront[3], atop[3], cpos[3], cfront[3], ctop[3];
	std::string context;
	std::wstring identity;

	if (!fetch(apos, afront, atop, cpos, cfront, ctop, context, identity)) {
		generic_unlock();
		return false;
	}

	return true;
}

static const std::wstring longdesc() {
	return std::wstring(L"Supports Battlefield 3. No identity or context support.");
}

static std::wstring description(L"Battlefield 3 v925790");
static std::wstring shortname(L"Battlefield 3");

static int trylock1() {
	return trylock(std::multimap<std::wstring, unsigned long long int>());
}

static MumblePlugin bf3plug = {
	MUMBLE_PLUGIN_MAGIC,
	description,
	shortname,
	NULL,
	NULL,
	trylock1,
	generic_unlock,
	longdesc,
	fetch
};

static MumblePlugin2 bf3plug2 = {
	MUMBLE_PLUGIN_MAGIC_2,
	MUMBLE_PLUGIN_VERSION,
	trylock
};

extern "C" __declspec(dllexport) MumblePlugin *getMumblePlugin() {
	return &bf3plug;
}

extern "C" __declspec(dllexport) MumblePlugin2 *getMumblePlugin2() {
	return &bf3plug2;
}
<commit_msg>Updated BF3 PA plugin for BF3 v936211<commit_after>/* Copyright (C) 2010-2011, Snares <snares@users.sourceforge.net>
   Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
   Copyright (C) 2011, Ryan Austin <ryan@gameforcecenters.com>

   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "../mumble_plugin_win32.h"

static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &) {
	for (int i=0;i<3;i++)
		avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f;

	//char ccontext[128];
	char state;
	bool ok;

	ok = peekProc((BYTE *) 0x0238CC2C, &state, 1); // State value
	if (! ok)
		return false;

	/*
	    Get context string; in this plugin this will be an
	    ip:port (char 256 bytes) string

	ccontext[127] = 0;
	context = std::string(ccontext);
	if ( state == 3 )
		context = std::string("menu");
	if ( state == 2 )
		context = std::string("ingame");
	if ( state == 1 )
		context = std::string("loading");
	*/

	// Current assesment of state values are:
	// 3 = in main menu
	// 2 = in game
	// 1 = loading
	if ( state != 2 )
		return true;	// This results in all vectors being zero which tells Mumble to ignore them.

	ok = peekProc((BYTE *) 0x0238CBC0, avatar_pos, 12) &&
		peekProc((BYTE *)  0x0238CBF0, avatar_front, 12) &&
		peekProc((BYTE *)  0x0238CBE0, avatar_top, 12);

	if (! ok)
		return false;

	// Flip our front vector
	for (int i=0;i<3;i++) {
		avatar_front[i] = -avatar_front[i];
	}

	// Convert from right to left handed
	avatar_pos[0] = -avatar_pos[0];
	avatar_front[0] = -avatar_front[0];
	avatar_top[0] = -avatar_top[0];

	for (int i=0;i<3;i++) {
		camera_pos[i] = avatar_pos[i];
		camera_front[i] = avatar_front[i];
		camera_top[i] = avatar_top[i];
	}

	return ok;
}

static int trylock(const std::multimap<std::wstring, unsigned long long int> &pids) {

	if (! initialize(pids, L"bf3.exe"))
		return false;

	float apos[3], afront[3], atop[3], cpos[3], cfront[3], ctop[3];
	std::string context;
	std::wstring identity;

	if (!fetch(apos, afront, atop, cpos, cfront, ctop, context, identity)) {
		generic_unlock();
		return false;
	}

	return true;
}

static const std::wstring longdesc() {
	return std::wstring(L"Supports Battlefield 3. No identity or context support.");
}

static std::wstring description(L"Battlefield 3 v936211");
static std::wstring shortname(L"Battlefield 3");

static int trylock1() {
	return trylock(std::multimap<std::wstring, unsigned long long int>());
}

static MumblePlugin bf3plug = {
	MUMBLE_PLUGIN_MAGIC,
	description,
	shortname,
	NULL,
	NULL,
	trylock1,
	generic_unlock,
	longdesc,
	fetch
};

static MumblePlugin2 bf3plug2 = {
	MUMBLE_PLUGIN_MAGIC_2,
	MUMBLE_PLUGIN_VERSION,
	trylock
};

extern "C" __declspec(dllexport) MumblePlugin *getMumblePlugin() {
	return &bf3plug;
}

extern "C" __declspec(dllexport) MumblePlugin2 *getMumblePlugin2() {
	return &bf3plug2;
}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2010 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

/**
  \file    render.cpp
  \author  Tom Fogal
           SCI Institute
           University of Utah
  \brief   Simple program to use Tuvok to render a dataset.
*/
#include "StdTuvokDefines.h"
#include <cstdlib>
#include <iostream>

#include <GL/glew.h>
#include <tclap/CmdLine.h>

#include "Basics/SysTools.h"
#include "Controller/Controller.h"
#include "IO/IOManager.h"
#include "Renderer/AbstrRenderer.h"
#include "Renderer/GL/GLFBOTex.h"
#include "Renderer/GL/GLFrameCapture.h"
#include "Renderer/GL/GLRenderer.h"

#include "context.h"

using namespace tuvok;

int main(int argc, char *argv[])
{
  std::string filename;
  try {
    TCLAP::CmdLine cmd("rendering test program");
    TCLAP::ValueArg<std::string> dset("d", "dataset", "Dataset to render.",
                                      true, "", "filename");
    cmd.add(dset);
    cmd.parse(argc, argv);

    filename = dset.getValue();
  } catch(const TCLAP::ArgException& e) {
    std::cerr << "error: " << e.error() << " for arg " << e.argId() << "\n";
    return EXIT_FAILURE;
  }

  try {
    std::auto_ptr<TvkContext> ctx(TvkContext::Create(640,480, 32,24,8, true));
    if(!ctx->isValid() || ctx->makeCurrent() == false) {
      T_ERROR("Could not utilize context.");
      return EXIT_FAILURE;
    }

    GLenum err = glewInit();
    if(err != GLEW_OK) {
      T_ERROR("Error initializing GLEW: %s", glewGetErrorString(err));
      return EXIT_FAILURE;
    }
    Controller::Instance().DebugOut()->SetOutput(true,true,true,true);

    // Convert the data into a UVF.
    std::string uvf_file;
    uvf_file = SysTools::RemoveExt(filename) + ".uvf";
    const std::string tmpdir = "/tmp/";
    const bool quantize8 = false;
    Controller::Instance().IOMan()->ConvertDataset(
      filename, uvf_file, tmpdir, true, 256, 4, quantize8
    );

    AbstrRenderer* ren;
    ren = Controller::Instance().RequestNewVolumeRenderer(
      MasterController::OPENGL_SBVR, false, false, false, false, false
    );
    ren->LoadDataset(uvf_file);
    ren->AddShaderPath("../../Shaders");
    ren->Resize(UINTVECTOR2(300,300));
    ren->Initialize();
    ren->SetTimeSlice(9000000);
    ren->Paint();
    ren->Paint();
    ren->Paint();

    GLRenderer* glren = dynamic_cast<GLRenderer*>(ren);
    GLFBOTex* fbo = glren->GetLastFBO();
    GLTargetBinder bind(&Controller::Instance());

    GLFrameCapture fc;
    fc.CaptureSingleFrame("test.png", fbo);

    ren->Cleanup();
    Controller::Instance().ReleaseVolumeRenderer(ren);
  } catch(const std::exception& e) {
    std::cerr << "Exception: " << e.what() << "\n";
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
<commit_msg>Fix test program to use "headless" render mode.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2010 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

/**
  \file    render.cpp
  \author  Tom Fogal
           SCI Institute
           University of Utah
  \brief   Simple program to use Tuvok to render a dataset.
*/
#include "StdTuvokDefines.h"
#include <cstdlib>
#include <iostream>

#include <GL/glew.h>
#include <tclap/CmdLine.h>

#include "Basics/SysTools.h"
#include "Controller/Controller.h"
#include "IO/IOManager.h"
#include "Renderer/AbstrRenderer.h"
#include "Renderer/GL/GLFBOTex.h"
#include "Renderer/GL/GLFrameCapture.h"
#include "Renderer/GL/GLRenderer.h"

#include "context.h"

using namespace tuvok;

int main(int argc, char *argv[])
{
  std::string filename;
  try {
    TCLAP::CmdLine cmd("rendering test program");
    TCLAP::ValueArg<std::string> dset("d", "dataset", "Dataset to render.",
                                      true, "", "filename");
    cmd.add(dset);
    cmd.parse(argc, argv);

    filename = dset.getValue();
  } catch(const TCLAP::ArgException& e) {
    std::cerr << "error: " << e.error() << " for arg " << e.argId() << "\n";
    return EXIT_FAILURE;
  }

  try {
    std::auto_ptr<TvkContext> ctx(TvkContext::Create(640,480, 32,24,8, true));
    if(!ctx->isValid() || ctx->makeCurrent() == false) {
      T_ERROR("Could not utilize context.");
      return EXIT_FAILURE;
    }

    GLenum err = glewInit();
    if(err != GLEW_OK) {
      T_ERROR("Error initializing GLEW: %s", glewGetErrorString(err));
      return EXIT_FAILURE;
    }
    Controller::Instance().DebugOut()->SetOutput(true,true,true,true);

    // Convert the data into a UVF.
    std::string uvf_file;
    uvf_file = SysTools::RemoveExt(filename) + ".uvf";
    const std::string tmpdir = "/tmp/";
    const bool quantize8 = false;
    Controller::Instance().IOMan()->ConvertDataset(
      filename, uvf_file, tmpdir, true, 256, 4, quantize8
    );

    AbstrRenderer* ren;
    ren = Controller::Instance().RequestNewVolumeRenderer(
      MasterController::OPENGL_SBVR, false, false, false, false, false
    );
    ren->LoadDataset(uvf_file);
    ren->AddShaderPath("../../Shaders");
    ren->Resize(UINTVECTOR2(640,480));
    ren->Initialize();
    ren->SetRendererTarget(AbstrRenderer::RT_HEADLESS);
    ren->Paint();

    GLRenderer* glren = dynamic_cast<GLRenderer*>(ren);
    GLFBOTex* fbo = glren->GetLastFBO();
    GLTargetBinder bind(&Controller::Instance());

    GLFrameCapture fc;
    fc.CaptureSingleFrame("test.png", fbo);

    ren->Cleanup();
    Controller::Instance().ReleaseVolumeRenderer(ren);
  } catch(const std::exception& e) {
    std::cerr << "Exception: " << e.what() << "\n";
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * This file is part of the "https://github.com/BlackMATov/kari.hpp"
 * For conditions of distribution and use, see copyright notice in LICENSE.md
 * Copyright (C) 2017-2020, by Matvey Cherevko (blackmatov@gmail.com)
 ******************************************************************************/

#pragma once

#include <tuple>
#include <type_traits>
#include <utility>

namespace kari_hpp
{
    template < std::size_t N, typename F, typename... Args >
    struct curry_t;

    namespace impl
    {
        template < typename F >
        struct is_curried_impl
        : std::false_type {};

        template < std::size_t N, typename F, typename... Args >
        struct is_curried_impl<curry_t<N, F, Args...>>
        : std::true_type {};
    }

    template < typename F >
    struct is_curried
    : impl::is_curried_impl<std::remove_cv_t<F>> {};

    template < typename F >
    inline constexpr bool is_curried_v = is_curried<F>::value;
}

namespace kari_hpp::detail
{
    template < std::size_t N, typename F, typename... Args >
    constexpr auto curry_or_apply(F&& f, std::tuple<Args...>&& args) {
        if constexpr ( !N && std::is_invocable_v<std::decay_t<F>, Args...> ) {
            return std::apply(std::forward<F>(f), std::move(args));
        } else {
            return curry_t<N, std::decay_t<F>, Args...>(std::forward<F>(f), std::move(args));
        }
    }

    template < std::size_t N, typename F >
    constexpr auto curry_or_apply(F&& f) {
        return curry_or_apply<N>(std::forward<F>(f), std::make_tuple());
    }
}

namespace kari_hpp
{
    template < std::size_t N, typename F, typename... Args >
    struct curry_t final {
        template < typename U >
        constexpr curry_t(U&& u, std::tuple<Args...>&& args)
        noexcept(noexcept(F(std::forward<U>(u))) && noexcept(std::tuple<Args...>(std::move(args))))
        : f_(std::forward<U>(u))
        , args_(std::move(args)) {}

        // min_arity

        constexpr std::size_t min_arity() const noexcept {
            return N;
        }

        // recurry

        template < std::size_t M >
        constexpr decltype(auto) recurry() &&
            noexcept(noexcept(
                detail::curry_or_apply<M>(
                    std::move(std::declval<F>()),
                    std::move(std::declval<std::tuple<Args...>>()))))
        {
            return detail::curry_or_apply<M>(
                std::move(f_),
                std::move(args_));
        }

        template < std::size_t M >
        constexpr decltype(auto) recurry() const &
            noexcept(noexcept(
                std::move(std::declval<curry_t>()).template recurry<M>()))
        {
            return std::move(curry_t(*this)).template recurry<M>();
        }

        // operator(As&&...)

        constexpr decltype(auto) operator()() &&
            noexcept(noexcept(
                std::move(std::declval<curry_t>()).template recurry<0>()))
        {
            return std::move(*this).template recurry<0>();
        }

        template < typename A >
        constexpr decltype(auto) operator()(A&& a) &&
            noexcept(noexcept(
                detail::curry_or_apply<(N > 0 ? N - 1 : 0)>(
                std::move(std::declval<F>()),
                std::tuple_cat(
                    std::move(std::declval<std::tuple<Args...>>()),
                    std::make_tuple(std::forward<A>(a))))))
        {
            return detail::curry_or_apply<(N > 0 ? N - 1 : 0)>(
                std::move(f_),
                std::tuple_cat(
                    std::move(args_),
                    std::make_tuple(std::forward<A>(a))));
        }

        template < typename A, typename... As >
        constexpr decltype(auto) operator()(A&& a, As&&... as) &&
            noexcept(noexcept(
                std::move(std::declval<curry_t>())(std::forward<A>(a))(std::forward<As>(as)...)))
        {
            return std::move(*this)(std::forward<A>(a))(std::forward<As>(as)...);
        }

        template < typename... As >
        constexpr decltype(auto) operator()(As&&... as) const &
            noexcept(noexcept(
                std::move(std::declval<curry_t>())(std::forward<As>(as)...)))
        {
            return std::move(curry_t(*this))(std::forward<As>(as)...);
        }
    private:
        F f_;
        std::tuple<Args...> args_;
    };
}

namespace kari_hpp
{
    //
    // curry
    //

    template < typename F >
    constexpr auto curry(F&& f) {
        if constexpr ( is_curried_v<std::decay_t<F>> ) {
            return std::forward<F>(f);
        } else {
            return detail::curry_or_apply<0>(std::forward<F>(f));
        }
    }

    template < typename F, typename A, typename... As >
    constexpr auto curry(F&& f, A&& a, As&&... as) {
        return curry(std::forward<F>(f))(std::forward<A>(a), std::forward<As>(as)...);
    }

    //
    // curryV
    //

    template < typename F >
    constexpr auto curryV(F&& f) {
        constexpr std::size_t max_n = std::size_t(-1);
        if constexpr ( is_curried_v<std::decay_t<F>> ) {
            return std::forward<F>(f).template recurry<max_n>();
        } else {
            return detail::curry_or_apply<max_n>(std::forward<F>(f));
        }
    }

    template < typename F, typename A, typename... As >
    constexpr auto curryV(F&& f, A&& a, As&&... as) {
        return curryV(std::forward<F>(f))(std::forward<A>(a), std::forward<As>(as)...);
    }

    //
    // curryN
    //

    template < std::size_t N, typename F >
    constexpr auto curryN(F&& f) {
        if constexpr ( is_curried_v<std::decay_t<F>> ) {
            return std::forward<F>(f).template recurry<N>();
        } else {
            return detail::curry_or_apply<N>(std::forward<F>(f));
        }
    }

    template < std::size_t N, typename F, typename A, typename... As >
    constexpr auto curryN(F&& f, A&& a, As&&... as) {
        constexpr std::size_t max_n = std::size_t(-1);
        constexpr std::size_t arg_n = sizeof...(As) + 1;
        static_assert(max_n - arg_n >= N, "invalid N argument");
        return curryN<N + arg_n>(std::forward<F>(f))(std::forward<A>(a), std::forward<As>(as)...);
    }
}
<commit_msg>goodbye noexcept<commit_after>/*******************************************************************************
 * This file is part of the "https://github.com/BlackMATov/kari.hpp"
 * For conditions of distribution and use, see copyright notice in LICENSE.md
 * Copyright (C) 2017-2020, by Matvey Cherevko (blackmatov@gmail.com)
 ******************************************************************************/

#pragma once

#include <tuple>
#include <type_traits>
#include <utility>

namespace kari_hpp
{
    template < std::size_t N, typename F, typename... Args >
    struct curry_t;

    namespace impl
    {
        template < typename F >
        struct is_curried_impl
        : std::false_type {};

        template < std::size_t N, typename F, typename... Args >
        struct is_curried_impl<curry_t<N, F, Args...>>
        : std::true_type {};
    }

    template < typename F >
    struct is_curried
    : impl::is_curried_impl<std::remove_cv_t<F>> {};

    template < typename F >
    inline constexpr bool is_curried_v = is_curried<F>::value;
}

namespace kari_hpp::detail
{
    template < std::size_t N, typename F, typename... Args >
    constexpr auto curry_or_apply(F&& f, std::tuple<Args...>&& args) {
        if constexpr ( !N && std::is_invocable_v<std::decay_t<F>, Args...> ) {
            return std::apply(std::forward<F>(f), std::move(args));
        } else {
            return curry_t<N, std::decay_t<F>, Args...>(std::forward<F>(f), std::move(args));
        }
    }

    template < std::size_t N, typename F >
    constexpr auto curry_or_apply(F&& f) {
        return curry_or_apply<N>(std::forward<F>(f), std::make_tuple());
    }
}

namespace kari_hpp
{
    template < std::size_t N, typename F, typename... Args >
    struct curry_t final {
        template < typename U >
        constexpr curry_t(U&& u, std::tuple<Args...>&& args)
        : f_(std::forward<U>(u))
        , args_(std::move(args)) {}

        // min_arity

        constexpr std::size_t min_arity() const noexcept {
            return N;
        }

        // recurry

        template < std::size_t M >
        constexpr auto recurry() && {
            return detail::curry_or_apply<M>(
                std::move(f_),
                std::move(args_));
        }

        template < std::size_t M >
        constexpr auto recurry() const & {
            return std::move(curry_t(*this)).template recurry<M>();
        }

        // operator(As&&...)

        constexpr auto operator()() && {
            return std::move(*this).template recurry<0>();
        }

        template < typename A >
        constexpr auto operator()(A&& a) && {
            return detail::curry_or_apply<(N > 0 ? N - 1 : 0)>(
                std::move(f_),
                std::tuple_cat(
                    std::move(args_),
                    std::make_tuple(std::forward<A>(a))));
        }

        template < typename A, typename... As >
        constexpr auto operator()(A&& a, As&&... as) && {
            return std::move(*this)(std::forward<A>(a))(std::forward<As>(as)...);
        }

        template < typename... As >
        constexpr auto operator()(As&&... as) const & {
            return std::move(curry_t(*this))(std::forward<As>(as)...);
        }
    private:
        F f_;
        std::tuple<Args...> args_;
    };
}

namespace kari_hpp
{
    //
    // curry
    //

    template < typename F >
    constexpr auto curry(F&& f) {
        if constexpr ( is_curried_v<std::decay_t<F>> ) {
            return std::forward<F>(f);
        } else {
            return detail::curry_or_apply<0>(std::forward<F>(f));
        }
    }

    template < typename F, typename A, typename... As >
    constexpr auto curry(F&& f, A&& a, As&&... as) {
        return curry(std::forward<F>(f))(std::forward<A>(a), std::forward<As>(as)...);
    }

    //
    // curryV
    //

    template < typename F >
    constexpr auto curryV(F&& f) {
        constexpr std::size_t max_n = std::size_t(-1);
        if constexpr ( is_curried_v<std::decay_t<F>> ) {
            return std::forward<F>(f).template recurry<max_n>();
        } else {
            return detail::curry_or_apply<max_n>(std::forward<F>(f));
        }
    }

    template < typename F, typename A, typename... As >
    constexpr auto curryV(F&& f, A&& a, As&&... as) {
        return curryV(std::forward<F>(f))(std::forward<A>(a), std::forward<As>(as)...);
    }

    //
    // curryN
    //

    template < std::size_t N, typename F >
    constexpr auto curryN(F&& f) {
        if constexpr ( is_curried_v<std::decay_t<F>> ) {
            return std::forward<F>(f).template recurry<N>();
        } else {
            return detail::curry_or_apply<N>(std::forward<F>(f));
        }
    }

    template < std::size_t N, typename F, typename A, typename... As >
    constexpr auto curryN(F&& f, A&& a, As&&... as) {
        constexpr std::size_t max_n = std::size_t(-1);
        constexpr std::size_t arg_n = sizeof...(As) + 1;
        static_assert(max_n - arg_n >= N, "invalid N argument");
        return curryN<N + arg_n>(std::forward<F>(f))(std::forward<A>(a), std::forward<As>(as)...);
    }
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <string>
// UNSUPPORTED: c++98, c++03, c++11, c++14
// XFAIL: libcpp-no-deduction-guides

// template<class InputIterator,
//      class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
//  basic_string(InputIterator, InputIterator, Allocator = Allocator())
//    -> basic_string<typename iterator_traits<InputIterator>::value_type,
//                 char_traits<typename iterator_traits<InputIterator>::value_type>,
//                 Allocator>;
//
//  The deduction guide shall not participate in overload resolution if InputIterator
//  is a type that does not qualify as an input iterator, or if Allocator is a type
//  that does not qualify as an allocator.

#include <string>
#include <iterator>
#include <cassert>
#include <cstddef>

#include "test_macros.h"

class NotAnItertor {};

template <typename T>
struct NotAnAllocator { typedef T value_type; };

int main()
{
    { // Not an iterator at all
    std::basic_string s1{NotAnItertor{}, NotAnItertor{}, std::allocator<char>{}}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}}
    }
    { // Not an input iterator
    const char16_t* s = u"12345678901234";
    std::basic_string<char16_t> s0;
    std::basic_string s1{std::back_insert_iterator(s0), //  expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}}
                         std::back_insert_iterator(s0),
                         std::allocator<char16_t>{}};
    }
    { // Not an allocator
    const wchar_t* s = L"12345678901234";
    std::basic_string s1{s, s+10, NotAnAllocator<wchar_t>{}}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}}
    }

}
<commit_msg>[libcxx][test] Marking libcpp-no-deduction-guides unsupported.<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <string>
// UNSUPPORTED: c++98, c++03, c++11, c++14
// UNSUPPORTED: libcpp-no-deduction-guides

// template<class InputIterator,
//      class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
//  basic_string(InputIterator, InputIterator, Allocator = Allocator())
//    -> basic_string<typename iterator_traits<InputIterator>::value_type,
//                 char_traits<typename iterator_traits<InputIterator>::value_type>,
//                 Allocator>;
//
//  The deduction guide shall not participate in overload resolution if InputIterator
//  is a type that does not qualify as an input iterator, or if Allocator is a type
//  that does not qualify as an allocator.

#include <string>
#include <iterator>
#include <cassert>
#include <cstddef>

#include "test_macros.h"

class NotAnItertor {};

template <typename T>
struct NotAnAllocator { typedef T value_type; };

int main()
{
    { // Not an iterator at all
    std::basic_string s1{NotAnItertor{}, NotAnItertor{}, std::allocator<char>{}}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}}
    }
    { // Not an input iterator
    const char16_t* s = u"12345678901234";
    std::basic_string<char16_t> s0;
    std::basic_string s1{std::back_insert_iterator(s0), //  expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}}
                         std::back_insert_iterator(s0),
                         std::allocator<char16_t>{}};
    }
    { // Not an allocator
    const wchar_t* s = L"12345678901234";
    std::basic_string s1{s, s+10, NotAnAllocator<wchar_t>{}}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}}
    }

}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef _SYMBOL_LOADER_HXX
#define _SYMBOL_LOADER_HXX
#if defined( WNT )
# include <tchar.h>
# include <windows.h>
# include <winreg.h>
#endif
#include <iostream>
#include <osl/module.h>
#include <rtl/ustring.hxx>

#define SYM_MAP(a) { #a, (SymbolFunc *)&a }

typedef void (*SymbolFunc) (void);

struct ApiMap
{
    const char *symName;
    SymbolFunc *refValue;
};

namespace
{
#if defined( UNX )
    const char LibName[] = "libvlc.so.5";
#elif defined( MACOS )
    const char LibName[] = "/Applications/VLC.app/Contents/MacOS/lib/libvlc.dylib";
#elif defined( WNT )
    const char LibName[] = "libvlc.dll";

    OUString GetVLCPath()
    {
        HKEY hKey;
        TCHAR arCurrent[MAX_PATH];
        DWORD dwType, dwCurrentSize = sizeof( arCurrent );

        if ( ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T( "Software\\VideoLAN\\VLC" ),
                             0, KEY_READ, &hKey ) == ERROR_SUCCESS )
        {
            if ( ::RegQueryValueEx( hKey, _T( "InstallDir" ), NULL, &dwType, ( LPBYTE )arCurrent, &dwCurrentSize ) == ERROR_SUCCESS )
            {
                ::RegCloseKey( hKey );
                return OUString( arCurrent, strlen(arCurrent), RTL_TEXTENCODING_UTF8 ) + "/";
            }

            ::RegCloseKey( hKey );
        }
        return OUString();
    }
#endif

    template<size_t N>
    bool tryLink( oslModule &aModule, const ApiMap ( &pMap )[N] )
    {
        for (size_t i = 0; i < N; ++i)
        {
            SymbolFunc aMethod = ( SymbolFunc )osl_getFunctionSymbol
                ( aModule, OUString::createFromAscii( pMap[ i ].symName ).pData );
            if ( !aMethod )
            {
                std::cerr << "Cannot load method " << pMap[ i ].symName << std::endl;
                *pMap[ i ].refValue = NULL;
                return false;
            }

            *pMap[ i ].refValue = aMethod;
        }

        return true;
    }
}

namespace VLC
{
    template<size_t N>
    bool InitApiMap( const ApiMap ( &pMap )[N]  )
    {
#if defined( UNX ) || defined( MACOS )
        const OUString& fullPath = OUString::createFromAscii(LibName);
#elif defined( WNT )
        const OUString& fullPath = GetVLCPath() + OUString::createFromAscii(LibName);
#endif

        oslModule aModule = osl_loadModule( fullPath.pData,
                                            SAL_LOADMODULE_DEFAULT );

        if( aModule == NULL)
        {
            std::cerr << "Cannot load libvlc" << std::endl;
            return false;
        }

        if (tryLink( aModule, pMap ))
        {
            osl_unloadModule( aModule );
            return true;
        }

        osl_unloadModule( aModule );

        return false;
    }
}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Just use the wide char API and no TCHAR crack, puh-lease<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef _SYMBOL_LOADER_HXX
#define _SYMBOL_LOADER_HXX
#if defined( WNT )
# include <windows.h>
# include <winreg.h>
#endif
#include <iostream>
#include <osl/module.h>
#include <rtl/ustring.hxx>

#define SYM_MAP(a) { #a, (SymbolFunc *)&a }

typedef void (*SymbolFunc) (void);

struct ApiMap
{
    const char *symName;
    SymbolFunc *refValue;
};

namespace
{
#if defined( UNX )
    const char LibName[] = "libvlc.so.5";
#elif defined( MACOS )
    const char LibName[] = "/Applications/VLC.app/Contents/MacOS/lib/libvlc.dylib";
#elif defined( WNT )
    const char LibName[] = "libvlc.dll";

    OUString GetVLCPath()
    {
        HKEY hKey;
        wchar_t arCurrent[MAX_PATH];
        DWORD dwType, dwCurrentSize = sizeof( arCurrent );

        if ( ::RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\VideoLAN\\VLC",
                             0, KEY_READ, &hKey ) == ERROR_SUCCESS )
        {
            if ( ::RegQueryValueExW( hKey, L"InstallDir", NULL, &dwType, (LPBYTE) arCurrent, &dwCurrentSize ) == ERROR_SUCCESS )
            {
                ::RegCloseKey( hKey );
                return OUString( arCurrent, wcslen(arCurrent) ) + "/";
            }

            ::RegCloseKey( hKey );
        }
        return OUString();
    }
#endif

    template<size_t N>
    bool tryLink( oslModule &aModule, const ApiMap ( &pMap )[N] )
    {
        for (size_t i = 0; i < N; ++i)
        {
            SymbolFunc aMethod = ( SymbolFunc )osl_getFunctionSymbol
                ( aModule, OUString::createFromAscii( pMap[ i ].symName ).pData );
            if ( !aMethod )
            {
                std::cerr << "Cannot load method " << pMap[ i ].symName << std::endl;
                *pMap[ i ].refValue = NULL;
                return false;
            }

            *pMap[ i ].refValue = aMethod;
        }

        return true;
    }
}

namespace VLC
{
    template<size_t N>
    bool InitApiMap( const ApiMap ( &pMap )[N]  )
    {
#if defined( UNX ) || defined( MACOS )
        const OUString& fullPath = OUString::createFromAscii(LibName);
#elif defined( WNT )
        const OUString& fullPath = GetVLCPath() + OUString::createFromAscii(LibName);
#endif

        oslModule aModule = osl_loadModule( fullPath.pData,
                                            SAL_LOADMODULE_DEFAULT );

        if( aModule == NULL)
        {
            std::cerr << "Cannot load libvlc" << std::endl;
            return false;
        }

        if (tryLink( aModule, pMap ))
        {
            osl_unloadModule( aModule );
            return true;
        }

        osl_unloadModule( aModule );

        return false;
    }
}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2014 ETH Zurich
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 **
 **    * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **      following disclaimer.
 **    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 **      following disclaimer in the documentation and/or other materials provided with the distribution.
 **    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
 **      derived from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **
 **********************************************************************************************************************/
#include "Exporter.h"
#include "FragmentLayouter.h"
#include "TextToNodeMap.h"
#include "../tree/SourceDir.h"
#include "../ExportException.h"

namespace Export {

TextToNodeMap* Exporter::exportToFileSystem(const QString& pathToProjectContainerDir, SourceDir* projectDir,
										  FragmentLayouter* layouter)
{
	QDir dir{pathToProjectContainerDir};

	if (!dir.exists()) throw ExportException("The directory to which a project will be exported must exist: "
																  + pathToProjectContainerDir);

	dir.mkdir(projectDir->name());
	dir.cd(projectDir->name());

	auto map =  new TextToNodeMap();
	saveDir(dir, projectDir, layouter, map);
	return map;
}

void Exporter::saveDir(QDir& fileSystemDir, SourceDir* sourceDir, FragmentLayouter* layouter, TextToNodeMap* map)
{
	// First remove all directories and files which are no longer part of the project
	auto entries = fileSystemDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDot | QDir::NoDotDot);
	for (auto entry : entries)
	{
		if (entry.isDir() && !sourceDir->hasSubDir(entry.fileName()))
		{
			QDir sub{fileSystemDir.path()};
			sub.cd(entry.fileName());
			sub.removeRecursively();
		}
		else if (entry.isFile() && !sourceDir->hasFile(entry.fileName()))
		{
			fileSystemDir.remove(entry.fileName());
		}
	}

	// Save all files
	for (auto& f : sourceDir->files())
		saveFile(fileSystemDir, &f, layouter, map);

	// Save all directories recursively
	for (auto& d : sourceDir->directories())
	{
		QDir sub{fileSystemDir};
		sub.mkdir(d.name());
		sub.cd(d.name());

		saveDir(sub, &d, layouter, map);
	}
}

void Exporter::saveFile(QDir& fileSystemDir, SourceFile* sourceFile, FragmentLayouter* layouter, TextToNodeMap* map)
{
	QString fileText = layouter->render(sourceFile, map);

	QString fileName = fileSystemDir.absoluteFilePath(sourceFile->name());
	QFile file{fileName};

	// Check to see if a file with the same name and content already exists
	if (fileSystemDir.exists(sourceFile->name()))
	{
		Q_ASSERT(file.exists());

		if (file.open(QIODevice::ReadOnly | QIODevice::Text))
		{
			if (fileText == file.readAll()) return;
		}
		else throw ExportException("Could not open file " + fileName + " for reading");

		// File has changed
		file.remove();
	}

	if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
		throw ExportException("Could not open file " + fileName + " for writing");

	auto data = fileText.toUtf8();
	auto written = file.write(data);
	file.close();

	if (written != data.size()) throw ExportException("Error writing to file " + fileName);
}

} /* namespace Export */
<commit_msg>Make Exporter create all directories on the path to the exported project<commit_after>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2014 ETH Zurich
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 **
 **    * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **      following disclaimer.
 **    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 **      following disclaimer in the documentation and/or other materials provided with the distribution.
 **    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
 **      derived from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **
 **********************************************************************************************************************/
#include "Exporter.h"
#include "FragmentLayouter.h"
#include "TextToNodeMap.h"
#include "../tree/SourceDir.h"
#include "../ExportException.h"

namespace Export {

TextToNodeMap* Exporter::exportToFileSystem(const QString& pathToProjectContainerDir, SourceDir* projectDir,
										  FragmentLayouter* layouter)
{
	QDir dir{pathToProjectContainerDir};
	if (!dir.exists(projectDir->name()))
		dir.mkpath(projectDir->name());

	Q_ASSERT(dir.exists(projectDir->name()));
	dir.cd(projectDir->name());

	auto map =  new TextToNodeMap();
	saveDir(dir, projectDir, layouter, map);
	return map;
}

void Exporter::saveDir(QDir& fileSystemDir, SourceDir* sourceDir, FragmentLayouter* layouter, TextToNodeMap* map)
{
	// First remove all directories and files which are no longer part of the project
	auto entries = fileSystemDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDot | QDir::NoDotDot);
	for (auto entry : entries)
	{
		if (entry.isDir() && !sourceDir->hasSubDir(entry.fileName()))
		{
			QDir sub{fileSystemDir.path()};
			sub.cd(entry.fileName());
			sub.removeRecursively();
		}
		else if (entry.isFile() && !sourceDir->hasFile(entry.fileName()))
		{
			fileSystemDir.remove(entry.fileName());
		}
	}

	// Save all files
	for (auto& f : sourceDir->files())
		saveFile(fileSystemDir, &f, layouter, map);

	// Save all directories recursively
	for (auto& d : sourceDir->directories())
	{
		QDir sub{fileSystemDir};
		sub.mkdir(d.name());
		sub.cd(d.name());

		saveDir(sub, &d, layouter, map);
	}
}

void Exporter::saveFile(QDir& fileSystemDir, SourceFile* sourceFile, FragmentLayouter* layouter, TextToNodeMap* map)
{
	QString fileText = layouter->render(sourceFile, map);

	QString fileName = fileSystemDir.absoluteFilePath(sourceFile->name());
	QFile file{fileName};

	// Check to see if a file with the same name and content already exists
	if (fileSystemDir.exists(sourceFile->name()))
	{
		Q_ASSERT(file.exists());

		if (file.open(QIODevice::ReadOnly | QIODevice::Text))
		{
			if (fileText == file.readAll()) return;
		}
		else throw ExportException("Could not open file " + fileName + " for reading");

		// File has changed
		file.remove();
	}

	if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
		throw ExportException("Could not open file " + fileName + " for writing");

	auto data = fileText.toUtf8();
	auto written = file.write(data);
	file.close();

	if (written != data.size()) throw ExportException("Error writing to file " + fileName);
}

} /* namespace Export */
<|endoftext|>


<commit_before><commit_msg>bugfix: use of vector after clear() was called<commit_after><|endoftext|>


<commit_before>#include "stdafx.h"

using namespace Magick;

DECLARE_COMPONENT_VERSION("Image decoder", "1.1.0", "Open BMP, PNG and JPG images in foobar!\n\nBe sure to add the image file extensions to your media library exclusions or you will have a bad time.\n;*.jpg;*.png;*.bmp;*.jpeg;");

static const GUID samples_per_pixel_guid = { 0xcaa64014, 0x6c9c, 0x46b2, { 0x7b, 0xa7, 0xa, 0x5c, 0xbb, 0x10, 0x2f, 0xb6 } };
advconfig_integer_factory samples_per_pixel(
  "Image decoding spectrogram height",
  samples_per_pixel_guid,
  advconfig_branch::guid_branch_decoding,
  0.0,
  900,
  100,
  1200
  );

static const GUID amp_scale_guid = { 0xcacc0014, 0x6c9c, 0x46b3, { 0x7b, 0xa7, 0xf, 0x5c, 0xab, 0x10, 0x6f, 0xb6 } };
advconfig_integer_factory amp_scale(
  "Image decoding amplitude scale (1-1000)",
  amp_scale_guid,
  advconfig_branch::guid_branch_decoding,
  0.0,
  430,
  1,
  1000
  );

static const GUID lowpass_enabled_guid = { 0xfab55014, 0xc445, 0x8ff1, { 0xc3, 0xa7, 0xaa, 0x5c, 0x71, 0x7c, 0xb7, 0xe4 } };
advconfig_checkbox_factory lowpass_enabled(
  "Enable image decoding lowpass filter",
  lowpass_enabled_guid,
  advconfig_branch::guid_branch_decoding,
  0.0,
  true
  );

class img_type : public input_singletrack_impl {
  typedef pfc::array_t<uint8_t> BArray;
  std::string n;
  file_ptr myFile;
  t_filestats fs;
  int c;
  BArray raw;

  float **img = nullptr;
  audio_sample * buffer = nullptr;

  int w, h;
  float *phase = nullptr, *hz = nullptr;
  float bdw, vol;
  int spp;
  int xx;
  float argv;

  float *oamp = nullptr;

  //ILuint ilimg = 0;

  //Blob imBlob;
  Magick::Image imImg;

  float * sinlook = nullptr;

  static const float PI;
  static const int LOOKUP_SIZE = 6000;

  int get_int32(BArray arr, int at) {
    return (arr[at+3] << 24) | (arr[at+2] << 16) | (arr[at+1] << 8) | (arr[at]);
  }
  int get_int16(BArray arr, int at) {
    return (arr[at + 1] << 8) | (arr[at]);
  }

  float my_sin(float val) {
    float mult = val / (2*PI);
    mult -= (int)(mult);

    float rem = (LOOKUP_SIZE - 1) * mult;
    int idx = (int)(rem);
    float ret = sinlook[idx];
    return ret;
  }

public:
  void open(service_ptr_t<file> p_filehint,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort)  {

    input_open_file_helper(p_filehint, p_path, p_reason, p_abort);
    if(p_filehint == nullptr) {
      return;
    }
    myFile = p_filehint;
    n = std::string(p_path);
    myFile->read_till_eof(raw, p_abort);

    try {
      Blob imBlob = Blob((void*)raw.get_ptr(), raw.get_count());
      imImg = Magick::Image(imBlob);
    }
    catch (Exception imE) {
      throw exception_io_unsupported_format(imE.what());
    }

    w = imImg.columns();
    h = imImg.rows();
    spp = samples_per_pixel.get();
    spp = -0.7646 * (-spp - 332);
    vol = amp_scale.get();
    vol = 18189 * pow(2.71828, -9.45817 * (vol / 1000.0));
    if (vol <= 0)
      vol = 1;

    if (h > spp) {
      try {
        float rat = (float)w / h;
        Geometry geom((int)(spp*rat), spp);
        imImg.resize(geom);
        w = imImg.columns();
        h = imImg.rows();
      }
      catch (Exception imE) {}
    }

    bool dum = false;
    foobar2000_io::filesystem::g_get_stats(p_path, fs, dum, p_abort);
    hz = phase = nullptr;

    sinlook = new float[LOOKUP_SIZE];
    for (int i = 0; i < LOOKUP_SIZE; i++) {
      float ang = (i / (float)(LOOKUP_SIZE - 1)) * 2 * PI;
      sinlook[i] = std::sinf(ang);
    }

    hz = new float[h];
    phase = new float[h];
    buffer = new audio_sample[spp];

    if (lowpass_enabled.get())
      oamp = new float[h];

    srand(time(NULL));
    bdw = 22000.0 / spp;

    /*bdw = 22000.0 / h;
    if (bdw > (22000.0 / spp))
      bdw = (22000.0 / spp);*/
    float logmul = 22000.0 / std::pow(h, 2.71828);
    for (int a = 0; a < h; a++) {
      phase[a] = ((rand() % 20000) / 19999.0) * 2 * PI;
      //phase[a] = ((1140671485 * a + 12820163) % 10000) / 10000.0 * 2 * PI;
      //phase[a] = ((float)(a % 12) / h) *PI/6;
      hz[a] = bdw * (h - a - 1);

      if (oamp != nullptr)
        oamp[a] = 0;
    }
    xx = 0;

    console::printf("foo_img::open: %s", p_path);

  }

  void get_info(file_info & p_info,abort_callback & p_abort) {
    p_info.info_set_int("samplerate", 44100);
    p_info.info_set_int("channels", 1);
    p_info.info_set_int("bitspersample", 32);
    p_info.info_set("codec", "PCM");
    p_info.info_set("encoding", "lossless");
    p_info.set_length((w * spp) / 44100.0);
    p_info.info_set_bitrate(44100 * 32);

    int p = n.rfind('\\');
    p_info.meta_add("TITLE", n.substr(p+1).c_str());
  }

  t_filestats get_file_stats(abort_callback & p_abort) {
    return fs;
  }

  void decode_initialize(unsigned p_flags,abort_callback & p_abort) {
    console::printf("foo_img::initialize: %s", n.c_str());
    int w = this->w;
    int h = this->h;

    img = new float*[w];
    float _min = 1.0, _max = 0.0;

    Pixels cache(imImg);
    PixelPacket *pix;
    pix = cache.get(0, 0, w, h);

    for (int x = 0; x < w; x++) {
      img[x] = new float[h];
      for (int y = h - 1; y >= 0; y--) {
        PixelPacket pp = pix[y*w + x];

        //float v = ((pow(pp.red / 65535.0, 2.2) * 0.2989 + pow(pp.green / 65535.0, 2.2) * 0.5870 + pow(pp.blue / 65535.0, 2.2) * 0.1140));
        float v = (pp.red *  0.2989 + pp.green *  0.5870 + pp.blue *  0.1140) / 65535;
        img[x][y] = v;

        if (v < _min)
          _min = v;
        else if (v > _max)
          _max = v;
      }
    }

    float scale = (_max-_min);

    for (int x = 0; x < w; x++) {
      float *c = img[x];
      for (int y = 0; y < h; y++) {
        c[y] = ((c[y] - _min) * scale);
      }
    }

  }

  bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort) {
    if(xx >= w)
      return false;

    float *col = img[xx];
    int w = this->w;
    int h = this->h;
    int xx = this->xx;
    int spp = this->spp;

    float max = 0;

    int pos = xx * spp;
    for(int s = 0; s < spp; s++) {
      float sum = 0;
      int smp = pos + s;
      float arg = smp * PI * 2 / 44100.0;
      for(int y = 0; y < h; y++) {
        float p = col[y];
        float amp = (p * 0.2 + p*p * 0.8);
        if (oamp != nullptr) {
          amp = oamp[y] * 0.92 + amp * 0.08;
          oamp[y] = amp;
        }
        float pt = my_sin(hz[y] * arg + phase[y]);
        sum += pt*amp;
      }
      sum = sum / vol;
      if(sum < -1.0)
        sum = -1.0;
      else if(sum > 1.0)
        sum = 1.0;

      buffer[s] = sum;
    }

    this->xx++;

    p_chunk.set_data(buffer, spp, 1, 44100);
    return true;
  }

  void decode_seek(double p_seconds,abort_callback & p_abort) {
    double samps = p_seconds * 44100;
    samps /= spp;
    xx = (int)samps;
  }

  bool decode_can_seek() {
    return true;
  }

  bool decode_get_dynamic_info(file_info & p_out, double & p_timestamp_delta){
    return false;
  }

  bool decode_get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta){
    return false;
  }

  void decode_on_idle(abort_callback & p_abort){
  }

  void retag(const file_info & p_info,abort_callback & p_abort){
    // don't care
  }

  static bool endswith(const char * s1, const char * s2) {
    return strlen(s1) >= strlen(s2) && stricmp(s1 + strlen(s1) - strlen(s2), s2) == 0;
  }
  static bool startswith(const char * s1, const char * s2) {
    return strlen(s1) >= strlen(s2) && strnicmp(s1, s2, strlen(s2)) == 0;
  }

  static bool g_is_our_content_type(const char * p_content_type){
    return stricmp(p_content_type, "image/bmp") == 0 ||
      stricmp(p_content_type, "image/png") == 0 ||
      stricmp(p_content_type, "image/jpeg") == 0;
  }
  static bool g_is_our_path(const char * p_path,const char * p_extension) {
    if (strncmp(p_path, "unpack:", strlen("unpack:")) == 0) {
      return false; // don't open packs
    }

    const char * fname = strrchr(p_path, '\\') + 1;

    if (startswith(fname, "albumart") ||
      startswith(fname, "cover") ||
      startswith(fname, "thumb") ||
      startswith(fname, "folder") ||
      startswith(fname, "front") ||
      startswith(fname, "disc") ||
      startswith(fname, "back"))
      return false;

    return stricmp(p_extension, "bmp") == 0 ||
      stricmp(p_extension, "jpg") == 0 ||
      stricmp(p_extension, "jpeg") == 0 ||
      stricmp(p_extension, "png") == 0;
  }

  ~img_type(){
    if (hz != nullptr) delete hz;
    if (phase != nullptr) delete phase;
    if (buffer != nullptr) delete buffer;
    if (sinlook != nullptr) delete sinlook;
    if (oamp != nullptr) delete oamp;

    if (img != nullptr) {
      for (int i = 0; i < w; i++)
        delete img[i];
      delete img;
    }
  }
};

const float img_type::PI = 3.14159265359;

input_singletrack_factory_t<img_type> fac;

std::string wstrtostr(const std::wstring &wstr)
{
  if (wstr.empty()) return std::string();
  int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
  std::string strTo(size_needed, 0);
  WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
  return strTo;
}

// Convert an UTF8 string to a wide Unicode String
std::wstring strtowstr(const std::string &str)
{
  if (str.empty()) return std::wstring();
  int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
  std::wstring wstrTo(size_needed, 0);
  MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
  return wstrTo;
}

BOOLEAN WINAPI DllMain(IN HINSTANCE hDllHandle,
  IN DWORD     nReason,
  IN LPVOID    Reserved)
{
  BOOLEAN bSuccess = TRUE;

  //  Perform global initialization.

  switch (nReason)
  {
  case DLL_PROCESS_ATTACH:

    //  For optimization.

    DisableThreadLibraryCalls(hDllHandle);

    break;

  case DLL_PROCESS_DETACH:

    break;
  }

  LPSTR s = GetCommandLineA();
  InitializeMagick(s);

  return bSuccess;

}<commit_msg>Removed redundant null checks<commit_after>#include "stdafx.h"

using namespace Magick;

DECLARE_COMPONENT_VERSION("Image decoder", "1.1.0", "Open BMP, PNG and JPG images in foobar!\n\nBe sure to add the image file extensions to your media library exclusions or you will have a bad time.\n;*.jpg;*.png;*.bmp;*.jpeg;");

static const GUID samples_per_pixel_guid = { 0xcaa64014, 0x6c9c, 0x46b2, { 0x7b, 0xa7, 0xa, 0x5c, 0xbb, 0x10, 0x2f, 0xb6 } };
advconfig_integer_factory samples_per_pixel(
  "Image decoding spectrogram height",
  samples_per_pixel_guid,
  advconfig_branch::guid_branch_decoding,
  0.0,
  900,
  100,
  1200
  );

static const GUID amp_scale_guid = { 0xcacc0014, 0x6c9c, 0x46b3, { 0x7b, 0xa7, 0xf, 0x5c, 0xab, 0x10, 0x6f, 0xb6 } };
advconfig_integer_factory amp_scale(
  "Image decoding amplitude scale (1-1000)",
  amp_scale_guid,
  advconfig_branch::guid_branch_decoding,
  0.0,
  430,
  1,
  1000
  );

static const GUID lowpass_enabled_guid = { 0xfab55014, 0xc445, 0x8ff1, { 0xc3, 0xa7, 0xaa, 0x5c, 0x71, 0x7c, 0xb7, 0xe4 } };
advconfig_checkbox_factory lowpass_enabled(
  "Enable image decoding lowpass filter",
  lowpass_enabled_guid,
  advconfig_branch::guid_branch_decoding,
  0.0,
  true
  );

class img_type : public input_singletrack_impl {
  typedef pfc::array_t<uint8_t> BArray;
  std::string n;
  file_ptr myFile;
  t_filestats fs;
  int c;
  BArray raw;

  float **img = nullptr;
  audio_sample * buffer = nullptr;

  int w, h;
  float *phase = nullptr, *hz = nullptr;
  float bdw, vol;
  int spp;
  int xx;
  float argv;

  float *oamp = nullptr;

  //ILuint ilimg = 0;

  //Blob imBlob;
  Magick::Image imImg;

  float * sinlook = nullptr;

  static const float PI;
  static const int LOOKUP_SIZE = 6000;

  int get_int32(BArray arr, int at) {
    return (arr[at+3] << 24) | (arr[at+2] << 16) | (arr[at+1] << 8) | (arr[at]);
  }
  int get_int16(BArray arr, int at) {
    return (arr[at + 1] << 8) | (arr[at]);
  }

  float my_sin(float val) {
    float mult = val / (2*PI);
    mult -= (int)(mult);

    float rem = (LOOKUP_SIZE - 1) * mult;
    int idx = (int)(rem);
    float ret = sinlook[idx];
    return ret;
  }

public:
  void open(service_ptr_t<file> p_filehint,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort)  {

    input_open_file_helper(p_filehint, p_path, p_reason, p_abort);
    if(p_filehint == nullptr) {
      return;
    }
    myFile = p_filehint;
    n = std::string(p_path);
    myFile->read_till_eof(raw, p_abort);

    try {
      Blob imBlob = Blob((void*)raw.get_ptr(), raw.get_count());
      imImg = Magick::Image(imBlob);
    }
    catch (Exception imE) {
      throw exception_io_unsupported_format(imE.what());
    }

    w = imImg.columns();
    h = imImg.rows();
    spp = samples_per_pixel.get();
    spp = -0.7646 * (-spp - 332);
    vol = amp_scale.get();
    vol = 18189 * pow(2.71828, -9.45817 * (vol / 1000.0));
    if (vol <= 0)
      vol = 1;

    if (h > spp) {
      try {
        float rat = (float)w / h;
        Geometry geom((int)(spp*rat), spp);
        imImg.resize(geom);
        w = imImg.columns();
        h = imImg.rows();
      }
      catch (Exception imE) {}
    }

    bool dum = false;
    foobar2000_io::filesystem::g_get_stats(p_path, fs, dum, p_abort);
    hz = phase = nullptr;

    sinlook = new float[LOOKUP_SIZE];
    for (int i = 0; i < LOOKUP_SIZE; i++) {
      float ang = (i / (float)(LOOKUP_SIZE - 1)) * 2 * PI;
      sinlook[i] = std::sinf(ang);
    }

    hz = new float[h];
    phase = new float[h];
    buffer = new audio_sample[spp];

    if (lowpass_enabled.get())
      oamp = new float[h];

    srand(time(NULL));
    bdw = 22000.0 / spp;

    /*bdw = 22000.0 / h;
    if (bdw > (22000.0 / spp))
      bdw = (22000.0 / spp);*/
    float logmul = 22000.0 / std::pow(h, 2.71828);
    for (int a = 0; a < h; a++) {
      phase[a] = ((rand() % 20000) / 19999.0) * 2 * PI;
      //phase[a] = ((1140671485 * a + 12820163) % 10000) / 10000.0 * 2 * PI;
      //phase[a] = ((float)(a % 12) / h) *PI/6;
      hz[a] = bdw * (h - a - 1);

      if (oamp != nullptr)
        oamp[a] = 0;
    }
    xx = 0;

    console::printf("foo_img::open: %s", p_path);

  }

  void get_info(file_info & p_info,abort_callback & p_abort) {
    p_info.info_set_int("samplerate", 44100);
    p_info.info_set_int("channels", 1);
    p_info.info_set_int("bitspersample", 32);
    p_info.info_set("codec", "PCM");
    p_info.info_set("encoding", "lossless");
    p_info.set_length((w * spp) / 44100.0);
    p_info.info_set_bitrate(44100 * 32);

    int p = n.rfind('\\');
    p_info.meta_add("TITLE", n.substr(p+1).c_str());
  }

  t_filestats get_file_stats(abort_callback & p_abort) {
    return fs;
  }

  void decode_initialize(unsigned p_flags,abort_callback & p_abort) {
    console::printf("foo_img::initialize: %s", n.c_str());
    int w = this->w;
    int h = this->h;

    img = new float*[w];
    float _min = 1.0, _max = 0.0;

    Pixels cache(imImg);
    PixelPacket *pix;
    pix = cache.get(0, 0, w, h);

    for (int x = 0; x < w; x++) {
      img[x] = new float[h];
      for (int y = h - 1; y >= 0; y--) {
        PixelPacket pp = pix[y*w + x];

        //float v = ((pow(pp.red / 65535.0, 2.2) * 0.2989 + pow(pp.green / 65535.0, 2.2) * 0.5870 + pow(pp.blue / 65535.0, 2.2) * 0.1140));
        float v = (pp.red *  0.2989 + pp.green *  0.5870 + pp.blue *  0.1140) / 65535;
        img[x][y] = v;

        if (v < _min)
          _min = v;
        else if (v > _max)
          _max = v;
      }
    }

    float scale = (_max-_min);

    for (int x = 0; x < w; x++) {
      float *c = img[x];
      for (int y = 0; y < h; y++) {
        c[y] = ((c[y] - _min) * scale);
      }
    }

  }

  bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort) {
    if(xx >= w)
      return false;

    float *col = img[xx];
    int w = this->w;
    int h = this->h;
    int xx = this->xx;
    int spp = this->spp;

    float max = 0;

    int pos = xx * spp;
    for(int s = 0; s < spp; s++) {
      float sum = 0;
      int smp = pos + s;
      float arg = smp * PI * 2 / 44100.0;
      for(int y = 0; y < h; y++) {
        float p = col[y];
        float amp = (p * 0.2 + p*p * 0.8);
        if (oamp != nullptr) {
          amp = oamp[y] * 0.92 + amp * 0.08;
          oamp[y] = amp;
        }
        float pt = my_sin(hz[y] * arg + phase[y]);
        sum += pt*amp;
      }
      sum = sum / vol;
      if(sum < -1.0)
        sum = -1.0;
      else if(sum > 1.0)
        sum = 1.0;

      buffer[s] = sum;
    }

    this->xx++;

    p_chunk.set_data(buffer, spp, 1, 44100);
    return true;
  }

  void decode_seek(double p_seconds,abort_callback & p_abort) {
    double samps = p_seconds * 44100;
    samps /= spp;
    xx = (int)samps;
  }

  bool decode_can_seek() {
    return true;
  }

  bool decode_get_dynamic_info(file_info & p_out, double & p_timestamp_delta){
    return false;
  }

  bool decode_get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta){
    return false;
  }

  void decode_on_idle(abort_callback & p_abort){
  }

  void retag(const file_info & p_info,abort_callback & p_abort){
    // don't care
  }

  static bool endswith(const char * s1, const char * s2) {
    return strlen(s1) >= strlen(s2) && stricmp(s1 + strlen(s1) - strlen(s2), s2) == 0;
  }
  static bool startswith(const char * s1, const char * s2) {
    return strlen(s1) >= strlen(s2) && strnicmp(s1, s2, strlen(s2)) == 0;
  }

  static bool g_is_our_content_type(const char * p_content_type){
    return stricmp(p_content_type, "image/bmp") == 0 ||
      stricmp(p_content_type, "image/png") == 0 ||
      stricmp(p_content_type, "image/jpeg") == 0;
  }
  static bool g_is_our_path(const char * p_path,const char * p_extension) {
    if (strncmp(p_path, "unpack:", strlen("unpack:")) == 0) {
      return false; // don't open packs
    }

    const char * fname = strrchr(p_path, '\\') + 1;

    if (startswith(fname, "albumart") ||
      startswith(fname, "cover") ||
      startswith(fname, "thumb") ||
      startswith(fname, "folder") ||
      startswith(fname, "front") ||
      startswith(fname, "disc") ||
      startswith(fname, "back"))
      return false;

    return stricmp(p_extension, "bmp") == 0 ||
      stricmp(p_extension, "jpg") == 0 ||
      stricmp(p_extension, "jpeg") == 0 ||
      stricmp(p_extension, "png") == 0;
  }

  ~img_type(){
    delete hz;
    delete phase;
    delete buffer;
    delete sinlook;
    delete oamp;

    if (img != nullptr) {
      for (int i = 0; i < w; i++)
        delete img[i];
      delete img;
    }
  }
};

const float img_type::PI = 3.14159265359;

input_singletrack_factory_t<img_type> fac;

std::string wstrtostr(const std::wstring &wstr)
{
  if (wstr.empty()) return std::string();
  int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
  std::string strTo(size_needed, 0);
  WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
  return strTo;
}

// Convert an UTF8 string to a wide Unicode String
std::wstring strtowstr(const std::string &str)
{
  if (str.empty()) return std::wstring();
  int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
  std::wstring wstrTo(size_needed, 0);
  MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
  return wstrTo;
}

BOOLEAN WINAPI DllMain(IN HINSTANCE hDllHandle,
  IN DWORD     nReason,
  IN LPVOID    Reserved)
{
  BOOLEAN bSuccess = TRUE;

  //  Perform global initialization.

  switch (nReason)
  {
  case DLL_PROCESS_ATTACH:

    //  For optimization.

    DisableThreadLibraryCalls(hDllHandle);

    break;

  case DLL_PROCESS_DETACH:

    break;
  }

  LPSTR s = GetCommandLineA();
  InitializeMagick(s);

  return bSuccess;

}<|endoftext|>