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