<commit_before>/*
 * Copyright (C) 2008 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * 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
 *
 */

#include <QFileInfo>
#include <QDir>
#include <QDebug>
#include <QMutex>
#include <QXmlSimpleReader>
#include <QXmlInputSource>
#include <QFile>
#include <stdlib.h>
#include "sconnect.h"
#include "infoxmlbackend.h"
#include "infobackendconfig.h"
#include "infoxmlkeysfinder.h"

InfoXmlBackend::InfoXmlBackend(QObject *parent)
    : InfoBackend(parent)
{
    /* Thinking about locking... the watcher notifications are delivered synced,
       so asuming the changes in the dir are atomic this is all we need. */

    qDebug() << "XML backend with path" << InfoXmlBackend::registryPath();

    QDir dir = QDir(InfoXmlBackend::registryPath());
    if (! dir.exists() || ! dir.isReadable()) {
        qDebug() << "Registry path is not a directory or is not readable!";
        return;
    }

    watcher.addPath(InfoXmlBackend::registryPath());
    sconnect(&watcher, SIGNAL(directoryChanged(QString)), this, SLOT(onDirectoryChanged(QString)));
    sconnect(&watcher, SIGNAL(fileChanged(QString)), this, SLOT(onFileChanged(QString)));

	regenerateKeyDataList();
}

QString InfoXmlBackend::name() const
{
    return QString("xml backend");
}

QStringList InfoXmlBackend::listKeys() const
{
	QStringList list;

    // FIXME Hmm, we could return just the keyDataHash.keys itself here...
    foreach (QString key, keyDataHash.keys()) {
        list << keyDataHash.value(key).name;
    }

	return list;
}

QStringList InfoXmlBackend::listKeys(QString providername) const
{
    // This is slow and not nice, but we're an xml backend and
    // we can afford to not be the first in the run
   	QStringList list;

    foreach (QString key, keyDataHash.keys()) {
        if (keyDataHash.value(key).provider == providername)
            list << keyDataHash.value(key).name;
    }

    return list;
}

QStringList InfoXmlBackend::listProviders() const
{
    // Again -- slow.
    QStringList list;

    foreach (QString key, keyDataHash.keys()) {
        QString provider = keyDataHash.value(key).provider;
        if (! list.contains(provider))
            list << provider;
    }

    return list;
}

QString InfoXmlBackend::typeForKey(QString key) const
{
    if (! keyDataHash.contains(key))
        return "";

    return keyDataHash.value(key).type;
}

QString InfoXmlBackend::docForKey(QString key) const
{
    if (! keyDataHash.contains(key))
        return "";

    return keyDataHash.value(key).doc;
}

QString InfoXmlBackend::providerForKey(QString key) const
{
    if (! keyDataHash.contains(key))
        return "";

    return keyDataHash.value(key).provider;
}

QString InfoXmlBackend::providerDBusTypeForKey(QString key) const
{
    if (! keyDataHash.contains(key))
        return "";

    return keyDataHash.value(key).bus;
}

QString InfoXmlBackend::registryPath()
{
    const char *regpath = getenv("CONTEXT_PROVIDERS");
    if (! regpath)
        regpath = DEFAULT_REGISTRY_PATH;

    return QString(regpath);
}

/* Slots */

void InfoXmlBackend::onFileChanged(const QString &path)
{
    // If one of the watched xml files changed this it pretty much
    // an unconditional reload message for us.

    qDebug() << path << "changed.";

    QStringList oldKeys = listKeys();
    regenerateKeyDataList();
    QStringList currentKeys = listKeys();

    // Emissions
    checkAndEmitKeysAdded(currentKeys, oldKeys);
    checkAndEmitKeysRemoved(currentKeys, oldKeys);
    emit keysChanged(listKeys());

    foreach(QString key, oldKeys) {
        emit keyDataChanged(key);
    }
}

void InfoXmlBackend::onDirectoryChanged(const QString &path)
{
    // It could be that some other file was added to the directory which
    // we don't care about anyways.

    QDir dir = QDir(registryPath());
    dir.setFilter(QDir::Files);
    dir.setNameFilters(QStringList("*.xml"));

    // It's enough for us to compare sizes here, not actual content (filenames). The
    // latter case is always handled by the fileChanged.

    if (dir.entryInfoList().size() == countOfFilesInLastParse)
        return;

    qDebug() << registryPath() << "directory changed.";

    QStringList oldKeys = listKeys();
    regenerateKeyDataList();
    QStringList currentKeys = listKeys();

    // Emissions
    emit keysChanged(listKeys());
    checkAndEmitKeysAdded(currentKeys, oldKeys);
    checkAndEmitKeysRemoved(currentKeys, oldKeys);

    foreach(QString key, oldKeys) {
        emit keyDataChanged(key);
    }
}

/* Private */

void InfoXmlBackend::regenerateKeyDataList()
{
    keyDataHash.clear();
    countOfFilesInLastParse = 0;

    // Stop watching all files. We do keep wathching the dir though.
    foreach (QString file, watcher.files())
        watcher.removePath(file);

    qDebug() << "Re-reading xml contents from" << InfoXmlBackend::registryPath();

    // For each xml file in the registry we parse it and
    // add it to our hash. We did some sanity checks in the constructor
    // so we skip them now.

    QDir dir = QDir(registryPath());
    dir.setFilter(QDir::Files);
    dir.setNameFilters(QStringList("*.xml"));

    QFileInfoList list = dir.entryInfoList();
    for (int i = 0; i < list.size(); ++i) {
        QFileInfo f = list.at(i);
		readKeyDataFromXml(f);
        watcher.addPath(f.filePath());
        countOfFilesInLastParse++;
    }
}

void InfoXmlBackend::readKeyDataFromXml(const QFileInfo &finfo)
{
    qDebug() << "Reading keys from" << finfo.filePath();

    InfoXmlKeysFinder handler;
    QFile f(finfo.filePath());
    QXmlInputSource source (&f);
    QXmlSimpleReader reader;

    reader.setContentHandler(&handler);
    reader.parse(source);

    // Use insert here instead of unite to overwrite keys
    foreach (QString key, handler.keyDataHash.keys()) {
        if (keyDataHash.contains(key))
            qDebug() << "WARNING: key" << key << "already defined in previous xml file. Overwriting.";

        keyDataHash.insert(key, handler.keyDataHash.value(key));
    }
}

<commit_msg>Fixing a bug where path would be added twice to the xml watcher.<commit_after>/*
 * Copyright (C) 2008 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * 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
 *
 */

#include <QFileInfo>
#include <QDir>
#include <QDebug>
#include <QMutex>
#include <QXmlSimpleReader>
#include <QXmlInputSource>
#include <QFile>
#include <stdlib.h>
#include "sconnect.h"
#include "infoxmlbackend.h"
#include "infobackendconfig.h"
#include "infoxmlkeysfinder.h"

InfoXmlBackend::InfoXmlBackend(QObject *parent)
    : InfoBackend(parent)
{
    /* Thinking about locking... the watcher notifications are delivered synced,
       so asuming the changes in the dir are atomic this is all we need. */

    qDebug() << "XML backend with path" << InfoXmlBackend::registryPath();

    QDir dir = QDir(InfoXmlBackend::registryPath());
    if (! dir.exists() || ! dir.isReadable()) {
        qDebug() << "Registry path is not a directory or is not readable!";
        return;
    }

    watcher.addPath(InfoXmlBackend::registryPath());
    sconnect(&watcher, SIGNAL(directoryChanged(QString)), this, SLOT(onDirectoryChanged(QString)));
    sconnect(&watcher, SIGNAL(fileChanged(QString)), this, SLOT(onFileChanged(QString)));

	regenerateKeyDataList();
}

QString InfoXmlBackend::name() const
{
    return QString("xml backend");
}

QStringList InfoXmlBackend::listKeys() const
{
	QStringList list;

    // FIXME Hmm, we could return just the keyDataHash.keys itself here...
    foreach (QString key, keyDataHash.keys()) {
        list << keyDataHash.value(key).name;
    }

	return list;
}

QStringList InfoXmlBackend::listKeys(QString providername) const
{
    // This is slow and not nice, but we're an xml backend and
    // we can afford to not be the first in the run
   	QStringList list;

    foreach (QString key, keyDataHash.keys()) {
        if (keyDataHash.value(key).provider == providername)
            list << keyDataHash.value(key).name;
    }

    return list;
}

QStringList InfoXmlBackend::listProviders() const
{
    // Again -- slow.
    QStringList list;

    foreach (QString key, keyDataHash.keys()) {
        QString provider = keyDataHash.value(key).provider;
        if (! list.contains(provider))
            list << provider;
    }

    return list;
}

QString InfoXmlBackend::typeForKey(QString key) const
{
    if (! keyDataHash.contains(key))
        return "";

    return keyDataHash.value(key).type;
}

QString InfoXmlBackend::docForKey(QString key) const
{
    if (! keyDataHash.contains(key))
        return "";

    return keyDataHash.value(key).doc;
}

QString InfoXmlBackend::providerForKey(QString key) const
{
    if (! keyDataHash.contains(key))
        return "";

    return keyDataHash.value(key).provider;
}

QString InfoXmlBackend::providerDBusTypeForKey(QString key) const
{
    if (! keyDataHash.contains(key))
        return "";

    return keyDataHash.value(key).bus;
}

QString InfoXmlBackend::registryPath()
{
    const char *regpath = getenv("CONTEXT_PROVIDERS");
    if (! regpath)
        regpath = DEFAULT_REGISTRY_PATH;

    return QString(regpath);
}

/* Slots */

void InfoXmlBackend::onFileChanged(const QString &path)
{
    // If one of the watched xml files changed this it pretty much
    // an unconditional reload message for us.

    qDebug() << path << "changed.";

    QStringList oldKeys = listKeys();
    regenerateKeyDataList();
    QStringList currentKeys = listKeys();

    // Emissions
    checkAndEmitKeysAdded(currentKeys, oldKeys);
    checkAndEmitKeysRemoved(currentKeys, oldKeys);
    emit keysChanged(listKeys());

    foreach(QString key, oldKeys) {
        emit keyDataChanged(key);
    }
}

void InfoXmlBackend::onDirectoryChanged(const QString &path)
{
    // It could be that some other file was added to the directory which
    // we don't care about anyways.

    QDir dir = QDir(registryPath());
    dir.setFilter(QDir::Files);
    dir.setNameFilters(QStringList("*.xml"));

    // It's enough for us to compare sizes here, not actual content (filenames). The
    // latter case is always handled by the fileChanged.

    if (dir.entryInfoList().size() == countOfFilesInLastParse)
        return;

    qDebug() << registryPath() << "directory changed.";

    QStringList oldKeys = listKeys();
    regenerateKeyDataList();
    QStringList currentKeys = listKeys();

    // Emissions
    emit keysChanged(listKeys());
    checkAndEmitKeysAdded(currentKeys, oldKeys);
    checkAndEmitKeysRemoved(currentKeys, oldKeys);

    foreach(QString key, oldKeys) {
        emit keyDataChanged(key);
    }
}

/* Private */

void InfoXmlBackend::regenerateKeyDataList()
{
    keyDataHash.clear();
    countOfFilesInLastParse = 0;

    // Stop watching all files. We do keep wathching the dir though.
    QStringList watchedFiles = watcher.files();
    if (watchedFiles.size() > 0)
        watcher.removePaths(watchedFiles);

    qDebug() << "Re-reading xml contents from" << InfoXmlBackend::registryPath();

    // For each xml file in the registry we parse it and
    // add it to our hash. We did some sanity checks in the constructor
    // so we skip them now.

    QDir dir = QDir(registryPath());
    dir.setFilter(QDir::Files);
    dir.setNameFilters(QStringList("*.xml"));

    QFileInfoList list = dir.entryInfoList();
    for (int i = 0; i < list.size(); ++i) {
        QFileInfo f = list.at(i);
		readKeyDataFromXml(f);

        if (! watcher.files().contains(f.filePath()))
            watcher.addPath(f.filePath());

        countOfFilesInLastParse++;
    }
}

void InfoXmlBackend::readKeyDataFromXml(const QFileInfo &finfo)
{
    qDebug() << "Reading keys from" << finfo.filePath();

    InfoXmlKeysFinder handler;
    QFile f(finfo.filePath());
    QXmlInputSource source (&f);
    QXmlSimpleReader reader;

    reader.setContentHandler(&handler);
    reader.parse(source);

    // Use insert here instead of unite to overwrite keys
    foreach (QString key, handler.keyDataHash.keys()) {
        if (keyDataHash.contains(key))
            qDebug() << "WARNING: key" << key << "already defined in previous xml file. Overwriting.";

        keyDataHash.insert(key, handler.keyDataHash.value(key));
    }
}

<|endoftext|>


<commit_before>#include "application.hpp"

#include "controllers/commands/commandcontroller.hpp"
#include "controllers/highlights/highlightcontroller.hpp"
#include "providers/twitch/pubsub.hpp"
#include "providers/twitch/twitchserver.hpp"
#include "singletons/accountmanager.hpp"
#include "singletons/emotemanager.hpp"
#include "singletons/fontmanager.hpp"
#include "singletons/loggingmanager.hpp"
#include "singletons/nativemessagingmanager.hpp"
#include "singletons/pathmanager.hpp"
#include "singletons/resourcemanager.hpp"
#include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp"
#include "singletons/windowmanager.hpp"
#include "util/posttothread.hpp"

#include <atomic>

#ifdef Q_OS_WIN
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#endif

using namespace chatterino::singletons;

namespace chatterino {

namespace {

bool isBigEndian()
{
    int test = 1;
    char *p = (char *)&test;

    return p[0] == 0;
}

}  // namespace

static std::atomic<bool> isAppConstructed{false};
static std::atomic<bool> isAppInitialized{false};

static Application *staticApp = nullptr;

// this class is responsible for handling the workflow of Chatterino
// It will create the instances of the major classes, and connect their signals to each other

Application::Application(int _argc, char **_argv)
    : argc(_argc)
    , argv(_argv)
{
}

void Application::construct()
{
    assert(isAppConstructed == false);
    isAppConstructed = true;

    // 1. Instantiate all classes
    this->paths = new singletons::PathManager(this->argc, this->argv);
    this->themes = new singletons::ThemeManager;
    this->windows = new singletons::WindowManager;
    this->logging = new singletons::LoggingManager;
    this->commands = new controllers::commands::CommandController;
    this->highlights = new controllers::highlights::HighlightController;
    this->accounts = new singletons::AccountManager;
    this->emotes = new singletons::EmoteManager;
    this->settings = new singletons::SettingManager;
    this->fonts = new singletons::FontManager;
    this->resources = new singletons::ResourceManager;

    this->twitch.server = new providers::twitch::TwitchServer;
    this->twitch.pubsub = new providers::twitch::PubSub;
}

void Application::instantiate(int argc, char **argv)
{
    assert(staticApp == nullptr);

    staticApp = new Application(argc, argv);
}

void Application::initialize()
{
    assert(isAppInitialized == false);
    isAppInitialized = true;

    // 2. Initialize/load classes
    this->settings->initialize();
    this->windows->initialize();

    this->nativeMessaging->registerHost();

    this->settings->load();
    this->commands->load();

    this->highlights->initialize();

    this->emotes->loadGlobalEmotes();

    this->accounts->load();

    this->twitch.server->initialize();
    this->logging->initialize();

    // XXX
    this->settings->updateWordTypeMask();

    this->nativeMessaging->openGuiMessageQueue();

    this->twitch.pubsub->sig.whisper.sent.connect([](const auto &msg) {
        debug::Log("WHISPER SENT LOL");  //
    });

    this->twitch.pubsub->sig.whisper.received.connect([](const auto &msg) {
        debug::Log("WHISPER RECEIVED LOL");  //
    });

    this->twitch.pubsub->sig.moderation.chatCleared.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text = QString("%1 cleared the chat").arg(action.source.name);

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.modeChanged.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text =
            QString("%1 turned %2 %3 mode")  //
                .arg(action.source.name)
                .arg(action.state == providers::twitch::ModeChangedAction::State::On ? "on" : "off")
                .arg(action.getModeName());

        if (action.duration > 0) {
            text.append(" (" + QString::number(action.duration) + " seconds)");
        }

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.moderationStateChanged.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text;

        if (action.modded) {
            text = QString("%1 modded %2").arg(action.source.name, action.target.name);
        } else {
            text = QString("%1 unmodded %2").arg(action.source.name, action.target.name);
        }

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.userBanned.connect([&](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);

        if (chan->isEmpty()) {
            return;
        }

        auto msg = messages::Message::createTimeoutMessage(action);

        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.userUnbanned.connect([&](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);

        if (chan->isEmpty()) {
            return;
        }

        auto msg = messages::Message::createUntimeoutMessage(action);

        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->start();

    auto RequestModerationActions = [=]() {
        this->twitch.pubsub->unlistenAllModerationActions();
        // TODO(pajlada): Unlisten to all authed topics instead of only moderation topics
        // this->twitch.pubsub->UnlistenAllAuthedTopics();

        this->twitch.pubsub->listenToWhispers(this->accounts->Twitch.getCurrent());  //
    };

    this->accounts->Twitch.currentUserChanged.connect(RequestModerationActions);

    RequestModerationActions();
}

int Application::run(QApplication &qtApp)
{
    // Start connecting to the IRC Servers (Twitch only for now)
    this->twitch.server->connect();

    // Show main window
    this->windows->getMainWindow().show();

    return qtApp.exec();
}

void Application::save()
{
    this->windows->save();

    this->commands->save();
}

void Application::runNativeMessagingHost()
{
    auto app = getApp();

    app->nativeMessaging = new singletons::NativeMessagingManager;

#ifdef Q_OS_WIN
    _setmode(_fileno(stdin), _O_BINARY);
    _setmode(_fileno(stdout), _O_BINARY);
#endif

#if 0
    bool bigEndian = isBigEndian();
#endif

    while (true) {
        char size_c[4];
        std::cin.read(size_c, 4);

        if (std::cin.eof()) {
            break;
        }

        uint32_t size = *reinterpret_cast<uint32_t *>(size_c);
#if 0
        // To avoid breaking strict-aliasing rules and potentially inducing undefined behaviour, the following code can be run instead
        uint32_t size = 0;
        if (bigEndian) {
            size = size_c[3] | static_cast<uint32_t>(size_c[2]) << 8 |
                   static_cast<uint32_t>(size_c[1]) << 16 | static_cast<uint32_t>(size_c[0]) << 24;
        } else {
            size = size_c[0] | static_cast<uint32_t>(size_c[1]) << 8 |
                   static_cast<uint32_t>(size_c[2]) << 16 | static_cast<uint32_t>(size_c[3]) << 24;
        }
#endif

        char *b = (char *)malloc(size + 1);
        std::cin.read(b, size);
        *(b + size) = '\0';

        app->nativeMessaging->sendToGuiProcess(QByteArray(b, size));

        free(b);
    }
}

Application *getApp()
{
    assert(staticApp != nullptr);

    return staticApp;
}

bool appInitialized()
{
    return isAppInitialized;
}

}  // namespace chatterino
<commit_msg>Add missing resources initialize call<commit_after>#include "application.hpp"

#include "controllers/commands/commandcontroller.hpp"
#include "controllers/highlights/highlightcontroller.hpp"
#include "providers/twitch/pubsub.hpp"
#include "providers/twitch/twitchserver.hpp"
#include "singletons/accountmanager.hpp"
#include "singletons/emotemanager.hpp"
#include "singletons/fontmanager.hpp"
#include "singletons/loggingmanager.hpp"
#include "singletons/nativemessagingmanager.hpp"
#include "singletons/pathmanager.hpp"
#include "singletons/resourcemanager.hpp"
#include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp"
#include "singletons/windowmanager.hpp"
#include "util/posttothread.hpp"

#include <atomic>

#ifdef Q_OS_WIN
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#endif

using namespace chatterino::singletons;

namespace chatterino {

namespace {

bool isBigEndian()
{
    int test = 1;
    char *p = (char *)&test;

    return p[0] == 0;
}

}  // namespace

static std::atomic<bool> isAppConstructed{false};
static std::atomic<bool> isAppInitialized{false};

static Application *staticApp = nullptr;

// this class is responsible for handling the workflow of Chatterino
// It will create the instances of the major classes, and connect their signals to each other

Application::Application(int _argc, char **_argv)
    : argc(_argc)
    , argv(_argv)
{
}

void Application::construct()
{
    assert(isAppConstructed == false);
    isAppConstructed = true;

    // 1. Instantiate all classes
    this->paths = new singletons::PathManager(this->argc, this->argv);
    this->themes = new singletons::ThemeManager;
    this->windows = new singletons::WindowManager;
    this->logging = new singletons::LoggingManager;
    this->commands = new controllers::commands::CommandController;
    this->highlights = new controllers::highlights::HighlightController;
    this->accounts = new singletons::AccountManager;
    this->emotes = new singletons::EmoteManager;
    this->settings = new singletons::SettingManager;
    this->fonts = new singletons::FontManager;
    this->resources = new singletons::ResourceManager;

    this->twitch.server = new providers::twitch::TwitchServer;
    this->twitch.pubsub = new providers::twitch::PubSub;
}

void Application::instantiate(int argc, char **argv)
{
    assert(staticApp == nullptr);

    staticApp = new Application(argc, argv);
}

void Application::initialize()
{
    assert(isAppInitialized == false);
    isAppInitialized = true;

    // 2. Initialize/load classes
    this->settings->initialize();
    this->windows->initialize();

    this->nativeMessaging->registerHost();

    this->settings->load();
    this->commands->load();

    this->resources->initialize();

    this->highlights->initialize();

    this->emotes->loadGlobalEmotes();

    this->accounts->load();

    this->twitch.server->initialize();
    this->logging->initialize();

    // XXX
    this->settings->updateWordTypeMask();

    this->nativeMessaging->openGuiMessageQueue();

    this->twitch.pubsub->sig.whisper.sent.connect([](const auto &msg) {
        debug::Log("WHISPER SENT LOL");  //
    });

    this->twitch.pubsub->sig.whisper.received.connect([](const auto &msg) {
        debug::Log("WHISPER RECEIVED LOL");  //
    });

    this->twitch.pubsub->sig.moderation.chatCleared.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text = QString("%1 cleared the chat").arg(action.source.name);

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.modeChanged.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text =
            QString("%1 turned %2 %3 mode")  //
                .arg(action.source.name)
                .arg(action.state == providers::twitch::ModeChangedAction::State::On ? "on" : "off")
                .arg(action.getModeName());

        if (action.duration > 0) {
            text.append(" (" + QString::number(action.duration) + " seconds)");
        }

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.moderationStateChanged.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text;

        if (action.modded) {
            text = QString("%1 modded %2").arg(action.source.name, action.target.name);
        } else {
            text = QString("%1 unmodded %2").arg(action.source.name, action.target.name);
        }

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.userBanned.connect([&](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);

        if (chan->isEmpty()) {
            return;
        }

        auto msg = messages::Message::createTimeoutMessage(action);

        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.userUnbanned.connect([&](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);

        if (chan->isEmpty()) {
            return;
        }

        auto msg = messages::Message::createUntimeoutMessage(action);

        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->start();

    auto RequestModerationActions = [=]() {
        this->twitch.pubsub->unlistenAllModerationActions();
        // TODO(pajlada): Unlisten to all authed topics instead of only moderation topics
        // this->twitch.pubsub->UnlistenAllAuthedTopics();

        this->twitch.pubsub->listenToWhispers(this->accounts->Twitch.getCurrent());  //
    };

    this->accounts->Twitch.currentUserChanged.connect(RequestModerationActions);

    RequestModerationActions();
}

int Application::run(QApplication &qtApp)
{
    // Start connecting to the IRC Servers (Twitch only for now)
    this->twitch.server->connect();

    // Show main window
    this->windows->getMainWindow().show();

    return qtApp.exec();
}

void Application::save()
{
    this->windows->save();

    this->commands->save();
}

void Application::runNativeMessagingHost()
{
    auto app = getApp();

    app->nativeMessaging = new singletons::NativeMessagingManager;

#ifdef Q_OS_WIN
    _setmode(_fileno(stdin), _O_BINARY);
    _setmode(_fileno(stdout), _O_BINARY);
#endif

#if 0
    bool bigEndian = isBigEndian();
#endif

    while (true) {
        char size_c[4];
        std::cin.read(size_c, 4);

        if (std::cin.eof()) {
            break;
        }

        uint32_t size = *reinterpret_cast<uint32_t *>(size_c);
#if 0
        // To avoid breaking strict-aliasing rules and potentially inducing undefined behaviour, the following code can be run instead
        uint32_t size = 0;
        if (bigEndian) {
            size = size_c[3] | static_cast<uint32_t>(size_c[2]) << 8 |
                   static_cast<uint32_t>(size_c[1]) << 16 | static_cast<uint32_t>(size_c[0]) << 24;
        } else {
            size = size_c[0] | static_cast<uint32_t>(size_c[1]) << 8 |
                   static_cast<uint32_t>(size_c[2]) << 16 | static_cast<uint32_t>(size_c[3]) << 24;
        }
#endif

        char *b = (char *)malloc(size + 1);
        std::cin.read(b, size);
        *(b + size) = '\0';

        app->nativeMessaging->sendToGuiProcess(QByteArray(b, size));

        free(b);
    }
}

Application *getApp()
{
    assert(staticApp != nullptr);

    return staticApp;
}

bool appInitialized()
{
    return isAppInitialized;
}

}  // namespace chatterino
<|endoftext|>


<commit_before>#include "SDLWindow.h"
#include "SDLApplication.h"

#ifdef HX_WINDOWS
#include <SDL_syswm.h>
#include <Windows.h>
#undef CreateWindow
#endif

namespace lime {

	static bool displayModeSet = false;

	SDLWindow::SDLWindow (Application* application, int width, int height, int flags, const char* title) {

		currentApplication = application;
		this->flags = flags;

		int sdlFlags = 0;

		if (flags & WINDOW_FLAG_FULLSCREEN) sdlFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
		if (flags & WINDOW_FLAG_RESIZABLE) sdlFlags |= SDL_WINDOW_RESIZABLE;
		if (flags & WINDOW_FLAG_BORDERLESS) sdlFlags |= SDL_WINDOW_BORDERLESS;
		if (flags & WINDOW_FLAG_HIDDEN) sdlFlags |= SDL_WINDOW_HIDDEN;
		if (flags & WINDOW_FLAG_MINIMIZED) sdlFlags |= SDL_WINDOW_MINIMIZED;
		if (flags & WINDOW_FLAG_MAXIMIZED) sdlFlags |= SDL_WINDOW_MAXIMIZED;
		if (flags & WINDOW_FLAG_ALWAYS_ON_TOP) sdlFlags |= SDL_WINDOW_ALWAYS_ON_TOP;

		#if defined (HX_WINDOWS) && defined (NATIVE_TOOLKIT_SDL_ANGLE)
		OSVERSIONINFOEXW osvi = { sizeof (osvi), 0, 0, 0, 0, {0}, 0, 0 };
		DWORDLONG const dwlConditionMask = VerSetConditionMask (VerSetConditionMask (VerSetConditionMask (0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
		osvi.dwMajorVersion = HIBYTE (_WIN32_WINNT_VISTA);
		osvi.dwMinorVersion = LOBYTE (_WIN32_WINNT_VISTA);
		osvi.wServicePackMajor = 0;

		if (VerifyVersionInfoW (&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) == FALSE) {

			flags &= ~WINDOW_FLAG_HARDWARE;

		}
		#endif

		if (flags & WINDOW_FLAG_HARDWARE) {

			sdlFlags |= SDL_WINDOW_OPENGL;

			if (flags & WINDOW_FLAG_ALLOW_HIGHDPI) {

				sdlFlags |= SDL_WINDOW_ALLOW_HIGHDPI;

			}

			#if defined (HX_WINDOWS) && defined (NATIVE_TOOLKIT_SDL_ANGLE)
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
			SDL_SetHint (SDL_HINT_VIDEO_WIN_D3DCOMPILER, "d3dcompiler_47.dll");
			#endif

			#if defined (RASPBERRYPI)
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
			SDL_SetHint (SDL_HINT_RENDER_DRIVER, "opengles2");
			#endif

			if (flags & WINDOW_FLAG_DEPTH_BUFFER) {

				SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 32 - (flags & WINDOW_FLAG_STENCIL_BUFFER) ? 8 : 0);

			}

			if (flags & WINDOW_FLAG_STENCIL_BUFFER) {

				SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8);

			}

			if (flags & WINDOW_FLAG_HW_AA_HIRES) {

				SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, true);
				SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, 4);

			} else if (flags & WINDOW_FLAG_HW_AA) {

				SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, true);
				SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, 2);

			}

			SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
			SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 6);
			SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);

		}

		sdlWindow = SDL_CreateWindow (title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, sdlFlags);

		if (!sdlWindow) {

			printf ("Could not create SDL window: %s.\n", SDL_GetError ());

		}

		((SDLApplication*)currentApplication)->RegisterWindow (this);

		#ifdef HX_WINDOWS

		HINSTANCE handle = ::GetModuleHandle (nullptr);
		HICON icon = ::LoadIcon (handle, MAKEINTRESOURCE (1));

		if (icon != nullptr) {

			SDL_SysWMinfo wminfo;
			SDL_VERSION (&wminfo.version);

			if (SDL_GetWindowWMInfo (sdlWindow, &wminfo) == 1) {

				HWND hwnd = wminfo.info.win.window;
				::SetClassLong (hwnd, GCL_HICON, reinterpret_cast<LONG>(icon));

			}

		}

		#endif

	}

	SDLWindow::~SDLWindow () {

		if (sdlWindow) {

			SDL_DestroyWindow (sdlWindow);
			sdlWindow = 0;

		}

	}

	void SDLWindow::Alert (const char* message, const char* title) {

		#ifdef HX_WINDOWS

		int count = 0;
		int speed = 0;
		bool stopOnForeground = true;

		SDL_SysWMinfo info;
		SDL_VERSION (&info.version);
		SDL_GetWindowWMInfo (sdlWindow, &info);

		FLASHWINFO fi;
		fi.cbSize = sizeof (FLASHWINFO);
		fi.hwnd = info.info.win.window;
		fi.dwFlags = stopOnForeground ? FLASHW_ALL | FLASHW_TIMERNOFG : FLASHW_ALL | FLASHW_TIMER;
		fi.uCount = count;
		fi.dwTimeout = speed;
		FlashWindowEx (&fi);

		#endif

		if (message) {

			SDL_ShowSimpleMessageBox (SDL_MESSAGEBOX_INFORMATION, title, message, sdlWindow);

		}

	}

	void SDLWindow::Close () {

		if (sdlWindow) {

			SDL_DestroyWindow (sdlWindow);
			sdlWindow = 0;

		}

	}

	void SDLWindow::Focus () {

		SDL_RaiseWindow (sdlWindow);

	}

	int SDLWindow::GetDisplay () {

		return SDL_GetWindowDisplayIndex (sdlWindow);

	}

	void SDLWindow::GetDisplayMode (DisplayMode* displayMode) {

		SDL_DisplayMode mode;
		SDL_GetWindowDisplayMode (sdlWindow, &mode);

		displayMode->width = mode.w;
		displayMode->height = mode.h;

		switch (mode.format) {

			case SDL_PIXELFORMAT_ARGB8888:

				displayMode->pixelFormat = ARGB32;
				break;

			case SDL_PIXELFORMAT_BGRA8888:
			case SDL_PIXELFORMAT_BGRX8888:

				displayMode->pixelFormat = BGRA32;
				break;

			default:

				displayMode->pixelFormat = RGBA32;

		}

		displayMode->refreshRate = mode.refresh_rate;

	}

	bool SDLWindow::GetEnableTextEvents () {

		return SDL_IsTextInputActive ();

	}

	int SDLWindow::GetHeight () {

		int width;
		int height;

		SDL_GetWindowSize (sdlWindow, &width, &height);

		return height;

	}

	uint32_t SDLWindow::GetID () {

		return SDL_GetWindowID (sdlWindow);

	}

	int SDLWindow::GetWidth () {

		int width;
		int height;

		SDL_GetWindowSize (sdlWindow, &width, &height);

		return width;

	}

	int SDLWindow::GetX () {

		int x;
		int y;

		SDL_GetWindowPosition (sdlWindow, &x, &y);

		return x;

	}

	int SDLWindow::GetY () {

		int x;
		int y;

		SDL_GetWindowPosition (sdlWindow, &x, &y);

		return y;

	}

	void SDLWindow::Move (int x, int y) {

		SDL_SetWindowPosition (sdlWindow, x, y);

	}

	void SDLWindow::Resize (int width, int height) {

		SDL_SetWindowSize (sdlWindow, width, height);

	}

	bool SDLWindow::SetBorderless (bool borderless) {

		if (borderless) {

			SDL_SetWindowBordered (sdlWindow, SDL_FALSE);

		} else {

			SDL_SetWindowBordered (sdlWindow, SDL_TRUE);

		}

		return borderless;

	}

	void SDLWindow::SetDisplayMode (DisplayMode* displayMode) {

		Uint32 pixelFormat = 0;

		switch (displayMode->pixelFormat) {

			case ARGB32:

				pixelFormat = SDL_PIXELFORMAT_ARGB8888;
				break;

			case BGRA32:

				pixelFormat = SDL_PIXELFORMAT_BGRA8888;
				break;

			default:

				pixelFormat = SDL_PIXELFORMAT_RGBA8888;

		}

		SDL_DisplayMode mode = { pixelFormat, displayMode->width, displayMode->height, displayMode->refreshRate, 0 };

		if (SDL_SetWindowDisplayMode (sdlWindow, &mode) == 0) {

			displayModeSet = true;

			if (SDL_GetWindowFlags (sdlWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP) {

				SDL_SetWindowFullscreen (sdlWindow, SDL_WINDOW_FULLSCREEN);

			}

		}

	}

	void SDLWindow::SetEnableTextEvents (bool enabled) {

		if (enabled) {

			SDL_StartTextInput ();

		} else {

			SDL_StopTextInput ();

		}

	}

	bool SDLWindow::SetFullscreen (bool fullscreen) {

		if (fullscreen) {

			if (displayModeSet) {

				SDL_SetWindowFullscreen (sdlWindow, SDL_WINDOW_FULLSCREEN);

			} else {

				SDL_SetWindowFullscreen (sdlWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);

			}

		} else {

			SDL_SetWindowFullscreen (sdlWindow, 0);

		}

		return fullscreen;

	}

	void SDLWindow::SetIcon (ImageBuffer *imageBuffer) {

		SDL_Surface *surface = SDL_CreateRGBSurfaceFrom (imageBuffer->data->Data (), imageBuffer->width, imageBuffer->height, imageBuffer->bitsPerPixel, imageBuffer->Stride (), 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);

		if (surface) {

			SDL_SetWindowIcon (sdlWindow, surface);
			SDL_FreeSurface (surface);

		}

	}

	bool SDLWindow::SetMaximized (bool maximized) {

		if (maximized) {

			SDL_MaximizeWindow (sdlWindow);

		} else {

			SDL_RestoreWindow (sdlWindow);

		}

		return maximized;

	}

	bool SDLWindow::SetMinimized (bool minimized) {

		if (minimized) {

			SDL_MinimizeWindow (sdlWindow);

		} else {

			SDL_RestoreWindow (sdlWindow);

		}

		return minimized;

	}

	bool SDLWindow::SetResizable (bool resizable) {

		#ifndef EMSCRIPTEN

		if (resizable) {

			SDL_SetWindowResizable (sdlWindow, SDL_TRUE);

		} else {

			SDL_SetWindowResizable (sdlWindow, SDL_FALSE);

		}

		return (SDL_GetWindowFlags (sdlWindow) & SDL_WINDOW_RESIZABLE);

		#else

		return resizable;

		#endif
	}

	const char* SDLWindow::SetTitle (const char* title) {

		SDL_SetWindowTitle (sdlWindow, title);

		return title;

	}

	Window* CreateWindow (Application* application, int width, int height, int flags, const char* title) {

		return new SDLWindow (application, width, height, flags, title);

	}

}
<commit_msg>Fix Emscripten build<commit_after>#include "SDLWindow.h"
#include "SDLApplication.h"

#ifdef HX_WINDOWS
#include <SDL_syswm.h>
#include <Windows.h>
#undef CreateWindow
#endif

namespace lime {

	static bool displayModeSet = false;

	SDLWindow::SDLWindow (Application* application, int width, int height, int flags, const char* title) {

		currentApplication = application;
		this->flags = flags;

		int sdlFlags = 0;

		if (flags & WINDOW_FLAG_FULLSCREEN) sdlFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
		if (flags & WINDOW_FLAG_RESIZABLE) sdlFlags |= SDL_WINDOW_RESIZABLE;
		if (flags & WINDOW_FLAG_BORDERLESS) sdlFlags |= SDL_WINDOW_BORDERLESS;
		if (flags & WINDOW_FLAG_HIDDEN) sdlFlags |= SDL_WINDOW_HIDDEN;
		if (flags & WINDOW_FLAG_MINIMIZED) sdlFlags |= SDL_WINDOW_MINIMIZED;
		if (flags & WINDOW_FLAG_MAXIMIZED) sdlFlags |= SDL_WINDOW_MAXIMIZED;

		#ifndef EMSCRIPTEN
		if (flags & WINDOW_FLAG_ALWAYS_ON_TOP) sdlFlags |= SDL_WINDOW_ALWAYS_ON_TOP;
		#endif

		#if defined (HX_WINDOWS) && defined (NATIVE_TOOLKIT_SDL_ANGLE)
		OSVERSIONINFOEXW osvi = { sizeof (osvi), 0, 0, 0, 0, {0}, 0, 0 };
		DWORDLONG const dwlConditionMask = VerSetConditionMask (VerSetConditionMask (VerSetConditionMask (0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
		osvi.dwMajorVersion = HIBYTE (_WIN32_WINNT_VISTA);
		osvi.dwMinorVersion = LOBYTE (_WIN32_WINNT_VISTA);
		osvi.wServicePackMajor = 0;

		if (VerifyVersionInfoW (&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) == FALSE) {

			flags &= ~WINDOW_FLAG_HARDWARE;

		}
		#endif

		if (flags & WINDOW_FLAG_HARDWARE) {

			sdlFlags |= SDL_WINDOW_OPENGL;

			if (flags & WINDOW_FLAG_ALLOW_HIGHDPI) {

				sdlFlags |= SDL_WINDOW_ALLOW_HIGHDPI;

			}

			#if defined (HX_WINDOWS) && defined (NATIVE_TOOLKIT_SDL_ANGLE)
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
			SDL_SetHint (SDL_HINT_VIDEO_WIN_D3DCOMPILER, "d3dcompiler_47.dll");
			#endif

			#if defined (RASPBERRYPI)
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
			SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
			SDL_SetHint (SDL_HINT_RENDER_DRIVER, "opengles2");
			#endif

			if (flags & WINDOW_FLAG_DEPTH_BUFFER) {

				SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 32 - (flags & WINDOW_FLAG_STENCIL_BUFFER) ? 8 : 0);

			}

			if (flags & WINDOW_FLAG_STENCIL_BUFFER) {

				SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8);

			}

			if (flags & WINDOW_FLAG_HW_AA_HIRES) {

				SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, true);
				SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, 4);

			} else if (flags & WINDOW_FLAG_HW_AA) {

				SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, true);
				SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, 2);

			}

			SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
			SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 6);
			SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);

		}

		sdlWindow = SDL_CreateWindow (title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, sdlFlags);

		if (!sdlWindow) {

			printf ("Could not create SDL window: %s.\n", SDL_GetError ());

		}

		((SDLApplication*)currentApplication)->RegisterWindow (this);

		#ifdef HX_WINDOWS

		HINSTANCE handle = ::GetModuleHandle (nullptr);
		HICON icon = ::LoadIcon (handle, MAKEINTRESOURCE (1));

		if (icon != nullptr) {

			SDL_SysWMinfo wminfo;
			SDL_VERSION (&wminfo.version);

			if (SDL_GetWindowWMInfo (sdlWindow, &wminfo) == 1) {

				HWND hwnd = wminfo.info.win.window;
				::SetClassLong (hwnd, GCL_HICON, reinterpret_cast<LONG>(icon));

			}

		}

		#endif

	}

	SDLWindow::~SDLWindow () {

		if (sdlWindow) {

			SDL_DestroyWindow (sdlWindow);
			sdlWindow = 0;

		}

	}

	void SDLWindow::Alert (const char* message, const char* title) {

		#ifdef HX_WINDOWS

		int count = 0;
		int speed = 0;
		bool stopOnForeground = true;

		SDL_SysWMinfo info;
		SDL_VERSION (&info.version);
		SDL_GetWindowWMInfo (sdlWindow, &info);

		FLASHWINFO fi;
		fi.cbSize = sizeof (FLASHWINFO);
		fi.hwnd = info.info.win.window;
		fi.dwFlags = stopOnForeground ? FLASHW_ALL | FLASHW_TIMERNOFG : FLASHW_ALL | FLASHW_TIMER;
		fi.uCount = count;
		fi.dwTimeout = speed;
		FlashWindowEx (&fi);

		#endif

		if (message) {

			SDL_ShowSimpleMessageBox (SDL_MESSAGEBOX_INFORMATION, title, message, sdlWindow);

		}

	}

	void SDLWindow::Close () {

		if (sdlWindow) {

			SDL_DestroyWindow (sdlWindow);
			sdlWindow = 0;

		}

	}

	void SDLWindow::Focus () {

		SDL_RaiseWindow (sdlWindow);

	}

	int SDLWindow::GetDisplay () {

		return SDL_GetWindowDisplayIndex (sdlWindow);

	}

	void SDLWindow::GetDisplayMode (DisplayMode* displayMode) {

		SDL_DisplayMode mode;
		SDL_GetWindowDisplayMode (sdlWindow, &mode);

		displayMode->width = mode.w;
		displayMode->height = mode.h;

		switch (mode.format) {

			case SDL_PIXELFORMAT_ARGB8888:

				displayMode->pixelFormat = ARGB32;
				break;

			case SDL_PIXELFORMAT_BGRA8888:
			case SDL_PIXELFORMAT_BGRX8888:

				displayMode->pixelFormat = BGRA32;
				break;

			default:

				displayMode->pixelFormat = RGBA32;

		}

		displayMode->refreshRate = mode.refresh_rate;

	}

	bool SDLWindow::GetEnableTextEvents () {

		return SDL_IsTextInputActive ();

	}

	int SDLWindow::GetHeight () {

		int width;
		int height;

		SDL_GetWindowSize (sdlWindow, &width, &height);

		return height;

	}

	uint32_t SDLWindow::GetID () {

		return SDL_GetWindowID (sdlWindow);

	}

	int SDLWindow::GetWidth () {

		int width;
		int height;

		SDL_GetWindowSize (sdlWindow, &width, &height);

		return width;

	}

	int SDLWindow::GetX () {

		int x;
		int y;

		SDL_GetWindowPosition (sdlWindow, &x, &y);

		return x;

	}

	int SDLWindow::GetY () {

		int x;
		int y;

		SDL_GetWindowPosition (sdlWindow, &x, &y);

		return y;

	}

	void SDLWindow::Move (int x, int y) {

		SDL_SetWindowPosition (sdlWindow, x, y);

	}

	void SDLWindow::Resize (int width, int height) {

		SDL_SetWindowSize (sdlWindow, width, height);

	}

	bool SDLWindow::SetBorderless (bool borderless) {

		if (borderless) {

			SDL_SetWindowBordered (sdlWindow, SDL_FALSE);

		} else {

			SDL_SetWindowBordered (sdlWindow, SDL_TRUE);

		}

		return borderless;

	}

	void SDLWindow::SetDisplayMode (DisplayMode* displayMode) {

		Uint32 pixelFormat = 0;

		switch (displayMode->pixelFormat) {

			case ARGB32:

				pixelFormat = SDL_PIXELFORMAT_ARGB8888;
				break;

			case BGRA32:

				pixelFormat = SDL_PIXELFORMAT_BGRA8888;
				break;

			default:

				pixelFormat = SDL_PIXELFORMAT_RGBA8888;

		}

		SDL_DisplayMode mode = { pixelFormat, displayMode->width, displayMode->height, displayMode->refreshRate, 0 };

		if (SDL_SetWindowDisplayMode (sdlWindow, &mode) == 0) {

			displayModeSet = true;

			if (SDL_GetWindowFlags (sdlWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP) {

				SDL_SetWindowFullscreen (sdlWindow, SDL_WINDOW_FULLSCREEN);

			}

		}

	}

	void SDLWindow::SetEnableTextEvents (bool enabled) {

		if (enabled) {

			SDL_StartTextInput ();

		} else {

			SDL_StopTextInput ();

		}

	}

	bool SDLWindow::SetFullscreen (bool fullscreen) {

		if (fullscreen) {

			if (displayModeSet) {

				SDL_SetWindowFullscreen (sdlWindow, SDL_WINDOW_FULLSCREEN);

			} else {

				SDL_SetWindowFullscreen (sdlWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);

			}

		} else {

			SDL_SetWindowFullscreen (sdlWindow, 0);

		}

		return fullscreen;

	}

	void SDLWindow::SetIcon (ImageBuffer *imageBuffer) {

		SDL_Surface *surface = SDL_CreateRGBSurfaceFrom (imageBuffer->data->Data (), imageBuffer->width, imageBuffer->height, imageBuffer->bitsPerPixel, imageBuffer->Stride (), 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);

		if (surface) {

			SDL_SetWindowIcon (sdlWindow, surface);
			SDL_FreeSurface (surface);

		}

	}

	bool SDLWindow::SetMaximized (bool maximized) {

		if (maximized) {

			SDL_MaximizeWindow (sdlWindow);

		} else {

			SDL_RestoreWindow (sdlWindow);

		}

		return maximized;

	}

	bool SDLWindow::SetMinimized (bool minimized) {

		if (minimized) {

			SDL_MinimizeWindow (sdlWindow);

		} else {

			SDL_RestoreWindow (sdlWindow);

		}

		return minimized;

	}

	bool SDLWindow::SetResizable (bool resizable) {

		#ifndef EMSCRIPTEN

		if (resizable) {

			SDL_SetWindowResizable (sdlWindow, SDL_TRUE);

		} else {

			SDL_SetWindowResizable (sdlWindow, SDL_FALSE);

		}

		return (SDL_GetWindowFlags (sdlWindow) & SDL_WINDOW_RESIZABLE);

		#else

		return resizable;

		#endif
	}

	const char* SDLWindow::SetTitle (const char* title) {

		SDL_SetWindowTitle (sdlWindow, title);

		return title;

	}

	Window* CreateWindow (Application* application, int width, int height, int flags, const char* title) {

		return new SDLWindow (application, width, height, flags, title);

	}

}
<|endoftext|>


<commit_before>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.

#include "../include/librealsense2/hpp/rs_sensor.hpp"
#include "../include/librealsense2/hpp/rs_processing.hpp"

#include "proc/synthetic-stream.h"
#include "context.h"
#include "environment.h"
#include "option.h"
#include "colorizer.h"
#include "disparity-transform.h"

namespace librealsense
{
    static color_map hue{ {
        { 255, 0, 0 },
        { 255, 255, 0 },
        { 0, 255, 0 },
        { 0, 255, 255 },
        { 0, 0, 255 },
        { 255, 0, 255 },
        { 255, 0, 0 },
        } };

    static color_map jet{ {
        { 0, 0, 255 },
        { 0, 255, 255 },
        { 255, 255, 0 },
        { 255, 0, 0 },
        { 50, 0, 0 },
        } };

    static color_map classic{ {
        { 30, 77, 203 },
        { 25, 60, 192 },
        { 45, 117, 220 },
        { 204, 108, 191 },
        { 196, 57, 178 },
        { 198, 33, 24 },
        } };

    static color_map grayscale{ {
        { 255, 255, 255 },
        { 0, 0, 0 },
        } };

    static color_map inv_grayscale{ {
        { 0, 0, 0 },
        { 255, 255, 255 },
        } };

    static color_map biomes{ {
        { 0, 0, 204 },
        { 204, 230, 255 },
        { 255, 255, 153 },
        { 170, 255, 128 },
        { 0, 153, 0 },
        { 230, 242, 255 },
        } };

    static color_map cold{ {
        { 230, 247, 255 },
        { 0, 92, 230 },
        { 0, 179, 179 },
        { 0, 51, 153 },
        { 0, 5, 15 }
        } };

    static color_map warm{ {
        { 255, 255, 230 },
        { 255, 204, 0 },
        { 255, 136, 77 },
        { 255, 51, 0 },
        { 128, 0, 0 },
        { 10, 0, 0 }
        } };

    static color_map quantized{ {
        { 255, 255, 255 },
        { 0, 0, 0 },
        }, 6 };

    static color_map pattern{ {
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        } };

    colorizer::colorizer()
        : colorizer("Depth Visualization")
    {}

    colorizer::colorizer(const char* name)
        : stream_filter_processing_block(name),
         _min(0.f), _max(6.f), _equalize(true),
         _target_stream_profile(), _histogram()
    {
        _histogram = std::vector<int>(MAX_DEPTH, 0);
        _hist_data = _histogram.data();
        _stream_filter.stream = RS2_STREAM_DEPTH;
        _stream_filter.format = RS2_FORMAT_Z16;

        _maps = { &jet, &classic, &grayscale, &inv_grayscale, &biomes, &cold, &warm, &quantized, &pattern, &hue };

        auto min_opt = std::make_shared< ptr_option< float > >(0.f, 16.f, 0.1f, 0.f, &_min, "Min range in meters");

        auto max_opt = std::make_shared< ptr_option< float > >(0.f, 16.f, 0.1f, 6.f, &_max, "Max range in meters");

        auto max_dist_opt = std::make_shared< max_distance_option >(max_opt, min_opt);

        auto min_dist_opt = std::make_shared< min_distance_option >(min_opt, max_opt);

        register_option(RS2_OPTION_MAX_DISTANCE, max_dist_opt);

        register_option(RS2_OPTION_MIN_DISTANCE, min_dist_opt);

        auto hist_opt = std::make_shared< ptr_option< bool > >(false,
            true,
            true,
            true,
            &_equalize,
            "Perform histogram equalization");
        register_option(RS2_OPTION_HISTOGRAM_EQUALIZATION_ENABLED, hist_opt);

        max_dist_opt->add_observer([weak_hist_opt = std::weak_ptr<ptr_option< bool >>(hist_opt)](float val)
        {
            auto strong = weak_hist_opt.lock();
            if (strong)
                strong->set(false);
        });

        min_dist_opt->add_observer([weak_hist_opt = std::weak_ptr<ptr_option< bool >>(hist_opt)](float val)
        {
            auto strong = weak_hist_opt.lock();
            if (strong)
                strong->set(false);
        });

        auto color_map = std::make_shared<ptr_option<int>>(0, (int)_maps.size() - 1, 1, 0, &_map_index, "Color map");
        color_map->set_description(0.f, "Jet");
        color_map->set_description(1.f, "Classic");
        color_map->set_description(2.f, "White to Black");
        color_map->set_description(3.f, "Black to White");
        color_map->set_description(4.f, "Bio");
        color_map->set_description(5.f, "Cold");
        color_map->set_description(6.f, "Warm");
        color_map->set_description(7.f, "Quantized");
        color_map->set_description(8.f, "Pattern");
        color_map->set_description(9.f, "Hue");
        register_option(RS2_OPTION_COLOR_SCHEME, color_map);

        auto preset_opt = std::make_shared<ptr_option<int>>(0, 3, 1, 0, &_preset, "Preset depth colorization");
        preset_opt->set_description(0.f, "Dynamic");
        preset_opt->set_description(1.f, "Fixed");
        preset_opt->set_description(2.f, "Near");
        preset_opt->set_description(3.f, "Far");

        preset_opt->on_set([this](float val)
        {
            if (fabs(val - 0.f) < 1e-6)
            {
                // Dynamic
                _equalize = true;
                _map_index = 0;
            }
            if (fabs(val - 1.f) < 1e-6)
            {
                // Fixed
                _equalize = false;
                _map_index = 0;
                _min = 0.f;
                _max = 6.f;
            }
            if (fabs(val - 2.f) < 1e-6)
            {
                // Near
                _equalize = false;
                _map_index = 1;
                _min = 0.3f;
                _max = 1.5f;
            }
            if (fabs(val - 3.f) < 1e-6)
            {
                // Far
                _equalize = false;
                _map_index = 0;
                _min = 1.f;
                _max = 16.f;
            }
        });
        register_option(RS2_OPTION_VISUAL_PRESET, preset_opt);
    }

    bool colorizer::should_process(const rs2::frame& frame)
    {
        if (!frame || frame.is<rs2::frameset>())
            return false;

        if (frame.get_profile().stream_type() != RS2_STREAM_DEPTH)
            return false;

        return true;
    }

    rs2::frame colorizer::process_frame(const rs2::frame_source& source, const rs2::frame& f)
    {
        if (f.as<rs2::depth_frame>())
            _depth_units = ((depth_frame*)f.get())->get_units();
        if (f.get_profile().get() != _source_stream_profile.get())
        {
            _source_stream_profile = f.get_profile();
            _target_stream_profile = f.get_profile().clone(RS2_STREAM_DEPTH, f.get_profile().stream_index(), RS2_FORMAT_RGB8);

            auto info = disparity_info::update_info_from_frame(f);
            _d2d_convert_factor = info.d2d_convert_factor;
        }

        auto make_equalized_histogram = [this](const rs2::video_frame& depth, rs2::video_frame rgb)
        {
            auto depth_format = depth.get_profile().format();
            const auto w = depth.get_width(), h = depth.get_height();
            auto rgb_data = reinterpret_cast<uint8_t*>(const_cast<void *>(rgb.get_data()));
            auto coloring_function = [&, this](float data) {
                auto hist_data = _hist_data[(int)data];
                auto pixels = (float)_hist_data[MAX_DEPTH - 1];
                return (hist_data / pixels);
            };

            if (depth_format == RS2_FORMAT_DISPARITY32)
            {
                auto depth_data = reinterpret_cast<const float*>(depth.get_data());
                update_histogram(_hist_data, depth_data, w, h);
                make_rgb_data<float>(depth_data, rgb_data, w, h, coloring_function);
            }
            else if (depth_format == RS2_FORMAT_Z16)
            {
                auto depth_data = reinterpret_cast<const uint16_t*>(depth.get_data());
                update_histogram(_hist_data, depth_data, w, h);
                make_rgb_data<uint16_t>(depth_data, rgb_data, w, h, coloring_function);
            }
        };

        auto make_value_cropped_frame = [this](const rs2::video_frame& depth, rs2::video_frame rgb)
        {
            auto depth_format = depth.get_profile().format();
            const auto w = depth.get_width(), h = depth.get_height();
            auto rgb_data = reinterpret_cast<uint8_t*>(const_cast<void *>(rgb.get_data()));

            if (depth_format == RS2_FORMAT_DISPARITY32)
            {
                auto depth_data = reinterpret_cast<const float*>(depth.get_data());
                // convert from depth min max to disparity min max
                // note: max min value is inverted in disparity domain
                auto __min = _min;
                if (__min < 1e-6f) { __min = 1e-6f; } // Min value set to prevent zero division. only when _min is zero.
                auto max = (_d2d_convert_factor / (__min)) * _depth_units + .5f;
                auto min = (_d2d_convert_factor / (_max)) * _depth_units + .5f;
                auto coloring_function = [&, this](float data) {
                    return (data - min) / (max - min);
                };
                make_rgb_data<float>(depth_data, rgb_data, w, h, coloring_function);
            }
            else if (depth_format == RS2_FORMAT_Z16)
            {
                auto depth_data = reinterpret_cast<const uint16_t*>(depth.get_data());
                auto min = _min;
                auto max = _max;
                auto coloring_function = [&, this](float data) {
                    if (min >= max) return 0.f;
                    return (data * _depth_units - min) / (max - min);
                };
                make_rgb_data<uint16_t>(depth_data, rgb_data, w, h, coloring_function);
            }
        };

        rs2::frame ret;

        auto vf = f.as<rs2::video_frame>();
        ret = source.allocate_video_frame(_target_stream_profile, f, 3, vf.get_width(), vf.get_height(), vf.get_width() * 3, RS2_EXTENSION_VIDEO_FRAME);

        if (_equalize)
            make_equalized_histogram(f, ret);
        else
            make_value_cropped_frame(f, ret);

        return ret;
    }
}
<commit_msg>move initializaton out to remove warning<commit_after>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.

#include "../include/librealsense2/hpp/rs_sensor.hpp"
#include "../include/librealsense2/hpp/rs_processing.hpp"

#include "proc/synthetic-stream.h"
#include "context.h"
#include "environment.h"
#include "option.h"
#include "colorizer.h"
#include "disparity-transform.h"

namespace librealsense
{
    static color_map hue{ {
        { 255, 0, 0 },
        { 255, 255, 0 },
        { 0, 255, 0 },
        { 0, 255, 255 },
        { 0, 0, 255 },
        { 255, 0, 255 },
        { 255, 0, 0 },
        } };

    static color_map jet{ {
        { 0, 0, 255 },
        { 0, 255, 255 },
        { 255, 255, 0 },
        { 255, 0, 0 },
        { 50, 0, 0 },
        } };

    static color_map classic{ {
        { 30, 77, 203 },
        { 25, 60, 192 },
        { 45, 117, 220 },
        { 204, 108, 191 },
        { 196, 57, 178 },
        { 198, 33, 24 },
        } };

    static color_map grayscale{ {
        { 255, 255, 255 },
        { 0, 0, 0 },
        } };

    static color_map inv_grayscale{ {
        { 0, 0, 0 },
        { 255, 255, 255 },
        } };

    static color_map biomes{ {
        { 0, 0, 204 },
        { 204, 230, 255 },
        { 255, 255, 153 },
        { 170, 255, 128 },
        { 0, 153, 0 },
        { 230, 242, 255 },
        } };

    static color_map cold{ {
        { 230, 247, 255 },
        { 0, 92, 230 },
        { 0, 179, 179 },
        { 0, 51, 153 },
        { 0, 5, 15 }
        } };

    static color_map warm{ {
        { 255, 255, 230 },
        { 255, 204, 0 },
        { 255, 136, 77 },
        { 255, 51, 0 },
        { 128, 0, 0 },
        { 10, 0, 0 }
        } };

    static color_map quantized{ {
        { 255, 255, 255 },
        { 0, 0, 0 },
        }, 6 };

    static color_map pattern{ {
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        { 255, 255, 255 },
        { 0, 0, 0 },
        } };

    colorizer::colorizer()
        : colorizer("Depth Visualization")
    {}

    colorizer::colorizer(const char* name)
        : stream_filter_processing_block(name),
         _min(0.f), _max(6.f), _equalize(true),
         _target_stream_profile(), _histogram()
    {
        _histogram = std::vector<int>(MAX_DEPTH, 0);
        _hist_data = _histogram.data();
        _stream_filter.stream = RS2_STREAM_DEPTH;
        _stream_filter.format = RS2_FORMAT_Z16;

        _maps = { &jet, &classic, &grayscale, &inv_grayscale, &biomes, &cold, &warm, &quantized, &pattern, &hue };

        auto min_opt = std::make_shared< ptr_option< float > >(0.f, 16.f, 0.1f, 0.f, &_min, "Min range in meters");

        auto max_opt = std::make_shared< ptr_option< float > >(0.f, 16.f, 0.1f, 6.f, &_max, "Max range in meters");

        auto max_dist_opt = std::make_shared< max_distance_option >(max_opt, min_opt);

        auto min_dist_opt = std::make_shared< min_distance_option >(min_opt, max_opt);

        register_option(RS2_OPTION_MAX_DISTANCE, max_dist_opt);

        register_option(RS2_OPTION_MIN_DISTANCE, min_dist_opt);

        auto hist_opt = std::make_shared< ptr_option< bool > >(false,
            true,
            true,
            true,
            &_equalize,
            "Perform histogram equalization");
        register_option(RS2_OPTION_HISTOGRAM_EQUALIZATION_ENABLED, hist_opt);

        auto weak_hist_opt = std::weak_ptr<ptr_option< bool >>(hist_opt);

        max_dist_opt->add_observer([weak_hist_opt](float val)
        {
            auto strong_hist_opt = weak_hist_opt.lock();
            if (strong_hist_opt)
                strong_hist_opt->set(false);
        });

        min_dist_opt->add_observer([weak_hist_opt](float val)
        {
            auto strong_hist_opt = weak_hist_opt.lock();
            if (strong_hist_opt)
                strong_hist_opt->set(false);
        });

        auto color_map = std::make_shared<ptr_option<int>>(0, (int)_maps.size() - 1, 1, 0, &_map_index, "Color map");
        color_map->set_description(0.f, "Jet");
        color_map->set_description(1.f, "Classic");
        color_map->set_description(2.f, "White to Black");
        color_map->set_description(3.f, "Black to White");
        color_map->set_description(4.f, "Bio");
        color_map->set_description(5.f, "Cold");
        color_map->set_description(6.f, "Warm");
        color_map->set_description(7.f, "Quantized");
        color_map->set_description(8.f, "Pattern");
        color_map->set_description(9.f, "Hue");
        register_option(RS2_OPTION_COLOR_SCHEME, color_map);

        auto preset_opt = std::make_shared<ptr_option<int>>(0, 3, 1, 0, &_preset, "Preset depth colorization");
        preset_opt->set_description(0.f, "Dynamic");
        preset_opt->set_description(1.f, "Fixed");
        preset_opt->set_description(2.f, "Near");
        preset_opt->set_description(3.f, "Far");

        preset_opt->on_set([this](float val)
        {
            if (fabs(val - 0.f) < 1e-6)
            {
                // Dynamic
                _equalize = true;
                _map_index = 0;
            }
            if (fabs(val - 1.f) < 1e-6)
            {
                // Fixed
                _equalize = false;
                _map_index = 0;
                _min = 0.f;
                _max = 6.f;
            }
            if (fabs(val - 2.f) < 1e-6)
            {
                // Near
                _equalize = false;
                _map_index = 1;
                _min = 0.3f;
                _max = 1.5f;
            }
            if (fabs(val - 3.f) < 1e-6)
            {
                // Far
                _equalize = false;
                _map_index = 0;
                _min = 1.f;
                _max = 16.f;
            }
        });
        register_option(RS2_OPTION_VISUAL_PRESET, preset_opt);
    }

    bool colorizer::should_process(const rs2::frame& frame)
    {
        if (!frame || frame.is<rs2::frameset>())
            return false;

        if (frame.get_profile().stream_type() != RS2_STREAM_DEPTH)
            return false;

        return true;
    }

    rs2::frame colorizer::process_frame(const rs2::frame_source& source, const rs2::frame& f)
    {
        if (f.as<rs2::depth_frame>())
            _depth_units = ((depth_frame*)f.get())->get_units();
        if (f.get_profile().get() != _source_stream_profile.get())
        {
            _source_stream_profile = f.get_profile();
            _target_stream_profile = f.get_profile().clone(RS2_STREAM_DEPTH, f.get_profile().stream_index(), RS2_FORMAT_RGB8);

            auto info = disparity_info::update_info_from_frame(f);
            _d2d_convert_factor = info.d2d_convert_factor;
        }

        auto make_equalized_histogram = [this](const rs2::video_frame& depth, rs2::video_frame rgb)
        {
            auto depth_format = depth.get_profile().format();
            const auto w = depth.get_width(), h = depth.get_height();
            auto rgb_data = reinterpret_cast<uint8_t*>(const_cast<void *>(rgb.get_data()));
            auto coloring_function = [&, this](float data) {
                auto hist_data = _hist_data[(int)data];
                auto pixels = (float)_hist_data[MAX_DEPTH - 1];
                return (hist_data / pixels);
            };

            if (depth_format == RS2_FORMAT_DISPARITY32)
            {
                auto depth_data = reinterpret_cast<const float*>(depth.get_data());
                update_histogram(_hist_data, depth_data, w, h);
                make_rgb_data<float>(depth_data, rgb_data, w, h, coloring_function);
            }
            else if (depth_format == RS2_FORMAT_Z16)
            {
                auto depth_data = reinterpret_cast<const uint16_t*>(depth.get_data());
                update_histogram(_hist_data, depth_data, w, h);
                make_rgb_data<uint16_t>(depth_data, rgb_data, w, h, coloring_function);
            }
        };

        auto make_value_cropped_frame = [this](const rs2::video_frame& depth, rs2::video_frame rgb)
        {
            auto depth_format = depth.get_profile().format();
            const auto w = depth.get_width(), h = depth.get_height();
            auto rgb_data = reinterpret_cast<uint8_t*>(const_cast<void *>(rgb.get_data()));

            if (depth_format == RS2_FORMAT_DISPARITY32)
            {
                auto depth_data = reinterpret_cast<const float*>(depth.get_data());
                // convert from depth min max to disparity min max
                // note: max min value is inverted in disparity domain
                auto __min = _min;
                if (__min < 1e-6f) { __min = 1e-6f; } // Min value set to prevent zero division. only when _min is zero.
                auto max = (_d2d_convert_factor / (__min)) * _depth_units + .5f;
                auto min = (_d2d_convert_factor / (_max)) * _depth_units + .5f;
                auto coloring_function = [&, this](float data) {
                    return (data - min) / (max - min);
                };
                make_rgb_data<float>(depth_data, rgb_data, w, h, coloring_function);
            }
            else if (depth_format == RS2_FORMAT_Z16)
            {
                auto depth_data = reinterpret_cast<const uint16_t*>(depth.get_data());
                auto min = _min;
                auto max = _max;
                auto coloring_function = [&, this](float data) {
                    if (min >= max) return 0.f;
                    return (data * _depth_units - min) / (max - min);
                };
                make_rgb_data<uint16_t>(depth_data, rgb_data, w, h, coloring_function);
            }
        };

        rs2::frame ret;

        auto vf = f.as<rs2::video_frame>();
        ret = source.allocate_video_frame(_target_stream_profile, f, 3, vf.get_width(), vf.get_height(), vf.get_width() * 3, RS2_EXTENSION_VIDEO_FRAME);

        if (_equalize)
            make_equalized_histogram(f, ret);
        else
            make_value_cropped_frame(f, ret);

        return ret;
    }
}
<|endoftext|>


<commit_before>//===-- X86TargetMachine.cpp - Define TargetMachine for the X86 -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the X86 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//

#include "X86MCAsmInfo.h"
#include "X86TargetMachine.h"
#include "X86.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
using namespace llvm;

static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
  Triple TheTriple(TT);
  switch (TheTriple.getOS()) {
  case Triple::Darwin:
    return new X86MCAsmInfoDarwin(TheTriple);
  case Triple::MinGW32:
  case Triple::MinGW64:
  case Triple::Cygwin:
  case Triple::Win32:
    return new X86MCAsmInfoCOFF(TheTriple);
  default:
    return new X86ELFMCAsmInfo(TheTriple);
  }
}

extern "C" void LLVMInitializeX86Target() {
  // Register the target.
  RegisterTargetMachine<X86_32TargetMachine> X(TheX86_32Target);
  RegisterTargetMachine<X86_64TargetMachine> Y(TheX86_64Target);

  // Register the target asm info.
  RegisterAsmInfoFn A(TheX86_32Target, createMCAsmInfo);
  RegisterAsmInfoFn B(TheX86_64Target, createMCAsmInfo);

  // Register the code emitter.
  TargetRegistry::RegisterCodeEmitter(TheX86_32Target,
                                      createX86_32MCCodeEmitter);
  TargetRegistry::RegisterCodeEmitter(TheX86_64Target,
                                      createX86_64MCCodeEmitter);

  // Register the asm backend.
  TargetRegistry::RegisterAsmBackend(TheX86_32Target,
                                     createX86_32AsmBackend);
  TargetRegistry::RegisterAsmBackend(TheX86_64Target,
                                     createX86_64AsmBackend);
}

X86_32TargetMachine::X86_32TargetMachine(const Target &T, const std::string &TT,
                                         const std::string &FS)
  : X86TargetMachine(T, TT, FS, false) {
}

X86_64TargetMachine::X86_64TargetMachine(const Target &T, const std::string &TT,
                                         const std::string &FS)
  : X86TargetMachine(T, TT, FS, true) {
}

/// X86TargetMachine ctor - Create an X86 target.
///
X86TargetMachine::X86TargetMachine(const Target &T, const std::string &TT,
                                   const std::string &FS, bool is64Bit)
  : LLVMTargetMachine(T, TT),
    Subtarget(TT, FS, is64Bit),
    DataLayout(Subtarget.getDataLayout()),
    FrameInfo(TargetFrameInfo::StackGrowsDown,
              Subtarget.getStackAlignment(),
              (Subtarget.isTargetWin64() ? -40 :
               (Subtarget.is64Bit() ? -8 : -4))),
    InstrInfo(*this), JITInfo(*this), TLInfo(*this), ELFWriterInfo(*this) {
  DefRelocModel = getRelocationModel();

  // If no relocation model was picked, default as appropriate for the target.
  if (getRelocationModel() == Reloc::Default) {
    if (!Subtarget.isTargetDarwin())
      setRelocationModel(Reloc::Static);
    else if (Subtarget.is64Bit())
      setRelocationModel(Reloc::PIC_);
    else
      setRelocationModel(Reloc::DynamicNoPIC);
  }

  assert(getRelocationModel() != Reloc::Default &&
         "Relocation mode not picked");

  // ELF and X86-64 don't have a distinct DynamicNoPIC model.  DynamicNoPIC
  // is defined as a model for code which may be used in static or dynamic
  // executables but not necessarily a shared library. On X86-32 we just
  // compile in -static mode, in x86-64 we use PIC.
  if (getRelocationModel() == Reloc::DynamicNoPIC) {
    if (is64Bit)
      setRelocationModel(Reloc::PIC_);
    else if (!Subtarget.isTargetDarwin())
      setRelocationModel(Reloc::Static);
  }

  // If we are on Darwin, disallow static relocation model in X86-64 mode, since
  // the Mach-O file format doesn't support it.
  if (getRelocationModel() == Reloc::Static &&
      Subtarget.isTargetDarwin() &&
      is64Bit)
    setRelocationModel(Reloc::PIC_);

  // Determine the PICStyle based on the target selected.
  if (getRelocationModel() == Reloc::Static) {
    // Unless we're in PIC or DynamicNoPIC mode, set the PIC style to None.
    Subtarget.setPICStyle(PICStyles::None);
  } else if (Subtarget.isTargetCygMing()) {
    Subtarget.setPICStyle(PICStyles::None);
  } else if (Subtarget.isTargetDarwin()) {
    if (Subtarget.is64Bit())
      Subtarget.setPICStyle(PICStyles::RIPRel);
    else if (getRelocationModel() == Reloc::PIC_)
      Subtarget.setPICStyle(PICStyles::StubPIC);
    else {
      assert(getRelocationModel() == Reloc::DynamicNoPIC);
      Subtarget.setPICStyle(PICStyles::StubDynamicNoPIC);
    }
  } else if (Subtarget.isTargetELF()) {
    if (Subtarget.is64Bit())
      Subtarget.setPICStyle(PICStyles::RIPRel);
    else
      Subtarget.setPICStyle(PICStyles::GOT);
  }

  // Finally, if we have "none" as our PIC style, force to static mode.
  if (Subtarget.getPICStyle() == PICStyles::None)
    setRelocationModel(Reloc::Static);
}

//===----------------------------------------------------------------------===//
// Pass Pipeline Configuration
//===----------------------------------------------------------------------===//

bool X86TargetMachine::addInstSelector(PassManagerBase &PM,
                                       CodeGenOpt::Level OptLevel) {
  // Install an instruction selector.
  PM.add(createX86ISelDag(*this, OptLevel));

  // Install a pass to insert x87 FP_REG_KILL instructions, as needed.
  PM.add(createX87FPRegKillInserterPass());

  return false;
}

bool X86TargetMachine::addPreRegAlloc(PassManagerBase &PM,
                                      CodeGenOpt::Level OptLevel) {
  return false;  // -print-machineinstr shouldn't print after this.
}

bool X86TargetMachine::addPostRegAlloc(PassManagerBase &PM,
                                       CodeGenOpt::Level OptLevel) {
  PM.add(createX86FloatingPointStackifierPass());
  return true;  // -print-machineinstr should print after this.
}

bool X86TargetMachine::addPreEmitPass(PassManagerBase &PM,
                                      CodeGenOpt::Level OptLevel) {
  if (OptLevel != CodeGenOpt::None && Subtarget.hasSSE2()) {
    PM.add(createSSEDomainFixPass());
    return true;
  }
  return false;
}

bool X86TargetMachine::addCodeEmitter(PassManagerBase &PM,
                                      CodeGenOpt::Level OptLevel,
                                      JITCodeEmitter &JCE) {
  // FIXME: Move this to TargetJITInfo!
  // On Darwin, do not override 64-bit setting made in X86TargetMachine().
  if (DefRelocModel == Reloc::Default &&
      (!Subtarget.isTargetDarwin() || !Subtarget.is64Bit())) {
    setRelocationModel(Reloc::Static);
    Subtarget.setPICStyle(PICStyles::None);
  }

  PM.add(createX86JITCodeEmitterPass(*this, JCE));

  return false;
}

void X86TargetMachine::setCodeModelForStatic() {

    if (getCodeModel() != CodeModel::Default) return;

    // For static codegen, if we're not already set, use Small codegen.
    setCodeModel(CodeModel::Small);
}

void X86TargetMachine::setCodeModelForJIT() {

  if (getCodeModel() != CodeModel::Default) return;

  // 64-bit JIT places everything in the same buffer except external functions.
  if (Subtarget.is64Bit())
    setCodeModel(CodeModel::Large);
  else
    setCodeModel(CodeModel::Small);
}
<commit_msg>Revert "Enable -sse-domain-fix by default. What could possibly go wrong?"<commit_after>//===-- X86TargetMachine.cpp - Define TargetMachine for the X86 -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the X86 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//

#include "X86MCAsmInfo.h"
#include "X86TargetMachine.h"
#include "X86.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
using namespace llvm;

static cl::opt<bool>
SSEDomainFix("sse-domain-fix",
               cl::desc("Enable fixing of SSE execution domain"),
               cl::init(false), cl::Hidden);

static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
  Triple TheTriple(TT);
  switch (TheTriple.getOS()) {
  case Triple::Darwin:
    return new X86MCAsmInfoDarwin(TheTriple);
  case Triple::MinGW32:
  case Triple::MinGW64:
  case Triple::Cygwin:
  case Triple::Win32:
    return new X86MCAsmInfoCOFF(TheTriple);
  default:
    return new X86ELFMCAsmInfo(TheTriple);
  }
}

extern "C" void LLVMInitializeX86Target() {
  // Register the target.
  RegisterTargetMachine<X86_32TargetMachine> X(TheX86_32Target);
  RegisterTargetMachine<X86_64TargetMachine> Y(TheX86_64Target);

  // Register the target asm info.
  RegisterAsmInfoFn A(TheX86_32Target, createMCAsmInfo);
  RegisterAsmInfoFn B(TheX86_64Target, createMCAsmInfo);

  // Register the code emitter.
  TargetRegistry::RegisterCodeEmitter(TheX86_32Target,
                                      createX86_32MCCodeEmitter);
  TargetRegistry::RegisterCodeEmitter(TheX86_64Target,
                                      createX86_64MCCodeEmitter);

  // Register the asm backend.
  TargetRegistry::RegisterAsmBackend(TheX86_32Target,
                                     createX86_32AsmBackend);
  TargetRegistry::RegisterAsmBackend(TheX86_64Target,
                                     createX86_64AsmBackend);
}

X86_32TargetMachine::X86_32TargetMachine(const Target &T, const std::string &TT,
                                         const std::string &FS)
  : X86TargetMachine(T, TT, FS, false) {
}

X86_64TargetMachine::X86_64TargetMachine(const Target &T, const std::string &TT,
                                         const std::string &FS)
  : X86TargetMachine(T, TT, FS, true) {
}

/// X86TargetMachine ctor - Create an X86 target.
///
X86TargetMachine::X86TargetMachine(const Target &T, const std::string &TT,
                                   const std::string &FS, bool is64Bit)
  : LLVMTargetMachine(T, TT),
    Subtarget(TT, FS, is64Bit),
    DataLayout(Subtarget.getDataLayout()),
    FrameInfo(TargetFrameInfo::StackGrowsDown,
              Subtarget.getStackAlignment(),
              (Subtarget.isTargetWin64() ? -40 :
               (Subtarget.is64Bit() ? -8 : -4))),
    InstrInfo(*this), JITInfo(*this), TLInfo(*this), ELFWriterInfo(*this) {
  DefRelocModel = getRelocationModel();

  // If no relocation model was picked, default as appropriate for the target.
  if (getRelocationModel() == Reloc::Default) {
    if (!Subtarget.isTargetDarwin())
      setRelocationModel(Reloc::Static);
    else if (Subtarget.is64Bit())
      setRelocationModel(Reloc::PIC_);
    else
      setRelocationModel(Reloc::DynamicNoPIC);
  }

  assert(getRelocationModel() != Reloc::Default &&
         "Relocation mode not picked");

  // ELF and X86-64 don't have a distinct DynamicNoPIC model.  DynamicNoPIC
  // is defined as a model for code which may be used in static or dynamic
  // executables but not necessarily a shared library. On X86-32 we just
  // compile in -static mode, in x86-64 we use PIC.
  if (getRelocationModel() == Reloc::DynamicNoPIC) {
    if (is64Bit)
      setRelocationModel(Reloc::PIC_);
    else if (!Subtarget.isTargetDarwin())
      setRelocationModel(Reloc::Static);
  }

  // If we are on Darwin, disallow static relocation model in X86-64 mode, since
  // the Mach-O file format doesn't support it.
  if (getRelocationModel() == Reloc::Static &&
      Subtarget.isTargetDarwin() &&
      is64Bit)
    setRelocationModel(Reloc::PIC_);

  // Determine the PICStyle based on the target selected.
  if (getRelocationModel() == Reloc::Static) {
    // Unless we're in PIC or DynamicNoPIC mode, set the PIC style to None.
    Subtarget.setPICStyle(PICStyles::None);
  } else if (Subtarget.isTargetCygMing()) {
    Subtarget.setPICStyle(PICStyles::None);
  } else if (Subtarget.isTargetDarwin()) {
    if (Subtarget.is64Bit())
      Subtarget.setPICStyle(PICStyles::RIPRel);
    else if (getRelocationModel() == Reloc::PIC_)
      Subtarget.setPICStyle(PICStyles::StubPIC);
    else {
      assert(getRelocationModel() == Reloc::DynamicNoPIC);
      Subtarget.setPICStyle(PICStyles::StubDynamicNoPIC);
    }
  } else if (Subtarget.isTargetELF()) {
    if (Subtarget.is64Bit())
      Subtarget.setPICStyle(PICStyles::RIPRel);
    else
      Subtarget.setPICStyle(PICStyles::GOT);
  }

  // Finally, if we have "none" as our PIC style, force to static mode.
  if (Subtarget.getPICStyle() == PICStyles::None)
    setRelocationModel(Reloc::Static);
}

//===----------------------------------------------------------------------===//
// Pass Pipeline Configuration
//===----------------------------------------------------------------------===//

bool X86TargetMachine::addInstSelector(PassManagerBase &PM,
                                       CodeGenOpt::Level OptLevel) {
  // Install an instruction selector.
  PM.add(createX86ISelDag(*this, OptLevel));

  // Install a pass to insert x87 FP_REG_KILL instructions, as needed.
  PM.add(createX87FPRegKillInserterPass());

  return false;
}

bool X86TargetMachine::addPreRegAlloc(PassManagerBase &PM,
                                      CodeGenOpt::Level OptLevel) {
  return false;  // -print-machineinstr shouldn't print after this.
}

bool X86TargetMachine::addPostRegAlloc(PassManagerBase &PM,
                                       CodeGenOpt::Level OptLevel) {
  PM.add(createX86FloatingPointStackifierPass());
  return true;  // -print-machineinstr should print after this.
}

bool X86TargetMachine::addPreEmitPass(PassManagerBase &PM,
                                      CodeGenOpt::Level OptLevel) {
  if (SSEDomainFix && OptLevel != CodeGenOpt::None && Subtarget.hasSSE2()) {
    PM.add(createSSEDomainFixPass());
    return true;
  }
  return false;
}

bool X86TargetMachine::addCodeEmitter(PassManagerBase &PM,
                                      CodeGenOpt::Level OptLevel,
                                      JITCodeEmitter &JCE) {
  // FIXME: Move this to TargetJITInfo!
  // On Darwin, do not override 64-bit setting made in X86TargetMachine().
  if (DefRelocModel == Reloc::Default &&
      (!Subtarget.isTargetDarwin() || !Subtarget.is64Bit())) {
    setRelocationModel(Reloc::Static);
    Subtarget.setPICStyle(PICStyles::None);
  }

  PM.add(createX86JITCodeEmitterPass(*this, JCE));

  return false;
}

void X86TargetMachine::setCodeModelForStatic() {

    if (getCodeModel() != CodeModel::Default) return;

    // For static codegen, if we're not already set, use Small codegen.
    setCodeModel(CodeModel::Small);
}

void X86TargetMachine::setCodeModelForJIT() {

  if (getCodeModel() != CodeModel::Default) return;

  // 64-bit JIT places everything in the same buffer except external functions.
  if (Subtarget.is64Bit())
    setCodeModel(CodeModel::Large);
  else
    setCodeModel(CodeModel::Small);
}
<|endoftext|>


<commit_before>//===-- X86TargetMachine.cpp - Define TargetMachine for the X86 -----------===//
//
// This file defines the X86 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//

#include "X86TargetMachine.h"
#include "X86.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/PassManager.h"
#include "Support/CommandLine.h"
#include "Support/Statistic.h"
#include <iostream>

namespace {
  cl::opt<bool> NoLocalRA("no-local-ra",
                          cl::desc("Use Simple RA instead of Local RegAlloc"));
  cl::opt<bool> PrintCode("print-machineinstrs",
			  cl::desc("Print generated machine code"));
}

// allocateX86TargetMachine - Allocate and return a subclass of TargetMachine
// that implements the X86 backend.
//
TargetMachine *allocateX86TargetMachine(unsigned Configuration) {
  return new X86TargetMachine(Configuration);
}

/// X86TargetMachine ctor - Create an ILP32 architecture model
///
X86TargetMachine::X86TargetMachine(unsigned Config)
  : TargetMachine("X86",
		  (Config & TM::EndianMask) == TM::LittleEndian,
		  1, 4,
		  (Config & TM::PtrSizeMask) == TM::PtrSize64 ? 8 : 4,
		  (Config & TM::PtrSizeMask) == TM::PtrSize64 ? 8 : 4) {
}

/// addPassesToJITCompile - Add passes to the specified pass manager to
/// implement a fast dynamic compiler for this target.  Return true if this is
/// not supported for this target.
///
bool X86TargetMachine::addPassesToJITCompile(PassManager &PM) {
  // For the moment we have decided that malloc and free will be
  // taken care of by converting them to calls, using the existing
  // LLVM scalar transforms pass to do this.
  PM.add(createLowerAllocationsPass());

  PM.add(createSimpleX86InstructionSelector(*this));

  // TODO: optional optimizations go here

  // Print the instruction selected machine code...
  if (PrintCode)
    PM.add(createMachineFunctionPrinterPass());

  // Perform register allocation to convert to a concrete x86 representation
  if (NoLocalRA)
    PM.add(createSimpleRegisterAllocator(*this));
  else
    PM.add(createLocalRegisterAllocator(*this));

  // Print the instruction selected machine code...
  // PM.add(createMachineFunctionPrinterPass());

  // Print the register-allocated code
  if (PrintCode)
    PM.add(createX86CodePrinterPass(*this, std::cerr));

  return false; // success!
}

<commit_msg>Free machine code<commit_after>//===-- X86TargetMachine.cpp - Define TargetMachine for the X86 -----------===//
//
// This file defines the X86 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//

#include "X86TargetMachine.h"
#include "X86.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/PassManager.h"
#include "Support/CommandLine.h"
#include "Support/Statistic.h"
#include <iostream>

namespace {
  cl::opt<bool> NoLocalRA("no-local-ra",
                          cl::desc("Use Simple RA instead of Local RegAlloc"));
  cl::opt<bool> PrintCode("print-machineinstrs",
			  cl::desc("Print generated machine code"));
}

// allocateX86TargetMachine - Allocate and return a subclass of TargetMachine
// that implements the X86 backend.
//
TargetMachine *allocateX86TargetMachine(unsigned Configuration) {
  return new X86TargetMachine(Configuration);
}

/// X86TargetMachine ctor - Create an ILP32 architecture model
///
X86TargetMachine::X86TargetMachine(unsigned Config)
  : TargetMachine("X86",
		  (Config & TM::EndianMask) == TM::LittleEndian,
		  1, 4,
		  (Config & TM::PtrSizeMask) == TM::PtrSize64 ? 8 : 4,
		  (Config & TM::PtrSizeMask) == TM::PtrSize64 ? 8 : 4) {
}

/// addPassesToJITCompile - Add passes to the specified pass manager to
/// implement a fast dynamic compiler for this target.  Return true if this is
/// not supported for this target.
///
bool X86TargetMachine::addPassesToJITCompile(PassManager &PM) {
  // For the moment we have decided that malloc and free will be
  // taken care of by converting them to calls, using the existing
  // LLVM scalar transforms pass to do this.
  PM.add(createLowerAllocationsPass());

  PM.add(createSimpleX86InstructionSelector(*this));

  // TODO: optional optimizations go here

  // Print the instruction selected machine code...
  if (PrintCode)
    PM.add(createMachineFunctionPrinterPass());

  // Perform register allocation to convert to a concrete x86 representation
  if (NoLocalRA)
    PM.add(createSimpleRegisterAllocator(*this));
  else
    PM.add(createLocalRegisterAllocator(*this));

  if (PrintCode)  // Print the register-allocated code
    PM.add(createX86CodePrinterPass(*this, std::cerr));

  PM.add(createMachineCodeDestructionPass());

  return false; // success!
}

<|endoftext|>


<commit_before>//===--- CommonOptionsParser.cpp - common options for clang tools ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements the CommonOptionsParser class used to parse common
//  command-line options for clang tools, so that they can be run as separate
//  command-line applications with a consistent common interface for handling
//  compilation database and input files.
//
//  It provides a common subset of command-line options, common algorithm
//  for locating a compilation database and source files, and help messages
//  for the basic command-line interface.
//
//  It creates a CompilationDatabase and reads common command-line options.
//
//  This class uses the Clang Tooling infrastructure, see
//    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
//  for details on setting it up with LLVM source tree.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/CommandLine.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"

using namespace clang::tooling;
using namespace llvm;

const char *const CommonOptionsParser::HelpMessage =
    "\n"
    "-p <build-path> is used to read a compile command database.\n"
    "\n"
    "\tFor example, it can be a CMake build directory in which a file named\n"
    "\tcompile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON\n"
    "\tCMake option to get this output). When no build path is specified,\n"
    "\tclang-check will attempt to locate it automatically using all parent\n"
    "\tpaths of the first input file. See:\n"
    "\thttp://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an\n"
    "\texample of setting up Clang Tooling on a source tree.\n"
    "\n"
    "<source0> ... specify the paths of source files. These paths are\n"
    "\tlooked up in the compile command database. If the path of a file is\n"
    "\tabsolute, it needs to point into CMake's source tree. If the path is\n"
    "\trelative, the current working directory needs to be in the CMake\n"
    "\tsource tree and the file must be in a subdirectory of the current\n"
    "\tworking directory. \"./\" prefixes in the relative files will be\n"
    "\tautomatically removed, but the rest of a relative path must be a\n"
    "\tsuffix of a path in the compile command database.\n"
    "\n";

static cl::opt<std::string> BuildPath(
    "p", cl::desc("Build path"), cl::Optional);

static cl::list<std::string> SourcePaths(
    cl::Positional, cl::desc("<source0> [... <sourceN>]"), cl::OneOrMore);

CommonOptionsParser::CommonOptionsParser(int &argc, const char **argv) {
  Compilations.reset(FixedCompilationDatabase::loadFromCommandLine(argc,
                                                                   argv));
  cl::ParseCommandLineOptions(argc, argv);
  SourcePathList = SourcePaths;
  if (!Compilations) {
    std::string ErrorMessage;
    if (!BuildPath.empty()) {
      Compilations.reset(CompilationDatabase::autoDetectFromDirectory(
                              BuildPath, ErrorMessage));
    } else {
      Compilations.reset(CompilationDatabase::autoDetectFromSource(
                              SourcePaths[0], ErrorMessage));
    }
    if (!Compilations)
      llvm::report_fatal_error(ErrorMessage);
  }
}
<commit_msg>Only add common tool options when CommonOptionsParser is used.<commit_after>//===--- CommonOptionsParser.cpp - common options for clang tools ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements the CommonOptionsParser class used to parse common
//  command-line options for clang tools, so that they can be run as separate
//  command-line applications with a consistent common interface for handling
//  compilation database and input files.
//
//  It provides a common subset of command-line options, common algorithm
//  for locating a compilation database and source files, and help messages
//  for the basic command-line interface.
//
//  It creates a CompilationDatabase and reads common command-line options.
//
//  This class uses the Clang Tooling infrastructure, see
//    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
//  for details on setting it up with LLVM source tree.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/CommandLine.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"

using namespace clang::tooling;
using namespace llvm;

const char *const CommonOptionsParser::HelpMessage =
    "\n"
    "-p <build-path> is used to read a compile command database.\n"
    "\n"
    "\tFor example, it can be a CMake build directory in which a file named\n"
    "\tcompile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON\n"
    "\tCMake option to get this output). When no build path is specified,\n"
    "\tclang-check will attempt to locate it automatically using all parent\n"
    "\tpaths of the first input file. See:\n"
    "\thttp://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an\n"
    "\texample of setting up Clang Tooling on a source tree.\n"
    "\n"
    "<source0> ... specify the paths of source files. These paths are\n"
    "\tlooked up in the compile command database. If the path of a file is\n"
    "\tabsolute, it needs to point into CMake's source tree. If the path is\n"
    "\trelative, the current working directory needs to be in the CMake\n"
    "\tsource tree and the file must be in a subdirectory of the current\n"
    "\tworking directory. \"./\" prefixes in the relative files will be\n"
    "\tautomatically removed, but the rest of a relative path must be a\n"
    "\tsuffix of a path in the compile command database.\n"
    "\n";

CommonOptionsParser::CommonOptionsParser(int &argc, const char **argv) {
  static cl::opt<std::string> BuildPath(
      "p", cl::desc("Build path"), cl::Optional);

  static cl::list<std::string> SourcePaths(
      cl::Positional, cl::desc("<source0> [... <sourceN>]"), cl::OneOrMore);

  Compilations.reset(FixedCompilationDatabase::loadFromCommandLine(argc,
                                                                   argv));
  cl::ParseCommandLineOptions(argc, argv);
  SourcePathList = SourcePaths;
  if (!Compilations) {
    std::string ErrorMessage;
    if (!BuildPath.empty()) {
      Compilations.reset(CompilationDatabase::autoDetectFromDirectory(
                              BuildPath, ErrorMessage));
    } else {
      Compilations.reset(CompilationDatabase::autoDetectFromSource(
                              SourcePaths[0], ErrorMessage));
    }
    if (!Compilations)
      llvm::report_fatal_error(ErrorMessage);
  }
}
<|endoftext|>