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

qpeapplication.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 #define QTOPIA_INTERNAL_LANGLIST
00021 #include <stdlib.h>
00022 #include <unistd.h>
00023 #ifndef Q_OS_MACX
00024 #include <linux/limits.h> // needed for some toolchains (PATH_MAX)
00025 #endif
00026 #include <qfile.h>
00027 #include <qqueue.h>
00028 #ifdef Q_WS_QWS
00029 #ifndef QT_NO_COP
00030 #if QT_VERSION <= 231
00031 #define private public
00032 #define sendLocally processEvent
00033 #include "qcopenvelope_qws.h"
00034 #undef private
00035 #else
00036 #include "qcopenvelope_qws.h"
00037 #endif
00038 #endif
00039 #include <qwindowsystem_qws.h>
00040 #endif
00041 #include <qtextstream.h>
00042 #include <qpalette.h>
00043 #include <qbuffer.h>
00044 #include <qptrdict.h>
00045 #include <qregexp.h>
00046 #include <qdir.h>
00047 #include <qlabel.h>
00048 #include <qdialog.h>
00049 #include <qdragobject.h>
00050 #include <qtextcodec.h>
00051 #include <qevent.h>
00052 #include <qtooltip.h>
00053 #include <qsignal.h>
00054 #include <qmainwindow.h>
00055 #include <qwidgetlist.h>
00056 #include <qpixmapcache.h>
00057 
00058 #if defined(Q_WS_QWS) && !defined(QT_NO_COP)
00059 #define QTOPIA_INTERNAL_INITAPP
00060 #include "qpeapplication.h"
00061 #include "qpestyle.h"
00062 #include "styleinterface.h"
00063 #if QT_VERSION >= 0x030000
00064 #include <qstylefactory.h>
00065 #else
00066 #include <qplatinumstyle.h>
00067 #include <qwindowsstyle.h>
00068 #include <qmotifstyle.h>
00069 #include <qmotifplusstyle.h>
00070 #include "lightstyle.h"
00071 
00072 #include <qpe/qlibrary.h>
00073 #endif
00074 #include "global.h"
00075 #include "resource.h"
00076 #if QT_VERSION <= 230 && defined(QT_NO_CODECS)
00077 #include "qutfcodec.h"
00078 #endif
00079 #include "config.h"
00080 #include "network.h"
00081 #ifdef QWS
00082 #include "fontmanager.h"
00083 #include "fontdatabase.h"
00084 #endif
00085 
00086 #include "alarmserver.h"
00087 #include "applnk.h"
00088 #include "qpemenubar.h"
00089 #include "textcodecinterface.h"
00090 #include "imagecodecinterface.h"
00091 #include <qtopia/qpeglobal.h>
00092 
00093 #include <unistd.h>
00094 #include <sys/file.h>
00095 #include <sys/ioctl.h>
00096 #ifndef QT_NO_SOUND
00097 #include <sys/soundcard.h>
00098 #endif
00099 
00100 #include <backend/rohfeedback.h>
00101 
00102 
00103 static bool useBigPixmaps = 0;
00104 
00105 class HackWidget : public QWidget
00106 {
00107 public:
00108     bool needsOk()
00109     { return (getWState() & WState_Reserved1 ); }
00110 
00111     QRect normalGeometry()
00112     { return topData()->normalGeometry; };
00113 };
00114 
00115 class QPEApplicationData
00116 {
00117 public:
00118     QPEApplicationData ( ) :
00119           presstimer( 0 ), presswidget( 0 ), rightpressed( false ), kbgrabbed( false ),
00120           notbusysent( false ), preloaded( false ), forceshow( false ), nomaximize( false ),
00121           keep_running( true ), qcopQok( false ),
00122           fontFamily( "Vera" ), fontSize( 10 ), smallIconSize( 14 ),
00123           bigIconSize( 32 ), qpe_main_widget( 0 )
00124     {
00125         Config cfg( "qpe" );
00126         cfg.setGroup( "Appearance" );
00127         useBigPixmaps = cfg.readBoolEntry( "useBigPixmaps", false );
00128         fontFamily = cfg.readEntry( "FontFamily", "Vera" );
00129         fontSize = cfg.readNumEntry( "FontSize", 10 );
00130         smallIconSize = cfg.readNumEntry( "SmallIconSize", 14 );
00131         bigIconSize = cfg.readNumEntry( "BigIconSize", 32 );
00132 #ifdef OPIE_WITHROHFEEDBACK
00133         RoH = 0;
00134 #endif
00135     }
00136 
00137     int presstimer;
00138     QWidget* presswidget;
00139     QPoint presspos;
00140 #ifdef OPIE_WITHROHFEEDBACK
00141     Opie::Internal::RoHFeedback *RoH;
00142 #endif
00143 
00144     bool rightpressed : 1;
00145     bool kbgrabbed    : 1;
00146     bool notbusysent  : 1;
00147     bool preloaded    : 1;
00148     bool forceshow    : 1;
00149     bool nomaximize   : 1;
00150     bool keep_running : 1;
00151     bool qcopQok      : 1;
00152 
00153     QCString fontFamily;
00154     int fontSize;
00155     int smallIconSize;
00156     int bigIconSize;
00157 
00158     QString appName;
00159     struct QCopRec
00160     {
00161         QCopRec( const QCString &ch, const QCString &msg,
00162                  const QByteArray &d ) :
00163                 channel( ch ), message( msg ), data( d )
00164         { }
00165 
00166         QCString channel;
00167         QCString message;
00168         QByteArray data;
00169     };
00170     QGuardedPtr<QWidget> qpe_main_widget;
00171         QGuardedPtr<QWidget> lastraised;
00172     QQueue<QCopRec> qcopq;
00173         QString styleName;
00174     QString decorationName;
00175 
00176     void enqueueQCop( const QCString &ch, const QCString &msg,
00177                       const QByteArray &data )
00178     {
00179         qcopq.enqueue( new QCopRec( ch, msg, data ) );
00180     }
00181     void sendQCopQ()
00182     {
00183             if (!qcopQok )
00184                 return;
00185 
00186         QCopRec * r;
00187 
00188            while((r=qcopq.dequeue())) {
00189                // remove from queue before sending...
00190                // event loop can come around again before getting
00191                // back from sendLocally
00192 #ifndef QT_NO_COP
00193                QCopChannel::sendLocally( r->channel, r->message, r->data );
00194 #endif
00195 
00196            delete r;
00197            }
00198     }
00199 
00200     static void show_mx(QWidget* mw, bool nomaximize, QString &strName) {
00201         if ( mw->inherits("QMainWindow") || mw->isA("QMainWindow") )
00202         {
00203             ( (  QMainWindow* ) mw )->setUsesBigPixmaps( useBigPixmaps );
00204         }
00205         QPoint p;
00206         QSize s;
00207         bool max;
00208 
00209         if ( mw->isVisible() ) {
00210             if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
00211                 mw->resize(s);
00212                 mw->move(p);
00213             }
00214             mw->raise();
00215         } else {
00216 
00217             if ( mw->layout() && mw->inherits("QDialog") ) {
00218                 if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
00219                     mw->resize(s);
00220                     mw->move(p);
00221 
00222                     if ( max && !nomaximize ) {
00223                         mw->showMaximized();
00224                     } else {
00225                         mw->show();
00226                     }
00227                 } else {
00228                     QPEApplication::showDialog((QDialog*)mw,nomaximize);
00229                 }
00230             } else {
00231                 if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
00232                     mw->resize(s);
00233                     mw->move(p);
00234                 } else {    //no stored rectangle, make an estimation
00235                     int x = (qApp->desktop()->width()-mw->frameGeometry().width())/2;
00236                     int y = (qApp->desktop()->height()-mw->frameGeometry().height())/2;
00237                     mw->move( QMAX(x,0), QMAX(y,0) );
00238 #ifdef Q_WS_QWS
00239                     if ( !nomaximize )
00240                         mw->showMaximized();
00241 #endif
00242                 }
00243                 if ( max && !nomaximize )
00244                     mw->showMaximized();
00245                 else
00246                     mw->show();
00247             }
00248         }
00249     }
00250 
00251     static bool read_widget_rect(const QString &app, bool &maximized, QPoint &p, QSize &s)
00252     {
00253 #ifndef OPIE_NO_WINDOWED
00254     maximized = TRUE;
00255     // 350 is the trigger in qwsdefaultdecoration for providing a resize button
00256     if ( qApp->desktop()->width() <= 350 )
00257         return FALSE;
00258 
00259     Config cfg( "qpe" );
00260     cfg.setGroup("ApplicationPositions");
00261     QString str = cfg.readEntry( app, QString::null );
00262     QStringList l = QStringList::split(",", str);
00263 
00264     if ( l.count() == 5) {
00265         p.setX( l[0].toInt() );
00266         p.setY( l[1].toInt() );
00267 
00268         s.setWidth( l[2].toInt() );
00269         s.setHeight( l[3].toInt() );
00270 
00271         maximized = l[4].toInt();
00272 
00273         return TRUE;
00274     }
00275 #endif
00276     return FALSE;
00277     }
00278 
00279 
00280         static bool validate_widget_size(const QWidget *w, QPoint &p, QSize &s)
00281     {
00282 #ifndef Q_WS_QWS
00283     QRect qt_maxWindowRect = qApp->desktop()->geometry();
00284 #endif
00285     int maxX = qt_maxWindowRect.width();
00286     int maxY = qt_maxWindowRect.height();
00287     int wWidth = s.width() + ( w->frameGeometry().width() - w->geometry().width() );
00288     int wHeight = s.height() + ( w->frameGeometry().height() - w->geometry().height() );
00289 
00290     // total window size is not allowed to be larger than desktop window size
00291     if ( ( wWidth >= maxX ) && ( wHeight >= maxY ) )
00292         return FALSE;
00293 
00294     if ( wWidth > maxX ) {
00295         s.setWidth( maxX - (w->frameGeometry().width() - w->geometry().width() ) );
00296         wWidth = maxX;
00297     }
00298 
00299     if ( wHeight > maxY ) {
00300         s.setHeight( maxY - (w->frameGeometry().height() - w->geometry().height() ) );
00301         wHeight = maxY;
00302     }
00303 
00304     // any smaller than this and the maximize/close/help buttons will be overlapping
00305     if ( wWidth < 80 || wHeight < 60 )
00306         return FALSE;
00307 
00308     if ( p.x() < 0 )
00309         p.setX(0);
00310     if ( p.y() < 0 )
00311         p.setY(0);
00312 
00313     if ( p.x() + wWidth > maxX )
00314         p.setX( maxX - wWidth );
00315     if ( p.y() + wHeight > maxY )
00316         p.setY( maxY - wHeight );
00317 
00318     return TRUE;
00319     }
00320 
00321     static void store_widget_rect(QWidget *w, QString &app)
00322     {
00323     if( !w )
00324     return;
00325 #ifndef OPIE_NO_WINDOWED
00326     // 350 is the trigger in qwsdefaultdecoration for providing a resize button
00327     if ( qApp->desktop()->width() <= 350 )
00328         return;
00329     // we use these to map the offset of geometry and pos.  ( we can only use normalGeometry to
00330     // get the non-maximized version, so we have to do it the hard way )
00331     int offsetX = w->x() - w->geometry().left();
00332     int offsetY = w->y() - w->geometry().top();
00333 
00334     QRect r;
00335     if ( w->isMaximized() )
00336         r = ( (HackWidget *) w)->normalGeometry();
00337     else
00338         r = w->geometry();
00339 
00340     // Stores the window placement as pos(), size()  (due to the offset mapping)
00341     Config cfg( "qpe" );
00342     cfg.setGroup("ApplicationPositions");
00343     QString s;
00344     s.sprintf("%d,%d,%d,%d,%d", r.left() + offsetX, r.top() + offsetY, r.width(), r.height(), w->isMaximized() );
00345     cfg.writeEntry( app, s );
00346 #endif
00347     }
00348 
00349     static bool setWidgetCaptionFromAppName( QWidget* /*mw*/, const QString& /*appName*/, const QString& /*appsPath*/ )
00350     {
00351         /*
00352         // This works but disable it for now until it is safe to apply
00353         // What is does is scan the .desktop files of all the apps for
00354         // the applnk that has the corresponding argv[0] as this program
00355         // then it uses the name stored in the .desktop file as the caption
00356         // for the main widget. This saves duplicating translations for
00357         // the app name in the program and in the .desktop files.
00358 
00359         AppLnkSet apps( appsPath );
00360 
00361         QList<AppLnk> appsList = apps.children();
00362         for ( QListIterator<AppLnk> it(appsList); it.current(); ++it ) {
00363           if ( (*it)->exec() == appName ) {
00364         mw->setCaption( (*it)->name() );
00365         return TRUE;
00366           }
00367         }
00368         */
00369         return FALSE;
00370     }
00371 
00372 
00373     void show(QWidget* mw, bool nomax)
00374     {
00375         setWidgetCaptionFromAppName( mw, appName, QPEApplication::qpeDir() + "apps" );
00376         nomaximize = nomax;
00377         qpe_main_widget = mw;
00378                 qcopQok = TRUE;
00379 #ifndef QT_NO_COP
00380 
00381         sendQCopQ();
00382 #endif
00383 
00384         if ( preloaded ) {
00385             if (forceshow)
00386                 show_mx(mw, nomax, appName);
00387         }
00388         else if ( keep_running ) {
00389             show_mx(mw, nomax, appName);
00390         }
00391     }
00392 
00393     void loadTextCodecs()
00394     {
00395         QString path = QPEApplication::qpeDir() + "plugins/textcodecs";
00396 #ifdef Q_OS_MACX
00397         QDir dir( path, "lib*.dylib" );
00398 #else
00399         QDir dir( path, "lib*.so" );
00400 #endif
00401         QStringList list;
00402         if ( dir. exists ( ))
00403             list = dir.entryList();
00404         QStringList::Iterator it;
00405         for ( it = list.begin(); it != list.end(); ++it ) {
00406             TextCodecInterface *iface = 0;
00407             QLibrary *lib = new QLibrary( path + "/" + *it );
00408             if ( lib->queryInterface( IID_QtopiaTextCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
00409                 QValueList<int> mibs = iface->mibEnums();
00410                 for (QValueList<int>::ConstIterator i = mibs.begin(); i != mibs.end(); ++i) {
00411                     (void)iface->createForMib(*i);
00412                     // ### it exists now; need to remember if we can delete it
00413                 }
00414             }
00415             else {
00416                 lib->unload();
00417                 delete lib;
00418             }
00419         }
00420     }
00421 
00422     void loadImageCodecs()
00423     {
00424         QString path = QPEApplication::qpeDir() + "plugins/imagecodecs";
00425 #ifdef Q_OS_MACX
00426         QDir dir( path, "lib*.dylib" );
00427 #else
00428         QDir dir( path, "lib*.so" );
00429 #endif
00430         QStringList list;
00431         if ( dir. exists ( ))
00432             list = dir.entryList();
00433         QStringList::Iterator it;
00434         for ( it = list.begin(); it != list.end(); ++it ) {
00435             ImageCodecInterface *iface = 0;
00436             QLibrary *lib = new QLibrary( path + "/" + *it );
00437             if ( lib->queryInterface( IID_QtopiaImageCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
00438                 QStringList formats = iface->keys();
00439                 for (QStringList::ConstIterator i = formats.begin(); i != formats.end(); ++i) {
00440                     (void)iface->installIOHandler(*i);
00441                     // ### it exists now; need to remember if we can delete it
00442                 }
00443             }
00444             else {
00445                 lib->unload();
00446                 delete lib;
00447             }
00448         }
00449     }
00450 
00451 };
00452 
00453 class ResourceMimeFactory : public QMimeSourceFactory
00454 {
00455 public:
00456         ResourceMimeFactory() : resImage( 0 )
00457     {
00458         setFilePath( Global::helpPath() );
00459         setExtensionType( "html", "text/html;charset=UTF-8" );
00460     }
00461         ~ResourceMimeFactory() {
00462             delete resImage;
00463         }
00464 
00465     const QMimeSource* data( const QString& abs_name ) const
00466     {
00467         const QMimeSource * r = QMimeSourceFactory::data( abs_name );
00468         if ( !r ) {
00469             int sl = abs_name.length();
00470             do {
00471                 sl = abs_name.findRev( '/', sl - 1 );
00472                 QString name = sl >= 0 ? abs_name.mid( sl + 1 ) : abs_name;
00473                 int dot = name.findRev( '.' );
00474                 if ( dot >= 0 )
00475                     name = name.left( dot );
00476                 QImage img = Resource::loadImage( name );
00477                 if ( !img.isNull() ) {
00478                                     delete resImage;
00479                                     resImage = new QImageDrag( img );
00480                                     r = resImage;
00481                                 }
00482             }
00483             while ( !r && sl > 0 );
00484         }
00485         return r;
00486     }
00487 private:
00488     mutable QImageDrag *resImage;
00489 };
00490 
00491 static int& hack(int& i)
00492 {
00493 #if QT_VERSION <= 230 && defined(QT_NO_CODECS)
00494     // These should be created, but aren't in Qt 2.3.0
00495     (void)new QUtf8Codec;
00496     (void)new QUtf16Codec;
00497 #endif
00498     return i;
00499 }
00500 
00501 static int muted = 0;
00502 static int micMuted = 0;
00503 
00504 static void setVolume( int t = 0, int percent = -1 )
00505 {
00506     switch ( t ) {
00507         case 0: {
00508                 Config cfg( "qpe" );
00509                 cfg.setGroup( "Volume" );
00510                 if ( percent < 0 )
00511                     percent = cfg.readNumEntry( "VolumePercent", 50 );
00512 #ifndef QT_NO_SOUND
00513                 int fd = 0;
00514 #ifdef QT_QWS_DEVFS
00515                 if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
00516 #else
00517                 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
00518 #endif
00519                     int vol = muted ? 0 : percent;
00520                     // set both channels to same volume
00521                     vol |= vol << 8;
00522                     ioctl( fd, MIXER_WRITE( SOUND_MIXER_VOLUME ), &vol );
00523                     ::close( fd );
00524                 }
00525 #endif
00526             }
00527             break;
00528     }
00529 }
00530 
00531 static void setMic( int t = 0, int percent = -1 )
00532 {
00533     switch ( t ) {
00534         case 0: {
00535                 Config cfg( "qpe" );
00536                 cfg.setGroup( "Volume" );
00537                 if ( percent < 0 )
00538                     percent = cfg.readNumEntry( "Mic", 50 );
00539 
00540 #ifndef QT_NO_SOUND
00541                 int fd = 0;
00542                 int mic = micMuted ? 0 : percent;
00543 #ifdef QT_QWS_DEVFS
00544                 if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
00545 #else
00546                 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
00547 #endif
00548                     ioctl( fd, MIXER_WRITE( SOUND_MIXER_MIC ), &mic );
00549                     ::close( fd );
00550                 }
00551 #endif
00552             }
00553             break;
00554     }
00555 }
00556 
00557 
00558 static void setBass( int t = 0, int percent = -1 )
00559 {
00560     switch ( t ) {
00561         case 0: {
00562                 Config cfg( "qpe" );
00563                 cfg.setGroup( "Volume" );
00564                 if ( percent < 0 )
00565                     percent = cfg.readNumEntry( "BassPercent", 50 );
00566 
00567 #ifndef QT_NO_SOUND
00568                 int fd = 0;
00569                 int bass = percent;
00570 #ifdef QT_QWS_DEVFS
00571                                 if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
00572 #else
00573                                 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
00574 #endif
00575                     ioctl( fd, MIXER_WRITE( SOUND_MIXER_BASS ), &bass );
00576                     ::close( fd );
00577                 }
00578 #endif
00579             }
00580             break;
00581     }
00582 }
00583 
00584 
00585 static void setTreble( int t = 0, int percent = -1 )
00586 {
00587     switch ( t ) {
00588         case 0: {
00589                 Config cfg( "qpe" );
00590                 cfg.setGroup( "Volume" );
00591                 if ( percent < 0 )
00592                     percent = cfg.readNumEntry( "TreblePercent", 50 );
00593 
00594 #ifndef QT_NO_SOUND
00595                 int fd = 0;
00596                 int treble = percent;
00597 #ifdef QT_QWS_DEVFS
00598                 if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
00599 #else
00600                 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
00601 #endif
00602                     ioctl( fd, MIXER_WRITE( SOUND_MIXER_TREBLE ), &treble );
00603                     ::close( fd );
00604                 }
00605 #endif
00606             }
00607             break;
00608     }
00609 }
00610 
00611 
00708 void QPEApplication::processQCopFile()
00709 {
00710     QString qcopfn("/tmp/qcop-msg-");
00711     qcopfn += d->appName; // append command name
00712 
00713     QFile f(qcopfn);
00714     if ( f.open(IO_ReadWrite) ) {
00715 #ifndef Q_OS_WIN32
00716     flock(f.handle(), LOCK_EX);
00717 #endif
00718     QDataStream ds(&f);
00719     QCString channel, message;
00720     QByteArray data;
00721     while(!ds.atEnd()) {
00722         ds >> channel >> message >> data;
00723         d->enqueueQCop(channel,message,data);
00724     }
00725     ::ftruncate(f.handle(), 0);
00726 #ifndef Q_OS_WIN32
00727     f.flush();
00728     flock(f.handle(), LOCK_UN);
00729 #endif
00730     }
00731 #endif
00732 }
00733 
00734 
00764 #ifndef QT_NO_TRANSLATION
00765 static void qtopia_loadTranslations( const QStringList& qms )
00766 {
00767     QStringList langs = Global::languageList();
00768 
00769     for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) {
00770         QString lang = *it;
00771 
00772         QTranslator * trans;
00773         QString tfn;
00774 
00775         for (QStringList::ConstIterator qmit = qms.begin(); qmit!=qms.end(); ++qmit) {
00776             trans = new QTranslator(qApp);
00777             tfn = QPEApplication::qpeDir() + "i18n/" + lang + "/" + *qmit + ".qm";
00778             if ( trans->load( tfn ))
00779                 qApp->installTranslator( trans );
00780             else
00781                 delete trans;
00782         }
00783     }
00784 }
00785 #endif
00786 
00787 /*
00788         Turn off qDebug in release mode
00789  */
00790 static void qtopiaMsgHandler(QtMsgType type, const char* msg)
00791 {
00792                 switch ( type ) {
00793                         case QtDebugMsg:
00794 #ifdef QT_DEBUG
00795                                         fprintf( stderr, "Debug: %s\n", msg );
00796 #endif
00797                                         break;
00798                         case QtWarningMsg:
00799 #ifdef QT_DEBUG
00800                                         fprintf( stderr, "Warning: %s\n", msg );
00801 #endif
00802                                         break;
00803                         case QtFatalMsg:
00804                                         fprintf( stderr, "Fatal: %s\n", msg );
00805                                         abort();
00806     }
00807 }
00808 
00816 QPEApplication::QPEApplication( int & argc, char **argv, Type t )
00817         : QApplication( hack(argc), argv, t ), pidChannel( 0 )
00818 {
00819     QPixmapCache::setCacheLimit(256); // sensible default for smaller devices.
00820     qInstallMsgHandler(qtopiaMsgHandler);
00821 
00822     d = new QPEApplicationData;
00823     d->loadTextCodecs();
00824     d->loadImageCodecs();
00825 
00826     setFont( QFont( d->fontFamily, d->fontSize ) );
00827     AppLnk::setSmallIconSize( d->smallIconSize );
00828     AppLnk::setBigIconSize( d->bigIconSize );
00829 
00830     QMimeSourceFactory::setDefaultFactory( new ResourceMimeFactory );
00831 
00832     connect( this, SIGNAL( lastWindowClosed() ), this, SLOT( hideOrQuit() ) );
00833 
00834 
00835     sysChannel = new QCopChannel( "QPE/System", this );
00836     connect( sysChannel, SIGNAL( received(const QCString&,const QByteArray&) ),
00837              this, SLOT( systemMessage(const QCString&,const QByteArray&) ) );
00838 
00839 /* COde now in initapp */
00840 #if 0
00841 #if defined(Q_WS_QWS) && !defined(QT_NO_COP)
00842 
00843     QString qcopfn( "/tmp/qcop-msg-" );
00844     qcopfn += QString( argv[ 0 ] ); // append command name
00845 
00846     QFile f( qcopfn );
00847     if ( f.open( IO_ReadOnly ) ) {
00848         flock( f.handle(), LOCK_EX );
00849     }
00850 
00851 
00852 
00853     QCString channel = QCString( argv[ 0 ] );
00854     channel.replace( QRegExp( ".*/" ), "" );
00855     d->appName = channel;
00856     channel = "QPE/Application/" + channel;
00857     pidChannel = new QCopChannel( channel, this );
00858     connect( pidChannel, SIGNAL( received(const QCString&,const QByteArray&) ),
00859              this, SLOT( pidMessage(const QCString&,const QByteArray&) ) );
00860 
00861     if ( f.isOpen() ) {
00862         d->keep_running = FALSE;
00863         QDataStream ds( &f );
00864         QCString channel, message;
00865         QByteArray data;
00866         while ( !ds.atEnd() ) {
00867             ds >> channel >> message >> data;
00868             d->enqueueQCop( channel, message, data );
00869         }
00870 
00871         flock( f.handle(), LOCK_UN );
00872         f.close();
00873         f.remove();
00874     }
00875 
00876     for ( int a = 0; a < argc; a++ ) {
00877         if ( qstrcmp( argv[ a ], "-preload" ) == 0 ) {
00878             argv[ a ] = argv[ a + 1 ];
00879             a++;
00880             d->preloaded = TRUE;
00881             argc -= 1;
00882         }
00883         else if ( qstrcmp( argv[ a ], "-preload-show" ) == 0 ) {
00884             argv[ a ] = argv[ a + 1 ];
00885             a++;
00886             d->preloaded = TRUE;
00887             d->forceshow = TRUE;
00888             argc -= 1;
00889         }
00890     }
00891 
00892     /* overide stored arguments */
00893     setArgs( argc, argv );
00894 
00895 #endif
00896 #else
00897     initApp( argc, argv );
00898 #endif
00899 #ifdef Q_WS_QWS
00900     /* load the font renderer factories */
00901     FontDatabase::loadRenderers();
00902 #endif
00903 #ifndef QT_NO_TRANSLATION
00904     QStringList qms;
00905     qms << "libqpe";
00906     qms << "libopie";
00907     qms << d->appName;
00908 
00909     qtopia_loadTranslations(qms);
00910 #endif
00911 
00912     applyStyle();
00913 
00914     if ( type() == GuiServer ) {
00915         setVolume();
00916     }
00917 
00918     installEventFilter( this );
00919 
00920     QPEMenuToolFocusManager::initialize();
00921 
00922 #ifdef QT_NO_QWS_CURSOR
00923     // if we have no cursor, probably don't want tooltips
00924     QToolTip::setEnabled( FALSE );
00925 #endif
00926 }
00927 
00928 
00929 #ifdef QTOPIA_INTERNAL_INITAPP
00930 void QPEApplication::initApp( int argc, char **argv )
00931 {
00932     delete pidChannel;
00933     d->keep_running = TRUE;
00934     d->preloaded = FALSE;
00935     d->forceshow = FALSE;
00936 
00937     QCString channel = QCString(argv[0]);
00938 
00939     channel.replace(QRegExp(".*/"),"");
00940     d->appName = channel;
00941 
00942 #ifndef QT_NO_TRANSLATION
00943     qtopia_loadTranslations( QStringList()<<channel );
00944 #endif
00945 
00946     #if QT_VERSION > 235
00947     qt_fbdpy->setIdentity( channel ); // In Qt/E 2.3.6
00948     #endif
00949 
00950     channel = "QPE/Application/" + channel;
00951     pidChannel = new QCopChannel( channel, this);
00952     connect( pidChannel, SIGNAL(received(const QCString&,const QByteArray&)),
00953         this, SLOT(pidMessage(const QCString&,const QByteArray&)));
00954 
00955 
00956 
00957     processQCopFile();
00958     d->keep_running = d->qcopq.isEmpty();
00959 
00960     for (int a=0; a<argc; a++) {
00961     if ( qstrcmp(argv[a],"-preload")==0 ) {
00962         argv[a] = argv[a+1];
00963         a++;
00964         d->preloaded = TRUE;
00965         argc-=1;
00966     } else if ( qstrcmp(argv[a],"-preload-show")==0 ) {
00967         argv[a] = argv[a+1];
00968         a++;
00969         d->preloaded = TRUE;
00970         d->forceshow = TRUE;
00971         argc-=1;
00972     }
00973     }
00974 
00975     /* overide stored arguments */
00976     setArgs(argc, argv);
00977 }
00978 #endif
00979 
00980 
00981 static QPtrDict<void>* inputMethodDict = 0;
00982 static void createInputMethodDict()
00983 {
00984     if ( !inputMethodDict )
00985         inputMethodDict = new QPtrDict<void>;
00986 }
00987 
00995 QPEApplication::InputMethodHint QPEApplication::inputMethodHint( QWidget * w )
00996 {
00997     if ( inputMethodDict && w )
00998         return ( InputMethodHint ) ( int ) inputMethodDict->find( w );
00999     return Normal;
01000 }
01001 
01016 void QPEApplication::setInputMethodHint( QWidget * w, InputMethodHint mode )
01017 {
01018     createInputMethodDict();
01019     if ( mode == Normal ) {
01020         inputMethodDict->remove
01021         ( w );
01022     }
01023     else {
01024         inputMethodDict->insert( w, ( void* ) mode );
01025     }
01026 }
01027 
01028 class HackDialog : public QDialog
01029 {
01030 public:
01031     void acceptIt()
01032     {
01033         accept();
01034     }
01035     void rejectIt()
01036     {
01037         reject();
01038     }
01039 };
01040 
01041 
01042 void QPEApplication::mapToDefaultAction( QWSKeyEvent * ke, int key )
01043 {
01044     // specialised actions for certain widgets. May want to
01045     // add more stuff here.
01046     if ( activePopupWidget() && activePopupWidget() ->inherits( "QListBox" )
01047             && activePopupWidget() ->parentWidget()
01048             && activePopupWidget() ->parentWidget() ->inherits( "QComboBox" ) )
01049         key = Qt::Key_Return;
01050 
01051     if ( activePopupWidget() && activePopupWidget() ->inherits( "QPopupMenu" ) )
01052         key = Qt::Key_Return;
01053 
01054 #ifdef QWS
01055 
01056     ke->simpleData.keycode = key;
01057 #endif
01058 }
01059 
01060 
01065 #ifdef QWS
01066 bool QPEApplication::qwsEventFilter( QWSEvent * e )
01067 {
01068     if ( !d->notbusysent && e->type == QWSEvent::Focus ) {
01069         if ( qApp->type() != QApplication::GuiServer ) {
01070             QCopEnvelope e( "QPE/System", "notBusy(QString)" );
01071             e << d->appName;
01072         }
01073         d->notbusysent = TRUE;
01074     }
01075     if ( type() == GuiServer ) {
01076         switch ( e->type ) {
01077             case QWSEvent::Mouse:
01078                 if ( e->asMouse() ->simpleData.state && !QWidget::find( e->window() ) )
01079                     emit clientMoused();
01080                 break;
01081             default:
01082                 break;
01083         }
01084     }
01085     if ( e->type == QWSEvent::Key ) {
01086         QWSKeyEvent *ke = ( QWSKeyEvent * ) e;
01087         if ( ke->simpleData.keycode == Qt::Key_F33 ) {
01088             // Use special "OK" key to press "OK" on top level widgets
01089             QWidget * active = activeWindow();
01090             QWidget *popup = 0;
01091             if ( active && active->isPopup() ) {
01092                 popup = active;
01093                 active = active->parentWidget();
01094             }
01095             if ( active && ( int ) active->winId() == ke->simpleData.window &&
01096                     !active->testWFlags( WStyle_Customize | WType_Popup | WType_Desktop ) ) {
01097                 if ( ke->simpleData.is_press ) {
01098                     if ( popup )
01099                         popup->close();
01100                     if ( active->inherits( "QDialog" ) ) {
01101                         HackDialog * d = ( HackDialog * ) active;
01102                         d->acceptIt();
01103                         return TRUE;
01104                     }
01105                     else if ( ( ( HackWidget * ) active ) ->needsOk() ) {
01106                         QSignal s;
01107                         s.connect( active, SLOT( accept() ) );
01108                         s.activate();
01109                     }
01110                     else {
01111                         // do the same as with the select key: Map to the default action of the widget:
01112                         mapToDefaultAction( ke, Qt::Key_Return );
01113                     }
01114                 }
01115             }
01116         }
01117         else if ( ke->simpleData.keycode == Qt::Key_F30 ) {
01118             // Use special "select" key to do whatever default action a widget has
01119             mapToDefaultAction( ke, Qt::Key_Space );
01120         }
01121         else if ( ke->simpleData.keycode == Qt::Key_Escape &&
01122                   ke->simpleData.is_press ) {
01123             // Escape key closes app if focus on toplevel
01124             QWidget * active = activeWindow();
01125             if ( active && active->testWFlags( WType_TopLevel ) &&
01126                     ( int ) active->winId() == ke->simpleData.window &&
01127                     !active->testWFlags( WStyle_Dialog | WStyle_Customize | WType_Popup | WType_Desktop ) ) {
01128                 if ( active->inherits( "QDialog" ) ) {
01129                     HackDialog * d = ( HackDialog * ) active;
01130                     d->rejectIt();
01131                     return TRUE;
01132                 } else /*if ( strcmp( argv() [ 0 ], "embeddedkonsole" ) != 0 )*/ {
01133                 active->close();
01134                 }
01135             }
01136 
01137         }
01138         else if ( ke->simpleData.keycode >= Qt::Key_F1 && ke->simpleData.keycode <= Qt::Key_F29 ) {
01139             // this should be if ( ODevice::inst ( )-> buttonForKeycode ( ... ))
01140             // but we cannot access libopie function within libqpe :(
01141 
01142             QWidget * active = activeWindow ( );
01143             if ( active && ((int) active-> winId ( ) == ke-> simpleData.window )) {
01144                 if ( d-> kbgrabbed ) { // we grabbed the keyboard
01145                     QChar ch ( ke-> simpleData.unicode );
01146                     QKeyEvent qke ( ke-> simpleData. is_press ? QEvent::KeyPress : QEvent::KeyRelease,
01147                                     ke-> simpleData.keycode,
01148                                     ch. latin1 ( ),
01149                                     ke-> simpleData.modifiers,
01150                                     QString ( ch ),
01151                                     ke-> simpleData.is_auto_repeat, 1 );
01152 
01153                     QObject *which = QWidget::keyboardGrabber ( );
01154                     if ( !which )
01155                         which = QApplication::focusWidget ( );
01156                     if ( !which )
01157                         which = QApplication::activeWindow ( );
01158                     if ( !which )
01159                         which = qApp;
01160 
01161                     QApplication::sendEvent ( which, &qke );
01162                 }
01163                 else { // we didn't grab the keyboard, so send the event to the launcher
01164                     QCopEnvelope e ( "QPE/Launcher", "deviceButton(int,int,int)" );
01165                     e << int( ke-> simpleData.keycode ) << int( ke-> simpleData. is_press ) << int( ke-> simpleData.is_auto_repeat );
01166                 }
01167             }
01168             return true;
01169         }
01170     }
01171     if ( e->type == QWSEvent::Focus ) {
01172         QWSFocusEvent * fe = ( QWSFocusEvent* ) e;
01173         if ( !fe->simpleData.get_focus ) {
01174             QWidget * active = activeWindow();
01175             while ( active && active->isPopup() ) {
01176                 active->close();
01177                 active = activeWindow();
01178             }
01179         }
01180         else {
01181             // make sure our modal widget is ALWAYS on top
01182             QWidget *topm = activeModalWidget();
01183             if ( topm && static_cast<int>( topm->winId() ) != fe->simpleData.window) {
01184                 topm->raise();
01185             }
01186         }
01187         if ( fe->simpleData.get_focus && inputMethodDict ) {
01188             InputMethodHint m = inputMethodHint( QWidget::find( e->window() ) );
01189             if ( m == AlwaysOff )
01190                 Global::hideInputMethod();
01191             if ( m == AlwaysOn )
01192                 Global::showInputMethod();
01193         }
01194     }
01195 
01196 
01197     return QApplication::qwsEventFilter( e );
01198 }
01199 #endif
01200 
01204 QPEApplication::~QPEApplication()
01205 {
01206     ungrabKeyboard();
01207 #if defined(Q_WS_QWS) && !defined(QT_NO_COP)
01208     // Need to delete QCopChannels early, since the display will
01209     // be gone by the time we get to ~QObject().
01210     delete sysChannel;
01211     delete pidChannel;
01212 #endif
01213 
01214 #ifdef OPIE_WITHROHFEEDBACK
01215     if( d->RoH )
01216       delete d->RoH;
01217 #endif
01218     delete d;
01219 }
01220 
01224 QString QPEApplication::qpeDir()
01225 {
01226     QString base, dir;
01227 
01228     if (getenv( "OPIEDIR" ))
01229         base = QString(getenv("OPIEDIR")).stripWhiteSpace();
01230     if ( !base.isNull() && (base.length() > 0 )){
01231 #ifdef Q_OS_WIN32
01232         QString temp(base);
01233         if (temp[(int)temp.length()-1] != QDir::separator())
01234             temp.append(QDir::separator());
01235         dir = temp;
01236 #else
01237         dir = QString( base ) + "/";
01238 #endif
01239     }else{
01240         dir = QString( ".." ) + QDir::separator();
01241     }
01242 
01243     return dir;
01244 }
01245 
01250 QString QPEApplication::documentDir()
01251 {
01252     const char* base = getenv( "HOME");
01253     if ( base )
01254         return QString( base ) + "/Documents";
01255 
01256     return QString( "../Documents" );
01257 }
01258 
01259 static int deforient = -1;
01260 
01264 int QPEApplication::defaultRotation()
01265 {
01266     if ( deforient < 0 ) {
01267         QString d = getenv( "QWS_DISPLAY" );
01268         if ( d.contains( "Rot90" ) ) {
01269             deforient = 90;
01270         }
01271         else if ( d.contains( "Rot180" ) ) {
01272             deforient = 180;
01273         }
01274         else if ( d.contains( "Rot270" ) ) {
01275             deforient = 270;
01276         }
01277         else {
01278             deforient = 0;
01279         }
01280     }
01281     return deforient;
01282 }
01283 
01287 void QPEApplication::setDefaultRotation( int r )
01288 {
01289     if ( qApp->type() == GuiServer ) {
01290         deforient = r;
01291         int j = 0;
01292         QCString old = getenv( "QWS_DISPLAY" ) ? getenv( "QWS_DISPLAY" ) : "Transformed";
01293         QString driver( old.left( ( ( j = old.find( ':' ) ) >= 0 ) ? j : old.size() ).data() );
01294         setenv( "QWS_DISPLAY", QString( "%1:Rot%2:0" ).arg(driver).arg( r ).latin1(), 1 );
01295         Config config("qpe");
01296         config.setGroup( "Rotation" );
01297         config.writeEntry( "Rot", r );
01298     }
01299     else {
01300 #ifndef QT_NO_COP
01301         { QCopEnvelope e( "QPE/System", "setDefaultRotation(int)" );
01302             e << r;
01303         }
01304 #endif
01305 
01306     }
01307 }
01308 
01309 #include <qgfx_qws.h>
01310 #include <qwindowsystem_qws.h>
01311 
01312 #if QT_VERSION > 236
01313 extern void qws_clearLoadedFonts();
01314 #endif
01315 
01316 void QPEApplication::setCurrentMode( int x, int y, int depth )
01317 {
01318     // Reset the caches
01319 #if QT_VERSION > 236
01320     qws_clearLoadedFonts();
01321 #endif
01322     QPixmapCache::clear();
01323 
01324     // Change the screen mode
01325     qt_screen->setMode(x, y, depth);
01326 
01327     if ( qApp->type() == GuiServer ) {
01328 #if QT_VERSION > 236
01329         // Reconfigure the GuiServer
01330         qwsServer->beginDisplayReconfigure();
01331         qwsServer->endDisplayReconfigure();
01332 #endif
01333         // Get all the running apps to reset
01334         QCopEnvelope env( "QPE/System", "reset()" );
01335     }
01336 }
01337 
01338 void QPEApplication::reset() {
01339     // Reconnect to the screen
01340     qt_screen->disconnect();
01341     qt_screen->connect( QString::null );
01342 
01343     // Redraw everything
01344     applyStyle();
01345 }
01346 
01347 #if (QT_VERSION < 238) && defined Q_OS_MACX
01348 bool qt_left_hand_scrollbars = false;
01349 #else
01350 extern bool qt_left_hand_scrollbars QPE_WEAK_SYMBOL;
01351 #endif
01352 
01356 void QPEApplication::applyStyle()
01357 {
01358     Config config( "qpe" );
01359     config.setGroup( "Appearance" );
01360 
01361 #if QT_VERSION > 233
01362     // Widget style
01363     QString style = config.readEntry( "Style", "FlatStyle" );
01364 
01365     internalSetStyle ( style );
01366 
01367     // Colors - from /etc/colors/Liquid.scheme
01368     QColor bgcolor( config.readEntry( "Background", "#E0E0E0" ) );
01369     QColor btncolor( config.readEntry( "Button", "#96c8fa" ) );
01370     QPalette pal( btncolor, bgcolor );
01371     QString color = config.readEntry( "Highlight", "#73adef" );
01372     pal.setColor( QColorGroup::Highlight, QColor( color ) );
01373     color = config.readEntry( "HighlightedText", "#FFFFFF" );
01374     pal.setColor( QColorGroup::HighlightedText, QColor( color ) );
01375     color = config.readEntry( "Text", "#000000" );
01376     pal.setColor( QColorGroup::Text, QColor( color ) );
01377     color = config.readEntry( "ButtonText", "#000000" );
01378     pal.setColor( QPalette::Active, QColorGroup::ButtonText, QColor( color ) );
01379     color = config.readEntry( "Base", "#FFFFFF" );
01380     pal.setColor( QColorGroup::Base, QColor( color ) );
01381 
01382     pal.setColor( QPalette::Disabled, QColorGroup::Text,
01383                   pal.color( QPalette::Active, QColorGroup::Background ).dark() );
01384 
01385     setPalette( pal, TRUE );
01386 
01387 
01388         // Set the ScrollBar on the 'right' side but only if the weak symbol is present
01389         if (&qt_left_hand_scrollbars )
01390             qt_left_hand_scrollbars = config.readBoolEntry( "LeftHand", false );
01391 
01392     // Window Decoration
01393     QString dec = config.readEntry( "Decoration", "Flat" );
01394 
01395     if ( dec != d->decorationName ) {
01396         qwsSetDecoration( new QPEDecoration( dec ) );
01397         d->decorationName = dec;
01398     }
01399 
01400     // Font
01401     QString ff = config.readEntry( "FontFamily", font().family() );
01402     int fs = config.readNumEntry( "FontSize", font().pointSize() );
01403 
01404     setFont ( QFont ( ff, fs ), true );
01405 #endif
01406 }
01407 
01408 void QPEApplication::systemMessage( const QCString& msg, const QByteArray& data )
01409 {
01410 #ifdef Q_WS_QWS
01411     QDataStream stream( data, IO_ReadOnly );
01412     if ( msg == "applyStyle()" ) {
01413         applyStyle();
01414     }
01415     else if ( msg == "toggleApplicationMenu()" ) {
01416         QWidget *active = activeWindow ( );
01417 
01418         if ( active ) {
01419             QPEMenuToolFocusManager *man = QPEMenuToolFocusManager::manager ( );
01420             bool oldactive = man-> isActive ( );
01421 
01422             man-> setActive( !man-> isActive() );
01423 
01424             if ( !oldactive && !man-> isActive ( )) { // no menubar to toggle -> try O-Menu
01425                 QCopEnvelope e ( "QPE/TaskBar", "toggleStartMenu()" );
01426             }
01427         }
01428     }
01429     else if ( msg == "setDefaultRotation(int)" ) {
01430         if ( type() == GuiServer ) {
01431             int r;
01432             stream >> r;
01433             setDefaultRotation( r );
01434         }
01435     }
01436     else if ( msg == "setCurrentMode(int,int,int)" ) { // Added: 2003-06-11 by Tim Ansell <mithro@mithis.net>
01437             if ( type() == GuiServer ) {
01438         int x, y, depth;
01439         stream >> x;
01440         stream >> y;
01441         stream >> depth;
01442         setCurrentMode( x, y, depth );
01443             }
01444      }
01445     else if ( msg == "reset()" ) {
01446             if ( type() != GuiServer )
01447                 reset();
01448     }
01449     else if ( msg == "setCurrentRotation(int)" ) {
01450         int r;
01451         stream >> r;
01452         setCurrentRotation( r );
01453      }
01454     else if ( msg == "shutdown()" ) {
01455         if ( type() == GuiServer )
01456             shutdown();
01457     }
01458     else if ( msg == "quit()" ) {
01459         if ( type() != GuiServer )
01460             tryQuit();
01461     }
01462     else if ( msg == "forceQuit()" ) {
01463         if ( type() != GuiServer )
01464             quit();
01465     }
01466     else if ( msg == "restart()" ) {
01467         if ( type() == GuiServer )
01468             restart();
01469     }
01470     else if ( msg == "language(QString)" ) {
01471         if ( type() == GuiServer ) {
01472             QString l;
01473             stream >> l;
01474             QString cl = getenv( "LANG" );
01475             if ( cl != l ) {
01476                 if ( l.isNull() )
01477                     unsetenv( "LANG" );
01478                 else
01479                     setenv( "LANG", l.latin1(), 1 );
01480                 restart();
01481             }
01482         }
01483     }
01484     else if ( msg == "timeChange(QString)" ) {
01485         QString t;
01486         stream >> t;
01487         if ( t.isNull() )
01488             unsetenv( "TZ" );
01489         else
01490             setenv( "TZ", t.latin1(), 1 );
01491         // emit the signal so everyone else knows...
01492         emit timeChanged();
01493     }
01494     else if ( msg == "addAlarm(QDateTime,QCString,QCString,int)" ) {
01495         if ( type() == GuiServer ) {
01496             QDateTime when;
01497             QCString channel, message;
01498             int data;
01499             stream >> when >> channel >> message >> data;
01500             AlarmServer::addAlarm( when, channel, message, data );
01501         }
01502     }
01503     else if ( msg == "deleteAlarm(QDateTime,QCString,QCString,int)" ) {
01504         if ( type() == GuiServer ) {
01505             QDateTime when;
01506             QCString channel, message;
01507             int data;
01508             stream >> when >> channel >> message >> data;
01509             AlarmServer::deleteAlarm( when, channel, message, data );
01510         }
01511     }
01512     else if ( msg == "clockChange(bool)" ) {
01513         int tmp;
01514         stream >> tmp;
01515         emit clockChanged( tmp );
01516     }
01517     else if ( msg == "weekChange(bool)" ) {
01518         int tmp;
01519         stream >> tmp;
01520         emit weekChanged( tmp );
01521     }
01522     else if ( msg == "setDateFormat(DateFormat)" ) {
01523         DateFormat tmp;
01524         stream >> tmp;
01525         emit dateFormatChanged( tmp );
01526     }
01527     else if ( msg == "setVolume(int,int)" ) {
01528         int t, v;
01529         stream >> t >> v;
01530         setVolume( t, v );
01531         emit volumeChanged( muted );
01532     }
01533     else if ( msg == "volumeChange(bool)" ) {
01534         stream >> muted;
01535         setVolume();
01536         emit volumeChanged( muted );
01537     }
01538     else if ( msg == "setMic(int,int)" ) { // Added: 2002-02-08 by Jeremy Cowgar <jc@cowgar.com>
01539         int t, v;
01540         stream >> t >> v;
01541         setMic( t, v );
01542         emit micChanged( micMuted );
01543     }
01544     else if ( msg == "micChange(bool)" ) { // Added: 2002-02-08 by Jeremy Cowgar <jc@cowgar.com>
01545         stream >> micMuted;
01546         setMic();
01547         emit micChanged( micMuted );
01548     }
01549     else if ( msg == "setBass(int,int)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
01550         int t, v;
01551         stream >> t >> v;
01552         setBass( t, v );
01553     }
01554     else if ( msg == "bassChange(bool)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
01555             setBass();
01556     }
01557         else if ( msg == "setTreble(int,int)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
01558         int t, v;
01559         stream >> t >> v;
01560         setTreble( t, v );
01561     }
01562     else if ( msg == "trebleChange(bool)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
01563             setTreble();
01564     } else if ( msg == "getMarkedText()" ) {
01565     if ( type() == GuiServer ) {
01566         const ushort unicode = 'C'-'@';
01567         const int scan = Key_C;
01568         qwsServer->processKeyEvent( unicode, scan, ControlButton, TRUE, FALSE );
01569         qwsServer->processKeyEvent( unicode, scan, ControlButton, FALSE, FALSE );
01570     }
01571     } else if ( msg == "newChannel(QString)") {
01572     QString myChannel = "QPE/Application/" + d->appName;
01573     QString channel;
01574     stream >> channel;
01575     if (channel == myChannel) {
01576         processQCopFile();
01577         d->sendQCopQ();
01578     }
01579     }
01580 
01581 
01582 #endif
01583 }
01584 
01585 
01586 
01587 
01588 
01592 bool QPEApplication::raiseAppropriateWindow()
01593 {
01594     bool r=FALSE;
01595 
01596     // 1. Raise the main widget
01597     QWidget *top = d->qpe_main_widget;
01598     if ( !top ) top = mainWidget();
01599 
01600     if ( top && d->keep_running ) {
01601     if ( top->isVisible() )
01602         r = TRUE;
01603     else if (d->preloaded) {
01604         // We are preloaded and not visible.. pretend we just started..
01605 #ifndef QT_NO_COP
01606         QCopEnvelope e("QPE/System", "fastAppShowing(QString)");
01607         e << d->appName;
01608 #endif
01609     }
01610 
01611     d->show_mx(top,d->nomaximize, d->appName);
01612     top->raise();
01613     }
01614 
01615     QWidget *topm = activeModalWidget();
01616 
01617     // 2. Raise any parentless widgets (except top and topm, as they
01618     //     are raised before and after this loop).  Order from most
01619     //     recently raised as deepest to least recently as top, so
01620     //     that repeated calls cycle through widgets.
01621     QWidgetList *list = topLevelWidgets();
01622     if ( list ) {
01623     bool foundlast = FALSE;
01624     QWidget* topsub = 0;
01625     if ( d->lastraised ) {
01626         for (QWidget* w = list->first(); w; w = list->next()) {
01627         if ( !w->parentWidget() && w != topm && w->isVisible() && !w->isDesktop() ) {
01628             if ( w == d->lastraised )
01629             foundlast = TRUE;
01630             if ( foundlast ) {
01631             w->raise();
01632             topsub = w;
01633             }
01634         }
01635         }
01636     }
01637     for (QWidget* w = list->first(); w; w = list->next()) {
01638         if ( !w->parentWidget() && w != topm && w->isVisible() && !w->isDesktop() ) {
01639         if ( w == d->lastraised )
01640             break;
01641         w->raise();
01642         topsub = w;
01643         }
01644     }
01645     d->lastraised = topsub;
01646     delete list;
01647     }
01648 
01649     // 3. Raise the active modal widget.
01650     if ( topm ) {
01651     topm->show();
01652     topm->raise();
01653     // If we haven't already handled the fastAppShowing message
01654     if (!top && d->preloaded) {
01655 #ifndef QT_NO_COP
01656         QCopEnvelope e("QPE/System", "fastAppShowing(QString)");
01657         e << d->appName;
01658 #endif
01659     }
01660     r = FALSE;
01661     }
01662 
01663     return r;
01664 }
01665 
01666 
01667 void QPEApplication::pidMessage( const QCString& msg, const QByteArray& data)
01668 {
01669 #ifdef Q_WS_QWS
01670 
01671     if ( msg == "quit()" ) {
01672         tryQuit();
01673     }
01674     else if ( msg == "quitIfInvisible()" ) {
01675         if ( d->qpe_main_widget && !d->qpe_main_widget->isVisible() )
01676             quit();
01677     }
01678     else if ( msg == "close()" ) {
01679         hideOrQuit();
01680     }
01681     else if ( msg == "disablePreload()" ) {
01682         d->preloaded = FALSE;
01683         d->keep_running = TRUE;
01684         /* so that quit will quit */
01685     }
01686     else if ( msg == "enablePreload()" ) {
01687         if (d->qpe_main_widget)
01688             d->preloaded = TRUE;
01689         d->keep_running = TRUE;
01690         /* so next quit won't quit */
01691     }
01692     else if ( msg == "raise()" ) {
01693         d->keep_running = TRUE;
01694         d->notbusysent = FALSE;
01695         raiseAppropriateWindow();
01696         // Tell the system we're still chugging along...
01697         QCopEnvelope e("QPE/System", "appRaised(QString)");
01698         e << d->appName;
01699     }
01700     else if ( msg == "flush()" ) {
01701         emit flush();
01702         // we need to tell the desktop
01703         QCopEnvelope e( "QPE/Desktop", "flushDone(QString)" );
01704         e << d->appName;
01705     }
01706     else if ( msg == "reload()" ) {
01707         emit reload();
01708     }
01709     else if ( msg == "setDocument(QString)" ) {
01710         d->keep_running = TRUE;
01711         QDataStream stream( data, IO_ReadOnly );
01712         QString doc;
01713         stream >> doc;
01714         QWidget *mw = mainWidget();
01715         if ( !mw )
01716             mw = d->qpe_main_widget;
01717         if ( mw )
01718             Global::setDocument( mw, doc );
01719 
01720     } else if ( msg == "QPEProcessQCop()" ) {
01721             processQCopFile();
01722             d->sendQCopQ();
01723         }else
01724         {
01725             bool p = d->keep_running;
01726             d->keep_running = FALSE;
01727             emit appMessage( msg, data);
01728             if ( d->keep_running ) {
01729                 d->notbusysent = FALSE;
01730                 raiseAppropriateWindow();
01731                 if ( !p ) {
01732                     // Tell the system we're still chugging along...
01733 #ifndef QT_NO_COP
01734                     QCopEnvelope e("QPE/System", "appRaised(QString)");
01735                     e << d->appName;
01736 #endif
01737                 }
01738             }
01739             if ( p )
01740                 d->keep_running = p;
01741     }
01742 #endif
01743 }
01744 
01745 
01752 void QPEApplication::showMainWidget( QWidget* mw, bool nomaximize )
01753 {
01754 //        setMainWidget(mw); this breaks FastLoading because lastWindowClose() would quit
01755             d->show(mw, nomaximize );
01756 }
01757 
01769 void QPEApplication::showMainDocumentWidget( QWidget* mw, bool nomaximize )
01770 {
01771     if ( mw && argc() == 2 )
01772         Global::setDocument( mw, QString::fromUtf8(argv()[1]) );
01773 
01774 
01775 //    setMainWidget(mw); see above
01776     d->show(mw, nomaximize );
01777 }
01778 
01779 
01790 void QPEApplication::setKeepRunning()
01791 {
01792     if ( qApp && qApp->inherits( "QPEApplication" ) ) {
01793         QPEApplication * qpeApp = ( QPEApplication* ) qApp;
01794         qpeApp->d->keep_running = TRUE;
01795     }
01796 }
01797 
01804 bool QPEApplication::keepRunning() const
01805 {
01806     return d->keep_running;
01807 }
01808 
01812 void QPEApplication::internalSetStyle( const QString &style )
01813 {
01814 #if QT_VERSION >= 0x030000
01815     if ( style == "QPE" ) {
01816         setStyle( new QPEStyle );
01817     }
01818     else {
01819         QStyle *s = QStyleFactory::create( style );
01820         if ( s )
01821             setStyle( s );
01822     }
01823 #else
01824     if ( style == "Windows" ) {
01825         setStyle( new QWindowsStyle );
01826     }
01827     else if ( style == "QPE" ) {
01828         setStyle( new QPEStyle );
01829     }
01830     else if ( style == "Light" ) {
01831         setStyle( new LightStyle );
01832     }
01833 #ifndef QT_NO_STYLE_PLATINUM
01834     else if ( style == "Platinum" ) {
01835         setStyle( new QPlatinumStyle );
01836     }
01837 #endif
01838 #ifndef QT_NO_STYLE_MOTIF
01839     else if ( style == "Motif" ) {
01840         setStyle( new QMotifStyle );
01841     }
01842 #endif
01843 #ifndef QT_NO_STYLE_MOTIFPLUS
01844     else if ( style == "MotifPlus" ) {
01845         setStyle( new QMotifPlusStyle );
01846     }
01847 #endif
01848 
01849     else {
01850         QStyle *sty = 0;
01851         QString path = QPEApplication::qpeDir ( ) + "plugins/styles/";
01852 
01853 #ifdef Q_OS_MACX
01854         if ( style. find ( ".dylib" ) > 0 )
01855             path += style;
01856         else
01857             path = path + "lib" + style. lower ( ) + ".dylib"; // compatibility
01858 #else
01859         if ( style. find ( ".so" ) > 0 )
01860             path += style;
01861         else
01862             path = path + "lib" + style. lower ( ) + ".so"; // compatibility
01863 #endif
01864         static QLibrary *lastlib = 0;
01865         static StyleInterface *lastiface = 0;
01866 
01867         QLibrary *lib = new QLibrary ( path );
01868         StyleInterface *iface = 0;
01869 
01870         if (( lib-> queryInterface ( IID_Style, ( QUnknownInterface ** ) &iface ) == QS_OK ) && iface )
01871             sty = iface-> style ( );
01872 
01873         if ( sty ) {
01874             setStyle ( sty );
01875 
01876             if ( lastiface )
01877                 lastiface-> release ( );
01878             lastiface = iface;
01879 
01880             if ( lastlib ) {
01881                 lastlib-> unload ( );
01882                 delete lastlib;
01883             }
01884             lastlib = lib;
01885         }
01886         else {
01887             if ( iface )
01888                 iface-> release ( );
01889             delete lib;
01890 
01891             setStyle ( new LightStyle ( ));
01892         }
01893     }
01894 #endif
01895 }
01896 
01900 void QPEApplication::prepareForTermination( bool willrestart )
01901 {
01902     if ( willrestart ) {
01903         QLabel *lblWait = new QLabel( tr( "Please wait..." ), 0, "wait hack", QWidget::WStyle_Customize |
01904                                       QWidget::WStyle_NoBorder | QWidget::WStyle_Tool );
01905         lblWait->setAlignment( QWidget::AlignCenter );
01906         lblWait->show();
01907         lblWait->showMaximized();
01908     }
01909     { QCopEnvelope envelope( "QPE/System", "forceQuit()" );
01910     }
01911     processEvents(); // ensure the message goes out.
01912 }
01913 
01917 void QPEApplication::shutdown()
01918 {
01919     // Implement in server's QPEApplication subclass
01920 }
01921 
01925 void QPEApplication::restart()
01926 {
01927     // Implement in server's QPEApplication subclass
01928 }
01929 
01930 static QPtrDict<void>* stylusDict = 0;
01931 static void createDict()
01932 {
01933     if ( !stylusDict )
01934         stylusDict = new QPtrDict<void>;
01935 }
01936 
01942 QPEApplication::StylusMode QPEApplication::stylusOperation( QWidget* w )
01943 {
01944     if ( stylusDict )
01945         return ( StylusMode ) ( int ) stylusDict->find( w );
01946     return LeftOnly;
01947 }
01948 
01966 void QPEApplication::setStylusOperation( QWidget * w, StylusMode mode )
01967 {
01968     createDict();
01969     if ( mode == LeftOnly ) {
01970         stylusDict->remove
01971         ( w );
01972         w->removeEventFilter( qApp );
01973     }
01974     else {
01975         stylusDict->insert( w, ( void* ) mode );
01976         connect( w, SIGNAL( destroyed() ), qApp, SLOT( removeSenderFromStylusDict() ) );
01977         w->installEventFilter( qApp );
01978     }
01979 }
01980 
01981 
01985 bool QPEApplication::eventFilter( QObject *o, QEvent *e )
01986 {
01987         if ( !o->isWidgetType() )
01988             return FALSE;
01989 
01990     if ( stylusDict && e->type() >= QEvent::MouseButtonPress && e->type() <= QEvent::MouseMove ) {
01991         QMouseEvent * me = ( QMouseEvent* ) e;
01992         StylusMode mode = (StylusMode)(int)stylusDict->find(o);
01993         switch (mode) {
01994             case RightOnHold:
01995                 switch ( me->type() ) {
01996                     case QEvent::MouseButtonPress:
01997                         if ( me->button() == LeftButton ) {
01998                             static long Pref = 500; // #### pref.
01999                             d->presswidget = (QWidget*)o;
02000                             d->presspos = me->pos();
02001                             d->rightpressed = FALSE;
02002 #ifdef OPIE_WITHROHFEEDBACK
02003                             if( ! d->RoH )
02004                               d->RoH = new Opie::Internal::RoHFeedback;
02005 
02006                             d->RoH->init( me->globalPos(), d->presswidget );
02007                             Pref = d->RoH->delay();
02008 
02009 #endif
02010                             if (!d->presstimer )
02011                                 d->presstimer = startTimer( Pref ); // #### pref.
02012 
02013                         }
02014                         break;
02015                     case QEvent::MouseMove:
02016                         if (d->presstimer && (me->pos() - d->presspos).manhattanLength() > 8) {
02017                             killTimer(d->presstimer);
02018 #ifdef OPIE_WITHROHFEEDBACK
02019                             d->RoH->stop();
02020 #endif
02021                             d->presstimer = 0;
02022                         }
02023                         break;
02024                     case QEvent::MouseButtonRelease:
02025                         if ( me->button() == LeftButton ) {
02026                             if ( d->presstimer ) {
02027                                 killTimer(d->presstimer);
02028 #ifdef OPIE_WITHROHFEEDBACK
02029                                 d->RoH->stop( );
02030 #endif
02031                                 d->presstimer = 0;
02032                             }
02033                             if ( d->rightpressed && d->presswidget ) {
02034                               printf( "Send ButtonRelease\n" );
02035                                 // Right released
02036                                 postEvent( d->presswidget,
02037                                            new QMouseEvent( QEvent::MouseButtonRelease, me->pos(),
02038                                                             RightButton, LeftButton + RightButton ) );
02039                                 // Left released, off-widget
02040                                 postEvent( d->presswidget,
02041                                            new QMouseEvent( QEvent::MouseMove, QPoint( -1, -1),
02042                                                             LeftButton, LeftButton ) );
02043                                 postEvent( d->presswidget,
02044                                            new QMouseEvent( QEvent::MouseButtonRelease, QPoint( -1, -1),
02045                                                             LeftButton, LeftButton ) );
02046                                 d->rightpressed = FALSE;
02047                                 return TRUE; // don't send the real Left release
02048                             }
02049                         }
02050                         break;
02051                     default:
02052                         break;
02053                 }
02054                 break;
02055             default:
02056                 ;
02057         }
02058     }
02059     else if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
02060         QKeyEvent *ke = (QKeyEvent *)e;
02061         if ( ke->key() == Key_Enter ) {
02062             if ( o->isA( "QRadioButton" ) || o->isA( "QCheckBox" ) ) {
02063                 postEvent( o, new QKeyEvent( e->type(), Key_Space, ' ',
02064                                              ke->state(), " ", ke->isAutoRepeat(), ke->count() ) );
02065                 return TRUE;
02066             }
02067         }
02068     }
02069     return FALSE;
02070 }
02071 
02075 void QPEApplication::timerEvent( QTimerEvent *e )
02076 {
02077     if ( e->timerId() == d->presstimer && d->presswidget ) {
02078 
02079           // Right pressed
02080           postEvent( d->presswidget,
02081                      new QMouseEvent( QEvent::MouseButtonPress, d->presspos,
02082                                       RightButton, LeftButton ) );
02083           killTimer( d->presstimer );
02084           d->presstimer = 0;
02085           d->rightpressed = TRUE;
02086 #ifdef OPIE_WITHROHFEEDBACK
02087           d->RoH->stop();
02088 #endif
02089     }
02090 }
02091 
02092 void QPEApplication::removeSenderFromStylusDict()
02093 {
02094     stylusDict->remove
02095     ( ( void* ) sender() );
02096     if ( d->presswidget == sender() )
02097         d->presswidget = 0;
02098 }
02099 
02103 bool QPEApplication::keyboardGrabbed() const
02104 {
02105     return d->kbgrabbed;
02106 }
02107 
02108 
02113 void QPEApplication::ungrabKeyboard()
02114 {
02115     ((QPEApplication *) qApp )-> d-> kbgrabbed = false;
02116 }
02117 
02127 void QPEApplication::grabKeyboard()
02128 {
02129     ((QPEApplication *) qApp )-> d-> kbgrabbed = true;
02130 }
02131 
02135 int QPEApplication::exec()
02136 {
02137         d->qcopQok = true;
02138 #ifndef QT_NO_COP
02139     d->sendQCopQ();
02140         if ( !d->keep_running )
02141             processEvents(); // we may have received QCop messages in the meantime.
02142 #endif
02143 
02144     if ( d->keep_running )
02145         //|| d->qpe_main_widget && d->qpe_main_widget->isVisible() )
02146         return QApplication::exec();
02147 
02148 #ifndef QT_NO_COP
02149 
02150     {
02151         QCopEnvelope e( "QPE/System", "closing(QString)" );
02152         e << d->appName;
02153     }
02154 #endif
02155     processEvents();
02156     return 0;
02157 }
02158 
02164 void QPEApplication::tryQuit()
02165 {
02166     if ( activeModalWidget() )
02167         return ; // Inside modal loop or konsole. Too hard to save state.
02168 #ifndef QT_NO_COP
02169 
02170     {
02171         QCopEnvelope e( "QPE/System", "closing(QString)" );
02172         e << d->appName;
02173     }
02174 #endif
02175     if ( d->keep_running )
02176     d->store_widget_rect(d->qpe_main_widget, d->appName);
02177     processEvents();
02178 
02179     quit();
02180 }
02181 
02182 
02189 void QPEApplication::hideOrQuit()
02190 {
02191     if ( d->keep_running )
02192     d->store_widget_rect(d->qpe_main_widget, d->appName);
02193     processEvents();
02194 
02195     // If we are a preloaded application we don't actually quit, so emit
02196     // a System message indicating we're quasi-closing.
02197     if ( d->preloaded && d->qpe_main_widget )
02198 #ifndef QT_NO_COP
02199 
02200     {
02201         QCopEnvelope e("QPE/System", "fastAppHiding(QString)" );
02202         e << d->appName;
02203         d->qpe_main_widget->hide();
02204     }
02205 #endif
02206     else
02207         quit();
02208 }
02209 
02210 #if (__GNUC__ > 2 ) && !defined(_OS_MACX_)
02211 extern "C" void __cxa_pure_virtual();
02212 
02213 void __cxa_pure_virtual()
02214 {
02215     fprintf( stderr, "Pure virtual called\n");
02216     abort();
02217 
02218 }
02219 
02220 #endif
02221 
02222 
02223 #if defined(OPIE_NEW_MALLOC)
02224 
02225 // The libraries with the skiff package (and possibly others) have
02226 // completely useless implementations of builtin new and delete that
02227 // use about 50% of your CPU. Here we revert to the simple libc
02228 // functions.
02229 
02230 void* operator new[]( size_t size )
02231 {
02232     return malloc( size );
02233 }
02234 
02235 void* operator new( size_t size )
02236 {
02237     return malloc( size );
02238 }
02239 
02240 void operator delete[]( void* p )
02241 {
02242     if ( p )
02243         free( p );
02244 }
02245 
02246 void operator delete[]( void* p, size_t /*size*/ )
02247 {
02248     if ( p )
02249         free( p );
02250 }
02251 
02252 
02253 void operator delete( void* p )
02254 {
02255     if ( p )
02256         free( p );
02257 }
02258 
02259 void operator delete( void* p, size_t /*size*/ )
02260 {
02261     if ( p )
02262         free( p );
02263 }
02264 
02265 #endif
02266 
02267 #if ( QT_VERSION <= 230 ) && !defined(SINGLE_APP)
02268 #include <qwidgetlist.h>
02269 #ifdef QWS
02270 #include <qgfx_qws.h>
02271 extern QRect qt_maxWindowRect;
02272 void qt_setMaxWindowRect(const QRect& r )
02273 {
02274     qt_maxWindowRect = qt_screen->mapFromDevice( r,
02275                        qt_screen->mapToDevice( QSize( qt_screen->width(), qt_screen->height() ) ) );
02276     // Re-resize any maximized windows
02277     QWidgetList* l = QApplication::topLevelWidgets();
02278     if ( l ) {
02279         QWidget * w = l->first();
02280         while ( w ) {
02281             if ( w->isVisible() && w->isMaximized() ) {
02282                 w->showMaximized();
02283             }
02284             w = l->next();
02285         }
02286         delete l;
02287     }
02288 }
02289 #endif
02290 #endif

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