Diffstat (limited to 'core/launcher/applauncher.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/launcher/applauncher.cpp | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/core/launcher/applauncher.cpp b/core/launcher/applauncher.cpp index 7d3c032..08a3cb4 100644 --- a/core/launcher/applauncher.cpp +++ b/core/launcher/applauncher.cpp @@ -1,286 +1,286 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef QTOPIA_INTERNAL_PRELOADACCESS #define QTOPIA_INTERNAL_PRELOADACCESS #endif #ifndef QTOPIA_INTERNAL_FILEOPERATIONS #define QTOPIA_INTERNAL_FILEOPERATIONS #endif #ifndef QTOPIA_PROGRAM_MONITOR #define QTOPIA_PROGRAM_MONITOR #endif #include <opie2/oglobal.h> #ifndef Q_OS_WIN32 #include <sys/stat.h> #include <sys/wait.h> #include <sys/file.h> #include <unistd.h> #include <sys/time.h> #include <sys/resource.h> #include <errno.h> #else #include <process.h> #include <windows.h> #include <winbase.h> #endif #include <signal.h> #include <sys/types.h> #include <stdlib.h> #include <qtimer.h> #include <qwindowsystem_qws.h> #include <qmessagebox.h> #include <qfileinfo.h> #include <qtopia/qcopenvelope_qws.h> #include <qtopia/qpeapplication.h> #include "applauncher.h" #include "documentlist.h" const int AppLauncher::RAISE_TIMEOUT_MS = 5000; //--------------------------------------------------------------------------- static AppLauncher* appLauncherPtr; const int appStopEventID = 1290; class AppStoppedEvent : public QCustomEvent { public: AppStoppedEvent(int pid, int status) : QCustomEvent( appStopEventID ), mPid(pid), mStatus(status) { } int pid() { return mPid; } int status() { return mStatus; } private: int mPid, mStatus; }; AppLauncher::AppLauncher(QObject *parent, const char *name) : QObject(parent, name), qlPid(0), qlReady(FALSE), appKillerBox(0) { connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&))); connect(qwsServer, SIGNAL(removedChannel(const QString&)), this, SLOT(removedQcopChannel(const QString&))); QCopChannel* channel = new QCopChannel( "QPE/System", this ); - connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), - this, SLOT(received(const QCString&, const QByteArray&)) ); + connect( channel, SIGNAL(received(const QCString&,const QByteArray&)), + this, SLOT(received(const QCString&,const QByteArray&)) ); channel = new QCopChannel( "QPE/Server", this ); - connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), - this, SLOT(received(const QCString&, const QByteArray&)) ); + connect( channel, SIGNAL(received(const QCString&,const QByteArray&)), + this, SLOT(received(const QCString&,const QByteArray&)) ); #ifndef Q_OS_WIN32 signal(SIGCHLD, signalHandler); #else runningAppsProc.setAutoDelete( TRUE ); #endif QString tmp = qApp->argv()[0]; int pos = tmp.findRev('/'); if ( pos > -1 ) tmp = tmp.mid(++pos); runningApps[::getpid()] = tmp; appLauncherPtr = this; QTimer::singleShot( 1000, this, SLOT(createQuickLauncher()) ); } AppLauncher::~AppLauncher() { appLauncherPtr = 0; #ifndef Q_OS_WIN32 signal(SIGCHLD, SIG_DFL); #endif if ( qlPid ) { int status; ::kill( qlPid, SIGTERM ); waitpid( qlPid, &status, 0 ); } } /* We use the QCopChannel of the app as an indicator of when it has been launched so that we can disable the busy indicators */ void AppLauncher::newQcopChannel(const QString& channelName) { // qDebug("channel %s added", channelName.data() ); QString prefix("QPE/Application/"); if (channelName.startsWith(prefix)) { { QCopEnvelope e("QPE/System", "newChannel(QString)"); e << channelName; } QString appName = channelName.mid(prefix.length()); if ( appName != "quicklauncher" ) { emit connected( appName ); QCopEnvelope e("QPE/System", "notBusy(QString)"); e << appName; } } else if (channelName.startsWith("QPE/QuickLauncher-")) { qDebug("Registered %s", channelName.latin1()); int pid = channelName.mid(18).toInt(); if (pid == qlPid) qlReady = TRUE; } } void AppLauncher::removedQcopChannel(const QString& channelName) { if (channelName.startsWith("QPE/Application/")) { QCopEnvelope e("QPE/System", "removedChannel(QString)"); e << channelName; } } void AppLauncher::received(const QCString& msg, const QByteArray& data) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "execute(QString)" ) { QString t; stream >> t; if ( !executeBuiltin( t, QString::null ) ) execute(t, QString::null); } else if ( msg == "execute(QString,QString)" ) { QString t,d; stream >> t >> d; if ( !executeBuiltin( t, d ) ) execute( t, d ); } else if ( msg == "processQCop(QString)" ) { // from QPE/Server QString t; stream >> t; if ( !executeBuiltin( t, QString::null ) ) execute( t, QString::null, TRUE); } else if ( msg == "raise(QString)" ) { QString appName; stream >> appName; if ( !executeBuiltin( appName, QString::null ) ) { if ( !waitingHeartbeat.contains( appName ) && appKillerName != appName ) { //qDebug( "Raising: %s", appName.latin1() ); QCString channel = "QPE/Application/"; channel += appName.latin1(); // Need to lock it to avoid race conditions with QPEApplication::processQCopFile QFile f("/tmp/qcop-msg-" + appName); if ( f.open(IO_WriteOnly | IO_Append) ) { #ifndef Q_OS_WIN32 flock(f.handle(), LOCK_EX); #endif QDataStream ds(&f); QByteArray b; QDataStream bstream(b, IO_WriteOnly); ds << channel << QCString("raise()") << b; f.flush(); #ifndef Q_OS_WIN32 flock(f.handle(), LOCK_UN); #endif f.close(); } bool alreadyRunning = isRunning( appName ); if ( execute(appName, QString::null) ) { int id = startTimer(RAISE_TIMEOUT_MS + alreadyRunning?2000:0); waitingHeartbeat.insert( appName, id ); } } } } else if ( msg == "sendRunningApps()" ) { QStringList apps; QMap<int,QString>::Iterator it; for( it = runningApps.begin(); it != runningApps.end(); ++it ) apps.append( *it ); QCopEnvelope e( "QPE/Desktop", "runningApps(QStringList)" ); e << apps; } else if ( msg == "appRaised(QString)" ) { QString appName; stream >> appName; qDebug("Got a heartbeat from %s", appName.latin1()); QMap<QString,int>::Iterator it = waitingHeartbeat.find(appName); if ( it != waitingHeartbeat.end() ) { killTimer( *it ); waitingHeartbeat.remove(it); } // Check to make sure we're not waiting on user input... if ( appKillerBox && appName == appKillerName ) { // If we are, we kill the dialog box, and the code waiting on the result // will clean us up (basically the user said "no"). delete appKillerBox; appKillerBox = 0; appKillerName = QString::null; } } } void AppLauncher::signalHandler(int) { #ifndef Q_OS_WIN32 int status; pid_t pid = waitpid(-1, &status, WNOHANG); /* if (pid == 0 || &status == 0 ) { qDebug("hmm, could not get return value from signal"); } */ QApplication::postEvent(appLauncherPtr, new AppStoppedEvent(pid, status) ); #else qDebug("Unhandled signal see by AppLauncher::signalHandler(int)"); #endif } bool AppLauncher::event(QEvent *e) { if ( e->type() == appStopEventID ) { AppStoppedEvent *ae = (AppStoppedEvent *) e; sigStopped(ae->pid(), ae->status() ); return TRUE; } return QObject::event(e); } void AppLauncher::timerEvent( QTimerEvent *e ) { int id = e->timerId(); QMap<QString,int>::Iterator it; for ( it = waitingHeartbeat.begin(); it != waitingHeartbeat.end(); ++it ) { if ( *it == id ) { if ( appKillerBox ) // we're already dealing with one return; appKillerName = it.key(); killTimer( id ); waitingHeartbeat.remove( it ); // qDebug("Checking in on %s", appKillerName.latin1()); // We store this incase the application responds while we're // waiting for user input so we know not to delete ourselves. appKillerBox = new QMessageBox(tr("Application Problem"), tr("<p>%1 is not responding.</p>").arg(appKillerName) + tr("<p>Would you like to force the application to exit?</p>"), QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default, QMessageBox::NoButton); if (appKillerBox->exec() == QMessageBox::Yes) { // qDebug("Killing the app!!! Bwuhahahaha!"); |