Back to index

kdeartwork  4.3.2
kxsrun.cpp
Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 //
00003 // KDE xscreensaver launcher
00004 //
00005 // Copyright (c)  Martin R. Jones <mjones@kde.org> 1999
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public
00009 // License as published by the Free Software Foundation;
00010 // version 2 of the License.
00011 //
00012 // This program is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 // General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with this program; see the file COPYING.  If not, write to
00019 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020 // Boston, MA 02110-1301, USA.
00021 #include <config-kxsconfig.h>
00022 
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <unistd.h>
00026 
00027 #include <qfile.h>
00028 #include <qfileinfo.h>
00029 
00030 #include <kdebug.h>
00031 #include <kapplication.h>
00032 #include <kconfig.h>
00033 #include <kstandarddirs.h>
00034 #include <klocale.h>
00035 #include <kcmdlineargs.h>
00036 
00037 #include "kxsitem.h"
00038 #include "kxsxml.h"
00039 
00040 #define MAX_ARGS  30
00041 
00042 //===========================================================================
00043 static const char appName[] = "kxsrun";
00044 
00045 static const char description[] = I18N_NOOP("KDE X Screen Saver Launcher");
00046 
00047 static const char version[] = "3.0.0";
00048 
00049 int main(int argc, char *argv[])
00050 {
00051     KLocale::setMainCatalog("kxsconfig");
00052     KCmdLineArgs::init(argc, argv, appName, 0, ki18n("KXSRun"), version, ki18n(description));
00053 
00054 
00055     KCmdLineOptions options;
00056 
00057     options.add("+screensaver", ki18n("Filename of the screen saver to start"));
00058 
00059     options.add("+-- [options]", ki18n("Extra options to pass to the screen saver"));
00060 
00061     KCmdLineArgs::addCmdLineOptions(options);
00062 
00063     KApplication app( false );
00064 
00065     KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00066 
00067     if ( !args->count() )
00068        exit( 1 );
00069 
00070     QString filename = args->arg(0);
00071     QString configFile(filename);
00072 
00073     // Get the config filename
00074     int slash = filename.lastIndexOf('/');
00075     if (slash >= 0)
00076        configFile = filename.mid(slash+1);
00077 
00078     QString exeName = configFile;
00079     configFile += "rc";
00080 
00081     // read configuration args
00082     KConfig config(configFile);
00083 
00084     QList<KXSConfigItem*> configItemList;
00085 
00086     QString xmlFile = "/doesntexist";
00087 #ifdef XSCREENSAVER_CONFIG_DIR
00088     xmlFile = XSCREENSAVER_CONFIG_DIR;
00089 #endif
00090     xmlFile += '/' + exeName + ".xml";
00091     if ( QFile::exists( xmlFile ) ) {
00092        // We can use the xscreensaver xml config files.
00093        KXSXml xmlParser(0);
00094        xmlParser.parse(xmlFile);
00095        configItemList = xmlParser.items();
00096         for ( int i = 0; i < configItemList.size(); i++ ) {
00097            configItemList[i]->read( config );
00098        }
00099     } else {
00100        // fall back to KDE's old config files.
00101        int idx = 0;
00102        while (true)
00103        {
00104            QString group = QString("Arg%1").arg(idx);
00105            if (config.hasGroup(group)) {
00106                 KConfigGroup grp = config.group(group);
00107               QString type = grp.readEntry("Type");
00108               if (type == "Range") {
00109                   KXSRangeItem *rc = new KXSRangeItem(group, config);
00110                   configItemList.append(rc);
00111               } else if (type == "DoubleRange") {
00112                   KXSDoubleRangeItem *rc = new KXSDoubleRangeItem(group, config);
00113                   configItemList.append(rc);
00114               } else if (type == "Check") {
00115                   KXSBoolItem *cc = new KXSBoolItem(group, config);
00116                   configItemList.append(cc);
00117               } else if (type == "DropList") {
00118                   KXSSelectItem *si = new KXSSelectItem(group, config);
00119                   configItemList.append(si);
00120               }
00121            } else {
00122               break;
00123            }
00124            idx++;
00125        }
00126     }
00127 
00128     // find the xscreensaver executable
00129     //work around a KStandarDirs::findExe() "feature" where it looks in $KDEDIR/bin first no matter what and sometimes finds the wrong executable
00130     QFileInfo checkExe;
00131     QString saverdir = QString("%1/%2").arg(XSCREENSAVER_HACKS_DIR).arg(filename);
00132     kDebug() << "saverdir is" << saverdir;
00133     QByteArray exeFile;
00134     checkExe.setFile(saverdir);
00135     if (checkExe.exists() && checkExe.isExecutable() && checkExe.isFile())
00136     {
00137         exeFile = QFile::encodeName(saverdir);
00138     }
00139 
00140 
00141     if (!exeFile.isEmpty()) {
00142        char *sargs[MAX_ARGS];
00143 
00144         {
00145             QByteArray encodedFile = QFile::encodeName(filename);
00146             sargs[0] = new char [encodedFile.size()+1];
00147             strcpy(sargs[0], encodedFile.constData());
00148         }
00149 
00150        // add the command line options
00151        QString cmd;
00152        int i;
00153        for (i = 1; i < args->count(); i++)
00154            cmd += ' ' + QString(args->arg(i));
00155 
00156        // add the config options
00157         for ( int i = 0; i < configItemList.size(); i++ ) {
00158            cmd += ' ' + configItemList[i]->command();
00159        }
00160 
00161        // put into char * array for execv
00162        QString word;
00163        int si = 1;
00164        i = 0;
00165        bool inQuotes = false;
00166        while (i < cmd.length() && si < MAX_ARGS-1) {
00167            word = "";
00168            while ( cmd[i].isSpace() && i < cmd.length() ) i++;
00169            while ( (!cmd[i].isSpace() || inQuotes) && i < cmd.length() ) {
00170               if ( cmd[i] == '\"' ) {
00171                   inQuotes = !inQuotes;
00172               } else {
00173                   word += cmd[i];
00174               }
00175               i++;
00176            }
00177            if (!word.isEmpty()) {
00178                 // filenames are likely to be the troublesome encodings
00179                 QByteArray encodedWord = QFile::encodeName(word);
00180               sargs[si] = new char [encodedWord.size()+1];
00181               strcpy(sargs[si], encodedWord.constData());
00182               si++;
00183            }
00184        }
00185 
00186        sargs[si] = 0;
00187 
00188        // here goes...
00189        execv(exeFile.constData(), sargs);
00190     }
00191 }
00192 
00193