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