<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QStandardPaths>
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickItem>
#include <QDir>
#include <QMenu>
#include <QAction>
#include <QDesktopServices>
#include <QCloseEvent>
#include <QSystemTrayIcon>
#include <QMessageBox>

#include <QtQml/qqml.h>
#include "wqmlfile.h"
#include "wqmlsystem.h"

mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::mainWindow){
    ui->setupUi(this);

    appConfig();
    addTrayIcon();
    addQmlApis();

    addTreeRightClickMenu();
    openWidgetsInFile();
}

mainWindow::~mainWindow()
{
    delete ui;
}

void mainWindow::addQmlApis(){
    qmlRegisterType<wqmlfile>("com.widgetci.file", 1, 0, "WFile");
    qmlRegisterType<wqmlsystem>("com.widgetci.system", 1, 0, "WSystem");
}

void mainWindow::openWidgetsInFile(){
    widgetsDataSettings = new QSettings(appDataDir + "/widgets.ini", QSettings::IniFormat);

    int count = 0;
    for(auto e : widgetsDataSettings->childGroups()){
        widgetsDataSettings->beginGroup(e);
        int wx = widgetsDataSettings->value("x", -1000).toInt();
        int wy = widgetsDataSettings->value("y", -1000).toInt();
        bool visible = widgetsDataSettings->value("visible", false).toBool();
        widgetsDataSettings->endGroup();

        if(visible){
            toggleWidget(e, wx, wy);
            count++;
        }
    }
    if(count == 0) this->show(); // if no widgets visible, show the form.
}

// Toggle widgets
void mainWindow::toggleWidget(QTreeWidgetItem *item, int wx = -1000, int wy = -1000){
    QString wid_filename = item->text(0);

    // If widget not exists. Create one.
    if(!map_widgetList.contains(wid_filename)){

        // Load configs about the widget
        QMap<QString, QVariant> widConf = getWidgetSettings(item->text(0));

        //Check if has spesific coordinates
        if(wx == -1000 || wy == -1000){
            wx = widConf["x"].toInt();
            wy = widConf["y"].toInt();
        }

        // Add the widget
        WWidget *wid = new WWidget(QUrl::fromLocalFile(widgetsDir + "/" + wid_filename + "/main.qml"), wid_filename, wx, wy);
        wid->toggleZPos(widConf["z-pos"].toInt());
        wid->widgetSettings = widgetsDataSettings;

        // Check for errors. (File not found etc...)
        if( wid->status() == QQuickView::Error ){

            QString errorString = "";
            for (int i = 0; i < wid->errors().length(); ++i) {
                errorString.append(wid->errors().at(i).toString());
            }
            errorString.append(tr("\n\nPlease try to fix the error and refresh the list"));

            item->setBackground(0, QBrush(QColor(160,0,0,255)));
            item->setTextColor(0, QColor(180, 180, 180, 255));
            item->setSelected(false);

            QMessageBox::warning(this, tr("An error occured"), errorString, QMessageBox::Ok);
            return;
        }else if(wid->status() == QQuickView::Ready){
            item->setBackground(0, QBrush(QColor(0,0,0,0)));
        }

        map_widgetList.insert(wid->filename, wid);

        item->setIcon(0, ico_toggleon);
        item->setTextColor(0, colorOn);

        // Delete the widget from list when destroyed
        disconnect(wid, &QQuickWindow::destroyed, 0, 0);
        connect(wid, &QQuickWindow::destroyed, [=]{
            if(map_widgetList.contains(wid->filename)){
                if(!CLOSING) saveWidgetSettings(wid->filename); // Save settings before closing the widgets.

                map_widgetList.remove(wid->filename);

                QList<QTreeWidgetItem *> item_lst = obj_widgetList->findItems(wid->filename, Qt::MatchExactly, 0);
                if(item_lst.length() > 0){
                    item_lst[0]->setTextColor(0, colorOff);
                    item_lst[0]->setIcon(0, ico_toggleoff);
                }
            }
        });

    }else if(map_widgetList.contains(wid_filename)){
        delete map_widgetList[wid_filename];
    }
}
void mainWindow::toggleWidget(QString widgetName, int wx = -1000, int wy = -1000){
    QList <QTreeWidgetItem *> items = obj_widgetList->findItems(widgetName, Qt::MatchExactly, 0);
    if(items.length() > 0){
        toggleWidget(items[0], wx, wy);
    }
}

QMap<QString, QVariant> mainWindow::getWidgetSettings(QString widgetname){
    QMap<QString, QVariant> mapTmp;

    widgetsDataSettings->beginGroup(widgetname);
    mapTmp["x"] = widgetsDataSettings->value("x", -1000);
    mapTmp["y"] = widgetsDataSettings->value("y", -1000);
    mapTmp["visible"] = widgetsDataSettings->value("visible", false);
    mapTmp["z-pos"] = widgetsDataSettings->value("z-pos", 0);
    mapTmp["lock"] = widgetsDataSettings->value("lock", false);
    widgetsDataSettings->endGroup();

    return mapTmp;
}

void mainWindow::saveWidgetSettings(QString widgetname){
    widgetsDataSettings->beginGroup(widgetname);
    widgetsDataSettings->setValue("x", map_widgetList[widgetname]->x());
    widgetsDataSettings->setValue("y", map_widgetList[widgetname]->y());
    widgetsDataSettings->setValue("visible", map_widgetList[widgetname]->isVisible());
    widgetsDataSettings->setValue("z-pos", map_widgetList[widgetname]->z_pos);
    widgetsDataSettings->endGroup();
    widgetsDataSettings->sync();
}

void mainWindow::updateWidgetList(QTreeWidget* widgetList_obj){
    QMap<QString, WWidget *> tmpWidgetsMap(map_widgetList);
    widgetList_obj->clear();

    QDir dir(widgetsDir);
    QStringList folderList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

    // Close all widgets (to open just available ones later)
    for(QString e : map_widgetList.keys()){
        delete map_widgetList.value(e);
    }

    // Add folders one by one
    for(int i=0; i<folderList.length(); i++){
        QString folder = folderList.at(i);

        QTreeWidgetItem* item = new QTreeWidgetItem(widgetList_obj);
        item->setText(0, folder);
        item->setIcon(0, ico_toggleoff);

        if(tmpWidgetsMap.contains(folder)){
            toggleWidget(folder);
            //item->setIcon(0, ico_toggleon);
        }
    }

    // Enable|Disable widgets by double clicking on themauto
    disconnect(widgetList_obj, &QTreeWidget::itemActivated, 0, 0); // prevent multiple connections & runs
    connect(widgetList_obj, &QTreeWidget::itemActivated, [=](QTreeWidgetItem* item) {
        toggleWidget(item);
    });
}

void mainWindow::addTreeRightClickMenu(){
    // Initialize the variables
    ico_toggleoff = QIcon(":/img/toggleoff.png");
    ico_toggleon = QIcon(":/img/toggleon.png");
    colorOn = QColor(0, 230, 0, 255);
    colorOff = QColor(255, 255, 255, 255);

    // QTreeWidget list object from ui:
    obj_widgetList = ui->obj_widgetList;

    // Update & Refresh the widgets
    updateWidgetList(obj_widgetList);

    // Right Click Menu
    obj_widgetList->setContextMenuPolicy(Qt::CustomContextMenu);
    menu_wlRightClick = new QMenu(this);

    // Right Click Menu Actions
    QAction* act_wlrc_ShowHide = new QAction(tr("Show"), this);
    connect(act_wlrc_ShowHide, &QAction::triggered, [=]{
        // Show/Hide Action
        toggleWidget(obj_widgetList->currentItem());
    });
    QAction* act_wlrc_Edit = new QAction(tr("Edit"), this);
    connect(act_wlrc_Edit, &QAction::triggered, [=]{
        // Edit the widget file with default editor
        QDesktopServices::openUrl(QUrl::fromLocalFile(widgetsDir + "/" + obj_widgetList->currentItem()->text(0) + "/main.qml"));
    });
    QAction* act_wlrc_Reload = new QAction(tr("Reload"), this);
    connect(act_wlrc_Reload, &QAction::triggered, [=]{
        // Reload the widget
        if(map_widgetList.contains(obj_widgetList->currentItem()->text(0)))
            map_widgetList.value(obj_widgetList->currentItem()->text(0))->reload();
    });
    QAction* act_wlrc_RefreshTheList = new QAction(tr("Refresh the list"), this);
    connect(act_wlrc_RefreshTheList, &QAction::triggered, [=]{
        // Refresh all the list.
        updateWidgetList(obj_widgetList);
    });
    QAction* act_wlrc_Delete = new QAction(tr("Remove"), this);
    connect(act_wlrc_Delete, &QAction::triggered, [=]{
        if(map_widgetList.contains(obj_widgetList->currentItem()->text(0)))
            toggleWidget(obj_widgetList->currentItem()->text(0));
        delete obj_widgetList->currentItem();
        obj_widgetList->clearSelection();
    });
    QAction* act_wlrc_DeleteDisk = new QAction(tr("Delete From Disk..."), this);
    connect(act_wlrc_DeleteDisk, &QAction::triggered, [=]{
        int answer = QMessageBox::warning(this, tr("Warning"), tr("The '%1' folder will be deleted from disk.\n\nAre you sure?").arg(obj_widgetList->currentItem()->text(0)), QMessageBox::Cancel | QMessageBox::Ok);
        if(answer == QMessageBox::Ok){
            QDir folder(widgetsDir + "/" + obj_widgetList->currentItem()->text(0));
            if(folder.removeRecursively()){
                QMessageBox::information(this, tr("Information"), tr("The folder has been deleted successfully."), QMessageBox::Ok);
                if(map_widgetList.contains(obj_widgetList->currentItem()->text(0))){
                    toggleWidget(obj_widgetList->currentItem()->text(0));
                    updateWidgetList(obj_widgetList);
                }

            }else{
                QMessageBox::critical(this, tr("Information"), tr("The folder couldn't be removed.\nCheck the folder and the files may be using by another program."), QMessageBox::Ok);
            }

        }
    });

    // Add Actions to the QTreeWidget's Right Click Menu
    menu_wlRightClick->addAction(act_wlrc_ShowHide);
    menu_wlRightClick->addSeparator();
    menu_wlRightClick->addAction(act_wlrc_Reload);
    menu_wlRightClick->addAction(act_wlrc_Edit);
    menu_wlRightClick->addAction(act_wlrc_RefreshTheList);
    menu_wlRightClick->addSeparator();
    menu_wlRightClick->addAction(act_wlrc_Delete);
    menu_wlRightClick->addAction(act_wlrc_DeleteDisk);
    connect(obj_widgetList, &QTreeWidget::customContextMenuRequested, [=](const QPoint & pos) {
        QPoint pt(pos);
        pt.setX(pt.x()+2);
        pt.setY(pt.y()+22);

        QTreeWidgetItem *item = obj_widgetList->currentItem();
        QString wid_filename = item->text(0);
        if(!map_widgetList.contains(wid_filename)){
            act_wlrc_ShowHide->setText(tr("Show"));
            act_wlrc_Reload->setEnabled(false);
        }else if(map_widgetList.contains(wid_filename)){
            act_wlrc_ShowHide->setText(tr("Hide"));
            act_wlrc_Reload->setEnabled(true);
        }

        menu_wlRightClick->exec( obj_widgetList->mapToGlobal(pt) );
    });
}

void mainWindow::addActionsToTray(){
    // Create Menu & Items
    trayMenu = new QMenu(this);
    QAction* openManager = new QAction(tr("Open Manager..."), this);
    QAction* reloadAll = new QAction(tr("Reload All"), this);
    QAction* quit = new QAction(tr("Quit"), this);

    trayMenu->addAction(openManager);
    trayMenu->addAction(reloadAll);
    trayMenu->addSeparator();
    trayMenu->addAction(quit);

    // Connect
    connect(openManager, &QAction::triggered, [=]{
        this->setVisible(true);
        this->raise();
        QApplication::setActiveWindow(this);
    });
    connect(reloadAll, &QAction::triggered, [=]{
        for(auto e : map_widgetList.keys()){
          map_widgetList.value(e)->reload();
        }
    });
    connect(quit, &QAction::triggered, [=]{
        onAppQuit();
    });
}

void mainWindow::addTrayIcon(){
    // Add actions
    addActionsToTray();

    // Set the app icon
    appIcon = new QIcon(":/img/icon.png");
    setWindowIcon(*appIcon);

    // Set the tray
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayMenu);
    trayIcon->setIcon(*appIcon);
    trayIcon->show();
    connect(trayIcon, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason){
        if(reason == QSystemTrayIcon::DoubleClick){
            this->setVisible(true);
            this->raise();
            QApplication::setActiveWindow(this);
        }
    });

}

void mainWindow::appConfig(){
    // Set directory variables.
    appDataDir = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0];
    widgetsDir = appDataDir + "/widgets";

    // Create the directory if not exists.
    QDir dir(widgetsDir);
    if(!dir.exists()){
        QDir localdir(":/widgets/defaultwidgets/");
        QStringList folderList = localdir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

        // Copy the local folders one by one
        QFile file;
        for(int i=0; i<folderList.length(); i++){
            QString folder = folderList.at(i);

            //qDebug() << localdir.path() + folder << widgetsDir + "/" + folder;
            dir.mkpath(widgetsDir + "/" + folder);

            // Copy the files inside folder
            QDir filedir(localdir.path() + "/" + folder);
            QStringList filelist = filedir.entryList(QDir::Files | QDir::NoDotAndDotDot);
            for (int a = 0; a < filelist.length(); ++a) {

                QString fileSrc = localdir.path() + "/" + folder + "/" + filelist.at(a);
                QString fileTarget = widgetsDir + "/" + folder + "/" + filelist.at(a);

                // Copy the file
                file.copy( fileSrc , fileTarget );
                // Set permissions Readable and Writeable.
                file.setPermissions(fileTarget, QFileDevice::ReadOther | QFileDevice::WriteOther | QFileDevice::ExeGroup);
            }
        }
    }
}

void mainWindow::on_obj_showFolderBtn_clicked(){
    QDesktopServices::openUrl(widgetsDir);
}

void mainWindow::on_obj_refreshWidgetListBtn_clicked(){
    updateWidgetList(ui->obj_widgetList);
}

// Before the app quit
void mainWindow::onAppQuit(){
    CLOSING = true;

    // Close the widgets too.
    for(auto e : map_widgetList.keys()){
        // Save widget configs.
        saveWidgetSettings(e);

        // Destroy them.
        delete map_widgetList.value(e);
    }
    QApplication::quit();
}

// Window Close Event
void mainWindow::closeEvent(QCloseEvent *event){
    event->ignore();
    this->setVisible(false);
}
<commit_msg>Copied Widget Files permissions fixed.<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QStandardPaths>
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickItem>
#include <QDir>
#include <QMenu>
#include <QAction>
#include <QDesktopServices>
#include <QCloseEvent>
#include <QSystemTrayIcon>
#include <QMessageBox>

#include <QtQml/qqml.h>
#include "wqmlfile.h"
#include "wqmlsystem.h"

mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::mainWindow){
    ui->setupUi(this);

    appConfig();
    addTrayIcon();
    addQmlApis();

    addTreeRightClickMenu();
    openWidgetsInFile();
}

mainWindow::~mainWindow()
{
    delete ui;
}

void mainWindow::addQmlApis(){
    qmlRegisterType<wqmlfile>("com.widgetci.file", 1, 0, "WFile");
    qmlRegisterType<wqmlsystem>("com.widgetci.system", 1, 0, "WSystem");
}

void mainWindow::openWidgetsInFile(){
    widgetsDataSettings = new QSettings(appDataDir + "/widgets.ini", QSettings::IniFormat);

    int count = 0;
    for(auto e : widgetsDataSettings->childGroups()){
        widgetsDataSettings->beginGroup(e);
        int wx = widgetsDataSettings->value("x", -1000).toInt();
        int wy = widgetsDataSettings->value("y", -1000).toInt();
        bool visible = widgetsDataSettings->value("visible", false).toBool();
        widgetsDataSettings->endGroup();

        if(visible){
            toggleWidget(e, wx, wy);
            count++;
        }
    }
    if(count == 0) this->show(); // if no widgets visible, show the form.
}

// Toggle widgets
void mainWindow::toggleWidget(QTreeWidgetItem *item, int wx = -1000, int wy = -1000){
    QString wid_filename = item->text(0);

    // If widget not exists. Create one.
    if(!map_widgetList.contains(wid_filename)){

        // Load configs about the widget
        QMap<QString, QVariant> widConf = getWidgetSettings(item->text(0));

        //Check if has spesific coordinates
        if(wx == -1000 || wy == -1000){
            wx = widConf["x"].toInt();
            wy = widConf["y"].toInt();
        }

        // Add the widget
        WWidget *wid = new WWidget(QUrl::fromLocalFile(widgetsDir + "/" + wid_filename + "/main.qml"), wid_filename, wx, wy);
        wid->toggleZPos(widConf["z-pos"].toInt());
        wid->widgetSettings = widgetsDataSettings;

        // Check for errors. (File not found etc...)
        if( wid->status() == QQuickView::Error ){

            QString errorString = "";
            for (int i = 0; i < wid->errors().length(); ++i) {
                errorString.append(wid->errors().at(i).toString());
            }
            errorString.append(tr("\n\nPlease try to fix the error and refresh the list"));

            item->setBackground(0, QBrush(QColor(160,0,0,255)));
            item->setTextColor(0, QColor(180, 180, 180, 255));
            item->setSelected(false);

            QMessageBox::warning(this, tr("An error occured"), errorString, QMessageBox::Ok);
            return;
        }else if(wid->status() == QQuickView::Ready){
            item->setBackground(0, QBrush(QColor(0,0,0,0)));
        }

        map_widgetList.insert(wid->filename, wid);

        item->setIcon(0, ico_toggleon);
        item->setTextColor(0, colorOn);

        // Delete the widget from list when destroyed
        disconnect(wid, &QQuickWindow::destroyed, 0, 0);
        connect(wid, &QQuickWindow::destroyed, [=]{
            if(map_widgetList.contains(wid->filename)){
                if(!CLOSING) saveWidgetSettings(wid->filename); // Save settings before closing the widgets.

                map_widgetList.remove(wid->filename);

                QList<QTreeWidgetItem *> item_lst = obj_widgetList->findItems(wid->filename, Qt::MatchExactly, 0);
                if(item_lst.length() > 0){
                    item_lst[0]->setTextColor(0, colorOff);
                    item_lst[0]->setIcon(0, ico_toggleoff);
                }
            }
        });

    }else if(map_widgetList.contains(wid_filename)){
        delete map_widgetList[wid_filename];
    }
}
void mainWindow::toggleWidget(QString widgetName, int wx = -1000, int wy = -1000){
    QList <QTreeWidgetItem *> items = obj_widgetList->findItems(widgetName, Qt::MatchExactly, 0);
    if(items.length() > 0){
        toggleWidget(items[0], wx, wy);
    }
}

QMap<QString, QVariant> mainWindow::getWidgetSettings(QString widgetname){
    QMap<QString, QVariant> mapTmp;

    widgetsDataSettings->beginGroup(widgetname);
    mapTmp["x"] = widgetsDataSettings->value("x", -1000);
    mapTmp["y"] = widgetsDataSettings->value("y", -1000);
    mapTmp["visible"] = widgetsDataSettings->value("visible", false);
    mapTmp["z-pos"] = widgetsDataSettings->value("z-pos", 0);
    mapTmp["lock"] = widgetsDataSettings->value("lock", false);
    widgetsDataSettings->endGroup();

    return mapTmp;
}

void mainWindow::saveWidgetSettings(QString widgetname){
    widgetsDataSettings->beginGroup(widgetname);
    widgetsDataSettings->setValue("x", map_widgetList[widgetname]->x());
    widgetsDataSettings->setValue("y", map_widgetList[widgetname]->y());
    widgetsDataSettings->setValue("visible", map_widgetList[widgetname]->isVisible());
    widgetsDataSettings->setValue("z-pos", map_widgetList[widgetname]->z_pos);
    widgetsDataSettings->endGroup();
    widgetsDataSettings->sync();
}

void mainWindow::updateWidgetList(QTreeWidget* widgetList_obj){
    QMap<QString, WWidget *> tmpWidgetsMap(map_widgetList);
    widgetList_obj->clear();

    QDir dir(widgetsDir);
    QStringList folderList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

    // Close all widgets (to open just available ones later)
    for(QString e : map_widgetList.keys()){
        delete map_widgetList.value(e);
    }

    // Add folders one by one
    for(int i=0; i<folderList.length(); i++){
        QString folder = folderList.at(i);

        QTreeWidgetItem* item = new QTreeWidgetItem(widgetList_obj);
        item->setText(0, folder);
        item->setIcon(0, ico_toggleoff);

        if(tmpWidgetsMap.contains(folder)){
            toggleWidget(folder);
            //item->setIcon(0, ico_toggleon);
        }
    }

    // Enable|Disable widgets by double clicking on themauto
    disconnect(widgetList_obj, &QTreeWidget::itemActivated, 0, 0); // prevent multiple connections & runs
    connect(widgetList_obj, &QTreeWidget::itemActivated, [=](QTreeWidgetItem* item) {
        toggleWidget(item);
    });
}

void mainWindow::addTreeRightClickMenu(){
    // Initialize the variables
    ico_toggleoff = QIcon(":/img/toggleoff.png");
    ico_toggleon = QIcon(":/img/toggleon.png");
    colorOn = QColor(0, 230, 0, 255);
    colorOff = QColor(255, 255, 255, 255);

    // QTreeWidget list object from ui:
    obj_widgetList = ui->obj_widgetList;

    // Update & Refresh the widgets
    updateWidgetList(obj_widgetList);

    // Right Click Menu
    obj_widgetList->setContextMenuPolicy(Qt::CustomContextMenu);
    menu_wlRightClick = new QMenu(this);

    // Right Click Menu Actions
    QAction* act_wlrc_ShowHide = new QAction(tr("Show"), this);
    connect(act_wlrc_ShowHide, &QAction::triggered, [=]{
        // Show/Hide Action
        toggleWidget(obj_widgetList->currentItem());
    });
    QAction* act_wlrc_Edit = new QAction(tr("Edit"), this);
    connect(act_wlrc_Edit, &QAction::triggered, [=]{
        // Edit the widget file with default editor
        QDesktopServices::openUrl(QUrl::fromLocalFile(widgetsDir + "/" + obj_widgetList->currentItem()->text(0) + "/main.qml"));
    });
    QAction* act_wlrc_Reload = new QAction(tr("Reload"), this);
    connect(act_wlrc_Reload, &QAction::triggered, [=]{
        // Reload the widget
        if(map_widgetList.contains(obj_widgetList->currentItem()->text(0)))
            map_widgetList.value(obj_widgetList->currentItem()->text(0))->reload();
    });
    QAction* act_wlrc_RefreshTheList = new QAction(tr("Refresh the list"), this);
    connect(act_wlrc_RefreshTheList, &QAction::triggered, [=]{
        // Refresh all the list.
        updateWidgetList(obj_widgetList);
    });
    QAction* act_wlrc_Delete = new QAction(tr("Remove"), this);
    connect(act_wlrc_Delete, &QAction::triggered, [=]{
        if(map_widgetList.contains(obj_widgetList->currentItem()->text(0)))
            toggleWidget(obj_widgetList->currentItem()->text(0));
        delete obj_widgetList->currentItem();
        obj_widgetList->clearSelection();
    });
    QAction* act_wlrc_DeleteDisk = new QAction(tr("Delete From Disk..."), this);
    connect(act_wlrc_DeleteDisk, &QAction::triggered, [=]{
        int answer = QMessageBox::warning(this, tr("Warning"), tr("The '%1' folder will be deleted from disk.\n\nAre you sure?").arg(obj_widgetList->currentItem()->text(0)), QMessageBox::Cancel | QMessageBox::Ok);
        if(answer == QMessageBox::Ok){
            QDir folder(widgetsDir + "/" + obj_widgetList->currentItem()->text(0));
            if(folder.removeRecursively()){
                QMessageBox::information(this, tr("Information"), tr("The folder has been deleted successfully."), QMessageBox::Ok);
                if(map_widgetList.contains(obj_widgetList->currentItem()->text(0))){
                    toggleWidget(obj_widgetList->currentItem()->text(0));
                    updateWidgetList(obj_widgetList);
                }

            }else{
                QMessageBox::critical(this, tr("Information"), tr("The folder couldn't be removed.\nCheck the folder and the files may be using by another program."), QMessageBox::Ok);
            }

        }
    });

    // Add Actions to the QTreeWidget's Right Click Menu
    menu_wlRightClick->addAction(act_wlrc_ShowHide);
    menu_wlRightClick->addSeparator();
    menu_wlRightClick->addAction(act_wlrc_Reload);
    menu_wlRightClick->addAction(act_wlrc_Edit);
    menu_wlRightClick->addAction(act_wlrc_RefreshTheList);
    menu_wlRightClick->addSeparator();
    menu_wlRightClick->addAction(act_wlrc_Delete);
    menu_wlRightClick->addAction(act_wlrc_DeleteDisk);
    connect(obj_widgetList, &QTreeWidget::customContextMenuRequested, [=](const QPoint & pos) {
        QPoint pt(pos);
        pt.setX(pt.x()+2);
        pt.setY(pt.y()+22);

        QTreeWidgetItem *item = obj_widgetList->currentItem();
        QString wid_filename = item->text(0);
        if(!map_widgetList.contains(wid_filename)){
            act_wlrc_ShowHide->setText(tr("Show"));
            act_wlrc_Reload->setEnabled(false);
        }else if(map_widgetList.contains(wid_filename)){
            act_wlrc_ShowHide->setText(tr("Hide"));
            act_wlrc_Reload->setEnabled(true);
        }

        menu_wlRightClick->exec( obj_widgetList->mapToGlobal(pt) );
    });
}

void mainWindow::addActionsToTray(){
    // Create Menu & Items
    trayMenu = new QMenu(this);
    QAction* openManager = new QAction(tr("Open Manager..."), this);
    QAction* reloadAll = new QAction(tr("Reload All"), this);
    QAction* quit = new QAction(tr("Quit"), this);

    trayMenu->addAction(openManager);
    trayMenu->addAction(reloadAll);
    trayMenu->addSeparator();
    trayMenu->addAction(quit);

    // Connect
    connect(openManager, &QAction::triggered, [=]{
        this->setVisible(true);
        this->raise();
        QApplication::setActiveWindow(this);
    });
    connect(reloadAll, &QAction::triggered, [=]{
        for(auto e : map_widgetList.keys()){
          map_widgetList.value(e)->reload();
        }
    });
    connect(quit, &QAction::triggered, [=]{
        onAppQuit();
    });
}

void mainWindow::addTrayIcon(){
    // Add actions
    addActionsToTray();

    // Set the app icon
    appIcon = new QIcon(":/img/icon.png");
    setWindowIcon(*appIcon);

    // Set the tray
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayMenu);
    trayIcon->setIcon(*appIcon);
    trayIcon->show();
    connect(trayIcon, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason){
        if(reason == QSystemTrayIcon::DoubleClick){
            this->setVisible(true);
            this->raise();
            QApplication::setActiveWindow(this);
        }
    });

}

void mainWindow::appConfig(){
    // Set directory variables.
    appDataDir = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0];
    widgetsDir = appDataDir + "/widgets";

    // Create the directory if not exists.
    QDir dir(widgetsDir);
    if(!dir.exists()){
        QDir localdir(":/widgets/defaultwidgets/");
        QStringList folderList = localdir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

        // Copy the local folders one by one
        QFile file;
        for(int i=0; i<folderList.length(); i++){
            QString folder = folderList.at(i);

            //qDebug() << localdir.path() + folder << widgetsDir + "/" + folder;
            dir.mkpath(widgetsDir + "/" + folder);

            // Copy the files inside folder
            QDir filedir(localdir.path() + "/" + folder);
            QStringList filelist = filedir.entryList(QDir::Files | QDir::NoDotAndDotDot);
            for (int a = 0; a < filelist.length(); ++a) {

                QString fileSrc = localdir.path() + "/" + folder + "/" + filelist.at(a);
                QString fileTarget = widgetsDir + "/" + folder + "/" + filelist.at(a);

                // Copy the file
                file.copy( fileSrc , fileTarget );
                // Set permissions Readable and Writeable.
                file.setPermissions(fileTarget, QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ReadUser | QFileDevice::WriteUser | QFileDevice::ReadGroup | QFileDevice::WriteGroup);
            }
        }
    }
}

void mainWindow::on_obj_showFolderBtn_clicked(){
    QDesktopServices::openUrl(widgetsDir);
}

void mainWindow::on_obj_refreshWidgetListBtn_clicked(){
    updateWidgetList(ui->obj_widgetList);
}

// Before the app quit
void mainWindow::onAppQuit(){
    CLOSING = true;

    // Close the widgets too.
    for(auto e : map_widgetList.keys()){
        // Save widget configs.
        saveWidgetSettings(e);

        // Destroy them.
        delete map_widgetList.value(e);
    }
    QApplication::quit();
}

// Window Close Event
void mainWindow::closeEvent(QCloseEvent *event){
    event->ignore();
    this->setVisible(false);
}
<|endoftext|>


<commit_before>#include <iostream>

using namespace std;

int
main(void)
{
	int retval = 0;

	cout << "Entrypoint" << endl;

	return retval;
}
<commit_msg>C++: refactors code.<commit_after>#include <iostream>

using namespace std;

int
main(void)
{
	cout << "Entrypoint" << endl;

	return 0;
}
<|endoftext|>


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

#include <aescrypt.hpp>

#include <cstring>
#include <stdexcept>

#include <openssl/aes.h>
#include <openssl/rand.h>

namespace aescrypt {

/***************************************************************************/

struct cryptor::impl {
	impl(const char *key, const key_length klen)
		:klen(klen)
	{
		if ( std::strlen(key)*8 != klen )
			throw std::runtime_error("length of key is not equal to "+std::to_string(klen)+" bits");

		std::memset(iv_enc, 0, AES_BLOCK_SIZE);
		std::memset(iv_dec, 0, AES_BLOCK_SIZE);

		AES_set_encrypt_key((const std::uint8_t*)key, klen, &enc_key);
		AES_set_decrypt_key((const std::uint8_t*)key, klen, &dec_key);
	}

	const key_length klen;
	std::uint8_t iv_enc[AES_BLOCK_SIZE];
	std::uint8_t iv_dec[AES_BLOCK_SIZE];
	AES_KEY enc_key;
	AES_KEY dec_key;
}; // struct impl

/***************************************************************************/

cryptor::cryptor(const char *key, const key_length klen)
	:pimpl(new impl(key, klen))
{}

cryptor::~cryptor()
{ delete pimpl; }

/***************************************************************************/

key_length cryptor::get_key_length() const { return pimpl->klen; }

/***************************************************************************/

void cryptor::encrypt(char *dst, const char *src, const std::size_t len) const {
	AES_cbc_encrypt(
		 (const std::uint8_t*)src
		,(std::uint8_t*)dst
		,len
		,&(pimpl->enc_key)
		,pimpl->iv_enc
		,AES_ENCRYPT
	);
}

void cryptor::decrypt(char *dst, const char *src, const std::size_t len) const {
	AES_cbc_encrypt(
		 (const std::uint8_t*)src
		,(std::uint8_t*)dst
		,len
		,&(pimpl->dec_key)
		,pimpl->iv_dec
		,AES_DECRYPT
	);
}

cryptor::buffer_type
cryptor::encrypt(const char *src, const std::size_t len) const {
	cryptor::buffer_type buf(new char[len]);
	encrypt(buf.get(), src, len);

	return std::move(buf);
}

cryptor::buffer_type
cryptor::decrypt(const char *src, const std::size_t len) const {
	cryptor::buffer_type buf(new char[len]);
	decrypt(buf.get(), src, len);

	return std::move(buf);
}

std::string cryptor::encrypt(const std::string &src) const {
	std::string res(src.length(), 0);
	encrypt(const_cast<char*>(res.c_str()), src.c_str(), src.length());

	return std::move(res);
}

std::string cryptor::decrypt(const std::string &src) const {
	std::string res(src.length(), 0);
	decrypt(const_cast<char*>(res.c_str()), src.c_str(), src.length());

	return std::move(res);
}

/***************************************************************************/

} // ns aescrypt
<commit_msg>initialization vectors initialized using random bytes<commit_after>
// Copyright (c) 2014 niXman (i dotty nixman doggy gmail dotty com)
// All rights reserved.
//
// This file is part of aescrypt(https://github.com/niXman/aescrypt) project.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
//   Redistributions in binary form must reproduce the above copyright notice, this
//   list of conditions and the following disclaimer in the documentation and/or
//   other materials provided with the distribution.
//
//   Neither the name of the {organization} nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <aescrypt.hpp>

#include <cstring>
#include <stdexcept>

#include <openssl/aes.h>
#include <openssl/rand.h>

namespace aescrypt {

/***************************************************************************/

struct cryptor::impl {
	impl(const char *key, const key_length klen)
		:klen(klen)
	{
		if ( std::strlen(key)*8 != klen )
			throw std::runtime_error("length of key is not equal to "+std::to_string(klen)+" bits");

		RAND_bytes(iv_enc, AES_BLOCK_SIZE);
		std::memcpy(iv_dec, iv_enc, AES_BLOCK_SIZE);

		AES_set_encrypt_key((const std::uint8_t*)key, klen, &enc_key);
		AES_set_decrypt_key((const std::uint8_t*)key, klen, &dec_key);
	}

	const key_length klen;
	std::uint8_t iv_enc[AES_BLOCK_SIZE];
	std::uint8_t iv_dec[AES_BLOCK_SIZE];
	AES_KEY enc_key;
	AES_KEY dec_key;
}; // struct impl

/***************************************************************************/

cryptor::cryptor(const char *key, const key_length klen)
	:pimpl(new impl(key, klen))
{}

cryptor::~cryptor()
{ delete pimpl; }

/***************************************************************************/

key_length cryptor::get_key_length() const { return pimpl->klen; }

/***************************************************************************/

void cryptor::encrypt(char *dst, const char *src, const std::size_t len) const {
	AES_cbc_encrypt(
		 (const std::uint8_t*)src
		,(std::uint8_t*)dst
		,len
		,&(pimpl->enc_key)
		,pimpl->iv_enc
		,AES_ENCRYPT
	);
}

void cryptor::decrypt(char *dst, const char *src, const std::size_t len) const {
	AES_cbc_encrypt(
		 (const std::uint8_t*)src
		,(std::uint8_t*)dst
		,len
		,&(pimpl->dec_key)
		,pimpl->iv_dec
		,AES_DECRYPT
	);
}

cryptor::buffer_type
cryptor::encrypt(const char *src, const std::size_t len) const {
	cryptor::buffer_type buf(new char[len]);
	encrypt(buf.get(), src, len);

	return std::move(buf);
}

cryptor::buffer_type
cryptor::decrypt(const char *src, const std::size_t len) const {
	cryptor::buffer_type buf(new char[len]);
	decrypt(buf.get(), src, len);

	return std::move(buf);
}

std::string cryptor::encrypt(const std::string &src) const {
	std::string res(src.length(), 0);
	encrypt(const_cast<char*>(res.c_str()), src.c_str(), src.length());

	return std::move(res);
}

std::string cryptor::decrypt(const std::string &src) const {
	std::string res(src.length(), 0);
	decrypt(const_cast<char*>(res.c_str()), src.c_str(), src.length());

	return std::move(res);
}

/***************************************************************************/

} // ns aescrypt
<|endoftext|>


<commit_before>#include "main.h"

#define WINDOW_WIDTH 400
#define WINDOW_HEIGHT 400

using namespace sf;

int main() {
	RenderWindow window(VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Ninja Chess");
	window.setVerticalSyncEnabled(true);

	while (window.isOpen()) {
		Event event;
		while (window.pollEvent(event)) {
			if (event.type == Event::Closed)
				window.close();
		}

		window.clear();

		drawBoard(window);

		window.display();
	}

	return EXIT_SUCCESS;
}

void drawBoard(RenderWindow& window) {
	RectangleShape square(Vector2f(WINDOW_WIDTH / 8.f, WINDOW_HEIGHT / 8.f));
	for (int x = 0; x < 8; x++) {
		for (int y = 0; y < 8; y++) {
			square.setPosition(x * WINDOW_WIDTH / 8.f, y * WINDOW_HEIGHT / 8.f);

			if ((x + y) % 2 == 0)
				square.setFillColor(Color::Green);
			else
				square.setFillColor(Color::Red);

			window.draw(square);
		}
	}
}<commit_msg>Better looking colors<commit_after>#include "main.h"

#define WINDOW_WIDTH 400
#define WINDOW_HEIGHT 400

using namespace sf;

int main() {
	RenderWindow window(VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Ninja Chess");
	window.setVerticalSyncEnabled(true);

	while (window.isOpen()) {
		Event event;
		while (window.pollEvent(event)) {
			if (event.type == Event::Closed)
				window.close();
		}

		window.clear();

		drawBoard(window);

		window.display();
	}

	return EXIT_SUCCESS;
}

void drawBoard(RenderWindow& window) {
	Color brightSquare(224, 217, 190);
	Color darkSquare(152, 145, 135);

	RectangleShape square(Vector2f(WINDOW_WIDTH / 8.f, WINDOW_HEIGHT / 8.f));
	for (int x = 0; x < 8; x++) {
		for (int y = 0; y < 8; y++) {
			square.setPosition(x * WINDOW_WIDTH / 8.f, y * WINDOW_HEIGHT / 8.f);

			if ((x + y) % 2 == 0)
				square.setFillColor(brightSquare);
			else
				square.setFillColor(darkSquare);

			window.draw(square);
		}
	}
}<|endoftext|>


<commit_before>/*
 * XClient.cpp -- X11 protocol client
 *
 * Copyright (c) 2007-2012, Frank Mertens
 *
 * This file is part of the a free software library. You can redistribute
 * it and/or modify it under the terms of FTL's 2-clause BSD license.
 *
 * See the LICENSE.txt file for details at the top-level of FTL's sources.
 */

#include <ftl/Process.hpp>
#include <ftl/StreamSocket.hpp>
#include <ftl/ByteEncoder.hpp>
#include <ftl/ByteDecoder.hpp>
#include <ftl/Format.hpp>
#include <ftl/stdio>
#include "XAuthFile.hpp"
#include "XClient.hpp"

namespace ftl
{

XClient::XClient()
	: defaultScreen_(0),
	  nextResourceId_(0),
	  freeResourceIds_(new List<uint32_t>),
	  sequenceNumber_(0)
{
	String host = 0;
	int display = 0;

	Ref<SocketAddress, Owner> address;
	String authProtocol, authData;
	{
		Ref<StringList, Owner> parts = Process::env("DISPLAY")->split(':');
		if (parts->length() == 2) {
			host = parts->get(0);
			parts = parts->get(1)->split('.');
			display = parts->get(0)->toInt();
			if (parts->length() == 2)
				defaultScreen_ = parts->get(1)->toInt();
		}
		if (host == "") {
			String path = Format("/tmp/.X11-unix/X%%") << display;
			address = new SocketAddress(AF_LOCAL, path);
		}
		else {
			Ref<SocketAddressList, Owner> list = SocketAddress::resolve(host, "x11");
			if (list->length() == 0) FTL_THROW(XException, "Unknown host");
			address = list->get(0);

			if (host == "") host = SocketAddress::hostName();
			XAuthFile file;
			Ref<XAuthRecords> records = file.records();
			for (int i = 0, n = records->length(); i < n; ++i) {
				Ref<XAuthRecord> record = records->get(i);
				if ( (record->family == address->family()) &&
				     (record->host == host) &&
				     (record->display == display) )
				{
					authProtocol = record->protocol;
					authData = record->data;
					break;
				}
			}
		}
	}

	socket_ = new StreamSocket(address);
	socket_->connect();

	Ref<ByteEncoder, Owner> sink = new ByteEncoder(socket_);

	sink->writeUInt8((sink->endian() == LittleEndian) ? 'l' : 'B');
	sink->writeUInt8(0); // unused
	sink->writeUInt16(11); // protocol-major-version
	sink->writeUInt16(0); // protocol-minor-version
	sink->writeUInt16(authProtocol->length());
	sink->writeUInt16(authData->length());
	sink->writeUInt16(0); // unused
	sink->write(authProtocol);
	sink->writePad(4);
	sink->write(authData);
	sink->writePad(4);
	sink->flush();

	Ref<ByteDecoder, Owner> source = new ByteDecoder(socket_);

	displayInfo_ = new XDisplayInfo;
	displayInfo_->read(source);

	if (defaultScreen_ >= displayInfo_->screenInfo->length())
		defaultScreen_ = displayInfo_->screenInfo->length() - 1;
}

Ref<XWindow, Owner> XClient::createWindow(int x, int y, int width, int height)
{
	++sequenceNumber_;

	Ref<XScreenInfo> screenInfo = displayInfo_->screenInfo->at(defaultScreen_);
	Ref<XWindow, Owner> window = new XWindow;
	window->id_ = allocateResourceId();
	window->visualId_ = screenInfo->rootVisualId;
	window->depth_ = screenInfo->rootDepth;

	Ref<ByteEncoder, Owner> sink = new ByteEncoder(socket_);
	sink->writeUInt8(1);
	sink->writeUInt8(window->depth_);
	sink->writeUInt16(8 + 1); // request length
	sink->writeUInt32(window->id_);
	sink->writeUInt32(screenInfo->rootWindowId);
	sink->writeUInt16(x);
	sink->writeUInt16(y);
	sink->writeUInt16(width);
	sink->writeUInt16(height);
	sink->writeUInt16(0); // border width
	sink->writeUInt16(1); // class (0=inherit, 1=input/output, 2=input only)
	sink->writeUInt32(window->visualId_);
	sink->writeUInt32(0x800); // value mask (0x800 = event mask)
	sink->writeUInt32(0x1FFFFFF); // event mask
	sink->flush();

	return window;
}

void XClient::mapWindow(Ref<XWindow> window)
{
	++sequenceNumber_;

	Ref<ByteEncoder, Owner> sink = new ByteEncoder(socket_);
	sink->writeUInt8(8);
	sink->writeUInt8(0); // unused
	sink->writeUInt16(2); // request length
	sink->writeUInt32(window->id_);
	sink->flush();
}

uint32_t XClient::allocateResourceId()
{
	Guard<Mutex> guard(&resourceIdMutex_);
	if (freeResourceIds_->length() > 0)
		return freeResourceIds_->pop();
	if (nextResourceId_ == displayInfo_->resourceIdMask)
		FTL_THROW(XException, "Pool of resource IDs exhausted");
	return displayInfo_->resourceIdBase | ((++nextResourceId_) & displayInfo_->resourceIdMask);
}

void XClient::freeResourceId(uint32_t id)
{
	Guard<Mutex> guard(&resourceIdMutex_);
	freeResourceIds_->push(id);
}

static const char *x11MessageName(int messageType)
{
	const char *names[] = {
		"error",             // 0
		"display info",      // 1
		"key press",         // 2
		"key release",       // 3
		"button press",      // 4
		"button release",    // 5
		"motion notify",     // 6
		"enter notify",      // 7
		"leave notify",      // 8
		"focus in",          // 9
		"focus out",         // 10
		"keymap notify",     // 11
		"expose",            // 12
		"graphics exposure", // 13
		"no exposure",       // 14
		"visibility notify", // 15
		"create notify",     // 16
		"destroy notify",    // 17
		"unmap notify",      // 18
		"map notify",        // 19
		"map request",       // 20
		"reparent notify",   // 21
		"configure notify",  // 22
		"configure request", // 23
		"gravity notify",    // 24
		"resize request",    // 25
		"circulate notify",  // 26
		"circulate request", // 27
		"property notify",   // 28
		"selection clear",   // 29
		"selection request", // 30
		"selection notify",  // 31
		"colormap notify",   // 32
		"client message",    // 33
		"mapping notify"     // 34
	};

	return ((0 <= messageType) && (messageType <= 34)) ? names[messageType] : "unknown";
}

void XClient::run()
{
	printTo(error(), "XClient::run()\n");
	Ref<ByteDecoder, Owner> source = new ByteDecoder(socket_);

	while (true) {
		uint8_t messageType = source->readUInt8();

		if (messageType == 0) // error
		{
			uint8_t code = source->readUInt8();
			uint16_t sequenceNumber = source->readUInt16();
			uint32_t badSomething = source->readUInt32();
			uint16_t minorOpcode = source->readUInt16();
			uint8_t majorOpcode = source->readUInt8();

			bool badValue = (code == 2);
			bool badResource =
				((3 <= code) && (code <= 7)) ||
				(code == 9) ||
				(code == 12) ||
				(code == 13) ||
				(code == 14);

			const char* errorNames[] = {
				"unknown", "request", "value", "window", "pixmap", "atom", "cursor", "font",
				"match", "drawable", "access", "alloc", "colormap", "graphics context",
				"id choice", "name", "length", "implementation"
			};
			const char* errorName = errorNames[((1 <= code) && (code <= 17)) ? int(code) : 0];

			if (badValue) {
				printTo(error(), "X11 %% error (opcode: %%.%%, bad value: %%) [%%]\n",
					errorName, majorOpcode, minorOpcode, badSomething, sequenceNumber
				);
			}
			else if (badResource) {
				printTo(error(), "X11 %% error (opcode: %%.%%, bad resource id: %%) [%%]\n",
					errorName, majorOpcode, minorOpcode, badSomething, sequenceNumber
				);
			}
			else {
				printTo(error(), "X11 %% error (opcode: %%.%%) [%%]\n",
					errorName, majorOpcode, minorOpcode, sequenceNumber
				);
			}
		}
		else if ((2 <= messageType ) && (messageType <= 6))
		{
			uint8_t detail = source->readUInt8();
			uint16_t sequenceNumber = source->readUInt16();
			uint32_t time = source->readUInt32();
			uint32_t rootWindowId = source->readUInt32();
			uint32_t eventWindowId = source->readUInt32();
			uint32_t childWindowId = source->readUInt32();
			uint16_t rootX = source->readUInt16();
			uint16_t rootY = source->readUInt16();
			uint16_t eventX = source->readUInt16();
			uint16_t eventY = source->readUInt16();
			uint16_t state = source->readUInt16();
			uint8_t sameScreen = source->readUInt8();
			source->skipPad(32);

			String detailString;
			if ((messageType == 2) || (messageType == 3))
				detailString = Format("keycode: %%") << detail;
			else if ((messageType == 4) || (messageType == 5))
				detailString = Format("button: %%") << detail;
			else if (messageType == 6)
				detailString = (detail == 0) ? "normal" : "hint";

			String stateString;
			{
				enum KeyButtonMask {
					Shift   = 1,
					Lock    = 2,
					Control = 4,
					Mod1    = 8,
					Mod2    = 16,
					Mod3    = 32,
					Mod4    = 64,
					Mod5    = 128,
					Button1 = 256,
					Button2 = 512,
					Button3 = 1024,
					Button4 = 2048,
					Button5 = 4096
				};
				Ref<StringList, Owner> bitNames = new StringList;
				if (state & Shift) bitNames->append("Shift");
				else if (state & Lock) bitNames->append("Lock");
				else if (state & Control) bitNames->append("Control");
				else if (state & Mod1) bitNames->append("Mod1");
				else if (state & Mod2) bitNames->append("Mod2");
				else if (state & Mod3) bitNames->append("Mod3");
				else if (state & Mod4) bitNames->append("Mod4");
				else if (state & Mod5) bitNames->append("Mod5");
				else if (state & Button1) bitNames->append("Button1");
				else if (state & Button2) bitNames->append("Button2");
				else if (state & Button3) bitNames->append("Button3");
				else if (state & Button4) bitNames->append("Button4");
				else if (state & Button5) bitNames->append("Button5");
				stateString = bitNames->join("|");
			}

			printTo(error(), "X11 %% event (\n"
				"  %%, time: %%,\n"
				"  root window id: %%,\n"
				"  event window id: %%,\n"
				"  child window id: %%,\n"
				"  rootX, rootY: %%, %%\n"
				"  eventX, eventY: %%, %%\n"
				"  same screen: %%\n"
				") [%%]\n",
				x11MessageName(messageType),
				detailString, time,
				rootWindowId,
				eventWindowId,
				childWindowId,
				rootX, rootY,
				eventX, eventY,
				bool(sameScreen),
				sequenceNumber
			);
		}
		/*else if ((messageType == 6) || (messageType == 7))
		{
			uint8_t detail = source->readUInt8();
			uint16_t sequenceNumber = source->readUInt16();
			uint32_t time = source->readUInt32();
			uint32_t rootWindowId = source->readUInt32();
			uint32_t eventWindowId = source->readUInt32();
			uint32_t childWindowId = source->readUInt32();
			uint16_t rootX = source->readUInt16();
			uint16_t rootY = source->readUInt16();
			uint16_t eventX = source->readUInt16();
			uint16_t eventY = source->readUInt16();
			uint16_t state = source->readUInt16();
			uint8_t mode = source->readUInt8();
			uint8_t flags = source->readUInt8();

			String evenName =
			String detailString
		}*/
		else {
			printTo(error(), "X11 %% (%%)\n", x11MessageName(messageType), messageType);
		}
		source->skipPad(32);
	}
}

} // namespace ftl
<commit_msg>Understand synthetic events.<commit_after>/*
 * XClient.cpp -- X11 protocol client
 *
 * Copyright (c) 2007-2012, Frank Mertens
 *
 * This file is part of the a free software library. You can redistribute
 * it and/or modify it under the terms of FTL's 2-clause BSD license.
 *
 * See the LICENSE.txt file for details at the top-level of FTL's sources.
 */

#include <ftl/Process.hpp>
#include <ftl/StreamSocket.hpp>
#include <ftl/ByteEncoder.hpp>
#include <ftl/ByteDecoder.hpp>
#include <ftl/Format.hpp>
#include <ftl/stdio>
#include "XAuthFile.hpp"
#include "XClient.hpp"

namespace ftl
{

XClient::XClient()
	: defaultScreen_(0),
	  nextResourceId_(0),
	  freeResourceIds_(new List<uint32_t>),
	  sequenceNumber_(0)
{
	String host = 0;
	int display = 0;

	Ref<SocketAddress, Owner> address;
	String authProtocol, authData;
	{
		Ref<StringList, Owner> parts = Process::env("DISPLAY")->split(':');
		if (parts->length() == 2) {
			host = parts->get(0);
			parts = parts->get(1)->split('.');
			display = parts->get(0)->toInt();
			if (parts->length() == 2)
				defaultScreen_ = parts->get(1)->toInt();
		}
		if (host == "") {
			String path = Format("/tmp/.X11-unix/X%%") << display;
			address = new SocketAddress(AF_LOCAL, path);
		}
		else {
			Ref<SocketAddressList, Owner> list = SocketAddress::resolve(host, "x11");
			if (list->length() == 0) FTL_THROW(XException, "Unknown host");
			address = list->get(0);

			if (host == "") host = SocketAddress::hostName();
			XAuthFile file;
			Ref<XAuthRecords> records = file.records();
			for (int i = 0, n = records->length(); i < n; ++i) {
				Ref<XAuthRecord> record = records->get(i);
				if ( (record->family == address->family()) &&
				     (record->host == host) &&
				     (record->display == display) )
				{
					authProtocol = record->protocol;
					authData = record->data;
					break;
				}
			}
		}
	}

	socket_ = new StreamSocket(address);
	socket_->connect();

	Ref<ByteEncoder, Owner> sink = new ByteEncoder(socket_);

	sink->writeUInt8((sink->endian() == LittleEndian) ? 'l' : 'B');
	sink->writeUInt8(0); // unused
	sink->writeUInt16(11); // protocol-major-version
	sink->writeUInt16(0); // protocol-minor-version
	sink->writeUInt16(authProtocol->length());
	sink->writeUInt16(authData->length());
	sink->writeUInt16(0); // unused
	sink->write(authProtocol);
	sink->writePad(4);
	sink->write(authData);
	sink->writePad(4);
	sink->flush();

	Ref<ByteDecoder, Owner> source = new ByteDecoder(socket_);

	displayInfo_ = new XDisplayInfo;
	displayInfo_->read(source);

	if (defaultScreen_ >= displayInfo_->screenInfo->length())
		defaultScreen_ = displayInfo_->screenInfo->length() - 1;
}

Ref<XWindow, Owner> XClient::createWindow(int x, int y, int width, int height)
{
	++sequenceNumber_;

	Ref<XScreenInfo> screenInfo = displayInfo_->screenInfo->at(defaultScreen_);
	Ref<XWindow, Owner> window = new XWindow;
	window->id_ = allocateResourceId();
	window->visualId_ = screenInfo->rootVisualId;
	window->depth_ = screenInfo->rootDepth;

	Ref<ByteEncoder, Owner> sink = new ByteEncoder(socket_);
	sink->writeUInt8(1);
	sink->writeUInt8(window->depth_);
	sink->writeUInt16(8 + 1); // request length
	sink->writeUInt32(window->id_);
	sink->writeUInt32(screenInfo->rootWindowId);
	sink->writeUInt16(x);
	sink->writeUInt16(y);
	sink->writeUInt16(width);
	sink->writeUInt16(height);
	sink->writeUInt16(0); // border width
	sink->writeUInt16(1); // class (0=inherit, 1=input/output, 2=input only)
	sink->writeUInt32(window->visualId_);
	sink->writeUInt32(0x800); // value mask (0x800 = event mask)
	sink->writeUInt32(0x1FFFFFF); // event mask
	sink->flush();

	return window;
}

void XClient::mapWindow(Ref<XWindow> window)
{
	++sequenceNumber_;

	Ref<ByteEncoder, Owner> sink = new ByteEncoder(socket_);
	sink->writeUInt8(8);
	sink->writeUInt8(0); // unused
	sink->writeUInt16(2); // request length
	sink->writeUInt32(window->id_);
	sink->flush();
}

uint32_t XClient::allocateResourceId()
{
	Guard<Mutex> guard(&resourceIdMutex_);
	if (freeResourceIds_->length() > 0)
		return freeResourceIds_->pop();
	if (nextResourceId_ == displayInfo_->resourceIdMask)
		FTL_THROW(XException, "Pool of resource IDs exhausted");
	return displayInfo_->resourceIdBase | ((++nextResourceId_) & displayInfo_->resourceIdMask);
}

void XClient::freeResourceId(uint32_t id)
{
	Guard<Mutex> guard(&resourceIdMutex_);
	freeResourceIds_->push(id);
}

static const char *x11MessageName(int messageCode)
{
	const char *names[] = {
		"error",             // 0
		"display info",      // 1
		"key press",         // 2
		"key release",       // 3
		"button press",      // 4
		"button release",    // 5
		"motion notify",     // 6
		"enter notify",      // 7
		"leave notify",      // 8
		"focus in",          // 9
		"focus out",         // 10
		"keymap notify",     // 11
		"expose",            // 12
		"graphics exposure", // 13
		"no exposure",       // 14
		"visibility notify", // 15
		"create notify",     // 16
		"destroy notify",    // 17
		"unmap notify",      // 18
		"map notify",        // 19
		"map request",       // 20
		"reparent notify",   // 21
		"configure notify",  // 22
		"configure request", // 23
		"gravity notify",    // 24
		"resize request",    // 25
		"circulate notify",  // 26
		"circulate request", // 27
		"property notify",   // 28
		"selection clear",   // 29
		"selection request", // 30
		"selection notify",  // 31
		"colormap notify",   // 32
		"client message",    // 33
		"mapping notify"     // 34
	};

	return ((0 <= messageCode) && (messageCode <= 34)) ? names[messageCode] : "unknown";
}

void XClient::run()
{
	printTo(error(), "XClient::run()\n");
	Ref<ByteDecoder, Owner> source = new ByteDecoder(socket_);

	while (true) {
		uint8_t messageCode = source->readUInt8();
		bool synthetic = messageCode & 0x80;
		messageCode &= 0x7F;

		if (messageCode == 0) // error
		{
			uint8_t code = source->readUInt8();
			uint16_t sequenceNumber = source->readUInt16();
			uint32_t badSomething = source->readUInt32();
			uint16_t minorOpcode = source->readUInt16();
			uint8_t majorOpcode = source->readUInt8();
			source->skipPad(32);

			bool badValue = (code == 2);
			bool badResource =
				((3 <= code) && (code <= 7)) ||
				(code == 9) ||
				(code == 12) ||
				(code == 13) ||
				(code == 14);

			const char* errorNames[] = {
				"unknown", "request", "value", "window", "pixmap", "atom", "cursor", "font",
				"match", "drawable", "access", "alloc", "colormap", "graphics context",
				"id choice", "name", "length", "implementation"
			};
			const char* errorName = errorNames[((1 <= code) && (code <= 17)) ? int(code) : 0];

			if (badValue) {
				printTo(error(), "X11 %% error (opcode: %%.%%, bad value: %%) [%%]\n",
					errorName, majorOpcode, minorOpcode, badSomething, sequenceNumber
				);
			}
			else if (badResource) {
				printTo(error(), "X11 %% error (opcode: %%.%%, bad resource id: %%) [%%]\n",
					errorName, majorOpcode, minorOpcode, badSomething, sequenceNumber
				);
			}
			else {
				printTo(error(), "X11 %% error (opcode: %%.%%) [%%]\n",
					errorName, majorOpcode, minorOpcode, sequenceNumber
				);
			}
		}
		else if ((2 <= messageCode) && (messageCode <= 6))
		{
			uint8_t detail = source->readUInt8();
			uint16_t sequenceNumber = source->readUInt16();
			uint32_t time = source->readUInt32();
			uint32_t rootWindowId = source->readUInt32();
			uint32_t eventWindowId = source->readUInt32();
			uint32_t childWindowId = source->readUInt32();
			uint16_t rootX = source->readUInt16();
			uint16_t rootY = source->readUInt16();
			uint16_t eventX = source->readUInt16();
			uint16_t eventY = source->readUInt16();
			uint16_t state = source->readUInt16();
			uint8_t sameScreen = source->readUInt8();
			source->skipPad(32);

			String detailString;
			if ((messageCode == 2) || (messageCode == 3))
				detailString = Format("keycode: %%") << detail;
			else if ((messageCode == 4) || (messageCode == 5))
				detailString = Format("button: %%") << detail;
			else if (messageCode == 6)
				detailString = (detail == 0) ? "normal" : "hint";

			String stateString;
			{
				enum KeyButtonMask {
					Shift   = 1,
					Lock    = 2,
					Control = 4,
					Mod1    = 8,
					Mod2    = 16,
					Mod3    = 32,
					Mod4    = 64,
					Mod5    = 128,
					Button1 = 256,
					Button2 = 512,
					Button3 = 1024,
					Button4 = 2048,
					Button5 = 4096
				};
				Ref<StringList, Owner> bitNames = new StringList;
				if (state & Shift) bitNames->append("Shift");
				else if (state & Lock) bitNames->append("Lock");
				else if (state & Control) bitNames->append("Control");
				else if (state & Mod1) bitNames->append("Mod1");
				else if (state & Mod2) bitNames->append("Mod2");
				else if (state & Mod3) bitNames->append("Mod3");
				else if (state & Mod4) bitNames->append("Mod4");
				else if (state & Mod5) bitNames->append("Mod5");
				else if (state & Button1) bitNames->append("Button1");
				else if (state & Button2) bitNames->append("Button2");
				else if (state & Button3) bitNames->append("Button3");
				else if (state & Button4) bitNames->append("Button4");
				else if (state & Button5) bitNames->append("Button5");
				stateString = bitNames->join("|");
			}

			printTo(error(), "X11 %% event (\n"
				"  %%, time: %%,\n"
				"  root window id: %%,\n"
				"  event window id: %%,\n"
				"  child window id: %%,\n"
				"  rootX, rootY: %%, %%\n"
				"  eventX, eventY: %%, %%\n"
				"  same screen: %%\n"
				") [%%]\n",
				x11MessageName(messageCode),
				detailString, time,
				rootWindowId,
				eventWindowId,
				childWindowId,
				rootX, rootY,
				eventX, eventY,
				bool(sameScreen),
				sequenceNumber
			);
		}
		/*else if ((messageCode == 6) || (messageCode == 7))
		{
			uint8_t detail = source->readUInt8();
			uint16_t sequenceNumber = source->readUInt16();
			uint32_t time = source->readUInt32();
			uint32_t rootWindowId = source->readUInt32();
			uint32_t eventWindowId = source->readUInt32();
			uint32_t childWindowId = source->readUInt32();
			uint16_t rootX = source->readUInt16();
			uint16_t rootY = source->readUInt16();
			uint16_t eventX = source->readUInt16();
			uint16_t eventY = source->readUInt16();
			uint16_t state = source->readUInt16();
			uint8_t mode = source->readUInt8();
			uint8_t flags = source->readUInt8();

			String evenName =
			String detailString
		}*/
		else {
			printTo(error(), "X11 %% (%%)\n", x11MessageName(messageCode), messageCode);
		}
		source->skipPad(32);
	}
}

} // namespace ftl
<|endoftext|>


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

	FILE:  ballwidget.cpp

	PROJECT:

		GLOW widgets for glutmech demo

	CONTENTS:

		Ball widget

	PROGRAMMERS:

		Daniel Azuma <dazuma@kagi.com>

	COPYRIGHT:

		Copyright (C) 2000  Daniel Azuma  (dazuma@kagi.com)

		This library is free software; you can redistribute it and/or
		modify it under the terms of the GNU Lesser General Public
		License as published by the Free Software Foundation; either
		version 2.1 of the License, or (at your option) any later version.

		This library is distributed in the hope that it will be useful,
		but WITHOUT ANY WARRANTY; without even the implied warranty of
		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
		GNU Lesser General Public License for more details.

		You should have received a copy of the GNU Lesser General Public
		License along with this library; if not, write to
			Free Software Foundation, Inc.
			59 Temple Place, Suite 330
			Boston, MA 02111-1307 USA

	VERSION:

		The GLOW Toolkit tutorial -- version 1.1.2dev  (7 August 2000)

	CHANGES:

		Original release (DA)

===============================================================================
*/

/*
===============================================================================
	Headers and declarations
===============================================================================
*/

#include <algorithm>

using namespace std;

#include "glowViewTransform.h"

GLOW_NAMESPACE_USING

#include "ballwidget.h"

/*
===============================================================================
	Component that draws a wire sphere
===============================================================================
*/

class DrawWireSphere :
	public GlowComponent
{
	public:

		DrawWireSphere(
			GlowComponent* parent) :
		GlowComponent(parent) {}

	protected:

		virtual void OnEndPaint();
};

void DrawWireSphere::OnEndPaint()
{
	::glEnable(GL_CULL_FACE);
	::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	::glColor3ub(0, 255, 255);
	::glutSolidSphere(1.0, 12, 6);
	::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	::glDisable(GL_CULL_FACE);
}

/*
===============================================================================
	Methods of BallWidget
===============================================================================
*/

BallWidget::BallWidget(
	GlowWidget* parent,
	int x,
	int y,
	int width)
{
	GLOW_DEBUGSCOPE("BallWidget::BallWidget");

	// Initialize widget
	GlowWidgetParams params;
	params.x = x;
	params.y = y;
	params.width = params.height = width;
	GlowWidget::Init(parent->Root(), parent, params);

	// Make view manipulator and drawing component
	manip_ = new GlowViewManipulator(this, GlowViewManipulatorParams::defaults);
	new DrawWireSphere(manip_);

	// Register to receive mouse events
	RegisterMouseEvents();
}

// Override this method to draw the widget
void BallWidget::OnWidgetPaint()
{
	// Here we just clear the widget's rectangle to black.
	// Since OnWidgetPaint() is called during GlowComponent::OnBeginPaint(),
	// this clears the rectangle to black, before the trackball is drawn.
	::glColor3ub(0, 0, 0);
	::glBegin(GL_QUADS);
	::glVertex2f(-1.0f, -1.0f);
	::glVertex2f(1.0f, -1.0f);
	::glVertex2f(1.0f, 1.0f);
	::glVertex2f(-1.0f, 1.0f);
	::glEnd();
}

// Handle mouse down in widget events
void BallWidget::OnWidgetMouseDown(
	Glow::MouseButton button,
	int x,
	int y,
	Glow::Modifiers modifiers)
{
	GLOW_DEBUGSCOPE("BallWidget::OnWidgetMouseDown");

	if (!manip_->IsDragging())
	{
		GLfloat xn;
		GLfloat yn;
		NormalizeCoordinates(x, y, xn, yn);
		manip_->BeginRotationDrag(xn, yn);
		button_ = button;
		modifiers_ = modifiers;
	}
}

// Handle mouse up in widget events
void BallWidget::OnWidgetMouseUp(
	Glow::MouseButton button,
	int x,
	int y,
	Glow::Modifiers modifiers)
{
	GLOW_DEBUGSCOPE("BallWidget::OnWidgetMouseUp");

	if (manip_->IsDragging())
	{
		GLfloat xn;
		GLfloat yn;
		NormalizeCoordinates(x, y, xn, yn);
		manip_->EndDrag(xn, yn);
		OnReleased(button_, modifiers_);
	}
}

// Handle mouse drag in widget events
void BallWidget::OnWidgetMouseDrag(
	int x,
	int y)
{
	GLOW_DEBUGSCOPE("BallWidget::OnWidgetMouseDrag");

	if (manip_->IsDragging())
	{
		GLfloat xn;
		GLfloat yn;
		NormalizeCoordinates(x, y, xn, yn);
		manip_->InDrag(xn, yn);
		OnDragged(button_, modifiers_);
	}
}

// Default method for handling trackball dragged events
void BallWidget::OnDragged(
	Glow::MouseButton button,
	Glow::Modifiers modifiers)
{
	GLOW_DEBUGSCOPE("BallWidget::OnDragged");

	// Send event message to receivers
	BallMessage message;
	message.widget = this;
	message.rotation = manip_->GetRotation();
	message.released = false;
	message.mouseButton = button;
	message.modifiers = modifiers;
	sender_.Send(message);
}

// Default method for handling trackball released events
void BallWidget::OnReleased(
	Glow::MouseButton button,
	Glow::Modifiers modifiers)
{
	GLOW_DEBUGSCOPE("BallWidget::OnReleased");

	// Send event message to receivers
	BallMessage message;
	message.widget = this;
	message.rotation = manip_->GetRotation();
	message.released = true;
	message.mouseButton = button;
	message.modifiers = modifiers;
	sender_.Send(message);
}

// Automatically resize widget according to constraints
GlowWidget::AutoPackError BallWidget::OnAutoPack(
	int hSize,
	int vSize,
	AutoPackOptions hOption,
	AutoPackOptions vOption,
	int& leftMargin,
	int& rightMargin,
	int& topMargin,
	int& bottomMargin)
{
	GLOW_DEBUGSCOPE("BallWidget::OnAutoPack");

	int hnew;
	int vnew;

	// noReshape is kind of like forcedSize for our purposes. We'll
	// fold the two options into one to make our life easier.
	if (hOption == noReshape)
	{
		hOption = forcedSize;
		hSize = Width();
	}
	if (vOption == noReshape)
	{
		vOption = forcedSize;
		vSize = Height();
	}

	// Handle forcedSize first
	// If forcing different sizes, fail because we want the widget square
	if (hOption == forcedSize && vOption == forcedSize && hSize != vSize)
	{
		return hAutoPackError;
	}
	// Set to the forced size, if it's not too small
	if (hOption == forcedSize)
	{
		if (hSize < 20)
		{
			return hAutoPackError;
		}
		hnew = hSize;
	}
	if (vOption == forcedSize)
	{
		if (vSize < 20)
		{
			return vAutoPackError;
		}
		vnew = vSize;
	}

	// Handle preferredSize and expandPreferredSize
	if (hOption == preferredSize || hOption == expandPreferredSize)
	{
		// Make sure the constraint isn't too small
		if (hSize != unspecifiedSize && hSize < 20)
		{
			return hAutoPackError;
		}
		// Adjust constraint if vertical size is already forced
		if (vOption == forcedSize)
		{
			// Do vertical forced size and horizontal constraint conflict?
			if (hSize != unspecifiedSize && hSize < vnew)
			{
				return hAutoPackError;
			}
			hnew = vnew;
		}
		else
		{
			// If using expandPreferredSize or constraint is smaller than 100
			// then set the size to the constraint, otherwise set it to 100.
			if (hOption == expandPreferredSize ||
				(hSize != unspecifiedSize && hSize <= 100))
			{
				hnew = hSize;
			}
			else
			{
				hnew = 100;
			}
		}
	}
	if (vOption == preferredSize || vOption == expandPreferredSize)
	{
		if (vSize != unspecifiedSize && vSize < 20)
		{
			return vAutoPackError;
		}
		if (hOption == forcedSize)
		{
			if (vSize != unspecifiedSize && vSize < hnew)
			{
				return vAutoPackError;
			}
			vnew = hnew;
		}
		else
		{
			if (vOption == expandPreferredSize ||
				(vSize != unspecifiedSize && vSize <= 100))
			{
				vnew = vSize;
			}
			else
			{
				vnew = 100;
			}
		}
	}

	// Handle one more case: neither vertical nor horizontal were forced,
	// but they evaluated to different sizes. To make it square, pick the
	// smaller size
	if (hnew != vnew)
	{
		hnew = vnew = min(hnew, vnew);
	}

	// Resize widget
	Reshape(hnew, vnew);

	// Done!
	return noAutoPackError;
}

/*
===============================================================================
*/

<commit_msg>Ballwidget now has a textured ball and an appearance consistent with other GLOW widgets.<commit_after>/*
===============================================================================

	FILE:  ballwidget.cpp

	PROJECT:

		GLOW widgets for glutmech demo

	CONTENTS:

		Ball widget

	PROGRAMMERS:

		Daniel Azuma <dazuma@kagi.com>
		John Nagle <nagle@animats.com>

	COPYRIGHT:

		Copyright (C) 2000  Daniel Azuma  (dazuma@kagi.com)

		This library is free software; you can redistribute it and/or
		modify it under the terms of the GNU Lesser General Public
		License as published by the Free Software Foundation; either
		version 2.1 of the License, or (at your option) any later version.

		This library is distributed in the hope that it will be useful,
		but WITHOUT ANY WARRANTY; without even the implied warranty of
		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
		GNU Lesser General Public License for more details.

		You should have received a copy of the GNU Lesser General Public
		License along with this library; if not, write to
			Free Software Foundation, Inc.
			59 Temple Place, Suite 330
			Boston, MA 02111-1307 USA

	VERSION:

		The GLOW Toolkit tutorial -- version 1.0.3  (10 September 2000)

	CHANGES:

		Original release (DA)
		2001-09-25 Converting to texture-mapped trackball. (JN)

===============================================================================
*/

/*
===============================================================================
	Headers and declarations
===============================================================================
*/

#include <algorithm>

using namespace std;

#include "glowViewTransform.h"

GLOW_NAMESPACE_USING

#include "ballwidget.h"
//
//	class DrawCircle  --  draw a filled circle
//
class DrawCircle {
private:
	float radius_;
	GLuint displayList_;
private:
	void Init();
public:
	DrawCircle(float radius):
		radius_(radius),displayList_(0) {}
	void Draw();
};
//
//	Init  --  called to build display list.
//
void DrawCircle::Init()
{	if (displayList_ != 0) return;		// already built
	displayList_ = glGenLists(1);		// get a new list
	if (displayList_ == 0) throw("OpenGL/Glow: can't allocate display list.");
	glNewList(displayList_,GL_COMPILE);	// circle display list
	glEnable(GL_LINE_SMOOTH);
	glBegin(GL_POLYGON);
	const int sides = 32;				// number of sides for circle
	for (int i=0; i<sides; i++)
	{	float angle = i*((Math::pi*2.0)/sides);	// angle of circle
		float x = sin(angle)*radius_;	// circle of indicated radius
		float y = cos(angle)*radius_;
		glVertex2f(x,y);
	}
	glEnd();
	glEndList();						// end the list
}
//
//	Draw  --  draws a circle
//
void DrawCircle::Draw()
{	Init();								// set up as needed
	glCallList(displayList_);			// draw the circle
}
static DrawCircle unitCircle(1.0);		// set up to draw circle
static DrawCircle innerCircle(0.95);	// smaller, inner circle
//
//	class CheckerboardTexture  --  a texture object of a checkerboard
//
//	This object cannot be initialized statically, because OpenGL isn't ready
//	at static construction time.
//
class CheckerboardTexture {
private:
	GLuint _textureID;					// texture ID if any
	int _darkColor;						// color of lines
	int _lightColor;					// color of background
private:
	Init();								// called on first GetID to initialize
public:
	CheckerboardTexture(int dark, int light):
	  _darkColor(dark),_lightColor(light),_textureID(0) {}
	GLuint GetID()
	{	if (_textureID == 0) Init();	// initialize if needed
		return(_textureID);
	}
};
//
//	Init  --  initial setup of a checkerboard texture.
//
//	Returns: OpenGL texture "name" (an integer ID)
//	Called at first GetID; can't be called until OpenGL is running.
//
//	Modelled after code in "OpenGL Programming Guide" and GLUI.
//
CheckerboardTexture::Init()
{	//	Build checkerboard image procedurally.
	const int kCheckerboardSize = 64;		// typical 64x64 texture
	unsigned char texture_image[kCheckerboardSize][kCheckerboardSize][3];
	for(int i=0; i<kCheckerboardSize; i++ )
		for(int j=0; j<kCheckerboardSize; j++ ) {
		{	bool isdark = ((i&0x8)==0) != ((j&0x8)==0);
			char texbyte = isdark ? _darkColor : _lightColor;	// pick texture byte
			texture_image[i][j][0] = texbyte;		// all colors same, thus grey
			texture_image[i][j][1] = texbyte;
			texture_image[i][j][2] = texbyte;
		}
	}
	//	Usual OpenGL ritual to setup a texture.
	GLuint textureNames[1] = { 0 };					// we need one texture name
	glPushAttrib(GL_ALL_ATTRIB_BITS);				// save OpenGL state
	glGenTextures(1,textureNames);					// get one
	glBindTexture(GL_TEXTURE_2D,textureNames[0]);	// bind it to next texture
	glColor3f( 1.0, 1.0, 1.0 );
	glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
	glEnable( GL_TEXTURE_2D);
	glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, kCheckerboardSize,
		kCheckerboardSize, 0, GL_RGB, GL_UNSIGNED_BYTE,
		texture_image );
	glPopAttrib();									// restore OpenGL state
	_textureID = textureNames[0];					// set name of new texture
	if (_textureID == 0) throw("OpenGL/GLOW: unable to create texture.");

}
//	A checkerboard texture to wrap around the arcball
static CheckerboardTexture darkCheckerboard(110,220);
/*
===============================================================================
	Component that draws a solid sphere with a checkerboard texture.
===============================================================================
*/

class DrawTexturedSphere :
	public GlowComponent
{
	private:
		GLUquadric* _texturedSphere;			// ID of sphere object
	public:

		DrawTexturedSphere(
			GlowComponent* parent) :
		GlowComponent(parent),_texturedSphere(0) {}
		virtual ~DrawTexturedSphere()			// destructor
		{	if (_texturedSphere) gluDeleteQuadric(_texturedSphere);
		}

	protected:
		virtual void OnEndPaint();
		virtual void Init();
};
//
//	Init  -- initialization, called on first draw
//
void DrawTexturedSphere::Init()
{
	if (_texturedSphere != 0) return;	// already initialized
	_texturedSphere = gluNewQuadric();
	if (!_texturedSphere) throw("OpenGL/GLOW: unable to create sphere.");
	gluQuadricDrawStyle(_texturedSphere, GLU_FILL);
    gluQuadricNormals(_texturedSphere, GLU_SMOOTH);
    gluQuadricTexture(_texturedSphere, true );
}

void DrawTexturedSphere::OnEndPaint()
{	const float radius = 0.9;				// sphere fills 0.9 of unit square
	Init();									// build sphere object if needed
	::glPushAttrib(GL_ALL_ATTRIB_BITS);		// save state
	::glEnable(GL_TEXTURE_2D);
	::glEnable(GL_CULL_FACE);
	::glDisable(GL_DEPTH_TEST);
	::glBindTexture(GL_TEXTURE_2D,darkCheckerboard.GetID());	// use specified texture
	::glColor3ub(255, 255, 255);			// Color gets modulated by texture
    ::gluSphere(_texturedSphere, radius, 16, 16);
	::glPopAttrib();
}

/*
===============================================================================
	Methods of BallWidget
===============================================================================
*/

BallWidget::BallWidget(
	GlowWidget* parent,
	int x,
	int y,
	int width)
{
	GLOW_DEBUGSCOPE("BallWidget::BallWidget");

	// Initialize widget
	GlowWidgetParams params;
	params.x = x;
	params.y = y;
	params.width = params.height = width;
	GlowWidget::Init(parent->Root(), parent, params);

	// Make view manipulator and drawing component
	manip_ = new GlowViewManipulator(this, GlowViewManipulatorParams::defaults);
	new DrawTexturedSphere(manip_);

	// Register to receive mouse events
	RegisterMouseEvents();
}

// Override this method to draw the widget
void BallWidget::OnWidgetPaint()
{	const float trackballBackgroundGrey = 0.9;	// outer ring around trackball
	const float trackballInnerGrey = 0.3;	// inner ring around trackball
		//	Start by drawing a circle around the control.
	::glPushAttrib(GL_ALL_ATTRIB_BITS);		// save state
	::glDisable(GL_DEPTH_TEST);
	::glColor3f(trackballBackgroundGrey,trackballBackgroundGrey,trackballBackgroundGrey);
	unitCircle.Draw();						// circle
	::glColor3f(trackballInnerGrey,trackballInnerGrey,trackballInnerGrey);
	innerCircle.Draw();						// inner circle
	::glPopAttrib();

}

// Handle mouse down in widget events
void BallWidget::OnWidgetMouseDown(
	Glow::MouseButton button,
	int x,
	int y,
	Glow::Modifiers modifiers)
{
	GLOW_DEBUGSCOPE("BallWidget::OnWidgetMouseDown");

	if (!manip_->IsDragging())
	{
		GLfloat xn;
		GLfloat yn;
		NormalizeCoordinates(x, y, xn, yn);
		manip_->BeginRotationDrag(xn, yn);
		button_ = button;
		modifiers_ = modifiers;
	}
}

// Handle mouse up in widget events
void BallWidget::OnWidgetMouseUp(
	Glow::MouseButton button,
	int x,
	int y,
	Glow::Modifiers modifiers)
{
	GLOW_DEBUGSCOPE("BallWidget::OnWidgetMouseUp");

	if (manip_->IsDragging())
	{
		GLfloat xn;
		GLfloat yn;
		NormalizeCoordinates(x, y, xn, yn);
		manip_->EndDrag(xn, yn);
		OnReleased(button_, modifiers_);
	}
}

// Handle mouse drag in widget events
void BallWidget::OnWidgetMouseDrag(
	int x,
	int y)
{
	GLOW_DEBUGSCOPE("BallWidget::OnWidgetMouseDrag");

	if (manip_->IsDragging())
	{
		GLfloat xn;
		GLfloat yn;
		NormalizeCoordinates(x, y, xn, yn);
		manip_->InDrag(xn, yn);
		OnDragged(button_, modifiers_);
	}
}

// Default method for handling trackball dragged events
void BallWidget::OnDragged(
	Glow::MouseButton button,
	Glow::Modifiers modifiers)
{
	GLOW_DEBUGSCOPE("BallWidget::OnDragged");

	// Send event message to receivers
	BallMessage message;
	message.widget = this;
	message.rotation = manip_->GetRotation();
	message.released = false;
	message.mouseButton = button;
	message.modifiers = modifiers;
	sender_.Send(message);
}

// Default method for handling trackball released events
void BallWidget::OnReleased(
	Glow::MouseButton button,
	Glow::Modifiers modifiers)
{
	GLOW_DEBUGSCOPE("BallWidget::OnReleased");

	// Send event message to receivers
	BallMessage message;
	message.widget = this;
	message.rotation = manip_->GetRotation();
	message.released = true;
	message.mouseButton = button;
	message.modifiers = modifiers;
	sender_.Send(message);
}

// Automatically resize widget according to constraints
GlowWidget::AutoPackError BallWidget::OnAutoPack(
	int hSize,
	int vSize,
	AutoPackOptions hOption,
	AutoPackOptions vOption,
	int& leftMargin,
	int& rightMargin,
	int& topMargin,
	int& bottomMargin)
{
	GLOW_DEBUGSCOPE("BallWidget::OnAutoPack");

	int hnew;
	int vnew;

	// noReshape is kind of like forcedSize for our purposes. We'll
	// fold the two options into one to make our life easier.
	if (hOption == noReshape)
	{
		hOption = forcedSize;
		hSize = Width();
	}
	if (vOption == noReshape)
	{
		vOption = forcedSize;
		vSize = Height();
	}

	// Handle forcedSize first
	// If forcing different sizes, fail because we want the widget square
	if (hOption == forcedSize && vOption == forcedSize && hSize != vSize)
	{
		return hAutoPackError;
	}
	// Set to the forced size, if it's not too small
	if (hOption == forcedSize)
	{
		if (hSize < 20)
		{
			return hAutoPackError;
		}
		hnew = hSize;
	}
	if (vOption == forcedSize)
	{
		if (vSize < 20)
		{
			return vAutoPackError;
		}
		vnew = vSize;
	}

	// Handle preferredSize and expandPreferredSize
	if (hOption == preferredSize || hOption == expandPreferredSize)
	{
		// Make sure the constraint isn't too small
		if (hSize != unspecifiedSize && hSize < 20)
		{
			return hAutoPackError;
		}
		// Adjust constraint if vertical size is already forced
		if (vOption == forcedSize)
		{
			// Do vertical forced size and horizontal constraint conflict?
			if (hSize != unspecifiedSize && hSize < vnew)
			{
				return hAutoPackError;
			}
			hnew = vnew;
		}
		else
		{
			// If using expandPreferredSize or constraint is smaller than 100
			// then set the size to the constraint, otherwise set it to 100.
			if (hOption == expandPreferredSize ||
				(hSize != unspecifiedSize && hSize <= 100))
			{
				hnew = hSize;
			}
			else
			{
				hnew = 100;
			}
		}
	}
	if (vOption == preferredSize || vOption == expandPreferredSize)
	{
		if (vSize != unspecifiedSize && vSize < 20)
		{
			return vAutoPackError;
		}
		if (hOption == forcedSize)
		{
			if (vSize != unspecifiedSize && vSize < hnew)
			{
				return vAutoPackError;
			}
			vnew = hnew;
		}
		else
		{
			if (vOption == expandPreferredSize ||
				(vSize != unspecifiedSize && vSize <= 100))
			{
				vnew = vSize;
			}
			else
			{
				vnew = 100;
			}
		}
	}

	// Handle one more case: neither vertical nor horizontal were forced,
	// but they evaluated to different sizes. To make it square, pick the
	// smaller size
	if (hnew != vnew)
	{
		hnew = vnew = min(hnew, vnew);
	}

	// Resize widget
	Reshape(hnew, vnew);

	// Done!
	return noAutoPackError;
}

/*
===============================================================================
*/

<|endoftext|>


<commit_before>/*
*  SixTrack Wrapper for Pythia8
*  V.K. Berglyd Olsen, BE-ABP-HSS
*  Last modified: 2018-07-30
*/

#include "pythia_wrapper.h"

using namespace Pythia8;

extern "C" {

bool pythiaWrapper_init() {
  if(!pythia.init()) return false;
  pythia.settings.writeFile("pythia_settings.dat", true);
  std::cout << "PYTHIA> Done" << std::endl;
  return true;
}

bool pythiaWrapper_defaults() {
  std::cout << "PYTHIA> Setting defaults" << std::endl;
  pythia.settings.flag("Init:showChangedSettings", true);
  pythia.settings.flag("Init:showChangedParticleData", false);
  pythia.settings.flag("SigmaTotal:mode", 3);
  pythia.settings.flag("SigmaDiffractive:mode", 3);
  return true;
}

void pythiaWrapper_setProcess(bool sEL, bool sSD, bool sDD, bool sCD, bool sND) {
  std::cout << "PYTHIA> Setting processes" << std::endl;
  pythia.settings.flag("SoftQCD:elastic", sEL);
  pythia.settings.flag("SoftQCD:singleDiffractive", sSD);
  pythia.settings.flag("SoftQCD:doubleDiffractive", sDD);
  pythia.settings.flag("SoftQCD:centralDiffractive", sCD);
  pythia.settings.flag("SoftQCD:nonDiffractive", sND);
}

void pythiaWrapper_setCoulomb(bool sCMB, double tAbsMin) {
  pythia.settings.flag("SigmaElastic:Coulomb", sCMB);
  pythia.settings.parm("SigmaElastic:tAbsMin", tAbsMin);
}

void pythiaWrapper_setSeed(int rndSeed) {
  std::cout << "PYTHIA> Setting random seed" << std::endl;
  pythia.settings.mode("Random:seed", rndSeed);
}

void pythiaWrapper_setBeam(int frameType, int idA, int idB, double eA, double eB) {
  std::cout << "PYTHIA> Setting beam parameters" << std::endl;
  pythia.settings.mode("Beams:frameType", frameType);
  pythia.settings.mode("Beams:idA", idA);
  pythia.settings.mode("Beams:idB", idB);
  pythia.settings.parm("Beams:eA", eA);
  pythia.settings.parm("Beams:eB", eB);
}

void pythiaWrapper_readFile(char* fileName) {
  std::cout << "PYTHIA> Loading settings from external file" << std::endl;
  pythia.readFile(std::string(fileName));
}

void pythiaWrapper_getCrossSection(double& sigTot, double& sigEl) {
  // sigTot = pythia.info.sigmaGen(0);
  sigTot = pythia.parm("SigmaTotal:sigmaTot");
  sigEl  = pythia.parm("SigmaTotal:sigmaEl");
}

void pythiaWrapper_getEvent(bool& status, int& code, double& t, double& theta, double& dEE, double& dPP) {
  status = pythia.next();
  code   = pythia.info.code();
  if(!status) {
    code  = 0;
    t     = 0.0;
    theta = 0.0;
    dEE   = 0.0;
    dPP   = 0.0;
    return;
  }
  if(code == 101) {
    t     = 0.0;
    theta = 0.0;
    dEE   = 0.0;
    dPP   = 0.0;
  }
  else if(code == 102) { // Elastic
    t     =  pythia.info.tHat();
    theta =  pythia.event[3].theta();
    dEE   = (pythia.event[3].e()    - pythia.event[1].e())    / pythia.event[1].e();
    dPP   = (pythia.event[3].pAbs() - pythia.event[1].pAbs()) / pythia.event[1].pAbs();
  }
  else if(code == 104) { // Single Diffractive AB->AX
    t     =  pythia.info.tHat();
    theta =  pythia.event[3].theta();
    dEE   = (pythia.event[3].e()    - pythia.event[1].e())    / pythia.event[1].e();
    dPP   = (pythia.event[3].pAbs() - pythia.event[1].pAbs()) / pythia.event[1].pAbs();
  }
  else if(code == 106) { // Central Diffractive AB->AXB
    t     = (pythia.event[3].p()    - pythia.event[1].p()).m2Calc();
    theta =  pythia.event[3].theta();
    dEE   = (pythia.event[3].e()    - pythia.event[1].e())    / pythia.event[1].e();
    dPP   = (pythia.event[3].pAbs() - pythia.event[1].pAbs()) / pythia.event[1].pAbs();
  }
  else {
    t     = 0.0;
    theta = 0.0;
    dEE   = 0.0;
    dPP   = 0.0;
  }
}

}
<commit_msg>Updated pythia interface<commit_after>/*
*  SixTrack Wrapper for Pythia8
*  V.K. Berglyd Olsen, BE-ABP-HSS
*  Created: 2018-07-30
*  Updated: 2019-07-17
*/

#include "pythia_wrapper.h"

using namespace Pythia8;

extern "C" {

bool pythiaWrapper_init() {
  if(!pythia.init()) return false;
  pythia.settings.writeFile("pythia_settings.dat", true);
  std::cout << "PYTHIA> Done" << std::endl;
  return true;
}

bool pythiaWrapper_defaults() {
  std::cout << "PYTHIA> Setting defaults" << std::endl;
  pythia.settings.flag("Init:showChangedSettings", true);
  pythia.settings.flag("Init:showChangedParticleData", false);
  pythia.settings.flag("SigmaTotal:mode", 3);
  pythia.settings.flag("SigmaDiffractive:mode", 3);
  return true;
}

void pythiaWrapper_setProcess(bool sEL, bool sSD, bool sDD, bool sCD, bool sND) {
  std::cout << "PYTHIA> Setting processes" << std::endl;
  pythia.settings.flag("SoftQCD:elastic", sEL);
  pythia.settings.flag("SoftQCD:singleDiffractive", sSD);
  pythia.settings.flag("SoftQCD:doubleDiffractive", sDD);
  pythia.settings.flag("SoftQCD:centralDiffractive", sCD);
  pythia.settings.flag("SoftQCD:nonDiffractive", sND);
}

void pythiaWrapper_setCoulomb(bool sCMB, double tAbsMin) {
  pythia.settings.flag("SigmaElastic:Coulomb", sCMB);
  pythia.settings.parm("SigmaElastic:tAbsMin", tAbsMin);
}

void pythiaWrapper_setSeed(int rndSeed) {
  std::cout << "PYTHIA> Setting random seed" << std::endl;
  pythia.settings.mode("Random:seed", rndSeed);
}

void pythiaWrapper_setBeam(int frameType, int idA, int idB, double eA, double eB) {
  std::cout << "PYTHIA> Setting beam parameters" << std::endl;
  pythia.settings.mode("Beams:frameType", frameType);
  pythia.settings.mode("Beams:idA", idA);
  pythia.settings.mode("Beams:idB", idB);
  pythia.settings.parm("Beams:eA", eA);
  pythia.settings.parm("Beams:eB", eB);
  if(frameType == 3) {
    pythia.settings.flag("Beams:allowVariableEnergy", true);
  }
}

void pythiaWrapper_readFile(char* fileName) {
  std::cout << "PYTHIA> Loading settings from external file" << std::endl;
  pythia.readFile(std::string(fileName));
}

void pythiaWrapper_getCrossSection(double& sigTot, double& sigEl) {
  // sigTot = pythia.info.sigmaGen(0);
  sigTot = pythia.parm("SigmaTotal:sigmaTot");
  sigEl  = pythia.parm("SigmaTotal:sigmaEl");
}

/**
 *  SoftQCD Events
 * ================
 *  101 : Non-Diffrcative
 *  102 : Elastic             AB -> AB
 *  103 : Single Diffractive  AB -> XB
 *  104 : Single Diffractive  AB -> AX
 *  105 : Double Diffractive  AB -> XX
 *  106 : Central Diffractive AB -> AXB
 */

void pythiaWrapper_getEvent(bool& status, int& code, double& t, double& theta, double& dEE, double& dPP) {
  status = pythia.next();
  code   = pythia.info.code();
  if(!status) {
    code  = 0;
    t     = 0.0;
    theta = 0.0;
    dEE   = 0.0;
    dPP   = 0.0;
    return;
  }
  if(code == 101) {
    t     = 0.0;
    theta = 0.0;
    dEE   = 0.0;
    dPP   = 0.0;
  }
  else if(code == 102) { // Elastic
    t     =  pythia.info.tHat();
    theta =  pythia.event[3].theta();
    dEE   = (pythia.event[3].e()    - pythia.event[1].e())    / pythia.event[1].e();
    dPP   = (pythia.event[3].pAbs() - pythia.event[1].pAbs()) / pythia.event[1].pAbs();
  }
  else if(code == 104) { // Single Diffractive AB->AX
    t     =  pythia.info.tHat();
    theta =  pythia.event[3].theta();
    dEE   = (pythia.event[3].e()    - pythia.event[1].e())    / pythia.event[1].e();
    dPP   = (pythia.event[3].pAbs() - pythia.event[1].pAbs()) / pythia.event[1].pAbs();
  }
  else if(code == 106) { // Central Diffractive AB->AXB
    t     = (pythia.event[3].p()    - pythia.event[1].p()).m2Calc();
    theta =  pythia.event[3].theta();
    dEE   = (pythia.event[3].e()    - pythia.event[1].e())    / pythia.event[1].e();
    dPP   = (pythia.event[3].pAbs() - pythia.event[1].pAbs()) / pythia.event[1].pAbs();
  }
  else {
    t     = 0.0;
    theta = 0.0;
    dEE   = 0.0;
    dPP   = 0.0;
  }
}

void pythiaWrapper_getEventPVector(bool& status, int& code, double& t, double& theta, double& dEE, double& dPP, double* vecPin, double* vecPout) {

  status = pythia.next(vecPin[0],vecPin[1],vecPin[2],vecPin[3],vecPin[4],vecPin[5]);
  code   = pythia.info.code();

  t      = 0.0;
  theta  = 0.0;
  dEE    = 0.0;
  dPP    = 0.0;

  if(code == 102 || code == 104 || code == 106) {
    theta =  pythia.event[3].theta();
    dEE   = (pythia.event[3].e()    - pythia.event[1].e())    / pythia.event[1].e();
    dPP   = (pythia.event[3].pAbs() - pythia.event[1].pAbs()) / pythia.event[1].pAbs();
  }
  if(code == 102 || code == 104) {
    t = pythia.info.tHat();
  }
  if(code == 106) {
    t = (pythia.event[3].p() - pythia.event[1].p()).m2Calc();
  }

  vecPin[0]  = pythia.event[1].px();
  vecPin[1]  = pythia.event[1].py();
  vecPin[2]  = pythia.event[1].pz();
  vecPin[3]  = pythia.event[2].px();
  vecPin[4]  = pythia.event[2].py();
  vecPin[5]  = pythia.event[2].pz();
  vecPout[0] = pythia.event[3].px();
  vecPout[1] = pythia.event[3].py();
  vecPout[2] = pythia.event[3].pz();
  vecPout[3] = pythia.event[4].px();
  vecPout[4] = pythia.event[4].py();
  vecPout[5] = pythia.event[4].pz();

}

}
<|endoftext|>