-rw-r--r-- | core/launcher/applauncher.h | 9 | ||||
-rw-r--r-- | core/launcher/documentlist.cpp | 31 | ||||
-rw-r--r-- | core/launcher/packageslave.cpp | 14 | ||||
-rw-r--r-- | core/launcher/packageslave.h | 2 | ||||
-rw-r--r-- | core/launcher/qrr.cpp | 220 | ||||
-rw-r--r-- | core/launcher/qrr.h | 66 | ||||
-rw-r--r-- | core/launcher/server.cpp | 391 | ||||
-rw-r--r-- | core/launcher/server.h | 12 | ||||
-rw-r--r-- | core/launcher/server.pro | 5 | ||||
-rw-r--r-- | core/launcher/serverapp.cpp | 7 |
10 files changed, 657 insertions, 100 deletions
diff --git a/core/launcher/applauncher.h b/core/launcher/applauncher.h index 4fd5491..22a458f 100644 --- a/core/launcher/applauncher.h +++ b/core/launcher/applauncher.h @@ -39,6 +39,7 @@ public: ~AppLauncher(); bool isRunning(const QString &app); + const QMap<int,QString> &runningApplications() { return runningApps; } static const int RAISE_TIMEOUT_MS; @@ -46,7 +47,7 @@ signals: void launched(int pid, const QString &app); void terminated(int pid, const QString &app); void connected(const QString &app); - + protected slots: void sigStopped(int sigPid, int sigStatus); void received(const QCString& msg, const QByteArray& data); @@ -65,12 +66,12 @@ private: bool execute(const QString &c, const QString &document, bool noRaise = FALSE); void kill( int pid ); int pidForName( const QString & ); - -private: + +private: QMap<int,QString> runningApps; QMap<QString,int> waitingHeartbeat; #ifdef Q_OS_WIN32 - QList<QProcess> runningAppsProc; + QList<QProcess> runningAppsProc; #endif int qlPid; bool qlReady; diff --git a/core/launcher/documentlist.cpp b/core/launcher/documentlist.cpp index 44ceb0c..d8e7a83 100644 --- a/core/launcher/documentlist.cpp +++ b/core/launcher/documentlist.cpp @@ -387,10 +387,10 @@ void DocumentList::DiffAppLnks() ++it1; } if (!found) { - odebug << "Item " << j->name().ascii() << " needs to be added" << oendl; + odebug << "Item " << j->name().ascii() << " needs to be added" << oendl; d->serverGui->applicationAdded( j->type(), *j ); - } - ++it2; + } + ++it2; } it1 = appLnkSet->children(); @@ -403,13 +403,13 @@ void DocumentList::DiffAppLnks() ++it2; } if (!found) { - odebug << "Item " << i->name().ascii() << " needs to be removed" << oendl; + odebug << "Item " << i->name().ascii() << " needs to be removed" << oendl; d->serverGui->applicationRemoved( i->type(), *i ); } - - ++it1; + + ++it1; } - + delete appLnkSet; appLnkSet = appLnkSet2; @@ -422,10 +422,10 @@ void DocumentList::storageChanged() t.start(); DiffAppLnks(); // reloadAppLnks(); - odebug << "Reload App links took " << t.elapsed() << " ms" << oendl; + odebug << "Reload App links took " << t.elapsed() << " ms" << oendl; reloadDocLnks(); // odebug << "Reload links took " << t.elapsed() << " ms " << oendl; - odebug << "Reload All links took " << t.elapsed() << " ms" << oendl; + odebug << "Reload All links took " << t.elapsed() << " ms" << oendl; // ### Optimization opportunity // Could be a bit more intelligent and somehow work out which // mtab entry has changed and then only scan that and add and remove @@ -456,7 +456,18 @@ void DocumentList::sendAllDocLinks() if ( f.open( IO_ReadOnly ) ) { QTextStream ts( &f ); ts.setEncoding( QTextStream::UnicodeUTF8 ); - contents += ts.read(); + QString docLnk = ts.read(); + // Strip out the (stale) LinkFile entry + int start = docLnk.find( "\nLinkFile = " ) + 1; + if ( start > 0 ) { + int end = docLnk.find( "\n", start + 1 ) + 1; + contents += docLnk.left(start); + contents += docLnk.mid(end); + } else { + contents += docLnk; + } + contents += "LinkFile = " + doc->linkFile() + "\n"; + f.close(); } else fake = TRUE; diff --git a/core/launcher/packageslave.cpp b/core/launcher/packageslave.cpp index 0461432..abbc610 100644 --- a/core/launcher/packageslave.cpp +++ b/core/launcher/packageslave.cpp @@ -65,6 +65,10 @@ void PackageHandler::qcopMessage( const QCString &msg, const QByteArray &data ) QString file; stream >> file; installPackage( file ); + } else if ( msg == "installPackage(QString,QString)" ) { + QString file, dest; + stream >> file >> dest; + installPackage( file, dest ); } else if ( msg == "removePackage(QString)" ) { QString file; stream >> file; @@ -93,7 +97,7 @@ void PackageHandler::qcopMessage( const QCString &msg, const QByteArray &data ) } } -void PackageHandler::installPackage( const QString &package ) +void PackageHandler::installPackage( const QString &package, const QString &dest ) { if ( mNoSpaceLeft ) { mNoSpaceLeft = FALSE; @@ -102,7 +106,13 @@ void PackageHandler::installPackage( const QString &package ) //return; } - currentProcess = new QProcess( QStringList() << "ipkg" << "install" << package ); // No tr + QStringList cmd; + cmd << "ipkg"; + if ( !dest.isEmpty() ) { + cmd << "-d" << dest; + } + cmd << "install" << package; + currentProcess = new QProcess( cmd ); // No tr connect( currentProcess, SIGNAL( processExited() ), SLOT( iProcessExited() ) ); connect( currentProcess, SIGNAL( readyReadStdout() ), SLOT( readyReadStdout() ) ); connect( currentProcess, SIGNAL( readyReadStderr() ), SLOT( readyReadStderr() ) ); diff --git a/core/launcher/packageslave.h b/core/launcher/packageslave.h index 878b4c3..83dfe6f 100644 --- a/core/launcher/packageslave.h +++ b/core/launcher/packageslave.h @@ -38,7 +38,7 @@ public slots: void redoPackages(); protected: - void installPackage( const QString &package ); + void installPackage( const QString &package, const QString &dest = QString::null ); void removePackage( const QString &package ); void addPackageFiles( const QString &location, const QString &listfile ); diff --git a/core/launcher/qrr.cpp b/core/launcher/qrr.cpp new file mode 100644 index 0000000..5809ca9 --- a/dev/null +++ b/core/launcher/qrr.cpp @@ -0,0 +1,220 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#include "qrr.h" + +#include <qtopia/qcopenvelope_qws.h> +#include <qfile.h> +#include <qtimer.h> +#include <qdialog.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qprogressbar.h> +#include <qapplication.h> +#include <qevent.h> + + +class CenteringDialog : public QDialog +{ +public: + CenteringDialog( QWidget *parent = 0, char *name = 0, bool modal = FALSE, WFlags f = 0 ); + virtual ~CenteringDialog(); + +protected: + void resizeEvent( QResizeEvent *e ); +}; + +CenteringDialog::CenteringDialog( QWidget *parent, char *name, bool modal, WFlags f ) + : QDialog( parent, name, modal, f ) +{ +} + +CenteringDialog::~CenteringDialog() +{ +} + +void CenteringDialog::resizeEvent( QResizeEvent *e ) +{ + int dist = -((width() - e->oldSize().width()) / 2); + qDebug( "move %d", dist ); + move( pos().x() + dist, pos().y() ); +} + +// ===================================================================== + +QueuedRequestRunner::QueuedRequestRunner( QFile *f, QWidget *parent ) + : readyToDelete( FALSE ), waitingForMessages( FALSE ), file( 0 ) +{ + file = f; + waitMsgs.setAutoDelete( TRUE ); + if ( parent ) { + progressDialog = new CenteringDialog( parent, 0, TRUE ); + QVBoxLayout *l = new QVBoxLayout( progressDialog ); + l->setMargin( 6 ); + l->setSpacing( 6 ); + progressLabel = new QLabel( progressDialog ); + progressLabel->setText( tr("Processing Queued Requests") ); + progressBar = new QProgressBar( progressDialog ); + l->addWidget( progressLabel ); + l->addWidget( progressBar ); + //progressDialog->setFixedSize( qApp->desktop()->width(), qApp->desktop()->height() ); + progressDialog->show(); + } + int totalSteps = countSteps(); + if ( parent ) { + qDebug( "%d steps", totalSteps ); + progressBar->setTotalSteps( totalSteps ); + progressBar->setProgress( 0 ); + } + file->open( IO_ReadOnly ); +} + +QueuedRequestRunner::~QueuedRequestRunner() +{ + delete progressDialog; + delete file; +} + +void QueuedRequestRunner::process() +{ + if ( process( FALSE ) ) { + if ( !waitingForMessages || action == "wait" ) + QTimer::singleShot( 100, this, SLOT(process()) ); + } else { + file->remove(); + emit finished(); + } + +} + +int QueuedRequestRunner::countSteps() +{ + int totalSteps = 0; + bool more = TRUE; + file->open( IO_ReadOnly ); + while ( more ) { + steps = 0; + more = process( TRUE ); + totalSteps += steps; + } + file->close(); + waitingForMessages = FALSE; + return totalSteps; +} + +bool QueuedRequestRunner::process( bool counting ) +{ + QDataStream stream( file ); + stream >> action; + if ( action == "info" ) { + QString message; + stream >> message; + qDebug( "info %s", message.latin1() ); + if ( counting ) { + steps++; + } else { + progressLabel->setText( message ); + } + } else if ( action == "qcop" ) { + QCString channel; + QCString message; + int args; + stream >> channel >> message >> args; + qDebug( "qcop %s %s", channel.data(), message.data() ); +#ifndef QT_NO_COP + QCopEnvelope *e = 0; + if ( !counting ) { + e = new QCopEnvelope( channel, message ); + } +#endif + QCString type; + for ( int i = 0; i < args; ++i ) { + stream >> type; + if ( type == "QString" ) { + QString arg; + stream >> arg; + qDebug( " %s %s", type.data(), arg.latin1() ); +#ifndef QT_NO_COP + if ( !counting ) + (*e) << arg; +#endif + } else if ( type == "int" ) { + int arg; + stream >> arg; + qDebug( " %s %d", type.data(), arg ); +#ifndef QT_NO_COP + if ( !counting ) + (*e) << arg; +#endif + } else { + qDebug( "\tBUG unknown type '%s'!", type.data() ); + } + } + if ( counting ) { + steps++; + } else { +#ifndef QT_NO_COP + // this causes the QCop message to be sent + delete e; +#endif + } + } else if ( action == "wait" ) { + int messageCount; + QCString message; + waitMsgs.clear(); + stream >> messageCount; + for ( int i = 0; i < messageCount; ++i ) { + stream >> message; + qDebug( "wait %s", message.data() ); + if ( !counting ) { + waitMsgs.append( new QCString( message ) ); + } + } + if ( counting ) + steps++; + waitingForMessages = TRUE; + } else { + qDebug( "\tBUG unknown action '%s'!", action.data() ); + } + + if ( !counting ) { + progressBar->setProgress( progressBar->progress() + 1 ); + } + + return !file->atEnd(); +} + +void QueuedRequestRunner::desktopMessage( const QCString &message, const QByteArray & ) +{ + bool found = FALSE; + QCString *msg; + for ( QListIterator<QCString> iter( waitMsgs ); ( msg = iter.current() ) != 0; ++iter ) { + if ( *msg == message ) { + found = TRUE; + break; + } + } + if ( found ) { + waitMsgs.clear(); + waitingForMessages = FALSE; + QTimer::singleShot( 100, this, SLOT(process()) ); + } +} + diff --git a/core/launcher/qrr.h b/core/launcher/qrr.h new file mode 100644 index 0000000..4c0a8db --- a/dev/null +++ b/core/launcher/qrr.h @@ -0,0 +1,66 @@ +/********************************************************************** +** 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 QRR_H +#define QRR_H + +#include <qobject.h> +#include <qlist.h> +#include <qcstring.h> + +class QFile; +class QDialog; +class QLabel; +class QProgressBar; +class QWidget; + +class QueuedRequestRunner : public QObject +{ + Q_OBJECT +public: + QueuedRequestRunner( QFile *f, QWidget *parent ); + virtual ~QueuedRequestRunner(); + + void desktopMessage( const QCString &message, const QByteArray &data ); + + bool readyToDelete; + bool waitingForMessages; + +signals: + void finished(); + +public slots: + void process(); + +private: + int countSteps(); + bool process( bool counting ); + + QFile *file; + QList<QCString> waitMsgs; + QDialog *progressDialog; + QLabel *progressLabel; + QProgressBar *progressBar; + int steps; + QCString action; +}; + + +#endif // QRR_H + diff --git a/core/launcher/server.cpp b/core/launcher/server.cpp index 3bef36e..524e6dd 100644 --- a/core/launcher/server.cpp +++ b/core/launcher/server.cpp @@ -35,6 +35,7 @@ #include "suspendmonitor.h" #endif #include "documentlist.h" +#include "qrr.h" /* OPIE */ #include <opie2/odebug.h> @@ -117,6 +118,10 @@ static Global::Command builtins[] = { { 0, calibrate, 0, 0 }, }; +#ifdef QPE_HAVE_DIRECT_ACCESS +extern void readyDirectAccess(QString cardInfo, QString installLocations); +extern const char *directAccessQueueFile(); +#endif //--------------------------------------------------------------------------- @@ -137,6 +142,7 @@ Server::Server() : /* tid_today = startTimer(3600*2*1000);*/ last_today_show = QDate::currentDate(); +#warning FIXME support TempScreenSaverMode #if 0 tsmMonitor = new TempScreenSaverMode(); connect( tsmMonitor, SIGNAL(forceSuspend()), qApp, SIGNAL(power()) ); @@ -154,6 +160,13 @@ Server::Server() : storage = new StorageInfo( this ); connect( storage, SIGNAL(disksChanged()), this, SLOT(storageChanged()) ); + +#ifdef QPE_HAVE_DIRECT_ACCESS + QCopChannel *desktopChannel = new QCopChannel( "QPE/Desktop", this ); + connect( desktopChannel, SIGNAL(received( const QCString &, const QByteArray & )), + this, SLOT(desktopMessage( const QCString &, const QByteArray & )) ); +#endif + // start services startTransferServer(); (void) new IrServer( this ); @@ -197,6 +210,31 @@ Server::~Server() } +static bool hasVisibleWindow(const QString& clientname, bool partial) +{ +#ifdef QWS + const QList<QWSWindow> &list = qwsServer->clientWindows(); + QWSWindow* w; + for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) { + if ( w->client()->identity() == clientname ) { + if ( partial && !w->isFullyObscured() ) + return TRUE; + if ( !partial && !w->isFullyObscured() && !w->isPartiallyObscured() ) { +# if QT_VERSION < 0x030000 + QRect mwr = qt_screen->mapToDevice(qt_maxWindowRect, + QSize(qt_screen->width(),qt_screen->height()) ); +# else + QRect mwr = qt_maxWindowRect; +# endif + if ( mwr.contains(w->requested().boundingRect()) ) + return TRUE; + } + } + } +#endif + return FALSE; +} + void Server::activate(const ODeviceButton* button, bool held) { Global::terminateBuiltin("calibrate"); // No tr @@ -292,48 +330,34 @@ void Server::systemMsg(const QCString &msg, const QByteArray &data) if ( qcopBridge ) qcopBridge->authorizeConnections(); - } else - +#warning FIXME support TempScreenSaverMode #if 0 - /* ### FIXME support TempScreenSaverMode */ - if ( msg == "setTempScreenSaverMode(int,int)" ) { + } else if ( msg == "setTempScreenSaverMode(int,int)" ) { int mode, pid; stream >> mode >> pid; tsmMonitor->setTempMode(mode, pid); - } else #endif - - if ( msg == "linkChanged(QString)" ) { + } else if ( msg == "linkChanged(QString)" ) { QString link; stream >> link; odebug << "desktop.cpp systemMsg -> linkchanged( " << link << " )" << oendl; docList->linkChanged(link); - } else - - if ( msg == "serviceChanged(QString)" ) { + } else if ( msg == "serviceChanged(QString)" ) { MimeType::updateApplications(); - } else - - if ( msg == "mkdir(QString)" ) { + } else if ( msg == "mkdir(QString)" ) { QString dir; stream >> dir; if ( !dir.isEmpty() ) mkdir( dir ); - } else - - if ( msg == "rdiffGenSig(QString,QString)" ) { + } else if ( msg == "rdiffGenSig(QString,QString)" ) { QString baseFile, sigFile; stream >> baseFile >> sigFile; QRsync::generateSignature( baseFile, sigFile ); - } else - - if ( msg == "rdiffGenDiff(QString,QString,QString)" ) { + } else if ( msg == "rdiffGenDiff(QString,QString,QString)" ) { QString baseFile, sigFile, deltaFile; stream >> baseFile >> sigFile >> deltaFile; QRsync::generateDiff( baseFile, sigFile, deltaFile ); - } else - - if ( msg == "rdiffApplyPatch(QString,QString)" ) { + } else if ( msg == "rdiffApplyPatch(QString,QString)" ) { QString baseFile, deltaFile; stream >> baseFile >> deltaFile; if ( !QFile::exists( baseFile ) ) { @@ -346,18 +370,14 @@ void Server::systemMsg(const QCString &msg, const QByteArray &data) QCopEnvelope e( "QPE/Desktop", "patchApplied(QString)" ); e << baseFile; #endif - } else - - if ( msg == "rdiffCleanup()" ) { + } else if ( msg == "rdiffCleanup()" ) { mkdir( "/tmp/rdiff" ); QDir dir; dir.setPath( "/tmp/rdiff" ); QStringList entries = dir.entryList(); for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it ) dir.remove( *it ); - } else - - if ( msg == "sendHandshakeInfo()" ) { + } else if ( msg == "sendHandshakeInfo()" ) { QString home = getenv( "HOME" ); #ifndef QT_NO_COP QCopEnvelope e( "QPE/Desktop", "handshakeInfo(QString,bool)" ); @@ -365,21 +385,17 @@ void Server::systemMsg(const QCString &msg, const QByteArray &data) int locked = (int) ServerApplication::screenLocked(); e << locked; #endif - } else - + } else if ( msg == "sendVersionInfo()" ) { /* * QtopiaDesktop relies on the major number - * to start with 1. We're at 0.9 - * so wee need to fake at least 1.4 to be able + * to start with 1. + * we need to fake at least 1.4 to be able * to sync with QtopiaDesktop1.6 */ - if ( msg == "sendVersionInfo()" ) { QCopEnvelope e( "QPE/Desktop", "versionInfo(QString,QString)" ); /* ### FIXME Architecture ### */ e << QString::fromLatin1("1.7") << "Uncustomized Device"; - } else - - if ( msg == "sendCardInfo()" ) { + } else if ( msg == "sendCardInfo()" ) { #ifndef QT_NO_COP QCopEnvelope e( "QPE/Desktop", "cardInfo(QString)" ); #endif @@ -409,9 +425,12 @@ void Server::systemMsg(const QCString &msg, const QByteArray &data) #ifndef QT_NO_COP e << s; #endif - } else - - if ( msg == "sendSyncDate(QString)" ) { + } else if ( msg == "sendInstallLocations()" ) { +#ifndef QT_NO_COP + QCopEnvelope e( "QPE/Desktop", "installLocations(QString)" ); + e << installLocationsString(); +#endif + } else if ( msg == "sendSyncDate(QString)" ) { QString app; stream >> app; Config cfg( "qpe" ); @@ -422,55 +441,48 @@ void Server::systemMsg(const QCString &msg, const QByteArray &data) #endif //odebug << "QPE/System sendSyncDate for " << app.latin1() << ": response " // << cfg.readEntry( app ).latin1() << oendl; - } else - - if ( msg == "setSyncDate(QString,QString)" ) { + } else if ( msg == "setSyncDate(QString,QString)" ) { QString app, date; stream >> app >> date; Config cfg( "qpe" ); cfg.setGroup("SyncDate"); cfg.writeEntry( app, date ); //odebug << "setSyncDate(QString,QString) " << app << " " << date << "" << oendl; - } else - - if ( msg == "startSync(QString)" ) { + } else if ( msg == "startSync(QString)" ) { QString what; stream >> what; delete syncDialog; syncDialog = new SyncDialog( this, what ); syncDialog->show(); connect( syncDialog, SIGNAL(cancel()), SLOT(cancelSync()) ); - } else - - if ( msg == "stopSync()") { + } else if ( msg == "stopSync()") { delete syncDialog; syncDialog = 0; - } else - - if (msg == "restoreDone(QString)") { + } else if (msg == "restoreDone(QString)") { docList->restoreDone(); - } else - - if ( msg == "getAllDocLinks()" ) { + } else if ( msg == "getAllDocLinks()" ) { docList->sendAllDocLinks(); - } else - + } +#ifdef QPE_HAVE_DIRECT_ACCESS + else if ( msg == "prepareDirectAccess()" ) { + prepareDirectAccess(); + } else if ( msg == "postDirectAccess()" ) { + postDirectAccess(); + } +#endif #ifdef Q_WS_QWS - if ( msg == "setMouseProto(QString)" ) { + + else if ( msg == "setMouseProto(QString)" ) { QString mice; stream >> mice; setenv("QWS_MOUSE_PROTO",mice.latin1(),1); qwsServer->openMouse(); - } else - - if ( msg == "setKeyboard(QString)" ) { + } else if ( msg == "setKeyboard(QString)" ) { QString kb; stream >> kb; setenv("QWS_KEYBOARD",kb.latin1(),1); qwsServer->openKeyboard(); - } else - - if ( msg == "setKeyboardAutoRepeat(int,int)" ) { + } else if ( msg == "setKeyboardAutoRepeat(int,int)" ) { int delay, period; stream >> delay >> period; qwsSetKeyboardAutoRepeat( delay, period ); @@ -478,18 +490,14 @@ void Server::systemMsg(const QCString &msg, const QByteArray &data) cfg.setGroup("Keyboard"); cfg.writeEntry( "RepeatDelay", delay ); cfg.writeEntry( "RepeatPeriod", period ); - } else - - if ( msg == "setKeyboardLayout(QString)" ) { + } else if ( msg == "setKeyboardLayout(QString)" ) { QString kb; stream >> kb; setKeyboardLayout( kb ); Config cfg( "qpe" ); cfg.setGroup("Keyboard"); cfg.writeEntry( "Layout", kb ); - } else - - if ( msg == "autoStart(QString)" ) { + } else if ( msg == "autoStart(QString)" ) { QString appName; stream >> appName; Config cfg( "autostart" ); @@ -497,9 +505,7 @@ void Server::systemMsg(const QCString &msg, const QByteArray &data) if ( appName.compare("clear") == 0){ cfg.writeEntry("Apps", ""); } - } else - - if ( msg == "autoStart(QString,QString)" ) { + } else if ( msg == "autoStart(QString,QString)" ) { QString modifier, appName; stream >> modifier >> appName; Config cfg( "autostart" ); @@ -520,9 +526,7 @@ void Server::systemMsg(const QCString &msg, const QByteArray &data) } } // case the autostart feature should be delayed - } else - - if ( msg == "autoStart(QString,QString,QString)") { + } else if ( msg == "autoStart(QString,QString,QString)") { QString modifier, appName, delay; stream >> modifier >> appName >> delay; Config cfg( "autostart" ); @@ -539,19 +543,71 @@ void Server::systemMsg(const QCString &msg, const QByteArray &data) #endif } +QString Server::cardInfoString() +{ + storage->update(); + const QList<FileSystem> &fs = storage->fileSystems(); + QListIterator<FileSystem> it ( fs ); + QString s; + QString homeDir = getenv("HOME"); + QString homeFs, homeFsPath; + for ( ; it.current(); ++it ) { + int k4 = (*it)->blockSize()/256; + if ( (*it)->isRemovable() ) { + s += (*it)->name() + "=" + (*it)->path() + "/Documents " // No tr + + QString::number( (*it)->availBlocks() * k4/4 ) + + "K " + (*it)->options() + ";"; + } else if ( homeDir.contains( (*it)->path() ) && + (*it)->path().length() > homeFsPath.length() ) { + homeFsPath = (*it)->path(); + homeFs = + (*it)->name() + "=" + homeDir + "/Documents " // No tr + + QString::number( (*it)->availBlocks() * k4/4 ) + + "K " + (*it)->options() + ";"; + } + } + if ( !homeFs.isEmpty() ) + s += homeFs; + return s; +} + +QString Server::installLocationsString() +{ + storage->update(); + const QList<FileSystem> &fs = storage->fileSystems(); + QListIterator<FileSystem> it ( fs ); + QString s; + QString homeDir = getenv("HOME"); + QString homeFs, homeFsPath; + for ( ; it.current(); ++it ) { + int k4 = (*it)->blockSize()/256; + if ( (*it)->isRemovable() ) { + s += (*it)->name() + "=" + (*it)->path() + " " // No tr + + QString::number( (*it)->availBlocks() * k4/4 ) + + "K " + (*it)->options() + ";"; + } else if ( homeDir.contains( (*it)->path() ) && + (*it)->path().length() > homeFsPath.length() ) { + homeFsPath = (*it)->path(); + homeFs = + (*it)->name() + "=" + homeDir + " " // No tr + + QString::number( (*it)->availBlocks() * k4/4 ) + + "K " + (*it)->options() + ";"; + } + } + if ( !homeFs.isEmpty() ) + s = homeFs + s; + return s; +} + void Server::receiveTaskBar(const QCString &msg, const QByteArray &data) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "reloadApps()" ) { docList->reloadAppLnks(); - } else - - if ( msg == "soundAlarm()" ) { + } else if ( msg == "soundAlarm()" ) { ServerApplication::soundAlarm(); - } else - - if ( msg == "setLed(int,bool)" ) { + } else if ( msg == "setLed(int,bool)" ) { int led, status; stream >> led >> status; @@ -748,3 +804,176 @@ void Server::preloadApps() #endif } } + +// This is only called if QPE_HAVE_DIRECT_ACCESS is defined +void Server::prepareDirectAccess() +{ + qDebug( "Server::prepareDirectAccess()" ); + // Put up a pretty dialog + syncDialog = new SyncDialog( this, tr("USB Lock") ); + syncDialog->show(); + + // Prevent the PDA from acting as a PDA + terminateServers(); + + // suspend the mtab monitor +#ifndef QT_NO_COP + { + QCopEnvelope e( "QPE/Stabmon", "suspendMonitor()" ); + } +#endif + + // send out a flush message + // once flushes are done call runDirectAccess() + // We just count the number of apps and set a timer. + // Either the timer expires or the correct number of apps responds. + // Note: quicklauncher isn't in the runningApps list but it responds + // to the flush so we start the counter at 1 + pendingFlushes = 1; + directAccessRun = FALSE; + for ( QMap<int,QString>::ConstIterator it = + appLauncher->runningApplications().begin(); + it != appLauncher->runningApplications().end(); + ++it ) { + pendingFlushes++; + } +#ifndef QT_NO_COP + QCopEnvelope e1( "QPE/System", "flush()" ); +#endif + QTimer::singleShot( 10000, this, SLOT(runDirectAccess()) ); +#warning FIXME support TempScreenSaverMode +#if 0 + QPEApplication::setTempScreenSaverMode(QPEApplication::DisableSuspend); +#endif +} + +// This is only connected if QPE_HAVE_DIRECT_ACCESS is defined +// It fakes the presence of Qtopia Desktop +void Server::desktopMessage( const QCString &message, const QByteArray &data ) +{ + QDataStream stream( data, IO_ReadOnly ); + if ( message == "flushDone(QString)" ) { + QString app; + stream >> app; + qDebug( "flushDone from %s", app.latin1() ); + if ( --pendingFlushes == 0 ) { + qDebug( "pendingFlushes == 0, all the apps responded" ); + runDirectAccess(); + } + } else if ( message == "installStarted(QString)" ) { + QString package; + stream >> package; + qDebug( "\tInstall Started for package %s", package.latin1() ); + } else if ( message == "installStep(QString)" ) { + QString step; + stream >> step; + qDebug( "\tInstall Step %s", step.latin1() ); + } else if ( message == "installDone(QString)" ) { + QString package; + stream >> package; + qDebug( "\tInstall Finished for package %s", package.latin1() ); + } else if ( message == "installFailed(QString,int,QString)" ) { + QString package, error; + int status; + stream >> package >> status >> error; + qDebug( "\tInstall Failed for package %s with error code %d and error message %s", + package.latin1(), status, error.latin1() ); + } else if ( message == "removeStarted(QString)" ) { + QString package; + stream >> package; + qDebug( "\tRemove Started for package %s", package.latin1() ); + } else if ( message == "removeDone(QString)" ) { + QString package; + stream >> package; + qDebug( "\tRemove Finished for package %s", package.latin1() ); + } else if ( message == "removeFailed(QString)" ) { + QString package; + stream >> package; + qDebug( "\tRemove Failed for package %s", package.latin1() ); + } + + if ( qrr && qrr->waitingForMessages ) + qrr->desktopMessage( message, data ); +} + + +// This is only connected if QPE_HAVE_DIRECT_ACCESS is defined +void Server::runDirectAccess() +{ +#ifdef QPE_HAVE_DIRECT_ACCESS + // The timer must have fired after all the apps responded + // with flushDone(). Just ignore it. + if ( directAccessRun ) + return; + + directAccessRun = TRUE; + ::readyDirectAccess(cardInfoString(), installLocationsString()); +#endif +} + +// This is only called if QPE_HAVE_DIRECT_ACCESS is defined +void Server::postDirectAccess() +{ +#ifdef QPE_HAVE_DIRECT_ACCESS + qDebug( "Server::postDirectAccess()" ); + + // Categories may have changed + QCopEnvelope e1( "QPE/System", "categoriesChanged()" ); + // Apps need to reload their data + QCopEnvelope e2( "QPE/System", "reload()" ); + // Reload DocLinks + docList->storageChanged(); + // Restart the PDA server stuff + startTransferServer(); + + // restart the mtab monitor +#ifndef QT_NO_COP + { + QCopEnvelope e( "QPE/Stabmon", "restartMonitor()" ); + } +#endif + + // Process queued requests + const char *queueFile = ::directAccessQueueFile(); + QFile *file = new QFile( queueFile ); + if ( !file->exists() ) { + delete file; + // Get rid of the dialog + if ( syncDialog ) { + delete syncDialog; + syncDialog = 0; + } +#warning FIXME support TempScreenSaverMode +#if 0 + QPEApplication::setTempScreenSaverMode(QPEApplication::Enable); +#endif + } else { + qrr = new QueuedRequestRunner( file, syncDialog ); + connect( qrr, SIGNAL(finished()), + this, SLOT(finishedQueuedRequests()) ); + QTimer::singleShot( 100, qrr, SLOT(process()) ); + // qrr will remove the sync dialog later + } +#endif +} + +void Server::finishedQueuedRequests() +{ + if ( qrr->readyToDelete ) { + delete qrr; + qrr = 0; + // Get rid of the dialog + if ( syncDialog ) { + delete syncDialog; + syncDialog = 0; + } +#warning FIXME support TempScreenSaverMode +#if 0 + QPEApplication::setTempScreenSaverMode(QPEApplication::Enable); +#endif + } else { + qrr->readyToDelete = TRUE; + QTimer::singleShot( 0, this, SLOT(finishedQueuedRequests()) ); + } +} + diff --git a/core/launcher/server.h b/core/launcher/server.h index 1dc5e7e..d71d68a 100644 --- a/core/launcher/server.h +++ b/core/launcher/server.h @@ -37,6 +37,7 @@ class StorageInfo; class SyncDialog; class DocumentList; class ServerInterface; +class QueuedRequestRunner; namespace Opie { namespace Core { class ODeviceButton; @@ -69,6 +70,9 @@ private slots: void applicationConnected(const QString &app); void storageChanged(); void cancelSync(); + void desktopMessage( const QCString &, const QByteArray & ); + void runDirectAccess(); + void finishedQueuedRequests(); protected: void styleChange( QStyle & ); @@ -78,6 +82,10 @@ private: void layout(); void startTransferServer(); void preloadApps(); + void prepareDirectAccess(); + void postDirectAccess(); + QString cardInfoString(); + QString installLocationsString(); QCopBridge *qcopBridge; TransferServer *transferServer; @@ -92,6 +100,10 @@ private: AppLauncher *appLauncher; DocumentList *docList; ServerInterface *serverGui; + + int pendingFlushes; + bool directAccessRun; + QueuedRequestRunner *qrr; }; diff --git a/core/launcher/server.pro b/core/launcher/server.pro index f366f54..5f2aa02 100644 --- a/core/launcher/server.pro +++ b/core/launcher/server.pro @@ -5,6 +5,7 @@ CONFIG += qt warn_on DESTDIR = $$(OPIEDIR)/bin HEADERS += server.h \ + qrr.h \ serverinterface.h \ launchertab.h \ documentlist.h \ @@ -34,6 +35,7 @@ HEADERS += server.h \ mediadlg.h SOURCES += server.cpp \ + qrr.cpp \ serverinterface.cpp \ launchertab.cpp \ documentlist.cpp \ @@ -77,6 +79,9 @@ DEPENDPATH += $(OPIEDIR)/noncore/settings/mediummount LIBS += -lqpe -lopiecore2 -lopieui2 -lopiesecurity2 -lqrsync TARGET = qpe +## not ready for use yet +# DEFINES += QPE_HAVE_DIRECT_ACCESS + contains( $(CONFIG_TARGET_MACOSX), y ) { LIBS += -lcrypt } diff --git a/core/launcher/serverapp.cpp b/core/launcher/serverapp.cpp index 66cc788..fac52a6 100644 --- a/core/launcher/serverapp.cpp +++ b/core/launcher/serverapp.cpp @@ -60,11 +60,13 @@ static int loggedin=0; QCopKeyRegister::QCopKeyRegister() : m_keyCode( 0 ) { +odebug << "KeyRegister1 " << m_keyCode << oendl; } QCopKeyRegister::QCopKeyRegister( int k, const QCString& c, const QCString& m ) :m_keyCode( k ), m_channel( c ), m_message( m ) { +odebug << "keyRegister2 " << m_keyCode << c << m << oendl; } int QCopKeyRegister::keyCode() const @@ -86,8 +88,8 @@ bool QCopKeyRegister::send() { if (m_channel.isNull() ) return false; - - QCopEnvelope( m_channel, m_message ); +qDebug("Send Message: "+m_channel+" "+m_message); + QCopEnvelope e( m_channel, m_message ); return true; } @@ -165,6 +167,7 @@ void KeyFilter::timerEvent(QTimerEvent* e) void KeyFilter::registerKey( const QCopKeyRegister& key ) { +odebug << "KeyFilter::registerKey " << key.keyCode() << key.channel() << key.message() << oendl; m_keys.insert( key.keyCode(), key ); } |