/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qglobal.h"
#include "qlibrary.h"
#include "qcursor.h"
#include "qapplication.h"
#include "private/qapplication_p.h"
#include "qwidget.h"
#include "qbitarray.h"
#include "qpainter.h"
#include "qpixmapcache.h"
#include "qdatetime.h"
#include "qtextcodec.h"
#include "qdatastream.h"
#include "qbuffer.h"
#include "qsocketnotifier.h"
#include "qsessionmanager.h"
#include "qclipboard.h"
#include "qbitmap.h"
#include "qwssocket_qws.h"
#include "qtransportauth_qws.h"
#include "private/qtransportauth_qws_p.h"
#include "qwsevent_qws.h"
#include "private/qwscommand_qws_p.h"
#include "qwsproperty_qws.h"
#include "qscreen_qws.h"
#include "qscreenproxy_qws.h"
#include "qcopchannel_qws.h"
#include "private/qlock_p.h"
#include "private/qwslock_p.h"
//#include "qmemorymanager_qws.h"
#include "qwsmanager_qws.h"
//#include "qwsregionmanager_qws.h"
#include "qwindowsystem_qws.h"
#include "private/qwindowsystem_p.h"
#include "qdecorationfactory_qws.h"

#include "qwsdisplay_qws.h"
#include "private/qwsdisplay_qws_p.h"
#include "private/qwsinputcontext_p.h"
#include "qfile.h"
#include "qhash.h"
#include "qdesktopwidget.h"
#include "qcolormap.h"
#include "private/qcursor_p.h"
#include "qsettings.h"
#include "qdebug.h"
#include "qeventdispatcher_qws_p.h"
#if !defined(QT_NO_GLIB)
#  include "qeventdispatcher_glib_qws_p.h"
#endif


#include "private/qwidget_p.h"
#include "private/qbackingstore_p.h"
#include "private/qwindowsurface_qws_p.h"
#include "private/qfont_p.h"

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <errno.h>
#include <fcntl.h>
#ifdef Q_OS_VXWORKS
#  include <sys/times.h>
#else
#  include <sys/time.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>

#include <qvfbhdr.h>

#ifndef QT_NO_QWS_MULTIPROCESS
#ifdef QT_NO_QSHM
#include <sys/ipc.h>
#include <sys/shm.h>
#ifndef Q_OS_DARWIN
# include <sys/sem.h>
#endif
#include <sys/socket.h>
#else
#include "private/qwssharedmemory_p.h"
#endif
#endif

QT_BEGIN_NAMESPACE

#ifndef QT_NO_DIRECTPAINTER
class QDirectPainter;
extern void qt_directpainter_region(QDirectPainter *dp, const QRegion &alloc, int type);
#ifndef QT_NO_QWSEMBEDWIDGET
extern void qt_directpainter_embedevent(QDirectPainter *dp,
                                        const QWSEmbedEvent *e);
#endif
#endif // QT_NO_DIRECTPAINTER

const int qwsSharedRamSize = 1 * 1024; // misc data, written by server, read by clients

extern QApplication::Type qt_appType;
extern QDesktopWidget *qt_desktopWidget;

//these used to be environment variables, they are initialized from
//environment variables in

bool qws_savefonts = false;
bool qws_screen_is_interlaced=false; //### should be detected
bool qws_shared_memory = false;
bool qws_sw_cursor = true;
bool qws_accel = true;            // ### never set
QByteArray qws_display_spec(":0");
Q_GUI_EXPORT int qws_display_id = 0;
Q_GUI_EXPORT int qws_client_id = 0;
QWidget *qt_pressGrab = 0;
QWidget *qt_mouseGrb = 0;
int *qt_last_x = 0;
int *qt_last_y = 0;

static int mouse_x_root = -1;
static int mouse_y_root = -1;
static int mouse_state = 0;
static int mouse_double_click_distance = 5;

int qt_servershmid = -1;

bool qws_overrideCursor = false;
#ifndef QT_NO_QWS_MANAGER

extern Q_GUI_EXPORT QWSServer *qwsServer;

static QDecoration *qws_decoration = 0;
#endif

#if defined(QT_DEBUG)
/*
extern "C" void dumpmem(const char* m)
{
    static int init=0;
    static int prev=0;
    FILE* f = fopen("/proc/meminfo","r");
    //    char line[100];
    int total=0,used=0,free=0,shared=0,buffers=0,cached=0;
    fscanf(f,"%*[^M]Mem: %d %d %d %d %d %d",&total,&used,&free,&shared,&buffers,&cached);
    used -= buffers + cached;
    if (!init) {
        init=used;
    } else {
        printf("%40s: %+8d = %8d\n",m,used-init-prev,used-init);
        prev = used-init;
    }
    fclose(f);
}
*/
#endif

// Get the name of the directory where Qt for Embedded Linux temporary data should
// live.
QString qws_dataDir()
{
    static QString result;
    if (!result.isEmpty())
        return result;
    result = QT_VFB_DATADIR(qws_display_id);
    QByteArray dataDir = result.toLocal8Bit();

    if (QT_MKDIR(dataDir, 0700)) {
        if (errno != EEXIST) {
            qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData());
        }
    }

    QT_STATBUF buf;
    if (QT_LSTAT(dataDir, &buf))
        qFatal("stat failed for Qt for Embedded Linux data directory: %s", dataDir.constData());

    if (!S_ISDIR(buf.st_mode))
        qFatal("%s is not a directory", dataDir.constData());

#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS)
    if (buf.st_uid != getuid())
        qFatal("Qt for Embedded Linux data directory is not owned by user %d", getuid());

    if ((buf.st_mode & 0677) != 0600)
        qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData());
#endif

    result.append("/");
    return result;
}

// Get the filename of the pipe Qt for Embedded Linux uses for server/client comms
Q_GUI_EXPORT QString qws_qtePipeFilename()
{
    qws_dataDir();
    return QTE_PIPE(qws_display_id);
}

static void setMaxWindowRect(const QRect &rect)
{
    const QList<QScreen*> subScreens = qt_screen->subScreens();
    QScreen *screen = qt_screen;
    int screenNo = 0;
    for (int i = 0; i < subScreens.size(); ++i) {
        if (subScreens.at(i)->region().contains(rect)) {
            screen = subScreens.at(i);
            screenNo = i;
            break;
        }
    }

    QApplicationPrivate *ap = QApplicationPrivate::instance();
    ap->setMaxWindowRect(screen, screenNo, rect);
}

void QApplicationPrivate::setMaxWindowRect(const QScreen *screen, int screenNo,
                                           const QRect &rect)
{
    if (maxWindowRects.value(screen) == rect)
        return;

    maxWindowRects[screen] = rect;

    // Re-resize any maximized windows
    QWidgetList l = QApplication::topLevelWidgets();
    for (int i = 0; i < l.size(); ++i) {
        QWidget *w = l.at(i);
        QScreen *s = w->d_func()->getScreen();
        if (w->isMaximized() && s == screen)
            w->d_func()->setMaxWindowState_helper();
    }

    if ( qt_desktopWidget ) // XXX workaround crash
        emit QApplication::desktop()->workAreaResized(screenNo);
}

#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION

typedef void (*TransformFunc)(QScreen *, int);
#ifndef QT_NO_QWS_TRANSFORMED
extern "C" void qws_setScreenTransformation(QScreen *, int);
#endif
static TransformFunc getTransformationFunction()
{
    static TransformFunc func = 0;

    if (!func) {
#ifdef QT_NO_QWS_TRANSFORMED
#  ifndef QT_NO_LIBRARY
        // symbol is not built into the library, search for the plugin
        const QStringList paths = QApplication::libraryPaths();
        foreach (const QString &path, paths) {
            const QString file = path + QLatin1String("/gfxdrivers/libqgfxtransformed");
            func = (TransformFunc)QLibrary::resolve(file,
                                                    "qws_setScreenTransformation");
            if (func)
                break;
        }
#  endif
#else
        func = qws_setScreenTransformation;
#endif
        if (!func)
            func = (TransformFunc)-1;
    }

    if (func == (TransformFunc)-1)
        return 0;

    return func;
}

static void setScreenTransformation(int screenNo, int transformation)
{
    QScreen *screen = QScreen::instance();
    const QList<QScreen*> subScreens = screen->subScreens();

    if (screenNo == -1)
        screenNo = 0;

    if (screenNo == -1 && !subScreens.isEmpty())
        screenNo = 0;

    if (subScreens.isEmpty() && screenNo == 0) {
        // nothing
    } else if (screenNo < 0 || screenNo >= subScreens.size()) {
        qWarning("setScreenTransformation: invalid screen %i", screenNo);
        return;
    }

    if (screenNo < subScreens.size())
        screen = subScreens.at(screenNo);

    QApplicationPrivate *ap = QApplicationPrivate::instance();
    ap->setScreenTransformation(screen, screenNo, transformation);
}

void QApplicationPrivate::setScreenTransformation(QScreen *screen,
                                                  int screenNo,
                                                  int transformation)
{
    QScreen *transformed = screen;

    while (transformed->classId() == QScreen::ProxyClass)
        transformed = static_cast<QProxyScreen*>(transformed)->screen();

    if (transformed->classId() != QScreen::TransformedClass)
        return;

    TransformFunc setScreenTransformation = getTransformationFunction();
    if (!setScreenTransformation)
        return;

    setScreenTransformation(transformed, transformation);

    // need to re-configure() proxies bottom-up
    if (screen->classId() == QScreen::ProxyClass) {
        QList<QProxyScreen*> proxies;
        QScreen *s = screen;

        do {
            QProxyScreen *proxy = static_cast<QProxyScreen*>(s);
            proxies.append(proxy);
            s = proxy->screen();
        } while (s->classId() == QScreen::ProxyClass);

        do {
            QProxyScreen *proxy = proxies.takeLast();
            proxy->setScreen(proxy->screen()); // triggers configure()
        } while (!proxies.isEmpty());
    }

    if (qt_desktopWidget) { // XXX workaround crash for early screen transform events
        QDesktopWidget *desktop = QApplication::desktop();

        emit desktop->resized(screenNo);
        if (maxWindowRect(screen).isEmpty()) // not explicitly set
            emit desktop->workAreaResized(screenNo);
    }

    QWSServer *server = QWSServer::instance();
    if (server) {
        server->updateWindowRegions();
        QRegion r = screen->region();
        server->refresh(r);
    }

    // make sure maximized and fullscreen windows are updated
    QWidgetList list = QApplication::topLevelWidgets();
    for (int i = list.size() - 1; i >= 0; --i) {
        QWidget *w = list.at(i);
        if (w->isFullScreen())
            w->d_func()->setFullScreenSize_helper();
        else if (w->isMaximized())
            w->d_func()->setMaxWindowState_helper();
    }
}

#endif // QT_NO_QWS_DYNAMICSCREENTRANSFORMATION

/*****************************************************************************
  Internal variables and functions
 *****************************************************************************/


static QString appName;                          // application name
static const char *appFont = 0;                  // application font
static const char *appBGCol = 0;                 // application bg color
static const char *appFGCol = 0;                 // application fg color
static const char *appBTNCol = 0;                // application btn color
static const char *mwGeometry = 0;               // main widget geometry
static const char *mwTitle = 0;                  // main widget title
//static bool mwIconic = false;                  // main widget iconified

static bool app_do_modal = false;                // modal mode
Q_GUI_EXPORT QWSDisplay *qt_fbdpy = 0;                        // QWS `display'
QLock *QWSDisplay::lock = 0;

static int mouseButtonPressed = 0;               // last mouse button pressed
static int mouseButtonPressTime = 0;             // when was a button pressed
static short mouseXPos, mouseYPos;               // mouse position in act window

extern QWidgetList *qt_modal_stack;              // stack of modal widgets

static QWidget *popupButtonFocus = 0;
static QWidget *popupOfPopupButtonFocus = 0;
static bool popupCloseDownMode = false;
static bool popupGrabOk;
static QPointer<QWidget> *mouseInWidget = 0;
QPointer<QWidget> qt_last_mouse_receiver = 0;

static bool sm_blockUserInput = false;           // session management

QWidget *qt_button_down = 0;                     // widget got last button-down
WId qt_last_cursor = 0xffffffff;                 // Was -1, but WIds are unsigned

class QWSMouseEvent;
class QWSKeyEvent;

class QETWidget : public QWidget                 // event translator widget
{
public:
    bool translateMouseEvent(const QWSMouseEvent *, int oldstate);
    bool translateKeyEvent(const QWSKeyEvent *, bool grab);
    bool translateRegionEvent(const QWSRegionEvent *);
#ifndef QT_NO_QWSEMBEDWIDGET
    void translateEmbedEvent(const QWSEmbedEvent *event);
#endif
    bool translateWheelEvent(const QWSMouseEvent *me);
    void repaintDecoration(QRegion r, bool post);
    void updateRegion();

    bool raiseOnClick()
    {
        // With limited windowmanagement/taskbar/etc., raising big windows
        // (eg. spreadsheet) over the top of everything else (eg. calculator)
        // is just annoying.
        return !isMaximized() && !isFullScreen();
    }
};

void QApplicationPrivate::createEventDispatcher()
{
    Q_Q(QApplication);
#if !defined(QT_NO_GLIB)
    if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
        eventDispatcher = (q->type() != QApplication::Tty
                           ? new QWSEventDispatcherGlib(q)
                           : new QEventDispatcherGlib(q));
    else
#endif
    eventDispatcher = (q->type() != QApplication::Tty
                       ? new QEventDispatcherQWS(q)
                       : new QEventDispatcherUNIX(q));
}

// Single-process stuff. This should maybe move into qwindowsystem_qws.cpp

static bool qws_single_process;
static QList<QWSEvent*> incoming;
static QList<QWSCommand*> outgoing;

void qt_client_enqueue(const QWSEvent *event)
{
    QWSEvent *copy = QWSEvent::factory(event->type);
    copy->copyFrom(event);
    incoming.append(copy);
}

QList<QWSCommand*> *qt_get_server_queue()
{
    return &outgoing;
}

void qt_server_enqueue(const QWSCommand *command)
{
    QWSCommand *copy = QWSCommand::factory(command->type);
    QT_TRY {
        copy->copyFrom(command);
        outgoing.append(copy);
    } QT_CATCH(...) {
        delete copy;
        QT_RETHROW;
    }
}

QWSDisplay::Data::Data(QObject* parent, bool singleProcess)
{
#ifdef QT_NO_QWS_MULTIPROCESS
    Q_UNUSED(parent);
    Q_UNUSED(singleProcess);
#else
    if (singleProcess)
        csocket = 0;
    else {
        csocket = new QWSSocket(parent);
        QObject::connect(csocket, SIGNAL(disconnected()),
                         qApp, SLOT(quit()));
    }
    clientLock = 0;
#endif
    init();
}

QWSDisplay::Data::~Data()
{
//        delete rgnMan; rgnMan = 0;
//        delete memorymanager; memorymanager = 0;
    qt_screen->disconnect();
    delete qt_screen; qt_screen = 0;
#ifndef QT_NO_QWS_CURSOR
    delete qt_screencursor; qt_screencursor = 0;
#endif
#ifndef QT_NO_QWS_MULTIPROCESS
    shm.detach();
    if (csocket) {
        QWSCommand shutdownCmd(QWSCommand::Shutdown, 0, 0);
        shutdownCmd.write(csocket);
        csocket->flush(); // may be pending QCop message, eg.
        delete csocket;
    }
    delete clientLock;
    clientLock = 0;
#endif
    delete connected_event;
    delete mouse_event;
    delete current_event;
    qDeleteAll(queue);
#ifndef QT_NO_COP
    delete qcop_response;
#endif
}

#ifndef QT_NO_QWS_MULTIPROCESS
bool QWSDisplay::Data::lockClient(QWSLock::LockType type, int timeout)
{
    return !clientLock || clientLock->lock(type, timeout);
}

void QWSDisplay::Data::unlockClient(QWSLock::LockType type)
{
    if (clientLock) clientLock->unlock(type);
}

bool QWSDisplay::Data::waitClient(QWSLock::LockType type, int timeout)
{
    return !clientLock || clientLock->wait(type, timeout);
}

QWSLock* QWSDisplay::Data::getClientLock()
{
    return clientLock;
}
#endif // QT_NO_QWS_MULTIPROCESS

void QWSDisplay::Data::flush()
{
#ifndef QT_NO_QWS_MULTIPROCESS
    if (csocket) {
        csocket->waitForReadyRead(0);
        csocket->flush();
   }
#endif
}

#if 0
void QWSDisplay::Data::debugQueue() {
    for (int i = 0; i < queue.size(); ++i) {
        QWSEvent *e = queue.at(i);
        qDebug( "   ev %d type %d sl %d rl %d", i, e->type, e->simpleLen, e->rawLen);
    }
}
#endif

bool QWSDisplay::Data::queueNotEmpty()
{
    return mouse_event/*||region_event*/||queue.count() > 0;
}
QWSEvent* QWSDisplay::Data::dequeue()
{
    QWSEvent *r=0;
    if (queue.count()) {
        r = queue.first();
        queue.removeFirst();
        if (r->type == QWSEvent::Region)
            region_events_count--;
    } else if (mouse_event) {
        r = mouse_event;
        mouse_event = 0;
#ifdef QAPPLICATION_EXTRA_DEBUG
        mouse_event_count = 0;
#endif
    }
    return r;
}

QWSEvent* QWSDisplay::Data::peek()
{
    return queue.first();
}

bool QWSDisplay::Data::directServerConnection()
{
#ifndef QT_NO_QWS_MULTIPROCESS
    return csocket == 0;
#else
    return true;
#endif
}

void QWSDisplay::Data::create(int n)
{
    QWSCreateCommand cmd(n);
    sendCommand(cmd);
}

void QWSDisplay::Data::flushCommands()
{
#ifndef QT_NO_QWS_MULTIPROCESS
    if  (csocket)
        csocket->flush();
#endif
}

void QWSDisplay::Data::sendCommand(QWSCommand & cmd)
{
#ifndef QT_NO_QWS_MULTIPROCESS
    if  (csocket)
        cmd.write(csocket);
    else
#endif
        qt_server_enqueue(&cmd);
}

void QWSDisplay::Data::sendSynchronousCommand(QWSCommand & cmd)
{
#ifndef QT_NO_QWS_MULTIPROCESS
    if  (csocket) {
        lockClient(QWSLock::Communication);
        cmd.write(csocket);
        bool ok = true;
        while (csocket->bytesToWrite() > 0) {
            if (!csocket->waitForBytesWritten(-1)) {
                qCritical("QWSDisplay::Data::sendSynchronousCommand: %s",
                          qPrintable(csocket->errorString()));
                ok = false;
                break;
            }
        }
        if (ok)
            waitClient(QWSLock::Communication);
    } else
#endif
        qt_server_enqueue(&cmd);
}

int QWSDisplay::Data::takeId()
{
    int unusedIdCount = unused_identifiers.count();
    if (unusedIdCount <= 10)
        create(15);
    if (unusedIdCount == 0) {
        create(1); // Make sure we have an incoming id to wait for, just in case we're recursive
        waitForCreation();
    }

    return unused_identifiers.takeFirst();
}

void QWSDisplay::Data::setMouseFilter(void (*filter)(QWSMouseEvent*))
{
    mouseFilter = filter;
}

#ifndef QT_NO_QWS_MULTIPROCESS

QWSLock* QWSDisplay::Data::clientLock = 0;

void Q_GUI_EXPORT qt_app_reinit( const QString& newAppName )
{
    qt_fbdpy->d->reinit( newAppName );
}

#endif // QT_NO_QWS_MULTIPROCESS

class QDesktopWidget;

#ifndef QT_NO_QWS_MULTIPROCESS
void QWSDisplay::Data::reinit( const QString& newAppName )
{
    Q_ASSERT(csocket);

    delete connected_event;
    connected_event = 0;
    region_events_count = 0;
//    region_ack = 0;
    delete mouse_event;
    mouse_event = 0;
//    region_event = 0;
    region_offset_window = 0;
#ifndef QT_NO_COP
    delete qcop_response;
    qcop_response = 0;
#endif
    delete current_event;
    current_event = 0;
#ifdef QAPPLICATION_EXTRA_DEBUG
    mouse_event_count = 0;
#endif
    mouseFilter = 0;

    qt_desktopWidget = 0;
    delete QWSDisplay::Data::clientLock;
    QWSDisplay::Data::clientLock = 0;

    QString pipe = qws_qtePipeFilename();

    // QWS client
    // Cleanup all cached ids
    unused_identifiers.clear();
    delete csocket;

    appName = newAppName;
    qApp->setObjectName( appName );

    csocket = new QWSSocket();
    QObject::connect(csocket, SIGNAL(disconnected()),
                     qApp, SLOT(quit()));
    csocket->connectToLocalFile(pipe);

    QWSDisplay::Data::clientLock = new QWSLock();

    QWSIdentifyCommand cmd;
    cmd.setId(appName, QWSDisplay::Data::clientLock->id());

#ifndef QT_NO_SXE
    QTransportAuth *a = QTransportAuth::getInstance();
    QTransportAuth::Data *d = a->connectTransport(
            QTransportAuth::UnixStreamSock |
            QTransportAuth::Trusted,
            csocket->socketDescriptor());
    QAuthDevice *ad = a->authBuf( d, csocket );
    ad->setClient( csocket );

    cmd.write(ad);
#else
    cmd.write(csocket);
#endif

    // wait for connect confirmation
    waitForConnection();

    qws_client_id = connected_event->simpleData.clientId;

    if (!QWSDisplay::initLock(pipe, false))
        qFatal("Cannot get display lock");

    if (shm.attach(connected_event->simpleData.servershmid)) {
        sharedRam = static_cast<uchar *>(shm.address());
        QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
        if (s)
            sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
    } else {
        perror("QWSDisplay::Data::init");
        qFatal("Client can't attach to main ram memory.");
    }

    qApp->desktop();

    // We wait for creation mainly so that we can process important
    // initialization events such as MaxWindowRect that are sent
    // before object id creation.  Waiting here avoids later window
    // resizing since we have the MWR before windows are displayed.
    waitForCreation();

    sharedRamSize -= sizeof(int);
    qt_last_x = reinterpret_cast<int *>(sharedRam + sharedRamSize);
    sharedRamSize -= sizeof(int);
    qt_last_y = reinterpret_cast<int *>(sharedRam + sharedRamSize);

#ifndef QT_NO_COP
    QCopChannel::reregisterAll();
#endif
    csocket->flush();
}
#endif

void QWSDisplay::Data::init()
{
    connected_event = 0;
    region_events_count = 0;
//    region_ack = 0;
    mouse_event = 0;
    mouse_state = -1;
    mouse_winid = 0;
//    region_event = 0;
    region_offset_window = 0;
#ifndef QT_NO_COP
    qcop_response = 0;
#endif
    current_event = 0;
#ifdef QAPPLICATION_EXTRA_DEBUG
    mouse_event_count = 0;
#endif
    mouseFilter = 0;

    QString pipe = qws_qtePipeFilename();

    sharedRamSize = qwsSharedRamSize;

#ifndef QT_NO_QWS_MULTIPROCESS
    if (csocket)    {
        // QWS client

        connectToPipe();

        QWSDisplay::Data::clientLock = new QWSLock();

        QWSIdentifyCommand cmd;
        cmd.setId(appName, QWSDisplay::Data::clientLock->id());
#ifndef QT_NO_SXE
        QTransportAuth *a = QTransportAuth::getInstance();
        QTransportAuth::Data *d = a->connectTransport(
                QTransportAuth::UnixStreamSock |
                QTransportAuth::Trusted,
                csocket->socketDescriptor());
        QAuthDevice *ad = a->authBuf( d, csocket );
        ad->setClient( csocket );
        cmd.write(ad);
#else
        cmd.write(csocket);
#endif

        // create(30); // not necessary, server will send ids anyway
        waitForConnection();

        qws_client_id = connected_event->simpleData.clientId;

        // now we want to get the exact display spec to use if we haven't
        // specified anything.
        if (qws_display_spec.at(0) == ':')
            qws_display_spec = connected_event->display;

        if (!QWSDisplay::initLock(pipe, false))
            qFatal("Cannot get display lock");

        if (shm.attach(connected_event->simpleData.servershmid)) {
            sharedRam = static_cast<uchar *>(shm.address());
            QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
            if (s)
                sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
        } else {
            perror("QWSDisplay::Data::init");
            qFatal("Client can't attach to main ram memory.");
        }

        // We wait for creation mainly so that we can process important
        // initialization events such as MaxWindowRect that are sent
        // before object id creation.  Waiting here avoids later window
        // resizing since we have the MWR before windows are displayed.
        waitForCreation();
    } else
#endif
    {
        create(30);

        // QWS server
        if (!QWSDisplay::initLock(pipe, true))
            qFatal("Cannot get display lock");

        QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
        if (s)
            sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));

#ifndef QT_NO_QWS_MULTIPROCESS

        if (!shm.create(sharedRamSize)) {
            perror("Cannot create main ram shared memory\n");
            qFatal("Unable to allocate %d bytes of shared memory", sharedRamSize);
        }
        qt_servershmid = shm.id();
        sharedRam = static_cast<uchar *>(shm.address());
#else
        sharedRam=static_cast<uchar *>(malloc(sharedRamSize));
#endif
        // Need to zero index count at end of block, might as well zero
        // the rest too
        memset(sharedRam,0,sharedRamSize);

        QWSIdentifyCommand cmd;
        cmd.setId(appName, -1);
        qt_server_enqueue(&cmd);
    }

    // Allow some memory for the graphics driver too
    //### Note that sharedRamSize() has side effects; it must be called
    //### once, and only once, and before initDevice()
    sharedRamSize -= qt_screen->sharedRamSize(sharedRam+sharedRamSize);

#ifndef QT_NO_QWS_MULTIPROCESS
    if(!csocket)
#endif
    {
        //QWS server process
        if (!qt_screen->initDevice())
            qFatal("Unable to initialize screen driver!");
    }

    sharedRamSize -= sizeof(int);
    qt_last_x = reinterpret_cast<int *>(sharedRam + sharedRamSize);
    sharedRamSize -= sizeof(int);
    qt_last_y = reinterpret_cast<int *>(sharedRam + sharedRamSize);

    /* Initialise framebuffer memory manager */
    /* Add 4k for luck and to avoid clobbering hardware cursor */
//    int screensize=qt_screen->screenSize();
//     memorymanager=new QMemoryManager(qt_screen->base()+screensize+4096,
//         qt_screen->totalSize()-(screensize+4096),0);

// #ifndef QT_NO_QWS_MULTIPROCESS
//     rgnMan = new QWSRegionManager(pipe, csocket);
// #else
//     rgnMan = new QWSRegionManager(pipe, 0); //####### not necessary
// #endif
#ifndef QT_NO_QWS_MULTIPROCESS
    if (csocket)
        csocket->flush();
#endif
}


QWSEvent* QWSDisplay::Data::readMore()
{
#ifdef QT_NO_QWS_MULTIPROCESS
    return incoming.isEmpty() ? 0 : incoming.takeFirst();
#else
    if (!csocket)
        return incoming.isEmpty() ? 0 : incoming.takeFirst();
    // read next event
    if (!current_event) {
        int event_type = qws_read_uint(csocket);

        if (event_type >= 0) {
            current_event = QWSEvent::factory(event_type);
        }
    }

    if (current_event) {
        if (current_event->read(csocket)) {
            // Finished reading a whole event.
            QWSEvent* result = current_event;
            current_event = 0;
            return result;
        }
    }

    // Not finished reading a whole event.
    return 0;
#endif
}

void QWSDisplay::Data::fillQueue()
{
    QWSServer::processEventQueue();
    QWSEvent *e = readMore();
#ifndef QT_NO_QWS_MULTIPROCESS
    int bytesAvailable = csocket ? csocket->bytesAvailable() : 0;
    int bytesRead = 0;
#endif
    while (e) {
#ifndef QT_NO_QWS_MULTIPROCESS
        bytesRead += QWS_PROTOCOL_ITEM_SIZE((*e));
#endif
        if (e->type == QWSEvent::Connected) {
            connected_event = static_cast<QWSConnectedEvent *>(e);
            return;
        } else if (e->type == QWSEvent::Creation) {
            QWSCreationEvent *ce = static_cast<QWSCreationEvent*>(e);
            int id = ce->simpleData.objectid;
            int count = ce->simpleData.count;
            for (int i = 0; i < count; ++i)
                unused_identifiers.append(id++);
            delete e;
        } else if (e->type == QWSEvent::Mouse) {
            if (!qt_screen) {
                delete e;
            } else {
                QWSMouseEvent *me = static_cast<QWSMouseEvent*>(e);
                if (mouseFilter)
                    mouseFilter(me);
#ifdef QAPPLICATION_EXTRA_DEBUG
                static const char *defaultAction= "INITIAL";
                const char * action = defaultAction;
#endif
                delete mouse_event;
                if (mouse_winid != me->window ()
                    || mouse_state != me->simpleData.state) {
                        queue.append(me);
                        mouse_winid = me->window();
                        mouse_state = me->simpleData.state;
                        mouse_event = 0;
#ifdef QAPPLICATION_EXTRA_DEBUG
                        mouse_event_count = 0;
                        action = "ENQUEUE";
#endif
                } else {
#ifdef QAPPLICATION_EXTRA_DEBUG
                    if (mouse_event)
                        action = "COMPRESS";
                    mouse_event_count++;
#endif
                    mouse_event = me;
                }
#ifdef QAPPLICATION_EXTRA_DEBUG
                if (me->simpleData.state !=0 || action != defaultAction || mouse_event_count != 0)
                    qDebug("fillQueue %s (%d,%d), state %x win %d count %d", action,
                           me->simpleData.x_root, me->simpleData.y_root, me->simpleData.state,
                           me->window(), mouse_event_count);
#endif
            }
#ifndef QT_NO_QWS_MULTIPROCESS
        } else if (e->type == QWSEvent::Region && clientLock) {
            // not really an unlock, decrements the semaphore
            region_events_count++;
            clientLock->unlock(QWSLock::RegionEvent);
            queue.append(e);
#endif
#ifndef QT_NO_QWS_PROPERTIES
        } else if (e->type == QWSEvent::PropertyReply) {
            QWSPropertyReplyEvent *pe = static_cast<QWSPropertyReplyEvent*>(e);
            int len = pe->simpleData.len;
            char *data;
            if (len <= 0) {
                data = 0;
            } else {
                data = new char[len];
                memcpy(data, pe->data, len) ;
            }
            QPaintDevice::qwsDisplay()->getPropertyLen = len;
            QPaintDevice::qwsDisplay()->getPropertyData = data;
            delete e;
#endif // QT_NO_QWS_PROPERTIES
        } else if (e->type==QWSEvent::MaxWindowRect && qt_screen) {
            // Process this ASAP, in case new widgets are created (startup)
            setMaxWindowRect((static_cast<QWSMaxWindowRectEvent*>(e))->simpleData.rect);
            delete e;
#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
        } else if (e->type == QWSEvent::ScreenTransformation) {
            QWSScreenTransformationEvent *pe = static_cast<QWSScreenTransformationEvent*>(e);
            setScreenTransformation(pe->simpleData.screen,
                                    pe->simpleData.transformation);
            delete e;
#endif
#ifndef QT_NO_COP
        } else if (e->type == QWSEvent::QCopMessage) {
            QWSQCopMessageEvent *pe = static_cast<QWSQCopMessageEvent*>(e);
            if (pe->simpleData.is_response) {
                qcop_response = pe;
            } else {
                queue.append(e);
            }
#endif
        } else {
            queue.append(e);
        }
        //debugQueue();
#ifndef QT_NO_QWS_MULTIPROCESS
        if (csocket && bytesRead >= bytesAvailable)
            break;
#endif
        e = readMore();
    }
}

#ifndef QT_NO_QWS_MULTIPROCESS

static int qws_connection_timeout = 5;

void QWSDisplay::Data::connectToPipe()
{
    Q_ASSERT(csocket);

    int timeout = qgetenv("QWS_CONNECTION_TIMEOUT").toInt();
    if (timeout)
        qws_connection_timeout = timeout;

    const QString pipe = qws_qtePipeFilename();
    int i = 0;
    while (!csocket->connectToLocalFile(pipe)) {
        if (++i > qws_connection_timeout) {
            qWarning("No Qt for Embedded Linux server appears to be running.");
            qWarning("If you want to run this program as a server,");
            qWarning("add the \"-qws\" command-line option.");
            exit(1);
        }
        sleep(1);
    }
}

void QWSDisplay::Data::waitForConnection()
{
    connected_event = 0;

    for (int i = 0; i < qws_connection_timeout; i++) {
        fillQueue();
        if (connected_event)
            return;
        csocket->flush();
        csocket->waitForReadyRead(1000);
    }

    csocket->flush();
    if (!connected_event)
        qFatal("Did not receive a connection event from the qws server");
}

void QWSDisplay::Data::waitForRegionAck(int winId)
{
    QWSEvent *ack = 0;

    if (csocket) { // GuiClient
        int i = 0;
        while (!ack) {
            fillQueue();

            while (i < queue.size()) {
                QWSEvent *e = queue.at(i);
                if (e->type == QWSEvent::Region && e->window() == winId) {
                    ack = e;
                    queue.removeAt(i);
                    break;
                }
                ++i;
            }

            if (!ack) {
                csocket->flush();
                csocket->waitForReadyRead(1000);
            }
        }
    } else { // GuiServer
        fillQueue();
        for (int i = 0; i < queue.size(); /* nothing */) {
            QWSEvent *e = queue.at(i);
            if (e->type == QWSEvent::Region && e->window() == winId) {
                ack = e;
                queue.removeAt(i);
                break;
            }
            ++i;
        }
        if (!ack) // already processed
            return;
    }

    Q_ASSERT(ack);

    qApp->qwsProcessEvent(ack);
    delete ack;
    region_events_count--;
}

void QWSDisplay::Data::waitForRegionEvents(int winId, bool ungrabDisplay)
{
    if (!clientLock)
        return;

    int removedEventsCount = 0;

    // fill queue with unreceived region events
    if (!clientLock->hasLock(QWSLock::RegionEvent)) {
        bool ungrabbed = false;
        if (ungrabDisplay && QWSDisplay::grabbed()) {
            QWSDisplay::ungrab();
            ungrabbed = true;
        }

        for (;;) {
            fillQueue();
            if (clientLock->hasLock(QWSLock::RegionEvent))
                break;
            csocket->flush();
            csocket->waitForReadyRead(1000);
        }

        if (ungrabbed)
            QWSDisplay::grab(true);
    }

    // check the queue for pending region events
    QWSEvent *regionEvent = 0;
    for (int i = 0; i < queue.size(); /* nothing */) {
        QWSEvent *e = queue.at(i);
        if (e->type == QWSEvent::Region && e->window() == winId) {
            QWSRegionEvent *re = static_cast<QWSRegionEvent*>(e);
            if (re->simpleData.type == QWSRegionEvent::Allocation) {
                delete regionEvent;
                regionEvent = re;
            }
            queue.removeAt(i);
            removedEventsCount++;
        } else {
            ++i;
        }
    }

    if (regionEvent) {
        qApp->qwsProcessEvent(regionEvent);
        delete regionEvent;
    }
    region_events_count -= removedEventsCount;
}

bool QWSDisplay::Data::hasPendingRegionEvents() const
{
    if (clientLock && !clientLock->hasLock(QWSLock::RegionEvent))
        return true;

    return region_events_count > 0;
}

#endif // QT_NO_QWS_MULTIPROCESS

void QWSDisplay::Data::waitForCreation()
{
    fillQueue();
#ifndef QT_NO_QWS_MULTIPROCESS
    while (unused_identifiers.count() == 0) {
        if (csocket) {
            csocket->flush();
            csocket->waitForReadyRead(1000);
        }
        fillQueue();
    }
#endif
}


#ifndef QT_NO_QWS_MULTIPROCESS
void QWSDisplay::Data::waitForPropertyReply()
{
    if (!csocket)
        return;
    fillQueue();
    while (qt_fbdpy->getPropertyLen == -2) {
        csocket->flush();
        csocket->waitForReadyRead(1000);
        fillQueue();
    }
}
#endif

#ifndef QT_NO_COP
void QWSDisplay::Data::waitForQCopResponse()
{
    for (;;) {
        fillQueue();
        if (qcop_response)
            break;
#ifndef QT_NO_QWS_MULTIPROCESS
        if (csocket) {
            csocket->flush();
            csocket->waitForReadyRead(1000);
        }
#endif
    }
    queue.prepend(qcop_response);
    qcop_response = 0;
}
#endif

/*!
    \class QWSDisplay
    \brief The QWSDisplay class provides a display for QWS; it is an internal class.

    \internal

    \ingroup qws
*/

QWSDisplay::QWSDisplay()
{
    d = new Data(0, qws_single_process);
}

QWSDisplay::~QWSDisplay()
{
    delete d;
    delete lock;
    lock = 0;
}

bool QWSDisplay::grabbed()
{
    return lock->locked();
}

void QWSDisplay::grab()
{
    lock->lock(QLock::Read);
}

void QWSDisplay::grab(bool write)
{
    lock->lock(write ? QLock::Write : QLock::Read);

}
void QWSDisplay::ungrab()
{
    lock->unlock();
}

#if 0
QWSRegionManager *QWSDisplay::regionManager() const
{
    return d->rgnMan;
}
#endif

bool QWSDisplay::eventPending() const
{
#ifndef QT_NO_QWS_MULTIPROCESS
    d->flush();
#endif
    d->fillQueue();
    return d->queueNotEmpty();
}


/*
  Caller must delete return value!
 */
QWSEvent *QWSDisplay::getEvent()
{
    d->fillQueue();
    Q_ASSERT(d->queueNotEmpty());
    QWSEvent* e = d->dequeue();

    return e;
}

uchar* QWSDisplay::frameBuffer() const { return qt_screen->base(); }
int QWSDisplay::width() const { return qt_screen->width(); }
int QWSDisplay::height() const { return qt_screen->height(); }
int QWSDisplay::depth() const { return qt_screen->depth(); }
int QWSDisplay::pixmapDepth() const { return qt_screen->pixmapDepth(); }
bool QWSDisplay::supportsDepth(int depth) const { return qt_screen->supportsDepth(depth); }
uchar *QWSDisplay::sharedRam() const { return d->sharedRam; }
int QWSDisplay::sharedRamSize() const { return d->sharedRamSize; }

#ifndef QT_NO_QWS_PROPERTIES

void QWSDisplay::addProperty(int winId, int property)
{
    QWSAddPropertyCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.property = property;
    d->sendCommand(cmd);
}

void QWSDisplay::setProperty(int winId, int property, int mode, const QByteArray &data)
{
    QWSSetPropertyCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.property = property;
    cmd.simpleData.mode = mode;
    cmd.setData(data.constData(), data.size());
    d->sendCommand(cmd);
}

void QWSDisplay::setProperty(int winId, int property, int mode,
                              const char * data)
{
    QWSSetPropertyCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.property = property;
    cmd.simpleData.mode = mode;
    cmd.setData(data, strlen(data));
    d->sendCommand(cmd);
}

void QWSDisplay::removeProperty(int winId, int property)
{
    QWSRemovePropertyCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.property = property;
    d->sendCommand(cmd);
}

/*
    It is the caller's responsibility to delete[] \a data.
 */
bool QWSDisplay::getProperty(int winId, int property, char *&data, int &len)
{
    if (d->directServerConnection()) {
        const char *propertyData;
        bool retval = qwsServer->d_func()->get_property(winId, property, propertyData, len);
        if (len <= 0) {
            data = 0;
        } else {
            data = new char[len];
            memcpy(data, propertyData, len) ;
        }
        return retval;
    }
    QWSGetPropertyCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.property = property;
    d->sendCommand(cmd);

    getPropertyLen = -2;
    getPropertyData = 0;

#ifndef QT_NO_QWS_MULTIPROCESS
    d->waitForPropertyReply();
#endif

    len = getPropertyLen;
    data = getPropertyData;

    getPropertyLen = -2;
    getPropertyData = 0;

    return len != -1;
}

#endif // QT_NO_QWS_PROPERTIES

void QWSDisplay::setAltitude(int winId, int alt, bool fixed)
{
    QWSChangeAltitudeCommand cmd;
#ifdef QT_DEBUG
    memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
#endif
    cmd.simpleData.windowid = winId;
    cmd.simpleData.altitude = QWSChangeAltitudeCommand::Altitude(alt);
    cmd.simpleData.fixed = fixed;
    if (d->directServerConnection()) {
        qwsServer->d_func()->set_altitude(&cmd);
    } else {
        d->sendSynchronousCommand(cmd);
    }
}

void QWSDisplay::setOpacity(int winId, int opacity)
{
    QWSSetOpacityCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.opacity = opacity;
    if (d->directServerConnection()) {
        qwsServer->d_func()->set_opacity(&cmd);
    } else {
        d->sendCommand(cmd);
    }
}



void QWSDisplay::requestFocus(int winId, bool get)
{
    QWSRequestFocusCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.flag = get;
    if (d->directServerConnection())
        qwsServer->d_func()->request_focus(&cmd);
    else
        d->sendCommand(cmd);
}

void QWSDisplay::setIdentity(const QString &appName)
{
    QWSIdentifyCommand cmd;
#ifdef QT_NO_QWS_MULTIPROCESS
    const int id = -1;
#else
    const int id = QWSDisplay::Data::clientLock ? QWSDisplay::Data::clientLock->id() : -1;
#endif
    cmd.setId(appName, id);
    if (d->directServerConnection())
        qwsServer->d_func()->set_identity(&cmd);
    else
        d->sendCommand(cmd);
}

void QWSDisplay::nameRegion(int winId, const QString& n, const QString &c)
{
    QWSRegionNameCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.setName(n, c);
    if (d->directServerConnection())
        qwsServer->d_func()->name_region(&cmd);
    else
        d->sendCommand(cmd);
}

void QWSDisplay::requestRegion(int winId, const QString &surfaceKey,
                               const QByteArray &surfaceData,
                               const QRegion &region)
{
    if (d->directServerConnection()) {
        qwsServer->d_func()->request_region(winId, surfaceKey,
                                            surfaceData, region);
    } else {
        QWSRegionCommand cmd;
        cmd.setData(winId, surfaceKey, surfaceData, region);
        d->sendSynchronousCommand(cmd);
    }
}

void QWSDisplay::repaintRegion(int winId, int windowFlags, bool opaque, QRegion r)
{
    if (d->directServerConnection()) {
        qwsServer->d_func()->repaint_region(winId, windowFlags, opaque, r);
    } else {
        QVector<QRect> ra = r.rects();

        /*
          for (int i = 0; i < ra.size(); i++) {
          QRect r(ra[i]);
          qDebug("rect: %d %d %d %d", r.x(), r.y(), r.right(), r.bottom());
          }
        */

        QWSRepaintRegionCommand cmd;
    /* XXX QWSRegionCommand is padded out in a compiler dependent way.
       Zeroed out to avoid valgrind reporting uninitialized memory usage.
       */
#ifdef QT_DEBUG
        memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
#endif
        cmd.simpleData.windowid = winId;
        cmd.simpleData.windowFlags = windowFlags;
        cmd.simpleData.opaque = opaque;
        cmd.simpleData.nrectangles = ra.count();
        cmd.setData(reinterpret_cast<const char *>(ra.constData()),
                    ra.count() * sizeof(QRect), false);

        d->sendSynchronousCommand(cmd);
    }
}


void QWSDisplay::moveRegion(int winId, int dx, int dy)
{
    QWSRegionMoveCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.dx = dx;
    cmd.simpleData.dy = dy;

    if (d->directServerConnection()) {
        qwsServer->d_func()->move_region(&cmd);
    } else {
        d->sendSynchronousCommand(cmd);
    }
//    d->offsetPendingExpose(winId, QPoint(cmd.simpleData.dx, cmd.simpleData.dy));
}

void QWSDisplay::destroyRegion(int winId)
{
    QWSRegionDestroyCommand cmd;
    cmd.simpleData.windowid = winId;
    if (d->directServerConnection()) {
        qwsServer->d_func()->destroy_region(&cmd);
    } else {
        d->sendCommand(cmd);
    }
}

#ifndef QT_NO_QWS_INPUTMETHODS

void QWSDisplay::sendIMUpdate(int type, int winId, int widgetid)
{
    QWSIMUpdateCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.widgetid = widgetid;

    cmd.simpleData.type = type;

      if (d->directServerConnection()) {
        qwsServer->d_func()->im_update(&cmd);
    } else {
        d->sendCommand(cmd);
    }
}

void QWSDisplay::sendIMResponse(int winId, int property, const QVariant &result)
{
    QWSIMResponseCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.property = property;

    cmd.setResult(result);

    if (d->directServerConnection()) {
        qwsServer->d_func()->im_response(&cmd);
    } else {
        d->sendCommand(cmd);
    }
}

void QWSDisplay::resetIM()
{
    sendIMUpdate(QWSInputMethod::Reset, -1, -1);
}

void QWSDisplay::sendIMMouseEvent(int index, bool isPress)
{
    QWSIMMouseCommand cmd;
    cmd.simpleData.index = index;
    cmd.simpleData.state = isPress ? QWSServer::MousePress : QWSServer::MouseRelease;
    if (d->directServerConnection()) {
        qwsServer->d_func()->send_im_mouse(&cmd);
    } else {
        d->sendCommand(cmd);
    }
}

#endif

int QWSDisplay::takeId()
{
    return d->takeId();
}

bool QWSDisplay::initLock(const QString &filename, bool create)
{
    if (!lock) {
        lock = new QLock(filename, 'd', create);

        if (!lock->isValid()) {
            delete lock;
            lock = 0;
            return false;
        }
    }

    return true;
}

void QWSDisplay::setSelectionOwner(int winId, const QTime &time)
{
    QWSSetSelectionOwnerCommand cmd;
    cmd.simpleData.windowid = winId;
    cmd.simpleData.hour = time.hour();
    cmd.simpleData.minute = time.minute();
    cmd.simpleData.sec = time.second();
    cmd.simpleData.ms = time.msec();
    d->sendCommand(cmd);
}

void QWSDisplay::convertSelection(int winId, int selectionProperty, const QString &mimeTypes)
{
#ifdef QT_NO_QWS_PROPERTIES
    Q_UNUSED(mimeTypes);
#else
    // ### we need the atom/property thingy like in X here
    addProperty(winId, QT_QWS_PROPERTY_CONVERTSELECTION);
    setProperty(winId, QT_QWS_PROPERTY_CONVERTSELECTION,
                 int(QWSPropertyManager::PropReplace), mimeTypes.toLatin1());
#endif
    QWSConvertSelectionCommand cmd;
    cmd.simpleData.requestor = winId;
    cmd.simpleData.selection = selectionProperty;
    cmd.simpleData.mimeTypes = QT_QWS_PROPERTY_CONVERTSELECTION;
    d->sendCommand(cmd);
}

void QWSDisplay::defineCursor(int id, const QBitmap &curs, const QBitmap &mask,
                            int hotX, int hotY)
{
    const QImage cursImg = curs.toImage().convertToFormat(QImage::Format_MonoLSB);
    const QImage maskImg = mask.toImage().convertToFormat(QImage::Format_MonoLSB);

    QWSDefineCursorCommand cmd;
    cmd.simpleData.width = curs.width();
    cmd.simpleData.height = curs.height();
    cmd.simpleData.hotX = hotX;
    cmd.simpleData.hotY = hotY;
    cmd.simpleData.id = id;


    // must copy each scanline since there might be gaps between them
    const int height = curs.height();
    const int width = curs.width();
    const int dst_bpl = (width + 7) / 8;

    int dataLen = dst_bpl * height;
    uchar *data = new uchar[dataLen*2];
    uchar *dst = data;

    int src_bpl = cursImg.bytesPerLine();
    const uchar *cursSrc = cursImg.bits();
    for (int i = 0; i < height; ++i) {
        memcpy(dst, cursSrc + i*src_bpl, dst_bpl);
        dst += dst_bpl;
    }

    src_bpl = maskImg.bytesPerLine();
    const uchar *maskSrc = maskImg.bits();
    for (int i = 0; i < height; ++i) {
        memcpy(dst, maskSrc + i*src_bpl, dst_bpl);
        dst += dst_bpl;
    }

    cmd.setData(reinterpret_cast<char*>(data), dataLen*2);
    delete [] data;
    d->sendCommand(cmd);
}

void QWSDisplay::destroyCursor(int id)
{
    QWSDefineCursorCommand cmd;
    cmd.simpleData.width = 0;
    cmd.simpleData.height = 0;
    cmd.simpleData.hotX = 0;
    cmd.simpleData.hotY = 0;
    cmd.simpleData.id = id;
    cmd.setData(0, 0);

    d->sendCommand(cmd);
}

#ifndef QT_NO_SOUND
void QWSDisplay::playSoundFile(const QString& f)
{
    QWSPlaySoundCommand cmd;
    cmd.setFileName(f);
    d->sendCommand(cmd);
}
#endif

#ifndef QT_NO_COP
void QWSDisplay::registerChannel(const QString& channel)
{
    QWSQCopRegisterChannelCommand reg;
    reg.setChannel(channel);
    qt_fbdpy->d->sendCommand(reg);
}

void QWSDisplay::sendMessage(const QString &channel, const QString &msg,
                   const QByteArray &data)
{
    QWSQCopSendCommand com;
    com.setMessage(channel, msg, data);
    qt_fbdpy->d->sendCommand(com);
}

void QWSDisplay::flushCommands()
{
    qt_fbdpy->d->flushCommands();
}

/*
  caller deletes result
*/
QWSQCopMessageEvent* QWSDisplay::waitForQCopResponse()
{
    qt_fbdpy->d->waitForQCopResponse();
    QWSQCopMessageEvent *e = static_cast<QWSQCopMessageEvent*>(qt_fbdpy->d->dequeue());
    Q_ASSERT(e->type == QWSEvent::QCopMessage);
    return e;
}
#endif

void QWSDisplay::sendFontCommand(int type, const QByteArray &fontName)
{
    QWSFontCommand cmd;
    cmd.simpleData.type = type;
    cmd.setFontName(fontName);
    d->sendCommand(cmd);
}

void QWSDisplay::setWindowCaption(QWidget *w, const QString &c)
{
    if (w->isWindow()) {
        nameRegion(w->internalWinId(), w->objectName(), c);
        static_cast<QETWidget *>(w)->repaintDecoration(qApp->desktop()->rect(), true);
    }
}

void QWSDisplay::selectCursor(QWidget *w, unsigned int cursId)
{
    if (cursId != qt_last_cursor)
    {
        QWidget *top = w->window();
        qt_last_cursor = cursId;
        QWSSelectCursorCommand cmd;
        cmd.simpleData.windowid = top->internalWinId();
        cmd.simpleData.id = cursId;
        d->sendCommand(cmd);
        d->flush();
    }
}

void QWSDisplay::setCursorPosition(int x, int y)
{
    QWSPositionCursorCommand cmd;
    cmd.simpleData.newX = x;
    cmd.simpleData.newY = y;
    d->sendCommand(cmd);
    d->flush();
}

void QWSDisplay::grabMouse(QWidget *w, bool grab)
{
    QWidget *top = w->window();
    QWSGrabMouseCommand cmd;
#ifdef QT_DEBUG
    memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
#endif
    cmd.simpleData.windowid = top->winId();
    cmd.simpleData.grab = grab;
    d->sendCommand(cmd);
    d->flush();
}

void QWSDisplay::grabKeyboard(QWidget *w, bool grab)
{
    QWidget *top = w->window();
    QWSGrabKeyboardCommand cmd;
#ifdef QT_DEBUG
    memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
#endif
    cmd.simpleData.windowid = top->winId();
    cmd.simpleData.grab = grab;
    d->sendCommand(cmd);
    d->flush();
}

QList<QWSWindowInfo> QWSDisplay::windowList()
{
    QList<QWSWindowInfo> ret;
    if(d->directServerConnection()) {
        QList<QWSInternalWindowInfo*> * qin=QWSServer::windowList();
        for (int i = 0; i < qin->count(); ++i) {
            QWSInternalWindowInfo * qwi = qin->at(i);
            QWSWindowInfo tmp;
            tmp.winid = qwi->winid;
            tmp.clientid = qwi->clientid;
            tmp.name = QString(qwi->name);
            ret.append(tmp);
        }
        qDeleteAll(*qin);
        delete qin;
    }
    return ret;
}

int QWSDisplay::windowAt(const QPoint &p)
{
    //### currently only implemented for the server process
    int ret = 0;
    if(d->directServerConnection()) {
        QWSWindow *win = qwsServer->windowAt(p);
        if (win)
            return win->winId();
    }
    return ret;
}

void QWSDisplay::setRawMouseEventFilter(void (*filter)(QWSMouseEvent *))
{
    if (qt_fbdpy)
        qt_fbdpy->d->setMouseFilter(filter);
}

/*!
  \relates QScreen

  Here it is. \a transformation and \a screenNo
 */
void QWSDisplay::setTransformation(int transformation, int screenNo)
{
    QWSScreenTransformCommand cmd;
    cmd.setTransformation(screenNo, transformation);
    QWSDisplay::instance()->d->sendCommand(cmd);
}

static bool qt_try_modal(QWidget *, QWSEvent *);

/*****************************************************************************
  qt_init() - initializes Qt/FB
 *****************************************************************************/

static void qt_set_qws_resources()

{
    if (QApplication::desktopSettingsAware())
        QApplicationPrivate::qws_apply_settings();

    if (appFont)
        QApplication::setFont(QFont(QString::fromLocal8Bit(appFont)));

    if (appBGCol || appBTNCol || appFGCol) {
        (void) QApplication::style();  // trigger creation of application style and system palettes
        QColor btn;
        QColor bg;
        QColor fg;
        if (appBGCol)
            bg = QColor(appBGCol);
        else
            bg = QApplicationPrivate::sys_pal->color(QPalette::Window);
        if (appFGCol)
            fg = QColor(appFGCol);
        else
            fg = QApplicationPrivate::sys_pal->color(QPalette::WindowText);
        if (appBTNCol)
            btn = QColor(appBTNCol);
        else
            btn = QApplicationPrivate::sys_pal->color(QPalette::Button);

        int h,s,v;
        fg.getHsv(&h,&s,&v);
        QColor base = Qt::white;
        bool bright_mode = false;
        if (v >= 255 - 50) {
            base = btn.darker(150);
            bright_mode = true;
        }

        QPalette pal(fg, btn, btn.lighter(), btn.darker(), btn.darker(150), fg, Qt::white, base, bg);
        if (bright_mode) {
            pal.setColor(QPalette::HighlightedText, base);
            pal.setColor(QPalette::Highlight, Qt::white);
        } else {
            pal.setColor(QPalette::HighlightedText, Qt::white);
            pal.setColor(QPalette::Highlight, Qt::darkBlue);
        }
        QColor disabled((fg.red()   + btn.red())  / 2,
                        (fg.green() + btn.green())/ 2,
                        (fg.blue()  + btn.blue()) / 2);
        pal.setColorGroup(QPalette::Disabled, disabled, btn, btn.lighter(125),
                          btn.darker(), btn.darker(150), disabled, Qt::white, Qt::white, bg);
        if (bright_mode) {
            pal.setColor(QPalette::Disabled, QPalette::HighlightedText, base);
            pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::white);
        } else {
            pal.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::white);
            pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
        }
        QApplicationPrivate::setSystemPalette(pal);

    }
}

void QApplicationPrivate::initializeWidgetPaletteHash()
{
}

/*! \internal
    apply the settings to the application
*/
bool QApplicationPrivate::qws_apply_settings()
{
#ifndef QT_NO_SETTINGS
    QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
    settings.beginGroup(QLatin1String("Qt"));

    QStringList strlist;
    int i;
    QPalette pal(Qt::black);
    int groupCount = 0;
    strlist = settings.value(QLatin1String("Palette/active")).toStringList();
    if (strlist.count() == QPalette::NColorRoles) {
        ++groupCount;
        for (i = 0; i < QPalette::NColorRoles; i++)
            pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
                         QColor(strlist[i]));
    }
    strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
    if (strlist.count() == QPalette::NColorRoles) {
        ++groupCount;
        for (i = 0; i < QPalette::NColorRoles; i++)
            pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
                         QColor(strlist[i]));
    }
    strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
    if (strlist.count() == QPalette::NColorRoles) {
        ++groupCount;
        for (i = 0; i < QPalette::NColorRoles; i++)
            pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
                         QColor(strlist[i]));
    }


    if (groupCount == QPalette::NColorGroups)
        QApplicationPrivate::setSystemPalette(pal);

    QString str = settings.value(QLatin1String("font")).toString();
    if (!str.isEmpty()) {
        QFont font(QApplication::font());
        font.fromString(str);
        QApplicationPrivate::setSystemFont(font);
    }

    // read library (ie. plugin) path list
    QString libpathkey =
        QString::fromLatin1("%1.%2/libraryPath")
        .arg(QT_VERSION >> 16)
        .arg((QT_VERSION & 0xff00) >> 8);
    QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
#ifndef QT_NO_LIBRARY
    if (! pathlist.isEmpty()) {
        QStringList::ConstIterator it = pathlist.constBegin();
        while (it != pathlist.constEnd())
            QApplication::addLibraryPath(*it++);
    }
#endif

    // read new QStyle
    QString stylename = settings.value(QLatin1String("style")).toString();
    if (QCoreApplication::startingUp()) {
        if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull())
            QApplicationPrivate::styleOverride = stylename;
    } else {
        QApplication::setStyle(stylename);
    }

    int num =
        settings.value(QLatin1String("doubleClickInterval"),
                       QApplication::doubleClickInterval()).toInt();
    QApplication::setDoubleClickInterval(num);

    num =
        settings.value(QLatin1String("cursorFlashTime"),
                       QApplication::cursorFlashTime()).toInt();
    QApplication::setCursorFlashTime(num);

#ifndef QT_NO_WHEELEVENT
    num =
        settings.value(QLatin1String("wheelScrollLines"),
                       QApplication::wheelScrollLines()).toInt();
    QApplication::setWheelScrollLines(num);
#endif

    QString colorspec = settings.value(QLatin1String("colorSpec"),
                                       QVariant(QLatin1String("default"))).toString();
    if (colorspec == QLatin1String("normal"))
        QApplication::setColorSpec(QApplication::NormalColor);
    else if (colorspec == QLatin1String("custom"))
        QApplication::setColorSpec(QApplication::CustomColor);
    else if (colorspec == QLatin1String("many"))
        QApplication::setColorSpec(QApplication::ManyColor);
    else if (colorspec != QLatin1String("default"))
        colorspec = QLatin1String("default");

#ifndef QT_NO_TEXTCODEC
    QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
                                          QVariant(QLatin1String("none"))).toString();
    if (defaultcodec != QLatin1String("none")) {
        QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
        if (codec)
            QTextCodec::setCodecForTr(codec);
    }
#endif

    int w = settings.value(QLatin1String("globalStrut/width")).toInt();
    int h = settings.value(QLatin1String("globalStrut/height")).toInt();
    QSize strut(w, h);
    if (strut.isValid())
        QApplication::setGlobalStrut(strut);

    QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
    QApplication::setEffectEnabled(Qt::UI_General,
                                   effects.contains(QLatin1String("general")));
    QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
                                   effects.contains(QLatin1String("animatemenu")));
    QApplication::setEffectEnabled(Qt::UI_FadeMenu,
                                   effects.contains(QLatin1String("fademenu")));
    QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
                                   effects.contains(QLatin1String("animatecombo")));
    QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
                                   effects.contains(QLatin1String("animatetooltip")));
    QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
                                   effects.contains(QLatin1String("fadetooltip")));
    QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
                                   effects.contains(QLatin1String("animatetoolbox")));

    settings.beginGroup(QLatin1String("Font Substitutions"));
    QStringList fontsubs = settings.childKeys();
    if (!fontsubs.isEmpty()) {
        QStringList::Iterator it = fontsubs.begin();
        for (; it != fontsubs.end(); ++it) {
            QString fam = *it;
            QStringList subs = settings.value(fam).toStringList();
            QFont::insertSubstitutions(fam, subs);
        }
    }
    settings.endGroup();

    settings.endGroup(); // Qt

    settings.beginGroup(QLatin1String("QWS Font Fallbacks"));
    if (!settings.childKeys().isEmpty()) {
        // from qfontdatabase_qws.cpp
        extern void qt_applyFontDatabaseSettings(const QSettings &);
        qt_applyFontDatabaseSettings(settings);
    }
    settings.endGroup();

    return true;
#else
    return false;
#endif // QT_NO_SETTINGS
}



static void init_display()
{
    if (qt_fbdpy) return; // workaround server==client case

    // Connect to FB server
    qt_fbdpy = new QWSDisplay();

    // Get display parameters
    // Set paintdevice parameters
    // XXX initial info sent from server
    // Misc. initialization

    QColormap::initialize();
    QFont::initialize();
#ifndef QT_NO_CURSOR
    QCursorData::initialize();
#endif

    qApp->setObjectName(appName);

    if (!QApplicationPrivate::sys_font) {
#ifdef QT_NO_FREETYPE
        QFont f = QFont(QLatin1String("helvetica"), 10);
#else
        QFont f = QFont(QLatin1String("DejaVu Sans"), 12);
#endif
        QApplicationPrivate::setSystemFont(f);
    }
    qt_set_qws_resources();
}

void qt_init_display()
{
    qt_is_gui_used = true;
    qws_single_process = true;
    init_display();
}

static bool read_bool_env_var(const char *var, bool defaultvalue)
{
    // returns true if env variable is set to non-zero
    // returns false if env var is set to zero
    // returns defaultvalue if env var not set
    char *x = ::getenv(var);
    return (x && *x) ? (strcmp(x,"0") != 0) : defaultvalue;
}

static int read_int_env_var(const char *var, int defaultvalue)
{
    bool ok;
    int r = qgetenv(var).toInt(&ok);
    return ok ? r : defaultvalue;
}

void qt_init(QApplicationPrivate *priv, int type)
{
#ifdef QT_NO_QWS_MULTIPROCESS
    if (type == QApplication::GuiClient)
        type = QApplication::GuiServer;
#endif
    if (type == QApplication::GuiServer)
        qt_is_gui_used = false; //we'll turn it on in a second
    qws_sw_cursor = read_bool_env_var("QWS_SW_CURSOR",qws_sw_cursor);
    qws_screen_is_interlaced = read_bool_env_var("QWS_INTERLACE",false);

    const char *display = ::getenv("QWS_DISPLAY");
    if (display)
        qws_display_spec = display; // since we setenv later!

    //qws_savefonts = qgetenv("QWS_SAVEFONTS") != 0;
    //qws_shared_memory = qgetenv("QWS_NOSHARED") == 0;

    mouse_double_click_distance = read_int_env_var("QWS_DBLCLICK_DISTANCE", 5);

    priv->inputContext = 0;

    int flags = 0;
    char *p;
    int argc = priv->argc;
    char **argv = priv->argv;
    int j;

    // Set application name

    if (argv && *argv) { //apparently, we allow people to pass 0 on the other platforms
        p = strrchr(argv[0], '/');
        appName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
    }

    // Get command line params

    j = argc ? 1 : 0;
    QString decoration;
    for (int i=1; i<argc; i++) {
        if (argv[i] && *argv[i] != '-') {
            argv[j++] = argv[i];
            continue;
        }
        QByteArray arg = argv[i];
        if (arg == "-fn" || arg == "-font") {
            if (++i < argc)
                appFont = argv[i];
        } else if (arg == "-bg" || arg == "-background") {
            if (++i < argc)
                appBGCol = argv[i];
        } else if (arg == "-btn" || arg == "-button") {
            if (++i < argc)
                appBTNCol = argv[i];
        } else if (arg == "-fg" || arg == "-foreground") {
            if (++i < argc)
                appFGCol = argv[i];
        } else if (arg == "-name") {
            if (++i < argc)
                appName = QString::fromLocal8Bit(argv[i]);
        } else if (arg == "-title") {
            if (++i < argc)
                mwTitle = argv[i];
        } else if (arg == "-geometry") {
            if (++i < argc)
                mwGeometry = argv[i];
        } else if (arg == "-shared") {
            qws_shared_memory = true;
        } else if (arg == "-noshared") {
            qws_shared_memory = false;
        } else if (arg == "-savefonts") {
            qws_savefonts = true;
        } else if (arg == "-nosavefonts") {
            qws_savefonts = false;
        } else if (arg == "-swcursor") {
            qws_sw_cursor = true;
        } else if (arg == "-noswcursor") {
            qws_sw_cursor = false;
        } else if (arg == "-keyboard") {
            flags &= ~QWSServer::DisableKeyboard;
        } else if (arg == "-nokeyboard") {
            flags |= QWSServer::DisableKeyboard;
        } else if (arg == "-mouse") {
            flags &= ~QWSServer::DisableMouse;
        } else if (arg == "-nomouse") {
            flags |= QWSServer::DisableMouse;
        } else if (arg == "-qws") {
            type = QApplication::GuiServer;
        } else if (arg == "-interlaced") {
            qws_screen_is_interlaced = true;
        } else if (arg == "-display") {
            if (++i < argc)
                qws_display_spec = argv[i];
        } else if (arg == "-decoration") {
            if (++i < argc)
                decoration = QString::fromLocal8Bit(argv[i]);
        } else {
            argv[j++] = argv[i];
        }
    }
    if(j < priv->argc) {
        priv->argv[j] = 0;
        priv->argc = j;
    }

    mouseInWidget = new QPointer<QWidget>;

    const QString disp = QString::fromLatin1(qws_display_spec);
    QRegExp regexp(QLatin1String(":(\\d+)$"));
    if (regexp.lastIndexIn(disp) != -1) {
        const QString capture = regexp.cap(1);
        bool ok = false;
        int id = capture.toInt(&ok);
        if (ok)
            qws_display_id = id;
    }

    if (type == QApplication::GuiServer) {
        qt_appType = QApplication::Type(type);
        qws_single_process = true;
        QWSServer::startup(flags);
        if (!display) // if not already set
            qputenv("QWS_DISPLAY", qws_display_spec);
    }

    if(qt_is_gui_used) {
        init_display();
#ifndef QT_NO_QWS_MANAGER
        if (decoration.isEmpty() && !qws_decoration) {
            const QStringList keys = QDecorationFactory::keys();
            if (!keys.isEmpty())
                decoration = keys.first();
        }
        if (!decoration.isEmpty())
            qws_decoration = QApplication::qwsSetDecoration(decoration);
#endif // QT_NO_QWS_MANAGER
#ifndef QT_NO_QWS_INPUTMETHODS
        qApp->setInputContext(new QWSInputContext(qApp));
#endif
    }

/*### convert interlace style
    if (qws_screen_is_interlaced)
        QApplication::setStyle(new QInterlaceStyle);
*/
}

/*****************************************************************************
  qt_cleanup() - cleans up when the application is finished
 *****************************************************************************/

void qt_cleanup()
{
    QPixmapCache::clear();
#ifndef QT_NO_CURSOR
    QCursorData::cleanup();
#endif
    QFont::cleanup();
    QColormap::cleanup();

    if (qws_single_process) {
        QWSServer::closedown();
    }

    qDeleteAll(outgoing);
    outgoing.clear();
    qDeleteAll(incoming);
    incoming.clear();

    if (qt_is_gui_used) {
        delete qt_fbdpy;
    }
    qt_fbdpy = 0;

#ifndef QT_NO_QWS_MANAGER
    delete qws_decoration;
    qws_decoration = 0;
#endif

    delete mouseInWidget;
    mouseInWidget = 0;

#if !defined(QT_NO_IM)
    delete QApplicationPrivate::inputContext;
    QApplicationPrivate::inputContext = 0;
#endif
}


/*****************************************************************************
  Platform specific global and internal functions
 *****************************************************************************/

QString QApplicationPrivate::appName() const // get application name
{
    return QT_PREPEND_NAMESPACE(appName);
}

/*****************************************************************************
  Platform specific QApplication members
 *****************************************************************************/

#define NoValue         0x0000
#define XValue          0x0001
#define YValue          0x0002
#define WidthValue      0x0004
#define HeightValue     0x0008
#define AllValues       0x000F
#define XNegative       0x0010
#define YNegative       0x0020

/* Copyright notice for ReadInteger and parseGeometry

Copyright (c) 1985, 1986, 1987  X Consortium

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from the X Consortium.

*/
/*
 *    XParseGeometry parses strings of the form
 *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
 *   width, height, xoffset, and yoffset are unsigned integers.
 *   Example:  "=80x24+300-49"
 *   The equal sign is optional.
 *   It returns a bitmask that indicates which of the four values
 *   were actually found in the string. For each value found,
 *   the corresponding argument is updated;  for each value
 *   not found, the corresponding argument is left unchanged.
 */

static int
ReadInteger(char *string, char **NextString)
{
    register int Result = 0;
    int Sign = 1;

    if (*string == '+')
        string++;
    else if (*string == '-')
    {
        string++;
        Sign = -1;
    }
    for (; (*string >= '0') && (*string <= '9'); string++)
    {
        Result = (Result * 10) + (*string - '0');
    }
    *NextString = string;
    if (Sign >= 0)
        return Result;
    else
        return -Result;
}

static int parseGeometry(const char* string,
                          int* x, int* y, int* width, int* height)
{
        int mask = NoValue;
        register char *strind;
        unsigned int tempWidth=0, tempHeight=0;
        int tempX=0, tempY=0;
        char *nextCharacter;

        if (!string || (*string == '\0')) return mask;
        if (*string == '=')
                string++;  /* ignore possible '=' at beg of geometry spec */

        strind = const_cast<char *>(string);
        if (*strind != '+' && *strind != '-' && *strind != 'x') {
                tempWidth = ReadInteger(strind, &nextCharacter);
                if (strind == nextCharacter)
                    return 0;
                strind = nextCharacter;
                mask |= WidthValue;
        }

        if (*strind == 'x' || *strind == 'X') {
                strind++;
                tempHeight = ReadInteger(strind, &nextCharacter);
                if (strind == nextCharacter)
                    return 0;
                strind = nextCharacter;
                mask |= HeightValue;
        }

        if ((*strind == '+') || (*strind == '-')) {
                if (*strind == '-') {
                        strind++;
                        tempX = -ReadInteger(strind, &nextCharacter);
                        if (strind == nextCharacter)
                            return 0;
                        strind = nextCharacter;
                        mask |= XNegative;

                }
                else
                {        strind++;
                        tempX = ReadInteger(strind, &nextCharacter);
                        if (strind == nextCharacter)
                            return 0;
                        strind = nextCharacter;
                }
                mask |= XValue;
                if ((*strind == '+') || (*strind == '-')) {
                        if (*strind == '-') {
                                strind++;
                                tempY = -ReadInteger(strind, &nextCharacter);
                                if (strind == nextCharacter)
                                    return 0;
                                strind = nextCharacter;
                                mask |= YNegative;

                        }
                        else
                        {
                                strind++;
                                tempY = ReadInteger(strind, &nextCharacter);
                                if (strind == nextCharacter)
                                    return 0;
                                strind = nextCharacter;
                        }
                        mask |= YValue;
                }
        }

        /* If strind isn't at the end of the string then it's an invalid
                geometry specification. */

        if (*strind != '\0') return 0;

        if (mask & XValue)
            *x = tempX;
        if (mask & YValue)
            *y = tempY;
        if (mask & WidthValue)
            *width = tempWidth;
        if (mask & HeightValue)
            *height = tempHeight;
        return mask;
}

#ifdef QT3_SUPPORT
void QApplication::setMainWidget(QWidget *mainWidget)
{
    QApplicationPrivate::main_widget = mainWidget;
    if (QApplicationPrivate::main_widget) // give WM command line
        QApplicationPrivate::applyQWSSpecificCommandLineArguments(QApplicationPrivate::main_widget);
}
#endif

void QApplicationPrivate::applyQWSSpecificCommandLineArguments(QWidget *main_widget)
{
    static bool beenHereDoneThat = false;
    if (beenHereDoneThat)
        return;
    beenHereDoneThat = true;
    if (qApp->windowIcon().isNull() && main_widget->testAttribute(Qt::WA_SetWindowIcon))
        qApp->setWindowIcon(main_widget->windowIcon());
    if (mwTitle) //  && main_widget->windowTitle().isEmpty())
        main_widget->setWindowTitle(QString::fromLocal8Bit(mwTitle));
    if (mwGeometry) { // parse geometry
        int x = 0;
        int y = 0;
        int w = 0;
        int h = 0;
        int m = parseGeometry(mwGeometry, &x, &y, &w, &h);
        QSize minSize = main_widget->minimumSize();
        QSize maxSize = main_widget->maximumSize();
        if ((m & XValue) == 0)
            x = main_widget->geometry().x();
        if ((m & YValue) == 0)
            y = main_widget->geometry().y();
        if ((m & WidthValue) == 0)
            w = main_widget->width();
        if ((m & HeightValue) == 0)
            h = main_widget->height();
        w = qMin(w,maxSize.width());
        h = qMin(h,maxSize.height());
        w = qMax(w,minSize.width());
        h = qMax(h,minSize.height());
        if ((m & XNegative)) {
            x = qApp->desktop()->width()  + x - w;
            x -= (main_widget->frameGeometry().width() - main_widget->width()) / 2;
        } else {
            x += (main_widget->geometry().x() - main_widget->x());
        }
        if ((m & YNegative)) {
            y = qApp->desktop()->height() + y - h;
        } else {
            y += (main_widget->geometry().y() - main_widget->y());
        }

        main_widget->setGeometry(x, y, w, h);
    }
}

/*****************************************************************************
  QApplication cursor stack
 *****************************************************************************/
#ifndef QT_NO_CURSOR
void QApplication::setOverrideCursor(const QCursor &cursor)
{
    qApp->d_func()->cursor_list.prepend(cursor);

    QWidget *w = QWidget::mouseGrabber();
    if (!w && qt_last_x)
        w = topLevelAt(*qt_last_x, *qt_last_y);
    if (!w)
        w = desktop();
    QPaintDevice::qwsDisplay()->selectCursor(w, qApp->d_func()->cursor_list.first().handle());
}

void QApplication::restoreOverrideCursor()
{
    if (qApp->d_func()->cursor_list.isEmpty())
        return;
    qApp->d_func()->cursor_list.removeFirst();

    QWidget *w = QWidget::mouseGrabber();
    if (!w && qt_last_x)
        w = topLevelAt(*qt_last_x, *qt_last_y);
    if (!w)
        w = desktop();

    int cursor_handle = Qt::ArrowCursor;
    if (qApp->d_func()->cursor_list.isEmpty()) {
        qws_overrideCursor = false;
        QWidget *upw = QApplication::widgetAt(*qt_last_x, *qt_last_y);
        if (upw)
            cursor_handle = upw->cursor().handle();
    } else {
        cursor_handle = qApp->d_func()->cursor_list.first().handle();
    }
    QPaintDevice::qwsDisplay()->selectCursor(w, cursor_handle);
}
#endif// QT_NO_CURSOR



/*****************************************************************************
  Routines to find a Qt widget from a screen position
 *****************************************************************************/

/*!
    \internal
*/
QWidget *QApplicationPrivate::findWidget(const QObjectList& list,
                                   const QPoint &pos, bool rec)
{
    QWidget *w;

    for (int i = list.size()-1; i >= 0; --i) {
        if (list.at(i)->isWidgetType()) {
          w = static_cast<QWidget*>(list.at(i));
            if (w->isVisible() && !w->testAttribute(Qt::WA_TransparentForMouseEvents) &&  w->geometry().contains(pos)
                && (!w->d_func()->extra || w->d_func()->extra->mask.isEmpty() ||  w->d_func()->extra->mask.contains(pos - w->geometry().topLeft()) )) {
                if (!rec)
                    return w;
                QWidget *c = w->childAt(w->mapFromParent(pos));
                return c ? c : w;
            }
        }
    }
    return 0;
}


QWidget *QApplication::topLevelAt(const QPoint &pos)
{
    //### QWSDisplay::windowAt() is currently only implemented in the server process
    int winId = QPaintDevice::qwsDisplay()->windowAt(pos);
    if (winId !=0)
        return QWidget::find(winId);

#if 1
    // fallback implementation for client processes
//### This is slightly wrong: we have no guarantee that the list is in
//### stacking order, so if the topmost window is transparent, we may
//### return the wrong widget

    QWidgetList list = topLevelWidgets();
    for (int i = list.size()-1; i >= 0; --i) {
        QWidget *w = list[i];
        if (w != QApplication::desktop() &&
             w->isVisible() && w->d_func()->localAllocatedRegion().contains(w->mapFromParent(pos))
            )
            return w;
    }
#endif
    return 0;
}

void QApplication::beep()
{
}

void QApplication::alert(QWidget *, int)
{
}

int QApplication::qwsProcessEvent(QWSEvent* event)
{
    Q_D(QApplication);
    QScopedLoopLevelCounter loopLevelCounter(d->threadData);
    int oldstate = -1;
    bool isMove = false;
    if (event->type == QWSEvent::Mouse) {
        QWSMouseEvent::SimpleData &mouse = event->asMouse()->simpleData;
        isMove = mouse_x_root != mouse.x_root || mouse_y_root != mouse.y_root;
        oldstate = mouse_state;
        mouse_x_root = mouse.x_root;
        mouse_y_root = mouse.y_root;
        mouse_state = mouse.state;
    }

    long unused;
    if (filterEvent(event, &unused))                  // send through app filter
        return 1;

    if (qwsEventFilter(event))                        // send through app filter
        return 1;


#ifndef QT_NO_QWS_PROPERTIES
    if (event->type == QWSEvent::PropertyNotify) {
        QWSPropertyNotifyEvent *e = static_cast<QWSPropertyNotifyEvent*>(event);
        if (e->simpleData.property == 424242) {       // Clipboard
#ifndef QT_NO_CLIPBOARD
            if (qt_clipboard) {
                QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
                QApplication::sendEvent(qt_clipboard, &e);
            }
#endif
        }
    }
#endif //QT_NO_QWS_PROPERTIES
#ifndef QT_NO_COP
    else if (event->type == QWSEvent::QCopMessage) {
        QWSQCopMessageEvent *e = static_cast<QWSQCopMessageEvent*>(event);
        QCopChannel::sendLocally(QLatin1String(e->channel), QLatin1String(e->message), e->data);
        return 0;
    }
#endif
#if !defined(QT_NO_QWS_QPF2)
    else if (event->type == QWSEvent::Font) {
        QWSFontEvent *e = static_cast<QWSFontEvent *>(event);
        if (e->simpleData.type == QWSFontEvent::FontRemoved) {
            QFontCache::instance()->removeEngineForFont(e->fontName);
        }
    }
#endif

    QPointer<QETWidget> widget = static_cast<QETWidget*>(QWidget::find(WId(event->window())));
#ifdef Q_BACKINGSTORE_SUBSURFACES
    if (!widget) { // XXX: hw: hack for accessing subsurfaces
        extern QWSWindowSurface* qt_findWindowSurface(int);
        QWSWindowSurface *s = qt_findWindowSurface(event->window());
        if (s)
            widget = static_cast<QETWidget*>(s->window());
    }
#endif

#ifndef QT_NO_DIRECTPAINTER
    if (!widget && d->directPainters) {
        QDirectPainter *dp = d->directPainters->value(WId(event->window()));
        if (dp == 0) {
        } else if (event->type == QWSEvent::Region) {
            QWSRegionEvent *e = static_cast<QWSRegionEvent*>(event);
            QRegion reg;
            reg.setRects(e->rectangles, e->simpleData.nrectangles);
            qt_directpainter_region(dp, reg, e->simpleData.type);
            return 1;
#ifndef QT_NO_QWSEMBEDWIDGET
        } else if (event->type == QWSEvent::Embed) {
            QWSEmbedEvent *e = static_cast<QWSEmbedEvent*>(event);
            qt_directpainter_embedevent(dp, e);
            return 1;
 #endif // QT_NO_QWSEMBEDWIDGET
        }
    }
#endif // QT_NO_DIRECTPAINTER

#ifndef QT_NO_QWS_MANAGER
    if (d->last_manager && event->type == QWSEvent::Mouse) {
        QPoint pos(event->asMouse()->simpleData.x_root, event->asMouse()->simpleData.y_root);
        if (!d->last_manager->cachedRegion().contains(pos)) {
            // MouseEvent not yet delivered, so QCursor::pos() is not yet updated, sending 2 x pos
            QMouseEvent outside(QEvent::MouseMove, pos, pos, Qt::NoButton, 0, 0);
            QApplication::sendSpontaneousEvent(d->last_manager, &outside);
            d->last_manager = 0;
            qt_last_cursor = 0xffffffff; //decoration is like another window; must redo cursor
        }
    }
#endif // QT_NO_QWS_MANAGER

    QETWidget *keywidget=0;
    bool grabbed=false;
    if (event->type==QWSEvent::Key || event->type == QWSEvent::IMEvent || event->type == QWSEvent::IMQuery) {
        keywidget = static_cast<QETWidget*>(QWidget::keyboardGrabber());
        if (keywidget) {
            grabbed = true;
        } else {
            if (QWidget *popup = QApplication::activePopupWidget()) {
                if (popup->focusWidget())
                    keywidget = static_cast<QETWidget*>(popup->focusWidget());
                else
                    keywidget = static_cast<QETWidget*>(popup);
            } else if (QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget->isVisible())
                keywidget = static_cast<QETWidget*>(QApplicationPrivate::focus_widget);
            else if (widget)
                keywidget = static_cast<QETWidget*>(widget->window());
        }
    } else if (event->type==QWSEvent::MaxWindowRect) {
        QRect r = static_cast<QWSMaxWindowRectEvent*>(event)->simpleData.rect;
        setMaxWindowRect(r);
        return 0;
#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
    } else if (event->type == QWSEvent::ScreenTransformation) {
        QWSScreenTransformationEvent *pe = static_cast<QWSScreenTransformationEvent*>(event);
        setScreenTransformation(pe->simpleData.screen,
                                pe->simpleData.transformation);
        return 0;
#endif
    } else if (widget && event->type==QWSEvent::Mouse) {
        // The mouse event is to one of my top-level widgets
        // which one?
        const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton;
        QPoint p(event->asMouse()->simpleData.x_root,
                 event->asMouse()->simpleData.y_root);
        int mouseButtonState = event->asMouse()->simpleData.state & btnMask;
        static int btnstate = 0;

        QETWidget *w = static_cast<QETWidget*>(QWidget::mouseGrabber());
        if (w && !mouseButtonState && qt_pressGrab == w)
            qt_pressGrab = 0;
#ifndef QT_NO_QWS_MANAGER
        if (!w)
            w = static_cast<QETWidget*>(QWSManager::grabbedMouse());
#endif
        if (w) {
            // Our mouse is grabbed - send it.
            widget = w;
            btnstate = mouseButtonState;
        } else {
            static QWidget *gw = 0;
            // Three jobs to do here:
            // 1. find the child widget this event belongs to.
            // 2. make sure the cursor is correct.
            // 3. handle implicit mouse grab due to button press.
            w = widget; // w is the widget the cursor is in.

            //### ??? alloc_region
            //#### why should we get events outside alloc_region ????
            if (1 /*widget->data->alloc_region.contains(dp) */) {
                // Find the child widget that the cursor is in.
                w = static_cast<QETWidget*>(widget->childAt(widget->mapFromParent(p)));
                if (!w)
                    w = widget;
#ifndef QT_NO_CURSOR
                // Update Cursor.
                if (!gw || gw != w || qt_last_cursor == 0xffffffff) {
                    QCursor *curs = 0;
                    if (!qApp->d_func()->cursor_list.isEmpty())
                        curs = &qApp->d_func()->cursor_list.first();
                    else if (w->d_func()->extraData())
                        curs = w->d_func()->extraData()->curs;
                    QWidget *pw = w;
                    // If this widget has no cursor set, try parent.
                    while (!curs) {
                        pw = pw->parentWidget();
                        if (!pw)
                            break;
                        if (pw->d_func()->extraData())
                            curs = pw->d_func()->extraData()->curs;
                    }
                    if (!qws_overrideCursor) {
                        if (curs)
                            QPaintDevice::qwsDisplay()->selectCursor(widget, curs->handle());
                        else
                            QPaintDevice::qwsDisplay()->selectCursor(widget, Qt::ArrowCursor);
                    }
                }
#endif
                gw = w;
            } else {
                // This event is not for any of our widgets
                gw = 0;
            }
            if (mouseButtonState && !btnstate) {
                // The server has grabbed the mouse for us.
                // Remember which of my widgets has it.
                qt_pressGrab = w;
                if (!widget->isActiveWindow() &&
                    (!app_do_modal || QApplication::activeModalWidget() == widget) &&
                    !((widget->windowFlags() & Qt::FramelessWindowHint) || (widget->windowType() == Qt::Tool))) {
                    widget->activateWindow();
                    if (widget->raiseOnClick())
                        widget->raise();
                }
            }
            btnstate = mouseButtonState;
            widget = w;
        }
    }

    if (!widget) {                                // don't know this window
        if (!QWidget::mouseGrabber()
#ifndef QT_NO_QWS_MANAGER
            && !QWSManager::grabbedMouse()
#endif
            ) {
            qt_last_cursor = 0xffffffff; // cursor can be changed by another application
        }

        QWidget* popup = QApplication::activePopupWidget();
        if (popup) {

            /*
              That is more than suboptimal. The real solution should
              do some keyevent and buttonevent translation, so that
              the popup still continues to work as the user expects.
              Unfortunately this translation is currently only
              possible with a known widget. I'll change that soon
              (Matthias).
            */

            // Danger - make sure we don't lock the server
            switch (event->type) {
            case QWSEvent::Mouse:
            case QWSEvent::Key:
                do {
                    popup->close();
                } while ((popup = qApp->activePopupWidget()));
                return 1;
            }
        }
        if (event->type == QWSEvent::Mouse && *mouseInWidget) {
            QApplicationPrivate::dispatchEnterLeave(0, *mouseInWidget);
            (*mouseInWidget) = 0;
        }
        return -1;
    }

    if (app_do_modal)                                // modal event handling
        if (!qt_try_modal(widget, event)) {
            return 1;
        }

    if (widget->qwsEvent(event))                // send through widget filter
        return 1;
    switch (event->type) {

    case QWSEvent::Mouse: {                        // mouse event
        QWSMouseEvent *me = event->asMouse();
        QWSMouseEvent::SimpleData &mouse = me->simpleData;

        //  Translate a QWS event into separate move
        // and press/release events
        // Beware of reentrancy: we can enter a modal state
        // inside translateMouseEvent

        if (isMove) {
            QWSMouseEvent move = *me;
            move.simpleData.state = oldstate;
            widget->translateMouseEvent(&move, oldstate);
        }
        if ((mouse.state&Qt::MouseButtonMask) != (oldstate&Qt::MouseButtonMask)) {
            widget->translateMouseEvent(me, oldstate);
        }

        if (mouse.delta != 0)
            widget->translateWheelEvent(me);

        if (qt_button_down && (mouse_state & Qt::MouseButtonMask) == 0)
            qt_button_down = 0;

        break;
    }
    case QWSEvent::Key:                                // keyboard event
        if (keywidget) // should always exist
            keywidget->translateKeyEvent(static_cast<QWSKeyEvent*>(event), grabbed);
        break;

#ifndef QT_NO_QWS_INPUTMETHODS
    case QWSEvent::IMEvent:
        if (keywidget) // should always exist
            QWSInputContext::translateIMEvent(keywidget, static_cast<QWSIMEvent*>(event));
        break;

    case QWSEvent::IMQuery:
        if (keywidget) // should always exist
            QWSInputContext::translateIMQueryEvent(keywidget, static_cast<QWSIMQueryEvent*>(event));
        break;

    case QWSEvent::IMInit:
        QWSInputContext::translateIMInitEvent(static_cast<QWSIMInitEvent*>(event));
        break;
#endif
    case QWSEvent::Region:
        widget->translateRegionEvent(static_cast<QWSRegionEvent*>(event));
        break;
    case QWSEvent::Focus:
        if ((static_cast<QWSFocusEvent*>(event))->simpleData.get_focus) {
            if (widget == static_cast<QWidget *>(desktop()))
                return true; // not interesting
            if (activeWindow() != widget) {
                setActiveWindow(widget);
                if (QApplicationPrivate::active_window)
                    static_cast<QETWidget *>(QApplicationPrivate::active_window)->repaintDecoration(desktop()->rect(), false);
                if (widget && !d->inPopupMode()) {
                    QWidget *w = widget->focusWidget();
                    while (w && w->focusProxy())
                        w = w->focusProxy();
                    if (w && (w->focusPolicy() != Qt::NoFocus))
                        w->setFocus();
                    else
                        widget->QWidget::focusNextPrevChild(true);
                    if (!QApplicationPrivate::focus_widget) {
                        if (widget->focusWidget())
                            widget->focusWidget()->setFocus();
                        else
                            widget->window()->setFocus();
                    }
                }
            }
        } else {        // lost focus
            if (widget == static_cast<QWidget *>(desktop()))
                return true; // not interesting
            if (QApplicationPrivate::focus_widget) {
                QETWidget *old = static_cast<QETWidget *>(QApplicationPrivate::active_window);
                setActiveWindow(0);
                qt_last_cursor = 0xffffffff;
                //QApplicationPrivate::active_window = 0;
                if (old)
                    old->repaintDecoration(desktop()->rect(), false);
                /* activateWindow() sends focus events
                   QApplication::setFocusWidget(0);
                */
            }
        }
        break;

    case QWSEvent::WindowOperation:
        if (static_cast<QWidget *>(widget) == desktop())
            return true;
        switch ((static_cast<QWSWindowOperationEvent *>(event))->simpleData.op) {
        case QWSWindowOperationEvent::Show:
            widget->show();
            break;
        case QWSWindowOperationEvent::Hide:
            widget->hide();
            break;
        case QWSWindowOperationEvent::ShowMaximized:
            widget->showMaximized();
            break;
        case QWSWindowOperationEvent::ShowMinimized:
            widget->showMinimized();
            break;
        case QWSWindowOperationEvent::ShowNormal:
            widget->showNormal();
            break;
        case QWSWindowOperationEvent::Close:
            widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
            break;
        }
        break;
#ifndef QT_NO_QWSEMBEDWIDGET
    case QWSEvent::Embed:
        widget->translateEmbedEvent(static_cast<QWSEmbedEvent*>(event));
        break;
#endif
    default:
        break;
    }

    return 0;
}

bool QApplication::qwsEventFilter(QWSEvent *)
{
    return false;
}

void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors)
{
    if (start < 0 || start > 39) {
        qWarning("QApplication::qwsSetCustomColors: start < 0 || start > 39");
        return;
    }
    if (start + numColors > 40) {
        numColors = 40 - start;
        qWarning("QApplication::qwsSetCustomColors: Too many colors");
    }
    start += 216;
    for (int i = 0; i < numColors; i++) {
        qt_screen->set(start + i, qRed(colorTable[i]), qGreen(colorTable[i]),
                        qBlue(colorTable[i]));
    }
}

#ifndef QT_NO_QWS_MANAGER
QDecoration &QApplication::qwsDecoration()
{
    return *qws_decoration;
}

void QApplication::qwsSetDecoration(QDecoration *dec)
{
    if (dec) {
        delete qws_decoration;
        qws_decoration = dec;
        QWidgetList widgets = topLevelWidgets();
        for (int i = 0; i < widgets.size(); ++i) {
            QWidget *w = widgets[i];
            if (w->isVisible() && w != desktop()) {
                static_cast<QETWidget *>(w)->updateRegion();
                static_cast<QETWidget *>(w)->repaintDecoration(desktop()->rect(), false);
                if (w->isMaximized())
                    w->showMaximized();
            }
        }
    }
}

QDecoration* QApplication::qwsSetDecoration(const QString &decoration)
{
    QDecoration *decore = QDecorationFactory::create(decoration);
    if (!decore)
        return 0;

    qwsSetDecoration(decore);
    return decore;
}

#endif

bool QApplicationPrivate::modalState()
{
    return app_do_modal;
}

void QApplicationPrivate::enterModal_sys(QWidget *widget)
{
    if (!qt_modal_stack)
        qt_modal_stack = new QWidgetList;
    qt_modal_stack->insert(0, widget);
    app_do_modal = true;
}

void QApplicationPrivate::leaveModal_sys(QWidget *widget)
{
    if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
        if (qt_modal_stack->isEmpty()) {
            delete qt_modal_stack;
            qt_modal_stack = 0;
        }
    }
    app_do_modal = qt_modal_stack != 0;
}

static bool qt_try_modal(QWidget *widget, QWSEvent *event)
{
    QWidget * top = 0;

    if (QApplicationPrivate::tryModalHelper(widget, &top))
        return true;

    bool block_event  = false;
    bool paint_event = false;

    switch (event->type) {
        case QWSEvent::Focus:
            if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
                break;
            // drop through
        case QWSEvent::Mouse:                        // disallow mouse/key events
        case QWSEvent::Key:
            block_event         = true;
            break;
    }

    if (top->parentWidget() == 0 && (block_event || paint_event))
        top->raise();

    return !block_event;
}

static int openPopupCount = 0;
void QApplicationPrivate::openPopup(QWidget *popup)
{
    openPopupCount++;
    if (!popupWidgets) {                        // create list
        popupWidgets = new QWidgetList;

        /* only grab if you are the first/parent popup */
        QPaintDevice::qwsDisplay()->grabMouse(popup,true);
        QPaintDevice::qwsDisplay()->grabKeyboard(popup,true);
        popupGrabOk = true;
    }
    popupWidgets->append(popup);                // add to end of list

    // popups are not focus-handled by the window system (the first
    // popup grabbed the keyboard), so we have to do that manually: A
    // new popup gets the focus
    if (popup->focusWidget()) {
        popup->focusWidget()->setFocus(Qt::PopupFocusReason);
    } else if (popupWidgets->count() == 1) { // this was the first popup
        if (QWidget *fw = QApplication::focusWidget()) {
            QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
            QApplication::sendEvent(fw, &e);
        }
    }
}

void QApplicationPrivate::closePopup(QWidget *popup)
{
    if (!popupWidgets)
        return;

    popupWidgets->removeAll(popup);
    if (popup == popupOfPopupButtonFocus) {
        popupButtonFocus = 0;
        popupOfPopupButtonFocus = 0;
    }
    if (popupWidgets->count() == 0) {                // this was the last popup
        popupCloseDownMode = true;                // control mouse events
        delete popupWidgets;
        popupWidgets = 0;
        if (popupGrabOk) {        // grabbing not disabled
            QPaintDevice::qwsDisplay()->grabMouse(popup,false);
            QPaintDevice::qwsDisplay()->grabKeyboard(popup,false);
            popupGrabOk = false;
            // XXX ungrab keyboard
        }
        if (active_window) {
            if (QWidget *fw = active_window->focusWidget()) {
                if (fw != QApplication::focusWidget()) {
                    fw->setFocus(Qt::PopupFocusReason);
                } else {
                    QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
                    QApplication::sendEvent(fw, &e);
                }
            }
        }
    } else {
        // popups are not focus-handled by the window system (the
        // first popup grabbed the keyboard), so we have to do that
        // manually: A popup was closed, so the previous popup gets
        // the focus.
        QWidget* aw = popupWidgets->last();
        if (QWidget *fw = aw->focusWidget())
            fw->setFocus(Qt::PopupFocusReason);
    }
}

/*****************************************************************************
  Event translation; translates FB events to Qt events
 *****************************************************************************/

//
// Mouse event translation
//
// FB doesn't give mouse double click events, so we generate them by
// comparing window, time and position between two mouse press events.
//


// Needed for QCursor::pos

static const int AnyButton = (Qt::LeftButton | Qt::MidButton | Qt::RightButton);



//
// Wheel event translation
//
bool QETWidget::translateWheelEvent(const QWSMouseEvent *me)
{
#ifdef QT_NO_WHEELEVENT
    Q_UNUSED(me);
    return false;
#else
    const QWSMouseEvent::SimpleData &mouse = me->simpleData;

    // Figure out wheeling direction:
    //    Horizontal wheel w/o Alt
    // OR Vertical wheel   w/  Alt  ==> Horizontal wheeling
    //    ..all other permutations  ==> Vertical wheeling
    int axis = mouse.delta / 120; // WHEEL_DELTA?
    Qt::Orientation orient = ((axis == 2 || axis == -2) && ((mouse.state & Qt::AltModifier) == 0))
                             ||((axis == 1 || axis == -1) && mouse.state & Qt::AltModifier)
                             ? Qt::Horizontal : Qt::Vertical;

    QPoint mousePoint = QPoint(mouse.x_root, mouse.y_root);

    // send the event to the widget or its ancestors
    QWidget* popup = qApp->activePopupWidget();
    if (popup && window() != popup)
        popup->close();
    QWheelEvent we(mapFromGlobal(mousePoint), mousePoint, mouse.delta,
                   Qt::MouseButtons(mouse.state & Qt::MouseButtonMask),
                   Qt::KeyboardModifiers(mouse.state & Qt::KeyboardModifierMask), orient);
    if (QApplication::sendSpontaneousEvent(this, &we))
        return true;

    // send the event to the widget that has the focus or its ancestors, if different
    QWidget *w = this;
    if (w != qApp->focusWidget() && (w = qApp->focusWidget())) {
        QWidget* popup = qApp->activePopupWidget();
        if (popup && w != popup)
            popup->hide();
        if (QApplication::sendSpontaneousEvent(w, &we))
            return true;
    }
    return false;
#endif
}

bool QETWidget::translateMouseEvent(const QWSMouseEvent *event, int prevstate)
{
    static bool manualGrab = false;
    QPoint pos;
    QPoint globalPos;
    int button = 0;

    if (sm_blockUserInput) // block user interaction during session management
        return true;
    const QWSMouseEvent::SimpleData &mouse = event->simpleData;
    pos = mapFromGlobal(QPoint(mouse.x_root, mouse.y_root));
//     if (qt_last_x) {
//         *qt_last_x=mouse.x_root;
//         *qt_last_y=mouse.y_root;
//     }
    globalPos.rx() = mouse.x_root;
    globalPos.ry() = mouse.y_root;

    QEvent::Type type = QEvent::None;

    Qt::MouseButtons buttonstate = Qt::MouseButtons(mouse.state & Qt::MouseButtonMask);
    Qt::KeyboardModifiers keystate = Qt::KeyboardModifiers(mouse.state & Qt::KeyboardModifierMask);

    if (mouse.state == prevstate) {
        // mouse move
        type = QEvent::MouseMove;
    } else if ((mouse.state&AnyButton) != (prevstate&AnyButton)) {
        Qt::MouseButtons current_buttons = Qt::MouseButtons(prevstate&Qt::MouseButtonMask);
        for (button = Qt::LeftButton; !type && button <= Qt::MidButton; button<<=1) {
            if ((mouse.state&button) != (current_buttons&button)) {
                // button press or release
                current_buttons = Qt::MouseButtons(current_buttons ^ button);

#ifndef QT_NO_QWS_INPUTMETHODS
                //############ We used to do a QInputContext::reset(oldFocus);
                // when we changed the focus widget. See change 93389 for where the
                // focus code went. The IM code was (after testing for ClickToFocus):
                //if (mouse.state&button && w != QInputContext::microFocusWidget()) //button press
                //        QInputContext::reset(oldFocus);

#endif
                if (mouse.state&button) { //button press
                    qt_button_down = childAt(pos);
                    if (!qt_button_down)
                        qt_button_down = this;
                    if (/*XXX mouseActWindow == this &&*/
                        mouseButtonPressed == button &&
                        long(mouse.time) -long(mouseButtonPressTime)
                            < QApplication::doubleClickInterval() &&
                        qAbs(mouse.x_root - mouseXPos) < mouse_double_click_distance &&
                        qAbs(mouse.y_root - mouseYPos) < mouse_double_click_distance ) {
                        type = QEvent::MouseButtonDblClick;
                        mouseButtonPressTime -= 2000;        // no double-click next time
                    } else {
                        type = QEvent::MouseButtonPress;
                        mouseButtonPressTime = mouse.time;
                    }
                    mouseButtonPressed = button;        // save event params for
                    mouseXPos = globalPos.x();                // future double click tests
                    mouseYPos = globalPos.y();
                } else {                                // mouse button released
                    if (manualGrab) {                        // release manual grab
                        manualGrab = false;
                        // XXX XUngrabPointer(x11Display(), CurrentTime);
                    }

                    type = QEvent::MouseButtonRelease;
                }
            }
        }
        button >>= 1;
    }
    //XXX mouseActWindow = winId();                        // save some event params

    if (type == 0) {                                // event consumed
        return false; //EXIT in the normal case
    }

    if (qApp->d_func()->inPopupMode()) {                        // in popup mode
        QWidget *popup = qApp->activePopupWidget();
        // in X11, this would be the window we are over.
        // in QWS this is the top level popup.  to allow mouse
        // events to other widgets, need to go through qApp->QApplicationPrivate::popupWidgets.
        QSize s(qt_screen->width(), qt_screen->height());
        for (int i = 0; i < QApplicationPrivate::popupWidgets->size(); ++i) {
            QWidget *w = QApplicationPrivate::popupWidgets->at(i);

            if ((w->windowType() == Qt::Popup) && w->d_func()->localAllocatedRegion().contains(globalPos - w->geometry().topLeft()))
            {
                popup = w;
                break;
            }
        }
        pos = popup->mapFromGlobal(globalPos);
        bool releaseAfter = false;
        QWidget *popupChild  = popup->childAt(pos);
        QWidget *popupTarget = popupChild ? popupChild : popup;

        if (popup != popupOfPopupButtonFocus){
            popupButtonFocus = 0;
            popupOfPopupButtonFocus = 0;
        }

        if (!popupTarget->isEnabled()) {
            return false; //EXIT special case
        }

        switch (type) {
            case QEvent::MouseButtonPress:
            case QEvent::MouseButtonDblClick:
                popupButtonFocus = popupChild;
                popupOfPopupButtonFocus = popup;
                break;
            case QEvent::MouseButtonRelease:
                releaseAfter = true;
                break;
            default:
                break;                                // nothing for mouse move
        }

        int oldOpenPopupCount = openPopupCount;

        if (popupButtonFocus) {
            QMouseEvent e(type, popupButtonFocus->mapFromGlobal(globalPos),
                        globalPos, Qt::MouseButton(button), buttonstate, keystate);
            QApplication::sendSpontaneousEvent(popupButtonFocus, & e);
            if (releaseAfter) {
                popupButtonFocus = 0;
                popupOfPopupButtonFocus = 0;
            }
        } else if (popupChild) {
            QMouseEvent e(type, popupChild->mapFromGlobal(globalPos),
                        globalPos, Qt::MouseButton(button), buttonstate, keystate);
            QApplication::sendSpontaneousEvent(popupChild, & e);
        } else {
            QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), buttonstate, keystate);
            QApplication::sendSpontaneousEvent(popupChild ? popupChild : popup, & e);
        }
#ifndef QT_NO_CONTEXTMENU
        if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
            QWidget *popupEvent = popup;
            if(popupButtonFocus)
                popupEvent = popupButtonFocus;
            else if(popupChild)
                popupEvent = popupChild;
            QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, keystate);
            QApplication::sendSpontaneousEvent(popupEvent, &e);
        }
#endif // QT_NO_CONTEXTMENU

        if (releaseAfter)
            qt_button_down = 0;

    } else { //qApp not in popup mode
        QWidget *widget = this;
        QWidget *w = QWidget::mouseGrabber();
        if (!w && qt_button_down)
            w = qt_button_down;
        if (w && w != this) {
            widget = w;
            pos = mapToGlobal(pos);
            pos = w->mapFromGlobal(pos);
        }

        if (popupCloseDownMode) {
            popupCloseDownMode = false;
            if ((windowType() == Qt::Popup))        // ignore replayed event
                return true; //EXIT
        }

        QPointer<QWidget> leaveAfterRelease = 0;
        if (type == QEvent::MouseButtonRelease &&
            (mouse.state & (~button) & (Qt::LeftButton |
                                    Qt::MidButton |
                                    Qt::RightButton)) == 0) {
            // Button released outside the widget -> leave the widget after the
            // release event has been delivered.
            if (widget == qt_button_down && (pos.x() < 0 || pos.y() < 0))
                leaveAfterRelease = qt_button_down;
            qt_button_down = 0;
        }

        int oldOpenPopupCount = openPopupCount;

        QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), buttonstate, keystate);
#ifndef QT_NO_QWS_MANAGER
        if (widget->isWindow() && widget->d_func()->topData()->qwsManager
            && (widget->d_func()->topData()->qwsManager->region().contains(globalPos)
                || QWSManager::grabbedMouse() )) {
            if ((*mouseInWidget)) {
                QApplicationPrivate::dispatchEnterLeave(0, *mouseInWidget);
                (*mouseInWidget) = 0;
            }
            QApplication::sendSpontaneousEvent(widget->d_func()->topData()->qwsManager, &e);
            qApp->d_func()->last_manager = widget->d_func()->topData()->qwsManager;
        } else
#endif
        {
            if (widget != (*mouseInWidget)) {
                QApplicationPrivate::dispatchEnterLeave(widget, *mouseInWidget);
                (*mouseInWidget) = widget;
                qt_last_mouse_receiver = widget;
            }
            QApplication::sendSpontaneousEvent(widget, &e);
            if (leaveAfterRelease && !QWidget::mouseGrabber()) {
                *mouseInWidget = QApplication::widgetAt(globalPos);
                qt_last_mouse_receiver = *mouseInWidget;
                QApplicationPrivate::dispatchEnterLeave(*mouseInWidget, leaveAfterRelease);
                leaveAfterRelease = 0;
            }
        }
#ifndef QT_NO_CONTEXTMENU
        if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
            QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, keystate);
            QApplication::sendSpontaneousEvent(widget, &e);
        }
#endif // QT_NO_CONTEXTMENU
    }
    return true;
}


bool QETWidget::translateKeyEvent(const QWSKeyEvent *event, bool grab) /* grab is used in the #ifdef */
{
    int code = -1;
    //### Qt assumes keyboard state is state *before*, while QWS uses state after the event
    static Qt::KeyboardModifiers oldstate;
    Qt::KeyboardModifiers state = oldstate;
    oldstate = event->simpleData.modifiers;

    if (sm_blockUserInput) // block user interaction during session management
        return true;

    if (!isEnabled())
        return true;

    QEvent::Type type = event->simpleData.is_press ?
                        QEvent::KeyPress : QEvent::KeyRelease;
    bool autor = event->simpleData.is_auto_repeat;
    QString text;
    char ascii = 0;
    if (event->simpleData.unicode) {
        QChar ch(event->simpleData.unicode);
        if (ch.unicode() != 0xffff)
            text += ch;
        ascii = ch.toLatin1();
    }
    code = event->simpleData.keycode;

#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
    if (type == QEvent::KeyPress && !grab
        && static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->use_compat()) {
        // send accel events if the keyboard is not grabbed
        QKeyEvent a(type, code, state, text, autor, int(text.length()));
        if (static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->qt_tryAccelEvent(this, &a))
            return true;
    }
#else
    Q_UNUSED(grab);
#endif
    if (!text.isEmpty() && testAttribute(Qt::WA_KeyCompression)) {
        // the widget wants key compression so it gets it

        // XXX not implemented
    }

    QKeyEvent e(type, code, state, text, autor, int(text.length()));
    return QApplication::sendSpontaneousEvent(this, &e);
}

bool QETWidget::translateRegionEvent(const QWSRegionEvent *event)
{
    QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(windowSurface());
    Q_ASSERT(surface);

    QRegion region;
    region.setRects(event->rectangles, event->simpleData.nrectangles);

    switch (event->simpleData.type) {
    case QWSRegionEvent::Allocation:
        region.translate(-mapToGlobal(QPoint()));
        surface->setClipRegion(region);
        break;
#ifdef QT_QWS_CLIENTBLIT
    case QWSRegionEvent::DirectPaint:
        surface->setDirectRegion(region, event->simpleData.id);
        break;
#endif
    default:
        break;
    }

    return true;
}

#ifndef QT_NO_QWSEMBEDWIDGET
void QETWidget::translateEmbedEvent(const QWSEmbedEvent *event)
{
    if (event->simpleData.type | QWSEmbedEvent::Region) {
        const QRegion region = event->region;
        setGeometry(region.boundingRect());
        setVisible(!region.isEmpty());
    }
}
#endif // QT_NO_QWSEMBEDWIDGET

void QETWidget::repaintDecoration(QRegion r, bool post)
{
    Q_UNUSED(post);
#ifdef QT_NO_QWS_MANAGER
    Q_UNUSED(r);
#else
    //please note that qwsManager is a QObject, not a QWidget.
    //therefore, normal ways of painting do not work.
    // However, it does listen to paint events.

    Q_D(QWidget);
    if (isWindow() && d->topData()->qwsManager && isVisible()) {
        QWSManager *manager = d->topData()->qwsManager;
        r &= manager->region();
        if (!r.isEmpty())
            manager->repaintRegion(QDecoration::All, QDecoration::Normal);
    }
#endif
}

void QETWidget::updateRegion()
{
    Q_D(QWidget);

    QTLWExtra *topextra = d->maybeTopData();
    if (!topextra)
        return;

    QRegion myregion = d->localRequestedRegion();
    myregion.translate(geometry().topLeft());

#ifndef QT_NO_QWS_MANAGER
    QWSManager *manager = topextra->qwsManager;
    if (manager)
        myregion += manager->region();
#endif

    QRect br(myregion.boundingRect());
    topextra->frameStrut.setCoords(d->data.crect.x() - br.x(),
                                   d->data.crect.y() - br.y(),
                                   br.right() - d->data.crect.right(),
                                   br.bottom() - d->data.crect.bottom());
}

void  QApplication::setCursorFlashTime(int msecs)
{
    QApplicationPrivate::cursor_flash_time = msecs;
}


int QApplication::cursorFlashTime()
{
    return QApplicationPrivate::cursor_flash_time;
}

void QApplication::setDoubleClickInterval(int ms)
{
    QApplicationPrivate::mouse_double_click_time = ms;
}

int QApplication::doubleClickInterval()
{
    return QApplicationPrivate::mouse_double_click_time;
}

void QApplication::setKeyboardInputInterval(int ms)
{
    QApplicationPrivate::keyboard_input_time = ms;
}

int QApplication::keyboardInputInterval()
{
    return QApplicationPrivate::keyboard_input_time;
}

#ifndef QT_NO_WHEELEVENT
void QApplication::setWheelScrollLines(int lines)
{
    QApplicationPrivate::wheel_scroll_lines = lines;
}

int QApplication::wheelScrollLines()
{
    return QApplicationPrivate::wheel_scroll_lines;
}
#endif

void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
{
    switch (effect) {
    case Qt::UI_AnimateMenu:
        QApplicationPrivate::animate_menu = enable;
        break;
    case Qt::UI_FadeMenu:
        if (enable)
            QApplicationPrivate::animate_menu = true;
        QApplicationPrivate::fade_menu = enable;
        break;
    case Qt::UI_AnimateCombo:
        QApplicationPrivate::animate_combo = enable;
        break;
    case Qt::UI_AnimateTooltip:
        QApplicationPrivate::animate_tooltip = enable;
        break;
    case Qt::UI_FadeTooltip:
        if (enable)
            QApplicationPrivate::animate_tooltip = true;
        QApplicationPrivate::fade_tooltip = enable;
        break;
    case Qt::UI_AnimateToolBox:
        QApplicationPrivate::animate_toolbox = enable;
        break;
    default:
        QApplicationPrivate::animate_ui = enable;
        break;
    }
}

bool QApplication::isEffectEnabled(Qt::UIEffect effect)
{
    if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
        return false;

    switch(effect) {
    case Qt::UI_AnimateMenu:
        return QApplicationPrivate::animate_menu;
    case Qt::UI_FadeMenu:
        return QApplicationPrivate::fade_menu;
    case Qt::UI_AnimateCombo:
        return QApplicationPrivate::animate_combo;
    case Qt::UI_AnimateTooltip:
        return QApplicationPrivate::animate_tooltip;
    case Qt::UI_FadeTooltip:
        return QApplicationPrivate::fade_tooltip;
    case Qt::UI_AnimateToolBox:
        return QApplicationPrivate::animate_toolbox;
    default:
        return QApplicationPrivate::animate_ui;
    }
}

void QApplication::setArgs(int c, char **v)
{
    Q_D(QApplication);
    d->argc = c;
    d->argv = v;
}

void QApplicationPrivate::initializeMultitouch_sys()
{ }
void QApplicationPrivate::cleanupMultitouch_sys()
{ }

/* \internal
   This is used to clean up the qws server
   in case the QApplication constructor threw an exception
*/
QWSServerCleaner::~QWSServerCleaner()
{
    if (qwsServer && qws_single_process)
        QWSServer::closedown();
}

QT_END_NAMESPACE
