<commit_before>#include <cstdlib>
#include <cstring>
#include <iostream>
#include <getopt.h>
#include <signal.h>
#include <map>

#include <sys/inotify.h>
#include <unistd.h>

#include "debug-func.hpp"
#include "main.hpp"
#include "wayfire/nonstd/safe-list.hpp"
#include <wayfire/config/file.hpp>

extern "C"
{
#define static
#include <wlr/render/gles2.h>
#undef static
#include <wlr/backend/multi.h>
#include <wlr/backend/wayland.h>
#include <wlr/util/log.h>
}

#include <wayland-server.h>

#include "core/core-impl.hpp"
#include "view/view-impl.hpp"
#include "wayfire/output.hpp"

wf_runtime_config runtime_config;

#define INOT_BUF_SIZE (1024 * sizeof(inotify_event))
static char buf[INOT_BUF_SIZE];

static std::string config_dir, config_file;

static void reload_config(int fd)
{
    wf::config::load_configuration_options_from_file(
        wf::get_core().config, config_file);
    inotify_add_watch(fd, config_dir.c_str(), IN_CREATE);
    inotify_add_watch(fd, config_file.c_str(), IN_MODIFY);
}

static int handle_config_updated(int fd, uint32_t mask, void *data)
{
    LOGD("Reloading configuration file");

    /* read, but don't use */
    read(fd, buf, INOT_BUF_SIZE);
    reload_config(fd);

    wf::get_core().emit_signal("reload-config", nullptr);

    return 0;
}

static void print_version()
{
    std::cout << WAYFIRE_VERSION << std::endl;
    exit(0);
}

static void print_help()
{
    std::cout << "Wayfire " << WAYFIRE_VERSION << std::endl;
    std::cout << "Usage: wayfire [OPTION]...\n" << std::endl;
    std::cout << " -c,  --config            specify config file to use" << std::endl;
    std::cout << " -h,  --help              print this help" << std::endl;
    std::cout << " -d,  --debug             enable debug logging" << std::endl;
    std::cout <<
        " -D,  --damage-debug      enable additional debug for damaged regions" <<
        std::endl;
    std::cout << " -R,  --damage-rerender   rerender damaged regions" << std::endl;
    std::cout << " -v,  --version           print version and exit" << std::endl;
    exit(0);
}

std::map<EGLint, EGLint> default_attribs = {
    {EGL_RED_SIZE, 1},
    {EGL_GREEN_SIZE, 1},
    {EGL_BLUE_SIZE, 1},
    {EGL_DEPTH_SIZE, 1},
};

std::map<wlr_renderer*, wlr_egl*> egl_for_renderer;

/* Merge the default config and the config we need */
static std::vector<EGLint> generate_config_attribs(EGLint *renderer_attribs)
{
    std::vector<EGLint> attribs;

    /* See what we have in the default config */
    for (auto i = renderer_attribs; i != NULL && *i != EGL_NONE; i++)
    {
        /* We will override this value later */
        if (default_attribs.count(*i))
        {
            ++i;
            continue;
        }

        attribs.push_back(*i);
        i++;
        attribs.push_back(*i);
    }

    /* Then pack all values we want */
    for (auto & p : default_attribs)
    {
        attribs.push_back(p.first);
        attribs.push_back(p.second);
    }

    attribs.push_back(EGL_NONE);

    return attribs;
}

wlr_renderer *add_egl_depth_renderer(wlr_egl *egl, EGLenum platform,
    void *remote, EGLint *_r_attr, EGLint visual)
{
    bool r;
    auto attribs = generate_config_attribs(_r_attr);
    r = wlr_egl_init(egl, platform, remote, attribs.data(), visual);

    if (!r)
    {
        LOGE("Failed to initialize EGL");

        return NULL;
    }

    auto renderer = wlr_gles2_renderer_create(egl);
    if (!renderer)
    {
        LOGE("Failed to create GLES2 renderer");
        wlr_egl_finish(egl);

        return NULL;
    }

    egl_for_renderer[renderer] = egl;

    return renderer;
}

namespace wf
{
namespace _safe_list_detail
{
wl_event_loop *event_loop;
void idle_cleanup_func(void *data)
{
    auto priv = reinterpret_cast<std::function<void()>*>(data);
    (*priv)();
}
}
}

static bool drop_permissions(void)
{
    if ((getuid() != geteuid()) || (getgid() != getegid()))
    {
        // Set the gid and uid in the correct order.
        if ((setgid(getgid()) != 0) || (setuid(getuid()) != 0))
        {
            LOGE("Unable to drop root, refusing to start");

            return false;
        }
    }

    if ((setgid(0) != -1) || (setuid(0) != -1))
    {
        LOGE("Unable to drop root (we shouldn't be able to "
             "restore it after setuid), refusing to start");

        return false;
    }

    return true;
}

static wf::log::color_mode_t detect_color_mode()
{
    return isatty(STDOUT_FILENO) ?
           wf::log::LOG_COLOR_MODE_ON : wf::log::LOG_COLOR_MODE_OFF;
}

static void wlr_log_handler(wlr_log_importance level,
    const char *fmt, va_list args)
{
    const int bufsize = 4 * 1024;
    char buffer[bufsize];
    vsnprintf(buffer, bufsize, fmt, args);

    wf::log::log_level_t wlevel;
    switch (level)
    {
      case WLR_ERROR:
        wlevel = wf::log::LOG_LEVEL_ERROR;
        break;

      case WLR_INFO:
        wlevel = wf::log::LOG_LEVEL_INFO;
        break;

      case WLR_DEBUG:
        wlevel = wf::log::LOG_LEVEL_DEBUG;
        break;

      default:
        return;
    }

    wf::log::log_plain(wlevel, buffer);
}

static void signal_handler(int signal)
{
    std::string error;
    switch (signal)
    {
      case SIGSEGV:
        error = "Segmentation fault";
        break;

      case SIGFPE:
        error = "Floating-point exception";
        break;

      case SIGABRT:
        error = "Fatal error(SIGABRT)";
        break;

      default:
        error = "Unknown";
    }

    LOGE("Fatal error: ", error);
    wf::print_trace(false);
    std::exit(0);
}

int main(int argc, char *argv[])
{
    config_dir = nonull(getenv("XDG_CONFIG_HOME"));
    if (!config_dir.compare("nil"))
    {
        config_dir = std::string(nonull(getenv("HOME"))) + "/.config";
    }

    config_file = config_dir + "/wayfire.ini";

    wf::log::log_level_t log_level = wf::log::LOG_LEVEL_INFO;
    struct option opts[] = {
        {
            "config", required_argument, NULL, 'c'
        },
        {"debug", no_argument, NULL, 'd'},
        {"damage-debug", no_argument, NULL, 'D'},
        {"damage-rerender", no_argument, NULL, 'R'},
        {"help", no_argument, NULL, 'h'},
        {"version", no_argument, NULL, 'v'},
        {0, 0, NULL, 0}
    };

    int c, i;
    while ((c = getopt_long(argc, argv, "c:dDhRv", opts, &i)) != -1)
    {
        switch (c)
        {
          case 'c':
            config_file = optarg;
            break;

          case 'D':
            runtime_config.damage_debug = true;
            break;

          case 'R':
            runtime_config.no_damage_track = true;
            break;

          case 'h':
            print_help();
            break;

          case 'd':
            log_level = wf::log::LOG_LEVEL_DEBUG;
            break;

          case 'v':
            print_version();
            break;

          default:
            std::cerr << "Unrecognized command line argument " << optarg << "\n" <<
                std::endl;
        }
    }

    auto wlr_log_level =
        (log_level == wf::log::LOG_LEVEL_DEBUG ? WLR_DEBUG : WLR_ERROR);
    wlr_log_init(wlr_log_level, wlr_log_handler);
    wf::log::initialize_logging(std::cout, log_level, detect_color_mode());

#ifndef ASAN_ENABLED
    /* In case of crash, print the stacktrace for debugging.
     * However, if ASAN is enabled, we'll get better stacktrace from there. */
    signal(SIGSEGV, signal_handler);
    signal(SIGFPE, signal_handler);
    signal(SIGABRT, signal_handler);
#endif

    LOGI("Starting wayfire version ", WAYFIRE_VERSION);
    /* First create display and initialize safe-list's event loop, so that
     * wf objects (which depend on safe-list) can work */
    auto display = wl_display_create();
    wf::_safe_list_detail::event_loop = wl_display_get_event_loop(display);

    auto& core = wf::get_core_impl();

    /** TODO: move this to core_impl constructor */
    core.display  = display;
    core.ev_loop  = wl_display_get_event_loop(core.display);
    core.backend  = wlr_backend_autocreate(core.display, add_egl_depth_renderer);
    core.renderer = wlr_backend_get_renderer(core.backend);
    core.egl = egl_for_renderer[core.renderer];
    assert(core.egl);

    if (!drop_permissions())
    {
        wl_display_destroy_clients(core.display);
        wl_display_destroy(core.display);

        return EXIT_FAILURE;
    }

    std::vector<std::string> xmldirs;
    if (char *plugin_xml_path = getenv("WAYFIRE_PLUGIN_XML_PATH"))
    {
        std::stringstream ss(plugin_xml_path);
        std::string entry;
        while (std::getline(ss, entry, ':'))
        {
            xmldirs.push_back(entry);
        }
    }

    xmldirs.push_back(PLUGIN_XML_DIR);

    LOGI("using config file: ", config_file.c_str());
    core.config = wf::config::build_configuration(
        xmldirs, SYSCONFDIR "/wayfire/defaults.ini", config_file);

    int inotify_fd = inotify_init1(IN_CLOEXEC);
    reload_config(inotify_fd);

    wl_event_loop_add_fd(core.ev_loop, inotify_fd, WL_EVENT_READABLE,
        handle_config_updated, NULL);
    core.init();

    auto server_name = wl_display_add_socket_auto(core.display);
    if (!server_name)
    {
        LOGE("failed to create wayland, socket, exiting");

        return -1;
    }

    setenv("_WAYLAND_DISPLAY", server_name, 1);

    core.wayland_display = server_name;
    if (!wlr_backend_start(core.backend))
    {
        LOGE("failed to initialize backend, exiting");
        wlr_backend_destroy(core.backend);
        wl_display_destroy(core.display);

        return -1;
    }

    LOGI("running at server ", server_name);
    setenv("WAYLAND_DISPLAY", server_name, 1);
    wf::xwayland_set_seat(core.get_current_seat());
    wl_display_run(core.display);

    /* Teardown */
    wl_display_destroy_clients(core.display);
    wl_display_destroy(core.display);

    return EXIT_SUCCESS;
}
<commit_msg>Fix warning when asan is enabled<commit_after>#include <cstdlib>
#include <cstring>
#include <iostream>
#include <getopt.h>
#include <signal.h>
#include <map>

#include <sys/inotify.h>
#include <unistd.h>

#include "debug-func.hpp"
#include "main.hpp"
#include "wayfire/nonstd/safe-list.hpp"
#include <wayfire/config/file.hpp>

extern "C"
{
#define static
#include <wlr/render/gles2.h>
#undef static
#include <wlr/backend/multi.h>
#include <wlr/backend/wayland.h>
#include <wlr/util/log.h>
}

#include <wayland-server.h>

#include "core/core-impl.hpp"
#include "view/view-impl.hpp"
#include "wayfire/output.hpp"

wf_runtime_config runtime_config;

#define INOT_BUF_SIZE (1024 * sizeof(inotify_event))
static char buf[INOT_BUF_SIZE];

static std::string config_dir, config_file;

static void reload_config(int fd)
{
    wf::config::load_configuration_options_from_file(
        wf::get_core().config, config_file);
    inotify_add_watch(fd, config_dir.c_str(), IN_CREATE);
    inotify_add_watch(fd, config_file.c_str(), IN_MODIFY);
}

static int handle_config_updated(int fd, uint32_t mask, void *data)
{
    LOGD("Reloading configuration file");

    /* read, but don't use */
    read(fd, buf, INOT_BUF_SIZE);
    reload_config(fd);

    wf::get_core().emit_signal("reload-config", nullptr);

    return 0;
}

static void print_version()
{
    std::cout << WAYFIRE_VERSION << std::endl;
    exit(0);
}

static void print_help()
{
    std::cout << "Wayfire " << WAYFIRE_VERSION << std::endl;
    std::cout << "Usage: wayfire [OPTION]...\n" << std::endl;
    std::cout << " -c,  --config            specify config file to use" << std::endl;
    std::cout << " -h,  --help              print this help" << std::endl;
    std::cout << " -d,  --debug             enable debug logging" << std::endl;
    std::cout <<
        " -D,  --damage-debug      enable additional debug for damaged regions" <<
        std::endl;
    std::cout << " -R,  --damage-rerender   rerender damaged regions" << std::endl;
    std::cout << " -v,  --version           print version and exit" << std::endl;
    exit(0);
}

std::map<EGLint, EGLint> default_attribs = {
    {EGL_RED_SIZE, 1},
    {EGL_GREEN_SIZE, 1},
    {EGL_BLUE_SIZE, 1},
    {EGL_DEPTH_SIZE, 1},
};

std::map<wlr_renderer*, wlr_egl*> egl_for_renderer;

/* Merge the default config and the config we need */
static std::vector<EGLint> generate_config_attribs(EGLint *renderer_attribs)
{
    std::vector<EGLint> attribs;

    /* See what we have in the default config */
    for (auto i = renderer_attribs; i != NULL && *i != EGL_NONE; i++)
    {
        /* We will override this value later */
        if (default_attribs.count(*i))
        {
            ++i;
            continue;
        }

        attribs.push_back(*i);
        i++;
        attribs.push_back(*i);
    }

    /* Then pack all values we want */
    for (auto & p : default_attribs)
    {
        attribs.push_back(p.first);
        attribs.push_back(p.second);
    }

    attribs.push_back(EGL_NONE);

    return attribs;
}

wlr_renderer *add_egl_depth_renderer(wlr_egl *egl, EGLenum platform,
    void *remote, EGLint *_r_attr, EGLint visual)
{
    bool r;
    auto attribs = generate_config_attribs(_r_attr);
    r = wlr_egl_init(egl, platform, remote, attribs.data(), visual);

    if (!r)
    {
        LOGE("Failed to initialize EGL");

        return NULL;
    }

    auto renderer = wlr_gles2_renderer_create(egl);
    if (!renderer)
    {
        LOGE("Failed to create GLES2 renderer");
        wlr_egl_finish(egl);

        return NULL;
    }

    egl_for_renderer[renderer] = egl;

    return renderer;
}

namespace wf
{
namespace _safe_list_detail
{
wl_event_loop *event_loop;
void idle_cleanup_func(void *data)
{
    auto priv = reinterpret_cast<std::function<void()>*>(data);
    (*priv)();
}
}
}

static bool drop_permissions(void)
{
    if ((getuid() != geteuid()) || (getgid() != getegid()))
    {
        // Set the gid and uid in the correct order.
        if ((setgid(getgid()) != 0) || (setuid(getuid()) != 0))
        {
            LOGE("Unable to drop root, refusing to start");

            return false;
        }
    }

    if ((setgid(0) != -1) || (setuid(0) != -1))
    {
        LOGE("Unable to drop root (we shouldn't be able to "
             "restore it after setuid), refusing to start");

        return false;
    }

    return true;
}

static wf::log::color_mode_t detect_color_mode()
{
    return isatty(STDOUT_FILENO) ?
           wf::log::LOG_COLOR_MODE_ON : wf::log::LOG_COLOR_MODE_OFF;
}

static void wlr_log_handler(wlr_log_importance level,
    const char *fmt, va_list args)
{
    const int bufsize = 4 * 1024;
    char buffer[bufsize];
    vsnprintf(buffer, bufsize, fmt, args);

    wf::log::log_level_t wlevel;
    switch (level)
    {
      case WLR_ERROR:
        wlevel = wf::log::LOG_LEVEL_ERROR;
        break;

      case WLR_INFO:
        wlevel = wf::log::LOG_LEVEL_INFO;
        break;

      case WLR_DEBUG:
        wlevel = wf::log::LOG_LEVEL_DEBUG;
        break;

      default:
        return;
    }

    wf::log::log_plain(wlevel, buffer);
}

#ifndef ASAN_ENABLED
static void signal_handler(int signal)
{
    std::string error;
    switch (signal)
    {
      case SIGSEGV:
        error = "Segmentation fault";
        break;

      case SIGFPE:
        error = "Floating-point exception";
        break;

      case SIGABRT:
        error = "Fatal error(SIGABRT)";
        break;

      default:
        error = "Unknown";
    }

    LOGE("Fatal error: ", error);
    wf::print_trace(false);
    std::exit(0);
}

#endif

int main(int argc, char *argv[])
{
    config_dir = nonull(getenv("XDG_CONFIG_HOME"));
    if (!config_dir.compare("nil"))
    {
        config_dir = std::string(nonull(getenv("HOME"))) + "/.config";
    }

    config_file = config_dir + "/wayfire.ini";

    wf::log::log_level_t log_level = wf::log::LOG_LEVEL_INFO;
    struct option opts[] = {
        {
            "config", required_argument, NULL, 'c'
        },
        {"debug", no_argument, NULL, 'd'},
        {"damage-debug", no_argument, NULL, 'D'},
        {"damage-rerender", no_argument, NULL, 'R'},
        {"help", no_argument, NULL, 'h'},
        {"version", no_argument, NULL, 'v'},
        {0, 0, NULL, 0}
    };

    int c, i;
    while ((c = getopt_long(argc, argv, "c:dDhRv", opts, &i)) != -1)
    {
        switch (c)
        {
          case 'c':
            config_file = optarg;
            break;

          case 'D':
            runtime_config.damage_debug = true;
            break;

          case 'R':
            runtime_config.no_damage_track = true;
            break;

          case 'h':
            print_help();
            break;

          case 'd':
            log_level = wf::log::LOG_LEVEL_DEBUG;
            break;

          case 'v':
            print_version();
            break;

          default:
            std::cerr << "Unrecognized command line argument " << optarg << "\n" <<
                std::endl;
        }
    }

    auto wlr_log_level =
        (log_level == wf::log::LOG_LEVEL_DEBUG ? WLR_DEBUG : WLR_ERROR);
    wlr_log_init(wlr_log_level, wlr_log_handler);
    wf::log::initialize_logging(std::cout, log_level, detect_color_mode());

#ifndef ASAN_ENABLED
    /* In case of crash, print the stacktrace for debugging.
     * However, if ASAN is enabled, we'll get better stacktrace from there. */
    signal(SIGSEGV, signal_handler);
    signal(SIGFPE, signal_handler);
    signal(SIGABRT, signal_handler);
#endif

    LOGI("Starting wayfire version ", WAYFIRE_VERSION);
    /* First create display and initialize safe-list's event loop, so that
     * wf objects (which depend on safe-list) can work */
    auto display = wl_display_create();
    wf::_safe_list_detail::event_loop = wl_display_get_event_loop(display);

    auto& core = wf::get_core_impl();

    /** TODO: move this to core_impl constructor */
    core.display  = display;
    core.ev_loop  = wl_display_get_event_loop(core.display);
    core.backend  = wlr_backend_autocreate(core.display, add_egl_depth_renderer);
    core.renderer = wlr_backend_get_renderer(core.backend);
    core.egl = egl_for_renderer[core.renderer];
    assert(core.egl);

    if (!drop_permissions())
    {
        wl_display_destroy_clients(core.display);
        wl_display_destroy(core.display);

        return EXIT_FAILURE;
    }

    std::vector<std::string> xmldirs;
    if (char *plugin_xml_path = getenv("WAYFIRE_PLUGIN_XML_PATH"))
    {
        std::stringstream ss(plugin_xml_path);
        std::string entry;
        while (std::getline(ss, entry, ':'))
        {
            xmldirs.push_back(entry);
        }
    }

    xmldirs.push_back(PLUGIN_XML_DIR);

    LOGI("using config file: ", config_file.c_str());
    core.config = wf::config::build_configuration(
        xmldirs, SYSCONFDIR "/wayfire/defaults.ini", config_file);

    int inotify_fd = inotify_init1(IN_CLOEXEC);
    reload_config(inotify_fd);

    wl_event_loop_add_fd(core.ev_loop, inotify_fd, WL_EVENT_READABLE,
        handle_config_updated, NULL);
    core.init();

    auto server_name = wl_display_add_socket_auto(core.display);
    if (!server_name)
    {
        LOGE("failed to create wayland, socket, exiting");

        return -1;
    }

    setenv("_WAYLAND_DISPLAY", server_name, 1);

    core.wayland_display = server_name;
    if (!wlr_backend_start(core.backend))
    {
        LOGE("failed to initialize backend, exiting");
        wlr_backend_destroy(core.backend);
        wl_display_destroy(core.display);

        return -1;
    }

    LOGI("running at server ", server_name);
    setenv("WAYLAND_DISPLAY", server_name, 1);
    wf::xwayland_set_seat(core.get_current_seat());
    wl_display_run(core.display);

    /* Teardown */
    wl_display_destroy_clients(core.display);
    wl_display_destroy(core.display);

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*ibnu.yahya@toroo.org*/
#include <QtWidgets/QApplication>
#include "ignsdk.h"
#include <QtWebKitWidgets/QWebView>
#include <QFileDialog>
#include <iostream>
#include "version.h"
#include <QCommandLineParser>

using namespace std;

int main(int argc, char *argv[]){
    QApplication app(argc, argv);
    ign ignsdk;

    QString url = NULL;
    bool file = false;
    QString optional;

    QCommandLineParser cmd_parser;
    cmd_parser.setApplicationDescription("IGOS Nusantara Software Development Kit");

    QCommandLineOption cmd_project(QStringList() << "p" << "project", "Specify project directory", "directory");
    cmd_parser.addOption(cmd_project);
    QCommandLineOption cmd_file(QStringList() << "f" << "file", "Load specific HTML file instead of index.html", "file");
    cmd_parser.addOption(cmd_file);
    QCommandLineOption cmd_dev(QStringList() << "d" << "development", "Activate development mode");
    cmd_parser.addOption(cmd_dev);
    QCommandLineOption cmd_remote(QStringList() << "r" << "remote", "Activate remote debugging", "port");
    cmd_parser.addOption(cmd_remote);
    QCommandLineOption cmd_version(QStringList() << "v" << "version", "Show version");
    cmd_parser.addOption(cmd_version);
    cmd_parser.addHelpOption();

    cmd_parser.process(app);

    if (cmd_parser.isSet(cmd_version)){
        printf("IGNSDK version %s (%s). Compiled on %s %s. Maintained by %s.\n", IGNSDK_VERSION, IGNSDK_CODENAME, __DATE__, __TIME__, IGNSDK_MAINTAINER);
        exit(0);
    }

    url = cmd_parser.value(cmd_project);

    if (cmd_parser.isSet(cmd_remote)){
        ignsdk.setDevRemote(cmd_parser.value(cmd_remote).toInt());
    }

    if (cmd_parser.isSet(cmd_file)){
        if (cmd_parser.isSet(cmd_project)){
            file = true;
            optional = cmd_parser.value(cmd_file);
        } else {
            qDebug() << "Error: Project directory must be specified.";
            exit(1);
        }
    }

    QString opt = url;
    QString path = url;

    if (!opt.isEmpty()){
        ignsdk.pathApp = opt;
        app.setWindowIcon(QIcon(path + "icons/app.png"));

        if (file){
            opt += "/";
            opt += optional;
        } else {
            opt += "/index.html";
        }

        if (QFile::exists(opt)){
            ignsdk.render(opt);
            ignsdk.config(url);
            ignsdk.show();
        } else {
            qDebug() << "Error:" << opt << "is not exist.";
            exit(1);
        }

    } else {
        QFileDialog *fileDialog = new QFileDialog;
#ifdef Linux
        QTreeView *tree = fileDialog->findChild <QTreeView*>();
        tree->setRootIsDecorated(true);
        tree->setItemsExpandable(true);
#endif
        fileDialog->setFileMode(QFileDialog::Directory);
        fileDialog->setOption(QFileDialog::ShowDirsOnly);
        fileDialog->setViewMode(QFileDialog::Detail);
        int result = fileDialog->exec();
        QString directory;

        if (result){
            directory = fileDialog->selectedFiles()[0];

            if (QFile::exists(directory + "/index.html"))
            {
                ignsdk.config(directory);
                ignsdk.render(directory + "/index.html");
                ignsdk.show();
            } else {
                qDebug() << "Error:" << (directory + "/index.html") << "is not exist.";
                exit(1);
            }
        } else {
            exit(1);
        }
    }

    return app.exec();
}
<commit_msg>src/main.cpp: Add command line option to enable development mode<commit_after>/*ibnu.yahya@toroo.org*/
#include <QtWidgets/QApplication>
#include "ignsdk.h"
#include <QtWebKitWidgets/QWebView>
#include <QFileDialog>
#include <iostream>
#include "version.h"
#include <QCommandLineParser>

using namespace std;

int main(int argc, char *argv[]){
    QApplication app(argc, argv);
    ign ignsdk;

    QString url = NULL;
    bool file = false;
    QString optional;

    QCommandLineParser cmd_parser;
    cmd_parser.setApplicationDescription("IGOS Nusantara Software Development Kit");

    QCommandLineOption cmd_project(QStringList() << "p" << "project", "Specify project directory", "directory");
    cmd_parser.addOption(cmd_project);
    QCommandLineOption cmd_file(QStringList() << "f" << "file", "Load specific HTML file instead of index.html", "file");
    cmd_parser.addOption(cmd_file);
    QCommandLineOption cmd_dev(QStringList() << "d" << "development", "Activate development mode");
    cmd_parser.addOption(cmd_dev);
    QCommandLineOption cmd_remote(QStringList() << "r" << "remote", "Activate remote debugging", "port");
    cmd_parser.addOption(cmd_remote);
    QCommandLineOption cmd_version(QStringList() << "v" << "version", "Show version");
    cmd_parser.addOption(cmd_version);
    cmd_parser.addHelpOption();

    cmd_parser.process(app);

    if (cmd_parser.isSet(cmd_version)){
        printf("IGNSDK version %s (%s). Compiled on %s %s. Maintained by %s.\n", IGNSDK_VERSION, IGNSDK_CODENAME, __DATE__, __TIME__, IGNSDK_MAINTAINER);
        exit(0);
    }

    url = cmd_parser.value(cmd_project);

    if (cmd_parser.isSet(cmd_remote)){
        ignsdk.setDevRemote(cmd_parser.value(cmd_remote).toInt());
    }

    if (cmd_parser.isSet(cmd_file)){
        if (cmd_parser.isSet(cmd_project)){
            file = true;
            optional = cmd_parser.value(cmd_file);
        } else {
            qDebug() << "Error: Project directory must be specified.";
            exit(1);
        }
    }

    if (cmd_parser.isSet(cmd_dev)){
        ignsdk.setDev(true);
    }

    QString opt = url;
    QString path = url;

    if (!opt.isEmpty()){
        ignsdk.pathApp = opt;
        app.setWindowIcon(QIcon(path + "icons/app.png"));

        if (file){
            opt += "/";
            opt += optional;
        } else {
            opt += "/index.html";
        }

        if (QFile::exists(opt)){
            ignsdk.render(opt);
            ignsdk.config(url);
            ignsdk.show();
        } else {
            qDebug() << "Error:" << opt << "is not exist.";
            exit(1);
        }

    } else {
        QFileDialog *fileDialog = new QFileDialog;
#ifdef Linux
        QTreeView *tree = fileDialog->findChild <QTreeView*>();
        tree->setRootIsDecorated(true);
        tree->setItemsExpandable(true);
#endif
        fileDialog->setFileMode(QFileDialog::Directory);
        fileDialog->setOption(QFileDialog::ShowDirsOnly);
        fileDialog->setViewMode(QFileDialog::Detail);
        int result = fileDialog->exec();
        QString directory;

        if (result){
            directory = fileDialog->selectedFiles()[0];

            if (QFile::exists(directory + "/index.html"))
            {
                ignsdk.config(directory);
                ignsdk.render(directory + "/index.html");
                ignsdk.show();
            } else {
                qDebug() << "Error:" << (directory + "/index.html") << "is not exist.";
                exit(1);
            }
        } else {
            exit(1);
        }
    }

    return app.exec();
}
<|endoftext|>


<commit_before>//Author: Julian Yi
//Date Started: 14 July 2017, Friday.
//Purpose: This is a project to create a working chess engine and gui using C++.
//File: This is the main file.
#include <iostream>
#include "board.h"
#include "pawn.h"
#include "knight.h"
#include "bishop.h"
#include "coord.h"
#include "ui.h"
#include "BearLibTerminal.h"

void handleInput(board& Chessboard);

int main()
{
	// Initialize board.
	auto Chessboard = std::make_shared<board>();
	Chessboard->initializeBoard();

	for (int i = 0; i < 8; i++) {
		Chessboard->placePiece(PieceType::Pawn, {i, 1}, TeamColor::White);
	}

	Chessboard->placePiece(PieceType::Rook, {0, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Rook, {7, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Knight, {1, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Knight, {6, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, {2, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, {5, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Queen, {3, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::King, { 4,0 }, TeamColor::White);

	for (int i = 0; i < 8; i++) {
		Chessboard->placePiece(PieceType::Pawn, {i, 6}, TeamColor::Black);
	}
	Chessboard->placePiece(PieceType::Rook, {0, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Rook, {7, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Knight, {1, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Knight, {6, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Bishop, {2, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Bishop, {5, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Queen, {3, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::King, { 4,7 }, TeamColor::Black);

	Chessboard->placePiece(PieceType::Pawn, { 2,3 }, TeamColor::Black);

	Chessboard->movePiece({ 1,1 }, { 1,2 }); //success
	Chessboard->movePiece({ 1,2 }, { 2,3 }); //success
	Chessboard->movePiece({ 2,3 }, { 3,3 }); //fail

	Chessboard->placePiece(PieceType::Pawn, { 3,4 }, TeamColor::Black);
	Chessboard->movePiece({ 3,4 }, { 2,3 }); //success

	Chessboard->placePiece(PieceType::Pawn, { 1,2 }, TeamColor::White);
	Chessboard->movePiece({ 2,3 }, { 1,2 });
	//Chessboard->movePiece({ 1,2 }, { 0,1 });
	//Chessboard->movePiece({ 0,1 }, { 1,0 });
	//Chessboard->movePiece({ 1,1 }, { 1,0 });

	/*
	it all works
	// Test an attack.
	// Expected Output : success, knight is destroyed
	Chessboard->movePiece({3, 4}, {1, 2});

	// Test creating a piece into the occupied coordinate (same color)
	// Expected Output : failure
	Chessboard->placePiece(PieceType::Rook, { 3,3 }, TeamColor::White);
	Chessboard->placePiece(PieceType::Pawn, { 3,3 }, TeamColor::White);

	// Test creating a piece into the occupied coordinate (different color)
	// Expected Output : failure
	Chessboard->deletePiece({ 3,3 });
	Chessboard->placePiece(PieceType::Pawn, { 3,3 }, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, { 3,3 }, TeamColor::Black);

	// Test Moving a piece into the occupied coordinate (same color)
	// Expected Output : failure
	Chessboard->placePiece(PieceType::Pawn, { 3,2 }, TeamColor::White);
	Chessboard->movePiece({ 3,2 }, { 3,3 });
	*/

	// Test Pawn's valid moves

	// Open the terminal. Since no terminal_set() method is called,
	// the terminal will use default settings.
	terminal_open();

	// Font setup. ./font/FSEX300.ttf
	terminal_set("window: title='Chess', size='46x24'; font: ./font/FSEX300.ttf, size=32x32");

	// Palette.
	terminal_set("palette: whitepiece=#C2CCCF, blackpiece=#4D483C, whitetile=#02171F, blacktile=#000000;");

	terminal_set(
	    "input:"
	    "cursor-symbol = 0x1F,"
	    "cursor-blink-rate = 500,"
	    "precise-mouse = false,"
	    "mouse-cursor = true,"
	    "filter=[keyboard, mouse];"
	);

	// Print intro text.
	terminal_print(1, 1, "Chess Engine");
	terminal_print(4, 2, "by Julian Yi, Sean Brock, and Simon Kim");
	terminal_print(1, 4, "Press Enter to start...");
	terminal_refresh();

	// Create UI manager
	ui UIManager;
	// Register the chessboard in a board element.
	UIManager.addElement(std::make_shared<boardElement>(Chessboard), { 2, 5 });

	//roughdraft until I figure out a better way to do this
	int mouseClicks = 0;
	int xCursor = 0;
	int yCursor = 0;
	coord current = {0, 0};
	coord next = {0, 0};
	bool clicked = false;

	bool running = true;
	coord boardOffset{ 2, 5 };

	while (running) {
 		// Check for input. termnial_read() is blocking, meaning the
		// program will wait until it reads a key press.
		auto key = terminal_read();
		// Reset the terminal to blank state.
		terminal_clear();

		// Text goes on layer 3.
		terminal_layer(3);

		// Print instructions.
		//terminal_print(1, 1, "Press Enter to start...");

		// Handle key presses.
		switch (key) {
			case TK_CLOSE:
				running = false;
				break;
			case TK_ESCAPE:
				running = false;
				break;
			case TK_ENTER:
				break;
			case TK_MOUSE_MOVE:
				xCursor = terminal_state(TK_MOUSE_X);
		 		yCursor = terminal_state(TK_MOUSE_Y);
				break;
			case TK_MOUSE_LEFT:
				mouseClicks++; //amount of time something is clicked

				//if the clicked square has something then set the object clicked flag to true and set the current coordinate
				if (Chessboard->isOccupied({ (xCursor - boardOffset.x), (yCursor - boardOffset.y) }) == true && (mouseClicks == 1))
				{
					current = { (xCursor - boardOffset.x), (yCursor - boardOffset.y) };
					std::cout << "first click" << current.x << "," << current.y << std::endl;
					clicked = true;
					std::cout << mouseClicks;
				}
				//if clicked flag is false and there is nothing on the board don't do anything
				else if(Chessboard->isOccupied({ (xCursor - boardOffset.x), (yCursor - boardOffset.y) }) == false && clicked == false)
				{
					current = { -1, -1 };
					std::cout << "nothing was clicked" << std::endl;
					mouseClicks = 0;
				}
				//mouseClicks has to be higher than 1 to perform the move function. clicked flag also has to be true
				//handles move
				if(clicked == true && mouseClicks > 1)
				{
					//do something with that piece
					next = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
					std::cout << "second click" << next.x << "," << next.y << std::endl;
					Chessboard->movePiece(current, next);
					clicked = false;
					std::cout << mouseClicks;
					mouseClicks = 0;
				}
				break;
			default:
				terminal_print(1, 2, "The key pressed has no function.");
				break;
		}

		// Draw board
		UIManager.draw();

		if((2 <= xCursor && xCursor <=9) && (5 <= yCursor && yCursor <= 12))
		{
			int select = 0x02C7;
			terminal_layer(2);
			terminal_color(color_from_name("green"));
			terminal_put(xCursor, yCursor, select);
		}

			 	//TK_MOUSE_CLICK
		//set the flag
		//flag true then call something.
		/*
		if (key == TK_MOUSE_LEFT)
		{
			int mouseClicks = terminal_state(TK_MOUSE_LEFT);
			if(mouseClicks == 1)
			{
				//select the piece
				current = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
				std::cout << "first click" << current.x << "," << current.y << std::endl;
			}
			else if(mouseClicks == 2)
			{
				//do something with that piece
				next = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
				std::cout << "second click" << next.x << "," << next.y << std::endl;
				Chessboard->movePiece(current, next);
			}
		}
		*/

		// Commit the buffer and draw it.
		// Move to ui manager eventually.
		terminal_refresh();

	}

	// We're done here.
	terminal_close();

	return 0;
}
<commit_msg>fixed the click boundary<commit_after>//Author: Julian Yi
//Date Started: 14 July 2017, Friday.
//Purpose: This is a project to create a working chess engine and gui using C++.
//File: This is the main file.
#include <iostream>
#include "board.h"
#include "pawn.h"
#include "knight.h"
#include "bishop.h"
#include "coord.h"
#include "ui.h"
#include "BearLibTerminal.h"

void handleInput(board& Chessboard);

int main()
{
	// Initialize board.
	auto Chessboard = std::make_shared<board>();
	Chessboard->initializeBoard();

	for (int i = 0; i < 8; i++) {
		Chessboard->placePiece(PieceType::Pawn, {i, 1}, TeamColor::White);
	}

	Chessboard->placePiece(PieceType::Rook, {0, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Rook, {7, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Knight, {1, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Knight, {6, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, {2, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, {5, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Queen, {3, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::King, { 4,0 }, TeamColor::White);

	for (int i = 0; i < 8; i++) {
		Chessboard->placePiece(PieceType::Pawn, {i, 6}, TeamColor::Black);
	}
	Chessboard->placePiece(PieceType::Rook, {0, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Rook, {7, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Knight, {1, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Knight, {6, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Bishop, {2, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Bishop, {5, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Queen, {3, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::King, { 4,7 }, TeamColor::Black);

	Chessboard->placePiece(PieceType::Pawn, { 2,3 }, TeamColor::Black);

	Chessboard->movePiece({ 1,1 }, { 1,2 }); //success
	Chessboard->movePiece({ 1,2 }, { 2,3 }); //success
	Chessboard->movePiece({ 2,3 }, { 3,3 }); //fail

	Chessboard->placePiece(PieceType::Pawn, { 3,4 }, TeamColor::Black);
	Chessboard->movePiece({ 3,4 }, { 2,3 }); //success

	Chessboard->placePiece(PieceType::Pawn, { 1,2 }, TeamColor::White);
	Chessboard->movePiece({ 2,3 }, { 1,2 });
	//Chessboard->movePiece({ 1,2 }, { 0,1 });
	//Chessboard->movePiece({ 0,1 }, { 1,0 });
	//Chessboard->movePiece({ 1,1 }, { 1,0 });

	/*
	it all works
	// Test an attack.
	// Expected Output : success, knight is destroyed
	Chessboard->movePiece({3, 4}, {1, 2});

	// Test creating a piece into the occupied coordinate (same color)
	// Expected Output : failure
	Chessboard->placePiece(PieceType::Rook, { 3,3 }, TeamColor::White);
	Chessboard->placePiece(PieceType::Pawn, { 3,3 }, TeamColor::White);

	// Test creating a piece into the occupied coordinate (different color)
	// Expected Output : failure
	Chessboard->deletePiece({ 3,3 });
	Chessboard->placePiece(PieceType::Pawn, { 3,3 }, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, { 3,3 }, TeamColor::Black);

	// Test Moving a piece into the occupied coordinate (same color)
	// Expected Output : failure
	Chessboard->placePiece(PieceType::Pawn, { 3,2 }, TeamColor::White);
	Chessboard->movePiece({ 3,2 }, { 3,3 });
	*/

	// Test Pawn's valid moves

	// Open the terminal. Since no terminal_set() method is called,
	// the terminal will use default settings.
	terminal_open();

	// Font setup. ./font/FSEX300.ttf
	terminal_set("window: title='Chess', size='46x24'; font: ./font/FSEX300.ttf, size=32x32");

	// Palette.
	terminal_set("palette: whitepiece=#C2CCCF, blackpiece=#4D483C, whitetile=#02171F, blacktile=#000000;");

	terminal_set(
	    "input:"
	    "cursor-symbol = 0x1F,"
	    "cursor-blink-rate = 500,"
	    "precise-mouse = false,"
	    "mouse-cursor = true,"
	    "filter=[keyboard, mouse];"
	);

	// Print intro text.
	terminal_print(1, 1, "Chess Engine");
	terminal_print(4, 2, "by Julian Yi, Sean Brock, and Simon Kim");
	terminal_print(1, 4, "Press Enter to start...");
	terminal_refresh();

	// Create UI manager
	ui UIManager;
	// Register the chessboard in a board element.
	UIManager.addElement(std::make_shared<boardElement>(Chessboard), { 2, 5 });

	//roughdraft until I figure out a better way to do this
	int mouseClicks = 0;
	int xCursor = 0;
	int yCursor = 0;
	coord current = {0, 0};
	coord next = {0, 0};
	bool clicked = false;

	bool running = true;
	coord boardOffset{ 2, 5 };

	while (running) {
 		// Check for input. termnial_read() is blocking, meaning the
		// program will wait until it reads a key press.
		auto key = terminal_read();
		// Reset the terminal to blank state.
		terminal_clear();

		// Text goes on layer 3.
		terminal_layer(3);

		// Print instructions.
		//terminal_print(1, 1, "Press Enter to start...");

		// Handle key presses.
		switch (key) {
			case TK_CLOSE:
				running = false;
				break;
			case TK_ESCAPE:
				running = false;
				break;
			case TK_ENTER:
				break;
			case TK_MOUSE_MOVE:
				xCursor = terminal_state(TK_MOUSE_X);
		 		yCursor = terminal_state(TK_MOUSE_Y);
				break;
			case TK_MOUSE_LEFT:
				mouseClicks++; //amount of time something is clicked

				if ((2 <= xCursor && xCursor <= 9) && (5 <= yCursor && yCursor <= 12)){
				//if the clicked square has something then set the object clicked flag to true and set the current coordinate
					if (Chessboard->isOccupied({ (xCursor - boardOffset.x), (yCursor - boardOffset.y) }) == true && (mouseClicks == 1))
					{
						current = { (xCursor - boardOffset.x), (yCursor - boardOffset.y) };
						std::cout << "first click" << current.x << "," << current.y << std::endl;
						clicked = true;
						std::cout << mouseClicks;
					}
					//if clicked flag is false and there is nothing on the board don't do anything
					else if(Chessboard->isOccupied({ (xCursor - boardOffset.x), (yCursor - boardOffset.y) }) == false && clicked == false)
					{
						current = { -1, -1 };
						std::cout << "nothing was clicked" << std::endl;
						mouseClicks = 0;
					}
					//mouseClicks has to be higher than 1 to perform the move function. clicked flag also has to be true
					//handles move
					if(clicked == true && mouseClicks > 1)
					{
						//do something with that piece
						next = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
						std::cout << "second click" << next.x << "," << next.y << std::endl;
						Chessboard->movePiece(current, next);
						clicked = false;
						std::cout << mouseClicks;
						mouseClicks = 0;
					}
				}
				break;
			default:
				terminal_print(1, 2, "The key pressed has no function.");
				break;
		}

		// Draw board
		UIManager.draw();

		if((2 <= xCursor && xCursor <=9) && (5 <= yCursor && yCursor <= 12))
		{
			int select = 0x02C7;
			terminal_layer(2);
			terminal_color(color_from_name("green"));
			terminal_put(xCursor, yCursor, select);
		}

			 	//TK_MOUSE_CLICK
		//set the flag
		//flag true then call something.
		/*
		if (key == TK_MOUSE_LEFT)
		{
			int mouseClicks = terminal_state(TK_MOUSE_LEFT);
			if(mouseClicks == 1)
			{
				//select the piece
				current = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
				std::cout << "first click" << current.x << "," << current.y << std::endl;
			}
			else if(mouseClicks == 2)
			{
				//do something with that piece
				next = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
				std::cout << "second click" << next.x << "," << next.y << std::endl;
				Chessboard->movePiece(current, next);
			}
		}
		*/

		// Commit the buffer and draw it.
		// Move to ui manager eventually.
		terminal_refresh();

	}

	// We're done here.
	terminal_close();

	return 0;
}
<|endoftext|>


<commit_before>//  main.cpp
//  Efficient Compression Tool
//  Created by Felix Hanau on 19.12.14.
//  Copyright (c) 2014-2015 Felix Hanau.

#include "main.h"
#include "support.h"

#include <unistd.h>

#ifndef NOMULTI
#include <thread>
#endif

#ifdef MP3_SUPPORTED
#include <id3/tag.h>
#endif

static unsigned long processedfiles;
static size_t bytes;
static long long savings;

static void Usage() {
    printf (
            "Efficient Compression Tool\n"
            "(C) 2014-2015 Felix Hanau.\n"
            "Version 0.2"
#ifdef __DATE__
            " compiled on %s\n"
#endif
            "Folder support "
#ifdef BOOST_SUPPORTED
            "enabled\n"
#else
            "disabled\n"
#endif

            "Losslessly optimizes JPEG and PNG images\n"
            "Usage: ECT [Options] File"
#ifdef BOOST_SUPPORTED
            "/Folder"
#endif
            "\n"
            "Options:\n"
            " -1 to -9       Set compression level (Default: 2)\n"
            " -strip         Strip metadata\n"
            " -progressive   Use progressive encoding for JPEGs\n"
#ifdef BOOST_SUPPORTED
            " -recurse       Recursively search directories\n"
#endif
            " -gzip          Compress file with GZIP algorithm\n"
            " -quiet         Print only error messages\n"
            " -help          Print this help\n"
            "Advanced Options:\n"
#ifdef BOOST_SUPPORTED
            " --disable-png  Disable PNG optimization\n"
            " --disable-jpg  Disable JPEG optimization\n"
#endif
            " --strict       Enable strict losslessness\n"
#ifndef NOMULTI
            " --mt-deflate   Use per block multithreading in Deflate\n"
            " --mt-deflate=i Use per block multithreading in Deflate, use i threads\n"
#endif
            //" --arithmetic   Use arithmetic encoding for JPEGs, incompatible with most software\n"
#ifdef __DATE__
            ,__DATE__
#endif
            );
}

static void ECT_ReportSavings(){
    if (processedfiles){
        printf("Processed %lu file%s\n", processedfiles, processedfiles > 1 ? "s":"");
        if (savings < 0){
            printf("Result is bigger\n");
            return;
        }

        int bk = 0;
        int k = 0;
        double smul = savings;
        double bmul = bytes;
        while (smul > 1024) {smul /= 1024; k++;}
        while (bmul > 1024) {bmul /= 1024; bk++;}
        char *counter;
        if (k == 1) {counter = (char *)"K";}
        else if (k == 2) {counter = (char *)"M";}
        else if (k == 3) {counter = (char *)"G";}
        else {counter = (char *)"";}
        char *counter2;
        if (bk == 1){counter2 = (char *)"K";}
        else if (bk == 2){counter2 = (char *)"M";}
        else if (bk == 3){counter2 = (char *)"G";}
        else {counter2 = (char *)"";}
        printf("Saved ");
        if (k == 0){printf("%0.0f", smul);}
        else{printf("%0.2f", smul);}
        printf("%sB out of ", counter);
        if (bk == 0){printf("%0.0f", bmul);}
        else{printf("%0.2f", bmul);}
        printf("%sB (%0.4f%%)\n", counter2, (100.0 * savings)/bytes);}
    else {printf("No compatible files found\n");}
}

static int ECTGzip(const char * Infile, const unsigned Mode, unsigned char multithreading, long long fs){
    if (!fs){
        printf("%s: Compression of empty files is currently not supported\n", Infile);
        return 2;
    }
    if (!IsGzip(Infile)){
        if (exists(((std::string)Infile).append(".gz").c_str())){
            printf("%s: Compressed file already exists\n", Infile);
            return 2;
        }
        ZopfliGzip(Infile, 0, Mode, multithreading);
        return 1;
    }
    else {
        if (exists(((std::string)Infile).append(".ungz").c_str())){
            return 2;
        }
        if (exists(((std::string)Infile).append(".ungz.gz").c_str())){
            return 2;
        }
        ungz(Infile, ((std::string)Infile).append(".ungz").c_str());
        ZopfliGzip(((std::string)Infile).append(".ungz").c_str(), 0, Mode, multithreading);
        if (filesize(((std::string)Infile).append(".ungz.gz").c_str()) < filesize(Infile)){
            unlink(Infile);
            rename(((std::string)Infile).append(".ungz.gz").c_str(), Infile);
        }
        else {
            unlink(((std::string)Infile).append(".ungz.gz").c_str());
        }
        unlink(((std::string)Infile).append(".ungz").c_str());
        return 0;
    }
}

static void OptimizePNG(const char * Infile, const ECTOptions& Options){
    int x = 1;
    long long size = filesize(Infile);
    if(Options.Mode == 9){
        x = Zopflipng(Options.strip, Infile, Options.Strict, 3, 0, Options.DeflateMultithreading);
    }
    //Disabled as using this causes libpng warnings
    //int filter = Optipng(Options.Mode, Infile, true, Options.Strict || Options.Mode > 1);
    int filter = Optipng(Options.Mode, Infile, false, Options.Strict || Options.Mode > 1);

    if (filter == -1){
        return;
    }
    if (Options.Mode != 1){
        if (Options.Mode == 9){
            Zopflipng(Options.strip, Infile, Options.Strict, Options.Mode, filter, Options.DeflateMultithreading);}
        else {
            x = Zopflipng(Options.strip, Infile, Options.Strict, Options.Mode, filter, Options.DeflateMultithreading);}
    }
    else {
        if (filesize(Infile) <= size){
            unlink(((std::string)Infile).append(".bak").c_str());
        }
        else {
            unlink(Infile);
            rename(((std::string)Infile).append(".bak").c_str(), Infile);
        }
    }

    if(Options.strip && x){
        Optipng(0, Infile, false, 0);
    }
}

static void OptimizeJPEG(const char * Infile, const ECTOptions& Options){
    mozjpegtran(Options.Arithmetic, Options.Progressive, Options.strip, Infile, Infile);
    if (Options.Progressive){
        long long fs = filesize(Infile);
        if((Options.Mode == 1 && fs < 6142) || (Options.Mode == 2 && fs < 8192) || (Options.Mode == 3 && fs < 15360) || (Options.Mode == 4 && fs < 30720) || (Options.Mode == 5 && fs < 51200) || Options.Mode > 5){
            mozjpegtran(Options.Arithmetic, false, Options.strip, Infile, Infile);
        }
    }
}

#ifdef MP3_SUPPORTED
static void OptimizeMP3(const char * Infile, const ECTOptions& Options){
    ID3_Tag orig (Infile);
    size_t start = orig.Size();
    ID3_Frame* picFrame = orig.Find(ID3FID_PICTURE);
    if (picFrame)
    {
        ID3_Field* mime = picFrame->GetField(ID3FN_MIMETYPE);
        if (mime){
            char mimetxt[20];
            mime->Get(mimetxt, 19);
            //printf("%s", mimetxt);
            ID3_Field* pic = picFrame->GetField(ID3FN_DATA);
            bool ispng = memcmp(mimetxt, "image/png", 9) == 0 || memcmp(mimetxt, "PNG", 3) == 0;
            if (pic && (memcmp(mimetxt, "image/jpeg", 10) == 0 || ispng)){
                pic->ToFile("out.jpg");
                if (ispng){
                    OptimizePNG("out.jpg", Options);
                }
                else{
                    OptimizeJPEG("out.jpg", Options);
                }
                pic->FromFile("out.jpg");
                unlink("out.jpg");
                orig.SetPadding(false);
                //orig.SetCompression(true);
                if (orig.Size() < start){
                    orig.Update();
                }
            }
        }
    }
}
#endif

static void PerFileWrapper(const char * Infile, const ECTOptions& Options){
    std::string Ext = Infile;
    std::string x = Ext.substr(Ext.find_last_of(".") + 1);

    if ((Options.PNG_ACTIVE && (x == "PNG" || x == "png")) || (Options.JPEG_ACTIVE && (x == "jpg" || x == "JPG" || x == "JPEG" || x == "jpeg")) || Options.Gzip){
        long long size = filesize(Infile);
        if (size < 0){
            printf("%s: bad file\n", Infile);
            return;
        }
        int statcompressedfile = 0;
        if (size < 1200000000) {//completely random value
            if (x == "PNG" || x == "png"){
                OptimizePNG(Infile, Options);
            }
            else if (x == "jpg" || x == "JPG" || x == "JPEG" || x == "jpeg"){
                OptimizeJPEG(Infile, Options);
            }
            else if (Options.Gzip){
                //if (!size)
                statcompressedfile = ECTGzip(Infile, Options.Mode, Options.DeflateMultithreading, size);
                if (statcompressedfile == 2){
                    return;
                }
            }
            if(Options.SavingsCounter){
                processedfiles++;
                bytes += size;
                if (!statcompressedfile){
                savings = savings + size - filesize(Infile);
                }
                else if (statcompressedfile){
                    savings += (size - filesize(((std::string)Infile).append(".gz").c_str()));
                }
            }
        }
        else{printf("File too big\n");}
    }
#ifdef MP3_SUPPORTED
    else if(x == "mp3"){
        OptimizeMP3(Infile, Options);
    }
#endif
}

int main(int argc, const char * argv[]) {
    ECTOptions Options;
    Options.strip = false;
    Options.Progressive = false;
    Options.Mode = 2;
#ifdef BOOST_SUPPORTED
    Options.Recurse = false;
#endif
    Options.PNG_ACTIVE = true;
    Options.JPEG_ACTIVE = true;
    Options.Arithmetic = false;
    Options.Gzip = false;
    Options.SavingsCounter = true;
    Options.Strict = false;
    Options.DeflateMultithreading = 0;
    if (argc >= 2){
        for (int i = 1; i < argc-1; i++) {
            if (strncmp(argv[i], "-strip", 2) == 0){Options.strip = true;}
            else if (strncmp(argv[i], "-progressive", 2) == 0) {Options.Progressive = true;}
            else if (strcmp(argv[i], "-1") == 0) {Options.Mode = 1;}
            else if (strcmp(argv[i], "-2") == 0) {Options.Mode = 2;}
            else if (strcmp(argv[i], "-3") == 0) {Options.Mode = 3;}
            else if (strcmp(argv[i], "-4") == 0) {Options.Mode = 4;}
            else if (strcmp(argv[i], "-5") == 0) {Options.Mode = 5;}
            else if (strcmp(argv[i], "-6") == 0) {Options.Mode = 6;}
            else if (strcmp(argv[i], "-7") == 0) {Options.Mode = 7;}
            else if (strcmp(argv[i], "-8") == 0) {Options.Mode = 8;}
            else if (strcmp(argv[i], "-9") == 0) {Options.Mode = 9;}
            else if (strncmp(argv[i], "-gzip", 2) == 0) {Options.Gzip = true;}
            else if (strncmp(argv[i], "-help", 2) == 0) {Usage(); return 0;}
            else if (strncmp(argv[i], "-quiet", 2) == 0) {Options.SavingsCounter = false;}
#ifdef BOOST_SUPPORTED
            else if (strcmp(argv[i], "--disable-jpeg") == 0 || strcmp(argv[i], "--disable-jpg") == 0 ){Options.JPEG_ACTIVE = false;}
            else if (strcmp(argv[i], "--disable-png") == 0){Options.PNG_ACTIVE = false;}
            else if (strncmp(argv[i], "-recurse", 2) == 0)  {Options.Recurse = 1;}
#endif
            else if (strcmp(argv[i], "--strict") == 0) {Options.Strict = true;}
#ifndef NOMULTI
            else if (strncmp(argv[i], "--mt-deflate", 12) == 0) {
                if (strncmp(argv[i], "--mt-deflate=", 13) == 0){
                    Options.DeflateMultithreading = atoi(argv[i] + 13);
                }
                else{
                    Options.DeflateMultithreading = std::thread::hardware_concurrency();
                }
            }
#endif
            //else if (strcmp(argv[i], "--arithmetic") == 0) {Options.Arithmetic = true;}
            else {printf("Unknown flag: %s\n", argv[i]); return 0;}
        }
#ifdef BOOST_SUPPORTED
        if (boost::filesystem::is_regular_file(argv[argc-1])){
            PerFileWrapper(argv[argc-1], Options);
        }
        else if (boost::filesystem::is_directory(argv[argc-1])){
            if(Options.Recurse){boost::filesystem::recursive_directory_iterator a(argv[argc-1]), b;
                std::vector<boost::filesystem::path> paths(a, b);
                for(unsigned i = 0; i < paths.size(); i++){PerFileWrapper(paths[i].c_str(), Options);}
            }
            else{
                boost::filesystem::directory_iterator a(argv[argc-1]), b;
                std::vector<boost::filesystem::path> paths(a, b);
                for(unsigned i = 0; i < paths.size(); i++){
                    PerFileWrapper(paths[i].c_str(), Options);}
            }
        }
#else
        PerFileWrapper(argv[argc-1], Options);
#endif
        if(Options.SavingsCounter){ECT_ReportSavings();}
    }
    else {Usage();}
}
<commit_msg>Change default mode to 3<commit_after>//  main.cpp
//  Efficient Compression Tool
//  Created by Felix Hanau on 19.12.14.
//  Copyright (c) 2014-2015 Felix Hanau.

#include "main.h"
#include "support.h"

#include <unistd.h>

#ifndef NOMULTI
#include <thread>
#endif

#ifdef MP3_SUPPORTED
#include <id3/tag.h>
#endif

static unsigned long processedfiles;
static size_t bytes;
static long long savings;

static void Usage() {
    printf (
            "Efficient Compression Tool\n"
            "(C) 2014-2015 Felix Hanau.\n"
            "Version 0.2"
#ifdef __DATE__
            " compiled on %s\n"
#endif
            "Folder support "
#ifdef BOOST_SUPPORTED
            "enabled\n"
#else
            "disabled\n"
#endif

            "Losslessly optimizes JPEG and PNG images\n"
            "Usage: ECT [Options] File"
#ifdef BOOST_SUPPORTED
            "/Folder"
#endif
            "\n"
            "Options:\n"
            " -1 to -9       Set compression level (Default: 3)\n"
            " -strip         Strip metadata\n"
            " -progressive   Use progressive encoding for JPEGs\n"
#ifdef BOOST_SUPPORTED
            " -recurse       Recursively search directories\n"
#endif
            " -gzip          Compress file with GZIP algorithm\n"
            " -quiet         Print only error messages\n"
            " -help          Print this help\n"
            "Advanced Options:\n"
#ifdef BOOST_SUPPORTED
            " --disable-png  Disable PNG optimization\n"
            " --disable-jpg  Disable JPEG optimization\n"
#endif
            " --strict       Enable strict losslessness\n"
#ifndef NOMULTI
            " --mt-deflate   Use per block multithreading in Deflate\n"
            " --mt-deflate=i Use per block multithreading in Deflate, use i threads\n"
#endif
            //" --arithmetic   Use arithmetic encoding for JPEGs, incompatible with most software\n"
#ifdef __DATE__
            ,__DATE__
#endif
            );
}

static void ECT_ReportSavings(){
    if (processedfiles){
        printf("Processed %lu file%s\n", processedfiles, processedfiles > 1 ? "s":"");
        if (savings < 0){
            printf("Result is bigger\n");
            return;
        }

        int bk = 0;
        int k = 0;
        double smul = savings;
        double bmul = bytes;
        while (smul > 1024) {smul /= 1024; k++;}
        while (bmul > 1024) {bmul /= 1024; bk++;}
        char *counter;
        if (k == 1) {counter = (char *)"K";}
        else if (k == 2) {counter = (char *)"M";}
        else if (k == 3) {counter = (char *)"G";}
        else {counter = (char *)"";}
        char *counter2;
        if (bk == 1){counter2 = (char *)"K";}
        else if (bk == 2){counter2 = (char *)"M";}
        else if (bk == 3){counter2 = (char *)"G";}
        else {counter2 = (char *)"";}
        printf("Saved ");
        if (k == 0){printf("%0.0f", smul);}
        else{printf("%0.2f", smul);}
        printf("%sB out of ", counter);
        if (bk == 0){printf("%0.0f", bmul);}
        else{printf("%0.2f", bmul);}
        printf("%sB (%0.4f%%)\n", counter2, (100.0 * savings)/bytes);}
    else {printf("No compatible files found\n");}
}

static int ECTGzip(const char * Infile, const unsigned Mode, unsigned char multithreading, long long fs){
    if (!fs){
        printf("%s: Compression of empty files is currently not supported\n", Infile);
        return 2;
    }
    if (!IsGzip(Infile)){
        if (exists(((std::string)Infile).append(".gz").c_str())){
            printf("%s: Compressed file already exists\n", Infile);
            return 2;
        }
        ZopfliGzip(Infile, 0, Mode, multithreading);
        return 1;
    }
    else {
        if (exists(((std::string)Infile).append(".ungz").c_str())){
            return 2;
        }
        if (exists(((std::string)Infile).append(".ungz.gz").c_str())){
            return 2;
        }
        ungz(Infile, ((std::string)Infile).append(".ungz").c_str());
        ZopfliGzip(((std::string)Infile).append(".ungz").c_str(), 0, Mode, multithreading);
        if (filesize(((std::string)Infile).append(".ungz.gz").c_str()) < filesize(Infile)){
            unlink(Infile);
            rename(((std::string)Infile).append(".ungz.gz").c_str(), Infile);
        }
        else {
            unlink(((std::string)Infile).append(".ungz.gz").c_str());
        }
        unlink(((std::string)Infile).append(".ungz").c_str());
        return 0;
    }
}

static void OptimizePNG(const char * Infile, const ECTOptions& Options){
    int x = 1;
    long long size = filesize(Infile);
    if(Options.Mode == 9){
        x = Zopflipng(Options.strip, Infile, Options.Strict, 3, 0, Options.DeflateMultithreading);
    }
    //Disabled as using this causes libpng warnings
    //int filter = Optipng(Options.Mode, Infile, true, Options.Strict || Options.Mode > 1);
    int filter = Optipng(Options.Mode, Infile, false, Options.Strict || Options.Mode > 1);

    if (filter == -1){
        return;
    }
    if (Options.Mode != 1){
        if (Options.Mode == 9){
            Zopflipng(Options.strip, Infile, Options.Strict, Options.Mode, filter, Options.DeflateMultithreading);}
        else {
            x = Zopflipng(Options.strip, Infile, Options.Strict, Options.Mode, filter, Options.DeflateMultithreading);}
    }
    else {
        if (filesize(Infile) <= size){
            unlink(((std::string)Infile).append(".bak").c_str());
        }
        else {
            unlink(Infile);
            rename(((std::string)Infile).append(".bak").c_str(), Infile);
        }
    }

    if(Options.strip && x){
        Optipng(0, Infile, false, 0);
    }
}

static void OptimizeJPEG(const char * Infile, const ECTOptions& Options){
    mozjpegtran(Options.Arithmetic, Options.Progressive, Options.strip, Infile, Infile);
    if (Options.Progressive){
        long long fs = filesize(Infile);
        if((Options.Mode == 1 && fs < 6142) || (Options.Mode == 2 && fs < 8192) || (Options.Mode == 3 && fs < 15360) || (Options.Mode == 4 && fs < 30720) || (Options.Mode == 5 && fs < 51200) || Options.Mode > 5){
            mozjpegtran(Options.Arithmetic, false, Options.strip, Infile, Infile);
        }
    }
}

#ifdef MP3_SUPPORTED
static void OptimizeMP3(const char * Infile, const ECTOptions& Options){
    ID3_Tag orig (Infile);
    size_t start = orig.Size();
    ID3_Frame* picFrame = orig.Find(ID3FID_PICTURE);
    if (picFrame)
    {
        ID3_Field* mime = picFrame->GetField(ID3FN_MIMETYPE);
        if (mime){
            char mimetxt[20];
            mime->Get(mimetxt, 19);
            //printf("%s", mimetxt);
            ID3_Field* pic = picFrame->GetField(ID3FN_DATA);
            bool ispng = memcmp(mimetxt, "image/png", 9) == 0 || memcmp(mimetxt, "PNG", 3) == 0;
            if (pic && (memcmp(mimetxt, "image/jpeg", 10) == 0 || ispng)){
                pic->ToFile("out.jpg");
                if (ispng){
                    OptimizePNG("out.jpg", Options);
                }
                else{
                    OptimizeJPEG("out.jpg", Options);
                }
                pic->FromFile("out.jpg");
                unlink("out.jpg");
                orig.SetPadding(false);
                //orig.SetCompression(true);
                if (orig.Size() < start){
                    orig.Update();
                }
            }
        }
    }
}
#endif

static void PerFileWrapper(const char * Infile, const ECTOptions& Options){
    std::string Ext = Infile;
    std::string x = Ext.substr(Ext.find_last_of(".") + 1);

    if ((Options.PNG_ACTIVE && (x == "PNG" || x == "png")) || (Options.JPEG_ACTIVE && (x == "jpg" || x == "JPG" || x == "JPEG" || x == "jpeg")) || Options.Gzip){
        long long size = filesize(Infile);
        if (size < 0){
            printf("%s: bad file\n", Infile);
            return;
        }
        int statcompressedfile = 0;
        if (size < 1200000000) {//completely random value
            if (x == "PNG" || x == "png"){
                OptimizePNG(Infile, Options);
            }
            else if (x == "jpg" || x == "JPG" || x == "JPEG" || x == "jpeg"){
                OptimizeJPEG(Infile, Options);
            }
            else if (Options.Gzip){
                //if (!size)
                statcompressedfile = ECTGzip(Infile, Options.Mode, Options.DeflateMultithreading, size);
                if (statcompressedfile == 2){
                    return;
                }
            }
            if(Options.SavingsCounter){
                processedfiles++;
                bytes += size;
                if (!statcompressedfile){
                savings = savings + size - filesize(Infile);
                }
                else if (statcompressedfile){
                    savings += (size - filesize(((std::string)Infile).append(".gz").c_str()));
                }
            }
        }
        else{printf("File too big\n");}
    }
#ifdef MP3_SUPPORTED
    else if(x == "mp3"){
        OptimizeMP3(Infile, Options);
    }
#endif
}

int main(int argc, const char * argv[]) {
    ECTOptions Options;
    Options.strip = false;
    Options.Progressive = false;
    Options.Mode = 3;
#ifdef BOOST_SUPPORTED
    Options.Recurse = false;
#endif
    Options.PNG_ACTIVE = true;
    Options.JPEG_ACTIVE = true;
    Options.Arithmetic = false;
    Options.Gzip = false;
    Options.SavingsCounter = true;
    Options.Strict = false;
    Options.DeflateMultithreading = 0;
    if (argc >= 2){
        for (int i = 1; i < argc-1; i++) {
            if (strncmp(argv[i], "-strip", 2) == 0){Options.strip = true;}
            else if (strncmp(argv[i], "-progressive", 2) == 0) {Options.Progressive = true;}
            else if (strcmp(argv[i], "-1") == 0) {Options.Mode = 1;}
            else if (strcmp(argv[i], "-2") == 0) {Options.Mode = 2;}
            else if (strcmp(argv[i], "-3") == 0) {Options.Mode = 3;}
            else if (strcmp(argv[i], "-4") == 0) {Options.Mode = 4;}
            else if (strcmp(argv[i], "-5") == 0) {Options.Mode = 5;}
            else if (strcmp(argv[i], "-6") == 0) {Options.Mode = 6;}
            else if (strcmp(argv[i], "-7") == 0) {Options.Mode = 7;}
            else if (strcmp(argv[i], "-8") == 0) {Options.Mode = 8;}
            else if (strcmp(argv[i], "-9") == 0) {Options.Mode = 9;}
            else if (strncmp(argv[i], "-gzip", 2) == 0) {Options.Gzip = true;}
            else if (strncmp(argv[i], "-help", 2) == 0) {Usage(); return 0;}
            else if (strncmp(argv[i], "-quiet", 2) == 0) {Options.SavingsCounter = false;}
#ifdef BOOST_SUPPORTED
            else if (strcmp(argv[i], "--disable-jpeg") == 0 || strcmp(argv[i], "--disable-jpg") == 0 ){Options.JPEG_ACTIVE = false;}
            else if (strcmp(argv[i], "--disable-png") == 0){Options.PNG_ACTIVE = false;}
            else if (strncmp(argv[i], "-recurse", 2) == 0)  {Options.Recurse = 1;}
#endif
            else if (strcmp(argv[i], "--strict") == 0) {Options.Strict = true;}
#ifndef NOMULTI
            else if (strncmp(argv[i], "--mt-deflate", 12) == 0) {
                if (strncmp(argv[i], "--mt-deflate=", 13) == 0){
                    Options.DeflateMultithreading = atoi(argv[i] + 13);
                }
                else{
                    Options.DeflateMultithreading = std::thread::hardware_concurrency();
                }
            }
#endif
            //else if (strcmp(argv[i], "--arithmetic") == 0) {Options.Arithmetic = true;}
            else {printf("Unknown flag: %s\n", argv[i]); return 0;}
        }
#ifdef BOOST_SUPPORTED
        if (boost::filesystem::is_regular_file(argv[argc-1])){
            PerFileWrapper(argv[argc-1], Options);
        }
        else if (boost::filesystem::is_directory(argv[argc-1])){
            if(Options.Recurse){boost::filesystem::recursive_directory_iterator a(argv[argc-1]), b;
                std::vector<boost::filesystem::path> paths(a, b);
                for(unsigned i = 0; i < paths.size(); i++){PerFileWrapper(paths[i].c_str(), Options);}
            }
            else{
                boost::filesystem::directory_iterator a(argv[argc-1]), b;
                std::vector<boost::filesystem::path> paths(a, b);
                for(unsigned i = 0; i < paths.size(); i++){
                    PerFileWrapper(paths[i].c_str(), Options);}
            }
        }
#else
        PerFileWrapper(argv[argc-1], Options);
#endif
        if(Options.SavingsCounter){ECT_ReportSavings();}
    }
    else {Usage();}
}
<|endoftext|>


<commit_before>/*
 *   O         ,-
 *  ° o    . -´  '     ,-
 *   °  .´        ` . ´,´
 *     ( °   ))     . (
 *      `-;_    . -´ `.`.
 *          `._'       ´
 *
 * Copyright (c) 2007-2012 Markus Fisch <mf@markusfisch.de>
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 */
#ifdef HAVE_KDE
#include <QApplication>
#endif

#include "Application.h"

#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <libgen.h>
#include <stdlib.h>

#ifdef HAVE_GTK
#include <gtk/gtk.h>
#endif

#include <iostream>
#include <stdexcept>

bool stop = false;

/**
 * Signal handler
 *
 * @param id - signal id
 */
void signalHandler( int id )
{
	switch( id )
	{
		case SIGCHLD:
			// more than one process may have been terminated
			while( waitpid( -1, 0, WNOHANG | WUNTRACED ) > 0 );
			break;
		case SIGHUP:
		case SIGINT:
		case SIGTERM:
			stop = true;
			break;
	}

	return;
}

/**
 * Process entry
 *
 * @param argc - number of arguments
 * @param argv - pointer to pointers of arguments
 */
int main( int argc, char **argv )
{
	try
	{
#ifdef HAVE_GTK
		gtk_init( &argc, &argv );
#endif

#ifdef HAVE_KDE
		QApplication q( argc, argv );
#endif

		PieDock::Settings settings;
		char *menuName = 0;

		// parse arguments
		{
			char *binary = basename( *argv );

			while( --argc )
				if( **++argv == '-' )
					switch( *((*argv)+1) )
					{
						default:
							std::cerr << "Skipping unknown flag '" <<
								*((*argv)+1) << "'" << std::endl;
							break;
						case '?':
						case 'h':
							std::cout <<
								binary << " [hvrm]" << std::endl <<
								"\t-h         this help" << std::endl <<
								"\t-v         show version" << std::endl <<
								"\t-r FILE    path and name of alternative " <<
									"configuration file" << std::endl <<
								"\t-m [MENU]  show already running " <<
									"instance" << std::endl;
							return 0;
						case 'v':
							std::cout <<
								binary << " 1.6.4" <<
								std::endl <<
								"Copyright (c) 2007-2012" <<
								std::endl <<
								"Markus Fisch <mf@markusfisch.de>" <<
								std::endl <<
								std::endl <<
								"Tatiana Azundris <hacks@azundris.com>" <<
								std::endl <<
								"* Modifier masks for key control" <<
								std::endl <<
								std::endl <<
								"Jonas Gehring <jonas.gehring@boolsoft.org>" <<
								std::endl <<
								"* Custom button actions for menus and icons" <<
								std::endl <<
								"* Better tokenization of settings statements" <<
								std::endl <<
								std::endl <<
								"Licensed under the MIT license:" <<
								std::endl <<
								"http://www.opensource.org/licenses/mit-license.php" <<
								std::endl;
							return 0;
						case 'r':
							if( !--argc )
								throw std::invalid_argument(
									"missing FILE argument" );
							settings.setConfigurationFile( *++argv );
							break;
						case 'm':
							if( argc > 1 &&
								**(argv+1) != '-' )
							{
								--argc;
								menuName = *++argv;
							}
							break;
					}
				else
					std::cerr << "skipping unknown argument \"" <<
						*argv << "\"" << std::endl;

			if( settings.getConfigurationFile().empty() )
				settings.setConfigurationFileFromBinary( binary );
		}

		switch( fork() )
		{
			default:
				// terminate parent process to detach from shell
				return 0;
			case 0:
				// pursue in child process
				break;
			case -1:
				throw std::runtime_error( "cannot fork" );
		}

		// always open display after fork
		PieDock::Application a( settings );

		// if another instance is already running, wake it
		if( a.remote( menuName ) )
			return 0;

		// obtain new process group
		setsid();

		signal( SIGCHLD, signalHandler );
		signal( SIGHUP, signalHandler );
		signal( SIGINT, signalHandler );
		signal( SIGTERM, signalHandler );

#ifdef HAVE_KDE
		int r = a.run( &stop );
		q.quit();
		return r;
#else
		return a.run( &stop );
#endif
	}
	catch( std::exception &e )
	{
		std::cerr << "error: " << e.what() << std::endl;

		return -1;
	}
}
<commit_msg>Init GTK/Qt after forking<commit_after>/*
 *   O         ,-
 *  ° o    . -´  '     ,-
 *   °  .´        ` . ´,´
 *     ( °   ))     . (
 *      `-;_    . -´ `.`.
 *          `._'       ´
 *
 * Copyright (c) 2007-2012 Markus Fisch <mf@markusfisch.de>
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 */
#ifdef HAVE_KDE
#include <QApplication>
#endif

#include "Application.h"

#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <libgen.h>
#include <stdlib.h>

#ifdef HAVE_GTK
#include <gtk/gtk.h>
#endif

#include <iostream>
#include <stdexcept>

bool stop = false;

/**
 * Signal handler
 *
 * @param id - signal id
 */
void signalHandler( int id )
{
	switch( id )
	{
		case SIGCHLD:
			// more than one process may have been terminated
			while( waitpid( -1, 0, WNOHANG | WUNTRACED ) > 0 );
			break;
		case SIGHUP:
		case SIGINT:
		case SIGTERM:
			stop = true;
			break;
	}

	return;
}

/**
 * Process entry
 *
 * @param argc - number of arguments
 * @param argv - pointer to pointers of arguments
 */
int main( int argc, char **argv )
{
	try
	{
		PieDock::Settings settings;
		char *menuName = 0;

		// parse arguments
		{
			char *binary = basename( *argv );

			while( --argc )
				if( **++argv == '-' )
					switch( *((*argv)+1) )
					{
						default:
							std::cerr << "Skipping unknown flag '" <<
								*((*argv)+1) << "'" << std::endl;
							break;
						case '?':
						case 'h':
							std::cout <<
								binary << " [hvrm]" << std::endl <<
								"\t-h         this help" << std::endl <<
								"\t-v         show version" << std::endl <<
								"\t-r FILE    path and name of alternative " <<
									"configuration file" << std::endl <<
								"\t-m [MENU]  show already running " <<
									"instance" << std::endl;
							return 0;
						case 'v':
							std::cout <<
								binary << " 1.6.4" <<
								std::endl <<
								"Copyright (c) 2007-2012" <<
								std::endl <<
								"Markus Fisch <mf@markusfisch.de>" <<
								std::endl <<
								std::endl <<
								"Tatiana Azundris <hacks@azundris.com>" <<
								std::endl <<
								"* Modifier masks for key control" <<
								std::endl <<
								std::endl <<
								"Jonas Gehring <jonas.gehring@boolsoft.org>" <<
								std::endl <<
								"* Custom button actions for menus and icons" <<
								std::endl <<
								"* Better tokenization of settings statements" <<
								std::endl <<
								std::endl <<
								"Licensed under the MIT license:" <<
								std::endl <<
								"http://www.opensource.org/licenses/mit-license.php" <<
								std::endl;
							return 0;
						case 'r':
							if( !--argc )
								throw std::invalid_argument(
									"missing FILE argument" );
							settings.setConfigurationFile( *++argv );
							break;
						case 'm':
							if( argc > 1 &&
								**(argv+1) != '-' )
							{
								--argc;
								menuName = *++argv;
							}
							break;
					}
				else
					std::cerr << "skipping unknown argument \"" <<
						*argv << "\"" << std::endl;

			if( settings.getConfigurationFile().empty() )
				settings.setConfigurationFileFromBinary( binary );
		}

		switch( fork() )
		{
			default:
				// terminate parent process to detach from shell
				return 0;
			case 0:
				// pursue in child process
				break;
			case -1:
				throw std::runtime_error( "cannot fork" );
		}

#ifdef HAVE_GTK
		gtk_init( &argc, &argv );
#endif

#ifdef HAVE_KDE
		QApplication q( argc, argv );
#endif

		// always open display after fork
		PieDock::Application a( settings );

		// if another instance is already running, wake it
		if( a.remote( menuName ) )
			return 0;

		// obtain new process group
		setsid();

		signal( SIGCHLD, signalHandler );
		signal( SIGHUP, signalHandler );
		signal( SIGINT, signalHandler );
		signal( SIGTERM, signalHandler );

#ifdef HAVE_KDE
		int r = a.run( &stop );
		q.quit();
		return r;
#else
		return a.run( &stop );
#endif
	}
	catch( std::exception &e )
	{
		std::cerr << "error: " << e.what() << std::endl;

		return -1;
	}
}
<|endoftext|>


<commit_before>//Author: Julian Yi
//Date Started: 14 July 2017, Friday.
//Purpose: This is a project to create a working chess engine and gui using C++.
//File: This is the main file.
#include <iostream>
#include "board.h"
#include "pawn.h"
#include "knight.h"
#include "bishop.h"
#include "coord.h"
#include "ui.h"
#include "BearLibTerminal.h"

void handleInput(board& Chessboard);

int main()
{
	// Initialize board.
	auto Chessboard = std::make_shared<board>();
	Chessboard->initializeBoard();

	for (int i = 0; i < 8; i++) {
		Chessboard->placePiece(PieceType::Pawn, {i, 1}, TeamColor::White);
	}

	Chessboard->placePiece(PieceType::Rook, {0, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Rook, {7, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Knight, {1, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Knight, {6, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, {2, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, {5, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Queen, {3, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::King, { 4,0 }, TeamColor::White);

	for (int i = 0; i < 8; i++) {
		Chessboard->placePiece(PieceType::Pawn, {i, 6}, TeamColor::Black);
	}
	Chessboard->placePiece(PieceType::Rook, {0, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Rook, {7, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Knight, {1, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Knight, {6, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Bishop, {2, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Bishop, {5, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Queen, {3, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::King, { 4,7 }, TeamColor::Black);

	Chessboard->placePiece(PieceType::Pawn, { 2,3 }, TeamColor::Black);

	Chessboard->movePiece({ 1,1 }, { 1,2 }); //success
	Chessboard->movePiece({ 1,2 }, { 2,3 }); //success
	Chessboard->movePiece({ 2,3 }, { 3,3 }); //fail

	Chessboard->placePiece(PieceType::Pawn, { 3,4 }, TeamColor::Black);
	Chessboard->movePiece({ 3,4 }, { 2,3 }); //success

	Chessboard->placePiece(PieceType::Pawn, { 1,2 }, TeamColor::White);
	Chessboard->movePiece({ 2,3 }, { 1,2 });
	//Chessboard->movePiece({ 1,2 }, { 0,1 });
	//Chessboard->movePiece({ 0,1 }, { 1,0 });
	//Chessboard->movePiece({ 1,1 }, { 1,0 });

	/*
	it all works
	// Test an attack.
	// Expected Output : success, knight is destroyed
	Chessboard->movePiece({3, 4}, {1, 2});

	// Test creating a piece into the occupied coordinate (same color)
	// Expected Output : failure
	Chessboard->placePiece(PieceType::Rook, { 3,3 }, TeamColor::White);
	Chessboard->placePiece(PieceType::Pawn, { 3,3 }, TeamColor::White);

	// Test creating a piece into the occupied coordinate (different color)
	// Expected Output : failure
	Chessboard->deletePiece({ 3,3 });
	Chessboard->placePiece(PieceType::Pawn, { 3,3 }, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, { 3,3 }, TeamColor::Black);

	// Test Moving a piece into the occupied coordinate (same color)
	// Expected Output : failure
	Chessboard->placePiece(PieceType::Pawn, { 3,2 }, TeamColor::White);
	Chessboard->movePiece({ 3,2 }, { 3,3 });
	*/

	// Test Pawn's valid moves

	// Open the terminal. Since no terminal_set() method is called,
	// the terminal will use default settings.
	terminal_open();

	// Font setup. ./font/FSEX300.ttf
	terminal_set("window: title='Chess', size='46x24'; font: ./font/FSEX300.ttf, size=32x32");

	// Palette.
	terminal_set("palette: whitepiece=#C2CCCF, blackpiece=#4D483C, whitetile=#02171F, blacktile=#000000;");

	terminal_set(
	    "input:"
	    "cursor-symbol = 0x1F,"
	    "cursor-blink-rate = 500,"
	    "precise-mouse = false,"
	    "mouse-cursor = true,"
	    "filter=[keyboard, mouse];"
	);

	// Print intro text.
	terminal_print(1, 1, "Chess Engine");
	terminal_print(4, 2, "by Julian Yi, Sean Brock, and Simon Kim");
	terminal_print(1, 4, "Press Enter to start...");
	terminal_refresh();

	// Create UI manager
	ui UIManager;
	// Register the chessboard in a board element.
	UIManager.addElement(std::make_shared<boardElement>(Chessboard), { 2, 5 });

	//roughdraft until I figure out a better way to do this
	int mouseClicks = 0;
	int xCursor = 0;
	int yCursor = 0;
	coord current = {0, 0};
	coord next = {0, 0};
	bool clicked = false;

	bool running = true;
	coord boardOffset{ 2, 5 };

	while (running) {
 		// Check for input. termnial_read() is blocking, meaning the
		// program will wait until it reads a key press.
		auto key = terminal_read();
		// Reset the terminal to blank state.
		terminal_clear();

		// Text goes on layer 3.
		terminal_layer(3);

		// Print instructions.
		//terminal_print(1, 1, "Press Enter to start...");

		// Handle key presses.
		switch (key) {
			case TK_CLOSE:
				running = false;
				break;
			case TK_ESCAPE:
				running = false;
				break;
			case TK_ENTER:
				break;
			case TK_MOUSE_MOVE:
				xCursor = terminal_state(TK_MOUSE_X);
		 		yCursor = terminal_state(TK_MOUSE_Y);
				break;
			case TK_MOUSE_LEFT:
				mouseClicks++; //amount of time something is clicked

				//if the clicked square has something then set the object clicked flag to true and set the current coordinate
				if (Chessboard->occupied({ (xCursor - boardOffset.x), (yCursor - boardOffset.y) }) == true && (mouseClicks == 1))
				{
					current = { (xCursor - boardOffset.x), (yCursor - boardOffset.y) };
					std::cout << "first click" << current.x << "," << current.y << std::endl;
					clicked = true;
					std::cout << mouseClicks;
				}
				//if clicked flag is false and there is nothing on the board don't do anything
				else if(Chessboard->occupied({ (xCursor - boardOffset.x), (yCursor - boardOffset.y) }) == false && clicked == false)
				{
					current = { -1, -1 };
					std::cout << "nothing was clicked" << std::endl;
					mouseClicks = 0;
				}
				//mouseClicks has to be higher than 1 to perform the move function. clicked flag also has to be true
				//handles move
				if(clicked == true && mouseClicks > 1)
				{
					//do something with that piece
					next = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
					std::cout << "second click" << next.x << "," << next.y << std::endl;
					Chessboard->movePiece(current, next);
					clicked = false;
					std::cout << mouseClicks;
					mouseClicks = 0;
				}
				break;
			default:
				terminal_print(1, 2, "The key pressed has no function.");
				break;
		}

		// Draw board
		UIManager.draw();

		if((2 <= xCursor && xCursor <=9) && (5 <= yCursor && yCursor <= 12))
		{
			int select = 0x02C7;
			terminal_layer(2);
			terminal_color(color_from_name("green"));
			terminal_put(xCursor, yCursor, select);
		}

			 	//TK_MOUSE_CLICK
		//set the flag
		//flag true then call something.
		/*
		if (key == TK_MOUSE_LEFT)
		{
			int mouseClicks = terminal_state(TK_MOUSE_LEFT);
			if(mouseClicks == 1)
			{
				//select the piece
				current = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
				std::cout << "first click" << current.x << "," << current.y << std::endl;
			}
			else if(mouseClicks == 2)
			{
				//do something with that piece
				next = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
				std::cout << "second click" << next.x << "," << next.y << std::endl;
				Chessboard->movePiece(current, next);
			}
		}
		*/

		// Commit the buffer and draw it.
		// Move to ui manager eventually.
		terminal_refresh();

	}

	// We're done here.
	terminal_close();

	return 0;
}
<commit_msg>LF again...<commit_after>//Author: Julian Yi
//Date Started: 14 July 2017, Friday.
//Purpose: This is a project to create a working chess engine and gui using C++.
//File: This is the main file.
#include <iostream>
#include "board.h"
#include "pawn.h"
#include "knight.h"
#include "bishop.h"
#include "coord.h"
#include "ui.h"
#include "BearLibTerminal.h"

void handleInput(board& Chessboard);

int main()
{
	// Initialize board.
	auto Chessboard = std::make_shared<board>();
	Chessboard->initializeBoard();

	for (int i = 0; i < 8; i++) {
		Chessboard->placePiece(PieceType::Pawn, {i, 1}, TeamColor::White);
	}

	Chessboard->placePiece(PieceType::Rook, {0, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Rook, {7, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Knight, {1, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Knight, {6, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, {2, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, {5, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::Queen, {3, 0}, TeamColor::White);
	Chessboard->placePiece(PieceType::King, { 4,0 }, TeamColor::White);

	for (int i = 0; i < 8; i++) {
		Chessboard->placePiece(PieceType::Pawn, {i, 6}, TeamColor::Black);
	}
	Chessboard->placePiece(PieceType::Rook, {0, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Rook, {7, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Knight, {1, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Knight, {6, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Bishop, {2, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Bishop, {5, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::Queen, {3, 7}, TeamColor::Black);
	Chessboard->placePiece(PieceType::King, { 4,7 }, TeamColor::Black);

	Chessboard->placePiece(PieceType::Pawn, { 2,3 }, TeamColor::Black);

	Chessboard->movePiece({ 1,1 }, { 1,2 }); //success
	Chessboard->movePiece({ 1,2 }, { 2,3 }); //success
	Chessboard->movePiece({ 2,3 }, { 3,3 }); //fail

	Chessboard->placePiece(PieceType::Pawn, { 3,4 }, TeamColor::Black);
	Chessboard->movePiece({ 3,4 }, { 2,3 }); //success

	Chessboard->placePiece(PieceType::Pawn, { 1,2 }, TeamColor::White);
	Chessboard->movePiece({ 2,3 }, { 1,2 });
	//Chessboard->movePiece({ 1,2 }, { 0,1 });
	//Chessboard->movePiece({ 0,1 }, { 1,0 });
	//Chessboard->movePiece({ 1,1 }, { 1,0 });

	/*
	it all works
	// Test an attack.
	// Expected Output : success, knight is destroyed
	Chessboard->movePiece({3, 4}, {1, 2});

	// Test creating a piece into the occupied coordinate (same color)
	// Expected Output : failure
	Chessboard->placePiece(PieceType::Rook, { 3,3 }, TeamColor::White);
	Chessboard->placePiece(PieceType::Pawn, { 3,3 }, TeamColor::White);

	// Test creating a piece into the occupied coordinate (different color)
	// Expected Output : failure
	Chessboard->deletePiece({ 3,3 });
	Chessboard->placePiece(PieceType::Pawn, { 3,3 }, TeamColor::White);
	Chessboard->placePiece(PieceType::Bishop, { 3,3 }, TeamColor::Black);

	// Test Moving a piece into the occupied coordinate (same color)
	// Expected Output : failure
	Chessboard->placePiece(PieceType::Pawn, { 3,2 }, TeamColor::White);
	Chessboard->movePiece({ 3,2 }, { 3,3 });
	*/

	// Test Pawn's valid moves

	// Open the terminal. Since no terminal_set() method is called,
	// the terminal will use default settings.
	terminal_open();

	// Font setup. ./font/FSEX300.ttf
	terminal_set("window: title='Chess', size='46x24'; font: ./font/FSEX300.ttf, size=32x32");

	// Palette.
	terminal_set("palette: whitepiece=#C2CCCF, blackpiece=#4D483C, whitetile=#02171F, blacktile=#000000;");

	terminal_set(
	    "input:"
	    "cursor-symbol = 0x1F,"
	    "cursor-blink-rate = 500,"
	    "precise-mouse = false,"
	    "mouse-cursor = true,"
	    "filter=[keyboard, mouse];"
	);

	// Print intro text.
	terminal_print(1, 1, "Chess Engine");
	terminal_print(4, 2, "by Julian Yi, Sean Brock, and Simon Kim");
	terminal_print(1, 4, "Press Enter to start...");
	terminal_refresh();

	// Create UI manager
	ui UIManager;
	// Register the chessboard in a board element.
	UIManager.addElement(std::make_shared<boardElement>(Chessboard), { 2, 5 });

	//roughdraft until I figure out a better way to do this
	int mouseClicks = 0;
	int xCursor = 0;
	int yCursor = 0;
	coord current = {0, 0};
	coord next = {0, 0};
	bool clicked = false;

	bool running = true;
	coord boardOffset{ 2, 5 };

	while (running) {
 		// Check for input. termnial_read() is blocking, meaning the
		// program will wait until it reads a key press.
		auto key = terminal_read();
		// Reset the terminal to blank state.
		terminal_clear();

		// Text goes on layer 3.
		terminal_layer(3);

		// Print instructions.
		//terminal_print(1, 1, "Press Enter to start...");

		// Handle key presses.
		switch (key) {
			case TK_CLOSE:
				running = false;
				break;
			case TK_ESCAPE:
				running = false;
				break;
			case TK_ENTER:
				break;
			case TK_MOUSE_MOVE:
				xCursor = terminal_state(TK_MOUSE_X);
		 		yCursor = terminal_state(TK_MOUSE_Y);
				break;
			case TK_MOUSE_LEFT:
				mouseClicks++; //amount of time something is clicked

				if ((2 <= xCursor && xCursor <= 9) && (5 <= yCursor && yCursor <= 12)){
				//if the clicked square has something then set the object clicked flag to true and set the current coordinate
					if (Chessboard->occupied({ (xCursor - boardOffset.x), (yCursor - boardOffset.y) }) == true && (mouseClicks == 1))
					{
						current = { (xCursor - boardOffset.x), (yCursor - boardOffset.y) };
						std::cout << "first click" << current.x << "," << current.y << std::endl;
						clicked = true;
						std::cout << mouseClicks;
					}
					//if clicked flag is false and there is nothing on the board don't do anything
					else if(Chessboard->occupied({ (xCursor - boardOffset.x), (yCursor - boardOffset.y) }) == false && clicked == false)
					{
						current = { -1, -1 };
						std::cout << "nothing was clicked" << std::endl;
						mouseClicks = 0;
					}
					//mouseClicks has to be higher than 1 to perform the move function. clicked flag also has to be true
					//handles move
					if(clicked == true && mouseClicks > 1)
					{
						//do something with that piece
						next = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
						std::cout << "second click" << next.x << "," << next.y << std::endl;
						Chessboard->movePiece(current, next);
						clicked = false;
						std::cout << mouseClicks;
						mouseClicks = 0;
					}
				}
				break;
			default:
				terminal_print(1, 2, "The key pressed has no function.");
				break;
		}

		// Draw board
		UIManager.draw();

		if((2 <= xCursor && xCursor <=9) && (5 <= yCursor && yCursor <= 12))
		{
			int select = 0x02C7;
			terminal_layer(2);
			terminal_color(color_from_name("green"));
			terminal_put(xCursor, yCursor, select);
		}

			 	//TK_MOUSE_CLICK
		//set the flag
		//flag true then call something.
		/*
		if (key == TK_MOUSE_LEFT)
		{
			int mouseClicks = terminal_state(TK_MOUSE_LEFT);
			if(mouseClicks == 1)
			{
				//select the piece
				current = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
				std::cout << "first click" << current.x << "," << current.y << std::endl;
			}
			else if(mouseClicks == 2)
			{
				//do something with that piece
				next = {(xCursor - boardOffset.x), (yCursor - boardOffset.y)};
				std::cout << "second click" << next.x << "," << next.y << std::endl;
				Chessboard->movePiece(current, next);
			}
		}
		*/

		// Commit the buffer and draw it.
		// Move to ui manager eventually.
		terminal_refresh();

	}

	// We're done here.
	terminal_close();

	return 0;
}
<|endoftext|>


<commit_before>#include "precompiled.h"

sgct::Engine *gEngine;
Scene *scene;

void initOpenGL();
void calcPhysics();
void drawScene();
void keyCallback(int key, int action);

bool stop = false;

int main( int argc, char* argv[] )
{
    // Allocate
    gEngine = new sgct::Engine( argc, argv );
    scene = new Scene();

    // Bind your functions
    gEngine->setInitOGLFunction( initOpenGL );
    gEngine->setPreSyncFunction( calcPhysics );
    gEngine->setDrawFunction( drawScene );
    gEngine->setKeyboardCallbackFunction( keyCallback );

    // Init the engine
    if( !gEngine->init() )
    {
        delete gEngine;
        return EXIT_FAILURE;
    }

    // Main loop
    gEngine->render();

    delete gEngine;

    exit( EXIT_SUCCESS );
}

void initOpenGL()
{
    // Dynamic objects
    // RigidBody *rb1 = new RigidBody(glm::vec2(0.0f, 0.0f), 0.0f, new Circle(0.2f));
    // rb1->_isStatic = true;

    // Ground
    RigidBody *rb3 = new RigidBody(glm::vec2(0.0f, -0.8f), 0.0f, new Box(2.4f, 0.2f));
    rb3->_isStatic = true;

    // // Fence
    RigidBody *rb4 = new RigidBody(glm::vec2(-1.1f, -0.2), 0.0f, new Box(0.2f, 0.5f));
    rb4->_isStatic = true;
    RigidBody *rb5 = new RigidBody(glm::vec2(1.1f, -0.2), 0.0f, new Box(0.2f, 0.5f));
    rb5->_isStatic = true;

    // scene->addBody(rb1);
    scene->addBody(rb3);
    scene->addBody(rb4);
    scene->addBody(rb5);

    int sign = 1;
    for (float f = 0.8f; f < 5.0f; f += 0.2f)
    {
        sign *= -1;
        float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
        RigidBody *temp = new RigidBody(glm::vec2(sign * 0.2f + r * 0.01f, f), 0.0f, new Circle(0.1f));
        scene->addBody(temp);
    }
}

void calcPhysics()
{
    // scene->step();
}

void drawScene()
{
    scene->step();
    scene->draw();
}

void keyCallback(int key, int action)
{
    // TODO
}
<commit_msg>Added onclick spawn circle<commit_after>#include "precompiled.h"

sgct::Engine *gEngine;
Scene *scene;

void initOpenGL();
void calcPhysics();
void drawScene();
void keyCallback(int key, int action);
void mouseCallback(int button, int action);

bool stop = false;
bool mouseLeftButton = false;
double  mousePos[] = {0.0f, 0.0f};

int main( int argc, char* argv[] )
{
    // Allocate
    gEngine = new sgct::Engine( argc, argv );
    scene = new Scene();

    // Bind your functions
    gEngine->setInitOGLFunction( initOpenGL );
    gEngine->setPreSyncFunction( calcPhysics );
    gEngine->setDrawFunction( drawScene );
    gEngine->setKeyboardCallbackFunction( keyCallback );
    gEngine->setMouseButtonCallbackFunction( mouseCallback );

    // Init the engine
    if( !gEngine->init() )
    {
        delete gEngine;
        return EXIT_FAILURE;
    }

    // Main loop
    gEngine->render();

    delete gEngine;

    exit( EXIT_SUCCESS );
}

void initOpenGL()
{
    // Dynamic objects
    // RigidBody *rb1 = new RigidBody(glm::vec2(0.0f, 0.0f), 0.0f, new Circle(0.2f));
    // rb1->_isStatic = true;

    // Ground
    RigidBody *rb3 = new RigidBody(glm::vec2(0.0f, -0.8f), 0.0f, new Box(2.4f, 0.2f));
    rb3->_isStatic = true;

    // // Fence
    RigidBody *rb4 = new RigidBody(glm::vec2(-1.1f, -0.2), 0.0f, new Box(0.2f, 0.5f));
    rb4->_isStatic = true;
    RigidBody *rb5 = new RigidBody(glm::vec2(1.1f, -0.2), 0.0f, new Box(0.2f, 0.5f));
    rb5->_isStatic = true;

    // scene->addBody(rb1);
    scene->addBody(rb3);
    scene->addBody(rb4);
    scene->addBody(rb5);

    int sign = 1;
    for (float f = 0.8f; f < 5.0f; f += 0.2f)
    {
        sign *= -1;
        float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
        RigidBody *temp = new RigidBody(glm::vec2(sign * 0.2f + r * 0.01f, f), 0.0f, new Circle(0.1f));
        scene->addBody(temp);
    }
}

void calcPhysics()
{
    // scene->step();
}

void drawScene()
{
    scene->step();
    scene->draw();
}

void mouseCallback(int button, int action)
{
    switch(button)
    {
        case GLFW_MOUSE_BUTTON_LEFT:
            mouseLeftButton = (action == GLFW_PRESS ? true : false);
            if(mouseLeftButton == true)
            {
                sgct::Engine::getMousePos(0, &mousePos[0], &mousePos[1]);
                double tempX = (mousePos[0]/960 - 0.5) * 3.56;
                double tempY = (-mousePos[1]/540 + 0.5) * 2;
                RigidBody *temp1 = new RigidBody(glm::vec2(tempX, tempY), 0.0f, new Circle(0.1f));
                scene->addBody(temp1);
            }
        break;
    }
}

void keyCallback(int key, int action)
{
    // TODO
}
<|endoftext|>