autostart.cpp
00001 /* 00002 * 00003 * This file is part of the KDE libraries 00004 * Copyright (c) 2001 Waldo Bastian <bastian@kde.org> 00005 * 00006 * $Id: autostart.cpp 534738 2006-04-27 18:04:45Z lunakl $ 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Library General Public 00010 * License version 2 as published by the Free Software Foundation. 00011 * 00012 * This library 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 * Library General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Library General Public License 00018 * along with this library; see the file COPYING.LIB. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 * Boston, MA 02110-1301, USA. 00021 **/ 00022 00023 #include "autostart.h" 00024 00025 #include <kconfig.h> 00026 #include <kdesktopfile.h> 00027 #include <kglobal.h> 00028 #include <kstandarddirs.h> 00029 00030 class AutoStartItem 00031 { 00032 public: 00033 QString name; 00034 QString service; 00035 QString startAfter; 00036 int phase; 00037 }; 00038 00039 class AutoStartList: public QPtrList<AutoStartItem> 00040 { 00041 public: 00042 AutoStartList() { } 00043 }; 00044 00045 AutoStart::AutoStart( bool new_startup ) 00046 : m_newStartup( new_startup ), m_phase( new_startup ? -1 : 0), m_phasedone(false) 00047 { 00048 m_startList = new AutoStartList; 00049 m_startList->setAutoDelete(true); 00050 KGlobal::dirs()->addResourceType("autostart", "share/autostart"); 00051 QString xdgconf_dirs = KGlobal::dirs()->kfsstnd_xdg_conf_prefixes(); 00052 if (xdgconf_dirs.isEmpty()) 00053 xdgconf_dirs = "/etc/xdg"; 00054 QStringList xdgconf_dirslist = QStringList::split( ':', xdgconf_dirs ); 00055 for ( QStringList::Iterator d = xdgconf_dirslist.begin(); d != xdgconf_dirslist.end(); ++d ) 00056 KGlobal::dirs()->addResourceDir("autostart", (*d) + "/autostart"); 00057 } 00058 00059 AutoStart::~AutoStart() 00060 { 00061 delete m_startList; 00062 } 00063 00064 void 00065 AutoStart::setPhase(int phase) 00066 { 00067 if (phase > m_phase) 00068 { 00069 m_phase = phase; 00070 m_phasedone = false; 00071 } 00072 } 00073 00074 void AutoStart::setPhaseDone() 00075 { 00076 m_phasedone = true; 00077 } 00078 00079 static QString extractName(QString path) 00080 { 00081 int i = path.findRev('/'); 00082 if (i >= 0) 00083 path = path.mid(i+1); 00084 i = path.findRev('.'); 00085 if (i >= 0) 00086 path = path.left(i); 00087 return path; 00088 } 00089 00090 static bool startCondition(const QString &condition) 00091 { 00092 if (condition.isEmpty()) 00093 return true; 00094 00095 QStringList list = QStringList::split(':', condition, true); 00096 if (list.count() < 4) 00097 return true; 00098 if (list[0].isEmpty() || list[2].isEmpty()) 00099 return true; 00100 00101 KConfig config(list[0], true, false); 00102 if (!list[1].isEmpty()) 00103 config.setGroup(list[1]); 00104 00105 bool defaultValue = (list[3].lower() == "true"); 00106 00107 return config.readBoolEntry(list[2], defaultValue); 00108 } 00109 00110 void 00111 AutoStart::loadAutoStartList() 00112 { 00113 QStringList files = KGlobal::dirs()->findAllResources("autostart", "*.desktop", false, true); 00114 00115 for(QStringList::ConstIterator it = files.begin(); 00116 it != files.end(); 00117 ++it) 00118 { 00119 KDesktopFile config(*it, true); 00120 if (!startCondition(config.readEntry("X-KDE-autostart-condition"))) 00121 continue; 00122 if (!config.tryExec()) 00123 continue; 00124 if (config.readBoolEntry("Hidden", false)) 00125 continue; 00126 00127 if (config.hasKey("OnlyShowIn")) 00128 { 00129 if (!config.readListEntry("OnlyShowIn", ';').contains("KDE")) 00130 continue; 00131 } 00132 if (config.hasKey("NotShowIn")) 00133 { 00134 if (config.readListEntry("NotShowIn", ';').contains("KDE")) 00135 continue; 00136 } 00137 00138 AutoStartItem *item = new AutoStartItem; 00139 item->name = extractName(*it); 00140 item->service = *it; 00141 item->startAfter = config.readEntry("X-KDE-autostart-after"); 00142 if( m_newStartup ) 00143 { 00144 item->phase = config.readNumEntry("X-KDE-autostart-phase", 2); 00145 if (item->phase < 0) 00146 item->phase = 0; 00147 } 00148 else 00149 { 00150 item->phase = config.readNumEntry("X-KDE-autostart-phase", 1); 00151 if (item->phase < 1) 00152 item->phase = 1; 00153 } 00154 m_startList->append(item); 00155 } 00156 } 00157 00158 QString 00159 AutoStart::startService() 00160 { 00161 if (m_startList->isEmpty()) 00162 return 0; 00163 00164 while(!m_started.isEmpty()) 00165 { 00166 00167 // Check for items that depend on previously started items 00168 QString lastItem = m_started[0]; 00169 for(AutoStartItem *item = m_startList->first(); 00170 item; item = m_startList->next()) 00171 { 00172 if (item->phase == m_phase 00173 && item->startAfter == lastItem) 00174 { 00175 m_started.prepend(item->name); 00176 QString service = item->service; 00177 m_startList->remove(); 00178 return service; 00179 } 00180 } 00181 m_started.remove(m_started.begin()); 00182 } 00183 00184 // Check for items that don't depend on anything 00185 AutoStartItem *item; 00186 for(item = m_startList->first(); 00187 item; item = m_startList->next()) 00188 { 00189 if (item->phase == m_phase 00190 && item->startAfter.isEmpty()) 00191 { 00192 m_started.prepend(item->name); 00193 QString service = item->service; 00194 m_startList->remove(); 00195 return service; 00196 } 00197 } 00198 00199 // Just start something in this phase 00200 for(item = m_startList->first(); 00201 item; item = m_startList->next()) 00202 { 00203 if (item->phase == m_phase) 00204 { 00205 m_started.prepend(item->name); 00206 QString service = item->service; 00207 m_startList->remove(); 00208 return service; 00209 } 00210 } 00211 00212 return 0; 00213 }