src/gui/embedded/qwindowsystem_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 "qplatformdefs.h"
       
    43 
       
    44 #include "qwindowsystem_qws.h"
       
    45 #include "qwsevent_qws.h"
       
    46 #include "qwscommand_qws_p.h"
       
    47 #include "qtransportauth_qws_p.h"
       
    48 #include "qwsutils_qws.h"
       
    49 #include "qwscursor_qws.h"
       
    50 #include "qwsdisplay_qws.h"
       
    51 #include "qmouse_qws.h"
       
    52 #include "qcopchannel_qws.h"
       
    53 #include "qwssocket_qws.h"
       
    54 
       
    55 #include "qapplication.h"
       
    56 #include "private/qapplication_p.h"
       
    57 #include "qsocketnotifier.h"
       
    58 #include "qpolygon.h"
       
    59 #include "qimage.h"
       
    60 #include "qcursor.h"
       
    61 #include <private/qpaintengine_raster_p.h>
       
    62 #include "qscreen_qws.h"
       
    63 #include "qwindowdefs.h"
       
    64 #include "private/qlock_p.h"
       
    65 #include "qwslock_p.h"
       
    66 #include "qfile.h"
       
    67 #include "qtimer.h"
       
    68 #include "qpen.h"
       
    69 #include "qdesktopwidget.h"
       
    70 #include "qevent.h"
       
    71 #include "qinputcontext.h"
       
    72 #include "qpainter.h"
       
    73 
       
    74 #include <qdebug.h>
       
    75 
       
    76 #include "qkbddriverfactory_qws.h"
       
    77 #include "qmousedriverfactory_qws.h"
       
    78 
       
    79 #include <qbuffer.h>
       
    80 #include <qdir.h>
       
    81 
       
    82 #include <private/qwindowsurface_qws_p.h>
       
    83 #include <private/qfontengine_qpf_p.h>
       
    84 
       
    85 #include "qwindowsystem_p.h"
       
    86 
       
    87 
       
    88 #include <stdlib.h>
       
    89 #include <stdio.h>
       
    90 #include <errno.h>
       
    91 
       
    92 #ifndef QT_NO_QWS_MULTIPROCESS
       
    93 #include <sys/param.h>
       
    94 #include <sys/mount.h>
       
    95 #endif
       
    96 
       
    97 #if !defined(QT_NO_SOUND) && !defined(Q_OS_DARWIN)
       
    98 #ifdef QT_USE_OLD_QWS_SOUND
       
    99 #include <sys/types.h>
       
   100 #include <sys/stat.h>
       
   101 #include <sys/ioctl.h>
       
   102 #include <sys/soundcard.h>
       
   103 #else
       
   104 #include "qsoundqss_qws.h"
       
   105 #endif
       
   106 #endif
       
   107 
       
   108 //#define QWS_DEBUG_FONTCLEANUP
       
   109 
       
   110 QT_BEGIN_NAMESPACE
       
   111 
       
   112 QWSServer Q_GUI_EXPORT *qwsServer=0;
       
   113 static QWSServerPrivate *qwsServerPrivate=0;
       
   114 
       
   115 #define MOUSE 0
       
   116 #define KEY 1
       
   117 //#define EVENT_BLOCK_DEBUG
       
   118 
       
   119 QWSScreenSaver::~QWSScreenSaver()
       
   120 {
       
   121 }
       
   122 
       
   123 extern QByteArray qws_display_spec;
       
   124 extern void qt_init_display(); //qapplication_qws.cpp
       
   125 extern QString qws_qtePipeFilename();
       
   126 
       
   127 extern void qt_client_enqueue(const QWSEvent *); //qapplication_qws.cpp
       
   128 extern QList<QWSCommand*> *qt_get_server_queue();
       
   129 
       
   130 Q_GLOBAL_STATIC_WITH_ARGS(QString, defaultMouse, (QLatin1String("Auto")))
       
   131 Q_GLOBAL_STATIC_WITH_ARGS(QString, defaultKeyboard, (QLatin1String("TTY")))
       
   132 static const int FontCleanupInterval = 60 * 1000;
       
   133 
       
   134 static int qws_keyModifiers = 0;
       
   135 
       
   136 static QWSWindow *keyboardGrabber;
       
   137 static bool keyboardGrabbing;
       
   138 
       
   139 static int get_object_id(int count = 1)
       
   140 {
       
   141     static int next=1000;
       
   142     int n = next;
       
   143     next += count;
       
   144     return n;
       
   145 }
       
   146 #ifndef QT_NO_QWS_INPUTMETHODS
       
   147 static QWSInputMethod *current_IM = 0;
       
   148 
       
   149 static QWSWindow *current_IM_composing_win = 0;
       
   150 static int current_IM_winId = -1;
       
   151 static bool force_reject_strokeIM = false;
       
   152 #endif
       
   153 
       
   154 static void cleanupFontsDir();
       
   155 
       
   156 //#define QWS_REGION_DEBUG
       
   157 
       
   158 /*!
       
   159     \class QWSScreenSaver
       
   160     \ingroup qws
       
   161 
       
   162     \brief The QWSScreenSaver class is a base class for screensavers
       
   163     in Qt for Embedded Linux.
       
   164 
       
   165     When running \l{Qt for Embedded Linux} applications, it is the server
       
   166     application that installs and controls the screensaver.
       
   167     \l{Qt for Embedded Linux} supports multilevel screen saving; i.e., it is possible to
       
   168     specify several different levels of screen responsiveness. For
       
   169     example, you can choose to first turn off the light before you
       
   170     fully activate the screensaver.
       
   171 
       
   172     Note that there exists no default screensaver implementation.
       
   173 
       
   174     To create a custom screensaver, derive from this class and
       
   175     reimplement the restore() and save() functions. These functions
       
   176     are called whenever the screensaver is activated or deactivated,
       
   177     respectively. Once an instance of your custom screensaver is
       
   178     created, you can use the QWSServer::setScreenSaver() function to
       
   179     install it.
       
   180 
       
   181     \sa QWSServer, QScreen, {Qt for Embedded Linux}
       
   182 */
       
   183 
       
   184 /*!
       
   185     \fn QWSScreenSaver::~QWSScreenSaver()
       
   186 
       
   187     Reimplement this function to destroy the screensaver.
       
   188 */
       
   189 
       
   190 /*!
       
   191     \fn QWSScreenSaver::restore()
       
   192 
       
   193     Implement this function to deactivate the screensaver, restoring
       
   194     the previously saved screen.
       
   195 
       
   196     \sa save(), QWSServer::screenSaverActivate()
       
   197 */
       
   198 
       
   199 /*!
       
   200     \fn QWSScreenSaver::save(int level)
       
   201 
       
   202     Implement this function to activate the screensaver, saving the
       
   203     current screen.
       
   204 
       
   205     \l{Qt for Embedded Linux} supports multilevel screen saving; i.e., it is
       
   206     possible to specify several different levels of screen
       
   207     responsiveness. For example, you can choose to first turn off the
       
   208     light before you fully activate the screensaver. Use the
       
   209     QWSServer::setScreenSaverIntervals() to specify the time intervals
       
   210     between the different levels.
       
   211 
       
   212     This function should return true if the screensaver successfully
       
   213     enters the given \a level; otherwise it should return false.
       
   214 
       
   215     \sa restore(), QWSServer::screenSaverActivate()
       
   216 */
       
   217 
       
   218 class QWSWindowPrivate
       
   219 {
       
   220 public:
       
   221     QWSWindowPrivate();
       
   222 
       
   223 #ifdef QT_QWS_CLIENTBLIT
       
   224     QRegion directPaintRegion;
       
   225 #endif
       
   226     QRegion allocatedRegion;
       
   227 #ifndef QT_NO_QWSEMBEDWIDGET
       
   228     QList<QWSWindow*> embedded;
       
   229     QWSWindow *embedder;
       
   230 #endif
       
   231     QWSWindow::State state;
       
   232     Qt::WindowFlags windowFlags;
       
   233     QRegion dirtyOnScreen;
       
   234     bool painted;
       
   235 };
       
   236 
       
   237 QWSWindowPrivate::QWSWindowPrivate()
       
   238     :
       
   239 #ifndef QT_NO_QWSEMBEDWIDGET
       
   240     embedder(0), state(QWSWindow::NoState),
       
   241 #endif
       
   242     painted(false)
       
   243 {
       
   244 }
       
   245 
       
   246 /*!
       
   247     \class QWSWindow
       
   248     \ingroup qws
       
   249 
       
   250     \brief The QWSWindow class encapsulates a top-level window in
       
   251     Qt for Embedded Linux.
       
   252 
       
   253     When you run a \l{Qt for Embedded Linux} application, it either runs as a
       
   254     server or connects to an existing server. As applications add and
       
   255     remove windows, the server process maintains information about
       
   256     each window. In \l{Qt for Embedded Linux}, top-level windows are
       
   257     encapsulated as QWSWindow objects. Note that you should never
       
   258     construct the QWSWindow class yourself; the current top-level
       
   259     windows can be retrieved using the QWSServer::clientWindows()
       
   260     function.
       
   261 
       
   262     With a window at hand, you can retrieve its caption, name, opacity
       
   263     and ID using the caption(), name(), opacity() and winId()
       
   264     functions, respectively. Use the client() function to retrieve a
       
   265     pointer to the client that owns the window.
       
   266 
       
   267     Use the isVisible() function to find out if the window is
       
   268     visible. You can find out if the window is completely obscured by
       
   269     another window or by the bounds of the screen, using the
       
   270     isFullyObscured() function. The isOpaque() function returns true
       
   271     if the window has an alpha channel equal to 255. Finally, the
       
   272     requestedRegion() function returns the region of the display the
       
   273     window wants to draw on.
       
   274 
       
   275     \sa QWSServer, QWSClient, {Qt for Embedded Linux Architecture}
       
   276 */
       
   277 
       
   278 /*!
       
   279     \fn int QWSWindow::winId() const
       
   280 
       
   281     Returns the window's ID.
       
   282 
       
   283     \sa name(), caption()
       
   284 */
       
   285 
       
   286 /*!
       
   287     \fn const QString &QWSWindow::name() const
       
   288 
       
   289     Returns the window's name, which is taken from the \l {QWidget::}{objectName()}
       
   290     at the time of \l {QWidget::}{show()}.
       
   291 
       
   292     \sa caption(), winId()
       
   293 */
       
   294 
       
   295 /*!
       
   296     \fn const QString &QWSWindow::caption() const
       
   297 
       
   298     Returns the window's caption.
       
   299 
       
   300     \sa name(), winId()
       
   301 */
       
   302 
       
   303 /*!
       
   304     \fn QWSClient* QWSWindow::client() const
       
   305 
       
   306     Returns a reference to the QWSClient object that owns this window.
       
   307 
       
   308     \sa requestedRegion()
       
   309 */
       
   310 
       
   311 /*!
       
   312     \fn QRegion QWSWindow::requestedRegion() const
       
   313 
       
   314     Returns the region that the window has requested to draw onto,
       
   315     including any window decorations.
       
   316 
       
   317     \sa client()
       
   318 */
       
   319 
       
   320 /*!
       
   321     \fn bool QWSWindow::isVisible() const
       
   322 
       
   323     Returns true if the window is visible; otherwise returns false.
       
   324 
       
   325     \sa isFullyObscured()
       
   326 */
       
   327 
       
   328 /*!
       
   329     \fn bool QWSWindow::isOpaque() const
       
   330 
       
   331     Returns true if the window is opaque, i.e., if its alpha channel
       
   332     equals 255; otherwise returns false.
       
   333 
       
   334     \sa opacity()
       
   335 */
       
   336 
       
   337 /*!
       
   338     \fn uint QWSWindow::opacity () const
       
   339 
       
   340     Returns the window's alpha channel value.
       
   341 
       
   342     \sa isOpaque()
       
   343 */
       
   344 
       
   345 /*!
       
   346     \fn bool QWSWindow::isPartiallyObscured() const
       
   347     \internal
       
   348 
       
   349     Returns true if the window is partially obsured by another window
       
   350     or by the bounds of the screen; otherwise returns false.
       
   351 */
       
   352 
       
   353 /*!
       
   354     \fn bool QWSWindow::isFullyObscured() const
       
   355 
       
   356     Returns true if the window is completely obsured by another window
       
   357     or by the bounds of the screen; otherwise returns false.
       
   358 
       
   359     \sa isVisible()
       
   360 */
       
   361 
       
   362 /*!
       
   363     \fn QWSWindowSurface* QWSWindow::windowSurface() const
       
   364     \internal
       
   365 */
       
   366 
       
   367 QWSWindow::QWSWindow(int i, QWSClient* client)
       
   368         : id(i), modified(false),
       
   369           onTop(false), c(client), last_focus_time(0), _opacity(255),
       
   370           opaque(true), d(new QWSWindowPrivate)
       
   371 {
       
   372     surface = 0;
       
   373 }
       
   374 
       
   375 
       
   376 /*!
       
   377     \enum QWSWindow::State
       
   378 
       
   379     This enum describes the state of a window. Most of the
       
   380     transitional states are set just before a call to
       
   381     QScreen::exposeRegion() and reset immediately afterwards.
       
   382 
       
   383     \value NoState Initial state before the window is properly initialized.
       
   384     \value Hidden The window is not visible.
       
   385     \value Showing The window is being shown.
       
   386     \value Visible The window is visible, and not in a transition.
       
   387     \value Hiding The window is being hidden.
       
   388     \value Raising The windoe is being raised.
       
   389     \value Lowering The window is being raised.
       
   390     \value Moving The window is being moved.
       
   391     \value ChangingGeometry The window's geometry is being changed.
       
   392     \value Destroyed  The window is destroyed.
       
   393 
       
   394     \sa state(), QScreen::exposeRegion()
       
   395 */
       
   396 
       
   397 /*!
       
   398   Returns the current state of the window.
       
   399 
       
   400   \since 4.3
       
   401 */
       
   402 QWSWindow::State QWSWindow::state() const
       
   403 {
       
   404     return d->state;
       
   405 }
       
   406 
       
   407 /*!
       
   408   Returns the window flags of the window. This value is only available
       
   409   after the first paint event.
       
   410 
       
   411   \since 4.3
       
   412 */
       
   413 Qt::WindowFlags QWSWindow::windowFlags() const
       
   414 {
       
   415     return d->windowFlags;
       
   416 }
       
   417 
       
   418 /*!
       
   419   Returns the region that has been repainted since the previous
       
   420   QScreen::exposeRegion(), and needs to be copied to the screen.
       
   421   \since 4.3
       
   422 */
       
   423 QRegion QWSWindow::dirtyOnScreen() const
       
   424 {
       
   425     return d->dirtyOnScreen;
       
   426 }
       
   427 
       
   428 void QWSWindow::createSurface(const QString &key, const QByteArray &data)
       
   429 {
       
   430 #ifndef QT_NO_QWS_MULTIPROCESS
       
   431     if (surface && !surface->isBuffered())
       
   432         c->removeUnbufferedSurface();
       
   433 #endif
       
   434 
       
   435     delete surface;
       
   436     surface = qt_screen->createSurface(key);
       
   437     surface->setPermanentState(data);
       
   438 
       
   439 #ifndef QT_NO_QWS_MULTIPROCESS
       
   440     if (!surface->isBuffered())
       
   441         c->addUnbufferedSurface();
       
   442 #endif
       
   443 }
       
   444 
       
   445 /*!
       
   446     \internal
       
   447     Raises the window above all other windows except "Stay on top" windows.
       
   448 */
       
   449 void QWSWindow::raise()
       
   450 {
       
   451     qwsServerPrivate->raiseWindow(this);
       
   452 #ifndef QT_NO_QWSEMBEDWIDGET
       
   453     const int n = d->embedded.size();
       
   454     for (int i = 0; i < n; ++i)
       
   455         d->embedded.at(i)->raise();
       
   456 #endif
       
   457 }
       
   458 
       
   459 /*!
       
   460     \internal
       
   461     Lowers the window below other windows.
       
   462 */
       
   463 void QWSWindow::lower()
       
   464 {
       
   465     qwsServerPrivate->lowerWindow(this);
       
   466 #ifndef QT_NO_QWSEMBEDWIDGET
       
   467     const int n = d->embedded.size();
       
   468     for (int i = 0; i < n; ++i)
       
   469         d->embedded.at(i)->lower();
       
   470 #endif
       
   471 }
       
   472 
       
   473 /*!
       
   474     \internal
       
   475     Shows the window.
       
   476 */
       
   477 void QWSWindow::show()
       
   478 {
       
   479     operation(QWSWindowOperationEvent::Show);
       
   480 #ifndef QT_NO_QWSEMBEDWIDGET
       
   481     const int n = d->embedded.size();
       
   482     for (int i = 0; i < n; ++i)
       
   483         d->embedded.at(i)->show();
       
   484 #endif
       
   485 }
       
   486 
       
   487 /*!
       
   488     \internal
       
   489     Hides the window.
       
   490 */
       
   491 void QWSWindow::hide()
       
   492 {
       
   493     operation(QWSWindowOperationEvent::Hide);
       
   494 #ifndef QT_NO_QWSEMBEDWIDGET
       
   495     const int n = d->embedded.size();
       
   496     for (int i = 0; i < n; ++i)
       
   497         d->embedded.at(i)->hide();
       
   498 #endif
       
   499 }
       
   500 
       
   501 /*!
       
   502     \internal
       
   503     Make this the active window (i.e., sets the keyboard focus to this
       
   504     window).
       
   505 */
       
   506 void QWSWindow::setActiveWindow()
       
   507 {
       
   508     qwsServerPrivate->setFocus(this, true);
       
   509 #ifndef QT_NO_QWSEMBEDWIDGET
       
   510     const int n = d->embedded.size();
       
   511     for (int i = 0; i < n; ++i)
       
   512         d->embedded.at(i)->setActiveWindow();
       
   513 #endif
       
   514 }
       
   515 
       
   516 void QWSWindow::setName(const QString &n)
       
   517 {
       
   518     rgnName = n;
       
   519 }
       
   520 
       
   521 /*!
       
   522   \internal
       
   523   Sets the window's caption to \a c.
       
   524 */
       
   525 void QWSWindow::setCaption(const QString &c)
       
   526 {
       
   527     rgnCaption = c;
       
   528 }
       
   529 
       
   530 
       
   531 static int global_focus_time_counter=100;
       
   532 
       
   533 void QWSWindow::focus(bool get)
       
   534 {
       
   535     if (get)
       
   536         last_focus_time = global_focus_time_counter++;
       
   537     if (c) {
       
   538         QWSFocusEvent event;
       
   539         event.simpleData.window = id;
       
   540         event.simpleData.get_focus = get;
       
   541         c->sendEvent(&event);
       
   542     }
       
   543 }
       
   544 
       
   545 void QWSWindow::operation(QWSWindowOperationEvent::Operation o)
       
   546 {
       
   547     if (!c)
       
   548         return;
       
   549     QWSWindowOperationEvent event;
       
   550     event.simpleData.window = id;
       
   551     event.simpleData.op = o;
       
   552     c->sendEvent(&event);
       
   553 }
       
   554 
       
   555 /*!
       
   556     \internal
       
   557     Destructor.
       
   558 */
       
   559 QWSWindow::~QWSWindow()
       
   560 {
       
   561 #ifndef QT_NO_QWS_INPUTMETHODS
       
   562     if (current_IM_composing_win == this)
       
   563         current_IM_composing_win = 0;
       
   564 #endif
       
   565 #ifndef QT_NO_QWSEMBEDWIDGET
       
   566     QWSWindow *embedder = d->embedder;
       
   567     if (embedder) {
       
   568         embedder->d->embedded.removeAll(this);
       
   569         d->embedder = 0;
       
   570     }
       
   571     while (!d->embedded.isEmpty())
       
   572         stopEmbed(d->embedded.first());
       
   573 #endif
       
   574 
       
   575 #ifndef QT_NO_QWS_MULTIPROCESS
       
   576     if (surface && !surface->isBuffered()) {
       
   577         if (c && c->d_func()) // d_func() will be 0 if client is deleted
       
   578             c->removeUnbufferedSurface();
       
   579     }
       
   580 #endif
       
   581 
       
   582     delete surface;
       
   583     delete d;
       
   584 }
       
   585 
       
   586 /*!
       
   587     \internal
       
   588 
       
   589     Returns the region that the window is allowed to draw onto,
       
   590     including any window decorations but excluding regions covered by
       
   591     other windows.
       
   592 
       
   593     \sa paintedRegion(), requestedRegion()
       
   594 */
       
   595 QRegion QWSWindow::allocatedRegion() const
       
   596 {
       
   597     return d->allocatedRegion;
       
   598 }
       
   599 
       
   600 #ifdef QT_QWS_CLIENTBLIT
       
   601 QRegion QWSWindow::directPaintRegion() const
       
   602 {
       
   603     return d->directPaintRegion;
       
   604 }
       
   605 
       
   606 inline void QWSWindow::setDirectPaintRegion(const QRegion &r)
       
   607 {
       
   608     d->directPaintRegion = r;
       
   609 }
       
   610 #endif
       
   611 
       
   612 /*!
       
   613     \internal
       
   614 
       
   615     Returns the region that the window is known to have drawn into.
       
   616 
       
   617     \sa allocatedRegion(), requestedRegion()
       
   618 */
       
   619 QRegion QWSWindow::paintedRegion() const
       
   620 {
       
   621     return (d->painted ? d->allocatedRegion : QRegion());
       
   622 }
       
   623 
       
   624 inline void QWSWindow::setAllocatedRegion(const QRegion &region)
       
   625 {
       
   626     d->allocatedRegion = region;
       
   627 }
       
   628 
       
   629 #ifndef QT_NO_QWSEMBEDWIDGET
       
   630 inline void QWSWindow::startEmbed(QWSWindow *w)
       
   631 {
       
   632     d->embedded.append(w);
       
   633     w->d->embedder = this;
       
   634 }
       
   635 
       
   636 inline void QWSWindow::stopEmbed(QWSWindow *w)
       
   637 {
       
   638     w->d->embedder = 0;
       
   639     w->client()->sendEmbedEvent(w->winId(), QWSEmbedEvent::Region, QRegion());
       
   640     d->embedded.removeAll(w);
       
   641 }
       
   642 #endif // QT_NO_QWSEMBEDWIDGET
       
   643 
       
   644 /*********************************************************************
       
   645  *
       
   646  * Class: QWSClient
       
   647  *
       
   648  *********************************************************************/
       
   649 
       
   650 class QWSClientPrivate : public QObjectPrivate
       
   651 {
       
   652     Q_DECLARE_PUBLIC(QWSClient)
       
   653 
       
   654 public:
       
   655     QWSClientPrivate();
       
   656     ~QWSClientPrivate();
       
   657 
       
   658     void setLockId(int id);
       
   659     void unlockCommunication();
       
   660 
       
   661 private:
       
   662 #ifndef QT_NO_QWS_MULTIPROCESS
       
   663     QWSLock *clientLock;
       
   664     bool shutdown;
       
   665     int numUnbufferedSurfaces;
       
   666 #endif
       
   667     QSet<QByteArray> usedFonts;
       
   668     friend class QWSServerPrivate;
       
   669 };
       
   670 
       
   671 QWSClientPrivate::QWSClientPrivate()
       
   672 {
       
   673 #ifndef QT_NO_QWS_MULTIPROCESS
       
   674     clientLock = 0;
       
   675     shutdown = false;
       
   676     numUnbufferedSurfaces = 0;
       
   677 #endif
       
   678 }
       
   679 
       
   680 QWSClientPrivate::~QWSClientPrivate()
       
   681 {
       
   682 #ifndef QT_NO_QWS_MULTIPROCESS
       
   683     delete clientLock;
       
   684 #endif
       
   685 }
       
   686 
       
   687 void QWSClientPrivate::setLockId(int id)
       
   688 {
       
   689 #ifdef QT_NO_QWS_MULTIPROCESS
       
   690     Q_UNUSED(id);
       
   691 #else
       
   692     clientLock = new QWSLock(id);
       
   693 #endif
       
   694 }
       
   695 
       
   696 void QWSClientPrivate::unlockCommunication()
       
   697 {
       
   698 #ifndef QT_NO_QWS_MULTIPROCESS
       
   699     if (clientLock)
       
   700         clientLock->unlock(QWSLock::Communication);
       
   701 #endif
       
   702 }
       
   703 
       
   704 /*!
       
   705     \class QWSClient
       
   706     \ingroup qws
       
   707 
       
   708     \brief The QWSClient class encapsulates a client process in Qt for Embedded Linux.
       
   709 
       
   710     When you run a \l{Qt for Embedded Linux} application, it either runs as a
       
   711     server or connects to an existing server. The server and client
       
   712     processes have different responsibilities: The client process
       
   713     performs all application specific operations. The server process
       
   714     is responsible for managing the clients as well as taking care of
       
   715     the pointer handling, character input, and screen output. In
       
   716     addition, the server provides functionality to handle input
       
   717     methods.
       
   718 
       
   719     As applications add and remove windows, the server process
       
   720     maintains information about each window. In \l{Qt for Embedded Linux},
       
   721     top-level windows are encapsulated as QWSWindow objects. A list of
       
   722     the current windows can be retrieved using the
       
   723     QWSServer::clientWindows() function, and each window can tell
       
   724     which client that owns it through its QWSWindow::client()
       
   725     function.
       
   726 
       
   727     A QWSClient object has an unique ID that can be retrieved using
       
   728     its clientId() function. QWSClient also provides the identity()
       
   729     function which typically returns the name of this client's running
       
   730     application.
       
   731 
       
   732     \sa QWSServer, QWSWindow, {Qt for Embedded Linux Architecture}
       
   733 */
       
   734 
       
   735 /*!
       
   736    \internal
       
   737 */
       
   738 //always use frame buffer
       
   739 QWSClient::QWSClient(QObject* parent, QWS_SOCK_BASE* sock, int id)
       
   740     : QObject(*new QWSClientPrivate, parent), command(0), cid(id)
       
   741 {
       
   742 #ifdef QT_NO_QWS_MULTIPROCESS
       
   743     Q_UNUSED(sock);
       
   744     isClosed = false;
       
   745 #else
       
   746     csocket = 0;
       
   747     if (!sock) {
       
   748         socketDescriptor = -1;
       
   749         isClosed = false;
       
   750     } else {
       
   751         csocket = static_cast<QWSSocket*>(sock); //###
       
   752         isClosed = false;
       
   753 
       
   754         csocket->flush();
       
   755         socketDescriptor = csocket->socketDescriptor();
       
   756         connect(csocket, SIGNAL(readyRead()), this, SIGNAL(readyRead()));
       
   757         connect(csocket, SIGNAL(disconnected()), this, SLOT(closeHandler()));
       
   758         connect(csocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(errorHandler()));
       
   759     }
       
   760 #endif //QT_NO_QWS_MULTIPROCESS
       
   761 }
       
   762 
       
   763 /*!
       
   764    \internal
       
   765 */
       
   766 QWSClient::~QWSClient()
       
   767 {
       
   768     qDeleteAll(cursors);
       
   769     delete command;
       
   770 #ifndef QT_NO_QWS_MULTIPROCESS
       
   771     delete csocket;
       
   772 #endif
       
   773 }
       
   774 
       
   775 #ifndef QT_NO_QWS_MULTIPROCESS
       
   776 void QWSClient::removeUnbufferedSurface()
       
   777 {
       
   778     Q_D(QWSClient);
       
   779     --d->numUnbufferedSurfaces;
       
   780 }
       
   781 
       
   782 void QWSClient::addUnbufferedSurface()
       
   783 {
       
   784     Q_D(QWSClient);
       
   785     ++d->numUnbufferedSurfaces;
       
   786 }
       
   787 #endif // QT_NO_QWS_MULTIPROCESS
       
   788 
       
   789 /*!
       
   790    \internal
       
   791 */
       
   792 void QWSClient::setIdentity(const QString& i)
       
   793 {
       
   794     id = i;
       
   795 }
       
   796 
       
   797 void QWSClient::closeHandler()
       
   798 {
       
   799     isClosed = true;
       
   800     emit connectionClosed();
       
   801 }
       
   802 
       
   803 void QWSClient::errorHandler()
       
   804 {
       
   805 #if defined(QWS_SOCKET_DEBUG)
       
   806     qDebug("Client %p error %s", this, csocket ? csocket->errorString().toLatin1().constData() : "(no socket)");
       
   807 #endif
       
   808     isClosed = true;
       
   809 //####Do we need to clean out the pipes?
       
   810 
       
   811     emit connectionClosed();
       
   812 }
       
   813 
       
   814 /*!
       
   815    \internal
       
   816 */
       
   817 int QWSClient::socket() const
       
   818 {
       
   819     return socketDescriptor;
       
   820 }
       
   821 
       
   822 /*!
       
   823    \internal
       
   824 */
       
   825 void QWSClient::sendEvent(QWSEvent* event)
       
   826 {
       
   827 #ifndef QT_NO_QWS_MULTIPROCESS
       
   828     if (csocket) {
       
   829         // qDebug() << "QWSClient::sendEvent type " << event->type << " socket state " << csocket->state();
       
   830         if ((QAbstractSocket::SocketState)(csocket->state()) == QAbstractSocket::ConnectedState) {
       
   831             event->write(csocket);
       
   832         }
       
   833     }
       
   834     else
       
   835 #endif
       
   836     {
       
   837         qt_client_enqueue(event);
       
   838     }
       
   839 }
       
   840 
       
   841 /*!
       
   842    \internal
       
   843 */
       
   844 void QWSClient::sendRegionEvent(int winid, QRegion rgn, int type
       
   845 #ifdef QT_QWS_CLIENTBLIT
       
   846         , int id
       
   847 #endif
       
   848         )
       
   849 {
       
   850 #ifndef QT_NO_QWS_MULTIPROCESS
       
   851     Q_D(QWSClient);
       
   852     if (d->clientLock)
       
   853         d->clientLock->lock(QWSLock::RegionEvent);
       
   854 #endif
       
   855 
       
   856     QWSRegionEvent event;
       
   857     event.setData(winid, rgn, type);
       
   858 #ifdef QT_QWS_CLIENTBLIT
       
   859     event.simpleData.id = id;
       
   860 #endif
       
   861 
       
   862 //    qDebug() << "Sending Region event to" << winid << "rgn" << rgn << "type" << type;
       
   863 
       
   864     sendEvent(&event);
       
   865 }
       
   866 
       
   867 extern int qt_servershmid;
       
   868 
       
   869 /*!
       
   870    \internal
       
   871 */
       
   872 void QWSClient::sendConnectedEvent(const char *display_spec)
       
   873 {
       
   874     QWSConnectedEvent event;
       
   875     event.simpleData.window = 0;
       
   876     event.simpleData.len = strlen(display_spec) + 1;
       
   877     event.simpleData.clientId = cid;
       
   878     event.simpleData.servershmid = qt_servershmid;
       
   879     char * tmp=(char *)display_spec;
       
   880     event.setData(tmp, event.simpleData.len);
       
   881     sendEvent(&event);
       
   882 }
       
   883 
       
   884 /*!
       
   885    \internal
       
   886 */
       
   887 void QWSClient::sendMaxWindowRectEvent(const QRect &rect)
       
   888 {
       
   889     QWSMaxWindowRectEvent event;
       
   890     event.simpleData.window = 0;
       
   891     event.simpleData.rect = rect;
       
   892     sendEvent(&event);
       
   893 }
       
   894 
       
   895 /*!
       
   896    \internal
       
   897 */
       
   898 #ifndef QT_NO_QWS_PROPERTIES
       
   899 void QWSClient::sendPropertyNotifyEvent(int property, int state)
       
   900 {
       
   901     QWSPropertyNotifyEvent event;
       
   902     event.simpleData.window = 0; // not used yet
       
   903     event.simpleData.property = property;
       
   904     event.simpleData.state = state;
       
   905     sendEvent(&event);
       
   906 }
       
   907 
       
   908 /*!
       
   909    \internal
       
   910 */
       
   911 void QWSClient::sendPropertyReplyEvent(int property, int len, const char *data)
       
   912 {
       
   913     QWSPropertyReplyEvent event;
       
   914     event.simpleData.window = 0; // not used yet
       
   915     event.simpleData.property = property;
       
   916     event.simpleData.len = len;
       
   917     event.setData(data, len);
       
   918     sendEvent(&event);
       
   919 }
       
   920 #endif //QT_NO_QWS_PROPERTIES
       
   921 
       
   922 /*!
       
   923    \internal
       
   924 */
       
   925 void QWSClient::sendSelectionClearEvent(int windowid)
       
   926 {
       
   927     QWSSelectionClearEvent event;
       
   928     event.simpleData.window = windowid;
       
   929     sendEvent(&event);
       
   930 }
       
   931 
       
   932 /*!
       
   933    \internal
       
   934 */
       
   935 void QWSClient::sendSelectionRequestEvent(QWSConvertSelectionCommand *cmd, int windowid)
       
   936 {
       
   937     QWSSelectionRequestEvent event;
       
   938     event.simpleData.window = windowid;
       
   939     event.simpleData.requestor = cmd->simpleData.requestor;
       
   940     event.simpleData.property = cmd->simpleData.selection;
       
   941     event.simpleData.mimeTypes = cmd->simpleData.mimeTypes;
       
   942     sendEvent(&event);
       
   943 }
       
   944 
       
   945 #ifndef QT_NO_QWSEMBEDWIDGET
       
   946 /*!
       
   947    \internal
       
   948 */
       
   949 void QWSClient::sendEmbedEvent(int windowid, QWSEmbedEvent::Type type,
       
   950                                const QRegion &region)
       
   951 {
       
   952     QWSEmbedEvent event;
       
   953     event.setData(windowid, type, region);
       
   954     sendEvent(&event);
       
   955 }
       
   956 #endif // QT_NO_QWSEMBEDWIDGET
       
   957 
       
   958 /*!
       
   959    \fn void QWSClient::connectionClosed()
       
   960    \internal
       
   961 */
       
   962 
       
   963 /*!
       
   964     \fn void QWSClient::readyRead();
       
   965     \internal
       
   966 */
       
   967 
       
   968 /*!
       
   969    \fn int QWSClient::clientId () const
       
   970 
       
   971    Returns an integer uniquely identfying this client.
       
   972 */
       
   973 
       
   974 /*!
       
   975    \fn QString QWSClient::identity () const
       
   976 
       
   977    Returns the name of this client's running application.
       
   978 */
       
   979 /*********************************************************************
       
   980  *
       
   981  * Class: QWSServer
       
   982  *
       
   983  *********************************************************************/
       
   984 
       
   985 /*!
       
   986     \class QWSServer
       
   987     \brief The QWSServer class encapsulates a server process in Qt for Embedded Linux.
       
   988 
       
   989     \ingroup qws
       
   990 
       
   991     When you run a \l{Qt for Embedded Linux} application, it either runs as a
       
   992     server or connects to an existing server. The server and client
       
   993     processes have different responsibilities: The client process
       
   994     performs all application specific operations. The server process
       
   995     is responsible for managing the clients as well as taking care of
       
   996     the pointer handling, character input, and screen output. In
       
   997     addition, the server provides functionality to handle input
       
   998     methods.
       
   999 
       
  1000     In \l{Qt for Embedded Linux}, all system generated events are passed to the
       
  1001     server application which then propagates the event to the
       
  1002     appropriate client. See the \l{Qt for Embedded Linux Architecture}
       
  1003     documentation for details.
       
  1004 
       
  1005     Note that this class is instantiated by QApplication for
       
  1006     \l{Qt for Embedded Linux} server processes; you should never construct this
       
  1007     class yourself. Use the instance() function to retrieve a pointer
       
  1008     to the server object.
       
  1009 
       
  1010     Note that the static functions of the QWSServer class can only be
       
  1011     used in the server process.
       
  1012 
       
  1013     \tableofcontents
       
  1014 
       
  1015     \section1 Client Administration
       
  1016 
       
  1017     As applications add and remove windows, the server process
       
  1018     maintains information about each window. In \l{Qt for Embedded Linux},
       
  1019     top-level windows are encapsulated as QWSWindow objects. Each
       
  1020     window can tell which client that owns it through its
       
  1021     QWSWindow::client() function. Use the clientWindows() function to
       
  1022     retrieve a list of the current top-level windows. Given a
       
  1023     particular position on the display, the window containing it can
       
  1024     be retrieved using the windowAt() function.
       
  1025 
       
  1026     QWSServer also provides the windowEvent() signal which is emitted
       
  1027     whenever something happens to a top level window; the WindowEvent
       
  1028     enum describes the various types of events that the signal
       
  1029     recognizes. In addition, the server class provides the
       
  1030     markedText() signal which is emitted whenever some text has been
       
  1031     selected in any of the windows, passing the selection as
       
  1032     parameter.
       
  1033 
       
  1034     The QCopChannel class and the QCOP communication protocol enable
       
  1035     transfer of messages between clients. QWSServer provides the
       
  1036     newChannel() and removedChannel() signals that is emitted whenever
       
  1037     a new QCopChannel object is created or destroyed, respectively.
       
  1038 
       
  1039     See also: QWSWindow, QWSClient and QCopChannel.
       
  1040 
       
  1041 
       
  1042     \section1 Mouse Handling
       
  1043 
       
  1044     The mouse driver (represented by an instance of the
       
  1045     QWSMouseHandler class) is loaded by the server application when it
       
  1046     starts running, using Qt's \l {How to Create Qt Plugins}{plugin
       
  1047     system}. A mouse driver receives mouse events from the device and
       
  1048     encapsulates each event with an instance of the QWSEvent class
       
  1049     which it then passes to the server.
       
  1050 
       
  1051     The openMouse() function opens the mouse devices specified by the
       
  1052     QWS_MOUSE_PROTO environment variable, and the setMouseHandler()
       
  1053     functions sets the primary mouse driver. Alternatively, the static
       
  1054     setDefaultMouse() function provides means of specifying the mouse
       
  1055     driver to use if the QWS_MOUSE_PROTO variable is not defined (note
       
  1056     that the default is otherwise platform dependent). The primary
       
  1057     mouse driver can be retrieved using the static mouseHandler()
       
  1058     function. Use the closeMouse() function to delete the mouse
       
  1059     drivers.
       
  1060 
       
  1061     In addition, the QWSServer class can control the flow of mouse
       
  1062     input using the suspendMouse() and resumeMouse() functions.
       
  1063 
       
  1064     See also: QWSMouseHandler and \l{Qt for Embedded Linux Pointer Handling}.
       
  1065 
       
  1066     \section1 Keyboard Handling
       
  1067 
       
  1068     The keyboard driver (represented by an instance of the
       
  1069     QWSKeyboardHandler class) is loaded by the server application when
       
  1070     it starts running, using Qt's \l {How to Create Qt Plugins}{plugin
       
  1071     system}. A keyboard driver receives keyboard events from the
       
  1072     device and encapsulates each event with an instance of the
       
  1073     QWSEvent class which it then passes to the server.
       
  1074 
       
  1075     The openKeyboard() function opens the keyboard devices specified
       
  1076     by the QWS_KEYBOARD environment variable, and the
       
  1077     setKeyboardHandler() functions sets the primary keyboard
       
  1078     driver. Alternatively, the static setDefaultKeyboard() function
       
  1079     provides means of specifying the keyboard driver to use if the
       
  1080     QWS_KEYBOARD variable is not defined (note again that the default
       
  1081     is otherwise platform dependent). The primary keyboard driver can
       
  1082     be retrieved using the static keyboardHandler() function. Use the
       
  1083     closeKeyboard() function to delete the keyboard drivers.
       
  1084 
       
  1085     In addition, the QWSServer class can handle key events from both
       
  1086     physical and virtual keyboards using the processKeyEvent() and
       
  1087     sendKeyEvent() functions, respectively. Use the
       
  1088     addKeyboardFilter() function to filter the key events from
       
  1089     physical keyboard drivers, the most recently added filter can be
       
  1090     removed and deleted using the removeKeyboardFilter() function.
       
  1091 
       
  1092     See also: QWSKeyboardHandler and \l{Qt for Embedded Linux Character Input}.
       
  1093 
       
  1094     \section1 Display Handling
       
  1095 
       
  1096     When a screen update is required, the server runs through all the
       
  1097     top-level windows that intersect with the region that is about to
       
  1098     be updated, and ensures that the associated clients have updated
       
  1099     their memory buffer. Then the server uses the screen driver
       
  1100     (represented by an instance of the QScreen class) to copy the
       
  1101     content of the memory to the screen.
       
  1102 
       
  1103     In addition, the QWSServer class provides some means of managing
       
  1104     the screen output: Use the refresh() function to refresh the
       
  1105     entire display, or alternatively a specified region of it. The
       
  1106     enablePainting() function can be used to disable (and enable)
       
  1107     painting onto the screen. QWSServer also provide the
       
  1108     setMaxWindowRect() function restricting the area of the screen
       
  1109     which \l{Qt for Embedded Linux} applications will consider to be the
       
  1110     maximum area to use for windows. To set the brush used as the
       
  1111     background in the absence of obscuring windows, QWSServer provides
       
  1112     the static setBackground() function. The corresponding
       
  1113     backgroundBrush() function returns the currently set brush.
       
  1114 
       
  1115     QWSServer also controls the screen saver: Use the setScreenSaver()
       
  1116     to install a custom screen saver derived from the QWSScreenSaver
       
  1117     class. Once installed, the screensaver can be activated using the
       
  1118     screenSaverActivate() function, and the screenSaverActive()
       
  1119     function returns its current status. Use the
       
  1120     setScreenSaverInterval() function to specify the timeout interval.
       
  1121     \l{Qt for Embedded Linux} also supports multilevel screen saving, use the
       
  1122     setScreenSaverIntervals() function to specify the various levels
       
  1123     and their timeout intervals.
       
  1124 
       
  1125     Finally, the QWSServer class controls the cursor's appearance,
       
  1126     i.e., use the setCursorVisible() function to hide or show the
       
  1127     cursor, and the isCursorVisible() function to determine whether
       
  1128     the cursor is visible on the display or not.
       
  1129 
       
  1130     See also: QScreen and \l{Qt for Embedded Linux Display Management}.
       
  1131 
       
  1132     \section1 Input Method Handling
       
  1133 
       
  1134     Whenever the server receives an event, it queries its stack of
       
  1135     top-level windows to find the window containing the event's
       
  1136     position (each window can identify the client application that
       
  1137     created it). Then the server forwards the event to the appropriate
       
  1138     client. If an input method is installed, it is used as a filter
       
  1139     between the server and the client application.
       
  1140 
       
  1141     Derive from the QWSInputMethod class to create custom input
       
  1142     methods, and use the server's setCurrentInputMethod() function to
       
  1143     install it. Use the sendIMEvent() and sendIMQuery() functions to
       
  1144     send input method events and queries.
       
  1145 
       
  1146     QWSServer provides the IMMouse enum describing the various mouse
       
  1147     events recognized by the QWSInputMethod::mouseHandler()
       
  1148     function. The latter function allows subclasses of QWSInputMethod
       
  1149     to handle mouse events within the preedit text.
       
  1150 
       
  1151     \sa QWSInputMethod
       
  1152 */
       
  1153 
       
  1154 /*!
       
  1155     \enum QWSServer::IMState
       
  1156     \obsolete
       
  1157 
       
  1158     This enum describes the various states of an input method.
       
  1159 
       
  1160     \value IMCompose Composing.
       
  1161     \value IMStart Equivalent to IMCompose.
       
  1162     \value IMEnd Finished composing.
       
  1163 
       
  1164     \sa QWSInputMethod::sendIMEvent()
       
  1165 */
       
  1166 
       
  1167 /*!
       
  1168     \enum QWSServer::IMMouse
       
  1169 
       
  1170     This enum describes the various types of mouse events recognized
       
  1171     by the QWSInputMethod::mouseHandler() function.
       
  1172 
       
  1173     \value MousePress An event generated by pressing a mouse button.
       
  1174     \value MouseRelease An event generated by relasing a mouse button.
       
  1175     \value MouseMove An event generated by moving the mouse cursor.
       
  1176     \value MouseOutside This value is only reserved, i.e., it is not used in
       
  1177                                     current implementations.
       
  1178 
       
  1179     \sa QWSInputMethod, setCurrentInputMethod()
       
  1180 */
       
  1181 
       
  1182 /*!
       
  1183     \enum QWSServer::ServerFlags
       
  1184     \internal
       
  1185 
       
  1186     This enum is used to pass various options to the window system
       
  1187     server.
       
  1188 
       
  1189     \value DisableKeyboard Ignore all keyboard input.
       
  1190     \value DisableMouse Ignore all mouse input.
       
  1191 */
       
  1192 
       
  1193 /*!
       
  1194     \enum QWSServer::WindowEvent
       
  1195 
       
  1196     This enum specifies the various events that can occur in a
       
  1197     top-level window.
       
  1198 
       
  1199     \value Create A new window has been created (by the QWidget constructor).
       
  1200     \value Destroy The window has been closed and deleted (by the QWidget destructor).
       
  1201     \value Hide The window has been hidden using the QWidget::hide() function.
       
  1202     \value Show The window has been shown using the QWidget::show() function or similar.
       
  1203     \value Raise The window has been raised to the top of the desktop.
       
  1204     \value Lower The window has been lowered.
       
  1205     \value Geometry The window has changed size or position.
       
  1206     \value Active The window has become the active window (i.e., it has keyboard focus).
       
  1207     \value Name The window has been named.
       
  1208 
       
  1209     \sa windowEvent()
       
  1210 */
       
  1211 
       
  1212 /*!
       
  1213     \fn void QWSServer::markedText(const QString &selection)
       
  1214 
       
  1215     This signal is emitted whenever some text is selected in any of
       
  1216     the running applications, passing the selected text in the \a
       
  1217     selection parameter.
       
  1218 
       
  1219     \sa windowEvent()
       
  1220 */
       
  1221 
       
  1222 /*!
       
  1223     \fn const QList<QWSWindow*> &QWSServer::clientWindows()
       
  1224 
       
  1225     Returns the list of current top-level windows.
       
  1226 
       
  1227     Note that the collection of top-level windows changes as
       
  1228     applications add and remove widgets so it should not be stored for
       
  1229     future use. The windows are sorted in stacking order from top-most
       
  1230     to bottom-most.
       
  1231 
       
  1232     Use the QWSWindow::client() function to retrieve the client
       
  1233     application that owns a given window.
       
  1234 
       
  1235     \sa windowAt(), instance()
       
  1236 */
       
  1237 
       
  1238 /*!
       
  1239     \fn void QWSServer::newChannel(const QString& channel)
       
  1240 
       
  1241     This signal is emitted whenever a new QCopChannel object is
       
  1242     created, passing the channel's name in the \a channel parameter.
       
  1243 
       
  1244     \sa removedChannel()
       
  1245 */
       
  1246 
       
  1247 /*!
       
  1248     \fn void QWSServer::removedChannel(const QString& channel)
       
  1249 
       
  1250     This signal is emitted immediately after the given the QCopChannel
       
  1251     object specified by \a channel, is destroyed.
       
  1252 
       
  1253     Note that a channel is not destroyed until all its listeners have
       
  1254     been unregistered.
       
  1255 
       
  1256     \sa newChannel()
       
  1257 */
       
  1258 
       
  1259 /*!
       
  1260     \fn QWSServer::QWSServer(int flags, QObject *parent)
       
  1261     \internal
       
  1262 
       
  1263     Construct a QWSServer object with the given \a parent.  The \a
       
  1264     flags are used for keyboard and mouse settings.
       
  1265 
       
  1266     \warning This class is instantiated by QApplication for
       
  1267     \l{Qt for Embedded Linux} server processes. You should never construct
       
  1268     this class yourself.
       
  1269 
       
  1270     \sa {Running Applications}
       
  1271 */
       
  1272 
       
  1273 /*!
       
  1274     \fn static QWSServer* QWSServer::instance()
       
  1275     \since 4.2
       
  1276 
       
  1277     Returns a pointer to the server instance.
       
  1278 
       
  1279     Note that the pointer will be 0 if the application is not the
       
  1280     server, i.e., if the QApplication::type() function doesn't return
       
  1281     QApplication::GuiServer.
       
  1282 
       
  1283     \sa clientWindows(), windowAt()
       
  1284 */
       
  1285 
       
  1286 struct QWSCommandStruct
       
  1287 {
       
  1288     QWSCommandStruct(QWSCommand *c, QWSClient *cl) :command(c),client(cl){}
       
  1289     ~QWSCommandStruct() { delete command; }
       
  1290 
       
  1291     QWSCommand *command;
       
  1292     QWSClient *client;
       
  1293 
       
  1294 };
       
  1295 
       
  1296 QWSServer::QWSServer(int flags, QObject *parent) :
       
  1297     QObject(*new QWSServerPrivate, parent)
       
  1298 {
       
  1299     Q_D(QWSServer);
       
  1300     QT_TRY {
       
  1301         d->initServer(flags);
       
  1302     } QT_CATCH(...) {
       
  1303         qwsServer = 0;
       
  1304         qwsServerPrivate = 0;
       
  1305         QT_RETHROW;
       
  1306     }
       
  1307 }
       
  1308 
       
  1309 #ifdef QT3_SUPPORT
       
  1310 /*!
       
  1311     Use the two-argument overload and call the
       
  1312     QObject::setObjectName() function instead.
       
  1313 */
       
  1314 QWSServer::QWSServer(int flags, QObject *parent, const char *name) :
       
  1315     QObject(*new QWSServerPrivate, parent)
       
  1316 {
       
  1317     Q_D(QWSServer);
       
  1318     setObjectName(QString::fromAscii(name));
       
  1319     d->initServer(flags);
       
  1320 }
       
  1321 #endif
       
  1322 
       
  1323 
       
  1324 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1325 static void ignoreSignal(int) {} // Used to eat SIGPIPE signals below
       
  1326 #endif
       
  1327 
       
  1328 bool QWSServerPrivate::screensaverblockevent( int index, int *screensaverinterval, bool isDown )
       
  1329 {
       
  1330     static bool ignoreEvents[2] = { false, false };
       
  1331     if ( isDown ) {
       
  1332         if ( !ignoreEvents[index] ) {
       
  1333             bool wake = false;
       
  1334             if ( screensaverintervals ) {
       
  1335                 if ( screensaverinterval != screensaverintervals ) {
       
  1336                     wake = true;
       
  1337                 }
       
  1338             }
       
  1339             if ( screensaverblockevents && wake ) {
       
  1340 #ifdef EVENT_BLOCK_DEBUG
       
  1341                 qDebug( "waking the screen" );
       
  1342 #endif
       
  1343                 ignoreEvents[index] = true;
       
  1344             } else if ( !screensaverblockevents ) {
       
  1345 #ifdef EVENT_BLOCK_DEBUG
       
  1346                 qDebug( "the screen was already awake" );
       
  1347 #endif
       
  1348                 ignoreEvents[index] = false;
       
  1349             }
       
  1350         }
       
  1351     } else {
       
  1352         if ( ignoreEvents[index] ) {
       
  1353 #ifdef EVENT_BLOCK_DEBUG
       
  1354             qDebug( "mouseup?" );
       
  1355 #endif
       
  1356             ignoreEvents[index] = false;
       
  1357             return true;
       
  1358         }
       
  1359     }
       
  1360     return ignoreEvents[index];
       
  1361 }
       
  1362 
       
  1363 void QWSServerPrivate::initServer(int flags)
       
  1364 {
       
  1365     Q_Q(QWSServer);
       
  1366     Q_ASSERT(!qwsServer);
       
  1367     qwsServer = q;
       
  1368     qwsServerPrivate = this;
       
  1369     disablePainting = false;
       
  1370 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1371     ssocket = new QWSServerSocket(qws_qtePipeFilename(), q);
       
  1372     QObject::connect(ssocket, SIGNAL(newConnection()), q, SLOT(_q_newConnection()));
       
  1373 
       
  1374     if ( !ssocket->isListening()) {
       
  1375         perror("QWSServerPrivate::initServer: server socket not listening");
       
  1376         qFatal("Failed to bind to %s", qws_qtePipeFilename().toLatin1().constData());
       
  1377     }
       
  1378 
       
  1379     struct linger tmp;
       
  1380     tmp.l_onoff=1;
       
  1381     tmp.l_linger=0;
       
  1382     setsockopt(ssocket->socketDescriptor(),SOL_SOCKET,SO_LINGER,(char *)&tmp,sizeof(tmp));
       
  1383 
       
  1384 
       
  1385     signal(SIGPIPE, ignoreSignal); //we get it when we read
       
  1386 #endif
       
  1387     focusw = 0;
       
  1388     mouseGrabber = 0;
       
  1389     mouseGrabbing = false;
       
  1390     inputMethodMouseGrabbed = false;
       
  1391     keyboardGrabber = 0;
       
  1392     keyboardGrabbing = false;
       
  1393 #ifndef QT_NO_QWS_CURSOR
       
  1394     haveviscurs = false;
       
  1395     cursor = 0;
       
  1396     nextCursor = 0;
       
  1397 #endif
       
  1398 
       
  1399 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1400 
       
  1401     if (!geteuid()) {
       
  1402 #if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
       
  1403         if(mount(0,"/var/shm", "shm", 0, 0)) {
       
  1404             /* This just confuses people with 2.2 kernels
       
  1405             if (errno != EBUSY)
       
  1406                 qDebug("Failed mounting shm fs on /var/shm: %s",strerror(errno));
       
  1407             */
       
  1408         }
       
  1409 #endif
       
  1410     }
       
  1411 #endif
       
  1412 
       
  1413     // no selection yet
       
  1414     selectionOwner.windowid = -1;
       
  1415     selectionOwner.time.set(-1, -1, -1, -1);
       
  1416 
       
  1417     cleanupFontsDir();
       
  1418 
       
  1419     // initialize the font database
       
  1420     // from qfontdatabase_qws.cpp
       
  1421     extern void qt_qws_init_fontdb();
       
  1422     qt_qws_init_fontdb();
       
  1423 
       
  1424     openDisplay();
       
  1425 
       
  1426     screensavertimer = new QTimer(q);
       
  1427     screensavertimer->setSingleShot(true);
       
  1428     QObject::connect(screensavertimer, SIGNAL(timeout()), q, SLOT(_q_screenSaverTimeout()));
       
  1429     _q_screenSaverWake();
       
  1430 
       
  1431     clientMap[-1] = new QWSClient(q, 0, 0);
       
  1432 
       
  1433     if (!bgBrush)
       
  1434         bgBrush = new QBrush(QColor(0x20, 0xb0, 0x50));
       
  1435 
       
  1436     initializeCursor();
       
  1437 
       
  1438     // input devices
       
  1439     if (!(flags&QWSServer::DisableMouse)) {
       
  1440         q->openMouse();
       
  1441     }
       
  1442 #ifndef QT_NO_QWS_KEYBOARD
       
  1443     if (!(flags&QWSServer::DisableKeyboard)) {
       
  1444         q->openKeyboard();
       
  1445     }
       
  1446 #endif
       
  1447 
       
  1448 #if !defined(QT_NO_SOUND) && !defined(QT_EXTERNAL_SOUND_SERVER) && !defined(Q_OS_DARWIN)
       
  1449     soundserver = new QWSSoundServer(q);
       
  1450 #endif
       
  1451 }
       
  1452 
       
  1453 /*!
       
  1454     \internal
       
  1455     Destructs this server.
       
  1456 */
       
  1457 QWSServer::~QWSServer()
       
  1458 {
       
  1459     closeMouse();
       
  1460 #ifndef QT_NO_QWS_KEYBOARD
       
  1461     closeKeyboard();
       
  1462 #endif
       
  1463     d_func()->cleanupFonts(/*force =*/true);
       
  1464 }
       
  1465 
       
  1466 /*!
       
  1467   \internal
       
  1468  */
       
  1469 void QWSServer::timerEvent(QTimerEvent *e)
       
  1470 {
       
  1471     Q_D(QWSServer);
       
  1472     if (e->timerId() == d->fontCleanupTimer.timerId()) {
       
  1473         d->cleanupFonts();
       
  1474         d->fontCleanupTimer.stop();
       
  1475     } else {
       
  1476         QObject::timerEvent(e);
       
  1477     }
       
  1478 }
       
  1479 
       
  1480 const QList<QWSWindow*> &QWSServer::clientWindows()
       
  1481 {
       
  1482     Q_D(QWSServer);
       
  1483     return d->windows;
       
  1484 }
       
  1485 
       
  1486 /*!
       
  1487   \internal
       
  1488 */
       
  1489 void QWSServerPrivate::releaseMouse(QWSWindow* w)
       
  1490 {
       
  1491     if (w && mouseGrabber == w) {
       
  1492         mouseGrabber = 0;
       
  1493         mouseGrabbing = false;
       
  1494 #ifndef QT_NO_QWS_CURSOR
       
  1495         if (nextCursor) {
       
  1496             // Not grabbing -> set the correct cursor
       
  1497             setCursor(nextCursor);
       
  1498             nextCursor = 0;
       
  1499         }
       
  1500 #endif
       
  1501     }
       
  1502 }
       
  1503 
       
  1504 /*!
       
  1505   \internal
       
  1506 */
       
  1507 void QWSServerPrivate::releaseKeyboard(QWSWindow* w)
       
  1508 {
       
  1509     if (keyboardGrabber == w) {
       
  1510         keyboardGrabber = 0;
       
  1511         keyboardGrabbing = false;
       
  1512     }
       
  1513 }
       
  1514 
       
  1515 void QWSServerPrivate::handleWindowClose(QWSWindow *w)
       
  1516 {
       
  1517     w->shuttingDown();
       
  1518     if (focusw == w)
       
  1519         setFocus(w,false);
       
  1520     if (mouseGrabber == w)
       
  1521         releaseMouse(w);
       
  1522     if (keyboardGrabber == w)
       
  1523         releaseKeyboard(w);
       
  1524 }
       
  1525 
       
  1526 
       
  1527 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1528 /*!
       
  1529   \internal
       
  1530 */
       
  1531 void QWSServerPrivate::_q_newConnection()
       
  1532 {
       
  1533     Q_Q(QWSServer);
       
  1534     while (QWS_SOCK_BASE *sock = ssocket->nextPendingConnection()) {
       
  1535         int socket = sock->socketDescriptor();
       
  1536         sock->setParent(0);
       
  1537 
       
  1538         QWSClient *client = new QWSClient(q,sock, get_object_id());
       
  1539         clientMap[socket] = client;
       
  1540 
       
  1541 #ifndef QT_NO_SXE
       
  1542 #ifdef QTRANSPORTAUTH_DEBUG
       
  1543         qDebug( "Transport auth connected: unix stream socket %d", socket );
       
  1544 #endif
       
  1545         // get a handle to the per-process authentication service
       
  1546         QTransportAuth *a = QTransportAuth::getInstance();
       
  1547 
       
  1548         // assert that this transport is trusted
       
  1549         QTransportAuth::Data *d = a->connectTransport(
       
  1550                 QTransportAuth::UnixStreamSock |
       
  1551                 QTransportAuth::Trusted, socket );
       
  1552 
       
  1553         QAuthDevice *ad = a->recvBuf( d, sock );
       
  1554         ad->setClient(client);
       
  1555 
       
  1556         QObject::connect(ad, SIGNAL(readyRead()),
       
  1557                 q, SLOT(_q_doClient()));
       
  1558 
       
  1559         QObject::connect(client, SIGNAL(connectionClosed()),
       
  1560                 q, SLOT(_q_clientClosed()));
       
  1561 #else
       
  1562         QObject::connect(client, SIGNAL(readyRead()),
       
  1563                          q, SLOT(_q_doClient()));
       
  1564         QObject::connect(client, SIGNAL(connectionClosed()),
       
  1565                          q, SLOT(_q_clientClosed()));
       
  1566 #endif // QT_NO_SXE
       
  1567 
       
  1568         client->sendConnectedEvent(qws_display_spec.constData());
       
  1569 
       
  1570         if (clientMap.contains(socket)) {
       
  1571             QList<QScreen*> screens = qt_screen->subScreens();
       
  1572             if (screens.isEmpty())
       
  1573                 screens.append(qt_screen);
       
  1574             for (int i = 0; i < screens.size(); ++i) {
       
  1575                 const QApplicationPrivate *ap = QApplicationPrivate::instance();
       
  1576                 QScreen *screen = screens.at(i);
       
  1577                 const QRect rect = ap->maxWindowRect(screen);
       
  1578                 if (!rect.isEmpty())
       
  1579                     client->sendMaxWindowRectEvent(rect);
       
  1580                 if (screen->isTransformed()) {
       
  1581                     QWSScreenTransformationEvent event;
       
  1582                     event.simpleData.screen = i;
       
  1583                     event.simpleData.transformation = screen->transformOrientation();
       
  1584                     client->sendEvent(&event);
       
  1585                 }
       
  1586             }
       
  1587         }
       
  1588 
       
  1589         // pre-provide some object id's
       
  1590         QWSCreateCommand cmd(30);
       
  1591         invokeCreate(&cmd, client);
       
  1592     }
       
  1593 }
       
  1594 /*!
       
  1595   \internal
       
  1596 */
       
  1597 void QWSServerPrivate::_q_clientClosed()
       
  1598 {
       
  1599     Q_Q(QWSServer);
       
  1600     QWSClient* cl = (QWSClient*)q->sender();
       
  1601 
       
  1602     // Remove any queued commands for this client
       
  1603     int i = 0;
       
  1604     while (i < commandQueue.size()) {
       
  1605         QWSCommandStruct *cs = commandQueue.at(i);
       
  1606         if (cs->client == cl) {
       
  1607             commandQueue.removeAt(i);
       
  1608             delete cs;
       
  1609         } else {
       
  1610             ++i;
       
  1611         }
       
  1612     }
       
  1613 
       
  1614 #ifndef QT_NO_COP
       
  1615     // Enfore unsubscription from all channels.
       
  1616     QCopChannel::detach(cl);
       
  1617 #endif
       
  1618 
       
  1619     // Shut down all windows for this client
       
  1620     for (int i = 0; i < windows.size(); ++i) {
       
  1621         QWSWindow* w = windows.at(i);
       
  1622         if (w->forClient(cl))
       
  1623             w->shuttingDown();
       
  1624     }
       
  1625 
       
  1626     // Delete all windows for this client
       
  1627     QRegion exposed;
       
  1628     i = 0;
       
  1629     while (i < windows.size()) {
       
  1630         QWSWindow* w = windows.at(i);
       
  1631         if (w->forClient(cl)) {
       
  1632             windows.takeAt(i);
       
  1633             w->c = 0; //so we don't send events to it anymore
       
  1634             releaseMouse(w);
       
  1635             releaseKeyboard(w);
       
  1636             exposed += w->allocatedRegion();
       
  1637 //                rgnMan->remove(w->allocationIndex());
       
  1638             if (focusw == w)
       
  1639                 setFocus(focusw,0);
       
  1640             if (mouseGrabber == w)
       
  1641                 releaseMouse(w);
       
  1642             if (i < nReserved)
       
  1643                 --nReserved;
       
  1644 #ifndef QT_NO_QWS_PROPERTIES
       
  1645             propertyManager.removeProperties(w->winId());
       
  1646 #endif
       
  1647             emit q->windowEvent(w, QWSServer::Destroy);
       
  1648             w->d->state = QWSWindow::Destroyed; //???
       
  1649             deletedWindows.append(w);
       
  1650         } else {
       
  1651             ++i;
       
  1652         }
       
  1653     }
       
  1654     if (deletedWindows.count())
       
  1655         QTimer::singleShot(0, q, SLOT(_q_deleteWindowsLater()));
       
  1656 
       
  1657     QWSClientPrivate *clientPrivate = cl->d_func();
       
  1658     if (!clientPrivate->shutdown) {
       
  1659 #if defined(QWS_DEBUG_FONTCLEANUP)
       
  1660         qDebug() << "client" << cl->clientId() << "crashed";
       
  1661 #endif
       
  1662         // this would be the place to emit a signal to notify about the
       
  1663         // crash of a client
       
  1664         crashedClientIds.append(cl->clientId());
       
  1665         fontCleanupTimer.start(10, q_func());
       
  1666     }
       
  1667     clientPrivate->shutdown = true;
       
  1668 
       
  1669     while (!clientPrivate->usedFonts.isEmpty()) {
       
  1670         const QByteArray font = *clientPrivate->usedFonts.begin();
       
  1671 #if defined(QWS_DEBUG_FONTCLEANUP)
       
  1672         qDebug() << "dereferencing font" << font << "from disconnected client";
       
  1673 #endif
       
  1674         dereferenceFont(clientPrivate, font);
       
  1675     }
       
  1676     clientPrivate->usedFonts.clear();
       
  1677 
       
  1678     //qDebug("removing client %d with socket %d", cl->clientId(), cl->socket());
       
  1679     clientMap.remove(cl->socket());
       
  1680     if (cl == cursorClient)
       
  1681         cursorClient = 0;
       
  1682     if (qt_screen->clearCacheFunc)
       
  1683         (qt_screen->clearCacheFunc)(qt_screen, cl->clientId());  // remove any remaining cache entries.
       
  1684     cl->deleteLater();
       
  1685 
       
  1686     update_regions();
       
  1687     exposeRegion(exposed);
       
  1688 }
       
  1689 
       
  1690 void QWSServerPrivate::_q_deleteWindowsLater()
       
  1691 {
       
  1692     qDeleteAll(deletedWindows);
       
  1693     deletedWindows.clear();
       
  1694 }
       
  1695 
       
  1696 #endif //QT_NO_QWS_MULTIPROCESS
       
  1697 
       
  1698 void QWSServerPrivate::referenceFont(QWSClientPrivate *client, const QByteArray &font)
       
  1699 {
       
  1700     if (!client->usedFonts.contains(font)) {
       
  1701         client->usedFonts.insert(font);
       
  1702 
       
  1703         ++fontReferenceCount[font];
       
  1704 #if defined(QWS_DEBUG_FONTCLEANUP)
       
  1705         qDebug() << "Client" << client->q_func()->clientId() << "added font" << font;
       
  1706         qDebug() << "Refcount is" << fontReferenceCount[font];
       
  1707 #endif
       
  1708     }
       
  1709 }
       
  1710 
       
  1711 void QWSServerPrivate::dereferenceFont(QWSClientPrivate *client, const QByteArray &font)
       
  1712 {
       
  1713     if (client->usedFonts.contains(font)) {
       
  1714         client->usedFonts.remove(font);
       
  1715 
       
  1716         Q_ASSERT(fontReferenceCount[font]);
       
  1717         if (!--fontReferenceCount[font] && !fontCleanupTimer.isActive())
       
  1718             fontCleanupTimer.start(FontCleanupInterval, q_func());
       
  1719 
       
  1720 #if defined(QWS_DEBUG_FONTCLEANUP)
       
  1721         qDebug() << "Client" << client->q_func()->clientId() << "removed font" << font;
       
  1722         qDebug() << "Refcount is" << fontReferenceCount[font];
       
  1723 #endif
       
  1724     }
       
  1725 }
       
  1726 
       
  1727 static void cleanupFontsDir()
       
  1728 {
       
  1729     static bool dontDelete = !qgetenv("QWS_KEEP_FONTS").isEmpty();
       
  1730     if (dontDelete)
       
  1731         return;
       
  1732 
       
  1733     extern QString qws_fontCacheDir();
       
  1734     QDir dir(qws_fontCacheDir(), QLatin1String("*.qsf"));
       
  1735     for (uint i = 0; i < dir.count(); ++i) {
       
  1736 #if defined(QWS_DEBUG_FONTCLEANUP)
       
  1737         qDebug() << "removing stale font file" << dir[i];
       
  1738 #endif
       
  1739         dir.remove(dir[i]);
       
  1740     }
       
  1741 }
       
  1742 
       
  1743 void QWSServerPrivate::cleanupFonts(bool force)
       
  1744 {
       
  1745     static bool dontDelete = !qgetenv("QWS_KEEP_FONTS").isEmpty();
       
  1746     if (dontDelete)
       
  1747         return;
       
  1748 
       
  1749 #if defined(QWS_DEBUG_FONTCLEANUP)
       
  1750     qDebug() << "cleanupFonts()";
       
  1751 #endif
       
  1752     if (!fontReferenceCount.isEmpty()) {
       
  1753         QMap<QByteArray, int>::Iterator it = fontReferenceCount.begin();
       
  1754         while (it != fontReferenceCount.end()) {
       
  1755             if (it.value() && !force) {
       
  1756                 ++it;
       
  1757                 continue;
       
  1758             }
       
  1759 
       
  1760             const QByteArray &fontName = it.key();
       
  1761 #if defined(QWS_DEBUG_FONTCLEANUP)
       
  1762             qDebug() << "removing unused font file" << fontName;
       
  1763 #endif
       
  1764             QT_TRY {
       
  1765                 QFile::remove(QFile::decodeName(fontName));
       
  1766                 sendFontRemovedEvent(fontName);
       
  1767 
       
  1768                 it = fontReferenceCount.erase(it);
       
  1769             } QT_CATCH(...) {
       
  1770                 // so we were not able to remove the font.
       
  1771                 // don't be angry and just continue with the next ones.
       
  1772                 ++it;
       
  1773             }
       
  1774         }
       
  1775     }
       
  1776 
       
  1777     if (crashedClientIds.isEmpty())
       
  1778         return;
       
  1779 
       
  1780     QList<QByteArray> removedFonts;
       
  1781 #if !defined(QT_NO_QWS_QPF2) && !defined(QT_FONTS_ARE_RESOURCES)
       
  1782     removedFonts = QFontEngineQPF::cleanUpAfterClientCrash(crashedClientIds);
       
  1783 #endif
       
  1784     crashedClientIds.clear();
       
  1785 
       
  1786     for (int i = 0; i < removedFonts.count(); ++i)
       
  1787         sendFontRemovedEvent(removedFonts.at(i));
       
  1788 }
       
  1789 
       
  1790 void QWSServerPrivate::sendFontRemovedEvent(const QByteArray &font)
       
  1791 {
       
  1792     QWSFontEvent event;
       
  1793     event.simpleData.type = QWSFontEvent::FontRemoved;
       
  1794     event.setData(font.constData(), font.length(), false);
       
  1795 
       
  1796     QMap<int,QWSClient*>::const_iterator it = clientMap.constBegin();
       
  1797     for (; it != clientMap.constEnd(); ++it)
       
  1798         (*it)->sendEvent(&event);
       
  1799 }
       
  1800 
       
  1801 /*!
       
  1802    \internal
       
  1803 */
       
  1804 QWSCommand* QWSClient::readMoreCommand()
       
  1805 {
       
  1806 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1807     QIODevice *socket = 0;
       
  1808 #endif
       
  1809 #ifndef QT_NO_SXE
       
  1810     if (socketDescriptor != -1)  // not server socket
       
  1811         socket = QTransportAuth::getInstance()->passThroughByClient( this );
       
  1812 #if QTRANSPORTAUTH_DEBUG
       
  1813     if (socket) {
       
  1814         char displaybuf[1024];
       
  1815         qint64 bytes = socket->bytesAvailable();
       
  1816         if ( bytes > 511 ) bytes = 511;
       
  1817         hexstring( displaybuf, ((unsigned char *)(reinterpret_cast<QAuthDevice*>(socket)->buffer().constData())), bytes );
       
  1818         qDebug( "readMoreCommand: %lli bytes - %s", socket->bytesAvailable(), displaybuf );
       
  1819     }
       
  1820 #endif
       
  1821 #endif // QT_NO_SXE
       
  1822 
       
  1823 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1824     if (!socket)
       
  1825         socket = csocket;   // server socket
       
  1826     if (socket) {
       
  1827         // read next command
       
  1828         if (!command) {
       
  1829             int command_type = qws_read_uint(socket);
       
  1830 
       
  1831             if (command_type >= 0)
       
  1832                 command = QWSCommand::factory(command_type);
       
  1833         }
       
  1834         if (command) {
       
  1835             if (command->read(socket)) {
       
  1836                 // Finished reading a whole command.
       
  1837                 QWSCommand* result = command;
       
  1838                 command = 0;
       
  1839                 return result;
       
  1840             }
       
  1841         }
       
  1842 
       
  1843         // Not finished reading a whole command.
       
  1844         return 0;
       
  1845     } else
       
  1846 #endif // QT_NO_QWS_MULTIPROCESS
       
  1847     {
       
  1848         QList<QWSCommand*> *serverQueue = qt_get_server_queue();
       
  1849         return serverQueue->isEmpty() ? 0 : serverQueue->takeFirst();
       
  1850     }
       
  1851 }
       
  1852 
       
  1853 
       
  1854 /*!
       
  1855   \internal
       
  1856 */
       
  1857 void QWSServer::processEventQueue()
       
  1858 {
       
  1859     if (qwsServerPrivate)
       
  1860         qwsServerPrivate->doClient(qwsServerPrivate->clientMap.value(-1));
       
  1861 }
       
  1862 
       
  1863 
       
  1864 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1865 void QWSServerPrivate::_q_doClient()
       
  1866 {
       
  1867     Q_Q(QWSServer);
       
  1868 
       
  1869     QWSClient* client;
       
  1870 #ifndef QT_NO_SXE
       
  1871     QAuthDevice *ad = qobject_cast<QAuthDevice*>(q->sender());
       
  1872     if (ad)
       
  1873         client = (QWSClient*)ad->client();
       
  1874     else
       
  1875 #endif
       
  1876         client = (QWSClient*)q->sender();
       
  1877 
       
  1878     if (doClientIsActive) {
       
  1879         pendingDoClients.append(client);
       
  1880         return;
       
  1881     }
       
  1882     doClientIsActive = true;
       
  1883 
       
  1884     doClient(client);
       
  1885 
       
  1886     while (!pendingDoClients.isEmpty()) {
       
  1887         doClient(pendingDoClients.takeFirst());
       
  1888     }
       
  1889 
       
  1890     doClientIsActive = false;
       
  1891 }
       
  1892 #endif // QT_NO_QWS_MULTIPROCESS
       
  1893 
       
  1894 void QWSServerPrivate::doClient(QWSClient *client)
       
  1895 {
       
  1896     QWSCommand* command=client->readMoreCommand();
       
  1897 
       
  1898     while (command) {
       
  1899         QWSCommandStruct *cs = new QWSCommandStruct(command, client);
       
  1900         commandQueue.append(cs);
       
  1901         // Try for some more...
       
  1902         command=client->readMoreCommand();
       
  1903     }
       
  1904 
       
  1905     while (!commandQueue.isEmpty()) {
       
  1906         QWSCommandStruct *cs = commandQueue.takeAt(0);
       
  1907         switch (cs->command->type) {
       
  1908         case QWSCommand::Identify:
       
  1909             invokeIdentify((QWSIdentifyCommand*)cs->command, cs->client);
       
  1910             break;
       
  1911         case QWSCommand::Create:
       
  1912             invokeCreate((QWSCreateCommand*)cs->command, cs->client);
       
  1913             break;
       
  1914 #ifndef QT_NO_QWS_MULTIPROCESS
       
  1915         case QWSCommand::Shutdown:
       
  1916             cs->client->d_func()->shutdown = true;
       
  1917             break;
       
  1918 #endif
       
  1919         case QWSCommand::RegionName:
       
  1920             invokeRegionName((QWSRegionNameCommand*)cs->command, cs->client);
       
  1921             break;
       
  1922         case QWSCommand::Region:
       
  1923             invokeRegion((QWSRegionCommand*)cs->command, cs->client);
       
  1924             cs->client->d_func()->unlockCommunication();
       
  1925             break;
       
  1926         case QWSCommand::RegionMove:
       
  1927             invokeRegionMove((QWSRegionMoveCommand*)cs->command, cs->client);
       
  1928             cs->client->d_func()->unlockCommunication();
       
  1929             break;
       
  1930         case QWSCommand::RegionDestroy:
       
  1931             invokeRegionDestroy((QWSRegionDestroyCommand*)cs->command, cs->client);
       
  1932             break;
       
  1933 #ifndef QT_NO_QWS_PROPERTIES
       
  1934         case QWSCommand::AddProperty:
       
  1935             invokeAddProperty((QWSAddPropertyCommand*)cs->command);
       
  1936             break;
       
  1937         case QWSCommand::SetProperty:
       
  1938             invokeSetProperty((QWSSetPropertyCommand*)cs->command);
       
  1939             break;
       
  1940         case QWSCommand::RemoveProperty:
       
  1941             invokeRemoveProperty((QWSRemovePropertyCommand*)cs->command);
       
  1942             break;
       
  1943         case QWSCommand::GetProperty:
       
  1944             invokeGetProperty((QWSGetPropertyCommand*)cs->command, cs->client);
       
  1945             break;
       
  1946 #endif
       
  1947         case QWSCommand::SetSelectionOwner:
       
  1948             invokeSetSelectionOwner((QWSSetSelectionOwnerCommand*)cs->command);
       
  1949             break;
       
  1950         case QWSCommand::RequestFocus:
       
  1951             invokeSetFocus((QWSRequestFocusCommand*)cs->command, cs->client);
       
  1952             break;
       
  1953         case QWSCommand::ChangeAltitude:
       
  1954             invokeSetAltitude((QWSChangeAltitudeCommand*)cs->command,
       
  1955                                cs->client);
       
  1956             cs->client->d_func()->unlockCommunication();
       
  1957             break;
       
  1958         case QWSCommand::SetOpacity:
       
  1959             invokeSetOpacity((QWSSetOpacityCommand*)cs->command,
       
  1960                                cs->client);
       
  1961             break;
       
  1962 
       
  1963 #ifndef QT_NO_QWS_CURSOR
       
  1964         case QWSCommand::DefineCursor:
       
  1965             invokeDefineCursor((QWSDefineCursorCommand*)cs->command, cs->client);
       
  1966             break;
       
  1967         case QWSCommand::SelectCursor:
       
  1968             invokeSelectCursor((QWSSelectCursorCommand*)cs->command, cs->client);
       
  1969             break;
       
  1970         case QWSCommand::PositionCursor:
       
  1971             invokePositionCursor((QWSPositionCursorCommand*)cs->command, cs->client);
       
  1972             break;
       
  1973 #endif
       
  1974         case QWSCommand::GrabMouse:
       
  1975             invokeGrabMouse((QWSGrabMouseCommand*)cs->command, cs->client);
       
  1976             break;
       
  1977         case QWSCommand::GrabKeyboard:
       
  1978             invokeGrabKeyboard((QWSGrabKeyboardCommand*)cs->command, cs->client);
       
  1979             break;
       
  1980 #if !defined(QT_NO_SOUND) && !defined(Q_OS_DARWIN)
       
  1981         case QWSCommand::PlaySound:
       
  1982             invokePlaySound((QWSPlaySoundCommand*)cs->command, cs->client);
       
  1983             break;
       
  1984 #endif
       
  1985 #ifndef QT_NO_COP
       
  1986         case QWSCommand::QCopRegisterChannel:
       
  1987             invokeRegisterChannel((QWSQCopRegisterChannelCommand*)cs->command,
       
  1988                                    cs->client);
       
  1989             break;
       
  1990         case QWSCommand::QCopSend:
       
  1991             invokeQCopSend((QWSQCopSendCommand*)cs->command, cs->client);
       
  1992             break;
       
  1993 #endif
       
  1994 #ifndef QT_NO_QWS_INPUTMETHODS
       
  1995         case QWSCommand::IMUpdate:
       
  1996             invokeIMUpdate((QWSIMUpdateCommand*)cs->command, cs->client);
       
  1997             break;
       
  1998         case QWSCommand::IMResponse:
       
  1999             invokeIMResponse((QWSIMResponseCommand*)cs->command, cs->client);
       
  2000             break;
       
  2001         case QWSCommand::IMMouse:
       
  2002             {
       
  2003                 if (current_IM) {
       
  2004                     QWSIMMouseCommand *cmd = (QWSIMMouseCommand *) cs->command;
       
  2005                     current_IM->mouseHandler(cmd->simpleData.index,
       
  2006                                               cmd->simpleData.state);
       
  2007                 }
       
  2008             }
       
  2009             break;
       
  2010 #endif
       
  2011         case QWSCommand::Font:
       
  2012             invokeFont((QWSFontCommand *)cs->command, cs->client);
       
  2013             break;
       
  2014         case QWSCommand::RepaintRegion:
       
  2015             invokeRepaintRegion((QWSRepaintRegionCommand*)cs->command,
       
  2016                                 cs->client);
       
  2017             cs->client->d_func()->unlockCommunication();
       
  2018             break;
       
  2019 #ifndef QT_NO_QWSEMBEDWIDGET
       
  2020         case QWSCommand::Embed:
       
  2021             invokeEmbed(static_cast<QWSEmbedCommand*>(cs->command),
       
  2022                         cs->client);
       
  2023             break;
       
  2024 #endif
       
  2025         case QWSCommand::ScreenTransform:
       
  2026             invokeScreenTransform(static_cast<QWSScreenTransformCommand*>(cs->command),
       
  2027                                   cs->client);
       
  2028             break;
       
  2029         }
       
  2030         delete cs;
       
  2031     }
       
  2032 }
       
  2033 
       
  2034 
       
  2035 void QWSServerPrivate::showCursor()
       
  2036 {
       
  2037 #ifndef QT_NO_QWS_CURSOR
       
  2038     if (qt_screencursor)
       
  2039         qt_screencursor->show();
       
  2040 #endif
       
  2041 }
       
  2042 
       
  2043 void QWSServerPrivate::hideCursor()
       
  2044 {
       
  2045 #ifndef QT_NO_QWS_CURSOR
       
  2046     if (qt_screencursor)
       
  2047         qt_screencursor->hide();
       
  2048 #endif
       
  2049 }
       
  2050 
       
  2051 /*!
       
  2052     \fn void QWSServer::enablePainting(bool enable)
       
  2053 
       
  2054     Enables painting onto the screen if \a enable is true; otherwise
       
  2055     painting is disabled.
       
  2056 
       
  2057     \sa {Qt for Embedded Linux Architecture#Drawing on Screen}{Qt for Embedded Linux
       
  2058     Architecture}
       
  2059 */
       
  2060 void QWSServer::enablePainting(bool enable)
       
  2061 {
       
  2062     Q_D(QWSServer);
       
  2063 
       
  2064     if (d->disablePainting == !enable)
       
  2065         return;
       
  2066 
       
  2067     d->disablePainting = !enable;
       
  2068 
       
  2069     if (enable) {
       
  2070         // Reset the server side allocated regions to ensure update_regions()
       
  2071         // will send out region events.
       
  2072         for (int i = 0; i < d->windows.size(); ++i) {
       
  2073             QWSWindow *w = d->windows.at(i);
       
  2074             w->setAllocatedRegion(QRegion());
       
  2075 #ifdef QT_QWS_CLIENTBLIT
       
  2076             w->setDirectPaintRegion(QRegion());
       
  2077 #endif
       
  2078         }
       
  2079         d->update_regions();
       
  2080         d->showCursor();
       
  2081     } else {
       
  2082         // Disable painting by clients by taking away their allocated region.
       
  2083         // To ensure mouse events are still delivered to the correct windows,
       
  2084         // the allocated regions are not modified on the server.
       
  2085         for (int i = 0; i < d->windows.size(); ++i) {
       
  2086             QWSWindow *w = d->windows.at(i);
       
  2087             w->client()->sendRegionEvent(w->winId(), QRegion(),
       
  2088                                          QWSRegionEvent::Allocation);
       
  2089 #ifdef QT_QWS_CLIENTBLIT
       
  2090             w->client()->sendRegionEvent(w->winId(), QRegion(),
       
  2091                                          QWSRegionEvent::DirectPaint);
       
  2092 #endif
       
  2093         }
       
  2094         d->hideCursor();
       
  2095     }
       
  2096 }
       
  2097 
       
  2098 /*!
       
  2099     Refreshes the display by making the screen driver update the
       
  2100     entire display.
       
  2101 
       
  2102     \sa QScreen::exposeRegion()
       
  2103 */
       
  2104 void QWSServer::refresh()
       
  2105 {
       
  2106     Q_D(QWSServer);
       
  2107     d->exposeRegion(QScreen::instance()->region());
       
  2108 //### send repaint to non-buffered windows
       
  2109 }
       
  2110 
       
  2111 /*!
       
  2112     \fn void QWSServer::refresh(QRegion & region)
       
  2113     \overload
       
  2114 
       
  2115     Refreshes the given \a region of the display.
       
  2116 */
       
  2117 void QWSServer::refresh(QRegion & r)
       
  2118 {
       
  2119     Q_D(QWSServer);
       
  2120     d->exposeRegion(r);
       
  2121 //### send repaint to non-buffered windows
       
  2122 }
       
  2123 
       
  2124 /*!
       
  2125     \fn void QWSServer::setMaxWindowRect(const QRect& rectangle)
       
  2126 
       
  2127     Sets the maximum area of the screen that \l{Qt for Embedded Linux}
       
  2128     applications can use, to be the given \a rectangle.
       
  2129 
       
  2130     Note that this function can only be used in the server process.
       
  2131 
       
  2132     \sa QWidget::showMaximized()
       
  2133 */
       
  2134 void QWSServer::setMaxWindowRect(const QRect &rect)
       
  2135 {
       
  2136     QList<QScreen*> subScreens = qt_screen->subScreens();
       
  2137     if (subScreens.isEmpty() && qt_screen != 0)
       
  2138         subScreens.append(qt_screen);
       
  2139 
       
  2140     for (int i = 0; i < subScreens.size(); ++i) {
       
  2141         const QScreen *screen = subScreens.at(i);
       
  2142         const QRect r = (screen->region() & rect).boundingRect();
       
  2143         if (r.isEmpty())
       
  2144             continue;
       
  2145 
       
  2146         QApplicationPrivate *ap = QApplicationPrivate::instance();
       
  2147         if (ap->maxWindowRect(screen) != r) {
       
  2148             ap->setMaxWindowRect(screen, i, r);
       
  2149             qwsServerPrivate->sendMaxWindowRectEvents(r);
       
  2150         }
       
  2151     }
       
  2152 }
       
  2153 
       
  2154 /*!
       
  2155   \internal
       
  2156 */
       
  2157 void QWSServerPrivate::sendMaxWindowRectEvents(const QRect &rect)
       
  2158 {
       
  2159     QMap<int,QWSClient*>::const_iterator it = clientMap.constBegin();
       
  2160     for (; it != clientMap.constEnd(); ++it)
       
  2161         (*it)->sendMaxWindowRectEvent(rect);
       
  2162 }
       
  2163 
       
  2164 /*!
       
  2165     \fn void QWSServer::setDefaultMouse(const char *mouseDriver)
       
  2166 
       
  2167     Sets the mouse driver that will be used if the QWS_MOUSE_PROTO
       
  2168     environment variable is not defined, to be the given \a
       
  2169     mouseDriver.
       
  2170 
       
  2171     Note that the default is platform-dependent. This function can
       
  2172     only be used in the server process.
       
  2173 
       
  2174 
       
  2175     \sa setMouseHandler(), {Qt for Embedded Linux Pointer Handling}
       
  2176 */
       
  2177 void QWSServer::setDefaultMouse(const char *m)
       
  2178 {
       
  2179     *defaultMouse() = QString::fromAscii(m);
       
  2180 }
       
  2181 
       
  2182 /*!
       
  2183     \fn void QWSServer::setDefaultKeyboard(const char *keyboardDriver)
       
  2184 
       
  2185     Sets the keyboard driver that will be used if the QWS_KEYBOARD
       
  2186     environment variable is not defined, to be the given \a
       
  2187     keyboardDriver.
       
  2188 
       
  2189     Note that the default is platform-dependent. This function can
       
  2190     only be used in the server process.
       
  2191 
       
  2192     \sa setKeyboardHandler(), {Qt for Embedded Linux Character Input}
       
  2193 */
       
  2194 void QWSServer::setDefaultKeyboard(const char *k)
       
  2195 {
       
  2196     *defaultKeyboard() = QString::fromAscii(k);
       
  2197 }
       
  2198 
       
  2199 #ifndef QT_NO_QWS_CURSOR
       
  2200 static bool prevWin;
       
  2201 #endif
       
  2202 
       
  2203 
       
  2204 extern int *qt_last_x,*qt_last_y;
       
  2205 
       
  2206 
       
  2207 /*!
       
  2208   \internal
       
  2209 
       
  2210   Send a mouse event. \a pos is the screen position where the mouse
       
  2211   event occurred and \a state is a mask indicating which buttons are
       
  2212   pressed.
       
  2213 
       
  2214   \a pos is in device coordinates
       
  2215 */
       
  2216 void QWSServer::sendMouseEvent(const QPoint& pos, int state, int wheel)
       
  2217 {
       
  2218     bool block = qwsServerPrivate->screensaverblockevent(MOUSE, qwsServerPrivate->screensaverinterval, state);
       
  2219 #ifdef EVENT_BLOCK_DEBUG
       
  2220     qDebug() << "sendMouseEvent" << pos.x() << pos.y() << state << (block ? "block" : "pass");
       
  2221 #endif
       
  2222 
       
  2223     if (state || wheel)
       
  2224         qwsServerPrivate->_q_screenSaverWake();
       
  2225 
       
  2226     if ( block )
       
  2227         return;
       
  2228 
       
  2229     QPoint tpos;
       
  2230     // transformations
       
  2231     if (qt_screen->isTransformed()) {
       
  2232 	QSize s = QSize(qt_screen->deviceWidth(), qt_screen->deviceHeight());
       
  2233 	tpos = qt_screen->mapFromDevice(pos, s);
       
  2234     } else {
       
  2235 	tpos = pos;
       
  2236     }
       
  2237 
       
  2238     if (qt_last_x) {
       
  2239          *qt_last_x = tpos.x();
       
  2240          *qt_last_y = tpos.y();
       
  2241     }
       
  2242     QWSServer::mousePosition = tpos;
       
  2243     qwsServerPrivate->mouseState = state;
       
  2244 
       
  2245 #ifndef QT_NO_QWS_INPUTMETHODS
       
  2246     const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton;
       
  2247     int stroke_count; // number of strokes to keep shown.
       
  2248     if (force_reject_strokeIM || !current_IM)
       
  2249     {
       
  2250 	stroke_count = 0;
       
  2251     } else {
       
  2252 	stroke_count = current_IM->filter(tpos, state, wheel);
       
  2253     }
       
  2254 
       
  2255     if (stroke_count == 0) {
       
  2256 	if (state&btnMask)
       
  2257 	    force_reject_strokeIM = true;
       
  2258         QWSServerPrivate::sendMouseEventUnfiltered(tpos, state, wheel);
       
  2259     }
       
  2260     // stop force reject after stroke ends.
       
  2261     if (state&btnMask && force_reject_strokeIM)
       
  2262 	force_reject_strokeIM = false;
       
  2263     // on end of stroke, force_rejct
       
  2264     // and once a stroke is rejected, do not try again till pen is lifted
       
  2265 #else
       
  2266     QWSServerPrivate::sendMouseEventUnfiltered(tpos, state, wheel);
       
  2267 #endif // end QT_NO_QWS_FSIM
       
  2268 }
       
  2269 
       
  2270 void QWSServerPrivate::sendMouseEventUnfiltered(const QPoint &pos, int state, int wheel)
       
  2271 {
       
  2272     const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton;
       
  2273     QWSMouseEvent event;
       
  2274 
       
  2275     QWSWindow *win = qwsServer->windowAt(pos);
       
  2276 
       
  2277     QWSClient *serverClient = qwsServerPrivate->clientMap.value(-1);
       
  2278     QWSClient *winClient = win ? win->client() : 0;
       
  2279 
       
  2280 
       
  2281     bool imMouse = false;
       
  2282 #ifndef QT_NO_QWS_INPUTMETHODS
       
  2283     // check for input method window
       
  2284     if (current_IM && current_IM_winId != -1) {
       
  2285         QWSWindow *kbw = keyboardGrabber ? keyboardGrabber :
       
  2286                          qwsServerPrivate->focusw;
       
  2287 
       
  2288         imMouse = kbw == win;
       
  2289         if ( !imMouse ) {
       
  2290             QWidget *target = winClient == serverClient ?
       
  2291                               QApplication::widgetAt(pos) : 0;
       
  2292             imMouse = target && (target->testAttribute(Qt::WA_InputMethodTransparent));
       
  2293         }
       
  2294     }
       
  2295 #endif
       
  2296 
       
  2297     //If grabbing window disappears, grab is still active until
       
  2298     //after mouse release.
       
  2299     if ( qwsServerPrivate->mouseGrabber && (!imMouse || qwsServerPrivate->inputMethodMouseGrabbed)) {
       
  2300         win = qwsServerPrivate->mouseGrabber;
       
  2301         winClient = win ? win->client() : 0;
       
  2302     }
       
  2303     event.simpleData.window = win ? win->id : 0;
       
  2304 
       
  2305 #ifndef QT_NO_QWS_CURSOR
       
  2306     if (qt_screencursor)
       
  2307         qt_screencursor->move(pos.x(),pos.y());
       
  2308 
       
  2309     // Arrow cursor over desktop
       
  2310     // prevWin remembers if the last event was over a window
       
  2311     if (!win && prevWin) {
       
  2312         if (!qwsServerPrivate->mouseGrabber)
       
  2313             qwsServerPrivate->setCursor(QWSCursor::systemCursor(Qt::ArrowCursor));
       
  2314         else
       
  2315             qwsServerPrivate->nextCursor = QWSCursor::systemCursor(Qt::ArrowCursor);
       
  2316         prevWin = false;
       
  2317     }
       
  2318     // reset prevWin
       
  2319     if (win && !prevWin)
       
  2320         prevWin = true;
       
  2321 #endif
       
  2322 
       
  2323     if ((state&btnMask) && !qwsServerPrivate->mouseGrabbing) {
       
  2324         qwsServerPrivate->mouseGrabber = win;
       
  2325         if (imMouse)
       
  2326             qwsServerPrivate->inputMethodMouseGrabbed = true;
       
  2327     }
       
  2328     if (!(state&btnMask))
       
  2329         qwsServerPrivate->inputMethodMouseGrabbed = false;
       
  2330 
       
  2331     event.simpleData.x_root=pos.x();
       
  2332     event.simpleData.y_root=pos.y();
       
  2333     event.simpleData.state=state | qws_keyModifiers;
       
  2334     event.simpleData.delta = wheel;
       
  2335     event.simpleData.time=qwsServerPrivate->timer.elapsed();
       
  2336 
       
  2337     static int oldstate = 0;
       
  2338 
       
  2339 #ifndef QT_NO_QWS_INPUTMETHODS
       
  2340     //tell the input method if we click on a different window that is not IM transparent
       
  2341     bool isPress = state > oldstate;
       
  2342     if (isPress && !imMouse && current_IM && current_IM_winId != -1)
       
  2343         current_IM->mouseHandler(-1, QWSServer::MouseOutside);
       
  2344 #endif
       
  2345 
       
  2346     if (serverClient)
       
  2347        serverClient->sendEvent(&event);
       
  2348     if (winClient && winClient != serverClient)
       
  2349        winClient->sendEvent(&event);
       
  2350 
       
  2351     if ( !imMouse ) {
       
  2352         // Make sure that if we leave a window, that window gets one last mouse
       
  2353         // event so that it knows the mouse has left.
       
  2354         QWSClient *oldClient = qwsServer->d_func()->cursorClient;
       
  2355         if (oldClient && oldClient != winClient && oldClient != serverClient) {
       
  2356             event.simpleData.state = oldstate | qws_keyModifiers;
       
  2357             oldClient->sendEvent(&event);
       
  2358         }
       
  2359     }
       
  2360 
       
  2361     oldstate = state;
       
  2362     if ( !imMouse )
       
  2363         qwsServer->d_func()->cursorClient = winClient;
       
  2364 
       
  2365     if (!(state&btnMask) && !qwsServerPrivate->mouseGrabbing)
       
  2366         qwsServerPrivate->releaseMouse(qwsServerPrivate->mouseGrabber);
       
  2367 }
       
  2368 
       
  2369 /*!
       
  2370     Returns the primary mouse driver.
       
  2371 
       
  2372     Note that this function can only be used in the server process.
       
  2373 
       
  2374     \sa setMouseHandler(), openMouse(), closeMouse()
       
  2375 */
       
  2376 QWSMouseHandler *QWSServer::mouseHandler()
       
  2377 {
       
  2378     if (qwsServerPrivate->mousehandlers.empty())
       
  2379         return 0;
       
  2380     return qwsServerPrivate->mousehandlers.first();
       
  2381 }
       
  2382 
       
  2383 /*!
       
  2384     \since 4.5
       
  2385 
       
  2386     Returns list of all mouse handlers
       
  2387 
       
  2388     Note that this function can only be used in the server process.
       
  2389 
       
  2390     \sa mouseHandler(), setMouseHandler(), openMouse(), closeMouse()
       
  2391 */
       
  2392 const QList<QWSMouseHandler*>& QWSServer::mouseHandlers()
       
  2393 {
       
  2394     return qwsServerPrivate->mousehandlers;
       
  2395 }
       
  2396 
       
  2397 
       
  2398 // called by QWSMouseHandler constructor, not user code.
       
  2399 /*!
       
  2400     \fn void QWSServer::setMouseHandler(QWSMouseHandler* driver)
       
  2401 
       
  2402     Sets the primary mouse driver to be the given \a driver.
       
  2403 
       
  2404     \l{Qt for Embedded Linux} provides several ready-made mouse drivers, and
       
  2405     custom drivers are typically added using Qt's plugin
       
  2406     mechanism. See the \l{Qt for Embedded Linux Pointer Handling} documentation
       
  2407     for details.
       
  2408 
       
  2409     Note that this function can only be used in the server process.
       
  2410 
       
  2411     \sa mouseHandler(), setDefaultMouse()
       
  2412 */
       
  2413 void QWSServer::setMouseHandler(QWSMouseHandler* mh)
       
  2414 {
       
  2415     if (!mh)
       
  2416         return;
       
  2417     qwsServerPrivate->mousehandlers.removeAll(mh);
       
  2418     qwsServerPrivate->mousehandlers.prepend(mh);
       
  2419 }
       
  2420 
       
  2421 /*!
       
  2422   \internal
       
  2423   \obsolete
       
  2424   Caller owns data in list, and must delete contents
       
  2425 */
       
  2426 QList<QWSInternalWindowInfo*> * QWSServer::windowList()
       
  2427 {
       
  2428     QList<QWSInternalWindowInfo*> * ret=new QList<QWSInternalWindowInfo*>;
       
  2429     for (int i=0; i < qwsServerPrivate->windows.size(); ++i) {
       
  2430         QWSWindow *window = qwsServerPrivate->windows.at(i);
       
  2431         QWSInternalWindowInfo * qwi=new QWSInternalWindowInfo();
       
  2432         qwi->winid=window->winId();
       
  2433         qwi->clientid=window->client()->clientId();
       
  2434         ret->append(qwi);
       
  2435     }
       
  2436     return ret;
       
  2437 }
       
  2438 
       
  2439 #ifndef QT_NO_COP
       
  2440 /*!
       
  2441   \internal
       
  2442 */
       
  2443 void QWSServerPrivate::sendQCopEvent(QWSClient *c, const QString &ch,
       
  2444                                const QString &msg, const QByteArray &data,
       
  2445                                bool response)
       
  2446 {
       
  2447     Q_ASSERT(c);
       
  2448 
       
  2449     QWSQCopMessageEvent event;
       
  2450     event.channel = ch.toLatin1();
       
  2451     event.message = msg.toLatin1();
       
  2452     event.data = data;
       
  2453     event.simpleData.is_response = response;
       
  2454     event.simpleData.lchannel = ch.length();
       
  2455     event.simpleData.lmessage = msg.length();
       
  2456     event.simpleData.ldata = data.size();
       
  2457     int l = event.simpleData.lchannel + event.simpleData.lmessage +
       
  2458             event.simpleData.ldata;
       
  2459 
       
  2460     // combine channel, message and data into one block of raw bytes
       
  2461     char *tmp = new char [l];
       
  2462     char *d = tmp;
       
  2463     memcpy(d, event.channel.constData(), event.simpleData.lchannel);
       
  2464     d += event.simpleData.lchannel;
       
  2465     memcpy(d, event.message.constData(), event.simpleData.lmessage);
       
  2466     d += event.simpleData.lmessage;
       
  2467     memcpy(d, data.constData(), event.simpleData.ldata);
       
  2468 
       
  2469     event.setDataDirect(tmp, l);
       
  2470 
       
  2471     c->sendEvent(&event);
       
  2472 }
       
  2473 #endif
       
  2474 
       
  2475 /*!
       
  2476     \fn QWSWindow *QWSServer::windowAt(const QPoint& position)
       
  2477 
       
  2478     Returns the window containing the given \a position.
       
  2479 
       
  2480     Note that if there is no window under the specified point this
       
  2481     function returns 0.
       
  2482 
       
  2483     \sa clientWindows(), instance()
       
  2484 */
       
  2485 QWSWindow *QWSServer::windowAt(const QPoint& pos)
       
  2486 {
       
  2487     Q_D(QWSServer);
       
  2488     for (int i=0; i<d->windows.size(); ++i) {
       
  2489         QWSWindow* w = d->windows.at(i);
       
  2490         if (w->allocatedRegion().contains(pos))
       
  2491             return w;
       
  2492     }
       
  2493     return 0;
       
  2494 }
       
  2495 
       
  2496 #ifndef QT_NO_QWS_KEYBOARD
       
  2497 static int keyUnicode(int keycode)
       
  2498 {
       
  2499     int code = 0xffff;
       
  2500 
       
  2501     if (keycode >= Qt::Key_A && keycode <= Qt::Key_Z)
       
  2502         code = keycode - Qt::Key_A + 'a';
       
  2503     else if (keycode >= Qt::Key_0 && keycode <= Qt::Key_9)
       
  2504         code = keycode - Qt::Key_0 + '0';
       
  2505 
       
  2506     return code;
       
  2507 }
       
  2508 #endif
       
  2509 
       
  2510 /*!
       
  2511     Sends the given key event. The key is identified by its \a unicode
       
  2512     value and the given \a keycode, \a modifiers, \a isPress and \a
       
  2513     autoRepeat parameters.
       
  2514 
       
  2515     Use this function to send key events generated by "virtual
       
  2516     keyboards" (note that the processKeyEvent() function is
       
  2517     impelemented using this function).
       
  2518 
       
  2519     The \a keycode parameter is the Qt keycode value as defined by the
       
  2520     Qt::Key enum. The \a modifiers is an OR combination of
       
  2521     Qt::KeyboardModifier values, indicating whether \gui
       
  2522     Shift/Alt/Ctrl keys are pressed. The \a isPress parameter is true
       
  2523     if the event is a key press event and \a autoRepeat is true if the
       
  2524     event is caused by an auto-repeat mechanism and not an actual key
       
  2525     press.
       
  2526 
       
  2527     Note that this function can only be used in the server process.
       
  2528 
       
  2529     \sa processKeyEvent(), {Qt for Embedded Linux Character Input}
       
  2530 */
       
  2531 void QWSServer::sendKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
       
  2532                              bool isPress, bool autoRepeat)
       
  2533 {
       
  2534     qws_keyModifiers = modifiers;
       
  2535 
       
  2536     if (isPress) {
       
  2537         if (keycode != Qt::Key_F34 && keycode != Qt::Key_F35)
       
  2538             qwsServerPrivate->_q_screenSaverWake();
       
  2539     }
       
  2540 
       
  2541 #ifndef QT_NO_QWS_INPUTMETHODS
       
  2542 
       
  2543     if (!current_IM || !current_IM->filter(unicode, keycode, modifiers, isPress, autoRepeat))
       
  2544         QWSServerPrivate::sendKeyEventUnfiltered(unicode, keycode, modifiers, isPress, autoRepeat);
       
  2545 #else
       
  2546     QWSServerPrivate::sendKeyEventUnfiltered(unicode, keycode, modifiers, isPress, autoRepeat);
       
  2547 #endif
       
  2548 }
       
  2549 
       
  2550 void QWSServerPrivate::sendKeyEventUnfiltered(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
       
  2551                                        bool isPress, bool autoRepeat)
       
  2552 {
       
  2553 
       
  2554     QWSKeyEvent event;
       
  2555     QWSWindow *win = keyboardGrabber ? keyboardGrabber :
       
  2556         qwsServerPrivate->focusw;
       
  2557 
       
  2558     event.simpleData.window = win ? win->winId() : 0;
       
  2559 
       
  2560     event.simpleData.unicode =
       
  2561 #ifndef QT_NO_QWS_KEYBOARD
       
  2562         unicode < 0 ? keyUnicode(keycode) :
       
  2563 #endif
       
  2564         unicode;
       
  2565     event.simpleData.keycode = keycode;
       
  2566     event.simpleData.modifiers = modifiers;
       
  2567     event.simpleData.is_press = isPress;
       
  2568     event.simpleData.is_auto_repeat = autoRepeat;
       
  2569 
       
  2570     QWSClient *serverClient = qwsServerPrivate->clientMap.value(-1);
       
  2571     QWSClient *winClient = win ? win->client() : 0;
       
  2572     if (serverClient)
       
  2573         serverClient->sendEvent(&event);
       
  2574     if (winClient && winClient != serverClient)
       
  2575         winClient->sendEvent(&event);
       
  2576 }
       
  2577 
       
  2578 /*!
       
  2579     \internal
       
  2580 */
       
  2581 void QWSServer::beginDisplayReconfigure()
       
  2582 {
       
  2583     qwsServer->enablePainting(false);
       
  2584 #ifndef QT_NO_QWS_CURSOR
       
  2585     if (qt_screencursor)
       
  2586         qt_screencursor->hide();
       
  2587 #endif
       
  2588     QWSDisplay::grab(true);
       
  2589     qt_screen->disconnect();
       
  2590 }
       
  2591 
       
  2592 /*!
       
  2593     \internal
       
  2594 */
       
  2595 void QWSServer::endDisplayReconfigure()
       
  2596 {
       
  2597     qt_screen->connect(QString());
       
  2598     qwsServerPrivate->swidth = qt_screen->deviceWidth();
       
  2599     qwsServerPrivate->sheight = qt_screen->deviceHeight();
       
  2600 
       
  2601     QWSDisplay::ungrab();
       
  2602 #ifndef QT_NO_QWS_CURSOR
       
  2603     if (qt_screencursor)
       
  2604         qt_screencursor->show();
       
  2605 #endif
       
  2606     QApplicationPrivate *ap = QApplicationPrivate::instance();
       
  2607     ap->setMaxWindowRect(qt_screen, 0,
       
  2608                          QRect(0, 0, qt_screen->width(), qt_screen->height()));
       
  2609     QSize olds = qApp->desktop()->size();
       
  2610     qApp->desktop()->resize(qt_screen->width(), qt_screen->height());
       
  2611     qApp->postEvent(qApp->desktop(), new QResizeEvent(qApp->desktop()->size(), olds));
       
  2612     qwsServer->enablePainting(true);
       
  2613     qwsServer->refresh();
       
  2614     qDebug("Desktop size: %dx%d", qApp->desktop()->width(), qApp->desktop()->height());
       
  2615 }
       
  2616 
       
  2617 void QWSServerPrivate::resetEngine()
       
  2618 {
       
  2619 #ifndef QT_NO_QWS_CURSOR
       
  2620     if (!qt_screencursor)
       
  2621         return;
       
  2622     qt_screencursor->hide();
       
  2623     qt_screencursor->show();
       
  2624 #endif
       
  2625 }
       
  2626 
       
  2627 
       
  2628 #ifndef QT_NO_QWS_CURSOR
       
  2629 /*!
       
  2630     \fn void QWSServer::setCursorVisible(bool visible)
       
  2631 
       
  2632     Shows the cursor if \a visible is true: otherwise the cursor is
       
  2633     hidden.
       
  2634 
       
  2635     Note that this function can only be used in the server process.
       
  2636 
       
  2637     \sa isCursorVisible()
       
  2638 */
       
  2639 void QWSServer::setCursorVisible(bool vis)
       
  2640 {
       
  2641     if (qwsServerPrivate && qwsServerPrivate->haveviscurs != vis) {
       
  2642         QWSCursor* c = qwsServerPrivate->cursor;
       
  2643         qwsServerPrivate->setCursor(QWSCursor::systemCursor(Qt::BlankCursor));
       
  2644         qwsServerPrivate->haveviscurs = vis;
       
  2645         qwsServerPrivate->setCursor(c);
       
  2646     }
       
  2647 }
       
  2648 
       
  2649 /*!
       
  2650     Returns true if the cursor is visible; otherwise returns false.
       
  2651 
       
  2652     Note that this function can only be used in the server process.
       
  2653 
       
  2654     \sa setCursorVisible()
       
  2655 */
       
  2656 bool QWSServer::isCursorVisible()
       
  2657 {
       
  2658     return qwsServerPrivate ? qwsServerPrivate->haveviscurs : true;
       
  2659 }
       
  2660 #endif
       
  2661 
       
  2662 #ifndef QT_NO_QWS_INPUTMETHODS
       
  2663 
       
  2664 
       
  2665 /*!
       
  2666     \fn void QWSServer::sendIMEvent(const QInputMethodEvent *event)
       
  2667 
       
  2668     Sends the given input method \a event.
       
  2669 
       
  2670     The \c QInputMethodEvent class is derived from QWSEvent, i.e., it
       
  2671     is a QWSEvent object of the QWSEvent::IMEvent type.
       
  2672 
       
  2673     If there is a window actively composing the preedit string, the
       
  2674     event is sent to that window. Otherwise, the event is sent to the
       
  2675     window currently in focus.
       
  2676 
       
  2677     \sa sendIMQuery(), QWSInputMethod::sendEvent()
       
  2678 */
       
  2679 void QWSServer::sendIMEvent(const QInputMethodEvent *ime)
       
  2680 {
       
  2681     QWSIMEvent event;
       
  2682 
       
  2683     QWSWindow *win = keyboardGrabber ? keyboardGrabber :
       
  2684                      qwsServerPrivate->focusw;
       
  2685 
       
  2686     //if currently composing then event must go to the composing window
       
  2687 
       
  2688     if (current_IM_composing_win)
       
  2689         win = current_IM_composing_win;
       
  2690 
       
  2691     event.simpleData.window = win ? win->winId() : 0;
       
  2692     event.simpleData.replaceFrom = ime->replacementStart();;
       
  2693     event.simpleData.replaceLength = ime->replacementLength();
       
  2694 
       
  2695     QBuffer buffer;
       
  2696     buffer.open(QIODevice::WriteOnly);
       
  2697     QDataStream out(&buffer);
       
  2698 
       
  2699     out << ime->preeditString();
       
  2700     out << ime->commitString();
       
  2701 
       
  2702     const QList<QInputMethodEvent::Attribute> &attributes = ime->attributes();
       
  2703     for (int i = 0; i < attributes.count(); ++i) {
       
  2704         const QInputMethodEvent::Attribute &a = attributes.at(i);
       
  2705         out << a.type << a.start << a.length << a.value;
       
  2706     }
       
  2707     event.setData(buffer.data(), buffer.size());
       
  2708     QWSClient *serverClient = qwsServerPrivate->clientMap.value(-1);
       
  2709     if (serverClient)
       
  2710         serverClient->sendEvent(&event);
       
  2711     if (win && win->client() && win->client() != serverClient)
       
  2712         win->client()->sendEvent(&event);
       
  2713 
       
  2714     current_IM_composing_win = ime->preeditString().isEmpty() ? 0 : win;
       
  2715     current_IM_winId = win ? win->winId() : 0;
       
  2716 }
       
  2717 
       
  2718 
       
  2719 /*!
       
  2720     Sends an input method query for the given \a property.
       
  2721 
       
  2722     To receive responses to input method queries, the virtual
       
  2723     QWSInputMethod::queryResponse() function must be reimplemented in
       
  2724     a QWSInputMethod subclass that is activated using the
       
  2725     setCurrentInputMethod() function.
       
  2726 
       
  2727     \sa sendIMEvent(), setCurrentInputMethod()
       
  2728 */
       
  2729 void QWSServer::sendIMQuery(int property)
       
  2730 {
       
  2731     QWSIMQueryEvent event;
       
  2732 
       
  2733     QWSWindow *win = keyboardGrabber ? keyboardGrabber :
       
  2734                      qwsServerPrivate->focusw;
       
  2735     if (current_IM_composing_win)
       
  2736         win = current_IM_composing_win;
       
  2737 
       
  2738     event.simpleData.window = win ? win->winId() : 0;
       
  2739     event.simpleData.property = property;
       
  2740     if (win && win->client())
       
  2741         win->client()->sendEvent(&event);
       
  2742 }
       
  2743 
       
  2744 
       
  2745 
       
  2746 /*!
       
  2747     \fn void QWSServer::setCurrentInputMethod(QWSInputMethod *method)
       
  2748 
       
  2749     Sets the current input method to be the given \a method.
       
  2750 
       
  2751     Note that this function can only be used in the server process.
       
  2752 
       
  2753     \sa sendIMQuery(), sendIMEvent()
       
  2754 */
       
  2755 void QWSServer::setCurrentInputMethod(QWSInputMethod *im)
       
  2756 {
       
  2757     if (current_IM)
       
  2758         current_IM->reset(); //??? send an update event instead ?
       
  2759     current_IM = im;
       
  2760 }
       
  2761 
       
  2762 /*!
       
  2763     \fn static void QWSServer::resetInputMethod()
       
  2764 
       
  2765     \internal
       
  2766 */
       
  2767 
       
  2768 #endif //QT_NO_QWS_INPUTMETHODS
       
  2769 
       
  2770 #ifndef QT_NO_QWS_PROPERTIES
       
  2771 /*!
       
  2772   \internal
       
  2773 */
       
  2774 void QWSServer::sendPropertyNotifyEvent(int property, int state)
       
  2775 {
       
  2776     Q_D(QWSServer);
       
  2777     QWSServerPrivate::ClientIterator it = d->clientMap.begin();
       
  2778     while (it != d->clientMap.end()) {
       
  2779         QWSClient *cl = *it;
       
  2780         ++it;
       
  2781         cl->sendPropertyNotifyEvent(property, state);
       
  2782     }
       
  2783 }
       
  2784 #endif
       
  2785 
       
  2786 void QWSServerPrivate::invokeIdentify(const QWSIdentifyCommand *cmd, QWSClient *client)
       
  2787 {
       
  2788     client->setIdentity(cmd->id);
       
  2789 #ifndef QT_NO_QWS_MULTIPROCESS
       
  2790     if (client->clientId() > 0)
       
  2791         client->d_func()->setLockId(cmd->simpleData.idLock);
       
  2792 #endif
       
  2793 }
       
  2794 
       
  2795 void QWSServerPrivate::invokeCreate(QWSCreateCommand *cmd, QWSClient *client)
       
  2796 {
       
  2797     QWSCreationEvent event;
       
  2798     event.simpleData.objectid = get_object_id(cmd->count);
       
  2799     event.simpleData.count = cmd->count;
       
  2800     client->sendEvent(&event);
       
  2801 }
       
  2802 
       
  2803 void QWSServerPrivate::invokeRegionName(const QWSRegionNameCommand *cmd, QWSClient *client)
       
  2804 {
       
  2805     Q_Q(QWSServer);
       
  2806     QWSWindow* changingw = findWindow(cmd->simpleData.windowid, client);
       
  2807     if (changingw && (changingw->name() != cmd->name || changingw->caption() !=cmd->caption)) {
       
  2808         changingw->setName(cmd->name);
       
  2809         changingw->setCaption(cmd->caption);
       
  2810         emit q->windowEvent(changingw, QWSServer::Name);
       
  2811     }
       
  2812 }
       
  2813 
       
  2814 void QWSServerPrivate::invokeRegion(QWSRegionCommand *cmd, QWSClient *client)
       
  2815 {
       
  2816 #ifdef QWS_REGION_DEBUG
       
  2817     qDebug("QWSServer::invokeRegion %d rects (%d)",
       
  2818             cmd->simpleData.nrectangles, cmd->simpleData.windowid);
       
  2819 #endif
       
  2820 
       
  2821     QWSWindow* changingw = findWindow(cmd->simpleData.windowid, 0);
       
  2822     if (!changingw) {
       
  2823         qWarning("Invalid window handle %08x",cmd->simpleData.windowid);
       
  2824         return;
       
  2825     }
       
  2826     if (!changingw->forClient(client)) {
       
  2827         qWarning("Disabled: clients changing other client's window region");
       
  2828         return;
       
  2829     }
       
  2830 
       
  2831     request_region(cmd->simpleData.windowid, cmd->surfaceKey, cmd->surfaceData,
       
  2832                    cmd->region);
       
  2833 }
       
  2834 
       
  2835 void QWSServerPrivate::invokeRegionMove(const QWSRegionMoveCommand *cmd, QWSClient *client)
       
  2836 {
       
  2837     Q_Q(QWSServer);
       
  2838     QWSWindow* changingw = findWindow(cmd->simpleData.windowid, 0);
       
  2839     if (!changingw) {
       
  2840         qWarning("invokeRegionMove: Invalid window handle %d",cmd->simpleData.windowid);
       
  2841         return;
       
  2842     }
       
  2843     if (!changingw->forClient(client)) {
       
  2844         qWarning("Disabled: clients changing other client's window region");
       
  2845         return;
       
  2846     }
       
  2847 
       
  2848 //    changingw->setNeedAck(true);
       
  2849     moveWindowRegion(changingw, cmd->simpleData.dx, cmd->simpleData.dy);
       
  2850     emit q->windowEvent(changingw, QWSServer::Geometry);
       
  2851 }
       
  2852 
       
  2853 void QWSServerPrivate::invokeRegionDestroy(const QWSRegionDestroyCommand *cmd, QWSClient *client)
       
  2854 {
       
  2855     Q_Q(QWSServer);
       
  2856     QWSWindow* changingw = findWindow(cmd->simpleData.windowid, 0);
       
  2857     if (!changingw) {
       
  2858         qWarning("invokeRegionDestroy: Invalid window handle %d",cmd->simpleData.windowid);
       
  2859         return;
       
  2860     }
       
  2861     if (!changingw->forClient(client)) {
       
  2862         qWarning("Disabled: clients changing other client's window region");
       
  2863         return;
       
  2864     }
       
  2865 
       
  2866     setWindowRegion(changingw, QRegion());
       
  2867 //    rgnMan->remove(changingw->allocationIndex());
       
  2868     for (int i = 0; i < windows.size(); ++i) {
       
  2869         if (windows.at(i) == changingw) {
       
  2870             windows.takeAt(i);
       
  2871             if (i < nReserved)
       
  2872                 --nReserved;
       
  2873             break;
       
  2874         }
       
  2875     }
       
  2876 
       
  2877     handleWindowClose(changingw);
       
  2878 #ifndef QT_NO_QWS_PROPERTIES
       
  2879     propertyManager.removeProperties(changingw->winId());
       
  2880 #endif
       
  2881     emit q->windowEvent(changingw, QWSServer::Destroy);
       
  2882     delete changingw;
       
  2883 }
       
  2884 
       
  2885 void QWSServerPrivate::invokeSetFocus(const QWSRequestFocusCommand *cmd, QWSClient *client)
       
  2886 {
       
  2887     int winId = cmd->simpleData.windowid;
       
  2888     int gain = cmd->simpleData.flag;
       
  2889 
       
  2890     if (gain != 0 && gain != 1) {
       
  2891         qWarning("Only 0(lose) and 1(gain) supported");
       
  2892         return;
       
  2893     }
       
  2894 
       
  2895     QWSWindow* changingw = findWindow(winId, 0);
       
  2896     if (!changingw)
       
  2897         return;
       
  2898 
       
  2899     if (!changingw->forClient(client)) {
       
  2900        qWarning("Disabled: clients changing other client's focus");
       
  2901         return;
       
  2902     }
       
  2903 
       
  2904     setFocus(changingw, gain);
       
  2905 }
       
  2906 
       
  2907 void QWSServerPrivate::setFocus(QWSWindow* changingw, bool gain)
       
  2908 {
       
  2909     Q_Q(QWSServer);
       
  2910 #ifndef QT_NO_QWS_INPUTMETHODS
       
  2911     /*
       
  2912       This is the logic:
       
  2913       QWSWindow *loser = 0;
       
  2914       if (gain && focusw != changingw)
       
  2915          loser = focusw;
       
  2916       else if (!gain && focusw == changingw)
       
  2917          loser = focusw;
       
  2918       But these five lines can be reduced to one:
       
  2919     */
       
  2920     if (current_IM) {
       
  2921         QWSWindow *loser =  (!gain == (focusw==changingw)) ? focusw : 0;
       
  2922         if (loser && loser->winId() == current_IM_winId)
       
  2923             current_IM->updateHandler(QWSInputMethod::FocusOut);
       
  2924     }
       
  2925 #endif
       
  2926     if (gain) {
       
  2927         if (focusw != changingw) {
       
  2928             if (focusw) focusw->focus(0);
       
  2929             focusw = changingw;
       
  2930             focusw->focus(1);
       
  2931             emit q->windowEvent(focusw, QWSServer::Active);
       
  2932         }
       
  2933     } else if (focusw == changingw) {
       
  2934         if (changingw->client())
       
  2935             changingw->focus(0);
       
  2936         focusw = 0;
       
  2937         // pass focus to window which most recently got it...
       
  2938         QWSWindow* bestw=0;
       
  2939         for (int i=0; i<windows.size(); ++i) {
       
  2940             QWSWindow* w = windows.at(i);
       
  2941             if (w != changingw && !w->hidden() &&
       
  2942                     (!bestw || bestw->focusPriority() < w->focusPriority()))
       
  2943                 bestw = w;
       
  2944         }
       
  2945         if (!bestw && changingw->focusPriority()) { // accept focus back?
       
  2946             bestw = changingw; // must be the only one
       
  2947         }
       
  2948         focusw = bestw;
       
  2949         if (focusw) {
       
  2950             focusw->focus(1);
       
  2951             emit q->windowEvent(focusw, QWSServer::Active);
       
  2952         }
       
  2953     }
       
  2954 }
       
  2955 
       
  2956 
       
  2957 
       
  2958 void QWSServerPrivate::invokeSetOpacity(const QWSSetOpacityCommand *cmd, QWSClient *client)
       
  2959 {
       
  2960     Q_UNUSED( client );
       
  2961     int winId = cmd->simpleData.windowid;
       
  2962     int opacity = cmd->simpleData.opacity;
       
  2963 
       
  2964     QWSWindow* changingw = findWindow(winId, 0);
       
  2965 
       
  2966     if (!changingw) {
       
  2967         qWarning("invokeSetOpacity: Invalid window handle %d", winId);
       
  2968         return;
       
  2969     }
       
  2970 
       
  2971     int altitude = windows.indexOf(changingw);
       
  2972     const bool wasOpaque = changingw->isOpaque();
       
  2973     changingw->_opacity = opacity;
       
  2974     if (wasOpaque != changingw->isOpaque())
       
  2975         update_regions();
       
  2976     exposeRegion(changingw->allocatedRegion(), altitude);
       
  2977 }
       
  2978 
       
  2979 void QWSServerPrivate::invokeSetAltitude(const QWSChangeAltitudeCommand *cmd,
       
  2980                                    QWSClient *client)
       
  2981 {
       
  2982     Q_UNUSED(client);
       
  2983 
       
  2984     int winId = cmd->simpleData.windowid;
       
  2985     int alt = cmd->simpleData.altitude;
       
  2986     bool fixed = cmd->simpleData.fixed;
       
  2987 #if 0
       
  2988     qDebug("QWSServer::invokeSetAltitude winId %d alt %d)", winId, alt);
       
  2989 #endif
       
  2990 
       
  2991     if (alt < -1 || alt > 1) {
       
  2992         qWarning("QWSServer::invokeSetAltitude Only lower, raise and stays-on-top supported");
       
  2993         return;
       
  2994     }
       
  2995 
       
  2996     QWSWindow* changingw = findWindow(winId, 0);
       
  2997     if (!changingw) {
       
  2998         qWarning("invokeSetAltitude: Invalid window handle %d", winId);
       
  2999         return;
       
  3000     }
       
  3001 
       
  3002     if (fixed && alt >= 1) {
       
  3003         changingw->onTop = true;
       
  3004     }
       
  3005     if (alt == QWSChangeAltitudeCommand::Lower)
       
  3006         changingw->lower();
       
  3007     else
       
  3008         changingw->raise();
       
  3009 
       
  3010 //      if (!changingw->forClient(client)) {
       
  3011 //         refresh();
       
  3012 //     }
       
  3013 }
       
  3014 
       
  3015 #ifndef QT_NO_QWS_PROPERTIES
       
  3016 void QWSServerPrivate::invokeAddProperty(QWSAddPropertyCommand *cmd)
       
  3017 {
       
  3018     propertyManager.addProperty(cmd->simpleData.windowid, cmd->simpleData.property);
       
  3019 }
       
  3020 
       
  3021 void QWSServerPrivate::invokeSetProperty(QWSSetPropertyCommand *cmd)
       
  3022 {
       
  3023     Q_Q(QWSServer);
       
  3024     if (propertyManager.setProperty(cmd->simpleData.windowid,
       
  3025                                     cmd->simpleData.property,
       
  3026                                     cmd->simpleData.mode,
       
  3027                                     cmd->data,
       
  3028                                     cmd->rawLen)) {
       
  3029         q->sendPropertyNotifyEvent(cmd->simpleData.property,
       
  3030                                  QWSPropertyNotifyEvent::PropertyNewValue);
       
  3031 #ifndef QT_NO_QWS_INPUTMETHODS
       
  3032         if (cmd->simpleData.property == QT_QWS_PROPERTY_MARKEDTEXT) {
       
  3033             QString s((const QChar*)cmd->data, cmd->rawLen/2);
       
  3034             emit q->markedText(s);
       
  3035         }
       
  3036 #endif
       
  3037     }
       
  3038 }
       
  3039 
       
  3040 void QWSServerPrivate::invokeRemoveProperty(QWSRemovePropertyCommand *cmd)
       
  3041 {
       
  3042     Q_Q(QWSServer);
       
  3043     if (propertyManager.removeProperty(cmd->simpleData.windowid,
       
  3044                                        cmd->simpleData.property)) {
       
  3045         q->sendPropertyNotifyEvent(cmd->simpleData.property,
       
  3046                                  QWSPropertyNotifyEvent::PropertyDeleted);
       
  3047     }
       
  3048 }
       
  3049 
       
  3050 
       
  3051 bool QWSServerPrivate:: get_property(int winId, int property, const char *&data, int &len)
       
  3052 {
       
  3053     return propertyManager.getProperty(winId, property, data, len);
       
  3054 }
       
  3055 
       
  3056 
       
  3057 void QWSServerPrivate::invokeGetProperty(QWSGetPropertyCommand *cmd, QWSClient *client)
       
  3058 {
       
  3059     const char *data;
       
  3060     int len;
       
  3061 
       
  3062     if (propertyManager.getProperty(cmd->simpleData.windowid,
       
  3063                                     cmd->simpleData.property,
       
  3064                                     data, len)) {
       
  3065         client->sendPropertyReplyEvent(cmd->simpleData.property, len, data);
       
  3066     } else {
       
  3067         client->sendPropertyReplyEvent(cmd->simpleData.property, -1, 0);
       
  3068     }
       
  3069 }
       
  3070 #endif //QT_NO_QWS_PROPERTIES
       
  3071 
       
  3072 void QWSServerPrivate::invokeSetSelectionOwner(QWSSetSelectionOwnerCommand *cmd)
       
  3073 {
       
  3074     qDebug("QWSServer::invokeSetSelectionOwner");
       
  3075 
       
  3076     SelectionOwner so;
       
  3077     so.windowid = cmd->simpleData.windowid;
       
  3078     so.time.set(cmd->simpleData.hour, cmd->simpleData.minute,
       
  3079                  cmd->simpleData.sec, cmd->simpleData.ms);
       
  3080 
       
  3081     if (selectionOwner.windowid != -1) {
       
  3082         QWSWindow *win = findWindow(selectionOwner.windowid, 0);
       
  3083         if (win)
       
  3084             win->client()->sendSelectionClearEvent(selectionOwner.windowid);
       
  3085         else
       
  3086             qDebug("couldn't find window %d", selectionOwner.windowid);
       
  3087     }
       
  3088 
       
  3089     selectionOwner = so;
       
  3090 }
       
  3091 
       
  3092 void QWSServerPrivate::invokeConvertSelection(QWSConvertSelectionCommand *cmd)
       
  3093 {
       
  3094     qDebug("QWSServer::invokeConvertSelection");
       
  3095 
       
  3096     if (selectionOwner.windowid != -1) {
       
  3097         QWSWindow *win = findWindow(selectionOwner.windowid, 0);
       
  3098         if (win)
       
  3099             win->client()->sendSelectionRequestEvent(cmd, selectionOwner.windowid);
       
  3100         else
       
  3101             qDebug("couldn't find window %d", selectionOwner.windowid);
       
  3102     }
       
  3103 }
       
  3104 
       
  3105 #ifndef QT_NO_QWS_CURSOR
       
  3106 void QWSServerPrivate::invokeDefineCursor(QWSDefineCursorCommand *cmd, QWSClient *client)
       
  3107 {
       
  3108     if (cmd->simpleData.height > 64 || cmd->simpleData.width > 64) {
       
  3109         qDebug("Cannot define cursor size > 64x64");
       
  3110         return;
       
  3111     }
       
  3112 
       
  3113     delete client->cursors.take(cmd->simpleData.id);
       
  3114 
       
  3115     int dataLen = cmd->simpleData.height * ((cmd->simpleData.width+7) / 8);
       
  3116 
       
  3117     if (dataLen > 0 && cmd->data) {
       
  3118         QWSCursor *curs = new QWSCursor(cmd->data, cmd->data + dataLen,
       
  3119                                         cmd->simpleData.width, cmd->simpleData.height,
       
  3120                                         cmd->simpleData.hotX, cmd->simpleData.hotY);
       
  3121         client->cursors.insert(cmd->simpleData.id, curs);
       
  3122     }
       
  3123 }
       
  3124 
       
  3125 void QWSServerPrivate::invokeSelectCursor(QWSSelectCursorCommand *cmd, QWSClient *client)
       
  3126 {
       
  3127     int id = cmd->simpleData.id;
       
  3128     QWSCursor *curs = 0;
       
  3129     if (id <= Qt::LastCursor) {
       
  3130         curs = QWSCursor::systemCursor(id);
       
  3131     }
       
  3132     else {
       
  3133         QWSCursorMap cursMap = client->cursors;
       
  3134         QWSCursorMap::Iterator it = cursMap.find(id);
       
  3135         if (it != cursMap.end()) {
       
  3136             curs = it.value();
       
  3137         }
       
  3138     }
       
  3139     if (curs == 0) {
       
  3140         curs = QWSCursor::systemCursor(Qt::ArrowCursor);
       
  3141     }
       
  3142 
       
  3143     QWSWindow* win = findWindow(cmd->simpleData.windowid, 0);
       
  3144     if (mouseGrabber) {
       
  3145         // If the mouse is being grabbed, we don't want just anyone to
       
  3146         // be able to change the cursor.  We do want the cursor to be set
       
  3147         // correctly once mouse grabbing is stopped though.
       
  3148         if (win != mouseGrabber)
       
  3149             nextCursor = curs;
       
  3150         else
       
  3151             setCursor(curs);
       
  3152     } else if (win && win->allocatedRegion().contains(QWSServer::mousePosition)) { //##################### cursor
       
  3153         // A non-grabbing window can only set the cursor shape if the
       
  3154         // cursor is within its allocated region.
       
  3155         setCursor(curs);
       
  3156     }
       
  3157 }
       
  3158 
       
  3159 void QWSServerPrivate::invokePositionCursor(QWSPositionCursorCommand *cmd, QWSClient *)
       
  3160 {
       
  3161     Q_Q(QWSServer);
       
  3162     QPoint newPos(cmd->simpleData.newX, cmd->simpleData.newY);
       
  3163     if (newPos != QWSServer::mousePosition)
       
  3164         q->sendMouseEvent(newPos, qwsServer->d_func()->mouseState);
       
  3165 }
       
  3166 #endif
       
  3167 
       
  3168 void QWSServerPrivate::invokeGrabMouse(QWSGrabMouseCommand *cmd, QWSClient *client)
       
  3169 {
       
  3170     QWSWindow* win = findWindow(cmd->simpleData.windowid, 0);
       
  3171     if (!win)
       
  3172         return;
       
  3173 
       
  3174     if (cmd->simpleData.grab) {
       
  3175         if (!mouseGrabber || mouseGrabber->client() == client) {
       
  3176             mouseGrabbing = true;
       
  3177             mouseGrabber = win;
       
  3178         }
       
  3179     } else {
       
  3180         releaseMouse(mouseGrabber);
       
  3181     }
       
  3182 }
       
  3183 
       
  3184 void QWSServerPrivate::invokeGrabKeyboard(QWSGrabKeyboardCommand *cmd, QWSClient *client)
       
  3185 {
       
  3186     QWSWindow* win = findWindow(cmd->simpleData.windowid, 0);
       
  3187     if (!win)
       
  3188         return;
       
  3189 
       
  3190     if (cmd->simpleData.grab) {
       
  3191         if (!keyboardGrabber || (keyboardGrabber->client() == client)) {
       
  3192             keyboardGrabbing = true;
       
  3193             keyboardGrabber = win;
       
  3194         }
       
  3195     } else {
       
  3196         releaseKeyboard(keyboardGrabber);
       
  3197     }
       
  3198 }
       
  3199 
       
  3200 #if !defined(QT_NO_SOUND)
       
  3201 void QWSServerPrivate::invokePlaySound(QWSPlaySoundCommand *cmd, QWSClient *)
       
  3202 {
       
  3203 #if !defined(QT_EXTERNAL_SOUND_SERVER) && !defined(Q_OS_DARWIN)
       
  3204     soundserver->playFile( 1, cmd->filename );
       
  3205 #else
       
  3206     Q_UNUSED(cmd);
       
  3207 #endif
       
  3208 }
       
  3209 #endif
       
  3210 
       
  3211 #ifndef QT_NO_COP
       
  3212 void QWSServerPrivate::invokeRegisterChannel(QWSQCopRegisterChannelCommand *cmd,
       
  3213                                        QWSClient *client)
       
  3214 {
       
  3215   // QCopChannel will force us to emit the newChannel signal if this channel
       
  3216   // didn't already exist.
       
  3217   QCopChannel::registerChannel(cmd->channel, client);
       
  3218 }
       
  3219 
       
  3220 void QWSServerPrivate::invokeQCopSend(QWSQCopSendCommand *cmd, QWSClient *client)
       
  3221 {
       
  3222     QCopChannel::answer(client, cmd->channel, cmd->message, cmd->data);
       
  3223 }
       
  3224 
       
  3225 #endif
       
  3226 
       
  3227 #ifndef QT_NO_QWS_INPUTMETHODS
       
  3228 void QWSServer::resetInputMethod()
       
  3229 {
       
  3230     if (current_IM && qwsServer) {
       
  3231       current_IM->reset();
       
  3232     }
       
  3233 }
       
  3234 
       
  3235 void QWSServerPrivate::invokeIMResponse(const QWSIMResponseCommand *cmd,
       
  3236                                  QWSClient *)
       
  3237 {
       
  3238     if (current_IM)
       
  3239         current_IM->queryResponse(cmd->simpleData.property, cmd->result);
       
  3240 }
       
  3241 
       
  3242 void QWSServerPrivate::invokeIMUpdate(const QWSIMUpdateCommand *cmd,
       
  3243                                  QWSClient *)
       
  3244 {
       
  3245     if (cmd->simpleData.type == QWSInputMethod::FocusIn)
       
  3246         current_IM_winId = cmd->simpleData.windowid;
       
  3247 
       
  3248     if (current_IM && (current_IM_winId == cmd->simpleData.windowid || cmd->simpleData.windowid == -1))
       
  3249         current_IM->updateHandler(cmd->simpleData.type);
       
  3250 }
       
  3251 
       
  3252 #endif
       
  3253 
       
  3254 void QWSServerPrivate::invokeFont(const QWSFontCommand *cmd, QWSClient *client)
       
  3255 {
       
  3256     QWSClientPrivate *priv = client->d_func();
       
  3257     if (cmd->simpleData.type == QWSFontCommand::StartedUsingFont) {
       
  3258         referenceFont(priv, cmd->fontName);
       
  3259     } else if (cmd->simpleData.type == QWSFontCommand::StoppedUsingFont) {
       
  3260         dereferenceFont(priv, cmd->fontName);
       
  3261     }
       
  3262 }
       
  3263 
       
  3264 void QWSServerPrivate::invokeRepaintRegion(QWSRepaintRegionCommand * cmd,
       
  3265                                            QWSClient *)
       
  3266 {
       
  3267     QRegion r;
       
  3268     r.setRects(cmd->rectangles,cmd->simpleData.nrectangles);
       
  3269     repaint_region(cmd->simpleData.windowid, cmd->simpleData.windowFlags, cmd->simpleData.opaque, r);
       
  3270 }
       
  3271 
       
  3272 #ifndef QT_NO_QWSEMBEDWIDGET
       
  3273 void QWSServerPrivate::invokeEmbed(QWSEmbedCommand *cmd, QWSClient *client)
       
  3274 {
       
  3275     // Should find these two windows in a single loop
       
  3276     QWSWindow *embedder = findWindow(cmd->simpleData.embedder, client);
       
  3277     QWSWindow *embedded = findWindow(cmd->simpleData.embedded);
       
  3278 
       
  3279     if (!embedder) {
       
  3280         qWarning("QWSServer: Embed command from window %i failed: No such id.",
       
  3281                  static_cast<int>(cmd->simpleData.embedder));
       
  3282         return;
       
  3283     }
       
  3284 
       
  3285     if (!embedded) {
       
  3286         qWarning("QWSServer: Embed command on window %i failed: No such id.",
       
  3287                  static_cast<int>(cmd->simpleData.embedded));
       
  3288         return;
       
  3289     }
       
  3290 
       
  3291     switch (cmd->simpleData.type) {
       
  3292     case QWSEmbedEvent::StartEmbed:
       
  3293         embedder->startEmbed(embedded);
       
  3294         windows.removeAll(embedded);
       
  3295         windows.insert(windows.indexOf(embedder), embedded);
       
  3296         break;
       
  3297     case QWSEmbedEvent::StopEmbed:
       
  3298         embedder->stopEmbed(embedded);
       
  3299         break;
       
  3300     case QWSEmbedEvent::Region:
       
  3301         break;
       
  3302     }
       
  3303 
       
  3304     embedded->client()->sendEmbedEvent(embedded->winId(),
       
  3305                                        cmd->simpleData.type, cmd->region);
       
  3306     const QRegion oldAllocated = embedded->allocatedRegion();
       
  3307     update_regions();
       
  3308     exposeRegion(oldAllocated - embedded->allocatedRegion(),
       
  3309                  windows.indexOf(embedded));
       
  3310 }
       
  3311 #endif // QT_NO_QWSEMBEDWIDGET
       
  3312 
       
  3313 void QWSServerPrivate::invokeScreenTransform(const QWSScreenTransformCommand *cmd,
       
  3314                                              QWSClient *client)
       
  3315 {
       
  3316     Q_UNUSED(client);
       
  3317 
       
  3318     QWSScreenTransformationEvent event;
       
  3319     event.simpleData.screen = cmd->simpleData.screen;
       
  3320     event.simpleData.transformation = cmd->simpleData.transformation;
       
  3321 
       
  3322     QMap<int, QWSClient*>::const_iterator it = clientMap.constBegin();
       
  3323     for (; it != clientMap.constEnd(); ++it)
       
  3324         (*it)->sendEvent(&event);
       
  3325 }
       
  3326 
       
  3327 QWSWindow* QWSServerPrivate::newWindow(int id, QWSClient* client)
       
  3328 {
       
  3329     Q_Q(QWSServer);
       
  3330     // Make a new window, put it on top.
       
  3331     QWSWindow* w = new QWSWindow(id,client);
       
  3332 
       
  3333     // insert after "stays on top" windows
       
  3334     bool added = false;
       
  3335     for (int i = nReserved; i < windows.size(); ++i) {
       
  3336         QWSWindow *win = windows.at(i);
       
  3337         if (!win->onTop) {
       
  3338             windows.insert(i, w);
       
  3339             added = true;
       
  3340             break;
       
  3341         }
       
  3342     }
       
  3343     if (!added)
       
  3344         windows.append(w);
       
  3345     emit q->windowEvent(w, QWSServer::Create);
       
  3346     return w;
       
  3347 }
       
  3348 
       
  3349 QWSWindow* QWSServerPrivate::findWindow(int windowid, QWSClient* client)
       
  3350 {
       
  3351     for (int i=0; i<windows.size(); ++i) {
       
  3352         QWSWindow* w = windows.at(i);
       
  3353         if (w->winId() == windowid)
       
  3354             return w;
       
  3355     }
       
  3356     if (client)
       
  3357         return newWindow(windowid,client);
       
  3358     else
       
  3359         return 0;
       
  3360 }
       
  3361 
       
  3362 void QWSServerPrivate::raiseWindow(QWSWindow *changingw, int /*alt*/)
       
  3363 {
       
  3364     Q_Q(QWSServer);
       
  3365     if (changingw == windows.first())
       
  3366         return;
       
  3367     QWSWindow::State oldstate = changingw->d->state;
       
  3368     changingw->d->state = QWSWindow::Raising;
       
  3369     // Expose regions previously overlapped by transparent windows
       
  3370     const QRegion bound = changingw->allocatedRegion();
       
  3371     QRegion expose;
       
  3372     int windowPos = 0;
       
  3373 
       
  3374     //change position in list:
       
  3375     for (int i = 0; i < windows.size(); ++i) {
       
  3376         QWSWindow *w = windows.at(i);
       
  3377         if (w == changingw) {
       
  3378             windowPos = i;
       
  3379             windows.takeAt(i);
       
  3380             break;
       
  3381         }
       
  3382         if (!w->isOpaque())
       
  3383             expose += (w->allocatedRegion() & bound);
       
  3384     }
       
  3385 
       
  3386     bool onTop = changingw->onTop;
       
  3387 
       
  3388 #ifndef QT_NO_QWSEMBEDWIDGET
       
  3389     // an embedded window is on top if the embedder is on top
       
  3390     QWSWindow *embedder = changingw->d->embedder;
       
  3391     while (!onTop && embedder) {
       
  3392         onTop = embedder->onTop;
       
  3393         embedder = embedder->d->embedder;
       
  3394     }
       
  3395 #endif
       
  3396 
       
  3397     int newPos = -1;
       
  3398     if (onTop) {
       
  3399         windows.insert(nReserved, changingw);
       
  3400         newPos = nReserved;
       
  3401     } else {
       
  3402         // insert after "stays on top" windows
       
  3403         bool in = false;
       
  3404         for (int i = nReserved; i < windows.size(); ++i) {
       
  3405             QWSWindow *w = windows.at(i);
       
  3406             if (!w->onTop) {
       
  3407                 windows.insert(i, changingw);
       
  3408                 in = true;
       
  3409                 newPos = i;
       
  3410                 break;
       
  3411             }
       
  3412         }
       
  3413         if (!in) {
       
  3414             windows.append(changingw);
       
  3415             newPos = windows.size()-1;
       
  3416         }
       
  3417     }
       
  3418 
       
  3419     if (windowPos != newPos) {
       
  3420         update_regions();
       
  3421         if (!expose.isEmpty())
       
  3422             exposeRegion(expose, newPos);
       
  3423     }
       
  3424     changingw->d->state = oldstate;
       
  3425     emit q->windowEvent(changingw, QWSServer::Raise);
       
  3426 }
       
  3427 
       
  3428 void QWSServerPrivate::lowerWindow(QWSWindow *changingw, int /*alt*/)
       
  3429 {
       
  3430     Q_Q(QWSServer);
       
  3431     if (changingw == windows.last())
       
  3432         return;
       
  3433     QWSWindow::State oldstate = changingw->d->state;
       
  3434     changingw->d->state = QWSWindow::Lowering;
       
  3435 
       
  3436     int i = windows.indexOf(changingw);
       
  3437     int newIdx = windows.size()-1;
       
  3438     windows.move(i, newIdx);
       
  3439 
       
  3440     const QRegion bound = changingw->allocatedRegion();
       
  3441 
       
  3442     update_regions();
       
  3443 
       
  3444     // Expose regions previously overlapped by transparent window
       
  3445     if (!changingw->isOpaque()) {
       
  3446         QRegion expose;
       
  3447         for (int j = i; j < windows.size() - 1; ++j)
       
  3448             expose += (windows.at(j)->allocatedRegion() & bound);
       
  3449         if (!expose.isEmpty())
       
  3450             exposeRegion(expose, newIdx);
       
  3451     }
       
  3452 
       
  3453     changingw->d->state = oldstate;
       
  3454     emit q->windowEvent(changingw, QWSServer::Lower);
       
  3455 }
       
  3456 
       
  3457 void QWSServerPrivate::update_regions()
       
  3458 {
       
  3459     if (disablePainting)
       
  3460         return;
       
  3461 
       
  3462     QRegion available = QRect(0, 0, qt_screen->width(), qt_screen->height());
       
  3463     QRegion transparentRegion;
       
  3464 
       
  3465     // only really needed if there are unbuffered surfaces...
       
  3466     const bool doLock = (clientMap.size() > 1);
       
  3467     if (doLock)
       
  3468         QWSDisplay::grab(true);
       
  3469 
       
  3470     for (int i = 0; i < windows.count(); ++i) {
       
  3471         QWSWindow *w = windows.at(i);
       
  3472         QRegion r = (w->requested_region & available);
       
  3473 
       
  3474 #ifndef QT_NO_QWSEMBEDWIDGET
       
  3475         // Subtract regions needed for embedded windows
       
  3476         const int n = w->d->embedded.size();
       
  3477         for (int i = 0; i < n; ++i)
       
  3478             r -= w->d->embedded.at(i)->allocatedRegion();
       
  3479 
       
  3480         // Limited to the embedder region
       
  3481         if (w->d->embedder)
       
  3482             r &= w->d->embedder->requested_region;
       
  3483 #endif // QT_NO_QWSEMBEDWIDGET
       
  3484 
       
  3485         QWSWindowSurface *surface = w->windowSurface();
       
  3486         const bool opaque = w->isOpaque()
       
  3487                             && (w->d->painted || !surface || !surface->isBuffered());
       
  3488 
       
  3489         if (!opaque) {
       
  3490             transparentRegion += r;
       
  3491         } else {
       
  3492             if (surface && (surface->isRegionReserved() || !surface->isBuffered()))
       
  3493                 r -= transparentRegion;
       
  3494             available -= r;
       
  3495         }
       
  3496 
       
  3497         if (r != w->allocatedRegion()) {
       
  3498             w->setAllocatedRegion(r);
       
  3499             w->client()->sendRegionEvent(w->winId(), r,
       
  3500                                          QWSRegionEvent::Allocation);
       
  3501         }
       
  3502 
       
  3503 #ifdef QT_QWS_CLIENTBLIT
       
  3504 #ifdef QT_NO_QWS_CURSOR
       
  3505         // This optimization only really works when there isn't a crazy cursor
       
  3506         // wizzing around.
       
  3507         QRegion directPaint = (r - transparentRegion); // in gloal coords
       
  3508         if(directPaint != w->directPaintRegion()) {
       
  3509             w->setDirectPaintRegion(directPaint);
       
  3510             static int id = 0;
       
  3511             surface->setDirectRegion(directPaint, ++id);
       
  3512             w->client()->sendRegionEvent(w->winId(), directPaint,
       
  3513                                          QWSRegionEvent::DirectPaint, id);
       
  3514         }
       
  3515 #endif
       
  3516 #endif
       
  3517     }
       
  3518 
       
  3519     if (doLock)
       
  3520         QWSDisplay::ungrab();
       
  3521 }
       
  3522 
       
  3523 void QWSServerPrivate::moveWindowRegion(QWSWindow *changingw, int dx, int dy)
       
  3524 {
       
  3525     if (!changingw)
       
  3526         return;
       
  3527 
       
  3528     QWSWindow::State oldState = changingw->d->state;
       
  3529     changingw->d->state = QWSWindow::Moving;
       
  3530     const QRegion oldRegion(changingw->allocatedRegion());
       
  3531     changingw->requested_region.translate(dx, dy);
       
  3532 
       
  3533     // hw: Even if the allocated region doesn't change, the requested region
       
  3534     // region has changed and we need to send region events.
       
  3535     // Resetting the allocated region to force update_regions to send events.
       
  3536     changingw->setAllocatedRegion(QRegion());
       
  3537     update_regions();
       
  3538     const QRegion newRegion(changingw->allocatedRegion());
       
  3539 
       
  3540     QWSWindowSurface *surface = changingw->windowSurface();
       
  3541     QRegion expose;
       
  3542     if (surface)
       
  3543         expose = surface->move(QPoint(dx, dy), changingw->allocatedRegion());
       
  3544     else
       
  3545         expose = oldRegion + newRegion;
       
  3546 
       
  3547     if (!changingw->d->painted && !expose.isEmpty())
       
  3548         expose = oldRegion - newRegion;
       
  3549 
       
  3550     int idx = windows.indexOf(changingw);
       
  3551     exposeRegion(expose, idx);
       
  3552     changingw->d->state = oldState;
       
  3553 }
       
  3554 
       
  3555 /*!
       
  3556     Changes the requested region of window \a changingw to \a r
       
  3557     If \a changingw is 0, the server's reserved region is changed.
       
  3558 */
       
  3559 void QWSServerPrivate::setWindowRegion(QWSWindow* changingw, const QRegion &r)
       
  3560 {
       
  3561     if (!changingw) {
       
  3562         qWarning("Not implemented in this release");
       
  3563         return;
       
  3564     }
       
  3565 
       
  3566     if (changingw->requested_region == r)
       
  3567         return;
       
  3568 
       
  3569     const QRegion oldRegion(changingw->allocatedRegion());
       
  3570     changingw->requested_region = r;
       
  3571     update_regions();
       
  3572     const QRegion newRegion(changingw->allocatedRegion());
       
  3573 
       
  3574     int idx = windows.indexOf(changingw);
       
  3575     exposeRegion(oldRegion - newRegion, idx);
       
  3576 }
       
  3577 
       
  3578 
       
  3579 void QWSServerPrivate::exposeRegion(const QRegion &r, int changing)
       
  3580 {
       
  3581     if (disablePainting)
       
  3582         return;
       
  3583 
       
  3584     if (r.isEmpty())
       
  3585         return;
       
  3586 
       
  3587     static bool initial = true;
       
  3588     if (initial) {
       
  3589         changing = 0;
       
  3590         initial = false;
       
  3591         qt_screen->exposeRegion(qt_screen->region(), changing);
       
  3592     } else {
       
  3593         qt_screen->exposeRegion(r, changing);
       
  3594     }
       
  3595 }
       
  3596 
       
  3597 /*!
       
  3598     Closes all pointer devices (specified by the QWS_MOUSE_PROTO
       
  3599     environment variable) by deleting the associated mouse drivers.
       
  3600 
       
  3601     \sa openMouse(), mouseHandler()
       
  3602 */
       
  3603 void QWSServer::closeMouse()
       
  3604 {
       
  3605     Q_D(QWSServer);
       
  3606     qDeleteAll(d->mousehandlers);
       
  3607     d->mousehandlers.clear();
       
  3608 }
       
  3609 
       
  3610 /*!
       
  3611     Opens the mouse devices specified by the QWS_MOUSE_PROTO
       
  3612     environment variable. Be advised that closeMouse() is called first
       
  3613     to delete all the existing mouse handlers. This behaviour could be
       
  3614     the cause of problems if you were not expecting it.
       
  3615 
       
  3616     \sa closeMouse(), mouseHandler()
       
  3617 */
       
  3618 void QWSServer::openMouse()
       
  3619 {
       
  3620     Q_D(QWSServer);
       
  3621     QString mice = QString::fromLatin1(qgetenv("QWS_MOUSE_PROTO"));
       
  3622 #if defined(QT_QWS_CASSIOPEIA)
       
  3623     if (mice.isEmpty())
       
  3624         mice = QLatin1String("TPanel:/dev/tpanel");
       
  3625 #endif
       
  3626     if (mice.isEmpty())
       
  3627         mice = *defaultMouse();
       
  3628     closeMouse();
       
  3629     bool needviscurs = true;
       
  3630     if (mice != QLatin1String("None")) {
       
  3631         const QStringList mouse = mice.split(QLatin1Char(' '));
       
  3632         for (int i = mouse.size() - 1; i >= 0; --i) {
       
  3633             QWSMouseHandler *handler = d->newMouseHandler(mouse.at(i));
       
  3634             setMouseHandler(handler);
       
  3635             /* XXX handle mouse cursor visibility sensibly
       
  3636                if (!h->inherits("QCalibratedMouseHandler"))
       
  3637                needviscurs = true;
       
  3638             */
       
  3639         }
       
  3640     }
       
  3641 #ifndef QT_NO_QWS_CURSOR
       
  3642     setCursorVisible(needviscurs);
       
  3643 #else
       
  3644     Q_UNUSED(needviscurs)
       
  3645 #endif
       
  3646 }
       
  3647 
       
  3648 /*!
       
  3649     Suspends pointer handling by deactivating all the mouse drivers
       
  3650     registered by the QWS_MOUSE_PROTO environment variable.
       
  3651 
       
  3652 
       
  3653     \sa resumeMouse(), QWSMouseHandler::suspend()
       
  3654 */
       
  3655 void QWSServer::suspendMouse()
       
  3656 {
       
  3657     Q_D(QWSServer);
       
  3658     for (int i=0; i < d->mousehandlers.size(); ++i)
       
  3659         d->mousehandlers.at(i)->suspend();
       
  3660 }
       
  3661 
       
  3662 /*!
       
  3663     Resumes pointer handling by reactivating all the mouse drivers
       
  3664     registered by the QWS_MOUSE_PROTO environment variable.
       
  3665 
       
  3666     \sa suspendMouse(), QWSMouseHandler::resume()
       
  3667 */
       
  3668 void QWSServer::resumeMouse()
       
  3669 {
       
  3670     Q_D(QWSServer);
       
  3671     for (int i=0; i < d->mousehandlers.size(); ++i)
       
  3672         d->mousehandlers.at(i)->resume();
       
  3673 }
       
  3674 
       
  3675 
       
  3676 
       
  3677 QWSMouseHandler* QWSServerPrivate::newMouseHandler(const QString& spec)
       
  3678 {
       
  3679     int c = spec.indexOf(QLatin1Char(':'));
       
  3680     QString mouseProto;
       
  3681     QString mouseDev;
       
  3682     if (c >= 0) {
       
  3683         mouseProto = spec.left(c);
       
  3684         mouseDev = spec.mid(c+1);
       
  3685     } else {
       
  3686         mouseProto = spec;
       
  3687     }
       
  3688 
       
  3689     int screen = -1;
       
  3690     const QList<QRegExp> regexps = QList<QRegExp>()
       
  3691                                    << QRegExp(QLatin1String(":screen=(\\d+)\\b"))
       
  3692                                    << QRegExp(QLatin1String("\\bscreen=(\\d+):"));
       
  3693     for (int i = 0; i < regexps.size(); ++i) {
       
  3694         QRegExp regexp = regexps.at(i);
       
  3695         if (regexp.indexIn(mouseDev) == -1)
       
  3696             continue;
       
  3697         screen = regexp.cap(1).toInt();
       
  3698         mouseDev.remove(regexp.pos(0), regexp.matchedLength());
       
  3699         break;
       
  3700     }
       
  3701 
       
  3702     QWSMouseHandler *handler = 0;
       
  3703     handler = QMouseDriverFactory::create(mouseProto, mouseDev);
       
  3704     if (screen != -1)
       
  3705         handler->setScreen(qt_screen->subScreens().at(screen));
       
  3706 
       
  3707     return handler;
       
  3708 }
       
  3709 
       
  3710 #ifndef QT_NO_QWS_KEYBOARD
       
  3711 
       
  3712 /*!
       
  3713     Closes all the keyboard devices (specified by the QWS_KEYBOARD
       
  3714     environment variable) by deleting the associated keyboard
       
  3715     drivers.
       
  3716 
       
  3717     \sa openKeyboard(),  keyboardHandler()
       
  3718 */
       
  3719 void QWSServer::closeKeyboard()
       
  3720 {
       
  3721     Q_D(QWSServer);
       
  3722     qDeleteAll(d->keyboardhandlers);
       
  3723     d->keyboardhandlers.clear();
       
  3724 }
       
  3725 
       
  3726 /*!
       
  3727     Returns the primary keyboard driver.
       
  3728 
       
  3729     Note that this function can only be used in the server process.
       
  3730 
       
  3731     \sa setKeyboardHandler(), openKeyboard(), closeKeyboard()
       
  3732 */
       
  3733 QWSKeyboardHandler* QWSServer::keyboardHandler()
       
  3734 {
       
  3735     return qwsServerPrivate->keyboardhandlers.first();
       
  3736 }
       
  3737 
       
  3738 /*!
       
  3739     \fn void QWSServer::setKeyboardHandler(QWSKeyboardHandler* driver)
       
  3740 
       
  3741     Sets the primary keyboard driver to be the given \a driver.
       
  3742 
       
  3743     \l{Qt for Embedded Linux} provides several ready-made keyboard drivers, and
       
  3744     custom drivers are typically added using Qt's plugin
       
  3745     mechanism. See the \l{Qt for Embedded Linux Character Input} documentation
       
  3746     for details.
       
  3747 
       
  3748     Note that this function can only be used in the server process.
       
  3749 
       
  3750     \sa keyboardHandler(), setDefaultKeyboard()
       
  3751 */
       
  3752 void QWSServer::setKeyboardHandler(QWSKeyboardHandler* kh)
       
  3753 {
       
  3754     if (!kh)
       
  3755         return;
       
  3756     qwsServerPrivate->keyboardhandlers.removeAll(kh);
       
  3757     qwsServerPrivate->keyboardhandlers.prepend(kh);
       
  3758 }
       
  3759 
       
  3760 /*!
       
  3761     Opens the keyboard devices specified by the QWS_KEYBOARD
       
  3762     environment variable.
       
  3763 
       
  3764     \sa closeKeyboard(), keyboardHandler()
       
  3765 */
       
  3766 void QWSServer::openKeyboard()
       
  3767 {
       
  3768     QString keyboards = QString::fromLatin1(qgetenv("QWS_KEYBOARD"));
       
  3769 #if defined(QT_QWS_CASSIOPEIA)
       
  3770     if (keyboards.isEmpty())
       
  3771         keyboards = QLatin1String("Buttons");
       
  3772 #endif
       
  3773     if (keyboards.isEmpty())
       
  3774         keyboards = *defaultKeyboard();
       
  3775 
       
  3776     closeKeyboard();
       
  3777     if (keyboards == QLatin1String("None"))
       
  3778         return;
       
  3779 
       
  3780     QString device;
       
  3781     QString type;
       
  3782     QStringList keyboard = keyboards.split(QLatin1Char(' '));
       
  3783     for (int i = keyboard.size() - 1; i >= 0; --i) {
       
  3784         const QString spec = keyboard.at(i);
       
  3785         int colon=spec.indexOf(QLatin1Char(':'));
       
  3786         if (colon>=0) {
       
  3787             type = spec.left(colon);
       
  3788             device = spec.mid(colon+1);
       
  3789         } else {
       
  3790             type = spec;
       
  3791             device = QString();
       
  3792         }
       
  3793         QWSKeyboardHandler *handler = QKbdDriverFactory::create(type, device);
       
  3794         setKeyboardHandler(handler);
       
  3795     }
       
  3796 }
       
  3797 
       
  3798 #endif //QT_NO_QWS_KEYBOARD
       
  3799 
       
  3800 QPoint QWSServer::mousePosition;
       
  3801 QBrush *QWSServerPrivate::bgBrush = 0;
       
  3802 
       
  3803 void QWSServerPrivate::move_region(const QWSRegionMoveCommand *cmd)
       
  3804 {
       
  3805     QWSClient *serverClient = clientMap.value(-1);
       
  3806     invokeRegionMove(cmd, serverClient);
       
  3807 }
       
  3808 
       
  3809 void QWSServerPrivate::set_altitude(const QWSChangeAltitudeCommand *cmd)
       
  3810 {
       
  3811     QWSClient *serverClient = clientMap.value(-1);
       
  3812     invokeSetAltitude(cmd, serverClient);
       
  3813 }
       
  3814 
       
  3815 void QWSServerPrivate::set_opacity(const QWSSetOpacityCommand *cmd)
       
  3816 {
       
  3817     QWSClient *serverClient = clientMap.value(-1);
       
  3818     invokeSetOpacity(cmd, serverClient);
       
  3819 }
       
  3820 
       
  3821 
       
  3822 void QWSServerPrivate::request_focus(const QWSRequestFocusCommand *cmd)
       
  3823 {
       
  3824     invokeSetFocus(cmd, clientMap.value(-1));
       
  3825 }
       
  3826 
       
  3827 void QWSServerPrivate::set_identity(const QWSIdentifyCommand *cmd)
       
  3828 {
       
  3829     invokeIdentify(cmd, clientMap.value(-1));
       
  3830 }
       
  3831 
       
  3832 void QWSServerPrivate::repaint_region(int wid, int windowFlags, bool opaque,
       
  3833                                       const QRegion &region)
       
  3834 {
       
  3835     QWSWindow* changingw = findWindow(wid, 0);
       
  3836     if (!changingw) {
       
  3837         return;
       
  3838     }
       
  3839 
       
  3840     const bool isOpaque = changingw->opaque;
       
  3841     const bool wasPainted = changingw->d->painted;
       
  3842     changingw->opaque = opaque;
       
  3843     changingw->d->windowFlags = QFlag(windowFlags);
       
  3844     changingw->d->dirtyOnScreen |= region;
       
  3845     changingw->d->painted = true;
       
  3846     if (isOpaque != opaque || !wasPainted)
       
  3847         update_regions();
       
  3848 
       
  3849     int level = windows.indexOf(changingw);
       
  3850     exposeRegion(region, level);
       
  3851     changingw->d->dirtyOnScreen = QRegion();
       
  3852 }
       
  3853 
       
  3854 QRegion QWSServerPrivate::reserve_region(QWSWindow *win, const QRegion &region)
       
  3855 {
       
  3856     QRegion r = region;
       
  3857 
       
  3858     int oldPos = windows.indexOf(win);
       
  3859     int newPos = oldPos < nReserved ? nReserved - 1 : nReserved;
       
  3860     for (int i = 0; i < nReserved; ++i) {
       
  3861         if (i != oldPos) {
       
  3862             QWSWindow *w = windows.at(i);
       
  3863             r -= w->requested_region;
       
  3864         }
       
  3865     }
       
  3866     windows.move(oldPos, newPos);
       
  3867     nReserved = newPos + 1;
       
  3868 
       
  3869     return r;
       
  3870 }
       
  3871 
       
  3872 void QWSServerPrivate::request_region(int wid, const QString &surfaceKey,
       
  3873                                       const QByteArray &surfaceData,
       
  3874                                       const QRegion &region)
       
  3875 {
       
  3876     QWSWindow *changingw = findWindow(wid, 0);
       
  3877     if (!changingw)
       
  3878         return;
       
  3879 
       
  3880     Q_Q(QWSServer);
       
  3881     QWSWindow::State windowState = QWSWindow::NoState;
       
  3882 
       
  3883     if (region.isEmpty()) {
       
  3884         windowState = QWSWindow::Hiding;
       
  3885         emit q->windowEvent(changingw, QWSServer::Hide);
       
  3886     }
       
  3887 
       
  3888     const bool wasOpaque = changingw->opaque;
       
  3889 
       
  3890     changingw->createSurface(surfaceKey, surfaceData);
       
  3891     QWSWindowSurface *surface = changingw->windowSurface();
       
  3892 
       
  3893     changingw->opaque = surface->isOpaque();
       
  3894 
       
  3895     QRegion r;
       
  3896     if (surface->isRegionReserved())
       
  3897         r = reserve_region(changingw, region);
       
  3898     else
       
  3899         r = region;
       
  3900 
       
  3901     if (!region.isEmpty())  {
       
  3902         if (changingw->isVisible())
       
  3903             windowState = QWSWindow::ChangingGeometry;
       
  3904         else
       
  3905             windowState = QWSWindow::Showing;
       
  3906     }
       
  3907     changingw->d->state = windowState;
       
  3908 
       
  3909     if (!r.isEmpty() && wasOpaque != changingw->opaque && surface->isBuffered())
       
  3910         changingw->requested_region = QRegion(); // XXX: force update_regions
       
  3911 
       
  3912     const QRegion oldAllocated = changingw->allocatedRegion();
       
  3913     setWindowRegion(changingw, r);
       
  3914     if (oldAllocated == changingw->allocatedRegion()) {
       
  3915         // Always send region event to the requesting window even if the
       
  3916         // region didn't change. This is necessary as the client will reset
       
  3917         // the clip region until an event is received.
       
  3918         changingw->client()->sendRegionEvent(wid, changingw->allocatedRegion(),
       
  3919                                              QWSRegionEvent::Allocation);
       
  3920     }
       
  3921 
       
  3922     surface->QWindowSurface::setGeometry(r.boundingRect());
       
  3923 
       
  3924     if (windowState == QWSWindow::Showing)
       
  3925         emit q->windowEvent(changingw, QWSServer::Show);
       
  3926     else if (windowState == QWSWindow::ChangingGeometry)
       
  3927         emit q->windowEvent(changingw, QWSServer::Geometry);
       
  3928     if (windowState == QWSWindow::Hiding) {
       
  3929         handleWindowClose(changingw);
       
  3930         changingw->d->state = QWSWindow::Hidden;
       
  3931         changingw->d->painted = false;
       
  3932     } else {
       
  3933         changingw->d->state = QWSWindow::Visible;
       
  3934     }
       
  3935 }
       
  3936 
       
  3937 void QWSServerPrivate::destroy_region(const QWSRegionDestroyCommand *cmd)
       
  3938 {
       
  3939     invokeRegionDestroy(cmd, clientMap.value(-1));
       
  3940 }
       
  3941 
       
  3942 void QWSServerPrivate::name_region(const QWSRegionNameCommand *cmd)
       
  3943 {
       
  3944     invokeRegionName(cmd, clientMap.value(-1));
       
  3945 }
       
  3946 
       
  3947 #ifndef QT_NO_QWS_INPUTMETHODS
       
  3948 void QWSServerPrivate::im_response(const QWSIMResponseCommand *cmd)
       
  3949  {
       
  3950      invokeIMResponse(cmd, clientMap.value(-1));
       
  3951 }
       
  3952 
       
  3953 void QWSServerPrivate::im_update(const QWSIMUpdateCommand *cmd)
       
  3954 {
       
  3955     invokeIMUpdate(cmd, clientMap.value(-1));
       
  3956 }
       
  3957 
       
  3958 void QWSServerPrivate::send_im_mouse(const QWSIMMouseCommand *cmd)
       
  3959 {
       
  3960     if (current_IM)
       
  3961         current_IM->mouseHandler(cmd->simpleData.index, cmd->simpleData.state);
       
  3962 }
       
  3963 #endif
       
  3964 
       
  3965 void QWSServerPrivate::openDisplay()
       
  3966 {
       
  3967     qt_init_display();
       
  3968 
       
  3969 //    rgnMan = qt_fbdpy->regionManager();
       
  3970     swidth = qt_screen->deviceWidth();
       
  3971     sheight = qt_screen->deviceHeight();
       
  3972 }
       
  3973 
       
  3974 void QWSServerPrivate::closeDisplay()
       
  3975 {
       
  3976     if (qt_screen)
       
  3977         qt_screen->shutdownDevice();
       
  3978 }
       
  3979 
       
  3980 /*!
       
  3981     Returns the brush used as background in the absence of obscuring
       
  3982     windows.
       
  3983 
       
  3984     \sa setBackground()
       
  3985 */
       
  3986 const QBrush &QWSServer::backgroundBrush() const
       
  3987 {
       
  3988     return *QWSServerPrivate::bgBrush;
       
  3989 }
       
  3990 
       
  3991 /*!
       
  3992     Sets the brush used as background in the absence of obscuring
       
  3993     windows, to be the given \a brush.
       
  3994 
       
  3995     Note that this function can only be used in the server process.
       
  3996 
       
  3997     \sa backgroundBrush()
       
  3998 */
       
  3999 void QWSServer::setBackground(const QBrush &brush)
       
  4000 {
       
  4001     if (!QWSServerPrivate::bgBrush)
       
  4002         QWSServerPrivate::bgBrush = new QBrush(brush);
       
  4003     else
       
  4004         *QWSServerPrivate::bgBrush = brush;
       
  4005     if (!qwsServer)
       
  4006         return;
       
  4007     qt_screen->exposeRegion(QRect(0,0,qt_screen->width(), qt_screen->height()), 0);
       
  4008 }
       
  4009 
       
  4010 
       
  4011 #ifdef QT3_SUPPORT
       
  4012 /*!
       
  4013     \fn void QWSServer::setDesktopBackground(const QImage &image)
       
  4014 
       
  4015     Sets the image used as background in the absence of obscuring
       
  4016     windows, to be the given \a image.
       
  4017 
       
  4018     Use the setBackground() function instead.
       
  4019 
       
  4020     \oldcode
       
  4021         QImage image;
       
  4022         setDesktopBackground(image);
       
  4023     \newcode
       
  4024         QImage image;
       
  4025         setBackground(QBrush(image));
       
  4026     \endcode
       
  4027 */
       
  4028 void QWSServer::setDesktopBackground(const QImage &img)
       
  4029 {
       
  4030     if (img.isNull())
       
  4031         setBackground(Qt::NoBrush);
       
  4032     else
       
  4033         setBackground(QBrush(QPixmap::fromImage(img)));
       
  4034 }
       
  4035 
       
  4036 /*!
       
  4037     \fn void QWSServer::setDesktopBackground(const QColor &color)
       
  4038     \overload
       
  4039 
       
  4040     Sets the color used as background in the absence of obscuring
       
  4041     windows, to be the given \a color.
       
  4042 
       
  4043     Use the setBackground() function instead.
       
  4044 
       
  4045     \oldcode
       
  4046         QColor color;
       
  4047         setDesktopBackground(color);
       
  4048     \newcode
       
  4049         QColor color;
       
  4050         setBackground(QBrush(color));
       
  4051     \endcode
       
  4052 */
       
  4053 void QWSServer::setDesktopBackground(const QColor &c)
       
  4054 {
       
  4055     setBackground(QBrush(c));
       
  4056 }
       
  4057 #endif //QT3_SUPPORT
       
  4058 
       
  4059 /*!
       
  4060   \internal
       
  4061  */
       
  4062 void QWSServer::startup(int flags)
       
  4063 {
       
  4064     if (qwsServer)
       
  4065         return;
       
  4066     unlink(qws_qtePipeFilename().toLatin1().constData());
       
  4067     (void)new QWSServer(flags);
       
  4068 }
       
  4069 
       
  4070 /*!
       
  4071   \internal
       
  4072 */
       
  4073 
       
  4074 void QWSServer::closedown()
       
  4075 {
       
  4076     QScopedPointer<QWSServer> server(qwsServer);
       
  4077     qwsServer = 0;
       
  4078     QT_TRY {
       
  4079         unlink(qws_qtePipeFilename().toLatin1().constData());
       
  4080     } QT_CATCH(const std::bad_alloc &) {
       
  4081         // ### TODO - what to do when we run out of memory
       
  4082         // when calling toLatin1?
       
  4083     }
       
  4084 }
       
  4085 
       
  4086 void QWSServerPrivate::emergency_cleanup()
       
  4087 {
       
  4088 #ifndef QT_NO_QWS_KEYBOARD
       
  4089     if (qwsServer)
       
  4090         qwsServer->closeKeyboard();
       
  4091 #endif
       
  4092 }
       
  4093 
       
  4094 #ifndef QT_NO_QWS_KEYBOARD
       
  4095 static QList<QWSServer::KeyboardFilter*> *keyFilters = 0;
       
  4096 
       
  4097 /*!
       
  4098     Processes the given key event. The key is identified by its \a
       
  4099     unicode value and the given \a keycode, \a modifiers, \a isPress
       
  4100     and \a autoRepeat parameters.
       
  4101 
       
  4102     The \a keycode parameter is the Qt keycode value as defined by the
       
  4103     Qt::Key enum. The \a modifiers is an OR combination of
       
  4104     Qt::KeyboardModifier values, indicating whether \gui
       
  4105     Shift/Alt/Ctrl keys are pressed. The \a isPress parameter is true
       
  4106     if the event is a key press event and \a autoRepeat is true if the
       
  4107     event is caused by an auto-repeat mechanism and not an actual key
       
  4108     press.
       
  4109 
       
  4110     This function is typically called internally by keyboard drivers.
       
  4111     Note that this function can only be used in the server process.
       
  4112 
       
  4113     \sa sendKeyEvent(), {Qt for Embedded Linux Character Input}
       
  4114 */
       
  4115 void QWSServer::processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
       
  4116                                 bool isPress, bool autoRepeat)
       
  4117 {
       
  4118     bool block;
       
  4119     // Don't block the POWER or LIGHT keys
       
  4120     if ( keycode == Qt::Key_F34 || keycode == Qt::Key_F35 )
       
  4121         block = false;
       
  4122     else
       
  4123         block = qwsServerPrivate->screensaverblockevent(KEY, qwsServerPrivate->screensaverinterval, isPress);
       
  4124 
       
  4125 #ifdef EVENT_BLOCK_DEBUG
       
  4126     qDebug() << "processKeyEvent" << unicode << keycode << modifiers << isPress << autoRepeat << (block ? "block" : "pass");
       
  4127 #endif
       
  4128 
       
  4129     // If we press a key and it's going to be blocked, wake up the screen
       
  4130     if ( block && isPress )
       
  4131         qwsServerPrivate->_q_screenSaverWake();
       
  4132 
       
  4133     if ( block )
       
  4134         return;
       
  4135 
       
  4136     if (keyFilters) {
       
  4137         for (int i = 0; i < keyFilters->size(); ++i) {
       
  4138             QWSServer::KeyboardFilter *keyFilter = keyFilters->at(i);
       
  4139             if (keyFilter->filter(unicode, keycode, modifiers, isPress, autoRepeat))
       
  4140                 return;
       
  4141         }
       
  4142     }
       
  4143     sendKeyEvent(unicode, keycode, modifiers, isPress, autoRepeat);
       
  4144 }
       
  4145 
       
  4146 /*!
       
  4147     \fn void QWSServer::addKeyboardFilter(KeyboardFilter *filter)
       
  4148 
       
  4149     Activates the given keyboard \a filter all key events generated by
       
  4150     physical keyboard drivers (i.e., events sent using the
       
  4151     processKeyEvent() function).
       
  4152 
       
  4153     Note that the filter is not invoked for keys generated by \e
       
  4154     virtual keyboard drivers (i.e., events sent using the
       
  4155     sendKeyEvent() function).
       
  4156 
       
  4157     Note that this function can only be used in the server process.
       
  4158 
       
  4159     \sa removeKeyboardFilter()
       
  4160 */
       
  4161 void QWSServer::addKeyboardFilter(KeyboardFilter *f)
       
  4162 {
       
  4163      if (!keyFilters)
       
  4164         keyFilters = new QList<QWSServer::KeyboardFilter*>;
       
  4165      if (f) {
       
  4166         keyFilters->prepend(f);
       
  4167      }
       
  4168 }
       
  4169 
       
  4170 /*
       
  4171 //#######
       
  4172  We should probably obsolete the whole keyboard filter thing since
       
  4173  it's not useful for input methods anyway
       
  4174 
       
  4175  We could do removeKeyboardFilter(KeyboardFilter *f), but
       
  4176  the "remove and delete the filter" concept does not match "user
       
  4177  remembers the pointer".
       
  4178 */
       
  4179 
       
  4180 /*!
       
  4181     Removes and deletes the most recently added filter.
       
  4182 
       
  4183     Note that the programmer is responsible for removing each added
       
  4184     keyboard filter.
       
  4185 
       
  4186     Note that this function can only be used in the server process.
       
  4187 
       
  4188     \sa addKeyboardFilter()
       
  4189 */
       
  4190 void QWSServer::removeKeyboardFilter()
       
  4191 {
       
  4192      if (!keyFilters || keyFilters->isEmpty())
       
  4193          return;
       
  4194      delete keyFilters->takeAt(0);
       
  4195 }
       
  4196 #endif // QT_NO_QWS_KEYBOARD
       
  4197 
       
  4198 /*!
       
  4199     \fn void QWSServer::setScreenSaverIntervals(int* intervals)
       
  4200 
       
  4201     Specifies the time \a intervals (in milliseconds) between the
       
  4202     different levels of screen responsiveness.
       
  4203 
       
  4204     \l{Qt for Embedded Linux} supports multilevel screen saving, i.e., it is
       
  4205     possible to specify several different levels of screen
       
  4206     responsiveness by implementing the QWSScreenSaver::save()
       
  4207     function. For example, you can choose to first turn off the light
       
  4208     before you fully activate the screensaver. See the QWSScreenSaver
       
  4209     documentation for details.
       
  4210 
       
  4211     Note that an interval of 0 milliseconds will turn off the
       
  4212     screensaver, and that the \a intervals array must be 0-terminated.
       
  4213     This function can only be used in the server process.
       
  4214 
       
  4215     \sa setScreenSaverInterval(), setScreenSaverBlockLevel()
       
  4216 */
       
  4217 void QWSServer::setScreenSaverIntervals(int* ms)
       
  4218 {
       
  4219     if (!qwsServerPrivate)
       
  4220         return;
       
  4221 
       
  4222     delete [] qwsServerPrivate->screensaverintervals;
       
  4223     if (ms) {
       
  4224         int* t=ms;
       
  4225         int n=0;
       
  4226         while (*t++) n++;
       
  4227         if (n) {
       
  4228             n++; // the 0
       
  4229             qwsServerPrivate->screensaverintervals = new int[n];
       
  4230             memcpy(qwsServerPrivate->screensaverintervals, ms, n*sizeof(int));
       
  4231         } else {
       
  4232             qwsServerPrivate->screensaverintervals = 0;
       
  4233         }
       
  4234     } else {
       
  4235         qwsServerPrivate->screensaverintervals = 0;
       
  4236     }
       
  4237     qwsServerPrivate->screensaverinterval = 0;
       
  4238 
       
  4239     qwsServerPrivate->screensavertimer->stop();
       
  4240     qt_screen->blank(false);
       
  4241     qwsServerPrivate->_q_screenSaverWake();
       
  4242 }
       
  4243 
       
  4244 /*!
       
  4245     \fn void QWSServer::setScreenSaverInterval(int milliseconds)
       
  4246 
       
  4247     Sets the timeout interval for the screensaver to the specified \a
       
  4248     milliseconds. To turn off the screensaver, set the timout interval
       
  4249     to 0.
       
  4250 
       
  4251     Note that this function can only be used in the server process.
       
  4252 
       
  4253     \sa setScreenSaverIntervals(), setScreenSaverBlockLevel()
       
  4254 */
       
  4255 void QWSServer::setScreenSaverInterval(int ms)
       
  4256 {
       
  4257     int v[2];
       
  4258     v[0] = ms;
       
  4259     v[1] = 0;
       
  4260     setScreenSaverIntervals(v);
       
  4261 }
       
  4262 
       
  4263 /*!
       
  4264   Block the key or mouse event that wakes the system from level \a eventBlockLevel or higher.
       
  4265   To completely disable event blocking (the default behavior), set \a eventBlockLevel to -1.
       
  4266 
       
  4267   The algorithm blocks the "down", "up" as well as any "repeat" events for the same key
       
  4268   but will not block other key events after the initial "down" event. For mouse events, the
       
  4269   algorithm blocks all mouse events until an event with no buttons pressed is received.
       
  4270 
       
  4271   There are 2 keys that are never blocked, Qt::Key_F34 (POWER) and Qt::Key_F35 (LIGHT).
       
  4272 
       
  4273   Example usage:
       
  4274 
       
  4275   \snippet doc/src/snippets/code/src_gui_embedded_qwindowsystem_qws.cpp 0
       
  4276 
       
  4277     Note that this function can only be used in the server process.
       
  4278 
       
  4279   \sa setScreenSaverIntervals(), setScreenSaverInterval()
       
  4280 */
       
  4281 void QWSServer::setScreenSaverBlockLevel(int eventBlockLevel)
       
  4282 {
       
  4283     if (!qwsServerPrivate)
       
  4284         return;
       
  4285     qwsServerPrivate->screensavereventblocklevel = eventBlockLevel;
       
  4286 #ifdef EVENT_BLOCK_DEBUG
       
  4287     qDebug() << "QWSServer::setScreenSaverBlockLevel() " << eventBlockLevel;
       
  4288 #endif
       
  4289 }
       
  4290 
       
  4291 extern bool qt_disable_lowpriority_timers; //in qeventloop_unix.cpp
       
  4292 
       
  4293 void QWSServerPrivate::_q_screenSaverWake()
       
  4294 {
       
  4295     if (screensaverintervals) {
       
  4296         if (screensaverinterval != screensaverintervals) {
       
  4297             if (saver) saver->restore();
       
  4298             screensaverinterval = screensaverintervals;
       
  4299             screensaverblockevents = false;
       
  4300         } else {
       
  4301             if (!screensavertimer->isActive()) {
       
  4302                 qt_screen->blank(false);
       
  4303                 if (saver) saver->restore();
       
  4304             }
       
  4305         }
       
  4306         screensavertimer->start(*screensaverinterval);
       
  4307         screensavertime.start();
       
  4308     }
       
  4309     qt_disable_lowpriority_timers=false;
       
  4310 }
       
  4311 
       
  4312 void QWSServerPrivate::_q_screenSaverSleep()
       
  4313 {
       
  4314     qt_screen->blank(true);
       
  4315 #if !defined(QT_QWS_IPAQ) && !defined(QT_QWS_EBX)
       
  4316     screensavertimer->stop();
       
  4317 #else
       
  4318     if (screensaverinterval) {
       
  4319         screensavertimer->start(*screensaverinterval);
       
  4320         screensavertime.start();
       
  4321     } else {
       
  4322         screensavertimer->stop();
       
  4323     }
       
  4324 #endif
       
  4325     qt_disable_lowpriority_timers=true;
       
  4326 }
       
  4327 
       
  4328 /*!
       
  4329     \fn void QWSServer::setScreenSaver(QWSScreenSaver* screenSaver)
       
  4330 
       
  4331     Installs the given \a screenSaver, deleting the current screen
       
  4332     saver.
       
  4333 
       
  4334     Note that this function can only be used in the server process.
       
  4335 
       
  4336     \sa screenSaverActivate(), setScreenSaverInterval(), setScreenSaverIntervals(), setScreenSaverBlockLevel()
       
  4337 */
       
  4338 void QWSServer::setScreenSaver(QWSScreenSaver* ss)
       
  4339 {
       
  4340     QWSServerPrivate *qd = qwsServer->d_func();
       
  4341     delete qd->saver;
       
  4342     qd->saver = ss;
       
  4343 }
       
  4344 
       
  4345 void QWSServerPrivate::screenSave(int level)
       
  4346 {
       
  4347     if (saver) {
       
  4348         // saver->save() may call QCoreApplication::processEvents,
       
  4349         // block event before calling saver->save().
       
  4350         bool oldScreensaverblockevents = screensaverblockevents;
       
  4351         if (*screensaverinterval >= 1000) {
       
  4352             screensaverblockevents = (screensavereventblocklevel >= 0 && screensavereventblocklevel <= level);
       
  4353 #ifdef EVENT_BLOCK_DEBUG
       
  4354             if (screensaverblockevents)
       
  4355                 qDebug("ready to block events");
       
  4356 #endif
       
  4357         }
       
  4358         int *oldScreensaverinterval = screensaverinterval;
       
  4359         if (saver->save(level)) {
       
  4360             // only update screensaverinterval if it hasn't already changed
       
  4361             if (oldScreensaverinterval == screensaverinterval) {
       
  4362                 if (screensaverinterval && screensaverinterval[1]) {
       
  4363                     screensavertimer->start(*++screensaverinterval);
       
  4364                     screensavertime.start();
       
  4365                 } else {
       
  4366                     screensaverinterval = 0;
       
  4367                 }
       
  4368             }
       
  4369         } else {
       
  4370             // restore previous state
       
  4371             screensaverblockevents = oldScreensaverblockevents;
       
  4372 
       
  4373             // for some reason, the saver don't want us to change to the
       
  4374             // next level, so we'll stay at this level for another interval
       
  4375             if (screensaverinterval && *screensaverinterval) {
       
  4376                 screensavertimer->start(*screensaverinterval);
       
  4377                 screensavertime.start();
       
  4378             }
       
  4379         }
       
  4380     } else {
       
  4381         screensaverinterval = 0;//screensaverintervals;
       
  4382         screensaverblockevents = false;
       
  4383         _q_screenSaverSleep();
       
  4384     }
       
  4385 }
       
  4386 
       
  4387 void QWSServerPrivate::_q_screenSaverTimeout()
       
  4388 {
       
  4389     if (screensaverinterval) {
       
  4390         if (screensavertime.elapsed() > *screensaverinterval*2) {
       
  4391             // bogus (eg. unsuspend, system time changed)
       
  4392             _q_screenSaverWake(); // try again
       
  4393             return;
       
  4394         }
       
  4395         screenSave(screensaverinterval - screensaverintervals);
       
  4396     }
       
  4397 }
       
  4398 
       
  4399 /*!
       
  4400     Returns true if the screen saver is active; otherwise returns
       
  4401     false.
       
  4402 
       
  4403     Note that this function can only be used in the server process.
       
  4404 
       
  4405     \sa screenSaverActivate()
       
  4406 */
       
  4407 bool QWSServer::screenSaverActive()
       
  4408 {
       
  4409     return qwsServerPrivate->screensaverinterval
       
  4410         && !qwsServerPrivate->screensavertimer->isActive();
       
  4411 }
       
  4412 
       
  4413 /*!
       
  4414     \internal
       
  4415 */
       
  4416 void QWSServer::updateWindowRegions() const
       
  4417 {
       
  4418     qwsServerPrivate->update_regions();
       
  4419 }
       
  4420 
       
  4421 /*!
       
  4422     Activates the screen saver if \a activate is true; otherwise it is
       
  4423     deactivated.
       
  4424 
       
  4425     Note that this function can only be used in the server process.
       
  4426 
       
  4427     \sa screenSaverActive(), setScreenSaver()
       
  4428 */
       
  4429 void QWSServer::screenSaverActivate(bool activate)
       
  4430 {
       
  4431     if (activate)
       
  4432         qwsServerPrivate->_q_screenSaverSleep();
       
  4433     else
       
  4434         qwsServerPrivate->_q_screenSaverWake();
       
  4435 }
       
  4436 
       
  4437 void QWSServerPrivate::disconnectClient(QWSClient *c)
       
  4438 {
       
  4439     QTimer::singleShot(0, c, SLOT(closeHandler()));
       
  4440 }
       
  4441 
       
  4442 void QWSServerPrivate::updateClientCursorPos()
       
  4443 {
       
  4444     Q_Q(QWSServer);
       
  4445     QWSWindow *win = qwsServerPrivate->mouseGrabber ? qwsServerPrivate->mouseGrabber : qwsServer->windowAt(QWSServer::mousePosition);
       
  4446     QWSClient *winClient = win ? win->client() : 0;
       
  4447     if (winClient && winClient != cursorClient)
       
  4448         q->sendMouseEvent(QWSServer::mousePosition, mouseState);
       
  4449 }
       
  4450 
       
  4451 #ifndef QT_NO_QWS_INPUTMETHODS
       
  4452 
       
  4453 /*!
       
  4454     \class QWSInputMethod
       
  4455     \preliminary
       
  4456     \ingroup qws
       
  4457 
       
  4458     \brief The QWSInputMethod class provides international input methods
       
  4459     in Qt for Embedded Linux.
       
  4460 
       
  4461     Note that this class is only available in \l{Qt for Embedded Linux}.
       
  4462 
       
  4463     A \l{Qt for Embedded Linux} application requires a server application to be
       
  4464     running, or to be the server application itself. All system
       
  4465     generated events, including keyboard and mouse events, are passed
       
  4466     to the server application which then propagates the event to the
       
  4467     appropriate client.
       
  4468 
       
  4469     An input method consists of a filter and optionally a graphical
       
  4470     interface, and is used to filter input events between the server
       
  4471     and the client application.
       
  4472 
       
  4473     \tableofcontents
       
  4474 
       
  4475     \section1 Creating Custom Input Methods
       
  4476 
       
  4477     To implement a custom input method, derive from the QWSInputMethod
       
  4478     class, and use the server's \l
       
  4479     {QWSServer::}{setCurrentInputMethod()} function to install it.
       
  4480 
       
  4481     When subclassing QWSInputMethod, you can reimplement the filter()
       
  4482     functions to handle input from both physical and virtual keyboards
       
  4483     as well as mouse devices. Note that the default implementations do
       
  4484     nothing. Use the setInputResolution() function to control the
       
  4485     number of bits shifted when filtering mouse input, i.e., when
       
  4486     going from pointer resolution to screen resolution (the current
       
  4487     resolution can be retrieved using the inputResolutionShift()
       
  4488     function).
       
  4489 
       
  4490     Reimplement the reset() function to restore the state of the input
       
  4491     method. Note that the default implementation calls the sendEvent()
       
  4492     function with empty preedit and commit strings if the input method
       
  4493     is in compose mode (i.e., if the input method is actively
       
  4494     composing a preedit string).
       
  4495 
       
  4496     To receive replies to an input method query (sent using the
       
  4497     sendQuery() function), you must reimplement the queryResponse()
       
  4498     function, while the mouseHandler() function must be reimplemented
       
  4499     if you want to handle mouse events within the preedit
       
  4500     text. Reimplement the updateHandler() function to handle update
       
  4501     events including resets and focus changes. The UpdateType enum
       
  4502     describes the various types of update events recognized by the
       
  4503     input method.
       
  4504 
       
  4505     \section1 Using Input Methods
       
  4506 
       
  4507     In addition to the filter(), reset(), queryResponse(),
       
  4508     mouseHandler() and updateHandler() function mentioned in the
       
  4509     previous section, the QWSInputMethod provides several other
       
  4510     functions helping the window system to manage the installed input
       
  4511     methods.
       
  4512 
       
  4513     The sendEvent() function sends the given event to the focus
       
  4514     widget, while the sendPreeditString() function sends the given
       
  4515     preedit text (encapsulated by an event). QWSInputMethod also
       
  4516     provides the sendCommitString() convenience function which sends
       
  4517     an event encapsulating the given commit string to the current
       
  4518     focus widget, and the sendMouseEvent() function which sends the
       
  4519     given mouse event.
       
  4520 
       
  4521     Finally, the QWSInputMethod class provides the sendQuery()
       
  4522     function for sending input method queries. This function
       
  4523     encapsulates the event with a QWSEvent instance of the \l
       
  4524     {QWSEvent::}{IMQuery} type.
       
  4525 
       
  4526     \sa QWSServer, {Qt for Embedded Linux Architecture}
       
  4527 */
       
  4528 
       
  4529 /*!
       
  4530     Constructs a new input method.
       
  4531 
       
  4532     Use the QWSServer::setCurrentInputMethod() function to install it.
       
  4533 */
       
  4534 
       
  4535 QWSInputMethod::QWSInputMethod()
       
  4536 {
       
  4537 
       
  4538 }
       
  4539 
       
  4540 /*!
       
  4541     Destroys this input method, uninstalling it if it is installed.
       
  4542 */
       
  4543 QWSInputMethod::~QWSInputMethod()
       
  4544 {
       
  4545     if (current_IM == this)
       
  4546         current_IM = 0;
       
  4547 }
       
  4548 
       
  4549 /*!
       
  4550     Filters the key input identified by the given \a unicode, \a
       
  4551     keycode, \a modifiers, \a isPress and \a autoRepeat parameters.
       
  4552 
       
  4553     Note that the default implementation does nothing; reimplement
       
  4554     this function to handle input from both physical and virtual
       
  4555     devices.
       
  4556 
       
  4557     The \a keycode is a Qt::Key value, and the \a modifiers is an OR
       
  4558     combination of Qt::KeyboardModifiers. The \a isPress parameter is
       
  4559     telling whether the input is a key press or key release, and the
       
  4560     \a autoRepeat parameter determines whether the input is
       
  4561     autorepeated ( i.e., in which case the
       
  4562     QWSKeyboardHandler::beginAutoRepeat() function has been called).
       
  4563 
       
  4564     To block the event from further processing, return true when
       
  4565     reimplementing this function; the default implementation returns
       
  4566     false.
       
  4567 
       
  4568     \sa setInputResolution(), inputResolutionShift()
       
  4569 */
       
  4570 bool QWSInputMethod::filter(int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat)
       
  4571 {
       
  4572     Q_UNUSED(unicode);
       
  4573     Q_UNUSED(keycode);
       
  4574     Q_UNUSED(modifiers);
       
  4575     Q_UNUSED(isPress);
       
  4576     Q_UNUSED(autoRepeat);
       
  4577     return false;
       
  4578 }
       
  4579 
       
  4580 /*!
       
  4581     \overload
       
  4582 
       
  4583     Filters the mouse input identified by the given \a position, \a
       
  4584     state, and \a wheel parameters.
       
  4585 */
       
  4586 bool QWSInputMethod::filter(const QPoint &position, int state, int wheel)
       
  4587 {
       
  4588     Q_UNUSED(position);
       
  4589     Q_UNUSED(state);
       
  4590     Q_UNUSED(wheel);
       
  4591     return false;
       
  4592 }
       
  4593 
       
  4594 /*!
       
  4595     Resets the state of the input method.
       
  4596 
       
  4597     If the input method is in compose mode, i.e., the input method is
       
  4598     actively composing a preedit string, the default implementation
       
  4599     calls sendEvent() with empty preedit and commit strings; otherwise
       
  4600     it does nothing. Reimplement this function to alter this behavior.
       
  4601 
       
  4602     \sa sendEvent()
       
  4603 */
       
  4604 void QWSInputMethod::reset()
       
  4605 {
       
  4606     if (current_IM_composing_win) {
       
  4607         QInputMethodEvent ime;
       
  4608         sendEvent(&ime);
       
  4609     }
       
  4610 }
       
  4611 
       
  4612 /*!
       
  4613     \enum QWSInputMethod::UpdateType
       
  4614 
       
  4615     This enum describes the various types of update events recognized
       
  4616     by the input method.
       
  4617 
       
  4618     \value Update    The input widget is updated in some way; use sendQuery() with
       
  4619                             Qt::ImMicroFocus as an argument for more information.
       
  4620     \value FocusIn   A new input widget receives focus.
       
  4621     \value FocusOut  The input widget loses focus.
       
  4622     \value Reset       The input method should be reset.
       
  4623     \value Destroyed The input widget is destroyed.
       
  4624 
       
  4625     \sa updateHandler()
       
  4626 */
       
  4627 
       
  4628 /*!
       
  4629     Handles update events including resets and focus changes. The
       
  4630     update events are specified by the given \a type which is one of
       
  4631     the UpdateType enum values.
       
  4632 
       
  4633     Note that reimplementations of this function must call the base
       
  4634     implementation for all cases that it does not handle itself.
       
  4635 
       
  4636     \sa UpdateType
       
  4637 */
       
  4638 void QWSInputMethod::updateHandler(int type)
       
  4639 {
       
  4640     switch (type) {
       
  4641     case FocusOut:
       
  4642     case Reset:
       
  4643         reset();
       
  4644         break;
       
  4645 
       
  4646     default:
       
  4647         break;
       
  4648     }
       
  4649 }
       
  4650 
       
  4651 
       
  4652 /*!
       
  4653     Receive replies to an input method query.
       
  4654 
       
  4655     Note that the default implementation does nothing; reimplement
       
  4656     this function to receive such replies.
       
  4657 
       
  4658     Internally, an input method query is passed encapsulated by an \l
       
  4659     {QWSEvent::IMQuery}{IMQuery} event generated by the sendQuery()
       
  4660     function. The queried property and the result is passed in the \a
       
  4661     property and \a result parameters.
       
  4662 
       
  4663     \sa sendQuery(), QWSServer::sendIMQuery()
       
  4664 */
       
  4665 void QWSInputMethod::queryResponse(int property, const QVariant &result)
       
  4666 {
       
  4667     Q_UNUSED(property);
       
  4668     Q_UNUSED(result);
       
  4669 }
       
  4670 
       
  4671 
       
  4672 
       
  4673 /*!
       
  4674     \fn void QWSInputMethod::mouseHandler(int offset, int state)
       
  4675 
       
  4676     Handles mouse events within the preedit text.
       
  4677 
       
  4678     Note that the default implementation resets the input method on
       
  4679     all mouse presses; reimplement this function to alter this
       
  4680     behavior.
       
  4681 
       
  4682     The \a offset parameter specifies the position of the mouse event
       
  4683     within the string, and \a state specifies the type of the mouse
       
  4684     event as described by the QWSServer::IMMouse enum. If \a state is
       
  4685     less than 0, the mouse event is inside the associated widget, but
       
  4686     outside the preedit text. When clicking in a different widget, the
       
  4687     \a state is QWSServer::MouseOutside.
       
  4688 
       
  4689     \sa sendPreeditString(), reset()
       
  4690 */
       
  4691 void QWSInputMethod::mouseHandler(int, int state)
       
  4692 {
       
  4693     if (state == QWSServer::MousePress || state == QWSServer::MouseOutside)
       
  4694         reset();
       
  4695 }
       
  4696 
       
  4697 
       
  4698 /*!
       
  4699     Sends an event encapsulating the given \a preeditString, to the
       
  4700     focus widget.
       
  4701 
       
  4702     The specified \a selectionLength is the number of characters to be
       
  4703     marked as selected (starting at the given \a cursorPosition). If
       
  4704     \a selectionLength is negative, the text \e before \a
       
  4705     cursorPosition is marked.
       
  4706 
       
  4707     The preedit string is marked with QInputContext::PreeditFormat,
       
  4708     and the selected part is marked with
       
  4709     QInputContext::SelectionFormat.
       
  4710 
       
  4711     Sending an input method event with a non-empty preedit string will
       
  4712     cause the input method to enter compose mode.  Sending an input
       
  4713     method event with an empty preedit string will cause the input
       
  4714     method to leave compose mode, i.e., the input method will no longer
       
  4715     be actively composing the preedit string.
       
  4716 
       
  4717     Internally, the event is represented by a QWSEvent object of the
       
  4718     \l {QWSEvent::IMEvent}{IMEvent} type.
       
  4719 
       
  4720     \sa sendEvent(), sendCommitString()
       
  4721 */
       
  4722 
       
  4723 void QWSInputMethod::sendPreeditString(const QString &preeditString, int cursorPosition, int selectionLength)
       
  4724 {
       
  4725     QList<QInputMethodEvent::Attribute> attributes;
       
  4726 
       
  4727     int selPos = cursorPosition;
       
  4728     if (selectionLength == 0) {
       
  4729         selPos = 0;
       
  4730     } else if (selectionLength < 0) {
       
  4731         selPos += selectionLength;
       
  4732         selectionLength = -selectionLength;
       
  4733     }
       
  4734     if (selPos > 0)
       
  4735         attributes += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selPos,
       
  4736                                                    QVariant(int(QInputContext::PreeditFormat)));
       
  4737 
       
  4738     if (selectionLength)
       
  4739         attributes += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selPos, selectionLength,
       
  4740                                                    QVariant(int(QInputContext::SelectionFormat)));
       
  4741 
       
  4742     if (selPos + selectionLength < preeditString.length())
       
  4743         attributes += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
       
  4744                                                    selPos + selectionLength,
       
  4745                                                    preeditString.length() - selPos - selectionLength,
       
  4746                                                    QVariant(int(QInputContext::PreeditFormat)));
       
  4747 
       
  4748     attributes += QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPosition,  0, QVariant());
       
  4749 
       
  4750     QInputMethodEvent ime(preeditString, attributes);
       
  4751     qwsServer->sendIMEvent(&ime);
       
  4752 }
       
  4753 
       
  4754 /*!
       
  4755     \fn void QWSInputMethod::sendCommitString(const QString &commitString, int replaceFromPosition, int replaceLength)
       
  4756 
       
  4757     Sends an event encapsulating the given \a commitString, to the
       
  4758     focus widget.
       
  4759 
       
  4760     Note that this will cause the input method to leave compose mode,
       
  4761     i.e., the input method will no longer be actively composing the
       
  4762     preedit string.
       
  4763 
       
  4764     If the specified \a replaceLength is greater than 0, the commit
       
  4765     string will replace the given number of characters of the
       
  4766     receiving widget's previous text, starting at the given \a
       
  4767     replaceFromPosition relative to the start of the current preedit
       
  4768     string.
       
  4769 
       
  4770     Internally, the event is represented by a QWSEvent object of the
       
  4771     \l {QWSEvent::IMEvent}{IMEvent} type.
       
  4772 
       
  4773     \sa sendEvent(), sendPreeditString()
       
  4774 */
       
  4775 void QWSInputMethod::sendCommitString(const QString &commitString, int replaceFrom, int replaceLength)
       
  4776 {
       
  4777     QInputMethodEvent ime;
       
  4778     ime.setCommitString(commitString, replaceFrom, replaceLength);
       
  4779     qwsServer->sendIMEvent(&ime);
       
  4780 }
       
  4781 
       
  4782 /*!
       
  4783     \fn QWSInputMethod::sendIMEvent(QWSServer::IMState state, const QString &text, int cursorPosition, int selectionLength)
       
  4784     \obsolete
       
  4785 
       
  4786     Sends a QInputMethodEvent object to the focus widget.
       
  4787 
       
  4788     If the specified \a state is QWSServer::IMCompose, \a text is a
       
  4789     preedit string, \a cursorPosition is the cursor's position within
       
  4790     the preedit string, and \a selectionLength is the number of
       
  4791     characters (starting at \a cursorPosition) that should be marked
       
  4792     as selected by the input widget receiving the event. If the
       
  4793     specified \a state is QWSServer::IMEnd, \a text is a commit
       
  4794     string.
       
  4795 
       
  4796     Use sendEvent(), sendPreeditString() or sendCommitString() instead.
       
  4797 */
       
  4798 
       
  4799 /*!
       
  4800     \fn QWSInputMethod::sendEvent(const QInputMethodEvent *event)
       
  4801 
       
  4802     Sends the given \a event to the focus widget.
       
  4803 
       
  4804     The \c QInputMethodEvent class is derived from QWSEvent, i.e., the
       
  4805     given \a event is a QWSEvent object of the \l
       
  4806     {QWSEvent::IMEvent}{IMEvent} type.
       
  4807 
       
  4808     \sa sendPreeditString(), sendCommitString(), reset()
       
  4809 */
       
  4810 
       
  4811 
       
  4812 /*!
       
  4813     \fn void QWSInputMethod::sendQuery(int property)
       
  4814 
       
  4815     Sends an input method query (internally encapsulated by a QWSEvent
       
  4816     of the \l {QWSEvent::IMQuery}{IMQuery} type) for the specified \a
       
  4817     property.
       
  4818 
       
  4819     To receive responses to input method queries, the virtual
       
  4820     queryResponse() function must be reimplemented.
       
  4821 
       
  4822     \sa queryResponse(), QWSServer::sendIMQuery()
       
  4823 */
       
  4824 
       
  4825 /*!
       
  4826     Sets and returns the number of bits shifted to go from pointer
       
  4827     resolution to screen resolution when filtering mouse input.
       
  4828 
       
  4829     If \a isHigh is true and the device has a pointer device
       
  4830     resolution twice or more of the screen resolution, the positions
       
  4831     passed to the filter() function will be presented at the higher
       
  4832     resolution; otherwise the resolution will be equal to that of the
       
  4833     screen resolution.
       
  4834 
       
  4835     \sa inputResolutionShift(), filter()
       
  4836 */
       
  4837 uint QWSInputMethod::setInputResolution(bool isHigh)
       
  4838 {
       
  4839     mIResolution = isHigh;
       
  4840     return inputResolutionShift();
       
  4841 }
       
  4842 
       
  4843 /*!
       
  4844     Returns the number of bits shifted to go from pointer resolution
       
  4845     to screen resolution when filtering mouse input.
       
  4846 
       
  4847     \sa setInputResolution(), filter()
       
  4848 */
       
  4849 uint QWSInputMethod::inputResolutionShift() const
       
  4850 {
       
  4851     return 0; // default for devices with single resolution.
       
  4852 }
       
  4853 
       
  4854 /*!
       
  4855     \fn void QWSInputMethod::sendMouseEvent( const QPoint &position, int state, int wheel )
       
  4856 
       
  4857     Sends a mouse event specified by the given \a position, \a state
       
  4858     and \a wheel parameters.
       
  4859 
       
  4860     The given \a position will be transformed if the screen
       
  4861     coordinates do not match the pointer device coordinates.
       
  4862 
       
  4863     Note that the event will be not be tested by the active input
       
  4864     method, but calling the QWSServer::sendMouseEvent() function will
       
  4865     make the current input method filter the event.
       
  4866 
       
  4867     \sa mouseHandler(), sendEvent()
       
  4868 */
       
  4869 void QWSInputMethod::sendMouseEvent( const QPoint &pos, int state, int wheel )
       
  4870 {
       
  4871         if (qt_last_x) {
       
  4872          *qt_last_x = pos.x();
       
  4873          *qt_last_y = pos.y();
       
  4874     }
       
  4875     QWSServer::mousePosition = pos;
       
  4876     qwsServerPrivate->mouseState = state;
       
  4877     QWSServerPrivate::sendMouseEventUnfiltered(pos, state, wheel);
       
  4878 }
       
  4879 #endif // QT_NO_QWS_INPUTMETHODS
       
  4880 
       
  4881 /*!
       
  4882     \fn  QWSWindow::QWSWindow(int i, QWSClient * client)
       
  4883     \internal
       
  4884 
       
  4885     Constructs a new top-level window, associated with the client \a
       
  4886     client and giving it the id \a i.
       
  4887 */
       
  4888 
       
  4889 /*!
       
  4890     \fn QWSServer::windowEvent(QWSWindow * window, QWSServer::WindowEvent eventType)
       
  4891 
       
  4892     This signal is emitted whenever something happens to a top-level
       
  4893     window (e.g., it's created or destroyed), passing a pointer to the
       
  4894     window and the event's type in the \a window and \a eventType
       
  4895     parameters, respectively.
       
  4896 
       
  4897     \sa markedText()
       
  4898 */
       
  4899 
       
  4900 /*!
       
  4901     \class QWSServer::KeyboardFilter
       
  4902     \ingroup qws
       
  4903 
       
  4904     \brief The KeyboardFilter class is a base class for global
       
  4905     keyboard event filters in Qt for Embedded Linux.
       
  4906 
       
  4907     Note that this class is only available in \l{Qt for Embedded Linux}.
       
  4908 
       
  4909     In \l{Qt for Embedded Linux}, all system generated events, including
       
  4910     keyboard events, are passed to the server application which then
       
  4911     propagates the event to the appropriate client. The KeyboardFilter
       
  4912     class is used to implement a global, low-level filter on the
       
  4913     server side. The server applies the filter to all keyboard events
       
  4914     before passing them on to the clients:
       
  4915 
       
  4916     \image qwsserver_keyboardfilter.png
       
  4917 
       
  4918     This feature can, for example, be used to filter things like APM
       
  4919     (advanced power management) suspended from a button without having
       
  4920     to filter for it in all applications.
       
  4921 
       
  4922     To add a new keyboard filter you must first create the filter by
       
  4923     deriving from this class, reimplementing the pure virtual filter()
       
  4924     function. Then you can install the filter on the server using
       
  4925     QWSServer's \l {QWSServer::}{addKeyboardFilter()}
       
  4926     function. QWSServer also provides a \l
       
  4927     {QWSServer::}{removeKeyboardFilter()} function.
       
  4928 
       
  4929     \sa {Qt for Embedded Linux Architecture}, QWSServer, QWSInputMethod
       
  4930 */
       
  4931 
       
  4932 /*!
       
  4933     \fn QWSServer::KeyboardFilter::~KeyboardFilter()
       
  4934 
       
  4935     Destroys the keyboard filter.
       
  4936 */
       
  4937 
       
  4938 /*!
       
  4939     \fn bool QWSServer::KeyboardFilter::filter(int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat)
       
  4940 
       
  4941     Implement this function to return true if a given key event should
       
  4942     be stopped from being processed any further; otherwise it should
       
  4943     return false.
       
  4944 
       
  4945     A key event can be identified by the given \a unicode value and
       
  4946     the \a keycode, \a modifiers, \a isPress and \a autoRepeat
       
  4947     parameters.
       
  4948 
       
  4949     The \a keycode parameter is the Qt keycode value as defined by the
       
  4950     Qt::Key enum. The \a modifiers is an OR combination of
       
  4951     Qt::KeyboardModifier values, indicating whether \gui
       
  4952     Shift/Alt/Ctrl keys are pressed. The \a isPress parameter is true
       
  4953     if the event is a key press event and \a autoRepeat is true if the
       
  4954     event is caused by an auto-repeat mechanism and not an actual key
       
  4955     press.
       
  4956 */
       
  4957 
       
  4958 QT_END_NAMESPACE
       
  4959 
       
  4960 #include "moc_qwindowsystem_qws.cpp"