main.cpp 5.21 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
    Copyright 2011-2012 Heikki Holstila <heikki.holstila@gmail.com>

    This file is part of FingerTerm.

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

    FingerTerm 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with FingerTerm.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "qplatformdefs.h"

#include <QtGui>
jbrooks's avatar
jbrooks committed
23
#include <QtQml>
24
#include <QQuickView>
25 26
#include <QDir>
#include <QString>
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

extern "C" {
#include <pty.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
}

#include "ptyiface.h"
#include "terminal.h"
#include "textrender.h"
#include "util.h"
#include "version.h"
#include "keyloader.h"

int main(int argc, char *argv[])
{
45 46 47 48 49 50 51 52 53
    QString settings_path(QDir::homePath() + "/.config/FingerTerm");
    QDir dir;

    if (!dir.exists(settings_path)) {
        if (!dir.mkdir(settings_path))
            qWarning() << "Could not create fingerterm settings path" << settings_path;
    }

    QSettings *settings = new QSettings(settings_path + "/settings.ini", QSettings::IniFormat);
54

55 56
    QCoreApplication::setApplicationName("Fingerterm");

jbrooks's avatar
jbrooks committed
57
    // fork the child process before creating QGuiApplication
58 59 60 61 62 63
    int socketM;
    int pid = forkpty(&socketM,NULL,NULL,NULL);
    if( pid==-1 ) {
        qFatal("forkpty failed");
        exit(1);
    } else if( pid==0 ) {
64
        setenv("TERM", settings->value("terminal/envVarTERM", "xterm").toByteArray(), 1);
65 66 67 68 69 70 71 72 73 74

        QString execCmd;
        for(int i=0; i<argc-1; i++) {
            if( QString(argv[i]) == "-e" )
                execCmd = QString(argv[i+1]);
        }
        if(execCmd.isEmpty()) {
            execCmd = settings->value("general/execCmd").toString();
        }

Pekka Vuorela's avatar
Pekka Vuorela committed
75
        delete settings; // don't need 'em here
76

77 78 79 80 81 82 83
        passwd *pwdstruct = getpwuid(getuid());
        char *shell = pwdstruct->pw_shell;
        if (execCmd.isEmpty()) {
            // execute the user's default shell
            execl(shell, shell, "--login", (char*)NULL);
        } else {
            execl(shell, shell, "-c", qPrintable(execCmd), (char*)NULL);
84 85 86 87 88
        }

        exit(0);
    }

jbrooks's avatar
jbrooks committed
89
    QGuiApplication app(argc, argv);
90

91 92
    QScreen* sc = app.primaryScreen();
    if(sc){
elros34's avatar
elros34 committed
93 94 95 96 97 98 99 100 101
        QFlags<Qt::ScreenOrientation> mask = Qt::PrimaryOrientation
                | Qt::PortraitOrientation
                | Qt::LandscapeOrientation
                | Qt::InvertedPortraitOrientation
                | Qt::InvertedLandscapeOrientation;
        if (settings->contains("ui/orientationMask")) {
            mask &= settings->value("ui/orientationMask").toInt();
        }
        sc->setOrientationUpdateMask(mask);
102 103
    }

104 105
    qmlRegisterType<TextRender>("FingerTerm", 1, 0, "TextRender");
    qmlRegisterUncreatableType<Util>("FingerTerm", 1, 0, "Util", "Util is created by app");
106
    QQuickView view;
107

108 109 110 111 112 113 114 115 116 117 118
    bool fullscreen = !app.arguments().contains("-nofs");
    QSize screenSize = QGuiApplication::primaryScreen()->size();

    if (fullscreen) {
        view.setWidth(screenSize.width());
        view.setHeight(screenSize.height());
    } else {
        view.setWidth(screenSize.width() / 2);
        view.setHeight(screenSize.height() / 2);
    }

119
    Terminal term;
120
    Util util(settings); // takes ownership
121
    term.setUtil(&util);
122 123 124
    TextRender::setUtil(&util);
    TextRender::setTerminal(&term);

125 126 127 128
    QString startupErrorMsg;

    KeyLoader keyLoader;
    keyLoader.setUtil(&util);
129
    bool ret = keyLoader.loadLayout(util.keyboardLayout());
130 131 132
    if(!ret) {
        // on failure, try to load the default one (english) directly from resources
        startupErrorMsg = "There was an error loading the keyboard layout.<br>\nUsing the default one instead.";
133
        util.setKeyboardLayout("english");
134 135 136 137 138
        ret = keyLoader.loadLayout(":/data/english.layout");
        if(!ret)
            qFatal("failure loading keyboard layout");
    }

jbrooks's avatar
jbrooks committed
139
    QQmlContext *context = view.rootContext();
140 141 142
    context->setContextProperty( "term", &term );
    context->setContextProperty( "util", &util );
    context->setContextProperty( "keyLoader", &keyLoader );
143
    context->setContextProperty( "startupErrorMessage", startupErrorMsg);
144

145 146 147 148 149 150
    term.setWindow(&view);
    util.setWindow(&view);
    util.setTerm(&term);

    QObject::connect(view.engine(),SIGNAL(quit()),&app,SLOT(quit()));

151
    view.setResizeMode(QQuickView::SizeRootObjectToView);
152 153
    view.engine()->addImportPath(QStringLiteral(DEPLOYMENT_PATH));
    view.setSource(QUrl::fromLocalFile(QStringLiteral(DEPLOYMENT_PATH) + QDir::separator() + QStringLiteral("Main.qml")));
154

155 156
    QObject *root = view.rootObject();
    if(!root)
157 158
        qFatal("no root object - qml error");

159
    if (fullscreen) {
160
        view.showFullScreen();
161
    } else {
162
        view.show();
163
    }
Herrie's avatar
Herrie committed
164

165
    PtyIFace ptyiface(pid, socketM, &term, util.charset());
166 167 168 169 170 171

    if( ptyiface.failed() )
        qFatal("pty failure");

    return app.exec();
}