00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <fcntl.h>
00026 #include <sys/types.h>
00027 #include <sys/stat.h>
00028
00029 #include <config.h>
00030 #ifndef WITHOUT_ARTS
00031
00032 #include <connect.h>
00033 #include <dispatcher.h>
00034 #include <flowsystem.h>
00035 #include <qiomanager.h>
00036 #include <soundserver.h>
00037 #endif
00038
00039
00040 #include <tqfile.h>
00041 #include <tqfileinfo.h>
00042 #include <tqstringlist.h>
00043 #include <tqtextstream.h>
00044
00045
00046 #include <dcopclient.h>
00047 #include <tdeaboutdata.h>
00048 #ifndef WITHOUT_ARTS
00049 #include <kartsdispatcher.h>
00050 #include <kartsserver.h>
00051 #endif
00052 #include <tdecmdlineargs.h>
00053 #include <tdeconfig.h>
00054 #include <kdebug.h>
00055 #include <tdeglobal.h>
00056 #include <tdelocale.h>
00057 #include <tdemessagebox.h>
00058 #include <kpassivepopup.h>
00059 #include <kiconloader.h>
00060 #include <kmacroexpander.h>
00061 #ifndef WITHOUT_ARTS
00062 #include <kplayobjectfactory.h>
00063 #include <kaudiomanagerplay.h>
00064 #endif
00065 #include <kprocess.h>
00066 #include <kstandarddirs.h>
00067 #include <kuniqueapplication.h>
00068 #include <twin.h>
00069
00070 #include "knotify.h"
00071 #include "knotify.moc"
00072
00073 class KNotifyPrivate
00074 {
00075 public:
00076 TDEConfig* globalEvents;
00077 TDEConfig* globalConfig;
00078 TQMap<TQString, TDEConfig*> events;
00079 TQMap<TQString, TDEConfig*> configs;
00080 TQString externalPlayer;
00081 TDEProcess *externalPlayerProc;
00082
00083 #ifndef WITHOUT_ARTS
00084 TQPtrList<KDE::PlayObject> playObjects;
00085 TQMap<KDE::PlayObject*,int> playObjectEventMap;
00086 KAudioManagerPlay *audioManager;
00087 #endif
00088 int externalPlayerEventId;
00089
00090 bool useExternal;
00091 bool useArts;
00092 int volume;
00093 TQTimer *playTimer;
00094 bool inStartup;
00095 TQString startupEvents;
00096 };
00097
00098
00099
00100 #ifndef WITHOUT_ARTS
00101 KArtsServer *soundServer = 0;
00102 #endif
00103
00104 extern "C"{
00105 KDE_EXPORT int kdemain(int argc, char **argv) {
00106 TDEAboutData aboutdata("knotify", I18N_NOOP("KNotify"),
00107 "3.0", I18N_NOOP("TDE Notification Server"),
00108 TDEAboutData::License_GPL, "(C) 1997-2003, KDE Developers");
00109 aboutdata.addAuthor("Carsten Pfeiffer",I18N_NOOP("Current Maintainer"),"pfeiffer@kde.org");
00110 aboutdata.addAuthor("Christian Esken",0,"esken@kde.org");
00111 aboutdata.addAuthor("Stefan Westerfeld",I18N_NOOP("Sound support"),"stefan@space.twc.de");
00112 aboutdata.addAuthor("Charles Samuels",I18N_NOOP("Previous Maintainer"),"charles@kde.org");
00113
00114 TDECmdLineArgs::init( argc, argv, &aboutdata );
00115 KUniqueApplication::addCmdLineOptions();
00116
00117
00118 if ( !KUniqueApplication::start() ) {
00119 kdDebug() << "Running knotify found" << endl;
00120 return 0;
00121 }
00122
00123 KUniqueApplication app;
00124 app.disableSessionManagement();
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 #ifndef WITHOUT_ARTS
00136 TDEConfigGroup config( TDEGlobal::config(), "StartProgress" );
00137 TDEConfig artsKCMConfig( "kcmartsrc" );
00138 artsKCMConfig.setGroup( "Arts" );
00139 bool useArts = artsKCMConfig.readBoolEntry( "StartServer", true );
00140 if (useArts) {
00141 useArts = config.readBoolEntry( "Use Arts", useArts );
00142 }
00143 bool ok = config.readBoolEntry( "Arts Init", true );
00144
00145 if ( useArts && !ok ) {
00146 if ( KMessageBox::questionYesNo(
00147 0L,
00148 i18n("During the previous startup, KNotify crashed while creating "
00149 "Arts::Dispatcher. Do you want to try again or disable "
00150 "aRts sound output?\n\n"
00151 "If you choose to disable aRts output now, you can re-enable "
00152 "it later or select an alternate sound player "
00153 "in the System Notifications control panel."),
00154 i18n("KNotify Problem"),
00155 i18n("&Try Again"),
00156 i18n("D&isable aRts Output"),
00157 "KNotifyStartProgress",
00158 0
00159 )
00160 == KMessageBox::No ) {
00161 useArts = false;
00162 }
00163 }
00164
00165
00166 config.writeEntry( "Arts Init", false );
00167 config.writeEntry( "Use Arts", useArts );
00168 config.sync();
00169
00170 KArtsDispatcher *dispatcher = 0;
00171 if ( useArts ) {
00172 dispatcher = new KArtsDispatcher;
00173 soundServer = new KArtsServer;
00174 }
00175
00176
00177 config.writeEntry("Arts Init", useArts );
00178 config.sync();
00179
00180 ok = config.readBoolEntry( "KNotify Init", true );
00181 if ( useArts && !ok ) {
00182 if ( KMessageBox::questionYesNo(
00183 0L,
00184 i18n("During the previous startup, KNotify crashed while instantiating "
00185 "KNotify. Do you want to try again or disable "
00186 "aRts sound output?\n\n"
00187 "If you choose to disable aRts output now, you can re-enable "
00188 "it later or select an alternate sound player "
00189 "in the System Notifications control panel."),
00190 i18n("KNotify Problem"),
00191 i18n("&Try Again"),
00192 i18n("D&isable aRts Output"),
00193 "KNotifyStartProgress",
00194 0
00195 )
00196 == KMessageBox::No ) {
00197 useArts = false;
00198 delete soundServer;
00199 soundServer = 0L;
00200 delete dispatcher;
00201 dispatcher = 0L;
00202 }
00203 }
00204
00205
00206 config.writeEntry( "KNotify Init", false );
00207 config.writeEntry( "Use Arts", useArts );
00208 config.sync();
00209
00210
00211 KNotify *notify = new KNotify( useArts );
00212
00213 config.writeEntry( "KNotify Init", true );
00214 config.sync();
00215
00216 #else
00217
00218
00219 KNotify *notify = new KNotify( false );
00220
00221 #endif
00222
00223 app.dcopClient()->setDefaultObject( "Notify" );
00224 app.dcopClient()->setDaemonMode( true );
00225
00226
00227 int ret = app.exec();
00228 delete notify;
00229 #ifndef WITHOUT_ARTS
00230 delete soundServer;
00231 delete dispatcher;
00232 #endif
00233 return ret;
00234 }
00235 }
00236
00237 KNotify::KNotify( bool useArts )
00238 : TQObject(), DCOPObject("Notify")
00239 {
00240 d = new KNotifyPrivate;
00241 d->globalEvents = new TDEConfig("knotify/eventsrc", true, false, "data");
00242 d->globalConfig = new TDEConfig("knotify.eventsrc", true, false);
00243 d->externalPlayerProc = 0;
00244 d->useArts = useArts;
00245 d->inStartup = true;
00246 #ifndef WITHOUT_ARTS
00247 d->playObjects.setAutoDelete(true);
00248 d->audioManager = 0;
00249 if( useArts ) {
00250 connect( soundServer, TQT_SIGNAL( restartedServer() ), this, TQT_SLOT( restartedArtsd() ) );
00251 restartedArtsd();
00252 }
00253 #endif
00254 d->volume = 100;
00255 d->playTimer = 0;
00256
00257 loadConfig();
00258 }
00259
00260 KNotify::~KNotify()
00261 {
00262 reconfigure();
00263
00264 #ifndef WITHOUT_ARTS
00265 d->playObjects.clear();
00266
00267 delete d->globalEvents;
00268 delete d->globalConfig;
00269 delete d->externalPlayerProc;
00270 delete d->audioManager;
00271 #endif
00272 delete d;
00273 }
00274
00275
00276 void KNotify::loadConfig() {
00277
00278 TDEConfig *kc = TDEGlobal::config();
00279 kc->setGroup("Misc");
00280 d->useExternal = kc->readBoolEntry( "Use external player", false );
00281 d->externalPlayer = kc->readPathEntry("External player");
00282
00283
00284 if ( d->externalPlayer.isEmpty() ) {
00285 TQStringList players;
00286 players << "wavplay" << "aplay" << "auplay";
00287 TQStringList::Iterator it = players.begin();
00288 while ( d->externalPlayer.isEmpty() && it != players.end() ) {
00289 d->externalPlayer = TDEStandardDirs::findExe( *it );
00290 ++it;
00291 }
00292 }
00293
00294
00295 d->volume = kc->readNumEntry( "Volume", 100 );
00296 }
00297
00298
00299 void KNotify::reconfigure()
00300 {
00301 kapp->config()->reparseConfiguration();
00302 loadConfig();
00303
00304
00305 d->globalConfig->reparseConfiguration();
00306 for ( TQMapIterator<TQString,TDEConfig*> it = d->configs.begin(); it != d->configs.end(); ++it ) {
00307 delete it.data();
00308 }
00309 d->configs.clear();
00310 }
00311
00312
00313 void KNotify::notify(const TQString &event, const TQString &fromApp,
00314 const TQString &text, TQString sound, TQString file,
00315 int present, int level)
00316 {
00317 notify( event, fromApp, text, sound, file, present, level, 0, 1 );
00318 }
00319
00320 void KNotify::notify(const TQString &event, const TQString &fromApp,
00321 const TQString &text, TQString sound, TQString file,
00322 int present, int level, int winId)
00323 {
00324 notify( event, fromApp, text, sound, file, present, level, winId, 1 );
00325 }
00326
00327 void KNotify::notify(const TQString &event, const TQString &fromApp,
00328 const TQString &text, TQString sound, TQString file,
00329 int present, int level, int winId, int eventId )
00330 {
00331
00332
00333 if( d->inStartup ) {
00334 d->startupEvents += "(" + event + ":" + fromApp + ")";
00335 }
00336
00337 TQString commandline;
00338 TDEConfig *eventsFile = NULL;
00339 TDEConfig *configFile = NULL;
00340
00341
00342 if ( !event.isEmpty() ) {
00343
00344
00345 if ( d->events.contains( fromApp ) ) {
00346 eventsFile = d->events[fromApp];
00347 }
00348 else {
00349 eventsFile=new TDEConfig(locate("data", fromApp+"/eventsrc"),true,false);
00350 d->events.insert( fromApp, eventsFile );
00351 }
00352 if ( d->configs.contains( fromApp) ) {
00353 configFile = d->configs[fromApp];
00354 }
00355 else {
00356 configFile=new TDEConfig(fromApp+".eventsrc",true,false);
00357 d->configs.insert( fromApp, configFile );
00358 }
00359
00360 if ( !eventsFile->hasGroup( event ) && isGlobal(event) ) {
00361 eventsFile = d->globalEvents;
00362 configFile = d->globalConfig;
00363 }
00364
00365 eventsFile->setGroup( event );
00366 configFile->setGroup( event );
00367
00368
00369 if ( present==-1 ) {
00370 present = configFile->readNumEntry( "presentation", -1 );
00371 }
00372 if ( present==-1 ) {
00373 present = eventsFile->readNumEntry( "default_presentation", 0 );
00374 }
00375
00376
00377 if( present & KNotifyClient::Sound ) {
00378 TQString theSound = configFile->readPathEntry( "soundfile" );
00379 if ( theSound.isEmpty() ) {
00380 theSound = eventsFile->readPathEntry( "default_sound" );
00381 }
00382 if ( !theSound.isEmpty() ) {
00383 sound = theSound;
00384 }
00385 }
00386
00387
00388 if( present & KNotifyClient::Logfile ) {
00389 TQString theFile = configFile->readPathEntry( "logfile" );
00390 if ( theFile.isEmpty() ) {
00391 theFile = eventsFile->readPathEntry( "default_logfile" );
00392 }
00393 if ( !theFile.isEmpty() ) {
00394 file = theFile;
00395 }
00396 }
00397
00398
00399 if( present & KNotifyClient::Messagebox ) {
00400 level = eventsFile->readNumEntry( "level", 0 );
00401 }
00402
00403
00404 if (present & KNotifyClient::Execute ) {
00405 commandline = configFile->readPathEntry( "commandline" );
00406 if ( commandline.isEmpty() ) {
00407 commandline = eventsFile->readPathEntry( "default_commandline" );
00408 }
00409 }
00410 }
00411
00412
00413 if ( present & KNotifyClient::Sound ) {
00414 notifyBySound( sound, fromApp, eventId );
00415 }
00416
00417 if ( present & KNotifyClient::Execute ) {
00418 notifyByExecute( commandline, event, fromApp, text, winId, eventId );
00419 }
00420
00421 if ( present & KNotifyClient::Logfile ) {
00422 notifyByLogfile( text, file );
00423 }
00424
00425 if ( present & KNotifyClient::Stderr ) {
00426 notifyByStderr( text );
00427 }
00428
00429 if ( present & KNotifyClient::Taskbar ) {
00430 notifyByTaskbar( checkWinId( fromApp, winId ));
00431 }
00432
00433 if ( present & KNotifyClient::PassivePopup ) {
00434 notifyByPassivePopup( text, fromApp, eventsFile, checkWinId( fromApp, winId ));
00435 }
00436 else if ( present & KNotifyClient::Messagebox ) {
00437 notifyByMessagebox( text, level, checkWinId( fromApp, winId ));
00438 }
00439
00440 TQByteArray qbd;
00441 TQDataStream ds(qbd, IO_WriteOnly);
00442 ds << event << fromApp << text << sound << file << present << level << winId << eventId;
00443 emitDCOPSignal("notifySignal(TQString,TQString,TQString,TQString,TQString,int,int,int,int)", qbd);
00444 }
00445
00446
00447 bool KNotify::notifyBySound( const TQString &sound, const TQString &appname, int eventId )
00448 {
00449 if (sound.isEmpty()) {
00450 soundFinished( eventId, NoSoundFile );
00451 return false;
00452 }
00453
00454 bool external = d->useExternal && !d->externalPlayer.isEmpty();
00455
00456 TQString soundFile(sound);
00457 if ( TQFileInfo(sound).isRelative() ) {
00458 TQString search = TQString("%1/sounds/%2").arg(appname).arg(sound);
00459 soundFile = TDEGlobal::instance()->dirs()->findResource("data", search);
00460 if ( soundFile.isEmpty() ) {
00461 soundFile = locate( "sound", sound );
00462 }
00463 }
00464 if ( soundFile.isEmpty() || isPlaying( soundFile ) ) {
00465 soundFinished( eventId, soundFile.isEmpty() ? NoSoundFile : FileAlreadyPlaying );
00466 return false;
00467 }
00468
00469
00470
00471
00472 if (!external) {
00473
00474
00475 if (!d->useArts)
00476 {
00477 soundFinished( eventId, NoSoundSupport );
00478 return false;
00479 }
00480
00481 #ifndef WITHOUT_ARTS
00482
00483 while( d->playObjects.count()>5 ) {
00484 abortFirstPlayObject();
00485 }
00486
00487 KDE::PlayObjectFactory factory(soundServer->server());
00488 if( d->audioManager ) {
00489 factory.setAudioManagerPlay( d->audioManager );
00490 }
00491 KURL soundURL;
00492 soundURL.setPath(soundFile);
00493 KDE::PlayObject *playObject = factory.createPlayObject(soundURL, false);
00494
00495 if (playObject->isNull()) {
00496 soundFinished( eventId, NoSoundSupport );
00497 delete playObject;
00498 return false;
00499 }
00500
00501 if ( d->volume != 100 ) {
00502
00503
00504 Arts::StereoVolumeControl volumeControl = Arts::DynamicCast(soundServer->server().createObject("Arts::StereoVolumeControl"));
00505 Arts::PlayObject player = playObject->object();
00506 Arts::Synth_AMAN_PLAY ap = d->audioManager->amanPlay();
00507 if( ! volumeControl.isNull() && ! player.isNull() && ! ap.isNull() ) {
00508 volumeControl.scaleFactor( d->volume/100.0 );
00509
00510 ap.stop();
00511 Arts::disconnect( player, "left", ap, "left" );
00512 Arts::disconnect( player, "right", ap, "right" );
00513
00514 ap.start();
00515 volumeControl.start();
00516
00517 Arts::connect(player,"left",volumeControl,"inleft");
00518 Arts::connect(player,"right",volumeControl,"inright");
00519
00520 Arts::connect(volumeControl,"outleft",ap,"left");
00521 Arts::connect(volumeControl,"outright",ap,"right");
00522
00523 player._addChild( volumeControl, "volume" );
00524 }
00525 }
00526
00527 playObject->play();
00528 d->playObjects.append( playObject );
00529 d->playObjectEventMap.insert( playObject, eventId );
00530
00531 if ( !d->playTimer ) {
00532 d->playTimer = new TQTimer( this );
00533 connect( d->playTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( playTimeout() ) );
00534 }
00535 if ( !d->playTimer->isActive() ) {
00536 d->playTimer->start( 1000 );
00537 }
00538 #endif
00539 return true;
00540 }
00541 else if(!d->externalPlayer.isEmpty()) {
00542
00543 TDEProcess *proc = d->externalPlayerProc;
00544 if (!proc) {
00545 proc = d->externalPlayerProc = new TDEProcess;
00546 connect( proc, TQT_SIGNAL( processExited( TDEProcess * )), TQT_SLOT( slotPlayerProcessExited( TDEProcess * )));
00547 }
00548 if (proc->isRunning()) {
00549 soundFinished( eventId, PlayerBusy );
00550 return false;
00551 }
00552 proc->clearArguments();
00553 (*proc) << d->externalPlayer << TQFile::encodeName( soundFile ).data();
00554 d->externalPlayerEventId = eventId;
00555 proc->start(TDEProcess::NotifyOnExit);
00556 return true;
00557 }
00558
00559 soundFinished( eventId, Unknown );
00560 return false;
00561 }
00562
00563 bool KNotify::notifyByMessagebox(const TQString &text, int level, WId winId)
00564 {
00565
00566 if ( text.isEmpty() ) {
00567 return false;
00568 }
00569
00570
00571 switch( level ) {
00572 default:
00573 case KNotifyClient::Notification:
00574 KMessageBox::informationWId( winId, text, i18n("Notification"), 0, false );
00575 break;
00576 case KNotifyClient::Warning:
00577 KMessageBox::sorryWId( winId, text, i18n("Warning"), false );
00578 break;
00579 case KNotifyClient::Error:
00580 KMessageBox::errorWId( winId, text, i18n("Error"), false );
00581 break;
00582 case KNotifyClient::Catastrophe:
00583 KMessageBox::errorWId( winId, text, i18n("Catastrophe!"), false );
00584 break;
00585 }
00586
00587 return true;
00588 }
00589
00590 bool KNotify::notifyByPassivePopup( const TQString &text,
00591 const TQString &appName,
00592 TDEConfig* eventsFile,
00593 WId senderWinId )
00594 {
00595 TDEIconLoader iconLoader( appName );
00596 if ( eventsFile != NULL ) {
00597 TDEConfigGroup config( eventsFile, "!Global!" );
00598 TQString iconName = config.readEntry( "IconName", appName );
00599 TQPixmap icon = iconLoader.loadIcon( iconName, TDEIcon::Small );
00600 TQString title = config.readEntry( "Comment", appName );
00601 KPassivePopup::message(title, text, icon, senderWinId);
00602 }
00603 else {
00604 kdError() << "No events for app " << appName << "defined!" <<endl;
00605 }
00606
00607 return true;
00608 }
00609
00610 bool KNotify::notifyByExecute(const TQString &command, const TQString& event,
00611 const TQString& fromApp, const TQString& text,
00612 int winId, int eventId) {
00613 if (!command.isEmpty()) {
00614
00615 TQMap<TQChar,TQString> subst;
00616 subst.insert( 'e', event );
00617 subst.insert( 'a', fromApp );
00618 subst.insert( 's', text );
00619 subst.insert( 'w', TQString::number( winId ));
00620 subst.insert( 'i', TQString::number( eventId ));
00621 TQString execLine = KMacroExpander::expandMacrosShellQuote( command, subst );
00622 if ( execLine.isEmpty() ) {
00623 execLine = command;
00624 }
00625
00626 TDEProcess p;
00627 p.setUseShell(true);
00628 p << execLine;
00629 p.start(TDEProcess::DontCare);
00630 return true;
00631 }
00632 return false;
00633 }
00634
00635
00636 bool KNotify::notifyByLogfile(const TQString &text, const TQString &file)
00637 {
00638
00639 if ( text.isEmpty() ) {
00640 return true;
00641 }
00642
00643
00644 TQFile logFile(file);
00645 if ( !logFile.open(IO_WriteOnly | IO_Append) ) {
00646 return false;
00647 }
00648
00649
00650 TQTextStream strm( &logFile );
00651 strm << "- KNotify " << TQDateTime::currentDateTime().toString() << ": ";
00652 strm << text << endl;
00653
00654
00655 logFile.close();
00656 return true;
00657 }
00658
00659 bool KNotify::notifyByStderr(const TQString &text)
00660 {
00661
00662 if ( text.isEmpty() ) {
00663 return true;
00664 }
00665
00666
00667 TQTextStream strm( stderr, IO_WriteOnly );
00668
00669
00670 strm << "KNotify " << TQDateTime::currentDateTime().toString() << ": ";
00671 strm << text << endl;
00672
00673 return true;
00674 }
00675
00676 bool KNotify::notifyByTaskbar( WId win )
00677 {
00678 if( win == 0 ) {
00679 return false;
00680 }
00681 KWin::demandAttention( win );
00682 return true;
00683 }
00684
00685 bool KNotify::isGlobal(const TQString &eventname)
00686 {
00687 return d->globalEvents->hasGroup( eventname );
00688 }
00689
00690 void KNotify::setVolume( int volume )
00691 {
00692 if ( volume<0 ) volume=0;
00693 if ( volume>=100 ) volume=100;
00694 d->volume = volume;
00695 }
00696
00697 void KNotify::playTimeout()
00698 {
00699 #ifndef WITHOUT_ARTS
00700 for ( TQPtrListIterator< KDE::PlayObject > it(d->playObjects); *it;) {
00701 TQPtrListIterator< KDE::PlayObject > current = it;
00702 ++it;
00703 if ( (*current)->state() != Arts::posPlaying ) {
00704 TQMap<KDE::PlayObject*,int>::Iterator eit = d->playObjectEventMap.find( *current );
00705 if ( eit != d->playObjectEventMap.end() ) {
00706 soundFinished( *eit, PlayedOK );
00707 d->playObjectEventMap.remove( eit );
00708 }
00709 d->playObjects.remove( current );
00710 }
00711 }
00712 if ( !d->playObjects.count() ) {
00713 d->playTimer->stop();
00714 }
00715 #endif
00716 }
00717
00718 bool KNotify::isPlaying( const TQString& soundFile ) const
00719 {
00720 #ifndef WITHOUT_ARTS
00721 for ( TQPtrListIterator< KDE::PlayObject > it(d->playObjects); *it; ++it) {
00722 if ( (*it)->mediaName() == soundFile ) {
00723 return true;
00724 }
00725 }
00726 #endif
00727 return false;
00728 }
00729
00730 void KNotify::slotPlayerProcessExited( TDEProcess *proc )
00731 {
00732 soundFinished( d->externalPlayerEventId, (proc->normalExit() && proc->exitStatus() == 0) ? PlayedOK : Unknown );
00733 }
00734
00735 void KNotify::abortFirstPlayObject()
00736 {
00737 #ifndef WITHOUT_ARTS
00738 TQMap<KDE::PlayObject*,int>::Iterator it = d->playObjectEventMap.find( d->playObjects.getFirst() );
00739 if ( it != d->playObjectEventMap.end() ) {
00740 soundFinished( it.data(), Aborted );
00741 d->playObjectEventMap.remove( it );
00742 }
00743 d->playObjects.removeFirst();
00744 #endif
00745 }
00746
00747 void KNotify::soundFinished( int eventId, PlayingFinishedStatus reason )
00748 {
00749 TQByteArray data;
00750 TQDataStream stream( data, IO_WriteOnly );
00751 stream << eventId << (int) reason;
00752
00753 DCOPClient::mainClient()->emitDCOPSignal( "KNotify", "playingFinished(int,int)", data );
00754 }
00755
00756 WId KNotify::checkWinId( const TQString &appName, WId senderWinId )
00757 {
00758 if ( senderWinId == 0 ) {
00759 TQCString senderId = kapp->dcopClient()->senderId();
00760 TQCString compare = (appName + "-mainwindow").latin1();
00761 int len = compare.length();
00762
00763
00764 QCStringList objs = kapp->dcopClient()->remoteObjects( senderId );
00765 for (QCStringList::ConstIterator it = objs.begin(); it != objs.end(); ++it ) {
00766 TQCString obj( *it );
00767 if ( obj.left(len) == compare) {
00768
00769 TQCString replyType;
00770 TQByteArray data, replyData;
00771
00772 if ( kapp->dcopClient()->call(senderId, obj, "getWinID()", data, replyType, replyData) ) {
00773 TQDataStream answer(replyData, IO_ReadOnly);
00774 if (replyType == "int") {
00775 answer >> senderWinId;
00776
00777
00778 }
00779 }
00780 }
00781 }
00782 }
00783 return senderWinId;
00784 }
00785
00786 void KNotify::restartedArtsd()
00787 {
00788 #ifndef WITHOUT_ARTS
00789 delete d->audioManager;
00790 d->audioManager = new KAudioManagerPlay( soundServer );
00791 d->audioManager->setTitle( i18n( "Trinity System Notifications" ) );
00792 d->audioManager->setAutoRestoreID( "KNotify Aman Play" );
00793 #endif
00794 }
00795
00796 void KNotify::sessionReady()
00797 {
00798 if( d->inStartup && !d->startupEvents.isEmpty()) {
00799 kdDebug() << "There were knotify events while startup:" << d->startupEvents << endl;
00800 }
00801 d->inStartup = false;
00802 }
00803
00804