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