00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qdir.h>
00021
00022 #include "kded.h"
00023 #include "kdedmodule.h"
00024
00025 #include <kresourcelist.h>
00026 #include <kcrash.h>
00027
00028 #include <unistd.h>
00029 #include <stdlib.h>
00030 #include <signal.h>
00031 #include <time.h>
00032
00033 #include <qfile.h>
00034 #include <qtimer.h>
00035
00036 #include <dcopclient.h>
00037
00038 #include <kuniqueapplication.h>
00039 #include <kcmdlineargs.h>
00040 #include <kaboutdata.h>
00041 #include <klocale.h>
00042 #include <kglobal.h>
00043 #include <kprocess.h>
00044 #include <kdebug.h>
00045 #include <kdirwatch.h>
00046 #include <kstandarddirs.h>
00047 #include <kdatastream.h>
00048 #include <kio/global.h>
00049 #include <kservicetype.h>
00050
00051 #ifdef Q_WS_X11
00052 #include <X11/Xlib.h>
00053 #include <fixx11h.h>
00054 #endif
00055
00056 Kded *Kded::_self = 0;
00057
00058 static bool checkStamps = true;
00059 static bool delayedCheck = false;
00060
00061 static void runBuildSycoca(QObject *callBackObj=0, const char *callBackSlot=0)
00062 {
00063 QStringList args;
00064 args.append("--incremental");
00065 if(checkStamps)
00066 args.append("--checkstamps");
00067 if(delayedCheck)
00068 args.append("--nocheckfiles");
00069 else
00070 checkStamps = false;
00071 if (callBackObj)
00072 {
00073 QByteArray data;
00074 QDataStream dataStream( data, IO_WriteOnly );
00075 dataStream << QString("kbuildsycoca") << args;
00076 QCString _launcher = KApplication::launcher();
00077
00078 kapp->dcopClient()->callAsync(_launcher, _launcher, "kdeinit_exec_wait(QString,QStringList)", data, callBackObj, callBackSlot);
00079 }
00080 else
00081 {
00082 KApplication::kdeinitExecWait( "kbuildsycoca", args );
00083 }
00084 }
00085
00086 static void runKonfUpdate()
00087 {
00088 KApplication::kdeinitExecWait( "kconf_update", QStringList(), 0, 0, "0" );
00089 }
00090
00091 static void runDontChangeHostname(const QCString &oldName, const QCString &newName)
00092 {
00093 QStringList args;
00094 args.append(QFile::decodeName(oldName));
00095 args.append(QFile::decodeName(newName));
00096 KApplication::kdeinitExecWait( "kdontchangethehostname", args );
00097 }
00098
00099 Kded::Kded(bool checkUpdates, bool new_startup)
00100 : DCOPObject("kbuildsycoca"), DCOPObjectProxy(),
00101 b_checkUpdates(checkUpdates),
00102 m_needDelayedCheck(false),
00103 m_newStartup( new_startup )
00104 {
00105 _self = this;
00106 QCString cPath;
00107 QCString ksycoca_env = getenv("KDESYCOCA");
00108 if (ksycoca_env.isEmpty())
00109 cPath = QFile::encodeName(KGlobal::dirs()->saveLocation("tmp")+"ksycoca");
00110 else
00111 cPath = ksycoca_env;
00112 m_pTimer = new QTimer(this);
00113 connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recreate()));
00114
00115 QTimer::singleShot(100, this, SLOT(installCrashHandler()));
00116
00117 m_pDirWatch = 0;
00118
00119 m_windowIdList.setAutoDelete(true);
00120
00121 m_recreateCount = 0;
00122 m_recreateBusy = false;
00123 }
00124
00125 Kded::~Kded()
00126 {
00127 _self = 0;
00128 m_pTimer->stop();
00129 delete m_pTimer;
00130 delete m_pDirWatch;
00131
00132
00133 QAsciiDictIterator<KDEDModule> it(m_modules);
00134 while (!it.isEmpty())
00135 delete it.toFirst();
00136 }
00137
00138 bool Kded::process(const QCString &obj, const QCString &fun,
00139 const QByteArray &data,
00140 QCString &replyType, QByteArray &replyData)
00141 {
00142 if (obj == "ksycoca") return false;
00143
00144 if (m_dontLoad[obj])
00145 return false;
00146
00147 KDEDModule *module = loadModule(obj, true);
00148 if (!module)
00149 return false;
00150
00151 module->setCallingDcopClient(kapp->dcopClient());
00152 return module->process(fun, data, replyType, replyData);
00153 }
00154
00155 void Kded::initModules()
00156 {
00157 m_dontLoad.clear();
00158 KConfig *config = kapp->config();
00159 bool kde_running = !( getenv( "KDE_FULL_SESSION" ) == NULL || getenv( "KDE_FULL_SESSION" )[ 0 ] == '\0' );
00160
00161 if( getenv( "KDE_SESSION_UID" ) != NULL && uid_t( atoi( getenv( "KDE_SESSION_UID" ))) != getuid())
00162 kde_running = false;
00163
00164 KService::List kdedModules = KServiceType::offers("KDEDModule");
00165 QString version = getenv( "KDE_SESSION_VERSION" );
00166 QStringList blacklist;
00167 if ( version >= "4" )
00168 {
00169 kdDebug(7020) << "KDE4 is running." << endl;
00170 blacklist << "mediamanager" << "medianotifier" << "kmilod" << "kwrited";
00171 }
00172 for(KService::List::ConstIterator it = kdedModules.begin(); it != kdedModules.end(); ++it)
00173 {
00174 KService::Ptr service = *it;
00175 bool autoload = service->property("X-KDE-Kded-autoload", QVariant::Bool).toBool();
00176 config->setGroup(QString("Module-%1").arg(service->desktopEntryName()));
00177 autoload = config->readBoolEntry("autoload", autoload);
00178 for (QStringList::Iterator module = blacklist.begin(); module != blacklist.end(); ++module)
00179 {
00180 if (service->desktopEntryName() == *module)
00181 {
00182 autoload = false;
00183 break;
00184 }
00185 }
00186 if( m_newStartup )
00187 {
00188
00189 QVariant phasev = service->property("X-KDE-Kded-phase", QVariant::Int );
00190 int phase = phasev.isValid() ? phasev.toInt() : 2;
00191 bool prevent_autoload = false;
00192 switch( phase )
00193 {
00194 case 0:
00195 break;
00196 case 1:
00197 if( !kde_running )
00198 prevent_autoload = true;
00199 break;
00200 case 2:
00201 default:
00202 prevent_autoload = true;
00203 break;
00204 }
00205 if (autoload && !prevent_autoload)
00206 loadModule(service, false);
00207 }
00208 else
00209 {
00210 if (autoload && kde_running)
00211 loadModule(service, false);
00212 }
00213 bool dontLoad = false;
00214 QVariant p = service->property("X-KDE-Kded-load-on-demand", QVariant::Bool);
00215 if (p.isValid() && (p.toBool() == false))
00216 dontLoad = true;
00217 if (dontLoad)
00218 noDemandLoad(service->desktopEntryName());
00219
00220 if (dontLoad && !autoload)
00221 unloadModule(service->desktopEntryName().latin1());
00222 }
00223 }
00224
00225 void Kded::loadSecondPhase()
00226 {
00227 kdDebug(7020) << "Loading second phase autoload" << endl;
00228 KConfig *config = kapp->config();
00229 KService::List kdedModules = KServiceType::offers("KDEDModule");
00230 for(KService::List::ConstIterator it = kdedModules.begin(); it != kdedModules.end(); ++it)
00231 {
00232 KService::Ptr service = *it;
00233 bool autoload = service->property("X-KDE-Kded-autoload", QVariant::Bool).toBool();
00234 config->setGroup(QString("Module-%1").arg(service->desktopEntryName()));
00235 autoload = config->readBoolEntry("autoload", autoload);
00236 QVariant phasev = service->property("X-KDE-Kded-phase", QVariant::Int );
00237 int phase = phasev.isValid() ? phasev.toInt() : 2;
00238 if( phase == 2 && autoload )
00239 loadModule(service, false);
00240 }
00241 }
00242
00243 void Kded::noDemandLoad(const QString &obj)
00244 {
00245 m_dontLoad.insert(obj.latin1(), this);
00246 }
00247
00248 KDEDModule *Kded::loadModule(const QCString &obj, bool onDemand)
00249 {
00250 KDEDModule *module = m_modules.find(obj);
00251 if (module)
00252 return module;
00253 KService::Ptr s = KService::serviceByDesktopPath("kded/"+obj+".desktop");
00254 return loadModule(s, onDemand);
00255 }
00256
00257 KDEDModule *Kded::loadModule(const KService *s, bool onDemand)
00258 {
00259 KDEDModule *module = 0;
00260 if (s && !s->library().isEmpty())
00261 {
00262 QCString obj = s->desktopEntryName().latin1();
00263 KDEDModule *oldModule = m_modules.find(obj);
00264 if (oldModule)
00265 return oldModule;
00266
00267 if (onDemand)
00268 {
00269 QVariant p = s->property("X-KDE-Kded-load-on-demand", QVariant::Bool);
00270 if (p.isValid() && (p.toBool() == false))
00271 {
00272 noDemandLoad(s->desktopEntryName());
00273 return 0;
00274 }
00275 }
00276
00277
00278 KLibLoader *loader = KLibLoader::self();
00279
00280 QVariant v = s->property("X-KDE-FactoryName", QVariant::String);
00281 QString factory = v.isValid() ? v.toString() : QString::null;
00282 if (factory.isEmpty())
00283 {
00284
00285 v = s->property("X-KDE-Factory", QVariant::String);
00286 factory = v.isValid() ? v.toString() : QString::null;
00287 }
00288 if (factory.isEmpty())
00289 factory = s->library();
00290
00291 factory = "create_" + factory;
00292 QString libname = "kded_"+s->library();
00293
00294 KLibrary *lib = loader->library(QFile::encodeName(libname));
00295 if (!lib)
00296 {
00297 kdWarning() << k_funcinfo << "Could not load library. [ "
00298 << loader->lastErrorMessage() << " ]" << endl;
00299 libname.prepend("lib");
00300 lib = loader->library(QFile::encodeName(libname));
00301 }
00302 if (lib)
00303 {
00304
00305 void *create = lib->symbol(QFile::encodeName(factory));
00306
00307 if (create)
00308 {
00309
00310 KDEDModule* (*func)(const QCString &);
00311 func = (KDEDModule* (*)(const QCString &)) create;
00312 module = func(obj);
00313 if (module)
00314 {
00315 m_modules.insert(obj, module);
00316 m_libs.insert(obj, lib);
00317 connect(module, SIGNAL(moduleDeleted(KDEDModule *)), SLOT(slotKDEDModuleRemoved(KDEDModule *)));
00318 kdDebug(7020) << "Successfully loaded module '" << obj << "'\n";
00319 return module;
00320 }
00321 }
00322 loader->unloadLibrary(QFile::encodeName(libname));
00323 }
00324 else
00325 {
00326 kdWarning() << k_funcinfo << "Could not load library. [ "
00327 << loader->lastErrorMessage() << " ]" << endl;
00328 }
00329 kdDebug(7020) << "Could not load module '" << obj << "'\n";
00330 }
00331 return 0;
00332 }
00333
00334 bool Kded::unloadModule(const QCString &obj)
00335 {
00336 KDEDModule *module = m_modules.take(obj);
00337 if (!module)
00338 return false;
00339 kdDebug(7020) << "Unloading module '" << obj << "'\n";
00340 delete module;
00341 return true;
00342 }
00343
00344
00345 QCStringList Kded::loadedModules()
00346 {
00347 QCStringList modules;
00348 QAsciiDictIterator<KDEDModule> it( m_modules );
00349 for ( ; it.current(); ++it)
00350 modules.append( it.currentKey() );
00351
00352 return modules;
00353 }
00354
00355 QCStringList Kded::functions()
00356 {
00357 QCStringList res = DCOPObject::functions();
00358 res += "ASYNC recreate()";
00359 return res;
00360 }
00361
00362 void Kded::slotKDEDModuleRemoved(KDEDModule *module)
00363 {
00364 m_modules.remove(module->objId());
00365 KLibrary *lib = m_libs.take(module->objId());
00366 if (lib)
00367 lib->unload();
00368 }
00369
00370 void Kded::slotApplicationRemoved(const QCString &appId)
00371 {
00372 for(QAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
00373 {
00374 it.current()->removeAll(appId);
00375 }
00376
00377 QValueList<long> *windowIds = m_windowIdList.find(appId);
00378 if (windowIds)
00379 {
00380 for( QValueList<long>::ConstIterator it = windowIds->begin();
00381 it != windowIds->end(); ++it)
00382 {
00383 long windowId = *it;
00384 m_globalWindowIdList.remove(windowId);
00385 for(QAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
00386 {
00387 emit it.current()->windowUnregistered(windowId);
00388 }
00389 }
00390 m_windowIdList.remove(appId);
00391 }
00392 }
00393
00394 void Kded::updateDirWatch()
00395 {
00396 if (!b_checkUpdates) return;
00397
00398 delete m_pDirWatch;
00399 m_pDirWatch = new KDirWatch;
00400
00401 QObject::connect( m_pDirWatch, SIGNAL(dirty(const QString&)),
00402 this, SLOT(update(const QString&)));
00403 QObject::connect( m_pDirWatch, SIGNAL(created(const QString&)),
00404 this, SLOT(update(const QString&)));
00405 QObject::connect( m_pDirWatch, SIGNAL(deleted(const QString&)),
00406 this, SLOT(dirDeleted(const QString&)));
00407
00408
00409 for( QStringList::ConstIterator it = m_allResourceDirs.begin();
00410 it != m_allResourceDirs.end();
00411 ++it )
00412 {
00413 readDirectory( *it );
00414 }
00415 }
00416
00417 void Kded::updateResourceList()
00418 {
00419 delete KSycoca::self();
00420
00421 if (!b_checkUpdates) return;
00422
00423 if (delayedCheck) return;
00424
00425 QStringList dirs = KSycoca::self()->allResourceDirs();
00426
00427 for( QStringList::ConstIterator it = dirs.begin();
00428 it != dirs.end();
00429 ++it )
00430 {
00431 if (m_allResourceDirs.find(*it) == m_allResourceDirs.end())
00432 {
00433 m_allResourceDirs.append(*it);
00434 readDirectory(*it);
00435 }
00436 }
00437 }
00438
00439 void Kded::crashHandler(int)
00440 {
00441 DCOPClient::emergencyClose();
00442 if (_self)
00443 system("kded");
00444 qWarning("Last DCOP call before KDED crash was from application '%s'\n"
00445 "to object '%s', function '%s'.",
00446 DCOPClient::postMortemSender(),
00447 DCOPClient::postMortemObject(),
00448 DCOPClient::postMortemFunction());
00449 }
00450
00451 void Kded::installCrashHandler()
00452 {
00453 KCrash::setEmergencySaveFunction(crashHandler);
00454 }
00455
00456 void Kded::recreate()
00457 {
00458 recreate(false);
00459 }
00460
00461 void Kded::runDelayedCheck()
00462 {
00463 if( m_needDelayedCheck )
00464 recreate(false);
00465 m_needDelayedCheck = false;
00466 }
00467
00468 void Kded::recreate(bool initial)
00469 {
00470 m_recreateBusy = true;
00471
00472
00473
00474 if (!initial)
00475 {
00476 updateDirWatch();
00477 runBuildSycoca(this, SLOT(recreateDone()));
00478 }
00479 else
00480 {
00481 if(!delayedCheck)
00482 updateDirWatch();
00483 runBuildSycoca();
00484 recreateDone();
00485 if(delayedCheck)
00486 {
00487
00488 QTimer::singleShot( 60000, this, SLOT( runDelayedCheck()));
00489 m_needDelayedCheck = true;
00490 delayedCheck = false;
00491 }
00492 else
00493 m_needDelayedCheck = false;
00494 }
00495 }
00496
00497 void Kded::recreateDone()
00498 {
00499 updateResourceList();
00500
00501 for(; m_recreateCount; m_recreateCount--)
00502 {
00503 QCString replyType = "void";
00504 QByteArray replyData;
00505 DCOPClientTransaction *transaction = m_recreateRequests.first();
00506 if (transaction)
00507 kapp->dcopClient()->endTransaction(transaction, replyType, replyData);
00508 m_recreateRequests.remove(m_recreateRequests.begin());
00509 }
00510 m_recreateBusy = false;
00511
00512
00513 if (!m_recreateRequests.isEmpty())
00514 {
00515 m_pTimer->start(2000, true );
00516 m_recreateCount = m_recreateRequests.count();
00517 }
00518 }
00519
00520 void Kded::dirDeleted(const QString& path)
00521 {
00522 update(path);
00523 }
00524
00525 void Kded::update(const QString& )
00526 {
00527 if (!m_recreateBusy)
00528 {
00529 m_pTimer->start( 2000, true );
00530 }
00531 else
00532 {
00533 m_recreateRequests.append(0);
00534 }
00535 }
00536
00537 bool Kded::process(const QCString &fun, const QByteArray &data,
00538 QCString &replyType, QByteArray &replyData)
00539 {
00540 if (fun == "recreate()") {
00541 if (!m_recreateBusy)
00542 {
00543 if (m_recreateRequests.isEmpty())
00544 {
00545 m_pTimer->start(0, true );
00546 m_recreateCount = 0;
00547 }
00548 m_recreateCount++;
00549 }
00550 m_recreateRequests.append(kapp->dcopClient()->beginTransaction());
00551 replyType = "void";
00552 return true;
00553 } else {
00554 return DCOPObject::process(fun, data, replyType, replyData);
00555 }
00556 }
00557
00558
00559 void Kded::readDirectory( const QString& _path )
00560 {
00561 QString path( _path );
00562 if ( path.right(1) != "/" )
00563 path += "/";
00564
00565 if ( m_pDirWatch->contains( path ) )
00566 return;
00567
00568 QDir d( _path, QString::null, QDir::Unsorted, QDir::Readable | QDir::Executable | QDir::Dirs | QDir::Hidden );
00569
00570
00571
00572
00573
00574
00575
00576 m_pDirWatch->addDir(path);
00577
00578 if ( !d.exists() )
00579 {
00580 kdDebug(7020) << QString("Does not exist! (%1)").arg(_path) << endl;
00581 return;
00582 }
00583
00584
00585
00586
00587
00588
00589 QString file;
00590 unsigned int i;
00591 unsigned int count = d.count();
00592 for( i = 0; i < count; i++ )
00593 {
00594 if (d[i] == "." || d[i] == ".." || d[i] == "magic")
00595 continue;
00596
00597 file = path;
00598 file += d[i];
00599
00600 readDirectory( file );
00601 }
00602 }
00603
00604 bool Kded::isWindowRegistered(long windowId)
00605 {
00606 return m_globalWindowIdList.find(windowId) != 0;
00607
00608 }
00609
00610
00611 void Kded::registerWindowId(long windowId)
00612 {
00613 m_globalWindowIdList.replace(windowId, &windowId);
00614 QCString sender = callingDcopClient()->senderId();
00615 if( sender.isEmpty())
00616 sender = callingDcopClient()->appId();
00617 QValueList<long> *windowIds = m_windowIdList.find(sender);
00618 if (!windowIds)
00619 {
00620 windowIds = new QValueList<long>;
00621 m_windowIdList.insert(sender, windowIds);
00622 }
00623 windowIds->append(windowId);
00624
00625
00626 for(QAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
00627 {
00628 emit it.current()->windowRegistered(windowId);
00629 }
00630 }
00631
00632
00633 void Kded::unregisterWindowId(long windowId)
00634 {
00635 m_globalWindowIdList.remove(windowId);
00636 QCString sender = callingDcopClient()->senderId();
00637 if( sender.isEmpty())
00638 sender = callingDcopClient()->appId();
00639 QValueList<long> *windowIds = m_windowIdList.find(sender);
00640 if (windowIds)
00641 {
00642 windowIds->remove(windowId);
00643 if (windowIds->isEmpty())
00644 m_windowIdList.remove(sender);
00645 }
00646
00647 for(QAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
00648 {
00649 emit it.current()->windowUnregistered(windowId);
00650 }
00651 }
00652
00653
00654 static void sighandler(int )
00655 {
00656 if (kapp)
00657 kapp->quit();
00658 }
00659
00660 KUpdateD::KUpdateD()
00661 {
00662 m_pDirWatch = new KDirWatch;
00663 m_pTimer = new QTimer;
00664 connect(m_pTimer, SIGNAL(timeout()), this, SLOT(runKonfUpdate()));
00665 QObject::connect( m_pDirWatch, SIGNAL(dirty(const QString&)),
00666 this, SLOT(slotNewUpdateFile()));
00667
00668 QStringList dirs = KGlobal::dirs()->findDirs("data", "kconf_update");
00669 for( QStringList::ConstIterator it = dirs.begin();
00670 it != dirs.end();
00671 ++it )
00672 {
00673 QString path = *it;
00674 if (path[path.length()-1] != '/')
00675 path += "/";
00676
00677 if (!m_pDirWatch->contains(path))
00678 m_pDirWatch->addDir(path);
00679 }
00680 }
00681
00682 KUpdateD::~KUpdateD()
00683 {
00684 delete m_pDirWatch;
00685 delete m_pTimer;
00686 }
00687
00688 void KUpdateD::runKonfUpdate()
00689 {
00690 ::runKonfUpdate();
00691 }
00692
00693 void KUpdateD::slotNewUpdateFile()
00694 {
00695 m_pTimer->start( 500, true );
00696 }
00697
00698 KHostnameD::KHostnameD(int pollInterval)
00699 {
00700 m_Timer.start(pollInterval, false );
00701 connect(&m_Timer, SIGNAL(timeout()), this, SLOT(checkHostname()));
00702 checkHostname();
00703 }
00704
00705 KHostnameD::~KHostnameD()
00706 {
00707
00708 }
00709
00710 void KHostnameD::checkHostname()
00711 {
00712 char buf[1024+1];
00713 if (gethostname(buf, 1024) != 0)
00714 return;
00715 buf[sizeof(buf)-1] = '\0';
00716
00717 if (m_hostname.isEmpty())
00718 {
00719 m_hostname = buf;
00720 return;
00721 }
00722
00723 if (m_hostname == buf)
00724 return;
00725
00726 QCString newHostname = buf;
00727
00728 runDontChangeHostname(m_hostname, newHostname);
00729 m_hostname = newHostname;
00730 }
00731
00732
00733 static KCmdLineOptions options[] =
00734 {
00735 { "check", I18N_NOOP("Check Sycoca database only once"), 0 },
00736 { "new-startup", "Internal", 0 },
00737 KCmdLineLastOption
00738 };
00739
00740 class KDEDQtDCOPObject : public DCOPObject
00741 {
00742 public:
00743 KDEDQtDCOPObject() : DCOPObject("qt/kded") { }
00744
00745 virtual bool process(const QCString &fun, const QByteArray &data,
00746 QCString& replyType, QByteArray &replyData)
00747 {
00748 if ( kapp && (fun == "quit()") )
00749 {
00750 kapp->quit();
00751 replyType = "void";
00752 return true;
00753 }
00754 return DCOPObject::process(fun, data, replyType, replyData);
00755 }
00756
00757 QCStringList functions()
00758 {
00759 QCStringList res = DCOPObject::functions();
00760 res += "void quit()";
00761 return res;
00762 }
00763 };
00764
00765 class KDEDApplication : public KUniqueApplication
00766 {
00767 public:
00768 KDEDApplication() : KUniqueApplication( )
00769 {
00770 startup = true;
00771 dcopClient()->connectDCOPSignal( "DCOPServer", "", "terminateKDE()",
00772 objId(), "quit()", false );
00773 }
00774
00775 int newInstance()
00776 {
00777 if (startup) {
00778 startup = false;
00779 if( Kded::self()->newStartup())
00780 Kded::self()->initModules();
00781 else
00782 QTimer::singleShot(500, Kded::self(), SLOT(initModules()));
00783 } else
00784 runBuildSycoca();
00785
00786 return 0;
00787 }
00788
00789 QCStringList functions()
00790 {
00791 QCStringList res = KUniqueApplication::functions();
00792 res += "bool loadModule(QCString)";
00793 res += "bool unloadModule(QCString)";
00794 res += "void registerWindowId(long int)";
00795 res += "void unregisterWindowId(long int)";
00796 res += "QCStringList loadedModules()";
00797 res += "void reconfigure()";
00798 res += "void loadSecondPhase()";
00799 res += "void quit()";
00800 return res;
00801 }
00802
00803 bool process(const QCString &fun, const QByteArray &data,
00804 QCString &replyType, QByteArray &replyData)
00805 {
00806 if (fun == "loadModule(QCString)") {
00807 QCString module;
00808 QDataStream arg( data, IO_ReadOnly );
00809 arg >> module;
00810 bool result = (Kded::self()->loadModule(module, false) != 0);
00811 replyType = "bool";
00812 QDataStream _replyStream( replyData, IO_WriteOnly );
00813 _replyStream << result;
00814 return true;
00815 }
00816 else if (fun == "unloadModule(QCString)") {
00817 QCString module;
00818 QDataStream arg( data, IO_ReadOnly );
00819 arg >> module;
00820 bool result = Kded::self()->unloadModule(module);
00821 replyType = "bool";
00822 QDataStream _replyStream( replyData, IO_WriteOnly );
00823 _replyStream << result;
00824 return true;
00825 }
00826 else if (fun == "registerWindowId(long int)") {
00827 long windowId;
00828 QDataStream arg( data, IO_ReadOnly );
00829 arg >> windowId;
00830 Kded::self()->setCallingDcopClient(callingDcopClient());
00831 Kded::self()->registerWindowId(windowId);
00832 replyType = "void";
00833 return true;
00834 }
00835 else if (fun == "unregisterWindowId(long int)") {
00836 long windowId;
00837 QDataStream arg( data, IO_ReadOnly );
00838 arg >> windowId;
00839 Kded::self()->setCallingDcopClient(callingDcopClient());
00840 Kded::self()->unregisterWindowId(windowId);
00841 replyType = "void";
00842 return true;
00843 }
00844 else if (fun == "loadedModules()") {
00845 replyType = "QCStringList";
00846 QDataStream _replyStream(replyData, IO_WriteOnly);
00847 _replyStream << Kded::self()->loadedModules();
00848 return true;
00849 }
00850 else if (fun == "reconfigure()") {
00851 config()->reparseConfiguration();
00852 Kded::self()->initModules();
00853 replyType = "void";
00854 return true;
00855 }
00856 else if (fun == "loadSecondPhase()") {
00857 Kded::self()->loadSecondPhase();
00858 replyType = "void";
00859 return true;
00860 }
00861 else if (fun == "quit()") {
00862 quit();
00863 replyType = "void";
00864 return true;
00865 }
00866 return KUniqueApplication::process(fun, data, replyType, replyData);
00867 }
00868
00869 bool startup;
00870 KDEDQtDCOPObject kdedQtDcopObject;
00871 };
00872
00873 extern "C" KDE_EXPORT int kdemain(int argc, char *argv[])
00874 {
00875 KAboutData aboutData( "kded", I18N_NOOP("KDE Daemon"),
00876 "$Id: kded.cpp 711061 2007-09-11 09:42:51Z tpatzig $",
00877 I18N_NOOP("KDE Daemon - triggers Sycoca database updates when needed"));
00878
00879 KApplication::installSigpipeHandler();
00880
00881 KCmdLineArgs::init(argc, argv, &aboutData);
00882
00883 KUniqueApplication::addCmdLineOptions();
00884
00885 KCmdLineArgs::addCmdLineOptions( options );
00886
00887
00888 KLocale::setMainCatalogue("kdelibs");
00889
00890
00891 putenv(strdup("SESSION_MANAGER="));
00892
00893
00894 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00895
00896
00897 {
00898 DCOPClient testDCOP;
00899 QCString dcopName = testDCOP.registerAs("kded", false);
00900 if (dcopName.isEmpty())
00901 {
00902 kdFatal() << "DCOP communication problem!" << endl;
00903 return 1;
00904 }
00905 }
00906
00907 KInstance *instance = new KInstance(&aboutData);
00908 KConfig *config = instance->config();
00909
00910 if (args->isSet("check"))
00911 {
00912 config->setGroup("General");
00913 checkStamps = config->readBoolEntry("CheckFileStamps", true);
00914 runBuildSycoca();
00915 runKonfUpdate();
00916 exit(0);
00917 }
00918
00919 if (!KUniqueApplication::start())
00920 {
00921 fprintf(stderr, "KDE Daemon (kded) already running.\n");
00922 exit(0);
00923 }
00924
00925 KUniqueApplication::dcopClient()->setQtBridgeEnabled(false);
00926
00927 config->setGroup("General");
00928 int HostnamePollInterval = config->readNumEntry("HostnamePollInterval", 5000);
00929 bool bCheckSycoca = config->readBoolEntry("CheckSycoca", true);
00930 bool bCheckUpdates = config->readBoolEntry("CheckUpdates", true);
00931 bool bCheckHostname = config->readBoolEntry("CheckHostname", true);
00932 checkStamps = config->readBoolEntry("CheckFileStamps", true);
00933 delayedCheck = config->readBoolEntry("DelayedCheck", false);
00934
00935 Kded *kded = new Kded(bCheckSycoca, args->isSet("new-startup"));
00936
00937 signal(SIGTERM, sighandler);
00938 signal(SIGHUP, sighandler);
00939 KDEDApplication k;
00940
00941 kded->recreate(true);
00942
00943 if (bCheckUpdates)
00944 (void) new KUpdateD;
00945
00946 runKonfUpdate();
00947
00948 if (bCheckHostname)
00949 (void) new KHostnameD(HostnamePollInterval);
00950
00951 DCOPClient *client = kapp->dcopClient();
00952 QObject::connect(client, SIGNAL(applicationRemoved(const QCString&)),
00953 kded, SLOT(slotApplicationRemoved(const QCString&)));
00954 client->setNotifications(true);
00955 client->setDaemonMode( true );
00956
00957
00958
00959
00960
00961
00962
00963 QByteArray data;
00964 client->send( "*", "ksycoca", "notifyDatabaseChanged()", data );
00965 client->send( "ksplash", "", "upAndRunning(QString)", QString("kded"));
00966 #ifdef Q_WS_X11
00967 XEvent e;
00968 e.xclient.type = ClientMessage;
00969 e.xclient.message_type = XInternAtom( qt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
00970 e.xclient.display = qt_xdisplay();
00971 e.xclient.window = qt_xrootwin();
00972 e.xclient.format = 8;
00973 strcpy( e.xclient.data.b, "kded" );
00974 XSendEvent( qt_xdisplay(), qt_xrootwin(), False, SubstructureNotifyMask, &e );
00975 #endif
00976 int result = k.exec();
00977
00978 delete kded;
00979 delete instance;
00980
00981 return result;
00982 }
00983
00984 #include "kded.moc"