SVN_SILENT made messages (.desktop file)
[kdeartwork.git] / kscreensaver / kxsconfig / kxsrun.cpp
blob409f716a4ed8166d41685386b33086d69e47471c
1 //-----------------------------------------------------------------------------
2 //
3 // KDE xscreensaver launcher
4 //
5 // Copyright (c) Martin R. Jones <mjones@kde.org> 1999
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public
9 // License as published by the Free Software Foundation;
10 // version 2 of the License.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; see the file COPYING. If not, write to
19 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 // Boston, MA 02110-1301, USA.
21 #include <config-kxsconfig.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <unistd.h>
27 #include <qfile.h>
28 #include <qfileinfo.h>
30 #include <kdebug.h>
31 #include <kapplication.h>
32 #include <kconfig.h>
33 #include <kstandarddirs.h>
34 #include <klocale.h>
35 #include <kcmdlineargs.h>
37 #include "kxsitem.h"
38 #include "kxsxml.h"
40 #define MAX_ARGS 30
42 //===========================================================================
43 static const char appName[] = "kxsrun";
45 static const char description[] = I18N_NOOP("KDE X Screen Saver Launcher");
47 static const char version[] = "3.0.0";
49 int main(int argc, char *argv[])
51 KLocale::setMainCatalog("kxsconfig");
52 KCmdLineArgs::init(argc, argv, appName, 0, ki18n("KXSRun"), version, ki18n(description));
55 KCmdLineOptions options;
57 options.add("+screensaver", ki18n("Filename of the screen saver to start"));
59 options.add("+-- [options]", ki18n("Extra options to pass to the screen saver"));
61 KCmdLineArgs::addCmdLineOptions(options);
63 KApplication app( false );
65 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
67 if ( !args->count() )
68 exit( 1 );
70 QString filename = args->arg(0);
71 QString configFile(filename);
73 // Get the config filename
74 int slash = filename.lastIndexOf('/');
75 if (slash >= 0)
76 configFile = filename.mid(slash+1);
78 QString exeName = configFile;
79 configFile += "rc";
81 // read configuration args
82 KConfig config(configFile);
84 QList<KXSConfigItem*> configItemList;
86 QString xmlFile = "/doesntexist";
87 #ifdef XSCREENSAVER_CONFIG_DIR
88 xmlFile = XSCREENSAVER_CONFIG_DIR;
89 #endif
90 xmlFile += "/" + exeName + ".xml";
91 if ( QFile::exists( xmlFile ) ) {
92 // We can use the xscreensaver xml config files.
93 KXSXml xmlParser(0);
94 xmlParser.parse(xmlFile);
95 configItemList = xmlParser.items();
96 for ( int i = 0; i < configItemList.size(); i++ ) {
97 configItemList[i]->read( config );
99 } else {
100 // fall back to KDE's old config files.
101 int idx = 0;
102 while (true)
104 QString group = QString("Arg%1").arg(idx);
105 if (config.hasGroup(group)) {
106 KConfigGroup grp = config.group(group);
107 QString type = grp.readEntry("Type");
108 if (type == "Range") {
109 KXSRangeItem *rc = new KXSRangeItem(group, config);
110 configItemList.append(rc);
111 } else if (type == "DoubleRange") {
112 KXSDoubleRangeItem *rc = new KXSDoubleRangeItem(group, config);
113 configItemList.append(rc);
114 } else if (type == "Check") {
115 KXSBoolItem *cc = new KXSBoolItem(group, config);
116 configItemList.append(cc);
117 } else if (type == "DropList") {
118 KXSSelectItem *si = new KXSSelectItem(group, config);
119 configItemList.append(si);
121 } else {
122 break;
124 idx++;
128 // find the xscreensaver executable
129 //work around a KStandarDirs::findExe() "feature" where it looks in $KDEDIR/bin first no matter what and sometimes finds the wrong executable
130 QFileInfo checkExe;
131 QString saverdir = QString("%1/%2").arg(XSCREENSAVER_HACKS_DIR).arg(filename);
132 kDebug() << "saverdir is" << saverdir;
133 QByteArray exeFile;
134 checkExe.setFile(saverdir);
135 if (checkExe.exists() && checkExe.isExecutable() && checkExe.isFile())
137 exeFile = QFile::encodeName(saverdir);
141 if (!exeFile.isEmpty()) {
142 char *sargs[MAX_ARGS];
145 QByteArray encodedFile = QFile::encodeName(filename);
146 sargs[0] = new char [encodedFile.size()+1];
147 strcpy(sargs[0], encodedFile.constData());
150 // add the command line options
151 QString cmd;
152 int i;
153 for (i = 1; i < args->count(); i++)
154 cmd += " " + QString(args->arg(i));
156 // add the config options
157 for ( int i = 0; i < configItemList.size(); i++ ) {
158 cmd += " " + configItemList[i]->command();
161 // put into char * array for execv
162 QString word;
163 int si = 1;
164 i = 0;
165 bool inQuotes = false;
166 while (i < cmd.length() && si < MAX_ARGS-1) {
167 word = "";
168 while ( cmd[i].isSpace() && i < cmd.length() ) i++;
169 while ( (!cmd[i].isSpace() || inQuotes) && i < cmd.length() ) {
170 if ( cmd[i] == '\"' ) {
171 inQuotes = !inQuotes;
172 } else {
173 word += cmd[i];
175 i++;
177 if (!word.isEmpty()) {
178 // filenames are likely to be the troublesome encodings
179 QByteArray encodedWord = QFile::encodeName(word);
180 sargs[si] = new char [encodedWord.size()+1];
181 strcpy(sargs[si], encodedWord.constData());
182 si++;
186 sargs[si] = 0;
188 // here goes...
189 execv(exeFile.constData(), sargs);