summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qapplication_qws.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qapplication_qws.cpp')
-rw-r--r--src/gui/kernel/qapplication_qws.cpp3817
1 files changed, 3817 insertions, 0 deletions
diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp
new file mode 100644
index 0000000..2deda8e
--- /dev/null
+++ b/src/gui/kernel/qapplication_qws.cpp
@@ -0,0 +1,3817 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+#include "qlibrary.h"
+#include "qcursor.h"
+#include "qapplication.h"
+#include "private/qapplication_p.h"
+#include "qwidget.h"
+#include "qbitarray.h"
+#include "qpainter.h"
+#include "qpixmapcache.h"
+#include "qdatetime.h"
+#include "qtextcodec.h"
+#include "qdatastream.h"
+#include "qbuffer.h"
+#include "qsocketnotifier.h"
+#include "qsessionmanager.h"
+#include "qclipboard.h"
+#include "qbitmap.h"
+#include "qwssocket_qws.h"
+#include "qtransportauth_qws.h"
+#include "private/qtransportauth_qws_p.h"
+#include "qwsevent_qws.h"
+#include "private/qwscommand_qws_p.h"
+#include "qwsproperty_qws.h"
+#include "qscreen_qws.h"
+#include "qscreenproxy_qws.h"
+#include "qcopchannel_qws.h"
+#include "private/qlock_p.h"
+#include "private/qwslock_p.h"
+//#include "qmemorymanager_qws.h"
+#include "qwsmanager_qws.h"
+//#include "qwsregionmanager_qws.h"
+#include "qwindowsystem_qws.h"
+#include "private/qwindowsystem_p.h"
+
+#include "qwsdisplay_qws.h"
+#include "private/qwsdisplay_qws_p.h"
+#include "private/qwsinputcontext_p.h"
+#include "qfile.h"
+#include "qhash.h"
+#include "qdesktopwidget.h"
+#include "qcolormap.h"
+#include "private/qcursor_p.h"
+#include "qsettings.h"
+#include "qdebug.h"
+#include "qeventdispatcher_qws_p.h"
+#if !defined(QT_NO_GLIB)
+# include "qeventdispatcher_glib_qws_p.h"
+#endif
+
+
+#include "private/qwidget_p.h"
+#include "private/qbackingstore_p.h"
+#include "private/qwindowsurface_qws_p.h"
+#include "private/qfont_p.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifndef QT_NO_QWS_MULTIPROCESS
+#ifdef QT_NO_QSHM
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#ifndef Q_OS_DARWIN
+# include <sys/sem.h>
+#endif
+#include <sys/socket.h>
+#else
+#include "private/qwssharedmemory_p.h"
+#endif
+#endif
+
+#ifndef QT_NO_DIRECTPAINTER
+class QDirectPainter;
+extern void qt_directpainter_region(QDirectPainter *dp, const QRegion &alloc, int type);
+#ifndef QT_NO_QWSEMBEDWIDGET
+extern void qt_directpainter_embedevent(QDirectPainter *dp,
+ const QWSEmbedEvent *e);
+#endif
+#endif // QT_NO_DIRECTPAINTER
+
+const int qwsSharedRamSize = 1 * 1024; // misc data, written by server, read by clients
+
+extern QApplication::Type qt_appType;
+extern QDesktopWidget *qt_desktopWidget;
+
+//these used to be environment variables, they are initialized from
+//environment variables in
+
+bool qws_savefonts = false;
+bool qws_screen_is_interlaced=false; //### should be detected
+bool qws_shared_memory = false;
+bool qws_sw_cursor = true;
+bool qws_accel = true; // ### never set
+QByteArray qws_display_spec(":0");
+Q_GUI_EXPORT int qws_display_id = 0;
+Q_GUI_EXPORT int qws_client_id = 0;
+QWidget *qt_pressGrab = 0;
+QWidget *qt_mouseGrb = 0;
+int *qt_last_x = 0;
+int *qt_last_y = 0;
+
+static int mouse_x_root = -1;
+static int mouse_y_root = -1;
+static int mouse_state = 0;
+static int mouse_double_click_distance = 5;
+
+int qt_servershmid = -1;
+
+bool qws_overrideCursor = false;
+#ifndef QT_NO_QWS_MANAGER
+#include "qdecorationfactory_qws.h"
+
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+static QDecoration *qws_decoration = 0;
+#endif
+
+#if defined(QT_DEBUG)
+/*
+extern "C" void dumpmem(const char* m)
+{
+ static int init=0;
+ static int prev=0;
+ FILE* f = fopen("/proc/meminfo","r");
+ // char line[100];
+ int total=0,used=0,free=0,shared=0,buffers=0,cached=0;
+ fscanf(f,"%*[^M]Mem: %d %d %d %d %d %d",&total,&used,&free,&shared,&buffers,&cached);
+ used -= buffers + cached;
+ if (!init) {
+ init=used;
+ } else {
+ printf("%40s: %+8d = %8d\n",m,used-init-prev,used-init);
+ prev = used-init;
+ }
+ fclose(f);
+}
+*/
+#endif
+
+// Get the name of the directory where Qt for Embedded Linux temporary data should
+// live.
+QString qws_dataDir()
+{
+ static QString result;
+ if (!result.isEmpty())
+ return result;
+ QByteArray dataDir = QString(QLatin1String("/tmp/qtembedded-%1")).arg(qws_display_id).toLocal8Bit();
+ if (mkdir(dataDir, 0700)) {
+ if (errno != EEXIST) {
+ qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData());
+ }
+ }
+
+ struct stat buf;
+ if (lstat(dataDir, &buf))
+ qFatal("stat failed for Qt for Embedded Linux data directory: %s", dataDir.constData());
+
+ if (!S_ISDIR(buf.st_mode))
+ qFatal("%s is not a directory", dataDir.constData());
+
+#ifndef Q_OS_INTEGRITY
+ if (buf.st_uid != getuid())
+ qFatal("Qt for Embedded Linux data directory is not owned by user %d", getuid());
+
+ if ((buf.st_mode & 0677) != 0600)
+ qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData());
+#endif
+ dataDir += "/";
+
+ result = QString::fromLocal8Bit(dataDir);
+ return result;
+}
+
+// Get the filename of the pipe Qt for Embedded Linux uses for server/client comms
+Q_GUI_EXPORT QString qws_qtePipeFilename()
+{
+ return (qws_dataDir() + QString(QLatin1String(QTE_PIPE)).arg(qws_display_id));
+}
+
+static void setMaxWindowRect(const QRect &rect)
+{
+ const QList<QScreen*> subScreens = qt_screen->subScreens();
+ QScreen *screen = qt_screen;
+ int screenNo = 0;
+ for (int i = 0; i < subScreens.size(); ++i) {
+ if (subScreens.at(i)->region().contains(rect)) {
+ screen = subScreens.at(i);
+ screenNo = i;
+ break;
+ }
+ }
+
+ QApplicationPrivate *ap = QApplicationPrivate::instance();
+ ap->setMaxWindowRect(screen, screenNo, rect);
+}
+
+void QApplicationPrivate::setMaxWindowRect(const QScreen *screen, int screenNo,
+ const QRect &rect)
+{
+ if (maxWindowRects.value(screen) == rect)
+ return;
+
+ maxWindowRects[screen] = rect;
+
+ // Re-resize any maximized windows
+ QWidgetList l = QApplication::topLevelWidgets();
+ for (int i = 0; i < l.size(); ++i) {
+ QWidget *w = l.at(i);
+ QScreen *s = w->d_func()->getScreen();
+ if (w->isMaximized() && s == screen)
+ w->d_func()->setMaxWindowState_helper();
+ }
+
+ if ( qt_desktopWidget ) // XXX workaround crash
+ emit QApplication::desktop()->workAreaResized(screenNo);
+}
+
+#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
+
+typedef void (*TransformFunc)(QScreen *, int);
+#ifndef QT_NO_QWS_TRANSFORMED
+extern "C" void qws_setScreenTransformation(QScreen *, int);
+#endif
+static TransformFunc getTransformationFunction()
+{
+ static TransformFunc func = 0;
+
+ if (!func) {
+#ifdef QT_NO_QWS_TRANSFORMED
+# ifndef QT_NO_LIBRARY
+ // symbol is not built into the library, search for the plugin
+ const QStringList paths = QApplication::libraryPaths();
+ foreach (const QString &path, paths) {
+ const QString file = path + QLatin1String("/gfxdrivers/libqgfxtransformed");
+ func = (TransformFunc)QLibrary::resolve(file,
+ "qws_setScreenTransformation");
+ if (func)
+ break;
+ }
+# endif
+#else
+ func = qws_setScreenTransformation;
+#endif
+ if (!func)
+ func = (TransformFunc)-1;
+ }
+
+ if (func == (TransformFunc)-1)
+ return 0;
+
+ return func;
+}
+
+static void setScreenTransformation(int screenNo, int transformation)
+{
+ QScreen *screen = QScreen::instance();
+ const QList<QScreen*> subScreens = screen->subScreens();
+
+ if (screenNo == -1)
+ screenNo = 0;
+
+ if (screenNo == -1 && !subScreens.isEmpty())
+ screenNo = 0;
+
+ if (subScreens.isEmpty() && screenNo == 0) {
+ // nothing
+ } else if (screenNo < 0 || screenNo >= subScreens.size()) {
+ qWarning("setScreenTransformation: invalid screen %i", screenNo);
+ return;
+ }
+
+ if (screenNo < subScreens.size())
+ screen = subScreens.at(screenNo);
+
+ QApplicationPrivate *ap = QApplicationPrivate::instance();
+ ap->setScreenTransformation(screen, screenNo, transformation);
+}
+
+void QApplicationPrivate::setScreenTransformation(QScreen *screen,
+ int screenNo,
+ int transformation)
+{
+ QScreen *transformed = screen;
+
+ while (transformed->classId() == QScreen::ProxyClass)
+ transformed = static_cast<QProxyScreen*>(transformed)->screen();
+
+ if (transformed->classId() != QScreen::TransformedClass)
+ return;
+
+ TransformFunc setScreenTransformation = getTransformationFunction();
+ if (!setScreenTransformation)
+ return;
+
+ setScreenTransformation(transformed, transformation);
+
+ // need to re-configure() proxies bottom-up
+ if (screen->classId() == QScreen::ProxyClass) {
+ QList<QProxyScreen*> proxies;
+ QScreen *s = screen;
+
+ do {
+ QProxyScreen *proxy = static_cast<QProxyScreen*>(s);
+ proxies.append(proxy);
+ s = proxy->screen();
+ } while (s->classId() == QScreen::ProxyClass);
+
+ do {
+ QProxyScreen *proxy = proxies.takeLast();
+ proxy->setScreen(proxy->screen()); // triggers configure()
+ } while (!proxies.isEmpty());
+ }
+
+ if (qt_desktopWidget) { // XXX workaround crash for early screen transform events
+ QDesktopWidget *desktop = QApplication::desktop();
+
+ emit desktop->resized(screenNo);
+ if (maxWindowRect(screen).isEmpty()) // not explicitly set
+ emit desktop->workAreaResized(screenNo);
+ }
+
+ QWSServer *server = QWSServer::instance();
+ if (server) {
+ server->updateWindowRegions();
+ QRegion r = screen->region();
+ server->refresh(r);
+ }
+
+ // make sure maximized and fullscreen windows are updated
+ QWidgetList list = QApplication::topLevelWidgets();
+ for (int i = list.size() - 1; i >= 0; --i) {
+ QWidget *w = list.at(i);
+ if (w->isFullScreen())
+ w->d_func()->setFullScreenSize_helper();
+ else if (w->isMaximized())
+ w->d_func()->setMaxWindowState_helper();
+ }
+}
+
+#endif // QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
+
+/*****************************************************************************
+ Internal variables and functions
+ *****************************************************************************/
+
+
+static QString appName; // application name
+static const char *appFont = 0; // application font
+static const char *appBGCol = 0; // application bg color
+static const char *appFGCol = 0; // application fg color
+static const char *appBTNCol = 0; // application btn color
+static const char *mwGeometry = 0; // main widget geometry
+static const char *mwTitle = 0; // main widget title
+//static bool mwIconic = false; // main widget iconified
+
+static bool app_do_modal = false; // modal mode
+Q_GUI_EXPORT QWSDisplay *qt_fbdpy = 0; // QWS `display'
+QLock *QWSDisplay::lock = 0;
+
+static int mouseButtonPressed = 0; // last mouse button pressed
+static int mouseButtonPressTime = 0; // when was a button pressed
+static short mouseXPos, mouseYPos; // mouse position in act window
+
+extern QWidgetList *qt_modal_stack; // stack of modal widgets
+
+static QWidget *popupButtonFocus = 0;
+static QWidget *popupOfPopupButtonFocus = 0;
+static bool popupCloseDownMode = false;
+static bool popupGrabOk;
+static QPointer<QWidget> *mouseInWidget = 0;
+
+static bool sm_blockUserInput = false; // session management
+
+QWidget *qt_button_down = 0; // widget got last button-down
+WId qt_last_cursor = 0xffffffff; // Was -1, but WIds are unsigned
+
+class QWSMouseEvent;
+class QWSKeyEvent;
+
+class QETWidget : public QWidget // event translator widget
+{
+public:
+ bool translateMouseEvent(const QWSMouseEvent *, int oldstate);
+ bool translateKeyEvent(const QWSKeyEvent *, bool grab);
+ bool translateRegionEvent(const QWSRegionEvent *);
+#ifndef QT_NO_QWSEMBEDWIDGET
+ void translateEmbedEvent(const QWSEmbedEvent *event);
+#endif
+ bool translateWheelEvent(const QWSMouseEvent *me);
+ void repaintDecoration(QRegion r, bool post);
+ void updateRegion();
+
+ bool raiseOnClick()
+ {
+ // With limited windowmanagement/taskbar/etc., raising big windows
+ // (eg. spreadsheet) over the top of everything else (eg. calculator)
+ // is just annoying.
+ return !isMaximized() && !isFullScreen();
+ }
+};
+
+void QApplicationPrivate::createEventDispatcher()
+{
+ Q_Q(QApplication);
+#if !defined(QT_NO_GLIB)
+ if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
+ eventDispatcher = (q->type() != QApplication::Tty
+ ? new QWSEventDispatcherGlib(q)
+ : new QEventDispatcherGlib(q));
+ else
+#endif
+ eventDispatcher = (q->type() != QApplication::Tty
+ ? new QEventDispatcherQWS(q)
+ : new QEventDispatcherUNIX(q));
+}
+
+// Single-process stuff. This should maybe move into qwindowsystem_qws.cpp
+
+static bool qws_single_process;
+static QList<QWSEvent*> incoming;
+static QList<QWSCommand*> outgoing;
+
+void qt_client_enqueue(const QWSEvent *event)
+{
+ QWSEvent *copy = QWSEvent::factory(event->type);
+ copy->copyFrom(event);
+ incoming.append(copy);
+}
+
+QList<QWSCommand*> *qt_get_server_queue()
+{
+ return &outgoing;
+}
+
+void qt_server_enqueue(const QWSCommand *command)
+{
+ QWSCommand *copy = QWSCommand::factory(command->type);
+ copy->copyFrom(command);
+ outgoing.append(copy);
+}
+
+QWSDisplay::Data::Data(QObject* parent, bool singleProcess)
+{
+#ifdef QT_NO_QWS_MULTIPROCESS
+ Q_UNUSED(parent);
+ Q_UNUSED(singleProcess);
+#else
+ if (singleProcess)
+ csocket = 0;
+ else {
+ csocket = new QWSSocket(parent);
+ QObject::connect(csocket, SIGNAL(disconnected()),
+ qApp, SLOT(quit()));
+ }
+ clientLock = 0;
+#endif
+ init();
+}
+
+QWSDisplay::Data::~Data()
+{
+// delete rgnMan; rgnMan = 0;
+// delete memorymanager; memorymanager = 0;
+ qt_screen->disconnect();
+ delete qt_screen; qt_screen = 0;
+#ifndef QT_NO_QWS_CURSOR
+ delete qt_screencursor; qt_screencursor = 0;
+#endif
+#ifndef QT_NO_QWS_MULTIPROCESS
+ shm.detach();
+ if (csocket) {
+ QWSCommand shutdownCmd(QWSCommand::Shutdown, 0, 0);
+ shutdownCmd.write(csocket);
+ csocket->flush(); // may be pending QCop message, eg.
+ delete csocket;
+ }
+ delete clientLock;
+ clientLock = 0;
+#endif
+ delete connected_event;
+ delete mouse_event;
+ delete current_event;
+ qDeleteAll(queue);
+#ifndef QT_NO_COP
+ delete qcop_response;
+#endif
+}
+
+#ifndef QT_NO_QWS_MULTIPROCESS
+bool QWSDisplay::Data::lockClient(QWSLock::LockType type, int timeout)
+{
+ return !clientLock || clientLock->lock(type, timeout);
+}
+
+void QWSDisplay::Data::unlockClient(QWSLock::LockType type)
+{
+ if (clientLock) clientLock->unlock(type);
+}
+
+bool QWSDisplay::Data::waitClient(QWSLock::LockType type, int timeout)
+{
+ return !clientLock || clientLock->wait(type, timeout);
+}
+
+QWSLock* QWSDisplay::Data::getClientLock()
+{
+ return clientLock;
+}
+#endif // QT_NO_QWS_MULTIPROCESS
+
+void QWSDisplay::Data::flush()
+{
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if (csocket) {
+ csocket->waitForReadyRead(0);
+ csocket->flush();
+ }
+#endif
+}
+
+#if 0
+void QWSDisplay::Data::debugQueue() {
+ for (int i = 0; i < queue.size(); ++i) {
+ QWSEvent *e = queue.at(i);
+ qDebug( " ev %d type %d sl %d rl %d", i, e->type, e->simpleLen, e->rawLen);
+ }
+}
+#endif
+
+bool QWSDisplay::Data::queueNotEmpty()
+{
+ return mouse_event/*||region_event*/||queue.count() > 0;
+}
+QWSEvent* QWSDisplay::Data::dequeue()
+{
+ QWSEvent *r=0;
+ if (queue.count()) {
+ r = queue.first();
+ queue.removeFirst();
+ if (r->type == QWSEvent::Region)
+ region_events_count--;
+ } else if (mouse_event) {
+ r = mouse_event;
+ mouse_event = 0;
+#ifdef QAPPLICATION_EXTRA_DEBUG
+ mouse_event_count = 0;
+#endif
+ }
+ return r;
+}
+
+QWSEvent* QWSDisplay::Data::peek()
+{
+ return queue.first();
+}
+
+bool QWSDisplay::Data::directServerConnection()
+{
+#ifndef QT_NO_QWS_MULTIPROCESS
+ return csocket == 0;
+#else
+ return true;
+#endif
+}
+
+void QWSDisplay::Data::create(int n)
+{
+ QWSCreateCommand cmd(n);
+ sendCommand(cmd);
+}
+
+void QWSDisplay::Data::flushCommands()
+{
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if (csocket)
+ csocket->flush();
+#endif
+}
+
+void QWSDisplay::Data::sendCommand(QWSCommand & cmd)
+{
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if (csocket)
+ cmd.write(csocket);
+ else
+#endif
+ qt_server_enqueue(&cmd);
+}
+
+void QWSDisplay::Data::sendSynchronousCommand(QWSCommand & cmd)
+{
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if (csocket) {
+ lockClient(QWSLock::Communication);
+ cmd.write(csocket);
+ bool ok = true;
+ while (csocket->bytesToWrite() > 0) {
+ if (!csocket->waitForBytesWritten(-1)) {
+ qCritical("QWSDisplay::Data::sendSynchronousCommand: %s",
+ qPrintable(csocket->errorString()));
+ ok = false;
+ break;
+ }
+ }
+ if (ok)
+ waitClient(QWSLock::Communication);
+ } else
+#endif
+ qt_server_enqueue(&cmd);
+}
+
+int QWSDisplay::Data::takeId()
+{
+ if (unused_identifiers.count() == 10)
+ create(15);
+ if (unused_identifiers.count() == 0)
+ waitForCreation();
+ return unused_identifiers.takeFirst();
+}
+
+void QWSDisplay::Data::setMouseFilter(void (*filter)(QWSMouseEvent*))
+{
+ mouseFilter = filter;
+}
+
+#ifndef QT_NO_QWS_MULTIPROCESS
+
+QWSLock* QWSDisplay::Data::clientLock = 0;
+
+void Q_GUI_EXPORT qt_app_reinit( const QString& newAppName )
+{
+ qt_fbdpy->d->reinit( newAppName );
+}
+
+#endif // QT_NO_QWS_MULTIPROCESS
+
+class QDesktopWidget;
+
+#ifndef QT_NO_QWS_MULTIPROCESS
+void QWSDisplay::Data::reinit( const QString& newAppName )
+{
+ Q_ASSERT(csocket);
+
+ delete connected_event;
+ connected_event = 0;
+ region_events_count = 0;
+// region_ack = 0;
+ delete mouse_event;
+ mouse_event = 0;
+// region_event = 0;
+ region_offset_window = 0;
+#ifndef QT_NO_COP
+ delete qcop_response;
+ qcop_response = 0;
+#endif
+ delete current_event;
+ current_event = 0;
+#ifdef QAPPLICATION_EXTRA_DEBUG
+ mouse_event_count = 0;
+#endif
+ mouseFilter = 0;
+
+ qt_desktopWidget = 0;
+ delete QWSDisplay::Data::clientLock;
+ QWSDisplay::Data::clientLock = 0;
+
+ QString pipe = qws_qtePipeFilename();
+
+ // QWS client
+ // Cleanup all cached ids
+ unused_identifiers.clear();
+ delete csocket;
+
+ appName = newAppName;
+ qApp->setObjectName( appName );
+
+ csocket = new QWSSocket();
+ QObject::connect(csocket, SIGNAL(disconnected()),
+ qApp, SLOT(quit()));
+ csocket->connectToLocalFile(pipe);
+
+ QWSDisplay::Data::clientLock = new QWSLock();
+
+ QWSIdentifyCommand cmd;
+ cmd.setId(appName, QWSDisplay::Data::clientLock->id());
+
+#ifndef QT_NO_SXE
+ QTransportAuth *a = QTransportAuth::getInstance();
+ QTransportAuth::Data *d = a->connectTransport(
+ QTransportAuth::UnixStreamSock |
+ QTransportAuth::Trusted,
+ csocket->socketDescriptor());
+ QAuthDevice *ad = a->authBuf( d, csocket );
+ ad->setClient( csocket );
+
+ cmd.write(ad);
+#else
+ cmd.write(csocket);
+#endif
+
+ // wait for connect confirmation
+ waitForConnection();
+
+ qws_client_id = connected_event->simpleData.clientId;
+
+ if (!QWSDisplay::initLock(pipe, false))
+ qFatal("Cannot get display lock");
+
+ if (shm.attach(connected_event->simpleData.servershmid)) {
+ sharedRam = static_cast<uchar *>(shm.address());
+ QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
+ if (s)
+ sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
+ } else {
+ perror("QWSDisplay::Data::init");
+ qFatal("Client can't attach to main ram memory.");
+ }
+
+ qApp->desktop();
+
+ // We wait for creation mainly so that we can process important
+ // initialization events such as MaxWindowRect that are sent
+ // before object id creation. Waiting here avoids later window
+ // resizing since we have the MWR before windows are displayed.
+ waitForCreation();
+
+ sharedRamSize -= sizeof(int);
+ qt_last_x = reinterpret_cast<int *>(sharedRam + sharedRamSize);
+ sharedRamSize -= sizeof(int);
+ qt_last_y = reinterpret_cast<int *>(sharedRam + sharedRamSize);
+
+#ifndef QT_NO_COP
+ QCopChannel::reregisterAll();
+#endif
+ csocket->flush();
+}
+#endif
+
+void QWSDisplay::Data::init()
+{
+ connected_event = 0;
+ region_events_count = 0;
+// region_ack = 0;
+ mouse_event = 0;
+ mouse_state = -1;
+ mouse_winid = 0;
+// region_event = 0;
+ region_offset_window = 0;
+#ifndef QT_NO_COP
+ qcop_response = 0;
+#endif
+ current_event = 0;
+#ifdef QAPPLICATION_EXTRA_DEBUG
+ mouse_event_count = 0;
+#endif
+ mouseFilter = 0;
+
+ QString pipe = qws_qtePipeFilename();
+
+ sharedRamSize = qwsSharedRamSize;
+
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if (csocket) {
+ // QWS client
+
+ connectToPipe();
+
+ QWSDisplay::Data::clientLock = new QWSLock();
+
+ QWSIdentifyCommand cmd;
+ cmd.setId(appName, QWSDisplay::Data::clientLock->id());
+#ifndef QT_NO_SXE
+ QTransportAuth *a = QTransportAuth::getInstance();
+ QTransportAuth::Data *d = a->connectTransport(
+ QTransportAuth::UnixStreamSock |
+ QTransportAuth::Trusted,
+ csocket->socketDescriptor());
+ QAuthDevice *ad = a->authBuf( d, csocket );
+ ad->setClient( csocket );
+ cmd.write(ad);
+#else
+ cmd.write(csocket);
+#endif
+
+ // create(30); // not necessary, server will send ids anyway
+ waitForConnection();
+
+ qws_client_id = connected_event->simpleData.clientId;
+
+ // now we want to get the exact display spec to use if we haven't
+ // specified anything.
+ if (qws_display_spec.at(0) == ':')
+ qws_display_spec = connected_event->display;
+
+ if (!QWSDisplay::initLock(pipe, false))
+ qFatal("Cannot get display lock");
+
+ if (shm.attach(connected_event->simpleData.servershmid)) {
+ sharedRam = static_cast<uchar *>(shm.address());
+ QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
+ if (s)
+ sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
+ } else {
+ perror("QWSDisplay::Data::init");
+ qFatal("Client can't attach to main ram memory.");
+ }
+
+ // We wait for creation mainly so that we can process important
+ // initialization events such as MaxWindowRect that are sent
+ // before object id creation. Waiting here avoids later window
+ // resizing since we have the MWR before windows are displayed.
+ waitForCreation();
+ } else
+#endif
+ {
+ create(30);
+
+ // QWS server
+ if (!QWSDisplay::initLock(pipe, true))
+ qFatal("Cannot get display lock");
+
+ QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
+ if (s)
+ sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
+
+#ifndef QT_NO_QWS_MULTIPROCESS
+
+ if (!shm.create(sharedRamSize)) {
+ perror("Cannot create main ram shared memory\n");
+ qFatal("Unable to allocate %d bytes of shared memory", sharedRamSize);
+ }
+ qt_servershmid = shm.id();
+ sharedRam = static_cast<uchar *>(shm.address());
+#else
+ sharedRam=static_cast<uchar *>(malloc(sharedRamSize));
+#endif
+ // Need to zero index count at end of block, might as well zero
+ // the rest too
+ memset(sharedRam,0,sharedRamSize);
+
+ QWSIdentifyCommand cmd;
+ cmd.setId(appName, -1);
+ qt_server_enqueue(&cmd);
+ }
+
+ // Allow some memory for the graphics driver too
+ //### Note that sharedRamSize() has side effects; it must be called
+ //### once, and only once, and before initDevice()
+ sharedRamSize -= qt_screen->sharedRamSize(sharedRam+sharedRamSize);
+
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if(!csocket)
+#endif
+ {
+ //QWS server process
+ if (!qt_screen->initDevice())
+ qFatal("Unable to initialize screen driver!");
+ }
+
+ sharedRamSize -= sizeof(int);
+ qt_last_x = reinterpret_cast<int *>(sharedRam + sharedRamSize);
+ sharedRamSize -= sizeof(int);
+ qt_last_y = reinterpret_cast<int *>(sharedRam + sharedRamSize);
+
+ /* Initialise framebuffer memory manager */
+ /* Add 4k for luck and to avoid clobbering hardware cursor */
+// int screensize=qt_screen->screenSize();
+// memorymanager=new QMemoryManager(qt_screen->base()+screensize+4096,
+// qt_screen->totalSize()-(screensize+4096),0);
+
+// #ifndef QT_NO_QWS_MULTIPROCESS
+// rgnMan = new QWSRegionManager(pipe, csocket);
+// #else
+// rgnMan = new QWSRegionManager(pipe, 0); //####### not necessary
+// #endif
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if (csocket)
+ csocket->flush();
+#endif
+}
+
+
+QWSEvent* QWSDisplay::Data::readMore()
+{
+#ifdef QT_NO_QWS_MULTIPROCESS
+ return incoming.isEmpty() ? 0 : incoming.takeFirst();
+#else
+ if (!csocket)
+ return incoming.isEmpty() ? 0 : incoming.takeFirst();
+ // read next event
+ if (!current_event) {
+ int event_type = qws_read_uint(csocket);
+
+ if (event_type >= 0) {
+ current_event = QWSEvent::factory(event_type);
+ }
+ }
+
+ if (current_event) {
+ if (current_event->read(csocket)) {
+ // Finished reading a whole event.
+ QWSEvent* result = current_event;
+ current_event = 0;
+ return result;
+ }
+ }
+
+ // Not finished reading a whole event.
+ return 0;
+#endif
+}
+
+void QWSDisplay::Data::fillQueue()
+{
+ QWSServer::processEventQueue();
+ QWSEvent *e = readMore();
+#ifndef QT_NO_QWS_MULTIPROCESS
+ int bytesAvailable = csocket ? csocket->bytesAvailable() : 0;
+ int bytesRead = 0;
+#endif
+ while (e) {
+#ifndef QT_NO_QWS_MULTIPROCESS
+ bytesRead += QWS_PROTOCOL_ITEM_SIZE((*e));
+#endif
+ if (e->type == QWSEvent::Connected) {
+ connected_event = static_cast<QWSConnectedEvent *>(e);
+ return;
+ } else if (e->type == QWSEvent::Creation) {
+ QWSCreationEvent *ce = static_cast<QWSCreationEvent*>(e);
+ int id = ce->simpleData.objectid;
+ int count = ce->simpleData.count;
+ for (int i = 0; i < count; ++i)
+ unused_identifiers.append(id++);
+ delete e;
+ } else if (e->type == QWSEvent::Mouse) {
+ if (!qt_screen) {
+ delete e;
+ } else {
+ QWSMouseEvent *me = static_cast<QWSMouseEvent*>(e);
+ if (mouseFilter)
+ mouseFilter(me);
+#ifdef QAPPLICATION_EXTRA_DEBUG
+ static const char *defaultAction= "INITIAL";
+ const char * action = defaultAction;
+#endif
+ delete mouse_event;
+ if (mouse_winid != me->window ()
+ || mouse_state != me->simpleData.state) {
+ queue.append(me);
+ mouse_winid = me->window();
+ mouse_state = me->simpleData.state;
+ mouse_event = 0;
+#ifdef QAPPLICATION_EXTRA_DEBUG
+ mouse_event_count = 0;
+ action = "ENQUEUE";
+#endif
+ } else {
+#ifdef QAPPLICATION_EXTRA_DEBUG
+ if (mouse_event)
+ action = "COMPRESS";
+ mouse_event_count++;
+#endif
+ mouse_event = me;
+ }
+#ifdef QAPPLICATION_EXTRA_DEBUG
+ if (me->simpleData.state !=0 || action != defaultAction || mouse_event_count != 0)
+ qDebug("fillQueue %s (%d,%d), state %x win %d count %d", action,
+ me->simpleData.x_root, me->simpleData.y_root, me->simpleData.state,
+ me->window(), mouse_event_count);
+#endif
+ }
+#ifndef QT_NO_QWS_MULTIPROCESS
+ } else if (e->type == QWSEvent::Region && clientLock) {
+ // not really an unlock, decrements the semaphore
+ region_events_count++;
+ clientLock->unlock(QWSLock::RegionEvent);
+ queue.append(e);
+#endif
+#ifndef QT_NO_QWS_PROPERTIES
+ } else if (e->type == QWSEvent::PropertyReply) {
+ QWSPropertyReplyEvent *pe = static_cast<QWSPropertyReplyEvent*>(e);
+ int len = pe->simpleData.len;
+ char *data;
+ if (len <= 0) {
+ data = 0;
+ } else {
+ data = new char[len];
+ memcpy(data, pe->data, len) ;
+ }
+ QPaintDevice::qwsDisplay()->getPropertyLen = len;
+ QPaintDevice::qwsDisplay()->getPropertyData = data;
+ delete e;
+#endif // QT_NO_QWS_PROPERTIES
+ } else if (e->type==QWSEvent::MaxWindowRect && qt_screen) {
+ // Process this ASAP, in case new widgets are created (startup)
+ setMaxWindowRect((static_cast<QWSMaxWindowRectEvent*>(e))->simpleData.rect);
+ delete e;
+#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
+ } else if (e->type == QWSEvent::ScreenTransformation) {
+ QWSScreenTransformationEvent *pe = static_cast<QWSScreenTransformationEvent*>(e);
+ setScreenTransformation(pe->simpleData.screen,
+ pe->simpleData.transformation);
+ delete e;
+#endif
+#ifndef QT_NO_COP
+ } else if (e->type == QWSEvent::QCopMessage) {
+ QWSQCopMessageEvent *pe = static_cast<QWSQCopMessageEvent*>(e);
+ if (pe->simpleData.is_response) {
+ qcop_response = pe;
+ } else {
+ queue.append(e);
+ }
+#endif
+ } else {
+ queue.append(e);
+ }
+ //debugQueue();
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if (csocket && bytesRead >= bytesAvailable)
+ break;
+#endif
+ e = readMore();
+ }
+}
+
+#ifndef QT_NO_QWS_MULTIPROCESS
+
+static int qws_connection_timeout = 5;
+
+void QWSDisplay::Data::connectToPipe()
+{
+ Q_ASSERT(csocket);
+
+ int timeout = qgetenv("QWS_CONNECTION_TIMEOUT").toInt();
+ if (timeout)
+ qws_connection_timeout = timeout;
+
+ const QString pipe = qws_qtePipeFilename();
+ int i = 0;
+ while (!csocket->connectToLocalFile(pipe)) {
+ if (++i > qws_connection_timeout) {
+ qWarning("No Qt for Embedded Linux server appears to be running.");
+ qWarning("If you want to run this program as a server,");
+ qWarning("add the \"-qws\" command-line option.");
+ exit(1);
+ }
+ sleep(1);
+ }
+}
+
+void QWSDisplay::Data::waitForConnection()
+{
+ connected_event = 0;
+
+ for (int i = 0; i < qws_connection_timeout; i++) {
+ fillQueue();
+ if (connected_event)
+ return;
+ csocket->flush();
+ csocket->waitForReadyRead(1000);
+ }
+
+ csocket->flush();
+ if (!connected_event)
+ qFatal("Did not receive a connection event from the qws server");
+}
+
+void QWSDisplay::Data::waitForRegionAck(int winId)
+{
+ QWSEvent *ack = 0;
+
+ if (csocket) { // GuiClient
+ int i = 0;
+ while (!ack) {
+ fillQueue();
+
+ while (i < queue.size()) {
+ QWSEvent *e = queue.at(i);
+ if (e->type == QWSEvent::Region && e->window() == winId) {
+ ack = e;
+ queue.removeAt(i);
+ break;
+ }
+ ++i;
+ }
+
+ if (!ack) {
+ csocket->flush();
+ csocket->waitForReadyRead(1000);
+ }
+ }
+ } else { // GuiServer
+ fillQueue();
+ for (int i = 0; i < queue.size(); /* nothing */) {
+ QWSEvent *e = queue.at(i);
+ if (e->type == QWSEvent::Region && e->window() == winId) {
+ ack = e;
+ queue.removeAt(i);
+ break;
+ }
+ ++i;
+ }
+ if (!ack) // already processed
+ return;
+ }
+
+ Q_ASSERT(ack);
+
+ qApp->qwsProcessEvent(ack);
+ delete ack;
+ region_events_count--;
+}
+
+void QWSDisplay::Data::waitForRegionEvents(int winId, bool ungrabDisplay)
+{
+ if (!clientLock)
+ return;
+
+ int removedEventsCount = 0;
+
+ // fill queue with unreceived region events
+ if (!clientLock->hasLock(QWSLock::RegionEvent)) {
+ bool ungrabbed = false;
+ if (ungrabDisplay && QWSDisplay::grabbed()) {
+ QWSDisplay::ungrab();
+ ungrabbed = true;
+ }
+
+ for (;;) {
+ fillQueue();
+ if (clientLock->hasLock(QWSLock::RegionEvent))
+ break;
+ csocket->flush();
+ csocket->waitForReadyRead(1000);
+ }
+
+ if (ungrabbed)
+ QWSDisplay::grab(true);
+ }
+
+ // check the queue for pending region events
+ QWSEvent *regionEvent = 0;
+ for (int i = 0; i < queue.size(); /* nothing */) {
+ QWSEvent *e = queue.at(i);
+ if (e->type == QWSEvent::Region && e->window() == winId) {
+ QWSRegionEvent *re = static_cast<QWSRegionEvent*>(e);
+ if (re->simpleData.type == QWSRegionEvent::Allocation) {
+ delete regionEvent;
+ regionEvent = re;
+ }
+ queue.removeAt(i);
+ removedEventsCount++;
+ } else {
+ ++i;
+ }
+ }
+
+ if (regionEvent) {
+ qApp->qwsProcessEvent(regionEvent);
+ delete regionEvent;
+ }
+ region_events_count -= removedEventsCount;
+}
+
+bool QWSDisplay::Data::hasPendingRegionEvents() const
+{
+ if (clientLock && !clientLock->hasLock(QWSLock::RegionEvent))
+ return true;
+
+ return region_events_count > 0;
+}
+
+#endif // QT_NO_QWS_MULTIPROCESS
+
+void QWSDisplay::Data::waitForCreation()
+{
+ fillQueue();
+#ifndef QT_NO_QWS_MULTIPROCESS
+ while (unused_identifiers.count() == 0) {
+ if (csocket) {
+ csocket->flush();
+ csocket->waitForReadyRead(1000);
+ }
+ fillQueue();
+ }
+#endif
+}
+
+
+#ifndef QT_NO_QWS_MULTIPROCESS
+void QWSDisplay::Data::waitForPropertyReply()
+{
+ if (!csocket)
+ return;
+ fillQueue();
+ while (qt_fbdpy->getPropertyLen == -2) {
+ csocket->flush();
+ csocket->waitForReadyRead(1000);
+ fillQueue();
+ }
+}
+#endif
+
+#ifndef QT_NO_COP
+void QWSDisplay::Data::waitForQCopResponse()
+{
+ for (;;) {
+ fillQueue();
+ if (qcop_response)
+ break;
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if (csocket) {
+ csocket->flush();
+ csocket->waitForReadyRead(1000);
+ }
+#endif
+ }
+ queue.prepend(qcop_response);
+ qcop_response = 0;
+}
+#endif
+
+/*!
+ \class QWSDisplay
+ \brief The QWSDisplay class provides a display for QWS; it is an internal class.
+
+ \internal
+
+ \ingroup qws
+*/
+
+QWSDisplay::QWSDisplay()
+{
+ d = new Data(0, qws_single_process);
+}
+
+QWSDisplay::~QWSDisplay()
+{
+ delete d;
+ delete lock;
+ lock = 0;
+}
+
+bool QWSDisplay::grabbed()
+{
+ return lock->locked();
+}
+
+void QWSDisplay::grab()
+{
+ lock->lock(QLock::Read);
+}
+
+void QWSDisplay::grab(bool write)
+{
+ lock->lock(write ? QLock::Write : QLock::Read);
+
+}
+void QWSDisplay::ungrab()
+{
+ lock->unlock();
+}
+
+#if 0
+QWSRegionManager *QWSDisplay::regionManager() const
+{
+ return d->rgnMan;
+}
+#endif
+
+bool QWSDisplay::eventPending() const
+{
+#ifndef QT_NO_QWS_MULTIPROCESS
+ d->flush();
+#endif
+ d->fillQueue();
+ return d->queueNotEmpty();
+}
+
+
+/*
+ Caller must delete return value!
+ */
+QWSEvent *QWSDisplay::getEvent()
+{
+ d->fillQueue();
+ Q_ASSERT(d->queueNotEmpty());
+ QWSEvent* e = d->dequeue();
+
+ return e;
+}
+
+uchar* QWSDisplay::frameBuffer() const { return qt_screen->base(); }
+int QWSDisplay::width() const { return qt_screen->width(); }
+int QWSDisplay::height() const { return qt_screen->height(); }
+int QWSDisplay::depth() const { return qt_screen->depth(); }
+int QWSDisplay::pixmapDepth() const { return qt_screen->pixmapDepth(); }
+bool QWSDisplay::supportsDepth(int depth) const { return qt_screen->supportsDepth(depth); }
+uchar *QWSDisplay::sharedRam() const { return d->sharedRam; }
+int QWSDisplay::sharedRamSize() const { return d->sharedRamSize; }
+
+#ifndef QT_NO_QWS_PROPERTIES
+
+void QWSDisplay::addProperty(int winId, int property)
+{
+ QWSAddPropertyCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.property = property;
+ d->sendCommand(cmd);
+}
+
+void QWSDisplay::setProperty(int winId, int property, int mode, const QByteArray &data)
+{
+ QWSSetPropertyCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.property = property;
+ cmd.simpleData.mode = mode;
+ cmd.setData(data.constData(), data.size());
+ d->sendCommand(cmd);
+}
+
+void QWSDisplay::setProperty(int winId, int property, int mode,
+ const char * data)
+{
+ QWSSetPropertyCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.property = property;
+ cmd.simpleData.mode = mode;
+ cmd.setData(data, strlen(data));
+ d->sendCommand(cmd);
+}
+
+void QWSDisplay::removeProperty(int winId, int property)
+{
+ QWSRemovePropertyCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.property = property;
+ d->sendCommand(cmd);
+}
+
+/*
+ It is the caller's responsibility to delete[] \a data.
+ */
+bool QWSDisplay::getProperty(int winId, int property, char *&data, int &len)
+{
+ if (d->directServerConnection()) {
+ const char *propertyData;
+ bool retval = qwsServer->d_func()->get_property(winId, property, propertyData, len);
+ if (len <= 0) {
+ data = 0;
+ } else {
+ data = new char[len];
+ memcpy(data, propertyData, len) ;
+ }
+ return retval;
+ }
+ QWSGetPropertyCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.property = property;
+ d->sendCommand(cmd);
+
+ getPropertyLen = -2;
+ getPropertyData = 0;
+
+#ifndef QT_NO_QWS_MULTIPROCESS
+ d->waitForPropertyReply();
+#endif
+
+ len = getPropertyLen;
+ data = getPropertyData;
+
+ getPropertyLen = -2;
+ getPropertyData = 0;
+
+ return len != -1;
+}
+
+#endif // QT_NO_QWS_PROPERTIES
+
+void QWSDisplay::setAltitude(int winId, int alt, bool fixed)
+{
+ QWSChangeAltitudeCommand cmd;
+#ifdef QT_DEBUG
+ memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
+#endif
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.altitude = QWSChangeAltitudeCommand::Altitude(alt);
+ cmd.simpleData.fixed = fixed;
+ if (d->directServerConnection()) {
+ qwsServer->d_func()->set_altitude(&cmd);
+ } else {
+ d->sendSynchronousCommand(cmd);
+ }
+}
+
+void QWSDisplay::setOpacity(int winId, int opacity)
+{
+ QWSSetOpacityCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.opacity = opacity;
+ if (d->directServerConnection()) {
+ qwsServer->d_func()->set_opacity(&cmd);
+ } else {
+ d->sendCommand(cmd);
+ }
+}
+
+
+
+void QWSDisplay::requestFocus(int winId, bool get)
+{
+ QWSRequestFocusCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.flag = get;
+ if (d->directServerConnection())
+ qwsServer->d_func()->request_focus(&cmd);
+ else
+ d->sendCommand(cmd);
+}
+
+void QWSDisplay::setIdentity(const QString &appName)
+{
+ QWSIdentifyCommand cmd;
+#ifdef QT_NO_QWS_MULTIPROCESS
+ const int id = -1;
+#else
+ const int id = QWSDisplay::Data::clientLock ? QWSDisplay::Data::clientLock->id() : -1;
+#endif
+ cmd.setId(appName, id);
+ if (d->directServerConnection())
+ qwsServer->d_func()->set_identity(&cmd);
+ else
+ d->sendCommand(cmd);
+}
+
+void QWSDisplay::nameRegion(int winId, const QString& n, const QString &c)
+{
+ QWSRegionNameCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.setName(n, c);
+ if (d->directServerConnection())
+ qwsServer->d_func()->name_region(&cmd);
+ else
+ d->sendCommand(cmd);
+}
+
+void QWSDisplay::requestRegion(int winId, const QString &surfaceKey,
+ const QByteArray &surfaceData,
+ const QRegion &region)
+{
+ if (d->directServerConnection()) {
+ qwsServer->d_func()->request_region(winId, surfaceKey,
+ surfaceData, region);
+ } else {
+ QWSRegionCommand cmd;
+ cmd.setData(winId, surfaceKey, surfaceData, region);
+ d->sendSynchronousCommand(cmd);
+ }
+}
+
+void QWSDisplay::repaintRegion(int winId, int windowFlags, bool opaque, QRegion r)
+{
+ if (d->directServerConnection()) {
+ qwsServer->d_func()->repaint_region(winId, windowFlags, opaque, r);
+ } else {
+ QVector<QRect> ra = r.rects();
+
+ /*
+ for (int i = 0; i < ra.size(); i++) {
+ QRect r(ra[i]);
+ qDebug("rect: %d %d %d %d", r.x(), r.y(), r.right(), r.bottom());
+ }
+ */
+
+ QWSRepaintRegionCommand cmd;
+ /* XXX QWSRegionCommand is padded out in a compiler dependent way.
+ Zeroed out to avoid valgrind reporting uninitialized memory usage.
+ */
+#ifdef QT_DEBUG
+ memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
+#endif
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.windowFlags = windowFlags;
+ cmd.simpleData.opaque = opaque;
+ cmd.simpleData.nrectangles = ra.count();
+ cmd.setData(reinterpret_cast<const char *>(ra.constData()),
+ ra.count() * sizeof(QRect), false);
+
+ d->sendSynchronousCommand(cmd);
+ }
+}
+
+
+void QWSDisplay::moveRegion(int winId, int dx, int dy)
+{
+ QWSRegionMoveCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.dx = dx;
+ cmd.simpleData.dy = dy;
+
+ if (d->directServerConnection()) {
+ qwsServer->d_func()->move_region(&cmd);
+ } else {
+ d->sendSynchronousCommand(cmd);
+ }
+// d->offsetPendingExpose(winId, QPoint(cmd.simpleData.dx, cmd.simpleData.dy));
+}
+
+void QWSDisplay::destroyRegion(int winId)
+{
+ QWSRegionDestroyCommand cmd;
+ cmd.simpleData.windowid = winId;
+ if (d->directServerConnection()) {
+ qwsServer->d_func()->destroy_region(&cmd);
+ } else {
+ d->sendCommand(cmd);
+ }
+}
+
+#ifndef QT_NO_QWS_INPUTMETHODS
+
+void QWSDisplay::sendIMUpdate(int type, int winId, int widgetid)
+{
+ QWSIMUpdateCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.widgetid = widgetid;
+
+ cmd.simpleData.type = type;
+
+ if (d->directServerConnection()) {
+ qwsServer->d_func()->im_update(&cmd);
+ } else {
+ d->sendCommand(cmd);
+ }
+}
+
+void QWSDisplay::sendIMResponse(int winId, int property, const QVariant &result)
+{
+ QWSIMResponseCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.property = property;
+
+ cmd.setResult(result);
+
+ if (d->directServerConnection()) {
+ qwsServer->d_func()->im_response(&cmd);
+ } else {
+ d->sendCommand(cmd);
+ }
+}
+
+void QWSDisplay::resetIM()
+{
+ sendIMUpdate(QWSInputMethod::Reset, -1, -1);
+}
+
+void QWSDisplay::sendIMMouseEvent(int index, bool isPress)
+{
+ QWSIMMouseCommand cmd;
+ cmd.simpleData.index = index;
+ cmd.simpleData.state = isPress ? QWSServer::MousePress : QWSServer::MouseRelease;
+ if (d->directServerConnection()) {
+ qwsServer->d_func()->send_im_mouse(&cmd);
+ } else {
+ d->sendCommand(cmd);
+ }
+}
+
+#endif
+
+int QWSDisplay::takeId()
+{
+ return d->takeId();
+}
+
+bool QWSDisplay::initLock(const QString &filename, bool create)
+{
+ if (!lock) {
+ lock = new QLock(filename, 'd', create);
+
+ if (!lock->isValid()) {
+ delete lock;
+ lock = 0;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void QWSDisplay::setSelectionOwner(int winId, const QTime &time)
+{
+ QWSSetSelectionOwnerCommand cmd;
+ cmd.simpleData.windowid = winId;
+ cmd.simpleData.hour = time.hour();
+ cmd.simpleData.minute = time.minute();
+ cmd.simpleData.sec = time.second();
+ cmd.simpleData.ms = time.msec();
+ d->sendCommand(cmd);
+}
+
+void QWSDisplay::convertSelection(int winId, int selectionProperty, const QString &mimeTypes)
+{
+#ifdef QT_NO_QWS_PROPERTIES
+ Q_UNUSED(mimeTypes);
+#else
+ // ### we need the atom/property thingy like in X here
+ addProperty(winId, QT_QWS_PROPERTY_CONVERTSELECTION);
+ setProperty(winId, QT_QWS_PROPERTY_CONVERTSELECTION,
+ int(QWSPropertyManager::PropReplace), mimeTypes.toLatin1());
+#endif
+ QWSConvertSelectionCommand cmd;
+ cmd.simpleData.requestor = winId;
+ cmd.simpleData.selection = selectionProperty;
+ cmd.simpleData.mimeTypes = QT_QWS_PROPERTY_CONVERTSELECTION;
+ d->sendCommand(cmd);
+}
+
+void QWSDisplay::defineCursor(int id, const QBitmap &curs, const QBitmap &mask,
+ int hotX, int hotY)
+{
+ const QImage cursImg = curs.toImage().convertToFormat(QImage::Format_MonoLSB);
+ const QImage maskImg = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
+
+ QWSDefineCursorCommand cmd;
+ cmd.simpleData.width = curs.width();
+ cmd.simpleData.height = curs.height();
+ cmd.simpleData.hotX = hotX;
+ cmd.simpleData.hotY = hotY;
+ cmd.simpleData.id = id;
+
+
+ // must copy each scanline since there might be gaps between them
+ const int height = curs.height();
+ const int width = curs.width();
+ const int dst_bpl = (width + 7) / 8;
+
+ int dataLen = dst_bpl * height;
+ uchar *data = new uchar[dataLen*2];
+ uchar *dst = data;
+
+ int src_bpl = cursImg.bytesPerLine();
+ const uchar *cursSrc = cursImg.bits();
+ for (int i = 0; i < height; ++i) {
+ memcpy(dst, cursSrc + i*src_bpl, dst_bpl);
+ dst += dst_bpl;
+ }
+
+ src_bpl = maskImg.bytesPerLine();
+ const uchar *maskSrc = maskImg.bits();
+ for (int i = 0; i < height; ++i) {
+ memcpy(dst, maskSrc + i*src_bpl, dst_bpl);
+ dst += dst_bpl;
+ }
+
+ cmd.setData(reinterpret_cast<char*>(data), dataLen*2);
+ delete [] data;
+ d->sendCommand(cmd);
+}
+
+void QWSDisplay::destroyCursor(int id)
+{
+ QWSDefineCursorCommand cmd;
+ cmd.simpleData.width = 0;
+ cmd.simpleData.height = 0;
+ cmd.simpleData.hotX = 0;
+ cmd.simpleData.hotY = 0;
+ cmd.simpleData.id = id;
+ cmd.setData(0, 0);
+
+ d->sendCommand(cmd);
+}
+
+#ifndef QT_NO_SOUND
+void QWSDisplay::playSoundFile(const QString& f)
+{
+ QWSPlaySoundCommand cmd;
+ cmd.setFileName(f);
+ d->sendCommand(cmd);
+}
+#endif
+
+#ifndef QT_NO_COP
+void QWSDisplay::registerChannel(const QString& channel)
+{
+ QWSQCopRegisterChannelCommand reg;
+ reg.setChannel(channel);
+ qt_fbdpy->d->sendCommand(reg);
+}
+
+void QWSDisplay::sendMessage(const QString &channel, const QString &msg,
+ const QByteArray &data)
+{
+ QWSQCopSendCommand com;
+ com.setMessage(channel, msg, data);
+ qt_fbdpy->d->sendCommand(com);
+}
+
+void QWSDisplay::flushCommands()
+{
+ qt_fbdpy->d->flushCommands();
+}
+
+/*
+ caller deletes result
+*/
+QWSQCopMessageEvent* QWSDisplay::waitForQCopResponse()
+{
+ qt_fbdpy->d->waitForQCopResponse();
+ QWSQCopMessageEvent *e = static_cast<QWSQCopMessageEvent*>(qt_fbdpy->d->dequeue());
+ Q_ASSERT(e->type == QWSEvent::QCopMessage);
+ return e;
+}
+#endif
+
+void QWSDisplay::sendFontCommand(int type, const QByteArray &fontName)
+{
+ QWSFontCommand cmd;
+ cmd.simpleData.type = type;
+ cmd.setFontName(fontName);
+ d->sendCommand(cmd);
+}
+
+void QWSDisplay::setWindowCaption(QWidget *w, const QString &c)
+{
+ if (w->isWindow()) {
+ nameRegion(w->internalWinId(), w->objectName(), c);
+ static_cast<QETWidget *>(w)->repaintDecoration(qApp->desktop()->rect(), true);
+ }
+}
+
+void QWSDisplay::selectCursor(QWidget *w, unsigned int cursId)
+{
+ if (cursId != qt_last_cursor)
+ {
+ QWidget *top = w->window();
+ qt_last_cursor = cursId;
+ QWSSelectCursorCommand cmd;
+ cmd.simpleData.windowid = top->internalWinId();
+ cmd.simpleData.id = cursId;
+ d->sendCommand(cmd);
+ d->flush();
+ }
+}
+
+void QWSDisplay::setCursorPosition(int x, int y)
+{
+ QWSPositionCursorCommand cmd;
+ cmd.simpleData.newX = x;
+ cmd.simpleData.newY = y;
+ d->sendCommand(cmd);
+ d->flush();
+}
+
+void QWSDisplay::grabMouse(QWidget *w, bool grab)
+{
+ QWidget *top = w->window();
+ QWSGrabMouseCommand cmd;
+#ifdef QT_DEBUG
+ memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
+#endif
+ cmd.simpleData.windowid = top->winId();
+ cmd.simpleData.grab = grab;
+ d->sendCommand(cmd);
+ d->flush();
+}
+
+void QWSDisplay::grabKeyboard(QWidget *w, bool grab)
+{
+ QWidget *top = w->window();
+ QWSGrabKeyboardCommand cmd;
+#ifdef QT_DEBUG
+ memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
+#endif
+ cmd.simpleData.windowid = top->winId();
+ cmd.simpleData.grab = grab;
+ d->sendCommand(cmd);
+ d->flush();
+}
+
+QList<QWSWindowInfo> QWSDisplay::windowList()
+{
+ QList<QWSWindowInfo> ret;
+ if(d->directServerConnection()) {
+ QList<QWSInternalWindowInfo*> * qin=QWSServer::windowList();
+ for (int i = 0; i < qin->count(); ++i) {
+ QWSInternalWindowInfo * qwi = qin->at(i);
+ QWSWindowInfo tmp;
+ tmp.winid = qwi->winid;
+ tmp.clientid = qwi->clientid;
+ tmp.name = QString(qwi->name);
+ ret.append(tmp);
+ }
+ qDeleteAll(*qin);
+ delete qin;
+ }
+ return ret;
+}
+
+int QWSDisplay::windowAt(const QPoint &p)
+{
+ //### currently only implemented for the server process
+ int ret = 0;
+ if(d->directServerConnection()) {
+ QWSWindow *win = qwsServer->windowAt(p);
+ if (win)
+ return win->winId();
+ }
+ return ret;
+}
+
+void QWSDisplay::setRawMouseEventFilter(void (*filter)(QWSMouseEvent *))
+{
+ if (qt_fbdpy)
+ qt_fbdpy->d->setMouseFilter(filter);
+}
+
+/*!
+ \relates QScreen
+
+ Here it is. \a transformation and \a screenNo
+ */
+void QWSDisplay::setTransformation(int transformation, int screenNo)
+{
+ QWSScreenTransformCommand cmd;
+ cmd.setTransformation(screenNo, transformation);
+ QWSDisplay::instance()->d->sendCommand(cmd);
+}
+
+static bool qt_try_modal(QWidget *, QWSEvent *);
+
+/*****************************************************************************
+ qt_init() - initializes Qt/FB
+ *****************************************************************************/
+
+static void qt_set_qws_resources()
+
+{
+ if (QApplication::desktopSettingsAware())
+ QApplicationPrivate::qws_apply_settings();
+
+ if (appFont)
+ QApplication::setFont(QFont(QString::fromLocal8Bit(appFont)));
+
+ if (appBGCol || appBTNCol || appFGCol) {
+ (void) QApplication::style(); // trigger creation of application style and system palettes
+ QColor btn;
+ QColor bg;
+ QColor fg;
+ if (appBGCol)
+ bg = QColor(appBGCol);
+ else
+ bg = QApplicationPrivate::sys_pal->color(QPalette::Window);
+ if (appFGCol)
+ fg = QColor(appFGCol);
+ else
+ fg = QApplicationPrivate::sys_pal->color(QPalette::WindowText);
+ if (appBTNCol)
+ btn = QColor(appBTNCol);
+ else
+ btn = QApplicationPrivate::sys_pal->color(QPalette::Button);
+
+ int h,s,v;
+ fg.getHsv(&h,&s,&v);
+ QColor base = Qt::white;
+ bool bright_mode = false;
+ if (v >= 255 - 50) {
+ base = btn.darker(150);
+ bright_mode = true;
+ }
+
+ QPalette pal(fg, btn, btn.lighter(), btn.darker(), btn.darker(150), fg, Qt::white, base, bg);
+ if (bright_mode) {
+ pal.setColor(QPalette::HighlightedText, base);
+ pal.setColor(QPalette::Highlight, Qt::white);
+ } else {
+ pal.setColor(QPalette::HighlightedText, Qt::white);
+ pal.setColor(QPalette::Highlight, Qt::darkBlue);
+ }
+ QColor disabled((fg.red() + btn.red()) / 2,
+ (fg.green() + btn.green())/ 2,
+ (fg.blue() + btn.blue()) / 2);
+ pal.setColorGroup(QPalette::Disabled, disabled, btn, btn.lighter(125),
+ btn.darker(), btn.darker(150), disabled, Qt::white, Qt::white, bg);
+ if (bright_mode) {
+ pal.setColor(QPalette::Disabled, QPalette::HighlightedText, base);
+ pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::white);
+ } else {
+ pal.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::white);
+ pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
+ }
+ QApplicationPrivate::setSystemPalette(pal);
+
+ }
+}
+
+void QApplicationPrivate::initializeWidgetPaletteHash()
+{
+}
+
+/*! \internal
+ apply the settings to the application
+*/
+bool QApplicationPrivate::qws_apply_settings()
+{
+#ifndef QT_NO_SETTINGS
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+
+ QStringList strlist;
+ int i;
+ QPalette pal(Qt::black);
+ int groupCount = 0;
+ strlist = settings.value(QLatin1String("Palette/active")).toStringList();
+ if (strlist.count() == QPalette::NColorRoles) {
+ ++groupCount;
+ for (i = 0; i < QPalette::NColorRoles; i++)
+ pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
+ QColor(strlist[i]));
+ }
+ strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
+ if (strlist.count() == QPalette::NColorRoles) {
+ ++groupCount;
+ for (i = 0; i < QPalette::NColorRoles; i++)
+ pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
+ QColor(strlist[i]));
+ }
+ strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
+ if (strlist.count() == QPalette::NColorRoles) {
+ ++groupCount;
+ for (i = 0; i < QPalette::NColorRoles; i++)
+ pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
+ QColor(strlist[i]));
+ }
+
+
+ if (groupCount == QPalette::NColorGroups)
+ QApplicationPrivate::setSystemPalette(pal);
+
+ QString str = settings.value(QLatin1String("font")).toString();
+ if (!str.isEmpty()) {
+ QFont font(QApplication::font());
+ font.fromString(str);
+ QApplicationPrivate::setSystemFont(font);
+ }
+
+ // read library (ie. plugin) path list
+ QString libpathkey =
+ QString::fromLatin1("%1.%2/libraryPath")
+ .arg(QT_VERSION >> 16)
+ .arg((QT_VERSION & 0xff00) >> 8);
+ QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
+#ifndef QT_NO_LIBRARY
+ if (! pathlist.isEmpty()) {
+ QStringList::ConstIterator it = pathlist.constBegin();
+ while (it != pathlist.constEnd())
+ QApplication::addLibraryPath(*it++);
+ }
+#endif
+
+ // read new QStyle
+ QString stylename = settings.value(QLatin1String("style")).toString();
+ if (QCoreApplication::startingUp()) {
+ if (!stylename.isEmpty() && !QApplicationPrivate::styleOverride)
+ QApplicationPrivate::styleOverride = new QString(stylename);
+ } else {
+ QApplication::setStyle(stylename);
+ }
+
+ int num =
+ settings.value(QLatin1String("doubleClickInterval"),
+ QApplication::doubleClickInterval()).toInt();
+ QApplication::setDoubleClickInterval(num);
+
+ num =
+ settings.value(QLatin1String("cursorFlashTime"),
+ QApplication::cursorFlashTime()).toInt();
+ QApplication::setCursorFlashTime(num);
+
+#ifndef QT_NO_WHEELEVENT
+ num =
+ settings.value(QLatin1String("wheelScrollLines"),
+ QApplication::wheelScrollLines()).toInt();
+ QApplication::setWheelScrollLines(num);
+#endif
+
+ QString colorspec = settings.value(QLatin1String("colorSpec"),
+ QVariant(QLatin1String("default"))).toString();
+ if (colorspec == QLatin1String("normal"))
+ QApplication::setColorSpec(QApplication::NormalColor);
+ else if (colorspec == QLatin1String("custom"))
+ QApplication::setColorSpec(QApplication::CustomColor);
+ else if (colorspec == QLatin1String("many"))
+ QApplication::setColorSpec(QApplication::ManyColor);
+ else if (colorspec != QLatin1String("default"))
+ colorspec = QLatin1String("default");
+
+#ifndef QT_NO_TEXTCODEC
+ QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
+ QVariant(QLatin1String("none"))).toString();
+ if (defaultcodec != QLatin1String("none")) {
+ QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
+ if (codec)
+ QTextCodec::setCodecForTr(codec);
+ }
+#endif
+
+ int w = settings.value(QLatin1String("globalStrut/width")).toInt();
+ int h = settings.value(QLatin1String("globalStrut/height")).toInt();
+ QSize strut(w, h);
+ if (strut.isValid())
+ QApplication::setGlobalStrut(strut);
+
+ QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
+ QApplication::setEffectEnabled(Qt::UI_General,
+ effects.contains(QLatin1String("general")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
+ effects.contains(QLatin1String("animatemenu")));
+ QApplication::setEffectEnabled(Qt::UI_FadeMenu,
+ effects.contains(QLatin1String("fademenu")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
+ effects.contains(QLatin1String("animatecombo")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
+ effects.contains(QLatin1String("animatetooltip")));
+ QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
+ effects.contains(QLatin1String("fadetooltip")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
+ effects.contains(QLatin1String("animatetoolbox")));
+
+ settings.beginGroup(QLatin1String("Font Substitutions"));
+ QStringList fontsubs = settings.childKeys();
+ if (!fontsubs.isEmpty()) {
+ QStringList::Iterator it = fontsubs.begin();
+ for (; it != fontsubs.end(); ++it) {
+ QString fam = *it;
+ QStringList subs = settings.value(fam).toStringList();
+ QFont::insertSubstitutions(fam, subs);
+ }
+ }
+ settings.endGroup();
+
+ settings.endGroup(); // Qt
+
+ settings.beginGroup(QLatin1String("QWS Font Fallbacks"));
+ if (!settings.childKeys().isEmpty()) {
+ // from qfontdatabase_qws.cpp
+ extern void qt_applyFontDatabaseSettings(const QSettings &);
+ qt_applyFontDatabaseSettings(settings);
+ }
+ settings.endGroup();
+
+ return true;
+#else
+ return false;
+#endif // QT_NO_SETTINGS
+}
+
+
+
+static void init_display()
+{
+ if (qt_fbdpy) return; // workaround server==client case
+
+ // Connect to FB server
+ qt_fbdpy = new QWSDisplay();
+
+ // Get display parameters
+ // Set paintdevice parameters
+ // XXX initial info sent from server
+ // Misc. initialization
+
+ QColormap::initialize();
+ QFont::initialize();
+#ifndef QT_NO_CURSOR
+ QCursorData::initialize();
+#endif
+
+ qApp->setObjectName(appName);
+
+ if (!QApplicationPrivate::sys_font) {
+#ifdef QT_NO_FREETYPE
+ QFont f = QFont(QLatin1String("helvetica"), 10);
+#else
+ QFont f = QFont(QLatin1String("DejaVu Sans"), 12);
+#endif
+ QApplicationPrivate::setSystemFont(f);
+ }
+ qt_set_qws_resources();
+}
+
+void qt_init_display()
+{
+ qt_is_gui_used = true;
+ qws_single_process = true;
+ init_display();
+}
+
+static bool read_bool_env_var(const char *var, bool defaultvalue)
+{
+ // returns true if env variable is set to non-zero
+ // returns false if env var is set to zero
+ // returns defaultvalue if env var not set
+ char *x = ::getenv(var);
+ return (x && *x) ? (strcmp(x,"0") != 0) : defaultvalue;
+}
+
+static int read_int_env_var(const char *var, int defaultvalue)
+{
+ bool ok;
+ int r = qgetenv(var).toInt(&ok);
+ return ok ? r : defaultvalue;
+}
+
+void qt_init(QApplicationPrivate *priv, int type)
+{
+#ifdef QT_NO_QWS_MULTIPROCESS
+ if (type == QApplication::GuiClient)
+ type = QApplication::GuiServer;
+#endif
+ if (type == QApplication::GuiServer)
+ qt_is_gui_used = false; //we'll turn it on in a second
+ qws_sw_cursor = read_bool_env_var("QWS_SW_CURSOR",qws_sw_cursor);
+ qws_screen_is_interlaced = read_bool_env_var("QWS_INTERLACE",false);
+
+ const char *display = ::getenv("QWS_DISPLAY");
+ if (display)
+ qws_display_spec = display; // since we setenv later!
+
+ //qws_savefonts = qgetenv("QWS_SAVEFONTS") != 0;
+ //qws_shared_memory = qgetenv("QWS_NOSHARED") == 0;
+
+ mouse_double_click_distance = read_int_env_var("QWS_DBLCLICK_DISTANCE", 5);
+
+ int flags = 0;
+ char *p;
+ int argc = priv->argc;
+ char **argv = priv->argv;
+ int j;
+
+ // Set application name
+
+ if (argv && *argv) { //apparently, we allow people to pass 0 on the other platforms
+ p = strrchr(argv[0], '/');
+ appName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
+ }
+
+ // Get command line params
+
+ j = argc ? 1 : 0;
+ QString decoration;
+ for (int i=1; i<argc; i++) {
+ if (argv[i] && *argv[i] != '-') {
+ argv[j++] = argv[i];
+ continue;
+ }
+ QByteArray arg = argv[i];
+ if (arg == "-fn" || arg == "-font") {
+ if (++i < argc)
+ appFont = argv[i];
+ } else if (arg == "-bg" || arg == "-background") {
+ if (++i < argc)
+ appBGCol = argv[i];
+ } else if (arg == "-btn" || arg == "-button") {
+ if (++i < argc)
+ appBTNCol = argv[i];
+ } else if (arg == "-fg" || arg == "-foreground") {
+ if (++i < argc)
+ appFGCol = argv[i];
+ } else if (arg == "-name") {
+ if (++i < argc)
+ appName = QString::fromLocal8Bit(argv[i]);
+ } else if (arg == "-title") {
+ if (++i < argc)
+ mwTitle = argv[i];
+ } else if (arg == "-geometry") {
+ if (++i < argc)
+ mwGeometry = argv[i];
+ } else if (arg == "-shared") {
+ qws_shared_memory = true;
+ } else if (arg == "-noshared") {
+ qws_shared_memory = false;
+ } else if (arg == "-savefonts") {
+ qws_savefonts = true;
+ } else if (arg == "-nosavefonts") {
+ qws_savefonts = false;
+ } else if (arg == "-swcursor") {
+ qws_sw_cursor = true;
+ } else if (arg == "-noswcursor") {
+ qws_sw_cursor = false;
+ } else if (arg == "-keyboard") {
+ flags &= ~QWSServer::DisableKeyboard;
+ } else if (arg == "-nokeyboard") {
+ flags |= QWSServer::DisableKeyboard;
+ } else if (arg == "-mouse") {
+ flags &= ~QWSServer::DisableMouse;
+ } else if (arg == "-nomouse") {
+ flags |= QWSServer::DisableMouse;
+ } else if (arg == "-qws") {
+ type = QApplication::GuiServer;
+ } else if (arg == "-interlaced") {
+ qws_screen_is_interlaced = true;
+ } else if (arg == "-display") {
+ if (++i < argc)
+ qws_display_spec = argv[i];
+ } else if (arg == "-decoration") {
+ if (++i < argc)
+ decoration = QString::fromLocal8Bit(argv[i]);
+ } else {
+ argv[j++] = argv[i];
+ }
+ }
+ if(j < priv->argc) {
+ priv->argv[j] = 0;
+ priv->argc = j;
+ }
+
+ mouseInWidget = new QPointer<QWidget>;
+
+ const QString disp = QString::fromLatin1(qws_display_spec);
+ QRegExp regexp(QLatin1String(":(\\d+)$"));
+ if (regexp.lastIndexIn(disp) != -1) {
+ const QString capture = regexp.cap(1);
+ bool ok = false;
+ int id = capture.toInt(&ok);
+ if (ok)
+ qws_display_id = id;
+ }
+
+ if (type == QApplication::GuiServer) {
+ qt_appType = QApplication::Type(type);
+ qws_single_process = true;
+ QWSServer::startup(flags);
+ setenv("QWS_DISPLAY", qws_display_spec.constData(), 0);
+ }
+
+ if(qt_is_gui_used) {
+ init_display();
+#ifndef QT_NO_QWS_MANAGER
+ if (decoration.isEmpty() && !qws_decoration) {
+ const QStringList keys = QDecorationFactory::keys();
+ if (!keys.isEmpty())
+ decoration = keys.first();
+ }
+ if (!decoration.isEmpty())
+ qws_decoration = QApplication::qwsSetDecoration(decoration);
+#endif // QT_NO_QWS_MANAGER
+#ifndef QT_NO_QWS_INPUTMETHODS
+ qApp->setInputContext(new QWSInputContext);
+#endif
+ }
+
+/*### convert interlace style
+ if (qws_screen_is_interlaced)
+ QApplication::setStyle(new QInterlaceStyle);
+*/
+}
+
+/*****************************************************************************
+ qt_cleanup() - cleans up when the application is finished
+ *****************************************************************************/
+
+void qt_cleanup()
+{
+ QPixmapCache::clear();
+#ifndef QT_NO_CURSOR
+ QCursorData::cleanup();
+#endif
+ QFont::cleanup();
+ QColormap::cleanup();
+
+ if (qws_single_process) {
+ QWSServer::closedown();
+ }
+
+ qDeleteAll(outgoing);
+ outgoing.clear();
+ qDeleteAll(incoming);
+ incoming.clear();
+
+ if (qt_is_gui_used) {
+ delete qt_fbdpy;
+ }
+ qt_fbdpy = 0;
+
+#ifndef QT_NO_QWS_MANAGER
+ delete qws_decoration;
+ qws_decoration = 0;
+#endif
+
+ delete mouseInWidget;
+ mouseInWidget = 0;
+}
+
+
+/*****************************************************************************
+ Platform specific global and internal functions
+ *****************************************************************************/
+
+QString QApplicationPrivate::appName() const // get application name
+{
+ return ::appName;
+}
+
+/*****************************************************************************
+ Platform specific QApplication members
+ *****************************************************************************/
+
+#define NoValue 0x0000
+#define XValue 0x0001
+#define YValue 0x0002
+#define WidthValue 0x0004
+#define HeightValue 0x0008
+#define AllValues 0x000F
+#define XNegative 0x0010
+#define YNegative 0x0020
+
+/* Copyright notice for ReadInteger and parseGeometry
+
+Copyright (c) 1985, 1986, 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+/*
+ * XParseGeometry parses strings of the form
+ * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
+ * width, height, xoffset, and yoffset are unsigned integers.
+ * Example: "=80x24+300-49"
+ * The equal sign is optional.
+ * It returns a bitmask that indicates which of the four values
+ * were actually found in the string. For each value found,
+ * the corresponding argument is updated; for each value
+ * not found, the corresponding argument is left unchanged.
+ */
+
+static int
+ReadInteger(char *string, char **NextString)
+{
+ register int Result = 0;
+ int Sign = 1;
+
+ if (*string == '+')
+ string++;
+ else if (*string == '-')
+ {
+ string++;
+ Sign = -1;
+ }
+ for (; (*string >= '0') && (*string <= '9'); string++)
+ {
+ Result = (Result * 10) + (*string - '0');
+ }
+ *NextString = string;
+ if (Sign >= 0)
+ return Result;
+ else
+ return -Result;
+}
+
+static int parseGeometry(const char* string,
+ int* x, int* y, int* width, int* height)
+{
+ int mask = NoValue;
+ register char *strind;
+ unsigned int tempWidth=0, tempHeight=0;
+ int tempX=0, tempY=0;
+ char *nextCharacter;
+
+ if (!string || (*string == '\0')) return mask;
+ if (*string == '=')
+ string++; /* ignore possible '=' at beg of geometry spec */
+
+ strind = const_cast<char *>(string);
+ if (*strind != '+' && *strind != '-' && *strind != 'x') {
+ tempWidth = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return 0;
+ strind = nextCharacter;
+ mask |= WidthValue;
+ }
+
+ if (*strind == 'x' || *strind == 'X') {
+ strind++;
+ tempHeight = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return 0;
+ strind = nextCharacter;
+ mask |= HeightValue;
+ }
+
+ if ((*strind == '+') || (*strind == '-')) {
+ if (*strind == '-') {
+ strind++;
+ tempX = -ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return 0;
+ strind = nextCharacter;
+ mask |= XNegative;
+
+ }
+ else
+ { strind++;
+ tempX = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return 0;
+ strind = nextCharacter;
+ }
+ mask |= XValue;
+ if ((*strind == '+') || (*strind == '-')) {
+ if (*strind == '-') {
+ strind++;
+ tempY = -ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return 0;
+ strind = nextCharacter;
+ mask |= YNegative;
+
+ }
+ else
+ {
+ strind++;
+ tempY = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return 0;
+ strind = nextCharacter;
+ }
+ mask |= YValue;
+ }
+ }
+
+ /* If strind isn't at the end of the string then it's an invalid
+ geometry specification. */
+
+ if (*strind != '\0') return 0;
+
+ if (mask & XValue)
+ *x = tempX;
+ if (mask & YValue)
+ *y = tempY;
+ if (mask & WidthValue)
+ *width = tempWidth;
+ if (mask & HeightValue)
+ *height = tempHeight;
+ return mask;
+}
+
+#ifdef QT3_SUPPORT
+void QApplication::setMainWidget(QWidget *mainWidget)
+{
+ QApplicationPrivate::main_widget = mainWidget;
+ if (QApplicationPrivate::main_widget) // give WM command line
+ QApplicationPrivate::applyQWSSpecificCommandLineArguments(QApplicationPrivate::main_widget);
+}
+#endif
+
+void QApplicationPrivate::applyQWSSpecificCommandLineArguments(QWidget *main_widget)
+{
+ static bool beenHereDoneThat = false;
+ if (beenHereDoneThat)
+ return;
+ beenHereDoneThat = true;
+ if (qApp->windowIcon().isNull() && main_widget->testAttribute(Qt::WA_SetWindowIcon))
+ qApp->setWindowIcon(main_widget->windowIcon());
+ if (mwTitle) // && main_widget->windowTitle().isEmpty())
+ main_widget->setWindowTitle(QString::fromLocal8Bit(mwTitle));
+ if (mwGeometry) { // parse geometry
+ int x = 0;
+ int y = 0;
+ int w = 0;
+ int h = 0;
+ int m = parseGeometry(mwGeometry, &x, &y, &w, &h);
+ QSize minSize = main_widget->minimumSize();
+ QSize maxSize = main_widget->maximumSize();
+ if ((m & XValue) == 0)
+ x = main_widget->geometry().x();
+ if ((m & YValue) == 0)
+ y = main_widget->geometry().y();
+ if ((m & WidthValue) == 0)
+ w = main_widget->width();
+ if ((m & HeightValue) == 0)
+ h = main_widget->height();
+ w = qMin(w,maxSize.width());
+ h = qMin(h,maxSize.height());
+ w = qMax(w,minSize.width());
+ h = qMax(h,minSize.height());
+ if ((m & XNegative)) {
+ x = qApp->desktop()->width() + x - w;
+ x -= (main_widget->frameGeometry().width() - main_widget->width()) / 2;
+ } else {
+ x += (main_widget->geometry().x() - main_widget->x());
+ }
+ if ((m & YNegative)) {
+ y = qApp->desktop()->height() + y - h;
+ } else {
+ y += (main_widget->geometry().y() - main_widget->y());
+ }
+
+ main_widget->setGeometry(x, y, w, h);
+ }
+}
+
+/*****************************************************************************
+ QApplication cursor stack
+ *****************************************************************************/
+#ifndef QT_NO_CURSOR
+void QApplication::setOverrideCursor(const QCursor &cursor)
+{
+ qApp->d_func()->cursor_list.prepend(cursor);
+
+ QWidget *w = QWidget::mouseGrabber();
+ if (!w && qt_last_x)
+ w = topLevelAt(*qt_last_x, *qt_last_y);
+ if (!w)
+ w = desktop();
+ QPaintDevice::qwsDisplay()->selectCursor(w, qApp->d_func()->cursor_list.first().handle());
+}
+
+void QApplication::restoreOverrideCursor()
+{
+ if (qApp->d_func()->cursor_list.isEmpty())
+ return;
+ qApp->d_func()->cursor_list.removeFirst();
+
+ QWidget *w = QWidget::mouseGrabber();
+ if (!w && qt_last_x)
+ w = topLevelAt(*qt_last_x, *qt_last_y);
+ if (!w)
+ w = desktop();
+
+ int cursor_handle = Qt::ArrowCursor;
+ if (qApp->d_func()->cursor_list.isEmpty()) {
+ qws_overrideCursor = false;
+ QWidget *upw = QApplication::widgetAt(*qt_last_x, *qt_last_y);
+ if (upw)
+ cursor_handle = upw->cursor().handle();
+ } else {
+ cursor_handle = qApp->d_func()->cursor_list.first().handle();
+ }
+ QPaintDevice::qwsDisplay()->selectCursor(w, cursor_handle);
+}
+#endif// QT_NO_CURSOR
+
+
+
+/*****************************************************************************
+ Routines to find a Qt widget from a screen position
+ *****************************************************************************/
+
+/*!
+ \internal
+*/
+QWidget *QApplicationPrivate::findWidget(const QObjectList& list,
+ const QPoint &pos, bool rec)
+{
+ QWidget *w;
+
+ for (int i = list.size()-1; i >= 0; --i) {
+ if (list.at(i)->isWidgetType()) {
+ w = static_cast<QWidget*>(list.at(i));
+ if (w->isVisible() && !w->testAttribute(Qt::WA_TransparentForMouseEvents) && w->geometry().contains(pos)
+ && (!w->d_func()->extra || w->d_func()->extra->mask.isEmpty() || w->d_func()->extra->mask.contains(pos - w->geometry().topLeft()) )) {
+ if (!rec)
+ return w;
+ QWidget *c = w->childAt(w->mapFromParent(pos));
+ return c ? c : w;
+ }
+ }
+ }
+ return 0;
+}
+
+
+QWidget *QApplication::topLevelAt(const QPoint &pos)
+{
+ //### QWSDisplay::windowAt() is currently only implemented in the server process
+ int winId = QPaintDevice::qwsDisplay()->windowAt(pos);
+ if (winId !=0)
+ return QWidget::find(winId);
+
+#if 1
+ // fallback implementation for client processes
+//### This is slightly wrong: we have no guarantee that the list is in
+//### stacking order, so if the topmost window is transparent, we may
+//### return the wrong widget
+
+ QWidgetList list = topLevelWidgets();
+ for (int i = list.size()-1; i >= 0; --i) {
+ QWidget *w = list[i];
+ if (w != QApplication::desktop() &&
+ w->isVisible() && w->d_func()->localAllocatedRegion().contains(w->mapFromParent(pos))
+ )
+ return w;
+ }
+#endif
+ return 0;
+}
+
+void QApplication::beep()
+{
+}
+
+void QApplication::alert(QWidget *, int)
+{
+}
+
+/*!
+ \internal
+*/
+int QApplication::qwsProcessEvent(QWSEvent* event)
+{
+ Q_D(QApplication);
+ QScopedLoopLevelCounter loopLevelCounter(d->threadData);
+ int oldstate = -1;
+ bool isMove = false;
+ if (event->type == QWSEvent::Mouse) {
+ QWSMouseEvent::SimpleData &mouse = event->asMouse()->simpleData;
+ isMove = mouse_x_root != mouse.x_root || mouse_y_root != mouse.y_root;
+ oldstate = mouse_state;
+ mouse_x_root = mouse.x_root;
+ mouse_y_root = mouse.y_root;
+ mouse_state = mouse.state;
+ }
+
+ long unused;
+ if (filterEvent(event, &unused)) // send through app filter
+ return 1;
+
+ if (qwsEventFilter(event)) // send through app filter
+ return 1;
+
+
+#ifndef QT_NO_QWS_PROPERTIES
+ if (event->type == QWSEvent::PropertyNotify) {
+ QWSPropertyNotifyEvent *e = static_cast<QWSPropertyNotifyEvent*>(event);
+ if (e->simpleData.property == 424242) { // Clipboard
+#ifndef QT_NO_CLIPBOARD
+ if (qt_clipboard) {
+ QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
+ QApplication::sendEvent(qt_clipboard, &e);
+ }
+#endif
+ }
+ }
+#endif //QT_NO_QWS_PROPERTIES
+#ifndef QT_NO_COP
+ else if (event->type == QWSEvent::QCopMessage) {
+ QWSQCopMessageEvent *e = static_cast<QWSQCopMessageEvent*>(event);
+ QCopChannel::sendLocally(QLatin1String(e->channel), QLatin1String(e->message), e->data);
+ return 0;
+ }
+#endif
+#if !defined(QT_NO_QWS_QPF2)
+ else if (event->type == QWSEvent::Font) {
+ QWSFontEvent *e = static_cast<QWSFontEvent *>(event);
+ if (e->simpleData.type == QWSFontEvent::FontRemoved) {
+ QFontCache::instance()->removeEngineForFont(e->fontName);
+ }
+ }
+#endif
+
+ QPointer<QETWidget> widget = static_cast<QETWidget*>(QWidget::find(WId(event->window())));
+#ifdef Q_BACKINGSTORE_SUBSURFACES
+ if (!widget) { // XXX: hw: hack for accessing subsurfaces
+ extern QWSWindowSurface* qt_findWindowSurface(int);
+ QWSWindowSurface *s = qt_findWindowSurface(event->window());
+ if (s)
+ widget = static_cast<QETWidget*>(s->window());
+ }
+#endif
+
+#ifndef QT_NO_DIRECTPAINTER
+ if (!widget && d->directPainters) {
+ QDirectPainter *dp = d->directPainters->value(WId(event->window()));
+ if (dp == 0) {
+ } else if (event->type == QWSEvent::Region) {
+ QWSRegionEvent *e = static_cast<QWSRegionEvent*>(event);
+ QRegion reg;
+ reg.setRects(e->rectangles, e->simpleData.nrectangles);
+ qt_directpainter_region(dp, reg, e->simpleData.type);
+ return 1;
+#ifndef QT_NO_QWSEMBEDWIDGET
+ } else if (event->type == QWSEvent::Embed) {
+ QWSEmbedEvent *e = static_cast<QWSEmbedEvent*>(event);
+ qt_directpainter_embedevent(dp, e);
+ return 1;
+ #endif // QT_NO_QWSEMBEDWIDGET
+ }
+ }
+#endif // QT_NO_DIRECTPAINTER
+
+#ifndef QT_NO_QWS_MANAGER
+ if (d->last_manager && event->type == QWSEvent::Mouse) {
+ QPoint pos(event->asMouse()->simpleData.x_root, event->asMouse()->simpleData.y_root);
+ if (!d->last_manager->cachedRegion().contains(pos)) {
+ // MouseEvent not yet delivered, so QCursor::pos() is not yet updated, sending 2 x pos
+ QMouseEvent outside(QEvent::MouseMove, pos, pos, Qt::NoButton, 0, 0);
+ QApplication::sendSpontaneousEvent(d->last_manager, &outside);
+ d->last_manager = 0;
+ qt_last_cursor = 0xffffffff; //decoration is like another window; must redo cursor
+ }
+ }
+#endif // QT_NO_QWS_MANAGER
+
+ QETWidget *keywidget=0;
+ bool grabbed=false;
+ if (event->type==QWSEvent::Key || event->type == QWSEvent::IMEvent || event->type == QWSEvent::IMQuery) {
+ keywidget = static_cast<QETWidget*>(QWidget::keyboardGrabber());
+ if (keywidget) {
+ grabbed = true;
+ } else {
+ if (QWidget *popup = QApplication::activePopupWidget()) {
+ if (popup->focusWidget())
+ keywidget = static_cast<QETWidget*>(popup->focusWidget());
+ else
+ keywidget = static_cast<QETWidget*>(popup);
+ } else if (QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget->isVisible())
+ keywidget = static_cast<QETWidget*>(QApplicationPrivate::focus_widget);
+ else if (widget)
+ keywidget = static_cast<QETWidget*>(widget->window());
+ }
+ } else if (event->type==QWSEvent::MaxWindowRect) {
+ QRect r = static_cast<QWSMaxWindowRectEvent*>(event)->simpleData.rect;
+ setMaxWindowRect(r);
+ return 0;
+#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
+ } else if (event->type == QWSEvent::ScreenTransformation) {
+ QWSScreenTransformationEvent *pe = static_cast<QWSScreenTransformationEvent*>(event);
+ setScreenTransformation(pe->simpleData.screen,
+ pe->simpleData.transformation);
+ return 0;
+#endif
+ } else if (widget && event->type==QWSEvent::Mouse) {
+ // The mouse event is to one of my top-level widgets
+ // which one?
+ const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton;
+ QPoint p(event->asMouse()->simpleData.x_root,
+ event->asMouse()->simpleData.y_root);
+ int mouseButtonState = event->asMouse()->simpleData.state & btnMask;
+ static int btnstate = 0;
+
+ QETWidget *w = static_cast<QETWidget*>(QWidget::mouseGrabber());
+ if (w && !mouseButtonState && qt_pressGrab == w)
+ qt_pressGrab = 0;
+#ifndef QT_NO_QWS_MANAGER
+ if (!w)
+ w = static_cast<QETWidget*>(QWSManager::grabbedMouse());
+#endif
+ if (w) {
+ // Our mouse is grabbed - send it.
+ widget = w;
+ btnstate = mouseButtonState;
+ } else {
+ static QWidget *gw = 0;
+ // Three jobs to do here:
+ // 1. find the child widget this event belongs to.
+ // 2. make sure the cursor is correct.
+ // 3. handle implicit mouse grab due to button press.
+ w = widget; // w is the widget the cursor is in.
+
+ //### ??? alloc_region
+ //#### why should we get events outside alloc_region ????
+ if (1 /*widget->data->alloc_region.contains(dp) */) {
+ // Find the child widget that the cursor is in.
+ w = static_cast<QETWidget*>(widget->childAt(widget->mapFromParent(p)));
+ if (!w)
+ w = widget;
+#ifndef QT_NO_CURSOR
+ // Update Cursor.
+ if (!gw || gw != w || qt_last_cursor == 0xffffffff) {
+ QCursor *curs = 0;
+ if (!qApp->d_func()->cursor_list.isEmpty())
+ curs = &qApp->d_func()->cursor_list.first();
+ else if (w->d_func()->extraData())
+ curs = w->d_func()->extraData()->curs;
+ QWidget *pw = w;
+ // If this widget has no cursor set, try parent.
+ while (!curs) {
+ pw = pw->parentWidget();
+ if (!pw)
+ break;
+ if (pw->d_func()->extraData())
+ curs = pw->d_func()->extraData()->curs;
+ }
+ if (!qws_overrideCursor) {
+ if (curs)
+ QPaintDevice::qwsDisplay()->selectCursor(widget, curs->handle());
+ else
+ QPaintDevice::qwsDisplay()->selectCursor(widget, Qt::ArrowCursor);
+ }
+ }
+#endif
+ gw = w;
+ } else {
+ // This event is not for any of our widgets
+ gw = 0;
+ }
+ if (mouseButtonState && !btnstate) {
+ // The server has grabbed the mouse for us.
+ // Remember which of my widgets has it.
+ qt_pressGrab = w;
+ if (!widget->isActiveWindow() &&
+ (!app_do_modal || QApplication::activeModalWidget() == widget) &&
+ !((widget->windowFlags() & Qt::FramelessWindowHint) || (widget->windowType() == Qt::Tool))) {
+ widget->activateWindow();
+ if (widget->raiseOnClick())
+ widget->raise();
+ }
+ }
+ btnstate = mouseButtonState;
+ widget = w;
+ }
+ }
+
+ if (!widget) { // don't know this window
+ if (!QWidget::mouseGrabber()
+#ifndef QT_NO_QWS_MANAGER
+ && !QWSManager::grabbedMouse()
+#endif
+ ) {
+ qt_last_cursor = 0xffffffff; // cursor can be changed by another application
+ }
+
+ QWidget* popup = QApplication::activePopupWidget();
+ if (popup) {
+
+ /*
+ That is more than suboptimal. The real solution should
+ do some keyevent and buttonevent translation, so that
+ the popup still continues to work as the user expects.
+ Unfortunately this translation is currently only
+ possible with a known widget. I'll change that soon
+ (Matthias).
+ */
+
+ // Danger - make sure we don't lock the server
+ switch (event->type) {
+ case QWSEvent::Mouse:
+ case QWSEvent::Key:
+ do {
+ popup->close();
+ } while ((popup = qApp->activePopupWidget()));
+ return 1;
+ }
+ }
+ if (event->type == QWSEvent::Mouse && *mouseInWidget) {
+ QApplicationPrivate::dispatchEnterLeave(0, *mouseInWidget);
+ (*mouseInWidget) = 0;
+ }
+ return -1;
+ }
+
+ if (app_do_modal) // modal event handling
+ if (!qt_try_modal(widget, event)) {
+ return 1;
+ }
+
+ if (widget->qwsEvent(event)) // send through widget filter
+ return 1;
+ switch (event->type) {
+
+ case QWSEvent::Mouse: { // mouse event
+ QWSMouseEvent *me = event->asMouse();
+ QWSMouseEvent::SimpleData &mouse = me->simpleData;
+
+ // Translate a QWS event into separate move
+ // and press/release events
+ // Beware of reentrancy: we can enter a modal state
+ // inside translateMouseEvent
+
+ if (isMove) {
+ QWSMouseEvent move = *me;
+ move.simpleData.state = oldstate;
+ widget->translateMouseEvent(&move, oldstate);
+ }
+ if ((mouse.state&Qt::MouseButtonMask) != (oldstate&Qt::MouseButtonMask)) {
+ widget->translateMouseEvent(me, oldstate);
+ }
+
+ if (mouse.delta != 0)
+ widget->translateWheelEvent(me);
+
+ if (qt_button_down && (mouse_state & Qt::MouseButtonMask) == 0)
+ qt_button_down = 0;
+
+ break;
+ }
+ case QWSEvent::Key: // keyboard event
+ if (keywidget) // should always exist
+ keywidget->translateKeyEvent(static_cast<QWSKeyEvent*>(event), grabbed);
+ break;
+
+#ifndef QT_NO_QWS_INPUTMETHODS
+ case QWSEvent::IMEvent:
+ if (keywidget) // should always exist
+ QWSInputContext::translateIMEvent(keywidget, static_cast<QWSIMEvent*>(event));
+ break;
+
+ case QWSEvent::IMQuery:
+ if (keywidget) // should always exist
+ QWSInputContext::translateIMQueryEvent(keywidget, static_cast<QWSIMQueryEvent*>(event));
+ break;
+
+ case QWSEvent::IMInit:
+ QWSInputContext::translateIMInitEvent(static_cast<QWSIMInitEvent*>(event));
+ break;
+#endif
+ case QWSEvent::Region:
+ widget->translateRegionEvent(static_cast<QWSRegionEvent*>(event));
+ break;
+ case QWSEvent::Focus:
+ if ((static_cast<QWSFocusEvent*>(event))->simpleData.get_focus) {
+ if (widget == static_cast<QWidget *>(desktop()))
+ return true; // not interesting
+ if (activeWindow() != widget) {
+ setActiveWindow(widget);
+ if (QApplicationPrivate::active_window)
+ static_cast<QETWidget *>(QApplicationPrivate::active_window)->repaintDecoration(desktop()->rect(), false);
+ if (widget && !d->inPopupMode()) {
+ QWidget *w = widget->focusWidget();
+ while (w && w->focusProxy())
+ w = w->focusProxy();
+ if (w && (w->focusPolicy() != Qt::NoFocus))
+ w->setFocus();
+ else
+ widget->QWidget::focusNextPrevChild(true);
+ if (!QApplicationPrivate::focus_widget) {
+ if (widget->focusWidget())
+ widget->focusWidget()->setFocus();
+ else
+ widget->window()->setFocus();
+ }
+ }
+ }
+ } else { // lost focus
+ if (widget == static_cast<QWidget *>(desktop()))
+ return true; // not interesting
+ if (QApplicationPrivate::focus_widget) {
+ QETWidget *old = static_cast<QETWidget *>(QApplicationPrivate::active_window);
+ setActiveWindow(0);
+ qt_last_cursor = 0xffffffff;
+ //QApplicationPrivate::active_window = 0;
+ if (old)
+ old->repaintDecoration(desktop()->rect(), false);
+ /* activateWindow() sends focus events
+ QApplication::setFocusWidget(0);
+ */
+ }
+ }
+ break;
+
+ case QWSEvent::WindowOperation:
+ if (static_cast<QWidget *>(widget) == desktop())
+ return true;
+ switch ((static_cast<QWSWindowOperationEvent *>(event))->simpleData.op) {
+ case QWSWindowOperationEvent::Show:
+ widget->show();
+ break;
+ case QWSWindowOperationEvent::Hide:
+ widget->hide();
+ break;
+ case QWSWindowOperationEvent::ShowMaximized:
+ widget->showMaximized();
+ break;
+ case QWSWindowOperationEvent::ShowMinimized:
+ widget->showMinimized();
+ break;
+ case QWSWindowOperationEvent::ShowNormal:
+ widget->showNormal();
+ break;
+ case QWSWindowOperationEvent::Close:
+ widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
+ break;
+ }
+ break;
+#ifndef QT_NO_QWSEMBEDWIDGET
+ case QWSEvent::Embed:
+ widget->translateEmbedEvent(static_cast<QWSEmbedEvent*>(event));
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/*!
+ \fn bool QApplication::qwsEventFilter(QWSEvent *event)
+
+ This virtual function is only implemented under Qt for Embedded Linux.
+
+ If you create an application that inherits QApplication and
+ reimplement this function, you get direct access to all QWS (Q
+ Window System) events that the are received from the QWS master
+ process. The events are passed in the \a event parameter.
+
+ Return true if you want to stop the event from being processed.
+ Return false for normal event dispatching. The default
+ implementation returns false.
+*/
+bool QApplication::qwsEventFilter(QWSEvent *)
+{
+ return false;
+}
+
+/*!
+ Set Qt for Embedded Linux custom color table.
+
+ Qt for Embedded Linux on 8-bpp displays allocates a standard 216 color cube.
+ The remaining 40 colors may be used by setting a custom color
+ table in the QWS master process before any clients connect.
+
+ \a colorTable is an array of up to 40 custom colors. \a start is
+ the starting index (0-39) and \a numColors is the number of colors
+ to be set (1-40).
+
+ This method is non-portable. It is available \e only in
+ Qt for Embedded Linux.
+
+ \note The custom colors will not be used by the default screen
+ driver. To make use of the new colors, implement a custom screen
+ driver, or use QDirectPainter.
+*/
+void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors)
+{
+ if (start < 0 || start > 39) {
+ qWarning("QApplication::qwsSetCustomColors: start < 0 || start > 39");
+ return;
+ }
+ if (start + numColors > 40) {
+ numColors = 40 - start;
+ qWarning("QApplication::qwsSetCustomColors: Too many colors");
+ }
+ start += 216;
+ for (int i = 0; i < numColors; i++) {
+ qt_screen->set(start + i, qRed(colorTable[i]), qGreen(colorTable[i]),
+ qBlue(colorTable[i]));
+ }
+}
+
+#ifndef QT_NO_QWS_MANAGER
+/*!
+ Return the QWSDecoration used for decorating windows.
+
+ \warning This method is non-portable. It is only available in
+ Qt for Embedded Linux.
+
+ \sa QDecoration
+*/
+QDecoration &QApplication::qwsDecoration()
+{
+ return *qws_decoration;
+}
+
+/*!
+ \fn void QApplication::qwsSetDecoration(QDecoration *decoration)
+
+ Sets the QDecoration derived class to use for decorating the
+ windows used by Qt for Embedded Linux to the \a decoration
+ specified.
+
+ This method is non-portable. It is only available in Qt for Embedded Linux.
+
+ \sa QDecoration
+*/
+void QApplication::qwsSetDecoration(QDecoration *dec)
+{
+ if (dec) {
+ delete qws_decoration;
+ qws_decoration = dec;
+ QWidgetList widgets = topLevelWidgets();
+ for (int i = 0; i < widgets.size(); ++i) {
+ QWidget *w = widgets[i];
+ if (w->isVisible() && w != desktop()) {
+ static_cast<QETWidget *>(w)->updateRegion();
+ static_cast<QETWidget *>(w)->repaintDecoration(desktop()->rect(), false);
+ if (w->isMaximized())
+ w->showMaximized();
+ }
+ }
+ }
+}
+
+/*!
+ \overload
+
+ Requests a QDecoration object for \a decoration from the QDecorationFactory.
+
+ The string must be one of the QDecorationFactory::keys(). Keys are
+ case insensitive.
+
+ A later call to the QApplication constructor will override the
+ requested style when a "-style" option is passed in as a commandline
+ parameter.
+
+ Returns 0 if an unknown \a decoration is passed, otherwise the QStyle object
+ returned is set as the application's GUI style.
+*/
+QDecoration* QApplication::qwsSetDecoration(const QString &decoration)
+{
+ QDecoration *decore = QDecorationFactory::create(decoration);
+ if (!decore)
+ return 0;
+
+ qwsSetDecoration(decore);
+ return decore;
+}
+
+#endif
+
+bool QApplicationPrivate::modalState()
+{
+ return app_do_modal;
+}
+
+void QApplicationPrivate::enterModal_sys(QWidget *widget)
+{
+ if (!qt_modal_stack)
+ qt_modal_stack = new QWidgetList;
+ qt_modal_stack->insert(0, widget);
+ app_do_modal = true;
+}
+
+void QApplicationPrivate::leaveModal_sys(QWidget *widget)
+{
+ if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
+ if (qt_modal_stack->isEmpty()) {
+ delete qt_modal_stack;
+ qt_modal_stack = 0;
+ }
+ }
+ app_do_modal = qt_modal_stack != 0;
+}
+
+static bool qt_try_modal(QWidget *widget, QWSEvent *event)
+{
+ QWidget * top = 0;
+
+ if (QApplicationPrivate::tryModalHelper(widget, &top))
+ return true;
+
+ bool block_event = false;
+ bool paint_event = false;
+
+ switch (event->type) {
+ case QWSEvent::Focus:
+ if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
+ break;
+ // drop through
+ case QWSEvent::Mouse: // disallow mouse/key events
+ case QWSEvent::Key:
+ block_event = true;
+ break;
+ }
+
+ if (top->parentWidget() == 0 && (block_event || paint_event))
+ top->raise();
+
+ return !block_event;
+}
+
+static int openPopupCount = 0;
+void QApplicationPrivate::openPopup(QWidget *popup)
+{
+ openPopupCount++;
+ if (!popupWidgets) { // create list
+ popupWidgets = new QWidgetList;
+
+ /* only grab if you are the first/parent popup */
+ QPaintDevice::qwsDisplay()->grabMouse(popup,true);
+ QPaintDevice::qwsDisplay()->grabKeyboard(popup,true);
+ popupGrabOk = true;
+ }
+ popupWidgets->append(popup); // add to end of list
+
+ // popups are not focus-handled by the window system (the first
+ // popup grabbed the keyboard), so we have to do that manually: A
+ // new popup gets the focus
+ if (popup->focusWidget()) {
+ popup->focusWidget()->setFocus(Qt::PopupFocusReason);
+ } else if (popupWidgets->count() == 1) { // this was the first popup
+ if (QWidget *fw = QApplication::focusWidget()) {
+ QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
+ QApplication::sendEvent(fw, &e);
+ }
+ }
+}
+
+void QApplicationPrivate::closePopup(QWidget *popup)
+{
+ if (!popupWidgets)
+ return;
+
+ popupWidgets->removeAll(popup);
+ if (popup == popupOfPopupButtonFocus) {
+ popupButtonFocus = 0;
+ popupOfPopupButtonFocus = 0;
+ }
+ if (popupWidgets->count() == 0) { // this was the last popup
+ popupCloseDownMode = true; // control mouse events
+ delete popupWidgets;
+ popupWidgets = 0;
+ if (popupGrabOk) { // grabbing not disabled
+ QPaintDevice::qwsDisplay()->grabMouse(popup,false);
+ QPaintDevice::qwsDisplay()->grabKeyboard(popup,false);
+ popupGrabOk = false;
+ // XXX ungrab keyboard
+ }
+ if (active_window) {
+ if (QWidget *fw = active_window->focusWidget()) {
+ if (fw != QApplication::focusWidget()) {
+ fw->setFocus(Qt::PopupFocusReason);
+ } else {
+ QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
+ QApplication::sendEvent(fw, &e);
+ }
+ }
+ }
+ } else {
+ // popups are not focus-handled by the window system (the
+ // first popup grabbed the keyboard), so we have to do that
+ // manually: A popup was closed, so the previous popup gets
+ // the focus.
+ QWidget* aw = popupWidgets->last();
+ if (QWidget *fw = aw->focusWidget())
+ fw->setFocus(Qt::PopupFocusReason);
+ }
+}
+
+/*****************************************************************************
+ Event translation; translates FB events to Qt events
+ *****************************************************************************/
+
+//
+// Mouse event translation
+//
+// FB doesn't give mouse double click events, so we generate them by
+// comparing window, time and position between two mouse press events.
+//
+
+
+// Needed for QCursor::pos
+
+static const int AnyButton = (Qt::LeftButton | Qt::MidButton | Qt::RightButton);
+
+
+
+//
+// Wheel event translation
+//
+bool QETWidget::translateWheelEvent(const QWSMouseEvent *me)
+{
+#ifdef QT_NO_WHEELEVENT
+ Q_UNUSED(me);
+ return false;
+#else
+ const QWSMouseEvent::SimpleData &mouse = me->simpleData;
+
+ // Figure out wheeling direction:
+ // Horizontal wheel w/o Alt
+ // OR Vertical wheel w/ Alt ==> Horizontal wheeling
+ // ..all other permutations ==> Vertical wheeling
+ int axis = mouse.delta / 120; // WHEEL_DELTA?
+ Qt::Orientation orient = ((axis == 2 || axis == -2) && ((mouse.state & Qt::AltModifier) == 0))
+ ||((axis == 1 || axis == -1) && mouse.state & Qt::AltModifier)
+ ? Qt::Horizontal : Qt::Vertical;
+
+ QPoint mousePoint = QPoint(mouse.x_root, mouse.y_root);
+
+ // send the event to the widget or its ancestors
+ QWidget* popup = qApp->activePopupWidget();
+ if (popup && window() != popup)
+ popup->close();
+ QWheelEvent we(mapFromGlobal(mousePoint), mousePoint, mouse.delta,
+ Qt::MouseButtons(mouse.state & Qt::MouseButtonMask),
+ Qt::KeyboardModifiers(mouse.state & Qt::KeyboardModifierMask), orient);
+ if (QApplication::sendSpontaneousEvent(this, &we))
+ return true;
+
+ // send the event to the widget that has the focus or its ancestors, if different
+ QWidget *w = this;
+ if (w != qApp->focusWidget() && (w = qApp->focusWidget())) {
+ QWidget* popup = qApp->activePopupWidget();
+ if (popup && w != popup)
+ popup->hide();
+ if (QApplication::sendSpontaneousEvent(w, &we))
+ return true;
+ }
+ return false;
+#endif
+}
+
+bool QETWidget::translateMouseEvent(const QWSMouseEvent *event, int prevstate)
+{
+ static bool manualGrab = false;
+ QPoint pos;
+ QPoint globalPos;
+ int button = 0;
+
+ if (sm_blockUserInput) // block user interaction during session management
+ return true;
+ const QWSMouseEvent::SimpleData &mouse = event->simpleData;
+ pos = mapFromGlobal(QPoint(mouse.x_root, mouse.y_root));
+// if (qt_last_x) {
+// *qt_last_x=mouse.x_root;
+// *qt_last_y=mouse.y_root;
+// }
+ globalPos.rx() = mouse.x_root;
+ globalPos.ry() = mouse.y_root;
+
+ QEvent::Type type = QEvent::None;
+
+ Qt::MouseButtons buttonstate = Qt::MouseButtons(mouse.state & Qt::MouseButtonMask);
+ Qt::KeyboardModifiers keystate = Qt::KeyboardModifiers(mouse.state & Qt::KeyboardModifierMask);
+
+ if (mouse.state == prevstate) {
+ // mouse move
+ type = QEvent::MouseMove;
+ } else if ((mouse.state&AnyButton) != (prevstate&AnyButton)) {
+ Qt::MouseButtons current_buttons = Qt::MouseButtons(prevstate&Qt::MouseButtonMask);
+ for (button = Qt::LeftButton; !type && button <= Qt::MidButton; button<<=1) {
+ if ((mouse.state&button) != (current_buttons&button)) {
+ // button press or release
+ current_buttons = Qt::MouseButtons(current_buttons ^ button);
+
+#ifndef QT_NO_QWS_INPUTMETHODS
+ //############ We used to do a QInputContext::reset(oldFocus);
+ // when we changed the focus widget. See change 93389 for where the
+ // focus code went. The IM code was (after testing for ClickToFocus):
+ //if (mouse.state&button && w != QInputContext::microFocusWidget()) //button press
+ // QInputContext::reset(oldFocus);
+
+#endif
+ if (mouse.state&button) { //button press
+ qt_button_down = childAt(pos);
+ if (!qt_button_down)
+ qt_button_down = this;
+ if (/*XXX mouseActWindow == this &&*/
+ mouseButtonPressed == button &&
+ long(mouse.time) -long(mouseButtonPressTime)
+ < QApplication::doubleClickInterval() &&
+ qAbs(mouse.x_root - mouseXPos) < mouse_double_click_distance &&
+ qAbs(mouse.y_root - mouseYPos) < mouse_double_click_distance ) {
+ type = QEvent::MouseButtonDblClick;
+ mouseButtonPressTime -= 2000; // no double-click next time
+ } else {
+ type = QEvent::MouseButtonPress;
+ mouseButtonPressTime = mouse.time;
+ }
+ mouseButtonPressed = button; // save event params for
+ mouseXPos = globalPos.x(); // future double click tests
+ mouseYPos = globalPos.y();
+ } else { // mouse button released
+ if (manualGrab) { // release manual grab
+ manualGrab = false;
+ // XXX XUngrabPointer(x11Display(), CurrentTime);
+ }
+
+ type = QEvent::MouseButtonRelease;
+ }
+ }
+ }
+ button >>= 1;
+ }
+ //XXX mouseActWindow = winId(); // save some event params
+
+ if (type == 0) { // event consumed
+ return false; //EXIT in the normal case
+ }
+
+ if (qApp->d_func()->inPopupMode()) { // in popup mode
+ QWidget *popup = qApp->activePopupWidget();
+ // in X11, this would be the window we are over.
+ // in QWS this is the top level popup. to allow mouse
+ // events to other widgets, need to go through qApp->QApplicationPrivate::popupWidgets.
+ QSize s(qt_screen->width(), qt_screen->height());
+ for (int i = 0; i < QApplicationPrivate::popupWidgets->size(); ++i) {
+ QWidget *w = QApplicationPrivate::popupWidgets->at(i);
+
+ if ((w->windowType() == Qt::Popup) && w->d_func()->localAllocatedRegion().contains(globalPos - w->geometry().topLeft()))
+ {
+ popup = w;
+ break;
+ }
+ }
+ pos = popup->mapFromGlobal(globalPos);
+ bool releaseAfter = false;
+ QWidget *popupChild = popup->childAt(pos);
+ QWidget *popupTarget = popupChild ? popupChild : popup;
+
+ if (popup != popupOfPopupButtonFocus){
+ popupButtonFocus = 0;
+ popupOfPopupButtonFocus = 0;
+ }
+
+ if (!popupTarget->isEnabled()) {
+ return false; //EXIT special case
+ }
+
+ switch (type) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ popupButtonFocus = popupChild;
+ popupOfPopupButtonFocus = popup;
+ break;
+ case QEvent::MouseButtonRelease:
+ releaseAfter = true;
+ break;
+ default:
+ break; // nothing for mouse move
+ }
+
+ int oldOpenPopupCount = openPopupCount;
+
+ if (popupButtonFocus) {
+ QMouseEvent e(type, popupButtonFocus->mapFromGlobal(globalPos),
+ globalPos, Qt::MouseButton(button), buttonstate, keystate);
+ QApplication::sendSpontaneousEvent(popupButtonFocus, & e);
+ if (releaseAfter) {
+ popupButtonFocus = 0;
+ popupOfPopupButtonFocus = 0;
+ }
+ } else if (popupChild) {
+ QMouseEvent e(type, popupChild->mapFromGlobal(globalPos),
+ globalPos, Qt::MouseButton(button), buttonstate, keystate);
+ QApplication::sendSpontaneousEvent(popupChild, & e);
+ } else {
+ QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), buttonstate, keystate);
+ QApplication::sendSpontaneousEvent(popupChild ? popupChild : popup, & e);
+ }
+#ifndef QT_NO_CONTEXTMENU
+ if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
+ QWidget *popupEvent = popup;
+ if(popupButtonFocus)
+ popupEvent = popupButtonFocus;
+ else if(popupChild)
+ popupEvent = popupChild;
+ QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, keystate);
+ QApplication::sendSpontaneousEvent(popupEvent, &e);
+ }
+#endif // QT_NO_CONTEXTMENU
+
+ if (releaseAfter)
+ qt_button_down = 0;
+
+ } else { //qApp not in popup mode
+ QWidget *widget = this;
+ QWidget *w = QWidget::mouseGrabber();
+ if (!w && qt_button_down)
+ w = qt_button_down;
+ if (w && w != this) {
+ widget = w;
+ pos = mapToGlobal(pos);
+ pos = w->mapFromGlobal(pos);
+ }
+
+ if (popupCloseDownMode) {
+ popupCloseDownMode = false;
+ if ((windowType() == Qt::Popup)) // ignore replayed event
+ return true; //EXIT
+ }
+
+ QPointer<QWidget> leaveAfterRelease = 0;
+ if (type == QEvent::MouseButtonRelease &&
+ (mouse.state & (~button) & (Qt::LeftButton |
+ Qt::MidButton |
+ Qt::RightButton)) == 0) {
+ // Button released outside the widget -> leave the widget after the
+ // release event has been delivered.
+ if (widget == qt_button_down && (pos.x() < 0 || pos.y() < 0))
+ leaveAfterRelease = qt_button_down;
+ qt_button_down = 0;
+ }
+
+ int oldOpenPopupCount = openPopupCount;
+
+ QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), buttonstate, keystate);
+#ifndef QT_NO_QWS_MANAGER
+ if (widget->isWindow() && widget->d_func()->topData()->qwsManager
+ && (widget->d_func()->topData()->qwsManager->region().contains(globalPos)
+ || QWSManager::grabbedMouse() )) {
+ if ((*mouseInWidget)) {
+ QApplicationPrivate::dispatchEnterLeave(0, *mouseInWidget);
+ (*mouseInWidget) = 0;
+ }
+ QApplication::sendSpontaneousEvent(widget->d_func()->topData()->qwsManager, &e);
+ qApp->d_func()->last_manager = widget->d_func()->topData()->qwsManager;
+ } else
+#endif
+ {
+ if (widget != (*mouseInWidget)) {
+ QApplicationPrivate::dispatchEnterLeave(widget, *mouseInWidget);
+ (*mouseInWidget) = widget;
+ }
+ QApplication::sendSpontaneousEvent(widget, &e);
+ if (leaveAfterRelease && !QWidget::mouseGrabber()) {
+ *mouseInWidget = QApplication::widgetAt(globalPos);
+ QApplicationPrivate::dispatchEnterLeave(*mouseInWidget, leaveAfterRelease);
+ leaveAfterRelease = 0;
+ }
+ }
+#ifndef QT_NO_CONTEXTMENU
+ if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
+ QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, keystate);
+ QApplication::sendSpontaneousEvent(widget, &e);
+ }
+#endif // QT_NO_CONTEXTMENU
+ }
+ return true;
+}
+
+
+bool QETWidget::translateKeyEvent(const QWSKeyEvent *event, bool grab) /* grab is used in the #ifdef */
+{
+ int code = -1;
+ //### Qt assumes keyboard state is state *before*, while QWS uses state after the event
+ static Qt::KeyboardModifiers oldstate;
+ Qt::KeyboardModifiers state = oldstate;
+ oldstate = event->simpleData.modifiers;
+
+ if (sm_blockUserInput) // block user interaction during session management
+ return true;
+
+ if (!isEnabled())
+ return true;
+
+ QEvent::Type type = event->simpleData.is_press ?
+ QEvent::KeyPress : QEvent::KeyRelease;
+ bool autor = event->simpleData.is_auto_repeat;
+ QString text;
+ char ascii = 0;
+ if (event->simpleData.unicode) {
+ QChar ch(event->simpleData.unicode);
+ if (ch.unicode() != 0xffff)
+ text += ch;
+ ascii = ch.toLatin1();
+ }
+ code = event->simpleData.keycode;
+
+#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
+ if (type == QEvent::KeyPress && !grab
+ && static_cast<QApplicationPrivate*>(qApp->d_ptr)->use_compat()) {
+ // send accel events if the keyboard is not grabbed
+ QKeyEvent a(type, code, state, text, autor, int(text.length()));
+ if (static_cast<QApplicationPrivate*>(qApp->d_ptr)->qt_tryAccelEvent(this, &a))
+ return true;
+ }
+#else
+ Q_UNUSED(grab);
+#endif
+ if (!text.isEmpty() && testAttribute(Qt::WA_KeyCompression)) {
+ // the widget wants key compression so it gets it
+
+ // XXX not implemented
+ }
+
+ QKeyEvent e(type, code, state, text, autor, int(text.length()));
+ return QApplication::sendSpontaneousEvent(this, &e);
+}
+
+bool QETWidget::translateRegionEvent(const QWSRegionEvent *event)
+{
+ QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(windowSurface());
+ Q_ASSERT(surface);
+
+ QRegion region;
+ region.setRects(event->rectangles, event->simpleData.nrectangles);
+
+ switch (event->simpleData.type) {
+ case QWSRegionEvent::Allocation:
+ region.translate(-mapToGlobal(QPoint()));
+ surface->setClipRegion(region);
+ break;
+#ifdef QT_QWS_CLIENTBLIT
+ case QWSRegionEvent::DirectPaint:
+ surface->setDirectRegion(region, event->simpleData.id);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return true;
+}
+
+#ifndef QT_NO_QWSEMBEDWIDGET
+void QETWidget::translateEmbedEvent(const QWSEmbedEvent *event)
+{
+ if (event->simpleData.type | QWSEmbedEvent::Region) {
+ const QRegion region = event->region;
+ setGeometry(region.boundingRect());
+ setVisible(!region.isEmpty());
+ }
+}
+#endif // QT_NO_QWSEMBEDWIDGET
+
+void QETWidget::repaintDecoration(QRegion r, bool post)
+{
+ Q_UNUSED(post);
+#ifdef QT_NO_QWS_MANAGER
+ Q_UNUSED(r);
+#else
+ //please note that qwsManager is a QObject, not a QWidget.
+ //therefore, normal ways of painting do not work.
+ // However, it does listen to paint events.
+
+ Q_D(QWidget);
+ if (isWindow() && d->topData()->qwsManager && isVisible()) {
+ QWSManager *manager = d->topData()->qwsManager;
+ r &= manager->region();
+ if (!r.isEmpty())
+ manager->repaintRegion(QDecoration::All, QDecoration::Normal);
+ }
+#endif
+}
+
+void QETWidget::updateRegion()
+{
+ Q_D(QWidget);
+
+ QTLWExtra *topextra = d->maybeTopData();
+ if (!topextra)
+ return;
+
+ QRegion myregion = d->localRequestedRegion();
+ myregion.translate(geometry().topLeft());
+
+#ifndef QT_NO_QWS_MANAGER
+ QWSManager *manager = topextra->qwsManager;
+ if (manager)
+ myregion += manager->region();
+#endif
+
+ QRect br(myregion.boundingRect());
+ topextra->frameStrut.setCoords(d->data.crect.x() - br.x(),
+ d->data.crect.y() - br.y(),
+ br.right() - d->data.crect.right(),
+ br.bottom() - d->data.crect.bottom());
+}
+
+void QApplication::setCursorFlashTime(int msecs)
+{
+ QApplicationPrivate::cursor_flash_time = msecs;
+}
+
+
+int QApplication::cursorFlashTime()
+{
+ return QApplicationPrivate::cursor_flash_time;
+}
+
+void QApplication::setDoubleClickInterval(int ms)
+{
+ QApplicationPrivate::mouse_double_click_time = ms;
+}
+
+int QApplication::doubleClickInterval()
+{
+ return QApplicationPrivate::mouse_double_click_time;
+}
+
+void QApplication::setKeyboardInputInterval(int ms)
+{
+ QApplicationPrivate::keyboard_input_time = ms;
+}
+
+int QApplication::keyboardInputInterval()
+{
+ return QApplicationPrivate::keyboard_input_time;
+}
+
+#ifndef QT_NO_WHEELEVENT
+void QApplication::setWheelScrollLines(int lines)
+{
+ QApplicationPrivate::wheel_scroll_lines = lines;
+}
+
+int QApplication::wheelScrollLines()
+{
+ return QApplicationPrivate::wheel_scroll_lines;
+}
+#endif
+
+void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
+{
+ switch (effect) {
+ case Qt::UI_AnimateMenu:
+ QApplicationPrivate::animate_menu = enable;
+ break;
+ case Qt::UI_FadeMenu:
+ if (enable)
+ QApplicationPrivate::animate_menu = true;
+ QApplicationPrivate::fade_menu = enable;
+ break;
+ case Qt::UI_AnimateCombo:
+ QApplicationPrivate::animate_combo = enable;
+ break;
+ case Qt::UI_AnimateTooltip:
+ QApplicationPrivate::animate_tooltip = enable;
+ break;
+ case Qt::UI_FadeTooltip:
+ if (enable)
+ QApplicationPrivate::animate_tooltip = true;
+ QApplicationPrivate::fade_tooltip = enable;
+ break;
+ case Qt::UI_AnimateToolBox:
+ QApplicationPrivate::animate_toolbox = enable;
+ break;
+ default:
+ QApplicationPrivate::animate_ui = enable;
+ break;
+ }
+}
+
+bool QApplication::isEffectEnabled(Qt::UIEffect effect)
+{
+ if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
+ return false;
+
+ switch(effect) {
+ case Qt::UI_AnimateMenu:
+ return QApplicationPrivate::animate_menu;
+ case Qt::UI_FadeMenu:
+ return QApplicationPrivate::fade_menu;
+ case Qt::UI_AnimateCombo:
+ return QApplicationPrivate::animate_combo;
+ case Qt::UI_AnimateTooltip:
+ return QApplicationPrivate::animate_tooltip;
+ case Qt::UI_FadeTooltip:
+ return QApplicationPrivate::fade_tooltip;
+ case Qt::UI_AnimateToolBox:
+ return QApplicationPrivate::animate_toolbox;
+ default:
+ return QApplicationPrivate::animate_ui;
+ }
+}
+
+void QApplication::setArgs(int c, char **v)
+{
+ Q_D(QApplication);
+ d->argc = c;
+ d->argv = v;
+}
+
+QT_END_NAMESPACE