summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/applauncher.h9
-rw-r--r--core/launcher/documentlist.cpp31
-rw-r--r--core/launcher/packageslave.cpp14
-rw-r--r--core/launcher/packageslave.h2
-rw-r--r--core/launcher/qrr.cpp220
-rw-r--r--core/launcher/qrr.h66
-rw-r--r--core/launcher/server.cpp391
-rw-r--r--core/launcher/server.h12
-rw-r--r--core/launcher/server.pro5
-rw-r--r--core/launcher/serverapp.cpp7
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
@@ -1,82 +1,83 @@
/**********************************************************************
** 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 APP_LAUNCHER_H
#define APP_LAUNCHER_H
#include <qtopia/global.h>
#include <qobject.h>
#include <qmap.h>
#ifdef Q_OS_WIN32
#include <qtopia/qprocess.h>
#include <qlist.h>
#endif
class QMessageBox;
class AppLauncher : public QObject
{
Q_OBJECT
public:
AppLauncher(QObject *parent = 0, const char *name = 0);
~AppLauncher();
bool isRunning(const QString &app);
+ const QMap<int,QString> &runningApplications() { return runningApps; }
static const int RAISE_TIMEOUT_MS;
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);
void newQcopChannel(const QString& channel);
void removedQcopChannel(const QString& channel);
void createQuickLauncher();
void processExited();
protected:
bool event(QEvent *);
void timerEvent( QTimerEvent * );
private:
static void signalHandler(int sig);
bool executeBuiltin(const QString &c, const QString &document);
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;
QMessageBox *appKillerBox;
QString appKillerName;
};
#endif
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
@@ -342,166 +342,177 @@ void DocumentList::DiffAppLnks()
if ( d->sendAppLnks && d->serverGui ) {
static QStringList prevTypeList = appLnkSet->types();
QStringList types = appLnkSet2->types();
for ( QStringList::Iterator ittypes=types.begin(); ittypes!=types.end(); ++ittypes) {
if ( !(*ittypes).isEmpty() ) {
if ( !prevTypeList.contains(*ittypes) ) {
QString name = appLnkSet2->typeName(*ittypes);
QPixmap pm = appLnkSet2->typePixmap(*ittypes);
QPixmap bgPm = appLnkSet2->typeBigPixmap(*ittypes);
if (pm.isNull()) {
QImage img( Resource::loadImage( "UnknownDocument" ) );
pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() );
bgPm = img.smoothScale( AppLnk::bigIconSize(), AppLnk::bigIconSize() );
}
odebug << "adding type " << (*ittypes) << "" << oendl;
// ### our current launcher expects docs tab to be last
d->serverGui->typeAdded( *ittypes, name.isNull() ? (*ittypes) : name, pm, bgPm );
}
prevTypeList.remove(*ittypes);
}
}
for ( QStringList::Iterator ittypes=prevTypeList.begin(); ittypes!=prevTypeList.end(); ++ittypes) {
odebug << "removing type " << (*ittypes) << "" << oendl;
d->serverGui->typeRemoved(*ittypes);
}
prevTypeList = types;
}
QListIterator<AppLnk> it1( appLnkSet->children() );
QListIterator<AppLnk> it2( appLnkSet2->children() );
AppLnk *i;
AppLnk *j;
bool found;
while ( (j=it2.current()) ) {
it1 = appLnkSet->children();
found = false;
while ( (i=it1.current()) ){
if (strcmp(i->name().ascii(),j->name().ascii()) == 0)
found = true;
++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();
while ( (i=it1.current()) ) {
it2 = appLnkSet2->children();
found = false;
while ( (j=it2.current()) ){
if (strcmp(i->name().ascii(),j->name().ascii()) == 0)
found = true;
++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;
}
void DocumentList::storageChanged()
{
QTime t;
// ### can implement better
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
// links appropriately.
// rescan();
}
void DocumentList::sendAllDocLinks()
{
if ( d->tid != 0 ) {
// We are in the middle of scanning, set a flag so
// we do this when we finish our scanning
d->needToSendAllDocLinks = true;
return;
}
QString contents;
Categories cats;
for ( QListIterator<DocLnk> it( d->dls.children() ); it.current(); ++it ) {
DocLnk *doc = it.current();
QFileInfo fi( doc->file() );
if ( !fi.exists() )
continue;
bool fake = !doc->linkFileKnown();
if ( !fake ) {
QFile f( doc->linkFile() );
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;
}
if (fake) {
contents += "[Desktop Entry]\n"; // No tr
contents += "Categories = " + // No tr
cats.labels("Document View",doc->categories()).join(";") + "\n"; // No tr
contents += "Name = "+doc->name()+"\n"; // No tr
contents += "Type = "+doc->type()+"\n"; // No tr
}
contents += "File = "+doc->file()+"\n"; // No tr // (resolves path)
contents += QString("Size = %1\n").arg( fi.size() ); // No tr
}
//odebug << "sending length " << contents.length() << "" << oendl;
#ifndef QT_NO_COP
QCopEnvelope e( "QPE/Desktop", "docLinks(QString)" );
e << contents;
#endif
//odebug << "================ \n\n" << contents << "\n\n===============" << oendl;
d->needToSendAllDocLinks = false;
}
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
@@ -20,134 +20,144 @@
#include "packageslave.h"
/* OPIE */
#include <opie2/odebug.h>
#include <qtopia/qprocess.h>
#ifdef Q_WS_QWS
#include <qtopia/qcopenvelope_qws.h>
#endif
using namespace Opie::Core;
/* QT */
#ifdef Q_WS_QWS
#include <qcopchannel_qws.h>
#endif
#include <qtextstream.h>
/* STD */
#include <stdlib.h>
#include <sys/stat.h> // mkdir()
#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
#include <unistd.h>
#include <sys/vfs.h>
#include <mntent.h>
#elif defined(Q_OS_MACX)
#include <unistd.h>
#endif
PackageHandler::PackageHandler( QObject *parent, char* name )
: QObject( parent, name ), packageChannel( 0 ), currentProcess( 0 ), mNoSpaceLeft( FALSE )
{
// setup qcop channel
#ifndef QT_NO_COP
packageChannel = new QCopChannel( "QPE/Package", this );
connect( packageChannel, SIGNAL( received(const QCString&,const QByteArray&) ),
this, SLOT( qcopMessage(const QCString&,const QByteArray&) ) );
#endif
}
void PackageHandler::qcopMessage( const QCString &msg, const QByteArray &data )
{
QDataStream stream( data, IO_ReadOnly );
if ( msg == "installPackage(QString)" ) {
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;
removePackage( file );
} else if ( msg == "addPackageFiles(QString,QString)" ) {
QString location, listfile;
stream >> location >> listfile;
addPackageFiles( location, listfile);
} else if ( msg == "addPackages(QString)" ) {
QString location;
stream >> location;
addPackages( location );
} else if ( msg == "cleanupPackageFiles(QString)" ) {
QString listfile;
stream >> listfile;
cleanupPackageFiles( listfile );
} else if ( msg == "cleanupPackages(QString)" ) {
QString location;
stream >> location;
cleanupPackages( location );
} else if ( msg == "prepareInstall(QString,QString)" ) {
QString size, path;
stream >> size;
stream >> path;
prepareInstall( size, path );
}
}
-void PackageHandler::installPackage( const QString &package )
+void PackageHandler::installPackage( const QString &package, const QString &dest )
{
if ( mNoSpaceLeft ) {
mNoSpaceLeft = FALSE;
// Don't emit that for now, I still couldn't test it (Wener)
//sendReply( "installFailed(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() ) );
currentPackage = package;
currentProcessError="";
sendReply( "installStarted(QString)", package );
currentProcess->start();
}
void PackageHandler::removePackage( const QString &package )
{
currentProcess = new QProcess( QStringList() << "ipkg" << "remove" << package ); // No tr
connect( currentProcess, SIGNAL( processExited() ), SLOT( rmProcessExited() ) );
connect( currentProcess, SIGNAL( readyReadStdout() ), SLOT( readyReadStdout() ) );
connect( currentProcess, SIGNAL( readyReadStderr() ), SLOT( readyReadStderr() ) );
currentPackage = package;
currentProcessError="";
sendReply( "removeStarted(QString)", package );
currentProcess->start();
}
void PackageHandler::sendReply( const QCString& msg, const QString& arg )
{
#ifndef QT_NO_COP
QCopEnvelope e( "QPE/Desktop", msg );
e << arg;
#endif
}
void PackageHandler::addPackageFiles( const QString &location,
const QString &listfile )
{
QFile f(listfile);
#ifndef Q_OS_WIN32
//make a copy so we can remove the symlinks later
mkdir( ("/usr/lib/ipkg/info/"+location).ascii(), 0777 );
system(("cp " + f.name() + " /usr/lib/ipkg/info/"+location).ascii());
#else
QDir d;
//#### revise
odebug << "Copy file at " << __FILE__ << ": " << __LINE__ << "" << oendl;
d.mkdir(("/usr/lib/ipkg/info/" + location).ascii());
system(("copy " + f.name() + " /usr/lib/ipkg/info/"+location).ascii());
#endif
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
@@ -1,73 +1,73 @@
/**********************************************************************
** 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 __packageslave_h__
#define __packageslave_h__
#include <qtopia/global.h>
#include <qobject.h>
class QCopChannel;
class QProcess;
class PackageHandler : public QObject
{
Q_OBJECT
public:
PackageHandler( QObject *parent, char* name = 0 );
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 );
void addPackages( const QString &location );
void cleanupPackageFiles( const QString &listfile );
void cleanupPackages( const QString &location );
void prepareInstall( const QString& size, const QString& path );
protected slots:
void qcopMessage( const QCString &msg, const QByteArray &data );
void iProcessExited();
void rmProcessExited();
void readyReadStdout();
void readyReadStderr();
private:
void sendReply( const QCString& msg, const QString& arg );
private:
QCopChannel *packageChannel;
QProcess *currentProcess;
QString currentPackage;
QString currentProcessError;
bool mNoSpaceLeft;
};
#endif // __QUICK_LAUNCHER_H__
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
@@ -1,602 +1,658 @@
/**********************************************************************
** 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 "server.h"
#include "serverapp.h"
#include "startmenu.h"
#include "launcher.h"
#include "transferserver.h"
#include "qcopbridge.h"
#include "irserver.h"
#include "packageslave.h"
#include "calibrate.h"
#include "qrsync.h"
#include "syncdialog.h"
#include "shutdownimpl.h"
#include "applauncher.h"
#if 0
#include "suspendmonitor.h"
#endif
#include "documentlist.h"
+#include "qrr.h"
/* OPIE */
#include <opie2/odebug.h>
#include <opie2/odevicebutton.h>
#include <opie2/odevice.h>
#include <qtopia/applnk.h>
#include <qtopia/private/categories.h>
#include <qtopia/mimetype.h>
#include <qtopia/config.h>
#include <qtopia/resource.h>
#include <qtopia/version.h>
#include <qtopia/storage.h>
#include <qtopia/qcopenvelope_qws.h>
#include <qtopia/global.h>
using namespace Opie::Core;
/* QT */
#include <qmainwindow.h>
#include <qmessagebox.h>
#include <qtimer.h>
#include <qtextstream.h>
#include <qwindowsystem_qws.h>
#include <qgfx_qws.h>
/* STD */
#include <unistd.h>
#include <stdlib.h>
extern QRect qt_maxWindowRect;
static QWidget *calibrate(bool)
{
#ifdef Q_WS_QWS
Calibrate *c = new Calibrate;
c->show();
return c;
#else
return 0;
#endif
}
#define FACTORY(T) \
static QWidget *new##T( bool maximized ) { \
QWidget *w = new T( 0, 0, QWidget::WDestructiveClose | QWidget::WGroupLeader ); \
if ( maximized ) { \
if ( qApp->desktop()->width() <= 350 ) { \
w->showMaximized(); \
} else { \
w->resize( QSize( 300, 300 ) ); \
} \
} \
w->show(); \
return w; \
}
#ifdef SINGLE_APP
#define APP(a,b,c,d) FACTORY(b)
#include "apps.h"
#undef APP
#endif // SINGLE_APP
static Global::Command builtins[] = {
#ifdef SINGLE_APP
#define APP(a,b,c,d) { a, new##b, c, d },
#include "apps.h"
#undef APP
#endif
/* FIXME defines need to be defined*/
#if !defined(OPIE_NO_BUILTIN_CALIBRATE)
{ "calibrate", calibrate, 1, 0 }, // No tr
#endif
#if !defined(OPIE_NO_BUILTIN_SHUTDOWN)
{ "shutdown", Global::shutdown, 1, 0 }, // No tr
// { "run", run, 1, 0 }, // No tr
#endif
{ 0, calibrate, 0, 0 },
};
+#ifdef QPE_HAVE_DIRECT_ACCESS
+extern void readyDirectAccess(QString cardInfo, QString installLocations);
+extern const char *directAccessQueueFile();
+#endif
//---------------------------------------------------------------------------
//===========================================================================
Server::Server() :
QWidget( 0, 0, WStyle_Tool | WStyle_Customize ),
qcopBridge( 0 ),
transferServer( 0 ),
packageHandler( 0 ),
syncDialog( 0 )
{
Global::setBuiltinCommands(builtins);
tid_xfer = 0;
/* ### FIXME ### */
/* 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()) );
#endif
serverGui = new Launcher;
serverGui->createGUI();
docList = new DocumentList( serverGui );
appLauncher = new AppLauncher(this);
connect(appLauncher, SIGNAL(launched(int,const QString&)), this, SLOT(applicationLaunched(int,const QString&)) );
connect(appLauncher, SIGNAL(terminated(int,const QString&)), this, SLOT(applicationTerminated(int,const QString&)) );
connect(appLauncher, SIGNAL(connected(const QString&)), this, SLOT(applicationConnected(const QString&)) );
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 );
packageHandler = new PackageHandler( this );
connect(qApp, SIGNAL(activate(const Opie::Core::ODeviceButton*,bool)),
this,SLOT(activate(const Opie::Core::ODeviceButton*,bool)));
setGeometry( -10, -10, 9, 9 );
QCopChannel *channel = new QCopChannel("QPE/System", this);
connect(channel, SIGNAL(received(const QCString&,const QByteArray&)),
this, SLOT(systemMsg(const QCString&,const QByteArray&)) );
QCopChannel *tbChannel = new QCopChannel( "QPE/TaskBar", this );
connect( tbChannel, SIGNAL(received(const QCString&,const QByteArray&)),
this, SLOT(receiveTaskBar(const QCString&,const QByteArray&)) );
connect( qApp, SIGNAL(prepareForRestart()), this, SLOT(terminateServers()) );
connect( qApp, SIGNAL(timeChanged()), this, SLOT(pokeTimeMonitors()) );
preloadApps();
}
void Server::show()
{
ServerApplication::login(TRUE);
QWidget::show();
}
Server::~Server()
{
serverGui->destroyGUI();
delete docList;
delete qcopBridge;
delete transferServer;
delete serverGui;
#if 0
delete tsmMonitor;
#endif
}
+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
OQCopMessage om;
if ( held ) {
om = button->heldAction();
} else {
om = button->pressedAction();
}
if ( om.channel() != "ignore" )
om.send();
// A button with no action defined, will return a null ServiceRequest. Don't attempt
// to send/do anything with this as it will crash
/* ### FIXME */
#if 0
if ( !sr.isNull() ) {
QString app = sr.app();
bool vis = hasVisibleWindow(app, app != "qpe");
if ( sr.message() == "raise()" && vis ) {
sr.setMessage("nextView()");
} else {
// "back door"
sr << (int)vis;
}
sr.send();
}
#endif
}
#ifdef Q_WS_QWS
typedef struct KeyOverride {
ushort scan_code;
QWSServer::KeyMap map;
};
static const KeyOverride jp109keys[] = {
{ 0x03, { Qt::Key_2, '2' , 0x22 , 0xffff } },
{ 0x07, { Qt::Key_6, '6' , '&' , 0xffff } },
{ 0x08, { Qt::Key_7, '7' , '\'' , 0xffff } },
{ 0x09, { Qt::Key_8, '8' , '(' , 0xffff } },
{ 0x0a, { Qt::Key_9, '9' , ')' , 0xffff } },
{ 0x0b, { Qt::Key_0, '0' , 0xffff, 0xffff } },
{ 0x0c, { Qt::Key_Minus, '-' , '=' , 0xffff } },
{ 0x0d, { Qt::Key_AsciiCircum, '^' , '~' , '^'-64 } },
{ 0x1a, { Qt::Key_At, '@' , '`' , 0xffff } },
{ 0x1b, { Qt::Key_BraceLeft, '[' , '{' , '['-64 } },
{ 0x27, { Qt::Key_Semicolon, ';' , '+' , 0xffff } },
{ 0x28, { Qt::Key_Colon, ':' , '*' , 0xffff } },
{ 0x29, { Qt::Key_Zenkaku_Hankaku, 0xffff, 0xffff, 0xffff } },
{ 0x2b, { Qt::Key_BraceRight, ']' , '}' , ']'-64 } },
{ 0x70, { Qt::Key_Hiragana_Katakana, 0xffff, 0xffff, 0xffff } },
{ 0x73, { Qt::Key_Backslash, '\\' , '_' , 0xffff } },
{ 0x79, { Qt::Key_Henkan, 0xffff, 0xffff, 0xffff } },
{ 0x7b, { Qt::Key_Muhenkan, 0xffff, 0xffff, 0xffff } },
{ 0x7d, { Qt::Key_yen, 0x00a5, '|' , 0xffff } },
{ 0x00, { 0, 0xffff, 0xffff, 0xffff } }
};
bool Server::setKeyboardLayout( const QString &kb )
{
//quick demo version that can be extended
QIntDict<QWSServer::KeyMap> *om = 0;
if ( kb == "us101" ) { // No tr
om = 0;
} else if ( kb == "jp109" ) {
om = new QIntDict<QWSServer::KeyMap>(37);
const KeyOverride *k = jp109keys;
while ( k->scan_code ) {
om->insert( k->scan_code, &k->map );
k++;
}
}
QWSServer::setOverrideKeys( om );
return TRUE;
}
#endif
void Server::systemMsg(const QCString &msg, const QByteArray &data)
{
QDataStream stream( data, IO_ReadOnly );
if ( msg == "securityChanged()" ) {
if ( transferServer )
transferServer->authorizeConnections();
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 ) ) {
QFile f( baseFile );
f.open( IO_WriteOnly );
f.close();
}
QRsync::applyDiff( baseFile, deltaFile );
#ifndef QT_NO_COP
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)" );
e << home;
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
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;
#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" );
cfg.setGroup("SyncDate");
#ifndef QT_NO_COP
QCopEnvelope e( "QPE/Desktop", "syncDate(QString,QString)" );
e << app << cfg.readEntry( app );
#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 );
Config cfg( "qpe" );
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" );
cfg.setGroup( "AutoStart" );
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" );
cfg.setGroup( "AutoStart" );
if ( modifier.compare("add") == 0 ){
// only add if appname is entered
if (!appName.isEmpty()) {
cfg.writeEntry("Apps", appName);
}
} else if (modifier.compare("remove") == 0 ) {
// need to change for multiple entries
// actually remove is right now simular to clear, but in future there
// should be multiple apps in autostart possible.
QString checkName;
checkName = cfg.readEntry("Apps", "");
if (checkName == appName) {
cfg.writeEntry("Apps", "");
}
}
// 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" );
cfg.setGroup( "AutoStart" );
if ( modifier.compare("add") == 0 ){
// only add it appname is entered
if (!appName.isEmpty()) {
cfg.writeEntry("Apps", appName);
cfg.writeEntry("Delay", delay);
}
}
}
#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;
QValueList <OLed> ll = ODevice::inst ( )-> ledList ( );
if ( ll. count ( )) {
OLed l = ll. contains ( Led_Mail ) ? Led_Mail : ll [0];
bool canblink = ODevice::inst ( )-> ledStateList ( l ). contains ( Led_BlinkSlow );
ODevice::inst ( )-> setLedState ( l, status ? ( canblink ? Led_BlinkSlow : Led_On ) : Led_Off );
}
}
}
void Server::cancelSync()
{
#ifndef QT_NO_COP
QCopEnvelope e( "QPE/Desktop", "cancelSync()" );
#endif
delete syncDialog;
syncDialog = 0;
}
bool Server::mkdir(const QString &localPath)
{
QDir fullDir(localPath);
if (fullDir.exists())
return true;
// at this point the directory doesn't exist
// go through the directory tree and start creating the direcotories
// that don't exist; if we can't create the directories, return false
QString dirSeps = "/";
int dirIndex = localPath.find(dirSeps);
QString checkedPath;
// didn't find any seps; weird, use the cur dir instead
if (dirIndex == -1) {
//odebug << "No seperators found in path " << localPath << "" << oendl;
checkedPath = QDir::currentDirPath();
}
while (checkedPath != localPath) {
// no more seperators found, use the local path
if (dirIndex == -1) {
checkedPath = localPath;
} else {
// the next directory to check
@@ -703,48 +759,221 @@ void Server::pokeTimeMonitors()
for (const char* ch = tms.first(); ch; ch=tms.next()) {
QString t = getenv("TZ");
QCopEnvelope e(ch, "timeChange(QString)");
e << t;
}
#endif
}
void Server::applicationLaunched(int, const QString &app)
{
serverGui->applicationStateChanged( app, ServerInterface::Launching );
}
void Server::applicationTerminated(int pid, const QString &app)
{
serverGui->applicationStateChanged( app, ServerInterface::Terminated );
#if 0
tsmMonitor->applicationTerminated( pid );
#else
Q_UNUSED( pid )
#endif
}
void Server::applicationConnected(const QString &app)
{
serverGui->applicationStateChanged( app, ServerInterface::Running );
}
void Server::storageChanged()
{
system( "opie-update-symlinks" );
serverGui->storageChanged( storage->fileSystems() );
docList->storageChanged();
}
void Server::preloadApps()
{
Config cfg("Launcher");
cfg.setGroup("Preload");
QStringList apps = cfg.readListEntry("Apps",',');
for (QStringList::ConstIterator it=apps.begin(); it!=apps.end(); ++it) {
#ifndef QT_NO_COP
QCopEnvelope e("QPE/Application/"+(*it).local8Bit(), "enablePreload()");
#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
@@ -1,99 +1,111 @@
/**********************************************************************
** 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 DESKTOP_H
#define DESKTOP_H
#include <qwidget.h>
#include <qdatetime.h>
//#include "qcopbridge.h"
class QCopBridge;
class QHostAddress;
class TransferServer;
class PackageHandler;
class ServiceRequest;
class TempScreenSaverMonitor;
class AppLauncher;
class AppLnkSet;
class StorageInfo;
class SyncDialog;
class DocumentList;
class ServerInterface;
+class QueuedRequestRunner;
namespace Opie {
namespace Core {
class ODeviceButton;
}
}
class Server : public QWidget {
Q_OBJECT
public:
Server();
~Server();
static bool mkdir(const QString &path);
void show();
static bool setKeyboardLayout( const QString &kb );
public slots:
void systemMsg(const QCString &, const QByteArray &);
void receiveTaskBar(const QCString &msg, const QByteArray &data);
void terminateServers();
void pokeTimeMonitors();
private slots:
void activate(const Opie::Core::ODeviceButton*,bool);
void syncConnectionClosed( const QHostAddress & );
void applicationLaunched(int pid, const QString &app);
void applicationTerminated(int pid, const QString &app);
void applicationConnected(const QString &app);
void storageChanged();
void cancelSync();
+ void desktopMessage( const QCString &, const QByteArray & );
+ void runDirectAccess();
+ void finishedQueuedRequests();
protected:
void styleChange( QStyle & );
void timerEvent( QTimerEvent *e );
private:
void layout();
void startTransferServer();
void preloadApps();
+ void prepareDirectAccess();
+ void postDirectAccess();
+ QString cardInfoString();
+ QString installLocationsString();
QCopBridge *qcopBridge;
TransferServer *transferServer;
PackageHandler *packageHandler;
QDate last_today_show;
int tid_xfer;
/* ### FIXME two below### */
// int tid_today;
// TempScreenSaverMonitor *tsmMonitor;
StorageInfo *storage;
SyncDialog *syncDialog;
AppLauncher *appLauncher;
DocumentList *docList;
ServerInterface *serverGui;
+
+ int pendingFlushes;
+ bool directAccessRun;
+ QueuedRequestRunner *qrr;
};
#endif // DESKTOP_H
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
@@ -1,84 +1,89 @@
TEMPLATE = app
CONFIG += qt warn_on
DESTDIR = $$(OPIEDIR)/bin
HEADERS += server.h \
+ qrr.h \
serverinterface.h \
launchertab.h \
documentlist.h \
appicons.h \
taskbar.h \
runningappbar.h \
applauncher.h \
stabmon.h \
inputmethods.h \
systray.h \
wait.h \
shutdownimpl.h \
launcher.h \
launcherview.h \
$$(OPIEDIR)/core/apps/calibrate/calibrate.h \
startmenu.h \
transferserver.h \
qcopbridge.h \
packageslave.h \
irserver.h \
firstuse.h \
syncdialog.h \
serverapp.h \
qprocess.h \
screensaver.h \
$$(OPIEDIR)/noncore/settings/mediummount/mediumwidget.h \
mediadlg.h
SOURCES += server.cpp \
+ qrr.cpp \
serverinterface.cpp \
launchertab.cpp \
documentlist.cpp \
appicons.cpp \
taskbar.cpp \
runningappbar.cpp \
applauncher.cpp \
stabmon.cpp \
inputmethods.cpp \
systray.cpp \
wait.cpp \
shutdownimpl.cpp \
launcher.cpp \
launcherview.cpp \
$$(OPIEDIR)/core/apps/calibrate/calibrate.cpp \
transferserver.cpp \
packageslave.cpp \
irserver.cpp \
qcopbridge.cpp \
startmenu.cpp \
main.cpp \
firstuse.cpp \
syncdialog.cpp \
serverapp.cpp \
qprocess.cpp \
qprocess_unix.cpp \
screensaver.cpp \
$$(OPIEDIR)/noncore/settings/mediummount/mediumwidget.cc \
mediadlg.cpp
INCLUDEPATH += $(OPIEDIR)/core/apps/calibrate
DEPENDPATH += $(OPIEDIR)/core/apps/calibrate
INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/rsync
DEPENDPATH += $(OPIEDIR)/rsync
INCLUDEPATH += $(OPIEDIR)/noncore/settings/mediummount
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
}
include ( $(OPIEDIR)/include.pro )
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
@@ -15,201 +15,204 @@
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#include "serverapp.h"
#include "screensaver.h"
/* OPIE */
#include <opie2/odebug.h>
#include <opie2/odevice.h>
#include <opie2/multiauthpassword.h>
#include <qtopia/config.h>
#include <qtopia/power.h>
#ifdef Q_WS_QWS
#include <qtopia/qcopenvelope_qws.h>
#endif
#include <qtopia/global.h>
using namespace Opie::Core;
/* QT */
#ifdef Q_WS_QWS
#include <qgfx_qws.h>
#endif
#include <qmessagebox.h>
#include <qtimer.h>
#include <qpainter.h>
#include <qfile.h>
#include <qpixmapcache.h>
/* STD */
#ifdef Q_OS_WIN32
#include <io.h>
#include <process.h>
#else
#include <unistd.h>
#endif
#include <stdlib.h>
static ServerApplication *serverApp = 0;
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
{
return m_keyCode;
}
QCString QCopKeyRegister::channel() const
{
return m_channel;
}
QCString QCopKeyRegister::message() const
{
return m_message;
}
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;
}
//---------------------------------------------------------------------------
/*
Priority is number of alerts that are needed to pop up
alert.
*/
class DesktopPowerAlerter : public QMessageBox
{
Q_OBJECT
public:
DesktopPowerAlerter( QWidget *parent, const char *name = 0 )
: QMessageBox( tr("Battery Status"), tr("Low Battery"),
QMessageBox::Critical,
QMessageBox::Ok | QMessageBox::Default,
QMessageBox::NoButton, QMessageBox::NoButton,
parent, name, FALSE )
{
currentPriority = INT_MAX;
alertCount = 0;
}
void alert( const QString &text, int priority );
void hideEvent( QHideEvent * );
private:
int currentPriority;
int alertCount;
};
void DesktopPowerAlerter::alert( const QString &text, int priority )
{
alertCount++;
if ( alertCount < priority )
return;
if ( priority > currentPriority )
return;
currentPriority = priority;
setText( text );
show();
}
void DesktopPowerAlerter::hideEvent( QHideEvent *e )
{
QMessageBox::hideEvent( e );
alertCount = 0;
currentPriority = INT_MAX;
}
//---------------------------------------------------------------------------
KeyFilter::KeyFilter(QObject* parent) : QObject(parent), held_tid(0), heldButton(0)
{
/* We don't do this cause it would interfere with ODevice */
#if 0
qwsServer->setKeyboardFilter(this);
#endif
}
void KeyFilter::timerEvent(QTimerEvent* e)
{
if ( e->timerId() == held_tid ) {
killTimer(held_tid);
// button held
if ( heldButton ) {
emit activate(heldButton, TRUE);
heldButton = 0;
}
held_tid = 0;
}
}
void KeyFilter::registerKey( const QCopKeyRegister& key )
{
+odebug << "KeyFilter::registerKey " << key.keyCode() << key.channel() << key.message() << oendl;
m_keys.insert( key.keyCode(), key );
}
void KeyFilter::unregisterKey( const QCopKeyRegister& key )
{
m_keys.remove( key.keyCode() );
}
bool KeyFilter::keyRegistered( int key )
{
/*
* Check if we've a key registered
*/
if ( !m_keys[key].send())
return false;
else
return true;
}
bool KeyFilter::checkButtonAction(bool db, int keycode, int press, int autoRepeat)
{
if ( !loggedin
// Permitted keys
&& keycode != Key_F34 // power
&& keycode != Key_F30 // select
&& keycode != Key_Enter
&& keycode != Key_Return
&& keycode != Key_Space
&& keycode != Key_Left
&& keycode != Key_Right
&& keycode != Key_Up
&& keycode != Key_Down )
return TRUE;
/* check if it was registered */
if (!db ) {
if (keycode != 0 &&press && !autoRepeat && keyRegistered(keycode) )
return true;
} else {
// First check to see if DeviceButtonManager knows something about this button:
const ODeviceButton* button = ODevice::inst()->buttonForKeycode(keycode);
if (button && !autoRepeat) {
if ( held_tid ) {
killTimer(held_tid);
held_tid = 0;
}
if ( button->heldAction().isNull() ) {