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