src/gui/kernel/qapplication_qws.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qglobal.h"
       
    43 #include "qlibrary.h"
       
    44 #include "qcursor.h"
       
    45 #include "qapplication.h"
       
    46 #include "private/qapplication_p.h"
       
    47 #include "qwidget.h"
       
    48 #include "qbitarray.h"
       
    49 #include "qpainter.h"
       
    50 #include "qpixmapcache.h"
       
    51 #include "qdatetime.h"
       
    52 #include "qtextcodec.h"
       
    53 #include "qdatastream.h"
       
    54 #include "qbuffer.h"
       
    55 #include "qsocketnotifier.h"
       
    56 #include "qsessionmanager.h"
       
    57 #include "qclipboard.h"
       
    58 #include "qbitmap.h"
       
    59 #include "qwssocket_qws.h"
       
    60 #include "qtransportauth_qws.h"
       
    61 #include "private/qtransportauth_qws_p.h"
       
    62 #include "qwsevent_qws.h"
       
    63 #include "private/qwscommand_qws_p.h"
       
    64 #include "qwsproperty_qws.h"
       
    65 #include "qscreen_qws.h"
       
    66 #include "qscreenproxy_qws.h"
       
    67 #include "qcopchannel_qws.h"
       
    68 #include "private/qlock_p.h"
       
    69 #include "private/qwslock_p.h"
       
    70 //#include "qmemorymanager_qws.h"
       
    71 #include "qwsmanager_qws.h"
       
    72 //#include "qwsregionmanager_qws.h"
       
    73 #include "qwindowsystem_qws.h"
       
    74 #include "private/qwindowsystem_p.h"
       
    75 #include "qdecorationfactory_qws.h"
       
    76 
       
    77 #include "qwsdisplay_qws.h"
       
    78 #include "private/qwsdisplay_qws_p.h"
       
    79 #include "private/qwsinputcontext_p.h"
       
    80 #include "qfile.h"
       
    81 #include "qhash.h"
       
    82 #include "qdesktopwidget.h"
       
    83 #include "qcolormap.h"
       
    84 #include "private/qcursor_p.h"
       
    85 #include "qsettings.h"
       
    86 #include "qdebug.h"
       
    87 #include "qeventdispatcher_qws_p.h"
       
    88 #if !defined(QT_NO_GLIB)
       
    89 #  include "qeventdispatcher_glib_qws_p.h"
       
    90 #endif
       
    91 
       
    92 
       
    93 #include "private/qwidget_p.h"
       
    94 #include "private/qbackingstore_p.h"
       
    95 #include "private/qwindowsurface_qws_p.h"
       
    96 #include "private/qfont_p.h"
       
    97 
       
    98 #include <unistd.h>
       
    99 #include <stdio.h>
       
   100 #include <stdlib.h>
       
   101 #include <string.h>
       
   102 #include <locale.h>
       
   103 #include <errno.h>
       
   104 #include <fcntl.h>
       
   105 #ifdef Q_OS_VXWORKS
       
   106 #  include <sys/times.h>
       
   107 #else
       
   108 #  include <sys/time.h>
       
   109 #endif
       
   110 #include <sys/stat.h>
       
   111 #include <sys/types.h>
       
   112 
       
   113 #include <qvfbhdr.h>
       
   114 
       
   115 #ifndef QT_NO_QWS_MULTIPROCESS
       
   116 #ifdef QT_NO_QSHM
       
   117 #include <sys/ipc.h>
       
   118 #include <sys/shm.h>
       
   119 #ifndef Q_OS_DARWIN
       
   120 # include <sys/sem.h>
       
   121 #endif
       
   122 #include <sys/socket.h>
       
   123 #else
       
   124 #include "private/qwssharedmemory_p.h"
       
   125 #endif
       
   126 #endif
       
   127 
       
   128 QT_BEGIN_NAMESPACE
       
   129 
       
   130 #ifndef QT_NO_DIRECTPAINTER
       
   131 class QDirectPainter;
       
   132 extern void qt_directpainter_region(QDirectPainter *dp, const QRegion &alloc, int type);
       
   133 #ifndef QT_NO_QWSEMBEDWIDGET
       
   134 extern void qt_directpainter_embedevent(QDirectPainter *dp,
       
   135                                         const QWSEmbedEvent *e);
       
   136 #endif
       
   137 #endif // QT_NO_DIRECTPAINTER
       
   138 
       
   139 const int qwsSharedRamSize = 1 * 1024; // misc data, written by server, read by clients
       
   140 
       
   141 extern QApplication::Type qt_appType;
       
   142 extern QDesktopWidget *qt_desktopWidget;
       
   143 
       
   144 //these used to be environment variables, they are initialized from
       
   145 //environment variables in
       
   146 
       
   147 bool qws_savefonts = false;
       
   148 bool qws_screen_is_interlaced=false; //### should be detected
       
   149 bool qws_shared_memory = false;
       
   150 bool qws_sw_cursor = true;
       
   151 bool qws_accel = true;            // ### never set
       
   152 QByteArray qws_display_spec(":0");
       
   153 Q_GUI_EXPORT int qws_display_id = 0;
       
   154 Q_GUI_EXPORT int qws_client_id = 0;
       
   155 QWidget *qt_pressGrab = 0;
       
   156 QWidget *qt_mouseGrb = 0;
       
   157 int *qt_last_x = 0;
       
   158 int *qt_last_y = 0;
       
   159 
       
   160 static int mouse_x_root = -1;
       
   161 static int mouse_y_root = -1;
       
   162 static int mouse_state = 0;
       
   163 static int mouse_double_click_distance = 5;
       
   164 
       
   165 int qt_servershmid = -1;
       
   166 
       
   167 bool qws_overrideCursor = false;
       
   168 #ifndef QT_NO_QWS_MANAGER
       
   169 
       
   170 extern Q_GUI_EXPORT QWSServer *qwsServer;
       
   171 
       
   172 static QDecoration *qws_decoration = 0;
       
   173 #endif
       
   174 
       
   175 #if defined(QT_DEBUG)
       
   176 /*
       
   177 extern "C" void dumpmem(const char* m)
       
   178 {
       
   179     static int init=0;
       
   180     static int prev=0;
       
   181     FILE* f = fopen("/proc/meminfo","r");
       
   182     //    char line[100];
       
   183     int total=0,used=0,free=0,shared=0,buffers=0,cached=0;
       
   184     fscanf(f,"%*[^M]Mem: %d %d %d %d %d %d",&total,&used,&free,&shared,&buffers,&cached);
       
   185     used -= buffers + cached;
       
   186     if (!init) {
       
   187         init=used;
       
   188     } else {
       
   189         printf("%40s: %+8d = %8d\n",m,used-init-prev,used-init);
       
   190         prev = used-init;
       
   191     }
       
   192     fclose(f);
       
   193 }
       
   194 */
       
   195 #endif
       
   196 
       
   197 // Get the name of the directory where Qt for Embedded Linux temporary data should
       
   198 // live.
       
   199 QString qws_dataDir()
       
   200 {
       
   201     static QString result;
       
   202     if (!result.isEmpty())
       
   203         return result;
       
   204     result = QT_VFB_DATADIR(qws_display_id);
       
   205     QByteArray dataDir = result.toLocal8Bit();
       
   206 
       
   207     if (QT_MKDIR(dataDir, 0700)) {
       
   208         if (errno != EEXIST) {
       
   209             qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData());
       
   210         }
       
   211     }
       
   212 
       
   213     QT_STATBUF buf;
       
   214     if (QT_LSTAT(dataDir, &buf))
       
   215         qFatal("stat failed for Qt for Embedded Linux data directory: %s", dataDir.constData());
       
   216 
       
   217     if (!S_ISDIR(buf.st_mode))
       
   218         qFatal("%s is not a directory", dataDir.constData());
       
   219 
       
   220 #if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS)
       
   221     if (buf.st_uid != getuid())
       
   222         qFatal("Qt for Embedded Linux data directory is not owned by user %d", getuid());
       
   223 
       
   224     if ((buf.st_mode & 0677) != 0600)
       
   225         qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData());
       
   226 #endif
       
   227 
       
   228     result.append("/");
       
   229     return result;
       
   230 }
       
   231 
       
   232 // Get the filename of the pipe Qt for Embedded Linux uses for server/client comms
       
   233 Q_GUI_EXPORT QString qws_qtePipeFilename()
       
   234 {
       
   235     qws_dataDir();
       
   236     return QTE_PIPE(qws_display_id);
       
   237 }
       
   238 
       
   239 static void setMaxWindowRect(const QRect &rect)
       
   240 {
       
   241     const QList<QScreen*> subScreens = qt_screen->subScreens();
       
   242     QScreen *screen = qt_screen;
       
   243     int screenNo = 0;
       
   244     for (int i = 0; i < subScreens.size(); ++i) {
       
   245         if (subScreens.at(i)->region().contains(rect)) {
       
   246             screen = subScreens.at(i);
       
   247             screenNo = i;
       
   248             break;
       
   249         }
       
   250     }
       
   251 
       
   252     QApplicationPrivate *ap = QApplicationPrivate::instance();
       
   253     ap->setMaxWindowRect(screen, screenNo, rect);
       
   254 }
       
   255 
       
   256 void QApplicationPrivate::setMaxWindowRect(const QScreen *screen, int screenNo,
       
   257                                            const QRect &rect)
       
   258 {
       
   259     if (maxWindowRects.value(screen) == rect)
       
   260         return;
       
   261 
       
   262     maxWindowRects[screen] = rect;
       
   263 
       
   264     // Re-resize any maximized windows
       
   265     QWidgetList l = QApplication::topLevelWidgets();
       
   266     for (int i = 0; i < l.size(); ++i) {
       
   267         QWidget *w = l.at(i);
       
   268         QScreen *s = w->d_func()->getScreen();
       
   269         if (w->isMaximized() && s == screen)
       
   270             w->d_func()->setMaxWindowState_helper();
       
   271     }
       
   272 
       
   273     if ( qt_desktopWidget ) // XXX workaround crash
       
   274         emit QApplication::desktop()->workAreaResized(screenNo);
       
   275 }
       
   276 
       
   277 #ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
       
   278 
       
   279 typedef void (*TransformFunc)(QScreen *, int);
       
   280 #ifndef QT_NO_QWS_TRANSFORMED
       
   281 extern "C" void qws_setScreenTransformation(QScreen *, int);
       
   282 #endif
       
   283 static TransformFunc getTransformationFunction()
       
   284 {
       
   285     static TransformFunc func = 0;
       
   286 
       
   287     if (!func) {
       
   288 #ifdef QT_NO_QWS_TRANSFORMED
       
   289 #  ifndef QT_NO_LIBRARY
       
   290         // symbol is not built into the library, search for the plugin
       
   291         const QStringList paths = QApplication::libraryPaths();
       
   292         foreach (const QString &path, paths) {
       
   293             const QString file = path + QLatin1String("/gfxdrivers/libqgfxtransformed");
       
   294             func = (TransformFunc)QLibrary::resolve(file,
       
   295                                                     "qws_setScreenTransformation");
       
   296             if (func)
       
   297                 break;
       
   298         }
       
   299 #  endif
       
   300 #else
       
   301         func = qws_setScreenTransformation;
       
   302 #endif
       
   303         if (!func)
       
   304             func = (TransformFunc)-1;
       
   305     }
       
   306 
       
   307     if (func == (TransformFunc)-1)
       
   308         return 0;
       
   309 
       
   310     return func;
       
   311 }
       
   312 
       
   313 static void setScreenTransformation(int screenNo, int transformation)
       
   314 {
       
   315     QScreen *screen = QScreen::instance();
       
   316     const QList<QScreen*> subScreens = screen->subScreens();
       
   317 
       
   318     if (screenNo == -1)
       
   319         screenNo = 0;
       
   320 
       
   321     if (screenNo == -1 && !subScreens.isEmpty())
       
   322         screenNo = 0;
       
   323 
       
   324     if (subScreens.isEmpty() && screenNo == 0) {
       
   325         // nothing
       
   326     } else if (screenNo < 0 || screenNo >= subScreens.size()) {
       
   327         qWarning("setScreenTransformation: invalid screen %i", screenNo);
       
   328         return;
       
   329     }
       
   330 
       
   331     if (screenNo < subScreens.size())
       
   332         screen = subScreens.at(screenNo);
       
   333 
       
   334     QApplicationPrivate *ap = QApplicationPrivate::instance();
       
   335     ap->setScreenTransformation(screen, screenNo, transformation);
       
   336 }
       
   337 
       
   338 void QApplicationPrivate::setScreenTransformation(QScreen *screen,
       
   339                                                   int screenNo,
       
   340                                                   int transformation)
       
   341 {
       
   342     QScreen *transformed = screen;
       
   343 
       
   344     while (transformed->classId() == QScreen::ProxyClass)
       
   345         transformed = static_cast<QProxyScreen*>(transformed)->screen();
       
   346 
       
   347     if (transformed->classId() != QScreen::TransformedClass)
       
   348         return;
       
   349 
       
   350     TransformFunc setScreenTransformation = getTransformationFunction();
       
   351     if (!setScreenTransformation)
       
   352         return;
       
   353 
       
   354     setScreenTransformation(transformed, transformation);
       
   355 
       
   356     // need to re-configure() proxies bottom-up
       
   357     if (screen->classId() == QScreen::ProxyClass) {
       
   358         QList<QProxyScreen*> proxies;
       
   359         QScreen *s = screen;
       
   360 
       
   361         do {
       
   362             QProxyScreen *proxy = static_cast<QProxyScreen*>(s);
       
   363             proxies.append(proxy);
       
   364             s = proxy->screen();
       
   365         } while (s->classId() == QScreen::ProxyClass);
       
   366 
       
   367         do {
       
   368             QProxyScreen *proxy = proxies.takeLast();
       
   369             proxy->setScreen(proxy->screen()); // triggers configure()
       
   370         } while (!proxies.isEmpty());
       
   371     }
       
   372 
       
   373     if (qt_desktopWidget) { // XXX workaround crash for early screen transform events
       
   374         QDesktopWidget *desktop = QApplication::desktop();
       
   375 
       
   376         emit desktop->resized(screenNo);
       
   377         if (maxWindowRect(screen).isEmpty()) // not explicitly set
       
   378             emit desktop->workAreaResized(screenNo);
       
   379     }
       
   380 
       
   381     QWSServer *server = QWSServer::instance();
       
   382     if (server) {
       
   383         server->updateWindowRegions();
       
   384         QRegion r = screen->region();
       
   385         server->refresh(r);
       
   386     }
       
   387 
       
   388     // make sure maximized and fullscreen windows are updated
       
   389     QWidgetList list = QApplication::topLevelWidgets();
       
   390     for (int i = list.size() - 1; i >= 0; --i) {
       
   391         QWidget *w = list.at(i);
       
   392         if (w->isFullScreen())
       
   393             w->d_func()->setFullScreenSize_helper();
       
   394         else if (w->isMaximized())
       
   395             w->d_func()->setMaxWindowState_helper();
       
   396     }
       
   397 }
       
   398 
       
   399 #endif // QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
       
   400 
       
   401 /*****************************************************************************
       
   402   Internal variables and functions
       
   403  *****************************************************************************/
       
   404 
       
   405 
       
   406 static QString appName;                          // application name
       
   407 static const char *appFont = 0;                  // application font
       
   408 static const char *appBGCol = 0;                 // application bg color
       
   409 static const char *appFGCol = 0;                 // application fg color
       
   410 static const char *appBTNCol = 0;                // application btn color
       
   411 static const char *mwGeometry = 0;               // main widget geometry
       
   412 static const char *mwTitle = 0;                  // main widget title
       
   413 //static bool mwIconic = false;                  // main widget iconified
       
   414 
       
   415 static bool app_do_modal = false;                // modal mode
       
   416 Q_GUI_EXPORT QWSDisplay *qt_fbdpy = 0;                        // QWS `display'
       
   417 QLock *QWSDisplay::lock = 0;
       
   418 
       
   419 static int mouseButtonPressed = 0;               // last mouse button pressed
       
   420 static int mouseButtonPressTime = 0;             // when was a button pressed
       
   421 static short mouseXPos, mouseYPos;               // mouse position in act window
       
   422 
       
   423 extern QWidgetList *qt_modal_stack;              // stack of modal widgets
       
   424 
       
   425 static QWidget *popupButtonFocus = 0;
       
   426 static QWidget *popupOfPopupButtonFocus = 0;
       
   427 static bool popupCloseDownMode = false;
       
   428 static bool popupGrabOk;
       
   429 static QPointer<QWidget> *mouseInWidget = 0;
       
   430 QPointer<QWidget> qt_last_mouse_receiver = 0;
       
   431 
       
   432 static bool sm_blockUserInput = false;           // session management
       
   433 
       
   434 QWidget *qt_button_down = 0;                     // widget got last button-down
       
   435 WId qt_last_cursor = 0xffffffff;                 // Was -1, but WIds are unsigned
       
   436 
       
   437 class QWSMouseEvent;
       
   438 class QWSKeyEvent;
       
   439 
       
   440 class QETWidget : public QWidget                 // event translator widget
       
   441 {
       
   442 public:
       
   443     bool translateMouseEvent(const QWSMouseEvent *, int oldstate);
       
   444     bool translateKeyEvent(const QWSKeyEvent *, bool grab);
       
   445     bool translateRegionEvent(const QWSRegionEvent *);
       
   446 #ifndef QT_NO_QWSEMBEDWIDGET
       
   447     void translateEmbedEvent(const QWSEmbedEvent *event);
       
   448 #endif
       
   449     bool translateWheelEvent(const QWSMouseEvent *me);
       
   450     void repaintDecoration(QRegion r, bool post);
       
   451     void updateRegion();
       
   452 
       
   453     bool raiseOnClick()
       
   454     {
       
   455         // With limited windowmanagement/taskbar/etc., raising big windows
       
   456         // (eg. spreadsheet) over the top of everything else (eg. calculator)
       
   457         // is just annoying.
       
   458         return !isMaximized() && !isFullScreen();
       
   459     }
       
   460 };
       
   461 
       
   462 void QApplicationPrivate::createEventDispatcher()
       
   463 {
       
   464     Q_Q(QApplication);
       
   465 #if !defined(QT_NO_GLIB)
       
   466     if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
       
   467         eventDispatcher = (q->type() != QApplication::Tty
       
   468                            ? new QWSEventDispatcherGlib(q)
       
   469                            : new QEventDispatcherGlib(q));
       
   470     else
       
   471 #endif
       
   472     eventDispatcher = (q->type() != QApplication::Tty
       
   473                        ? new QEventDispatcherQWS(q)
       
   474                        : new QEventDispatcherUNIX(q));
       
   475 }
       
   476 
       
   477 // Single-process stuff. This should maybe move into qwindowsystem_qws.cpp
       
   478 
       
   479 static bool qws_single_process;
       
   480 static QList<QWSEvent*> incoming;
       
   481 static QList<QWSCommand*> outgoing;
       
   482 
       
   483 void qt_client_enqueue(const QWSEvent *event)
       
   484 {
       
   485     QWSEvent *copy = QWSEvent::factory(event->type);
       
   486     copy->copyFrom(event);
       
   487     incoming.append(copy);
       
   488 }
       
   489 
       
   490 QList<QWSCommand*> *qt_get_server_queue()
       
   491 {
       
   492     return &outgoing;
       
   493 }
       
   494 
       
   495 void qt_server_enqueue(const QWSCommand *command)
       
   496 {
       
   497     QWSCommand *copy = QWSCommand::factory(command->type);
       
   498     QT_TRY {
       
   499         copy->copyFrom(command);
       
   500         outgoing.append(copy);
       
   501     } QT_CATCH(...) {
       
   502         delete copy;
       
   503         QT_RETHROW;
       
   504     }
       
   505 }
       
   506 
       
   507 QWSDisplay::Data::Data(QObject* parent, bool singleProcess)
       
   508 {
       
   509 #ifdef QT_NO_QWS_MULTIPROCESS
       
   510     Q_UNUSED(parent);
       
   511     Q_UNUSED(singleProcess);
       
   512 #else
       
   513     if (singleProcess)
       
   514         csocket = 0;
       
   515     else {
       
   516         csocket = new QWSSocket(parent);
       
   517         QObject::connect(csocket, SIGNAL(disconnected()),
       
   518                          qApp, SLOT(quit()));
       
   519     }
       
   520     clientLock = 0;
       
   521 #endif
       
   522     init();
       
   523 }
       
   524 
       
   525 QWSDisplay::Data::~Data()
       
   526 {
       
   527 //        delete rgnMan; rgnMan = 0;
       
   528 //        delete memorymanager; memorymanager = 0;
       
   529     qt_screen->disconnect();
       
   530     delete qt_screen; qt_screen = 0;
       
   531 #ifndef QT_NO_QWS_CURSOR
       
   532     delete qt_screencursor; qt_screencursor = 0;
       
   533 #endif
       
   534 #ifndef QT_NO_QWS_MULTIPROCESS
       
   535     shm.detach();
       
   536     if (csocket) {
       
   537         QWSCommand shutdownCmd(QWSCommand::Shutdown, 0, 0);
       
   538         shutdownCmd.write(csocket);
       
   539         csocket->flush(); // may be pending QCop message, eg.
       
   540         delete csocket;
       
   541     }
       
   542     delete clientLock;
       
   543     clientLock = 0;
       
   544 #endif
       
   545     delete connected_event;
       
   546     delete mouse_event;
       
   547     delete current_event;
       
   548     qDeleteAll(queue);
       
   549 #ifndef QT_NO_COP
       
   550     delete qcop_response;
       
   551 #endif
       
   552 }
       
   553 
       
   554 #ifndef QT_NO_QWS_MULTIPROCESS
       
   555 bool QWSDisplay::Data::lockClient(QWSLock::LockType type, int timeout)
       
   556 {
       
   557     return !clientLock || clientLock->lock(type, timeout);
       
   558 }
       
   559 
       
   560 void QWSDisplay::Data::unlockClient(QWSLock::LockType type)
       
   561 {
       
   562     if (clientLock) clientLock->unlock(type);
       
   563 }
       
   564 
       
   565 bool QWSDisplay::Data::waitClient(QWSLock::LockType type, int timeout)
       
   566 {
       
   567     return !clientLock || clientLock->wait(type, timeout);
       
   568 }
       
   569 
       
   570 QWSLock* QWSDisplay::Data::getClientLock()
       
   571 {
       
   572     return clientLock;
       
   573 }
       
   574 #endif // QT_NO_QWS_MULTIPROCESS
       
   575 
       
   576 void QWSDisplay::Data::flush()
       
   577 {
       
   578 #ifndef QT_NO_QWS_MULTIPROCESS
       
   579     if (csocket) {
       
   580         csocket->waitForReadyRead(0);
       
   581         csocket->flush();
       
   582    }
       
   583 #endif
       
   584 }
       
   585 
       
   586 #if 0
       
   587 void QWSDisplay::Data::debugQueue() {
       
   588     for (int i = 0; i < queue.size(); ++i) {
       
   589         QWSEvent *e = queue.at(i);
       
   590         qDebug( "   ev %d type %d sl %d rl %d", i, e->type, e->simpleLen, e->rawLen);
       
   591     }
       
   592 }
       
   593 #endif
       
   594 
       
   595 bool QWSDisplay::Data::queueNotEmpty()
       
   596 {
       
   597     return mouse_event/*||region_event*/||queue.count() > 0;
       
   598 }
       
   599 QWSEvent* QWSDisplay::Data::dequeue()
       
   600 {
       
   601     QWSEvent *r=0;
       
   602     if (queue.count()) {
       
   603         r = queue.first();
       
   604         queue.removeFirst();
       
   605         if (r->type == QWSEvent::Region)
       
   606             region_events_count--;
       
   607     } else if (mouse_event) {
       
   608         r = mouse_event;
       
   609         mouse_event = 0;
       
   610 #ifdef QAPPLICATION_EXTRA_DEBUG
       
   611         mouse_event_count = 0;
       
   612 #endif
       
   613     }
       
   614     return r;
       
   615 }
       
   616 
       
   617 QWSEvent* QWSDisplay::Data::peek()
       
   618 {
       
   619     return queue.first();
       
   620 }
       
   621 
       
   622 bool QWSDisplay::Data::directServerConnection()
       
   623 {
       
   624 #ifndef QT_NO_QWS_MULTIPROCESS
       
   625     return csocket == 0;
       
   626 #else
       
   627     return true;
       
   628 #endif
       
   629 }
       
   630 
       
   631 void QWSDisplay::Data::create(int n)
       
   632 {
       
   633     QWSCreateCommand cmd(n);
       
   634     sendCommand(cmd);
       
   635 }
       
   636 
       
   637 void QWSDisplay::Data::flushCommands()
       
   638 {
       
   639 #ifndef QT_NO_QWS_MULTIPROCESS
       
   640     if  (csocket)
       
   641         csocket->flush();
       
   642 #endif
       
   643 }
       
   644 
       
   645 void QWSDisplay::Data::sendCommand(QWSCommand & cmd)
       
   646 {
       
   647 #ifndef QT_NO_QWS_MULTIPROCESS
       
   648     if  (csocket)
       
   649         cmd.write(csocket);
       
   650     else
       
   651 #endif
       
   652         qt_server_enqueue(&cmd);
       
   653 }
       
   654 
       
   655 void QWSDisplay::Data::sendSynchronousCommand(QWSCommand & cmd)
       
   656 {
       
   657 #ifndef QT_NO_QWS_MULTIPROCESS
       
   658     if  (csocket) {
       
   659         lockClient(QWSLock::Communication);
       
   660         cmd.write(csocket);
       
   661         bool ok = true;
       
   662         while (csocket->bytesToWrite() > 0) {
       
   663             if (!csocket->waitForBytesWritten(-1)) {
       
   664                 qCritical("QWSDisplay::Data::sendSynchronousCommand: %s",
       
   665                           qPrintable(csocket->errorString()));
       
   666                 ok = false;
       
   667                 break;
       
   668             }
       
   669         }
       
   670         if (ok)
       
   671             waitClient(QWSLock::Communication);
       
   672     } else
       
   673 #endif
       
   674         qt_server_enqueue(&cmd);
       
   675 }
       
   676 
       
   677 int QWSDisplay::Data::takeId()
       
   678 {
       
   679     int unusedIdCount = unused_identifiers.count();
       
   680     if (unusedIdCount <= 10)
       
   681         create(15);
       
   682     if (unusedIdCount == 0) {
       
   683         create(1); // Make sure we have an incoming id to wait for, just in case we're recursive
       
   684         waitForCreation();
       
   685     }
       
   686 
       
   687     return unused_identifiers.takeFirst();
       
   688 }
       
   689 
       
   690 void QWSDisplay::Data::setMouseFilter(void (*filter)(QWSMouseEvent*))
       
   691 {
       
   692     mouseFilter = filter;
       
   693 }
       
   694 
       
   695 #ifndef QT_NO_QWS_MULTIPROCESS
       
   696 
       
   697 QWSLock* QWSDisplay::Data::clientLock = 0;
       
   698 
       
   699 void Q_GUI_EXPORT qt_app_reinit( const QString& newAppName )
       
   700 {
       
   701     qt_fbdpy->d->reinit( newAppName );
       
   702 }
       
   703 
       
   704 #endif // QT_NO_QWS_MULTIPROCESS
       
   705 
       
   706 class QDesktopWidget;
       
   707 
       
   708 #ifndef QT_NO_QWS_MULTIPROCESS
       
   709 void QWSDisplay::Data::reinit( const QString& newAppName )
       
   710 {
       
   711     Q_ASSERT(csocket);
       
   712 
       
   713     delete connected_event;
       
   714     connected_event = 0;
       
   715     region_events_count = 0;
       
   716 //    region_ack = 0;
       
   717     delete mouse_event;
       
   718     mouse_event = 0;
       
   719 //    region_event = 0;
       
   720     region_offset_window = 0;
       
   721 #ifndef QT_NO_COP
       
   722     delete qcop_response;
       
   723     qcop_response = 0;
       
   724 #endif
       
   725     delete current_event;
       
   726     current_event = 0;
       
   727 #ifdef QAPPLICATION_EXTRA_DEBUG
       
   728     mouse_event_count = 0;
       
   729 #endif
       
   730     mouseFilter = 0;
       
   731 
       
   732     qt_desktopWidget = 0;
       
   733     delete QWSDisplay::Data::clientLock;
       
   734     QWSDisplay::Data::clientLock = 0;
       
   735 
       
   736     QString pipe = qws_qtePipeFilename();
       
   737 
       
   738     // QWS client
       
   739     // Cleanup all cached ids
       
   740     unused_identifiers.clear();
       
   741     delete csocket;
       
   742 
       
   743     appName = newAppName;
       
   744     qApp->setObjectName( appName );
       
   745 
       
   746     csocket = new QWSSocket();
       
   747     QObject::connect(csocket, SIGNAL(disconnected()),
       
   748                      qApp, SLOT(quit()));
       
   749     csocket->connectToLocalFile(pipe);
       
   750 
       
   751     QWSDisplay::Data::clientLock = new QWSLock();
       
   752 
       
   753     QWSIdentifyCommand cmd;
       
   754     cmd.setId(appName, QWSDisplay::Data::clientLock->id());
       
   755 
       
   756 #ifndef QT_NO_SXE
       
   757     QTransportAuth *a = QTransportAuth::getInstance();
       
   758     QTransportAuth::Data *d = a->connectTransport(
       
   759             QTransportAuth::UnixStreamSock |
       
   760             QTransportAuth::Trusted,
       
   761             csocket->socketDescriptor());
       
   762     QAuthDevice *ad = a->authBuf( d, csocket );
       
   763     ad->setClient( csocket );
       
   764 
       
   765     cmd.write(ad);
       
   766 #else
       
   767     cmd.write(csocket);
       
   768 #endif
       
   769 
       
   770     // wait for connect confirmation
       
   771     waitForConnection();
       
   772 
       
   773     qws_client_id = connected_event->simpleData.clientId;
       
   774 
       
   775     if (!QWSDisplay::initLock(pipe, false))
       
   776         qFatal("Cannot get display lock");
       
   777 
       
   778     if (shm.attach(connected_event->simpleData.servershmid)) {
       
   779         sharedRam = static_cast<uchar *>(shm.address());
       
   780         QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
       
   781         if (s)
       
   782             sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
       
   783     } else {
       
   784         perror("QWSDisplay::Data::init");
       
   785         qFatal("Client can't attach to main ram memory.");
       
   786     }
       
   787 
       
   788     qApp->desktop();
       
   789 
       
   790     // We wait for creation mainly so that we can process important
       
   791     // initialization events such as MaxWindowRect that are sent
       
   792     // before object id creation.  Waiting here avoids later window
       
   793     // resizing since we have the MWR before windows are displayed.
       
   794     waitForCreation();
       
   795 
       
   796     sharedRamSize -= sizeof(int);
       
   797     qt_last_x = reinterpret_cast<int *>(sharedRam + sharedRamSize);
       
   798     sharedRamSize -= sizeof(int);
       
   799     qt_last_y = reinterpret_cast<int *>(sharedRam + sharedRamSize);
       
   800 
       
   801 #ifndef QT_NO_COP
       
   802     QCopChannel::reregisterAll();
       
   803 #endif
       
   804     csocket->flush();
       
   805 }
       
   806 #endif
       
   807 
       
   808 void QWSDisplay::Data::init()
       
   809 {
       
   810     connected_event = 0;
       
   811     region_events_count = 0;
       
   812 //    region_ack = 0;
       
   813     mouse_event = 0;
       
   814     mouse_state = -1;
       
   815     mouse_winid = 0;
       
   816 //    region_event = 0;
       
   817     region_offset_window = 0;
       
   818 #ifndef QT_NO_COP
       
   819     qcop_response = 0;
       
   820 #endif
       
   821     current_event = 0;
       
   822 #ifdef QAPPLICATION_EXTRA_DEBUG
       
   823     mouse_event_count = 0;
       
   824 #endif
       
   825     mouseFilter = 0;
       
   826 
       
   827     QString pipe = qws_qtePipeFilename();
       
   828 
       
   829     sharedRamSize = qwsSharedRamSize;
       
   830 
       
   831 #ifndef QT_NO_QWS_MULTIPROCESS
       
   832     if (csocket)    {
       
   833         // QWS client
       
   834 
       
   835         connectToPipe();
       
   836 
       
   837         QWSDisplay::Data::clientLock = new QWSLock();
       
   838 
       
   839         QWSIdentifyCommand cmd;
       
   840         cmd.setId(appName, QWSDisplay::Data::clientLock->id());
       
   841 #ifndef QT_NO_SXE
       
   842         QTransportAuth *a = QTransportAuth::getInstance();
       
   843         QTransportAuth::Data *d = a->connectTransport(
       
   844                 QTransportAuth::UnixStreamSock |
       
   845                 QTransportAuth::Trusted,
       
   846                 csocket->socketDescriptor());
       
   847         QAuthDevice *ad = a->authBuf( d, csocket );
       
   848         ad->setClient( csocket );
       
   849         cmd.write(ad);
       
   850 #else
       
   851         cmd.write(csocket);
       
   852 #endif
       
   853 
       
   854         // create(30); // not necessary, server will send ids anyway
       
   855         waitForConnection();
       
   856 
       
   857         qws_client_id = connected_event->simpleData.clientId;
       
   858 
       
   859         // now we want to get the exact display spec to use if we haven't
       
   860         // specified anything.
       
   861         if (qws_display_spec.at(0) == ':')
       
   862             qws_display_spec = connected_event->display;
       
   863 
       
   864         if (!QWSDisplay::initLock(pipe, false))
       
   865             qFatal("Cannot get display lock");
       
   866 
       
   867         if (shm.attach(connected_event->simpleData.servershmid)) {
       
   868             sharedRam = static_cast<uchar *>(shm.address());
       
   869             QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
       
   870             if (s)
       
   871                 sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
       
   872         } else {
       
   873             perror("QWSDisplay::Data::init");
       
   874             qFatal("Client can't attach to main ram memory.");
       
   875         }
       
   876 
       
   877         // We wait for creation mainly so that we can process important
       
   878         // initialization events such as MaxWindowRect that are sent
       
   879         // before object id creation.  Waiting here avoids later window
       
   880         // resizing since we have the MWR before windows are displayed.
       
   881         waitForCreation();
       
   882     } else
       
   883 #endif
       
   884     {
       
   885         create(30);
       
   886 
       
   887         // QWS server
       
   888         if (!QWSDisplay::initLock(pipe, true))
       
   889             qFatal("Cannot get display lock");
       
   890 
       
   891         QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
       
   892         if (s)
       
   893             sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
       
   894 
       
   895 #ifndef QT_NO_QWS_MULTIPROCESS
       
   896 
       
   897         if (!shm.create(sharedRamSize)) {
       
   898             perror("Cannot create main ram shared memory\n");
       
   899             qFatal("Unable to allocate %d bytes of shared memory", sharedRamSize);
       
   900         }
       
   901         qt_servershmid = shm.id();
       
   902         sharedRam = static_cast<uchar *>(shm.address());
       
   903 #else
       
   904         sharedRam=static_cast<uchar *>(malloc(sharedRamSize));
       
   905 #endif
       
   906         // Need to zero index count at end of block, might as well zero
       
   907         // the rest too
       
   908         memset(sharedRam,0,sharedRamSize);
       
   909 
       
   910         QWSIdentifyCommand cmd;
       
   911         cmd.setId(appName, -1);
       
   912         qt_server_enqueue(&cmd);
       
   913     }
       
   914 
       
   915     // Allow some memory for the graphics driver too
       
   916     //### Note that sharedRamSize() has side effects; it must be called
       
   917     //### once, and only once, and before initDevice()
       
   918     sharedRamSize -= qt_screen->sharedRamSize(sharedRam+sharedRamSize);
       
   919 
       
   920 #ifndef QT_NO_QWS_MULTIPROCESS
       
   921     if(!csocket)
       
   922 #endif
       
   923     {
       
   924         //QWS server process
       
   925         if (!qt_screen->initDevice())
       
   926             qFatal("Unable to initialize screen driver!");
       
   927     }
       
   928 
       
   929     sharedRamSize -= sizeof(int);
       
   930     qt_last_x = reinterpret_cast<int *>(sharedRam + sharedRamSize);
       
   931     sharedRamSize -= sizeof(int);
       
   932     qt_last_y = reinterpret_cast<int *>(sharedRam + sharedRamSize);
       
   933 
       
   934     /* Initialise framebuffer memory manager */
       
   935     /* Add 4k for luck and to avoid clobbering hardware cursor */
       
   936 //    int screensize=qt_screen->screenSize();
       
   937 //     memorymanager=new QMemoryManager(qt_screen->base()+screensize+4096,
       
   938 //         qt_screen->totalSize()-(screensize+4096),0);
       
   939 
       
   940 // #ifndef QT_NO_QWS_MULTIPROCESS
       
   941 //     rgnMan = new QWSRegionManager(pipe, csocket);
       
   942 // #else
       
   943 //     rgnMan = new QWSRegionManager(pipe, 0); //####### not necessary
       
   944 // #endif
       
   945 #ifndef QT_NO_QWS_MULTIPROCESS
       
   946     if (csocket)
       
   947         csocket->flush();
       
   948 #endif
       
   949 }
       
   950 
       
   951 
       
   952 QWSEvent* QWSDisplay::Data::readMore()
       
   953 {
       
   954 #ifdef QT_NO_QWS_MULTIPROCESS
       
   955     return incoming.isEmpty() ? 0 : incoming.takeFirst();
       
   956 #else
       
   957     if (!csocket)
       
   958         return incoming.isEmpty() ? 0 : incoming.takeFirst();
       
   959     // read next event
       
   960     if (!current_event) {
       
   961         int event_type = qws_read_uint(csocket);
       
   962 
       
   963         if (event_type >= 0) {
       
   964             current_event = QWSEvent::factory(event_type);
       
   965         }
       
   966     }
       
   967 
       
   968     if (current_event) {
       
   969         if (current_event->read(csocket)) {
       
   970             // Finished reading a whole event.
       
   971             QWSEvent* result = current_event;
       
   972             current_event = 0;
       
   973             return result;
       
   974         }
       
   975     }
       
   976 
       
   977     // Not finished reading a whole event.
       
   978     return 0;
       
   979 #endif
       
   980 }
       
   981 
       
   982 void QWSDisplay::Data::fillQueue()
       
   983 {
       
   984     QWSServer::processEventQueue();
       
   985     QWSEvent *e = readMore();
       
   986 #ifndef QT_NO_QWS_MULTIPROCESS
       
   987     int bytesAvailable = csocket ? csocket->bytesAvailable() : 0;
       
   988     int bytesRead = 0;
       
   989 #endif
       
   990     while (e) {
       
   991 #ifndef QT_NO_QWS_MULTIPROCESS
       
   992         bytesRead += QWS_PROTOCOL_ITEM_SIZE((*e));
       
   993 #endif
       
   994         if (e->type == QWSEvent::Connected) {
       
   995             connected_event = static_cast<QWSConnectedEvent *>(e);
       
   996             return;
       
   997         } else if (e->type == QWSEvent::Creation) {
       
   998             QWSCreationEvent *ce = static_cast<QWSCreationEvent*>(e);
       
   999             int id = ce->simpleData.objectid;
       
  1000             int count = ce->simpleData.count;
       
  1001             for (int i = 0; i < count; ++i)
       
  1002                 unused_identifiers.append(id++);
       
  1003             delete e;
       
  1004         } else if (e->type == QWSEvent::Mouse) {
       
  1005             if (!qt_screen) {
       
  1006                 delete e;
       
  1007             } else {
       
  1008                 QWSMouseEvent *me = static_cast<QWSMouseEvent*>(e);
       
  1009                 if (mouseFilter)
       
  1010                     mouseFilter(me);
       
  1011 #ifdef QAPPLICATION_EXTRA_DEBUG
       
  1012                 static const char *defaultAction= "INITIAL";
       
  1013                 const char * action = defaultAction;
       
  1014 #endif
       
  1015                 delete mouse_event;
       
  1016                 if (mouse_winid != me->window ()
       
  1017                     || mouse_state != me->simpleData.state) {
       
  1018                         queue.append(me);
       
  1019                         mouse_winid = me->window();
       
  1020                         mouse_state = me->simpleData.state;
       
  1021                         mouse_event = 0;
       
  1022 #ifdef QAPPLICATION_EXTRA_DEBUG
       
  1023                         mouse_event_count = 0;
       
  1024                         action = "ENQUEUE";
       
  1025 #endif
       
  1026                 } else {
       
  1027 #ifdef QAPPLICATION_EXTRA_DEBUG
       
  1028                     if (mouse_event)
       
  1029                         action = "COMPRESS";
       
  1030                     mouse_event_count++;
       
  1031 #endif
       
  1032                     mouse_event = me;
       
  1033                 }
       
  1034 #ifdef QAPPLICATION_EXTRA_DEBUG
       
  1035                 if (me->simpleData.state !=0 || action != defaultAction || mouse_event_count != 0)
       
  1036                     qDebug("fillQueue %s (%d,%d), state %x win %d count %d", action,
       
  1037                            me->simpleData.x_root, me->simpleData.y_root, me->simpleData.state,
       
  1038                            me->window(), mouse_event_count);
       
  1039 #endif
       
  1040             }
       
  1041 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1042         } else if (e->type == QWSEvent::Region && clientLock) {
       
  1043             // not really an unlock, decrements the semaphore
       
  1044             region_events_count++;
       
  1045             clientLock->unlock(QWSLock::RegionEvent);
       
  1046             queue.append(e);
       
  1047 #endif
       
  1048 #ifndef QT_NO_QWS_PROPERTIES
       
  1049         } else if (e->type == QWSEvent::PropertyReply) {
       
  1050             QWSPropertyReplyEvent *pe = static_cast<QWSPropertyReplyEvent*>(e);
       
  1051             int len = pe->simpleData.len;
       
  1052             char *data;
       
  1053             if (len <= 0) {
       
  1054                 data = 0;
       
  1055             } else {
       
  1056                 data = new char[len];
       
  1057                 memcpy(data, pe->data, len) ;
       
  1058             }
       
  1059             QPaintDevice::qwsDisplay()->getPropertyLen = len;
       
  1060             QPaintDevice::qwsDisplay()->getPropertyData = data;
       
  1061             delete e;
       
  1062 #endif // QT_NO_QWS_PROPERTIES
       
  1063         } else if (e->type==QWSEvent::MaxWindowRect && qt_screen) {
       
  1064             // Process this ASAP, in case new widgets are created (startup)
       
  1065             setMaxWindowRect((static_cast<QWSMaxWindowRectEvent*>(e))->simpleData.rect);
       
  1066             delete e;
       
  1067 #ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
       
  1068         } else if (e->type == QWSEvent::ScreenTransformation) {
       
  1069             QWSScreenTransformationEvent *pe = static_cast<QWSScreenTransformationEvent*>(e);
       
  1070             setScreenTransformation(pe->simpleData.screen,
       
  1071                                     pe->simpleData.transformation);
       
  1072             delete e;
       
  1073 #endif
       
  1074 #ifndef QT_NO_COP
       
  1075         } else if (e->type == QWSEvent::QCopMessage) {
       
  1076             QWSQCopMessageEvent *pe = static_cast<QWSQCopMessageEvent*>(e);
       
  1077             if (pe->simpleData.is_response) {
       
  1078                 qcop_response = pe;
       
  1079             } else {
       
  1080                 queue.append(e);
       
  1081             }
       
  1082 #endif
       
  1083         } else {
       
  1084             queue.append(e);
       
  1085         }
       
  1086         //debugQueue();
       
  1087 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1088         if (csocket && bytesRead >= bytesAvailable)
       
  1089             break;
       
  1090 #endif
       
  1091         e = readMore();
       
  1092     }
       
  1093 }
       
  1094 
       
  1095 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1096 
       
  1097 static int qws_connection_timeout = 5;
       
  1098 
       
  1099 void QWSDisplay::Data::connectToPipe()
       
  1100 {
       
  1101     Q_ASSERT(csocket);
       
  1102 
       
  1103     int timeout = qgetenv("QWS_CONNECTION_TIMEOUT").toInt();
       
  1104     if (timeout)
       
  1105         qws_connection_timeout = timeout;
       
  1106 
       
  1107     const QString pipe = qws_qtePipeFilename();
       
  1108     int i = 0;
       
  1109     while (!csocket->connectToLocalFile(pipe)) {
       
  1110         if (++i > qws_connection_timeout) {
       
  1111             qWarning("No Qt for Embedded Linux server appears to be running.");
       
  1112             qWarning("If you want to run this program as a server,");
       
  1113             qWarning("add the \"-qws\" command-line option.");
       
  1114             exit(1);
       
  1115         }
       
  1116         sleep(1);
       
  1117     }
       
  1118 }
       
  1119 
       
  1120 void QWSDisplay::Data::waitForConnection()
       
  1121 {
       
  1122     connected_event = 0;
       
  1123 
       
  1124     for (int i = 0; i < qws_connection_timeout; i++) {
       
  1125         fillQueue();
       
  1126         if (connected_event)
       
  1127             return;
       
  1128         csocket->flush();
       
  1129         csocket->waitForReadyRead(1000);
       
  1130     }
       
  1131 
       
  1132     csocket->flush();
       
  1133     if (!connected_event)
       
  1134         qFatal("Did not receive a connection event from the qws server");
       
  1135 }
       
  1136 
       
  1137 void QWSDisplay::Data::waitForRegionAck(int winId)
       
  1138 {
       
  1139     QWSEvent *ack = 0;
       
  1140 
       
  1141     if (csocket) { // GuiClient
       
  1142         int i = 0;
       
  1143         while (!ack) {
       
  1144             fillQueue();
       
  1145 
       
  1146             while (i < queue.size()) {
       
  1147                 QWSEvent *e = queue.at(i);
       
  1148                 if (e->type == QWSEvent::Region && e->window() == winId) {
       
  1149                     ack = e;
       
  1150                     queue.removeAt(i);
       
  1151                     break;
       
  1152                 }
       
  1153                 ++i;
       
  1154             }
       
  1155 
       
  1156             if (!ack) {
       
  1157                 csocket->flush();
       
  1158                 csocket->waitForReadyRead(1000);
       
  1159             }
       
  1160         }
       
  1161     } else { // GuiServer
       
  1162         fillQueue();
       
  1163         for (int i = 0; i < queue.size(); /* nothing */) {
       
  1164             QWSEvent *e = queue.at(i);
       
  1165             if (e->type == QWSEvent::Region && e->window() == winId) {
       
  1166                 ack = e;
       
  1167                 queue.removeAt(i);
       
  1168                 break;
       
  1169             }
       
  1170             ++i;
       
  1171         }
       
  1172         if (!ack) // already processed
       
  1173             return;
       
  1174     }
       
  1175 
       
  1176     Q_ASSERT(ack);
       
  1177 
       
  1178     qApp->qwsProcessEvent(ack);
       
  1179     delete ack;
       
  1180     region_events_count--;
       
  1181 }
       
  1182 
       
  1183 void QWSDisplay::Data::waitForRegionEvents(int winId, bool ungrabDisplay)
       
  1184 {
       
  1185     if (!clientLock)
       
  1186         return;
       
  1187 
       
  1188     int removedEventsCount = 0;
       
  1189 
       
  1190     // fill queue with unreceived region events
       
  1191     if (!clientLock->hasLock(QWSLock::RegionEvent)) {
       
  1192         bool ungrabbed = false;
       
  1193         if (ungrabDisplay && QWSDisplay::grabbed()) {
       
  1194             QWSDisplay::ungrab();
       
  1195             ungrabbed = true;
       
  1196         }
       
  1197 
       
  1198         for (;;) {
       
  1199             fillQueue();
       
  1200             if (clientLock->hasLock(QWSLock::RegionEvent))
       
  1201                 break;
       
  1202             csocket->flush();
       
  1203             csocket->waitForReadyRead(1000);
       
  1204         }
       
  1205 
       
  1206         if (ungrabbed)
       
  1207             QWSDisplay::grab(true);
       
  1208     }
       
  1209 
       
  1210     // check the queue for pending region events
       
  1211     QWSEvent *regionEvent = 0;
       
  1212     for (int i = 0; i < queue.size(); /* nothing */) {
       
  1213         QWSEvent *e = queue.at(i);
       
  1214         if (e->type == QWSEvent::Region && e->window() == winId) {
       
  1215             QWSRegionEvent *re = static_cast<QWSRegionEvent*>(e);
       
  1216             if (re->simpleData.type == QWSRegionEvent::Allocation) {
       
  1217                 delete regionEvent;
       
  1218                 regionEvent = re;
       
  1219             }
       
  1220             queue.removeAt(i);
       
  1221             removedEventsCount++;
       
  1222         } else {
       
  1223             ++i;
       
  1224         }
       
  1225     }
       
  1226 
       
  1227     if (regionEvent) {
       
  1228         qApp->qwsProcessEvent(regionEvent);
       
  1229         delete regionEvent;
       
  1230     }
       
  1231     region_events_count -= removedEventsCount;
       
  1232 }
       
  1233 
       
  1234 bool QWSDisplay::Data::hasPendingRegionEvents() const
       
  1235 {
       
  1236     if (clientLock && !clientLock->hasLock(QWSLock::RegionEvent))
       
  1237         return true;
       
  1238 
       
  1239     return region_events_count > 0;
       
  1240 }
       
  1241 
       
  1242 #endif // QT_NO_QWS_MULTIPROCESS
       
  1243 
       
  1244 void QWSDisplay::Data::waitForCreation()
       
  1245 {
       
  1246     fillQueue();
       
  1247 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1248     while (unused_identifiers.count() == 0) {
       
  1249         if (csocket) {
       
  1250             csocket->flush();
       
  1251             csocket->waitForReadyRead(1000);
       
  1252         }
       
  1253         fillQueue();
       
  1254     }
       
  1255 #endif
       
  1256 }
       
  1257 
       
  1258 
       
  1259 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1260 void QWSDisplay::Data::waitForPropertyReply()
       
  1261 {
       
  1262     if (!csocket)
       
  1263         return;
       
  1264     fillQueue();
       
  1265     while (qt_fbdpy->getPropertyLen == -2) {
       
  1266         csocket->flush();
       
  1267         csocket->waitForReadyRead(1000);
       
  1268         fillQueue();
       
  1269     }
       
  1270 }
       
  1271 #endif
       
  1272 
       
  1273 #ifndef QT_NO_COP
       
  1274 void QWSDisplay::Data::waitForQCopResponse()
       
  1275 {
       
  1276     for (;;) {
       
  1277         fillQueue();
       
  1278         if (qcop_response)
       
  1279             break;
       
  1280 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1281         if (csocket) {
       
  1282             csocket->flush();
       
  1283             csocket->waitForReadyRead(1000);
       
  1284         }
       
  1285 #endif
       
  1286     }
       
  1287     queue.prepend(qcop_response);
       
  1288     qcop_response = 0;
       
  1289 }
       
  1290 #endif
       
  1291 
       
  1292 /*!
       
  1293     \class QWSDisplay
       
  1294     \brief The QWSDisplay class provides a display for QWS; it is an internal class.
       
  1295 
       
  1296     \internal
       
  1297 
       
  1298     \ingroup qws
       
  1299 */
       
  1300 
       
  1301 QWSDisplay::QWSDisplay()
       
  1302 {
       
  1303     d = new Data(0, qws_single_process);
       
  1304 }
       
  1305 
       
  1306 QWSDisplay::~QWSDisplay()
       
  1307 {
       
  1308     delete d;
       
  1309     delete lock;
       
  1310     lock = 0;
       
  1311 }
       
  1312 
       
  1313 bool QWSDisplay::grabbed()
       
  1314 {
       
  1315     return lock->locked();
       
  1316 }
       
  1317 
       
  1318 void QWSDisplay::grab()
       
  1319 {
       
  1320     lock->lock(QLock::Read);
       
  1321 }
       
  1322 
       
  1323 void QWSDisplay::grab(bool write)
       
  1324 {
       
  1325     lock->lock(write ? QLock::Write : QLock::Read);
       
  1326 
       
  1327 }
       
  1328 void QWSDisplay::ungrab()
       
  1329 {
       
  1330     lock->unlock();
       
  1331 }
       
  1332 
       
  1333 #if 0
       
  1334 QWSRegionManager *QWSDisplay::regionManager() const
       
  1335 {
       
  1336     return d->rgnMan;
       
  1337 }
       
  1338 #endif
       
  1339 
       
  1340 bool QWSDisplay::eventPending() const
       
  1341 {
       
  1342 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1343     d->flush();
       
  1344 #endif
       
  1345     d->fillQueue();
       
  1346     return d->queueNotEmpty();
       
  1347 }
       
  1348 
       
  1349 
       
  1350 /*
       
  1351   Caller must delete return value!
       
  1352  */
       
  1353 QWSEvent *QWSDisplay::getEvent()
       
  1354 {
       
  1355     d->fillQueue();
       
  1356     Q_ASSERT(d->queueNotEmpty());
       
  1357     QWSEvent* e = d->dequeue();
       
  1358 
       
  1359     return e;
       
  1360 }
       
  1361 
       
  1362 uchar* QWSDisplay::frameBuffer() const { return qt_screen->base(); }
       
  1363 int QWSDisplay::width() const { return qt_screen->width(); }
       
  1364 int QWSDisplay::height() const { return qt_screen->height(); }
       
  1365 int QWSDisplay::depth() const { return qt_screen->depth(); }
       
  1366 int QWSDisplay::pixmapDepth() const { return qt_screen->pixmapDepth(); }
       
  1367 bool QWSDisplay::supportsDepth(int depth) const { return qt_screen->supportsDepth(depth); }
       
  1368 uchar *QWSDisplay::sharedRam() const { return d->sharedRam; }
       
  1369 int QWSDisplay::sharedRamSize() const { return d->sharedRamSize; }
       
  1370 
       
  1371 #ifndef QT_NO_QWS_PROPERTIES
       
  1372 
       
  1373 void QWSDisplay::addProperty(int winId, int property)
       
  1374 {
       
  1375     QWSAddPropertyCommand cmd;
       
  1376     cmd.simpleData.windowid = winId;
       
  1377     cmd.simpleData.property = property;
       
  1378     d->sendCommand(cmd);
       
  1379 }
       
  1380 
       
  1381 void QWSDisplay::setProperty(int winId, int property, int mode, const QByteArray &data)
       
  1382 {
       
  1383     QWSSetPropertyCommand cmd;
       
  1384     cmd.simpleData.windowid = winId;
       
  1385     cmd.simpleData.property = property;
       
  1386     cmd.simpleData.mode = mode;
       
  1387     cmd.setData(data.constData(), data.size());
       
  1388     d->sendCommand(cmd);
       
  1389 }
       
  1390 
       
  1391 void QWSDisplay::setProperty(int winId, int property, int mode,
       
  1392                               const char * data)
       
  1393 {
       
  1394     QWSSetPropertyCommand cmd;
       
  1395     cmd.simpleData.windowid = winId;
       
  1396     cmd.simpleData.property = property;
       
  1397     cmd.simpleData.mode = mode;
       
  1398     cmd.setData(data, strlen(data));
       
  1399     d->sendCommand(cmd);
       
  1400 }
       
  1401 
       
  1402 void QWSDisplay::removeProperty(int winId, int property)
       
  1403 {
       
  1404     QWSRemovePropertyCommand cmd;
       
  1405     cmd.simpleData.windowid = winId;
       
  1406     cmd.simpleData.property = property;
       
  1407     d->sendCommand(cmd);
       
  1408 }
       
  1409 
       
  1410 /*
       
  1411     It is the caller's responsibility to delete[] \a data.
       
  1412  */
       
  1413 bool QWSDisplay::getProperty(int winId, int property, char *&data, int &len)
       
  1414 {
       
  1415     if (d->directServerConnection()) {
       
  1416         const char *propertyData;
       
  1417         bool retval = qwsServer->d_func()->get_property(winId, property, propertyData, len);
       
  1418         if (len <= 0) {
       
  1419             data = 0;
       
  1420         } else {
       
  1421             data = new char[len];
       
  1422             memcpy(data, propertyData, len) ;
       
  1423         }
       
  1424         return retval;
       
  1425     }
       
  1426     QWSGetPropertyCommand cmd;
       
  1427     cmd.simpleData.windowid = winId;
       
  1428     cmd.simpleData.property = property;
       
  1429     d->sendCommand(cmd);
       
  1430 
       
  1431     getPropertyLen = -2;
       
  1432     getPropertyData = 0;
       
  1433 
       
  1434 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1435     d->waitForPropertyReply();
       
  1436 #endif
       
  1437 
       
  1438     len = getPropertyLen;
       
  1439     data = getPropertyData;
       
  1440 
       
  1441     getPropertyLen = -2;
       
  1442     getPropertyData = 0;
       
  1443 
       
  1444     return len != -1;
       
  1445 }
       
  1446 
       
  1447 #endif // QT_NO_QWS_PROPERTIES
       
  1448 
       
  1449 void QWSDisplay::setAltitude(int winId, int alt, bool fixed)
       
  1450 {
       
  1451     QWSChangeAltitudeCommand cmd;
       
  1452 #ifdef QT_DEBUG
       
  1453     memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
       
  1454 #endif
       
  1455     cmd.simpleData.windowid = winId;
       
  1456     cmd.simpleData.altitude = QWSChangeAltitudeCommand::Altitude(alt);
       
  1457     cmd.simpleData.fixed = fixed;
       
  1458     if (d->directServerConnection()) {
       
  1459         qwsServer->d_func()->set_altitude(&cmd);
       
  1460     } else {
       
  1461         d->sendSynchronousCommand(cmd);
       
  1462     }
       
  1463 }
       
  1464 
       
  1465 void QWSDisplay::setOpacity(int winId, int opacity)
       
  1466 {
       
  1467     QWSSetOpacityCommand cmd;
       
  1468     cmd.simpleData.windowid = winId;
       
  1469     cmd.simpleData.opacity = opacity;
       
  1470     if (d->directServerConnection()) {
       
  1471         qwsServer->d_func()->set_opacity(&cmd);
       
  1472     } else {
       
  1473         d->sendCommand(cmd);
       
  1474     }
       
  1475 }
       
  1476 
       
  1477 
       
  1478 
       
  1479 void QWSDisplay::requestFocus(int winId, bool get)
       
  1480 {
       
  1481     QWSRequestFocusCommand cmd;
       
  1482     cmd.simpleData.windowid = winId;
       
  1483     cmd.simpleData.flag = get;
       
  1484     if (d->directServerConnection())
       
  1485         qwsServer->d_func()->request_focus(&cmd);
       
  1486     else
       
  1487         d->sendCommand(cmd);
       
  1488 }
       
  1489 
       
  1490 void QWSDisplay::setIdentity(const QString &appName)
       
  1491 {
       
  1492     QWSIdentifyCommand cmd;
       
  1493 #ifdef QT_NO_QWS_MULTIPROCESS
       
  1494     const int id = -1;
       
  1495 #else
       
  1496     const int id = QWSDisplay::Data::clientLock ? QWSDisplay::Data::clientLock->id() : -1;
       
  1497 #endif
       
  1498     cmd.setId(appName, id);
       
  1499     if (d->directServerConnection())
       
  1500         qwsServer->d_func()->set_identity(&cmd);
       
  1501     else
       
  1502         d->sendCommand(cmd);
       
  1503 }
       
  1504 
       
  1505 void QWSDisplay::nameRegion(int winId, const QString& n, const QString &c)
       
  1506 {
       
  1507     QWSRegionNameCommand cmd;
       
  1508     cmd.simpleData.windowid = winId;
       
  1509     cmd.setName(n, c);
       
  1510     if (d->directServerConnection())
       
  1511         qwsServer->d_func()->name_region(&cmd);
       
  1512     else
       
  1513         d->sendCommand(cmd);
       
  1514 }
       
  1515 
       
  1516 void QWSDisplay::requestRegion(int winId, const QString &surfaceKey,
       
  1517                                const QByteArray &surfaceData,
       
  1518                                const QRegion &region)
       
  1519 {
       
  1520     if (d->directServerConnection()) {
       
  1521         qwsServer->d_func()->request_region(winId, surfaceKey,
       
  1522                                             surfaceData, region);
       
  1523     } else {
       
  1524         QWSRegionCommand cmd;
       
  1525         cmd.setData(winId, surfaceKey, surfaceData, region);
       
  1526         d->sendSynchronousCommand(cmd);
       
  1527     }
       
  1528 }
       
  1529 
       
  1530 void QWSDisplay::repaintRegion(int winId, int windowFlags, bool opaque, QRegion r)
       
  1531 {
       
  1532     if (d->directServerConnection()) {
       
  1533         qwsServer->d_func()->repaint_region(winId, windowFlags, opaque, r);
       
  1534     } else {
       
  1535         QVector<QRect> ra = r.rects();
       
  1536 
       
  1537         /*
       
  1538           for (int i = 0; i < ra.size(); i++) {
       
  1539           QRect r(ra[i]);
       
  1540           qDebug("rect: %d %d %d %d", r.x(), r.y(), r.right(), r.bottom());
       
  1541           }
       
  1542         */
       
  1543 
       
  1544         QWSRepaintRegionCommand cmd;
       
  1545     /* XXX QWSRegionCommand is padded out in a compiler dependent way.
       
  1546        Zeroed out to avoid valgrind reporting uninitialized memory usage.
       
  1547        */
       
  1548 #ifdef QT_DEBUG
       
  1549         memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
       
  1550 #endif
       
  1551         cmd.simpleData.windowid = winId;
       
  1552         cmd.simpleData.windowFlags = windowFlags;
       
  1553         cmd.simpleData.opaque = opaque;
       
  1554         cmd.simpleData.nrectangles = ra.count();
       
  1555         cmd.setData(reinterpret_cast<const char *>(ra.constData()),
       
  1556                     ra.count() * sizeof(QRect), false);
       
  1557 
       
  1558         d->sendSynchronousCommand(cmd);
       
  1559     }
       
  1560 }
       
  1561 
       
  1562 
       
  1563 void QWSDisplay::moveRegion(int winId, int dx, int dy)
       
  1564 {
       
  1565     QWSRegionMoveCommand cmd;
       
  1566     cmd.simpleData.windowid = winId;
       
  1567     cmd.simpleData.dx = dx;
       
  1568     cmd.simpleData.dy = dy;
       
  1569 
       
  1570     if (d->directServerConnection()) {
       
  1571         qwsServer->d_func()->move_region(&cmd);
       
  1572     } else {
       
  1573         d->sendSynchronousCommand(cmd);
       
  1574     }
       
  1575 //    d->offsetPendingExpose(winId, QPoint(cmd.simpleData.dx, cmd.simpleData.dy));
       
  1576 }
       
  1577 
       
  1578 void QWSDisplay::destroyRegion(int winId)
       
  1579 {
       
  1580     QWSRegionDestroyCommand cmd;
       
  1581     cmd.simpleData.windowid = winId;
       
  1582     if (d->directServerConnection()) {
       
  1583         qwsServer->d_func()->destroy_region(&cmd);
       
  1584     } else {
       
  1585         d->sendCommand(cmd);
       
  1586     }
       
  1587 }
       
  1588 
       
  1589 #ifndef QT_NO_QWS_INPUTMETHODS
       
  1590 
       
  1591 void QWSDisplay::sendIMUpdate(int type, int winId, int widgetid)
       
  1592 {
       
  1593     QWSIMUpdateCommand cmd;
       
  1594     cmd.simpleData.windowid = winId;
       
  1595     cmd.simpleData.widgetid = widgetid;
       
  1596 
       
  1597     cmd.simpleData.type = type;
       
  1598 
       
  1599       if (d->directServerConnection()) {
       
  1600         qwsServer->d_func()->im_update(&cmd);
       
  1601     } else {
       
  1602         d->sendCommand(cmd);
       
  1603     }
       
  1604 }
       
  1605 
       
  1606 void QWSDisplay::sendIMResponse(int winId, int property, const QVariant &result)
       
  1607 {
       
  1608     QWSIMResponseCommand cmd;
       
  1609     cmd.simpleData.windowid = winId;
       
  1610     cmd.simpleData.property = property;
       
  1611 
       
  1612     cmd.setResult(result);
       
  1613 
       
  1614     if (d->directServerConnection()) {
       
  1615         qwsServer->d_func()->im_response(&cmd);
       
  1616     } else {
       
  1617         d->sendCommand(cmd);
       
  1618     }
       
  1619 }
       
  1620 
       
  1621 void QWSDisplay::resetIM()
       
  1622 {
       
  1623     sendIMUpdate(QWSInputMethod::Reset, -1, -1);
       
  1624 }
       
  1625 
       
  1626 void QWSDisplay::sendIMMouseEvent(int index, bool isPress)
       
  1627 {
       
  1628     QWSIMMouseCommand cmd;
       
  1629     cmd.simpleData.index = index;
       
  1630     cmd.simpleData.state = isPress ? QWSServer::MousePress : QWSServer::MouseRelease;
       
  1631     if (d->directServerConnection()) {
       
  1632         qwsServer->d_func()->send_im_mouse(&cmd);
       
  1633     } else {
       
  1634         d->sendCommand(cmd);
       
  1635     }
       
  1636 }
       
  1637 
       
  1638 #endif
       
  1639 
       
  1640 int QWSDisplay::takeId()
       
  1641 {
       
  1642     return d->takeId();
       
  1643 }
       
  1644 
       
  1645 bool QWSDisplay::initLock(const QString &filename, bool create)
       
  1646 {
       
  1647     if (!lock) {
       
  1648         lock = new QLock(filename, 'd', create);
       
  1649 
       
  1650         if (!lock->isValid()) {
       
  1651             delete lock;
       
  1652             lock = 0;
       
  1653             return false;
       
  1654         }
       
  1655     }
       
  1656 
       
  1657     return true;
       
  1658 }
       
  1659 
       
  1660 void QWSDisplay::setSelectionOwner(int winId, const QTime &time)
       
  1661 {
       
  1662     QWSSetSelectionOwnerCommand cmd;
       
  1663     cmd.simpleData.windowid = winId;
       
  1664     cmd.simpleData.hour = time.hour();
       
  1665     cmd.simpleData.minute = time.minute();
       
  1666     cmd.simpleData.sec = time.second();
       
  1667     cmd.simpleData.ms = time.msec();
       
  1668     d->sendCommand(cmd);
       
  1669 }
       
  1670 
       
  1671 void QWSDisplay::convertSelection(int winId, int selectionProperty, const QString &mimeTypes)
       
  1672 {
       
  1673 #ifdef QT_NO_QWS_PROPERTIES
       
  1674     Q_UNUSED(mimeTypes);
       
  1675 #else
       
  1676     // ### we need the atom/property thingy like in X here
       
  1677     addProperty(winId, QT_QWS_PROPERTY_CONVERTSELECTION);
       
  1678     setProperty(winId, QT_QWS_PROPERTY_CONVERTSELECTION,
       
  1679                  int(QWSPropertyManager::PropReplace), mimeTypes.toLatin1());
       
  1680 #endif
       
  1681     QWSConvertSelectionCommand cmd;
       
  1682     cmd.simpleData.requestor = winId;
       
  1683     cmd.simpleData.selection = selectionProperty;
       
  1684     cmd.simpleData.mimeTypes = QT_QWS_PROPERTY_CONVERTSELECTION;
       
  1685     d->sendCommand(cmd);
       
  1686 }
       
  1687 
       
  1688 void QWSDisplay::defineCursor(int id, const QBitmap &curs, const QBitmap &mask,
       
  1689                             int hotX, int hotY)
       
  1690 {
       
  1691     const QImage cursImg = curs.toImage().convertToFormat(QImage::Format_MonoLSB);
       
  1692     const QImage maskImg = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
       
  1693 
       
  1694     QWSDefineCursorCommand cmd;
       
  1695     cmd.simpleData.width = curs.width();
       
  1696     cmd.simpleData.height = curs.height();
       
  1697     cmd.simpleData.hotX = hotX;
       
  1698     cmd.simpleData.hotY = hotY;
       
  1699     cmd.simpleData.id = id;
       
  1700 
       
  1701 
       
  1702     // must copy each scanline since there might be gaps between them
       
  1703     const int height = curs.height();
       
  1704     const int width = curs.width();
       
  1705     const int dst_bpl = (width + 7) / 8;
       
  1706 
       
  1707     int dataLen = dst_bpl * height;
       
  1708     uchar *data = new uchar[dataLen*2];
       
  1709     uchar *dst = data;
       
  1710 
       
  1711     int src_bpl = cursImg.bytesPerLine();
       
  1712     const uchar *cursSrc = cursImg.bits();
       
  1713     for (int i = 0; i < height; ++i) {
       
  1714         memcpy(dst, cursSrc + i*src_bpl, dst_bpl);
       
  1715         dst += dst_bpl;
       
  1716     }
       
  1717 
       
  1718     src_bpl = maskImg.bytesPerLine();
       
  1719     const uchar *maskSrc = maskImg.bits();
       
  1720     for (int i = 0; i < height; ++i) {
       
  1721         memcpy(dst, maskSrc + i*src_bpl, dst_bpl);
       
  1722         dst += dst_bpl;
       
  1723     }
       
  1724 
       
  1725     cmd.setData(reinterpret_cast<char*>(data), dataLen*2);
       
  1726     delete [] data;
       
  1727     d->sendCommand(cmd);
       
  1728 }
       
  1729 
       
  1730 void QWSDisplay::destroyCursor(int id)
       
  1731 {
       
  1732     QWSDefineCursorCommand cmd;
       
  1733     cmd.simpleData.width = 0;
       
  1734     cmd.simpleData.height = 0;
       
  1735     cmd.simpleData.hotX = 0;
       
  1736     cmd.simpleData.hotY = 0;
       
  1737     cmd.simpleData.id = id;
       
  1738     cmd.setData(0, 0);
       
  1739 
       
  1740     d->sendCommand(cmd);
       
  1741 }
       
  1742 
       
  1743 #ifndef QT_NO_SOUND
       
  1744 void QWSDisplay::playSoundFile(const QString& f)
       
  1745 {
       
  1746     QWSPlaySoundCommand cmd;
       
  1747     cmd.setFileName(f);
       
  1748     d->sendCommand(cmd);
       
  1749 }
       
  1750 #endif
       
  1751 
       
  1752 #ifndef QT_NO_COP
       
  1753 void QWSDisplay::registerChannel(const QString& channel)
       
  1754 {
       
  1755     QWSQCopRegisterChannelCommand reg;
       
  1756     reg.setChannel(channel);
       
  1757     qt_fbdpy->d->sendCommand(reg);
       
  1758 }
       
  1759 
       
  1760 void QWSDisplay::sendMessage(const QString &channel, const QString &msg,
       
  1761                    const QByteArray &data)
       
  1762 {
       
  1763     QWSQCopSendCommand com;
       
  1764     com.setMessage(channel, msg, data);
       
  1765     qt_fbdpy->d->sendCommand(com);
       
  1766 }
       
  1767 
       
  1768 void QWSDisplay::flushCommands()
       
  1769 {
       
  1770     qt_fbdpy->d->flushCommands();
       
  1771 }
       
  1772 
       
  1773 /*
       
  1774   caller deletes result
       
  1775 */
       
  1776 QWSQCopMessageEvent* QWSDisplay::waitForQCopResponse()
       
  1777 {
       
  1778     qt_fbdpy->d->waitForQCopResponse();
       
  1779     QWSQCopMessageEvent *e = static_cast<QWSQCopMessageEvent*>(qt_fbdpy->d->dequeue());
       
  1780     Q_ASSERT(e->type == QWSEvent::QCopMessage);
       
  1781     return e;
       
  1782 }
       
  1783 #endif
       
  1784 
       
  1785 void QWSDisplay::sendFontCommand(int type, const QByteArray &fontName)
       
  1786 {
       
  1787     QWSFontCommand cmd;
       
  1788     cmd.simpleData.type = type;
       
  1789     cmd.setFontName(fontName);
       
  1790     d->sendCommand(cmd);
       
  1791 }
       
  1792 
       
  1793 void QWSDisplay::setWindowCaption(QWidget *w, const QString &c)
       
  1794 {
       
  1795     if (w->isWindow()) {
       
  1796         nameRegion(w->internalWinId(), w->objectName(), c);
       
  1797         static_cast<QETWidget *>(w)->repaintDecoration(qApp->desktop()->rect(), true);
       
  1798     }
       
  1799 }
       
  1800 
       
  1801 void QWSDisplay::selectCursor(QWidget *w, unsigned int cursId)
       
  1802 {
       
  1803     if (cursId != qt_last_cursor)
       
  1804     {
       
  1805         QWidget *top = w->window();
       
  1806         qt_last_cursor = cursId;
       
  1807         QWSSelectCursorCommand cmd;
       
  1808         cmd.simpleData.windowid = top->internalWinId();
       
  1809         cmd.simpleData.id = cursId;
       
  1810         d->sendCommand(cmd);
       
  1811         d->flush();
       
  1812     }
       
  1813 }
       
  1814 
       
  1815 void QWSDisplay::setCursorPosition(int x, int y)
       
  1816 {
       
  1817     QWSPositionCursorCommand cmd;
       
  1818     cmd.simpleData.newX = x;
       
  1819     cmd.simpleData.newY = y;
       
  1820     d->sendCommand(cmd);
       
  1821     d->flush();
       
  1822 }
       
  1823 
       
  1824 void QWSDisplay::grabMouse(QWidget *w, bool grab)
       
  1825 {
       
  1826     QWidget *top = w->window();
       
  1827     QWSGrabMouseCommand cmd;
       
  1828 #ifdef QT_DEBUG
       
  1829     memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
       
  1830 #endif
       
  1831     cmd.simpleData.windowid = top->winId();
       
  1832     cmd.simpleData.grab = grab;
       
  1833     d->sendCommand(cmd);
       
  1834     d->flush();
       
  1835 }
       
  1836 
       
  1837 void QWSDisplay::grabKeyboard(QWidget *w, bool grab)
       
  1838 {
       
  1839     QWidget *top = w->window();
       
  1840     QWSGrabKeyboardCommand cmd;
       
  1841 #ifdef QT_DEBUG
       
  1842     memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
       
  1843 #endif
       
  1844     cmd.simpleData.windowid = top->winId();
       
  1845     cmd.simpleData.grab = grab;
       
  1846     d->sendCommand(cmd);
       
  1847     d->flush();
       
  1848 }
       
  1849 
       
  1850 QList<QWSWindowInfo> QWSDisplay::windowList()
       
  1851 {
       
  1852     QList<QWSWindowInfo> ret;
       
  1853     if(d->directServerConnection()) {
       
  1854         QList<QWSInternalWindowInfo*> * qin=QWSServer::windowList();
       
  1855         for (int i = 0; i < qin->count(); ++i) {
       
  1856             QWSInternalWindowInfo * qwi = qin->at(i);
       
  1857             QWSWindowInfo tmp;
       
  1858             tmp.winid = qwi->winid;
       
  1859             tmp.clientid = qwi->clientid;
       
  1860             tmp.name = QString(qwi->name);
       
  1861             ret.append(tmp);
       
  1862         }
       
  1863         qDeleteAll(*qin);
       
  1864         delete qin;
       
  1865     }
       
  1866     return ret;
       
  1867 }
       
  1868 
       
  1869 int QWSDisplay::windowAt(const QPoint &p)
       
  1870 {
       
  1871     //### currently only implemented for the server process
       
  1872     int ret = 0;
       
  1873     if(d->directServerConnection()) {
       
  1874         QWSWindow *win = qwsServer->windowAt(p);
       
  1875         if (win)
       
  1876             return win->winId();
       
  1877     }
       
  1878     return ret;
       
  1879 }
       
  1880 
       
  1881 void QWSDisplay::setRawMouseEventFilter(void (*filter)(QWSMouseEvent *))
       
  1882 {
       
  1883     if (qt_fbdpy)
       
  1884         qt_fbdpy->d->setMouseFilter(filter);
       
  1885 }
       
  1886 
       
  1887 /*!
       
  1888   \relates QScreen
       
  1889 
       
  1890   Here it is. \a transformation and \a screenNo
       
  1891  */
       
  1892 void QWSDisplay::setTransformation(int transformation, int screenNo)
       
  1893 {
       
  1894     QWSScreenTransformCommand cmd;
       
  1895     cmd.setTransformation(screenNo, transformation);
       
  1896     QWSDisplay::instance()->d->sendCommand(cmd);
       
  1897 }
       
  1898 
       
  1899 static bool qt_try_modal(QWidget *, QWSEvent *);
       
  1900 
       
  1901 /*****************************************************************************
       
  1902   qt_init() - initializes Qt/FB
       
  1903  *****************************************************************************/
       
  1904 
       
  1905 static void qt_set_qws_resources()
       
  1906 
       
  1907 {
       
  1908     if (QApplication::desktopSettingsAware())
       
  1909         QApplicationPrivate::qws_apply_settings();
       
  1910 
       
  1911     if (appFont)
       
  1912         QApplication::setFont(QFont(QString::fromLocal8Bit(appFont)));
       
  1913 
       
  1914     if (appBGCol || appBTNCol || appFGCol) {
       
  1915         (void) QApplication::style();  // trigger creation of application style and system palettes
       
  1916         QColor btn;
       
  1917         QColor bg;
       
  1918         QColor fg;
       
  1919         if (appBGCol)
       
  1920             bg = QColor(appBGCol);
       
  1921         else
       
  1922             bg = QApplicationPrivate::sys_pal->color(QPalette::Window);
       
  1923         if (appFGCol)
       
  1924             fg = QColor(appFGCol);
       
  1925         else
       
  1926             fg = QApplicationPrivate::sys_pal->color(QPalette::WindowText);
       
  1927         if (appBTNCol)
       
  1928             btn = QColor(appBTNCol);
       
  1929         else
       
  1930             btn = QApplicationPrivate::sys_pal->color(QPalette::Button);
       
  1931 
       
  1932         int h,s,v;
       
  1933         fg.getHsv(&h,&s,&v);
       
  1934         QColor base = Qt::white;
       
  1935         bool bright_mode = false;
       
  1936         if (v >= 255 - 50) {
       
  1937             base = btn.darker(150);
       
  1938             bright_mode = true;
       
  1939         }
       
  1940 
       
  1941         QPalette pal(fg, btn, btn.lighter(), btn.darker(), btn.darker(150), fg, Qt::white, base, bg);
       
  1942         if (bright_mode) {
       
  1943             pal.setColor(QPalette::HighlightedText, base);
       
  1944             pal.setColor(QPalette::Highlight, Qt::white);
       
  1945         } else {
       
  1946             pal.setColor(QPalette::HighlightedText, Qt::white);
       
  1947             pal.setColor(QPalette::Highlight, Qt::darkBlue);
       
  1948         }
       
  1949         QColor disabled((fg.red()   + btn.red())  / 2,
       
  1950                         (fg.green() + btn.green())/ 2,
       
  1951                         (fg.blue()  + btn.blue()) / 2);
       
  1952         pal.setColorGroup(QPalette::Disabled, disabled, btn, btn.lighter(125),
       
  1953                           btn.darker(), btn.darker(150), disabled, Qt::white, Qt::white, bg);
       
  1954         if (bright_mode) {
       
  1955             pal.setColor(QPalette::Disabled, QPalette::HighlightedText, base);
       
  1956             pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::white);
       
  1957         } else {
       
  1958             pal.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::white);
       
  1959             pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
       
  1960         }
       
  1961         QApplicationPrivate::setSystemPalette(pal);
       
  1962 
       
  1963     }
       
  1964 }
       
  1965 
       
  1966 void QApplicationPrivate::initializeWidgetPaletteHash()
       
  1967 {
       
  1968 }
       
  1969 
       
  1970 /*! \internal
       
  1971     apply the settings to the application
       
  1972 */
       
  1973 bool QApplicationPrivate::qws_apply_settings()
       
  1974 {
       
  1975 #ifndef QT_NO_SETTINGS
       
  1976     QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
       
  1977     settings.beginGroup(QLatin1String("Qt"));
       
  1978 
       
  1979     QStringList strlist;
       
  1980     int i;
       
  1981     QPalette pal(Qt::black);
       
  1982     int groupCount = 0;
       
  1983     strlist = settings.value(QLatin1String("Palette/active")).toStringList();
       
  1984     if (strlist.count() == QPalette::NColorRoles) {
       
  1985         ++groupCount;
       
  1986         for (i = 0; i < QPalette::NColorRoles; i++)
       
  1987             pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
       
  1988                          QColor(strlist[i]));
       
  1989     }
       
  1990     strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
       
  1991     if (strlist.count() == QPalette::NColorRoles) {
       
  1992         ++groupCount;
       
  1993         for (i = 0; i < QPalette::NColorRoles; i++)
       
  1994             pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
       
  1995                          QColor(strlist[i]));
       
  1996     }
       
  1997     strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
       
  1998     if (strlist.count() == QPalette::NColorRoles) {
       
  1999         ++groupCount;
       
  2000         for (i = 0; i < QPalette::NColorRoles; i++)
       
  2001             pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
       
  2002                          QColor(strlist[i]));
       
  2003     }
       
  2004 
       
  2005 
       
  2006     if (groupCount == QPalette::NColorGroups)
       
  2007         QApplicationPrivate::setSystemPalette(pal);
       
  2008 
       
  2009     QString str = settings.value(QLatin1String("font")).toString();
       
  2010     if (!str.isEmpty()) {
       
  2011         QFont font(QApplication::font());
       
  2012         font.fromString(str);
       
  2013         QApplicationPrivate::setSystemFont(font);
       
  2014     }
       
  2015 
       
  2016     // read library (ie. plugin) path list
       
  2017     QString libpathkey =
       
  2018         QString::fromLatin1("%1.%2/libraryPath")
       
  2019         .arg(QT_VERSION >> 16)
       
  2020         .arg((QT_VERSION & 0xff00) >> 8);
       
  2021     QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
       
  2022 #ifndef QT_NO_LIBRARY
       
  2023     if (! pathlist.isEmpty()) {
       
  2024         QStringList::ConstIterator it = pathlist.constBegin();
       
  2025         while (it != pathlist.constEnd())
       
  2026             QApplication::addLibraryPath(*it++);
       
  2027     }
       
  2028 #endif
       
  2029 
       
  2030     // read new QStyle
       
  2031     QString stylename = settings.value(QLatin1String("style")).toString();
       
  2032     if (QCoreApplication::startingUp()) {
       
  2033         if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull())
       
  2034             QApplicationPrivate::styleOverride = stylename;
       
  2035     } else {
       
  2036         QApplication::setStyle(stylename);
       
  2037     }
       
  2038 
       
  2039     int num =
       
  2040         settings.value(QLatin1String("doubleClickInterval"),
       
  2041                        QApplication::doubleClickInterval()).toInt();
       
  2042     QApplication::setDoubleClickInterval(num);
       
  2043 
       
  2044     num =
       
  2045         settings.value(QLatin1String("cursorFlashTime"),
       
  2046                        QApplication::cursorFlashTime()).toInt();
       
  2047     QApplication::setCursorFlashTime(num);
       
  2048 
       
  2049 #ifndef QT_NO_WHEELEVENT
       
  2050     num =
       
  2051         settings.value(QLatin1String("wheelScrollLines"),
       
  2052                        QApplication::wheelScrollLines()).toInt();
       
  2053     QApplication::setWheelScrollLines(num);
       
  2054 #endif
       
  2055 
       
  2056     QString colorspec = settings.value(QLatin1String("colorSpec"),
       
  2057                                        QVariant(QLatin1String("default"))).toString();
       
  2058     if (colorspec == QLatin1String("normal"))
       
  2059         QApplication::setColorSpec(QApplication::NormalColor);
       
  2060     else if (colorspec == QLatin1String("custom"))
       
  2061         QApplication::setColorSpec(QApplication::CustomColor);
       
  2062     else if (colorspec == QLatin1String("many"))
       
  2063         QApplication::setColorSpec(QApplication::ManyColor);
       
  2064     else if (colorspec != QLatin1String("default"))
       
  2065         colorspec = QLatin1String("default");
       
  2066 
       
  2067 #ifndef QT_NO_TEXTCODEC
       
  2068     QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
       
  2069                                           QVariant(QLatin1String("none"))).toString();
       
  2070     if (defaultcodec != QLatin1String("none")) {
       
  2071         QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
       
  2072         if (codec)
       
  2073             QTextCodec::setCodecForTr(codec);
       
  2074     }
       
  2075 #endif
       
  2076 
       
  2077     int w = settings.value(QLatin1String("globalStrut/width")).toInt();
       
  2078     int h = settings.value(QLatin1String("globalStrut/height")).toInt();
       
  2079     QSize strut(w, h);
       
  2080     if (strut.isValid())
       
  2081         QApplication::setGlobalStrut(strut);
       
  2082 
       
  2083     QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
       
  2084     QApplication::setEffectEnabled(Qt::UI_General,
       
  2085                                    effects.contains(QLatin1String("general")));
       
  2086     QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
       
  2087                                    effects.contains(QLatin1String("animatemenu")));
       
  2088     QApplication::setEffectEnabled(Qt::UI_FadeMenu,
       
  2089                                    effects.contains(QLatin1String("fademenu")));
       
  2090     QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
       
  2091                                    effects.contains(QLatin1String("animatecombo")));
       
  2092     QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
       
  2093                                    effects.contains(QLatin1String("animatetooltip")));
       
  2094     QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
       
  2095                                    effects.contains(QLatin1String("fadetooltip")));
       
  2096     QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
       
  2097                                    effects.contains(QLatin1String("animatetoolbox")));
       
  2098 
       
  2099     settings.beginGroup(QLatin1String("Font Substitutions"));
       
  2100     QStringList fontsubs = settings.childKeys();
       
  2101     if (!fontsubs.isEmpty()) {
       
  2102         QStringList::Iterator it = fontsubs.begin();
       
  2103         for (; it != fontsubs.end(); ++it) {
       
  2104             QString fam = *it;
       
  2105             QStringList subs = settings.value(fam).toStringList();
       
  2106             QFont::insertSubstitutions(fam, subs);
       
  2107         }
       
  2108     }
       
  2109     settings.endGroup();
       
  2110 
       
  2111     settings.endGroup(); // Qt
       
  2112 
       
  2113     settings.beginGroup(QLatin1String("QWS Font Fallbacks"));
       
  2114     if (!settings.childKeys().isEmpty()) {
       
  2115         // from qfontdatabase_qws.cpp
       
  2116         extern void qt_applyFontDatabaseSettings(const QSettings &);
       
  2117         qt_applyFontDatabaseSettings(settings);
       
  2118     }
       
  2119     settings.endGroup();
       
  2120 
       
  2121     return true;
       
  2122 #else
       
  2123     return false;
       
  2124 #endif // QT_NO_SETTINGS
       
  2125 }
       
  2126 
       
  2127 
       
  2128 
       
  2129 static void init_display()
       
  2130 {
       
  2131     if (qt_fbdpy) return; // workaround server==client case
       
  2132 
       
  2133     // Connect to FB server
       
  2134     qt_fbdpy = new QWSDisplay();
       
  2135 
       
  2136     // Get display parameters
       
  2137     // Set paintdevice parameters
       
  2138     // XXX initial info sent from server
       
  2139     // Misc. initialization
       
  2140 
       
  2141     QColormap::initialize();
       
  2142     QFont::initialize();
       
  2143 #ifndef QT_NO_CURSOR
       
  2144     QCursorData::initialize();
       
  2145 #endif
       
  2146 
       
  2147     qApp->setObjectName(appName);
       
  2148 
       
  2149     if (!QApplicationPrivate::sys_font) {
       
  2150 #ifdef QT_NO_FREETYPE
       
  2151         QFont f = QFont(QLatin1String("helvetica"), 10);
       
  2152 #else
       
  2153         QFont f = QFont(QLatin1String("DejaVu Sans"), 12);
       
  2154 #endif
       
  2155         QApplicationPrivate::setSystemFont(f);
       
  2156     }
       
  2157     qt_set_qws_resources();
       
  2158 }
       
  2159 
       
  2160 void qt_init_display()
       
  2161 {
       
  2162     qt_is_gui_used = true;
       
  2163     qws_single_process = true;
       
  2164     init_display();
       
  2165 }
       
  2166 
       
  2167 static bool read_bool_env_var(const char *var, bool defaultvalue)
       
  2168 {
       
  2169     // returns true if env variable is set to non-zero
       
  2170     // returns false if env var is set to zero
       
  2171     // returns defaultvalue if env var not set
       
  2172     char *x = ::getenv(var);
       
  2173     return (x && *x) ? (strcmp(x,"0") != 0) : defaultvalue;
       
  2174 }
       
  2175 
       
  2176 static int read_int_env_var(const char *var, int defaultvalue)
       
  2177 {
       
  2178     bool ok;
       
  2179     int r = qgetenv(var).toInt(&ok);
       
  2180     return ok ? r : defaultvalue;
       
  2181 }
       
  2182 
       
  2183 void qt_init(QApplicationPrivate *priv, int type)
       
  2184 {
       
  2185 #ifdef QT_NO_QWS_MULTIPROCESS
       
  2186     if (type == QApplication::GuiClient)
       
  2187         type = QApplication::GuiServer;
       
  2188 #endif
       
  2189     if (type == QApplication::GuiServer)
       
  2190         qt_is_gui_used = false; //we'll turn it on in a second
       
  2191     qws_sw_cursor = read_bool_env_var("QWS_SW_CURSOR",qws_sw_cursor);
       
  2192     qws_screen_is_interlaced = read_bool_env_var("QWS_INTERLACE",false);
       
  2193 
       
  2194     const char *display = ::getenv("QWS_DISPLAY");
       
  2195     if (display)
       
  2196         qws_display_spec = display; // since we setenv later!
       
  2197 
       
  2198     //qws_savefonts = qgetenv("QWS_SAVEFONTS") != 0;
       
  2199     //qws_shared_memory = qgetenv("QWS_NOSHARED") == 0;
       
  2200 
       
  2201     mouse_double_click_distance = read_int_env_var("QWS_DBLCLICK_DISTANCE", 5);
       
  2202 
       
  2203     priv->inputContext = 0;
       
  2204 
       
  2205     int flags = 0;
       
  2206     char *p;
       
  2207     int argc = priv->argc;
       
  2208     char **argv = priv->argv;
       
  2209     int j;
       
  2210 
       
  2211     // Set application name
       
  2212 
       
  2213     if (argv && *argv) { //apparently, we allow people to pass 0 on the other platforms
       
  2214         p = strrchr(argv[0], '/');
       
  2215         appName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
       
  2216     }
       
  2217 
       
  2218     // Get command line params
       
  2219 
       
  2220     j = argc ? 1 : 0;
       
  2221     QString decoration;
       
  2222     for (int i=1; i<argc; i++) {
       
  2223         if (argv[i] && *argv[i] != '-') {
       
  2224             argv[j++] = argv[i];
       
  2225             continue;
       
  2226         }
       
  2227         QByteArray arg = argv[i];
       
  2228         if (arg == "-fn" || arg == "-font") {
       
  2229             if (++i < argc)
       
  2230                 appFont = argv[i];
       
  2231         } else if (arg == "-bg" || arg == "-background") {
       
  2232             if (++i < argc)
       
  2233                 appBGCol = argv[i];
       
  2234         } else if (arg == "-btn" || arg == "-button") {
       
  2235             if (++i < argc)
       
  2236                 appBTNCol = argv[i];
       
  2237         } else if (arg == "-fg" || arg == "-foreground") {
       
  2238             if (++i < argc)
       
  2239                 appFGCol = argv[i];
       
  2240         } else if (arg == "-name") {
       
  2241             if (++i < argc)
       
  2242                 appName = QString::fromLocal8Bit(argv[i]);
       
  2243         } else if (arg == "-title") {
       
  2244             if (++i < argc)
       
  2245                 mwTitle = argv[i];
       
  2246         } else if (arg == "-geometry") {
       
  2247             if (++i < argc)
       
  2248                 mwGeometry = argv[i];
       
  2249         } else if (arg == "-shared") {
       
  2250             qws_shared_memory = true;
       
  2251         } else if (arg == "-noshared") {
       
  2252             qws_shared_memory = false;
       
  2253         } else if (arg == "-savefonts") {
       
  2254             qws_savefonts = true;
       
  2255         } else if (arg == "-nosavefonts") {
       
  2256             qws_savefonts = false;
       
  2257         } else if (arg == "-swcursor") {
       
  2258             qws_sw_cursor = true;
       
  2259         } else if (arg == "-noswcursor") {
       
  2260             qws_sw_cursor = false;
       
  2261         } else if (arg == "-keyboard") {
       
  2262             flags &= ~QWSServer::DisableKeyboard;
       
  2263         } else if (arg == "-nokeyboard") {
       
  2264             flags |= QWSServer::DisableKeyboard;
       
  2265         } else if (arg == "-mouse") {
       
  2266             flags &= ~QWSServer::DisableMouse;
       
  2267         } else if (arg == "-nomouse") {
       
  2268             flags |= QWSServer::DisableMouse;
       
  2269         } else if (arg == "-qws") {
       
  2270             type = QApplication::GuiServer;
       
  2271         } else if (arg == "-interlaced") {
       
  2272             qws_screen_is_interlaced = true;
       
  2273         } else if (arg == "-display") {
       
  2274             if (++i < argc)
       
  2275                 qws_display_spec = argv[i];
       
  2276         } else if (arg == "-decoration") {
       
  2277             if (++i < argc)
       
  2278                 decoration = QString::fromLocal8Bit(argv[i]);
       
  2279         } else {
       
  2280             argv[j++] = argv[i];
       
  2281         }
       
  2282     }
       
  2283     if(j < priv->argc) {
       
  2284         priv->argv[j] = 0;
       
  2285         priv->argc = j;
       
  2286     }
       
  2287 
       
  2288     mouseInWidget = new QPointer<QWidget>;
       
  2289 
       
  2290     const QString disp = QString::fromLatin1(qws_display_spec);
       
  2291     QRegExp regexp(QLatin1String(":(\\d+)$"));
       
  2292     if (regexp.lastIndexIn(disp) != -1) {
       
  2293         const QString capture = regexp.cap(1);
       
  2294         bool ok = false;
       
  2295         int id = capture.toInt(&ok);
       
  2296         if (ok)
       
  2297             qws_display_id = id;
       
  2298     }
       
  2299 
       
  2300     if (type == QApplication::GuiServer) {
       
  2301         qt_appType = QApplication::Type(type);
       
  2302         qws_single_process = true;
       
  2303         QWSServer::startup(flags);
       
  2304         if (!display) // if not already set
       
  2305             qputenv("QWS_DISPLAY", qws_display_spec);
       
  2306     }
       
  2307 
       
  2308     if(qt_is_gui_used) {
       
  2309         init_display();
       
  2310 #ifndef QT_NO_QWS_MANAGER
       
  2311         if (decoration.isEmpty() && !qws_decoration) {
       
  2312             const QStringList keys = QDecorationFactory::keys();
       
  2313             if (!keys.isEmpty())
       
  2314                 decoration = keys.first();
       
  2315         }
       
  2316         if (!decoration.isEmpty())
       
  2317             qws_decoration = QApplication::qwsSetDecoration(decoration);
       
  2318 #endif // QT_NO_QWS_MANAGER
       
  2319 #ifndef QT_NO_QWS_INPUTMETHODS
       
  2320         qApp->setInputContext(new QWSInputContext(qApp));
       
  2321 #endif
       
  2322     }
       
  2323 
       
  2324 /*### convert interlace style
       
  2325     if (qws_screen_is_interlaced)
       
  2326         QApplication::setStyle(new QInterlaceStyle);
       
  2327 */
       
  2328 }
       
  2329 
       
  2330 /*****************************************************************************
       
  2331   qt_cleanup() - cleans up when the application is finished
       
  2332  *****************************************************************************/
       
  2333 
       
  2334 void qt_cleanup()
       
  2335 {
       
  2336     QPixmapCache::clear();
       
  2337 #ifndef QT_NO_CURSOR
       
  2338     QCursorData::cleanup();
       
  2339 #endif
       
  2340     QFont::cleanup();
       
  2341     QColormap::cleanup();
       
  2342 
       
  2343     if (qws_single_process) {
       
  2344         QWSServer::closedown();
       
  2345     }
       
  2346 
       
  2347     qDeleteAll(outgoing);
       
  2348     outgoing.clear();
       
  2349     qDeleteAll(incoming);
       
  2350     incoming.clear();
       
  2351 
       
  2352     if (qt_is_gui_used) {
       
  2353         delete qt_fbdpy;
       
  2354     }
       
  2355     qt_fbdpy = 0;
       
  2356 
       
  2357 #ifndef QT_NO_QWS_MANAGER
       
  2358     delete qws_decoration;
       
  2359     qws_decoration = 0;
       
  2360 #endif
       
  2361 
       
  2362     delete mouseInWidget;
       
  2363     mouseInWidget = 0;
       
  2364 
       
  2365 #if !defined(QT_NO_IM)
       
  2366     delete QApplicationPrivate::inputContext;
       
  2367     QApplicationPrivate::inputContext = 0;
       
  2368 #endif
       
  2369 }
       
  2370 
       
  2371 
       
  2372 /*****************************************************************************
       
  2373   Platform specific global and internal functions
       
  2374  *****************************************************************************/
       
  2375 
       
  2376 QString QApplicationPrivate::appName() const // get application name
       
  2377 {
       
  2378     return QT_PREPEND_NAMESPACE(appName);
       
  2379 }
       
  2380 
       
  2381 /*****************************************************************************
       
  2382   Platform specific QApplication members
       
  2383  *****************************************************************************/
       
  2384 
       
  2385 #define NoValue         0x0000
       
  2386 #define XValue          0x0001
       
  2387 #define YValue          0x0002
       
  2388 #define WidthValue      0x0004
       
  2389 #define HeightValue     0x0008
       
  2390 #define AllValues       0x000F
       
  2391 #define XNegative       0x0010
       
  2392 #define YNegative       0x0020
       
  2393 
       
  2394 /* Copyright notice for ReadInteger and parseGeometry
       
  2395 
       
  2396 Copyright (c) 1985, 1986, 1987  X Consortium
       
  2397 
       
  2398 Permission is hereby granted, free of charge, to any person obtaining
       
  2399 a copy of this software and associated documentation files (the
       
  2400 "Software"), to deal in the Software without restriction, including
       
  2401 without limitation the rights to use, copy, modify, merge, publish,
       
  2402 distribute, sublicense, and/or sell copies of the Software, and to
       
  2403 permit persons to whom the Software is furnished to do so, subject to
       
  2404 the following conditions:
       
  2405 
       
  2406 The above copyright notice and this permission notice shall be included
       
  2407 in all copies or substantial portions of the Software.
       
  2408 
       
  2409 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
       
  2410 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
  2411 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
       
  2412 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
       
  2413 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
       
  2414 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
       
  2415 OTHER DEALINGS IN THE SOFTWARE.
       
  2416 
       
  2417 Except as contained in this notice, the name of the X Consortium shall
       
  2418 not be used in advertising or otherwise to promote the sale, use or
       
  2419 other dealings in this Software without prior written authorization
       
  2420 from the X Consortium.
       
  2421 
       
  2422 */
       
  2423 /*
       
  2424  *    XParseGeometry parses strings of the form
       
  2425  *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
       
  2426  *   width, height, xoffset, and yoffset are unsigned integers.
       
  2427  *   Example:  "=80x24+300-49"
       
  2428  *   The equal sign is optional.
       
  2429  *   It returns a bitmask that indicates which of the four values
       
  2430  *   were actually found in the string. For each value found,
       
  2431  *   the corresponding argument is updated;  for each value
       
  2432  *   not found, the corresponding argument is left unchanged.
       
  2433  */
       
  2434 
       
  2435 static int
       
  2436 ReadInteger(char *string, char **NextString)
       
  2437 {
       
  2438     register int Result = 0;
       
  2439     int Sign = 1;
       
  2440 
       
  2441     if (*string == '+')
       
  2442         string++;
       
  2443     else if (*string == '-')
       
  2444     {
       
  2445         string++;
       
  2446         Sign = -1;
       
  2447     }
       
  2448     for (; (*string >= '0') && (*string <= '9'); string++)
       
  2449     {
       
  2450         Result = (Result * 10) + (*string - '0');
       
  2451     }
       
  2452     *NextString = string;
       
  2453     if (Sign >= 0)
       
  2454         return Result;
       
  2455     else
       
  2456         return -Result;
       
  2457 }
       
  2458 
       
  2459 static int parseGeometry(const char* string,
       
  2460                           int* x, int* y, int* width, int* height)
       
  2461 {
       
  2462         int mask = NoValue;
       
  2463         register char *strind;
       
  2464         unsigned int tempWidth=0, tempHeight=0;
       
  2465         int tempX=0, tempY=0;
       
  2466         char *nextCharacter;
       
  2467 
       
  2468         if (!string || (*string == '\0')) return mask;
       
  2469         if (*string == '=')
       
  2470                 string++;  /* ignore possible '=' at beg of geometry spec */
       
  2471 
       
  2472         strind = const_cast<char *>(string);
       
  2473         if (*strind != '+' && *strind != '-' && *strind != 'x') {
       
  2474                 tempWidth = ReadInteger(strind, &nextCharacter);
       
  2475                 if (strind == nextCharacter)
       
  2476                     return 0;
       
  2477                 strind = nextCharacter;
       
  2478                 mask |= WidthValue;
       
  2479         }
       
  2480 
       
  2481         if (*strind == 'x' || *strind == 'X') {
       
  2482                 strind++;
       
  2483                 tempHeight = ReadInteger(strind, &nextCharacter);
       
  2484                 if (strind == nextCharacter)
       
  2485                     return 0;
       
  2486                 strind = nextCharacter;
       
  2487                 mask |= HeightValue;
       
  2488         }
       
  2489 
       
  2490         if ((*strind == '+') || (*strind == '-')) {
       
  2491                 if (*strind == '-') {
       
  2492                         strind++;
       
  2493                         tempX = -ReadInteger(strind, &nextCharacter);
       
  2494                         if (strind == nextCharacter)
       
  2495                             return 0;
       
  2496                         strind = nextCharacter;
       
  2497                         mask |= XNegative;
       
  2498 
       
  2499                 }
       
  2500                 else
       
  2501                 {        strind++;
       
  2502                         tempX = ReadInteger(strind, &nextCharacter);
       
  2503                         if (strind == nextCharacter)
       
  2504                             return 0;
       
  2505                         strind = nextCharacter;
       
  2506                 }
       
  2507                 mask |= XValue;
       
  2508                 if ((*strind == '+') || (*strind == '-')) {
       
  2509                         if (*strind == '-') {
       
  2510                                 strind++;
       
  2511                                 tempY = -ReadInteger(strind, &nextCharacter);
       
  2512                                 if (strind == nextCharacter)
       
  2513                                     return 0;
       
  2514                                 strind = nextCharacter;
       
  2515                                 mask |= YNegative;
       
  2516 
       
  2517                         }
       
  2518                         else
       
  2519                         {
       
  2520                                 strind++;
       
  2521                                 tempY = ReadInteger(strind, &nextCharacter);
       
  2522                                 if (strind == nextCharacter)
       
  2523                                     return 0;
       
  2524                                 strind = nextCharacter;
       
  2525                         }
       
  2526                         mask |= YValue;
       
  2527                 }
       
  2528         }
       
  2529 
       
  2530         /* If strind isn't at the end of the string then it's an invalid
       
  2531                 geometry specification. */
       
  2532 
       
  2533         if (*strind != '\0') return 0;
       
  2534 
       
  2535         if (mask & XValue)
       
  2536             *x = tempX;
       
  2537         if (mask & YValue)
       
  2538             *y = tempY;
       
  2539         if (mask & WidthValue)
       
  2540             *width = tempWidth;
       
  2541         if (mask & HeightValue)
       
  2542             *height = tempHeight;
       
  2543         return mask;
       
  2544 }
       
  2545 
       
  2546 #ifdef QT3_SUPPORT
       
  2547 void QApplication::setMainWidget(QWidget *mainWidget)
       
  2548 {
       
  2549     QApplicationPrivate::main_widget = mainWidget;
       
  2550     if (QApplicationPrivate::main_widget) // give WM command line
       
  2551         QApplicationPrivate::applyQWSSpecificCommandLineArguments(QApplicationPrivate::main_widget);
       
  2552 }
       
  2553 #endif
       
  2554 
       
  2555 void QApplicationPrivate::applyQWSSpecificCommandLineArguments(QWidget *main_widget)
       
  2556 {
       
  2557     static bool beenHereDoneThat = false;
       
  2558     if (beenHereDoneThat)
       
  2559         return;
       
  2560     beenHereDoneThat = true;
       
  2561     if (qApp->windowIcon().isNull() && main_widget->testAttribute(Qt::WA_SetWindowIcon))
       
  2562         qApp->setWindowIcon(main_widget->windowIcon());
       
  2563     if (mwTitle) //  && main_widget->windowTitle().isEmpty())
       
  2564         main_widget->setWindowTitle(QString::fromLocal8Bit(mwTitle));
       
  2565     if (mwGeometry) { // parse geometry
       
  2566         int x = 0;
       
  2567         int y = 0;
       
  2568         int w = 0;
       
  2569         int h = 0;
       
  2570         int m = parseGeometry(mwGeometry, &x, &y, &w, &h);
       
  2571         QSize minSize = main_widget->minimumSize();
       
  2572         QSize maxSize = main_widget->maximumSize();
       
  2573         if ((m & XValue) == 0)
       
  2574             x = main_widget->geometry().x();
       
  2575         if ((m & YValue) == 0)
       
  2576             y = main_widget->geometry().y();
       
  2577         if ((m & WidthValue) == 0)
       
  2578             w = main_widget->width();
       
  2579         if ((m & HeightValue) == 0)
       
  2580             h = main_widget->height();
       
  2581         w = qMin(w,maxSize.width());
       
  2582         h = qMin(h,maxSize.height());
       
  2583         w = qMax(w,minSize.width());
       
  2584         h = qMax(h,minSize.height());
       
  2585         if ((m & XNegative)) {
       
  2586             x = qApp->desktop()->width()  + x - w;
       
  2587             x -= (main_widget->frameGeometry().width() - main_widget->width()) / 2;
       
  2588         } else {
       
  2589             x += (main_widget->geometry().x() - main_widget->x());
       
  2590         }
       
  2591         if ((m & YNegative)) {
       
  2592             y = qApp->desktop()->height() + y - h;
       
  2593         } else {
       
  2594             y += (main_widget->geometry().y() - main_widget->y());
       
  2595         }
       
  2596 
       
  2597         main_widget->setGeometry(x, y, w, h);
       
  2598     }
       
  2599 }
       
  2600 
       
  2601 /*****************************************************************************
       
  2602   QApplication cursor stack
       
  2603  *****************************************************************************/
       
  2604 #ifndef QT_NO_CURSOR
       
  2605 void QApplication::setOverrideCursor(const QCursor &cursor)
       
  2606 {
       
  2607     qApp->d_func()->cursor_list.prepend(cursor);
       
  2608 
       
  2609     QWidget *w = QWidget::mouseGrabber();
       
  2610     if (!w && qt_last_x)
       
  2611         w = topLevelAt(*qt_last_x, *qt_last_y);
       
  2612     if (!w)
       
  2613         w = desktop();
       
  2614     QPaintDevice::qwsDisplay()->selectCursor(w, qApp->d_func()->cursor_list.first().handle());
       
  2615 }
       
  2616 
       
  2617 void QApplication::restoreOverrideCursor()
       
  2618 {
       
  2619     if (qApp->d_func()->cursor_list.isEmpty())
       
  2620         return;
       
  2621     qApp->d_func()->cursor_list.removeFirst();
       
  2622 
       
  2623     QWidget *w = QWidget::mouseGrabber();
       
  2624     if (!w && qt_last_x)
       
  2625         w = topLevelAt(*qt_last_x, *qt_last_y);
       
  2626     if (!w)
       
  2627         w = desktop();
       
  2628 
       
  2629     int cursor_handle = Qt::ArrowCursor;
       
  2630     if (qApp->d_func()->cursor_list.isEmpty()) {
       
  2631         qws_overrideCursor = false;
       
  2632         QWidget *upw = QApplication::widgetAt(*qt_last_x, *qt_last_y);
       
  2633         if (upw)
       
  2634             cursor_handle = upw->cursor().handle();
       
  2635     } else {
       
  2636         cursor_handle = qApp->d_func()->cursor_list.first().handle();
       
  2637     }
       
  2638     QPaintDevice::qwsDisplay()->selectCursor(w, cursor_handle);
       
  2639 }
       
  2640 #endif// QT_NO_CURSOR
       
  2641 
       
  2642 
       
  2643 
       
  2644 /*****************************************************************************
       
  2645   Routines to find a Qt widget from a screen position
       
  2646  *****************************************************************************/
       
  2647 
       
  2648 /*!
       
  2649     \internal
       
  2650 */
       
  2651 QWidget *QApplicationPrivate::findWidget(const QObjectList& list,
       
  2652                                    const QPoint &pos, bool rec)
       
  2653 {
       
  2654     QWidget *w;
       
  2655 
       
  2656     for (int i = list.size()-1; i >= 0; --i) {
       
  2657         if (list.at(i)->isWidgetType()) {
       
  2658           w = static_cast<QWidget*>(list.at(i));
       
  2659             if (w->isVisible() && !w->testAttribute(Qt::WA_TransparentForMouseEvents) &&  w->geometry().contains(pos)
       
  2660                 && (!w->d_func()->extra || w->d_func()->extra->mask.isEmpty() ||  w->d_func()->extra->mask.contains(pos - w->geometry().topLeft()) )) {
       
  2661                 if (!rec)
       
  2662                     return w;
       
  2663                 QWidget *c = w->childAt(w->mapFromParent(pos));
       
  2664                 return c ? c : w;
       
  2665             }
       
  2666         }
       
  2667     }
       
  2668     return 0;
       
  2669 }
       
  2670 
       
  2671 
       
  2672 QWidget *QApplication::topLevelAt(const QPoint &pos)
       
  2673 {
       
  2674     //### QWSDisplay::windowAt() is currently only implemented in the server process
       
  2675     int winId = QPaintDevice::qwsDisplay()->windowAt(pos);
       
  2676     if (winId !=0)
       
  2677         return QWidget::find(winId);
       
  2678 
       
  2679 #if 1
       
  2680     // fallback implementation for client processes
       
  2681 //### This is slightly wrong: we have no guarantee that the list is in
       
  2682 //### stacking order, so if the topmost window is transparent, we may
       
  2683 //### return the wrong widget
       
  2684 
       
  2685     QWidgetList list = topLevelWidgets();
       
  2686     for (int i = list.size()-1; i >= 0; --i) {
       
  2687         QWidget *w = list[i];
       
  2688         if (w != QApplication::desktop() &&
       
  2689              w->isVisible() && w->d_func()->localAllocatedRegion().contains(w->mapFromParent(pos))
       
  2690             )
       
  2691             return w;
       
  2692     }
       
  2693 #endif
       
  2694     return 0;
       
  2695 }
       
  2696 
       
  2697 void QApplication::beep()
       
  2698 {
       
  2699 }
       
  2700 
       
  2701 void QApplication::alert(QWidget *, int)
       
  2702 {
       
  2703 }
       
  2704 
       
  2705 int QApplication::qwsProcessEvent(QWSEvent* event)
       
  2706 {
       
  2707     Q_D(QApplication);
       
  2708     QScopedLoopLevelCounter loopLevelCounter(d->threadData);
       
  2709     int oldstate = -1;
       
  2710     bool isMove = false;
       
  2711     if (event->type == QWSEvent::Mouse) {
       
  2712         QWSMouseEvent::SimpleData &mouse = event->asMouse()->simpleData;
       
  2713         isMove = mouse_x_root != mouse.x_root || mouse_y_root != mouse.y_root;
       
  2714         oldstate = mouse_state;
       
  2715         mouse_x_root = mouse.x_root;
       
  2716         mouse_y_root = mouse.y_root;
       
  2717         mouse_state = mouse.state;
       
  2718     }
       
  2719 
       
  2720     long unused;
       
  2721     if (filterEvent(event, &unused))                  // send through app filter
       
  2722         return 1;
       
  2723 
       
  2724     if (qwsEventFilter(event))                        // send through app filter
       
  2725         return 1;
       
  2726 
       
  2727 
       
  2728 #ifndef QT_NO_QWS_PROPERTIES
       
  2729     if (event->type == QWSEvent::PropertyNotify) {
       
  2730         QWSPropertyNotifyEvent *e = static_cast<QWSPropertyNotifyEvent*>(event);
       
  2731         if (e->simpleData.property == 424242) {       // Clipboard
       
  2732 #ifndef QT_NO_CLIPBOARD
       
  2733             if (qt_clipboard) {
       
  2734                 QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
       
  2735                 QApplication::sendEvent(qt_clipboard, &e);
       
  2736             }
       
  2737 #endif
       
  2738         }
       
  2739     }
       
  2740 #endif //QT_NO_QWS_PROPERTIES
       
  2741 #ifndef QT_NO_COP
       
  2742     else if (event->type == QWSEvent::QCopMessage) {
       
  2743         QWSQCopMessageEvent *e = static_cast<QWSQCopMessageEvent*>(event);
       
  2744         QCopChannel::sendLocally(QLatin1String(e->channel), QLatin1String(e->message), e->data);
       
  2745         return 0;
       
  2746     }
       
  2747 #endif
       
  2748 #if !defined(QT_NO_QWS_QPF2)
       
  2749     else if (event->type == QWSEvent::Font) {
       
  2750         QWSFontEvent *e = static_cast<QWSFontEvent *>(event);
       
  2751         if (e->simpleData.type == QWSFontEvent::FontRemoved) {
       
  2752             QFontCache::instance()->removeEngineForFont(e->fontName);
       
  2753         }
       
  2754     }
       
  2755 #endif
       
  2756 
       
  2757     QPointer<QETWidget> widget = static_cast<QETWidget*>(QWidget::find(WId(event->window())));
       
  2758 #ifdef Q_BACKINGSTORE_SUBSURFACES
       
  2759     if (!widget) { // XXX: hw: hack for accessing subsurfaces
       
  2760         extern QWSWindowSurface* qt_findWindowSurface(int);
       
  2761         QWSWindowSurface *s = qt_findWindowSurface(event->window());
       
  2762         if (s)
       
  2763             widget = static_cast<QETWidget*>(s->window());
       
  2764     }
       
  2765 #endif
       
  2766 
       
  2767 #ifndef QT_NO_DIRECTPAINTER
       
  2768     if (!widget && d->directPainters) {
       
  2769         QDirectPainter *dp = d->directPainters->value(WId(event->window()));
       
  2770         if (dp == 0) {
       
  2771         } else if (event->type == QWSEvent::Region) {
       
  2772             QWSRegionEvent *e = static_cast<QWSRegionEvent*>(event);
       
  2773             QRegion reg;
       
  2774             reg.setRects(e->rectangles, e->simpleData.nrectangles);
       
  2775             qt_directpainter_region(dp, reg, e->simpleData.type);
       
  2776             return 1;
       
  2777 #ifndef QT_NO_QWSEMBEDWIDGET
       
  2778         } else if (event->type == QWSEvent::Embed) {
       
  2779             QWSEmbedEvent *e = static_cast<QWSEmbedEvent*>(event);
       
  2780             qt_directpainter_embedevent(dp, e);
       
  2781             return 1;
       
  2782  #endif // QT_NO_QWSEMBEDWIDGET
       
  2783         }
       
  2784     }
       
  2785 #endif // QT_NO_DIRECTPAINTER
       
  2786 
       
  2787 #ifndef QT_NO_QWS_MANAGER
       
  2788     if (d->last_manager && event->type == QWSEvent::Mouse) {
       
  2789         QPoint pos(event->asMouse()->simpleData.x_root, event->asMouse()->simpleData.y_root);
       
  2790         if (!d->last_manager->cachedRegion().contains(pos)) {
       
  2791             // MouseEvent not yet delivered, so QCursor::pos() is not yet updated, sending 2 x pos
       
  2792             QMouseEvent outside(QEvent::MouseMove, pos, pos, Qt::NoButton, 0, 0);
       
  2793             QApplication::sendSpontaneousEvent(d->last_manager, &outside);
       
  2794             d->last_manager = 0;
       
  2795             qt_last_cursor = 0xffffffff; //decoration is like another window; must redo cursor
       
  2796         }
       
  2797     }
       
  2798 #endif // QT_NO_QWS_MANAGER
       
  2799 
       
  2800     QETWidget *keywidget=0;
       
  2801     bool grabbed=false;
       
  2802     if (event->type==QWSEvent::Key || event->type == QWSEvent::IMEvent || event->type == QWSEvent::IMQuery) {
       
  2803         keywidget = static_cast<QETWidget*>(QWidget::keyboardGrabber());
       
  2804         if (keywidget) {
       
  2805             grabbed = true;
       
  2806         } else {
       
  2807             if (QWidget *popup = QApplication::activePopupWidget()) {
       
  2808                 if (popup->focusWidget())
       
  2809                     keywidget = static_cast<QETWidget*>(popup->focusWidget());
       
  2810                 else
       
  2811                     keywidget = static_cast<QETWidget*>(popup);
       
  2812             } else if (QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget->isVisible())
       
  2813                 keywidget = static_cast<QETWidget*>(QApplicationPrivate::focus_widget);
       
  2814             else if (widget)
       
  2815                 keywidget = static_cast<QETWidget*>(widget->window());
       
  2816         }
       
  2817     } else if (event->type==QWSEvent::MaxWindowRect) {
       
  2818         QRect r = static_cast<QWSMaxWindowRectEvent*>(event)->simpleData.rect;
       
  2819         setMaxWindowRect(r);
       
  2820         return 0;
       
  2821 #ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
       
  2822     } else if (event->type == QWSEvent::ScreenTransformation) {
       
  2823         QWSScreenTransformationEvent *pe = static_cast<QWSScreenTransformationEvent*>(event);
       
  2824         setScreenTransformation(pe->simpleData.screen,
       
  2825                                 pe->simpleData.transformation);
       
  2826         return 0;
       
  2827 #endif
       
  2828     } else if (widget && event->type==QWSEvent::Mouse) {
       
  2829         // The mouse event is to one of my top-level widgets
       
  2830         // which one?
       
  2831         const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton;
       
  2832         QPoint p(event->asMouse()->simpleData.x_root,
       
  2833                  event->asMouse()->simpleData.y_root);
       
  2834         int mouseButtonState = event->asMouse()->simpleData.state & btnMask;
       
  2835         static int btnstate = 0;
       
  2836 
       
  2837         QETWidget *w = static_cast<QETWidget*>(QWidget::mouseGrabber());
       
  2838         if (w && !mouseButtonState && qt_pressGrab == w)
       
  2839             qt_pressGrab = 0;
       
  2840 #ifndef QT_NO_QWS_MANAGER
       
  2841         if (!w)
       
  2842             w = static_cast<QETWidget*>(QWSManager::grabbedMouse());
       
  2843 #endif
       
  2844         if (w) {
       
  2845             // Our mouse is grabbed - send it.
       
  2846             widget = w;
       
  2847             btnstate = mouseButtonState;
       
  2848         } else {
       
  2849             static QWidget *gw = 0;
       
  2850             // Three jobs to do here:
       
  2851             // 1. find the child widget this event belongs to.
       
  2852             // 2. make sure the cursor is correct.
       
  2853             // 3. handle implicit mouse grab due to button press.
       
  2854             w = widget; // w is the widget the cursor is in.
       
  2855 
       
  2856             //### ??? alloc_region
       
  2857             //#### why should we get events outside alloc_region ????
       
  2858             if (1 /*widget->data->alloc_region.contains(dp) */) {
       
  2859                 // Find the child widget that the cursor is in.
       
  2860                 w = static_cast<QETWidget*>(widget->childAt(widget->mapFromParent(p)));
       
  2861                 if (!w)
       
  2862                     w = widget;
       
  2863 #ifndef QT_NO_CURSOR
       
  2864                 // Update Cursor.
       
  2865                 if (!gw || gw != w || qt_last_cursor == 0xffffffff) {
       
  2866                     QCursor *curs = 0;
       
  2867                     if (!qApp->d_func()->cursor_list.isEmpty())
       
  2868                         curs = &qApp->d_func()->cursor_list.first();
       
  2869                     else if (w->d_func()->extraData())
       
  2870                         curs = w->d_func()->extraData()->curs;
       
  2871                     QWidget *pw = w;
       
  2872                     // If this widget has no cursor set, try parent.
       
  2873                     while (!curs) {
       
  2874                         pw = pw->parentWidget();
       
  2875                         if (!pw)
       
  2876                             break;
       
  2877                         if (pw->d_func()->extraData())
       
  2878                             curs = pw->d_func()->extraData()->curs;
       
  2879                     }
       
  2880                     if (!qws_overrideCursor) {
       
  2881                         if (curs)
       
  2882                             QPaintDevice::qwsDisplay()->selectCursor(widget, curs->handle());
       
  2883                         else
       
  2884                             QPaintDevice::qwsDisplay()->selectCursor(widget, Qt::ArrowCursor);
       
  2885                     }
       
  2886                 }
       
  2887 #endif
       
  2888                 gw = w;
       
  2889             } else {
       
  2890                 // This event is not for any of our widgets
       
  2891                 gw = 0;
       
  2892             }
       
  2893             if (mouseButtonState && !btnstate) {
       
  2894                 // The server has grabbed the mouse for us.
       
  2895                 // Remember which of my widgets has it.
       
  2896                 qt_pressGrab = w;
       
  2897                 if (!widget->isActiveWindow() &&
       
  2898                     (!app_do_modal || QApplication::activeModalWidget() == widget) &&
       
  2899                     !((widget->windowFlags() & Qt::FramelessWindowHint) || (widget->windowType() == Qt::Tool))) {
       
  2900                     widget->activateWindow();
       
  2901                     if (widget->raiseOnClick())
       
  2902                         widget->raise();
       
  2903                 }
       
  2904             }
       
  2905             btnstate = mouseButtonState;
       
  2906             widget = w;
       
  2907         }
       
  2908     }
       
  2909 
       
  2910     if (!widget) {                                // don't know this window
       
  2911         if (!QWidget::mouseGrabber()
       
  2912 #ifndef QT_NO_QWS_MANAGER
       
  2913             && !QWSManager::grabbedMouse()
       
  2914 #endif
       
  2915             ) {
       
  2916             qt_last_cursor = 0xffffffff; // cursor can be changed by another application
       
  2917         }
       
  2918 
       
  2919         QWidget* popup = QApplication::activePopupWidget();
       
  2920         if (popup) {
       
  2921 
       
  2922             /*
       
  2923               That is more than suboptimal. The real solution should
       
  2924               do some keyevent and buttonevent translation, so that
       
  2925               the popup still continues to work as the user expects.
       
  2926               Unfortunately this translation is currently only
       
  2927               possible with a known widget. I'll change that soon
       
  2928               (Matthias).
       
  2929             */
       
  2930 
       
  2931             // Danger - make sure we don't lock the server
       
  2932             switch (event->type) {
       
  2933             case QWSEvent::Mouse:
       
  2934             case QWSEvent::Key:
       
  2935                 do {
       
  2936                     popup->close();
       
  2937                 } while ((popup = qApp->activePopupWidget()));
       
  2938                 return 1;
       
  2939             }
       
  2940         }
       
  2941         if (event->type == QWSEvent::Mouse && *mouseInWidget) {
       
  2942             QApplicationPrivate::dispatchEnterLeave(0, *mouseInWidget);
       
  2943             (*mouseInWidget) = 0;
       
  2944         }
       
  2945         return -1;
       
  2946     }
       
  2947 
       
  2948     if (app_do_modal)                                // modal event handling
       
  2949         if (!qt_try_modal(widget, event)) {
       
  2950             return 1;
       
  2951         }
       
  2952 
       
  2953     if (widget->qwsEvent(event))                // send through widget filter
       
  2954         return 1;
       
  2955     switch (event->type) {
       
  2956 
       
  2957     case QWSEvent::Mouse: {                        // mouse event
       
  2958         QWSMouseEvent *me = event->asMouse();
       
  2959         QWSMouseEvent::SimpleData &mouse = me->simpleData;
       
  2960 
       
  2961         //  Translate a QWS event into separate move
       
  2962         // and press/release events
       
  2963         // Beware of reentrancy: we can enter a modal state
       
  2964         // inside translateMouseEvent
       
  2965 
       
  2966         if (isMove) {
       
  2967             QWSMouseEvent move = *me;
       
  2968             move.simpleData.state = oldstate;
       
  2969             widget->translateMouseEvent(&move, oldstate);
       
  2970         }
       
  2971         if ((mouse.state&Qt::MouseButtonMask) != (oldstate&Qt::MouseButtonMask)) {
       
  2972             widget->translateMouseEvent(me, oldstate);
       
  2973         }
       
  2974 
       
  2975         if (mouse.delta != 0)
       
  2976             widget->translateWheelEvent(me);
       
  2977 
       
  2978         if (qt_button_down && (mouse_state & Qt::MouseButtonMask) == 0)
       
  2979             qt_button_down = 0;
       
  2980 
       
  2981         break;
       
  2982     }
       
  2983     case QWSEvent::Key:                                // keyboard event
       
  2984         if (keywidget) // should always exist
       
  2985             keywidget->translateKeyEvent(static_cast<QWSKeyEvent*>(event), grabbed);
       
  2986         break;
       
  2987 
       
  2988 #ifndef QT_NO_QWS_INPUTMETHODS
       
  2989     case QWSEvent::IMEvent:
       
  2990         if (keywidget) // should always exist
       
  2991             QWSInputContext::translateIMEvent(keywidget, static_cast<QWSIMEvent*>(event));
       
  2992         break;
       
  2993 
       
  2994     case QWSEvent::IMQuery:
       
  2995         if (keywidget) // should always exist
       
  2996             QWSInputContext::translateIMQueryEvent(keywidget, static_cast<QWSIMQueryEvent*>(event));
       
  2997         break;
       
  2998 
       
  2999     case QWSEvent::IMInit:
       
  3000         QWSInputContext::translateIMInitEvent(static_cast<QWSIMInitEvent*>(event));
       
  3001         break;
       
  3002 #endif
       
  3003     case QWSEvent::Region:
       
  3004         widget->translateRegionEvent(static_cast<QWSRegionEvent*>(event));
       
  3005         break;
       
  3006     case QWSEvent::Focus:
       
  3007         if ((static_cast<QWSFocusEvent*>(event))->simpleData.get_focus) {
       
  3008             if (widget == static_cast<QWidget *>(desktop()))
       
  3009                 return true; // not interesting
       
  3010             if (activeWindow() != widget) {
       
  3011                 setActiveWindow(widget);
       
  3012                 if (QApplicationPrivate::active_window)
       
  3013                     static_cast<QETWidget *>(QApplicationPrivate::active_window)->repaintDecoration(desktop()->rect(), false);
       
  3014                 if (widget && !d->inPopupMode()) {
       
  3015                     QWidget *w = widget->focusWidget();
       
  3016                     while (w && w->focusProxy())
       
  3017                         w = w->focusProxy();
       
  3018                     if (w && (w->focusPolicy() != Qt::NoFocus))
       
  3019                         w->setFocus();
       
  3020                     else
       
  3021                         widget->QWidget::focusNextPrevChild(true);
       
  3022                     if (!QApplicationPrivate::focus_widget) {
       
  3023                         if (widget->focusWidget())
       
  3024                             widget->focusWidget()->setFocus();
       
  3025                         else
       
  3026                             widget->window()->setFocus();
       
  3027                     }
       
  3028                 }
       
  3029             }
       
  3030         } else {        // lost focus
       
  3031             if (widget == static_cast<QWidget *>(desktop()))
       
  3032                 return true; // not interesting
       
  3033             if (QApplicationPrivate::focus_widget) {
       
  3034                 QETWidget *old = static_cast<QETWidget *>(QApplicationPrivate::active_window);
       
  3035                 setActiveWindow(0);
       
  3036                 qt_last_cursor = 0xffffffff;
       
  3037                 //QApplicationPrivate::active_window = 0;
       
  3038                 if (old)
       
  3039                     old->repaintDecoration(desktop()->rect(), false);
       
  3040                 /* activateWindow() sends focus events
       
  3041                    QApplication::setFocusWidget(0);
       
  3042                 */
       
  3043             }
       
  3044         }
       
  3045         break;
       
  3046 
       
  3047     case QWSEvent::WindowOperation:
       
  3048         if (static_cast<QWidget *>(widget) == desktop())
       
  3049             return true;
       
  3050         switch ((static_cast<QWSWindowOperationEvent *>(event))->simpleData.op) {
       
  3051         case QWSWindowOperationEvent::Show:
       
  3052             widget->show();
       
  3053             break;
       
  3054         case QWSWindowOperationEvent::Hide:
       
  3055             widget->hide();
       
  3056             break;
       
  3057         case QWSWindowOperationEvent::ShowMaximized:
       
  3058             widget->showMaximized();
       
  3059             break;
       
  3060         case QWSWindowOperationEvent::ShowMinimized:
       
  3061             widget->showMinimized();
       
  3062             break;
       
  3063         case QWSWindowOperationEvent::ShowNormal:
       
  3064             widget->showNormal();
       
  3065             break;
       
  3066         case QWSWindowOperationEvent::Close:
       
  3067             widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
       
  3068             break;
       
  3069         }
       
  3070         break;
       
  3071 #ifndef QT_NO_QWSEMBEDWIDGET
       
  3072     case QWSEvent::Embed:
       
  3073         widget->translateEmbedEvent(static_cast<QWSEmbedEvent*>(event));
       
  3074         break;
       
  3075 #endif
       
  3076     default:
       
  3077         break;
       
  3078     }
       
  3079 
       
  3080     return 0;
       
  3081 }
       
  3082 
       
  3083 bool QApplication::qwsEventFilter(QWSEvent *)
       
  3084 {
       
  3085     return false;
       
  3086 }
       
  3087 
       
  3088 void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors)
       
  3089 {
       
  3090     if (start < 0 || start > 39) {
       
  3091         qWarning("QApplication::qwsSetCustomColors: start < 0 || start > 39");
       
  3092         return;
       
  3093     }
       
  3094     if (start + numColors > 40) {
       
  3095         numColors = 40 - start;
       
  3096         qWarning("QApplication::qwsSetCustomColors: Too many colors");
       
  3097     }
       
  3098     start += 216;
       
  3099     for (int i = 0; i < numColors; i++) {
       
  3100         qt_screen->set(start + i, qRed(colorTable[i]), qGreen(colorTable[i]),
       
  3101                         qBlue(colorTable[i]));
       
  3102     }
       
  3103 }
       
  3104 
       
  3105 #ifndef QT_NO_QWS_MANAGER
       
  3106 QDecoration &QApplication::qwsDecoration()
       
  3107 {
       
  3108     return *qws_decoration;
       
  3109 }
       
  3110 
       
  3111 void QApplication::qwsSetDecoration(QDecoration *dec)
       
  3112 {
       
  3113     if (dec) {
       
  3114         delete qws_decoration;
       
  3115         qws_decoration = dec;
       
  3116         QWidgetList widgets = topLevelWidgets();
       
  3117         for (int i = 0; i < widgets.size(); ++i) {
       
  3118             QWidget *w = widgets[i];
       
  3119             if (w->isVisible() && w != desktop()) {
       
  3120                 static_cast<QETWidget *>(w)->updateRegion();
       
  3121                 static_cast<QETWidget *>(w)->repaintDecoration(desktop()->rect(), false);
       
  3122                 if (w->isMaximized())
       
  3123                     w->showMaximized();
       
  3124             }
       
  3125         }
       
  3126     }
       
  3127 }
       
  3128 
       
  3129 QDecoration* QApplication::qwsSetDecoration(const QString &decoration)
       
  3130 {
       
  3131     QDecoration *decore = QDecorationFactory::create(decoration);
       
  3132     if (!decore)
       
  3133         return 0;
       
  3134 
       
  3135     qwsSetDecoration(decore);
       
  3136     return decore;
       
  3137 }
       
  3138 
       
  3139 #endif
       
  3140 
       
  3141 bool QApplicationPrivate::modalState()
       
  3142 {
       
  3143     return app_do_modal;
       
  3144 }
       
  3145 
       
  3146 void QApplicationPrivate::enterModal_sys(QWidget *widget)
       
  3147 {
       
  3148     if (!qt_modal_stack)
       
  3149         qt_modal_stack = new QWidgetList;
       
  3150     qt_modal_stack->insert(0, widget);
       
  3151     app_do_modal = true;
       
  3152 }
       
  3153 
       
  3154 void QApplicationPrivate::leaveModal_sys(QWidget *widget)
       
  3155 {
       
  3156     if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
       
  3157         if (qt_modal_stack->isEmpty()) {
       
  3158             delete qt_modal_stack;
       
  3159             qt_modal_stack = 0;
       
  3160         }
       
  3161     }
       
  3162     app_do_modal = qt_modal_stack != 0;
       
  3163 }
       
  3164 
       
  3165 static bool qt_try_modal(QWidget *widget, QWSEvent *event)
       
  3166 {
       
  3167     QWidget * top = 0;
       
  3168 
       
  3169     if (QApplicationPrivate::tryModalHelper(widget, &top))
       
  3170         return true;
       
  3171 
       
  3172     bool block_event  = false;
       
  3173     bool paint_event = false;
       
  3174 
       
  3175     switch (event->type) {
       
  3176         case QWSEvent::Focus:
       
  3177             if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
       
  3178                 break;
       
  3179             // drop through
       
  3180         case QWSEvent::Mouse:                        // disallow mouse/key events
       
  3181         case QWSEvent::Key:
       
  3182             block_event         = true;
       
  3183             break;
       
  3184     }
       
  3185 
       
  3186     if (top->parentWidget() == 0 && (block_event || paint_event))
       
  3187         top->raise();
       
  3188 
       
  3189     return !block_event;
       
  3190 }
       
  3191 
       
  3192 static int openPopupCount = 0;
       
  3193 void QApplicationPrivate::openPopup(QWidget *popup)
       
  3194 {
       
  3195     openPopupCount++;
       
  3196     if (!popupWidgets) {                        // create list
       
  3197         popupWidgets = new QWidgetList;
       
  3198 
       
  3199         /* only grab if you are the first/parent popup */
       
  3200         QPaintDevice::qwsDisplay()->grabMouse(popup,true);
       
  3201         QPaintDevice::qwsDisplay()->grabKeyboard(popup,true);
       
  3202         popupGrabOk = true;
       
  3203     }
       
  3204     popupWidgets->append(popup);                // add to end of list
       
  3205 
       
  3206     // popups are not focus-handled by the window system (the first
       
  3207     // popup grabbed the keyboard), so we have to do that manually: A
       
  3208     // new popup gets the focus
       
  3209     if (popup->focusWidget()) {
       
  3210         popup->focusWidget()->setFocus(Qt::PopupFocusReason);
       
  3211     } else if (popupWidgets->count() == 1) { // this was the first popup
       
  3212         if (QWidget *fw = QApplication::focusWidget()) {
       
  3213             QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
       
  3214             QApplication::sendEvent(fw, &e);
       
  3215         }
       
  3216     }
       
  3217 }
       
  3218 
       
  3219 void QApplicationPrivate::closePopup(QWidget *popup)
       
  3220 {
       
  3221     if (!popupWidgets)
       
  3222         return;
       
  3223 
       
  3224     popupWidgets->removeAll(popup);
       
  3225     if (popup == popupOfPopupButtonFocus) {
       
  3226         popupButtonFocus = 0;
       
  3227         popupOfPopupButtonFocus = 0;
       
  3228     }
       
  3229     if (popupWidgets->count() == 0) {                // this was the last popup
       
  3230         popupCloseDownMode = true;                // control mouse events
       
  3231         delete popupWidgets;
       
  3232         popupWidgets = 0;
       
  3233         if (popupGrabOk) {        // grabbing not disabled
       
  3234             QPaintDevice::qwsDisplay()->grabMouse(popup,false);
       
  3235             QPaintDevice::qwsDisplay()->grabKeyboard(popup,false);
       
  3236             popupGrabOk = false;
       
  3237             // XXX ungrab keyboard
       
  3238         }
       
  3239         if (active_window) {
       
  3240             if (QWidget *fw = active_window->focusWidget()) {
       
  3241                 if (fw != QApplication::focusWidget()) {
       
  3242                     fw->setFocus(Qt::PopupFocusReason);
       
  3243                 } else {
       
  3244                     QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
       
  3245                     QApplication::sendEvent(fw, &e);
       
  3246                 }
       
  3247             }
       
  3248         }
       
  3249     } else {
       
  3250         // popups are not focus-handled by the window system (the
       
  3251         // first popup grabbed the keyboard), so we have to do that
       
  3252         // manually: A popup was closed, so the previous popup gets
       
  3253         // the focus.
       
  3254         QWidget* aw = popupWidgets->last();
       
  3255         if (QWidget *fw = aw->focusWidget())
       
  3256             fw->setFocus(Qt::PopupFocusReason);
       
  3257     }
       
  3258 }
       
  3259 
       
  3260 /*****************************************************************************
       
  3261   Event translation; translates FB events to Qt events
       
  3262  *****************************************************************************/
       
  3263 
       
  3264 //
       
  3265 // Mouse event translation
       
  3266 //
       
  3267 // FB doesn't give mouse double click events, so we generate them by
       
  3268 // comparing window, time and position between two mouse press events.
       
  3269 //
       
  3270 
       
  3271 
       
  3272 // Needed for QCursor::pos
       
  3273 
       
  3274 static const int AnyButton = (Qt::LeftButton | Qt::MidButton | Qt::RightButton);
       
  3275 
       
  3276 
       
  3277 
       
  3278 //
       
  3279 // Wheel event translation
       
  3280 //
       
  3281 bool QETWidget::translateWheelEvent(const QWSMouseEvent *me)
       
  3282 {
       
  3283 #ifdef QT_NO_WHEELEVENT
       
  3284     Q_UNUSED(me);
       
  3285     return false;
       
  3286 #else
       
  3287     const QWSMouseEvent::SimpleData &mouse = me->simpleData;
       
  3288 
       
  3289     // Figure out wheeling direction:
       
  3290     //    Horizontal wheel w/o Alt
       
  3291     // OR Vertical wheel   w/  Alt  ==> Horizontal wheeling
       
  3292     //    ..all other permutations  ==> Vertical wheeling
       
  3293     int axis = mouse.delta / 120; // WHEEL_DELTA?
       
  3294     Qt::Orientation orient = ((axis == 2 || axis == -2) && ((mouse.state & Qt::AltModifier) == 0))
       
  3295                              ||((axis == 1 || axis == -1) && mouse.state & Qt::AltModifier)
       
  3296                              ? Qt::Horizontal : Qt::Vertical;
       
  3297 
       
  3298     QPoint mousePoint = QPoint(mouse.x_root, mouse.y_root);
       
  3299 
       
  3300     // send the event to the widget or its ancestors
       
  3301     QWidget* popup = qApp->activePopupWidget();
       
  3302     if (popup && window() != popup)
       
  3303         popup->close();
       
  3304     QWheelEvent we(mapFromGlobal(mousePoint), mousePoint, mouse.delta,
       
  3305                    Qt::MouseButtons(mouse.state & Qt::MouseButtonMask),
       
  3306                    Qt::KeyboardModifiers(mouse.state & Qt::KeyboardModifierMask), orient);
       
  3307     if (QApplication::sendSpontaneousEvent(this, &we))
       
  3308         return true;
       
  3309 
       
  3310     // send the event to the widget that has the focus or its ancestors, if different
       
  3311     QWidget *w = this;
       
  3312     if (w != qApp->focusWidget() && (w = qApp->focusWidget())) {
       
  3313         QWidget* popup = qApp->activePopupWidget();
       
  3314         if (popup && w != popup)
       
  3315             popup->hide();
       
  3316         if (QApplication::sendSpontaneousEvent(w, &we))
       
  3317             return true;
       
  3318     }
       
  3319     return false;
       
  3320 #endif
       
  3321 }
       
  3322 
       
  3323 bool QETWidget::translateMouseEvent(const QWSMouseEvent *event, int prevstate)
       
  3324 {
       
  3325     static bool manualGrab = false;
       
  3326     QPoint pos;
       
  3327     QPoint globalPos;
       
  3328     int button = 0;
       
  3329 
       
  3330     if (sm_blockUserInput) // block user interaction during session management
       
  3331         return true;
       
  3332     const QWSMouseEvent::SimpleData &mouse = event->simpleData;
       
  3333     pos = mapFromGlobal(QPoint(mouse.x_root, mouse.y_root));
       
  3334 //     if (qt_last_x) {
       
  3335 //         *qt_last_x=mouse.x_root;
       
  3336 //         *qt_last_y=mouse.y_root;
       
  3337 //     }
       
  3338     globalPos.rx() = mouse.x_root;
       
  3339     globalPos.ry() = mouse.y_root;
       
  3340 
       
  3341     QEvent::Type type = QEvent::None;
       
  3342 
       
  3343     Qt::MouseButtons buttonstate = Qt::MouseButtons(mouse.state & Qt::MouseButtonMask);
       
  3344     Qt::KeyboardModifiers keystate = Qt::KeyboardModifiers(mouse.state & Qt::KeyboardModifierMask);
       
  3345 
       
  3346     if (mouse.state == prevstate) {
       
  3347         // mouse move
       
  3348         type = QEvent::MouseMove;
       
  3349     } else if ((mouse.state&AnyButton) != (prevstate&AnyButton)) {
       
  3350         Qt::MouseButtons current_buttons = Qt::MouseButtons(prevstate&Qt::MouseButtonMask);
       
  3351         for (button = Qt::LeftButton; !type && button <= Qt::MidButton; button<<=1) {
       
  3352             if ((mouse.state&button) != (current_buttons&button)) {
       
  3353                 // button press or release
       
  3354                 current_buttons = Qt::MouseButtons(current_buttons ^ button);
       
  3355 
       
  3356 #ifndef QT_NO_QWS_INPUTMETHODS
       
  3357                 //############ We used to do a QInputContext::reset(oldFocus);
       
  3358                 // when we changed the focus widget. See change 93389 for where the
       
  3359                 // focus code went. The IM code was (after testing for ClickToFocus):
       
  3360                 //if (mouse.state&button && w != QInputContext::microFocusWidget()) //button press
       
  3361                 //        QInputContext::reset(oldFocus);
       
  3362 
       
  3363 #endif
       
  3364                 if (mouse.state&button) { //button press
       
  3365                     qt_button_down = childAt(pos);
       
  3366                     if (!qt_button_down)
       
  3367                         qt_button_down = this;
       
  3368                     if (/*XXX mouseActWindow == this &&*/
       
  3369                         mouseButtonPressed == button &&
       
  3370                         long(mouse.time) -long(mouseButtonPressTime)
       
  3371                             < QApplication::doubleClickInterval() &&
       
  3372                         qAbs(mouse.x_root - mouseXPos) < mouse_double_click_distance &&
       
  3373                         qAbs(mouse.y_root - mouseYPos) < mouse_double_click_distance ) {
       
  3374                         type = QEvent::MouseButtonDblClick;
       
  3375                         mouseButtonPressTime -= 2000;        // no double-click next time
       
  3376                     } else {
       
  3377                         type = QEvent::MouseButtonPress;
       
  3378                         mouseButtonPressTime = mouse.time;
       
  3379                     }
       
  3380                     mouseButtonPressed = button;        // save event params for
       
  3381                     mouseXPos = globalPos.x();                // future double click tests
       
  3382                     mouseYPos = globalPos.y();
       
  3383                 } else {                                // mouse button released
       
  3384                     if (manualGrab) {                        // release manual grab
       
  3385                         manualGrab = false;
       
  3386                         // XXX XUngrabPointer(x11Display(), CurrentTime);
       
  3387                     }
       
  3388 
       
  3389                     type = QEvent::MouseButtonRelease;
       
  3390                 }
       
  3391             }
       
  3392         }
       
  3393         button >>= 1;
       
  3394     }
       
  3395     //XXX mouseActWindow = winId();                        // save some event params
       
  3396 
       
  3397     if (type == 0) {                                // event consumed
       
  3398         return false; //EXIT in the normal case
       
  3399     }
       
  3400 
       
  3401     if (qApp->d_func()->inPopupMode()) {                        // in popup mode
       
  3402         QWidget *popup = qApp->activePopupWidget();
       
  3403         // in X11, this would be the window we are over.
       
  3404         // in QWS this is the top level popup.  to allow mouse
       
  3405         // events to other widgets, need to go through qApp->QApplicationPrivate::popupWidgets.
       
  3406         QSize s(qt_screen->width(), qt_screen->height());
       
  3407         for (int i = 0; i < QApplicationPrivate::popupWidgets->size(); ++i) {
       
  3408             QWidget *w = QApplicationPrivate::popupWidgets->at(i);
       
  3409 
       
  3410             if ((w->windowType() == Qt::Popup) && w->d_func()->localAllocatedRegion().contains(globalPos - w->geometry().topLeft()))
       
  3411             {
       
  3412                 popup = w;
       
  3413                 break;
       
  3414             }
       
  3415         }
       
  3416         pos = popup->mapFromGlobal(globalPos);
       
  3417         bool releaseAfter = false;
       
  3418         QWidget *popupChild  = popup->childAt(pos);
       
  3419         QWidget *popupTarget = popupChild ? popupChild : popup;
       
  3420 
       
  3421         if (popup != popupOfPopupButtonFocus){
       
  3422             popupButtonFocus = 0;
       
  3423             popupOfPopupButtonFocus = 0;
       
  3424         }
       
  3425 
       
  3426         if (!popupTarget->isEnabled()) {
       
  3427             return false; //EXIT special case
       
  3428         }
       
  3429 
       
  3430         switch (type) {
       
  3431             case QEvent::MouseButtonPress:
       
  3432             case QEvent::MouseButtonDblClick:
       
  3433                 popupButtonFocus = popupChild;
       
  3434                 popupOfPopupButtonFocus = popup;
       
  3435                 break;
       
  3436             case QEvent::MouseButtonRelease:
       
  3437                 releaseAfter = true;
       
  3438                 break;
       
  3439             default:
       
  3440                 break;                                // nothing for mouse move
       
  3441         }
       
  3442 
       
  3443         int oldOpenPopupCount = openPopupCount;
       
  3444 
       
  3445         if (popupButtonFocus) {
       
  3446             QMouseEvent e(type, popupButtonFocus->mapFromGlobal(globalPos),
       
  3447                         globalPos, Qt::MouseButton(button), buttonstate, keystate);
       
  3448             QApplication::sendSpontaneousEvent(popupButtonFocus, & e);
       
  3449             if (releaseAfter) {
       
  3450                 popupButtonFocus = 0;
       
  3451                 popupOfPopupButtonFocus = 0;
       
  3452             }
       
  3453         } else if (popupChild) {
       
  3454             QMouseEvent e(type, popupChild->mapFromGlobal(globalPos),
       
  3455                         globalPos, Qt::MouseButton(button), buttonstate, keystate);
       
  3456             QApplication::sendSpontaneousEvent(popupChild, & e);
       
  3457         } else {
       
  3458             QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), buttonstate, keystate);
       
  3459             QApplication::sendSpontaneousEvent(popupChild ? popupChild : popup, & e);
       
  3460         }
       
  3461 #ifndef QT_NO_CONTEXTMENU
       
  3462         if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
       
  3463             QWidget *popupEvent = popup;
       
  3464             if(popupButtonFocus)
       
  3465                 popupEvent = popupButtonFocus;
       
  3466             else if(popupChild)
       
  3467                 popupEvent = popupChild;
       
  3468             QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, keystate);
       
  3469             QApplication::sendSpontaneousEvent(popupEvent, &e);
       
  3470         }
       
  3471 #endif // QT_NO_CONTEXTMENU
       
  3472 
       
  3473         if (releaseAfter)
       
  3474             qt_button_down = 0;
       
  3475 
       
  3476     } else { //qApp not in popup mode
       
  3477         QWidget *widget = this;
       
  3478         QWidget *w = QWidget::mouseGrabber();
       
  3479         if (!w && qt_button_down)
       
  3480             w = qt_button_down;
       
  3481         if (w && w != this) {
       
  3482             widget = w;
       
  3483             pos = mapToGlobal(pos);
       
  3484             pos = w->mapFromGlobal(pos);
       
  3485         }
       
  3486 
       
  3487         if (popupCloseDownMode) {
       
  3488             popupCloseDownMode = false;
       
  3489             if ((windowType() == Qt::Popup))        // ignore replayed event
       
  3490                 return true; //EXIT
       
  3491         }
       
  3492 
       
  3493         QPointer<QWidget> leaveAfterRelease = 0;
       
  3494         if (type == QEvent::MouseButtonRelease &&
       
  3495             (mouse.state & (~button) & (Qt::LeftButton |
       
  3496                                     Qt::MidButton |
       
  3497                                     Qt::RightButton)) == 0) {
       
  3498             // Button released outside the widget -> leave the widget after the
       
  3499             // release event has been delivered.
       
  3500             if (widget == qt_button_down && (pos.x() < 0 || pos.y() < 0))
       
  3501                 leaveAfterRelease = qt_button_down;
       
  3502             qt_button_down = 0;
       
  3503         }
       
  3504 
       
  3505         int oldOpenPopupCount = openPopupCount;
       
  3506 
       
  3507         QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), buttonstate, keystate);
       
  3508 #ifndef QT_NO_QWS_MANAGER
       
  3509         if (widget->isWindow() && widget->d_func()->topData()->qwsManager
       
  3510             && (widget->d_func()->topData()->qwsManager->region().contains(globalPos)
       
  3511                 || QWSManager::grabbedMouse() )) {
       
  3512             if ((*mouseInWidget)) {
       
  3513                 QApplicationPrivate::dispatchEnterLeave(0, *mouseInWidget);
       
  3514                 (*mouseInWidget) = 0;
       
  3515             }
       
  3516             QApplication::sendSpontaneousEvent(widget->d_func()->topData()->qwsManager, &e);
       
  3517             qApp->d_func()->last_manager = widget->d_func()->topData()->qwsManager;
       
  3518         } else
       
  3519 #endif
       
  3520         {
       
  3521             if (widget != (*mouseInWidget)) {
       
  3522                 QApplicationPrivate::dispatchEnterLeave(widget, *mouseInWidget);
       
  3523                 (*mouseInWidget) = widget;
       
  3524                 qt_last_mouse_receiver = widget;
       
  3525             }
       
  3526             QApplication::sendSpontaneousEvent(widget, &e);
       
  3527             if (leaveAfterRelease && !QWidget::mouseGrabber()) {
       
  3528                 *mouseInWidget = QApplication::widgetAt(globalPos);
       
  3529                 qt_last_mouse_receiver = *mouseInWidget;
       
  3530                 QApplicationPrivate::dispatchEnterLeave(*mouseInWidget, leaveAfterRelease);
       
  3531                 leaveAfterRelease = 0;
       
  3532             }
       
  3533         }
       
  3534 #ifndef QT_NO_CONTEXTMENU
       
  3535         if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
       
  3536             QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, keystate);
       
  3537             QApplication::sendSpontaneousEvent(widget, &e);
       
  3538         }
       
  3539 #endif // QT_NO_CONTEXTMENU
       
  3540     }
       
  3541     return true;
       
  3542 }
       
  3543 
       
  3544 
       
  3545 bool QETWidget::translateKeyEvent(const QWSKeyEvent *event, bool grab) /* grab is used in the #ifdef */
       
  3546 {
       
  3547     int code = -1;
       
  3548     //### Qt assumes keyboard state is state *before*, while QWS uses state after the event
       
  3549     static Qt::KeyboardModifiers oldstate;
       
  3550     Qt::KeyboardModifiers state = oldstate;
       
  3551     oldstate = event->simpleData.modifiers;
       
  3552 
       
  3553     if (sm_blockUserInput) // block user interaction during session management
       
  3554         return true;
       
  3555 
       
  3556     if (!isEnabled())
       
  3557         return true;
       
  3558 
       
  3559     QEvent::Type type = event->simpleData.is_press ?
       
  3560                         QEvent::KeyPress : QEvent::KeyRelease;
       
  3561     bool autor = event->simpleData.is_auto_repeat;
       
  3562     QString text;
       
  3563     char ascii = 0;
       
  3564     if (event->simpleData.unicode) {
       
  3565         QChar ch(event->simpleData.unicode);
       
  3566         if (ch.unicode() != 0xffff)
       
  3567             text += ch;
       
  3568         ascii = ch.toLatin1();
       
  3569     }
       
  3570     code = event->simpleData.keycode;
       
  3571 
       
  3572 #if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
       
  3573     if (type == QEvent::KeyPress && !grab
       
  3574         && static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->use_compat()) {
       
  3575         // send accel events if the keyboard is not grabbed
       
  3576         QKeyEvent a(type, code, state, text, autor, int(text.length()));
       
  3577         if (static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->qt_tryAccelEvent(this, &a))
       
  3578             return true;
       
  3579     }
       
  3580 #else
       
  3581     Q_UNUSED(grab);
       
  3582 #endif
       
  3583     if (!text.isEmpty() && testAttribute(Qt::WA_KeyCompression)) {
       
  3584         // the widget wants key compression so it gets it
       
  3585 
       
  3586         // XXX not implemented
       
  3587     }
       
  3588 
       
  3589     QKeyEvent e(type, code, state, text, autor, int(text.length()));
       
  3590     return QApplication::sendSpontaneousEvent(this, &e);
       
  3591 }
       
  3592 
       
  3593 bool QETWidget::translateRegionEvent(const QWSRegionEvent *event)
       
  3594 {
       
  3595     QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(windowSurface());
       
  3596     Q_ASSERT(surface);
       
  3597 
       
  3598     QRegion region;
       
  3599     region.setRects(event->rectangles, event->simpleData.nrectangles);
       
  3600 
       
  3601     switch (event->simpleData.type) {
       
  3602     case QWSRegionEvent::Allocation:
       
  3603         region.translate(-mapToGlobal(QPoint()));
       
  3604         surface->setClipRegion(region);
       
  3605         break;
       
  3606 #ifdef QT_QWS_CLIENTBLIT
       
  3607     case QWSRegionEvent::DirectPaint:
       
  3608         surface->setDirectRegion(region, event->simpleData.id);
       
  3609         break;
       
  3610 #endif
       
  3611     default:
       
  3612         break;
       
  3613     }
       
  3614 
       
  3615     return true;
       
  3616 }
       
  3617 
       
  3618 #ifndef QT_NO_QWSEMBEDWIDGET
       
  3619 void QETWidget::translateEmbedEvent(const QWSEmbedEvent *event)
       
  3620 {
       
  3621     if (event->simpleData.type | QWSEmbedEvent::Region) {
       
  3622         const QRegion region = event->region;
       
  3623         setGeometry(region.boundingRect());
       
  3624         setVisible(!region.isEmpty());
       
  3625     }
       
  3626 }
       
  3627 #endif // QT_NO_QWSEMBEDWIDGET
       
  3628 
       
  3629 void QETWidget::repaintDecoration(QRegion r, bool post)
       
  3630 {
       
  3631     Q_UNUSED(post);
       
  3632 #ifdef QT_NO_QWS_MANAGER
       
  3633     Q_UNUSED(r);
       
  3634 #else
       
  3635     //please note that qwsManager is a QObject, not a QWidget.
       
  3636     //therefore, normal ways of painting do not work.
       
  3637     // However, it does listen to paint events.
       
  3638 
       
  3639     Q_D(QWidget);
       
  3640     if (isWindow() && d->topData()->qwsManager && isVisible()) {
       
  3641         QWSManager *manager = d->topData()->qwsManager;
       
  3642         r &= manager->region();
       
  3643         if (!r.isEmpty())
       
  3644             manager->repaintRegion(QDecoration::All, QDecoration::Normal);
       
  3645     }
       
  3646 #endif
       
  3647 }
       
  3648 
       
  3649 void QETWidget::updateRegion()
       
  3650 {
       
  3651     Q_D(QWidget);
       
  3652 
       
  3653     QTLWExtra *topextra = d->maybeTopData();
       
  3654     if (!topextra)
       
  3655         return;
       
  3656 
       
  3657     QRegion myregion = d->localRequestedRegion();
       
  3658     myregion.translate(geometry().topLeft());
       
  3659 
       
  3660 #ifndef QT_NO_QWS_MANAGER
       
  3661     QWSManager *manager = topextra->qwsManager;
       
  3662     if (manager)
       
  3663         myregion += manager->region();
       
  3664 #endif
       
  3665 
       
  3666     QRect br(myregion.boundingRect());
       
  3667     topextra->frameStrut.setCoords(d->data.crect.x() - br.x(),
       
  3668                                    d->data.crect.y() - br.y(),
       
  3669                                    br.right() - d->data.crect.right(),
       
  3670                                    br.bottom() - d->data.crect.bottom());
       
  3671 }
       
  3672 
       
  3673 void  QApplication::setCursorFlashTime(int msecs)
       
  3674 {
       
  3675     QApplicationPrivate::cursor_flash_time = msecs;
       
  3676 }
       
  3677 
       
  3678 
       
  3679 int QApplication::cursorFlashTime()
       
  3680 {
       
  3681     return QApplicationPrivate::cursor_flash_time;
       
  3682 }
       
  3683 
       
  3684 void QApplication::setDoubleClickInterval(int ms)
       
  3685 {
       
  3686     QApplicationPrivate::mouse_double_click_time = ms;
       
  3687 }
       
  3688 
       
  3689 int QApplication::doubleClickInterval()
       
  3690 {
       
  3691     return QApplicationPrivate::mouse_double_click_time;
       
  3692 }
       
  3693 
       
  3694 void QApplication::setKeyboardInputInterval(int ms)
       
  3695 {
       
  3696     QApplicationPrivate::keyboard_input_time = ms;
       
  3697 }
       
  3698 
       
  3699 int QApplication::keyboardInputInterval()
       
  3700 {
       
  3701     return QApplicationPrivate::keyboard_input_time;
       
  3702 }
       
  3703 
       
  3704 #ifndef QT_NO_WHEELEVENT
       
  3705 void QApplication::setWheelScrollLines(int lines)
       
  3706 {
       
  3707     QApplicationPrivate::wheel_scroll_lines = lines;
       
  3708 }
       
  3709 
       
  3710 int QApplication::wheelScrollLines()
       
  3711 {
       
  3712     return QApplicationPrivate::wheel_scroll_lines;
       
  3713 }
       
  3714 #endif
       
  3715 
       
  3716 void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
       
  3717 {
       
  3718     switch (effect) {
       
  3719     case Qt::UI_AnimateMenu:
       
  3720         QApplicationPrivate::animate_menu = enable;
       
  3721         break;
       
  3722     case Qt::UI_FadeMenu:
       
  3723         if (enable)
       
  3724             QApplicationPrivate::animate_menu = true;
       
  3725         QApplicationPrivate::fade_menu = enable;
       
  3726         break;
       
  3727     case Qt::UI_AnimateCombo:
       
  3728         QApplicationPrivate::animate_combo = enable;
       
  3729         break;
       
  3730     case Qt::UI_AnimateTooltip:
       
  3731         QApplicationPrivate::animate_tooltip = enable;
       
  3732         break;
       
  3733     case Qt::UI_FadeTooltip:
       
  3734         if (enable)
       
  3735             QApplicationPrivate::animate_tooltip = true;
       
  3736         QApplicationPrivate::fade_tooltip = enable;
       
  3737         break;
       
  3738     case Qt::UI_AnimateToolBox:
       
  3739         QApplicationPrivate::animate_toolbox = enable;
       
  3740         break;
       
  3741     default:
       
  3742         QApplicationPrivate::animate_ui = enable;
       
  3743         break;
       
  3744     }
       
  3745 }
       
  3746 
       
  3747 bool QApplication::isEffectEnabled(Qt::UIEffect effect)
       
  3748 {
       
  3749     if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
       
  3750         return false;
       
  3751 
       
  3752     switch(effect) {
       
  3753     case Qt::UI_AnimateMenu:
       
  3754         return QApplicationPrivate::animate_menu;
       
  3755     case Qt::UI_FadeMenu:
       
  3756         return QApplicationPrivate::fade_menu;
       
  3757     case Qt::UI_AnimateCombo:
       
  3758         return QApplicationPrivate::animate_combo;
       
  3759     case Qt::UI_AnimateTooltip:
       
  3760         return QApplicationPrivate::animate_tooltip;
       
  3761     case Qt::UI_FadeTooltip:
       
  3762         return QApplicationPrivate::fade_tooltip;
       
  3763     case Qt::UI_AnimateToolBox:
       
  3764         return QApplicationPrivate::animate_toolbox;
       
  3765     default:
       
  3766         return QApplicationPrivate::animate_ui;
       
  3767     }
       
  3768 }
       
  3769 
       
  3770 void QApplication::setArgs(int c, char **v)
       
  3771 {
       
  3772     Q_D(QApplication);
       
  3773     d->argc = c;
       
  3774     d->argv = v;
       
  3775 }
       
  3776 
       
  3777 void QApplicationPrivate::initializeMultitouch_sys()
       
  3778 { }
       
  3779 void QApplicationPrivate::cleanupMultitouch_sys()
       
  3780 { }
       
  3781 
       
  3782 /* \internal
       
  3783    This is used to clean up the qws server
       
  3784    in case the QApplication constructor threw an exception
       
  3785 */
       
  3786 QWSServerCleaner::~QWSServerCleaner()
       
  3787 {
       
  3788     if (qwsServer && qws_single_process)
       
  3789         QWSServer::closedown();
       
  3790 }
       
  3791 
       
  3792 QT_END_NAMESPACE