• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kded
 

kded

  • kded
kded.cpp
1/* This file is part of the KDE libraries
2 * Copyright (C) 1999 David Faure <faure@kde.org>
3 * Copyright (C) 2000 Waldo Bastian <bastian@kde.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License version 2 as published by the Free Software Foundation;
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 **/
19
20#include <tqdir.h>
21
22#include "kded.h"
23#include "kdedmodule.h"
24
25#include <kresourcelist.h>
26#include <tdecrash.h>
27
28#include <unistd.h>
29#include <stdlib.h>
30#include <signal.h>
31#include <time.h>
32
33#include <tqfile.h>
34#include <tqtimer.h>
35
36#include <dcopclient.h>
37
38#include <tdeuniqueapplication.h>
39#include <tdecmdlineargs.h>
40#include <tdeaboutdata.h>
41#include <tdelocale.h>
42#include <tdeglobal.h>
43#include <tdeprocess.h>
44#include <kdebug.h>
45#include <kdirwatch.h>
46#include <tdestandarddirs.h>
47#include <kdatastream.h>
48#include <tdeio/global.h>
49#include <kservicetype.h>
50
51#ifdef TQ_WS_X11
52#include <X11/Xlib.h>
53#include <fixx11h.h>
54#endif
55
56Kded *Kded::_self = 0;
57
58static bool checkStamps = true;
59static bool delayedCheck = false;
60
61static void runBuildSycoca(TQObject *callBackObj=0, const char *callBackSlot=0)
62{
63 TQStringList args;
64 args.append("--incremental");
65 if(checkStamps)
66 args.append("--checkstamps");
67 if(delayedCheck)
68 args.append("--nocheckfiles");
69 else
70 checkStamps = false; // useful only during kded startup
71 if (callBackObj)
72 {
73 TQByteArray data;
74 TQDataStream dataStream( data, IO_WriteOnly );
75 dataStream << TQString("tdebuildsycoca") << args;
76 TQCString _launcher = TDEApplication::launcher();
77
78 tdeApp->dcopClient()->callAsync(_launcher, _launcher, "tdeinit_exec_wait(TQString,TQStringList)", data, callBackObj, callBackSlot);
79 }
80 else
81 {
82 TDEApplication::tdeinitExecWait( "tdebuildsycoca", args );
83 }
84}
85
86static void runKonfUpdate()
87{
88 TDEApplication::tdeinitExecWait( "tdeconf_update", TQStringList(), 0, 0, "0" /*no startup notification*/ );
89}
90
91static void runDontChangeHostname(const TQCString &oldName, const TQCString &newName)
92{
93 TQStringList args;
94 args.append(TQFile::decodeName(oldName));
95 args.append(TQFile::decodeName(newName));
96 TDEApplication::tdeinitExecWait( "kdontchangethehostname", args );
97}
98
99Kded::Kded(bool checkUpdates, bool new_startup)
100 : DCOPObject("tdebuildsycoca"), DCOPObjectProxy(),
101 b_checkUpdates(checkUpdates),
102 m_needDelayedCheck(false),
103 m_newStartup( new_startup )
104{
105 _self = this;
106 TQCString cPath;
107 TQCString tdesycoca_env = getenv("TDESYCOCA");
108 if (tdesycoca_env.isEmpty())
109 cPath = TQFile::encodeName(TDEGlobal::dirs()->saveLocation("tmp")+"tdesycoca");
110 else
111 cPath = tdesycoca_env;
112 m_pTimer = new TQTimer(this);
113 connect(m_pTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(recreate()));
114
115 TQTimer::singleShot(100, this, TQ_SLOT(installCrashHandler()));
116
117 m_pDirWatch = 0;
118
119 m_windowIdList.setAutoDelete(true);
120
121 m_recreateCount = 0;
122 m_recreateBusy = false;
123}
124
125Kded::~Kded()
126{
127 _self = 0;
128 m_pTimer->stop();
129 delete m_pTimer;
130 delete m_pDirWatch;
131 // We have to delete the modules while we're still able to process incoming
132 // DCOP messages, since modules might make DCOP calls in their destructors.
133 TQAsciiDictIterator<KDEDModule> it(m_modules);
134 while (!it.isEmpty())
135 delete it.toFirst();
136}
137
138bool Kded::process(const TQCString &obj, const TQCString &fun,
139 const TQByteArray &data,
140 TQCString &replyType, TQByteArray &replyData)
141{
142 if (obj == "tdesycoca") return false; // Ignore this one.
143
144 if (m_dontLoad[obj])
145 return false;
146
147 KDEDModule *module = loadModule(obj, true);
148 if (!module)
149 return false;
150
151 module->setCallingDcopClient(tdeApp->dcopClient());
152 return module->process(fun, data, replyType, replyData);
153}
154
155void Kded::initModules()
156{
157 m_dontLoad.clear();
158 TDEConfig *config = tdeApp->config();
159 bool tde_running = !( getenv( "TDE_FULL_SESSION" ) == NULL || getenv( "TDE_FULL_SESSION" )[ 0 ] == '\0' );
160 // not the same user like the one running the session (most likely we're run via sudo or something)
161 if( getenv( "TDE_SESSION_UID" ) != NULL && uid_t( atoi( getenv( "TDE_SESSION_UID" ))) != getuid())
162 tde_running = false;
163 // Preload kded modules.
164 KService::List kdedModules = KServiceType::offers("KDEDModule");
165 TQString version = getenv( "KDE_SESSION_VERSION" );
166 TQStringList blacklist;
167 if ( !(version == NULL) && version >= "4" )
168 {
169 kdDebug(7020) << "KDE4 is running:" << endl;
170 kdDebug(7020) << " KDE_SESSION_VERSION: " << version << endl;
171 kdDebug(7020) << " Blacklisting mediamanager, medianotifier, kmilod, kwrited." << endl;
172 blacklist << "mediamanager" << "medianotifier" << "kmilod" << "kwrited";
173 }
174 for(KService::List::ConstIterator it = kdedModules.begin(); it != kdedModules.end(); ++it)
175 {
176 KService::Ptr service = *it;
177 bool autoload = service->property("X-TDE-Kded-autoload", TQVariant::Bool).toBool();
178 config->setGroup(TQString("Module-%1").arg(service->desktopEntryName()));
179 autoload = config->readBoolEntry("autoload", autoload);
180 for (TQStringList::Iterator module = blacklist.begin(); module != blacklist.end(); ++module)
181 {
182 if (service->desktopEntryName() == *module)
183 {
184 autoload = false;
185 break;
186 }
187 }
188 if( m_newStartup )
189 {
190 // see ksmserver's README for description of the phases
191 TQVariant phasev = service->property("X-TDE-Kded-phase", TQVariant::Int );
192 int phase = phasev.isValid() ? phasev.toInt() : 2;
193 bool prevent_autoload = false;
194 switch( phase )
195 {
196 case 0: // always autoload
197 break;
198 case 1: // autoload only in TDE
199 if( !tde_running )
200 prevent_autoload = true;
201 break;
202 case 2: // autoload delayed, only in TDE
203 default:
204 prevent_autoload = true;
205 break;
206 }
207 if (autoload && !prevent_autoload)
208 loadModule(service, false);
209 }
210 else
211 {
212 if (autoload && tde_running)
213 loadModule(service, false);
214 }
215 bool dontLoad = false;
216 TQVariant p = service->property("X-TDE-Kded-load-on-demand", TQVariant::Bool);
217 if (p.isValid() && (p.toBool() == false))
218 dontLoad = true;
219 if (dontLoad)
220 noDemandLoad(service->desktopEntryName());
221
222 if (dontLoad && !autoload)
223 unloadModule(service->desktopEntryName().latin1());
224 }
225}
226
227void Kded::loadSecondPhase()
228{
229 kdDebug(7020) << "Loading second phase autoload" << endl;
230 TDEConfig *config = tdeApp->config();
231 KService::List kdedModules = KServiceType::offers("KDEDModule");
232 for(KService::List::ConstIterator it = kdedModules.begin(); it != kdedModules.end(); ++it)
233 {
234 KService::Ptr service = *it;
235 bool autoload = service->property("X-TDE-Kded-autoload", TQVariant::Bool).toBool();
236 config->setGroup(TQString("Module-%1").arg(service->desktopEntryName()));
237 autoload = config->readBoolEntry("autoload", autoload);
238 TQVariant phasev = service->property("X-TDE-Kded-phase", TQVariant::Int );
239 int phase = phasev.isValid() ? phasev.toInt() : 2;
240 if( phase == 2 && autoload )
241 loadModule(service, false);
242 }
243}
244
245void Kded::noDemandLoad(const TQString &obj)
246{
247 m_dontLoad.insert(obj.latin1(), this);
248}
249
250KDEDModule *Kded::loadModule(const TQCString &obj, bool onDemand)
251{
252 KDEDModule *module = m_modules.find(obj);
253 if (module)
254 return module;
255 KService::Ptr s = KService::serviceByDesktopPath("kded/"+obj+".desktop");
256 return loadModule(s, onDemand);
257}
258
259KDEDModule *Kded::loadModule(const KService *s, bool onDemand)
260{
261 KDEDModule *module = 0;
262 if (s && !s->library().isEmpty())
263 {
264 TQCString obj = s->desktopEntryName().latin1();
265 KDEDModule *oldModule = m_modules.find(obj);
266 if (oldModule)
267 return oldModule;
268
269 if (onDemand)
270 {
271 TQVariant p = s->property("X-TDE-Kded-load-on-demand", TQVariant::Bool);
272 if (p.isValid() && (p.toBool() == false))
273 {
274 noDemandLoad(s->desktopEntryName());
275 return 0;
276 }
277 }
278 // get the library loader instance
279
280 KLibLoader *loader = KLibLoader::self();
281
282 TQVariant v = s->property("X-TDE-FactoryName", TQVariant::String);
283 TQString factory = v.isValid() ? v.toString() : TQString::null;
284 if (factory.isEmpty())
285 {
286 // Stay bugward compatible
287 v = s->property("X-TDE-Factory", TQVariant::String);
288 factory = v.isValid() ? v.toString() : TQString::null;
289 }
290 if (factory.isEmpty())
291 factory = s->library();
292
293 factory = "create_" + factory;
294 TQString libname = "kded_"+s->library();
295
296 KLibrary *lib = loader->library(TQFile::encodeName(libname));
297 if (!lib)
298 {
299 kdWarning() << k_funcinfo << "Could not load library. [ "
300 << loader->lastErrorMessage() << " ]" << endl;
301 libname.prepend("lib");
302 lib = loader->library(TQFile::encodeName(libname));
303 }
304 if (lib)
305 {
306 // get the create_ function
307 void *create = lib->symbol(TQFile::encodeName(factory));
308
309 if (create)
310 {
311 // create the module
312 KDEDModule* (*func)(const TQCString &);
313 func = (KDEDModule* (*)(const TQCString &)) create;
314 module = func(obj);
315 if (module)
316 {
317 m_modules.insert(obj, module);
318 m_libs.insert(obj, lib);
319 connect(module, TQ_SIGNAL(moduleDeleted(KDEDModule *)), TQ_SLOT(slotKDEDModuleRemoved(KDEDModule *)));
320 kdDebug(7020) << "Successfully loaded module '" << obj << "'\n";
321 return module;
322 }
323 }
324 loader->unloadLibrary(TQFile::encodeName(libname));
325 }
326 else
327 {
328 kdWarning() << k_funcinfo << "Could not load library. [ "
329 << loader->lastErrorMessage() << " ]" << endl;
330 }
331 kdDebug(7020) << "Could not load module '" << obj << "'\n";
332 }
333 return 0;
334}
335
336bool Kded::unloadModule(const TQCString &obj)
337{
338 KDEDModule *module = m_modules.take(obj);
339 if (!module)
340 return false;
341 kdDebug(7020) << "Unloading module '" << obj << "'\n";
342 delete module;
343 return true;
344}
345
346// DCOP
347QCStringList Kded::loadedModules()
348{
349 QCStringList modules;
350 TQAsciiDictIterator<KDEDModule> it( m_modules );
351 for ( ; it.current(); ++it)
352 modules.append( it.currentKey() );
353
354 return modules;
355}
356
357QCStringList Kded::functions()
358{
359 QCStringList res = DCOPObject::functions();
360 res += "ASYNC recreate()";
361 return res;
362}
363
364void Kded::slotKDEDModuleRemoved(KDEDModule *module)
365{
366 m_modules.remove(module->objId());
367 KLibrary *lib = m_libs.take(module->objId());
368 if (lib)
369 lib->unload();
370}
371
372void Kded::slotApplicationRemoved(const TQCString &appId)
373{
374 for(TQAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
375 {
376 it.current()->removeAll(appId);
377 }
378
379 TQValueList<long> *windowIds = m_windowIdList.find(appId);
380 if (windowIds)
381 {
382 for( TQValueList<long>::ConstIterator it = windowIds->begin();
383 it != windowIds->end(); ++it)
384 {
385 long windowId = *it;
386 m_globalWindowIdList.remove(windowId);
387 for(TQAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
388 {
389 emit it.current()->windowUnregistered(windowId);
390 }
391 }
392 m_windowIdList.remove(appId);
393 }
394}
395
396void Kded::updateDirWatch()
397{
398 if (!b_checkUpdates) return;
399
400 delete m_pDirWatch;
401 m_pDirWatch = new KDirWatch;
402
403 TQObject::connect( m_pDirWatch, TQ_SIGNAL(dirty(const TQString&)),
404 this, TQ_SLOT(update(const TQString&)));
405 TQObject::connect( m_pDirWatch, TQ_SIGNAL(created(const TQString&)),
406 this, TQ_SLOT(update(const TQString&)));
407 TQObject::connect( m_pDirWatch, TQ_SIGNAL(deleted(const TQString&)),
408 this, TQ_SLOT(dirDeleted(const TQString&)));
409
410 // For each resource
411 for( TQStringList::ConstIterator it = m_allResourceDirs.begin();
412 it != m_allResourceDirs.end();
413 ++it )
414 {
415 readDirectory( *it );
416 }
417}
418
419void Kded::updateResourceList()
420{
421 delete KSycoca::self();
422
423 if (!b_checkUpdates) return;
424
425 if (delayedCheck) return;
426
427 TQStringList dirs = KSycoca::self()->allResourceDirs();
428 // For each resource
429 for( TQStringList::ConstIterator it = dirs.begin();
430 it != dirs.end();
431 ++it )
432 {
433 if (m_allResourceDirs.find(*it) == m_allResourceDirs.end())
434 {
435 m_allResourceDirs.append(*it);
436 readDirectory(*it);
437 }
438 }
439}
440
441void Kded::crashHandler(int)
442{
443 DCOPClient::emergencyClose();
444 if (_self) { // Don't restart if we were closing down
445 tqWarning("Last DCOP call before KDED crash was from application '%s'\n"
446 "to object '%s', function '%s'.",
447 DCOPClient::postMortemSender(),
448 DCOPClient::postMortemObject(),
449 DCOPClient::postMortemFunction());
450 tqWarning("Restarting KDED...\n");
451 if (system("kded") < 0) {
452 tqWarning("Unable to restart KDED!\n");
453 }
454 }
455}
456
457void Kded::installCrashHandler()
458{
459 TDECrash::setEmergencySaveFunction(crashHandler);
460}
461
462void Kded::recreate()
463{
464 recreate(false);
465}
466
467void Kded::runDelayedCheck()
468{
469 if( m_needDelayedCheck )
470 recreate(false);
471 m_needDelayedCheck = false;
472}
473
474void Kded::recreate(bool initial)
475{
476 m_recreateBusy = true;
477 // Using TDELauncher here is difficult since we might not have a
478 // database
479
480 if (!initial)
481 {
482 updateDirWatch(); // Update tree first, to be sure to miss nothing.
483 runBuildSycoca(this, TQ_SLOT(recreateDone()));
484 }
485 else
486 {
487 if(!delayedCheck)
488 updateDirWatch(); // this would search all the directories
489 runBuildSycoca();
490 recreateDone();
491 if(delayedCheck)
492 {
493 // do a proper tdesycoca check after a delay
494 TQTimer::singleShot( 60000, this, TQ_SLOT( runDelayedCheck()));
495 m_needDelayedCheck = true;
496 delayedCheck = false;
497 }
498 else
499 m_needDelayedCheck = false;
500 }
501}
502
503void Kded::recreateDone()
504{
505 updateResourceList();
506
507 for(; m_recreateCount; m_recreateCount--)
508 {
509 TQCString replyType = "void";
510 TQByteArray replyData;
511 DCOPClientTransaction *transaction = m_recreateRequests.first();
512 if (transaction)
513 tdeApp->dcopClient()->endTransaction(transaction, replyType, replyData);
514 m_recreateRequests.remove(m_recreateRequests.begin());
515 }
516 m_recreateBusy = false;
517
518 // Did a new request come in while building?
519 if (!m_recreateRequests.isEmpty())
520 {
521 m_pTimer->start(2000, true /* single shot */ );
522 m_recreateCount = m_recreateRequests.count();
523 }
524}
525
526void Kded::dirDeleted(const TQString& path)
527{
528 update(path);
529}
530
531void Kded::update(const TQString& )
532{
533 if (!m_recreateBusy)
534 {
535 m_pTimer->start( 2000, true /* single shot */ );
536 }
537 else
538 {
539 m_recreateRequests.append(0);
540 }
541}
542
543bool Kded::process(const TQCString &fun, const TQByteArray &data,
544 TQCString &replyType, TQByteArray &replyData)
545{
546 if (fun == "recreate()") {
547 if (!m_recreateBusy)
548 {
549 if (m_recreateRequests.isEmpty())
550 {
551 m_pTimer->start(0, true /* single shot */ );
552 m_recreateCount = 0;
553 }
554 m_recreateCount++;
555 }
556 m_recreateRequests.append(tdeApp->dcopClient()->beginTransaction());
557 replyType = "void";
558 return true;
559 } else {
560 return DCOPObject::process(fun, data, replyType, replyData);
561 }
562}
563
564
565void Kded::readDirectory( const TQString& _path )
566{
567 TQString path( _path );
568 if ( path.right(1) != "/" )
569 path += "/";
570
571 if ( m_pDirWatch->contains( path ) ) // Already seen this one?
572 return;
573
574 TQDir d( _path, TQString::null, TQDir::Unsorted, TQDir::Readable | TQDir::Executable | TQDir::Dirs | TQDir::Hidden );
575 // set TQDir ...
576
577
578 //************************************************************************
579 // Setting dirs
580 //************************************************************************
581
582 m_pDirWatch->addDir(path); // add watch on this dir
583
584 if ( !d.exists() ) // exists&isdir?
585 {
586 kdDebug(7020) << TQString(TQString("Does not exist! (%1)").arg(_path)) << endl;
587 return; // return false
588 }
589
590 // Note: If some directory is gone, dirwatch will delete it from the list.
591
592 //************************************************************************
593 // Reading
594 //************************************************************************
595 TQString file;
596 unsigned int i; // counter and string length.
597 unsigned int count = d.count();
598 for( i = 0; i < count; i++ ) // check all entries
599 {
600 if (d[i] == "." || d[i] == ".." || d[i] == "magic")
601 continue; // discard those ".", "..", "magic"...
602
603 file = path; // set full path
604 file += d[i]; // and add the file name.
605
606 readDirectory( file ); // yes, dive into it.
607 }
608}
609
610bool Kded::isWindowRegistered(long windowId)
611{
612 return m_globalWindowIdList.find(windowId) != 0;
613
614}
615
616// DCOP
617void Kded::registerWindowId(long windowId)
618{
619 m_globalWindowIdList.replace(windowId, &windowId);
620 TQCString sender = callingDcopClient()->senderId();
621 if( sender.isEmpty()) // local call
622 sender = callingDcopClient()->appId();
623 TQValueList<long> *windowIds = m_windowIdList.find(sender);
624 if (!windowIds)
625 {
626 windowIds = new TQValueList<long>;
627 m_windowIdList.insert(sender, windowIds);
628 }
629 windowIds->append(windowId);
630
631
632 for(TQAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
633 {
634 emit it.current()->windowRegistered(windowId);
635 }
636}
637
638// DCOP
639void Kded::unregisterWindowId(long windowId)
640{
641 m_globalWindowIdList.remove(windowId);
642 TQCString sender = callingDcopClient()->senderId();
643 if( sender.isEmpty()) // local call
644 sender = callingDcopClient()->appId();
645 TQValueList<long> *windowIds = m_windowIdList.find(sender);
646 if (windowIds)
647 {
648 windowIds->remove(windowId);
649 if (windowIds->isEmpty())
650 m_windowIdList.remove(sender);
651 }
652
653 for(TQAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
654 {
655 emit it.current()->windowUnregistered(windowId);
656 }
657}
658
659
660static void sighandler(int /*sig*/)
661{
662 if (tdeApp)
663 tdeApp->quit();
664}
665
666KUpdateD::KUpdateD()
667{
668 m_pDirWatch = new KDirWatch;
669 m_pTimer = new TQTimer;
670 connect(m_pTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(runKonfUpdate()));
671 TQObject::connect( m_pDirWatch, TQ_SIGNAL(dirty(const TQString&)),
672 this, TQ_SLOT(slotNewUpdateFile()));
673
674 TQStringList dirs = TDEGlobal::dirs()->findDirs("data", "tdeconf_update");
675 for( TQStringList::ConstIterator it = dirs.begin();
676 it != dirs.end();
677 ++it )
678 {
679 TQString path = *it;
680 if (path[path.length()-1] != '/')
681 path += "/";
682
683 if (!m_pDirWatch->contains(path))
684 m_pDirWatch->addDir(path);
685 }
686}
687
688KUpdateD::~KUpdateD()
689{
690 delete m_pDirWatch;
691 delete m_pTimer;
692}
693
694void KUpdateD::runKonfUpdate()
695{
696 ::runKonfUpdate();
697}
698
699void KUpdateD::slotNewUpdateFile()
700{
701 m_pTimer->start( 500, true /* single shot */ );
702}
703
704KHostnameD::KHostnameD(int pollInterval)
705{
706 m_Timer.start(pollInterval, false /* repetitive */ );
707 connect(&m_Timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(checkHostname()));
708 checkHostname();
709}
710
711KHostnameD::~KHostnameD()
712{
713 // Empty
714}
715
716void KHostnameD::checkHostname()
717{
718 char buf[1024+1];
719 if (gethostname(buf, 1024) != 0)
720 return;
721 buf[sizeof(buf)-1] = '\0';
722
723 if (m_hostname.isEmpty())
724 {
725 m_hostname = buf;
726 return;
727 }
728
729 if (m_hostname == buf)
730 return;
731
732 TQCString newHostname = buf;
733
734 runDontChangeHostname(m_hostname, newHostname);
735 m_hostname = newHostname;
736}
737
738
739static TDECmdLineOptions options[] =
740{
741 { "check", I18N_NOOP("Check Sycoca database only once"), 0 },
742 { "new-startup", "Internal", 0 },
743 TDECmdLineLastOption
744};
745
746class KDEDQtDCOPObject : public DCOPObject
747{
748public:
749 KDEDQtDCOPObject() : DCOPObject("qt/kded") { }
750
751 virtual bool process(const TQCString &fun, const TQByteArray &data,
752 TQCString& replyType, TQByteArray &replyData)
753 {
754 if ( tdeApp && (fun == "quit()") )
755 {
756 tdeApp->quit();
757 replyType = "void";
758 return true;
759 }
760 return DCOPObject::process(fun, data, replyType, replyData);
761 }
762
763 QCStringList functions()
764 {
765 QCStringList res = DCOPObject::functions();
766 res += "void quit()";
767 return res;
768 }
769};
770
771class KDEDApplication : public TDEUniqueApplication
772{
773public:
774 KDEDApplication() : TDEUniqueApplication( )
775 {
776 startup = true;
777 dcopClient()->connectDCOPSignal( "DCOPServer", "", "terminateTDE()",
778 objId(), "quit()", false );
779 }
780
781 int newInstance()
782 {
783 if (startup) {
784 startup = false;
785 if( Kded::self()->newStartup())
786 Kded::self()->initModules();
787 else
788 TQTimer::singleShot(500, Kded::self(), TQ_SLOT(initModules()));
789 } else
790 runBuildSycoca();
791
792 return 0;
793 }
794
795 QCStringList functions()
796 {
797 QCStringList res = TDEUniqueApplication::functions();
798 res += "bool loadModule(TQCString)";
799 res += "bool unloadModule(TQCString)";
800 res += "void registerWindowId(long int)";
801 res += "void unregisterWindowId(long int)";
802 res += "QCStringList loadedModules()";
803 res += "void reconfigure()";
804 res += "void loadSecondPhase()";
805 res += "void quit()";
806 return res;
807 }
808
809 bool process(const TQCString &fun, const TQByteArray &data,
810 TQCString &replyType, TQByteArray &replyData)
811 {
812 if (fun == "loadModule(TQCString)") {
813 TQCString module;
814 TQDataStream arg( data, IO_ReadOnly );
815 arg >> module;
816 bool result = (Kded::self()->loadModule(module, false) != 0);
817 replyType = "bool";
818 TQDataStream _replyStream( replyData, IO_WriteOnly );
819 _replyStream << result;
820 return true;
821 }
822 else if (fun == "unloadModule(TQCString)") {
823 TQCString module;
824 TQDataStream arg( data, IO_ReadOnly );
825 arg >> module;
826 bool result = Kded::self()->unloadModule(module);
827 replyType = "bool";
828 TQDataStream _replyStream( replyData, IO_WriteOnly );
829 _replyStream << result;
830 return true;
831 }
832 else if (fun == "registerWindowId(long int)") {
833 long windowId;
834 TQDataStream arg( data, IO_ReadOnly );
835 arg >> windowId;
836 Kded::self()->setCallingDcopClient(callingDcopClient());
837 Kded::self()->registerWindowId(windowId);
838 replyType = "void";
839 return true;
840 }
841 else if (fun == "unregisterWindowId(long int)") {
842 long windowId;
843 TQDataStream arg( data, IO_ReadOnly );
844 arg >> windowId;
845 Kded::self()->setCallingDcopClient(callingDcopClient());
846 Kded::self()->unregisterWindowId(windowId);
847 replyType = "void";
848 return true;
849 }
850 else if (fun == "loadedModules()") {
851 replyType = "QCStringList";
852 TQDataStream _replyStream(replyData, IO_WriteOnly);
853 _replyStream << Kded::self()->loadedModules();
854 return true;
855 }
856 else if (fun == "reconfigure()") {
857 config()->reparseConfiguration();
858 Kded::self()->initModules();
859 replyType = "void";
860 return true;
861 }
862 else if (fun == "loadSecondPhase()") {
863 Kded::self()->loadSecondPhase();
864 replyType = "void";
865 return true;
866 }
867 else if (fun == "quit()") {
868 quit();
869 replyType = "void";
870 return true;
871 }
872 return TDEUniqueApplication::process(fun, data, replyType, replyData);
873 }
874
875 bool startup;
876 KDEDQtDCOPObject kdedQtDcopObject;
877};
878
879extern "C" TDE_EXPORT int kdemain(int argc, char *argv[])
880{
881 TDEAboutData aboutData( "kded", I18N_NOOP("TDE Daemon"),
882 "$Id$",
883 I18N_NOOP("TDE Daemon - triggers Sycoca database updates when needed"));
884
885 TDEApplication::installSigpipeHandler();
886
887 TDECmdLineArgs::init(argc, argv, &aboutData);
888
889 TDEUniqueApplication::addCmdLineOptions();
890
891 TDECmdLineArgs::addCmdLineOptions( options );
892
893 // this program is in tdelibs so it uses tdelibs as catalog
894 TDELocale::setMainCatalogue("tdelibs");
895
896 // WABA: Make sure not to enable session management.
897 putenv(strdup("SESSION_MANAGER="));
898
899 // Parse command line before checking DCOP
900 TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
901
902 // Check DCOP communication.
903 {
904 DCOPClient testDCOP;
905 TQCString dcopName = testDCOP.registerAs("kded", false);
906 if (dcopName.isEmpty())
907 {
908 kdFatal() << "DCOP communication problem!" << endl;
909 return 1;
910 }
911 }
912
913 TDEInstance *instance = new TDEInstance(&aboutData);
914 TDEConfig *config = instance->config(); // Enable translations.
915
916 if (args->isSet("check"))
917 {
918 config->setGroup("General");
919 checkStamps = config->readBoolEntry("CheckFileStamps", true);
920 runBuildSycoca();
921 runKonfUpdate();
922 exit(0);
923 }
924
925 if (!TDEUniqueApplication::start())
926 {
927 fprintf(stderr, "[kded] Daemon (kded) is already running.\n");
928 exit(0);
929 }
930
931 TDEUniqueApplication::dcopClient()->setQtBridgeEnabled(false);
932
933 config->setGroup("General");
934 int HostnamePollInterval = config->readNumEntry("HostnamePollInterval", 5000);
935 bool bCheckSycoca = config->readBoolEntry("CheckSycoca", true);
936 bool bCheckUpdates = config->readBoolEntry("CheckUpdates", true);
937 bool bCheckHostname = config->readBoolEntry("CheckHostname", true);
938 checkStamps = config->readBoolEntry("CheckFileStamps", true);
939 delayedCheck = config->readBoolEntry("DelayedCheck", false);
940
941 Kded *kded = new Kded(bCheckSycoca, args->isSet("new-startup")); // Build data base
942
943 signal(SIGTERM, sighandler);
944 signal(SIGHUP, sighandler);
945 KDEDApplication k;
946
947 kded->recreate(true); // initial
948
949 if (bCheckUpdates)
950 (void) new KUpdateD; // Watch for updates
951
952 runKonfUpdate(); // Run it once.
953
954 if (bCheckHostname)
955 (void) new KHostnameD(HostnamePollInterval); // Watch for hostname changes
956
957 DCOPClient *client = tdeApp->dcopClient();
958 TQObject::connect(client, TQ_SIGNAL(applicationRemoved(const TQCString&)),
959 kded, TQ_SLOT(slotApplicationRemoved(const TQCString&)));
960 client->setNotifications(true);
961 client->setDaemonMode( true );
962
963 // During startup kdesktop waits for KDED to finish.
964 // Send a notifyDatabaseChanged signal even if the database hasn't
965 // changed.
966 // If the database changed, tdebuildsycoca's signal didn't go anywhere
967 // anyway, because it was too early, so let's send this signal
968 // unconditionnally (David)
969 TQByteArray data;
970 client->send( "*", "tdesycoca", "notifyDatabaseChanged()", data );
971 client->send( "ksplash", "", "upAndRunning(TQString)", TQString("kded"));
972#ifdef TQ_WS_X11
973 XEvent e;
974 e.xclient.type = ClientMessage;
975 e.xclient.message_type = XInternAtom( tqt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
976 e.xclient.display = tqt_xdisplay();
977 e.xclient.window = tqt_xrootwin();
978 e.xclient.format = 8;
979 strcpy( e.xclient.data.b, "kded" );
980 XSendEvent( tqt_xdisplay(), tqt_xrootwin(), False, SubstructureNotifyMask, &e );
981#endif
982 int result = k.exec(); // keep running
983
984 delete kded;
985 delete instance; // Deletes config as well
986
987 return result;
988}
989
990#include "kded.moc"
KDEDModule
The base class for KDED modules.
Definition: kdedmodule.h:56
KDEDModule::find
TDEShared * find(const TQCString &app, const TQCString &key)
Lookup object indexed with app and key.
Definition: kdedmodule.cpp:83

kded

Skip menu "kded"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kded

Skip menu "kded"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kded by doxygen 1.9.4
This website is maintained by Timothy Pearson.