Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

server.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #include "server.h"
00022 #include "serverapp.h"
00023 #include "startmenu.h"
00024 #include "launcher.h"
00025 #include "transferserver.h"
00026 #include "qcopbridge.h"
00027 #include "irserver.h"
00028 #include "packageslave.h"
00029 #include "calibrate.h"
00030 #include "qrsync.h"
00031 #include "syncdialog.h"
00032 #include "shutdownimpl.h"
00033 #include "applauncher.h"
00034 #if 0
00035 #include "suspendmonitor.h"
00036 #endif
00037 #include "documentlist.h"
00038 #include "qrr.h"
00039 
00040 /* OPIE */
00041 #include <opie2/odebug.h>
00042 #include <opie2/odevicebutton.h>
00043 #include <opie2/odevice.h>
00044 #include <opie2/oprocess.h>
00045 
00046 #include <qtopia/applnk.h>
00047 #include <qtopia/private/categories.h>
00048 #include <qtopia/mimetype.h>
00049 #include <qtopia/config.h>
00050 #include <qtopia/resource.h>
00051 #include <qtopia/version.h>
00052 #include <qtopia/storage.h>
00053 #include <qtopia/qcopenvelope_qws.h>
00054 #include <qtopia/global.h>
00055 using namespace Opie::Core;
00056 
00057 /* QT */
00058 #include <qmainwindow.h>
00059 #include <qmessagebox.h>
00060 #include <qtimer.h>
00061 #include <qtextstream.h>
00062 #include <qwindowsystem_qws.h>
00063 #include <qgfx_qws.h>
00064 
00065 /* STD */
00066 #include <unistd.h>
00067 #include <stdlib.h>
00068 
00069 extern QRect qt_maxWindowRect;
00070 
00071 static QWidget *calibrate(bool)
00072 {
00073 #ifdef Q_WS_QWS
00074     Calibrate *c = new Calibrate;
00075     c->show();
00076     return c;
00077 #else
00078     return 0;
00079 #endif
00080 }
00081 
00082 #define FACTORY(T) \
00083     static QWidget *new##T( bool maximized ) { \
00084     QWidget *w = new T( 0, 0, QWidget::WDestructiveClose | QWidget::WGroupLeader ); \
00085     if ( maximized ) { \
00086         if ( qApp->desktop()->width() <= 350 ) { \
00087         w->showMaximized(); \
00088         } else { \
00089         w->resize( QSize( 300, 300 ) ); \
00090         } \
00091     } \
00092     w->show(); \
00093     return w; \
00094     }
00095 
00096 
00097 #ifdef SINGLE_APP
00098 #define APP(a,b,c,d) FACTORY(b)
00099 #include "apps.h"
00100 #undef APP
00101 #endif // SINGLE_APP
00102 
00103 static Global::Command builtins[] = {
00104 
00105 #ifdef SINGLE_APP
00106 #define APP(a,b,c,d) { a, new##b, c, d },
00107 #include "apps.h"
00108 #undef APP
00109 #endif
00110 
00111     /* FIXME defines need to be defined*/
00112 #if !defined(OPIE_NO_BUILTIN_CALIBRATE)
00113         { "calibrate",          calibrate,          1, 0 }, // No tr
00114 #endif
00115 #if !defined(OPIE_NO_BUILTIN_SHUTDOWN)
00116     { "shutdown",           Global::shutdown,       1, 0 }, // No tr
00117 //  { "run",                run,            1, 0 }, // No tr
00118 #endif
00119 
00120     { 0,            calibrate,  0, 0 },
00121 };
00122 
00123 #ifdef QPE_HAVE_DIRECT_ACCESS
00124 extern void readyDirectAccess(QString cardInfo, QString installLocations);
00125 extern const char *directAccessQueueFile();
00126 #endif
00127 
00128 //---------------------------------------------------------------------------
00129 
00130 
00131 //===========================================================================
00132 
00133 Server::Server() :
00134     QWidget( 0, 0, WStyle_Tool | WStyle_Customize ),
00135     qcopBridge( 0 ),
00136     transferServer( 0 ),
00137     packageHandler( 0 ),
00138     syncDialog( 0 ),
00139     process( 0 )
00140 {
00141     Global::setBuiltinCommands(builtins);
00142 
00143     tid_xfer = 0;
00144     /* ### FIXME ### */
00145 /*    tid_today = startTimer(3600*2*1000);*/
00146     last_today_show = QDate::currentDate();
00147 
00148 #warning FIXME support TempScreenSaverMode
00149 #if 0
00150     tsmMonitor = new TempScreenSaverMode();
00151     connect( tsmMonitor, SIGNAL(forceSuspend()), qApp, SIGNAL(power()) );
00152 #endif
00153 
00154     serverGui = new Launcher;
00155     serverGui->createGUI();
00156 
00157     docList = new DocumentList( serverGui );
00158     appLauncher = new AppLauncher(this);
00159     connect(appLauncher, SIGNAL(launched(int,const QString&)), this, SLOT(applicationLaunched(int,const QString&)) );
00160     connect(appLauncher, SIGNAL(terminated(int,const QString&)), this, SLOT(applicationTerminated(int,const QString&)) );
00161     connect(appLauncher, SIGNAL(connected(const QString&)), this, SLOT(applicationConnected(const QString&)) );
00162 
00163     storage = new StorageInfo( this );
00164     connect( storage, SIGNAL(disksChanged()), this, SLOT(storageChanged()) );
00165 
00166 
00167 #ifdef QPE_HAVE_DIRECT_ACCESS
00168     QCopChannel *desktopChannel = new QCopChannel( "QPE/Desktop", this );
00169     connect( desktopChannel, SIGNAL(received( const QCString &, const QByteArray & )),
00170          this, SLOT(desktopMessage( const QCString &, const QByteArray & )) );
00171 #endif
00172 
00173     soundServerExited();
00174 
00175     // start services
00176     startTransferServer();
00177     (void) new IrServer( this );
00178 
00179     packageHandler = new PackageHandler( this );
00180     connect(qApp, SIGNAL(activate(const Opie::Core::ODeviceButton*,bool)),
00181             this,SLOT(activate(const Opie::Core::ODeviceButton*,bool)));
00182 
00183     setGeometry( -10, -10, 9, 9 );
00184 
00185     QCopChannel *channel = new QCopChannel("QPE/System", this);
00186     connect(channel, SIGNAL(received(const QCString&,const QByteArray&)),
00187         this, SLOT(systemMsg(const QCString&,const QByteArray&)) );
00188 
00189     QCopChannel *tbChannel = new QCopChannel( "QPE/TaskBar", this );
00190     connect( tbChannel, SIGNAL(received(const QCString&,const QByteArray&)),
00191         this, SLOT(receiveTaskBar(const QCString&,const QByteArray&)) );
00192 
00193     connect( qApp, SIGNAL(prepareForRestart()), this, SLOT(terminateServers()) );
00194     connect( qApp, SIGNAL(timeChanged()), this, SLOT(pokeTimeMonitors()) );
00195 
00196     preloadApps();
00197 }
00198 
00199 void Server::show()
00200 {
00201     ServerApplication::login(TRUE);
00202     QWidget::show();
00203 }
00204 
00205 Server::~Server()
00206 {
00207     serverGui->destroyGUI();
00208     delete docList;
00209     delete qcopBridge;
00210     delete transferServer;
00211     delete serverGui;
00212 #if 0
00213     delete tsmMonitor;
00214 #endif
00215 }
00216 
00217 
00218 static bool hasVisibleWindow(const QString& clientname, bool partial)
00219 {
00220 #ifdef QWS
00221     const QList<QWSWindow> &list = qwsServer->clientWindows();
00222     QWSWindow* w;
00223     for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) {
00224     if ( w->client()->identity() == clientname ) {
00225         if ( partial && !w->isFullyObscured() )
00226         return TRUE;
00227         if ( !partial && !w->isFullyObscured() && !w->isPartiallyObscured() ) {
00228 # if QT_VERSION < 0x030000
00229         QRect mwr = qt_screen->mapToDevice(qt_maxWindowRect,
00230             QSize(qt_screen->width(),qt_screen->height()) );
00231 # else
00232         QRect mwr = qt_maxWindowRect;
00233 # endif
00234         if ( mwr.contains(w->requested().boundingRect()) )
00235             return TRUE;
00236         }
00237     }
00238     }
00239 #endif
00240     return FALSE;
00241 }
00242 
00243 void Server::activate(const ODeviceButton* button, bool held)
00244 {
00245     Global::terminateBuiltin("calibrate"); // No tr
00246     OQCopMessage om;
00247     if ( held ) {
00248     om = button->heldAction();
00249     } else {
00250     om = button->pressedAction();
00251     }
00252 
00253     if ( om.channel() != "ignore" )
00254         om.send();
00255 
00256     // A button with no action defined, will return a null ServiceRequest.  Don't attempt
00257     // to send/do anything with this as it will crash
00258     /* ### FIXME */
00259 #if 0
00260     if ( !sr.isNull() ) {
00261     QString app = sr.app();
00262     bool vis = hasVisibleWindow(app, app != "qpe");
00263     if ( sr.message() == "raise()" && vis ) {
00264         sr.setMessage("nextView()");
00265     } else {
00266         // "back door"
00267         sr << (int)vis;
00268     }
00269 
00270     sr.send();
00271     }
00272 #endif
00273 }
00274 
00275 
00276 #ifdef Q_WS_QWS
00277 
00278 typedef struct KeyOverride {
00279     ushort scan_code;
00280     QWSServer::KeyMap map;
00281 };
00282 
00283 
00284 static const KeyOverride jp109keys[] = {
00285    { 0x03, { Qt::Key_2,                 '2'   , 0x22  , 0xffff  } },
00286    { 0x07, { Qt::Key_6,                 '6'   , '&'   , 0xffff  } },
00287    { 0x08, { Qt::Key_7,                 '7'   , '\''  , 0xffff  } },
00288    { 0x09, { Qt::Key_8,                 '8'   , '('   , 0xffff  } },
00289    { 0x0a, { Qt::Key_9,                 '9'   , ')'   , 0xffff  } },
00290    { 0x0b, { Qt::Key_0,                 '0'   , 0xffff, 0xffff  } },
00291    { 0x0c, { Qt::Key_Minus,             '-'   , '='   , 0xffff  } },
00292    { 0x0d, { Qt::Key_AsciiCircum,       '^'   , '~'   , '^'-64  } },
00293    { 0x1a, { Qt::Key_At,                '@'   , '`'   , 0xffff  } },
00294    { 0x1b, { Qt::Key_BraceLeft,         '['   , '{'   , '['-64  } },
00295    { 0x27, { Qt::Key_Semicolon,         ';'   , '+'   , 0xffff  } },
00296    { 0x28, { Qt::Key_Colon,             ':'   , '*'   , 0xffff  } },
00297    { 0x29, { Qt::Key_Zenkaku_Hankaku,   0xffff, 0xffff, 0xffff  } },
00298    { 0x2b, { Qt::Key_BraceRight,        ']'   , '}'   , ']'-64  } },
00299    { 0x70, { Qt::Key_Hiragana_Katakana, 0xffff, 0xffff, 0xffff  } },
00300    { 0x73, { Qt::Key_Backslash,         '\\'  , '_'   , 0xffff  } },
00301    { 0x79, { Qt::Key_Henkan,            0xffff, 0xffff, 0xffff  } },
00302    { 0x7b, { Qt::Key_Muhenkan,          0xffff, 0xffff, 0xffff  } },
00303    { 0x7d, { Qt::Key_yen,               0x00a5, '|'   , 0xffff  } },
00304    { 0x00, { 0,                         0xffff, 0xffff, 0xffff  } }
00305 };
00306 
00307 bool Server::setKeyboardLayout( const QString &kb )
00308 {
00309     //quick demo version that can be extended
00310 
00311     QIntDict<QWSServer::KeyMap> *om = 0;
00312     if ( kb == "us101" ) { // No tr
00313     om = 0;
00314     } else if ( kb == "jp109" ) {
00315     om = new QIntDict<QWSServer::KeyMap>(37);
00316     const KeyOverride *k = jp109keys;
00317     while ( k->scan_code ) {
00318         om->insert( k->scan_code, &k->map );
00319         k++;
00320     }
00321     }
00322     QWSServer::setOverrideKeys( om );
00323 
00324     return TRUE;
00325 }
00326 #endif
00327 
00328 void Server::systemMsg(const QCString &msg, const QByteArray &data)
00329 {
00330     QDataStream stream( data, IO_ReadOnly );
00331 
00332     if ( msg == "securityChanged()" ) {
00333     if ( transferServer )
00334        transferServer->authorizeConnections();
00335 
00336     if ( qcopBridge )
00337         qcopBridge->authorizeConnections();
00338 #warning FIXME support TempScreenSaverMode
00339 #if 0
00340     } else if ( msg == "setTempScreenSaverMode(int,int)" ) {
00341         int mode, pid;
00342         stream >> mode >> pid;
00343         tsmMonitor->setTempMode(mode, pid);
00344 #endif
00345     } else if ( msg == "linkChanged(QString)" ) {
00346         QString link;
00347         stream >> link;
00348         odebug << "desktop.cpp systemMsg -> linkchanged( " << link << " )" << oendl;
00349         docList->linkChanged(link);
00350     } else if (msg =="reforceDocuments()") {
00351         docList->reforceDocuments();
00352     } else if ( msg == "serviceChanged(QString)" ) {
00353         MimeType::updateApplications();
00354     } else if ( msg == "mkdir(QString)" ) {
00355         QString dir;
00356         stream >> dir;
00357         if ( !dir.isEmpty() )
00358             mkdir( dir );
00359     } else if ( msg == "rdiffGenSig(QString,QString)" ) {
00360         QString baseFile, sigFile;
00361         stream >> baseFile >> sigFile;
00362         QRsync::generateSignature( baseFile, sigFile );
00363     } else if ( msg == "rdiffGenDiff(QString,QString,QString)" ) {
00364         QString baseFile, sigFile, deltaFile;
00365         stream >> baseFile >> sigFile >> deltaFile;
00366         QRsync::generateDiff( baseFile, sigFile, deltaFile );
00367     } else if ( msg == "rdiffApplyPatch(QString,QString)" ) {
00368         QString baseFile, deltaFile;
00369         stream >> baseFile >> deltaFile;
00370         if ( !QFile::exists( baseFile ) ) {
00371             QFile f( baseFile );
00372             f.open( IO_WriteOnly );
00373             f.close();
00374         }
00375         QRsync::applyDiff( baseFile, deltaFile );
00376 #ifndef QT_NO_COP
00377         QCopEnvelope e( "QPE/Desktop", "patchApplied(QString)" );
00378         e << baseFile;
00379 #endif
00380     } else if ( msg == "rdiffCleanup()" ) {
00381         mkdir( "/tmp/rdiff" );
00382         QDir dir;
00383         dir.setPath( "/tmp/rdiff" );
00384         QStringList entries = dir.entryList();
00385         for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it )
00386             dir.remove( *it );
00387     } else if ( msg == "sendHandshakeInfo()" ) {
00388         QString home = getenv( "HOME" );
00389 #ifndef QT_NO_COP
00390         QCopEnvelope e( "QPE/Desktop", "handshakeInfo(QString,bool)" );
00391         e << home;
00392         int locked = (int) ServerApplication::screenLocked();
00393         e << locked;
00394 #endif
00395     } else  if ( msg == "sendVersionInfo()" ) {
00396     /*
00397      * @&$*! Qtopiadesktop relies on the major number
00398      * to start with 1. (or 2 as the case of version 2.1 will be)
00399      * we need to fake 1.7 to be able
00400      * to sync with Qtopiadesktop 1.7.
00401      * We'll send it Opie's version in the platform string for now,
00402      * until such time when QD gets rewritten correctly.
00403      */
00404         QCopEnvelope e( "QPE/Desktop", "versionInfo(QString,QString)" );
00405 
00406         QString opiename = "Opie "+QString(QPE_VERSION);
00407         QString QDVersion="1.7";
00408         e << QDVersion << opiename;
00409 
00410     } else if ( msg == "sendCardInfo()" ) {
00411 #ifndef QT_NO_COP
00412         QCopEnvelope e( "QPE/Desktop", "cardInfo(QString)" );
00413 #endif
00414         storage->update();
00415         const QList<FileSystem> &fs = storage->fileSystems();
00416         QListIterator<FileSystem> it ( fs );
00417         QString s;
00418         QString homeDir = getenv("HOME");
00419         QString homeFs, homeFsPath;
00420         for ( ; it.current(); ++it ) {
00421             int k4 = (*it)->blockSize()/256;
00422             if ( (*it)->isRemovable() ) {
00423             s += (*it)->name() + "=" + (*it)->path() + "/Documents " // No tr
00424                  + QString::number( (*it)->availBlocks() * k4/4 )
00425                  + "K " + (*it)->options() + ";";
00426             } else if ( homeDir.contains( (*it)->path() ) &&
00427                   (*it)->path().length() > homeFsPath.length() ) {
00428             homeFsPath = (*it)->path();
00429             homeFs =
00430                 (*it)->name() + "=" + homeDir + "/Documents " // No tr
00431                 + QString::number( (*it)->availBlocks() * k4/4 )
00432                 + "K " + (*it)->options() + ";";
00433             }
00434         }
00435         if ( !homeFs.isEmpty() )
00436             s += homeFs;
00437 #ifndef QT_NO_COP
00438         e << s;
00439 #endif
00440     } else if ( msg == "sendInstallLocations()" ) {
00441 #ifndef QT_NO_COP
00442     QCopEnvelope e( "QPE/Desktop", "installLocations(QString)" );
00443     e << installLocationsString();
00444 #endif
00445     } else if ( msg == "sendSyncDate(QString)" ) {
00446         QString app;
00447         stream >> app;
00448         Config cfg( "qpe" );
00449         cfg.setGroup("SyncDate");
00450 #ifndef QT_NO_COP
00451         QCopEnvelope e( "QPE/Desktop", "syncDate(QString,QString)" );
00452         e  << app  << cfg.readEntry( app );
00453 #endif
00454         //odebug << "QPE/System sendSyncDate for " << app.latin1() << ": response "
00455         //       << cfg.readEntry( app ).latin1() << oendl;
00456     } else if ( msg == "setSyncDate(QString,QString)" ) {
00457         QString app, date;
00458         stream >> app >> date;
00459         Config cfg( "qpe" );
00460         cfg.setGroup("SyncDate");
00461         cfg.writeEntry( app, date );
00462         //odebug << "setSyncDate(QString,QString) " << app << " " << date << "" << oendl;
00463     } else if ( msg == "startSync(QString)" ) {
00464         QString what;
00465         stream >> what;
00466         delete syncDialog;
00467         syncDialog = new SyncDialog( this, what );
00468         syncDialog->show();
00469         connect( syncDialog, SIGNAL(cancel()), SLOT(cancelSync()) );
00470     } else if ( msg == "stopSync()") {
00471         delete syncDialog;
00472         syncDialog = 0;
00473     } else if (msg == "restoreDone(QString)") {
00474         docList->restoreDone();
00475     } else if ( msg == "getAllDocLinks()" ) {
00476         docList->sendAllDocLinks();
00477     }
00478 #ifdef QPE_HAVE_DIRECT_ACCESS
00479     else if ( msg == "prepareDirectAccess()" ) {
00480     prepareDirectAccess();
00481     } else if ( msg == "postDirectAccess()" ) {
00482     postDirectAccess();
00483     }
00484 #endif
00485 #ifdef Q_WS_QWS
00486 
00487  else if ( msg == "setMouseProto(QString)" ) {
00488         QString mice;
00489         stream >> mice;
00490         setenv("QWS_MOUSE_PROTO",mice.latin1(),1);
00491         qwsServer->openMouse();
00492     } else if ( msg == "setKeyboard(QString)" ) {
00493         QString kb;
00494         stream >> kb;
00495         setenv("QWS_KEYBOARD",kb.latin1(),1);
00496         qwsServer->openKeyboard();
00497     } else if ( msg == "setKeyboardAutoRepeat(int,int)" ) {
00498         int delay, period;
00499         stream >> delay >> period;
00500         qwsSetKeyboardAutoRepeat( delay, period );
00501         Config cfg( "qpe" );
00502         cfg.setGroup("Keyboard");
00503         cfg.writeEntry( "RepeatDelay", delay );
00504         cfg.writeEntry( "RepeatPeriod", period );
00505     } else if ( msg == "setKeyboardLayout(QString)" ) {
00506         QString kb;
00507         stream >> kb;
00508         setKeyboardLayout( kb );
00509         Config cfg( "qpe" );
00510         cfg.setGroup("Keyboard");
00511         cfg.writeEntry( "Layout", kb );
00512     } else if ( msg == "autoStart(QString)" ) {
00513         QString appName;
00514         stream >> appName;
00515         Config cfg( "autostart" );
00516         cfg.setGroup( "AutoStart" );
00517         if ( appName.compare("clear") == 0){
00518             cfg.writeEntry("Apps", "");
00519         }
00520     } else if ( msg == "autoStart(QString,QString)" ) {
00521         QString modifier, appName;
00522         stream >> modifier >> appName;
00523         Config cfg( "autostart" );
00524         cfg.setGroup( "AutoStart" );
00525         if ( modifier.compare("add") == 0 ){
00526             // only add if appname is entered
00527            if (!appName.isEmpty()) {
00528                 cfg.writeEntry("Apps", appName);
00529             }
00530         } else if (modifier.compare("remove") == 0 ) {
00531             // need to change for multiple entries
00532             // actually remove is right now simular to clear, but in future there
00533             // should be multiple apps in autostart possible.
00534             QString checkName;
00535             checkName = cfg.readEntry("Apps", "");
00536             if (checkName == appName) {
00537                 cfg.writeEntry("Apps", "");
00538             }
00539         }
00540         // case the autostart feature should be delayed
00541     } else if ( msg == "autoStart(QString,QString,QString)") {
00542         QString modifier, appName, delay;
00543         stream >> modifier >> appName >> delay;
00544         Config cfg( "autostart" );
00545 
00546         cfg.setGroup( "AutoStart" );
00547         if ( modifier.compare("add") == 0 ){
00548             // only add it appname is entered
00549             if (!appName.isEmpty()) {
00550                 cfg.writeEntry("Apps", appName);
00551                 cfg.writeEntry("Delay", delay);
00552             }
00553         }
00554     }
00555 #endif
00556 }
00557 
00558 QString Server::cardInfoString()
00559 {
00560     storage->update();
00561     const QList<FileSystem> &fs = storage->fileSystems();
00562     QListIterator<FileSystem> it ( fs );
00563     QString s;
00564     QString homeDir = getenv("HOME");
00565     QString homeFs, homeFsPath;
00566     for ( ; it.current(); ++it ) {
00567     int k4 = (*it)->blockSize()/256;
00568     if ( (*it)->isRemovable() ) {
00569         s += (*it)->name() + "=" + (*it)->path() + "/Documents " // No tr
00570          + QString::number( (*it)->availBlocks() * k4/4 )
00571          + "K " + (*it)->options() + ";";
00572     } else if ( homeDir.contains( (*it)->path() ) &&
00573           (*it)->path().length() > homeFsPath.length() ) {
00574         homeFsPath = (*it)->path();
00575         homeFs =
00576         (*it)->name() + "=" + homeDir + "/Documents " // No tr
00577         + QString::number( (*it)->availBlocks() * k4/4 )
00578         + "K " + (*it)->options() + ";";
00579     }
00580     }
00581     if ( !homeFs.isEmpty() )
00582     s += homeFs;
00583     return s;
00584 }
00585 
00586 QString Server::installLocationsString()
00587 {
00588     storage->update();
00589     const QList<FileSystem> &fs = storage->fileSystems();
00590     QListIterator<FileSystem> it ( fs );
00591     QString s;
00592     QString homeDir = getenv("HOME");
00593     QString homeFs, homeFsPath;
00594     for ( ; it.current(); ++it ) {
00595     int k4 = (*it)->blockSize()/256;
00596     if ( (*it)->isRemovable() ) {
00597         s += (*it)->name() + "=" + (*it)->path() + " " // No tr
00598          + QString::number( (*it)->availBlocks() * k4/4 )
00599          + "K " + (*it)->options() + ";";
00600     } else if ( homeDir.contains( (*it)->path() ) &&
00601             (*it)->path().length() > homeFsPath.length() ) {
00602         homeFsPath = (*it)->path();
00603         homeFs =
00604         (*it)->name() + "=" + homeDir + " " // No tr
00605         + QString::number( (*it)->availBlocks() * k4/4 )
00606         + "K " + (*it)->options() + ";";
00607     }
00608     }
00609     if ( !homeFs.isEmpty() )
00610     s = homeFs + s;
00611     return s;
00612 }
00613 
00614 void Server::receiveTaskBar(const QCString &msg, const QByteArray &data)
00615 {
00616     QDataStream stream( data, IO_ReadOnly );
00617 
00618     if ( msg == "reloadApps()" ) {
00619       docList->reloadAppLnks();
00620     } else if ( msg == "soundAlarm()" ) {
00621       ServerApplication::soundAlarm();
00622     } else if ( msg == "setLed(int,bool)" ) {
00623         int led, status;
00624         stream >> led >> status;
00625 
00626         QValueList <OLed> ll = ODevice::inst ( )-> ledList ( );
00627         if ( ll. count ( )) {
00628             OLed l = ll. contains ( Led_Mail ) ? Led_Mail : ll [0];
00629             bool canblink = ODevice::inst ( )-> ledStateList ( l ). contains ( Led_BlinkSlow );
00630 
00631             ODevice::inst ( )-> setLedState ( l, status ? ( canblink ? Led_BlinkSlow : Led_On ) : Led_Off );
00632         }
00633     }
00634 }
00635 
00636 void Server::cancelSync()
00637 {
00638 #ifndef QT_NO_COP
00639     QCopEnvelope e( "QPE/Desktop", "cancelSync()" );
00640 #endif
00641     delete syncDialog;
00642     syncDialog = 0;
00643 }
00644 
00645 bool Server::mkdir(const QString &localPath)
00646 {
00647     QDir fullDir(localPath);
00648     if (fullDir.exists())
00649     return true;
00650 
00651     // at this point the directory doesn't exist
00652     // go through the directory tree and start creating the direcotories
00653     // that don't exist; if we can't create the directories, return false
00654 
00655     QString dirSeps = "/";
00656     int dirIndex = localPath.find(dirSeps);
00657     QString checkedPath;
00658 
00659     // didn't find any seps; weird, use the cur dir instead
00660     if (dirIndex == -1) {
00661         //odebug << "No seperators found in path " << localPath << "" << oendl;
00662         checkedPath = QDir::currentDirPath();
00663     }
00664 
00665     while (checkedPath != localPath) {
00666     // no more seperators found, use the local path
00667     if (dirIndex == -1) {
00668         checkedPath = localPath;
00669     } else {
00670         // the next directory to check
00671         checkedPath = localPath.left(dirIndex) + "/";
00672         // advance the iterator; the next dir seperator
00673         dirIndex = localPath.find(dirSeps, dirIndex+1);
00674     }
00675 
00676     QDir checkDir(checkedPath);
00677     if (!checkDir.exists()) {
00678         //odebug << "mkdir making dir " << checkedPath << "" << oendl;
00679 
00680         if (!checkDir.mkdir(checkedPath)) {
00681         odebug << "Unable to make directory " << checkedPath << "" << oendl;
00682         return FALSE;
00683         }
00684     }
00685 
00686     }
00687     return TRUE;
00688 }
00689 
00690 void Server::styleChange( QStyle &s )
00691 {
00692     QWidget::styleChange( s );
00693 }
00694 
00695 void Server::startTransferServer()
00696 {
00697     if ( !qcopBridge ) {
00698        // start qcop bridge server
00699        qcopBridge = new QCopBridge( 4243 );
00700        if ( qcopBridge->ok() ) {
00701            // ... OK
00702            connect( qcopBridge, SIGNAL(connectionClosed(const QHostAddress&)),
00703                this, SLOT(syncConnectionClosed(const QHostAddress&)) );
00704        } else {
00705            delete qcopBridge;
00706            qcopBridge = 0;
00707        }
00708     }
00709 
00710     if ( !transferServer ) {
00711         // start transfer server
00712         transferServer = new TransferServer( 4242 );
00713         if ( transferServer->ok() ) {
00714             // ... OK
00715         } else {
00716             delete transferServer;
00717             transferServer = 0;
00718         }
00719 
00720         if ( !qcopBridge )
00721             tid_xfer = startTimer( 2000 );
00722     }
00723 }
00724 
00725 void Server::timerEvent( QTimerEvent *e )
00726 {
00727     if ( e->timerId() == tid_xfer ) {
00728         killTimer( tid_xfer );
00729         tid_xfer = 0;
00730         startTransferServer();
00731     }
00732 #if 0
00733     /* ### FIXME today startin */
00734     else if ( e->timerId() == tid_today ) {
00735         QDate today = QDate::currentDate();
00736         if ( today != last_today_show ) {
00737             last_today_show = today;
00738             Config cfg("today");
00739             cfg.setGroup("Start");
00740 #ifndef QPE_DEFAULT_TODAY_MODE
00741 #define QPE_DEFAULT_TODAY_MODE "Never"
00742 #endif
00743             if ( cfg.readEntry("Mode",QPE_DEFAULT_TODAY_MODE) == "Daily" ) {
00744             QCopEnvelope env(Service::channel("today"),"raise()");
00745             }
00746         }
00747     }
00748 #endif
00749 }
00750 
00751 void Server::terminateServers()
00752 {
00753     delete transferServer;
00754     delete qcopBridge;
00755     transferServer = 0;
00756     qcopBridge = 0;
00757 }
00758 
00759 void Server::syncConnectionClosed( const QHostAddress & )
00760 {
00761     odebug << "Lost sync connection" << oendl;
00762     delete syncDialog;
00763     syncDialog = 0;
00764 }
00765 
00766 void Server::pokeTimeMonitors()
00767 {
00768 #if 0
00769     // inform all TimeMonitors
00770     QStrList tms = Service::channels("TimeMonitor");
00771     for (const char* ch = tms.first(); ch; ch=tms.next()) {
00772     QString t = getenv("TZ");
00773     QCopEnvelope e(ch, "timeChange(QString)");
00774     e << t;
00775     }
00776 #endif
00777 }
00778 
00779 void Server::applicationLaunched(int, const QString &app)
00780 {
00781     serverGui->applicationStateChanged( app, ServerInterface::Launching );
00782 }
00783 
00784 void Server::applicationTerminated(int pid, const QString &app)
00785 {
00786     serverGui->applicationStateChanged( app, ServerInterface::Terminated );
00787 #if 0
00788     tsmMonitor->applicationTerminated( pid );
00789 #else
00790     Q_UNUSED( pid )
00791 #endif
00792 }
00793 
00794 void Server::applicationConnected(const QString &app)
00795 {
00796     serverGui->applicationStateChanged( app, ServerInterface::Running );
00797 }
00798 
00799 void Server::storageChanged()
00800 {
00801     system( "opie-update-symlinks" );
00802     serverGui->storageChanged( storage->fileSystems() );
00803     docList->storageChanged();
00804 }
00805 
00806 
00807 
00808 void Server::preloadApps()
00809 {
00810     Config cfg("Launcher");
00811     cfg.setGroup("Preload");
00812     QStringList apps = cfg.readListEntry("Apps",',');
00813     for (QStringList::ConstIterator it=apps.begin(); it!=apps.end(); ++it) {
00814 #ifndef QT_NO_COP
00815         QCopEnvelope e("QPE/Application/"+(*it).local8Bit(), "enablePreload()");
00816 #endif
00817     }
00818 }
00819 
00820 // This is only called if QPE_HAVE_DIRECT_ACCESS is defined
00821 void Server::prepareDirectAccess()
00822 {
00823     qDebug( "Server::prepareDirectAccess()" );
00824     // Put up a pretty dialog
00825     syncDialog = new SyncDialog( this, tr("USB Lock") );
00826     syncDialog->show();
00827 
00828     // Prevent the PDA from acting as a PDA
00829     terminateServers();
00830 
00831     // suspend the mtab monitor
00832 #ifndef QT_NO_COP
00833     {
00834     QCopEnvelope e( "QPE/Stabmon", "suspendMonitor()" );
00835     }
00836 #endif
00837 
00838     // send out a flush message
00839     // once flushes are done call runDirectAccess()
00840     // We just count the number of apps and set a timer.
00841     // Either the timer expires or the correct number of apps responds.
00842     // Note: quicklauncher isn't in the runningApps list but it responds
00843     //       to the flush so we start the counter at 1
00844     pendingFlushes = 1;
00845     directAccessRun = FALSE;
00846     for ( QMap<int,QString>::ConstIterator it =
00847         appLauncher->runningApplications().begin();
00848       it != appLauncher->runningApplications().end();
00849       ++it ) {
00850     pendingFlushes++;
00851     }
00852 #ifndef QT_NO_COP
00853     QCopEnvelope e1( "QPE/System", "flush()" );
00854 #endif
00855     QTimer::singleShot( 10000, this, SLOT(runDirectAccess()) );
00856 #warning FIXME support TempScreenSaverMode
00857 #if 0
00858     QPEApplication::setTempScreenSaverMode(QPEApplication::DisableSuspend);
00859 #endif
00860 }
00861 
00862 // This is only connected if QPE_HAVE_DIRECT_ACCESS is defined
00863 // It fakes the presence of Qtopia Desktop
00864 void Server::desktopMessage( const QCString &message, const QByteArray &data )
00865 {
00866     QDataStream stream( data, IO_ReadOnly );
00867     if ( message == "flushDone(QString)" ) {
00868     QString app;
00869     stream >> app;
00870     qDebug( "flushDone from %s", app.latin1() );
00871     if ( --pendingFlushes == 0 ) {
00872         qDebug( "pendingFlushes == 0, all the apps responded" );
00873         runDirectAccess();
00874     }
00875     } else if ( message == "installStarted(QString)" ) {
00876     QString package;
00877     stream >> package;
00878     qDebug( "\tInstall Started for package %s", package.latin1() );
00879     } else if ( message == "installStep(QString)" ) {
00880     QString step;
00881     stream >> step;
00882     qDebug( "\tInstall Step %s", step.latin1() );
00883     } else if ( message == "installDone(QString)" ) {
00884     QString package;
00885     stream >> package;
00886     qDebug( "\tInstall Finished for package %s", package.latin1() );
00887     } else if ( message == "installFailed(QString,int,QString)" ) {
00888     QString package, error;
00889     int status;
00890     stream >> package >> status >> error;
00891     qDebug( "\tInstall Failed for package %s with error code %d and error message %s",
00892         package.latin1(), status, error.latin1() );
00893     } else if ( message == "removeStarted(QString)" ) {
00894     QString package;
00895     stream >> package;
00896     qDebug( "\tRemove Started for package %s", package.latin1() );
00897     } else if ( message == "removeDone(QString)" ) {
00898     QString package;
00899     stream >> package;
00900     qDebug( "\tRemove Finished for package %s", package.latin1() );
00901     } else if ( message == "removeFailed(QString)" ) {
00902     QString package;
00903     stream >> package;
00904     qDebug( "\tRemove Failed for package %s", package.latin1() );
00905     }
00906 
00907     if ( qrr && qrr->waitingForMessages )
00908     qrr->desktopMessage( message, data );
00909 }
00910 
00911 
00912 // This is only connected if QPE_HAVE_DIRECT_ACCESS is defined
00913 void Server::runDirectAccess()
00914 {
00915 #ifdef QPE_HAVE_DIRECT_ACCESS
00916     // The timer must have fired after all the apps responded
00917     // with flushDone(). Just ignore it.
00918     if ( directAccessRun )
00919     return;
00920 
00921     directAccessRun = TRUE;
00922     ::readyDirectAccess(cardInfoString(), installLocationsString());
00923 #endif
00924 }
00925 
00926 // This is only called if QPE_HAVE_DIRECT_ACCESS is defined
00927 void Server::postDirectAccess()
00928 {
00929 #ifdef QPE_HAVE_DIRECT_ACCESS
00930     qDebug( "Server::postDirectAccess()" );
00931 
00932     // Categories may have changed
00933     QCopEnvelope e1( "QPE/System", "categoriesChanged()" );
00934     // Apps need to reload their data
00935     QCopEnvelope e2( "QPE/System", "reload()" );
00936     // Reload DocLinks
00937     docList->storageChanged();
00938     // Restart the PDA server stuff
00939     startTransferServer();
00940 
00941     // restart the mtab monitor
00942 #ifndef QT_NO_COP
00943     {
00944     QCopEnvelope e( "QPE/Stabmon", "restartMonitor()" );
00945     }
00946 #endif
00947 
00948     // Process queued requests
00949     const char *queueFile = ::directAccessQueueFile();
00950     QFile *file = new QFile( queueFile );
00951     if ( !file->exists() ) {
00952     delete file;
00953     // Get rid of the dialog
00954     if ( syncDialog ) {
00955         delete syncDialog;
00956         syncDialog = 0;
00957     }
00958 #warning FIXME support TempScreenSaverMode
00959 #if 0
00960     QPEApplication::setTempScreenSaverMode(QPEApplication::Enable);
00961 #endif
00962     } else {
00963     qrr = new QueuedRequestRunner( file, syncDialog );
00964     connect( qrr, SIGNAL(finished()),
00965          this, SLOT(finishedQueuedRequests()) );
00966     QTimer::singleShot( 100, qrr, SLOT(process()) );
00967     // qrr will remove the sync dialog later
00968     }
00969 #endif
00970 }
00971 
00972 void Server::finishedQueuedRequests()
00973 {
00974     if ( qrr->readyToDelete ) {
00975     delete qrr;
00976     qrr = 0;
00977     // Get rid of the dialog
00978     if ( syncDialog ) {
00979         delete syncDialog;
00980         syncDialog = 0;
00981     }
00982 #warning FIXME support TempScreenSaverMode
00983 #if 0
00984     QPEApplication::setTempScreenSaverMode(QPEApplication::Enable);
00985 #endif
00986     } else {
00987     qrr->readyToDelete = TRUE;
00988     QTimer::singleShot( 0, this, SLOT(finishedQueuedRequests()) );
00989     }
00990 }
00991 
00992 void Server::startSoundServer() {
00993     if ( !process ) {
00994         process = new Opie::Core::OProcess( this );
00995         connect(process, SIGNAL(processExited(Opie::Core::OProcess*)),
00996                 SLOT(soundServerExited()));
00997     }
00998 
00999     process->clearArguments();
01000     *process << QPEApplication::qpeDir() + "bin/qss";
01001     process->start();
01002 }
01003 
01004 void Server::soundServerExited() {
01005     QTimer::singleShot(5000, this, SLOT(startSoundServer()));
01006 }

Generated on Sat Nov 5 16:15:32 2005 for OPIE by  doxygen 1.4.2