summaryrefslogtreecommitdiff
path: root/library/qpeapplication.cpp
Side-by-side diff
Diffstat (limited to 'library/qpeapplication.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/qpeapplication.cpp1597
1 files changed, 1597 insertions, 0 deletions
diff --git a/library/qpeapplication.cpp b/library/qpeapplication.cpp
new file mode 100644
index 0000000..f0a68cf
--- a/dev/null
+++ b/library/qpeapplication.cpp
@@ -0,0 +1,1597 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************/
+#include <stdlib.h>
+#include <unistd.h>
+#include <qfile.h>
+#ifdef Q_WS_QWS
+#ifndef QT_NO_COP
+#if QT_VERSION <= 231
+#define private public
+#define sendLocally processEvent
+#include "qcopenvelope_qws.h"
+#undef private
+#else
+#include "qcopenvelope_qws.h"
+#endif
+#endif
+#include <qwindowsystem_qws.h>
+#endif
+#include <qtextstream.h>
+#include <qpalette.h>
+#include <qbuffer.h>
+#include <qptrdict.h>
+#include <qregexp.h>
+#include <qdir.h>
+#include <qlabel.h>
+#include <qdialog.h>
+#include <qdragobject.h>
+#include <qevent.h>
+#include <qtooltip.h>
+#include <qsignal.h>
+#include "qpeapplication.h"
+#include "qpestyle.h"
+#if QT_VERSION >= 300
+#include <qstylefactory.h>
+#else
+#include <qplatinumstyle.h>
+#include <qwindowsstyle.h>
+#include <qmotifstyle.h>
+#include <qmotifplusstyle.h>
+#include "lightstyle.h"
+#endif
+#include "global.h"
+#include "resource.h"
+#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
+#include "qutfcodec.h"
+#endif
+#include "config.h"
+#include "network.h"
+#include "fontmanager.h"
+#include "power.h"
+#include "alarmserver.h"
+#include "applnk.h"
+#include "qpemenubar.h"
+
+#include <unistd.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
+
+// for setBacklight()
+#if defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
+#include <linux/fb.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+#include <stdlib.h>
+
+
+class QPEApplicationData {
+public:
+ QPEApplicationData() : presstimer(0), presswidget(0), rightpressed(FALSE),
+ kbgrabber(0), kbregrab(FALSE), notbusysent(FALSE), preloaded(FALSE),
+ forceshow(FALSE), nomaximize(FALSE), qpe_main_widget(0),
+ keep_running(TRUE)
+ {
+ qcopq.setAutoDelete(TRUE);
+ }
+
+ int presstimer;
+ QWidget* presswidget;
+ QPoint presspos;
+ bool rightpressed;
+ int kbgrabber;
+ bool kbregrab;
+ bool notbusysent;
+ QString appName;
+ struct QCopRec {
+ QCopRec(const QCString &ch, const QCString &msg,
+ const QByteArray &d) :
+ channel(ch), message(msg), data(d) { }
+
+ QCString channel;
+ QCString message;
+ QByteArray data;
+ };
+ bool preloaded;
+ bool forceshow;
+ bool nomaximize;
+ QWidget* qpe_main_widget;
+ bool keep_running;
+ QList<QCopRec> qcopq;
+
+ void enqueueQCop(const QCString &ch, const QCString &msg,
+ const QByteArray &data)
+ {
+ qcopq.append(new QCopRec(ch,msg,data));
+ }
+ void sendQCopQ()
+ {
+ QCopRec* r;
+ for (QListIterator<QCopRec> it(qcopq); (r=it.current()); ++it)
+ QCopChannel::sendLocally(r->channel,r->message,r->data);
+ qcopq.clear();
+ }
+};
+
+class ResourceMimeFactory : public QMimeSourceFactory {
+public:
+ ResourceMimeFactory()
+ {
+ QStringList path;
+ QString lang = getenv("LANG");
+ if ( !lang.isEmpty() )
+ path += QPEApplication::qpeDir() + "/help/" + lang + "/html";
+ path += QPEApplication::qpeDir() + "/pics";
+ path += QPEApplication::qpeDir() + "/help/en/html";
+ path += QPEApplication::qpeDir() + "/docs";
+ QString dir = QDir::current().canonicalPath();
+ if ( dir == "/" )
+ dir += "/docs";
+ else {
+ path += dir + "/../pics";
+ dir += "/../docs";
+ path += dir;
+ }
+ setFilePath( path );
+ setExtensionType("html","text/html;charset=UTF-8");
+ }
+
+ const QMimeSource* data(const QString& abs_name) const
+ {
+ const QMimeSource* r = QMimeSourceFactory::data(abs_name);
+ if ( !r ) {
+ int sl = abs_name.length();
+ do {
+ sl = abs_name.findRev('/',sl-1);
+ QString name = sl>=0 ? abs_name.mid(sl+1) : abs_name;
+ int dot = name.findRev('.');
+ if ( dot >= 0 )
+ name = name.left(dot);
+ QImage img = Resource::loadImage(name);
+ if ( !img.isNull() )
+ r = new QImageDrag(img);
+ } while (!r && sl>0);
+ }
+ return r;
+ }
+};
+
+static int muted=0;
+
+static void setVolume(int t=0, int percent=-1)
+{
+ switch (t) {
+ case 0: {
+ Config cfg("Sound");
+ cfg.setGroup("System");
+ if ( percent < 0 )
+ percent = cfg.readNumEntry("Volume",50);
+ int fd = 0;
+ if ((fd = open("/dev/mixer", O_RDWR))>=0) {
+ int vol = muted ? 0 : percent;
+ // set both channels to same volume
+ vol |= vol << 8;
+ ioctl(fd, MIXER_WRITE(0), &vol);
+ ::close(fd);
+ }
+ } break;
+ }
+}
+
+int qpe_sysBrightnessSteps()
+{
+#if defined(QT_QWS_IPAQ)
+ return 255;
+#elif defined(QT_QWS_EBX)
+ return 4;
+#else
+ return 255; // ?
+#endif
+}
+
+
+static int& hack(int& i)
+{
+#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
+ // These should be created, but aren't in Qt 2.3.0
+ (void)new QUtf8Codec;
+ (void)new QUtf16Codec;
+#endif
+ return i;
+}
+
+static bool forced_off = FALSE;
+static int curbl=-1;
+
+static int backlight()
+{
+ if ( curbl == -1 ) {
+ // Read from config
+ Config config( "qpe" );
+ config.setGroup( "Screensaver" );
+ curbl = config.readNumEntry("Brightness",255);
+ }
+ return curbl;
+}
+
+static void setBacklight(int bright)
+{
+ if ( bright == -3 ) {
+ // Forced on
+ forced_off = FALSE;
+ bright = -1;
+ }
+ if ( forced_off && bright != -2 )
+ return;
+ if ( bright == -2 ) {
+ // Toggle between off and on
+ bright = curbl ? 0 : -1;
+ forced_off = !bright;
+ }
+ if ( bright == -1 ) {
+ // Read from config
+ Config config( "qpe" );
+ config.setGroup( "Screensaver" );
+ bright = config.readNumEntry("Brightness",255);
+ }
+#if defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
+ if ( QFile::exists("/usr/bin/bl") ) {
+ QString cmd = "/usr/bin/bl 1 ";
+ cmd += bright<=0 ? "0 " : "1 ";
+ cmd += QString::number(bright);
+ system(cmd.latin1());
+#if defined(QT_QWS_EBX)
+ } else if ( QFile::exists("/dev/fl") ) {
+#define FL_IOCTL_STEP_CONTRAST 100
+ int fd = open("/dev/fl", O_WRONLY);
+ if (fd >= 0 ) {
+ int steps = qpe_sysBrightnessSteps();
+ int bl = ( bright * steps + 127 ) / 255;
+ if ( bright && !bl ) bl = 1;
+ bl = ioctl(fd, FL_IOCTL_STEP_CONTRAST, bl);
+ close(fd);
+ }
+ }
+#elif defined(QT_QWS_IPAQ)
+ } else if ( QFile::exists("/dev/ts") || QFile::exists("/dev/h3600_ts") ) {
+ typedef struct {
+ unsigned char mode;
+ unsigned char pwr;
+ unsigned char brightness;
+ } FLITE_IN;
+# ifndef FLITE_ON
+# ifndef _LINUX_IOCTL_H
+# include <linux/ioctl.h>
+# endif
+# define FLITE_ON _IOW('f', 7, FLITE_IN)
+# endif
+ int fd;
+ if ( QFile::exists("/dev/ts") )
+ fd = open("/dev/ts", O_WRONLY);
+ else
+ fd = open("/dev/h3600_ts", O_WRONLY);
+ if (fd >= 0 ) {
+ FLITE_IN bl;
+ bl.mode = 1;
+ bl.pwr = bright ? 1 : 0;
+ bl.brightness = bright;
+ ioctl(fd, FLITE_ON, &bl);
+ close(fd);
+ }
+ }
+#endif
+#endif
+ curbl = bright;
+}
+
+void qpe_setBacklight(int bright) { setBacklight(bright); }
+
+static bool dim_on = FALSE;
+static bool lightoff_on = FALSE;
+static int disable_suspend = 100;
+
+static bool powerOnline()
+{
+ return PowerStatusManager::readStatus().acStatus() == PowerStatus::Online;
+}
+
+static bool networkOnline()
+{
+ return Network::networkOnline();
+}
+
+class QPEScreenSaver : public QWSScreenSaver
+{
+
+public:
+ QPEScreenSaver()
+ {
+ }
+ void restore()
+ {
+ setBacklight(-1);
+ }
+ bool save(int level)
+ {
+ switch ( level ) {
+ case 0:
+ if ( disable_suspend > 0 && dim_on ) {
+ if (backlight() > 1)
+ setBacklight(1); // lowest non-off
+ }
+ return TRUE;
+ break;
+ case 1:
+ if ( disable_suspend > 1 && lightoff_on ) {
+ setBacklight(0); // off
+ }
+ return TRUE;
+ break;
+ case 2:
+ if ( disable_suspend > 2 && !powerOnline() && !networkOnline() ) {
+ QWSServer::sendKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE );
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+ }
+};
+
+static int ssi(int interval, Config &config, const QString &enable, const QString& value, int def)
+{
+ if ( !enable.isEmpty() && config.readNumEntry(enable,0) == 0 )
+ return 0;
+
+ if ( interval < 0 ) {
+ // Restore screen blanking and power saving state
+ interval = config.readNumEntry( value, def );
+ }
+ return interval;
+}
+
+static void setScreenSaverIntervals(int i1, int i2, int i3)
+{
+ Config config( "qpe" );
+ config.setGroup( "Screensaver" );
+
+ int v[4];
+ i1 = ssi(i1, config, "Dim","Interval_Dim", 30);
+ i2 = ssi(i2, config, "LightOff","Interval_LightOff", 20);
+ i3 = ssi(i3, config, "","Interval", 60);
+
+ //qDebug("screen saver intervals: %d %d %d", i1, i2, i3);
+
+ v[0] = QMAX( 1000*i1, 100);
+ v[1] = QMAX( 1000*i2, 100);
+ v[2] = QMAX( 1000*i3, 100);
+ v[3] = 0;
+ dim_on = ( (i1 != 0) ? config.readNumEntry("Dim",1) : FALSE );
+ lightoff_on = ( (i2 != 0 ) ? config.readNumEntry("LightOff",1) : FALSE );
+ if ( !i1 && !i2 && !i3 )
+ QWSServer::setScreenSaverInterval(0);
+ else
+ QWSServer::setScreenSaverIntervals(v);
+}
+
+static void setScreenSaverInterval(int interval)
+{
+ setScreenSaverIntervals(-1,-1,interval);
+}
+
+
+/*!
+ \class QPEApplication qpeapplication.h
+ \brief The QPEApplication class implements various system services
+ that are available to all Qtopia applications.
+
+ Simply by using QPEApplication instead of QApplication, a plain Qt
+ application becomes a Qtopia application. It automatically follows
+ style changes, quits and raises, and in the
+ case of \link docwidget.html document-oriented\endlink applications,
+ changes the current displayed document in response to the environment.
+*/
+
+/*!
+ \fn void QPEApplication::clientMoused()
+
+ \internal
+*/
+
+/*!
+ \fn void QPEApplication::timeChanged();
+
+ This signal is emitted when the time jumps forward or backwards
+ by more than the normal passage of time.
+*/
+
+/*!
+ \fn void QPEApplication::clockChanged( bool ampm );
+
+ This signal is emitted when the user changes the style
+ of clock. If \a ampm is TRUE, the user wants a 12-hour
+ AM/PM close, otherwise, they want a 24-hour clock.
+*/
+
+/*!
+ \fn void QPEApplication::appMessage( const QCString& msg, const QByteArray& data )
+
+ This signal is emitted when a message is received on the
+ QPE/Application/<i>appname</i> QCop channel for this application.
+
+ The slot to which you connect this signal uses \a msg and \a data
+ in the following way:
+
+\code
+ void MyWidget::receive( const QCString& msg, const QByteArray& data )
+ {
+ QDataStream stream( data, IO_ReadOnly );
+ if ( msg == "someMessage(int,int,int)" ) {
+ int a,b,c;
+ stream >> a >> b >> c;
+ ...
+ } else if ( msg == "otherMessage(QString)" ) {
+ ...
+ }
+ }
+\endcode
+
+ \sa qcop.html
+*/
+
+/*!
+ Constructs a QPEApplication just as you would construct
+ a QApplication, passing \a argc, \a argv, and \a t.
+*/
+QPEApplication::QPEApplication( int& argc, char **argv, Type t )
+ : QApplication( hack(argc), argv, t )
+{
+ int dw = desktop()->width();
+ if ( dw < 200 ) {
+ setFont( QFont( "helvetica", 8 ) );
+ AppLnk::setSmallIconSize(10);
+ AppLnk::setBigIconSize(28);
+ }
+
+ d = new QPEApplicationData;
+ QMimeSourceFactory::setDefaultFactory(new ResourceMimeFactory);
+
+ connect(this, SIGNAL(lastWindowClosed()), this, SLOT(hideOrQuit()));
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+
+ QString qcopfn("/tmp/qcop-msg-");
+ qcopfn += QString(argv[0]); // append command name
+
+ QFile f(qcopfn);
+ if ( f.open(IO_ReadOnly) ) {
+ flock(f.handle(), LOCK_EX);
+ }
+
+ sysChannel = new QCopChannel( "QPE/System", this );
+ connect( sysChannel, SIGNAL(received(const QCString &, const QByteArray &)),
+ this, SLOT(systemMessage( const QCString &, const QByteArray &)) );
+
+ QCString channel = QCString(argv[0]);
+ channel.replace(QRegExp(".*/"),"");
+ d->appName = channel;
+ channel = "QPE/Application/" + channel;
+ pidChannel = new QCopChannel( channel, this);
+ connect( pidChannel, SIGNAL(received(const QCString &, const QByteArray &)),
+ this, SLOT(pidMessage(const QCString &, const QByteArray &)));
+
+ if ( f.isOpen() ) {
+ d->keep_running = FALSE;
+ QDataStream ds(&f);
+ QCString channel, message;
+ QByteArray data;
+ while(!ds.atEnd()) {
+ ds >> channel >> message >> data;
+ d->enqueueQCop(channel,message,data);
+ }
+
+ flock(f.handle(), LOCK_UN);
+ f.close();
+ f.remove();
+ }
+
+ for (int a=0; a<argc; a++) {
+ if ( qstrcmp(argv[a],"-preload")==0 ) {
+ argv[a] = argv[a+1];
+ a++;
+ d->preloaded = TRUE;
+ argc-=1;
+ } else if ( qstrcmp(argv[a],"-preload-show")==0 ) {
+ argv[a] = argv[a+1];
+ a++;
+ d->preloaded = TRUE;
+ d->forceshow = TRUE;
+ argc-=1;
+ }
+ }
+
+ /* overide stored arguments */
+ setArgs(argc, argv);
+
+#endif
+
+ qwsSetDecoration( new QPEDecoration() );
+
+#ifndef QT_NO_TRANSLATION
+ char *l = getenv( "LANG" );
+ QString lang;
+ if ( l ) {
+ lang = l;
+
+ /*
+ Config config("qpe");
+ config.setGroup( "Appearance" );
+ lang = config.readEntry( "Language", lang );
+ */
+
+ QTranslator * trans = new QTranslator(this);
+ QString tfn = qpeDir()+"/i18n/"+lang+"/"+d->appName+".qm";
+ if ( trans->load( tfn ))
+ installTranslator( trans );
+ else
+ delete trans;
+
+ trans = new QTranslator(this);
+ tfn = qpeDir()+"/i18n/"+lang+"/libqpe.qm";
+ if ( trans->load( tfn ))
+ installTranslator( trans );
+ else
+ delete trans;
+
+ //###language/font hack; should look it up somewhere
+ if ( lang == "ja" || lang == "zh_CN" || lang == "zh_TW" || lang == "ko" ) {
+ QFont fn = FontManager::unicodeFont( FontManager::Proportional );
+ setFont( fn );
+ }
+ }
+#endif
+
+ applyStyle();
+
+ if ( type() == GuiServer ) {
+ setScreenSaverInterval(-1);
+ setVolume();
+ QWSServer::setScreenSaver(new QPEScreenSaver);
+ }
+
+ installEventFilter( this );
+
+ QPEMenuToolFocusManager::initialize();
+
+#ifdef QT_NO_QWS_CURSOR
+ // if we have no cursor, probably don't want tooltips
+ QToolTip::setEnabled( FALSE );
+#endif
+}
+
+static QPtrDict<void>* inputMethodDict=0;
+static void createInputMethodDict()
+{
+ if ( !inputMethodDict )
+ inputMethodDict = new QPtrDict<void>;
+}
+
+/*!
+ Returns the currently set hint to the system as to whether
+ \a w has any use for text input methods.
+
+ \sa setInputMethodHint()
+*/
+QPEApplication::InputMethodHint QPEApplication::inputMethodHint( QWidget* w )
+{
+ if ( inputMethodDict && w )
+ return (InputMethodHint)(int)inputMethodDict->find(w);
+ return Normal;
+}
+
+/*!
+ \enum QPEApplication::InputMethodHint
+
+ \value Normal the application sometimes needs text input (the default).
+ \value AlwaysOff the application never needs text input.
+ \value AlwaysOn the application always needs text input.
+*/
+
+/*!
+ Hints to the system that \a w has use for text input methods
+ as specified by \a mode.
+
+ \sa inputMethodHint()
+*/
+void QPEApplication::setInputMethodHint( QWidget* w, InputMethodHint mode )
+{
+ createInputMethodDict();
+ if ( mode == Normal ) {
+ inputMethodDict->remove(w);
+ } else {
+ inputMethodDict->insert(w,(void*)mode);
+ }
+}
+
+class HackDialog : public QDialog
+{
+public:
+ void acceptIt() { accept(); }
+ void rejectIt() { reject(); }
+};
+
+
+void QPEApplication::mapToDefaultAction( QWSKeyEvent *ke, int key )
+{
+ // specialised actions for certain widgets. May want to
+ // add more stuff here.
+ if ( activePopupWidget() && activePopupWidget()->inherits( "QListBox" )
+ && activePopupWidget()->parentWidget()
+ && activePopupWidget()->parentWidget()->inherits( "QComboBox" ) )
+ key = Qt::Key_Return;
+
+ if ( activePopupWidget() && activePopupWidget()->inherits( "QPopupMenu" ) )
+ key = Qt::Key_Return;
+
+ ke->simpleData.keycode = key;
+}
+
+class HackWidget : public QWidget
+{
+public:
+ bool needsOk()
+ { return (getWState() & WState_Reserved1 ); }
+};
+
+/*!
+ \internal
+*/
+bool QPEApplication::qwsEventFilter( QWSEvent *e )
+{
+ if ( !d->notbusysent && e->type == QWSEvent::Focus ) {
+ if ( qApp->type() != QApplication::GuiServer ) {
+ QCopEnvelope e("QPE/System", "notBusy(QString)" );
+ e << d->appName;
+ }
+ d->notbusysent=TRUE;
+ }
+ if ( type() == GuiServer ) {
+ switch ( e->type ) {
+ case QWSEvent::Mouse:
+ if ( e->asMouse()->simpleData.state && !QWidget::find(e->window()) )
+ emit clientMoused();
+ }
+ }
+ if ( e->type == QWSEvent::Key ) {
+ if ( d->kbgrabber == 1 )
+ return TRUE;
+ QWSKeyEvent *ke = (QWSKeyEvent *)e;
+ if ( ke->simpleData.keycode == Qt::Key_F33 ) {
+ // Use special "OK" key to press "OK" on top level widgets
+ QWidget *active = activeWindow();
+ QWidget *popup = 0;
+ if ( active && active->isPopup() ) {
+ popup = active;
+ active = active->parentWidget();
+ }
+ if ( active && (int)active->winId() == ke->simpleData.window &&
+ !active->testWFlags( WStyle_Customize|WType_Popup|WType_Desktop )) {
+ if ( ke->simpleData.is_press ) {
+ if ( popup )
+ popup->close();
+ if ( active->inherits( "QDialog" ) ) {
+ HackDialog *d = (HackDialog *)active;
+ d->acceptIt();
+ return TRUE;
+ } else if ( ((HackWidget *)active)->needsOk() ) {
+ QSignal s;
+ s.connect( active, SLOT( accept() ) );
+ s.activate();
+ } else {
+ // do the same as with the select key: Map to the default action of the widget:
+ mapToDefaultAction( ke, Qt::Key_Return );
+ }
+ }
+ }
+ } else if ( ke->simpleData.keycode == Qt::Key_F30 ) {
+ // Use special "select" key to do whatever default action a widget has
+ mapToDefaultAction( ke, Qt::Key_Space );
+ } else if ( ke->simpleData.keycode == Qt::Key_Escape &&
+ ke->simpleData.is_press ) {
+ // Escape key closes app if focus on toplevel
+ QWidget *active = activeWindow();
+ if ( active && active->testWFlags( WType_TopLevel ) &&
+ (int)active->winId() == ke->simpleData.window &&
+ !active->testWFlags( WStyle_Dialog|WStyle_Customize|WType_Popup|WType_Desktop )) {
+ if ( active->inherits( "QDialog" ) ) {
+ HackDialog *d = (HackDialog *)active;
+ d->rejectIt();
+ return TRUE;
+ } else if ( strcmp( argv()[0], "embeddedkonsole") != 0 ) {
+ active->close();
+ }
+ }
+ }
+
+#if QT_VERSION < 231
+ // Filter out the F4/Launcher key from apps
+ // ### The launcher key may not always be F4 on all devices
+ if ( ((QWSKeyEvent *)e)->simpleData.keycode == Qt::Key_F4 )
+ return TRUE;
+#endif
+ }
+ if ( e->type == QWSEvent::Focus ) {
+ QWSFocusEvent *fe = (QWSFocusEvent*)e;
+ QWidget* nfw = QWidget::find(e->window());
+ if ( !fe->simpleData.get_focus ) {
+ QWidget *active = activeWindow();
+ while ( active && active->isPopup() ) {
+ active->close();
+ active = activeWindow();
+ }
+ if ( !nfw && d->kbgrabber == 2 ) {
+ ungrabKeyboard();
+ d->kbregrab = TRUE; // want kb back when we're active
+ }
+ } else {
+ // make sure our modal widget is ALWAYS on top
+ QWidget *topm = activeModalWidget();
+ if ( topm ) {
+ topm->raise();
+ }
+ if ( d->kbregrab ) {
+ grabKeyboard();
+ d->kbregrab = FALSE;
+ }
+ }
+ if ( fe->simpleData.get_focus && inputMethodDict ) {
+ InputMethodHint m = inputMethodHint( QWidget::find(e->window()) );
+ if ( m == AlwaysOff )
+ Global::hideInputMethod();
+ if ( m == AlwaysOn )
+ Global::showInputMethod();
+ }
+ }
+ return QApplication::qwsEventFilter( e );
+}
+
+/*!
+ Destroys the QPEApplication.
+*/
+QPEApplication::~QPEApplication()
+{
+ ungrabKeyboard();
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+ // Need to delete QCopChannels early, since the display will
+ // be gone by the time we get to ~QObject().
+ delete sysChannel;
+ delete pidChannel;
+#endif
+ delete d;
+}
+
+/*!
+ Returns <tt>$QPEDIR/</tt>.
+*/
+QString QPEApplication::qpeDir()
+{
+ const char *base = getenv( "QPEDIR" );
+ if ( base )
+ return QString( base ) + "/";
+
+ return QString( "../" );
+}
+
+/*!
+ Returns the user's current Document directory. There is a trailing "/".
+*/
+QString QPEApplication::documentDir()
+{
+ const char *base = getenv( "HOME" );
+ if ( base )
+ return QString( base ) + "/Documents/";
+
+ return QString( "../Documents/" );
+}
+
+static int deforient=-1;
+
+/*!
+ \internal
+*/
+int QPEApplication::defaultRotation()
+{
+ if ( deforient < 0 ) {
+ QString d = getenv("QWS_DISPLAY");
+ if ( d.contains("Rot90") ) {
+ deforient = 90;
+ } else if ( d.contains("Rot180") ) {
+ deforient = 180;
+ } else if ( d.contains("Rot270") ) {
+ deforient = 270;
+ } else {
+ deforient=0;
+ }
+ }
+ return deforient;
+}
+
+/*!
+ \internal
+*/
+void QPEApplication::setDefaultRotation(int r)
+{
+ if ( qApp->type() == GuiServer ) {
+ deforient = r;
+ setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(r).latin1(), 1);
+ } else {
+ QCopEnvelope("QPE/System", "setDefaultRotation(int)") << r;
+ }
+}
+
+/*!
+ \internal
+*/
+void QPEApplication::applyStyle()
+{
+ Config config( "qpe" );
+
+ config.setGroup( "Appearance" );
+
+ // Widget style
+ QString style = config.readEntry( "Style", "Light" );
+ internalSetStyle( style );
+
+ // Colors
+ QColor bgcolor( config.readEntry( "Background", "#E5E1D5" ) );
+ QColor btncolor( config.readEntry( "Button", "#D6CDBB" ) );
+ QPalette pal( btncolor, bgcolor );
+ QString color = config.readEntry( "Highlight", "#800000" );
+ pal.setColor( QColorGroup::Highlight, QColor(color) );
+ color = config.readEntry( "HighlightedText", "#FFFFFF" );
+ pal.setColor( QColorGroup::HighlightedText, QColor(color) );
+ color = config.readEntry( "Text", "#000000" );
+ pal.setColor( QColorGroup::Text, QColor(color) );
+ color = config.readEntry( "ButtonText", "#000000" );
+ pal.setColor( QPalette::Active, QColorGroup::ButtonText, QColor(color) );
+ color = config.readEntry( "Base", "#FFFFFF" );
+ pal.setColor( QColorGroup::Base, QColor(color) );
+
+ pal.setColor( QPalette::Disabled, QColorGroup::Text,
+ pal.color(QPalette::Active, QColorGroup::Background).dark() );
+
+ setPalette( pal, TRUE );
+}
+
+void QPEApplication::systemMessage( const QCString &msg, const QByteArray &data)
+{
+#ifdef Q_WS_QWS
+ QDataStream stream( data, IO_ReadOnly );
+ if ( msg == "applyStyle()" ) {
+ applyStyle();
+ } else if ( msg == "setScreenSaverInterval(int)" ) {
+ if ( type() == GuiServer ) {
+ int time;
+ stream >> time;
+ setScreenSaverInterval(time);
+ }
+ } else if ( msg == "setScreenSaverIntervals(int,int,int)" ) {
+ if ( type() == GuiServer ) {
+ int t1,t2,t3;
+ stream >> t1 >> t2 >> t3;
+ setScreenSaverIntervals(t1,t2,t3);
+ }
+ } else if ( msg == "setBacklight(int)" ) {
+ if ( type() == GuiServer ) {
+ int bright;
+ stream >> bright;
+ setBacklight(bright);
+ }
+ } else if ( msg == "setDefaultRotation(int)" ) {
+ if ( type() == GuiServer ) {
+ int r;
+ stream >> r;
+ setDefaultRotation(r);
+ }
+ } else if ( msg == "shutdown()" ) {
+ if ( type() == GuiServer )
+ shutdown();
+ } else if ( msg == "quit()" ) {
+ if ( type() != GuiServer )
+ tryQuit();
+ } else if ( msg == "forceQuit()" ) {
+ if ( type() != GuiServer )
+ quit();
+ } else if ( msg == "restart()" ) {
+ if ( type() == GuiServer )
+ restart();
+ } else if ( msg == "grabKeyboard(QString)" ) {
+ QString who;
+ stream >> who;
+ if ( who.isEmpty() )
+ d->kbgrabber = 0;
+ else if ( who != d->appName )
+ d->kbgrabber = 1;
+ else
+ d->kbgrabber = 2;
+ } else if ( msg == "language(QString)" ) {
+ if ( type() == GuiServer ) {
+ QString l;
+ stream >> l;
+ QString cl = getenv("LANG");
+ if ( cl != l ) {
+ if ( l.isNull() )
+ unsetenv( "LANG" );
+ else
+ setenv( "LANG", l.latin1(), 1 );
+ restart();
+ }
+ }
+ } else if ( msg == "timeChange(QString)" ) {
+ QString t;
+ stream >> t;
+ if ( t.isNull() )
+ unsetenv( "TZ" );
+ else
+ setenv( "TZ", t.latin1(), 1 );
+ // emit the signal so everyone else knows...
+ emit timeChanged();
+ } else if ( msg == "execute(QString)" ) {
+ if ( type() == GuiServer ) {
+ QString t;
+ stream >> t;
+ Global::execute( t );
+ }
+ } else if ( msg == "execute(QString,QString)" ) {
+ if ( type() == GuiServer ) {
+ QString t,d;
+ stream >> t >> d;
+ Global::execute( t, d );
+ }
+ } else if ( msg == "addAlarm(QDateTime,QCString,QCString,int)" ) {
+ if ( type() == GuiServer ) {
+ QDateTime when;
+ QCString channel, message;
+ int data;
+ stream >> when >> channel >> message >> data;
+ AlarmServer::addAlarm( when, channel, message, data );
+ }
+ } else if ( msg == "deleteAlarm(QDateTime,QCString,QCString,int)" ) {
+ if ( type() == GuiServer ) {
+ QDateTime when;
+ QCString channel, message;
+ int data;
+ stream >> when >> channel >> message >> data;
+ AlarmServer::deleteAlarm( when, channel, message, data );
+ }
+ } else if ( msg == "clockChange(bool)" ) {
+ int tmp;
+ stream >> tmp;
+ emit clockChanged( tmp );
+ } else if ( msg == "weekChange(bool)" ) {
+ int tmp;
+ stream >> tmp;
+ emit weekChanged( tmp );
+ } else if ( msg == "setDateFormat(DateFormat)" ) {
+ DateFormat tmp;
+ stream >> tmp;
+ emit dateFormatChanged( tmp );
+ } else if ( msg == "setVolume(int,int)" ) {
+ int t,v;
+ stream >> t >> v;
+ setVolume(t,v);
+ emit volumeChanged( muted );
+ } else if ( msg == "volumeChange(bool)" ) {
+ stream >> muted;
+ setVolume();
+ emit volumeChanged( muted );
+ } else if ( msg == "setScreenSaverMode(int)" ) {
+ if ( type() == GuiServer ) {
+ int old = disable_suspend;
+ stream >> disable_suspend;
+ //qDebug("setScreenSaverMode(%d)", disable_suspend );
+ if ( disable_suspend > old )
+ setScreenSaverInterval( -1 );
+ }
+ }
+#endif
+}
+
+/*!
+ \internal
+*/
+bool QPEApplication::raiseAppropriateWindow()
+{
+ bool r=FALSE;
+ // ########## raise()ing main window should raise and set active
+ // ########## it and then all childen. This belongs in Qt/Embedded
+ QWidget *top = d->qpe_main_widget;
+ if ( !top ) top =mainWidget();
+ if ( top && d->keep_running ) {
+ if ( top->isVisible() )
+ r = TRUE;
+#ifdef Q_WS_QWS
+ if ( !d->nomaximize )
+ top->showMaximized();
+ else
+#endif
+ top->show();
+ top->raise();
+ top->setActiveWindow();
+ }
+ QWidget *topm = activeModalWidget();
+ if ( topm && topm != top ) {
+ topm->show();
+ topm->raise();
+ topm->setActiveWindow();
+ r = FALSE;
+ }
+ return r;
+}
+
+void QPEApplication::pidMessage( const QCString &msg, const QByteArray & data)
+{
+#ifdef Q_WS_QWS
+
+ if ( msg == "quit()" ) {
+ tryQuit();
+ } else if ( msg == "quitIfInvisible()" ) {
+ if ( d->qpe_main_widget && !d->qpe_main_widget->isVisible() )
+ quit();
+ } else if ( msg == "close()" ) {
+ hideOrQuit();
+ } else if ( msg == "disablePreload()" ) {
+ d->preloaded = FALSE;
+ d->keep_running = TRUE;
+ /* so that quit will quit */
+ } else if ( msg == "enablePreload()" ) {
+ d->preloaded = TRUE;
+ d->keep_running = TRUE;
+ /* so next quit won't quit */
+ } else if ( msg == "raise()" ) {
+ d->keep_running = TRUE;
+ d->notbusysent = FALSE;
+ raiseAppropriateWindow();
+ } else if ( msg == "flush()" ) {
+ emit flush();
+ // we need to tell the desktop
+ QCopEnvelope e( "QPE/Desktop", "flushDone(QString)" );
+ e << d->appName;
+ } else if ( msg == "reload()" ) {
+ emit reload();
+ } else if ( msg == "setDocument(QString)" ) {
+ d->keep_running = TRUE;
+ QDataStream stream( data, IO_ReadOnly );
+ QString doc;
+ stream >> doc;
+ QWidget *mw = mainWidget();
+ if ( !mw )
+ mw = d->qpe_main_widget;
+ if ( mw )
+ Global::setDocument( mw, doc );
+ } else if ( msg == "nextView()" ) {
+ if ( raiseAppropriateWindow() )
+ emit appMessage( msg, data);
+ } else {
+ emit appMessage( msg, data);
+ }
+#endif
+}
+
+
+static bool setWidgetCaptionFromAppName( QWidget* /*mw*/, const QString& /*appName*/, const QString& /*appsPath*/ )
+{
+/*
+ // This works but disable it for now until it is safe to apply
+ // What is does is scan the .desktop files of all the apps for
+ // the applnk that has the corresponding argv[0] as this program
+ // then it uses the name stored in the .desktop file as the caption
+ // for the main widget. This saves duplicating translations for
+ // the app name in the program and in the .desktop files.
+
+ AppLnkSet apps( appsPath );
+
+ QList<AppLnk> appsList = apps.children();
+ for ( QListIterator<AppLnk> it(appsList); it.current(); ++it ) {
+ if ( (*it)->exec() == appName ) {
+ mw->setCaption( (*it)->name() );
+ return TRUE;
+ }
+ }
+*/
+ return FALSE;
+}
+
+
+/*!
+ Sets \a mw as the mainWidget() and shows it. For small windows,
+ consider passing TRUE for \a nomaximize rather than the default FALSE.
+
+ \sa showMainDocumentWidget()
+*/
+void QPEApplication::showMainWidget( QWidget* mw, bool nomaximize )
+{
+ setWidgetCaptionFromAppName( mw, d->appName, qpeDir() + "apps" );
+
+ d->nomaximize = nomaximize;
+ d->qpe_main_widget = mw;
+ d->sendQCopQ();
+ if ( d->preloaded ) {
+ if(d->forceshow) {
+#ifdef Q_WS_QWS
+ if ( !nomaximize )
+ mw->showMaximized();
+ else
+#endif
+ mw->show();
+ }
+ } else if ( d->keep_running ) {
+#ifdef Q_WS_QWS
+ if ( !nomaximize )
+ mw->showMaximized();
+ else
+#endif
+ mw->show();
+ }
+}
+
+/*!
+ Sets \a mw as the mainWidget() and shows it. For small windows,
+ consider passing TRUE for \a nomaximize rather than the default FALSE.
+
+ This calls designates the application as
+ a \link docwidget.html document-oriented\endlink application.
+
+ The \a mw widget must have a slot: setDocument(const QString&).
+
+ \sa showMainWidget()
+*/
+void QPEApplication::showMainDocumentWidget( QWidget* mw, bool nomaximize )
+{
+ setWidgetCaptionFromAppName( mw, d->appName, qpeDir() + "apps" );
+
+ if ( mw && argc() == 2 )
+ Global::setDocument( mw, QString::fromUtf8(argv()[1]) );
+ d->nomaximize = nomaximize;
+ d->qpe_main_widget = mw;
+ d->sendQCopQ();
+ if ( d->preloaded ) {
+ if(d->forceshow) {
+#ifdef Q_WS_QWS
+ if ( !nomaximize )
+ mw->showMaximized();
+ else
+#endif
+ mw->show();
+ }
+ } else if ( d->keep_running ) {
+#ifdef Q_WS_QWS
+ if ( !nomaximize )
+ mw->showMaximized();
+ else
+#endif
+ mw->show();
+ }
+}
+
+
+/*!
+ Sets that the application should continue running after processing
+ qcop messages. Normally if an application is started via a qcop message,
+ the application will process the qcop message and then quit. If while
+ processing the qcop message it calls this function, then the application
+ will show and start proper once it has finished processing qcop messages.
+
+ \sa keepRunning()
+*/
+void QPEApplication::setKeepRunning()
+{
+ if ( qApp && qApp->inherits( "QPEApplication" ) ) {
+ QPEApplication *qpeApp = (QPEApplication*)qApp;
+ qpeApp->d->keep_running = TRUE;
+ }
+}
+
+/*!
+ Returns whether the application will quit after processing the current
+ list of qcop messages.
+
+ \sa setKeepRunning()
+*/
+bool QPEApplication::keepRunning() const
+{
+ return d->keep_running;
+}
+
+/*!
+ \internal
+*/
+void QPEApplication::internalSetStyle( const QString &style )
+{
+#if QT_VERSION >= 300
+ if ( style == "QPE" ) {
+ setStyle( new QPEStyle );
+ } else {
+ QStyle *s = QStyleFactory::create(style);
+ if ( s ) setStyle(s);
+ }
+#else
+ if ( style == "Windows" ) {
+ setStyle( new QWindowsStyle );
+ } else if ( style == "QPE" ) {
+ setStyle( new QPEStyle );
+ } else if ( style == "Light" ) {
+ setStyle( new LightStyle );
+ }
+#ifndef QT_NO_STYLE_PLATINUM
+ else if ( style == "Platinum" ) {
+ setStyle( new QPlatinumStyle );
+ }
+#endif
+#ifndef QT_NO_STYLE_MOTIF
+ else if ( style == "Motif" ) {
+ setStyle( new QMotifStyle );
+ }
+#endif
+#ifndef QT_NO_STYLE_MOTIFPLUS
+ else if ( style == "MotifPlus" ) {
+ setStyle( new QMotifPlusStyle );
+ }
+#endif
+#endif
+}
+
+/*!
+ \internal
+*/
+void QPEApplication::prepareForTermination(bool willrestart)
+{
+ if ( willrestart ) {
+ // Draw a big wait icon, the image can be altered in later revisions
+// QWidget *d = QApplication::desktop();
+ QImage img = Resource::loadImage( "wait" );
+ QPixmap pix;
+ pix.convertFromImage(img.smoothScale(3*img.width(), 3*img.height()));
+ QLabel *lblWait = new QLabel(0, "wait hack!", QWidget::WStyle_Customize |
+ QWidget::WStyle_NoBorder | QWidget::WStyle_Tool );
+ lblWait->setPixmap( pix );
+ lblWait->setAlignment( QWidget::AlignCenter );
+ lblWait->show();
+ lblWait->showMaximized();
+ }
+#ifndef SINGLE_APP
+ { QCopEnvelope envelope("QPE/System", "forceQuit()"); }
+ processEvents(); // ensure the message goes out.
+ sleep(1); // You have 1 second to comply.
+#endif
+}
+
+/*!
+ \internal
+*/
+void QPEApplication::shutdown()
+{
+ // Implement in server's QPEApplication subclass
+}
+
+/*!
+ \internal
+*/
+void QPEApplication::restart()
+{
+ // Implement in server's QPEApplication subclass
+}
+
+static QPtrDict<void>* stylusDict=0;
+static void createDict()
+{
+ if ( !stylusDict )
+ stylusDict = new QPtrDict<void>;
+}
+
+/*!
+ Returns the current StylusMode for \a w.
+
+ \sa setStylusOperation()
+*/
+QPEApplication::StylusMode QPEApplication::stylusOperation( QWidget* w )
+{
+ if ( stylusDict )
+ return (StylusMode)(int)stylusDict->find(w);
+ return LeftOnly;
+}
+
+/*!
+ \enum QPEApplication::StylusMode
+
+ \value LeftOnly the stylus only generates LeftButton
+ events (the default).
+ \value RightOnHold the stylus generates RightButton events
+ if the user uses the press-and-hold gesture.
+
+ See setStylusOperation().
+*/
+
+/*!
+ Causes \a w to receive mouse events according to \a mode.
+
+ \sa stylusOperation()
+*/
+void QPEApplication::setStylusOperation( QWidget* w, StylusMode mode )
+{
+ createDict();
+ if ( mode == LeftOnly ) {
+ stylusDict->remove(w);
+ w->removeEventFilter(qApp);
+ } else {
+ stylusDict->insert(w,(void*)mode);
+ connect(w,SIGNAL(destroyed()),qApp,SLOT(removeSenderFromStylusDict()));
+ w->installEventFilter(qApp);
+ }
+}
+
+
+/*!
+ \reimp
+*/
+bool QPEApplication::eventFilter( QObject *o, QEvent *e )
+{
+ if ( stylusDict && e->type() >= QEvent::MouseButtonPress && e->type() <= QEvent::MouseMove ) {
+ QMouseEvent* me = (QMouseEvent*)e;
+ if ( me->button() == LeftButton ) {
+ StylusMode mode = (StylusMode)(int)stylusDict->find(o);
+ switch (mode) {
+ case RightOnHold:
+ switch ( me->type() ) {
+ case QEvent::MouseButtonPress:
+ d->presstimer = startTimer(500); // #### pref.
+ d->presswidget = (QWidget*)o;
+ d->presspos = me->pos();
+ d->rightpressed = FALSE;
+ break;
+ case QEvent::MouseButtonRelease:
+ if ( d->presstimer ) {
+ killTimer(d->presstimer);
+ d->presstimer = 0;
+ }
+ if ( d->rightpressed && d->presswidget ) {
+ // Right released
+ postEvent( d->presswidget,
+ new QMouseEvent( QEvent::MouseButtonRelease, me->pos(),
+ RightButton, LeftButton+RightButton ) );
+ // Left released, off-widget
+ postEvent( d->presswidget,
+ new QMouseEvent( QEvent::MouseMove, QPoint(-1,-1),
+ LeftButton, LeftButton ) );
+ postEvent( d->presswidget,
+ new QMouseEvent( QEvent::MouseButtonRelease, QPoint(-1,-1),
+ LeftButton, LeftButton ) );
+ d->rightpressed = FALSE;
+ return TRUE; // don't send the real Left release
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ } else if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
+ QKeyEvent *ke = (QKeyEvent *)e;
+ if ( ke->key() == Key_Enter ) {
+ if ( o->isA( "QRadioButton" ) || o->isA( "QCheckBox" ) ) {
+ postEvent( o, new QKeyEvent( e->type(), Key_Space, ' ',
+ ke->state(), " ", ke->isAutoRepeat(), ke->count() ) );
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/*!
+ \reimp
+*/
+void QPEApplication::timerEvent( QTimerEvent *e )
+{
+ if ( e->timerId() == d->presstimer && d->presswidget ) {
+ // Right pressed
+ postEvent( d->presswidget,
+ new QMouseEvent( QEvent::MouseButtonPress, d->presspos,
+ RightButton, LeftButton ) );
+ killTimer( d->presstimer );
+ d->presstimer = 0;
+ d->rightpressed = TRUE;
+ }
+}
+
+void QPEApplication::removeSenderFromStylusDict()
+{
+ stylusDict->remove((void*)sender());
+ if ( d->presswidget == sender() )
+ d->presswidget = 0;
+}
+
+/*!
+ \internal
+*/
+bool QPEApplication::keyboardGrabbed() const
+{
+ return d->kbgrabber;
+}
+
+
+/*!
+ Reverses the effect of grabKeyboard(). This is called automatically
+ on program exit.
+*/
+void QPEApplication::ungrabKeyboard()
+{
+ QPEApplicationData* d = ((QPEApplication*)qApp)->d;
+ if ( d->kbgrabber == 2 ) {
+ QCopEnvelope e("QPE/System", "grabKeyboard(QString)" );
+ e << QString::null;
+ d->kbregrab = FALSE;
+ d->kbgrabber = 0;
+ }
+}
+
+/*!
+ Grabs the keyboard such that the system's application launching
+ keys no longer work, and instead they are receivable by this
+ application.
+
+ \sa ungrabKeyboard()
+*/
+void QPEApplication::grabKeyboard()
+{
+ QPEApplicationData* d = ((QPEApplication*)qApp)->d;
+ if ( qApp->type() == QApplication::GuiServer )
+ d->kbgrabber = 0;
+ else {
+ QCopEnvelope e("QPE/System", "grabKeyboard(QString)" );
+ e << d->appName;
+ d->kbgrabber = 2; // me
+ }
+}
+
+/*!
+ \reimp
+*/
+int QPEApplication::exec()
+{
+ d->sendQCopQ();
+ if ( d->keep_running)
+ //|| d->qpe_main_widget && d->qpe_main_widget->isVisible() )
+ return QApplication::exec();
+
+ {
+ QCopEnvelope e("QPE/System", "closing(QString)" );
+ e << d->appName;
+ }
+ processEvents();
+ return 0;
+}
+
+/*!
+ \internal
+ External request for application to quit. Quits if possible without
+ loosing state.
+*/
+void QPEApplication::tryQuit()
+{
+ if ( activeModalWidget() || strcmp( argv()[0], "embeddedkonsole") == 0 )
+ return; // Inside modal loop or konsole. Too hard to save state.
+ {
+ QCopEnvelope e("QPE/System", "closing(QString)" );
+ e << d->appName;
+ }
+ processEvents();
+
+ quit();
+}
+
+/*!
+ \internal
+ User initiated quit. Makes the window 'Go Away'. If preloaded this means
+ hiding the window. If not it means quitting the application.
+ As this is user initiated we don't need to check state.
+*/
+void QPEApplication::hideOrQuit()
+{
+ // notify of our demise :)
+ {
+ QCopEnvelope e("QPE/System", "closing(QString)" );
+ e << d->appName;
+ }
+ processEvents();
+ if ( d->preloaded && d->qpe_main_widget )
+ d->qpe_main_widget->hide();
+ else
+ quit();
+}
+
+#if defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
+
+// The libraries with the skiff package (and possibly others) have
+// completely useless implementations of builtin new and delete that
+// use about 50% of your CPU. Here we revert to the simple libc
+// functions.
+
+void* operator new[](size_t size)
+{
+ return malloc(size);
+}
+
+void* operator new(size_t size)
+{
+ return malloc(size);
+}
+
+void operator delete[](void* p)
+{
+ free(p);
+}
+
+void operator delete[](void* p, size_t /*size*/)
+{
+ free(p);
+}
+
+void operator delete(void* p)
+{
+ free(p);
+}
+
+void operator delete(void* p, size_t /*size*/)
+{
+ free(p);
+}
+
+#endif
+
+#if ( QT_VERSION <= 230 ) && !defined(SINGLE_APP)
+#include <qwidgetlist.h>
+#include <qgfx_qws.h>
+extern QRect qt_maxWindowRect;
+void qt_setMaxWindowRect(const QRect& r)
+{
+ qt_maxWindowRect = qt_screen->mapFromDevice(r,
+ qt_screen->mapToDevice(QSize(qt_screen->width(),qt_screen->height())));
+ // Re-resize any maximized windows
+ QWidgetList* l = QApplication::topLevelWidgets();
+ if ( l ) {
+ QWidget *w = l->first();
+ while ( w ) {
+ if ( w->isVisible() && w->isMaximized() )
+ {
+ w->showMaximized();
+ }
+ w = l->next();
+ }
+ delete l;
+ }
+}
+#endif